Page MenuHomeFreeBSD

D2655.id5707.diff
No OneTemporary

D2655.id5707.diff

Index: etc/network.subr
===================================================================
--- etc/network.subr
+++ etc/network.subr
@@ -1249,6 +1249,38 @@
fi
}
+# wlan_up
+# Create IEEE802.3 interfaces.
+#
+wlan_up()
+{
+ local _list _iflist wlan parent ifn
+ _list=
+ _iflist=$*
+
+ for wlan in `set | egrep ^wlans_[a-z]+[0-9]+=[a-z]+[0-9]+`; do
+ # Parse wlans_$parent=$ifn
+ wlan=`echo $wlan | sed -E 's/wlans_([a-z]+[0-9]+)=([a-z]+[0-9]+)/\1:\2/'`
+ OIFS=$IFS; IFS=:; set -- $wlan; parent=$1; ifn=$2; IFS=$OIFS
+ case $_iflist in
+ ""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;;
+ *) continue ;;
+ esac
+ # Skip if ${ifn} already exists.
+ if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
+ continue
+ fi
+ ${IFCONFIG_CMD} ${ifn} create wlandev ${parent}
+ if [ $? -eq 0 ]; then
+ _list="$_list $ifn"
+ fi
+ done
+ if [ -n "${_list# }" ]; then
+ echo "Created wlan interfaces: ${_list# }."
+ fi
+ debug "Wlans: ${_list# }"
+}
+
# clone_up
# Create cloneable interfaces.
#
Index: etc/rc.d/netif
===================================================================
--- etc/rc.d/netif
+++ etc/rc.d/netif
@@ -37,6 +37,7 @@
rcvar="${name}_enable"
start_cmd="netif_start"
stop_cmd="netif_stop"
+wlanup_cmd="wlan_up"
cloneup_cmd="clone_up"
clonedown_cmd="clone_down"
clear_cmd="doclear"
@@ -65,6 +66,9 @@
trap : 2
fi
+ # Create IEEE802.3 interface
+ wlan_up $cmdifn
+
# Create cloned interfaces
clone_up $cmdifn
Index: sys/dev/iwn/if_iwn.c
===================================================================
--- sys/dev/iwn/if_iwn.c
+++ sys/dev/iwn/if_iwn.c
@@ -234,10 +234,11 @@
const struct ieee80211_bpf_params *params);
static int iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
-static void iwn_start(struct ifnet *);
-static void iwn_start_locked(struct ifnet *);
+static int iwn_transmit(struct ieee80211com *, struct mbuf *);
+static void iwn_start_locked(struct iwn_softc *);
static void iwn_watchdog(void *);
-static int iwn_ioctl(struct ifnet *, u_long, caddr_t);
+static int iwn_ioctl(struct ieee80211com *, u_long , char *);
+static void iwn_parent(struct ieee80211com *);
static int iwn_cmd(struct iwn_softc *, int, const void *, int, int);
static int iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
int);
@@ -335,7 +336,7 @@
static void iwn_radio_off(void *, int);
static void iwn_panicked(void *, int);
static void iwn_init_locked(struct iwn_softc *);
-static void iwn_init(void *);
+static void iwn_init(struct iwn_softc *);
static void iwn_stop_locked(struct iwn_softc *);
static void iwn_stop(struct iwn_softc *);
static void iwn_scan_start(struct ieee80211com *);
@@ -405,9 +406,7 @@
{
struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
struct ieee80211com *ic;
- struct ifnet *ifp;
int i, error, rid;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
sc->sc_dev = dev;
@@ -463,6 +462,7 @@
}
IWN_LOCK_INIT(sc);
+ mbufq_init(&sc->sc_snd, ifqmaxlen);
/* Read hardware revision and attach. */
sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> IWN_HW_REV_TYPE_SHIFT)
@@ -548,14 +548,7 @@
/* Clear pending interrupts. */
IWN_WRITE(sc, IWN_INT, 0xffffffff);
- ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
- if (ifp == NULL) {
- device_printf(dev, "can not allocate ifnet structure\n");
- goto fail;
- }
-
- ic = ifp->if_l2com;
- ic->ic_ifp = ifp;
+ ic = &sc->sc_ic;
ic->ic_softc = sc;
ic->ic_name = device_get_nameunit(dev);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
@@ -578,7 +571,7 @@
;
/* Read MAC address, channels, etc from EEPROM. */
- if ((error = iwn_read_eeprom(sc, macaddr)) != 0) {
+ if ((error = iwn_read_eeprom(sc, ic->ic_macaddr)) != 0) {
device_printf(dev, "could not read EEPROM, error %d\n",
error);
goto fail;
@@ -596,7 +589,7 @@
if (bootverbose) {
device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n",
sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
- macaddr, ":");
+ ic->ic_macaddr, ":");
}
if (sc->sc_flags & IWN_FLAG_HAS_11N) {
@@ -637,19 +630,12 @@
;
}
- if_initname(ifp, device_get_name(dev), device_get_unit(dev));
- ifp->if_softc = sc;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = iwn_init;
- ifp->if_ioctl = iwn_ioctl;
- ifp->if_start = iwn_start;
- IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
- ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
- IFQ_SET_READY(&ifp->if_snd);
-
- ieee80211_ifattach(ic, macaddr);
+ ieee80211_ifattach(ic);
ic->ic_vap_create = iwn_vap_create;
+ ic->ic_ioctl = iwn_ioctl;
+ ic->ic_parent = iwn_parent;
ic->ic_vap_delete = iwn_vap_delete;
+ ic->ic_transmit = iwn_transmit;
ic->ic_raw_xmit = iwn_raw_xmit;
ic->ic_node_alloc = iwn_node_alloc;
sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
@@ -1287,10 +1273,9 @@
static void
iwn_radiotap_attach(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
- ieee80211_radiotap_attach(ic,
+ ieee80211_radiotap_attach(&sc->sc_ic,
&sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
IWN_TX_RADIOTAP_PRESENT,
&sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
@@ -1320,21 +1305,14 @@
struct iwn_softc *sc = ic->ic_softc;
struct iwn_vap *ivp;
struct ieee80211vap *vap;
- uint8_t mac1[IEEE80211_ADDR_LEN];
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
return NULL;
- IEEE80211_ADDR_COPY(mac1, mac);
-
- ivp = (struct iwn_vap *) malloc(sizeof(struct iwn_vap),
- M_80211_VAP, M_NOWAIT | M_ZERO);
- if (ivp == NULL)
- return NULL;
+ ivp = malloc(sizeof(struct iwn_vap), M_80211_VAP, M_WAITOK | M_ZERO);
vap = &ivp->iv_vap;
- ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac1);
+ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
ivp->ctx = IWN_RXON_BSS_CTX;
- IEEE80211_ADDR_COPY(ivp->macaddr, mac1);
vap->iv_bmissthreshold = 10; /* override default */
/* Override with driver methods. */
ivp->iv_newstate = vap->iv_newstate;
@@ -1343,7 +1321,8 @@
ieee80211_ratectl_init(vap);
/* Complete setup. */
- ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status);
+ ieee80211_vap_attach(vap, iwn_media_change, ieee80211_media_status,
+ mac);
ic->ic_opmode = opmode;
return vap;
}
@@ -1362,19 +1341,14 @@
iwn_detach(device_t dev)
{
struct iwn_softc *sc = device_get_softc(dev);
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic;
int qid;
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
- if (ifp != NULL) {
- ic = ifp->if_l2com;
-
- ieee80211_draintask(ic, &sc->sc_reinit_task);
- ieee80211_draintask(ic, &sc->sc_radioon_task);
- ieee80211_draintask(ic, &sc->sc_radiooff_task);
-
+ if (sc->sc_ic.ic_softc != NULL) {
+ ieee80211_draintask(&sc->sc_ic, &sc->sc_reinit_task);
+ ieee80211_draintask(&sc->sc_ic, &sc->sc_radioon_task);
+ ieee80211_draintask(&sc->sc_ic, &sc->sc_radiooff_task);
iwn_stop(sc);
taskqueue_drain_all(sc->sc_tq);
@@ -1382,7 +1356,7 @@
callout_drain(&sc->watchdog_to);
callout_drain(&sc->calib_to);
- ieee80211_ifdetach(ic);
+ ieee80211_ifdetach(&sc->sc_ic);
}
/* Uninstall interrupt handler. */
@@ -1407,9 +1381,6 @@
bus_release_resource(dev, SYS_RES_MEMORY,
rman_get_rid(sc->mem), sc->mem);
- if (ifp != NULL)
- if_free(ifp);
-
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n", __func__);
IWN_LOCK_DESTROY(sc);
return 0;
@@ -1428,9 +1399,8 @@
iwn_suspend(device_t dev)
{
struct iwn_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
- ieee80211_suspend_all(ic);
+ ieee80211_suspend_all(&sc->sc_ic);
return 0;
}
@@ -1438,12 +1408,11 @@
iwn_resume(device_t dev)
{
struct iwn_softc *sc = device_get_softc(dev);
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
/* Clear device-specific "PCI retry timeout" register (41h). */
pci_write_config(dev, 0x41, 0, 1);
- ieee80211_resume_all(ic);
+ ieee80211_resume_all(&sc->sc_ic);
return 0;
}
@@ -2352,8 +2321,7 @@
static void
iwn_read_eeprom_band(struct iwn_softc *sc, int n)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
const struct iwn_chan_band *band = &iwn_bands[n];
struct ieee80211_channel *c;
@@ -2412,8 +2380,7 @@
static void
iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
const struct iwn_chan_band *band = &iwn_bands[n];
struct ieee80211_channel *c, *cent, *extc;
@@ -2481,8 +2448,7 @@
static void
iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n],
iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan));
@@ -2550,8 +2516,7 @@
iwn_read_eeprom_enhinfo(struct iwn_softc *sc)
{
struct iwn_eeprom_enhinfo enhinfo[35];
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_channel *c;
uint16_t val, base;
int8_t maxpwr;
@@ -2922,8 +2887,7 @@
struct iwn_rx_data *data)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_rx_ring *ring = &sc->rxq;
struct ieee80211_frame *wh;
struct ieee80211_node *ni;
@@ -2970,14 +2934,14 @@
if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n",
__func__, flags);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
/* Discard frames that are too short. */
if (len < sizeof (struct ieee80211_frame_ack)) {
DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
__func__, len);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -2985,7 +2949,7 @@
if (m1 == NULL) {
DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
__func__);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
bus_dmamap_unload(ring->data_dmat, data->map);
@@ -3008,7 +2972,7 @@
ring->desc[ring->cur] = htole32(paddr >> 8);
bus_dmamap_sync(ring->data_dmat, ring->desc_dma.map,
BUS_DMASYNC_PREWRITE);
- if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
+ counter_u64_add(ic->ic_ierrors, 1);
return;
}
@@ -3020,7 +2984,6 @@
BUS_DMASYNC_PREWRITE);
/* Finalize mbuf. */
- m->m_pkthdr.rcvif = ifp;
m->m_data = head;
m->m_pkthdr.len = m->m_len = len;
@@ -3088,7 +3051,6 @@
struct iwn_rx_data *data)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
struct iwn_node *wn;
struct ieee80211_node *ni;
struct iwn_compressed_ba *ba = (struct iwn_compressed_ba *)(desc + 1);
@@ -3169,12 +3131,10 @@
bitmap = (le64toh(ba->bitmap) >> shift) & wn->agg[tid].bitmap;
for (i = 0; bitmap; i++) {
if ((bitmap & 1) == 0) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
tx_err ++;
ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
} else {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
tx_ok ++;
ieee80211_ratectl_tx_complete(ni->ni_vap, ni,
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
@@ -3320,8 +3280,7 @@
struct iwn_rx_data *data)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
struct iwn_calib_state *calib = &sc->calib;
struct iwn_stats *stats = (struct iwn_stats *)(desc + 1);
@@ -3494,7 +3453,6 @@
iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt,
uint8_t status)
{
- struct ifnet *ifp = sc->sc_ifp;
struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf];
struct iwn_tx_data *data = &ring->data[desc->idx];
struct mbuf *m;
@@ -3515,15 +3473,12 @@
/*
* Update rate control statistics for the node.
*/
- if (status & IWN_TX_FAIL) {
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
+ if (status & IWN_TX_FAIL)
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL);
- } else {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ else
ieee80211_ratectl_tx_complete(vap, ni,
IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL);
- }
/*
* Channels marked for "radar" require traffic to be received
@@ -3549,11 +3504,8 @@
sc->sc_tx_timer = 0;
if (--ring->queued < IWN_TX_RING_LOMARK) {
sc->qfullmsk &= ~(1 << ring->qid);
- if (sc->qfullmsk == 0 &&
- (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- iwn_start_locked(ifp);
- }
+ if (sc->qfullmsk == 0)
+ iwn_start_locked(sc);
}
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
@@ -3598,7 +3550,6 @@
int ackfailcnt, void *stat)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
struct iwn_tx_ring *ring = &sc->txq[qid];
struct iwn_tx_data *data;
struct mbuf *m;
@@ -3737,11 +3688,8 @@
sc->sc_tx_timer = 0;
if (ring->queued < IWN_TX_RING_LOMARK) {
sc->qfullmsk &= ~(1 << ring->qid);
- if (sc->qfullmsk == 0 &&
- (ifp->if_drv_flags & IFF_DRV_OACTIVE)) {
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- iwn_start_locked(ifp);
- }
+ if (sc->qfullmsk == 0)
+ iwn_start_locked(sc);
}
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
@@ -3755,8 +3703,7 @@
iwn_notif_intr(struct iwn_softc *sc)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
uint16_t hw;
@@ -3950,8 +3897,7 @@
static void
iwn_rftoggle_intr(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t tmp = IWN_READ(sc, IWN_GP_CNTRL);
IWN_LOCK_ASSERT(sc);
@@ -4030,7 +3976,6 @@
iwn_intr(void *arg)
{
struct iwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
uint32_t r1, r2, tmp;
IWN_LOCK(sc);
@@ -4123,7 +4068,7 @@
done:
/* Re-enable interrupts. */
- if (ifp->if_flags & IFF_UP)
+ if (sc->sc_flags & IWN_FLAG_RUNNING)
IWN_WRITE(sc, IWN_INT_MASK, sc->int_mask);
IWN_UNLOCK(sc);
@@ -4607,9 +4552,7 @@
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
{
struct iwn_ops *ops = &sc->ops;
-// struct ifnet *ifp = sc->sc_ifp;
struct ieee80211vap *vap = ni->ni_vap;
-// struct ieee80211com *ic = ifp->if_l2com;
struct iwn_tx_cmd *cmd;
struct iwn_cmd_data *tx;
struct ieee80211_frame *wh;
@@ -4805,13 +4748,12 @@
const struct ieee80211_bpf_params *params)
{
struct ieee80211com *ic = ni->ni_ic;
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
int error = 0;
DPRINTF(sc, IWN_DEBUG_XMIT | IWN_DEBUG_TRACE, "->%s begin\n", __func__);
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) {
ieee80211_free_node(ni);
m_freem(m);
return ENETDOWN;
@@ -4833,8 +4775,8 @@
}
if (error != 0) {
/* NB: m is reclaimed on tx failure */
+ if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
ieee80211_free_node(ni);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
} else
sc->sc_tx_timer = 5;
@@ -4845,47 +4787,48 @@
return error;
}
-static void
-iwn_start(struct ifnet *ifp)
+static int
+iwn_transmit(struct ieee80211com *ic, struct mbuf *m)
{
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc;
+ int error;
+
+ sc = ic->ic_softc;
IWN_LOCK(sc);
- iwn_start_locked(ifp);
+ if ((sc->sc_flags & IWN_FLAG_RUNNING) == 0) {
+ IWN_UNLOCK(sc);
+ return (ENXIO);
+ }
+ error = mbufq_enqueue(&sc->sc_snd, m);
+ if (error) {
+ IWN_UNLOCK(sc);
+ return (error);
+ }
+ iwn_start_locked(sc);
IWN_UNLOCK(sc);
+ return (0);
}
static void
-iwn_start_locked(struct ifnet *ifp)
+iwn_start_locked(struct iwn_softc *sc)
{
- struct iwn_softc *sc = ifp->if_softc;
struct ieee80211_node *ni;
struct mbuf *m;
IWN_LOCK_ASSERT(sc);
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: called\n", __func__);
-
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
- (ifp->if_drv_flags & IFF_DRV_OACTIVE))
- return;
-
- for (;;) {
- if (sc->qfullmsk != 0) {
- ifp->if_drv_flags |= IFF_DRV_OACTIVE;
- break;
- }
- IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
+ while (sc->qfullmsk == 0 &&
+ (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
if (iwn_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);
} else
sc->sc_tx_timer = 5;
}
-
DPRINTF(sc, IWN_DEBUG_XMIT, "%s: done\n", __func__);
}
@@ -4893,12 +4836,11 @@
iwn_watchdog(void *arg)
{
struct iwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
IWN_LOCK_ASSERT(sc);
- KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running"));
+ KASSERT(sc->sc_flags & IWN_FLAG_RUNNING, ("not running"));
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -4913,41 +4855,13 @@
}
static int
-iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+iwn_ioctl(struct ieee80211com *ic, u_long cmd, char *data)
{
- struct iwn_softc *sc = ifp->if_softc;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ struct iwn_softc *sc = ic->ic_softc;
struct ifreq *ifr = (struct ifreq *) data;
- int error = 0, startall = 0, stop = 0;
-
+ int error = 0;
+
switch (cmd) {
- case SIOCGIFADDR:
- error = ether_ioctl(ifp, cmd, data);
- break;
- case SIOCSIFFLAGS:
- IWN_LOCK(sc);
- if (ifp->if_flags & IFF_UP) {
- if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
- iwn_init_locked(sc);
- if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
- startall = 1;
- else
- stop = 1;
- }
- } else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- iwn_stop_locked(sc);
- }
- IWN_UNLOCK(sc);
- if (startall)
- ieee80211_start_all(ic);
- else if (vap != NULL && stop)
- ieee80211_stop(vap);
- break;
- case SIOCGIFMEDIA:
- error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
- break;
case SIOCGIWNSTATS:
IWN_LOCK(sc);
/* XXX validate permissions/memory/etc? */
@@ -4961,10 +4875,35 @@
IWN_UNLOCK(sc);
break;
default:
- error = EINVAL;
+ error = ENOTTY;
break;
}
- return error;
+ return (error);
+}
+
+static void
+iwn_parent(struct ieee80211com *ic)
+{
+ struct iwn_softc *sc = ic->ic_softc;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ int startall = 0, stop = 0;
+
+ IWN_LOCK(sc);
+ if (ic->ic_nrunning > 0) {
+ if (!(sc->sc_flags & IWN_FLAG_RUNNING)) {
+ iwn_init_locked(sc);
+ if (IWN_READ(sc, IWN_GP_CNTRL) & IWN_GP_CNTRL_RFKILL)
+ startall = 1;
+ else
+ stop = 1;
+ }
+ } else if (sc->sc_flags & IWN_FLAG_RUNNING)
+ iwn_stop_locked(sc);
+ IWN_UNLOCK(sc);
+ if (startall)
+ ieee80211_start_all(ic);
+ else if (vap != NULL && stop)
+ ieee80211_stop(vap);
}
/*
@@ -5198,8 +5137,7 @@
iwn_add_broadcast_node(struct iwn_softc *sc, int async)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct iwn_node_info node;
struct iwn_cmd_link_quality linkq;
uint8_t txant;
@@ -5210,7 +5148,7 @@
sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX];
memset(&node, 0, sizeof node);
- IEEE80211_ADDR_COPY(node.macaddr, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(node.macaddr, ieee80211broadcastaddr);
node.id = sc->broadcast_id;
DPRINTF(sc, IWN_DEBUG_RESET, "%s: adding broadcast node\n", __func__);
if ((error = ops->add_node(sc, &node, async)) != 0)
@@ -5359,8 +5297,7 @@
static void
iwn4965_power_calibration(struct iwn_softc *sc, int temp)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -5730,8 +5667,7 @@
{
struct iwn_ops *ops = &sc->ops;
struct iwn_calib_state *calib = &sc->calib;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
uint32_t val;
int i;
@@ -6365,8 +6301,9 @@
iwn_config(struct iwn_softc *sc)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
+ const uint8_t *macaddr;
uint32_t txmask;
uint16_t rxchain;
int error;
@@ -6448,8 +6385,9 @@
/* Set mode, channel, RX filter and enable RX. */
sc->rxon = &sc->rx_on[IWN_RXON_BSS_CTX];
memset(sc->rxon, 0, sizeof (struct iwn_rxon));
- IEEE80211_ADDR_COPY(sc->rxon->myaddr, IF_LLADDR(ifp));
- IEEE80211_ADDR_COPY(sc->rxon->wlap, IF_LLADDR(ifp));
+ macaddr = vap ? vap->iv_myaddr : ic->ic_macaddr;
+ IEEE80211_ADDR_COPY(sc->rxon->myaddr, macaddr);
+ IEEE80211_ADDR_COPY(sc->rxon->wlap, macaddr);
sc->rxon->chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
sc->rxon->flags = htole32(IWN_RXON_TSF | IWN_RXON_CTS_TO_SELF);
if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
@@ -6557,7 +6495,7 @@
static uint16_t
iwn_limit_dwell(struct iwn_softc *sc, uint16_t dwell_time)
{
- struct ieee80211com *ic = sc->sc_ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = NULL;
int bintval = 0;
@@ -6605,8 +6543,7 @@
iwn_scan(struct iwn_softc *sc, struct ieee80211vap *vap,
struct ieee80211_scan_state *ss, struct ieee80211_channel *c)
{
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni = vap->iv_bss;
struct iwn_scan_hdr *hdr;
struct iwn_cmd_data *tx;
@@ -6744,9 +6681,9 @@
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
IEEE80211_FC0_SUBTYPE_PROBE_REQ;
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
- IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
- IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(ifp));
- IEEE80211_ADDR_COPY(wh->i_addr3, ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr1, vap->iv_ifp->if_broadcastaddr);
+ IEEE80211_ADDR_COPY(wh->i_addr2, IF_LLADDR(vap->iv_ifp));
+ IEEE80211_ADDR_COPY(wh->i_addr3, vap->iv_ifp->if_broadcastaddr);
*(uint16_t *)&wh->i_dur[0] = 0; /* filled by HW */
*(uint16_t *)&wh->i_seq[0] = 0; /* filled by HW */
@@ -6865,8 +6802,7 @@
iwn_auth(struct iwn_softc *sc, struct ieee80211vap *vap)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni = vap->iv_bss;
int error;
@@ -6934,8 +6870,7 @@
iwn_run(struct iwn_softc *sc, struct ieee80211vap *vap)
{
struct iwn_ops *ops = &sc->ops;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni = vap->iv_bss;
struct iwn_node_info node;
uint32_t htflags = 0;
@@ -8521,8 +8456,7 @@
iwn_radio_on(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -8537,8 +8471,7 @@
iwn_radio_off(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -8558,8 +8491,7 @@
iwn_panicked(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
int error;
@@ -8587,7 +8519,7 @@
}
/* Only run start once the NIC is in a useful state, like associated */
- iwn_start_locked(sc->sc_ifp);
+ iwn_start_locked(sc);
IWN_UNLOCK(sc);
}
@@ -8595,13 +8527,14 @@
static void
iwn_init_locked(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
int error;
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
IWN_LOCK_ASSERT(sc);
+ sc->sc_flags |= IWN_FLAG_RUNNING;
+
if ((error = iwn_hw_prepare(sc)) != 0) {
device_printf(sc->sc_dev, "%s: hardware not ready, error %d\n",
__func__, error);
@@ -8649,38 +8582,33 @@
goto fail;
}
- ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
-
callout_reset(&sc->watchdog_to, hz, iwn_watchdog, sc);
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
return;
-fail: iwn_stop_locked(sc);
+fail:
+ sc->sc_flags &= ~IWN_FLAG_RUNNING;
+ iwn_stop_locked(sc);
DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end in error\n",__func__);
}
static void
-iwn_init(void *arg)
+iwn_init(struct iwn_softc *sc)
{
- struct iwn_softc *sc = arg;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
IWN_LOCK(sc);
iwn_init_locked(sc);
IWN_UNLOCK(sc);
- if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- ieee80211_start_all(ic);
+ if (sc->sc_flags & IWN_FLAG_RUNNING)
+ ieee80211_start_all(&sc->sc_ic);
}
static void
iwn_stop_locked(struct iwn_softc *sc)
{
- struct ifnet *ifp = sc->sc_ifp;
IWN_LOCK_ASSERT(sc);
@@ -8688,7 +8616,7 @@
sc->sc_tx_timer = 0;
callout_stop(&sc->watchdog_to);
callout_stop(&sc->calib_to);
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ sc->sc_flags &= ~IWN_FLAG_RUNNING;
/* Power OFF hardware. */
iwn_hw_stop(sc);
@@ -8708,8 +8636,7 @@
static void
iwn_scan_start(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
IWN_LOCK(sc);
/* make the link LED blink while we're scanning */
@@ -8723,8 +8650,7 @@
static void
iwn_scan_end(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
IWN_LOCK(sc);
@@ -8742,8 +8668,7 @@
iwn_set_channel(struct ieee80211com *ic)
{
const struct ieee80211_channel *c = ic->ic_curchan;
- struct ifnet *ifp = ic->ic_ifp;
- struct iwn_softc *sc = ifp->if_softc;
+ struct iwn_softc *sc = ic->ic_softc;
int error;
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
@@ -8800,8 +8725,7 @@
iwn_hw_reset(void *arg0, int pending)
{
struct iwn_softc *sc = arg0;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
+ struct ieee80211com *ic = &sc->sc_ic;
DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__);
Index: sys/dev/iwn/if_iwnvar.h
===================================================================
--- sys/dev/iwn/if_iwnvar.h
+++ sys/dev/iwn/if_iwnvar.h
@@ -228,18 +228,16 @@
enum ieee80211_state, int);
int ctx;
int beacon_int;
- uint8_t macaddr[IEEE80211_ADDR_LEN];
};
#define IWN_VAP(_vap) ((struct iwn_vap *)(_vap))
struct iwn_softc {
device_t sc_dev;
-
- struct ifnet *sc_ifp;
int sc_debug;
-
struct mtx sc_mtx;
+ struct ieee80211com sc_ic;
+ struct mbufq sc_snd;
u_int sc_flags;
#define IWN_FLAG_HAS_OTPROM (1 << 1)
@@ -251,6 +249,7 @@
#define IWN_FLAG_ADV_BTCOEX (1 << 8)
#define IWN_FLAG_PAN_SUPPORT (1 << 9)
#define IWN_FLAG_BTCOEX (1 << 10)
+#define IWN_FLAG_RUNNING (1 << 11)
uint8_t hw_type;
/* subdevice_id used to adjust configuration */
@@ -319,7 +318,6 @@
struct iwn_calib_state calib;
int last_calib_ticks;
struct callout watchdog_to;
- struct callout ct_kill_exit_to;
struct iwn_fw_info fw;
struct iwn_calib_info calibcmd[IWN5000_PHY_CALIB_MAX_RESULT];
uint32_t errptr;
Index: sys/net80211/ieee80211.c
===================================================================
--- sys/net80211/ieee80211.c
+++ sys/net80211/ieee80211.c
@@ -91,8 +91,6 @@
static int ieee80211_media_setup(struct ieee80211com *ic,
struct ifmedia *media, int caps, int addsta,
ifm_change_cb_t media_change, ifm_stat_cb_t media_stat);
-static void ieee80211com_media_status(struct ifnet *, struct ifmediareq *);
-static int ieee80211com_media_change(struct ifnet *);
static int media_status(enum ieee80211_opmode,
const struct ieee80211_channel *);
static uint64_t ieee80211_get_counter(struct ifnet *, ift_counter);
@@ -121,7 +119,7 @@
* all available channels as active, and pick
* a default channel if not already specified.
*/
-static void
+void
ieee80211_chan_init(struct ieee80211com *ic)
{
#define DEFAULTRATES(m, def) do { \
@@ -238,29 +236,6 @@
ic_printf(ic, "need promiscuous mode update callback\n");
}
-static int
-null_transmit(struct ifnet *ifp, struct mbuf *m)
-{
- m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return EACCES; /* XXX EIO/EPERM? */
-}
-
-static int
-null_output(struct ifnet *ifp, struct mbuf *m,
- const struct sockaddr *dst, struct route *ro)
-{
- if_printf(ifp, "discard raw packet\n");
- return null_transmit(ifp, m);
-}
-
-static void
-null_input(struct ifnet *ifp, struct mbuf *m)
-{
- if_printf(ifp, "if_input should not be called\n");
- m_freem(m);
-}
-
static void
null_update_chw(struct ieee80211com *ic)
{
@@ -268,6 +243,8 @@
ic_printf(ic, "%s: need callback\n", __func__);
}
+static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head);
+
int
ic_printf(struct ieee80211com *ic, const char * fmt, ...)
{
@@ -286,14 +263,8 @@
* the driver on attach to prior to creating any vap's.
*/
void
-ieee80211_ifattach(struct ieee80211com *ic,
- const uint8_t macaddr[IEEE80211_ADDR_LEN])
+ieee80211_ifattach(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct sockaddr_dl *sdl;
- struct ifaddr *ifa;
-
- KASSERT(ifp->if_type == IFT_IEEE80211, ("if_type %d", ifp->if_type));
IEEE80211_LOCK_INIT(ic, ic->ic_name);
IEEE80211_TX_LOCK_INIT(ic, ic->ic_name);
@@ -311,7 +282,7 @@
* available channels as active, and pick a default
* channel if not already specified.
*/
- ieee80211_media_init(ic);
+ ieee80211_chan_init(ic);
ic->ic_update_mcast = null_update_mcast;
ic->ic_update_promisc = null_update_promisc;
@@ -336,28 +307,7 @@
ieee80211_sysctl_attach(ic);
- ifp->if_addrlen = IEEE80211_ADDR_LEN;
- ifp->if_hdrlen = 0;
-
- CURVNET_SET(vnet0);
-
- if_attach(ifp);
-
- ifp->if_mtu = IEEE80211_MTU_MAX;
- ifp->if_broadcastaddr = ieee80211broadcastaddr;
- ifp->if_output = null_output;
- ifp->if_input = null_input; /* just in case */
- ifp->if_resolvemulti = NULL; /* NB: callers check */
-
- ifa = ifaddr_byindex(ifp->if_index);
- KASSERT(ifa != NULL, ("%s: no lladdr!\n", __func__));
- sdl = (struct sockaddr_dl *)ifa->ifa_addr;
- sdl->sdl_type = IFT_ETHER; /* XXX IFT_IEEE80211? */
- sdl->sdl_alen = IEEE80211_ADDR_LEN;
- IEEE80211_ADDR_COPY(LLADDR(sdl), macaddr);
- ifa_free(ifa);
-
- CURVNET_RESTORE();
+ LIST_INSERT_HEAD(&ic_head, ic, ic_next);
}
/*
@@ -369,16 +319,9 @@
void
ieee80211_ifdetach(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
struct ieee80211vap *vap;
- /*
- * This detaches the main interface, but not the vaps.
- * Each VAP may be in a separate VIMAGE.
- */
- CURVNET_SET(ifp->if_vnet);
- if_detach(ifp);
- CURVNET_RESTORE();
+ LIST_REMOVE(ic, ic_next);
/*
* The VAP is responsible for setting and clearing
@@ -402,8 +345,6 @@
ieee80211_power_detach(ic);
ieee80211_node_detach(ic);
- /* XXX VNET needed? */
- ifmedia_removeall(&ic->ic_media);
counter_u64_free(ic->ic_ierrors);
counter_u64_free(ic->ic_oerrors);
@@ -412,6 +353,17 @@
IEEE80211_LOCK_DESTROY(ic);
}
+struct ieee80211com *
+ieee80211_find_com(const char *name)
+{
+ struct ieee80211com *ic;
+
+ LIST_FOREACH(ic, &ic_head, ic_next)
+ if (strcmp(ic->ic_name, name) == 0)
+ break;
+ return (ic);
+}
+
/*
* Default reset method for use with the ioctl support. This
* method is invoked after any state change in the 802.11
@@ -460,8 +412,7 @@
int
ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap,
const char name[IFNAMSIZ], int unit, enum ieee80211_opmode opmode,
- int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t macaddr[IEEE80211_ADDR_LEN])
+ int flags, const uint8_t bssid[IEEE80211_ADDR_LEN])
{
struct ifnet *ifp;
@@ -490,6 +441,7 @@
vap->iv_htextcaps = ic->ic_htextcaps;
vap->iv_opmode = opmode;
vap->iv_caps |= ieee80211_opcap[opmode];
+ vap->iv_myaddr = ic->ic_macaddr;
switch (opmode) {
case IEEE80211_M_WDS:
/*
@@ -556,8 +508,6 @@
*/
vap->iv_reset = default_reset;
- IEEE80211_ADDR_COPY(vap->iv_myaddr, macaddr);
-
ieee80211_sysctl_vattach(vap);
ieee80211_crypto_vattach(vap);
ieee80211_node_vattach(vap);
@@ -581,8 +531,8 @@
* from this call the vap is ready for use.
*/
int
-ieee80211_vap_attach(struct ieee80211vap *vap,
- ifm_change_cb_t media_change, ifm_stat_cb_t media_stat)
+ieee80211_vap_attach(struct ieee80211vap *vap, ifm_change_cb_t media_change,
+ ifm_stat_cb_t media_stat, const uint8_t macaddr[IEEE80211_ADDR_LEN])
{
struct ifnet *ifp = vap->iv_ifp;
struct ieee80211com *ic = vap->iv_ic;
@@ -610,7 +560,8 @@
if (maxrate)
ifp->if_baudrate = IF_Mbps(maxrate);
- ether_ifattach(ifp, vap->iv_myaddr);
+ ether_ifattach(ifp, macaddr);
+ vap->iv_myaddr = IF_LLADDR(ifp);
/* hook output method setup by ether_ifattach */
vap->iv_output = ifp->if_output;
ifp->if_output = ieee80211_output;
@@ -626,8 +577,6 @@
ieee80211_syncflag_locked(ic, IEEE80211_F_BURST);
ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_HT);
ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
IEEE80211_UNLOCK(ic);
return 1;
@@ -677,8 +626,10 @@
ieee80211_syncflag_ht_locked(ic, IEEE80211_FHT_USEHT40);
/* NB: this handles the bpfdetach done below */
ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
+ if (vap->iv_ifflags & IFF_PROMISC)
+ ieee80211_promisc(vap, false);
+ if (vap->iv_ifflags & IFF_ALLMULTI)
+ ieee80211_allmulti(vap, false);
IEEE80211_UNLOCK(ic);
ifmedia_removeall(&vap->iv_media);
@@ -703,49 +654,57 @@
}
/*
- * Synchronize flag bit state in the parent ifnet structure
- * according to the state of all vap ifnet's. This is used,
- * for example, to handle IFF_PROMISC and IFF_ALLMULTI.
+ * Count number of vaps in promisc, and issue promisc on
+ * parent respectively.
*/
void
-ieee80211_syncifflag_locked(struct ieee80211com *ic, int flag)
+ieee80211_promisc(struct ieee80211vap *vap, bool on)
{
- struct ifnet *ifp = ic->ic_ifp;
- struct ieee80211vap *vap;
- int bit, oflags;
+ struct ieee80211com *ic = vap->iv_ic;
- IEEE80211_LOCK_ASSERT(ic);
+ /*
+ * XXX the bridge sets PROMISC but we don't want to
+ * enable it on the device, discard here so all the
+ * drivers don't need to special-case it
+ */
+ if (!(vap->iv_opmode == IEEE80211_M_MONITOR ||
+ (vap->iv_opmode == IEEE80211_M_AHDEMO &&
+ (vap->iv_caps & IEEE80211_C_TDMA) == 0)))
+ return;
- bit = 0;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
- if (vap->iv_ifp->if_flags & flag) {
- /*
- * XXX the bridge sets PROMISC but we don't want to
- * enable it on the device, discard here so all the
- * drivers don't need to special-case it
- */
- if (flag == IFF_PROMISC &&
- !(vap->iv_opmode == IEEE80211_M_MONITOR ||
- (vap->iv_opmode == IEEE80211_M_AHDEMO &&
- (vap->iv_caps & IEEE80211_C_TDMA) == 0)))
- continue;
- bit = 1;
- break;
- }
- oflags = ifp->if_flags;
- if (bit)
- ifp->if_flags |= flag;
- else
- ifp->if_flags &= ~flag;
- if ((ifp->if_flags ^ oflags) & flag) {
- /* XXX should we return 1/0 and let caller do this? */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- if (flag == IFF_PROMISC)
- ieee80211_runtask(ic, &ic->ic_promisc_task);
- else if (flag == IFF_ALLMULTI)
- ieee80211_runtask(ic, &ic->ic_mcast_task);
- }
+ IEEE80211_LOCK(ic);
+ if (on) {
+ if (ic->ic_promisc++ == 1)
+ ieee80211_runtask(ic, &ic->ic_promisc_task);
+ } else {
+ KASSERT(ic->ic_promisc > 0, ("%s: ic %p not promisc",
+ __func__, ic));
+ if (ic->ic_promisc-- == 0)
+ ieee80211_runtask(ic, &ic->ic_promisc_task);
}
+ IEEE80211_UNLOCK(ic);
+}
+
+/*
+ * Count number of vaps in allmulti, and issue allmulti on
+ * parent respectively.
+ */
+void
+ieee80211_allmulti(struct ieee80211vap *vap, bool on)
+{
+ struct ieee80211com *ic = vap->iv_ic;
+
+ IEEE80211_LOCK(ic);
+ if (on) {
+ if (ic->ic_allmulti++ == 1)
+ ieee80211_runtask(ic, &ic->ic_mcast_task);
+ } else {
+ KASSERT(ic->ic_allmulti > 0, ("%s: ic %p not allmulti",
+ __func__, ic));
+ if (ic->ic_allmulti-- == 0)
+ ieee80211_runtask(ic, &ic->ic_mcast_task);
+ }
+ IEEE80211_UNLOCK(ic);
}
/*
@@ -1234,39 +1193,6 @@
return maxrate;
}
-void
-ieee80211_media_init(struct ieee80211com *ic)
-{
- struct ifnet *ifp = ic->ic_ifp;
- int maxrate;
-
- /* NB: this works because the structure is initialized to zero */
- if (!LIST_EMPTY(&ic->ic_media.ifm_list)) {
- /*
- * We are re-initializing the channel list; clear
- * the existing media state as the media routines
- * don't suppress duplicates.
- */
- ifmedia_removeall(&ic->ic_media);
- }
- ieee80211_chan_init(ic);
-
- /*
- * Recalculate media settings in case new channel list changes
- * the set of available modes.
- */
- maxrate = ieee80211_media_setup(ic, &ic->ic_media, ic->ic_caps, 1,
- ieee80211com_media_change, ieee80211com_media_status);
- /* NB: strip explicit mode; we're actually in autoselect */
- ifmedia_set(&ic->ic_media,
- media_status(ic->ic_opmode, ic->ic_curchan) &~
- (IFM_MMASK | IFM_IEEE80211_TURBO));
- if (maxrate)
- ifp->if_baudrate = IF_Mbps(maxrate);
-
- /* XXX need to propagate new media settings to vap's */
-}
-
/* XXX inline or eliminate? */
const struct ieee80211_rateset *
ieee80211_get_suprates(struct ieee80211com *ic, const struct ieee80211_channel *c)
@@ -1395,15 +1321,6 @@
}
/*
- * Handle a media change request on the underlying interface.
- */
-int
-ieee80211com_media_change(struct ifnet *ifp)
-{
- return EINVAL;
-}
-
-/*
* Handle a media change request on the vap interface.
*/
int
@@ -1480,23 +1397,6 @@
return status;
}
-static void
-ieee80211com_media_status(struct ifnet *ifp, struct ifmediareq *imr)
-{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap;
-
- imr->ifm_status = IFM_AVALID;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
- if (vap->iv_ifp->if_flags & IFF_UP) {
- imr->ifm_status |= IFM_ACTIVE;
- break;
- }
- imr->ifm_active = media_status(ic->ic_opmode, ic->ic_curchan);
- if (imr->ifm_status & IFM_ACTIVE)
- imr->ifm_current = imr->ifm_active;
-}
-
void
ieee80211_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
Index: sys/net80211/ieee80211_ddb.c
===================================================================
--- sys/net80211/ieee80211_ddb.c
+++ sys/net80211/ieee80211_ddb.c
@@ -520,7 +520,7 @@
TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
db_printf(" %s(%p)", vap->iv_ifp->if_xname, vap);
db_printf("\n");
- db_printf("\tifp %p(%s)", ic->ic_ifp, ic->ic_ifp->if_xname);
+ db_printf("\tsoftc %p", ic->ic_softc);
db_printf("\tname %s", ic->ic_name);
db_printf(" comlock %p", &ic->ic_comlock);
db_printf("\n");
@@ -528,7 +528,6 @@
db_printf(" phytype %d", ic->ic_phytype);
db_printf(" opmode %s", ieee80211_opmode_name[ic->ic_opmode]);
db_printf("\n");
- db_printf("\tmedia %p", &ic->ic_media);
db_printf(" inact %p", &ic->ic_inact);
db_printf("\n");
Index: sys/net80211/ieee80211_freebsd.c
===================================================================
--- sys/net80211/ieee80211_freebsd.c
+++ sys/net80211/ieee80211_freebsd.c
@@ -69,58 +69,27 @@
static const char wlanname[] = "wlan";
static struct if_clone *wlan_cloner;
-/*
- * Allocate/free com structure in conjunction with ifnet;
- * these routines are registered with if_register_com_alloc
- * below and are called automatically by the ifnet code
- * when the ifnet of the parent device is created.
- */
-static void *
-wlan_alloc(u_char type, struct ifnet *ifp)
-{
- struct ieee80211com *ic;
-
- ic = IEEE80211_MALLOC(sizeof(struct ieee80211com), M_80211_COM,
- IEEE80211_M_WAITOK | IEEE80211_M_ZERO);
- ic->ic_ifp = ifp;
-
- return (ic);
-}
-
-static void
-wlan_free(void *ic, u_char type)
-{
- IEEE80211_FREE(ic, M_80211_COM);
-}
-
static int
wlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
{
struct ieee80211_clone_params cp;
struct ieee80211vap *vap;
struct ieee80211com *ic;
- struct ifnet *ifp;
int error;
error = copyin(params, &cp, sizeof(cp));
if (error)
return error;
- ifp = ifunit(cp.icp_parent);
- if (ifp == NULL)
+ ic = ieee80211_find_com(cp.icp_parent);
+ if (ic == NULL)
return ENXIO;
- /* XXX move printfs to DIAGNOSTIC before release */
- if (ifp->if_type != IFT_IEEE80211) {
- if_printf(ifp, "%s: reject, not an 802.11 device\n", __func__);
- return ENXIO;
- }
if (cp.icp_opmode >= IEEE80211_OPMODE_MAX) {
- if_printf(ifp, "%s: invalid opmode %d\n",
- __func__, cp.icp_opmode);
+ ic_printf(ic, "%s: invalid opmode %d\n", __func__,
+ cp.icp_opmode);
return EINVAL;
}
- ic = ifp->if_l2com;
if ((ic->ic_caps & ieee80211_opcap[cp.icp_opmode]) == 0) {
- if_printf(ifp, "%s mode not supported\n",
+ ic_printf(ic, "%s mode not supported\n",
ieee80211_opmode_name[cp.icp_opmode]);
return EOPNOTSUPP;
}
@@ -131,13 +100,13 @@
(1)
#endif
) {
- if_printf(ifp, "TDMA not supported\n");
+ ic_printf(ic, "TDMA not supported\n");
return EOPNOTSUPP;
}
vap = ic->ic_vap_create(ic, wlanname, unit,
cp.icp_opmode, cp.icp_flags, cp.icp_bssid,
cp.icp_flags & IEEE80211_CLONE_MACADDR ?
- cp.icp_macaddr : (const uint8_t *)IF_LLADDR(ifp));
+ cp.icp_macaddr : ic->ic_macaddr);
return (vap == NULL ? EIO : 0);
}
@@ -494,17 +463,19 @@
* (the callers will first need modifying.)
*/
int
-ieee80211_parent_xmitpkt(struct ieee80211com *ic,
- struct mbuf *m)
+ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
{
- struct ifnet *parent = ic->ic_ifp;
+ int error;
+
/*
* Assert the IC TX lock is held - this enforces the
* processing -> queuing order is maintained
*/
IEEE80211_TX_LOCK_ASSERT(ic);
-
- return (parent->if_transmit(parent, m));
+ error = ic->ic_transmit(ic, m);
+ if (error)
+ m_freem(m);
+ return (error);
}
/*
@@ -802,7 +773,6 @@
}
static eventhandler_tag wlan_bpfevent;
-static eventhandler_tag wlan_ifllevent;
static void
bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach)
@@ -830,33 +800,6 @@
}
}
-static void
-wlan_iflladdr(void *arg __unused, struct ifnet *ifp)
-{
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap, *next;
-
- if (ifp->if_type != IFT_IEEE80211 || ic == NULL)
- return;
-
- IEEE80211_LOCK(ic);
- TAILQ_FOREACH_SAFE(vap, &ic->ic_vaps, iv_next, next) {
- /*
- * If the MAC address has changed on the parent and it was
- * copied to the vap on creation then re-sync.
- */
- if (vap->iv_ic == ic &&
- (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) {
- IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp));
- IEEE80211_UNLOCK(ic);
- if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp),
- IEEE80211_ADDR_LEN);
- IEEE80211_LOCK(ic);
- }
- }
- IEEE80211_UNLOCK(ic);
-}
-
/*
* Module glue.
*
@@ -871,17 +814,12 @@
printf("wlan: <802.11 Link Layer>\n");
wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track,
bpf_track, 0, EVENTHANDLER_PRI_ANY);
- wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
- wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY);
wlan_cloner = if_clone_simple(wlanname, wlan_clone_create,
wlan_clone_destroy, 0);
- if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free);
return 0;
case MOD_UNLOAD:
- if_deregister_com_alloc(IFT_IEEE80211);
if_clone_detach(wlan_cloner);
EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent);
- EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent);
return 0;
}
return EINVAL;
Index: sys/net80211/ieee80211_ioctl.c
===================================================================
--- sys/net80211/ieee80211_ioctl.c
+++ sys/net80211/ieee80211_ioctl.c
@@ -1329,13 +1329,12 @@
setmlme_dropsta(struct ieee80211vap *vap,
const uint8_t mac[IEEE80211_ADDR_LEN], struct mlmeop *mlmeop)
{
- struct ieee80211com *ic = vap->iv_ic;
- struct ieee80211_node_table *nt = &ic->ic_sta;
+ struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta;
struct ieee80211_node *ni;
int error = 0;
/* NB: the broadcast address means do 'em all */
- if (!IEEE80211_ADDR_EQ(mac, ic->ic_ifp->if_broadcastaddr)) {
+ if (!IEEE80211_ADDR_EQ(mac, vap->iv_ifp->if_broadcastaddr)) {
IEEE80211_NODE_LOCK(nt);
ni = ieee80211_find_node_locked(nt, mac);
IEEE80211_NODE_UNLOCK(nt);
@@ -2529,14 +2528,9 @@
static __noinline int
ieee80211_ioctl_scanreq(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
- struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_scan_req sr; /* XXX off stack? */
int error;
- /* NB: parent must be running */
- if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
- return ENXIO;
-
if (ireq->i_len != sizeof(sr))
return EINVAL;
error = copyin(ireq->i_data, &sr, sizeof(sr));
@@ -3300,41 +3294,6 @@
return error;
}
-/*
- * Rebuild the parent's multicast address list after an add/del
- * of a multicast address for a vap. We have no way to tell
- * what happened above to optimize the work so we purge the entire
- * list and rebuild from scratch. This is way expensive.
- * Note also the half-baked workaround for if_addmulti calling
- * back to the parent device; there's no way to insert mcast
- * entries quietly and/or cheaply.
- */
-static void
-ieee80211_ioctl_updatemulti(struct ieee80211com *ic)
-{
- struct ifnet *parent = ic->ic_ifp;
- struct ieee80211vap *vap;
- void *ioctl;
-
- IEEE80211_LOCK(ic);
- if_delallmulti(parent);
- ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */
- parent->if_ioctl = NULL;
- TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
- struct ifnet *ifp = vap->iv_ifp;
- struct ifmultiaddr *ifma;
-
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- (void) if_addmulti(parent, ifma->ifma_addr, NULL);
- }
- }
- parent->if_ioctl = ioctl;
- ieee80211_runtask(ic, &ic->ic_mcast_task);
- IEEE80211_UNLOCK(ic);
-}
-
int
ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
@@ -3347,8 +3306,11 @@
switch (cmd) {
case SIOCSIFFLAGS:
IEEE80211_LOCK(ic);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- ieee80211_syncifflag_locked(ic, IFF_ALLMULTI);
+ if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_PROMISC)
+ ieee80211_promisc(vap, ifp->if_flags & IFF_PROMISC);
+ if ((ifp->if_flags ^ vap->iv_ifflags) & IFF_ALLMULTI)
+ ieee80211_allmulti(vap, ifp->if_flags & IFF_ALLMULTI);
+ vap->iv_ifflags = ifp->if_flags;
if (ifp->if_flags & IFF_UP) {
/*
* Bring ourself up unless we're already operational.
@@ -3371,7 +3333,7 @@
break;
case SIOCADDMULTI:
case SIOCDELMULTI:
- ieee80211_ioctl_updatemulti(ic);
+ ieee80211_runtask(ic, &ic->ic_mcast_task);
break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
@@ -3427,17 +3389,16 @@
break;
}
break;
- /* Pass NDIS ioctls up to the driver */
- case SIOCGDRVSPEC:
- case SIOCSDRVSPEC:
- case SIOCGPRIVATE_0: {
- struct ifnet *parent = vap->iv_ic->ic_ifp;
- error = parent->if_ioctl(parent, cmd, data);
- break;
- }
default:
+ /*
+ * Pass unknown ioctls first to the driver, and if it
+ * returns ENOTTY, then to the generic Ethernet handler.
+ */
+ if (ic->ic_ioctl != NULL &&
+ (error = ic->ic_ioctl(ic, cmd, data)) != ENOTTY)
+ break;
error = ether_ioctl(ifp, cmd, data);
break;
}
- return error;
+ return (error);
}
Index: sys/net80211/ieee80211_output.c
===================================================================
--- sys/net80211/ieee80211_output.c
+++ sys/net80211/ieee80211_output.c
@@ -254,10 +254,6 @@
/* NB: IFQ_HANDOFF reclaims mbuf */
ieee80211_free_node(ni);
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- } else {
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
- if_inc_counter(ifp, IFCOUNTER_OMCASTS, mcast);
- if_inc_counter(ifp, IFCOUNTER_OBYTES, len);
}
ic->ic_lastdata = ticks;
@@ -430,17 +426,6 @@
{
struct ieee80211vap *vap = ifp->if_softc;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *parent = ic->ic_ifp;
-
- /* NB: parent must be up and running */
- if (!IFNET_IS_UP_RUNNING(parent)) {
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
- "%s: ignore queue, parent %s not up+running\n",
- __func__, parent->if_xname);
- m_freem(m);
- if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
- return (ENETDOWN);
- }
/*
* No data frames go out unless we're running.
@@ -3437,6 +3422,15 @@
{
if (ni != NULL) {
+ struct ifnet *ifp = ni->ni_vap->iv_ifp;
+
+ if (status == 0) {
+ if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ if (m->m_flags & M_MCAST)
+ if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
+ } else
+ if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
if (m->m_flags & M_TXCB)
ieee80211_process_callback(ni, m, status);
ieee80211_free_node(ni);
Index: sys/net80211/ieee80211_power.c
===================================================================
--- sys/net80211/ieee80211_power.c
+++ sys/net80211/ieee80211_power.c
@@ -418,7 +418,6 @@
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_psq_head *qhead;
- struct ifnet *parent, *ifp;
struct mbuf *parent_q = NULL, *ifp_q = NULL;
struct mbuf *m;
@@ -429,59 +428,51 @@
qhead = &psq->psq_head[0]; /* 802.11 frames */
if (qhead->head != NULL) {
/* XXX could dispatch through vap and check M_ENCAP */
- parent = vap->iv_ic->ic_ifp;
/* XXX need different driver interface */
/* XXX bypasses q max and OACTIVE */
parent_q = qhead->head;
qhead->head = qhead->tail = NULL;
qhead->len = 0;
- } else
- parent = NULL;
+ }
qhead = &psq->psq_head[1]; /* 802.3 frames */
if (qhead->head != NULL) {
- ifp = vap->iv_ifp;
/* XXX need different driver interface */
/* XXX bypasses q max and OACTIVE */
ifp_q = qhead->head;
qhead->head = qhead->tail = NULL;
qhead->len = 0;
- } else
- ifp = NULL;
+ }
psq->psq_len = 0;
IEEE80211_PSQ_UNLOCK(psq);
/* NB: do this outside the psq lock */
/* XXX packets might get reordered if parent is OACTIVE */
/* parent frames, should be encapsulated */
- if (parent != NULL) {
- while (parent_q != NULL) {
- m = parent_q;
- parent_q = m->m_nextpkt;
- m->m_nextpkt = NULL;
- /* must be encapsulated */
- KASSERT((m->m_flags & M_ENCAP),
- ("%s: parentq with non-M_ENCAP frame!\n",
- __func__));
- /*
- * For encaped frames, we need to free the node
- * reference upon failure.
- */
- if (ieee80211_parent_xmitpkt(ic, m) != 0)
- ieee80211_free_node(ni);
- }
+ while (parent_q != NULL) {
+ m = parent_q;
+ parent_q = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ /* must be encapsulated */
+ KASSERT((m->m_flags & M_ENCAP),
+ ("%s: parentq with non-M_ENCAP frame!\n",
+ __func__));
+ /*
+ * For encaped frames, we need to free the node
+ * reference upon failure.
+ */
+ if (ieee80211_parent_xmitpkt(ic, m) != 0)
+ ieee80211_free_node(ni);
}
/* VAP frames, aren't encapsulated */
- if (ifp != NULL) {
- while (ifp_q != NULL) {
- m = ifp_q;
- ifp_q = m->m_nextpkt;
- m->m_nextpkt = NULL;
- KASSERT((!(m->m_flags & M_ENCAP)),
- ("%s: vapq with M_ENCAP frame!\n", __func__));
- (void) ieee80211_vap_xmitpkt(vap, m);
- }
+ while (ifp_q != NULL) {
+ m = ifp_q;
+ ifp_q = m->m_nextpkt;
+ m->m_nextpkt = NULL;
+ KASSERT((!(m->m_flags & M_ENCAP)),
+ ("%s: vapq with M_ENCAP frame!\n", __func__));
+ (void) ieee80211_vap_xmitpkt(vap, m);
}
}
Index: sys/net80211/ieee80211_proto.h
===================================================================
--- sys/net80211/ieee80211_proto.h
+++ sys/net80211/ieee80211_proto.h
@@ -56,7 +56,8 @@
void ieee80211_proto_vattach(struct ieee80211vap *);
void ieee80211_proto_vdetach(struct ieee80211vap *);
-void ieee80211_syncifflag_locked(struct ieee80211com *, int flag);
+void ieee80211_promisc(struct ieee80211vap *, bool);
+void ieee80211_allmulti(struct ieee80211vap *, bool);
void ieee80211_syncflag(struct ieee80211vap *, int flag);
void ieee80211_syncflag_ht(struct ieee80211vap *, int flag);
void ieee80211_syncflag_ext(struct ieee80211vap *, int flag);
Index: sys/net80211/ieee80211_proto.c
===================================================================
--- sys/net80211/ieee80211_proto.c
+++ sys/net80211/ieee80211_proto.c
@@ -122,23 +122,23 @@
void
ieee80211_proto_attach(struct ieee80211com *ic)
{
- struct ifnet *ifp = ic->ic_ifp;
+ uint8_t hdrlen;
/* override the 802.3 setting */
- ifp->if_hdrlen = ic->ic_headroom
+ hdrlen = ic->ic_headroom
+ sizeof(struct ieee80211_qosframe_addr4)
+ IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN
+ IEEE80211_WEP_EXTIVLEN;
/* XXX no way to recalculate on ifdetach */
- if (ALIGN(ifp->if_hdrlen) > max_linkhdr) {
+ if (ALIGN(hdrlen) > max_linkhdr) {
/* XXX sanity check... */
- max_linkhdr = ALIGN(ifp->if_hdrlen);
+ max_linkhdr = ALIGN(hdrlen);
max_hdr = max_linkhdr + max_protohdr;
max_datalen = MHLEN - max_hdr;
}
ic->ic_protmode = IEEE80211_PROT_CTSONLY;
- TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ifp);
+ TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ic);
TASK_INIT(&ic->ic_mcast_task, 0, update_mcast, ic);
TASK_INIT(&ic->ic_promisc_task, 0, update_promisc, ic);
TASK_INIT(&ic->ic_chan_task, 0, update_channel, ic);
@@ -188,7 +188,10 @@
int i;
/* override the 802.3 setting */
- ifp->if_hdrlen = ic->ic_ifp->if_hdrlen;
+ ifp->if_hdrlen = ic->ic_headroom
+ + sizeof(struct ieee80211_qosframe_addr4)
+ + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN
+ + IEEE80211_WEP_EXTIVLEN;
vap->iv_rtsthreshold = IEEE80211_RTS_DEFAULT;
vap->iv_fragthreshold = IEEE80211_FRAG_DEFAULT;
@@ -1155,9 +1158,9 @@
static void
parent_updown(void *arg, int npending)
{
- struct ifnet *parent = arg;
+ struct ieee80211com *ic = arg;
- parent->if_ioctl(parent, SIOCSIFFLAGS, NULL);
+ ic->ic_parent(ic);
}
static void
@@ -1224,7 +1227,6 @@
{
struct ifnet *ifp = vap->iv_ifp;
struct ieee80211com *ic = vap->iv_ic;
- struct ifnet *parent = ic->ic_ifp;
IEEE80211_LOCK_ASSERT(ic);
@@ -1246,12 +1248,10 @@
* We are not running; if this we are the first vap
* to be brought up auto-up the parent if necessary.
*/
- if (ic->ic_nrunning++ == 0 &&
- (parent->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ if (ic->ic_nrunning++ == 0) {
IEEE80211_DPRINTF(vap,
IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
- "%s: up parent %s\n", __func__, parent->if_xname);
- parent->if_flags |= IFF_UP;
+ "%s: up parent %s\n", __func__, ic->ic_name);
ieee80211_runtask(ic, &ic->ic_parent_task);
return;
}
@@ -1260,8 +1260,7 @@
* If the parent is up and running, then kick the
* 802.11 state machine as appropriate.
*/
- if ((parent->if_drv_flags & IFF_DRV_RUNNING) &&
- vap->iv_roaming != IEEE80211_ROAMING_MANUAL) {
+ if (vap->iv_roaming != IEEE80211_ROAMING_MANUAL) {
if (vap->iv_opmode == IEEE80211_M_STA) {
#if 0
/* XXX bypasses scan too easily; disable for now */
@@ -1344,7 +1343,6 @@
{
struct ieee80211com *ic = vap->iv_ic;
struct ifnet *ifp = vap->iv_ifp;
- struct ifnet *parent = ic->ic_ifp;
IEEE80211_LOCK_ASSERT(ic);
@@ -1354,12 +1352,10 @@
ieee80211_new_state_locked(vap, IEEE80211_S_INIT, -1);
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; /* mark us stopped */
- if (--ic->ic_nrunning == 0 &&
- (parent->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (--ic->ic_nrunning == 0) {
IEEE80211_DPRINTF(vap,
IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG,
- "down parent %s\n", parent->if_xname);
- parent->if_flags &= ~IFF_UP;
+ "down parent %s\n", ic->ic_name);
ieee80211_runtask(ic, &ic->ic_parent_task);
}
}
Index: sys/net80211/ieee80211_regdomain.c
===================================================================
--- sys/net80211/ieee80211_regdomain.c
+++ sys/net80211/ieee80211_regdomain.c
@@ -35,7 +35,6 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
-
#include <sys/socket.h>
#include <net/if.h>
@@ -487,7 +486,7 @@
memset(&ic->ic_channels[ic->ic_nchans], 0,
(IEEE80211_CHAN_MAX - ic->ic_nchans) *
sizeof(struct ieee80211_channel));
- ieee80211_media_init(ic);
+ ieee80211_chan_init(ic);
/*
* Invalidate channel-related state.
Index: sys/net80211/ieee80211_scan_sta.c
===================================================================
--- sys/net80211/ieee80211_scan_sta.c
+++ sys/net80211/ieee80211_scan_sta.c
@@ -1706,26 +1706,6 @@
IEEE80211_SCANNER_ALG(ibss, IEEE80211_M_IBSS, adhoc_default);
IEEE80211_SCANNER_ALG(ahdemo, IEEE80211_M_AHDEMO, adhoc_default);
-static void
-ap_force_promisc(struct ieee80211com *ic)
-{
- struct ifnet *ifp = ic->ic_ifp;
-
- IEEE80211_LOCK(ic);
- /* set interface into promiscuous mode */
- ifp->if_flags |= IFF_PROMISC;
- ieee80211_runtask(ic, &ic->ic_promisc_task);
- IEEE80211_UNLOCK(ic);
-}
-
-static void
-ap_reset_promisc(struct ieee80211com *ic)
-{
- IEEE80211_LOCK(ic);
- ieee80211_syncifflag_locked(ic, IFF_PROMISC);
- IEEE80211_UNLOCK(ic);
-}
-
static int
ap_start(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
{
@@ -1741,7 +1721,7 @@
st->st_scangen++;
st->st_newscan = 1;
- ap_force_promisc(vap->iv_ic);
+ ieee80211_promisc(vap, true);
return 0;
}
@@ -1751,7 +1731,7 @@
static int
ap_cancel(struct ieee80211_scan_state *ss, struct ieee80211vap *vap)
{
- ap_reset_promisc(vap->iv_ic);
+ ieee80211_promisc(vap, false);
return 0;
}
@@ -1825,7 +1805,7 @@
return 0;
}
}
- ap_reset_promisc(ic);
+ ieee80211_promisc(vap, false);
if (ss->ss_flags & (IEEE80211_SCAN_NOPICK | IEEE80211_SCAN_NOJOIN)) {
/*
* Manual/background scan, don't select+join the
Index: sys/net80211/ieee80211_var.h
===================================================================
--- sys/net80211/ieee80211_var.h
+++ sys/net80211/ieee80211_var.h
@@ -116,16 +116,15 @@
struct ieee80211_frame;
struct ieee80211com {
- struct ifnet *ic_ifp; /* associated device */
void *ic_softc; /* driver softc */
const char *ic_name; /* usually device name */
ieee80211_com_lock_t ic_comlock; /* state update lock */
ieee80211_tx_lock_t ic_txlock; /* ic/vap TX lock */
+ LIST_ENTRY(ieee80211com) ic_next; /* on global list */
TAILQ_HEAD(, ieee80211vap) ic_vaps; /* list of vap instances */
int ic_headroom; /* driver tx headroom needs */
enum ieee80211_phytype ic_phytype; /* XXX wrong for multi-mode */
enum ieee80211_opmode ic_opmode; /* operation mode */
- struct ifmedia ic_media; /* interface media config */
struct callout ic_inact; /* inactivity processing */
struct taskqueue *ic_tq; /* deferred state thread */
struct task ic_parent_task; /* deferred parent processing */
@@ -151,6 +150,7 @@
uint8_t ic_allmulti; /* vap's needing all multicast*/
uint8_t ic_nrunning; /* vap's marked running */
uint8_t ic_curmode; /* current mode */
+ uint8_t ic_macaddr[IEEE80211_ADDR_LEN];
uint16_t ic_bintval; /* beacon interval */
uint16_t ic_lintval; /* listen interval */
uint16_t ic_holdover; /* PM hold over duration */
@@ -240,6 +240,11 @@
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN]);
void (*ic_vap_delete)(struct ieee80211vap *);
+ /* device specific ioctls */
+ int (*ic_ioctl)(struct ieee80211com *,
+ u_long, char *);
+ /* start/stop device */
+ void (*ic_parent)(struct ieee80211com *);
/* operating mode attachment */
ieee80211vap_attach ic_vattach[IEEE80211_OPMODE_MAX];
/* return hardware/radio capabilities */
@@ -253,6 +258,9 @@
int (*ic_set_quiet)(struct ieee80211_node *,
u_int8_t *quiet_elm);
+ /* regular transmit */
+ int (*ic_transmit)(struct ieee80211com *,
+ struct mbuf *);
/* send/recv 802.11 management frame */
int (*ic_send_mgmt)(struct ieee80211_node *,
int, int);
@@ -350,14 +358,15 @@
TAILQ_ENTRY(ieee80211vap) iv_next; /* list of vap instances */
struct ieee80211com *iv_ic; /* back ptr to common state */
+ const uint8_t *iv_myaddr; /* MAC address: ifp or ic */
uint32_t iv_debug; /* debug msg flags */
struct ieee80211_stats iv_stats; /* statistics */
- uint8_t iv_myaddr[IEEE80211_ADDR_LEN];
uint32_t iv_flags; /* state flags */
uint32_t iv_flags_ext; /* extended state flags */
uint32_t iv_flags_ht; /* HT state flags */
uint32_t iv_flags_ven; /* vendor state flags */
+ uint32_t iv_ifflags; /* ifnet flags */
uint32_t iv_caps; /* capabilities */
uint32_t iv_htcaps; /* HT capabilities */
uint32_t iv_htextcaps; /* HT extended capabilities */
@@ -680,24 +689,24 @@
"\21AMPDU\22AMSDU\23HT\24SMPS\25RIFS"
int ic_printf(struct ieee80211com *, const char *, ...) __printflike(2, 3);
-void ieee80211_ifattach(struct ieee80211com *,
- const uint8_t macaddr[IEEE80211_ADDR_LEN]);
+void ieee80211_ifattach(struct ieee80211com *);
void ieee80211_ifdetach(struct ieee80211com *);
int ieee80211_vap_setup(struct ieee80211com *, struct ieee80211vap *,
const char name[IFNAMSIZ], int unit,
enum ieee80211_opmode opmode, int flags,
- const uint8_t bssid[IEEE80211_ADDR_LEN],
- const uint8_t macaddr[IEEE80211_ADDR_LEN]);
+ const uint8_t bssid[IEEE80211_ADDR_LEN]);
int ieee80211_vap_attach(struct ieee80211vap *,
- ifm_change_cb_t, ifm_stat_cb_t);
+ ifm_change_cb_t, ifm_stat_cb_t,
+ const uint8_t macaddr[IEEE80211_ADDR_LEN]);
void ieee80211_vap_detach(struct ieee80211vap *);
const struct ieee80211_rateset *ieee80211_get_suprates(struct ieee80211com *ic,
const struct ieee80211_channel *);
void ieee80211_announce(struct ieee80211com *);
void ieee80211_announce_channels(struct ieee80211com *);
void ieee80211_drain(struct ieee80211com *);
-void ieee80211_media_init(struct ieee80211com *);
+void ieee80211_chan_init(struct ieee80211com *);
struct ieee80211com *ieee80211_find_vap(const uint8_t mac[IEEE80211_ADDR_LEN]);
+struct ieee80211com *ieee80211_find_com(const char *name);
int ieee80211_media_change(struct ifnet *);
void ieee80211_media_status(struct ifnet *, struct ifmediareq *);
int ieee80211_ioctl(struct ifnet *, u_long, caddr_t);
Index: tools/tools/iwn/iwnstats/main.c
===================================================================
--- tools/tools/iwn/iwnstats/main.c
+++ tools/tools/iwn/iwnstats/main.c
@@ -50,7 +50,7 @@
#include "iwnstats.h"
#include "iwn_ioctl.h"
-#define IWN_DEFAULT_IF "iwn0"
+#define IWN_DEFAULT_IF "wlan0"
static struct iwnstats *
iwnstats_new(const char *ifname)
@@ -290,19 +290,6 @@
if (ifname)
free(ifname);
ifname = strdup(optarg);
- if (strncmp(ifname, "wlan", 4) == 0) {
- free(ifname);
- len = 0;
- asprintf(&sysctlname, "net.wlan.%s.%%parent", ifname + 4);
- ret = sysctlbyname(sysctlname, NULL, &len, NULL, 0);
- if (ret != 0)
- err(1, "sysctl failed");
- ifname = calloc(len, 1);
- ret = sysctlbyname(sysctlname, ifname, &len, NULL, 0);
- if (ret != 0)
- err(1, "sysctl failed");
- free(sysctlname);
- }
break;
default:
case '?':

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 16, 2:57 PM (19 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25374046
Default Alt Text
D2655.id5707.diff (63 KB)

Event Timeline