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
29d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ixgb_hw.h"
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ixgb_ee.h"
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Local prototypes */
34222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u16 ixgb_shift_in_bits(struct ixgb_hw *hw);
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ixgb_shift_out_bits(struct ixgb_hw *hw,
37222441a6201f791238320e77eb4ba9528cd3934cJoe Perches				u16 data,
38222441a6201f791238320e77eb4ba9528cd3934cJoe Perches				u16 count);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ixgb_standby_eeprom(struct ixgb_hw *hw);
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool ixgb_wait_eeprom_command(struct ixgb_hw *hw);
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ixgb_cleanup_eeprom(struct ixgb_hw *hw);
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Raises the EEPROM's clock input.
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * eecd_reg - EECD's current value
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_raise_clock(struct ixgb_hw *hw,
53222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  u32 *eecd_reg)
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  wait 50 microseconds.
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*eecd_reg = *eecd_reg | IXGB_EECD_SK;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, *eecd_reg);
60945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Lowers the EEPROM's clock input.
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * eecd_reg - EECD's current value
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_lower_clock(struct ixgb_hw *hw,
72222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  u32 *eecd_reg)
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * wait 50 microseconds.
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*eecd_reg = *eecd_reg & ~IXGB_EECD_SK;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, *eecd_reg);
79945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Shift data bits out to the EEPROM.
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data - data to send to the EEPROM
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * count - number of bits to shift out
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_shift_out_bits(struct ixgb_hw *hw,
92222441a6201f791238320e77eb4ba9528cd3934cJoe Perches					 u16 data,
93222441a6201f791238320e77eb4ba9528cd3934cJoe Perches					 u16 count)
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
95222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 eecd_reg;
96222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 mask;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* We need to shift "count" bits out to the EEPROM. So, value in the
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * "data" parameter will be shifted out to the EEPROM one bit at a time.
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * In order to do this, "data" must be broken down into bits.
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mask = 0x01 << (count - 1);
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg = IXGB_READ_REG(hw, EECD);
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * and then raising and then lowering the clock (the SK bit controls
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * by setting "DI" to "0" and then raising and then lowering the clock.
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eecd_reg &= ~IXGB_EECD_DI;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11303f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if (data & mask)
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			eecd_reg |= IXGB_EECD_DI;
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IXGB_WRITE_REG(hw, EECD, eecd_reg);
117945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg		IXGB_WRITE_FLUSH(hw);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(50);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_raise_clock(hw, &eecd_reg);
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_lower_clock(hw, &eecd_reg);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mask = mask >> 1;
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1269a432992870b4a528bf36dd0327a45c23ddb6f94Jesse Brandeburg	} while (mask);
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* We leave the "DI" bit set to "0" when we leave this routine. */
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~IXGB_EECD_DI;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Shift data bits in from the EEPROM
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
138222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u16
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_shift_in_bits(struct ixgb_hw *hw)
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
141222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 eecd_reg;
142222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
143222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 data;
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* In order to read a register from the EEPROM, we need to shift 16 bits
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * in from the EEPROM. Bits are "shifted in" by raising the clock input to
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the EEPROM (setting the SK bit), and then reading the value of the "DO"
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * bit.  During this "shifting in" process the "DI" bit should always be
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * clear..
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg = IXGB_READ_REG(hw, EECD);
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data = 0;
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < 16; i++) {
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data = data << 1;
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_raise_clock(hw, &eecd_reg);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eecd_reg = IXGB_READ_REG(hw, EECD);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eecd_reg &= ~(IXGB_EECD_DI);
16403f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if (eecd_reg & IXGB_EECD_DO)
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			data |= 1;
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_lower_clock(hw, &eecd_reg);
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return data;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Prepares EEPROM for access
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function should be called before issuing a command to the EEPROM.
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_setup_eeprom(struct ixgb_hw *hw)
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
184222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 eecd_reg;
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg = IXGB_READ_REG(hw, EECD);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Clear SK and DI  */
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~(IXGB_EECD_SK | IXGB_EECD_DI);
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Set CS  */
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg |= IXGB_EECD_CS;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns EEPROM to a "standby" state
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_standby_eeprom(struct ixgb_hw *hw)
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
205222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 eecd_reg;
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg = IXGB_READ_REG(hw, EECD);
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20952035bdbe8229c6bffae0be3444924ffbccf6506Jesse Brandeburg	/*  Deselect EEPROM  */
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
212945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Clock high  */
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg |= IXGB_EECD_SK;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
218945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Select EEPROM  */
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg |= IXGB_EECD_CS;
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
224945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Clock low  */
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~IXGB_EECD_SK;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
230945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Raises then lowers the EEPROM's clock pin
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_clock_eeprom(struct ixgb_hw *hw)
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
242222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 eecd_reg;
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg = IXGB_READ_REG(hw, EECD);
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Rising edge of clock  */
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg |= IXGB_EECD_SK;
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
249945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Falling edge of clock  */
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~IXGB_EECD_SK;
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
255945a51517cc0bd9e461f2018624dfc1faef9ddeeJesse Brandeburg	IXGB_WRITE_FLUSH(hw);
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	udelay(50);
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Terminates a command by lowering the EEPROM's chip select pin
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_cleanup_eeprom(struct ixgb_hw *hw)
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
267222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 eecd_reg;
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg = IXGB_READ_REG(hw, EECD);
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_DI);
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IXGB_WRITE_REG(hw, EECD, eecd_reg);
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_clock_eeprom(hw);
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Waits for the EEPROM to finish the current command.
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The command is done when the EEPROM's data out pin goes high.
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
286446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      true: EEPROM data pin is high before timeout.
287446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      false:  Time expired.
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
289446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_wait_eeprom_command(struct ixgb_hw *hw)
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
292222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 eecd_reg;
293222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 i;
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Toggle the CS line.  This in effect tells to EEPROM to actually execute
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * the command in question.
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_standby_eeprom(hw);
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
30052035bdbe8229c6bffae0be3444924ffbccf6506Jesse Brandeburg	/* Now read DO repeatedly until is high (equal to '1').  The EEPROM will
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * signal that the command has been completed by raising the DO signal.
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * If DO does not go high in 10 milliseconds, then error out.
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3041459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < 200; i++) {
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eecd_reg = IXGB_READ_REG(hw, EECD);
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
30703f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if (eecd_reg & IXGB_EECD_DO)
308807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet			return true;
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udelay(50);
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ASSERT(0);
313807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return false;
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Verifies that the EEPROM has a valid checksum
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reads the first 64 16 bit words of the EEPROM and sums the values read.
32259c51591a0ac7568824f541f57de967e88adaa07Michael Opdenacker * If the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * valid.
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
326446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *  true: Checksum is valid
327446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *  false: Checksum is not valid.
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
329446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesbool
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
332222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 checksum = 0;
333222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 i;
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3351459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		checksum += ixgb_read_eeprom(hw, i);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
33803f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (checksum == (u16) EEPROM_SUM)
339807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return true;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
341807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return false;
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Calculates the EEPROM checksum and writes it to the EEPROM
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Writes the difference to word offset 63 of the EEPROM.
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_update_eeprom_checksum(struct ixgb_hw *hw)
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
355222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 checksum = 0;
356222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 i;
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3581459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		checksum += ixgb_read_eeprom(hw, i);
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	checksum = (u16) EEPROM_SUM - checksum;
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum);
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Writes a 16 bit word to a given offset in the EEPROM.
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * reg - offset within the EEPROM to be written to
37152035bdbe8229c6bffae0be3444924ffbccf6506Jesse Brandeburg * data - 16 bit word to be written to the EEPROM
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If ixgb_update_eeprom_checksum is not called after this function, the
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * EEPROM will most likely contain an invalid checksum.
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
378222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesixgb_write_eeprom(struct ixgb_hw *hw, u16 offset, u16 data)
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Prepare the EEPROM for writing */
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_setup_eeprom(hw);
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Send the 9-bit EWEN (write enable) command to the EEPROM (5-bit opcode
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *  plus 4-bit dummy).  This puts the EEPROM into write/erase mode.
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, EEPROM_EWEN_OPCODE, 5);
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, 0, 4);
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Prepare the EEPROM  */
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_standby_eeprom(hw);
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Send the Write command (3-bit opcode + 6-bit addr)  */
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, EEPROM_WRITE_OPCODE, 3);
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, offset, 6);
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Send the data  */
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, data, 16);
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_wait_eeprom_command(hw);
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Recover from write  */
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_standby_eeprom(hw);
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Send the 9-bit EWDS (write disable) command to the EEPROM (5-bit
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * opcode plus 4-bit dummy).  This takes the EEPROM out of write/erase
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * mode.
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, EEPROM_EWDS_OPCODE, 5);
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, 0, 4);
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Done with writing  */
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_cleanup_eeprom(hw);
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* clear the init_ctrl_reg_1 to signify that the cache is invalidated */
417c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro	ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR);
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reads a 16 bit word from the EEPROM.
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * offset - offset of 16 bit word in the EEPROM to read
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  The 16-bit value read from the eeprom
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
429222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesu16
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_read_eeprom(struct ixgb_hw *hw,
431222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  u16 offset)
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
433222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 data;
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Prepare the EEPROM for reading  */
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_setup_eeprom(hw);
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Send the READ command (opcode + addr)  */
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, EEPROM_READ_OPCODE, 3);
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * We have a 64 word EEPROM, there are 6 address bits
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_shift_out_bits(hw, offset, 6);
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  Read the data  */
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	data = ixgb_shift_in_bits(hw);
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*  End this read operation  */
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_standby_eeprom(hw);
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return data;
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reads eeprom and stores data in shared structure.
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Validates eeprom checksum and eeprom signature.
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
461446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      true: if eeprom read is successful
462446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      false: otherwise.
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/
464446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesbool
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_eeprom_data(struct ixgb_hw *hw)
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
467222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 i;
468222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 checksum = 0;
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_ee_map_type *ee_map;
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
475d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	pr_debug("Reading eeprom data\n");
4761459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < IXGB_EEPROM_SIZE ; i++) {
477222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		u16 ee_data;
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ee_data = ixgb_read_eeprom(hw, i);
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		checksum += ee_data;
480c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro		hw->eeprom[i] = cpu_to_le16(ee_data);
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
483222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	if (checksum != (u16) EEPROM_SUM) {
484d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Checksum invalid\n");
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* clear the init_ctrl_reg_1 to signify that the cache is
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * invalidated */
487c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro		ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR);
488807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return false;
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro	if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK))
492c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro		 != cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) {
493d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("Signature invalid\n");
494807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return false;
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
497807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return true;
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Local function to check if the eeprom signature is good
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the eeprom signature is good, calls ixgb)get_eeprom_data.
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
507446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      true: eeprom signature was good and the eeprom read was successful
508446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches *      false: otherwise.
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
510446490ca44dcc8a1a9f3c082809bdab208626891Joe Perchesstatic bool
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_check_and_get_eeprom_data (struct ixgb_hw* hw)
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
515c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro	if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK))
516c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro	    == cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) {
517807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return true;
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ixgb_get_eeprom_data(hw);
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return a word from the eeprom
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * index - Offset of eeprom word
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *          Word at indexed offset in eeprom, if valid, 0 otherwise.
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
532c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro__le16
533222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesixgb_get_eeprom_word(struct ixgb_hw *hw, u16 index)
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
53623677ce3172fcb93522a1df077d21019e73ee1e3Joe Perches	if (index < IXGB_EEPROM_SIZE && ixgb_check_and_get_eeprom_data(hw))
53723677ce3172fcb93522a1df077d21019e73ee1e3Joe Perches		return hw->eeprom[index];
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
539807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return 0;
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return the mac address from EEPROM
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw       - Struct containing variables accessed by shared code
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mac_addr - Ethernet Address if EEPROM contents are valid, 0 otherwise
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns: None.
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_ee_mac_addr(struct ixgb_hw *hw,
552222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			u8 *mac_addr)
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
557d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches	ENTER();
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
55923677ce3172fcb93522a1df077d21019e73ee1e3Joe Perches	if (ixgb_check_and_get_eeprom_data(hw)) {
560ac5ac789ebcf5b27e9edc231f6d33c92d722c607Jesse Brandeburg		for (i = 0; i < ETH_ALEN; i++) {
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mac_addr[i] = ee_map->mac_addr[i];
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
563d328bc839eac685cdd91f5d9d8ad95c070252038Joe Perches		pr_debug("eeprom mac address = %pM\n", mac_addr);
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return the Printed Board Assembly number from EEPROM
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *          PBA number if EEPROM contents are valid, 0 otherwise
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
576222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesu32
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_ee_pba_number(struct ixgb_hw *hw)
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
57923677ce3172fcb93522a1df077d21019e73ee1e3Joe Perches	if (ixgb_check_and_get_eeprom_data(hw))
580807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
581807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16);
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
583807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return 0;
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return the Device Id from EEPROM
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * hw - Struct containing variables accessed by shared code
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns:
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *          Device Id if EEPROM contents are valid, 0 otherwise
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ******************************************************************************/
595222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesu16
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_ee_device_id(struct ixgb_hw *hw)
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
60023677ce3172fcb93522a1df077d21019e73ee1e3Joe Perches	if (ixgb_check_and_get_eeprom_data(hw))
601807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet		return le16_to_cpu(ee_map->device_id);
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
603807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return 0;
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
606