summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2008-06-13 22:23:09 +0000
committerBrad Smith <brad@cvs.openbsd.org>2008-06-13 22:23:09 +0000
commited9c14c6a134bfc6a99942488c7390a573d81a07 (patch)
tree2b54566755c43aefff0b523da142bb5e3bc849be
parent32aa15e1a2824ec1c7a50b7ac042abe8e274a055 (diff)
Add support for fiber PHY on bge(4) (BCM5714/BCM5780) and
bnx(4) (BCM5706/BCM5708) adapters. Thanks to Balázs Nagy <bnagy at thenewpush dot com> for providing remote access to a Inventec IB4220 blade with fiber BCM5780 interfaces and David Christensen at Broadcom for providing BCM5708 2.5Gbps adapters. Tested with various existing copper adapters and the above mentioned adapters. Some inspiration from similar changes to FreeBSD's brgphy(4) driver.
-rw-r--r--sys/dev/mii/brgphy.c375
1 files changed, 296 insertions, 79 deletions
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index cd5be3501c2..b6279316099 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: brgphy.c,v 1.80 2008/06/11 23:53:49 brad Exp $ */
+/* $OpenBSD: brgphy.c,v 1.81 2008/06/13 22:23:08 brad Exp $ */
/*
* Copyright (c) 2000
@@ -63,6 +63,7 @@
#include <dev/mii/brgphyreg.h>
#include <dev/pci/if_bgereg.h>
+#include <dev/pci/if_bnxreg.h>
int brgphy_probe(struct device *, void *, void *);
void brgphy_attach(struct device *, struct device *, void *);
@@ -77,7 +78,9 @@ struct cfdriver brgphy_cd = {
};
int brgphy_service(struct mii_softc *, struct mii_data *, int);
-void brgphy_status(struct mii_softc *);
+void brgphy_copper_status(struct mii_softc *);
+void brgphy_fiber_status(struct mii_softc *);
+void brgphy_5708s_status(struct mii_softc *);
int brgphy_mii_phy_auto(struct mii_softc *);
void brgphy_loop(struct mii_softc *);
void brgphy_reset(struct mii_softc *);
@@ -92,8 +95,16 @@ void brgphy_crc_bug(struct mii_softc *);
void brgphy_jumbo_settings(struct mii_softc *);
void brgphy_eth_wirespeed(struct mii_softc *);
-const struct mii_phy_funcs brgphy_funcs = {
- brgphy_service, brgphy_status, brgphy_reset,
+const struct mii_phy_funcs brgphy_copper_funcs = {
+ brgphy_service, brgphy_copper_status, brgphy_reset,
+};
+
+const struct mii_phy_funcs brgphy_fiber_funcs = {
+ brgphy_service, brgphy_fiber_status, brgphy_reset,
+};
+
+const struct mii_phy_funcs brgphy_5708s_funcs = {
+ brgphy_service, brgphy_5708s_status, brgphy_reset,
};
static const struct mii_phydesc brgphys[] = {
@@ -135,6 +146,8 @@ static const struct mii_phydesc brgphys[] = {
MII_STR_xxBROADCOM_BCM5706 },
{ MII_OUI_xxBROADCOM, MII_MODEL_xxBROADCOM_BCM5708C,
MII_STR_xxBROADCOM_BCM5708C },
+ { MII_OUI_xxBROADCOM2, MII_MODEL_xxBROADCOM2_BCM5708S,
+ MII_STR_xxBROADCOM2_BCM5708S },
{ MII_OUI_BROADCOM2, MII_MODEL_BROADCOM2_BCM5906,
MII_STR_BROADCOM2_BCM5906 },
@@ -157,39 +170,65 @@ void
brgphy_attach(struct device *parent, struct device *self, void *aux)
{
struct mii_softc *sc = (struct mii_softc *)self;
+ struct bnx_softc *bnx_sc = NULL;
struct mii_attach_args *ma = aux;
struct mii_data *mii = ma->mii_data;
const struct mii_phydesc *mpd;
+ char *devname;
+
+ devname = sc->mii_dev.dv_parent->dv_cfdata->cf_driver->cd_name;
mpd = mii_phy_match(ma, brgphys);
printf(": %s, rev. %d\n", mpd->mpd_name, MII_REV(ma->mii_id2));
sc->mii_inst = mii->mii_instance;
sc->mii_phy = ma->mii_phyno;
- sc->mii_funcs = &brgphy_funcs;
sc->mii_model = MII_MODEL(ma->mii_id2);
sc->mii_rev = MII_REV(ma->mii_id2);
sc->mii_pdata = mii;
sc->mii_flags = ma->mii_flags;
+ if (sc->mii_flags & MIIF_HAVEFIBER) {
+ if (MII_OUI(ma->mii_id1, ma->mii_id2) ==
+ MII_OUI_xxBROADCOM &&
+ (sc->mii_model == MII_MODEL_xxBROADCOM_BCM5706 ||
+ sc->mii_model == MII_MODEL_xxBROADCOM_BCM5714 ||
+ sc->mii_model == MII_MODEL_xxBROADCOM_BCM5780))
+ sc->mii_funcs = &brgphy_fiber_funcs;
+ else if (MII_OUI(ma->mii_id1, ma->mii_id2) ==
+ MII_OUI_xxBROADCOM2 && sc->mii_model ==
+ MII_MODEL_xxBROADCOM2_BCM5708S)
+ sc->mii_funcs = &brgphy_5708s_funcs;
+ } else
+ sc->mii_funcs = &brgphy_copper_funcs;
sc->mii_anegticks = MII_ANEGTICKS;
- sc->mii_flags |= MIIF_NOISOLATE;
+ sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
+
+ if (strcmp(devname, "bnx") == 0)
+ bnx_sc = sc->mii_pdata->mii_ifp->if_softc;
PHY_RESET(sc);
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
if (sc->mii_capabilities & BMSR_EXTSTAT)
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
- if ((sc->mii_capabilities & BMSR_MEDIAMASK) ||
- (sc->mii_extcapabilities & EXTSR_MEDIAMASK))
- mii_phy_add_media(sc);
+
+ mii_phy_add_media(sc);
+
+ if (sc->mii_flags & MIIF_HAVEFIBER && bnx_sc &&
+ (bnx_sc->bnx_phy_flags & BNX_PHY_2_5G_CAPABLE_FLAG)) {
+ sc->mii_anegticks = MII_ANEGTICKS_GIGE;
+ ifmedia_add(&mii->mii_media,
+ IFM_MAKEWORD(IFM_ETHER, IFM_2500_SX, IFM_FDX,
+ sc->mii_inst), 0, NULL);
+ }
}
int
brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
- int reg, speed, gig;
+ int reg, speed = 0, gig;
if ((sc->mii_dev.dv_flags & DVF_ACTIVE) == 0)
return (ENXIO);
@@ -226,6 +265,9 @@ brgphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
case IFM_AUTO:
(void) brgphy_mii_phy_auto(sc);
break;
+ case IFM_2500_SX:
+ speed = BRGPHY_5708S_BMCR_2500;
+ goto setit;
case IFM_1000_T:
speed = BRGPHY_S1000;
goto setit;
@@ -247,7 +289,9 @@ setit:
PHY_WRITE(sc, BRGPHY_MII_BMCR, speed);
PHY_WRITE(sc, BRGPHY_MII_ANAR, BRGPHY_SEL_TYPE);
- if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T)
+ if ((IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) &&
+ (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_SX) &&
+ (IFM_SUBTYPE(ife->ifm_media) != IFM_2500_SX))
break;
PHY_WRITE(sc, BRGPHY_MII_1000CTL, gig);
@@ -290,8 +334,8 @@ setit:
* need to restart the autonegotiation process. Read
* the BMSR twice in case it's latched.
*/
- reg = PHY_READ(sc, BRGPHY_MII_AUXSTS);
- if (reg & BRGPHY_AUXSTS_LINK)
+ reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
+ if (reg & BMSR_LINK)
break;
/*
@@ -336,19 +380,16 @@ setit:
}
void
-brgphy_status(struct mii_softc *sc)
+brgphy_copper_status(struct mii_softc *sc)
{
struct mii_data *mii = sc->mii_pdata;
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
- int bmsr, bmcr, gsr;
+ int bmcr, bmsr;
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
- bmsr = PHY_READ(sc, BRGPHY_MII_BMSR);
- if (PHY_READ(sc, BRGPHY_MII_AUXSTS) & BRGPHY_AUXSTS_LINK)
- mii->mii_media_status |= IFM_ACTIVE;
-
+ bmsr = PHY_READ(sc, BRGPHY_MII_BMSR) | PHY_READ(sc, BRGPHY_MII_BMSR);
bmcr = PHY_READ(sc, BRGPHY_MII_BMCR);
if (bmcr & BRGPHY_BMCR_LOOP)
@@ -360,6 +401,12 @@ brgphy_status(struct mii_softc *sc)
mii->mii_media_active |= IFM_NONE;
return;
}
+ }
+
+ if (bmsr & BRGPHY_BMSR_LINK) {
+ int gsr;
+
+ mii->mii_media_status |= IFM_ACTIVE;
switch (PHY_READ(sc, BRGPHY_MII_AUXSTS) &
BRGPHY_AUXSTS_AN_RES) {
@@ -386,7 +433,7 @@ brgphy_status(struct mii_softc *sc)
break;
default:
mii->mii_media_active |= IFM_NONE;
- break;
+ return;
}
if (mii->mii_media_active & IFM_FDX)
@@ -396,34 +443,146 @@ brgphy_status(struct mii_softc *sc)
if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) &&
gsr & BRGPHY_1000STS_MSR)
mii->mii_media_active |= IFM_ETH_MASTER;
+ } else
+ mii->mii_media_active = ife->ifm_media;
+}
- return;
+void
+brgphy_fiber_status(struct mii_softc *sc)
+{
+ struct mii_data *mii = sc->mii_pdata;
+ struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
+ int bmcr, bmsr;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = PHY_READ(sc, BRGPHY_MII_BMSR) | PHY_READ(sc, BRGPHY_MII_BMSR);
+ bmcr = PHY_READ(sc, BRGPHY_MII_BMCR);
+
+ if (bmcr & BRGPHY_BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if (bmcr & BRGPHY_BMCR_AUTOEN) {
+ if ((bmsr & BRGPHY_BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
}
- mii->mii_media_active = ife->ifm_media;
+ if (bmsr & BRGPHY_BMSR_LINK) {
+ mii->mii_media_status |= IFM_ACTIVE;
+ mii->mii_media_active |= IFM_1000_SX;
+
+ /*
+ * If autoneg enabled, read negotiated
+ * duplex settings
+ */
+ if (bmcr & BRGPHY_BMCR_AUTOEN) {
+ int val;
+
+ val = PHY_READ(sc, BRGPHY_SERDES_ANAR) &
+ PHY_READ(sc, BRGPHY_SERDES_ANLPAR);
+
+ if (val & BRGPHY_SERDES_ANAR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
+
+ if (mii->mii_media_active & IFM_FDX)
+ mii->mii_media_active |=
+ mii_phy_flowstatus(sc);
+ }
+ mii->mii_media_active |= IFM_FDX;
+ } else
+ mii->mii_media_active = ife->ifm_media;
}
+void
+brgphy_5708s_status(struct mii_softc *sc)
+{
+ struct mii_data *mii = sc->mii_pdata;
+ struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
+ int bmcr, bmsr;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = PHY_READ(sc, BRGPHY_MII_BMSR) | PHY_READ(sc, BRGPHY_MII_BMSR);
+ bmcr = PHY_READ(sc, BRGPHY_MII_BMCR);
+
+ if (bmcr & BRGPHY_BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if (bmcr & BRGPHY_BMCR_AUTOEN) {
+ if ((bmsr & BRGPHY_BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+ }
+
+ if (bmsr & BRGPHY_BMSR_LINK) {
+ int xstat;
+
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
+ BRGPHY_5708S_DIG_PG0);
+
+ xstat = PHY_READ(sc, BRGPHY_5708S_PG0_1000X_STAT1);
+
+ /* Todo: Create #defines for hard coded values */
+ switch (xstat & BRGPHY_5708S_PG0_1000X_STAT1_SPEED_MASK) {
+ case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_10:
+ mii->mii_media_active |= IFM_10_FL;
+ break;
+ case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_100:
+ mii->mii_media_active |= IFM_100_FX;
+ break;
+ case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_1G:
+ mii->mii_media_active |= IFM_1000_SX;
+ break;
+ case BRGPHY_5708S_PG0_1000X_STAT1_SPEED_25G:
+ mii->mii_media_active |= IFM_2500_SX;
+ break;
+ }
+
+ if (xstat & BRGPHY_5708S_PG0_1000X_STAT1_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
+ } else
+ mii->mii_media_active = ife->ifm_media;
+}
int
brgphy_mii_phy_auto(struct mii_softc *sc)
{
int anar, ktcr = 0;
- brgphy_loop(sc);
PHY_RESET(sc);
+
+ if (sc->mii_flags & MIIF_HAVEFIBER) {
+ anar = BRGPHY_SERDES_ANAR_FDX | BRGPHY_SERDES_ANAR_HDX;
+ if (sc->mii_flags & MIIF_DOPAUSE)
+ anar |= BRGPHY_SERDES_ANAR_BOTH_PAUSE;
+ PHY_WRITE(sc, BRGPHY_SERDES_ANAR, anar);
+ } else {
+ anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
+ if (sc->mii_flags & MIIF_DOPAUSE)
+ anar |= BRGPHY_ANAR_ASP | BRGPHY_ANAR_PC;
+ PHY_WRITE(sc, BRGPHY_MII_ANAR, anar);
+ }
+
/* Enable speed in the 1000baseT control register */
- ktcr = BRGPHY_1000CTL_AFD|BRGPHY_1000CTL_AHD;
+ ktcr = BRGPHY_1000CTL_AFD | BRGPHY_1000CTL_AHD;
if (sc->mii_model == MII_MODEL_xxBROADCOM_BCM5701)
- ktcr |= BRGPHY_1000CTL_MSE|BRGPHY_1000CTL_MSC;
+ ktcr |= BRGPHY_1000CTL_MSE | BRGPHY_1000CTL_MSC;
PHY_WRITE(sc, BRGPHY_MII_1000CTL, ktcr);
ktcr = PHY_READ(sc, BRGPHY_MII_1000CTL);
- DELAY(1000);
- anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
- if (sc->mii_flags & MIIF_DOPAUSE)
- anar |= BRGPHY_ANAR_PC | BRGPHY_ANAR_ASP;
- PHY_WRITE(sc, BRGPHY_MII_ANAR, anar);
- DELAY(1000);
/* Start autonegotiation */
PHY_WRITE(sc, BRGPHY_MII_BMCR,
BRGPHY_BMCR_AUTOEN | BRGPHY_BMCR_STARTNEG);
@@ -452,6 +611,7 @@ void
brgphy_reset(struct mii_softc *sc)
{
struct bge_softc *bge_sc = NULL;
+ struct bnx_softc *bnx_sc = NULL;
char *devname;
devname = sc->mii_dev.dv_parent->dv_cfdata->cf_driver->cd_name;
@@ -479,60 +639,117 @@ brgphy_reset(struct mii_softc *sc)
/* Handle any bge (NetXtreme/NetLink) workarounds. */
if (strcmp(devname, "bge") == 0) {
- bge_sc = sc->mii_pdata->mii_ifp->if_softc;
-
- if (bge_sc->bge_flags & BGE_PHY_ADC_BUG)
- brgphy_adc_bug(sc);
- if (bge_sc->bge_flags & BGE_PHY_5704_A0_BUG)
- brgphy_5704_a0_bug(sc);
- if (bge_sc->bge_flags & BGE_PHY_BER_BUG)
- brgphy_ber_bug(sc);
- else if (bge_sc->bge_flags & BGE_PHY_JITTER_BUG) {
- PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x0c00);
- PHY_WRITE(sc, BRGPHY_MII_DSP_ADDR_REG, 0x000a);
-
- if (bge_sc->bge_flags & BGE_PHY_ADJUST_TRIM) {
- PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT,
- 0x110b);
- PHY_WRITE(sc, BRGPHY_TEST1,
- BRGPHY_TEST1_TRIM_EN | 0x4);
- } else {
- PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT,
- 0x010b);
+ if (!(sc->mii_flags & MIIF_HAVEFIBER)) {
+ bge_sc = sc->mii_pdata->mii_ifp->if_softc;
+
+ if (bge_sc->bge_flags & BGE_PHY_ADC_BUG)
+ brgphy_adc_bug(sc);
+ if (bge_sc->bge_flags & BGE_PHY_5704_A0_BUG)
+ brgphy_5704_a0_bug(sc);
+ if (bge_sc->bge_flags & BGE_PHY_BER_BUG)
+ brgphy_ber_bug(sc);
+ else if (bge_sc->bge_flags & BGE_PHY_JITTER_BUG) {
+ PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x0c00);
+ PHY_WRITE(sc, BRGPHY_MII_DSP_ADDR_REG,
+ 0x000a);
+
+ if (bge_sc->bge_flags & BGE_PHY_ADJUST_TRIM) {
+ PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT,
+ 0x110b);
+ PHY_WRITE(sc, BRGPHY_TEST1,
+ BRGPHY_TEST1_TRIM_EN | 0x4);
+ } else {
+ PHY_WRITE(sc, BRGPHY_MII_DSP_RW_PORT,
+ 0x010b);
+ }
+
+ PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x0400);
+ }
+ if (bge_sc->bge_flags & BGE_PHY_CRC_BUG)
+ brgphy_crc_bug(sc);
+
+ /* Set Jumbo frame settings in the PHY. */
+ if (bge_sc->bge_flags & BGE_JUMBO_CAP)
+ brgphy_jumbo_settings(sc);
+
+ /* Adjust output voltage */
+ if (sc->mii_model == MII_MODEL_BROADCOM2_BCM5906)
+ PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12);
+
+ /* Enable Ethernet@Wirespeed */
+ if (!(bge_sc->bge_flags & BGE_NO_ETH_WIRE_SPEED))
+ brgphy_eth_wirespeed(sc);
+
+ /* Enable Link LED on Dell boxes */
+ if (bge_sc->bge_flags & BGE_NO_3LED) {
+ PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL,
+ PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL)
+ & ~BRGPHY_PHY_EXTCTL_3_LED);
}
-
- PHY_WRITE(sc, BRGPHY_MII_AUXCTL, 0x0400);
- }
- if (bge_sc->bge_flags & BGE_PHY_CRC_BUG)
- brgphy_crc_bug(sc);
-
- /* Set Jumbo frame settings in the PHY. */
- if (bge_sc->bge_flags & BGE_JUMBO_CAP)
- brgphy_jumbo_settings(sc);
-
- /* Adjust output voltage */
- if (sc->mii_model == MII_MODEL_BROADCOM2_BCM5906)
- PHY_WRITE(sc, BRGPHY_MII_EPHY_PTEST, 0x12);
-
- /* Enable Ethernet@Wirespeed */
- if (!(bge_sc->bge_flags & BGE_NO_ETH_WIRE_SPEED))
- brgphy_eth_wirespeed(sc);
-
- /* Enable Link LED on Dell boxes */
- if (bge_sc->bge_flags & BGE_NO_3LED) {
- PHY_WRITE(sc, BRGPHY_MII_PHY_EXTCTL,
- PHY_READ(sc, BRGPHY_MII_PHY_EXTCTL)
- & ~BRGPHY_PHY_EXTCTL_3_LED);
}
/* Handle any bnx (NetXtreme II) workarounds. */
} else if (strcmp(devname, "bnx") == 0) {
- brgphy_ber_bug(sc);
+ bnx_sc = sc->mii_pdata->mii_ifp->if_softc;
+
+ if (sc->mii_model == MII_MODEL_xxBROADCOM2_BCM5708S) {
+ /* Store autoneg capabilities/results in digital block (Page 0) */
+ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG3_PG2);
+ PHY_WRITE(sc, BRGPHY_5708S_PG2_DIGCTL_3_0,
+ BRGPHY_5708S_PG2_DIGCTL_3_0_USE_IEEE);
+ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR, BRGPHY_5708S_DIG_PG0);
+
+ /* Enable fiber mode and autodetection */
+ PHY_WRITE(sc, BRGPHY_5708S_PG0_1000X_CTL1,
+ PHY_READ(sc, BRGPHY_5708S_PG0_1000X_CTL1) |
+ BRGPHY_5708S_PG0_1000X_CTL1_AUTODET_EN |
+ BRGPHY_5708S_PG0_1000X_CTL1_FIBER_MODE);
+
+ /* Enable parallel detection */
+ PHY_WRITE(sc, BRGPHY_5708S_PG0_1000X_CTL2,
+ PHY_READ(sc, BRGPHY_5708S_PG0_1000X_CTL2) |
+ BRGPHY_5708S_PG0_1000X_CTL2_PAR_DET_EN);
+
+ /* Advertise 2.5G support through next page during autoneg */
+ if (bnx_sc->bnx_phy_flags & BNX_PHY_2_5G_CAPABLE_FLAG)
+ PHY_WRITE(sc, BRGPHY_5708S_ANEG_NXT_PG_XMIT1,
+ PHY_READ(sc, BRGPHY_5708S_ANEG_NXT_PG_XMIT1) |
+ BRGPHY_5708S_ANEG_NXT_PG_XMIT1_25G);
+
+ /* Increase TX signal amplitude */
+ if ((BNX_CHIP_ID(bnx_sc) == BNX_CHIP_ID_5708_A0) ||
+ (BNX_CHIP_ID(bnx_sc) == BNX_CHIP_ID_5708_B0) ||
+ (BNX_CHIP_ID(bnx_sc) == BNX_CHIP_ID_5708_B1)) {
+ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
+ BRGPHY_5708S_TX_MISC_PG5);
+ PHY_WRITE(sc, BRGPHY_5708S_PG5_TXACTL1,
+ PHY_READ(sc, BRGPHY_5708S_PG5_TXACTL1) &
+ ~BRGPHY_5708S_PG5_TXACTL1_VCM);
+ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
+ BRGPHY_5708S_DIG_PG0);
+ }
+
+ /* Backplanes use special driver/pre-driver/pre-emphasis values. */
+ if ((bnx_sc->bnx_shared_hw_cfg & BNX_SHARED_HW_CFG_PHY_BACKPLANE) &&
+ (bnx_sc->bnx_port_hw_cfg & BNX_PORT_HW_CFG_CFG_TXCTL3_MASK)) {
+ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
+ BRGPHY_5708S_TX_MISC_PG5);
+ PHY_WRITE(sc, BRGPHY_5708S_PG5_TXACTL3,
+ bnx_sc->bnx_port_hw_cfg &
+ BNX_PORT_HW_CFG_CFG_TXCTL3_MASK);
+ PHY_WRITE(sc, BRGPHY_5708S_BLOCK_ADDR,
+ BRGPHY_5708S_DIG_PG0);
+ }
+ } else {
+ if (!(sc->mii_flags & MIIF_HAVEFIBER)) {
+ brgphy_ber_bug(sc);
- /* Set Jumbo frame settings in the PHY. */
- brgphy_jumbo_settings(sc);
+ /* Set Jumbo frame settings in the PHY. */
+ brgphy_jumbo_settings(sc);
- /* Enable Ethernet@Wirespeed */
- brgphy_eth_wirespeed(sc);
+ /* Enable Ethernet@Wirespeed */
+ brgphy_eth_wirespeed(sc);
+ }
+ }
}
}