Root/package/madwifi/patches/415-chan_switch.patch

1--- a/net80211/ieee80211_beacon.c
2+++ b/net80211/ieee80211_beacon.c
3@@ -224,18 +224,18 @@ ieee80211_beacon_alloc(struct ieee80211_
4     pktlen = 8 /* time stamp */
5          + sizeof(u_int16_t) /* beacon interval */
6          + sizeof(u_int16_t) /* capability information */
7- + 2 + ni->ni_esslen /* ssid */
8+ + 2 + IEEE80211_NWID_LEN /* ssid */
9          + 2 + IEEE80211_RATE_SIZE /* supported rates */
10          + 7 /* FH/DS parameters max(7,3) */
11- + 2 + 4 + vap->iv_tim_len /* IBSS/TIM parameter set*/
12+ + sizeof(struct ieee80211_tim_ie) + 128 /* IBSS/TIM parameter set*/
13          + ic->ic_country_ie.country_len + 2 /* country code */
14          + 3 /* power constraint */
15          + 5 /* channel switch announcement */
16          + 3 /* ERP */
17          + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) /* Ext. Supp. Rates */
18- + (vap->iv_caps & IEEE80211_C_WME ? /* WME */
19+ + (ic->ic_caps & IEEE80211_C_WME ? /* WME */
20             sizeof(struct ieee80211_wme_param) : 0)
21- + (vap->iv_caps & IEEE80211_C_WPA ? /* WPA 1+2 */
22+ + (ic->ic_caps & IEEE80211_C_WPA ? /* WPA 1+2 */
23             2 * sizeof(struct ieee80211_ie_wpa) : 0)
24          + sizeof(struct ieee80211_ie_athAdvCap)
25 #ifdef ATH_SUPERG_XR
26@@ -290,17 +290,26 @@ ieee80211_beacon_update(struct ieee80211
27     IEEE80211_LOCK_IRQ(ic);
28 
29     /* Check if we need to change channel right now */
30- if ((ic->ic_flags & IEEE80211_F_DOTH) &&
31- (vap->iv_flags & IEEE80211_F_CHANSWITCH)) {
32- struct ieee80211_channel *c =
33+ if (ic->ic_flags & IEEE80211_F_CHANSWITCH) {
34+ struct ieee80211_channel *c =
35             ieee80211_doth_findchan(vap, ic->ic_chanchange_chan);
36-
37- if (!vap->iv_chanchange_count && !c) {
38- vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
39- ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
40- } else if (vap->iv_chanchange_count &&
41- ((!ic->ic_chanchange_tbtt) ||
42- (vap->iv_chanchange_count == ic->ic_chanchange_tbtt))) {
43+ struct ieee80211vap *avp;
44+ int do_switch = 1;
45+
46+ TAILQ_FOREACH(avp, &ic->ic_vaps, iv_next) {
47+ if (!(avp->iv_flags & IEEE80211_F_CHANSWITCH))
48+ continue;
49+
50+ do_switch = 0;
51+ break;
52+ }
53+ if (vap->iv_flags & IEEE80211_F_CHANSWITCH) {
54+ if (vap->iv_chanchange_count-- <= 1) {
55+ vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
56+ vap->iv_chanchange_count = 0;
57+ }
58+ }
59+ if (do_switch) {
60             u_int8_t *frm;
61 
62             IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
63@@ -316,16 +325,7 @@ ieee80211_beacon_update(struct ieee80211
64             } else
65                 ic->ic_bsschan = c;
66 
67- skb_pull(skb, sizeof(struct ieee80211_frame));
68- skb_trim(skb, 0);
69- frm = skb->data;
70- skb_put(skb, ieee80211_beacon_init(ni, bo, frm) - frm);
71- skb_push(skb, sizeof(struct ieee80211_frame));
72-
73- vap->iv_chanchange_count = 0;
74- vap->iv_flags &= ~IEEE80211_F_CHANSWITCH;
75             ic->ic_flags &= ~IEEE80211_F_CHANSWITCH;
76-
77             /* NB: Only for the first VAP to get here, and when we
78              * have a valid channel to which to change. */
79             if (c && (ic->ic_curchan != c)) {
80@@ -488,22 +488,20 @@ ieee80211_beacon_update(struct ieee80211
81 
82     if (IEEE80211_IS_MODE_BEACON(vap->iv_opmode)) {
83 
84- if ((ic->ic_flags & IEEE80211_F_DOTH) &&
85- (ic->ic_flags & IEEE80211_F_CHANSWITCH)) {
86+ if (ic->ic_flags & IEEE80211_F_CHANSWITCH) {
87             struct ieee80211_ie_csa *csa_ie =
88                 (struct ieee80211_ie_csa *)bo->bo_chanswitch;
89 
90- IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
91+ if (csa_ie->csa_len == 0) {
92+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
93                     "%s: Sending 802.11h chanswitch IE: "
94                     "%d/%d\n", __func__,
95                     ic->ic_chanchange_chan,
96                     ic->ic_chanchange_tbtt);
97- if (!vap->iv_chanchange_count) {
98- vap->iv_flags |= IEEE80211_F_CHANSWITCH;
99 
100                 /* copy out trailer to open up a slot */
101                 memmove(bo->bo_chanswitch + sizeof(*csa_ie),
102- bo->bo_chanswitch,
103+ bo->bo_chanswitch,
104                     bo->bo_chanswitch_trailerlen);
105 
106                 /* add ie in opened slot */
107@@ -523,17 +521,15 @@ ieee80211_beacon_update(struct ieee80211
108                 bo->bo_ath_caps += sizeof(*csa_ie);
109                 bo->bo_xr += sizeof(*csa_ie);
110 
111- /* indicate new beacon length so other layers
112+ /* indicate new beacon length so other layers
113                  * may manage memory */
114                 skb_put(skb, sizeof(*csa_ie));
115                 len_changed = 1;
116- } else if(csa_ie->csa_count)
117- csa_ie->csa_count--;
118-
119- vap->iv_chanchange_count++;
120- IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
121- "%s: CHANSWITCH IE, change in %d TBTT\n",
122- __func__, csa_ie->csa_count);
123+
124+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_DOTH,
125+ "%s: CHANSWITCH IE, change in %d TBTT\n",
126+ __func__, csa_ie->csa_count);
127+ }
128         }
129 #ifdef ATH_SUPERG_XR
130         if (vap->iv_flags & IEEE80211_F_XRUPDATE) {
131--- a/net80211/ieee80211_wireless.c
132+++ b/net80211/ieee80211_wireless.c
133@@ -699,39 +699,11 @@ ieee80211_ioctl_siwfreq(struct net_devic
134             if (c == NULL) /* no channel */
135                 return -EINVAL;
136         }
137- /*
138- * Fine tune channel selection based on desired mode:
139- * if 11b is requested, find the 11b version of any
140- * 11g channel returned,
141- * if static turbo, find the turbo version of any
142- * 11a channel return,
143- * otherwise we should be ok with what we've got.
144- */
145- switch (vap->iv_des_mode) {
146- case IEEE80211_MODE_11B:
147- if (IEEE80211_IS_CHAN_ANYG(c)) {
148- c2 = findchannel(ic, i, IEEE80211_MODE_11B);
149- /* NB: should not happen, =>'s 11g w/o 11b */
150- if (c2 != NULL)
151- c = c2;
152- }
153- break;
154- case IEEE80211_MODE_TURBO_A:
155- if (IEEE80211_IS_CHAN_A(c)) {
156- c2 = findchannel(ic, i, IEEE80211_MODE_TURBO_A);
157- if (c2 != NULL)
158- c = c2;
159- }
160- break;
161- default: /* NB: no static turboG */
162- break;
163- }
164+
165         if (ieee80211_check_mode_consistency(ic, vap->iv_des_mode, c)) {
166             if (vap->iv_opmode == IEEE80211_M_HOSTAP)
167                 return -EINVAL;
168         }
169- if ((vap->iv_state == IEEE80211_S_RUN) && (c == vap->iv_des_chan))
170- return 0; /* no change, return */
171 
172         /* Don't allow to change to channel with radar found */
173         if (c->ic_flags & IEEE80211_CHAN_RADAR)
174@@ -4634,7 +4606,13 @@ static void
175 pre_announced_chanswitch(struct net_device *dev, u_int32_t channel, u_int32_t tbtt) {
176     struct ieee80211vap *vap = dev->priv;
177     struct ieee80211com *ic = vap->iv_ic;
178+ struct ieee80211vap *avp;
179+
180     /* now flag the beacon update to include the channel switch IE */
181+ TAILQ_FOREACH(avp, &ic->ic_vaps, iv_next) {
182+ avp->iv_flags |= IEEE80211_F_CHANSWITCH;
183+ avp->iv_chanchange_count = tbtt;
184+ }
185     ic->ic_flags |= IEEE80211_F_CHANSWITCH;
186     ic->ic_chanchange_chan = channel;
187     ic->ic_chanchange_tbtt = tbtt;
188

Archive Download this file



interactive