Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci sync OpenBSD if_msk.c revs 1.66-1.79 skipping fr...
details: https://anonhg.NetBSD.org/src/rev/7600d67fc7d5
branches: trunk
changeset: 324398:7600d67fc7d5
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Mon Jul 02 06:03:13 2018 +0000
description:
sync OpenBSD if_msk.c revs 1.66-1.79 skipping framework changes and already
present changes:
- Make Yukon-2 FE+ (88E8040, 88E8042) work
- 88E8057 is a Yukon 2 Ultra 2, and this might make it work on a little
shiny green box in Japan
- Prevent null pointer dereference that could happen when we process an RX
interrupt that was queued while stopping the interface.
- Remove holdover XMAC II writes/reads inherited from sk as
they aren't required and cause problems like the 88E8072
hard locking a system when enabling macsec bypass.
- Bypass macsec on extreme/supreme based chips.
Makes my 88E8072 work.
- Add detach support to a few more drivers, and in others do the neccessary
operations in the detach function in the right order.
towards resolution of PR kern/53301 but will need more work
tested by John Halfpenny on another 8040/Yukon-2 FE+ and reported
improving behaviour (system hang to stall) so committing as stopgap; also
tested on my SK-9E22 (Yukon-2 XL), there works without any issues both before
and after
diffstat:
sys/dev/pci/if_msk.c | 303 ++++++++++++++++++++++++-----------------------
sys/dev/pci/if_mskvar.h | 4 +-
2 files changed, 154 insertions(+), 153 deletions(-)
diffs (truncated from 633 to 300 lines):
diff -r 7522ddc7059e -r 7600d67fc7d5 sys/dev/pci/if_msk.c
--- a/sys/dev/pci/if_msk.c Mon Jul 02 03:52:32 2018 +0000
+++ b/sys/dev/pci/if_msk.c Mon Jul 02 06:03:13 2018 +0000
@@ -1,5 +1,5 @@
-/* $NetBSD: if_msk.c,v 1.67 2018/06/26 06:48:01 msaitoh Exp $ */
-/* $OpenBSD: if_msk.c,v 1.65 2008/09/10 14:01:22 blambert Exp $ */
+/* $NetBSD: if_msk.c,v 1.68 2018/07/02 06:03:13 jdolecek Exp $ */
+/* $OpenBSD: if_msk.c,v 1.79 2009/10/15 17:54:56 deraadt Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_msk.c,v 1.67 2018/06/26 06:48:01 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_msk.c,v 1.68 2018/07/02 06:03:13 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -106,7 +106,7 @@
int msk_intr(void *);
void msk_intr_yukon(struct sk_if_softc *);
void msk_rxeof(struct sk_if_softc *, u_int16_t, u_int32_t);
-void msk_txeof(struct sk_if_softc *, int);
+void msk_txeof(struct sk_if_softc *);
int msk_encap(struct sk_if_softc *, struct mbuf *, u_int32_t *);
void msk_start(struct ifnet *);
int msk_ioctl(struct ifnet *, u_long, void *);
@@ -114,12 +114,13 @@
void msk_init_yukon(struct sk_if_softc *);
void msk_stop(struct ifnet *, int);
void msk_watchdog(struct ifnet *);
-int msk_newbuf(struct sk_if_softc *, int, struct mbuf *, bus_dmamap_t);
+int msk_newbuf(struct sk_if_softc *, struct mbuf *, bus_dmamap_t);
int msk_alloc_jumbo_mem(struct sk_if_softc *);
void *msk_jalloc(struct sk_if_softc *);
void msk_jfree(struct mbuf *, void *, size_t, void *);
int msk_init_rx_ring(struct sk_if_softc *);
int msk_init_tx_ring(struct sk_if_softc *);
+void msk_fill_rx_ring(struct sk_if_softc *);
void msk_update_int_mod(struct sk_softc *, int);
@@ -419,17 +420,11 @@
cd->sk_rx_chain[i].sk_next = &cd->sk_rx_chain[nexti];
}
- for (i = 0; i < MSK_RX_RING_CNT; i++) {
- if (msk_newbuf(sc_if, i, NULL,
- sc_if->sk_cdata.sk_rx_jumbo_map) == ENOBUFS) {
- aprint_error_dev(sc_if->sk_dev, "failed alloc of %dth mbuf\n", i);
- return (ENOBUFS);
- }
- }
-
- sc_if->sk_cdata.sk_rx_prod = MSK_RX_RING_CNT - 1;
+ sc_if->sk_cdata.sk_rx_prod = 0;
sc_if->sk_cdata.sk_rx_cons = 0;
-
+ sc_if->sk_cdata.sk_rx_cnt = 0;
+
+ msk_fill_rx_ring(sc_if);
return (0);
}
@@ -478,7 +473,7 @@
}
int
-msk_newbuf(struct sk_if_softc *sc_if, int i, struct mbuf *m,
+msk_newbuf(struct sk_if_softc *sc_if, struct mbuf *m,
bus_dmamap_t dmamap)
{
struct mbuf *m_new = NULL;
@@ -516,7 +511,7 @@
}
m_adj(m_new, ETHER_ALIGN);
- c = &sc_if->sk_cdata.sk_rx_chain[i];
+ c = &sc_if->sk_cdata.sk_rx_chain[sc_if->sk_cdata.sk_rx_prod];
r = c->sk_le;
c->sk_mbuf = m_new;
r->sk_addr = htole32(dmamap->dm_segs[0].ds_addr +
@@ -526,7 +521,11 @@
r->sk_ctl = 0;
r->sk_opcode = SK_Y2_RXOPC_PACKET | SK_Y2_RXOPC_OWN;
- MSK_CDRXSYNC(sc_if, i, BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
+ MSK_CDRXSYNC(sc_if, sc_if->sk_cdata.sk_rx_prod,
+ BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
+
+ SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
+ sc_if->sk_cdata.sk_rx_cnt++;
return (0);
}
@@ -765,6 +764,9 @@
case SK_YUKON_FE:
imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE;
break;
+ case SK_YUKON_FE_P:
+ imtimer_ticks = SK_IMTIMER_TICKS_YUKON_FE_P;
+ break;
case SK_YUKON_XL:
imtimer_ticks = SK_IMTIMER_TICKS_YUKON_XL;
break;
@@ -1121,16 +1123,24 @@
sc_if->sk_rdata = (struct msk_ring_data *)kva;
memset(sc_if->sk_rdata, 0, sizeof(struct msk_ring_data));
- ifp = &sc_if->sk_ethercom.ec_if;
+ if (sc->sk_type != SK_YUKON_FE &&
+ sc->sk_type != SK_YUKON_FE_P)
+ sc_if->sk_pktlen = SK_JLEN;
+ else
+ sc_if->sk_pktlen = MCLBYTES;
+
/* Try to allocate memory for jumbo buffers. */
if (msk_alloc_jumbo_mem(sc_if)) {
aprint_error(": jumbo buffer allocation failed\n");
goto fail_3;
}
+
sc_if->sk_ethercom.ec_capabilities = ETHERCAP_VLAN_MTU;
- if (sc->sk_type != SK_YUKON_FE)
+ if (sc->sk_type != SK_YUKON_FE &&
+ sc->sk_type != SK_YUKON_FE_P)
sc_if->sk_ethercom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
+ ifp = &sc_if->sk_ethercom.ec_if;
ifp->if_softc = sc_if;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = msk_ioctl;
@@ -1215,6 +1225,8 @@
if (sc->sk_if[sc_if->sk_port] == NULL)
return (0);
+ msk_stop(ifp, 0);
+
rnd_detach_source(&sc->rnd_source);
callout_halt(&sc_if->sk_tick_ch, NULL);
@@ -1232,11 +1244,11 @@
ether_ifdetach(ifp);
if_detach(ifp);
- bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
bus_dmamem_unmap(sc->sc_dmatag, sc_if->sk_rdata,
sizeof(struct msk_ring_data));
bus_dmamem_free(sc->sc_dmatag,
&sc_if->sk_ring_seg, sc_if->sk_ring_nseg);
+ bus_dmamap_destroy(sc->sc_dmatag, sc_if->sk_ring_map);
sc->sk_if[sc_if->sk_port] = NULL;
return (0);
@@ -1354,7 +1366,8 @@
sc->sk_pc = pc;
if (bus_dmamem_alloc(sc->sc_dmatag,
- MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc), PAGE_SIZE,
+ MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
+ MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc),
0, &sc->sk_status_seg, 1, &sc->sk_status_nseg, BUS_DMA_NOWAIT)) {
aprint_error(": can't alloc status buffers\n");
goto fail_2;
@@ -1632,10 +1645,8 @@
return;
- fail_6:
+fail_6:
bus_dmamap_unload(sc->sc_dmatag, sc->sk_status_map);
-fail_5:
- bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
fail_4:
bus_dmamem_unmap(sc->sc_dmatag, kva,
MSK_STATUS_RING_CNT * sizeof(struct msk_status_desc));
@@ -1643,6 +1654,8 @@
bus_dmamem_free(sc->sc_dmatag,
&sc->sk_status_seg, sc->sk_status_nseg);
sc->sk_status_nseg = 0;
+fail_5:
+ bus_dmamap_destroy(sc->sc_dmatag, sc->sk_status_map);
fail_2:
pci_intr_disestablish(pc, sc->sk_intrhand);
sc->sk_intrhand = NULL;
@@ -1657,6 +1670,9 @@
struct sk_softc *sc = (struct sk_softc *)self;
int rv;
+ if (sc->sk_intrhand)
+ pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
+
rv = config_detach_children(self, flags);
if (rv != 0)
return (rv);
@@ -1669,9 +1685,6 @@
&sc->sk_status_seg, sc->sk_status_nseg);
}
- if (sc->sk_intrhand)
- pci_intr_disestablish(sc->sk_pc, sc->sk_intrhand);
-
if (sc->sk_bsize > 0)
bus_space_unmap(sc->sk_btag, sc->sk_bhandle, sc->sk_bsize);
@@ -1828,31 +1841,21 @@
msk_watchdog(struct ifnet *ifp)
{
struct sk_if_softc *sc_if = ifp->if_softc;
- u_int32_t reg;
- int idx;
/*
* Reclaim first as there is a possibility of losing Tx completion
* interrupts.
*/
- if (sc_if->sk_port == SK_PORT_A)
- reg = SK_STAT_BMU_TXA1_RIDX;
- else
- reg = SK_STAT_BMU_TXA2_RIDX;
-
- idx = sk_win_read_2(sc_if->sk_softc, reg);
- if (sc_if->sk_cdata.sk_tx_cons != idx) {
- msk_txeof(sc_if, idx);
- if (sc_if->sk_cdata.sk_tx_cnt != 0) {
- aprint_error_dev(sc_if->sk_dev, "watchdog timeout\n");
-
- ifp->if_oerrors++;
-
- /* XXX Resets both ports; we shouldn't do that. */
- mskc_reset(sc_if->sk_softc);
- msk_reset(sc_if);
- msk_init(ifp);
- }
+ msk_txeof(sc_if);
+ if (sc_if->sk_cdata.sk_tx_cnt != 0) {
+ aprint_error_dev(sc_if->sk_dev, "watchdog timeout\n");
+
+ ifp->if_oerrors++;
+
+ /* XXX Resets both ports; we shouldn't do that. */
+ mskc_reset(sc_if->sk_softc);
+ msk_reset(sc_if);
+ msk_init(ifp);
}
}
@@ -1908,8 +1911,6 @@
DPRINTFN(2, ("msk_rxeof\n"));
cur = sc_if->sk_cdata.sk_rx_cons;
- SK_INC(sc_if->sk_cdata.sk_rx_cons, MSK_RX_RING_CNT);
- SK_INC(sc_if->sk_cdata.sk_rx_prod, MSK_RX_RING_CNT);
/* Sync the descriptor */
MSK_CDRXSYNC(sc_if, cur, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
@@ -1919,6 +1920,9 @@
return;
dmamap = sc_if->sk_cdata.sk_rx_jumbo_map;
+ SK_INC(sc_if->sk_cdata.sk_rx_cons, MSK_RX_RING_CNT);
+ sc_if->sk_cdata.sk_rx_cnt--;
+
bus_dmamap_sync(sc_if->sk_softc->sc_dmatag, dmamap, 0,
dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
@@ -1929,7 +1933,7 @@
total_len > ETHER_MAX_LEN_JUMBO ||
msk_rxvalid(sc, rxstat, total_len) == 0) {
ifp->if_ierrors++;
- msk_newbuf(sc_if, cur, m, dmamap);
+ msk_newbuf(sc_if, m, dmamap);
return;
}
@@ -1939,11 +1943,11 @@
* so it can be re-used. If allocating mbufs fails, then we
* have to drop the packet.
*/
- if (msk_newbuf(sc_if, cur, NULL, dmamap) == ENOBUFS) {
+ if (msk_newbuf(sc_if, NULL, dmamap) == ENOBUFS) {
struct mbuf *m0;
m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
total_len + ETHER_ALIGN, 0, ifp, NULL);
- msk_newbuf(sc_if, cur, m, dmamap);
+ msk_newbuf(sc_if, m, dmamap);
if (m0 == NULL) {
ifp->if_ierrors++;
return;
@@ -1960,41 +1964,43 @@
}
void
-msk_txeof(struct sk_if_softc *sc_if, int idx)
+msk_txeof(struct sk_if_softc *sc_if)
{
struct sk_softc *sc = sc_if->sk_softc;
struct msk_tx_desc *cur_tx;
Home |
Main Index |
Thread Index |
Old Index