e1000_i210.c revision ef3a009297c50876980f21060aee61e8b516a990
1f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/*******************************************************************************
2f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
3f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  Intel(R) Gigabit Ethernet Linux driver
44b9ea4626b52c113c367c4776c9bb11b7231393dAkeem G. Abodunrin  Copyright(c) 2007-2013 Intel Corporation.
5f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
6f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  This program is free software; you can redistribute it and/or modify it
7f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  under the terms and conditions of the GNU General Public License,
8f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  version 2, as published by the Free Software Foundation.
9f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
10f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  This program is distributed in the hope it will be useful, but WITHOUT
11f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  more details.
14f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
15f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  You should have received a copy of the GNU General Public License along with
16f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  this program; if not, write to the Free Software Foundation, Inc.,
17f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
19f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  The full GNU General Public License is included in this distribution in
20f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  the file called "COPYING".
21f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
22f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  Contact Information:
23f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
24f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
26f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny******************************************************************************/
27f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
28f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/* e1000_i210
29f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny * e1000_i211
30f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny */
31f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
32f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include <linux/types.h>
33f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include <linux/if_ether.h>
34f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
35f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include "e1000_hw.h"
36f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny#include "e1000_i210.h"
37f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
387916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/**
397916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny * igb_get_hw_semaphore_i210 - Acquire hardware semaphore
407916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  @hw: pointer to the HW structure
417916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *
427916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  Acquire the HW semaphore to access the PHY or NVM
437916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny */
447916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornystatic s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
457916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{
467916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	u32 swsm;
477916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	s32 timeout = hw->nvm.word_size + 1;
487916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	s32 i = 0;
497916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
50d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	/* Get the SW semaphore */
51d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	while (i < timeout) {
52d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		swsm = rd32(E1000_SWSM);
53d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		if (!(swsm & E1000_SWSM_SMBI))
54d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick			break;
55d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick
56d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		udelay(50);
57d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		i++;
58d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	}
59d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick
60d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	if (i == timeout) {
61d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		/* In rare circumstances, the SW semaphore may already be held
62d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		 * unintentionally. Clear the semaphore once before giving up.
63d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		 */
64d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		if (hw->dev_spec._82575.clear_semaphore_once) {
65d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick			hw->dev_spec._82575.clear_semaphore_once = false;
66d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick			igb_put_hw_semaphore(hw);
67d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick			for (i = 0; i < timeout; i++) {
68d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick				swsm = rd32(E1000_SWSM);
69d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick				if (!(swsm & E1000_SWSM_SMBI))
70d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick					break;
71d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick
72d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick				udelay(50);
73d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick			}
74d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		}
75d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick
76d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		/* If we do not have the semaphore here, we have to give up. */
77d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		if (i == timeout) {
78d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick			hw_dbg("Driver can't access device - SMBI bit is set.\n");
79d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick			return -E1000_ERR_NVM;
80d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		}
81d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	}
82d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick
837916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	/* Get the FW semaphore. */
847916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	for (i = 0; i < timeout; i++) {
857916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		swsm = rd32(E1000_SWSM);
867916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
877916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
887916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		/* Semaphore acquired if bit latched */
897916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
907916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			break;
917916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
927916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		udelay(50);
937916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	}
947916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
957916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	if (i == timeout) {
967916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		/* Release semaphores */
977916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		igb_put_hw_semaphore(hw);
987916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		hw_dbg("Driver can't access the NVM\n");
99d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		return -E1000_ERR_NVM;
1007916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	}
1017916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
102d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	return E1000_SUCCESS;
1037916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny}
104f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
105f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
106f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_acquire_nvm_i210 - Request for access to EEPROM
107f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
108f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
109f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Acquire the necessary semaphores for exclusive access to the EEPROM.
110f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
111f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Return successful if access grant bit set, else clear the request for
112f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  EEPROM access and return -E1000_ERR_NVM (-1).
113f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
114f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_acquire_nvm_i210(struct e1000_hw *hw)
115f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
116f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
117f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
118f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
119f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
120f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_release_nvm_i210 - Release exclusive access to EEPROM
121f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
122f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
123f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Stop any current commands to the EEPROM and clear the EEPROM request bit,
124f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  then release the semaphores acquired.
125f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
126f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyvoid igb_release_nvm_i210(struct e1000_hw *hw)
127f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
128f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
129f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
130f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
131f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
132f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
133f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
134f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @mask: specifies which semaphore to acquire
135f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
136f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
137f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  will also specify which port we're acquiring the lock for.
138f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
139f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
140f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
141f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u32 swfw_sync;
142f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u32 swmask = mask;
143f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u32 fwmask = mask << 16;
144f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 ret_val = E1000_SUCCESS;
145f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
146f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
147f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	while (i < timeout) {
148f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		if (igb_get_hw_semaphore_i210(hw)) {
149f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			ret_val = -E1000_ERR_SWFW_SYNC;
150f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			goto out;
151f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		}
152f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
153f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		swfw_sync = rd32(E1000_SW_FW_SYNC);
154d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		if (!(swfw_sync & (fwmask | swmask)))
155f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			break;
156f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
157b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher		/* Firmware currently using resource (fwmask) */
158d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick		igb_put_hw_semaphore(hw);
159f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		mdelay(5);
160f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		i++;
161f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
162f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
163f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (i == timeout) {
164f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
165f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		ret_val = -E1000_ERR_SWFW_SYNC;
166f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		goto out;
167f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
168f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
169f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	swfw_sync |= swmask;
170f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	wr32(E1000_SW_FW_SYNC, swfw_sync);
171f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
172d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	igb_put_hw_semaphore(hw);
173f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout:
174f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return ret_val;
175f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
176f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
177f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
178f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_release_swfw_sync_i210 - Release SW/FW semaphore
179f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
180f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @mask: specifies which semaphore to acquire
181f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
182f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
183f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  will also specify which port we're releasing the lock for.
184f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
185f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyvoid igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
186f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
187f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u32 swfw_sync;
188f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
189f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
190f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		; /* Empty */
191f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
192f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	swfw_sync = rd32(E1000_SW_FW_SYNC);
193f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	swfw_sync &= ~mask;
194f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	wr32(E1000_SW_FW_SYNC, swfw_sync);
195f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
196d44e7a9a1f1e56918f8e937dcf750626ac5ad9b4Matthew Vick	igb_put_hw_semaphore(hw);
197f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
198f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
199f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
200f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
201f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
202f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @offset: offset of word in the Shadow Ram to read
203f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @words: number of words to read
204f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @data: word read from the Shadow Ram
205f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
206f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Reads a 16 bit word from the Shadow Ram using the EERD register.
207f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Uses necessary synchronization semaphores.
208f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
209f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
210f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			     u16 *data)
211f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
212f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 status = E1000_SUCCESS;
213f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u16 i, count;
214f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
215f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	/* We cannot hold synchronization semaphores for too long,
216f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	 * because of forceful takeover procedure. However it is more efficient
217b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher	 * to read in bursts than synchronizing access for each word.
218b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher	 */
219f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
220f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
221f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			E1000_EERD_EEWR_MAX_COUNT : (words - i);
222f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
223f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			status = igb_read_nvm_eerd(hw, offset, count,
224f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny						     data + i);
225f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			hw->nvm.ops.release(hw);
226f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		} else {
227f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			status = E1000_ERR_SWFW_SYNC;
228f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		}
229f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
230f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		if (status != E1000_SUCCESS)
231f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			break;
232f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
233f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
234f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return status;
235f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
236f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
237f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
238f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_write_nvm_srwr - Write to Shadow Ram using EEWR
239f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
240f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @offset: offset within the Shadow Ram to be written to
241f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @words: number of words to write
242f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @data: 16 bit word(s) to be written to the Shadow Ram
243f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
244f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Writes data to Shadow Ram at offset using EEWR register.
245f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
246f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  If igb_update_nvm_checksum is not called after this function , the
247f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Shadow Ram will most likely contain an invalid checksum.
248f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
249f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornystatic s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
250f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny				u16 *data)
251f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
252f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	struct e1000_nvm_info *nvm = &hw->nvm;
253f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u32 i, k, eewr = 0;
254f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u32 attempts = 100000;
255f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 ret_val = E1000_SUCCESS;
256f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
257b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher	/* A check for invalid values:  offset too large, too many words,
258f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	 * too many words for the offset, and not enough words.
259f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	 */
260f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
261f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	    (words == 0)) {
262f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("nvm parameter(s) out of bounds\n");
263f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		ret_val = -E1000_ERR_NVM;
264f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		goto out;
265f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
266f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
267f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	for (i = 0; i < words; i++) {
268f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
269f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			(data[i] << E1000_NVM_RW_REG_DATA) |
270f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			E1000_NVM_RW_REG_START;
271f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
272f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		wr32(E1000_SRWR, eewr);
273f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
274f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		for (k = 0; k < attempts; k++) {
275f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			if (E1000_NVM_RW_REG_DONE &
276f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			    rd32(E1000_SRWR)) {
277f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny				ret_val = E1000_SUCCESS;
278f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny				break;
279f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			}
280f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			udelay(5);
281f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
282f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
283f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		if (ret_val != E1000_SUCCESS) {
284f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			hw_dbg("Shadow RAM write EEWR timed out\n");
285f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			break;
286f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		}
287f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
288f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
289f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout:
290f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return ret_val;
291f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
292f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
293f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
2947916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
2957916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  @hw: pointer to the HW structure
2967916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  @offset: offset within the Shadow RAM to be written to
2977916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  @words: number of words to write
2987916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  @data: 16 bit word(s) to be written to the Shadow RAM
2997916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *
3007916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  Writes data to Shadow RAM at offset using EEWR register.
3017916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *
3027916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  If e1000_update_nvm_checksum is not called after this function , the
3037916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  data will not be committed to FLASH and also Shadow RAM will most likely
3047916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  contain an invalid checksum.
3057916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *
3067916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  If error code is returned, data and Shadow RAM may be inconsistent - buffer
3077916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  partially written.
308b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher **/
3097916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornys32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
3107916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			      u16 *data)
3117916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{
3127916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	s32 status = E1000_SUCCESS;
3137916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	u16 i, count;
3147916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
3157916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	/* We cannot hold synchronization semaphores for too long,
3167916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	 * because of forceful takeover procedure. However it is more efficient
3177916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	 * to write in bursts than synchronizing access for each word.
3187916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	 */
3197916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
3207916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
3217916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			E1000_EERD_EEWR_MAX_COUNT : (words - i);
3227916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
3237916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			status = igb_write_nvm_srwr(hw, offset, count,
3247916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny						      data + i);
3257916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			hw->nvm.ops.release(hw);
3267916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		} else {
3277916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			status = E1000_ERR_SWFW_SYNC;
3287916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		}
3297916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
3307916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		if (status != E1000_SUCCESS)
3317916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			break;
3327916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	}
3337916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
3347916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	return status;
3357916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny}
3367916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
3377916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/**
338ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *  igb_read_invm_word_i210 - Reads OTP
339ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *  @hw: pointer to the HW structure
340ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *  @address: the word address (aka eeprom offset) to read
341ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *  @data: pointer to the data read
342ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *
343ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *  Reads 16-bit words from the OTP. Return error when the word is not
344ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny *  stored in OTP.
345ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny **/
346ef3a009297c50876980f21060aee61e8b516a990Carolyn Wybornystatic s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
347ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny{
348ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
349ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	u32 invm_dword;
350ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	u16 i;
351ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	u8 record_type, word_address;
352ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny
353ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	for (i = 0; i < E1000_INVM_SIZE; i++) {
354ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		invm_dword = rd32(E1000_INVM_DATA_REG(i));
355ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		/* Get record type */
356ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
357ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
358ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny			break;
359ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
360ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny			i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
361ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
362ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny			i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
363ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
364ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny			word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
365ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny			if (word_address == address) {
366ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny				*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
367ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny				hw_dbg("Read INVM Word 0x%02x = %x",
368ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny					  address, *data);
369ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny				status = E1000_SUCCESS;
370ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny				break;
371ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny			}
372ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		}
373ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	}
374ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	if (status != E1000_SUCCESS)
375ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		hw_dbg("Requested word 0x%02x not found in OTP\n", address);
376ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny	return status;
377ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny}
378ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny
379ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny/**
380ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny * igb_read_invm_i210 - Read invm wrapper function for I210/I211
381f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
3825c17a203721d72c36798e5d7fa564e1adf8beb65Akeem G. Abodunrin *  @words: number of words to read
383f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @data: pointer to the data read
384f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
385f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Wrapper function to return data formerly found in the NVM.
386f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
387ef3a009297c50876980f21060aee61e8b516a990Carolyn Wybornystatic s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset,
388ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny				u16 words __always_unused, u16 *data)
389f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
390f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 ret_val = E1000_SUCCESS;
391f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
392f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	/* Only the MAC addr is required to be present in the iNVM */
393f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	switch (offset) {
394f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_MAC_ADDR:
395ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val = igb_read_invm_word_i210(hw, (u8)offset, &data[0]);
396ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val |= igb_read_invm_word_i210(hw, (u8)offset+1,
397ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny						     &data[1]);
398ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val |= igb_read_invm_word_i210(hw, (u8)offset+2,
399ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny						     &data[2]);
400f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		if (ret_val != E1000_SUCCESS)
401f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			hw_dbg("MAC Addr not found in iNVM\n");
402f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		break;
403f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_INIT_CTRL_2:
404ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
4051720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		if (ret_val != E1000_SUCCESS) {
4061720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			*data = NVM_INIT_CTRL_2_DEFAULT_I211;
4071720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			ret_val = E1000_SUCCESS;
4081720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		}
4091720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		break;
410f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_INIT_CTRL_4:
411ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
4121720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		if (ret_val != E1000_SUCCESS) {
4131720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			*data = NVM_INIT_CTRL_4_DEFAULT_I211;
4141720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			ret_val = E1000_SUCCESS;
4151720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		}
4161720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		break;
417f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_LED_1_CFG:
418ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
4191720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		if (ret_val != E1000_SUCCESS) {
4201720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			*data = NVM_LED_1_CFG_DEFAULT_I211;
4211720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			ret_val = E1000_SUCCESS;
4221720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		}
4231720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		break;
424f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_LED_0_2_CFG:
425ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
4261720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		if (ret_val != E1000_SUCCESS) {
4271720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			*data = NVM_LED_0_2_CFG_DEFAULT_I211;
4281720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			ret_val = E1000_SUCCESS;
4291720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		}
430f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		break;
4311720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny	case NVM_ID_LED_SETTINGS:
432ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
4331720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		if (ret_val != E1000_SUCCESS) {
4341720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			*data = ID_LED_RESERVED_FFFF;
4351720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny			ret_val = E1000_SUCCESS;
4361720ee3e4054eff175743820ceba16ecfe97943aCarolyn Wyborny		}
437f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_SUB_DEV_ID:
438f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		*data = hw->subsystem_device_id;
439f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		break;
440f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_SUB_VEN_ID:
441f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		*data = hw->subsystem_vendor_id;
442f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		break;
443f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_DEV_ID:
444f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		*data = hw->device_id;
445f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		break;
446f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	case NVM_VEN_ID:
447f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		*data = hw->vendor_id;
448f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		break;
449f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	default:
450f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("NVM word 0x%02x is not mapped.\n", offset);
451f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		*data = NVM_RESERVED_WORD;
452f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		break;
453f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
454f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return ret_val;
455f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
456f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
457f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
45809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny *  igb_read_invm_version - Reads iNVM version and image type
45909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny *  @hw: pointer to the HW structure
46009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny *  @invm_ver: version structure for the version read
46109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny *
46209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny *  Reads iNVM version and image type.
46309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny **/
46409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wybornys32 igb_read_invm_version(struct e1000_hw *hw,
46509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			  struct e1000_fw_version *invm_ver) {
46609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	u32 *record = NULL;
46709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	u32 *next_record = NULL;
46809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	u32 i = 0;
46909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	u32 invm_dword = 0;
47009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
47109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny					     E1000_INVM_RECORD_SIZE_IN_BYTES);
47209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	u32 buffer[E1000_INVM_SIZE];
47309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
47409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	u16 version = 0;
47509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny
47609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	/* Read iNVM memory */
47709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	for (i = 0; i < E1000_INVM_SIZE; i++) {
47809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		invm_dword = rd32(E1000_INVM_DATA_REG(i));
47909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		buffer[i] = invm_dword;
48009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	}
48109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny
48209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	/* Read version number */
48309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	for (i = 1; i < invm_blocks; i++) {
48409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		record = &buffer[invm_blocks - i];
48509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		next_record = &buffer[invm_blocks - i + 1];
48609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny
48709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		/* Check if we have first version location used */
48809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
48909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			version = 0;
49009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			status = E1000_SUCCESS;
49109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			break;
49209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		}
49309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		/* Check if we have second version location used */
49409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		else if ((i == 1) &&
49509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			 ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
49609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
49709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			status = E1000_SUCCESS;
49809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			break;
49909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		}
50009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		/* Check if we have odd version location
50109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		 * used and it is the last one used
50209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		 */
50309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
50409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			 ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
50509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			 (i != 1))) {
50609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			version = (*next_record & E1000_INVM_VER_FIELD_TWO)
50709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny				  >> 13;
50809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			status = E1000_SUCCESS;
50909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			break;
51009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		}
51109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		/* Check if we have even version location
51209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		 * used and it is the last one used
51309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		 */
51409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
51509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			 ((*record & 0x3) == 0)) {
51609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
51709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			status = E1000_SUCCESS;
51809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			break;
51909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		}
52009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	}
52109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny
52209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	if (status == E1000_SUCCESS) {
52309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
52409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny					>> E1000_INVM_MAJOR_SHIFT;
52509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
52609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	}
52709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	/* Read Image Type */
52809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	for (i = 1; i < invm_blocks; i++) {
52909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		record = &buffer[invm_blocks - i];
53009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		next_record = &buffer[invm_blocks - i + 1];
53109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny
53209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		/* Check if we have image type in first location used */
53309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
53409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			invm_ver->invm_img_type = 0;
53509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			status = E1000_SUCCESS;
53609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			break;
53709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		}
53809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		/* Check if we have image type in first location used */
53909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		else if ((((*record & 0x3) == 0) &&
54009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			 ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
54109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			 ((((*record & 0x3) != 0) && (i != 1)))) {
54209e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			invm_ver->invm_img_type =
54309e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny				(*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
54409e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			status = E1000_SUCCESS;
54509e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny			break;
54609e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny		}
54709e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	}
54809e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny	return status;
54909e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny}
55009e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny
55109e77287e752c8fc9743d865ddadc1a0d81a4927Carolyn Wyborny/**
552f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
553f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
554f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
555f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
556f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
557f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
558f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw)
559f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
560f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 status = E1000_SUCCESS;
561f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
562f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
563f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
564f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
565b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher		/* Replace the read function with semaphore grabbing with
566f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		 * the one that skips this for a while.
567f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		 * We have semaphore taken already here.
568f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		 */
569f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		read_op_ptr = hw->nvm.ops.read;
570f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw->nvm.ops.read = igb_read_nvm_eerd;
571f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
572f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		status = igb_validate_nvm_checksum(hw);
573f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
574f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		/* Revert original read operation. */
575f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw->nvm.ops.read = read_op_ptr;
576f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
577f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw->nvm.ops.release(hw);
578f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	} else {
579f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		status = E1000_ERR_SWFW_SYNC;
580f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
581f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
582f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return status;
583f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
584f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
585f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
586f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_update_nvm_checksum_i210 - Update EEPROM checksum
587f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
588f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
589f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
590f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  up to the checksum.  Then calculates the EEPROM checksum and writes the
591f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  value to the EEPROM. Next commit EEPROM data onto the Flash.
592f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
593f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
594f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
595f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 ret_val = E1000_SUCCESS;
596f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u16 checksum = 0;
597f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u16 i, nvm_data;
598f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
599b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher	/* Read the first word from the EEPROM. If this times out or fails, do
600f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	 * not continue or we could be in for a very long wait while every
601f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	 * EEPROM read fails
602f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	 */
603f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data);
604f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (ret_val != E1000_SUCCESS) {
605f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("EEPROM read failed\n");
606f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		goto out;
607f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
608f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
609f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
610b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher		/* Do not use hw->nvm.ops.write, hw->nvm.ops.read
611f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		 * because we do not want to take the synchronization
612f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		 * semaphores twice here.
613f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		 */
614f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
615f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		for (i = 0; i < NVM_CHECKSUM_REG; i++) {
616f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data);
617f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			if (ret_val) {
618f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny				hw->nvm.ops.release(hw);
619f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny				hw_dbg("NVM Read Error while updating checksum.\n");
620f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny				goto out;
621f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			}
622f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			checksum += nvm_data;
623f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		}
624f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		checksum = (u16) NVM_SUM - checksum;
625f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
626f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny						&checksum);
627f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		if (ret_val != E1000_SUCCESS) {
628f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			hw->nvm.ops.release(hw);
629f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			hw_dbg("NVM Write Error while updating checksum.\n");
630f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			goto out;
631f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		}
632f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
633f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw->nvm.ops.release(hw);
634f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
635f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		ret_val = igb_update_flash_i210(hw);
636f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	} else {
637f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		ret_val = -E1000_ERR_SWFW_SYNC;
638f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
639f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout:
640f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return ret_val;
641f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
642f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
643f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
6447916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  igb_pool_flash_update_done_i210 - Pool FLUDONE status.
6457916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *  @hw: pointer to the HW structure
6467916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny *
647b980ac18c95f3251038da7a3826370aff05a7434Jeff Kirsher **/
6487916a53d203f12461095886cf72d58e9281240d9Carolyn Wybornystatic s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
6497916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny{
6507916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	s32 ret_val = -E1000_ERR_NVM;
6517916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	u32 i, reg;
6527916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
6537916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
6547916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		reg = rd32(E1000_EECD);
6557916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		if (reg & E1000_EECD_FLUDONE_I210) {
6567916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			ret_val = E1000_SUCCESS;
6577916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny			break;
6587916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		}
6597916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny		udelay(5);
6607916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	}
6617916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
6627916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny	return ret_val;
6637916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny}
6647916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny
6657916a53d203f12461095886cf72d58e9281240d9Carolyn Wyborny/**
6665a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny *  igb_get_flash_presence_i210 - Check if flash device is detected.
6675a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny *  @hw: pointer to the HW structure
6685a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny *
6695a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny **/
6705a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wybornybool igb_get_flash_presence_i210(struct e1000_hw *hw)
6715a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny{
6725a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	u32 eec = 0;
6735a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	bool ret_val = false;
6745a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny
6755a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	eec = rd32(E1000_EECD);
6765a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	if (eec & E1000_EECD_FLASH_DETECTED_I210)
6775a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		ret_val = true;
6785a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny
6795a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	return ret_val;
6805a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny}
6815a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny
6825a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny/**
683f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_update_flash_i210 - Commit EEPROM to the flash
684f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
685f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
686f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
687f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_update_flash_i210(struct e1000_hw *hw)
688f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
689f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 ret_val = E1000_SUCCESS;
690f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	u32 flup;
691f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
692f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	ret_val = igb_pool_flash_update_done_i210(hw);
693f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (ret_val == -E1000_ERR_NVM) {
694f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("Flash update time out\n");
695f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		goto out;
696f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
697f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
698f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210;
699f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	wr32(E1000_EECD, flup);
700f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
701f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	ret_val = igb_pool_flash_update_done_i210(hw);
702f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (ret_val == E1000_SUCCESS)
703f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("Flash update complete\n");
704f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	else
705f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("Flash update time out\n");
706f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
707f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout:
708f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return ret_val;
709f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
710f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
711f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny/**
712f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  igb_valid_led_default_i210 - Verify a valid default LED config
713f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @hw: pointer to the HW structure
714f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  @data: pointer to the NVM (EEPROM)
715f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *
716f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  Read the EEPROM for the current default LED configuration.  If the
717f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny *  LED configuration is not valid, set to a valid LED configuration.
718f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny **/
719f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornys32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
720f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny{
721f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	s32 ret_val;
722f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
723f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
724f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (ret_val) {
725f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		hw_dbg("NVM Read Error\n");
726f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		goto out;
727f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
728f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny
729f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
730f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		switch (hw->phy.media_type) {
731f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		case e1000_media_type_internal_serdes:
732f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			*data = ID_LED_DEFAULT_I210_SERDES;
733f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			break;
734f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		case e1000_media_type_copper:
735f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		default:
736f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			*data = ID_LED_DEFAULT_I210;
737f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny			break;
738f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny		}
739f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	}
740f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wybornyout:
741f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny	return ret_val;
742f96a8a0b78548c0ec06b0b4b438db6ee895d67e9Carolyn Wyborny}
74387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
74487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick/**
74587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  __igb_access_xmdio_reg - Read/write XMDIO register
74687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @hw: pointer to the HW structure
74787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @address: XMDIO address to program
74887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @dev_addr: device address to program
74987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @data: pointer to value to read/write from/to the XMDIO address
75087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @read: boolean flag to indicate read or write
75187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick **/
75287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vickstatic s32 __igb_access_xmdio_reg(struct e1000_hw *hw, u16 address,
75387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick				  u8 dev_addr, u16 *data, bool read)
75487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick{
75587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	s32 ret_val = E1000_SUCCESS;
75687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
75787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
75887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	if (ret_val)
75987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick		return ret_val;
76087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
76187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
76287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	if (ret_val)
76387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick		return ret_val;
76487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
76587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
76687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick							 dev_addr);
76787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	if (ret_val)
76887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick		return ret_val;
76987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
77087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	if (read)
77187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick		ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
77287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	else
77387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick		ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
77487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	if (ret_val)
77587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick		return ret_val;
77687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
77787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	/* Recalibrate the device back to 0 */
77887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
77987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	if (ret_val)
78087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick		return ret_val;
78187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
78287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	return ret_val;
78387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick}
78487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
78587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick/**
78687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  igb_read_xmdio_reg - Read XMDIO register
78787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @hw: pointer to the HW structure
78887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @addr: XMDIO address to program
78987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @dev_addr: device address to program
79087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @data: value to be read from the EMI address
79187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick **/
79287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vicks32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
79387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick{
79487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	return __igb_access_xmdio_reg(hw, addr, dev_addr, data, true);
79587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick}
79687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick
79787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick/**
79887371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  igb_write_xmdio_reg - Write XMDIO register
79987371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @hw: pointer to the HW structure
80087371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @addr: XMDIO address to program
80187371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @dev_addr: device address to program
80287371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick *  @data: value to be written to the XMDIO address
80387371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick **/
80487371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vicks32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
80587371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick{
80687371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick	return __igb_access_xmdio_reg(hw, addr, dev_addr, &data, false);
80787371b9de5becc32af2f9be84008b8a8a424c58aMatthew Vick}
8085a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny
8095a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny/**
8105a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny *  igb_init_nvm_params_i210 - Init NVM func ptrs.
8115a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny *  @hw: pointer to the HW structure
8125a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny **/
8135a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wybornys32 igb_init_nvm_params_i210(struct e1000_hw *hw)
8145a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny{
8155a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	s32 ret_val = 0;
8165a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	struct e1000_nvm_info *nvm = &hw->nvm;
8175a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny
8185a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	nvm->ops.acquire = igb_acquire_nvm_i210;
8195a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	nvm->ops.release = igb_release_nvm_i210;
8205a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	nvm->ops.valid_led_default = igb_valid_led_default_i210;
8215a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny
8225a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	/* NVM Function Pointers */
8235a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	if (igb_get_flash_presence_i210(hw)) {
8245a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		hw->nvm.type = e1000_nvm_flash_hw;
8255a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		nvm->ops.read    = igb_read_nvm_srrd_i210;
8265a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		nvm->ops.write   = igb_write_nvm_srwr_i210;
8275a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		nvm->ops.validate = igb_validate_nvm_checksum_i210;
8285a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		nvm->ops.update   = igb_update_nvm_checksum_i210;
8295a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	} else {
8305a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		hw->nvm.type = e1000_nvm_invm;
831ef3a009297c50876980f21060aee61e8b516a990Carolyn Wyborny		nvm->ops.read     = igb_read_invm_i210;
8325a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		nvm->ops.write    = NULL;
8335a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		nvm->ops.validate = NULL;
8345a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny		nvm->ops.update   = NULL;
8355a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	}
8365a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny	return ret_val;
8375a823d8cdd0e16081bc09a03fa253b9750c4b034Carolyn Wyborny}
838