mac80211: fix ad-hoc mode performance regression
[openwrt.git] / package / mac80211 / patches / 300-pending_work.patch
1 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
2 +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
3 @@ -510,7 +510,11 @@ int ath9k_hw_process_rxdesc_edma(struct 
4                  */
5                 if (rxsp->status11 & AR_CRCErr)
6                         rxs->rs_status |= ATH9K_RXERR_CRC;
7 -               else if (rxsp->status11 & AR_PHYErr) {
8 +               else if (rxsp->status11 & AR_DecryptCRCErr)
9 +                       rxs->rs_status |= ATH9K_RXERR_DECRYPT;
10 +               else if (rxsp->status11 & AR_MichaelErr)
11 +                       rxs->rs_status |= ATH9K_RXERR_MIC;
12 +               if (rxsp->status11 & AR_PHYErr) {
13                         phyerr = MS(rxsp->status11, AR_PHYErrCode);
14                         /*
15                          * If we reach a point here where AR_PostDelimCRCErr is
16 @@ -532,11 +536,7 @@ int ath9k_hw_process_rxdesc_edma(struct 
17                                 rxs->rs_status |= ATH9K_RXERR_PHY;
18                                 rxs->rs_phyerr = phyerr;
19                         }
20 -
21 -               } else if (rxsp->status11 & AR_DecryptCRCErr)
22 -                       rxs->rs_status |= ATH9K_RXERR_DECRYPT;
23 -               else if (rxsp->status11 & AR_MichaelErr)
24 -                       rxs->rs_status |= ATH9K_RXERR_MIC;
25 +               };
26         }
27  
28         if (rxsp->status11 & AR_KeyMiss)
29 --- a/drivers/net/wireless/ath/carl9170/tx.c
30 +++ b/drivers/net/wireless/ath/carl9170/tx.c
31 @@ -1236,6 +1236,7 @@ static bool carl9170_tx_ps_drop(struct a
32  {
33         struct ieee80211_sta *sta;
34         struct carl9170_sta_info *sta_info;
35 +       struct ieee80211_tx_info *tx_info;
36  
37         rcu_read_lock();
38         sta = __carl9170_get_tx_sta(ar, skb);
39 @@ -1243,12 +1244,13 @@ static bool carl9170_tx_ps_drop(struct a
40                 goto out_rcu;
41  
42         sta_info = (void *) sta->drv_priv;
43 -       if (unlikely(sta_info->sleeping)) {
44 -               struct ieee80211_tx_info *tx_info;
45 +       tx_info = IEEE80211_SKB_CB(skb);
46  
47 +       if (unlikely(sta_info->sleeping) &&
48 +           !(tx_info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
49 +                               IEEE80211_TX_CTL_CLEAR_PS_FILT))) {
50                 rcu_read_unlock();
51  
52 -               tx_info = IEEE80211_SKB_CB(skb);
53                 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
54                         atomic_dec(&ar->tx_ampdu_upload);
55  
56 --- a/drivers/net/wireless/iwlegacy/4965-mac.c
57 +++ b/drivers/net/wireless/iwlegacy/4965-mac.c
58 @@ -1694,7 +1694,7 @@ il4965_tx_skb(struct il_priv *il, struct
59                 sta_priv = (void *)sta->drv_priv;
60  
61         if (sta_priv && sta_priv->asleep &&
62 -           (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
63 +           (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) {
64                 /*
65                  * This sends an asynchronous command to the device,
66                  * but we can rely on it being processed before the
67 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
68 +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
69 @@ -322,7 +322,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
70                 sta_priv = (void *)info->control.sta->drv_priv;
71  
72         if (sta_priv && sta_priv->asleep &&
73 -           (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
74 +           (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) {
75                 /*
76                  * This sends an asynchronous command to the device,
77                  * but we can rely on it being processed before the
78 @@ -331,6 +331,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
79                  * counter.
80                  * For now set the counter to just 1 since we do not
81                  * support uAPSD yet.
82 +                *
83 +                * FIXME: If we get two non-bufferable frames one
84 +                * after the other, we might only send out one of
85 +                * them because this is racy.
86                  */
87                 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
88         }
89 --- a/drivers/net/wireless/p54/txrx.c
90 +++ b/drivers/net/wireless/p54/txrx.c
91 @@ -690,7 +690,7 @@ static void p54_tx_80211_header(struct p
92         if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
93                 *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
94  
95 -       if (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)
96 +       if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)
97                 *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
98  
99         if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
100 --- a/include/net/mac80211.h
101 +++ b/include/net/mac80211.h
102 @@ -341,9 +341,9 @@ struct ieee80211_bss_conf {
103   *     used to indicate that a frame was already retried due to PS
104   * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
105   *     used to indicate frame should not be encrypted
106 - * @IEEE80211_TX_CTL_POLL_RESPONSE: This frame is a response to a poll
107 - *     frame (PS-Poll or uAPSD) and should be sent although the station
108 - *     is in powersave mode.
109 + * @IEEE80211_TX_CTL_NO_PS_BUFFER: This frame is a response to a poll
110 + *     frame (PS-Poll or uAPSD) or a non-bufferable MMPDU and must
111 + *     be sent although the station is in powersave mode.
112   * @IEEE80211_TX_CTL_MORE_FRAMES: More frames will be passed to the
113   *     transmit function after the current frame, this can be used
114   *     by drivers to kick the DMA queue only if unset or when the
115 @@ -399,7 +399,7 @@ enum mac80211_tx_control_flags {
116         IEEE80211_TX_INTFL_NEED_TXPROCESSING    = BIT(14),
117         IEEE80211_TX_INTFL_RETRIED              = BIT(15),
118         IEEE80211_TX_INTFL_DONT_ENCRYPT         = BIT(16),
119 -       IEEE80211_TX_CTL_POLL_RESPONSE          = BIT(17),
120 +       IEEE80211_TX_CTL_NO_PS_BUFFER           = BIT(17),
121         IEEE80211_TX_CTL_MORE_FRAMES            = BIT(18),
122         IEEE80211_TX_INTFL_RETRANSMISSION       = BIT(19),
123         /* hole at 20, use later */
124 @@ -425,7 +425,7 @@ enum mac80211_tx_control_flags {
125         IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU |           \
126         IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK |               \
127         IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK |           \
128 -       IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_POLL_RESPONSE |   \
129 +       IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_NO_PS_BUFFER |    \
130         IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC |                \
131         IEEE80211_TX_CTL_STBC | IEEE80211_TX_STATUS_EOSP)
132  
133 @@ -1634,7 +1634,7 @@ void ieee80211_free_txskb(struct ieee802
134   * the station sends a PS-Poll or a uAPSD trigger frame, mac80211
135   * will inform the driver of this with the @allow_buffered_frames
136   * callback; this callback is optional. mac80211 will then transmit
137 - * the frames as usual and set the %IEEE80211_TX_CTL_POLL_RESPONSE
138 + * the frames as usual and set the %IEEE80211_TX_CTL_NO_PS_BUFFER
139   * on each frame. The last frame in the service period (or the only
140   * response to a PS-Poll) also has %IEEE80211_TX_STATUS_EOSP set to
141   * indicate that it ends the service period; as this frame must have
142 @@ -1642,6 +1642,9 @@ void ieee80211_free_txskb(struct ieee802
143   * When TX status is reported for this frame, the service period is
144   * marked has having ended and a new one can be started by the peer.
145   *
146 + * Additionally, non-bufferable MMPDUs can also be transmitted by
147 + * mac80211 with the %IEEE80211_TX_CTL_NO_PS_BUFFER set in them.
148 + *
149   * Another race condition can happen on some devices like iwlwifi
150   * when there are frames queued for the station and it wakes up
151   * or polls; the frames that are already queued could end up being
152 @@ -2140,7 +2143,7 @@ enum ieee80211_frame_release_type {
153   * @allow_buffered_frames: Prepare device to allow the given number of frames
154   *     to go out to the given station. The frames will be sent by mac80211
155   *     via the usual TX path after this call. The TX information for frames
156 - *     released will also have the %IEEE80211_TX_CTL_POLL_RESPONSE flag set
157 + *     released will also have the %IEEE80211_TX_CTL_NO_PS_BUFFER flag set
158   *     and the last one will also have %IEEE80211_TX_STATUS_EOSP set. In case
159   *     frames from multiple TIDs are released and the driver might reorder
160   *     them between the TIDs, it must set the %IEEE80211_TX_STATUS_EOSP flag
161 --- a/net/mac80211/agg-rx.c
162 +++ b/net/mac80211/agg-rx.c
163 @@ -187,6 +187,8 @@ static void ieee80211_send_addba_resp(st
164                 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
165         else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
166                 memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN);
167 +       else if (sdata->vif.type == NL80211_IFTYPE_WDS)
168 +               memcpy(mgmt->bssid, da, ETH_ALEN);
169  
170         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
171                                           IEEE80211_STYPE_ACTION);
172 --- a/net/mac80211/agg-tx.c
173 +++ b/net/mac80211/agg-tx.c
174 @@ -81,7 +81,8 @@ static void ieee80211_send_addba_request
175         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
176         if (sdata->vif.type == NL80211_IFTYPE_AP ||
177             sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
178 -           sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
179 +           sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
180 +           sdata->vif.type == NL80211_IFTYPE_WDS)
181                 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
182         else if (sdata->vif.type == NL80211_IFTYPE_STATION)
183                 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
184 @@ -471,6 +472,7 @@ int ieee80211_start_tx_ba_session(struct
185             sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
186             sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
187             sdata->vif.type != NL80211_IFTYPE_AP &&
188 +           sdata->vif.type != NL80211_IFTYPE_WDS &&
189             sdata->vif.type != NL80211_IFTYPE_ADHOC)
190                 return -EINVAL;
191  
192 --- a/net/mac80211/debugfs_sta.c
193 +++ b/net/mac80211/debugfs_sta.c
194 @@ -63,11 +63,11 @@ static ssize_t sta_flags_read(struct fil
195         test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
196  
197         int res = scnprintf(buf, sizeof(buf),
198 -                           "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
199 +                           "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
200                             TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
201                             TEST(PS_DRIVER), TEST(AUTHORIZED),
202                             TEST(SHORT_PREAMBLE),
203 -                           TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
204 +                           TEST(WME), TEST(CLEAR_PS_FILT),
205                             TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
206                             TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
207                             TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
208 --- a/net/mac80211/iface.c
209 +++ b/net/mac80211/iface.c
210 @@ -178,7 +178,6 @@ static int ieee80211_do_open(struct net_
211  {
212         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
213         struct ieee80211_local *local = sdata->local;
214 -       struct sta_info *sta;
215         u32 changed = 0;
216         int res;
217         u32 hw_reconf_flags = 0;
218 @@ -309,28 +308,6 @@ static int ieee80211_do_open(struct net_
219  
220         set_bit(SDATA_STATE_RUNNING, &sdata->state);
221  
222 -       if (sdata->vif.type == NL80211_IFTYPE_WDS) {
223 -               /* Create STA entry for the WDS peer */
224 -               sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
225 -                                    GFP_KERNEL);
226 -               if (!sta) {
227 -                       res = -ENOMEM;
228 -                       goto err_del_interface;
229 -               }
230 -
231 -               sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
232 -               sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
233 -               sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
234 -
235 -               res = sta_info_insert(sta);
236 -               if (res) {
237 -                       /* STA has been freed */
238 -                       goto err_del_interface;
239 -               }
240 -
241 -               rate_control_rate_init(sta);
242 -       }
243 -
244         /*
245          * set_multicast_list will be invoked by the networking core
246          * which will check whether any increments here were done in
247 @@ -357,8 +334,7 @@ static int ieee80211_do_open(struct net_
248         netif_tx_start_all_queues(dev);
249  
250         return 0;
251 - err_del_interface:
252 -       drv_remove_interface(local, sdata);
253 +
254   err_stop:
255         if (!local->open_count)
256                 drv_stop(local);
257 @@ -722,6 +698,70 @@ static void ieee80211_if_setup(struct ne
258         dev->destructor = free_netdev;
259  }
260  
261 +static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
262 +                                        struct sk_buff *skb)
263 +{
264 +       struct ieee80211_local *local = sdata->local;
265 +       struct ieee80211_rx_status *rx_status;
266 +       struct ieee802_11_elems elems;
267 +       struct ieee80211_mgmt *mgmt;
268 +       struct sta_info *sta;
269 +       size_t baselen;
270 +       u32 rates = 0;
271 +       u16 stype;
272 +       bool new = false;
273 +       enum ieee80211_band band = local->hw.conf.channel->band;
274 +       struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
275 +
276 +       rx_status = IEEE80211_SKB_RXCB(skb);
277 +       mgmt = (struct ieee80211_mgmt *) skb->data;
278 +       stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
279 +
280 +       if (stype != IEEE80211_STYPE_BEACON)
281 +               return;
282 +
283 +       baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
284 +       if (baselen > skb->len)
285 +               return;
286 +
287 +       ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
288 +                              skb->len - baselen, &elems);
289 +
290 +       rates = ieee80211_sta_get_rates(local, &elems, band);
291 +
292 +       rcu_read_lock();
293 +
294 +       sta = sta_info_get(sdata, sdata->u.wds.remote_addr);
295 +
296 +       if (!sta) {
297 +               rcu_read_unlock();
298 +               sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
299 +                                    GFP_KERNEL);
300 +               if (!sta)
301 +                       return;
302 +
303 +               new = true;
304 +       }
305 +
306 +       sta->last_rx = jiffies;
307 +       sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
308 +
309 +       if (elems.ht_cap_elem)
310 +               ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
311 +                               elems.ht_cap_elem, &sta->sta.ht_cap);
312 +
313 +       if (elems.wmm_param)
314 +               set_sta_flag(sta, WLAN_STA_WME);
315 +
316 +       if (new) {
317 +               set_sta_flag(sta, WLAN_STA_AUTHORIZED);
318 +               rate_control_rate_init(sta);
319 +               sta_info_insert_rcu(sta);
320 +       }
321 +
322 +       rcu_read_unlock();
323 +}
324 +
325  static void ieee80211_iface_work(struct work_struct *work)
326  {
327         struct ieee80211_sub_if_data *sdata =
328 @@ -826,6 +866,9 @@ static void ieee80211_iface_work(struct 
329                                 break;
330                         ieee80211_mesh_rx_queued_mgmt(sdata, skb);
331                         break;
332 +               case NL80211_IFTYPE_WDS:
333 +                       ieee80211_wds_rx_queued_mgmt(sdata, skb);
334 +                       break;
335                 default:
336                         WARN(1, "frame for unexpected interface type");
337                         break;
338 --- a/net/mac80211/rx.c
339 +++ b/net/mac80211/rx.c
340 @@ -2282,6 +2282,7 @@ ieee80211_rx_h_action(struct ieee80211_r
341                     sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
342                     sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
343                     sdata->vif.type != NL80211_IFTYPE_AP &&
344 +                   sdata->vif.type != NL80211_IFTYPE_WDS &&
345                     sdata->vif.type != NL80211_IFTYPE_ADHOC)
346                         break;
347  
348 @@ -2492,14 +2493,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
349  
350         if (!ieee80211_vif_is_mesh(&sdata->vif) &&
351             sdata->vif.type != NL80211_IFTYPE_ADHOC &&
352 -           sdata->vif.type != NL80211_IFTYPE_STATION)
353 +           sdata->vif.type != NL80211_IFTYPE_STATION &&
354 +           sdata->vif.type != NL80211_IFTYPE_WDS)
355                 return RX_DROP_MONITOR;
356  
357         switch (stype) {
358         case cpu_to_le16(IEEE80211_STYPE_AUTH):
359         case cpu_to_le16(IEEE80211_STYPE_BEACON):
360         case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
361 -               /* process for all: mesh, mlme, ibss */
362 +               /* process for all: mesh, mlme, ibss, wds */
363                 break;
364         case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
365         case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
366 @@ -2853,10 +2855,16 @@ static int prepare_for_handlers(struct i
367                 }
368                 break;
369         case NL80211_IFTYPE_WDS:
370 -               if (bssid || !ieee80211_is_data(hdr->frame_control))
371 -                       return 0;
372                 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
373                         return 0;
374 +
375 +               if (ieee80211_is_data(hdr->frame_control) ||
376 +                   ieee80211_is_action(hdr->frame_control)) {
377 +                       if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
378 +                               return 0;
379 +               } else if (!ieee80211_is_beacon(hdr->frame_control))
380 +                       return 0;
381 +
382                 break;
383         default:
384                 /* should never get here */
385 --- a/net/mac80211/sta_info.c
386 +++ b/net/mac80211/sta_info.c
387 @@ -1050,7 +1050,7 @@ static void ieee80211_send_null_response
388          * exchange. Also set EOSP to indicate this packet
389          * ends the poll/service period.
390          */
391 -       info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE |
392 +       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER |
393                        IEEE80211_TX_STATUS_EOSP |
394                        IEEE80211_TX_CTL_REQ_TX_STATUS;
395  
396 @@ -1177,7 +1177,7 @@ ieee80211_sta_ps_deliver_response(struct
397                          * STA may still remain is PS mode after this frame
398                          * exchange.
399                          */
400 -                       info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE;
401 +                       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
402  
403                         /*
404                          * Use MoreData flag to indicate whether there are
405 --- a/net/mac80211/sta_info.h
406 +++ b/net/mac80211/sta_info.h
407 @@ -31,7 +31,6 @@
408   * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
409   *     frames.
410   * @WLAN_STA_WME: Station is a QoS-STA.
411 - * @WLAN_STA_WDS: Station is one of our WDS peers.
412   * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
413   *     IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
414   *     frame to this station is transmitted.
415 @@ -62,7 +61,6 @@ enum ieee80211_sta_info_flags {
416         WLAN_STA_AUTHORIZED,
417         WLAN_STA_SHORT_PREAMBLE,
418         WLAN_STA_WME,
419 -       WLAN_STA_WDS,
420         WLAN_STA_CLEAR_PS_FILT,
421         WLAN_STA_MFP,
422         WLAN_STA_BLOCK_BA,
423 --- a/net/mac80211/tx.c
424 +++ b/net/mac80211/tx.c
425 @@ -448,18 +448,23 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
426         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
427         struct ieee80211_local *local = tx->local;
428  
429 -       if (unlikely(!sta ||
430 -                    ieee80211_is_probe_resp(hdr->frame_control) ||
431 -                    ieee80211_is_auth(hdr->frame_control) ||
432 -                    ieee80211_is_assoc_resp(hdr->frame_control) ||
433 -                    ieee80211_is_reassoc_resp(hdr->frame_control)))
434 +       if (unlikely(!sta))
435                 return TX_CONTINUE;
436  
437         if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
438                       test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
439 -                    !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) {
440 +                    !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
441                 int ac = skb_get_queue_mapping(tx->skb);
442  
443 +               /* only deauth, disassoc and action are bufferable MMPDUs */
444 +               if (ieee80211_is_mgmt(hdr->frame_control) &&
445 +                   !ieee80211_is_deauth(hdr->frame_control) &&
446 +                   !ieee80211_is_disassoc(hdr->frame_control) &&
447 +                   !ieee80211_is_action(hdr->frame_control)) {
448 +                       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
449 +                       return TX_CONTINUE;
450 +               }
451 +
452  #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
453                 printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n",
454                        sta->sta.addr, sta->sta.aid, ac);
455 --- a/net/mac80211/ieee80211_i.h
456 +++ b/net/mac80211/ieee80211_i.h
457 @@ -480,7 +480,7 @@ struct ieee80211_if_ibss {
458  
459         bool control_port;
460  
461 -       u8 bssid[ETH_ALEN];
462 +       u8 bssid[ETH_ALEN] __aligned(2);
463         u8 ssid[IEEE80211_MAX_SSID_LEN];
464         u8 ssid_len, ie_len;
465         u8 *ie;