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