1 /*
2 * Copyright 2007-2013 Solarflare Communications Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 #include "efsys.h"
27 #include "efx.h"
28 #include "efx_types.h"
29 #include "efx_regs.h"
30 #include "efx_impl.h"
31
32 #if EFSYS_OPT_FALCON
33
34 #define I2C_READ_CMD(_devid) (((_devid) << 1) | 1)
35 #define I2C_WRITE_CMD(_devid) (((_devid) << 1) | 0)
36
37 #define I2C_PERIOD 100
38
39 #define I2C_RETRY_LIMIT 10
40
41 static void
42 falcon_i2c_set_sda_scl(
43 __in efx_nic_t *enp,
44 __in falcon_i2c_t *fip,
45 __inout_opt efsys_timestamp_t *timep)
46 {
47 efx_oword_t oword;
48 efsys_timestamp_t delta = 0;
49
50 EFSYS_SPIN(I2C_PERIOD);
51 delta += I2C_PERIOD;
52
53 /* Set the pin state */
54 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
55
56 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO3_OUT, 0);
57 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO3_OEN,
58 fip->fi_sda ? 0 : 1);
59
60 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO0_OEN, 1);
61 EFX_SET_OWORD_FIELD(oword, FRF_AB_GPIO0_OUT,
62 fip->fi_scl ? 1 : 0);
63
64 EFX_BAR_WRITEO(enp, FR_AB_GPIO_CTL_REG, &oword);
65
66 EFSYS_SPIN(I2C_PERIOD);
67 delta += I2C_PERIOD;
68
69 if (timep != NULL)
70 *timep += delta;
71 }
72
73 static __checkReturn boolean_t
74 falcon_i2c_get_sda(
75 __in efx_nic_t *enp,
76 __inout_opt efsys_timestamp_t *timep)
77 {
78 efx_oword_t oword;
79 efsys_timestamp_t delta = 0;
80 boolean_t state;
81
82 EFSYS_SPIN(I2C_PERIOD);
83 delta += I2C_PERIOD;
84
85 /* Get the pin state */
86 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
87 state = (EFX_OWORD_FIELD(oword, FRF_AB_GPIO3_IN) != 0);
88
89 EFSYS_SPIN(I2C_PERIOD);
90 delta += I2C_PERIOD;
91
92 if (timep != NULL)
93 *timep += delta;
94
95 return (state);
96 }
97
98 static __checkReturn boolean_t
99 falcon_i2c_get_scl(
100 __in efx_nic_t *enp,
101 __inout_opt efsys_timestamp_t *timep)
102 {
103 efx_oword_t oword;
104 efsys_timestamp_t delta = 0;
105 boolean_t state;
106
107 EFSYS_SPIN(I2C_PERIOD);
108 delta += I2C_PERIOD;
109
110 /* Get the pin state */
111 EFX_BAR_READO(enp, FR_AB_GPIO_CTL_REG, &oword);
112 state = (EFX_OWORD_FIELD(oword, FRF_AB_GPIO0_IN) != 0);
113
114 EFSYS_SPIN(I2C_PERIOD);
115 delta += I2C_PERIOD;
116
117 if (timep != NULL)
118 *timep += delta;
119
120 return (state);
121 }
122
123 static void
124 falcon_i2c_sda_write(
125 __in efx_nic_t *enp,
126 __in boolean_t on,
127 __inout_opt efsys_timestamp_t *timep)
128 {
129 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
130
131 fip->fi_sda = on;
132 falcon_i2c_set_sda_scl(enp, fip, timep);
133 }
134
135 static void
136 falcon_i2c_scl_write(
137 __in efx_nic_t *enp,
138 __in boolean_t on,
139 __inout_opt efsys_timestamp_t *timep)
140 {
141 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
142
143 fip->fi_scl = on;
144 falcon_i2c_set_sda_scl(enp, fip, timep);
145 }
146
147 static void
148 falcon_i2c_start(
149 __in efx_nic_t *enp,
150 __inout_opt efsys_timestamp_t *timep)
151 {
152 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
153
154 EFSYS_ASSERT(timep != NULL);
155
156 EFSYS_ASSERT(fip->fi_sda);
157
158 falcon_i2c_scl_write(enp, B_TRUE, timep);
159 falcon_i2c_sda_write(enp, B_FALSE, timep);
160 falcon_i2c_scl_write(enp, B_FALSE, timep);
161 falcon_i2c_sda_write(enp, B_TRUE, timep);
162 }
163
164 static void
165 falcon_i2c_bit_out(
166 __in efx_nic_t *enp,
167 __in boolean_t bit,
168 __inout_opt efsys_timestamp_t *timep)
169 {
170 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
171
172 EFSYS_ASSERT(timep != NULL);
173
174 EFSYS_ASSERT(!(fip->fi_scl));
175
176 falcon_i2c_sda_write(enp, bit, timep);
177 falcon_i2c_scl_write(enp, B_TRUE, timep);
178 falcon_i2c_scl_write(enp, B_FALSE, timep);
179 falcon_i2c_sda_write(enp, B_TRUE, timep);
180 }
181
182 static boolean_t
183 falcon_i2c_bit_in(
184 __in efx_nic_t *enp,
185 __inout_opt efsys_timestamp_t *timep)
186 {
187 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
188 boolean_t bit;
189
190 EFSYS_ASSERT(timep != NULL);
191
192 EFSYS_ASSERT(!(fip->fi_scl));
193 EFSYS_ASSERT(fip->fi_sda);
194
195 falcon_i2c_scl_write(enp, B_TRUE, timep);
196 bit = falcon_i2c_get_sda(enp, timep);
197 falcon_i2c_scl_write(enp, B_FALSE, timep);
198
199 return (bit);
200 }
201
202 static void
203 falcon_i2c_stop(
204 __in efx_nic_t *enp,
205 __inout_opt efsys_timestamp_t *timep)
206 {
207 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
208
209 EFSYS_ASSERT(timep != NULL);
210
211 EFSYS_ASSERT(!(fip->fi_scl));
212
213 falcon_i2c_sda_write(enp, B_FALSE, timep);
214 falcon_i2c_scl_write(enp, B_TRUE, timep);
215 falcon_i2c_sda_write(enp, B_TRUE, timep);
216 }
217
218 static void
219 falcon_i2c_release(
220 __in efx_nic_t *enp,
221 __inout_opt efsys_timestamp_t *timep)
222 {
223 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
224
225 EFSYS_ASSERT(timep != NULL);
226
227 falcon_i2c_scl_write(enp, B_TRUE, timep);
228 falcon_i2c_sda_write(enp, B_TRUE, timep);
229
230 EFSYS_ASSERT(falcon_i2c_get_sda(enp, timep));
231 EFSYS_ASSERT(falcon_i2c_get_scl(enp, timep));
232
233 EFSYS_ASSERT(fip->fi_scl);
234 EFSYS_ASSERT(fip->fi_sda);
235
236 EFSYS_SPIN(10000);
237 *timep += 10000;
238 }
239
240 static __checkReturn int
241 falcon_i2c_wait(
242 __in efx_nic_t *enp)
243 {
244 falcon_i2c_t *fip = &(enp->en_u.falcon.enu_fip);
245 int count;
246 int rc;
247
248 if (enp->en_u.falcon.enu_i2c_locked) {
249 rc = EBUSY;
250 goto fail1;
251 }
252
253 EFSYS_ASSERT(fip->fi_scl);
254 EFSYS_ASSERT(fip->fi_sda);
255
256 count = 0;
257 do {
258 EFSYS_PROBE1(wait, unsigned int, count);
259
260 if (falcon_i2c_get_scl(enp, NULL) &&
261 falcon_i2c_get_sda(enp, NULL))
262 goto done;
263
264 /* Spin for 1 ms */
265 EFSYS_SPIN(1000);
266
267 } while (++count < 20);
268
269 rc = ETIMEDOUT;
270 goto fail2;
271
272 done:
273 return (0);
274
275 fail2:
276 EFSYS_PROBE(fail2);
277 fail1:
278 EFSYS_PROBE1(fail1, int, rc);
279
280 return (rc);
281 }
282
283 static __checkReturn int
284 falcon_i2c_byte_out(
285 __in efx_nic_t *enp,
286 __in uint8_t byte,
287 __inout_opt efsys_timestamp_t *timep)
288 {
289 unsigned int bit;
290
291 for (bit = 0; bit < 8; bit++) {
292 falcon_i2c_bit_out(enp, ((byte & 0x80) != 0), timep);
293 byte <<= 1;
294 }
295
296 /* Check for acknowledgement */
297 return ((falcon_i2c_bit_in(enp, timep)) ? EIO : 0);
298 }
299
300 static uint8_t
301 falcon_i2c_byte_in(
302 __in efx_nic_t *enp,
303 __in boolean_t ack,
304 __inout_opt efsys_timestamp_t *timep)
305 {
306 uint8_t byte;
307 unsigned int bit;
308
309 byte = 0;
310 for (bit = 0; bit < 8; bit++) {
311 byte <<= 1;
312 byte |= falcon_i2c_bit_in(enp, timep);
313 }
314
315 /* Send acknowledgement */
316 falcon_i2c_bit_out(enp, !ack, timep);
317
318 return (byte);
319 }
320
321 __checkReturn int
322 falcon_i2c_check(
323 __in efx_nic_t *enp,
324 __in uint8_t devid)
325 {
326 int pstate;
327 int lstate;
328 efsys_timestamp_t start;
329 efsys_timestamp_t end;
330 efsys_timestamp_t expected;
331 unsigned int attempt;
332 int rc;
333
334 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
335 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
336
337 EFSYS_LOCK(enp->en_eslp, lstate);
338 EFSYS_PREEMPT_DISABLE(pstate);
339
340 /* Check the state of the I2C bus */
341 if ((rc = falcon_i2c_wait(enp)) != 0)
342 goto fail1;
343
344 attempt = 0;
345
346 again:
347 EFSYS_TIMESTAMP(&start);
348 expected = 0;
349
350 /* Select device and write cycle */
351 falcon_i2c_start(enp, &expected);
352
353 if ((rc = falcon_i2c_byte_out(enp, I2C_WRITE_CMD(devid),
354 &expected)) != 0)
355 goto fail2;
356
357 /* Abort the cycle since we're only testing the target is there */
358 falcon_i2c_stop(enp, &expected);
359 falcon_i2c_release(enp, &expected);
360
361 EFSYS_TIMESTAMP(&end);
362
363 /* The transaction may have timed out */
364 if (end - start > expected * 2) {
365 if (++attempt < I2C_RETRY_LIMIT) {
366 EFSYS_PROBE1(retry, unsigned int, attempt);
367
368 goto again;
369 }
370
371 rc = ETIMEDOUT;
372 goto fail3;
373 }
374
375 EFSYS_PREEMPT_ENABLE(pstate);
376 EFSYS_UNLOCK(enp->en_eslp, lstate);
377
378 EFSYS_PROBE(success);
379 return (0);
380
381 fail3:
382 EFSYS_PROBE(fail3);
383
384 goto fail1;
385
386 fail2:
387 falcon_i2c_stop(enp, &expected);
388 falcon_i2c_release(enp, &expected);
389
390 EFSYS_TIMESTAMP(&end);
391
392 /* The transaction may have timed out */
393 if (end - start > expected * 2) {
394 if (++attempt < I2C_RETRY_LIMIT) {
395 EFSYS_PROBE1(retry, unsigned int, attempt);
396
397 goto again;
398 }
399
400 rc = ETIMEDOUT;
401 }
402
403 EFSYS_PROBE(fail2);
404
405 fail1:
406 EFSYS_PROBE1(fail1, int, rc);
407
408 EFSYS_PREEMPT_ENABLE(pstate);
409 EFSYS_UNLOCK(enp->en_eslp, lstate);
410 return (rc);
411 }
412
413 __checkReturn int
414 falcon_i2c_read(
415 __in efx_nic_t *enp,
416 __in uint8_t devid,
417 __in uint8_t addr,
418 __out_bcount(size) caddr_t base,
419 __in size_t size)
420 {
421 int pstate;
422 int lstate;
423 efsys_timestamp_t start;
424 efsys_timestamp_t end;
425 efsys_timestamp_t expected;
426 unsigned int attempt;
427 unsigned int i;
428 int rc;
429
430 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
431 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
432
433 EFSYS_ASSERT(size != 0);
434
435 EFSYS_LOCK(enp->en_eslp, lstate);
436 EFSYS_PREEMPT_DISABLE(pstate);
437
438 /* Check the state of the I2C bus */
439 if ((rc = falcon_i2c_wait(enp)) != 0)
440 goto fail1;
441
442 attempt = 0;
443
444 again:
445 EFSYS_TIMESTAMP(&start);
446 expected = 0;
447
448 /* Select device and write cycle */
449 falcon_i2c_start(enp, &expected);
450
451 if ((rc = falcon_i2c_byte_out(enp, I2C_WRITE_CMD(devid),
452 &expected)) != 0)
453 goto fail2;
454
455 /* Write address */
456 if ((rc = falcon_i2c_byte_out(enp, addr, &expected)) != 0)
457 goto fail3;
458
459 /* Select device and read cycle */
460 falcon_i2c_start(enp, &expected);
461
462 if ((rc = falcon_i2c_byte_out(enp, I2C_READ_CMD(devid),
463 &expected)) != 0)
464 goto fail4;
465
466 /* Read bytes */
467 for (i = 0; i < size; i++)
468 *(uint8_t *)(base + i) =
469 falcon_i2c_byte_in(enp, (i < size - 1), &expected);
470
471 falcon_i2c_stop(enp, &expected);
472 falcon_i2c_release(enp, &expected);
473
474 EFSYS_TIMESTAMP(&end);
475
476 /* The transaction may have timed out */
477 if (end - start > expected * 2) {
478 if (++attempt < I2C_RETRY_LIMIT) {
479 EFSYS_PROBE1(retry, unsigned int, attempt);
480
481 goto again;
482 }
483
484 rc = ETIMEDOUT;
485 goto fail5;
486 }
487
488 EFSYS_PREEMPT_ENABLE(pstate);
489 EFSYS_UNLOCK(enp->en_eslp, lstate);
490 return (0);
491
492 fail5:
493 EFSYS_PROBE(fail5);
494
495 goto fail1;
496
497 fail4:
498 EFSYS_PROBE(fail4);
499 fail3:
500 EFSYS_PROBE(fail3);
501 fail2:
502 falcon_i2c_stop(enp, &expected);
503 falcon_i2c_release(enp, &expected);
504
505 EFSYS_TIMESTAMP(&end);
506
507 /* The transaction may have timed out */
508 if (end - start > expected * 2) {
509 if (++attempt < I2C_RETRY_LIMIT) {
510 EFSYS_PROBE1(retry, unsigned int, attempt);
511
512 goto again;
513 }
514
515 rc = ETIMEDOUT;
516 }
517
518 EFSYS_PROBE(fail2);
519
520 fail1:
521 EFSYS_PROBE1(fail1, int, rc);
522
523 EFSYS_PREEMPT_ENABLE(pstate);
524 EFSYS_UNLOCK(enp->en_eslp, lstate);
525 return (rc);
526 }
527
528 __checkReturn int
529 falcon_i2c_write(
530 __in efx_nic_t *enp,
531 __in uint8_t devid,
532 __in uint8_t addr,
533 __in_bcount(size) caddr_t base,
534 __in size_t size)
535 {
536 int pstate;
537 int lstate;
538 efsys_timestamp_t start;
539 efsys_timestamp_t end;
540 efsys_timestamp_t expected;
541 unsigned int attempt;
542 unsigned int i;
543 int rc;
544
545 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
546 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
547
548 EFSYS_ASSERT(size != 0);
549
550 EFSYS_LOCK(enp->en_eslp, lstate);
551 EFSYS_PREEMPT_DISABLE(pstate);
552
553 /* Check the state of the I2C bus */
554 if ((rc = falcon_i2c_wait(enp)) != 0)
555 goto fail1;
556
557 attempt = 0;
558
559 again:
560 EFSYS_TIMESTAMP(&start);
561 expected = 0;
562
563 /* Select device and write cycle */
564 falcon_i2c_start(enp, &expected);
565
566 if ((rc = falcon_i2c_byte_out(enp, I2C_WRITE_CMD(devid),
567 &expected)) != 0)
568 goto fail2;
569
570 /* Write address */
571 if ((rc = falcon_i2c_byte_out(enp, addr, &expected)) != 0)
572 goto fail3;
573
574 /* Write bytes */
575 for (i = 0; i < size; i++) {
576 if ((rc = falcon_i2c_byte_out(enp, *(uint8_t *)(base + i),
577 &expected)) != 0)
578 goto fail4;
579 }
580
581 falcon_i2c_stop(enp, &expected);
582 falcon_i2c_release(enp, &expected);
583
584 EFSYS_TIMESTAMP(&end);
585
586 /* The transaction may have timed out */
587 if (end - start > expected * 2) {
588 if (++attempt < I2C_RETRY_LIMIT) {
589 EFSYS_PROBE1(retry, unsigned int, attempt);
590
591 goto again;
592 }
593
594 rc = ETIMEDOUT;
595 goto fail5;
596 }
597
598 EFSYS_PREEMPT_ENABLE(pstate);
599 EFSYS_UNLOCK(enp->en_eslp, lstate);
600 return (0);
601
602 fail5:
603 EFSYS_PROBE(fail5);
604
605 goto fail1;
606
607 fail4:
608 EFSYS_PROBE(fail4);
609 fail3:
610 EFSYS_PROBE(fail3);
611 fail2:
612 falcon_i2c_stop(enp, &expected);
613 falcon_i2c_release(enp, &expected);
614
615 EFSYS_TIMESTAMP(&end);
616
617 /* The transaction may have timed out */
618 if (end - start > expected * 2) {
619 if (++attempt < I2C_RETRY_LIMIT) {
620 EFSYS_PROBE1(retry, unsigned int, attempt);
621
622 goto again;
623 }
624
625 rc = ETIMEDOUT;
626 }
627
628 EFSYS_PROBE(fail2);
629
630 fail1:
631 EFSYS_PROBE1(fail1, int, rc);
632
633 EFSYS_PREEMPT_ENABLE(pstate);
634 EFSYS_UNLOCK(enp->en_eslp, lstate);
635 return (rc);
636 }
637
638 #if EFSYS_OPT_PHY_NULL
639
640 __checkReturn int
641 falcon_i2c_recv(
642 __in efx_nic_t *enp,
643 __in uint8_t devid,
644 __out_bcount(size) caddr_t base,
645 __in size_t size)
646 {
647 int pstate;
648 int lstate;
649 efsys_timestamp_t start;
650 efsys_timestamp_t end;
651 efsys_timestamp_t expected;
652 unsigned int attempt;
653 unsigned int i;
654 int rc;
655
656 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
657 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
658
659 EFSYS_ASSERT(size != 0);
660
661 EFSYS_LOCK(enp->en_eslp, lstate);
662 EFSYS_PREEMPT_DISABLE(pstate);
663
664 /* Check the state of the I2C bus */
665 if ((rc = falcon_i2c_wait(enp)) != 0)
666 goto fail1;
667
668 attempt = 0;
669
670 again:
671 EFSYS_TIMESTAMP(&start);
672 expected = 0;
673
674 /* Select device and read cycle */
675 falcon_i2c_start(enp, &expected);
676
677 if ((rc = falcon_i2c_byte_out(enp, I2C_READ_CMD(devid), &expected))
678 != 0)
679 goto fail2;
680
681 /* Read bytes */
682 for (i = 0; i < size; i++)
683 *(uint8_t *)(base + i) = falcon_i2c_byte_in(enp, (i < size - 1),
684 &expected);
685
686 falcon_i2c_stop(enp, &expected);
687 falcon_i2c_release(enp, &expected);
688
689 EFSYS_TIMESTAMP(&end);
690
691 /* The transaction may have timed out */
692 if (end - start > expected * 2) {
693 if (++attempt < I2C_RETRY_LIMIT) {
694 EFSYS_PROBE1(retry, unsigned int, attempt);
695
696 goto again;
697 }
698
699 rc = ETIMEDOUT;
700 goto fail3;
701 }
702
703 EFSYS_PREEMPT_ENABLE(pstate);
704 EFSYS_UNLOCK(enp->en_eslp, lstate);
705 return (0);
706
707 fail3:
708 EFSYS_PROBE(fail5);
709
710 goto fail1;
711
712 fail2:
713 falcon_i2c_stop(enp, &expected);
714 falcon_i2c_release(enp, &expected);
715
716 EFSYS_TIMESTAMP(&end);
717
718 /* The transaction may have timed out */
719 if (end - start > expected * 2) {
720 if (++attempt < I2C_RETRY_LIMIT) {
721 EFSYS_PROBE1(retry, unsigned int, attempt);
722
723 goto again;
724 }
725
726 rc = ETIMEDOUT;
727 }
728
729 EFSYS_PROBE(fail2);
730
731 fail1:
732 EFSYS_PROBE1(fail1, int, rc);
733
734 EFSYS_PREEMPT_ENABLE(pstate);
735 EFSYS_UNLOCK(enp->en_eslp, lstate);
736 return (rc);
737 }
738
739 __checkReturn int
740 falcon_i2c_send(
741 __in efx_nic_t *enp,
742 __in uint8_t devid,
743 __in_bcount(size) caddr_t base,
744 __in size_t size)
745 {
746 int pstate;
747 int lstate;
748 efsys_timestamp_t start;
749 efsys_timestamp_t end;
750 efsys_timestamp_t expected;
751 unsigned int attempt;
752 unsigned int i;
753 int rc;
754
755 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
756 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_FALCON);
757
758 EFSYS_ASSERT(size != 0);
759
760 EFSYS_LOCK(enp->en_eslp, lstate);
761 EFSYS_PREEMPT_DISABLE(pstate);
762
763 /* Check the state of the I2C bus */
764 if ((rc = falcon_i2c_wait(enp)) != 0)
765 goto fail1;
766
767 attempt = 0;
768
769 again:
770 EFSYS_TIMESTAMP(&start);
771 expected = 0;
772
773 /* Select device and write cycle */
774 falcon_i2c_start(enp, &expected);
775
776 if ((rc = falcon_i2c_byte_out(enp, I2C_WRITE_CMD(devid), &expected))
777 != 0)
778 goto fail2;
779
780 /* Write bytes */
781 for (i = 0; i < size; i++)
782 if ((rc = falcon_i2c_byte_out(enp, *(uint8_t *)(base + i),
783 &expected)) != 0)
784 goto fail3;
785
786 falcon_i2c_stop(enp, &expected);
787 falcon_i2c_release(enp, &expected);
788
789 EFSYS_TIMESTAMP(&end);
790
791 /* The transaction may have timed out */
792 if (end - start > expected * 2) {
793 if (++attempt < I2C_RETRY_LIMIT) {
794 EFSYS_PROBE1(retry, unsigned int, attempt);
795
796 goto again;
797 }
798
799 rc = ETIMEDOUT;
800 goto fail4;
801 }
802
803 EFSYS_PREEMPT_ENABLE(pstate);
804 EFSYS_UNLOCK(enp->en_eslp, lstate);
805 return (0);
806
807 fail4:
808 EFSYS_PROBE(fail5);
809
810 goto fail1;
811
812 fail3:
813 EFSYS_PROBE(fail3);
814 fail2:
815 falcon_i2c_stop(enp, &expected);
816 falcon_i2c_release(enp, &expected);
817
818 EFSYS_TIMESTAMP(&end);
819
820 /* The transaction may have timed out */
821 if (end - start > expected * 2) {
822 if (++attempt < I2C_RETRY_LIMIT) {
823 EFSYS_PROBE1(retry, unsigned int, attempt);
824
825 goto again;
826 }
827
828 rc = ETIMEDOUT;
829 }
830
831 EFSYS_PROBE(fail2);
832
833 fail1:
834 EFSYS_PROBE1(fail1, int, rc);
835
836 EFSYS_PREEMPT_ENABLE(pstate);
837 EFSYS_UNLOCK(enp->en_eslp, lstate);
838 return (rc);
839 }
840 #endif /* EFSYS_OPT_PHY_NULL */
841
842 #endif /* EFSYS_OPT_FALCON */