summaryrefslogtreecommitdiffstats
path: root/sys/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/pci')
-rw-r--r--sys/pci/if_vr.c89
-rw-r--r--sys/pci/if_vrreg.h4
2 files changed, 93 insertions, 0 deletions
diff --git a/sys/pci/if_vr.c b/sys/pci/if_vr.c
index 138cba3..36ee680 100644
--- a/sys/pci/if_vr.c
+++ b/sys/pci/if_vr.c
@@ -104,6 +104,8 @@ static const char rcsid[] =
"$FreeBSD$";
#endif
+#undef VR_USESWSHIFT
+
/*
* Various supported device vendors/types and their names.
*/
@@ -146,8 +148,10 @@ static void vr_shutdown (device_t);
static int vr_ifmedia_upd (struct ifnet *);
static void vr_ifmedia_sts (struct ifnet *, struct ifmediareq *);
+#ifdef VR_USESWSHIFT
static void vr_mii_sync (struct vr_softc *);
static void vr_mii_send (struct vr_softc *, u_int32_t, int);
+#endif
static int vr_mii_readreg (struct vr_softc *, struct vr_mii_frame *);
static int vr_mii_writereg (struct vr_softc *, struct vr_mii_frame *);
static int vr_miibus_readreg (device_t, int, int);
@@ -231,6 +235,7 @@ DRIVER_MODULE(miibus, vr, miibus_driver, miibus_devclass, 0, 0);
CSR_WRITE_1(sc, VR_MIICMD, \
CSR_READ_1(sc, VR_MIICMD) & ~(x))
+#ifdef VR_USESWSHIFT
/*
* Sync the PHYs by setting data bit and strobing the clock 32 times.
*/
@@ -277,6 +282,7 @@ vr_mii_send(sc, bits, cnt)
SIO_SET(VR_MIICMD_CLK);
}
}
+#endif
/*
* Read an PHY register through the MII.
@@ -286,6 +292,7 @@ vr_mii_readreg(sc, frame)
struct vr_softc *sc;
struct vr_mii_frame *frame;
+#ifdef VR_USESWSHIFT
{
int i, ack;
@@ -372,6 +379,34 @@ fail:
return(1);
return(0);
}
+#else
+{
+ int s, i;
+
+ s = splimp();
+
+ /* Set the PHY-adress */
+ CSR_WRITE_1(sc, VR_PHYADDR, (CSR_READ_1(sc, VR_PHYADDR)& 0xe0)|
+ frame->mii_phyaddr);
+
+ /* Set the register-adress */
+ CSR_WRITE_1(sc, VR_MIIADDR, frame->mii_regaddr);
+ VR_SETBIT(sc, VR_MIICMD, VR_MIICMD_READ_ENB);
+
+ for (i = 0; i < 10000; i++) {
+ if ((CSR_READ_1(sc, VR_MIICMD) & VR_MIICMD_READ_ENB) == 0)
+ break;
+ DELAY(1);
+ }
+
+ frame->mii_data = CSR_READ_2(sc, VR_MIIDATA);
+
+ (void)splx(s);
+
+ return(0);
+}
+#endif
+
/*
* Write to a PHY register through the MII.
@@ -381,6 +416,7 @@ vr_mii_writereg(sc, frame)
struct vr_softc *sc;
struct vr_mii_frame *frame;
+#ifdef VR_USESWSHIFT
{
VR_LOCK(sc);
@@ -424,6 +460,33 @@ vr_mii_writereg(sc, frame)
return(0);
}
+#else
+{
+ int s, i;
+
+ s = splimp();
+
+ /* Set the PHY-adress */
+ CSR_WRITE_1(sc, VR_PHYADDR, (CSR_READ_1(sc, VR_PHYADDR)& 0xe0)|
+ frame->mii_phyaddr);
+
+ /* Set the register-adress and data to write */
+ CSR_WRITE_1(sc, VR_MIIADDR, frame->mii_regaddr);
+ CSR_WRITE_2(sc, VR_MIIDATA, frame->mii_data);
+
+ VR_SETBIT(sc, VR_MIICMD, VR_MIICMD_WRITE_ENB);
+
+ for (i = 0; i < 10000; i++) {
+ if ((CSR_READ_1(sc, VR_MIICMD) & VR_MIICMD_WRITE_ENB) == 0)
+ break;
+ DELAY(1);
+ }
+
+ (void)splx(s);
+
+ return(0);
+}
+#endif
static int
vr_miibus_readreg(dev, phy, reg)
@@ -434,6 +497,15 @@ vr_miibus_readreg(dev, phy, reg)
struct vr_mii_frame frame;
sc = device_get_softc(dev);
+
+ switch (sc->vr_revid) {
+ case REV_ID_VT6102_APOLLO:
+ if (phy != 1)
+ return 0;
+ default:
+ break;
+ }
+
bzero((char *)&frame, sizeof(frame));
frame.mii_phyaddr = phy;
@@ -452,6 +524,15 @@ vr_miibus_writereg(dev, phy, reg, data)
struct vr_mii_frame frame;
sc = device_get_softc(dev);
+
+ switch (sc->vr_revid) {
+ case REV_ID_VT6102_APOLLO:
+ if (phy != 1)
+ return 0;
+ default:
+ break;
+ }
+
bzero((char *)&frame, sizeof(frame));
frame.mii_phyaddr = phy;
@@ -755,6 +836,14 @@ vr_attach(dev)
/* Reset the adapter. */
vr_reset(sc);
+ /*
+ * Turn on bit2 (MIION) in PCI configuration register 0x53 during
+ * initialization and disable AUTOPOLL.
+ */
+ pci_write_config(dev, VR_PCI_MODE,
+ pci_read_config(dev, VR_PCI_MODE, 4) | (VR_MODE3_MIION << 24), 4);
+ VR_CLRBIT(sc, VR_MIICMD, VR_MIICMD_AUTOPOLL);
+
/*
* Get station address. The way the Rhine chips work,
* you're not allowed to directly access the EEPROM once
diff --git a/sys/pci/if_vrreg.h b/sys/pci/if_vrreg.h
index b7903c1..8129a24 100644
--- a/sys/pci/if_vrreg.h
+++ b/sys/pci/if_vrreg.h
@@ -540,6 +540,7 @@ struct vr_softc {
#define REV_ID_VT3065_A 0x40
#define REV_ID_VT3065_B 0x41
#define REV_ID_VT3065_C 0x42
+#define REV_ID_VT6102_APOLLO 0x74
#define REV_ID_VT3106 0x80
#define REV_ID_VT3106_J 0x80 /* 0x80-0x8F */
#define REV_ID_VT3106_S 0x90 /* 0x90-0xA0 */
@@ -566,6 +567,9 @@ struct vr_softc {
#define VR_PCI_MINLAT 0x0F
#define VR_PCI_RESETOPT 0x48
#define VR_PCI_EEPROM_DATA 0x4C
+#define VR_PCI_MODE 0x50
+
+#define VR_MODE3_MIION 0x04
/* power management registers */
#define VR_PCI_CAPID 0xDC /* 8 bits */
OpenPOWER on IntegriCloud