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'->''
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 ''->'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_reg - 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 read 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_reg - 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 controlling 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_aq - Reads 8 bit word over I2C using an AQ command
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, false,
710 byte_offset,
711 ®, 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_aq - Writes 8 bit word over I2C using an AQ command
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, false,
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 }
Cache object: 0437f44e6641e393fdbb43675d4b8a1f
|