📄 e1000_mac.c
字号:
/******************************************************************************* Intel PRO/1000 Linux driver Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. The full GNU General Public License is included in this distribution in the file called "COPYING". Contact Information: Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************/#include "e1000.h"static u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr);static s32 e1000_set_default_fc_generic(struct e1000_hw *hw);static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw);static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw);static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw);static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw);/** * e1000_init_mac_ops_generic - Initialize MAC function pointers * @hw: pointer to the HW structure * * Setups up the function pointers to no-op functions **/void e1000_init_mac_ops_generic(struct e1000_hw *hw){ struct e1000_mac_info *mac = &hw->mac; /* General Setup */ mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pcie; mac->ops.read_mac_addr = e1000e_read_mac_addr_generic; mac->ops.config_collision_dist = e1000e_config_collision_dist; /* LINK */ mac->ops.wait_autoneg = e1000_wait_autoneg; /* Management */ mac->ops.mng_host_if_write = e1000_mng_host_if_write_generic; mac->ops.mng_write_cmd_header = e1000_mng_write_cmd_header_generic; mac->ops.mng_enable_host_if = e1000_mng_enable_host_if_generic; /* VLAN, MC, etc. */ mac->ops.rar_set = e1000e_rar_set; mac->ops.validate_mdi_setting = e1000_validate_mdi_setting_generic;}/** * e1000e_get_bus_info_pcie - Get PCIe bus information * @hw: pointer to the HW structure * * Determines and stores the system bus information for a particular * network interface. The following bus information is determined and stored: * bus speed, bus width, type (PCIe), and PCIe function. **/s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw){ struct e1000_mac_info *mac = &hw->mac; struct e1000_bus_info *bus = &hw->bus; s32 ret_val; u16 pcie_link_status; bus->type = e1000_bus_type_pci_express; bus->speed = e1000_bus_speed_2500; ret_val = e1000_read_pcie_cap_reg(hw, PCIE_LINK_STATUS, &pcie_link_status); if (ret_val) bus->width = e1000_bus_width_unknown; else bus->width = (enum e1000_bus_width)((pcie_link_status & PCIE_LINK_WIDTH_MASK) >> PCIE_LINK_WIDTH_SHIFT); mac->ops.set_lan_id(hw); return E1000_SUCCESS;}/** * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices * * @hw: pointer to the HW structure * * Determines the LAN function id by reading memory-mapped registers * and swaps the port value if requested. **/static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw){ struct e1000_bus_info *bus = &hw->bus; u32 reg; /* * The status register reports the correct function number * for the device regardless of function swap state. */ reg = er32(STATUS); bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;}/** * e1000_set_lan_id_single_port - Set LAN id for a single port device * @hw: pointer to the HW structure * * Sets the LAN function id to zero for a single port device. **/void e1000_set_lan_id_single_port(struct e1000_hw *hw){ struct e1000_bus_info *bus = &hw->bus; bus->func = 0;}/** * e1000e_clear_vfta_generic - Clear VLAN filter table * @hw: pointer to the HW structure * * Clears the register array which contains the VLAN filter table by * setting all the values to 0. **/void e1000e_clear_vfta_generic(struct e1000_hw *hw){ u32 offset; for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); e1e_flush(); }}/** * e1000e_write_vfta_generic - Write value to VLAN filter table * @hw: pointer to the HW structure * @offset: register offset in VLAN filter table * @value: register value written to VLAN filter table * * Writes value at the given offset in the register array which stores * the VLAN filter table. **/void e1000e_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value){ E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); e1e_flush();}/** * e1000e_init_rx_addrs - Initialize receive address's * @hw: pointer to the HW structure * @rar_count: receive address registers * * Setups the receive address registers by setting the base receive address * register to the devices MAC address and clearing all the other receive * address registers to 0. **/void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count){ u32 i; /* Setup the receive address */ e_dbg("Programming MAC Address into RAR[0]\n"); hw->mac.ops.rar_set(hw, hw->mac.addr, 0); /* Zero out the other (rar_entry_count - 1) receive addresses */ e_dbg("Clearing RAR[1-%u]\n", rar_count-1); for (i = 1; i < rar_count; i++) { E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0); e1e_flush(); E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0); e1e_flush(); }}/** * 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]; ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, &nvm_alt_mac_addr_offset); if (ret_val) { e_dbg("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) { e_dbg("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]; hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);out: return ret_val;}/** * e1000e_rar_set - Set receive address register * @hw: pointer to the HW structure * @addr: pointer to the receive address * @index: receive address array register * * Sets the receive address array register at index to the address passed * in by addr. **/void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index){ u32 rar_low, rar_high; /* * 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] | ((u32) addr[1] << 8) | ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); /* If MAC address zero, no need to set the AV bit */ if (rar_low || rar_high) rar_high |= E1000_RAH_AV; /* * Some bridges will combine consecutive 32-bit writes into * a single burst write, which will malfunction on some * 82546 parts. The flush avoids this. */ ew32(RAL(index), rar_low); e1e_flush(); ew32(RAH(index), rar_high);}/** * e1000_mta_set_generic - Set multicast filter table address * @hw: pointer to the HW structure * @hash_value: determines the MTA register and bit to set * * The multicast table address is a register array of 32-bit registers. * The hash_value is used to determine what register the bit is in, the * 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){ u32 hash_bit, hash_reg, mta; /* * 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 * back the new value. The (hw->mac.mta_reg_count - 1) serves as a * mask to bits 31:5 of the hash value which gives us the * register we're modifying. The hash bit within that register * is determined by the lower 5 bits of the hash value. */ hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); hash_bit = hash_value & 0x1F; mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg); mta |= (1 << hash_bit); E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta); e1e_flush();}/** * e1000e_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 * @rar_used_count: the first RAR register free to program * @rar_count: total number of supported Receive Address Registers * * Updates the Receive Address Registers and Multicast Table Array. * The caller must have a packed mc_addr_list of multicast addresses. * The parameter rar_count will usually be hw->mac.rar_entry_count * unless there are workarounds that change this. **/void e1000e_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; /* * 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. */ for (i = rar_used_count; i < rar_count; i++) { if (mc_addr_count) { hw->mac.ops.rar_set(hw, mc_addr_list, i); mc_addr_count--; mc_addr_list += ETH_ADDR_LEN; } else { E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0); e1e_flush(); E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0); e1e_flush(); } } /* Clear the old settings from the MTA */ e_dbg("Clearing MTA\n"); for (i = 0; i < hw->mac.mta_reg_count; i++) { E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); e1e_flush(); } /* Load any remaining multicast addresses into the hash table. */ for (; mc_addr_count > 0; mc_addr_count--) { hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list); e_dbg("Hash value = 0x%03X\n", hash_value); hw->mac.ops.mta_set(hw, hash_value); mc_addr_list += ETH_ADDR_LEN; }}/** * e1000_hash_mc_addr_generic - Generate a multicast hash value * @hw: pointer to the HW structure * @mc_addr: pointer to a multicast address * * Generates a multicast address hash value which is used to determine * the multicast filter table array address and new table value. See * e1000_mta_set_generic() **/static u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr){ u32 hash_value, hash_mask; u8 bit_shift = 0; /* 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. */ while (hash_mask >> bit_shift != 0xFF) bit_shift++; /* * 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 * left-shifts where the MSB of mc_addr[5] would still fall within * the hash_mask. Case 0 does this exactly. Since there are a total * of 8 bits of shifting, then mc_addr[4] will shift right the * remaining number of bits. Thus 8 - bit_shift. The rest of the * 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 * 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... * [0] [1] [2] [3] [4] [5] * 01 AA 00 12 34 56 * LSB MSB * * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163 * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634 */ switch (hw->mac.mc_filter_type) { default: case 0: break; case 1: bit_shift += 1; break; case 2: bit_shift += 2; break; case 3: bit_shift += 4; break; } hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | (((u16) mc_addr[5]) << bit_shift))); return hash_value;}/** * e1000e_clear_hw_cntrs_base - Clear base hardware counters * @hw: pointer to the HW structure * * Clears the base hardware counters by reading the counter registers. **/void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw){ er32(CRCERRS); er32(SYMERRS); er32(MPC); er32(SCC); er32(ECOL); er32(MCC); er32(LATECOL); er32(COLC); er32(DC); er32(SEC); er32(RLEC); er32(XONRXC); er32(XONTXC); er32(XOFFRXC); er32(XOFFTXC); er32(FCRUC); er32(GPRC);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -