aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>2016-09-09 10:25:29 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2016-09-13 08:31:02 -0400
commit9e19e13261423eeb4398177001daa874c2128aa4 (patch)
treec9c88eefc019385f8473127bc92a94e95d4e6231 /drivers/net/wireless/ath
parentae02c8719aab19bf311b6ce2881feb844456297e (diff)
ath10k: properly remove padding from the start of rx payload
In QCA99X0 (QCA99X0, QCA9984, QCA9888 and QCA4019) family chips, hw adds padding at the begining of the rx payload to make L3 header 4-byte aligned. In the chips doing this type of padding, the number of bytes padded will be indicated through msdu_end:info1. Define a hw_rx_desc_ops wrapper to retrieve the number of padded bytes and use this while doing undecap. This should fix padding related issues with ethernt decap format with QCA99X0, QCA9984, QCA9888 and QCA4019 hw. Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com> [Rename operations to hw_ops for other purposes] Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c36
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h9
2 files changed, 31 insertions, 14 deletions
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 714b0deded9c..a3785a9aa843 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1051,9 +1051,11 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
1051 const u8 first_hdr[64]) 1051 const u8 first_hdr[64])
1052{ 1052{
1053 struct ieee80211_hdr *hdr; 1053 struct ieee80211_hdr *hdr;
1054 struct htt_rx_desc *rxd;
1054 size_t hdr_len; 1055 size_t hdr_len;
1055 u8 da[ETH_ALEN]; 1056 u8 da[ETH_ALEN];
1056 u8 sa[ETH_ALEN]; 1057 u8 sa[ETH_ALEN];
1058 int l3_pad_bytes;
1057 1059
1058 /* Delivered decapped frame: 1060 /* Delivered decapped frame:
1059 * [nwifi 802.11 header] <-- replaced with 802.11 hdr 1061 * [nwifi 802.11 header] <-- replaced with 802.11 hdr
@@ -1067,19 +1069,12 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
1067 */ 1069 */
1068 1070
1069 /* pull decapped header and copy SA & DA */ 1071 /* pull decapped header and copy SA & DA */
1070 if ((ar->hw_params.hw_4addr_pad == ATH10K_HW_4ADDR_PAD_BEFORE) && 1072 rxd = (void *)msdu->data - sizeof(*rxd);
1071 ieee80211_has_a4(((struct ieee80211_hdr *)first_hdr)->frame_control)) { 1073
1072 /* The QCA99X0 4 address mode pad 2 bytes at the 1074 l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1073 * beginning of MSDU 1075 skb_put(msdu, l3_pad_bytes);
1074 */ 1076
1075 hdr = (struct ieee80211_hdr *)(msdu->data + 2); 1077 hdr = (struct ieee80211_hdr *)(msdu->data + l3_pad_bytes);
1076 /* The skb length need be extended 2 as the 2 bytes at the tail
1077 * be excluded due to the padding
1078 */
1079 skb_put(msdu, 2);
1080 } else {
1081 hdr = (struct ieee80211_hdr *)(msdu->data);
1082 }
1083 1078
1084 hdr_len = ath10k_htt_rx_nwifi_hdrlen(ar, hdr); 1079 hdr_len = ath10k_htt_rx_nwifi_hdrlen(ar, hdr);
1085 ether_addr_copy(da, ieee80211_get_DA(hdr)); 1080 ether_addr_copy(da, ieee80211_get_DA(hdr));
@@ -1146,6 +1141,8 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
1146 void *rfc1042; 1141 void *rfc1042;
1147 u8 da[ETH_ALEN]; 1142 u8 da[ETH_ALEN];
1148 u8 sa[ETH_ALEN]; 1143 u8 sa[ETH_ALEN];
1144 int l3_pad_bytes;
1145 struct htt_rx_desc *rxd;
1149 1146
1150 /* Delivered decapped frame: 1147 /* Delivered decapped frame:
1151 * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc 1148 * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
@@ -1156,6 +1153,11 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
1156 if (WARN_ON_ONCE(!rfc1042)) 1153 if (WARN_ON_ONCE(!rfc1042))
1157 return; 1154 return;
1158 1155
1156 rxd = (void *)msdu->data - sizeof(*rxd);
1157 l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1158 skb_put(msdu, l3_pad_bytes);
1159 skb_pull(msdu, l3_pad_bytes);
1160
1159 /* pull decapped header and copy SA & DA */ 1161 /* pull decapped header and copy SA & DA */
1160 eth = (struct ethhdr *)msdu->data; 1162 eth = (struct ethhdr *)msdu->data;
1161 ether_addr_copy(da, eth->h_dest); 1163 ether_addr_copy(da, eth->h_dest);
@@ -1186,6 +1188,8 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
1186{ 1188{
1187 struct ieee80211_hdr *hdr; 1189 struct ieee80211_hdr *hdr;
1188 size_t hdr_len; 1190 size_t hdr_len;
1191 int l3_pad_bytes;
1192 struct htt_rx_desc *rxd;
1189 1193
1190 /* Delivered decapped frame: 1194 /* Delivered decapped frame:
1191 * [amsdu header] <-- replaced with 802.11 hdr 1195 * [amsdu header] <-- replaced with 802.11 hdr
@@ -1193,7 +1197,11 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
1193 * [payload] 1197 * [payload]
1194 */ 1198 */
1195 1199
1196 skb_pull(msdu, sizeof(struct amsdu_subframe_hdr)); 1200 rxd = (void *)msdu->data - sizeof(*rxd);
1201 l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(&ar->hw_params, rxd);
1202
1203 skb_put(msdu, l3_pad_bytes);
1204 skb_pull(msdu, sizeof(struct amsdu_subframe_hdr) + l3_pad_bytes);
1197 1205
1198 hdr = (struct ieee80211_hdr *)first_hdr; 1206 hdr = (struct ieee80211_hdr *)first_hdr;
1199 hdr_len = ieee80211_hdrlen(hdr->frame_control); 1207 hdr_len = ieee80211_hdrlen(hdr->frame_control);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 1b5ea3147f3a..204f88273572 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -428,6 +428,15 @@ struct ath10k_hw_ops {
428extern const struct ath10k_hw_ops qca988x_ops; 428extern const struct ath10k_hw_ops qca988x_ops;
429extern const struct ath10k_hw_ops qca99x0_ops; 429extern const struct ath10k_hw_ops qca99x0_ops;
430 430
431static inline int
432ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
433 struct htt_rx_desc *rxd)
434{
435 if (hw->hw_ops->rx_desc_get_l3_pad_bytes)
436 return hw->hw_ops->rx_desc_get_l3_pad_bytes(rxd);
437 return 0;
438}
439
431/* Target specific defines for MAIN firmware */ 440/* Target specific defines for MAIN firmware */
432#define TARGET_NUM_VDEVS 8 441#define TARGET_NUM_VDEVS 8
433#define TARGET_NUM_PEER_AST 2 442#define TARGET_NUM_PEER_AST 2