From: Sepherosa Ziehau Date: Tue, 28 Jun 2011 05:45:01 +0000 (+0800) Subject: em(4)/emx(4): Update to Intel's 7.1.7 X-Git-Tag: v2.12.0~422 X-Git-Url: http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/2d0e5700f20de35b08afb96e1871776a16447d99 em(4)/emx(4): Update to Intel's 7.1.7 - Restore stock version of e1000_read_mac_addr_generic(); if this function is called after hardware reset, it just works as expected. - For em(4), add 82567/82577/82578/82579/82583, PCH and PCH2 support. - For em(4) and emx(4) o Reorganize hardware initialization sequence o Fix ITR and EIAC settings for 82574 o Fix hardware control support for chips with AMT --- diff --git a/sys/dev/netif/em/if_em.c b/sys/dev/netif/em/if_em.c index 744306e..c319d52 100644 --- a/sys/dev/netif/em/if_em.c +++ b/sys/dev/netif/em/if_em.c @@ -135,7 +135,7 @@ #include #define EM_NAME "Intel(R) PRO/1000 Network Connection " -#define EM_VER " 6.9.6" +#define EM_VER " 7.1.7" #define _EM_DEVICE(id, ret) \ { EM_VENDOR_ID, E1000_DEV_ID_##id, ret, EM_NAME #id EM_VER } @@ -208,6 +208,8 @@ static const struct em_vendor_info em_vendor_info_array[] = { EM_EMX_DEVICE(82573E_IAMT), EM_EMX_DEVICE(82573L), + EM_DEVICE(82583V), + EM_EMX_DEVICE(80003ES2LAN_COPPER_SPT), EM_EMX_DEVICE(80003ES2LAN_SERDES_SPT), EM_EMX_DEVICE(80003ES2LAN_COPPER_DPT), @@ -220,6 +222,7 @@ static const struct em_vendor_info em_vendor_info_array[] = { EM_DEVICE(ICH8_IFE_GT), EM_DEVICE(ICH8_IFE_G), EM_DEVICE(ICH8_IGP_M), + EM_DEVICE(ICH8_82567V_3), EM_DEVICE(ICH9_IGP_M_AMT), EM_DEVICE(ICH9_IGP_AMT), @@ -232,12 +235,22 @@ static const struct em_vendor_info em_vendor_info_array[] = { EM_DEVICE(ICH9_BM), EM_EMX_DEVICE(82574L), + EM_EMX_DEVICE(82574LA), EM_DEVICE(ICH10_R_BM_LM), EM_DEVICE(ICH10_R_BM_LF), EM_DEVICE(ICH10_R_BM_V), EM_DEVICE(ICH10_D_BM_LM), EM_DEVICE(ICH10_D_BM_LF), + EM_DEVICE(ICH10_D_BM_V), + + EM_DEVICE(PCH_M_HV_LM), + EM_DEVICE(PCH_M_HV_LC), + EM_DEVICE(PCH_D_HV_DM), + EM_DEVICE(PCH_D_HV_DC), + + EM_DEVICE(PCH2_LV_LM), + EM_DEVICE(PCH2_LV_V), /* required last entry */ EM_DEVICE_NULL @@ -291,7 +304,7 @@ static int em_get_hw_info(struct adapter *); static int em_is_valid_eaddr(const uint8_t *); static int em_alloc_pci_res(struct adapter *); static void em_free_pci_res(struct adapter *); -static int em_hw_init(struct adapter *); +static int em_reset(struct adapter *); static void em_setup_ifp(struct adapter *); static void em_init_tx_unit(struct adapter *); static void em_init_rx_unit(struct adapter *); @@ -301,6 +314,7 @@ static void em_disable_promisc(struct adapter *); static void em_set_multi(struct adapter *); static void em_update_link_status(struct adapter *); static void em_smartspeed(struct adapter *); +static void em_set_itr(struct adapter *, uint32_t); /* Hardware workarounds */ static int em_82547_fifo_workaround(struct adapter *, int); @@ -413,7 +427,7 @@ em_attach(device_t dev) struct ifnet *ifp = &adapter->arpcom.ac_if; int tsize, rsize; int error = 0; - uint16_t eeprom_data, device_id; + uint16_t eeprom_data, device_id, apme_mask; adapter->dev = adapter->osdep.dev = dev; @@ -439,8 +453,10 @@ em_attach(device_t dev) * and this must happen after the MAC is identified. */ if (adapter->hw.mac.type == e1000_ich8lan || + adapter->hw.mac.type == e1000_ich9lan || adapter->hw.mac.type == e1000_ich10lan || - adapter->hw.mac.type == e1000_ich9lan) { + adapter->hw.mac.type == e1000_pchlan || + adapter->hw.mac.type == e1000_pch2lan) { adapter->flash_rid = EM_BAR_FLASH; adapter->flash = bus_alloc_resource_any(dev, SYS_RES_MEMORY, @@ -577,6 +593,22 @@ em_attach(device_t dev) } adapter->rx_desc_base = adapter->rxdma.dma_vaddr; + /* Allocate multicast array memory. */ + adapter->mta = kmalloc(ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES, + M_DEVBUF, M_WAITOK); + + /* Indicate SOL/IDER usage */ + if (e1000_check_reset_block(&adapter->hw)) { + device_printf(dev, + "PHY reset is blocked due to SOL/IDER session.\n"); + } + + /* + * Start from a known state, this is important in reading the + * nvm and mac from that. + */ + e1000_reset_hw(&adapter->hw); + /* Make sure we have a good EEPROM before we read from it */ if (e1000_validate_nvm_checksum(&adapter->hw) < 0) { /* @@ -592,13 +624,6 @@ em_attach(device_t dev) } } - /* Initialize the hardware */ - error = em_hw_init(adapter); - if (error) { - device_printf(dev, "Unable to initialize the hardware\n"); - goto fail; - } - /* Copy the permanent MAC address out of the EEPROM */ if (e1000_read_mac_addr(&adapter->hw) < 0) { device_printf(dev, "EEPROM read error while reading MAC" @@ -629,38 +654,28 @@ em_attach(device_t dev) /* Manually turn off all interrupts */ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); - /* Setup OS specific network interface */ - em_setup_ifp(adapter); - - /* Add sysctl tree, must after em_setup_ifp() */ - em_add_sysctl(adapter); - - /* Initialize statistics */ - em_update_stats(adapter); - - adapter->hw.mac.get_link_status = 1; - em_update_link_status(adapter); - - /* Indicate SOL/IDER usage */ - if (e1000_check_reset_block(&adapter->hw)) { - device_printf(dev, - "PHY reset is blocked due to SOL/IDER session.\n"); - } - /* Determine if we have to control management hardware */ adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw); /* * Setup Wake-on-Lan */ + apme_mask = EM_EEPROM_APME; + eeprom_data = 0; switch (adapter->hw.mac.type) { case e1000_82542: case e1000_82543: break; + case e1000_82573: + case e1000_82583: + adapter->has_amt = 1; + /* FALL THROUGH */ + case e1000_82546: case e1000_82546_rev_3: case e1000_82571: + case e1000_82572: case e1000_80003es2lan: if (adapter->hw.bus.func == 1) { e1000_read_nvm(&adapter->hw, @@ -669,17 +684,26 @@ em_attach(device_t dev) e1000_read_nvm(&adapter->hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); } - eeprom_data &= EM_EEPROM_APME; + break; + + case e1000_ich8lan: + case e1000_ich9lan: + case e1000_ich10lan: + case e1000_pchlan: + case e1000_pch2lan: + apme_mask = E1000_WUC_APME; + adapter->has_amt = TRUE; + eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC); break; default: - /* APME bit in EEPROM is mapped to WUC.APME */ - eeprom_data = - E1000_READ_REG(&adapter->hw, E1000_WUC) & E1000_WUC_APME; + e1000_read_nvm(&adapter->hw, + NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); break; } - if (eeprom_data) - adapter->wol = E1000_WUFC_MAG; + if (eeprom_data & apme_mask) + adapter->wol = E1000_WUFC_MAG | E1000_WUFC_MC; + /* * We have the eeprom settings, now apply the special cases * where the eeprom may be wrong or the board won't support @@ -719,6 +743,25 @@ em_attach(device_t dev) /* XXX disable wol */ adapter->wol = 0; + /* Setup OS specific network interface */ + em_setup_ifp(adapter); + + /* Add sysctl tree, must after em_setup_ifp() */ + em_add_sysctl(adapter); + + /* Reset the hardware */ + error = em_reset(adapter); + if (error) { + device_printf(dev, "Unable to reset the hardware\n"); + goto fail; + } + + /* Initialize statistics */ + em_update_stats(adapter); + + adapter->hw.mac.get_link_status = 1; + em_update_link_status(adapter); + /* Do we need workaround for 82544 PCI-X adapter? */ if (adapter->hw.bus.type == e1000_bus_type_pcix && adapter->hw.mac.type == e1000_82544) @@ -753,6 +796,11 @@ em_attach(device_t dev) if (adapter->tx_int_nsegs < adapter->oact_tx_desc) adapter->tx_int_nsegs = adapter->oact_tx_desc; + /* Non-AMT based hardware can now take control from firmware */ + if (adapter->has_manage && !adapter->has_amt && + adapter->hw.mac.type >= e1000_82571) + em_get_hw_control(adapter); + error = bus_setup_intr(dev, adapter->intr_res, INTR_MPSAFE, em_intr, adapter, &adapter->intr_tag, ifp->if_serializer); @@ -785,13 +833,7 @@ em_detach(device_t dev) e1000_phy_hw_reset(&adapter->hw); em_rel_mgmt(adapter); - - if ((adapter->hw.mac.type == e1000_82573 || - adapter->hw.mac.type == e1000_ich8lan || - adapter->hw.mac.type == e1000_ich10lan || - adapter->hw.mac.type == e1000_ich9lan) && - e1000_check_mng_mode(&adapter->hw)) - em_rel_hw_control(adapter); + em_rel_hw_control(adapter); if (adapter->wol) { E1000_WRITE_REG(&adapter->hw, E1000_WUC, @@ -805,6 +847,8 @@ em_detach(device_t dev) lwkt_serialize_exit(ifp->if_serializer); ether_ifdetach(ifp); + } else { + em_rel_hw_control(adapter); } bus_generic_detach(dev); @@ -849,19 +893,13 @@ em_suspend(device_t dev) em_stop(adapter); em_rel_mgmt(adapter); + em_rel_hw_control(adapter); - if ((adapter->hw.mac.type == e1000_82573 || - adapter->hw.mac.type == e1000_ich8lan || - adapter->hw.mac.type == e1000_ich10lan || - adapter->hw.mac.type == e1000_ich9lan) && - e1000_check_mng_mode(&adapter->hw)) - em_rel_hw_control(adapter); - - if (adapter->wol) { + if (adapter->wol) { E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol); em_enable_wol(dev); - } + } lwkt_serialize_exit(ifp->if_serializer); @@ -963,13 +1001,19 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) case e1000_82572: case e1000_ich9lan: case e1000_ich10lan: + case e1000_pch2lan: case e1000_82574: case e1000_80003es2lan: max_frame_size = 9234; break; + case e1000_pchlan: + max_frame_size = 4096; + break; + /* Adapters that do not support jumbo frames */ case e1000_82542: + case e1000_82583: case e1000_ich8lan: max_frame_size = ETHER_MAX_LEN; break; @@ -1156,17 +1200,23 @@ em_init(void *xsc) break; case e1000_82574: + case e1000_82583: pba = E1000_PBA_20K; /* 20K for Rx, 20K for Tx */ break; + case e1000_ich8lan: + pba = E1000_PBA_8K; + break; + case e1000_ich9lan: case e1000_ich10lan: #define E1000_PBA_10K 0x000A pba = E1000_PBA_10K; break; - case e1000_ich8lan: - pba = E1000_PBA_8K; + case e1000_pchlan: + case e1000_pch2lan: + pba = E1000_PBA_26K; break; default: @@ -1196,9 +1246,9 @@ em_init(void *xsc) E1000_RAR_ENTRIES - 1); } - /* Initialize the hardware */ - if (em_hw_init(adapter)) { - device_printf(dev, "Unable to initialize the hardware\n"); + /* Reset the hardware */ + if (em_reset(adapter)) { + device_printf(dev, "Unable to reset the hardware\n"); /* XXX em_stop()? */ return; } @@ -1256,6 +1306,7 @@ em_init(void *xsc) tmp |= E1000_CTRL_EXT_PBA_CLR; E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp); /* + * XXX MSIX * Set the IVAR - interrupt vector routing. * Each nibble represents a vector, high bit * is enable, other 3 bits are the MSIX table @@ -1276,6 +1327,11 @@ em_init(void *xsc) #endif /* DEVICE_POLLING */ em_enable_intr(adapter); + /* AMT based hardware can now take control from firmware */ + if (adapter->has_manage && adapter->has_amt && + adapter->hw.mac.type >= e1000_82571) + em_get_hw_control(adapter); + /* Don't reset the phy next time init gets called */ adapter->hw.phy.reset_disable = TRUE; } @@ -1826,9 +1882,12 @@ em_set_multi(struct adapter *adapter) struct ifnet *ifp = &adapter->arpcom.ac_if; struct ifmultiaddr *ifma; uint32_t reg_rctl = 0; - uint8_t mta[512]; /* Largest MTS is 4096 bits */ + uint8_t *mta; int mcnt = 0; + mta = adapter->mta; + bzero(mta, ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES); + if (adapter->hw.mac.type == e1000_82542 && adapter->hw.revision_id == E1000_REVISION_2) { reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL); @@ -1945,15 +2004,13 @@ em_update_link_status(struct adapter *adapter) * Check if we should enable/disable SPEED_MODE bit on * 82571/82572 */ - if (hw->mac.type == e1000_82571 || - hw->mac.type == e1000_82572) { + if (adapter->link_speed != SPEED_1000 && + (hw->mac.type == e1000_82571 || + hw->mac.type == e1000_82572)) { int tarc0; tarc0 = E1000_READ_REG(hw, E1000_TARC(0)); - if (adapter->link_speed != SPEED_1000) - tarc0 &= ~SPEED_MODE_BIT; - else - tarc0 |= SPEED_MODE_BIT; + tarc0 &= ~SPEED_MODE_BIT; E1000_WRITE_REG(hw, E1000_TARC(0), tarc0); } if (bootverbose) { @@ -2153,22 +2210,11 @@ em_free_pci_res(struct adapter *adapter) } static int -em_hw_init(struct adapter *adapter) +em_reset(struct adapter *adapter) { device_t dev = adapter->dev; uint16_t rx_buffer_size; - /* Issue a global reset */ - e1000_reset_hw(&adapter->hw); - - /* Get control from any management/hw control */ - if ((adapter->hw.mac.type == e1000_82573 || - adapter->hw.mac.type == e1000_ich8lan || - adapter->hw.mac.type == e1000_ich10lan || - adapter->hw.mac.type == e1000_ich9lan) && - e1000_check_mng_mode(&adapter->hw)) - em_get_hw_control(adapter); - /* When hardware is reset, fifo_head is also reset */ adapter->tx_fifo_head = 0; @@ -2211,14 +2257,41 @@ em_hw_init(struct adapter *adapter) adapter->hw.fc.pause_time = 0xFFFF; else adapter->hw.fc.pause_time = EM_FC_PAUSE_TIME; + adapter->hw.fc.send_xon = TRUE; + adapter->hw.fc.requested_mode = e1000_fc_full; + /* Workaround: no TX flow ctrl for PCH */ + if (adapter->hw.mac.type == e1000_pchlan) + adapter->hw.fc.requested_mode = e1000_fc_rx_pause; + + /* Override - settings for PCH2LAN, ya its magic :) */ + if (adapter->hw.mac.type == e1000_pch2lan) { + adapter->hw.fc.high_water = 0x5C20; + adapter->hw.fc.low_water = 0x5048; + adapter->hw.fc.pause_time = 0x0650; + adapter->hw.fc.refresh_time = 0x0400; + + /* Jumbos need adjusted PBA */ + if (adapter->arpcom.ac_if.if_mtu > ETHERMTU) + E1000_WRITE_REG(&adapter->hw, E1000_PBA, 12); + else + E1000_WRITE_REG(&adapter->hw, E1000_PBA, 26); + } + + /* Issue a global reset */ + e1000_reset_hw(&adapter->hw); + if (adapter->hw.mac.type >= e1000_82544) + E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0); + if (e1000_init_hw(&adapter->hw) < 0) { device_printf(dev, "Hardware Initialization Failed\n"); return (EIO); } + E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); + e1000_get_phy_info(&adapter->hw); e1000_check_for_link(&adapter->hw); return (0); @@ -3030,7 +3103,7 @@ em_init_rx_unit(struct adapter *adapter) { struct ifnet *ifp = &adapter->arpcom.ac_if; uint64_t bus_addr; - uint32_t rctl, rxcsum; + uint32_t rctl; /* * Make sure receives are disabled while setting @@ -3040,16 +3113,17 @@ em_init_rx_unit(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN); if (adapter->hw.mac.type >= e1000_82540) { + uint32_t itr; + /* * Set the interrupt throttling rate. Value is calculated * as ITR = 1 / (INT_THROTTLE_CEIL * 256ns) */ - if (adapter->int_throttle_ceil) { - E1000_WRITE_REG(&adapter->hw, E1000_ITR, - 1000000000 / 256 / adapter->int_throttle_ceil); - } else { - E1000_WRITE_REG(&adapter->hw, E1000_ITR, 0); - } + if (adapter->int_throttle_ceil) + itr = 1000000000 / 256 / adapter->int_throttle_ceil; + else + itr = 0; + em_set_itr(adapter, itr); } /* Disable accelerated ackknowledge */ @@ -3058,7 +3132,30 @@ em_init_rx_unit(struct adapter *adapter) E1000_RFCTL, E1000_RFCTL_ACK_DIS); } - /* Setup the Base and Length of the Rx Descriptor Ring */ + /* Receive Checksum Offload for TCP and UDP */ + if (ifp->if_capenable & IFCAP_RXCSUM) { + uint32_t rxcsum; + + rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM); + rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); + E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum); + } + + /* + * XXX TEMPORARY WORKAROUND: on some systems with 82573 + * long latencies are observed, like Lenovo X60. This + * change eliminates the problem, but since having positive + * values in RDTR is a known source of problems on other + * platforms another solution is being sought. + */ + if (em_82573_workaround && adapter->hw.mac.type == e1000_82573) { + E1000_WRITE_REG(&adapter->hw, E1000_RADV, EM_RADV_82573); + E1000_WRITE_REG(&adapter->hw, E1000_RDTR, EM_RDTR_82573); + } + + /* + * Setup the Base and Length of the Rx Descriptor Ring + */ bus_addr = adapter->rxdma.dma_paddr; E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0), adapter->num_rx_desc * sizeof(struct e1000_rx_desc)); @@ -3067,6 +3164,31 @@ em_init_rx_unit(struct adapter *adapter) E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0), (uint32_t)bus_addr); + /* + * Setup the HW Rx Head and Tail Descriptor Pointers + */ + E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0); + E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1); + + /* Set early receive threshold on appropriate hw */ + if (((adapter->hw.mac.type == e1000_ich9lan) || + (adapter->hw.mac.type == e1000_pch2lan) || + (adapter->hw.mac.type == e1000_ich10lan)) && + (ifp->if_mtu > ETHERMTU)) { + uint32_t rxdctl; + + rxdctl = E1000_READ_REG(&adapter->hw, E1000_RXDCTL(0)); + E1000_WRITE_REG(&adapter->hw, E1000_RXDCTL(0), rxdctl | 3); + E1000_WRITE_REG(&adapter->hw, E1000_ERT, 0x100 | (1 << 13)); + } + + if (adapter->hw.mac.type == e1000_pch2lan) { + if (ifp->if_mtu > ETHERMTU) + e1000_lv_jumbo_workaround_ich8lan(&adapter->hw, TRUE); + else + e1000_lv_jumbo_workaround_ich8lan(&adapter->hw, FALSE); + } + /* Setup the Receive Control Register */ rctl &= ~(3 << E1000_RCTL_MO_SHIFT); rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | @@ -3108,31 +3230,6 @@ em_init_rx_unit(struct adapter *adapter) else rctl &= ~E1000_RCTL_LPE; - /* Receive Checksum Offload for TCP and UDP */ - if (ifp->if_capenable & IFCAP_RXCSUM) { - rxcsum = E1000_READ_REG(&adapter->hw, E1000_RXCSUM); - rxcsum |= (E1000_RXCSUM_IPOFL | E1000_RXCSUM_TUOFL); - E1000_WRITE_REG(&adapter->hw, E1000_RXCSUM, rxcsum); - } - - /* - * XXX TEMPORARY WORKAROUND: on some systems with 82573 - * long latencies are observed, like Lenovo X60. This - * change eliminates the problem, but since having positive - * values in RDTR is a known source of problems on other - * platforms another solution is being sought. - */ - if (em_82573_workaround && adapter->hw.mac.type == e1000_82573) { - E1000_WRITE_REG(&adapter->hw, E1000_RADV, EM_RADV_82573); - E1000_WRITE_REG(&adapter->hw, E1000_RDTR, EM_RDTR_82573); - } - - /* - * Setup the HW Rx Head and Tail Descriptor Pointers - */ - E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0); - E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1); - /* Enable Receives */ E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl); } @@ -3353,8 +3450,18 @@ em_rxcsum(struct adapter *adapter, struct e1000_rx_desc *rx_desc, static void em_enable_intr(struct adapter *adapter) { + uint32_t ims_mask = IMS_ENABLE_MASK; + lwkt_serialize_handler_enable(adapter->arpcom.ac_if.if_serializer); - E1000_WRITE_REG(&adapter->hw, E1000_IMS, IMS_ENABLE_MASK); + +#if 0 + /* XXX MSIX */ + if (adapter->hw.mac.type == e1000_82574) { + E1000_WRITE_REG(&adapter->hw, EM_EIAC, EM_MSIX_MASK); + ims_mask |= EM_MSIX_MASK; + } +#endif + E1000_WRITE_REG(&adapter->hw, E1000_IMS, ims_mask); } static void @@ -3373,6 +3480,8 @@ em_disable_intr(struct adapter *adapter) if (adapter->hw.mac.type == e1000_82542 && adapter->hw.revision_id == E1000_REVISION_2) clear &= ~E1000_IMC_RXSEQ; + else if (adapter->hw.mac.type == e1000_82574) + E1000_WRITE_REG(&adapter->hw, EM_EIAC, 0); E1000_WRITE_REG(&adapter->hw, E1000_IMC, clear); @@ -3439,28 +3548,21 @@ em_rel_mgmt(struct adapter *adapter) static void em_get_hw_control(struct adapter *adapter) { - uint32_t ctrl_ext, swsm; - /* Let firmware know the driver has taken over */ - switch (adapter->hw.mac.type) { - case e1000_82573: + if (adapter->hw.mac.type == e1000_82573) { + uint32_t swsm; + swsm = E1000_READ_REG(&adapter->hw, E1000_SWSM); E1000_WRITE_REG(&adapter->hw, E1000_SWSM, swsm | E1000_SWSM_DRV_LOAD); - break; - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: - case e1000_ich8lan: - case e1000_ich9lan: - case e1000_ich10lan: + } else { + uint32_t ctrl_ext; + ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); - break; - default: - break; } + adapter->control_hw = 1; } /* @@ -3472,29 +3574,23 @@ em_get_hw_control(struct adapter *adapter) static void em_rel_hw_control(struct adapter *adapter) { - uint32_t ctrl_ext, swsm; + if (!adapter->control_hw) + return; + adapter->control_hw = 0; /* Let firmware taken over control of h/w */ - switch (adapter->hw.mac.type) { - case e1000_82573: + if (adapter->hw.mac.type == e1000_82573) { + uint32_t swsm; + swsm = E1000_READ_REG(&adapter->hw, E1000_SWSM); E1000_WRITE_REG(&adapter->hw, E1000_SWSM, swsm & ~E1000_SWSM_DRV_LOAD); - break; + } else { + uint32_t ctrl_ext; - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: - case e1000_ich8lan: - case e1000_ich9lan: - case e1000_ich10lan: ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT); E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); - break; - - default: - break; } } @@ -3948,7 +4044,7 @@ em_sysctl_int_throttle(SYSCTL_HANDLER_ARGS) adapter->int_throttle_ceil = 0; if (ifp->if_flags & IFF_RUNNING) - E1000_WRITE_REG(&adapter->hw, E1000_ITR, throttle); + em_set_itr(adapter, throttle); lwkt_serialize_exit(ifp->if_serializer); @@ -3995,3 +4091,21 @@ em_sysctl_int_tx_nsegs(SYSCTL_HANDLER_ARGS) return error; } + +static void +em_set_itr(struct adapter *adapter, uint32_t itr) +{ + E1000_WRITE_REG(&adapter->hw, E1000_ITR, itr); + if (adapter->hw.mac.type == e1000_82574) { + int i; + + /* + * When using MSIX interrupts we need to + * throttle using the EITR register + */ + for (i = 0; i < 4; ++i) { + E1000_WRITE_REG(&adapter->hw, + E1000_EITR_82574(i), itr); + } + } +} diff --git a/sys/dev/netif/em/if_em.h b/sys/dev/netif/em/if_em.h index d532e95..a45f801 100644 --- a/sys/dev/netif/em/if_em.h +++ b/sys/dev/netif/em/if_em.h @@ -276,6 +276,11 @@ struct adapter { /* Management and WOL features */ int wol; int has_manage; + int has_amt; + int control_hw; + + /* Multicast array memory */ + uint8_t *mta; /* Info about the board itself */ uint8_t link_active; diff --git a/sys/dev/netif/emx/if_emx.c b/sys/dev/netif/emx/if_emx.c index fbb631f..a72745c 100644 --- a/sys/dev/netif/emx/if_emx.c +++ b/sys/dev/netif/emx/if_emx.c @@ -158,6 +158,7 @@ static const struct emx_device { EMX_DEVICE(80003ES2LAN_SERDES_DPT), EMX_DEVICE(82574L), + EMX_DEVICE(82574LA), /* required last entry */ EMX_DEVICE_NULL @@ -214,7 +215,7 @@ static int emx_txcsum(struct emx_softc *, struct mbuf *, uint32_t *, uint32_t *); static int emx_is_valid_eaddr(const uint8_t *); -static int emx_hw_init(struct emx_softc *); +static int emx_reset(struct emx_softc *); static void emx_setup_ifp(struct emx_softc *); static void emx_init_tx_unit(struct emx_softc *); static void emx_init_rx_unit(struct emx_softc *); @@ -224,6 +225,7 @@ static void emx_disable_promisc(struct emx_softc *); static void emx_set_multi(struct emx_softc *); static void emx_update_link_status(struct emx_softc *); static void emx_smartspeed(struct emx_softc *); +static void emx_set_itr(struct emx_softc *, uint32_t); static void emx_print_debug_info(struct emx_softc *); static void emx_print_nvm_info(struct emx_softc *); @@ -397,7 +399,7 @@ emx_attach(device_t dev) struct emx_softc *sc = device_get_softc(dev); struct ifnet *ifp = &sc->arpcom.ac_if; int error = 0, i; - uint16_t eeprom_data, device_id; + uint16_t eeprom_data, device_id, apme_mask; lwkt_serialize_init(&sc->main_serialize); lwkt_serialize_init(&sc->tx_serialize); @@ -526,6 +528,22 @@ emx_attach(device_t dev) if (error) goto fail; + /* Allocate multicast array memory. */ + sc->mta = kmalloc(ETH_ADDR_LEN * EMX_MCAST_ADDR_MAX, + M_DEVBUF, M_WAITOK); + + /* Indicate SOL/IDER usage */ + if (e1000_check_reset_block(&sc->hw)) { + device_printf(dev, + "PHY reset is blocked due to SOL/IDER session.\n"); + } + + /* + * Start from a known state, this is important in reading the + * nvm and mac from that. + */ + e1000_reset_hw(&sc->hw); + /* Make sure we have a good EEPROM before we read from it */ if (e1000_validate_nvm_checksum(&sc->hw) < 0) { /* @@ -541,13 +559,6 @@ emx_attach(device_t dev) } } - /* Initialize the hardware */ - error = emx_hw_init(sc); - if (error) { - device_printf(dev, "Unable to initialize the hardware\n"); - goto fail; - } - /* Copy the permanent MAC address out of the EEPROM */ if (e1000_read_mac_addr(&sc->hw) < 0) { device_printf(dev, "EEPROM read error while reading MAC" @@ -561,35 +572,21 @@ emx_attach(device_t dev) goto fail; } - /* Manually turn off all interrupts */ - E1000_WRITE_REG(&sc->hw, E1000_IMC, 0xffffffff); - - /* Setup OS specific network interface */ - emx_setup_ifp(sc); - - /* Add sysctl tree, must after emx_setup_ifp() */ - emx_add_sysctl(sc); - - /* Initialize statistics */ - emx_update_stats(sc); - - sc->hw.mac.get_link_status = 1; - emx_update_link_status(sc); - - /* Indicate SOL/IDER usage */ - if (e1000_check_reset_block(&sc->hw)) { - device_printf(dev, - "PHY reset is blocked due to SOL/IDER session.\n"); - } - /* Determine if we have to control management hardware */ sc->has_manage = e1000_enable_mng_pass_thru(&sc->hw); /* * Setup Wake-on-Lan */ + apme_mask = EMX_EEPROM_APME; + eeprom_data = 0; switch (sc->hw.mac.type) { + case e1000_82573: + sc->has_amt = 1; + /* FALL THROUGH */ + case e1000_82571: + case e1000_82572: case e1000_80003es2lan: if (sc->hw.bus.func == 1) { e1000_read_nvm(&sc->hw, @@ -598,17 +595,16 @@ emx_attach(device_t dev) e1000_read_nvm(&sc->hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); } - eeprom_data &= EMX_EEPROM_APME; break; default: - /* APME bit in EEPROM is mapped to WUC.APME */ - eeprom_data = - E1000_READ_REG(&sc->hw, E1000_WUC) & E1000_WUC_APME; + e1000_read_nvm(&sc->hw, + NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); break; } - if (eeprom_data) - sc->wol = E1000_WUFC_MAG; + if (eeprom_data & apme_mask) + sc->wol = E1000_WUFC_MAG | E1000_WUFC_MC; + /* * We have the eeprom settings, now apply the special cases * where the eeprom may be wrong or the board won't support @@ -641,6 +637,25 @@ emx_attach(device_t dev) /* XXX disable wol */ sc->wol = 0; + /* Setup OS specific network interface */ + emx_setup_ifp(sc); + + /* Add sysctl tree, must after em_setup_ifp() */ + emx_add_sysctl(sc); + + /* Reset the hardware */ + error = emx_reset(sc); + if (error) { + device_printf(dev, "Unable to reset the hardware\n"); + goto fail; + } + + /* Initialize statistics */ + emx_update_stats(sc); + + sc->hw.mac.get_link_status = 1; + emx_update_link_status(sc); + sc->spare_tx_desc = EMX_TX_SPARE; /* @@ -659,6 +674,10 @@ emx_attach(device_t dev) if (sc->tx_int_nsegs < sc->oact_tx_desc) sc->tx_int_nsegs = sc->oact_tx_desc; + /* Non-AMT based hardware can now take control from firmware */ + if (sc->has_manage && !sc->has_amt) + emx_get_hw_control(sc); + error = bus_setup_intr(dev, sc->intr_res, INTR_MPSAFE, emx_intr, sc, &sc->intr_tag, &sc->main_serialize); if (error) { @@ -690,10 +709,7 @@ emx_detach(device_t dev) e1000_phy_hw_reset(&sc->hw); emx_rel_mgmt(sc); - - if (sc->hw.mac.type == e1000_82573 && - e1000_check_mng_mode(&sc->hw)) - emx_rel_hw_control(sc); + emx_rel_hw_control(sc); if (sc->wol) { E1000_WRITE_REG(&sc->hw, E1000_WUC, E1000_WUC_PME_EN); @@ -706,6 +722,8 @@ emx_detach(device_t dev) ifnet_deserialize_all(ifp); ether_ifdetach(ifp); + } else { + emx_rel_hw_control(sc); } bus_generic_detach(dev); @@ -745,16 +763,13 @@ emx_suspend(device_t dev) emx_stop(sc); emx_rel_mgmt(sc); + emx_rel_hw_control(sc); - if (sc->hw.mac.type == e1000_82573 && - e1000_check_mng_mode(&sc->hw)) - emx_rel_hw_control(sc); - - if (sc->wol) { + if (sc->wol) { E1000_WRITE_REG(&sc->hw, E1000_WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&sc->hw, E1000_WUFC, sc->wol); emx_enable_wol(dev); - } + } ifnet_deserialize_all(ifp); @@ -1055,8 +1070,8 @@ emx_init(void *xsc) } /* Initialize the hardware */ - if (emx_hw_init(sc)) { - device_printf(dev, "Unable to initialize the hardware\n"); + if (emx_reset(sc)) { + device_printf(dev, "Unable to reset the hardware\n"); /* XXX emx_stop()? */ return; } @@ -1125,6 +1140,7 @@ emx_init(void *xsc) tmp |= E1000_CTRL_EXT_PBA_CLR; E1000_WRITE_REG(&sc->hw, E1000_CTRL_EXT, tmp); /* + * XXX MSIX * Set the IVAR - interrupt vector routing. * Each nibble represents a vector, high bit * is enable, other 3 bits are the MSIX table @@ -1145,6 +1161,10 @@ emx_init(void *xsc) #endif /* IFPOLL_ENABLE */ emx_enable_intr(sc); + /* AMT based hardware can now take control from firmware */ + if (sc->has_manage && sc->has_amt) + emx_get_hw_control(sc); + /* Don't reset the phy next time init gets called */ sc->hw.phy.reset_disable = TRUE; } @@ -1491,9 +1511,12 @@ emx_set_multi(struct emx_softc *sc) struct ifnet *ifp = &sc->arpcom.ac_if; struct ifmultiaddr *ifma; uint32_t reg_rctl = 0; - uint8_t mta[512]; /* Largest MTS is 4096 bits */ + uint8_t *mta; int mcnt = 0; + mta = sc->mta; + bzero(mta, ETH_ADDR_LEN * EMX_MCAST_ADDR_MAX); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; @@ -1589,15 +1612,13 @@ emx_update_link_status(struct emx_softc *sc) * Check if we should enable/disable SPEED_MODE bit on * 82571EB/82572EI */ - if (hw->mac.type == e1000_82571 || - hw->mac.type == e1000_82572) { + if (sc->link_speed != SPEED_1000 && + (hw->mac.type == e1000_82571 || + hw->mac.type == e1000_82572)) { int tarc0; tarc0 = E1000_READ_REG(hw, E1000_TARC(0)); - if (sc->link_speed != SPEED_1000) - tarc0 &= ~EMX_TARC_SPEED_MODE; - else - tarc0 |= EMX_TARC_SPEED_MODE; + tarc0 &= ~EMX_TARC_SPEED_MODE; E1000_WRITE_REG(hw, E1000_TARC(0), tarc0); } if (bootverbose) { @@ -1676,19 +1697,11 @@ emx_stop(struct emx_softc *sc) } static int -emx_hw_init(struct emx_softc *sc) +emx_reset(struct emx_softc *sc) { device_t dev = sc->dev; uint16_t rx_buffer_size; - /* Issue a global reset */ - e1000_reset_hw(&sc->hw); - - /* Get control from any management/hw control */ - if (sc->hw.mac.type == e1000_82573 && - e1000_check_mng_mode(&sc->hw)) - emx_get_hw_control(sc); - /* Set up smart power down as default off on newer adapters. */ if (!emx_smart_pwr_down && (sc->hw.mac.type == e1000_82571 || @@ -1730,11 +1743,17 @@ emx_hw_init(struct emx_softc *sc) sc->hw.fc.send_xon = TRUE; sc->hw.fc.requested_mode = e1000_fc_full; + /* Issue a global reset */ + e1000_reset_hw(&sc->hw); + E1000_WRITE_REG(&sc->hw, E1000_WUC, 0); + if (e1000_init_hw(&sc->hw) < 0) { device_printf(dev, "Hardware Initialization Failed\n"); return (EIO); } + E1000_WRITE_REG(&sc->hw, E1000_VET, ETHERTYPE_VLAN); + e1000_get_phy_info(&sc->hw); e1000_check_for_link(&sc->hw); return (0); @@ -2593,7 +2612,7 @@ emx_init_rx_unit(struct emx_softc *sc) { struct ifnet *ifp = &sc->arpcom.ac_if; uint64_t bus_addr; - uint32_t rctl, rxcsum, rfctl; + uint32_t rctl, itr, rfctl; int i; /* @@ -2607,12 +2626,11 @@ emx_init_rx_unit(struct emx_softc *sc) * Set the interrupt throttling rate. Value is calculated * as ITR = 1 / (INT_THROTTLE_CEIL * 256ns) */ - if (sc->int_throttle_ceil) { - E1000_WRITE_REG(&sc->hw, E1000_ITR, - 1000000000 / 256 / sc->int_throttle_ceil); - } else { - E1000_WRITE_REG(&sc->hw, E1000_ITR, 0); - } + if (sc->int_throttle_ceil) + itr = 1000000000 / 256 / sc->int_throttle_ceil; + else + itr = 0; + emx_set_itr(sc, itr); /* Use extended RX descriptor */ rfctl = E1000_RFCTL_EXTEN; @@ -2623,39 +2641,6 @@ emx_init_rx_unit(struct emx_softc *sc) E1000_WRITE_REG(&sc->hw, E1000_RFCTL, rfctl); - /* Setup the Base and Length of the Rx Descriptor Ring */ - for (i = 0; i < sc->rx_ring_inuse; ++i) { - struct emx_rxdata *rdata = &sc->rx_data[i]; - - bus_addr = rdata->rx_desc_paddr; - E1000_WRITE_REG(&sc->hw, E1000_RDLEN(i), - rdata->num_rx_desc * sizeof(emx_rxdesc_t)); - E1000_WRITE_REG(&sc->hw, E1000_RDBAH(i), - (uint32_t)(bus_addr >> 32)); - E1000_WRITE_REG(&sc->hw, E1000_RDBAL(i), - (uint32_t)bus_addr); - } - - /* Setup the Receive Control Register */ - rctl &= ~(3 << E1000_RCTL_MO_SHIFT); - rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | - E1000_RCTL_RDMTS_HALF | E1000_RCTL_SECRC | - (sc->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); - - /* Make sure VLAN Filters are off */ - rctl &= ~E1000_RCTL_VFE; - - /* Don't store bad paket */ - rctl &= ~E1000_RCTL_SBP; - - /* MCLBYTES */ - rctl |= E1000_RCTL_SZ_2048; - - if (ifp->if_mtu > ETHERMTU) - rctl |= E1000_RCTL_LPE; - else - rctl &= ~E1000_RCTL_LPE; - /* * Receive Checksum Offload for TCP and UDP * @@ -2664,6 +2649,8 @@ emx_init_rx_unit(struct emx_softc *sc) * packet type. */ if (ifp->if_capenable & (IFCAP_RSS | IFCAP_RXCSUM)) { + uint32_t rxcsum; + rxcsum = E1000_READ_REG(&sc->hw, E1000_RXCSUM); /* @@ -2746,15 +2733,48 @@ emx_init_rx_unit(struct emx_softc *sc) E1000_WRITE_REG(&sc->hw, E1000_RDTR, EMX_RDTR_82573); } - /* - * Setup the HW Rx Head and Tail Descriptor Pointers - */ for (i = 0; i < sc->rx_ring_inuse; ++i) { + struct emx_rxdata *rdata = &sc->rx_data[i]; + + /* + * Setup the Base and Length of the Rx Descriptor Ring + */ + bus_addr = rdata->rx_desc_paddr; + E1000_WRITE_REG(&sc->hw, E1000_RDLEN(i), + rdata->num_rx_desc * sizeof(emx_rxdesc_t)); + E1000_WRITE_REG(&sc->hw, E1000_RDBAH(i), + (uint32_t)(bus_addr >> 32)); + E1000_WRITE_REG(&sc->hw, E1000_RDBAL(i), + (uint32_t)bus_addr); + + /* + * Setup the HW Rx Head and Tail Descriptor Pointers + */ E1000_WRITE_REG(&sc->hw, E1000_RDH(i), 0); E1000_WRITE_REG(&sc->hw, E1000_RDT(i), sc->rx_data[i].num_rx_desc - 1); } + /* Setup the Receive Control Register */ + rctl &= ~(3 << E1000_RCTL_MO_SHIFT); + rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_LBM_NO | + E1000_RCTL_RDMTS_HALF | E1000_RCTL_SECRC | + (sc->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + + /* Make sure VLAN Filters are off */ + rctl &= ~E1000_RCTL_VFE; + + /* Don't store bad paket */ + rctl &= ~E1000_RCTL_SBP; + + /* MCLBYTES */ + rctl |= E1000_RCTL_SZ_2048; + + if (ifp->if_mtu > ETHERMTU) + rctl |= E1000_RCTL_LPE; + else + rctl &= ~E1000_RCTL_LPE; + /* Enable Receives */ E1000_WRITE_REG(&sc->hw, E1000_RCTL, rctl); } @@ -2934,14 +2954,26 @@ discard: static void emx_enable_intr(struct emx_softc *sc) { + uint32_t ims_mask = IMS_ENABLE_MASK; + lwkt_serialize_handler_enable(&sc->main_serialize); - E1000_WRITE_REG(&sc->hw, E1000_IMS, IMS_ENABLE_MASK); + +#if 0 + if (sc->hw.mac.type == e1000_82574) { + E1000_WRITE_REG(hw, EMX_EIAC, EM_MSIX_MASK); + ims_mask |= EM_MSIX_MASK; + } +#endif + E1000_WRITE_REG(&sc->hw, E1000_IMS, ims_mask); } static void emx_disable_intr(struct emx_softc *sc) { + if (sc->hw.mac.type == e1000_82574) + E1000_WRITE_REG(&sc->hw, EMX_EIAC, 0); E1000_WRITE_REG(&sc->hw, E1000_IMC, 0xffffffff); + lwkt_serialize_handler_disable(&sc->main_serialize); } @@ -3000,27 +3032,21 @@ emx_rel_mgmt(struct emx_softc *sc) static void emx_get_hw_control(struct emx_softc *sc) { - uint32_t ctrl_ext, swsm; - /* Let firmware know the driver has taken over */ - switch (sc->hw.mac.type) { - case e1000_82573: + if (sc->hw.mac.type == e1000_82573) { + uint32_t swsm; + swsm = E1000_READ_REG(&sc->hw, E1000_SWSM); E1000_WRITE_REG(&sc->hw, E1000_SWSM, swsm | E1000_SWSM_DRV_LOAD); - break; + } else { + uint32_t ctrl_ext; - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: ctrl_ext = E1000_READ_REG(&sc->hw, E1000_CTRL_EXT); E1000_WRITE_REG(&sc->hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); - break; - - default: - break; } + sc->control_hw = 1; } /* @@ -3032,26 +3058,23 @@ emx_get_hw_control(struct emx_softc *sc) static void emx_rel_hw_control(struct emx_softc *sc) { - uint32_t ctrl_ext, swsm; + if (!sc->control_hw) + return; + sc->control_hw = 0; /* Let firmware taken over control of h/w */ - switch (sc->hw.mac.type) { - case e1000_82573: + if (sc->hw.mac.type == e1000_82573) { + uint32_t swsm; + swsm = E1000_READ_REG(&sc->hw, E1000_SWSM); E1000_WRITE_REG(&sc->hw, E1000_SWSM, swsm & ~E1000_SWSM_DRV_LOAD); - break; + } else { + uint32_t ctrl_ext; - case e1000_82571: - case e1000_82572: - case e1000_80003es2lan: ctrl_ext = E1000_READ_REG(&sc->hw, E1000_CTRL_EXT); E1000_WRITE_REG(&sc->hw, E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); - break; - - default: - break; } } @@ -3447,7 +3470,7 @@ emx_sysctl_int_throttle(SYSCTL_HANDLER_ARGS) sc->int_throttle_ceil = 0; if (ifp->if_flags & IFF_RUNNING) - E1000_WRITE_REG(&sc->hw, E1000_ITR, throttle); + emx_set_itr(sc, throttle); ifnet_deserialize_all(ifp); @@ -3787,3 +3810,19 @@ emx_qpoll(struct ifnet *ifp, struct ifpoll_info *info) } #endif /* IFPOLL_ENABLE */ + +static void +emx_set_itr(struct emx_softc *sc, uint32_t itr) +{ + E1000_WRITE_REG(&sc->hw, E1000_ITR, itr); + if (sc->hw.mac.type == e1000_82574) { + int i; + + /* + * When using MSIX interrupts we need to + * throttle using the EITR register + */ + for (i = 0; i < 4; ++i) + E1000_WRITE_REG(&sc->hw, E1000_EITR_82574(i), itr); + } +} diff --git a/sys/dev/netif/emx/if_emx.h b/sys/dev/netif/emx/if_emx.h index 1083ec1..af52c83 100644 --- a/sys/dev/netif/emx/if_emx.h +++ b/sys/dev/netif/emx/if_emx.h @@ -262,6 +262,11 @@ struct emx_softc { /* Management and WOL features */ int wol; int has_manage; + int has_amt; + int control_hw; + + /* Multicast array memory */ + uint8_t *mta; /* Info about the board itself */ uint8_t link_active; diff --git a/sys/dev/netif/ig_hal/e1000_nvm.c b/sys/dev/netif/ig_hal/e1000_nvm.c index f0669e2..ec26671 100644 --- a/sys/dev/netif/ig_hal/e1000_nvm.c +++ b/sys/dev/netif/ig_hal/e1000_nvm.c @@ -1006,7 +1006,6 @@ out: **/ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) { -#ifdef foo u32 rar_high; u32 rar_low; u16 i; @@ -1024,33 +1023,6 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) hw->mac.addr[i] = hw->mac.perm_addr[i]; return E1000_SUCCESS; -#else - s32 ret_val = E1000_SUCCESS; - u16 offset, nvm_data, i; - - DEBUGFUNC("e1000_read_mac_addr"); - - for (i = 0; i < ETH_ADDR_LEN; i += 2) { - offset = i >> 1; - ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); - if (ret_val) { - DEBUGOUT("NVM Read Error\n"); - goto out; - } - hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); - hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); - } - - /* Flip last bit of mac address if we're on second port */ - if (hw->bus.func == E1000_FUNC_1) - hw->mac.perm_addr[5] ^= 1; - - for (i = 0; i < ETH_ADDR_LEN; i++) - hw->mac.addr[i] = hw->mac.perm_addr[i]; - -out: - return ret_val; -#endif } /**