summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/wlan/if_rsu.c299
-rw-r--r--sys/dev/usb/wlan/if_rsureg.h9
-rw-r--r--sys/dev/usb/wlan/if_rum.c302
-rw-r--r--sys/dev/usb/wlan/if_rumvar.h7
-rw-r--r--sys/dev/usb/wlan/if_run.c363
-rw-r--r--sys/dev/usb/wlan/if_runvar.h9
-rw-r--r--sys/dev/usb/wlan/if_uath.c308
-rw-r--r--sys/dev/usb/wlan/if_uathvar.h3
-rw-r--r--sys/dev/usb/wlan/if_upgt.c323
-rw-r--r--sys/dev/usb/wlan/if_upgtvar.h6
-rw-r--r--sys/dev/usb/wlan/if_ural.c284
-rw-r--r--sys/dev/usb/wlan/if_uralvar.h7
-rw-r--r--sys/dev/usb/wlan/if_urtw.c338
-rw-r--r--sys/dev/usb/wlan/if_urtwn.c282
-rw-r--r--sys/dev/usb/wlan/if_urtwnreg.h5
-rw-r--r--sys/dev/usb/wlan/if_urtwvar.h6
-rw-r--r--sys/dev/usb/wlan/if_zyd.c299
-rw-r--r--sys/dev/usb/wlan/if_zydreg.h5
18 files changed, 1057 insertions, 1798 deletions
diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c
index 89b8c00..463a9bd 100644
--- a/sys/dev/usb/wlan/if_rsu.c
+++ b/sys/dev/usb/wlan/if_rsu.c
@@ -187,15 +187,13 @@ static struct mbuf *
static void rsu_txeof(struct usb_xfer *, struct rsu_data *);
static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void rsu_init(void *);
-static void rsu_init_locked(struct rsu_softc *);
+static void rsu_init(struct rsu_softc *);
static int rsu_tx_start(struct rsu_softc *, struct ieee80211_node *,
struct mbuf *, struct rsu_data *);
-static void rsu_start(struct ifnet *);
-static void rsu_start_locked(struct ifnet *);
-static int rsu_ioctl(struct ifnet *, u_long, caddr_t);
-static void rsu_stop(struct ifnet *, int);
-static void rsu_stop_locked(struct ifnet *, int);
+static int rsu_transmit(struct ieee80211com *, struct mbuf *);
+static void rsu_start(struct rsu_softc *);
+static void rsu_parent(struct ieee80211com *);
+static void rsu_stop(struct rsu_softc *);
static void rsu_ms_delay(struct rsu_softc *);
static device_method_t rsu_methods[] = {
@@ -285,8 +283,7 @@ rsu_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct rsu_softc *sc = device_get_softc(self);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
int error;
uint8_t iface_index, bands;
@@ -298,6 +295,7 @@ rsu_attach(device_t self)
MTX_DEF);
TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_task, 0,
rsu_calib_task, sc);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/* Allocate Tx/Rx buffers. */
error = rsu_alloc_rx_list(sc);
@@ -333,28 +331,9 @@ rsu_attach(device_t self)
device_printf(self, "could not read ROM\n");
goto fail_rom;
}
- IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->rom[0x12]);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, &sc->rom[0x12]);
device_printf(self, "MAC/BB RTL8712 cut %d\n", sc->cut);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(self, "cannot allocate interface\n");
- goto fail_ifalloc;
- }
- ic = ifp->if_l2com;
- ifp->if_softc = sc;
- if_initname(ifp, "rsu", device_get_unit(self));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rsu_init;
- ifp->if_ioctl = rsu_ioctl;
- ifp->if_start = rsu_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
- ifp->if_capabilities |= IFCAP_RXCSUM;
- ifp->if_capenable |= IFCAP_RXCSUM;
- ifp->if_hwassist = CSUM_TCP;
-
- ic->ic_ifp = ifp;
+
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */
@@ -387,7 +366,7 @@ rsu_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = rsu_raw_xmit;
ic->ic_scan_start = rsu_scan_start;
ic->ic_scan_end = rsu_scan_end;
@@ -395,6 +374,8 @@ rsu_attach(device_t self)
ic->ic_vap_create = rsu_vap_create;
ic->ic_vap_delete = rsu_vap_delete;
ic->ic_update_mcast = rsu_update_mcast;
+ ic->ic_parent = rsu_parent;
+ ic->ic_transmit = rsu_transmit;
ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr,
sizeof(sc->sc_txtap), RSU_TX_RADIOTAP_PRESENT,
@@ -406,7 +387,6 @@ rsu_attach(device_t self)
return (0);
-fail_ifalloc:
fail_rom:
usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
fail_usb:
@@ -418,10 +398,11 @@ static int
rsu_detach(device_t self)
{
struct rsu_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
- rsu_stop(ifp, 1);
+ RSU_LOCK(sc);
+ rsu_stop(sc);
+ RSU_UNLOCK(sc);
usbd_transfer_unsetup(sc->sc_xfer, RSU_N_TRANSFER);
ieee80211_ifdetach(ic);
@@ -431,7 +412,7 @@ rsu_detach(device_t self)
rsu_free_tx_list(sc);
rsu_free_rx_list(sc);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -471,14 +452,11 @@ rsu_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct rsu_vap *) malloc(sizeof(struct rsu_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct rsu_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags, bssid, mac) != 0) {
+ flags, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -490,7 +468,7 @@ rsu_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_status, mac);
ic->ic_opmode = opmode;
return (vap);
@@ -508,9 +486,8 @@ rsu_vap_delete(struct ieee80211vap *vap)
static void
rsu_scan_start(struct ieee80211com *ic)
{
+ struct rsu_softc *sc = ic->ic_softc;
int error;
- struct ifnet *ifp = ic->ic_ifp;
- struct rsu_softc *sc = ifp->if_softc;
/* Scanning is done by the firmware. */
RSU_LOCK(sc);
@@ -676,11 +653,8 @@ rsu_getbuf(struct rsu_softc *sc)
RSU_ASSERT_LOCKED(sc);
bf = _rsu_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
+ if (bf == NULL)
DPRINTF("stop queue\n");
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -935,7 +909,7 @@ rsu_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rsu_vap *uvp = RSU_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rsu_softc *sc = ic->ic_ifp->if_softc;
+ struct rsu_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
struct ieee80211_rateset *rs;
enum ieee80211_state ostate;
@@ -1033,29 +1007,27 @@ static int
rsu_site_survey(struct rsu_softc *sc, struct ieee80211vap *vap)
{
struct r92s_fw_cmd_sitesurvey cmd;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
memset(&cmd, 0, sizeof(cmd));
- if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1)
+ if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->sc_scan_pass == 1)
cmd.active = htole32(1);
cmd.limit = htole32(48);
- if (sc->scan_pass == 1 && vap->iv_des_nssid > 0) {
+ if (sc->sc_scan_pass == 1 && vap->iv_des_nssid > 0) {
/* Do a directed scan for second pass. */
cmd.ssidlen = htole32(vap->iv_des_ssid[0].len);
memcpy(cmd.ssid, vap->iv_des_ssid[0].ssid,
vap->iv_des_ssid[0].len);
}
- DPRINTF("sending site survey command, pass=%d\n", sc->scan_pass);
+ DPRINTF("sending site survey command, pass=%d\n", sc->sc_scan_pass);
return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd)));
}
static int
rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ndis_wlan_bssid_ex *bss;
struct ndis_802_11_fixed_ies *fixed;
@@ -1133,8 +1105,7 @@ rsu_disconnect(struct rsu_softc *sc)
static void
rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_channel *c;
struct ndis_wlan_bssid_ex *bss;
@@ -1165,7 +1136,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
IEEE80211_FC0_SUBTYPE_BEACON;
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
USETW(wh->i_dur, 0);
- IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr);
IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr);
*(uint16_t *)wh->i_seq = 0;
@@ -1173,7 +1144,6 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
/* Finalize mbuf. */
m->m_pkthdr.len = m->m_len = pktlen;
- m->m_pkthdr.rcvif = ifp;
/* Fix the channel. */
c = ieee80211_find_channel_byieee(ic,
le32toh(bss->config.dsconfig),
@@ -1191,8 +1161,7 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len)
static void
rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni = vap->iv_bss;
struct r92s_event_join_bss *rsp;
@@ -1228,8 +1197,7 @@ rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len)
static void
rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTFN(4, "Rx event code=%d len=%d\n", code, len);
@@ -1240,18 +1208,18 @@ rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len)
break;
case R92S_EVT_SURVEY_DONE:
DPRINTF("site survey pass %d done, found %d BSS\n",
- sc->scan_pass, le32toh(*(uint32_t *)buf));
+ sc->sc_scan_pass, le32toh(*(uint32_t *)buf));
if (vap->iv_state != IEEE80211_S_SCAN)
break; /* Ignore if not scanning. */
- if (sc->scan_pass == 0 && vap->iv_des_nssid != 0) {
+ if (sc->sc_scan_pass == 0 && vap->iv_des_nssid != 0) {
/* Schedule a directed scan for hidden APs. */
- sc->scan_pass = 1;
+ sc->sc_scan_pass = 1;
RSU_UNLOCK(sc);
ieee80211_new_state(vap, IEEE80211_S_SCAN, -1);
RSU_LOCK(sc);
break;
}
- sc->scan_pass = 0;
+ sc->sc_scan_pass = 0;
break;
case R92S_EVT_JOIN_BSS:
if (vap->iv_state == IEEE80211_S_AUTH)
@@ -1274,7 +1242,7 @@ XXX and disrupts the WLAN traffic. Disable for now.
DPRINTF("WPS PBC pushed.\n");
break;
case R92S_EVT_FWDBG:
- if (ifp->if_flags & IFF_DEBUG) {
+ if (vap->iv_ifp->if_flags & IFF_DEBUG) {
buf[60] = '\0';
printf("FWDBG: %s\n", (char *)buf);
}
@@ -1341,8 +1309,7 @@ rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt)
static struct mbuf *
rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct r92s_rx_stat *stat;
uint32_t rxdw0, rxdw3;
@@ -1355,11 +1322,11 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
rxdw3 = le32toh(stat->rxdw3);
if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return NULL;
}
if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return NULL;
}
@@ -1377,11 +1344,9 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi)
m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m == NULL)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return NULL;
}
- /* Finalize mbuf. */
- m->m_pkthdr.rcvif = ifp;
/* Hardware does Rx TCP checksum offload. */
if (rxdw3 & R92S_RXDW3_TCPCHKVALID) {
if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT))
@@ -1479,6 +1444,7 @@ static struct mbuf *
rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi)
{
struct rsu_softc *sc = data->sc;
+ struct ieee80211com *ic = &sc->sc_ic;
struct r92s_rx_stat *stat;
int len;
@@ -1486,7 +1452,7 @@ rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi)
if (__predict_false(len < sizeof(*stat))) {
DPRINTF("xfer too short %d\n", len);
- if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
/* Determine if it is a firmware C2H event or an 802.11 frame. */
@@ -1503,8 +1469,7 @@ static void
rsu_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct rsu_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL, *next;
@@ -1564,7 +1529,7 @@ tr_setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
break;
@@ -1572,35 +1537,16 @@ tr_setup:
}
-
static void
rsu_txeof(struct usb_xfer *xfer, struct rsu_data *data)
{
- struct rsu_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- RSU_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
@@ -1608,7 +1554,7 @@ rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error,
uint8_t which)
{
struct rsu_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rsu_data *data;
RSU_ASSERT_LOCKED(sc);
@@ -1643,7 +1589,7 @@ tr_setup:
rsu_txeof(xfer, data);
STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
}
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(ic->ic_oerrors, 1);
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
@@ -1669,8 +1615,7 @@ static int
rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
struct mbuf *m0, struct rsu_data *data)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ieee80211_key *k = NULL;
@@ -1772,82 +1717,75 @@ rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni,
return (0);
}
-static void
-rsu_start(struct ifnet *ifp)
+static int
+rsu_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct rsu_softc *sc = ifp->if_softc;
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
+ struct rsu_softc *sc = ic->ic_softc;
+ int error;
RSU_LOCK(sc);
- rsu_start_locked(ifp);
+ if (!sc->sc_running) {
+ RSU_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RSU_UNLOCK(sc);
+ return (error);
+ }
+ rsu_start(sc);
RSU_UNLOCK(sc);
+
+ return (0);
}
static void
-rsu_start_locked(struct ifnet *ifp)
+rsu_start(struct rsu_softc *sc)
{
- struct rsu_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct rsu_data *bf;
struct mbuf *m;
RSU_ASSERT_LOCKED(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+ bf = rsu_getbuf(sc);
+ if (bf == NULL) {
+ mbufq_prepend(&sc->sc_snd, m);
break;
+ }
+
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
- bf = rsu_getbuf(sc);
- if (bf == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
- m_freem(m);
- ieee80211_free_node(ni);
- } else if (rsu_tx_start(sc, ni, m, bf) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if (rsu_tx_start(sc, ni, m, bf) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
ieee80211_free_node(ni);
+ break;
}
}
}
-static int
-rsu_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+rsu_parent(struct ieee80211com *ic)
{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rsu_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rsu_stop(ifp, 1);
+ struct rsu_softc *sc = ic->ic_softc;
+ int startall = 0;
+
+ RSU_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if (!sc->sc_running) {
+ rsu_init(sc);
+ startall = 1;
}
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
+ } else if (sc->sc_running)
+ rsu_stop(sc);
+ RSU_UNLOCK(sc);
- return (error);
+ if (startall)
+ ieee80211_start_all(ic);
}
/*
@@ -2296,12 +2234,11 @@ rsu_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 rsu_softc *sc = ifp->if_softc;
+ struct rsu_softc *sc = ic->ic_softc;
struct rsu_data *bf;
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->sc_running) {
m_freem(m);
ieee80211_free_node(ni);
return (ENETDOWN);
@@ -2314,10 +2251,8 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
RSU_UNLOCK(sc);
return (ENOBUFS);
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if (rsu_tx_start(sc, ni, m, bf) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
RSU_UNLOCK(sc);
return (EIO);
@@ -2328,23 +2263,17 @@ rsu_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
}
static void
-rsu_init(void *arg)
+rsu_init(struct rsu_softc *sc)
{
- struct rsu_softc *sc = arg;
-
- RSU_LOCK(sc);
- rsu_init_locked(arg);
- RSU_UNLOCK(sc);
-}
-
-static void
-rsu_init_locked(struct rsu_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
struct r92s_set_pwr_mode cmd;
int error;
int i;
+ RSU_ASSERT_LOCKED(sc);
+
/* Init host async commands ring. */
sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0;
@@ -2384,14 +2313,14 @@ rsu_init_locked(struct rsu_softc *sc)
rsu_read_1(sc, 0xfe5c) | 0x80);
/* Set MAC address. */
- rsu_write_region_1(sc, R92S_MACID, IF_LLADDR(ifp),
- IEEE80211_ADDR_LEN);
+ IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ rsu_write_region_1(sc, R92S_MACID, macaddr, IEEE80211_ADDR_LEN);
/* It really takes 1.5 seconds for the firmware to boot: */
usb_pause_mtx(&sc->sc_mtx, (3 * hz) / 2);
- DPRINTF("setting MAC address to %s\n", ether_sprintf(IF_LLADDR(ifp)));
- error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, IF_LLADDR(ifp),
+ DPRINTF("setting MAC address to %s\n", ether_sprintf(macaddr));
+ error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, macaddr,
IEEE80211_ADDR_LEN);
if (error != 0) {
device_printf(sc->sc_dev, "could not set MAC address\n");
@@ -2427,12 +2356,11 @@ rsu_init_locked(struct rsu_softc *sc)
/* Set default channel. */
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
#endif
- sc->scan_pass = 0;
+ sc->sc_scan_pass = 0;
usbd_transfer_start(sc->sc_xfer[RSU_BULK_RX]);
/* We're ready to go. */
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
return;
fail:
/* Need to stop all failed transfers, if any */
@@ -2441,22 +2369,11 @@ fail:
}
static void
-rsu_stop(struct ifnet *ifp, int disable)
-{
- struct rsu_softc *sc = ifp->if_softc;
-
- RSU_LOCK(sc);
- rsu_stop_locked(ifp, disable);
- RSU_UNLOCK(sc);
-}
-
-static void
-rsu_stop_locked(struct ifnet *ifp, int disable __unused)
+rsu_stop(struct rsu_softc *sc)
{
- struct rsu_softc *sc = ifp->if_softc;
int i;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_running = 0;
sc->sc_calibrating = 0;
taskqueue_cancel_timeout(taskqueue_thread, &sc->calib_task, NULL);
diff --git a/sys/dev/usb/wlan/if_rsureg.h b/sys/dev/usb/wlan/if_rsureg.h
index db0751d..4e6cd88 100644
--- a/sys/dev/usb/wlan/if_rsureg.h
+++ b/sys/dev/usb/wlan/if_rsureg.h
@@ -726,7 +726,8 @@ struct rsu_vap {
#define RSU_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
struct rsu_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
int (*sc_newstate)(struct ieee80211com *,
@@ -736,17 +737,17 @@ struct rsu_softc {
const uint8_t *qid2idx;
struct mtx sc_mtx;
+ u_int sc_running:1,
+ sc_calibrating:1,
+ sc_scan_pass:1;
u_int cut;
- int scan_pass;
struct rsu_host_cmd_ring cmdq;
struct rsu_data sc_rx[RSU_RX_LIST_COUNT];
struct rsu_data sc_tx[RSU_TX_LIST_COUNT];
struct rsu_data *fwcmd_data;
uint8_t cmd_seq;
uint8_t rom[128];
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
struct usb_xfer *sc_xfer[RSU_N_TRANSFER];
- uint8_t sc_calibrating;
STAILQ_HEAD(, rsu_data) sc_rx_active;
STAILQ_HEAD(, rsu_data) sc_rx_inactive;
diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c
index d5142ea..6a558f6 100644
--- a/sys/dev/usb/wlan/if_rum.c
+++ b/sys/dev/usb/wlan/if_rum.c
@@ -175,8 +175,9 @@ static int rum_tx_raw(struct rum_softc *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int rum_tx_data(struct rum_softc *, struct mbuf *,
struct ieee80211_node *);
-static void rum_start(struct ifnet *);
-static int rum_ioctl(struct ifnet *, u_long, caddr_t);
+static int rum_transmit(struct ieee80211com *, struct mbuf *);
+static void rum_start(struct rum_softc *);
+static void rum_parent(struct ieee80211com *);
static void rum_eeprom_read(struct rum_softc *, uint16_t, void *,
int);
static uint32_t rum_read(struct rum_softc *, uint16_t);
@@ -198,7 +199,7 @@ static void rum_set_chan(struct rum_softc *,
struct ieee80211_channel *);
static void rum_enable_tsf_sync(struct rum_softc *);
static void rum_enable_tsf(struct rum_softc *);
-static void rum_update_slot(struct ifnet *);
+static void rum_update_slot(struct rum_softc *);
static void rum_set_bssid(struct rum_softc *, const uint8_t *);
static void rum_set_macaddr(struct rum_softc *, const uint8_t *);
static void rum_update_mcast(struct ieee80211com *);
@@ -207,8 +208,7 @@ static void rum_setpromisc(struct rum_softc *);
static const char *rum_get_rf(int);
static void rum_read_eeprom(struct rum_softc *);
static int rum_bbp_init(struct rum_softc *);
-static void rum_init_locked(struct rum_softc *);
-static void rum_init(void *);
+static void rum_init(struct rum_softc *);
static void rum_stop(struct rum_softc *);
static void rum_load_microcode(struct rum_softc *, const uint8_t *,
size_t);
@@ -425,8 +425,7 @@ rum_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct rum_softc *sc = device_get_softc(self);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
uint32_t tmp;
int error, ntries;
@@ -437,6 +436,7 @@ rum_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(self),
MTX_NETWORK_LOCK, MTX_DEF);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = RT2573_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device, &iface_index,
@@ -470,24 +470,6 @@ rum_attach(device_t self)
rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
RUM_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = rum_init;
- ifp->if_ioctl = rum_ioctl;
- ifp->if_start = rum_start;
- 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(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -512,13 +494,14 @@ rum_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_update_promisc = rum_update_promisc;
ic->ic_raw_xmit = rum_raw_xmit;
ic->ic_scan_start = rum_scan_start;
ic->ic_scan_end = rum_scan_end;
ic->ic_set_channel = rum_set_channel;
-
+ ic->ic_transmit = rum_transmit;
+ ic->ic_parent = rum_parent;
ic->ic_vap_create = rum_vap_create;
ic->ic_vap_delete = rum_vap_delete;
ic->ic_update_mcast = rum_update_mcast;
@@ -543,8 +526,6 @@ static int
rum_detach(device_t self)
{
struct rum_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
/* Prevent further ioctls */
RUM_LOCK(sc);
@@ -559,11 +540,9 @@ rum_detach(device_t self)
rum_unsetup_tx_list(sc);
RUM_UNLOCK(sc);
- if (ifp) {
- ic = ifp->if_l2com;
- ieee80211_ifdetach(ic);
- if_free(ifp);
- }
+ if (sc->sc_ic.ic_softc == sc)
+ ieee80211_ifdetach(&sc->sc_ic);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -595,21 +574,18 @@ rum_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 rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
struct rum_vap *rvp;
struct ieee80211vap *vap;
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return NULL;
+ rvp = malloc(sizeof(struct rum_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &rvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(rvp, M_80211_VAP);
return (NULL);
@@ -624,7 +600,8 @@ rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -648,13 +625,8 @@ rum_tx_free(struct rum_tx_data *data, int txerr)
struct rum_softc *sc = data->sc;
if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
+ ieee80211_tx_complete(data->ni, data->m, txerr);
data->m = NULL;
-
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
@@ -711,7 +683,7 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rum_vap *rvp = RUM_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
const struct ieee80211_txparam *tp;
enum ieee80211_state ostate;
struct ieee80211_node *ni;
@@ -745,12 +717,12 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_free_node(ni);
return (-1);
}
- rum_update_slot(ic->ic_ifp);
+ rum_update_slot(sc);
rum_enable_mrr(sc);
rum_set_txpreamble(sc);
rum_set_basicrates(sc);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- rum_set_bssid(sc, sc->sc_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid);
+ rum_set_bssid(sc, ic->ic_macaddr);
}
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -780,7 +752,6 @@ static void
rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct rum_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap;
struct rum_tx_data *data;
struct mbuf *m;
@@ -799,9 +770,6 @@ rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
rum_tx_free(data, 0);
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -844,16 +812,14 @@ tr_setup:
usbd_transfer_submit(xfer);
}
- RUM_UNLOCK(sc);
- rum_start(ifp);
- RUM_LOCK(sc);
+ rum_start(sc);
break;
default: /* Error */
DPRINTFN(11, "transfer error, %s\n",
usbd_errstr(error));
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
data = usbd_xfer_get_priv(xfer);
if (data != NULL) {
rum_tx_free(data, error);
@@ -880,8 +846,7 @@ static void
rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct rum_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
struct usb_page_cache *pc;
@@ -899,7 +864,7 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
if (len < (int)(RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
DPRINTF("%s: xfer too short %d\n",
device_get_nameunit(sc->sc_dev), len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
@@ -916,21 +881,20 @@ rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
* filled RUM_TXRX_CSR2:
*/
DPRINTFN(5, "PHY or CRC error\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m == NULL) {
DPRINTF("could not allocate mbuf\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
usbd_copy_out(pc, RT2573_RX_DESC_SIZE,
mtod(m, uint8_t *), len);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
if (ieee80211_radiotap_active(ic)) {
@@ -968,10 +932,8 @@ tr_setup:
(void) ieee80211_input_all(ic, m, rssi,
RT2573_NOISE_FLOOR);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- rum_start(ifp);
RUM_LOCK(sc);
+ rum_start(sc);
return;
default: /* Error */
@@ -1011,8 +973,7 @@ static void
rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
uint32_t flags, uint16_t xflags, int len, int rate)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t plcp_length;
int remainder;
@@ -1109,8 +1070,7 @@ static int
rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rum_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
@@ -1221,8 +1181,7 @@ static int
rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct rum_tx_data *data;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
@@ -1299,80 +1258,73 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
return 0;
}
+static int
+rum_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct rum_softc *sc = ic->ic_softc;
+ int error;
+
+ RUM_LOCK(sc);
+ if (!sc->sc_running) {
+ RUM_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RUM_UNLOCK(sc);
+ return (error);
+ }
+ rum_start(sc);
+ RUM_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-rum_start(struct ifnet *ifp)
+rum_start(struct rum_softc *sc)
{
- struct rum_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- RUM_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RUM_UNLOCK(sc);
+ RUM_LOCK_ASSERT(sc, MA_OWNED);
+
+ if (!sc->sc_running)
return;
- }
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree < RUM_TX_MINFREE) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+
+ while (sc->tx_nfree >= RUM_TX_MINFREE &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (rum_tx_data(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
}
}
- RUM_UNLOCK(sc);
}
-static int
-rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+rum_parent(struct ieee80211com *ic)
{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct rum_softc *sc = ic->ic_softc;
int startall = 0;
RUM_LOCK(sc);
- error = sc->sc_detached ? ENXIO : 0;
- RUM_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RUM_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- rum_init_locked(sc);
- startall = 1;
- } else
- rum_setpromisc(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- rum_stop(sc);
- }
+ if (sc->sc_detached) {
RUM_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ return;
}
- return error;
+ if (ic->ic_nrunning > 0) {
+ if (!sc->sc_running) {
+ rum_init(sc);
+ startall = 1;
+ } else
+ rum_setpromisc(sc);
+ } else if (sc->sc_running)
+ rum_stop(sc);
+ RUM_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -1572,8 +1524,7 @@ rum_select_antenna(struct rum_softc *sc)
static void
rum_enable_mrr(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = rum_read(sc, RT2573_TXRX_CSR4);
@@ -1589,8 +1540,7 @@ rum_enable_mrr(struct rum_softc *sc)
static void
rum_set_txpreamble(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
tmp = rum_read(sc, RT2573_TXRX_CSR4);
@@ -1605,8 +1555,7 @@ rum_set_txpreamble(struct rum_softc *sc)
static void
rum_set_basicrates(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/* update basic rate set */
if (ic->ic_curmode == IEEE80211_MODE_11B) {
@@ -1671,8 +1620,7 @@ rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
static void
rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
const struct rfprog *rfprog;
uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
int8_t power;
@@ -1748,8 +1696,7 @@ rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
static void
rum_enable_tsf_sync(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
@@ -1784,10 +1731,9 @@ rum_enable_tsf(struct rum_softc *sc)
}
static void
-rum_update_slot(struct ifnet *ifp)
+rum_update_slot(struct rum_softc *sc)
{
- struct rum_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t slottime;
uint32_t tmp;
@@ -1827,18 +1773,17 @@ rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
static void
rum_setpromisc(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
tmp = rum_read(sc, RT2573_TXRX_CSR0);
tmp &= ~RT2573_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (sc->sc_ic.ic_promisc == 0)
tmp |= RT2573_DROP_NOT_TO_ME;
rum_write(sc, RT2573_TXRX_CSR0, tmp);
- DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
+ DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc > 0 ?
"entering" : "leaving");
}
@@ -1847,10 +1792,11 @@ rum_update_promisc(struct ieee80211com *ic)
{
struct rum_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
RUM_LOCK(sc);
+ if (!sc->sc_running) {
+ RUM_UNLOCK(sc);
+ return;
+ }
rum_setpromisc(sc);
RUM_UNLOCK(sc);
}
@@ -1887,7 +1833,7 @@ rum_read_eeprom(struct rum_softc *sc)
#endif
/* read MAC address */
- rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_bssid, 6);
+ rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_ic.ic_macaddr, 6);
rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
val = le16toh(val);
@@ -1994,10 +1940,10 @@ rum_bbp_init(struct rum_softc *sc)
}
static void
-rum_init_locked(struct rum_softc *sc)
+rum_init(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
usb_error_t error;
int i, ntries;
@@ -2039,7 +1985,7 @@ rum_init_locked(struct rum_softc *sc)
/* clear STA registers */
rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
- rum_set_macaddr(sc, IF_LLADDR(ifp));
+ rum_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
/* initialize ASIC */
rum_write(sc, RT2573_MAC_CSR1, 4);
@@ -2058,13 +2004,12 @@ rum_init_locked(struct rum_softc *sc)
RT2573_DROP_ACKCTS;
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
tmp |= RT2573_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RT2573_DROP_NOT_TO_ME;
}
rum_write(sc, RT2573_TXRX_CSR0, tmp);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
usbd_xfer_set_stall(sc->sc_xfer[RUM_BULK_WR]);
usbd_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
return;
@@ -2074,29 +2019,13 @@ fail: rum_stop(sc);
}
static void
-rum_init(void *priv)
-{
- struct rum_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RUM_LOCK(sc);
- rum_init_locked(sc);
- RUM_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
rum_stop(struct rum_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
RUM_LOCK_ASSERT(sc, MA_OWNED);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_running = 0;
RUM_UNLOCK(sc);
@@ -2188,27 +2117,23 @@ static int
rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
+ struct rum_softc *sc = ni->ni_ic->ic_softc;
RUM_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->sc_running) {
RUM_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->tx_nfree < RUM_TX_MINFREE) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
RUM_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return EIO;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -2228,7 +2153,6 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
RUM_UNLOCK(sc);
ieee80211_free_node(ni);
return EIO;
@@ -2262,8 +2186,7 @@ rum_ratectl_task(void *arg, int pending)
struct rum_vap *rvp = arg;
struct ieee80211vap *vap = &rvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
int ok, fail;
int sum, retrycnt;
@@ -2283,7 +2206,8 @@ rum_ratectl_task(void *arg, int pending)
(void) ieee80211_ratectl_rate(ni, NULL, 0);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, fail); /* count TX retry-fail as Tx errors */
+ /* count TX retry-fail as Tx errors */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail);
usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
RUM_UNLOCK(sc);
@@ -2292,15 +2216,14 @@ rum_ratectl_task(void *arg, int pending)
static void
rum_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct rum_softc *sc = ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
uint32_t tmp;
RUM_LOCK(sc);
/* abort TSF synchronization */
tmp = rum_read(sc, RT2573_TXRX_CSR9);
rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
- rum_set_bssid(sc, ifp->if_broadcastaddr);
+ rum_set_bssid(sc, ieee80211broadcastaddr);
RUM_UNLOCK(sc);
}
@@ -2308,11 +2231,11 @@ rum_scan_start(struct ieee80211com *ic)
static void
rum_scan_end(struct ieee80211com *ic)
{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
RUM_LOCK(sc);
rum_enable_tsf_sync(sc);
- rum_set_bssid(sc, sc->sc_bssid);
+ rum_set_bssid(sc, ic->ic_macaddr);
RUM_UNLOCK(sc);
}
@@ -2320,7 +2243,7 @@ rum_scan_end(struct ieee80211com *ic)
static void
rum_set_channel(struct ieee80211com *ic)
{
- struct rum_softc *sc = ic->ic_ifp->if_softc;
+ struct rum_softc *sc = ic->ic_softc;
RUM_LOCK(sc);
rum_set_chan(sc, ic->ic_curchan);
@@ -2330,8 +2253,7 @@ rum_set_channel(struct ieee80211com *ic)
static int
rum_get_rssi(struct rum_softc *sc, uint8_t raw)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int lna, agc, rssi;
lna = (raw >> 5) & 0x3;
diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h
index 17944aa..35da6d3 100644
--- a/sys/dev/usb/wlan/if_rumvar.h
+++ b/sys/dev/usb/wlan/if_rumvar.h
@@ -85,7 +85,8 @@ enum {
};
struct rum_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -105,8 +106,8 @@ struct rum_softc {
uint32_t sta[6];
uint32_t rf_regs[4];
uint8_t txpow[44];
- uint8_t sc_bssid[6];
- uint8_t sc_detached;
+ u_int sc_detached:1,
+ sc_running:1;
struct {
uint8_t val;
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index ac14178..193b9ad 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -410,8 +410,9 @@ static int run_tx_param(struct run_softc *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int run_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void run_start(struct ifnet *);
-static int run_ioctl(struct ifnet *, u_long, caddr_t);
+static int run_transmit(struct ieee80211com *, struct mbuf *);
+static void run_start(struct run_softc *);
+static void run_parent(struct ieee80211com *);
static void run_iq_calib(struct run_softc *, u_int);
static void run_set_agc(struct run_softc *, uint8_t);
static void run_select_chan_group(struct run_softc *, int);
@@ -457,7 +458,6 @@ static void run_rt3593_rf_setup(struct run_softc *);
static void run_rt5390_rf_setup(struct run_softc *);
static int run_txrx_enable(struct run_softc *);
static void run_adjust_freq_offset(struct run_softc *);
-static void run_init(void *);
static void run_init_locked(struct run_softc *);
static void run_stop(void *);
static void run_delay(struct run_softc *, u_int);
@@ -702,8 +702,7 @@ run_attach(device_t self)
{
struct run_softc *sc = device_get_softc(self);
struct usb_attach_arg *uaa = device_get_ivars(self);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t ver;
int ntries, error;
uint8_t iface_index, bands;
@@ -716,6 +715,7 @@ run_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
MTX_NETWORK_LOCK, MTX_DEF);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = RT2860_IFACE_INDEX;
@@ -754,28 +754,10 @@ run_attach(device_t self)
device_printf(sc->sc_dev,
"MAC/BBP RT%04X (rev 0x%04X), RF %s (MIMO %dT%dR), address %s\n",
sc->mac_ver, sc->mac_rev, run_get_rf(sc->rf_rev),
- sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid));
+ sc->ntxchains, sc->nrxchains, ether_sprintf(ic->ic_macaddr));
RUN_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "run", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = run_init;
- ifp->if_ioctl = run_ioctl;
- ifp->if_start = run_start;
- 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(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -812,7 +794,7 @@ run_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_scan_start = run_scan_start;
ic->ic_scan_end = run_scan_end;
@@ -824,9 +806,10 @@ run_attach(device_t self)
ic->ic_wme.wme_update = run_wme_update;
ic->ic_raw_xmit = run_raw_xmit;
ic->ic_update_promisc = run_update_promisc;
-
ic->ic_vap_create = run_vap_create;
ic->ic_vap_delete = run_vap_delete;
+ ic->ic_transmit = run_transmit;
+ ic->ic_parent = run_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -852,8 +835,7 @@ static int
run_detach(device_t self)
{
struct run_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
int i;
RUN_LOCK(sc);
@@ -872,16 +854,15 @@ run_detach(device_t self)
run_unsetup_tx_list(sc, &sc->sc_epq[i]);
RUN_UNLOCK(sc);
- if (ifp) {
- ic = ifp->if_l2com;
+ if (sc->sc_ic.ic_softc == sc) {
/* drain tasks */
usb_callout_drain(&sc->ratectl_ch);
ieee80211_draintask(ic, &sc->cmdq_task);
ieee80211_draintask(ic, &sc->ratectl_task);
ieee80211_ifdetach(ic);
- if_free(ifp);
}
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -893,14 +874,13 @@ run_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 run_softc *sc = ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct run_vap *rvp;
struct ieee80211vap *vap;
int i;
if (sc->rvp_cnt >= RUN_VAP_MAX) {
- if_printf(ifp, "number of VAPs maxed out\n");
+ device_printf(sc->sc_dev, "number of VAPs maxed out\n");
return (NULL);
}
@@ -926,23 +906,21 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
break;
}
if (vap == NULL) {
- if_printf(ifp, "wds only supported in ap mode\n");
+ device_printf(sc->sc_dev,
+ "wds only supported in ap mode\n");
return (NULL);
}
break;
default:
- if_printf(ifp, "unknown opmode %d\n", opmode);
+ device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
return (NULL);
}
- rvp = (struct run_vap *) malloc(sizeof(struct run_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (rvp == NULL)
- return (NULL);
+ rvp = malloc(sizeof(struct run_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &rvp->vap;
- if (ieee80211_vap_setup(ic, vap, name, unit,
- opmode, flags, bssid, mac) != 0) {
+ if (ieee80211_vap_setup(ic, vap, name, unit, opmode, flags,
+ bssid) != 0) {
/* out of memory */
free(rvp, M_80211_VAP);
return (NULL);
@@ -969,7 +947,8 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
- ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status,
+ mac);
/* make sure id is always unique */
for (i = 0; i < RUN_VAP_MAX; i++) {
@@ -995,7 +974,6 @@ static void
run_vap_delete(struct ieee80211vap *vap)
{
struct run_vap *rvp = RUN_VAP(vap);
- struct ifnet *ifp;
struct ieee80211com *ic;
struct run_softc *sc;
uint8_t rvp_id;
@@ -1004,9 +982,7 @@ run_vap_delete(struct ieee80211vap *vap)
return;
ic = vap->iv_ic;
- ifp = ic->ic_ifp;
-
- sc = ifp->if_softc;
+ sc = ic->ic_softc;
RUN_LOCK(sc);
@@ -1740,6 +1716,7 @@ run_get_txpower(struct run_softc *sc)
static int
run_read_eeprom(struct run_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
int8_t delta_2ghz, delta_5ghz;
uint32_t tmp;
uint16_t val;
@@ -1760,14 +1737,14 @@ run_read_eeprom(struct run_softc *sc)
/* read MAC address */
run_srom_read(sc, RT2860_EEPROM_MAC01, &val);
- sc->sc_bssid[0] = val & 0xff;
- sc->sc_bssid[1] = val >> 8;
+ ic->ic_macaddr[0] = val & 0xff;
+ ic->ic_macaddr[1] = val >> 8;
run_srom_read(sc, RT2860_EEPROM_MAC23, &val);
- sc->sc_bssid[2] = val & 0xff;
- sc->sc_bssid[3] = val >> 8;
+ ic->ic_macaddr[2] = val & 0xff;
+ ic->ic_macaddr[3] = val >> 8;
run_srom_read(sc, RT2860_EEPROM_MAC45, &val);
- sc->sc_bssid[4] = val & 0xff;
- sc->sc_bssid[5] = val >> 8;
+ ic->ic_macaddr[4] = val & 0xff;
+ ic->ic_macaddr[5] = val >> 8;
if (sc->mac_ver < 0x3593) {
/* read vender BBP settings */
@@ -2002,7 +1979,7 @@ run_media_change(struct ifnet *ifp)
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
const struct ieee80211_txparam *tp;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint8_t rate, ridx;
int error;
@@ -2033,7 +2010,7 @@ run_media_change(struct ifnet *ifp)
#if 0
if ((ifp->if_flags & IFF_UP) &&
- (ifp->if_drv_flags & IFF_DRV_RUNNING)){
+ (ifp->if_drv_flags & RUN_RUNNING)){
run_init_locked(sc);
}
#endif
@@ -2048,7 +2025,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
const struct ieee80211_txparam *tp;
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct run_vap *rvp = RUN_VAP(vap);
enum ieee80211_state ostate;
uint32_t sta[3];
@@ -2144,7 +2121,7 @@ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
run_set_txpreamble(sc);
run_set_basicrates(sc);
ni = ieee80211_ref_node(vap->iv_bss);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid);
run_set_bssid(sc, ni->ni_bssid);
ieee80211_free_node(ni);
run_enable_tsf_sync(sc);
@@ -2181,7 +2158,7 @@ static void
run_wme_update_cb(void *arg)
{
struct ieee80211com *ic = arg;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct ieee80211_wme_state *wmesp = &ic->ic_wme;
int aci, error = 0;
@@ -2234,7 +2211,7 @@ err:
static int
run_wme_update(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
/* sometime called wothout lock */
if (mtx_owned(&ic->ic_comlock.mtx)) {
@@ -2277,7 +2254,7 @@ run_key_set_cb(void *arg)
struct ieee80211vap *vap = cmdq->arg1;
struct ieee80211_key *k = cmdq->k;
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
uint32_t attr;
uint16_t base, associd;
@@ -2399,7 +2376,7 @@ run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k,
const uint8_t mac[IEEE80211_ADDR_LEN])
{
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t i;
i = RUN_CMDQ_GET(&sc->cmdq_store);
@@ -2467,7 +2444,7 @@ static int
run_key_delete(struct ieee80211vap *vap, struct ieee80211_key *k)
{
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct ieee80211_key *k0;
uint32_t i;
@@ -2498,7 +2475,7 @@ run_ratectl_to(void *arg)
struct run_softc *sc = arg;
/* do it in a process context, so it can go sleep */
- ieee80211_runtask(sc->sc_ifp->if_l2com, &sc->ratectl_task);
+ ieee80211_runtask(&sc->sc_ic, &sc->ratectl_task);
/* next timeout will be rescheduled in the callback task */
}
@@ -2507,7 +2484,7 @@ static void
run_ratectl_cb(void *arg, int pending)
{
struct run_softc *sc = arg;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
if (vap == NULL)
@@ -2540,7 +2517,6 @@ static void
run_drain_fifo(void *arg)
{
struct run_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t stat;
uint16_t (*wstat)[3];
uint8_t wcid, mcs, pid;
@@ -2577,7 +2553,7 @@ run_drain_fifo(void *arg)
if (stat & RT2860_TXQ_OK)
(*wstat)[RUN_SUCCESS]++;
else
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
/*
* Check if there were retries, ie if the Tx success rate is
* different from the requested rate. Note that it works only
@@ -2600,8 +2576,6 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
{
struct run_softc *sc = arg;
struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
struct run_node *rn = (void *)ni;
union run_stats sta[2];
uint16_t (*wstat)[3];
@@ -2623,7 +2597,8 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
goto fail;
/* count failed TX as errors */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, le16toh(sta[0].error.fail));
+ if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS,
+ le16toh(sta[0].error.fail));
retrycnt = le16toh(sta[1].tx.retry);
success = le16toh(sta[1].tx.success);
@@ -2661,7 +2636,7 @@ run_newassoc_cb(void *arg)
{
struct run_cmdq *cmdq = arg;
struct ieee80211_node *ni = cmdq->arg1;
- struct run_softc *sc = ni->ni_vap->iv_ic->ic_ifp->if_softc;
+ struct run_softc *sc = ni->ni_vap->iv_ic->ic_softc;
uint8_t wcid = cmdq->wcid;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -2679,7 +2654,7 @@ run_newassoc(struct ieee80211_node *ni, int isnew)
struct ieee80211_rateset *rs = &ni->ni_rates;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint8_t rate;
uint8_t ridx;
uint8_t wcid;
@@ -2769,8 +2744,7 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi)
static void
run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct rt2870_rxd *rxd;
@@ -2789,7 +2763,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
rxwisize += sizeof(uint32_t);
if (__predict_false(len > dmalen)) {
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF("bad RXWI length %u > %u\n", len, dmalen);
return;
}
@@ -2799,7 +2773,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
if (__predict_false(flags & (RT2860_RX_CRCERR | RT2860_RX_ICVERR))) {
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF("%s error.\n", (flags & RT2860_RX_CRCERR)?"CRC":"ICV");
return;
}
@@ -2828,7 +2802,7 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
ieee80211_notify_michael_failure(ni->ni_vap, wh,
rxwi->keyidx);
m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
DPRINTF("MIC error. Someone is lying.\n");
return;
}
@@ -2837,7 +2811,6 @@ run_rx_frame(struct run_softc *sc, struct mbuf *m, uint32_t dmalen)
rssi = rxwi->rssi[ant];
nf = run_rssi2dbm(sc, rssi, ant);
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = len;
if (ni != NULL) {
@@ -2890,7 +2863,7 @@ static void
run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct run_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
struct mbuf *m = NULL;
struct mbuf *m0;
uint32_t dmalen;
@@ -2928,7 +2901,7 @@ tr_setup:
}
if (sc->rx_m == NULL) {
DPRINTF("could not allocate mbuf - idle with stall\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
usbd_xfer_set_stall(xfer);
usbd_xfer_set_frames(xfer, 0);
} else {
@@ -2948,12 +2921,9 @@ tr_setup:
if (error != USB_ERR_CANCELLED) {
/* try to clear stall first */
usbd_xfer_set_stall(xfer);
-
if (error == USB_ERR_TIMEOUT)
device_printf(sc->sc_dev, "device timeout\n");
-
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
-
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
if (sc->rx_m != NULL) {
@@ -3001,7 +2971,7 @@ tr_setup:
m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m0 == NULL)) {
DPRINTF("could not allocate mbuf\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
break;
}
m_copydata(m, 4 /* skip 32-bit DMA-len header */,
@@ -3048,8 +3018,7 @@ static void
run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index)
{
struct run_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct run_tx_data *data;
struct ieee80211vap *vap = NULL;
struct usb_page_cache *pc;
@@ -3067,14 +3036,9 @@ run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index)
"bytes @ index %d\n", actlen, index);
data = usbd_xfer_get_priv(xfer);
-
run_tx_free(pq, data, 0);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -3091,11 +3055,7 @@ tr_setup:
size + 3 + 8) > RUN_MAX_TXSZ) {
DPRINTF("data overflow, %u bytes\n",
m->m_pkthdr.len);
-
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
-
run_tx_free(pq, data, 1);
-
goto tr_setup;
}
@@ -3132,12 +3092,8 @@ tr_setup:
usbd_xfer_set_frame_len(xfer, 0, size);
usbd_xfer_set_priv(xfer, data);
-
usbd_transfer_submit(xfer);
-
- RUN_UNLOCK(sc);
- run_start(ifp);
- RUN_LOCK(sc);
+ run_start(sc);
break;
@@ -3147,14 +3103,13 @@ tr_setup:
data = usbd_xfer_get_priv(xfer);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
-
if (data != NULL) {
if(data->ni != NULL)
vap = data->ni->ni_vap;
run_tx_free(pq, data, error);
usbd_xfer_set_priv(xfer, NULL);
}
+
if (vap == NULL)
vap = TAILQ_FIRST(&ic->ic_vaps);
@@ -3220,7 +3175,7 @@ static void
run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data)
{
struct mbuf *m = data->m;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = data->ni->ni_vap;
struct ieee80211_frame *wh;
struct rt2870_txd *txd;
@@ -3283,7 +3238,7 @@ run_set_tx_desc(struct run_softc *sc, struct run_tx_data *data)
static int
run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ieee80211_channel *chan;
@@ -3451,8 +3406,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
static int
run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct run_node *rn = (void *)ni;
struct run_tx_data *data;
struct ieee80211_frame *wh;
@@ -3483,11 +3437,9 @@ run_tx_mgt(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
USETW(wh->i_dur, dur);
}
- if (sc->sc_epq[0].tx_nfree == 0) {
+ if (sc->sc_epq[0].tx_nfree == 0)
/* let caller free mbuf */
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (EIO);
- }
data = STAILQ_FIRST(&sc->sc_epq[0].tx_fh);
STAILQ_REMOVE_HEAD(&sc->sc_epq[0].tx_fh, next);
sc->sc_epq[0].tx_nfree--;
@@ -3555,11 +3507,9 @@ run_sendprot(struct run_softc *sc,
wflags = RT2860_TX_FRAG;
/* check that there are free slots before allocating the mbuf */
- if (sc->sc_epq[0].tx_nfree == 0) {
+ if (sc->sc_epq[0].tx_nfree == 0)
/* let caller free mbuf */
- sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (ENOBUFS);
- }
if (prot == IEEE80211_PROT_RTSCTS) {
/* NB: CTS is the same size as an ACK */
@@ -3570,7 +3520,7 @@ run_sendprot(struct run_softc *sc,
mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
}
if (mprot == NULL) {
- if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
DPRINTF("could not allocate mbuf\n");
return (ENOBUFS);
}
@@ -3652,7 +3602,6 @@ run_tx_param(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
if (sc->sc_epq[0].tx_nfree == 0) {
/* let caller free mbuf */
- sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE;
DPRINTF("sending raw frame, but tx ring is full\n");
return (EIO);
}
@@ -3691,36 +3640,31 @@ static int
run_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
- struct ifnet *ifp = ni->ni_ic->ic_ifp;
- struct run_softc *sc = ifp->if_softc;
+ struct run_softc *sc = ni->ni_ic->ic_softc;
int error = 0;
RUN_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- error = ENETDOWN;
+ if (!(sc->sc_flags & RUN_RUNNING)) {
+ error = ENETDOWN;
goto done;
}
if (params == NULL) {
/* tx mgt packet */
if ((error = run_tx_mgt(sc, m, ni)) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
DPRINTF("mgt tx failed\n");
goto done;
}
} else {
/* tx raw packet with param */
if ((error = run_tx_param(sc, m, ni, params)) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
DPRINTF("tx with param failed\n");
goto done;
}
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
done:
RUN_UNLOCK(sc);
@@ -3733,83 +3677,71 @@ done:
return (error);
}
+static int
+run_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct run_softc *sc = ic->ic_softc;
+ int error;
+
+ RUN_LOCK(sc);
+ if ((sc->sc_flags & RUN_RUNNING) == 0) {
+ RUN_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RUN_UNLOCK(sc);
+ return (error);
+ }
+ run_start(sc);
+ RUN_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-run_start(struct ifnet *ifp)
+run_start(struct run_softc *sc)
{
- struct run_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- RUN_LOCK(sc);
+ RUN_LOCK_ASSERT(sc, MA_OWNED);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RUN_UNLOCK(sc);
+ if ((sc->sc_flags & RUN_RUNNING) == 0)
return;
- }
-
- for (;;) {
- /* send data frames */
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (run_tx(sc, m, ni) != 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
}
-
- RUN_UNLOCK(sc);
}
-static int
-run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+run_parent(struct ieee80211com *ic)
{
- struct run_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
+ struct run_softc *sc = ic->ic_softc;
int startall = 0;
- int error;
RUN_LOCK(sc);
- error = sc->sc_detached ? ENXIO : 0;
- RUN_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RUN_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)){
- startall = 1;
- run_init_locked(sc);
- } else
- run_update_promisc_locked(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- (ic->ic_nrunning == 0 || sc->rvp_cnt <= 1)) {
- run_stop(sc);
- }
- }
+ if (sc->sc_detached) {
RUN_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ return;
}
- return (error);
+ if (ic->ic_nrunning > 0) {
+ if (!(sc->sc_flags & RUN_RUNNING)) {
+ startall = 1;
+ run_init_locked(sc);
+ } else
+ run_update_promisc_locked(sc);
+ } else if ((sc->sc_flags & RUN_RUNNING) && sc->rvp_cnt <= 1)
+ run_stop(sc);
+ RUN_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -4796,7 +4728,7 @@ run_set_rx_antenna(struct run_softc *sc, int aux)
static int
run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
u_int chan, group;
chan = ieee80211_chan2ieee(ic, c);
@@ -4841,7 +4773,7 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c)
static void
run_set_channel(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
RUN_LOCK(sc);
run_set_chan(sc, ic->ic_curchan);
@@ -4853,7 +4785,7 @@ run_set_channel(struct ieee80211com *ic)
static void
run_scan_start(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t tmp;
RUN_LOCK(sc);
@@ -4863,7 +4795,7 @@ run_scan_start(struct ieee80211com *ic)
run_write(sc, RT2860_BCN_TIME_CFG,
tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN |
RT2860_TBTT_TIMER_EN));
- run_set_bssid(sc, sc->sc_ifp->if_broadcastaddr);
+ run_set_bssid(sc, ieee80211broadcastaddr);
RUN_UNLOCK(sc);
@@ -4873,13 +4805,13 @@ run_scan_start(struct ieee80211com *ic)
static void
run_scan_end(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
RUN_LOCK(sc);
run_enable_tsf_sync(sc);
/* XXX keep local copy */
- run_set_bssid(sc, sc->sc_bssid);
+ run_set_bssid(sc, ic->ic_macaddr);
RUN_UNLOCK(sc);
@@ -4894,7 +4826,7 @@ static void
run_update_beacon(struct ieee80211vap *vap, int item)
{
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct run_vap *rvp = RUN_VAP(vap);
int mcast = 0;
uint32_t i;
@@ -4939,7 +4871,7 @@ run_update_beacon_cb(void *arg)
struct ieee80211vap *vap = arg;
struct run_vap *rvp = RUN_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
struct rt2860_txwi txwi;
struct mbuf *m;
uint16_t txwisize;
@@ -4987,7 +4919,7 @@ run_update_beacon_cb(void *arg)
static void
run_updateprot(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t i;
i = RUN_CMDQ_GET(&sc->cmdq_store);
@@ -5001,7 +4933,7 @@ static void
run_updateprot_cb(void *arg)
{
struct ieee80211com *ic = arg;
- struct run_softc *sc = ic->ic_ifp->if_softc;
+ struct run_softc *sc = ic->ic_softc;
uint32_t tmp;
tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
@@ -5025,7 +4957,7 @@ static void
run_usb_timeout_cb(void *arg)
{
struct ieee80211vap *vap = arg;
- struct run_softc *sc = vap->iv_ic->ic_ifp->if_softc;
+ struct run_softc *sc = vap->iv_ic->ic_softc;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -5071,12 +5003,12 @@ run_update_promisc_locked(struct run_softc *sc)
run_read(sc, RT2860_RX_FILTR_CFG, &tmp);
tmp |= RT2860_DROP_UC_NOME;
- if (sc->sc_ifp->if_flags & IFF_PROMISC)
+ if (sc->sc_ic.ic_promisc > 0)
tmp &= ~RT2860_DROP_UC_NOME;
run_write(sc, RT2860_RX_FILTR_CFG, tmp);
- DPRINTF("%s promiscuous mode\n", (sc->sc_ifp->if_flags & IFF_PROMISC) ?
+ DPRINTF("%s promiscuous mode\n", (sc->sc_ic.ic_promisc > 0) ?
"entering" : "leaving");
}
@@ -5085,7 +5017,7 @@ run_update_promisc(struct ieee80211com *ic)
{
struct run_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & RUN_RUNNING) == 0)
return;
RUN_LOCK(sc);
@@ -5096,7 +5028,7 @@ run_update_promisc(struct ieee80211com *ic)
static void
run_enable_tsf_sync(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
@@ -5161,7 +5093,7 @@ run_enable_mrr(struct run_softc *sc)
static void
run_set_txpreamble(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
run_read(sc, RT2860_AUTO_RSP_CFG, &tmp);
@@ -5175,7 +5107,7 @@ run_set_txpreamble(struct run_softc *sc)
static void
run_set_basicrates(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
/* set basic rates mask */
if (ic->ic_curmode == IEEE80211_MODE_11B)
@@ -5220,7 +5152,7 @@ run_updateslot(struct ieee80211com *ic)
i = RUN_CMDQ_GET(&sc->cmdq_store);
DPRINTF("cmdq_store=%d\n", i);
sc->cmdq[i].func = run_updateslot_cb;
- sc->cmdq[i].arg0 = ic->ic_ifp;
+ sc->cmdq[i].arg0 = ic;
ieee80211_runtask(ic, &sc->cmdq_task);
return;
@@ -5230,9 +5162,8 @@ run_updateslot(struct ieee80211com *ic)
static void
run_updateslot_cb(void *arg)
{
- struct ifnet *ifp = arg;
- struct run_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = arg;
+ struct run_softc *sc = ic->ic_softc;
uint32_t tmp;
run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp);
@@ -5244,15 +5175,12 @@ run_updateslot_cb(void *arg)
static void
run_update_mcast(struct ieee80211com *ic)
{
-
- /* h/w filter supports getting everything or nothing */
- ic->ic_ifp->if_flags |= IFF_ALLMULTI;
}
static int8_t
run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c = ic->ic_curchan;
int delta;
@@ -5902,7 +5830,7 @@ run_rt5390_rf_setup(struct run_softc *sc)
static int
run_txrx_enable(struct run_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp;
int error, ntries;
@@ -5962,8 +5890,8 @@ run_adjust_freq_offset(struct run_softc *sc)
static void
run_init_locked(struct run_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
uint8_t bbp1, bbp3;
int i;
@@ -5993,7 +5921,7 @@ run_init_locked(struct run_softc *sc)
for (i = 0; i != RUN_EP_QUEUES; i++)
run_setup_tx_list(sc, &sc->sc_epq[i]);
- run_set_macaddr(sc, IF_LLADDR(ifp));
+ run_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
for (ntries = 0; ntries < 100; ntries++) {
if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
@@ -6166,8 +6094,7 @@ run_init_locked(struct run_softc *sc)
/* turn radio LED on */
run_set_leds(sc, RT2860_LED_RADIO);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= RUN_RUNNING;
sc->cmdq_run = RUN_CMDQ_GO;
for (i = 0; i != RUN_N_XFER; i++)
@@ -6185,35 +6112,19 @@ fail:
}
static void
-run_init(void *arg)
-{
- struct run_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RUN_LOCK(sc);
- run_init_locked(sc);
- RUN_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic);
-}
-
-static void
run_stop(void *arg)
{
struct run_softc *sc = (struct run_softc *)arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
int i;
int ntries;
RUN_LOCK_ASSERT(sc, MA_OWNED);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & RUN_RUNNING)
run_set_leds(sc, 0); /* turn all LEDs off */
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~RUN_RUNNING;
sc->ratectl_run = RUN_RATECTL_OFF;
sc->cmdq_run = sc->cmdq_key_set;
diff --git a/sys/dev/usb/wlan/if_runvar.h b/sys/dev/usb/wlan/if_runvar.h
index ad0fc30..b8cb12f 100644
--- a/sys/dev/usb/wlan/if_runvar.h
+++ b/sys/dev/usb/wlan/if_runvar.h
@@ -151,13 +151,16 @@ struct run_endpoint_queue {
};
struct run_softc {
+ struct mtx sc_mtx;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
- struct ifnet *sc_ifp;
int sc_need_fwload;
int sc_flags;
#define RUN_FLAG_FWLOAD_NEEDED 0x01
+#define RUN_RUNNING 0x02
uint16_t wcid_stats[RT2870_WCID_MAX + 1][3];
#define RUN_TXCNT 0
@@ -203,10 +206,6 @@ struct run_softc {
uint32_t txpow40mhz_2ghz[5];
uint32_t txpow40mhz_5ghz[5];
- uint8_t sc_bssid[6];
-
- struct mtx sc_mtx;
-
struct run_endpoint_queue sc_epq[RUN_EP_QUEUES];
struct task ratectl_task;
diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c
index fca9e39..04e09204 100644
--- a/sys/dev/usb/wlan/if_uath.c
+++ b/sys/dev/usb/wlan/if_uath.c
@@ -279,12 +279,11 @@ static int uath_alloc_rx_data_list(struct uath_softc *);
static int uath_alloc_tx_data_list(struct uath_softc *);
static void uath_free_rx_data_list(struct uath_softc *);
static void uath_free_tx_data_list(struct uath_softc *);
-static int uath_init_locked(void *);
-static void uath_init(void *);
-static void uath_stop_locked(struct ifnet *);
-static void uath_stop(struct ifnet *);
-static int uath_ioctl(struct ifnet *, u_long, caddr_t);
-static void uath_start(struct ifnet *);
+static int uath_init(struct uath_softc *);
+static void uath_stop(struct uath_softc *);
+static void uath_parent(struct ieee80211com *);
+static int uath_transmit(struct ieee80211com *, struct mbuf *);
+static void uath_start(struct uath_softc *);
static int uath_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void uath_scan_start(struct ieee80211com *);
@@ -336,11 +335,9 @@ uath_attach(device_t dev)
{
struct uath_softc *sc = device_get_softc(dev);
struct usb_attach_arg *uaa = device_get_ivars(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t bands, iface_index = UATH_IFACE_INDEX; /* XXX */
usb_error_t error;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
sc->sc_udev = uaa->device;
@@ -356,6 +353,7 @@ uath_attach(device_t dev)
MTX_DEF);
callout_init(&sc->stat_ch, 0);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
uath_usbconfig, UATH_N_XFERS, sc, &sc->sc_mtx);
@@ -387,31 +385,24 @@ uath_attach(device_t dev)
error = uath_host_available(sc);
if (error != 0) {
device_printf(sc->sc_dev, "could not initialize adapter\n");
- goto fail3;
+ goto fail2;
}
error = uath_get_devcap(sc);
if (error != 0) {
device_printf(sc->sc_dev,
"could not get device capabilities\n");
- goto fail3;
+ goto fail2;
}
UATH_UNLOCK(sc);
/* Create device sysctl node. */
uath_sysctl_node(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not allocate ifnet\n");
- error = ENXIO;
- goto fail2;
- }
-
UATH_LOCK(sc);
- error = uath_get_devstatus(sc, macaddr);
+ error = uath_get_devstatus(sc, ic->ic_macaddr);
if (error != 0) {
device_printf(sc->sc_dev, "could not get device status\n");
- goto fail4;
+ goto fail2;
}
/*
@@ -420,28 +411,15 @@ uath_attach(device_t dev)
error = uath_alloc_rx_data_list(sc);
if (error != 0) {
device_printf(sc->sc_dev, "could not allocate Rx data list\n");
- goto fail4;
+ goto fail2;
}
error = uath_alloc_tx_data_list(sc);
if (error != 0) {
device_printf(sc->sc_dev, "could not allocate Tx data list\n");
- goto fail4;
+ goto fail2;
}
UATH_UNLOCK(sc);
- ifp->if_softc = sc;
- if_initname(ifp, "uath", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = uath_init;
- ifp->if_ioctl = uath_ioctl;
- ifp->if_start = uath_start;
- /* XXX UATH_TX_DATA_LIST_COUNT */
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -469,16 +447,17 @@ uath_attach(device_t dev)
/* XXX turbo */
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = uath_raw_xmit;
ic->ic_scan_start = uath_scan_start;
ic->ic_scan_end = uath_scan_end;
ic->ic_set_channel = uath_set_channel;
-
ic->ic_vap_create = uath_vap_create;
ic->ic_vap_delete = uath_vap_delete;
ic->ic_update_mcast = uath_update_mcast;
ic->ic_update_promisc = uath_update_promisc;
+ ic->ic_transmit = uath_transmit;
+ ic->ic_parent = uath_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -491,9 +470,8 @@ uath_attach(device_t dev)
return (0);
-fail4: if_free(ifp);
-fail3: UATH_UNLOCK(sc);
-fail2: uath_free_cmd_list(sc, sc->sc_cmd);
+fail2: UATH_UNLOCK(sc);
+ uath_free_cmd_list(sc, sc->sc_cmd);
fail1: usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
fail:
return (error);
@@ -503,8 +481,7 @@ static int
uath_detach(device_t dev)
{
struct uath_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/*
@@ -525,9 +502,9 @@ uath_detach(device_t dev)
STAILQ_INIT(&sc->sc_cmd_pending);
STAILQ_INIT(&sc->sc_cmd_waiting);
STAILQ_INIT(&sc->sc_cmd_inactive);
- UATH_UNLOCK(sc);
- uath_stop(ifp);
+ uath_stop(sc);
+ UATH_UNLOCK(sc);
callout_drain(&sc->stat_ch);
callout_drain(&sc->watchdog_ch);
@@ -547,7 +524,7 @@ uath_detach(device_t dev)
usbd_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS);
ieee80211_ifdetach(ic);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -1067,15 +1044,12 @@ uath_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct uath_vap *) malloc(sizeof(struct uath_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct uath_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -1087,7 +1061,7 @@ uath_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_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -1102,18 +1076,17 @@ uath_vap_delete(struct ieee80211vap *vap)
}
static int
-uath_init_locked(void *arg)
+uath_init(struct uath_softc *sc)
{
- struct uath_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t val;
int error;
UATH_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- uath_stop_locked(ifp);
+ if (sc->sc_flags & UATH_FLAG_INITDONE)
+ uath_stop(sc);
/* reset variables */
sc->sc_intrx_nextnum = sc->sc_msgid = 0;
@@ -1122,7 +1095,8 @@ uath_init_locked(void *arg)
uath_cmd_write(sc, WDCMSG_BIND, &val, sizeof val, 0);
/* set MAC address */
- uath_config_multi(sc, CFG_MAC_ADDR, IF_LLADDR(ifp), IEEE80211_ADDR_LEN);
+ uath_config_multi(sc, CFG_MAC_ADDR,
+ vap ? vap->iv_myaddr : ic->ic_macaddr, IEEE80211_ADDR_LEN);
/* XXX honor net80211 state */
uath_config(sc, CFG_RATE_CONTROL_ENABLE, 0x00000001);
@@ -1171,8 +1145,6 @@ uath_init_locked(void *arg)
UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON,
UATH_FILTER_OP_SET);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->sc_flags |= UATH_FLAG_INITDONE;
callout_reset(&sc->watchdog_ch, hz, uath_watchdog, sc);
@@ -1180,28 +1152,16 @@ uath_init_locked(void *arg)
return (0);
fail:
- uath_stop_locked(ifp);
+ uath_stop(sc);
return (error);
}
static void
-uath_init(void *arg)
-{
- struct uath_softc *sc = arg;
-
- UATH_LOCK(sc);
- (void)uath_init_locked(sc);
- UATH_UNLOCK(sc);
-}
-
-static void
-uath_stop_locked(struct ifnet *ifp)
+uath_stop(struct uath_softc *sc)
{
- struct uath_softc *sc = ifp->if_softc;
UATH_ASSERT_LOCKED(sc);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->sc_flags &= ~UATH_FLAG_INITDONE;
callout_stop(&sc->stat_ch);
@@ -1217,16 +1177,6 @@ uath_stop_locked(struct ifnet *ifp)
uath_cmd_write(sc, WDCMSG_TARGET_STOP, NULL, 0, 0);
}
-static void
-uath_stop(struct ifnet *ifp)
-{
- struct uath_softc *sc = ifp->if_softc;
-
- UATH_LOCK(sc);
- uath_stop_locked(ifp);
- UATH_UNLOCK(sc);
-}
-
static int
uath_config(struct uath_softc *sc, uint32_t reg, uint32_t val)
{
@@ -1329,13 +1279,13 @@ static void
uath_watchdog(void *arg)
{
struct uath_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
device_printf(sc->sc_dev, "device timeout\n");
- /*uath_init(ifp); XXX needs a process context! */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ /*uath_init(sc); XXX needs a process context! */
+ counter_u64_add(ic->ic_oerrors, 1);
return;
}
callout_reset(&sc->watchdog_ch, hz, uath_watchdog, sc);
@@ -1450,12 +1400,8 @@ uath_getbuf(struct uath_softc *sc)
UATH_ASSERT_LOCKED(sc);
bf = _uath_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
-
+ if (bf == NULL)
DPRINTF(sc, UATH_DEBUG_XMIT, "%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -1474,8 +1420,7 @@ static int
uath_set_chan(struct uath_softc *sc, struct ieee80211_channel *c)
{
#ifdef UATH_DEBUG
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
#endif
struct uath_cmd_reset reset;
@@ -1554,47 +1499,28 @@ uath_wme_init(struct uath_softc *sc)
return (error);
}
-static int
-uath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+uath_parent(struct ieee80211com *ic)
{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- struct uath_softc *sc = ifp->if_softc;
- int error;
+ struct uath_softc *sc = ic->ic_softc;
int startall = 0;
UATH_LOCK(sc);
- error = (sc->sc_flags & UATH_FLAG_INVALID) ? ENXIO : 0;
- UATH_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- uath_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- uath_stop(ifp);
- }
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ if (sc->sc_flags & UATH_FLAG_INVALID) {
+ UATH_UNLOCK(sc);
+ return;
}
- return (error);
+ if (ic->ic_nrunning > 0) {
+ if (!(sc->sc_flags & UATH_FLAG_INITDONE)) {
+ uath_init(sc);
+ startall = 1;
+ }
+ } else if (sc->sc_flags & UATH_FLAG_INITDONE)
+ uath_stop(sc);
+ UATH_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static int
@@ -1763,31 +1689,49 @@ uath_freetx(struct mbuf *m)
} while ((m = next) != NULL);
}
+static int
+uath_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct uath_softc *sc = ic->ic_softc;
+ int error;
+
+ UATH_LOCK(sc);
+ if ((sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
+ UATH_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ UATH_UNLOCK(sc);
+ return (error);
+ }
+ uath_start(sc);
+ UATH_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-uath_start(struct ifnet *ifp)
+uath_start(struct uath_softc *sc)
{
struct uath_data *bf;
- struct uath_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m, *next;
uath_datahead frags;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+ UATH_ASSERT_LOCKED(sc);
+
+ if ((sc->sc_flags & UATH_FLAG_INITDONE) == 0 ||
(sc->sc_flags & UATH_FLAG_INVALID))
return;
- UATH_LOCK(sc);
- for (;;) {
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
bf = uath_getbuf(sc);
- if (bf == NULL)
- break;
-
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL) {
- STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
- UATH_STAT_INC(sc, st_tx_inactive);
+ if (bf == NULL) {
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
+
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
@@ -1816,7 +1760,8 @@ uath_start(struct ifnet *ifp)
next = m->m_nextpkt;
if (uath_tx_start(sc, m, ni, bf) != 0) {
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
reclaim:
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
UATH_STAT_INC(sc, st_tx_inactive);
@@ -1847,7 +1792,6 @@ uath_start(struct ifnet *ifp)
sc->sc_tx_timer = 5;
}
- UATH_UNLOCK(sc);
}
static int
@@ -1855,19 +1799,19 @@ uath_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 uath_data *bf;
- struct uath_softc *sc = ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
+ UATH_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ !(sc->sc_flags & UATH_FLAG_INITDONE)) {
m_freem(m);
ieee80211_free_node(ni);
+ UATH_UNLOCK(sc);
return (ENETDOWN);
}
- UATH_LOCK(sc);
/* grab a TX buffer */
bf = uath_getbuf(sc);
if (bf == NULL) {
@@ -1880,7 +1824,6 @@ uath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
sc->sc_seqnum = 0;
if (uath_tx_start(sc, m, ni, bf) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
UATH_STAT_INC(sc, st_tx_inactive);
UATH_UNLOCK(sc);
@@ -1907,12 +1850,11 @@ uath_scan_end(struct ieee80211com *ic)
static void
uath_set_channel(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct uath_softc *sc = ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
UATH_UNLOCK(sc);
return;
}
@@ -1933,7 +1875,7 @@ uath_update_mcast(struct ieee80211com *ic)
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
UATH_UNLOCK(sc);
return;
}
@@ -1953,7 +1895,7 @@ uath_update_promisc(struct ieee80211com *ic)
UATH_LOCK(sc);
if ((sc->sc_flags & UATH_FLAG_INVALID) ||
- (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ (sc->sc_flags & UATH_FLAG_INITDONE) == 0) {
UATH_UNLOCK(sc);
return;
}
@@ -1970,7 +1912,7 @@ static int
uath_create_connection(struct uath_softc *sc, uint32_t connid)
{
const struct ieee80211_rateset *rs;
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct uath_cmd_create_connection create;
@@ -2021,7 +1963,7 @@ uath_set_rates(struct uath_softc *sc, const struct ieee80211_rateset *rs)
static int
uath_write_associd(struct uath_softc *sc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct uath_cmd_set_associd associd;
@@ -2075,7 +2017,7 @@ uath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
int error;
struct ieee80211_node *ni;
struct ieee80211com *ic = vap->iv_ic;
- struct uath_softc *sc = ic->ic_ifp->if_softc;
+ struct uath_softc *sc = ic->ic_softc;
struct uath_vap *uvp = UATH_VAP(vap);
DPRINTF(sc, UATH_DEBUG_STATE,
@@ -2542,8 +2484,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
struct uath_rx_desc **pdesc)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct uath_chunk *chunk;
struct uath_rx_desc *desc;
struct mbuf *m = data->m, *mnew, *mp;
@@ -2555,14 +2496,14 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
if (actlen < (int)UATH_MIN_RXBUFSZ) {
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
"%s: wrong xfer size (len=%d)\n", __func__, actlen);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
chunk = (struct uath_chunk *)data->buf;
if (chunk->seqnum == 0 && chunk->flags == 0 && chunk->length == 0) {
device_printf(sc->sc_dev, "%s: strange response\n", __func__);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
UATH_RESET_INTRX(sc);
return (NULL);
}
@@ -2595,7 +2536,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
if ((sc->sc_intrx_len + sizeof(struct uath_rx_desc) +
chunklen) > UATH_MAX_INTRX_SIZE) {
UATH_STAT_INC(sc, st_invalidlen);
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
if (sc->sc_intrx_head != NULL)
m_freem(sc->sc_intrx_head);
UATH_RESET_INTRX(sc);
@@ -2620,7 +2561,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
if (mnew == NULL) {
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
"%s: can't get new mbuf, drop frame\n", __func__);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
if (sc->sc_intrx_head != NULL)
m_freem(sc->sc_intrx_head);
UATH_RESET_INTRX(sc);
@@ -2661,7 +2602,7 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
DPRINTF(sc, UATH_DEBUG_RECV | UATH_DEBUG_RECV_ALL,
"%s: bad descriptor (len=%d)\n", __func__,
be32toh(desc->len));
- if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
UATH_STAT_INC(sc, st_toobigrxpkt);
if (sc->sc_intrx_head != NULL)
m_freem(sc->sc_intrx_head);
@@ -2673,13 +2614,11 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
/* finalize mbuf */
if (sc->sc_intrx_head == NULL) {
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len =
be32toh(desc->framelen) - UATH_RX_DUMMYSIZE;
m->m_data += sizeof(struct uath_chunk);
} else {
mp = sc->sc_intrx_head;
- mp->m_pkthdr.rcvif = ifp;
mp->m_flags |= M_PKTHDR;
mp->m_pkthdr.len = sc->sc_intrx_len;
m = mp;
@@ -2705,7 +2644,6 @@ uath_data_rxeof(struct usb_xfer *xfer, struct uath_data *data,
tap->wr_antnoise = -95;
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
UATH_RESET_INTRX(sc);
return (m);
@@ -2715,8 +2653,7 @@ static void
uath_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
@@ -2776,10 +2713,8 @@ setup:
m = NULL;
desc = NULL;
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- uath_start(ifp);
UATH_LOCK(sc);
+ uath_start(sc);
break;
default:
/* needs it to the inactive queue due to a error. */
@@ -2792,7 +2727,7 @@ setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -2803,40 +2738,22 @@ static void
uath_data_txeof(struct usb_xfer *xfer, struct uath_data *data)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
UATH_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB &&
- (sc->sc_flags & UATH_FLAG_INVALID) == 0) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- if ((sc->sc_flags & UATH_FLAG_INVALID) == 0)
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
sc->sc_tx_timer = 0;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
uath_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct uath_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct uath_data *data;
UATH_ASSERT_LOCKED(sc);
@@ -2868,19 +2785,18 @@ setup:
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- UATH_UNLOCK(sc);
- uath_start(ifp);
- UATH_LOCK(sc);
+ uath_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
if ((sc->sc_flags & UATH_FLAG_INVALID) == 0)
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
diff --git a/sys/dev/usb/wlan/if_uathvar.h b/sys/dev/usb/wlan/if_uathvar.h
index fae3604..56b5ba3 100644
--- a/sys/dev/usb/wlan/if_uathvar.h
+++ b/sys/dev/usb/wlan/if_uathvar.h
@@ -183,7 +183,8 @@ struct uath_vap {
#define UATH_VAP(vap) ((struct uath_vap *)(vap))
struct uath_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
void *sc_cmd_dma_buf;
diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c
index a2e493e..b882fe3 100644
--- a/sys/dev/usb/wlan/if_upgt.c
+++ b/sys/dev/usb/wlan/if_upgt.c
@@ -128,10 +128,10 @@ static void upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int);
static void upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int);
static uint32_t upgt_chksum_le(const uint32_t *, size_t);
static void upgt_tx_done(struct upgt_softc *, uint8_t *);
-static void upgt_init(void *);
-static void upgt_init_locked(struct upgt_softc *);
-static int upgt_ioctl(struct ifnet *, u_long, caddr_t);
-static void upgt_start(struct ifnet *);
+static void upgt_init(struct upgt_softc *);
+static void upgt_parent(struct ieee80211com *);
+static int upgt_transmit(struct ieee80211com *, struct mbuf *);
+static void upgt_start(struct upgt_softc *);
static int upgt_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void upgt_scan_start(struct ieee80211com *);
@@ -240,12 +240,11 @@ upgt_match(device_t dev)
static int
upgt_attach(device_t dev)
{
- int error;
- struct ieee80211com *ic;
- struct ifnet *ifp;
struct upgt_softc *sc = device_get_softc(dev);
+ struct ieee80211com *ic = &sc->sc_ic;
struct usb_attach_arg *uaa = device_get_ivars(dev);
uint8_t bands, iface_index = UPGT_IFACE_INDEX;
+ int error;
sc->sc_dev = dev;
sc->sc_udev = uaa->device;
@@ -258,6 +257,7 @@ upgt_attach(device_t dev)
MTX_DEF);
callout_init(&sc->sc_led_ch, 0);
callout_init(&sc->sc_watchdog_ch, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
upgt_config, UPGT_N_XFERS, sc, &sc->sc_mtx);
@@ -280,26 +280,20 @@ upgt_attach(device_t dev)
if (error)
goto fail3;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not if_alloc()\n");
- goto fail4;
- }
-
/* Initialize the device. */
error = upgt_device_reset(sc);
if (error)
- goto fail5;
+ goto fail4;
/* Verify the firmware. */
error = upgt_fw_verify(sc);
if (error)
- goto fail5;
+ goto fail4;
/* Calculate device memory space. */
if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) {
device_printf(dev,
"could not find memory space addresses on FW\n");
error = EIO;
- goto fail5;
+ goto fail4;
}
sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1;
sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1;
@@ -316,31 +310,19 @@ upgt_attach(device_t dev)
/* Load the firmware. */
error = upgt_fw_load(sc);
if (error)
- goto fail5;
+ goto fail4;
/* Read the whole EEPROM content and parse it. */
error = upgt_eeprom_read(sc);
if (error)
- goto fail5;
+ goto fail4;
error = upgt_eeprom_parse(sc);
if (error)
- goto fail5;
+ goto fail4;
/* all works related with the device have done here. */
upgt_abort_xfers(sc);
- /* Setup the 802.11 device. */
- ifp->if_softc = sc;
- if_initname(ifp, "upgt", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = upgt_init;
- ifp->if_ioctl = upgt_ioctl;
- ifp->if_start = upgt_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -360,15 +342,16 @@ upgt_attach(device_t dev)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_myaddr);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = upgt_raw_xmit;
ic->ic_scan_start = upgt_scan_start;
ic->ic_scan_end = upgt_scan_end;
ic->ic_set_channel = upgt_set_channel;
-
ic->ic_vap_create = upgt_vap_create;
ic->ic_vap_delete = upgt_vap_delete;
ic->ic_update_mcast = upgt_update_mcast;
+ ic->ic_transmit = upgt_transmit;
+ ic->ic_parent = upgt_parent;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -383,7 +366,6 @@ upgt_attach(device_t dev)
return (0);
-fail5: if_free(ifp);
fail4: upgt_free_rx(sc);
fail3: upgt_free_tx(sc);
fail2: usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
@@ -395,30 +377,13 @@ fail1: mtx_destroy(&sc->sc_mtx);
static void
upgt_txeof(struct usb_xfer *xfer, struct upgt_data *data)
{
- struct upgt_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
-
- UPGT_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
static void
@@ -462,77 +427,43 @@ upgt_get_stats(struct upgt_softc *sc)
upgt_bulk_tx(sc, data_cmd);
}
-static int
-upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+upgt_parent(struct ieee80211com *ic)
{
- struct upgt_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct upgt_softc *sc = ic->ic_softc;
int startall = 0;
UPGT_LOCK(sc);
- error = (sc->sc_flags & UPGT_FLAG_DETACHED) ? ENXIO : 0;
- UPGT_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- upgt_set_multi(sc);
- } else {
- upgt_init(sc);
- startall = 1;
- }
+ if (sc->sc_flags & UPGT_FLAG_DETACHED) {
+ UPGT_UNLOCK(sc);
+ return;
+ }
+ if (ic->ic_nrunning > 0) {
+ if (sc->sc_flags & UPGT_FLAG_INITDONE) {
+ if (ic->ic_allmulti > 0 || ic->ic_promisc > 0)
+ upgt_set_multi(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- upgt_stop(sc);
+ upgt_init(sc);
+ startall = 1;
}
- sc->sc_if_flags = ifp->if_flags;
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ } else if (sc->sc_flags & UPGT_FLAG_INITDONE)
+ upgt_stop(sc);
+ UPGT_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
-upgt_stop_locked(struct upgt_softc *sc)
+upgt_stop(struct upgt_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
UPGT_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & UPGT_FLAG_INITDONE)
upgt_set_macfilter(sc, IEEE80211_S_INIT);
upgt_abort_xfers_locked(sc);
-}
-
-static void
-upgt_stop(struct upgt_softc *sc)
-{
- struct ifnet *ifp = sc->sc_ifp;
-
- UPGT_LOCK(sc);
- upgt_stop_locked(sc);
- UPGT_UNLOCK(sc);
-
/* device down */
sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->sc_flags &= ~UPGT_FLAG_INITDONE;
}
@@ -624,36 +555,18 @@ upgt_set_led_blink(void *arg)
}
static void
-upgt_init(void *priv)
-{
- struct upgt_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- UPGT_LOCK(sc);
- upgt_init_locked(sc);
- UPGT_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
-upgt_init_locked(struct upgt_softc *sc)
+upgt_init(struct upgt_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
UPGT_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- upgt_stop_locked(sc);
+ if (sc->sc_flags & UPGT_FLAG_INITDONE)
+ upgt_stop(sc);
usbd_transfer_start(sc->sc_xfer[UPGT_BULK_RX]);
(void)upgt_set_macfilter(sc, IEEE80211_S_SCAN);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->sc_flags |= UPGT_FLAG_INITDONE;
callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
@@ -662,14 +575,12 @@ upgt_init_locked(struct upgt_softc *sc)
static int
upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct upgt_data *data_cmd;
struct upgt_lmac_mem *mem;
struct upgt_lmac_filter *filter;
- uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
UPGT_ASSERT_LOCKED(sc);
@@ -709,10 +620,11 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
case IEEE80211_S_SCAN:
DPRINTF(sc, UPGT_DEBUG_STATE,
"set MAC filter to SCAN (bssid %s)\n",
- ether_sprintf(broadcast));
+ ether_sprintf(ieee80211broadcastaddr));
filter->type = htole16(UPGT_FILTER_TYPE_NONE);
- IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr);
- IEEE80211_ADDR_COPY(filter->src, broadcast);
+ IEEE80211_ADDR_COPY(filter->dst,
+ vap ? vap->iv_myaddr : ic->ic_macaddr);
+ IEEE80211_ADDR_COPY(filter->src, ieee80211broadcastaddr);
filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
@@ -724,7 +636,8 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
/* XXX monitor mode isn't tested yet. */
if (vap->iv_opmode == IEEE80211_M_MONITOR) {
filter->type = htole16(UPGT_FILTER_TYPE_MONITOR);
- IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr);
+ IEEE80211_ADDR_COPY(filter->dst,
+ vap ? vap->iv_myaddr : ic->ic_macaddr);
IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1);
filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
@@ -736,7 +649,8 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
"set MAC filter to RUN (bssid %s)\n",
ether_sprintf(ni->ni_bssid));
filter->type = htole16(UPGT_FILTER_TYPE_STA);
- IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr);
+ IEEE80211_ADDR_COPY(filter->dst,
+ vap ? vap->iv_myaddr : ic->ic_macaddr);
IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
@@ -765,8 +679,7 @@ upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
static void
upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct upgt_softc *sc = ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
const struct ieee80211_txparam *tp;
/*
@@ -813,39 +726,48 @@ upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic)
static void
upgt_set_multi(void *arg)
{
- struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- if (!(ifp->if_flags & IFF_UP))
- return;
+ /* XXX don't know how to set a device. Lack of docs. */
+}
- /*
- * XXX don't know how to set a device. Lack of docs. Just try to set
- * IFF_ALLMULTI flag here.
- */
- ifp->if_flags |= IFF_ALLMULTI;
+static int
+upgt_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct upgt_softc *sc = ic->ic_softc;
+ int error;
+
+ UPGT_LOCK(sc);
+ if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0) {
+ UPGT_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ UPGT_UNLOCK(sc);
+ return (error);
+ }
+ upgt_start(sc);
+ UPGT_UNLOCK(sc);
+
+ return (0);
}
static void
-upgt_start(struct ifnet *ifp)
+upgt_start(struct upgt_softc *sc)
{
- struct upgt_softc *sc = ifp->if_softc;
struct upgt_data *data_tx;
struct ieee80211_node *ni;
struct mbuf *m;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
+ UPGT_ASSERT_LOCKED(sc);
- UPGT_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ if ((sc->sc_flags & UPGT_FLAG_INITDONE) == 0)
+ return;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
data_tx = upgt_gettxbuf(sc);
if (data_tx == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
@@ -853,15 +775,15 @@ upgt_start(struct ifnet *ifp)
m->m_pkthdr.rcvif = NULL;
if (upgt_tx_start(sc, m, ni, data_tx) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
UPGT_STAT_INC(sc, st_tx_inactive);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
continue;
}
sc->sc_tx_timer = 5;
}
- UPGT_UNLOCK(sc);
}
static int
@@ -869,18 +791,18 @@ upgt_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 upgt_softc *sc = ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
struct upgt_data *data_tx = NULL;
+ UPGT_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & UPGT_FLAG_INITDONE)) {
m_freem(m);
ieee80211_free_node(ni);
+ UPGT_UNLOCK(sc);
return ENETDOWN;
}
- UPGT_LOCK(sc);
data_tx = upgt_gettxbuf(sc);
if (data_tx == NULL) {
ieee80211_free_node(ni);
@@ -893,7 +815,6 @@ upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next);
UPGT_STAT_INC(sc, st_tx_inactive);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
UPGT_UNLOCK(sc);
return (EIO);
}
@@ -907,13 +828,13 @@ static void
upgt_watchdog(void *arg)
{
struct upgt_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
if (sc->sc_tx_timer > 0) {
if (--sc->sc_tx_timer == 0) {
device_printf(sc->sc_dev, "watchdog timeout\n");
- /* upgt_init(ifp); XXX needs a process context ? */
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ /* upgt_init(sc); XXX needs a process context ? */
+ counter_u64_add(ic->ic_oerrors, 1);
return;
}
callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc);
@@ -950,7 +871,7 @@ upgt_scan_end(struct ieee80211com *ic)
static void
upgt_set_channel(struct ieee80211com *ic)
{
- struct upgt_softc *sc = ic->ic_ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
UPGT_LOCK(sc);
upgt_set_chan(sc, ic->ic_curchan);
@@ -960,8 +881,7 @@ upgt_set_channel(struct ieee80211com *ic)
static void
upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct upgt_data *data_cmd;
struct upgt_lmac_mem *mem;
struct upgt_lmac_channel *chan;
@@ -1044,7 +964,7 @@ upgt_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -1059,7 +979,7 @@ upgt_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_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -1069,7 +989,7 @@ upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct upgt_vap *uvp = UPGT_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct upgt_softc *sc = ic->ic_ifp->if_softc;
+ struct upgt_softc *sc = ic->ic_softc;
/* do it in a process context */
sc->sc_state = nstate;
@@ -1125,6 +1045,7 @@ upgt_update_mcast(struct ieee80211com *ic)
static int
upgt_eeprom_parse(struct upgt_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
struct upgt_eeprom_header *eeprom_header;
struct upgt_eeprom_option *eeprom_option;
uint16_t option_len;
@@ -1169,7 +1090,8 @@ upgt_eeprom_parse(struct upgt_softc *sc)
DPRINTF(sc, UPGT_DEBUG_FW,
"EEPROM mac len=%d\n", option_len);
- IEEE80211_ADDR_COPY(sc->sc_myaddr, eeprom_option->data);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr,
+ eeprom_option->data);
break;
case UPGT_EEPROM_TYPE_HWRX:
DPRINTF(sc, UPGT_DEBUG_FW,
@@ -1518,8 +1440,7 @@ upgt_chksum_le(const uint32_t *buf, size_t size)
static struct mbuf *
upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct upgt_lmac_rx_desc *rxdesc;
struct mbuf *m;
@@ -1527,7 +1448,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
* don't pass packets to the ieee80211 framework if the driver isn't
* RUNNING.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!(sc->sc_flags & UPGT_FLAG_INITDONE))
return (NULL);
/* access RX packet descriptor */
@@ -1545,7 +1466,6 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
memcpy(mtod(m, char *), rxdesc->data, pkglen);
/* trim FCS */
m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN;
- m->m_pkthdr.rcvif = ifp;
if (ieee80211_radiotap_active(ic)) {
struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
@@ -1554,7 +1474,6 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
tap->wr_antsignal = rxdesc->rssi;
}
- if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__);
*rssi = rxdesc->rssi;
@@ -1564,8 +1483,7 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi)
static uint8_t
upgt_rx_rate(struct upgt_softc *sc, const int rate)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 };
static const uint8_t ofdm_upgt2rate[12] =
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
@@ -1584,7 +1502,6 @@ upgt_rx_rate(struct upgt_softc *sc, const int rate)
static void
upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
{
- struct ifnet *ifp = sc->sc_ifp;
struct upgt_lmac_tx_done_desc *desc;
int i, freed = 0;
@@ -1613,10 +1530,9 @@ upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
}
if (freed != 0) {
- sc->sc_tx_timer = 0;
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
UPGT_UNLOCK(sc);
- upgt_start(ifp);
+ sc->sc_tx_timer = 0;
+ upgt_start(sc);
UPGT_LOCK(sc);
}
}
@@ -2022,8 +1938,7 @@ static int
upgt_detach(device_t dev)
{
struct upgt_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/*
@@ -2039,9 +1954,9 @@ upgt_detach(device_t dev)
STAILQ_INIT(&sc->sc_rx_active);
STAILQ_INIT(&sc->sc_rx_inactive);
- UPGT_UNLOCK(sc);
upgt_stop(sc);
+ UPGT_UNLOCK(sc);
callout_drain(&sc->sc_led_ch);
callout_drain(&sc->sc_watchdog_ch);
@@ -2060,7 +1975,7 @@ upgt_detach(device_t dev)
usbd_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS);
ieee80211_ifdetach(ic);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -2168,12 +2083,8 @@ upgt_getbuf(struct upgt_softc *sc)
UPGT_ASSERT_LOCKED(sc);
bf = _upgt_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
-
+ if (bf == NULL)
DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -2191,14 +2102,10 @@ upgt_gettxbuf(struct upgt_softc *sc)
bf->addr = upgt_mem_alloc(sc);
if (bf->addr == 0) {
- struct ifnet *ifp = sc->sc_ifp;
-
DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: no free prism memory!\n",
__func__);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
UPGT_STAT_INC(sc, st_tx_inactive);
- if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE))
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return (NULL);
}
return (bf);
@@ -2212,7 +2119,6 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
int error = 0, len;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
- struct ifnet *ifp = sc->sc_ifp;
struct upgt_lmac_mem *mem;
struct upgt_lmac_tx_desc *txdesc;
@@ -2295,7 +2201,7 @@ done:
* will stall. It's strange, but it works, so we keep reading
* the statistics here. *shrug*
*/
- if (!(ifp->if_get_counter(ifp, IFCOUNTER_OPACKETS) %
+ if (!(vap->iv_ifp->if_get_counter(vap->iv_ifp, IFCOUNTER_OPACKETS) %
UPGT_TX_STAT_INTERVAL))
upgt_get_stats(sc);
@@ -2306,8 +2212,7 @@ static void
upgt_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct upgt_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
@@ -2355,10 +2260,8 @@ setup:
(void) ieee80211_input_all(ic, m, rssi, nf);
m = NULL;
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- upgt_start(ifp);
UPGT_LOCK(sc);
+ upgt_start(sc);
break;
default:
/* needs it to the inactive queue due to a error. */
@@ -2369,7 +2272,7 @@ setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -2380,7 +2283,6 @@ static void
upgt_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct upgt_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct upgt_data *data;
UPGT_ASSERT_LOCKED(sc);
@@ -2410,18 +2312,17 @@ setup:
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- UPGT_UNLOCK(sc);
- upgt_start(ifp);
- UPGT_LOCK(sc);
+ upgt_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
diff --git a/sys/dev/usb/wlan/if_upgtvar.h b/sys/dev/usb/wlan/if_upgtvar.h
index c50276b..3dcd335 100644
--- a/sys/dev/usb/wlan/if_upgtvar.h
+++ b/sys/dev/usb/wlan/if_upgtvar.h
@@ -418,8 +418,9 @@ struct upgt_vap {
#define UPGT_VAP(vap) ((struct upgt_vap *)(vap))
struct upgt_softc {
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
- struct ifnet *sc_ifp;
struct usb_device *sc_udev;
void *sc_rx_dma_buf;
void *sc_tx_dma_buf;
@@ -429,11 +430,8 @@ struct upgt_softc {
#define UPGT_FLAG_FWLOADED (1 << 0)
#define UPGT_FLAG_INITDONE (1 << 1)
#define UPGT_FLAG_DETACHED (1 << 2)
- int sc_if_flags;
int sc_debug;
- uint8_t sc_myaddr[IEEE80211_ADDR_LEN];
-
enum ieee80211_state sc_state;
int sc_arg;
int sc_led_blink;
diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c
index 79a5be0..e8224ba 100644
--- a/sys/dev/usb/wlan/if_ural.c
+++ b/sys/dev/usb/wlan/if_ural.c
@@ -149,8 +149,9 @@ static int ural_tx_mgt(struct ural_softc *, struct mbuf *,
struct ieee80211_node *);
static int ural_tx_data(struct ural_softc *, struct mbuf *,
struct ieee80211_node *);
-static void ural_start(struct ifnet *);
-static int ural_ioctl(struct ifnet *, u_long, caddr_t);
+static int ural_transmit(struct ieee80211com *, struct mbuf *);
+static void ural_start(struct ural_softc *);
+static void ural_parent(struct ieee80211com *);
static void ural_set_testmode(struct ural_softc *);
static void ural_eeprom_read(struct ural_softc *, uint16_t, void *,
int);
@@ -171,12 +172,12 @@ static void ural_set_chan(struct ural_softc *,
static void ural_disable_rf_tune(struct ural_softc *);
static void ural_enable_tsf_sync(struct ural_softc *);
static void ural_enable_tsf(struct ural_softc *);
-static void ural_update_slot(struct ifnet *);
+static void ural_update_slot(struct ural_softc *);
static void ural_set_txpreamble(struct ural_softc *);
static void ural_set_basicrates(struct ural_softc *,
const struct ieee80211_channel *);
static void ural_set_bssid(struct ural_softc *, const uint8_t *);
-static void ural_set_macaddr(struct ural_softc *, uint8_t *);
+static void ural_set_macaddr(struct ural_softc *, const uint8_t *);
static void ural_update_promisc(struct ieee80211com *);
static void ural_setpromisc(struct ural_softc *);
static const char *ural_get_rf(int);
@@ -184,8 +185,7 @@ static void ural_read_eeprom(struct ural_softc *);
static int ural_bbp_init(struct ural_softc *);
static void ural_set_txantenna(struct ural_softc *, int);
static void ural_set_rxantenna(struct ural_softc *, int);
-static void ural_init_locked(struct ural_softc *);
-static void ural_init(void *);
+static void ural_init(struct ural_softc *);
static void ural_stop(struct ural_softc *);
static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
@@ -422,8 +422,7 @@ ural_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct ural_softc *sc = device_get_softc(self);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
int error;
@@ -433,6 +432,7 @@ ural_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(self),
MTX_NETWORK_LOCK, MTX_DEF);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = RAL_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device,
@@ -455,24 +455,6 @@ ural_attach(device_t self)
device_printf(self, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n",
sc->asic_rev, ural_get_rf(sc->rf_rev));
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "ural", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = ural_init;
- ifp->if_ioctl = ural_ioctl;
- ifp->if_start = ural_start;
- 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(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -497,13 +479,14 @@ ural_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_update_promisc = ural_update_promisc;
ic->ic_raw_xmit = ural_raw_xmit;
ic->ic_scan_start = ural_scan_start;
ic->ic_scan_end = ural_scan_end;
ic->ic_set_channel = ural_set_channel;
-
+ ic->ic_parent = ural_parent;
+ ic->ic_transmit = ural_transmit;
ic->ic_vap_create = ural_vap_create;
ic->ic_vap_delete = ural_vap_delete;
@@ -527,8 +510,7 @@ static int
ural_detach(device_t self)
{
struct ural_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
/* prevent further ioctls */
RAL_LOCK(sc);
@@ -543,11 +525,9 @@ ural_detach(device_t self)
ural_unsetup_tx_list(sc);
RAL_UNLOCK(sc);
- if (ifp) {
- ic = ifp->if_l2com;
+ if (ic->ic_softc == sc)
ieee80211_ifdetach(ic);
- if_free(ifp);
- }
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -580,7 +560,7 @@ ural_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 ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
struct ural_vap *uvp;
struct ieee80211vap *vap;
@@ -594,7 +574,7 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -610,7 +590,8 @@ ural_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, ieee80211_media_change,
+ ieee80211_media_status, mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -634,13 +615,8 @@ ural_tx_free(struct ural_tx_data *data, int txerr)
struct ural_softc *sc = data->sc;
if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
+ ieee80211_tx_complete(data->ni, data->m, txerr);
data->m = NULL;
-
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
@@ -697,7 +673,7 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ural_vap *uvp = URAL_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
const struct ieee80211_txparam *tp;
struct ieee80211_node *ni;
struct mbuf *m;
@@ -731,11 +707,11 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
ieee80211_free_node(ni);
return (-1);
}
- ural_update_slot(ic->ic_ifp);
+ ural_update_slot(sc);
ural_set_txpreamble(sc);
ural_set_basicrates(sc, ic->ic_bsschan);
- IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
- ural_set_bssid(sc, sc->sc_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, ni->ni_bssid);
+ ural_set_bssid(sc, ic->ic_macaddr);
}
if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -789,7 +765,6 @@ static void
ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct ural_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap;
struct ural_tx_data *data;
struct mbuf *m;
@@ -807,9 +782,6 @@ ural_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
ural_tx_free(data, 0);
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -852,16 +824,13 @@ tr_setup:
usbd_transfer_submit(xfer);
}
- RAL_UNLOCK(sc);
- ural_start(ifp);
- RAL_LOCK(sc);
+ ural_start(sc);
break;
default: /* Error */
DPRINTFN(11, "transfer error, %s\n",
usbd_errstr(error));
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
data = usbd_xfer_get_priv(xfer);
if (data != NULL) {
ural_tx_free(data, error);
@@ -883,8 +852,7 @@ static void
ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct ural_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
struct usb_page_cache *pc;
@@ -902,7 +870,7 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
if (len < (int)(RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
DPRINTF("%s: xfer too short %d\n",
device_get_nameunit(sc->sc_dev), len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
@@ -921,20 +889,19 @@ ural_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
* filled RAL_TXRX_CSR2:
*/
DPRINTFN(5, "PHY or CRC error\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m == NULL) {
DPRINTF("could not allocate mbuf\n");
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
usbd_copy_out(pc, 0, mtod(m, uint8_t *), len);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
if (ieee80211_radiotap_active(ic)) {
@@ -973,10 +940,8 @@ tr_setup:
} else
(void) ieee80211_input_all(ic, m, rssi, nf);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- ural_start(ifp);
RAL_LOCK(sc);
+ ural_start(sc);
return;
default: /* Error */
@@ -1016,8 +981,7 @@ static void
ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc,
uint32_t flags, int len, int rate)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t plcp_length;
int remainder;
@@ -1066,12 +1030,10 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = sc->sc_ifp;
const struct ieee80211_txparam *tp;
struct ural_tx_data *data;
if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
m_freem(m0);
ieee80211_free_node(ni);
return (EIO);
@@ -1348,78 +1310,73 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
return 0;
}
+static int
+ural_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct ural_softc *sc = ic->ic_softc;
+ int error;
+
+ RAL_LOCK(sc);
+ if (!sc->sc_running) {
+ RAL_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ RAL_UNLOCK(sc);
+ return (error);
+ }
+ ural_start(sc);
+ RAL_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-ural_start(struct ifnet *ifp)
+ural_start(struct ural_softc *sc)
{
- struct ural_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- RAL_LOCK(sc);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- RAL_UNLOCK(sc);
+ RAL_LOCK_ASSERT(sc, MA_OWNED);
+
+ if (sc->sc_running == 0)
return;
- }
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree < RAL_TX_MINFREE) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+
+ while (sc->tx_nfree >= RAL_TX_MINFREE &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (ural_tx_data(sc, m, ni) != 0) {
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
}
}
- RAL_UNLOCK(sc);
}
-static int
-ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+ural_parent(struct ieee80211com *ic)
{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct ural_softc *sc = ic->ic_softc;
int startall = 0;
RAL_LOCK(sc);
- error = sc->sc_detached ? ENXIO : 0;
- RAL_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- RAL_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- ural_init_locked(sc);
- startall = 1;
- } else
- ural_setpromisc(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ural_stop(sc);
- }
+ if (sc->sc_detached) {
RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- default:
- error = ether_ioctl(ifp, cmd, data);
- break;
+ return;
}
- return error;
+ if (ic->ic_nrunning > 0) {
+ if (sc->sc_running == 0) {
+ ural_init(sc);
+ startall = 1;
+ } else
+ ural_setpromisc(sc);
+ } else if (sc->sc_running)
+ ural_stop(sc);
+ RAL_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
@@ -1614,23 +1571,22 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
static void
ural_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
ural_write(sc, RAL_TXRX_CSR19, 0);
- ural_set_bssid(sc, ifp->if_broadcastaddr);
+ ural_set_bssid(sc, ieee80211broadcastaddr);
RAL_UNLOCK(sc);
}
static void
ural_scan_end(struct ieee80211com *ic)
{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
ural_enable_tsf_sync(sc);
- ural_set_bssid(sc, sc->sc_bssid);
+ ural_set_bssid(sc, ic->ic_macaddr);
RAL_UNLOCK(sc);
}
@@ -1638,7 +1594,7 @@ ural_scan_end(struct ieee80211com *ic)
static void
ural_set_channel(struct ieee80211com *ic)
{
- struct ural_softc *sc = ic->ic_ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
ural_set_chan(sc, ic->ic_curchan);
@@ -1648,8 +1604,7 @@ ural_set_channel(struct ieee80211com *ic)
static void
ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t power, tmp;
int i, chan;
@@ -1780,8 +1735,7 @@ ural_disable_rf_tune(struct ural_softc *sc)
static void
ural_enable_tsf_sync(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t logcwmin, preload, tmp;
@@ -1817,10 +1771,9 @@ ural_enable_tsf(struct ural_softc *sc)
#define RAL_RXTX_TURNAROUND 5 /* us */
static void
-ural_update_slot(struct ifnet *ifp)
+ural_update_slot(struct ural_softc *sc)
{
- struct ural_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t slottime, sifs, eifs;
slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
@@ -1845,8 +1798,7 @@ ural_update_slot(struct ifnet *ifp)
static void
ural_set_txpreamble(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t tmp;
tmp = ural_read(sc, RAL_TXRX_CSR10);
@@ -1893,7 +1845,7 @@ ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid)
}
static void
-ural_set_macaddr(struct ural_softc *sc, uint8_t *addr)
+ural_set_macaddr(struct ural_softc *sc, const uint8_t *addr)
{
uint16_t tmp;
@@ -1912,18 +1864,17 @@ ural_set_macaddr(struct ural_softc *sc, uint8_t *addr)
static void
ural_setpromisc(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
tmp = ural_read(sc, RAL_TXRX_CSR2);
tmp &= ~RAL_DROP_NOT_TO_ME;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (sc->sc_ic.ic_promisc == 0)
tmp |= RAL_DROP_NOT_TO_ME;
ural_write(sc, RAL_TXRX_CSR2, tmp);
- DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
+ DPRINTF("%s promiscuous mode\n", sc->sc_ic.ic_promisc ?
"entering" : "leaving");
}
@@ -1932,11 +1883,9 @@ ural_update_promisc(struct ieee80211com *ic)
{
struct ural_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
RAL_LOCK(sc);
- ural_setpromisc(sc);
+ if (sc->sc_running)
+ ural_setpromisc(sc);
RAL_UNLOCK(sc);
}
@@ -1958,6 +1907,7 @@ ural_get_rf(int rev)
static void
ural_read_eeprom(struct ural_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t val;
ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2);
@@ -1970,7 +1920,7 @@ ural_read_eeprom(struct ural_softc *sc)
sc->nb_ant = val & 0x3;
/* read MAC address */
- ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, sc->sc_bssid, 6);
+ ural_eeprom_read(sc, RAL_EEPROM_ADDRESS, ic->ic_macaddr, 6);
/* read default values for BBP registers */
ural_eeprom_read(sc, RAL_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
@@ -2064,11 +2014,11 @@ ural_set_rxantenna(struct ural_softc *sc, int antenna)
}
static void
-ural_init_locked(struct ural_softc *sc)
+ural_init(struct ural_softc *sc)
{
#define N(a) ((int)(sizeof (a) / sizeof ((a)[0])))
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t tmp;
int i, ntries;
@@ -2115,7 +2065,7 @@ ural_init_locked(struct ural_softc *sc)
ural_set_txantenna(sc, sc->tx_ant);
ural_set_rxantenna(sc, sc->rx_ant);
- ural_set_macaddr(sc, IF_LLADDR(ifp));
+ ural_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
/*
* Allocate Tx and Rx xfer queues.
@@ -2128,13 +2078,12 @@ ural_init_locked(struct ural_softc *sc)
tmp |= RAL_DROP_CTL | RAL_DROP_BAD_VERSION;
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
tmp |= RAL_DROP_TODS;
- if (!(ifp->if_flags & IFF_PROMISC))
+ if (ic->ic_promisc == 0)
tmp |= RAL_DROP_NOT_TO_ME;
}
ural_write(sc, RAL_TXRX_CSR2, tmp);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_running = 1;
usbd_xfer_set_stall(sc->sc_xfer[URAL_BULK_WR]);
usbd_transfer_start(sc->sc_xfer[URAL_BULK_RD]);
return;
@@ -2144,28 +2093,12 @@ fail: ural_stop(sc);
}
static void
-ural_init(void *priv)
-{
- struct ural_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- RAL_LOCK(sc);
- ural_init_locked(sc);
- RAL_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
ural_stop(struct ural_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc, MA_OWNED);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_running = 0;
/*
* Drain all the transfers, if not already drained:
@@ -2193,27 +2126,23 @@ ural_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 ural_softc *sc = ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->sc_running) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->tx_nfree < RAL_TX_MINFREE) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return EIO;
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
-
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -2232,7 +2161,6 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
RAL_UNLOCK(sc);
return 0;
bad:
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
RAL_UNLOCK(sc);
ieee80211_free_node(ni);
return EIO; /* XXX */
@@ -2266,8 +2194,7 @@ ural_ratectl_task(void *arg, int pending)
struct ural_vap *uvp = arg;
struct ieee80211vap *vap = &uvp->vap;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct ural_softc *sc = ifp->if_softc;
+ struct ural_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
int ok, fail;
int sum, retrycnt;
@@ -2286,7 +2213,8 @@ ural_ratectl_task(void *arg, int pending)
ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
(void) ieee80211_ratectl_rate(ni, NULL, 0);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, fail); /* count TX retry-fail as Tx errors */
+ /* count TX retry-fail as Tx errors */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, fail);
usb_callout_reset(&uvp->ratectl_ch, hz, ural_ratectl_timeout, uvp);
RAL_UNLOCK(sc);
diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h
index c62b0e4..f40f71d 100644
--- a/sys/dev/usb/wlan/if_uralvar.h
+++ b/sys/dev/usb/wlan/if_uralvar.h
@@ -89,7 +89,8 @@ enum {
};
struct ural_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -109,8 +110,8 @@ struct ural_softc {
uint16_t sta[11];
uint32_t rf_regs[4];
uint8_t txpow[14];
- uint8_t sc_bssid[6];
- uint8_t sc_detached;
+ u_int sc_detached:1,
+ sc_running:1;
struct {
uint8_t val;
diff --git a/sys/dev/usb/wlan/if_urtw.c b/sys/dev/usb/wlan/if_urtw.c
index f8b77d4..f0d2674 100644
--- a/sys/dev/usb/wlan/if_urtw.c
+++ b/sys/dev/usb/wlan/if_urtw.c
@@ -651,11 +651,11 @@ static struct ieee80211vap *urtw_vap_create(struct ieee80211com *,
int, const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
static void urtw_vap_delete(struct ieee80211vap *);
-static void urtw_init(void *);
-static void urtw_stop(struct ifnet *);
-static void urtw_stop_locked(struct ifnet *);
-static int urtw_ioctl(struct ifnet *, u_long, caddr_t);
-static void urtw_start(struct ifnet *);
+static void urtw_init(struct urtw_softc *);
+static void urtw_stop(struct urtw_softc *);
+static void urtw_parent(struct ieee80211com *);
+static int urtw_transmit(struct ieee80211com *, struct mbuf *);
+static void urtw_start(struct urtw_softc *);
static int urtw_alloc_rx_data_list(struct urtw_softc *);
static int urtw_alloc_tx_data_list(struct urtw_softc *);
static int urtw_raw_xmit(struct ieee80211_node *, struct mbuf *,
@@ -784,8 +784,7 @@ urtw_attach(device_t dev)
int ret = ENXIO;
struct urtw_softc *sc = device_get_softc(dev);
struct usb_attach_arg *uaa = device_get_ivars(dev);
- struct ieee80211com *ic;
- struct ifnet *ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t bands, iface_index = URTW_IFACE_INDEX; /* XXX */
uint16_t n_setup;
uint32_t data;
@@ -807,6 +806,7 @@ urtw_attach(device_t dev)
TASK_INIT(&sc->sc_led_task, 0, urtw_ledtask, sc);
TASK_INIT(&sc->sc_updateslot_task, 0, urtw_updateslottask, sc);
callout_init(&sc->sc_watchdog_ch, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
if (sc->sc_flags & URTW_RTL8187B) {
setup_start = urtw_8187b_usbconfig;
@@ -861,26 +861,6 @@ urtw_attach(device_t dev)
sc->sc_currate = 3;
sc->sc_preamble_mode = urtw_preamble_mode;
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not allocate ifnet\n");
- ret = ENOMEM;
- goto fail1;
- }
-
- ifp->if_softc = sc;
- if_initname(ifp, "urtw", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = urtw_init;
- ifp->if_ioctl = urtw_ioctl;
- ifp->if_start = urtw_start;
- /* XXX URTW_TX_DATA_LIST_COUNT */
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -901,7 +881,7 @@ urtw_attach(device_t dev)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = urtw_raw_xmit;
ic->ic_scan_start = urtw_scan_start;
ic->ic_scan_end = urtw_scan_end;
@@ -910,6 +890,8 @@ urtw_attach(device_t dev)
ic->ic_vap_create = urtw_vap_create;
ic->ic_vap_delete = urtw_vap_delete;
ic->ic_update_mcast = urtw_update_mcast;
+ ic->ic_parent = urtw_parent;
+ ic->ic_transmit = urtw_transmit;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -923,8 +905,9 @@ urtw_attach(device_t dev)
ieee80211_announce(ic);
return (0);
-fail: URTW_UNLOCK(sc);
-fail1: usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
+fail:
+ URTW_UNLOCK(sc);
+ usbd_transfer_unsetup(sc->sc_xfer, (sc->sc_flags & URTW_RTL8187B) ?
URTW_8187B_N_XFERS : URTW_8187L_N_XFERS);
fail0:
return (ret);
@@ -934,18 +917,16 @@ static int
urtw_detach(device_t dev)
{
struct urtw_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
unsigned int n_xfers;
/* Prevent further ioctls */
URTW_LOCK(sc);
sc->sc_flags |= URTW_DETACHED;
+ urtw_stop(sc);
URTW_UNLOCK(sc);
- urtw_stop(ifp);
-
ieee80211_draintask(ic, &sc->sc_updateslot_task);
ieee80211_draintask(ic, &sc->sc_led_task);
@@ -979,7 +960,7 @@ urtw_detach(device_t dev)
usbd_transfer_unsetup(sc->sc_xfer, n_xfers);
ieee80211_ifdetach(ic);
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
}
@@ -1032,15 +1013,12 @@ urtw_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct urtw_vap *) malloc(sizeof(struct urtw_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct urtw_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -1052,7 +1030,7 @@ urtw_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_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -1067,15 +1045,15 @@ urtw_vap_delete(struct ieee80211vap *vap)
}
static void
-urtw_init_locked(void *arg)
+urtw_init(struct urtw_softc *sc)
{
- int ret;
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
usb_error_t error;
+ int ret;
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtw_stop_locked(ifp);
+ URTW_ASSERT_LOCKED(sc);
+
+ if (sc->sc_flags & URTW_RUNNING)
+ urtw_stop(sc);
error = (sc->sc_flags & URTW_RTL8187B) ? urtw_adapter_start_b(sc) :
urtw_adapter_start(sc);
@@ -1105,24 +1083,13 @@ urtw_init_locked(void *arg)
if (sc->sc_flags & URTW_RTL8187B)
usbd_transfer_start(sc->sc_xfer[URTW_8187B_BULK_TX_STATUS]);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= URTW_RUNNING;
callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
fail:
return;
}
-static void
-urtw_init(void *arg)
-{
- struct urtw_softc *sc = arg;
-
- URTW_LOCK(sc);
- urtw_init_locked(arg);
- URTW_UNLOCK(sc);
-}
-
static usb_error_t
urtw_adapter_start_b(struct urtw_softc *sc)
{
@@ -1215,6 +1182,7 @@ fail:
static usb_error_t
urtw_adapter_start(struct urtw_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
usb_error_t error;
error = urtw_reset(sc);
@@ -1234,8 +1202,8 @@ urtw_adapter_start(struct urtw_softc *sc)
if (error)
goto fail;
/* applying MAC address again. */
- urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
- urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
+ urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
+ urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
if (error)
goto fail;
@@ -1338,13 +1306,14 @@ urtw_do_request(struct urtw_softc *sc,
}
static void
-urtw_stop_locked(struct ifnet *ifp)
+urtw_stop(struct urtw_softc *sc)
{
- struct urtw_softc *sc = ifp->if_softc;
uint8_t data8;
usb_error_t error;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ URTW_ASSERT_LOCKED(sc);
+
+ sc->sc_flags &= ~URTW_RUNNING;
error = urtw_intr_disable(sc);
if (error)
@@ -1377,16 +1346,6 @@ fail:
}
static void
-urtw_stop(struct ifnet *ifp)
-{
- struct urtw_softc *sc = ifp->if_softc;
-
- URTW_LOCK(sc);
- urtw_stop_locked(ifp);
- URTW_UNLOCK(sc);
-}
-
-static void
urtw_abort_xfers(struct urtw_softc *sc)
{
int i, max;
@@ -1401,72 +1360,71 @@ urtw_abort_xfers(struct urtw_softc *sc)
usbd_transfer_stop(sc->sc_xfer[i]);
}
-static int
-urtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+urtw_parent(struct ieee80211com *ic)
{
- struct urtw_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct urtw_softc *sc = ic->ic_softc;
int startall = 0;
URTW_LOCK(sc);
- error = (sc->sc_flags & URTW_DETACHED) ? ENXIO : 0;
- URTW_UNLOCK(sc);
- if (error)
- return (error);
+ if (sc->sc_flags & URTW_DETACHED) {
+ URTW_UNLOCK(sc);
+ return;
+ }
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if ((ifp->if_flags ^ sc->sc_if_flags) &
- (IFF_ALLMULTI | IFF_PROMISC))
- urtw_set_multi(sc);
- } else {
- urtw_init(ifp->if_softc);
- startall = 1;
- }
+ if (ic->ic_nrunning > 0) {
+ if (sc->sc_flags & URTW_RUNNING) {
+ if (ic->ic_promisc > 0 || ic->ic_allmulti > 0)
+ urtw_set_multi(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtw_stop(ifp);
+ urtw_init(sc);
+ startall = 1;
}
- sc->sc_if_flags = ifp->if_flags;
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ } else if (sc->sc_flags & URTW_RUNNING)
+ urtw_stop(sc);
+ URTW_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
+}
+
+static int
+urtw_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct urtw_softc *sc = ic->ic_softc;
+ int error;
+
+ URTW_LOCK(sc);
+ if ((sc->sc_flags & URTW_RUNNING) == 0) {
+ URTW_UNLOCK(sc);
+ return (ENXIO);
}
- return (error);
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ URTW_UNLOCK(sc);
+ return (error);
+ }
+ urtw_start(sc);
+ URTW_UNLOCK(sc);
+
+ return (0);
}
static void
-urtw_start(struct ifnet *ifp)
+urtw_start(struct urtw_softc *sc)
{
struct urtw_data *bf;
- struct urtw_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ URTW_ASSERT_LOCKED(sc);
+
+ if ((sc->sc_flags & URTW_RUNNING) == 0)
return;
- URTW_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
bf = urtw_getbuf(sc);
if (bf == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
@@ -1474,7 +1432,8 @@ urtw_start(struct ifnet *ifp)
m->m_pkthdr.rcvif = NULL;
if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_NORMAL) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
ieee80211_free_node(ni);
break;
@@ -1483,7 +1442,6 @@ urtw_start(struct ifnet *ifp)
sc->sc_txtimer = 5;
callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
}
- URTW_UNLOCK(sc);
}
static int
@@ -1565,12 +1523,11 @@ urtw_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 urtw_softc *sc = ic->ic_softc;
struct urtw_data *bf;
- struct urtw_softc *sc = ifp->if_softc;
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & URTW_RUNNING)) {
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
@@ -1584,10 +1541,8 @@ urtw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return (ENOBUFS); /* XXX */
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if (urtw_tx_start(sc, ni, m, bf, URTW_PRIORITY_LOW) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
URTW_UNLOCK(sc);
return (EIO);
@@ -1615,8 +1570,7 @@ urtw_scan_end(struct ieee80211com *ic)
static void
urtw_set_channel(struct ieee80211com *ic)
{
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
- struct ifnet *ifp = sc->sc_ifp;
+ struct urtw_softc *sc = ic->ic_softc;
uint32_t data, orig;
usb_error_t error;
@@ -1626,7 +1580,7 @@ urtw_set_channel(struct ieee80211com *ic)
* initialization would be failed if setting a channel is called before
* the init have done.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!(sc->sc_flags & URTW_RUNNING))
return;
if (sc->sc_curchan != NULL && sc->sc_curchan == ic->ic_curchan)
@@ -1673,11 +1627,10 @@ static int
urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0,
struct urtw_data *data, int prior)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_frame *wh = mtod(m0, struct ieee80211_frame *);
struct ieee80211_key *k;
const struct ieee80211_txparam *tp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct usb_xfer *rtl8187b_pipes[URTW_8187B_TXPIPE_MAX] = {
sc->sc_xfer[URTW_8187B_BULK_TX_BE],
@@ -1862,7 +1815,7 @@ static int
urtw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct ieee80211com *ic = vap->iv_ic;
- struct urtw_softc *sc = ic->ic_ifp->if_softc;
+ struct urtw_softc *sc = ic->ic_softc;
struct urtw_vap *uvp = URTW_VAP(vap);
struct ieee80211_node *ni;
usb_error_t error = 0;
@@ -1915,12 +1868,11 @@ static void
urtw_watchdog(void *arg)
{
struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
if (sc->sc_txtimer > 0) {
if (--sc->sc_txtimer == 0) {
device_printf(sc->sc_dev, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
return;
}
callout_reset(&sc->sc_watchdog_ch, hz, urtw_watchdog, sc);
@@ -1930,17 +1882,7 @@ urtw_watchdog(void *arg)
static void
urtw_set_multi(void *arg)
{
- struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
-
- if (!(ifp->if_flags & IFF_UP))
- return;
-
- /*
- * XXX don't know how to set a device. Lack of docs. Just try to set
- * IFF_ALLMULTI flag here.
- */
- ifp->if_flags |= IFF_ALLMULTI;
+ /* XXX don't know how to set a device. Lack of docs. */
}
static usb_error_t
@@ -2002,8 +1944,7 @@ urtw_rtl2rate(uint32_t rate)
static usb_error_t
urtw_update_msr(struct urtw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t data;
usb_error_t error;
@@ -2144,24 +2085,25 @@ urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data)
static usb_error_t
urtw_get_macaddr(struct urtw_softc *sc)
{
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t data;
usb_error_t error;
error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR, &data);
if (error != 0)
goto fail;
- sc->sc_bssid[0] = data & 0xff;
- sc->sc_bssid[1] = (data & 0xff00) >> 8;
+ ic->ic_macaddr[0] = data & 0xff;
+ ic->ic_macaddr[1] = (data & 0xff00) >> 8;
error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 1, &data);
if (error != 0)
goto fail;
- sc->sc_bssid[2] = data & 0xff;
- sc->sc_bssid[3] = (data & 0xff00) >> 8;
+ ic->ic_macaddr[2] = data & 0xff;
+ ic->ic_macaddr[3] = (data & 0xff00) >> 8;
error = urtw_eprom_read32(sc, URTW_EPROM_MACADDR + 2, &data);
if (error != 0)
goto fail;
- sc->sc_bssid[4] = data & 0xff;
- sc->sc_bssid[5] = (data & 0xff00) >> 8;
+ ic->ic_macaddr[4] = data & 0xff;
+ ic->ic_macaddr[5] = (data & 0xff00) >> 8;
fail:
return (error);
}
@@ -3233,7 +3175,7 @@ fail:
static usb_error_t
urtw_8225v2b_rf_init(struct urtw_softc *sc)
{
-#define N(a) ((int)(sizeof(a) / sizeof((a)[0])))
+ struct ieee80211com *ic = &sc->sc_ic;
int i;
uint8_t data8;
usb_error_t error;
@@ -3281,8 +3223,8 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
urtw_write8_m(sc, URTW_CONFIG1, data8);
/* applying MAC address again. */
- urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)sc->sc_bssid)[0]);
- urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)sc->sc_bssid)[1] & 0xffff);
+ urtw_write32_m(sc, URTW_MAC0, ((uint32_t *)ic->ic_macaddr)[0]);
+ urtw_write16_m(sc, URTW_MAC4, ((uint32_t *)ic->ic_macaddr)[1] & 0xffff);
error = urtw_set_mode(sc, URTW_EPROM_CMD_NORMAL);
if (error)
@@ -3293,7 +3235,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
/*
* MAC configuration
*/
- for (i = 0; i < N(urtw_8225v2b_rf_part1); i++)
+ for (i = 0; i < nitems(urtw_8225v2b_rf_part1); i++)
urtw_write8_m(sc, urtw_8225v2b_rf_part1[i].reg,
urtw_8225v2b_rf_part1[i].val);
urtw_write16_m(sc, URTW_TID_AC_MAP, 0xfa50);
@@ -3326,7 +3268,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1fff);
usb_pause_mtx(&sc->sc_mtx, 1100);
- for (i = 0; i < N(urtw_8225v2b_rf_part0); i++) {
+ for (i = 0; i < nitems(urtw_8225v2b_rf_part0); i++) {
urtw_8225_write(sc, urtw_8225v2b_rf_part0[i].reg,
urtw_8225v2b_rf_part0[i].val);
usb_pause_mtx(&sc->sc_mtx, 1);
@@ -3372,7 +3314,7 @@ urtw_8225v2b_rf_init(struct urtw_softc *sc)
}
urtw_8187_write_phy_ofdm(sc, 0x80, 0x10);
- for (i = 0; i < N(urtw_8225v2b_rf_part2); i++)
+ for (i = 0; i < nitems(urtw_8225v2b_rf_part2); i++)
urtw_8187_write_phy_ofdm(sc, i, urtw_8225v2b_rf_part2[i].val);
urtw_write32_m(sc, URTW_8187B_AC_VO, (7 << 12) | (3 << 8) | 0x1c);
@@ -3787,8 +3729,7 @@ static void
urtw_led_ch(void *arg)
{
struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
ieee80211_runtask(ic, &sc->sc_led_task);
}
@@ -3935,8 +3876,7 @@ fail:
static usb_error_t
urtw_rx_setconf(struct urtw_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t data;
usb_error_t error;
@@ -3961,7 +3901,7 @@ urtw_rx_setconf(struct urtw_softc *sc)
data = data | URTW_RX_FILTER_CRCERR;
if (ic->ic_opmode == IEEE80211_M_MONITOR ||
- (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) {
+ ic->ic_promisc > 0 || ic->ic_allmulti > 0) {
data = data | URTW_RX_FILTER_ALLMAC;
} else {
data = data | URTW_RX_FILTER_NICMAC;
@@ -3988,14 +3928,13 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
struct ieee80211_frame *wh;
struct mbuf *m, *mnew;
struct urtw_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t noise = 0, rate;
usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
if (actlen < (int)URTW_MIN_RXBUFSZ) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -4006,7 +3945,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
(actlen - (sizeof(struct urtw_8187b_rxhdr))));
flen = le32toh(rx->flag) & 0xfff;
if (flen > actlen) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
rate = (le32toh(rx->flag) >> URTW_RX_FLAG_RXRATE_SHIFT) & 0xf;
@@ -4020,7 +3959,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
(actlen - (sizeof(struct urtw_8187l_rxhdr))));
flen = le32toh(rx->flag) & 0xfff;
if (flen > actlen) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -4032,7 +3971,7 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -4041,7 +3980,6 @@ urtw_rxeof(struct usb_xfer *xfer, struct urtw_data *data, int *rssi_p,
data->buf = mtod(mnew, uint8_t *);
/* finalize mbuf */
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = flen - IEEE80211_CRC_LEN;
if (ieee80211_radiotap_active(ic)) {
@@ -4067,8 +4005,7 @@ static void
urtw_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL;
@@ -4129,7 +4066,7 @@ setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -4143,7 +4080,7 @@ static void
urtw_txstatus_eof(struct usb_xfer *xfer)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
int actlen, type, pktretry, seq;
uint64_t val;
@@ -4158,7 +4095,7 @@ urtw_txstatus_eof(struct usb_xfer *xfer)
pktretry = val & 0xff;
seq = (val >> 16) & 0xff;
if (pktretry == URTW_TX_MAXRETRY)
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(ic->ic_oerrors, 1);
DPRINTF(sc, URTW_DEBUG_TXSTATUS, "pktretry %d seq %#x\n",
pktretry, seq);
}
@@ -4168,7 +4105,7 @@ static void
urtw_bulk_tx_status_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
void *dma_buf = usbd_xfer_get_frame_buffer(xfer, 0);
URTW_ASSERT_LOCKED(sc);
@@ -4186,7 +4123,7 @@ setup:
default:
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto setup;
}
break;
@@ -4197,38 +4134,22 @@ static void
urtw_txeof(struct usb_xfer *xfer, struct urtw_data *data)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
URTW_ASSERT_LOCKED(sc);
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
sc->sc_txtimer = 0;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
urtw_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtw_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct urtw_data *data;
URTW_ASSERT_LOCKED(sc);
@@ -4256,18 +4177,17 @@ setup:
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- URTW_UNLOCK(sc);
- urtw_start(ifp);
- URTW_LOCK(sc);
+ urtw_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
@@ -4301,12 +4221,8 @@ urtw_getbuf(struct urtw_softc *sc)
URTW_ASSERT_LOCKED(sc);
bf = _urtw_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
-
+ if (bf == NULL)
DPRINTF(sc, URTW_DEBUG_XMIT, "%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -4378,14 +4294,14 @@ static void
urtw_updateslottask(void *arg, int pending)
{
struct urtw_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
int error;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
URTW_LOCK(sc);
+ if ((sc->sc_flags & URTW_RUNNING) == 0) {
+ URTW_UNLOCK(sc);
+ return;
+ }
if (sc->sc_flags & URTW_RTL8187B) {
urtw_write8_m(sc, URTW_SIFS, 0x22);
if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan))
diff --git a/sys/dev/usb/wlan/if_urtwn.c b/sys/dev/usb/wlan/if_urtwn.c
index 6b712b3..457a885 100644
--- a/sys/dev/usb/wlan/if_urtwn.c
+++ b/sys/dev/usb/wlan/if_urtwn.c
@@ -169,8 +169,8 @@ static device_detach_t urtwn_detach;
static usb_callback_t urtwn_bulk_tx_callback;
static usb_callback_t urtwn_bulk_rx_callback;
-static usb_error_t urtwn_do_request(struct urtwn_softc *sc,
- struct usb_device_request *req, void *data);
+static usb_error_t urtwn_do_request(struct urtwn_softc *,
+ struct usb_device_request *, void *);
static struct ieee80211vap *urtwn_vap_create(struct ieee80211com *,
const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
const uint8_t [IEEE80211_ADDR_LEN],
@@ -228,10 +228,9 @@ static int8_t urtwn_r88e_get_rssi(struct urtwn_softc *, int, void *);
static int urtwn_tx_start(struct urtwn_softc *,
struct ieee80211_node *, struct mbuf *,
struct urtwn_data *);
-static void urtwn_start(struct ifnet *);
-static void urtwn_start_locked(struct ifnet *,
- struct urtwn_softc *);
-static int urtwn_ioctl(struct ifnet *, u_long, caddr_t);
+static int urtwn_transmit(struct ieee80211com *, struct mbuf *);
+static void urtwn_start(struct urtwn_softc *);
+static void urtwn_parent(struct ieee80211com *);
static int urtwn_r92c_power_on(struct urtwn_softc *);
static int urtwn_r88e_power_on(struct urtwn_softc *);
static int urtwn_llt_init(struct urtwn_softc *);
@@ -269,10 +268,8 @@ static void urtwn_set_chan(struct urtwn_softc *,
static void urtwn_update_mcast(struct ieee80211com *);
static void urtwn_iq_calib(struct urtwn_softc *);
static void urtwn_lc_calib(struct urtwn_softc *);
-static void urtwn_init(void *);
-static void urtwn_init_locked(void *);
-static void urtwn_stop(struct ifnet *);
-static void urtwn_stop_locked(struct ifnet *);
+static void urtwn_init(struct urtwn_softc *);
+static void urtwn_stop(struct urtwn_softc *);
static void urtwn_abort_xfers(struct urtwn_softc *);
static int urtwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
@@ -368,8 +365,7 @@ urtwn_attach(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
struct urtwn_softc *sc = device_get_softc(self);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
int error;
@@ -382,6 +378,7 @@ urtwn_attach(device_t self)
mtx_init(&sc->sc_mtx, device_get_nameunit(self),
MTX_NETWORK_LOCK, MTX_DEF);
callout_init(&sc->sc_watchdog_ch, 0);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = URTWN_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer,
@@ -424,24 +421,6 @@ urtwn_attach(device_t self)
URTWN_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ic = ifp->if_l2com;
-
- ifp->if_softc = sc;
- if_initname(ifp, "urtwn", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = urtwn_init;
- ifp->if_ioctl = urtwn_ioctl;
- ifp->if_start = urtwn_start;
- 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(self);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -462,12 +441,13 @@ urtwn_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = urtwn_raw_xmit;
ic->ic_scan_start = urtwn_scan_start;
ic->ic_scan_end = urtwn_scan_end;
ic->ic_set_channel = urtwn_set_channel;
-
+ ic->ic_transmit = urtwn_transmit;
+ ic->ic_parent = urtwn_parent;
ic->ic_vap_create = urtwn_vap_create;
ic->ic_vap_delete = urtwn_vap_delete;
ic->ic_update_mcast = urtwn_update_mcast;
@@ -491,17 +471,15 @@ static int
urtwn_detach(device_t self)
{
struct urtwn_softc *sc = device_get_softc(self);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/* Prevent further ioctls. */
URTWN_LOCK(sc);
sc->sc_flags |= URTWN_DETACHED;
+ urtwn_stop(sc);
URTWN_UNLOCK(sc);
- urtwn_stop(ifp);
-
callout_drain(&sc->sc_watchdog_ch);
/* Prevent further allocations from RX/TX data lists. */
@@ -527,8 +505,7 @@ urtwn_detach(device_t self)
/* stop all USB transfers */
usbd_transfer_unsetup(sc->sc_xfer, URTWN_N_TRANSFER);
ieee80211_ifdetach(ic);
-
- if_free(ifp);
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -599,15 +576,12 @@ urtwn_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- uvp = (struct urtwn_vap *) malloc(sizeof(struct urtwn_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (uvp == NULL)
- return (NULL);
+ uvp = malloc(sizeof(struct urtwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &uvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(uvp, M_80211_VAP);
return (NULL);
@@ -619,7 +593,7 @@ urtwn_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_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -636,8 +610,7 @@ urtwn_vap_delete(struct ieee80211vap *vap)
static struct mbuf *
urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct mbuf *m;
struct r92c_rx_stat *stat;
@@ -650,7 +623,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
* don't pass packets to the ieee80211 framework if the driver isn't
* RUNNING.
*/
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
+ if (!(sc->sc_flags & URTWN_RUNNING))
return (NULL);
stat = (struct r92c_rx_stat *)buf;
@@ -662,11 +635,11 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
* This should not happen since we setup our Rx filter
* to not receive these frames.
*/
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
if (pktlen < sizeof(*wh) || pktlen > MCLBYTES) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -695,7 +668,6 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen, int *rssi_p)
}
/* Finalize mbuf. */
- m->m_pkthdr.rcvif = ifp;
wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
memcpy(mtod(m, uint8_t *), wh, pktlen);
m->m_pkthdr.len = m->m_len = pktlen;
@@ -741,7 +713,7 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
int8_t *nf)
{
struct urtwn_softc *sc = data->sc;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
struct r92c_rx_stat *stat;
struct mbuf *m, *m0 = NULL, *prevm = NULL;
uint32_t rxdw0;
@@ -751,7 +723,7 @@ urtwn_rxeof(struct usb_xfer *xfer, struct urtwn_data *data, int *rssi,
usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
if (len < sizeof(*stat)) {
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return (NULL);
}
@@ -802,8 +774,7 @@ static void
urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct mbuf *m = NULL, *next;
@@ -866,7 +837,7 @@ tr_setup:
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
goto tr_setup;
}
break;
@@ -877,38 +848,19 @@ static void
urtwn_txeof(struct usb_xfer *xfer, struct urtwn_data *data)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct mbuf *m;
URTWN_ASSERT_LOCKED(sc);
-
- /*
- * Do any tx complete callback. Note this must be done before releasing
- * the node reference.
- */
- if (data->m) {
- m = data->m;
- if (m->m_flags & M_TXCB) {
- /* XXX status? */
- ieee80211_process_callback(data->ni, m, 0);
- }
- m_freem(m);
- data->m = NULL;
- }
- if (data->ni) {
- ieee80211_free_node(data->ni);
- data->ni = NULL;
- }
+ /* XXX status? */
+ ieee80211_tx_complete(data->ni, data->m, 0);
+ data->ni = NULL;
+ data->m = NULL;
sc->sc_txtimer = 0;
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
static void
urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct urtwn_data *data;
URTWN_ASSERT_LOCKED(sc);
@@ -933,16 +885,17 @@ tr_setup:
STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next);
usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen);
usbd_transfer_submit(xfer);
- urtwn_start_locked(ifp, sc);
+ urtwn_start(sc);
break;
default:
data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL)
goto tr_setup;
if (data->ni != NULL) {
+ if_inc_counter(data->ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
ieee80211_free_node(data->ni);
data->ni = NULL;
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer);
@@ -975,11 +928,8 @@ urtwn_getbuf(struct urtwn_softc *sc)
URTWN_ASSERT_LOCKED(sc);
bf = _urtwn_getbuf(sc);
- if (bf == NULL) {
- struct ifnet *ifp = sc->sc_ifp;
+ if (bf == NULL)
DPRINTF("%s: stop queue\n", __func__);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- }
return (bf);
}
@@ -1302,7 +1252,7 @@ urtwn_read_rom(struct urtwn_softc *sc)
sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
DPRINTF("regulatory type=%d\n", sc->regulatory);
- IEEE80211_ADDR_COPY(sc->sc_bssid, rom->macaddr);
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, rom->macaddr);
sc->sc_rf_write = urtwn_r92c_rf_write;
sc->sc_power_on = urtwn_r92c_power_on;
@@ -1363,7 +1313,7 @@ urtwn_r88e_read_rom(struct urtwn_softc *sc)
if (sc->ofdm_tx_pwr_diff & 0x08)
sc->ofdm_tx_pwr_diff |= 0xf0;
sc->regulatory = MS(sc->r88e_rom[0xc1], R92C_ROM_RF1_REGULATORY);
- IEEE80211_ADDR_COPY(sc->sc_bssid, &sc->r88e_rom[0xd7]);
+ IEEE80211_ADDR_COPY(sc->sc_ic.ic_macaddr, &sc->r88e_rom[0xd7]);
sc->sc_rf_write = urtwn_r88e_rf_write;
sc->sc_power_on = urtwn_r88e_power_on;
@@ -1378,7 +1328,7 @@ urtwn_ra_init(struct urtwn_softc *sc)
{
static const uint8_t map[] =
{ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct ieee80211_rateset *rs;
@@ -1455,8 +1405,7 @@ urtwn_ra_init(struct urtwn_softc *sc)
void
urtwn_tsf_sync_enable(struct urtwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni = vap->iv_bss;
@@ -1513,7 +1462,7 @@ urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct urtwn_vap *uvp = URTWN_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct urtwn_softc *sc = ic->ic_ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
struct ieee80211_node *ni;
enum ieee80211_state ostate;
uint32_t reg;
@@ -1669,12 +1618,11 @@ static void
urtwn_watchdog(void *arg)
{
struct urtwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
if (sc->sc_txtimer > 0) {
if (--sc->sc_txtimer == 0) {
device_printf(sc->sc_dev, "device timeout\n");
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
return;
}
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
@@ -1800,10 +1748,9 @@ static int
urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni,
struct mbuf *m0, struct urtwn_data *data)
{
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_frame *wh;
struct ieee80211_key *k;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct usb_xfer *xfer;
struct r92c_tx_desc *txd;
@@ -1942,89 +1889,78 @@ urtwn_tx_start(struct urtwn_softc *sc, struct ieee80211_node *ni,
return (0);
}
-static void
-urtwn_start(struct ifnet *ifp)
+static int
+urtwn_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct urtwn_softc *sc = ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
+ int error;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
URTWN_LOCK(sc);
- urtwn_start_locked(ifp, sc);
+ if ((sc->sc_flags & URTWN_RUNNING) == 0) {
+ URTWN_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ URTWN_UNLOCK(sc);
+ return (error);
+ }
+ urtwn_start(sc);
URTWN_UNLOCK(sc);
+
+ return (0);
}
static void
-urtwn_start_locked(struct ifnet *ifp, struct urtwn_softc *sc)
+urtwn_start(struct urtwn_softc *sc)
{
struct ieee80211_node *ni;
struct mbuf *m;
struct urtwn_data *bf;
URTWN_ASSERT_LOCKED(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
bf = urtwn_getbuf(sc);
if (bf == NULL) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ mbufq_prepend(&sc->sc_snd, m);
break;
}
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
m->m_pkthdr.rcvif = NULL;
-
if (urtwn_tx_start(sc, ni, m, bf) != 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
ieee80211_free_node(ni);
break;
}
-
sc->sc_txtimer = 5;
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
}
}
-static int
-urtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+urtwn_parent(struct ieee80211com *ic)
{
- struct urtwn_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0;
+ struct urtwn_softc *sc = ic->ic_softc;
+ int startall = 0;
URTWN_LOCK(sc);
- error = (sc->sc_flags & URTWN_DETACHED) ? ENXIO : 0;
+ if (sc->sc_flags & URTWN_DETACHED) {
+ URTWN_UNLOCK(sc);
+ return;
+ }
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & URTWN_RUNNING) == 0) {
+ urtwn_init(sc);
+ startall = 1;
+ }
+ } else if (sc->sc_flags & URTWN_RUNNING)
+ urtwn_stop(sc);
URTWN_UNLOCK(sc);
- if (error != 0)
- return (error);
- switch (cmd) {
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- urtwn_init(ifp->if_softc);
- startall = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtwn_stop(ifp);
- }
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
- }
- return (error);
+ if (startall)
+ ieee80211_start_all(ic);
}
static int
@@ -2938,7 +2874,7 @@ urtwn_get_txpower(struct urtwn_softc *sc, int chain,
struct ieee80211_channel *c, struct ieee80211_channel *extc,
uint16_t power[URTWN_RIDX_COUNT])
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct r92c_rom *rom = &sc->rom;
uint16_t cckpow, ofdmpow, htpow, diff, max;
const struct urtwn_txpwr *base;
@@ -3037,7 +2973,7 @@ urtwn_r88e_get_txpower(struct urtwn_softc *sc, int chain,
struct ieee80211_channel *c, struct ieee80211_channel *extc,
uint16_t power[URTWN_RIDX_COUNT])
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint16_t cckpow, ofdmpow, bw20pow, htpow;
const struct urtwn_r88e_txpwr *base;
int ridx, chan, group;
@@ -3134,7 +3070,7 @@ urtwn_scan_end(struct ieee80211com *ic)
static void
urtwn_set_channel(struct ieee80211com *ic)
{
- struct urtwn_softc *sc = ic->ic_ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
URTWN_LOCK(sc);
@@ -3156,7 +3092,7 @@ static void
urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c,
struct ieee80211_channel *extc)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t reg;
u_int chan;
int i;
@@ -3287,17 +3223,18 @@ urtwn_lc_calib(struct urtwn_softc *sc)
}
static void
-urtwn_init_locked(void *arg)
+urtwn_init(struct urtwn_softc *sc)
{
- struct urtwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
uint32_t reg;
int error;
URTWN_ASSERT_LOCKED(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- urtwn_stop_locked(ifp);
+ if (sc->sc_flags & URTWN_RUNNING)
+ urtwn_stop(sc);
/* Init firmware commands ring. */
sc->fwcur = 0;
@@ -3340,8 +3277,8 @@ urtwn_init_locked(void *arg)
}
/* Set MAC address. */
- urtwn_write_region_1(sc, R92C_MACID, IF_LLADDR(ifp),
- IEEE80211_ADDR_LEN);
+ IEEE80211_ADDR_COPY(macaddr, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ urtwn_write_region_1(sc, R92C_MACID, macaddr, IEEE80211_ADDR_LEN);
/* Set initial network type. */
reg = urtwn_read_4(sc, R92C_CR);
@@ -3465,8 +3402,7 @@ urtwn_init_locked(void *arg)
usbd_transfer_start(sc->sc_xfer[URTWN_BULK_RX]);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= URTWN_RUNNING;
callout_reset(&sc->sc_watchdog_ch, hz, urtwn_watchdog, sc);
fail:
@@ -3474,39 +3410,16 @@ fail:
}
static void
-urtwn_init(void *arg)
-{
- struct urtwn_softc *sc = arg;
-
- URTWN_LOCK(sc);
- urtwn_init_locked(arg);
- URTWN_UNLOCK(sc);
-}
-
-static void
-urtwn_stop_locked(struct ifnet *ifp)
+urtwn_stop(struct urtwn_softc *sc)
{
- struct urtwn_softc *sc = ifp->if_softc;
URTWN_ASSERT_LOCKED(sc);
-
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
-
+ sc->sc_flags &= ~URTWN_RUNNING;
callout_stop(&sc->sc_watchdog_ch);
urtwn_abort_xfers(sc);
}
static void
-urtwn_stop(struct ifnet *ifp)
-{
- struct urtwn_softc *sc = ifp->if_softc;
-
- URTWN_LOCK(sc);
- urtwn_stop_locked(ifp);
- URTWN_UNLOCK(sc);
-}
-
-static void
urtwn_abort_xfers(struct urtwn_softc *sc)
{
int i;
@@ -3523,12 +3436,11 @@ urtwn_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 urtwn_softc *sc = ifp->if_softc;
+ struct urtwn_softc *sc = ic->ic_softc;
struct urtwn_data *bf;
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & URTWN_RUNNING)) {
m_freem(m);
ieee80211_free_node(ni);
return (ENETDOWN);
@@ -3542,10 +3454,8 @@ urtwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return (ENOBUFS);
}
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if (urtwn_tx_start(sc, ni, m, bf) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
URTWN_UNLOCK(sc);
return (EIO);
diff --git a/sys/dev/usb/wlan/if_urtwnreg.h b/sys/dev/usb/wlan/if_urtwnreg.h
index 2bbec7a..0ca9db7 100644
--- a/sys/dev/usb/wlan/if_urtwnreg.h
+++ b/sys/dev/usb/wlan/if_urtwnreg.h
@@ -1172,7 +1172,8 @@ enum {
#define URTWN_EP_QUEUES URTWN_BULK_RX
struct urtwn_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -1180,6 +1181,7 @@ struct urtwn_softc {
u_int sc_flags;
#define URTWN_FLAG_CCK_HIPWR 0x01
#define URTWN_DETACHED 0x02
+#define URTWN_RUNNING 0x04
u_int chip;
#define URTWN_CHIP_92C 0x01
@@ -1224,7 +1226,6 @@ struct urtwn_softc {
uint8_t ht40_tx_pwr[5];
int8_t bw20_tx_pwr_diff;
int8_t ofdm_tx_pwr_diff;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
struct callout sc_watchdog_ch;
struct mtx sc_mtx;
diff --git a/sys/dev/usb/wlan/if_urtwvar.h b/sys/dev/usb/wlan/if_urtwvar.h
index e99cbf4..a423214 100644
--- a/sys/dev/usb/wlan/if_urtwvar.h
+++ b/sys/dev/usb/wlan/if_urtwvar.h
@@ -93,14 +93,14 @@ struct urtw_vap {
#define URTW_VAP(vap) ((struct urtw_vap *)(vap))
struct urtw_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
struct mtx sc_mtx;
void *sc_tx_dma_buf;
int sc_debug;
- int sc_if_flags;
int sc_flags;
#define URTW_INIT_ONCE (1 << 1)
#define URTW_RTL8187B (1 << 2)
@@ -108,13 +108,13 @@ struct urtw_softc {
#define URTW_RTL8187B_REV_D (1 << 4)
#define URTW_RTL8187B_REV_E (1 << 5)
#define URTW_DETACHED (1 << 6)
+#define URTW_RUNNING (1 << 7)
enum ieee80211_state sc_state;
int sc_epromtype;
#define URTW_EEPROM_93C46 0
#define URTW_EEPROM_93C56 1
uint8_t sc_crcmon;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
struct ieee80211_channel *sc_curchan;
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 8f9035e..4c1c778 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -154,12 +154,12 @@ static int zyd_set_beacon_interval(struct zyd_softc *, int);
static void zyd_rx_data(struct usb_xfer *, int, uint16_t);
static int zyd_tx_start(struct zyd_softc *, struct mbuf *,
struct ieee80211_node *);
-static void zyd_start(struct ifnet *);
+static int zyd_transmit(struct ieee80211com *, struct mbuf *);
+static void zyd_start(struct zyd_softc *);
static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static int zyd_ioctl(struct ifnet *, u_long, caddr_t);
+static void zyd_parent(struct ieee80211com *);
static void zyd_init_locked(struct zyd_softc *);
-static void zyd_init(void *);
static void zyd_stop(struct zyd_softc *);
static int zyd_loadfirmware(struct zyd_softc *);
static void zyd_scan_start(struct ieee80211com *);
@@ -333,8 +333,7 @@ zyd_attach(device_t dev)
{
struct usb_attach_arg *uaa = device_get_ivars(dev);
struct zyd_softc *sc = device_get_softc(dev);
- struct ifnet *ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
uint8_t iface_index, bands;
int error;
@@ -353,6 +352,7 @@ zyd_attach(device_t dev)
mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
MTX_NETWORK_LOCK, MTX_DEF);
STAILQ_INIT(&sc->sc_rqh);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
iface_index = ZYD_IFACE_INDEX;
error = usbd_transfer_setup(uaa->device,
@@ -372,22 +372,6 @@ zyd_attach(device_t dev)
}
ZYD_UNLOCK(sc);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(sc->sc_dev, "can not if_alloc()\n");
- goto detach;
- }
- ifp->if_softc = sc;
- if_initname(ifp, "zyd", device_get_unit(sc->sc_dev));
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = zyd_init;
- ifp->if_ioctl = zyd_ioctl;
- ifp->if_start = zyd_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- IFQ_SET_READY(&ifp->if_snd);
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -408,16 +392,17 @@ zyd_attach(device_t dev)
setbit(&bands, IEEE80211_MODE_11G);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic, sc->sc_bssid);
+ ieee80211_ifattach(ic);
ic->ic_raw_xmit = zyd_raw_xmit;
ic->ic_scan_start = zyd_scan_start;
ic->ic_scan_end = zyd_scan_end;
ic->ic_set_channel = zyd_set_channel;
-
ic->ic_vap_create = zyd_vap_create;
ic->ic_vap_delete = zyd_vap_delete;
ic->ic_update_mcast = zyd_update_mcast;
ic->ic_update_promisc = zyd_update_mcast;
+ ic->ic_parent = zyd_parent;
+ ic->ic_transmit = zyd_transmit;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -439,8 +424,7 @@ static int
zyd_detach(device_t dev)
{
struct zyd_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
+ struct ieee80211com *ic = &sc->sc_ic;
unsigned int x;
/*
@@ -465,11 +449,9 @@ zyd_detach(device_t dev)
/* free USB transfers and some data buffers */
usbd_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
- if (ifp) {
- ic = ifp->if_l2com;
+ if (ic->ic_softc == sc)
ieee80211_ifdetach(ic);
- if_free(ifp);
- }
+ mbufq_drain(&sc->sc_snd);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -486,15 +468,12 @@ zyd_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return (NULL);
- zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (zvp == NULL)
- return (NULL);
+ zvp = malloc(sizeof(struct zyd_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &zvp->vap;
/* enable s/w bmiss handling for sta mode */
if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
- flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) {
+ flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
/* out of memory */
free(zvp, M_80211_VAP);
return (NULL);
@@ -509,7 +488,7 @@ zyd_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_status, mac);
ic->ic_opmode = opmode;
return (vap);
}
@@ -530,13 +509,8 @@ zyd_tx_free(struct zyd_tx_data *data, int txerr)
struct zyd_softc *sc = data->sc;
if (data->m != NULL) {
- if (data->m->m_flags & M_TXCB)
- ieee80211_process_callback(data->ni, data->m,
- txerr ? ETIMEDOUT : 0);
- m_freem(data->m);
+ ieee80211_tx_complete(data->ni, data->m, txerr);
data->m = NULL;
-
- ieee80211_free_node(data->ni);
data->ni = NULL;
}
STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
@@ -593,7 +567,7 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct zyd_vap *zvp = ZYD_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
int error;
DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
@@ -618,8 +592,8 @@ zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
/* make data LED blink upon Tx */
zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
- IEEE80211_ADDR_COPY(sc->sc_bssid, vap->iv_bss->ni_bssid);
- zyd_set_bssid(sc, sc->sc_bssid);
+ IEEE80211_ADDR_COPY(ic->ic_macaddr, vap->iv_bss->ni_bssid);
+ zyd_set_bssid(sc, ic->ic_macaddr);
break;
default:
break;
@@ -637,8 +611,7 @@ static void
zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct ieee80211_node *ni;
struct zyd_cmd *cmd = &sc->sc_ibuf;
@@ -681,7 +654,9 @@ zyd_intr_read_callback(struct usb_xfer *xfer, usb_error_t error)
ieee80211_free_node(ni);
}
if (le16toh(retry->count) & 0x100)
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); /* too many retries */
+ /* too many retries */
+ if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS,
+ 1);
break;
}
case ZYD_NOTIF_IORD:
@@ -1243,8 +1218,7 @@ zyd_al2230_bandedge6(struct zyd_rf *rf, struct ieee80211_channel *c)
#define N(a) ((int)(sizeof(a) / sizeof((a)[0])))
int error = 0, i;
struct zyd_softc *sc = rf->rf_sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6;
int chan = ieee80211_chan2ieee(ic, c);
@@ -1932,7 +1906,7 @@ zyd_get_macaddr(struct zyd_softc *sc)
USETW(req.wIndex, 0);
USETW(req.wLength, IEEE80211_ADDR_LEN);
- error = zyd_do_request(sc, &req, sc->sc_bssid);
+ error = zyd_do_request(sc, &req, sc->sc_ic.ic_macaddr);
if (error != 0) {
device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
usbd_errstr(error));
@@ -2004,36 +1978,41 @@ fail:
static void
zyd_set_multi(struct zyd_softc *sc)
{
- int error;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifmultiaddr *ifma;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t low, high;
- uint8_t v;
+ int error;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0)
return;
low = 0x00000000;
high = 0x80000000;
- 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) {
low = 0xffffffff;
high = 0xffffffff;
} else {
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
- ifma->ifma_addr))[5] >> 2;
- if (v < 32)
- low |= 1 << v;
- else
- high |= 1 << (v - 32);
+ struct ieee80211vap *vap;
+ struct ifnet *ifp;
+ struct ifmultiaddr *ifma;
+ uint8_t v;
+
+ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
+ 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;
+ v = ((uint8_t *)LLADDR((struct sockaddr_dl *)
+ ifma->ifma_addr))[5] >> 2;
+ if (v < 32)
+ low |= 1 << v;
+ else
+ high |= 1 << (v - 32);
+ }
+ if_maddr_runlock(ifp);
}
- if_maddr_runlock(ifp);
}
/* reprogram multicast global hash table */
@@ -2050,9 +2029,6 @@ zyd_update_mcast(struct ieee80211com *ic)
{
struct zyd_softc *sc = ic->ic_softc;
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return;
-
ZYD_LOCK(sc);
zyd_set_multi(sc);
ZYD_UNLOCK(sc);
@@ -2061,8 +2037,7 @@ zyd_update_mcast(struct ieee80211com *ic)
static int
zyd_set_rxfilter(struct zyd_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t rxfilter;
switch (ic->ic_opmode) {
@@ -2087,8 +2062,7 @@ static void
zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c)
{
int error;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct zyd_rf *rf = &sc->sc_rf;
uint32_t tmp;
int chan;
@@ -2179,8 +2153,7 @@ static void
zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct zyd_plcphdr plcp;
struct zyd_rx_stat stat;
struct usb_page_cache *pc;
@@ -2190,7 +2163,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
if (len < ZYD_MIN_FRAGSZ) {
DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too short (length=%d)\n",
device_get_nameunit(sc->sc_dev), len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
pc = usbd_xfer_get_frame(xfer, 0);
@@ -2201,7 +2174,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
DPRINTF(sc, ZYD_DEBUG_RECV,
"%s: RX status indicated error (%x)\n",
device_get_nameunit(sc->sc_dev), stat.flags);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -2213,7 +2186,7 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
if (rlen > (int)MCLBYTES) {
DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n",
device_get_nameunit(sc->sc_dev), rlen);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
} else if (rlen > (int)MHLEN)
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
@@ -2222,10 +2195,9 @@ zyd_rx_data(struct usb_xfer *xfer, int offset, uint16_t len)
if (m == NULL) {
DPRINTF(sc, ZYD_DEBUG_RECV, "%s: could not allocate rx mbuf\n",
device_get_nameunit(sc->sc_dev));
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
- m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = rlen;
usbd_copy_out(pc, offset + sizeof(plcp), mtod(m, uint8_t *), rlen);
@@ -2255,8 +2227,7 @@ static void
zyd_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
struct zyd_rx_desc desc;
struct mbuf *m;
@@ -2328,10 +2299,8 @@ tr_setup:
} else
(void)ieee80211_input_all(ic, m, rssi, nf);
}
- if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
- !IFQ_IS_EMPTY(&ifp->if_snd))
- zyd_start(ifp);
ZYD_LOCK(sc);
+ zyd_start(sc);
break;
default: /* Error */
@@ -2386,7 +2355,6 @@ static void
zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct zyd_softc *sc = usbd_xfer_softc(xfer);
- struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap;
struct zyd_tx_data *data;
struct mbuf *m;
@@ -2405,9 +2373,6 @@ zyd_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
zyd_tx_free(data, 0);
usbd_xfer_set_priv(xfer, NULL);
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
@@ -2440,16 +2405,14 @@ tr_setup:
usbd_xfer_set_priv(xfer, data);
usbd_transfer_submit(xfer);
}
- ZYD_UNLOCK(sc);
- zyd_start(ifp);
- ZYD_LOCK(sc);
+ zyd_start(sc);
break;
default: /* Error */
DPRINTF(sc, ZYD_DEBUG_ANY, "transfer error, %s\n",
usbd_errstr(error));
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ counter_u64_add(sc->sc_ic.ic_oerrors, 1);
data = usbd_xfer_get_priv(xfer);
usbd_xfer_set_priv(xfer, NULL);
if (data != NULL)
@@ -2590,31 +2553,45 @@ zyd_tx_start(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
return (0);
}
+static int
+zyd_transmit(struct ieee80211com *ic, struct mbuf *m)
+{
+ struct zyd_softc *sc = ic->ic_softc;
+ int error;
+
+ ZYD_LOCK(sc);
+ if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
+ ZYD_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ ZYD_UNLOCK(sc);
+ return (error);
+ }
+ zyd_start(sc);
+ ZYD_UNLOCK(sc);
+
+ return (0);
+}
+
static void
-zyd_start(struct ifnet *ifp)
+zyd_start(struct zyd_softc *sc)
{
- struct zyd_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- ZYD_LOCK(sc);
- for (;;) {
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
- if (sc->tx_nfree == 0) {
- IFQ_DRV_PREPEND(&ifp->if_snd, m);
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
+ ZYD_LOCK_ASSERT(sc, MA_LOCKED);
+
+ while (sc->tx_nfree > 0 && (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (zyd_tx_start(sc, m, ni) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ni->ni_vap->iv_ifp,
+ IFCOUNTER_OERRORS, 1);
break;
}
}
- ZYD_UNLOCK(sc);
}
static int
@@ -2622,19 +2599,17 @@ zyd_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 zyd_softc *sc = ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!(sc->sc_flags & ZYD_FLAG_RUNNING)) {
ZYD_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return (ENETDOWN);
}
if (sc->tx_nfree == 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
ZYD_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
@@ -2648,7 +2623,6 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
*/
if (zyd_tx_start(sc, m, ni) != 0) {
ZYD_UNLOCK(sc);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
return (EIO);
}
@@ -2656,56 +2630,35 @@ zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return (0);
}
-static int
-zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+static void
+zyd_parent(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ifreq *ifr = (struct ifreq *) data;
- int error;
+ struct zyd_softc *sc = ic->ic_softc;
int startall = 0;
ZYD_LOCK(sc);
- error = (sc->sc_flags & ZYD_FLAG_DETACHED) ? ENXIO : 0;
- ZYD_UNLOCK(sc);
- if (error)
- return (error);
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- ZYD_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
- zyd_init_locked(sc);
- startall = 1;
- } else
- zyd_set_multi(sc);
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- zyd_stop(sc);
- }
+ if (sc->sc_flags & ZYD_FLAG_DETACHED) {
ZYD_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- default:
- error = EINVAL;
- break;
+ return;
}
- return (error);
+ if (ic->ic_nrunning > 0) {
+ if ((sc->sc_flags & ZYD_FLAG_RUNNING) == 0) {
+ zyd_init_locked(sc);
+ startall = 1;
+ } else
+ zyd_set_multi(sc);
+ } else if (sc->sc_flags & ZYD_FLAG_RUNNING)
+ zyd_stop(sc);
+ ZYD_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
}
static void
zyd_init_locked(struct zyd_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct usb_config_descriptor *cd;
int error;
uint32_t val;
@@ -2757,12 +2710,12 @@ zyd_init_locked(struct zyd_softc *sc)
sc->sc_flags |= ZYD_FLAG_INITONCE;
}
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ if (sc->sc_flags & ZYD_FLAG_RUNNING)
zyd_stop(sc);
DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %6D\n",
- IF_LLADDR(ifp), ":");
- error = zyd_set_macaddr(sc, IF_LLADDR(ifp));
+ vap ? vap->iv_myaddr : ic->ic_macaddr, ":");
+ error = zyd_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
if (error != 0)
return;
@@ -2798,8 +2751,7 @@ zyd_init_locked(struct zyd_softc *sc)
/* enable interrupts */
zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
+ sc->sc_flags |= ZYD_FLAG_RUNNING;
usbd_xfer_set_stall(sc->sc_xfer[ZYD_BULK_WR]);
usbd_transfer_start(sc->sc_xfer[ZYD_BULK_RD]);
usbd_transfer_start(sc->sc_xfer[ZYD_INTR_RD]);
@@ -2811,29 +2763,13 @@ fail: zyd_stop(sc);
}
static void
-zyd_init(void *priv)
-{
- struct zyd_softc *sc = priv;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ZYD_LOCK(sc);
- zyd_init_locked(sc);
- ZYD_UNLOCK(sc);
-
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic); /* start all vap's */
-}
-
-static void
zyd_stop(struct zyd_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int error;
ZYD_LOCK_ASSERT(sc, MA_OWNED);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~ZYD_FLAG_RUNNING;
/*
* Drain all the transfers, if not already drained:
@@ -2925,30 +2861,29 @@ zyd_loadfirmware(struct zyd_softc *sc)
static void
zyd_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct zyd_softc *sc = ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
/* want broadcast address while scanning */
- zyd_set_bssid(sc, ifp->if_broadcastaddr);
+ zyd_set_bssid(sc, ieee80211broadcastaddr);
ZYD_UNLOCK(sc);
}
static void
zyd_scan_end(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
/* restore previous bssid */
- zyd_set_bssid(sc, sc->sc_bssid);
+ zyd_set_bssid(sc, ic->ic_macaddr);
ZYD_UNLOCK(sc);
}
static void
zyd_set_channel(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct zyd_softc *sc = ic->ic_softc;
ZYD_LOCK(sc);
zyd_set_chan(sc, ic->ic_curchan);
diff --git a/sys/dev/usb/wlan/if_zydreg.h b/sys/dev/usb/wlan/if_zydreg.h
index 05d94e3..ec61d06 100644
--- a/sys/dev/usb/wlan/if_zydreg.h
+++ b/sys/dev/usb/wlan/if_zydreg.h
@@ -1249,7 +1249,8 @@ enum {
};
struct zyd_softc {
- struct ifnet *sc_ifp;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
device_t sc_dev;
struct usb_device *sc_udev;
@@ -1260,13 +1261,13 @@ struct zyd_softc {
#define ZYD_FLAG_INITONCE (1 << 1)
#define ZYD_FLAG_INITDONE (1 << 2)
#define ZYD_FLAG_DETACHED (1 << 3)
+#define ZYD_FLAG_RUNNING (1 << 4)
struct zyd_rf sc_rf;
STAILQ_HEAD(, zyd_rq) sc_rtx;
STAILQ_HEAD(, zyd_rq) sc_rqh;
- uint8_t sc_bssid[IEEE80211_ADDR_LEN];
uint16_t sc_fwbase;
uint8_t sc_regdomain;
uint8_t sc_macrev;
OpenPOWER on IntegriCloud