madwifi: do not use turbo mode during ap mode autoselection unless specifically requested
[openwrt/svn-archive/archive.git] / 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 @@ -4625,7 +4597,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;