aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ral
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2015-08-08 01:10:17 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2015-08-08 01:10:17 +0000
commitba2c1fbc03f312b978f76f7b6c67eec6afa80bf8 (patch)
tree5973a9059f73ed5abf84d6d98e44f1953e764064 /sys/dev/ral
parent721b581722c3a383f02036d009db4473590e3f88 (diff)
Notes
Diffstat (limited to 'sys/dev/ral')
-rw-r--r--sys/dev/ral/if_ral_pci.c1
-rw-r--r--sys/dev/ral/rt2560.c305
-rw-r--r--sys/dev/ral/rt2560var.h9
-rw-r--r--sys/dev/ral/rt2661.c289
-rw-r--r--sys/dev/ral/rt2661var.h7
-rw-r--r--sys/dev/ral/rt2860.c274
-rw-r--r--sys/dev/ral/rt2860var.h7
7 files changed, 543 insertions, 349 deletions
diff --git a/sys/dev/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c
index 42ec03424bdf..519b4ca30d78 100644
--- a/sys/dev/ral/if_ral_pci.c
+++ b/sys/dev/ral/if_ral_pci.c
@@ -28,7 +28,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
-#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/rman.h>
diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c
index ea9c4162b8f8..29ce8cbf8014 100644
--- a/sys/dev/ral/rt2560.c
+++ b/sys/dev/ral/rt2560.c
@@ -127,10 +127,10 @@ static int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *,
struct ieee80211_node *);
static int rt2560_tx_data(struct rt2560_softc *, struct mbuf *,
struct ieee80211_node *);
-static int rt2560_transmit(struct ieee80211com *, struct mbuf *);
-static void rt2560_start(struct rt2560_softc *);
+static void rt2560_start_locked(struct ifnet *);
+static void rt2560_start(struct ifnet *);
static void rt2560_watchdog(void *);
-static void rt2560_parent(struct ieee80211com *);
+static int rt2560_ioctl(struct ifnet *, u_long, caddr_t);
static void rt2560_bbp_write(struct rt2560_softc *, uint8_t,
uint8_t);
static uint8_t rt2560_bbp_read(struct rt2560_softc *, uint8_t);
@@ -149,8 +149,7 @@ static void rt2560_set_basicrates(struct rt2560_softc *,
const struct ieee80211_rateset *);
static void rt2560_update_led(struct rt2560_softc *, int, int);
static void rt2560_set_bssid(struct rt2560_softc *, const uint8_t *);
-static void rt2560_set_macaddr(struct rt2560_softc *,
- const uint8_t *);
+static void rt2560_set_macaddr(struct rt2560_softc *, uint8_t *);
static void rt2560_get_macaddr(struct rt2560_softc *, uint8_t *);
static void rt2560_update_promisc(struct ieee80211com *);
static const char *rt2560_get_rf(int);
@@ -198,9 +197,11 @@ int
rt2560_attach(device_t dev, int id)
{
struct rt2560_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = &sc->sc_ic;
- uint8_t bands;
+ struct ieee80211com *ic;
+ struct ifnet *ifp;
int error;
+ uint8_t bands;
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
@@ -208,7 +209,6 @@ rt2560_attach(device_t dev, int id)
MTX_DEF | MTX_RECURSE);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
- mbufq_init(&sc->sc_snd, ifqmaxlen);
/* retrieve RT2560 rev. no */
sc->asic_rev = RAL_READ(sc, RT2560_CSR0);
@@ -252,9 +252,27 @@ rt2560_attach(device_t dev, int id)
goto fail5;
}
+ ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
+ if (ifp == NULL) {
+ device_printf(sc->sc_dev, "can not if_alloc()\n");
+ goto fail6;
+ }
+ ic = ifp->if_l2com;
+
/* retrieve MAC address */
- rt2560_get_macaddr(sc, ic->ic_macaddr);
+ rt2560_get_macaddr(sc, macaddr);
+
+ ifp->if_softc = sc;
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_init = rt2560_init;
+ ifp->if_ioctl = rt2560_ioctl;
+ ifp->if_start = rt2560_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(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -285,7 +303,7 @@ rt2560_attach(device_t dev, int id)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic);
+ ieee80211_ifattach(ic, macaddr);
ic->ic_raw_xmit = rt2560_raw_xmit;
ic->ic_updateslot = rt2560_update_slot;
ic->ic_update_promisc = rt2560_update_promisc;
@@ -295,8 +313,6 @@ rt2560_attach(device_t dev, int id)
ic->ic_vap_create = rt2560_vap_create;
ic->ic_vap_delete = rt2560_vap_delete;
- ic->ic_parent = rt2560_parent;
- ic->ic_transmit = rt2560_transmit;
ieee80211_radiotap_attach(ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
@@ -325,6 +341,7 @@ rt2560_attach(device_t dev, int id)
return 0;
+fail6: rt2560_free_rx_ring(sc, &sc->rxq);
fail5: rt2560_free_tx_ring(sc, &sc->bcnq);
fail4: rt2560_free_tx_ring(sc, &sc->prioq);
fail3: rt2560_free_tx_ring(sc, &sc->atimq);
@@ -338,12 +355,12 @@ int
rt2560_detach(void *xsc)
{
struct rt2560_softc *sc = xsc;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
rt2560_stop(sc);
ieee80211_ifdetach(ic);
- mbufq_drain(&sc->sc_snd);
rt2560_free_tx_ring(sc, &sc->txq);
rt2560_free_tx_ring(sc, &sc->atimq);
@@ -351,6 +368,8 @@ rt2560_detach(void *xsc)
rt2560_free_tx_ring(sc, &sc->bcnq);
rt2560_free_rx_ring(sc, &sc->rxq);
+ if_free(ifp);
+
mtx_destroy(&sc->sc_mtx);
return 0;
@@ -362,7 +381,7 @@ rt2560_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 rt2560_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
struct rt2560_vap *rvp;
struct ieee80211vap *vap;
@@ -375,7 +394,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MBSS:
/* XXXRP: TBD */
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- device_printf(sc->sc_dev, "only 1 vap supported\n");
+ if_printf(ifp, "only 1 vap supported\n");
return NULL;
}
if (opmode == IEEE80211_M_STA)
@@ -384,8 +403,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_WDS:
if (TAILQ_EMPTY(&ic->ic_vaps) ||
ic->ic_opmode != IEEE80211_M_HOSTAP) {
- device_printf(sc->sc_dev,
- "wds only supported in ap mode\n");
+ if_printf(ifp, "wds only supported in ap mode\n");
return NULL;
}
/*
@@ -396,12 +414,15 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
flags &= ~IEEE80211_CLONE_BSSID;
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 rt2560_vap), M_80211_VAP, M_WAITOK | M_ZERO);
+ rvp = (struct rt2560_vap *) malloc(sizeof(struct rt2560_vap),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (rvp == NULL)
+ return NULL;
vap = &rvp->ral_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
/* override state transition machine */
rvp->ral_newstate = vap->iv_newstate;
@@ -410,8 +431,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status, mac);
+ ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
ic->ic_opmode = opmode;
return vap;
@@ -431,8 +451,9 @@ void
rt2560_resume(void *xsc)
{
struct rt2560_softc *sc = xsc;
+ struct ifnet *ifp = sc->sc_ifp;
- if (sc->sc_ic.ic_nrunning > 0)
+ if (ifp->if_flags & IFF_UP)
rt2560_init(sc);
}
@@ -742,7 +763,8 @@ static int
rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rt2560_vap *rvp = RT2560_VAP(vap);
- struct rt2560_softc *sc = vap->iv_ic->ic_softc;
+ struct ifnet *ifp = vap->iv_ic->ic_ifp;
+ struct rt2560_softc *sc = ifp->if_softc;
int error;
if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) {
@@ -770,8 +792,7 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
vap->iv_opmode == IEEE80211_M_MBSS) {
m = ieee80211_beacon_alloc(ni, &rvp->ral_bo);
if (m == NULL) {
- device_printf(sc->sc_dev,
- "could not allocate beacon\n");
+ if_printf(ifp, "could not allocate beacon\n");
return ENOBUFS;
}
ieee80211_ref_node(ni);
@@ -905,13 +926,14 @@ rt2560_encryption_intr(struct rt2560_softc *sc)
static void
rt2560_tx_intr(struct rt2560_softc *sc)
{
+ struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
struct mbuf *m;
+ uint32_t flags;
+ int retrycnt;
struct ieee80211vap *vap;
struct ieee80211_node *ni;
- uint32_t flags;
- int retrycnt, status;
bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
BUS_DMASYNC_POSTREAD);
@@ -939,7 +961,7 @@ rt2560_tx_intr(struct rt2560_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS,
&retrycnt, NULL);
- status = 0;
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
break;
case RT2560_TX_SUCCESS_RETRY:
@@ -951,7 +973,7 @@ rt2560_tx_intr(struct rt2560_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS,
&retrycnt, NULL);
- status = 0;
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
break;
case RT2560_TX_FAIL_RETRY:
@@ -963,7 +985,7 @@ rt2560_tx_intr(struct rt2560_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE,
&retrycnt, NULL);
- status = 1;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
case RT2560_TX_FAIL_INVALID:
@@ -971,16 +993,16 @@ rt2560_tx_intr(struct rt2560_softc *sc)
default:
device_printf(sc->sc_dev, "sending data frame failed "
"0x%08x\n", flags);
- status = 1;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
bus_dmamap_sync(sc->txq.data_dmat, data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->txq.data_dmat, data->map);
-
- ieee80211_tx_complete(ni, m, status);
- data->ni = NULL;
+ m_freem(m);
data->m = NULL;
+ ieee80211_free_node(data->ni);
+ data->ni = NULL;
/* descriptor is no longer valid */
desc->flags &= ~htole32(RT2560_TX_VALID);
@@ -997,13 +1019,19 @@ rt2560_tx_intr(struct rt2560_softc *sc)
if (sc->prioq.queued == 0 && sc->txq.queued == 0)
sc->sc_tx_timer = 0;
- if (sc->txq.queued < RT2560_TX_RING_COUNT - 1)
- rt2560_start(sc);
+ if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) {
+ sc->sc_flags &= ~RT2560_F_DATA_OACTIVE;
+ if ((sc->sc_flags &
+ (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0)
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ rt2560_start_locked(ifp);
+ }
}
static void
rt2560_prio_intr(struct rt2560_softc *sc)
{
+ struct ifnet *ifp = sc->sc_ifp;
struct rt2560_tx_desc *desc;
struct rt2560_tx_data *data;
struct ieee80211_node *ni;
@@ -1075,8 +1103,13 @@ rt2560_prio_intr(struct rt2560_softc *sc)
if (sc->prioq.queued == 0 && sc->txq.queued == 0)
sc->sc_tx_timer = 0;
- if (sc->prioq.queued < RT2560_PRIO_RING_COUNT)
- rt2560_start(sc);
+ if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) {
+ sc->sc_flags &= ~RT2560_F_PRIO_OACTIVE;
+ if ((sc->sc_flags &
+ (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0)
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ rt2560_start_locked(ifp);
+ }
}
/*
@@ -1086,7 +1119,8 @@ rt2560_prio_intr(struct rt2560_softc *sc)
static void
rt2560_decryption_intr(struct rt2560_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct rt2560_rx_desc *desc;
struct rt2560_rx_data *data;
bus_addr_t physaddr;
@@ -1112,13 +1146,13 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
break;
if (data->drop) {
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
if ((le32toh(desc->flags) & RT2560_RX_CIPHER_MASK) != 0 &&
(le32toh(desc->flags) & RT2560_RX_ICV_ERROR)) {
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1131,7 +1165,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
*/
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1154,7 +1188,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
panic("%s: could not load old rx mbuf",
device_get_name(sc->sc_dev));
}
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1167,6 +1201,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
desc->physaddr = htole32(physaddr);
/* finalize mbuf */
+ m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len =
(le32toh(desc->flags) >> 16) & 0xfff;
@@ -1286,7 +1321,8 @@ rt2560_beacon_update(struct ieee80211vap *vap, int item)
static void
rt2560_beacon_expire(struct rt2560_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct rt2560_vap *rvp = RT2560_VAP(vap);
struct rt2560_tx_data *data;
@@ -1327,6 +1363,7 @@ void
rt2560_intr(void *arg)
{
struct rt2560_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
uint32_t r;
RAL_LOCK(sc);
@@ -1335,7 +1372,7 @@ rt2560_intr(void *arg)
RAL_WRITE(sc, RT2560_CSR8, 0xffffffff);
/* don't re-enable interrupts if we're shutting down */
- if (!(sc->sc_flags & RT2560_F_RUNNING)) {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
RAL_UNLOCK(sc);
return;
}
@@ -1403,7 +1440,8 @@ static void
rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc,
uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint16_t plcp_length;
int remainder;
@@ -1878,57 +1916,55 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
return 0;
}
-static int
-rt2560_transmit(struct ieee80211com *ic, struct mbuf *m)
-{
- struct rt2560_softc *sc = ic->ic_softc;
- int error;
-
- RAL_LOCK(sc);
- if ((sc->sc_flags & RT2560_F_RUNNING) == 0) {
- RAL_UNLOCK(sc);
- return (ENXIO);
- }
- error = mbufq_enqueue(&sc->sc_snd, m);
- if (error) {
- RAL_UNLOCK(sc);
- return (error);
- }
- rt2560_start(sc);
- RAL_UNLOCK(sc);
-
- return (0);
-}
-
static void
-rt2560_start(struct rt2560_softc *sc)
+rt2560_start_locked(struct ifnet *ifp)
{
- struct ieee80211_node *ni;
+ struct rt2560_softc *sc = ifp->if_softc;
struct mbuf *m;
+ struct ieee80211_node *ni;
RAL_LOCK_ASSERT(sc);
- while (sc->txq.queued < RT2560_TX_RING_COUNT - 1 &&
- (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+ for (;;) {
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+ if (m == NULL)
+ break;
+ if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) {
+ IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ sc->sc_flags |= RT2560_F_DATA_OACTIVE;
+ break;
+ }
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (rt2560_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;
}
+
sc->sc_tx_timer = 5;
}
}
static void
+rt2560_start(struct ifnet *ifp)
+{
+ struct rt2560_softc *sc = ifp->if_softc;
+
+ RAL_LOCK(sc);
+ rt2560_start_locked(ifp);
+ RAL_UNLOCK(sc);
+}
+
+static void
rt2560_watchdog(void *arg)
{
struct rt2560_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc);
- KASSERT(sc->sc_flags & RT2560_F_RUNNING, ("not running"));
+ KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
if (sc->sc_invalid) /* card ejected */
return;
@@ -1937,33 +1973,51 @@ rt2560_watchdog(void *arg)
rt2560_tx_intr(sc);
if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
+ if_printf(ifp, "device timeout\n");
rt2560_init_locked(sc);
- counter_u64_add(sc->sc_ic.ic_oerrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
/* NB: callout is reset in rt2560_init() */
return;
}
callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
}
-static void
-rt2560_parent(struct ieee80211com *ic)
+static int
+rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
- struct rt2560_softc *sc = ic->ic_softc;
- int startall = 0;
+ struct rt2560_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ifreq *ifr = (struct ifreq *) data;
+ int error = 0, startall = 0;
- RAL_LOCK(sc);
- if (ic->ic_nrunning > 0) {
- if ((sc->sc_flags & RT2560_F_RUNNING) == 0) {
- rt2560_init_locked(sc);
- startall = 1;
- } else
- rt2560_update_promisc(ic);
- } else if (sc->sc_flags & RT2560_F_RUNNING)
- rt2560_stop_locked(sc);
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ RAL_LOCK(sc);
+ if (ifp->if_flags & IFF_UP) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ rt2560_init_locked(sc);
+ startall = 1;
+ } else
+ rt2560_update_promisc(ic);
+ } else {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ rt2560_stop_locked(sc);
+ }
+ RAL_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 error;
}
static void
@@ -2047,7 +2101,8 @@ rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val)
static void
rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint8_t power, tmp;
u_int i, chan;
@@ -2146,7 +2201,8 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c)
static void
rt2560_set_channel(struct ieee80211com *ic)
{
- struct rt2560_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2560_softc *sc = ifp->if_softc;
RAL_LOCK(sc);
rt2560_set_chan(sc, ic->ic_curchan);
@@ -2182,7 +2238,8 @@ rt2560_disable_rf_tune(struct rt2560_softc *sc)
static void
rt2560_enable_tsf_sync(struct rt2560_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t logcwmin, preload;
uint32_t tmp;
@@ -2223,7 +2280,8 @@ rt2560_enable_tsf(struct rt2560_softc *sc)
static void
rt2560_update_plcp(struct rt2560_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
/* no short preamble for 1Mbps */
RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400);
@@ -2302,7 +2360,8 @@ rt2560_set_basicrates(struct rt2560_softc *sc,
const struct ieee80211_rateset *rs)
{
#define RV(r) ((r) & IEEE80211_RATE_VAL)
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t mask = 0;
uint8_t rate;
int i;
@@ -2347,7 +2406,7 @@ rt2560_set_bssid(struct rt2560_softc *sc, const uint8_t *bssid)
}
static void
-rt2560_set_macaddr(struct rt2560_softc *sc, const uint8_t *addr)
+rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr)
{
uint32_t tmp;
@@ -2385,13 +2444,13 @@ rt2560_update_promisc(struct ieee80211com *ic)
tmp = RAL_READ(sc, RT2560_RXCSR0);
tmp &= ~RT2560_DROP_NOT_TO_ME;
- if (ic->ic_promisc == 0)
+ if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
tmp |= RT2560_DROP_NOT_TO_ME;
RAL_WRITE(sc, RT2560_RXCSR0, tmp);
DPRINTF(sc, "%s promiscuous mode\n",
- (ic->ic_promisc > 0) ? "entering" : "leaving");
+ (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
}
static const char *
@@ -2457,17 +2516,19 @@ rt2560_read_config(struct rt2560_softc *sc)
static void
rt2560_scan_start(struct ieee80211com *ic)
{
- struct rt2560_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2560_softc *sc = ifp->if_softc;
/* abort TSF synchronization */
RAL_WRITE(sc, RT2560_CSR14, 0);
- rt2560_set_bssid(sc, ieee80211broadcastaddr);
+ rt2560_set_bssid(sc, ifp->if_broadcastaddr);
}
static void
rt2560_scan_end(struct ieee80211com *ic)
{
- struct rt2560_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2560_softc *sc = ifp->if_softc;
struct ieee80211vap *vap = ic->ic_scan->ss_vap;
rt2560_enable_tsf_sync(sc);
@@ -2561,8 +2622,8 @@ static void
rt2560_init_locked(struct rt2560_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
- 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;
int i;
@@ -2593,7 +2654,7 @@ rt2560_init_locked(struct rt2560_softc *sc)
for (i = 0; i < N(rt2560_def_mac); i++)
RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val);
- rt2560_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ rt2560_set_macaddr(sc, IF_LLADDR(ifp));
/* set basic rate set (will be updated later) */
RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153);
@@ -2623,7 +2684,7 @@ rt2560_init_locked(struct rt2560_softc *sc)
if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
ic->ic_opmode != IEEE80211_M_MBSS)
tmp |= RT2560_DROP_TODS;
- if (ic->ic_promisc == 0)
+ if (!(ifp->if_flags & IFF_PROMISC))
tmp |= RT2560_DROP_NOT_TO_ME;
}
RAL_WRITE(sc, RT2560_RXCSR0, tmp);
@@ -2638,7 +2699,8 @@ rt2560_init_locked(struct rt2560_softc *sc)
/* enable interrupts */
RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK);
- sc->sc_flags |= RT2560_F_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
#undef N
@@ -2648,19 +2710,21 @@ static void
rt2560_init(void *priv)
{
struct rt2560_softc *sc = priv;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
RAL_LOCK(sc);
rt2560_init_locked(sc);
RAL_UNLOCK(sc);
- if (sc->sc_flags & RT2560_F_RUNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ieee80211_start_all(ic); /* start all vap's */
}
static void
rt2560_stop_locked(struct rt2560_softc *sc)
{
+ struct ifnet *ifp = sc->sc_ifp;
volatile int *flags = &sc->sc_flags;
RAL_LOCK_ASSERT(sc);
@@ -2671,8 +2735,8 @@ rt2560_stop_locked(struct rt2560_softc *sc)
callout_stop(&sc->watchdog_ch);
sc->sc_tx_timer = 0;
- if (sc->sc_flags & RT2560_F_RUNNING) {
- sc->sc_flags &= ~RT2560_F_RUNNING;
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
/* abort Tx */
RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX);
@@ -2694,6 +2758,7 @@ rt2560_stop_locked(struct rt2560_softc *sc)
rt2560_reset_tx_ring(sc, &sc->bcnq);
rt2560_reset_rx_ring(sc, &sc->rxq);
}
+ sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE);
}
void
@@ -2711,24 +2776,29 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct rt2560_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2560_softc *sc = ifp->if_softc;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(sc->sc_flags & RT2560_F_RUNNING)) {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ sc->sc_flags |= RT2560_F_PRIO_OACTIVE;
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENOBUFS; /* XXX */
}
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+
if (params == NULL) {
/*
* Legacy path; interpret frame contents to decide
@@ -2750,6 +2820,7 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
RAL_UNLOCK(sc);
return EIO; /* XXX */
diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h
index 3a5fef981080..b6a8d68e9236 100644
--- a/sys/dev/ral/rt2560var.h
+++ b/sys/dev/ral/rt2560var.h
@@ -105,13 +105,13 @@ struct rt2560_vap {
#define RT2560_VAP(vap) ((struct rt2560_vap *)(vap))
struct rt2560_softc {
- struct ieee80211com sc_ic;
- struct mtx sc_mtx;
- struct mbufq sc_snd;
+ struct ifnet *sc_ifp;
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
+ struct mtx sc_mtx;
+
struct callout watchdog_ch;
int sc_tx_timer;
@@ -152,7 +152,8 @@ struct rt2560_softc {
struct rt2560_tx_radiotap_header sc_txtap;
int sc_txtap_len;
#define RT2560_F_INPUT_RUNNING 0x1
-#define RT2560_F_RUNNING 0x2
+#define RT2560_F_PRIO_OACTIVE 0x2
+#define RT2560_F_DATA_OACTIVE 0x4
int sc_flags;
};
diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c
index c77d4f88df76..15a2364a2c74 100644
--- a/sys/dev/ral/rt2661.c
+++ b/sys/dev/ral/rt2661.c
@@ -121,12 +121,12 @@ static int rt2661_tx_data(struct rt2661_softc *, struct mbuf *,
struct ieee80211_node *, int);
static int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *,
struct ieee80211_node *);
-static int rt2661_transmit(struct ieee80211com *, struct mbuf *);
-static void rt2661_start(struct rt2661_softc *);
+static void rt2661_start_locked(struct ifnet *);
+static void rt2661_start(struct ifnet *);
static int rt2661_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void rt2661_watchdog(void *);
-static void rt2661_parent(struct ieee80211com *);
+static int rt2661_ioctl(struct ifnet *, u_long, caddr_t);
static void rt2661_bbp_write(struct rt2661_softc *, uint8_t,
uint8_t);
static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t);
@@ -197,19 +197,27 @@ int
rt2661_attach(device_t dev, int id)
{
struct rt2661_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic;
+ struct ifnet *ifp;
uint32_t val;
int error, ac, ntries;
uint8_t bands;
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_id = id;
sc->sc_dev = dev;
+ ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
+ if (ifp == NULL) {
+ device_printf(sc->sc_dev, "can not if_alloc()\n");
+ return ENOMEM;
+ }
+ ic = ifp->if_l2com;
+
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
- mbufq_init(&sc->sc_snd, ifqmaxlen);
/* wait for NIC to initialize */
for (ntries = 0; ntries < 1000; ntries++) {
@@ -225,7 +233,7 @@ rt2661_attach(device_t dev, int id)
}
/* retrieve RF rev. no and various other things from EEPROM */
- rt2661_read_eeprom(sc, ic->ic_macaddr);
+ rt2661_read_eeprom(sc, macaddr);
device_printf(dev, "MAC/BBP RT%X, RF %s\n", val,
rt2661_get_rf(sc->rf_rev));
@@ -255,6 +263,17 @@ rt2661_attach(device_t dev, int id)
goto fail3;
}
+ ifp->if_softc = sc;
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_init = rt2661_init;
+ ifp->if_ioctl = rt2661_ioctl;
+ ifp->if_start = rt2661_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(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -286,7 +305,7 @@ rt2661_attach(device_t dev, int id)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic);
+ ieee80211_ifattach(ic, macaddr);
#if 0
ic->ic_wme.wme_update = rt2661_wme_update;
#endif
@@ -296,8 +315,7 @@ rt2661_attach(device_t dev, int id)
ic->ic_updateslot = rt2661_update_slot;
ic->ic_update_promisc = rt2661_update_promisc;
ic->ic_raw_xmit = rt2661_raw_xmit;
- ic->ic_transmit = rt2661_transmit;
- ic->ic_parent = rt2661_parent;
+
ic->ic_vap_create = rt2661_vap_create;
ic->ic_vap_delete = rt2661_vap_delete;
@@ -321,6 +339,7 @@ fail3: rt2661_free_tx_ring(sc, &sc->mgtq);
fail2: while (--ac >= 0)
rt2661_free_tx_ring(sc, &sc->txq[ac]);
fail1: mtx_destroy(&sc->sc_mtx);
+ if_free(ifp);
return error;
}
@@ -328,14 +347,14 @@ int
rt2661_detach(void *xsc)
{
struct rt2661_softc *sc = xsc;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
RAL_LOCK(sc);
rt2661_stop_locked(sc);
RAL_UNLOCK(sc);
ieee80211_ifdetach(ic);
- mbufq_drain(&sc->sc_snd);
rt2661_free_tx_ring(sc, &sc->txq[0]);
rt2661_free_tx_ring(sc, &sc->txq[1]);
@@ -344,6 +363,8 @@ rt2661_detach(void *xsc)
rt2661_free_tx_ring(sc, &sc->mgtq);
rt2661_free_rx_ring(sc, &sc->rxq);
+ if_free(ifp);
+
mtx_destroy(&sc->sc_mtx);
return 0;
@@ -355,7 +376,7 @@ rt2661_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 rt2661_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
struct rt2661_vap *rvp;
struct ieee80211vap *vap;
@@ -368,7 +389,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MBSS:
/* XXXRP: TBD */
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- device_printf(sc->sc_dev, "only 1 vap supported\n");
+ if_printf(ifp, "only 1 vap supported\n");
return NULL;
}
if (opmode == IEEE80211_M_STA)
@@ -377,8 +398,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_WDS:
if (TAILQ_EMPTY(&ic->ic_vaps) ||
ic->ic_opmode != IEEE80211_M_HOSTAP) {
- device_printf(sc->sc_dev,
- "wds only supported in ap mode\n");
+ if_printf(ifp, "wds only supported in ap mode\n");
return NULL;
}
/*
@@ -389,12 +409,15 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
flags &= ~IEEE80211_CLONE_BSSID;
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 rt2661_vap), M_80211_VAP, M_WAITOK | M_ZERO);
+ rvp = (struct rt2661_vap *) malloc(sizeof(struct rt2661_vap),
+ M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (rvp == NULL)
+ return NULL;
vap = &rvp->ral_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
/* override state transition machine */
rvp->ral_newstate = vap->iv_newstate;
@@ -405,8 +428,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status, mac);
+ ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
ic->ic_opmode = opmode;
return vap;
@@ -442,8 +464,9 @@ void
rt2661_resume(void *xsc)
{
struct rt2661_softc *sc = xsc;
+ struct ifnet *ifp = sc->sc_ifp;
- if (sc->sc_ic.ic_nrunning > 0)
+ if (ifp->if_flags & IFF_UP)
rt2661_init(sc);
}
@@ -747,7 +770,7 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rt2661_vap *rvp = RT2661_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rt2661_softc *sc = ic->ic_softc;
+ struct rt2661_softc *sc = ic->ic_ifp->if_softc;
int error;
if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) {
@@ -846,10 +869,11 @@ rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr)
static void
rt2661_tx_intr(struct rt2661_softc *sc)
{
+ struct ifnet *ifp = sc->sc_ifp;
struct rt2661_tx_ring *txq;
struct rt2661_tx_data *data;
uint32_t val;
- int error, qid, retrycnt;
+ int qid, retrycnt;
struct ieee80211vap *vap;
for (;;) {
@@ -887,7 +911,7 @@ rt2661_tx_intr(struct rt2661_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS,
&retrycnt, NULL);
- error = 0;
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
break;
case RT2661_TX_RETRY_FAIL:
@@ -899,14 +923,14 @@ rt2661_tx_intr(struct rt2661_softc *sc)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE,
&retrycnt, NULL);
- error = 1;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
default:
/* other failure */
device_printf(sc->sc_dev,
"sending data frame failed 0x%08x\n", val);
- error = 1;
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
DPRINTFN(sc, 15, "tx done q=%d idx=%u\n", qid, txq->stat);
@@ -915,12 +939,17 @@ rt2661_tx_intr(struct rt2661_softc *sc)
if (++txq->stat >= txq->count) /* faster than % count */
txq->stat = 0;
- ieee80211_tx_complete(ni, m, error);
+ if (m->m_flags & M_TXCB)
+ ieee80211_process_callback(ni, m,
+ RT2661_TX_RESULT(val) != RT2661_TX_SUCCESS);
+ m_freem(m);
+ ieee80211_free_node(ni);
}
sc->sc_tx_timer = 0;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- rt2661_start(sc);
+ rt2661_start_locked(ifp);
}
static void
@@ -958,7 +987,8 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq)
static void
rt2661_rx_intr(struct rt2661_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct rt2661_rx_desc *desc;
struct rt2661_rx_data *data;
bus_addr_t physaddr;
@@ -987,12 +1017,12 @@ rt2661_rx_intr(struct rt2661_softc *sc)
*/
DPRINTFN(sc, 5, "PHY or CRC error flags 0x%08x\n",
le32toh(desc->flags));
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
if ((le32toh(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) {
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1005,7 +1035,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
*/
mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mnew == NULL) {
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1028,7 +1058,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
panic("%s: could not load old rx mbuf",
device_get_name(sc->sc_dev));
}
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1041,6 +1071,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
desc->physaddr = htole32(physaddr);
/* finalize mbuf */
+ m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len =
(le32toh(desc->flags) >> 16) & 0xfff;
@@ -1125,6 +1156,7 @@ void
rt2661_intr(void *arg)
{
struct rt2661_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
uint32_t r1, r2;
RAL_LOCK(sc);
@@ -1134,7 +1166,7 @@ rt2661_intr(void *arg)
RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
/* don't re-enable interrupts if we're shutting down */
- if (!(sc->sc_flags & RAL_RUNNING)) {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
RAL_UNLOCK(sc);
return;
}
@@ -1210,7 +1242,8 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
uint32_t flags, uint16_t xflags, int len, int rate,
const bus_dma_segment_t *segs, int nsegs, int ac)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint16_t plcp_length;
int i, remainder;
@@ -1428,7 +1461,8 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
struct ieee80211_node *ni, int ac)
{
struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct rt2661_tx_ring *txq = &sc->txq[ac];
struct rt2661_tx_desc *desc;
struct rt2661_tx_data *data;
@@ -1570,31 +1604,10 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
return 0;
}
-static int
-rt2661_transmit(struct ieee80211com *ic, struct mbuf *m)
-{
- struct rt2661_softc *sc = ic->ic_softc;
- int error;
-
- RAL_LOCK(sc);
- if ((sc->sc_flags & RAL_RUNNING) == 0) {
- RAL_UNLOCK(sc);
- return (ENXIO);
- }
- error = mbufq_enqueue(&sc->sc_snd, m);
- if (error) {
- RAL_UNLOCK(sc);
- return (error);
- }
- rt2661_start(sc);
- RAL_UNLOCK(sc);
-
- return (0);
-}
-
static void
-rt2661_start(struct rt2661_softc *sc)
+rt2661_start_locked(struct ifnet *ifp)
{
+ struct rt2661_softc *sc = ifp->if_softc;
struct mbuf *m;
struct ieee80211_node *ni;
int ac;
@@ -1602,50 +1615,69 @@ rt2661_start(struct rt2661_softc *sc)
RAL_LOCK_ASSERT(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(sc->sc_flags & RAL_RUNNING) || sc->sc_invalid)
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid)
return;
- while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+ for (;;) {
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+ if (m == NULL)
+ break;
+
ac = M_WME_GETAC(m);
if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) {
/* there is no place left in this ring */
- mbufq_prepend(&sc->sc_snd, m);
+ IFQ_DRV_PREPEND(&ifp->if_snd, m);
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
if (rt2661_tx_data(sc, m, ni, ac) != 0) {
ieee80211_free_node(ni);
- if_inc_counter(ni->ni_vap->iv_ifp,
- IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
break;
}
+
sc->sc_tx_timer = 5;
}
}
+static void
+rt2661_start(struct ifnet *ifp)
+{
+ struct rt2661_softc *sc = ifp->if_softc;
+
+ RAL_LOCK(sc);
+ rt2661_start_locked(ifp);
+ RAL_UNLOCK(sc);
+}
+
static int
rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct rt2661_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2661_softc *sc = ifp->if_softc;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(sc->sc_flags & RAL_RUNNING)) {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENETDOWN;
}
if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
return ENOBUFS; /* XXX */
}
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+
/*
* Legacy path; interpret frame contents to decide
* precisely how to send the frame.
@@ -1659,6 +1691,7 @@ rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return 0;
bad:
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
RAL_UNLOCK(sc);
return EIO; /* XXX */
@@ -1668,42 +1701,61 @@ static void
rt2661_watchdog(void *arg)
{
struct rt2661_softc *sc = (struct rt2661_softc *)arg;
+ struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc);
- KASSERT(sc->sc_flags & RAL_RUNNING, ("not running"));
+ KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
if (sc->sc_invalid) /* card ejected */
return;
if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
+ if_printf(ifp, "device timeout\n");
rt2661_init_locked(sc);
- counter_u64_add(sc->sc_ic.ic_oerrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
/* NB: callout is reset in rt2661_init() */
return;
}
callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
}
-static void
-rt2661_parent(struct ieee80211com *ic)
+static int
+rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
- struct rt2661_softc *sc = ic->ic_softc;
- int startall = 0;
+ struct rt2661_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ifreq *ifr = (struct ifreq *) data;
+ int error = 0, startall = 0;
- RAL_LOCK(sc);
- if (ic->ic_nrunning > 0) {
- if ((sc->sc_flags & RAL_RUNNING) == 0) {
- rt2661_init_locked(sc);
- startall = 1;
- } else
- rt2661_update_promisc(ic);
- } else if (sc->sc_flags & RAL_RUNNING)
- rt2661_stop_locked(sc);
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ RAL_LOCK(sc);
+ if (ifp->if_flags & IFF_UP) {
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ rt2661_init_locked(sc);
+ startall = 1;
+ } else
+ rt2661_update_promisc(ic);
+ } else {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ rt2661_stop_locked(sc);
+ }
+ RAL_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 error;
}
static void
@@ -1827,7 +1879,8 @@ rt2661_select_antenna(struct rt2661_softc *sc)
static void
rt2661_enable_mrr(struct rt2661_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
@@ -1843,7 +1896,8 @@ rt2661_enable_mrr(struct rt2661_softc *sc)
static void
rt2661_set_txpreamble(struct rt2661_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
@@ -1860,7 +1914,8 @@ rt2661_set_basicrates(struct rt2661_softc *sc,
const struct ieee80211_rateset *rs)
{
#define RV(r) ((r) & IEEE80211_RATE_VAL)
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t mask = 0;
uint8_t rate;
int i;
@@ -1929,7 +1984,8 @@ rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
static void
rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
const struct rfprog *rfprog;
uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT;
int8_t power;
@@ -2032,13 +2088,13 @@ rt2661_update_promisc(struct ieee80211com *ic)
tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
tmp &= ~RT2661_DROP_NOT_TO_ME;
- if (ic->ic_promisc == 0)
+ if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
tmp |= RT2661_DROP_NOT_TO_ME;
RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
DPRINTF(sc, "%s promiscuous mode\n",
- (ic->ic_promisc > 0) ? "entering" : "leaving");
+ (ic->ic_ifp->if_flags & IFF_PROMISC) ? "entering" : "leaving");
}
/*
@@ -2047,7 +2103,7 @@ rt2661_update_promisc(struct ieee80211com *ic)
static int
rt2661_wme_update(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ic->ic_softc;
+ struct rt2661_softc *sc = ic->ic_ifp->if_softc;
const struct wmeParams *wmep;
wmep = ic->ic_wme.wme_chanParams.cap_wmeParams;
@@ -2245,8 +2301,8 @@ static void
rt2661_init_locked(struct rt2661_softc *sc)
{
#define N(a) (sizeof (a) / sizeof ((a)[0]))
- 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, sta[3];
int i, error, ntries;
@@ -2255,7 +2311,7 @@ rt2661_init_locked(struct rt2661_softc *sc)
if ((sc->sc_flags & RAL_FW_LOADED) == 0) {
error = rt2661_load_microcode(sc);
if (error != 0) {
- device_printf(sc->sc_dev,
+ if_printf(ifp,
"%s: could not load 8051 microcode, error %d\n",
__func__, error);
return;
@@ -2308,7 +2364,7 @@ rt2661_init_locked(struct rt2661_softc *sc)
for (i = 0; i < N(rt2661_def_mac); i++)
RAL_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val);
- rt2661_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ rt2661_set_macaddr(sc, IF_LLADDR(ifp));
/* set host ready */
RAL_WRITE(sc, RT2661_MAC_CSR1, 3);
@@ -2347,7 +2403,7 @@ rt2661_init_locked(struct rt2661_softc *sc)
if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
ic->ic_opmode != IEEE80211_M_MBSS)
tmp |= RT2661_DROP_TODS;
- if (ic->ic_promisc == 0)
+ if (!(ifp->if_flags & IFF_PROMISC))
tmp |= RT2661_DROP_NOT_TO_ME;
}
@@ -2369,7 +2425,8 @@ rt2661_init_locked(struct rt2661_softc *sc)
/* kick Rx */
RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1);
- sc->sc_flags |= RAL_RUNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
#undef N
@@ -2379,21 +2436,23 @@ static void
rt2661_init(void *priv)
{
struct rt2661_softc *sc = priv;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
RAL_LOCK(sc);
rt2661_init_locked(sc);
RAL_UNLOCK(sc);
- if (sc->sc_flags & RAL_RUNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ieee80211_start_all(ic); /* start all vap's */
}
void
rt2661_stop_locked(struct rt2661_softc *sc)
{
- volatile int *flags = &sc->sc_flags;
+ struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
+ volatile int *flags = &sc->sc_flags;
while (*flags & RAL_INPUT_RUNNING)
msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10);
@@ -2401,8 +2460,8 @@ rt2661_stop_locked(struct rt2661_softc *sc)
callout_stop(&sc->watchdog_ch);
sc->sc_tx_timer = 0;
- if (sc->sc_flags & RAL_RUNNING) {
- sc->sc_flags &= ~RAL_RUNNING;
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
/* abort Tx (for all 5 Tx rings) */
RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16);
@@ -2446,6 +2505,7 @@ rt2661_stop(void *priv)
static int
rt2661_load_microcode(struct rt2661_softc *sc)
{
+ struct ifnet *ifp = sc->sc_ifp;
const struct firmware *fp;
const char *imagename;
int ntries, error;
@@ -2457,7 +2517,7 @@ rt2661_load_microcode(struct rt2661_softc *sc)
case 0x0302: imagename = "rt2561fw"; break;
case 0x0401: imagename = "rt2661fw"; break;
default:
- device_printf(sc->sc_dev, "%s: unexpected pci device id 0x%x, "
+ if_printf(ifp, "%s: unexpected pci device id 0x%x, "
"don't know how to retrieve firmware\n",
__func__, sc->sc_id);
return EINVAL;
@@ -2466,8 +2526,7 @@ rt2661_load_microcode(struct rt2661_softc *sc)
fp = firmware_get(imagename);
RAL_LOCK(sc);
if (fp == NULL) {
- device_printf(sc->sc_dev,
- "%s: unable to retrieve firmware image %s\n",
+ if_printf(ifp, "%s: unable to retrieve firmware image %s\n",
__func__, imagename);
return EINVAL;
}
@@ -2498,8 +2557,8 @@ rt2661_load_microcode(struct rt2661_softc *sc)
DELAY(100);
}
if (ntries == 500) {
- device_printf(sc->sc_dev,
- "%s: timeout waiting for MCU to initialize\n", __func__);
+ if_printf(ifp, "%s: timeout waiting for MCU to initialize\n",
+ __func__);
error = EIO;
} else
error = 0;
@@ -2667,7 +2726,8 @@ rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap)
static void
rt2661_enable_tsf_sync(struct rt2661_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
@@ -2751,19 +2811,21 @@ rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw)
static void
rt2661_scan_start(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2661_softc *sc = ifp->if_softc;
uint32_t tmp;
/* abort TSF synchronization */
tmp = RAL_READ(sc, RT2661_TXRX_CSR9);
RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0xffffff);
- rt2661_set_bssid(sc, ieee80211broadcastaddr);
+ rt2661_set_bssid(sc, ifp->if_broadcastaddr);
}
static void
rt2661_scan_end(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2661_softc *sc = ifp->if_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
rt2661_enable_tsf_sync(sc);
@@ -2774,7 +2836,8 @@ rt2661_scan_end(struct ieee80211com *ic)
static void
rt2661_set_channel(struct ieee80211com *ic)
{
- struct rt2661_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2661_softc *sc = ifp->if_softc;
RAL_LOCK(sc);
rt2661_set_chan(sc, ic->ic_curchan);
diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h
index 7ea16f623d57..9927d138fa71 100644
--- a/sys/dev/ral/rt2661var.h
+++ b/sys/dev/ral/rt2661var.h
@@ -97,13 +97,13 @@ struct rt2661_vap {
#define RT2661_VAP(vap) ((struct rt2661_vap *)(vap))
struct rt2661_softc {
- struct ieee80211com sc_ic;
- struct mtx sc_mtx;
- struct mbufq sc_snd;
+ struct ifnet *sc_ifp;
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
+ struct mtx sc_mtx;
+
struct callout watchdog_ch;
int sc_tx_timer;
@@ -117,7 +117,6 @@ struct rt2661_softc {
int sc_flags;
#define RAL_FW_LOADED 0x1
#define RAL_INPUT_RUNNING 0x2
-#define RAL_RUNNING 0x4
int sc_id;
struct ieee80211_channel *sc_curchan;
diff --git a/sys/dev/ral/rt2860.c b/sys/dev/ral/rt2860.c
index b3c737d67c66..782fa1f9780b 100644
--- a/sys/dev/ral/rt2860.c
+++ b/sys/dev/ral/rt2860.c
@@ -122,10 +122,10 @@ static int rt2860_raw_xmit(struct ieee80211_node *, struct mbuf *,
static int rt2860_tx_raw(struct rt2860_softc *, struct mbuf *,
struct ieee80211_node *,
const struct ieee80211_bpf_params *params);
-static int rt2860_transmit(struct ieee80211com *, struct mbuf *);
-static void rt2860_start(struct rt2860_softc *);
+static void rt2860_start(struct ifnet *);
+static void rt2860_start_locked(struct ifnet *);
static void rt2860_watchdog(void *);
-static void rt2860_parent(struct ieee80211com *);
+static int rt2860_ioctl(struct ifnet *, u_long, caddr_t);
static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t);
static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t);
static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t);
@@ -156,7 +156,7 @@ static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *);
static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *);
static void rt2860_update_promisc(struct ieee80211com *);
static void rt2860_updateslot(struct ieee80211com *);
-static void rt2860_updateprot(struct rt2860_softc *);
+static void rt2860_updateprot(struct ifnet *);
static int rt2860_updateedca(struct ieee80211com *);
#ifdef HW_CRYPTO
static int rt2860_set_key(struct ieee80211com *, struct ieee80211_node *,
@@ -230,19 +230,27 @@ int
rt2860_attach(device_t dev, int id)
{
struct rt2860_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic;
+ struct ifnet *ifp;
uint32_t tmp;
int error, ntries, qid;
uint8_t bands;
+ uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
sc->sc_debug = 0;
+ ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
+ if (ifp == NULL) {
+ device_printf(sc->sc_dev, "can not if_alloc()\n");
+ return ENOMEM;
+ }
+ ic = ifp->if_l2com;
+
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
- mbufq_init(&sc->sc_snd, ifqmaxlen);
/* wait for NIC to initialize */
for (ntries = 0; ntries < 100; ntries++) {
@@ -265,11 +273,11 @@ rt2860_attach(device_t dev, int id)
sc->sc_flags |= RT2860_ADVANCED_PS;
/* retrieve RF rev. no and various other things from EEPROM */
- rt2860_read_eeprom(sc, ic->ic_macaddr);
+ rt2860_read_eeprom(sc, macaddr);
device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), "
"RF %s (MIMO %dT%dR), address %6D\n",
sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev),
- sc->ntxchains, sc->nrxchains, ic->ic_macaddr, ":");
+ sc->ntxchains, sc->nrxchains, macaddr, ":");
/*
* Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings.
@@ -296,6 +304,17 @@ rt2860_attach(device_t dev, int id)
sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ?
WME_AC_VO : 5;
+ ifp->if_softc = sc;
+ if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+ ifp->if_init = rt2860_init;
+ ifp->if_ioctl = rt2860_ioctl;
+ ifp->if_start = rt2860_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(dev);
ic->ic_opmode = IEEE80211_M_STA;
@@ -326,7 +345,7 @@ rt2860_attach(device_t dev, int id)
setbit(&bands, IEEE80211_MODE_11A);
ieee80211_init_channels(ic, NULL, &bands);
- ieee80211_ifattach(ic);
+ ieee80211_ifattach(ic, macaddr);
ic->ic_wme.wme_update = rt2860_updateedca;
ic->ic_scan_start = rt2860_scan_start;
@@ -338,8 +357,7 @@ rt2860_attach(device_t dev, int id)
sc->sc_node_free = ic->ic_node_free;
ic->ic_node_free = rt2860_node_free;
ic->ic_newassoc = rt2860_newassoc;
- ic->ic_transmit = rt2860_transmit;
- ic->ic_parent = rt2860_parent;
+
ic->ic_vap_create = rt2860_vap_create;
ic->ic_vap_delete = rt2860_vap_delete;
@@ -363,6 +381,7 @@ fail3: rt2860_free_rx_ring(sc, &sc->rxq);
fail2: while (--qid >= 0)
rt2860_free_tx_ring(sc, &sc->txq[qid]);
fail1: mtx_destroy(&sc->sc_mtx);
+ if_free(ifp);
return error;
}
@@ -370,7 +389,8 @@ int
rt2860_detach(void *xsc)
{
struct rt2860_softc *sc = xsc;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
int qid;
RAL_LOCK(sc);
@@ -378,12 +398,14 @@ rt2860_detach(void *xsc)
RAL_UNLOCK(sc);
ieee80211_ifdetach(ic);
- mbufq_drain(&sc->sc_snd);
+
for (qid = 0; qid < 6; qid++)
rt2860_free_tx_ring(sc, &sc->txq[qid]);
rt2860_free_rx_ring(sc, &sc->rxq);
rt2860_free_tx_pool(sc);
+ if_free(ifp);
+
mtx_destroy(&sc->sc_mtx);
return 0;
@@ -409,8 +431,9 @@ void
rt2860_resume(void *xsc)
{
struct rt2860_softc *sc = xsc;
+ struct ifnet *ifp = sc->sc_ifp;
- if (sc->sc_ic.ic_nrunning > 0)
+ if (ifp->if_flags & IFF_UP)
rt2860_init(sc);
}
@@ -420,7 +443,7 @@ rt2860_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 rt2860_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
struct rt2860_vap *rvp;
struct ieee80211vap *vap;
@@ -433,7 +456,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_MBSS:
/* XXXRP: TBD */
if (!TAILQ_EMPTY(&ic->ic_vaps)) {
- device_printf(sc->sc_dev, "only 1 vap supported\n");
+ if_printf(ifp, "only 1 vap supported\n");
return NULL;
}
if (opmode == IEEE80211_M_STA)
@@ -442,8 +465,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
case IEEE80211_M_WDS:
if (TAILQ_EMPTY(&ic->ic_vaps) ||
ic->ic_opmode != IEEE80211_M_HOSTAP) {
- device_printf(sc->sc_dev,
- "wds only supported in ap mode\n");
+ if_printf(ifp, "wds only supported in ap mode\n");
return NULL;
}
/*
@@ -454,12 +476,14 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
flags &= ~IEEE80211_CLONE_BSSID;
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 rt2860_vap), M_80211_VAP, M_WAITOK | M_ZERO);
+ rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_NOWAIT | M_ZERO);
+ if (rvp == NULL)
+ return NULL;
vap = &rvp->ral_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
/* override state transition machine */
rvp->ral_newstate = vap->iv_newstate;
@@ -473,8 +497,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
ieee80211_ratectl_init(vap);
/* complete setup */
- ieee80211_vap_attach(vap, ieee80211_media_change,
- ieee80211_media_status, mac);
+ ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
if (TAILQ_FIRST(&ic->ic_vaps) == vap)
ic->ic_opmode = opmode;
return vap;
@@ -806,7 +829,7 @@ rt2860_free_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring)
static void
rt2860_updatestats(struct rt2860_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
/*
* In IBSS or HostAP modes (when the hardware sends beacons), the
@@ -833,7 +856,7 @@ static void
rt2860_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ieee80211com *ic = ni->ni_ic;
- struct rt2860_softc *sc = ic->ic_softc;
+ struct rt2860_softc *sc = ic->ic_ifp->if_softc;
uint8_t wcid;
wcid = IEEE80211_AID(ni->ni_associd);
@@ -852,7 +875,7 @@ static void
rt2860_node_free(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
- struct rt2860_softc *sc = ic->ic_softc;
+ struct rt2860_softc *sc = ic->ic_ifp->if_softc;
uint8_t wcid;
if (ni->ni_associd != 0) {
@@ -900,7 +923,7 @@ rt2860_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
struct rt2860_vap *rvp = RT2860_VAP(vap);
struct ieee80211com *ic = vap->iv_ic;
- struct rt2860_softc *sc = ic->ic_softc;
+ struct rt2860_softc *sc = ic->ic_ifp->if_softc;
uint32_t tmp;
int error;
@@ -1078,6 +1101,7 @@ rt2860_intr_coherent(struct rt2860_softc *sc)
static void
rt2860_drain_stats_fifo(struct rt2860_softc *sc)
{
+ struct ifnet *ifp = sc->sc_ifp;
struct ieee80211_node *ni;
uint32_t stat;
int retrycnt;
@@ -1113,8 +1137,7 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc)
} else {
ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL);
- if_inc_counter(ni->ni_vap->iv_ifp,
- IFCOUNTER_OERRORS, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
}
}
@@ -1122,6 +1145,7 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc)
static void
rt2860_tx_intr(struct rt2860_softc *sc, int qid)
{
+ struct ifnet *ifp = sc->sc_ifp;
struct rt2860_tx_ring *ring = &sc->txq[qid];
uint32_t hw;
@@ -1139,11 +1163,15 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid)
ieee80211_process_callback(data->ni, data->m,
0);
}
- ieee80211_tx_complete(data->ni, data->m, 0);
- data->ni = NULL;
+ m_freem(data->m);
+ ieee80211_free_node(data->ni);
data->m = NULL;
+ data->ni = NULL;
+
SLIST_INSERT_HEAD(&sc->data_pool, data, next);
ring->data[ring->next] = NULL;
+
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
ring->queued--;
ring->next = (ring->next + 1) % RT2860_TX_RING_COUNT;
@@ -1152,7 +1180,8 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid)
sc->sc_tx_timer = 0;
if (ring->queued < RT2860_TX_RING_COUNT)
sc->qfullmsk &= ~(1 << qid);
- rt2860_start(sc);
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ rt2860_start_locked(ifp);
}
/*
@@ -1177,7 +1206,8 @@ static void
rt2860_rx_intr(struct rt2860_softc *sc)
{
struct rt2860_rx_radiotap_header *tap;
- 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 mbuf *m, *m1;
@@ -1204,7 +1234,7 @@ rt2860_rx_intr(struct rt2860_softc *sc)
if (__predict_false(rxd->flags &
htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) {
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1213,14 +1243,14 @@ rt2860_rx_intr(struct rt2860_softc *sc)
/* report MIC failures to net80211 for TKIP */
ic->ic_stats.is_rx_locmicfail++;
ieee80211_michael_mic_failure(ic, 0/* XXX */);
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
#endif
m1 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (__predict_false(m1 == NULL)) {
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1244,7 +1274,7 @@ rt2860_rx_intr(struct rt2860_softc *sc)
}
/* physical address may have changed */
rxd->sdp0 = htole32(physaddr);
- counter_u64_add(ic->ic_ierrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
goto skip;
}
@@ -1259,6 +1289,7 @@ rt2860_rx_intr(struct rt2860_softc *sc)
rxwi = mtod(m, struct rt2860_rxwi *);
/* finalize mbuf */
+ m->m_pkthdr.rcvif = ifp;
m->m_data = (caddr_t)(rxwi + 1);
m->m_pkthdr.len = m->m_len = le16toh(rxwi->len) & 0xfff;
@@ -1368,7 +1399,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc)
#endif
/* check if protection mode has changed */
if ((sc->sc_ic_flags ^ ic->ic_flags) & IEEE80211_F_USEPROT) {
- rt2860_updateprot(sc);
+ rt2860_updateprot(ic);
sc->sc_ic_flags = ic->ic_flags;
}
#endif
@@ -1377,7 +1408,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc)
static void
rt2860_gp_intr(struct rt2860_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211com *ic = sc->sc_ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTFN(2, ("GP timeout state=%d\n", vap->iv_state));
@@ -1449,7 +1480,8 @@ rt2860_intr(void *arg)
static int
rt2860_tx(struct rt2860_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 ieee80211vap *vap = ni->ni_vap;
struct rt2860_tx_ring *ring;
struct rt2860_tx_data *data;
@@ -1693,13 +1725,14 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct rt2860_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2860_softc *sc = ifp->if_softc;
int error;
RAL_LOCK(sc);
/* prevent management frames from being sent if we're not ready */
- if (!(sc->sc_flags & RT2860_RUNNNING)) {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
RAL_UNLOCK(sc);
m_freem(m);
ieee80211_free_node(ni);
@@ -1721,6 +1754,7 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
if (error != 0) {
/* NB: m is reclaimed on tx failure */
ieee80211_free_node(ni);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
}
sc->sc_tx_timer = 5;
RAL_UNLOCK(sc);
@@ -1731,7 +1765,8 @@ static int
rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m,
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = ni->ni_vap;
struct rt2860_tx_ring *ring;
struct rt2860_tx_data *data;
@@ -1938,46 +1973,41 @@ rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m,
return 0;
}
-static int
-rt2860_transmit(struct ieee80211com *ic, struct mbuf *m)
+static void
+rt2860_start(struct ifnet *ifp)
{
- struct rt2860_softc *sc = ic->ic_softc;
- int error;
+ struct rt2860_softc *sc = ifp->if_softc;
RAL_LOCK(sc);
- if ((sc->sc_flags & RT2860_RUNNNING) == 0) {
- RAL_UNLOCK(sc);
- return (ENXIO);
- }
- error = mbufq_enqueue(&sc->sc_snd, m);
- if (error) {
- RAL_UNLOCK(sc);
- return (error);
- }
- rt2860_start(sc);
+ rt2860_start_locked(ifp);
RAL_UNLOCK(sc);
-
- return (0);
}
static void
-rt2860_start(struct rt2860_softc *sc)
+rt2860_start_locked(struct ifnet *ifp)
{
+ struct rt2860_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
RAL_LOCK_ASSERT(sc);
- if ((sc->sc_flags & RT2860_RUNNNING) == 0)
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
+ (ifp->if_drv_flags & IFF_DRV_OACTIVE))
return;
- while (!SLIST_EMPTY(&sc->data_pool) && sc->qfullmsk == 0 &&
- (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
+ for (;;) {
+ if (SLIST_EMPTY(&sc->data_pool) || sc->qfullmsk != 0) {
+ ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+ break;
+ }
+ IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
+ if (m == NULL)
+ break;
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (rt2860_tx(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);
continue;
}
sc->sc_tx_timer = 5;
@@ -1988,42 +2018,61 @@ static void
rt2860_watchdog(void *arg)
{
struct rt2860_softc *sc = arg;
+ struct ifnet *ifp = sc->sc_ifp;
RAL_LOCK_ASSERT(sc);
- KASSERT(sc->sc_flags & RT2860_RUNNNING, ("not running"));
+ KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
if (sc->sc_invalid) /* card ejected */
return;
if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) {
- device_printf(sc->sc_dev, "device timeout\n");
+ if_printf(ifp, "device timeout\n");
rt2860_stop_locked(sc);
rt2860_init_locked(sc);
- counter_u64_add(sc->sc_ic.ic_oerrors, 1);
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return;
}
callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc);
}
-static void
-rt2860_parent(struct ieee80211com *ic)
+static int
+rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
- struct rt2860_softc *sc = ic->ic_softc;
- int startall = 0;
+ struct rt2860_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
+ struct ifreq *ifr = (struct ifreq *)data;
+ int error = 0, startall = 0;
- RAL_LOCK(sc);
- if (ic->ic_nrunning> 0) {
- if (!(sc->sc_flags & RT2860_RUNNNING)) {
- rt2860_init_locked(sc);
- startall = 1;
- } else
- rt2860_update_promisc(ic);
- } else if (sc->sc_flags & RT2860_RUNNNING)
- rt2860_stop_locked(sc);
- RAL_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ RAL_LOCK(sc);
+ if (ifp->if_flags & IFF_UP) {
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ rt2860_init_locked(sc);
+ startall = 1;
+ } else
+ rt2860_update_promisc(ic);
+ } else {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ rt2860_stop_locked(sc);
+ }
+ RAL_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
+ break;
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
+ break;
+ case SIOCSIFADDR:
+ error = ether_ioctl(ifp, cmd, data);
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ return error;
}
/*
@@ -2246,7 +2295,8 @@ rt2860_enable_mrr(struct rt2860_softc *sc)
static void
rt2860_set_txpreamble(struct rt2860_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
tmp = RAL_READ(sc, RT2860_AUTO_RSP_CFG);
@@ -2261,7 +2311,8 @@ rt2860_set_basicrates(struct rt2860_softc *sc,
const struct ieee80211_rateset *rs)
{
#define RV(r) ((r) & IEEE80211_RATE_VAL)
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t mask = 0;
uint8_t rate;
int i;
@@ -2282,7 +2333,8 @@ rt2860_set_basicrates(struct rt2860_softc *sc,
static void
rt2860_scan_start(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2860_softc *sc = ifp->if_softc;
uint32_t tmp;
tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG);
@@ -2295,7 +2347,8 @@ rt2860_scan_start(struct ieee80211com *ic)
static void
rt2860_scan_end(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2860_softc *sc = ifp->if_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
if (vap->iv_state == IEEE80211_S_RUN) {
@@ -2307,7 +2360,8 @@ rt2860_scan_end(struct ieee80211com *ic)
static void
rt2860_set_channel(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ic->ic_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct rt2860_softc *sc = ifp->if_softc;
RAL_LOCK(sc);
rt2860_switch_chan(sc, ic->ic_curchan);
@@ -3059,9 +3113,10 @@ rt2860_updateslot(struct ieee80211com *ic)
}
static void
-rt2860_updateprot(struct rt2860_softc *sc)
+rt2860_updateprot(struct ifnet *ifp)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct rt2860_softc *sc = ifp->if_softc;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL;
@@ -3090,7 +3145,7 @@ rt2860_update_promisc(struct ieee80211com *ic)
tmp = RAL_READ(sc, RT2860_RX_FILTR_CFG);
tmp &= ~RT2860_DROP_NOT_MYBSS;
- if (ic->ic_promisc == 0)
+ if (!(ic->ic_ifp->if_flags & IFF_PROMISC))
tmp |= RT2860_DROP_NOT_MYBSS;
RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp);
}
@@ -3098,7 +3153,7 @@ rt2860_update_promisc(struct ieee80211com *ic)
static int
rt2860_updateedca(struct ieee80211com *ic)
{
- struct rt2860_softc *sc = ic->ic_softc;
+ struct rt2860_softc *sc = ic->ic_ifp->if_softc;
const struct wmeParams *wmep;
int aci;
@@ -3270,7 +3325,8 @@ rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
static int8_t
rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211_channel *c = ic->ic_curchan;
int delta;
@@ -3745,7 +3801,8 @@ rt5390_bbp_init(struct rt2860_softc *sc)
static int
rt2860_txrx_enable(struct rt2860_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
uint32_t tmp;
int ntries;
@@ -3791,21 +3848,22 @@ static void
rt2860_init(void *arg)
{
struct rt2860_softc *sc = arg;
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
RAL_LOCK(sc);
rt2860_init_locked(sc);
RAL_UNLOCK(sc);
- if (sc->sc_flags & RT2860_RUNNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
ieee80211_start_all(ic);
}
static void
rt2860_init_locked(struct rt2860_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, qid, ridx, ntries, error;
@@ -3841,7 +3899,7 @@ rt2860_init_locked(struct rt2860_softc *sc)
return;
}
- rt2860_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
+ rt2860_set_macaddr(sc, IF_LLADDR(ifp));
/* init Tx power for all Tx rates (from EEPROM) */
for (ridx = 0; ridx < 5; ridx++) {
@@ -4038,7 +4096,7 @@ rt2860_init_locked(struct rt2860_softc *sc)
RAL_WRITE(sc, RT2860_TX_RTS_CFG, tmp);
/* setup initial protection mode */
- rt2860_updateprot(sc);
+ rt2860_updateprot(ifp);
/* turn radio LED on */
rt2860_set_leds(sc, RT2860_LED_RADIO);
@@ -4057,7 +4115,8 @@ rt2860_init_locked(struct rt2860_softc *sc)
if (sc->sc_flags & RT2860_ADVANCED_PS)
rt2860_mcu_cmd(sc, RT2860_MCU_CMD_PSLEVEL, sc->pslevel, 0);
- sc->sc_flags |= RT2860_RUNNNING;
+ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ ifp->if_drv_flags |= IFF_DRV_RUNNING;
callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc);
}
@@ -4075,15 +4134,16 @@ rt2860_stop(void *arg)
static void
rt2860_stop_locked(struct rt2860_softc *sc)
{
+ struct ifnet *ifp = sc->sc_ifp;
uint32_t tmp;
int qid;
- if (sc->sc_flags & RT2860_RUNNNING)
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
rt2860_set_leds(sc, 0); /* turn all LEDs off */
callout_stop(&sc->watchdog_ch);
sc->sc_tx_timer = 0;
- sc->sc_flags &= ~RT2860_RUNNNING;
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
/* disable interrupts */
RAL_WRITE(sc, RT2860_INT_MASK, 0);
@@ -4234,7 +4294,8 @@ rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux)
static void
rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
u_int chan, group;
chan = ieee80211_chan2ieee(ic, c);
@@ -4303,7 +4364,8 @@ rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap)
static void
rt2860_enable_tsf_sync(struct rt2860_softc *sc)
{
- struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = sc->sc_ifp;
+ struct ieee80211com *ic = ifp->if_l2com;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint32_t tmp;
diff --git a/sys/dev/ral/rt2860var.h b/sys/dev/ral/rt2860var.h
index 3779e5beb1d1..28a3d59b8263 100644
--- a/sys/dev/ral/rt2860var.h
+++ b/sys/dev/ral/rt2860var.h
@@ -115,13 +115,13 @@ struct rt2860_vap {
#define RT2860_VAP(vap) ((struct rt2860_vap *)(vap))
struct rt2860_softc {
- struct ieee80211com sc_ic;
- struct mbufq sc_snd;
- struct mtx sc_mtx;
+ struct ifnet *sc_ifp;
device_t sc_dev;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
+ struct mtx sc_mtx;
+
struct callout watchdog_ch;
int sc_invalid;
@@ -139,7 +139,6 @@ struct rt2860_softc {
#define RT2860_ENABLED (1 << 0)
#define RT2860_ADVANCED_PS (1 << 1)
#define RT2860_PCIE (1 << 2)
-#define RT2860_RUNNNING (1 << 3)
struct ieee80211_node *wcid2ni[RT2860_WCID_MAX];