aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/htt_rx.c
diff options
context:
space:
mode:
authorJanusz Dziedzic <janusz.dziedzic@tieto.com>2014-03-24 16:23:20 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2014-03-25 08:12:29 -0400
commitd84dd60f2ccd6d17965adeb30435770b6f7b6608 (patch)
treedf9d146b83c4a658409a13a50186edcb49c4bad2 /drivers/net/wireless/ath/ath10k/htt_rx.c
parent87326c97b8a49fb8ec1cc4abddbfddc8a963d665 (diff)
ath10k: return error when ath10k_htt_rx_amsdu_pop() fail
Return error when rx_amsdu_pop() will fail. Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/htt_rx.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a994a4f9dc1a..64abc2ab6041 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -297,6 +297,7 @@ static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb)
297 } 297 }
298} 298}
299 299
300/* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */
300static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, 301static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
301 u8 **fw_desc, int *fw_desc_len, 302 u8 **fw_desc, int *fw_desc_len,
302 struct sk_buff **head_msdu, 303 struct sk_buff **head_msdu,
@@ -310,7 +311,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
310 311
311 if (htt->rx_confused) { 312 if (htt->rx_confused) {
312 ath10k_warn("htt is confused. refusing rx\n"); 313 ath10k_warn("htt is confused. refusing rx\n");
313 return 0; 314 return -1;
314 } 315 }
315 316
316 msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt); 317 msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt);
@@ -442,6 +443,9 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
442 } 443 }
443 *tail_msdu = msdu; 444 *tail_msdu = msdu;
444 445
446 if (*head_msdu == NULL)
447 msdu_chaining = -1;
448
445 /* 449 /*
446 * Don't refill the ring yet. 450 * Don't refill the ring yet.
447 * 451 *
@@ -1139,11 +1143,6 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
1139 enum htt_rx_mpdu_status status, 1143 enum htt_rx_mpdu_status status,
1140 bool channel_set) 1144 bool channel_set)
1141{ 1145{
1142 if (!head) {
1143 ath10k_warn("htt rx no data!\n");
1144 return false;
1145 }
1146
1147 if (head->len == 0) { 1146 if (head->len == 0) {
1148 ath10k_dbg(ATH10K_DBG_HTT, 1147 ath10k_dbg(ATH10K_DBG_HTT,
1149 "htt rx dropping due to zero-len\n"); 1148 "htt rx dropping due to zero-len\n");
@@ -1199,6 +1198,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
1199 u8 *fw_desc; 1198 u8 *fw_desc;
1200 bool channel_set, fcs_err, mic_err; 1199 bool channel_set, fcs_err, mic_err;
1201 int i, j; 1200 int i, j;
1201 int ret;
1202 1202
1203 lockdep_assert_held(&htt->rx_ring.lock); 1203 lockdep_assert_held(&htt->rx_ring.lock);
1204 1204
@@ -1242,15 +1242,21 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
1242 1242
1243 for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) { 1243 for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
1244 struct sk_buff *msdu_head, *msdu_tail; 1244 struct sk_buff *msdu_head, *msdu_tail;
1245 int msdu_chaining;
1246 1245
1247 msdu_head = NULL; 1246 msdu_head = NULL;
1248 msdu_tail = NULL; 1247 msdu_tail = NULL;
1249 msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, 1248 ret = ath10k_htt_rx_amsdu_pop(htt,
1250 &fw_desc, 1249 &fw_desc,
1251 &fw_desc_len, 1250 &fw_desc_len,
1252 &msdu_head, 1251 &msdu_head,
1253 &msdu_tail); 1252 &msdu_tail);
1253
1254 if (ret < 0) {
1255 ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
1256 ret);
1257 ath10k_htt_rx_free_msdu_chain(msdu_head);
1258 continue;
1259 }
1254 1260
1255 if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head, 1261 if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
1256 status, 1262 status,
@@ -1259,8 +1265,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
1259 continue; 1265 continue;
1260 } 1266 }
1261 1267
1262 if (msdu_chaining && 1268 if (ret > 0 &&
1263 (ath10k_unchain_msdu(msdu_head) < 0)) { 1269 ath10k_unchain_msdu(msdu_head) < 0) {
1264 ath10k_htt_rx_free_msdu_chain(msdu_head); 1270 ath10k_htt_rx_free_msdu_chain(msdu_head);
1265 continue; 1271 continue;
1266 } 1272 }
@@ -1308,7 +1314,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
1308 enum rx_msdu_decap_format fmt; 1314 enum rx_msdu_decap_format fmt;
1309 struct htt_rx_info info = {}; 1315 struct htt_rx_info info = {};
1310 struct ieee80211_hdr *hdr; 1316 struct ieee80211_hdr *hdr;
1311 int msdu_chaining; 1317 int ret;
1312 bool tkip_mic_err; 1318 bool tkip_mic_err;
1313 bool decrypt_err; 1319 bool decrypt_err;
1314 u8 *fw_desc; 1320 u8 *fw_desc;
@@ -1322,19 +1328,15 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
1322 msdu_tail = NULL; 1328 msdu_tail = NULL;
1323 1329
1324 spin_lock_bh(&htt->rx_ring.lock); 1330 spin_lock_bh(&htt->rx_ring.lock);
1325 msdu_chaining = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len, 1331 ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len,
1326 &msdu_head, &msdu_tail); 1332 &msdu_head, &msdu_tail);
1327 spin_unlock_bh(&htt->rx_ring.lock); 1333 spin_unlock_bh(&htt->rx_ring.lock);
1328 1334
1329 ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); 1335 ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
1330 1336
1331 if (!msdu_head) { 1337 if (ret) {
1332 ath10k_warn("htt rx frag no data\n"); 1338 ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n",
1333 return; 1339 ret);
1334 }
1335
1336 if (msdu_chaining || msdu_head != msdu_tail) {
1337 ath10k_warn("aggregation with fragmentation?!\n");
1338 ath10k_htt_rx_free_msdu_chain(msdu_head); 1340 ath10k_htt_rx_free_msdu_chain(msdu_head);
1339 return; 1341 return;
1340 } 1342 }