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 */
52static s32	ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data);
53static bool	ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl);
54static void	ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
55static void	ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
56static s32	ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data);
57static s32	ixl_get_i2c_ack(struct ixl_pf *pf);
58static s32	ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data);
59static s32	ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data);
60static s32	ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data);
61static void 	ixl_i2c_bus_clear(struct ixl_pf *pf);
62static void	ixl_i2c_start(struct ixl_pf *pf);
63static void	ixl_i2c_stop(struct ixl_pf *pf);
64
65static 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 **/
74static void
75ixl_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 **/
111static void
112ixl_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 **/
139static s32
140ixl_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 **/
162static s32
163ixl_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 **/
197static s32
198ixl_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 **/
248static s32
249ixl_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 **/
283static s32
284ixl_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 **/
319static void
320ixl_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 **/
341static void
342ixl_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 **/
371static bool
372ixl_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 **/
392static s32
393ixl_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 **/
426static void
427ixl_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 **/
456s32
457ixl_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
523fail:
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);
533done:
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 **/
545s32
546ixl_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
589fail:
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
599write_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 **/
611s32
612ixl_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 **/
641s32
642ixl_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 controling 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 **/
677static s32
678ixl_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 **/
699s32
700ixl_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 **/
725s32
726ixl_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