1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include "bge_impl.h"
27
28 /*
29 * Bit test macros, returning boolean_t values
30 */
31 #define BIS(w, b) (((w) & (b)) ? B_TRUE : B_FALSE)
32 #define BIC(w, b) (((w) & (b)) ? B_FALSE : B_TRUE)
33 #define UPORDOWN(x) ((x) ? "up" : "down")
34
35 /*
36 * ========== Copper (PHY) support ==========
37 */
38
39 #define BGE_DBG BGE_DBG_PHY /* debug flag for this code */
40
41 /*
42 * #defines:
43 * BGE_COPPER_WIRESPEED controls whether the Broadcom WireSpeed(tm)
44 * feature is enabled. We need to recheck whether this can be
45 * enabled; at one time it seemed to interact unpleasantly with the
46 * loopback modes.
47 *
48 * BGE_COPPER_IDLEOFF controls whether the (copper) PHY power is
49 * turned off when the PHY is idled i.e. during driver suspend().
50 * For now this is disabled because the chip doesn't seem to
51 * resume cleanly if the PHY power is turned off.
52 */
53 #define BGE_COPPER_WIRESPEED B_TRUE
54 #define BGE_COPPER_IDLEOFF B_FALSE
55
56 /*
57 * The arrays below can be indexed by the MODE bits from the Auxiliary
58 * Status register to determine the current speed/duplex settings.
59 */
60 static const int16_t bge_copper_link_speed[] = {
61 0, /* MII_AUX_STATUS_MODE_NONE */
62 10, /* MII_AUX_STATUS_MODE_10_H */
63 10, /* MII_AUX_STATUS_MODE_10_F */
64 100, /* MII_AUX_STATUS_MODE_100_H */
65 0, /* MII_AUX_STATUS_MODE_100_4 */
66 100, /* MII_AUX_STATUS_MODE_100_F */
67 1000, /* MII_AUX_STATUS_MODE_1000_H */
68 1000 /* MII_AUX_STATUS_MODE_1000_F */
69 };
70
71 static const int8_t bge_copper_link_duplex[] = {
72 LINK_DUPLEX_UNKNOWN, /* MII_AUX_STATUS_MODE_NONE */
73 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_10_H */
74 LINK_DUPLEX_FULL, /* MII_AUX_STATUS_MODE_10_F */
75 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_100_H */
76 LINK_DUPLEX_UNKNOWN, /* MII_AUX_STATUS_MODE_100_4 */
77 LINK_DUPLEX_FULL, /* MII_AUX_STATUS_MODE_100_F */
78 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_1000_H */
79 LINK_DUPLEX_FULL /* MII_AUX_STATUS_MODE_1000_F */
80 };
81
82 static const int16_t bge_copper_link_speed_5906[] = {
83 0, /* MII_AUX_STATUS_MODE_NONE */
84 10, /* MII_AUX_STATUS_MODE_10_H */
85 10, /* MII_AUX_STATUS_MODE_10_F */
86 100, /* MII_AUX_STATUS_MODE_100_H */
87 0, /* MII_AUX_STATUS_MODE_100_4 */
88 100, /* MII_AUX_STATUS_MODE_100_F */
89 0, /* MII_AUX_STATUS_MODE_1000_H */
90 0 /* MII_AUX_STATUS_MODE_1000_F */
91 };
92
93 static const int8_t bge_copper_link_duplex_5906[] = {
94 LINK_DUPLEX_UNKNOWN, /* MII_AUX_STATUS_MODE_NONE */
95 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_10_H */
96 LINK_DUPLEX_FULL, /* MII_AUX_STATUS_MODE_10_F */
97 LINK_DUPLEX_HALF, /* MII_AUX_STATUS_MODE_100_H */
98 LINK_DUPLEX_UNKNOWN, /* MII_AUX_STATUS_MODE_100_4 */
99 LINK_DUPLEX_FULL, /* MII_AUX_STATUS_MODE_100_F */
100 LINK_DUPLEX_UNKNOWN, /* MII_AUX_STATUS_MODE_1000_H */
101 LINK_DUPLEX_UNKNOWN /* MII_AUX_STATUS_MODE_1000_F */
102 };
103
104 #if BGE_DEBUGGING
105
106 static void
bge_phydump(bge_t * bgep,uint16_t mii_status,uint16_t aux)107 bge_phydump(bge_t *bgep, uint16_t mii_status, uint16_t aux)
108 {
109 uint16_t regs[32];
110 int i;
111
112 ASSERT(mutex_owned(bgep->genlock));
113
114 for (i = 0; i < 32; ++i)
115 switch (i) {
116 default:
117 regs[i] = bge_mii_get16(bgep, i);
118 break;
119
120 case MII_STATUS:
121 regs[i] = mii_status;
122 break;
123
124 case MII_AUX_STATUS:
125 regs[i] = aux;
126 break;
127
128 case 0x0b: case 0x0c: case 0x0d: case 0x0e:
129 case 0x15: case 0x16: case 0x17:
130 case 0x1c:
131 case 0x1f:
132 /* reserved registers -- don't read these */
133 regs[i] = 0;
134 break;
135 }
136
137 for (i = 0; i < 32; i += 8)
138 BGE_DEBUG(("bge_phydump: "
139 "0x%04x %04x %04x %04x %04x %04x %04x %04x",
140 regs[i+0], regs[i+1], regs[i+2], regs[i+3],
141 regs[i+4], regs[i+5], regs[i+6], regs[i+7]));
142 }
143
144 #endif /* BGE_DEBUGGING */
145
146 /*
147 * Basic low-level function to probe for a PHY
148 *
149 * Returns TRUE if the PHY responds with valid data, FALSE otherwise
150 */
151 static boolean_t
bge_phy_probe(bge_t * bgep)152 bge_phy_probe(bge_t *bgep)
153 {
154 uint16_t miicfg;
155 uint32_t nicsig, niccfg;
156
157 BGE_TRACE(("bge_phy_probe($%p)", (void *)bgep));
158
159 ASSERT(mutex_owned(bgep->genlock));
160
161 nicsig = bge_nic_read32(bgep, BGE_NIC_DATA_SIG_ADDR);
162 if (nicsig == BGE_NIC_DATA_SIG) {
163 niccfg = bge_nic_read32(bgep, BGE_NIC_DATA_NIC_CFG_ADDR);
164 switch (niccfg & BGE_NIC_CFG_PHY_TYPE_MASK) {
165 default:
166 case BGE_NIC_CFG_PHY_TYPE_COPPER:
167 return (B_TRUE);
168 case BGE_NIC_CFG_PHY_TYPE_FIBER:
169 return (B_FALSE);
170 }
171 } else {
172 /*
173 * Read the MII_STATUS register twice, in
174 * order to clear any sticky bits (but they should
175 * have been cleared by the RESET, I think).
176 */
177 miicfg = bge_mii_get16(bgep, MII_STATUS);
178 miicfg = bge_mii_get16(bgep, MII_STATUS);
179 BGE_DEBUG(("bge_phy_probe: status 0x%x", miicfg));
180
181 /*
182 * Now check the value read; it should have at least one bit set
183 * (for the device capabilities) and at least one clear (one of
184 * the error bits). So if we see all 0s or all 1s, there's a
185 * problem. In particular, bge_mii_get16() returns all 1s if
186 * communications fails ...
187 */
188 switch (miicfg) {
189 case 0x0000:
190 case 0xffff:
191 return (B_FALSE);
192
193 default :
194 return (B_TRUE);
195 }
196 }
197 }
198
199 /*
200 * Basic low-level function to reset the PHY.
201 * Doesn't incorporate any special-case workarounds.
202 *
203 * Returns TRUE on success, FALSE if the RESET bit doesn't clear
204 */
205 static boolean_t
bge_phy_reset(bge_t * bgep)206 bge_phy_reset(bge_t *bgep)
207 {
208 uint16_t control;
209 uint_t count;
210
211 BGE_TRACE(("bge_phy_reset($%p)", (void *)bgep));
212
213 ASSERT(mutex_owned(bgep->genlock));
214
215 if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
216 drv_usecwait(40);
217 /* put PHY into ready state */
218 bge_reg_clr32(bgep, MISC_CONFIG_REG, MISC_CONFIG_EPHY_IDDQ);
219 (void) bge_reg_get32(bgep, MISC_CONFIG_REG); /* flush */
220 drv_usecwait(40);
221 }
222
223 /*
224 * Set the PHY RESET bit, then wait up to 5 ms for it to self-clear
225 */
226 bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_RESET);
227 for (count = 0; ++count < 1000; ) {
228 drv_usecwait(5);
229 control = bge_mii_get16(bgep, MII_CONTROL);
230 if (BIC(control, MII_CONTROL_RESET))
231 return (B_TRUE);
232 }
233
234 if (DEVICE_5906_SERIES_CHIPSETS(bgep))
235 (void) bge_adj_volt_5906(bgep);
236
237 BGE_DEBUG(("bge_phy_reset: FAILED, control now 0x%x", control));
238
239 return (B_FALSE);
240 }
241
242 /*
243 * Basic low-level function to powerdown the PHY, if supported
244 * If powerdown support is compiled out, this function does nothing.
245 */
246 static void
bge_phy_powerdown(bge_t * bgep)247 bge_phy_powerdown(bge_t *bgep)
248 {
249 BGE_TRACE(("bge_phy_powerdown"));
250 #if BGE_COPPER_IDLEOFF
251 bge_mii_put16(bgep, MII_CONTROL, MII_CONTROL_PWRDN);
252 #endif /* BGE_COPPER_IDLEOFF */
253 }
254
255 /*
256 * The following functions are based on sample code provided by
257 * Broadcom (20-June-2003), and implement workarounds said to be
258 * required on the early revisions of the BCM5703/4C.
259 *
260 * The registers and values used are mostly UNDOCUMENTED, and
261 * therefore don't have symbolic names ;-(
262 *
263 * Many of the comments are straight out of the Broadcom code:
264 * even where the code has been restructured, the original
265 * comments have been preserved in order to explain what these
266 * undocumented registers & values are all about ...
267 */
268
269 static void
bge_phy_macro_wait(bge_t * bgep)270 bge_phy_macro_wait(bge_t *bgep)
271 {
272 uint_t count;
273
274 for (count = 100; --count; )
275 if ((bge_mii_get16(bgep, 0x16) & 0x1000) == 0)
276 break;
277 }
278
279 /*
280 * PHY test data pattern:
281 *
282 * For 5703/04, each DFE TAP has 21-bits (low word 15, hi word 6)
283 * For 5705, each DFE TAP has 19-bits (low word 15, hi word 4)
284 * For simplicity, we check only 19-bits, so we don't have to
285 * distinguish which chip it is.
286 * the LO word contains 15 bits, make sure pattern data is < 0x7fff
287 * the HI word contains 6 bits, make sure pattern data is < 0x003f
288 */
289 #define N_CHANNELS 4
290 #define N_TAPS 3
291
292 static struct {
293 uint16_t lo;
294 uint16_t hi;
295 } tap_data[N_CHANNELS][N_TAPS] = {
296 {
297 { 0x5555, 0x0005 }, /* ch0, TAP 0, LO/HI pattern */
298 { 0x2aaa, 0x000a }, /* ch0, TAP 1, LO/HI pattern */
299 { 0x3456, 0x0003 } /* ch0, TAP 2, LO/HI pattern */
300 },
301 {
302 { 0x2aaa, 0x000a }, /* ch1, TAP 0, LO/HI pattern */
303 { 0x3333, 0x0003 }, /* ch1, TAP 1, LO/HI pattern */
304 { 0x789a, 0x0005 } /* ch1, TAP 2, LO/HI pattern */
305 },
306 {
307 { 0x5a5a, 0x0005 }, /* ch2, TAP 0, LO/HI pattern */
308 { 0x2a6a, 0x000a }, /* ch2, TAP 1, LO/HI pattern */
309 { 0x1bcd, 0x0003 } /* ch2, TAP 2, LO/HI pattern */
310 },
311 {
312 { 0x2a5a, 0x000a }, /* ch3, TAP 0, LO/HI pattern */
313 { 0x33c3, 0x0003 }, /* ch3, TAP 1, LO/HI pattern */
314 { 0x2ef1, 0x0005 } /* ch3, TAP 2, LO/HI pattern */
315 }
316 };
317
318 /*
319 * Check whether the PHY has locked up after a RESET.
320 *
321 * Returns TRUE if it did, FALSE is it's OK ;-)
322 */
323 static boolean_t
bge_phy_locked_up(bge_t * bgep)324 bge_phy_locked_up(bge_t *bgep)
325 {
326 uint16_t dataLo;
327 uint16_t dataHi;
328 uint_t chan;
329 uint_t tap;
330
331 /*
332 * Check TAPs for all 4 channels, as soon as we see a lockup
333 * we'll stop checking.
334 */
335 for (chan = 0; chan < N_CHANNELS; ++chan) {
336 /* Select channel and set TAP index to 0 */
337 bge_mii_put16(bgep, 0x17, (chan << 13) | 0x0200);
338 /* Freeze filter again just to be safe */
339 bge_mii_put16(bgep, 0x16, 0x0002);
340
341 /*
342 * Write fixed pattern to the RAM, 3 TAPs for
343 * each channel, each TAP have 2 WORDs (LO/HI)
344 */
345 for (tap = 0; tap < N_TAPS; ++tap) {
346 bge_mii_put16(bgep, 0x15, tap_data[chan][tap].lo);
347 bge_mii_put16(bgep, 0x15, tap_data[chan][tap].hi);
348 }
349
350 /*
351 * Active PHY's Macro operation to write DFE
352 * TAP from RAM, and wait for Macro to complete.
353 */
354 bge_mii_put16(bgep, 0x16, 0x0202);
355 bge_phy_macro_wait(bgep);
356
357 /*
358 * Done with write phase, now begin read phase.
359 */
360
361 /* Select channel and set TAP index to 0 */
362 bge_mii_put16(bgep, 0x17, (chan << 13) | 0x0200);
363
364 /*
365 * Active PHY's Macro operation to load DFE
366 * TAP to RAM, and wait for Macro to complete
367 */
368 bge_mii_put16(bgep, 0x16, 0x0082);
369 bge_phy_macro_wait(bgep);
370
371 /* Enable "pre-fetch" */
372 bge_mii_put16(bgep, 0x16, 0x0802);
373 bge_phy_macro_wait(bgep);
374
375 /*
376 * Read back the TAP values. 3 TAPs for each
377 * channel, each TAP have 2 WORDs (LO/HI)
378 */
379 for (tap = 0; tap < N_TAPS; ++tap) {
380 /*
381 * Read Lo/Hi then wait for 'done' is faster.
382 * For DFE TAP, the HI word contains 6 bits,
383 * LO word contains 15 bits
384 */
385 dataLo = bge_mii_get16(bgep, 0x15) & 0x7fff;
386 dataHi = bge_mii_get16(bgep, 0x15) & 0x003f;
387 bge_phy_macro_wait(bgep);
388
389 /*
390 * Check if what we wrote is what we read back.
391 * If failed, then the PHY is locked up, we need
392 * to do PHY reset again
393 */
394 if (dataLo != tap_data[chan][tap].lo)
395 return (B_TRUE); /* wedged! */
396
397 if (dataHi != tap_data[chan][tap].hi)
398 return (B_TRUE); /* wedged! */
399 }
400 }
401
402 /*
403 * The PHY isn't locked up ;-)
404 */
405 return (B_FALSE);
406 }
407
408 /*
409 * Special-case code to reset the PHY on the 5702/5703/5704C/5705/5782.
410 * Tries up to 5 times to recover from failure to reset or PHY lockup.
411 *
412 * Returns TRUE on success, FALSE if there's an unrecoverable problem
413 */
414 static boolean_t
bge_phy_reset_and_check(bge_t * bgep)415 bge_phy_reset_and_check(bge_t *bgep)
416 {
417 boolean_t reset_success;
418 boolean_t phy_locked;
419 uint16_t extctrl;
420 uint16_t gigctrl;
421 uint_t retries;
422
423 for (retries = 0; retries < 5; ++retries) {
424 /* Issue a phy reset, and wait for reset to complete */
425 /* Assuming reset is successful first */
426 reset_success = bge_phy_reset(bgep);
427
428 /*
429 * Now go check the DFE TAPs to see if locked up, but
430 * first, we need to set up PHY so we can read DFE
431 * TAPs.
432 */
433
434 /*
435 * Disable Transmitter and Interrupt, while we play
436 * with the PHY registers, so the link partner won't
437 * see any strange data and the Driver won't see any
438 * interrupts.
439 */
440 extctrl = bge_mii_get16(bgep, 0x10);
441 bge_mii_put16(bgep, 0x10, extctrl | 0x3000);
442
443 /* Setup Full-Duplex, 1000 mbps */
444 bge_mii_put16(bgep, 0x0, 0x0140);
445
446 /* Set to Master mode */
447 gigctrl = bge_mii_get16(bgep, 0x9);
448 bge_mii_put16(bgep, 0x9, 0x1800);
449
450 /* Enable SM_DSP_CLOCK & 6dB */
451 bge_mii_put16(bgep, 0x18, 0x0c00); /* "the ADC fix" */
452
453 /* Work-arounds */
454 bge_mii_put16(bgep, 0x17, 0x201f);
455 bge_mii_put16(bgep, 0x15, 0x2aaa);
456
457 /* More workarounds */
458 bge_mii_put16(bgep, 0x17, 0x000a);
459 bge_mii_put16(bgep, 0x15, 0x0323); /* "the Gamma fix" */
460
461 /* Blocks the PHY control access */
462 bge_mii_put16(bgep, 0x17, 0x8005);
463 bge_mii_put16(bgep, 0x15, 0x0800);
464
465 /* Test whether PHY locked up ;-( */
466 phy_locked = bge_phy_locked_up(bgep);
467 if (reset_success && !phy_locked)
468 break;
469
470 /*
471 * Some problem here ... log it & retry
472 */
473 if (!reset_success)
474 BGE_REPORT((bgep, "PHY didn't reset!"));
475 if (phy_locked)
476 BGE_REPORT((bgep, "PHY locked up!"));
477 }
478
479 /* Remove block phy control */
480 bge_mii_put16(bgep, 0x17, 0x8005);
481 bge_mii_put16(bgep, 0x15, 0x0000);
482
483 /* Unfreeze DFE TAP filter for all channels */
484 bge_mii_put16(bgep, 0x17, 0x8200);
485 bge_mii_put16(bgep, 0x16, 0x0000);
486
487 /* Restore PHY back to operating state */
488 bge_mii_put16(bgep, 0x18, 0x0400);
489
490 /* Restore 1000BASE-T Control Register */
491 bge_mii_put16(bgep, 0x9, gigctrl);
492
493 /* Enable transmitter and interrupt */
494 extctrl = bge_mii_get16(bgep, 0x10);
495 bge_mii_put16(bgep, 0x10, extctrl & ~0x3000);
496
497 if (DEVICE_5906_SERIES_CHIPSETS(bgep))
498 (void) bge_adj_volt_5906(bgep);
499
500 if (!reset_success)
501 bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
502 else if (phy_locked)
503 bge_fm_ereport(bgep, DDI_FM_DEVICE_INVAL_STATE);
504 return (reset_success && !phy_locked);
505 }
506
507 static void
bge_phy_tweak_gmii(bge_t * bgep)508 bge_phy_tweak_gmii(bge_t *bgep)
509 {
510 /* Tweak GMII timing */
511 bge_mii_put16(bgep, 0x1c, 0x8d68);
512 bge_mii_put16(bgep, 0x1c, 0x8d68);
513 }
514
515 /* Bit Error Rate reduction fix */
516 static void
bge_phy_bit_err_fix(bge_t * bgep)517 bge_phy_bit_err_fix(bge_t *bgep)
518 {
519 bge_mii_put16(bgep, 0x18, 0x0c00);
520 bge_mii_put16(bgep, 0x17, 0x000a);
521 bge_mii_put16(bgep, 0x15, 0x310b);
522 bge_mii_put16(bgep, 0x17, 0x201f);
523 bge_mii_put16(bgep, 0x15, 0x9506);
524 bge_mii_put16(bgep, 0x17, 0x401f);
525 bge_mii_put16(bgep, 0x15, 0x14e2);
526 bge_mii_put16(bgep, 0x18, 0x0400);
527 }
528
529 /*
530 * End of Broadcom-derived workaround code *
531 */
532
533 static int
bge_restart_copper(bge_t * bgep,boolean_t powerdown)534 bge_restart_copper(bge_t *bgep, boolean_t powerdown)
535 {
536 uint16_t phy_status;
537 boolean_t reset_ok;
538 uint16_t extctrl, auxctrl;
539
540 BGE_TRACE(("bge_restart_copper($%p, %d)", (void *)bgep, powerdown));
541
542 ASSERT(mutex_owned(bgep->genlock));
543
544 switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) {
545 default:
546 /*
547 * Shouldn't happen; it means we don't recognise this chip.
548 * It's probably a new one, so we'll try our best anyway ...
549 */
550 case MHCR_CHIP_ASIC_REV_5703:
551 case MHCR_CHIP_ASIC_REV_5704:
552 case MHCR_CHIP_ASIC_REV_5705:
553 case MHCR_CHIP_ASIC_REV_5752:
554 case MHCR_CHIP_ASIC_REV_5714:
555 case MHCR_CHIP_ASIC_REV_5715:
556 reset_ok = bge_phy_reset_and_check(bgep);
557 break;
558
559 case MHCR_CHIP_ASIC_REV_5906:
560 case MHCR_CHIP_ASIC_REV_5700:
561 case MHCR_CHIP_ASIC_REV_5701:
562 case MHCR_CHIP_ASIC_REV_5723:
563 case MHCR_CHIP_ASIC_REV_5721_5751:
564 /*
565 * Just a plain reset; the "check" code breaks these chips
566 */
567 reset_ok = bge_phy_reset(bgep);
568 if (!reset_ok)
569 bge_fm_ereport(bgep, DDI_FM_DEVICE_NO_RESPONSE);
570 break;
571 }
572 if (!reset_ok) {
573 BGE_REPORT((bgep, "PHY failed to reset correctly"));
574 return (DDI_FAILURE);
575 }
576
577 /*
578 * Step 5: disable WOL (not required after RESET)
579 *
580 * Step 6: refer to errata
581 */
582 switch (bgep->chipid.asic_rev) {
583 default:
584 break;
585
586 case MHCR_CHIP_REV_5704_A0:
587 bge_phy_tweak_gmii(bgep);
588 break;
589 }
590
591 switch (MHCR_CHIP_ASIC_REV(bgep->chipid.asic_rev)) {
592 case MHCR_CHIP_ASIC_REV_5705:
593 case MHCR_CHIP_ASIC_REV_5721_5751:
594 bge_phy_bit_err_fix(bgep);
595 break;
596 }
597
598 if (!(bgep->chipid.flags & CHIP_FLAG_NO_JUMBO) &&
599 (bgep->chipid.default_mtu > BGE_DEFAULT_MTU)) {
600 /* Set the GMII Fifo Elasticity to high latency */
601 extctrl = bge_mii_get16(bgep, 0x10);
602 bge_mii_put16(bgep, 0x10, extctrl | 0x1);
603
604 /* Allow reception of extended length packets */
605 bge_mii_put16(bgep, MII_AUX_CONTROL, 0x0007);
606 auxctrl = bge_mii_get16(bgep, MII_AUX_CONTROL);
607 auxctrl |= 0x4000;
608 bge_mii_put16(bgep, MII_AUX_CONTROL, auxctrl);
609 }
610
611 /*
612 * Step 7: read the MII_INTR_STATUS register twice,
613 * in order to clear any sticky bits (but they should
614 * have been cleared by the RESET, I think), and we're
615 * not using PHY interrupts anyway.
616 *
617 * Step 8: enable the PHY to interrupt on link status
618 * change (not required)
619 *
620 * Step 9: configure PHY LED Mode - not applicable?
621 *
622 * Step 10: read the MII_STATUS register twice, in
623 * order to clear any sticky bits (but they should
624 * have been cleared by the RESET, I think).
625 */
626 phy_status = bge_mii_get16(bgep, MII_STATUS);
627 phy_status = bge_mii_get16(bgep, MII_STATUS);
628 BGE_DEBUG(("bge_restart_copper: status 0x%x", phy_status));
629
630 /*
631 * Finally, shut down the PHY, if required
632 */
633 if (powerdown)
634 bge_phy_powerdown(bgep);
635 return (DDI_SUCCESS);
636 }
637
638 /*
639 * Synchronise the (copper) PHY's speed/duplex/autonegotiation capabilities
640 * and advertisements with the required settings as specified by the various
641 * param_* variables that can be poked via the NDD interface.
642 *
643 * We always reset the PHY and reprogram *all* the relevant registers,
644 * not just those changed. This should cause the link to go down, and then
645 * back up again once the link is stable and autonegotiation (if enabled)
646 * is complete. We should get a link state change interrupt somewhere along
647 * the way ...
648 *
649 * NOTE: <genlock> must already be held by the caller
650 */
651 static int
bge_update_copper(bge_t * bgep)652 bge_update_copper(bge_t *bgep)
653 {
654 boolean_t adv_autoneg;
655 boolean_t adv_pause;
656 boolean_t adv_asym_pause;
657 boolean_t adv_1000fdx;
658 boolean_t adv_1000hdx;
659 boolean_t adv_100fdx;
660 boolean_t adv_100hdx;
661 boolean_t adv_10fdx;
662 boolean_t adv_10hdx;
663
664 uint16_t control;
665 uint16_t gigctrl;
666 uint16_t auxctrl;
667 uint16_t anar;
668
669 BGE_TRACE(("bge_update_copper($%p)", (void *)bgep));
670
671 ASSERT(mutex_owned(bgep->genlock));
672
673 BGE_DEBUG(("bge_update_copper: autoneg %d "
674 "pause %d asym_pause %d "
675 "1000fdx %d 1000hdx %d "
676 "100fdx %d 100hdx %d "
677 "10fdx %d 10hdx %d ",
678 bgep->param_adv_autoneg,
679 bgep->param_adv_pause, bgep->param_adv_asym_pause,
680 bgep->param_adv_1000fdx, bgep->param_adv_1000hdx,
681 bgep->param_adv_100fdx, bgep->param_adv_100hdx,
682 bgep->param_adv_10fdx, bgep->param_adv_10hdx));
683
684 control = gigctrl = auxctrl = anar = 0;
685
686 /*
687 * PHY settings are normally based on the param_* variables,
688 * but if any loopback mode is in effect, that takes precedence.
689 *
690 * BGE supports MAC-internal loopback, PHY-internal loopback,
691 * and External loopback at a variety of speeds (with a special
692 * cable). In all cases, autoneg is turned OFF, full-duplex
693 * is turned ON, and the speed/mastership is forced.
694 */
695 switch (bgep->param_loop_mode) {
696 case BGE_LOOP_NONE:
697 default:
698 adv_autoneg = bgep->param_adv_autoneg;
699 adv_pause = bgep->param_adv_pause;
700 adv_asym_pause = bgep->param_adv_asym_pause;
701 adv_1000fdx = bgep->param_adv_1000fdx;
702 adv_1000hdx = bgep->param_adv_1000hdx;
703 adv_100fdx = bgep->param_adv_100fdx;
704 adv_100hdx = bgep->param_adv_100hdx;
705 adv_10fdx = bgep->param_adv_10fdx;
706 adv_10hdx = bgep->param_adv_10hdx;
707 break;
708
709 case BGE_LOOP_EXTERNAL_1000:
710 case BGE_LOOP_EXTERNAL_100:
711 case BGE_LOOP_EXTERNAL_10:
712 case BGE_LOOP_INTERNAL_PHY:
713 case BGE_LOOP_INTERNAL_MAC:
714 adv_autoneg = adv_pause = adv_asym_pause = B_FALSE;
715 adv_1000fdx = adv_100fdx = adv_10fdx = B_FALSE;
716 adv_1000hdx = adv_100hdx = adv_10hdx = B_FALSE;
717 bgep->param_link_duplex = LINK_DUPLEX_FULL;
718
719 switch (bgep->param_loop_mode) {
720 case BGE_LOOP_EXTERNAL_1000:
721 bgep->param_link_speed = 1000;
722 adv_1000fdx = B_TRUE;
723 auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK;
724 gigctrl |= MII_MSCONTROL_MANUAL;
725 gigctrl |= MII_MSCONTROL_MASTER;
726 break;
727
728 case BGE_LOOP_EXTERNAL_100:
729 bgep->param_link_speed = 100;
730 adv_100fdx = B_TRUE;
731 auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK;
732 break;
733
734 case BGE_LOOP_EXTERNAL_10:
735 bgep->param_link_speed = 10;
736 adv_10fdx = B_TRUE;
737 auxctrl = MII_AUX_CTRL_NORM_EXT_LOOPBACK;
738 break;
739
740 case BGE_LOOP_INTERNAL_PHY:
741 bgep->param_link_speed = 1000;
742 adv_1000fdx = B_TRUE;
743 control = MII_CONTROL_LOOPBACK;
744 break;
745
746 case BGE_LOOP_INTERNAL_MAC:
747 bgep->param_link_speed = 1000;
748 adv_1000fdx = B_TRUE;
749 break;
750 }
751 }
752
753 BGE_DEBUG(("bge_update_copper: autoneg %d "
754 "pause %d asym_pause %d "
755 "1000fdx %d 1000hdx %d "
756 "100fdx %d 100hdx %d "
757 "10fdx %d 10hdx %d ",
758 adv_autoneg,
759 adv_pause, adv_asym_pause,
760 adv_1000fdx, adv_1000hdx,
761 adv_100fdx, adv_100hdx,
762 adv_10fdx, adv_10hdx));
763
764 /*
765 * We should have at least one technology capability set;
766 * if not, we select a default of 1000Mb/s full-duplex
767 */
768 if (!adv_1000fdx && !adv_100fdx && !adv_10fdx &&
769 !adv_1000hdx && !adv_100hdx && !adv_10hdx)
770 adv_1000fdx = B_TRUE;
771
772 /*
773 * Now transform the adv_* variables into the proper settings
774 * of the PHY registers ...
775 *
776 * If autonegotiation is (now) enabled, we want to trigger
777 * a new autonegotiation cycle once the PHY has been
778 * programmed with the capabilities to be advertised.
779 */
780 if (adv_autoneg)
781 control |= MII_CONTROL_ANE|MII_CONTROL_RSAN;
782
783 if (adv_1000fdx)
784 control |= MII_CONTROL_1GB|MII_CONTROL_FDUPLEX;
785 else if (adv_1000hdx)
786 control |= MII_CONTROL_1GB;
787 else if (adv_100fdx)
788 control |= MII_CONTROL_100MB|MII_CONTROL_FDUPLEX;
789 else if (adv_100hdx)
790 control |= MII_CONTROL_100MB;
791 else if (adv_10fdx)
792 control |= MII_CONTROL_FDUPLEX;
793 else if (adv_10hdx)
794 control |= 0;
795 else
796 { _NOTE(EMPTY); } /* Can't get here anyway ... */
797
798 if (adv_1000fdx)
799 gigctrl |= MII_MSCONTROL_1000T_FD;
800 if (adv_1000hdx)
801 gigctrl |= MII_MSCONTROL_1000T;
802
803 if (adv_100fdx)
804 anar |= MII_ABILITY_100BASE_TX_FD;
805 if (adv_100hdx)
806 anar |= MII_ABILITY_100BASE_TX;
807 if (adv_10fdx)
808 anar |= MII_ABILITY_10BASE_T_FD;
809 if (adv_10hdx)
810 anar |= MII_ABILITY_10BASE_T;
811
812 if (adv_pause)
813 anar |= MII_ABILITY_PAUSE;
814 if (adv_asym_pause)
815 anar |= MII_ABILITY_ASMPAUSE;
816
817 /*
818 * Munge in any other fixed bits we require ...
819 */
820 anar |= MII_AN_SELECTOR_8023;
821 auxctrl |= MII_AUX_CTRL_NORM_TX_MODE;
822 auxctrl |= MII_AUX_CTRL_NORMAL;
823
824 /*
825 * Restart the PHY and write the new values. Note the
826 * time, so that we can say whether subsequent link state
827 * changes can be attributed to our reprogramming the PHY
828 */
829 if ((*bgep->physops->phys_restart)(bgep, B_FALSE) == DDI_FAILURE)
830 return (DDI_FAILURE);
831 bge_mii_put16(bgep, MII_AN_ADVERT, anar);
832 if (auxctrl & MII_AUX_CTRL_NORM_EXT_LOOPBACK)
833 bge_mii_put16(bgep, MII_AUX_CONTROL, auxctrl);
834 bge_mii_put16(bgep, MII_MSCONTROL, gigctrl);
835 bge_mii_put16(bgep, MII_CONTROL, control);
836
837 BGE_DEBUG(("bge_update_copper: anar <- 0x%x", anar));
838 BGE_DEBUG(("bge_update_copper: auxctrl <- 0x%x", auxctrl));
839 BGE_DEBUG(("bge_update_copper: gigctrl <- 0x%x", gigctrl));
840 BGE_DEBUG(("bge_update_copper: control <- 0x%x", control));
841
842 #if BGE_COPPER_WIRESPEED
843 /*
844 * Enable the 'wire-speed' feature, if the chip supports it
845 * and we haven't got (any) loopback mode selected.
846 */
847 switch (bgep->chipid.device) {
848 case DEVICE_ID_5700:
849 case DEVICE_ID_5700x:
850 case DEVICE_ID_5705C:
851 case DEVICE_ID_5782:
852 /*
853 * These chips are known or assumed not to support it
854 */
855 break;
856
857 default:
858 /*
859 * All other Broadcom chips are expected to support it.
860 */
861 if (bgep->param_loop_mode == BGE_LOOP_NONE)
862 bge_mii_put16(bgep, MII_AUX_CONTROL,
863 MII_AUX_CTRL_MISC_WRITE_ENABLE |
864 MII_AUX_CTRL_MISC_WIRE_SPEED |
865 MII_AUX_CTRL_MISC);
866 break;
867 }
868 #endif /* BGE_COPPER_WIRESPEED */
869 return (DDI_SUCCESS);
870 }
871
872 static boolean_t
bge_check_copper(bge_t * bgep,boolean_t recheck)873 bge_check_copper(bge_t *bgep, boolean_t recheck)
874 {
875 uint32_t emac_status;
876 uint16_t mii_status;
877 uint16_t aux;
878 uint_t mode;
879 boolean_t linkup;
880
881 /*
882 * Step 10: read the status from the PHY (which is self-clearing
883 * on read!); also read & clear the main (Ethernet) MAC status
884 * (the relevant bits of this are write-one-to-clear).
885 */
886 mii_status = bge_mii_get16(bgep, MII_STATUS);
887 emac_status = bge_reg_get32(bgep, ETHERNET_MAC_STATUS_REG);
888 bge_reg_put32(bgep, ETHERNET_MAC_STATUS_REG, emac_status);
889
890 BGE_DEBUG(("bge_check_copper: link %d/%s, MII status 0x%x "
891 "(was 0x%x), Ethernet MAC status 0x%x",
892 bgep->link_state, UPORDOWN(bgep->param_link_up), mii_status,
893 bgep->phy_gen_status, emac_status));
894
895 /*
896 * If the PHY status hasn't changed since last we looked, and
897 * we not forcing a recheck (i.e. the link state was already
898 * known), there's nothing to do.
899 */
900 if (mii_status == bgep->phy_gen_status && !recheck)
901 return (B_FALSE);
902
903 do {
904 /*
905 * Step 11: read AUX STATUS register to find speed/duplex
906 */
907 aux = bge_mii_get16(bgep, MII_AUX_STATUS);
908 BGE_CDB(bge_phydump, (bgep, mii_status, aux));
909
910 /*
911 * We will only consider the link UP if all the readings
912 * are consistent and give meaningful results ...
913 */
914 mode = aux & MII_AUX_STATUS_MODE_MASK;
915 mode >>= MII_AUX_STATUS_MODE_SHIFT;
916 if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
917 linkup = BIS(aux, MII_AUX_STATUS_LINKUP);
918 linkup &= BIS(mii_status, MII_STATUS_LINKUP);
919 } else {
920 linkup = bge_copper_link_speed[mode] > 0;
921 linkup &= bge_copper_link_duplex[mode] !=
922 LINK_DUPLEX_UNKNOWN;
923 linkup &= BIS(aux, MII_AUX_STATUS_LINKUP);
924 linkup &= BIS(mii_status, MII_STATUS_LINKUP);
925 }
926
927 BGE_DEBUG(("bge_check_copper: MII status 0x%x aux 0x%x "
928 "=> mode %d (%s)",
929 mii_status, aux,
930 mode, UPORDOWN(linkup)));
931
932 /*
933 * Record current register values, then reread status
934 * register & loop until it stabilises ...
935 */
936 bgep->phy_aux_status = aux;
937 bgep->phy_gen_status = mii_status;
938 mii_status = bge_mii_get16(bgep, MII_STATUS);
939 } while (mii_status != bgep->phy_gen_status);
940
941 /*
942 * Assume very little ...
943 */
944 bgep->param_lp_autoneg = B_FALSE;
945 bgep->param_lp_1000fdx = B_FALSE;
946 bgep->param_lp_1000hdx = B_FALSE;
947 bgep->param_lp_100fdx = B_FALSE;
948 bgep->param_lp_100hdx = B_FALSE;
949 bgep->param_lp_10fdx = B_FALSE;
950 bgep->param_lp_10hdx = B_FALSE;
951 bgep->param_lp_pause = B_FALSE;
952 bgep->param_lp_asym_pause = B_FALSE;
953 bgep->param_link_autoneg = B_FALSE;
954 bgep->param_link_tx_pause = B_FALSE;
955 if (bgep->param_adv_autoneg)
956 bgep->param_link_rx_pause = B_FALSE;
957 else
958 bgep->param_link_rx_pause = bgep->param_adv_pause;
959
960 /*
961 * Discover all the link partner's abilities.
962 * These are scattered through various registers ...
963 */
964 if (BIS(aux, MII_AUX_STATUS_LP_ANEG_ABLE)) {
965 bgep->param_lp_autoneg = B_TRUE;
966 bgep->param_link_autoneg = B_TRUE;
967 bgep->param_link_tx_pause = BIS(aux, MII_AUX_STATUS_TX_PAUSE);
968 bgep->param_link_rx_pause = BIS(aux, MII_AUX_STATUS_RX_PAUSE);
969
970 aux = bge_mii_get16(bgep, MII_MSSTATUS);
971 bgep->param_lp_1000fdx = BIS(aux, MII_MSSTATUS_LP1000T_FD);
972 bgep->param_lp_1000hdx = BIS(aux, MII_MSSTATUS_LP1000T);
973
974 aux = bge_mii_get16(bgep, MII_AN_LPABLE);
975 bgep->param_lp_100fdx = BIS(aux, MII_ABILITY_100BASE_TX_FD);
976 bgep->param_lp_100hdx = BIS(aux, MII_ABILITY_100BASE_TX);
977 bgep->param_lp_10fdx = BIS(aux, MII_ABILITY_10BASE_T_FD);
978 bgep->param_lp_10hdx = BIS(aux, MII_ABILITY_10BASE_T);
979 bgep->param_lp_pause = BIS(aux, MII_ABILITY_PAUSE);
980 bgep->param_lp_asym_pause = BIS(aux, MII_ABILITY_ASMPAUSE);
981 }
982
983 /*
984 * Step 12: update ndd-visible state parameters, BUT!
985 * we don't transfer the new state to <link_state> just yet;
986 * instead we mark the <link_state> as UNKNOWN, and our caller
987 * will resolve it once the status has stopped changing and
988 * been stable for several seconds.
989 */
990 BGE_DEBUG(("bge_check_copper: link was %s speed %d duplex %d",
991 UPORDOWN(bgep->param_link_up),
992 bgep->param_link_speed,
993 bgep->param_link_duplex));
994
995 if (!linkup)
996 mode = MII_AUX_STATUS_MODE_NONE;
997 bgep->param_link_up = linkup;
998 bgep->link_state = LINK_STATE_UNKNOWN;
999 if (DEVICE_5906_SERIES_CHIPSETS(bgep)) {
1000 if (bgep->phy_aux_status & MII_AUX_STATUS_NEG_ENABLED_5906) {
1001 bgep->param_link_speed =
1002 bge_copper_link_speed_5906[mode];
1003 bgep->param_link_duplex =
1004 bge_copper_link_duplex_5906[mode];
1005 } else {
1006 bgep->param_link_speed = (bgep->phy_aux_status &
1007 MII_AUX_STATUS_SPEED_IND_5906) ? 100 : 10;
1008 bgep->param_link_duplex = (bgep->phy_aux_status &
1009 MII_AUX_STATUS_DUPLEX_IND_5906) ? LINK_DUPLEX_FULL :
1010 LINK_DUPLEX_HALF;
1011 }
1012 } else {
1013 bgep->param_link_speed = bge_copper_link_speed[mode];
1014 bgep->param_link_duplex = bge_copper_link_duplex[mode];
1015 }
1016
1017 BGE_DEBUG(("bge_check_copper: link now %s speed %d duplex %d",
1018 UPORDOWN(bgep->param_link_up),
1019 bgep->param_link_speed,
1020 bgep->param_link_duplex));
1021
1022 return (B_TRUE);
1023 }
1024
1025 static const phys_ops_t copper_ops = {
1026 bge_restart_copper,
1027 bge_update_copper,
1028 bge_check_copper
1029 };
1030
1031
1032 /*
1033 * ========== SerDes support ==========
1034 */
1035
1036 #undef BGE_DBG
1037 #define BGE_DBG BGE_DBG_SERDES /* debug flag for this code */
1038
1039 /*
1040 * Reinitialise the SerDes interface. Note that it normally powers
1041 * up in the disabled state, so we need to explicitly activate it.
1042 */
1043 static int
bge_restart_serdes(bge_t * bgep,boolean_t powerdown)1044 bge_restart_serdes(bge_t *bgep, boolean_t powerdown)
1045 {
1046 uint32_t macmode;
1047
1048 BGE_TRACE(("bge_restart_serdes($%p, %d)", (void *)bgep, powerdown));
1049
1050 ASSERT(mutex_owned(bgep->genlock));
1051
1052 /*
1053 * Ensure that the main Ethernet MAC mode register is programmed
1054 * appropriately for the SerDes interface ...
1055 */
1056 macmode = bge_reg_get32(bgep, ETHERNET_MAC_MODE_REG);
1057 if (DEVICE_5714_SERIES_CHIPSETS(bgep)) {
1058 macmode |= ETHERNET_MODE_LINK_POLARITY;
1059 macmode &= ~ETHERNET_MODE_PORTMODE_MASK;
1060 macmode |= ETHERNET_MODE_PORTMODE_GMII;
1061 } else {
1062 macmode &= ~ETHERNET_MODE_LINK_POLARITY;
1063 macmode &= ~ETHERNET_MODE_PORTMODE_MASK;
1064 macmode |= ETHERNET_MODE_PORTMODE_TBI;
1065 }
1066 bge_reg_put32(bgep, ETHERNET_MAC_MODE_REG, macmode);
1067
1068 /*
1069 * Ensure that loopback is OFF and comma detection is enabled. Then
1070 * disable the SerDes output (the first time through, it may/will
1071 * already be disabled). If we're shutting down, leave it disabled.
1072 */
1073 bge_reg_clr32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TBI_LOOPBACK);
1074 bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_COMMA_DETECT);
1075 bge_reg_set32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TX_DISABLE);
1076 if (powerdown)
1077 return (DDI_SUCCESS);
1078
1079 /*
1080 * Otherwise, pause, (re-)enable the SerDes output, and send
1081 * all-zero config words in order to force autoneg restart.
1082 * Invalidate the saved "link partners received configs", as
1083 * we're starting over ...
1084 */
1085 drv_usecwait(10000);
1086 bge_reg_clr32(bgep, SERDES_CONTROL_REG, SERDES_CONTROL_TX_DISABLE);
1087 bge_reg_put32(bgep, TX_1000BASEX_AUTONEG_REG, 0);
1088 bge_reg_set32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS);
1089 drv_usecwait(10);
1090 bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG, ETHERNET_MODE_SEND_CFGS);
1091 bgep->serdes_lpadv = AUTONEG_CODE_FAULT_ANEG_ERR;
1092 bgep->serdes_status = ~0U;
1093 return (DDI_SUCCESS);
1094 }
1095
1096 /*
1097 * Synchronise the SerDes speed/duplex/autonegotiation capabilities and
1098 * advertisements with the required settings as specified by the various
1099 * param_* variables that can be poked via the NDD interface.
1100 *
1101 * We always reinitalise the SerDes; this should cause the link to go down,
1102 * and then back up again once the link is stable and autonegotiation
1103 * (if enabled) is complete. We should get a link state change interrupt
1104 * somewhere along the way ...
1105 *
1106 * NOTE: SerDes only supports 1000FDX/HDX (with or without pause) so the
1107 * param_* variables relating to lower speeds are ignored.
1108 *
1109 * NOTE: <genlock> must already be held by the caller
1110 */
1111 static int
bge_update_serdes(bge_t * bgep)1112 bge_update_serdes(bge_t *bgep)
1113 {
1114 boolean_t adv_autoneg;
1115 boolean_t adv_pause;
1116 boolean_t adv_asym_pause;
1117 boolean_t adv_1000fdx;
1118 boolean_t adv_1000hdx;
1119
1120 uint32_t serdes;
1121 uint32_t advert;
1122
1123 BGE_TRACE(("bge_update_serdes($%p)", (void *)bgep));
1124
1125 ASSERT(mutex_owned(bgep->genlock));
1126
1127 BGE_DEBUG(("bge_update_serdes: autoneg %d "
1128 "pause %d asym_pause %d "
1129 "1000fdx %d 1000hdx %d "
1130 "100fdx %d 100hdx %d "
1131 "10fdx %d 10hdx %d ",
1132 bgep->param_adv_autoneg,
1133 bgep->param_adv_pause, bgep->param_adv_asym_pause,
1134 bgep->param_adv_1000fdx, bgep->param_adv_1000hdx,
1135 bgep->param_adv_100fdx, bgep->param_adv_100hdx,
1136 bgep->param_adv_10fdx, bgep->param_adv_10hdx));
1137
1138 serdes = advert = 0;
1139
1140 /*
1141 * SerDes settings are normally based on the param_* variables,
1142 * but if any loopback mode is in effect, that takes precedence.
1143 *
1144 * BGE supports MAC-internal loopback, PHY-internal loopback,
1145 * and External loopback at a variety of speeds (with a special
1146 * cable). In all cases, autoneg is turned OFF, full-duplex
1147 * is turned ON, and the speed/mastership is forced.
1148 *
1149 * Note: for the SerDes interface, "PHY" internal loopback is
1150 * interpreted as SerDes internal loopback, and all external
1151 * loopback modes are treated equivalently, as 1Gb/external.
1152 */
1153 switch (bgep->param_loop_mode) {
1154 case BGE_LOOP_NONE:
1155 default:
1156 adv_autoneg = bgep->param_adv_autoneg;
1157 adv_pause = bgep->param_adv_pause;
1158 adv_asym_pause = bgep->param_adv_asym_pause;
1159 adv_1000fdx = bgep->param_adv_1000fdx;
1160 adv_1000hdx = bgep->param_adv_1000hdx;
1161 break;
1162
1163 case BGE_LOOP_INTERNAL_PHY:
1164 serdes |= SERDES_CONTROL_TBI_LOOPBACK;
1165 /* FALLTHRU */
1166 case BGE_LOOP_INTERNAL_MAC:
1167 case BGE_LOOP_EXTERNAL_1000:
1168 case BGE_LOOP_EXTERNAL_100:
1169 case BGE_LOOP_EXTERNAL_10:
1170 adv_autoneg = adv_pause = adv_asym_pause = B_FALSE;
1171 adv_1000fdx = B_TRUE;
1172 adv_1000hdx = B_FALSE;
1173 break;
1174 }
1175
1176 BGE_DEBUG(("bge_update_serdes: autoneg %d "
1177 "pause %d asym_pause %d "
1178 "1000fdx %d 1000hdx %d ",
1179 adv_autoneg,
1180 adv_pause, adv_asym_pause,
1181 adv_1000fdx, adv_1000hdx));
1182
1183 /*
1184 * We should have at least one gigabit technology capability
1185 * set; if not, we select a default of 1000Mb/s full-duplex
1186 */
1187 if (!adv_1000fdx && !adv_1000hdx)
1188 adv_1000fdx = B_TRUE;
1189
1190 /*
1191 * Now transform the adv_* variables into the proper settings
1192 * of the SerDes registers ...
1193 *
1194 * If autonegotiation is (now) not enabled, pretend it's been
1195 * done and failed ...
1196 */
1197 if (!adv_autoneg)
1198 advert |= AUTONEG_CODE_FAULT_ANEG_ERR;
1199
1200 if (adv_1000fdx) {
1201 advert |= AUTONEG_CODE_FULL_DUPLEX;
1202 bgep->param_adv_1000fdx = adv_1000fdx;
1203 bgep->param_link_duplex = LINK_DUPLEX_FULL;
1204 bgep->param_link_speed = 1000;
1205 }
1206 if (adv_1000hdx) {
1207 advert |= AUTONEG_CODE_HALF_DUPLEX;
1208 bgep->param_adv_1000hdx = adv_1000hdx;
1209 bgep->param_link_duplex = LINK_DUPLEX_HALF;
1210 bgep->param_link_speed = 1000;
1211 }
1212
1213 if (adv_pause)
1214 advert |= AUTONEG_CODE_PAUSE;
1215 if (adv_asym_pause)
1216 advert |= AUTONEG_CODE_ASYM_PAUSE;
1217
1218 /*
1219 * Restart the SerDes and write the new values. Note the
1220 * time, so that we can say whether subsequent link state
1221 * changes can be attributed to our reprogramming the SerDes
1222 */
1223 bgep->serdes_advert = advert;
1224 (void) bge_restart_serdes(bgep, B_FALSE);
1225 bge_reg_set32(bgep, SERDES_CONTROL_REG, serdes);
1226
1227 BGE_DEBUG(("bge_update_serdes: serdes |= 0x%x, advert 0x%x",
1228 serdes, advert));
1229 return (DDI_SUCCESS);
1230 }
1231
1232 /*
1233 * Bare-minimum autoneg protocol
1234 *
1235 * This code is only called when the link is up and we're receiving config
1236 * words, which implies that the link partner wants to autonegotiate
1237 * (otherwise, we wouldn't see configs and wouldn't reach this code).
1238 */
1239 static void
bge_autoneg_serdes(bge_t * bgep)1240 bge_autoneg_serdes(bge_t *bgep)
1241 {
1242 boolean_t ack;
1243
1244 bgep->serdes_lpadv = bge_reg_get32(bgep, RX_1000BASEX_AUTONEG_REG);
1245 ack = BIS(bgep->serdes_lpadv, AUTONEG_CODE_ACKNOWLEDGE);
1246
1247 if (!ack) {
1248 /*
1249 * Phase 1: after SerDes reset, we send a few zero configs
1250 * but then stop. Here the partner is sending configs, but
1251 * not ACKing ours; we assume that's 'cos we're not sending
1252 * any. So here we send ours, with ACK already set.
1253 */
1254 bge_reg_put32(bgep, TX_1000BASEX_AUTONEG_REG,
1255 bgep->serdes_advert | AUTONEG_CODE_ACKNOWLEDGE);
1256 bge_reg_set32(bgep, ETHERNET_MAC_MODE_REG,
1257 ETHERNET_MODE_SEND_CFGS);
1258 } else {
1259 /*
1260 * Phase 2: partner has ACKed our configs, so now we can
1261 * stop sending; once our partner also stops sending, we
1262 * can resolve the Tx/Rx configs.
1263 */
1264 bge_reg_clr32(bgep, ETHERNET_MAC_MODE_REG,
1265 ETHERNET_MODE_SEND_CFGS);
1266 }
1267
1268 BGE_DEBUG(("bge_autoneg_serdes: Rx 0x%x %s Tx 0x%x",
1269 bgep->serdes_lpadv,
1270 ack ? "stop" : "send",
1271 bgep->serdes_advert));
1272 }
1273
1274 static boolean_t
bge_check_serdes(bge_t * bgep,boolean_t recheck)1275 bge_check_serdes(bge_t *bgep, boolean_t recheck)
1276 {
1277 uint32_t emac_status;
1278 uint32_t tx_status;
1279 uint32_t lpadv;
1280 boolean_t linkup;
1281 boolean_t linkup_old = bgep->param_link_up;
1282
1283 for (;;) {
1284 /*
1285 * Step 10: BCM5714S, BCM5715S only
1286 * Don't call function bge_autoneg_serdes() as
1287 * RX_1000BASEX_AUTONEG_REG (0x0448) is not applicable
1288 * to BCM5705, BCM5788, BCM5721, BCM5751, BCM5752,
1289 * BCM5714, and BCM5715 devices.
1290 */
1291 if (DEVICE_5714_SERIES_CHIPSETS(bgep)) {
1292 tx_status = bge_reg_get32(bgep,
1293 TRANSMIT_MAC_STATUS_REG);
1294 linkup = BIS(tx_status, TRANSMIT_STATUS_LINK_UP);
1295 emac_status = bge_reg_get32(bgep,
1296 ETHERNET_MAC_STATUS_REG);
1297 bgep->serdes_status = emac_status;
1298 if ((linkup && linkup_old) ||
1299 (!linkup && !linkup_old)) {
1300 emac_status &= ~ETHERNET_STATUS_LINK_CHANGED;
1301 emac_status &= ~ETHERNET_STATUS_RECEIVING_CFG;
1302 break;
1303 }
1304 emac_status |= ETHERNET_STATUS_LINK_CHANGED;
1305 emac_status |= ETHERNET_STATUS_RECEIVING_CFG;
1306 if (linkup)
1307 linkup_old = B_TRUE;
1308 else
1309 linkup_old = B_FALSE;
1310 recheck = B_TRUE;
1311 } else {
1312 /*
1313 * Step 10: others
1314 * read & clear the main (Ethernet) MAC status
1315 * (the relevant bits of this are write-one-to-clear).
1316 */
1317 emac_status = bge_reg_get32(bgep,
1318 ETHERNET_MAC_STATUS_REG);
1319 bge_reg_put32(bgep,
1320 ETHERNET_MAC_STATUS_REG, emac_status);
1321
1322 BGE_DEBUG(("bge_check_serdes: link %d/%s, "
1323 "MAC status 0x%x (was 0x%x)",
1324 bgep->link_state, UPORDOWN(bgep->param_link_up),
1325 emac_status, bgep->serdes_status));
1326
1327 /*
1328 * We will only consider the link UP if all the readings
1329 * are consistent and give meaningful results ...
1330 */
1331 bgep->serdes_status = emac_status;
1332 linkup = BIS(emac_status,
1333 ETHERNET_STATUS_SIGNAL_DETECT);
1334 linkup &= BIS(emac_status, ETHERNET_STATUS_PCS_SYNCHED);
1335
1336 /*
1337 * Now some fiddling with the interpretation:
1338 * if there's been an error at the PCS level, treat
1339 * it as a link change (the h/w doesn't do this)
1340 *
1341 * if there's been a change, but it's only a PCS
1342 * sync change (not a config change), AND the link
1343 * already was & is still UP, then ignore the
1344 * change
1345 */
1346 if (BIS(emac_status, ETHERNET_STATUS_PCS_ERROR))
1347 emac_status |= ETHERNET_STATUS_LINK_CHANGED;
1348 else if (BIC(emac_status, ETHERNET_STATUS_CFG_CHANGED))
1349 if (bgep->param_link_up && linkup)
1350 emac_status &=
1351 ~ETHERNET_STATUS_LINK_CHANGED;
1352
1353 BGE_DEBUG(("bge_check_serdes: status 0x%x => 0x%x %s",
1354 bgep->serdes_status, emac_status,
1355 UPORDOWN(linkup)));
1356
1357 /*
1358 * If we're receiving configs, run the autoneg protocol
1359 */
1360 if (linkup && BIS(emac_status,
1361 ETHERNET_STATUS_RECEIVING_CFG))
1362 bge_autoneg_serdes(bgep);
1363
1364 /*
1365 * If the SerDes status hasn't changed, we're done ...
1366 */
1367 if (BIC(emac_status, ETHERNET_STATUS_LINK_CHANGED))
1368 break;
1369
1370 /*
1371 * Go round again until we no longer see a change ...
1372 */
1373 recheck = B_TRUE;
1374 }
1375 }
1376
1377 /*
1378 * If we're not forcing a recheck (i.e. the link state was already
1379 * known), and we didn't see the hardware flag a change, there's
1380 * no more to do (and we tell the caller nothing happened).
1381 */
1382 if (!recheck)
1383 return (B_FALSE);
1384
1385 /*
1386 * Don't resolve autoneg until we're no longer receiving configs
1387 */
1388 if (linkup && BIS(emac_status, ETHERNET_STATUS_RECEIVING_CFG))
1389 return (B_FALSE);
1390
1391 /*
1392 * Assume very little ...
1393 */
1394 bgep->param_lp_autoneg = B_FALSE;
1395 bgep->param_lp_1000fdx = B_FALSE;
1396 bgep->param_lp_1000hdx = B_FALSE;
1397 bgep->param_lp_100fdx = B_FALSE;
1398 bgep->param_lp_100hdx = B_FALSE;
1399 bgep->param_lp_10fdx = B_FALSE;
1400 bgep->param_lp_10hdx = B_FALSE;
1401 bgep->param_lp_pause = B_FALSE;
1402 bgep->param_lp_asym_pause = B_FALSE;
1403 bgep->param_link_autoneg = B_FALSE;
1404 bgep->param_link_tx_pause = B_FALSE;
1405 if (bgep->param_adv_autoneg)
1406 bgep->param_link_rx_pause = B_FALSE;
1407 else
1408 bgep->param_link_rx_pause = bgep->param_adv_pause;
1409
1410 /*
1411 * Discover all the link partner's abilities.
1412 */
1413 lpadv = bgep->serdes_lpadv;
1414 if (lpadv != 0 && BIC(lpadv, AUTONEG_CODE_FAULT_MASK)) {
1415 /*
1416 * No fault, so derive partner's capabilities
1417 */
1418 bgep->param_lp_autoneg = B_TRUE;
1419 bgep->param_lp_1000fdx = BIS(lpadv, AUTONEG_CODE_FULL_DUPLEX);
1420 bgep->param_lp_1000hdx = BIS(lpadv, AUTONEG_CODE_HALF_DUPLEX);
1421 bgep->param_lp_pause = BIS(lpadv, AUTONEG_CODE_PAUSE);
1422 bgep->param_lp_asym_pause = BIS(lpadv, AUTONEG_CODE_ASYM_PAUSE);
1423
1424 /*
1425 * Pause direction resolution
1426 */
1427 bgep->param_link_autoneg = B_TRUE;
1428 if (bgep->param_adv_pause &&
1429 bgep->param_lp_pause) {
1430 bgep->param_link_tx_pause = B_TRUE;
1431 bgep->param_link_rx_pause = B_TRUE;
1432 }
1433 if (bgep->param_adv_asym_pause &&
1434 bgep->param_lp_asym_pause) {
1435 if (bgep->param_adv_pause)
1436 bgep->param_link_rx_pause = B_TRUE;
1437 if (bgep->param_lp_pause)
1438 bgep->param_link_tx_pause = B_TRUE;
1439 }
1440 }
1441
1442 /*
1443 * Step 12: update ndd-visible state parameters, BUT!
1444 * we don't transfer the new state to <link_state> just yet;
1445 * instead we mark the <link_state> as UNKNOWN, and our caller
1446 * will resolve it once the status has stopped changing and
1447 * been stable for several seconds.
1448 */
1449 BGE_DEBUG(("bge_check_serdes: link was %s speed %d duplex %d",
1450 UPORDOWN(bgep->param_link_up),
1451 bgep->param_link_speed,
1452 bgep->param_link_duplex));
1453
1454 if (linkup) {
1455 bgep->param_link_up = B_TRUE;
1456 bgep->param_link_speed = 1000;
1457 if (bgep->param_adv_1000fdx)
1458 bgep->param_link_duplex = LINK_DUPLEX_FULL;
1459 else
1460 bgep->param_link_duplex = LINK_DUPLEX_HALF;
1461 if (bgep->param_lp_autoneg && !bgep->param_lp_1000fdx)
1462 bgep->param_link_duplex = LINK_DUPLEX_HALF;
1463 } else {
1464 bgep->param_link_up = B_FALSE;
1465 bgep->param_link_speed = 0;
1466 bgep->param_link_duplex = LINK_DUPLEX_UNKNOWN;
1467 }
1468 bgep->link_state = LINK_STATE_UNKNOWN;
1469
1470 BGE_DEBUG(("bge_check_serdes: link now %s speed %d duplex %d",
1471 UPORDOWN(bgep->param_link_up),
1472 bgep->param_link_speed,
1473 bgep->param_link_duplex));
1474
1475 return (B_TRUE);
1476 }
1477
1478 static const phys_ops_t serdes_ops = {
1479 bge_restart_serdes,
1480 bge_update_serdes,
1481 bge_check_serdes
1482 };
1483
1484 /*
1485 * ========== Exported physical layer control routines ==========
1486 */
1487
1488 #undef BGE_DBG
1489 #define BGE_DBG BGE_DBG_PHYS /* debug flag for this code */
1490
1491 /*
1492 * Here we have to determine which media we're using (copper or serdes).
1493 * Once that's done, we can initialise the physical layer appropriately.
1494 */
1495 int
bge_phys_init(bge_t * bgep)1496 bge_phys_init(bge_t *bgep)
1497 {
1498 BGE_TRACE(("bge_phys_init($%p)", (void *)bgep));
1499
1500 mutex_enter(bgep->genlock);
1501
1502 /*
1503 * Probe for the (internal) PHY. If it's not there, we'll assume
1504 * that this is a 5703/4S, with a SerDes interface rather than
1505 * a PHY. BCM5714S/BCM5715S are not supported.It are based on
1506 * BCM800x PHY.
1507 */
1508 bgep->phy_mii_addr = 1;
1509 if (DEVICE_5717_SERIES_CHIPSETS(bgep)) {
1510 int regval = bge_reg_get32(bgep, CPMU_STATUS_REG);
1511 if (regval & CPMU_STATUS_FUN_NUM)
1512 bgep->phy_mii_addr += 1;
1513 regval = bge_reg_get32(bgep, SGMII_STATUS_REG);
1514 if (regval & MEDIA_SELECTION_MODE)
1515 bgep->phy_mii_addr += 7;
1516 }
1517
1518 if (bge_phy_probe(bgep)) {
1519 bgep->chipid.flags &= ~CHIP_FLAG_SERDES;
1520 bgep->physops = &copper_ops;
1521 } else {
1522 bgep->chipid.flags |= CHIP_FLAG_SERDES;
1523 bgep->physops = &serdes_ops;
1524 }
1525
1526 if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS) {
1527 mutex_exit(bgep->genlock);
1528 return (EIO);
1529 }
1530 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1531 mutex_exit(bgep->genlock);
1532 return (EIO);
1533 }
1534 mutex_exit(bgep->genlock);
1535 return (0);
1536 }
1537
1538 /*
1539 * Reset the physical layer
1540 */
1541 void
bge_phys_reset(bge_t * bgep)1542 bge_phys_reset(bge_t *bgep)
1543 {
1544 BGE_TRACE(("bge_phys_reset($%p)", (void *)bgep));
1545
1546 mutex_enter(bgep->genlock);
1547 if ((*bgep->physops->phys_restart)(bgep, B_FALSE) != DDI_SUCCESS)
1548 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
1549 if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
1550 ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
1551 mutex_exit(bgep->genlock);
1552 }
1553
1554 /*
1555 * Reset and power off the physical layer.
1556 *
1557 * Another RESET should get it back to working, but it may take a few
1558 * seconds it may take a few moments to return to normal operation ...
1559 */
1560 int
bge_phys_idle(bge_t * bgep)1561 bge_phys_idle(bge_t *bgep)
1562 {
1563 BGE_TRACE(("bge_phys_idle($%p)", (void *)bgep));
1564
1565 ASSERT(mutex_owned(bgep->genlock));
1566 return ((*bgep->physops->phys_restart)(bgep, B_TRUE));
1567 }
1568
1569 /*
1570 * Synchronise the PHYSICAL layer's speed/duplex/autonegotiation capabilities
1571 * and advertisements with the required settings as specified by the various
1572 * param_* variables that can be poked via the NDD interface.
1573 *
1574 * We always reset the PHYSICAL layer and reprogram *all* relevant registers.
1575 * This is expected to cause the link to go down, and then back up again once
1576 * the link is stable and autonegotiation (if enabled) is complete. We should
1577 * get a link state change interrupt somewhere along the way ...
1578 *
1579 * NOTE: <genlock> must already be held by the caller
1580 */
1581 int
bge_phys_update(bge_t * bgep)1582 bge_phys_update(bge_t *bgep)
1583 {
1584 BGE_TRACE(("bge_phys_update($%p)", (void *)bgep));
1585
1586 ASSERT(mutex_owned(bgep->genlock));
1587 return ((*bgep->physops->phys_update)(bgep));
1588 }
1589
1590 #undef BGE_DBG
1591 #define BGE_DBG BGE_DBG_LINK /* debug flag for this code */
1592
1593 /*
1594 * Read the link status and determine whether anything's changed ...
1595 *
1596 * This routine should be called whenever the chip flags a change
1597 * in the hardware link state.
1598 *
1599 * This routine returns B_FALSE if the link state has not changed,
1600 * returns B_TRUE when the change to the new state should be accepted.
1601 * In such a case, the param_* variables give the new hardware state,
1602 * which the caller should use to update link_state etc.
1603 *
1604 * The caller must already hold <genlock>
1605 */
1606 boolean_t
bge_phys_check(bge_t * bgep)1607 bge_phys_check(bge_t *bgep)
1608 {
1609 int32_t orig_state;
1610 boolean_t recheck;
1611
1612 BGE_TRACE(("bge_phys_check($%p)", (void *)bgep));
1613
1614 ASSERT(mutex_owned(bgep->genlock));
1615
1616 orig_state = bgep->link_state;
1617 recheck = orig_state == LINK_STATE_UNKNOWN;
1618 recheck = (*bgep->physops->phys_check)(bgep, recheck);
1619 if (!recheck)
1620 return (B_FALSE);
1621
1622 return (B_TRUE);
1623 }
1624