Home | History | Annotate | Line # | Download | only in igc
igc_mac.c revision 1.1
      1  1.1  rin /*	$OpenBSD: igc_mac.c,v 1.1 2021/10/31 14:52:57 patrick Exp $	*/
      2  1.1  rin /*-
      3  1.1  rin  * Copyright 2021 Intel Corp
      4  1.1  rin  * Copyright 2021 Rubicon Communications, LLC (Netgate)
      5  1.1  rin  * SPDX-License-Identifier: BSD-3-Clause
      6  1.1  rin  */
      7  1.1  rin 
      8  1.1  rin #include <dev/pci/igc_api.h>
      9  1.1  rin 
     10  1.1  rin /**
     11  1.1  rin  *  igc_init_mac_ops_generic - Initialize MAC function pointers
     12  1.1  rin  *  @hw: pointer to the HW structure
     13  1.1  rin  *
     14  1.1  rin  *  Setups up the function pointers to no-op functions
     15  1.1  rin  **/
     16  1.1  rin void
     17  1.1  rin igc_init_mac_ops_generic(struct igc_hw *hw)
     18  1.1  rin {
     19  1.1  rin 	struct igc_mac_info *mac = &hw->mac;
     20  1.1  rin 	DEBUGFUNC("igc_init_mac_ops_generic");
     21  1.1  rin 
     22  1.1  rin 	/* General Setup */
     23  1.1  rin 	mac->ops.init_params = igc_null_ops_generic;
     24  1.1  rin 	mac->ops.config_collision_dist = igc_config_collision_dist_generic;
     25  1.1  rin 	mac->ops.rar_set = igc_rar_set_generic;
     26  1.1  rin }
     27  1.1  rin 
     28  1.1  rin /**
     29  1.1  rin  *  igc_null_ops_generic - No-op function, returns 0
     30  1.1  rin  *  @hw: pointer to the HW structure
     31  1.1  rin  **/
     32  1.1  rin int
     33  1.1  rin igc_null_ops_generic(struct igc_hw IGC_UNUSEDARG *hw)
     34  1.1  rin {
     35  1.1  rin 	DEBUGFUNC("igc_null_ops_generic");
     36  1.1  rin 	return IGC_SUCCESS;
     37  1.1  rin }
     38  1.1  rin 
     39  1.1  rin /**
     40  1.1  rin  *  igc_write_vfta_generic - Write value to VLAN filter table
     41  1.1  rin  *  @hw: pointer to the HW structure
     42  1.1  rin  *  @offset: register offset in VLAN filter table
     43  1.1  rin  *  @value: register value written to VLAN filter table
     44  1.1  rin  *
     45  1.1  rin  *  Writes value at the given offset in the register array which stores
     46  1.1  rin  *  the VLAN filter table.
     47  1.1  rin  **/
     48  1.1  rin void
     49  1.1  rin igc_write_vfta_generic(struct igc_hw *hw, uint32_t offset, uint32_t value)
     50  1.1  rin {
     51  1.1  rin 	DEBUGFUNC("igc_write_vfta_generic");
     52  1.1  rin 
     53  1.1  rin 	IGC_WRITE_REG_ARRAY(hw, IGC_VFTA, offset, value);
     54  1.1  rin 	IGC_WRITE_FLUSH(hw);
     55  1.1  rin }
     56  1.1  rin 
     57  1.1  rin /**
     58  1.1  rin  *  igc_init_rx_addrs_generic - Initialize receive address's
     59  1.1  rin  *  @hw: pointer to the HW structure
     60  1.1  rin  *  @rar_count: receive address registers
     61  1.1  rin  *
     62  1.1  rin  *  Setup the receive address registers by setting the base receive address
     63  1.1  rin  *  register to the devices MAC address and clearing all the other receive
     64  1.1  rin  *  address registers to 0.
     65  1.1  rin  **/
     66  1.1  rin void
     67  1.1  rin igc_init_rx_addrs_generic(struct igc_hw *hw, uint16_t rar_count)
     68  1.1  rin {
     69  1.1  rin 	uint32_t i;
     70  1.1  rin 	uint8_t mac_addr[ETHER_ADDR_LEN] = {0};
     71  1.1  rin 
     72  1.1  rin 	DEBUGFUNC("igc_init_rx_addrs_generic");
     73  1.1  rin 
     74  1.1  rin 	/* Setup the receive address */
     75  1.1  rin 	DEBUGOUT("Programming MAC Address into RAR[0]\n");
     76  1.1  rin 
     77  1.1  rin 	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
     78  1.1  rin 
     79  1.1  rin 	/* Zero out the other (rar_entry_count - 1) receive addresses */
     80  1.1  rin 	DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1);
     81  1.1  rin 	for (i = 1; i < rar_count; i++)
     82  1.1  rin 		hw->mac.ops.rar_set(hw, mac_addr, i);
     83  1.1  rin }
     84  1.1  rin 
     85  1.1  rin /**
     86  1.1  rin  *  igc_check_alt_mac_addr_generic - Check for alternate MAC addr
     87  1.1  rin  *  @hw: pointer to the HW structure
     88  1.1  rin  *
     89  1.1  rin  *  Checks the nvm for an alternate MAC address.  An alternate MAC address
     90  1.1  rin  *  can be setup by pre-boot software and must be treated like a permanent
     91  1.1  rin  *  address and must override the actual permanent MAC address. If an
     92  1.1  rin  *  alternate MAC address is found it is programmed into RAR0, replacing
     93  1.1  rin  *  the permanent address that was installed into RAR0 by the Si on reset.
     94  1.1  rin  *  This function will return SUCCESS unless it encounters an error while
     95  1.1  rin  *  reading the EEPROM.
     96  1.1  rin  **/
     97  1.1  rin int
     98  1.1  rin igc_check_alt_mac_addr_generic(struct igc_hw *hw)
     99  1.1  rin {
    100  1.1  rin 	uint32_t i;
    101  1.1  rin 	int ret_val;
    102  1.1  rin 	uint16_t offset, nvm_alt_mac_addr_offset, nvm_data;
    103  1.1  rin 	uint8_t alt_mac_addr[ETHER_ADDR_LEN];
    104  1.1  rin 
    105  1.1  rin 	DEBUGFUNC("igc_check_alt_mac_addr_generic");
    106  1.1  rin 
    107  1.1  rin 	ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &nvm_data);
    108  1.1  rin 	if (ret_val)
    109  1.1  rin 		return ret_val;
    110  1.1  rin 
    111  1.1  rin 	ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1,
    112  1.1  rin 	    &nvm_alt_mac_addr_offset);
    113  1.1  rin 	if (ret_val) {
    114  1.1  rin 		DEBUGOUT("NVM Read Error\n");
    115  1.1  rin 		return ret_val;
    116  1.1  rin 	}
    117  1.1  rin 
    118  1.1  rin 	if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
    119  1.1  rin 	    (nvm_alt_mac_addr_offset == 0x0000))
    120  1.1  rin 		/* There is no Alternate MAC Address */
    121  1.1  rin 		return IGC_SUCCESS;
    122  1.1  rin 
    123  1.1  rin 	if (hw->bus.func == IGC_FUNC_1)
    124  1.1  rin 		nvm_alt_mac_addr_offset += IGC_ALT_MAC_ADDRESS_OFFSET_LAN1;
    125  1.1  rin 	for (i = 0; i < ETHER_ADDR_LEN; i += 2) {
    126  1.1  rin 		offset = nvm_alt_mac_addr_offset + (i >> 1);
    127  1.1  rin 		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
    128  1.1  rin 		if (ret_val) {
    129  1.1  rin 			DEBUGOUT("NVM Read Error\n");
    130  1.1  rin 			return ret_val;
    131  1.1  rin 		}
    132  1.1  rin 
    133  1.1  rin 		alt_mac_addr[i] = (uint8_t)(nvm_data & 0xFF);
    134  1.1  rin 		alt_mac_addr[i + 1] = (uint8_t)(nvm_data >> 8);
    135  1.1  rin 	}
    136  1.1  rin 
    137  1.1  rin 	/* if multicast bit is set, the alternate address will not be used */
    138  1.1  rin 	if (alt_mac_addr[0] & 0x01) {
    139  1.1  rin 		DEBUGOUT("Ignoring Alternate Mac Address with MC bit set\n");
    140  1.1  rin 		return IGC_SUCCESS;
    141  1.1  rin 	}
    142  1.1  rin 
    143  1.1  rin 	/* We have a valid alternate MAC address, and we want to treat it the
    144  1.1  rin 	 * same as the normal permanent MAC address stored by the HW into the
    145  1.1  rin 	 * RAR. Do this by mapping this address into RAR0.
    146  1.1  rin 	 */
    147  1.1  rin 	hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
    148  1.1  rin 
    149  1.1  rin 	return IGC_SUCCESS;
    150  1.1  rin }
    151  1.1  rin 
    152  1.1  rin /**
    153  1.1  rin  *  igc_rar_set_generic - Set receive address register
    154  1.1  rin  *  @hw: pointer to the HW structure
    155  1.1  rin  *  @addr: pointer to the receive address
    156  1.1  rin  *  @index: receive address array register
    157  1.1  rin  *
    158  1.1  rin  *  Sets the receive address array register at index to the address passed
    159  1.1  rin  *  in by addr.
    160  1.1  rin  **/
    161  1.1  rin int
    162  1.1  rin igc_rar_set_generic(struct igc_hw *hw, uint8_t *addr, uint32_t index)
    163  1.1  rin {
    164  1.1  rin 	uint32_t rar_low, rar_high;
    165  1.1  rin 
    166  1.1  rin 	DEBUGFUNC("igc_rar_set_generic");
    167  1.1  rin 
    168  1.1  rin 	/* HW expects these in little endian so we reverse the byte order
    169  1.1  rin 	 * from network order (big endian) to little endian
    170  1.1  rin 	 */
    171  1.1  rin 	rar_low = ((uint32_t) addr[0] | ((uint32_t) addr[1] << 8) |
    172  1.1  rin 	    ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
    173  1.1  rin 
    174  1.1  rin 	rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8));
    175  1.1  rin 
    176  1.1  rin 	/* If MAC address zero, no need to set the AV bit */
    177  1.1  rin 	if (rar_low || rar_high)
    178  1.1  rin 		rar_high |= IGC_RAH_AV;
    179  1.1  rin 
    180  1.1  rin 	/* Some bridges will combine consecutive 32-bit writes into
    181  1.1  rin 	 * a single burst write, which will malfunction on some parts.
    182  1.1  rin 	 * The flushes avoid this.
    183  1.1  rin 	 */
    184  1.1  rin 	IGC_WRITE_REG(hw, IGC_RAL(index), rar_low);
    185  1.1  rin 	IGC_WRITE_FLUSH(hw);
    186  1.1  rin 	IGC_WRITE_REG(hw, IGC_RAH(index), rar_high);
    187  1.1  rin 	IGC_WRITE_FLUSH(hw);
    188  1.1  rin 
    189  1.1  rin 	return IGC_SUCCESS;
    190  1.1  rin }
    191  1.1  rin 
    192  1.1  rin /**
    193  1.1  rin  *  igc_hash_mc_addr_generic - Generate a multicast hash value
    194  1.1  rin  *  @hw: pointer to the HW structure
    195  1.1  rin  *  @mc_addr: pointer to a multicast address
    196  1.1  rin  *
    197  1.1  rin  *  Generates a multicast address hash value which is used to determine
    198  1.1  rin  *  the multicast filter table array address and new table value.
    199  1.1  rin  **/
    200  1.1  rin int
    201  1.1  rin igc_hash_mc_addr_generic(struct igc_hw *hw, uint8_t *mc_addr)
    202  1.1  rin {
    203  1.1  rin 	uint32_t hash_value, hash_mask;
    204  1.1  rin 	uint8_t bit_shift = 0;
    205  1.1  rin 
    206  1.1  rin 	DEBUGFUNC("igc_hash_mc_addr_generic");
    207  1.1  rin 
    208  1.1  rin 	/* Register count multiplied by bits per register */
    209  1.1  rin 	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
    210  1.1  rin 
    211  1.1  rin 	/* For a mc_filter_type of 0, bit_shift is the number of left-shifts
    212  1.1  rin 	 * where 0xFF would still fall within the hash mask.
    213  1.1  rin 	 */
    214  1.1  rin 	while (hash_mask >> bit_shift != 0xFF)
    215  1.1  rin 		bit_shift++;
    216  1.1  rin 
    217  1.1  rin 	/* The portion of the address that is used for the hash table
    218  1.1  rin 	 * is determined by the mc_filter_type setting.
    219  1.1  rin 	 * The algorithm is such that there is a total of 8 bits of shifting.
    220  1.1  rin 	 * The bit_shift for a mc_filter_type of 0 represents the number of
    221  1.1  rin 	 * left-shifts where the MSB of mc_addr[5] would still fall within
    222  1.1  rin 	 * the hash_mask.  Case 0 does this exactly.  Since there are a total
    223  1.1  rin 	 * of 8 bits of shifting, then mc_addr[4] will shift right the
    224  1.1  rin 	 * remaining number of bits. Thus 8 - bit_shift.  The rest of the
    225  1.1  rin 	 * cases are a variation of this algorithm...essentially raising the
    226  1.1  rin 	 * number of bits to shift mc_addr[5] left, while still keeping the
    227  1.1  rin 	 * 8-bit shifting total.
    228  1.1  rin 	 *
    229  1.1  rin 	 * For example, given the following Destination MAC Address and an
    230  1.1  rin 	 * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
    231  1.1  rin 	 * we can see that the bit_shift for case 0 is 4.  These are the hash
    232  1.1  rin 	 * values resulting from each mc_filter_type...
    233  1.1  rin 	 * [0] [1] [2] [3] [4] [5]
    234  1.1  rin 	 * 01  AA  00  12  34  56
    235  1.1  rin 	 * LSB		 MSB
    236  1.1  rin 	 *
    237  1.1  rin 	 * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
    238  1.1  rin 	 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
    239  1.1  rin 	 * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
    240  1.1  rin 	 * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
    241  1.1  rin 	 */
    242  1.1  rin 	switch (hw->mac.mc_filter_type) {
    243  1.1  rin 	default:
    244  1.1  rin 	case 0:
    245  1.1  rin 		break;
    246  1.1  rin 	case 1:
    247  1.1  rin 		bit_shift += 1;
    248  1.1  rin 		break;
    249  1.1  rin 	case 2:
    250  1.1  rin 		bit_shift += 2;
    251  1.1  rin 		break;
    252  1.1  rin 	case 3:
    253  1.1  rin 		bit_shift += 4;
    254  1.1  rin 		break;
    255  1.1  rin 	}
    256  1.1  rin 
    257  1.1  rin 	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
    258  1.1  rin 	    (((uint16_t) mc_addr[5]) << bit_shift)));
    259  1.1  rin 
    260  1.1  rin 	return hash_value;
    261  1.1  rin }
    262  1.1  rin 
    263  1.1  rin /**
    264  1.1  rin  *  igc_update_mc_addr_list_generic - Update Multicast addresses
    265  1.1  rin  *  @hw: pointer to the HW structure
    266  1.1  rin  *  @mc_addr_list: array of multicast addresses to program
    267  1.1  rin  *  @mc_addr_count: number of multicast addresses to program
    268  1.1  rin  *
    269  1.1  rin  *  Updates entire Multicast Table Array.
    270  1.1  rin  *  The caller must have a packed mc_addr_list of multicast addresses.
    271  1.1  rin  **/
    272  1.1  rin void
    273  1.1  rin igc_update_mc_addr_list_generic(struct igc_hw *hw, uint8_t *mc_addr_list,
    274  1.1  rin     uint32_t mc_addr_count)
    275  1.1  rin {
    276  1.1  rin 	uint32_t hash_value, hash_bit, hash_reg;
    277  1.1  rin 	int i;
    278  1.1  rin 
    279  1.1  rin 	DEBUGFUNC("igc_update_mc_addr_list_generic");
    280  1.1  rin 
    281  1.1  rin 	/* clear mta_shadow */
    282  1.1  rin 	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
    283  1.1  rin 
    284  1.1  rin 	/* update mta_shadow from mc_addr_list */
    285  1.1  rin 	for (i = 0; (uint32_t)i < mc_addr_count; i++) {
    286  1.1  rin 		hash_value = igc_hash_mc_addr_generic(hw, mc_addr_list);
    287  1.1  rin 
    288  1.1  rin 		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
    289  1.1  rin 		hash_bit = hash_value & 0x1F;
    290  1.1  rin 
    291  1.1  rin 		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
    292  1.1  rin 		mc_addr_list += (ETHER_ADDR_LEN);
    293  1.1  rin 	}
    294  1.1  rin 
    295  1.1  rin 	/* replace the entire MTA table */
    296  1.1  rin 	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
    297  1.1  rin 		IGC_WRITE_REG_ARRAY(hw, IGC_MTA, i, hw->mac.mta_shadow[i]);
    298  1.1  rin 	IGC_WRITE_FLUSH(hw);
    299  1.1  rin }
    300  1.1  rin 
    301  1.1  rin /**
    302  1.1  rin  *  igc_clear_hw_cntrs_base_generic - Clear base hardware counters
    303  1.1  rin  *  @hw: pointer to the HW structure
    304  1.1  rin  *
    305  1.1  rin  *  Clears the base hardware counters by reading the counter registers.
    306  1.1  rin  **/
    307  1.1  rin void
    308  1.1  rin igc_clear_hw_cntrs_base_generic(struct igc_hw *hw)
    309  1.1  rin {
    310  1.1  rin 	DEBUGFUNC("igc_clear_hw_cntrs_base_generic");
    311  1.1  rin 
    312  1.1  rin 	IGC_READ_REG(hw, IGC_CRCERRS);
    313  1.1  rin 	IGC_READ_REG(hw, IGC_MPC);
    314  1.1  rin 	IGC_READ_REG(hw, IGC_SCC);
    315  1.1  rin 	IGC_READ_REG(hw, IGC_ECOL);
    316  1.1  rin 	IGC_READ_REG(hw, IGC_MCC);
    317  1.1  rin 	IGC_READ_REG(hw, IGC_LATECOL);
    318  1.1  rin 	IGC_READ_REG(hw, IGC_COLC);
    319  1.1  rin 	IGC_READ_REG(hw, IGC_RERC);
    320  1.1  rin 	IGC_READ_REG(hw, IGC_DC);
    321  1.1  rin 	IGC_READ_REG(hw, IGC_RLEC);
    322  1.1  rin 	IGC_READ_REG(hw, IGC_XONRXC);
    323  1.1  rin 	IGC_READ_REG(hw, IGC_XONTXC);
    324  1.1  rin 	IGC_READ_REG(hw, IGC_XOFFRXC);
    325  1.1  rin 	IGC_READ_REG(hw, IGC_XOFFTXC);
    326  1.1  rin 	IGC_READ_REG(hw, IGC_FCRUC);
    327  1.1  rin 	IGC_READ_REG(hw, IGC_GPRC);
    328  1.1  rin 	IGC_READ_REG(hw, IGC_BPRC);
    329  1.1  rin 	IGC_READ_REG(hw, IGC_MPRC);
    330  1.1  rin 	IGC_READ_REG(hw, IGC_GPTC);
    331  1.1  rin 	IGC_READ_REG(hw, IGC_GORCL);
    332  1.1  rin 	IGC_READ_REG(hw, IGC_GORCH);
    333  1.1  rin 	IGC_READ_REG(hw, IGC_GOTCL);
    334  1.1  rin 	IGC_READ_REG(hw, IGC_GOTCH);
    335  1.1  rin 	IGC_READ_REG(hw, IGC_RNBC);
    336  1.1  rin 	IGC_READ_REG(hw, IGC_RUC);
    337  1.1  rin 	IGC_READ_REG(hw, IGC_RFC);
    338  1.1  rin 	IGC_READ_REG(hw, IGC_ROC);
    339  1.1  rin 	IGC_READ_REG(hw, IGC_RJC);
    340  1.1  rin 	IGC_READ_REG(hw, IGC_TORL);
    341  1.1  rin 	IGC_READ_REG(hw, IGC_TORH);
    342  1.1  rin 	IGC_READ_REG(hw, IGC_TOTL);
    343  1.1  rin 	IGC_READ_REG(hw, IGC_TOTH);
    344  1.1  rin 	IGC_READ_REG(hw, IGC_TPR);
    345  1.1  rin 	IGC_READ_REG(hw, IGC_TPT);
    346  1.1  rin 	IGC_READ_REG(hw, IGC_MPTC);
    347  1.1  rin 	IGC_READ_REG(hw, IGC_BPTC);
    348  1.1  rin 	IGC_READ_REG(hw, IGC_TLPIC);
    349  1.1  rin 	IGC_READ_REG(hw, IGC_RLPIC);
    350  1.1  rin 	IGC_READ_REG(hw, IGC_RXDMTC);
    351  1.1  rin }
    352  1.1  rin 
    353  1.1  rin /**
    354  1.1  rin  *  igc_setup_link_generic - Setup flow control and link settings
    355  1.1  rin  *  @hw: pointer to the HW structure
    356  1.1  rin  *
    357  1.1  rin  *  Determines which flow control settings to use, then configures flow
    358  1.1  rin  *  control.  Calls the appropriate media-specific link configuration
    359  1.1  rin  *  function.  Assuming the adapter has a valid link partner, a valid link
    360  1.1  rin  *  should be established.  Assumes the hardware has previously been reset
    361  1.1  rin  *  and the transmitter and receiver are not enabled.
    362  1.1  rin  **/
    363  1.1  rin int
    364  1.1  rin igc_setup_link_generic(struct igc_hw *hw)
    365  1.1  rin {
    366  1.1  rin 	int ret_val;
    367  1.1  rin 
    368  1.1  rin 	DEBUGFUNC("igc_setup_link_generic");
    369  1.1  rin 
    370  1.1  rin 	/* In the case of the phy reset being blocked, we already have a link.
    371  1.1  rin 	 * We do not need to set it up again.
    372  1.1  rin 	 */
    373  1.1  rin 	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
    374  1.1  rin 		return IGC_SUCCESS;
    375  1.1  rin 
    376  1.1  rin 	/* If requested flow control is set to default, set flow control
    377  1.1  rin 	 * for both 'rx' and 'tx' pause frames.
    378  1.1  rin 	 */
    379  1.1  rin 	if (hw->fc.requested_mode == igc_fc_default) {
    380  1.1  rin 		hw->fc.requested_mode = igc_fc_full;
    381  1.1  rin 	}
    382  1.1  rin 
    383  1.1  rin 	/* Save off the requested flow control mode for use later.  Depending
    384  1.1  rin 	 * on the link partner's capabilities, we may or may not use this mode.
    385  1.1  rin 	 */
    386  1.1  rin 	hw->fc.current_mode = hw->fc.requested_mode;
    387  1.1  rin 
    388  1.1  rin 	DEBUGOUT1("After fix-ups FlowControl is now = %x\n",
    389  1.1  rin 	    hw->fc.current_mode);
    390  1.1  rin 
    391  1.1  rin 	/* Call the necessary media_type subroutine to configure the link. */
    392  1.1  rin 	ret_val = hw->mac.ops.setup_physical_interface(hw);
    393  1.1  rin 	if (ret_val)
    394  1.1  rin 		return ret_val;
    395  1.1  rin 
    396  1.1  rin 	/* Initialize the flow control address, type, and PAUSE timer
    397  1.1  rin 	 * registers to their default values.  This is done even if flow
    398  1.1  rin 	 * control is disabled, because it does not hurt anything to
    399  1.1  rin 	 * initialize these registers.
    400  1.1  rin 	 */
    401  1.1  rin 	IGC_WRITE_REG(hw, IGC_FCT, FLOW_CONTROL_TYPE);
    402  1.1  rin 	IGC_WRITE_REG(hw, IGC_FCAH, FLOW_CONTROL_ADDRESS_HIGH);
    403  1.1  rin 	IGC_WRITE_REG(hw, IGC_FCAL, FLOW_CONTROL_ADDRESS_LOW);
    404  1.1  rin 
    405  1.1  rin 	IGC_WRITE_REG(hw, IGC_FCTTV, hw->fc.pause_time);
    406  1.1  rin 
    407  1.1  rin 	return igc_set_fc_watermarks_generic(hw);
    408  1.1  rin }
    409  1.1  rin 
    410  1.1  rin /**
    411  1.1  rin  *  igc_config_collision_dist_generic - Configure collision distance
    412  1.1  rin  *  @hw: pointer to the HW structure
    413  1.1  rin  *
    414  1.1  rin  *  Configures the collision distance to the default value and is used
    415  1.1  rin  *  during link setup.
    416  1.1  rin  **/
    417  1.1  rin void
    418  1.1  rin igc_config_collision_dist_generic(struct igc_hw *hw)
    419  1.1  rin {
    420  1.1  rin 	uint32_t tctl;
    421  1.1  rin 
    422  1.1  rin 	DEBUGFUNC("igc_config_collision_dist_generic");
    423  1.1  rin 
    424  1.1  rin 	tctl = IGC_READ_REG(hw, IGC_TCTL);
    425  1.1  rin 
    426  1.1  rin 	tctl &= ~IGC_TCTL_COLD;
    427  1.1  rin 	tctl |= IGC_COLLISION_DISTANCE << IGC_COLD_SHIFT;
    428  1.1  rin 
    429  1.1  rin 	IGC_WRITE_REG(hw, IGC_TCTL, tctl);
    430  1.1  rin 	IGC_WRITE_FLUSH(hw);
    431  1.1  rin }
    432  1.1  rin 
    433  1.1  rin /**
    434  1.1  rin  *  igc_set_fc_watermarks_generic - Set flow control high/low watermarks
    435  1.1  rin  *  @hw: pointer to the HW structure
    436  1.1  rin  *
    437  1.1  rin  *  Sets the flow control high/low threshold (watermark) registers.  If
    438  1.1  rin  *  flow control XON frame transmission is enabled, then set XON frame
    439  1.1  rin  *  transmission as well.
    440  1.1  rin  **/
    441  1.1  rin int
    442  1.1  rin igc_set_fc_watermarks_generic(struct igc_hw *hw)
    443  1.1  rin {
    444  1.1  rin 	uint32_t fcrtl = 0, fcrth = 0;
    445  1.1  rin 
    446  1.1  rin 	DEBUGFUNC("igc_set_fc_watermarks_generic");
    447  1.1  rin 
    448  1.1  rin 	/* Set the flow control receive threshold registers.  Normally,
    449  1.1  rin 	 * these registers will be set to a default threshold that may be
    450  1.1  rin 	 * adjusted later by the driver's runtime code.  However, if the
    451  1.1  rin 	 * ability to transmit pause frames is not enabled, then these
    452  1.1  rin 	 * registers will be set to 0.
    453  1.1  rin 	 */
    454  1.1  rin 	if (hw->fc.current_mode & igc_fc_tx_pause) {
    455  1.1  rin 		/* We need to set up the Receive Threshold high and low water
    456  1.1  rin 		 * marks as well as (optionally) enabling the transmission of
    457  1.1  rin 		 * XON frames.
    458  1.1  rin 		 */
    459  1.1  rin 		fcrtl = hw->fc.low_water;
    460  1.1  rin 		if (hw->fc.send_xon)
    461  1.1  rin 			fcrtl |= IGC_FCRTL_XONE;
    462  1.1  rin 
    463  1.1  rin 		fcrth = hw->fc.high_water;
    464  1.1  rin 	}
    465  1.1  rin 	IGC_WRITE_REG(hw, IGC_FCRTL, fcrtl);
    466  1.1  rin 	IGC_WRITE_REG(hw, IGC_FCRTH, fcrth);
    467  1.1  rin 
    468  1.1  rin 	return IGC_SUCCESS;
    469  1.1  rin }
    470  1.1  rin 
    471  1.1  rin /**
    472  1.1  rin  *  igc_force_mac_fc_generic - Force the MAC's flow control settings
    473  1.1  rin  *  @hw: pointer to the HW structure
    474  1.1  rin  *
    475  1.1  rin  *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
    476  1.1  rin  *  device control register to reflect the adapter settings.  TFCE and RFCE
    477  1.1  rin  *  need to be explicitly set by software when a copper PHY is used because
    478  1.1  rin  *  autonegotiation is managed by the PHY rather than the MAC.  Software must
    479  1.1  rin  *  also configure these bits when link is forced on a fiber connection.
    480  1.1  rin  **/
    481  1.1  rin int
    482  1.1  rin igc_force_mac_fc_generic(struct igc_hw *hw)
    483  1.1  rin {
    484  1.1  rin 	uint32_t ctrl;
    485  1.1  rin 
    486  1.1  rin 	DEBUGFUNC("igc_force_mac_fc_generic");
    487  1.1  rin 
    488  1.1  rin 	ctrl = IGC_READ_REG(hw, IGC_CTRL);
    489  1.1  rin 
    490  1.1  rin 	/* Because we didn't get link via the internal auto-negotiation
    491  1.1  rin 	 * mechanism (we either forced link or we got link via PHY
    492  1.1  rin 	 * auto-neg), we have to manually enable/disable transmit an
    493  1.1  rin 	 * receive flow control.
    494  1.1  rin 	 *
    495  1.1  rin 	 * The "Case" statement below enables/disable flow control
    496  1.1  rin 	 * according to the "hw->fc.current_mode" parameter.
    497  1.1  rin 	 *
    498  1.1  rin 	 * The possible values of the "fc" parameter are:
    499  1.1  rin 	 *      0:  Flow control is completely disabled
    500  1.1  rin 	 *      1:  Rx flow control is enabled (we can receive pause
    501  1.1  rin 	 *          frames but not send pause frames).
    502  1.1  rin 	 *      2:  Tx flow control is enabled (we can send pause frames
    503  1.1  rin 	 *          frames but we do not receive pause frames).
    504  1.1  rin 	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
    505  1.1  rin 	 *  other:  No other values should be possible at this point.
    506  1.1  rin 	 */
    507  1.1  rin 	DEBUGOUT1("hw->fc.current_mode = %u\n", hw->fc.current_mode);
    508  1.1  rin 
    509  1.1  rin 	switch (hw->fc.current_mode) {
    510  1.1  rin 	case igc_fc_none:
    511  1.1  rin 		ctrl &= (~(IGC_CTRL_TFCE | IGC_CTRL_RFCE));
    512  1.1  rin 		break;
    513  1.1  rin 	case igc_fc_rx_pause:
    514  1.1  rin 		ctrl &= (~IGC_CTRL_TFCE);
    515  1.1  rin 		ctrl |= IGC_CTRL_RFCE;
    516  1.1  rin 		break;
    517  1.1  rin 	case igc_fc_tx_pause:
    518  1.1  rin 		ctrl &= (~IGC_CTRL_RFCE);
    519  1.1  rin 		ctrl |= IGC_CTRL_TFCE;
    520  1.1  rin 		break;
    521  1.1  rin 	case igc_fc_full:
    522  1.1  rin 		ctrl |= (IGC_CTRL_TFCE | IGC_CTRL_RFCE);
    523  1.1  rin 		break;
    524  1.1  rin 	default:
    525  1.1  rin 		DEBUGOUT("Flow control param set incorrectly\n");
    526  1.1  rin 		return -IGC_ERR_CONFIG;
    527  1.1  rin 	}
    528  1.1  rin 
    529  1.1  rin 	IGC_WRITE_REG(hw, IGC_CTRL, ctrl);
    530  1.1  rin 
    531  1.1  rin 	return IGC_SUCCESS;
    532  1.1  rin }
    533  1.1  rin 
    534  1.1  rin /**
    535  1.1  rin  *  igc_config_fc_after_link_up_generic - Configures flow control after link
    536  1.1  rin  *  @hw: pointer to the HW structure
    537  1.1  rin  *
    538  1.1  rin  *  Checks the status of auto-negotiation after link up to ensure that the
    539  1.1  rin  *  speed and duplex were not forced.  If the link needed to be forced, then
    540  1.1  rin  *  flow control needs to be forced also.  If auto-negotiation is enabled
    541  1.1  rin  *  and did not fail, then we configure flow control based on our link
    542  1.1  rin  *  partner.
    543  1.1  rin  **/
    544  1.1  rin int
    545  1.1  rin igc_config_fc_after_link_up_generic(struct igc_hw *hw)
    546  1.1  rin {
    547  1.1  rin 	struct igc_mac_info *mac = &hw->mac;
    548  1.1  rin 	uint16_t mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
    549  1.1  rin 	uint16_t speed, duplex;
    550  1.1  rin 	int ret_val = IGC_SUCCESS;
    551  1.1  rin 
    552  1.1  rin 	DEBUGFUNC("igc_config_fc_after_link_up_generic");
    553  1.1  rin 
    554  1.1  rin 	if (ret_val) {
    555  1.1  rin 		DEBUGOUT("Error forcing flow control settings\n");
    556  1.1  rin 		return ret_val;
    557  1.1  rin 	}
    558  1.1  rin 
    559  1.1  rin 	/* Check for the case where we have copper media and auto-neg is
    560  1.1  rin 	 * enabled.  In this case, we need to check and see if Auto-Neg
    561  1.1  rin 	 * has completed, and if so, how the PHY and link partner has
    562  1.1  rin 	 * flow control configured.
    563  1.1  rin 	 */
    564  1.1  rin 	if (mac->autoneg) {
    565  1.1  rin 		/* Read the MII Status Register and check to see if AutoNeg
    566  1.1  rin 		 * has completed.  We read this twice because this reg has
    567  1.1  rin 		 * some "sticky" (latched) bits.
    568  1.1  rin 		 */
    569  1.1  rin 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
    570  1.1  rin 		if (ret_val)
    571  1.1  rin 			return ret_val;
    572  1.1  rin 		ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg);
    573  1.1  rin 		if (ret_val)
    574  1.1  rin 			return ret_val;
    575  1.1  rin 
    576  1.1  rin 		if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE))
    577  1.1  rin 			return ret_val;
    578  1.1  rin 
    579  1.1  rin 		/* The AutoNeg process has completed, so we now need to
    580  1.1  rin 		 * read both the Auto Negotiation Advertisement
    581  1.1  rin 		 * Register (Address 4) and the Auto_Negotiation Base
    582  1.1  rin 		 * Page Ability Register (Address 5) to determine how
    583  1.1  rin 		 * flow control was negotiated.
    584  1.1  rin 		 */
    585  1.1  rin 		ret_val = hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV,
    586  1.1  rin 		    &mii_nway_adv_reg);
    587  1.1  rin 		if (ret_val)
    588  1.1  rin 			return ret_val;
    589  1.1  rin 		ret_val = hw->phy.ops.read_reg(hw, PHY_LP_ABILITY,
    590  1.1  rin 		    &mii_nway_lp_ability_reg);
    591  1.1  rin 		if (ret_val)
    592  1.1  rin 			return ret_val;
    593  1.1  rin 
    594  1.1  rin 		/* Two bits in the Auto Negotiation Advertisement Register
    595  1.1  rin 		 * (Address 4) and two bits in the Auto Negotiation Base
    596  1.1  rin 		 * Page Ability Register (Address 5) determine flow control
    597  1.1  rin 		 * for both the PHY and the link partner.  The following
    598  1.1  rin 		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
    599  1.1  rin 		 * 1999, describes these PAUSE resolution bits and how flow
    600  1.1  rin 		 * control is determined based upon these settings.
    601  1.1  rin 		 * NOTE:  DC = Don't Care
    602  1.1  rin 		 *
    603  1.1  rin 		 *   LOCAL DEVICE  |   LINK PARTNER
    604  1.1  rin 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
    605  1.1  rin 		 *-------|---------|-------|---------|--------------------
    606  1.1  rin 		 *   0   |    0    |  DC   |   DC    | igc_fc_none
    607  1.1  rin 		 *   0   |    1    |   0   |   DC    | igc_fc_none
    608  1.1  rin 		 *   0   |    1    |   1   |    0    | igc_fc_none
    609  1.1  rin 		 *   0   |    1    |   1   |    1    | igc_fc_tx_pause
    610  1.1  rin 		 *   1   |    0    |   0   |   DC    | igc_fc_none
    611  1.1  rin 		 *   1   |   DC    |   1   |   DC    | igc_fc_full
    612  1.1  rin 		 *   1   |    1    |   0   |    0    | igc_fc_none
    613  1.1  rin 		 *   1   |    1    |   0   |    1    | igc_fc_rx_pause
    614  1.1  rin 		 *
    615  1.1  rin 		 * Are both PAUSE bits set to 1?  If so, this implies
    616  1.1  rin 		 * Symmetric Flow Control is enabled at both ends.  The
    617  1.1  rin 		 * ASM_DIR bits are irrelevant per the spec.
    618  1.1  rin 		 *
    619  1.1  rin 		 * For Symmetric Flow Control:
    620  1.1  rin 		 *
    621  1.1  rin 		 *   LOCAL DEVICE  |   LINK PARTNER
    622  1.1  rin 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
    623  1.1  rin 		 *-------|---------|-------|---------|--------------------
    624  1.1  rin 		 *   1   |   DC    |   1   |   DC    | IGC_fc_full
    625  1.1  rin 		 *
    626  1.1  rin 		 */
    627  1.1  rin 		if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
    628  1.1  rin 		    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
    629  1.1  rin 			/* Now we need to check if the user selected Rx ONLY
    630  1.1  rin 			 * of pause frames.  In this case, we had to advertise
    631  1.1  rin 			 * FULL flow control because we could not advertise Rx
    632  1.1  rin 			 * ONLY. Hence, we must now check to see if we need to
    633  1.1  rin 			 * turn OFF the TRANSMISSION of PAUSE frames.
    634  1.1  rin 			 */
    635  1.1  rin 			if (hw->fc.requested_mode == igc_fc_full)
    636  1.1  rin 				hw->fc.current_mode = igc_fc_full;
    637  1.1  rin 			else
    638  1.1  rin 				hw->fc.current_mode = igc_fc_rx_pause;
    639  1.1  rin 		}
    640  1.1  rin 		/* For receiving PAUSE frames ONLY.
    641  1.1  rin 		 *
    642  1.1  rin 		 *   LOCAL DEVICE  |   LINK PARTNER
    643  1.1  rin 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
    644  1.1  rin 		 *-------|---------|-------|---------|--------------------
    645  1.1  rin 		 *   0   |    1    |   1   |    1    | igc_fc_tx_pause
    646  1.1  rin 		 */
    647  1.1  rin 		else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
    648  1.1  rin 			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
    649  1.1  rin 			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
    650  1.1  rin 			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
    651  1.1  rin 				hw->fc.current_mode = igc_fc_tx_pause;
    652  1.1  rin 		}
    653  1.1  rin 		/* For transmitting PAUSE frames ONLY.
    654  1.1  rin 		 *
    655  1.1  rin 		 *   LOCAL DEVICE  |   LINK PARTNER
    656  1.1  rin 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
    657  1.1  rin 		 *-------|---------|-------|---------|--------------------
    658  1.1  rin 		 *   1   |    1    |   0   |    1    | igc_fc_rx_pause
    659  1.1  rin 		 */
    660  1.1  rin 		else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
    661  1.1  rin 			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
    662  1.1  rin 			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
    663  1.1  rin 			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
    664  1.1  rin 				hw->fc.current_mode = igc_fc_rx_pause;
    665  1.1  rin 		} else {
    666  1.1  rin 			/* Per the IEEE spec, at this point flow control
    667  1.1  rin 			 * should be disabled.
    668  1.1  rin 			 */
    669  1.1  rin 			hw->fc.current_mode = igc_fc_none;
    670  1.1  rin 			DEBUGOUT("Flow Control = NONE.\n");
    671  1.1  rin 		}
    672  1.1  rin 
    673  1.1  rin 		/* Now we need to do one last check...  If we auto-
    674  1.1  rin 		 * negotiated to HALF DUPLEX, flow control should not be
    675  1.1  rin 		 * enabled per IEEE 802.3 spec.
    676  1.1  rin 		 */
    677  1.1  rin 		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
    678  1.1  rin 		if (ret_val) {
    679  1.1  rin 			DEBUGOUT("Error getting link speed and duplex\n");
    680  1.1  rin 			return ret_val;
    681  1.1  rin 		}
    682  1.1  rin 
    683  1.1  rin 		if (duplex == HALF_DUPLEX)
    684  1.1  rin 			hw->fc.current_mode = igc_fc_none;
    685  1.1  rin 
    686  1.1  rin 		/* Now we call a subroutine to actually force the MAC
    687  1.1  rin 		 * controller to use the correct flow control settings.
    688  1.1  rin 		 */
    689  1.1  rin 		ret_val = igc_force_mac_fc_generic(hw);
    690  1.1  rin 		if (ret_val) {
    691  1.1  rin 			DEBUGOUT("Error forcing flow control settings\n");
    692  1.1  rin 			return ret_val;
    693  1.1  rin 		}
    694  1.1  rin 	}
    695  1.1  rin 
    696  1.1  rin 	return IGC_SUCCESS;
    697  1.1  rin }
    698  1.1  rin 
    699  1.1  rin /**
    700  1.1  rin  *  igc_get_speed_and_duplex_copper_generic - Retrieve current speed/duplex
    701  1.1  rin  *  @hw: pointer to the HW structure
    702  1.1  rin  *  @speed: stores the current speed
    703  1.1  rin  *  @duplex: stores the current duplex
    704  1.1  rin  *
    705  1.1  rin  *  Read the status register for the current speed/duplex and store the current
    706  1.1  rin  *  speed and duplex for copper connections.
    707  1.1  rin  **/
    708  1.1  rin int
    709  1.1  rin igc_get_speed_and_duplex_copper_generic(struct igc_hw *hw, uint16_t *speed,
    710  1.1  rin     uint16_t *duplex)
    711  1.1  rin {
    712  1.1  rin 	uint32_t status;
    713  1.1  rin 
    714  1.1  rin 	DEBUGFUNC("igc_get_speed_and_duplex_copper_generic");
    715  1.1  rin 
    716  1.1  rin 	status = IGC_READ_REG(hw, IGC_STATUS);
    717  1.1  rin 	if (status & IGC_STATUS_SPEED_1000) {
    718  1.1  rin 		/* For I225, STATUS will indicate 1G speed in both 1 Gbps
    719  1.1  rin 		 * and 2.5 Gbps link modes. An additional bit is used
    720  1.1  rin 		 * to differentiate between 1 Gbps and 2.5 Gbps.
    721  1.1  rin 		 */
    722  1.1  rin 		if ((hw->mac.type == igc_i225) &&
    723  1.1  rin 		    (status & IGC_STATUS_SPEED_2500)) {
    724  1.1  rin 			*speed = SPEED_2500;
    725  1.1  rin 			DEBUGOUT("2500 Mbs, ");
    726  1.1  rin 		} else {
    727  1.1  rin 			*speed = SPEED_1000;
    728  1.1  rin 			DEBUGOUT("1000 Mbs, ");
    729  1.1  rin 		}
    730  1.1  rin 	} else if (status & IGC_STATUS_SPEED_100) {
    731  1.1  rin 		*speed = SPEED_100;
    732  1.1  rin 		DEBUGOUT("100 Mbs, ");
    733  1.1  rin 	} else {
    734  1.1  rin 		*speed = SPEED_10;
    735  1.1  rin 		DEBUGOUT("10 Mbs, ");
    736  1.1  rin 	}
    737  1.1  rin 
    738  1.1  rin 	if (status & IGC_STATUS_FD) {
    739  1.1  rin 		*duplex = FULL_DUPLEX;
    740  1.1  rin 		DEBUGOUT("Full Duplex\n");
    741  1.1  rin 	} else {
    742  1.1  rin 		*duplex = HALF_DUPLEX;
    743  1.1  rin 		DEBUGOUT("Half Duplex\n");
    744  1.1  rin 	}
    745  1.1  rin 
    746  1.1  rin 	return IGC_SUCCESS;
    747  1.1  rin }
    748  1.1  rin 
    749  1.1  rin /**
    750  1.1  rin  *  igc_put_hw_semaphore_generic - Release hardware semaphore
    751  1.1  rin  *  @hw: pointer to the HW structure
    752  1.1  rin  *
    753  1.1  rin  *  Release hardware semaphore used to access the PHY or NVM
    754  1.1  rin  **/
    755  1.1  rin void
    756  1.1  rin igc_put_hw_semaphore_generic(struct igc_hw *hw)
    757  1.1  rin {
    758  1.1  rin 	uint32_t swsm;
    759  1.1  rin 
    760  1.1  rin         DEBUGFUNC("igc_put_hw_semaphore_generic");
    761  1.1  rin 
    762  1.1  rin 	swsm = IGC_READ_REG(hw, IGC_SWSM);
    763  1.1  rin 	swsm &= ~(IGC_SWSM_SMBI | IGC_SWSM_SWESMBI);
    764  1.1  rin 
    765  1.1  rin 	IGC_WRITE_REG(hw, IGC_SWSM, swsm);
    766  1.1  rin }
    767  1.1  rin 
    768  1.1  rin /**
    769  1.1  rin  *  igc_get_auto_rd_done_generic - Check for auto read completion
    770  1.1  rin  *  @hw: pointer to the HW structure
    771  1.1  rin  *
    772  1.1  rin  *  Check EEPROM for Auto Read done bit.
    773  1.1  rin  **/
    774  1.1  rin int
    775  1.1  rin igc_get_auto_rd_done_generic(struct igc_hw *hw)
    776  1.1  rin {
    777  1.1  rin 	int i = 0;
    778  1.1  rin 
    779  1.1  rin 	DEBUGFUNC("igc_get_auto_rd_done_generic");
    780  1.1  rin 
    781  1.1  rin 	while (i < AUTO_READ_DONE_TIMEOUT) {
    782  1.1  rin 		if (IGC_READ_REG(hw, IGC_EECD) & IGC_EECD_AUTO_RD)
    783  1.1  rin 			break;
    784  1.1  rin 		msec_delay(1);
    785  1.1  rin 		i++;
    786  1.1  rin 	}
    787  1.1  rin 
    788  1.1  rin 	if (i == AUTO_READ_DONE_TIMEOUT) {
    789  1.1  rin 		DEBUGOUT("Auto read by HW from NVM has not completed.\n");
    790  1.1  rin 		return -IGC_ERR_RESET;
    791  1.1  rin 	}
    792  1.1  rin 
    793  1.1  rin 	return IGC_SUCCESS;
    794  1.1  rin }
    795  1.1  rin 
    796  1.1  rin /**
    797  1.1  rin  *  igc_disable_pcie_master_generic - Disables PCI-express master access
    798  1.1  rin  *  @hw: pointer to the HW structure
    799  1.1  rin  *
    800  1.1  rin  *  Returns IGC_SUCCESS if successful, else returns -10
    801  1.1  rin  *  (-IGC_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
    802  1.1  rin  *  the master requests to be disabled.
    803  1.1  rin  *
    804  1.1  rin  *  Disables PCI-Express master access and verifies there are no pending
    805  1.1  rin  *  requests.
    806  1.1  rin  **/
    807  1.1  rin int
    808  1.1  rin igc_disable_pcie_master_generic(struct igc_hw *hw)
    809  1.1  rin {
    810  1.1  rin 	uint32_t ctrl;
    811  1.1  rin 	int timeout = MASTER_DISABLE_TIMEOUT;
    812  1.1  rin 
    813  1.1  rin 	DEBUGFUNC("igc_disable_pcie_master_generic");
    814  1.1  rin 
    815  1.1  rin 	ctrl = IGC_READ_REG(hw, IGC_CTRL);
    816  1.1  rin 	ctrl |= IGC_CTRL_GIO_MASTER_DISABLE;
    817  1.1  rin 	IGC_WRITE_REG(hw, IGC_CTRL, ctrl);
    818  1.1  rin 
    819  1.1  rin 	while (timeout) {
    820  1.1  rin 		if (!(IGC_READ_REG(hw, IGC_STATUS) &
    821  1.1  rin 		    IGC_STATUS_GIO_MASTER_ENABLE))
    822  1.1  rin 			break;
    823  1.1  rin 		DELAY(100);
    824  1.1  rin 		timeout--;
    825  1.1  rin 	}
    826  1.1  rin 
    827  1.1  rin 	if (!timeout) {
    828  1.1  rin 		DEBUGOUT("Master requests are pending.\n");
    829  1.1  rin 		return -IGC_ERR_MASTER_REQUESTS_PENDING;
    830  1.1  rin 	}
    831  1.1  rin 
    832  1.1  rin 	return IGC_SUCCESS;
    833  1.1  rin }
    834