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