xref: /freebsd/sys/dev/ixl/ixl_pf_i2c.c (revision 19fae0f66023a97a9b464b3beeeabb2081f575b3)
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_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 					&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_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 }
744