ath10k: fix aggregated 4addr Rx
authorMichal Kazior <michal.kazior@tieto.com>
Mon, 28 Jul 2014 20:59:42 +0000 (23:59 +0300)
committerKalle Valo <kvalo@qca.qualcomm.com>
Tue, 29 Jul 2014 09:43:37 +0000 (12:43 +0300)
A-MSDU 4addr frames weren't reconstructed properly
and in some cases this resulted in a warning:

 br0: received packet on wlan0.sta1 with own address as source address

Since this was only related to A-MSDU it would
trigger when more intense traffic was generated.

Reported-by: Vu Hai NGUYEN <vh.nguyen@actiasodielec.fr>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/htt_rx.c

index 80cdac15588a2352608881acb5fc59fe8808f0ec..e31d93e3e98b194e5177a157fc82a23e5720a86f 100644 (file)
@@ -866,7 +866,7 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
        enum rx_msdu_decap_format fmt;
        enum htt_rx_mpdu_encrypt_type enctype;
        struct ieee80211_hdr *hdr;
-       u8 hdr_buf[64], addr[ETH_ALEN], *qos;
+       u8 hdr_buf[64], da[ETH_ALEN], sa[ETH_ALEN], *qos;
        unsigned int hdr_len;
 
        rxd = (void *)skb->data - sizeof(*rxd);
@@ -904,10 +904,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
                        skb_trim(skb, skb->len - FCS_LEN);
                        break;
                case RX_MSDU_DECAP_NATIVE_WIFI:
-                       /* pull decapped header and copy DA */
+                       /* pull decapped header and copy SA & DA */
                        hdr = (struct ieee80211_hdr *)skb->data;
                        hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr);
-                       memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
+                       memcpy(da, ieee80211_get_DA(hdr), ETH_ALEN);
+                       memcpy(sa, ieee80211_get_SA(hdr), ETH_ALEN);
                        skb_pull(skb, hdr_len);
 
                        /* push original 802.11 header */
@@ -921,8 +922,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
                        qos = ieee80211_get_qos_ctl(hdr);
                        qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
 
-                       /* original 802.11 header has a different DA */
-                       memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
+                       /* original 802.11 header has a different DA and in
+                        * case of 4addr it may also have different SA
+                        */
+                       memcpy(ieee80211_get_DA(hdr), da, ETH_ALEN);
+                       memcpy(ieee80211_get_SA(hdr), sa, ETH_ALEN);
                        break;
                case RX_MSDU_DECAP_ETHERNET2_DIX:
                        /* strip ethernet header and insert decapped 802.11