summaryrefslogtreecommitdiffstats
path: root/sys/dev/malo/if_malo.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/malo/if_malo.c')
-rw-r--r--sys/dev/malo/if_malo.c439
1 files changed, 178 insertions, 261 deletions
diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c
index 7418379..2790fdc 100644
--- a/sys/dev/malo/if_malo.c
+++ b/sys/dev/malo/if_malo.c
@@ -102,13 +102,9 @@ enum {
(IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON))
#define IFF_DUMPPKTS_RECV(sc, wh) \
(((sc->malo_debug & MALO_DEBUG_RECV) && \
- ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \
- (sc->malo_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == \
- (IFF_DEBUG|IFF_LINK2))
+ ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))))
#define IFF_DUMPPKTS_XMIT(sc) \
- ((sc->malo_debug & MALO_DEBUG_XMIT) || \
- (sc->malo_ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == \
- (IFF_DEBUG | IFF_LINK2))
+ (sc->malo_debug & MALO_DEBUG_XMIT)
#define DPRINTF(sc, m, fmt, ...) do { \
if (sc->malo_debug & (m)) \
printf(fmt, __VA_ARGS__); \
@@ -130,9 +126,10 @@ static int malo_dma_setup(struct malo_softc *);
static int malo_setup_hwdma(struct malo_softc *);
static void malo_txq_init(struct malo_softc *, struct malo_txq *, int);
static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
-static void malo_start(struct ifnet *);
+static void malo_parent(struct ieee80211com *);
+static int malo_transmit(struct ieee80211com *, struct mbuf *);
+static void malo_start(struct malo_softc *);
static void malo_watchdog(void *);
-static int malo_ioctl(struct ifnet *, u_long, caddr_t);
static void malo_updateslot(struct ieee80211com *);
static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void malo_scan_start(struct ieee80211com *);
@@ -143,7 +140,7 @@ static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *,
static void malo_sysctlattach(struct malo_softc *);
static void malo_announce(struct malo_softc *);
static void malo_dma_cleanup(struct malo_softc *);
-static void malo_stop_locked(struct ifnet *, int);
+static void malo_stop(struct malo_softc *);
static int malo_chan_set(struct malo_softc *, struct ieee80211_channel *);
static int malo_mode_init(struct malo_softc *);
static void malo_tx_proc(void *, int);
@@ -173,30 +170,19 @@ malo_bar0_write4(struct malo_softc *sc, bus_size_t off, uint32_t val)
int
malo_attach(uint16_t devid, struct malo_softc *sc)
{
- int error;
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_hal *mh;
+ int error;
uint8_t bands;
- ifp = sc->malo_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->malo_dev, "can not if_alloc()\n");
- return ENOSPC;
- }
- ic = ifp->if_l2com;
-
MALO_LOCK_INIT(sc);
callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0);
-
- /* set these up early for if_printf use */
- if_initname(ifp, device_get_name(sc->malo_dev),
- device_get_unit(sc->malo_dev));
+ mbufq_init(&sc->malo_snd, ifqmaxlen);
mh = malo_hal_attach(sc->malo_dev, devid,
sc->malo_io1h, sc->malo_io1t, sc->malo_dmat);
if (mh == NULL) {
- if_printf(ifp, "unable to attach HAL\n");
+ device_printf(sc->malo_dev, "unable to attach HAL\n");
error = EIO;
goto bad;
}
@@ -209,13 +195,13 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
*/
error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m");
if (error != 0) {
- if_printf(ifp, "unable to setup firmware\n");
+ device_printf(sc->malo_dev, "unable to setup firmware\n");
goto bad1;
}
/* XXX gethwspecs() extracts correct informations? not maybe! */
error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs);
if (error != 0) {
- if_printf(ifp, "unable to fetch h/w specs\n");
+ device_printf(sc->malo_dev, "unable to fetch h/w specs\n");
goto bad1;
}
@@ -251,7 +237,8 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
*/
error = malo_dma_setup(sc);
if (error != 0) {
- if_printf(ifp, "failed to setup descriptors: %d\n", error);
+ device_printf(sc->malo_dev,
+ "failed to setup descriptors: %d\n", error);
goto bad1;
}
error = malo_setup_hwdma(sc); /* push to firmware */
@@ -261,21 +248,11 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT,
taskqueue_thread_enqueue, &sc->malo_tq);
taskqueue_start_threads(&sc->malo_tq, 1, PI_NET,
- "%s taskq", ifp->if_xname);
+ "%s taskq", device_get_nameunit(sc->malo_dev));
TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc);
TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc);
- ifp->if_softc = sc;
- ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
- ifp->if_start = malo_start;
- ifp->if_ioctl = malo_ioctl;
- ifp->if_init = malo_init;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(sc->malo_dev);
/* XXX not right but it's not used anywhere important */
@@ -290,6 +267,7 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
| IEEE80211_C_TXPMGT /* capable of txpow mgt */
| IEEE80211_C_WPA /* capable of WPA1+WPA2 */
;
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->malo_hwspecs.macaddr);
/*
* Transmit requires space in the packet for a special format transmit
@@ -301,16 +279,17 @@ malo_attach(uint16_t devid, struct malo_softc *sc)
sizeof(struct ieee80211_frame);
/* call MI attach routine. */
- ieee80211_ifattach(ic, sc->malo_hwspecs.macaddr);
+ ieee80211_ifattach(ic);
/* override default methods */
ic->ic_vap_create = malo_vap_create;
ic->ic_vap_delete = malo_vap_delete;
ic->ic_raw_xmit = malo_raw_xmit;
ic->ic_updateslot = malo_updateslot;
-
ic->ic_scan_start = malo_scan_start;
ic->ic_scan_end = malo_scan_end;
ic->ic_set_channel = malo_set_channel;
+ ic->ic_parent = malo_parent;
+ ic->ic_transmit = malo_transmit;
sc->malo_invalid = 0; /* ready to go, enable int handling */
@@ -335,7 +314,6 @@ bad2:
bad1:
malo_hal_detach(mh);
bad:
- if_free(ifp);
sc->malo_invalid = 1;
return error;
@@ -347,12 +325,12 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct ifnet *ifp = ic->ic_ifp;
+ struct malo_softc *sc = ic->ic_softc;
struct malo_vap *mvp;
struct ieee80211vap *vap;
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- if_printf(ifp, "multiple vaps not supported\n");
+ device_printf(sc->malo_dev, "multiple vaps not supported\n");
return NULL;
}
switch (opmode) {
@@ -363,18 +341,13 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MONITOR:
break;
default:
- if_printf(ifp, "%s mode not supported\n",
+ device_printf(sc->malo_dev, "%s mode not supported\n",
ieee80211_opmode_name[opmode]);
return NULL; /* unsupported */
}
- mvp = (struct malo_vap *) malloc(sizeof(struct malo_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (mvp == NULL) {
- if_printf(ifp, "cannot allocate vap state block\n");
- return NULL;
- }
+ mvp = malloc(sizeof(struct malo_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &mvp->malo_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
/* override state transition machine */
mvp->malo_newstate = vap->iv_newstate;
@@ -382,7 +355,7 @@ malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* complete setup */
ieee80211_vap_attach(vap,
- ieee80211_media_change, ieee80211_media_status);
+ ieee80211_media_change, ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -461,7 +434,6 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
int nbuf, size_t bufsize, int ndesc, size_t descsize)
{
int error;
- struct ifnet *ifp = sc->malo_ifp;
uint8_t *ds;
DPRINTF(sc, MALO_DEBUG_RESET,
@@ -488,7 +460,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
NULL, /* lockarg */
&dd->dd_dmat);
if (error != 0) {
- if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name);
+ device_printf(sc->malo_dev, "cannot allocate %s DMA tag\n",
+ dd->dd_name);
return error;
}
@@ -496,7 +469,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc,
BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to alloc memory for %u %s descriptors, "
+ device_printf(sc->malo_dev,
+ "unable to alloc memory for %u %s descriptors, "
"error %u\n", nbuf * ndesc, dd->dd_name, error);
goto fail1;
}
@@ -505,7 +479,8 @@ malo_desc_setup(struct malo_softc *sc, const char *name,
dd->dd_desc, dd->dd_desc_len,
malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT);
if (error != 0) {
- if_printf(ifp, "unable to map %s descriptors, error %u\n",
+ device_printf(sc->malo_dev,
+ "unable to map %s descriptors, error %u\n",
dd->dd_name, error);
goto fail2;
}
@@ -532,7 +507,6 @@ fail1:
static int
malo_rxdma_setup(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
int error, bsize, i;
struct malo_rxbuf *bf;
struct malo_rxdesc *ds;
@@ -549,7 +523,8 @@ malo_rxdma_setup(struct malo_softc *sc)
bsize = malo_rxbuf * sizeof(struct malo_rxbuf);
bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %u rx buffers failed\n", bsize);
+ device_printf(sc->malo_dev,
+ "malloc of %u rx buffers failed\n", bsize);
return error;
}
sc->malo_rxdma.dd_bufptr = bf;
@@ -562,8 +537,9 @@ malo_rxdma_setup(struct malo_softc *sc)
error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
&bf->bf_dmamap);
if (error != 0) {
- if_printf(ifp, "%s: unable to dmamap for rx buffer, "
- "error %d\n", __func__, error);
+ device_printf(sc->malo_dev,
+ "%s: unable to dmamap for rx buffer, error %d\n",
+ __func__, error);
return error;
}
/* NB: tail is intentional to preserve descriptor order */
@@ -575,7 +551,6 @@ malo_rxdma_setup(struct malo_softc *sc)
static int
malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
{
- struct ifnet *ifp = sc->malo_ifp;
int error, bsize, i;
struct malo_txbuf *bf;
struct malo_txdesc *ds;
@@ -590,7 +565,7 @@ malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
bsize = malo_txbuf * sizeof(struct malo_txbuf);
bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO);
if (bf == NULL) {
- if_printf(ifp, "malloc of %u tx buffers failed\n",
+ device_printf(sc->malo_dev, "malloc of %u tx buffers failed\n",
malo_txbuf);
return ENOMEM;
}
@@ -605,7 +580,8 @@ malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq)
error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT,
&bf->bf_dmamap);
if (error != 0) {
- if_printf(ifp, "unable to create dmamap for tx "
+ device_printf(sc->malo_dev,
+ "unable to create dmamap for tx "
"buffer %u, error %u\n", i, error);
return error;
}
@@ -1004,33 +980,19 @@ malo_tx_processq(struct malo_softc *sc, struct malo_txq *txq)
if (status & MALO_TXD_STATUS_FAILED_AGING)
sc->malo_stats.mst_tx_aging++;
}
- /*
- * Do any tx complete callback. Note this must
- * be done before releasing the node reference.
- * XXX no way to figure out if frame was ACK'd
- */
- if (bf->bf_m->m_flags & M_TXCB) {
- /* XXX strip fw len in case header inspected */
- m_adj(bf->bf_m, sizeof(uint16_t));
- ieee80211_process_callback(ni, bf->bf_m,
- (status & MALO_TXD_STATUS_OK) == 0);
- }
- /*
- * Reclaim reference to node.
- *
- * NB: the node may be reclaimed here if, for example
- * this is a DEAUTH message that was sent and the
- * node was timed out due to inactivity.
- */
- ieee80211_free_node(ni);
- }
+ /* XXX strip fw len in case header inspected */
+ m_adj(bf->bf_m, sizeof(uint16_t));
+ ieee80211_tx_complete(ni, bf->bf_m,
+ (status & MALO_TXD_STATUS_OK) == 0);
+ } else
+ m_freem(bf->bf_m);
+
ds->status = htole32(MALO_TXD_STATUS_IDLE);
ds->pktlen = htole32(0);
bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap);
- m_freem(bf->bf_m);
bf->bf_m = NULL;
bf->bf_node = NULL;
@@ -1049,23 +1011,23 @@ static void
malo_tx_proc(void *arg, int npending)
{
struct malo_softc *sc = arg;
- struct ifnet *ifp = sc->malo_ifp;
int i, nreaped;
/*
* Process each active queue.
*/
nreaped = 0;
+ MALO_LOCK(sc);
for (i = 0; i < MALO_NUM_TX_QUEUES; i++) {
if (!STAILQ_EMPTY(&sc->malo_txq[i].active))
nreaped += malo_tx_processq(sc, &sc->malo_txq[i]);
}
if (nreaped != 0) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
sc->malo_timer = 0;
- malo_start(ifp);
+ malo_start(sc);
}
+ MALO_UNLOCK(sc);
}
static int
@@ -1079,8 +1041,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
int error, ismcast, iswep;
int copyhdrlen, hdrlen, pktlen;
struct ieee80211_frame *wh;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct malo_txdesc *ds;
struct malo_txrec *tr;
@@ -1225,7 +1186,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
ds->txpriority = txq->qnum;
break;
default:
- if_printf(ifp, "bogus frame type 0x%x (%s)\n",
+ device_printf(sc->malo_dev, "bogus frame type 0x%x (%s)\n",
wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
/* XXX statistic */
m_freem(m0);
@@ -1246,37 +1207,52 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni,
STAILQ_INSERT_TAIL(&txq->active, bf, bf_list);
MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
sc->malo_timer = 5;
MALO_TXQ_UNLOCK(txq);
return 0;
#undef IEEE80211_DIR_DSTODS
}
+static int
+malo_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct malo_softc *sc = ic->ic_softc;
+ int error;
+
+ MALO_LOCK(sc);
+ if (!sc->malo_running) {
+ MALO_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->malo_snd, m);
+ if (error) {
+ MALO_UNLOCK(sc);
+ return (error);
+ }
+ malo_start(sc);
+ MALO_UNLOCK(sc);
+ return (0);
+}
+
static void
-malo_start(struct ifnet *ifp)
+malo_start(struct malo_softc *sc)
{
- struct malo_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct malo_txq *txq = &sc->malo_txq[0];
struct malo_txbuf *bf = NULL;
struct mbuf *m;
int nqueued = 0;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid)
+ MALO_LOCK_ASSERT(sc);
+
+ if (!sc->malo_running || sc->malo_invalid)
return;
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->malo_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
bf = malo_getbuf(sc, txq);
if (bf == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
-
- /* XXX blocks other traffic */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ mbufq_prepend(&sc->malo_snd, m);
sc->malo_stats.mst_tx_qstop++;
break;
}
@@ -1284,7 +1260,8 @@ malo_start(struct ifnet *ifp)
* Pass the frame to the h/w for transmission.
*/
if (malo_tx_start(sc, ni, bf, m)) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
if (bf != NULL) {
bf->bf_m = NULL;
bf->bf_node = NULL;
@@ -1328,21 +1305,18 @@ malo_start(struct ifnet *ifp)
static void
malo_watchdog(void *arg)
{
- struct malo_softc *sc;
- struct ifnet *ifp;
+ struct malo_softc *sc = arg;
- sc = arg;
callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
if (sc->malo_timer == 0 || --sc->malo_timer > 0)
return;
- ifp = sc->malo_ifp;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->malo_invalid) {
- if_printf(ifp, "watchdog timeout\n");
+ if (sc->malo_running && !sc->malo_invalid) {
+ device_printf(sc->malo_dev, "watchdog timeout\n");
/* XXX no way to reset h/w. now */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->malo_ic.ic_oerrors, 1);
sc->malo_stats.mst_watchdog++;
}
}
@@ -1351,8 +1325,7 @@ static int
malo_hal_reset(struct malo_softc *sc)
{
static int first = 0;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_hal *mh = sc->malo_mh;
if (first == 0) {
@@ -1392,7 +1365,7 @@ malo_getrxmbuf(struct malo_softc *sc, struct malo_rxbuf *bf)
mtod(m, caddr_t), MJUMPAGESIZE,
malo_load_cb, &paddr, BUS_DMA_NOWAIT);
if (error != 0) {
- if_printf(sc->malo_ifp,
+ device_printf(sc->malo_dev,
"%s: bus_dmamap_load failed, error %d\n", __func__, error);
m_freem(m);
return NULL;
@@ -1483,26 +1456,23 @@ malo_startrecv(struct malo_softc *sc)
static void
malo_init_locked(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
struct malo_hal *mh = sc->malo_mh;
int error;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n",
- __func__, ifp->if_flags);
-
MALO_LOCK_ASSERT(sc);
/*
* Stop anything previously setup. This is safe whether this is
* the first time through or not.
*/
- malo_stop_locked(ifp, 0);
+ malo_stop(sc);
/*
* Push state to the firmware.
*/
if (!malo_hal_reset(sc)) {
- if_printf(ifp, "%s: unable to reset hardware\n", __func__);
+ device_printf(sc->malo_dev,
+ "%s: unable to reset hardware\n", __func__);
return;
}
@@ -1511,7 +1481,8 @@ malo_init_locked(struct malo_softc *sc)
*/
error = malo_startrecv(sc);
if (error != 0) {
- if_printf(ifp, "%s: unable to start recv logic, error %d\n",
+ device_printf(sc->malo_dev,
+ "%s: unable to start recv logic, error %d\n",
__func__, error);
return;
}
@@ -1528,7 +1499,7 @@ malo_init_locked(struct malo_softc *sc)
| MALO_A2HRIC_BIT_RADAR_DETECT
| MALO_A2HRIC_BIT_CHAN_SWITCH;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->malo_running = 1;
malo_hal_intrset(mh, sc->malo_imask);
callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
}
@@ -1537,18 +1508,13 @@ static void
malo_init(void *arg)
{
struct malo_softc *sc = (struct malo_softc *) arg;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n",
- __func__, ifp->if_flags);
-
MALO_LOCK(sc);
malo_init_locked(sc);
-
MALO_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->malo_running)
ieee80211_start_all(ic); /* start all vap's */
}
@@ -1558,9 +1524,8 @@ malo_init(void *arg)
static void
malo_setmcastfilter(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifmultiaddr *ifma;
+ struct ieee80211com *ic = &sc->malo_ic;
+ struct ieee80211vap *vap;
uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX];
uint8_t *mp;
int nmc;
@@ -1568,26 +1533,32 @@ malo_setmcastfilter(struct malo_softc *sc)
mp = macs;
nmc = 0;
- if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)))
+ if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 ||
+ ic->ic_promisc > 0)
goto all;
-
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- if (nmc == MALO_HAL_MCAST_MAX) {
- ifp->if_flags |= IFF_ALLMULTI;
- if_maddr_runlock(ifp);
- goto all;
- }
- IEEE80211_ADDR_COPY(mp,
- LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ struct ifnet *ifp;
+ struct ifmultiaddr *ifma;
+
+ ifp = vap->iv_ifp;
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+
+ if (nmc == MALO_HAL_MCAST_MAX) {
+ ifp->if_flags |= IFF_ALLMULTI;
+ if_maddr_runlock(ifp);
+ goto all;
+ }
+ IEEE80211_ADDR_COPY(mp,
+ LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
- mp += IEEE80211_ADDR_LEN, nmc++;
+ mp += IEEE80211_ADDR_LEN, nmc++;
+ }
+ if_maddr_runlock(ifp);
}
- if_maddr_runlock(ifp);
malo_hal_setmcast(sc->malo_mh, nmc, macs);
@@ -1602,8 +1573,7 @@ all:
static int
malo_mode_init(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_hal *mh = sc->malo_mh;
/*
@@ -1612,7 +1582,7 @@ malo_mode_init(struct malo_softc *sc)
* identify internal requests (from the bridge)
* versus external requests such as for tcpdump.
*/
- malo_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) &&
+ malo_hal_setpromisc(mh, ic->ic_promisc > 0 &&
ic->ic_opmode != IEEE80211_M_HOSTAP);
malo_setmcastfilter(sc);
@@ -1641,8 +1611,7 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq)
MALO_TXQ_UNLOCK(txq);
#ifdef MALO_DEBUG
if (sc->malo_debug & MALO_DEBUG_RESET) {
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
const struct malo_txrec *tr =
mtod(bf->bf_m, const struct malo_txrec *);
malo_printtxbuf(bf, txq->qnum, ix);
@@ -1670,18 +1639,17 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq)
}
static void
-malo_stop_locked(struct ifnet *ifp, int disable)
+malo_stop(struct malo_softc *sc)
{
- struct malo_softc *sc = ifp->if_softc;
struct malo_hal *mh = sc->malo_mh;
int i;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n",
- __func__, sc->malo_invalid, ifp->if_flags);
+ DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u running %u\n",
+ __func__, sc->malo_invalid, sc->malo_running);
MALO_LOCK_ASSERT(sc);
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!sc->malo_running)
return;
/*
@@ -1693,10 +1661,10 @@ malo_stop_locked(struct ifnet *ifp, int disable)
* Note that some of this work is not possible if the hardware
* is gone (invalid).
*/
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ sc->malo_running = 0;
callout_stop(&sc->malo_watchdog_timer);
sc->malo_timer = 0;
- /* diable interrupt. */
+ /* disable interrupt. */
malo_hal_intrset(mh, 0);
/* turn off the radio. */
malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE);
@@ -1706,57 +1674,38 @@ malo_stop_locked(struct ifnet *ifp, int disable)
malo_tx_draintxq(sc, &sc->malo_txq[i]);
}
-static int
-malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+malo_parent(struct ieee80211com *ic)
{
-#define MALO_IS_RUNNING(ifp) \
- ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- struct malo_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct malo_softc *sc = ic->ic_softc;
+ int startall = 0;
MALO_LOCK(sc);
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (MALO_IS_RUNNING(ifp)) {
- /*
- * To avoid rescanning another access point,
- * do not call malo_init() here. Instead,
- * only reflect promisc mode settings.
- */
- malo_mode_init(sc);
- } else if (ifp->if_flags & IFF_UP) {
- /*
- * Beware of being called during attach/detach
- * to reset promiscuous mode. In that case we
- * will still be marked UP but not RUNNING.
- * However trying to re-init the interface
- * is the wrong thing to do as we've already
- * torn down much of our state. There's
- * probably a better way to deal with this.
- */
- if (!sc->malo_invalid) {
- malo_init_locked(sc);
- startall = 1;
- }
- } else
- malo_stop_locked(ifp, 1);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
- }
+ if (ic->ic_nrunning > 0) {
+ /*
+ * Beware of being called during attach/detach
+ * to reset promiscuous mode. In that case we
+ * will still be marked UP but not RUNNING.
+ * However trying to re-init the interface
+ * is the wrong thing to do as we've already
+ * torn down much of our state. There's
+ * probably a better way to deal with this.
+ */
+ if (!sc->malo_running && !sc->malo_invalid) {
+ malo_init(sc);
+ startall = 1;
+ }
+ /*
+ * To avoid rescanning another access point,
+ * do not call malo_init() here. Instead,
+ * only reflect promisc mode settings.
+ */
+ malo_mode_init(sc);
+ } else if (sc->malo_running)
+ malo_stop(sc);
MALO_UNLOCK(sc);
-
if (startall)
ieee80211_start_all(ic);
- return error;
-#undef MALO_IS_RUNNING
}
/*
@@ -1773,7 +1722,7 @@ malo_updateslot(struct ieee80211com *ic)
int error;
/* NB: can be called early; suppress needless cmds */
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if (!sc->malo_running)
return;
DPRINTF(sc, MALO_DEBUG_RESET,
@@ -1795,7 +1744,7 @@ static int
malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct malo_softc *sc = ic->ic_ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
struct malo_hal *mh = sc->malo_mh;
int error;
@@ -1839,12 +1788,11 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
struct malo_txbuf *bf;
struct malo_txq *txq;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) {
+ if (!sc->malo_running || sc->malo_invalid) {
ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
@@ -1859,8 +1807,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
txq = &sc->malo_txq[0];
bf = malo_getbuf(sc, txq);
if (bf == NULL) {
- /* XXX blocks other traffic */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
ieee80211_free_node(ni);
m_freem(m);
return ENOBUFS;
@@ -1870,7 +1816,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
* Pass the frame to the h/w for transmission.
*/
if (malo_tx_start(sc, ni, bf, m) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
bf->bf_m = NULL;
bf->bf_node = NULL;
MALO_TXQ_LOCK(txq);
@@ -1915,9 +1860,9 @@ malo_sysctlattach(struct malo_softc *sc)
static void
malo_announce(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- if_printf(ifp, "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n",
+ device_printf(sc->malo_dev,
+ "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n",
sc->malo_hwspecs.hwversion,
(sc->malo_hwspecs.fw_releasenum >> 24) & 0xff,
(sc->malo_hwspecs.fw_releasenum >> 16) & 0xff,
@@ -1926,9 +1871,11 @@ malo_announce(struct malo_softc *sc)
sc->malo_hwspecs.regioncode);
if (bootverbose || malo_rxbuf != MALO_RXBUF)
- if_printf(ifp, "using %u rx buffers\n", malo_rxbuf);
+ device_printf(sc->malo_dev,
+ "using %u rx buffers\n", malo_rxbuf);
if (bootverbose || malo_txbuf != MALO_TXBUF)
- if_printf(ifp, "using %u tx buffers\n", malo_txbuf);
+ device_printf(sc->malo_dev,
+ "using %u tx buffers\n", malo_txbuf);
}
/*
@@ -1989,8 +1936,7 @@ malo_chan_set(struct malo_softc *sc, struct ieee80211_channel *chan)
static void
malo_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
}
@@ -1998,8 +1944,7 @@ malo_scan_start(struct ieee80211com *ic)
static void
malo_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__);
}
@@ -2007,8 +1952,7 @@ malo_scan_end(struct ieee80211com *ic)
static void
malo_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct malo_softc *sc = ifp->if_softc;
+ struct malo_softc *sc = ic->ic_softc;
(void) malo_chan_set(sc, ic->ic_curchan);
}
@@ -2020,8 +1964,7 @@ malo_rx_proc(void *arg, int npending)
((((const struct ieee80211_frame *)wh)->i_fc[1] & \
IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
struct malo_softc *sc = arg;
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
struct malo_rxbuf *bf;
struct malo_rxdesc *ds;
struct mbuf *m, *mnew;
@@ -2078,7 +2021,7 @@ malo_rx_proc(void *arg, int npending)
#endif
status = ds->status;
if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto rx_next;
}
/*
@@ -2117,7 +2060,7 @@ malo_rx_proc(void *arg, int npending)
/* XXX don't need mbuf, just dma buffer */
mnew = malo_getrxmbuf(sc, bf);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto rx_next;
}
/*
@@ -2128,7 +2071,6 @@ malo_rx_proc(void *arg, int npending)
bf->bf_m = mnew;
m->m_data += off - hdrlen;
m->m_pkthdr.len = m->m_len = pktlen;
- m->m_pkthdr.rcvif = ifp;
/*
* Piece 802.11 header together.
@@ -2158,8 +2100,6 @@ malo_rx_proc(void *arg, int npending)
len, ds->rate, rssi);
}
#endif
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
-
/* dispatch */
ni = ieee80211_find_rxnode(ic,
(struct ieee80211_frame_min *)wh);
@@ -2177,22 +2117,11 @@ rx_next:
malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr);
sc->malo_rxnext = bf;
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- malo_start(ifp);
+ if (mbufq_first(&sc->malo_snd) != NULL)
+ malo_start(sc);
#undef IEEE80211_DIR_DSTODS
}
-static void
-malo_stop(struct ifnet *ifp, int disable)
-{
- struct malo_softc *sc = ifp->if_softc;
-
- MALO_LOCK(sc);
- malo_stop_locked(ifp, disable);
- MALO_UNLOCK(sc);
-}
-
/*
* Reclaim all tx queue resources.
*/
@@ -2208,13 +2137,9 @@ malo_tx_cleanup(struct malo_softc *sc)
int
malo_detach(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->malo_ic;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- malo_stop(ifp, 1);
+ malo_stop(sc);
if (sc->malo_tq != NULL) {
taskqueue_drain(sc->malo_tq, &sc->malo_rxtask);
@@ -2240,8 +2165,7 @@ malo_detach(struct malo_softc *sc)
malo_dma_cleanup(sc);
malo_tx_cleanup(sc);
malo_hal_detach(sc->malo_mh);
- if_free(ifp);
-
+ mbufq_drain(&sc->malo_snd);
MALO_LOCK_DESTROY(sc);
return 0;
@@ -2250,28 +2174,21 @@ malo_detach(struct malo_softc *sc)
void
malo_shutdown(struct malo_softc *sc)
{
- malo_stop(sc->malo_ifp, 1);
+
+ malo_stop(sc);
}
void
malo_suspend(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
-
- malo_stop(ifp, 1);
+ malo_stop(sc);
}
void
malo_resume(struct malo_softc *sc)
{
- struct ifnet *ifp = sc->malo_ifp;
-
- DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n",
- __func__, ifp->if_flags);
- if (ifp->if_flags & IFF_UP)
+ if (sc->malo_ic.ic_nrunning > 0)
malo_init(sc);
}
OpenPOWER on IntegriCloud