]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ixl/ixl_pf_i2c.c
Make iflib a loadable module.
[FreeBSD/FreeBSD.git] / sys / dev / ixl / ixl_pf_i2c.c
1 /******************************************************************************
2
3   Copyright (c) 2013-2018, Intel Corporation
4   All rights reserved.
5   
6   Redistribution and use in source and binary forms, with or without 
7   modification, are permitted provided that the following conditions are met:
8   
9    1. Redistributions of source code must retain the above copyright notice, 
10       this list of conditions and the following disclaimer.
11   
12    2. Redistributions in binary form must reproduce the above copyright 
13       notice, this list of conditions and the following disclaimer in the 
14       documentation and/or other materials provided with the distribution.
15   
16    3. Neither the name of the Intel Corporation nor the names of its 
17       contributors may be used to endorse or promote products derived from 
18       this software without specific prior written permission.
19   
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   POSSIBILITY OF SUCH DAMAGE.
31
32 ******************************************************************************/
33 /*$FreeBSD$*/
34
35 #include "ixl_pf.h"
36
37 #define IXL_I2C_T_RISE          1
38 #define IXL_I2C_T_FALL          1
39 #define IXL_I2C_T_SU_DATA       1
40 #define IXL_I2C_T_SU_STA        5
41 #define IXL_I2C_T_SU_STO        4
42 #define IXL_I2C_T_HD_STA        4
43 #define IXL_I2C_T_LOW           5
44 #define IXL_I2C_T_HIGH          4
45 #define IXL_I2C_T_BUF           5
46 #define IXL_I2C_CLOCK_STRETCHING_TIMEOUT 500
47
48 #define IXL_I2C_REG(_hw)        \
49     I40E_GLGEN_I2CPARAMS(_hw->func_caps.mdio_port_num)
50
51 /* I2C bit-banging functions */
52 static s32      ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data);
53 static bool     ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl);
54 static void     ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
55 static void     ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
56 static s32      ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data);
57 static s32      ixl_get_i2c_ack(struct ixl_pf *pf);
58 static s32      ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data);
59 static s32      ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data);
60 static s32      ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data);
61 static void     ixl_i2c_bus_clear(struct ixl_pf *pf);
62 static void     ixl_i2c_start(struct ixl_pf *pf);
63 static void     ixl_i2c_stop(struct ixl_pf *pf);
64
65 static s32      ixl_wait_for_i2c_completion(struct i40e_hw *hw, u8 portnum);
66
67 /**
68  *  ixl_i2c_bus_clear - Clears the I2C bus
69  *  @hw: pointer to hardware structure
70  *
71  *  Clears the I2C bus by sending nine clock pulses.
72  *  Used when data line is stuck low.
73  **/
74 static void
75 ixl_i2c_bus_clear(struct ixl_pf *pf)
76 {
77         struct i40e_hw *hw = &pf->hw;
78         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
79         u32 i;
80
81         DEBUGFUNC("ixl_i2c_bus_clear");
82
83         ixl_i2c_start(pf);
84
85         ixl_set_i2c_data(pf, &i2cctl, 1);
86
87         for (i = 0; i < 9; i++) {
88                 ixl_raise_i2c_clk(pf, &i2cctl);
89
90                 /* Min high period of clock is 4us */
91                 i40e_usec_delay(IXL_I2C_T_HIGH);
92
93                 ixl_lower_i2c_clk(pf, &i2cctl);
94
95                 /* Min low period of clock is 4.7us*/
96                 i40e_usec_delay(IXL_I2C_T_LOW);
97         }
98
99         ixl_i2c_start(pf);
100
101         /* Put the i2c bus back to default state */
102         ixl_i2c_stop(pf);
103 }
104
105 /**
106  *  ixl_i2c_stop - Sets I2C stop condition
107  *  @hw: pointer to hardware structure
108  *
109  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
110  **/
111 static void
112 ixl_i2c_stop(struct ixl_pf *pf)
113 {
114         struct i40e_hw *hw = &pf->hw;
115         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
116
117         DEBUGFUNC("ixl_i2c_stop");
118
119         /* Stop condition must begin with data low and clock high */
120         ixl_set_i2c_data(pf, &i2cctl, 0);
121         ixl_raise_i2c_clk(pf, &i2cctl);
122
123         /* Setup time for stop condition (4us) */
124         i40e_usec_delay(IXL_I2C_T_SU_STO);
125
126         ixl_set_i2c_data(pf, &i2cctl, 1);
127
128         /* bus free time between stop and start (4.7us)*/
129         i40e_usec_delay(IXL_I2C_T_BUF);
130 }
131
132 /**
133  *  ixl_clock_in_i2c_byte - Clocks in one byte via I2C
134  *  @hw: pointer to hardware structure
135  *  @data: data byte to clock in
136  *
137  *  Clocks in one byte data via I2C data/clock
138  **/
139 static s32
140 ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data)
141 {
142         s32 i;
143         bool bit = 0;
144
145         DEBUGFUNC("ixl_clock_in_i2c_byte");
146
147         for (i = 7; i >= 0; i--) {
148                 ixl_clock_in_i2c_bit(pf, &bit);
149                 *data |= bit << i;
150         }
151
152         return I40E_SUCCESS;
153 }
154
155 /**
156  *  ixl_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
157  *  @hw: pointer to hardware structure
158  *  @data: read data value
159  *
160  *  Clocks in one bit via I2C data/clock
161  **/
162 static s32
163 ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data)
164 {
165         struct i40e_hw *hw = &pf->hw;
166         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
167
168         DEBUGFUNC("ixl_clock_in_i2c_bit");
169
170         ixl_raise_i2c_clk(pf, &i2cctl);
171
172         /* Minimum high period of clock is 4us */
173         i40e_usec_delay(IXL_I2C_T_HIGH);
174
175         i2cctl = rd32(hw, IXL_I2C_REG(hw));
176         i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
177         wr32(hw, IXL_I2C_REG(hw), i2cctl);
178         ixl_flush(hw);
179
180         i2cctl = rd32(hw, IXL_I2C_REG(hw));
181         *data = ixl_get_i2c_data(pf, &i2cctl);
182
183         ixl_lower_i2c_clk(pf, &i2cctl);
184
185         /* Minimum low period of clock is 4.7 us */
186         i40e_usec_delay(IXL_I2C_T_LOW);
187
188         return I40E_SUCCESS;
189 }
190
191 /**
192  *  ixl_get_i2c_ack - Polls for I2C ACK
193  *  @hw: pointer to hardware structure
194  *
195  *  Clocks in/out one bit via I2C data/clock
196  **/
197 static s32
198 ixl_get_i2c_ack(struct ixl_pf *pf)
199 {
200         struct i40e_hw *hw = &pf->hw;
201         s32 status = I40E_SUCCESS;
202         u32 i = 0;
203         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
204         u32 timeout = 10;
205         bool ack = 1;
206
207         ixl_raise_i2c_clk(pf, &i2cctl);
208
209         /* Minimum high period of clock is 4us */
210         i40e_usec_delay(IXL_I2C_T_HIGH);
211
212         i2cctl = rd32(hw, IXL_I2C_REG(hw));
213         i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
214         wr32(hw, IXL_I2C_REG(hw), i2cctl);
215         ixl_flush(hw);
216
217         /* Poll for ACK.  Note that ACK in I2C spec is
218          * transition from 1 to 0 */
219         for (i = 0; i < timeout; i++) {
220                 i2cctl = rd32(hw, IXL_I2C_REG(hw));
221                 ack = ixl_get_i2c_data(pf, &i2cctl);
222
223                 i40e_usec_delay(1);
224                 if (!ack)
225                         break;
226         }
227
228         if (ack) {
229                 ixl_dbg(pf, IXL_DBG_I2C, "I2C ack was not received.\n");
230                 status = I40E_ERR_PHY;
231         }
232
233         ixl_lower_i2c_clk(pf, &i2cctl);
234
235         /* Minimum low period of clock is 4.7 us */
236         i40e_usec_delay(IXL_I2C_T_LOW);
237
238         return status;
239 }
240
241 /**
242  *  ixl_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
243  *  @hw: pointer to hardware structure
244  *  @data: data value to write
245  *
246  *  Clocks out one bit via I2C data/clock
247  **/
248 static s32
249 ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data)
250 {
251         struct i40e_hw *hw = &pf->hw;
252         s32 status;
253         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
254
255         status = ixl_set_i2c_data(pf, &i2cctl, data);
256         if (status == I40E_SUCCESS) {
257                 ixl_raise_i2c_clk(pf, &i2cctl);
258
259                 /* Minimum high period of clock is 4us */
260                 i40e_usec_delay(IXL_I2C_T_HIGH);
261
262                 ixl_lower_i2c_clk(pf, &i2cctl);
263
264                 /* Minimum low period of clock is 4.7 us.
265                  * This also takes care of the data hold time.
266                  */
267                 i40e_usec_delay(IXL_I2C_T_LOW);
268         } else {
269                 status = I40E_ERR_PHY;
270                 ixl_dbg(pf, IXL_DBG_I2C, "I2C data was not set to %#x\n", data);
271         }
272
273         return status;
274 }
275
276 /**
277  *  ixl_clock_out_i2c_byte - Clocks out one byte via I2C
278  *  @hw: pointer to hardware structure
279  *  @data: data byte clocked out
280  *
281  *  Clocks out one byte data via I2C data/clock
282  **/
283 static s32
284 ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data)
285 {
286         struct i40e_hw *hw = &pf->hw;
287         s32 status = I40E_SUCCESS;
288         s32 i;
289         u32 i2cctl;
290         bool bit;
291
292         DEBUGFUNC("ixl_clock_out_i2c_byte");
293
294         for (i = 7; i >= 0; i--) {
295                 bit = (data >> i) & 0x1;
296                 status = ixl_clock_out_i2c_bit(pf, bit);
297
298                 if (status != I40E_SUCCESS)
299                         break;
300         }
301
302         /* Release SDA line (set high) */
303         i2cctl = rd32(hw, IXL_I2C_REG(hw));
304         i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
305         i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
306         wr32(hw, IXL_I2C_REG(hw), i2cctl);
307         ixl_flush(hw);
308
309         return status;
310 }
311
312 /**
313  *  ixl_lower_i2c_clk - Lowers the I2C SCL clock
314  *  @hw: pointer to hardware structure
315  *  @i2cctl: Current value of I2CCTL register
316  *
317  *  Lowers the I2C clock line '1'->'0'
318  **/
319 static void
320 ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
321 {
322         struct i40e_hw *hw = &pf->hw;
323
324         *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_MASK);
325         *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
326
327         wr32(hw, IXL_I2C_REG(hw), *i2cctl);
328         ixl_flush(hw);
329
330         /* SCL fall time (300ns) */
331         i40e_usec_delay(IXL_I2C_T_FALL);
332 }
333
334 /**
335  *  ixl_raise_i2c_clk - Raises the I2C SCL clock
336  *  @hw: pointer to hardware structure
337  *  @i2cctl: Current value of I2CCTL register
338  *
339  *  Raises the I2C clock line '0'->'1'
340  **/
341 static void
342 ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
343 {
344         struct i40e_hw *hw = &pf->hw;
345         u32 i = 0;
346         u32 timeout = IXL_I2C_CLOCK_STRETCHING_TIMEOUT;
347         u32 i2cctl_r = 0;
348
349         for (i = 0; i < timeout; i++) {
350                 *i2cctl |= I40E_GLGEN_I2CPARAMS_CLK_MASK;
351                 *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
352
353                 wr32(hw, IXL_I2C_REG(hw), *i2cctl);
354                 ixl_flush(hw);
355                 /* SCL rise time (1000ns) */
356                 i40e_usec_delay(IXL_I2C_T_RISE);
357
358                 i2cctl_r = rd32(hw, IXL_I2C_REG(hw));
359                 if (i2cctl_r & I40E_GLGEN_I2CPARAMS_CLK_IN_MASK)
360                         break;
361         }
362 }
363
364 /**
365  *  ixl_get_i2c_data - Reads the I2C SDA data bit
366  *  @hw: pointer to hardware structure
367  *  @i2cctl: Current value of I2CCTL register
368  *
369  *  Returns the I2C data bit value
370  **/
371 static bool
372 ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl)
373 {
374         bool data;
375
376         if (*i2cctl & I40E_GLGEN_I2CPARAMS_DATA_IN_MASK)
377                 data = 1;
378         else
379                 data = 0;
380
381         return data;
382 }
383
384 /**
385  *  ixl_set_i2c_data - Sets the I2C data bit
386  *  @hw: pointer to hardware structure
387  *  @i2cctl: Current value of I2CCTL register
388  *  @data: I2C data value (0 or 1) to set
389  *
390  *  Sets the I2C data bit
391  **/
392 static s32
393 ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data)
394 {
395         struct i40e_hw *hw = &pf->hw;
396         s32 status = I40E_SUCCESS;
397
398         DEBUGFUNC("ixl_set_i2c_data");
399
400         if (data)
401                 *i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
402         else
403                 *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK);
404         *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
405
406         wr32(hw, IXL_I2C_REG(hw), *i2cctl);
407         ixl_flush(hw);
408
409         /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
410         i40e_usec_delay(IXL_I2C_T_RISE + IXL_I2C_T_FALL + IXL_I2C_T_SU_DATA);
411
412         /* Verify data was set correctly */
413         *i2cctl = rd32(hw, IXL_I2C_REG(hw));
414         if (data != ixl_get_i2c_data(pf, i2cctl)) {
415                 status = I40E_ERR_PHY;
416                 ixl_dbg(pf, IXL_DBG_I2C, "Error - I2C data was not set to %X.\n", data);
417         }
418
419         return status;
420 }
421
422 /**
423  *  ixl_i2c_start - Sets I2C start condition
424  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
425  **/
426 static void
427 ixl_i2c_start(struct ixl_pf *pf)
428 {
429         struct i40e_hw *hw = &pf->hw;
430         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
431
432         DEBUGFUNC("ixl_i2c_start");
433
434         /* Start condition must begin with data and clock high */
435         ixl_set_i2c_data(pf, &i2cctl, 1);
436         ixl_raise_i2c_clk(pf, &i2cctl);
437
438         /* Setup time for start condition (4.7us) */
439         i40e_usec_delay(IXL_I2C_T_SU_STA);
440
441         ixl_set_i2c_data(pf, &i2cctl, 0);
442
443         /* Hold time for start condition (4us) */
444         i40e_usec_delay(IXL_I2C_T_HD_STA);
445
446         ixl_lower_i2c_clk(pf, &i2cctl);
447
448         /* Minimum low period of clock is 4.7 us */
449         i40e_usec_delay(IXL_I2C_T_LOW);
450
451 }
452
453 /**
454  *  ixl_read_i2c_byte_bb - Reads 8 bit word over I2C
455  **/
456 s32
457 ixl_read_i2c_byte_bb(struct ixl_pf *pf, u8 byte_offset,
458                   u8 dev_addr, u8 *data)
459 {
460         struct i40e_hw *hw = &pf->hw;
461         u32 max_retry = 10;
462         u32 retry = 0;
463         bool nack = 1;
464         s32 status;
465         *data = 0;
466
467         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
468         i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
469         wr32(hw, IXL_I2C_REG(hw), i2cctl);
470         ixl_flush(hw);
471
472         do {
473                 ixl_i2c_start(pf);
474
475                 /* Device Address and write indication */
476                 status = ixl_clock_out_i2c_byte(pf, dev_addr);
477                 if (status != I40E_SUCCESS) {
478                         ixl_dbg(pf, IXL_DBG_I2C, "dev_addr clock out error\n");
479                         goto fail;
480                 }
481
482                 status = ixl_get_i2c_ack(pf);
483                 if (status != I40E_SUCCESS) {
484                         ixl_dbg(pf, IXL_DBG_I2C, "dev_addr i2c ack error\n");
485                         goto fail;
486                 }
487
488                 status = ixl_clock_out_i2c_byte(pf, byte_offset);
489                 if (status != I40E_SUCCESS) {
490                         ixl_dbg(pf, IXL_DBG_I2C, "byte_offset clock out error\n");
491                         goto fail;
492                 }
493
494                 status = ixl_get_i2c_ack(pf);
495                 if (status != I40E_SUCCESS) {
496                         ixl_dbg(pf, IXL_DBG_I2C, "byte_offset i2c ack error\n");
497                         goto fail;
498                 }
499
500                 ixl_i2c_start(pf);
501
502                 /* Device Address and read indication */
503                 status = ixl_clock_out_i2c_byte(pf, (dev_addr | 0x1));
504                 if (status != I40E_SUCCESS)
505                         goto fail;
506
507                 status = ixl_get_i2c_ack(pf);
508                 if (status != I40E_SUCCESS)
509                         goto fail;
510
511                 status = ixl_clock_in_i2c_byte(pf, data);
512                 if (status != I40E_SUCCESS)
513                         goto fail;
514
515                 status = ixl_clock_out_i2c_bit(pf, nack);
516                 if (status != I40E_SUCCESS)
517                         goto fail;
518
519                 ixl_i2c_stop(pf);
520                 status = I40E_SUCCESS;
521                 goto done;
522
523 fail:
524                 ixl_i2c_bus_clear(pf);
525                 i40e_msec_delay(100);
526                 retry++;
527                 if (retry < max_retry)
528                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error - Retrying\n");
529                 else
530                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error\n");
531
532         } while (retry < max_retry);
533 done:
534         i2cctl = rd32(hw, IXL_I2C_REG(hw));
535         i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
536         wr32(hw, IXL_I2C_REG(hw), i2cctl);
537         ixl_flush(hw);
538
539         return status;
540 }
541
542 /**
543  *  ixl_write_i2c_byte_bb - Writes 8 bit word over I2C
544  **/
545 s32
546 ixl_write_i2c_byte_bb(struct ixl_pf *pf, u8 byte_offset,
547                        u8 dev_addr, u8 data)
548 {
549         struct i40e_hw *hw = &pf->hw;
550         s32 status = I40E_SUCCESS;
551         u32 max_retry = 1;
552         u32 retry = 0;
553
554         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
555         i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
556         wr32(hw, IXL_I2C_REG(hw), i2cctl);
557         ixl_flush(hw);
558
559         do {
560                 ixl_i2c_start(pf);
561
562                 status = ixl_clock_out_i2c_byte(pf, dev_addr);
563                 if (status != I40E_SUCCESS)
564                         goto fail;
565
566                 status = ixl_get_i2c_ack(pf);
567                 if (status != I40E_SUCCESS)
568                         goto fail;
569
570                 status = ixl_clock_out_i2c_byte(pf, byte_offset);
571                 if (status != I40E_SUCCESS)
572                         goto fail;
573
574                 status = ixl_get_i2c_ack(pf);
575                 if (status != I40E_SUCCESS)
576                         goto fail;
577
578                 status = ixl_clock_out_i2c_byte(pf, data);
579                 if (status != I40E_SUCCESS)
580                         goto fail;
581
582                 status = ixl_get_i2c_ack(pf);
583                 if (status != I40E_SUCCESS)
584                         goto fail;
585
586                 ixl_i2c_stop(pf);
587                 goto write_byte_out;
588
589 fail:
590                 ixl_i2c_bus_clear(pf);
591                 i40e_msec_delay(100);
592                 retry++;
593                 if (retry < max_retry)
594                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error - Retrying\n");
595                 else
596                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error\n");
597         } while (retry < max_retry);
598
599 write_byte_out:
600         i2cctl = rd32(hw, IXL_I2C_REG(hw));
601         i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
602         wr32(hw, IXL_I2C_REG(hw), i2cctl);
603         ixl_flush(hw);
604
605         return status;
606 }
607
608 /**
609  *  ixl_read_i2c_byte - Reads 8 bit word over I2C using a hardware register
610  **/
611 s32
612 ixl_read_i2c_byte_reg(struct ixl_pf *pf, u8 byte_offset,
613                   u8 dev_addr, u8 *data)
614 {
615         struct i40e_hw *hw = &pf->hw;
616         u32 reg = 0;
617         s32 status;
618         *data = 0;
619
620         reg |= (byte_offset << I40E_GLGEN_I2CCMD_REGADD_SHIFT);
621         reg |= (((dev_addr >> 1) & 0x7) << I40E_GLGEN_I2CCMD_PHYADD_SHIFT);
622         reg |= I40E_GLGEN_I2CCMD_OP_MASK;
623         wr32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num), reg);
624
625         status = ixl_wait_for_i2c_completion(hw, hw->func_caps.mdio_port_num);
626
627         /* Get data from I2C register */
628         reg = rd32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num));
629
630         /* Retrieve data readed from EEPROM */
631         *data = (u8)(reg & 0xff);
632
633         if (status)
634                 ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error\n");
635         return status;
636 }
637
638 /**
639  *  ixl_write_i2c_byte - Writes 8 bit word over I2C using a hardware register
640  **/
641 s32
642 ixl_write_i2c_byte_reg(struct ixl_pf *pf, u8 byte_offset,
643                        u8 dev_addr, u8 data)
644 {
645         struct i40e_hw *hw = &pf->hw;
646         s32 status = I40E_SUCCESS;
647         u32 reg = 0;
648         u8 upperbyte = 0;
649         u16 datai2c = 0;
650
651         status = ixl_read_i2c_byte_reg(pf, byte_offset + 1, dev_addr, &upperbyte);
652         datai2c = ((u16)upperbyte << 8) | (u16)data;
653         reg = rd32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num));
654
655         /* Form write command */
656         reg &= ~I40E_GLGEN_I2CCMD_PHYADD_MASK;
657         reg |= (((dev_addr >> 1) & 0x7) << I40E_GLGEN_I2CCMD_PHYADD_SHIFT);
658         reg &= ~I40E_GLGEN_I2CCMD_REGADD_MASK;
659         reg |= (byte_offset << I40E_GLGEN_I2CCMD_REGADD_SHIFT);
660         reg &= ~I40E_GLGEN_I2CCMD_DATA_MASK;
661         reg |= (datai2c << I40E_GLGEN_I2CCMD_DATA_SHIFT);
662         reg &= ~I40E_GLGEN_I2CCMD_OP_MASK;
663
664         /* Write command to registers controling I2C - data and address. */
665         wr32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num), reg);
666
667         status = ixl_wait_for_i2c_completion(hw, hw->func_caps.mdio_port_num);
668
669         if (status)
670                 ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error\n");
671         return status;
672 }
673
674 /**
675  *  ixl_wait_for_i2c_completion
676  **/
677 static s32
678 ixl_wait_for_i2c_completion(struct i40e_hw *hw, u8 portnum)
679 {
680         s32 status = 0;
681         u32 timeout = 100;
682         u32 reg;
683         do {
684                 reg = rd32(hw, I40E_GLGEN_I2CCMD(portnum));
685                 if ((reg & I40E_GLGEN_I2CCMD_R_MASK) != 0)
686                         break;
687                 i40e_usec_delay(10);
688         } while (timeout-- > 0);
689
690         if (timeout == 0)
691                 return I40E_ERR_TIMEOUT;
692         else
693                 return status;
694 }
695
696 /**
697  *  ixl_read_i2c_byte - Reads 8 bit word over I2C using a hardware register
698  **/
699 s32
700 ixl_read_i2c_byte_aq(struct ixl_pf *pf, u8 byte_offset,
701                   u8 dev_addr, u8 *data)
702 {
703         struct i40e_hw *hw = &pf->hw;
704         s32 status = I40E_SUCCESS;
705         u32 reg;
706
707         status = i40e_aq_get_phy_register(hw,
708                                         I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
709                                         dev_addr,
710                                         byte_offset,
711                                         &reg, NULL);
712
713         if (status)
714                 ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read status %s, error %s\n",
715                     i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
716         else
717                 *data = (u8)reg;
718
719         return status;
720 }
721
722 /**
723  *  ixl_write_i2c_byte - Writes 8 bit word over I2C using a hardware register
724  **/
725 s32
726 ixl_write_i2c_byte_aq(struct ixl_pf *pf, u8 byte_offset,
727                        u8 dev_addr, u8 data)
728 {
729         struct i40e_hw *hw = &pf->hw;
730         s32 status = I40E_SUCCESS;
731
732         status = i40e_aq_set_phy_register(hw,
733                                         I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
734                                         dev_addr,
735                                         byte_offset,
736                                         data, NULL);
737
738         if (status)
739                 ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write status %s, error %s\n",
740                     i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
741
742         return status;
743 }