diff options
Diffstat (limited to 'sys/net80211/ieee80211_proto.c')
-rw-r--r-- | sys/net80211/ieee80211_proto.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 7adf044..01c60e1 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -122,23 +122,23 @@ null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, void ieee80211_proto_attach(struct ieee80211com *ic) { - uint8_t hdrlen; + struct ifnet *ifp = ic->ic_ifp; /* override the 802.3 setting */ - hdrlen = ic->ic_headroom + ifp->if_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(hdrlen) > max_linkhdr) { + if (ALIGN(ifp->if_hdrlen) > max_linkhdr) { /* XXX sanity check... */ - max_linkhdr = ALIGN(hdrlen); + max_linkhdr = ALIGN(ifp->if_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, ic); + TASK_INIT(&ic->ic_parent_task, 0, parent_updown, ifp); 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,10 +188,7 @@ ieee80211_proto_vattach(struct ieee80211vap *vap) int i; /* override the 802.3 setting */ - ifp->if_hdrlen = ic->ic_headroom - + sizeof(struct ieee80211_qosframe_addr4) - + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN - + IEEE80211_WEP_EXTIVLEN; + ifp->if_hdrlen = ic->ic_ifp->if_hdrlen; vap->iv_rtsthreshold = IEEE80211_RTS_DEFAULT; vap->iv_fragthreshold = IEEE80211_FRAG_DEFAULT; @@ -1158,9 +1155,9 @@ ieee80211_wme_updateparams(struct ieee80211vap *vap) static void parent_updown(void *arg, int npending) { - struct ieee80211com *ic = arg; + struct ifnet *parent = arg; - ic->ic_parent(ic); + parent->if_ioctl(parent, SIOCSIFFLAGS, NULL); } static void @@ -1227,6 +1224,7 @@ ieee80211_start_locked(struct ieee80211vap *vap) { struct ifnet *ifp = vap->iv_ifp; struct ieee80211com *ic = vap->iv_ic; + struct ifnet *parent = ic->ic_ifp; IEEE80211_LOCK_ASSERT(ic); @@ -1248,10 +1246,12 @@ ieee80211_start_locked(struct ieee80211vap *vap) * 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) { + if (ic->ic_nrunning++ == 0 && + (parent->if_drv_flags & IFF_DRV_RUNNING) == 0) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "%s: up parent %s\n", __func__, ic->ic_name); + "%s: up parent %s\n", __func__, parent->if_xname); + parent->if_flags |= IFF_UP; ieee80211_runtask(ic, &ic->ic_parent_task); return; } @@ -1260,7 +1260,8 @@ ieee80211_start_locked(struct ieee80211vap *vap) * If the parent is up and running, then kick the * 802.11 state machine as appropriate. */ - if (vap->iv_roaming != IEEE80211_ROAMING_MANUAL) { + if ((parent->if_drv_flags & IFF_DRV_RUNNING) && + vap->iv_roaming != IEEE80211_ROAMING_MANUAL) { if (vap->iv_opmode == IEEE80211_M_STA) { #if 0 /* XXX bypasses scan too easily; disable for now */ @@ -1343,6 +1344,7 @@ ieee80211_stop_locked(struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = vap->iv_ifp; + struct ifnet *parent = ic->ic_ifp; IEEE80211_LOCK_ASSERT(ic); @@ -1352,10 +1354,12 @@ ieee80211_stop_locked(struct ieee80211vap *vap) 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) { + if (--ic->ic_nrunning == 0 && + (parent->if_drv_flags & IFF_DRV_RUNNING)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE | IEEE80211_MSG_DEBUG, - "down parent %s\n", ic->ic_name); + "down parent %s\n", parent->if_xname); + parent->if_flags &= ~IFF_UP; ieee80211_runtask(ic, &ic->ic_parent_task); } } |