[package] e2fsprogs: fix blkid dependencies (#9377)
[openwrt.git] / package / mac80211 / patches / 310-ibss_ht.patch
1 --- a/include/net/cfg80211.h
2 +++ b/include/net/cfg80211.h
3 @@ -1038,6 +1038,7 @@ struct cfg80211_ibss_params {
4         u8 *ssid;
5         u8 *bssid;
6         struct ieee80211_channel *channel;
7 +       enum nl80211_channel_type channel_type;
8         u8 *ie;
9         u8 ssid_len, ie_len;
10         u16 beacon_interval;
11 @@ -2539,6 +2540,12 @@ struct cfg80211_bss *cfg80211_get_bss(st
12                                       const u8 *bssid,
13                                       const u8 *ssid, size_t ssid_len,
14                                       u16 capa_mask, u16 capa_val);
15 +struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
16 +                                         struct ieee80211_channel *channel,
17 +                                         const u8 *bssid,
18 +                                         const u8 *ssid, size_t ssid_len,
19 +                                         u16 capa_mask, u16 capa_val,
20 +                                      enum nl80211_channel_type channel_type);
21  static inline struct cfg80211_bss *
22  cfg80211_get_ibss(struct wiphy *wiphy,
23                   struct ieee80211_channel *channel,
24 --- a/net/mac80211/ieee80211_i.h
25 +++ b/net/mac80211/ieee80211_i.h
26 @@ -439,6 +439,7 @@ struct ieee80211_if_ibss {
27         u8 ssid_len, ie_len;
28         u8 *ie;
29         struct ieee80211_channel *channel;
30 +       enum nl80211_channel_type channel_type;
31  
32         unsigned long ibss_join_req;
33         /* probe response/beacon for IBSS */
34 @@ -1121,6 +1122,7 @@ void ieee80211_ibss_notify_scan_complete
35  void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
36  struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
37                                         u8 *bssid, u8 *addr, u32 supp_rates,
38 +                                       struct ieee80211_ht_cap *ht_cap,
39                                         gfp_t gfp);
40  int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
41                         struct cfg80211_ibss_params *params);
42 @@ -1373,6 +1375,12 @@ void ieee80211_recalc_smps(struct ieee80
43  size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
44                           const u8 *ids, int n_ids, size_t offset);
45  size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
46 +u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
47 +                              u16 cap);
48 +u8 *ieee80211_ie_build_ht_info(u8 *pos,
49 +                               struct ieee80211_sta_ht_cap *ht_cap,
50 +                               struct ieee80211_channel *channel,
51 +                               enum nl80211_channel_type channel_type);
52  
53  /* internal work items */
54  void ieee80211_work_init(struct ieee80211_local *local);
55 @@ -1401,6 +1409,8 @@ ieee80211_get_channel_mode(struct ieee80
56  bool ieee80211_set_channel_type(struct ieee80211_local *local,
57                                 struct ieee80211_sub_if_data *sdata,
58                                 enum nl80211_channel_type chantype);
59 +enum nl80211_channel_type ieee80211_ht_info_to_channel_type(
60 +                                       struct ieee80211_ht_info *ht_info);
61  
62  #ifdef CONFIG_MAC80211_NOINLINE
63  #define debug_noinline noinline
64 --- a/net/mac80211/util.c
65 +++ b/net/mac80211/util.c
66 @@ -1007,23 +1007,8 @@ int ieee80211_build_preq_ies(struct ieee
67                 offset = noffset;
68         }
69  
70 -       if (sband->ht_cap.ht_supported) {
71 -               u16 cap = sband->ht_cap.cap;
72 -               __le16 tmp;
73 -
74 -               *pos++ = WLAN_EID_HT_CAPABILITY;
75 -               *pos++ = sizeof(struct ieee80211_ht_cap);
76 -               memset(pos, 0, sizeof(struct ieee80211_ht_cap));
77 -               tmp = cpu_to_le16(cap);
78 -               memcpy(pos, &tmp, sizeof(u16));
79 -               pos += sizeof(u16);
80 -               *pos++ = sband->ht_cap.ampdu_factor |
81 -                        (sband->ht_cap.ampdu_density <<
82 -                               IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
83 -               memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
84 -               pos += sizeof(sband->ht_cap.mcs);
85 -               pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
86 -       }
87 +       if (sband->ht_cap.ht_supported)
88 +               pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap);
89  
90         /*
91          * If adding more here, adjust code in main.c
92 @@ -1464,3 +1449,100 @@ size_t ieee80211_ie_split_vendor(const u
93  
94         return pos;
95  }
96 +
97 +u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband,
98 +                              u16 cap)
99 +{
100 +       __le16 tmp;
101 +
102 +       *pos++ = WLAN_EID_HT_CAPABILITY;
103 +       *pos++ = sizeof(struct ieee80211_ht_cap);
104 +       memset(pos, 0, sizeof(struct ieee80211_ht_cap));
105 +
106 +       /* capability flags */
107 +       tmp = cpu_to_le16(cap);
108 +       memcpy(pos, &tmp, sizeof(u16));
109 +       pos += sizeof(u16);
110 +
111 +       /* AMPDU parameters */
112 +       *pos++ = sband->ht_cap.ampdu_factor |
113 +                (sband->ht_cap.ampdu_density <<
114 +                       IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
115 +
116 +       /* MCS set */
117 +       memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
118 +       pos += sizeof(sband->ht_cap.mcs);
119 +
120 +       /* extended capabilities */
121 +       pos += sizeof(__le16);
122 +
123 +       /* BF capabilities */
124 +       pos += sizeof(__le32);
125 +
126 +       /* antenna selection */
127 +       pos += sizeof(u8);
128 +
129 +       return pos;
130 +}
131 +
132 +u8 *ieee80211_ie_build_ht_info(u8 *pos,
133 +                               struct ieee80211_sta_ht_cap *ht_cap,
134 +                               struct ieee80211_channel *channel,
135 +                               enum nl80211_channel_type channel_type)
136 +{
137 +       struct ieee80211_ht_info *ht_info;
138 +       /* Build HT Information */
139 +       *pos++ = WLAN_EID_HT_INFORMATION;
140 +       *pos++ = sizeof(struct ieee80211_ht_info);
141 +       ht_info = (struct ieee80211_ht_info *)pos;
142 +       ht_info->control_chan =
143 +                       ieee80211_frequency_to_channel(channel->center_freq);
144 +       switch (channel_type) {
145 +       case NL80211_CHAN_HT40MINUS:
146 +               ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
147 +               break;
148 +       case NL80211_CHAN_HT40PLUS:
149 +               ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
150 +               break;
151 +       case NL80211_CHAN_HT20:
152 +       default:
153 +               ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE;
154 +               break;
155 +       }
156 +       if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
157 +               ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
158 +       ht_info->operation_mode = 0x0000;
159 +       ht_info->stbc_param = 0x0000;
160 +
161 +       /* It seems that Basic MCS set and Supported MCS set
162 +          are identical for the first 10 bytes */
163 +       memset(&ht_info->basic_set, 0, 16);
164 +       memcpy(&ht_info->basic_set, &ht_cap->mcs, 10);
165 +
166 +       return pos + sizeof(struct ieee80211_ht_info);
167 +}
168 +
169 +enum nl80211_channel_type ieee80211_ht_info_to_channel_type(
170 +                                       struct ieee80211_ht_info *ht_info)
171 +{
172 +       enum nl80211_channel_type channel_type;
173 +
174 +       if (!ht_info)
175 +               return NL80211_CHAN_NO_HT;
176 +
177 +       switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
178 +       case IEEE80211_HT_PARAM_CHA_SEC_NONE:
179 +               channel_type = NL80211_CHAN_HT20;
180 +               break;
181 +       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
182 +               channel_type = NL80211_CHAN_HT40PLUS;
183 +               break;
184 +       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
185 +               channel_type = NL80211_CHAN_HT40MINUS;
186 +               break;
187 +       default:
188 +               channel_type = NL80211_CHAN_NO_HT;
189 +       }
190 +
191 +       return channel_type;
192 +}
193 --- a/net/mac80211/work.c
194 +++ b/net/mac80211/work.c
195 @@ -117,7 +117,6 @@ static void ieee80211_add_ht_ie(struct s
196         u8 *pos;
197         u32 flags = channel->flags;
198         u16 cap = sband->ht_cap.cap;
199 -       __le16 tmp;
200  
201         if (!sband->ht_cap.ht_supported)
202                 return;
203 @@ -168,34 +167,8 @@ static void ieee80211_add_ht_ie(struct s
204         }
205  
206         /* reserve and fill IE */
207 -
208         pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
209 -       *pos++ = WLAN_EID_HT_CAPABILITY;
210 -       *pos++ = sizeof(struct ieee80211_ht_cap);
211 -       memset(pos, 0, sizeof(struct ieee80211_ht_cap));
212 -
213 -       /* capability flags */
214 -       tmp = cpu_to_le16(cap);
215 -       memcpy(pos, &tmp, sizeof(u16));
216 -       pos += sizeof(u16);
217 -
218 -       /* AMPDU parameters */
219 -       *pos++ = sband->ht_cap.ampdu_factor |
220 -                (sband->ht_cap.ampdu_density <<
221 -                       IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
222 -
223 -       /* MCS set */
224 -       memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
225 -       pos += sizeof(sband->ht_cap.mcs);
226 -
227 -       /* extended capabilities */
228 -       pos += sizeof(__le16);
229 -
230 -       /* BF capabilities */
231 -       pos += sizeof(__le32);
232 -
233 -       /* antenna selection */
234 -       pos += sizeof(u8);
235 +       ieee80211_ie_build_ht_cap(pos, sband, cap);
236  }
237  
238  static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
239 --- a/net/wireless/scan.c
240 +++ b/net/wireless/scan.c
241 @@ -365,6 +365,18 @@ struct cfg80211_bss *cfg80211_get_bss(st
242                                       const u8 *ssid, size_t ssid_len,
243                                       u16 capa_mask, u16 capa_val)
244  {
245 +       return cfg80211_get_bss_ht(wiphy, channel, bssid, ssid, ssid_len,
246 +                                  capa_mask, capa_val, NL80211_CHAN_NO_HT);
247 +}
248 +EXPORT_SYMBOL(cfg80211_get_bss);
249 +
250 +struct cfg80211_bss *cfg80211_get_bss_ht(struct wiphy *wiphy,
251 +                                     struct ieee80211_channel *channel,
252 +                                     const u8 *bssid,
253 +                                     const u8 *ssid, size_t ssid_len,
254 +                                     u16 capa_mask, u16 capa_val,
255 +                                     enum nl80211_channel_type channel_type)
256 +{
257         struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
258         struct cfg80211_internal_bss *bss, *res = NULL;
259         unsigned long now = jiffies;
260 @@ -374,8 +386,27 @@ struct cfg80211_bss *cfg80211_get_bss(st
261         list_for_each_entry(bss, &dev->bss_list, list) {
262                 if ((bss->pub.capability & capa_mask) != capa_val)
263                         continue;
264 -               if (channel && bss->pub.channel != channel)
265 -                       continue;
266 +               if (channel) {
267 +                       if (bss->pub.channel != channel)
268 +                               continue;
269 +                       if (channel_type == NL80211_CHAN_HT40MINUS ||
270 +                           channel_type == NL80211_CHAN_HT40PLUS) {
271 +                               struct ieee80211_ht_info *ht_info;
272 +                               ht_info = (struct ieee80211_ht_info *)
273 +                                       ieee80211_bss_get_ie(&bss->pub,
274 +                                                      WLAN_EID_HT_INFORMATION);
275 +                               if (!ht_info)
276 +                                       continue;
277 +                               if (channel_type == NL80211_CHAN_HT40MINUS &&
278 +                                             !(ht_info->ht_param &
279 +                                             IEEE80211_HT_PARAM_CHA_SEC_BELOW))
280 +                                       continue;
281 +                               if (channel_type == NL80211_CHAN_HT40PLUS &&
282 +                                             !(ht_info->ht_param &
283 +                                             IEEE80211_HT_PARAM_CHA_SEC_ABOVE))
284 +                                       continue;
285 +                       }
286 +               }
287                 /* Don't get expired BSS structs */
288                 if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
289                     !atomic_read(&bss->hold))
290 @@ -392,7 +423,7 @@ struct cfg80211_bss *cfg80211_get_bss(st
291                 return NULL;
292         return &res->pub;
293  }
294 -EXPORT_SYMBOL(cfg80211_get_bss);
295 +EXPORT_SYMBOL(cfg80211_get_bss_ht);
296  
297  struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
298                                        struct ieee80211_channel *channel,
299 --- a/net/wireless/nl80211.c
300 +++ b/net/wireless/nl80211.c
301 @@ -4282,13 +4282,42 @@ static int nl80211_join_ibss(struct sk_b
302                 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
303         }
304  
305 -       ibss.channel = ieee80211_get_channel(wiphy,
306 -               nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
307 +       if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
308 +               enum nl80211_channel_type channel_type;
309 +
310 +               channel_type = nla_get_u32(
311 +                       info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
312 +               if (channel_type != NL80211_CHAN_NO_HT &&
313 +                   channel_type != NL80211_CHAN_HT20 &&
314 +                   channel_type != NL80211_CHAN_HT40PLUS &&
315 +                   channel_type != NL80211_CHAN_HT40MINUS)
316 +                       return -EINVAL;
317 +               ibss.channel_type = channel_type;
318 +       } else {
319 +               ibss.channel_type = NL80211_CHAN_NO_HT;
320 +       }
321 +
322 +       ibss.channel = rdev_freq_to_chan(rdev,
323 +               nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
324 +               ibss.channel_type);
325 +
326         if (!ibss.channel ||
327 +           ibss.channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
328             ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
329             ibss.channel->flags & IEEE80211_CHAN_DISABLED)
330                 return -EINVAL;
331  
332 +#if 0
333 +       if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
334 +            ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
335 +           !can_beacon_sec_chan(&rdev->wiphy, ibss.chan, ibss.channel_type)) {
336 +               printk(KERN_DEBUG
337 +                      "cfg80211: Secondary channel not "
338 +                      "allowed to initiate communication\n");
339 +               return -EINVAL;
340 +       }
341 +#endif
342 +
343         ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
344         ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
345  
346 --- a/net/mac80211/agg-rx.c
347 +++ b/net/mac80211/agg-rx.c
348 @@ -178,6 +178,8 @@ static void ieee80211_send_addba_resp(st
349                 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
350         else if (sdata->vif.type == NL80211_IFTYPE_WDS)
351                 memcpy(mgmt->bssid, da, ETH_ALEN);
352 +       else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
353 +               memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
354  
355         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
356                                           IEEE80211_STYPE_ACTION);
357 --- a/net/mac80211/agg-tx.c
358 +++ b/net/mac80211/agg-tx.c
359 @@ -84,6 +84,8 @@ static void ieee80211_send_addba_request
360                 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
361         else if (sdata->vif.type == NL80211_IFTYPE_STATION)
362                 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
363 +       else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
364 +               memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
365  
366         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
367                                           IEEE80211_STYPE_ACTION);
368 @@ -400,7 +402,8 @@ int ieee80211_start_tx_ba_session(struct
369         if (sdata->vif.type != NL80211_IFTYPE_STATION &&
370             sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
371             sdata->vif.type != NL80211_IFTYPE_AP &&
372 -           sdata->vif.type != NL80211_IFTYPE_WDS)
373 +           sdata->vif.type != NL80211_IFTYPE_WDS &&
374 +           sdata->vif.type != NL80211_IFTYPE_ADHOC)
375                 return -EINVAL;
376  
377         if (test_sta_flags(sta, WLAN_STA_BLOCK_BA)) {
378 --- a/net/mac80211/ht.c
379 +++ b/net/mac80211/ht.c
380 @@ -203,6 +203,8 @@ void ieee80211_send_delba(struct ieee802
381                 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
382         else if (sdata->vif.type == NL80211_IFTYPE_STATION)
383                 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
384 +       else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
385 +               memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
386  
387         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
388                                           IEEE80211_STYPE_ACTION);
389 --- a/net/mac80211/ibss.c
390 +++ b/net/mac80211/ibss.c
391 @@ -64,6 +64,7 @@ static void ieee80211_rx_mgmt_auth_ibss(
392  static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
393                                       const u8 *bssid, const int beacon_int,
394                                       struct ieee80211_channel *chan,
395 +                                     enum nl80211_channel_type channel_type,
396                                       const u32 basic_rates,
397                                       const u16 capability, u64 tsf)
398  {
399 @@ -104,8 +105,12 @@ static void __ieee80211_sta_join_ibss(st
400  
401         sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
402  
403 +       /* entering a legacy IBSS. Use given HT configuration. */
404 +       if (channel_type == NL80211_CHAN_NO_HT)
405 +               channel_type = ifibss->channel_type;
406 +
407         local->oper_channel = chan;
408 -       WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
409 +       WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
410         ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
411  
412         sband = local->hw.wiphy->bands[chan->band];
413 @@ -171,6 +176,17 @@ static void __ieee80211_sta_join_ibss(st
414                 memcpy(skb_put(skb, ifibss->ie_len),
415                        ifibss->ie, ifibss->ie_len);
416  
417 +       if (channel_type != NL80211_CHAN_NO_HT && sband->ht_cap.ht_supported) {
418 +               pos = skb_put(skb, 4 +
419 +                                  sizeof(struct ieee80211_ht_cap) +
420 +                                  sizeof(struct ieee80211_ht_info));
421 +               pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap);
422 +               pos = ieee80211_ie_build_ht_info(pos,
423 +                                                &sband->ht_cap,
424 +                                                chan,
425 +                                                channel_type);
426 +       }
427 +
428         if (local->hw.queues >= 4) {
429                 pos = skb_put(skb, 9);
430                 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
431 @@ -219,6 +235,8 @@ static void ieee80211_sta_join_ibss(stru
432         u32 basic_rates;
433         int i, j;
434         u16 beacon_int = cbss->beacon_interval;
435 +       const u8 *ht_info_ie;
436 +       enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
437  
438         lockdep_assert_held(&sdata->u.ibss.mtx);
439  
440 @@ -242,9 +260,15 @@ static void ieee80211_sta_join_ibss(stru
441                 }
442         }
443  
444 +       ht_info_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_INFORMATION);
445 +       if (ht_info_ie)
446 +               channel_type = ieee80211_ht_info_to_channel_type(
447 +                       (struct ieee80211_ht_info *) (ht_info_ie + 2));
448 +
449         __ieee80211_sta_join_ibss(sdata, cbss->bssid,
450                                   beacon_int,
451                                   cbss->channel,
452 +                                 channel_type,
453                                   basic_rates,
454                                   cbss->capability,
455                                   cbss->tsf);
456 @@ -310,11 +334,65 @@ static void ieee80211_rx_bss_info(struct
457                         } else
458                                 sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
459                                                 mgmt->sa, supp_rates,
460 -                                               GFP_ATOMIC);
461 +                                               elems->ht_cap_elem, GFP_ATOMIC);
462                 }
463  
464 -               if (sta && elems->wmm_info)
465 -                       set_sta_flags(sta, WLAN_STA_WME);
466 +               if (sta) {
467 +                       if (elems->wmm_info)
468 +                               set_sta_flags(sta, WLAN_STA_WME);
469 +
470 +                       if (elems->ht_info_elem) {
471 +                               struct ieee80211_supported_band *sband =
472 +                                       local->hw.wiphy->bands[channel->band];
473 +                               enum nl80211_channel_type channel_type;
474 +
475 +                               channel_type =
476 +                                       ieee80211_ht_info_to_channel_type(
477 +                                               elems->ht_info_elem);
478 +                               if (channel_type != local->_oper_channel_type) {
479 +                                       struct sk_buff *skb =
480 +                                                       sdata->u.ibss.presp;
481 +                                       struct sk_buff *nskb;
482 +                                       u8 *ht_ie;
483 +
484 +                                       nskb = skb_copy(skb, GFP_ATOMIC);
485 +                                       ht_ie = (u8 *) cfg80211_find_ie(
486 +                                               WLAN_EID_HT_CAPABILITY,
487 +                                               nskb->data + 24 +
488 +                                                       sizeof(mgmt->u.beacon),
489 +                                               nskb->len - 24 -
490 +                                                       sizeof(mgmt->u.beacon));
491 +
492 +                                       if (!ht_ie)
493 +                                               ht_ie = skb_put(nskb, 4 +
494 +                                             sizeof(struct ieee80211_ht_cap) +
495 +                                             sizeof(struct ieee80211_ht_info));
496 +                                       ht_ie = ieee80211_ie_build_ht_cap(ht_ie,
497 +                                                            sband,
498 +                                                            sband->ht_cap.cap);
499 +                                       ht_ie = ieee80211_ie_build_ht_info(
500 +                                                                ht_ie,
501 +                                                                &sband->ht_cap,
502 +                                                                channel,
503 +                                                                channel_type);
504 +                                       sdata->u.ibss.presp = nskb;
505 +                                       kfree_skb(skb);
506 +
507 +                                       local->_oper_channel_type =
508 +                                                               channel_type;
509 +                                       WARN_ON(!ieee80211_set_channel_type(
510 +                                                               local,
511 +                                                               sdata,
512 +                                                               channel_type));
513 +                                       ieee80211_hw_config(local,
514 +                                               IEEE80211_CONF_CHANGE_CHANNEL);
515 +                               }
516 +                               ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
517 +                                                       elems->ht_cap_elem,
518 +                                                       &sta->sta.ht_cap);
519 +
520 +                       }
521 +               }
522  
523                 rcu_read_unlock();
524         }
525 @@ -404,7 +482,7 @@ static void ieee80211_rx_bss_info(struct
526                 ieee80211_sta_join_ibss(sdata, bss);
527                 supp_rates = ieee80211_sta_get_rates(local, elems, band);
528                 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
529 -                                      supp_rates, GFP_KERNEL);
530 +                                   supp_rates, elems->ht_cap_elem, GFP_KERNEL);
531         }
532  
533   put_bss:
534 @@ -417,7 +495,8 @@ static void ieee80211_rx_bss_info(struct
535   * must be callable in atomic context.
536   */
537  struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
538 -                                       u8 *bssid,u8 *addr, u32 supp_rates,
539 +                                       u8 *bssid, u8 *addr, u32 supp_rates,
540 +                                       struct ieee80211_ht_cap *ht_cap,
541                                         gfp_t gfp)
542  {
543         struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
544 @@ -458,6 +537,11 @@ struct sta_info *ieee80211_ibss_add_sta(
545         sta->sta.supp_rates[band] = supp_rates |
546                         ieee80211_mandatory_rates(local, band);
547  
548 +       /* fill in ht rates */
549 +       if (ht_cap)
550 +               ieee80211_ht_cap_ie_to_sta_ht_cap(local->hw.wiphy->bands[band],
551 +                               ht_cap, &sta->sta.ht_cap);
552 +
553         rate_control_rate_init(sta);
554  
555         /* If it fails, maybe we raced another insertion? */
556 @@ -556,8 +640,8 @@ static void ieee80211_sta_create_ibss(st
557                 sdata->drop_unencrypted = 0;
558  
559         __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
560 -                                 ifibss->channel, ifibss->basic_rates,
561 -                                 capability, 0);
562 +                                 ifibss->channel, ifibss->channel_type,
563 +                                 ifibss->basic_rates, capability, 0);
564  }
565  
566  /*
567 @@ -594,10 +678,10 @@ static void ieee80211_sta_find_ibss(stru
568                 chan = ifibss->channel;
569         if (!is_zero_ether_addr(ifibss->bssid))
570                 bssid = ifibss->bssid;
571 -       cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
572 +       cbss = cfg80211_get_bss_ht(local->hw.wiphy, chan, bssid,
573                                 ifibss->ssid, ifibss->ssid_len,
574                                 WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_PRIVACY,
575 -                               capability);
576 +                               capability, ifibss->channel_type);
577  
578         if (cbss) {
579                 struct ieee80211_bss *bss;
580 @@ -896,10 +980,15 @@ int ieee80211_ibss_join(struct ieee80211
581         struct sk_buff *skb;
582  
583         skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
584 -                           36 /* bitrates */ +
585 -                           34 /* SSID */ +
586 -                           3  /* DS params */ +
587 -                           4  /* IBSS params */ +
588 +                           sizeof(struct ieee80211_hdr_3addr) +
589 +                           12 /* struct ieee80211_mgmt.u.beacon */ +
590 +                           2 + IEEE80211_MAX_SSID_LEN /* max SSID */ +
591 +                           2 + 8 /* max Supported Rates */ +
592 +                           3 /* max DS params */ +
593 +                           4 /* IBSS params */ +
594 +                           2 + (IEEE80211_MAX_SUPP_RATES - 8) +
595 +                           2 + sizeof(struct ieee80211_ht_cap) +
596 +                           2 + sizeof(struct ieee80211_ht_info) +
597                             params->ie_len);
598         if (!skb)
599                 return -ENOMEM;
600 @@ -920,13 +1009,14 @@ int ieee80211_ibss_join(struct ieee80211
601         sdata->vif.bss_conf.beacon_int = params->beacon_interval;
602  
603         sdata->u.ibss.channel = params->channel;
604 +       sdata->u.ibss.channel_type = params->channel_type;
605         sdata->u.ibss.fixed_channel = params->channel_fixed;
606  
607         /* fix ourselves to that channel now already */
608         if (params->channel_fixed) {
609                 sdata->local->oper_channel = params->channel;
610                 WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
611 -                                                   NL80211_CHAN_NO_HT));
612 +                                                   params->channel_type));
613         }
614  
615         if (params->ie) {
616 --- a/net/mac80211/rx.c
617 +++ b/net/mac80211/rx.c
618 @@ -2138,7 +2138,8 @@ ieee80211_rx_h_action(struct ieee80211_r
619                 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
620                     sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
621                     sdata->vif.type != NL80211_IFTYPE_AP &&
622 -                   sdata->vif.type != NL80211_IFTYPE_WDS)
623 +                   sdata->vif.type != NL80211_IFTYPE_WDS &&
624 +                   sdata->vif.type != NL80211_IFTYPE_ADHOC)
625                         break;
626  
627                 /* verify action_code is present */
628 @@ -2654,7 +2655,8 @@ static int prepare_for_handlers(struct i
629                         else
630                                 rate_idx = status->rate_idx;
631                         rx->sta = ieee80211_ibss_add_sta(sdata, bssid,
632 -                                       hdr->addr2, BIT(rate_idx), GFP_ATOMIC);
633 +                                       hdr->addr2, BIT(rate_idx), NULL,
634 +                                                               GFP_ATOMIC);
635                 }
636                 break;
637         case NL80211_IFTYPE_MESH_POINT: