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