summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2005-03-17 14:21:51 +0000
committerbz <bz@FreeBSD.org>2005-03-17 14:21:51 +0000
commit342779d193ab2d98d6916c776a3aca44abe8a080 (patch)
tree5bb7de907c1ce2dc1c221b97008cefd9628f1309 /sys
parent4a845497316284fc31758c4452909e29eacda21a (diff)
downloadFreeBSD-src-342779d193ab2d98d6916c776a3aca44abe8a080.zip
FreeBSD-src-342779d193ab2d98d6916c776a3aca44abe8a080.tar.gz
* Improve chip identification.
Obtained from: NetBSD if_sk.c rev. 1.11 * Take PHY out of reset for Yukon Lite Rev. A3. Submitted by: postings on net@ in thread "skc0: no PHY found", 2005-02-22 Tested by: net Approved by: rwatson (mentor) MFC after: 5 days
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sk/if_sk.c158
-rw-r--r--sys/dev/sk/if_skreg.h16
-rw-r--r--sys/pci/if_sk.c158
-rw-r--r--sys/pci/if_skreg.h16
4 files changed, 284 insertions, 64 deletions
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index d6e1cf3..39c0f8a 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -526,6 +526,8 @@ sk_miibus_readreg(dev, phy, reg)
case SK_GENESIS:
return(sk_xmac_miibus_readreg(sc_if, phy, reg));
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
return(sk_marv_miibus_readreg(sc_if, phy, reg));
}
@@ -545,6 +547,8 @@ sk_miibus_writereg(dev, phy, reg, val)
case SK_GENESIS:
return(sk_xmac_miibus_writereg(sc_if, phy, reg, val));
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
return(sk_marv_miibus_writereg(sc_if, phy, reg, val));
}
@@ -564,6 +568,8 @@ sk_miibus_statchg(dev)
sk_xmac_miibus_statchg(sc_if);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sk_marv_miibus_statchg(sc_if);
break;
}
@@ -796,6 +802,8 @@ sk_setmulti(sc_if)
SK_XM_WRITE_4(sc_if, XM_MAR2, 0);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
@@ -830,6 +838,8 @@ sk_setmulti(sc_if)
LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
h = sk_gmchash(
LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
break;
@@ -849,6 +859,8 @@ sk_setmulti(sc_if)
SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
@@ -875,6 +887,8 @@ sk_setpromisc(sc_if)
}
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
if (ifp->if_flags & IFF_PROMISC) {
SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
YU_RCR_UFLEN | YU_RCR_MUFLEN);
@@ -1263,14 +1277,14 @@ sk_reset(sc)
{
CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET);
CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET);
- if (sc->sk_type == SK_YUKON)
+ if (SK_YUKON_FAMILY(sc->sk_type))
CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
DELAY(1000);
CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET);
DELAY(2);
CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
- if (sc->sk_type == SK_YUKON)
+ if (SK_YUKON_FAMILY(sc->sk_type))
CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
if (sc->sk_type == SK_GENESIS) {
@@ -1320,6 +1334,8 @@ sk_probe(dev)
device_set_desc(dev, "XaQti Corp. XMAC II");
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
device_set_desc(dev, "Marvell Semiconductor, Inc. Yukon");
break;
}
@@ -1479,6 +1495,8 @@ sk_attach(dev)
sk_init_xmac(sc_if);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sk_init_yukon(sc_if);
break;
}
@@ -1513,6 +1531,7 @@ skc_attach(dev)
struct sk_softc *sc;
int unit, error = 0, rid, *port;
uint8_t skrs;
+ char *pname, *revstr;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
@@ -1536,6 +1555,17 @@ skc_attach(dev)
sc->sk_btag = rman_get_bustag(sc->sk_res);
sc->sk_bhandle = rman_get_bushandle(sc->sk_res);
+ sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
+ sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4) & 0xf;
+
+ /* Bail out if chip is not recognized. */
+ if (sc->sk_type != SK_GENESIS && !SK_YUKON_FAMILY(sc->sk_type)) {
+ printf("skc%d: unknown device: chipver=%02x, rev=%x\n",
+ unit, sc->sk_type, sc->sk_rev);
+ error = ENXIO;
+ goto fail;
+ }
+
/* Allocate interrupt */
rid = 0;
sc->sk_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
@@ -1547,24 +1577,6 @@ skc_attach(dev)
goto fail;
}
- /* Set adapter type */
- switch (pci_get_device(dev)) {
- case DEVICEID_SK_V1:
- sc->sk_type = SK_GENESIS;
- break;
- case DEVICEID_SK_V2:
- case DEVICEID_BELKIN_5005:
- case DEVICEID_3COM_3C940:
- case DEVICEID_LINKSYS_EG1032:
- case DEVICEID_DLINK_DGE530T:
- sc->sk_type = SK_YUKON;
- break;
- default:
- printf("skc%d: unknown device!\n", unit);
- error = ENXIO;
- goto fail;
- }
-
/* Reset the adapter. */
sk_reset(sc);
@@ -1599,7 +1611,7 @@ skc_attach(dev)
error = ENXIO;
goto fail;
}
- } else { /* SK_YUKON */
+ } else { /* SK_YUKON_FAMILY */
if (skrs == 0x00)
sc->sk_ramsize = 0x20000;
else
@@ -1628,9 +1640,88 @@ skc_attach(dev)
goto fail;
}
+ /* Determine whether to name it with VPD PN or just make it up.
+ * Marvell Yukon VPD PN seems to freqently be bogus. */
+ switch (pci_get_device(dev)) {
+ case DEVICEID_SK_V1:
+ case DEVICEID_BELKIN_5005:
+ case DEVICEID_3COM_3C940:
+ case DEVICEID_LINKSYS_EG1032:
+ case DEVICEID_DLINK_DGE530T:
+ /* Stay with VPD PN. */
+ pname = sc->sk_vpd_prodname;
+ break;
+ case DEVICEID_SK_V2:
+ /* YUKON VPD PN might bear no resemblance to reality. */
+ switch (sc->sk_type) {
+ case SK_GENESIS:
+ /* Stay with VPD PN. */
+ pname = sc->sk_vpd_prodname;
+ break;
+ case SK_YUKON:
+ pname = "Marvell Yukon Gigabit Ethernet";
+ break;
+ case SK_YUKON_LITE:
+ pname = "Marvell Yukon Lite Gigabit Ethernet";
+ break;
+ case SK_YUKON_LP:
+ pname = "Marvell Yukon LP Gigabit Ethernet";
+ break;
+ default:
+ pname = "Marvell Yukon (Unknown) Gigabit Ethernet";
+ break;
+ }
+
+ /* Yukon Lite Rev. A0 needs special test. */
+ if (sc->sk_type == SK_YUKON || sc->sk_type == SK_YUKON_LP) {
+ u_int32_t far;
+ u_int8_t testbyte;
+
+ /* Save flash address register before testing. */
+ far = sk_win_read_4(sc, SK_EP_ADDR);
+
+ sk_win_write_1(sc, SK_EP_ADDR+0x03, 0xff);
+ testbyte = sk_win_read_1(sc, SK_EP_ADDR+0x03);
+
+ if (testbyte != 0x00) {
+ /* Yukon Lite Rev. A0 detected. */
+ sc->sk_type = SK_YUKON_LITE;
+ sc->sk_rev = SK_YUKON_LITE_REV_A0;
+ /* Restore flash address register. */
+ sk_win_write_4(sc, SK_EP_ADDR, far);
+ }
+ }
+ break;
+ default:
+ device_printf(dev, "unknown device: vendor=%04x, device=%04x, "
+ "chipver=%02x, rev=%x\n",
+ pci_get_vendor(dev), pci_get_device(dev),
+ sc->sk_type, sc->sk_rev);
+ error = ENXIO;
+ goto fail;
+ }
+
+ if (sc->sk_type == SK_YUKON_LITE) {
+ switch (sc->sk_rev) {
+ case SK_YUKON_LITE_REV_A0:
+ revstr = "A0";
+ break;
+ case SK_YUKON_LITE_REV_A1:
+ revstr = "A1";
+ break;
+ case SK_YUKON_LITE_REV_A3:
+ revstr = "A3";
+ break;
+ default:
+ revstr = "";
+ break;
+ }
+ } else {
+ revstr = "";
+ }
+
/* Announce the product name and more VPD data if there. */
- if (sc->sk_vpd_prodname != NULL)
- printf("skc%d: %s\n", sc->sk_unit, sc->sk_vpd_prodname);
+ device_printf(dev, "%s rev. %s(0x%x)\n", pname, revstr, sc->sk_rev);
if (bootverbose) {
if (sc->sk_vpd_readonly != NULL &&
@@ -1660,14 +1751,10 @@ skc_attach(dev)
}
}
}
- device_printf(dev, "type = %s\n",
- (sc->sk_type == SK_GENESIS) ? "GENESIS" : "YUKON");
+ device_printf(dev, "chip ver = 0x%02x\n", sc->sk_type);
+ device_printf(dev, "chip rev = 0x%02x\n", sc->sk_rev);
device_printf(dev, "SK_EPROM0 = 0x%02x\n", skrs);
device_printf(dev, "SRAM size = 0x%06x\n", sc->sk_ramsize);
- device_printf(dev, "chip ver 0x%02x\n",
- sk_win_read_1(sc, SK_CHIPVER));
- device_printf(dev, "chip conf 0x%02x\n",
- sk_win_read_1(sc, SK_CONFIG));
}
sc->sk_devs[SK_PORT_A] = device_add_child(dev, "sk", -1);
@@ -2452,6 +2539,13 @@ sk_init_yukon(sc_if)
sc = sc_if->sk_softc;
ifp = &sc_if->arpcom.ac_if;
+ if (sc->sk_type == SK_YUKON_LITE &&
+ sc->sk_rev == SK_YUKON_LITE_REV_A3) {
+ /* Take PHY out of reset. */
+ sk_win_write_4(sc, SK_GPIO,
+ (sk_win_read_4(sc, SK_GPIO) | SK_GPIO_DIR9) & ~SK_GPIO_DAT9);
+ }
+
/* GMAC and GPHY Reset */
SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
@@ -2592,6 +2686,8 @@ sk_init(xsc)
sk_init_xmac(sc_if);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sk_init_yukon(sc_if);
break;
}
@@ -2670,6 +2766,8 @@ sk_init(xsc)
SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
reg = SK_YU_READ_2(sc_if, YUKON_GPCR);
reg |= YU_GPCR_TXEN | YU_GPCR_RXEN;
reg &= ~(YU_GPCR_SPEED_EN | YU_GPCR_DPLX_EN);
@@ -2721,6 +2819,8 @@ sk_stop(sc_if)
SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
break;
diff --git a/sys/dev/sk/if_skreg.h b/sys/dev/sk/if_skreg.h
index 1db61c2..44d31c3 100644
--- a/sys/dev/sk/if_skreg.h
+++ b/sys/dev/sk/if_skreg.h
@@ -50,9 +50,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* Values to keep the different chip revisions apart */
-#define SK_GENESIS 0
-#define SK_YUKON 1
+/* Values to keep the different chip revisions apart (SK_CHIPVER). */
+#define SK_GENESIS 0x0A
+#define SK_YUKON 0xB0
+#define SK_YUKON_LITE 0xB1
+#define SK_YUKON_LP 0xB2
+#define SK_YUKON_FAMILY(x) ((x) & 0xB0)
+
+/* Known revisions in SK_CONFIG. */
+#define SK_YUKON_LITE_REV_A0 0x0 /* invented, see test in skc_attach. */
+#define SK_YUKON_LITE_REV_A1 0x3
+#define SK_YUKON_LITE_REV_A3 0x7
/*
* SysKonnect PCI vendor ID
@@ -1425,6 +1433,8 @@ struct sk_softc {
struct resource *sk_res; /* I/O or shared mem handle */
u_int8_t sk_unit; /* controller number */
u_int8_t sk_type;
+ u_int8_t sk_rev;
+ u_int8_t spare;
char *sk_vpd_prodname;
char *sk_vpd_readonly;
uint16_t sk_vpd_readonly_len;
diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c
index d6e1cf3..39c0f8a 100644
--- a/sys/pci/if_sk.c
+++ b/sys/pci/if_sk.c
@@ -526,6 +526,8 @@ sk_miibus_readreg(dev, phy, reg)
case SK_GENESIS:
return(sk_xmac_miibus_readreg(sc_if, phy, reg));
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
return(sk_marv_miibus_readreg(sc_if, phy, reg));
}
@@ -545,6 +547,8 @@ sk_miibus_writereg(dev, phy, reg, val)
case SK_GENESIS:
return(sk_xmac_miibus_writereg(sc_if, phy, reg, val));
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
return(sk_marv_miibus_writereg(sc_if, phy, reg, val));
}
@@ -564,6 +568,8 @@ sk_miibus_statchg(dev)
sk_xmac_miibus_statchg(sc_if);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sk_marv_miibus_statchg(sc_if);
break;
}
@@ -796,6 +802,8 @@ sk_setmulti(sc_if)
SK_XM_WRITE_4(sc_if, XM_MAR2, 0);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0);
SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0);
SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0);
@@ -830,6 +838,8 @@ sk_setmulti(sc_if)
LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
h = sk_gmchash(
LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
break;
@@ -849,6 +859,8 @@ sk_setmulti(sc_if)
SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff);
SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff);
SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff);
@@ -875,6 +887,8 @@ sk_setpromisc(sc_if)
}
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
if (ifp->if_flags & IFF_PROMISC) {
SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
YU_RCR_UFLEN | YU_RCR_MUFLEN);
@@ -1263,14 +1277,14 @@ sk_reset(sc)
{
CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET);
CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET);
- if (sc->sk_type == SK_YUKON)
+ if (SK_YUKON_FAMILY(sc->sk_type))
CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET);
DELAY(1000);
CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET);
DELAY(2);
CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET);
- if (sc->sk_type == SK_YUKON)
+ if (SK_YUKON_FAMILY(sc->sk_type))
CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR);
if (sc->sk_type == SK_GENESIS) {
@@ -1320,6 +1334,8 @@ sk_probe(dev)
device_set_desc(dev, "XaQti Corp. XMAC II");
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
device_set_desc(dev, "Marvell Semiconductor, Inc. Yukon");
break;
}
@@ -1479,6 +1495,8 @@ sk_attach(dev)
sk_init_xmac(sc_if);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sk_init_yukon(sc_if);
break;
}
@@ -1513,6 +1531,7 @@ skc_attach(dev)
struct sk_softc *sc;
int unit, error = 0, rid, *port;
uint8_t skrs;
+ char *pname, *revstr;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
@@ -1536,6 +1555,17 @@ skc_attach(dev)
sc->sk_btag = rman_get_bustag(sc->sk_res);
sc->sk_bhandle = rman_get_bushandle(sc->sk_res);
+ sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
+ sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4) & 0xf;
+
+ /* Bail out if chip is not recognized. */
+ if (sc->sk_type != SK_GENESIS && !SK_YUKON_FAMILY(sc->sk_type)) {
+ printf("skc%d: unknown device: chipver=%02x, rev=%x\n",
+ unit, sc->sk_type, sc->sk_rev);
+ error = ENXIO;
+ goto fail;
+ }
+
/* Allocate interrupt */
rid = 0;
sc->sk_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
@@ -1547,24 +1577,6 @@ skc_attach(dev)
goto fail;
}
- /* Set adapter type */
- switch (pci_get_device(dev)) {
- case DEVICEID_SK_V1:
- sc->sk_type = SK_GENESIS;
- break;
- case DEVICEID_SK_V2:
- case DEVICEID_BELKIN_5005:
- case DEVICEID_3COM_3C940:
- case DEVICEID_LINKSYS_EG1032:
- case DEVICEID_DLINK_DGE530T:
- sc->sk_type = SK_YUKON;
- break;
- default:
- printf("skc%d: unknown device!\n", unit);
- error = ENXIO;
- goto fail;
- }
-
/* Reset the adapter. */
sk_reset(sc);
@@ -1599,7 +1611,7 @@ skc_attach(dev)
error = ENXIO;
goto fail;
}
- } else { /* SK_YUKON */
+ } else { /* SK_YUKON_FAMILY */
if (skrs == 0x00)
sc->sk_ramsize = 0x20000;
else
@@ -1628,9 +1640,88 @@ skc_attach(dev)
goto fail;
}
+ /* Determine whether to name it with VPD PN or just make it up.
+ * Marvell Yukon VPD PN seems to freqently be bogus. */
+ switch (pci_get_device(dev)) {
+ case DEVICEID_SK_V1:
+ case DEVICEID_BELKIN_5005:
+ case DEVICEID_3COM_3C940:
+ case DEVICEID_LINKSYS_EG1032:
+ case DEVICEID_DLINK_DGE530T:
+ /* Stay with VPD PN. */
+ pname = sc->sk_vpd_prodname;
+ break;
+ case DEVICEID_SK_V2:
+ /* YUKON VPD PN might bear no resemblance to reality. */
+ switch (sc->sk_type) {
+ case SK_GENESIS:
+ /* Stay with VPD PN. */
+ pname = sc->sk_vpd_prodname;
+ break;
+ case SK_YUKON:
+ pname = "Marvell Yukon Gigabit Ethernet";
+ break;
+ case SK_YUKON_LITE:
+ pname = "Marvell Yukon Lite Gigabit Ethernet";
+ break;
+ case SK_YUKON_LP:
+ pname = "Marvell Yukon LP Gigabit Ethernet";
+ break;
+ default:
+ pname = "Marvell Yukon (Unknown) Gigabit Ethernet";
+ break;
+ }
+
+ /* Yukon Lite Rev. A0 needs special test. */
+ if (sc->sk_type == SK_YUKON || sc->sk_type == SK_YUKON_LP) {
+ u_int32_t far;
+ u_int8_t testbyte;
+
+ /* Save flash address register before testing. */
+ far = sk_win_read_4(sc, SK_EP_ADDR);
+
+ sk_win_write_1(sc, SK_EP_ADDR+0x03, 0xff);
+ testbyte = sk_win_read_1(sc, SK_EP_ADDR+0x03);
+
+ if (testbyte != 0x00) {
+ /* Yukon Lite Rev. A0 detected. */
+ sc->sk_type = SK_YUKON_LITE;
+ sc->sk_rev = SK_YUKON_LITE_REV_A0;
+ /* Restore flash address register. */
+ sk_win_write_4(sc, SK_EP_ADDR, far);
+ }
+ }
+ break;
+ default:
+ device_printf(dev, "unknown device: vendor=%04x, device=%04x, "
+ "chipver=%02x, rev=%x\n",
+ pci_get_vendor(dev), pci_get_device(dev),
+ sc->sk_type, sc->sk_rev);
+ error = ENXIO;
+ goto fail;
+ }
+
+ if (sc->sk_type == SK_YUKON_LITE) {
+ switch (sc->sk_rev) {
+ case SK_YUKON_LITE_REV_A0:
+ revstr = "A0";
+ break;
+ case SK_YUKON_LITE_REV_A1:
+ revstr = "A1";
+ break;
+ case SK_YUKON_LITE_REV_A3:
+ revstr = "A3";
+ break;
+ default:
+ revstr = "";
+ break;
+ }
+ } else {
+ revstr = "";
+ }
+
/* Announce the product name and more VPD data if there. */
- if (sc->sk_vpd_prodname != NULL)
- printf("skc%d: %s\n", sc->sk_unit, sc->sk_vpd_prodname);
+ device_printf(dev, "%s rev. %s(0x%x)\n", pname, revstr, sc->sk_rev);
if (bootverbose) {
if (sc->sk_vpd_readonly != NULL &&
@@ -1660,14 +1751,10 @@ skc_attach(dev)
}
}
}
- device_printf(dev, "type = %s\n",
- (sc->sk_type == SK_GENESIS) ? "GENESIS" : "YUKON");
+ device_printf(dev, "chip ver = 0x%02x\n", sc->sk_type);
+ device_printf(dev, "chip rev = 0x%02x\n", sc->sk_rev);
device_printf(dev, "SK_EPROM0 = 0x%02x\n", skrs);
device_printf(dev, "SRAM size = 0x%06x\n", sc->sk_ramsize);
- device_printf(dev, "chip ver 0x%02x\n",
- sk_win_read_1(sc, SK_CHIPVER));
- device_printf(dev, "chip conf 0x%02x\n",
- sk_win_read_1(sc, SK_CONFIG));
}
sc->sk_devs[SK_PORT_A] = device_add_child(dev, "sk", -1);
@@ -2452,6 +2539,13 @@ sk_init_yukon(sc_if)
sc = sc_if->sk_softc;
ifp = &sc_if->arpcom.ac_if;
+ if (sc->sk_type == SK_YUKON_LITE &&
+ sc->sk_rev == SK_YUKON_LITE_REV_A3) {
+ /* Take PHY out of reset. */
+ sk_win_write_4(sc, SK_GPIO,
+ (sk_win_read_4(sc, SK_GPIO) | SK_GPIO_DIR9) & ~SK_GPIO_DAT9);
+ }
+
/* GMAC and GPHY Reset */
SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET);
SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET);
@@ -2592,6 +2686,8 @@ sk_init(xsc)
sk_init_xmac(sc_if);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sk_init_yukon(sc_if);
break;
}
@@ -2670,6 +2766,8 @@ sk_init(xsc)
SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
reg = SK_YU_READ_2(sc_if, YUKON_GPCR);
reg |= YU_GPCR_TXEN | YU_GPCR_RXEN;
reg &= ~(YU_GPCR_SPEED_EN | YU_GPCR_DPLX_EN);
@@ -2721,6 +2819,8 @@ sk_stop(sc_if)
SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET);
SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET);
break;
diff --git a/sys/pci/if_skreg.h b/sys/pci/if_skreg.h
index 1db61c2..44d31c3 100644
--- a/sys/pci/if_skreg.h
+++ b/sys/pci/if_skreg.h
@@ -50,9 +50,17 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* Values to keep the different chip revisions apart */
-#define SK_GENESIS 0
-#define SK_YUKON 1
+/* Values to keep the different chip revisions apart (SK_CHIPVER). */
+#define SK_GENESIS 0x0A
+#define SK_YUKON 0xB0
+#define SK_YUKON_LITE 0xB1
+#define SK_YUKON_LP 0xB2
+#define SK_YUKON_FAMILY(x) ((x) & 0xB0)
+
+/* Known revisions in SK_CONFIG. */
+#define SK_YUKON_LITE_REV_A0 0x0 /* invented, see test in skc_attach. */
+#define SK_YUKON_LITE_REV_A1 0x3
+#define SK_YUKON_LITE_REV_A3 0x7
/*
* SysKonnect PCI vendor ID
@@ -1425,6 +1433,8 @@ struct sk_softc {
struct resource *sk_res; /* I/O or shared mem handle */
u_int8_t sk_unit; /* controller number */
u_int8_t sk_type;
+ u_int8_t sk_rev;
+ u_int8_t spare;
char *sk_vpd_prodname;
char *sk_vpd_readonly;
uint16_t sk_vpd_readonly_len;
OpenPOWER on IntegriCloud