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 #include "falcon_nvram.h"
32 #include "sfx7101.h"
33 #include "sfx7101_impl.h"
34 #include "xphy.h"
35
36 #if EFSYS_OPT_PHY_SFX7101
37
38 static __checkReturn int
39 sfx7101_power_on(
40 __in efx_nic_t *enp,
41 __in boolean_t reflash)
42 {
43 efx_byte_t byte;
44 int rc;
45
46 if ((rc = falcon_i2c_check(enp, PCA9539)) != 0)
47 goto fail1;
48
49 /* Enable all port 0 outputs on IO expander */
50 EFX_ZERO_BYTE(byte);
51
52 if ((rc = falcon_i2c_write(enp, PCA9539, P0_CONFIG, (caddr_t)&byte,
53 1)) != 0)
54 goto fail2;
55
56 /* Enable necessary port 1 outputs on IO expander */
57 EFX_SET_BYTE(byte);
58 EFX_SET_BYTE_FIELD(byte, P1_SPARE, 0);
59
60 if ((rc = falcon_i2c_write(enp, PCA9539, P1_CONFIG, (caddr_t)&byte,
61 1)) != 0)
62 goto fail3;
63
64 /* Turn off all power rails */
65 EFX_SET_BYTE(byte);
66 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte,
67 1)) != 0)
68 goto fail4;
69
70 /* Sleep for 1 s */
71 EFSYS_SLEEP(1000000);
72
73 /* Turn on 1.2V, 2.5V, and 5V power rails */
74 EFX_SET_BYTE(byte);
75 EFX_SET_BYTE_FIELD(byte, P0_EN_1V2, 0);
76 EFX_SET_BYTE_FIELD(byte, P0_EN_2V5, 0);
77 EFX_SET_BYTE_FIELD(byte, P0_EN_5V, 0);
78 EFX_SET_BYTE_FIELD(byte, P0_X_TRST, 0);
79
80 /* Disable flash configuration */
81 if (!reflash)
82 EFX_SET_BYTE_FIELD(byte, P0_FLASH_CFG_EN, 0);
83
84 /* Turn off JTAG */
85 EFX_SET_BYTE_FIELD(byte, P0_SHORTEN_JTAG, 0);
86
87 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte,
88 1)) != 0)
89 goto fail5;
90
91 /* Spin for 10 ms */
92 EFSYS_SPIN(10000);
93
94 /* Turn on 1V power rail */
95 EFX_SET_BYTE_FIELD(byte, P0_EN_1V0X, 0);
96
97 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte,
98 1)) != 0)
99 goto fail6;
100
101 /* Sleep for 1 s */
102 EFSYS_SLEEP(1000000);
103
104 enp->en_reset_flags |= EFX_RESET_PHY;
105
106 return (0);
107
108 fail6:
109 EFSYS_PROBE(fail6);
110 fail5:
111 EFSYS_PROBE(fail5);
112 fail4:
113 EFSYS_PROBE(fail4);
114
115 /* Turn off all power rails */
116 EFX_SET_BYTE(byte);
117
118 (void) falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte, 1);
119
120 fail3:
121 EFSYS_PROBE(fail3);
122
123 /* Disable port 1 outputs on IO expander */
124 EFX_SET_BYTE(byte);
125 (void) falcon_i2c_write(enp, PCA9539, P1_CONFIG, (caddr_t)&byte, 1);
126
127 fail2:
128 EFSYS_PROBE(fail2);
129
130 /* Disable port 0 outputs on IO expander */
131 EFX_SET_BYTE(byte);
132 (void) falcon_i2c_write(enp, PCA9539, P0_CONFIG, (caddr_t)&byte, 1);
133
134 fail1:
135 EFSYS_PROBE1(fail1, int, rc);
136
137 return (rc);
138 }
139
140 static __checkReturn int
141 sfx7101_power_off(
142 __in efx_nic_t *enp)
143 {
144 efx_port_t *epp = &(enp->en_port);
145 efx_word_t word;
146 efx_byte_t byte;
147 int rc;
148
149 /* Power down the LNPGA */
150 EFX_POPULATE_WORD_1(word, LNPGA_POWERDOWN, 1);
151 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD,
152 PMA_PMD_XCONTROL_REG, &word)) != 0)
153 goto fail1;
154
155 /* Sleep for 200 ms */
156 EFSYS_SLEEP(200000);
157
158 /* Turn off all power rails */
159 EFX_SET_BYTE(byte);
160 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT, (caddr_t)&byte,
161 1)) != 0)
162 goto fail2;
163
164 /* Disable port 1 outputs on IO expander */
165 EFX_SET_BYTE(byte);
166 if ((rc = falcon_i2c_write(enp, PCA9539, P1_CONFIG, (caddr_t)&byte,
167 1)) != 0)
168 goto fail3;
169
170 /* Disable port 0 outputs on IO expander */
171 EFX_SET_BYTE(byte);
172 if ((rc = falcon_i2c_write(enp, PCA9539, P0_CONFIG, (caddr_t)&byte,
173 1)) != 0)
174 goto fail4;
175
176 return (0);
177
178 fail4:
179 EFSYS_PROBE(fail4);
180 fail3:
181 EFSYS_PROBE(fail3);
182 fail2:
183 EFSYS_PROBE(fail2);
184 fail1:
185 EFSYS_PROBE1(fail1, int, rc);
186
187 return (rc);
188 }
189
190 __checkReturn int
191 sfx7101_power(
192 __in efx_nic_t *enp,
193 __in boolean_t on)
194 {
195 int rc;
196
197 if (on) {
198 if ((rc = sfx7101_power_on(enp, B_FALSE)) != 0)
199 goto fail1;
200
201 } else {
202 if ((rc = sfx7101_power_off(enp)) != 0)
203 goto fail1;
204 }
205
206 return (0);
207
208 fail1:
209 EFSYS_PROBE1(fail1, int, rc);
210
211 return (rc);
212 }
213
214 __checkReturn int
215 sfx7101_reset(
216 __in efx_nic_t *enp)
217 {
218 efx_port_t *epp = &(enp->en_port);
219 efx_word_t word;
220 int rc;
221
222 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
223 PMA_PMD_XCONTROL_REG, &word)) != 0)
224 goto fail1;
225
226 EFX_SET_WORD_FIELD(word, SSR, 1);
227
228 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD,
229 PMA_PMD_XCONTROL_REG, &word)) != 0)
230 goto fail2;
231
232 /* Sleep 500ms */
233 EFSYS_SPIN(500000);
234
235 enp->en_reset_flags |= EFX_RESET_PHY;
236
237 return (0);
238
239 fail2:
240 EFSYS_PROBE(fail2);
241 fail1:
242 EFSYS_PROBE1(fail1, int, rc);
243
244 return (rc);
245 }
246
247 static __checkReturn int
248 sfx7101_an_set(
249 __in efx_nic_t *enp,
250 __in boolean_t on)
251 {
252 efx_port_t *epp = &(enp->en_port);
253 efx_word_t word;
254 int rc;
255
256 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD,
257 AN_CONTROL1_REG, &word)) != 0)
258 goto fail1;
259
260 if (on) {
261 EFX_SET_WORD_FIELD(word, AN_ENABLE, 1);
262 EFX_SET_WORD_FIELD(word, AN_RESTART, 1);
263 } else {
264 EFX_SET_WORD_FIELD(word, AN_ENABLE, 0);
265 }
266
267 if ((rc = falcon_mdio_write(enp, epp->ep_port, AN_MMD,
268 AN_CONTROL1_REG, &word)) != 0)
269 goto fail2;
270
271 return (0);
272
273 fail2:
274 EFSYS_PROBE(fail2);
275 fail1:
276 EFSYS_PROBE1(fail1, int, rc);
277
278 return (rc);
279 }
280
281 static __checkReturn int
282 sfx7101_led_cfg(
283 __in efx_nic_t *enp)
284 {
285 efx_port_t *epp = &(enp->en_port);
286 efx_word_t word;
287 int rc;
288
289 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
290 PMA_PMD_LED_CONTROL_REG, &word)) != 0)
291 goto fail1;
292
293 EFX_SET_WORD_FIELD(word, LED_ACTIVITY_EN, 1);
294
295 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD,
296 PMA_PMD_LED_CONTROL_REG, &word)) != 0)
297 goto fail2;
298
299 #if EFSYS_OPT_PHY_LED_CONTROL
300
301 switch (epp->ep_phy_led_mode) {
302 case EFX_PHY_LED_DEFAULT:
303 EFX_POPULATE_WORD_3(word,
304 LED_LINK, LED_NORMAL_DECODE,
305 LED_TX, LED_NORMAL_DECODE,
306 LED_RX, LED_OFF_DECODE);
307 break;
308
309 case EFX_PHY_LED_OFF:
310 EFX_POPULATE_WORD_3(word,
311 LED_LINK, LED_OFF_DECODE,
312 LED_TX, LED_OFF_DECODE,
313 LED_RX, LED_OFF_DECODE);
314 break;
315
316 case EFX_PHY_LED_ON:
317 EFX_POPULATE_WORD_3(word,
318 LED_LINK, LED_ON_DECODE,
319 LED_TX, LED_ON_DECODE,
320 LED_RX, LED_ON_DECODE);
321 break;
322
323 case EFX_PHY_LED_FLASH:
324 EFX_POPULATE_WORD_3(word,
325 LED_LINK, LED_FLASH_DECODE,
326 LED_TX, LED_FLASH_DECODE,
327 LED_RX, LED_FLASH_DECODE);
328 break;
329
330 default:
331 EFSYS_ASSERT(B_FALSE);
332 break;
333 }
334
335 #else /* EFSYS_OPT_PHY_LED_CONTROL */
336
337 EFX_POPULATE_WORD_3(word,
338 LED_LINK, LED_NORMAL_DECODE,
339 LED_TX, LED_NORMAL_DECODE,
340 LED_RX, LED_OFF_DECODE);
341
342 #endif /* EFSYS_OPT_PHY_LED_CONTROL */
343
344 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD,
345 PMA_PMD_LED_OVERRIDE_REG, &word)) != 0)
346 goto fail3;
347
348 return (0);
349
350 fail3:
351 EFSYS_PROBE(fail3);
352 fail2:
353 EFSYS_PROBE(fail2);
354 fail1:
355 EFSYS_PROBE1(fail1, int, rc);
356
357 return (rc);
358 }
359
360 static __checkReturn int
361 sfx7101_clock_cfg(
362 __in efx_nic_t *enp,
363 __in boolean_t enable)
364 {
365 efx_port_t *epp = &(enp->en_port);
366 efx_word_t word;
367 int rc;
368
369 EFX_POPULATE_WORD_1(word, CLK312_EN, (enable) ? 1 : 0);
370
371 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
372 PCS_TEST_SELECT_REG, &word)) != 0)
373 goto fail1;
374
375 return (0);
376
377 fail1:
378 EFSYS_PROBE1(fail1, int, rc);
379
380 return (rc);
381 }
382
383 static __checkReturn int
384 sfx7101_adv_cap_cfg(
385 __in efx_nic_t *enp)
386 {
387 efx_port_t *epp = &(enp->en_port);
388 efx_word_t word;
389 int rc;
390
391 /* Check base page */
392 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD,
393 AN_ADV_BP_CAP_REG, &word)) != 0)
394 goto fail1;
395
396 EFX_SET_WORD_FIELD(word, AN_ADV_TA_PAUSE,
397 ((epp->ep_adv_cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1));
398 EFX_SET_WORD_FIELD(word, AN_ADV_TA_ASM_DIR,
399 ((epp->ep_adv_cap_mask >> EFX_PHY_CAP_ASYM) & 0x1));
400
401 if ((rc = falcon_mdio_write(enp, epp->ep_port, AN_MMD,
402 AN_ADV_BP_CAP_REG, &word)) != 0)
403 goto fail2;
404
405 return (0);
406
407 fail2:
408 EFSYS_PROBE(fail2);
409 fail1:
410 EFSYS_PROBE1(fail1, int, rc);
411
412 return (rc);
413 }
414
415 #if EFSYS_OPT_LOOPBACK
416 static __checkReturn int
417 sfx7101_loopback_cfg(
418 __in efx_nic_t *enp)
419 {
420 efx_port_t *epp = &(enp->en_port);
421 efx_word_t word;
422 int rc;
423
424 switch (epp->ep_loopback_type) {
425 case EFX_LOOPBACK_PHY_XS:
426 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD,
427 PHY_XS_XGXS_TEST_REG, &word)) != 0)
428 goto fail1;
429
430 EFX_SET_WORD_FIELD(word, NE_LOOPBACK, 1);
431
432 if ((rc = falcon_mdio_write(enp, epp->ep_port, PHY_XS_MMD,
433 PHY_XS_XGXS_TEST_REG, &word)) != 0)
434 goto fail2;
435
436 break;
437
438 case EFX_LOOPBACK_PCS:
439 if ((rc = xphy_mmd_loopback_set(enp, epp->ep_port, PCS_MMD,
440 B_TRUE)) != 0)
441 goto fail1;
442
443 break;
444
445 case EFX_LOOPBACK_PMA_PMD:
446 if ((rc = xphy_mmd_loopback_set(enp, epp->ep_port, PMA_PMD_MMD,
447 B_TRUE)) != 0)
448 goto fail1;
449
450 break;
451
452 default:
453 break;
454 }
455
456 return (0);
457
458 fail2:
459 EFSYS_PROBE(fail2);
460 fail1:
461 EFSYS_PROBE1(fail1, int, rc);
462
463 return (rc);
464 }
465 #endif /* EFSYS_OPT_LOOPBACK */
466
467 __checkReturn int
468 sfx7101_reconfigure(
469 __in efx_nic_t *enp)
470 {
471 efx_port_t *epp = &(enp->en_port);
472 unsigned int count;
473 int rc;
474
475 /* Wait for the firmware boot to complete */
476 count = 0;
477 do {
478 efx_word_t word;
479
480 EFSYS_PROBE1(wait, unsigned int, count);
481
482 /* Spin for 1 ms */
483 EFSYS_SPIN(1000);
484
485 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
486 PCS_BOOT_STATUS_REG, &word)) != 0)
487 goto fail1;
488
489 if (EFX_WORD_FIELD(word, FATAL_ERR) != 0)
490 break; /* no point in continuing */
491
492 if (EFX_WORD_FIELD(word, BOOT_STATUS) != 0 &&
493 EFX_WORD_FIELD(word, CODE_DOWNLOAD) != 0 &&
494 EFX_WORD_FIELD(word, CKSUM_OK) != 0 &&
495 EFX_WORD_FIELD(word, CODE_STARTED) != 0 &&
496 EFX_WORD_FIELD(word, BOOT_PROGRESS) == APP_JMP_DECODE)
497 goto configure;
498
499 } while (++count < 1000);
500
501 rc = ENOTACTIVE;
502 goto fail2;
503
504 configure:
505 if ((rc = xphy_pkg_wait(enp, epp->ep_port, SFX7101_MMD_MASK)) != 0)
506 goto fail3;
507
508 /* Make sure auto-negotiation is off whilst we configure the PHY */
509 if ((rc = sfx7101_an_set(enp, B_FALSE)) != 0)
510 goto fail4;
511
512 if ((rc = sfx7101_clock_cfg(enp, B_TRUE)) != 0)
513 goto fail5;
514
515 #if EFSYS_OPT_LOOPBACK
516 if ((rc = sfx7101_loopback_cfg(enp)) != 0)
517 goto fail6;
518 #endif /* EFSYS_OPT_LOOPBACK */
519
520 if ((rc = sfx7101_led_cfg(enp)) != 0)
521 goto fail7;
522
523 if ((rc = sfx7101_adv_cap_cfg(enp)) != 0)
524 goto fail8;
525
526 #if EFSYS_OPT_LOOPBACK
527 if (epp->ep_loopback_type == EFX_LOOPBACK_OFF) {
528 if ((rc = sfx7101_an_set(enp, B_TRUE)) != 0)
529 goto fail9;
530 }
531 #else /* EFSYS_OPT_LOOPBACK */
532 if ((rc = sfx7101_an_set(enp, B_TRUE)) != 0)
533 goto fail9;
534 #endif /* EFSYS_OPT_LOOPBACK */
535
536 return (0);
537
538 fail9:
539 EFSYS_PROBE(fail9);
540 fail8:
541 EFSYS_PROBE(fail8);
542 fail7:
543 EFSYS_PROBE(fail7);
544
545 #if EFSYS_OPT_LOOPBACK
546 fail6:
547 EFSYS_PROBE(fail6);
548 #endif /* EFSYS_OPT_LOOPBACK */
549
550 fail5:
551 EFSYS_PROBE(fail5);
552 fail4:
553 EFSYS_PROBE(fail4);
554 fail3:
555 EFSYS_PROBE(fail3);
556 fail2:
557 EFSYS_PROBE(fail2);
558 fail1:
559 EFSYS_PROBE1(fail1, int, rc);
560
561 return (rc);
562 }
563
564 __checkReturn int
565 sfx7101_verify(
566 __in efx_nic_t *enp)
567 {
568 efx_port_t *epp = &(enp->en_port);
569 int rc;
570
571 if ((rc = xphy_pkg_verify(enp, epp->ep_port, SFX7101_MMD_MASK)) != 0)
572 goto fail1;
573
574 return (0);
575
576 fail1:
577 EFSYS_PROBE1(fail1, int, rc);
578
579 return (rc);
580 }
581
582 __checkReturn int
583 sfx7101_uplink_check(
584 __in efx_nic_t *enp,
585 __out boolean_t *upp)
586 {
587 efx_port_t *epp = &(enp->en_port);
588 efx_word_t word;
589 int rc;
590
591 if (epp->ep_mac_type != EFX_MAC_FALCON_XMAC) {
592 rc = ENOTSUP;
593 goto fail1;
594 }
595
596 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD,
597 PHY_XS_LANE_STATUS_REG, &word)) != 0)
598 goto fail2;
599
600 *upp = ((EFX_WORD_FIELD(word, PHY_XS_ALIGNED) != 0) &&
601 (EFX_WORD_FIELD(word, PHY_XS_LANE0_SYNC) != 0) &&
602 (EFX_WORD_FIELD(word, PHY_XS_LANE1_SYNC) != 0) &&
603 (EFX_WORD_FIELD(word, PHY_XS_LANE2_SYNC) != 0) &&
604 (EFX_WORD_FIELD(word, PHY_XS_LANE3_SYNC) != 0));
605
606 return (0);
607
608 fail2:
609 EFSYS_PROBE(fail2);
610 fail1:
611 EFSYS_PROBE1(fail1, int, rc);
612
613 return (rc);
614 }
615
616 void
617 sfx7101_uplink_reset(
618 __in efx_nic_t *enp)
619 {
620 efx_port_t *epp = &(enp->en_port);
621 efx_word_t word;
622 int rc;
623
624 if (epp->ep_mac_type != EFX_MAC_FALCON_XMAC) {
625 rc = ENOTSUP;
626 goto fail1;
627 }
628
629 /* Disable the clock */
630 if ((rc = sfx7101_clock_cfg(enp, B_FALSE)) != 0)
631 goto fail2;
632
633 /* Put the XGXS and SERDES into reset */
634 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
635 PCS_SOFT_RST2_REG, &word)) != 0)
636 goto fail3;
637
638 EFX_SET_WORD_FIELD(word, XGXS_RST_N, 0);
639 EFX_SET_WORD_FIELD(word, SERDES_RST_N, 0);
640
641 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
642 PCS_SOFT_RST2_REG, &word)) != 0)
643 goto fail4;
644
645 /* Put the PLL into reset */
646 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
647 PCS_CLOCK_CTRL_REG, &word)) != 0)
648 goto fail5;
649
650 EFX_SET_WORD_FIELD(word, PLL312_RST_N, 0);
651
652 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
653 PCS_CLOCK_CTRL_REG, &word)) != 0)
654 goto fail6;
655
656 EFSYS_SPIN(10);
657
658 /* Take the PLL out of reset */
659 EFX_SET_WORD_FIELD(word, PLL312_RST_N, 1);
660
661 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
662 PCS_CLOCK_CTRL_REG, &word)) != 0)
663 goto fail7;
664
665 EFSYS_SPIN(10);
666
667 /* Take the XGXS and SERDES out of reset */
668 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
669 PCS_SOFT_RST2_REG, &word)) != 0)
670 goto fail8;
671
672 EFX_SET_WORD_FIELD(word, XGXS_RST_N, 1);
673 EFX_SET_WORD_FIELD(word, SERDES_RST_N, 1);
674
675 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
676 PCS_SOFT_RST2_REG, &word)) != 0)
677 goto fail9;
678
679 /* Enable the clock */
680 if ((rc = sfx7101_clock_cfg(enp, B_TRUE)) != 0)
681 goto fail10;
682
683 /* Sleep 200 ms */
684 EFSYS_SLEEP(200000);
685
686 return;
687
688 fail10:
689 EFSYS_PROBE(fail10);
690 fail9:
691 EFSYS_PROBE(fail9);
692 fail8:
693 EFSYS_PROBE(fail8);
694 fail7:
695 EFSYS_PROBE(fail7);
696 fail6:
697 EFSYS_PROBE(fail6);
698 fail5:
699 EFSYS_PROBE(fail5);
700 fail4:
701 EFSYS_PROBE(fail4);
702 fail3:
703 EFSYS_PROBE(fail3);
704 fail2:
705 EFSYS_PROBE(fail2);
706 fail1:
707 EFSYS_PROBE1(fail1, int, rc);
708 }
709
710 static __checkReturn int
711 sfx7101_lp_cap_get(
712 __in efx_nic_t *enp,
713 __out unsigned int *maskp)
714 {
715 efx_port_t *epp = &(enp->en_port);
716 efx_word_t word;
717 int rc;
718
719 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD,
720 AN_LP_BP_CAP_REG, &word)) != 0)
721 goto fail1;
722
723 if (EFX_WORD_FIELD(word, AN_LP_TA_10BASE_T) != 0)
724 *maskp |= (1 << EFX_PHY_CAP_10HDX);
725
726 if (EFX_WORD_FIELD(word, AN_LP_TA_10BASE_T_FDX) != 0)
727 *maskp |= (1 << EFX_PHY_CAP_10FDX);
728
729 if (EFX_WORD_FIELD(word, AN_LP_TA_100BASE_TX) != 0)
730 *maskp |= (1 << EFX_PHY_CAP_100HDX);
731
732 if (EFX_WORD_FIELD(word, AN_LP_TA_100BASE_TX_FDX) != 0)
733 *maskp |= (1 << EFX_PHY_CAP_100FDX);
734
735 if (EFX_WORD_FIELD(word, AN_LP_TA_PAUSE) != 0)
736 *maskp |= (1 << EFX_PHY_CAP_PAUSE);
737
738 if (EFX_WORD_FIELD(word, AN_LP_TA_ASM_DIR) != 0)
739 *maskp |= (1 << EFX_PHY_CAP_ASYM);
740
741 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD,
742 AN_10G_BASE_T_STATUS_REG, &word)) != 0)
743 goto fail2;
744
745 if (EFX_WORD_FIELD(word, AN_10G_BASE_T_LP) != 0)
746 *maskp |= (1 << EFX_PHY_CAP_10000FDX);
747
748 return (0);
749
750 fail2:
751 EFSYS_PROBE(fail2);
752 fail1:
753 EFSYS_PROBE1(fail1, int, rc);
754
755 return (rc);
756 }
757
758 __checkReturn int
759 sfx7101_downlink_check(
760 __in efx_nic_t *enp,
761 __out efx_link_mode_t *modep,
762 __out unsigned int *fcntlp,
763 __out uint32_t *lp_cap_maskp)
764 {
765 efx_port_t *epp = &(enp->en_port);
766 unsigned int lp_cap_mask = epp->ep_lp_cap_mask;
767 unsigned int fcntl = epp->ep_fcntl;
768 uint32_t common;
769 boolean_t up;
770 int rc;
771
772 #if EFSYS_OPT_LOOPBACK
773 switch (epp->ep_loopback_type) {
774 case EFX_LOOPBACK_PHY_XS:
775 rc = xphy_mmd_fault(enp, epp->ep_port, &up);
776 if (rc != 0)
777 goto fail1;
778
779 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN;
780 goto done;
781
782 case EFX_LOOPBACK_PCS:
783 case EFX_LOOPBACK_PMA_PMD:
784 rc = xphy_mmd_check(enp, epp->ep_port, PHY_XS_MMD, &up);
785 if (rc != 0)
786 goto fail1;
787
788 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN;
789 goto done;
790
791 default:
792 break;
793 }
794
795 #endif /* EFSYS_OPT_LOOPBACK */
796 rc = xphy_mmd_check(enp, epp->ep_port, AN_MMD, &up);
797 if (rc != 0)
798 goto fail1;
799
800 /* Check the link partner capabilities */
801 if ((rc = sfx7101_lp_cap_get(enp, &lp_cap_mask)) != 0)
802 goto fail2;
803
804 /* Resolve the common capabilities */
805 common = epp->ep_adv_cap_mask & lp_cap_mask;
806
807 /* Determine negotiated or forced flow control mode */
808 fcntl = 0;
809 if (epp->ep_fcntl_autoneg) {
810 if (common & (1 << EFX_PHY_CAP_PAUSE))
811 fcntl = EFX_FCNTL_GENERATE | EFX_FCNTL_RESPOND;
812 else if (common & (1 << EFX_PHY_CAP_ASYM)) {
813 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
814 fcntl = EFX_FCNTL_RESPOND;
815 else if (lp_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
816 fcntl = EFX_FCNTL_GENERATE;
817 }
818 } else {
819 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
820 fcntl = EFX_FCNTL_GENERATE | EFX_FCNTL_RESPOND;
821 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
822 fcntl ^= EFX_FCNTL_GENERATE;
823 }
824
825 *fcntlp = fcntl;
826 *lp_cap_maskp = lp_cap_mask;
827 *modep = (up) ? EFX_LINK_10000FDX : EFX_LINK_DOWN;
828
829 #if EFSYS_OPT_LOOPBACK
830 done:
831 #endif
832 *fcntlp = epp->ep_fcntl;
833 *lp_cap_maskp = epp->ep_lp_cap_mask;
834
835 return (0);
836
837 fail2:
838 EFSYS_PROBE(fail2);
839 fail1:
840 EFSYS_PROBE1(fail1, int, rc);
841
842 return (rc);
843 }
844
845 __checkReturn int
846 sfx7101_oui_get(
847 __in efx_nic_t *enp,
848 __out uint32_t *ouip)
849 {
850 efx_port_t *epp = &(enp->en_port);
851 int rc;
852
853 if ((rc = xphy_mmd_oui_get(enp, epp->ep_port, PMA_PMD_MMD, ouip)) != 0)
854 goto fail1;
855
856 return (0);
857
858 fail1:
859 EFSYS_PROBE1(fail1, int, rc);
860
861 return (rc);
862 }
863
864 #if EFSYS_OPT_PHY_STATS
865
866 #define SFX7101_STAT_SET(_stat, _mask, _id, _val) \
867 do { \
868 (_mask) |= (1ULL << (_id)); \
869 (_stat)[_id] = (uint32_t)(_val); \
870 _NOTE(CONSTANTCONDITION) \
871 } while (B_FALSE)
872
873 static __checkReturn int
874 sfx7101_rev_get(
875 __in efx_nic_t *enp,
876 __out uint16_t *majorp,
877 __out uint16_t *minorp,
878 __out uint16_t *microp)
879 {
880 efx_port_t *epp = &(enp->en_port);
881 efx_word_t word[2];
882 int rc;
883
884 /*
885 * There appear to be two version string formats in use:
886 *
887 * - ('0','major') ('.','minor') with micro == 0
888 * - ('major','.') ('minor','micro')
889 *
890 */
891
892 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
893 PMA_PMD_FW_REV0_REG, &(word[0]))) != 0)
894 goto fail1;
895
896 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
897 PMA_PMD_FW_REV1_REG, &(word[1]))) != 0)
898 goto fail2;
899
900 if (EFX_WORD_FIELD(word[1], EFX_BYTE_0) == '0') {
901 *majorp = EFX_WORD_FIELD(word[1], EFX_BYTE_1) - '0';
902
903 if (EFX_WORD_FIELD(word[0], EFX_BYTE_0) != '.')
904 goto fail3;
905
906 *minorp = EFX_WORD_FIELD(word[0], EFX_BYTE_1) - '0';
907 *microp = 0;
908
909 } else {
910 *majorp = EFX_WORD_FIELD(word[1], EFX_BYTE_0) - '0';
911
912 if (EFX_WORD_FIELD(word[1], EFX_BYTE_1) != '.')
913 goto fail3;
914
915 *minorp = EFX_WORD_FIELD(word[0], EFX_BYTE_0) - '0';
916 *microp = EFX_WORD_FIELD(word[0], EFX_BYTE_1) - '0';
917 }
918
919 return (0);
920
921 fail3:
922 rc = EIO;
923 EFSYS_PROBE(fail3);
924 fail2:
925 EFSYS_PROBE(fail2);
926 fail1:
927 EFSYS_PROBE1(fail1, int, rc);
928
929 return (rc);
930 }
931
932 static __checkReturn int
933 sfx7101_pma_pmd_stats_update(
934 __in efx_nic_t *enp,
935 __inout uint64_t *maskp,
936 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
937 {
938 efx_port_t *epp = &(enp->en_port);
939 efx_word_t word;
940 uint16_t major;
941 uint16_t minor;
942 uint16_t micro;
943 int rc;
944
945 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
946 PMA_PMD_STATUS1_REG, &word)) != 0)
947 goto fail1;
948
949 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_LINK_UP,
950 (EFX_WORD_FIELD(word, PMA_PMD_LINK_UP) != 0) ? 1 : 0);
951
952 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
953 PMA_PMD_STATUS2_REG, &word)) != 0)
954 goto fail2;
955
956 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_RX_FAULT,
957 (EFX_WORD_FIELD(word, PMA_PMD_RX_FAULT) != 0) ? 1 : 0);
958 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_TX_FAULT,
959 (EFX_WORD_FIELD(word, PMA_PMD_TX_FAULT) != 0) ? 1 : 0);
960
961 if ((rc = sfx7101_rev_get(enp, &major, &minor, µ)) != 0)
962 goto fail3;
963
964 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_MAJOR, major);
965 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_MINOR, minor);
966 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PMA_PMD_REV_MICRO, micro);
967
968 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
969 PMA_PMD_CHANNELA_SNR_REG, &word)) != 0)
970 goto fail4;
971
972 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_A,
973 EFX_WORD_FIELD(word, PMA_PMD_SNR));
974
975 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
976 PMA_PMD_CHANNELB_SNR_REG, &word)) != 0)
977 goto fail5;
978
979 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_B,
980 EFX_WORD_FIELD(word, PMA_PMD_SNR));
981
982 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
983 PMA_PMD_CHANNELC_SNR_REG, &word)) != 0)
984 goto fail6;
985
986 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_C,
987 EFX_WORD_FIELD(word, PMA_PMD_SNR));
988
989 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
990 PMA_PMD_CHANNELD_SNR_REG, &word)) != 0)
991 goto fail7;
992
993 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_SNR_D,
994 EFX_WORD_FIELD(word, PMA_PMD_SNR));
995
996 return (0);
997
998 fail7:
999 EFSYS_PROBE(fail7);
1000 fail6:
1001 EFSYS_PROBE(fail6);
1002 fail5:
1003 EFSYS_PROBE(fail5);
1004 fail4:
1005 EFSYS_PROBE(fail4);
1006 fail3:
1007 EFSYS_PROBE(fail3);
1008 fail2:
1009 EFSYS_PROBE(fail2);
1010 fail1:
1011 EFSYS_PROBE1(fail1, int, rc);
1012
1013 return (rc);
1014 }
1015
1016 static __checkReturn int
1017 sfx7101_pcs_stats_update(
1018 __in efx_nic_t *enp,
1019 __inout uint64_t *maskp,
1020 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
1021 {
1022 efx_port_t *epp = &(enp->en_port);
1023 efx_word_t word;
1024 int rc;
1025
1026 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
1027 PCS_STATUS1_REG, &word)) != 0)
1028 goto fail1;
1029
1030 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_LINK_UP,
1031 (EFX_WORD_FIELD(word, PCS_LINK_UP) != 0) ? 1 : 0);
1032
1033 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
1034 PCS_STATUS2_REG, &word)) != 0)
1035 goto fail2;
1036
1037 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_RX_FAULT,
1038 (EFX_WORD_FIELD(word, PCS_RX_FAULT) != 0) ? 1 : 0);
1039 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_TX_FAULT,
1040 (EFX_WORD_FIELD(word, PCS_TX_FAULT) != 0) ? 1 : 0);
1041
1042 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
1043 PCS_10GBASE_R_STATUS2_REG, &word)) != 0)
1044 goto fail3;
1045
1046 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_BER,
1047 EFX_WORD_FIELD(word, PCS_BER));
1048 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PCS_BLOCK_ERRORS,
1049 EFX_WORD_FIELD(word, PCS_ERR));
1050
1051 return (0);
1052
1053 fail3:
1054 EFSYS_PROBE(fail3);
1055 fail2:
1056 EFSYS_PROBE(fail2);
1057 fail1:
1058 EFSYS_PROBE1(fail1, int, rc);
1059
1060 return (rc);
1061 }
1062
1063 static __checkReturn int
1064 sfx7101_phy_xs_stats_update(
1065 __in efx_nic_t *enp,
1066 __inout uint64_t *maskp,
1067 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
1068 {
1069 efx_port_t *epp = &(enp->en_port);
1070 efx_word_t word;
1071 int rc;
1072
1073 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD,
1074 PHY_XS_STATUS1_REG, &word)) != 0)
1075 goto fail1;
1076
1077 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_LINK_UP,
1078 (EFX_WORD_FIELD(word, PHY_XS_LINK_UP) != 0) ? 1 : 0);
1079
1080 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD,
1081 PHY_XS_STATUS2_REG, &word)) != 0)
1082 goto fail2;
1083
1084 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_RX_FAULT,
1085 (EFX_WORD_FIELD(word, PHY_XS_RX_FAULT) != 0) ? 1 : 0);
1086 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_TX_FAULT,
1087 (EFX_WORD_FIELD(word, PHY_XS_TX_FAULT) != 0) ? 1 : 0);
1088
1089 if ((rc = falcon_mdio_read(enp, epp->ep_port, PHY_XS_MMD,
1090 PHY_XS_LANE_STATUS_REG, &word)) != 0)
1091 goto fail3;
1092
1093 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_ALIGN,
1094 (EFX_WORD_FIELD(word, PHY_XS_ALIGNED) != 0) ? 1 : 0);
1095 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_A,
1096 (EFX_WORD_FIELD(word, PHY_XS_LANE0_SYNC) != 0) ? 1 : 0);
1097 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_B,
1098 (EFX_WORD_FIELD(word, PHY_XS_LANE1_SYNC) != 0) ? 1 : 0);
1099 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_C,
1100 (EFX_WORD_FIELD(word, PHY_XS_LANE2_SYNC) != 0) ? 1 : 0);
1101 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_PHY_XS_SYNC_D,
1102 (EFX_WORD_FIELD(word, PHY_XS_LANE3_SYNC) != 0) ? 1 : 0);
1103
1104 return (0);
1105
1106 fail3:
1107 EFSYS_PROBE(fail3);
1108 fail2:
1109 EFSYS_PROBE(fail2);
1110 fail1:
1111 EFSYS_PROBE1(fail1, int, rc);
1112
1113 return (rc);
1114 }
1115
1116 static __checkReturn int
1117 sfx7101_an_stats_update(
1118 __in efx_nic_t *enp,
1119 __inout uint64_t *maskp,
1120 __inout_ecount(EFX_PHY_NSTATS) uint32_t *stat)
1121 {
1122 efx_port_t *epp = &(enp->en_port);
1123 efx_word_t word;
1124 int rc;
1125
1126 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD,
1127 AN_STATUS1_REG, &word)) != 0)
1128 goto fail1;
1129
1130 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_LINK_UP,
1131 (EFX_WORD_FIELD(word, AN_LINK_UP) != 0) ? 1 : 0);
1132
1133 if ((rc = falcon_mdio_read(enp, epp->ep_port, AN_MMD,
1134 AN_10G_BASE_T_STATUS_REG, &word)) != 0)
1135 goto fail2;
1136
1137 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_MASTER,
1138 (EFX_WORD_FIELD(word, AN_MASTER) != 0) ? 1 : 0);
1139 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_LOCAL_RX_OK,
1140 (EFX_WORD_FIELD(word, AN_LOCAL_RX_OK) != 0) ? 1 : 0);
1141 SFX7101_STAT_SET(stat, *maskp, EFX_PHY_STAT_AN_REMOTE_RX_OK,
1142 (EFX_WORD_FIELD(word, AN_REMOTE_RX_OK) != 0) ? 1 : 0);
1143
1144 return (0);
1145
1146 fail2:
1147 EFSYS_PROBE(fail2);
1148 fail1:
1149 EFSYS_PROBE1(fail1, int, rc);
1150
1151 return (rc);
1152 }
1153
1154 __checkReturn int
1155 sfx7101_stats_update(
1156 __in efx_nic_t *enp,
1157 __in efsys_mem_t *esmp,
1158 __out_ecount(EFX_PHY_NSTATS) uint32_t *stat)
1159 {
1160 efx_port_t *epp = &(enp->en_port);
1161 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
1162 uint64_t mask = 0;
1163 uint32_t oui;
1164 int rc;
1165
1166 _NOTE(ARGUNUSED(esmp))
1167
1168 if ((rc = xphy_mmd_oui_get(enp, epp->ep_port, PMA_PMD_MMD, &oui)) != 0)
1169 goto fail1;
1170
1171 SFX7101_STAT_SET(stat, mask, EFX_PHY_STAT_OUI, oui);
1172
1173 if ((rc = sfx7101_pma_pmd_stats_update(enp, &mask, stat)) != 0)
1174 goto fail2;
1175
1176 if ((rc = sfx7101_pcs_stats_update(enp, &mask, stat)) != 0)
1177 goto fail3;
1178
1179 if ((rc = sfx7101_phy_xs_stats_update(enp, &mask, stat)) != 0)
1180 goto fail4;
1181
1182 if ((rc = sfx7101_an_stats_update(enp, &mask, stat)) != 0)
1183 goto fail5;
1184
1185 /* Ensure all the supported statistics are up to date */
1186 EFSYS_ASSERT(mask == encp->enc_phy_stat_mask);
1187
1188 return (0);
1189
1190 fail5:
1191 EFSYS_PROBE(fail5);
1192 fail4:
1193 EFSYS_PROBE(fail4);
1194 fail3:
1195 EFSYS_PROBE(fail3);
1196 fail2:
1197 EFSYS_PROBE(fail2);
1198 fail1:
1199 EFSYS_PROBE1(fail1, int, rc);
1200
1201 return (rc);
1202 }
1203 #endif /* EFSYS_OPT_PHY_STATS */
1204
1205 #if EFSYS_OPT_PHY_PROPS
1206
1207 #if EFSYS_OPT_NAMES
1208 const char __cs *
1209 sfx7101_prop_name(
1210 __in efx_nic_t *enp,
1211 __in unsigned int id)
1212 {
1213 _NOTE(ARGUNUSED(enp, id))
1214
1215 EFSYS_ASSERT(B_FALSE);
1216
1217 return (NULL);
1218 }
1219 #endif /* EFSYS_OPT_NAMES */
1220
1221 __checkReturn int
1222 sfx7101_prop_get(
1223 __in efx_nic_t *enp,
1224 __in unsigned int id,
1225 __in uint32_t flags,
1226 __out uint32_t *valp)
1227 {
1228 _NOTE(ARGUNUSED(enp, id, flags, valp))
1229
1230 EFSYS_ASSERT(B_FALSE);
1231
1232 return (ENOTSUP);
1233 }
1234
1235 __checkReturn int
1236 sfx7101_prop_set(
1237 __in efx_nic_t *enp,
1238 __in unsigned int id,
1239 __in uint32_t val)
1240 {
1241 _NOTE(ARGUNUSED(enp, id, val))
1242
1243 EFSYS_ASSERT(B_FALSE);
1244
1245 return (ENOTSUP);
1246 }
1247
1248 #endif /* EFSYS_OPT_PHY_PROPS */
1249
1250 #if EFSYS_OPT_NVRAM_SFX7101
1251
1252 static __checkReturn int
1253 sfx7101_loader_wait(
1254 __in efx_nic_t *enp)
1255 {
1256 efx_port_t *epp = &(enp->en_port);
1257 efx_word_t word;
1258 unsigned int count;
1259 unsigned int response;
1260 int rc;
1261
1262 /* Wait up to 20s for the command to complete */
1263 for (count = 0; count < 200; count++) {
1264 EFSYS_SLEEP(100000); /* 100ms */
1265
1266 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD,
1267 LOADER_CMD_RESPONSE_REG, &word)) != 0)
1268 goto fail1;
1269
1270 response = EFX_WORD_FIELD(word, EFX_WORD_0);
1271 if (response == LOADER_RESPONSE_OK)
1272 return (0);
1273 if (response != LOADER_RESPONSE_BUSY) {
1274 rc = EIO;
1275 goto fail2;
1276 }
1277 }
1278
1279 rc = ETIMEDOUT;
1280
1281 EFSYS_PROBE(fail3);
1282 fail2:
1283 EFSYS_PROBE(fail2);
1284 fail1:
1285 EFSYS_PROBE1(fail1, int, rc);
1286
1287 return (rc);
1288 }
1289
1290 static __checkReturn int
1291 sfx7101_program_loader(
1292 __in efx_nic_t *enp,
1293 __in unsigned int offset,
1294 __in size_t words)
1295 {
1296 efx_port_t *epp = &(enp->en_port);
1297 efx_word_t word;
1298 int rc;
1299
1300 /* Setup address of block transfer */
1301 EFX_POPULATE_WORD_1(word, EFX_WORD_0, offset);
1302 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD,
1303 LOADER_FLASH_ADDR_LOW_REG, &word)) != 0)
1304 goto fail1;
1305
1306 EFX_POPULATE_WORD_1(word, EFX_WORD_0, (offset >> 16));
1307 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD,
1308 LOADER_FLASH_ADDR_HI_REG, &word)) != 0)
1309 goto fail2;
1310
1311 EFX_POPULATE_WORD_1(word, EFX_WORD_0, words);
1312 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD,
1313 LOADER_ACTUAL_BUFF_SZ_REG, &word)) != 0)
1314 goto fail3;
1315
1316 return (0);
1317
1318 fail3:
1319 EFSYS_PROBE(fail3);
1320 fail2:
1321 EFSYS_PROBE(fail2);
1322 fail1:
1323 EFSYS_PROBE1(fail1, int, rc);
1324
1325 return (rc);
1326 }
1327
1328 __checkReturn int
1329 sfx7101_nvram_size(
1330 __in efx_nic_t *enp,
1331 __out size_t *sizep)
1332 {
1333 _NOTE(ARGUNUSED(enp))
1334 EFSYS_ASSERT(sizep);
1335
1336 *sizep = FIRMWARE_MAX_SIZE;
1337
1338 return (0);
1339 }
1340
1341 __checkReturn int
1342 sfx7101_nvram_get_version(
1343 __in efx_nic_t *enp,
1344 __out uint32_t *subtypep,
1345 __out_ecount(4) uint16_t version[4])
1346 {
1347 uint16_t major, minor, micro;
1348 int rc;
1349
1350 if ((rc = sfx7101_rev_get(enp, &major, &minor, µ)) != 0)
1351 goto fail1;
1352
1353 version[0] = major;
1354 version[1] = minor;
1355 version[2] = 0;
1356 version[3] = 0;
1357
1358 *subtypep = PHY_TYPE_SFX7101_DECODE;
1359
1360 return (0);
1361
1362 fail1:
1363 EFSYS_PROBE1(fail1, int, rc);
1364
1365 return (0);
1366 }
1367
1368 __checkReturn int
1369 sfx7101_nvram_rw_start(
1370 __in efx_nic_t *enp,
1371 __out size_t *block_sizep)
1372 {
1373 efx_port_t *epp = &(enp->en_port);
1374 sfx7101_firmware_header_t header;
1375 efx_word_t word;
1376 unsigned int pos;
1377 int rc;
1378
1379 /* Ensure the PHY is on */
1380 if ((rc = sfx7101_power_on(enp, B_TRUE)) != 0)
1381 goto fail1;
1382
1383 /* Special software reset */
1384 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
1385 PMA_PMD_XCONTROL_REG, &word)) != 0)
1386 goto fail2;
1387 EFX_SET_WORD_FIELD(word, SSR, 1);
1388 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD,
1389 PMA_PMD_XCONTROL_REG, &word)) != 0)
1390 goto fail3;
1391
1392 /* Sleep for 500ms */
1393 EFSYS_SLEEP(500000);
1394
1395 /* Check that the C166 is idle, and in download mode */
1396 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
1397 PCS_BOOT_STATUS_REG, &word)) != 0)
1398 goto fail4;
1399 if (EFX_WORD_FIELD(word, BOOT_STATUS) == 0 ||
1400 EFX_WORD_FIELD(word, BOOT_PROGRESS) != MDIO_WAIT_DECODE) {
1401 rc = ETIMEDOUT;
1402 goto fail5;
1403 }
1404
1405 /* Download loader code into PHY RAM */
1406 EFX_ZERO_WORD(word);
1407 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
1408 PCS_LM_RAM_LS_ADDR_REG, &word)) != 0)
1409 goto fail6;
1410 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
1411 PCS_LM_RAM_MS_ADDR_REG, &word)) != 0)
1412 goto fail7;
1413
1414 for (pos = 0; pos < sfx7101_loader_size / sizeof (uint16_t); pos++) {
1415 /* Firmware is little endian */
1416 word.ew_u8[0] = sfx7101_loader[pos];
1417 word.ew_u8[1] = sfx7101_loader[pos+1];
1418 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
1419 PCS_LM_RAM_DATA_REG, &word)) != 0)
1420 goto fail8;
1421 }
1422
1423 /* Sleep for 500ms */
1424 EFSYS_SLEEP(500000);
1425
1426 /* Start downloaded code */
1427 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
1428 PCS_BOOT_STATUS_REG, &word)) != 0)
1429 goto fail9;
1430 EFX_SET_WORD_FIELD(word, CODE_DOWNLOAD, 1);
1431 if ((rc = falcon_mdio_write(enp, epp->ep_port, PCS_MMD,
1432 PCS_BOOT_STATUS_REG, &word)) != 0)
1433 goto fail10;
1434
1435 /* Sleep 1s */
1436 EFSYS_SLEEP(1000000);
1437
1438 /* And check it started */
1439 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
1440 PCS_BOOT_STATUS_REG, &word)) != 0)
1441 goto fail11;
1442
1443 if (!EFX_WORD_FIELD(word, CODE_STARTED)) {
1444 rc = ETIMEDOUT;
1445 goto fail12;
1446 }
1447
1448 /* Verify program block size is appropriate */
1449 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD,
1450 LOADER_MAX_BUFF_SZ_REG, &word)) != 0)
1451 goto fail13;
1452 if (EFX_WORD_FIELD(word, EFX_WORD_0) < FIRMWARE_BLOCK_SIZE) {
1453 rc = EIO;
1454 goto fail14;
1455 }
1456 if (block_sizep != NULL)
1457 *block_sizep = FIRMWARE_BLOCK_SIZE;
1458
1459 /* Read firmware header */
1460 if ((rc = sfx7101_nvram_read_chunk(enp, 0, (void *)&header,
1461 sizeof (header))) != 0)
1462 goto fail15;
1463
1464 /* Verify firmware isn't too large */
1465 if (EFX_DWORD_FIELD(header.code_length, EFX_DWORD_0) +
1466 sizeof (sfx7101_firmware_header_t) > FIRMWARE_MAX_SIZE) {
1467 rc = EIO;
1468 goto fail16;
1469 }
1470
1471 return (0);
1472
1473 fail16:
1474 EFSYS_PROBE(fail16);
1475 fail15:
1476 EFSYS_PROBE(fail15);
1477 fail14:
1478 EFSYS_PROBE(fail14);
1479 fail13:
1480 EFSYS_PROBE(fail13);
1481 fail12:
1482 EFSYS_PROBE(fail12);
1483 fail11:
1484 EFSYS_PROBE(fail11);
1485 fail10:
1486 EFSYS_PROBE(fail10);
1487 fail9:
1488 EFSYS_PROBE(fail9);
1489 fail8:
1490 EFSYS_PROBE(fail8);
1491 fail7:
1492 EFSYS_PROBE(fail7);
1493 fail6:
1494 EFSYS_PROBE(fail6);
1495 fail5:
1496 EFSYS_PROBE(fail5);
1497 fail4:
1498 EFSYS_PROBE(fail4);
1499 fail3:
1500 EFSYS_PROBE(fail3);
1501 fail2:
1502 EFSYS_PROBE(fail2);
1503 fail1:
1504 EFSYS_PROBE1(fail1, int, rc);
1505
1506 /* Restore the original image */
1507 sfx7101_nvram_rw_finish(enp);
1508
1509 return (rc);
1510 }
1511
1512 __checkReturn int
1513 sfx7101_nvram_read_chunk(
1514 __in efx_nic_t *enp,
1515 __in unsigned int offset,
1516 __out_bcount(size) caddr_t data,
1517 __in size_t size)
1518 {
1519 efx_port_t *epp = &(enp->en_port);
1520 efx_word_t word;
1521 unsigned int pos;
1522 size_t chunk;
1523 size_t words;
1524 int rc;
1525
1526 while (size > 0) {
1527 chunk = MIN(size, FIRMWARE_BLOCK_SIZE);
1528
1529 /* Read in 2byte words */
1530 EFSYS_ASSERT(!(chunk & 0x1));
1531 words = chunk >> 1;
1532
1533 /* Program address/length */
1534 if ((rc = sfx7101_program_loader(enp, offset, words)) != 0)
1535 goto fail1;
1536
1537 /* Select read mode, and wait for buffer to fill */
1538 EFX_POPULATE_WORD_1(word, EFX_WORD_0, LOADER_CMD_READ_FLASH);
1539 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD,
1540 LOADER_CMD_RESPONSE_REG, &word)) != 0)
1541 goto fail2;
1542
1543 if ((rc = sfx7101_loader_wait(enp)) != 0)
1544 goto fail3;
1545
1546 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD,
1547 LOADER_WORDS_READ_REG, &word)) != 0)
1548 goto fail4;
1549
1550 if (words != (size_t)EFX_WORD_FIELD(word, EFX_WORD_0))
1551 goto fail5;
1552
1553 for (pos = 0; pos < words; ++pos) {
1554 if ((rc = falcon_mdio_read(enp, epp->ep_port,
1555 LOADER_MMD, LOADER_DATA_REG, &word)) != 0)
1556 goto fail6;
1557
1558 /* Firmware is little endian */
1559 data[pos] = word.ew_u8[0];
1560 data[pos+1] = word.ew_u8[1];
1561 }
1562
1563 offset += chunk;
1564 data += chunk;
1565 size -= chunk;
1566 }
1567
1568 return (0);
1569
1570 fail6:
1571 EFSYS_PROBE(fail6);
1572 fail5:
1573 EFSYS_PROBE(fail5);
1574 fail4:
1575 EFSYS_PROBE(fail4);
1576 fail3:
1577 EFSYS_PROBE(fail3);
1578 fail2:
1579 EFSYS_PROBE(fail2);
1580 fail1:
1581 EFSYS_PROBE1(fail1, int, rc);
1582
1583 return (rc);
1584 }
1585
1586 __checkReturn int
1587 sfx7101_nvram_erase(
1588 __in efx_nic_t *enp)
1589 {
1590 efx_port_t *epp = &(enp->en_port);
1591 efx_word_t word;
1592 int rc;
1593
1594 EFX_POPULATE_WORD_1(word, EFX_BYTE_0, LOADER_CMD_ERASE_FLASH);
1595 if ((rc = falcon_mdio_write(enp, epp->ep_port,
1596 LOADER_MMD, LOADER_CMD_RESPONSE_REG, &word)) != 0)
1597 goto fail1;
1598
1599 return (0);
1600
1601 fail1:
1602 EFSYS_PROBE1(fail1, int, rc);
1603
1604 return (rc);
1605 }
1606
1607 __checkReturn int
1608 sfx7101_nvram_write_chunk(
1609 __in efx_nic_t *enp,
1610 __in unsigned int offset,
1611 __in_bcount(size) caddr_t data,
1612 __in size_t size)
1613 {
1614 efx_port_t *epp = &(enp->en_port);
1615 efx_word_t word;
1616 unsigned int pos;
1617 size_t chunk;
1618 size_t words;
1619 int rc;
1620
1621 while (size > 0) {
1622 chunk = MIN(size, FIRMWARE_BLOCK_SIZE);
1623
1624 /* Write in 2byte words */
1625 EFSYS_ASSERT(!(chunk & 0x1));
1626 words = chunk >> 1;
1627
1628 /* Program address/length */
1629 if ((rc = sfx7101_program_loader(enp, offset, words)) != 0)
1630 goto fail1;
1631
1632 /* Select write mode */
1633 EFX_POPULATE_WORD_1(word, EFX_WORD_0, LOADER_CMD_FILL_BUFFER);
1634 if ((rc = falcon_mdio_write(enp, epp->ep_port, LOADER_MMD,
1635 LOADER_CMD_RESPONSE_REG, &word)) != 0)
1636 goto fail2;
1637
1638 for (pos = 0; pos < words; ++pos) {
1639 /* Firmware is little-endian */
1640 word.ew_u8[0] = data[pos];
1641 word.ew_u8[1] = data[pos+1];
1642
1643 if ((rc = falcon_mdio_write(enp, epp->ep_port,
1644 LOADER_MMD, LOADER_DATA_REG, &word)) != 0)
1645 goto fail3;
1646 }
1647
1648 EFX_POPULATE_WORD_1(word, EFX_WORD_0,
1649 LOADER_CMD_PROGRAM_FLASH);
1650 if ((rc = falcon_mdio_write(enp, epp->ep_port,
1651 LOADER_MMD, LOADER_CMD_RESPONSE_REG, &word)) != 0)
1652 goto fail4;
1653
1654 if ((rc = sfx7101_loader_wait(enp)) != 0)
1655 goto fail5;
1656
1657 if ((rc = falcon_mdio_read(enp, epp->ep_port, LOADER_MMD,
1658 LOADER_WORDS_WRITTEN_REG, &word)) != 0)
1659 goto fail6;
1660
1661 if (words != EFX_WORD_FIELD(word, EFX_WORD_0))
1662 goto fail7;
1663
1664 size -= chunk;
1665 offset += chunk;
1666 data += chunk;
1667 }
1668
1669 return (0);
1670
1671 fail7:
1672 EFSYS_PROBE(fail7);
1673 fail6:
1674 EFSYS_PROBE(fail6);
1675 fail5:
1676 EFSYS_PROBE(fail5);
1677 fail4:
1678 EFSYS_PROBE(fail4);
1679 fail3:
1680 EFSYS_PROBE(fail3);
1681 fail2:
1682 EFSYS_PROBE(fail2);
1683 fail1:
1684 EFSYS_PROBE1(fail1, int, rc);
1685
1686 return (rc);
1687 }
1688
1689
1690 void
1691 sfx7101_nvram_rw_finish(
1692 __in efx_nic_t *enp)
1693 {
1694 efx_port_t *epp = &(enp->en_port);
1695 efx_word_t word;
1696 efx_byte_t byte;
1697 int rc;
1698
1699 EFX_SET_BYTE(byte);
1700 EFX_SET_BYTE_FIELD(byte, P0_EN_1V2, 0);
1701 EFX_SET_BYTE_FIELD(byte, P0_EN_2V5, 0);
1702 EFX_SET_BYTE_FIELD(byte, P0_EN_5V, 0);
1703 EFX_SET_BYTE_FIELD(byte, P0_X_TRST, 0);
1704 EFX_SET_BYTE_FIELD(byte, P0_FLASH_CFG_EN, 0);
1705
1706 if ((rc = falcon_i2c_write(enp, PCA9539, P0_OUT,
1707 (caddr_t)&byte, 1)) != 0)
1708 goto fail1;
1709
1710 /* Special software reset */
1711 if ((rc = falcon_mdio_read(enp, epp->ep_port, PMA_PMD_MMD,
1712 PMA_PMD_XCONTROL_REG, &word)) != 0)
1713 goto fail2;
1714 EFX_SET_WORD_FIELD(word, SSR, 1);
1715 if ((rc = falcon_mdio_write(enp, epp->ep_port, PMA_PMD_MMD,
1716 PMA_PMD_XCONTROL_REG, &word)) != 0)
1717 goto fail3;
1718
1719 /* Sleep 1/2 second */
1720 EFSYS_SLEEP(500000);
1721
1722 /* Verify that PHY rebooted */
1723 if ((rc = falcon_mdio_read(enp, epp->ep_port, PCS_MMD,
1724 PCS_BOOT_STATUS_REG, &word)) != 0)
1725 goto fail4;
1726 if (EFX_WORD_FIELD(word, EFX_WORD_0) != 0x7E)
1727 goto fail5;
1728
1729 return;
1730
1731 fail5:
1732 EFSYS_PROBE(fail4);
1733 fail4:
1734 EFSYS_PROBE(fail4);
1735 fail3:
1736 EFSYS_PROBE(fail3);
1737 fail2:
1738 EFSYS_PROBE(fail2);
1739 fail1:
1740 EFSYS_PROBE1(fail1, int, rc);
1741 }
1742
1743 #endif /* EFSYS_OPT_NVRAM_SFX7101 */
1744
1745 #endif /* EFSYS_OPT_PHY_SFX7101 */