11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
30abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  Intel PRO/10GbE Linux driver
4f731a9ef82c6728559b34743bca19d231e5e1b63Jesse Brandeburg  Copyright(c) 1999 - 2008 Intel Corporation.
50abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
60abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  This program is free software; you can redistribute it and/or modify it
70abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  under the terms and conditions of the GNU General Public License,
80abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  version 2, as published by the Free Software Foundation.
90abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
100abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  This program is distributed in the hope it will be useful, but WITHOUT
110abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
120abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  more details.
140abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  You should have received a copy of the GNU General Public License along with
160abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  this program; if not, write to the Free Software Foundation, Inc.,
170abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
180abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
190abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  The full GNU General Public License is included in this distribution in
200abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  the file called "COPYING".
210abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  Contact Information:
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  Linux NICS <linux.nics@intel.com>
240abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*******************************************************************************/
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ixgb_hw.c
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Shared functions for accessing and configuring the adapter
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
33d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
34d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ixgb_hw.h"
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ixgb_ids.h"
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
38d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches#include <linux/etherdevice.h>
39d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*  Local function prototypes */
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u32 ixgb_hash_mc_addr(struct ixgb_hw *hw, u8 * mc_addr);
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
44222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic void ixgb_mta_set(struct ixgb_hw *hw, u32 hash_value);
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ixgb_get_bus_info(struct ixgb_hw *hw);
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
48446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool ixgb_link_reset(struct ixgb_hw *hw);
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ixgb_optics_reset(struct ixgb_hw *hw);
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
528b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Workustatic void ixgb_optics_reset_bcm(struct ixgb_hw *hw);
538b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
56e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunkstatic void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
58e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunkstatic void ixgb_clear_vfta(struct ixgb_hw *hw);
59e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunk
60e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunkstatic void ixgb_init_rx_addrs(struct ixgb_hw *hw);
61e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunk
62222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u16 ixgb_read_phy_reg(struct ixgb_hw *hw,
63222441a6201f791238320e77eb4ba9528cd3934cJoe Perches				  u32 reg_address,
64222441a6201f791238320e77eb4ba9528cd3934cJoe Perches				  u32 phy_address,
65222441a6201f791238320e77eb4ba9528cd3934cJoe Perches				  u32 device_type);
66e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunk
67446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool ixgb_setup_fc(struct ixgb_hw *hw);
68e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunk
69222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic bool mac_addr_valid(u8 *mac_addr);
70e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunk
71222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u32 ixgb_mac_reset(struct ixgb_hw *hw)
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
73222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 ctrl_reg;
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl_reg =  IXGB_CTRL0_RST |
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				IXGB_CTRL0_SDP3_DIR |   /* All pins are Output=1 */
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				IXGB_CTRL0_SDP2_DIR |
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				IXGB_CTRL0_SDP1_DIR |
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				IXGB_CTRL0_SDP0_DIR |
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				IXGB_CTRL0_SDP3	 |   /* Initial value 1101   */
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				IXGB_CTRL0_SDP2	 |
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				IXGB_CTRL0_SDP0;
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef HP_ZX1
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Workaround for 82597EX reset errata */
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG_IO(hw, CTRL0, ctrl_reg);
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, CTRL0, ctrl_reg);
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Delay a few ms just to allow the reset to complete */
92f8ec473387f70d103c83ffb3ab50cb2b1380d0c0Jeff Garzik	msleep(IXGB_DELAY_AFTER_RESET);
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl_reg = IXGB_READ_REG(hw, CTRL0);
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef DBG
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Make sure the self-clearing global reset bit did self clear */
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(!(ctrl_reg & IXGB_CTRL0_RST));
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
998b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	if (hw->subsystem_vendor_id == SUN_SUBVENDOR_ID) {
1008b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku		ctrl_reg =  /* Enable interrupt from XFP and SerDes */
1018b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_CTRL1_GPI0_EN |
1028b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_CTRL1_SDP6_DIR |
1038b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_CTRL1_SDP7_DIR |
1048b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_CTRL1_SDP6 |
1058b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_CTRL1_SDP7;
1068b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku		IXGB_WRITE_REG(hw, CTRL1, ctrl_reg);
1078b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku		ixgb_optics_reset_bcm(hw);
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1108b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	if (hw->phy_type == ixgb_phy_type_txn17401)
1118b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku		ixgb_optics_reset(hw);
1128b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ctrl_reg;
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reset the transmit and receive units; mask and clear all interrupts.
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
121446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesbool
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_adapter_stop(struct ixgb_hw *hw)
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
124222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 ctrl_reg;
125222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 icr_reg;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
127d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* If we are stopped or resetting exit gracefully and wait to be
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * started again before accessing the hardware.
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
13203f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (hw->adapter_stopped) {
133d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Exiting because the adapter is already stopped!!!\n");
134446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		return false;
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set the Adapter Stopped flag so other driver functions stop
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * touching the Hardware.
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
140446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	hw->adapter_stopped = true;
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Clear interrupt mask to stop board from generating interrupts */
143d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Masking off all interrupts\n");
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, IMC, 0xFFFFFFFF);
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Disable the Transmit and Receive units.  Then delay to allow
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * any pending transactions to complete before we hit the MAC with
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the global reset.
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, RCTL, IXGB_READ_REG(hw, RCTL) & ~IXGB_RCTL_RXEN);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, TCTL, IXGB_READ_REG(hw, TCTL) & ~IXGB_TCTL_TXEN);
152945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
153f8ec473387f70d103c83ffb3ab50cb2b1380d0c0Jeff Garzik	msleep(IXGB_DELAY_BEFORE_RESET);
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Issue a global reset to the MAC.  This will reset the chip's
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * transmit, receive, DMA, and link units.  It will not effect
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the current PCI configuration.  The global reset bit is self-
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * clearing, and should clear within a microsecond.
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
160d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Issuing a global reset to MAC\n");
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl_reg = ixgb_mac_reset(hw);
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Clear interrupt mask to stop board from generating interrupts */
165d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Masking off all interrupts\n");
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, IMC, 0xffffffff);
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Clear any pending interrupt events. */
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	icr_reg = IXGB_READ_REG(hw, ICR);
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return ctrl_reg & IXGB_CTRL0_RST;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Identifies the vendor of the optics module on the adapter.  The SR adapters
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * support two different types of XPAK optics, so it is necessary to determine
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * which optics are present before applying any optics-specific workarounds.
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code.
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns: the vendor of the XPAK optics module.
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ixgb_xpak_vendor
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_identify_xpak_vendor(struct ixgb_hw *hw)
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
187222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
188222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 vendor_name[5];
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_xpak_vendor xpak_vendor;
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
191d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Read the first few bytes of the vendor string from the XPAK NVR
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * registers.  These are standard XENPAK/XPAK registers, so all XPAK
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * devices should implement them. */
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < 5; i++) {
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		vendor_name[i] = ixgb_read_phy_reg(hw,
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						   MDIO_PMA_PMD_XPAK_VENDOR_NAME
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						   + i, IXGB_PHY_ADDRESS,
200cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings						   MDIO_MMD_PMAPMD);
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Determine the actual vendor */
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (vendor_name[0] == 'I' &&
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    vendor_name[1] == 'N' &&
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    vendor_name[2] == 'T' &&
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    vendor_name[3] == 'E' && vendor_name[4] == 'L') {
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xpak_vendor = ixgb_xpak_vendor_intel;
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xpak_vendor = ixgb_xpak_vendor_infineon;
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
213807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return xpak_vendor;
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Determine the physical layer module on the adapter.
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code.  The device_id
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      field must be (correctly) populated before calling this routine.
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns: the phy type of the adapter.
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ixgb_phy_type
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_identify_phy(struct ixgb_hw *hw)
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_phy_type phy_type;
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_xpak_vendor xpak_vendor;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
230d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Infer the transceiver/phy type from the device id */
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (hw->device_id) {
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IXGB_DEVICE_ID_82597EX:
235d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Identified TXN17401 optics\n");
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		phy_type = ixgb_phy_type_txn17401;
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IXGB_DEVICE_ID_82597EX_SR:
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* The SR adapters carry two different types of XPAK optics
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * modules; read the vendor identifier to determine the exact
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * type of optics. */
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		xpak_vendor = ixgb_identify_xpak_vendor(hw);
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (xpak_vendor == ixgb_xpak_vendor_intel) {
245d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			pr_debug("Identified TXN17201 optics\n");
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			phy_type = ixgb_phy_type_txn17201;
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
248d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			pr_debug("Identified G6005 optics\n");
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			phy_type = ixgb_phy_type_g6005;
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case IXGB_DEVICE_ID_82597EX_LR:
253d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Identified G6104 optics\n");
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		phy_type = ixgb_phy_type_g6104;
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2560fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval	case IXGB_DEVICE_ID_82597EX_CX4:
257d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Identified CX4\n");
2580fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval		xpak_vendor = ixgb_identify_xpak_vendor(hw);
2590fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval		if (xpak_vendor == ixgb_xpak_vendor_intel) {
260d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			pr_debug("Identified TXN17201 optics\n");
2610fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval			phy_type = ixgb_phy_type_txn17201;
2620fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval		} else {
263d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			pr_debug("Identified G6005 optics\n");
2640fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval			phy_type = ixgb_phy_type_g6005;
2650fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval		}
2660fe198a5e10229b269624a18bbd390001a8d3476Manasi Deval		break;
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
268d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Unknown physical layer module\n");
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		phy_type = ixgb_phy_type_unknown;
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2738b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	/* update phy type for sun specific board */
2748b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	if (hw->subsystem_vendor_id == SUN_SUBVENDOR_ID)
2758b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku		phy_type = ixgb_phy_type_bcm;
2768b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
277807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return phy_type;
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Performs basic configuration of the adapter.
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Resets the controller.
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reads and validates the EEPROM.
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initializes the receive address registers.
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initializes the multicast table.
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Clears all on-chip counters.
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Calls routine to setup flow control settings.
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Leaves the transmit and receive units disabled and uninitialized.
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
294446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      true if successful,
295446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      false if unrecoverable problems were encountered.
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
297446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesbool
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_init_hw(struct ixgb_hw *hw)
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
300222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
301222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 ctrl_reg;
302446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	bool status;
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
304d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Issue a global reset to the MAC.  This will reset the chip's
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * transmit, receive, DMA, and link units.  It will not effect
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the current PCI configuration.  The global reset bit is self-
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * clearing, and should clear within a microsecond.
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
311d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Issuing a global reset to MAC\n");
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl_reg = ixgb_mac_reset(hw);
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
315d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Issuing an EE reset to MAC\n");
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef HP_ZX1
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Workaround for 82597EX reset errata */
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG_IO(hw, CTRL1, IXGB_CTRL1_EE_RST);
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, CTRL1, IXGB_CTRL1_EE_RST);
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Delay a few ms just to allow the reset to complete */
324f8ec473387f70d103c83ffb3ab50cb2b1380d0c0Jeff Garzik	msleep(IXGB_DELAY_AFTER_EE_RESET);
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
326446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	if (!ixgb_get_eeprom_data(hw))
327446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		return false;
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Use the device id to determine the type of phy/transceiver. */
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hw->device_id = ixgb_get_ee_device_id(hw);
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hw->phy_type = ixgb_identify_phy(hw);
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Setup the receive addresses.
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Receive Address Registers (RARs 0 - 15).
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_init_rx_addrs(hw);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Check that a valid MAC address has been set.
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If it is not valid, we fail hardware init.
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mac_addr_valid(hw->curr_mac_addr)) {
343d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("MAC address invalid after ixgb_init_rx_addrs\n");
344446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		return(false);
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* tell the routines in this file they can access hardware again */
348446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	hw->adapter_stopped = false;
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Fill in the bus_info structure */
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_get_bus_info(hw);
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Zero out the Multicast HASH table */
354d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Zeroing the MTA\n");
3551459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Zero out the VLAN Filter Table Array */
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_clear_vfta(hw);
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Zero all of the hardware counters */
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_clear_hw_cntrs(hw);
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Call a subroutine to setup flow control. */
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status = ixgb_setup_fc(hw);
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* 82597EX errata: Call check-for-link in case lane deskew is locked */
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_check_for_link(hw);
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
370807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return status;
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initializes receive address filters.
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Places the MAC address in receive address register 0 and clears the rest
37952035bdbe8229c6bffae0be3444924ffbccf6506Jesse Brandeburg * of the receive address registers. Clears the multicast table. Assumes
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the receiver is in reset when the routine is called.
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
382e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunkstatic void
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_init_rx_addrs(struct ixgb_hw *hw)
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
385222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
387d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If the current mac address is valid, assume it is a software override
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * to the permanent address.
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Otherwise, use the permanent address from the eeprom.
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mac_addr_valid(hw->curr_mac_addr)) {
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Get the MAC address from the eeprom for later reference */
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_get_ee_mac_addr(hw, hw->curr_mac_addr);
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
399d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Keeping Permanent MAC Addr = %pM\n",
400d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			 hw->curr_mac_addr);
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Setup the receive address. */
404d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Overriding MAC Address in RAR[0]\n");
405d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("New MAC Addr = %pM\n", hw->curr_mac_addr);
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_rar_set(hw, hw->curr_mac_addr, 0);
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Zero out the other 15 receive addresses. */
411d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Clearing RAR[1-15]\n");
4121459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 1; i < IXGB_RAR_ENTRIES; i++) {
413a3ffab87588234e41248d8cebd8cec88db605d3cAaron Salter		/* Write high reg first to disable the AV bit first */
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
415a3ffab87588234e41248d8cebd8cec88db605d3cAaron Salter		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Updates the MAC's list of multicast addresses.
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mc_addr_list - the list of new multicast addresses
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mc_addr_count - number of addresses
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pad - number of bytes between addresses in the list
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The given list replaces any existing list. Clears the last 15 receive
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * address registers and the multicast table. Uses receive address registers
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for the first 15 multicast addresses, and hashes the rest into the
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * multicast table.
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_mc_addr_list_update(struct ixgb_hw *hw,
434222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			  u8 *mc_addr_list,
435222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			  u32 mc_addr_count,
436222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			  u32 pad)
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
438222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 hash_value;
439222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
440222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 rar_used_count = 1;		/* RAR[0] is used for our MAC address */
441d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	u8 *mca;
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
443d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set the new number of MC addresses that we are being requested to use. */
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hw->num_mc_addrs = mc_addr_count;
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Clear RAR[1-15] */
449d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Clearing RAR[1-15]\n");
4501459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Clear the MTA */
456d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Clearing MTA\n");
4571459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Add the new addresses */
461d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	mca = mc_addr_list;
4621459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < mc_addr_count; i++) {
463d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Adding the multicast addresses:\n");
464d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("MC Addr #%d = %pM\n", i, mca);
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Place this multicast address in the RAR if there is room, *
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * else put it in the MTA
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
46903f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if (rar_used_count < IXGB_RAR_ENTRIES) {
470d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			ixgb_rar_set(hw, mca, rar_used_count);
471d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			pr_debug("Added a multicast address to RAR[%d]\n", i);
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			rar_used_count++;
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
474d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			hash_value = ixgb_hash_mc_addr(hw, mca);
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
476d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			pr_debug("Hash value = 0x%03X\n", hash_value);
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ixgb_mta_set(hw, hash_value);
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
480d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches
481ac5ac789ebcf5b27e9edc231f6d33c92d722c607Jesse Brandeburg		mca += ETH_ALEN + pad;
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
484d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("MC Update Complete\n");
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Hashes an address to determine its location in the multicast table
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mc_addr - the multicast address to hash
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *      The hash value
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
496222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u32
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_hash_mc_addr(struct ixgb_hw *hw,
498222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		   u8 *mc_addr)
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
500222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 hash_value = 0;
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
502d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* The portion of the address that is used for the hash table is
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * determined by the mc_filter_type setting.
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (hw->mc_filter_type) {
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* [0] [1] [2] [3] [4] [5]
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * 01  AA  00  12  34  56
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * LSB                 MSB - According to H/W docs */
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 0:
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* [47:36] i.e. 0x563 for above example address */
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hash_value =
514222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		    ((mc_addr[4] >> 4) | (((u16) mc_addr[5]) << 4));
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 1:		/* [46:35] i.e. 0xAC6 for above example address */
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hash_value =
518222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		    ((mc_addr[4] >> 3) | (((u16) mc_addr[5]) << 5));
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 2:		/* [45:34] i.e. 0x5D8 for above example address */
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hash_value =
522222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		    ((mc_addr[4] >> 2) | (((u16) mc_addr[5]) << 6));
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case 3:		/* [43:32] i.e. 0x634 for above example address */
525222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		hash_value = ((mc_addr[4]) | (((u16) mc_addr[5]) << 8));
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Invalid mc_filter_type, what should we do? */
529d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("MC filter type param set incorrectly\n");
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ASSERT(0);
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hash_value &= 0xFFF;
535807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return hash_value;
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sets the bit in the multicast table corresponding to the hash value.
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hash_value - Multicast address hash value
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_mta_set(struct ixgb_hw *hw,
546222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  u32 hash_value)
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
548222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 hash_bit, hash_reg;
549222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 mta_reg;
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* The MTA is a register array of 128 32-bit registers.
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * It is treated like an array of 4096 bits.  We want to set
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * bit BitArray[hash_value]. So we figure out what register
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the bit is in, read it, OR in the new bit, then write
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * back the new value.  The register is determined by the
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * upper 7 bits of the hash value and the bit within that
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * register are determined by the lower 5 bits of the value.
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hash_reg = (hash_value >> 5) & 0x7F;
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hash_bit = hash_value & 0x1F;
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mta_reg = IXGB_READ_REG_ARRAY(hw, MTA, hash_reg);
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mta_reg |= (1 << hash_bit);
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta_reg);
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Puts an ethernet address into a receive address register.
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * addr - Address to put into receive address register
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * index - Receive address register to write
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_rar_set(struct ixgb_hw *hw,
578222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  u8 *addr,
579222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  u32 index)
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
581222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 rar_low, rar_high;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
583d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* HW expects these in little endian so we reverse the byte order
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * from network order (big endian) to little endian
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
588222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	rar_low = ((u32) addr[0] |
589222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		   ((u32)addr[1] << 8) |
590222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		   ((u32)addr[2] << 16) |
591222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		   ((u32)addr[3] << 24));
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
593222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	rar_high = ((u32) addr[4] |
594222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			((u32)addr[5] << 8) |
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			IXGB_RAH_AV);
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Writes a value to the specified offset in the VLAN filter table.
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * offset - Offset in VLAN filer table to write
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * value - Value to write into VLAN filter table
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_write_vfta(struct ixgb_hw *hw,
610222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		 u32 offset,
611222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		 u32 value)
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value);
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Clears the VLAN filer table
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
621e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunkstatic void
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_clear_vfta(struct ixgb_hw *hw)
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
624222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 offset;
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6261459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Configures the flow control settings based on SW configuration.
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
636446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_setup_fc(struct ixgb_hw *hw)
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
639222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 ctrl_reg;
640222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 pap_reg = 0;   /* by default, assume no pause time */
641446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	bool status = true;
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
643d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Get the current control reg 0 settings */
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl_reg = IXGB_READ_REG(hw, CTRL0);
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Clear the Receive Pause Enable and Transmit Pause Enable bits */
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl_reg &= ~(IXGB_CTRL0_RPE | IXGB_CTRL0_TPE);
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* The possible values of the "flow_control" parameter are:
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *      0:  Flow control is completely disabled
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *      1:  Rx flow control is enabled (we can receive pause frames
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *          but not send pause frames).
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *      2:  Tx flow control is enabled (we can send pause frames
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *          but we do not support receiving pause frames).
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  other:  Invalid.
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (hw->fc.type) {
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ixgb_fc_none:	/* 0 */
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Set CMDC bit to disable Rx Flow control */
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ctrl_reg |= (IXGB_CTRL0_CMDC);
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ixgb_fc_rx_pause:	/* 1 */
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* RX Flow control is enabled, and TX Flow control is
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * disabled.
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ctrl_reg |= (IXGB_CTRL0_RPE);
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ixgb_fc_tx_pause:	/* 2 */
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* TX Flow control is enabled, and RX Flow control is
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * disabled, by a software over-ride.
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ctrl_reg |= (IXGB_CTRL0_TPE);
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pap_reg = hw->fc.pause_time;
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ixgb_fc_full:	/* 3 */
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Flow control (both RX and TX) is enabled by a software
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * over-ride.
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ctrl_reg |= (IXGB_CTRL0_RPE | IXGB_CTRL0_TPE);
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pap_reg = hw->fc.pause_time;
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* We should never get here.  The value should be 0-3. */
687d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Flow control param set incorrectly\n");
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ASSERT(0);
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Write the new settings */
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, CTRL0, ctrl_reg);
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
69503f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (pap_reg != 0)
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG(hw, PAP, pap_reg);
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set the flow control receive threshold registers.  Normally,
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * these registers will be set to a default threshold that may be
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * adjusted later by the driver's runtime code.  However, if the
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * ability to transmit pause frames in not enabled, then these
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * registers will be set to 0.
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
70403f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (!(hw->fc.type & ixgb_fc_tx_pause)) {
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG(hw, FCRTL, 0);
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG(hw, FCRTH, 0);
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   /* We need to set up the Receive Threshold high and low water
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    * marks as well as (optionally) enabling the transmission of XON
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    * frames. */
71103f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if (hw->fc.send_xon) {
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			IXGB_WRITE_REG(hw, FCRTL,
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				(hw->fc.low_water | IXGB_FCRTL_XONE));
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			IXGB_WRITE_REG(hw, FCRTL, hw->fc.low_water);
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG(hw, FCRTH, hw->fc.high_water);
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
719807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return status;
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reads a word from a device over the Management Data Interface (MDI) bus.
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This interface is used to manage Physical layer devices.
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw          - Struct containing variables accessed by hw code
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * reg_address - Offset of device register being read.
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * phy_address - Address of device on MDI.
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:  Data word (16 bits) from MDI device.
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The 82597EX has support for several MDI access methods.  This routine
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * uses the new protocol MDI Single Command and Address Operation.
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This requires that first an address cycle command is sent, followed by a
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * read command.
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
737222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u16
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_read_phy_reg(struct ixgb_hw *hw,
739222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		u32 reg_address,
740222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		u32 phy_address,
741222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		u32 device_type)
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
743222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
744222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 data;
745222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 command = 0;
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS);
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS);
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Setup and write the address cycle command */
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, MSCA, command);
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    /**************************************************************
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** Check every 10 usec to see if the address cycle completed
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** The COMMAND bit will clear when the operation is complete.
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** This may take as long as 64 usecs (we'll wait 100 usecs max)
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** from the CPU Write to the Ready bit assertion.
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    **************************************************************/
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7661459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < 10; i++)
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(10);
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		command = IXGB_READ_REG(hw, MSCA);
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((command & IXGB_MSCA_MDI_COMMAND) == 0)
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Address cycle complete, setup and write the read command */
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (IXGB_MSCA_READ | IXGB_MSCA_MDI_COMMAND));
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, MSCA, command);
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    /**************************************************************
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** Check every 10 usec to see if the read command completed
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** The COMMAND bit will clear when the operation is complete.
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** The read may take as long as 64 usecs (we'll wait 100 usecs max)
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ** from the CPU Write to the Ready bit assertion.
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    **************************************************************/
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7931459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < 10; i++)
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(10);
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		command = IXGB_READ_REG(hw, MSCA);
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((command & IXGB_MSCA_MDI_COMMAND) == 0)
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Operation is complete, get the data from the MDIO Read/Write Data
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * register and return.
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data = IXGB_READ_REG(hw, MSRWD);
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data >>= IXGB_MSRWD_READ_DATA_SHIFT;
810222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	return((u16) data);
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Writes a word to a device over the Management Data Interface (MDI) bus.
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This interface is used to manage Physical layer devices.
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw          - Struct containing variables accessed by hw code
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * reg_address - Offset of device register being read.
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * phy_address - Address of device on MDI.
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * device_type - Also known as the Device ID or DID.
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data        - 16-bit value to be written
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:  void.
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The 82597EX has support for several MDI access methods.  This routine
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * uses the new protocol MDI Single Command and Address Operation.
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This requires that first an address cycle command is sent, followed by a
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * write command.
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
830e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunkstatic void
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_write_phy_reg(struct ixgb_hw *hw,
832222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			u32 reg_address,
833222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			u32 phy_address,
834222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			u32 device_type,
835222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			u16 data)
8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
837222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
838222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 command = 0;
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(reg_address <= IXGB_MAX_PHY_REG_ADDRESS);
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(phy_address <= IXGB_MAX_PHY_ADDRESS);
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Put the data in the MDIO Read/Write Data register */
845222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	IXGB_WRITE_REG(hw, MSRWD, (u32)data);
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Setup and write the address cycle command */
8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, MSCA, command);
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/**************************************************************
8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** Check every 10 usec to see if the address cycle completed
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** The COMMAND bit will clear when the operation is complete.
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** This may take as long as 64 usecs (we'll wait 100 usecs max)
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** from the CPU Write to the Ready bit assertion.
8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	**************************************************************/
8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8621459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < 10; i++)
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(10);
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		command = IXGB_READ_REG(hw, MSCA);
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((command & IXGB_MSCA_MDI_COMMAND) == 0)
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Address cycle complete, setup and write the write command */
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, MSCA, command);
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/**************************************************************
8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** Check every 10 usec to see if the read command completed
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** The COMMAND bit will clear when the operation is complete.
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** The write may take as long as 64 usecs (we'll wait 100 usecs max)
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	** from the CPU Write to the Ready bit assertion.
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	**************************************************************/
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8891459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < 10; i++)
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(10);
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		command = IXGB_READ_REG(hw, MSCA);
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((command & IXGB_MSCA_MDI_COMMAND) == 0)
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Operation is complete, return. */
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Checks to see if the link status of the hardware has changed.
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by hw code
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Called by any function that needs to check the link status of the adapter.
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_check_for_link(struct ixgb_hw *hw)
9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
914222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 status_reg;
915222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 xpcss_reg;
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
917d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	xpcss_reg = IXGB_READ_REG(hw, XPCSS);
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status_reg = IXGB_READ_REG(hw, STATUS);
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((xpcss_reg & IXGB_XPCSS_ALIGN_STATUS) &&
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    (status_reg & IXGB_STATUS_LU)) {
924446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		hw->link_up = true;
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else if (!(xpcss_reg & IXGB_XPCSS_ALIGN_STATUS) &&
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   (status_reg & IXGB_STATUS_LU)) {
927d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("XPCSS Not Aligned while Status:LU is set\n");
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->link_up = ixgb_link_reset(hw);
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * 82597EX errata.  Since the lane deskew problem may prevent
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * link, reset the link before reporting link down.
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->link_up = ixgb_link_reset(hw);
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Anything else for 10 Gig?? */
9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
94052035bdbe8229c6bffae0be3444924ffbccf6506Jesse Brandeburg * Check for a bad link condition that may have occurred.
9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The indication is that the RFC / LFC registers may be incrementing
9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * continually.  A full adapter reset is required to recover.
9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by hw code
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Called by any function that needs to check the link status of the adapter.
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
948446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesbool ixgb_check_for_bad_link(struct ixgb_hw *hw)
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
950222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 newLFC, newRFC;
951446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	bool bad_link_returncode = false;
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (hw->phy_type == ixgb_phy_type_txn17401) {
9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		newLFC = IXGB_READ_REG(hw, LFC);
9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		newRFC = IXGB_READ_REG(hw, RFC);
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((hw->lastLFC + 250 < newLFC)
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    || (hw->lastRFC + 250 < newRFC)) {
958d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches			pr_debug("BAD LINK! too many LFC/RFC since last check\n");
959446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches			bad_link_returncode = true;
9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->lastLFC = newLFC;
9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->lastRFC = newRFC;
9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return bad_link_returncode;
9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Clears all hardware statistics counters.
9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
973e9ab1d145365a871858f402f3655cd4939fa38d5Adrian Bunkstatic void
9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_clear_hw_cntrs(struct ixgb_hw *hw)
9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
976222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	volatile u32 temp_reg;
9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
978d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* if we are stopped or resetting exit gracefully */
98103f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (hw->adapter_stopped) {
982d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Exiting because the adapter is stopped!!!\n");
9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TPRL);
9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TPRH);
9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GPRCL);
9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GPRCH);
9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, BPRCL);
9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, BPRCH);
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, MPRCL);
9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, MPRCH);
9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, UPRCL);
9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, UPRCH);
9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, VPRCL);
9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, VPRCH);
9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, JPRCL);
9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, JPRCH);
10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GORCL);
10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GORCH);
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TORL);
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TORH);
10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, RNBC);
10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, RUC);
10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, ROC);
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, RLEC);
10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, CRCERRS);
10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, ICBC);
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, ECBC);
10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, MPC);
10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TPTL);
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TPTH);
10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GPTCL);
10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GPTCH);
10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, BPTCL);
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, BPTCH);
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, MPTCL);
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, MPTCH);
10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, UPTCL);
10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, UPTCH);
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, VPTCL);
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, VPTCH);
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, JPTCL);
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, JPTCH);
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GOTCL);
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, GOTCH);
10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TOTL);
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TOTH);
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, DC);
10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, PLT64C);
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TSCTC);
10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, TSCTFC);
10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, IBIC);
10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, RFC);
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, LFC);
10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, PFRC);
10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, PFTC);
10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, MCFRC);
10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, MCFTC);
10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, XONRXC);
10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, XONTXC);
10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, XOFFRXC);
10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, XOFFTXC);
10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	temp_reg = IXGB_READ_REG(hw, RJC);
10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Turns on the software controllable LED
10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_led_on(struct ixgb_hw *hw)
10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1056222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* To turn on the LED, clear software-definable pin 0 (SDP0). */
10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl0_reg &= ~IXGB_CTRL0_SDP0;
10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, CTRL0, ctrl0_reg);
10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Turns off the software controllable LED
10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_led_off(struct ixgb_hw *hw)
10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1071222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* To turn off the LED, set software-definable pin 0 (SDP0). */
10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ctrl0_reg |= IXGB_CTRL0_SDP0;
10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, CTRL0, ctrl0_reg);
10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Gets the current PCI bus type, speed, and width of the hardware
10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_bus_info(struct ixgb_hw *hw)
10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1086222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 status_reg;
10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status_reg = IXGB_READ_REG(hw, STATUS);
10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hw->bus.type = (status_reg & IXGB_STATUS_PCIX_MODE) ?
10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_bus_type_pcix : ixgb_bus_type_pci;
10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (hw->bus.type == ixgb_bus_type_pci) {
10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->bus.speed = (status_reg & IXGB_STATUS_PCI_SPD) ?
10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ixgb_bus_speed_66 : ixgb_bus_speed_33;
10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		switch (status_reg & IXGB_STATUS_PCIX_SPD_MASK) {
10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case IXGB_STATUS_PCIX_SPD_66:
10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hw->bus.speed = ixgb_bus_speed_66;
11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case IXGB_STATUS_PCIX_SPD_100:
11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hw->bus.speed = ixgb_bus_speed_100;
11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		case IXGB_STATUS_PCIX_SPD_133:
11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hw->bus.speed = ixgb_bus_speed_133;
11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		default:
11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			hw->bus.speed = ixgb_bus_speed_reserved;
11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hw->bus.width = (status_reg & IXGB_STATUS_BUS64) ?
11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_bus_width_64 : ixgb_bus_width_32;
11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Tests a MAC address to ensure it is a valid Individual Address
11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mac_addr - pointer to MAC address.
11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
1123446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool
1124222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesmac_addr_valid(u8 *mac_addr)
11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1126446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	bool is_valid = true;
1127d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Make sure it is not a multicast address */
1130d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	if (is_multicast_ether_addr(mac_addr)) {
1131d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("MAC address is multicast\n");
1132446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		is_valid = false;
11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Not a broadcast address */
1135d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	else if (is_broadcast_ether_addr(mac_addr)) {
1136d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("MAC address is broadcast\n");
1137446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		is_valid = false;
11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Reject the zero address */
1140d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	else if (is_zero_ether_addr(mac_addr)) {
1141d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("MAC address is all zeros\n");
1142446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		is_valid = false;
11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1144807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return is_valid;
11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Resets the 10GbE link.  Waits the settle time and returns the state of
11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the link.
11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
1153446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool
11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_link_reset(struct ixgb_hw *hw)
11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1156446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches	bool link_status = false;
1157222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u8 wait_retries = MAX_RESET_ITERATIONS;
1158222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u8 lrst_retries = MAX_RESET_ITERATIONS;
11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Reset the link */
11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG(hw, CTRL0,
11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       IXGB_READ_REG(hw, CTRL0) | IXGB_CTRL0_LRST);
11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Wait for link-up and lane re-alignment */
11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		do {
11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			udelay(IXGB_DELAY_USECS_AFTER_LINK_RESET);
11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			link_status =
11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    ((IXGB_READ_REG(hw, STATUS) & IXGB_STATUS_LU)
11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     && (IXGB_READ_REG(hw, XPCSS) &
1171446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches				 IXGB_XPCSS_ALIGN_STATUS)) ? true : false;
11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} while (!link_status && --wait_retries);
11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (!link_status && --lrst_retries);
11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return link_status;
11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Resets the 10GbE optics module.
11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
1184273dc74e1c7d9aa2eab2036153c8fe65593fb85eStephen Hemmingerstatic void
11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_optics_reset(struct ixgb_hw *hw)
11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (hw->phy_type == ixgb_phy_type_txn17401) {
1188222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		u16 mdio_reg;
11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_write_phy_reg(hw,
1191cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings				   MDIO_CTRL1,
1192cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings				   IXGB_PHY_ADDRESS,
1193cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings				   MDIO_MMD_PMAPMD,
1194cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings				   MDIO_CTRL1_RESET);
1195cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings
1196cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings		mdio_reg = ixgb_read_phy_reg(hw,
1197cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings					     MDIO_CTRL1,
1198cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings					     IXGB_PHY_ADDRESS,
1199cdbf0eb478dd4c76aa665c80976837dc58367f52Ben Hutchings					     MDIO_MMD_PMAPMD);
12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
12028b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
12038b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku/******************************************************************************
12048b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku * Resets the 10GbE optics module for Sun variant NIC.
12058b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku *
12068b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku * hw - Struct containing variables accessed by shared code
12078b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku *****************************************************************************/
12088b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
12098b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku#define   IXGB_BCM8704_USER_PMD_TX_CTRL_REG         0xC803
12108b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku#define   IXGB_BCM8704_USER_PMD_TX_CTRL_REG_VAL     0x0164
12118b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku#define   IXGB_BCM8704_USER_CTRL_REG                0xC800
12128b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku#define   IXGB_BCM8704_USER_CTRL_REG_VAL            0x7FBF
12138b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku#define   IXGB_BCM8704_USER_DEV3_ADDR               0x0003
12148b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku#define   IXGB_SUN_PHY_ADDRESS                      0x0000
12158b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku#define   IXGB_SUN_PHY_RESET_DELAY                     305
12168b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
12178b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Workustatic void
12188b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Workuixgb_optics_reset_bcm(struct ixgb_hw *hw)
12198b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku{
12208b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	u32 ctrl = IXGB_READ_REG(hw, CTRL0);
12218b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ctrl &= ~IXGB_CTRL0_SDP2;
12228b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ctrl |= IXGB_CTRL0_SDP3;
12238b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	IXGB_WRITE_REG(hw, CTRL0, ctrl);
1224945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
12258b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
12268b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	/* SerDes needs extra delay */
12278b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	msleep(IXGB_SUN_PHY_RESET_DELAY);
12288b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
12298b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	/* Broadcom 7408L configuration */
12308b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	/* Reference clock config */
12318b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ixgb_write_phy_reg(hw,
12328b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_BCM8704_USER_PMD_TX_CTRL_REG,
12338b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_SUN_PHY_ADDRESS,
12348b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_BCM8704_USER_DEV3_ADDR,
12358b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_BCM8704_USER_PMD_TX_CTRL_REG_VAL);
12368b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	/*  we must read the registers twice */
12378b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ixgb_read_phy_reg(hw,
12388b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_PMD_TX_CTRL_REG,
12398b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_SUN_PHY_ADDRESS,
12408b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_DEV3_ADDR);
12418b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ixgb_read_phy_reg(hw,
12428b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_PMD_TX_CTRL_REG,
12438b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_SUN_PHY_ADDRESS,
12448b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_DEV3_ADDR);
12458b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
12468b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ixgb_write_phy_reg(hw,
12478b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_BCM8704_USER_CTRL_REG,
12488b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_SUN_PHY_ADDRESS,
12498b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_BCM8704_USER_DEV3_ADDR,
12508b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			   IXGB_BCM8704_USER_CTRL_REG_VAL);
12518b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ixgb_read_phy_reg(hw,
12528b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_CTRL_REG,
12538b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_SUN_PHY_ADDRESS,
12548b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_DEV3_ADDR);
12558b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	ixgb_read_phy_reg(hw,
12568b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_CTRL_REG,
12578b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_SUN_PHY_ADDRESS,
12588b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku			  IXGB_BCM8704_USER_DEV3_ADDR);
12598b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku
12608b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	/* SerDes needs extra delay */
12618b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku	msleep(IXGB_SUN_PHY_RESET_DELAY);
12628b32e63d48d43f3843222ca66fecd45ff2a74147Matheos Worku}
1263