diff options
author | Janusz Dziedzic <janusz.dziedzic@tieto.com> | 2014-03-24 16:23:20 -0400 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2014-03-25 08:12:29 -0400 |
commit | d84dd60f2ccd6d17965adeb30435770b6f7b6608 (patch) | |
tree | df9d146b83c4a658409a13a50186edcb49c4bad2 /drivers/net/wireless/ath/ath10k/htt_rx.c | |
parent | 87326c97b8a49fb8ec1cc4abddbfddc8a963d665 (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.c | 50 |
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 */ | ||
300 | static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, | 301 | static 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 | } |