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;