Module Name: src
Committed By: jdolecek
Date: Mon Jul 2 06:03:13 UTC 2018
Modified Files:
src/sys/dev/pci: if_msk.c if_mskvar.h
Log Message:
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
To generate a diff of this commit:
cvs rdiff -u -r1.67 -r1.68 src/sys/dev/pci/if_msk.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/pci/if_mskvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_msk.c
diff -u src/sys/dev/pci/if_msk.c:1.67 src/sys/dev/pci/if_msk.c:1.68
--- src/sys/dev/pci/if_msk.c:1.67 Tue Jun 26 06:48:01 2018
+++ src/sys/dev/pci/if_msk.c Mon Jul 2 06:03:13 2018
@@ -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 mskcprint(void *, const char *);
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 @@ int msk_init(struct ifnet *);
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 @@ msk_init_rx_ring(struct sk_if_softc *sc_
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 @@ msk_init_tx_ring(struct sk_if_softc *sc_
}
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 @@ msk_newbuf(struct sk_if_softc *sc_if, in
}
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 @@ msk_newbuf(struct sk_if_softc *sc_if, in
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 @@ msk_update_int_mod(struct sk_softc *sc,
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 @@ msk_attach(device_t parent, device_t sel
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 @@ msk_detach(device_t self, int flags)
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 @@ msk_detach(device_t self, int flags)
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 @@ mskc_attach(device_t parent, device_t se
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 @@ mskc_attach(device_t parent, device_t se
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 @@ fail_3:
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 @@ mskc_detach(device_t self, int flags)
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 @@ mskc_detach(device_t self, int flags)
&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 @@ void
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 @@ msk_rxeof(struct sk_if_softc *sc_if, u_i
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 @@ msk_rxeof(struct sk_if_softc *sc_if, u_i
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 @@ msk_rxeof(struct sk_if_softc *sc_if, u_i
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 @@ msk_rxeof(struct sk_if_softc *sc_if, u_i
* 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 @@ msk_rxeof(struct sk_if_softc *sc_if, u_i
}
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;
struct ifnet *ifp = &sc_if->sk_ethercom.ec_if;
- u_int32_t sk_ctl;
+ u_int32_t idx, reg, sk_ctl;
struct sk_txmap_entry *entry;
- int cons, prog;
DPRINTFN(2, ("msk_txeof\n"));
+ if (sc_if->sk_port == SK_PORT_A)
+ reg = SK_STAT_BMU_TXA1_RIDX;
+ else
+ reg = SK_STAT_BMU_TXA2_RIDX;
+
/*
* Go through our tx ring and free mbufs for those
* frames that have been sent.
*/
- cons = sc_if->sk_cdata.sk_tx_cons;
- prog = 0;
- while (cons != idx) {
- if (sc_if->sk_cdata.sk_tx_cnt <= 0)
- break;
- prog++;
- cur_tx = &sc_if->sk_rdata->sk_tx_ring[cons];
-
- MSK_CDTXSYNC(sc_if, cons, 1,
+ idx = sc_if->sk_cdata.sk_tx_cons;
+ while (idx != sk_win_read_2(sc, reg)) {
+ MSK_CDTXSYNC(sc_if, idx, 1,
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+
+ cur_tx = &sc_if->sk_rdata->sk_tx_ring[idx];
sk_ctl = cur_tx->sk_ctl;
- MSK_CDTXSYNC(sc_if, cons, 1, BUS_DMASYNC_PREREAD);
#ifdef MSK_DEBUG
if (mskdebug >= 2)
- msk_dump_txdesc(cur_tx, cons);
+ msk_dump_txdesc(cur_tx, idx);
#endif
if (sk_ctl & SK_Y2_TXCTL_LASTFRAG)
ifp->if_opackets++;
- if (sc_if->sk_cdata.sk_tx_chain[cons].sk_mbuf != NULL) {
- entry = sc_if->sk_cdata.sk_tx_map[cons];
+ if (sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf != NULL) {
+ entry = sc_if->sk_cdata.sk_tx_map[idx];
+
+ m_freem(sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf);
+ sc_if->sk_cdata.sk_tx_chain[idx].sk_mbuf = NULL;
bus_dmamap_sync(sc->sc_dmatag, entry->dmamap, 0,
entry->dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
@@ -2002,20 +2008,29 @@ msk_txeof(struct sk_if_softc *sc_if, int
bus_dmamap_unload(sc->sc_dmatag, entry->dmamap);
SIMPLEQ_INSERT_TAIL(&sc_if->sk_txmap_head, entry,
link);
- sc_if->sk_cdata.sk_tx_map[cons] = NULL;
- m_freem(sc_if->sk_cdata.sk_tx_chain[cons].sk_mbuf);
- sc_if->sk_cdata.sk_tx_chain[cons].sk_mbuf = NULL;
+ sc_if->sk_cdata.sk_tx_map[idx] = NULL;
}
sc_if->sk_cdata.sk_tx_cnt--;
- SK_INC(cons, MSK_TX_RING_CNT);
+ SK_INC(idx, MSK_TX_RING_CNT);
}
ifp->if_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? 5 : 0;
if (sc_if->sk_cdata.sk_tx_cnt < MSK_TX_RING_CNT - 2)
ifp->if_flags &= ~IFF_OACTIVE;
- if (prog > 0)
- sc_if->sk_cdata.sk_tx_cons = cons;
+ sc_if->sk_cdata.sk_tx_cons = idx;
+}
+
+void
+msk_fill_rx_ring(struct sk_if_softc *sc_if)
+{
+ /* Make sure to not completely wrap around */
+ while (sc_if->sk_cdata.sk_rx_cnt < (MSK_RX_RING_CNT - 1)) {
+ if (msk_newbuf(sc_if, NULL,
+ sc_if->sk_cdata.sk_rx_jumbo_map) == ENOBUFS) {
+ break;
+ }
+ }
}
void
@@ -2056,17 +2071,17 @@ int
msk_intr(void *xsc)
{
struct sk_softc *sc = xsc;
+ struct sk_if_softc *sc_if;
struct sk_if_softc *sc_if0 = sc->sk_if[SK_PORT_A];
struct sk_if_softc *sc_if1 = sc->sk_if[SK_PORT_B];
struct ifnet *ifp0 = NULL, *ifp1 = NULL;
int claimed = 0;
u_int32_t status;
- uint32_t st_status;
- uint16_t st_len;
- uint8_t st_opcode, st_link;
struct msk_status_desc *cur_st;
status = CSR_READ_4(sc, SK_Y2_ISSR2);
+ if (status == 0xffffffff)
+ return (0);
if (status == 0) {
CSR_WRITE_4(sc, SK_Y2_ICR, 2);
return (0);
@@ -2089,56 +2104,36 @@ msk_intr(void *xsc)
msk_intr_yukon(sc_if1);
}
- for (;;) {
- cur_st = &sc->sk_status_ring[sc->sk_status_idx];
- MSK_CDSTSYNC(sc, sc->sk_status_idx,
- BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
- st_opcode = cur_st->sk_opcode;
- if ((st_opcode & SK_Y2_STOPC_OWN) == 0) {
- MSK_CDSTSYNC(sc, sc->sk_status_idx,
- BUS_DMASYNC_PREREAD);
- break;
- }
- st_status = le32toh(cur_st->sk_status);
- st_len = le16toh(cur_st->sk_len);
- st_link = cur_st->sk_link;
- st_opcode &= ~SK_Y2_STOPC_OWN;
+ MSK_CDSTSYNC(sc, sc->sk_status_idx,
+ BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+ cur_st = &sc->sk_status_ring[sc->sk_status_idx];
- switch (st_opcode) {
+ while (cur_st->sk_opcode & SK_Y2_STOPC_OWN) {
+ cur_st->sk_opcode &= ~SK_Y2_STOPC_OWN;
+ switch (cur_st->sk_opcode) {
case SK_Y2_STOPC_RXSTAT:
- msk_rxeof(sc->sk_if[st_link], st_len, st_status);
- SK_IF_WRITE_2(sc->sk_if[st_link], 0,
- SK_RXQ1_Y2_PREF_PUTIDX,
- sc->sk_if[st_link]->sk_cdata.sk_rx_prod);
+ sc_if = sc->sk_if[cur_st->sk_link & 0x01];
+ msk_rxeof(sc_if, letoh16(cur_st->sk_len),
+ letoh32(cur_st->sk_status));
+ msk_fill_rx_ring(sc_if);
+ SK_IF_WRITE_2(sc_if, 0, SK_RXQ1_Y2_PREF_PUTIDX,
+ sc_if->sk_cdata.sk_rx_prod);
break;
case SK_Y2_STOPC_TXSTAT:
if (sc_if0)
- msk_txeof(sc_if0, st_status
- & SK_Y2_ST_TXA1_MSKL);
+ msk_txeof(sc_if0);
if (sc_if1)
- msk_txeof(sc_if1,
- ((st_status & SK_Y2_ST_TXA2_MSKL)
- >> SK_Y2_ST_TXA2_SHIFTL)
- | ((st_len & SK_Y2_ST_TXA2_MSKH) << SK_Y2_ST_TXA2_SHIFTH));
+ msk_txeof(sc_if1);
break;
default:
- aprint_error("opcode=0x%x\n", st_opcode);
+ aprint_error("opcode=0x%x\n", cur_st->sk_opcode);
break;
}
SK_INC(sc->sk_status_idx, MSK_STATUS_RING_CNT);
- }
-
-#define MSK_STATUS_RING_OWN_CNT(sc) \
- (((sc)->sk_status_idx + MSK_STATUS_RING_CNT - \
- (sc)->sk_status_own_idx) % MSK_STATUS_RING_CNT)
- while (MSK_STATUS_RING_OWN_CNT(sc) > MSK_STATUS_RING_CNT / 2) {
- cur_st = &sc->sk_status_ring[sc->sk_status_own_idx];
- cur_st->sk_opcode &= ~SK_Y2_STOPC_OWN;
- MSK_CDSTSYNC(sc, sc->sk_status_own_idx,
- BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
-
- SK_INC(sc->sk_status_own_idx, MSK_STATUS_RING_CNT);
+ MSK_CDSTSYNC(sc, sc->sk_status_idx,
+ BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+ cur_st = &sc->sk_status_ring[sc->sk_status_idx];
}
if (status & SK_Y2_IMR_BMU) {
@@ -2148,9 +2143,9 @@ msk_intr(void *xsc)
CSR_WRITE_4(sc, SK_Y2_ICR, 2);
- if (ifp0 != NULL)
+ if (ifp0 != NULL && !IFQ_IS_EMPTY(&ifp0->if_snd))
if_schedule_deferred_start(ifp0);
- if (ifp1 != NULL)
+ if (ifp1 != NULL && !IFQ_IS_EMPTY(&ifp1->if_snd))
if_schedule_deferred_start(ifp1);
rnd_add_uint32(&sc->rnd_source, status);
@@ -2303,7 +2298,7 @@ msk_init(struct ifnet *ifp)
s = splnet();
/* Cancel pending I/O and free all RX/TX buffers. */
- msk_stop(ifp, 0);
+ msk_stop(ifp, 1);
/* Configure I2C registers */
@@ -2352,7 +2347,7 @@ msk_init(struct ifnet *ifp)
if (msk_init_rx_ring(sc_if) == ENOBUFS) {
aprint_error_dev(sc_if->sk_dev, "initialization failed: no "
"memory for rx buffers\n");
- msk_stop(ifp, 0);
+ msk_stop(ifp, 1);
splx(s);
return ENOBUFS;
}
@@ -2360,7 +2355,7 @@ msk_init(struct ifnet *ifp)
if (msk_init_tx_ring(sc_if) == ENOBUFS) {
aprint_error_dev(sc_if->sk_dev, "initialization failed: no "
"memory for tx buffers\n");
- msk_stop(ifp, 0);
+ msk_stop(ifp, 1);
splx(s);
return ENOBUFS;
}
@@ -2439,6 +2434,10 @@ out:
return rc;
}
+/*
+ * Note: the logic of second parameter is inverted compared to OpenBSD
+ * code, since this code uses the function as if_stop hook too.
+ */
void
msk_stop(struct ifnet *ifp, int disable)
{
@@ -2457,32 +2456,30 @@ msk_stop(struct ifnet *ifp, int disable)
/* Stop transfer of Rx descriptors */
- /* Turn off various components of this interface. */
- SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC);
- 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);
- SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
- SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
- SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE);
- SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
- SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
- SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
- SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP);
- SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
- SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
-
- SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
- SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
-
- /* Disable interrupts */
- if (sc_if->sk_port == SK_PORT_A)
- sc->sk_intrmask &= ~SK_Y2_INTRS1;
- else
- sc->sk_intrmask &= ~SK_Y2_INTRS2;
- CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
-
- SK_XM_READ_2(sc_if, XM_ISR);
- SK_XM_WRITE_2(sc_if, XM_IMR, 0xFFFF);
+ if (disable) {
+ /* Turn off various components of this interface. */
+ 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);
+ SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE);
+ SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
+ SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_BMU_CSR, SK_TXBMU_OFFLINE);
+ SK_IF_WRITE_4(sc_if, 1, SK_TXRBA1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF);
+ SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, SK_TXARCTL_OFF);
+ SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_STOP);
+ SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_STOP);
+ SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_OFF);
+ SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_OFF);
+
+ SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_Y2_PREF_CSR, 0x00000001);
+ SK_IF_WRITE_4(sc_if, 1, SK_TXQA1_Y2_PREF_CSR, 0x00000001);
+
+ /* Disable interrupts */
+ if (sc_if->sk_port == SK_PORT_A)
+ sc->sk_intrmask &= ~SK_Y2_INTRS1;
+ else
+ sc->sk_intrmask &= ~SK_Y2_INTRS2;
+ CSR_WRITE_4(sc, SK_IMR, sc->sk_intrmask);
+ }
/* Free RX and TX mbufs still in the queues. */
for (i = 0; i < MSK_RX_RING_CNT; i++) {
@@ -2492,6 +2489,10 @@ msk_stop(struct ifnet *ifp, int disable)
}
}
+ sc_if->sk_cdata.sk_rx_prod = 0;
+ sc_if->sk_cdata.sk_rx_cons = 0;
+ sc_if->sk_cdata.sk_rx_cnt = 0;
+
for (i = 0; i < MSK_TX_RING_CNT; i++) {
if (sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf != NULL) {
m_freem(sc_if->sk_cdata.sk_tx_chain[i].sk_mbuf);
@@ -2611,8 +2612,8 @@ msk_sysctl_handler(SYSCTLFN_ARGS)
}
/*
- * Set up sysctl(3) MIB, hw.sk.* - Individual controllers will be
- * set up in skc_attach()
+ * Set up sysctl(3) MIB, hw.msk.* - Individual controllers will be
+ * set up in mskc_attach()
*/
SYSCTL_SETUP(sysctl_msk, "sysctl msk subtree setup")
{
Index: src/sys/dev/pci/if_mskvar.h
diff -u src/sys/dev/pci/if_mskvar.h:1.14 src/sys/dev/pci/if_mskvar.h:1.15
--- src/sys/dev/pci/if_mskvar.h:1.14 Wed Jun 13 19:37:23 2018
+++ src/sys/dev/pci/if_mskvar.h Mon Jul 2 06:03:13 2018
@@ -1,5 +1,5 @@
/* $OpenBSD: if_mskvar.h,v 1.3 2006/12/28 16:34:42 kettenis Exp $ */
-/* $NetBSD: if_mskvar.h,v 1.14 2018/06/13 19:37:23 jdolecek Exp $ */
+/* $NetBSD: if_mskvar.h,v 1.15 2018/07/02 06:03:13 jdolecek Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -223,7 +223,7 @@ struct sk_if_softc {
u_int32_t sk_rx_ramend;
u_int32_t sk_tx_ramstart;
u_int32_t sk_tx_ramend;
- int sk_cnt;
+ int sk_pktlen; /* XXX set but unused for now */
int sk_link;
struct callout sk_tick_ch;
struct msk_chain_data sk_cdata;