Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys wlan interfaces make interrupt routine running on softin...
details: https://anonhg.NetBSD.org/src/rev/c71c6125e40a
branches: trunk
changeset: 351099:c71c6125e40a
user: nonaka <nonaka%NetBSD.org@localhost>
date: Thu Feb 02 10:05:35 2017 +0000
description:
wlan interfaces make interrupt routine running on softint context.
see http://mail-index.netbsd.org/tech-kern/2016/12/06/msg021281.html
tested device:
* ath at pci: AR5212, AR5424
* athn at pci: AR9287
* ipw at pci: 2100BG
* iwi at pci: 2915ABG
* iwm at pci: 3165, 7260, 8260
* iwn at pci: 4945, 6235
* ral at pci: RT2560
* rtwn at pci: RTL8192CE
diffstat:
sys/dev/ic/an.c | 75 ++++++++-
sys/dev/ic/anvar.h | 3 +-
sys/dev/ic/arn5008.c | 54 +++++-
sys/dev/ic/arn9003.c | 55 ++++++-
sys/dev/ic/ath.c | 77 +++++++++-
sys/dev/ic/ath_netbsd.h | 20 +-
sys/dev/ic/athn.c | 48 +++++-
sys/dev/ic/athnvar.h | 4 +-
sys/dev/ic/atw.c | 82 +++++++++-
sys/dev/ic/atwvar.h | 4 +-
sys/dev/ic/awi.c | 49 ++++-
sys/dev/ic/awivar.h | 3 +-
sys/dev/ic/bwi.c | 289 +++++++++++++++++++++---------------
sys/dev/ic/bwivar.h | 3 +-
sys/dev/ic/malo.c | 51 +++++-
sys/dev/ic/malovar.h | 8 +-
sys/dev/ic/rt2560.c | 87 +++++++++--
sys/dev/ic/rt2560var.h | 3 +-
sys/dev/ic/rt2661.c | 67 +++++++-
sys/dev/ic/rt2661var.h | 3 +-
sys/dev/ic/rt2860.c | 62 +++++++-
sys/dev/ic/rt2860var.h | 3 +-
sys/dev/ic/rtw.c | 88 +++++++++-
sys/dev/ic/rtwvar.h | 3 +-
sys/dev/ic/wi.c | 130 +++++++++++++--
sys/dev/ic/wivar.h | 3 +-
sys/dev/pci/if_ipw.c | 81 ++++++++--
sys/dev/pci/if_ipwvar.h | 3 +-
sys/dev/pci/if_iwi.c | 96 ++++++++++-
sys/dev/pci/if_iwivar.h | 3 +-
sys/dev/pci/if_iwm.c | 49 ++---
sys/dev/pci/if_iwmvar.h | 3 +-
sys/dev/pci/if_iwn.c | 85 +++++++--
sys/dev/pci/if_iwnvar.h | 4 +-
sys/dev/pci/if_malo_pci.c | 40 ++++-
sys/dev/pci/if_rtwn.c | 52 +++++-
sys/dev/pci/if_rtwnreg.h | 4 +-
sys/dev/pci/if_wpi.c | 79 ++++++++-
sys/dev/pci/if_wpivar.h | 3 +-
sys/dev/pcmcia/if_malo_pcmcia.c | 59 +++++-
sys/dev/pcmcia/if_malo_pcmciavar.h | 3 +-
sys/net80211/ieee80211_input.c | 7 +-
sys/net80211/ieee80211_proto.c | 7 +-
43 files changed, 1440 insertions(+), 412 deletions(-)
diffs (truncated from 5021 to 300 lines):
diff -r a72d0e61170c -r c71c6125e40a sys/dev/ic/an.c
--- a/sys/dev/ic/an.c Thu Feb 02 08:57:04 2017 +0000
+++ b/sys/dev/ic/an.c Thu Feb 02 10:05:35 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: an.c,v 1.63 2016/06/10 13:27:13 ozaki-r Exp $ */
+/* $NetBSD: an.c,v 1.64 2017/02/02 10:05:35 nonaka Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul%ctr.columbia.edu@localhost>. All rights reserved.
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: an.c,v 1.63 2016/06/10 13:27:13 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: an.c,v 1.64 2017/02/02 10:05:35 nonaka Exp $");
#include <sys/param.h>
@@ -96,6 +96,7 @@
#include <sys/kauth.h>
#include <sys/bus.h>
+#include <sys/intr.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -116,6 +117,7 @@
static int an_reset(struct an_softc *);
static void an_wait(struct an_softc *);
+static void an_softintr(void *);
static int an_init(struct ifnet *);
static void an_stop(struct ifnet *, int);
static void an_start(struct ifnet *);
@@ -178,6 +180,13 @@
return 1;
}
+ sc->sc_soft_ih = softint_establish(SOFTINT_NET, an_softintr, sc);
+ if (sc->sc_soft_ih == NULL) {
+ splx(s);
+ aprint_error_dev(sc->sc_dev, "failed to establish softint\n");
+ return 1;
+ }
+
/* Load factory config */
if (an_cmd(sc, AN_CMD_READCFG, 0) != 0) {
splx(s);
@@ -308,8 +317,10 @@
/*
* Call MI attach routine.
*/
- if_attach(ifp);
+ if_initialize(ifp);
ieee80211_ifattach(ic);
+ ifp->if_percpuq = if_percpuq_create(ifp);
+ if_register(ifp);
sc->sc_newstate = ic->ic_newstate;
ic->ic_newstate = an_newstate;
@@ -409,7 +420,10 @@
an_stop(ifp, 1);
ieee80211_ifdetach(ic);
if_detach(ifp);
+ if (sc->sc_soft_ih != NULL)
+ softint_disestablish(sc->sc_soft_ih);
splx(s);
+
return 0;
}
@@ -432,8 +446,6 @@
{
struct an_softc *sc = arg;
struct ifnet *ifp = &sc->sc_if;
- int i;
- u_int16_t status;
if (!sc->sc_enabled || !device_is_active(sc->sc_dev) ||
(ifp->if_flags & IFF_RUNNING) == 0)
@@ -445,15 +457,39 @@
return 1;
}
+ /* Disable interrupts */
+ CSR_WRITE_2(sc, AN_INT_EN, 0);
+
+ softint_schedule(sc->sc_soft_ih);
+ return 1;
+}
+
+static void
+an_softintr(void *arg)
+{
+ struct an_softc *sc = arg;
+ struct ifnet *ifp = &sc->sc_if;
+ int i, s;
+ uint16_t status;
+
+ if (!sc->sc_enabled || !device_is_active(sc->sc_dev) ||
+ (ifp->if_flags & IFF_RUNNING) == 0)
+ return;
+
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ CSR_WRITE_2(sc, AN_EVENT_ACK, ~0);
+ return;
+ }
+
/* maximum 10 loops per interrupt */
for (i = 0; i < 10; i++) {
if (!sc->sc_enabled || !device_is_active(sc->sc_dev))
- return 1;
+ return;
if (CSR_READ_2(sc, AN_SW0) != AN_MAGIC) {
DPRINTF(("an_intr: magic number changed: %x\n",
CSR_READ_2(sc, AN_SW0)));
config_deactivate(sc->sc_dev);
- return 1;
+ return;
}
status = CSR_READ_2(sc, AN_EVENT_STAT);
CSR_WRITE_2(sc, AN_EVENT_ACK, status & ~(AN_INTRS));
@@ -471,11 +507,17 @@
if ((ifp->if_flags & IFF_OACTIVE) == 0 &&
sc->sc_ic.ic_state == IEEE80211_S_RUN &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
+ !IFQ_IS_EMPTY(&ifp->if_snd)) {
+ s = splnet();
an_start(ifp);
+ splx(s);
+ }
}
+ if (i == 10)
+ softint_schedule(sc->sc_soft_ih);
- return 1;
+ /* Re-enable interrupts */
+ CSR_WRITE_2(sc, AN_INT_EN, AN_INTRS);
}
static int
@@ -1328,7 +1370,7 @@
struct an_rxframe frmhdr;
struct mbuf *m;
u_int16_t status;
- int fid, gaplen, len, off;
+ int fid, gaplen, len, off, s;
uint8_t *gap;
fid = CSR_READ_2(sc, AN_RX_FID);
@@ -1441,6 +1483,8 @@
m_set_rcvif(m, ifp);
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
+ s = splnet();
+
if (sc->sc_drvbpf) {
struct an_rx_radiotap_header *tap = &sc->sc_rxtap;
@@ -1473,13 +1517,17 @@
ieee80211_input(ic, m, ni, frmhdr.an_rx_signal_strength,
le32toh(frmhdr.an_rx_time));
ieee80211_free_node(ni);
+
+ splx(s);
}
static void
an_tx_intr(struct an_softc *sc, int status)
{
struct ifnet *ifp = &sc->sc_if;
- int cur, fid;
+ int cur, fid, s;
+
+ s = splnet();
sc->sc_tx_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
@@ -1513,7 +1561,7 @@
fid, cur);
}
- return;
+ splx(s);
}
static void
@@ -1521,11 +1569,13 @@
{
struct ieee80211com *ic = &sc->sc_ic;
u_int16_t status;
+ int s;
status = CSR_READ_2(sc, AN_LINKSTAT);
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_LINKSTAT);
DPRINTF(("an_linkstat_intr: status 0x%x\n", status));
+ s = splnet();
if (status == AN_LINKSTAT_ASSOCIATED) {
if (ic->ic_state != IEEE80211_S_RUN ||
ic->ic_opmode == IEEE80211_M_IBSS)
@@ -1534,6 +1584,7 @@
if (ic->ic_opmode == IEEE80211_M_STA)
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
}
+ splx(s);
}
/* Must be called at proper protection level! */
diff -r a72d0e61170c -r c71c6125e40a sys/dev/ic/anvar.h
--- a/sys/dev/ic/anvar.h Thu Feb 02 08:57:04 2017 +0000
+++ b/sys/dev/ic/anvar.h Thu Feb 02 10:05:35 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: anvar.h,v 1.20 2010/01/17 19:45:06 pooka Exp $ */
+/* $NetBSD: anvar.h,v 1.21 2017/02/02 10:05:35 nonaka Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul%ctr.columbia.edu@localhost>. All rights reserved.
@@ -108,6 +108,7 @@
struct ieee80211com sc_ic;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
+ void *sc_soft_ih;
int (*sc_enable)(struct an_softc *);
void (*sc_disable)(struct an_softc *);
int (*sc_newstate)(struct ieee80211com *,
diff -r a72d0e61170c -r c71c6125e40a sys/dev/ic/arn5008.c
--- a/sys/dev/ic/arn5008.c Thu Feb 02 08:57:04 2017 +0000
+++ b/sys/dev/ic/arn5008.c Thu Feb 02 10:05:35 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arn5008.c,v 1.11 2016/06/10 13:27:13 ozaki-r Exp $ */
+/* $NetBSD: arn5008.c,v 1.12 2017/02/02 10:05:35 nonaka Exp $ */
/* $OpenBSD: ar5008.c,v 1.21 2012/08/25 12:14:31 kettenis Exp $ */
/*-
@@ -24,7 +24,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arn5008.c,v 1.11 2016/06/10 13:27:13 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arn5008.c,v 1.12 2017/02/02 10:05:35 nonaka Exp $");
#include <sys/param.h>
#include <sys/sockio.h>
@@ -88,6 +88,7 @@
struct ieee80211_channel *);
Static void ar5008_init_baseband(struct athn_softc *);
Static void ar5008_init_chains(struct athn_softc *);
+Static int ar5008_intr_status(struct athn_softc *);
Static int ar5008_intr(struct athn_softc *);
Static void ar5008_next_calib(struct athn_softc *);
Static int ar5008_read_eep_word(struct athn_softc *, uint32_t,
@@ -175,6 +176,7 @@
ops->dma_alloc = ar5008_dma_alloc;
ops->dma_free = ar5008_dma_free;
ops->rx_enable = ar5008_rx_enable;
+ ops->intr_status = ar5008_intr_status;
ops->intr = ar5008_intr;
ops->tx = ar5008_tx;
@@ -797,7 +799,7 @@
struct ieee80211_node *ni;
struct mbuf *m, *m1;
u_int32_t rstamp;
- int error, len, rssi;
+ int error, len, rssi, s;
bf = SIMPLEQ_FIRST(&rxq->head);
if (__predict_false(bf == NULL)) { /* Should not happen. */
@@ -908,6 +910,8 @@
m_set_rcvif(m, ifp);
m->m_pkthdr.len = m->m_len = len;
+ s = splnet();
+
/* Grab a reference to the source node. */
wh = mtod(m, struct ieee80211_frame *);
ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
@@ -934,6 +938,8 @@
/* Node is no longer needed. */
ieee80211_free_node(ni);
+ splx(s);
+
skip:
/* Unlink this descriptor from head. */
SIMPLEQ_REMOVE_HEAD(&rxq->head, bf_list);
@@ -1031,7 +1037,9 @@
struct ifnet *ifp = &sc->sc_if;
uint16_t mask = 0;
uint32_t reg;
- int qid;
+ int qid, s;
+
+ s = splnet();
reg = AR_READ(sc, AR_ISR_S0_S);
mask |= MS(reg, AR_ISR_S0_QCU_TXOK);
@@ -1050,6 +1058,8 @@
Home |
Main Index |
Thread Index |
Old Index