You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
6.3 KiB
188 lines
6.3 KiB
16 years ago
|
--- a/net80211/ieee80211_beacon.c
|
||
|
+++ b/net80211/ieee80211_beacon.c
|
||
|
@@ -224,18 +224,18 @@ ieee80211_beacon_alloc(struct ieee80211_
|
||
|
pktlen = 8 /* time stamp */
|
||
|
+ sizeof(u_int16_t) /* beacon interval */
|
||
|
+ sizeof(u_int16_t) /* capability information */
|
||
|
- + 2 + ni->ni_esslen /* ssid */
|
||
|
+ + 2 + IEEE80211_NWID_LEN /* ssid */
|
||
|
+ 2 + IEEE80211_RATE_SIZE /* supported rates */
|
||
|
+ 7 /* FH/DS parameters max(7,3) */
|
||
|
- + 2 + 4 + vap->iv_tim_len /* IBSS/TIM parameter set*/
|
||
|
+ + sizeof(struct ieee80211_tim_ie) + 128 /* IBSS/TIM parameter set*/
|
||
|
+ ic->ic_country_ie.country_len + 2 /* country code */
|
||
|
+ 3 /* power constraint */
|
||
|
+ 5 /* channel switch announcement */
|
||
|
+ 3 /* ERP */
|
||
|
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) /* Ext. Supp. Rates */
|
||
|
- + (vap->iv_caps & IEEE80211_C_WME ? /* WME */
|
||
|
+ + (ic->ic_caps & IEEE80211_C_WME ? /* WME */
|
||
|
sizeof(struct ieee80211_wme_param) : 0)
|
||
|
- + (vap->iv_caps & IEEE80211_C_WPA ? /* WPA 1+2 */
|
||
|
+ + (ic->ic_caps & IEEE80211_C_WPA ? /* WPA 1+2 */
|
||
|
2 * sizeof(struct ieee80211_ie_wpa) : 0)
|
||
|
+ sizeof(struct ieee80211_ie_athAdvCap)
|
||
|
#ifdef ATH_SUPERG_XR
|
||
|
@@ -290,17 +290,26 @@ ieee80211_beacon_update(struct ieee80211
|
||
|
IEEE80211_LOCK_IRQ(ic);
|
||
|
|
||
|
/* Check if we need to change channel right now */
|
||
|
- if ((ic->ic_flags & IEEE80211_F_DOTH) &&
|
||
|
- (vap->iv_flags & IEEE80211_F_CHANSWITCH)) {
|
||
|
- struct ieee80211_channel *c =
|
||
|
+ if (ic->ic_flags & IEEE80211_F_CHANSWITCH) {
|
||
|
+ struct ieee80211_channel *c =
|
||
|
ieee80211_doth_findchan(vap, ic->ic_chanchange_chan);
|
||
|
-
|
||
|
- if (!vap->iv_chanchange_count && !c) {
|
||
|
- vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
|
||
|
- ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
|
||
|
- } else if (vap->iv_chanchange_count &&
|
||
|
- ((!ic->ic_chanchange_tbtt) ||
|
||
|
- (vap->iv_chanchange_count == ic->ic_chanchange_tbtt))) {
|
||
|
+ struct ieee80211vap *avp;
|
||
|
+ int do_switch = 1;
|
||
|
+
|
||
|
+ TAILQ_FOREACH(avp, &ic->ic_vaps, iv_next) {
|
||
|
+ if (!(avp->iv_flags & IEEE80211_F_CHANSWITCH))
|
||
|
+ continue;
|
||
|
+
|
||
|
+ do_switch = 0;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ if (vap->iv_flags & IEEE80211_F_CHANSWITCH) {
|
||
|
+ if (vap->iv_chanchange_count-- <= 1) {
|
||
|
+ vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
|
||
|
+ vap->iv_chanchange_count = 0;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if (do_switch) {
|
||
|
u_int8_t *frm;
|
||
|
|
||
|
IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||
|
@@ -316,16 +325,7 @@ ieee80211_beacon_update(struct ieee80211
|
||
|
} else
|
||
|
ic->ic_bsschan = c;
|
||
|
|
||
|
- skb_pull(skb, sizeof(struct ieee80211_frame));
|
||
|
- skb_trim(skb, 0);
|
||
|
- frm = skb->data;
|
||
|
- skb_put(skb, ieee80211_beacon_init(ni, bo, frm) - frm);
|
||
|
- skb_push(skb, sizeof(struct ieee80211_frame));
|
||
|
-
|
||
|
- vap->iv_chanchange_count = 0;
|
||
|
- vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
|
||
|
ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
|
||
|
-
|
||
|
/* NB: Only for the first VAP to get here, and when we
|
||
|
* have a valid channel to which to change. */
|
||
|
if (c && (ic->ic_curchan != c)) {
|
||
|
@@ -488,22 +488,20 @@ ieee80211_beacon_update(struct ieee80211
|
||
|
|
||
|
if (IEEE80211_IS_MODE_BEACON(vap->iv_opmode)) {
|
||
|
|
||
|
- if ((ic->ic_flags & IEEE80211_F_DOTH) &&
|
||
|
- (ic->ic_flags & IEEE80211_F_CHANSWITCH)) {
|
||
|
+ if (ic->ic_flags & IEEE80211_F_CHANSWITCH) {
|
||
|
struct ieee80211_ie_csa *csa_ie =
|
||
|
(struct ieee80211_ie_csa *)bo->bo_chanswitch;
|
||
|
|
||
|
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||
|
+ if (csa_ie->csa_len == 0) {
|
||
|
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||
|
"%s: Sending 802.11h chanswitch IE: "
|
||
|
"%d/%d\n", __func__,
|
||
|
ic->ic_chanchange_chan,
|
||
|
ic->ic_chanchange_tbtt);
|
||
|
- if (!vap->iv_chanchange_count) {
|
||
|
- vap->iv_flags |= IEEE80211_F_CHANSWITCH;
|
||
|
|
||
|
/* copy out trailer to open up a slot */
|
||
|
memmove(bo->bo_chanswitch + sizeof(*csa_ie),
|
||
|
- bo->bo_chanswitch,
|
||
|
+ bo->bo_chanswitch,
|
||
|
bo->bo_chanswitch_trailerlen);
|
||
|
|
||
|
/* add ie in opened slot */
|
||
|
@@ -523,17 +521,15 @@ ieee80211_beacon_update(struct ieee80211
|
||
|
bo->bo_ath_caps += sizeof(*csa_ie);
|
||
|
bo->bo_xr += sizeof(*csa_ie);
|
||
|
|
||
|
- /* indicate new beacon length so other layers
|
||
|
+ /* indicate new beacon length so other layers
|
||
|
* may manage memory */
|
||
|
skb_put(skb, sizeof(*csa_ie));
|
||
|
len_changed = 1;
|
||
|
- } else if(csa_ie->csa_count)
|
||
|
- csa_ie->csa_count--;
|
||
|
-
|
||
|
- vap->iv_chanchange_count++;
|
||
|
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||
|
- "%s: CHANSWITCH IE, change in %d TBTT\n",
|
||
|
- __func__, csa_ie->csa_count);
|
||
|
+
|
||
|
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
|
||
|
+ "%s: CHANSWITCH IE, change in %d TBTT\n",
|
||
|
+ __func__, csa_ie->csa_count);
|
||
|
+ }
|
||
|
}
|
||
|
#ifdef ATH_SUPERG_XR
|
||
|
if (vap->iv_flags & IEEE80211_F_XRUPDATE) {
|
||
|
--- a/net80211/ieee80211_wireless.c
|
||
|
+++ b/net80211/ieee80211_wireless.c
|
||
|
@@ -699,39 +699,11 @@ ieee80211_ioctl_siwfreq(struct net_devic
|
||
|
if (c == NULL) /* no channel */
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
- /*
|
||
|
- * Fine tune channel selection based on desired mode:
|
||
|
- * if 11b is requested, find the 11b version of any
|
||
|
- * 11g channel returned,
|
||
|
- * if static turbo, find the turbo version of any
|
||
|
- * 11a channel return,
|
||
|
- * otherwise we should be ok with what we've got.
|
||
|
- */
|
||
|
- switch (vap->iv_des_mode) {
|
||
|
- case IEEE80211_MODE_11B:
|
||
|
- if (IEEE80211_IS_CHAN_ANYG(c)) {
|
||
|
- c2 = findchannel(ic, i, IEEE80211_MODE_11B);
|
||
|
- /* NB: should not happen, =>'s 11g w/o 11b */
|
||
|
- if (c2 != NULL)
|
||
|
- c = c2;
|
||
|
- }
|
||
|
- break;
|
||
|
- case IEEE80211_MODE_TURBO_A:
|
||
|
- if (IEEE80211_IS_CHAN_A(c)) {
|
||
|
- c2 = findchannel(ic, i, IEEE80211_MODE_TURBO_A);
|
||
|
- if (c2 != NULL)
|
||
|
- c = c2;
|
||
|
- }
|
||
|
- break;
|
||
|
- default: /* NB: no static turboG */
|
||
|
- break;
|
||
|
- }
|
||
|
+
|
||
|
if (ieee80211_check_mode_consistency(ic, vap->iv_des_mode, c)) {
|
||
|
if (vap->iv_opmode == IEEE80211_M_HOSTAP)
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
- if ((vap->iv_state == IEEE80211_S_RUN) && (c == vap->iv_des_chan))
|
||
|
- return 0; /* no change, return */
|
||
|
|
||
|
/* Don't allow to change to channel with radar found */
|
||
|
if (c->ic_flags & IEEE80211_CHAN_RADAR)
|
||
|
@@ -4625,7 +4597,13 @@ static void
|
||
|
pre_announced_chanswitch(struct net_device *dev, u_int32_t channel, u_int32_t tbtt) {
|
||
|
struct ieee80211vap *vap = dev->priv;
|
||
|
struct ieee80211com *ic = vap->iv_ic;
|
||
|
+ struct ieee80211vap *avp;
|
||
|
+
|
||
|
/* now flag the beacon update to include the channel switch IE */
|
||
|
+ TAILQ_FOREACH(avp, &ic->ic_vaps, iv_next) {
|
||
|
+ avp->iv_flags |= IEEE80211_F_CHANSWITCH;
|
||
|
+ avp->iv_chanchange_count = tbtt;
|
||
|
+ }
|
||
|
ic->ic_flags |= IEEE80211_F_CHANSWITCH;
|
||
|
ic->ic_chanchange_chan = channel;
|
||
|
ic->ic_chanchange_tbtt = tbtt;
|