xref: /freebsd/sys/dev/ixl/ixl_pf_i2c.c (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 					&reg, 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
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