devices/e1000e/mac-3.16-ethercat.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2588 792892ab4806
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2588
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/* Intel PRO/1000 Linux driver
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
 * Copyright(c) 1999 - 2014 Intel Corporation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
 * This program is free software; you can redistribute it and/or modify it
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
 * under the terms and conditions of the GNU General Public License,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
 * version 2, as published by the Free Software Foundation.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
 * This program is distributed in the hope it will be useful, but WITHOUT
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
 * more details.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
 * The full GNU General Public License is included in this distribution in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
 * the file called "COPYING".
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
 * Contact Information:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
 * Linux NICS <linux.nics@intel.com>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
#include "e1000-3.16-ethercat.h"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
 *  e1000e_get_bus_info_pcie - Get PCIe bus information
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
 *  Determines and stores the system bus information for a particular
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
 *  network interface.  The following bus information is determined and stored:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
 *  bus speed, bus width, type (PCIe), and PCIe function.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
	struct e1000_bus_info *bus = &hw->bus;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
	struct e1000_adapter *adapter = hw->adapter;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
	u16 pcie_link_status, cap_offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
	cap_offset = adapter->pdev->pcie_cap;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
	if (!cap_offset) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
		bus->width = e1000_bus_width_unknown;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
		pci_read_config_word(adapter->pdev,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
				     cap_offset + PCIE_LINK_STATUS,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
				     &pcie_link_status);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
		bus->width = (enum e1000_bus_width)((pcie_link_status &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
						     PCIE_LINK_WIDTH_MASK) >>
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
						    PCIE_LINK_WIDTH_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
	mac->ops.set_lan_id(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
 *  e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
 *  Determines the LAN function id by reading memory-mapped registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
 *  and swaps the port value if requested.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	struct e1000_bus_info *bus = &hw->bus;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	u32 reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	/* The status register reports the correct function number
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	 * for the device regardless of function swap state.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	reg = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
 *  e1000_set_lan_id_single_port - Set LAN id for a single port device
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
 *  Sets the LAN function id to zero for a single port device.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
void e1000_set_lan_id_single_port(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	struct e1000_bus_info *bus = &hw->bus;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	bus->func = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
 *  e1000_clear_vfta_generic - Clear VLAN filter table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
 *  Clears the register array which contains the VLAN filter table by
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
 *  setting all the values to 0.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
void e1000_clear_vfta_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	u32 offset;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
		e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
 *  e1000_write_vfta_generic - Write value to VLAN filter table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
 *  @offset: register offset in VLAN filter table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
 *  @value: register value written to VLAN filter table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
 *  Writes value at the given offset in the register array which stores
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
 *  the VLAN filter table.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
 *  e1000e_init_rx_addrs - Initialize receive address's
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
 *  @rar_count: receive address registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
 *  Setup the receive address registers by setting the base receive address
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
 *  register to the devices MAC address and clearing all the other receive
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
 *  address registers to 0.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
	u8 mac_addr[ETH_ALEN] = { 0 };
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
	/* Setup the receive address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
	e_dbg("Programming MAC Address into RAR[0]\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
	/* Zero out the other (rar_entry_count - 1) receive addresses */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
	e_dbg("Clearing RAR[1-%u]\n", rar_count - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
	for (i = 1; i < rar_count; i++)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
		hw->mac.ops.rar_set(hw, mac_addr, i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
 *  e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
 *  Checks the nvm for an alternate MAC address.  An alternate MAC address
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
 *  can be setup by pre-boot software and must be treated like a permanent
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
 *  address and must override the actual permanent MAC address. If an
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
 *  alternate MAC address is found it is programmed into RAR0, replacing
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
 *  the permanent address that was installed into RAR0 by the Si on reset.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
 *  This function will return SUCCESS unless it encounters an error while
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
 *  reading the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
	u16 offset, nvm_alt_mac_addr_offset, nvm_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
	u8 alt_mac_addr[ETH_ALEN];
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
	ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	/* not supported on 82573 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
	if (hw->mac.type == e1000_82573)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
	ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
				 &nvm_alt_mac_addr_offset);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
		e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
	if ((nvm_alt_mac_addr_offset == 0xFFFF) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
	    (nvm_alt_mac_addr_offset == 0x0000))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
		/* There is no Alternate MAC Address */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
	if (hw->bus.func == E1000_FUNC_1)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
		nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
	for (i = 0; i < ETH_ALEN; i += 2) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
		offset = nvm_alt_mac_addr_offset + (i >> 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
			e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
		alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
		alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	/* if multicast bit is set, the alternate address will not be used */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
	if (is_multicast_ether_addr(alt_mac_addr)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
		e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
	/* We have a valid alternate MAC address, and we want to treat it the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	 * same as the normal permanent MAC address stored by the HW into the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
	 * RAR. Do this by mapping this address into RAR0.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
u32 e1000e_rar_get_count_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	return hw->mac.rar_entry_count;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
 *  e1000e_rar_set_generic - Set receive address register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
 *  @addr: pointer to the receive address
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
 *  @index: receive address array register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
 *  Sets the receive address array register at index to the address passed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
 *  in by addr.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
int e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	u32 rar_low, rar_high;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
	/* HW expects these in little endian so we reverse the byte order
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
	 * from network order (big endian) to little endian
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
	rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
		   ((u32)addr[2] << 16) | ((u32)addr[3] << 24));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
	rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	/* If MAC address zero, no need to set the AV bit */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
	if (rar_low || rar_high)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
		rar_high |= E1000_RAH_AV;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
	/* Some bridges will combine consecutive 32-bit writes into
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
	 * a single burst write, which will malfunction on some parts.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
	 * The flushes avoid this.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	ew32(RAL(index), rar_low);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	ew32(RAH(index), rar_high);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
 *  e1000_hash_mc_addr - Generate a multicast hash value
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
 *  @mc_addr: pointer to a multicast address
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
 *  Generates a multicast address hash value which is used to determine
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
 *  the multicast filter table array address and new table value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	u32 hash_value, hash_mask;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	u8 bit_shift = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	/* Register count multiplied by bits per register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	/* For a mc_filter_type of 0, bit_shift is the number of left-shifts
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	 * where 0xFF would still fall within the hash mask.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	while (hash_mask >> bit_shift != 0xFF)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		bit_shift++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
	/* The portion of the address that is used for the hash table
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	 * is determined by the mc_filter_type setting.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
	 * The algorithm is such that there is a total of 8 bits of shifting.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	 * The bit_shift for a mc_filter_type of 0 represents the number of
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	 * left-shifts where the MSB of mc_addr[5] would still fall within
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	 * the hash_mask.  Case 0 does this exactly.  Since there are a total
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	 * of 8 bits of shifting, then mc_addr[4] will shift right the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	 * remaining number of bits. Thus 8 - bit_shift.  The rest of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
	 * cases are a variation of this algorithm...essentially raising the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
	 * number of bits to shift mc_addr[5] left, while still keeping the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
	 * 8-bit shifting total.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
	 * For example, given the following Destination MAC Address and an
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
	 * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
	 * we can see that the bit_shift for case 0 is 4.  These are the hash
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
	 * values resulting from each mc_filter_type...
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
	 * [0] [1] [2] [3] [4] [5]
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
	 * 01  AA  00  12  34  56
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
	 * LSB           MSB
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
	 * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	 * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
	 * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
	 * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
	switch (hw->mac.mc_filter_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
	case 0:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
	case 1:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
		bit_shift += 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
	case 2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
		bit_shift += 2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	case 3:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
		bit_shift += 4;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
	hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
				   (((u16)mc_addr[5]) << bit_shift)));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
	return hash_value;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
 *  e1000e_update_mc_addr_list_generic - Update Multicast addresses
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
 *  @mc_addr_list: array of multicast addresses to program
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
 *  @mc_addr_count: number of multicast addresses to program
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
 *  Updates entire Multicast Table Array.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
 *  The caller must have a packed mc_addr_list of multicast addresses.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
					u8 *mc_addr_list, u32 mc_addr_count)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
	u32 hash_value, hash_bit, hash_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	int i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	/* clear mta_shadow */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
	memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	/* update mta_shadow from mc_addr_list */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	for (i = 0; (u32)i < mc_addr_count; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
		hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
		hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
		hash_bit = hash_value & 0x1F;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
		hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
		mc_addr_list += (ETH_ALEN);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	/* replace the entire MTA table */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
		E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
 *  e1000e_clear_hw_cntrs_base - Clear base hardware counters
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
 *  Clears the base hardware counters by reading the counter registers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
	er32(CRCERRS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
	er32(SYMERRS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	er32(MPC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	er32(SCC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	er32(ECOL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
	er32(MCC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	er32(LATECOL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
	er32(COLC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	er32(DC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
	er32(SEC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
	er32(RLEC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	er32(XONRXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
	er32(XONTXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	er32(XOFFRXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
	er32(XOFFTXC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
	er32(FCRUC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
	er32(GPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
	er32(BPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
	er32(MPRC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
	er32(GPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
	er32(GORCL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	er32(GORCH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
	er32(GOTCL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
	er32(GOTCH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
	er32(RNBC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
	er32(RUC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
	er32(RFC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
	er32(ROC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
	er32(RJC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
	er32(TORL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
	er32(TORH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
	er32(TOTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
	er32(TOTH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
	er32(TPR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
	er32(TPT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
	er32(MPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
	er32(BPTC);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
 *  e1000e_check_for_copper_link - Check for link (Copper)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
 *  Checks to see of the link status of the hardware has changed.  If a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
 *  change in link status has been detected, then we read the PHY registers
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
 *  to get the current speed/duplex if link exists.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
	bool link;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	/* We only want to go out to the PHY registers to see if Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
	 * has completed and/or if our link status has changed.  The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
	 * get_link_status flag is set upon receiving a Link Status
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
	 * Change or Rx Sequence Error interrupt.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	if (!mac->get_link_status)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
	/* First we want to see if the MII Status Register reports
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
	 * link.  If so, then we want to get the current speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
	 * of the PHY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
	if (!link)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
		return 0;	/* No link detected */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	mac->get_link_status = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	/* Check if there was DownShift, must be checked
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
	 * immediately after link-up
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
	e1000e_check_downshift(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
	/* If we are forcing speed/duplex, then we simply return since
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	 * we have already determined whether we have link or not.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
	if (!mac->autoneg)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
	/* Auto-Neg is enabled.  Auto Speed Detection takes care
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	 * of MAC speed/duplex configuration.  So we only need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	 * configure Collision Distance in the MAC.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	mac->ops.config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
	/* Configure Flow Control now that Auto-Neg has completed.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	 * First, we need to restore the desired flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	 * settings because we may have had to re-autoneg with a
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	 * different link partner.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	ret_val = e1000e_config_fc_after_link_up(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
		e_dbg("Error configuring flow control\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
 *  e1000e_check_for_fiber_link - Check for link (Fiber)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
 *  Checks for link up on the hardware.  If link is not up and we have
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
 *  a signal, then we need to force link up.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
	u32 rxcw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
	/* If we don't have link (auto-negotiation failed or link partner
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	 * cannot auto-negotiate), the cable is plugged in (we have signal),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
	 * and our link partner is not trying to auto-negotiate with us (we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
	 * are receiving idles or data), we need to force link up. We also
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
	 * need to give auto-negotiation time to complete, in case the cable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
	 * was just plugged in. The autoneg_failed flag does this.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
	if ((ctrl & E1000_CTRL_SWDPIN1) && !(status & E1000_STATUS_LU) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
	    !(rxcw & E1000_RXCW_C)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
		if (!mac->autoneg_failed) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
			mac->autoneg_failed = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
			return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
		/* Disable auto-negotiation in the TXCW register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
		/* Force link-up and also force full-duplex. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
		/* Configure Flow Control after forcing link up. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
		ret_val = e1000e_config_fc_after_link_up(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
			e_dbg("Error configuring flow control\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
		/* If we are forcing link and we are receiving /C/ ordered
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		 * sets, re-enable auto-negotiation in the TXCW register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
		 * and disable forced link in the Device Control register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
		 * in an attempt to auto-negotiate with our link partner.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		ew32(TXCW, mac->txcw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
		mac->serdes_has_link = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
 *  e1000e_check_for_serdes_link - Check for link (Serdes)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
 *  Checks for link up on the hardware.  If link is not up and we have
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
 *  a signal, then we need to force link up.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
	u32 rxcw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
	rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
	/* If we don't have link (auto-negotiation failed or link partner
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
	 * cannot auto-negotiate), and our link partner is not trying to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
	 * auto-negotiate with us (we are receiving idles or data),
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
	 * we need to force link up. We also need to give auto-negotiation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
	 * time to complete.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	/* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	if (!(status & E1000_STATUS_LU) && !(rxcw & E1000_RXCW_C)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
		if (!mac->autoneg_failed) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
			mac->autoneg_failed = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
			return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
		e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
		/* Disable auto-negotiation in the TXCW register */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
		ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
		/* Force link-up and also force full-duplex. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
		ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
		/* Configure Flow Control after forcing link up. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		ret_val = e1000e_config_fc_after_link_up(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
			e_dbg("Error configuring flow control\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
		/* If we are forcing link and we are receiving /C/ ordered
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
		 * sets, re-enable auto-negotiation in the TXCW register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		 * and disable forced link in the Device Control register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
		 * in an attempt to auto-negotiate with our link partner.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
		e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
		ew32(TXCW, mac->txcw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
		ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		mac->serdes_has_link = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		/* If we force link for non-auto-negotiation switch, check
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		 * link status based on MAC synchronization for internal
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
		 * serdes media type.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		/* SYNCH bit and IV bit are sticky. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		usleep_range(10, 20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
		if (rxcw & E1000_RXCW_SYNCH) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
			if (!(rxcw & E1000_RXCW_IV)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
				mac->serdes_has_link = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
				e_dbg("SERDES: Link up - forced.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
			mac->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
			e_dbg("SERDES: Link down - force failed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	if (E1000_TXCW_ANE & er32(TXCW)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
		if (status & E1000_STATUS_LU) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
			/* SYNCH bit and IV bit are sticky, so reread rxcw. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
			usleep_range(10, 20);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
			rxcw = er32(RXCW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
			if (rxcw & E1000_RXCW_SYNCH) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
				if (!(rxcw & E1000_RXCW_IV)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
					mac->serdes_has_link = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
					e_dbg("SERDES: Link up - autoneg completed successfully.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
				} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
					mac->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
					e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
				}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
				mac->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
				e_dbg("SERDES: Link down - no sync.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
			mac->serdes_has_link = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
			e_dbg("SERDES: Link down - autoneg failed\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
 *  e1000_set_default_fc_generic - Set flow control default values
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
 *  Read the EEPROM for the default values for flow control and store the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
 *  values.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
	u16 nvm_data;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
	/* Read and store word 0x0F of the EEPROM. This word contains bits
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
	 * that determine the hardware's default PAUSE (flow control) mode,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
	 * a bit that determines whether the HW defaults to enabling or
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	 * disabling auto-negotiation, and the direction of the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
	 * SW defined pins. If there is no SW over-ride of the flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	 * control setting, then the variable hw->fc will
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	 * be initialized based on a value in the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
		e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	if (!(nvm_data & NVM_WORD0F_PAUSE_MASK))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
		hw->fc.requested_mode = e1000_fc_none;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == NVM_WORD0F_ASM_DIR)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
		hw->fc.requested_mode = e1000_fc_tx_pause;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
		hw->fc.requested_mode = e1000_fc_full;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
 *  e1000e_setup_link_generic - Setup flow control and link settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
 *  Determines which flow control settings to use, then configures flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
 *  control.  Calls the appropriate media-specific link configuration
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
 *  function.  Assuming the adapter has a valid link partner, a valid link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
 *  should be established.  Assumes the hardware has previously been reset
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
 *  and the transmitter and receiver are not enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
s32 e1000e_setup_link_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
	/* In the case of the phy reset being blocked, we already have a link.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	 * We do not need to set it up again.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
	if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	/* If requested flow control is set to default, set flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
	 * based on the EEPROM flow control settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	if (hw->fc.requested_mode == e1000_fc_default) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		ret_val = e1000_set_default_fc_generic(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
	/* Save off the requested flow control mode for use later.  Depending
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	 * on the link partner's capabilities, we may or may not use this mode.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	hw->fc.current_mode = hw->fc.requested_mode;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
	e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	/* Call the necessary media_type subroutine to configure the link. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
	ret_val = hw->mac.ops.setup_physical_interface(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
	/* Initialize the flow control address, type, and PAUSE timer
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	 * registers to their default values.  This is done even if flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	 * control is disabled, because it does not hurt anything to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
	 * initialize these registers.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
	e_dbg("Initializing the Flow Control address, type and timer regs\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
	ew32(FCT, FLOW_CONTROL_TYPE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	ew32(FCTTV, hw->fc.pause_time);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	return e1000e_set_fc_watermarks(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
 *  e1000_commit_fc_settings_generic - Configure flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
 *  Write the flow control settings to the Transmit Config Word Register (TXCW)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
 *  base on the flow control settings in e1000_mac_info.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	u32 txcw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
	/* Check for a software override of the flow control settings, and
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
	 * setup the device accordingly.  If auto-negotiation is enabled, then
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
	 * software will have to set the "PAUSE" bits to the correct value in
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
	 * the Transmit Config Word Register (TXCW) and re-start auto-
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	 * negotiation.  However, if auto-negotiation is disabled, then
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
	 * software will have to manually configure the two flow control enable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	 * bits in the CTRL register.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
	 * The possible values of the "fc" parameter are:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
	 *      0:  Flow control is completely disabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
	 *      1:  Rx flow control is enabled (we can receive pause frames,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	 *          but not send pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	 *      2:  Tx flow control is enabled (we can send pause frames but we
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
	 *          do not support receiving pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	switch (hw->fc.current_mode) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
	case e1000_fc_none:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
		/* Flow control completely disabled by a software over-ride. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
	case e1000_fc_rx_pause:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
		/* Rx Flow control is enabled and Tx Flow control is disabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
		 * by a software over-ride. Since there really isn't a way to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
		 * advertise that we are capable of Rx Pause ONLY, we will
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
		 * advertise that we support both symmetric and asymmetric Rx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
		 * PAUSE.  Later, we will disable the adapter's ability to send
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
		 * PAUSE frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
	case e1000_fc_tx_pause:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
		/* Tx Flow control is enabled, and Rx Flow control is disabled,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
		 * by a software over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
	case e1000_fc_full:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
		/* Flow control (both Rx and Tx) is enabled by a software
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
		 * over-ride.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
		e_dbg("Flow control param set incorrectly\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
	ew32(TXCW, txcw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	mac->txcw = txcw;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
 *  e1000_poll_fiber_serdes_link_generic - Poll for link up
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
 *  Polls for link up by reading the status register, if link fails to come
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
 *  up with auto-negotiation, then the link is forced if a signal is detected.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	u32 i, status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
	/* If we have a signal (the cable is plugged in, or assumed true for
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
	 * serdes media) then poll for a "Link-Up" indication in the Device
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	 * Status Register.  Time-out if a link isn't seen in 500 milliseconds
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
	 * seconds (Auto-negotiation should complete in less than 500
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
	 * milliseconds even if the other end is doing it in SW).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
		usleep_range(10000, 20000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
		status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
		if (status & E1000_STATUS_LU)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
	if (i == FIBER_LINK_UP_LIMIT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
		e_dbg("Never got a valid link from auto-neg!!!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
		mac->autoneg_failed = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
		/* AutoNeg failed to achieve a link, so we'll call
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
		 * mac->check_for_link. This routine will force the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
		 * link up if we detect a signal. This will allow us to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
		 * communicate with non-autonegotiating link partners.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
		ret_val = mac->ops.check_for_link(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
			e_dbg("Error while checking for link\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
		mac->autoneg_failed = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
		mac->autoneg_failed = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
		e_dbg("Valid Link Found\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
 *  e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
 *  Configures collision distance and flow control for fiber and serdes
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
 *  links.  Upon successful setup, poll for link.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
	/* Take the link out of reset */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
	ctrl &= ~E1000_CTRL_LRST;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	hw->mac.ops.config_collision_dist(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	ret_val = e1000_commit_fc_settings_generic(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
	/* Since auto-negotiation is enabled, take the link out of reset (the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
	 * link will be in reset, because we previously reset the chip). This
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
	 * will restart auto-negotiation.  If auto-negotiation is successful
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	 * then the link-up status bit will be set and the flow control enable
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
	 * bits (RFCE and TFCE) will be set according to their negotiated value.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	e_dbg("Auto-negotiation enabled\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	usleep_range(1000, 2000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	/* For these adapters, the SW definable pin 1 is set when the optics
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	 * detect a signal.  If we have a signal, then poll for a "Link-Up"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	 * indication.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
		e_dbg("No signal detected\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
 *  e1000e_config_collision_dist_generic - Configure collision distance
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
 *  Configures the collision distance to the default value and is used
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
 *  during link setup.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
void e1000e_config_collision_dist_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
	u32 tctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
	tctl = er32(TCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
	tctl &= ~E1000_TCTL_COLD;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
	ew32(TCTL, tctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
	e1e_flush();
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
 *  e1000e_set_fc_watermarks - Set flow control high/low watermarks
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
 *  Sets the flow control high/low threshold (watermark) registers.  If
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
 *  flow control XON frame transmission is enabled, then set XON frame
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
 *  transmission as well.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
	u32 fcrtl = 0, fcrth = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
	/* Set the flow control receive threshold registers.  Normally,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
	 * these registers will be set to a default threshold that may be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
	 * adjusted later by the driver's runtime code.  However, if the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
	 * ability to transmit pause frames is not enabled, then these
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
	 * registers will be set to 0.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
	if (hw->fc.current_mode & e1000_fc_tx_pause) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		/* We need to set up the Receive Threshold high and low water
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
		 * marks as well as (optionally) enabling the transmission of
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
		 * XON frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
		fcrtl = hw->fc.low_water;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		if (hw->fc.send_xon)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
			fcrtl |= E1000_FCRTL_XONE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
		fcrth = hw->fc.high_water;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
	ew32(FCRTL, fcrtl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
	ew32(FCRTH, fcrth);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
 *  e1000e_force_mac_fc - Force the MAC's flow control settings
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
 *  Force the MAC's flow control settings.  Sets the TFCE and RFCE bits in the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
 *  device control register to reflect the adapter settings.  TFCE and RFCE
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
 *  need to be explicitly set by software when a copper PHY is used because
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
 *  autonegotiation is managed by the PHY rather than the MAC.  Software must
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
 *  also configure these bits when link is forced on a fiber connection.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
s32 e1000e_force_mac_fc(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	/* Because we didn't get link via the internal auto-negotiation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
	 * mechanism (we either forced link or we got link via PHY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
	 * auto-neg), we have to manually enable/disable transmit an
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
	 * receive flow control.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	 * The "Case" statement below enables/disable flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	 * according to the "hw->fc.current_mode" parameter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
	 * The possible values of the "fc" parameter are:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	 *      0:  Flow control is completely disabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
	 *      1:  Rx flow control is enabled (we can receive pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	 *          frames but not send pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
	 *      2:  Tx flow control is enabled (we can send pause frames
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
	 *          frames but we do not receive pause frames).
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
	 *  other:  No other values should be possible at this point.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	switch (hw->fc.current_mode) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	case e1000_fc_none:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	case e1000_fc_rx_pause:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
		ctrl &= (~E1000_CTRL_TFCE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
		ctrl |= E1000_CTRL_RFCE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	case e1000_fc_tx_pause:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
		ctrl &= (~E1000_CTRL_RFCE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		ctrl |= E1000_CTRL_TFCE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
	case e1000_fc_full:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
		e_dbg("Flow control param set incorrectly\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
 *  e1000e_config_fc_after_link_up - Configures flow control after link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
 *  Checks the status of auto-negotiation after link up to ensure that the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
 *  speed and duplex were not forced.  If the link needed to be forced, then
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
 *  flow control needs to be forced also.  If auto-negotiation is enabled
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
 *  and did not fail, then we configure flow control based on our link
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
 *  partner.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
	s32 ret_val = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
	u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
	u16 speed, duplex;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
	/* Check for the case where we have fiber media and auto-neg failed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
	 * so we had to force link.  In this case, we need to force the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
	 * configuration of the MAC to match the "fc" parameter.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
	if (mac->autoneg_failed) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
		if (hw->phy.media_type == e1000_media_type_fiber ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		    hw->phy.media_type == e1000_media_type_internal_serdes)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
			ret_val = e1000e_force_mac_fc(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
		if (hw->phy.media_type == e1000_media_type_copper)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
			ret_val = e1000e_force_mac_fc(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
		e_dbg("Error forcing flow control settings\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
	/* Check for the case where we have copper media and auto-neg is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
	 * enabled.  In this case, we need to check and see if Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
	 * has completed, and if so, how the PHY and link partner has
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
	 * flow control configured.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
	if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
		/* Read the MII Status Register and check to see if AutoNeg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		 * has completed.  We read this twice because this reg has
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
		 * some "sticky" (latched) bits.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		ret_val = e1e_rphy(hw, MII_BMSR, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		ret_val = e1e_rphy(hw, MII_BMSR, &mii_status_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		if (!(mii_status_reg & BMSR_ANEGCOMPLETE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
			e_dbg("Copper PHY and Auto Neg has not completed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
		/* The AutoNeg process has completed, so we now need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
		 * read both the Auto Negotiation Advertisement
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		 * Register (Address 4) and the Auto_Negotiation Base
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
		 * Page Ability Register (Address 5) to determine how
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		 * flow control was negotiated.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
		ret_val = e1e_rphy(hw, MII_ADVERTISE, &mii_nway_adv_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
		ret_val = e1e_rphy(hw, MII_LPA, &mii_nway_lp_ability_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
		if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
		/* Two bits in the Auto Negotiation Advertisement Register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
		 * (Address 4) and two bits in the Auto Negotiation Base
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
		 * Page Ability Register (Address 5) determine flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
		 * for both the PHY and the link partner.  The following
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
		 * 1999, describes these PAUSE resolution bits and how flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
		 * control is determined based upon these settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
		 * NOTE:  DC = Don't Care
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
		 *   0   |    1    |   0   |   DC    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
		 *   0   |    1    |   1   |    0    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
		 *   1   |    0    |   0   |   DC    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
		 *   1   |    1    |   0   |    0    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		 * Are both PAUSE bits set to 1?  If so, this implies
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		 * Symmetric Flow Control is enabled at both ends.  The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		 * ASM_DIR bits are irrelevant per the spec.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
		 * For Symmetric Flow Control:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
		 *   1   |   DC    |   1   |   DC    | E1000_fc_full
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
		if ((mii_nway_adv_reg & ADVERTISE_PAUSE_CAP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
		    (mii_nway_lp_ability_reg & LPA_PAUSE_CAP)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
			/* Now we need to check if the user selected Rx ONLY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
			 * of pause frames.  In this case, we had to advertise
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
			 * FULL flow control because we could not advertise Rx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
			 * ONLY. Hence, we must now check to see if we need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			 * turn OFF the TRANSMISSION of PAUSE frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			if (hw->fc.requested_mode == e1000_fc_full) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
				hw->fc.current_mode = e1000_fc_full;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
				e_dbg("Flow Control = FULL.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
				hw->fc.current_mode = e1000_fc_rx_pause;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
				e_dbg("Flow Control = Rx PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
		/* For receiving PAUSE frames ONLY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
		else if (!(mii_nway_adv_reg & ADVERTISE_PAUSE_CAP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
			 (mii_nway_adv_reg & ADVERTISE_PAUSE_ASYM) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
			 (mii_nway_lp_ability_reg & LPA_PAUSE_CAP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
			 (mii_nway_lp_ability_reg & LPA_PAUSE_ASYM)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
			hw->fc.current_mode = e1000_fc_tx_pause;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
			e_dbg("Flow Control = Tx PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
		/* For transmitting PAUSE frames ONLY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		else if ((mii_nway_adv_reg & ADVERTISE_PAUSE_CAP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
			 (mii_nway_adv_reg & ADVERTISE_PAUSE_ASYM) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
			 !(mii_nway_lp_ability_reg & LPA_PAUSE_CAP) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
			 (mii_nway_lp_ability_reg & LPA_PAUSE_ASYM)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
			hw->fc.current_mode = e1000_fc_rx_pause;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
			e_dbg("Flow Control = Rx PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
			/* Per the IEEE spec, at this point flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
			 * should be disabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
			hw->fc.current_mode = e1000_fc_none;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
			e_dbg("Flow Control = NONE.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
		/* Now we need to do one last check...  If we auto-
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
		 * negotiated to HALF DUPLEX, flow control should not be
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
		 * enabled per IEEE 802.3 spec.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
		ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
			e_dbg("Error getting link speed and duplex\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		if (duplex == HALF_DUPLEX)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
			hw->fc.current_mode = e1000_fc_none;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
		/* Now we call a subroutine to actually force the MAC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
		 * controller to use the correct flow control settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		ret_val = e1000e_force_mac_fc(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
			e_dbg("Error forcing flow control settings\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	/* Check for the case where we have SerDes media and auto-neg is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
	 * enabled.  In this case, we need to check and see if Auto-Neg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
	 * has completed, and if so, how the PHY and link partner has
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	 * flow control configured.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
	    mac->autoneg) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
		/* Read the PCS_LSTS and check to see if AutoNeg
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
		 * has completed.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
		pcs_status_reg = er32(PCS_LSTAT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
		if (!(pcs_status_reg & E1000_PCS_LSTS_AN_COMPLETE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
			e_dbg("PCS Auto Neg has not completed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		/* The AutoNeg process has completed, so we now need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		 * read both the Auto Negotiation Advertisement
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		 * Register (PCS_ANADV) and the Auto_Negotiation Base
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
		 * Page Ability Register (PCS_LPAB) to determine how
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		 * flow control was negotiated.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
		pcs_adv_reg = er32(PCS_ANADV);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
		pcs_lp_ability_reg = er32(PCS_LPAB);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		/* Two bits in the Auto Negotiation Advertisement Register
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		 * (PCS_ANADV) and two bits in the Auto Negotiation Base
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		 * Page Ability Register (PCS_LPAB) determine flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		 * for both the PHY and the link partner.  The following
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		 * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
		 * 1999, describes these PAUSE resolution bits and how flow
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		 * control is determined based upon these settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
		 * NOTE:  DC = Don't Care
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		 *   0   |    0    |  DC   |   DC    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		 *   0   |    1    |   0   |   DC    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
		 *   0   |    1    |   1   |    0    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		 *   1   |    0    |   0   |   DC    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
		 *   1   |    1    |   0   |    0    | e1000_fc_none
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
		 * Are both PAUSE bits set to 1?  If so, this implies
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		 * Symmetric Flow Control is enabled at both ends.  The
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
		 * ASM_DIR bits are irrelevant per the spec.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
		 * For Symmetric Flow Control:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
		 *   1   |   DC    |   1   |   DC    | e1000_fc_full
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
		if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
		    (pcs_lp_ability_reg & E1000_TXCW_PAUSE)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
			/* Now we need to check if the user selected Rx ONLY
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
			 * of pause frames.  In this case, we had to advertise
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
			 * FULL flow control because we could not advertise Rx
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
			 * ONLY. Hence, we must now check to see if we need to
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
			 * turn OFF the TRANSMISSION of PAUSE frames.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
			if (hw->fc.requested_mode == e1000_fc_full) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
				hw->fc.current_mode = e1000_fc_full;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
				e_dbg("Flow Control = FULL.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
			} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
				hw->fc.current_mode = e1000_fc_rx_pause;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
				e_dbg("Flow Control = Rx PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
		/* For receiving PAUSE frames ONLY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
		 *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
		else if (!(pcs_adv_reg & E1000_TXCW_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
			 (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
			 (pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
			 (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
			hw->fc.current_mode = e1000_fc_tx_pause;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
			e_dbg("Flow Control = Tx PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
		/* For transmitting PAUSE frames ONLY.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
		 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		 *   LOCAL DEVICE  |   LINK PARTNER
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
		 *-------|---------|-------|---------|--------------------
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		else if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
			 (pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
			 !(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
			 (pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
			hw->fc.current_mode = e1000_fc_rx_pause;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
			e_dbg("Flow Control = Rx PAUSE frames only.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
			/* Per the IEEE spec, at this point flow control
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
			 * should be disabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
			 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
			hw->fc.current_mode = e1000_fc_none;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
			e_dbg("Flow Control = NONE.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
		/* Now we call a subroutine to actually force the MAC
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
		 * controller to use the correct flow control settings.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
		pcs_ctrl_reg = er32(PCS_LCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
		pcs_ctrl_reg |= E1000_PCS_LCTL_FORCE_FCTRL;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
		ew32(PCS_LCTL, pcs_ctrl_reg);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
		ret_val = e1000e_force_mac_fc(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
		if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
			e_dbg("Error forcing flow control settings\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
			return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
 *  e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
 *  @speed: stores the current speed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
 *  @duplex: stores the current duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
 *  Read the status register for the current speed/duplex and store the current
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
 *  speed and duplex for copper connections.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
				       u16 *duplex)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
	u32 status;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
	status = er32(STATUS);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
	if (status & E1000_STATUS_SPEED_1000)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
		*speed = SPEED_1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
	else if (status & E1000_STATUS_SPEED_100)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		*speed = SPEED_100;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
		*speed = SPEED_10;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	if (status & E1000_STATUS_FD)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
		*duplex = FULL_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
		*duplex = HALF_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
	e_dbg("%u Mbps, %s Duplex\n",
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
	      *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10,
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
	      *duplex == FULL_DUPLEX ? "Full" : "Half");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
 *  e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
 *  @speed: stores the current speed
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
 *  @duplex: stores the current duplex
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
 *  Sets the speed and duplex to gigabit full duplex (the only possible option)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
 *  for fiber/serdes links.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw __always_unused
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
					     *hw, u16 *speed, u16 *duplex)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
	*speed = SPEED_1000;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
	*duplex = FULL_DUPLEX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
 *  e1000e_get_hw_semaphore - Acquire hardware semaphore
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
 *  Acquire the HW semaphore to access the PHY or NVM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
s32 e1000e_get_hw_semaphore(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	u32 swsm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
	s32 timeout = hw->nvm.word_size + 1;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
	s32 i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
	/* Get the SW semaphore */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
	while (i < timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		swsm = er32(SWSM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		if (!(swsm & E1000_SWSM_SMBI))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
		usleep_range(50, 100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
		i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
	if (i == timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		e_dbg("Driver can't access device - SMBI bit is set.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
	/* Get the FW semaphore. */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	for (i = 0; i < timeout; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		swsm = er32(SWSM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
		ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
		/* Semaphore acquired if bit latched */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
		if (er32(SWSM) & E1000_SWSM_SWESMBI)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
		usleep_range(50, 100);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	if (i == timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		/* Release semaphores */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		e1000e_put_hw_semaphore(hw);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		e_dbg("Driver can't access the NVM\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
		return -E1000_ERR_NVM;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
 *  e1000e_put_hw_semaphore - Release hardware semaphore
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
 *  Release hardware semaphore used to access the PHY or NVM
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
void e1000e_put_hw_semaphore(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
	u32 swsm;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
	swsm = er32(SWSM);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	ew32(SWSM, swsm);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
 *  e1000e_get_auto_rd_done - Check for auto read completion
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
 *  Check EEPROM for Auto Read done bit.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
	s32 i = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	while (i < AUTO_READ_DONE_TIMEOUT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
		if (er32(EECD) & E1000_EECD_AUTO_RD)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
		usleep_range(1000, 2000);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
		i++;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	if (i == AUTO_READ_DONE_TIMEOUT) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
		e_dbg("Auto read by HW from NVM has not completed.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
		return -E1000_ERR_RESET;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
 *  e1000e_valid_led_default - Verify a valid default LED config
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
 *  @data: pointer to the NVM (EEPROM)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
 *  Read the EEPROM for the current default LED configuration.  If the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
 *  LED configuration is not valid, set to a valid LED configuration.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	if (ret_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
		e_dbg("NVM Read Error\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
		*data = ID_LED_DEFAULT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
 *  e1000e_id_led_init_generic -
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
s32 e1000e_id_led_init_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	s32 ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	const u32 ledctl_mask = 0x000000FF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
	const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	u16 data, i, temp;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	const u16 led_mask = 0x0F;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
	ret_val = hw->nvm.ops.valid_led_default(hw, &data);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	if (ret_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
		return ret_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	mac->ledctl_default = er32(LEDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	mac->ledctl_mode1 = mac->ledctl_default;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	mac->ledctl_mode2 = mac->ledctl_default;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	for (i = 0; i < 4; i++) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
		temp = (data >> (i << 2)) & led_mask;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
		switch (temp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
		case ID_LED_ON1_DEF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
		case ID_LED_ON1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
		case ID_LED_ON1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
			mac->ledctl_mode1 |= ledctl_on << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
		case ID_LED_OFF1_DEF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
		case ID_LED_OFF1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
		case ID_LED_OFF1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
			mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
			mac->ledctl_mode1 |= ledctl_off << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
			/* Do nothing */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
		switch (temp) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		case ID_LED_DEF1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
		case ID_LED_ON1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
		case ID_LED_OFF1_ON2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
			mac->ledctl_mode2 |= ledctl_on << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
		case ID_LED_DEF1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
		case ID_LED_ON1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
		case ID_LED_OFF1_OFF2:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
			mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3));
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
			mac->ledctl_mode2 |= ledctl_off << (i << 3);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
		default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
			/* Do nothing */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
 *  e1000e_setup_led_generic - Configures SW controllable LED
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
 *  This prepares the SW controllable LED for use and saves the current state
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
 *  of the LED so it can be later restored.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
s32 e1000e_setup_led_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
	u32 ledctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
	if (hw->mac.ops.setup_led != e1000e_setup_led_generic)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
		return -E1000_ERR_CONFIG;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
	if (hw->phy.media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
		ledctl = er32(LEDCTL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
		hw->mac.ledctl_default = ledctl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		/* Turn off LED0 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
			    E1000_LEDCTL_LED0_MODE_MASK);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
		ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
			   E1000_LEDCTL_LED0_MODE_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
		ew32(LEDCTL, ledctl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
	} else if (hw->phy.media_type == e1000_media_type_copper) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		ew32(LEDCTL, hw->mac.ledctl_mode1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
 *  e1000e_cleanup_led_generic - Set LED config to default operation
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
 *  Remove the current LED configuration and set the LED configuration
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
 *  to the default value, saved from the EEPROM.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
	ew32(LEDCTL, hw->mac.ledctl_default);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
 *  e1000e_blink_led_generic - Blink LED
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
 *  Blink the LEDs which are set to be on.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
s32 e1000e_blink_led_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
	u32 ledctl_blink = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
	u32 i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	if (hw->phy.media_type == e1000_media_type_fiber) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		/* always blink LED0 for PCI-E fiber */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
		    (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
		/* Set the blink bit for each LED that's "on" (0x0E)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
		 * (or "off" if inverted) in ledctl_mode2.  The blink
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
		 * logic in hardware only works when mode is set to "on"
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
		 * so it must be changed accordingly when the mode is
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
		 * "off" and inverted.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
		 */
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
		ledctl_blink = hw->mac.ledctl_mode2;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
		for (i = 0; i < 32; i += 8) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
			u32 mode = (hw->mac.ledctl_mode2 >> i) &
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
			    E1000_LEDCTL_LED0_MODE_MASK;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
			u32 led_default = hw->mac.ledctl_default >> i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
			if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
			     (mode == E1000_LEDCTL_MODE_LED_ON)) ||
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
			    ((led_default & E1000_LEDCTL_LED0_IVRT) &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
			     (mode == E1000_LEDCTL_MODE_LED_OFF))) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
				ledctl_blink &=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
				    ~(E1000_LEDCTL_LED0_MODE_MASK << i);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
				ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
						 E1000_LEDCTL_MODE_LED_ON) << i;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	ew32(LEDCTL, ledctl_blink);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
 *  e1000e_led_on_generic - Turn LED on
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
 *  Turn LED on.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
s32 e1000e_led_on_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
	switch (hw->phy.media_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
	case e1000_media_type_fiber:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
		ctrl &= ~E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
	case e1000_media_type_copper:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		ew32(LEDCTL, hw->mac.ledctl_mode2);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
 *  e1000e_led_off_generic - Turn LED off
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
 *  Turn LED off.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
s32 e1000e_led_off_generic(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
	switch (hw->phy.media_type) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
	case e1000_media_type_fiber:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
		ctrl |= E1000_CTRL_SWDPIN0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
		ctrl |= E1000_CTRL_SWDPIO0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
		ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
	case e1000_media_type_copper:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
		ew32(LEDCTL, hw->mac.ledctl_mode1);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
	default:
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
		break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
 *  e1000e_set_pcie_no_snoop - Set PCI-express capabilities
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
 *  @no_snoop: bitmap of snoop events
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
 *  Set the PCI-express register to snoop for events enabled in 'no_snoop'.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
	u32 gcr;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	if (no_snoop) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		gcr = er32(GCR);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
		gcr &= ~(PCIE_NO_SNOOP_ALL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
		gcr |= no_snoop;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
		ew32(GCR, gcr);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
 *  e1000e_disable_pcie_master - Disables PCI-express master access
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
 *  Returns 0 if successful, else returns -10
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
 *  (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
 *  the master requests to be disabled.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
 *  Disables PCI-Express master access and verifies there are no pending
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
 *  requests.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
s32 e1000e_disable_pcie_master(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	u32 ctrl;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
	s32 timeout = MASTER_DISABLE_TIMEOUT;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
	ctrl = er32(CTRL);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
	ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
	ew32(CTRL, ctrl);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
	while (timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
		if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
			break;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
		usleep_range(100, 200);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
		timeout--;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
	if (!timeout) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
		e_dbg("Master requests are pending.\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		return -E1000_ERR_MASTER_REQUESTS_PENDING;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
	return 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
 *  e1000e_reset_adaptive - Reset Adaptive Interframe Spacing
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
 *  Reset the Adaptive Interframe Spacing throttle to default values.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
void e1000e_reset_adaptive(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	if (!mac->adaptive_ifs) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
		e_dbg("Not in Adaptive IFS mode!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	mac->current_ifs_val = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
	mac->ifs_min_val = IFS_MIN;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	mac->ifs_max_val = IFS_MAX;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
	mac->ifs_step_size = IFS_STEP;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
	mac->ifs_ratio = IFS_RATIO;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
	mac->in_ifs_mode = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
	ew32(AIT, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
/**
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
 *  e1000e_update_adaptive - Update Adaptive Interframe Spacing
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
 *  @hw: pointer to the HW structure
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
 *
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
 *  Update the Adaptive Interframe Spacing Throttle value based on the
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
 *  time between transmitted packets and time between collisions.
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
 **/
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
void e1000e_update_adaptive(struct e1000_hw *hw)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
{
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
	struct e1000_mac_info *mac = &hw->mac;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
	if (!mac->adaptive_ifs) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
		e_dbg("Not in Adaptive IFS mode!\n");
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		return;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
	if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		if (mac->tx_packet_delta > MIN_NUM_XMITS) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
			mac->in_ifs_mode = true;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
			if (mac->current_ifs_val < mac->ifs_max_val) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
				if (!mac->current_ifs_val)
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
					mac->current_ifs_val = mac->ifs_min_val;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
				else
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
					mac->current_ifs_val +=
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
					    mac->ifs_step_size;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
				ew32(AIT, mac->current_ifs_val);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
			}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
	} else {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
		if (mac->in_ifs_mode &&
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		    (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			mac->current_ifs_val = 0;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
			mac->in_ifs_mode = false;
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
			ew32(AIT, 0);
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
	}
792892ab4806 Added all drivers for kernel 3.16.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
}