1 /* $NetBSD: brgphy.c,v 1.50 2009/10/19 18:41:13 bouyer Exp $ */
4 * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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 THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 * driver for the Broadcom BCM5400 Gig-E PHY.
60 * Programming information for this PHY was gleaned from FreeBSD
61 * (they were apparently able to get a datasheet from Broadcom).
64 #include <sys/cdefs.h>
65 __KERNEL_RCSID(0, "$NetBSD: brgphy.c,v 1.50 2009/10/19 18:41:13 bouyer Exp $");
67 #include <sys/param.h>
68 #include <sys/systm.h>
69 #include <sys/kernel.h>
70 #include <sys/device.h>
71 #include <sys/socket.h>
72 #include <sys/errno.h>
73 #include <prop/proplib.h>
76 #include <net/if_media.h>
78 #include <dev/mii/mii.h>
79 #include <dev/mii/miivar.h>
80 #include <dev/mii/miidevs.h>
81 #include <dev/mii/brgphyreg.h>
83 #include <dev/pci/if_bgereg.h>
85 #include <dev/pci/if_bnxreg.h>
88 static int brgphymatch(device_t
, cfdata_t
, void *);
89 static void brgphyattach(device_t
, device_t
, void *);
92 struct mii_softc sc_mii
;
99 CFATTACH_DECL3_NEW(brgphy
, sizeof(struct brgphy_softc
),
100 brgphymatch
, brgphyattach
, mii_phy_detach
, mii_phy_activate
, NULL
, NULL
,
101 DVF_DETACH_SHUTDOWN
);
103 static int brgphy_service(struct mii_softc
*, struct mii_data
*, int);
104 static void brgphy_status(struct mii_softc
*);
105 static int brgphy_mii_phy_auto(struct mii_softc
*);
106 static void brgphy_loop(struct mii_softc
*);
107 static void brgphy_reset(struct mii_softc
*);
108 static void brgphy_bcm5401_dspcode(struct mii_softc
*);
109 static void brgphy_bcm5411_dspcode(struct mii_softc
*);
110 static void brgphy_bcm5421_dspcode(struct mii_softc
*);
111 static void brgphy_bcm54k2_dspcode(struct mii_softc
*);
112 static void brgphy_adc_bug(struct mii_softc
*);
113 static void brgphy_5704_a0_bug(struct mii_softc
*);
114 static void brgphy_ber_bug(struct mii_softc
*);
115 static void brgphy_crc_bug(struct mii_softc
*);
118 static const struct mii_phy_funcs brgphy_funcs
= {
119 brgphy_service
, brgphy_status
, brgphy_reset
,
122 static const struct mii_phydesc brgphys
[] = {
123 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5400
,
124 MII_STR_BROADCOM_BCM5400
},
126 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5401
,
127 MII_STR_BROADCOM_BCM5401
},
129 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5411
,
130 MII_STR_BROADCOM_BCM5411
},
132 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5421
,
133 MII_STR_BROADCOM_BCM5421
},
135 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM54K2
,
136 MII_STR_BROADCOM_BCM54K2
},
138 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5464
,
139 MII_STR_BROADCOM_BCM5464
},
141 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5462
,
142 MII_STR_BROADCOM_BCM5462
},
144 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5701
,
145 MII_STR_BROADCOM_BCM5701
},
147 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5703
,
148 MII_STR_BROADCOM_BCM5703
},
150 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5704
,
151 MII_STR_BROADCOM_BCM5704
},
153 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5705
,
154 MII_STR_BROADCOM_BCM5705
},
156 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5714
,
157 MII_STR_BROADCOM_BCM5714
},
159 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5750
,
160 MII_STR_BROADCOM_BCM5750
},
162 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5752
,
163 MII_STR_BROADCOM_BCM5752
},
165 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5780
,
166 MII_STR_BROADCOM_BCM5780
},
168 { MII_OUI_BROADCOM
, MII_MODEL_BROADCOM_BCM5708C
,
169 MII_STR_BROADCOM_BCM5708C
},
171 { MII_OUI_BROADCOM2
, MII_MODEL_BROADCOM2_BCM5709C
,
172 MII_STR_BROADCOM2_BCM5709C
},
174 { MII_OUI_BROADCOM2
, MII_MODEL_BROADCOM2_BCM5709CAX
,
175 MII_STR_BROADCOM2_BCM5709CAX
},
177 { MII_OUI_BROADCOM2
, MII_MODEL_BROADCOM2_BCM5722
,
178 MII_STR_BROADCOM2_BCM5722
},
180 { MII_OUI_BROADCOM2
, MII_MODEL_BROADCOM2_BCM5755
,
181 MII_STR_BROADCOM2_BCM5755
},
183 { MII_OUI_BROADCOM2
, MII_MODEL_BROADCOM2_BCM5754
,
184 MII_STR_BROADCOM2_BCM5754
},
186 { MII_OUI_xxBROADCOM_ALT1
, MII_MODEL_xxBROADCOM_ALT1_BCM5906
,
187 MII_STR_xxBROADCOM_ALT1_BCM5906
},
194 brgphymatch(device_t parent
, cfdata_t match
, void *aux
)
196 struct mii_attach_args
*ma
= aux
;
198 if (mii_phy_match(ma
, brgphys
) != NULL
)
205 brgphyattach(device_t parent
, device_t self
, void *aux
)
207 struct brgphy_softc
*bsc
= device_private(self
);
208 struct mii_softc
*sc
= &bsc
->sc_mii
;
209 struct mii_attach_args
*ma
= aux
;
210 struct mii_data
*mii
= ma
->mii_data
;
211 const struct mii_phydesc
*mpd
;
212 prop_dictionary_t dict
;
214 mpd
= mii_phy_match(ma
, brgphys
);
215 aprint_naive(": Media interface\n");
216 aprint_normal(": %s, rev. %d\n", mpd
->mpd_name
, MII_REV(ma
->mii_id2
));
219 sc
->mii_inst
= mii
->mii_instance
;
220 sc
->mii_phy
= ma
->mii_phyno
;
221 sc
->mii_mpd_model
= MII_MODEL(ma
->mii_id2
);
222 sc
->mii_mpd_rev
= MII_REV(ma
->mii_id2
);
224 sc
->mii_flags
= ma
->mii_flags
;
225 sc
->mii_anegticks
= MII_ANEGTICKS
;
226 sc
->mii_funcs
= &brgphy_funcs
;
230 sc
->mii_capabilities
=
231 PHY_READ(sc
, MII_BMSR
) & ma
->mii_capmask
;
232 if (sc
->mii_capabilities
& BMSR_EXTSTAT
)
233 sc
->mii_extcapabilities
= PHY_READ(sc
, MII_EXTSR
);
235 aprint_normal_dev(self
, "");
236 if ((sc
->mii_capabilities
& BMSR_MEDIAMASK
) == 0 &&
237 (sc
->mii_extcapabilities
& EXTSR_MEDIAMASK
) == 0)
238 aprint_error("no media present");
240 mii_phy_add_media(sc
);
243 if (device_is_a(parent
, "bge")) {
245 dict
= device_properties(parent
);
246 prop_dictionary_get_uint32(dict
, "phyflags",
248 } else if (device_is_a(parent
, "bnx")) {
250 dict
= device_properties(parent
);
251 prop_dictionary_get_uint32(dict
, "phyflags",
257 brgphy_service(struct mii_softc
*sc
, struct mii_data
*mii
, int cmd
)
259 struct ifmedia_entry
*ife
= mii
->mii_media
.ifm_cur
;
265 * If we're not polling our PHY instance, just return.
267 if (IFM_INST(ife
->ifm_media
) != sc
->mii_inst
)
273 * If the media indicates a different PHY instance,
276 if (IFM_INST(ife
->ifm_media
) != sc
->mii_inst
) {
277 reg
= PHY_READ(sc
, MII_BMCR
);
278 PHY_WRITE(sc
, MII_BMCR
, reg
| BMCR_ISO
);
283 * If the interface is not up, don't do anything.
285 if ((mii
->mii_ifp
->if_flags
& IFF_UP
) == 0)
288 PHY_RESET(sc
); /* XXX hardware bug work-around */
290 switch (IFM_SUBTYPE(ife
->ifm_media
)) {
292 (void) brgphy_mii_phy_auto(sc
);
304 if ((ife
->ifm_media
& IFM_GMASK
) == IFM_FDX
) {
306 gig
= GTCR_ADV_1000TFDX
;
308 gig
= GTCR_ADV_1000THDX
;
311 PHY_WRITE(sc
, MII_100T2CR
, 0);
312 PHY_WRITE(sc
, MII_ANAR
, ANAR_CSMA
);
313 PHY_WRITE(sc
, MII_BMCR
, speed
);
315 if (IFM_SUBTYPE(ife
->ifm_media
) != IFM_1000_T
)
318 PHY_WRITE(sc
, MII_100T2CR
, gig
);
319 PHY_WRITE(sc
, MII_BMCR
,
320 speed
|BMCR_AUTOEN
|BMCR_STARTNEG
);
322 if (sc
->mii_mpd_model
!= MII_MODEL_BROADCOM_BCM5701
)
325 if (mii
->mii_media
.ifm_media
& IFM_ETH_MASTER
)
326 gig
|= GTCR_MAN_MS
| GTCR_ADV_MS
;
327 PHY_WRITE(sc
, MII_100T2CR
, gig
);
336 * If we're not currently selected, just return.
338 if (IFM_INST(ife
->ifm_media
) != sc
->mii_inst
)
341 if (mii_phy_tick(sc
) == EJUSTRETURN
)
350 /* Update the media status. */
354 * Callback if something changed. Note that we need to poke the DSP on
355 * the Broadcom PHYs if the media changes.
357 if (sc
->mii_media_active
!= mii
->mii_media_active
||
358 sc
->mii_media_status
!= mii
->mii_media_status
||
359 cmd
== MII_MEDIACHG
) {
360 switch (sc
->mii_mpd_model
) {
361 case MII_MODEL_BROADCOM_BCM5400
:
362 brgphy_bcm5401_dspcode(sc
);
364 case MII_MODEL_BROADCOM_BCM5401
:
365 if (sc
->mii_mpd_rev
== 1 || sc
->mii_mpd_rev
== 3)
366 brgphy_bcm5401_dspcode(sc
);
368 case MII_MODEL_BROADCOM_BCM5411
:
369 brgphy_bcm5411_dspcode(sc
);
374 /* Callback if something changed. */
375 mii_phy_update(sc
, cmd
);
380 brgphy_status(struct mii_softc
*sc
)
382 struct mii_data
*mii
= sc
->mii_pdata
;
383 struct ifmedia_entry
*ife
= mii
->mii_media
.ifm_cur
;
384 int bmcr
, auxsts
, gtsr
;
386 mii
->mii_media_status
= IFM_AVALID
;
387 mii
->mii_media_active
= IFM_ETHER
;
389 auxsts
= PHY_READ(sc
, BRGPHY_MII_AUXSTS
);
391 if (auxsts
& BRGPHY_AUXSTS_LINK
)
392 mii
->mii_media_status
|= IFM_ACTIVE
;
394 bmcr
= PHY_READ(sc
, MII_BMCR
);
395 if (bmcr
& BMCR_ISO
) {
396 mii
->mii_media_active
|= IFM_NONE
;
397 mii
->mii_media_status
= 0;
401 if (bmcr
& BMCR_LOOP
)
402 mii
->mii_media_active
|= IFM_LOOP
;
404 if (bmcr
& BMCR_AUTOEN
) {
406 * The media status bits are only valid of autonegotiation
407 * has completed (or it's disabled).
409 if ((auxsts
& BRGPHY_AUXSTS_ACOMP
) == 0) {
410 /* Erg, still trying, I guess... */
411 mii
->mii_media_active
|= IFM_NONE
;
415 switch (auxsts
& BRGPHY_AUXSTS_AN_RES
) {
416 case BRGPHY_RES_1000FD
:
417 mii
->mii_media_active
|= IFM_1000_T
|IFM_FDX
;
418 gtsr
= PHY_READ(sc
, MII_100T2SR
);
419 if (gtsr
& GTSR_MS_RES
)
420 mii
->mii_media_active
|= IFM_ETH_MASTER
;
423 case BRGPHY_RES_1000HD
:
424 mii
->mii_media_active
|= IFM_1000_T
;
425 gtsr
= PHY_READ(sc
, MII_100T2SR
);
426 if (gtsr
& GTSR_MS_RES
)
427 mii
->mii_media_active
|= IFM_ETH_MASTER
;
430 case BRGPHY_RES_100FD
:
431 mii
->mii_media_active
|= IFM_100_TX
|IFM_FDX
;
434 case BRGPHY_RES_100T4
:
435 mii
->mii_media_active
|= IFM_100_T4
;
438 case BRGPHY_RES_100HD
:
439 mii
->mii_media_active
|= IFM_100_TX
;
442 case BRGPHY_RES_10FD
:
443 mii
->mii_media_active
|= IFM_10_T
|IFM_FDX
;
446 case BRGPHY_RES_10HD
:
447 mii
->mii_media_active
|= IFM_10_T
;
451 mii
->mii_media_active
|= IFM_NONE
;
452 mii
->mii_media_status
= 0;
454 if (mii
->mii_media_active
& IFM_FDX
)
455 mii
->mii_media_active
|= mii_phy_flowstatus(sc
);
457 mii
->mii_media_active
= ife
->ifm_media
;
461 brgphy_mii_phy_auto(struct mii_softc
*sc
)
467 ktcr
= GTCR_ADV_1000TFDX
|GTCR_ADV_1000THDX
;
468 if (sc
->mii_mpd_model
== MII_MODEL_BROADCOM_BCM5701
)
469 ktcr
|= GTCR_MAN_MS
|GTCR_ADV_MS
;
470 PHY_WRITE(sc
, MII_100T2CR
, ktcr
);
471 ktcr
= PHY_READ(sc
, MII_100T2CR
);
473 anar
= BMSR_MEDIA_TO_ANAR(sc
->mii_capabilities
) | ANAR_CSMA
;
474 if (sc
->mii_flags
& MIIF_DOPAUSE
)
475 anar
|= ANAR_FC
| ANAR_X_PAUSE_ASYM
;
477 PHY_WRITE(sc
, MII_ANAR
, anar
);
479 PHY_WRITE(sc
, MII_BMCR
,
480 BMCR_AUTOEN
| BMCR_STARTNEG
);
481 PHY_WRITE(sc
, BRGPHY_MII_IMR
, 0xFF00);
483 return (EJUSTRETURN
);
487 brgphy_loop(struct mii_softc
*sc
)
492 PHY_WRITE(sc
, MII_BMCR
, BMCR_LOOP
);
493 for (i
= 0; i
< 15000; i
++) {
494 bmsr
= PHY_READ(sc
, MII_BMSR
);
495 if (!(bmsr
& BMSR_LINK
))
502 brgphy_reset(struct mii_softc
*sc
)
504 struct brgphy_softc
*bsc
= (void *)sc
;
508 switch (sc
->mii_mpd_model
) {
509 case MII_MODEL_BROADCOM_BCM5400
:
510 brgphy_bcm5401_dspcode(sc
);
512 case MII_MODEL_BROADCOM_BCM5401
:
513 if (sc
->mii_mpd_rev
== 1 || sc
->mii_mpd_rev
== 3)
514 brgphy_bcm5401_dspcode(sc
);
516 case MII_MODEL_BROADCOM_BCM5411
:
517 brgphy_bcm5411_dspcode(sc
);
519 case MII_MODEL_BROADCOM_BCM5421
:
520 brgphy_bcm5421_dspcode(sc
);
522 case MII_MODEL_BROADCOM_BCM54K2
:
523 brgphy_bcm54k2_dspcode(sc
);
527 /* Handle any bge (NetXtreme/NetLink) workarounds. */
528 if (bsc
->sc_isbge
!= 0) {
529 if (!(sc
->mii_flags
& MIIF_HAVEFIBER
)) {
531 if (bsc
->sc_bge_flags
& BGE_PHY_ADC_BUG
)
533 if (bsc
->sc_bge_flags
& BGE_PHY_5704_A0_BUG
)
534 brgphy_5704_a0_bug(sc
);
535 if (bsc
->sc_bge_flags
& BGE_PHY_BER_BUG
)
537 else if (bsc
->sc_bge_flags
& BGE_PHY_JITTER_BUG
) {
538 PHY_WRITE(sc
, BRGPHY_MII_AUXCTL
, 0x0c00);
539 PHY_WRITE(sc
, BRGPHY_MII_DSP_ADDR_REG
,
542 if (bsc
->sc_bge_flags
& BGE_PHY_ADJUST_TRIM
) {
543 PHY_WRITE(sc
, BRGPHY_MII_DSP_RW_PORT
,
545 PHY_WRITE(sc
, BRGPHY_TEST1
,
546 BRGPHY_TEST1_TRIM_EN
| 0x4);
548 PHY_WRITE(sc
, BRGPHY_MII_DSP_RW_PORT
,
552 PHY_WRITE(sc
, BRGPHY_MII_AUXCTL
, 0x0400);
554 if (bsc
->sc_bge_flags
& BGE_PHY_CRC_BUG
)
558 /* Set Jumbo frame settings in the PHY. */
559 if (bsc
->sc_bge_flags
& BGE_JUMBO_CAP
)
560 brgphy_jumbo_settings(sc
);
563 /* Adjust output voltage */
564 if (sc
->mii_mpd_model
== MII_MODEL_BROADCOM2_BCM5906
)
565 PHY_WRITE(sc
, BRGPHY_MII_EPHY_PTEST
, 0x12);
568 /* Enable Ethernet@Wirespeed */
569 if (!(bsc
->sc_bge_flags
& BGE_NO_ETH_WIRE_SPEED
))
570 brgphy_eth_wirespeed(sc
);
572 /* Enable Link LED on Dell boxes */
573 if (bsc
->sc_bge_flags
& BGE_NO_3LED
) {
574 PHY_WRITE(sc
, BRGPHY_MII_PHY_EXTCTL
,
575 PHY_READ(sc
, BRGPHY_MII_PHY_EXTCTL
)
576 & ~BRGPHY_PHY_EXTCTL_3_LED
);
581 /* Handle any bnx (NetXtreme II) workarounds. */
582 } else if (sc
->sc_isbnx
!= 0) {
583 bnx_sc
= sc
->mii_pdata
->mii_ifp
->if_softc
;
585 if (sc
->mii_mpd_model
== MII_MODEL_xxBROADCOM2_BCM5708S
) {
586 /* Store autoneg capabilities/results in digital block (Page 0) */
587 PHY_WRITE(sc
, BRGPHY_5708S_BLOCK_ADDR
, BRGPHY_5708S_DIG3_PG2
);
588 PHY_WRITE(sc
, BRGPHY_5708S_PG2_DIGCTL_3_0
,
589 BRGPHY_5708S_PG2_DIGCTL_3_0_USE_IEEE
);
590 PHY_WRITE(sc
, BRGPHY_5708S_BLOCK_ADDR
, BRGPHY_5708S_DIG_PG0
);
592 /* Enable fiber mode and autodetection */
593 PHY_WRITE(sc
, BRGPHY_5708S_PG0_1000X_CTL1
,
594 PHY_READ(sc
, BRGPHY_5708S_PG0_1000X_CTL1
) |
595 BRGPHY_5708S_PG0_1000X_CTL1_AUTODET_EN
|
596 BRGPHY_5708S_PG0_1000X_CTL1_FIBER_MODE
);
598 /* Enable parallel detection */
599 PHY_WRITE(sc
, BRGPHY_5708S_PG0_1000X_CTL2
,
600 PHY_READ(sc
, BRGPHY_5708S_PG0_1000X_CTL2
) |
601 BRGPHY_5708S_PG0_1000X_CTL2_PAR_DET_EN
);
603 /* Advertise 2.5G support through next page during autoneg */
604 if (bnx_sc
->bnx_phy_flags
& BNX_PHY_2_5G_CAPABLE_FLAG
)
605 PHY_WRITE(sc
, BRGPHY_5708S_ANEG_NXT_PG_XMIT1
,
606 PHY_READ(sc
, BRGPHY_5708S_ANEG_NXT_PG_XMIT1
) |
607 BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G
);
609 /* Increase TX signal amplitude */
610 if ((BNX_CHIP_ID(bnx_sc
) == BNX_CHIP_ID_5708_A0
) ||
611 (BNX_CHIP_ID(bnx_sc
) == BNX_CHIP_ID_5708_B0
) ||
612 (BNX_CHIP_ID(bnx_sc
) == BNX_CHIP_ID_5708_B1
)) {
613 PHY_WRITE(sc
, BRGPHY_5708S_BLOCK_ADDR
,
614 BRGPHY_5708S_TX_MISC_PG5
);
615 PHY_WRITE(sc
, BRGPHY_5708S_PG5_TXACTL1
,
616 PHY_READ(sc
, BRGPHY_5708S_PG5_TXACTL1
) &
617 ~BRGPHY_5708S_PG5_TXACTL1_VCM
);
618 PHY_WRITE(sc
, BRGPHY_5708S_BLOCK_ADDR
,
619 BRGPHY_5708S_DIG_PG0
);
622 /* Backplanes use special driver/pre-driver/pre-emphasis values. */
623 if ((bnx_sc
->bnx_shared_hw_cfg
& BNX_SHARED_HW_CFG_PHY_BACKPLANE
) &&
624 (bnx_sc
->bnx_port_hw_cfg
& BNX_PORT_HW_CFG_CFG_TXCTL3_MASK
)) {
625 PHY_WRITE(sc
, BRGPHY_5708S_BLOCK_ADDR
,
626 BRGPHY_5708S_TX_MISC_PG5
);
627 PHY_WRITE(sc
, BRGPHY_5708S_PG5_TXACTL3
,
628 bnx_sc
->bnx_port_hw_cfg
&
629 BNX_PORT_HW_CFG_CFG_TXCTL3_MASK
);
630 PHY_WRITE(sc
, BRGPHY_5708S_BLOCK_ADDR
,
631 BRGPHY_5708S_DIG_PG0
);
634 if (!(sc
->mii_flags
& MIIF_HAVEFIBER
)) {
637 /* Set Jumbo frame settings in the PHY. */
638 brgphy_jumbo_settings(sc
);
640 /* Enable Ethernet@Wirespeed */
641 brgphy_eth_wirespeed(sc
);
648 /* Turn off tap power management on 5401. */
650 brgphy_bcm5401_dspcode(struct mii_softc
*sc
)
652 static const struct {
656 { BRGPHY_MII_AUXCTL
, 0x0c20 },
657 { BRGPHY_MII_DSP_ADDR_REG
, 0x0012 },
658 { BRGPHY_MII_DSP_RW_PORT
, 0x1804 },
659 { BRGPHY_MII_DSP_ADDR_REG
, 0x0013 },
660 { BRGPHY_MII_DSP_RW_PORT
, 0x1204 },
661 { BRGPHY_MII_DSP_ADDR_REG
, 0x8006 },
662 { BRGPHY_MII_DSP_RW_PORT
, 0x0132 },
663 { BRGPHY_MII_DSP_ADDR_REG
, 0x8006 },
664 { BRGPHY_MII_DSP_RW_PORT
, 0x0232 },
665 { BRGPHY_MII_DSP_ADDR_REG
, 0x201f },
666 { BRGPHY_MII_DSP_RW_PORT
, 0x0a20 },
671 for (i
= 0; dspcode
[i
].reg
!= 0; i
++)
672 PHY_WRITE(sc
, dspcode
[i
].reg
, dspcode
[i
].val
);
677 brgphy_bcm5411_dspcode(struct mii_softc
*sc
)
679 static const struct {
690 for (i
= 0; dspcode
[i
].reg
!= 0; i
++)
691 PHY_WRITE(sc
, dspcode
[i
].reg
, dspcode
[i
].val
);
695 brgphy_bcm5421_dspcode(struct mii_softc
*sc
)
699 /* Set Class A mode */
700 PHY_WRITE(sc
, BRGPHY_MII_AUXCTL
, 0x1007);
701 data
= PHY_READ(sc
, BRGPHY_MII_AUXCTL
);
702 PHY_WRITE(sc
, BRGPHY_MII_AUXCTL
, data
| 0x0400);
704 /* Set FFE gamma override to -0.125 */
705 PHY_WRITE(sc
, BRGPHY_MII_AUXCTL
, 0x0007);
706 data
= PHY_READ(sc
, BRGPHY_MII_AUXCTL
);
707 PHY_WRITE(sc
, BRGPHY_MII_AUXCTL
, data
| 0x0800);
708 PHY_WRITE(sc
, BRGPHY_MII_DSP_ADDR_REG
, 0x000a);
709 data
= PHY_READ(sc
, BRGPHY_MII_DSP_RW_PORT
);
710 PHY_WRITE(sc
, BRGPHY_MII_DSP_RW_PORT
, data
| 0x0200);
714 brgphy_bcm54k2_dspcode(struct mii_softc
*sc
)
716 static const struct {
726 for (i
= 0; dspcode
[i
].reg
!= 0; i
++)
727 PHY_WRITE(sc
, dspcode
[i
].reg
, dspcode
[i
].val
);
731 brgphy_adc_bug(struct mii_softc
*sc
)
733 static const struct {
737 { BRGPHY_MII_AUXCTL
, 0x0c00 },
738 { BRGPHY_MII_DSP_ADDR_REG
, 0x201f },
739 { BRGPHY_MII_DSP_RW_PORT
, 0x2aaa },
740 { BRGPHY_MII_DSP_ADDR_REG
, 0x000a },
741 { BRGPHY_MII_DSP_RW_PORT
, 0x0323 },
742 { BRGPHY_MII_AUXCTL
, 0x0400 },
747 for (i
= 0; dspcode
[i
].reg
!= 0; i
++)
748 PHY_WRITE(sc
, dspcode
[i
].reg
, dspcode
[i
].val
);
752 brgphy_5704_a0_bug(struct mii_softc
*sc
)
754 static const struct {
764 for (i
= 0; dspcode
[i
].reg
!= 0; i
++)
765 PHY_WRITE(sc
, dspcode
[i
].reg
, dspcode
[i
].val
);
769 brgphy_ber_bug(struct mii_softc
*sc
)
771 static const struct {
775 { BRGPHY_MII_AUXCTL
, 0x0c00 },
776 { BRGPHY_MII_DSP_ADDR_REG
, 0x000a },
777 { BRGPHY_MII_DSP_RW_PORT
, 0x310b },
778 { BRGPHY_MII_DSP_ADDR_REG
, 0x201f },
779 { BRGPHY_MII_DSP_RW_PORT
, 0x9506 },
780 { BRGPHY_MII_DSP_ADDR_REG
, 0x401f },
781 { BRGPHY_MII_DSP_RW_PORT
, 0x14e2 },
782 { BRGPHY_MII_AUXCTL
, 0x0400 },
787 for (i
= 0; dspcode
[i
].reg
!= 0; i
++)
788 PHY_WRITE(sc
, dspcode
[i
].reg
, dspcode
[i
].val
);
791 /* BCM5701 A0/B0 CRC bug workaround */
793 brgphy_crc_bug(struct mii_softc
*sc
)
795 static const struct {
799 { BRGPHY_MII_DSP_ADDR_REG
, 0x0a75 },
807 for (i
= 0; dspcode
[i
].reg
!= 0; i
++)
808 PHY_WRITE(sc
, dspcode
[i
].reg
, dspcode
[i
].val
);