ath9k: disable MAC sample debugging, it is almost never used and wastes precious...
[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 @@ -489,12 +489,12 @@ ieee80211_rx_mesh_check(struct ieee80211
341                         if (ieee80211_has_tods(hdr->frame_control) ||
342                                 !ieee80211_has_fromds(hdr->frame_control))
343                                 return RX_DROP_MONITOR;
344 -                       if (memcmp(hdr->addr3, dev_addr, ETH_ALEN) == 0)
345 +                       if (compare_ether_addr(hdr->addr3, dev_addr) == 0)
346                                 return RX_DROP_MONITOR;
347                 } else {
348                         if (!ieee80211_has_a4(hdr->frame_control))
349                                 return RX_DROP_MONITOR;
350 -                       if (memcmp(hdr->addr4, dev_addr, ETH_ALEN) == 0)
351 +                       if (compare_ether_addr(hdr->addr4, dev_addr) == 0)
352                                 return RX_DROP_MONITOR;
353                 }
354         }
355 @@ -2282,6 +2282,7 @@ ieee80211_rx_h_action(struct ieee80211_r
356                     sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
357                     sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
358                     sdata->vif.type != NL80211_IFTYPE_AP &&
359 +                   sdata->vif.type != NL80211_IFTYPE_WDS &&
360                     sdata->vif.type != NL80211_IFTYPE_ADHOC)
361                         break;
362  
363 @@ -2336,7 +2337,7 @@ ieee80211_rx_h_action(struct ieee80211_r
364                         if (sdata->vif.type != NL80211_IFTYPE_STATION)
365                                 break;
366  
367 -                       if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))
368 +                       if (compare_ether_addr(mgmt->bssid, sdata->u.mgd.bssid))
369                                 break;
370  
371                         goto queue;
372 @@ -2492,14 +2493,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_
373  
374         if (!ieee80211_vif_is_mesh(&sdata->vif) &&
375             sdata->vif.type != NL80211_IFTYPE_ADHOC &&
376 -           sdata->vif.type != NL80211_IFTYPE_STATION)
377 +           sdata->vif.type != NL80211_IFTYPE_STATION &&
378 +           sdata->vif.type != NL80211_IFTYPE_WDS)
379                 return RX_DROP_MONITOR;
380  
381         switch (stype) {
382         case cpu_to_le16(IEEE80211_STYPE_AUTH):
383         case cpu_to_le16(IEEE80211_STYPE_BEACON):
384         case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
385 -               /* process for all: mesh, mlme, ibss */
386 +               /* process for all: mesh, mlme, ibss, wds */
387                 break;
388         case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
389         case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
390 @@ -2853,10 +2855,16 @@ static int prepare_for_handlers(struct i
391                 }
392                 break;
393         case NL80211_IFTYPE_WDS:
394 -               if (bssid || !ieee80211_is_data(hdr->frame_control))
395 -                       return 0;
396                 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
397                         return 0;
398 +
399 +               if (ieee80211_is_data(hdr->frame_control) ||
400 +                   ieee80211_is_action(hdr->frame_control)) {
401 +                       if (compare_ether_addr(sdata->vif.addr, hdr->addr1))
402 +                               return 0;
403 +               } else if (!ieee80211_is_beacon(hdr->frame_control))
404 +                       return 0;
405 +
406                 break;
407         default:
408                 /* should never get here */
409 --- a/net/mac80211/sta_info.c
410 +++ b/net/mac80211/sta_info.c
411 @@ -9,6 +9,7 @@
412  
413  #include <linux/module.h>
414  #include <linux/init.h>
415 +#include <linux/etherdevice.h>
416  #include <linux/netdevice.h>
417  #include <linux/types.h>
418  #include <linux/slab.h>
419 @@ -101,7 +102,7 @@ struct sta_info *sta_info_get(struct iee
420                                     lockdep_is_held(&local->sta_mtx));
421         while (sta) {
422                 if (sta->sdata == sdata &&
423 -                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
424 +                   compare_ether_addr(sta->sta.addr, addr) == 0)
425                         break;
426                 sta = rcu_dereference_check(sta->hnext,
427                                             lockdep_is_held(&local->sta_mtx));
428 @@ -124,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct
429         while (sta) {
430                 if ((sta->sdata == sdata ||
431                      (sta->sdata->bss && sta->sdata->bss == sdata->bss)) &&
432 -                   memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
433 +                   compare_ether_addr(sta->sta.addr, addr) == 0)
434                         break;
435                 sta = rcu_dereference_check(sta->hnext,
436                                             lockdep_is_held(&local->sta_mtx));
437 @@ -1050,7 +1051,7 @@ static void ieee80211_send_null_response
438          * exchange. Also set EOSP to indicate this packet
439          * ends the poll/service period.
440          */
441 -       info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE |
442 +       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER |
443                        IEEE80211_TX_STATUS_EOSP |
444                        IEEE80211_TX_CTL_REQ_TX_STATUS;
445  
446 @@ -1177,7 +1178,7 @@ ieee80211_sta_ps_deliver_response(struct
447                          * STA may still remain is PS mode after this frame
448                          * exchange.
449                          */
450 -                       info->flags |= IEEE80211_TX_CTL_POLL_RESPONSE;
451 +                       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
452  
453                         /*
454                          * Use MoreData flag to indicate whether there are
455 --- a/net/mac80211/sta_info.h
456 +++ b/net/mac80211/sta_info.h
457 @@ -14,6 +14,7 @@
458  #include <linux/if_ether.h>
459  #include <linux/workqueue.h>
460  #include <linux/average.h>
461 +#include <linux/etherdevice.h>
462  #include "key.h"
463  
464  /**
465 @@ -31,7 +32,6 @@
466   * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
467   *     frames.
468   * @WLAN_STA_WME: Station is a QoS-STA.
469 - * @WLAN_STA_WDS: Station is one of our WDS peers.
470   * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
471   *     IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
472   *     frame to this station is transmitted.
473 @@ -62,7 +62,6 @@ enum ieee80211_sta_info_flags {
474         WLAN_STA_AUTHORIZED,
475         WLAN_STA_SHORT_PREAMBLE,
476         WLAN_STA_WME,
477 -       WLAN_STA_WDS,
478         WLAN_STA_CLEAR_PS_FILT,
479         WLAN_STA_MFP,
480         WLAN_STA_BLOCK_BA,
481 @@ -489,7 +488,7 @@ void for_each_sta_info_type_check(struct
482                 nxt = _sta ? rcu_dereference(_sta->hnext) : NULL        \
483              )                                                          \
484         /* compare address and run code only if it matches */           \
485 -       if (memcmp(_sta->sta.addr, (_addr), ETH_ALEN) == 0)
486 +       if (compare_ether_addr(_sta->sta.addr, (_addr)) == 0)
487  
488  /*
489   * Get STA info by index, BROKEN!
490 --- a/net/mac80211/tx.c
491 +++ b/net/mac80211/tx.c
492 @@ -448,18 +448,23 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
493         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
494         struct ieee80211_local *local = tx->local;
495  
496 -       if (unlikely(!sta ||
497 -                    ieee80211_is_probe_resp(hdr->frame_control) ||
498 -                    ieee80211_is_auth(hdr->frame_control) ||
499 -                    ieee80211_is_assoc_resp(hdr->frame_control) ||
500 -                    ieee80211_is_reassoc_resp(hdr->frame_control)))
501 +       if (unlikely(!sta))
502                 return TX_CONTINUE;
503  
504         if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
505                       test_sta_flag(sta, WLAN_STA_PS_DRIVER)) &&
506 -                    !(info->flags & IEEE80211_TX_CTL_POLL_RESPONSE))) {
507 +                    !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
508                 int ac = skb_get_queue_mapping(tx->skb);
509  
510 +               /* only deauth, disassoc and action are bufferable MMPDUs */
511 +               if (ieee80211_is_mgmt(hdr->frame_control) &&
512 +                   !ieee80211_is_deauth(hdr->frame_control) &&
513 +                   !ieee80211_is_disassoc(hdr->frame_control) &&
514 +                   !ieee80211_is_action(hdr->frame_control)) {
515 +                       info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER;
516 +                       return TX_CONTINUE;
517 +               }
518 +
519  #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
520                 printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n",
521                        sta->sta.addr, sta->sta.aid, ac);
522 --- a/net/mac80211/ieee80211_i.h
523 +++ b/net/mac80211/ieee80211_i.h
524 @@ -480,7 +480,7 @@ struct ieee80211_if_ibss {
525  
526         bool control_port;
527  
528 -       u8 bssid[ETH_ALEN];
529 +       u8 bssid[ETH_ALEN] __aligned(2);
530         u8 ssid[IEEE80211_MAX_SSID_LEN];
531         u8 ssid_len, ie_len;
532         u8 *ie;
533 --- a/net/mac80211/ibss.c
534 +++ b/net/mac80211/ibss.c
535 @@ -66,7 +66,7 @@ static void __ieee80211_sta_join_ibss(st
536         skb_reset_tail_pointer(skb);
537         skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
538  
539 -       if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
540 +       if (compare_ether_addr(ifibss->bssid, bssid))
541                 sta_info_flush(sdata->local, sdata);
542  
543         /* if merging, indicate to driver that we leave the old IBSS */
544 @@ -403,7 +403,7 @@ static void ieee80211_rx_bss_info(struct
545                 return;
546  
547         if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
548 -           memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) {
549 +           compare_ether_addr(mgmt->bssid, sdata->u.ibss.bssid) == 0) {
550  
551                 rcu_read_lock();
552                 sta = sta_info_get(sdata, mgmt->sa);
553 @@ -508,7 +508,7 @@ static void ieee80211_rx_bss_info(struct
554                 goto put_bss;
555  
556         /* same BSSID */
557 -       if (memcmp(cbss->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0)
558 +       if (compare_ether_addr(cbss->bssid, sdata->u.ibss.bssid) == 0)
559                 goto put_bss;
560  
561         if (rx_status->flag & RX_FLAG_MACTIME_MPDU) {
562 @@ -831,8 +831,8 @@ static void ieee80211_rx_mgmt_probe_req(
563         if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
564                 return;
565  
566 -       if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
567 -           memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0)
568 +       if (compare_ether_addr(mgmt->bssid, ifibss->bssid) != 0 &&
569 +           !is_broadcast_ether_addr(mgmt->bssid))
570                 return;
571  
572         end = ((u8 *) mgmt) + len;
573 --- a/net/mac80211/mesh.c
574 +++ b/net/mac80211/mesh.c
575 @@ -204,7 +204,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80
576                         kmem_cache_free(rm_cache, p);
577                         --entries;
578                 } else if ((seqnum == p->seqnum) &&
579 -                          (memcmp(sa, p->sa, ETH_ALEN) == 0))
580 +                          (compare_ether_addr(sa, p->sa) == 0))
581                         return -1;
582         }
583  
584 --- a/net/mac80211/mesh_hwmp.c
585 +++ b/net/mac80211/mesh_hwmp.c
586 @@ -8,6 +8,7 @@
587   */
588  
589  #include <linux/slab.h>
590 +#include <linux/etherdevice.h>
591  #include <asm/unaligned.h>
592  #include "wme.h"
593  #include "mesh.h"
594 @@ -419,7 +420,7 @@ static u32 hwmp_route_info_get(struct ie
595                 new_metric = MAX_METRIC;
596         exp_time = TU_TO_EXP_TIME(orig_lifetime);
597  
598 -       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0) {
599 +       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0) {
600                 /* This MP is the originator, we are not interested in this
601                  * frame, except for updating transmitter's path info.
602                  */
603 @@ -469,7 +470,7 @@ static u32 hwmp_route_info_get(struct ie
604  
605         /* Update and check transmitter routing info */
606         ta = mgmt->sa;
607 -       if (memcmp(orig_addr, ta, ETH_ALEN) == 0)
608 +       if (compare_ether_addr(orig_addr, ta) == 0)
609                 fresh_info = false;
610         else {
611                 fresh_info = true;
612 @@ -529,7 +530,7 @@ static void hwmp_preq_frame_process(stru
613  
614         mhwmp_dbg("received PREQ from %pM", orig_addr);
615  
616 -       if (memcmp(target_addr, sdata->vif.addr, ETH_ALEN) == 0) {
617 +       if (compare_ether_addr(target_addr, sdata->vif.addr) == 0) {
618                 mhwmp_dbg("PREQ is for us");
619                 forward = false;
620                 reply = true;
621 @@ -624,7 +625,7 @@ static void hwmp_prep_frame_process(stru
622         mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem));
623  
624         orig_addr = PREP_IE_ORIG_ADDR(prep_elem);
625 -       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
626 +       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0)
627                 /* destination, no forwarding required */
628                 return;
629  
630 @@ -694,10 +695,12 @@ static void hwmp_perr_frame_process(stru
631         rcu_read_lock();
632         mpath = mesh_path_lookup(target_addr, sdata);
633         if (mpath) {
634 +               struct sta_info *sta;
635 +
636                 spin_lock_bh(&mpath->state_lock);
637 +               sta = next_hop_deref_protected(mpath);
638                 if (mpath->flags & MESH_PATH_ACTIVE &&
639 -                   memcmp(ta, next_hop_deref_protected(mpath)->sta.addr,
640 -                                                       ETH_ALEN) == 0 &&
641 +                   compare_ether_addr(ta, sta->sta.addr) == 0 &&
642                     (!(mpath->flags & MESH_PATH_SN_VALID) ||
643                     SN_GT(target_sn, mpath->sn))) {
644                         mpath->flags &= ~MESH_PATH_ACTIVE;
645 @@ -739,7 +742,7 @@ static void hwmp_rann_frame_process(stru
646         metric = rann->rann_metric;
647  
648         /*  Ignore our own RANNs */
649 -       if (memcmp(orig_addr, sdata->vif.addr, ETH_ALEN) == 0)
650 +       if (compare_ether_addr(orig_addr, sdata->vif.addr) == 0)
651                 return;
652  
653         mhwmp_dbg("received RANN from %pM (is_gate=%d)", orig_addr,
654 @@ -1064,7 +1067,7 @@ int mesh_nexthop_lookup(struct sk_buff *
655         if (time_after(jiffies,
656                        mpath->exp_time -
657                        msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
658 -           !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) &&
659 +           !compare_ether_addr(sdata->vif.addr, hdr->addr4) &&
660             !(mpath->flags & MESH_PATH_RESOLVING) &&
661             !(mpath->flags & MESH_PATH_FIXED))
662                 mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH);
663 --- a/net/mac80211/mesh_pathtbl.c
664 +++ b/net/mac80211/mesh_pathtbl.c
665 @@ -350,7 +350,7 @@ static struct mesh_path *mpath_lookup(st
666         hlist_for_each_entry_rcu(node, n, bucket, list) {
667                 mpath = node->mpath;
668                 if (mpath->sdata == sdata &&
669 -                               memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
670 +                               compare_ether_addr(dst, mpath->dst) == 0) {
671                         if (MPATH_EXPIRED(mpath)) {
672                                 spin_lock_bh(&mpath->state_lock);
673                                 mpath->flags &= ~MESH_PATH_ACTIVE;
674 @@ -525,7 +525,7 @@ int mesh_path_add(u8 *dst, struct ieee80
675         int err = 0;
676         u32 hash_idx;
677  
678 -       if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
679 +       if (compare_ether_addr(dst, sdata->vif.addr) == 0)
680                 /* never add ourselves as neighbours */
681                 return -ENOTSUPP;
682  
683 @@ -566,7 +566,8 @@ int mesh_path_add(u8 *dst, struct ieee80
684         err = -EEXIST;
685         hlist_for_each_entry(node, n, bucket, list) {
686                 mpath = node->mpath;
687 -               if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
688 +               if (mpath->sdata == sdata &&
689 +                   compare_ether_addr(dst, mpath->dst) == 0)
690                         goto err_exists;
691         }
692  
693 @@ -657,7 +658,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struc
694         int err = 0;
695         u32 hash_idx;
696  
697 -       if (memcmp(dst, sdata->vif.addr, ETH_ALEN) == 0)
698 +       if (compare_ether_addr(dst, sdata->vif.addr) == 0)
699                 /* never add ourselves as neighbours */
700                 return -ENOTSUPP;
701  
702 @@ -694,7 +695,8 @@ int mpp_path_add(u8 *dst, u8 *mpp, struc
703         err = -EEXIST;
704         hlist_for_each_entry(node, n, bucket, list) {
705                 mpath = node->mpath;
706 -               if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
707 +               if (mpath->sdata == sdata &&
708 +                   compare_ether_addr(dst, mpath->dst) == 0)
709                         goto err_exists;
710         }
711  
712 @@ -887,7 +889,7 @@ int mesh_path_del(u8 *addr, struct ieee8
713         hlist_for_each_entry(node, n, bucket, list) {
714                 mpath = node->mpath;
715                 if (mpath->sdata == sdata &&
716 -                   memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
717 +                   compare_ether_addr(addr, mpath->dst) == 0) {
718                         __mesh_path_del(tbl, node);
719                         goto enddel;
720                 }
721 --- a/net/mac80211/mlme.c
722 +++ b/net/mac80211/mlme.c
723 @@ -1812,7 +1812,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_
724  
725         memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
726  
727 -       if (memcmp(bssid, mgmt->bssid, ETH_ALEN))
728 +       if (compare_ether_addr(bssid, mgmt->bssid))
729                 return RX_MGMT_NONE;
730  
731         auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
732 @@ -1893,7 +1893,7 @@ ieee80211_rx_mgmt_deauth(struct ieee8021
733                 return RX_MGMT_NONE;
734  
735         if (!ifmgd->associated ||
736 -           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
737 +           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
738                 return RX_MGMT_NONE;
739  
740         bssid = ifmgd->associated->bssid;
741 @@ -1925,7 +1925,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80
742                 return RX_MGMT_NONE;
743  
744         if (!ifmgd->associated ||
745 -           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
746 +           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
747                 return RX_MGMT_NONE;
748  
749         reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
750 @@ -2190,7 +2190,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee
751  
752         if (!assoc_data)
753                 return RX_MGMT_NONE;
754 -       if (memcmp(assoc_data->bss->bssid, mgmt->bssid, ETH_ALEN))
755 +       if (compare_ether_addr(assoc_data->bss->bssid, mgmt->bssid))
756                 return RX_MGMT_NONE;
757  
758         /*
759 @@ -2278,8 +2278,8 @@ static void ieee80211_rx_bss_info(struct
760         bool need_ps = false;
761  
762         if (sdata->u.mgd.associated &&
763 -           memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
764 -                  ETH_ALEN) == 0) {
765 +           compare_ether_addr(mgmt->bssid, sdata->u.mgd.associated->bssid)
766 +           == 0) {
767                 bss = (void *)sdata->u.mgd.associated->priv;
768                 /* not previously set so we may need to recalc */
769                 need_ps = !bss->dtim_period;
770 @@ -2334,7 +2334,7 @@ static void ieee80211_rx_mgmt_probe_resp
771  
772         ASSERT_MGD_MTX(ifmgd);
773  
774 -       if (memcmp(mgmt->da, sdata->vif.addr, ETH_ALEN))
775 +       if (compare_ether_addr(mgmt->da, sdata->vif.addr))
776                 return; /* ignore ProbeResp to foreign address */
777  
778         baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
779 @@ -2347,11 +2347,12 @@ static void ieee80211_rx_mgmt_probe_resp
780         ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
781  
782         if (ifmgd->associated &&
783 -           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN) == 0)
784 +           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid) == 0)
785                 ieee80211_reset_ap_probe(sdata);
786  
787         if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies &&
788 -           memcmp(mgmt->bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN) == 0) {
789 +           compare_ether_addr(mgmt->bssid, ifmgd->auth_data->bss->bssid)
790 +           == 0) {
791                 /* got probe response, continue with auth */
792                 printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
793                 ifmgd->auth_data->tries = 0;
794 @@ -2408,7 +2409,8 @@ static void ieee80211_rx_mgmt_beacon(str
795                 return;
796  
797         if (ifmgd->assoc_data && !ifmgd->assoc_data->have_beacon &&
798 -           memcmp(mgmt->bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN) == 0) {
799 +           compare_ether_addr(mgmt->bssid, ifmgd->assoc_data->bss->bssid)
800 +           == 0) {
801                 ieee802_11_parse_elems(mgmt->u.beacon.variable,
802                                        len - baselen, &elems);
803  
804 @@ -2423,7 +2425,7 @@ static void ieee80211_rx_mgmt_beacon(str
805         }
806  
807         if (!ifmgd->associated ||
808 -           memcmp(mgmt->bssid, ifmgd->associated->bssid, ETH_ALEN))
809 +           compare_ether_addr(mgmt->bssid, ifmgd->associated->bssid))
810                 return;
811         bssid = ifmgd->associated->bssid;
812  
813 @@ -3285,7 +3287,7 @@ int ieee80211_mgd_assoc(struct ieee80211
814                 bool match;
815  
816                 /* keep sta info, bssid if matching */
817 -               match = memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN) == 0;
818 +               match = compare_ether_addr(ifmgd->bssid, req->bss->bssid) == 0;
819                 ieee80211_destroy_auth_data(sdata, match);
820         }
821  
822 @@ -3407,7 +3409,7 @@ int ieee80211_mgd_assoc(struct ieee80211
823                         goto err_clear;
824                 }
825         } else
826 -               WARN_ON_ONCE(memcmp(ifmgd->bssid, req->bss->bssid, ETH_ALEN));
827 +               WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid));
828  
829         if (!bss->dtim_period &&
830             sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
831 @@ -3448,7 +3450,7 @@ int ieee80211_mgd_deauth(struct ieee8021
832         mutex_lock(&ifmgd->mtx);
833  
834         if (ifmgd->associated &&
835 -           memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0) {
836 +           compare_ether_addr(ifmgd->associated->bssid, req->bssid) == 0) {
837                 ieee80211_set_disassoc(sdata, false, true);
838                 assoc_bss = true;
839         } else if (ifmgd->auth_data) {
840 --- a/net/mac80211/status.c
841 +++ b/net/mac80211/status.c
842 @@ -10,6 +10,7 @@
843   */
844  
845  #include <linux/export.h>
846 +#include <linux/etherdevice.h>
847  #include <net/mac80211.h>
848  #include <asm/unaligned.h>
849  #include "ieee80211_i.h"
850 @@ -377,7 +378,7 @@ void ieee80211_tx_status(struct ieee8021
851  
852         for_each_sta_info(local, hdr->addr1, sta, tmp) {
853                 /* skip wrong virtual interface */
854 -               if (memcmp(hdr->addr2, sta->sdata->vif.addr, ETH_ALEN))
855 +               if (compare_ether_addr(hdr->addr2, sta->sdata->vif.addr))
856                         continue;
857  
858                 if (info->flags & IEEE80211_TX_STATUS_EOSP)
859 --- a/net/wireless/mlme.c
860 +++ b/net/wireless/mlme.c
861 @@ -6,6 +6,7 @@
862  
863  #include <linux/kernel.h>
864  #include <linux/module.h>
865 +#include <linux/etherdevice.h>
866  #include <linux/netdevice.h>
867  #include <linux/nl80211.h>
868  #include <linux/slab.h>
869 @@ -100,7 +101,7 @@ void __cfg80211_send_deauth(struct net_d
870         ASSERT_WDEV_LOCK(wdev);
871  
872         if (wdev->current_bss &&
873 -           memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
874 +           compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) {
875                 cfg80211_unhold_bss(wdev->current_bss);
876                 cfg80211_put_bss(&wdev->current_bss->pub);
877                 wdev->current_bss = NULL;
878 @@ -115,7 +116,7 @@ void __cfg80211_send_deauth(struct net_d
879  
880                 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
881  
882 -               from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
883 +               from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0;
884                 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
885         } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
886                 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
887 @@ -154,7 +155,7 @@ void __cfg80211_send_disassoc(struct net
888                 return;
889  
890         if (wdev->current_bss &&
891 -           memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
892 +           compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0) {
893                 cfg80211_sme_disassoc(dev, wdev->current_bss);
894                 cfg80211_unhold_bss(wdev->current_bss);
895                 cfg80211_put_bss(&wdev->current_bss->pub);
896 @@ -165,7 +166,7 @@ void __cfg80211_send_disassoc(struct net
897  
898         reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
899  
900 -       from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
901 +       from_ap = compare_ether_addr(mgmt->sa, dev->dev_addr) != 0;
902         __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
903  }
904  EXPORT_SYMBOL(__cfg80211_send_disassoc);
905 @@ -285,7 +286,7 @@ int __cfg80211_mlme_auth(struct cfg80211
906                         return -EINVAL;
907  
908         if (wdev->current_bss &&
909 -           memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
910 +           compare_ether_addr(bssid, wdev->current_bss->pub.bssid) == 0)
911                 return -EALREADY;
912  
913         memset(&req, 0, sizeof(req));
914 @@ -362,7 +363,7 @@ int __cfg80211_mlme_assoc(struct cfg8021
915         memset(&req, 0, sizeof(req));
916  
917         if (wdev->current_bss && prev_bssid &&
918 -           memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
919 +           compare_ether_addr(wdev->current_bss->pub.bssid, prev_bssid) == 0) {
920                 /*
921                  * Trying to reassociate: Allow this to proceed and let the old
922                  * association to be dropped when the new one is completed.
923 @@ -446,7 +447,8 @@ int __cfg80211_mlme_deauth(struct cfg802
924  
925         if (local_state_change) {
926                 if (wdev->current_bss &&
927 -                   memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
928 +                   compare_ether_addr(wdev->current_bss->pub.bssid, bssid)
929 +                   == 0) {
930                         cfg80211_unhold_bss(wdev->current_bss);
931                         cfg80211_put_bss(&wdev->current_bss->pub);
932                         wdev->current_bss = NULL;
933 @@ -495,7 +497,7 @@ static int __cfg80211_mlme_disassoc(stru
934         req.local_state_change = local_state_change;
935         req.ie = ie;
936         req.ie_len = ie_len;
937 -       if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
938 +       if (compare_ether_addr(wdev->current_bss->pub.bssid, bssid) == 0)
939                 req.bss = &wdev->current_bss->pub;
940         else
941                 return -ENOTCONN;
942 @@ -758,8 +760,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg8021
943                                 break;
944                         }
945  
946 -                       if (memcmp(wdev->current_bss->pub.bssid,
947 -                                  mgmt->bssid, ETH_ALEN)) {
948 +                       if (compare_ether_addr(wdev->current_bss->pub.bssid,
949 +                                              mgmt->bssid)) {
950                                 err = -ENOTCONN;
951                                 break;
952                         }
953 @@ -772,8 +774,8 @@ int cfg80211_mlme_mgmt_tx(struct cfg8021
954                                 break;
955  
956                         /* for station, check that DA is the AP */
957 -                       if (memcmp(wdev->current_bss->pub.bssid,
958 -                                  mgmt->da, ETH_ALEN)) {
959 +                       if (compare_ether_addr(wdev->current_bss->pub.bssid,
960 +                                              mgmt->da)) {
961                                 err = -ENOTCONN;
962                                 break;
963                         }
964 @@ -781,11 +783,11 @@ int cfg80211_mlme_mgmt_tx(struct cfg8021
965                 case NL80211_IFTYPE_AP:
966                 case NL80211_IFTYPE_P2P_GO:
967                 case NL80211_IFTYPE_AP_VLAN:
968 -                       if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
969 +                       if (compare_ether_addr(mgmt->bssid, dev->dev_addr))
970                                 err = -EINVAL;
971                         break;
972                 case NL80211_IFTYPE_MESH_POINT:
973 -                       if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) {
974 +                       if (compare_ether_addr(mgmt->sa, mgmt->bssid)) {
975                                 err = -EINVAL;
976                                 break;
977                         }
978 @@ -804,7 +806,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg8021
979                         return err;
980         }
981  
982 -       if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
983 +       if (compare_ether_addr(mgmt->sa, dev->dev_addr) != 0)
984                 return -EINVAL;
985  
986         /* Transmit the Action frame as requested by user space */
987 --- a/net/wireless/scan.c
988 +++ b/net/wireless/scan.c
989 @@ -378,7 +378,7 @@ static int cmp_bss_core(struct cfg80211_
990                                b->len_information_elements);
991         }
992  
993 -       return memcmp(a->bssid, b->bssid, ETH_ALEN);
994 +       return compare_ether_addr(a->bssid, b->bssid);
995  }
996  
997  static int cmp_bss(struct cfg80211_bss *a,
998 --- a/drivers/net/wireless/ath/ath9k/Kconfig
999 +++ b/drivers/net/wireless/ath/ath9k/Kconfig
1000 @@ -81,6 +81,14 @@ config ATH9K_DFS_CERTIFIED
1001           developed. At this point enabling this option won't do anything
1002           except increase code size.
1003  
1004 +config ATH9K_MAC_DEBUG
1005 +       bool "Atheros MAC statistics"
1006 +       depends on ATH9K_DEBUGFS
1007 +       default y
1008 +       ---help---
1009 +         This option enables collection of statistics for Rx/Tx status
1010 +         data and some other MAC related statistics
1011 +
1012  config ATH9K_RATE_CONTROL
1013         bool "Atheros ath9k rate control"
1014         depends on ATH9K
1015 --- a/drivers/net/wireless/ath/ath9k/debug.c
1016 +++ b/drivers/net/wireless/ath/ath9k/debug.c
1017 @@ -818,6 +818,7 @@ void ath_debug_stat_tx(struct ath_softc 
1018         if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN)
1019                 TX_STAT_INC(qnum, delim_underrun);
1020  
1021 +#ifdef CONFIG_ATH9K_MAC_DEBUG
1022         spin_lock(&sc->debug.samp_lock);
1023         TX_SAMP_DBG(jiffies) = jiffies;
1024         TX_SAMP_DBG(rssi_ctl0) = ts->ts_rssi_ctl0;
1025 @@ -844,6 +845,7 @@ void ath_debug_stat_tx(struct ath_softc 
1026  
1027         sc->debug.tsidx = (sc->debug.tsidx + 1) % ATH_DBG_MAX_SAMPLES;
1028         spin_unlock(&sc->debug.samp_lock);
1029 +#endif
1030  
1031  #undef TX_SAMP_DBG
1032  }
1033 @@ -1019,6 +1021,7 @@ void ath_debug_stat_rx(struct ath_softc 
1034  
1035         sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna;
1036  
1037 +#ifdef CONFIG_ATH9K_MAC_DEBUG
1038         spin_lock(&sc->debug.samp_lock);
1039         RX_SAMP_DBG(jiffies) = jiffies;
1040         RX_SAMP_DBG(rssi_ctl0) = rs->rs_rssi_ctl0;
1041 @@ -1035,6 +1038,8 @@ void ath_debug_stat_rx(struct ath_softc 
1042         sc->debug.rsidx = (sc->debug.rsidx + 1) % ATH_DBG_MAX_SAMPLES;
1043         spin_unlock(&sc->debug.samp_lock);
1044  
1045 +#endif
1046 +
1047  #undef RX_STAT_INC
1048  #undef RX_PHY_ERR_INC
1049  #undef RX_SAMP_DBG
1050 @@ -1278,6 +1283,8 @@ static const struct file_operations fops
1051         .llseek = default_llseek,
1052  };
1053  
1054 +#ifdef CONFIG_ATH9K_MAC_DEBUG
1055 +
1056  void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
1057  {
1058  #define ATH_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].c)
1059 @@ -1551,6 +1558,7 @@ static const struct file_operations fops
1060         .llseek = default_llseek,
1061  };
1062  
1063 +#endif
1064  
1065  int ath9k_init_debug(struct ath_hw *ah)
1066  {
1067 @@ -1604,8 +1612,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1068                             &fops_base_eeprom);
1069         debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
1070                             &fops_modal_eeprom);
1071 +#ifdef CONFIG_ATH9K_MAC_DEBUG
1072         debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
1073                             &fops_samps);
1074 +#endif
1075  
1076         debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
1077                            sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
1078 --- a/drivers/net/wireless/ath/ath9k/debug.h
1079 +++ b/drivers/net/wireless/ath/ath9k/debug.h
1080 @@ -235,16 +235,17 @@ struct ath9k_debug {
1081         struct dentry *debugfs_phy;
1082         u32 regidx;
1083         struct ath_stats stats;
1084 +#ifdef CONFIG_ATH9K_MAC_DEBUG
1085         spinlock_t samp_lock;
1086         struct ath_dbg_bb_mac_samp bb_mac_samp[ATH_DBG_MAX_SAMPLES];
1087         u8 sampidx;
1088         u8 tsidx;
1089         u8 rsidx;
1090 +#endif
1091  };
1092  
1093  int ath9k_init_debug(struct ath_hw *ah);
1094  
1095 -void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
1096  void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
1097  void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
1098                        struct ath_tx_status *ts, struct ath_txq *txq,
1099 @@ -258,10 +259,6 @@ static inline int ath9k_init_debug(struc
1100         return 0;
1101  }
1102  
1103 -static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
1104 -{
1105 -}
1106 -
1107  static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
1108                                             enum ath9k_int status)
1109  {
1110 @@ -282,4 +279,17 @@ static inline void ath_debug_stat_rx(str
1111  
1112  #endif /* CONFIG_ATH9K_DEBUGFS */
1113  
1114 +#ifdef CONFIG_ATH9K_MAC_DEBUG
1115 +
1116 +void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
1117 +
1118 +#else
1119 +
1120 +static inline void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
1121 +{
1122 +}
1123 +
1124 +#endif
1125 +
1126 +
1127  #endif /* DEBUG_H */
1128 --- a/drivers/net/wireless/ath/ath9k/init.c
1129 +++ b/drivers/net/wireless/ath/ath9k/init.c
1130 @@ -555,9 +555,11 @@ static int ath9k_init_softc(u16 devid, s
1131         mutex_init(&sc->mutex);
1132  #ifdef CONFIG_ATH9K_DEBUGFS
1133         spin_lock_init(&sc->nodes_lock);
1134 -       spin_lock_init(&sc->debug.samp_lock);
1135         INIT_LIST_HEAD(&sc->nodes);
1136  #endif
1137 +#ifdef CONFIG_ATH9K_MAC_DEBUG
1138 +       spin_lock_init(&sc->debug.samp_lock);
1139 +#endif
1140         tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
1141         tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
1142                      (unsigned long)sc);