diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2004-11-16 17:45:55 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2004-11-16 17:45:55 +0000 |
commit | 186c15bdd490790a2e30f89350546e5e5889c328 (patch) | |
tree | 681ce10f12d9d4a265260d5856f7c60c6477ba13 /sys | |
parent | a41dec8cc998e207616f4f86405c56cb3c2d2840 (diff) |
back out previous commit and put the right change in which corresponds
to what the previous commit message said...
Fix tx queue (slist can be corrupted when tx interrupts hit within tx_encap).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_sk.c | 152 | ||||
-rw-r--r-- | sys/dev/pci/if_skreg.h | 6 |
2 files changed, 36 insertions, 122 deletions
diff --git a/sys/dev/pci/if_sk.c b/sys/dev/pci/if_sk.c index bf1a5f39ffa..db0254fa315 100644 --- a/sys/dev/pci/if_sk.c +++ b/sys/dev/pci/if_sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_sk.c,v 1.49 2004/11/16 14:41:47 brad Exp $ */ +/* $OpenBSD: if_sk.c,v 1.50 2004/11/16 17:45:54 brad Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -381,7 +381,7 @@ sk_vpd_read(struct sk_softc *sc) 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; i++) + for (i = 0; i < res.vr_len + 1; i++) sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos); } @@ -594,8 +594,6 @@ sk_setmulti(struct sk_if_softc *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); @@ -634,8 +632,6 @@ allmulti: break; case SK_YUKON: - case SK_YUKON_LITE: - case SK_YUKON_LP: h = sk_yukon_hash(enm->enm_addrlo); break; } @@ -657,8 +653,6 @@ allmulti: 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); @@ -719,7 +713,7 @@ sk_init_tx_ring(struct sk_if_softc *sc_if) bzero((char *)sc_if->sk_rdata->sk_tx_ring, sizeof(struct sk_tx_desc) * SK_TX_RING_CNT); - SLIST_INIT(&sc_if->sk_txmap_listhead); + SIMPLEQ_INIT(&sc_if->sk_txmap_head); for (i = 0; i < SK_TX_RING_CNT; i++) { cd->sk_tx_chain[i].sk_desc = &rd->sk_tx_ring[i]; if (i == (SK_TX_RING_CNT - 1)) { @@ -740,7 +734,7 @@ sk_init_tx_ring(struct sk_if_softc *sc_if) return (ENOBUFS); } 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_cdata.sk_tx_prod = 0; @@ -1011,8 +1005,6 @@ sk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 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; @@ -1027,8 +1019,6 @@ sk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 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; @@ -1094,14 +1084,14 @@ void sk_reset(struct sk_softc *sc) CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET); CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET); - if (SK_YUKON_FAMILY(sc->sk_type)) + if (sc->sk_type == SK_YUKON) 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 (SK_YUKON_FAMILY(sc->sk_type)) + if (sc->sk_type == SK_YUKON) 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))); @@ -1304,8 +1294,6 @@ sk_attach(struct device *parent, struct device *self, void *aux) sk_init_xmac(sc_if); break; case SK_YUKON: - case SK_YUKON_LITE: - case SK_YUKON_LP: sk_init_yukon(sc_if); break; default: @@ -1323,8 +1311,6 @@ sk_attach(struct device *parent, struct device *self, void *aux) 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; @@ -1393,7 +1379,6 @@ skc_attach(struct device *parent, struct device *self, void *aux) bus_size_t iosize; int s; u_int32_t command; - char *revstr; DPRINTFN(2, ("begin skc_attach\n")); @@ -1434,6 +1419,28 @@ skc_attach(struct device *parent, struct device *self, void *aux) */ command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); +#define SK_MK_ID(vnd,prd) \ + (((vnd) << PCI_VENDOR_SHIFT) | ((prd) << PCI_PRODUCT_SHIFT)) + + switch (pa->pa_id) { + case SK_MK_ID(PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_GE): + sc->sk_type = SK_GENESIS; + break; + case SK_MK_ID(PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3C940): + case SK_MK_ID(PCI_VENDOR_DLINK, PCI_PRODUCT_DLINK_DGE530T): + case SK_MK_ID(PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_EG1032): + case SK_MK_ID(PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_EG1064): + case SK_MK_ID(PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_SK_V2): + case SK_MK_ID(PCI_VENDOR_MARVELL, PCI_PRODUCT_MARVELL_SK_V2_BELKIN): + case SK_MK_ID(PCI_VENDOR_SCHNEIDERKOCH, PCI_PRODUCT_SCHNEIDERKOCH_SK9821v2): + sc->sk_type = SK_YUKON; + break; + default: + printf(": unknown device!\n"); + goto fail; + } +#undef SK_MK_ID + #ifdef SK_USEIOSPACE if (!(command & PCI_COMMAND_IO_ENABLE)) { printf(": failed to enable I/O ports!\n"); @@ -1470,14 +1477,6 @@ skc_attach(struct device *parent, struct device *self, void *aux) #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)) { - printf("%s: unknown chip type\n",sc->sk_dev.dv_xname); - goto fail; - } DPRINTFN(2, ("skc_attach: allocate interrupt\n")); /* Allocate interrupt */ @@ -1559,89 +1558,8 @@ skc_attach(struct device *parent, struct device *self, void *aux) 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_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_MARVELL,PCI_PRODUCT_MARVELL_SK_V2): - case PCI_ID_CODE(PCI_VENDOR_MARVELL,PCI_PRODUCT_MARVELL_SK_V2_BELKIN): - /* 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 a 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. */ - printf("%s: %s rev. %s(0x%x)\n", sc->sk_dev.dv_xname, - sc->sk_name, revstr, sc->sk_rev); + printf("%s: %s\n", sc->sk_dev.dv_xname, sc->sk_vpd_prodname); skca.skc_port = SK_PORT_A; (void)config_found(&sc->sk_dev, &skca, skcprint); @@ -1670,7 +1588,7 @@ sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) DPRINTFN(2, ("sk_encap\n")); - entry = SLIST_FIRST(&sc_if->sk_txmap_listhead); + entry = SIMPLEQ_FIRST(&sc_if->sk_txmap_head); if (entry == NULL) { DPRINTFN(2, ("sk_encap: no txmap available\n")); return ENOBUFS; @@ -1716,7 +1634,7 @@ sk_encap(struct sk_if_softc *sc_if, struct mbuf *m_head, u_int32_t *txidx) } 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; @@ -2022,7 +1940,7 @@ sk_txeof(struct sk_if_softc *sc_if) 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); sc_if->sk_cdata.sk_tx_map[idx] = NULL; } @@ -2588,8 +2506,6 @@ sk_init(void *xsc_if) sk_init_xmac(sc_if); break; case SK_YUKON: - case SK_YUKON_LITE: - case SK_YUKON_LP: sk_init_yukon(sc_if); break; } @@ -2675,7 +2591,7 @@ sk_init(void *xsc_if) XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB); } - if (SK_YUKON_FAMILY(sc->sk_type)) { + if (sc->sk_type == SK_YUKON) { u_int16_t 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); @@ -2724,8 +2640,6 @@ sk_stop(struct sk_if_softc *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/pci/if_skreg.h b/sys/dev/pci/if_skreg.h index 412a0629f1b..dd378288d68 100644 --- a/sys/dev/pci/if_skreg.h +++ b/sys/dev/pci/if_skreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_skreg.h,v 1.13 2004/08/05 19:57:17 brad Exp $ */ +/* $OpenBSD: if_skreg.h,v 1.14 2004/11/16 17:45:54 brad Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -1345,7 +1345,7 @@ struct sk_chain { struct sk_txmap_entry { bus_dmamap_t dmamap; - SLIST_ENTRY(sk_txmap_entry) link; + SIMPLEQ_ENTRY(sk_txmap_entry) link; }; struct sk_chain_data { @@ -1432,7 +1432,7 @@ struct sk_if_softc { int sk_if_flags; LIST_HEAD(__sk_jfreehead, sk_jpool_entry) sk_jfree_listhead; LIST_HEAD(__sk_jinusehead, sk_jpool_entry) sk_jinuse_listhead; - SLIST_HEAD(__sk_txmaphead, sk_txmap_entry) sk_txmap_listhead; + SIMPLEQ_HEAD(__sk_txmaphead, sk_txmap_entry) sk_txmap_head; }; struct skc_attach_args { |