Release 4.7 drivers/net/ethernet/intel/e1000e/mac.c
  
  
/* Intel PRO/1000 Linux driver
 * Copyright(c) 1999 - 2015 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.
 *
 * 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"
/**
 *  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;
	struct e1000_adapter *adapter = hw->adapter;
	u16 pcie_link_status, cap_offset;
	cap_offset = adapter->pdev->pcie_cap;
	if (!cap_offset) {
		bus->width = e1000_bus_width_unknown;
	} else {
		pci_read_config_word(adapter->pdev,
				     cap_offset + PCIE_LINK_STATUS,
				     &pcie_link_status);
		bus->width = (enum e1000_bus_width)((pcie_link_status &
						     PCIE_LINK_WIDTH_MASK) >>
						    PCIE_LINK_WIDTH_SHIFT);
	}
	mac->ops.set_lan_id(hw);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 90 | 80.36% | 1 | 33.33% | 
| bruce allan | bruce allan | 20 | 17.86% | 1 | 33.33% | 
| jon mason | jon mason | 2 | 1.79% | 1 | 33.33% | 
 | Total | 112 | 100.00% | 3 | 100.00% | 
/**
 *  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.
 **/
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;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| bruce allan | bruce allan | 24 | 55.81% | 2 | 66.67% | 
| auke kok | auke kok | 19 | 44.19% | 1 | 33.33% | 
 | Total | 43 | 100.00% | 3 | 100.00% | 
/**
 *  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;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| bruce allan | bruce allan | 18 | 69.23% | 1 | 50.00% | 
| auke kok | auke kok | 8 | 30.77% | 1 | 50.00% | 
 | Total | 26 | 100.00% | 2 | 100.00% | 
/**
 *  e1000_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 e1000_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();
	}
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| bruce allan | bruce allan | 41 | 97.62% | 1 | 50.00% | 
| auke kok | auke kok | 1 | 2.38% | 1 | 50.00% | 
 | Total | 42 | 100.00% | 2 | 100.00% | 
/**
 *  e1000_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 e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
{
	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
	e1e_flush();
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 28 | 93.33% | 1 | 50.00% | 
| bruce allan | bruce allan | 2 | 6.67% | 1 | 50.00% | 
 | Total | 30 | 100.00% | 2 | 100.00% | 
/**
 *  e1000e_init_rx_addrs - Initialize receive address's
 *  @hw: pointer to the HW structure
 *  @rar_count: receive address registers
 *
 *  Setup 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;
	u8 mac_addr[ETH_ALEN] = { 0 };
	/* 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++)
		hw->mac.ops.rar_set(hw, mac_addr, i);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 62 | 69.66% | 1 | 25.00% | 
| bruce allan | bruce allan | 27 | 30.34% | 3 | 75.00% | 
 | Total | 89 | 100.00% | 4 | 100.00% | 
/**
 *  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 programmed into RAR0, replacing
 *  the permanent address that was installed into RAR0 by the Si on reset.
 *  This function will return SUCCESS unless it encounters an error while
 *  reading the EEPROM.
 **/
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
{
	u32 i;
	s32 ret_val;
	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
	u8 alt_mac_addr[ETH_ALEN];
	ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
	if (ret_val)
		return ret_val;
	/* not supported on 82573 */
	if (hw->mac.type == e1000_82573)
		return 0;
	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");
		return ret_val;
	}
	if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
	    (nvm_alt_mac_addr_offset == 0x0000))
		/* There is no Alternate MAC Address */
		return 0;
	if (hw->bus.func == E1000_FUNC_1)
		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
	for (i = 0; i < ETH_ALEN; 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");
			return ret_val;
		}
		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 (is_multicast_ether_addr(alt_mac_addr)) {
		e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
		return 0;
	}
	/* We have a valid alternate MAC address, and we want to treat it the
         * same as the normal permanent MAC address stored by the HW into the
         * RAR. Do this by mapping this address into RAR0.
         */
	hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| bruce allan | bruce allan | 242 | 98.78% | 9 | 90.00% | 
| tobias klauser | tobias klauser | 3 | 1.22% | 1 | 10.00% | 
 | Total | 245 | 100.00% | 10 | 100.00% | 
u32 e1000e_rar_get_count_generic(struct e1000_hw *hw)
{
	return hw->mac.rar_entry_count;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| david ertman | david ertman | 17 | 100.00% | 1 | 100.00% | 
 | Total | 17 | 100.00% | 1 | 100.00% | 
/**
 *  e1000e_rar_set_generic - 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.
 **/
int e1000e_rar_set_generic(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 parts.
         * The flushes avoid this.
         */
	ew32(RAL(index), rar_low);
	e1e_flush();
	ew32(RAH(index), rar_high);
	e1e_flush();
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 108 | 79.41% | 1 | 20.00% | 
| bruce allan | bruce allan | 24 | 17.65% | 3 | 60.00% | 
| david ertman | david ertman | 4 | 2.94% | 1 | 20.00% | 
 | Total | 136 | 100.00% | 5 | 100.00% | 
/**
 *  e1000_hash_mc_addr - 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.
 **/
static u32 e1000_hash_mc_addr(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;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 128 | 98.46% | 1 | 50.00% | 
| bruce allan | bruce allan | 2 | 1.54% | 1 | 50.00% | 
 | Total | 130 | 100.00% | 2 | 100.00% | 
/**
 *  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
 *
 *  Updates entire Multicast Table Array.
 *  The caller must have a packed mc_addr_list of multicast addresses.
 **/
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
					u8 *mc_addr_list, u32 mc_addr_count)
{
	u32 hash_value, hash_bit, hash_reg;
	int i;
	/* clear mta_shadow */
	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
	/* update mta_shadow from mc_addr_list */
	for (i = 0; (u32)i < mc_addr_count; i++) {
		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
		hash_bit = hash_value & 0x1F;
		hw->mac.mta_shadow[hash_reg] |= BIT(hash_bit);
		mc_addr_list += (ETH_ALEN);
	}
	/* replace the entire MTA table */
	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
	e1e_flush();
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 55 | 33.95% | 1 | 20.00% | 
| jesse brandeburg | jesse brandeburg | 54 | 33.33% | 1 | 20.00% | 
| bruce allan | bruce allan | 49 | 30.25% | 1 | 20.00% | 
| jacob e keller | jacob e keller | 3 | 1.85% | 1 | 20.00% | 
| jeff kirsher | jeff kirsher | 1 | 0.62% | 1 | 20.00% | 
 | Total | 162 | 100.00% | 5 | 100.00% | 
/**
 *  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);
	er32(BPRC);
	er32(MPRC);
	er32(GPTC);
	er32(GORCL);
	er32(GORCH);
	er32(GOTCL);
	er32(GOTCH);
	er32(RNBC);
	er32(RUC);
	er32(RFC);
	er32(ROC);
	er32(RJC);
	er32(TORL);
	er32(TORH);
	er32(TOTL);
	er32(TOTH);
	er32(TPR);
	er32(TPT);
	er32(MPTC);
	er32(BPTC);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 195 | 100.00% | 1 | 100.00% | 
 | Total | 195 | 100.00% | 1 | 100.00% | 
/**
 *  e1000e_check_for_copper_link - 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 e1000e_check_for_copper_link(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	s32 ret_val;
	bool 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)
		return 0;
	/* 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 = e1000e_phy_has_link_generic(hw, 1, 0, &link);
	if (ret_val)
		return ret_val;
	if (!link)
		return 0;	/* No link detected */
	mac->get_link_status = false;
	/* Check if there was DownShift, must be checked
         * immediately after link-up
         */
	e1000e_check_downshift(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)
		return -E1000_ERR_CONFIG;
	/* 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.
         */
	mac->ops.config_collision_dist(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 = e1000e_config_fc_after_link_up(hw);
	if (ret_val)
		e_dbg("Error configuring flow control\n");
	return ret_val;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 107 | 87.70% | 1 | 14.29% | 
| bruce allan | bruce allan | 15 | 12.30% | 6 | 85.71% | 
 | Total | 122 | 100.00% | 7 | 100.00% | 
/**
 *  e1000e_check_for_fiber_link - 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 e1000e_check_for_fiber_link(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	u32 rxcw;
	u32 ctrl;
	u32 status;
	s32 ret_val;
	ctrl = er32(CTRL);
	status = er32(STATUS);
	rxcw = er32(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) {
			mac->autoneg_failed = true;
			return 0;
		}
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
		/* Disable auto-negotiation in the TXCW register */
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
		/* Force link-up and also force full-duplex. */
		ctrl = er32(CTRL);
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
		ew32(CTRL, ctrl);
		/* Configure Flow Control after forcing link up. */
		ret_val = e1000e_config_fc_after_link_up(hw);
		if (ret_val) {
			e_dbg("Error configuring flow control\n");
			return ret_val;
		}
	} 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.
                 */
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
		ew32(TXCW, mac->txcw);
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
		mac->serdes_has_link = true;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 205 | 95.35% | 1 | 16.67% | 
| bruce allan | bruce allan | 9 | 4.19% | 4 | 66.67% | 
| alex chiang | alex chiang | 1 | 0.47% | 1 | 16.67% | 
 | Total | 215 | 100.00% | 6 | 100.00% | 
/**
 *  e1000e_check_for_serdes_link - 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 e1000e_check_for_serdes_link(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	u32 rxcw;
	u32 ctrl;
	u32 status;
	s32 ret_val;
	ctrl = er32(CTRL);
	status = er32(STATUS);
	rxcw = er32(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)) {
		if (!mac->autoneg_failed) {
			mac->autoneg_failed = true;
			return 0;
		}
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
		/* Disable auto-negotiation in the TXCW register */
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
		/* Force link-up and also force full-duplex. */
		ctrl = er32(CTRL);
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
		ew32(CTRL, ctrl);
		/* Configure Flow Control after forcing link up. */
		ret_val = e1000e_config_fc_after_link_up(hw);
		if (ret_val) {
			e_dbg("Error configuring flow control\n");
			return ret_val;
		}
	} 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.
                 */
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
		ew32(TXCW, mac->txcw);
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
		mac->serdes_has_link = true;
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
		/* If we force link for non-auto-negotiation switch, check
                 * link status based on MAC synchronization for internal
                 * serdes media type.
                 */
		/* SYNCH bit and IV bit are sticky. */
		usleep_range(10, 20);
		rxcw = er32(RXCW);
		if (rxcw & E1000_RXCW_SYNCH) {
			if (!(rxcw & E1000_RXCW_IV)) {
				mac->serdes_has_link = true;
				e_dbg("SERDES: Link up - forced.\n");
			}
		} else {
			mac->serdes_has_link = false;
			e_dbg("SERDES: Link down - force failed.\n");
		}
	}
	if (E1000_TXCW_ANE & er32(TXCW)) {
		status = er32(STATUS);
		if (status & E1000_STATUS_LU) {
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
			usleep_range(10, 20);
			rxcw = er32(RXCW);
			if (rxcw & E1000_RXCW_SYNCH) {
				if (!(rxcw & E1000_RXCW_IV)) {
					mac->serdes_has_link = true;
					e_dbg("SERDES: Link up - autoneg completed successfully.\n");
				} else {
					mac->serdes_has_link = false;
					e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n");
				}
			} else {
				mac->serdes_has_link = false;
				e_dbg("SERDES: Link down - no sync.\n");
			}
		} else {
			mac->serdes_has_link = false;
			e_dbg("SERDES: Link down - autoneg failed\n");
		}
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 279 | 70.28% | 1 | 10.00% | 
| bruce allan | bruce allan | 117 | 29.47% | 8 | 80.00% | 
| alex chiang | alex chiang | 1 | 0.25% | 1 | 10.00% | 
 | Total | 397 | 100.00% | 10 | 100.00% | 
/**
 *  e1000_set_default_fc_generic - Set flow control default values
 *  @hw: pointer to the HW structure
 *
 *  Read the EEPROM for the default values for flow control and store the
 *  values.
 **/
static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
{
	s32 ret_val;
	u16 nvm_data;
	/* 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
         * SW defined pins. If there is no SW over-ride of the flow
         * control setting, then the variable hw->fc will
         * be initialized based on a value in the EEPROM.
         */
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
	if (ret_val) {
		e_dbg("NVM Read Error\n");
		return ret_val;
	}
	if (!(nvm_data & NVM_WORD0F_PAUSE_MASK))
		hw->fc.requested_mode = e1000_fc_none;
	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == NVM_WORD0F_ASM_DIR)
		hw->fc.requested_mode = e1000_fc_tx_pause;
	else
		hw->fc.requested_mode = e1000_fc_full;
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 82 | 87.23% | 1 | 16.67% | 
| bruce allan | bruce allan | 6 | 6.38% | 4 | 66.67% | 
| jeff kirsher | jeff kirsher | 6 | 6.38% | 1 | 16.67% | 
 | Total | 94 | 100.00% | 6 | 100.00% | 
/**
 *  e1000e_setup_link_generic - Setup flow control and link settings
 *  @hw: pointer to the HW structure
 *
 *  Determines which flow control settings to use, then configures flow
 *  control.  Calls the appropriate media-specific link configuration
 *  function.  Assuming the adapter has a valid link partner, a valid link
 *  should be established.  Assumes the hardware has previously been reset
 *  and the transmitter and receiver are not enabled.
 **/
s32 e1000e_setup_link_generic(struct e1000_hw *hw)
{
	s32 ret_val;
	/* In the case of the phy reset being blocked, we already have a link.
         * We do not need to set it up again.
         */
	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
		return 0;
	/* If requested flow control is set to default, set flow control
         * based on the EEPROM flow control settings.
         */
	if (hw->fc.requested_mode == e1000_fc_default) {
		ret_val = e1000_set_default_fc_generic(hw);
		if (ret_val)
			return ret_val;
	}
	/* Save off the requested flow control mode for use later.  Depending
         * on the link partner's capabilities, we may or may not use this mode.
         */
	hw->fc.current_mode = hw->fc.requested_mode;
	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
	/* Call the necessary media_type subroutine to configure the link. */
	ret_val = hw->mac.ops.setup_physical_interface(hw);
	if (ret_val)
		return ret_val;
	/* 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.
         */
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
	ew32(FCT, FLOW_CONTROL_TYPE);
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
	ew32(FCTTV, hw->fc.pause_time);
	return e1000e_set_fc_watermarks(hw);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 112 | 72.73% | 2 | 20.00% | 
| bruce allan | bruce allan | 29 | 18.83% | 7 | 70.00% | 
| jeff kirsher | jeff kirsher | 13 | 8.44% | 1 | 10.00% | 
 | Total | 154 | 100.00% | 10 | 100.00% | 
/**
 *  e1000_commit_fc_settings_generic - Configure flow control
 *  @hw: pointer to the HW structure
 *
 *  Write the flow control settings to the Transmit Config Word Register (TXCW)
 *  base on the flow control settings in e1000_mac_info.
 **/
static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	u32 txcw;
	/* 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-
         * negotiation.  However, if auto-negotiation is disabled, then
         * software will have to manually configure the two flow control enable
         * bits in the CTRL register.
         *
         * The possible values of the "fc" parameter are:
         *      0:  Flow control is completely disabled
         *      1:  Rx flow control is enabled (we can receive pause frames,
         *          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.
         */
	switch (hw->fc.current_mode) {
	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
                 * 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, we will disable the adapter's ability to send
                 * PAUSE frames.
                 */
		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,
                 * 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
                 * over-ride.
                 */
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
		break;
	default:
		e_dbg("Flow control param set incorrectly\n");
		return -E1000_ERR_CONFIG;
	}
	ew32(TXCW, txcw);
	mac->txcw = txcw;
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 111 | 93.28% | 1 | 20.00% | 
| bruce allan | bruce allan | 6 | 5.04% | 3 | 60.00% | 
| jeff kirsher | jeff kirsher | 2 | 1.68% | 1 | 20.00% | 
 | Total | 119 | 100.00% | 5 | 100.00% | 
/**
 *  e1000_poll_fiber_serdes_link_generic - Poll for link up
 *  @hw: pointer to the HW structure
 *
 *  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.
 **/
static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	u32 i, status;
	s32 ret_val;
	/* 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
         * milliseconds even if the other end is doing it in SW).
         */
	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
		usleep_range(10000, 20000);
		status = er32(STATUS);
		if (status & E1000_STATUS_LU)
			break;
	}
	if (i == FIBER_LINK_UP_LIMIT) {
		e_dbg("Never got a valid link from auto-neg!!!\n");
		mac->autoneg_failed = true;
		/* 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.
                 */
		ret_val = mac->ops.check_for_link(hw);
		if (ret_val) {
			e_dbg("Error while checking for link\n");
			return ret_val;
		}
		mac->autoneg_failed = false;
	} else {
		mac->autoneg_failed = false;
		e_dbg("Valid Link Found\n");
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 122 | 91.04% | 1 | 20.00% | 
| bruce allan | bruce allan | 12 | 8.96% | 4 | 80.00% | 
 | Total | 134 | 100.00% | 5 | 100.00% | 
/**
 *  e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes
 *  @hw: pointer to the HW structure
 *
 *  Configures collision distance and flow control for fiber and serdes
 *  links.  Upon successful setup, poll for link.
 **/
s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
{
	u32 ctrl;
	s32 ret_val;
	ctrl = er32(CTRL);
	/* Take the link out of reset */
	ctrl &= ~E1000_CTRL_LRST;
	hw->mac.ops.config_collision_dist(hw);
	ret_val = e1000_commit_fc_settings_generic(hw);
	if (ret_val)
		return ret_val;
	/* 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
         * bits (RFCE and TFCE) will be set according to their negotiated value.
         */
	e_dbg("Auto-negotiation enabled\n");
	ew32(CTRL, ctrl);
	e1e_flush();
	usleep_range(1000, 2000);
	/* For these adapters, the SW definable pin 1 is set when the optics
         * detect a signal.  If we have a signal, then poll for a "Link-Up"
         * indication.
         */
	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
	} else {
		e_dbg("No signal detected\n");
	}
	return ret_val;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 99 | 84.62% | 1 | 14.29% | 
| bruce allan | bruce allan | 16 | 13.68% | 5 | 71.43% | 
| jeff kirsher | jeff kirsher | 2 | 1.71% | 1 | 14.29% | 
 | Total | 117 | 100.00% | 7 | 100.00% | 
/**
 *  e1000e_config_collision_dist_generic - Configure collision distance
 *  @hw: pointer to the HW structure
 *
 *  Configures the collision distance to the default value and is used
 *  during link setup.
 **/
void e1000e_config_collision_dist_generic(struct e1000_hw *hw)
{
	u32 tctl;
	tctl = er32(TCTL);
	tctl &= ~E1000_TCTL_COLD;
	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
	ew32(TCTL, tctl);
	e1e_flush();
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 40 | 97.56% | 1 | 50.00% | 
| bruce allan | bruce allan | 1 | 2.44% | 1 | 50.00% | 
 | Total | 41 | 100.00% | 2 | 100.00% | 
/**
 *  e1000e_set_fc_watermarks - Set flow control high/low watermarks
 *  @hw: pointer to the HW structure
 *
 *  Sets the flow control high/low threshold (watermark) registers.  If
 *  flow control XON frame transmission is enabled, then set XON frame
 *  transmission as well.
 **/
s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
{
	u32 fcrtl = 0, fcrth = 0;
	/* 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 (hw->fc.current_mode & 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 = hw->fc.low_water;
		if (hw->fc.send_xon)
			fcrtl |= E1000_FCRTL_XONE;
		fcrth = hw->fc.high_water;
	}
	ew32(FCRTL, fcrtl);
	ew32(FCRTH, fcrth);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 57 | 73.08% | 1 | 20.00% | 
| bruce allan | bruce allan | 11 | 14.10% | 3 | 60.00% | 
| jeff kirsher | jeff kirsher | 10 | 12.82% | 1 | 20.00% | 
 | Total | 78 | 100.00% | 5 | 100.00% | 
/**
 *  e1000e_force_mac_fc - Force the MAC's flow control settings
 *  @hw: pointer to the HW structure
 *
 *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
 *  device control register to reflect the adapter settings.  TFCE and RFCE
 *  need to be explicitly set by software when a copper PHY is used because
 *  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 e1000e_force_mac_fc(struct e1000_hw *hw)
{
	u32 ctrl;
	ctrl = er32(CTRL);
	/* 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 "hw->fc.current_mode" parameter.
         *
         * The possible values of the "fc" parameter are:
         *      0:  Flow control is completely disabled
         *      1:  Rx flow control is enabled (we can receive pause
         *          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.
         *  other:  No other values should be possible at this point.
         */
	e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
	switch (hw->fc.current_mode) {
	case e1000_fc_none:
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
		break;
	case e1000_fc_rx_pause:
		ctrl &= (~E1000_CTRL_TFCE);
		ctrl |= E1000_CTRL_RFCE;
		break;
	case e1000_fc_tx_pause:
		ctrl &= (~E1000_CTRL_RFCE);
		ctrl |= E1000_CTRL_TFCE;
		break;
	case e1000_fc_full:
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
		break;
	default:
		e_dbg("Flow control param set incorrectly\n");
		return -E1000_ERR_CONFIG;
	}
	ew32(CTRL, ctrl);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 109 | 91.60% | 1 | 20.00% | 
| bruce allan | bruce allan | 6 | 5.04% | 3 | 60.00% | 
| jeff kirsher | jeff kirsher | 4 | 3.36% | 1 | 20.00% | 
 | Total | 119 | 100.00% | 5 | 100.00% | 
/**
 *  e1000e_config_fc_after_link_up - Configures flow control after link
 *  @hw: pointer to the HW structure
 *
 *  Checks the status of auto-negotiation after link up to ensure that the
 *  speed and duplex were not forced.  If the link needed to be forced, then
 *  flow control needs to be forced also.  If auto-negotiation is enabled
 *  and did not fail, then we configure flow control based on our link
 *  partner.
 **/
s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	s32 ret_val = 0;
	u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
	u16 speed, duplex;
	/* 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->phy.media_type == e1000_media_type_fiber ||
		    hw->phy.media_type == e1000_media_type_internal_serdes)
			ret_val = e1000e_force_mac_fc(hw);
	} else {
		if (hw->phy.media_type == e1000_media_type_copper)
			ret_val = e1000e_force_mac_fc(hw);
	}
	if (ret_val) {
		e_dbg("Error forcing flow control settings\n");
		return ret_val;
	}
	/* 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->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.
                 */
		ret_val = e1e_rphy(hw, MII_BMSR, &mii_status_reg);
		if (ret_val)
			return ret_val;
		ret_val = e1e_rphy(hw, MII_BMSR, &mii_status_reg);
		if (ret_val)
			return ret_val;
		if (!(mii_status_reg & BMSR_ANEGCOMPLETE)) {
			e_dbg("Copper PHY and Auto Neg has not completed.\n");
			return ret_val;
		}
		/* 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
                 * flow control was negotiated.
                 */
		ret_val = e1e_rphy(hw, MII_ADVERTISE, &mii_nway_adv_reg);
		if (ret_val)
			return ret_val;
		ret_val = e1e_rphy(hw, MII_LPA, &mii_nway_lp_ability_reg);
		if (ret_val)
			return ret_val;
		/* 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
                 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
                 * 1999, describes these PAUSE resolution bits and how flow
                 * control is determined based upon these settings.
                 * NOTE:  DC = Don't Care
                 *
                 *   LOCAL DEVICE  |   LINK PARTNER
                 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
                 *-------|---------|-------|---------|--------------------
                 *   0   |    0    |  DC   |   DC    | e1000_fc_none
                 *   0   |    1    |   0   |   DC    | e1000_fc_none
                 *   0   |    1    |   1   |    0    | e1000_fc_none
                 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
                 *   1   |    0    |   0   |   DC    | e1000_fc_none
                 *   1   |   DC    |   1   |   DC    | e1000_fc_full
                 *   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
                 * Symmetric Flow Control is enabled at both ends.  The
                 * ASM_DIR bits are irrelevant per the spec.
                 *
                 * For Symmetric Flow Control:
                 *
                 *   LOCAL DEVICE  |   LINK PARTNER
                 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
                 *-------|---------|-------|---------|--------------------
                 *   1   |   DC    |   1   |   DC    | E1000_fc_full
                 *
                 */
		if ((mii_nway_adv_reg & ADVERTISE_PAUSE_CAP) &&
		    (mii_nway_lp_ability_reg & LPA_PAUSE_CAP)) {
			/* 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 (hw->fc.requested_mode == e1000_fc_full) {
				hw->fc.current_mode = e1000_fc_full;
				e_dbg("Flow Control = FULL.\n");
			} else {
				hw->fc.current_mode = e1000_fc_rx_pause;
				e_dbg("Flow Control = Rx PAUSE frames only.\n");
			}
		}
		/* 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 & ADVERTISE_PAUSE_CAP) &&
			 (mii_nway_adv_reg & ADVERTISE_PAUSE_ASYM) &&
			 (mii_nway_lp_ability_reg & LPA_PAUSE_CAP) &&
			 (mii_nway_lp_ability_reg & LPA_PAUSE_ASYM)) {
			hw->fc.current_mode = e1000_fc_tx_pause;
			e_dbg("Flow Control = Tx PAUSE frames only.\n");
		}
		/* 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 & ADVERTISE_PAUSE_CAP) &&
			 (mii_nway_adv_reg & ADVERTISE_PAUSE_ASYM) &&
			 !(mii_nway_lp_ability_reg & LPA_PAUSE_CAP) &&
			 (mii_nway_lp_ability_reg & LPA_PAUSE_ASYM)) {
			hw->fc.current_mode = e1000_fc_rx_pause;
			e_dbg("Flow Control = Rx PAUSE frames only.\n");
		} else {
			/* Per the IEEE spec, at this point flow control
                         * should be disabled.
                         */
			hw->fc.current_mode = e1000_fc_none;
			e_dbg("Flow Control = NONE.\n");
		}
		/* 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.
                 */
		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
		if (ret_val) {
			e_dbg("Error getting link speed and duplex\n");
			return ret_val;
		}
		if (duplex == HALF_DUPLEX)
			hw->fc.current_mode = e1000_fc_none;
		/* Now we call a subroutine to actually force the MAC
                 * controller to use the correct flow control settings.
                 */
		ret_val = e1000e_force_mac_fc(hw);
		if (ret_val) {
			e_dbg("Error forcing flow control settings\n");
			return ret_val;
		}
	}
	/* Check for the case where we have SerDes 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->phy.media_type == e1000_media_type_internal_serdes) &&
	    mac->autoneg) {
		/* Read the PCS_LSTS and check to see if AutoNeg
                 * has completed.
                 */
		pcs_status_reg = er32(PCS_LSTAT);
		if (!(pcs_status_reg & E1000_PCS_LSTS_AN_COMPLETE)) {
			e_dbg("PCS Auto Neg has not completed.\n");
			return ret_val;
		}
		/* The AutoNeg process has completed, so we now need to
                 * read both the Auto Negotiation Advertisement
                 * Register (PCS_ANADV) and the Auto_Negotiation Base
                 * Page Ability Register (PCS_LPAB) to determine how
                 * flow control was negotiated.
                 */
		pcs_adv_reg = er32(PCS_ANADV);
		pcs_lp_ability_reg = er32(PCS_LPAB);
		/* Two bits in the Auto Negotiation Advertisement Register
                 * (PCS_ANADV) and two bits in the Auto Negotiation Base
                 * Page Ability Register (PCS_LPAB) determine flow control
                 * for both the PHY and the link partner.  The following
                 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
                 * 1999, describes these PAUSE resolution bits and how flow
                 * control is determined based upon these settings.
                 * NOTE:  DC = Don't Care
                 *
                 *   LOCAL DEVICE  |   LINK PARTNER
                 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
                 *-------|---------|-------|---------|--------------------
                 *   0   |    0    |  DC   |   DC    | e1000_fc_none
                 *   0   |    1    |   0   |   DC    | e1000_fc_none
                 *   0   |    1    |   1   |    0    | e1000_fc_none
                 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
                 *   1   |    0    |   0   |   DC    | e1000_fc_none
                 *   1   |   DC    |   1   |   DC    | e1000_fc_full
                 *   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
                 * Symmetric Flow Control is enabled at both ends.  The
                 * ASM_DIR bits are irrelevant per the spec.
                 *
                 * For Symmetric Flow Control:
                 *
                 *   LOCAL DEVICE  |   LINK PARTNER
                 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
                 *-------|---------|-------|---------|--------------------
                 *   1   |   DC    |   1   |   DC    | e1000_fc_full
                 *
                 */
		if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
		    (pcs_lp_ability_reg & E1000_TXCW_PAUSE)) {
			/* 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 (hw->fc.requested_mode == e1000_fc_full) {
				hw->fc.current_mode = e1000_fc_full;
				e_dbg("Flow Control = FULL.\n");
			} else {
				hw->fc.current_mode = e1000_fc_rx_pause;
				e_dbg("Flow Control = Rx PAUSE frames only.\n");
			}
		}
		/* 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 (!(pcs_adv_reg & E1000_TXCW_PAUSE) &&
			 (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
			 (pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
			 (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
			hw->fc.current_mode = e1000_fc_tx_pause;
			e_dbg("Flow Control = Tx PAUSE frames only.\n");
		}
		/* 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 ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
			 (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
			 !(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
			 (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
			hw->fc.current_mode = e1000_fc_rx_pause;
			e_dbg("Flow Control = Rx PAUSE frames only.\n");
		} else {
			/* Per the IEEE spec, at this point flow control
                         * should be disabled.
                         */
			hw->fc.current_mode = e1000_fc_none;
			e_dbg("Flow Control = NONE.\n");
		}
		/* Now we call a subroutine to actually force the MAC
                 * controller to use the correct flow control settings.
                 */
		pcs_ctrl_reg = er32(PCS_LCTL);
		pcs_ctrl_reg |= E1000_PCS_LCTL_FORCE_FCTRL;
		ew32(PCS_LCTL, pcs_ctrl_reg);
		ret_val = e1000e_force_mac_fc(hw);
		if (ret_val) {
			e_dbg("Error forcing flow control settings\n");
			return ret_val;
		}
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 384 | 52.60% | 1 | 11.11% | 
| bruce allan | bruce allan | 322 | 44.11% | 6 | 66.67% | 
| jeff kirsher | jeff kirsher | 23 | 3.15% | 1 | 11.11% | 
| jesse brandeburg | jesse brandeburg | 1 | 0.14% | 1 | 11.11% | 
 | Total | 730 | 100.00% | 9 | 100.00% | 
/**
 *  e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
 *  @hw: pointer to the HW structure
 *  @speed: stores the current speed
 *  @duplex: stores the current duplex
 *
 *  Read the status register for the current speed/duplex and store the current
 *  speed and duplex for copper connections.
 **/
s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
				       u16 *duplex)
{
	u32 status;
	status = er32(STATUS);
	if (status & E1000_STATUS_SPEED_1000)
		*speed = SPEED_1000;
	else if (status & E1000_STATUS_SPEED_100)
		*speed = SPEED_100;
	else
		*speed = SPEED_10;
	if (status & E1000_STATUS_FD)
		*duplex = FULL_DUPLEX;
	else
		*duplex = HALF_DUPLEX;
	e_dbg("%u Mbps, %s Duplex\n",
	      *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10,
	      *duplex == FULL_DUPLEX ? "Full" : "Half");
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 80 | 74.77% | 1 | 33.33% | 
| joe perches | joe perches | 26 | 24.30% | 1 | 33.33% | 
| bruce allan | bruce allan | 1 | 0.93% | 1 | 33.33% | 
 | Total | 107 | 100.00% | 3 | 100.00% | 
/**
 *  e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
 *  @hw: pointer to the HW structure
 *  @speed: stores the current speed
 *  @duplex: stores the current duplex
 *
 *  Sets the speed and duplex to gigabit full duplex (the only possible option)
 *  for fiber/serdes links.
 **/
s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw __always_unused
					     *hw, u16 *speed, u16 *duplex)
{
	*speed = SPEED_1000;
	*duplex = FULL_DUPLEX;
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 31 | 96.88% | 1 | 50.00% | 
| bruce allan | bruce allan | 1 | 3.12% | 1 | 50.00% | 
 | Total | 32 | 100.00% | 2 | 100.00% | 
/**
 *  e1000e_get_hw_semaphore - Acquire hardware semaphore
 *  @hw: pointer to the HW structure
 *
 *  Acquire the HW semaphore to access the PHY or NVM
 **/
s32 e1000e_get_hw_semaphore(struct e1000_hw *hw)
{
	u32 swsm;
	s32 timeout = hw->nvm.word_size + 1;
	s32 i = 0;
	/* Get the SW semaphore */
	while (i < timeout) {
		swsm = er32(SWSM);
		if (!(swsm & E1000_SWSM_SMBI))
			break;
		usleep_range(50, 100);
		i++;
	}
	if (i == timeout) {
		e_dbg("Driver can't access device - SMBI bit is set.\n");
		return -E1000_ERR_NVM;
	}
	/* Get the FW semaphore. */
	for (i = 0; i < timeout; i++) {
		swsm = er32(SWSM);
		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
		/* Semaphore acquired if bit latched */
		if (er32(SWSM) & E1000_SWSM_SWESMBI)
			break;
		usleep_range(50, 100);
	}
	if (i == timeout) {
		/* Release semaphores */
		e1000e_put_hw_semaphore(hw);
		e_dbg("Driver can't access the NVM\n");
		return -E1000_ERR_NVM;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 150 | 94.94% | 1 | 33.33% | 
| bruce allan | bruce allan | 8 | 5.06% | 2 | 66.67% | 
 | Total | 158 | 100.00% | 3 | 100.00% | 
/**
 *  e1000e_put_hw_semaphore - Release hardware semaphore
 *  @hw: pointer to the HW structure
 *
 *  Release hardware semaphore used to access the PHY or NVM
 **/
void e1000e_put_hw_semaphore(struct e1000_hw *hw)
{
	u32 swsm;
	swsm = er32(SWSM);
	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
	ew32(SWSM, swsm);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 36 | 100.00% | 1 | 100.00% | 
 | Total | 36 | 100.00% | 1 | 100.00% | 
/**
 *  e1000e_get_auto_rd_done - Check for auto read completion
 *  @hw: pointer to the HW structure
 *
 *  Check EEPROM for Auto Read done bit.
 **/
s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
{
	s32 i = 0;
	while (i < AUTO_READ_DONE_TIMEOUT) {
		if (er32(EECD) & E1000_EECD_AUTO_RD)
			break;
		usleep_range(1000, 2000);
		i++;
	}
	if (i == AUTO_READ_DONE_TIMEOUT) {
		e_dbg("Auto read by HW from NVM has not completed.\n");
		return -E1000_ERR_RESET;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 58 | 92.06% | 1 | 33.33% | 
| bruce allan | bruce allan | 5 | 7.94% | 2 | 66.67% | 
 | Total | 63 | 100.00% | 3 | 100.00% | 
/**
 *  e1000e_valid_led_default - Verify a valid default LED config
 *  @hw: pointer to the HW structure
 *  @data: pointer to the NVM (EEPROM)
 *
 *  Read the EEPROM for the current default LED configuration.  If the
 *  LED configuration is not valid, set to a valid LED configuration.
 **/
s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data)
{
	s32 ret_val;
	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
	if (ret_val) {
		e_dbg("NVM Read Error\n");
		return ret_val;
	}
	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
		*data = ID_LED_DEFAULT;
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 63 | 98.44% | 1 | 50.00% | 
| bruce allan | bruce allan | 1 | 1.56% | 1 | 50.00% | 
 | Total | 64 | 100.00% | 2 | 100.00% | 
/**
 *  e1000e_id_led_init_generic -
 *  @hw: pointer to the HW structure
 *
 **/
s32 e1000e_id_led_init_generic(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	s32 ret_val;
	const u32 ledctl_mask = 0x000000FF;
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
	u16 data, i, temp;
	const u16 led_mask = 0x0F;
	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
	if (ret_val)
		return ret_val;
	mac->ledctl_default = er32(LEDCTL);
	mac->ledctl_mode1 = mac->ledctl_default;
	mac->ledctl_mode2 = mac->ledctl_default;
	for (i = 0; i < 4; i++) {
		temp = (data >> (i << 2)) & led_mask;
		switch (temp) {
		case ID_LED_ON1_DEF2:
		case ID_LED_ON1_ON2:
		case ID_LED_ON1_OFF2:
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
			mac->ledctl_mode1 |= ledctl_on << (i << 3);
			break;
		case ID_LED_OFF1_DEF2:
		case ID_LED_OFF1_ON2:
		case ID_LED_OFF1_OFF2:
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
			mac->ledctl_mode1 |= ledctl_off << (i << 3);
			break;
		default:
			/* Do nothing */
			break;
		}
		switch (temp) {
		case ID_LED_DEF1_ON2:
		case ID_LED_ON1_ON2:
		case ID_LED_OFF1_ON2:
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
			mac->ledctl_mode2 |= ledctl_on << (i << 3);
			break;
		case ID_LED_DEF1_OFF2:
		case ID_LED_ON1_OFF2:
		case ID_LED_OFF1_OFF2:
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
			mac->ledctl_mode2 |= ledctl_off << (i << 3);
			break;
		default:
			/* Do nothing */
			break;
		}
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 299 | 99.67% | 1 | 50.00% | 
| bruce allan | bruce allan | 1 | 0.33% | 1 | 50.00% | 
 | Total | 300 | 100.00% | 2 | 100.00% | 
/**
 *  e1000e_setup_led_generic - Configures SW controllable LED
 *  @hw: pointer to the HW structure
 *
 *  This prepares the SW controllable LED for use and saves the current state
 *  of the LED so it can be later restored.
 **/
s32 e1000e_setup_led_generic(struct e1000_hw *hw)
{
	u32 ledctl;
	if (hw->mac.ops.setup_led != e1000e_setup_led_generic)
		return -E1000_ERR_CONFIG;
	if (hw->phy.media_type == e1000_media_type_fiber) {
		ledctl = er32(LEDCTL);
		hw->mac.ledctl_default = ledctl;
		/* Turn off LED0 */
		ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK |
			    E1000_LEDCTL_LED0_MODE_MASK);
		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
			   E1000_LEDCTL_LED0_MODE_SHIFT);
		ew32(LEDCTL, ledctl);
	} else if (hw->phy.media_type == e1000_media_type_copper) {
		ew32(LEDCTL, hw->mac.ledctl_mode1);
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| bruce allan | bruce allan | 110 | 100.00% | 1 | 100.00% | 
 | Total | 110 | 100.00% | 1 | 100.00% | 
/**
 *  e1000e_cleanup_led_generic - Set LED config to default operation
 *  @hw: pointer to the HW structure
 *
 *  Remove the current LED configuration and set the LED configuration
 *  to the default value, saved from the EEPROM.
 **/
s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
{
	ew32(LEDCTL, hw->mac.ledctl_default);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 24 | 100.00% | 1 | 100.00% | 
 | Total | 24 | 100.00% | 1 | 100.00% | 
/**
 *  e1000e_blink_led_generic - Blink LED
 *  @hw: pointer to the HW structure
 *
 *  Blink the LEDs which are set to be on.
 **/
s32 e1000e_blink_led_generic(struct e1000_hw *hw)
{
	u32 ledctl_blink = 0;
	u32 i;
	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)
                 * (or "off" if inverted) in ledctl_mode2.  The blink
                 * logic in hardware only works when mode is set to "on"
                 * so it must be changed accordingly when the mode is
                 * "off" and inverted.
                 */
		ledctl_blink = hw->mac.ledctl_mode2;
		for (i = 0; i < 32; i += 8) {
			u32 mode = (hw->mac.ledctl_mode2 >> i) &
			    E1000_LEDCTL_LED0_MODE_MASK;
			u32 led_default = hw->mac.ledctl_default >> i;
			if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
			     (mode == E1000_LEDCTL_MODE_LED_ON)) ||
			    ((led_default & E1000_LEDCTL_LED0_IVRT) &&
			     (mode == E1000_LEDCTL_MODE_LED_OFF))) {
				ledctl_blink &=
				    ~(E1000_LEDCTL_LED0_MODE_MASK << i);
				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
						 E1000_LEDCTL_MODE_LED_ON) << i;
			}
		}
	}
	ew32(LEDCTL, ledctl_blink);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 91 | 57.96% | 1 | 25.00% | 
| bruce allan | bruce allan | 64 | 40.76% | 2 | 50.00% | 
| jeff kirsher | jeff kirsher | 2 | 1.27% | 1 | 25.00% | 
 | Total | 157 | 100.00% | 4 | 100.00% | 
/**
 *  e1000e_led_on_generic - Turn LED on
 *  @hw: pointer to the HW structure
 *
 *  Turn LED on.
 **/
s32 e1000e_led_on_generic(struct e1000_hw *hw)
{
	u32 ctrl;
	switch (hw->phy.media_type) {
	case e1000_media_type_fiber:
		ctrl = er32(CTRL);
		ctrl &= ~E1000_CTRL_SWDPIN0;
		ctrl |= E1000_CTRL_SWDPIO0;
		ew32(CTRL, ctrl);
		break;
	case e1000_media_type_copper:
		ew32(LEDCTL, hw->mac.ledctl_mode2);
		break;
	default:
		break;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 68 | 97.14% | 1 | 50.00% | 
| jeff kirsher | jeff kirsher | 2 | 2.86% | 1 | 50.00% | 
 | Total | 70 | 100.00% | 2 | 100.00% | 
/**
 *  e1000e_led_off_generic - Turn LED off
 *  @hw: pointer to the HW structure
 *
 *  Turn LED off.
 **/
s32 e1000e_led_off_generic(struct e1000_hw *hw)
{
	u32 ctrl;
	switch (hw->phy.media_type) {
	case e1000_media_type_fiber:
		ctrl = er32(CTRL);
		ctrl |= E1000_CTRL_SWDPIN0;
		ctrl |= E1000_CTRL_SWDPIO0;
		ew32(CTRL, ctrl);
		break;
	case e1000_media_type_copper:
		ew32(LEDCTL, hw->mac.ledctl_mode1);
		break;
	default:
		break;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 67 | 97.10% | 1 | 50.00% | 
| jeff kirsher | jeff kirsher | 2 | 2.90% | 1 | 50.00% | 
 | Total | 69 | 100.00% | 2 | 100.00% | 
/**
 *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities
 *  @hw: pointer to the HW structure
 *  @no_snoop: bitmap of snoop events
 *
 *  Set the PCI-express register to snoop for events enabled in 'no_snoop'.
 **/
void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
{
	u32 gcr;
	if (no_snoop) {
		gcr = er32(GCR);
		gcr &= ~(PCIE_NO_SNOOP_ALL);
		gcr |= no_snoop;
		ew32(GCR, gcr);
	}
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 47 | 100.00% | 1 | 100.00% | 
 | Total | 47 | 100.00% | 1 | 100.00% | 
/**
 *  e1000e_disable_pcie_master - Disables PCI-express master access
 *  @hw: pointer to the HW structure
 *
 *  Returns 0 if successful, else returns -10
 *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
 *  the master requests to be disabled.
 *
 *  Disables PCI-Express master access and verifies there are no pending
 *  requests.
 **/
s32 e1000e_disable_pcie_master(struct e1000_hw *hw)
{
	u32 ctrl;
	s32 timeout = MASTER_DISABLE_TIMEOUT;
	ctrl = er32(CTRL);
	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
	ew32(CTRL, ctrl);
	while (timeout) {
		if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
			break;
		usleep_range(100, 200);
		timeout--;
	}
	if (!timeout) {
		e_dbg("Master requests are pending.\n");
		return -E1000_ERR_MASTER_REQUESTS_PENDING;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 80 | 95.24% | 1 | 33.33% | 
| bruce allan | bruce allan | 4 | 4.76% | 2 | 66.67% | 
 | Total | 84 | 100.00% | 3 | 100.00% | 
/**
 *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
 *  @hw: pointer to the HW structure
 *
 *  Reset the Adaptive Interframe Spacing throttle to default values.
 **/
void e1000e_reset_adaptive(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	if (!mac->adaptive_ifs) {
		e_dbg("Not in Adaptive IFS mode!\n");
		return;
	}
	mac->current_ifs_val = 0;
	mac->ifs_min_val = IFS_MIN;
	mac->ifs_max_val = IFS_MAX;
	mac->ifs_step_size = IFS_STEP;
	mac->ifs_ratio = IFS_RATIO;
	mac->in_ifs_mode = false;
	ew32(AIT, 0);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 62 | 79.49% | 1 | 25.00% | 
| bruce allan | bruce allan | 16 | 20.51% | 3 | 75.00% | 
 | Total | 78 | 100.00% | 4 | 100.00% | 
/**
 *  e1000e_update_adaptive - Update Adaptive Interframe Spacing
 *  @hw: pointer to the HW structure
 *
 *  Update the Adaptive Interframe Spacing Throttle value based on the
 *  time between transmitted packets and time between collisions.
 **/
void e1000e_update_adaptive(struct e1000_hw *hw)
{
	struct e1000_mac_info *mac = &hw->mac;
	if (!mac->adaptive_ifs) {
		e_dbg("Not in Adaptive IFS mode!\n");
		return;
	}
	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
			mac->in_ifs_mode = true;
			if (mac->current_ifs_val < mac->ifs_max_val) {
				if (!mac->current_ifs_val)
					mac->current_ifs_val = mac->ifs_min_val;
				else
					mac->current_ifs_val +=
					    mac->ifs_step_size;
				ew32(AIT, mac->current_ifs_val);
			}
		}
	} else {
		if (mac->in_ifs_mode &&
		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
			mac->current_ifs_val = 0;
			mac->in_ifs_mode = false;
			ew32(AIT, 0);
		}
	}
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 135 | 88.82% | 1 | 25.00% | 
| bruce allan | bruce allan | 17 | 11.18% | 3 | 75.00% | 
 | Total | 152 | 100.00% | 4 | 100.00% | 
Overall Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| auke kok | auke kok | 3719 | 72.34% | 3 | 5.08% | 
| bruce allan | bruce allan | 1242 | 24.16% | 45 | 76.27% | 
| jeff kirsher | jeff kirsher | 67 | 1.30% | 2 | 3.39% | 
| jesse brandeburg | jesse brandeburg | 55 | 1.07% | 2 | 3.39% | 
| joe perches | joe perches | 26 | 0.51% | 1 | 1.69% | 
| david ertman | david ertman | 21 | 0.41% | 1 | 1.69% | 
| jacob e keller | jacob e keller | 3 | 0.06% | 1 | 1.69% | 
| tobias klauser | tobias klauser | 3 | 0.06% | 1 | 1.69% | 
| alex chiang | alex chiang | 2 | 0.04% | 1 | 1.69% | 
| jon mason | jon mason | 2 | 0.04% | 1 | 1.69% | 
| yanir lubetkin | yanir lubetkin | 1 | 0.02% | 1 | 1.69% | 
 | Total | 5141 | 100.00% | 59 | 100.00% | 
  
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.