Fix TX hang and RMCP Ping issue (due to a microcode loading issue)

The large number of lines changed for this patch are due to several fuctions
moving in order to be called from a new function.

Signed-off-by: Jesse Brandeburg <[EMAIL PROTECTED]>
Signed-off-by: Jeff Kirsher <[EMAIL PROTECTED]>
Signed-off-by: John Ronciak <[EMAIL PROTECTED]>
---

 drivers/net/e100.c |  315 +++++++++++++++++++++++++++++-----------------------
 1 files changed, 174 insertions(+), 141 deletions(-)

diff --git a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -156,7 +156,7 @@
 
 #define DRV_NAME               "e100"
 #define DRV_EXT                "-NAPI"
-#define DRV_VERSION            "3.4.14-k4"DRV_EXT
+#define DRV_VERSION            "3.5.10-k2"DRV_EXT
 #define DRV_DESCRIPTION                "Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT          "Copyright(c) 1999-2005 Intel Corporation"
 #define PFX                    DRV_NAME ": "
@@ -872,141 +872,6 @@ err_unlock:
        return err;
 }
 
-static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
-{
-       u32 data_out = 0;
-       unsigned int i;
-
-       writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
-
-       for(i = 0; i < 100; i++) {
-               udelay(20);
-               if((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready)
-                       break;
-       }
-
-       DPRINTK(HW, DEBUG,
-               "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
-               dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);
-       return (u16)data_out;
-}
-
-static int mdio_read(struct net_device *netdev, int addr, int reg)
-{
-       return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
-}
-
-static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
-{
-       mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
-}
-
-static void e100_get_defaults(struct nic *nic)
-{
-       struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
-       struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
-
-       pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
-       /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
-       nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
-       if(nic->mac == mac_unknown)
-               nic->mac = mac_82557_D100_A;
-
-       nic->params.rfds = rfds;
-       nic->params.cbs = cbs;
-
-       /* Quadwords to DMA into FIFO before starting frame transmit */
-       nic->tx_threshold = 0xE0;
-
-       /* no interrupt for every tx completion, delay = 256us if not 557*/
-       nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |
-               ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
-
-       /* Template for a freshly allocated RFD */
-       nic->blank_rfd.command = cpu_to_le16(cb_el);
-       nic->blank_rfd.rbd = 0xFFFFFFFF;
-       nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
-
-       /* MII setup */
-       nic->mii.phy_id_mask = 0x1F;
-       nic->mii.reg_num_mask = 0x1F;
-       nic->mii.dev = nic->netdev;
-       nic->mii.mdio_read = mdio_read;
-       nic->mii.mdio_write = mdio_write;
-}
-
-static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
-{
-       struct config *config = &cb->u.config;
-       u8 *c = (u8 *)config;
-
-       cb->command = cpu_to_le16(cb_config);
-
-       memset(config, 0, sizeof(struct config));
-
-       config->byte_count = 0x16;              /* bytes in this struct */
-       config->rx_fifo_limit = 0x8;            /* bytes in FIFO before DMA */
-       config->direct_rx_dma = 0x1;            /* reserved */
-       config->standard_tcb = 0x1;             /* 1=standard, 0=extended */
-       config->standard_stat_counter = 0x1;    /* 1=standard, 0=extended */
-       config->rx_discard_short_frames = 0x1;  /* 1=discard, 0=pass */
-       config->tx_underrun_retry = 0x3;        /* # of underrun retries */
-       config->mii_mode = 0x1;                 /* 1=MII mode, 0=503 mode */
-       config->pad10 = 0x6;
-       config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
-       config->preamble_length = 0x2;          /* 0=1, 1=3, 2=7, 3=15 bytes */
-       config->ifs = 0x6;                      /* x16 = inter frame spacing */
-       config->ip_addr_hi = 0xF2;              /* ARP IP filter - not used */
-       config->pad15_1 = 0x1;
-       config->pad15_2 = 0x1;
-       config->crs_or_cdt = 0x0;               /* 0=CRS only, 1=CRS or CDT */
-       config->fc_delay_hi = 0x40;             /* time delay for fc frame */
-       config->tx_padding = 0x1;               /* 1=pad short frames */
-       config->fc_priority_threshold = 0x7;    /* 7=priority fc disabled */
-       config->pad18 = 0x1;
-       config->full_duplex_pin = 0x1;          /* 1=examine FDX# pin */
-       config->pad20_1 = 0x1F;
-       config->fc_priority_location = 0x1;     /* 1=byte#31, 0=byte#19 */
-       config->pad21_1 = 0x5;
-
-       config->adaptive_ifs = nic->adaptive_ifs;
-       config->loopback = nic->loopback;
-
-       if(nic->mii.force_media && nic->mii.full_duplex)
-               config->full_duplex_force = 0x1;        /* 1=force, 0=auto */
-
-       if(nic->flags & promiscuous || nic->loopback) {
-               config->rx_save_bad_frames = 0x1;       /* 1=save, 0=discard */
-               config->rx_discard_short_frames = 0x0;  /* 1=discard, 0=save */
-               config->promiscuous_mode = 0x1;         /* 1=on, 0=off */
-       }
-
-       if(nic->flags & multicast_all)
-               config->multicast_all = 0x1;            /* 1=accept, 0=no */
-
-       /* disable WoL when up */
-       if(netif_running(nic->netdev) || !(nic->flags & wol_magic))
-               config->magic_packet_disable = 0x1;     /* 1=off, 0=on */
-
-       if(nic->mac >= mac_82558_D101_A4) {
-               config->fc_disable = 0x1;       /* 1=Tx fc off, 0=Tx fc on */
-               config->mwi_enable = 0x1;       /* 1=enable, 0=disable */
-               config->standard_tcb = 0x0;     /* 1=standard, 0=extended */
-               config->rx_long_ok = 0x1;       /* 1=VLANs ok, 0=standard */
-               if(nic->mac >= mac_82559_D101M)
-                       config->tno_intr = 0x1;         /* TCO stats enable */
-               else
-                       config->standard_stat_counter = 0x0;
-       }
-
-       DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-               c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
-       DPRINTK(HW, DEBUG, "[08-15]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-               c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
-       DPRINTK(HW, DEBUG, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-               c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
-}
-
 /********************************************************/
 /*  Micro code for 8086:1229 Rev 8                      */
 /********************************************************/
@@ -1145,7 +1010,7 @@ static void e100_configure(struct nic *n
 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
 }
 
-static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff 
*skb)
+static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff 
*skb)
 {
 /* *INDENT-OFF* */
        static struct {
@@ -1238,7 +1103,6 @@ static void e100_load_ucode(struct nic *
 #define BUNDLEMAX (u16)6
 #define INTDELAY (u16)1536 /* 0x600 */
 
-       /* do not load u-code for ICH devices */
        if (nic->flags & ich)
                goto noloaducode;
 
@@ -1259,12 +1123,181 @@ static void e100_load_ucode(struct nic *
 
                for (i = 0; i < UCODE_SIZE; i++)
                        cb->u.ucode[i] = cpu_to_le32(ucode[i]);
-               cb->command = cpu_to_le16(cb_ucode);
+               cb->command = cpu_to_le16(cb_ucode | cb_el);
                return;
        }
 
 noloaducode:
-       cb->command = cpu_to_le16(cb_nop);
+       cb->command = cpu_to_le16(cb_nop | cb_el);
+}
+
+static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb,
+       void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
+{
+       int err = 0, counter = 50;
+       struct cb *cb = nic->cb_to_clean;
+
+       if ((err = e100_exec_cb(nic, NULL, e100_setup_ucode)))
+               DPRINTK(PROBE,ERR, "ucode cmd failed with error %d\n", err);
+               
+       /* must restart cuc */
+       nic->cuc_cmd = cuc_start;
+
+       /* wait for completion */
+       e100_write_flush(nic);
+       udelay(10);
+
+       /* wait for possibly (ouch) 500ms */
+       while (!(cb->status & cpu_to_le16(cb_complete))) {
+               msleep(10);
+               if (!--counter) break;
+       }
+       
+       /* ack any interupts, something could have been set */
+       writeb(~0, &nic->csr->scb.stat_ack);
+
+       /* if the command failed, or is not OK, notify and return */
+       if (!counter || !(cb->status & cpu_to_le16(cb_ok))) {
+               DPRINTK(PROBE,ERR, "ucode load failed\n");
+               err = -EPERM;
+       }
+       
+       return err;
+}
+
+static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
+{
+       u32 data_out = 0;
+       unsigned int i;
+
+       writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
+
+       for(i = 0; i < 100; i++) {
+               udelay(20);
+               if((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready)
+                       break;
+       }
+
+       DPRINTK(HW, DEBUG,
+               "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
+               dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);
+       return (u16)data_out;
+}
+
+static int mdio_read(struct net_device *netdev, int addr, int reg)
+{
+       return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
+}
+
+static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
+{
+       mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
+}
+
+static void e100_get_defaults(struct nic *nic)
+{
+       struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
+       struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
+
+       pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
+       /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
+       nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
+       if(nic->mac == mac_unknown)
+               nic->mac = mac_82557_D100_A;
+
+       nic->params.rfds = rfds;
+       nic->params.cbs = cbs;
+
+       /* Quadwords to DMA into FIFO before starting frame transmit */
+       nic->tx_threshold = 0xE0;
+
+       /* no interrupt for every tx completion, delay = 256us if not 557*/
+       nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |
+               ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
+
+       /* Template for a freshly allocated RFD */
+       nic->blank_rfd.command = cpu_to_le16(cb_el);
+       nic->blank_rfd.rbd = 0xFFFFFFFF;
+       nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
+
+       /* MII setup */
+       nic->mii.phy_id_mask = 0x1F;
+       nic->mii.reg_num_mask = 0x1F;
+       nic->mii.dev = nic->netdev;
+       nic->mii.mdio_read = mdio_read;
+       nic->mii.mdio_write = mdio_write;
+}
+
+static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
+{
+       struct config *config = &cb->u.config;
+       u8 *c = (u8 *)config;
+
+       cb->command = cpu_to_le16(cb_config);
+
+       memset(config, 0, sizeof(struct config));
+
+       config->byte_count = 0x16;              /* bytes in this struct */
+       config->rx_fifo_limit = 0x8;            /* bytes in FIFO before DMA */
+       config->direct_rx_dma = 0x1;            /* reserved */
+       config->standard_tcb = 0x1;             /* 1=standard, 0=extended */
+       config->standard_stat_counter = 0x1;    /* 1=standard, 0=extended */
+       config->rx_discard_short_frames = 0x1;  /* 1=discard, 0=pass */
+       config->tx_underrun_retry = 0x3;        /* # of underrun retries */
+       config->mii_mode = 0x1;                 /* 1=MII mode, 0=503 mode */
+       config->pad10 = 0x6;
+       config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
+       config->preamble_length = 0x2;          /* 0=1, 1=3, 2=7, 3=15 bytes */
+       config->ifs = 0x6;                      /* x16 = inter frame spacing */
+       config->ip_addr_hi = 0xF2;              /* ARP IP filter - not used */
+       config->pad15_1 = 0x1;
+       config->pad15_2 = 0x1;
+       config->crs_or_cdt = 0x0;               /* 0=CRS only, 1=CRS or CDT */
+       config->fc_delay_hi = 0x40;             /* time delay for fc frame */
+       config->tx_padding = 0x1;               /* 1=pad short frames */
+       config->fc_priority_threshold = 0x7;    /* 7=priority fc disabled */
+       config->pad18 = 0x1;
+       config->full_duplex_pin = 0x1;          /* 1=examine FDX# pin */
+       config->pad20_1 = 0x1F;
+       config->fc_priority_location = 0x1;     /* 1=byte#31, 0=byte#19 */
+       config->pad21_1 = 0x5;
+
+       config->adaptive_ifs = nic->adaptive_ifs;
+       config->loopback = nic->loopback;
+
+       if(nic->mii.force_media && nic->mii.full_duplex)
+               config->full_duplex_force = 0x1;        /* 1=force, 0=auto */
+
+       if(nic->flags & promiscuous || nic->loopback) {
+               config->rx_save_bad_frames = 0x1;       /* 1=save, 0=discard */
+               config->rx_discard_short_frames = 0x0;  /* 1=discard, 0=save */
+               config->promiscuous_mode = 0x1;         /* 1=on, 0=off */
+       }
+
+       if(nic->flags & multicast_all)
+               config->multicast_all = 0x1;            /* 1=accept, 0=no */
+
+       /* disable WoL when up */
+       if(netif_running(nic->netdev) || !(nic->flags & wol_magic))
+               config->magic_packet_disable = 0x1;     /* 1=off, 0=on */
+
+       if(nic->mac >= mac_82558_D101_A4) {
+               config->fc_disable = 0x1;       /* 1=Tx fc off, 0=Tx fc on */
+               config->mwi_enable = 0x1;       /* 1=enable, 0=disable */
+               config->standard_tcb = 0x0;     /* 1=standard, 0=extended */
+               config->rx_long_ok = 0x1;       /* 1=VLANs ok, 0=standard */
+               if(nic->mac >= mac_82559_D101M)
+                       config->tno_intr = 0x1;         /* TCO stats enable */
+               else
+                       config->standard_stat_counter = 0x0;
+       }
+
+       DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+               c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
+       DPRINTK(HW, DEBUG, "[08-15]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+               c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
+       DPRINTK(HW, DEBUG, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+               c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
 }
 
 static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
@@ -1363,7 +1396,7 @@ static int e100_hw_init(struct nic *nic)
                return err;
        if((err = e100_exec_cmd(nic, ruc_load_base, 0)))
                return err;
-       if((err = e100_exec_cb(nic, NULL, e100_load_ucode)))
+       if ((err = e100_exec_cb_wait(nic, NULL, e100_setup_ucode)))
                return err;
        if((err = e100_exec_cb(nic, NULL, e100_configure)))
                return err;
Fix TX hang and RMCP Ping issue (due to a microcode loading issue)

The large number of lines changed for this patch are due to several fuctions
moving in order to be called from a new function.

Signed-off-by: Jesse Brandeburg <[EMAIL PROTECTED]>
Signed-off-by: Jeff Kirsher <[EMAIL PROTECTED]>
Signed-off-by: John Ronciak <[EMAIL PROTECTED]>
---

 drivers/net/e100.c |  315 +++++++++++++++++++++++++++++-----------------------
 1 files changed, 174 insertions(+), 141 deletions(-)

diff --git a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -156,7 +156,7 @@
 
 #define DRV_NAME               "e100"
 #define DRV_EXT                "-NAPI"
-#define DRV_VERSION            "3.4.14-k4"DRV_EXT
+#define DRV_VERSION            "3.5.10-k2"DRV_EXT
 #define DRV_DESCRIPTION                "Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT          "Copyright(c) 1999-2005 Intel Corporation"
 #define PFX                    DRV_NAME ": "
@@ -872,141 +872,6 @@ err_unlock:
        return err;
 }
 
-static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
-{
-       u32 data_out = 0;
-       unsigned int i;
-
-       writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
-
-       for(i = 0; i < 100; i++) {
-               udelay(20);
-               if((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready)
-                       break;
-       }
-
-       DPRINTK(HW, DEBUG,
-               "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
-               dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);
-       return (u16)data_out;
-}
-
-static int mdio_read(struct net_device *netdev, int addr, int reg)
-{
-       return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
-}
-
-static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
-{
-       mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
-}
-
-static void e100_get_defaults(struct nic *nic)
-{
-       struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
-       struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
-
-       pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
-       /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
-       nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
-       if(nic->mac == mac_unknown)
-               nic->mac = mac_82557_D100_A;
-
-       nic->params.rfds = rfds;
-       nic->params.cbs = cbs;
-
-       /* Quadwords to DMA into FIFO before starting frame transmit */
-       nic->tx_threshold = 0xE0;
-
-       /* no interrupt for every tx completion, delay = 256us if not 557*/
-       nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |
-               ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
-
-       /* Template for a freshly allocated RFD */
-       nic->blank_rfd.command = cpu_to_le16(cb_el);
-       nic->blank_rfd.rbd = 0xFFFFFFFF;
-       nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
-
-       /* MII setup */
-       nic->mii.phy_id_mask = 0x1F;
-       nic->mii.reg_num_mask = 0x1F;
-       nic->mii.dev = nic->netdev;
-       nic->mii.mdio_read = mdio_read;
-       nic->mii.mdio_write = mdio_write;
-}
-
-static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
-{
-       struct config *config = &cb->u.config;
-       u8 *c = (u8 *)config;
-
-       cb->command = cpu_to_le16(cb_config);
-
-       memset(config, 0, sizeof(struct config));
-
-       config->byte_count = 0x16;              /* bytes in this struct */
-       config->rx_fifo_limit = 0x8;            /* bytes in FIFO before DMA */
-       config->direct_rx_dma = 0x1;            /* reserved */
-       config->standard_tcb = 0x1;             /* 1=standard, 0=extended */
-       config->standard_stat_counter = 0x1;    /* 1=standard, 0=extended */
-       config->rx_discard_short_frames = 0x1;  /* 1=discard, 0=pass */
-       config->tx_underrun_retry = 0x3;        /* # of underrun retries */
-       config->mii_mode = 0x1;                 /* 1=MII mode, 0=503 mode */
-       config->pad10 = 0x6;
-       config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
-       config->preamble_length = 0x2;          /* 0=1, 1=3, 2=7, 3=15 bytes */
-       config->ifs = 0x6;                      /* x16 = inter frame spacing */
-       config->ip_addr_hi = 0xF2;              /* ARP IP filter - not used */
-       config->pad15_1 = 0x1;
-       config->pad15_2 = 0x1;
-       config->crs_or_cdt = 0x0;               /* 0=CRS only, 1=CRS or CDT */
-       config->fc_delay_hi = 0x40;             /* time delay for fc frame */
-       config->tx_padding = 0x1;               /* 1=pad short frames */
-       config->fc_priority_threshold = 0x7;    /* 7=priority fc disabled */
-       config->pad18 = 0x1;
-       config->full_duplex_pin = 0x1;          /* 1=examine FDX# pin */
-       config->pad20_1 = 0x1F;
-       config->fc_priority_location = 0x1;     /* 1=byte#31, 0=byte#19 */
-       config->pad21_1 = 0x5;
-
-       config->adaptive_ifs = nic->adaptive_ifs;
-       config->loopback = nic->loopback;
-
-       if(nic->mii.force_media && nic->mii.full_duplex)
-               config->full_duplex_force = 0x1;        /* 1=force, 0=auto */
-
-       if(nic->flags & promiscuous || nic->loopback) {
-               config->rx_save_bad_frames = 0x1;       /* 1=save, 0=discard */
-               config->rx_discard_short_frames = 0x0;  /* 1=discard, 0=save */
-               config->promiscuous_mode = 0x1;         /* 1=on, 0=off */
-       }
-
-       if(nic->flags & multicast_all)
-               config->multicast_all = 0x1;            /* 1=accept, 0=no */
-
-       /* disable WoL when up */
-       if(netif_running(nic->netdev) || !(nic->flags & wol_magic))
-               config->magic_packet_disable = 0x1;     /* 1=off, 0=on */
-
-       if(nic->mac >= mac_82558_D101_A4) {
-               config->fc_disable = 0x1;       /* 1=Tx fc off, 0=Tx fc on */
-               config->mwi_enable = 0x1;       /* 1=enable, 0=disable */
-               config->standard_tcb = 0x0;     /* 1=standard, 0=extended */
-               config->rx_long_ok = 0x1;       /* 1=VLANs ok, 0=standard */
-               if(nic->mac >= mac_82559_D101M)
-                       config->tno_intr = 0x1;         /* TCO stats enable */
-               else
-                       config->standard_stat_counter = 0x0;
-       }
-
-       DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-               c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
-       DPRINTK(HW, DEBUG, "[08-15]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-               c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
-       DPRINTK(HW, DEBUG, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
-               c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
-}
-
 /********************************************************/
 /*  Micro code for 8086:1229 Rev 8                      */
 /********************************************************/
@@ -1145,7 +1010,7 @@ static void e100_configure(struct nic *n
 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
 }
 
-static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff 
*skb)
+static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff 
*skb)
 {
 /* *INDENT-OFF* */
        static struct {
@@ -1238,7 +1103,6 @@ static void e100_load_ucode(struct nic *
 #define BUNDLEMAX (u16)6
 #define INTDELAY (u16)1536 /* 0x600 */
 
-       /* do not load u-code for ICH devices */
        if (nic->flags & ich)
                goto noloaducode;
 
@@ -1259,12 +1123,181 @@ static void e100_load_ucode(struct nic *
 
                for (i = 0; i < UCODE_SIZE; i++)
                        cb->u.ucode[i] = cpu_to_le32(ucode[i]);
-               cb->command = cpu_to_le16(cb_ucode);
+               cb->command = cpu_to_le16(cb_ucode | cb_el);
                return;
        }
 
 noloaducode:
-       cb->command = cpu_to_le16(cb_nop);
+       cb->command = cpu_to_le16(cb_nop | cb_el);
+}
+
+static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb,
+       void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
+{
+       int err = 0, counter = 50;
+       struct cb *cb = nic->cb_to_clean;
+
+       if ((err = e100_exec_cb(nic, NULL, e100_setup_ucode)))
+               DPRINTK(PROBE,ERR, "ucode cmd failed with error %d\n", err);
+               
+       /* must restart cuc */
+       nic->cuc_cmd = cuc_start;
+
+       /* wait for completion */
+       e100_write_flush(nic);
+       udelay(10);
+
+       /* wait for possibly (ouch) 500ms */
+       while (!(cb->status & cpu_to_le16(cb_complete))) {
+               msleep(10);
+               if (!--counter) break;
+       }
+       
+       /* ack any interupts, something could have been set */
+       writeb(~0, &nic->csr->scb.stat_ack);
+
+       /* if the command failed, or is not OK, notify and return */
+       if (!counter || !(cb->status & cpu_to_le16(cb_ok))) {
+               DPRINTK(PROBE,ERR, "ucode load failed\n");
+               err = -EPERM;
+       }
+       
+       return err;
+}
+
+static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
+{
+       u32 data_out = 0;
+       unsigned int i;
+
+       writel((reg << 16) | (addr << 21) | dir | data, &nic->csr->mdi_ctrl);
+
+       for(i = 0; i < 100; i++) {
+               udelay(20);
+               if((data_out = readl(&nic->csr->mdi_ctrl)) & mdi_ready)
+                       break;
+       }
+
+       DPRINTK(HW, DEBUG,
+               "%s:addr=%d, reg=%d, data_in=0x%04X, data_out=0x%04X\n",
+               dir == mdi_read ? "READ" : "WRITE", addr, reg, data, data_out);
+       return (u16)data_out;
+}
+
+static int mdio_read(struct net_device *netdev, int addr, int reg)
+{
+       return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
+}
+
+static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
+{
+       mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
+}
+
+static void e100_get_defaults(struct nic *nic)
+{
+       struct param_range rfds = { .min = 16, .max = 256, .count = 256 };
+       struct param_range cbs  = { .min = 64, .max = 256, .count = 128 };
+
+       pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id);
+       /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */
+       nic->mac = (nic->flags & ich) ? mac_82559_D101M : nic->rev_id;
+       if(nic->mac == mac_unknown)
+               nic->mac = mac_82557_D100_A;
+
+       nic->params.rfds = rfds;
+       nic->params.cbs = cbs;
+
+       /* Quadwords to DMA into FIFO before starting frame transmit */
+       nic->tx_threshold = 0xE0;
+
+       /* no interrupt for every tx completion, delay = 256us if not 557*/
+       nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf |
+               ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i));
+
+       /* Template for a freshly allocated RFD */
+       nic->blank_rfd.command = cpu_to_le16(cb_el);
+       nic->blank_rfd.rbd = 0xFFFFFFFF;
+       nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
+
+       /* MII setup */
+       nic->mii.phy_id_mask = 0x1F;
+       nic->mii.reg_num_mask = 0x1F;
+       nic->mii.dev = nic->netdev;
+       nic->mii.mdio_read = mdio_read;
+       nic->mii.mdio_write = mdio_write;
+}
+
+static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
+{
+       struct config *config = &cb->u.config;
+       u8 *c = (u8 *)config;
+
+       cb->command = cpu_to_le16(cb_config);
+
+       memset(config, 0, sizeof(struct config));
+
+       config->byte_count = 0x16;              /* bytes in this struct */
+       config->rx_fifo_limit = 0x8;            /* bytes in FIFO before DMA */
+       config->direct_rx_dma = 0x1;            /* reserved */
+       config->standard_tcb = 0x1;             /* 1=standard, 0=extended */
+       config->standard_stat_counter = 0x1;    /* 1=standard, 0=extended */
+       config->rx_discard_short_frames = 0x1;  /* 1=discard, 0=pass */
+       config->tx_underrun_retry = 0x3;        /* # of underrun retries */
+       config->mii_mode = 0x1;                 /* 1=MII mode, 0=503 mode */
+       config->pad10 = 0x6;
+       config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
+       config->preamble_length = 0x2;          /* 0=1, 1=3, 2=7, 3=15 bytes */
+       config->ifs = 0x6;                      /* x16 = inter frame spacing */
+       config->ip_addr_hi = 0xF2;              /* ARP IP filter - not used */
+       config->pad15_1 = 0x1;
+       config->pad15_2 = 0x1;
+       config->crs_or_cdt = 0x0;               /* 0=CRS only, 1=CRS or CDT */
+       config->fc_delay_hi = 0x40;             /* time delay for fc frame */
+       config->tx_padding = 0x1;               /* 1=pad short frames */
+       config->fc_priority_threshold = 0x7;    /* 7=priority fc disabled */
+       config->pad18 = 0x1;
+       config->full_duplex_pin = 0x1;          /* 1=examine FDX# pin */
+       config->pad20_1 = 0x1F;
+       config->fc_priority_location = 0x1;     /* 1=byte#31, 0=byte#19 */
+       config->pad21_1 = 0x5;
+
+       config->adaptive_ifs = nic->adaptive_ifs;
+       config->loopback = nic->loopback;
+
+       if(nic->mii.force_media && nic->mii.full_duplex)
+               config->full_duplex_force = 0x1;        /* 1=force, 0=auto */
+
+       if(nic->flags & promiscuous || nic->loopback) {
+               config->rx_save_bad_frames = 0x1;       /* 1=save, 0=discard */
+               config->rx_discard_short_frames = 0x0;  /* 1=discard, 0=save */
+               config->promiscuous_mode = 0x1;         /* 1=on, 0=off */
+       }
+
+       if(nic->flags & multicast_all)
+               config->multicast_all = 0x1;            /* 1=accept, 0=no */
+
+       /* disable WoL when up */
+       if(netif_running(nic->netdev) || !(nic->flags & wol_magic))
+               config->magic_packet_disable = 0x1;     /* 1=off, 0=on */
+
+       if(nic->mac >= mac_82558_D101_A4) {
+               config->fc_disable = 0x1;       /* 1=Tx fc off, 0=Tx fc on */
+               config->mwi_enable = 0x1;       /* 1=enable, 0=disable */
+               config->standard_tcb = 0x0;     /* 1=standard, 0=extended */
+               config->rx_long_ok = 0x1;       /* 1=VLANs ok, 0=standard */
+               if(nic->mac >= mac_82559_D101M)
+                       config->tno_intr = 0x1;         /* TCO stats enable */
+               else
+                       config->standard_stat_counter = 0x0;
+       }
+
+       DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+               c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
+       DPRINTK(HW, DEBUG, "[08-15]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+               c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15]);
+       DPRINTK(HW, DEBUG, "[16-23]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
+               c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
 }
 
 static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
@@ -1363,7 +1396,7 @@ static int e100_hw_init(struct nic *nic)
                return err;
        if((err = e100_exec_cmd(nic, ruc_load_base, 0)))
                return err;
-       if((err = e100_exec_cb(nic, NULL, e100_load_ucode)))
+       if ((err = e100_exec_cb_wait(nic, NULL, e100_setup_ucode)))
                return err;
        if((err = e100_exec_cb(nic, NULL, e100_configure)))
                return err;

Reply via email to