Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-2-0]: src/sys/dev/pci Pull up revision 1.11 (requested by abs in ...
details: https://anonhg.NetBSD.org/src/rev/b8db9e9df6e4
branches: netbsd-2-0
changeset: 564642:b8db9e9df6e4
user: jdc <jdc%NetBSD.org@localhost>
date: Fri Jan 07 12:13:50 2005 +0000
description:
Pull up revision 1.11 (requested by abs in ticket #973).
Fix Yukon ram sizing.
Fix tx queue (slist can be corrupted when tx interrupts hit within tx_encap.
Lower interrupt moderation timer to (improves performance).
Improve chip identification. (from linux sk98lin driver).
Keep tx queue running by kicking the tx bmu repeatedly.
diffstat:
sys/dev/pci/if_sk.c | 156 ++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 127 insertions(+), 29 deletions(-)
diffs (truncated from 338 to 300 lines):
diff -r 6043302b2376 -r b8db9e9df6e4 sys/dev/pci/if_sk.c
--- a/sys/dev/pci/if_sk.c Fri Jan 07 11:44:22 2005 +0000
+++ b/sys/dev/pci/if_sk.c Fri Jan 07 12:13:50 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_sk.c,v 1.7.2.3 2004/05/25 01:32:30 jmc Exp $ */
+/* $NetBSD: if_sk.c,v 1.7.2.4 2005/01/07 12:13:50 jdc Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -407,7 +407,7 @@
sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
if (sc->sk_vpd_readonly == NULL)
panic("sk_vpd_read");
- for (i = 0; i < res.vr_len + 1; i++)
+ for (i = 0; i < res.vr_len ; i++)
sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos);
}
@@ -624,6 +624,8 @@
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);
@@ -663,6 +665,8 @@
h = sk_xmac_hash(enm->enm_addrlo);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
h = sk_yukon_hash(enm->enm_addrlo);
break;
}
@@ -684,6 +688,8 @@
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);
@@ -879,6 +885,8 @@
XM_MODE_RX_PROMISC);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_YU_CLRBIT_2(sc_if, YUKON_RCR,
YU_RCR_UFLEN | YU_RCR_MUFLEN);
break;
@@ -893,6 +901,8 @@
XM_MODE_RX_PROMISC);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
SK_YU_SETBIT_2(sc_if, YUKON_RCR,
YU_RCR_UFLEN | YU_RCR_MUFLEN);
break;
@@ -977,14 +987,14 @@
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);
DPRINTFN(2, ("sk_reset: sk_csr=%x\n", CSR_READ_2(sc, SK_CSR)));
@@ -1011,7 +1021,7 @@
* register represents 18.825ns, so to specify a timeout in
* microseconds, we have to multiply by 54.
*/
- sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(200));
+ sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(100));
sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF|
SK_ISR_RX1_EOF|SK_ISR_RX2_EOF);
sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START);
@@ -1168,7 +1178,7 @@
for (i = 0; i < SK_RX_RING_CNT; i++)
sc_if->sk_cdata.sk_rx_chain[i].sk_mbuf = NULL;
- SLIST_INIT(&sc_if->sk_txmap_listhead);
+ SIMPLEQ_INIT(&sc_if->sk_txmap_head);
for (i = 0; i < SK_TX_RING_CNT; i++) {
sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf = NULL;
@@ -1197,7 +1207,7 @@
goto fail;
}
entry->dmamap = dmamap;
- SLIST_INSERT_HEAD(&sc_if->sk_txmap_listhead, entry, link);
+ SIMPLEQ_INSERT_HEAD(&sc_if->sk_txmap_head, entry, link);
}
sc_if->sk_rdata = (struct sk_ring_data *)kva;
@@ -1229,6 +1239,8 @@
sk_init_xmac(sc_if);
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sk_init_yukon(sc_if);
break;
default:
@@ -1246,6 +1258,8 @@
sc_if->sk_mii.mii_statchg = sk_xmac_miibus_statchg;
break;
case SK_YUKON:
+ case SK_YUKON_LITE:
+ case SK_YUKON_LP:
sc_if->sk_mii.mii_readreg = sk_marv_miibus_readreg;
sc_if->sk_mii.mii_writereg = sk_marv_miibus_writereg;
sc_if->sk_mii.mii_statchg = sk_marv_miibus_statchg;
@@ -1322,6 +1336,7 @@
bus_size_t iosize;
int s;
u_int32_t command;
+ char *revstr;
DPRINTFN(2, ("begin skc_attach\n"));
@@ -1367,22 +1382,6 @@
pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
- switch (PCI_PRODUCT(pa->pa_id)) {
- case PCI_PRODUCT_SCHNEIDERKOCH_SKNET_GE:
- sc->sk_type = SK_GENESIS;
- break;
- case PCI_PRODUCT_SCHNEIDERKOCH_SK9821v2:
- case PCI_PRODUCT_3COM_3C940:
- case PCI_PRODUCT_DLINK_DGE530T:
- case PCI_PRODUCT_LINKSYS_EG1032:
- case PCI_PRODUCT_LINKSYS_EG1064:
- sc->sk_type = SK_YUKON;
- break;
- default:
- aprint_error(": unknown device!\n");
- goto fail;
- }
-
#ifdef SK_USEIOSPACE
if (!(command & PCI_COMMAND_IO_ENABLE)) {
aprint_error(": failed to enable I/O ports!\n");
@@ -1419,6 +1418,14 @@
#endif
sc->sc_dmatag = pa->pa_dmat;
+ sc->sk_type = sk_win_read_1(sc, SK_CHIPVER);
+ sc->sk_rev = (sk_win_read_1(sc, SK_CONFIG) >> 4);
+
+ /* bail out here if chip is not recognized */
+ if ( sc->sk_type != SK_GENESIS && ! SK_YUKON_FAMILY(sc->sk_type)) {
+ aprint_error("%s: unknown chip type\n",sc->sk_dev.dv_xname);
+ goto fail;
+ }
DPRINTFN(2, ("skc_attach: allocate interrupt\n"));
/* Allocate interrupt */
@@ -1474,7 +1481,8 @@
sc->sk_ramsize, sc->sk_ramsize / 1024,
sc->sk_rboff));
} else {
- sc->sk_ramsize = 0x20000;
+ u_int8_t val = sk_win_read_1(sc, SK_EPROM0);
+ sc->sk_ramsize = ( val == 0 ) ? 0x20000 : (( val * 4 )*1024);
sc->sk_rboff = SK_RBOFF_0;
DPRINTFN(2, ("skc_attach: ramsize=%dk (%d), rboff=%d\n",
@@ -1502,8 +1510,91 @@
goto fail;
}
+ /* determine whether to name it with vpd or just make it up */
+ /* Marvell Yukon VPD's can freqently be bogus */
+
+ switch (pa->pa_id) {
+ case PCI_ID_CODE(PCI_VENDOR_SCHNEIDERKOCH,
+ PCI_PRODUCT_SCHNEIDERKOCH_SKNET_GE):
+ case PCI_PRODUCT_SCHNEIDERKOCH_SK9821v2:
+ case PCI_PRODUCT_3COM_3C940:
+ case PCI_PRODUCT_DLINK_DGE530T:
+ case PCI_PRODUCT_LINKSYS_EG1032:
+ case PCI_PRODUCT_LINKSYS_EG1064:
+ case PCI_ID_CODE(PCI_VENDOR_SCHNEIDERKOCH,
+ PCI_PRODUCT_SCHNEIDERKOCH_SK9821v2):
+ case PCI_ID_CODE(PCI_VENDOR_3COM,PCI_PRODUCT_3COM_3C940):
+ case PCI_ID_CODE(PCI_VENDOR_DLINK,PCI_PRODUCT_DLINK_DGE530T):
+ case PCI_ID_CODE(PCI_VENDOR_LINKSYS,PCI_PRODUCT_LINKSYS_EG1032):
+ case PCI_ID_CODE(PCI_VENDOR_LINKSYS,PCI_PRODUCT_LINKSYS_EG1064):
+ sc->sk_name = sc->sk_vpd_prodname;
+ break;
+ case PCI_ID_CODE(PCI_VENDOR_GALILEO,PCI_PRODUCT_GALILEO_SKNET):
+ /* whoops yukon vpd prodname bears no resemblance to reality */
+ switch (sc->sk_type) {
+ case SK_GENESIS:
+ sc->sk_name = sc->sk_vpd_prodname;
+ break;
+ case SK_YUKON:
+ sc->sk_name = "Marvell Yukon Gigabit Ethernet";
+ break;
+ case SK_YUKON_LITE:
+ sc->sk_name = "Marvell Yukon Lite Gigabit Ethernet";
+ break;
+ case SK_YUKON_LP:
+ sc->sk_name = "Marvell Yukon LP Gigabit Ethernet";
+ break;
+ default:
+ sc->sk_name = "Marvell Yukon (Unknown) Gigabit Ethernet";
+ }
+
+ /* Yukon Lite Rev A0 needs special test, from sk98lin driver */
+
+ if ( sc->sk_type == SK_YUKON ) {
+ uint32_t flashaddr;
+ uint8_t testbyte;
+
+ flashaddr = sk_win_read_4(sc,SK_EP_ADDR);
+
+ /* test Flash-Address Register */
+ sk_win_write_1(sc,SK_EP_ADDR+3, 0xff);
+ testbyte = sk_win_read_1(sc, SK_EP_ADDR+3);
+
+ if (testbyte != 0) {
+ /* this is yukon lite Rev. A0 */
+ 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,flashaddr);
+ }
+ }
+ break;
+ default:
+ sc->sk_name = "Unkown Marvell";
+ }
+
+
+ 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 = "";
+ }
+ } else {
+ revstr = "";
+ }
+
/* Announce the product name. */
- aprint_normal("%s: %s\n", sc->sk_dev.dv_xname, sc->sk_vpd_prodname);
+ aprint_normal("%s: %s rev. %s(0x%x)\n", sc->sk_dev.dv_xname,
+ sc->sk_name, revstr, sc->sk_rev);
skca.skc_port = SK_PORT_A;
(void)config_found(&sc->sk_dev, &skca, skcprint);
@@ -1532,7 +1623,7 @@
DPRINTFN(3, ("sk_encap\n"));
- entry = SLIST_FIRST(&sc_if->sk_txmap_listhead);
+ entry = SIMPLEQ_FIRST(&sc_if->sk_txmap_head);
if (entry == NULL) {
DPRINTFN(3, ("sk_encap: no txmap available\n"));
return ENOBUFS;
@@ -1582,7 +1673,8 @@
}
sc_if->sk_cdata.sk_tx_chain[cur].sk_mbuf = m_head;
- SLIST_REMOVE_HEAD(&sc_if->sk_txmap_listhead, link);
+ SIMPLEQ_REMOVE_HEAD(&sc_if->sk_txmap_head, link);
+
sc_if->sk_cdata.sk_tx_map[cur] = entry;
sc_if->sk_rdata->sk_tx_ring[cur].sk_ctl |=
SK_TXCTL_LASTFRAG|SK_TXCTL_EOF_INTR;
@@ -1827,7 +1919,7 @@
entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
- SLIST_INSERT_HEAD(&sc_if->sk_txmap_listhead, entry,
+ SIMPLEQ_INSERT_TAIL(&sc_if->sk_txmap_head, entry,
link);
Home |
Main Index |
Thread Index |
Old Index