📄 e1000_mac.c
字号:
E1000_WRITE_REG(hw, E1000_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; DEBUGFUNC("e1000_mta_set_generic"); /* * 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); E1000_WRITE_FLUSH(hw);}/** * 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 * @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 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_update_mc_addr_list_generic"); /* * 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); E1000_WRITE_FLUSH(hw); E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0); E1000_WRITE_FLUSH(hw); } } /* Clear the old settings from the MTA */ DEBUGOUT("Clearing MTA\n"); for (i = 0; i < hw->mac.mta_reg_count; i++) { E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); E1000_WRITE_FLUSH(hw); } /* Load any remaining multicast addresses into the hash table. */ for (; mc_addr_count > 0; mc_addr_count--) { hash_value = e1000_hash_mc_addr(hw, mc_addr_list); DEBUGOUT1("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() **/u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr){ u32 hash_value, hash_mask; u8 bit_shift = 0; DEBUGFUNC("e1000_hash_mc_addr_generic"); /* 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;}/** * e1000_pcix_mmrbc_workaround_generic - Fix incorrect MMRBC value * @hw: pointer to the HW structure * * In certain situations, a system BIOS may report that the PCIx maximum * memory read byte count (MMRBC) value is higher than than the actual * value. We check the PCIx command register with the current PCIx status * register. **/void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw){ u16 cmd_mmrbc; u16 pcix_cmd; u16 pcix_stat_hi_word; u16 stat_mmrbc; DEBUGFUNC("e1000_pcix_mmrbc_workaround_generic"); /* Workaround for PCI-X issue when BIOS sets MMRBC incorrectly */ if (hw->bus.type != e1000_bus_type_pcix) return; e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd); e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word); cmd_mmrbc = (pcix_cmd & PCIX_COMMAND_MMRBC_MASK) >> PCIX_COMMAND_MMRBC_SHIFT; stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> PCIX_STATUS_HI_MMRBC_SHIFT; if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; if (cmd_mmrbc > stat_mmrbc) { pcix_cmd &= ~PCIX_COMMAND_MMRBC_MASK; pcix_cmd |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd); }}/** * e1000_clear_hw_cntrs_base_generic - Clear base hardware counters * @hw: pointer to the HW structure * * Clears the base hardware counters by reading the counter registers. **/void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw){ volatile u32 temp; DEBUGFUNC("e1000_clear_hw_cntrs_base_generic"); temp = E1000_READ_REG(hw, E1000_CRCERRS); temp = E1000_READ_REG(hw, E1000_SYMERRS); temp = E1000_READ_REG(hw, E1000_MPC); temp = E1000_READ_REG(hw, E1000_SCC); temp = E1000_READ_REG(hw, E1000_ECOL); temp = E1000_READ_REG(hw, E1000_MCC); temp = E1000_READ_REG(hw, E1000_LATECOL); temp = E1000_READ_REG(hw, E1000_COLC); temp = E1000_READ_REG(hw, E1000_DC); temp = E1000_READ_REG(hw, E1000_SEC); temp = E1000_READ_REG(hw, E1000_RLEC); temp = E1000_READ_REG(hw, E1000_XONRXC); temp = E1000_READ_REG(hw, E1000_XONTXC); temp = E1000_READ_REG(hw, E1000_XOFFRXC); temp = E1000_READ_REG(hw, E1000_XOFFTXC); temp = E1000_READ_REG(hw, E1000_FCRUC); temp = E1000_READ_REG(hw, E1000_GPRC); temp = E1000_READ_REG(hw, E1000_BPRC); temp = E1000_READ_REG(hw, E1000_MPRC); temp = E1000_READ_REG(hw, E1000_GPTC); temp = E1000_READ_REG(hw, E1000_GORCL); temp = E1000_READ_REG(hw, E1000_GORCH); temp = E1000_READ_REG(hw, E1000_GOTCL); temp = E1000_READ_REG(hw, E1000_GOTCH); temp = E1000_READ_REG(hw, E1000_RNBC); temp = E1000_READ_REG(hw, E1000_RUC); temp = E1000_READ_REG(hw, E1000_RFC); temp = E1000_READ_REG(hw, E1000_ROC); temp = E1000_READ_REG(hw, E1000_RJC); temp = E1000_READ_REG(hw, E1000_TORL); temp = E1000_READ_REG(hw, E1000_TORH); temp = E1000_READ_REG(hw, E1000_TOTL); temp = E1000_READ_REG(hw, E1000_TOTH); temp = E1000_READ_REG(hw, E1000_TPR); temp = E1000_READ_REG(hw, E1000_TPT); temp = E1000_READ_REG(hw, E1000_MPTC); temp = E1000_READ_REG(hw, E1000_BPTC);}/** * e1000_check_for_copper_link_generic - Check for link (Copper) * @hw: pointer to the HW structure * * Checks to see of the link status of the hardware has changed. If a * 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){ struct e1000_mac_info *mac = &hw->mac; s32 ret_val; bool link; DEBUGFUNC("e1000_check_for_copper_link"); /* * 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. */ if (!mac->get_link_status) { ret_val = E1000_SUCCESS; goto out; } /* * 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. */ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); if (ret_val) goto out; if (!link) goto out; /* No link detected */ mac->get_link_status = FALSE; /* * 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 * we have already determined whether we have link or not. */ if (!mac->autoneg) { ret_val = -E1000_ERR_CONFIG; goto out; } /* * 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. * First, we need to restore the desired flow control * settings because we may have had to re-autoneg with a * different link partner. */ ret_val = e1000_config_fc_after_link_up_generic(hw); if (ret_val) { DEBUGOUT("Error configuring flow control\n"); }out: return ret_val;}/** * e1000_check_for_fiber_link_generic - Check for link (Fiber) * @hw: pointer to the HW structure * * 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){ struct e1000_mac_info *mac = &hw->mac; u32 rxcw; u32 ctrl; u32 status; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_check_for_fiber_link_generic"); ctrl = 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 * 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 * need to give auto-negotiation time to complete, in case the cable * was just plugged in. The autoneg_failed flag does this. */ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { if (mac->autoneg_failed == 0) { mac->autoneg_failed = 1; goto out; } DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n"); /* Disable auto-negotiation in the TXCW register */ E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE)); /* Force link-up and also force full-duplex. */ ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); /* Configure Flow Control after forcing link up. */ ret_val = e1000_config_fc_after_link_up_generic(hw); if (ret_val) { DEBUGOUT("Error configuring flow control\n"); goto out; } } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { /* * 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. */ DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n"); E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw); E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU)); mac->serdes_has_link = TRUE; }out: return ret_val;}/** * e1000_check_for_serdes_link_generic - Check for link (Serdes) * @hw: pointer to the HW structure * * 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){ struct e1000_mac_info *mac = &hw->mac; u32 rxcw; u32 ctrl; u32 status; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_check_for_serdes_link_generic"); ctrl = 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 * 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 * time to complete. */ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -