1cb6b8299SEric Joyner /******************************************************************************
2cb6b8299SEric Joyner
3f4cc2d17SEric Joyner Copyright (c) 2013-2018, Intel Corporation
4cb6b8299SEric Joyner All rights reserved.
5cb6b8299SEric Joyner
6cb6b8299SEric Joyner Redistribution and use in source and binary forms, with or without
7cb6b8299SEric Joyner modification, are permitted provided that the following conditions are met:
8cb6b8299SEric Joyner
9cb6b8299SEric Joyner 1. Redistributions of source code must retain the above copyright notice,
10cb6b8299SEric Joyner this list of conditions and the following disclaimer.
11cb6b8299SEric Joyner
12cb6b8299SEric Joyner 2. Redistributions in binary form must reproduce the above copyright
13cb6b8299SEric Joyner notice, this list of conditions and the following disclaimer in the
14cb6b8299SEric Joyner documentation and/or other materials provided with the distribution.
15cb6b8299SEric Joyner
16cb6b8299SEric Joyner 3. Neither the name of the Intel Corporation nor the names of its
17cb6b8299SEric Joyner contributors may be used to endorse or promote products derived from
18cb6b8299SEric Joyner this software without specific prior written permission.
19cb6b8299SEric Joyner
20cb6b8299SEric Joyner THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21cb6b8299SEric Joyner AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22cb6b8299SEric Joyner IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23cb6b8299SEric Joyner ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24cb6b8299SEric Joyner LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25cb6b8299SEric Joyner CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26cb6b8299SEric Joyner SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27cb6b8299SEric Joyner INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28cb6b8299SEric Joyner CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29cb6b8299SEric Joyner ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30cb6b8299SEric Joyner POSSIBILITY OF SUCH DAMAGE.
31cb6b8299SEric Joyner
32cb6b8299SEric Joyner ******************************************************************************/
33cb6b8299SEric Joyner
34cb6b8299SEric Joyner #include "ixl_pf.h"
35cb6b8299SEric Joyner
36cb6b8299SEric Joyner #define IXL_I2C_T_RISE 1
37cb6b8299SEric Joyner #define IXL_I2C_T_FALL 1
38cb6b8299SEric Joyner #define IXL_I2C_T_SU_DATA 1
39cb6b8299SEric Joyner #define IXL_I2C_T_SU_STA 5
40cb6b8299SEric Joyner #define IXL_I2C_T_SU_STO 4
41cb6b8299SEric Joyner #define IXL_I2C_T_HD_STA 4
42cb6b8299SEric Joyner #define IXL_I2C_T_LOW 5
43cb6b8299SEric Joyner #define IXL_I2C_T_HIGH 4
44cb6b8299SEric Joyner #define IXL_I2C_T_BUF 5
45cb6b8299SEric Joyner #define IXL_I2C_CLOCK_STRETCHING_TIMEOUT 500
46cb6b8299SEric Joyner
47cb6b8299SEric Joyner #define IXL_I2C_REG(_hw) \
481031d839SEric Joyner I40E_GLGEN_I2CPARAMS(_hw->func_caps.mdio_port_num)
49cb6b8299SEric Joyner
501031d839SEric Joyner /* I2C bit-banging functions */
51cb6b8299SEric Joyner static s32 ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data);
52cb6b8299SEric Joyner static bool ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl);
53cb6b8299SEric Joyner static void ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
54cb6b8299SEric Joyner static void ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
55cb6b8299SEric Joyner static s32 ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data);
56cb6b8299SEric Joyner static s32 ixl_get_i2c_ack(struct ixl_pf *pf);
57cb6b8299SEric Joyner static s32 ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data);
58cb6b8299SEric Joyner static s32 ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data);
59cb6b8299SEric Joyner static s32 ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data);
60cb6b8299SEric Joyner static void ixl_i2c_bus_clear(struct ixl_pf *pf);
61cb6b8299SEric Joyner static void ixl_i2c_start(struct ixl_pf *pf);
62cb6b8299SEric Joyner static void ixl_i2c_stop(struct ixl_pf *pf);
63cb6b8299SEric Joyner
641031d839SEric Joyner static s32 ixl_wait_for_i2c_completion(struct i40e_hw *hw, u8 portnum);
651031d839SEric Joyner
66cb6b8299SEric Joyner /**
67cb6b8299SEric Joyner * ixl_i2c_bus_clear - Clears the I2C bus
68cb6b8299SEric Joyner * @hw: pointer to hardware structure
69cb6b8299SEric Joyner *
70cb6b8299SEric Joyner * Clears the I2C bus by sending nine clock pulses.
71cb6b8299SEric Joyner * Used when data line is stuck low.
72cb6b8299SEric Joyner **/
73cb6b8299SEric Joyner static void
ixl_i2c_bus_clear(struct ixl_pf * pf)74cb6b8299SEric Joyner ixl_i2c_bus_clear(struct ixl_pf *pf)
75cb6b8299SEric Joyner {
76cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
77cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
78cb6b8299SEric Joyner u32 i;
79cb6b8299SEric Joyner
80cb6b8299SEric Joyner DEBUGFUNC("ixl_i2c_bus_clear");
81cb6b8299SEric Joyner
82cb6b8299SEric Joyner ixl_i2c_start(pf);
83cb6b8299SEric Joyner
84cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 1);
85cb6b8299SEric Joyner
86cb6b8299SEric Joyner for (i = 0; i < 9; i++) {
87cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl);
88cb6b8299SEric Joyner
89cb6b8299SEric Joyner /* Min high period of clock is 4us */
90cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH);
91cb6b8299SEric Joyner
92cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl);
93cb6b8299SEric Joyner
94cb6b8299SEric Joyner /* Min low period of clock is 4.7us*/
95cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW);
96cb6b8299SEric Joyner }
97cb6b8299SEric Joyner
98cb6b8299SEric Joyner ixl_i2c_start(pf);
99cb6b8299SEric Joyner
100cb6b8299SEric Joyner /* Put the i2c bus back to default state */
101cb6b8299SEric Joyner ixl_i2c_stop(pf);
102cb6b8299SEric Joyner }
103cb6b8299SEric Joyner
104cb6b8299SEric Joyner /**
105cb6b8299SEric Joyner * ixl_i2c_stop - Sets I2C stop condition
106cb6b8299SEric Joyner * @hw: pointer to hardware structure
107cb6b8299SEric Joyner *
108cb6b8299SEric Joyner * Sets I2C stop condition (Low -> High on SDA while SCL is High)
109cb6b8299SEric Joyner **/
110cb6b8299SEric Joyner static void
ixl_i2c_stop(struct ixl_pf * pf)111cb6b8299SEric Joyner ixl_i2c_stop(struct ixl_pf *pf)
112cb6b8299SEric Joyner {
113cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
114cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
115cb6b8299SEric Joyner
116cb6b8299SEric Joyner DEBUGFUNC("ixl_i2c_stop");
117cb6b8299SEric Joyner
118cb6b8299SEric Joyner /* Stop condition must begin with data low and clock high */
119cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 0);
120cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl);
121cb6b8299SEric Joyner
122cb6b8299SEric Joyner /* Setup time for stop condition (4us) */
123cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_SU_STO);
124cb6b8299SEric Joyner
125cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 1);
126cb6b8299SEric Joyner
127cb6b8299SEric Joyner /* bus free time between stop and start (4.7us)*/
128cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_BUF);
129cb6b8299SEric Joyner }
130cb6b8299SEric Joyner
131cb6b8299SEric Joyner /**
132cb6b8299SEric Joyner * ixl_clock_in_i2c_byte - Clocks in one byte via I2C
133cb6b8299SEric Joyner * @hw: pointer to hardware structure
134cb6b8299SEric Joyner * @data: data byte to clock in
135cb6b8299SEric Joyner *
136cb6b8299SEric Joyner * Clocks in one byte data via I2C data/clock
137cb6b8299SEric Joyner **/
138cb6b8299SEric Joyner static s32
ixl_clock_in_i2c_byte(struct ixl_pf * pf,u8 * data)139cb6b8299SEric Joyner ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data)
140cb6b8299SEric Joyner {
141cb6b8299SEric Joyner s32 i;
142cb6b8299SEric Joyner bool bit = 0;
143cb6b8299SEric Joyner
144cb6b8299SEric Joyner DEBUGFUNC("ixl_clock_in_i2c_byte");
145cb6b8299SEric Joyner
146cb6b8299SEric Joyner for (i = 7; i >= 0; i--) {
147cb6b8299SEric Joyner ixl_clock_in_i2c_bit(pf, &bit);
148cb6b8299SEric Joyner *data |= bit << i;
149cb6b8299SEric Joyner }
150cb6b8299SEric Joyner
151cb6b8299SEric Joyner return I40E_SUCCESS;
152cb6b8299SEric Joyner }
153cb6b8299SEric Joyner
154cb6b8299SEric Joyner /**
155cb6b8299SEric Joyner * ixl_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
156cb6b8299SEric Joyner * @hw: pointer to hardware structure
157cb6b8299SEric Joyner * @data: read data value
158cb6b8299SEric Joyner *
159cb6b8299SEric Joyner * Clocks in one bit via I2C data/clock
160cb6b8299SEric Joyner **/
161cb6b8299SEric Joyner static s32
ixl_clock_in_i2c_bit(struct ixl_pf * pf,bool * data)162cb6b8299SEric Joyner ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data)
163cb6b8299SEric Joyner {
164cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
165cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
166cb6b8299SEric Joyner
167cb6b8299SEric Joyner DEBUGFUNC("ixl_clock_in_i2c_bit");
168cb6b8299SEric Joyner
169cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl);
170cb6b8299SEric Joyner
171cb6b8299SEric Joyner /* Minimum high period of clock is 4us */
172cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH);
173cb6b8299SEric Joyner
174cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw));
175cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
176cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl);
177cb6b8299SEric Joyner ixl_flush(hw);
178cb6b8299SEric Joyner
179cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw));
180cb6b8299SEric Joyner *data = ixl_get_i2c_data(pf, &i2cctl);
181cb6b8299SEric Joyner
182cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl);
183cb6b8299SEric Joyner
184cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us */
185cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW);
186cb6b8299SEric Joyner
187cb6b8299SEric Joyner return I40E_SUCCESS;
188cb6b8299SEric Joyner }
189cb6b8299SEric Joyner
190cb6b8299SEric Joyner /**
191cb6b8299SEric Joyner * ixl_get_i2c_ack - Polls for I2C ACK
192cb6b8299SEric Joyner * @hw: pointer to hardware structure
193cb6b8299SEric Joyner *
194cb6b8299SEric Joyner * Clocks in/out one bit via I2C data/clock
195cb6b8299SEric Joyner **/
196cb6b8299SEric Joyner static s32
ixl_get_i2c_ack(struct ixl_pf * pf)197cb6b8299SEric Joyner ixl_get_i2c_ack(struct ixl_pf *pf)
198cb6b8299SEric Joyner {
199cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
200cb6b8299SEric Joyner s32 status = I40E_SUCCESS;
201cb6b8299SEric Joyner u32 i = 0;
202cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
203cb6b8299SEric Joyner u32 timeout = 10;
204cb6b8299SEric Joyner bool ack = 1;
205cb6b8299SEric Joyner
206cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl);
207cb6b8299SEric Joyner
208cb6b8299SEric Joyner /* Minimum high period of clock is 4us */
209cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH);
210cb6b8299SEric Joyner
211cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw));
212cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
213cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl);
214cb6b8299SEric Joyner ixl_flush(hw);
215cb6b8299SEric Joyner
216cb6b8299SEric Joyner /* Poll for ACK. Note that ACK in I2C spec is
217cb6b8299SEric Joyner * transition from 1 to 0 */
218cb6b8299SEric Joyner for (i = 0; i < timeout; i++) {
219cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw));
220cb6b8299SEric Joyner ack = ixl_get_i2c_data(pf, &i2cctl);
221cb6b8299SEric Joyner
222cb6b8299SEric Joyner i40e_usec_delay(1);
223cb6b8299SEric Joyner if (!ack)
224cb6b8299SEric Joyner break;
225cb6b8299SEric Joyner }
226cb6b8299SEric Joyner
227cb6b8299SEric Joyner if (ack) {
228cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C ack was not received.\n");
229cb6b8299SEric Joyner status = I40E_ERR_PHY;
230cb6b8299SEric Joyner }
231cb6b8299SEric Joyner
232cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl);
233cb6b8299SEric Joyner
234cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us */
235cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW);
236cb6b8299SEric Joyner
237cb6b8299SEric Joyner return status;
238cb6b8299SEric Joyner }
239cb6b8299SEric Joyner
240cb6b8299SEric Joyner /**
241cb6b8299SEric Joyner * ixl_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
242cb6b8299SEric Joyner * @hw: pointer to hardware structure
243cb6b8299SEric Joyner * @data: data value to write
244cb6b8299SEric Joyner *
245cb6b8299SEric Joyner * Clocks out one bit via I2C data/clock
246cb6b8299SEric Joyner **/
247cb6b8299SEric Joyner static s32
ixl_clock_out_i2c_bit(struct ixl_pf * pf,bool data)248cb6b8299SEric Joyner ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data)
249cb6b8299SEric Joyner {
250cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
251cb6b8299SEric Joyner s32 status;
252cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
253cb6b8299SEric Joyner
254cb6b8299SEric Joyner status = ixl_set_i2c_data(pf, &i2cctl, data);
255cb6b8299SEric Joyner if (status == I40E_SUCCESS) {
256cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl);
257cb6b8299SEric Joyner
258cb6b8299SEric Joyner /* Minimum high period of clock is 4us */
259cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH);
260cb6b8299SEric Joyner
261cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl);
262cb6b8299SEric Joyner
263cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us.
264cb6b8299SEric Joyner * This also takes care of the data hold time.
265cb6b8299SEric Joyner */
266cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW);
267cb6b8299SEric Joyner } else {
268cb6b8299SEric Joyner status = I40E_ERR_PHY;
269cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C data was not set to %#x\n", data);
270cb6b8299SEric Joyner }
271cb6b8299SEric Joyner
272cb6b8299SEric Joyner return status;
273cb6b8299SEric Joyner }
274cb6b8299SEric Joyner
275cb6b8299SEric Joyner /**
276cb6b8299SEric Joyner * ixl_clock_out_i2c_byte - Clocks out one byte via I2C
277cb6b8299SEric Joyner * @hw: pointer to hardware structure
278cb6b8299SEric Joyner * @data: data byte clocked out
279cb6b8299SEric Joyner *
280cb6b8299SEric Joyner * Clocks out one byte data via I2C data/clock
281cb6b8299SEric Joyner **/
282cb6b8299SEric Joyner static s32
ixl_clock_out_i2c_byte(struct ixl_pf * pf,u8 data)283cb6b8299SEric Joyner ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data)
284cb6b8299SEric Joyner {
285cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
286cb6b8299SEric Joyner s32 status = I40E_SUCCESS;
287cb6b8299SEric Joyner s32 i;
288cb6b8299SEric Joyner u32 i2cctl;
289cb6b8299SEric Joyner bool bit;
290cb6b8299SEric Joyner
291cb6b8299SEric Joyner DEBUGFUNC("ixl_clock_out_i2c_byte");
292cb6b8299SEric Joyner
293cb6b8299SEric Joyner for (i = 7; i >= 0; i--) {
294cb6b8299SEric Joyner bit = (data >> i) & 0x1;
295cb6b8299SEric Joyner status = ixl_clock_out_i2c_bit(pf, bit);
296cb6b8299SEric Joyner
297cb6b8299SEric Joyner if (status != I40E_SUCCESS)
298cb6b8299SEric Joyner break;
299cb6b8299SEric Joyner }
300cb6b8299SEric Joyner
301cb6b8299SEric Joyner /* Release SDA line (set high) */
302cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw));
303cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
304cb6b8299SEric Joyner i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
305cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl);
306cb6b8299SEric Joyner ixl_flush(hw);
307cb6b8299SEric Joyner
308cb6b8299SEric Joyner return status;
309cb6b8299SEric Joyner }
310cb6b8299SEric Joyner
311cb6b8299SEric Joyner /**
312cb6b8299SEric Joyner * ixl_lower_i2c_clk - Lowers the I2C SCL clock
313cb6b8299SEric Joyner * @hw: pointer to hardware structure
314cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register
315cb6b8299SEric Joyner *
316cb6b8299SEric Joyner * Lowers the I2C clock line '1'->'0'
317cb6b8299SEric Joyner **/
318cb6b8299SEric Joyner static void
ixl_lower_i2c_clk(struct ixl_pf * pf,u32 * i2cctl)319cb6b8299SEric Joyner ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
320cb6b8299SEric Joyner {
321cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
322cb6b8299SEric Joyner
323cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_MASK);
324cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
325cb6b8299SEric Joyner
326cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), *i2cctl);
327cb6b8299SEric Joyner ixl_flush(hw);
328cb6b8299SEric Joyner
329cb6b8299SEric Joyner /* SCL fall time (300ns) */
330cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_FALL);
331cb6b8299SEric Joyner }
332cb6b8299SEric Joyner
333cb6b8299SEric Joyner /**
334cb6b8299SEric Joyner * ixl_raise_i2c_clk - Raises the I2C SCL clock
335cb6b8299SEric Joyner * @hw: pointer to hardware structure
336cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register
337cb6b8299SEric Joyner *
338cb6b8299SEric Joyner * Raises the I2C clock line '0'->'1'
339cb6b8299SEric Joyner **/
340cb6b8299SEric Joyner static void
ixl_raise_i2c_clk(struct ixl_pf * pf,u32 * i2cctl)341cb6b8299SEric Joyner ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
342cb6b8299SEric Joyner {
343cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
344cb6b8299SEric Joyner u32 i = 0;
345cb6b8299SEric Joyner u32 timeout = IXL_I2C_CLOCK_STRETCHING_TIMEOUT;
346cb6b8299SEric Joyner u32 i2cctl_r = 0;
347cb6b8299SEric Joyner
348cb6b8299SEric Joyner for (i = 0; i < timeout; i++) {
349cb6b8299SEric Joyner *i2cctl |= I40E_GLGEN_I2CPARAMS_CLK_MASK;
350cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
351cb6b8299SEric Joyner
352cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), *i2cctl);
353cb6b8299SEric Joyner ixl_flush(hw);
354cb6b8299SEric Joyner /* SCL rise time (1000ns) */
355cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_RISE);
356cb6b8299SEric Joyner
357cb6b8299SEric Joyner i2cctl_r = rd32(hw, IXL_I2C_REG(hw));
358cb6b8299SEric Joyner if (i2cctl_r & I40E_GLGEN_I2CPARAMS_CLK_IN_MASK)
359cb6b8299SEric Joyner break;
360cb6b8299SEric Joyner }
361cb6b8299SEric Joyner }
362cb6b8299SEric Joyner
363cb6b8299SEric Joyner /**
364cb6b8299SEric Joyner * ixl_get_i2c_data - Reads the I2C SDA data bit
365cb6b8299SEric Joyner * @hw: pointer to hardware structure
366cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register
367cb6b8299SEric Joyner *
368cb6b8299SEric Joyner * Returns the I2C data bit value
369cb6b8299SEric Joyner **/
370cb6b8299SEric Joyner static bool
ixl_get_i2c_data(struct ixl_pf * pf,u32 * i2cctl)371cb6b8299SEric Joyner ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl)
372cb6b8299SEric Joyner {
373cb6b8299SEric Joyner bool data;
374cb6b8299SEric Joyner
375cb6b8299SEric Joyner if (*i2cctl & I40E_GLGEN_I2CPARAMS_DATA_IN_MASK)
376cb6b8299SEric Joyner data = 1;
377cb6b8299SEric Joyner else
378cb6b8299SEric Joyner data = 0;
379cb6b8299SEric Joyner
380cb6b8299SEric Joyner return data;
381cb6b8299SEric Joyner }
382cb6b8299SEric Joyner
383cb6b8299SEric Joyner /**
384cb6b8299SEric Joyner * ixl_set_i2c_data - Sets the I2C data bit
385cb6b8299SEric Joyner * @hw: pointer to hardware structure
386cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register
387cb6b8299SEric Joyner * @data: I2C data value (0 or 1) to set
388cb6b8299SEric Joyner *
389cb6b8299SEric Joyner * Sets the I2C data bit
390cb6b8299SEric Joyner **/
391cb6b8299SEric Joyner static s32
ixl_set_i2c_data(struct ixl_pf * pf,u32 * i2cctl,bool data)392cb6b8299SEric Joyner ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data)
393cb6b8299SEric Joyner {
394cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
395cb6b8299SEric Joyner s32 status = I40E_SUCCESS;
396cb6b8299SEric Joyner
397cb6b8299SEric Joyner DEBUGFUNC("ixl_set_i2c_data");
398cb6b8299SEric Joyner
399cb6b8299SEric Joyner if (data)
400cb6b8299SEric Joyner *i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
401cb6b8299SEric Joyner else
402cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK);
403cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
404cb6b8299SEric Joyner
405cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), *i2cctl);
406cb6b8299SEric Joyner ixl_flush(hw);
407cb6b8299SEric Joyner
408cb6b8299SEric Joyner /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
409cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_RISE + IXL_I2C_T_FALL + IXL_I2C_T_SU_DATA);
410cb6b8299SEric Joyner
411cb6b8299SEric Joyner /* Verify data was set correctly */
412cb6b8299SEric Joyner *i2cctl = rd32(hw, IXL_I2C_REG(hw));
413cb6b8299SEric Joyner if (data != ixl_get_i2c_data(pf, i2cctl)) {
414cb6b8299SEric Joyner status = I40E_ERR_PHY;
415cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "Error - I2C data was not set to %X.\n", data);
416cb6b8299SEric Joyner }
417cb6b8299SEric Joyner
418cb6b8299SEric Joyner return status;
419cb6b8299SEric Joyner }
420cb6b8299SEric Joyner
421cb6b8299SEric Joyner /**
422cb6b8299SEric Joyner * ixl_i2c_start - Sets I2C start condition
423cb6b8299SEric Joyner * Sets I2C start condition (High -> Low on SDA while SCL is High)
424cb6b8299SEric Joyner **/
425cb6b8299SEric Joyner static void
ixl_i2c_start(struct ixl_pf * pf)426cb6b8299SEric Joyner ixl_i2c_start(struct ixl_pf *pf)
427cb6b8299SEric Joyner {
428cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
429cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
430cb6b8299SEric Joyner
431cb6b8299SEric Joyner DEBUGFUNC("ixl_i2c_start");
432cb6b8299SEric Joyner
433cb6b8299SEric Joyner /* Start condition must begin with data and clock high */
434cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 1);
435cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl);
436cb6b8299SEric Joyner
437cb6b8299SEric Joyner /* Setup time for start condition (4.7us) */
438cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_SU_STA);
439cb6b8299SEric Joyner
440cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 0);
441cb6b8299SEric Joyner
442cb6b8299SEric Joyner /* Hold time for start condition (4us) */
443cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HD_STA);
444cb6b8299SEric Joyner
445cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl);
446cb6b8299SEric Joyner
447cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us */
448cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW);
449cb6b8299SEric Joyner
450cb6b8299SEric Joyner }
451cb6b8299SEric Joyner
452cb6b8299SEric Joyner /**
4531031d839SEric Joyner * ixl_read_i2c_byte_bb - Reads 8 bit word over I2C
454cb6b8299SEric Joyner **/
455cb6b8299SEric Joyner s32
ixl_read_i2c_byte_bb(struct ixl_pf * pf,u8 byte_offset,u8 dev_addr,u8 * data)4561031d839SEric Joyner ixl_read_i2c_byte_bb(struct ixl_pf *pf, u8 byte_offset,
457cb6b8299SEric Joyner u8 dev_addr, u8 *data)
458cb6b8299SEric Joyner {
459cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
460cb6b8299SEric Joyner u32 max_retry = 10;
461cb6b8299SEric Joyner u32 retry = 0;
462cb6b8299SEric Joyner bool nack = 1;
463cb6b8299SEric Joyner s32 status;
464cb6b8299SEric Joyner *data = 0;
465cb6b8299SEric Joyner
466cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
467cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
468cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl);
469cb6b8299SEric Joyner ixl_flush(hw);
470cb6b8299SEric Joyner
471cb6b8299SEric Joyner do {
472cb6b8299SEric Joyner ixl_i2c_start(pf);
473cb6b8299SEric Joyner
474cb6b8299SEric Joyner /* Device Address and write indication */
475cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, dev_addr);
476cb6b8299SEric Joyner if (status != I40E_SUCCESS) {
477cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "dev_addr clock out error\n");
478cb6b8299SEric Joyner goto fail;
479cb6b8299SEric Joyner }
480cb6b8299SEric Joyner
481cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf);
482cb6b8299SEric Joyner if (status != I40E_SUCCESS) {
483cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "dev_addr i2c ack error\n");
484cb6b8299SEric Joyner goto fail;
485cb6b8299SEric Joyner }
486cb6b8299SEric Joyner
487cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, byte_offset);
488cb6b8299SEric Joyner if (status != I40E_SUCCESS) {
489cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "byte_offset clock out error\n");
490cb6b8299SEric Joyner goto fail;
491cb6b8299SEric Joyner }
492cb6b8299SEric Joyner
493cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf);
494cb6b8299SEric Joyner if (status != I40E_SUCCESS) {
495cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "byte_offset i2c ack error\n");
496cb6b8299SEric Joyner goto fail;
497cb6b8299SEric Joyner }
498cb6b8299SEric Joyner
499cb6b8299SEric Joyner ixl_i2c_start(pf);
500cb6b8299SEric Joyner
501cb6b8299SEric Joyner /* Device Address and read indication */
502cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, (dev_addr | 0x1));
503cb6b8299SEric Joyner if (status != I40E_SUCCESS)
504cb6b8299SEric Joyner goto fail;
505cb6b8299SEric Joyner
506cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf);
507cb6b8299SEric Joyner if (status != I40E_SUCCESS)
508cb6b8299SEric Joyner goto fail;
509cb6b8299SEric Joyner
510cb6b8299SEric Joyner status = ixl_clock_in_i2c_byte(pf, data);
511cb6b8299SEric Joyner if (status != I40E_SUCCESS)
512cb6b8299SEric Joyner goto fail;
513cb6b8299SEric Joyner
514cb6b8299SEric Joyner status = ixl_clock_out_i2c_bit(pf, nack);
515cb6b8299SEric Joyner if (status != I40E_SUCCESS)
516cb6b8299SEric Joyner goto fail;
517cb6b8299SEric Joyner
518cb6b8299SEric Joyner ixl_i2c_stop(pf);
519cb6b8299SEric Joyner status = I40E_SUCCESS;
520cb6b8299SEric Joyner goto done;
521cb6b8299SEric Joyner
522cb6b8299SEric Joyner fail:
523cb6b8299SEric Joyner ixl_i2c_bus_clear(pf);
524cb6b8299SEric Joyner i40e_msec_delay(100);
525cb6b8299SEric Joyner retry++;
526cb6b8299SEric Joyner if (retry < max_retry)
5271031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error - Retrying\n");
528cb6b8299SEric Joyner else
5291031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error\n");
530cb6b8299SEric Joyner
531cb6b8299SEric Joyner } while (retry < max_retry);
532cb6b8299SEric Joyner done:
533cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw));
534cb6b8299SEric Joyner i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
535cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl);
536cb6b8299SEric Joyner ixl_flush(hw);
537cb6b8299SEric Joyner
538cb6b8299SEric Joyner return status;
539cb6b8299SEric Joyner }
540cb6b8299SEric Joyner
541cb6b8299SEric Joyner /**
5421031d839SEric Joyner * ixl_write_i2c_byte_bb - Writes 8 bit word over I2C
543cb6b8299SEric Joyner **/
544cb6b8299SEric Joyner s32
ixl_write_i2c_byte_bb(struct ixl_pf * pf,u8 byte_offset,u8 dev_addr,u8 data)5451031d839SEric Joyner ixl_write_i2c_byte_bb(struct ixl_pf *pf, u8 byte_offset,
546cb6b8299SEric Joyner u8 dev_addr, u8 data)
547cb6b8299SEric Joyner {
548cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw;
549cb6b8299SEric Joyner s32 status = I40E_SUCCESS;
550cb6b8299SEric Joyner u32 max_retry = 1;
551cb6b8299SEric Joyner u32 retry = 0;
552cb6b8299SEric Joyner
553cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
554cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
555cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl);
556cb6b8299SEric Joyner ixl_flush(hw);
557cb6b8299SEric Joyner
558cb6b8299SEric Joyner do {
559cb6b8299SEric Joyner ixl_i2c_start(pf);
560cb6b8299SEric Joyner
561cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, dev_addr);
562cb6b8299SEric Joyner if (status != I40E_SUCCESS)
563cb6b8299SEric Joyner goto fail;
564cb6b8299SEric Joyner
565cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf);
566cb6b8299SEric Joyner if (status != I40E_SUCCESS)
567cb6b8299SEric Joyner goto fail;
568cb6b8299SEric Joyner
569cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, byte_offset);
570cb6b8299SEric Joyner if (status != I40E_SUCCESS)
571cb6b8299SEric Joyner goto fail;
572cb6b8299SEric Joyner
573cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf);
574cb6b8299SEric Joyner if (status != I40E_SUCCESS)
575cb6b8299SEric Joyner goto fail;
576cb6b8299SEric Joyner
577cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, data);
578cb6b8299SEric Joyner if (status != I40E_SUCCESS)
579cb6b8299SEric Joyner goto fail;
580cb6b8299SEric Joyner
581cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf);
582cb6b8299SEric Joyner if (status != I40E_SUCCESS)
583cb6b8299SEric Joyner goto fail;
584cb6b8299SEric Joyner
585cb6b8299SEric Joyner ixl_i2c_stop(pf);
586cb6b8299SEric Joyner goto write_byte_out;
587cb6b8299SEric Joyner
588cb6b8299SEric Joyner fail:
589cb6b8299SEric Joyner ixl_i2c_bus_clear(pf);
590cb6b8299SEric Joyner i40e_msec_delay(100);
591cb6b8299SEric Joyner retry++;
592cb6b8299SEric Joyner if (retry < max_retry)
5931031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error - Retrying\n");
594cb6b8299SEric Joyner else
5951031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error\n");
596cb6b8299SEric Joyner } while (retry < max_retry);
597cb6b8299SEric Joyner
598cb6b8299SEric Joyner write_byte_out:
599cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw));
600cb6b8299SEric Joyner i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
601cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl);
602cb6b8299SEric Joyner ixl_flush(hw);
603cb6b8299SEric Joyner
604cb6b8299SEric Joyner return status;
605cb6b8299SEric Joyner }
606cb6b8299SEric Joyner
6071031d839SEric Joyner /**
608b4a7ce06SEric Joyner * ixl_read_i2c_byte_reg - Reads 8 bit word over I2C using a hardware register
6091031d839SEric Joyner **/
6101031d839SEric Joyner s32
ixl_read_i2c_byte_reg(struct ixl_pf * pf,u8 byte_offset,u8 dev_addr,u8 * data)6111031d839SEric Joyner ixl_read_i2c_byte_reg(struct ixl_pf *pf, u8 byte_offset,
6121031d839SEric Joyner u8 dev_addr, u8 *data)
6131031d839SEric Joyner {
6141031d839SEric Joyner struct i40e_hw *hw = &pf->hw;
6151031d839SEric Joyner u32 reg = 0;
6161031d839SEric Joyner s32 status;
6171031d839SEric Joyner *data = 0;
6181031d839SEric Joyner
6191031d839SEric Joyner reg |= (byte_offset << I40E_GLGEN_I2CCMD_REGADD_SHIFT);
6201031d839SEric Joyner reg |= (((dev_addr >> 1) & 0x7) << I40E_GLGEN_I2CCMD_PHYADD_SHIFT);
6211031d839SEric Joyner reg |= I40E_GLGEN_I2CCMD_OP_MASK;
6221031d839SEric Joyner wr32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num), reg);
6231031d839SEric Joyner
6241031d839SEric Joyner status = ixl_wait_for_i2c_completion(hw, hw->func_caps.mdio_port_num);
6251031d839SEric Joyner
6261031d839SEric Joyner /* Get data from I2C register */
6271031d839SEric Joyner reg = rd32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num));
6281031d839SEric Joyner
629b4a7ce06SEric Joyner /* Retrieve data read from EEPROM */
6301031d839SEric Joyner *data = (u8)(reg & 0xff);
6311031d839SEric Joyner
6321031d839SEric Joyner if (status)
6331031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error\n");
6341031d839SEric Joyner return status;
6351031d839SEric Joyner }
6361031d839SEric Joyner
6371031d839SEric Joyner /**
638b4a7ce06SEric Joyner * ixl_write_i2c_byte_reg - Writes 8 bit word over I2C using a hardware register
6391031d839SEric Joyner **/
6401031d839SEric Joyner s32
ixl_write_i2c_byte_reg(struct ixl_pf * pf,u8 byte_offset,u8 dev_addr,u8 data)6411031d839SEric Joyner ixl_write_i2c_byte_reg(struct ixl_pf *pf, u8 byte_offset,
6421031d839SEric Joyner u8 dev_addr, u8 data)
6431031d839SEric Joyner {
6441031d839SEric Joyner struct i40e_hw *hw = &pf->hw;
6451031d839SEric Joyner s32 status = I40E_SUCCESS;
6461031d839SEric Joyner u32 reg = 0;
6471031d839SEric Joyner u8 upperbyte = 0;
6481031d839SEric Joyner u16 datai2c = 0;
6491031d839SEric Joyner
6501031d839SEric Joyner status = ixl_read_i2c_byte_reg(pf, byte_offset + 1, dev_addr, &upperbyte);
6511031d839SEric Joyner datai2c = ((u16)upperbyte << 8) | (u16)data;
6521031d839SEric Joyner reg = rd32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num));
6531031d839SEric Joyner
6541031d839SEric Joyner /* Form write command */
6551031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_PHYADD_MASK;
6561031d839SEric Joyner reg |= (((dev_addr >> 1) & 0x7) << I40E_GLGEN_I2CCMD_PHYADD_SHIFT);
6571031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_REGADD_MASK;
6581031d839SEric Joyner reg |= (byte_offset << I40E_GLGEN_I2CCMD_REGADD_SHIFT);
6591031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_DATA_MASK;
6601031d839SEric Joyner reg |= (datai2c << I40E_GLGEN_I2CCMD_DATA_SHIFT);
6611031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_OP_MASK;
6621031d839SEric Joyner
663*5666643aSGordon Bergling /* Write command to registers controlling I2C - data and address. */
6641031d839SEric Joyner wr32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num), reg);
6651031d839SEric Joyner
6661031d839SEric Joyner status = ixl_wait_for_i2c_completion(hw, hw->func_caps.mdio_port_num);
6671031d839SEric Joyner
6681031d839SEric Joyner if (status)
6691031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error\n");
6701031d839SEric Joyner return status;
6711031d839SEric Joyner }
6721031d839SEric Joyner
6731031d839SEric Joyner /**
6741031d839SEric Joyner * ixl_wait_for_i2c_completion
6751031d839SEric Joyner **/
6761031d839SEric Joyner static s32
ixl_wait_for_i2c_completion(struct i40e_hw * hw,u8 portnum)6771031d839SEric Joyner ixl_wait_for_i2c_completion(struct i40e_hw *hw, u8 portnum)
6781031d839SEric Joyner {
6791031d839SEric Joyner s32 status = 0;
6801031d839SEric Joyner u32 timeout = 100;
6811031d839SEric Joyner u32 reg;
6821031d839SEric Joyner do {
6831031d839SEric Joyner reg = rd32(hw, I40E_GLGEN_I2CCMD(portnum));
6841031d839SEric Joyner if ((reg & I40E_GLGEN_I2CCMD_R_MASK) != 0)
6851031d839SEric Joyner break;
6861031d839SEric Joyner i40e_usec_delay(10);
6871031d839SEric Joyner } while (timeout-- > 0);
6881031d839SEric Joyner
6891031d839SEric Joyner if (timeout == 0)
6901031d839SEric Joyner return I40E_ERR_TIMEOUT;
6911031d839SEric Joyner else
6921031d839SEric Joyner return status;
6931031d839SEric Joyner }
6941031d839SEric Joyner
6951031d839SEric Joyner /**
696b4a7ce06SEric Joyner * ixl_read_i2c_byte_aq - Reads 8 bit word over I2C using an AQ command
6971031d839SEric Joyner **/
6981031d839SEric Joyner s32
ixl_read_i2c_byte_aq(struct ixl_pf * pf,u8 byte_offset,u8 dev_addr,u8 * data)6991031d839SEric Joyner ixl_read_i2c_byte_aq(struct ixl_pf *pf, u8 byte_offset,
7001031d839SEric Joyner u8 dev_addr, u8 *data)
7011031d839SEric Joyner {
7021031d839SEric Joyner struct i40e_hw *hw = &pf->hw;
7031031d839SEric Joyner s32 status = I40E_SUCCESS;
7041031d839SEric Joyner u32 reg;
7051031d839SEric Joyner
7061031d839SEric Joyner status = i40e_aq_get_phy_register(hw,
7071031d839SEric Joyner I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
708b4a7ce06SEric Joyner dev_addr, false,
7091031d839SEric Joyner byte_offset,
7101031d839SEric Joyner ®, NULL);
7111031d839SEric Joyner
7121031d839SEric Joyner if (status)
7131031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read status %s, error %s\n",
7141031d839SEric Joyner i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
7151031d839SEric Joyner else
7161031d839SEric Joyner *data = (u8)reg;
7171031d839SEric Joyner
7181031d839SEric Joyner return status;
7191031d839SEric Joyner }
7201031d839SEric Joyner
7211031d839SEric Joyner /**
722b4a7ce06SEric Joyner * ixl_write_i2c_byte_aq - Writes 8 bit word over I2C using an AQ command
7231031d839SEric Joyner **/
7241031d839SEric Joyner s32
ixl_write_i2c_byte_aq(struct ixl_pf * pf,u8 byte_offset,u8 dev_addr,u8 data)7251031d839SEric Joyner ixl_write_i2c_byte_aq(struct ixl_pf *pf, u8 byte_offset,
7261031d839SEric Joyner u8 dev_addr, u8 data)
7271031d839SEric Joyner {
7281031d839SEric Joyner struct i40e_hw *hw = &pf->hw;
7291031d839SEric Joyner s32 status = I40E_SUCCESS;
7301031d839SEric Joyner
7311031d839SEric Joyner status = i40e_aq_set_phy_register(hw,
7321031d839SEric Joyner I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE,
733b4a7ce06SEric Joyner dev_addr, false,
7341031d839SEric Joyner byte_offset,
7351031d839SEric Joyner data, NULL);
7361031d839SEric Joyner
7371031d839SEric Joyner if (status)
7381031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write status %s, error %s\n",
7391031d839SEric Joyner i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
7401031d839SEric Joyner
7411031d839SEric Joyner return status;
7421031d839SEric Joyner }
743