From f6b1d9cab82e9beda31f53f9102c0e4a00165378 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Tue, 20 Nov 2007 21:41:22 +0000 Subject: [PATCH] Driver version 6.7.3 - Bring HEAD up to the latest shared code - Fix TSO problem using limited MSS and forwarding - Dual lock implementation - New device support - For my ease, this code can compile in either 6.x or later - brings this driver in sync with the 6.3 --- sys/dev/em/e1000_80003es2lan.c | 245 +++++---- sys/dev/em/e1000_80003es2lan.h | 45 +- sys/dev/em/e1000_82540.c | 109 ++-- sys/dev/em/e1000_82541.c | 174 ++++--- sys/dev/em/e1000_82541.h | 2 +- sys/dev/em/e1000_82542.c | 102 ++-- sys/dev/em/e1000_82543.c | 390 +++++++------- sys/dev/em/e1000_82543.h | 7 +- sys/dev/em/e1000_82571.c | 306 ++++++----- sys/dev/em/e1000_82571.h | 2 +- sys/dev/em/e1000_82575.c | 345 +++++++------ sys/dev/em/e1000_82575.h | 30 +- sys/dev/em/e1000_api.c | 440 ++++++++-------- sys/dev/em/e1000_api.h | 178 +++---- sys/dev/em/e1000_defines.h | 173 ++++--- sys/dev/em/e1000_hw.h | 200 ++++---- sys/dev/em/e1000_ich8lan.c | 641 +++++++++++++---------- sys/dev/em/e1000_ich8lan.h | 18 +- sys/dev/em/e1000_mac.c | 479 +++++++++-------- sys/dev/em/e1000_mac.h | 8 +- sys/dev/em/e1000_manage.c | 55 +- sys/dev/em/e1000_manage.h | 28 +- sys/dev/em/e1000_nvm.c | 147 +++--- sys/dev/em/e1000_nvm.h | 4 +- sys/dev/em/e1000_osdep.h | 3 +- sys/dev/em/e1000_phy.c | 370 ++++++++------ sys/dev/em/e1000_phy.h | 22 +- sys/dev/em/e1000_regs.h | 409 ++++++--------- sys/dev/em/if_em.c | 909 +++++++++++++++++++++------------ sys/dev/em/if_em.h | 36 +- 30 files changed, 3220 insertions(+), 2657 deletions(-) diff --git a/sys/dev/em/e1000_80003es2lan.c b/sys/dev/em/e1000_80003es2lan.c index 56c123523ef8..46587aca37be 100644 --- a/sys/dev/em/e1000_80003es2lan.c +++ b/sys/dev/em/e1000_80003es2lan.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ /* e1000_80003es2lan */ @@ -70,13 +70,14 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); +STATIC void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); -/* A table for the GG82563 cable length where the range is defined +/* + * A table for the GG82563 cable length where the range is defined * with a lower bound at "index" and the upper bound at * "index + 5". */ -static const -u16 e1000_gg82563_cable_length_table[] = +static const u16 e1000_gg82563_cable_length_table[] = { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; #define GG82563_CABLE_LENGTH_TABLE_SIZE \ (sizeof(e1000_gg82563_cable_length_table) / \ @@ -88,8 +89,7 @@ u16 e1000_gg82563_cable_length_table[] = * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_functions *func = &hw->func; @@ -97,9 +97,12 @@ e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_init_phy_params_80003es2lan"); - if (hw->media_type != e1000_media_type_copper) { + if (hw->phy.media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; goto out; + } else { + func->power_up_phy = e1000_power_up_phy_copper; + func->power_down_phy = e1000_power_down_phy_copper_80003es2lan; } phy->addr = 1; @@ -141,8 +144,7 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; @@ -173,10 +175,15 @@ e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); - /* Added to a constant, "size" becomes the left-shift value + /* + * Added to a constant, "size" becomes the left-shift value * for setting word_size. */ size += NVM_WORD_SIZE_BASE_SHIFT; + + /* EEPROM access above 16k is unsupported */ + if (size > 14) + size = 14; nvm->word_size = 1 << size; /* Function Pointers */ @@ -197,8 +204,7 @@ e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -209,10 +215,10 @@ e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) /* Set media type */ switch (hw->device_id) { case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: - hw->media_type = e1000_media_type_internal_serdes; + hw->phy.media_type = e1000_media_type_internal_serdes; break; default: - hw->media_type = e1000_media_type_copper; + hw->phy.media_type = e1000_media_type_copper; break; } @@ -239,11 +245,11 @@ e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) func->setup_link = e1000_setup_link_generic; /* physical interface link setup */ func->setup_physical_interface = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_80003es2lan : e1000_setup_fiber_serdes_link_generic; /* check for link */ - switch (hw->media_type) { + switch (hw->phy.media_type) { case e1000_media_type_copper: func->check_for_link = e1000_check_for_copper_link_generic; break; @@ -261,7 +267,7 @@ e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) /* check management mode */ func->check_mng_mode = e1000_check_mng_mode_generic; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_generic; + func->update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ func->write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ @@ -295,8 +301,7 @@ out: * The only function explicitly called by the api module to initialize * all function pointers and parameters. **/ -void -e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) +void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_80003es2lan"); @@ -312,8 +317,7 @@ e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) * A wrapper to acquire access rights to the correct PHY. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) { u16 mask; @@ -331,8 +335,7 @@ e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) * A wrapper to release access rights to the correct PHY. This is a * function pointer entry point called by the api module. **/ -STATIC void -e1000_release_phy_80003es2lan(struct e1000_hw *hw) +STATIC void e1000_release_phy_80003es2lan(struct e1000_hw *hw) { u16 mask; @@ -349,8 +352,7 @@ e1000_release_phy_80003es2lan(struct e1000_hw *hw) * Acquire the semaphore to access the EEPROM. This is a function * pointer entry point called by the api module. **/ -STATIC s32 -e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) { s32 ret_val; @@ -376,8 +378,7 @@ out: * Release the semaphore used to access the EEPROM. This is a * function pointer entry point called by the api module. **/ -STATIC void -e1000_release_nvm_80003es2lan(struct e1000_hw *hw) +STATIC void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_80003es2lan"); @@ -393,8 +394,7 @@ e1000_release_nvm_80003es2lan(struct e1000_hw *hw) * Acquire the SW/FW semaphore to access the PHY or NVM. The mask * will also specify which port we're acquiring the lock for. **/ -static s32 -e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) +static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) { u32 swfw_sync; u32 swmask = mask; @@ -414,8 +414,10 @@ e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) if (!(swfw_sync & (fwmask | swmask))) break; - /* Firmware currently using resource (fwmask) - * or other software thread using resource (swmask) */ + /* + * Firmware currently using resource (fwmask) + * or other software thread using resource (swmask) + */ e1000_put_hw_semaphore_generic(hw); msec_delay_irq(5); i++; @@ -444,8 +446,7 @@ out: * Release the SW/FW semaphore used to access the PHY or NVM. The mask * will also specify which port we're releasing the lock for. **/ -static void -e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) +static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) { u32 swfw_sync; @@ -470,9 +471,8 @@ e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) * Read the GG82563 PHY register. This is a function pointer entry * point called by the api module. **/ -STATIC s32 -e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, - u16 *data) +STATIC s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, + u32 offset, u16 *data) { s32 ret_val; u32 page_select; @@ -481,10 +481,11 @@ e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan"); /* Select Configuration Page */ - if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) + if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { page_select = GG82563_PHY_PAGE_SELECT; - else { - /* Use Alternative Page Select register to access + } else { + /* + * Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; @@ -495,7 +496,8 @@ e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, if (ret_val) goto out; - /* The "ready" bit in the MDIC register may be incorrectly set + /* + * The "ready" bit in the MDIC register may be incorrectly set * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ @@ -530,9 +532,8 @@ out: * Write to the GG82563 PHY register. This is a function pointer entry * point called by the api module. **/ -STATIC s32 -e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, - u16 data) +STATIC s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, + u32 offset, u16 data) { s32 ret_val; u32 page_select; @@ -541,10 +542,11 @@ e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan"); /* Select Configuration Page */ - if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) + if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { page_select = GG82563_PHY_PAGE_SELECT; - else { - /* Use Alternative Page Select register to access + } else { + /* + * Use Alternative Page Select register to access * registers 30 and 31 */ page_select = GG82563_PHY_PAGE_SELECT_ALT; @@ -556,7 +558,8 @@ e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, goto out; - /* The "ready" bit in the MDIC register may be incorrectly set + /* + * The "ready" bit in the MDIC register may be incorrectly set * before the device has completed the "Page Select" MDI * transaction. So we wait 200us after each MDI command... */ @@ -592,8 +595,7 @@ out: * Write "words" of data to the ESB2 NVM. This is a function * pointer entry point called by the api module. **/ -STATIC s32 -e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, +STATIC s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { DEBUGFUNC("e1000_write_nvm_80003es2lan"); @@ -608,8 +610,7 @@ e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, * Wait a specific amount of time for manageability processes to complete. * This is a function pointer entry point called by the phy module. **/ -STATIC s32 -e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; @@ -643,16 +644,16 @@ out: * Force the speed and duplex settings onto the PHY. This is a * function pointer entry point called by the phy module. **/ -STATIC s32 -e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) { s32 ret_val; u16 phy_data; - boolean_t link; + bool link; DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan"); - /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI + /* + * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed and duplex are forced. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); @@ -681,7 +682,7 @@ e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) usec_delay(1); - if (hw->phy.wait_for_link) { + if (hw->phy.autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link " "on GG82563 phy.\n"); @@ -691,7 +692,8 @@ e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) goto out; if (!link) { - /* We didn't get link. + /* + * We didn't get link. * Reset the DSP and cross our fingers. */ ret_val = e1000_phy_reset_dsp_generic(hw); @@ -710,7 +712,8 @@ e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) if (ret_val) goto out; - /* Resetting the phy means we need to verify the TX_CLK corresponds + /* + * Resetting the phy means we need to verify the TX_CLK corresponds * to the link speed. 10Mbps -> 2.5MHz, else 25MHz. */ phy_data &= ~GG82563_MSCR_TX_CLK_MASK; @@ -719,7 +722,8 @@ e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) else phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25; - /* In addition, we must re-enable CRS on Tx for both half and full + /* + * In addition, we must re-enable CRS on Tx for both half and full * duplex. */ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; @@ -736,8 +740,7 @@ out: * Find the approximate cable length as measured by the GG82563 PHY. * This is a function pointer entry point called by the phy module. **/ -STATIC s32 -e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -768,14 +771,14 @@ out: * Retrieve the current speed and duplex configuration. * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, u16 *duplex) +STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, + u16 *duplex) { s32 ret_val; DEBUGFUNC("e1000_get_link_up_info_80003es2lan"); - if (hw->media_type == e1000_media_type_copper) { + if (hw->phy.media_type == e1000_media_type_copper) { ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex); @@ -786,10 +789,11 @@ e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, u16 *duplex) else ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, *duplex); - } else + } else { ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw, speed, duplex); + } out: return ret_val; @@ -802,15 +806,15 @@ out: * Perform a global reset to the ESB2 controller. * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_reset_hw_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) { u32 ctrl, icr; s32 ret_val; DEBUGFUNC("e1000_reset_hw_80003es2lan"); - /* Prevent the PCI-E bus from sticking if there is no TLP connection + /* + * Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); @@ -852,8 +856,7 @@ out: * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_hw_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 reg_data; @@ -868,7 +871,7 @@ e1000_init_hw_80003es2lan(struct e1000_hw *hw) ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); - goto out; + /* This is not fatal and we should not stop init due to this */ } /* Disabling VLAN filtering */ @@ -887,16 +890,16 @@ e1000_init_hw_80003es2lan(struct e1000_hw *hw) ret_val = e1000_setup_link(hw); /* Set the transmit descriptor write-back policy */ - reg_data = E1000_READ_REG(hw, E1000_TXDCTL); + reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; - E1000_WRITE_REG(hw, E1000_TXDCTL, reg_data); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); /* ...for both queues. */ - reg_data = E1000_READ_REG(hw, E1000_TXDCTL1); + reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; - E1000_WRITE_REG(hw, E1000_TXDCTL1, reg_data); + E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); /* Enable retransmit on late collisions */ reg_data = E1000_READ_REG(hw, E1000_TCTL); @@ -919,14 +922,14 @@ e1000_init_hw_80003es2lan(struct e1000_hw *hw) reg_data &= ~0x00100000; E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. */ e1000_clear_hw_cntrs_80003es2lan(hw); -out: return ret_val; } @@ -936,8 +939,7 @@ out: * * Initializes required hardware-dependent bits needed for normal operation. **/ -static void -e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) +static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) { u32 reg; @@ -947,29 +949,29 @@ e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) goto out; /* Transmit Descriptor Control 0 */ - reg = E1000_READ_REG(hw, E1000_TXDCTL); + reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); reg |= (1 << 22); - E1000_WRITE_REG(hw, E1000_TXDCTL, reg); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); /* Transmit Descriptor Control 1 */ - reg = E1000_READ_REG(hw, E1000_TXDCTL1); + reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); reg |= (1 << 22); - E1000_WRITE_REG(hw, E1000_TXDCTL1, reg); + E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); /* Transmit Arbitration Control 0 */ - reg = E1000_READ_REG(hw, E1000_TARC0); + reg = E1000_READ_REG(hw, E1000_TARC(0)); reg &= ~(0xF << 27); /* 30:27 */ - if (hw->media_type != e1000_media_type_copper) + if (hw->phy.media_type != e1000_media_type_copper) reg &= ~(1 << 20); - E1000_WRITE_REG(hw, E1000_TARC0, reg); + E1000_WRITE_REG(hw, E1000_TARC(0), reg); /* Transmit Arbitration Control 1 */ - reg = E1000_READ_REG(hw, E1000_TARC1); + reg = E1000_READ_REG(hw, E1000_TARC(1)); if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) reg &= ~(1 << 28); else reg |= (1 << 28); - E1000_WRITE_REG(hw, E1000_TARC1, reg); + E1000_WRITE_REG(hw, E1000_TARC(1), reg); out: return; @@ -981,8 +983,7 @@ out: * * Setup some GG82563 PHY registers for obtaining link **/ -static s32 -e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) +static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1006,7 +1007,8 @@ e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (ret_val) goto out; - /* Options: + /* + * Options: * MDI/MDI-X = 0 (default) * 0 - Auto for all speeds * 1 - MDI mode @@ -1032,14 +1034,15 @@ e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) break; } - /* Options: + /* + * Options: * disable_polarity_correction = 0 (default) * Automatic Correction for Reversed Cable Polarity * 0 - Disabled * 1 - Enabled */ data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - if (phy->disable_polarity_correction == TRUE) + if (phy->disable_polarity_correction) data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, data); @@ -1055,7 +1058,7 @@ e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) } - /* Bypass RX and TX FIFO's */ + /* Bypass Rx and Tx FIFO's */ ret_val = e1000_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | @@ -1063,6 +1066,18 @@ e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (ret_val) goto out; + ret_val = e1000_read_kmrn_reg(hw, + E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, + &data); + if (ret_val) + goto out; + data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; + ret_val = e1000_write_kmrn_reg(hw, + E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, + data); + if (ret_val) + goto out; + ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data); if (ret_val) goto out; @@ -1080,11 +1095,12 @@ e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (ret_val) goto out; - /* Do not init these registers when the HW is in IAMT mode, since the + /* + * Do not init these registers when the HW is in IAMT mode, since the * firmware will have already initialized them. We only initialize * them if the HW is not in IAMT mode. */ - if (e1000_check_mng_mode(hw) == FALSE) { + if (!(e1000_check_mng_mode(hw))) { /* Enable Electrical Idle on the PHY */ data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; ret_val = e1000_write_phy_reg(hw, @@ -1108,7 +1124,8 @@ e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) goto out; } - /* Workaround: Disable padding in Kumeran interface in the MAC + /* + * Workaround: Disable padding in Kumeran interface in the MAC * and in the PHY to avoid CRC errors. */ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_INBAND_CTRL, &data); @@ -1131,8 +1148,7 @@ out: * Essentially a wrapper for setting up all things "copper" related. * This is a function pointer entry point called by the mac module. **/ -STATIC s32 -e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) +STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -1145,9 +1161,11 @@ e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - /* Set the mac to wait the maximum time between each + /* + * Set the mac to wait the maximum time between each * iteration and increase the max iterations when - * polling the phy; this fixes erroneous timeouts at 10Mbps. */ + * polling the phy; this fixes erroneous timeouts at 10Mbps. + */ ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF); if (ret_val) goto out; @@ -1188,8 +1206,7 @@ out: * Configure the KMRN interface by applying last minute quirks for * 10/100 operation. **/ -static s32 -e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) +static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) { s32 ret_val = E1000_SUCCESS; u32 tipg; @@ -1243,8 +1260,7 @@ out: * Configure the KMRN interface by applying last minute quirks for * gigabit operation. **/ -static s32 -e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) +static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 reg_data, reg_data2; @@ -1287,14 +1303,29 @@ out: return ret_val; } +/** + * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, remove the link. + **/ +STATIC void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) +{ + /* If the management interface is not enabled, then power down */ + if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw))) + e1000_power_down_phy_copper(hw); + + return; +} + /** * e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters * @hw: pointer to the HW structure * * Clears the hardware counters by reading the counter registers. **/ -STATIC void -e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_80003es2lan.h b/sys/dev/em/e1000_80003es2lan.h index e574f6d5a4b8..d81def42867b 100644 --- a/sys/dev/em/e1000_80003es2lan.h +++ b/sys/dev/em/e1000_80003es2lan.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_80003ES2LAN_H_ @@ -39,6 +39,7 @@ #define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 #define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 #define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 +#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F #define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 #define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 @@ -46,12 +47,13 @@ #define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 +#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ -#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 +#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 -#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8 -#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9 +#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8 +#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9 /* GG82563 PHY Specific Status Register (Page 0, Register 16 */ #define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disabled */ @@ -61,37 +63,40 @@ #define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */ /* PHY Specific Control Register 2 (Page 0, Register 26) */ -#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 +#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Negotiation */ /* MAC Specific Control Register (Page 2, Register 21) */ /* Tx clock speed for Link Down and 1000BASE-T for the following speeds */ -#define GG82563_MSCR_TX_CLK_MASK 0x0007 -#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004 -#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005 -#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006 -#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007 +#define GG82563_MSCR_TX_CLK_MASK 0x0007 +#define GG82563_MSCR_TX_CLK_10MBPS_2_5 0x0004 +#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005 +#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006 +#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007 -#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ +#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ /* DSP Distance Register (Page 5, Register 26) */ -#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M; - 1 = 50-80M; - 2 = 80-110M; - 3 = 110-140M; - 4 = >140M */ +/* + * 0 = <50M + * 1 = 50-80M + * 2 = 80-100M + * 3 = 110-140M + * 4 = >140M + */ +#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* Kumeran Mode Control Register (Page 193, Register 16) */ -#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 +#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 /* Max number of times Kumeran read/write should be validated */ -#define GG82563_MAX_KMRN_RETRY 0x5 +#define GG82563_MAX_KMRN_RETRY 0x5 /* Power Management Control Register (Page 193, Register 20) */ -#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 +#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* 1=Enable SERDES Electrical Idle */ /* In-Band Control Register (Page 194, Register 18) */ -#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */ +#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */ #endif diff --git a/sys/dev/em/e1000_82540.c b/sys/dev/em/e1000_82540.c index 7fdc66458f7c..6f053959e17c 100644 --- a/sys/dev/em/e1000_82540.c +++ b/sys/dev/em/e1000_82540.c @@ -30,8 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ - +/* $FreeBSD$ */ /* e1000_82540 * e1000_82545 @@ -55,6 +54,7 @@ static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw); static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw); STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw); STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw); +STATIC void e1000_power_down_phy_copper_82540(struct e1000_hw *hw); /** * e1000_init_phy_params_82540 - Init PHY func ptrs. @@ -62,8 +62,7 @@ STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw); * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_phy_params_82540(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_82540(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_functions *func = &hw->func; @@ -84,6 +83,8 @@ e1000_init_phy_params_82540(struct e1000_hw *hw) func->reset_phy = e1000_phy_hw_reset_generic; func->write_phy_reg = e1000_write_phy_reg_m88; func->get_phy_info = e1000_get_phy_info_m88; + func->power_up_phy = e1000_power_up_phy_copper; + func->power_down_phy = e1000_power_down_phy_copper_82540; ret_val = e1000_get_phy_id(hw); if (ret_val) @@ -115,8 +116,7 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_nvm_params_82540(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_82540(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; @@ -160,8 +160,7 @@ e1000_init_nvm_params_82540(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_mac_params_82540(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_82540(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -175,14 +174,14 @@ e1000_init_mac_params_82540(struct e1000_hw *hw) case E1000_DEV_ID_82545GM_FIBER: case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546GB_FIBER: - hw->media_type = e1000_media_type_fiber; + hw->phy.media_type = e1000_media_type_fiber; break; case E1000_DEV_ID_82545GM_SERDES: case E1000_DEV_ID_82546GB_SERDES: - hw->media_type = e1000_media_type_internal_serdes; + hw->phy.media_type = e1000_media_type_internal_serdes; break; default: - hw->media_type = e1000_media_type_copper; + hw->phy.media_type = e1000_media_type_copper; break; } @@ -203,11 +202,11 @@ e1000_init_mac_params_82540(struct e1000_hw *hw) func->setup_link = e1000_setup_link_generic; /* physical interface setup */ func->setup_physical_interface = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82540 : e1000_setup_fiber_serdes_link_82540; /* check for link */ - switch (hw->media_type) { + switch (hw->phy.media_type) { case e1000_media_type_copper: func->check_for_link = e1000_check_for_copper_link_generic; break; @@ -224,11 +223,11 @@ e1000_init_mac_params_82540(struct e1000_hw *hw) } /* link info */ func->get_link_up_info = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_get_speed_and_duplex_copper_generic : e1000_get_speed_and_duplex_fiber_serdes_generic; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_generic; + func->update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ func->write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ @@ -256,8 +255,7 @@ out: * The only function explicitly called by the api module to initialize * all function pointers and parameters. **/ -void -e1000_init_function_pointers_82540(struct e1000_hw *hw) +void e1000_init_function_pointers_82540(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82540"); @@ -273,8 +271,7 @@ e1000_init_function_pointers_82540(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_reset_hw_82540(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_82540(struct e1000_hw *hw) { u32 ctrl, icr, manc; s32 ret_val = E1000_SUCCESS; @@ -288,7 +285,8 @@ e1000_reset_hw_82540(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); E1000_WRITE_FLUSH(hw); - /* Delay to allow any outstanding PCI transactions to complete + /* + * Delay to allow any outstanding PCI transactions to complete * before resetting the device. */ msec_delay(10); @@ -302,7 +300,8 @@ e1000_reset_hw_82540(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_CTRL_DUP, ctrl | E1000_CTRL_RST); break; default: - /* These controllers can't ack the 64-bit write when + /* + * These controllers can't ack the 64-bit write when * issuing the reset, so we use IO-mapping as a * workaround to issue the reset. */ @@ -331,8 +330,7 @@ e1000_reset_hw_82540(struct e1000_hw *hw) * This inits the hardware readying it for operation. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_hw_82540(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 txdctl, ctrl_ext; @@ -345,14 +343,14 @@ e1000_init_hw_82540(struct e1000_hw *hw) ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); - goto out; + /* This is not fatal and we should not stop init due to this */ } /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); - if (mac->type < e1000_82545_rev_3) { + if (mac->type < e1000_82545_rev_3) E1000_WRITE_REG(hw, E1000_VET, 0); - } + e1000_clear_vfta(hw); /* Setup the receive address. */ @@ -362,7 +360,8 @@ e1000_init_hw_82540(struct e1000_hw *hw) DEBUGOUT("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) { E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); - /* Avoid back to back register writes by adding the register + /* + * Avoid back to back register writes by adding the register * read (flush). This is to protect against some strange * bridge configurations that may issue Memory Write Block * (MWB) to our register space. The *_rev_3 hardware at @@ -378,12 +377,13 @@ e1000_init_hw_82540(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = e1000_setup_link(hw); - txdctl = E1000_READ_REG(hw, E1000_TXDCTL); + txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; - E1000_WRITE_REG(hw, E1000_TXDCTL, txdctl); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. @@ -393,13 +393,14 @@ e1000_init_hw_82540(struct e1000_hw *hw) if ((hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER) || (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3)) { ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); - /* Relaxed ordering must be disabled to avoid a parity - * error crash in a PCI slot. */ + /* + * Relaxed ordering must be disabled to avoid a parity + * error crash in a PCI slot. + */ ctrl_ext |= E1000_CTRL_EXT_RO_DIS; E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); } -out: return ret_val; } @@ -413,8 +414,7 @@ out: * not established, we return -E1000_ERR_PHY (-2). This is a function * pointer entry point called by the api module. **/ -STATIC s32 -e1000_setup_copper_link_82540(struct e1000_hw *hw) +STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw) { u32 ctrl; s32 ret_val = E1000_SUCCESS; @@ -462,8 +462,7 @@ out: * setup, poll for link. This is a function pointer entry point called by * the api module. **/ -STATIC s32 -e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw) +STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val = E1000_SUCCESS; @@ -473,8 +472,9 @@ e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw) switch (mac->type) { case e1000_82545_rev_3: case e1000_82546_rev_3: - if (hw->media_type == e1000_media_type_internal_serdes) { - /* If we're on serdes media, adjust the output + if (hw->phy.media_type == e1000_media_type_internal_serdes) { + /* + * If we're on serdes media, adjust the output * amplitude to value set in the EEPROM. */ ret_val = e1000_adjust_serdes_amplitude_82540(hw); @@ -501,8 +501,7 @@ out: * * Adjust the SERDES ouput amplitude based on the EEPROM settings. **/ -static s32 -e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw) +static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 nvm_data; @@ -510,9 +509,8 @@ e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw) DEBUGFUNC("e1000_adjust_serdes_amplitude_82540"); ret_val = e1000_read_nvm(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data); - if (ret_val) { + if (ret_val) goto out; - } if (nvm_data != NVM_RESERVED_WORD) { /* Adjust serdes output amplitude only. */ @@ -534,8 +532,7 @@ out: * * Set the VCO speed to improve Bit Error Rate (BER) performance. **/ -static s32 -e1000_set_vco_speed_82540(struct e1000_hw *hw) +static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 default_page = 0; @@ -595,8 +592,7 @@ out: * 1. Do a PHY soft reset. * 2. Restart auto-negotiation or force link. **/ -static s32 -e1000_set_phy_mode_82540(struct e1000_hw *hw) +static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -635,14 +631,29 @@ out: return ret_val; } +/** + * e1000_power_down_phy_copper_82540 - Remove link in case of PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, remove the link. + **/ +STATIC void e1000_power_down_phy_copper_82540(struct e1000_hw *hw) +{ + /* If the management interface is not enabled, then power down */ + if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_SMBUS_EN)) + e1000_power_down_phy_copper(hw); + + return; +} + /** * e1000_clear_hw_cntrs_82540 - Clear device specific hardware counters * @hw: pointer to the HW structure * * Clears the hardware counters by reading the counter registers. **/ -STATIC void -e1000_clear_hw_cntrs_82540(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82541.c b/sys/dev/em/e1000_82541.c index 3bc648308328..78bcc27269f0 100644 --- a/sys/dev/em/e1000_82541.c +++ b/sys/dev/em/e1000_82541.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ /* e1000_82541 @@ -56,16 +56,16 @@ STATIC s32 e1000_setup_copper_link_82541(struct e1000_hw *hw); STATIC s32 e1000_check_for_link_82541(struct e1000_hw *hw); STATIC s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw); STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, - boolean_t active); + bool active); STATIC s32 e1000_setup_led_82541(struct e1000_hw *hw); STATIC s32 e1000_cleanup_led_82541(struct e1000_hw *hw); STATIC void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw); static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, - boolean_t link_up); + bool link_up); static s32 e1000_phy_init_script_82541(struct e1000_hw *hw); +STATIC void e1000_power_down_phy_copper_82541(struct e1000_hw *hw); -static const -u16 e1000_igp_cable_length_table[] = +static const u16 e1000_igp_cable_length_table[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 20, 20, 20, 20, 20, 25, 25, 25, 25, 25, 25, 25, 30, 30, 30, 30, 40, 40, 40, 40, 40, 40, 40, 40, @@ -82,7 +82,7 @@ struct e1000_dev_spec_82541 { e1000_dsp_config dsp_config; e1000_ffe_config ffe_config; u16 spd_default; - boolean_t phy_init_script; + bool phy_init_script; }; /** @@ -91,8 +91,7 @@ struct e1000_dev_spec_82541 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_phy_params_82541(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_82541(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_functions *func = &hw->func; @@ -115,6 +114,8 @@ e1000_init_phy_params_82541(struct e1000_hw *hw) func->reset_phy = e1000_phy_hw_reset_82541; func->set_d3_lplu_state = e1000_set_d3_lplu_state_82541; func->write_phy_reg = e1000_write_phy_reg_igp; + func->power_up_phy = e1000_power_up_phy_copper; + func->power_down_phy = e1000_power_down_phy_copper_82541; ret_val = e1000_get_phy_id(hw); if (ret_val) @@ -136,8 +137,7 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_nvm_params_82541(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; @@ -188,7 +188,8 @@ e1000_init_nvm_params_82541(struct e1000_hw *hw) func->validate_nvm = e1000_validate_nvm_checksum_generic; func->write_nvm = e1000_write_nvm_spi; - /* nvm->word_size must be discovered after the pointers + /* + * nvm->word_size must be discovered after the pointers * are set so we can verify the size from the nvm image * itself. Temporarily set it to a dummy value so the * read will work. @@ -198,7 +199,8 @@ e1000_init_nvm_params_82541(struct e1000_hw *hw) if (ret_val) goto out; size = (size & NVM_SIZE_MASK) >> NVM_SIZE_SHIFT; - /* if size != 0, it can be added to a constant and become + /* + * if size != 0, it can be added to a constant and become * the left-shift value to set the word_size. Otherwise, * word_size stays at 64. */ @@ -234,8 +236,7 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_mac_params_82541(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -244,7 +245,7 @@ e1000_init_mac_params_82541(struct e1000_hw *hw) DEBUGFUNC("e1000_init_mac_params_82541"); /* Set media type */ - hw->media_type = e1000_media_type_copper; + hw->phy.media_type = e1000_media_type_copper; /* Set mta register count */ mac->mta_reg_count = 128; /* Set rar entry count */ @@ -269,7 +270,7 @@ e1000_init_mac_params_82541(struct e1000_hw *hw) /* link info */ func->get_link_up_info = e1000_get_link_up_info_82541; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_generic; + func->update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ func->write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ @@ -303,8 +304,7 @@ e1000_init_mac_params_82541(struct e1000_hw *hw) * The only function explicitly called by the api module to initialize * all function pointers and parameters. **/ -void -e1000_init_function_pointers_82541(struct e1000_hw *hw) +void e1000_init_function_pointers_82541(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82541"); @@ -320,8 +320,7 @@ e1000_init_function_pointers_82541(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_reset_hw_82541(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_82541(struct e1000_hw *hw) { u32 ledctl, ctrl, icr, manc; @@ -334,7 +333,8 @@ e1000_reset_hw_82541(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); E1000_WRITE_FLUSH(hw); - /* Delay to allow any outstanding PCI transactions to complete + /* + * Delay to allow any outstanding PCI transactions to complete * before resetting the device. */ msec_delay(10); @@ -351,7 +351,8 @@ e1000_reset_hw_82541(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82541: case e1000_82541_rev_2: - /* These controllers can't ack the 64-bit write when + /* + * These controllers can't ack the 64-bit write when * issuing the reset, so we use IO-mapping as a * workaround to issue the reset. */ @@ -397,8 +398,7 @@ e1000_reset_hw_82541(struct e1000_hw *hw) * This inits the hardware readying it for operation. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_hw_82541(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 i, txdctl; @@ -410,7 +410,7 @@ e1000_init_hw_82541(struct e1000_hw *hw) ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); - goto out; + /* This is not fatal and we should not stop init due to this */ } /* Disabling VLAN filtering */ @@ -424,7 +424,8 @@ e1000_init_hw_82541(struct e1000_hw *hw) DEBUGOUT("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) { E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); - /* Avoid back to back register writes by adding the register + /* + * Avoid back to back register writes by adding the register * read (flush). This is to protect against some strange * bridge configurations that may issue Memory Write Block * (MWB) to our register space. @@ -435,19 +436,19 @@ e1000_init_hw_82541(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = e1000_setup_link(hw); - txdctl = E1000_READ_REG(hw, E1000_TXDCTL); + txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; - E1000_WRITE_REG(hw, E1000_TXDCTL, txdctl); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. */ e1000_clear_hw_cntrs_82541(hw); -out: return ret_val; } @@ -460,8 +461,8 @@ out: * Retrieve the current speed and duplex configuration. * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, u16 *duplex) +STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, + u16 *duplex) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -476,7 +477,8 @@ e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, u16 *duplex) if (!phy->speed_downgraded) goto out; - /* IGP01 PHY may advertise full duplex operation after speed + /* + * IGP01 PHY may advertise full duplex operation after speed * downgrade even if it is operating at half duplex. * Here we set the duplex settings to match the duplex in the * link partner's capabilities. @@ -485,9 +487,9 @@ e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, u16 *duplex) if (ret_val) goto out; - if (!(data & NWAY_ER_LP_NWAY_CAPS)) + if (!(data & NWAY_ER_LP_NWAY_CAPS)) { *duplex = HALF_DUPLEX; - else { + } else { ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, &data); if (ret_val) goto out; @@ -515,8 +517,7 @@ out: * reset and relase the semaphore (if necessary). * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_phy_hw_reset_82541(struct e1000_hw *hw) +STATIC s32 e1000_phy_hw_reset_82541(struct e1000_hw *hw) { s32 ret_val; u32 ledctl; @@ -551,8 +552,7 @@ out: * not established, we return -E1000_ERR_PHY (-2). This is a function * pointer entry point called by the api module. **/ -STATIC s32 -e1000_setup_copper_link_82541(struct e1000_hw *hw) +STATIC s32 e1000_setup_copper_link_82541(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_dev_spec_82541 *dev_spec; @@ -574,8 +574,9 @@ e1000_setup_copper_link_82541(struct e1000_hw *hw) if (hw->mac.type == e1000_82541 || hw->mac.type == e1000_82547) { dev_spec->dsp_config = e1000_dsp_config_disabled; phy->mdix = 1; - } else + } else { dev_spec->dsp_config = e1000_dsp_config_enabled; + } ret_val = e1000_copper_link_setup_igp(hw); if (ret_val) @@ -606,16 +607,16 @@ out: * results in the hw->mac structure. This is a function pointer entry * point called by the api module. **/ -STATIC s32 -e1000_check_for_link_82541(struct e1000_hw *hw) +STATIC s32 e1000_check_for_link_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; - boolean_t link; + bool link; DEBUGFUNC("e1000_check_for_link_82541"); - /* We only want to go out to the PHY registers to see if Auto-Neg + /* + * We only want to go out to the PHY registers to see if Auto-Neg * has completed and/or if our link status has changed. The * get_link_status flag is set upon receiving a Link Status * Change or Rx Sequence Error interrupt. @@ -625,7 +626,8 @@ e1000_check_for_link_82541(struct e1000_hw *hw) goto out; } - /* First we want to see if the MII Status Register reports + /* + * First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex * of the PHY. */ @@ -640,11 +642,14 @@ e1000_check_for_link_82541(struct e1000_hw *hw) mac->get_link_status = FALSE; - /* Check if there was DownShift, must be checked - * immediately after link-up */ + /* + * Check if there was DownShift, must be checked + * immediately after link-up + */ e1000_check_downshift_generic(hw); - /* If we are forcing speed/duplex, then we simply return since + /* + * If we are forcing speed/duplex, then we simply return since * we have already determined whether we have link or not. */ if (!mac->autoneg) { @@ -654,13 +659,15 @@ e1000_check_for_link_82541(struct e1000_hw *hw) ret_val = e1000_config_dsp_after_link_change_82541(hw, TRUE); - /* Auto-Neg is enabled. Auto Speed Detection takes care + /* + * Auto-Neg is enabled. Auto Speed Detection takes care * of MAC speed/duplex configuration. So we only need to * configure Collision Distance in the MAC. */ e1000_config_collision_dist_generic(hw); - /* Configure Flow Control now that Auto-Neg has completed. + /* + * Configure Flow Control now that Auto-Neg has completed. * First, we need to restore the desired flow control * settings because we may have had to re-autoneg with a * different link partner. @@ -686,8 +693,8 @@ out: * gigabit link is achieved to improve link quality. * This is a function pointer entry point called by the api module. **/ -static s32 -e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, boolean_t link_up) +static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, + bool link_up) { struct e1000_phy_info *phy = &hw->phy; struct e1000_dev_spec_82541 *dev_spec; @@ -779,8 +786,10 @@ e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, boolean_t link_up) } } else { if (dev_spec->dsp_config == e1000_dsp_config_activated) { - /* Save off the current value of register 0x2F5B - * to be restored at the end of the routines. */ + /* + * Save off the current value of register 0x2F5B + * to be restored at the end of the routines. + */ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); @@ -839,8 +848,10 @@ e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, boolean_t link_up) goto out; } - /* Save off the current value of register 0x2F5B - * to be restored at the end of the routines. */ + /* + * Save off the current value of register 0x2F5B + * to be restored at the end of the routines. + */ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); if (ret_val) goto out; @@ -897,8 +908,7 @@ out: * for each channel. This is a function pointer entry point called by the * api module. **/ -STATIC s32 -e1000_get_cable_length_igp_82541(struct e1000_hw *hw) +STATIC s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -973,8 +983,7 @@ out: * maintained. This is a function pointer entry point called by the * api module. **/ -STATIC s32 -e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, boolean_t active) +STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1002,10 +1011,12 @@ e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, boolean_t active) if (ret_val) goto out; - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used + /* + * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. */ + * SmartSpeed, so performance is maintained. + */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -1066,8 +1077,7 @@ out: * of the LED so it can be later restored. This is a function pointer entry * point called by the api module. **/ -STATIC s32 -e1000_setup_led_82541(struct e1000_hw *hw) +STATIC s32 e1000_setup_led_82541(struct e1000_hw *hw) { struct e1000_dev_spec_82541 *dev_spec; s32 ret_val; @@ -1103,8 +1113,7 @@ out: * to the default value, saved from the EEPROM. This is a function pointer * entry point called by the api module. **/ -STATIC s32 -e1000_cleanup_led_82541(struct e1000_hw *hw) +STATIC s32 e1000_cleanup_led_82541(struct e1000_hw *hw) { struct e1000_dev_spec_82541 *dev_spec; s32 ret_val; @@ -1131,8 +1140,7 @@ out: * * Initializes the IGP PHY. **/ -static s32 -e1000_phy_init_script_82541(struct e1000_hw *hw) +static s32 e1000_phy_init_script_82541(struct e1000_hw *hw) { struct e1000_dev_spec_82541 *dev_spec; u32 ret_val; @@ -1150,8 +1158,10 @@ e1000_phy_init_script_82541(struct e1000_hw *hw) /* Delay after phy reset to enable NVM configuration to load */ msec_delay(20); - /* Save off the current value of register 0x2F5B to be restored at - * the end of this routine. */ + /* + * Save off the current value of register 0x2F5B to be restored at + * the end of this routine. + */ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); /* Disabled the PHY transmitter */ @@ -1247,8 +1257,7 @@ out: * Allows the driver to enable/disable the PHY init script, if the PHY is an * IGP PHY. This is a function pointer entry point called by the api module. **/ -void -e1000_init_script_state_82541(struct e1000_hw *hw, boolean_t state) +void e1000_init_script_state_82541(struct e1000_hw *hw, bool state) { struct e1000_dev_spec_82541 *dev_spec; @@ -1261,7 +1270,7 @@ e1000_init_script_state_82541(struct e1000_hw *hw, boolean_t state) dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); goto out; } @@ -1272,14 +1281,29 @@ out: return; } +/** + * e1000_power_down_phy_copper_82541 - Remove link in case of PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, remove the link. + **/ +STATIC void e1000_power_down_phy_copper_82541(struct e1000_hw *hw) +{ + /* If the management interface is not enabled, then power down */ + if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_SMBUS_EN)) + e1000_power_down_phy_copper(hw); + + return; +} + /** * e1000_clear_hw_cntrs_82541 - Clear device specific hardware counters * @hw: pointer to the HW structure * * Clears the hardware counters by reading the counter registers. **/ -STATIC void -e1000_clear_hw_cntrs_82541(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82541.h b/sys/dev/em/e1000_82541.h index 1b1735b5baea..e72cb83b715f 100644 --- a/sys/dev/em/e1000_82541.h +++ b/sys/dev/em/e1000_82541.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_82541_H_ diff --git a/sys/dev/em/e1000_82542.c b/sys/dev/em/e1000_82542.c index c03dbde46800..eb92da661223 100644 --- a/sys/dev/em/e1000_82542.c +++ b/sys/dev/em/e1000_82542.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ /* e1000_82542 (rev 1 & 2) @@ -52,7 +52,7 @@ STATIC s32 e1000_led_off_82542(struct e1000_hw *hw); STATIC void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw); struct e1000_dev_spec_82542 { - boolean_t dma_fairness; + bool dma_fairness; }; /** @@ -61,8 +61,7 @@ struct e1000_dev_spec_82542 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_phy_params_82542(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_82542(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -80,8 +79,7 @@ e1000_init_phy_params_82542(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_nvm_params_82542(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_82542(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; @@ -110,8 +108,7 @@ e1000_init_nvm_params_82542(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_mac_params_82542(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_82542(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -120,7 +117,7 @@ e1000_init_mac_params_82542(struct e1000_hw *hw) DEBUGFUNC("e1000_init_mac_params_82542"); /* Set media type */ - hw->media_type = e1000_media_type_fiber; + hw->phy.media_type = e1000_media_type_fiber; /* Set mta register count */ mac->mta_reg_count = 128; @@ -142,7 +139,7 @@ e1000_init_mac_params_82542(struct e1000_hw *hw) /* check for link */ func->check_for_link = e1000_check_for_fiber_link_generic; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_generic; + func->update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ func->write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ @@ -174,8 +171,7 @@ e1000_init_mac_params_82542(struct e1000_hw *hw) * The only function explicitly called by the api module to initialize * all function pointers and parameters. **/ -void -e1000_init_function_pointers_82542(struct e1000_hw *hw) +void e1000_init_function_pointers_82542(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82542"); @@ -192,8 +188,7 @@ e1000_init_function_pointers_82542(struct e1000_hw *hw) * adaper is attached and stores it in the hw structure. This is a function * pointer entry point called by the api module. **/ -STATIC s32 -e1000_get_bus_info_82542(struct e1000_hw *hw) +STATIC s32 e1000_get_bus_info_82542(struct e1000_hw *hw) { DEBUGFUNC("e1000_get_bus_info_82542"); @@ -211,8 +206,7 @@ e1000_get_bus_info_82542(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_reset_hw_82542(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_82542(struct e1000_hw *hw) { struct e1000_bus_info *bus = &hw->bus; s32 ret_val = E1000_SUCCESS; @@ -232,7 +226,8 @@ e1000_reset_hw_82542(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); E1000_WRITE_FLUSH(hw); - /* Delay to allow any outstanding PCI transactions to complete before + /* + * Delay to allow any outstanding PCI transactions to complete before * resetting the device */ msec_delay(10); @@ -263,8 +258,7 @@ e1000_reset_hw_82542(struct e1000_hw *hw) * This inits the hardware readying it for operation. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_hw_82542(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_82542(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_dev_spec_82542 *dev_spec; @@ -306,7 +300,8 @@ e1000_init_hw_82542(struct e1000_hw *hw) for (i = 0; i < mac->mta_reg_count; i++) E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); - /* Set the PCI priority bit correctly in the CTRL register. This + /* + * Set the PCI priority bit correctly in the CTRL register. This * determines if the adapter gives priority to receives, or if it * gives equal priority to transmits and receives. */ @@ -318,7 +313,8 @@ e1000_init_hw_82542(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = e1000_setup_link_82542(hw); - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. @@ -339,8 +335,7 @@ e1000_init_hw_82542(struct e1000_hw *hw) * and the transmitter and receiver are not enabled. This is a function * pointer entry point called by the api module. **/ -STATIC s32 -e1000_setup_link_82542(struct e1000_hw *hw) +STATIC s32 e1000_setup_link_82542(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -352,25 +347,27 @@ e1000_setup_link_82542(struct e1000_hw *hw) if (ret_val) goto out; - mac->fc &= ~e1000_fc_tx_pause; + hw->fc.type &= ~e1000_fc_tx_pause; if (mac->report_tx_early == 1) - mac->fc &= ~e1000_fc_rx_pause; + hw->fc.type &= ~e1000_fc_rx_pause; - /* We want to save off the original Flow Control configuration just in + /* + * We want to save off the original Flow Control configuration just in * case we get disconnected and then reconnected into a different hub * or switch with different Flow Control capabilities. */ - mac->original_fc = mac->fc; + hw->fc.original_type = hw->fc.type; - DEBUGOUT1("After fix-ups FlowControl is now = %x\n", mac->fc); + DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); /* Call the necessary subroutine to configure the link. */ ret_val = func->setup_physical_interface(hw); if (ret_val) goto out; - /* Initialize the flow control address, type, and PAUSE timer + /* + * Initialize the flow control address, type, and PAUSE timer * registers to their default values. This is done even if flow * control is disabled, because it does not hurt anything to * initialize these registers. @@ -381,7 +378,7 @@ e1000_setup_link_82542(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH); E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE); - E1000_WRITE_REG(hw, E1000_FCTTV, mac->fc_pause_time); + E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); ret_val = e1000_set_fc_watermarks_generic(hw); @@ -396,8 +393,7 @@ out: * Turns the SW defined LED on. This is a function pointer entry point * called by the api module. **/ -STATIC s32 -e1000_led_on_82542(struct e1000_hw *hw) +STATIC s32 e1000_led_on_82542(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -417,8 +413,7 @@ e1000_led_on_82542(struct e1000_hw *hw) * Turns the SW defined LED off. This is a function pointer entry point * called by the api module. **/ -STATIC s32 -e1000_led_off_82542(struct e1000_hw *hw) +STATIC s32 e1000_led_off_82542(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -440,10 +435,10 @@ e1000_led_off_82542(struct e1000_hw *hw) * the name of the register to read and returns the correct offset for * 82542 silicon. **/ -u32 -e1000_translate_register_82542(u32 reg) +u32 e1000_translate_register_82542(u32 reg) { - /* Some of the 82542 registers are located at different + /* + * Some of the 82542 registers are located at different * offsets than they are in newer adapters. * Despite the difference in location, the registers * function in the same manner. @@ -455,34 +450,34 @@ e1000_translate_register_82542(u32 reg) case E1000_RDTR: reg = 0x00108; break; - case E1000_RDBAL: + case E1000_RDBAL(0): reg = 0x00110; break; - case E1000_RDBAH: + case E1000_RDBAH(0): reg = 0x00114; break; - case E1000_RDLEN: + case E1000_RDLEN(0): reg = 0x00118; break; - case E1000_RDH: + case E1000_RDH(0): reg = 0x00120; break; - case E1000_RDT: + case E1000_RDT(0): reg = 0x00128; break; - case E1000_RDBAL1: + case E1000_RDBAL(1): reg = 0x00138; break; - case E1000_RDBAH1: + case E1000_RDBAH(1): reg = 0x0013C; break; - case E1000_RDLEN1: + case E1000_RDLEN(1): reg = 0x00140; break; - case E1000_RDH1: + case E1000_RDH(1): reg = 0x00148; break; - case E1000_RDT1: + case E1000_RDT(1): reg = 0x00150; break; case E1000_FCRTH: @@ -494,19 +489,19 @@ e1000_translate_register_82542(u32 reg) case E1000_MTA: reg = 0x00200; break; - case E1000_TDBAL: + case E1000_TDBAL(0): reg = 0x00420; break; - case E1000_TDBAH: + case E1000_TDBAH(0): reg = 0x00424; break; - case E1000_TDLEN: + case E1000_TDLEN(0): reg = 0x00428; break; - case E1000_TDH: + case E1000_TDH(0): reg = 0x00430; break; - case E1000_TDT: + case E1000_TDT(0): reg = 0x00438; break; case E1000_TIDV: @@ -534,8 +529,7 @@ e1000_translate_register_82542(u32 reg) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void -e1000_clear_hw_cntrs_82542(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82543.c b/sys/dev/em/e1000_82543.c index f820568bad24..13f2ff953d3b 100644 --- a/sys/dev/em/e1000_82543.c +++ b/sys/dev/em/e1000_82543.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ /* e1000_82543 @@ -42,43 +42,43 @@ void e1000_init_function_pointers_82543(struct e1000_hw *hw); -STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_82543(struct e1000_hw *hw); -STATIC s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, - u16 *data); -STATIC s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, - u16 data); -STATIC s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw); -STATIC s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw); -STATIC s32 e1000_reset_hw_82543(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_82543(struct e1000_hw *hw); -STATIC s32 e1000_setup_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_led_on_82543(struct e1000_hw *hw); -STATIC s32 e1000_led_off_82543(struct e1000_hw *hw); -STATIC void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, - u32 value); -STATIC void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value); -STATIC void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw); -static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw); -static boolean_t e1000_init_phy_disabled_82543(struct e1000_hw *hw); -static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl); -static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw); -static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl); -static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw); -static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data, - u16 count); -static boolean_t e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw); -static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, boolean_t state); +STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw); +STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw); +STATIC s32 e1000_init_mac_params_82543(struct e1000_hw *hw); +STATIC s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, + u16 *data); +STATIC s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, + u16 data); +STATIC s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw); +STATIC s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw); +STATIC s32 e1000_reset_hw_82543(struct e1000_hw *hw); +STATIC s32 e1000_init_hw_82543(struct e1000_hw *hw); +STATIC s32 e1000_setup_link_82543(struct e1000_hw *hw); +STATIC s32 e1000_setup_copper_link_82543(struct e1000_hw *hw); +STATIC s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw); +STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw); +STATIC s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw); +STATIC s32 e1000_led_on_82543(struct e1000_hw *hw); +STATIC s32 e1000_led_off_82543(struct e1000_hw *hw); +STATIC void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, + u32 value); +STATIC void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value); +STATIC void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw); +static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw); +static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw); +static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl); +static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw); +static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl); +static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw); +static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data, + u16 count); +static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw); +static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state); struct e1000_dev_spec_82543 { u32 tbi_compatibility; - boolean_t dma_fairness; - boolean_t init_phy_disabled; + bool dma_fairness; + bool init_phy_disabled; }; /** @@ -87,8 +87,7 @@ struct e1000_dev_spec_82543 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_phy_params_82543(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_functions *func = &hw->func; @@ -96,9 +95,12 @@ e1000_init_phy_params_82543(struct e1000_hw *hw) DEBUGFUNC("e1000_init_phy_params_82543"); - if (hw->media_type != e1000_media_type_copper) { + if (hw->phy.media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; goto out; + } else { + func->power_up_phy = e1000_power_up_phy_copper; + func->power_down_phy = e1000_power_down_phy_copper; } phy->addr = 1; @@ -123,7 +125,8 @@ e1000_init_phy_params_82543(struct e1000_hw *hw) : e1000_write_phy_reg_m88; func->get_phy_info = e1000_get_phy_info_m88; - /* The external PHY of the 82543 can be in a funky state. + /* + * The external PHY of the 82543 can be in a funky state. * Resetting helps us read the PHY registers for acquiring * the PHY ID. */ @@ -170,8 +173,7 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_nvm_params_82543(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; @@ -200,8 +202,7 @@ e1000_init_nvm_params_82543(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_mac_params_82543(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -213,10 +214,10 @@ e1000_init_mac_params_82543(struct e1000_hw *hw) switch (hw->device_id) { case E1000_DEV_ID_82543GC_FIBER: case E1000_DEV_ID_82544EI_FIBER: - hw->media_type = e1000_media_type_fiber; + hw->phy.media_type = e1000_media_type_fiber; break; default: - hw->media_type = e1000_media_type_copper; + hw->phy.media_type = e1000_media_type_copper; break; } @@ -237,21 +238,21 @@ e1000_init_mac_params_82543(struct e1000_hw *hw) func->setup_link = e1000_setup_link_82543; /* physical interface setup */ func->setup_physical_interface = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82543 : e1000_setup_fiber_link_82543; /* check for link */ func->check_for_link = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_check_for_copper_link_82543 : e1000_check_for_fiber_link_82543; /* link info */ func->get_link_up_info = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_get_speed_and_duplex_copper_generic : e1000_get_speed_and_duplex_fiber_serdes_generic; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_generic; + func->update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ func->write_vfta = e1000_write_vfta_82543; /* clearing VFTA */ @@ -275,7 +276,7 @@ e1000_init_mac_params_82543(struct e1000_hw *hw) /* Set tbi compatibility */ if ((hw->mac.type != e1000_82543) || - (hw->media_type == e1000_media_type_fiber)) + (hw->phy.media_type == e1000_media_type_fiber)) e1000_set_tbi_compatibility_82543(hw, FALSE); out: @@ -289,8 +290,7 @@ out: * The only function explicitly called by the api module to initialize * all function pointers and parameters. **/ -void -e1000_init_function_pointers_82543(struct e1000_hw *hw) +void e1000_init_function_pointers_82543(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82543"); @@ -306,11 +306,10 @@ e1000_init_function_pointers_82543(struct e1000_hw *hw) * Returns the curent status of 10-bit Interface (TBI) compatibility * (enabled/disabled). **/ -static boolean_t -e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw) +static bool e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw) { struct e1000_dev_spec_82543 *dev_spec; - boolean_t state = FALSE; + bool state = FALSE; DEBUGFUNC("e1000_tbi_compatibility_enabled_82543"); @@ -321,7 +320,7 @@ e1000_tbi_compatibility_enabled_82543(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_82543 *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); goto out; } @@ -340,8 +339,7 @@ out: * * Enables or disabled 10-bit Interface (TBI) compatibility. **/ -void -e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, boolean_t state) +void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, bool state) { struct e1000_dev_spec_82543 *dev_spec; @@ -354,7 +352,7 @@ e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, boolean_t state) dev_spec = (struct e1000_dev_spec_82543 *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); goto out; } @@ -375,11 +373,10 @@ out: * Returns the curent status of 10-bit Interface (TBI) store bad packet (SBP) * (enabled/disabled). **/ -boolean_t -e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw) +bool e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw) { struct e1000_dev_spec_82543 *dev_spec; - boolean_t state = FALSE; + bool state = FALSE; DEBUGFUNC("e1000_tbi_sbp_enabled_82543"); @@ -390,7 +387,7 @@ e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_82543 *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); goto out; } @@ -409,8 +406,7 @@ out: * * Enables or disabled 10-bit Interface (TBI) store bad packet (SBP). **/ -static void -e1000_set_tbi_sbp_82543(struct e1000_hw *hw, boolean_t state) +static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state) { struct e1000_dev_spec_82543 *dev_spec; @@ -433,11 +429,10 @@ e1000_set_tbi_sbp_82543(struct e1000_hw *hw, boolean_t state) * Returns the current status of whether PHY initialization is disabled. * True if PHY initialization is disabled else false. **/ -static boolean_t -e1000_init_phy_disabled_82543(struct e1000_hw *hw) +static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw) { struct e1000_dev_spec_82543 *dev_spec; - boolean_t ret_val; + bool ret_val; DEBUGFUNC("e1000_init_phy_disabled_82543"); @@ -448,7 +443,7 @@ e1000_init_phy_disabled_82543(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_82543 *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); ret_val = FALSE; goto out; @@ -466,21 +461,21 @@ out: * @stats: Struct containing statistic register values * @frame_len: The length of the frame in question * @mac_addr: The Ethernet destination address of the frame in question + * @max_frame_size: The maximum frame size * * Adjusts the statistic counters when a frame is accepted by TBI_ACCEPT **/ -void -e1000_tbi_adjust_stats_82543(struct e1000_hw *hw, struct e1000_hw_stats *stats, - u32 frame_len, u8 *mac_addr) +void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw, + struct e1000_hw_stats *stats, u32 frame_len, + u8 *mac_addr, u32 max_frame_size) { - u64 carry_bit; - - if (e1000_tbi_sbp_enabled_82543(hw) == FALSE) + if (!(e1000_tbi_sbp_enabled_82543(hw))) goto out; /* First adjust the frame length. */ frame_len--; - /* We need to adjust the statistics counters, since the hardware + /* + * We need to adjust the statistics counters, since the hardware * counters overcount this packet as a CRC error and undercount * the packet as a good packet */ @@ -490,18 +485,10 @@ e1000_tbi_adjust_stats_82543(struct e1000_hw *hw, struct e1000_hw_stats *stats, stats->gprc++; /* Adjust the Good Octets received counters */ - carry_bit = 0x80000000 & stats->gorcl; - stats->gorcl += frame_len; - /* If the high bit of Gorcl (the low 32 bits of the Good Octets - * Received Count) was one before the addition, - * AND it is zero after, then we lost the carry out, - * need to add one to Gorch (Good Octets Received Count High). - * This could be simplified if all environments supported - * 64-bit integers. - */ - if (carry_bit && ((stats->gorcl & 0x80000000) == 0)) - stats->gorch++; - /* Is this a broadcast or multicast? Check broadcast first, + stats->gorc += frame_len; + + /* + * Is this a broadcast or multicast? Check broadcast first, * since the test for a multicast frame will test positive on * a broadcast frame. */ @@ -512,13 +499,15 @@ e1000_tbi_adjust_stats_82543(struct e1000_hw *hw, struct e1000_hw_stats *stats, /* Multicast packet */ stats->mprc++; - /* In this case, the hardware has overcounted the number of + /* + * In this case, the hardware has overcounted the number of * oversize frames. */ - if ((frame_len == hw->mac.max_frame_size) && (stats->roc > 0)) + if ((frame_len == max_frame_size) && (stats->roc > 0)) stats->roc--; - /* Adjust the bin counters when the extra byte put the frame in the + /* + * Adjust the bin counters when the extra byte put the frame in the * wrong bin. Remember that the frame_len was adjusted above. */ if (frame_len == 64) { @@ -552,8 +541,7 @@ out: * * Reads the PHY at offset and stores the information read to data. **/ -STATIC s32 -e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data) +STATIC s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data) { u32 mdic; s32 ret_val = E1000_SUCCESS; @@ -566,13 +554,15 @@ e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data) goto out; } - /* We must first send a preamble through the MDIO pin to signal the + /* + * We must first send a preamble through the MDIO pin to signal the * beginning of an MII instruction. This is done by sending 32 * consecutive "1" bits. */ e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE); - /* Now combine the next few fields that are required for a read + /* + * Now combine the next few fields that are required for a read * operation. We use this method instead of calling the * e1000_shift_out_mdi_bits routine five different times. The format * of an MII read instruction consists of a shift out of 14 bits and @@ -588,7 +578,8 @@ e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data) e1000_shift_out_mdi_bits_82543(hw, mdic, 14); - /* Now that we've shifted out the read command to the MII, we need to + /* + * Now that we've shifted out the read command to the MII, we need to * "shift in" the 16-bit value (18 total bits) of the requested PHY * register address. */ @@ -606,8 +597,7 @@ out: * * Writes data to the PHY at offset. **/ -STATIC s32 -e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data) +STATIC s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data) { u32 mdic; s32 ret_val = E1000_SUCCESS; @@ -620,14 +610,16 @@ e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - /* We'll need to use the SW defined pins to shift the write command + /* + * We'll need to use the SW defined pins to shift the write command * out to the PHY. We first send a preamble to the PHY to signal the * beginning of the MII instruction. This is done by sending 32 * consecutive "1" bits. */ e1000_shift_out_mdi_bits_82543(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE); - /* Now combine the remaining required fields that will indicate a + /* + * Now combine the remaining required fields that will indicate a * write operation. We use this method instead of calling the * e1000_shift_out_mdi_bits routine for each field in the command. The * format of a MII write instruction is as follows: @@ -652,10 +644,10 @@ out: * Raise the management data input clock by setting the MDC bit in the control * register. **/ -static void -e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl) +static void e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl) { - /* Raise the clock input to the Management Data Clock (by setting the + /* + * Raise the clock input to the Management Data Clock (by setting the * MDC bit), and then delay a sufficient amount of time. */ E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl | E1000_CTRL_MDC)); @@ -671,10 +663,10 @@ e1000_raise_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl) * Lower the management data input clock by clearing the MDC bit in the control * register. **/ -static void -e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl) +static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl) { - /* Lower the clock input to the Management Data Clock (by clearing the + /* + * Lower the clock input to the Management Data Clock (by clearing the * MDC bit), and then delay a sufficient amount of time. */ E1000_WRITE_REG(hw, E1000_CTRL, (*ctrl & ~E1000_CTRL_MDC)); @@ -692,12 +684,13 @@ e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl) * "data" parameter will be shifted out to the PHY one bit at a time. * In order to do this, "data" must be broken down into bits. **/ -static void -e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data, u16 count) +static void e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data, + u16 count) { u32 ctrl, mask; - /* We need to shift "count" number of bits out to the PHY. So, the + /* + * We need to shift "count" number of bits out to the PHY. So, the * value in the "data" parameter will be shifted out to the PHY one * bit at a time. In order to do this, "data" must be broken down * into bits. @@ -711,7 +704,8 @@ e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data, u16 count) ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR); while (mask) { - /* A "1" is shifted out to the PHY by setting the MDIO bit to + /* + * A "1" is shifted out to the PHY by setting the MDIO bit to * "1" and then raising and lowering the Management Data Clock. * A "0" is shifted out to the PHY by setting the MDIO bit to * "0" and then raising and lowering the clock. @@ -740,14 +734,14 @@ e1000_shift_out_mdi_bits_82543(struct e1000_hw *hw, u32 data, u16 count) * the PHY (setting the MDC bit), and then reading the value of the data out * MDIO bit. **/ -static u16 -e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw) +static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw) { u32 ctrl; u16 data = 0; u8 i; - /* In order to read a register from the PHY, we need to shift in a + /* + * In order to read a register from the PHY, we need to shift in a * total of 18 bits from the PHY. The first two bit (turnaround) * times are used to avoid contention on the MDIO pin when a read * operation is performed. These two bits are ignored by us and @@ -757,7 +751,8 @@ e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw) */ ctrl = E1000_READ_REG(hw, E1000_CTRL); - /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as + /* + * Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as * input. */ ctrl &= ~E1000_CTRL_MDIO_DIR; @@ -766,7 +761,8 @@ e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_CTRL, ctrl); E1000_WRITE_FLUSH(hw); - /* Raise and lower the clock before reading in the data. This accounts + /* + * Raise and lower the clock before reading in the data. This accounts * for the turnaround bits. The first clock occurred when we clocked * out the last bit of the Register Address. */ @@ -797,8 +793,7 @@ e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw) * if the PHY is not auto-negotiating and the speed is forced to 10Mbit, * then call the function for polarity reversal workaround. **/ -STATIC s32 -e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw) +STATIC s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw) { s32 ret_val; @@ -824,13 +819,12 @@ out: * inadvertantly. To workaround the issue, we disable the transmitter on * the PHY until we have established the link partner's link parameters. **/ -static s32 -e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) +static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) { s32 ret_val; u16 mii_status_reg; u16 i; - boolean_t link; + bool link; /* Polarity reversal workaround for forced 10F/10H links. */ @@ -847,11 +841,13 @@ e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) if (ret_val) goto out; - /* This loop will early-out if the NO link condition has been met. + /* + * This loop will early-out if the NO link condition has been met. * In other words, DO NOT use e1000_phy_has_link_generic() here. */ for (i = PHY_FORCE_TIME; i > 0; i--) { - /* Read the MII Status Register and wait for Link Status bit + /* + * Read the MII Status Register and wait for Link Status bit * to be clear. */ @@ -893,7 +889,8 @@ e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) if (ret_val) goto out; - /* Read the MII Status Register and wait for Link Status bit + /* + * Read the MII Status Register and wait for Link Status bit * to be set. */ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_TIME, 100000, &link); @@ -913,8 +910,7 @@ out: * has been accomplished, clear the PHY_RESET_DIR bit to take the PHY out * of reset. This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_phy_hw_reset_82543(struct e1000_hw *hw) +STATIC s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw) { struct e1000_functions *func = &hw->func; u32 ctrl_ext; @@ -922,7 +918,8 @@ e1000_phy_hw_reset_82543(struct e1000_hw *hw) DEBUGFUNC("e1000_phy_hw_reset_82543"); - /* Read the Extended Device Control Register, assert the PHY_RESET_DIR + /* + * Read the Extended Device Control Register, assert the PHY_RESET_DIR * bit to put the PHY into reset... */ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); @@ -952,8 +949,7 @@ e1000_phy_hw_reset_82543(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_reset_hw_82543(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_82543(struct e1000_hw *hw) { u32 ctrl, icr; s32 ret_val = E1000_SUCCESS; @@ -969,7 +965,8 @@ e1000_reset_hw_82543(struct e1000_hw *hw) e1000_set_tbi_sbp_82543(hw, FALSE); - /* Delay to allow any outstanding PCI transactions to complete before + /* + * Delay to allow any outstanding PCI transactions to complete before * resetting the device */ msec_delay(10); @@ -980,13 +977,15 @@ e1000_reset_hw_82543(struct e1000_hw *hw) if (hw->mac.type == e1000_82543) { E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); } else { - /* The 82544 can't ACK the 64-bit write when issuing the + /* + * The 82544 can't ACK the 64-bit write when issuing the * reset, so use IO-mapping as a workaround. */ E1000_WRITE_REG_IO(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); } - /* After MAC reset, force reload of NVM to restore power-on + /* + * After MAC reset, force reload of NVM to restore power-on * settings to device. */ e1000_reload_nvm(hw); @@ -1005,8 +1004,7 @@ e1000_reset_hw_82543(struct e1000_hw *hw) * * This inits the hardware readying it for operation. **/ -STATIC s32 -e1000_init_hw_82543(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_dev_spec_82543 *dev_spec; @@ -1018,7 +1016,7 @@ e1000_init_hw_82543(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_82543 *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); ret_val = -E1000_ERR_CONFIG; goto out; @@ -1038,7 +1036,8 @@ e1000_init_hw_82543(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); } - /* Set the PCI priority bit correctly in the CTRL register. This + /* + * Set the PCI priority bit correctly in the CTRL register. This * determines if the adapter gives priority to receives, or if it * gives equal priority to transmits and receives. */ @@ -1052,7 +1051,8 @@ e1000_init_hw_82543(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = e1000_setup_link(hw); - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. @@ -1076,8 +1076,7 @@ out: * should be established. Assumes the hardware has previously been reset * and the transmitter and receiver are not enabled. **/ -STATIC s32 -e1000_setup_link_82543(struct e1000_hw *hw) +STATIC s32 e1000_setup_link_82543(struct e1000_hw *hw) { u32 ctrl_ext; s32 ret_val; @@ -1085,7 +1084,8 @@ e1000_setup_link_82543(struct e1000_hw *hw) DEBUGFUNC("e1000_setup_link_82543"); - /* Take the 4 bits from NVM word 0xF that determine the initial + /* + * Take the 4 bits from NVM word 0xF that determine the initial * polarity value for the SW controlled pins, and setup the * Extended Device Control reg with that info. * This is needed because one of the SW controlled pins is used for @@ -1117,17 +1117,17 @@ out: * for link, once link is established calls to configure collision distance * and flow control are called. **/ -STATIC s32 -e1000_setup_copper_link_82543(struct e1000_hw *hw) +STATIC s32 e1000_setup_copper_link_82543(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; - boolean_t link; + bool link; DEBUGFUNC("e1000_setup_copper_link_82543"); ctrl = E1000_READ_REG(hw, E1000_CTRL) | E1000_CTRL_SLU; - /* With 82543, we need to force speed and duplex on the MAC + /* + * With 82543, we need to force speed and duplex on the MAC * equal to what the PHY speed and duplex configuration is. * In addition, we need to perform a hardware reset on the * PHY to take it out of reset. @@ -1150,14 +1150,18 @@ e1000_setup_copper_link_82543(struct e1000_hw *hw) goto out; if (hw->mac.autoneg) { - /* Setup autoneg and flow control advertisement and perform - * autonegotiation. */ + /* + * Setup autoneg and flow control advertisement and perform + * autonegotiation. + */ ret_val = e1000_copper_link_autoneg(hw); if (ret_val) goto out; } else { - /* PHY will be set to 10H, 10F, 100H or 100F - * depending on user settings. */ + /* + * PHY will be set to 10H, 10F, 100H or 100F + * depending on user settings. + */ DEBUGOUT("Forcing Speed and Duplex\n"); ret_val = e1000_phy_force_speed_duplex_82543(hw); if (ret_val) { @@ -1166,7 +1170,8 @@ e1000_setup_copper_link_82543(struct e1000_hw *hw) } } - /* Check link status. Wait up to 100 microseconds for link to become + /* + * Check link status. Wait up to 100 microseconds for link to become * valid. */ ret_val = e1000_phy_has_link_generic(hw, @@ -1180,9 +1185,9 @@ e1000_setup_copper_link_82543(struct e1000_hw *hw) if (link) { DEBUGOUT("Valid link established!!!\n"); /* Config the MAC and PHY after link is up */ - if (hw->mac.type == e1000_82544) + if (hw->mac.type == e1000_82544) { e1000_config_collision_dist_generic(hw); - else { + } else { ret_val = e1000_config_mac_to_phy_82543(hw); if (ret_val) goto out; @@ -1203,8 +1208,7 @@ out: * Configures collision distance and flow control for fiber links. Upon * successful setup, poll for link. **/ -STATIC s32 -e1000_setup_fiber_link_82543(struct e1000_hw *hw) +STATIC s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -1228,7 +1232,8 @@ e1000_setup_fiber_link_82543(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); msec_delay(1); - /* For these adapters, the SW defineable pin 1 is cleared when the + /* + * For these adapters, the SW defineable pin 1 is cleared when the * optics detect a signal. If we have a signal, then poll for a * "Link-Up" indication. */ @@ -1253,14 +1258,13 @@ out: * - configure flow control after link up * - configure tbi compatibility **/ -STATIC s32 -e1000_check_for_copper_link_82543(struct e1000_hw *hw) +STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 icr, rctl; s32 ret_val; u16 speed, duplex; - boolean_t link; + bool link; DEBUGFUNC("e1000_check_for_copper_link_82543"); @@ -1280,11 +1284,13 @@ e1000_check_for_copper_link_82543(struct e1000_hw *hw) e1000_check_downshift_generic(hw); - /* If we are forcing speed/duplex, then we can return since + /* + * If we are forcing speed/duplex, then we can return since * we have already determined whether we have link or not. */ if (!mac->autoneg) { - /* If speed and duplex are forced to 10H or 10F, then we will + /* + * If speed and duplex are forced to 10H or 10F, then we will * implement the polarity reversal workaround. We disable * interrupts first, and upon returning, place the devices * interrupt state to its previous value except for the link @@ -1303,7 +1309,8 @@ e1000_check_for_copper_link_82543(struct e1000_hw *hw) goto out; } - /* We have a M88E1000 PHY and Auto-Neg is enabled. If we + /* + * We have a M88E1000 PHY and Auto-Neg is enabled. If we * have Si on board that is 82544 or newer, Auto * Speed Detection takes care of MAC speed/duplex * configuration. So we only need to configure Collision @@ -1321,7 +1328,8 @@ e1000_check_for_copper_link_82543(struct e1000_hw *hw) } } - /* Configure Flow Control now that Auto-Neg has completed. + /* + * Configure Flow Control now that Auto-Neg has completed. * First, we need to restore the desired flow control * settings because we may have had to re-autoneg with a * different link partner. @@ -1331,7 +1339,8 @@ e1000_check_for_copper_link_82543(struct e1000_hw *hw) DEBUGOUT("Error configuring flow control\n"); } - /* At this point we know that we are on copper and we have + /* + * At this point we know that we are on copper and we have * auto-negotiated link. These are conditions for checking the link * partner capability register. We use the link speed to determine if * TBI compatibility needs to be turned on or off. If the link is not @@ -1345,11 +1354,13 @@ e1000_check_for_copper_link_82543(struct e1000_hw *hw) return ret_val; } if (speed != SPEED_1000) { - /* If link speed is not set to gigabit speed, + /* + * If link speed is not set to gigabit speed, * we do not need to enable TBI compatibility. */ if (e1000_tbi_sbp_enabled_82543(hw)) { - /* If we previously were in the mode, + /* + * If we previously were in the mode, * turn it off. */ e1000_set_tbi_sbp_82543(hw, FALSE); @@ -1358,7 +1369,8 @@ e1000_check_for_copper_link_82543(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_RCTL, rctl); } } else { - /* If TBI compatibility is was previously off, + /* + * If TBI compatibility is was previously off, * turn it on. For compatibility with a TBI link * partner, we will store bad packets. Some * frames have an additional byte on the end and @@ -1383,8 +1395,7 @@ out: * Checks for link up on the hardware. If link is not up and we have * a signal, then we need to force link up. **/ -STATIC s32 -e1000_check_for_fiber_link_82543(struct e1000_hw *hw) +STATIC s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 rxcw, ctrl, status; @@ -1393,10 +1404,11 @@ e1000_check_for_fiber_link_82543(struct e1000_hw *hw) DEBUGFUNC("e1000_check_for_fiber_link_82543"); ctrl = E1000_READ_REG(hw, E1000_CTRL); - status = E1000_READ_REG(hw, E1000_CTRL); - rxcw = E1000_READ_REG(hw, E1000_CTRL); + status = E1000_READ_REG(hw, E1000_STATUS); + rxcw = E1000_READ_REG(hw, E1000_RXCW); - /* If we don't have link (auto-negotiation failed or link partner + /* + * If we don't have link (auto-negotiation failed or link partner * cannot auto-negotiate), the cable is plugged in (we have signal), * and our link partner is not trying to auto-negotiate with us (we * are receiving idles or data), we need to force link up. We also @@ -1429,7 +1441,8 @@ e1000_check_for_fiber_link_82543(struct e1000_hw *hw) goto out; } } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - /* If we are forcing link and we are receiving /C/ ordered + /* + * If we are forcing link and we are receiving /C/ ordered * sets, re-enable auto-negotiation in the TXCW register * and disable forced link in the Device Control register * in an attempt to auto-negotiate with our link partner. @@ -1452,8 +1465,7 @@ out: * For the 82543 silicon, we need to set the MAC to match the settings * of the PHY, even if the PHY is auto-negotiating. **/ -static s32 -e1000_config_mac_to_phy_82543(struct e1000_hw *hw) +static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -1466,7 +1478,8 @@ e1000_config_mac_to_phy_82543(struct e1000_hw *hw) ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS); - /* Set up duplex in the Device Control and Transmit Control + /* + * Set up duplex in the Device Control and Transmit Control * registers depending on negotiated values. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); @@ -1479,7 +1492,8 @@ e1000_config_mac_to_phy_82543(struct e1000_hw *hw) e1000_config_collision_dist_generic(hw); - /* Set up speed in the Device Control register depending on + /* + * Set up speed in the Device Control register depending on * negotiated values. */ if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) @@ -1502,8 +1516,7 @@ out: * This writes a 32-bit value to a 32-bit offset in the VLAN filter * table. **/ -STATIC void -e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) +STATIC void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) { u32 temp; @@ -1515,8 +1528,9 @@ e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) E1000_WRITE_FLUSH(hw); E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset - 1, temp); E1000_WRITE_FLUSH(hw); - } else + } else { e1000_write_vfta_generic(hw, offset, value); + } } /** @@ -1529,8 +1543,7 @@ e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) * current value is read, the new bit is OR'd in and the new value is * written back into the register. **/ -STATIC void -e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) +STATIC void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) { u32 hash_bit, hash_reg, mta, temp; @@ -1538,7 +1551,8 @@ e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) hash_reg = (hash_value >> 5); - /* If we are on an 82544 and we are trying to write an odd offset + /* + * If we are on an 82544 and we are trying to write an odd offset * in the MTA, save off the previous entry before writing and * restore the old value after writing. */ @@ -1553,8 +1567,9 @@ e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) E1000_WRITE_FLUSH(hw); E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg - 1, temp); E1000_WRITE_FLUSH(hw); - } else + } else { e1000_mta_set_generic(hw, hash_value); + } } /** @@ -1564,15 +1579,14 @@ e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) * Turns the SW defined LED on. This is a function pointer entry point * called by the api module. **/ -STATIC s32 -e1000_led_on_82543(struct e1000_hw *hw) +STATIC s32 e1000_led_on_82543(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); DEBUGFUNC("e1000_led_on_82543"); if (hw->mac.type == e1000_82544 && - hw->media_type == e1000_media_type_copper) { + hw->phy.media_type == e1000_media_type_copper) { /* Clear SW-defineable Pin 0 to turn on the LED */ ctrl &= ~E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; @@ -1593,15 +1607,14 @@ e1000_led_on_82543(struct e1000_hw *hw) * Turns the SW defined LED off. This is a function pointer entry point * called by the api module. **/ -STATIC s32 -e1000_led_off_82543(struct e1000_hw *hw) +STATIC s32 e1000_led_off_82543(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); DEBUGFUNC("e1000_led_off_82543"); if (hw->mac.type == e1000_82544 && - hw->media_type == e1000_media_type_copper) { + hw->phy.media_type == e1000_media_type_copper) { /* Set SW-defineable Pin 0 to turn off the LED */ ctrl |= E1000_CTRL_SWDPIN0; ctrl |= E1000_CTRL_SWDPIO0; @@ -1620,8 +1633,7 @@ e1000_led_off_82543(struct e1000_hw *hw) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void -e1000_clear_hw_cntrs_82543(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82543.h b/sys/dev/em/e1000_82543.h index b27d1b558beb..dfb1befbc1b8 100644 --- a/sys/dev/em/e1000_82543.h +++ b/sys/dev/em/e1000_82543.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_82543_H_ @@ -44,7 +44,8 @@ #define PHY_TURNAROUND 0x2 #define TBI_COMPAT_ENABLED 0x1 /* Global "knob" for the workaround */ -#define TBI_SBP_ENABLED 0x2 /* If TBI_COMPAT_ENABLED, - * then this is the current state (on/off) */ +/* If TBI_COMPAT_ENABLED, then this is the current state (on/off) */ +#define TBI_SBP_ENABLED 0x2 + #endif diff --git a/sys/dev/em/e1000_82571.c b/sys/dev/em/e1000_82571.c index 8617e6279e0f..1ba6be3045a5 100644 --- a/sys/dev/em/e1000_82571.c +++ b/sys/dev/em/e1000_82571.c @@ -30,12 +30,13 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ /* e1000_82571 * e1000_82572 * e1000_82573 + * e1000_82574 */ #include "e1000_api.h" @@ -54,11 +55,11 @@ STATIC s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw); STATIC s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw); STATIC s32 e1000_get_cfg_done_82571(struct e1000_hw *hw); STATIC s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, - boolean_t active); + bool active); STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw); STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw); STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw); -STATIC void e1000_mc_addr_list_update_82571(struct e1000_hw *hw, +STATIC void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, u32 rar_used_count, u32 rar_count); STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw); @@ -73,9 +74,11 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); +STATIC s32 e1000_read_mac_addr_82571(struct e1000_hw *hw); +STATIC void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); struct e1000_dev_spec_82571 { - boolean_t laa_is_present; + bool laa_is_present; }; /** @@ -84,8 +87,7 @@ struct e1000_dev_spec_82571 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_phy_params_82571(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_functions *func = &hw->func; @@ -93,7 +95,7 @@ e1000_init_phy_params_82571(struct e1000_hw *hw) DEBUGFUNC("e1000_init_phy_params_82571"); - if (hw->media_type != e1000_media_type_copper) { + if (hw->phy.media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; goto out; } @@ -109,6 +111,8 @@ e1000_init_phy_params_82571(struct e1000_hw *hw) func->reset_phy = e1000_phy_hw_reset_generic; func->set_d0_lplu_state = e1000_set_d0_lplu_state_82571; func->set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + func->power_up_phy = e1000_power_up_phy_copper; + func->power_down_phy = e1000_power_down_phy_copper_82571; switch (hw->mac.type) { case e1000_82571: @@ -120,6 +124,15 @@ e1000_init_phy_params_82571(struct e1000_hw *hw) func->get_cable_length = e1000_get_cable_length_igp_2; func->read_phy_reg = e1000_read_phy_reg_igp; func->write_phy_reg = e1000_write_phy_reg_igp; + + /* This uses above function pointers */ + ret_val = e1000_get_phy_id_82571(hw); + + /* Verify PHY ID */ + if (phy->id != IGP01E1000_I_PHY_ID) { + ret_val = -E1000_ERR_PHY; + goto out; + } break; case e1000_82573: phy->type = e1000_phy_m88; @@ -130,28 +143,14 @@ e1000_init_phy_params_82571(struct e1000_hw *hw) func->get_cable_length = e1000_get_cable_length_m88; func->read_phy_reg = e1000_read_phy_reg_m88; func->write_phy_reg = e1000_write_phy_reg_m88; - break; - default: - ret_val = -E1000_ERR_PHY; - goto out; - break; - } - /* This can only be done after all function pointers are setup. */ - ret_val = e1000_get_phy_id_82571(hw); + /* This uses above function pointers */ + ret_val = e1000_get_phy_id_82571(hw); - /* Verify phy id */ - switch (hw->mac.type) { - case e1000_82571: - case e1000_82572: - if (phy->id != IGP01E1000_I_PHY_ID) { - ret_val = -E1000_ERR_PHY; - goto out; - } - break; - case e1000_82573: + /* Verify PHY ID */ if (phy->id != M88E1111_I_PHY_ID) { ret_val = -E1000_ERR_PHY; + DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id); goto out; } break; @@ -171,8 +170,7 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_nvm_params_82571(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; @@ -203,7 +201,8 @@ e1000_init_nvm_params_82571(struct e1000_hw *hw) if (((eecd >> 15) & 0x3) == 0x3) { nvm->type = e1000_nvm_flash_hw; nvm->word_size = 2048; - /* Autonomous Flash update bit must be cleared due + /* + * Autonomous Flash update bit must be cleared due * to Flash update issue. */ eecd &= ~E1000_EECD_AUPDEN; @@ -215,10 +214,15 @@ e1000_init_nvm_params_82571(struct e1000_hw *hw) nvm->type = e1000_nvm_eeprom_spi; size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); - /* Added to a constant, "size" becomes the left-shift value + /* + * Added to a constant, "size" becomes the left-shift value * for setting word_size. */ size += NVM_WORD_SIZE_BASE_SHIFT; + + /* EEPROM access above 16k is unsupported */ + if (size > 14) + size = 14; nvm->word_size = 1 << size; break; } @@ -243,8 +247,7 @@ e1000_init_nvm_params_82571(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_mac_params_82571(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_82571(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -257,16 +260,16 @@ e1000_init_mac_params_82571(struct e1000_hw *hw) case E1000_DEV_ID_82571EB_FIBER: case E1000_DEV_ID_82572EI_FIBER: case E1000_DEV_ID_82571EB_QUAD_FIBER: - hw->media_type = e1000_media_type_fiber; + hw->phy.media_type = e1000_media_type_fiber; break; case E1000_DEV_ID_82571EB_SERDES: case E1000_DEV_ID_82571EB_SERDES_DUAL: case E1000_DEV_ID_82571EB_SERDES_QUAD: case E1000_DEV_ID_82572EI_SERDES: - hw->media_type = e1000_media_type_internal_serdes; + hw->phy.media_type = e1000_media_type_internal_serdes; break; default: - hw->media_type = e1000_media_type_copper; + hw->phy.media_type = e1000_media_type_copper; break; } @@ -293,11 +296,11 @@ e1000_init_mac_params_82571(struct e1000_hw *hw) func->setup_link = e1000_setup_link_82571; /* physical interface link setup */ func->setup_physical_interface = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82571 : e1000_setup_fiber_serdes_link_82571; /* check for link */ - switch (hw->media_type) { + switch (hw->phy.media_type) { case e1000_media_type_copper: func->check_for_link = e1000_check_for_copper_link_generic; break; @@ -315,13 +318,15 @@ e1000_init_mac_params_82571(struct e1000_hw *hw) /* check management mode */ func->check_mng_mode = e1000_check_mng_mode_generic; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_82571; + func->update_mc_addr_list = e1000_update_mc_addr_list_82571; /* writing VFTA */ func->write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ func->clear_vfta = e1000_clear_vfta_82571; /* setting MTA */ func->mta_set = e1000_mta_set_generic; + /* read mac address */ + func->read_mac_addr = e1000_read_mac_addr_82571; /* blink LED */ func->blink_led = e1000_blink_led_generic; /* setup LED */ @@ -337,7 +342,7 @@ e1000_init_mac_params_82571(struct e1000_hw *hw) func->clear_hw_cntrs = e1000_clear_hw_cntrs_82571; /* link info */ func->get_link_up_info = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_get_speed_and_duplex_copper_generic : e1000_get_speed_and_duplex_fiber_serdes_generic; @@ -357,8 +362,7 @@ out: * The only function explicitly called by the api module to initialize * all function pointers and parameters. **/ -void -e1000_init_function_pointers_82571(struct e1000_hw *hw) +void e1000_init_function_pointers_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82571"); @@ -374,8 +378,7 @@ e1000_init_function_pointers_82571(struct e1000_hw *hw) * Reads the PHY registers and stores the PHY ID and possibly the PHY * revision in the hardware structure. **/ -static s32 -e1000_get_phy_id_82571(struct e1000_hw *hw) +static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -385,10 +388,12 @@ e1000_get_phy_id_82571(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82571: case e1000_82572: - /* The 82571 firmware may still be configuring the PHY. + /* + * The 82571 firmware may still be configuring the PHY. * In this case, we cannot access the PHY until the * configuration is done. So we explicitly set the - * PHY ID. */ + * PHY ID. + */ phy->id = IGP01E1000_I_PHY_ID; break; case e1000_82573: @@ -408,8 +413,7 @@ e1000_get_phy_id_82571(struct e1000_hw *hw) * * Acquire the HW semaphore to access the PHY or NVM **/ -s32 -e1000_get_hw_semaphore_82571(struct e1000_hw *hw) +s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; s32 ret_val = E1000_SUCCESS; @@ -448,8 +452,7 @@ out: * * Release hardware semaphore used to access the PHY or NVM **/ -void -e1000_put_hw_semaphore_82571(struct e1000_hw *hw) +void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) { u32 swsm; @@ -471,8 +474,7 @@ e1000_put_hw_semaphore_82571(struct e1000_hw *hw) * for EEPROM access grant bit. If the access grant bit is not set, release * hardware semaphore. **/ -STATIC s32 -e1000_acquire_nvm_82571(struct e1000_hw *hw) +STATIC s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) { s32 ret_val; @@ -498,8 +500,7 @@ out: * * Stop any current commands to the EEPROM and clear the EEPROM request bit. **/ -STATIC void -e1000_release_nvm_82571(struct e1000_hw *hw) +STATIC void e1000_release_nvm_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_82571"); @@ -519,8 +520,8 @@ e1000_release_nvm_82571(struct e1000_hw *hw) * If e1000_update_nvm_checksum is not called after this function, the * EEPROM will most likley contain an invalid checksum. **/ -STATIC s32 -e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +STATIC s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) { s32 ret_val = E1000_SUCCESS; @@ -550,8 +551,7 @@ e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * up to the checksum. Then calculates the EEPROM checksum and writes the * value to the EEPROM. **/ -STATIC s32 -e1000_update_nvm_checksum_82571(struct e1000_hw *hw) +STATIC s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) { u32 eecd; s32 ret_val; @@ -563,8 +563,10 @@ e1000_update_nvm_checksum_82571(struct e1000_hw *hw) if (ret_val) goto out; - /* If our nvm is an EEPROM, then we're done - * otherwise, commit the checksum to the flash NVM. */ + /* + * If our nvm is an EEPROM, then we're done + * otherwise, commit the checksum to the flash NVM. + */ if (hw->nvm.type != e1000_nvm_flash_hw) goto out; @@ -582,7 +584,8 @@ e1000_update_nvm_checksum_82571(struct e1000_hw *hw) /* Reset the firmware if using STM opcode. */ if ((E1000_READ_REG(hw, E1000_FLOP) & 0xFF00) == E1000_STM_OPCODE) { - /* The enabling of and the actual reset must be done + /* + * The enabling of and the actual reset must be done * in two write cycles. */ E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET_ENABLE); @@ -616,8 +619,7 @@ out: * Calculates the EEPROM checksum by reading/adding each word of the EEPROM * and then verifies that the sum of the EEPROM is equal to 0xBABA. **/ -STATIC s32 -e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) +STATIC s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_validate_nvm_checksum_82571"); @@ -641,9 +643,8 @@ e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) * If e1000_update_nvm_checksum is not called after this function, the * EEPROM will most likley contain an invalid checksum. **/ -static s32 -e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data) +static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, + u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i, eewr = 0; @@ -651,8 +652,10 @@ e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, u16 words, DEBUGFUNC("e1000_write_nvm_eewr_82571"); - /* A check for invalid values: offset too large, too many words, - * and not enough words. */ + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { DEBUGOUT("nvm parameter(s) out of bounds\n"); @@ -686,8 +689,7 @@ out: * * Reads the management control register for the config done bit to be set. **/ -STATIC s32 -e1000_get_cfg_done_82571(struct e1000_hw *hw) +STATIC s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; @@ -721,8 +723,7 @@ out: * of either 10 or 10/100 or 10/100/1000 at all duplexes. This is a function * pointer entry point only called by PHY setup routines. **/ -STATIC s32 -e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, boolean_t active) +STATIC s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -757,10 +758,12 @@ e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, boolean_t active) ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, data); - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used + /* + * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. */ + * SmartSpeed, so performance is maintained. + */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -801,8 +804,7 @@ out: * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_reset_hw_82571(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw) { u32 ctrl, extcnf_ctrl, ctrl_ext, icr; s32 ret_val; @@ -810,7 +812,8 @@ e1000_reset_hw_82571(struct e1000_hw *hw) DEBUGFUNC("e1000_reset_hw_82571"); - /* Prevent the PCI-E bus from sticking if there is no TLP connection + /* + * Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); @@ -827,8 +830,10 @@ e1000_reset_hw_82571(struct e1000_hw *hw) msec_delay(10); - /* Must acquire the MDIO ownership before MAC reset. - * Ownership defaults to firmware after a reset. */ + /* + * Must acquire the MDIO ownership before MAC reset. + * Ownership defaults to firmware after a reset. + */ if (hw->mac.type == e1000_82573) { extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; @@ -865,7 +870,8 @@ e1000_reset_hw_82571(struct e1000_hw *hw) /* We don't want to continue accessing MAC registers. */ goto out; - /* Phy configuration from NVM just starts after EECD_AUTO_RD is set. + /* + * Phy configuration from NVM just starts after EECD_AUTO_RD is set. * Need to wait for Phy configuration completion before accessing * NVM and Phy. */ @@ -876,6 +882,9 @@ e1000_reset_hw_82571(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); icr = E1000_READ_REG(hw, E1000_ICR); + if (!(e1000_check_alt_mac_addr_generic(hw))) + e1000_set_laa_state_82571(hw, TRUE); + out: return ret_val; } @@ -886,8 +895,7 @@ out: * * This inits the hardware readying it for operation. **/ -STATIC s32 -e1000_init_hw_82571(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 reg_data; @@ -902,7 +910,7 @@ e1000_init_hw_82571(struct e1000_hw *hw) ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); - goto out; + /* This is not fatal and we should not stop init due to this */ } /* Disabling VLAN filtering */ @@ -910,11 +918,12 @@ e1000_init_hw_82571(struct e1000_hw *hw) e1000_clear_vfta(hw); /* Setup the receive address. */ - /* If, however, a locally administered address was assigned to the + /* + * If, however, a locally administered address was assigned to the * 82571, we must reserve a RAR for it to work around an issue where * resetting one port will reload the MAC on the other port. */ - if (e1000_get_laa_state_82571(hw) == TRUE) + if (e1000_get_laa_state_82571(hw)) rar_count--; e1000_init_rx_addrs_generic(hw, rar_count); @@ -927,19 +936,19 @@ e1000_init_hw_82571(struct e1000_hw *hw) ret_val = e1000_setup_link(hw); /* Set the transmit descriptor write-back policy */ - reg_data = E1000_READ_REG(hw, E1000_TXDCTL); + reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; - E1000_WRITE_REG(hw, E1000_TXDCTL, reg_data); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); /* ...for both queues. */ if (mac->type != e1000_82573) { - reg_data = E1000_READ_REG(hw, E1000_TXDCTL1); + reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; - E1000_WRITE_REG(hw, E1000_TXDCTL1, reg_data); + E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); } else { e1000_enable_tx_pkt_filtering(hw); reg_data = E1000_READ_REG(hw, E1000_GCR); @@ -947,14 +956,14 @@ e1000_init_hw_82571(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_GCR, reg_data); } - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. */ e1000_clear_hw_cntrs_82571(hw); -out: return ret_val; } @@ -964,8 +973,7 @@ out: * * Initializes required hardware-dependent bits needed for normal operation. **/ -static void -e1000_initialize_hw_bits_82571(struct e1000_hw *hw) +static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) { u32 reg; @@ -975,17 +983,17 @@ e1000_initialize_hw_bits_82571(struct e1000_hw *hw) goto out; /* Transmit Descriptor Control 0 */ - reg = E1000_READ_REG(hw, E1000_TXDCTL); + reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); reg |= (1 << 22); - E1000_WRITE_REG(hw, E1000_TXDCTL, reg); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); /* Transmit Descriptor Control 1 */ - reg = E1000_READ_REG(hw, E1000_TXDCTL1); + reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); reg |= (1 << 22); - E1000_WRITE_REG(hw, E1000_TXDCTL1, reg); + E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); /* Transmit Arbitration Control 0 */ - reg = E1000_READ_REG(hw, E1000_TARC0); + reg = E1000_READ_REG(hw, E1000_TARC(0)); reg &= ~(0xF << 27); /* 30:27 */ switch (hw->mac.type) { case e1000_82571: @@ -995,10 +1003,10 @@ e1000_initialize_hw_bits_82571(struct e1000_hw *hw) default: break; } - E1000_WRITE_REG(hw, E1000_TARC0, reg); + E1000_WRITE_REG(hw, E1000_TARC(0), reg); /* Transmit Arbitration Control 1 */ - reg = E1000_READ_REG(hw, E1000_TARC1); + reg = E1000_READ_REG(hw, E1000_TARC(1)); switch (hw->mac.type) { case e1000_82571: case e1000_82572: @@ -1008,7 +1016,7 @@ e1000_initialize_hw_bits_82571(struct e1000_hw *hw) reg &= ~(1 << 28); else reg |= (1 << 28); - E1000_WRITE_REG(hw, E1000_TARC1, reg); + E1000_WRITE_REG(hw, E1000_TARC(1), reg); break; default: break; @@ -1040,8 +1048,7 @@ out: * Clears the register array which contains the VLAN filter table by * setting all the values to 0. **/ -STATIC void -e1000_clear_vfta_82571(struct e1000_hw *hw) +STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw) { u32 offset; u32 vfta_value = 0; @@ -1052,7 +1059,8 @@ e1000_clear_vfta_82571(struct e1000_hw *hw) if (hw->mac.type == e1000_82573) { if (hw->mng_cookie.vlan_id != 0) { - /* The VFTA is a 4096b bit-field, each identifying + /* + * The VFTA is a 4096b bit-field, each identifying * a single VLAN ID. The following operations * determine which 32b entry (i.e. offset) into the * array we want to set the VLAN ID (i.e. bit) of @@ -1066,7 +1074,8 @@ e1000_clear_vfta_82571(struct e1000_hw *hw) } } for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { - /* If the offset we want to clear is the same offset of the + /* + * If the offset we want to clear is the same offset of the * manageability VLAN ID, then clear all bits except that of * the manageability unit. */ @@ -1077,7 +1086,7 @@ e1000_clear_vfta_82571(struct e1000_hw *hw) } /** - * e1000_mc_addr_list_update_82571 - Update Multicast addresses + * e1000_update_mc_addr_list_82571 - Update Multicast addresses * @hw: pointer to the HW structure * @mc_addr_list: array of multicast addresses to program * @mc_addr_count: number of multicast addresses to program @@ -1089,17 +1098,16 @@ e1000_clear_vfta_82571(struct e1000_hw *hw) * The parameter rar_count will usually be hw->mac.rar_entry_count * unless there are workarounds that change this. **/ -STATIC void -e1000_mc_addr_list_update_82571(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count, - u32 rar_used_count, u32 rar_count) +STATIC void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count, + u32 rar_used_count, u32 rar_count) { - DEBUGFUNC("e1000_mc_addr_list_update_82571"); + DEBUGFUNC("e1000_update_mc_addr_list_82571"); if (e1000_get_laa_state_82571(hw)) rar_count--; - e1000_mc_addr_list_update_generic(hw, mc_addr_list, mc_addr_count, + e1000_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count, rar_used_count, rar_count); } @@ -1113,17 +1121,17 @@ e1000_mc_addr_list_update_82571(struct e1000_hw *hw, * should be established. Assumes the hardware has previously been reset * and the transmitter and receiver are not enabled. **/ -STATIC s32 -e1000_setup_link_82571(struct e1000_hw *hw) +STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_setup_link_82571"); - /* 82573 does not have a word in the NVM to determine + /* + * 82573 does not have a word in the NVM to determine * the default flow control setting, so we explicitly * set it to full. */ if (hw->mac.type == e1000_82573) - hw->mac.fc = e1000_fc_full; + hw->fc.type = e1000_fc_full; return e1000_setup_link_generic(hw); } @@ -1136,8 +1144,7 @@ e1000_setup_link_82571(struct e1000_hw *hw) * for link, once link is established calls to configure collision distance * and flow control are called. **/ -STATIC s32 -e1000_setup_copper_link_82571(struct e1000_hw *hw) +STATIC s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) { u32 ctrl, led_ctrl; s32 ret_val; @@ -1182,15 +1189,15 @@ out: * Configures collision distance and flow control for fiber and serdes links. * Upon successful setup, poll for link. **/ -STATIC s32 -e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) +STATIC s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_setup_fiber_serdes_link_82571"); switch (hw->mac.type) { case e1000_82571: case e1000_82572: - /* If SerDes loopback mode is entered, there is no form + /* + * If SerDes loopback mode is entered, there is no form * of reset to take the adapter out of that mode. So we * have to explicitly take the adapter out of loopback * mode. This prevents drivers from twidling their thumbs @@ -1213,8 +1220,7 @@ e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) * Read the EEPROM for the current default LED configuration. If the * LED configuration is not valid, set to a valid LED configuration. **/ -STATIC s32 -e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) +STATIC s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) { s32 ret_val; @@ -1232,7 +1238,6 @@ e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) *data = ID_LED_DEFAULT; - out: return ret_val; } @@ -1243,11 +1248,10 @@ out: * * Retrieve and return the current locally administed address state. **/ -boolean_t -e1000_get_laa_state_82571(struct e1000_hw *hw) +bool e1000_get_laa_state_82571(struct e1000_hw *hw) { struct e1000_dev_spec_82571 *dev_spec; - boolean_t state = FALSE; + bool state = FALSE; DEBUGFUNC("e1000_get_laa_state_82571"); @@ -1269,8 +1273,7 @@ out: * * Enable/Disable the current locally administed address state. **/ -void -e1000_set_laa_state_82571(struct e1000_hw *hw, boolean_t state) +void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state) { struct e1000_dev_spec_82571 *dev_spec; @@ -1284,8 +1287,9 @@ e1000_set_laa_state_82571(struct e1000_hw *hw, boolean_t state) dev_spec->laa_is_present = state; /* If workaround is activated... */ - if (state == TRUE) { - /* Hold a copy of the LAA in RAR[14] This is done so that + if (state) { + /* + * Hold a copy of the LAA in RAR[14] This is done so that * between the time RAR[0] gets clobbered and the time it * gets fixed, the actual LAA is in one of the RARs and no * incoming packets directed to this port are dropped. @@ -1309,8 +1313,7 @@ out: * the checksum. Otherwise, if bit 15 is set and the checksum is incorrect, * we need to return bad checksum. **/ -static s32 -e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) +static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; s32 ret_val = E1000_SUCCESS; @@ -1321,7 +1324,8 @@ e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) if (nvm->type != e1000_nvm_flash_hw) goto out; - /* Check bit 4 of word 10h. If it is 0, firmware is done updating + /* + * Check bit 4 of word 10h. If it is 0, firmware is done updating * 10h-12h. Checksum may need to be fixed. */ ret_val = e1000_read_nvm(hw, 0x10, 1, &data); @@ -1329,7 +1333,8 @@ e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) goto out; if (!(data & 0x10)) { - /* Read 0x23 and check bit 15. This bit is a 1 + /* + * Read 0x23 and check bit 15. This bit is a 1 * when the checksum has already been fixed. If * the checksum is still wrong and this bit is a * 1, we need to return bad checksum. Otherwise, @@ -1353,21 +1358,50 @@ out: return ret_val; } +/** + * e1000_read_mac_addr_82571 - Read device MAC address + * @hw: pointer to the HW structure + **/ +STATIC s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_read_mac_addr_82571"); + if (e1000_check_alt_mac_addr_generic(hw)) + ret_val = e1000_read_mac_addr_generic(hw); + + return ret_val; +} + +/** + * e1000_power_down_phy_copper_82571 - Remove link during PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, remove the link. + **/ +STATIC void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) +{ + /* If the management interface is not enabled, then power down */ + if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw))) + e1000_power_down_phy_copper(hw); + + return; +} + /** * e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters * @hw: pointer to the HW structure * * Clears the hardware counters by reading the counter registers. **/ -STATIC void -e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) { volatile u32 temp; DEBUGFUNC("e1000_clear_hw_cntrs_82571"); e1000_clear_hw_cntrs_base_generic(hw); - temp = E1000_READ_REG(hw, E1000_PRC64); temp = E1000_READ_REG(hw, E1000_PRC127); temp = E1000_READ_REG(hw, E1000_PRC255); diff --git a/sys/dev/em/e1000_82571.h b/sys/dev/em/e1000_82571.h index 992518e5f76e..ea44b6cc9dd0 100644 --- a/sys/dev/em/e1000_82571.h +++ b/sys/dev/em/e1000_82571.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_82571_H_ diff --git a/sys/dev/em/e1000_82575.c b/sys/dev/em/e1000_82575.c index 5e3782976e0e..40de43d68142 100644 --- a/sys/dev/em/e1000_82575.c +++ b/sys/dev/em/e1000_82575.c @@ -30,10 +30,11 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ /* e1000_82575 + * e1000_82576 */ #include "e1000_api.h" @@ -41,41 +42,44 @@ void e1000_init_function_pointers_82575(struct e1000_hw *hw); -STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_82575(struct e1000_hw *hw); -STATIC s32 e1000_acquire_phy_82575(struct e1000_hw *hw); -STATIC void e1000_release_phy_82575(struct e1000_hw *hw); -STATIC s32 e1000_acquire_nvm_82575(struct e1000_hw *hw); -STATIC void e1000_release_nvm_82575(struct e1000_hw *hw); -STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw); -STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, - u16 *duplex); -STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw); -STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw); -STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, - u16 *data); -STATIC void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index); -STATIC s32 e1000_reset_hw_82575(struct e1000_hw *hw); -STATIC s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, - boolean_t active); -STATIC s32 e1000_setup_copper_link_82575(struct e1000_hw *hw); -STATIC s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw); -STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, - u32 offset, u16 data); -STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw); -static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask); -static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw); -static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, - u16 *speed, u16 *duplex); -static s32 e1000_get_phy_id_82575(struct e1000_hw *hw); -static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask); -static boolean_t e1000_sgmii_active_82575(struct e1000_hw *hw); -STATIC s32 e1000_reset_init_script_82575(struct e1000_hw* hw); +STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw); +STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw); +STATIC s32 e1000_init_mac_params_82575(struct e1000_hw *hw); +STATIC s32 e1000_acquire_phy_82575(struct e1000_hw *hw); +STATIC void e1000_release_phy_82575(struct e1000_hw *hw); +STATIC s32 e1000_acquire_nvm_82575(struct e1000_hw *hw); +STATIC void e1000_release_nvm_82575(struct e1000_hw *hw); +STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw); +STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw); +STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, + u16 *duplex); +STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw); +STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw); +STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, + u16 *data); +STATIC void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index); +STATIC s32 e1000_reset_hw_82575(struct e1000_hw *hw); +STATIC s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, + bool active); +STATIC s32 e1000_setup_copper_link_82575(struct e1000_hw *hw); +STATIC s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw); +STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, + u32 offset, u16 data); +STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw); +static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask); +static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw); +static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, + u16 *speed, u16 *duplex); +static s32 e1000_get_phy_id_82575(struct e1000_hw *hw); +static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask); +static bool e1000_sgmii_active_82575(struct e1000_hw *hw); +STATIC s32 e1000_reset_init_script_82575(struct e1000_hw *hw); +STATIC s32 e1000_read_mac_addr_82575(struct e1000_hw *hw); +STATIC void e1000_power_down_phy_copper_82575(struct e1000_hw *hw); + struct e1000_dev_spec_82575 { - boolean_t sgmii_active; + bool sgmii_active; }; /** @@ -84,8 +88,7 @@ struct e1000_dev_spec_82575 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_phy_params_82575(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_functions *func = &hw->func; @@ -93,9 +96,12 @@ e1000_init_phy_params_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_init_phy_params_82575"); - if (hw->media_type != e1000_media_type_copper) { - phy->type = e1000_phy_none; + if (hw->phy.media_type != e1000_media_type_copper) { + phy->type = e1000_phy_none; goto out; + } else { + func->power_up_phy = e1000_power_up_phy_copper; + func->power_down_phy = e1000_power_down_phy_copper_82575; } phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; @@ -107,7 +113,7 @@ e1000_init_phy_params_82575(struct e1000_hw *hw) func->get_cfg_done = e1000_get_cfg_done_82575; func->release_phy = e1000_release_phy_82575; - if (e1000_sgmii_active_82575(hw) == TRUE) { + if (e1000_sgmii_active_82575(hw)) { func->reset_phy = e1000_phy_hw_reset_sgmii_82575; func->read_phy_reg = e1000_read_phy_reg_sgmii_82575; func->write_phy_reg = e1000_write_phy_reg_sgmii_82575; @@ -153,8 +159,7 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_nvm_params_82575(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_82575(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; @@ -185,10 +190,15 @@ e1000_init_nvm_params_82575(struct e1000_hw *hw) size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> E1000_EECD_SIZE_EX_SHIFT); - /* Added to a constant, "size" becomes the left-shift value + /* + * Added to a constant, "size" becomes the left-shift value * for setting word_size. */ size += NVM_WORD_SIZE_BASE_SHIFT; + + /* EEPROM access above 16k is unsupported */ + if (size > 14) + size = 14; nvm->word_size = 1 << size; /* Function Pointers */ @@ -209,13 +219,12 @@ e1000_init_nvm_params_82575(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 -e1000_init_mac_params_82575(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; struct e1000_dev_spec_82575 *dev_spec; - u32 ctrl, ctrl_ext; + u32 ctrl_ext = 0; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_82575"); @@ -230,24 +239,28 @@ e1000_init_mac_params_82575(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec; /* Set media type */ - /* The 82575 uses bits 22:23 for link mode. The mode can be changed + /* + * The 82575 uses bits 22:23 for link mode. The mode can be changed * based on the EEPROM. We cannot rely upon device ID. There * is no distinguishable difference between fiber and internal * SerDes mode on the 82575. There can be an external PHY attached * on the SGMII interface. For this, we'll set sgmii_active to TRUE. */ - hw->media_type = e1000_media_type_copper; + hw->phy.media_type = e1000_media_type_copper; dev_spec->sgmii_active = FALSE; ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); if ((ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) == E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES) { - hw->media_type = e1000_media_type_internal_serdes; + hw->phy.media_type = e1000_media_type_internal_serdes; + ctrl_ext |= E1000_CTRL_I2C_ENA; } else if (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII) { dev_spec->sgmii_active = TRUE; - ctrl = E1000_READ_REG(hw, E1000_CTRL); - E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_I2C_ENA)); + ctrl_ext |= E1000_CTRL_I2C_ENA; + } else { + ctrl_ext &= ~E1000_CTRL_I2C_ENA; } + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); /* Set mta register count */ mac->mta_reg_count = 128; @@ -272,15 +285,17 @@ e1000_init_mac_params_82575(struct e1000_hw *hw) func->setup_link = e1000_setup_link_generic; /* physical interface link setup */ func->setup_physical_interface = - (hw->media_type == e1000_media_type_copper) + (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82575 : e1000_setup_fiber_serdes_link_82575; /* check for link */ func->check_for_link = e1000_check_for_link_82575; /* receive address register setting */ func->rar_set = e1000_rar_set_82575; + /* read mac address */ + func->read_mac_addr = e1000_read_mac_addr_82575; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_generic; + func->update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ func->write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ @@ -314,8 +329,7 @@ out: * The only function explicitly called by the api module to initialize * all function pointers and parameters. **/ -void -e1000_init_function_pointers_82575(struct e1000_hw *hw) +void e1000_init_function_pointers_82575(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82575"); @@ -331,8 +345,7 @@ e1000_init_function_pointers_82575(struct e1000_hw *hw) * Acquire access rights to the correct PHY. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_acquire_phy_82575(struct e1000_hw *hw) +STATIC s32 e1000_acquire_phy_82575(struct e1000_hw *hw) { u16 mask; @@ -350,8 +363,7 @@ e1000_acquire_phy_82575(struct e1000_hw *hw) * A wrapper to release access rights to the correct PHY. This is a * function pointer entry point called by the api module. **/ -STATIC void -e1000_release_phy_82575(struct e1000_hw *hw) +STATIC void e1000_release_phy_82575(struct e1000_hw *hw) { u16 mask; @@ -370,8 +382,8 @@ e1000_release_phy_82575(struct e1000_hw *hw) * Reads the PHY register at offset using the serial gigabit media independent * interface and stores the retrieved information in data. **/ -STATIC s32 -e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 *data) +STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, + u16 *data) { struct e1000_phy_info *phy = &hw->phy; u32 i, i2ccmd = 0; @@ -383,7 +395,8 @@ e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 *data) return -E1000_ERR_PARAM; } - /* Set up Op-code, Phy Address, and register address in the I2CCMD + /* + * Set up Op-code, Phy Address, and register address in the I2CCMD * register. The MAC will take care of interfacing with the * PHY to retrieve the desired data. */ @@ -424,8 +437,8 @@ e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 *data) * Writes the data to PHY register at the offset using the serial gigabit * media independent interface. **/ -STATIC s32 -e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data) +STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, + u16 data) { struct e1000_phy_info *phy = &hw->phy; u32 i, i2ccmd = 0; @@ -441,7 +454,8 @@ e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data) /* Swap the data bytes for the I2C interface */ phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00); - /* Set up Op-code, Phy Address, and register address in the I2CCMD + /* + * Set up Op-code, Phy Address, and register address in the I2CCMD * register. The MAC will take care of interfacing with the * PHY to retrieve the desired data. */ @@ -478,8 +492,7 @@ e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, u16 data) * Retreives the PHY address and ID for both PHY's which do and do not use * sgmi interface. **/ -static s32 -e1000_get_phy_id_82575(struct e1000_hw *hw) +static s32 e1000_get_phy_id_82575(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -487,19 +500,21 @@ e1000_get_phy_id_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_get_phy_id_82575"); - /* For SGMII PHYs, we try the list of possible addresses until + /* + * For SGMII PHYs, we try the list of possible addresses until * we find one that works. For non-SGMII PHYs * (e.g. integrated copper PHYs), an address of 1 should * work. The result of this function should mean phy->phy_addr * and phy->id are set correctly. */ - if (e1000_sgmii_active_82575(hw) == FALSE) { + if (!(e1000_sgmii_active_82575(hw))) { phy->addr = 1; ret_val = e1000_get_phy_id(hw); goto out; } - /* The address field in the I2CCMD register is 3 bits and 0 is invalid. + /* + * The address field in the I2CCMD register is 3 bits and 0 is invalid. * Therefore, we need to test 1-7 */ for (phy->addr = 1; phy->addr < 8; phy->addr++) { @@ -508,8 +523,10 @@ e1000_get_phy_id_82575(struct e1000_hw *hw) DEBUGOUT2("Vendor ID 0x%08X read at address %u\n", phy_id, phy->addr); - /* At the time of this writing, The M88 part is - * the only supported SGMII PHY product. */ + /* + * At the time of this writing, The M88 part is + * the only supported SGMII PHY product. + */ if (phy_id == M88_VENDOR) break; } else { @@ -537,20 +554,21 @@ out: * * Resets the PHY using the serial gigabit media independent interface. **/ -STATIC s32 -e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw) +STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw) { s32 ret_val; DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575"); - /* This isn't a true "hard" reset, but is the only reset + /* + * This isn't a true "hard" reset, but is the only reset * available to us at this time. */ DEBUGOUT("Soft resetting SGMII attached PHY...\n"); - /* SFP documentation requires the following to configure the SPF module + /* + * SFP documentation requires the following to configure the SPF module * to work on SGMII. No further documentation is given. */ ret_val = e1000_write_phy_reg(hw, 0x1B, 0x8084); @@ -576,8 +594,7 @@ out: * This is a function pointer entry point only called by * PHY setup routines. **/ -STATIC s32 -e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, boolean_t active) +STATIC s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -612,10 +629,12 @@ e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, boolean_t active) ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, data); - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used + /* + * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. */ + * SmartSpeed, so performance is maintained. + */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -658,8 +677,7 @@ out: * Return successful if access grant bit set, else clear the request for * EEPROM access and return -E1000_ERR_NVM (-1). **/ -STATIC s32 -e1000_acquire_nvm_82575(struct e1000_hw *hw) +STATIC s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) { s32 ret_val; @@ -685,8 +703,7 @@ out: * Stop any current commands to the EEPROM and clear the EEPROM request bit, * then release the semaphores acquired. **/ -STATIC void -e1000_release_nvm_82575(struct e1000_hw *hw) +STATIC void e1000_release_nvm_82575(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_82575"); @@ -702,8 +719,7 @@ e1000_release_nvm_82575(struct e1000_hw *hw) * Acquire the SW/FW semaphore to access the PHY or NVM. The mask * will also specify which port we're acquiring the lock for. **/ -static s32 -e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask) +static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask) { u32 swfw_sync; u32 swmask = mask; @@ -723,8 +739,10 @@ e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask) if (!(swfw_sync & (fwmask | swmask))) break; - /* Firmware currently using resource (fwmask) - * or other software thread using resource (swmask) */ + /* + * Firmware currently using resource (fwmask) + * or other software thread using resource (swmask) + */ e1000_put_hw_semaphore_generic(hw); msec_delay_irq(5); i++; @@ -753,8 +771,7 @@ out: * Release the SW/FW semaphore used to access the PHY or NVM. The mask * will also specify which port we're releasing the lock for. **/ -static void -e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) +static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) { u32 swfw_sync; @@ -780,8 +797,7 @@ e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask) * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon * would not be able to be reset or change link. **/ -STATIC s32 -e1000_get_cfg_done_82575(struct e1000_hw *hw) +STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; @@ -821,20 +837,21 @@ e1000_get_cfg_done_82575(struct e1000_hw *hw) * interface, use pcs to retreive the link speed and duplex information. * Otherwise, use the generic function to get the link speed and duplex info. **/ -STATIC s32 -e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, u16 *duplex) +STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, + u16 *duplex) { s32 ret_val; DEBUGFUNC("e1000_get_link_up_info_82575"); - if (hw->media_type != e1000_media_type_copper || - e1000_sgmii_active_82575(hw) == TRUE) { + if (hw->phy.media_type != e1000_media_type_copper || + e1000_sgmii_active_82575(hw)) { ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, speed, duplex); - } else + } else { ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex); + } return ret_val; } @@ -846,8 +863,7 @@ e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, u16 *duplex) * If sgmii is enabled, then use the pcs register to determine link, otherwise * use the generic interface for determining link. **/ -STATIC s32 -e1000_check_for_link_82575(struct e1000_hw *hw) +STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw) { s32 ret_val; u16 speed, duplex; @@ -855,8 +871,8 @@ e1000_check_for_link_82575(struct e1000_hw *hw) DEBUGFUNC("e1000_check_for_link_82575"); /* SGMII link check is done through the PCS register. */ - if ((hw->media_type != e1000_media_type_copper) || - (e1000_sgmii_active_82575(hw) == TRUE)) + if ((hw->phy.media_type != e1000_media_type_copper) || + (e1000_sgmii_active_82575(hw))) ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed, &duplex); else @@ -874,9 +890,8 @@ e1000_check_for_link_82575(struct e1000_hw *hw) * Using the physical coding sub-layer (PCS), retreive the current speed and * duplex, then store the values in the pointers provided. **/ -static s32 -e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, - u16 *duplex) +static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, + u16 *duplex) { struct e1000_mac_info *mac = &hw->mac; u32 pcs; @@ -888,12 +903,15 @@ e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, *speed = 0; *duplex = 0; - /* Read the PCS Status register for link state. For non-copper mode, + /* + * Read the PCS Status register for link state. For non-copper mode, * the status register is not accurate. The PCS status register is - * used instead. */ + * used instead. + */ pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT); - /* The link up bit determines when link is up on autoneg. The sync ok + /* + * The link up bit determines when link is up on autoneg. The sync ok * gets set once both sides sync up and agree upon link. Stable link * can be determined by checking for both link up and link sync ok */ @@ -929,17 +947,14 @@ e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed, * Sets the receive address array register at index to the address passed * in by addr. **/ -void -e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index) +void e1000_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index) { DEBUGFUNC("e1000_rar_set_82575"); if (index < E1000_RAR_ENTRIES_82575) { e1000_rar_set_generic(hw, addr, index); - goto out; } -out: return; } @@ -950,15 +965,15 @@ out: * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 -e1000_reset_hw_82575(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_82575(struct e1000_hw *hw) { u32 ctrl, icr; s32 ret_val; DEBUGFUNC("e1000_reset_hw_82575"); - /* Prevent the PCI-E bus from sticking if there is no TLP connection + /* + * Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); @@ -982,7 +997,8 @@ e1000_reset_hw_82575(struct e1000_hw *hw) ret_val = e1000_get_auto_rd_done_generic(hw); if (ret_val) { - /* When auto config read does not complete, do not + /* + * When auto config read does not complete, do not * return with an error. This can happen in situations * where there is no eeprom and prevents getting link. */ @@ -997,6 +1013,8 @@ e1000_reset_hw_82575(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); icr = E1000_READ_REG(hw, E1000_ICR); + e1000_check_alt_mac_addr_generic(hw); + return ret_val; } @@ -1006,8 +1024,7 @@ e1000_reset_hw_82575(struct e1000_hw *hw) * * This inits the hardware readying it for operation. **/ -STATIC s32 -e1000_init_hw_82575(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; @@ -1019,16 +1036,15 @@ e1000_init_hw_82575(struct e1000_hw *hw) ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); - goto out; + /* This is not fatal and we should not stop init due to this */ } /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); e1000_clear_vfta(hw); - /* Setup the receive address. */ + /* Setup the receive address */ e1000_init_rx_addrs_generic(hw, rar_count); - /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); for (i = 0; i < mac->mta_reg_count; i++) @@ -1037,14 +1053,14 @@ e1000_init_hw_82575(struct e1000_hw *hw) /* Setup link and flow control */ ret_val = e1000_setup_link(hw); - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. */ e1000_clear_hw_cntrs_82575(hw); -out: return ret_val; } @@ -1056,12 +1072,11 @@ out: * for link, once link is established calls to configure collision distance * and flow control are called. **/ -STATIC s32 -e1000_setup_copper_link_82575(struct e1000_hw *hw) +STATIC s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) { u32 ctrl, led_ctrl; s32 ret_val; - boolean_t link; + bool link; DEBUGFUNC("e1000_setup_copper_link_82575"); @@ -1091,14 +1106,18 @@ e1000_setup_copper_link_82575(struct e1000_hw *hw) goto out; if (hw->mac.autoneg) { - /* Setup autoneg and flow control advertisement - * and perform autonegotiation. */ + /* + * Setup autoneg and flow control advertisement + * and perform autonegotiation. + */ ret_val = e1000_copper_link_autoneg(hw); if (ret_val) goto out; } else { - /* PHY will be set to 10H, 10F, 100H or 100F - * depending on user settings. */ + /* + * PHY will be set to 10H, 10F, 100H or 100F + * depending on user settings. + */ DEBUGOUT("Forcing Speed and Duplex\n"); ret_val = e1000_phy_force_speed_duplex(hw); if (ret_val) { @@ -1111,7 +1130,8 @@ e1000_setup_copper_link_82575(struct e1000_hw *hw) if (ret_val) goto out; - /* Check link status. Wait up to 100 microseconds for link to become + /* + * Check link status. Wait up to 100 microseconds for link to become * valid. */ ret_val = e1000_phy_has_link_generic(hw, @@ -1140,14 +1160,14 @@ out: * * Configures speed and duplex for fiber and serdes links. **/ -STATIC s32 -e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw) +STATIC s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw) { u32 reg; DEBUGFUNC("e1000_setup_fiber_serdes_link_82575"); - /* On the 82575, SerDes loopback mode persists until it is + /* + * On the 82575, SerDes loopback mode persists until it is * explicitly turned off or a power cycle is performed. A read to * the register does not indicate its status. Therefore, we ensure * loopback mode is disabled during initialization. @@ -1168,12 +1188,17 @@ e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw) reg |= E1000_CONNSW_ENRGSRC; E1000_WRITE_REG(hw, E1000_CONNSW, reg); - /* New SerDes mode allows for forcing speed or autonegotiating speed + /* + * New SerDes mode allows for forcing speed or autonegotiating speed * at 1gb. Autoneg should be default set by most drivers. This is the * mode that will be compatible with older link partners and switches. * However, both are supported by the hardware and some drivers/tools. */ reg = E1000_READ_REG(hw, E1000_PCS_LCTL); + + reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP | + E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); + if (hw->mac.autoneg) { /* Set PCS register for autoneg */ reg |= E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */ @@ -1204,16 +1229,15 @@ e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw) * independent interface (sgmii) is being used. Configures the link * for auto-negotiation or forces speed/duplex. **/ -static s32 -e1000_configure_pcs_link_82575(struct e1000_hw *hw) +static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 reg = 0; DEBUGFUNC("e1000_configure_pcs_link_82575"); - if (hw->media_type != e1000_media_type_copper || - e1000_sgmii_active_82575(hw) == FALSE) + if (hw->phy.media_type != e1000_media_type_copper || + !(e1000_sgmii_active_82575(hw))) goto out; /* For SGMII, we need to issue a PCS autoneg restart */ @@ -1226,7 +1250,8 @@ e1000_configure_pcs_link_82575(struct e1000_hw *hw) /* Make sure forced speed and force link are not set */ reg &= ~(E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); - /* The PHY should be setup prior to calling this function. + /* + * The PHY should be setup prior to calling this function. * All we need to do is restart autoneg and enable autoneg. */ reg |= E1000_PCS_LCTL_AN_RESTART | E1000_PCS_LCTL_AN_ENABLE; @@ -1269,11 +1294,10 @@ out: * which can be enabled for use in the embedded applications. Simply * return the current state of the sgmii interface. **/ -static boolean_t -e1000_sgmii_active_82575(struct e1000_hw *hw) +static bool e1000_sgmii_active_82575(struct e1000_hw *hw) { struct e1000_dev_spec_82575 *dev_spec; - boolean_t ret_val; + bool ret_val; DEBUGFUNC("e1000_sgmii_active_82575"); @@ -1297,8 +1321,7 @@ out: * Inits recommended HW defaults after a reset when there is no EEPROM * detected. This is only for the 82575. **/ -STATIC s32 -e1000_reset_init_script_82575(struct e1000_hw* hw) +STATIC s32 e1000_reset_init_script_82575(struct e1000_hw* hw) { DEBUGFUNC("e1000_reset_init_script_82575"); @@ -1329,14 +1352,44 @@ e1000_reset_init_script_82575(struct e1000_hw* hw) return E1000_SUCCESS; } +/** + * e1000_read_mac_addr_82575 - Read device MAC address + * @hw: pointer to the HW structure + **/ +STATIC s32 e1000_read_mac_addr_82575(struct e1000_hw *hw) +{ + s32 ret_val = E1000_SUCCESS; + + DEBUGFUNC("e1000_read_mac_addr_82575"); + if (e1000_check_alt_mac_addr_generic(hw)) + ret_val = e1000_read_mac_addr_generic(hw); + + return ret_val; +} + +/** + * e1000_power_down_phy_copper_82575 - Remove link during PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, remove the link. + **/ +STATIC void e1000_power_down_phy_copper_82575(struct e1000_hw *hw) +{ + /* If the management interface is not enabled, then power down */ + if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw))) + e1000_power_down_phy_copper(hw); + + return; +} + /** * e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters * @hw: pointer to the HW structure * * Clears the hardware counters by reading the counter registers. **/ -STATIC void -e1000_clear_hw_cntrs_82575(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw) { volatile u32 temp; @@ -1392,6 +1445,6 @@ e1000_clear_hw_cntrs_82575(struct e1000_hw *hw) temp = E1000_READ_REG(hw, E1000_LENERRS); /* This register should not be read in copper configurations */ - if (hw->media_type == e1000_media_type_internal_serdes) + if (hw->phy.media_type == e1000_media_type_internal_serdes) temp = E1000_READ_REG(hw, E1000_SCVPC); } diff --git a/sys/dev/em/e1000_82575.h b/sys/dev/em/e1000_82575.h index f9628bb610b5..8f4424442b0e 100644 --- a/sys/dev/em/e1000_82575.h +++ b/sys/dev/em/e1000_82575.h @@ -30,13 +30,14 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_82575_H_ #define _E1000_82575_H_ -/* Receive Address Register Count +/* + * Receive Address Register Count * Number of high/low register pairs in the RAR. The RAR (Receive Address * Registers) holds the directed and multicast addresses that we monitor. * These entries are also used for MAC-based filtering. @@ -116,6 +117,10 @@ struct e1000_adv_context_desc { #define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION 0x06000000 #define E1000_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 +#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000 + +#define E1000_SRRCTL_BSIZEPKT_MASK 0x0000007F +#define E1000_SRRCTL_BSIZEHDR_MASK 0x00003F00 #define E1000_TX_HEAD_WB_ENABLE 0x1 #define E1000_TX_SEQNUM_WB_ENABLE 0x2 @@ -146,7 +151,7 @@ struct e1000_adv_context_desc { E1000_EIMS_TCP_TIMER | \ E1000_EIMS_OTHER) -/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */ +/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */ #define E1000_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */ #define E1000_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */ #define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */ @@ -169,7 +174,7 @@ union e1000_adv_rx_desc { struct { u16 pkt_info; /* RSS type, Packet type */ u16 hdr_info; /* Split Header, - * header buffer length */ + * header buffer length */ } lo_dword; union { u32 rss; /* RSS Hash */ @@ -207,6 +212,17 @@ union e1000_adv_rx_desc { #define E1000_RXDADV_RSSTYPE_IPV6_UDP 0x00000008 #define E1000_RXDADV_RSSTYPE_IPV6_UDP_EX 0x00000009 +/* RSS Packet Types as indicated in the receive descriptor */ +#define E1000_RXDADV_PKTTYPE_NONE 0x00000000 +#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */ +#define E1000_RXDADV_PKTTYPE_IPV4_EX 0x00000020 /* IPV4 hdr + extensions */ +#define E1000_RXDADV_PKTTYPE_IPV6 0x00000040 /* IPV6 hdr present */ +#define E1000_RXDADV_PKTTYPE_IPV6_EX 0x00000080 /* IPV6 hdr + extensions */ +#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */ +#define E1000_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ +#define E1000_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ +#define E1000_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ + /* Transmit Descriptor - Advanced */ union e1000_adv_tx_desc { struct { @@ -272,8 +288,8 @@ struct e1000_adv_tx_context_desc { /* Additional Transmit Descriptor Control definitions */ #define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */ #define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. write-back flushing */ -#define E1000_TXDCTL_PRIORITY 0x08000000 /* Tx Queue Arbitration Priority - 0=low, 1=high */ +/* Tx Queue Arbitration Priority 0=low, 1=high */ +#define E1000_TXDCTL_PRIORITY 0x08000000 /* Additional Receive Descriptor Control definitions */ #define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */ @@ -293,6 +309,8 @@ struct e1000_adv_tx_context_desc { #define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ #define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ +#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ + #endif diff --git a/sys/dev/em/e1000_api.c b/sys/dev/em/e1000_api.c index 9f8a48e68ff2..6603a8019872 100644 --- a/sys/dev/em/e1000_api.c +++ b/sys/dev/em/e1000_api.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #include "e1000_api.h" @@ -56,12 +56,11 @@ extern void e1000_init_function_pointers_82575(struct e1000_hw *hw); * This function initializes the function pointers for the MAC * set of functions. Called by drivers or by e1000_setup_init_funcs. **/ -s32 -e1000_init_mac_params(struct e1000_hw *hw) +s32 e1000_init_mac_params(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - if (hw->func.init_mac_params != NULL) { + if (hw->func.init_mac_params) { ret_val = hw->func.init_mac_params(hw); if (ret_val) { DEBUGOUT("MAC Initialization Error\n"); @@ -83,12 +82,11 @@ out: * This function initializes the function pointers for the NVM * set of functions. Called by drivers or by e1000_setup_init_funcs. **/ -s32 -e1000_init_nvm_params(struct e1000_hw *hw) +s32 e1000_init_nvm_params(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - if (hw->func.init_nvm_params != NULL) { + if (hw->func.init_nvm_params) { ret_val = hw->func.init_nvm_params(hw); if (ret_val) { DEBUGOUT("NVM Initialization Error\n"); @@ -110,12 +108,11 @@ out: * This function initializes the function pointers for the PHY * set of functions. Called by drivers or by e1000_setup_init_funcs. **/ -s32 -e1000_init_phy_params(struct e1000_hw *hw) +s32 e1000_init_phy_params(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - if (hw->func.init_phy_params != NULL) { + if (hw->func.init_phy_params) { ret_val = hw->func.init_phy_params(hw); if (ret_val) { DEBUGOUT("PHY Initialization Error\n"); @@ -139,8 +136,7 @@ out: * MUST BE FIRST FUNCTION CALLED (explicitly or through * e1000_setup_init_funcs()). **/ -s32 -e1000_set_mac_type(struct e1000_hw *hw) +s32 e1000_set_mac_type(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val = E1000_SUCCESS; @@ -216,6 +212,7 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82571EB_SERDES_DUAL: case E1000_DEV_ID_82571EB_SERDES_QUAD: case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571PT_QUAD_COPPER: case E1000_DEV_ID_82571EB_QUAD_FIBER: case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: mac->type = e1000_82571; @@ -255,8 +252,6 @@ e1000_set_mac_type(struct e1000_hw *hw) break; case E1000_DEV_ID_82575EB_COPPER: case E1000_DEV_ID_82575EB_FIBER_SERDES: - case E1000_DEV_ID_82575EM_COPPER: - case E1000_DEV_ID_82575EM_FIBER_SERDES: case E1000_DEV_ID_82575GB_QUAD_COPPER: mac->type = e1000_82575; break; @@ -281,13 +276,11 @@ e1000_set_mac_type(struct e1000_hw *hw) * This function must be called by a driver in order to use the rest * of the 'shared' code files. Called by drivers only. **/ -s32 -e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t init_device) +s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) { s32 ret_val; - /* Can't do much good without knowing the MAC type. - */ + /* Can't do much good without knowing the MAC type. */ ret_val = e1000_set_mac_type(hw); if (ret_val) { DEBUGOUT("ERROR: MAC type could not be set properly.\n"); @@ -300,7 +293,8 @@ e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t init_device) goto out; } - /* Init some generic function pointers that are currently all pointing + /* + * Init some generic function pointers that are currently all pointing * to generic implementations. We do this first allowing a driver * module to override it afterwards. */ @@ -313,7 +307,8 @@ e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t init_device) hw->func.wait_autoneg = e1000_wait_autoneg_generic; hw->func.reload_nvm = e1000_reload_nvm_generic; - /* Set up the init function pointers. These are functions within the + /* + * Set up the init function pointers. These are functions within the * adapter family file that sets up function pointers for the rest of * the functions in that family. */ @@ -361,10 +356,11 @@ e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t init_device) break; } - /* Initialize the rest of the function pointers. These require some + /* + * Initialize the rest of the function pointers. These require some * register reads/writes in some cases. */ - if ((ret_val == E1000_SUCCESS) && (init_device == TRUE)) { + if (!(ret_val) && init_device) { ret_val = e1000_init_mac_params(hw); if (ret_val) goto out; @@ -390,10 +386,9 @@ out: * If a device specific structure was allocated, this function will * free it. This is a function pointer entry point called by drivers. **/ -void -e1000_remove_device(struct e1000_hw *hw) +void e1000_remove_device(struct e1000_hw *hw) { - if (hw->func.remove_device != NULL) + if (hw->func.remove_device) hw->func.remove_device(hw); } @@ -405,13 +400,12 @@ e1000_remove_device(struct e1000_hw *hw) * adaper is attached and stores it in the hw structure. This is a * function pointer entry point called by drivers. **/ -s32 -e1000_get_bus_info(struct e1000_hw *hw) +s32 e1000_get_bus_info(struct e1000_hw *hw) { - if (hw->func.get_bus_info != NULL) + if (hw->func.get_bus_info) return hw->func.get_bus_info(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -421,10 +415,9 @@ e1000_get_bus_info(struct e1000_hw *hw) * This clears the VLAN filter table on the adapter. This is a function * pointer entry point called by drivers. **/ -void -e1000_clear_vfta(struct e1000_hw *hw) +void e1000_clear_vfta(struct e1000_hw *hw) { - if (hw->func.clear_vfta != NULL) + if (hw->func.clear_vfta) hw->func.clear_vfta (hw); } @@ -437,15 +430,14 @@ e1000_clear_vfta(struct e1000_hw *hw) * This writes a 32-bit value to a 32-bit offset in the VLAN filter * table. This is a function pointer entry point called by drivers. **/ -void -e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) +void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) { - if (hw->func.write_vfta != NULL) + if (hw->func.write_vfta) hw->func.write_vfta(hw, offset, value); } /** - * e1000_mc_addr_list_update - Update Multicast addresses + * e1000_update_mc_addr_list - Update Multicast addresses * @hw: pointer to the HW structure * @mc_addr_list: array of multicast addresses to program * @mc_addr_count: number of multicast addresses to program @@ -459,15 +451,12 @@ e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) * exists and all implementations are handled in the generic version of this * function. **/ -void -e1000_mc_addr_list_update(struct e1000_hw *hw, - u8 *mc_addr_list, - u32 mc_addr_count, - u32 rar_used_count, - u32 rar_count) +void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, u32 rar_used_count, + u32 rar_count) { - if (hw->func.mc_addr_list_update != NULL) - hw->func.mc_addr_list_update(hw, + if (hw->func.update_mc_addr_list) + hw->func.update_mc_addr_list(hw, mc_addr_list, mc_addr_count, rar_used_count, @@ -482,8 +471,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, * and all implementations are handled in the generic version of this * function. **/ -s32 -e1000_force_mac_fc(struct e1000_hw *hw) +s32 e1000_force_mac_fc(struct e1000_hw *hw) { return e1000_force_mac_fc_generic(hw); } @@ -496,13 +484,12 @@ e1000_force_mac_fc(struct e1000_hw *hw) * results in the hw->mac structure. This is a function pointer entry * point called by drivers. **/ -s32 -e1000_check_for_link(struct e1000_hw *hw) +s32 e1000_check_for_link(struct e1000_hw *hw) { - if (hw->func.check_for_link != NULL) + if (hw->func.check_for_link) return hw->func.check_for_link(hw); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -512,13 +499,12 @@ e1000_check_for_link(struct e1000_hw *hw) * This checks if the adapter has manageability enabled. * This is a function pointer entry point called by drivers. **/ -boolean_t -e1000_check_mng_mode(struct e1000_hw *hw) +bool e1000_check_mng_mode(struct e1000_hw *hw) { - if (hw->func.check_mng_mode != NULL) + if (hw->func.check_mng_mode) return hw->func.check_mng_mode(hw); - else - return FALSE; + + return FALSE; } /** @@ -529,8 +515,7 @@ e1000_check_mng_mode(struct e1000_hw *hw) * * Writes the DHCP information to the host interface. **/ -s32 -e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) +s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) { return e1000_mng_write_dhcp_info_generic(hw, buffer, length); } @@ -542,13 +527,12 @@ e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) * This resets the hardware into a known state. This is a function pointer * entry point called by drivers. **/ -s32 -e1000_reset_hw(struct e1000_hw *hw) +s32 e1000_reset_hw(struct e1000_hw *hw) { - if (hw->func.reset_hw != NULL) + if (hw->func.reset_hw) return hw->func.reset_hw(hw); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -558,13 +542,12 @@ e1000_reset_hw(struct e1000_hw *hw) * This inits the hardware readying it for operation. This is a function * pointer entry point called by drivers. **/ -s32 -e1000_init_hw(struct e1000_hw *hw) +s32 e1000_init_hw(struct e1000_hw *hw) { - if (hw->func.init_hw != NULL) + if (hw->func.init_hw) return hw->func.init_hw(hw); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -575,13 +558,12 @@ e1000_init_hw(struct e1000_hw *hw) * is a function pointer entry point called by drivers. While modules can * also call this, they probably call their own version of this function. **/ -s32 -e1000_setup_link(struct e1000_hw *hw) +s32 e1000_setup_link(struct e1000_hw *hw) { - if (hw->func.setup_link != NULL) + if (hw->func.setup_link) return hw->func.setup_link(hw); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -594,13 +576,12 @@ e1000_setup_link(struct e1000_hw *hw) * variables passed in. This is a function pointer entry point called * by drivers. **/ -s32 -e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex) +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex) { - if (hw->func.get_link_up_info != NULL) + if (hw->func.get_link_up_info) return hw->func.get_link_up_info(hw, speed, duplex); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -611,13 +592,12 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex) * of the LED so it can be later restored. This is a function pointer entry * point called by drivers. **/ -s32 -e1000_setup_led(struct e1000_hw *hw) +s32 e1000_setup_led(struct e1000_hw *hw) { - if (hw->func.setup_led != NULL) + if (hw->func.setup_led) return hw->func.setup_led(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -627,13 +607,12 @@ e1000_setup_led(struct e1000_hw *hw) * This restores the SW controllable LED to the value saved off by * e1000_setup_led. This is a function pointer entry point called by drivers. **/ -s32 -e1000_cleanup_led(struct e1000_hw *hw) +s32 e1000_cleanup_led(struct e1000_hw *hw) { - if (hw->func.cleanup_led != NULL) + if (hw->func.cleanup_led) return hw->func.cleanup_led(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -644,13 +623,12 @@ e1000_cleanup_led(struct e1000_hw *hw) * and cleaned up after. This is a function pointer entry point called by * drivers. **/ -s32 -e1000_blink_led(struct e1000_hw *hw) +s32 e1000_blink_led(struct e1000_hw *hw) { - if (hw->func.blink_led != NULL) + if (hw->func.blink_led) return hw->func.blink_led(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -660,13 +638,12 @@ e1000_blink_led(struct e1000_hw *hw) * Turns the SW defined LED on. This is a function pointer entry point * called by drivers. **/ -s32 -e1000_led_on(struct e1000_hw *hw) +s32 e1000_led_on(struct e1000_hw *hw) { - if (hw->func.led_on != NULL) + if (hw->func.led_on) return hw->func.led_on(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -676,13 +653,12 @@ e1000_led_on(struct e1000_hw *hw) * Turns the SW defined LED off. This is a function pointer entry point * called by drivers. **/ -s32 -e1000_led_off(struct e1000_hw *hw) +s32 e1000_led_off(struct e1000_hw *hw) { - if (hw->func.led_off != NULL) + if (hw->func.led_off) return hw->func.led_off(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -692,8 +668,7 @@ e1000_led_off(struct e1000_hw *hw) * Resets the adaptive IFS. Currently no func pointer exists and all * implementations are handled in the generic version of this function. **/ -void -e1000_reset_adaptive(struct e1000_hw *hw) +void e1000_reset_adaptive(struct e1000_hw *hw) { e1000_reset_adaptive_generic(hw); } @@ -705,8 +680,7 @@ e1000_reset_adaptive(struct e1000_hw *hw) * Updates adapter IFS. Currently no func pointer exists and all * implementations are handled in the generic version of this function. **/ -void -e1000_update_adaptive(struct e1000_hw *hw) +void e1000_update_adaptive(struct e1000_hw *hw) { e1000_update_adaptive_generic(hw); } @@ -719,8 +693,7 @@ e1000_update_adaptive(struct e1000_hw *hw) * requests. Currently no func pointer exists and all implementations are * handled in the generic version of this function. **/ -s32 -e1000_disable_pcie_master(struct e1000_hw *hw) +s32 e1000_disable_pcie_master(struct e1000_hw *hw) { return e1000_disable_pcie_master_generic(hw); } @@ -732,10 +705,9 @@ e1000_disable_pcie_master(struct e1000_hw *hw) * Configures the collision distance to the default value and is used * during link setup. **/ -void -e1000_config_collision_dist(struct e1000_hw *hw) +void e1000_config_collision_dist(struct e1000_hw *hw) { - if (hw->func.config_collision_dist != NULL) + if (hw->func.config_collision_dist) hw->func.config_collision_dist(hw); } @@ -747,10 +719,9 @@ e1000_config_collision_dist(struct e1000_hw *hw) * * Sets a Receive Address Register (RAR) to the specified address. **/ -void -e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) +void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) { - if (hw->func.rar_set != NULL) + if (hw->func.rar_set) hw->func.rar_set(hw, addr, index); } @@ -760,13 +731,12 @@ e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) * * Ensures that the MDI/MDIX SW state is valid. **/ -s32 -e1000_validate_mdi_setting(struct e1000_hw *hw) +s32 e1000_validate_mdi_setting(struct e1000_hw *hw) { - if (hw->func.validate_mdi_setting != NULL) + if (hw->func.validate_mdi_setting) return hw->func.validate_mdi_setting(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -777,10 +747,9 @@ e1000_validate_mdi_setting(struct e1000_hw *hw) * This sets the bit in the multicast table corresponding to the * hash value. This is a function pointer entry point called by drivers. **/ -void -e1000_mta_set(struct e1000_hw *hw, u32 hash_value) +void e1000_mta_set(struct e1000_hw *hw, u32 hash_value) { - if (hw->func.mta_set != NULL) + if (hw->func.mta_set) hw->func.mta_set(hw, hash_value); } @@ -793,8 +762,7 @@ e1000_mta_set(struct e1000_hw *hw, u32 hash_value) * table. Currently no func pointer exists and all implementations * are handled in the generic version of this function. **/ -u32 -e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) +u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) { return e1000_hash_mc_addr_generic(hw, mc_addr); } @@ -808,8 +776,7 @@ e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) * Currently no func pointer exists and all implementations are handled in the * generic version of this function. **/ -boolean_t -e1000_enable_tx_pkt_filtering(struct e1000_hw *hw) +bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw) { return e1000_enable_tx_pkt_filtering_generic(hw); } @@ -826,15 +793,14 @@ e1000_enable_tx_pkt_filtering(struct e1000_hw *hw) * It also does alignment considerations to do the writes in most efficient * way. Also fills up the sum of the buffer in *buffer parameter. **/ -s32 -e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length, - u16 offset, u8 *sum) +s32 e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length, + u16 offset, u8 *sum) { - if (hw->func.mng_host_if_write != NULL) + if (hw->func.mng_host_if_write) return hw->func.mng_host_if_write(hw, buffer, length, offset, sum); - else - return E1000_NOT_IMPLEMENTED; + + return E1000_NOT_IMPLEMENTED; } /** @@ -844,14 +810,13 @@ e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length, * * Writes the command header after does the checksum calculation. **/ -s32 -e1000_mng_write_cmd_header(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr) +s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, + struct e1000_host_mng_command_header *hdr) { - if (hw->func.mng_write_cmd_header != NULL) + if (hw->func.mng_write_cmd_header) return hw->func.mng_write_cmd_header(hw, hdr); - else - return E1000_NOT_IMPLEMENTED; + + return E1000_NOT_IMPLEMENTED; } /** @@ -864,13 +829,12 @@ e1000_mng_write_cmd_header(struct e1000_hw *hw, * and also checks whether the previous command is completed. It busy waits * in case of previous command is not completed. **/ -s32 -e1000_mng_enable_host_if(struct e1000_hw * hw) +s32 e1000_mng_enable_host_if(struct e1000_hw * hw) { - if (hw->func.mng_enable_host_if != NULL) + if (hw->func.mng_enable_host_if) return hw->func.mng_enable_host_if(hw); - else - return E1000_NOT_IMPLEMENTED; + + return E1000_NOT_IMPLEMENTED; } /** @@ -880,13 +844,12 @@ e1000_mng_enable_host_if(struct e1000_hw * hw) * Waits for autoneg to complete. Currently no func pointer exists and all * implementations are handled in the generic version of this function. **/ -s32 -e1000_wait_autoneg(struct e1000_hw *hw) +s32 e1000_wait_autoneg(struct e1000_hw *hw) { - if (hw->func.wait_autoneg != NULL) + if (hw->func.wait_autoneg) return hw->func.wait_autoneg(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -896,13 +859,12 @@ e1000_wait_autoneg(struct e1000_hw *hw) * Checks if the PHY is in a state that can be reset or if manageability * has it tied up. This is a function pointer entry point called by drivers. **/ -s32 -e1000_check_reset_block(struct e1000_hw *hw) +s32 e1000_check_reset_block(struct e1000_hw *hw) { - if (hw->func.check_reset_block != NULL) + if (hw->func.check_reset_block) return hw->func.check_reset_block(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -914,13 +876,12 @@ e1000_check_reset_block(struct e1000_hw *hw) * Reads the PHY register and returns the value in data. * This is a function pointer entry point called by drivers. **/ -s32 -e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data) { - if (hw->func.read_phy_reg != NULL) + if (hw->func.read_phy_reg) return hw->func.read_phy_reg(hw, offset, data); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -932,13 +893,12 @@ e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data) * Writes the PHY register at offset with the value in data. * This is a function pointer entry point called by drivers. **/ -s32 -e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data) { - if (hw->func.write_phy_reg != NULL) + if (hw->func.write_phy_reg) return hw->func.write_phy_reg(hw, offset, data); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -951,8 +911,7 @@ e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data) * exists and all implementations are handled in the generic version of * this function. **/ -s32 -e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) { return e1000_read_kmrn_reg_generic(hw, offset, data); } @@ -967,8 +926,7 @@ e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) * exists and all implementations are handled in the generic version of * this function. **/ -s32 -e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) { return e1000_write_kmrn_reg_generic(hw, offset, data); } @@ -981,13 +939,12 @@ e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) * hw->phy.min_length and hw->phy.max_length. This is a function pointer * entry point called by drivers. **/ -s32 -e1000_get_cable_length(struct e1000_hw *hw) +s32 e1000_get_cable_length(struct e1000_hw *hw) { - if (hw->func.get_cable_length != NULL) + if (hw->func.get_cable_length) return hw->func.get_cable_length(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -998,13 +955,12 @@ e1000_get_cable_length(struct e1000_hw *hw) * populates hw->phy values with it. This is a function pointer entry * point called by drivers. **/ -s32 -e1000_get_phy_info(struct e1000_hw *hw) +s32 e1000_get_phy_info(struct e1000_hw *hw) { - if (hw->func.get_phy_info != NULL) + if (hw->func.get_phy_info) return hw->func.get_phy_info(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1014,13 +970,12 @@ e1000_get_phy_info(struct e1000_hw *hw) * Performs a hard PHY reset. This is a function pointer entry point called * by drivers. **/ -s32 -e1000_phy_hw_reset(struct e1000_hw *hw) +s32 e1000_phy_hw_reset(struct e1000_hw *hw) { - if (hw->func.reset_phy != NULL) + if (hw->func.reset_phy) return hw->func.reset_phy(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1030,13 +985,12 @@ e1000_phy_hw_reset(struct e1000_hw *hw) * Performs a soft PHY reset on those that apply. This is a function pointer * entry point called by drivers. **/ -s32 -e1000_phy_commit(struct e1000_hw *hw) +s32 e1000_phy_commit(struct e1000_hw *hw) { - if (hw->func.commit_phy != NULL) + if (hw->func.commit_phy) return hw->func.commit_phy(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1053,13 +1007,12 @@ e1000_phy_commit(struct e1000_hw *hw) * During driver activity, SmartSpeed should be enabled so performance is * maintained. This is a function pointer entry point called by drivers. **/ -s32 -e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active) +s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) { - if (hw->func.set_d0_lplu_state != NULL) + if (hw->func.set_d0_lplu_state) return hw->func.set_d0_lplu_state(hw, active); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1076,13 +1029,12 @@ e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active) * During driver activity, SmartSpeed should be enabled so performance is * maintained. This is a function pointer entry point called by drivers. **/ -s32 -e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active) +s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active) { - if (hw->func.set_d3_lplu_state != NULL) + if (hw->func.set_d3_lplu_state) return hw->func.set_d3_lplu_state(hw, active); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1093,26 +1045,27 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active) * Currently no func pointer exists and all implementations are handled in the * generic version of this function. **/ -s32 -e1000_read_mac_addr(struct e1000_hw *hw) +s32 e1000_read_mac_addr(struct e1000_hw *hw) { + if (hw->func.read_mac_addr) + return hw->func.read_mac_addr(hw); + return e1000_read_mac_addr_generic(hw); } /** - * e1000_read_part_num - Read device part number + * e1000_read_pba_num - Read device part number * @hw: pointer to the HW structure - * @part_num: pointer to device part number + * @pba_num: pointer to device part number * * Reads the product board assembly (PBA) number from the EEPROM and stores - * the value in part_num. + * the value in pba_num. * Currently no func pointer exists and all implementations are handled in the * generic version of this function. **/ -s32 -e1000_read_part_num(struct e1000_hw *hw, u32 *part_num) +s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *pba_num) { - return e1000_read_part_num_generic(hw, part_num); + return e1000_read_pba_num_generic(hw, pba_num); } /** @@ -1122,13 +1075,12 @@ e1000_read_part_num(struct e1000_hw *hw, u32 *part_num) * Validates the NVM checksum is correct. This is a function pointer entry * point called by drivers. **/ -s32 -e1000_validate_nvm_checksum(struct e1000_hw *hw) +s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) { - if (hw->func.validate_nvm != NULL) + if (hw->func.validate_nvm) return hw->func.validate_nvm(hw); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -1138,13 +1090,12 @@ e1000_validate_nvm_checksum(struct e1000_hw *hw) * Updates the NVM checksum. Currently no func pointer exists and all * implementations are handled in the generic version of this function. **/ -s32 -e1000_update_nvm_checksum(struct e1000_hw *hw) +s32 e1000_update_nvm_checksum(struct e1000_hw *hw) { - if (hw->func.update_nvm != NULL) + if (hw->func.update_nvm) return hw->func.update_nvm(hw); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -1154,10 +1105,9 @@ e1000_update_nvm_checksum(struct e1000_hw *hw) * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the * extended control register. **/ -void -e1000_reload_nvm(struct e1000_hw *hw) +void e1000_reload_nvm(struct e1000_hw *hw) { - if (hw->func.reload_nvm != NULL) + if (hw->func.reload_nvm) hw->func.reload_nvm(hw); } @@ -1171,13 +1121,12 @@ e1000_reload_nvm(struct e1000_hw *hw) * Reads 16-bit chunks of data from the NVM (EEPROM). This is a function * pointer entry point called by drivers. **/ -s32 -e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { - if (hw->func.read_nvm != NULL) + if (hw->func.read_nvm) return hw->func.read_nvm(hw, offset, words, data); - else - return -E1000_ERR_CONFIG; + + return -E1000_ERR_CONFIG; } /** @@ -1190,13 +1139,12 @@ e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * Writes 16-bit chunks of data to the NVM (EEPROM). This is a function * pointer entry point called by drivers. **/ -s32 -e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { - if (hw->func.write_nvm != NULL) + if (hw->func.write_nvm) return hw->func.write_nvm(hw, offset, words, data); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1209,8 +1157,36 @@ e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) * Writes the PHY register at offset with the value in data. * This is a function pointer entry point called by drivers. **/ -s32 -e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, u8 data) +s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, u8 data) { return e1000_write_8bit_ctrl_reg_generic(hw, reg, offset, data); } + +/** + * e1000_power_up_phy - Restores link in case of PHY power down + * @hw: pointer to the HW structure + * + * The phy may be powered down to save power, to turn off link when the + * driver is unloaded, or wake on lan is not enabled (among others). + **/ +void e1000_power_up_phy(struct e1000_hw *hw) +{ + if (hw->func.power_up_phy) + hw->func.power_up_phy(hw); + + e1000_setup_link(hw); +} + +/** + * e1000_power_down_phy - Power down PHY + * @hw: pointer to the HW structure + * + * The phy may be powered down to save power, to turn off link when the + * driver is unloaded, or wake on lan is not enabled (among others). + **/ +void e1000_power_down_phy(struct e1000_hw *hw) +{ + if (hw->func.power_down_phy) + hw->func.power_down_phy(hw); +} + diff --git a/sys/dev/em/e1000_api.h b/sys/dev/em/e1000_api.h index 15a274fa562b..bd8e93a3080a 100644 --- a/sys/dev/em/e1000_api.h +++ b/sys/dev/em/e1000_api.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_API_H_ @@ -38,95 +38,99 @@ #include "e1000_hw.h" -s32 e1000_set_mac_type(struct e1000_hw *hw); -s32 e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t init_device); -s32 e1000_init_mac_params(struct e1000_hw *hw); -s32 e1000_init_nvm_params(struct e1000_hw *hw); -s32 e1000_init_phy_params(struct e1000_hw *hw); -void e1000_remove_device(struct e1000_hw *hw); -s32 e1000_get_bus_info(struct e1000_hw *hw); -void e1000_clear_vfta(struct e1000_hw *hw); -void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value); -s32 e1000_force_mac_fc(struct e1000_hw *hw); -s32 e1000_check_for_link(struct e1000_hw *hw); -s32 e1000_reset_hw(struct e1000_hw *hw); -s32 e1000_init_hw(struct e1000_hw *hw); -s32 e1000_setup_link(struct e1000_hw *hw); -s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, - u16 *duplex); -s32 e1000_disable_pcie_master(struct e1000_hw *hw); -void e1000_config_collision_dist(struct e1000_hw *hw); -void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); -void e1000_mta_set(struct e1000_hw *hw, u32 hash_value); -u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr); -void e1000_mc_addr_list_update(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count, - u32 rar_used_count, u32 rar_count); -s32 e1000_setup_led(struct e1000_hw *hw); -s32 e1000_cleanup_led(struct e1000_hw *hw); -s32 e1000_check_reset_block(struct e1000_hw *hw); -s32 e1000_blink_led(struct e1000_hw *hw); -s32 e1000_led_on(struct e1000_hw *hw); -s32 e1000_led_off(struct e1000_hw *hw); -void e1000_reset_adaptive(struct e1000_hw *hw); -void e1000_update_adaptive(struct e1000_hw *hw); -s32 e1000_get_cable_length(struct e1000_hw *hw); -s32 e1000_validate_mdi_setting(struct e1000_hw *hw); -s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data); -s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data); -s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, - u32 offset, u8 data); -s32 e1000_get_phy_info(struct e1000_hw *hw); -s32 e1000_phy_hw_reset(struct e1000_hw *hw); -s32 e1000_phy_commit(struct e1000_hw *hw); -s32 e1000_read_mac_addr(struct e1000_hw *hw); -s32 e1000_read_part_num(struct e1000_hw *hw, u32 *part_num); -void e1000_reload_nvm(struct e1000_hw *hw); -s32 e1000_update_nvm_checksum(struct e1000_hw *hw); -s32 e1000_validate_nvm_checksum(struct e1000_hw *hw); -s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); -s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); -s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, - u16 *data); -s32 e1000_wait_autoneg(struct e1000_hw *hw); -s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); -s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active); -boolean_t e1000_check_mng_mode(struct e1000_hw *hw); -boolean_t e1000_enable_mng_pass_thru(struct e1000_hw *hw); -boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw); -s32 e1000_mng_enable_host_if(struct e1000_hw *hw); -s32 e1000_mng_host_if_write(struct e1000_hw *hw, - u8 *buffer, u16 length, u16 offset, u8 *sum); -s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr); -s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw, +s32 e1000_set_mac_type(struct e1000_hw *hw); +s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device); +s32 e1000_init_mac_params(struct e1000_hw *hw); +s32 e1000_init_nvm_params(struct e1000_hw *hw); +s32 e1000_init_phy_params(struct e1000_hw *hw); +void e1000_remove_device(struct e1000_hw *hw); +s32 e1000_get_bus_info(struct e1000_hw *hw); +void e1000_clear_vfta(struct e1000_hw *hw); +void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value); +s32 e1000_force_mac_fc(struct e1000_hw *hw); +s32 e1000_check_for_link(struct e1000_hw *hw); +s32 e1000_reset_hw(struct e1000_hw *hw); +s32 e1000_init_hw(struct e1000_hw *hw); +s32 e1000_setup_link(struct e1000_hw *hw); +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, + u16 *duplex); +s32 e1000_disable_pcie_master(struct e1000_hw *hw); +void e1000_config_collision_dist(struct e1000_hw *hw); +void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); +void e1000_mta_set(struct e1000_hw *hw, u32 hash_value); +u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr); +void e1000_update_mc_addr_list(struct e1000_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count, + u32 rar_used_count, u32 rar_count); +s32 e1000_setup_led(struct e1000_hw *hw); +s32 e1000_cleanup_led(struct e1000_hw *hw); +s32 e1000_check_reset_block(struct e1000_hw *hw); +s32 e1000_blink_led(struct e1000_hw *hw); +s32 e1000_led_on(struct e1000_hw *hw); +s32 e1000_led_off(struct e1000_hw *hw); +void e1000_reset_adaptive(struct e1000_hw *hw); +void e1000_update_adaptive(struct e1000_hw *hw); +s32 e1000_get_cable_length(struct e1000_hw *hw); +s32 e1000_validate_mdi_setting(struct e1000_hw *hw); +s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data); +s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data); +s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, + u32 offset, u8 data); +s32 e1000_get_phy_info(struct e1000_hw *hw); +s32 e1000_phy_hw_reset(struct e1000_hw *hw); +s32 e1000_phy_commit(struct e1000_hw *hw); +void e1000_power_up_phy(struct e1000_hw *hw); +void e1000_power_down_phy(struct e1000_hw *hw); +s32 e1000_read_mac_addr(struct e1000_hw *hw); +s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *part_num); +void e1000_reload_nvm(struct e1000_hw *hw); +s32 e1000_update_nvm_checksum(struct e1000_hw *hw); +s32 e1000_validate_nvm_checksum(struct e1000_hw *hw); +s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); +s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); +s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); +s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data); +s32 e1000_wait_autoneg(struct e1000_hw *hw); +s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active); +s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active); +bool e1000_check_mng_mode(struct e1000_hw *hw); +bool e1000_enable_mng_pass_thru(struct e1000_hw *hw); +bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw); +s32 e1000_mng_enable_host_if(struct e1000_hw *hw); +s32 e1000_mng_host_if_write(struct e1000_hw *hw, + u8 *buffer, u16 length, u16 offset, u8 *sum); +s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, + struct e1000_host_mng_command_header *hdr); +s32 e1000_mng_write_dhcp_info(struct e1000_hw * hw, u8 *buffer, u16 length); -void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw, - struct e1000_hw_stats *stats, - u32 frame_len, u8 *mac_addr); -void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, - boolean_t state); -boolean_t e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw); +void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw, + struct e1000_hw_stats *stats, + u32 frame_len, u8 *mac_addr, + u32 max_frame_size); +void e1000_set_tbi_compatibility_82543(struct e1000_hw *hw, + bool state); +bool e1000_tbi_sbp_enabled_82543(struct e1000_hw *hw); #ifndef NO_82542_SUPPORT -u32 e1000_translate_register_82542(u32 reg); +u32 e1000_translate_register_82542(u32 reg); #endif -void e1000_init_script_state_82541(struct e1000_hw *hw, boolean_t state); -boolean_t e1000_get_laa_state_82571(struct e1000_hw *hw); -void e1000_set_laa_state_82571(struct e1000_hw *hw, boolean_t state); -void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, - boolean_t state); -void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); -void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); +void e1000_init_script_state_82541(struct e1000_hw *hw, bool state); +bool e1000_get_laa_state_82571(struct e1000_hw *hw); +void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state); +void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, + bool state); +void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); +void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); -/* TBI_ACCEPT macro definition: +/* + * TBI_ACCEPT macro definition: * * This macro requires: * adapter = a pointer to struct e1000_hw - * status = the 8 bit status field of the RX descriptor with EOP set - * error = the 8 bit error field of the RX descriptor with EOP set - * length = the sum of all the length fields of the RX descriptors that + * status = the 8 bit status field of the Rx descriptor with EOP set + * error = the 8 bit error field of the Rx descriptor with EOP set + * length = the sum of all the length fields of the Rx descriptors that * make up the current frame * last_byte = the last byte of the frame DMAed by the hardware * max_frame_length = the maximum frame length we want to accept. @@ -150,14 +154,14 @@ void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); /* The carrier extension symbol, as received by the NIC. */ #define CARRIER_EXTENSION 0x0F -#define TBI_ACCEPT(a, status, errors, length, last_byte) \ +#define TBI_ACCEPT(a, status, errors, length, last_byte, min_frame_size, max_frame_size) \ (e1000_tbi_sbp_enabled_82543(a) && \ (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \ ((last_byte) == CARRIER_EXTENSION) && \ (((status) & E1000_RXD_STAT_VP) ? \ - (((length) > ((a)->mac.min_frame_size - VLAN_TAG_SIZE)) && \ - ((length) <= ((a)->mac.max_frame_size + 1))) : \ - (((length) > (a)->mac.min_frame_size) && \ - ((length) <= ((a)->mac.max_frame_size + VLAN_TAG_SIZE + 1))))) + (((length) > (min_frame_size - VLAN_TAG_SIZE)) && \ + ((length) <= (max_frame_size + 1))) : \ + (((length) > min_frame_size) && \ + ((length) <= (max_frame_size + VLAN_TAG_SIZE + 1))))) #endif diff --git a/sys/dev/em/e1000_defines.h b/sys/dev/em/e1000_defines.h index 342297669c8a..9d87064bc332 100644 --- a/sys/dev/em/e1000_defines.h +++ b/sys/dev/em/e1000_defines.h @@ -30,31 +30,12 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_DEFINES_H_ #define _E1000_DEFINES_H_ -#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ -#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ -#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ -#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ -#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ -#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ -#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */ -#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ -#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ -#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ -#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ -#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ -#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ -#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ -#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ -#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ -#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ -/* Extended desc bits for Linksec and timesync */ /* Number of Transmit and Receive Descriptors must be a multiple of 8 */ #define REQ_TX_DESCRIPTOR_MULTIPLE 8 #define REQ_RX_DESCRIPTOR_MULTIPLE 8 @@ -243,20 +224,20 @@ #define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ #define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ #define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ -#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery - * Filtering */ +/* Enable Neighbor Discovery Filtering */ +#define E1000_MANC_NEIGHBOR_EN 0x00004000 #define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */ #define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ #define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ #define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */ #define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ -#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address - * filtering */ -#define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host - * memory */ -#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address - * filtering */ +/* Enable MAC address filtering */ +#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 +/* Enable MNG packets to host memory */ +#define E1000_MANC_EN_MNG2HOST 0x00200000 +/* Enable IP address filtering */ +#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 #define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */ #define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */ #define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ @@ -311,7 +292,8 @@ #define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ #define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ -/* Use byte values for the following shift parameters +/* + * Use byte values for the following shift parameters * Usage: * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) & * E1000_PSRCTL_BSIZE0_MASK) | @@ -342,6 +324,8 @@ #define E1000_SWFW_PHY0_SM 0x2 #define E1000_SWFW_PHY1_SM 0x4 +/* FACTPS Definitions */ +#define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */ /* Device Control */ #define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ #define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ @@ -533,6 +517,7 @@ /* Transmit Descriptor bit definitions */ #define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ #define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ +#define E1000_TXD_POPTS_SHIFT 8 /* POPTS shift */ #define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ #define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ #define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ @@ -551,6 +536,7 @@ #define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ #define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ #define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ +/* Extended desc bits for Linksec and timesync */ /* Transmit Control */ #define E1000_TCTL_RST 0x00000001 /* software reset */ @@ -651,9 +637,9 @@ #define E1000_KABGTXD_BGSQLBIAS 0x00050000 /* PBA constants */ -#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ -#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ -#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ +#define E1000_PBA_8K 0x0008 /* 8KB */ +#define E1000_PBA_12K 0x000C /* 12KB */ +#define E1000_PBA_16K 0x0010 /* 16KB */ #define E1000_PBA_20K 0x0014 #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 @@ -662,7 +648,8 @@ #define E1000_PBA_34K 0x0022 #define E1000_PBA_38K 0x0026 #define E1000_PBA_40K 0x0028 -#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */ +#define E1000_PBA_48K 0x0030 /* 48KB */ +#define E1000_PBA_64K 0x0040 /* 64KB */ #define E1000_PBS_16K E1000_PBA_16K #define E1000_PBS_24K E1000_PBA_24K @@ -688,7 +675,7 @@ #define E1000_ICR_RXO 0x00000040 /* rx overrun */ #define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ #define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ -#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */ +#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */ #define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ #define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ #define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ @@ -727,7 +714,8 @@ #define E1000_TCPTIMER_COUNT_FINISH 0x00000400 /* Count finish */ #define E1000_TCPTIMER_LOOP 0x00000800 /* Loop */ -/* This defines the bits that are set in the Interrupt Mask +/* + * This defines the bits that are set in the Interrupt Mask * Set/Read Register. Each bit is documented below: * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) * o RXSEQ = Receive Sequence Error @@ -736,7 +724,8 @@ E1000_IMS_RXDMT0 | \ E1000_IMS_RXSEQ) -/* This defines the bits that are set in the Interrupt Mask +/* + * This defines the bits that are set in the Interrupt Mask * Set/Read Register. Each bit is documented below: * o RXT0 = Receiver Timer Interrupt (ring 0) * o TXDW = Transmit Descriptor Written Back @@ -760,7 +749,7 @@ #define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ #define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ #define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ #define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ #define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ @@ -801,7 +790,7 @@ #define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ #define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ #define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ -#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */ +#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ #define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ #define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ #define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ @@ -841,8 +830,8 @@ #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ #define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */ -#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc. - still to be processed. */ +/* Enable the counting of descriptors still to be processed. */ +#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Flow Control Constants */ #define FLOW_CONTROL_ADDRESS_LOW 0x00C28001 @@ -854,7 +843,8 @@ #define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ /* Receive Address */ -/* Number of high/low register pairs in the RAR. The RAR (Receive Address +/* + * Number of high/low register pairs in the RAR. The RAR (Receive Address * Registers) holds the directed and multicast addresses that we monitor. * Technically, we have 16 spots. However, we reserve one of these spots * (RAR[15]) for our directed address used by controllers with @@ -1021,7 +1011,7 @@ #define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ #define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ #define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ -#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ +#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local Tx is Master, 0=Slave */ #define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ #define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5 @@ -1035,7 +1025,7 @@ #define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ #define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ #define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ -#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */ +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page Tx */ #define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ #define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ @@ -1054,8 +1044,8 @@ #define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */ #define E1000_EECD_PRES 0x00000100 /* NVM Present */ #define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */ -#define E1000_EECD_ADDR_BITS 0x00000400 /* NVM Addressing bits based on type - * (0-small, 1-large) */ +/* NVM Addressing bits based on type 0=small, 1=large */ +#define E1000_EECD_ADDR_BITS 0x00000400 #define E1000_EECD_TYPE 0x00002000 /* NVM Type (1-SPI, 0-Microwire) */ #ifndef E1000_NVM_GRANT_ATTEMPTS #define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */ @@ -1097,6 +1087,7 @@ #define NVM_INIT_CONTROL3_PORT_A 0x0024 #define NVM_CFG 0x0012 #define NVM_FLASH_VERSION 0x0032 +#define NVM_ALT_MAC_ADDR_PTR 0x0037 #define NVM_CHECKSUM_REG 0x003F #define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */ @@ -1199,7 +1190,8 @@ #define MAX_PHY_MULTI_PAGE_REG 0xF /* Bit definitions for valid PHY IDs. */ -/* I = Integrated +/* + * I = Integrated * E = External */ #define M88E1000_E_PHY_ID 0x01410C50 @@ -1233,26 +1225,22 @@ #define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ #define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ #define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */ -#define M88E1000_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, - * 0=CLK125 toggling - */ +/* 1=CLK125 low, 0=CLK125 toggling */ +#define M88E1000_PSCR_CLK125_DISABLE 0x0010 #define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */ /* Manual MDI configuration */ #define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ -#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, - * 100BASE-TX/10BASE-T: - * MDI Mode - */ -#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled - * all speeds. - */ +/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ +#define M88E1000_PSCR_AUTO_X_1000T 0x0040 +/* Auto crossover enabled all speeds */ +#define M88E1000_PSCR_AUTO_X_MODE 0x0060 +/* + * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T Rx Threshold + * 0=Normal 10BASE-T Rx Threshold + */ #define M88E1000_PSCR_EN_10BT_EXT_DIST 0x0080 - /* 1=Enable Extended 10BASE-T distance - * (Lower 10BASE-T RX Threshold) - * 0=Normal 10BASE-T RX Threshold */ +/* 1=5-bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */ #define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100 - /* 1=5-Bit interface in 100BASE-TX - * 0=MII interface in 100BASE-TX */ #define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ #define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ #define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ @@ -1262,8 +1250,14 @@ #define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ #define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */ #define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ -#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M; - * 3=110-140M;4=>140M */ +/* + * 0 = <50M + * 1 = 50-80M + * 2 = 80-110M + * 3 = 110-140M + * 4 = >140M + */ +#define M88E1000_PSSR_CABLE_LENGTH 0x0380 #define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */ #define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ #define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */ @@ -1277,20 +1271,26 @@ /* M88E1000 Extended PHY Specific Control Register */ #define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */ -#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 /* 1=Lost lock detect enabled. - * Will assert lost lock and bring - * link down if idle not seen - * within 1ms in 1000BASE-T - */ -/* Number of times we will attempt to autonegotiate before downshifting if we - * are the master */ +/* + * 1 = Lost lock detect enabled. + * Will assert lost lock and bring + * link down if idle not seen + * within 1ms in 1000BASE-T + */ +#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 +/* + * Number of times we will attempt to autonegotiate before downshifting if we + * are the master + */ #define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00 -/* Number of times we will attempt to autonegotiate before downshifting if we - * are the slave */ +/* + * Number of times we will attempt to autonegotiate before downshifting if we + * are the slave + */ #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300 #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000 #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 @@ -1311,7 +1311,8 @@ #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00 -/* Bits... +/* + * Bits... * 15-5: page * 4-0: register offset */ @@ -1400,4 +1401,30 @@ #define E1000_GEN_CTL_READY 0x80000000 #define E1000_GEN_CTL_ADDRESS_SHIFT 8 #define E1000_GEN_POLL_TIMEOUT 640 + +/* LinkSec register fields */ +#define E1000_LSECTXCAP_SUM_MASK 0x00FF0000 +#define E1000_LSECTXCAP_SUM_SHIFT 16 +#define E1000_LSECRXCAP_SUM_MASK 0x00FF0000 +#define E1000_LSECRXCAP_SUM_SHIFT 16 + +#define E1000_LSECTXCTRL_EN_MASK 0x00000003 +#define E1000_LSECTXCTRL_DISABLE 0x0 +#define E1000_LSECTXCTRL_AUTH 0x1 +#define E1000_LSECTXCTRL_AUTH_ENCRYPT 0x2 +#define E1000_LSECTXCTRL_AISCI 0x00000020 +#define E1000_LSECTXCTRL_PNTHRSH_MASK 0xFFFFFF00 +#define E1000_LSECTXCTRL_RSV_MASK 0x000000D8 + +#define E1000_LSECRXCTRL_EN_MASK 0x0000000C +#define E1000_LSECRXCTRL_EN_SHIFT 2 +#define E1000_LSECRXCTRL_DISABLE 0x0 +#define E1000_LSECRXCTRL_CHECK 0x1 +#define E1000_LSECRXCTRL_STRICT 0x2 +#define E1000_LSECRXCTRL_DROP 0x3 +#define E1000_LSECRXCTRL_PLSH 0x00000040 +#define E1000_LSECRXCTRL_RP 0x00000080 +#define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33 + +#define UNREFERENCED_PARAMETER(_p) #endif diff --git a/sys/dev/em/e1000_hw.h b/sys/dev/em/e1000_hw.h index c5f2cd72804b..5e98a24afcdc 100644 --- a/sys/dev/em/e1000_hw.h +++ b/sys/dev/em/e1000_hw.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_HW_H_ @@ -86,6 +86,7 @@ struct e1000_hw; #define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 #define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA #define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 #define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 #define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC #define E1000_DEV_ID_82572EI_COPPER 0x107D @@ -113,8 +114,6 @@ struct e1000_hw; #define E1000_DEV_ID_ICH9_IFE_G 0x10C2 #define E1000_DEV_ID_82575EB_COPPER 0x10A7 #define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9 -#define E1000_DEV_ID_82575EM_COPPER 0x10AA -#define E1000_DEV_ID_82575EM_FIBER_SERDES 0x10AC #define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6 #define E1000_REVISION_0 0 @@ -204,6 +203,7 @@ typedef enum { e1000_bus_speed_120, e1000_bus_speed_133, e1000_bus_speed_2500, + e1000_bus_speed_5000, e1000_bus_speed_reserved } e1000_bus_speed; @@ -212,6 +212,7 @@ typedef enum { e1000_bus_width_pcie_x1, e1000_bus_width_pcie_x2, e1000_bus_width_pcie_x4 = 4, + e1000_bus_width_pcie_x8 = 8, e1000_bus_width_32, e1000_bus_width_64, e1000_bus_width_reserved @@ -235,7 +236,7 @@ typedef enum { e1000_fc_tx_pause, e1000_fc_full, e1000_fc_default = 0xFF -} e1000_fc_mode; +} e1000_fc_type; typedef enum { e1000_ffe_config_enabled = 0, @@ -382,7 +383,7 @@ struct e1000_data_desc { struct { u8 status; /* Descriptor status */ u8 popts; /* Packet Options */ - u16 special; /* */ + u16 special; } fields; } upper; }; @@ -419,10 +420,8 @@ struct e1000_hw_stats { u64 bprc; u64 mprc; u64 gptc; - u64 gorcl; - u64 gorch; - u64 gotcl; - u64 gotch; + u64 gorc; + u64 gotc; u64 rnbc; u64 ruc; u64 rfc; @@ -431,10 +430,8 @@ struct e1000_hw_stats { u64 mgprc; u64 mgpdc; u64 mgptc; - u64 torl; - u64 torh; - u64 totl; - u64 toth; + u64 tor; + u64 tot; u64 tpr; u64 tpt; u64 ptc64; @@ -463,10 +460,8 @@ struct e1000_hw_stats { u64 rpthc; u64 hgptc; u64 htcbdpc; - u64 hgorcl; - u64 hgorch; - u64 hgotcl; - u64 hgotch; + u64 hgorc; + u64 hgotc; u64 lenerrs; u64 scvpc; u64 hrmpc; @@ -524,63 +519,66 @@ struct e1000_host_mng_command_info { struct e1000_functions { /* Function pointers for the MAC. */ - s32 (*init_mac_params)(struct e1000_hw *); - s32 (*blink_led)(struct e1000_hw *); - s32 (*check_for_link)(struct e1000_hw *); - boolean_t (*check_mng_mode)(struct e1000_hw *hw); - s32 (*cleanup_led)(struct e1000_hw *); - void (*clear_hw_cntrs)(struct e1000_hw *); - void (*clear_vfta)(struct e1000_hw *); - s32 (*get_bus_info)(struct e1000_hw *); - s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); - s32 (*led_on)(struct e1000_hw *); - s32 (*led_off)(struct e1000_hw *); - void (*mc_addr_list_update)(struct e1000_hw *, u8 *, u32, u32, - u32); - void (*remove_device)(struct e1000_hw *); - s32 (*reset_hw)(struct e1000_hw *); - s32 (*init_hw)(struct e1000_hw *); - s32 (*setup_link)(struct e1000_hw *); - s32 (*setup_physical_interface)(struct e1000_hw *); - s32 (*setup_led)(struct e1000_hw *); - void (*write_vfta)(struct e1000_hw *, u32, u32); - void (*mta_set)(struct e1000_hw *, u32); - void (*config_collision_dist)(struct e1000_hw*); - void (*rar_set)(struct e1000_hw*, u8*, u32); - s32 (*validate_mdi_setting)(struct e1000_hw*); - s32 (*mng_host_if_write)(struct e1000_hw*, u8*, u16, u16, u8*); - s32 (*mng_write_cmd_header)(struct e1000_hw *hw, - struct e1000_host_mng_command_header*); - s32 (*mng_enable_host_if)(struct e1000_hw*); - s32 (*wait_autoneg)(struct e1000_hw*); + s32 (*init_mac_params)(struct e1000_hw *); + s32 (*blink_led)(struct e1000_hw *); + s32 (*check_for_link)(struct e1000_hw *); + bool (*check_mng_mode)(struct e1000_hw *hw); + s32 (*cleanup_led)(struct e1000_hw *); + void (*clear_hw_cntrs)(struct e1000_hw *); + void (*clear_vfta)(struct e1000_hw *); + s32 (*get_bus_info)(struct e1000_hw *); + s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); + s32 (*led_on)(struct e1000_hw *); + s32 (*led_off)(struct e1000_hw *); + void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, + u32); + void (*remove_device)(struct e1000_hw *); + s32 (*reset_hw)(struct e1000_hw *); + s32 (*init_hw)(struct e1000_hw *); + s32 (*setup_link)(struct e1000_hw *); + s32 (*setup_physical_interface)(struct e1000_hw *); + s32 (*setup_led)(struct e1000_hw *); + void (*write_vfta)(struct e1000_hw *, u32, u32); + void (*mta_set)(struct e1000_hw *, u32); + void (*config_collision_dist)(struct e1000_hw*); + void (*rar_set)(struct e1000_hw*, u8*, u32); + s32 (*read_mac_addr)(struct e1000_hw*); + s32 (*validate_mdi_setting)(struct e1000_hw*); + s32 (*mng_host_if_write)(struct e1000_hw*, u8*, u16, u16, u8*); + s32 (*mng_write_cmd_header)(struct e1000_hw *hw, + struct e1000_host_mng_command_header*); + s32 (*mng_enable_host_if)(struct e1000_hw*); + s32 (*wait_autoneg)(struct e1000_hw*); /* Function pointers for the PHY. */ - s32 (*init_phy_params)(struct e1000_hw *); - s32 (*acquire_phy)(struct e1000_hw *); - s32 (*check_polarity)(struct e1000_hw *); - s32 (*check_reset_block)(struct e1000_hw *); - s32 (*commit_phy)(struct e1000_hw *); - s32 (*force_speed_duplex)(struct e1000_hw *); - s32 (*get_cfg_done)(struct e1000_hw *hw); - s32 (*get_cable_length)(struct e1000_hw *); - s32 (*get_phy_info)(struct e1000_hw *); - s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *); - void (*release_phy)(struct e1000_hw *); - s32 (*reset_phy)(struct e1000_hw *); - s32 (*set_d0_lplu_state)(struct e1000_hw *, boolean_t); - s32 (*set_d3_lplu_state)(struct e1000_hw *, boolean_t); - s32 (*write_phy_reg)(struct e1000_hw *, u32, u16); + s32 (*init_phy_params)(struct e1000_hw *); + s32 (*acquire_phy)(struct e1000_hw *); + s32 (*check_polarity)(struct e1000_hw *); + s32 (*check_reset_block)(struct e1000_hw *); + s32 (*commit_phy)(struct e1000_hw *); + s32 (*force_speed_duplex)(struct e1000_hw *); + s32 (*get_cfg_done)(struct e1000_hw *hw); + s32 (*get_cable_length)(struct e1000_hw *); + s32 (*get_phy_info)(struct e1000_hw *); + s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *); + void (*release_phy)(struct e1000_hw *); + s32 (*reset_phy)(struct e1000_hw *); + s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); + s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); + s32 (*write_phy_reg)(struct e1000_hw *, u32, u16); + void (*power_up_phy)(struct e1000_hw *); + void (*power_down_phy)(struct e1000_hw *); /* Function pointers for the NVM. */ - s32 (*init_nvm_params)(struct e1000_hw *); - s32 (*acquire_nvm)(struct e1000_hw *); - s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *); - void (*release_nvm)(struct e1000_hw *); - void (*reload_nvm)(struct e1000_hw *); - s32 (*update_nvm)(struct e1000_hw *); - s32 (*valid_led_default)(struct e1000_hw *, u16 *); - s32 (*validate_nvm)(struct e1000_hw *); - s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *); + s32 (*init_nvm_params)(struct e1000_hw *); + s32 (*acquire_nvm)(struct e1000_hw *); + s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *); + void (*release_nvm)(struct e1000_hw *); + void (*reload_nvm)(struct e1000_hw *); + s32 (*update_nvm)(struct e1000_hw *); + s32 (*valid_led_default)(struct e1000_hw *, u16 *); + s32 (*validate_nvm)(struct e1000_hw *); + s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *); }; struct e1000_mac_info { @@ -588,16 +586,12 @@ struct e1000_mac_info { u8 perm_addr[6]; e1000_mac_type type; - e1000_fc_mode fc; - e1000_fc_mode original_fc; u32 collision_delta; u32 ledctl_default; u32 ledctl_mode1; u32 ledctl_mode2; - u32 max_frame_size; u32 mc_filter_type; - u32 min_frame_size; u32 tx_packet_delta; u32 txcw; @@ -608,27 +602,22 @@ struct e1000_mac_info { u16 ifs_step_size; u16 mta_reg_count; u16 rar_entry_count; - u16 fc_high_water; - u16 fc_low_water; - u16 fc_pause_time; u8 forced_speed_duplex; - boolean_t adaptive_ifs; - boolean_t arc_subsystem_valid; - boolean_t asf_firmware_present; - boolean_t autoneg; - boolean_t autoneg_failed; - boolean_t disable_av; - boolean_t disable_hw_init_bits; - boolean_t fc_send_xon; - boolean_t fc_strict_ieee; - boolean_t get_link_status; - boolean_t ifs_params_forced; - boolean_t in_ifs_mode; - boolean_t report_tx_early; - boolean_t serdes_has_link; - boolean_t tx_pkt_filtering; + bool adaptive_ifs; + bool arc_subsystem_valid; + bool asf_firmware_present; + bool autoneg; + bool autoneg_failed; + bool disable_av; + bool disable_hw_init_bits; + bool get_link_status; + bool ifs_params_forced; + bool in_ifs_mode; + bool report_tx_early; + bool serdes_has_link; + bool tx_pkt_filtering; }; struct e1000_phy_info { @@ -646,6 +635,8 @@ struct e1000_phy_info { u32 reset_delay_us; /* in usec */ u32 revision; + e1000_media_type media_type; + u16 autoneg_advertised; u16 autoneg_mask; u16 cable_length; @@ -654,12 +645,12 @@ struct e1000_phy_info { u8 mdix; - boolean_t disable_polarity_correction; - boolean_t is_mdix; - boolean_t polarity_correction; - boolean_t reset_disable; - boolean_t speed_downgraded; - boolean_t wait_for_link; + bool disable_polarity_correction; + bool is_mdix; + bool polarity_correction; + bool reset_disable; + bool speed_downgraded; + bool autoneg_wait_to_complete; }; struct e1000_nvm_info { @@ -687,6 +678,16 @@ struct e1000_bus_info { u16 pci_cmd_word; }; +struct e1000_fc_info { + u32 high_water; /* Flow control high-water mark */ + u32 low_water; /* Flow control low-water mark */ + u16 pause_time; /* Flow control pause timer */ + bool send_xon; /* Flow control send XON */ + bool strict_ieee; /* Strict IEEE mode */ + e1000_fc_type type; /* Type of flow control */ + e1000_fc_type original_type; +}; + struct e1000_hw { void *back; void *dev_spec; @@ -697,13 +698,12 @@ struct e1000_hw { struct e1000_functions func; struct e1000_mac_info mac; + struct e1000_fc_info fc; struct e1000_phy_info phy; struct e1000_nvm_info nvm; struct e1000_bus_info bus; struct e1000_host_mng_dhcp_cookie mng_cookie; - e1000_media_type media_type; - u32 dev_spec_size; u16 device_id; diff --git a/sys/dev/em/e1000_ich8lan.c b/sys/dev/em/e1000_ich8lan.c index 7a7ced1c0d2c..4b288114e59b 100644 --- a/sys/dev/em/e1000_ich8lan.c +++ b/sys/dev/em/e1000_ich8lan.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ /* e1000_ich8lan @@ -42,57 +42,58 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); -STATIC void e1000_release_swflag_ich8lan(struct e1000_hw *hw); -STATIC boolean_t e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, - boolean_t active); -STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, - boolean_t active); -STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); -STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, - u16 words, u16 *data); -STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, - u16 *data); -STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, - u16 *speed, u16 *duplex); -STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw); -STATIC void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); -static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout); -static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw); -static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw); -static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); -static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); -static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16* data); -STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, - u32 offset, u16 *data); -static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, - u32 offset, u8 byte); -STATIC s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, - u32 offset, u8 data); -static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16 data); -STATIC s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); +STATIC void e1000_release_swflag_ich8lan(struct e1000_hw *hw); +STATIC bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, + bool active); +STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, + bool active); +STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, + u16 words, u16 *data); +STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, + u16 words, u16 *data); +STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, + u16 *data); +STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_init_hw_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, + u16 *speed, u16 *duplex); +STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw); +STATIC void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); +STATIC s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); +static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout); +static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw); +static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw); +static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); +static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); +static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, + u8 size, u16* data); +STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, + u32 offset, u16 *data); +static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, + u32 offset, u8 byte); +STATIC s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, + u32 offset, u8 data); +static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, + u8 size, u16 data); +STATIC s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); +STATIC void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ @@ -137,11 +138,11 @@ union ich8_hws_flash_regacc { struct e1000_shadow_ram { u16 value; - boolean_t modified; + bool modified; }; struct e1000_dev_spec_ich8lan { - boolean_t kmrn_lock_loss_workaround_enabled; + bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS]; }; @@ -151,8 +152,7 @@ struct e1000_dev_spec_ich8lan { * * Initialize family-specific PHY parameters and function pointers. **/ -STATIC s32 -e1000_init_phy_params_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; struct e1000_functions *func = &hw->func; @@ -177,6 +177,8 @@ e1000_init_phy_params_ich8lan(struct e1000_hw *hw) func->set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; func->set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; func->write_phy_reg = e1000_write_phy_reg_igp; + func->power_up_phy = e1000_power_up_phy_copper; + func->power_down_phy = e1000_power_down_phy_copper_ich8lan; phy->id = 0; @@ -216,20 +218,18 @@ out: * Initialize family-specific NVM parameters and function * pointers. **/ -STATIC s32 -e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_functions *func = &hw->func; struct e1000_dev_spec_ich8lan *dev_spec; u32 gfpreg, sector_base_addr, sector_end_addr; - s32 ret_val = E1000_SUCCESS; + s32 ret_val = E1000_SUCCESS; u16 i; DEBUGFUNC("e1000_init_nvm_params_ich8lan"); - /* Can't read flash registers if the register set isn't mapped. - */ + /* Can't read flash registers if the register set isn't mapped. */ if (!hw->flash_address) { DEBUGOUT("ERROR: Flash registers not mapped\n"); ret_val = -E1000_ERR_CONFIG; @@ -240,17 +240,21 @@ e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG); - /* sector_X_addr is a "sector"-aligned address (4096 bytes) + /* + * sector_X_addr is a "sector"-aligned address (4096 bytes) * Add 1 to sector_end_addr since this sector is included in - * the overall size. */ + * the overall size. + */ sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK; sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1; /* flash_base_addr is byte-aligned */ nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT; - /* find total size of the NVM, then cut in half since the total - * size represents two separate NVM banks. */ + /* + * find total size of the NVM, then cut in half since the total + * size represents two separate NVM banks. + */ nvm->flash_bank_size = (sector_end_addr - sector_base_addr) << FLASH_SECTOR_ADDR_SHIFT; nvm->flash_bank_size /= 2; @@ -261,7 +265,7 @@ e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); ret_val = -E1000_ERR_CONFIG; goto out; @@ -293,8 +297,7 @@ out: * Initialize family-specific MAC parameters and function * pointers. **/ -STATIC s32 -e1000_init_mac_params_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; @@ -303,7 +306,7 @@ e1000_init_mac_params_ich8lan(struct e1000_hw *hw) DEBUGFUNC("e1000_init_mac_params_ich8lan"); /* Set media type function pointer */ - hw->media_type = e1000_media_type_copper; + hw->phy.media_type = e1000_media_type_copper; /* Set mta register count */ mac->mta_reg_count = 32; @@ -335,7 +338,7 @@ e1000_init_mac_params_ich8lan(struct e1000_hw *hw) /* link info */ func->get_link_up_info = e1000_get_link_up_info_ich8lan; /* multicast address update */ - func->mc_addr_list_update = e1000_mc_addr_list_update_generic; + func->update_mc_addr_list = e1000_update_mc_addr_list_generic; /* setting MTA */ func->mta_set = e1000_mta_set_generic; /* blink LED */ @@ -374,8 +377,7 @@ out: * * Initialize family-specific function pointers for PHY, MAC, and NVM. **/ -void -e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) +void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_ich8lan"); @@ -392,8 +394,7 @@ e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) * operations. This is a function pointer entry point only called by * read/write routines for the PHY and NVM parts. **/ -STATIC s32 -e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) { u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; @@ -414,6 +415,8 @@ e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) if (!timeout) { DEBUGOUT("FW or HW has locked the resource for too long.\n"); + extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; + E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); ret_val = -E1000_ERR_CONFIG; goto out; } @@ -430,8 +433,7 @@ out: * This is a function pointer entry point only called by read/write * routines for the PHY and NVM parts. **/ -STATIC void -e1000_release_swflag_ich8lan(struct e1000_hw *hw) +STATIC void e1000_release_swflag_ich8lan(struct e1000_hw *hw) { u32 extcnf_ctrl; @@ -452,8 +454,7 @@ e1000_release_swflag_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by read/write * routines for the PHY and NVM parts. **/ -STATIC boolean_t -e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) +STATIC bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) { u32 fwsm; @@ -473,8 +474,7 @@ e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by * reset routines. **/ -STATIC s32 -e1000_check_reset_block_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) { u32 fwsm; @@ -494,13 +494,12 @@ e1000_check_reset_block_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by * PHY setup routines. **/ -STATIC s32 -e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 data; - boolean_t link; + bool link; DEBUGFUNC("e1000_phy_force_speed_duplex_ich8lan"); @@ -535,7 +534,7 @@ e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) usec_delay(1); - if (phy->wait_for_link) { + if (phy->autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n"); ret_val = e1000_phy_has_link_generic(hw, @@ -570,8 +569,7 @@ out: * This is a function pointer entry point called by drivers * or other shared routines. **/ -STATIC s32 -e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; @@ -585,7 +583,8 @@ e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) if (ret_val) goto out; - /* Initialize the PHY from the NVM on ICH platforms. This + /* + * Initialize the PHY from the NVM on ICH platforms. This * is needed due to an issue where the NVM configuration is * not properly autoloaded after power transitions. * Therefore, after each PHY reset, we will load the @@ -610,7 +609,8 @@ e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) usec_delay(100); } while ((!data) && --loop); - /* If basic configuration is incomplete before the above loop + /* + * If basic configuration is incomplete before the above loop * count reaches 0, loading the configuration from NVM will * leave the PHY in a bad state possibly resulting in no link. */ @@ -623,8 +623,10 @@ e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) data &= ~E1000_STATUS_LAN_INIT_DONE; E1000_WRITE_REG(hw, E1000_STATUS, data); - /* Make sure HW does not configure LCD from PHY - * extended configuration before SW configuration */ + /* + * Make sure HW does not configure LCD from PHY + * extended configuration before SW configuration + */ data = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) goto out; @@ -638,8 +640,10 @@ e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; - /* Configure LCD from extended configuration - * region. */ + /* + * Configure LCD from extended configuration + * region. + */ /* cnf_base_addr is in DWORD */ word_addr = (u16)(cnf_base_addr << 1); @@ -687,8 +691,7 @@ out: * This is a function pointer entry point called by drivers * or other shared routines. **/ -STATIC s32 -e1000_get_phy_info_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) { s32 ret_val = -E1000_ERR_PHY_TYPE; @@ -716,13 +719,12 @@ e1000_get_phy_info_ich8lan(struct e1000_hw *hw) * This function is only called by other family-specific * routines. **/ -static s32 -e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) +static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 data; - boolean_t link; + bool link; DEBUGFUNC("e1000_get_phy_info_ife_ich8lan"); @@ -776,8 +778,7 @@ out: * This function is only called by other family-specific * routines. **/ -STATIC s32 -e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -785,7 +786,8 @@ e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) DEBUGFUNC("e1000_check_polarity_ife_ich8lan"); - /* Polarity is determined based on the reversal feature + /* + * Polarity is determined based on the reversal feature * being enabled. */ if (phy->polarity_correction) { @@ -819,8 +821,8 @@ e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by * PHY setup routines. **/ -STATIC s32 -e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active) +STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, + bool active) { struct e1000_phy_info *phy = &hw->phy; u32 phy_ctrl; @@ -829,7 +831,7 @@ e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active) DEBUGFUNC("e1000_set_d0_lplu_state_ich8lan"); - if (phy->type != e1000_phy_igp_3) + if (phy->type == e1000_phy_ife) goto out; phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); @@ -838,8 +840,10 @@ e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active) phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); - /* Call gig speed drop workaround on LPLU before accessing - * any PHY registers */ + /* + * Call gig speed drop workaround on LPLU before accessing + * any PHY registers + */ if ((hw->mac.type == e1000_ich8lan) && (hw->phy.type == e1000_phy_igp_3)) e1000_gig_downshift_workaround_ich8lan(hw); @@ -858,10 +862,12 @@ e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active) phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used + /* + * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. */ + * SmartSpeed, so performance is maintained. + */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -908,8 +914,8 @@ out: * This is a function pointer entry point only called by * PHY setup routines. **/ -STATIC s32 -e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active) +STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, + bool active) { struct e1000_phy_info *phy = &hw->phy; u32 phy_ctrl; @@ -923,10 +929,12 @@ e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active) if (!active) { phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used + /* + * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. */ + * SmartSpeed, so performance is maintained. + */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -960,8 +968,10 @@ e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, boolean_t active) phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); - /* Call gig speed drop workaround on LPLU before accessing - * any PHY registers */ + /* + * Call gig speed drop workaround on LPLU before accessing + * any PHY registers + */ if ((hw->mac.type == e1000_ich8lan) && (hw->phy.type == e1000_phy_igp_3)) e1000_gig_downshift_workaround_ich8lan(hw); @@ -983,6 +993,24 @@ out: return ret_val; } +/** + * e1000_valid_nvm_bank_detect_ich8lan - finds out the valid bank 0 or 1 + * @hw: pointer to the HW structure + * @bank: pointer to the variable that returns the active bank + * + * Reads signature byte from the NVM using the flash access registers. + **/ +STATIC s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) +{ + s32 ret_val = E1000_SUCCESS; + if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL) + *bank = 1; + else + *bank = 0; + + return ret_val; +} + /** * e1000_read_nvm_ich8lan - Read word(s) from the NVM * @hw: pointer to the HW structure @@ -992,20 +1020,21 @@ out: * * Reads a word(s) from the NVM using the flash access registers. **/ -STATIC s32 -e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_dev_spec_ich8lan *dev_spec; u32 act_offset; s32 ret_val = E1000_SUCCESS; + u32 bank = 0; u16 i, word; DEBUGFUNC("e1000_read_nvm_ich8lan"); dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); ret_val = -E1000_ERR_CONFIG; goto out; @@ -1022,15 +1051,16 @@ e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) if (ret_val) goto out; - /* Start with the bank offset, then add the relative offset. */ - act_offset = (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL) - ? nvm->flash_bank_size - : 0; + ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); + if (ret_val != E1000_SUCCESS) + goto out; + + act_offset = (bank) ? nvm->flash_bank_size : 0; act_offset += offset; for (i = 0; i < words; i++) { - if ((dev_spec->shadow_ram != NULL) && - (dev_spec->shadow_ram[offset+i].modified == TRUE)) { + if ((dev_spec->shadow_ram) && + (dev_spec->shadow_ram[offset+i].modified)) { data[i] = dev_spec->shadow_ram[offset+i].value; } else { ret_val = e1000_read_flash_word_ich8lan(hw, @@ -1055,8 +1085,7 @@ out: * This function does initial flash setup so that a new read/write/erase cycle * can be started. **/ -static s32 -e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) +static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) { union ich8_hws_flash_status hsfsts; s32 ret_val = -E1000_ERR_NVM; @@ -1079,7 +1108,8 @@ e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval); - /* Either we should have a hardware SPI cycle in progress + /* + * Either we should have a hardware SPI cycle in progress * bit to check against, in order to start a new cycle or * FDONE bit should be changed in the hardware so that it * is 1 after harware reset, which can then be used as an @@ -1088,15 +1118,19 @@ e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) */ if (hsfsts.hsf_status.flcinprog == 0) { - /* There is no cycle running at present, - * so we can start a cycle */ - /* Begin by setting Flash Cycle Done. */ + /* + * There is no cycle running at present, + * so we can start a cycle. + * Begin by setting Flash Cycle Done. + */ hsfsts.hsf_status.flcdone = 1; E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval); ret_val = E1000_SUCCESS; } else { - /* otherwise poll for sometime so the current - * cycle has a chance to end before giving up. */ + /* + * Otherwise poll for sometime so the current + * cycle has a chance to end before giving up. + */ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); @@ -1107,8 +1141,10 @@ e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) usec_delay(1); } if (ret_val == E1000_SUCCESS) { - /* Successful in waiting for previous cycle to timeout, - * now set the Flash Cycle Done. */ + /* + * Successful in waiting for previous cycle to timeout, + * now set the Flash Cycle Done. + */ hsfsts.hsf_status.flcdone = 1; E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, @@ -1129,8 +1165,7 @@ out: * * This function starts a flash cycle and waits for its completion. **/ -static s32 -e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) +static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) { union ich8_hws_flash_ctrl hsflctl; union ich8_hws_flash_status hsfsts; @@ -1167,14 +1202,14 @@ e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) * Reads the flash word at offset into data. Offset is converted * to bytes before read. **/ -STATIC s32 -e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, u16 *data) +STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, + u16 *data) { s32 ret_val; DEBUGFUNC("e1000_read_flash_word_ich8lan"); - if (data == NULL) { + if (!data) { ret_val = -E1000_ERR_NVM; goto out; } @@ -1197,9 +1232,8 @@ out: * * Reads a byte or word from the NVM using the flash access registers. **/ -static s32 -e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16* data) +static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, + u8 size, u16* data) { union ich8_hws_flash_status hsfsts; union ich8_hws_flash_ctrl hsflctl; @@ -1210,8 +1244,7 @@ e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, DEBUGFUNC("e1000_read_flash_data_ich8lan"); - if (size < 1 || size > 2 || data == 0x0 || - offset > ICH_FLASH_LINEAR_ADDR_MASK) + if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) goto out; flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + @@ -1235,10 +1268,12 @@ e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ret_val = e1000_flash_cycle_ich8lan(hw, ICH_FLASH_READ_COMMAND_TIMEOUT); - /* Check if FCERR is set to 1, if set to 1, clear it + /* + * Check if FCERR is set to 1, if set to 1, clear it * and try the whole sequence a few more times, else * read in (shift in) the Flash Data0, the order is - * least significant byte first msb to lsb */ + * least significant byte first msb to lsb + */ if (ret_val == E1000_SUCCESS) { flash_data = E1000_READ_FLASH_REG(hw, ICH_FLASH_FDATA0); if (size == 1) { @@ -1248,7 +1283,8 @@ e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, } break; } else { - /* If we've gotten here, then things are probably + /* + * If we've gotten here, then things are probably * completely hosed, but if the error condition is * detected, it won't hurt to give it another try... * ICH_FLASH_CYCLE_REPEAT_COUNT times. @@ -1279,8 +1315,8 @@ out: * * Writes a byte or word to the NVM using the flash access registers. **/ -STATIC s32 -e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_dev_spec_ich8lan *dev_spec; @@ -1291,7 +1327,7 @@ e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); ret_val = -E1000_ERR_CONFIG; goto out; @@ -1330,12 +1366,11 @@ out: * After a succesful commit, the shadow ram is cleared and is ready for * future writes. **/ -STATIC s32 -e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_dev_spec_ich8lan *dev_spec; - u32 i, act_offset, new_bank_offset, old_bank_offset; + u32 i, act_offset, new_bank_offset, old_bank_offset, bank; s32 ret_val; u16 data; @@ -1354,10 +1389,16 @@ e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (ret_val) goto out; - /* We're writing to the opposite bank so if we're on bank 1, + /* + * We're writing to the opposite bank so if we're on bank 1, * write to bank 0 etc. We also need to erase the segment that - * is going to be written */ - if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL)) { + * is going to be written + */ + ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); + if (ret_val != E1000_SUCCESS) + goto out; + + if (bank == 0) { new_bank_offset = nvm->flash_bank_size; old_bank_offset = 0; e1000_erase_flash_bank_ich8lan(hw, 1); @@ -1368,10 +1409,12 @@ e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) } for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { - /* Determine whether to write the value stored + /* + * Determine whether to write the value stored * in the other NVM bank or a modified value stored - * in the shadow RAM */ - if (dev_spec->shadow_ram[i].modified == TRUE) { + * in the shadow RAM + */ + if (dev_spec->shadow_ram[i].modified) { data = dev_spec->shadow_ram[i].value; } else { e1000_read_flash_word_ich8lan(hw, @@ -1379,12 +1422,14 @@ e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) &data); } - /* If the word is 0x13, then make sure the signature bits + /* + * If the word is 0x13, then make sure the signature bits * (15:14) are 11b until the commit has completed. * This will allow us to write 10b which indicates the * signature is valid. We want to do this after the write * has completed so that we don't mark the segment valid - * while the write is still in progress */ + * while the write is still in progress + */ if (i == E1000_ICH_NVM_SIG_WORD) data |= E1000_ICH_NVM_SIG_MASK; @@ -1407,18 +1452,22 @@ e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) break; } - /* Don't bother writing the segment valid bits if sector - * programming failed. */ + /* + * Don't bother writing the segment valid bits if sector + * programming failed. + */ if (ret_val) { DEBUGOUT("Flash commit failed.\n"); e1000_release_nvm(hw); goto out; } - /* Finally validate the new segment by setting bit 15:14 + /* + * Finally validate the new segment by setting bit 15:14 * to 10b in word 0x13 , this can be done without an * erase as well since these bits are 11 to start with - * and we need to change bit 14 to 0b */ + * and we need to change bit 14 to 0b + */ act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; e1000_read_flash_word_ich8lan(hw, act_offset, &data); data &= 0xBFFF; @@ -1430,10 +1479,12 @@ e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) goto out; } - /* And invalidate the previously valid segment by setting + /* + * And invalidate the previously valid segment by setting * its signature word (0x13) high_byte to 0b. This can be * done without an erase because flash erase sets all bits - * to 1's. We can write 1's to 0's without an erase */ + * to 1's. We can write 1's to 0's without an erase + */ act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); if (ret_val) { @@ -1449,7 +1500,8 @@ e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) e1000_release_nvm(hw); - /* Reload the EEPROM, or else modifications will not appear + /* + * Reload the EEPROM, or else modifications will not appear * until after the next adapter reset. */ e1000_reload_nvm(hw); @@ -1467,15 +1519,15 @@ out: * If the bit is 0, that the EEPROM had been modified, but the checksum was not * calculated, in which case we need to calculate the checksum and set bit 6. **/ -STATIC s32 -e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 data; DEBUGFUNC("e1000_validate_nvm_checksum_ich8lan"); - /* Read 0x19 and check bit 6. If this bit is 0, the checksum + /* + * Read 0x19 and check bit 6. If this bit is 0, the checksum * needs to be fixed. This bit is an indication that the NVM * was prepared by OEM software and did not calculate the * checksum...a likely scenario. @@ -1509,9 +1561,8 @@ out: * * Writes one/two bytes to the NVM using the flash access registers. **/ -static s32 -e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, - u8 size, u16 data) +static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, + u8 size, u16 data) { union ich8_hws_flash_status hsfsts; union ich8_hws_flash_ctrl hsflctl; @@ -1551,14 +1602,17 @@ e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FDATA0, flash_data); - /* check if FCERR is set to 1 , if set to 1, clear it - * and try the whole sequence a few more times else done */ + /* + * check if FCERR is set to 1 , if set to 1, clear it + * and try the whole sequence a few more times else done + */ ret_val = e1000_flash_cycle_ich8lan(hw, ICH_FLASH_WRITE_COMMAND_TIMEOUT); if (ret_val == E1000_SUCCESS) { break; } else { - /* If we're here, then things are most likely + /* + * If we're here, then things are most likely * completely hosed, but if the error condition * is detected, it won't hurt to give it another * try...ICH_FLASH_CYCLE_REPEAT_COUNT times. @@ -1588,8 +1642,8 @@ out: * * Writes a single byte to the NVM using the flash access registers. **/ -STATIC s32 -e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 data) +STATIC s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, + u8 data) { u16 word = (u16)data; @@ -1607,8 +1661,8 @@ e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 data) * Writes a single byte to the NVM using the flash access registers. * Goes through a retry algorithm before giving up. **/ -static s32 -e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 byte) +static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, + u8 byte) { s32 ret_val; u16 program_retries; @@ -1616,11 +1670,9 @@ e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 byte) DEBUGFUNC("e1000_retry_write_flash_byte_ich8lan"); ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); - if (ret_val) + if (ret_val == E1000_SUCCESS) goto out; - usec_delay(100); - for (program_retries = 0; program_retries < 100; program_retries++) { DEBUGOUT2("Retrying Byte %2.2X at offset %u\n", byte, offset); usec_delay(100); @@ -1645,14 +1697,14 @@ out: * Erases the bank specified. Each bank is a 4k block. Banks are 0 based. * bank N is 4096 * N + flash_reg_addr. **/ -STATIC s32 -e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) +STATIC s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) { struct e1000_nvm_info *nvm = &hw->nvm; union ich8_hws_flash_status hsfsts; union ich8_hws_flash_ctrl hsflctl; u32 flash_linear_addr; - u32 flash_bank_size = nvm->flash_bank_size * 2; /* bank size is in 16bit words - adjust to bytes */ + /* bank size is in 16bit words - adjust to bytes */ + u32 flash_bank_size = nvm->flash_bank_size * 2; s32 ret_val = E1000_SUCCESS; s32 count = 0; s32 j, iteration, sector_size; @@ -1661,9 +1713,10 @@ e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); - /* Determine HW Sector size: Read BERASE bits of hw flash status - * register */ - /* 00: The Hw sector is 256 bytes, hence we need to erase 16 + /* + * Determine HW Sector size: Read BERASE bits of hw flash status + * register + * 00: The Hw sector is 256 bytes, hence we need to erase 16 * consecutive sectors. The start index for the nth Hw sector * can be calculated as = bank * 4096 + n * 256 * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector. @@ -1712,8 +1765,10 @@ e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) if (ret_val) goto out; - /* Write a value 11 (block Erase) in Flash - * Cycle field in hw flash control */ + /* + * Write a value 11 (block Erase) in Flash + * Cycle field in hw flash control + */ hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE; @@ -1721,7 +1776,8 @@ e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) ICH_FLASH_HSFCTL, hsflctl.regval); - /* Write the last 24 bits of an index within the + /* + * Write the last 24 bits of an index within the * block into Flash Linear address field in Flash * Address. */ @@ -1735,14 +1791,18 @@ e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) if (ret_val == E1000_SUCCESS) { break; } else { - /* Check if FCERR is set to 1. If 1, + /* + * Check if FCERR is set to 1. If 1, * clear it and try the whole sequence - * a few more times else Done */ + * a few more times else Done + */ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcerr == 1) { - /* repeat for some time before - * giving up */ + /* + * repeat for some time before + * giving up + */ continue; } else if (hsfsts.hsf_status.flcdone == 0) goto out; @@ -1763,8 +1823,7 @@ out: * settings is all 0's or F's, set the LED default to a valid LED default * setting. **/ -STATIC s32 -e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) +STATIC s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) { s32 ret_val; @@ -1791,8 +1850,7 @@ out: * ICH8 use the PCI Express bus, but does not contain a PCI Express Capability * register, so the the bus width is hard coded. **/ -STATIC s32 -e1000_get_bus_info_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) { struct e1000_bus_info *bus = &hw->bus; s32 ret_val; @@ -1801,7 +1859,8 @@ e1000_get_bus_info_ich8lan(struct e1000_hw *hw) ret_val = e1000_get_bus_info_pcie_generic(hw); - /* ICH devices are "PCI Express"-ish. They have + /* + * ICH devices are "PCI Express"-ish. They have * a configuration space, but do not contain * PCI Express Capability registers, so bus width * must be hardcoded. @@ -1819,15 +1878,15 @@ e1000_get_bus_info_ich8lan(struct e1000_hw *hw) * Does a full reset of the hardware which includes a reset of the PHY and * MAC. **/ -STATIC s32 -e1000_reset_hw_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) { u32 ctrl, icr, kab; s32 ret_val; DEBUGFUNC("e1000_reset_hw_ich8lan"); - /* Prevent the PCI-E bus from sticking if there is no TLP connection + /* + * Prevent the PCI-E bus from sticking if there is no TLP connection * on the last TLP read/write transaction when MAC is reset. */ ret_val = e1000_disable_pcie_master_generic(hw); @@ -1838,7 +1897,8 @@ e1000_reset_hw_ich8lan(struct e1000_hw *hw) DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); - /* Disable the Transmit and Receive units. Then delay to allow + /* + * Disable the Transmit and Receive units. Then delay to allow * any pending transactions to complete before we hit the MAC * with the global reset. */ @@ -1859,7 +1919,8 @@ e1000_reset_hw_ich8lan(struct e1000_hw *hw) ctrl = E1000_READ_REG(hw, E1000_CTRL); if (!e1000_check_reset_block(hw) && !hw->phy.reset_disable) { - /* PHY HW reset requires MAC CORE reset at the same + /* + * PHY HW reset requires MAC CORE reset at the same * time to make sure the interface between MAC and the * external PHY is reset. */ @@ -1902,8 +1963,7 @@ e1000_reset_hw_ich8lan(struct e1000_hw *hw) * - setup transmit discriptors * - clear statistics **/ -STATIC s32 -e1000_init_hw_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 ctrl_ext, txdctl, snoop; @@ -1918,7 +1978,7 @@ e1000_init_hw_ich8lan(struct e1000_hw *hw) ret_val = e1000_id_led_init_generic(hw); if (ret_val) { DEBUGOUT("Error initializing identification LED\n"); - goto out; + /* This is not fatal and we should not stop init due to this */ } /* Setup the receive address. */ @@ -1933,21 +1993,23 @@ e1000_init_hw_ich8lan(struct e1000_hw *hw) ret_val = e1000_setup_link(hw); /* Set the transmit descriptor write-back policy for both queues */ - txdctl = E1000_READ_REG(hw, E1000_TXDCTL); + txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | E1000_TXDCTL_MAX_TX_DESC_PREFETCH; - E1000_WRITE_REG(hw, E1000_TXDCTL, txdctl); - txdctl = E1000_READ_REG(hw, E1000_TXDCTL1); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); + txdctl = E1000_READ_REG(hw, E1000_TXDCTL(1)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | E1000_TXDCTL_MAX_TX_DESC_PREFETCH; - E1000_WRITE_REG(hw, E1000_TXDCTL1, txdctl); + E1000_WRITE_REG(hw, E1000_TXDCTL(1), txdctl); - /* ICH8 has opposite polarity of no_snoop bits. - * By default, we should use snoop behavior. */ + /* + * ICH8 has opposite polarity of no_snoop bits. + * By default, we should use snoop behavior. + */ if (mac->type == e1000_ich8lan) snoop = PCIE_ICH8_SNOOP_ALL; else @@ -1958,14 +2020,14 @@ e1000_init_hw_ich8lan(struct e1000_hw *hw) ctrl_ext |= E1000_CTRL_EXT_RO_DIS; E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); - /* Clear all of the statistics registers (clear on read). It is + /* + * Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there * is no link. */ e1000_clear_hw_cntrs_ich8lan(hw); -out: return ret_val; } /** @@ -1975,8 +2037,7 @@ out: * Sets/Clears required hardware bits necessary for correctly setting up the * hardware for transmit and receive. **/ -static void -e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) +static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) { u32 reg; @@ -1991,30 +2052,30 @@ e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); /* Transmit Descriptor Control 0 */ - reg = E1000_READ_REG(hw, E1000_TXDCTL); + reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); reg |= (1 << 22); - E1000_WRITE_REG(hw, E1000_TXDCTL, reg); + E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); /* Transmit Descriptor Control 1 */ - reg = E1000_READ_REG(hw, E1000_TXDCTL1); + reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); reg |= (1 << 22); - E1000_WRITE_REG(hw, E1000_TXDCTL1, reg); + E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); /* Transmit Arbitration Control 0 */ - reg = E1000_READ_REG(hw, E1000_TARC0); + reg = E1000_READ_REG(hw, E1000_TARC(0)); if (hw->mac.type == e1000_ich8lan) reg |= (1 << 28) | (1 << 29); reg |= (1 << 23) | (1 << 24) | (1 << 26) | (1 << 27); - E1000_WRITE_REG(hw, E1000_TARC0, reg); + E1000_WRITE_REG(hw, E1000_TARC(0), reg); /* Transmit Arbitration Control 1 */ - reg = E1000_READ_REG(hw, E1000_TARC1); + reg = E1000_READ_REG(hw, E1000_TARC(1)); if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) reg &= ~(1 << 28); else reg |= (1 << 28); reg |= (1 << 24) | (1 << 26) | (1 << 30); - E1000_WRITE_REG(hw, E1000_TARC1, reg); + E1000_WRITE_REG(hw, E1000_TARC(1), reg); /* Device Status */ if (hw->mac.type == e1000_ich8lan) { @@ -2037,10 +2098,8 @@ out: * should be established. Assumes the hardware has previously been reset * and the transmitter and receiver are not enabled. **/ -STATIC s32 -e1000_setup_link_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) { - struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; @@ -2049,23 +2108,24 @@ e1000_setup_link_ich8lan(struct e1000_hw *hw) if (e1000_check_reset_block(hw)) goto out; - /* ICH parts do not have a word in the NVM to determine + /* + * ICH parts do not have a word in the NVM to determine * the default flow control setting, so we explicitly * set it to full. */ - if (mac->fc == e1000_fc_default) - mac->fc = e1000_fc_full; + if (hw->fc.type == e1000_fc_default) + hw->fc.type = e1000_fc_full; - mac->original_fc = mac->fc; + hw->fc.original_type = hw->fc.type; - DEBUGOUT1("After fix-ups FlowControl is now = %x\n", mac->fc); + DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); /* Continue to configure the copper link. */ ret_val = func->setup_physical_interface(hw); if (ret_val) goto out; - E1000_WRITE_REG(hw, E1000_FCTTV, mac->fc_pause_time); + E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); ret_val = e1000_set_fc_watermarks_generic(hw); @@ -2081,8 +2141,7 @@ out: * when polling the PHY, then call the generic setup_copper_link to finish * configuring the copper link. **/ -STATIC s32 -e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -2095,9 +2154,11 @@ e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - /* Set the mac to wait the maximum time between each iteration + /* + * Set the mac to wait the maximum time between each iteration * and increase the max iterations when polling the phy; - * this fixes erroneous timeouts at 10Mbps. */ + * this fixes erroneous timeouts at 10Mbps. + */ ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF); if (ret_val) goto out; @@ -2115,6 +2176,29 @@ e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) goto out; } + if (hw->phy.type == e1000_phy_ife) { + ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, ®_data); + if (ret_val) + goto out; + + reg_data &= ~IFE_PMC_AUTO_MDIX; + + switch (hw->phy.mdix) { + case 1: + reg_data &= ~IFE_PMC_FORCE_MDIX; + break; + case 2: + reg_data |= IFE_PMC_FORCE_MDIX; + break; + case 0: + default: + reg_data |= IFE_PMC_AUTO_MDIX; + break; + } + ret_val = e1000_write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, reg_data); + if (ret_val) + goto out; + } ret_val = e1000_setup_copper_link_generic(hw); out: @@ -2131,8 +2215,8 @@ out: * information and then calls the Kumeran lock loss workaround for links at * gigabit speeds. **/ -STATIC s32 -e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, u16 *duplex) +STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, + u16 *duplex) { s32 ret_val; @@ -2167,31 +2251,32 @@ out: * 5) repeat up to 10 times * Note: this is only called for IGP3 copper when speed is 1gb. **/ -static s32 -e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) +static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) { struct e1000_dev_spec_ich8lan *dev_spec; u32 phy_ctrl; s32 ret_val = E1000_SUCCESS; u16 i, data; - boolean_t link; + bool link; DEBUGFUNC("e1000_kmrn_lock_loss_workaround_ich8lan"); dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); ret_val = -E1000_ERR_CONFIG; goto out; } - if (dev_spec->kmrn_lock_loss_workaround_enabled == FALSE) + if (!(dev_spec->kmrn_lock_loss_workaround_enabled)) goto out; - /* Make sure link is up before proceeding. If not just return. + /* + * Make sure link is up before proceeding. If not just return. * Attempting this while link is negotiating fouled up link - * stability */ + * stability + */ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); if (!link) { ret_val = E1000_SUCCESS; @@ -2224,8 +2309,10 @@ e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_NOND0A_GBE_DISABLE); E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); - /* Call gig speed drop workaround on Giga disable before accessing - * any PHY registers */ + /* + * Call gig speed drop workaround on Giga disable before accessing + * any PHY registers + */ e1000_gig_downshift_workaround_ich8lan(hw); /* unable to acquire PCS lock */ @@ -2243,9 +2330,8 @@ out: * If ICH8, set the current Kumeran workaround state (enabled - TRUE * /disabled - FALSE). **/ -void -e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, - boolean_t state) +void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, + bool state) { struct e1000_dev_spec_ich8lan *dev_spec; @@ -2258,7 +2344,7 @@ e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; - if (dev_spec == NULL) { + if (!dev_spec) { DEBUGOUT("dev_spec pointer is set to NULL.\n"); goto out; } @@ -2279,8 +2365,7 @@ out: * 3) read it back * Continue if successful, else issue LCD reset and repeat **/ -void -e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) +void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) { u32 reg; u16 data; @@ -2299,8 +2384,10 @@ e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) E1000_PHY_CTRL_NOND0A_GBE_DISABLE); E1000_WRITE_REG(hw, E1000_PHY_CTRL, reg); - /* Call gig speed drop workaround on Giga disable before - * accessing any PHY registers */ + /* + * Call gig speed drop workaround on Giga disable before + * accessing any PHY registers + */ if (hw->mac.type == e1000_ich8lan) e1000_gig_downshift_workaround_ich8lan(hw); @@ -2337,8 +2424,7 @@ out: * 2) Clear Kumeran Near-end loopback * Should only be called for ICH8[m] devices with IGP_3 Phy. **/ -void -e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) +void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 reg_data; @@ -2371,8 +2457,7 @@ out: * * Return the LED back to the default configuration. **/ -STATIC s32 -e1000_cleanup_led_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; @@ -2394,8 +2479,7 @@ e1000_cleanup_led_ich8lan(struct e1000_hw *hw) * * Turn on the LED's. **/ -STATIC s32 -e1000_led_on_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; @@ -2417,8 +2501,7 @@ e1000_led_on_ich8lan(struct e1000_hw *hw) * * Turn off the LED's. **/ -STATIC s32 -e1000_led_off_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; @@ -2444,9 +2527,10 @@ e1000_led_off_ich8lan(struct e1000_hw *hw) * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon * would not be able to be reset or change link. **/ -STATIC s32 -e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) +STATIC s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) { + s32 ret_val = E1000_SUCCESS; + e1000_get_cfg_done_generic(hw); /* If EEPROM is not marked present, init the IGP 3 PHY manually */ @@ -2455,7 +2539,23 @@ e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) e1000_phy_init_script_igp3(hw); } - return E1000_SUCCESS; + return ret_val; +} + +/** + * e1000_power_down_phy_copper_ich8lan - Remove link during PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, remove the link. + **/ +STATIC void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) +{ + /* If the management interface is not enabled, then power down */ + if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw))) + e1000_power_down_phy_copper(hw); + + return; } /** @@ -2465,8 +2565,7 @@ e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) * Clears hardware counters specific to the silicon family and calls * clear_hw_cntrs_generic to clear all general purpose counters. **/ -STATIC void -e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) +STATIC void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_ich8lan.h b/sys/dev/em/e1000_ich8lan.h index 95f0d5564a52..2d9e8d34509a 100644 --- a/sys/dev/em/e1000_ich8lan.h +++ b/sys/dev/em/e1000_ich8lan.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_ICH8LAN_H_ @@ -67,9 +67,8 @@ #define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ #define E1000_ICH_FWSM_DISSW 0x10000000 /* FW Disables SW Writes */ -#define E1000_ICH_FWSM_FW_VALID 0x00008000 /* FW established a valid - * mode. - */ +/* FW established a valid mode */ +#define E1000_ICH_FWSM_FW_VALID 0x00008000 #define E1000_ICH_MNG_IAMT_MODE 0x2 @@ -103,13 +102,16 @@ #define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 #define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020 -/* Additional interrupts need to be handled for ICH family: - DSW = The FW changed the status of the DISSW bit in FWSM - PHYINT = The LAN connected device generates an interrupt - EPRST = Manageability reset event */ +/* + * Additional interrupts need to be handled for ICH family: + * DSW = The FW changed the status of the DISSW bit in FWSM + * PHYINT = The LAN connected device generates an interrupt + * EPRST = Manageability reset event + */ #define IMS_ICH_ENABLE_MASK (\ E1000_IMS_DSW | \ E1000_IMS_PHYINT | \ E1000_IMS_EPRST) + #endif diff --git a/sys/dev/em/e1000_mac.c b/sys/dev/em/e1000_mac.c index 399a2c10a078..400d30e8dd5a 100644 --- a/sys/dev/em/e1000_mac.c +++ b/sys/dev/em/e1000_mac.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #include "e1000_api.h" @@ -43,8 +43,7 @@ * If a device specific structure was allocated, this function will * free it. **/ -void -e1000_remove_device_generic(struct e1000_hw *hw) +void e1000_remove_device_generic(struct e1000_hw *hw) { DEBUGFUNC("e1000_remove_device_generic"); @@ -60,8 +59,7 @@ e1000_remove_device_generic(struct e1000_hw *hw) * network interface. The following bus information is determined and stored: * bus speed, bus width, type (PCI/PCIx), and PCI(-x) function. **/ -s32 -e1000_get_bus_info_pci_generic(struct e1000_hw *hw) +s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw) { struct e1000_bus_info *bus = &hw->bus; u32 status = E1000_READ_REG(hw, E1000_STATUS); @@ -121,8 +119,7 @@ e1000_get_bus_info_pci_generic(struct e1000_hw *hw) * network interface. The following bus information is determined and stored: * bus speed, bus width, type (PCIe), and PCIe function. **/ -s32 -e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) +s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) { struct e1000_bus_info *bus = &hw->bus; s32 ret_val; @@ -149,8 +146,9 @@ e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) status = E1000_READ_REG(hw, E1000_STATUS); bus->func = (status & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; - } else + } else { bus->func = 0; + } return E1000_SUCCESS; } @@ -162,8 +160,7 @@ e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) * Clears the register array which contains the VLAN filter table by * setting all the values to 0. **/ -void -e1000_clear_vfta_generic(struct e1000_hw *hw) +void e1000_clear_vfta_generic(struct e1000_hw *hw) { u32 offset; @@ -184,8 +181,7 @@ e1000_clear_vfta_generic(struct e1000_hw *hw) * Writes value at the given offset in the register array which stores * the VLAN filter table. **/ -void -e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) +void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) { DEBUGFUNC("e1000_write_vfta_generic"); @@ -202,8 +198,7 @@ e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) * register to the devices MAC address and clearing all the other receive * address registers to 0. **/ -void -e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) +void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) { u32 i; @@ -224,6 +219,67 @@ e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) } } +/** + * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr + * @hw: pointer to the HW structure + * + * Checks the nvm for an alternate MAC address. An alternate MAC address + * can be setup by pre-boot software and must be treated like a permanent + * address and must override the actual permanent MAC address. If an + * alternate MAC address is found it is saved in the hw struct and + * programmed into RAR0 and the function returns success, otherwise the + * function returns an error. + **/ +s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) +{ + u32 i; + s32 ret_val = E1000_SUCCESS; + u16 offset, nvm_alt_mac_addr_offset, nvm_data; + u8 alt_mac_addr[ETH_ADDR_LEN]; + + DEBUGFUNC("e1000_check_alt_mac_addr_generic"); + + ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, &nvm_alt_mac_addr_offset); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + goto out; + } + + if (nvm_alt_mac_addr_offset == 0xFFFF) { + ret_val = -(E1000_NOT_IMPLEMENTED); + goto out; + } + + if (hw->bus.func == E1000_FUNC_1) + nvm_alt_mac_addr_offset += ETH_ADDR_LEN/sizeof(u16); + + for (i = 0; i < ETH_ADDR_LEN; i += 2) { + offset = nvm_alt_mac_addr_offset + (i >> 1); + ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); + if (ret_val) { + DEBUGOUT("NVM Read Error\n"); + goto out; + } + + alt_mac_addr[i] = (u8)(nvm_data & 0xFF); + alt_mac_addr[i + 1] = (u8)(nvm_data >> 8); + } + + /* if multicast bit is set, the alternate address will not be used */ + if (alt_mac_addr[0] & 0x01) { + ret_val = -(E1000_NOT_IMPLEMENTED); + goto out; + } + + for (i = 0; i < ETH_ADDR_LEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i]; + + e1000_rar_set(hw, hw->mac.perm_addr, 0); + +out: + return ret_val; +} + /** * e1000_rar_set_generic - Set receive address register * @hw: pointer to the HW structure @@ -233,14 +289,14 @@ e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) * Sets the receive address array register at index to the address passed * in by addr. **/ -void -e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) +void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) { u32 rar_low, rar_high; DEBUGFUNC("e1000_rar_set_generic"); - /* HW expects these in little endian so we reverse the byte order + /* + * HW expects these in little endian so we reverse the byte order * from network order (big endian) to little endian */ rar_low = ((u32) addr[0] | @@ -249,8 +305,11 @@ e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); - if (!hw->mac.disable_av) - rar_high |= E1000_RAH_AV; + /* If MAC address zero, no need to set the AV bit */ + if (rar_low || rar_high) { + if (!hw->mac.disable_av) + rar_high |= E1000_RAH_AV; + } E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); @@ -266,13 +325,13 @@ e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) * current value is read, the new bit is OR'd in and the new value is * written back into the register. **/ -void -e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value) +void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value) { u32 hash_bit, hash_reg, mta; DEBUGFUNC("e1000_mta_set_generic"); - /* The MTA is a register array of 32-bit registers. It is + /* + * The MTA is a register array of 32-bit registers. It is * treated like an array of (32*mta_reg_count) bits. We want to * set bit BitArray[hash_value]. So we figure out what register * the bit is in, read it, OR in the new bit, then write @@ -293,7 +352,7 @@ e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value) } /** - * e1000_mc_addr_list_update_generic - Update Multicast addresses + * e1000_update_mc_addr_list_generic - Update Multicast addresses * @hw: pointer to the HW structure * @mc_addr_list: array of multicast addresses to program * @mc_addr_count: number of multicast addresses to program @@ -305,17 +364,17 @@ e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value) * The parameter rar_count will usually be hw->mac.rar_entry_count * unless there are workarounds that change this. **/ -void -e1000_mc_addr_list_update_generic(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count, - u32 rar_used_count, u32 rar_count) +void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count, + u32 rar_used_count, u32 rar_count) { u32 hash_value; u32 i; - DEBUGFUNC("e1000_mc_addr_list_update_generic"); + DEBUGFUNC("e1000_update_mc_addr_list_generic"); - /* Load the first set of multicast addresses into the exact + /* + * Load the first set of multicast addresses into the exact * filters (RAR). If there are not enough to fill the RAR * array, clear the filters. */ @@ -357,8 +416,7 @@ e1000_mc_addr_list_update_generic(struct e1000_hw *hw, * the multicast filter table array address and new table value. See * e1000_mta_set_generic() **/ -u32 -e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) +u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) { u32 hash_value, hash_mask; u8 bit_shift = 0; @@ -368,12 +426,15 @@ e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) /* Register count multiplied by bits per register */ hash_mask = (hw->mac.mta_reg_count * 32) - 1; - /* For a mc_filter_type of 0, bit_shift is the number of left-shifts - * where 0xFF would still fall within the hash mask. */ + /* + * For a mc_filter_type of 0, bit_shift is the number of left-shifts + * where 0xFF would still fall within the hash mask. + */ while (hash_mask >> bit_shift != 0xFF) bit_shift++; - /* The portion of the address that is used for the hash table + /* + * The portion of the address that is used for the hash table * is determined by the mc_filter_type setting. * The algorithm is such that there is a total of 8 bits of shifting. * The bit_shift for a mc_filter_type of 0 represents the number of @@ -384,8 +445,8 @@ e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) * cases are a variation of this algorithm...essentially raising the * number of bits to shift mc_addr[5] left, while still keeping the * 8-bit shifting total. - */ - /* For example, given the following Destination MAC Address and an + * + * For example, given the following Destination MAC Address and an * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask), * we can see that the bit_shift for case 0 is 4. These are the hash * values resulting from each mc_filter_type... @@ -428,8 +489,7 @@ e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) * value. We check the PCIx command regsiter with the current PCIx status * regsiter. **/ -void -e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw) +void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw) { u16 cmd_mmrbc; u16 pcix_cmd; @@ -463,8 +523,7 @@ e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw) * * Clears the base hardware counters by reading the counter registers. **/ -void -e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw) +void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw) { volatile u32 temp; @@ -517,16 +576,16 @@ e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw) * change in link status has been detected, then we read the PHY registers * to get the current speed/duplex if link exists. **/ -s32 -e1000_check_for_copper_link_generic(struct e1000_hw *hw) +s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; - boolean_t link; + bool link; DEBUGFUNC("e1000_check_for_copper_link"); - /* We only want to go out to the PHY registers to see if Auto-Neg + /* + * We only want to go out to the PHY registers to see if Auto-Neg * has completed and/or if our link status has changed. The * get_link_status flag is set upon receiving a Link Status * Change or Rx Sequence Error interrupt. @@ -536,7 +595,8 @@ e1000_check_for_copper_link_generic(struct e1000_hw *hw) goto out; } - /* First we want to see if the MII Status Register reports + /* + * First we want to see if the MII Status Register reports * link. If so, then we want to get the current speed/duplex * of the PHY. */ @@ -549,11 +609,14 @@ e1000_check_for_copper_link_generic(struct e1000_hw *hw) mac->get_link_status = FALSE; - /* Check if there was DownShift, must be checked - * immediately after link-up */ + /* + * Check if there was DownShift, must be checked + * immediately after link-up + */ e1000_check_downshift_generic(hw); - /* If we are forcing speed/duplex, then we simply return since + /* + * If we are forcing speed/duplex, then we simply return since * we have already determined whether we have link or not. */ if (!mac->autoneg) { @@ -561,13 +624,15 @@ e1000_check_for_copper_link_generic(struct e1000_hw *hw) goto out; } - /* Auto-Neg is enabled. Auto Speed Detection takes care + /* + * Auto-Neg is enabled. Auto Speed Detection takes care * of MAC speed/duplex configuration. So we only need to * configure Collision Distance in the MAC. */ e1000_config_collision_dist_generic(hw); - /* Configure Flow Control now that Auto-Neg has completed. + /* + * Configure Flow Control now that Auto-Neg has completed. * First, we need to restore the desired flow control * settings because we may have had to re-autoneg with a * different link partner. @@ -588,8 +653,7 @@ out: * Checks for link up on the hardware. If link is not up and we have * a signal, then we need to force link up. **/ -s32 -e1000_check_for_fiber_link_generic(struct e1000_hw *hw) +s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 rxcw; @@ -603,7 +667,8 @@ e1000_check_for_fiber_link_generic(struct e1000_hw *hw) status = E1000_READ_REG(hw, E1000_STATUS); rxcw = E1000_READ_REG(hw, E1000_RXCW); - /* If we don't have link (auto-negotiation failed or link partner + /* + * If we don't have link (auto-negotiation failed or link partner * cannot auto-negotiate), the cable is plugged in (we have signal), * and our link partner is not trying to auto-negotiate with us (we * are receiving idles or data), we need to force link up. We also @@ -634,7 +699,8 @@ e1000_check_for_fiber_link_generic(struct e1000_hw *hw) goto out; } } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - /* If we are forcing link and we are receiving /C/ ordered + /* + * If we are forcing link and we are receiving /C/ ordered * sets, re-enable auto-negotiation in the TXCW register * and disable forced link in the Device Control register * in an attempt to auto-negotiate with our link partner. @@ -657,8 +723,7 @@ out: * Checks for link up on the hardware. If link is not up and we have * a signal, then we need to force link up. **/ -s32 -e1000_check_for_serdes_link_generic(struct e1000_hw *hw) +s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 rxcw; @@ -672,7 +737,8 @@ e1000_check_for_serdes_link_generic(struct e1000_hw *hw) status = E1000_READ_REG(hw, E1000_STATUS); rxcw = E1000_READ_REG(hw, E1000_RXCW); - /* If we don't have link (auto-negotiation failed or link partner + /* + * If we don't have link (auto-negotiation failed or link partner * cannot auto-negotiate), and our link partner is not trying to * auto-negotiate with us (we are receiving idles or data), * we need to force link up. We also need to give auto-negotiation @@ -701,7 +767,8 @@ e1000_check_for_serdes_link_generic(struct e1000_hw *hw) goto out; } } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - /* If we are forcing link and we are receiving /C/ ordered + /* + * If we are forcing link and we are receiving /C/ ordered * sets, re-enable auto-negotiation in the TXCW register * and disable forced link in the Device Control register * in an attempt to auto-negotiate with our link partner. @@ -712,7 +779,8 @@ e1000_check_for_serdes_link_generic(struct e1000_hw *hw) mac->serdes_has_link = TRUE; } else if (!(E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW))) { - /* If we force link for non-auto-negotiation switch, check + /* + * If we force link for non-auto-negotiation switch, check * link status based on MAC synchronization for internal * serdes media type. */ @@ -750,39 +818,46 @@ out: * should be established. Assumes the hardware has previously been reset * and the transmitter and receiver are not enabled. **/ -s32 -e1000_setup_link_generic(struct e1000_hw *hw) +s32 e1000_setup_link_generic(struct e1000_hw *hw) { - struct e1000_mac_info *mac = &hw->mac; struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_setup_link_generic"); - /* In the case of the phy reset being blocked, we already have a link. + /* + * In the case of the phy reset being blocked, we already have a link. * We do not need to set it up again. */ if (e1000_check_reset_block(hw)) goto out; - ret_val = e1000_set_default_fc_generic(hw); - if (ret_val) - goto out; + /* + * If flow control is set to default, set flow control based on + * the EEPROM flow control settings. + */ + if (hw->fc.type == e1000_fc_default) { + ret_val = e1000_set_default_fc_generic(hw); + if (ret_val) + goto out; + } - /* We want to save off the original Flow Control configuration just + /* + * We want to save off the original Flow Control configuration just * in case we get disconnected and then reconnected into a different * hub or switch with different Flow Control capabilities. */ - mac->original_fc = mac->fc; + hw->fc.original_type = hw->fc.type; - DEBUGOUT1("After fix-ups FlowControl is now = %x\n", mac->fc); + DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); /* Call the necessary media_type subroutine to configure the link. */ ret_val = func->setup_physical_interface(hw); if (ret_val) goto out; - /* Initialize the flow control address, type, and PAUSE timer + /* + * Initialize the flow control address, type, and PAUSE timer * registers to their default values. This is done even if flow * control is disabled, because it does not hurt anything to * initialize these registers. @@ -792,7 +867,7 @@ e1000_setup_link_generic(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH); E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW); - E1000_WRITE_REG(hw, E1000_FCTTV, mac->fc_pause_time); + E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); ret_val = e1000_set_fc_watermarks_generic(hw); @@ -807,8 +882,7 @@ out: * Configures collision distance and flow control for fiber and serdes * links. Upon successful setup, poll for link. **/ -s32 -e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) +s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) { u32 ctrl; s32 ret_val = E1000_SUCCESS; @@ -826,7 +900,8 @@ e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) if (ret_val) goto out; - /* Since auto-negotiation is enabled, take the link out of reset (the + /* + * Since auto-negotiation is enabled, take the link out of reset (the * link will be in reset, because we previously reset the chip). This * will restart auto-negotiation. If auto-negotiation is successful * then the link-up status bit will be set and the flow control enable @@ -838,11 +913,12 @@ e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); msec_delay(1); - /* For these adapters, the SW defineable pin 1 is set when the optics + /* + * For these adapters, the SW defineable pin 1 is set when the optics * detect a signal. If we have a signal, then poll for a "Link-Up" * indication. */ - if (hw->media_type == e1000_media_type_internal_serdes || + if (hw->phy.media_type == e1000_media_type_internal_serdes || (E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1)) { ret_val = e1000_poll_fiber_serdes_link_generic(hw); } else { @@ -861,8 +937,7 @@ out: * during link setup. Currently no func pointer exists and all * implementations are handled in the generic version of this function. **/ -void -e1000_config_collision_dist_generic(struct e1000_hw *hw) +void e1000_config_collision_dist_generic(struct e1000_hw *hw) { u32 tctl; @@ -884,8 +959,7 @@ e1000_config_collision_dist_generic(struct e1000_hw *hw) * Polls for link up by reading the status register, if link fails to come * up with auto-negotiation, then the link is forced if a signal is detected. **/ -s32 -e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) +s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 i, status; @@ -893,7 +967,8 @@ e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_poll_fiber_serdes_link_generic"); - /* If we have a signal (the cable is plugged in, or assumed true for + /* + * If we have a signal (the cable is plugged in, or assumed true for * serdes media) then poll for a "Link-Up" indication in the Device * Status Register. Time-out if a link isn't seen in 500 milliseconds * seconds (Auto-negotiation should complete in less than 500 @@ -908,7 +983,8 @@ e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) if (i == FIBER_LINK_UP_LIMIT) { DEBUGOUT("Never got a valid link from auto-neg!!!\n"); mac->autoneg_failed = 1; - /* AutoNeg failed to achieve a link, so we'll call + /* + * AutoNeg failed to achieve a link, so we'll call * mac->check_for_link. This routine will force the * link up if we detect a signal. This will allow us to * communicate with non-autonegotiating link partners. @@ -935,8 +1011,7 @@ out: * Write the flow control settings to the Transmit Config Word Register (TXCW) * base on the flow control settings in e1000_mac_info. **/ -s32 -e1000_commit_fc_settings_generic(struct e1000_hw *hw) +s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 txcw; @@ -944,7 +1019,8 @@ e1000_commit_fc_settings_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_commit_fc_settings_generic"); - /* Check for a software override of the flow control settings, and + /* + * Check for a software override of the flow control settings, and * setup the device accordingly. If auto-negotiation is enabled, then * software will have to set the "PAUSE" bits to the correct value in * the Transmit Config Word Register (TXCW) and re-start auto- @@ -958,17 +1034,18 @@ e1000_commit_fc_settings_generic(struct e1000_hw *hw) * but not send pause frames). * 2: Tx flow control is enabled (we can send pause frames but we * do not support receiving pause frames). - * 3: Both Rx and TX flow control (symmetric) are enabled. + * 3: Both Rx and Tx flow control (symmetric) are enabled. */ - switch (mac->fc) { + switch (hw->fc.type) { case e1000_fc_none: /* Flow control completely disabled by a software over-ride. */ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); break; case e1000_fc_rx_pause: - /* RX Flow control is enabled and TX Flow control is disabled + /* + * Rx Flow control is enabled and Tx Flow control is disabled * by a software over-ride. Since there really isn't a way to - * advertise that we are capable of RX Pause ONLY, we will + * advertise that we are capable of Rx Pause ONLY, we will * advertise that we support both symmetric and asymmetric RX * PAUSE. Later, we will disable the adapter's ability to send * PAUSE frames. @@ -976,13 +1053,15 @@ e1000_commit_fc_settings_generic(struct e1000_hw *hw) txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); break; case e1000_fc_tx_pause: - /* TX Flow control is enabled, and RX Flow control is disabled, + /* + * Tx Flow control is enabled, and Rx Flow control is disabled, * by a software over-ride. */ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); break; case e1000_fc_full: - /* Flow control (both RX and TX) is enabled by a software + /* + * Flow control (both Rx and Tx) is enabled by a software * over-ride. */ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); @@ -1009,31 +1088,31 @@ out: * flow control XON frame transmission is enabled, then set XON frame * tansmission as well. **/ -s32 -e1000_set_fc_watermarks_generic(struct e1000_hw *hw) +s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw) { - struct e1000_mac_info *mac = &hw->mac; s32 ret_val = E1000_SUCCESS; u32 fcrtl = 0, fcrth = 0; DEBUGFUNC("e1000_set_fc_watermarks_generic"); - /* Set the flow control receive threshold registers. Normally, + /* + * Set the flow control receive threshold registers. Normally, * these registers will be set to a default threshold that may be * adjusted later by the driver's runtime code. However, if the * ability to transmit pause frames is not enabled, then these * registers will be set to 0. */ - if (mac->fc & e1000_fc_tx_pause) { - /* We need to set up the Receive Threshold high and low water + if (hw->fc.type & e1000_fc_tx_pause) { + /* + * We need to set up the Receive Threshold high and low water * marks as well as (optionally) enabling the transmission of * XON frames. */ - fcrtl = mac->fc_low_water; - if (mac->fc_send_xon) + fcrtl = hw->fc.low_water; + if (hw->fc.send_xon) fcrtl |= E1000_FCRTL_XONE; - fcrth = mac->fc_high_water; + fcrth = hw->fc.high_water; } E1000_WRITE_REG(hw, E1000_FCRTL, fcrtl); E1000_WRITE_REG(hw, E1000_FCRTH, fcrth); @@ -1048,19 +1127,15 @@ e1000_set_fc_watermarks_generic(struct e1000_hw *hw) * Read the EEPROM for the default values for flow control and store the * values. **/ -s32 -e1000_set_default_fc_generic(struct e1000_hw *hw) +s32 e1000_set_default_fc_generic(struct e1000_hw *hw) { - struct e1000_mac_info *mac = &hw->mac; s32 ret_val = E1000_SUCCESS; u16 nvm_data; DEBUGFUNC("e1000_set_default_fc_generic"); - if (mac->fc != e1000_fc_default) - goto out; - - /* Read and store word 0x0F of the EEPROM. This word contains bits + /* + * Read and store word 0x0F of the EEPROM. This word contains bits * that determine the hardware's default PAUSE (flow control) mode, * a bit that determines whether the HW defaults to enabling or * disabling auto-negotiation, and the direction of the @@ -1076,12 +1151,12 @@ e1000_set_default_fc_generic(struct e1000_hw *hw) } if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) - mac->fc = e1000_fc_none; + hw->fc.type = e1000_fc_none; else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == NVM_WORD0F_ASM_DIR) - mac->fc = e1000_fc_tx_pause; + hw->fc.type = e1000_fc_tx_pause; else - mac->fc = e1000_fc_full; + hw->fc.type = e1000_fc_full; out: return ret_val; @@ -1097,10 +1172,8 @@ out: * autonegotiation is managed by the PHY rather than the MAC. Software must * also configure these bits when link is forced on a fiber connection. **/ -s32 -e1000_force_mac_fc_generic(struct e1000_hw *hw) +s32 e1000_force_mac_fc_generic(struct e1000_hw *hw) { - struct e1000_mac_info *mac = &hw->mac; u32 ctrl; s32 ret_val = E1000_SUCCESS; @@ -1108,13 +1181,14 @@ e1000_force_mac_fc_generic(struct e1000_hw *hw) ctrl = E1000_READ_REG(hw, E1000_CTRL); - /* Because we didn't get link via the internal auto-negotiation + /* + * Because we didn't get link via the internal auto-negotiation * mechanism (we either forced link or we got link via PHY * auto-neg), we have to manually enable/disable transmit an * receive flow control. * * The "Case" statement below enables/disable flow control - * according to the "mac->fc" parameter. + * according to the "hw->fc.type" parameter. * * The possible values of the "fc" parameter are: * 0: Flow control is completely disabled @@ -1122,12 +1196,12 @@ e1000_force_mac_fc_generic(struct e1000_hw *hw) * frames but not send pause frames). * 2: Tx flow control is enabled (we can send pause frames * frames but we do not receive pause frames). - * 3: Both Rx and TX flow control (symmetric) is enabled. + * 3: Both Rx and Tx flow control (symmetric) is enabled. * other: No other values should be possible at this point. */ - DEBUGOUT1("mac->fc = %u\n", mac->fc); + DEBUGOUT1("hw->fc.type = %u\n", hw->fc.type); - switch (mac->fc) { + switch (hw->fc.type) { case e1000_fc_none: ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); break; @@ -1164,8 +1238,7 @@ out: * and did not fail, then we configure flow control based on our link * partner. **/ -s32 -e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) +s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val = E1000_SUCCESS; @@ -1174,16 +1247,17 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_config_fc_after_link_up_generic"); - /* Check for the case where we have fiber media and auto-neg failed + /* + * Check for the case where we have fiber media and auto-neg failed * so we had to force link. In this case, we need to force the * configuration of the MAC to match the "fc" parameter. */ if (mac->autoneg_failed) { - if (hw->media_type == e1000_media_type_fiber || - hw->media_type == e1000_media_type_internal_serdes) + if (hw->phy.media_type == e1000_media_type_fiber || + hw->phy.media_type == e1000_media_type_internal_serdes) ret_val = e1000_force_mac_fc_generic(hw); } else { - if (hw->media_type == e1000_media_type_copper) + if (hw->phy.media_type == e1000_media_type_copper) ret_val = e1000_force_mac_fc_generic(hw); } @@ -1192,13 +1266,15 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) goto out; } - /* Check for the case where we have copper media and auto-neg is + /* + * Check for the case where we have copper media and auto-neg is * enabled. In this case, we need to check and see if Auto-Neg * has completed, and if so, how the PHY and link partner has * flow control configured. */ - if ((hw->media_type == e1000_media_type_copper) && mac->autoneg) { - /* Read the MII Status Register and check to see if AutoNeg + if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) { + /* + * Read the MII Status Register and check to see if AutoNeg * has completed. We read this twice because this reg has * some "sticky" (latched) bits. */ @@ -1215,7 +1291,8 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) goto out; } - /* The AutoNeg process has completed, so we now need to + /* + * The AutoNeg process has completed, so we now need to * read both the Auto Negotiation Advertisement * Register (Address 4) and the Auto_Negotiation Base * Page Ability Register (Address 5) to determine how @@ -1230,7 +1307,8 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) if (ret_val) goto out; - /* Two bits in the Auto Negotiation Advertisement Register + /* + * Two bits in the Auto Negotiation Advertisement Register * (Address 4) and two bits in the Auto Negotiation Base * Page Ability Register (Address 5) determine flow control * for both the PHY and the link partner. The following @@ -1251,8 +1329,7 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * 1 | 1 | 0 | 0 | e1000_fc_none * 1 | 1 | 0 | 1 | e1000_fc_rx_pause * - */ - /* Are both PAUSE bits set to 1? If so, this implies + * Are both PAUSE bits set to 1? If so, this implies * Symmetric Flow Control is enabled at both ends. The * ASM_DIR bits are irrelevant per the spec. * @@ -1266,82 +1343,62 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) */ if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { - /* Now we need to check if the user selected RX ONLY + /* + * Now we need to check if the user selected Rx ONLY * of pause frames. In this case, we had to advertise * FULL flow control because we could not advertise RX * ONLY. Hence, we must now check to see if we need to * turn OFF the TRANSMISSION of PAUSE frames. */ - if (mac->original_fc == e1000_fc_full) { - mac->fc = e1000_fc_full; + if (hw->fc.original_type == e1000_fc_full) { + hw->fc.type = e1000_fc_full; DEBUGOUT("Flow Control = FULL.\r\n"); } else { - mac->fc = e1000_fc_rx_pause; + hw->fc.type = e1000_fc_rx_pause; DEBUGOUT("Flow Control = " "RX PAUSE frames only.\r\n"); } } - /* For receiving PAUSE frames ONLY. + /* + * For receiving PAUSE frames ONLY. * * LOCAL DEVICE | LINK PARTNER * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result *-------|---------|-------|---------|-------------------- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause - * */ else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { - mac->fc = e1000_fc_tx_pause; + hw->fc.type = e1000_fc_tx_pause; DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n"); } - /* For transmitting PAUSE frames ONLY. + /* + * For transmitting PAUSE frames ONLY. * * LOCAL DEVICE | LINK PARTNER * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result *-------|---------|-------|---------|-------------------- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause - * */ else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { - mac->fc = e1000_fc_rx_pause; + hw->fc.type = e1000_fc_rx_pause; DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n"); - } - /* Per the IEEE spec, at this point flow control should be - * disabled. However, we want to consider that we could - * be connected to a legacy switch that doesn't advertise - * desired flow control, but can be forced on the link - * partner. So if we advertised no flow control, that is - * what we will resolve to. If we advertised some kind of - * receive capability (Rx Pause Only or Full Flow Control) - * and the link partner advertised none, we will configure - * ourselves to enable Rx Flow Control only. We can do - * this safely for two reasons: If the link partner really - * didn't want flow control enabled, and we enable Rx, no - * harm done since we won't be receiving any PAUSE frames - * anyway. If the intent on the link partner was to have - * flow control enabled, then by us enabling RX only, we - * can at least receive pause frames and process them. - * This is a good idea because in most cases, since we are - * predominantly a server NIC, more times than not we will - * be asked to delay transmission of packets than asking - * our link partner to pause transmission of frames. - */ - else if ((mac->original_fc == e1000_fc_none || - mac->original_fc == e1000_fc_tx_pause) || - mac->fc_strict_ieee) { - mac->fc = e1000_fc_none; - DEBUGOUT("Flow Control = NONE.\r\n"); } else { - mac->fc = e1000_fc_rx_pause; - DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n"); + /* + * Per the IEEE spec, at this point flow control + * should be disabled. + */ + hw->fc.type = e1000_fc_none; + DEBUGOUT("Flow Control = NONE.\r\n"); } - /* Now we need to do one last check... If we auto- + /* + * Now we need to do one last check... If we auto- * negotiated to HALF DUPLEX, flow control should not be * enabled per IEEE 802.3 spec. */ @@ -1352,9 +1409,10 @@ e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) } if (duplex == HALF_DUPLEX) - mac->fc = e1000_fc_none; + hw->fc.type = e1000_fc_none; - /* Now we call a subroutine to actually force the MAC + /* + * Now we call a subroutine to actually force the MAC * controller to use the correct flow control settings. */ ret_val = e1000_force_mac_fc_generic(hw); @@ -1377,9 +1435,8 @@ out: * Read the status register for the current speed/duplex and store the current * speed and duplex for copper connections. **/ -s32 -e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, - u16 *duplex) +s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, + u16 *duplex) { u32 status; @@ -1417,11 +1474,11 @@ e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, * Sets the speed and duplex to gigabit full duplex (the only possible option) * for fiber/serdes links. **/ -s32 -e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, u16 *speed, - u16 *duplex) +s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, + u16 *speed, u16 *duplex) { DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic"); + UNREFERENCED_PARAMETER(hw); *speed = SPEED_1000; *duplex = FULL_DUPLEX; @@ -1435,8 +1492,7 @@ e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, u16 *speed, * * Acquire the HW semaphore to access the PHY or NVM **/ -s32 -e1000_get_hw_semaphore_generic(struct e1000_hw *hw) +s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw) { u32 swsm; s32 ret_val = E1000_SUCCESS; @@ -1491,8 +1547,7 @@ out: * * Release hardware semaphore used to access the PHY or NVM **/ -void -e1000_put_hw_semaphore_generic(struct e1000_hw *hw) +void e1000_put_hw_semaphore_generic(struct e1000_hw *hw) { u32 swsm; @@ -1511,8 +1566,7 @@ e1000_put_hw_semaphore_generic(struct e1000_hw *hw) * * Check EEPROM for Auto Read done bit. **/ -s32 -e1000_get_auto_rd_done_generic(struct e1000_hw *hw) +s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw) { s32 i = 0; s32 ret_val = E1000_SUCCESS; @@ -1544,8 +1598,7 @@ out: * Read the EEPROM for the current default LED configuration. If the * LED configuration is not valid, set to a valid LED configuration. **/ -s32 -e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data) +s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data) { s32 ret_val; @@ -1569,8 +1622,7 @@ out: * @hw: pointer to the HW structure * **/ -s32 -e1000_id_led_init_generic(struct e1000_hw * hw) +s32 e1000_id_led_init_generic(struct e1000_hw * hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; @@ -1639,8 +1691,7 @@ out: * This prepares the SW controllable LED for use and saves the current state * of the LED so it can be later restored. **/ -s32 -e1000_setup_led_generic(struct e1000_hw *hw) +s32 e1000_setup_led_generic(struct e1000_hw *hw) { u32 ledctl; s32 ret_val = E1000_SUCCESS; @@ -1652,7 +1703,7 @@ e1000_setup_led_generic(struct e1000_hw *hw) goto out; } - if (hw->media_type == e1000_media_type_fiber) { + if (hw->phy.media_type == e1000_media_type_fiber) { ledctl = E1000_READ_REG(hw, E1000_LEDCTL); hw->mac.ledctl_default = ledctl; /* Turn off LED0 */ @@ -1662,7 +1713,7 @@ e1000_setup_led_generic(struct e1000_hw *hw) ledctl |= (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT); E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl); - } else if (hw->media_type == e1000_media_type_copper) { + } else if (hw->phy.media_type == e1000_media_type_copper) { E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); } @@ -1677,8 +1728,7 @@ out: * Remove the current LED configuration and set the LED configuration * to the default value, saved from the EEPROM. **/ -s32 -e1000_cleanup_led_generic(struct e1000_hw *hw) +s32 e1000_cleanup_led_generic(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; @@ -1701,21 +1751,22 @@ out: * * Blink the led's which are set to be on. **/ -s32 -e1000_blink_led_generic(struct e1000_hw *hw) +s32 e1000_blink_led_generic(struct e1000_hw *hw) { u32 ledctl_blink = 0; u32 i; DEBUGFUNC("e1000_blink_led_generic"); - if (hw->media_type == e1000_media_type_fiber) { + if (hw->phy.media_type == e1000_media_type_fiber) { /* always blink LED0 for PCI-E fiber */ ledctl_blink = E1000_LEDCTL_LED0_BLINK | (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT); } else { - /* set the blink bit for each LED that's "on" (0x0E) - * in ledctl_mode2 */ + /* + * set the blink bit for each LED that's "on" (0x0E) + * in ledctl_mode2 + */ ledctl_blink = hw->mac.ledctl_mode2; for (i = 0; i < 4; i++) if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == @@ -1735,14 +1786,13 @@ e1000_blink_led_generic(struct e1000_hw *hw) * * Turn LED on. **/ -s32 -e1000_led_on_generic(struct e1000_hw *hw) +s32 e1000_led_on_generic(struct e1000_hw *hw) { u32 ctrl; DEBUGFUNC("e1000_led_on_generic"); - switch (hw->media_type) { + switch (hw->phy.media_type) { case e1000_media_type_fiber: ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl &= ~E1000_CTRL_SWDPIN0; @@ -1765,14 +1815,13 @@ e1000_led_on_generic(struct e1000_hw *hw) * * Turn LED off. **/ -s32 -e1000_led_off_generic(struct e1000_hw *hw) +s32 e1000_led_off_generic(struct e1000_hw *hw) { u32 ctrl; DEBUGFUNC("e1000_led_off_generic"); - switch (hw->media_type) { + switch (hw->phy.media_type) { case e1000_media_type_fiber: ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl |= E1000_CTRL_SWDPIN0; @@ -1796,8 +1845,7 @@ e1000_led_off_generic(struct e1000_hw *hw) * * Set the PCI-express register to snoop for events enabled in 'no_snoop'. **/ -void -e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop) +void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop) { u32 gcr; @@ -1827,8 +1875,7 @@ out: * Disables PCI-Express master access and verifies there are no pending * requests. **/ -s32 -e1000_disable_pcie_master_generic(struct e1000_hw *hw) +s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw) { u32 ctrl; s32 timeout = MASTER_DISABLE_TIMEOUT; @@ -1867,8 +1914,7 @@ out: * * Reset the Adaptive Interframe Spacing throttle to default values. **/ -void -e1000_reset_adaptive_generic(struct e1000_hw *hw) +void e1000_reset_adaptive_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; @@ -1900,8 +1946,7 @@ out: * Update the Adaptive Interframe Spacing Throttle value based on the * time between transmitted packets and time between collisions. **/ -void -e1000_update_adaptive_generic(struct e1000_hw *hw) +void e1000_update_adaptive_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; @@ -1943,8 +1988,7 @@ out: * Verify that when not using auto-negotitation that MDI/MDIx is correctly * set, which is forced to MDI mode only. **/ -s32 -e1000_validate_mdi_setting_generic(struct e1000_hw *hw) +s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; @@ -1972,9 +2016,8 @@ out: * and they all have the format address << 8 | data and bit 31 is polled for * completion. **/ -s32 -e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, - u32 offset, u8 data) +s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, + u32 offset, u8 data) { u32 i, regvalue = 0; s32 ret_val = E1000_SUCCESS; diff --git a/sys/dev/em/e1000_mac.h b/sys/dev/em/e1000_mac.h index cc485db7231f..9887280e1198 100644 --- a/sys/dev/em/e1000_mac.h +++ b/sys/dev/em/e1000_mac.h @@ -30,13 +30,14 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_MAC_H_ #define _E1000_MAC_H_ -/* Functions that should not be called directly from drivers but can be used +/* + * Functions that should not be called directly from drivers but can be used * by other files in this 'shared code' */ s32 e1000_blink_led_generic(struct e1000_hw *hw); @@ -59,7 +60,7 @@ s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, s32 e1000_id_led_init_generic(struct e1000_hw *hw); s32 e1000_led_on_generic(struct e1000_hw *hw); s32 e1000_led_off_generic(struct e1000_hw *hw); -void e1000_mc_addr_list_update_generic(struct e1000_hw *hw, +void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, u32 rar_used_count, u32 rar_count); s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw); @@ -82,6 +83,7 @@ void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value); void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw); void e1000_put_hw_semaphore_generic(struct e1000_hw *hw); void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); +s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw); void e1000_remove_device_generic(struct e1000_hw *hw); void e1000_reset_adaptive_generic(struct e1000_hw *hw); void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop); diff --git a/sys/dev/em/e1000_manage.c b/sys/dev/em/e1000_manage.c index 490802358966..0eff18b43a2c 100644 --- a/sys/dev/em/e1000_manage.c +++ b/sys/dev/em/e1000_manage.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #include "e1000_api.h" @@ -46,8 +46,7 @@ static u8 e1000_calculate_checksum(u8 *buffer, u32 length); * Calculates the checksum for some buffer on a specified length. The * checksum calculated is returned. **/ -static u8 -e1000_calculate_checksum(u8 *buffer, u32 length) +static u8 e1000_calculate_checksum(u8 *buffer, u32 length) { u32 i; u8 sum = 0; @@ -73,8 +72,7 @@ e1000_calculate_checksum(u8 *buffer, u32 length) * and also checks whether the previous command is completed. It busy waits * in case of previous command is not completed. **/ -s32 -e1000_mng_enable_host_if_generic(struct e1000_hw * hw) +s32 e1000_mng_enable_host_if_generic(struct e1000_hw * hw) { u32 hicr; s32 ret_val = E1000_SUCCESS; @@ -114,8 +112,7 @@ out: * Reads the firmware semaphore register and returns true (>0) if * manageability is enabled, else false (0). **/ -boolean_t -e1000_check_mng_mode_generic(struct e1000_hw *hw) +bool e1000_check_mng_mode_generic(struct e1000_hw *hw) { u32 fwsm; @@ -134,15 +131,14 @@ e1000_check_mng_mode_generic(struct e1000_hw *hw) * Enables packet filtering on transmit packets if manageability is enabled * and host interface is enabled. **/ -boolean_t -e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) +bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) { struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; u32 *buffer = (u32 *)&hw->mng_cookie; u32 offset; s32 ret_val, hdr_csum, csum; u8 i, len; - boolean_t tx_filter = TRUE; + bool tx_filter = TRUE; DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic"); @@ -152,7 +148,8 @@ e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) goto out; } - /* If we can't read from the host interface for whatever + /* + * If we can't read from the host interface for whatever * reason, disable filtering. */ ret_val = e1000_mng_enable_host_if(hw); @@ -173,7 +170,8 @@ e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) hdr->checksum = 0; csum = e1000_calculate_checksum((u8 *)hdr, E1000_MNG_DHCP_COOKIE_LENGTH); - /* If either the checksums or signature don't match, then + /* + * If either the checksums or signature don't match, then * the cookie area isn't considered valid, in which case we * take the safe route of assuming Tx filtering is enabled. */ @@ -199,8 +197,8 @@ out: * * Writes the DHCP information to the host interface. **/ -s32 -e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer, u16 length) +s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer, + u16 length) { struct e1000_host_mng_command_header hdr; s32 ret_val; @@ -245,9 +243,8 @@ out: * * Writes the command header after does the checksum calculation. **/ -s32 -e1000_mng_write_cmd_header_generic(struct e1000_hw * hw, - struct e1000_host_mng_command_header * hdr) +s32 e1000_mng_write_cmd_header_generic(struct e1000_hw * hw, + struct e1000_host_mng_command_header * hdr) { u16 i, length = sizeof(struct e1000_host_mng_command_header); @@ -260,7 +257,8 @@ e1000_mng_write_cmd_header_generic(struct e1000_hw * hw, length >>= 2; /* Write the relevant command block into the ram area. */ for (i = 0; i < length; i++) { - E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, *((u32 *) hdr + i)); + E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, + *((u32 *) hdr + i)); E1000_WRITE_FLUSH(hw); } @@ -279,9 +277,8 @@ e1000_mng_write_cmd_header_generic(struct e1000_hw * hw, * It also does alignment considerations to do the writes in most efficient * way. Also fills up the sum of the buffer in *buffer parameter. **/ -s32 -e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer, u16 length, - u16 offset, u8 *sum) +s32 e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer, + u16 length, u16 offset, u8 *sum) { u8 *tmp; u8 *bufptr = buffer; @@ -319,8 +316,10 @@ e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer, u16 length, /* Calculate length in DWORDs */ length >>= 2; - /* The device driver writes the relevant command block into the - * ram area. */ + /* + * The device driver writes the relevant command block into the + * ram area. + */ for (i = 0; i < length; i++) { for (j = 0; j < sizeof(u32); j++) { *(tmp + j) = *bufptr++; @@ -351,12 +350,11 @@ out: * * Verifies the hardware needs to allow ARPs to be processed by the host. **/ -boolean_t -e1000_enable_mng_pass_thru(struct e1000_hw *hw) +bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) { u32 manc; u32 fwsm, factps; - boolean_t ret_val = FALSE; + bool ret_val = FALSE; DEBUGFUNC("e1000_enable_mng_pass_thru"); @@ -369,7 +367,7 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw) !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) goto out; - if (hw->mac.arc_subsystem_valid == TRUE) { + if (hw->mac.arc_subsystem_valid) { fwsm = E1000_READ_REG(hw, E1000_FWSM); factps = E1000_READ_REG(hw, E1000_FACTPS); @@ -379,12 +377,13 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw) ret_val = TRUE; goto out; } - } else + } else { if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) { ret_val = TRUE; goto out; } + } out: return ret_val; diff --git a/sys/dev/em/e1000_manage.h b/sys/dev/em/e1000_manage.h index 0c0208737472..17849c1f816f 100644 --- a/sys/dev/em/e1000_manage.h +++ b/sys/dev/em/e1000_manage.h @@ -30,21 +30,21 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_MANAGE_H_ #define _E1000_MANAGE_H_ -boolean_t e1000_check_mng_mode_generic(struct e1000_hw *hw); -boolean_t e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw); -s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw); -s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, - u16 length, u16 offset, u8 *sum); -s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr); -s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, - u8 *buffer, u16 length); +bool e1000_check_mng_mode_generic(struct e1000_hw *hw); +bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw); +s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw); +s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, + u16 length, u16 offset, u8 *sum); +s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, + struct e1000_host_mng_command_header *hdr); +s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, + u8 *buffer, u16 length); typedef enum { e1000_mng_mode_none = 0, @@ -76,13 +76,13 @@ typedef enum { #define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */ #define E1000_HICR_EN 0x01 /* Enable bit - RO */ -#define E1000_HICR_C 0x02 /* Driver sets this bit when done - * to put command in RAM */ +/* Driver sets this bit when done to put command in RAM */ +#define E1000_HICR_C 0x02 #define E1000_HICR_SV 0x04 /* Status Validity */ #define E1000_HICR_FW_RESET_ENABLE 0x40 #define E1000_HICR_FW_RESET 0x80 -#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management - * Technology signature */ +/* Intel(R) Active Management Technology signature */ +#define E1000_IAMT_SIGNATURE 0x544D4149 #endif diff --git a/sys/dev/em/e1000_nvm.c b/sys/dev/em/e1000_nvm.c index 7d58f53a9b81..726fa7bc5fe6 100644 --- a/sys/dev/em/e1000_nvm.c +++ b/sys/dev/em/e1000_nvm.c @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #include "e1000_api.h" @@ -43,8 +43,7 @@ * * Enable/Raise the EEPROM clock bit. **/ -static void -e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) +static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) { *eecd = *eecd | E1000_EECD_SK; E1000_WRITE_REG(hw, E1000_EECD, *eecd); @@ -59,8 +58,7 @@ e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) * * Clear/Lower the EEPROM clock bit. **/ -static void -e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) +static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) { *eecd = *eecd & ~E1000_EECD_SK; E1000_WRITE_REG(hw, E1000_EECD, *eecd); @@ -78,8 +76,7 @@ e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) * "data" parameter will be shifted out to the EEPROM one bit at a time. * In order to do this, "data" must be broken down into bits. **/ -static void -e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) +static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) { struct e1000_nvm_info *nvm = &hw->nvm; u32 eecd = E1000_READ_REG(hw, E1000_EECD); @@ -125,8 +122,7 @@ e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) * "DO" bit. During this "shifting in" process the data in "DI" bit should * always be clear. **/ -static u16 -e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) +static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) { u32 eecd; u32 i; @@ -163,8 +159,7 @@ e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) * Polls the EEPROM status bit for either read or write completion based * upon the value of 'ee_reg'. **/ -s32 -e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) +s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) { u32 attempts = 100000; u32 i, reg = 0; @@ -197,8 +192,7 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) * Return successful if access grant bit set, else clear the request for * EEPROM access and return -E1000_ERR_NVM (-1). **/ -s32 -e1000_acquire_nvm_generic(struct e1000_hw *hw) +s32 e1000_acquire_nvm_generic(struct e1000_hw *hw) { u32 eecd = E1000_READ_REG(hw, E1000_EECD); s32 timeout = E1000_NVM_GRANT_ATTEMPTS; @@ -233,8 +227,7 @@ e1000_acquire_nvm_generic(struct e1000_hw *hw) * * Return the EEPROM to a standby state. **/ -static void -e1000_standby_nvm(struct e1000_hw *hw) +static void e1000_standby_nvm(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; u32 eecd = E1000_READ_REG(hw, E1000_EECD); @@ -275,8 +268,7 @@ e1000_standby_nvm(struct e1000_hw *hw) * * Terminates the current command by inverting the EEPROM's chip select pin. **/ -void -e1000_stop_nvm(struct e1000_hw *hw) +void e1000_stop_nvm(struct e1000_hw *hw) { u32 eecd; @@ -302,8 +294,7 @@ e1000_stop_nvm(struct e1000_hw *hw) * * Stop any current commands to the EEPROM and clear the EEPROM request bit. **/ -void -e1000_release_nvm_generic(struct e1000_hw *hw) +void e1000_release_nvm_generic(struct e1000_hw *hw) { u32 eecd; @@ -322,8 +313,7 @@ e1000_release_nvm_generic(struct e1000_hw *hw) * * Setups the EEPROM for reading and writing. **/ -static s32 -e1000_ready_nvm_eeprom(struct e1000_hw *hw) +static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; u32 eecd = E1000_READ_REG(hw, E1000_EECD); @@ -347,10 +337,12 @@ e1000_ready_nvm_eeprom(struct e1000_hw *hw) usec_delay(1); timeout = NVM_MAX_RETRY_SPI; - /* Read "Status Register" repeatedly until the LSB is cleared. + /* + * Read "Status Register" repeatedly until the LSB is cleared. * The EEPROM will signal that the command has been completed * by clearing bit 0 of the internal status register. If it's - * not cleared within 'timeout', then error out. */ + * not cleared within 'timeout', then error out. + */ while (timeout) { e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, hw->nvm.opcode_bits); @@ -383,8 +375,7 @@ out: * * Reads a 16 bit word from the EEPROM. **/ -s32 -e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i = 0; @@ -394,8 +385,10 @@ e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) DEBUGFUNC("e1000_read_nvm_spi"); - /* A check for invalid values: offset too large, too many words, - * and not enough words. */ + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { DEBUGOUT("nvm parameter(s) out of bounds\n"); @@ -420,9 +413,11 @@ e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); - /* Read the data. SPI NVMs increment the address with each byte + /* + * Read the data. SPI NVMs increment the address with each byte * read and will roll over if reading beyond the end. This allows - * us to read the whole NVM from any offset */ + * us to read the whole NVM from any offset + */ for (i = 0; i < words; i++) { word_in = e1000_shift_in_eec_bits(hw, 16); data[i] = (word_in >> 8) | (word_in << 8); @@ -444,8 +439,8 @@ out: * * Reads a 16 bit word from the EEPROM. **/ -s32 -e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i = 0; @@ -454,8 +449,10 @@ e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) DEBUGFUNC("e1000_read_nvm_microwire"); - /* A check for invalid values: offset too large, too many words, - * and not enough words. */ + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { DEBUGOUT("nvm parameter(s) out of bounds\n"); @@ -477,8 +474,10 @@ e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) e1000_shift_out_eec_bits(hw, (u16)(offset + i), nvm->address_bits); - /* Read the data. For microwire, each word requires the - * overhead of setup and tear-down. */ + /* + * Read the data. For microwire, each word requires the + * overhead of setup and tear-down. + */ data[i] = e1000_shift_in_eec_bits(hw, 16); e1000_standby_nvm(hw); } @@ -499,8 +498,7 @@ out: * * Reads a 16 bit word from the EEPROM using the EERD register. **/ -s32 -e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; u32 i, eerd = 0; @@ -508,8 +506,10 @@ e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) DEBUGFUNC("e1000_read_nvm_eerd"); - /* A check for invalid values: offset too large, too many words, - * and not enough words. */ + /* + * A check for invalid values: offset too large, too many words, + * too many words for the offset, and not enough words. + */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { DEBUGOUT("nvm parameter(s) out of bounds\n"); @@ -526,7 +526,8 @@ e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) if (ret_val) break; - data[i] = (E1000_READ_REG(hw, E1000_EERD) >> E1000_NVM_RW_REG_DATA); + data[i] = (E1000_READ_REG(hw, E1000_EERD) >> + E1000_NVM_RW_REG_DATA); } out: @@ -545,8 +546,7 @@ out: * If e1000_update_nvm_checksum is not called after this function , the * EEPROM will most likley contain an invalid checksum. **/ -s32 -e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; s32 ret_val; @@ -554,8 +554,10 @@ e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) DEBUGFUNC("e1000_write_nvm_spi"); - /* A check for invalid values: offset too large, too many words, - * and not enough words. */ + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { DEBUGOUT("nvm parameter(s) out of bounds\n"); @@ -584,8 +586,10 @@ e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) e1000_standby_nvm(hw); - /* Some SPI eeproms use the 8th address bit embedded in the - * opcode */ + /* + * Some SPI eeproms use the 8th address bit embedded in the + * opcode + */ if ((nvm->address_bits == 8) && (offset >= 128)) write_opcode |= NVM_A8_OPCODE_SPI; @@ -628,8 +632,8 @@ out: * If e1000_update_nvm_checksum is not called after this function , the * EEPROM will most likley contain an invalid checksum. **/ -s32 -e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; s32 ret_val; @@ -639,8 +643,10 @@ e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) DEBUGFUNC("e1000_write_nvm_microwire"); - /* A check for invalid values: offset too large, too many words, - * and not enough words. */ + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || (words == 0)) { DEBUGOUT("nvm parameter(s) out of bounds\n"); @@ -705,34 +711,33 @@ out: } /** - * e1000_read_part_num_generic - Read device part number + * e1000_read_pba_num_generic - Read device part number * @hw: pointer to the HW structure - * @part_num: pointer to device part number + * @pba_num: pointer to device part number * * Reads the product board assembly (PBA) number from the EEPROM and stores - * the value in part_num. + * the value in pba_num. **/ -s32 -e1000_read_part_num_generic(struct e1000_hw *hw, u32 *part_num) +s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num) { s32 ret_val; u16 nvm_data; - DEBUGFUNC("e1000_read_part_num_generic"); + DEBUGFUNC("e1000_read_pba_num_generic"); ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; } - *part_num = (u32)(nvm_data << 16); + *pba_num = (u32)(nvm_data << 16); ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; } - *part_num |= nvm_data; + *pba_num |= nvm_data; out: return ret_val; @@ -746,8 +751,7 @@ out: * Since devices with two ports use the same EEPROM, we increment the * last bit in the MAC address for the second port. **/ -s32 -e1000_read_mac_addr_generic(struct e1000_hw *hw) +s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 offset, nvm_data, i; @@ -783,8 +787,7 @@ out: * Calculates the EEPROM checksum by reading/adding each word of the EEPROM * and then verifies that the sum of the EEPROM is equal to 0xBABA. **/ -s32 -e1000_validate_nvm_checksum_generic(struct e1000_hw *hw) +s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 checksum = 0; @@ -819,8 +822,7 @@ out: * up to the checksum. Then calculates the EEPROM checksum and writes the * value to the EEPROM. **/ -s32 -e1000_update_nvm_checksum_generic(struct e1000_hw *hw) +s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw) { s32 ret_val; u16 checksum = 0; @@ -853,8 +855,7 @@ out: * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the * extended control register. **/ -void -e1000_reload_nvm_generic(struct e1000_hw *hw) +void e1000_reload_nvm_generic(struct e1000_hw *hw) { u32 ctrl_ext; @@ -876,13 +877,12 @@ e1000_reload_nvm_generic(struct e1000_hw *hw) * For those silicon families which have implemented a NVM acquire function, * run the defined function else return success. **/ -s32 -e1000_acquire_nvm(struct e1000_hw *hw) +s32 e1000_acquire_nvm(struct e1000_hw *hw) { - if (hw->func.acquire_nvm != NULL) + if (hw->func.acquire_nvm) return hw->func.acquire_nvm(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -892,10 +892,9 @@ e1000_acquire_nvm(struct e1000_hw *hw) * For those silicon families which have implemented a NVM release function, * run the defined fucntion else return success. **/ -void -e1000_release_nvm(struct e1000_hw *hw) +void e1000_release_nvm(struct e1000_hw *hw) { - if (hw->func.release_nvm != NULL) + if (hw->func.release_nvm) hw->func.release_nvm(hw); } diff --git a/sys/dev/em/e1000_nvm.h b/sys/dev/em/e1000_nvm.h index 80938739dcb1..8082c3e82460 100644 --- a/sys/dev/em/e1000_nvm.h +++ b/sys/dev/em/e1000_nvm.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_NVM_H_ @@ -40,7 +40,7 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw); s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg); s32 e1000_read_mac_addr_generic(struct e1000_hw *hw); -s32 e1000_read_part_num_generic(struct e1000_hw *hw, u32 *part_num); +s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num); s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); diff --git a/sys/dev/em/e1000_osdep.h b/sys/dev/em/e1000_osdep.h index b9877caf657c..257d5da0c551 100644 --- a/sys/dev/em/e1000_osdep.h +++ b/sys/dev/em/e1000_osdep.h @@ -30,7 +30,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _FREEBSD_OS_H_ @@ -89,6 +89,7 @@ typedef int64_t s64; typedef int32_t s32; typedef int16_t s16; typedef int8_t s8; +typedef boolean_t bool; struct e1000_osdep { diff --git a/sys/dev/em/e1000_phy.c b/sys/dev/em/e1000_phy.c index 298b47064f21..dbbbdc598419 100644 --- a/sys/dev/em/e1000_phy.c +++ b/sys/dev/em/e1000_phy.c @@ -30,26 +30,24 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #include "e1000_api.h" #include "e1000_phy.h" static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw); -static void e1000_release_phy(struct e1000_hw *hw); -static s32 e1000_acquire_phy(struct e1000_hw *hw); +STATIC void e1000_release_phy(struct e1000_hw *hw); +STATIC s32 e1000_acquire_phy(struct e1000_hw *hw); /* Cable length tables */ -static const -u16 e1000_m88_cable_length_table[] = +static const u16 e1000_m88_cable_length_table[] = { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; #define M88E1000_CABLE_LENGTH_TABLE_SIZE \ (sizeof(e1000_m88_cable_length_table) / \ sizeof(e1000_m88_cable_length_table[0])) -static const -u16 e1000_igp_2_cable_length_table[] = +static const u16 e1000_igp_2_cable_length_table[] = { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21, 0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41, 6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61, @@ -70,8 +68,7 @@ u16 e1000_igp_2_cable_length_table[] = * is blocked. If a reset is not blocked return E1000_SUCCESS, otherwise * return E1000_BLK_PHY_RESET (12). **/ -s32 -e1000_check_reset_block_generic(struct e1000_hw *hw) +s32 e1000_check_reset_block_generic(struct e1000_hw *hw) { u32 manc; @@ -90,8 +87,7 @@ e1000_check_reset_block_generic(struct e1000_hw *hw) * Reads the PHY registers and stores the PHY ID and possibly the PHY * revision in the hardware structure. **/ -s32 -e1000_get_phy_id(struct e1000_hw *hw) +s32 e1000_get_phy_id(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -122,8 +118,7 @@ out: * * Reset the digital signal processor. **/ -s32 -e1000_phy_reset_dsp_generic(struct e1000_hw *hw) +s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw) { s32 ret_val; @@ -148,8 +143,7 @@ out: * Reads the MDI control regsiter in the PHY at offset and stores the * information read to data. **/ -static s32 -e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) +STATIC s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) { struct e1000_phy_info *phy = &hw->phy; u32 i, mdic = 0; @@ -163,7 +157,8 @@ e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) goto out; } - /* Set up Op-code, Phy Address, and register offset in the MDI + /* + * Set up Op-code, Phy Address, and register offset in the MDI * Control register. The MAC will take care of interfacing with the * PHY to retrieve the desired data. */ @@ -173,8 +168,12 @@ e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) E1000_WRITE_REG(hw, E1000_MDIC, mdic); - /* Poll the ready bit to see if the MDI read completed */ - for (i = 0; i < 64; i++) { + /* + * Poll the ready bit to see if the MDI read completed + * Increasing the time out as testing showed failures with + * the lower time out + */ + for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { usec_delay(50); mdic = E1000_READ_REG(hw, E1000_MDIC); if (mdic & E1000_MDIC_READY) @@ -204,8 +203,7 @@ out: * * Writes data to MDI control register in the PHY at offset. **/ -static s32 -e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) +STATIC s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) { struct e1000_phy_info *phy = &hw->phy; u32 i, mdic = 0; @@ -219,7 +217,8 @@ e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - /* Set up Op-code, Phy Address, and register offset in the MDI + /* + * Set up Op-code, Phy Address, and register offset in the MDI * Control register. The MAC will take care of interfacing with the * PHY to retrieve the desired data. */ @@ -230,9 +229,13 @@ e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) E1000_WRITE_REG(hw, E1000_MDIC, mdic); - /* Poll the ready bit to see if the MDI read completed */ - for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) { - usec_delay(5); + /* + * Poll the ready bit to see if the MDI read completed + * Increasing the time out as testing showed failures with + * the lower time out + */ + for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { + usec_delay(50); mdic = E1000_READ_REG(hw, E1000_MDIC); if (mdic & E1000_MDIC_READY) break; @@ -242,6 +245,11 @@ e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) ret_val = -E1000_ERR_PHY; goto out; } + if (mdic & E1000_MDIC_ERROR) { + DEBUGOUT("MDI Error\n"); + ret_val = -E1000_ERR_PHY; + goto out; + } out: return ret_val; @@ -257,8 +265,7 @@ out: * and storing the retrieved information in data. Release any acquired * semaphores before exiting. **/ -s32 -e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) { s32 ret_val; @@ -287,8 +294,7 @@ out: * Acquires semaphore, if necessary, then writes the data to PHY register * at the offset. Release any acquired semaphores before exiting. **/ -s32 -e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) { s32 ret_val; @@ -318,8 +324,7 @@ out: * and storing the retrieved information in data. Release any acquired * semaphores before exiting. **/ -s32 -e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) { s32 ret_val; @@ -358,8 +363,7 @@ out: * Acquires semaphore, if necessary, then writes the data to PHY register * at the offset. Release any acquired semaphores before exiting. **/ -s32 -e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) { s32 ret_val; @@ -399,8 +403,7 @@ out: * using the kumeran interface. The information retrieved is stored in data. * Release any acquired semaphores before exiting. **/ -s32 -e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) +s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) { u32 kmrnctrlsta; s32 ret_val; @@ -436,8 +439,7 @@ out: * at the offset using the kumeran interface. Release any acquired semaphores * before exiting. **/ -s32 -e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data) +s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data) { u32 kmrnctrlsta; s32 ret_val; @@ -466,8 +468,7 @@ out: * Sets up MDI/MDI-X and polarity for m88 PHY's. If necessary, transmit clock * and downshift values are set also. **/ -s32 -e1000_copper_link_setup_m88(struct e1000_hw *hw) +s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -487,7 +488,8 @@ e1000_copper_link_setup_m88(struct e1000_hw *hw) phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - /* Options: + /* + * Options: * MDI/MDI-X = 0 (default) * 0 - Auto for all speeds * 1 - MDI mode @@ -512,7 +514,8 @@ e1000_copper_link_setup_m88(struct e1000_hw *hw) break; } - /* Options: + /* + * Options: * disable_polarity_correction = 0 (default) * Automatic Correction for Reversed Cable Polarity * 0 - Disabled @@ -527,7 +530,8 @@ e1000_copper_link_setup_m88(struct e1000_hw *hw) goto out; if (phy->revision < E1000_REVISION_4) { - /* Force TX_CLK in the Extended PHY Specific Control Register + /* + * Force TX_CLK in the Extended PHY Specific Control Register * to 25MHz clock. */ ret_val = e1000_read_phy_reg(hw, @@ -575,8 +579,7 @@ out: * Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for * igp PHY's. **/ -s32 -e1000_copper_link_setup_igp(struct e1000_hw *hw) +s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -598,8 +601,10 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw) /* Wait 15ms for MAC to configure PHY from NVM settings. */ msec_delay(15); - /* The NVM settings will configure LPLU in D3 for - * non-IGP1 PHYs. */ + /* + * The NVM settings will configure LPLU in D3 for + * non-IGP1 PHYs. + */ if (phy->type == e1000_phy_igp) { /* disable lplu d3 during driver init */ ret_val = e1000_set_d3_lplu_state(hw, FALSE); @@ -640,9 +645,11 @@ e1000_copper_link_setup_igp(struct e1000_hw *hw) /* set auto-master slave resolution settings */ if (hw->mac.autoneg) { - /* when autonegotiation advertisement is only 1000Mbps then we + /* + * when autonegotiation advertisement is only 1000Mbps then we * should disable SmartSpeed and enable Auto MasterSlave - * resolution as hardware default. */ + * resolution as hardware default. + */ if (phy->autoneg_advertised == ADVERTISE_1000_FULL) { /* Disable SmartSpeed */ ret_val = e1000_read_phy_reg(hw, @@ -709,10 +716,9 @@ out: * Performs initial bounds checking on autoneg advertisement parameter, then * configure to advertise the full capability. Setup the PHY to autoneg * and restart the negotiation process between the link partner. If - * wait_for_link, then wait for autoneg to complete before exiting. + * autoneg_wait_to_complete, then wait for autoneg to complete before exiting. **/ -s32 -e1000_copper_link_autoneg(struct e1000_hw *hw) +s32 e1000_copper_link_autoneg(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -720,12 +726,14 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_autoneg"); - /* Perform some bounds checking on the autoneg advertisement + /* + * Perform some bounds checking on the autoneg advertisement * parameter. */ phy->autoneg_advertised &= phy->autoneg_mask; - /* If autoneg_advertised is zero, we assume it was not defaulted + /* + * If autoneg_advertised is zero, we assume it was not defaulted * by the calling code so we set to advertise full capability. */ if (phy->autoneg_advertised == 0) @@ -739,7 +747,8 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) } DEBUGOUT("Restarting Auto-Neg\n"); - /* Restart auto-negotiation by setting the Auto Neg Enable bit and + /* + * Restart auto-negotiation by setting the Auto Neg Enable bit and * the Auto Neg Restart bit in the PHY control register. */ ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl); @@ -751,10 +760,11 @@ e1000_copper_link_autoneg(struct e1000_hw *hw) if (ret_val) goto out; - /* Does the user want to wait for Auto-Neg to complete here, or + /* + * Does the user want to wait for Auto-Neg to complete here, or * check at a later time (for example, callback routine). */ - if (phy->wait_for_link) { + if (phy->autoneg_wait_to_complete) { ret_val = e1000_wait_autoneg(hw); if (ret_val) { DEBUGOUT("Error while waiting for " @@ -778,8 +788,7 @@ out: * return successful. Otherwise, setup advertisement and flow control to * the appropriate values for the wanted auto-negotiation. **/ -s32 -e1000_phy_setup_autoneg(struct e1000_hw *hw) +s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -804,14 +813,16 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) goto out; } - /* Need to parse both autoneg_advertised and fc and set up + /* + * Need to parse both autoneg_advertised and fc and set up * the appropriate PHY registers. First we will parse for * autoneg_advertised software override. Since we can advertise * a plethora of combinations, we need to check each bit * individually. */ - /* First we clear all the 10/100 mb speed bits in the Auto-Neg + /* + * First we clear all the 10/100 mb speed bits in the Auto-Neg * Advertisement Register (Address 4) and the 1000 mb speed bits in * the 1000Base-T Control Register (Address 9). */ @@ -858,7 +869,8 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS; } - /* Check for a software override of the flow control settings, and + /* + * Check for a software override of the flow control settings, and * setup the PHY advertisement registers accordingly. If * auto-negotiation is enabled, then software will have to set the * "PAUSE" bits to the correct value in the Auto-Negotiation @@ -871,38 +883,42 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) * but not send pause frames). * 2: Tx flow control is enabled (we can send pause frames * but we do not support receiving pause frames). - * 3: Both Rx and TX flow control (symmetric) are enabled. + * 3: Both Rx and Tx flow control (symmetric) are enabled. * other: No software override. The flow control configuration * in the EEPROM is used. */ - switch (hw->mac.fc) { + switch (hw->fc.type) { case e1000_fc_none: - /* Flow control (RX & TX) is completely disabled by a + /* + * Flow control (Rx & Tx) is completely disabled by a * software over-ride. */ mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); break; case e1000_fc_rx_pause: - /* RX Flow control is enabled, and TX Flow control is + /* + * Rx Flow control is enabled, and Tx Flow control is * disabled, by a software over-ride. - */ - /* Since there really isn't a way to advertise that we are - * capable of RX Pause ONLY, we will advertise that we - * support both symmetric and asymmetric RX PAUSE. Later + * + * Since there really isn't a way to advertise that we are + * capable of Rx Pause ONLY, we will advertise that we + * support both symmetric and asymmetric Rx PAUSE. Later * (in e1000_config_fc_after_link_up) we will disable the * hw's ability to send PAUSE frames. */ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); break; case e1000_fc_tx_pause: - /* TX Flow control is enabled, and RX Flow control is + /* + * Tx Flow control is enabled, and Rx Flow control is * disabled, by a software over-ride. */ mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR; mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE; break; case e1000_fc_full: - /* Flow control (both RX and TX) is enabled by a software + /* + * Flow control (both Rx and Tx) is enabled by a software * over-ride. */ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); @@ -940,23 +956,26 @@ out: * to configure collision distance and flow control are called. If link is * not established, we return -E1000_ERR_PHY (-2). **/ -s32 -e1000_setup_copper_link_generic(struct e1000_hw *hw) +s32 e1000_setup_copper_link_generic(struct e1000_hw *hw) { s32 ret_val; - boolean_t link; + bool link; DEBUGFUNC("e1000_setup_copper_link_generic"); if (hw->mac.autoneg) { - /* Setup autoneg and flow control advertisement and perform - * autonegotiation. */ + /* + * Setup autoneg and flow control advertisement and perform + * autonegotiation. + */ ret_val = e1000_copper_link_autoneg(hw); if (ret_val) goto out; } else { - /* PHY will be set to 10H, 10F, 100H or 100F - * depending on user settings. */ + /* + * PHY will be set to 10H, 10F, 100H or 100F + * depending on user settings. + */ DEBUGOUT("Forcing Speed and Duplex\n"); ret_val = e1000_phy_force_speed_duplex(hw); if (ret_val) { @@ -965,7 +984,8 @@ e1000_setup_copper_link_generic(struct e1000_hw *hw) } } - /* Check link status. Wait up to 100 microseconds for link to become + /* + * Check link status. Wait up to 100 microseconds for link to become * valid. */ ret_val = e1000_phy_has_link_generic(hw, @@ -995,13 +1015,12 @@ out: * auto-crossover to force MDI manually. Waits for link and returns * successful if link up is successful, else -E1000_ERR_PHY (-2). **/ -s32 -e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) +s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 phy_data; - boolean_t link; + bool link; DEBUGFUNC("e1000_phy_force_speed_duplex_igp"); @@ -1015,7 +1034,8 @@ e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) if (ret_val) goto out; - /* Clear Auto-Crossover to force MDI manually. IGP requires MDI + /* + * Clear Auto-Crossover to force MDI manually. IGP requires MDI * forced whenever speed and duplex are forced. */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); @@ -1033,7 +1053,7 @@ e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) usec_delay(1); - if (phy->wait_for_link) { + if (phy->autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link on IGP phy.\n"); ret_val = e1000_phy_has_link_generic(hw, @@ -1067,20 +1087,20 @@ out: * Calls the PHY setup function to force speed and duplex. Clears the * auto-crossover to force MDI manually. Resets the PHY to commit the * changes. If time expires while waiting for link up, we reset the DSP. - * After reset, TX_CLK and CRS on TX must be set. Return successful upon + * After reset, TX_CLK and CRS on Tx must be set. Return successful upon * successful completion, else return corresponding error code. **/ -s32 -e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) +s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 phy_data; - boolean_t link; + bool link; DEBUGFUNC("e1000_phy_force_speed_duplex_m88"); - /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI + /* + * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed and duplex are forced. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); @@ -1109,7 +1129,7 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) usec_delay(1); - if (phy->wait_for_link) { + if (phy->autoneg_wait_to_complete) { DEBUGOUT("Waiting for forced speed/duplex link on M88 phy.\n"); ret_val = e1000_phy_has_link_generic(hw, @@ -1120,7 +1140,8 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; if (!link) { - /* We didn't get link. + /* + * We didn't get link. * Reset the DSP and cross our fingers. */ ret_val = e1000_write_phy_reg(hw, @@ -1146,7 +1167,8 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) if (ret_val) goto out; - /* Resetting the phy means we need to re-force TX_CLK in the + /* + * Resetting the phy means we need to re-force TX_CLK in the * Extended PHY Specific Control Register to 25MHz clock from * the reset value of 2.5MHz. */ @@ -1155,7 +1177,8 @@ e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) if (ret_val) goto out; - /* In addition, we must re-enable CRS on Tx for both half and full + /* + * In addition, we must re-enable CRS on Tx for both half and full * duplex. */ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); @@ -1181,8 +1204,7 @@ out: * caller must write to the PHY_CONTROL register for these settings to * take affect. **/ -void -e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) +void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) { struct e1000_mac_info *mac = &hw->mac; u32 ctrl; @@ -1190,7 +1212,7 @@ e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) DEBUGFUNC("e1000_phy_force_speed_duplex_setup"); /* Turn off flow control when forcing speed/duplex */ - mac->fc = e1000_fc_none; + hw->fc.type = e1000_fc_none; /* Force speed/duplex on the mac */ ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -1246,8 +1268,7 @@ e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) * During driver activity, SmartSpeed should be enabled so performance is * maintained. **/ -s32 -e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, boolean_t active) +s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1266,10 +1287,12 @@ e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, boolean_t active) data); if (ret_val) goto out; - /* LPLU and SmartSpeed are mutually exclusive. LPLU is used + /* + * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable - * SmartSpeed, so performance is maintained. */ + * SmartSpeed, so performance is maintained. + */ if (phy->smart_speed == e1000_smart_speed_on) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, @@ -1332,8 +1355,7 @@ out: * * A downshift is detected by querying the PHY link health. **/ -s32 -e1000_check_downshift_generic(struct e1000_hw *hw) +s32 e1000_check_downshift_generic(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1377,8 +1399,7 @@ out: * * Polarity is determined based on the PHY specific status register. **/ -s32 -e1000_check_polarity_m88(struct e1000_hw *hw) +s32 e1000_check_polarity_m88(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1405,8 +1426,7 @@ e1000_check_polarity_m88(struct e1000_hw *hw) * Polarity is determined based on the PHY port status register, and the * current speed (since there is no polarity at 100Mbps). **/ -s32 -e1000_check_polarity_igp(struct e1000_hw *hw) +s32 e1000_check_polarity_igp(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1414,8 +1434,10 @@ e1000_check_polarity_igp(struct e1000_hw *hw) DEBUGFUNC("e1000_check_polarity_igp"); - /* Polarity is determined based on the speed of - * our connection. */ + /* + * Polarity is determined based on the speed of + * our connection. + */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); if (ret_val) goto out; @@ -1425,7 +1447,8 @@ e1000_check_polarity_igp(struct e1000_hw *hw) offset = IGP01E1000_PHY_PCS_INIT_REG; mask = IGP01E1000_PHY_POLARITY_MASK; } else { - /* This really only applies to 10Mbps since + /* + * This really only applies to 10Mbps since * there is no polarity for 100Mbps (always 0). */ offset = IGP01E1000_PHY_PORT_STATUS; @@ -1450,8 +1473,7 @@ out: * Waits for auto-negotiation to complete or for the auto-negotiation time * limit to expire, which ever happens first. **/ -s32 -e1000_wait_autoneg_generic(struct e1000_hw *hw) +s32 e1000_wait_autoneg_generic(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 i, phy_status; @@ -1471,7 +1493,8 @@ e1000_wait_autoneg_generic(struct e1000_hw *hw) msec_delay(100); } - /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation + /* + * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation * has completed. */ return ret_val; @@ -1486,9 +1509,8 @@ e1000_wait_autoneg_generic(struct e1000_hw *hw) * * Polls the PHY status register for link, 'iterations' number of times. **/ -s32 -e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, - u32 usec_interval, boolean_t *success) +s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, + u32 usec_interval, bool *success) { s32 ret_val = E1000_SUCCESS; u16 i, phy_status; @@ -1496,7 +1518,8 @@ e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, DEBUGFUNC("e1000_phy_has_link_generic"); for (i = 0; i < iterations; i++) { - /* Some PHYs require the PHY_STATUS register to be read + /* + * Some PHYs require the PHY_STATUS register to be read * twice due to the link bit being sticky. No harm doing * it across the board. */ @@ -1534,8 +1557,7 @@ e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, * 3 110 - 140 meters * 4 > 140 meters **/ -s32 -e1000_get_cable_length_m88(struct e1000_hw *hw) +s32 e1000_get_cable_length_m88(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1569,11 +1591,10 @@ out: * into a lookup table to obtain the approximate cable length * for each channel. **/ -s32 -e1000_get_cable_length_igp_2(struct e1000_hw *hw) +s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 phy_data, i, agc_value = 0; u16 cur_agc_index, max_agc_index = 0; u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; @@ -1591,10 +1612,12 @@ e1000_get_cable_length_igp_2(struct e1000_hw *hw) if (ret_val) goto out; - /* Getting bits 15:9, which represent the combination of + /* + * Getting bits 15:9, which represent the combination of * course and fine gain values. The result is a number * that can be put into the lookup table to obtain the - * approximate cable length. */ + * approximate cable length. + */ cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) & IGP02E1000_AGC_LENGTH_MASK; @@ -1641,17 +1664,16 @@ out: * special status register to determine MDI/MDIx and current speed. If * speed is 1000, then determine cable length, local and remote receiver. **/ -s32 -e1000_get_phy_info_m88(struct e1000_hw *hw) +s32 e1000_get_phy_info_m88(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 phy_data; - boolean_t link; + bool link; DEBUGFUNC("e1000_get_phy_info_m88"); - if (hw->media_type != e1000_media_type_copper) { + if (hw->phy.media_type != e1000_media_type_copper) { DEBUGOUT("Phy info is only valid for copper media\n"); ret_val = -E1000_ERR_CONFIG; goto out; @@ -1721,13 +1743,12 @@ out: * PHY port status to determine MDI/MDIx and speed. Based on the speed, * determine on the cable length, local and remote receiver. **/ -s32 -e1000_get_phy_info_igp(struct e1000_hw *hw) +s32 e1000_get_phy_info_igp(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 data; - boolean_t link; + bool link; DEBUGFUNC("e1000_get_phy_info_igp"); @@ -1787,8 +1808,7 @@ out: * Does a software reset of the PHY by reading the PHY control register and * setting/write the control register reset bit to the PHY. **/ -s32 -e1000_phy_sw_reset_generic(struct e1000_hw *hw) +s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw) { s32 ret_val; u16 phy_ctrl; @@ -1819,8 +1839,7 @@ out: * bit in the PHY. Wait the appropriate delay time for the device to * reset and relase the semaphore (if necessary). **/ -s32 -e1000_phy_hw_reset_generic(struct e1000_hw *hw) +s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -1864,10 +1883,10 @@ out: * Generic function to wait 10 milli-seconds for configuration to complete * and return success. **/ -s32 -e1000_get_cfg_done_generic(struct e1000_hw *hw) +s32 e1000_get_cfg_done_generic(struct e1000_hw *hw) { DEBUGFUNC("e1000_get_cfg_done_generic"); + UNREFERENCED_PARAMETER(hw); msec_delay_irq(10); @@ -1883,13 +1902,12 @@ e1000_get_cfg_done_generic(struct e1000_hw *hw) * Return success if silicon family did not implement a family specific * get_cfg_done function. **/ -s32 -e1000_get_phy_cfg_done(struct e1000_hw *hw) +s32 e1000_get_phy_cfg_done(struct e1000_hw *hw) { - if (hw->func.get_cfg_done != NULL) + if (hw->func.get_cfg_done) return hw->func.get_cfg_done(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1899,10 +1917,9 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) * Return if silicon family does not require a semaphore when accessing the * PHY. **/ -void -e1000_release_phy(struct e1000_hw *hw) +void e1000_release_phy(struct e1000_hw *hw) { - if (hw->func.release_phy != NULL) + if (hw->func.release_phy) hw->func.release_phy(hw); } @@ -1913,13 +1930,12 @@ e1000_release_phy(struct e1000_hw *hw) * Return success if silicon family does not require a semaphore when * accessing the PHY. **/ -s32 -e1000_acquire_phy(struct e1000_hw *hw) +s32 e1000_acquire_phy(struct e1000_hw *hw) { - if (hw->func.acquire_phy != NULL) + if (hw->func.acquire_phy) return hw->func.acquire_phy(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1929,13 +1945,12 @@ e1000_acquire_phy(struct e1000_hw *hw) * When the silicon family has not implemented a forced speed/duplex * function for the PHY, simply return E1000_SUCCESS. **/ -s32 -e1000_phy_force_speed_duplex(struct e1000_hw *hw) +s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw) { - if (hw->func.force_speed_duplex != NULL) + if (hw->func.force_speed_duplex) return hw->func.force_speed_duplex(hw); - else - return E1000_SUCCESS; + + return E1000_SUCCESS; } /** @@ -1944,8 +1959,7 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) * * Initializes a Intel Gigabit PHY3 when an EEPROM is not present. **/ -s32 -e1000_phy_init_script_igp3(struct e1000_hw *hw) +s32 e1000_phy_init_script_igp3(struct e1000_hw *hw) { DEBUGOUT("Running IGP 3 PHY init script\n"); @@ -1958,7 +1972,7 @@ e1000_phy_init_script_igp3(struct e1000_hw *hw) e1000_write_phy_reg(hw, 0x2FB1, 0x8B24); /* Increase Hybrid poly bias */ e1000_write_phy_reg(hw, 0x2FB2, 0xF8F0); - /* Add 4% to TX amplitude in Giga mode */ + /* Add 4% to Tx amplitude in Giga mode */ e1000_write_phy_reg(hw, 0x2010, 0x10B0); /* Disable trimming (TTT) */ e1000_write_phy_reg(hw, 0x2011, 0x0000); @@ -2002,13 +2016,15 @@ e1000_phy_init_script_igp3(struct e1000_hw *hw) e1000_write_phy_reg(hw, 0x1796, 0x0008); /* Change cg_icount + enable integbp for channels BCD */ e1000_write_phy_reg(hw, 0x1798, 0xD008); - /* Change cg_icount + enable integbp + change prop_factor_master + /* + * Change cg_icount + enable integbp + change prop_factor_master * to 8 for channel A */ e1000_write_phy_reg(hw, 0x1898, 0xD918); /* Disable AHT in Slave mode on channel A */ e1000_write_phy_reg(hw, 0x187A, 0x0800); - /* Enable LPLU and disable AN to 1000 in non-D0a states, + /* + * Enable LPLU and disable AN to 1000 in non-D0a states, * Enable SPD+B2B */ e1000_write_phy_reg(hw, 0x0019, 0x008D); @@ -2028,8 +2044,7 @@ e1000_phy_init_script_igp3(struct e1000_hw *hw) * * Returns the phy type from the id. **/ -e1000_phy_type -e1000_get_phy_type_from_id(u32 phy_id) +e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id) { e1000_phy_type phy_type = e1000_phy_unknown; @@ -2061,4 +2076,39 @@ e1000_get_phy_type_from_id(u32 phy_id) return phy_type; } +/** + * e1000_power_up_phy_copper - Restore copper link in case of PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, restore the link to previous + * settings. + **/ +void e1000_power_up_phy_copper(struct e1000_hw *hw) +{ + u16 mii_reg = 0; + /* The PHY will retain its settings across a power down/up cycle */ + e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg); + mii_reg &= ~MII_CR_POWER_DOWN; + e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg); +} + +/** + * e1000_power_down_phy_copper - Restore copper link in case of PHY power down + * @hw: pointer to the HW structure + * + * In the case of a PHY power down to save power, or to turn off link during a + * driver unload, or wake on lan is not enabled, restore the link to previous + * settings. + **/ +void e1000_power_down_phy_copper(struct e1000_hw *hw) +{ + u16 mii_reg = 0; + + /* The PHY will retain its settings across a power down/up cycle */ + e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg); + mii_reg |= MII_CR_POWER_DOWN; + e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg); + msec_delay(1); +} diff --git a/sys/dev/em/e1000_phy.h b/sys/dev/em/e1000_phy.h index 3be660a5e0ce..4fa91e03ce7b 100644 --- a/sys/dev/em/e1000_phy.h +++ b/sys/dev/em/e1000_phy.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_PHY_H_ @@ -73,7 +73,7 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw); s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); -s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, boolean_t active); +s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active); s32 e1000_setup_copper_link_generic(struct e1000_hw *hw); s32 e1000_wait_autoneg_generic(struct e1000_hw *hw); s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data); @@ -81,9 +81,12 @@ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_phy_reset_dsp(struct e1000_hw *hw); s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, - u32 usec_interval, boolean_t *success); + u32 usec_interval, bool *success); s32 e1000_phy_init_script_igp3(struct e1000_hw *hw); e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id); +void e1000_power_up_phy_copper(struct e1000_hw *hw); +void e1000_power_down_phy_copper(struct e1000_hw *hw); + #define E1000_MAX_PHY_ADDR 4 /* IGP01E1000 Specific Registers */ @@ -95,17 +98,10 @@ e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id); #define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */ #define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ -#define IGP4_PHY_PAGE_SELECT 22 /* Page Select for IGP 4 */ +#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ #define IGP_PAGE_SHIFT 5 #define PHY_REG_MASK 0x1F -#define IGP4_WUC_PAGE 800 -#define IGP4_WUC_ADDRESS_OPCODE 0x11 -#define IGP4_WUC_DATA_OPCODE 0x12 -#define IGP4_WUC_ENABLE_PAGE 769 -#define IGP4_WUC_ENABLE_REG 17 -#define IGP4_WUC_ENABLE_BIT (1 << 2) -#define IGP4_WUC_HOST_WU_BIT (1 << 4) #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 #define IGP01E1000_PHY_POLARITY_MASK 0x0078 @@ -115,8 +111,8 @@ e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id); #define IGP01E1000_PSCFR_SMART_SPEED 0x0080 -#define IGP01E1000_GMII_FLEX_SPD 0x0010 /* Enable flexible speed - * on link-up */ +/* Enable flexible speed on link-up */ +#define IGP01E1000_GMII_FLEX_SPD 0x0010 #define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */ #define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ diff --git a/sys/dev/em/e1000_regs.h b/sys/dev/em/e1000_regs.h index e2bde1ee203f..bfc641b63b47 100644 --- a/sys/dev/em/e1000_regs.h +++ b/sys/dev/em/e1000_regs.h @@ -30,7 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ -/*$FreeBSD$*/ +/* $FreeBSD$ */ #ifndef _E1000_REGS_H_ @@ -57,36 +57,21 @@ #define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ #define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ #define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ -#define E1000_RCTL 0x00100 /* RX Control - RW */ -#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */ -#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */ -#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */ -#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */ -#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */ -#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */ +#define E1000_RCTL 0x00100 /* Rx Control - RW */ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ -#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ -#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */ +#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */ +#define E1000_RXCW 0x00180 /* Rx Configuration Word - RO */ #define E1000_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ -#define E1000_EITR0 0x01680 /* Ext. Int. Throttling Rate Vector 0 - RW */ -#define E1000_EITR1 0x01684 /* Ext. Int. Throttling Rate Vector 1 - RW */ -#define E1000_EITR2 0x01688 /* Ext. Int. Throttling Rate Vector 2 - RW */ -#define E1000_EITR3 0x0168C /* Ext. Int. Throttling Rate Vector 3 - RW */ -#define E1000_EITR4 0x01690 /* Ext. Int. Throttling Rate Vector 4 - RW */ -#define E1000_EITR5 0x01694 /* Ext. Int. Throttling Rate Vector 5 - RW */ -#define E1000_EITR6 0x01698 /* Ext. Int. Throttling Rate Vector 6 - RW */ -#define E1000_EITR7 0x0169C /* Ext. Int. Throttling Rate Vector 7 - RW */ -#define E1000_EITR8 0x016A0 /* Ext. Int. Throttling Rate Vector 8 - RW */ -#define E1000_EITR9 0x016A4 /* Ext. Int. Throttling Rate Vector 9 - RW */ +#define E1000_EITR(_n) (0x01680 + (0x4 * (_n))) #define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ #define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ #define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ #define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */ #define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */ -#define E1000_TCTL 0x00400 /* TX Control - RW */ -#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */ -#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */ -#define E1000_TBT 0x00448 /* TX Burst Timer - RW */ +#define E1000_TCTL 0x00400 /* Tx Control - RW */ +#define E1000_TCTL_EXT 0x00404 /* Extended Tx Control - RW */ +#define E1000_TIPG 0x00410 /* Tx Inter-packet gap -RW */ +#define E1000_TBT 0x00448 /* Tx Burst Timer - RW */ #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ #define E1000_LEDCTL 0x00E00 /* LED Control - RW */ #define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ @@ -112,137 +97,70 @@ #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ #define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ -#define E1000_RDFPCQ0 0x02430 -#define E1000_RDFPCQ1 0x02434 -#define E1000_RDFPCQ2 0x02438 -#define E1000_RDFPCQ3 0x0243C -#define E1000_PBRTH 0x02458 /* PB RX Arbitration Threshold - RW */ +#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n))) +#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */ #define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */ -#define E1000_SRRCTL0 0x0280C -#define E1000_SRRCTL(_n) (0x280C + (_n << 8)) /* Split and Replication - * RX Control - RW */ -#define E1000_RDPUMB 0x025CC /* DMA RX Descriptor uC Mailbox - RW */ -#define E1000_RDPUAD 0x025D0 /* DMA RX Descriptor uC Addr Command - RW */ -#define E1000_RDPUWD 0x025D4 /* DMA RX Descriptor uC Data Write - RW */ -#define E1000_RDPURD 0x025D8 /* DMA RX Descriptor uC Data Read - RW */ -#define E1000_RDPUCTL 0x025DC /* DMA RX Descriptor uC Control - RW */ -#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ -#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ -#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ -#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */ -#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */ -#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */ -#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */ -#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */ -#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */ -#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */ -#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */ -#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */ -#define E1000_RXDCTL 0x02828 /* RX Descriptor Control queue 0 - RW */ -#define E1000_RXDCTL1 0x02928 /* RX Descriptor Control queue 1 - RW */ -#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ -/* Convenience macros +/* Split and Replication Rx Control - RW */ +#define E1000_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */ +#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */ +#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */ +#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */ +#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */ +#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */ +#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */ +/* + * Convenience macros * * Note: "_n" is the queue number of the register to be written to. * * Example usage: * E1000_RDBAL_REG(current_rx_queue) - * */ -#define E1000_RDBAL_REG(_n) (E1000_RDBAL + (_n << 8)) -#define E1000_RDBAH_REG(_n) (E1000_RDBAH + (_n << 8)) -#define E1000_RDLEN_REG(_n) (E1000_RDLEN + (_n << 8)) -#define E1000_RDH_REG(_n) (E1000_RDH + (_n << 8)) -#define E1000_RDT_REG(_n) (E1000_RDT + (_n << 8)) -#define E1000_RXDCTL_REG(_n) (E1000_RXDCTL + (_n << 8)) -#define E1000_TDBAL_REG(_n) (E1000_TDBAL + (_n << 8)) -#define E1000_TDBAH_REG(_n) (E1000_TDBAH + (_n << 8)) -#define E1000_TDLEN_REG(_n) (E1000_TDLEN + (_n << 8)) -#define E1000_TDH_REG(_n) (E1000_TDH + (_n << 8)) -#define E1000_TDT_REG(_n) (E1000_TDT + (_n << 8)) -#define E1000_TXDCTL_REG(_n) (E1000_TXDCTL + (_n << 8)) -#define E1000_TARC_REG(_n) (E1000_TARC0 + (_n << 8)) +#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : (0x0C000 + ((_n) * 0x40))) +#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : (0x0C004 + ((_n) * 0x40))) +#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : (0x0C008 + ((_n) * 0x40))) +#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : (0x0C00C + ((_n) * 0x40))) +#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : (0x0C010 + ((_n) * 0x40))) +#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : (0x0C018 + ((_n) * 0x40))) +#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : (0x0C028 + ((_n) * 0x40))) +#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : (0x0E000 + ((_n) * 0x40))) +#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : (0x0E004 + ((_n) * 0x40))) +#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : (0x0E008 + ((_n) * 0x40))) +#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : (0x0E010 + ((_n) * 0x40))) +#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : (0x0E018 + ((_n) * 0x40))) +#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : (0x0E028 + ((_n) * 0x40))) +#define E1000_TARC(_n) (0x03840 + (_n << 8)) +#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) #define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) -#define E1000_DCA_RXCTRL0 0x02814 /* RX Queue 0 DCA CTRL - RW */ -#define E1000_DCA_RXCTRL1 0x02914 /* RX Queue 1 DCA CTRL - RW */ -#define E1000_RDBAL2 0x02A00 /* RX Descriptor Base Low Queue 2 - RW */ -#define E1000_RDBAH2 0x02A04 /* RX Descriptor Base High Queue 2 - RW */ -#define E1000_RDLEN2 0x02A08 /* RX Descriptor Length Queue 2 - RW */ -#define E1000_RDH2 0x02A10 /* RX Descriptor Head Queue 2 - RW */ -#define E1000_DCA_RXCTRL2 0x02A14 /* RX Queue 2 DCA CTRL - RW */ -#define E1000_RDT2 0x02A18 /* RX Descriptor Tail Queue 2 - RW */ -#define E1000_RXDCTL2 0x02A28 /* RX Descriptor Control queue 2 - RW */ -#define E1000_RDBAL3 0x02B00 /* RX Descriptor Base Low Queue 3 - RW */ -#define E1000_RDBAH3 0x02B04 /* RX Descriptor Base High Queue 3 - RW */ -#define E1000_RDLEN3 0x02B08 /* RX Descriptor Length Queue 3 - RW */ -#define E1000_RDH3 0x02B10 /* RX Descriptor Head Queue 3 - RW */ -#define E1000_DCA_RXCTRL3 0x02B14 /* RX Queue 3 DCA Control - RW */ -#define E1000_RDT3 0x02B18 /* RX Descriptor Tail Queue 3 - RW */ -#define E1000_RXDCTL3 0x02B28 /* RX Descriptor Control Queue 3 - RW */ -#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ +#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : (0x0E038 + ((_n) * 0x40))) +#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : (0x0E03C + ((_n) * 0x40))) +#define E1000_RSRPD 0x02C00 /* Rx Small Packet Detect - RW */ #define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ -#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ +#define E1000_TXDMAC 0x03000 /* Tx DMA Control - RW */ #define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */ -#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ -#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ -#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */ -#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */ -#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */ -#define E1000_TDPUMB 0x0357C /* DMA TX Descriptor uC Mail Box - RW */ -#define E1000_TDPUAD 0x03580 /* DMA TX Descriptor uC Addr Command - RW */ -#define E1000_TDPUWD 0x03584 /* DMA TX Descriptor uC Data Write - RW */ -#define E1000_TDPURD 0x03588 /* DMA TX Descriptor uC Data Read - RW */ -#define E1000_TDPUCTL 0x0358C /* DMA TX Descriptor uC Control - RW */ -#define E1000_DTXCTL 0x03590 /* DMA TX Control - RW */ -#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */ -#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */ -#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */ -#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */ -#define E1000_TDT 0x03818 /* TX Descriptor Tail - RW */ -#define E1000_TDBAL0 E1000_TDBAL /* TX Descriptor Base Address Low - RW */ -#define E1000_TDBAH0 E1000_TDBAH /* TX Descriptor Base Address High - RW */ -#define E1000_TDLEN0 E1000_TDLEN /* TX Descriptor Length - RW */ -#define E1000_TDH0 E1000_TDH /* TX Descriptor Head - RW */ -#define E1000_TDT0 E1000_TDT /* TX Descriptor Tail - RW */ -#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */ -#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */ -#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */ +#define E1000_PSRTYPE_REG(_i) (0x05480 + ((_i) * 4)) +#define E1000_RAL(_i) (0x05400 + ((_i) * 8)) +#define E1000_RAH(_i) (0x05404 + ((_i) * 8)) +#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8)) +#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4)) +#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4)) +#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8)) +#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8)) +#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8)) +#define E1000_TDFH 0x03410 /* Tx Data FIFO Head - RW */ +#define E1000_TDFT 0x03418 /* Tx Data FIFO Tail - RW */ +#define E1000_TDFHS 0x03420 /* Tx Data FIFO Head Saved - RW */ +#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */ +#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */ +#define E1000_TDPUMB 0x0357C /* DMA Tx Descriptor uC Mail Box - RW */ +#define E1000_TDPUAD 0x03580 /* DMA Tx Descriptor uC Addr Command - RW */ +#define E1000_TDPUWD 0x03584 /* DMA Tx Descriptor uC Data Write - RW */ +#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */ +#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */ +#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */ +#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */ +#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */ #define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */ -#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */ -#define E1000_DCA_TXCTRL0 0x03814 /* TX Queue 0 DCA CTRL - RW */ -#define E1000_TDWBAL0 0x03838 /* TX Desc. WB Addr Low Queue 0 - RW */ -#define E1000_TDWBAH0 0x0383C /* TX Desc. WB Addr High Queue 0 - RW */ -#define E1000_DCA_TXCTRL(_n) (E1000_DCA_TXCTRL0 + (_n << 8)) -#define E1000_TDWBAL_REG(_n) (E1000_TDWBAL0 + (_n << 8)) -#define E1000_TDWBAH_REG(_n) (E1000_TDWBAH0 + (_n << 8)) -#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */ -#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */ -#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */ -#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */ -#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */ -#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */ -#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */ -#define E1000_DCA_TXCTRL1 0x03914 /* TX Queue 0 DCA CTRL - RW */ -#define E1000_TDWBAL1 0x03938 /* TX Descriptor WB Addr Low Queue 1 - RW */ -#define E1000_TDWBAH1 0x0393C /* TX Descriptor WB Addr High Queue 1 - RW */ -#define E1000_TDBAL2 0x03A00 /* TX Descriptor Base Low Queue 2 - RW */ -#define E1000_TDBAH2 0x03A04 /* TX Descriptor Base High Queue 2 - RW */ -#define E1000_TDLEN2 0x03A08 /* TX Descriptor Length Queue 2 - RW */ -#define E1000_TDH2 0x03A10 /* TX Descriptor Head Queue 2 - RW */ -#define E1000_DCA_TXCTRL2 0x03A14 /* TX Queue 2 DCA Control - RW */ -#define E1000_TDT2 0x03A18 /* TX Descriptor Tail Queue 2 - RW */ -#define E1000_TXDCTL2 0x03A28 /* TX Descriptor Control 2 - RW */ -#define E1000_TDWBAL2 0x03A38 /* TX Descriptor WB Addr Low Queue 2 - RW */ -#define E1000_TDWBAH2 0x03A3C /* TX Descriptor WB Addr High Queue 2 - RW */ -#define E1000_TDBAL3 0x03B00 /* TX Descriptor Base Low Queue 3 - RW */ -#define E1000_TDBAH3 0x03B04 /* TX Descriptor Base High Queue 3 - RW */ -#define E1000_TDLEN3 0x03B08 /* TX Descriptor Length Queue 3 - RW */ -#define E1000_TDH3 0x03B10 /* TX Descriptor Head Queue 3 - RW */ -#define E1000_DCA_TXCTRL3 0x03B14 /* TX Queue 3 DCA Control - RW */ -#define E1000_TDT3 0x03B18 /* TX Descriptor Tail Queue 3 - RW */ -#define E1000_TXDCTL3 0x03B28 /* TX Descriptor Control 3 - RW */ -#define E1000_TDWBAL3 0x03B38 /* TX Descriptor WB Addr Low Queue 3 - RW */ -#define E1000_TDWBAH3 0x03B3C /* TX Descriptor WB Addr High Queue 3 - RW */ #define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ #define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ #define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ @@ -254,53 +172,53 @@ #define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ #define E1000_COLC 0x04028 /* Collision Count - R/clr */ #define E1000_DC 0x04030 /* Defer Count - R/clr */ -#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */ +#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */ #define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */ #define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */ #define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ -#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */ -#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */ -#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */ -#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */ -#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */ -#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */ -#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */ -#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */ -#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */ -#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */ -#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */ -#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */ -#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */ -#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */ -#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */ -#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */ -#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */ -#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */ -#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */ -#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */ -#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */ -#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */ -#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */ -#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */ -#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */ +#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */ +#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */ +#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */ +#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */ +#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */ +#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */ +#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */ +#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */ +#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */ +#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */ +#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */ +#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */ +#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */ +#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */ +#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */ +#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */ +#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */ +#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */ +#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */ +#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */ +#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */ +#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */ +#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */ +#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */ +#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */ #define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */ -#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */ -#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */ -#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */ -#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */ -#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */ -#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */ -#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */ -#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */ -#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */ -#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */ -#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */ -#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */ -#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */ -#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */ -#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ -#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ -#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */ +#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */ +#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */ +#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */ +#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */ +#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */ +#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */ +#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */ +#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */ +#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */ +#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */ +#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */ +#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */ +#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */ +#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */ +#define E1000_BPTC 0x040F4 /* Broadcast Packets Tx Count - R/clr */ +#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context Tx - R/clr */ +#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context Tx Fail - R/clr */ #define E1000_IAC 0x04100 /* Interrupt Assertion Count */ #define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */ #define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */ @@ -310,16 +228,57 @@ #define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */ #define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */ #define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */ + +#define E1000_LSECTXUT 0x04300 /* LinkSec Tx Untagged Packet Count - OutPktsUntagged */ +#define E1000_LSECTXPKTE 0x04304 /* LinkSec Encrypted Tx Packets Count - OutPktsEncrypted */ +#define E1000_LSECTXPKTP 0x04308 /* LinkSec Protected Tx Packet Count - OutPktsProtected */ +#define E1000_LSECTXOCTE 0x0430C /* LinkSec Encrypted Tx Octets Count - OutOctetsEncrypted */ +#define E1000_LSECTXOCTP 0x04310 /* LinkSec Protected Tx Octets Count - OutOctetsProtected */ +#define E1000_LSECRXUT 0x04314 /* LinkSec Untagged non-Strict Rx Packet Count - InPktsUntagged/InPktsNoTag */ +#define E1000_LSECRXOCTD 0x0431C /* LinkSec Rx Octets Decrypted Count - InOctetsDecrypted */ +#define E1000_LSECRXOCTV 0x04320 /* LinkSec Rx Octets Validated - InOctetsValidated */ +#define E1000_LSECRXBAD 0x04324 /* LinkSec Rx Bad Tag - InPktsBadTag */ +#define E1000_LSECRXNOSCI 0x04328 /* LinkSec Rx Packet No SCI Count - InPktsNoSci */ +#define E1000_LSECRXUNSCI 0x0432C /* LinkSec Rx Packet Unknown SCI Count - InPktsUnknownSci */ +#define E1000_LSECRXUNCH 0x04330 /* LinkSec Rx Unchecked Packets Count - InPktsUnchecked */ +#define E1000_LSECRXDELAY 0x04340 /* LinkSec Rx Delayed Packet Count - InPktsDelayed */ +#define E1000_LSECRXLATE 0x04350 /* LinkSec Rx Late Packets Count - InPktsLate */ +#define E1000_LSECRXOK(_n) (0x04360 + (0x04 * (_n))) /* LinkSec Rx Packet OK Count - InPktsOk */ +#define E1000_LSECRXINV(_n) (0x04380 + (0x04 * (_n))) /* LinkSec Rx Invalid Count - InPktsInvalid */ +#define E1000_LSECRXNV(_n) (0x043A0 + (0x04 * (_n))) /* LinkSec Rx Not Valid Count - InPktsNotValid */ +#define E1000_LSECRXUNSA 0x043C0 /* LinkSec Rx Unused SA Count - InPktsUnusedSa */ +#define E1000_LSECRXNUSA 0x043D0 /* LinkSec Rx Not Using SA Count - InPktsNotUsingSa */ +#define E1000_LSECTXCAP 0x0B000 /* LinkSec Tx Capabilities Register - RO */ +#define E1000_LSECRXCAP 0x0B300 /* LinkSec Rx Capabilities Register - RO */ +#define E1000_LSECTXCTRL 0x0B004 /* LinkSec Tx Control - RW */ +#define E1000_LSECRXCTRL 0x0B304 /* LinkSec Rx Control - RW */ +#define E1000_LSECTXSCIL 0x0B008 /* LinkSec Tx SCI Low - RW */ +#define E1000_LSECTXSCIH 0x0B00C /* LinkSec Tx SCI High - RW */ +#define E1000_LSECTXSA 0x0B010 /* LinkSec Tx SA0 - RW */ +#define E1000_LSECTXPN0 0x0B018 /* LinkSec Tx SA PN 0 - RW */ +#define E1000_LSECTXPN1 0x0B01C /* LinkSec Tx SA PN 1 - RW */ +#define E1000_LSECRXSCL 0x0B3D0 /* LinkSec Rx SCI Low - RW */ +#define E1000_LSECRXSCH 0x0B3E0 /* LinkSec Rx SCI High - RW */ +#define E1000_LSECTXKEY0(_n) (0x0B020 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 0 - WO */ +#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n))) /* LinkSec Tx 128-bit Key 1 - WO */ +#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */ +#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* LinkSec Rx SAs - RW */ +/* + * LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit + * key - RW. + */ +#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m))) + #define E1000_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */ #define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */ #define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */ -#define E1000_CBTMPC 0x0402C /* Circuit Breaker TX Packet Count */ +#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */ #define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */ -#define E1000_CBRDPC 0x04044 /* Circuit Breaker RX Dropped Count */ -#define E1000_CBRMPC 0x040FC /* Circuit Breaker RX Packet Count */ +#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */ +#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */ #define E1000_RPTHC 0x04104 /* Rx Packets To Host */ -#define E1000_HGPTC 0x04118 /* Host Good Packets TX Count */ -#define E1000_HTCBDPC 0x04124 /* Host TX Circuit Breaker Dropped Count */ +#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */ +#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */ #define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */ #define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */ #define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */ @@ -332,8 +291,8 @@ #define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */ #define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */ #define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */ -#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ -#define E1000_RLPML 0x05004 /* RX Long Packet Max Length */ +#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */ +#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */ #define E1000_RFCTL 0x05008 /* Receive Filter Control*/ #define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ #define E1000_RA 0x05400 /* Receive Address - RW Array */ @@ -351,6 +310,7 @@ #define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ #define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ #define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ +#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */ #define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ #define E1000_HOST_IF 0x08800 /* Host Interface */ #define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ @@ -381,60 +341,15 @@ #define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */ #define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */ #define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/ -#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt RX VLAN Priority - RW */ -#define E1000_MSIXBM0 0x01600 /* MSI-X Allocation Register 0 - RW */ -#define E1000_MSIXBM1 0x01604 /* MSI-X Allocation Register 1 - RW */ -#define E1000_MSIXBM2 0x01608 /* MSI-X Allocation Register 2 - RW */ -#define E1000_MSIXBM3 0x0160C /* MSI-X Allocation Register 3 - RW */ -#define E1000_MSIXBM4 0x01610 /* MSI-X Allocation Register 4 - RW */ -#define E1000_MSIXBM5 0x01614 /* MSI-X Allocation Register 5 - RW */ -#define E1000_MSIXBM6 0x01618 /* MSI-X Allocation Register 6 - RW */ -#define E1000_MSIXBM7 0x0161C /* MSI-X Allocation Register 7 - RW */ -#define E1000_MSIXBM8 0x01620 /* MSI-X Allocation Register 8 - RW */ -#define E1000_MSIXBM9 0x01624 /* MSI-X Allocation Register 9 - RW */ -#define E1000_MSIXTADD0 0x0C000 /* MSI-X Table entry addr low reg 0 - RW */ -#define E1000_MSIXTADD1 0x0C010 /* MSI-X Table entry addr low reg 1 - RW */ -#define E1000_MSIXTADD2 0x0C020 /* MSI-X Table entry addr low reg 2 - RW */ -#define E1000_MSIXTADD3 0x0C030 /* MSI-X Table entry addr low reg 3 - RW */ -#define E1000_MSIXTADD4 0x0C040 /* MSI-X Table entry addr low reg 4 - RW */ -#define E1000_MSIXTADD5 0x0C050 /* MSI-X Table entry addr low reg 5 - RW */ -#define E1000_MSIXTADD6 0x0C060 /* MSI-X Table entry addr low reg 6 - RW */ -#define E1000_MSIXTADD7 0x0C070 /* MSI-X Table entry addr low reg 7 - RW */ -#define E1000_MSIXTADD8 0x0C080 /* MSI-X Table entry addr low reg 8 - RW */ -#define E1000_MSIXTADD9 0x0C090 /* MSI-X Table entry addr low reg 9 - RW */ -#define E1000_MSIXTUADD0 0x0C004 /* MSI-X Table entry addr upper reg 0 - RW */ -#define E1000_MSIXTUADD1 0x0C014 /* MSI-X Table entry addr upper reg 1 - RW */ -#define E1000_MSIXTUADD2 0x0C024 /* MSI-X Table entry addr upper reg 2 - RW */ -#define E1000_MSIXTUADD3 0x0C034 /* MSI-X Table entry addr upper reg 3 - RW */ -#define E1000_MSIXTUADD4 0x0C044 /* MSI-X Table entry addr upper reg 4 - RW */ -#define E1000_MSIXTUADD5 0x0C054 /* MSI-X Table entry addr upper reg 5 - RW */ -#define E1000_MSIXTUADD6 0x0C064 /* MSI-X Table entry addr upper reg 6 - RW */ -#define E1000_MSIXTUADD7 0x0C074 /* MSI-X Table entry addr upper reg 7 - RW */ -#define E1000_MSIXTUADD8 0x0C084 /* MSI-X Table entry addr upper reg 8 - RW */ -#define E1000_MSIXTUADD9 0x0C094 /* MSI-X Table entry addr upper reg 9 - RW */ -#define E1000_MSIXTMSG0 0x0C008 /* MSI-X Table entry message reg 0 - RW */ -#define E1000_MSIXTMSG1 0x0C018 /* MSI-X Table entry message reg 1 - RW */ -#define E1000_MSIXTMSG2 0x0C028 /* MSI-X Table entry message reg 2 - RW */ -#define E1000_MSIXTMSG3 0x0C038 /* MSI-X Table entry message reg 3 - RW */ -#define E1000_MSIXTMSG4 0x0C048 /* MSI-X Table entry message reg 4 - RW */ -#define E1000_MSIXTMSG5 0x0C058 /* MSI-X Table entry message reg 5 - RW */ -#define E1000_MSIXTMSG6 0x0C068 /* MSI-X Table entry message reg 6 - RW */ -#define E1000_MSIXTMSG7 0x0C078 /* MSI-X Table entry message reg 7 - RW */ -#define E1000_MSIXTMSG8 0x0C088 /* MSI-X Table entry message reg 8 - RW */ -#define E1000_MSIXTMSG9 0x0C098 /* MSI-X Table entry message reg 9 - RW */ -#define E1000_MSIXVCTRL0 0x0C00C /* MSI-X Table entry vector ctrl reg 0 - RW */ -#define E1000_MSIXVCTRL1 0x0C01C /* MSI-X Table entry vector ctrl reg 1 - RW */ -#define E1000_MSIXVCTRL2 0x0C02C /* MSI-X Table entry vector ctrl reg 2 - RW */ -#define E1000_MSIXVCTRL3 0x0C03C /* MSI-X Table entry vector ctrl reg 3 - RW */ -#define E1000_MSIXVCTRL4 0x0C04C /* MSI-X Table entry vector ctrl reg 4 - RW */ -#define E1000_MSIXVCTRL5 0x0C05C /* MSI-X Table entry vector ctrl reg 5 - RW */ -#define E1000_MSIXVCTRL6 0x0C06C /* MSI-X Table entry vector ctrl reg 6 - RW */ -#define E1000_MSIXVCTRL7 0x0C07C /* MSI-X Table entry vector ctrl reg 7 - RW */ -#define E1000_MSIXVCTRL8 0x0C08C /* MSI-X Table entry vector ctrl reg 8 - RW */ -#define E1000_MSIXVCTRL9 0x0C09C /* MSI-X Table entry vector ctrl reg 9 - RW */ +#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt Rx VLAN Priority - RW */ +#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Allocation Register (_i) - RW */ +#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10)) /* MSI-X Table entry addr low reg 0 - RW */ +#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10)) /* MSI-X Table entry addr upper reg 0 - RW */ +#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10)) /* MSI-X Table entry message reg 0 - RW */ +#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10)) /* MSI-X Table entry vector ctrl reg 0 - RW */ #define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */ -#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */ -#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */ +#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW Array */ +#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */ #define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ #define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c index 7a933e69f1cc..de3e1f3a242c 100644 --- a/sys/dev/em/if_em.c +++ b/sys/dev/em/if_em.c @@ -89,7 +89,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "Version - 6.5.3"; +char em_driver_version[] = "Version - 6.7.3"; /********************************************************************* @@ -159,6 +159,8 @@ static em_vendor_info_t em_vendor_info_array[] = PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82571EB_QUAD_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, + { 0x8086, E1000_DEV_ID_82571PT_QUAD_COPPER, + PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82572EI_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82572EI_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82572EI_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, @@ -192,9 +194,6 @@ static em_vendor_info_t em_vendor_info_array[] = { 0x8086, E1000_DEV_ID_82575EB_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82575EB_FIBER_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82575EM_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, - { 0x8086, E1000_DEV_ID_82575EM_FIBER_SERDES, - PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_82575GB_QUAD_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0}, /* required last entry */ @@ -230,12 +229,13 @@ static int em_media_change(struct ifnet *); static void em_identify_hardware(struct adapter *); static int em_allocate_pci_resources(struct adapter *); static int em_allocate_intr(struct adapter *); +static bool em_setup_msix(struct adapter *); static void em_free_intr(struct adapter *); static void em_free_pci_resources(struct adapter *); static void em_local_timer(void *); static int em_hardware_init(struct adapter *); static void em_setup_interface(device_t, struct adapter *); -static int em_setup_transmit_structures(struct adapter *); +static void em_setup_transmit_structures(struct adapter *); static void em_initialize_transmit_unit(struct adapter *); static int em_setup_receive_structures(struct adapter *); static void em_initialize_receive_unit(struct adapter *); @@ -245,6 +245,7 @@ static void em_free_transmit_structures(struct adapter *); static void em_free_receive_structures(struct adapter *); static void em_update_stats_counters(struct adapter *); static void em_txeof(struct adapter *); +static void em_tx_purge(struct adapter *); static int em_allocate_receive_structures(struct adapter *); static int em_allocate_transmit_structures(struct adapter *); static int em_rxeof(struct adapter *, int); @@ -256,16 +257,18 @@ static void em_receive_checksum(struct adapter *, struct e1000_rx_desc *, static void em_transmit_checksum_setup(struct adapter *, struct mbuf *, uint32_t *, uint32_t *); static boolean_t em_tx_adv_ctx_setup(struct adapter *, struct mbuf *); +#if __FreeBSD_version >= 700000 static boolean_t em_tso_setup(struct adapter *, struct mbuf *, uint32_t *, uint32_t *); static boolean_t em_tso_adv_setup(struct adapter *, struct mbuf *, uint32_t *); +#endif /* FreeBSD_version >= 700000 */ static void em_set_promisc(struct adapter *); static void em_disable_promisc(struct adapter *); static void em_set_multi(struct adapter *); static void em_print_hw_stats(struct adapter *); static void em_update_link_status(struct adapter *); static int em_get_buf(struct adapter *, int); -static void em_enable_vlans(struct adapter *); +static void em_enable_hw_vlans(struct adapter *); static int em_encap(struct adapter *, struct mbuf **); static int em_adv_encap(struct adapter *, struct mbuf **); static void em_smartspeed(struct adapter *); @@ -277,6 +280,7 @@ static int em_dma_malloc(struct adapter *, bus_size_t, struct em_dma_alloc *, int); static void em_dma_free(struct adapter *, struct em_dma_alloc *); static void em_print_debug_info(struct adapter *); +static void em_print_nvm_info(struct adapter *); static int em_is_valid_ether_addr(uint8_t *); static int em_sysctl_stats(SYSCTL_HANDLER_ARGS); static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS); @@ -292,16 +296,22 @@ static void em_get_hw_control(struct adapter *); static void em_release_hw_control(struct adapter *); static void em_enable_wakeup(device_t); +#ifndef EM_FAST_IRQ +static void em_intr(void *); #ifdef DEVICE_POLLING static poll_handler_t em_poll; -static void em_intr(void *); +#endif /* POLLING */ +#else /* FAST IRQ */ +#if __FreeBSD_version < 700000 +static void em_intr_fast(void *); #else static int em_intr_fast(void *); +#endif static void em_add_rx_process_limit(struct adapter *, const char *, const char *, int *, int); static void em_handle_rxtx(void *context, int pending); static void em_handle_link(void *context, int pending); -#endif +#endif /* EM_FAST_IRQ */ /********************************************************************* * FreeBSD Device Interface Entry Points @@ -335,6 +345,11 @@ MODULE_DEPEND(em, ether, 1, 1, 1); #define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024) #define M_TSO_LEN 66 +/* Allow common code without TSO */ +#ifndef CSUM_TSO +#define CSUM_TSO 0 +#endif + static int em_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV); static int em_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR); static int em_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV); @@ -350,7 +365,7 @@ TUNABLE_INT("hw.em.rx_abs_int_delay", &em_rx_abs_int_delay_dflt); TUNABLE_INT("hw.em.rxd", &em_rxd); TUNABLE_INT("hw.em.txd", &em_txd); TUNABLE_INT("hw.em.smart_pwr_down", &em_smart_pwr_down); -#ifndef DEVICE_POLLING +#ifdef EM_FAST_IRQ /* How many packets rxeof tries to clean at a time */ static int em_rx_process_limit = 100; TUNABLE_INT("hw.em.rx_process_limit", &em_rx_process_limit); @@ -431,12 +446,13 @@ em_attach(device_t dev) adapter = device_get_softc(dev); adapter->dev = adapter->osdep.dev = dev; - EM_LOCK_INIT(adapter, device_get_nameunit(dev)); + EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); + EM_TX_LOCK_INIT(adapter, device_get_nameunit(dev)); /* SYSCTL stuff */ SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), - OID_AUTO, "debug_info", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, + OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, em_sysctl_debug_info, "I", "Debug Information"); SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), @@ -444,8 +460,8 @@ em_attach(device_t dev) OID_AUTO, "stats", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, em_sysctl_stats, "I", "Statistics"); - callout_init_mtx(&adapter->timer, &adapter->mtx, 0); - callout_init_mtx(&adapter->tx_fifo_timer, &adapter->mtx, 0); + callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); + callout_init_mtx(&adapter->tx_fifo_timer, &adapter->tx_mtx, 0); /* Determine hardware and mac info */ em_identify_hardware(adapter); @@ -505,7 +521,7 @@ em_attach(device_t dev) em_tx_abs_int_delay_dflt); } -#ifndef DEVICE_POLLING +#ifdef EM_FAST_IRQ /* Sysctls for limiting the amount of work done in the taskqueue */ em_add_rx_process_limit(adapter, "rx_processing_limit", "max number of rx packets to process", &adapter->rx_process_limit, @@ -537,7 +553,7 @@ em_attach(device_t dev) adapter->num_rx_desc = em_rxd; adapter->hw.mac.autoneg = DO_AUTO_NEG; - adapter->hw.phy.wait_for_link = FALSE; + adapter->hw.phy.autoneg_wait_to_complete = FALSE; adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT; adapter->rx_buffer_len = 2048; @@ -545,20 +561,18 @@ em_attach(device_t dev) e1000_set_tbi_compatibility_82543(&adapter->hw, TRUE); /* Copper options */ - if (adapter->hw.media_type == e1000_media_type_copper) { + if (adapter->hw.phy.media_type == e1000_media_type_copper) { adapter->hw.phy.mdix = AUTO_ALL_MODES; adapter->hw.phy.disable_polarity_correction = FALSE; adapter->hw.phy.ms_type = EM_MASTER_SLAVE; } /* - * Set the max frame size assuming standard ethernet - * sized frames. + * Set the frame limits assuming + * standard ethernet sized frames. */ - adapter->hw.mac.max_frame_size = - ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE; - - adapter->hw.mac.min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE; + adapter->max_frame_size = ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE; + adapter->min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE; /* * This controls when hardware reports transmit completion @@ -605,13 +619,6 @@ em_attach(device_t dev) } } - if (e1000_read_part_num(&adapter->hw, &(adapter->part_num)) < 0) { - device_printf(dev, "EEPROM read error " - "reading part number\n"); - error = EIO; - goto err_hw_init; - } - /* Initialize the hardware */ if (em_hardware_init(adapter)) { device_printf(dev, "Unable to initialize the hardware\n"); @@ -633,6 +640,20 @@ em_attach(device_t dev) goto err_hw_init; } + /* Allocate transmit descriptors and buffers */ + if (em_allocate_transmit_structures(adapter)) { + device_printf(dev, "Could not setup transmit structures\n"); + error = ENOMEM; + goto err_tx_struct; + } + + /* Allocate receive descriptors and buffers */ + if (em_allocate_receive_structures(adapter)) { + device_printf(dev, "Could not setup receive structures\n"); + error = ENOMEM; + goto err_rx_struct; + } + /* Setup OS specific network interface */ em_setup_interface(dev, adapter); @@ -726,6 +747,9 @@ em_attach(device_t dev) return (0); +err_rx_struct: + em_free_transmit_structures(adapter); +err_tx_struct: err_hw_init: em_release_hw_control(adapter); e1000_remove_device(&adapter->hw); @@ -736,7 +760,8 @@ err_tx_desc: err_pci: em_free_intr(adapter); em_free_pci_resources(adapter); - EM_LOCK_DESTROY(adapter); + EM_TX_LOCK_DESTROY(adapter); + EM_CORE_LOCK_DESTROY(adapter); return (error); } @@ -759,6 +784,16 @@ em_detach(device_t dev) INIT_DEBUGOUT("em_detach: begin"); + /* Make sure VLANS are not using driver */ +#if __FreeBSD_version >= 700000 + if (adapter->ifp->if_vlantrunk != NULL) { +#else + if (adapter->ifp->if_nvlans != 0) { +#endif + device_printf(dev,"Vlan in use, detach first\n"); + return (EBUSY); + } + #ifdef DEVICE_POLLING if (ifp->if_capenable & IFCAP_POLLING) ether_poll_deregister(ifp); @@ -766,7 +801,7 @@ em_detach(device_t dev) em_disable_intr(adapter); em_free_intr(adapter); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); adapter->in_detach = 1; em_stop(adapter); e1000_phy_hw_reset(&adapter->hw); @@ -785,7 +820,7 @@ em_detach(device_t dev) em_enable_wakeup(dev); } - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); ether_ifdetach(adapter->ifp); callout_drain(&adapter->timer); @@ -811,7 +846,8 @@ em_detach(device_t dev) adapter->rx_desc_base = NULL; } - EM_LOCK_DESTROY(adapter); + EM_TX_LOCK_DESTROY(adapter); + EM_CORE_LOCK_DESTROY(adapter); return (0); } @@ -836,7 +872,7 @@ em_suspend(device_t dev) { struct adapter *adapter = device_get_softc(dev); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); em_stop(adapter); em_release_manageability(adapter); @@ -853,7 +889,7 @@ em_suspend(device_t dev) em_enable_wakeup(dev); } - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return bus_generic_suspend(dev); } @@ -864,7 +900,7 @@ em_resume(device_t dev) struct adapter *adapter = device_get_softc(dev); struct ifnet *ifp = adapter->ifp; - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); em_init_locked(adapter); em_init_manageability(adapter); @@ -872,7 +908,7 @@ em_resume(device_t dev) (ifp->if_drv_flags & IFF_DRV_RUNNING)) em_start_locked(ifp); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return bus_generic_resume(dev); } @@ -894,7 +930,7 @@ em_start_locked(struct ifnet *ifp) struct adapter *adapter = ifp->if_softc; struct mbuf *m_head; - EM_LOCK_ASSERT(adapter); + EM_TX_LOCK_ASSERT(adapter); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING) @@ -935,10 +971,10 @@ em_start(struct ifnet *ifp) { struct adapter *adapter = ifp->if_softc; - EM_LOCK(adapter); + EM_TX_LOCK(adapter); if (ifp->if_drv_flags & IFF_DRV_RUNNING) em_start_locked(ifp); - EM_UNLOCK(adapter); + EM_TX_UNLOCK(adapter); } /********************************************************************* @@ -973,9 +1009,9 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) */ ifp->if_flags |= IFF_UP; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); em_init_locked(adapter); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); } arp_ifinit(ifp, ifa); } else @@ -988,7 +1024,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)"); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); switch (adapter->hw.mac.type) { case e1000_82573: /* @@ -1019,22 +1055,22 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } if (ifr->ifr_mtu > max_frame_size - ETHER_HDR_LEN - ETHER_CRC_LEN) { - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); error = EINVAL; break; } ifp->if_mtu = ifr->ifr_mtu; - adapter->hw.mac.max_frame_size = - ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; + adapter->max_frame_size = + ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; em_init_locked(adapter); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); break; } case SIOCSIFFLAGS: IOCTL_DEBUGOUT("ioctl rcv'd:\ SIOCSIFFLAGS (Set Interface Flags)"); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); if (ifp->if_flags & IFF_UP) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { if ((ifp->if_flags ^ adapter->if_flags) & @@ -1048,13 +1084,13 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (ifp->if_drv_flags & IFF_DRV_RUNNING) em_stop(adapter); adapter->if_flags = ifp->if_flags; - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); break; case SIOCADDMULTI: case SIOCDELMULTI: IOCTL_DEBUGOUT("ioctl rcv'd: SIOC(ADD|DEL)MULTI"); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); em_disable_intr(adapter); em_set_multi(adapter); if (adapter->hw.mac.type == e1000_82542 && @@ -1065,19 +1101,19 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (!(ifp->if_capenable & IFCAP_POLLING)) #endif em_enable_intr(adapter); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); } break; case SIOCSIFMEDIA: /* Check SOL/IDER usage */ - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); if (e1000_check_reset_block(&adapter->hw)) { - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); device_printf(adapter->dev, "Media change is" " blocked due to SOL/IDER session.\n"); break; } - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); case SIOCGIFMEDIA: IOCTL_DEBUGOUT("ioctl rcv'd: \ SIOCxIFMEDIA (Get/Set Interface Media)"); @@ -1096,17 +1132,17 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = ether_poll_register(em_poll, ifp); if (error) return (error); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); em_disable_intr(adapter); ifp->if_capenable |= IFCAP_POLLING; - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); } else { error = ether_poll_deregister(ifp); /* Enable interrupt even in error case */ - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); em_enable_intr(adapter); ifp->if_capenable &= ~IFCAP_POLLING; - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); } } #endif @@ -1114,17 +1150,21 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_capenable ^= IFCAP_HWCSUM; reinit = 1; } +#if __FreeBSD_version >= 700000 if (mask & IFCAP_TSO4) { ifp->if_capenable ^= IFCAP_TSO4; reinit = 1; } +#endif if (mask & IFCAP_VLAN_HWTAGGING) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; reinit = 1; } if (reinit && (ifp->if_drv_flags & IFF_DRV_RUNNING)) em_init(adapter); +#if __FreeBSD_version >= 700000 VLAN_CAPABILITIES(ifp); +#endif break; } default: @@ -1148,17 +1188,20 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) static void em_watchdog(struct adapter *adapter) { +#ifdef EM_FAST_IRQ + struct task *t = &adapter->rxtx_task; +#endif - EM_LOCK_ASSERT(adapter); + EM_CORE_LOCK_ASSERT(adapter); /* ** The timer is set to 5 every time start queues a packet. - ** Then txeof keeps resetting to 5 as long as it cleans at + ** Then txeof keeps resetting it as long as it cleans at ** least one descriptor. ** Finally, anytime all descriptors are clean the timer is ** set to 0. */ - if (adapter->watchdog_timer == 0 || --adapter->watchdog_timer) + if ((adapter->watchdog_timer == 0) || (--adapter->watchdog_timer)) return; /* If we are in this routine because of pause frames, then @@ -1198,7 +1241,7 @@ em_init_locked(struct adapter *adapter) INIT_DEBUGOUT("em_init: begin"); - EM_LOCK_ASSERT(adapter); + EM_CORE_LOCK_ASSERT(adapter); em_stop(adapter); @@ -1216,7 +1259,7 @@ em_init_locked(struct adapter *adapter) switch (adapter->hw.mac.type) { case e1000_82547: case e1000_82547_rev_2: /* 82547: Total Packet Buffer is 40K */ - if (adapter->hw.mac.max_frame_size > 8192) + if (adapter->max_frame_size > 8192) pba = E1000_PBA_22K; /* 22K for Rx, 18K for Tx */ else pba = E1000_PBA_30K; /* 30K for Rx, 10K for Tx */ @@ -1244,7 +1287,7 @@ em_init_locked(struct adapter *adapter) break; default: /* Devices before 82547 had a Packet Buffer of 64K. */ - if (adapter->hw.mac.max_frame_size > 8192) + if (adapter->max_frame_size > 8192) pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ else pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ @@ -1261,11 +1304,16 @@ em_init_locked(struct adapter *adapter) e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); /* - * With 82571 controllers, LAA may be overwritten - * due to controller reset from the other port. + * With the 82571 adapter, RAR[0] may be overwritten + * when the other port is reset, we make a duplicate + * in RAR[14] for that eventuality, this assures + * the interface continues to function. */ - if (adapter->hw.mac.type == e1000_82571) - e1000_set_laa_state_82571(&adapter->hw, TRUE); + if (adapter->hw.mac.type == e1000_82571) { + e1000_set_laa_state_82571(&adapter->hw, TRUE); + e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, + E1000_RAR_ENTRIES - 1); + } /* Initialize the hardware */ if (em_hardware_init(adapter)) { @@ -1274,27 +1322,27 @@ em_init_locked(struct adapter *adapter) } em_update_link_status(adapter); + /* Setup VLAN support, basic and offload if available */ + E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) - em_enable_vlans(adapter); + em_enable_hw_vlans(adapter); /* Set hardware offload abilities */ ifp->if_hwassist = 0; if (adapter->hw.mac.type >= e1000_82543) { if (ifp->if_capenable & IFCAP_TXCSUM) ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); +#if __FreeBSD_version >= 700000 if (ifp->if_capenable & IFCAP_TSO4) ifp->if_hwassist |= CSUM_TSO; +#endif } /* Configure for OS presence */ em_init_manageability(adapter); /* Prepare transmit descriptors and buffers */ - if (em_setup_transmit_structures(adapter)) { - device_printf(dev, "Could not setup transmit structures\n"); - em_stop(adapter); - return; - } + em_setup_transmit_structures(adapter); em_initialize_transmit_unit(adapter); /* Setup Multicast table */ @@ -1337,9 +1385,9 @@ em_init(void *arg) { struct adapter *adapter = arg; - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); em_init_locked(adapter); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); } @@ -1355,9 +1403,9 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) struct adapter *adapter = ifp->if_softc; uint32_t reg_icr; - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return; } @@ -1373,13 +1421,18 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } } em_rxeof(adapter, count); + EM_CORE_UNLOCK(adapter); + + EM_TX_LOCK(adapter); em_txeof(adapter); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) em_start_locked(ifp); - EM_UNLOCK(adapter); + EM_TX_UNLOCK(adapter); } +#endif /* DEVICE_POLLING */ +#ifndef EM_FAST_IRQ /********************************************************************* * * Legacy Interrupt Service routine @@ -1393,11 +1446,11 @@ em_intr(void *arg) struct ifnet *ifp; uint32_t reg_icr; - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); ifp = adapter->ifp; if (ifp->if_capenable & IFCAP_POLLING) { - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return; } @@ -1421,7 +1474,9 @@ em_intr(void *arg) if (ifp->if_drv_flags & IFF_DRV_RUNNING) { em_rxeof(adapter, -1); + EM_TX_LOCK(adapter); em_txeof(adapter); + EM_TX_UNLOCK(adapter); } /* Link status change */ @@ -1430,6 +1485,8 @@ em_intr(void *arg) adapter->hw.mac.get_link_status = 1; e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); + /* Deal with TX cruft when link lost */ + em_tx_purge(adapter); callout_reset(&adapter->timer, hz, em_local_timer, adapter); } @@ -1437,14 +1494,14 @@ em_intr(void *arg) if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; } + EM_CORE_UNLOCK(adapter); if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - em_start_locked(ifp); - EM_UNLOCK(adapter); + em_start(ifp); } -#else /* if not DEVICE_POLLING, then fast interrupt routines only */ +#else /* EM_FAST_IRQ, then fast interrupt routines only */ static void em_handle_link(void *context, int pending) @@ -1454,9 +1511,9 @@ em_handle_link(void *context, int pending) ifp = adapter->ifp; - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return; } @@ -1464,16 +1521,26 @@ em_handle_link(void *context, int pending) adapter->hw.mac.get_link_status = 1; e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); + /* Deal with TX cruft when link lost */ + em_tx_purge(adapter); callout_reset(&adapter->timer, hz, em_local_timer, adapter); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); } +#if __FreeBSD_version >= 700000 +#if !defined(NET_LOCK_GIANT) +#define NET_LOCK_GIANT() +#define NET_UNLOCK_GIANT() +#endif +#endif + static void em_handle_rxtx(void *context, int pending) { struct adapter *adapter = context; struct ifnet *ifp; + NET_LOCK_GIANT(); ifp = adapter->ifp; /* @@ -1483,15 +1550,16 @@ em_handle_rxtx(void *context, int pending) if (ifp->if_drv_flags & IFF_DRV_RUNNING) { if (em_rxeof(adapter, adapter->rx_process_limit) != 0) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); - EM_LOCK(adapter); + EM_TX_LOCK(adapter); em_txeof(adapter); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) em_start_locked(ifp); - EM_UNLOCK(adapter); + EM_TX_UNLOCK(adapter); } em_enable_intr(adapter); + NET_UNLOCK_GIANT(); } /********************************************************************* @@ -1499,7 +1567,13 @@ em_handle_rxtx(void *context, int pending) * Fast Interrupt Service routine * *********************************************************************/ +#if __FreeBSD_version < 700000 +#define FILTER_STRAY +#define FILTER_HANDLED +static void +#else static int +#endif em_intr_fast(void *arg) { struct adapter *adapter = arg; @@ -1512,11 +1586,11 @@ em_intr_fast(void *arg) /* Hot eject? */ if (reg_icr == 0xffffffff) - return (FILTER_STRAY); + return FILTER_STRAY; /* Definitely not our interrupt. */ if (reg_icr == 0x0) - return (FILTER_STRAY); + return FILTER_STRAY; /* * Starting with the 82571 chip, bit 31 should be used to @@ -1524,7 +1598,7 @@ em_intr_fast(void *arg) */ if (adapter->hw.mac.type >= e1000_82571 && (reg_icr & E1000_ICR_INT_ASSERTED) == 0) - return (FILTER_STRAY); + return FILTER_STRAY; /* * Mask interrupts until the taskqueue is finished running. This is @@ -1540,9 +1614,9 @@ em_intr_fast(void *arg) if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; - return (FILTER_HANDLED); + return FILTER_HANDLED; } -#endif /* ! DEVICE_POLLING */ +#endif /* EM_FAST_IRQ */ /********************************************************************* * @@ -1560,7 +1634,7 @@ em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) INIT_DEBUGOUT("em_media_status: begin"); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); @@ -1568,14 +1642,14 @@ em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) ifmr->ifm_active = IFM_ETHER; if (!adapter->link_active) { - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return; } ifmr->ifm_status |= IFM_ACTIVE; - if ((adapter->hw.media_type == e1000_media_type_fiber) || - (adapter->hw.media_type == e1000_media_type_internal_serdes)) { + if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || + (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) { if (adapter->hw.mac.type == e1000_82545) fiber_type = IFM_1000_LX; ifmr->ifm_active |= fiber_type | IFM_FDX; @@ -1596,7 +1670,7 @@ em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) else ifmr->ifm_active |= IFM_HDX; } - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); } /********************************************************************* @@ -1618,7 +1692,7 @@ em_media_change(struct ifnet *ifp) if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) return (EINVAL); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); switch (IFM_SUBTYPE(ifm->ifm_media)) { case IFM_AUTO: adapter->hw.mac.autoneg = DO_AUTO_NEG; @@ -1656,7 +1730,7 @@ em_media_change(struct ifnet *ifp) adapter->hw.phy.reset_disable = FALSE; em_init_locked(adapter); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return (0); } @@ -1679,11 +1753,17 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp) uint32_t txd_upper, txd_lower, txd_used, txd_saved; int nsegs, i, j, first, last = 0; int error, do_tso, tso_desc = 0; - +#if __FreeBSD_version < 700000 + struct m_tag *mtag; +#endif m_head = *m_headp; txd_upper = txd_lower = txd_used = txd_saved = 0; +#if __FreeBSD_version >= 700000 do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0); +#else + do_tso = 0; +#endif /* * Force a cleanup if number of TX descriptors @@ -1791,10 +1871,16 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp) m_head = *m_headp; /* Do hardware assists */ - if (em_tso_setup(adapter, m_head, &txd_upper, &txd_lower)) +#if __FreeBSD_version >= 700000 + if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { + error = em_tso_setup(adapter, m_head, &txd_upper, &txd_lower); + if (error != TRUE) + return (ENXIO); /* something foobar */ /* we need to make a final sentinel transmit desc */ tso_desc = TRUE; - else if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) + } else +#endif + if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) em_transmit_checksum_setup(adapter, m_head, &txd_upper, &txd_lower); @@ -1895,10 +1981,23 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp) adapter->num_tx_desc_avail -= txd_used; } + /* + ** Handle VLAN tag, this is the + ** biggest difference between + ** 6.x and 7 + */ +#if __FreeBSD_version < 700000 + /* Find out if we are in vlan mode. */ + mtag = VLAN_OUTPUT_TAG(ifp, m_head); + if (mtag != NULL) { + ctxd->upper.fields.special = + htole16(VLAN_TAG_VALUE(mtag)); +#else /* FreeBSD 7 */ if (m_head->m_flags & M_VLANTAG) { /* Set the vlan id. */ ctxd->upper.fields.special = htole16(m_head->m_pkthdr.ether_vtag); +#endif /* Tell hardware to add tag */ ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); } @@ -1932,7 +2031,7 @@ em_encap(struct adapter *adapter, struct mbuf **m_headp) adapter->link_duplex == HALF_DUPLEX) em_82547_move_tail(adapter); else { - E1000_WRITE_REG(&adapter->hw, E1000_TDT, i); + E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), i); if (adapter->hw.mac.type == e1000_82547) em_82547_update_fifo_head(adapter, m_head->m_pkthdr.len); @@ -1957,8 +2056,12 @@ em_adv_encap(struct adapter *adapter, struct mbuf **m_headp) union e1000_adv_tx_desc *txd = NULL; struct mbuf *m_head; u32 olinfo_status = 0, cmd_type_len = 0; - u32 paylen = 0; int nsegs, i, j, error, first, last = 0; +#if __FreeBSD_version < 700000 + struct m_tag *mtag; +#else + u32 hdrlen = 0; +#endif m_head = *m_headp; @@ -1966,6 +2069,13 @@ em_adv_encap(struct adapter *adapter, struct mbuf **m_headp) /* Set basic descriptor constants */ cmd_type_len |= E1000_ADVTXD_DTYP_DATA; cmd_type_len |= E1000_ADVTXD_DCMD_IFCS | E1000_ADVTXD_DCMD_DEXT; +#if __FreeBSD_version < 700000 + mtag = VLAN_OUTPUT_TAG(ifp, m_head); + if (mtag != NULL) +#else + if (m_head->m_flags & M_VLANTAG) +#endif + cmd_type_len |= E1000_ADVTXD_DCMD_VLE; /* * Force a cleanup if number of TX descriptors @@ -2045,16 +2155,23 @@ em_adv_encap(struct adapter *adapter, struct mbuf **m_headp) * This includes CSUM, VLAN, and TSO. It * will use the first descriptor. */ - /* First try TSO */ - if (em_tso_adv_setup(adapter, m_head, &paylen)) { - cmd_type_len |= E1000_ADVTXD_DCMD_TSE; - olinfo_status |= E1000_TXD_POPTS_IXSM << 8; - olinfo_status |= E1000_TXD_POPTS_TXSM << 8; - olinfo_status |= paylen << E1000_ADVTXD_PAYLEN_SHIFT; - } else if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) { - if (em_tx_adv_ctx_setup(adapter, m_head)) +#if __FreeBSD_version >= 700000 + if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { + if (em_tso_adv_setup(adapter, m_head, &hdrlen)) { + cmd_type_len |= E1000_ADVTXD_DCMD_TSE; + olinfo_status |= E1000_TXD_POPTS_IXSM << 8; olinfo_status |= E1000_TXD_POPTS_TXSM << 8; + } else + return (ENXIO); } +#endif + /* Do all other context descriptor setup */ + if (em_tx_adv_ctx_setup(adapter, m_head)) + olinfo_status |= E1000_TXD_POPTS_TXSM << 8; + + /* Calculate payload length */ + olinfo_status |= ((m_head->m_pkthdr.len - hdrlen) + << E1000_ADVTXD_PAYLEN_SHIFT); /* Set up our transmit descriptors */ i = adapter->next_avail_tx_desc; @@ -2106,7 +2223,7 @@ em_adv_encap(struct adapter *adapter, struct mbuf **m_headp) */ bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - E1000_WRITE_REG(&adapter->hw, E1000_TDT, i); + E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), i); return (0); @@ -2130,9 +2247,9 @@ em_82547_move_tail(void *arg) uint16_t length = 0; boolean_t eop = 0; - EM_LOCK_ASSERT(adapter); + EM_TX_LOCK_ASSERT(adapter); - hw_tdt = E1000_READ_REG(&adapter->hw, E1000_TDT); + hw_tdt = E1000_READ_REG(&adapter->hw, E1000_TDT(0)); sw_tdt = adapter->next_avail_tx_desc; while (hw_tdt != sw_tdt) { @@ -2149,7 +2266,7 @@ em_82547_move_tail(void *arg) em_82547_move_tail, adapter); break; } - E1000_WRITE_REG(&adapter->hw, E1000_TDT, hw_tdt); + E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), hw_tdt); em_82547_update_fifo_head(adapter, length); length = 0; } @@ -2195,8 +2312,8 @@ em_82547_tx_fifo_reset(struct adapter *adapter) { uint32_t tctl; - if ((E1000_READ_REG(&adapter->hw, E1000_TDT) == - E1000_READ_REG(&adapter->hw, E1000_TDH)) && + if ((E1000_READ_REG(&adapter->hw, E1000_TDT(0)) == + E1000_READ_REG(&adapter->hw, E1000_TDH(0))) && (E1000_READ_REG(&adapter->hw, E1000_TDFT) == E1000_READ_REG(&adapter->hw, E1000_TDFH)) && (E1000_READ_REG(&adapter->hw, E1000_TDFTS) == @@ -2309,7 +2426,7 @@ em_set_multi(struct adapter *adapter) reg_rctl |= E1000_RCTL_MPE; E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl); } else - e1000_mc_addr_list_update(&adapter->hw, mta, + e1000_update_mc_addr_list(&adapter->hw, mta, mcnt, 1, adapter->hw.mac.rar_entry_count); if (adapter->hw.mac.type == e1000_82542 && @@ -2337,14 +2454,14 @@ em_local_timer(void *arg) struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; - EM_LOCK_ASSERT(adapter); + EM_CORE_LOCK_ASSERT(adapter); e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); em_update_stats_counters(adapter); - /* Check for 82571 LAA reset by other port */ - if (e1000_get_laa_state_82571(&adapter->hw) == TRUE) + /* Reset LAA into RAR[0] on 82571 */ + if (e1000_get_laa_state_82571(&adapter->hw) == TRUE) e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); if (em_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -2359,6 +2476,7 @@ em_local_timer(void *arg) em_watchdog(adapter); callout_reset(&adapter->timer, hz, em_local_timer, adapter); + } static void @@ -2379,10 +2497,10 @@ em_update_link_status(struct adapter *adapter) int tarc0; tarc0 = E1000_READ_REG(&adapter->hw, - E1000_TARC0); + E1000_TARC(0)); tarc0 &= ~SPEED_MODE_BIT; E1000_WRITE_REG(&adapter->hw, - E1000_TARC0, tarc0); + E1000_TARC(0), tarc0); } if (bootverbose) device_printf(dev, "Link is up %d Mbps %s\n", @@ -2419,15 +2537,13 @@ em_stop(void *arg) struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; - EM_LOCK_ASSERT(adapter); + EM_CORE_LOCK_ASSERT(adapter); INIT_DEBUGOUT("em_stop: begin"); em_disable_intr(adapter); callout_stop(&adapter->timer); callout_stop(&adapter->tx_fifo_timer); - em_free_transmit_structures(adapter); - em_free_receive_structures(adapter); /* Tell the stack that the interface is no longer active */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); @@ -2466,7 +2582,8 @@ em_identify_hardware(struct adapter *adapter) adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1); adapter->hw.subsystem_vendor_id = pci_read_config(dev, PCIR_SUBVEND_0, 2); - adapter->hw.subsystem_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2); + adapter->hw.subsystem_device_id = + pci_read_config(dev, PCIR_SUBDEV_0, 2); /* Do Shared Code Init and Setup */ if (e1000_set_mac_type(&adapter->hw)) { @@ -2534,36 +2651,13 @@ em_allocate_pci_resources(struct adapter *adapter) */ adapter->msi = 0; /* Set defaults */ rid = 0x0; - if (adapter->hw.mac.type >= e1000_82575) { - /* - * Setup MSI/X - */ - rid = PCIR_BAR(EM_MSIX_BAR); - adapter->msix_mem = bus_alloc_resource_any(dev, - SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (!adapter->msix_mem) { - device_printf(dev,"Unable to map MSIX table \n"); - return (ENXIO); - } - /* - * Eventually this may be used - * for Multiqueue, for now we will - * just use one vector. - * - * val = pci_msix_count(dev); - */ - val = 1; - if ((val) && pci_alloc_msix(dev, &val) == 0) { - rid = 1; - adapter->msi = 1; - } - } else if (adapter->hw.mac.type >= e1000_82571) { - val = pci_msi_count(dev); - if (val == 1 && pci_alloc_msi(dev, &val) == 0) { - rid = 1; - adapter->msi = 1; - } - } + +#if __FreeBSD_version > 602111 /* MSI support is present */ + /* This will setup either MSI/X or MSI */ + if (em_setup_msix(adapter)) + rid = 1; +#endif /* FreeBSD_version */ + adapter->res_interrupt = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (adapter->res_interrupt == NULL) { @@ -2591,17 +2685,21 @@ em_allocate_intr(struct adapter *adapter) /* Manually turn off all interrupts */ E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff); -#ifdef DEVICE_POLLING +#ifndef EM_FAST_IRQ /* We do Legacy setup */ if (adapter->int_handler_tag == NULL && (error = bus_setup_intr(dev, adapter->res_interrupt, +#if __FreeBSD_version > 700000 INTR_TYPE_NET | INTR_MPSAFE, NULL, em_intr, adapter, +#else /* 6.X */ + INTR_TYPE_NET | INTR_MPSAFE, em_intr, adapter, +#endif &adapter->int_handler_tag)) != 0) { device_printf(dev, "Failed to register interrupt handler"); return (error); } -#else +#else /* FAST_IRQ */ /* * Try allocating a fast interrupt and the associated deferred * processing contexts. @@ -2612,8 +2710,13 @@ em_allocate_intr(struct adapter *adapter) taskqueue_thread_enqueue, &adapter->tq); taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s taskq", device_get_nameunit(adapter->dev)); +#if __FreeBSD_version < 700000 + if ((error = bus_setup_intr(dev, adapter->res_interrupt, + INTR_TYPE_NET | INTR_FAST, em_intr_fast, adapter, +#else if ((error = bus_setup_intr(dev, adapter->res_interrupt, INTR_TYPE_NET, em_intr_fast, NULL, adapter, +#endif &adapter->int_handler_tag)) != 0) { device_printf(dev, "Failed to register fast interrupt " "handler: %d\n", error); @@ -2621,7 +2724,7 @@ em_allocate_intr(struct adapter *adapter) adapter->tq = NULL; return (error); } -#endif +#endif /* EM_FAST_IRQ */ em_enable_intr(adapter); return (0); @@ -2654,12 +2757,14 @@ em_free_pci_resources(struct adapter *adapter) bus_release_resource(dev, SYS_RES_IRQ, adapter->msi ? 1 : 0, adapter->res_interrupt); +#if __FreeBSD_version > 602111 /* MSI support is present */ if (adapter->msix_mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem); if (adapter->msi) pci_release_msi(dev); +#endif /* FreeBSD_version */ if (adapter->res_memory != NULL) bus_release_resource(dev, SYS_RES_MEMORY, @@ -2674,6 +2779,48 @@ em_free_pci_resources(struct adapter *adapter) adapter->io_rid, adapter->res_ioport); } +#if __FreeBSD_version > 602111 /* MSI support is present */ +/* + * Setup MSI/X + */ +static bool +em_setup_msix(struct adapter *adapter) +{ + device_t dev = adapter->dev; + int rid, val; + + if (adapter->hw.mac.type < e1000_82571) + return (FALSE); + + /* First try MSI/X if possible */ + if (adapter->hw.mac.type >= e1000_82575) { + rid = PCIR_BAR(EM_MSIX_BAR); + adapter->msix_mem = bus_alloc_resource_any(dev, + SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (!adapter->msix_mem) { + /* May not be enabled */ + device_printf(adapter->dev, + "Unable to map MSIX table \n"); + goto msi; + } + val = pci_msix_count(dev); + if ((val) && pci_alloc_msix(dev, &val) == 0) { + adapter->msi = 1; + device_printf(adapter->dev,"Using MSIX interrupts\n"); + return (TRUE); + } + } +msi: + val = pci_msi_count(dev); + if (val == 1 && pci_alloc_msi(dev, &val) == 0) { + adapter->msi = 1; + device_printf(adapter->dev,"Using MSI interrupt\n"); + return (TRUE); + } + return (FALSE); +} +#endif /* FreeBSD_version */ + /********************************************************************* * * Initialize the hardware to a configuration @@ -2731,15 +2878,16 @@ em_hardware_init(struct adapter *adapter) rx_buffer_size = ((E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff) << 10 ); - adapter->hw.mac.fc_high_water = rx_buffer_size - - roundup2(adapter->hw.mac.max_frame_size, 1024); - adapter->hw.mac.fc_low_water = adapter->hw.mac.fc_high_water - 1500; + adapter->hw.fc.high_water = rx_buffer_size - + roundup2(adapter->max_frame_size, 1024); + adapter->hw.fc.low_water = adapter->hw.fc.high_water - 1500; + if (adapter->hw.mac.type == e1000_80003es2lan) - adapter->hw.mac.fc_pause_time = 0xFFFF; + adapter->hw.fc.pause_time = 0xFFFF; else - adapter->hw.mac.fc_pause_time = EM_FC_PAUSE_TIME; - adapter->hw.mac.fc_send_xon = TRUE; - adapter->hw.mac.fc = e1000_fc_full; + adapter->hw.fc.pause_time = EM_FC_PAUSE_TIME; + adapter->hw.fc.send_xon = TRUE; + adapter->hw.fc.type = e1000_fc_full; if (e1000_init_hw(&adapter->hw) < 0) { device_printf(dev, "Hardware Initialization Failed\n"); @@ -2782,10 +2930,17 @@ em_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capabilities = ifp->if_capenable = 0; if (adapter->hw.mac.type >= e1000_82543) { - ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; - ifp->if_capenable |= IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; + int version_cap; +#if __FreeBSD_version < 700000 + version_cap = IFCAP_HWCSUM; +#else + version_cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM; +#endif + ifp->if_capabilities |= version_cap; + ifp->if_capenable |= version_cap; } +#if __FreeBSD_version >= 700000 /* Identify TSO capable adapters */ if ((adapter->hw.mac.type > e1000_82544) && (adapter->hw.mac.type != e1000_82547)) @@ -2796,13 +2951,14 @@ em_setup_interface(device_t dev, struct adapter *adapter) */ if (adapter->hw.mac.type >= e1000_82571) ifp->if_capenable |= IFCAP_TSO4; +#endif /* * Tell the upper layer(s) we support long frames. */ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; - ifp->if_capenable |= IFCAP_VLAN_MTU; + ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; @@ -2814,8 +2970,8 @@ em_setup_interface(device_t dev, struct adapter *adapter) */ ifmedia_init(&adapter->media, IFM_IMASK, em_media_change, em_media_status); - if ((adapter->hw.media_type == e1000_media_type_fiber) || - (adapter->hw.media_type == e1000_media_type_internal_serdes)) { + if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || + (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) { u_char fiber_type = IFM_1000_SX; /* default type */ if (adapter->hw.mac.type == e1000_82545) @@ -2920,7 +3076,11 @@ em_dma_malloc(struct adapter *adapter, bus_size_t size, { int error; +#if __FreeBSD_version >= 700000 error = bus_dma_tag_create(bus_get_dma_tag(adapter->dev), /* parent */ +#else + error = bus_dma_tag_create(NULL, /* parent */ +#endif EM_DBA_ALIGN, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -2939,13 +3099,8 @@ em_dma_malloc(struct adapter *adapter, bus_size_t size, goto fail_0; } -#ifdef __arm__ - error = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr, - BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dma->dma_map); -#else error = bus_dmamem_alloc(dma->dma_tag, (void**) &dma->dma_vaddr, BUS_DMA_NOWAIT, &dma->dma_map); -#endif if (error) { device_printf(adapter->dev, "%s: bus_dmamem_alloc(%ju) failed: %d\n", @@ -3002,38 +3157,19 @@ em_dma_free(struct adapter *adapter, struct em_dma_alloc *dma) **********************************************************************/ static int em_allocate_transmit_structures(struct adapter *adapter) -{ - device_t dev = adapter->dev; - - adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) * - adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); - if (adapter->tx_buffer_area == NULL) { - device_printf(dev, "Unable to allocate tx_buffer memory\n"); - return (ENOMEM); - } - - bzero(adapter->tx_buffer_area, - (sizeof(struct em_buffer)) * adapter->num_tx_desc); - - return (0); -} - -/********************************************************************* - * - * Initialize transmit structures. - * - **********************************************************************/ -static int -em_setup_transmit_structures(struct adapter *adapter) { device_t dev = adapter->dev; struct em_buffer *tx_buffer; - int error, i; + int error; /* * Create DMA tags for tx descriptors */ +#if __FreeBSD_version >= 700000 if ((error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ +#else + if ((error = bus_dma_tag_create(NULL, /* parent */ +#endif 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -3049,39 +3185,65 @@ em_setup_transmit_structures(struct adapter *adapter) goto fail; } - if ((error = em_allocate_transmit_structures(adapter)) != 0) + adapter->tx_buffer_area = malloc(sizeof(struct em_buffer) * + adapter->num_tx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); + if (adapter->tx_buffer_area == NULL) { + device_printf(dev, "Unable to allocate tx_buffer memory\n"); + error = ENOMEM; goto fail; - - /* Clear the old ring contents */ - bzero(adapter->tx_desc_base, - (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc); + } /* Create the descriptor buffer dma maps */ - tx_buffer = adapter->tx_buffer_area; - for (i = 0; i < adapter->num_tx_desc; i++) { + for (int i = 0; i < adapter->num_tx_desc; i++) { + tx_buffer = &adapter->tx_buffer_area[i]; error = bus_dmamap_create(adapter->txtag, 0, &tx_buffer->map); if (error != 0) { device_printf(dev, "Unable to create TX DMA map\n"); goto fail; } tx_buffer->next_eop = -1; - tx_buffer++; } + return (0); +fail: + em_free_transmit_structures(adapter); + return (error); +} + +/********************************************************************* + * + * (Re)Initialize transmit structures. + * + **********************************************************************/ +static void +em_setup_transmit_structures(struct adapter *adapter) +{ + struct em_buffer *tx_buffer; + + /* Clear the old ring contents */ + bzero(adapter->tx_desc_base, + (sizeof(struct e1000_tx_desc)) * adapter->num_tx_desc); + + /* Free any existing TX buffers */ + for (int i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) { + tx_buffer = &adapter->tx_buffer_area[i]; + bus_dmamap_sync(adapter->txtag, tx_buffer->map, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(adapter->txtag, tx_buffer->map); + m_freem(tx_buffer->m_head); + tx_buffer->m_head = NULL; + tx_buffer->next_eop = -1; + } + + /* Reset state */ adapter->next_avail_tx_desc = 0; adapter->next_tx_to_clean = 0; - - /* Set number of descriptors available */ adapter->num_tx_desc_avail = adapter->num_tx_desc; bus_dmamap_sync(adapter->txdma.dma_tag, adapter->txdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - return (0); - -fail: - em_free_transmit_structures(adapter); - return (error); + return; } /********************************************************************* @@ -3098,18 +3260,19 @@ em_initialize_transmit_unit(struct adapter *adapter) INIT_DEBUGOUT("em_initialize_transmit_unit: begin"); /* Setup the Base and Length of the Tx Descriptor Ring */ bus_addr = adapter->txdma.dma_paddr; - E1000_WRITE_REG(&adapter->hw, E1000_TDLEN, + E1000_WRITE_REG(&adapter->hw, E1000_TDLEN(0), adapter->num_tx_desc * sizeof(struct e1000_tx_desc)); - E1000_WRITE_REG(&adapter->hw, E1000_TDBAH, (uint32_t)(bus_addr >> 32)); - E1000_WRITE_REG(&adapter->hw, E1000_TDBAL, (uint32_t)bus_addr); - + E1000_WRITE_REG(&adapter->hw, E1000_TDBAH(0), + (uint32_t)(bus_addr >> 32)); + E1000_WRITE_REG(&adapter->hw, E1000_TDBAL(0), + (uint32_t)bus_addr); /* Setup the HW Tx Head and Tail descriptor pointers */ - E1000_WRITE_REG(&adapter->hw, E1000_TDT, 0); - E1000_WRITE_REG(&adapter->hw, E1000_TDH, 0); + E1000_WRITE_REG(&adapter->hw, E1000_TDT(0), 0); + E1000_WRITE_REG(&adapter->hw, E1000_TDH(0), 0); HW_DEBUGOUT2("Base = %x, Length = %x\n", - E1000_READ_REG(&adapter->hw, E1000_TDBAL), - E1000_READ_REG(&adapter->hw, E1000_TDLEN)); + E1000_READ_REG(&adapter->hw, E1000_TDBAL(0)), + E1000_READ_REG(&adapter->hw, E1000_TDLEN(0))); /* Set the default values for the Tx Inter Packet Gap timer */ switch (adapter->hw.mac.type) { @@ -3124,8 +3287,8 @@ em_initialize_transmit_unit(struct adapter *adapter) E1000_TIPG_IPGR2_SHIFT; break; default: - if ((adapter->hw.media_type == e1000_media_type_fiber) || - (adapter->hw.media_type == + if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || + (adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) tipg = DEFAULT_82543_TIPG_IPGT_FIBER; else @@ -3142,16 +3305,16 @@ em_initialize_transmit_unit(struct adapter *adapter) if ((adapter->hw.mac.type == e1000_82571) || (adapter->hw.mac.type == e1000_82572)) { - tarc = E1000_READ_REG(&adapter->hw, E1000_TARC0); + tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0)); tarc |= SPEED_MODE_BIT; - E1000_WRITE_REG(&adapter->hw, E1000_TARC0, tarc); + E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc); } else if (adapter->hw.mac.type == e1000_80003es2lan) { - tarc = E1000_READ_REG(&adapter->hw, E1000_TARC0); + tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0)); tarc |= 1; - E1000_WRITE_REG(&adapter->hw, E1000_TARC0, tarc); - tarc = E1000_READ_REG(&adapter->hw, E1000_TARC1); + E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc); + tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(1)); tarc |= 1; - E1000_WRITE_REG(&adapter->hw, E1000_TARC1, tarc); + E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc); } /* Program the Transmit Control Register */ @@ -3189,13 +3352,12 @@ static void em_free_transmit_structures(struct adapter *adapter) { struct em_buffer *tx_buffer; - int i; INIT_DEBUGOUT("free_transmit_structures: begin"); if (adapter->tx_buffer_area != NULL) { - tx_buffer = adapter->tx_buffer_area; - for (i = 0; i < adapter->num_tx_desc; i++, tx_buffer++) { + for (int i = 0; i < adapter->num_tx_desc; i++) { + tx_buffer = &adapter->tx_buffer_area[i]; if (tx_buffer->m_head != NULL) { bus_dmamap_sync(adapter->txtag, tx_buffer->map, BUS_DMASYNC_POSTWRITE); @@ -3366,12 +3528,14 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, adapter->next_avail_tx_desc = curr_txd; } + +#if __FreeBSD_version >= 700000 /********************************************************************** * * Setup work for hardware segmentation offload (TSO) * **********************************************************************/ -static boolean_t +static bool em_tso_setup(struct adapter *adapter, struct mbuf *mp, uint32_t *txd_upper, uint32_t *txd_lower) { @@ -3384,17 +3548,6 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, uint32_t *txd_upper, int curr_txd, ehdrlen, hdr_len, ip_hlen, isip6; uint16_t etype; - /* - * XXX: This is not really correct as the stack would not have - * set up all checksums. - * XXX: Return FALSE is not sufficient as we may have to return - * in true failure cases as well. Should do -1 (failure), 0 (no) - * and 1 (success). - */ - if (((mp->m_pkthdr.csum_flags & CSUM_TSO) == 0) || - (mp->m_pkthdr.len <= EM_TX_BUFFER_SIZE)) - return FALSE; - /* * This function could/should be extended to support IP/IPv6 * fragmentation as well. But as they say, one step at a time. @@ -3530,26 +3683,22 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, uint32_t *txd_upper, /********************************************************************** * * Setup work for hardware segmentation offload (TSO) on - * adapters using advanced tx descriptors + * adapters using advanced tx descriptors (82575) * **********************************************************************/ static boolean_t -em_tso_adv_setup(struct adapter *adapter, struct mbuf *mp, u32 *paylen) +em_tso_adv_setup(struct adapter *adapter, struct mbuf *mp, u32 *hdrlen) { struct e1000_adv_tx_context_desc *TXD; struct em_buffer *tx_buffer; u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; u32 mss_l4len_idx = 0; u16 vtag = 0; - int ctxd, ehdrlen, hdrlen, ip_hlen, tcp_hlen; + int ctxd, ehdrlen, ip_hlen, tcp_hlen; struct ether_vlan_header *eh; struct ip *ip; struct tcphdr *th; - if (((mp->m_pkthdr.csum_flags & CSUM_TSO) == 0) || - (mp->m_pkthdr.len <= EM_TX_BUFFER_SIZE)) - return FALSE; - /* * Determine where frame payload starts. * Jump over vlan headers if already present @@ -3579,15 +3728,18 @@ em_tso_adv_setup(struct adapter *adapter, struct mbuf *mp, u32 *paylen) th->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htons(IPPROTO_TCP)); tcp_hlen = th->th_off << 2; - hdrlen = ehdrlen + ip_hlen + tcp_hlen; - /* Calculate payload, this is used in the transmit desc in encap */ - *paylen = mp->m_pkthdr.len - hdrlen; + /* + * Calculate header length, this is used + * in the transmit desc in igb_encap + */ + *hdrlen = ehdrlen + ip_hlen + tcp_hlen; /* VLAN MACLEN IPLEN */ if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT); } + vlan_macip_lens |= (ehdrlen << E1000_ADVTXD_MACLEN_SHIFT); vlan_macip_lens |= ip_hlen; TXD->vlan_macip_lens |= htole32(vlan_macip_lens); @@ -3615,6 +3767,7 @@ em_tso_adv_setup(struct adapter *adapter, struct mbuf *mp, u32 *paylen) return TRUE; } +#endif /* FreeBSD_version >= 700000 */ /********************************************************************* * @@ -3631,25 +3784,40 @@ em_tx_adv_ctx_setup(struct adapter *adapter, struct mbuf *mp) struct ether_vlan_header *eh; struct ip *ip; struct ip6_hdr *ip6; - int ehdrlen, ip_hlen; + int ehdrlen, ip_hlen = 0; u16 etype; - u8 ipproto; + u8 ipproto = 0; + bool offload = TRUE; +#if __FreeBSD_version < 700000 + struct m_tag *mtag; +#else + u16 vtag = 0; +#endif int ctxd = adapter->next_avail_tx_desc; - u16 vtag = 0; - tx_buffer = &adapter->tx_buffer_area[ctxd]; TXD = (struct e1000_adv_tx_context_desc *) &adapter->tx_desc_base[ctxd]; + if ((mp->m_pkthdr.csum_flags & CSUM_OFFLOAD) == 0) + offload = FALSE; /* Only here to handle VLANs */ /* ** In advanced descriptors the vlan tag must ** be placed into the descriptor itself. */ +#if __FreeBSD_version < 700000 + mtag = VLAN_OUTPUT_TAG(ifp, mp); + if (mtag != NULL) { + vlan_macip_lens |= + htole16(VLAN_TAG_VALUE(mtag)) << E1000_ADVTXD_VLAN_SHIFT; + } else if (offload == FALSE) + return FALSE; /* No CTX needed */ +#else if (mp->m_flags & M_VLANTAG) { vtag = htole16(mp->m_pkthdr.ether_vtag); vlan_macip_lens |= (vtag << E1000_ADVTXD_VLAN_SHIFT); - } - + } else if (offload == FALSE) + return FALSE; +#endif /* * Determine where frame payload starts. * Jump over vlan headers if already present, @@ -3671,8 +3839,10 @@ em_tx_adv_ctx_setup(struct adapter *adapter, struct mbuf *mp) case ETHERTYPE_IP: ip = (struct ip *)(mp->m_data + ehdrlen); ip_hlen = ip->ip_hl << 2; - if (mp->m_len < ehdrlen + ip_hlen) - return FALSE; /* failure */ + if (mp->m_len < ehdrlen + ip_hlen) { + offload = FALSE; + break; + } ipproto = ip->ip_p; type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV4; break; @@ -3685,7 +3855,8 @@ em_tx_adv_ctx_setup(struct adapter *adapter, struct mbuf *mp) type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_IPV6; break; default: - return FALSE; + offload = FALSE; + break; } vlan_macip_lens |= ip_hlen; @@ -3700,6 +3871,9 @@ em_tx_adv_ctx_setup(struct adapter *adapter, struct mbuf *mp) if (mp->m_pkthdr.csum_flags & CSUM_UDP) type_tucmd_mlhl |= E1000_ADVTXD_TUCMD_L4T_UDP; break; + default: + offload = FALSE; + break; } /* Now copy bits into descriptor */ @@ -3717,7 +3891,7 @@ em_tx_adv_ctx_setup(struct adapter *adapter, struct mbuf *mp) adapter->next_avail_tx_desc = ctxd; --adapter->num_tx_desc_avail; - return TRUE; + return (offload); } @@ -3736,7 +3910,7 @@ em_txeof(struct adapter *adapter) struct e1000_tx_desc *tx_desc, *eop_desc; struct ifnet *ifp = adapter->ifp; - EM_LOCK_ASSERT(adapter); + EM_TX_LOCK_ASSERT(adapter); if (adapter->num_tx_desc_avail == adapter->num_tx_desc) return; @@ -3822,6 +3996,28 @@ em_txeof(struct adapter *adapter) return; } +/********************************************************************* + * + * When Link is lost sometimes there is work still in the TX ring + * which will result in a watchdog, rather than allow that do an + * attempted cleanup and then reinit here. Note that this has been + * seens mostly with fiber adapters. + * + **********************************************************************/ +static void +em_tx_purge(struct adapter *adapter) +{ + if ((!adapter->link_active) && (adapter->watchdog_timer)) { + EM_TX_LOCK(adapter); + em_txeof(adapter); + EM_TX_UNLOCK(adapter); + if (adapter->watchdog_timer) { /* Still not clean? */ + adapter->watchdog_timer = 0; + em_init_locked(adapter); + } + } +} + /********************************************************************* * * Get a buffer from system mbuf buffer pool. @@ -3843,7 +4039,7 @@ em_get_buf(struct adapter *adapter, int i) } m->m_len = m->m_pkthdr.len = MCLBYTES; - if (adapter->hw.mac.max_frame_size <= (MCLBYTES - ETHER_ALIGN)) + if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN)) m_adj(m, ETHER_ALIGN); /* @@ -3890,16 +4086,17 @@ em_allocate_receive_structures(struct adapter *adapter) int i, error; adapter->rx_buffer_area = malloc(sizeof(struct em_buffer) * - adapter->num_rx_desc, M_DEVBUF, M_NOWAIT); + adapter->num_rx_desc, M_DEVBUF, M_NOWAIT | M_ZERO); if (adapter->rx_buffer_area == NULL) { device_printf(dev, "Unable to allocate rx_buffer memory\n"); return (ENOMEM); } - bzero(adapter->rx_buffer_area, - sizeof(struct em_buffer) * adapter->num_rx_desc); - - error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ +#if __FreeBSD_version >= 700000 + error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ +#else + error = bus_dma_tag_create(NULL, /* parent */ +#endif 1, 0, /* alignment, bounds */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ @@ -3937,15 +4134,6 @@ em_allocate_receive_structures(struct adapter *adapter) } } - /* Setup the initial buffers */ - for (i = 0; i < adapter->num_rx_desc; i++) { - error = em_get_buf(adapter, i); - if (error) - goto fail; - } - bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - return (0); fail: @@ -3955,22 +4143,42 @@ fail: /********************************************************************* * - * Allocate and initialize receive structures. + * (Re)initialize receive structures. * **********************************************************************/ static int em_setup_receive_structures(struct adapter *adapter) { - int error; + struct em_buffer *rx_buffer; + int i, error; + /* Reset descriptor ring */ bzero(adapter->rx_desc_base, (sizeof(struct e1000_rx_desc)) * adapter->num_rx_desc); - if ((error = em_allocate_receive_structures(adapter)) !=0) - return (error); + /* Free current RX buffers. */ + rx_buffer = adapter->rx_buffer_area; + for (i = 0; i < adapter->num_rx_desc; i++, rx_buffer++) { + if (rx_buffer->m_head != NULL) { + bus_dmamap_sync(adapter->rxtag, rx_buffer->map, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(adapter->rxtag, rx_buffer->map); + m_freem(rx_buffer->m_head); + rx_buffer->m_head = NULL; + } + } + + /* Allocate new ones. */ + for (i = 0; i < adapter->num_rx_desc; i++) { + error = em_get_buf(adapter, i); + if (error) + return (error); + } /* Setup our descriptor pointers */ adapter->next_rx_desc_to_check = 0; + bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); return (0); } @@ -4011,10 +4219,12 @@ em_initialize_receive_unit(struct adapter *adapter) /* Setup the Base and Length of the Rx Descriptor Ring */ bus_addr = adapter->rxdma.dma_paddr; - E1000_WRITE_REG(&adapter->hw, E1000_RDLEN, adapter->num_rx_desc * - sizeof(struct e1000_rx_desc)); - E1000_WRITE_REG(&adapter->hw, E1000_RDBAH, (uint32_t)(bus_addr >> 32)); - E1000_WRITE_REG(&adapter->hw, E1000_RDBAL, (uint32_t)bus_addr); + E1000_WRITE_REG(&adapter->hw, E1000_RDLEN(0), + adapter->num_rx_desc * sizeof(struct e1000_rx_desc)); + E1000_WRITE_REG(&adapter->hw, E1000_RDBAH(0), + (uint32_t)(bus_addr >> 32)); + E1000_WRITE_REG(&adapter->hw, E1000_RDBAL(0), + (uint32_t)bus_addr); /* Setup the Receive Control Register */ reg_rctl &= ~(3 << E1000_RCTL_MO_SHIFT); @@ -4022,6 +4232,9 @@ em_initialize_receive_unit(struct adapter *adapter) E1000_RCTL_RDMTS_HALF | (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + /* Make sure VLAN Filters are off */ + reg_rctl &= ~E1000_RCTL_VFE; + if (e1000_tbi_sbp_enabled_82543(&adapter->hw)) reg_rctl |= E1000_RCTL_SBP; else @@ -4076,8 +4289,8 @@ em_initialize_receive_unit(struct adapter *adapter) * Setup the HW Rx Head and * Tail Descriptor Pointers */ - E1000_WRITE_REG(&adapter->hw, E1000_RDH, 0); - E1000_WRITE_REG(&adapter->hw, E1000_RDT, adapter->num_rx_desc - 1); + E1000_WRITE_REG(&adapter->hw, E1000_RDH(0), 0); + E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), adapter->num_rx_desc - 1); return; } @@ -4205,10 +4418,12 @@ em_rxeof(struct adapter *adapter, int count) last_byte = *(mtod(mp, caddr_t) + desc_len - 1); if (TBI_ACCEPT(&adapter->hw, status, - current_desc->errors, pkt_len, last_byte)) { + current_desc->errors, pkt_len, last_byte, + adapter->min_frame_size, adapter->max_frame_size)) { e1000_tbi_adjust_stats_82543(&adapter->hw, &adapter->stats, pkt_len, - adapter->hw.mac.addr); + adapter->hw.mac.addr, + adapter->max_frame_size); if (len > 0) len--; } else @@ -4252,16 +4467,22 @@ em_rxeof(struct adapter *adapter, int count) em_receive_checksum(adapter, current_desc, adapter->fmp); #ifndef __NO_STRICT_ALIGNMENT - if (adapter->hw.mac.max_frame_size > + if (adapter->max_frame_size > (MCLBYTES - ETHER_ALIGN) && em_fixup_rx(adapter) != 0) goto skip; #endif if (status & E1000_RXD_STAT_VP) { +#if __FreeBSD_version < 700000 + VLAN_INPUT_TAG_NEW(ifp, adapter->fmp, + (le16toh(current_desc->special) & + E1000_RXD_SPC_VLAN_MASK)); +#else adapter->fmp->m_pkthdr.ether_vtag = (le16toh(current_desc->special) & E1000_RXD_SPC_VLAN_MASK); adapter->fmp->m_flags |= M_VLANTAG; +#endif } #ifndef __NO_STRICT_ALIGNMENT skip: @@ -4278,7 +4499,7 @@ discard: mp->m_len = mp->m_pkthdr.len = MCLBYTES; mp->m_data = mp->m_ext.ext_buf; mp->m_next = NULL; - if (adapter->hw.mac.max_frame_size <= + if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN)) m_adj(mp, ETHER_ALIGN); if (adapter->fmp != NULL) { @@ -4299,10 +4520,10 @@ discard: i = 0; if (m != NULL) { adapter->next_rx_desc_to_check = i; -#ifdef DEVICE_POLLING - EM_UNLOCK(adapter); +#ifndef EM_FAST_IRQ + EM_CORE_UNLOCK(adapter); (*ifp->if_input)(ifp, m); - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); #else /* Already running unlocked */ (*ifp->if_input)(ifp, m); @@ -4316,7 +4537,7 @@ discard: /* Advance the E1000's Receive Queue #0 "Tail Pointer". */ if (--i < 0) i = adapter->num_rx_desc - 1; - E1000_WRITE_REG(&adapter->hw, E1000_RDT, i); + E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i); if (!((current_desc->status) & E1000_RXD_STAT_DD)) return (0); @@ -4412,14 +4633,15 @@ em_receive_checksum(struct adapter *adapter, } } - +/* + * This turns on the hardware offload of the VLAN + * tag insertion and strip + */ static void -em_enable_vlans(struct adapter *adapter) +em_enable_hw_vlans(struct adapter *adapter) { uint32_t ctrl; - E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN); - ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL); ctrl |= E1000_CTRL_VME; E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl); @@ -4735,7 +4957,7 @@ em_update_stats_counters(struct adapter *adapter) { struct ifnet *ifp; - if(adapter->hw.media_type == e1000_media_type_copper || + if(adapter->hw.phy.media_type == e1000_media_type_copper || (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) { adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS); adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC); @@ -4769,10 +4991,8 @@ em_update_stats_counters(struct adapter *adapter) /* For the 64-bit byte counters the low dword must be read first. */ /* Both registers clear on the read of the high dword */ - adapter->stats.gorcl += E1000_READ_REG(&adapter->hw, E1000_GORCL); - adapter->stats.gorch += E1000_READ_REG(&adapter->hw, E1000_GORCH); - adapter->stats.gotcl += E1000_READ_REG(&adapter->hw, E1000_GOTCL); - adapter->stats.gotch += E1000_READ_REG(&adapter->hw, E1000_GOTCH); + adapter->stats.gorc += E1000_READ_REG(&adapter->hw, E1000_GORCH); + adapter->stats.gotc += E1000_READ_REG(&adapter->hw, E1000_GOTCH); adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, E1000_RNBC); adapter->stats.ruc += E1000_READ_REG(&adapter->hw, E1000_RUC); @@ -4780,10 +5000,8 @@ em_update_stats_counters(struct adapter *adapter) adapter->stats.roc += E1000_READ_REG(&adapter->hw, E1000_ROC); adapter->stats.rjc += E1000_READ_REG(&adapter->hw, E1000_RJC); - adapter->stats.torl += E1000_READ_REG(&adapter->hw, E1000_TORL); - adapter->stats.torh += E1000_READ_REG(&adapter->hw, E1000_TORH); - adapter->stats.totl += E1000_READ_REG(&adapter->hw, E1000_TOTL); - adapter->stats.toth += E1000_READ_REG(&adapter->hw, E1000_TOTH); + adapter->stats.tor += E1000_READ_REG(&adapter->hw, E1000_TORH); + adapter->stats.tot += E1000_READ_REG(&adapter->hw, E1000_TOTH); adapter->stats.tpr += E1000_READ_REG(&adapter->hw, E1000_TPR); adapter->stats.tpt += E1000_READ_REG(&adapter->hw, E1000_TPT); @@ -4847,8 +5065,8 @@ em_print_debug_info(struct adapter *adapter) ((E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff0000) >> 16),\ (E1000_READ_REG(&adapter->hw, E1000_PBA) & 0xffff) ); device_printf(dev, "Flow control watermarks high = %d low = %d\n", - adapter->hw.mac.fc_high_water, - adapter->hw.mac.fc_low_water); + adapter->hw.fc.high_water, + adapter->hw.fc.low_water); device_printf(dev, "tx_int_delay = %d, tx_abs_int_delay = %d\n", E1000_READ_REG(&adapter->hw, E1000_TIDV), E1000_READ_REG(&adapter->hw, E1000_TADV)); @@ -4859,11 +5077,11 @@ em_print_debug_info(struct adapter *adapter) (long long)adapter->tx_fifo_wrk_cnt, (long long)adapter->tx_fifo_reset_cnt); device_printf(dev, "hw tdh = %d, hw tdt = %d\n", - E1000_READ_REG(&adapter->hw, E1000_TDH), - E1000_READ_REG(&adapter->hw, E1000_TDT)); + E1000_READ_REG(&adapter->hw, E1000_TDH(0)), + E1000_READ_REG(&adapter->hw, E1000_TDT(0))); device_printf(dev, "hw rdh = %d, hw rdt = %d\n", - E1000_READ_REG(&adapter->hw, E1000_RDH), - E1000_READ_REG(&adapter->hw, E1000_RDT)); + E1000_READ_REG(&adapter->hw, E1000_RDH(0)), + E1000_READ_REG(&adapter->hw, E1000_RDT(0))); device_printf(dev, "Num Tx descriptors avail = %d\n", adapter->num_tx_desc_avail); device_printf(dev, "Tx Descriptors not avail1 = %ld\n", @@ -4908,7 +5126,8 @@ em_print_hw_stats(struct adapter *adapter) (long long)adapter->stats.crcerrs); device_printf(dev, "Alignment errors = %lld\n", (long long)adapter->stats.algnerrc); - device_printf(dev, "Carrier extension errors = %lld\n", + /* On 82575 these are collision counts */ + device_printf(dev, "Collision/Carrier extension errors = %lld\n", (long long)adapter->stats.cexterr); device_printf(dev, "RX overruns = %ld\n", adapter->rx_overruns); device_printf(dev, "watchdog timeouts = %ld\n", @@ -4931,6 +5150,33 @@ em_print_hw_stats(struct adapter *adapter) (long long)adapter->stats.tsctfc); } +/********************************************************************** + * + * This routine provides a way to dump out the adapter eeprom, + * often a useful debug/service tool. This only dumps the first + * 32 words, stuff that matters is in that extent. + * + **********************************************************************/ +static void +em_print_nvm_info(struct adapter *adapter) +{ + u16 eeprom_data; + int i, j, row = 0; + + /* Its a bit crude, but it gets the job done */ + printf("\nInterface EEPROM Dump:\n"); + printf("Offset\n0x0000 "); + for (i = 0, j = 0; i < 32; i++, j++) { + if (j == 8) { /* Make the offset block */ + j = 0; ++row; + printf("\n0x00%x0 ",row); + } + e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data); + printf("%04x ", eeprom_data); + } + printf("\n"); +} + static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS) { @@ -4948,6 +5194,15 @@ em_sysctl_debug_info(SYSCTL_HANDLER_ARGS) adapter = (struct adapter *)arg1; em_print_debug_info(adapter); } + /* + * This value will cause a hex dump of the + * first 32 16-bit words of the EEPROM to + * the screen. + */ + if (result == 2) { + adapter = (struct adapter *)arg1; + em_print_nvm_info(adapter); + } return (error); } @@ -4996,7 +5251,7 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS) adapter = info->adapter; - EM_LOCK(adapter); + EM_CORE_LOCK(adapter); regval = E1000_READ_OFFSET(&adapter->hw, info->offset); regval = (regval & ~0xffff) | (ticks & 0xffff); /* Handle a few special cases. */ @@ -5014,7 +5269,7 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS) break; } E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval); - EM_UNLOCK(adapter); + EM_CORE_UNLOCK(adapter); return (0); } @@ -5032,7 +5287,7 @@ em_add_int_delay_sysctl(struct adapter *adapter, const char *name, info, 0, em_sysctl_int_delay, "I", description); } -#ifndef DEVICE_POLLING +#ifdef EM_FAST_IRQ static void em_add_rx_process_limit(struct adapter *adapter, const char *name, const char *description, int *limit, int value) diff --git a/sys/dev/em/if_em.h b/sys/dev/em/if_em.h index a4bf4fe30f62..3292e94a3b12 100644 --- a/sys/dev/em/if_em.h +++ b/sys/dev/em/if_em.h @@ -135,7 +135,7 @@ POSSIBILITY OF SUCH DAMAGE. /* * This parameter controls the duration of transmit watchdog timer. */ -#define EM_TX_TIMEOUT 5 /* set to 5 seconds */ +#define EM_TX_TIMEOUT 5 /* * This parameter controls when the driver calls the routine to reclaim @@ -185,10 +185,14 @@ POSSIBILITY OF SUCH DAMAGE. #define MAX_NUM_MULTICAST_ADDRESSES 128 #define PCI_ANY_ID (~0U) #define ETHER_ALIGN 2 -#define EM_TX_BUFFER_SIZE ((uint32_t) 1514) #define EM_FC_PAUSE_TIME 0x0680 #define EM_EEPROM_APME 0x400; +/* Code compatilbility between 6 and 7 */ +#ifndef ETHER_BPF_MTAP +#define ETHER_BPF_MTAP BPF_MTAP +#endif + /* * TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be * multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will @@ -226,11 +230,11 @@ POSSIBILITY OF SUCH DAMAGE. #define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B) #define EM_MAX_SCATTER 64 -#define EM_TSO_SIZE 65535 /* maxsize of a dma transfer */ +#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header)) #define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */ #define ETH_ZLEN 60 #define ETH_ADDR_LEN 6 -#define CSUM_OFFLOAD 7 /* Offload bits in csum flags */ +#define CSUM_OFFLOAD 7 /* Offload bits in mbuf flag */ struct adapter; @@ -274,7 +278,10 @@ struct adapter { int io_rid; int msi; int if_flags; - struct mtx mtx; + int max_frame_size; + int min_frame_size; + struct mtx core_mtx; + struct mtx tx_mtx; int em_insert_vlan_header; struct task link_task; struct task rxtx_task; @@ -284,7 +291,6 @@ struct adapter { int has_manage; /* Info about the board itself */ - uint32_t part_num; uint8_t link_active; uint16_t link_speed; uint16_t link_duplex; @@ -413,11 +419,17 @@ typedef struct _DESCRIPTOR_PAIR uint32_t elements; } DESC_ARRAY, *PDESC_ARRAY; -#define EM_LOCK_INIT(_sc, _name) \ - mtx_init(&(_sc)->mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) -#define EM_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx) -#define EM_LOCK(_sc) mtx_lock(&(_sc)->mtx) -#define EM_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) -#define EM_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED) +#define EM_CORE_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->core_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) +#define EM_TX_LOCK_INIT(_sc, _name) \ + mtx_init(&(_sc)->tx_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) +#define EM_CORE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->core_mtx) +#define EM_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->tx_mtx) +#define EM_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx) +#define EM_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx) +#define EM_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx) +#define EM_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx) +#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED) +#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED) #endif /* _EM_H_DEFINED_ */