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/bwi/bwimac.c =================================================================== --- sys/dev/bwi/bwimac.c +++ sys/dev/bwi/bwimac.c @@ -832,11 +832,11 @@ uint8_t fw_type) { const struct bwi_fwhdr *hdr; - struct ifnet *ifp = sc->sc_ifp; if (fw->datasize < sizeof(*hdr)) { - if_printf(ifp, "invalid firmware (%s): invalid size %zu\n", - fw->name, fw->datasize); + device_printf(sc->sc_dev, + "invalid firmware (%s): invalid size %zu\n", + fw->name, fw->datasize); return 0; } @@ -847,25 +847,26 @@ * Don't verify IV's size, it has different meaning */ if (be32toh(hdr->fw_size) != fw->datasize - sizeof(*hdr)) { - if_printf(ifp, "invalid firmware (%s): size mismatch, " - "fw %u, real %zu\n", fw->name, - be32toh(hdr->fw_size), - fw->datasize - sizeof(*hdr)); + device_printf(sc->sc_dev, + "invalid firmware (%s): size mismatch, " + "fw %u, real %zu\n", fw->name, + be32toh(hdr->fw_size), fw->datasize - sizeof(*hdr)); return 0; } } if (hdr->fw_type != fw_type) { - if_printf(ifp, "invalid firmware (%s): type mismatch, " - "fw \'%c\', target \'%c\'\n", fw->name, - hdr->fw_type, fw_type); + device_printf(sc->sc_dev, + "invalid firmware (%s): type mismatch, " + "fw \'%c\', target \'%c\'\n", fw->name, + hdr->fw_type, fw_type); return 0; } if (hdr->fw_gen != BWI_FW_GEN_1) { - if_printf(ifp, "invalid firmware (%s): wrong generation, " - "fw %d, target %d\n", fw->name, - hdr->fw_gen, BWI_FW_GEN_1); + device_printf(sc->sc_dev, + "invalid firmware (%s): wrong generation, " + "fw %d, target %d\n", fw->name, hdr->fw_gen, BWI_FW_GEN_1); return 0; } return 1; @@ -1002,7 +1003,6 @@ bwi_mac_fw_load(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; const uint32_t *fw; uint16_t fw_rev; int fw_len, i; @@ -1057,7 +1057,8 @@ DELAY(10); } if (i == NRETRY) { - if_printf(ifp, "firmware (ucode&pcm) loading timed out\n"); + device_printf(sc->sc_dev, + "firmware (ucode&pcm) loading timed out\n"); return ETIMEDOUT; } @@ -1067,12 +1068,14 @@ fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV); if (fw_rev > BWI_FW_VERSION3_REVMAX) { - if_printf(ifp, "firmware version 4 is not supported yet\n"); + device_printf(sc->sc_dev, + "firmware version 4 is not supported yet\n"); return ENODEV; } - if_printf(ifp, "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev, - MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV)); + device_printf(sc->sc_dev, + "firmware rev 0x%04x, patch level 0x%04x\n", fw_rev, + MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV)); return 0; } @@ -1132,7 +1135,6 @@ bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; const struct bwi_fwhdr *hdr; const struct bwi_fw_iv *iv; int n, i, iv_img_size; @@ -1155,7 +1157,7 @@ int sz = 0; if (iv_img_size < sizeof(iv->iv_ofs)) { - if_printf(ifp, "invalid IV image, ofs\n"); + device_printf(sc->sc_dev, "invalid IV image, ofs\n"); return EINVAL; } iv_img_size -= sizeof(iv->iv_ofs); @@ -1165,7 +1167,7 @@ ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK); if (ofs >= 0x1000) { - if_printf(ifp, "invalid ofs (0x%04x) " + device_printf(sc->sc_dev, "invalid ofs (0x%04x) " "for %dth iv\n", ofs, i); return EINVAL; } @@ -1174,7 +1176,8 @@ uint32_t val32; if (iv_img_size < sizeof(iv->iv_val.val32)) { - if_printf(ifp, "invalid IV image, val32\n"); + device_printf(sc->sc_dev, + "invalid IV image, val32\n"); return EINVAL; } iv_img_size -= sizeof(iv->iv_val.val32); @@ -1186,7 +1189,8 @@ uint16_t val16; if (iv_img_size < sizeof(iv->iv_val.val16)) { - if_printf(ifp, "invalid IV image, val16\n"); + device_printf(sc->sc_dev, + "invalid IV image, val16\n"); return EINVAL; } iv_img_size -= sizeof(iv->iv_val.val16); @@ -1200,7 +1204,8 @@ } if (iv_img_size != 0) { - if_printf(ifp, "invalid IV image, size left %d\n", iv_img_size); + device_printf(sc->sc_dev, "invalid IV image, size left %d\n", + iv_img_size); return EINVAL; } return 0; @@ -1209,19 +1214,19 @@ static int bwi_mac_fw_init(struct bwi_mac *mac) { - struct ifnet *ifp = mac->mac_sc->sc_ifp; + device_t dev = mac->mac_sc->sc_dev; int error; error = bwi_mac_fw_load_iv(mac, mac->mac_iv); if (error) { - if_printf(ifp, "load IV failed\n"); + device_printf(dev, "load IV failed\n"); return error; } if (mac->mac_iv_ext != NULL) { error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext); if (error) - if_printf(ifp, "load ExtIV failed\n"); + device_printf(dev, "load ExtIV failed\n"); } return error; } @@ -1230,8 +1235,7 @@ bwi_mac_opmode_init(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mac_status; uint16_t pre_tbtt; @@ -1280,7 +1284,7 @@ break; } - if (ic->ic_ifp->if_flags & IFF_PROMISC) + if (ic->ic_promisc > 0) mac_status |= BWI_MAC_STATUS_PROMISC; CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status); @@ -1331,8 +1335,7 @@ { struct bwi_softc *sc = mac->mac_sc; struct bwi_phy *phy = &mac->mac_phy; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct ieee80211_rate_table *rt; struct bwi_retry_lim lim; uint16_t cw_min; @@ -1915,8 +1918,7 @@ bwi_mac_lock(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0, ("mac_flags 0x%x", mac->mac_flags)); @@ -1939,8 +1941,7 @@ bwi_mac_unlock(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED, ("mac_flags 0x%x", mac->mac_flags)); Index: sys/dev/bwi/bwiphy.c =================================================================== --- sys/dev/bwi/bwiphy.c +++ sys/dev/bwi/bwiphy.c @@ -429,7 +429,7 @@ bwi_phy_init_11b_rev2(struct bwi_mac *mac) { /* TODO:11B */ - if_printf(mac->mac_sc->sc_ifp, + device_printf(mac->mac_sc->sc_dev, "%s is not implemented yet\n", __func__); } Index: sys/dev/bwi/bwirf.c =================================================================== --- sys/dev/bwi/bwirf.c +++ sys/dev/bwi/bwirf.c @@ -1260,7 +1260,6 @@ bwi_rf_lo_update_11g(struct bwi_mac *mac) { struct bwi_softc *sc = mac->mac_sc; - struct ifnet *ifp = sc->sc_ifp; struct bwi_rf *rf = &mac->mac_rf; struct bwi_phy *phy = &mac->mac_phy; struct bwi_tpctl *tpctl = &mac->mac_tpctl; @@ -1329,7 +1328,7 @@ PHY_WRITE(mac, 0x812, 0xb2); } - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & BWI_F_RUNNING) == 0) tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac); PHY_WRITE(mac, 0x80f, 0x8078); @@ -1352,7 +1351,7 @@ PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0); } - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & BWI_F_RUNNING) == 0) tpctl = NULL; bwi_rf_lo_adjust(mac, tpctl); @@ -1462,7 +1461,7 @@ static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] = { 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 }; - struct ifnet *ifp = mac->mac_sc->sc_ifp; + struct bwi_softc *sc = mac->mac_sc; struct bwi_rf_lo lo_save, *lo; uint8_t devi_ctrl = 0; int idx, adj_rf7a = 0; @@ -1476,7 +1475,7 @@ for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) { uint16_t tp_ctrl2, rf7a; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { if (idx == 0) { bzero(&lo_save, sizeof(lo_save)); } else if (init_rf_atten < 0) { Index: sys/dev/bwi/if_bwi.c =================================================================== --- sys/dev/bwi/if_bwi.c +++ sys/dev/bwi/if_bwi.c @@ -102,10 +102,10 @@ const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void bwi_vap_delete(struct ieee80211vap *); -static void bwi_init(void *); -static int bwi_ioctl(struct ifnet *, u_long, caddr_t); -static void bwi_start(struct ifnet *); -static void bwi_start_locked(struct ifnet *); +static void bwi_init(struct bwi_softc *); +static void bwi_parent(struct ieee80211com *); +static int bwi_transmit(struct ieee80211com *, struct mbuf *); +static void bwi_start_locked(struct bwi_softc *); static int bwi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void bwi_watchdog(void *); @@ -352,14 +352,12 @@ int bwi_attach(struct bwi_softc *sc) { - struct ieee80211com *ic; + struct ieee80211com *ic = &sc->sc_ic; device_t dev = sc->sc_dev; - struct ifnet *ifp; struct bwi_mac *mac; struct bwi_phy *phy; int i, error; uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; BWI_LOCK_INIT(sc); @@ -371,8 +369,8 @@ taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(dev)); TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc); - callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* * Initialize sysctl variables @@ -450,25 +448,6 @@ if (error) goto fail; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - error = ENOSPC; - goto fail; - } - ic = ifp->if_l2com; - - /* set these up early for if_printf use */ - 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 = bwi_init; - ifp->if_ioctl = bwi_ioctl; - ifp->if_start = bwi_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0); /* @@ -485,13 +464,13 @@ setbit(&bands, IEEE80211_MODE_11G); } - bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, macaddr); - if (IEEE80211_IS_MULTICAST(macaddr)) { - bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, macaddr); - if (IEEE80211_IS_MULTICAST(macaddr)) { + bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_macaddr); + if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) { + bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_macaddr); + if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) { device_printf(dev, "invalid MAC address: %6D\n", - macaddr, ":"); + ic->ic_macaddr, ":"); } } } else if (phy->phy_mode == IEEE80211_MODE_11A) { @@ -510,7 +489,6 @@ /* XXX use locale */ ieee80211_init_channels(ic, NULL, &bands); - ic->ic_ifp = ifp; ic->ic_softc = sc; ic->ic_name = device_get_nameunit(dev); ic->ic_caps = IEEE80211_C_STA | @@ -520,7 +498,7 @@ IEEE80211_C_BGSCAN | IEEE80211_C_MONITOR; ic->ic_opmode = IEEE80211_M_STA; - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_headroom = sizeof(struct bwi_txbuf_hdr); @@ -532,6 +510,8 @@ ic->ic_scan_start = bwi_scan_start; ic->ic_scan_end = bwi_scan_end; ic->ic_set_channel = bwi_set_channel; + ic->ic_transmit = bwi_transmit; + ic->ic_parent = bwi_parent; sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); @@ -577,8 +557,7 @@ int bwi_detach(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int i; bwi_stop(sc, 1); @@ -590,7 +569,6 @@ for (i = 0; i < sc->sc_nmac; ++i) bwi_mac_detach(&sc->sc_mac[i]); bwi_dma_free(sc); - if_free(ifp); taskqueue_free(sc->sc_tq); BWI_LOCK_DESTROY(sc); @@ -609,14 +587,11 @@ if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ return NULL; - bvp = (struct bwi_vap *) malloc(sizeof(struct bwi_vap), - M_80211_VAP, M_WAITOK | M_ZERO); - if (bvp == NULL) - return NULL; + bvp = malloc(sizeof(struct bwi_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &bvp->bv_vap; /* enable s/w bmiss handling for sta mode */ ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + flags | IEEE80211_CLONE_NOBEACONS, bssid); /* override default methods */ bvp->bv_newstate = vap->iv_newstate; @@ -627,7 +602,8 @@ ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status, + mac); ic->ic_opmode = opmode; return vap; } @@ -651,9 +627,8 @@ void bwi_resume(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) bwi_init(sc); } @@ -1217,27 +1192,26 @@ } static void -bwi_init(void *xsc) +bwi_init(struct bwi_softc *sc) { - struct bwi_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; BWI_LOCK(sc); bwi_init_statechg(sc, 1); BWI_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & BWI_F_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } static void bwi_init_statechg(struct bwi_softc *sc, int statechg) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; int error; + BWI_ASSERT_LOCKED(sc); + bwi_stop_locked(sc, statechg); bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); @@ -1247,20 +1221,21 @@ mac = &sc->sc_mac[0]; error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL); if (error) { - if_printf(ifp, "%s: error %d on regwin switch\n", + device_printf(sc->sc_dev, "%s: error %d on regwin switch\n", __func__, error); goto bad; } error = bwi_mac_init(mac); if (error) { - if_printf(ifp, "%s: error %d on MAC init\n", __func__, error); + device_printf(sc->sc_dev, "%s: error %d on MAC init\n", + __func__, error); goto bad; } bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN); bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */ - bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, IF_LLADDR(ifp)); + bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, sc->sc_ic.ic_macaddr); bwi_mac_reset_hwkeys(mac); @@ -1278,7 +1253,8 @@ CSR_READ_4(sc, BWI_TXSTATUS1); } if (i == NRETRY) - if_printf(ifp, "%s: can't drain TX status\n", __func__); + device_printf(sc->sc_dev, + "%s: can't drain TX status\n", __func__); #undef NRETRY } @@ -1288,14 +1264,14 @@ /* Start MAC */ error = bwi_mac_start(mac); if (error) { - if_printf(ifp, "%s: error %d starting MAC\n", __func__, error); + device_printf(sc->sc_dev, "%s: error %d starting MAC\n", + __func__, error); goto bad; } /* Clear stop flag before enabling interrupt */ sc->sc_flags &= ~BWI_F_STOP; - - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= BWI_F_RUNNING; callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc); /* Enable intrs */ @@ -1305,135 +1281,110 @@ bwi_stop_locked(sc, 1); } -static int -bwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +bwi_parent(struct ieee80211com *ic) { -#define IS_RUNNING(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - struct bwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct bwi_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - BWI_LOCK(sc); - if (IS_RUNNING(ifp)) { - struct bwi_mac *mac; - int promisc = -1; - - KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, - ("current regwin type %d", - sc->sc_cur_regwin->rw_type)); - mac = (struct bwi_mac *)sc->sc_cur_regwin; - - if ((ifp->if_flags & IFF_PROMISC) && - (sc->sc_flags & BWI_F_PROMISC) == 0) { - promisc = 1; - sc->sc_flags |= BWI_F_PROMISC; - } else if ((ifp->if_flags & IFF_PROMISC) == 0 && - (sc->sc_flags & BWI_F_PROMISC)) { - promisc = 0; - sc->sc_flags &= ~BWI_F_PROMISC; - } + BWI_LOCK(sc); + if (ic->ic_nrunning > 0) { + struct bwi_mac *mac; + int promisc = -1; - if (promisc >= 0) - bwi_mac_set_promisc(mac, promisc); - } + KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, + ("current regwin type %d", + sc->sc_cur_regwin->rw_type)); + mac = (struct bwi_mac *)sc->sc_cur_regwin; - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - bwi_init_statechg(sc, 1); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - bwi_stop_locked(sc, 1); + if (ic->ic_promisc > 0 && (sc->sc_flags & BWI_F_PROMISC) == 0) { + promisc = 1; + sc->sc_flags |= BWI_F_PROMISC; + } else if (ic->ic_promisc == 0 && + (sc->sc_flags & BWI_F_PROMISC) != 0) { + promisc = 0; + sc->sc_flags &= ~BWI_F_PROMISC; + } + + if (promisc >= 0) + bwi_mac_set_promisc(mac, promisc); + } + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { + bwi_init_statechg(sc, 1); + startall = 1; } - BWI_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; -#undef IS_RUNNING + } else if (sc->sc_flags & BWI_F_RUNNING) + bwi_stop_locked(sc, 1); + BWI_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } -static void -bwi_start(struct ifnet *ifp) +static int +bwi_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct bwi_softc *sc = ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; + int error; BWI_LOCK(sc); - bwi_start_locked(ifp); + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { + BWI_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + BWI_UNLOCK(sc); + return (error); + } + bwi_start_locked(sc); BWI_UNLOCK(sc); + return (0); } static void -bwi_start_locked(struct ifnet *ifp) +bwi_start_locked(struct bwi_softc *sc) { - struct bwi_softc *sc = ifp->if_softc; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct ieee80211_frame *wh; struct ieee80211_node *ni; - struct ieee80211_key *k; struct mbuf *m; int trans, idx; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - return; + BWI_ASSERT_LOCKED(sc); trans = 0; idx = tbd->tbd_idx; - while (tbd->tbd_buf[idx].tb_mbuf == NULL) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ - if (m == NULL) - break; - + while (tbd->tbd_buf[idx].tb_mbuf == NULL && + tbd->tbd_used + BWI_TX_NSPRDESC < BWI_TX_NDESC && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; wh = mtod(m, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { - k = ieee80211_crypto_encap(ni, m); - if (k == NULL) { - ieee80211_free_node(ni); - m_freem(m); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - continue; - } + if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0 && + ieee80211_crypto_encap(ni, m) == NULL) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); + ieee80211_free_node(ni); + m_freem(m); + continue; } - wh = NULL; /* Catch any invalid use */ - if (bwi_encap(sc, idx, m, ni) != 0) { /* 'm' is freed in bwi_encap() if we reach here */ - if (ni != NULL) + if (ni != NULL) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + } else + counter_u64_add(sc->sc_ic.ic_oerrors, 1); continue; } - trans = 1; tbd->tbd_used++; idx = (idx + 1) % BWI_TX_NDESC; - - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - - if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } } - tbd->tbd_idx = idx; + tbd->tbd_idx = idx; if (trans) sc->sc_tx_timer = 5; } @@ -1443,13 +1394,12 @@ const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct bwi_softc *sc = ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; /* XXX wme? */ struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; int idx, error; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + if ((sc->sc_flags & BWI_F_RUNNING) == 0) { ieee80211_free_node(ni); m_freem(m); return ENETDOWN; @@ -1472,16 +1422,12 @@ error = bwi_encap_raw(sc, idx, m, ni, params); } if (error == 0) { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - if (++tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + tbd->tbd_used++; tbd->tbd_idx = (idx + 1) % BWI_TX_NDESC; sc->sc_tx_timer = 5; - } else { + } else /* NB: m is reclaimed on encap failure */ ieee80211_free_node(ni); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); - } BWI_UNLOCK(sc); return error; } @@ -1490,14 +1436,12 @@ bwi_watchdog(void *arg) { struct bwi_softc *sc; - struct ifnet *ifp; sc = arg; - ifp = sc->sc_ifp; BWI_ASSERT_LOCKED(sc); if (sc->sc_tx_timer != 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "watchdog timeout\n"); - if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); + device_printf(sc->sc_dev, "watchdog timeout\n"); + counter_u64_add(sc->sc_ic.ic_oerrors, 1); taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task); } callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc); @@ -1514,7 +1458,6 @@ static void bwi_stop_locked(struct bwi_softc *sc, int statechg) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; int i, error, pwr_off = 0; @@ -1525,7 +1468,7 @@ sc->sc_led_blinking = 0; sc->sc_flags |= BWI_F_STOP; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_flags & BWI_F_RUNNING) { KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, ("current regwin type %d", sc->sc_cur_regwin->rw_type)); mac = (struct bwi_mac *)sc->sc_cur_regwin; @@ -1557,14 +1500,13 @@ sc->sc_tx_timer = 0; callout_stop(&sc->sc_watchdog_timer); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~BWI_F_RUNNING; } void bwi_intr(void *xsc) { struct bwi_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; uint32_t intr_status; uint32_t txrx_intr_status[BWI_TXRX_NRING]; @@ -1572,7 +1514,7 @@ BWI_LOCK(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || + if ((sc->sc_flags & BWI_F_RUNNING) == 0 || (sc->sc_flags & BWI_F_STOP)) { BWI_UNLOCK(sc); return; @@ -1615,7 +1557,7 @@ i, txrx_intr_status[i]); if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) { - if_printf(ifp, + device_printf(sc->sc_dev, "%s: intr fatal TX/RX (%d) error 0x%08x\n", __func__, i, txrx_intr_status[i]); txrx_error = 1; @@ -1653,7 +1595,8 @@ */ if (intr_status & BWI_INTR_PHY_TXERR) { if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) { - if_printf(ifp, "%s: intr PHY TX error\n", __func__); + device_printf(sc->sc_dev, "%s: intr PHY TX error\n", + __func__); taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task); BWI_UNLOCK(sc); return; @@ -1668,7 +1611,7 @@ bwi_mac_config_ps(mac); if (intr_status & BWI_INTR_EO_ATIM) - if_printf(ifp, "EO_ATIM\n"); + device_printf(sc->sc_dev, "EO_ATIM\n"); if (intr_status & BWI_INTR_PMQ) { for (;;) { @@ -1679,7 +1622,7 @@ } if (intr_status & BWI_INTR_NOISE) - if_printf(ifp, "intr noise\n"); + device_printf(sc->sc_dev, "intr noise\n"); if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) { rx_data = sc->sc_rxeof(sc); @@ -1728,7 +1671,7 @@ static void bwi_scan_start(struct ieee80211com *ic) { - struct bwi_softc *sc = ic->ic_ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; BWI_LOCK(sc); /* Enable MAC beacon promiscuity */ @@ -1739,7 +1682,7 @@ static void bwi_set_channel(struct ieee80211com *ic) { - struct bwi_softc *sc = ic->ic_ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; struct ieee80211_channel *c = ic->ic_curchan; struct bwi_mac *mac; @@ -1765,7 +1708,7 @@ static void bwi_scan_end(struct ieee80211com *ic) { - struct bwi_softc *sc = ic->ic_ifp->if_softc; + struct bwi_softc *sc = ic->ic_softc; BWI_LOCK(sc); CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN); @@ -1777,9 +1720,8 @@ { struct bwi_vap *bvp = BWI_VAP(vap); struct ieee80211com *ic= vap->iv_ic; - struct ifnet *ifp = ic->ic_ifp; + struct bwi_softc *sc = ic->ic_softc; enum ieee80211_state ostate = vap->iv_state; - struct bwi_softc *sc = ifp->if_softc; struct bwi_mac *mac; int error; @@ -2625,8 +2567,7 @@ { struct bwi_ring_data *rd = &sc->sc_rx_rdata; struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int idx, rx_data = 0; idx = rbd->rbd_idx; @@ -2645,7 +2586,7 @@ BUS_DMASYNC_POSTREAD); if (bwi_newbuf(sc, idx, 0)) { - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + counter_u64_add(ic->ic_ierrors, 1); goto next; } @@ -2659,9 +2600,10 @@ buflen = le16toh(hdr->rxh_buflen); if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { - if_printf(ifp, "%s: zero length data, hdr_extra %d\n", - __func__, hdr_extra); - if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); + device_printf(sc->sc_dev, + "%s: zero length data, hdr_extra %d\n", + __func__, hdr_extra); + counter_u64_add(ic->ic_ierrors, 1); m_freem(m); goto next; } @@ -2670,7 +2612,6 @@ rssi = bwi_calc_rssi(sc, hdr); noise = bwi_calc_noise(sc); - m->m_pkthdr.rcvif = ifp; m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); m_adj(m, sizeof(*hdr) + wh_ofs); @@ -2804,7 +2745,6 @@ { struct bwi_ring_data *rd; struct bwi_txbuf_data *tbd; - struct ifnet *ifp = sc->sc_ifp; uint32_t state, val; int i; @@ -2825,8 +2765,9 @@ DELAY(1000); } if (i == NRETRY) { - if_printf(ifp, "%s: wait for TX ring(%d) stable timed out\n", - __func__, ring_idx); + device_printf(sc->sc_dev, + "%s: wait for TX ring(%d) stable timed out\n", + __func__, ring_idx); } CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0); @@ -2839,7 +2780,7 @@ DELAY(1000); } if (i == NRETRY) - if_printf(ifp, "%s: reset TX ring (%d) timed out\n", + device_printf(sc->sc_dev, "%s: reset TX ring (%d) timed out\n", __func__, ring_idx); #undef NRETRY @@ -2947,8 +2888,7 @@ struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; @@ -3024,7 +2964,8 @@ */ M_PREPEND(m, sizeof(*hdr), M_NOWAIT); if (m == NULL) { - if_printf(ifp, "%s: prepend TX header failed\n", __func__); + device_printf(sc->sc_dev, "%s: prepend TX header failed\n", + __func__); return ENOBUFS; } hdr = mtod(m, struct bwi_txbuf_hdr *); @@ -3073,7 +3014,7 @@ error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m, bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); if (error && error != EFBIG) { - if_printf(ifp, "%s: can't load TX buffer (1) %d\n", + device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n", __func__, error); goto back; } @@ -3083,8 +3024,8 @@ m_new = m_defrag(m, M_NOWAIT); if (m_new == NULL) { - if_printf(ifp, "%s: can't defrag TX buffer\n", - __func__); + device_printf(sc->sc_dev, + "%s: can't defrag TX buffer\n", __func__); error = ENOBUFS; goto back; } else { @@ -3095,7 +3036,8 @@ bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); if (error) { - if_printf(ifp, "%s: can't load TX buffer (2) %d\n", + device_printf(sc->sc_dev, + "%s: can't load TX buffer (2) %d\n", __func__, error); goto back; } @@ -3137,7 +3079,6 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; @@ -3204,7 +3145,8 @@ */ M_PREPEND(m, sizeof(*hdr), M_NOWAIT); if (m == NULL) { - if_printf(ifp, "%s: prepend TX header failed\n", __func__); + device_printf(sc->sc_dev, "%s: prepend TX header failed\n", + __func__); return ENOBUFS; } hdr = mtod(m, struct bwi_txbuf_hdr *); @@ -3252,14 +3194,15 @@ struct mbuf *m_new; if (error != EFBIG) { - if_printf(ifp, "%s: can't load TX buffer (1) %d\n", + device_printf(sc->sc_dev, + "%s: can't load TX buffer (1) %d\n", __func__, error); goto back; } m_new = m_defrag(m, M_NOWAIT); if (m_new == NULL) { - if_printf(ifp, "%s: can't defrag TX buffer\n", - __func__); + device_printf(sc->sc_dev, + "%s: can't defrag TX buffer\n", __func__); error = ENOBUFS; goto back; } @@ -3268,7 +3211,8 @@ bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT); if (error) { - if_printf(ifp, "%s: can't load TX buffer (2) %d\n", + device_printf(sc->sc_dev, + "%s: can't load TX buffer (2) %d\n", __func__, error); goto back; } @@ -3312,7 +3256,6 @@ static void bwi_txeof_status32(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; uint32_t val, ctrl_base; int end_idx; @@ -3327,8 +3270,7 @@ CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX, end_idx * sizeof(struct bwi_desc32)); - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) - ifp->if_start(ifp); + bwi_start_locked(sc); } static void @@ -3340,7 +3282,6 @@ static void _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_txbuf_data *tbd; struct bwi_txbuf *tb; int ring_idx, buf_idx; @@ -3348,7 +3289,7 @@ struct ieee80211vap *vap; if (tx_id == 0) { - if_printf(ifp, "%s: zero tx id\n", __func__); + device_printf(sc->sc_dev, "%s: zero tx id\n", __func__); return; } @@ -3404,8 +3345,6 @@ if (tbd->tbd_used == 0) sc->sc_tx_timer = 0; - - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void @@ -3437,7 +3376,6 @@ static void bwi_txeof(struct bwi_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; for (;;) { uint32_t tx_status0, tx_status1; @@ -3460,8 +3398,7 @@ data_txcnt); } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) - ifp->if_start(ifp); + bwi_start_locked(sc); } static int @@ -3709,7 +3646,6 @@ static void bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid) { - struct ifnet *ifp = sc->sc_ifp; struct bwi_mac *mac; struct bwi_myaddr_bssid buf; const uint8_t *p; @@ -3722,7 +3658,7 @@ bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid); - bcopy(IF_LLADDR(ifp), buf.myaddr, sizeof(buf.myaddr)); + bcopy(sc->sc_ic.ic_macaddr, buf.myaddr, sizeof(buf.myaddr)); bcopy(bssid, buf.bssid, sizeof(buf.bssid)); n = sizeof(buf) / sizeof(val); @@ -3745,7 +3681,7 @@ struct bwi_mac *mac; BWI_LOCK(sc); - if (ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (sc->sc_flags & BWI_F_RUNNING) { DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__); KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, @@ -3761,16 +3697,12 @@ bwi_calibrate(void *xsc) { struct bwi_softc *sc = xsc; -#ifdef INVARIANTS - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; -#endif struct bwi_mac *mac; BWI_ASSERT_LOCKED(sc); - KASSERT(ic->ic_opmode != IEEE80211_M_MONITOR, - ("opmode %d", ic->ic_opmode)); + KASSERT(sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR, + ("opmode %d", sc->sc_ic.ic_opmode)); KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, ("current regwin type %d", sc->sc_cur_regwin->rw_type)); @@ -3912,8 +3844,7 @@ static void bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t val; int i; @@ -3922,7 +3853,7 @@ sc->sc_led_blinking = 0; } - if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + if ((sc->sc_flags & BWI_F_RUNNING) == 0) return; val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL); @@ -4050,13 +3981,12 @@ bwi_restart(void *xsc, int pending) { struct bwi_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if_printf(ifp, "%s begin, help!\n", __func__); + device_printf(sc->sc_dev, "%s begin, help!\n", __func__); BWI_LOCK(sc); - bwi_init_statechg(xsc, 0); + bwi_init_statechg(sc, 0); #if 0 - bwi_start_locked(ifp); + bwi_start_locked(sc); #endif BWI_UNLOCK(sc); } Index: sys/dev/bwi/if_bwivar.h =================================================================== --- sys/dev/bwi/if_bwivar.h +++ sys/dev/bwi/if_bwivar.h @@ -541,10 +541,11 @@ #define BWI_VAP(vap) ((struct bwi_vap *)(vap)) struct bwi_softc { - struct ifnet *sc_ifp; uint32_t sc_flags; /* BWI_F_ */ device_t sc_dev; struct mtx sc_mtx; + struct ieee80211com sc_ic; + struct mbufq sc_snd; int sc_invalid; uint32_t sc_cap; /* BWI_CAP_ */ @@ -647,6 +648,7 @@ #define BWI_F_BUS_INITED 0x1 #define BWI_F_PROMISC 0x2 #define BWI_F_STOP 0x4 +#define BWI_F_RUNNING 0x8 #define BWI_DBG_MAC 0x00000001 #define BWI_DBG_RF 0x00000002 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 #include #include - #include #include @@ -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 '?':