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 */
51static s32	ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data);
52static bool	ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl);
53static void	ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
54static void	ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
55static s32	ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data);
56static s32	ixl_get_i2c_ack(struct ixl_pf *pf);
57static s32	ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data);
58static s32	ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data);
59static s32	ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data);
60static void 	ixl_i2c_bus_clear(struct ixl_pf *pf);
61static void	ixl_i2c_start(struct ixl_pf *pf);
62static void	ixl_i2c_stop(struct ixl_pf *pf);
63
64static 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 **/
73static void
74ixl_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 **/
110static void
111ixl_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 **/
138static s32
139ixl_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 **/
161static s32
162ixl_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 **/
196static s32
197ixl_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 **/
247static s32
248ixl_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 **/
282static s32
283ixl_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 **/
318static void
319ixl_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 **/
340static void
341ixl_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 **/
370static bool
371ixl_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 **/
391static s32
392ixl_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 **/
425static void
426ixl_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 **/
455s32
456ixl_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
522fail:
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);
532done:
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 **/
544s32
545ixl_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
588fail:
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
598write_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 **/
610s32
611ixl_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 **/
640s32
641ixl_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 **/
676static s32
677ixl_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 **/
698s32
699ixl_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 **/
724s32
725ixl_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