]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ixl/ixl_pf_i2c.c
Support for TLS offload of TOE connections on T6 adapters.
[FreeBSD/FreeBSD.git] / sys / dev / ixl / ixl_pf_i2c.c
1 /******************************************************************************
2
3   Copyright (c) 2013-2015, 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(((struct i40e_osdep *)(_hw)->back)->i2c_intfc_num)
50
51
52 static s32      ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data);
53 static bool     ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl);
54 static void     ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
55 static void     ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl);
56 static s32      ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data);
57 static s32      ixl_get_i2c_ack(struct ixl_pf *pf);
58 static s32      ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data);
59 static s32      ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data);
60 static s32      ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data);
61 static void     ixl_i2c_bus_clear(struct ixl_pf *pf);
62 static void     ixl_i2c_start(struct ixl_pf *pf);
63 static void     ixl_i2c_stop(struct ixl_pf *pf);
64
65 /**
66  *  ixl_i2c_bus_clear - Clears the I2C bus
67  *  @hw: pointer to hardware structure
68  *
69  *  Clears the I2C bus by sending nine clock pulses.
70  *  Used when data line is stuck low.
71  **/
72 static void
73 ixl_i2c_bus_clear(struct ixl_pf *pf)
74 {
75         struct i40e_hw *hw = &pf->hw;
76         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
77         u32 i;
78
79         DEBUGFUNC("ixl_i2c_bus_clear");
80
81         ixl_i2c_start(pf);
82
83         ixl_set_i2c_data(pf, &i2cctl, 1);
84
85         for (i = 0; i < 9; i++) {
86                 ixl_raise_i2c_clk(pf, &i2cctl);
87
88                 /* Min high period of clock is 4us */
89                 i40e_usec_delay(IXL_I2C_T_HIGH);
90
91                 ixl_lower_i2c_clk(pf, &i2cctl);
92
93                 /* Min low period of clock is 4.7us*/
94                 i40e_usec_delay(IXL_I2C_T_LOW);
95         }
96
97         ixl_i2c_start(pf);
98
99         /* Put the i2c bus back to default state */
100         ixl_i2c_stop(pf);
101 }
102
103 /**
104  *  ixl_i2c_stop - Sets I2C stop condition
105  *  @hw: pointer to hardware structure
106  *
107  *  Sets I2C stop condition (Low -> High on SDA while SCL is High)
108  **/
109 static void
110 ixl_i2c_stop(struct ixl_pf *pf)
111 {
112         struct i40e_hw *hw = &pf->hw;
113         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
114
115         DEBUGFUNC("ixl_i2c_stop");
116
117         /* Stop condition must begin with data low and clock high */
118         ixl_set_i2c_data(pf, &i2cctl, 0);
119         ixl_raise_i2c_clk(pf, &i2cctl);
120
121         /* Setup time for stop condition (4us) */
122         i40e_usec_delay(IXL_I2C_T_SU_STO);
123
124         ixl_set_i2c_data(pf, &i2cctl, 1);
125
126         /* bus free time between stop and start (4.7us)*/
127         i40e_usec_delay(IXL_I2C_T_BUF);
128 }
129
130 /**
131  *  ixl_clock_in_i2c_byte - Clocks in one byte via I2C
132  *  @hw: pointer to hardware structure
133  *  @data: data byte to clock in
134  *
135  *  Clocks in one byte data via I2C data/clock
136  **/
137 static s32
138 ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data)
139 {
140         s32 i;
141         bool bit = 0;
142
143         DEBUGFUNC("ixl_clock_in_i2c_byte");
144
145         for (i = 7; i >= 0; i--) {
146                 ixl_clock_in_i2c_bit(pf, &bit);
147                 *data |= bit << i;
148         }
149
150         return I40E_SUCCESS;
151 }
152
153 /**
154  *  ixl_clock_in_i2c_bit - Clocks in one bit via I2C data/clock
155  *  @hw: pointer to hardware structure
156  *  @data: read data value
157  *
158  *  Clocks in one bit via I2C data/clock
159  **/
160 static s32
161 ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data)
162 {
163         struct i40e_hw *hw = &pf->hw;
164         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
165
166         DEBUGFUNC("ixl_clock_in_i2c_bit");
167
168         ixl_raise_i2c_clk(pf, &i2cctl);
169
170         /* Minimum high period of clock is 4us */
171         i40e_usec_delay(IXL_I2C_T_HIGH);
172
173         i2cctl = rd32(hw, IXL_I2C_REG(hw));
174         i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
175         wr32(hw, IXL_I2C_REG(hw), i2cctl);
176         ixl_flush(hw);
177
178         i2cctl = rd32(hw, IXL_I2C_REG(hw));
179         *data = ixl_get_i2c_data(pf, &i2cctl);
180
181         ixl_lower_i2c_clk(pf, &i2cctl);
182
183         /* Minimum low period of clock is 4.7 us */
184         i40e_usec_delay(IXL_I2C_T_LOW);
185
186         return I40E_SUCCESS;
187 }
188
189 /**
190  *  ixl_get_i2c_ack - Polls for I2C ACK
191  *  @hw: pointer to hardware structure
192  *
193  *  Clocks in/out one bit via I2C data/clock
194  **/
195 static s32
196 ixl_get_i2c_ack(struct ixl_pf *pf)
197 {
198         struct i40e_hw *hw = &pf->hw;
199         s32 status = I40E_SUCCESS;
200         u32 i = 0;
201         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
202         u32 timeout = 10;
203         bool ack = 1;
204
205         ixl_raise_i2c_clk(pf, &i2cctl);
206
207         /* Minimum high period of clock is 4us */
208         i40e_usec_delay(IXL_I2C_T_HIGH);
209
210         i2cctl = rd32(hw, IXL_I2C_REG(hw));
211         i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK;
212         wr32(hw, IXL_I2C_REG(hw), i2cctl);
213         ixl_flush(hw);
214
215         /* Poll for ACK.  Note that ACK in I2C spec is
216          * transition from 1 to 0 */
217         for (i = 0; i < timeout; i++) {
218                 i2cctl = rd32(hw, IXL_I2C_REG(hw));
219                 ack = ixl_get_i2c_data(pf, &i2cctl);
220
221                 i40e_usec_delay(1);
222                 if (!ack)
223                         break;
224         }
225
226         if (ack) {
227                 ixl_dbg(pf, IXL_DBG_I2C, "I2C ack was not received.\n");
228                 status = I40E_ERR_PHY;
229         }
230
231         ixl_lower_i2c_clk(pf, &i2cctl);
232
233         /* Minimum low period of clock is 4.7 us */
234         i40e_usec_delay(IXL_I2C_T_LOW);
235
236         return status;
237 }
238
239 /**
240  *  ixl_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock
241  *  @hw: pointer to hardware structure
242  *  @data: data value to write
243  *
244  *  Clocks out one bit via I2C data/clock
245  **/
246 static s32
247 ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data)
248 {
249         struct i40e_hw *hw = &pf->hw;
250         s32 status;
251         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
252
253         status = ixl_set_i2c_data(pf, &i2cctl, data);
254         if (status == I40E_SUCCESS) {
255                 ixl_raise_i2c_clk(pf, &i2cctl);
256
257                 /* Minimum high period of clock is 4us */
258                 i40e_usec_delay(IXL_I2C_T_HIGH);
259
260                 ixl_lower_i2c_clk(pf, &i2cctl);
261
262                 /* Minimum low period of clock is 4.7 us.
263                  * This also takes care of the data hold time.
264                  */
265                 i40e_usec_delay(IXL_I2C_T_LOW);
266         } else {
267                 status = I40E_ERR_PHY;
268                 ixl_dbg(pf, IXL_DBG_I2C, "I2C data was not set to %#x\n", data);
269         }
270
271         return status;
272 }
273
274 /**
275  *  ixl_clock_out_i2c_byte - Clocks out one byte via I2C
276  *  @hw: pointer to hardware structure
277  *  @data: data byte clocked out
278  *
279  *  Clocks out one byte data via I2C data/clock
280  **/
281 static s32
282 ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data)
283 {
284         struct i40e_hw *hw = &pf->hw;
285         s32 status = I40E_SUCCESS;
286         s32 i;
287         u32 i2cctl;
288         bool bit;
289
290         DEBUGFUNC("ixl_clock_out_i2c_byte");
291
292         for (i = 7; i >= 0; i--) {
293                 bit = (data >> i) & 0x1;
294                 status = ixl_clock_out_i2c_bit(pf, bit);
295
296                 if (status != I40E_SUCCESS)
297                         break;
298         }
299
300         /* Release SDA line (set high) */
301         i2cctl = rd32(hw, IXL_I2C_REG(hw));
302         i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
303         i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
304         wr32(hw, IXL_I2C_REG(hw), i2cctl);
305         ixl_flush(hw);
306
307         return status;
308 }
309
310 /**
311  *  ixl_lower_i2c_clk - Lowers the I2C SCL clock
312  *  @hw: pointer to hardware structure
313  *  @i2cctl: Current value of I2CCTL register
314  *
315  *  Lowers the I2C clock line '1'->'0'
316  **/
317 static void
318 ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
319 {
320         struct i40e_hw *hw = &pf->hw;
321
322         *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_MASK);
323         *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
324
325         wr32(hw, IXL_I2C_REG(hw), *i2cctl);
326         ixl_flush(hw);
327
328         /* SCL fall time (300ns) */
329         i40e_usec_delay(IXL_I2C_T_FALL);
330 }
331
332 /**
333  *  ixl_raise_i2c_clk - Raises the I2C SCL clock
334  *  @hw: pointer to hardware structure
335  *  @i2cctl: Current value of I2CCTL register
336  *
337  *  Raises the I2C clock line '0'->'1'
338  **/
339 static void
340 ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl)
341 {
342         struct i40e_hw *hw = &pf->hw;
343         u32 i = 0;
344         u32 timeout = IXL_I2C_CLOCK_STRETCHING_TIMEOUT;
345         u32 i2cctl_r = 0;
346
347         for (i = 0; i < timeout; i++) {
348                 *i2cctl |= I40E_GLGEN_I2CPARAMS_CLK_MASK;
349                 *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK);
350
351                 wr32(hw, IXL_I2C_REG(hw), *i2cctl);
352                 ixl_flush(hw);
353                 /* SCL rise time (1000ns) */
354                 i40e_usec_delay(IXL_I2C_T_RISE);
355
356                 i2cctl_r = rd32(hw, IXL_I2C_REG(hw));
357                 if (i2cctl_r & I40E_GLGEN_I2CPARAMS_CLK_IN_MASK)
358                         break;
359         }
360 }
361
362 /**
363  *  ixl_get_i2c_data - Reads the I2C SDA data bit
364  *  @hw: pointer to hardware structure
365  *  @i2cctl: Current value of I2CCTL register
366  *
367  *  Returns the I2C data bit value
368  **/
369 static bool
370 ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl)
371 {
372         bool data;
373
374         if (*i2cctl & I40E_GLGEN_I2CPARAMS_DATA_IN_MASK)
375                 data = 1;
376         else
377                 data = 0;
378
379         return data;
380 }
381
382 /**
383  *  ixl_set_i2c_data - Sets the I2C data bit
384  *  @hw: pointer to hardware structure
385  *  @i2cctl: Current value of I2CCTL register
386  *  @data: I2C data value (0 or 1) to set
387  *
388  *  Sets the I2C data bit
389  **/
390 static s32
391 ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data)
392 {
393         struct i40e_hw *hw = &pf->hw;
394         s32 status = I40E_SUCCESS;
395
396         DEBUGFUNC("ixl_set_i2c_data");
397
398         if (data)
399                 *i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK;
400         else
401                 *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK);
402         *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK);
403
404         wr32(hw, IXL_I2C_REG(hw), *i2cctl);
405         ixl_flush(hw);
406
407         /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */
408         i40e_usec_delay(IXL_I2C_T_RISE + IXL_I2C_T_FALL + IXL_I2C_T_SU_DATA);
409
410         /* Verify data was set correctly */
411         *i2cctl = rd32(hw, IXL_I2C_REG(hw));
412         if (data != ixl_get_i2c_data(pf, i2cctl)) {
413                 status = I40E_ERR_PHY;
414                 ixl_dbg(pf, IXL_DBG_I2C, "Error - I2C data was not set to %X.\n", data);
415         }
416
417         return status;
418 }
419
420 /**
421  *  ixl_i2c_start - Sets I2C start condition
422  *  Sets I2C start condition (High -> Low on SDA while SCL is High)
423  **/
424 static void
425 ixl_i2c_start(struct ixl_pf *pf)
426 {
427         struct i40e_hw *hw = &pf->hw;
428         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
429
430         DEBUGFUNC("ixl_i2c_start");
431
432         /* Start condition must begin with data and clock high */
433         ixl_set_i2c_data(pf, &i2cctl, 1);
434         ixl_raise_i2c_clk(pf, &i2cctl);
435
436         /* Setup time for start condition (4.7us) */
437         i40e_usec_delay(IXL_I2C_T_SU_STA);
438
439         ixl_set_i2c_data(pf, &i2cctl, 0);
440
441         /* Hold time for start condition (4us) */
442         i40e_usec_delay(IXL_I2C_T_HD_STA);
443
444         ixl_lower_i2c_clk(pf, &i2cctl);
445
446         /* Minimum low period of clock is 4.7 us */
447         i40e_usec_delay(IXL_I2C_T_LOW);
448
449 }
450
451 /**
452  *  ixl_read_i2c_byte - Reads 8 bit word over I2C
453  **/
454 s32
455 ixl_read_i2c_byte(struct ixl_pf *pf, u8 byte_offset,
456                   u8 dev_addr, u8 *data)
457 {
458         struct i40e_hw *hw = &pf->hw;
459         u32 max_retry = 10;
460         u32 retry = 0;
461         bool nack = 1;
462         s32 status;
463         *data = 0;
464
465         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
466         i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
467         wr32(hw, IXL_I2C_REG(hw), i2cctl);
468         ixl_flush(hw);
469
470         do {
471                 ixl_i2c_start(pf);
472
473                 /* Device Address and write indication */
474                 status = ixl_clock_out_i2c_byte(pf, dev_addr);
475                 if (status != I40E_SUCCESS) {
476                         ixl_dbg(pf, IXL_DBG_I2C, "dev_addr clock out error\n");
477                         goto fail;
478                 }
479
480                 status = ixl_get_i2c_ack(pf);
481                 if (status != I40E_SUCCESS) {
482                         ixl_dbg(pf, IXL_DBG_I2C, "dev_addr i2c ack error\n");
483                         goto fail;
484                 }
485
486                 status = ixl_clock_out_i2c_byte(pf, byte_offset);
487                 if (status != I40E_SUCCESS) {
488                         ixl_dbg(pf, IXL_DBG_I2C, "byte_offset clock out error\n");
489                         goto fail;
490                 }
491
492                 status = ixl_get_i2c_ack(pf);
493                 if (status != I40E_SUCCESS) {
494                         ixl_dbg(pf, IXL_DBG_I2C, "byte_offset i2c ack error\n");
495                         goto fail;
496                 }
497
498                 ixl_i2c_start(pf);
499
500                 /* Device Address and read indication */
501                 status = ixl_clock_out_i2c_byte(pf, (dev_addr | 0x1));
502                 if (status != I40E_SUCCESS)
503                         goto fail;
504
505                 status = ixl_get_i2c_ack(pf);
506                 if (status != I40E_SUCCESS)
507                         goto fail;
508
509                 status = ixl_clock_in_i2c_byte(pf, data);
510                 if (status != I40E_SUCCESS)
511                         goto fail;
512
513                 status = ixl_clock_out_i2c_bit(pf, nack);
514                 if (status != I40E_SUCCESS)
515                         goto fail;
516
517                 ixl_i2c_stop(pf);
518                 status = I40E_SUCCESS;
519                 goto done;
520
521 fail:
522                 ixl_i2c_bus_clear(pf);
523                 i40e_msec_delay(100);
524                 retry++;
525                 if (retry < max_retry)
526                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error - Retrying.\n");
527                 else
528                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error.\n");
529
530         } while (retry < max_retry);
531 done:
532         i2cctl = rd32(hw, IXL_I2C_REG(hw));
533         i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
534         wr32(hw, IXL_I2C_REG(hw), i2cctl);
535         ixl_flush(hw);
536
537         return status;
538 }
539
540 /**
541  *  ixl_write_i2c_byte - Writes 8 bit word over I2C
542  **/
543 s32
544 ixl_write_i2c_byte(struct ixl_pf *pf, u8 byte_offset,
545                        u8 dev_addr, u8 data)
546 {
547         struct i40e_hw *hw = &pf->hw;
548         s32 status = I40E_SUCCESS;
549         u32 max_retry = 1;
550         u32 retry = 0;
551
552         u32 i2cctl = rd32(hw, IXL_I2C_REG(hw));
553         i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
554         wr32(hw, IXL_I2C_REG(hw), i2cctl);
555         ixl_flush(hw);
556
557         do {
558                 ixl_i2c_start(pf);
559
560                 status = ixl_clock_out_i2c_byte(pf, dev_addr);
561                 if (status != I40E_SUCCESS)
562                         goto fail;
563
564                 status = ixl_get_i2c_ack(pf);
565                 if (status != I40E_SUCCESS)
566                         goto fail;
567
568                 status = ixl_clock_out_i2c_byte(pf, byte_offset);
569                 if (status != I40E_SUCCESS)
570                         goto fail;
571
572                 status = ixl_get_i2c_ack(pf);
573                 if (status != I40E_SUCCESS)
574                         goto fail;
575
576                 status = ixl_clock_out_i2c_byte(pf, data);
577                 if (status != I40E_SUCCESS)
578                         goto fail;
579
580                 status = ixl_get_i2c_ack(pf);
581                 if (status != I40E_SUCCESS)
582                         goto fail;
583
584                 ixl_i2c_stop(pf);
585                 goto write_byte_out;
586
587 fail:
588                 ixl_i2c_bus_clear(pf);
589                 i40e_msec_delay(100);
590                 retry++;
591                 if (retry < max_retry)
592                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error - Retrying.\n");
593                 else
594                         ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error.\n");
595         } while (retry < max_retry);
596
597 write_byte_out:
598         i2cctl = rd32(hw, IXL_I2C_REG(hw));
599         i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK;
600         wr32(hw, IXL_I2C_REG(hw), i2cctl);
601         ixl_flush(hw);
602
603         return status;
604 }
605