summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/wlan/if_run.c
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2015-08-08 01:10:17 +0000
committeradrian <adrian@FreeBSD.org>2015-08-08 01:10:17 +0000
commitbad6d5c89b6ffd35818850d95cb88e218dee73b3 (patch)
tree5973a9059f73ed5abf84d6d98e44f1953e764064 /sys/dev/usb/wlan/if_run.c
parent33a3844dbf69152b9d47f6fa1ac1c2d5b1d502e4 (diff)
downloadFreeBSD-src-bad6d5c89b6ffd35818850d95cb88e218dee73b3.zip
FreeBSD-src-bad6d5c89b6ffd35818850d95cb88e218dee73b3.tar.gz
Revert the wifi ifnet changes until things are more baked and tested.
* 286410 * 286413 * 286416 The initial commit broke a variety of debug and features that aren't in the GENERIC kernels but are enabled in other platforms.
Diffstat (limited to 'sys/dev/usb/wlan/if_run.c')
-rw-r--r--sys/dev/usb/wlan/if_run.c363
1 files changed, 226 insertions, 137 deletions
diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c
index 193b9ad..ac14178 100644
--- a/sys/dev/usb/wlan/if_run.c
+++ b/sys/dev/usb/wlan/if_run.c
@@ -410,9 +410,8 @@ 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 int run_transmit(struct ieee80211com *, struct mbuf *);
-static void run_start(struct run_softc *);
-static void run_parent(struct ieee80211com *);
+static void run_start(struct ifnet *);
+static int run_ioctl(struct ifnet *, u_long, caddr_t);
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);
@@ -458,6 +457,7 @@ 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,7 +702,8 @@ 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 = &sc->sc_ic;
+ struct ieee80211com *ic;
+ struct ifnet *ifp;
uint32_t ver;
int ntries, error;
uint8_t iface_index, bands;
@@ -715,7 +716,6 @@ 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,10 +754,28 @@ 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(ic->ic_macaddr));
+ sc->ntxchains, sc->nrxchains, ether_sprintf(sc->sc_bssid));
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 */
@@ -794,7 +812,7 @@ run_attach(device_t self)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic);
+ ieee80211_ifattach(ic, sc->sc_bssid);
ic->ic_scan_start = run_scan_start;
ic->ic_scan_end = run_scan_end;
@@ -806,10 +824,9 @@ 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),
@@ -835,7 +852,8 @@ static int
run_detach(device_t self)
{
struct run_softc *sc = device_get_softc(self);
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic;
int i;
RUN_LOCK(sc);
@@ -854,15 +872,16 @@ run_detach(device_t self)
run_unsetup_tx_list(sc, &sc->sc_epq[i]);
RUN_UNLOCK(sc);
- if (sc->sc_ic.ic_softc == sc) {
+ if (ifp) {
+ ic = ifp->if_l2com;
/* 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);
@@ -874,13 +893,14 @@ 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 run_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct run_softc *sc = ifp->if_softc;
struct run_vap *rvp;
struct ieee80211vap *vap;
int i;
if (sc->rvp_cnt >= RUN_VAP_MAX) {
- device_printf(sc->sc_dev, "number of VAPs maxed out\n");
+ if_printf(ifp, "number of VAPs maxed out\n");
return (NULL);
}
@@ -906,21 +926,23 @@ run_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
break;
}
if (vap == NULL) {
- device_printf(sc->sc_dev,
- "wds only supported in ap mode\n");
+ if_printf(ifp, "wds only supported in ap mode\n");
return (NULL);
}
break;
default:
- device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
+ if_printf(ifp, "unknown opmode %d\n", opmode);
return (NULL);
}
- rvp = malloc(sizeof(struct run_vap), M_80211_VAP, M_WAITOK | M_ZERO);
+ rvp = (struct run_vap *) malloc(sizeof(struct run_vap),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (rvp == NULL)
+ return (NULL);
vap = &rvp->vap;
- if (ieee80211_vap_setup(ic, vap, name, unit, opmode, flags,
- bssid) != 0) {
+ if (ieee80211_vap_setup(ic, vap, name, unit,
+ opmode, flags, bssid, mac) != 0) {
/* out of memory */
free(rvp, M_80211_VAP);
return (NULL);
@@ -947,8 +969,7 @@ 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,
- mac);
+ ieee80211_vap_attach(vap, run_media_change, ieee80211_media_status);
/* make sure id is always unique */
for (i = 0; i < RUN_VAP_MAX; i++) {
@@ -974,6 +995,7 @@ 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;
@@ -982,7 +1004,9 @@ run_vap_delete(struct ieee80211vap *vap)
return;
ic = vap->iv_ic;
- sc = ic->ic_softc;
+ ifp = ic->ic_ifp;
+
+ sc = ifp->if_softc;
RUN_LOCK(sc);
@@ -1716,7 +1740,6 @@ 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;
@@ -1737,14 +1760,14 @@ run_read_eeprom(struct run_softc *sc)
/* read MAC address */
run_srom_read(sc, RT2860_EEPROM_MAC01, &val);
- ic->ic_macaddr[0] = val & 0xff;
- ic->ic_macaddr[1] = val >> 8;
+ sc->sc_bssid[0] = val & 0xff;
+ sc->sc_bssid[1] = val >> 8;
run_srom_read(sc, RT2860_EEPROM_MAC23, &val);
- ic->ic_macaddr[2] = val & 0xff;
- ic->ic_macaddr[3] = val >> 8;
+ sc->sc_bssid[2] = val & 0xff;
+ sc->sc_bssid[3] = val >> 8;
run_srom_read(sc, RT2860_EEPROM_MAC45, &val);
- ic->ic_macaddr[4] = val & 0xff;
- ic->ic_macaddr[5] = val >> 8;
+ sc->sc_bssid[4] = val & 0xff;
+ sc->sc_bssid[5] = val >> 8;
if (sc->mac_ver < 0x3593) {
/* read vender BBP settings */
@@ -1979,7 +2002,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
uint8_t rate, ridx;
int error;
@@ -2010,7 +2033,7 @@ run_media_change(struct ifnet *ifp)
#if 0
if ((ifp->if_flags & IFF_UP) &&
- (ifp->if_drv_flags & RUN_RUNNING)){
+ (ifp->if_drv_flags & IFF_DRV_RUNNING)){
run_init_locked(sc);
}
#endif
@@ -2025,7 +2048,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
struct run_vap *rvp = RUN_VAP(vap);
enum ieee80211_state ostate;
uint32_t sta[3];
@@ -2121,7 +2144,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(ic->ic_macaddr, ni->ni_bssid);
+ IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
run_set_bssid(sc, ni->ni_bssid);
ieee80211_free_node(ni);
run_enable_tsf_sync(sc);
@@ -2158,7 +2181,7 @@ static void
run_wme_update_cb(void *arg)
{
struct ieee80211com *ic = arg;
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
struct ieee80211_wme_state *wmesp = &ic->ic_wme;
int aci, error = 0;
@@ -2211,7 +2234,7 @@ err:
static int
run_wme_update(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
/* sometime called wothout lock */
if (mtx_owned(&ic->ic_comlock.mtx)) {
@@ -2254,7 +2277,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
struct ieee80211_node *ni;
uint32_t attr;
uint16_t base, associd;
@@ -2376,7 +2399,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
uint32_t i;
i = RUN_CMDQ_GET(&sc->cmdq_store);
@@ -2444,7 +2467,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
struct ieee80211_key *k0;
uint32_t i;
@@ -2475,7 +2498,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_ic, &sc->ratectl_task);
+ ieee80211_runtask(sc->sc_ifp->if_l2com, &sc->ratectl_task);
/* next timeout will be rescheduled in the callback task */
}
@@ -2484,7 +2507,7 @@ static void
run_ratectl_cb(void *arg, int pending)
{
struct run_softc *sc = arg;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
if (vap == NULL)
@@ -2517,6 +2540,7 @@ 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;
@@ -2553,7 +2577,7 @@ run_drain_fifo(void *arg)
if (stat & RT2860_TXQ_OK)
(*wstat)[RUN_SUCCESS]++;
else
- counter_u64_add(sc->sc_ic.ic_oerrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
/*
* Check if there were retries, ie if the Tx success rate is
* different from the requested rate. Note that it works only
@@ -2576,6 +2600,8 @@ 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];
@@ -2597,8 +2623,7 @@ run_iter_func(void *arg, struct ieee80211_node *ni)
goto fail;
/* count failed TX as errors */
- if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS,
- le16toh(sta[0].error.fail));
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, le16toh(sta[0].error.fail));
retrycnt = le16toh(sta[1].tx.retry);
success = le16toh(sta[1].tx.success);
@@ -2636,7 +2661,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_softc;
+ struct run_softc *sc = ni->ni_vap->iv_ic->ic_ifp->if_softc;
uint8_t wcid = cmdq->wcid;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -2654,7 +2679,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
uint8_t rate;
uint8_t ridx;
uint8_t wcid;
@@ -2744,7 +2769,8 @@ 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 ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
struct rt2870_rxd *rxd;
@@ -2763,7 +2789,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);
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
DPRINTF("bad RXWI length %u > %u\n", len, dmalen);
return;
}
@@ -2773,7 +2799,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);
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
DPRINTF("%s error.\n", (flags & RT2860_RX_CRCERR)?"CRC":"ICV");
return;
}
@@ -2802,7 +2828,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);
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
DPRINTF("MIC error. Someone is lying.\n");
return;
}
@@ -2811,6 +2837,7 @@ 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) {
@@ -2863,7 +2890,7 @@ static void
run_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
{
struct run_softc *sc = usbd_xfer_softc(xfer);
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
struct mbuf *m = NULL;
struct mbuf *m0;
uint32_t dmalen;
@@ -2901,7 +2928,7 @@ tr_setup:
}
if (sc->rx_m == NULL) {
DPRINTF("could not allocate mbuf - idle with stall\n");
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
usbd_xfer_set_stall(xfer);
usbd_xfer_set_frames(xfer, 0);
} else {
@@ -2921,9 +2948,12 @@ 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");
- counter_u64_add(ic->ic_ierrors, 1);
+
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+
goto tr_setup;
}
if (sc->rx_m != NULL) {
@@ -2971,7 +3001,7 @@ tr_setup:
m0 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m0 == NULL)) {
DPRINTF("could not allocate mbuf\n");
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
break;
}
m_copydata(m, 4 /* skip 32-bit DMA-len header */,
@@ -3018,7 +3048,8 @@ 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 ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct run_tx_data *data;
struct ieee80211vap *vap = NULL;
struct usb_page_cache *pc;
@@ -3036,9 +3067,14 @@ 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:
@@ -3055,7 +3091,11 @@ 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;
}
@@ -3092,8 +3132,12 @@ tr_setup:
usbd_xfer_set_frame_len(xfer, 0, size);
usbd_xfer_set_priv(xfer, data);
+
usbd_transfer_submit(xfer);
- run_start(sc);
+
+ RUN_UNLOCK(sc);
+ run_start(ifp);
+ RUN_LOCK(sc);
break;
@@ -3103,13 +3147,14 @@ 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);
@@ -3175,7 +3220,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_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211vap *vap = data->ni->ni_vap;
struct ieee80211_frame *wh;
struct rt2870_txd *txd;
@@ -3238,7 +3283,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_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh;
struct ieee80211_channel *chan;
@@ -3406,7 +3451,8 @@ 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 ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct run_node *rn = (void *)ni;
struct run_tx_data *data;
struct ieee80211_frame *wh;
@@ -3437,9 +3483,11 @@ 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--;
@@ -3507,9 +3555,11 @@ 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 */
@@ -3520,7 +3570,7 @@ run_sendprot(struct run_softc *sc,
mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
}
if (mprot == NULL) {
- if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
+ if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1);
DPRINTF("could not allocate mbuf\n");
return (ENOBUFS);
}
@@ -3602,6 +3652,7 @@ 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);
}
@@ -3640,31 +3691,36 @@ static int
run_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
- struct run_softc *sc = ni->ni_ic->ic_softc;
+ struct ifnet *ifp = ni->ni_ic->ic_ifp;
+ struct run_softc *sc = ifp->if_softc;
int error = 0;
RUN_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(sc->sc_flags & RUN_RUNNING)) {
- error = ENETDOWN;
+ if (!(ifp->if_drv_flags & IFF_DRV_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);
@@ -3677,71 +3733,83 @@ 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 run_softc *sc)
+run_start(struct ifnet *ifp)
{
+ struct run_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
- RUN_LOCK_ASSERT(sc, MA_OWNED);
+ RUN_LOCK(sc);
- if ((sc->sc_flags & RUN_RUNNING) == 0)
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ RUN_UNLOCK(sc);
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) {
- mbufq_prepend(&sc->sc_snd, m);
+ IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
}
+
+ RUN_UNLOCK(sc);
}
-static void
-run_parent(struct ieee80211com *ic)
+static int
+run_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ifreq *ifr = (struct ifreq *) data;
int startall = 0;
+ int error;
RUN_LOCK(sc);
- if (sc->sc_detached) {
+ 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);
+ }
+ }
RUN_UNLOCK(sc);
- return;
+ 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 (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);
+ return (error);
}
static void
@@ -4728,7 +4796,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_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
u_int chan, group;
chan = ieee80211_chan2ieee(ic, c);
@@ -4773,7 +4841,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
RUN_LOCK(sc);
run_set_chan(sc, ic->ic_curchan);
@@ -4785,7 +4853,7 @@ run_set_channel(struct ieee80211com *ic)
static void
run_scan_start(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
uint32_t tmp;
RUN_LOCK(sc);
@@ -4795,7 +4863,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, ieee80211broadcastaddr);
+ run_set_bssid(sc, sc->sc_ifp->if_broadcastaddr);
RUN_UNLOCK(sc);
@@ -4805,13 +4873,13 @@ run_scan_start(struct ieee80211com *ic)
static void
run_scan_end(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
RUN_LOCK(sc);
run_enable_tsf_sync(sc);
/* XXX keep local copy */
- run_set_bssid(sc, ic->ic_macaddr);
+ run_set_bssid(sc, sc->sc_bssid);
RUN_UNLOCK(sc);
@@ -4826,7 +4894,7 @@ static void
run_update_beacon(struct ieee80211vap *vap, int item)
{
struct ieee80211com *ic = vap->iv_ic;
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
struct run_vap *rvp = RUN_VAP(vap);
int mcast = 0;
uint32_t i;
@@ -4871,7 +4939,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_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
struct rt2860_txwi txwi;
struct mbuf *m;
uint16_t txwisize;
@@ -4919,7 +4987,7 @@ run_update_beacon_cb(void *arg)
static void
run_updateprot(struct ieee80211com *ic)
{
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
uint32_t i;
i = RUN_CMDQ_GET(&sc->cmdq_store);
@@ -4933,7 +5001,7 @@ static void
run_updateprot_cb(void *arg)
{
struct ieee80211com *ic = arg;
- struct run_softc *sc = ic->ic_softc;
+ struct run_softc *sc = ic->ic_ifp->if_softc;
uint32_t tmp;
tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
@@ -4957,7 +5025,7 @@ static void
run_usb_timeout_cb(void *arg)
{
struct ieee80211vap *vap = arg;
- struct run_softc *sc = vap->iv_ic->ic_softc;
+ struct run_softc *sc = vap->iv_ic->ic_ifp->if_softc;
RUN_LOCK_ASSERT(sc, MA_OWNED);
@@ -5003,12 +5071,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_ic.ic_promisc > 0)
+ if (sc->sc_ifp->if_flags & IFF_PROMISC)
tmp &= ~RT2860_DROP_UC_NOME;
run_write(sc, RT2860_RX_FILTR_CFG, tmp);
- DPRINTF("%s promiscuous mode\n", (sc->sc_ic.ic_promisc > 0) ?
+ DPRINTF("%s promiscuous mode\n", (sc->sc_ifp->if_flags & IFF_PROMISC) ?
"entering" : "leaving");
}
@@ -5017,7 +5085,7 @@ run_update_promisc(struct ieee80211com *ic)
{
struct run_softc *sc = ic->ic_softc;
- if ((sc->sc_flags & RUN_RUNNING) == 0)
+ if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
return;
RUN_LOCK(sc);
@@ -5028,7 +5096,7 @@ run_update_promisc(struct ieee80211com *ic)
static void
run_enable_tsf_sync(struct run_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
@@ -5093,7 +5161,7 @@ run_enable_mrr(struct run_softc *sc)
static void
run_set_txpreamble(struct run_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
uint32_t tmp;
run_read(sc, RT2860_AUTO_RSP_CFG, &tmp);
@@ -5107,7 +5175,7 @@ run_set_txpreamble(struct run_softc *sc)
static void
run_set_basicrates(struct run_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
/* set basic rates mask */
if (ic->ic_curmode == IEEE80211_MODE_11B)
@@ -5152,7 +5220,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;
+ sc->cmdq[i].arg0 = ic->ic_ifp;
ieee80211_runtask(ic, &sc->cmdq_task);
return;
@@ -5162,8 +5230,9 @@ run_updateslot(struct ieee80211com *ic)
static void
run_updateslot_cb(void *arg)
{
- struct ieee80211com *ic = arg;
- struct run_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = arg;
+ struct run_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
run_read(sc, RT2860_BKOFF_SLOT_CFG, &tmp);
@@ -5175,12 +5244,15 @@ 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_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211_channel *c = ic->ic_curchan;
int delta;
@@ -5830,7 +5902,7 @@ run_rt5390_rf_setup(struct run_softc *sc)
static int
run_txrx_enable(struct run_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
uint32_t tmp;
int error, ntries;
@@ -5890,8 +5962,8 @@ run_adjust_freq_offset(struct run_softc *sc)
static void
run_init_locked(struct run_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
uint8_t bbp1, bbp3;
int i;
@@ -5921,7 +5993,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, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ run_set_macaddr(sc, IF_LLADDR(ifp));
for (ntries = 0; ntries < 100; ntries++) {
if (run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp) != 0)
@@ -6094,7 +6166,8 @@ run_init_locked(struct run_softc *sc)
/* turn radio LED on */
run_set_leds(sc, RT2860_LED_RADIO);
- sc->sc_flags |= RUN_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->cmdq_run = RUN_CMDQ_GO;
for (i = 0; i != RUN_N_XFER; i++)
@@ -6112,19 +6185,35 @@ 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 (sc->sc_flags & RUN_RUNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
run_set_leds(sc, 0); /* turn all LEDs off */
- sc->sc_flags &= ~RUN_RUNNING;
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
sc->ratectl_run = RUN_RATECTL_OFF;
sc->cmdq_run = sc->cmdq_key_set;
OpenPOWER on IntegriCloud