1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606 * Copyright(c) 2001-2020 Intel Corporation
3*2d9fd380Sjfb8856606 */
4*2d9fd380Sjfb8856606
5*2d9fd380Sjfb8856606 #include "igc_api.h"
6*2d9fd380Sjfb8856606
7*2d9fd380Sjfb8856606 /**
8*2d9fd380Sjfb8856606 * igc_get_i2c_data - Reads the I2C SDA data bit
9*2d9fd380Sjfb8856606 * @i2cctl: Current value of I2CCTL register
10*2d9fd380Sjfb8856606 *
11*2d9fd380Sjfb8856606 * Returns the I2C data bit value
12*2d9fd380Sjfb8856606 **/
igc_get_i2c_data(u32 * i2cctl)13*2d9fd380Sjfb8856606 static bool igc_get_i2c_data(u32 *i2cctl)
14*2d9fd380Sjfb8856606 {
15*2d9fd380Sjfb8856606 bool data;
16*2d9fd380Sjfb8856606
17*2d9fd380Sjfb8856606 DEBUGFUNC("igc_get_i2c_data");
18*2d9fd380Sjfb8856606
19*2d9fd380Sjfb8856606 if (*i2cctl & IGC_I2C_DATA_IN)
20*2d9fd380Sjfb8856606 data = 1;
21*2d9fd380Sjfb8856606 else
22*2d9fd380Sjfb8856606 data = 0;
23*2d9fd380Sjfb8856606
24*2d9fd380Sjfb8856606 return data;
25*2d9fd380Sjfb8856606 }
26*2d9fd380Sjfb8856606
27*2d9fd380Sjfb8856606 /**
28*2d9fd380Sjfb8856606 * igc_set_i2c_data - Sets the I2C data bit
29*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
30*2d9fd380Sjfb8856606 * @i2cctl: Current value of I2CCTL register
31*2d9fd380Sjfb8856606 * @data: I2C data value (0 or 1) to set
32*2d9fd380Sjfb8856606 *
33*2d9fd380Sjfb8856606 * Sets the I2C data bit
34*2d9fd380Sjfb8856606 **/
igc_set_i2c_data(struct igc_hw * hw,u32 * i2cctl,bool data)35*2d9fd380Sjfb8856606 static s32 igc_set_i2c_data(struct igc_hw *hw, u32 *i2cctl, bool data)
36*2d9fd380Sjfb8856606 {
37*2d9fd380Sjfb8856606 s32 status = IGC_SUCCESS;
38*2d9fd380Sjfb8856606
39*2d9fd380Sjfb8856606 DEBUGFUNC("igc_set_i2c_data");
40*2d9fd380Sjfb8856606
41*2d9fd380Sjfb8856606 if (data)
42*2d9fd380Sjfb8856606 *i2cctl |= IGC_I2C_DATA_OUT;
43*2d9fd380Sjfb8856606 else
44*2d9fd380Sjfb8856606 *i2cctl &= ~IGC_I2C_DATA_OUT;
45*2d9fd380Sjfb8856606
46*2d9fd380Sjfb8856606 *i2cctl &= ~IGC_I2C_DATA_OE_N;
47*2d9fd380Sjfb8856606 *i2cctl |= IGC_I2C_CLK_OE_N;
48*2d9fd380Sjfb8856606 IGC_WRITE_REG(hw, IGC_I2CPARAMS, *i2cctl);
49*2d9fd380Sjfb8856606 IGC_WRITE_FLUSH(hw);
50*2d9fd380Sjfb8856606
51*2d9fd380Sjfb8856606 /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
52*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_RISE + IGC_I2C_T_FALL + IGC_I2C_T_SU_DATA);
53*2d9fd380Sjfb8856606
54*2d9fd380Sjfb8856606 *i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
55*2d9fd380Sjfb8856606 if (data != igc_get_i2c_data(i2cctl)) {
56*2d9fd380Sjfb8856606 status = IGC_ERR_I2C;
57*2d9fd380Sjfb8856606 DEBUGOUT1("Error - I2C data was not set to %X.\n", data);
58*2d9fd380Sjfb8856606 }
59*2d9fd380Sjfb8856606
60*2d9fd380Sjfb8856606 return status;
61*2d9fd380Sjfb8856606 }
62*2d9fd380Sjfb8856606
63*2d9fd380Sjfb8856606 /**
64*2d9fd380Sjfb8856606 * igc_raise_i2c_clk - Raises the I2C SCL clock
65*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
66*2d9fd380Sjfb8856606 * @i2cctl: Current value of I2CCTL register
67*2d9fd380Sjfb8856606 *
68*2d9fd380Sjfb8856606 * Raises the I2C clock line '0'->'1'
69*2d9fd380Sjfb8856606 **/
igc_raise_i2c_clk(struct igc_hw * hw,u32 * i2cctl)70*2d9fd380Sjfb8856606 static void igc_raise_i2c_clk(struct igc_hw *hw, u32 *i2cctl)
71*2d9fd380Sjfb8856606 {
72*2d9fd380Sjfb8856606 DEBUGFUNC("igc_raise_i2c_clk");
73*2d9fd380Sjfb8856606
74*2d9fd380Sjfb8856606 *i2cctl |= IGC_I2C_CLK_OUT;
75*2d9fd380Sjfb8856606 *i2cctl &= ~IGC_I2C_CLK_OE_N;
76*2d9fd380Sjfb8856606 IGC_WRITE_REG(hw, IGC_I2CPARAMS, *i2cctl);
77*2d9fd380Sjfb8856606 IGC_WRITE_FLUSH(hw);
78*2d9fd380Sjfb8856606
79*2d9fd380Sjfb8856606 /* SCL rise time (1000ns) */
80*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_RISE);
81*2d9fd380Sjfb8856606 }
82*2d9fd380Sjfb8856606
83*2d9fd380Sjfb8856606 /**
84*2d9fd380Sjfb8856606 * igc_lower_i2c_clk - Lowers the I2C SCL clock
85*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
86*2d9fd380Sjfb8856606 * @i2cctl: Current value of I2CCTL register
87*2d9fd380Sjfb8856606 *
88*2d9fd380Sjfb8856606 * Lowers the I2C clock line '1'->'0'
89*2d9fd380Sjfb8856606 **/
igc_lower_i2c_clk(struct igc_hw * hw,u32 * i2cctl)90*2d9fd380Sjfb8856606 static void igc_lower_i2c_clk(struct igc_hw *hw, u32 *i2cctl)
91*2d9fd380Sjfb8856606 {
92*2d9fd380Sjfb8856606 DEBUGFUNC("igc_lower_i2c_clk");
93*2d9fd380Sjfb8856606
94*2d9fd380Sjfb8856606 *i2cctl &= ~IGC_I2C_CLK_OUT;
95*2d9fd380Sjfb8856606 *i2cctl &= ~IGC_I2C_CLK_OE_N;
96*2d9fd380Sjfb8856606 IGC_WRITE_REG(hw, IGC_I2CPARAMS, *i2cctl);
97*2d9fd380Sjfb8856606 IGC_WRITE_FLUSH(hw);
98*2d9fd380Sjfb8856606
99*2d9fd380Sjfb8856606 /* SCL fall time (300ns) */
100*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_FALL);
101*2d9fd380Sjfb8856606 }
102*2d9fd380Sjfb8856606
103*2d9fd380Sjfb8856606 /**
104*2d9fd380Sjfb8856606 * igc_i2c_start - Sets I2C start condition
105*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
106*2d9fd380Sjfb8856606 *
107*2d9fd380Sjfb8856606 * Sets I2C start condition (High -> Low on SDA while SCL is High)
108*2d9fd380Sjfb8856606 **/
igc_i2c_start(struct igc_hw * hw)109*2d9fd380Sjfb8856606 static void igc_i2c_start(struct igc_hw *hw)
110*2d9fd380Sjfb8856606 {
111*2d9fd380Sjfb8856606 u32 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
112*2d9fd380Sjfb8856606
113*2d9fd380Sjfb8856606 DEBUGFUNC("igc_i2c_start");
114*2d9fd380Sjfb8856606
115*2d9fd380Sjfb8856606 /* Start condition must begin with data and clock high */
116*2d9fd380Sjfb8856606 igc_set_i2c_data(hw, &i2cctl, 1);
117*2d9fd380Sjfb8856606 igc_raise_i2c_clk(hw, &i2cctl);
118*2d9fd380Sjfb8856606
119*2d9fd380Sjfb8856606 /* Setup time for start condition (4.7us) */
120*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_SU_STA);
121*2d9fd380Sjfb8856606
122*2d9fd380Sjfb8856606 igc_set_i2c_data(hw, &i2cctl, 0);
123*2d9fd380Sjfb8856606
124*2d9fd380Sjfb8856606 /* Hold time for start condition (4us) */
125*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_HD_STA);
126*2d9fd380Sjfb8856606
127*2d9fd380Sjfb8856606 igc_lower_i2c_clk(hw, &i2cctl);
128*2d9fd380Sjfb8856606
129*2d9fd380Sjfb8856606 /* Minimum low period of clock is 4.7 us */
130*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_LOW);
131*2d9fd380Sjfb8856606 }
132*2d9fd380Sjfb8856606
133*2d9fd380Sjfb8856606 /**
134*2d9fd380Sjfb8856606 * igc_i2c_stop - Sets I2C stop condition
135*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
136*2d9fd380Sjfb8856606 *
137*2d9fd380Sjfb8856606 * Sets I2C stop condition (Low -> High on SDA while SCL is High)
138*2d9fd380Sjfb8856606 **/
igc_i2c_stop(struct igc_hw * hw)139*2d9fd380Sjfb8856606 static void igc_i2c_stop(struct igc_hw *hw)
140*2d9fd380Sjfb8856606 {
141*2d9fd380Sjfb8856606 u32 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
142*2d9fd380Sjfb8856606
143*2d9fd380Sjfb8856606 DEBUGFUNC("igc_i2c_stop");
144*2d9fd380Sjfb8856606
145*2d9fd380Sjfb8856606 /* Stop condition must begin with data low and clock high */
146*2d9fd380Sjfb8856606 igc_set_i2c_data(hw, &i2cctl, 0);
147*2d9fd380Sjfb8856606 igc_raise_i2c_clk(hw, &i2cctl);
148*2d9fd380Sjfb8856606
149*2d9fd380Sjfb8856606 /* Setup time for stop condition (4us) */
150*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_SU_STO);
151*2d9fd380Sjfb8856606
152*2d9fd380Sjfb8856606 igc_set_i2c_data(hw, &i2cctl, 1);
153*2d9fd380Sjfb8856606
154*2d9fd380Sjfb8856606 /* bus free time between stop and start (4.7us)*/
155*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_BUF);
156*2d9fd380Sjfb8856606 }
157*2d9fd380Sjfb8856606
158*2d9fd380Sjfb8856606 /**
159*2d9fd380Sjfb8856606 * igc_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
160*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
161*2d9fd380Sjfb8856606 * @data: read data value
162*2d9fd380Sjfb8856606 *
163*2d9fd380Sjfb8856606 * Clocks in one bit via I2C data/clock
164*2d9fd380Sjfb8856606 **/
igc_clock_in_i2c_bit(struct igc_hw * hw,bool * data)165*2d9fd380Sjfb8856606 static void igc_clock_in_i2c_bit(struct igc_hw *hw, bool *data)
166*2d9fd380Sjfb8856606 {
167*2d9fd380Sjfb8856606 u32 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
168*2d9fd380Sjfb8856606
169*2d9fd380Sjfb8856606 DEBUGFUNC("igc_clock_in_i2c_bit");
170*2d9fd380Sjfb8856606
171*2d9fd380Sjfb8856606 igc_raise_i2c_clk(hw, &i2cctl);
172*2d9fd380Sjfb8856606
173*2d9fd380Sjfb8856606 /* Minimum high period of clock is 4us */
174*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_HIGH);
175*2d9fd380Sjfb8856606
176*2d9fd380Sjfb8856606 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
177*2d9fd380Sjfb8856606 *data = igc_get_i2c_data(&i2cctl);
178*2d9fd380Sjfb8856606
179*2d9fd380Sjfb8856606 igc_lower_i2c_clk(hw, &i2cctl);
180*2d9fd380Sjfb8856606
181*2d9fd380Sjfb8856606 /* Minimum low period of clock is 4.7 us */
182*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_LOW);
183*2d9fd380Sjfb8856606 }
184*2d9fd380Sjfb8856606
185*2d9fd380Sjfb8856606 /**
186*2d9fd380Sjfb8856606 * igc_clock_in_i2c_byte - Clocks in one byte via I2C
187*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
188*2d9fd380Sjfb8856606 * @data: data byte to clock in
189*2d9fd380Sjfb8856606 *
190*2d9fd380Sjfb8856606 * Clocks in one byte data via I2C data/clock
191*2d9fd380Sjfb8856606 **/
igc_clock_in_i2c_byte(struct igc_hw * hw,u8 * data)192*2d9fd380Sjfb8856606 static void igc_clock_in_i2c_byte(struct igc_hw *hw, u8 *data)
193*2d9fd380Sjfb8856606 {
194*2d9fd380Sjfb8856606 s32 i;
195*2d9fd380Sjfb8856606 bool bit = 0;
196*2d9fd380Sjfb8856606
197*2d9fd380Sjfb8856606 DEBUGFUNC("igc_clock_in_i2c_byte");
198*2d9fd380Sjfb8856606
199*2d9fd380Sjfb8856606 *data = 0;
200*2d9fd380Sjfb8856606 for (i = 7; i >= 0; i--) {
201*2d9fd380Sjfb8856606 igc_clock_in_i2c_bit(hw, &bit);
202*2d9fd380Sjfb8856606 *data |= bit << i;
203*2d9fd380Sjfb8856606 }
204*2d9fd380Sjfb8856606 }
205*2d9fd380Sjfb8856606
206*2d9fd380Sjfb8856606 /**
207*2d9fd380Sjfb8856606 * igc_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
208*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
209*2d9fd380Sjfb8856606 * @data: data value to write
210*2d9fd380Sjfb8856606 *
211*2d9fd380Sjfb8856606 * Clocks out one bit via I2C data/clock
212*2d9fd380Sjfb8856606 **/
igc_clock_out_i2c_bit(struct igc_hw * hw,bool data)213*2d9fd380Sjfb8856606 static s32 igc_clock_out_i2c_bit(struct igc_hw *hw, bool data)
214*2d9fd380Sjfb8856606 {
215*2d9fd380Sjfb8856606 s32 status;
216*2d9fd380Sjfb8856606 u32 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
217*2d9fd380Sjfb8856606
218*2d9fd380Sjfb8856606 DEBUGFUNC("igc_clock_out_i2c_bit");
219*2d9fd380Sjfb8856606
220*2d9fd380Sjfb8856606 status = igc_set_i2c_data(hw, &i2cctl, data);
221*2d9fd380Sjfb8856606 if (status == IGC_SUCCESS) {
222*2d9fd380Sjfb8856606 igc_raise_i2c_clk(hw, &i2cctl);
223*2d9fd380Sjfb8856606
224*2d9fd380Sjfb8856606 /* Minimum high period of clock is 4us */
225*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_HIGH);
226*2d9fd380Sjfb8856606
227*2d9fd380Sjfb8856606 igc_lower_i2c_clk(hw, &i2cctl);
228*2d9fd380Sjfb8856606
229*2d9fd380Sjfb8856606 /* Minimum low period of clock is 4.7 us.
230*2d9fd380Sjfb8856606 * This also takes care of the data hold time.
231*2d9fd380Sjfb8856606 */
232*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_LOW);
233*2d9fd380Sjfb8856606 } else {
234*2d9fd380Sjfb8856606 status = IGC_ERR_I2C;
235*2d9fd380Sjfb8856606 DEBUGOUT1("I2C data was not set to %X\n", data);
236*2d9fd380Sjfb8856606 }
237*2d9fd380Sjfb8856606
238*2d9fd380Sjfb8856606 return status;
239*2d9fd380Sjfb8856606 }
240*2d9fd380Sjfb8856606
241*2d9fd380Sjfb8856606 /**
242*2d9fd380Sjfb8856606 * igc_clock_out_i2c_byte - Clocks out one byte via I2C
243*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
244*2d9fd380Sjfb8856606 * @data: data byte clocked out
245*2d9fd380Sjfb8856606 *
246*2d9fd380Sjfb8856606 * Clocks out one byte data via I2C data/clock
247*2d9fd380Sjfb8856606 **/
igc_clock_out_i2c_byte(struct igc_hw * hw,u8 data)248*2d9fd380Sjfb8856606 static s32 igc_clock_out_i2c_byte(struct igc_hw *hw, u8 data)
249*2d9fd380Sjfb8856606 {
250*2d9fd380Sjfb8856606 s32 status = IGC_SUCCESS;
251*2d9fd380Sjfb8856606 s32 i;
252*2d9fd380Sjfb8856606 u32 i2cctl;
253*2d9fd380Sjfb8856606 bool bit = 0;
254*2d9fd380Sjfb8856606
255*2d9fd380Sjfb8856606 DEBUGFUNC("igc_clock_out_i2c_byte");
256*2d9fd380Sjfb8856606
257*2d9fd380Sjfb8856606 for (i = 7; i >= 0; i--) {
258*2d9fd380Sjfb8856606 bit = (data >> i) & 0x1;
259*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_bit(hw, bit);
260*2d9fd380Sjfb8856606
261*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
262*2d9fd380Sjfb8856606 break;
263*2d9fd380Sjfb8856606 }
264*2d9fd380Sjfb8856606
265*2d9fd380Sjfb8856606 /* Release SDA line (set high) */
266*2d9fd380Sjfb8856606 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
267*2d9fd380Sjfb8856606
268*2d9fd380Sjfb8856606 i2cctl |= IGC_I2C_DATA_OE_N;
269*2d9fd380Sjfb8856606 IGC_WRITE_REG(hw, IGC_I2CPARAMS, i2cctl);
270*2d9fd380Sjfb8856606 IGC_WRITE_FLUSH(hw);
271*2d9fd380Sjfb8856606
272*2d9fd380Sjfb8856606 return status;
273*2d9fd380Sjfb8856606 }
274*2d9fd380Sjfb8856606
275*2d9fd380Sjfb8856606 /**
276*2d9fd380Sjfb8856606 * igc_get_i2c_ack - Polls for I2C ACK
277*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
278*2d9fd380Sjfb8856606 *
279*2d9fd380Sjfb8856606 * Clocks in/out one bit via I2C data/clock
280*2d9fd380Sjfb8856606 **/
igc_get_i2c_ack(struct igc_hw * hw)281*2d9fd380Sjfb8856606 static s32 igc_get_i2c_ack(struct igc_hw *hw)
282*2d9fd380Sjfb8856606 {
283*2d9fd380Sjfb8856606 s32 status = IGC_SUCCESS;
284*2d9fd380Sjfb8856606 u32 i = 0;
285*2d9fd380Sjfb8856606 u32 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
286*2d9fd380Sjfb8856606 u32 timeout = 10;
287*2d9fd380Sjfb8856606 bool ack = true;
288*2d9fd380Sjfb8856606
289*2d9fd380Sjfb8856606 DEBUGFUNC("igc_get_i2c_ack");
290*2d9fd380Sjfb8856606
291*2d9fd380Sjfb8856606 igc_raise_i2c_clk(hw, &i2cctl);
292*2d9fd380Sjfb8856606
293*2d9fd380Sjfb8856606 /* Minimum high period of clock is 4us */
294*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_HIGH);
295*2d9fd380Sjfb8856606
296*2d9fd380Sjfb8856606 /* Wait until SCL returns high */
297*2d9fd380Sjfb8856606 for (i = 0; i < timeout; i++) {
298*2d9fd380Sjfb8856606 usec_delay(1);
299*2d9fd380Sjfb8856606 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
300*2d9fd380Sjfb8856606 if (i2cctl & IGC_I2C_CLK_IN)
301*2d9fd380Sjfb8856606 break;
302*2d9fd380Sjfb8856606 }
303*2d9fd380Sjfb8856606 if (!(i2cctl & IGC_I2C_CLK_IN))
304*2d9fd380Sjfb8856606 return IGC_ERR_I2C;
305*2d9fd380Sjfb8856606
306*2d9fd380Sjfb8856606 ack = igc_get_i2c_data(&i2cctl);
307*2d9fd380Sjfb8856606 if (ack) {
308*2d9fd380Sjfb8856606 DEBUGOUT("I2C ack was not received.\n");
309*2d9fd380Sjfb8856606 status = IGC_ERR_I2C;
310*2d9fd380Sjfb8856606 }
311*2d9fd380Sjfb8856606
312*2d9fd380Sjfb8856606 igc_lower_i2c_clk(hw, &i2cctl);
313*2d9fd380Sjfb8856606
314*2d9fd380Sjfb8856606 /* Minimum low period of clock is 4.7 us */
315*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_LOW);
316*2d9fd380Sjfb8856606
317*2d9fd380Sjfb8856606 return status;
318*2d9fd380Sjfb8856606 }
319*2d9fd380Sjfb8856606
320*2d9fd380Sjfb8856606 /**
321*2d9fd380Sjfb8856606 * igc_set_i2c_bb - Enable I2C bit-bang
322*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
323*2d9fd380Sjfb8856606 *
324*2d9fd380Sjfb8856606 * Enable I2C bit-bang interface
325*2d9fd380Sjfb8856606 *
326*2d9fd380Sjfb8856606 **/
igc_set_i2c_bb(struct igc_hw * hw)327*2d9fd380Sjfb8856606 s32 igc_set_i2c_bb(struct igc_hw *hw)
328*2d9fd380Sjfb8856606 {
329*2d9fd380Sjfb8856606 s32 ret_val = IGC_SUCCESS;
330*2d9fd380Sjfb8856606 u32 ctrl_ext, i2cparams;
331*2d9fd380Sjfb8856606
332*2d9fd380Sjfb8856606 DEBUGFUNC("igc_set_i2c_bb");
333*2d9fd380Sjfb8856606
334*2d9fd380Sjfb8856606 ctrl_ext = IGC_READ_REG(hw, IGC_CTRL_EXT);
335*2d9fd380Sjfb8856606 ctrl_ext |= IGC_CTRL_I2C_ENA;
336*2d9fd380Sjfb8856606 IGC_WRITE_REG(hw, IGC_CTRL_EXT, ctrl_ext);
337*2d9fd380Sjfb8856606 IGC_WRITE_FLUSH(hw);
338*2d9fd380Sjfb8856606
339*2d9fd380Sjfb8856606 i2cparams = IGC_READ_REG(hw, IGC_I2CPARAMS);
340*2d9fd380Sjfb8856606 i2cparams |= IGC_I2CBB_EN;
341*2d9fd380Sjfb8856606 i2cparams |= IGC_I2C_DATA_OE_N;
342*2d9fd380Sjfb8856606 i2cparams |= IGC_I2C_CLK_OE_N;
343*2d9fd380Sjfb8856606 IGC_WRITE_REG(hw, IGC_I2CPARAMS, i2cparams);
344*2d9fd380Sjfb8856606 IGC_WRITE_FLUSH(hw);
345*2d9fd380Sjfb8856606
346*2d9fd380Sjfb8856606 return ret_val;
347*2d9fd380Sjfb8856606 }
348*2d9fd380Sjfb8856606
349*2d9fd380Sjfb8856606 /**
350*2d9fd380Sjfb8856606 * igc_read_i2c_byte_generic - Reads 8 bit word over I2C
351*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
352*2d9fd380Sjfb8856606 * @byte_offset: byte offset to read
353*2d9fd380Sjfb8856606 * @dev_addr: device address
354*2d9fd380Sjfb8856606 * @data: value read
355*2d9fd380Sjfb8856606 *
356*2d9fd380Sjfb8856606 * Performs byte read operation over I2C interface at
357*2d9fd380Sjfb8856606 * a specified device address.
358*2d9fd380Sjfb8856606 **/
igc_read_i2c_byte_generic(struct igc_hw * hw,u8 byte_offset,u8 dev_addr,u8 * data)359*2d9fd380Sjfb8856606 s32 igc_read_i2c_byte_generic(struct igc_hw *hw, u8 byte_offset,
360*2d9fd380Sjfb8856606 u8 dev_addr, u8 *data)
361*2d9fd380Sjfb8856606 {
362*2d9fd380Sjfb8856606 s32 status = IGC_SUCCESS;
363*2d9fd380Sjfb8856606 u32 max_retry = 10;
364*2d9fd380Sjfb8856606 u32 retry = 1;
365*2d9fd380Sjfb8856606 u16 swfw_mask = 0;
366*2d9fd380Sjfb8856606
367*2d9fd380Sjfb8856606 bool nack = true;
368*2d9fd380Sjfb8856606
369*2d9fd380Sjfb8856606 DEBUGFUNC("igc_read_i2c_byte_generic");
370*2d9fd380Sjfb8856606
371*2d9fd380Sjfb8856606 swfw_mask = IGC_SWFW_PHY0_SM;
372*2d9fd380Sjfb8856606
373*2d9fd380Sjfb8856606 do {
374*2d9fd380Sjfb8856606 if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
375*2d9fd380Sjfb8856606 != IGC_SUCCESS) {
376*2d9fd380Sjfb8856606 status = IGC_ERR_SWFW_SYNC;
377*2d9fd380Sjfb8856606 goto read_byte_out;
378*2d9fd380Sjfb8856606 }
379*2d9fd380Sjfb8856606
380*2d9fd380Sjfb8856606 igc_i2c_start(hw);
381*2d9fd380Sjfb8856606
382*2d9fd380Sjfb8856606 /* Device Address and write indication */
383*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_byte(hw, dev_addr);
384*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
385*2d9fd380Sjfb8856606 goto fail;
386*2d9fd380Sjfb8856606
387*2d9fd380Sjfb8856606 status = igc_get_i2c_ack(hw);
388*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
389*2d9fd380Sjfb8856606 goto fail;
390*2d9fd380Sjfb8856606
391*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_byte(hw, byte_offset);
392*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
393*2d9fd380Sjfb8856606 goto fail;
394*2d9fd380Sjfb8856606
395*2d9fd380Sjfb8856606 status = igc_get_i2c_ack(hw);
396*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
397*2d9fd380Sjfb8856606 goto fail;
398*2d9fd380Sjfb8856606
399*2d9fd380Sjfb8856606 igc_i2c_start(hw);
400*2d9fd380Sjfb8856606
401*2d9fd380Sjfb8856606 /* Device Address and read indication */
402*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_byte(hw, (dev_addr | 0x1));
403*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
404*2d9fd380Sjfb8856606 goto fail;
405*2d9fd380Sjfb8856606
406*2d9fd380Sjfb8856606 status = igc_get_i2c_ack(hw);
407*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
408*2d9fd380Sjfb8856606 goto fail;
409*2d9fd380Sjfb8856606
410*2d9fd380Sjfb8856606 igc_clock_in_i2c_byte(hw, data);
411*2d9fd380Sjfb8856606
412*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_bit(hw, nack);
413*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
414*2d9fd380Sjfb8856606 goto fail;
415*2d9fd380Sjfb8856606
416*2d9fd380Sjfb8856606 igc_i2c_stop(hw);
417*2d9fd380Sjfb8856606 break;
418*2d9fd380Sjfb8856606
419*2d9fd380Sjfb8856606 fail:
420*2d9fd380Sjfb8856606 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
421*2d9fd380Sjfb8856606 msec_delay(100);
422*2d9fd380Sjfb8856606 igc_i2c_bus_clear(hw);
423*2d9fd380Sjfb8856606 retry++;
424*2d9fd380Sjfb8856606 if (retry < max_retry)
425*2d9fd380Sjfb8856606 DEBUGOUT("I2C byte read error - Retrying.\n");
426*2d9fd380Sjfb8856606 else
427*2d9fd380Sjfb8856606 DEBUGOUT("I2C byte read error.\n");
428*2d9fd380Sjfb8856606
429*2d9fd380Sjfb8856606 } while (retry < max_retry);
430*2d9fd380Sjfb8856606
431*2d9fd380Sjfb8856606 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
432*2d9fd380Sjfb8856606
433*2d9fd380Sjfb8856606 read_byte_out:
434*2d9fd380Sjfb8856606
435*2d9fd380Sjfb8856606 return status;
436*2d9fd380Sjfb8856606 }
437*2d9fd380Sjfb8856606
438*2d9fd380Sjfb8856606 /**
439*2d9fd380Sjfb8856606 * igc_write_i2c_byte_generic - Writes 8 bit word over I2C
440*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
441*2d9fd380Sjfb8856606 * @byte_offset: byte offset to write
442*2d9fd380Sjfb8856606 * @dev_addr: device address
443*2d9fd380Sjfb8856606 * @data: value to write
444*2d9fd380Sjfb8856606 *
445*2d9fd380Sjfb8856606 * Performs byte write operation over I2C interface at
446*2d9fd380Sjfb8856606 * a specified device address.
447*2d9fd380Sjfb8856606 **/
igc_write_i2c_byte_generic(struct igc_hw * hw,u8 byte_offset,u8 dev_addr,u8 data)448*2d9fd380Sjfb8856606 s32 igc_write_i2c_byte_generic(struct igc_hw *hw, u8 byte_offset,
449*2d9fd380Sjfb8856606 u8 dev_addr, u8 data)
450*2d9fd380Sjfb8856606 {
451*2d9fd380Sjfb8856606 s32 status = IGC_SUCCESS;
452*2d9fd380Sjfb8856606 u32 max_retry = 1;
453*2d9fd380Sjfb8856606 u32 retry = 0;
454*2d9fd380Sjfb8856606 u16 swfw_mask = 0;
455*2d9fd380Sjfb8856606
456*2d9fd380Sjfb8856606 DEBUGFUNC("igc_write_i2c_byte_generic");
457*2d9fd380Sjfb8856606
458*2d9fd380Sjfb8856606 swfw_mask = IGC_SWFW_PHY0_SM;
459*2d9fd380Sjfb8856606
460*2d9fd380Sjfb8856606 if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != IGC_SUCCESS) {
461*2d9fd380Sjfb8856606 status = IGC_ERR_SWFW_SYNC;
462*2d9fd380Sjfb8856606 goto write_byte_out;
463*2d9fd380Sjfb8856606 }
464*2d9fd380Sjfb8856606
465*2d9fd380Sjfb8856606 do {
466*2d9fd380Sjfb8856606 igc_i2c_start(hw);
467*2d9fd380Sjfb8856606
468*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_byte(hw, dev_addr);
469*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
470*2d9fd380Sjfb8856606 goto fail;
471*2d9fd380Sjfb8856606
472*2d9fd380Sjfb8856606 status = igc_get_i2c_ack(hw);
473*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
474*2d9fd380Sjfb8856606 goto fail;
475*2d9fd380Sjfb8856606
476*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_byte(hw, byte_offset);
477*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
478*2d9fd380Sjfb8856606 goto fail;
479*2d9fd380Sjfb8856606
480*2d9fd380Sjfb8856606 status = igc_get_i2c_ack(hw);
481*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
482*2d9fd380Sjfb8856606 goto fail;
483*2d9fd380Sjfb8856606
484*2d9fd380Sjfb8856606 status = igc_clock_out_i2c_byte(hw, data);
485*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
486*2d9fd380Sjfb8856606 goto fail;
487*2d9fd380Sjfb8856606
488*2d9fd380Sjfb8856606 status = igc_get_i2c_ack(hw);
489*2d9fd380Sjfb8856606 if (status != IGC_SUCCESS)
490*2d9fd380Sjfb8856606 goto fail;
491*2d9fd380Sjfb8856606
492*2d9fd380Sjfb8856606 igc_i2c_stop(hw);
493*2d9fd380Sjfb8856606 break;
494*2d9fd380Sjfb8856606
495*2d9fd380Sjfb8856606 fail:
496*2d9fd380Sjfb8856606 igc_i2c_bus_clear(hw);
497*2d9fd380Sjfb8856606 retry++;
498*2d9fd380Sjfb8856606 if (retry < max_retry)
499*2d9fd380Sjfb8856606 DEBUGOUT("I2C byte write error - Retrying.\n");
500*2d9fd380Sjfb8856606 else
501*2d9fd380Sjfb8856606 DEBUGOUT("I2C byte write error.\n");
502*2d9fd380Sjfb8856606 } while (retry < max_retry);
503*2d9fd380Sjfb8856606
504*2d9fd380Sjfb8856606 hw->mac.ops.release_swfw_sync(hw, swfw_mask);
505*2d9fd380Sjfb8856606
506*2d9fd380Sjfb8856606 write_byte_out:
507*2d9fd380Sjfb8856606
508*2d9fd380Sjfb8856606 return status;
509*2d9fd380Sjfb8856606 }
510*2d9fd380Sjfb8856606
511*2d9fd380Sjfb8856606 /**
512*2d9fd380Sjfb8856606 * igc_i2c_bus_clear - Clears the I2C bus
513*2d9fd380Sjfb8856606 * @hw: pointer to hardware structure
514*2d9fd380Sjfb8856606 *
515*2d9fd380Sjfb8856606 * Clears the I2C bus by sending nine clock pulses.
516*2d9fd380Sjfb8856606 * Used when data line is stuck low.
517*2d9fd380Sjfb8856606 **/
igc_i2c_bus_clear(struct igc_hw * hw)518*2d9fd380Sjfb8856606 void igc_i2c_bus_clear(struct igc_hw *hw)
519*2d9fd380Sjfb8856606 {
520*2d9fd380Sjfb8856606 u32 i2cctl = IGC_READ_REG(hw, IGC_I2CPARAMS);
521*2d9fd380Sjfb8856606 u32 i;
522*2d9fd380Sjfb8856606
523*2d9fd380Sjfb8856606 DEBUGFUNC("igc_i2c_bus_clear");
524*2d9fd380Sjfb8856606
525*2d9fd380Sjfb8856606 igc_i2c_start(hw);
526*2d9fd380Sjfb8856606
527*2d9fd380Sjfb8856606 igc_set_i2c_data(hw, &i2cctl, 1);
528*2d9fd380Sjfb8856606
529*2d9fd380Sjfb8856606 for (i = 0; i < 9; i++) {
530*2d9fd380Sjfb8856606 igc_raise_i2c_clk(hw, &i2cctl);
531*2d9fd380Sjfb8856606
532*2d9fd380Sjfb8856606 /* Min high period of clock is 4us */
533*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_HIGH);
534*2d9fd380Sjfb8856606
535*2d9fd380Sjfb8856606 igc_lower_i2c_clk(hw, &i2cctl);
536*2d9fd380Sjfb8856606
537*2d9fd380Sjfb8856606 /* Min low period of clock is 4.7us*/
538*2d9fd380Sjfb8856606 usec_delay(IGC_I2C_T_LOW);
539*2d9fd380Sjfb8856606 }
540*2d9fd380Sjfb8856606
541*2d9fd380Sjfb8856606 igc_i2c_start(hw);
542*2d9fd380Sjfb8856606
543*2d9fd380Sjfb8856606 /* Put the i2c bus back to default state */
544*2d9fd380Sjfb8856606 igc_i2c_stop(hw);
545*2d9fd380Sjfb8856606 }
546*2d9fd380Sjfb8856606
547*2d9fd380Sjfb8856606 /**
548*2d9fd380Sjfb8856606 * igc_init_mac_params - Initialize MAC function pointers
549*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
550*2d9fd380Sjfb8856606 *
551*2d9fd380Sjfb8856606 * This function initializes the function pointers for the MAC
552*2d9fd380Sjfb8856606 * set of functions. Called by drivers or by igc_setup_init_funcs.
553*2d9fd380Sjfb8856606 **/
igc_init_mac_params(struct igc_hw * hw)554*2d9fd380Sjfb8856606 s32 igc_init_mac_params(struct igc_hw *hw)
555*2d9fd380Sjfb8856606 {
556*2d9fd380Sjfb8856606 s32 ret_val = IGC_SUCCESS;
557*2d9fd380Sjfb8856606
558*2d9fd380Sjfb8856606 if (hw->mac.ops.init_params) {
559*2d9fd380Sjfb8856606 ret_val = hw->mac.ops.init_params(hw);
560*2d9fd380Sjfb8856606 if (ret_val) {
561*2d9fd380Sjfb8856606 DEBUGOUT("MAC Initialization Error\n");
562*2d9fd380Sjfb8856606 goto out;
563*2d9fd380Sjfb8856606 }
564*2d9fd380Sjfb8856606 } else {
565*2d9fd380Sjfb8856606 DEBUGOUT("mac.init_mac_params was NULL\n");
566*2d9fd380Sjfb8856606 ret_val = -IGC_ERR_CONFIG;
567*2d9fd380Sjfb8856606 }
568*2d9fd380Sjfb8856606
569*2d9fd380Sjfb8856606 out:
570*2d9fd380Sjfb8856606 return ret_val;
571*2d9fd380Sjfb8856606 }
572*2d9fd380Sjfb8856606
573*2d9fd380Sjfb8856606 /**
574*2d9fd380Sjfb8856606 * igc_init_nvm_params - Initialize NVM function pointers
575*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
576*2d9fd380Sjfb8856606 *
577*2d9fd380Sjfb8856606 * This function initializes the function pointers for the NVM
578*2d9fd380Sjfb8856606 * set of functions. Called by drivers or by igc_setup_init_funcs.
579*2d9fd380Sjfb8856606 **/
igc_init_nvm_params(struct igc_hw * hw)580*2d9fd380Sjfb8856606 s32 igc_init_nvm_params(struct igc_hw *hw)
581*2d9fd380Sjfb8856606 {
582*2d9fd380Sjfb8856606 s32 ret_val = IGC_SUCCESS;
583*2d9fd380Sjfb8856606
584*2d9fd380Sjfb8856606 if (hw->nvm.ops.init_params) {
585*2d9fd380Sjfb8856606 ret_val = hw->nvm.ops.init_params(hw);
586*2d9fd380Sjfb8856606 if (ret_val) {
587*2d9fd380Sjfb8856606 DEBUGOUT("NVM Initialization Error\n");
588*2d9fd380Sjfb8856606 goto out;
589*2d9fd380Sjfb8856606 }
590*2d9fd380Sjfb8856606 } else {
591*2d9fd380Sjfb8856606 DEBUGOUT("nvm.init_nvm_params was NULL\n");
592*2d9fd380Sjfb8856606 ret_val = -IGC_ERR_CONFIG;
593*2d9fd380Sjfb8856606 }
594*2d9fd380Sjfb8856606
595*2d9fd380Sjfb8856606 out:
596*2d9fd380Sjfb8856606 return ret_val;
597*2d9fd380Sjfb8856606 }
598*2d9fd380Sjfb8856606
599*2d9fd380Sjfb8856606 /**
600*2d9fd380Sjfb8856606 * igc_init_phy_params - Initialize PHY function pointers
601*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
602*2d9fd380Sjfb8856606 *
603*2d9fd380Sjfb8856606 * This function initializes the function pointers for the PHY
604*2d9fd380Sjfb8856606 * set of functions. Called by drivers or by igc_setup_init_funcs.
605*2d9fd380Sjfb8856606 **/
igc_init_phy_params(struct igc_hw * hw)606*2d9fd380Sjfb8856606 s32 igc_init_phy_params(struct igc_hw *hw)
607*2d9fd380Sjfb8856606 {
608*2d9fd380Sjfb8856606 s32 ret_val = IGC_SUCCESS;
609*2d9fd380Sjfb8856606
610*2d9fd380Sjfb8856606 if (hw->phy.ops.init_params) {
611*2d9fd380Sjfb8856606 ret_val = hw->phy.ops.init_params(hw);
612*2d9fd380Sjfb8856606 if (ret_val) {
613*2d9fd380Sjfb8856606 DEBUGOUT("PHY Initialization Error\n");
614*2d9fd380Sjfb8856606 goto out;
615*2d9fd380Sjfb8856606 }
616*2d9fd380Sjfb8856606 } else {
617*2d9fd380Sjfb8856606 DEBUGOUT("phy.init_phy_params was NULL\n");
618*2d9fd380Sjfb8856606 ret_val = -IGC_ERR_CONFIG;
619*2d9fd380Sjfb8856606 }
620*2d9fd380Sjfb8856606
621*2d9fd380Sjfb8856606 out:
622*2d9fd380Sjfb8856606 return ret_val;
623*2d9fd380Sjfb8856606 }
624*2d9fd380Sjfb8856606
625*2d9fd380Sjfb8856606 /**
626*2d9fd380Sjfb8856606 * igc_init_mbx_params - Initialize mailbox function pointers
627*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
628*2d9fd380Sjfb8856606 *
629*2d9fd380Sjfb8856606 * This function initializes the function pointers for the PHY
630*2d9fd380Sjfb8856606 * set of functions. Called by drivers or by igc_setup_init_funcs.
631*2d9fd380Sjfb8856606 **/
igc_init_mbx_params(struct igc_hw * hw)632*2d9fd380Sjfb8856606 s32 igc_init_mbx_params(struct igc_hw *hw)
633*2d9fd380Sjfb8856606 {
634*2d9fd380Sjfb8856606 s32 ret_val = IGC_SUCCESS;
635*2d9fd380Sjfb8856606
636*2d9fd380Sjfb8856606 if (hw->mbx.ops.init_params) {
637*2d9fd380Sjfb8856606 ret_val = hw->mbx.ops.init_params(hw);
638*2d9fd380Sjfb8856606 if (ret_val) {
639*2d9fd380Sjfb8856606 DEBUGOUT("Mailbox Initialization Error\n");
640*2d9fd380Sjfb8856606 goto out;
641*2d9fd380Sjfb8856606 }
642*2d9fd380Sjfb8856606 } else {
643*2d9fd380Sjfb8856606 DEBUGOUT("mbx.init_mbx_params was NULL\n");
644*2d9fd380Sjfb8856606 ret_val = -IGC_ERR_CONFIG;
645*2d9fd380Sjfb8856606 }
646*2d9fd380Sjfb8856606
647*2d9fd380Sjfb8856606 out:
648*2d9fd380Sjfb8856606 return ret_val;
649*2d9fd380Sjfb8856606 }
650*2d9fd380Sjfb8856606
651*2d9fd380Sjfb8856606 /**
652*2d9fd380Sjfb8856606 * igc_set_mac_type - Sets MAC type
653*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
654*2d9fd380Sjfb8856606 *
655*2d9fd380Sjfb8856606 * This function sets the mac type of the adapter based on the
656*2d9fd380Sjfb8856606 * device ID stored in the hw structure.
657*2d9fd380Sjfb8856606 * MUST BE FIRST FUNCTION CALLED (explicitly or through
658*2d9fd380Sjfb8856606 * igc_setup_init_funcs()).
659*2d9fd380Sjfb8856606 **/
igc_set_mac_type(struct igc_hw * hw)660*2d9fd380Sjfb8856606 s32 igc_set_mac_type(struct igc_hw *hw)
661*2d9fd380Sjfb8856606 {
662*2d9fd380Sjfb8856606 struct igc_mac_info *mac = &hw->mac;
663*2d9fd380Sjfb8856606 s32 ret_val = IGC_SUCCESS;
664*2d9fd380Sjfb8856606
665*2d9fd380Sjfb8856606 DEBUGFUNC("igc_set_mac_type");
666*2d9fd380Sjfb8856606
667*2d9fd380Sjfb8856606 switch (hw->device_id) {
668*2d9fd380Sjfb8856606 case IGC_DEV_ID_82542:
669*2d9fd380Sjfb8856606 mac->type = igc_82542;
670*2d9fd380Sjfb8856606 break;
671*2d9fd380Sjfb8856606 case IGC_DEV_ID_82543GC_FIBER:
672*2d9fd380Sjfb8856606 case IGC_DEV_ID_82543GC_COPPER:
673*2d9fd380Sjfb8856606 mac->type = igc_82543;
674*2d9fd380Sjfb8856606 break;
675*2d9fd380Sjfb8856606 case IGC_DEV_ID_82544EI_COPPER:
676*2d9fd380Sjfb8856606 case IGC_DEV_ID_82544EI_FIBER:
677*2d9fd380Sjfb8856606 case IGC_DEV_ID_82544GC_COPPER:
678*2d9fd380Sjfb8856606 case IGC_DEV_ID_82544GC_LOM:
679*2d9fd380Sjfb8856606 mac->type = igc_82544;
680*2d9fd380Sjfb8856606 break;
681*2d9fd380Sjfb8856606 case IGC_DEV_ID_82540EM:
682*2d9fd380Sjfb8856606 case IGC_DEV_ID_82540EM_LOM:
683*2d9fd380Sjfb8856606 case IGC_DEV_ID_82540EP:
684*2d9fd380Sjfb8856606 case IGC_DEV_ID_82540EP_LOM:
685*2d9fd380Sjfb8856606 case IGC_DEV_ID_82540EP_LP:
686*2d9fd380Sjfb8856606 mac->type = igc_82540;
687*2d9fd380Sjfb8856606 break;
688*2d9fd380Sjfb8856606 case IGC_DEV_ID_82545EM_COPPER:
689*2d9fd380Sjfb8856606 case IGC_DEV_ID_82545EM_FIBER:
690*2d9fd380Sjfb8856606 mac->type = igc_82545;
691*2d9fd380Sjfb8856606 break;
692*2d9fd380Sjfb8856606 case IGC_DEV_ID_82545GM_COPPER:
693*2d9fd380Sjfb8856606 case IGC_DEV_ID_82545GM_FIBER:
694*2d9fd380Sjfb8856606 case IGC_DEV_ID_82545GM_SERDES:
695*2d9fd380Sjfb8856606 mac->type = igc_82545_rev_3;
696*2d9fd380Sjfb8856606 break;
697*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546EB_COPPER:
698*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546EB_FIBER:
699*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546EB_QUAD_COPPER:
700*2d9fd380Sjfb8856606 mac->type = igc_82546;
701*2d9fd380Sjfb8856606 break;
702*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546GB_COPPER:
703*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546GB_FIBER:
704*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546GB_SERDES:
705*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546GB_PCIE:
706*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546GB_QUAD_COPPER:
707*2d9fd380Sjfb8856606 case IGC_DEV_ID_82546GB_QUAD_COPPER_KSP3:
708*2d9fd380Sjfb8856606 mac->type = igc_82546_rev_3;
709*2d9fd380Sjfb8856606 break;
710*2d9fd380Sjfb8856606 case IGC_DEV_ID_82541EI:
711*2d9fd380Sjfb8856606 case IGC_DEV_ID_82541EI_MOBILE:
712*2d9fd380Sjfb8856606 case IGC_DEV_ID_82541ER_LOM:
713*2d9fd380Sjfb8856606 mac->type = igc_82541;
714*2d9fd380Sjfb8856606 break;
715*2d9fd380Sjfb8856606 case IGC_DEV_ID_82541ER:
716*2d9fd380Sjfb8856606 case IGC_DEV_ID_82541GI:
717*2d9fd380Sjfb8856606 case IGC_DEV_ID_82541GI_LF:
718*2d9fd380Sjfb8856606 case IGC_DEV_ID_82541GI_MOBILE:
719*2d9fd380Sjfb8856606 mac->type = igc_82541_rev_2;
720*2d9fd380Sjfb8856606 break;
721*2d9fd380Sjfb8856606 case IGC_DEV_ID_82547EI:
722*2d9fd380Sjfb8856606 case IGC_DEV_ID_82547EI_MOBILE:
723*2d9fd380Sjfb8856606 mac->type = igc_82547;
724*2d9fd380Sjfb8856606 break;
725*2d9fd380Sjfb8856606 case IGC_DEV_ID_82547GI:
726*2d9fd380Sjfb8856606 mac->type = igc_82547_rev_2;
727*2d9fd380Sjfb8856606 break;
728*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_COPPER:
729*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_FIBER:
730*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_SERDES:
731*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_SERDES_DUAL:
732*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_SERDES_QUAD:
733*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_QUAD_COPPER:
734*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571PT_QUAD_COPPER:
735*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_QUAD_FIBER:
736*2d9fd380Sjfb8856606 case IGC_DEV_ID_82571EB_QUAD_COPPER_LP:
737*2d9fd380Sjfb8856606 mac->type = igc_82571;
738*2d9fd380Sjfb8856606 break;
739*2d9fd380Sjfb8856606 case IGC_DEV_ID_82572EI:
740*2d9fd380Sjfb8856606 case IGC_DEV_ID_82572EI_COPPER:
741*2d9fd380Sjfb8856606 case IGC_DEV_ID_82572EI_FIBER:
742*2d9fd380Sjfb8856606 case IGC_DEV_ID_82572EI_SERDES:
743*2d9fd380Sjfb8856606 mac->type = igc_82572;
744*2d9fd380Sjfb8856606 break;
745*2d9fd380Sjfb8856606 case IGC_DEV_ID_82573E:
746*2d9fd380Sjfb8856606 case IGC_DEV_ID_82573E_IAMT:
747*2d9fd380Sjfb8856606 case IGC_DEV_ID_82573L:
748*2d9fd380Sjfb8856606 mac->type = igc_82573;
749*2d9fd380Sjfb8856606 break;
750*2d9fd380Sjfb8856606 case IGC_DEV_ID_82574L:
751*2d9fd380Sjfb8856606 case IGC_DEV_ID_82574LA:
752*2d9fd380Sjfb8856606 mac->type = igc_82574;
753*2d9fd380Sjfb8856606 break;
754*2d9fd380Sjfb8856606 case IGC_DEV_ID_82583V:
755*2d9fd380Sjfb8856606 mac->type = igc_82583;
756*2d9fd380Sjfb8856606 break;
757*2d9fd380Sjfb8856606 case IGC_DEV_ID_80003ES2LAN_COPPER_DPT:
758*2d9fd380Sjfb8856606 case IGC_DEV_ID_80003ES2LAN_SERDES_DPT:
759*2d9fd380Sjfb8856606 case IGC_DEV_ID_80003ES2LAN_COPPER_SPT:
760*2d9fd380Sjfb8856606 case IGC_DEV_ID_80003ES2LAN_SERDES_SPT:
761*2d9fd380Sjfb8856606 mac->type = igc_80003es2lan;
762*2d9fd380Sjfb8856606 break;
763*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_IFE:
764*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_IFE_GT:
765*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_IFE_G:
766*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_IGP_M:
767*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_IGP_M_AMT:
768*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_IGP_AMT:
769*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_IGP_C:
770*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH8_82567V_3:
771*2d9fd380Sjfb8856606 mac->type = igc_ich8lan;
772*2d9fd380Sjfb8856606 break;
773*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IFE:
774*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IFE_GT:
775*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IFE_G:
776*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IGP_M:
777*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IGP_M_AMT:
778*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IGP_M_V:
779*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IGP_AMT:
780*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_BM:
781*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH9_IGP_C:
782*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH10_R_BM_LM:
783*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH10_R_BM_LF:
784*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH10_R_BM_V:
785*2d9fd380Sjfb8856606 mac->type = igc_ich9lan;
786*2d9fd380Sjfb8856606 break;
787*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH10_D_BM_LM:
788*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH10_D_BM_LF:
789*2d9fd380Sjfb8856606 case IGC_DEV_ID_ICH10_D_BM_V:
790*2d9fd380Sjfb8856606 mac->type = igc_ich10lan;
791*2d9fd380Sjfb8856606 break;
792*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_D_HV_DM:
793*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_D_HV_DC:
794*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_M_HV_LM:
795*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_M_HV_LC:
796*2d9fd380Sjfb8856606 mac->type = igc_pchlan;
797*2d9fd380Sjfb8856606 break;
798*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH2_LV_LM:
799*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH2_LV_V:
800*2d9fd380Sjfb8856606 mac->type = igc_pch2lan;
801*2d9fd380Sjfb8856606 break;
802*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_LPT_I217_LM:
803*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_LPT_I217_V:
804*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_LPTLP_I218_LM:
805*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_LPTLP_I218_V:
806*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_I218_LM2:
807*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_I218_V2:
808*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_I218_LM3:
809*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_I218_V3:
810*2d9fd380Sjfb8856606 mac->type = igc_pch_lpt;
811*2d9fd380Sjfb8856606 break;
812*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_LM:
813*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_V:
814*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_LM2:
815*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_V2:
816*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_LBG_I219_LM3:
817*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_LM4:
818*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_V4:
819*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_LM5:
820*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_SPT_I219_V5:
821*2d9fd380Sjfb8856606 mac->type = igc_pch_spt;
822*2d9fd380Sjfb8856606 break;
823*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_CNP_I219_LM6:
824*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_CNP_I219_V6:
825*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_CNP_I219_LM7:
826*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_CNP_I219_V7:
827*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_ICP_I219_LM8:
828*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_ICP_I219_V8:
829*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_ICP_I219_LM9:
830*2d9fd380Sjfb8856606 case IGC_DEV_ID_PCH_ICP_I219_V9:
831*2d9fd380Sjfb8856606 mac->type = igc_pch_cnp;
832*2d9fd380Sjfb8856606 break;
833*2d9fd380Sjfb8856606 case IGC_DEV_ID_82575EB_COPPER:
834*2d9fd380Sjfb8856606 case IGC_DEV_ID_82575EB_FIBER_SERDES:
835*2d9fd380Sjfb8856606 case IGC_DEV_ID_82575GB_QUAD_COPPER:
836*2d9fd380Sjfb8856606 mac->type = igc_82575;
837*2d9fd380Sjfb8856606 break;
838*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576:
839*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_FIBER:
840*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_SERDES:
841*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_QUAD_COPPER:
842*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_QUAD_COPPER_ET2:
843*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_NS:
844*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_NS_SERDES:
845*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_SERDES_QUAD:
846*2d9fd380Sjfb8856606 mac->type = igc_82576;
847*2d9fd380Sjfb8856606 break;
848*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_VF:
849*2d9fd380Sjfb8856606 case IGC_DEV_ID_82576_VF_HV:
850*2d9fd380Sjfb8856606 mac->type = igc_vfadapt;
851*2d9fd380Sjfb8856606 break;
852*2d9fd380Sjfb8856606 case IGC_DEV_ID_82580_COPPER:
853*2d9fd380Sjfb8856606 case IGC_DEV_ID_82580_FIBER:
854*2d9fd380Sjfb8856606 case IGC_DEV_ID_82580_SERDES:
855*2d9fd380Sjfb8856606 case IGC_DEV_ID_82580_SGMII:
856*2d9fd380Sjfb8856606 case IGC_DEV_ID_82580_COPPER_DUAL:
857*2d9fd380Sjfb8856606 case IGC_DEV_ID_82580_QUAD_FIBER:
858*2d9fd380Sjfb8856606 case IGC_DEV_ID_DH89XXCC_SGMII:
859*2d9fd380Sjfb8856606 case IGC_DEV_ID_DH89XXCC_SERDES:
860*2d9fd380Sjfb8856606 case IGC_DEV_ID_DH89XXCC_BACKPLANE:
861*2d9fd380Sjfb8856606 case IGC_DEV_ID_DH89XXCC_SFP:
862*2d9fd380Sjfb8856606 mac->type = igc_82580;
863*2d9fd380Sjfb8856606 break;
864*2d9fd380Sjfb8856606 case IGC_DEV_ID_I350_COPPER:
865*2d9fd380Sjfb8856606 case IGC_DEV_ID_I350_FIBER:
866*2d9fd380Sjfb8856606 case IGC_DEV_ID_I350_SERDES:
867*2d9fd380Sjfb8856606 case IGC_DEV_ID_I350_SGMII:
868*2d9fd380Sjfb8856606 case IGC_DEV_ID_I350_DA4:
869*2d9fd380Sjfb8856606 mac->type = igc_i350;
870*2d9fd380Sjfb8856606 break;
871*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_COPPER_FLASHLESS:
872*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_SERDES_FLASHLESS:
873*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_SGMII_FLASHLESS:
874*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_COPPER:
875*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_COPPER_OEM1:
876*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_COPPER_IT:
877*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_FIBER:
878*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_SERDES:
879*2d9fd380Sjfb8856606 case IGC_DEV_ID_I210_SGMII:
880*2d9fd380Sjfb8856606 mac->type = igc_i210;
881*2d9fd380Sjfb8856606 break;
882*2d9fd380Sjfb8856606 case IGC_DEV_ID_I211_COPPER:
883*2d9fd380Sjfb8856606 mac->type = igc_i211;
884*2d9fd380Sjfb8856606 break;
885*2d9fd380Sjfb8856606 case IGC_DEV_ID_I225_LM:
886*2d9fd380Sjfb8856606 case IGC_DEV_ID_I225_V:
887*2d9fd380Sjfb8856606 case IGC_DEV_ID_I225_K:
888*2d9fd380Sjfb8856606 case IGC_DEV_ID_I225_I:
889*2d9fd380Sjfb8856606 case IGC_DEV_ID_I220_V:
890*2d9fd380Sjfb8856606 case IGC_DEV_ID_I225_BLANK_NVM:
891*2d9fd380Sjfb8856606 mac->type = igc_i225;
892*2d9fd380Sjfb8856606 break;
893*2d9fd380Sjfb8856606 case IGC_DEV_ID_I350_VF:
894*2d9fd380Sjfb8856606 case IGC_DEV_ID_I350_VF_HV:
895*2d9fd380Sjfb8856606 mac->type = igc_vfadapt_i350;
896*2d9fd380Sjfb8856606 break;
897*2d9fd380Sjfb8856606 case IGC_DEV_ID_I354_BACKPLANE_1GBPS:
898*2d9fd380Sjfb8856606 case IGC_DEV_ID_I354_SGMII:
899*2d9fd380Sjfb8856606 case IGC_DEV_ID_I354_BACKPLANE_2_5GBPS:
900*2d9fd380Sjfb8856606 mac->type = igc_i354;
901*2d9fd380Sjfb8856606 break;
902*2d9fd380Sjfb8856606 default:
903*2d9fd380Sjfb8856606 /* Should never have loaded on this device */
904*2d9fd380Sjfb8856606 ret_val = -IGC_ERR_MAC_INIT;
905*2d9fd380Sjfb8856606 break;
906*2d9fd380Sjfb8856606 }
907*2d9fd380Sjfb8856606
908*2d9fd380Sjfb8856606 return ret_val;
909*2d9fd380Sjfb8856606 }
910*2d9fd380Sjfb8856606
911*2d9fd380Sjfb8856606 /**
912*2d9fd380Sjfb8856606 * igc_setup_init_funcs - Initializes function pointers
913*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
914*2d9fd380Sjfb8856606 * @init_device: true will initialize the rest of the function pointers
915*2d9fd380Sjfb8856606 * getting the device ready for use. false will only set
916*2d9fd380Sjfb8856606 * MAC type and the function pointers for the other init
917*2d9fd380Sjfb8856606 * functions. Passing false will not generate any hardware
918*2d9fd380Sjfb8856606 * reads or writes.
919*2d9fd380Sjfb8856606 *
920*2d9fd380Sjfb8856606 * This function must be called by a driver in order to use the rest
921*2d9fd380Sjfb8856606 * of the 'shared' code files. Called by drivers only.
922*2d9fd380Sjfb8856606 **/
igc_setup_init_funcs(struct igc_hw * hw,bool init_device)923*2d9fd380Sjfb8856606 s32 igc_setup_init_funcs(struct igc_hw *hw, bool init_device)
924*2d9fd380Sjfb8856606 {
925*2d9fd380Sjfb8856606 s32 ret_val;
926*2d9fd380Sjfb8856606
927*2d9fd380Sjfb8856606 /* Can't do much good without knowing the MAC type. */
928*2d9fd380Sjfb8856606 ret_val = igc_set_mac_type(hw);
929*2d9fd380Sjfb8856606 if (ret_val) {
930*2d9fd380Sjfb8856606 DEBUGOUT("ERROR: MAC type could not be set properly.\n");
931*2d9fd380Sjfb8856606 goto out;
932*2d9fd380Sjfb8856606 }
933*2d9fd380Sjfb8856606
934*2d9fd380Sjfb8856606 if (!hw->hw_addr) {
935*2d9fd380Sjfb8856606 DEBUGOUT("ERROR: Registers not mapped\n");
936*2d9fd380Sjfb8856606 ret_val = -IGC_ERR_CONFIG;
937*2d9fd380Sjfb8856606 goto out;
938*2d9fd380Sjfb8856606 }
939*2d9fd380Sjfb8856606
940*2d9fd380Sjfb8856606 /*
941*2d9fd380Sjfb8856606 * Init function pointers to generic implementations. We do this first
942*2d9fd380Sjfb8856606 * allowing a driver module to override it afterward.
943*2d9fd380Sjfb8856606 */
944*2d9fd380Sjfb8856606 igc_init_mac_ops_generic(hw);
945*2d9fd380Sjfb8856606 igc_init_phy_ops_generic(hw);
946*2d9fd380Sjfb8856606 igc_init_nvm_ops_generic(hw);
947*2d9fd380Sjfb8856606
948*2d9fd380Sjfb8856606 /*
949*2d9fd380Sjfb8856606 * Set up the init function pointers. These are functions within the
950*2d9fd380Sjfb8856606 * adapter family file that sets up function pointers for the rest of
951*2d9fd380Sjfb8856606 * the functions in that family.
952*2d9fd380Sjfb8856606 */
953*2d9fd380Sjfb8856606 switch (hw->mac.type) {
954*2d9fd380Sjfb8856606 case igc_i225:
955*2d9fd380Sjfb8856606 igc_init_function_pointers_i225(hw);
956*2d9fd380Sjfb8856606 break;
957*2d9fd380Sjfb8856606 default:
958*2d9fd380Sjfb8856606 DEBUGOUT("Hardware not supported\n");
959*2d9fd380Sjfb8856606 ret_val = -IGC_ERR_CONFIG;
960*2d9fd380Sjfb8856606 break;
961*2d9fd380Sjfb8856606 }
962*2d9fd380Sjfb8856606
963*2d9fd380Sjfb8856606 /*
964*2d9fd380Sjfb8856606 * Initialize the rest of the function pointers. These require some
965*2d9fd380Sjfb8856606 * register reads/writes in some cases.
966*2d9fd380Sjfb8856606 */
967*2d9fd380Sjfb8856606 if (!(ret_val) && init_device) {
968*2d9fd380Sjfb8856606 ret_val = igc_init_mac_params(hw);
969*2d9fd380Sjfb8856606 if (ret_val)
970*2d9fd380Sjfb8856606 goto out;
971*2d9fd380Sjfb8856606
972*2d9fd380Sjfb8856606 ret_val = igc_init_nvm_params(hw);
973*2d9fd380Sjfb8856606 if (ret_val)
974*2d9fd380Sjfb8856606 goto out;
975*2d9fd380Sjfb8856606
976*2d9fd380Sjfb8856606 ret_val = igc_init_phy_params(hw);
977*2d9fd380Sjfb8856606 if (ret_val)
978*2d9fd380Sjfb8856606 goto out;
979*2d9fd380Sjfb8856606 }
980*2d9fd380Sjfb8856606
981*2d9fd380Sjfb8856606 out:
982*2d9fd380Sjfb8856606 return ret_val;
983*2d9fd380Sjfb8856606 }
984*2d9fd380Sjfb8856606
985*2d9fd380Sjfb8856606 /**
986*2d9fd380Sjfb8856606 * igc_get_bus_info - Obtain bus information for adapter
987*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
988*2d9fd380Sjfb8856606 *
989*2d9fd380Sjfb8856606 * This will obtain information about the HW bus for which the
990*2d9fd380Sjfb8856606 * adapter is attached and stores it in the hw structure. This is a
991*2d9fd380Sjfb8856606 * function pointer entry point called by drivers.
992*2d9fd380Sjfb8856606 **/
igc_get_bus_info(struct igc_hw * hw)993*2d9fd380Sjfb8856606 s32 igc_get_bus_info(struct igc_hw *hw)
994*2d9fd380Sjfb8856606 {
995*2d9fd380Sjfb8856606 if (hw->mac.ops.get_bus_info)
996*2d9fd380Sjfb8856606 return hw->mac.ops.get_bus_info(hw);
997*2d9fd380Sjfb8856606
998*2d9fd380Sjfb8856606 return IGC_SUCCESS;
999*2d9fd380Sjfb8856606 }
1000*2d9fd380Sjfb8856606
1001*2d9fd380Sjfb8856606 /**
1002*2d9fd380Sjfb8856606 * igc_clear_vfta - Clear VLAN filter table
1003*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1004*2d9fd380Sjfb8856606 *
1005*2d9fd380Sjfb8856606 * This clears the VLAN filter table on the adapter. This is a function
1006*2d9fd380Sjfb8856606 * pointer entry point called by drivers.
1007*2d9fd380Sjfb8856606 **/
igc_clear_vfta(struct igc_hw * hw)1008*2d9fd380Sjfb8856606 void igc_clear_vfta(struct igc_hw *hw)
1009*2d9fd380Sjfb8856606 {
1010*2d9fd380Sjfb8856606 if (hw->mac.ops.clear_vfta)
1011*2d9fd380Sjfb8856606 hw->mac.ops.clear_vfta(hw);
1012*2d9fd380Sjfb8856606 }
1013*2d9fd380Sjfb8856606
1014*2d9fd380Sjfb8856606 /**
1015*2d9fd380Sjfb8856606 * igc_write_vfta - Write value to VLAN filter table
1016*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1017*2d9fd380Sjfb8856606 * @offset: the 32-bit offset in which to write the value to.
1018*2d9fd380Sjfb8856606 * @value: the 32-bit value to write at location offset.
1019*2d9fd380Sjfb8856606 *
1020*2d9fd380Sjfb8856606 * This writes a 32-bit value to a 32-bit offset in the VLAN filter
1021*2d9fd380Sjfb8856606 * table. This is a function pointer entry point called by drivers.
1022*2d9fd380Sjfb8856606 **/
igc_write_vfta(struct igc_hw * hw,u32 offset,u32 value)1023*2d9fd380Sjfb8856606 void igc_write_vfta(struct igc_hw *hw, u32 offset, u32 value)
1024*2d9fd380Sjfb8856606 {
1025*2d9fd380Sjfb8856606 if (hw->mac.ops.write_vfta)
1026*2d9fd380Sjfb8856606 hw->mac.ops.write_vfta(hw, offset, value);
1027*2d9fd380Sjfb8856606 }
1028*2d9fd380Sjfb8856606
1029*2d9fd380Sjfb8856606 /**
1030*2d9fd380Sjfb8856606 * igc_update_mc_addr_list - Update Multicast addresses
1031*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1032*2d9fd380Sjfb8856606 * @mc_addr_list: array of multicast addresses to program
1033*2d9fd380Sjfb8856606 * @mc_addr_count: number of multicast addresses to program
1034*2d9fd380Sjfb8856606 *
1035*2d9fd380Sjfb8856606 * Updates the Multicast Table Array.
1036*2d9fd380Sjfb8856606 * The caller must have a packed mc_addr_list of multicast addresses.
1037*2d9fd380Sjfb8856606 **/
igc_update_mc_addr_list(struct igc_hw * hw,u8 * mc_addr_list,u32 mc_addr_count)1038*2d9fd380Sjfb8856606 void igc_update_mc_addr_list(struct igc_hw *hw, u8 *mc_addr_list,
1039*2d9fd380Sjfb8856606 u32 mc_addr_count)
1040*2d9fd380Sjfb8856606 {
1041*2d9fd380Sjfb8856606 if (hw->mac.ops.update_mc_addr_list)
1042*2d9fd380Sjfb8856606 hw->mac.ops.update_mc_addr_list(hw, mc_addr_list,
1043*2d9fd380Sjfb8856606 mc_addr_count);
1044*2d9fd380Sjfb8856606 }
1045*2d9fd380Sjfb8856606
1046*2d9fd380Sjfb8856606 /**
1047*2d9fd380Sjfb8856606 * igc_force_mac_fc - Force MAC flow control
1048*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1049*2d9fd380Sjfb8856606 *
1050*2d9fd380Sjfb8856606 * Force the MAC's flow control settings. Currently no func pointer exists
1051*2d9fd380Sjfb8856606 * and all implementations are handled in the generic version of this
1052*2d9fd380Sjfb8856606 * function.
1053*2d9fd380Sjfb8856606 **/
igc_force_mac_fc(struct igc_hw * hw)1054*2d9fd380Sjfb8856606 s32 igc_force_mac_fc(struct igc_hw *hw)
1055*2d9fd380Sjfb8856606 {
1056*2d9fd380Sjfb8856606 return igc_force_mac_fc_generic(hw);
1057*2d9fd380Sjfb8856606 }
1058*2d9fd380Sjfb8856606
1059*2d9fd380Sjfb8856606 /**
1060*2d9fd380Sjfb8856606 * igc_check_for_link - Check/Store link connection
1061*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1062*2d9fd380Sjfb8856606 *
1063*2d9fd380Sjfb8856606 * This checks the link condition of the adapter and stores the
1064*2d9fd380Sjfb8856606 * results in the hw->mac structure. This is a function pointer entry
1065*2d9fd380Sjfb8856606 * point called by drivers.
1066*2d9fd380Sjfb8856606 **/
igc_check_for_link(struct igc_hw * hw)1067*2d9fd380Sjfb8856606 s32 igc_check_for_link(struct igc_hw *hw)
1068*2d9fd380Sjfb8856606 {
1069*2d9fd380Sjfb8856606 if (hw->mac.ops.check_for_link)
1070*2d9fd380Sjfb8856606 return hw->mac.ops.check_for_link(hw);
1071*2d9fd380Sjfb8856606
1072*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1073*2d9fd380Sjfb8856606 }
1074*2d9fd380Sjfb8856606
1075*2d9fd380Sjfb8856606 /**
1076*2d9fd380Sjfb8856606 * igc_check_mng_mode - Check management mode
1077*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1078*2d9fd380Sjfb8856606 *
1079*2d9fd380Sjfb8856606 * This checks if the adapter has manageability enabled.
1080*2d9fd380Sjfb8856606 * This is a function pointer entry point called by drivers.
1081*2d9fd380Sjfb8856606 **/
igc_check_mng_mode(struct igc_hw * hw)1082*2d9fd380Sjfb8856606 bool igc_check_mng_mode(struct igc_hw *hw)
1083*2d9fd380Sjfb8856606 {
1084*2d9fd380Sjfb8856606 if (hw->mac.ops.check_mng_mode)
1085*2d9fd380Sjfb8856606 return hw->mac.ops.check_mng_mode(hw);
1086*2d9fd380Sjfb8856606
1087*2d9fd380Sjfb8856606 return false;
1088*2d9fd380Sjfb8856606 }
1089*2d9fd380Sjfb8856606
1090*2d9fd380Sjfb8856606 /**
1091*2d9fd380Sjfb8856606 * igc_mng_write_dhcp_info - Writes DHCP info to host interface
1092*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1093*2d9fd380Sjfb8856606 * @buffer: pointer to the host interface
1094*2d9fd380Sjfb8856606 * @length: size of the buffer
1095*2d9fd380Sjfb8856606 *
1096*2d9fd380Sjfb8856606 * Writes the DHCP information to the host interface.
1097*2d9fd380Sjfb8856606 **/
igc_mng_write_dhcp_info(struct igc_hw * hw,u8 * buffer,u16 length)1098*2d9fd380Sjfb8856606 s32 igc_mng_write_dhcp_info(struct igc_hw *hw, u8 *buffer, u16 length)
1099*2d9fd380Sjfb8856606 {
1100*2d9fd380Sjfb8856606 return igc_mng_write_dhcp_info_generic(hw, buffer, length);
1101*2d9fd380Sjfb8856606 }
1102*2d9fd380Sjfb8856606
1103*2d9fd380Sjfb8856606 /**
1104*2d9fd380Sjfb8856606 * igc_reset_hw - Reset hardware
1105*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1106*2d9fd380Sjfb8856606 *
1107*2d9fd380Sjfb8856606 * This resets the hardware into a known state. This is a function pointer
1108*2d9fd380Sjfb8856606 * entry point called by drivers.
1109*2d9fd380Sjfb8856606 **/
igc_reset_hw(struct igc_hw * hw)1110*2d9fd380Sjfb8856606 s32 igc_reset_hw(struct igc_hw *hw)
1111*2d9fd380Sjfb8856606 {
1112*2d9fd380Sjfb8856606 if (hw->mac.ops.reset_hw)
1113*2d9fd380Sjfb8856606 return hw->mac.ops.reset_hw(hw);
1114*2d9fd380Sjfb8856606
1115*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1116*2d9fd380Sjfb8856606 }
1117*2d9fd380Sjfb8856606
1118*2d9fd380Sjfb8856606 /**
1119*2d9fd380Sjfb8856606 * igc_init_hw - Initialize hardware
1120*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1121*2d9fd380Sjfb8856606 *
1122*2d9fd380Sjfb8856606 * This inits the hardware readying it for operation. This is a function
1123*2d9fd380Sjfb8856606 * pointer entry point called by drivers.
1124*2d9fd380Sjfb8856606 **/
igc_init_hw(struct igc_hw * hw)1125*2d9fd380Sjfb8856606 s32 igc_init_hw(struct igc_hw *hw)
1126*2d9fd380Sjfb8856606 {
1127*2d9fd380Sjfb8856606 if (hw->mac.ops.init_hw)
1128*2d9fd380Sjfb8856606 return hw->mac.ops.init_hw(hw);
1129*2d9fd380Sjfb8856606
1130*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1131*2d9fd380Sjfb8856606 }
1132*2d9fd380Sjfb8856606
1133*2d9fd380Sjfb8856606 /**
1134*2d9fd380Sjfb8856606 * igc_setup_link - Configures link and flow control
1135*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1136*2d9fd380Sjfb8856606 *
1137*2d9fd380Sjfb8856606 * This configures link and flow control settings for the adapter. This
1138*2d9fd380Sjfb8856606 * is a function pointer entry point called by drivers. While modules can
1139*2d9fd380Sjfb8856606 * also call this, they probably call their own version of this function.
1140*2d9fd380Sjfb8856606 **/
igc_setup_link(struct igc_hw * hw)1141*2d9fd380Sjfb8856606 s32 igc_setup_link(struct igc_hw *hw)
1142*2d9fd380Sjfb8856606 {
1143*2d9fd380Sjfb8856606 if (hw->mac.ops.setup_link)
1144*2d9fd380Sjfb8856606 return hw->mac.ops.setup_link(hw);
1145*2d9fd380Sjfb8856606
1146*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1147*2d9fd380Sjfb8856606 }
1148*2d9fd380Sjfb8856606
1149*2d9fd380Sjfb8856606 /**
1150*2d9fd380Sjfb8856606 * igc_get_speed_and_duplex - Returns current speed and duplex
1151*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1152*2d9fd380Sjfb8856606 * @speed: pointer to a 16-bit value to store the speed
1153*2d9fd380Sjfb8856606 * @duplex: pointer to a 16-bit value to store the duplex.
1154*2d9fd380Sjfb8856606 *
1155*2d9fd380Sjfb8856606 * This returns the speed and duplex of the adapter in the two 'out'
1156*2d9fd380Sjfb8856606 * variables passed in. This is a function pointer entry point called
1157*2d9fd380Sjfb8856606 * by drivers.
1158*2d9fd380Sjfb8856606 **/
igc_get_speed_and_duplex(struct igc_hw * hw,u16 * speed,u16 * duplex)1159*2d9fd380Sjfb8856606 s32 igc_get_speed_and_duplex(struct igc_hw *hw, u16 *speed, u16 *duplex)
1160*2d9fd380Sjfb8856606 {
1161*2d9fd380Sjfb8856606 if (hw->mac.ops.get_link_up_info)
1162*2d9fd380Sjfb8856606 return hw->mac.ops.get_link_up_info(hw, speed, duplex);
1163*2d9fd380Sjfb8856606
1164*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1165*2d9fd380Sjfb8856606 }
1166*2d9fd380Sjfb8856606
1167*2d9fd380Sjfb8856606 /**
1168*2d9fd380Sjfb8856606 * igc_setup_led - Configures SW controllable LED
1169*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1170*2d9fd380Sjfb8856606 *
1171*2d9fd380Sjfb8856606 * This prepares the SW controllable LED for use and saves the current state
1172*2d9fd380Sjfb8856606 * of the LED so it can be later restored. This is a function pointer entry
1173*2d9fd380Sjfb8856606 * point called by drivers.
1174*2d9fd380Sjfb8856606 **/
igc_setup_led(struct igc_hw * hw)1175*2d9fd380Sjfb8856606 s32 igc_setup_led(struct igc_hw *hw)
1176*2d9fd380Sjfb8856606 {
1177*2d9fd380Sjfb8856606 if (hw->mac.ops.setup_led)
1178*2d9fd380Sjfb8856606 return hw->mac.ops.setup_led(hw);
1179*2d9fd380Sjfb8856606
1180*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1181*2d9fd380Sjfb8856606 }
1182*2d9fd380Sjfb8856606
1183*2d9fd380Sjfb8856606 /**
1184*2d9fd380Sjfb8856606 * igc_cleanup_led - Restores SW controllable LED
1185*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1186*2d9fd380Sjfb8856606 *
1187*2d9fd380Sjfb8856606 * This restores the SW controllable LED to the value saved off by
1188*2d9fd380Sjfb8856606 * igc_setup_led. This is a function pointer entry point called by drivers.
1189*2d9fd380Sjfb8856606 **/
igc_cleanup_led(struct igc_hw * hw)1190*2d9fd380Sjfb8856606 s32 igc_cleanup_led(struct igc_hw *hw)
1191*2d9fd380Sjfb8856606 {
1192*2d9fd380Sjfb8856606 if (hw->mac.ops.cleanup_led)
1193*2d9fd380Sjfb8856606 return hw->mac.ops.cleanup_led(hw);
1194*2d9fd380Sjfb8856606
1195*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1196*2d9fd380Sjfb8856606 }
1197*2d9fd380Sjfb8856606
1198*2d9fd380Sjfb8856606 /**
1199*2d9fd380Sjfb8856606 * igc_blink_led - Blink SW controllable LED
1200*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1201*2d9fd380Sjfb8856606 *
1202*2d9fd380Sjfb8856606 * This starts the adapter LED blinking. Request the LED to be setup first
1203*2d9fd380Sjfb8856606 * and cleaned up after. This is a function pointer entry point called by
1204*2d9fd380Sjfb8856606 * drivers.
1205*2d9fd380Sjfb8856606 **/
igc_blink_led(struct igc_hw * hw)1206*2d9fd380Sjfb8856606 s32 igc_blink_led(struct igc_hw *hw)
1207*2d9fd380Sjfb8856606 {
1208*2d9fd380Sjfb8856606 if (hw->mac.ops.blink_led)
1209*2d9fd380Sjfb8856606 return hw->mac.ops.blink_led(hw);
1210*2d9fd380Sjfb8856606
1211*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1212*2d9fd380Sjfb8856606 }
1213*2d9fd380Sjfb8856606
1214*2d9fd380Sjfb8856606 /**
1215*2d9fd380Sjfb8856606 * igc_id_led_init - store LED configurations in SW
1216*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1217*2d9fd380Sjfb8856606 *
1218*2d9fd380Sjfb8856606 * Initializes the LED config in SW. This is a function pointer entry point
1219*2d9fd380Sjfb8856606 * called by drivers.
1220*2d9fd380Sjfb8856606 **/
igc_id_led_init(struct igc_hw * hw)1221*2d9fd380Sjfb8856606 s32 igc_id_led_init(struct igc_hw *hw)
1222*2d9fd380Sjfb8856606 {
1223*2d9fd380Sjfb8856606 if (hw->mac.ops.id_led_init)
1224*2d9fd380Sjfb8856606 return hw->mac.ops.id_led_init(hw);
1225*2d9fd380Sjfb8856606
1226*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1227*2d9fd380Sjfb8856606 }
1228*2d9fd380Sjfb8856606
1229*2d9fd380Sjfb8856606 /**
1230*2d9fd380Sjfb8856606 * igc_led_on - Turn on SW controllable LED
1231*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1232*2d9fd380Sjfb8856606 *
1233*2d9fd380Sjfb8856606 * Turns the SW defined LED on. This is a function pointer entry point
1234*2d9fd380Sjfb8856606 * called by drivers.
1235*2d9fd380Sjfb8856606 **/
igc_led_on(struct igc_hw * hw)1236*2d9fd380Sjfb8856606 s32 igc_led_on(struct igc_hw *hw)
1237*2d9fd380Sjfb8856606 {
1238*2d9fd380Sjfb8856606 if (hw->mac.ops.led_on)
1239*2d9fd380Sjfb8856606 return hw->mac.ops.led_on(hw);
1240*2d9fd380Sjfb8856606
1241*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1242*2d9fd380Sjfb8856606 }
1243*2d9fd380Sjfb8856606
1244*2d9fd380Sjfb8856606 /**
1245*2d9fd380Sjfb8856606 * igc_led_off - Turn off SW controllable LED
1246*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1247*2d9fd380Sjfb8856606 *
1248*2d9fd380Sjfb8856606 * Turns the SW defined LED off. This is a function pointer entry point
1249*2d9fd380Sjfb8856606 * called by drivers.
1250*2d9fd380Sjfb8856606 **/
igc_led_off(struct igc_hw * hw)1251*2d9fd380Sjfb8856606 s32 igc_led_off(struct igc_hw *hw)
1252*2d9fd380Sjfb8856606 {
1253*2d9fd380Sjfb8856606 if (hw->mac.ops.led_off)
1254*2d9fd380Sjfb8856606 return hw->mac.ops.led_off(hw);
1255*2d9fd380Sjfb8856606
1256*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1257*2d9fd380Sjfb8856606 }
1258*2d9fd380Sjfb8856606
1259*2d9fd380Sjfb8856606 /**
1260*2d9fd380Sjfb8856606 * igc_reset_adaptive - Reset adaptive IFS
1261*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1262*2d9fd380Sjfb8856606 *
1263*2d9fd380Sjfb8856606 * Resets the adaptive IFS. Currently no func pointer exists and all
1264*2d9fd380Sjfb8856606 * implementations are handled in the generic version of this function.
1265*2d9fd380Sjfb8856606 **/
igc_reset_adaptive(struct igc_hw * hw)1266*2d9fd380Sjfb8856606 void igc_reset_adaptive(struct igc_hw *hw)
1267*2d9fd380Sjfb8856606 {
1268*2d9fd380Sjfb8856606 igc_reset_adaptive_generic(hw);
1269*2d9fd380Sjfb8856606 }
1270*2d9fd380Sjfb8856606
1271*2d9fd380Sjfb8856606 /**
1272*2d9fd380Sjfb8856606 * igc_update_adaptive - Update adaptive IFS
1273*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1274*2d9fd380Sjfb8856606 *
1275*2d9fd380Sjfb8856606 * Updates adapter IFS. Currently no func pointer exists and all
1276*2d9fd380Sjfb8856606 * implementations are handled in the generic version of this function.
1277*2d9fd380Sjfb8856606 **/
igc_update_adaptive(struct igc_hw * hw)1278*2d9fd380Sjfb8856606 void igc_update_adaptive(struct igc_hw *hw)
1279*2d9fd380Sjfb8856606 {
1280*2d9fd380Sjfb8856606 igc_update_adaptive_generic(hw);
1281*2d9fd380Sjfb8856606 }
1282*2d9fd380Sjfb8856606
1283*2d9fd380Sjfb8856606 /**
1284*2d9fd380Sjfb8856606 * igc_disable_pcie_master - Disable PCI-Express master access
1285*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1286*2d9fd380Sjfb8856606 *
1287*2d9fd380Sjfb8856606 * Disables PCI-Express master access and verifies there are no pending
1288*2d9fd380Sjfb8856606 * requests. Currently no func pointer exists and all implementations are
1289*2d9fd380Sjfb8856606 * handled in the generic version of this function.
1290*2d9fd380Sjfb8856606 **/
igc_disable_pcie_master(struct igc_hw * hw)1291*2d9fd380Sjfb8856606 s32 igc_disable_pcie_master(struct igc_hw *hw)
1292*2d9fd380Sjfb8856606 {
1293*2d9fd380Sjfb8856606 return igc_disable_pcie_master_generic(hw);
1294*2d9fd380Sjfb8856606 }
1295*2d9fd380Sjfb8856606
1296*2d9fd380Sjfb8856606 /**
1297*2d9fd380Sjfb8856606 * igc_config_collision_dist - Configure collision distance
1298*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1299*2d9fd380Sjfb8856606 *
1300*2d9fd380Sjfb8856606 * Configures the collision distance to the default value and is used
1301*2d9fd380Sjfb8856606 * during link setup.
1302*2d9fd380Sjfb8856606 **/
igc_config_collision_dist(struct igc_hw * hw)1303*2d9fd380Sjfb8856606 void igc_config_collision_dist(struct igc_hw *hw)
1304*2d9fd380Sjfb8856606 {
1305*2d9fd380Sjfb8856606 if (hw->mac.ops.config_collision_dist)
1306*2d9fd380Sjfb8856606 hw->mac.ops.config_collision_dist(hw);
1307*2d9fd380Sjfb8856606 }
1308*2d9fd380Sjfb8856606
1309*2d9fd380Sjfb8856606 /**
1310*2d9fd380Sjfb8856606 * igc_rar_set - Sets a receive address register
1311*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1312*2d9fd380Sjfb8856606 * @addr: address to set the RAR to
1313*2d9fd380Sjfb8856606 * @index: the RAR to set
1314*2d9fd380Sjfb8856606 *
1315*2d9fd380Sjfb8856606 * Sets a Receive Address Register (RAR) to the specified address.
1316*2d9fd380Sjfb8856606 **/
igc_rar_set(struct igc_hw * hw,u8 * addr,u32 index)1317*2d9fd380Sjfb8856606 int igc_rar_set(struct igc_hw *hw, u8 *addr, u32 index)
1318*2d9fd380Sjfb8856606 {
1319*2d9fd380Sjfb8856606 if (hw->mac.ops.rar_set)
1320*2d9fd380Sjfb8856606 return hw->mac.ops.rar_set(hw, addr, index);
1321*2d9fd380Sjfb8856606
1322*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1323*2d9fd380Sjfb8856606 }
1324*2d9fd380Sjfb8856606
1325*2d9fd380Sjfb8856606 /**
1326*2d9fd380Sjfb8856606 * igc_validate_mdi_setting - Ensures valid MDI/MDIX SW state
1327*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1328*2d9fd380Sjfb8856606 *
1329*2d9fd380Sjfb8856606 * Ensures that the MDI/MDIX SW state is valid.
1330*2d9fd380Sjfb8856606 **/
igc_validate_mdi_setting(struct igc_hw * hw)1331*2d9fd380Sjfb8856606 s32 igc_validate_mdi_setting(struct igc_hw *hw)
1332*2d9fd380Sjfb8856606 {
1333*2d9fd380Sjfb8856606 if (hw->mac.ops.validate_mdi_setting)
1334*2d9fd380Sjfb8856606 return hw->mac.ops.validate_mdi_setting(hw);
1335*2d9fd380Sjfb8856606
1336*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1337*2d9fd380Sjfb8856606 }
1338*2d9fd380Sjfb8856606
1339*2d9fd380Sjfb8856606 /**
1340*2d9fd380Sjfb8856606 * igc_hash_mc_addr - Determines address location in multicast table
1341*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1342*2d9fd380Sjfb8856606 * @mc_addr: Multicast address to hash.
1343*2d9fd380Sjfb8856606 *
1344*2d9fd380Sjfb8856606 * This hashes an address to determine its location in the multicast
1345*2d9fd380Sjfb8856606 * table. Currently no func pointer exists and all implementations
1346*2d9fd380Sjfb8856606 * are handled in the generic version of this function.
1347*2d9fd380Sjfb8856606 **/
igc_hash_mc_addr(struct igc_hw * hw,u8 * mc_addr)1348*2d9fd380Sjfb8856606 u32 igc_hash_mc_addr(struct igc_hw *hw, u8 *mc_addr)
1349*2d9fd380Sjfb8856606 {
1350*2d9fd380Sjfb8856606 return igc_hash_mc_addr_generic(hw, mc_addr);
1351*2d9fd380Sjfb8856606 }
1352*2d9fd380Sjfb8856606
1353*2d9fd380Sjfb8856606 /**
1354*2d9fd380Sjfb8856606 * igc_enable_tx_pkt_filtering - Enable packet filtering on TX
1355*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1356*2d9fd380Sjfb8856606 *
1357*2d9fd380Sjfb8856606 * Enables packet filtering on transmit packets if manageability is enabled
1358*2d9fd380Sjfb8856606 * and host interface is enabled.
1359*2d9fd380Sjfb8856606 * Currently no func pointer exists and all implementations are handled in the
1360*2d9fd380Sjfb8856606 * generic version of this function.
1361*2d9fd380Sjfb8856606 **/
igc_enable_tx_pkt_filtering(struct igc_hw * hw)1362*2d9fd380Sjfb8856606 bool igc_enable_tx_pkt_filtering(struct igc_hw *hw)
1363*2d9fd380Sjfb8856606 {
1364*2d9fd380Sjfb8856606 return igc_enable_tx_pkt_filtering_generic(hw);
1365*2d9fd380Sjfb8856606 }
1366*2d9fd380Sjfb8856606
1367*2d9fd380Sjfb8856606 /**
1368*2d9fd380Sjfb8856606 * igc_mng_host_if_write - Writes to the manageability host interface
1369*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1370*2d9fd380Sjfb8856606 * @buffer: pointer to the host interface buffer
1371*2d9fd380Sjfb8856606 * @length: size of the buffer
1372*2d9fd380Sjfb8856606 * @offset: location in the buffer to write to
1373*2d9fd380Sjfb8856606 * @sum: sum of the data (not checksum)
1374*2d9fd380Sjfb8856606 *
1375*2d9fd380Sjfb8856606 * This function writes the buffer content at the offset given on the host if.
1376*2d9fd380Sjfb8856606 * It also does alignment considerations to do the writes in most efficient
1377*2d9fd380Sjfb8856606 * way. Also fills up the sum of the buffer in *buffer parameter.
1378*2d9fd380Sjfb8856606 **/
igc_mng_host_if_write(struct igc_hw * hw,u8 * buffer,u16 length,u16 offset,u8 * sum)1379*2d9fd380Sjfb8856606 s32 igc_mng_host_if_write(struct igc_hw *hw, u8 *buffer, u16 length,
1380*2d9fd380Sjfb8856606 u16 offset, u8 *sum)
1381*2d9fd380Sjfb8856606 {
1382*2d9fd380Sjfb8856606 return igc_mng_host_if_write_generic(hw, buffer, length, offset, sum);
1383*2d9fd380Sjfb8856606 }
1384*2d9fd380Sjfb8856606
1385*2d9fd380Sjfb8856606 /**
1386*2d9fd380Sjfb8856606 * igc_mng_write_cmd_header - Writes manageability command header
1387*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1388*2d9fd380Sjfb8856606 * @hdr: pointer to the host interface command header
1389*2d9fd380Sjfb8856606 *
1390*2d9fd380Sjfb8856606 * Writes the command header after does the checksum calculation.
1391*2d9fd380Sjfb8856606 **/
igc_mng_write_cmd_header(struct igc_hw * hw,struct igc_host_mng_command_header * hdr)1392*2d9fd380Sjfb8856606 s32 igc_mng_write_cmd_header(struct igc_hw *hw,
1393*2d9fd380Sjfb8856606 struct igc_host_mng_command_header *hdr)
1394*2d9fd380Sjfb8856606 {
1395*2d9fd380Sjfb8856606 return igc_mng_write_cmd_header_generic(hw, hdr);
1396*2d9fd380Sjfb8856606 }
1397*2d9fd380Sjfb8856606
1398*2d9fd380Sjfb8856606 /**
1399*2d9fd380Sjfb8856606 * igc_mng_enable_host_if - Checks host interface is enabled
1400*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1401*2d9fd380Sjfb8856606 *
1402*2d9fd380Sjfb8856606 * Returns IGC_success upon success, else IGC_ERR_HOST_INTERFACE_COMMAND
1403*2d9fd380Sjfb8856606 *
1404*2d9fd380Sjfb8856606 * This function checks whether the HOST IF is enabled for command operation
1405*2d9fd380Sjfb8856606 * and also checks whether the previous command is completed. It busy waits
1406*2d9fd380Sjfb8856606 * in case of previous command is not completed.
1407*2d9fd380Sjfb8856606 **/
igc_mng_enable_host_if(struct igc_hw * hw)1408*2d9fd380Sjfb8856606 s32 igc_mng_enable_host_if(struct igc_hw *hw)
1409*2d9fd380Sjfb8856606 {
1410*2d9fd380Sjfb8856606 return igc_mng_enable_host_if_generic(hw);
1411*2d9fd380Sjfb8856606 }
1412*2d9fd380Sjfb8856606
1413*2d9fd380Sjfb8856606 /**
1414*2d9fd380Sjfb8856606 * igc_check_reset_block - Verifies PHY can be reset
1415*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1416*2d9fd380Sjfb8856606 *
1417*2d9fd380Sjfb8856606 * Checks if the PHY is in a state that can be reset or if manageability
1418*2d9fd380Sjfb8856606 * has it tied up. This is a function pointer entry point called by drivers.
1419*2d9fd380Sjfb8856606 **/
igc_check_reset_block(struct igc_hw * hw)1420*2d9fd380Sjfb8856606 s32 igc_check_reset_block(struct igc_hw *hw)
1421*2d9fd380Sjfb8856606 {
1422*2d9fd380Sjfb8856606 if (hw->phy.ops.check_reset_block)
1423*2d9fd380Sjfb8856606 return hw->phy.ops.check_reset_block(hw);
1424*2d9fd380Sjfb8856606
1425*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1426*2d9fd380Sjfb8856606 }
1427*2d9fd380Sjfb8856606
1428*2d9fd380Sjfb8856606 /**
1429*2d9fd380Sjfb8856606 * igc_read_phy_reg - Reads PHY register
1430*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1431*2d9fd380Sjfb8856606 * @offset: the register to read
1432*2d9fd380Sjfb8856606 * @data: the buffer to store the 16-bit read.
1433*2d9fd380Sjfb8856606 *
1434*2d9fd380Sjfb8856606 * Reads the PHY register and returns the value in data.
1435*2d9fd380Sjfb8856606 * This is a function pointer entry point called by drivers.
1436*2d9fd380Sjfb8856606 **/
igc_read_phy_reg(struct igc_hw * hw,u32 offset,u16 * data)1437*2d9fd380Sjfb8856606 s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data)
1438*2d9fd380Sjfb8856606 {
1439*2d9fd380Sjfb8856606 if (hw->phy.ops.read_reg)
1440*2d9fd380Sjfb8856606 return hw->phy.ops.read_reg(hw, offset, data);
1441*2d9fd380Sjfb8856606
1442*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1443*2d9fd380Sjfb8856606 }
1444*2d9fd380Sjfb8856606
1445*2d9fd380Sjfb8856606 /**
1446*2d9fd380Sjfb8856606 * igc_write_phy_reg - Writes PHY register
1447*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1448*2d9fd380Sjfb8856606 * @offset: the register to write
1449*2d9fd380Sjfb8856606 * @data: the value to write.
1450*2d9fd380Sjfb8856606 *
1451*2d9fd380Sjfb8856606 * Writes the PHY register at offset with the value in data.
1452*2d9fd380Sjfb8856606 * This is a function pointer entry point called by drivers.
1453*2d9fd380Sjfb8856606 **/
igc_write_phy_reg(struct igc_hw * hw,u32 offset,u16 data)1454*2d9fd380Sjfb8856606 s32 igc_write_phy_reg(struct igc_hw *hw, u32 offset, u16 data)
1455*2d9fd380Sjfb8856606 {
1456*2d9fd380Sjfb8856606 if (hw->phy.ops.write_reg)
1457*2d9fd380Sjfb8856606 return hw->phy.ops.write_reg(hw, offset, data);
1458*2d9fd380Sjfb8856606
1459*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1460*2d9fd380Sjfb8856606 }
1461*2d9fd380Sjfb8856606
1462*2d9fd380Sjfb8856606 /**
1463*2d9fd380Sjfb8856606 * igc_release_phy - Generic release PHY
1464*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1465*2d9fd380Sjfb8856606 *
1466*2d9fd380Sjfb8856606 * Return if silicon family does not require a semaphore when accessing the
1467*2d9fd380Sjfb8856606 * PHY.
1468*2d9fd380Sjfb8856606 **/
igc_release_phy(struct igc_hw * hw)1469*2d9fd380Sjfb8856606 void igc_release_phy(struct igc_hw *hw)
1470*2d9fd380Sjfb8856606 {
1471*2d9fd380Sjfb8856606 if (hw->phy.ops.release)
1472*2d9fd380Sjfb8856606 hw->phy.ops.release(hw);
1473*2d9fd380Sjfb8856606 }
1474*2d9fd380Sjfb8856606
1475*2d9fd380Sjfb8856606 /**
1476*2d9fd380Sjfb8856606 * igc_acquire_phy - Generic acquire PHY
1477*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1478*2d9fd380Sjfb8856606 *
1479*2d9fd380Sjfb8856606 * Return success if silicon family does not require a semaphore when
1480*2d9fd380Sjfb8856606 * accessing the PHY.
1481*2d9fd380Sjfb8856606 **/
igc_acquire_phy(struct igc_hw * hw)1482*2d9fd380Sjfb8856606 s32 igc_acquire_phy(struct igc_hw *hw)
1483*2d9fd380Sjfb8856606 {
1484*2d9fd380Sjfb8856606 if (hw->phy.ops.acquire)
1485*2d9fd380Sjfb8856606 return hw->phy.ops.acquire(hw);
1486*2d9fd380Sjfb8856606
1487*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1488*2d9fd380Sjfb8856606 }
1489*2d9fd380Sjfb8856606
1490*2d9fd380Sjfb8856606 /**
1491*2d9fd380Sjfb8856606 * igc_cfg_on_link_up - Configure PHY upon link up
1492*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1493*2d9fd380Sjfb8856606 **/
igc_cfg_on_link_up(struct igc_hw * hw)1494*2d9fd380Sjfb8856606 s32 igc_cfg_on_link_up(struct igc_hw *hw)
1495*2d9fd380Sjfb8856606 {
1496*2d9fd380Sjfb8856606 if (hw->phy.ops.cfg_on_link_up)
1497*2d9fd380Sjfb8856606 return hw->phy.ops.cfg_on_link_up(hw);
1498*2d9fd380Sjfb8856606
1499*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1500*2d9fd380Sjfb8856606 }
1501*2d9fd380Sjfb8856606
1502*2d9fd380Sjfb8856606 /**
1503*2d9fd380Sjfb8856606 * igc_read_kmrn_reg - Reads register using Kumeran interface
1504*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1505*2d9fd380Sjfb8856606 * @offset: the register to read
1506*2d9fd380Sjfb8856606 * @data: the location to store the 16-bit value read.
1507*2d9fd380Sjfb8856606 *
1508*2d9fd380Sjfb8856606 * Reads a register out of the Kumeran interface. Currently no func pointer
1509*2d9fd380Sjfb8856606 * exists and all implementations are handled in the generic version of
1510*2d9fd380Sjfb8856606 * this function.
1511*2d9fd380Sjfb8856606 **/
igc_read_kmrn_reg(struct igc_hw * hw,u32 offset,u16 * data)1512*2d9fd380Sjfb8856606 s32 igc_read_kmrn_reg(struct igc_hw *hw, u32 offset, u16 *data)
1513*2d9fd380Sjfb8856606 {
1514*2d9fd380Sjfb8856606 return igc_read_kmrn_reg_generic(hw, offset, data);
1515*2d9fd380Sjfb8856606 }
1516*2d9fd380Sjfb8856606
1517*2d9fd380Sjfb8856606 /**
1518*2d9fd380Sjfb8856606 * igc_write_kmrn_reg - Writes register using Kumeran interface
1519*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1520*2d9fd380Sjfb8856606 * @offset: the register to write
1521*2d9fd380Sjfb8856606 * @data: the value to write.
1522*2d9fd380Sjfb8856606 *
1523*2d9fd380Sjfb8856606 * Writes a register to the Kumeran interface. Currently no func pointer
1524*2d9fd380Sjfb8856606 * exists and all implementations are handled in the generic version of
1525*2d9fd380Sjfb8856606 * this function.
1526*2d9fd380Sjfb8856606 **/
igc_write_kmrn_reg(struct igc_hw * hw,u32 offset,u16 data)1527*2d9fd380Sjfb8856606 s32 igc_write_kmrn_reg(struct igc_hw *hw, u32 offset, u16 data)
1528*2d9fd380Sjfb8856606 {
1529*2d9fd380Sjfb8856606 return igc_write_kmrn_reg_generic(hw, offset, data);
1530*2d9fd380Sjfb8856606 }
1531*2d9fd380Sjfb8856606
1532*2d9fd380Sjfb8856606 /**
1533*2d9fd380Sjfb8856606 * igc_get_cable_length - Retrieves cable length estimation
1534*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1535*2d9fd380Sjfb8856606 *
1536*2d9fd380Sjfb8856606 * This function estimates the cable length and stores them in
1537*2d9fd380Sjfb8856606 * hw->phy.min_length and hw->phy.max_length. This is a function pointer
1538*2d9fd380Sjfb8856606 * entry point called by drivers.
1539*2d9fd380Sjfb8856606 **/
igc_get_cable_length(struct igc_hw * hw)1540*2d9fd380Sjfb8856606 s32 igc_get_cable_length(struct igc_hw *hw)
1541*2d9fd380Sjfb8856606 {
1542*2d9fd380Sjfb8856606 if (hw->phy.ops.get_cable_length)
1543*2d9fd380Sjfb8856606 return hw->phy.ops.get_cable_length(hw);
1544*2d9fd380Sjfb8856606
1545*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1546*2d9fd380Sjfb8856606 }
1547*2d9fd380Sjfb8856606
1548*2d9fd380Sjfb8856606 /**
1549*2d9fd380Sjfb8856606 * igc_get_phy_info - Retrieves PHY information from registers
1550*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1551*2d9fd380Sjfb8856606 *
1552*2d9fd380Sjfb8856606 * This function gets some information from various PHY registers and
1553*2d9fd380Sjfb8856606 * populates hw->phy values with it. This is a function pointer entry
1554*2d9fd380Sjfb8856606 * point called by drivers.
1555*2d9fd380Sjfb8856606 **/
igc_get_phy_info(struct igc_hw * hw)1556*2d9fd380Sjfb8856606 s32 igc_get_phy_info(struct igc_hw *hw)
1557*2d9fd380Sjfb8856606 {
1558*2d9fd380Sjfb8856606 if (hw->phy.ops.get_info)
1559*2d9fd380Sjfb8856606 return hw->phy.ops.get_info(hw);
1560*2d9fd380Sjfb8856606
1561*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1562*2d9fd380Sjfb8856606 }
1563*2d9fd380Sjfb8856606
1564*2d9fd380Sjfb8856606 /**
1565*2d9fd380Sjfb8856606 * igc_phy_hw_reset - Hard PHY reset
1566*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1567*2d9fd380Sjfb8856606 *
1568*2d9fd380Sjfb8856606 * Performs a hard PHY reset. This is a function pointer entry point called
1569*2d9fd380Sjfb8856606 * by drivers.
1570*2d9fd380Sjfb8856606 **/
igc_phy_hw_reset(struct igc_hw * hw)1571*2d9fd380Sjfb8856606 s32 igc_phy_hw_reset(struct igc_hw *hw)
1572*2d9fd380Sjfb8856606 {
1573*2d9fd380Sjfb8856606 if (hw->phy.ops.reset)
1574*2d9fd380Sjfb8856606 return hw->phy.ops.reset(hw);
1575*2d9fd380Sjfb8856606
1576*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1577*2d9fd380Sjfb8856606 }
1578*2d9fd380Sjfb8856606
1579*2d9fd380Sjfb8856606 /**
1580*2d9fd380Sjfb8856606 * igc_phy_commit - Soft PHY reset
1581*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1582*2d9fd380Sjfb8856606 *
1583*2d9fd380Sjfb8856606 * Performs a soft PHY reset on those that apply. This is a function pointer
1584*2d9fd380Sjfb8856606 * entry point called by drivers.
1585*2d9fd380Sjfb8856606 **/
igc_phy_commit(struct igc_hw * hw)1586*2d9fd380Sjfb8856606 s32 igc_phy_commit(struct igc_hw *hw)
1587*2d9fd380Sjfb8856606 {
1588*2d9fd380Sjfb8856606 if (hw->phy.ops.commit)
1589*2d9fd380Sjfb8856606 return hw->phy.ops.commit(hw);
1590*2d9fd380Sjfb8856606
1591*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1592*2d9fd380Sjfb8856606 }
1593*2d9fd380Sjfb8856606
1594*2d9fd380Sjfb8856606 /**
1595*2d9fd380Sjfb8856606 * igc_set_d0_lplu_state - Sets low power link up state for D0
1596*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1597*2d9fd380Sjfb8856606 * @active: boolean used to enable/disable lplu
1598*2d9fd380Sjfb8856606 *
1599*2d9fd380Sjfb8856606 * Success returns 0, Failure returns 1
1600*2d9fd380Sjfb8856606 *
1601*2d9fd380Sjfb8856606 * The low power link up (lplu) state is set to the power management level D0
1602*2d9fd380Sjfb8856606 * and SmartSpeed is disabled when active is true, else clear lplu for D0
1603*2d9fd380Sjfb8856606 * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
1604*2d9fd380Sjfb8856606 * is used during Dx states where the power conservation is most important.
1605*2d9fd380Sjfb8856606 * During driver activity, SmartSpeed should be enabled so performance is
1606*2d9fd380Sjfb8856606 * maintained. This is a function pointer entry point called by drivers.
1607*2d9fd380Sjfb8856606 **/
igc_set_d0_lplu_state(struct igc_hw * hw,bool active)1608*2d9fd380Sjfb8856606 s32 igc_set_d0_lplu_state(struct igc_hw *hw, bool active)
1609*2d9fd380Sjfb8856606 {
1610*2d9fd380Sjfb8856606 if (hw->phy.ops.set_d0_lplu_state)
1611*2d9fd380Sjfb8856606 return hw->phy.ops.set_d0_lplu_state(hw, active);
1612*2d9fd380Sjfb8856606
1613*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1614*2d9fd380Sjfb8856606 }
1615*2d9fd380Sjfb8856606
1616*2d9fd380Sjfb8856606 /**
1617*2d9fd380Sjfb8856606 * igc_set_d3_lplu_state - Sets low power link up state for D3
1618*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1619*2d9fd380Sjfb8856606 * @active: boolean used to enable/disable lplu
1620*2d9fd380Sjfb8856606 *
1621*2d9fd380Sjfb8856606 * Success returns 0, Failure returns 1
1622*2d9fd380Sjfb8856606 *
1623*2d9fd380Sjfb8856606 * The low power link up (lplu) state is set to the power management level D3
1624*2d9fd380Sjfb8856606 * and SmartSpeed is disabled when active is true, else clear lplu for D3
1625*2d9fd380Sjfb8856606 * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU
1626*2d9fd380Sjfb8856606 * is used during Dx states where the power conservation is most important.
1627*2d9fd380Sjfb8856606 * During driver activity, SmartSpeed should be enabled so performance is
1628*2d9fd380Sjfb8856606 * maintained. This is a function pointer entry point called by drivers.
1629*2d9fd380Sjfb8856606 **/
igc_set_d3_lplu_state(struct igc_hw * hw,bool active)1630*2d9fd380Sjfb8856606 s32 igc_set_d3_lplu_state(struct igc_hw *hw, bool active)
1631*2d9fd380Sjfb8856606 {
1632*2d9fd380Sjfb8856606 if (hw->phy.ops.set_d3_lplu_state)
1633*2d9fd380Sjfb8856606 return hw->phy.ops.set_d3_lplu_state(hw, active);
1634*2d9fd380Sjfb8856606
1635*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1636*2d9fd380Sjfb8856606 }
1637*2d9fd380Sjfb8856606
1638*2d9fd380Sjfb8856606 /**
1639*2d9fd380Sjfb8856606 * igc_read_mac_addr - Reads MAC address
1640*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1641*2d9fd380Sjfb8856606 *
1642*2d9fd380Sjfb8856606 * Reads the MAC address out of the adapter and stores it in the HW structure.
1643*2d9fd380Sjfb8856606 * Currently no func pointer exists and all implementations are handled in the
1644*2d9fd380Sjfb8856606 * generic version of this function.
1645*2d9fd380Sjfb8856606 **/
igc_read_mac_addr(struct igc_hw * hw)1646*2d9fd380Sjfb8856606 s32 igc_read_mac_addr(struct igc_hw *hw)
1647*2d9fd380Sjfb8856606 {
1648*2d9fd380Sjfb8856606 if (hw->mac.ops.read_mac_addr)
1649*2d9fd380Sjfb8856606 return hw->mac.ops.read_mac_addr(hw);
1650*2d9fd380Sjfb8856606
1651*2d9fd380Sjfb8856606 return igc_read_mac_addr_generic(hw);
1652*2d9fd380Sjfb8856606 }
1653*2d9fd380Sjfb8856606
1654*2d9fd380Sjfb8856606 /**
1655*2d9fd380Sjfb8856606 * igc_read_pba_string - Read device part number string
1656*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1657*2d9fd380Sjfb8856606 * @pba_num: pointer to device part number
1658*2d9fd380Sjfb8856606 * @pba_num_size: size of part number buffer
1659*2d9fd380Sjfb8856606 *
1660*2d9fd380Sjfb8856606 * Reads the product board assembly (PBA) number from the EEPROM and stores
1661*2d9fd380Sjfb8856606 * the value in pba_num.
1662*2d9fd380Sjfb8856606 * Currently no func pointer exists and all implementations are handled in the
1663*2d9fd380Sjfb8856606 * generic version of this function.
1664*2d9fd380Sjfb8856606 **/
igc_read_pba_string(struct igc_hw * hw,u8 * pba_num,u32 pba_num_size)1665*2d9fd380Sjfb8856606 s32 igc_read_pba_string(struct igc_hw *hw, u8 *pba_num, u32 pba_num_size)
1666*2d9fd380Sjfb8856606 {
1667*2d9fd380Sjfb8856606 return igc_read_pba_string_generic(hw, pba_num, pba_num_size);
1668*2d9fd380Sjfb8856606 }
1669*2d9fd380Sjfb8856606
1670*2d9fd380Sjfb8856606 /**
1671*2d9fd380Sjfb8856606 * igc_read_pba_length - Read device part number string length
1672*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1673*2d9fd380Sjfb8856606 * @pba_num_size: size of part number buffer
1674*2d9fd380Sjfb8856606 *
1675*2d9fd380Sjfb8856606 * Reads the product board assembly (PBA) number length from the EEPROM and
1676*2d9fd380Sjfb8856606 * stores the value in pba_num.
1677*2d9fd380Sjfb8856606 * Currently no func pointer exists and all implementations are handled in the
1678*2d9fd380Sjfb8856606 * generic version of this function.
1679*2d9fd380Sjfb8856606 **/
igc_read_pba_length(struct igc_hw * hw,u32 * pba_num_size)1680*2d9fd380Sjfb8856606 s32 igc_read_pba_length(struct igc_hw *hw, u32 *pba_num_size)
1681*2d9fd380Sjfb8856606 {
1682*2d9fd380Sjfb8856606 return igc_read_pba_length_generic(hw, pba_num_size);
1683*2d9fd380Sjfb8856606 }
1684*2d9fd380Sjfb8856606
1685*2d9fd380Sjfb8856606 /**
1686*2d9fd380Sjfb8856606 * igc_read_pba_num - Read device part number
1687*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1688*2d9fd380Sjfb8856606 * @pba_num: pointer to device part number
1689*2d9fd380Sjfb8856606 *
1690*2d9fd380Sjfb8856606 * Reads the product board assembly (PBA) number from the EEPROM and stores
1691*2d9fd380Sjfb8856606 * the value in pba_num.
1692*2d9fd380Sjfb8856606 * Currently no func pointer exists and all implementations are handled in the
1693*2d9fd380Sjfb8856606 * generic version of this function.
1694*2d9fd380Sjfb8856606 **/
igc_read_pba_num(struct igc_hw * hw,u32 * pba_num)1695*2d9fd380Sjfb8856606 s32 igc_read_pba_num(struct igc_hw *hw, u32 *pba_num)
1696*2d9fd380Sjfb8856606 {
1697*2d9fd380Sjfb8856606 return igc_read_pba_num_generic(hw, pba_num);
1698*2d9fd380Sjfb8856606 }
1699*2d9fd380Sjfb8856606
1700*2d9fd380Sjfb8856606 /**
1701*2d9fd380Sjfb8856606 * igc_validate_nvm_checksum - Verifies NVM (EEPROM) checksum
1702*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1703*2d9fd380Sjfb8856606 *
1704*2d9fd380Sjfb8856606 * Validates the NVM checksum is correct. This is a function pointer entry
1705*2d9fd380Sjfb8856606 * point called by drivers.
1706*2d9fd380Sjfb8856606 **/
igc_validate_nvm_checksum(struct igc_hw * hw)1707*2d9fd380Sjfb8856606 s32 igc_validate_nvm_checksum(struct igc_hw *hw)
1708*2d9fd380Sjfb8856606 {
1709*2d9fd380Sjfb8856606 if (hw->nvm.ops.validate)
1710*2d9fd380Sjfb8856606 return hw->nvm.ops.validate(hw);
1711*2d9fd380Sjfb8856606
1712*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1713*2d9fd380Sjfb8856606 }
1714*2d9fd380Sjfb8856606
1715*2d9fd380Sjfb8856606 /**
1716*2d9fd380Sjfb8856606 * igc_update_nvm_checksum - Updates NVM (EEPROM) checksum
1717*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1718*2d9fd380Sjfb8856606 *
1719*2d9fd380Sjfb8856606 * Updates the NVM checksum. Currently no func pointer exists and all
1720*2d9fd380Sjfb8856606 * implementations are handled in the generic version of this function.
1721*2d9fd380Sjfb8856606 **/
igc_update_nvm_checksum(struct igc_hw * hw)1722*2d9fd380Sjfb8856606 s32 igc_update_nvm_checksum(struct igc_hw *hw)
1723*2d9fd380Sjfb8856606 {
1724*2d9fd380Sjfb8856606 if (hw->nvm.ops.update)
1725*2d9fd380Sjfb8856606 return hw->nvm.ops.update(hw);
1726*2d9fd380Sjfb8856606
1727*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1728*2d9fd380Sjfb8856606 }
1729*2d9fd380Sjfb8856606
1730*2d9fd380Sjfb8856606 /**
1731*2d9fd380Sjfb8856606 * igc_reload_nvm - Reloads EEPROM
1732*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1733*2d9fd380Sjfb8856606 *
1734*2d9fd380Sjfb8856606 * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
1735*2d9fd380Sjfb8856606 * extended control register.
1736*2d9fd380Sjfb8856606 **/
igc_reload_nvm(struct igc_hw * hw)1737*2d9fd380Sjfb8856606 void igc_reload_nvm(struct igc_hw *hw)
1738*2d9fd380Sjfb8856606 {
1739*2d9fd380Sjfb8856606 if (hw->nvm.ops.reload)
1740*2d9fd380Sjfb8856606 hw->nvm.ops.reload(hw);
1741*2d9fd380Sjfb8856606 }
1742*2d9fd380Sjfb8856606
1743*2d9fd380Sjfb8856606 /**
1744*2d9fd380Sjfb8856606 * igc_read_nvm - Reads NVM (EEPROM)
1745*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1746*2d9fd380Sjfb8856606 * @offset: the word offset to read
1747*2d9fd380Sjfb8856606 * @words: number of 16-bit words to read
1748*2d9fd380Sjfb8856606 * @data: pointer to the properly sized buffer for the data.
1749*2d9fd380Sjfb8856606 *
1750*2d9fd380Sjfb8856606 * Reads 16-bit chunks of data from the NVM (EEPROM). This is a function
1751*2d9fd380Sjfb8856606 * pointer entry point called by drivers.
1752*2d9fd380Sjfb8856606 **/
igc_read_nvm(struct igc_hw * hw,u16 offset,u16 words,u16 * data)1753*2d9fd380Sjfb8856606 s32 igc_read_nvm(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
1754*2d9fd380Sjfb8856606 {
1755*2d9fd380Sjfb8856606 if (hw->nvm.ops.read)
1756*2d9fd380Sjfb8856606 return hw->nvm.ops.read(hw, offset, words, data);
1757*2d9fd380Sjfb8856606
1758*2d9fd380Sjfb8856606 return -IGC_ERR_CONFIG;
1759*2d9fd380Sjfb8856606 }
1760*2d9fd380Sjfb8856606
1761*2d9fd380Sjfb8856606 /**
1762*2d9fd380Sjfb8856606 * igc_write_nvm - Writes to NVM (EEPROM)
1763*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1764*2d9fd380Sjfb8856606 * @offset: the word offset to read
1765*2d9fd380Sjfb8856606 * @words: number of 16-bit words to write
1766*2d9fd380Sjfb8856606 * @data: pointer to the properly sized buffer for the data.
1767*2d9fd380Sjfb8856606 *
1768*2d9fd380Sjfb8856606 * Writes 16-bit chunks of data to the NVM (EEPROM). This is a function
1769*2d9fd380Sjfb8856606 * pointer entry point called by drivers.
1770*2d9fd380Sjfb8856606 **/
igc_write_nvm(struct igc_hw * hw,u16 offset,u16 words,u16 * data)1771*2d9fd380Sjfb8856606 s32 igc_write_nvm(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
1772*2d9fd380Sjfb8856606 {
1773*2d9fd380Sjfb8856606 if (hw->nvm.ops.write)
1774*2d9fd380Sjfb8856606 return hw->nvm.ops.write(hw, offset, words, data);
1775*2d9fd380Sjfb8856606
1776*2d9fd380Sjfb8856606 return IGC_SUCCESS;
1777*2d9fd380Sjfb8856606 }
1778*2d9fd380Sjfb8856606
1779*2d9fd380Sjfb8856606 /**
1780*2d9fd380Sjfb8856606 * igc_write_8bit_ctrl_reg - Writes 8bit Control register
1781*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1782*2d9fd380Sjfb8856606 * @reg: 32bit register offset
1783*2d9fd380Sjfb8856606 * @offset: the register to write
1784*2d9fd380Sjfb8856606 * @data: the value to write.
1785*2d9fd380Sjfb8856606 *
1786*2d9fd380Sjfb8856606 * Writes the PHY register at offset with the value in data.
1787*2d9fd380Sjfb8856606 * This is a function pointer entry point called by drivers.
1788*2d9fd380Sjfb8856606 **/
igc_write_8bit_ctrl_reg(struct igc_hw * hw,u32 reg,u32 offset,u8 data)1789*2d9fd380Sjfb8856606 s32 igc_write_8bit_ctrl_reg(struct igc_hw *hw, u32 reg, u32 offset,
1790*2d9fd380Sjfb8856606 u8 data)
1791*2d9fd380Sjfb8856606 {
1792*2d9fd380Sjfb8856606 return igc_write_8bit_ctrl_reg_generic(hw, reg, offset, data);
1793*2d9fd380Sjfb8856606 }
1794*2d9fd380Sjfb8856606
1795*2d9fd380Sjfb8856606 /**
1796*2d9fd380Sjfb8856606 * igc_power_up_phy - Restores link in case of PHY power down
1797*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1798*2d9fd380Sjfb8856606 *
1799*2d9fd380Sjfb8856606 * The phy may be powered down to save power, to turn off link when the
1800*2d9fd380Sjfb8856606 * driver is unloaded, or wake on lan is not enabled (among others).
1801*2d9fd380Sjfb8856606 **/
igc_power_up_phy(struct igc_hw * hw)1802*2d9fd380Sjfb8856606 void igc_power_up_phy(struct igc_hw *hw)
1803*2d9fd380Sjfb8856606 {
1804*2d9fd380Sjfb8856606 if (hw->phy.ops.power_up)
1805*2d9fd380Sjfb8856606 hw->phy.ops.power_up(hw);
1806*2d9fd380Sjfb8856606
1807*2d9fd380Sjfb8856606 igc_setup_link(hw);
1808*2d9fd380Sjfb8856606 }
1809*2d9fd380Sjfb8856606
1810*2d9fd380Sjfb8856606 /**
1811*2d9fd380Sjfb8856606 * igc_power_down_phy - Power down PHY
1812*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1813*2d9fd380Sjfb8856606 *
1814*2d9fd380Sjfb8856606 * The phy may be powered down to save power, to turn off link when the
1815*2d9fd380Sjfb8856606 * driver is unloaded, or wake on lan is not enabled (among others).
1816*2d9fd380Sjfb8856606 **/
igc_power_down_phy(struct igc_hw * hw)1817*2d9fd380Sjfb8856606 void igc_power_down_phy(struct igc_hw *hw)
1818*2d9fd380Sjfb8856606 {
1819*2d9fd380Sjfb8856606 if (hw->phy.ops.power_down)
1820*2d9fd380Sjfb8856606 hw->phy.ops.power_down(hw);
1821*2d9fd380Sjfb8856606 }
1822*2d9fd380Sjfb8856606
1823*2d9fd380Sjfb8856606 /**
1824*2d9fd380Sjfb8856606 * igc_power_up_fiber_serdes_link - Power up serdes link
1825*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1826*2d9fd380Sjfb8856606 *
1827*2d9fd380Sjfb8856606 * Power on the optics and PCS.
1828*2d9fd380Sjfb8856606 **/
igc_power_up_fiber_serdes_link(struct igc_hw * hw)1829*2d9fd380Sjfb8856606 void igc_power_up_fiber_serdes_link(struct igc_hw *hw)
1830*2d9fd380Sjfb8856606 {
1831*2d9fd380Sjfb8856606 if (hw->mac.ops.power_up_serdes)
1832*2d9fd380Sjfb8856606 hw->mac.ops.power_up_serdes(hw);
1833*2d9fd380Sjfb8856606 }
1834*2d9fd380Sjfb8856606
1835*2d9fd380Sjfb8856606 /**
1836*2d9fd380Sjfb8856606 * igc_shutdown_fiber_serdes_link - Remove link during power down
1837*2d9fd380Sjfb8856606 * @hw: pointer to the HW structure
1838*2d9fd380Sjfb8856606 *
1839*2d9fd380Sjfb8856606 * Shutdown the optics and PCS on driver unload.
1840*2d9fd380Sjfb8856606 **/
igc_shutdown_fiber_serdes_link(struct igc_hw * hw)1841*2d9fd380Sjfb8856606 void igc_shutdown_fiber_serdes_link(struct igc_hw *hw)
1842*2d9fd380Sjfb8856606 {
1843*2d9fd380Sjfb8856606 if (hw->mac.ops.shutdown_serdes)
1844*2d9fd380Sjfb8856606 hw->mac.ops.shutdown_serdes(hw);
1845*2d9fd380Sjfb8856606 }
1846