Deleted Added
sdiff udiff text old ( 215015 ) new ( 215297 )
full compact
1/*-
2 * Copyright (c) 2000
3 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 17 unchanged lines hidden (view full) ---

26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/dev/mii/brgphy.c 215015 2010-11-08 21:23:28Z jmallett $");
35
36/*
37 * Driver for the Broadcom BCM54xx/57xx 1000baseTX PHY.
38 */
39
40#include <sys/param.h>
41#include <sys/systm.h>
42#include <sys/kernel.h>

--- 51 unchanged lines hidden (view full) ---

94 "brgphy",
95 brgphy_methods,
96 sizeof(struct brgphy_softc)
97};
98
99DRIVER_MODULE(brgphy, miibus, brgphy_driver, brgphy_devclass, 0, 0);
100
101static int brgphy_service(struct mii_softc *, struct mii_data *, int);
102static void brgphy_setmedia(struct mii_softc *, int, int);
103static void brgphy_status(struct mii_softc *);
104static void brgphy_mii_phy_auto(struct mii_softc *);
105static void brgphy_reset(struct mii_softc *);
106static void brgphy_enable_loopback(struct mii_softc *);
107static void bcm5401_load_dspcode(struct mii_softc *);
108static void bcm5411_load_dspcode(struct mii_softc *);
109static void bcm54k2_load_dspcode(struct mii_softc *);
110static void brgphy_fixup_5704_a0_bug(struct mii_softc *);
111static void brgphy_fixup_adc_bug(struct mii_softc *);
112static void brgphy_fixup_adjust_trim(struct mii_softc *);

--- 51 unchanged lines hidden (view full) ---

164 return (0);
165 return (1);
166}
167
168/* Search for our PHY in the list of known PHYs */
169static int
170brgphy_probe(device_t dev)
171{
172 return (mii_phy_dev_probe(dev, brgphys, BUS_PROBE_DEFAULT));
173}
174
175/* Attach the PHY to the MII bus */
176static int
177brgphy_attach(device_t dev)
178{
179 struct brgphy_softc *bsc;
180 struct bge_softc *bge_sc = NULL;
181 struct bce_softc *bce_sc = NULL;
182 struct mii_softc *sc;
183 struct mii_attach_args *ma;
184 struct mii_data *mii;
185 struct ifnet *ifp;
186 int fast_ether;
187
188 bsc = device_get_softc(dev);
189 sc = &bsc->mii_sc;
190 ma = device_get_ivars(dev);
191 sc->mii_dev = device_get_parent(dev);
192 mii = ma->mii_data;
193 LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
194
195 /* Initialize mii_softc structure */
196 sc->mii_flags = miibus_get_flags(dev);
197 sc->mii_inst = mii->mii_instance++;
198 sc->mii_phy = ma->mii_phyno;
199 sc->mii_service = brgphy_service;
200 sc->mii_pdata = mii;
201
202 /*
203 * At least some variants wedge when isolating, at least some also
204 * don't support loopback.
205 */
206 sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
207 sc->mii_anegticks = MII_ANEGTICKS_GIGE;
208
209 /* Initialize brgphy_softc structure */
210 bsc->mii_oui = MII_OUI(ma->mii_id1, ma->mii_id2);
211 bsc->mii_model = MII_MODEL(ma->mii_id2);
212 bsc->mii_rev = MII_REV(ma->mii_id2);
213 bsc->serdes_flags = 0;
214
215 fast_ether = 0;
216
217 if (bootverbose)
218 device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n",
219 bsc->mii_oui, bsc->mii_model, bsc->mii_rev);
220
221 /* Handle any special cases based on the PHY ID */
222 switch (bsc->mii_oui) {
223 case MII_OUI_BROADCOM:
224 case MII_OUI_BROADCOM2:

--- 49 unchanged lines hidden (view full) ---

274 /* Todo: Need to add additional controllers such as 5906 & 5787F */
275 /* The 590x chips are 10/100 only. */
276 if (bge_sc &&
277 pci_get_vendor(bge_sc->bge_dev) == BCOM_VENDORID &&
278 (pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901 ||
279 pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5901A2 ||
280 pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906 ||
281 pci_get_device(bge_sc->bge_dev) == BCOM_DEVICEID_BCM5906M)) {
282 fast_ether = 1;
283 sc->mii_anegticks = MII_ANEGTICKS;
284 }
285
286 brgphy_reset(sc);
287
288 /* Read the PHY's capabilities. */
289 sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
290 if (sc->mii_capabilities & BMSR_EXTSTAT)
291 sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
292 device_printf(dev, " ");
293
294#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
295
296 /* Add the supported media types */
297 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
298 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst),
299 BRGPHY_S10);
300 printf("10baseT, ");
301 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst),
302 BRGPHY_S10 | BRGPHY_BMCR_FDX);
303 printf("10baseT-FDX, ");
304 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst),
305 BRGPHY_S100);
306 printf("100baseTX, ");
307 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst),
308 BRGPHY_S100 | BRGPHY_BMCR_FDX);
309 printf("100baseTX-FDX, ");
310 if (fast_ether == 0) {
311 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, sc->mii_inst),
312 BRGPHY_S1000);
313 printf("1000baseT, ");
314 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, sc->mii_inst),
315 BRGPHY_S1000 | BRGPHY_BMCR_FDX);
316 printf("1000baseT-FDX, ");
317 }
318 } else {
319 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst),
320 BRGPHY_S1000 | BRGPHY_BMCR_FDX);
321 printf("1000baseSX-FDX, ");
322 /* 2.5G support is a software enabled feature on the 5708S and 5709S. */
323 if (bce_sc && (bce_sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) {
324 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX, sc->mii_inst), 0);
325 printf("2500baseSX-FDX, ");
326 } else if ((bsc->serdes_flags & BRGPHY_5708S) && bce_sc &&

--- 5 unchanged lines hidden (view full) ---

332 * complete. This happens with a specific chip id
333 * only and when the 1000baseSX-FDX is the only
334 * mode. Workaround this issue since it's unlikely
335 * to be ever addressed.
336 */
337 printf("auto-neg workaround, ");
338 bsc->serdes_flags |= BRGPHY_NOANWAIT;
339 }
340 }
341
342 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0);
343 printf("auto\n");
344
345#undef ADD
346 MIIBUS_MEDIAINIT(sc->mii_dev);
347 return (0);
348}
349
350static int
351brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
352{

--- 9 unchanged lines hidden (view full) ---

362 if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
363 break;
364
365 /* Todo: Why is this here? Is it really needed? */
366 brgphy_reset(sc); /* XXX hardware bug work-around */
367
368 switch (IFM_SUBTYPE(ife->ifm_media)) {
369 case IFM_AUTO:
370 brgphy_mii_phy_auto(sc);
371 break;
372 case IFM_2500_SX:
373 case IFM_1000_SX:
374 case IFM_1000_T:
375 case IFM_100_TX:
376 case IFM_10_T:
377 brgphy_setmedia(sc, ife->ifm_media,
378 mii->mii_ifp->if_flags & IFF_LINK0);
379 break;
380 default:
381 return (EINVAL);
382 }
383 break;
384 case MII_TICK:
385 /* Bail if the interface isn't up. */
386 if ((mii->mii_ifp->if_flags & IFF_UP) == 0)

--- 5 unchanged lines hidden (view full) ---

392 sc->mii_ticks = 0;
393 break;
394 }
395
396 /*
397 * Check to see if we have link. If we do, we don't
398 * need to restart the autonegotiation process.
399 */
400 val = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
401 if (val & BMSR_LINK) {
402 sc->mii_ticks = 0; /* Reset autoneg timer. */
403 break;
404 }
405
406 /* Announce link loss right after it happens. */
407 if (sc->mii_ticks++ == 0)
408 break;
409
410 /* Only retry autonegotiation every mii_anegticks seconds. */
411 if (sc->mii_ticks <= sc->mii_anegticks)
412 break;
413
414
415 /* Retry autonegotiation */
416 sc->mii_ticks = 0;
417 brgphy_mii_phy_auto(sc);
418 break;
419 }
420
421 /* Update the media status. */
422 brgphy_status(sc);
423
424 /*
425 * Callback if something changed. Note that we need to poke

--- 25 unchanged lines hidden (view full) ---

451 case MII_OUI_xxBROADCOM_ALT1:
452 break;
453 }
454 }
455 mii_phy_update(sc, cmd);
456 return (0);
457}
458
459
460/****************************************************************************/
461/* Sets the PHY link speed. */
462/* */
463/* Returns: */
464/* None */
465/****************************************************************************/
466static void
467brgphy_setmedia(struct mii_softc *sc, int media, int master)
468{
469 struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
470 int bmcr = 0, gig;
471
472 /* Calculate the value for the BMCR register. */
473 switch (IFM_SUBTYPE(media)) {
474 case IFM_2500_SX:
475 break;
476 case IFM_1000_SX:
477 case IFM_1000_T:
478 bmcr = BRGPHY_S1000;
479 break;
480 case IFM_100_TX:
481 bmcr = BRGPHY_S100;
482 break;
483 case IFM_10_T:
484 default:
485 bmcr = BRGPHY_S10;
486 break;
487 }
488
489 /* Calculate duplex settings for 1000BasetT/1000BaseX. */
490 if ((media & IFM_GMASK) == IFM_FDX) {
491 bmcr |= BRGPHY_BMCR_FDX;
492 gig = BRGPHY_1000CTL_AFD;
493 } else {
494 gig = BRGPHY_1000CTL_AHD;
495 }
496
497 /* Force loopback to disconnect PHY for Ethernet medium. */
498 brgphy_enable_loopback(sc);
499
500 /* Disable 1000BaseT advertisements. */
501 PHY_WRITE(sc, BRGPHY_MII_1000CTL, 0);
502 /* Disable 10/100 advertisements. */
503 PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE);
504 /* Write forced link speed. */
505 PHY_WRITE(sc, BRGPHY_MII_BMCR, bmcr);
506
507 /* If 10/100 only then configuration is complete. */
508 if ((IFM_SUBTYPE(media) != IFM_1000_T) && (IFM_SUBTYPE(media) != IFM_1000_SX))
509 goto brgphy_setmedia_exit;
510
511 /* Set duplex speed advertisement for 1000BaseT/1000BaseX. */
512 PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig);
513 /* Restart auto-negotiation for 1000BaseT/1000BaseX. */
514 PHY_WRITE(sc, BRGPHY_MII_BMCR,
515 bmcr | BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG);
516
517 /* If not 5701 PHY then configuration is complete. */
518 if (bsc->mii_model != MII_MODEL_xxBROADCOM_BCM5701)
519 goto brgphy_setmedia_exit;
520
521 /*
522 * When setting the link manually, one side must be the master and
523 * the other the slave. However ifmedia doesn't give us a good way
524 * to specify this, so we fake it by using one of the LINK flags.
525 * If LINK0 is set, we program the PHY to be a master, otherwise
526 * it's a slave.
527 */
528 if (master) {
529 PHY_WRITE(sc, BRGPHY_MII_1000CTL,
530 gig | BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC);
531 } else {
532 PHY_WRITE(sc, BRGPHY_MII_1000CTL,
533 gig | BRGPHY_1000CTL_MSE);
534 }
535
536brgphy_setmedia_exit:
537 return;
538}
539
540/****************************************************************************/
541/* Set the media status based on the PHY settings. */
542/* IFM_FLAG0 = 0 (RX flow control disabled) | 1 (enabled) */
543/* IFM_FLAG1 = 0 (TX flow control disabled) | 1 (enabled) */
544/* */
545/* Returns: */
546/* None */
547/****************************************************************************/
548static void
549brgphy_status(struct mii_softc *sc)
550{
551 struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
552 struct mii_data *mii = sc->mii_pdata;
553 int aux, bmcr, bmsr, anar, anlpar, xstat, val;
554
555
556 mii->mii_media_status = IFM_AVALID;
557 mii->mii_media_active = IFM_ETHER;
558
559 bmsr = PHY_READ(sc, BRGPHY_MII_BMSR) | PHY_READ(sc, BRGPHY_MII_BMSR);
560 bmcr = PHY_READ(sc, BRGPHY_MII_BMCR);
561 anar = PHY_READ(sc, BRGPHY_MII_ANAR);
562 anlpar = PHY_READ(sc, BRGPHY_MII_ANLPAR);
563
564 /* Loopback is enabled. */
565 if (bmcr & BRGPHY_BMCR_LOOP) {
566
567 mii->mii_media_active |= IFM_LOOP;
568 }
569
570 /* Autoneg is still in progress. */
571 if ((bmcr & BRGPHY_BMCR_AUTOEN) &&
572 (bmsr & BRGPHY_BMSR_ACOMP) == 0 &&
573 (bsc->serdes_flags & BRGPHY_NOANWAIT) == 0) {
574 /* Erg, still trying, I guess... */
575 mii->mii_media_active |= IFM_NONE;
576 goto brgphy_status_exit;
577 }
578
579 /* Autoneg is enabled and complete, link should be up. */
580 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
581 aux = PHY_READ(sc, BRGPHY_MII_AUXSTS);
582
583 /* If copper link is up, get the negotiated speed/duplex. */
584 if (aux & BRGPHY_AUXSTS_LINK) {
585 mii->mii_media_status |= IFM_ACTIVE;
586 switch (aux & BRGPHY_AUXSTS_AN_RES) {
587 case BRGPHY_RES_1000FD:
588 mii->mii_media_active |= IFM_1000_T | IFM_FDX; break;

--- 7 unchanged lines hidden (view full) ---

596 mii->mii_media_active |= IFM_100_TX | IFM_HDX; break;
597 case BRGPHY_RES_10FD:
598 mii->mii_media_active |= IFM_10_T | IFM_FDX; break;
599 case BRGPHY_RES_10HD:
600 mii->mii_media_active |= IFM_10_T | IFM_HDX; break;
601 default:
602 mii->mii_media_active |= IFM_NONE; break;
603 }
604 }
605 } else {
606 /* If serdes link is up, get the negotiated speed/duplex. */
607 if (bmsr & BRGPHY_BMSR_LINK) {
608 mii->mii_media_status |= IFM_ACTIVE;
609 }
610
611 /* Check the link speed/duplex based on the PHY type. */
612 if (bsc->serdes_flags & BRGPHY_5706S) {
613 mii->mii_media_active |= IFM_1000_SX;
614
615 /* If autoneg enabled, read negotiated duplex settings */
616 if (bmcr & BRGPHY_BMCR_AUTOEN) {
617 val = PHY_READ(sc, BRGPHY_SERDES_ANAR) & PHY_READ(sc, BRGPHY_SERDES_ANLPAR);
618 if (val & BRGPHY_SERDES_ANAR_FDX)
619 mii->mii_media_active |= IFM_FDX;
620 else
621 mii->mii_media_active |= IFM_HDX;
622 }
623
624 } else if (bsc->serdes_flags & BRGPHY_5708S) {
625 PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);
626 xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1);
627
628 /* Check for MRBE auto-negotiated speed results. */
629 switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) {
630 case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10:
631 mii->mii_media_active |= IFM_10_FL; break;

--- 5 unchanged lines hidden (view full) ---

637 mii->mii_media_active |= IFM_2500_SX; break;
638 }
639
640 /* Check for MRBE auto-negotiated duplex results. */
641 if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX)
642 mii->mii_media_active |= IFM_FDX;
643 else
644 mii->mii_media_active |= IFM_HDX;
645
646 } else if (bsc->serdes_flags & BRGPHY_5709S) {
647
648 /* Select GP Status Block of the AN MMD, get autoneg results. */
649 PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_GP_STATUS);
650 xstat = PHY_READ(sc, BRGPHY_GP_STATUS_TOP_ANEG_STATUS);
651
652 /* Restore IEEE0 block (assumed in all brgphy(4) code). */
653 PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
654
655 /* Check for MRBE auto-negotiated speed results. */

--- 9 unchanged lines hidden (view full) ---

665 }
666
667 /* Check for MRBE auto-negotiated duplex results. */
668 if (xstat & BRGPHY_GP_STATUS_TOP_ANEG_FDX)
669 mii->mii_media_active |= IFM_FDX;
670 else
671 mii->mii_media_active |= IFM_HDX;
672 }
673
674 }
675
676 /* Todo: Change bge to use these settings. */
677
678 /* Fetch flow control settings from the copper PHY. */
679 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
680 /* Set FLAG0 if RX is enabled and FLAG1 if TX is enabled */
681 if ((anar & BRGPHY_ANAR_PC) && (anlpar & BRGPHY_ANLPAR_PC)) {
682 mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1;
683 } else if (!(anar & BRGPHY_ANAR_PC) && (anlpar & BRGPHY_ANAR_ASP) &&
684 (anlpar & BRGPHY_ANLPAR_PC) && (anlpar & BRGPHY_ANLPAR_ASP)) {
685 mii->mii_media_active |= IFM_FLAG1;
686 } else if ((anar & BRGPHY_ANAR_PC) && (anar & BRGPHY_ANAR_ASP) &&
687 !(anlpar & BRGPHY_ANLPAR_PC) && (anlpar & BRGPHY_ANLPAR_ASP)) {
688 mii->mii_media_active |= IFM_FLAG0;
689 }
690 }
691
692 /* Todo: Add support for fiber settings too. */
693
694
695brgphy_status_exit:
696 return;
697}
698
699static void
700brgphy_mii_phy_auto(struct mii_softc *sc)
701{
702 struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
703 int ktcr = 0;
704
705 brgphy_reset(sc);
706
707 /* Enable flow control in the advertisement register. */
708 if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) {
709 /* Pause capability advertisement (pause capable & asymmetric) */
710 PHY_WRITE(sc, BRGPHY_MII_ANAR,
711 BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA |
712 BRGPHY_ANAR_ASP | BRGPHY_ANAR_PC);
713 } else {
714 PHY_WRITE(sc, BRGPHY_SERDES_ANAR, BRGPHY_SERDES_ANAR_FDX |
715 BRGPHY_SERDES_ANAR_HDX | BRGPHY_SERDES_ANAR_BOTH_PAUSE);
716 }
717
718 /* Enable speed in the 1000baseT control register */
719 ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD;
720 if (bsc->mii_model == MII_MODEL_xxBROADCOM_BCM5701)
721 ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC;
722 PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr);
723 ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL);
724
725 /* Start autonegotiation */
726 PHY_WRITE(sc, BRGPHY_MII_BMCR,BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG);
727 PHY_WRITE(sc, BRGPHY_MII_IMR, 0xFF00);
728
729}
730
731
732/* Enable loopback to force the link down. */
733static void
734brgphy_enable_loopback(struct mii_softc *sc)
735{
736 int i;
737
738 PHY_WRITE(sc, BRGPHY_MII_BMCR, BRGPHY_BMCR_LOOP);
739 for (i = 0; i < 15000; i++) {

--- 178 unchanged lines hidden (view full) ---

918 { 0, 0 },
919 };
920 int i;
921
922 for (i = 0; dspcode[i].reg != 0; i++)
923 PHY_WRITE(sc, dspcode[i].reg, dspcode[i].val);
924}
925
926
927static void
928brgphy_fixup_disable_early_dac(struct mii_softc *sc)
929{
930 uint32_t val;
931
932 PHY_WRITE(sc, BRGPHY_MII_DSP_ADDR_REG, 0x0f08);
933 val = PHY_READ(sc, BRGPHY_MII_DSP_RW_PORT);
934 val &= ~(1 << 8);
935 PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT, val);
936
937}
938
939
940static void
941brgphy_ethernet_wirespeed(struct mii_softc *sc)
942{
943 uint32_t val;
944
945 /* Enable Ethernet@WireSpeed. */
946 PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x7007);
947 val = PHY_READ(sc, BRGPHY_MII_AUXCTL);
948 PHY_WRITE(sc, BRGPHY_MII_AUXCTL, val | (1 << 15) | (1 << 4));
949}
950
951
952static void
953brgphy_jumbo_settings(struct mii_softc *sc, u_long mtu)
954{
955 struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
956 uint32_t val;
957
958 /* Set or clear jumbo frame settings in the PHY. */
959 if (mtu > ETHER_MAX_LEN) {

--- 24 unchanged lines hidden (view full) ---

984
985static void
986brgphy_reset(struct mii_softc *sc)
987{
988 struct brgphy_softc *bsc = (struct brgphy_softc *)sc;
989 struct bge_softc *bge_sc = NULL;
990 struct bce_softc *bce_sc = NULL;
991 struct ifnet *ifp;
992 int val;
993
994 /* Perform a standard PHY reset. */
995 mii_phy_reset(sc);
996
997 /* Handle any PHY specific procedures following the reset. */
998 switch (bsc->mii_oui) {
999 case MII_OUI_BROADCOM:
1000 break;

--- 23 unchanged lines hidden (view full) ---

1024
1025 /* Find the driver associated with this PHY. */
1026 if (strcmp(ifp->if_dname, "bge") == 0) {
1027 bge_sc = ifp->if_softc;
1028 } else if (strcmp(ifp->if_dname, "bce") == 0) {
1029 bce_sc = ifp->if_softc;
1030 }
1031
1032 /* Handle any bge (NetXtreme/NetLink) workarounds. */
1033 if (bge_sc) {
1034 /* Fix up various bugs */
1035 if (bge_sc->bge_phy_flags & BGE_PHY_5704_A0_BUG)
1036 brgphy_fixup_5704_a0_bug(sc);
1037 if (bge_sc->bge_phy_flags & BGE_PHY_ADC_BUG)
1038 brgphy_fixup_adc_bug(sc);
1039 if (bge_sc->bge_phy_flags & BGE_PHY_ADJUST_TRIM)
1040 brgphy_fixup_adjust_trim(sc);

--- 14 unchanged lines hidden (view full) ---

1055 PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL,
1056 PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL) &
1057 ~BRGPHY_PHY_EXTCTL_3_LED);
1058 }
1059
1060 /* Adjust output voltage (From Linux driver) */
1061 if (bge_sc->bge_asicrev == BGE_ASICREV_BCM5906)
1062 PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12);
1063
1064 /* Handle any bce (NetXtreme II) workarounds. */
1065 } else if (bce_sc) {
1066
1067 if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5708 &&
1068 (bce_sc->bce_phy_flags & BCE_PHY_SERDES_FLAG)) {
1069
1070 /* Store autoneg capabilities/results in digital block (Page 0) */
1071 PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG3_PG2);
1072 PHY_WRITE(sc, BRGPHY_5708S_PG2_DIGCTL_3_0,
1073 BRGPHY_5708S_PG2_DIGCTL_3_0_USE_IEEE);
1074 PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);

--- 74 unchanged lines hidden (view full) ---

1149 /* Enable MRBE speed autoneg. */
1150 PHY_WRITE(sc, BRGPHY_CL73_USER_B0_MBRE_CTL1,
1151 BRGPHY_CL73_USER_B0_MBRE_CTL1_NP_AFT_BP |
1152 BRGPHY_CL73_USER_B0_MBRE_CTL1_STA_MGR |
1153 BRGPHY_CL73_USER_B0_MBRE_CTL1_ANEG);
1154
1155 /* Restore IEEE0 block (assumed in all brgphy(4) code). */
1156 PHY_WRITE(sc, BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
1157
1158 } else if (BCE_CHIP_NUM(bce_sc) == BCE_CHIP_NUM_5709) {
1159 if ((BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Ax) ||
1160 (BCE_CHIP_REV(bce_sc) == BCE_CHIP_REV_Bx))
1161 brgphy_fixup_disable_early_dac(sc);
1162
1163 brgphy_jumbo_settings(sc, ifp->if_mtu);
1164 brgphy_ethernet_wirespeed(sc);
1165 } else {
1166 brgphy_fixup_ber_bug(sc);
1167 brgphy_jumbo_settings(sc, ifp->if_mtu);
1168 brgphy_ethernet_wirespeed(sc);
1169 }
1170
1171 }
1172}