Date: Thu, 5 Jul 2012 20:26:58 +0000 (UTC) From: Jack F Vogel <jfv@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r238148 - in head/sys: conf dev/e1000 modules/igb Message-ID: <201207052026.q65KQw9m016770@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jfv Date: Thu Jul 5 20:26:57 2012 New Revision: 238148 URL: http://svn.freebsd.org/changeset/base/238148 Log: Sync with Intel internal source: shared code update and small changes in core required Add support for new i210/i211 devices Improve queue calculation based on mac type MFC after:5 days Added: head/sys/dev/e1000/e1000_i210.c (contents, props changed) head/sys/dev/e1000/e1000_i210.h (contents, props changed) Modified: head/sys/conf/files head/sys/dev/e1000/e1000_82541.c head/sys/dev/e1000/e1000_82543.c head/sys/dev/e1000/e1000_82571.c head/sys/dev/e1000/e1000_82575.c head/sys/dev/e1000/e1000_api.c head/sys/dev/e1000/e1000_api.h head/sys/dev/e1000/e1000_defines.h head/sys/dev/e1000/e1000_hw.h head/sys/dev/e1000/e1000_ich8lan.c head/sys/dev/e1000/e1000_mac.c head/sys/dev/e1000/e1000_mac.h head/sys/dev/e1000/e1000_manage.c head/sys/dev/e1000/e1000_manage.h head/sys/dev/e1000/e1000_phy.c head/sys/dev/e1000/e1000_phy.h head/sys/dev/e1000/e1000_regs.h head/sys/dev/e1000/if_em.c head/sys/dev/e1000/if_igb.c head/sys/modules/igb/Makefile Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/conf/files Thu Jul 5 20:26:57 2012 (r238148) @@ -1196,6 +1196,8 @@ dev/e1000/e1000_82575.c optional em | i compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_ich8lan.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" +dev/e1000/e1000_i210.c optional em | igb \ + compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_api.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mac.c optional em | igb \ Modified: head/sys/dev/e1000/e1000_82541.c ============================================================================== --- head/sys/dev/e1000/e1000_82541.c Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_82541.c Thu Jul 5 20:26:57 2012 (r238148) @@ -642,7 +642,7 @@ static s32 e1000_check_for_link_82541(st * of MAC speed/duplex configuration. So we only need to * configure Collision Distance in the MAC. */ - e1000_config_collision_dist_generic(hw); + mac->ops.config_collision_dist(hw); /* * Configure Flow Control now that Auto-Neg has completed. Modified: head/sys/dev/e1000/e1000_82543.c ============================================================================== --- head/sys/dev/e1000/e1000_82543.c Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_82543.c Thu Jul 5 20:26:57 2012 (r238148) @@ -1126,7 +1126,7 @@ static s32 e1000_setup_copper_link_82543 DEBUGOUT("Valid link established!!!\n"); /* Config the MAC and PHY after link is up */ if (hw->mac.type == e1000_82544) { - e1000_config_collision_dist_generic(hw); + hw->mac.ops.config_collision_dist(hw); } else { ret_val = e1000_config_mac_to_phy_82543(hw); if (ret_val) @@ -1160,7 +1160,7 @@ static s32 e1000_setup_fiber_link_82543( /* Take the link out of reset */ ctrl &= ~E1000_CTRL_LRST; - e1000_config_collision_dist_generic(hw); + hw->mac.ops.config_collision_dist(hw); ret_val = e1000_commit_fc_settings_generic(hw); if (ret_val) @@ -1259,7 +1259,7 @@ static s32 e1000_check_for_copper_link_8 * settings. */ if (mac->type == e1000_82544) - e1000_config_collision_dist_generic(hw); + hw->mac.ops.config_collision_dist(hw); else { ret_val = e1000_config_mac_to_phy_82543(hw); if (ret_val) { @@ -1433,7 +1433,7 @@ static s32 e1000_config_mac_to_phy_82543 if (phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD; - e1000_config_collision_dist_generic(hw); + hw->mac.ops.config_collision_dist(hw); /* * Set up speed in the Device Control register depending on Modified: head/sys/dev/e1000/e1000_82571.c ============================================================================== --- head/sys/dev/e1000/e1000_82571.c Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_82571.c Thu Jul 5 20:26:57 2012 (r238148) @@ -1907,7 +1907,7 @@ void e1000_set_laa_state_82571(struct e1 * incoming packets directed to this port are dropped. * Eventually the LAA will be in RAR[0] and RAR[14]. */ - e1000_rar_set_generic(hw, hw->mac.addr, + hw->mac.ops.rar_set(hw, hw->mac.addr, hw->mac.rar_entry_count - 1); return; } Modified: head/sys/dev/e1000/e1000_82575.c ============================================================================== --- head/sys/dev/e1000/e1000_82575.c Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_82575.c Thu Jul 5 20:26:57 2012 (r238148) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -38,9 +38,12 @@ * 82575GB Gigabit Network Connection * 82576 Gigabit Network Connection * 82576 Quad Port Gigabit Mezzanine Adapter + * 82580 Gigabit Network Connection + * I350 Gigabit Network Connection */ #include "e1000_api.h" +#include "e1000_i210.h" static s32 e1000_init_phy_params_82575(struct e1000_hw *hw); static s32 e1000_init_mac_params_82575(struct e1000_hw *hw); @@ -162,6 +165,9 @@ static s32 e1000_init_phy_params_82575(s DEBUGFUNC("e1000_init_phy_params_82575"); + phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic; + phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic; + if (hw->phy.media_type != e1000_media_type_copper) { phy->type = e1000_phy_none; goto out; @@ -195,12 +201,22 @@ static s32 e1000_init_phy_params_82575(s if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) { phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575; phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575; - } else if (hw->mac.type >= e1000_82580) { - phy->ops.read_reg = e1000_read_phy_reg_82580; - phy->ops.write_reg = e1000_write_phy_reg_82580; } else { - phy->ops.read_reg = e1000_read_phy_reg_igp; - phy->ops.write_reg = e1000_write_phy_reg_igp; + switch (hw->mac.type) { + case e1000_82580: + case e1000_i350: + phy->ops.read_reg = e1000_read_phy_reg_82580; + phy->ops.write_reg = e1000_write_phy_reg_82580; + break; + case e1000_i210: + case e1000_i211: + phy->ops.read_reg = e1000_read_phy_reg_gs40g; + phy->ops.write_reg = e1000_write_phy_reg_gs40g; + break; + default: + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.write_reg = e1000_write_phy_reg_igp; + } } /* Set phy->phy_addr and phy->id. */ @@ -245,6 +261,15 @@ static s32 e1000_init_phy_params_82575(s phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580; phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580; break; + case I210_I_PHY_ID: + phy->type = e1000_phy_i210; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + break; default: ret_val = -E1000_ERR_PHY; goto out; @@ -281,28 +306,32 @@ s32 e1000_init_nvm_params_82575(struct e size = 15; nvm->word_size = 1 << size; - nvm->opcode_bits = 8; - nvm->delay_usec = 1; - switch (nvm->override) { - case e1000_nvm_override_spi_large: - nvm->page_size = 32; - nvm->address_bits = 16; - break; - case e1000_nvm_override_spi_small: - nvm->page_size = 8; - nvm->address_bits = 8; - break; - default: - nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; - nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; - break; - } - - nvm->type = e1000_nvm_eeprom_spi; - - if (nvm->word_size == (1 << 15)) - nvm->page_size = 128; + if (hw->mac.type < e1000_i210) { + nvm->opcode_bits = 8; + nvm->delay_usec = 1; + + switch (nvm->override) { + case e1000_nvm_override_spi_large: + nvm->page_size = 32; + nvm->address_bits = 16; + break; + case e1000_nvm_override_spi_small: + nvm->page_size = 8; + nvm->address_bits = 8; + break; + default: + nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; + nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? + 16 : 8; + break; + } + if (nvm->word_size == (1 << 15)) + nvm->page_size = 128; + nvm->type = e1000_nvm_eeprom_spi; + } else { + nvm->type = e1000_nvm_flash_hw; + } /* Function Pointers */ nvm->ops.acquire = e1000_acquire_nvm_82575; nvm->ops.release = e1000_release_nvm_82575; @@ -316,7 +345,7 @@ s32 e1000_init_nvm_params_82575(struct e nvm->ops.update = e1000_update_nvm_checksum_generic; nvm->ops.valid_led_default = e1000_valid_led_default_82575; - /* override genric family function pointers for specific descendants */ + /* override generic family function pointers for specific descendants */ switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = e1000_validate_nvm_checksum_82580; @@ -368,8 +397,7 @@ static s32 e1000_init_mac_params_82575(s mac->has_fwsm = TRUE; /* ARC supported; valid only if manageability features are enabled. */ mac->arc_subsystem_valid = - (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) - ? TRUE : FALSE; + !!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK); /* Function pointers */ @@ -394,8 +422,6 @@ static s32 e1000_init_mac_params_82575(s mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575; /* check for link */ mac->ops.check_for_link = e1000_check_for_link_82575; - /* receive address register setting */ - mac->ops.rar_set = e1000_rar_set_generic; /* read mac address */ mac->ops.read_mac_addr = e1000_read_mac_addr_82575; /* configure collision distance */ @@ -428,6 +454,13 @@ static s32 e1000_init_mac_params_82575(s mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575; /* link info */ mac->ops.get_link_up_info = e1000_get_link_up_info_82575; + /* acquire SW_FW sync */ + mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575; + mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575; + if (mac->type >= e1000_i210) { + mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210; + mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210; + } /* set lan id for port to determine which phy lock to use */ hw->mac.ops.set_lan_id(hw); @@ -470,7 +503,7 @@ static s32 e1000_acquire_phy_82575(struc else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - return e1000_acquire_swfw_sync_82575(hw, mask); + return hw->mac.ops.acquire_swfw_sync(hw, mask); } /** @@ -492,7 +525,7 @@ static void e1000_release_phy_82575(stru else if (hw->bus.func == E1000_FUNC_3) mask = E1000_SWFW_PHY3_SM; - e1000_release_swfw_sync_82575(hw, mask); + hw->mac.ops.release_swfw_sync(hw, mask); } /** @@ -796,7 +829,7 @@ static s32 e1000_set_d0_lplu_state_82580 { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; - u16 data; + u32 data; DEBUGFUNC("e1000_set_d0_lplu_state_82580"); @@ -844,7 +877,7 @@ s32 e1000_set_d3_lplu_state_82580(struct { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; - u16 data; + u32 data; DEBUGFUNC("e1000_set_d3_lplu_state_82580"); @@ -918,11 +951,7 @@ static s32 e1000_acquire_nvm_82575(struc } - switch (hw->mac.type) { - default: - ret_val = e1000_acquire_nvm_generic(hw); - } - + ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); @@ -941,10 +970,8 @@ static void e1000_release_nvm_82575(stru { DEBUGFUNC("e1000_release_nvm_82575"); - switch (hw->mac.type) { - default: - e1000_release_nvm_generic(hw); - } + e1000_release_nvm_generic(hw); + e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); } @@ -1058,7 +1085,7 @@ static s32 e1000_get_cfg_done_82575(stru DEBUGOUT("MNG configuration cycle has not completed.\n"); /* If EEPROM is not marked present, init the PHY manually */ - if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) && + if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) && (hw->phy.type == e1000_phy_igp_3)) e1000_phy_init_script_igp3(hw); @@ -1115,6 +1142,7 @@ static s32 e1000_check_for_link_82575(st * continue to check for link. */ hw->mac.get_link_status = !hw->mac.serdes_has_link; + } else { ret_val = e1000_check_for_copper_link_generic(hw); } @@ -1168,11 +1196,6 @@ static s32 e1000_get_pcs_speed_and_duple DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575"); - /* Set up defaults for the return values of this function */ - mac->serdes_has_link = FALSE; - *speed = 0; - *duplex = 0; - /* * Read the PCS Status register for link state. For non-copper mode, * the status register is not accurate. The PCS status register is @@ -1181,11 +1204,9 @@ static s32 e1000_get_pcs_speed_and_duple pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT); /* - * 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 + * The link up bit determines when link is up on autoneg. */ - if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) { + if (pcs & E1000_PCS_LSTS_LINK_OK) { mac->serdes_has_link = TRUE; /* Detect and store PCS speed */ @@ -1201,6 +1222,10 @@ static s32 e1000_get_pcs_speed_and_duple *duplex = FULL_DUPLEX; else *duplex = HALF_DUPLEX; + } else { + mac->serdes_has_link = FALSE; + *speed = 0; + *duplex = 0; } return E1000_SUCCESS; @@ -1293,7 +1318,7 @@ static s32 e1000_reset_hw_82575(struct e } /* If EEPROM is not present, run manual init scripts */ - if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) + if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES)) e1000_reset_init_script_82575(hw); /* Clear any pending interrupt events. */ @@ -1396,6 +1421,7 @@ static s32 e1000_setup_copper_link_82575 } } switch (hw->phy.type) { + case e1000_phy_i210: case e1000_phy_m88: if (hw->phy.id == I347AT4_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID || @@ -1605,31 +1631,28 @@ static s32 e1000_get_media_type_82575(st } /* Read Init Control Word #3*/ hw->nvm.ops.read(hw, init_ctrl_wd_3_offset, 1, &init_ctrl_wd_3); + + /* + * Align link mode bits to + * their CTRL_EXT location. + */ current_link_mode = init_ctrl_wd_3; + current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET - + init_ctrl_wd_3_bit_offset); + current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK; + /* * Switch to CSR for all but internal PHY. */ - if ((init_ctrl_wd_3 << (E1000_CTRL_EXT_LINK_MODE_OFFSET - - init_ctrl_wd_3_bit_offset)) != - E1000_CTRL_EXT_LINK_MODE_GMII) { - current_link_mode = ctrl_ext; - init_ctrl_wd_3_bit_offset = - E1000_CTRL_EXT_LINK_MODE_OFFSET; - } + if (current_link_mode != E1000_CTRL_EXT_LINK_MODE_GMII) + /* Take link mode from CSR */ + current_link_mode = ctrl_ext & + E1000_CTRL_EXT_LINK_MODE_MASK; } else { /* Take link mode from CSR */ - current_link_mode = ctrl_ext; - init_ctrl_wd_3_bit_offset = E1000_CTRL_EXT_LINK_MODE_OFFSET; + current_link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK; } - /* - * Align link mode bits to - * their CTRL_EXT location. - */ - current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET - - init_ctrl_wd_3_bit_offset); - current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK; - switch (current_link_mode) { case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: @@ -2331,7 +2354,7 @@ static s32 e1000_reset_hw_82580(struct e msec_delay(10); /* Determine whether or not a global dev reset is requested */ - if (global_device_reset && e1000_acquire_swfw_sync_82575(hw, + if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw, swmbsw_mask)) global_device_reset = FALSE; @@ -2359,7 +2382,7 @@ static s32 e1000_reset_hw_82580(struct e } /* If EEPROM is not present, run manual init scripts */ - if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) + if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES)) e1000_reset_init_script_82575(hw); /* clear global device reset status bit */ @@ -2378,7 +2401,7 @@ static s32 e1000_reset_hw_82580(struct e /* Release semaphore */ if (global_device_reset) - e1000_release_swfw_sync_82575(hw, swmbsw_mask); + hw->mac.ops.release_swfw_sync(hw, swmbsw_mask); return ret_val; } @@ -2538,7 +2561,7 @@ static s32 e1000_update_nvm_checksum_825 goto out; } - if ((nvm_data & NVM_COMPATIBILITY_BIT_MASK) == 0) { + if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) { /* set compatibility bit to validate checksums appropriately */ nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK; ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1, @@ -2737,6 +2760,7 @@ s32 e1000_set_i2c_bb(struct e1000_hw *hw * e1000_read_i2c_byte_generic - Reads 8 bit word over I2C * @hw: pointer to hardware structure * @byte_offset: byte offset to read + * @dev_addr: device address * @data: value read * * Performs byte read operation over I2C interface at @@ -2750,14 +2774,14 @@ s32 e1000_read_i2c_byte_generic(struct e u32 retry = 1; u16 swfw_mask = 0; - bool nack = 1; + bool nack = TRUE; DEBUGFUNC("e1000_read_i2c_byte_generic"); swfw_mask = E1000_SWFW_PHY0_SM; do { - if (e1000_acquire_swfw_sync_82575(hw, swfw_mask) + if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) { status = E1000_ERR_SWFW_SYNC; goto read_byte_out; @@ -2805,7 +2829,7 @@ s32 e1000_read_i2c_byte_generic(struct e break; fail: - e1000_release_swfw_sync_82575(hw, swfw_mask); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); msec_delay(100); e1000_i2c_bus_clear(hw); retry++; @@ -2816,7 +2840,7 @@ fail: } while (retry < max_retry); - e1000_release_swfw_sync_82575(hw, swfw_mask); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); read_byte_out: @@ -2827,6 +2851,7 @@ read_byte_out: * e1000_write_i2c_byte_generic - Writes 8 bit word over I2C * @hw: pointer to hardware structure * @byte_offset: byte offset to write + * @dev_addr: device address * @data: value to write * * Performs byte write operation over I2C interface at @@ -2844,7 +2869,7 @@ s32 e1000_write_i2c_byte_generic(struct swfw_mask = E1000_SWFW_PHY0_SM; - if (e1000_acquire_swfw_sync_82575(hw, swfw_mask) != E1000_SUCCESS) { + if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) { status = E1000_ERR_SWFW_SYNC; goto write_byte_out; } @@ -2888,7 +2913,7 @@ fail: DEBUGOUT("I2C byte write error.\n"); } while (retry < max_retry); - e1000_release_swfw_sync_82575(hw, swfw_mask); + hw->mac.ops.release_swfw_sync(hw, swfw_mask); write_byte_out: @@ -3020,7 +3045,7 @@ static s32 e1000_get_i2c_ack(struct e100 u32 i = 0; u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS); u32 timeout = 10; - bool ack = 1; + bool ack = TRUE; DEBUGFUNC("e1000_get_i2c_ack"); @@ -3040,7 +3065,7 @@ static s32 e1000_get_i2c_ack(struct e100 return E1000_ERR_I2C; ack = e1000_get_i2c_data(&i2cctl); - if (ack == 1) { + if (ack) { DEBUGOUT("I2C ack was not received.\n"); status = E1000_ERR_I2C; } Modified: head/sys/dev/e1000/e1000_api.c ============================================================================== --- head/sys/dev/e1000/e1000_api.c Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_api.c Thu Jul 5 20:26:57 2012 (r238148) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -323,6 +323,17 @@ s32 e1000_set_mac_type(struct e1000_hw * case E1000_DEV_ID_I350_DA4: mac->type = e1000_i350; break; + case E1000_DEV_ID_I210_COPPER: + case E1000_DEV_ID_I210_COPPER_OEM1: + case E1000_DEV_ID_I210_COPPER_IT: + case E1000_DEV_ID_I210_FIBER: + case E1000_DEV_ID_I210_SERDES: + case E1000_DEV_ID_I210_SGMII: + mac->type = e1000_i210; + break; + case E1000_DEV_ID_I211_COPPER: + mac->type = e1000_i211; + break; case E1000_DEV_ID_82576_VF: mac->type = e1000_vfadapt; break; @@ -425,6 +436,10 @@ s32 e1000_setup_init_funcs(struct e1000_ case e1000_i350: e1000_init_function_pointers_82575(hw); break; + case e1000_i210: + case e1000_i211: + e1000_init_function_pointers_i210(hw); + break; case e1000_vfadapt: e1000_init_function_pointers_vf(hw); break; Modified: head/sys/dev/e1000/e1000_api.h ============================================================================== --- head/sys/dev/e1000/e1000_api.h Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_api.h Thu Jul 5 20:26:57 2012 (r238148) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ extern void e1000_rx_fifo_flush_82575(st extern void e1000_init_function_pointers_vf(struct e1000_hw *hw); extern void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw); extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw); +extern void e1000_init_function_pointers_i210(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); @@ -118,6 +119,7 @@ s32 e1000_mng_write_dhcp_info(struct e10 u32 e1000_translate_register_82542(u32 reg); + /* * TBI_ACCEPT macro definition: * Modified: head/sys/dev/e1000/e1000_defines.h ============================================================================== --- head/sys/dev/e1000/e1000_defines.h Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_defines.h Thu Jul 5 20:26:57 2012 (r238148) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -1344,6 +1344,16 @@ #define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ #define E1000_EECD_SECVAL_SHIFT 22 #define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES) +#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */ +#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done */ +#define E1000_EECD_FLASH_DETECTED_I210 0x00080000 /* FLASH detected */ +#define E1000_FLUDONE_ATTEMPTS 20000 +#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */ +#define E1000_I210_FIFO_SEL_RX 0x00 +#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i)) +#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0) +#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06 +#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01 #define E1000_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */ #define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */ @@ -1361,6 +1371,20 @@ #define NVM_VERSION 0x0005 #define NVM_SERDES_AMPLITUDE 0x0006 /* SERDES output amplitude */ #define NVM_PHY_CLASS_WORD 0x0007 +#define NVM_ETRACK_WORD 0x0042 +#define NVM_COMB_VER_OFF 0x0083 +#define NVM_COMB_VER_PTR 0x003d + +#define NVM_MAC_ADDR 0x0000 +#define NVM_SUB_DEV_ID 0x000B +#define NVM_SUB_VEN_ID 0x000C +#define NVM_DEV_ID 0x000D +#define NVM_VEN_ID 0x000E +#define NVM_INIT_CTRL_2 0x000F +#define NVM_INIT_CTRL_4 0x0013 +#define NVM_LED_1_CFG 0x001C +#define NVM_LED_0_2_CFG 0x001F + #define NVM_INIT_CONTROL1_REG 0x000A #define NVM_INIT_CONTROL2_REG 0x000F #define NVM_SWDEF_PINS_CTRL_PORT_1 0x0010 @@ -1380,12 +1404,12 @@ #define E1000_NVM_CFG_DONE_PORT_2 0x100000 /* ...for third port */ #define E1000_NVM_CFG_DONE_PORT_3 0x200000 /* ...for fourth port */ -#define NVM_82580_LAN_FUNC_OFFSET(a) (a ? (0x40 + (0x40 * a)) : 0) +#define NVM_82580_LAN_FUNC_OFFSET(a) ((a) ? (0x40 + (0x40 * (a))) : 0) /* Mask bits for fields in Word 0x24 of the NVM */ #define NVM_WORD24_COM_MDIO 0x0008 /* MDIO interface shared */ #define NVM_WORD24_EXT_MDIO 0x0004 /* MDIO accesses routed extrnl */ -/* Offset of Link Mode bits for 82575 up to Kawela */ +/* Offset of Link Mode bits for 82575/82576 */ #define NVM_WORD24_LNK_MODE_OFFSET 8 /* Offset of Link Mode bits for 82580 up */ #define NVM_WORD24_82580_LNK_MODE_OFFSET 4 @@ -1525,6 +1549,7 @@ #define I82579_E_PHY_ID 0x01540090 #define I82580_I_PHY_ID 0x015403A0 #define I350_I_PHY_ID 0x015403B0 +#define I210_I_PHY_ID 0x01410C00 #define IGP04E1000_E_PHY_ID 0x02A80391 #define M88_VENDOR 0x0141 @@ -1787,6 +1812,8 @@ #define E1000_DMACR_DMAC_LX_MASK 0x30000000 #define E1000_DMACR_DMAC_LX_SHIFT 28 #define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */ +/* DMA Coalescing BMC-to-OS Watchdog Enable */ +#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000 /* DMA Coalescing Transmit Threshold */ #define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF @@ -1807,8 +1834,9 @@ /* Lx power decision based on DMA coal */ #define E1000_PCIEMISC_LX_DECISION 0x00000080 -#define E1000_LTRC_EEEMS_EN 0x00000005 /* Enable EEE LTR max send */ #define E1000_RXPBS_SIZE_I210_MASK 0x0000003F /* Rx packet buffer size */ +#define E1000_TXPB0S_SIZE_I210_MASK 0x0000003F /* Tx packet buffer 0 size */ +#define E1000_LTRC_EEEMS_EN 0x00000020 /* Enable EEE LTR max send */ /* Minimum time for 1000BASE-T where no data will be transmit following move out * of EEE LPI Tx state */ @@ -1826,12 +1854,14 @@ #define E1000_LTRMINV_SCALE_1024 2 /* Reg val to set scale to 32768 nsec */ #define E1000_LTRMINV_SCALE_32768 3 +#define E1000_LTRMINV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */ #define E1000_LTRMAXV_SCALE_MASK 0x00001C00 /* LTR maximum scale */ #define E1000_LTRMAXV_SCALE_SHIFT 10 /* Reg val to set scale to 1024 nsec */ #define E1000_LTRMAXV_SCALE_1024 2 /* Reg val to set scale to 32768 nsec */ #define E1000_LTRMAXV_SCALE_32768 3 +#define E1000_LTRMAXV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */ #define E1000_DOBFFCTL_OBFFTHR_MASK 0x000000FF /* OBFF threshold */ #define E1000_DOBFFCTL_EXIT_ACT_MASK 0x01000000 /* Exit active CB */ Modified: head/sys/dev/e1000/e1000_hw.h ============================================================================== --- head/sys/dev/e1000/e1000_hw.h Thu Jul 5 20:21:13 2012 (r238147) +++ head/sys/dev/e1000/e1000_hw.h Thu Jul 5 20:26:57 2012 (r238148) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -154,6 +154,13 @@ struct e1000_hw; #define E1000_DEV_ID_I350_SERDES 0x1523 #define E1000_DEV_ID_I350_SGMII 0x1524 #define E1000_DEV_ID_I350_DA4 0x1546 +#define E1000_DEV_ID_I210_COPPER 0x1533 +#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534 +#define E1000_DEV_ID_I210_COPPER_IT 0x1535 +#define E1000_DEV_ID_I210_FIBER 0x1536 +#define E1000_DEV_ID_I210_SERDES 0x1537 +#define E1000_DEV_ID_I210_SGMII 0x1538 +#define E1000_DEV_ID_I211_COPPER 0x1539 #define E1000_DEV_ID_DH89XXCC_SGMII 0x0438 #define E1000_DEV_ID_DH89XXCC_SERDES 0x043A #define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C @@ -203,6 +210,8 @@ enum e1000_mac_type { e1000_82576, e1000_82580, e1000_i350, + e1000_i210, + e1000_i211, e1000_vfadapt, e1000_vfadapt_i350, e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */ @@ -248,6 +257,7 @@ enum e1000_phy_type { e1000_phy_82579, e1000_phy_82580, e1000_phy_vf, + e1000_phy_i210, }; enum e1000_bus_type { @@ -674,6 +684,8 @@ struct e1000_mac_operations { struct e1000_host_mng_command_header*); s32 (*mng_enable_host_if)(struct e1000_hw *); s32 (*wait_autoneg)(struct e1000_hw *); + s32 (*acquire_swfw_sync)(struct e1000_hw *, u16); + void (*release_swfw_sync)(struct e1000_hw *, u16); }; /* @@ -911,13 +923,13 @@ struct e1000_dev_spec_ich8lan { E1000_MUTEX nvm_mutex; E1000_MUTEX swflag_mutex; bool nvm_k1_enabled; - int eee_disable; + bool eee_disable; }; struct e1000_dev_spec_82575 { bool sgmii_active; bool global_device_reset; - int eee_disable; + bool eee_disable; bool module_plugged; u32 mtu; }; @@ -967,6 +979,7 @@ struct e1000_hw { #include "e1000_80003es2lan.h" #include "e1000_ich8lan.h" #include "e1000_82575.h" +#include "e1000_i210.h" /* These functions must be implemented by drivers */ void e1000_pci_clear_mwi(struct e1000_hw *hw); Added: head/sys/dev/e1000/e1000_i210.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/e1000/e1000_i210.c Thu Jul 5 20:26:57 2012 (r238148) @@ -0,0 +1,740 @@ +/****************************************************************************** + + Copyright (c) 2001-2012, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#include "e1000_api.h" + + +static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw); +static void e1000_release_nvm_i210(struct e1000_hw *hw); +static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw); +static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw); +static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data); +static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw); +static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data); +static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, + u16 *data); + +/** + * e1000_acquire_nvm_i210 - Request for access to EEPROM + * @hw: pointer to the HW structure + * + * Acquire the necessary semaphores for exclusive access to the EEPROM. + * Set the EEPROM access request bit and wait for EEPROM access grant bit. + * 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_i210(struct e1000_hw *hw) +{ + s32 ret_val; + + DEBUGFUNC("e1000_acquire_nvm_i210"); + + ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); + + return ret_val; +} + +/** + * e1000_release_nvm_i210 - Release exclusive access to EEPROM + * @hw: pointer to the HW structure + * + * Stop any current commands to the EEPROM and clear the EEPROM request bit, + * then release the semaphores acquired. + **/ +static void e1000_release_nvm_i210(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_release_nvm_i210"); + + e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM); +} + +/** + * e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * Acquire the SW/FW semaphore to access the PHY or NVM. The mask + * will also specify which port we're acquiring the lock for. + **/ +s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + u32 swmask = mask; + u32 fwmask = mask << 16; + s32 ret_val = E1000_SUCCESS; + s32 i = 0, timeout = 200; /* FIXME: find real value to use here */ + + DEBUGFUNC("e1000_acquire_swfw_sync_i210"); + + while (i < timeout) { + if (e1000_get_hw_semaphore_i210(hw)) { + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + if (!(swfw_sync & fwmask)) + break; + + /* + * Firmware currently using resource (fwmask) + */ + e1000_put_hw_semaphore_i210(hw); + msec_delay_irq(5); + i++; + } + + if (i == timeout) { + DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); + ret_val = -E1000_ERR_SWFW_SYNC; + goto out; + } + + swfw_sync |= swmask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_i210(hw); + +out: + return ret_val; +} + +/** + * e1000_release_swfw_sync_i210 - Release SW/FW semaphore + * @hw: pointer to the HW structure + * @mask: specifies which semaphore to acquire + * + * 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. + **/ +void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask) +{ + u32 swfw_sync; + + DEBUGFUNC("e1000_release_swfw_sync_i210"); + + while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS) + ; /* Empty */ + + swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); + swfw_sync &= ~mask; + E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); + + e1000_put_hw_semaphore_i210(hw); +} + +/** + * e1000_get_hw_semaphore_i210 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM + **/ +static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw) +{ + u32 swsm; + s32 ret_val = E1000_SUCCESS; + s32 timeout = hw->nvm.word_size + 1; + s32 i = 0; + + DEBUGFUNC("e1000_get_hw_semaphore_i210"); + + /* Get the FW semaphore. */ + for (i = 0; i < timeout; i++) { + swsm = E1000_READ_REG(hw, E1000_SWSM); + E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) + break; + + usec_delay(50); + } + + if (i == timeout) { + /* Release semaphores */ + e1000_put_hw_semaphore_generic(hw); + DEBUGOUT("Driver can't access the NVM\n"); + ret_val = -E1000_ERR_NVM; + goto out; + } + +out: + return ret_val; +} + +/** + * e1000_put_hw_semaphore_i210 - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + **/ +static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw) +{ + u32 swsm; + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207052026.q65KQw9m016770>