aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorZhaoyang Liu <liuzy@marvell.com>2015-03-23 10:20:56 -0400
committerKalle Valo <kvalo@codeaurora.org>2015-03-30 04:34:51 -0400
commit4acaf048b1d27cb6e1b214d370ed993bb2aac664 (patch)
treeda59e666cca69ad9029485a97c1f7832ecc3db0a /drivers/net/wireless/mwifiex
parent5ff46f7923b87f6cc5d5d66df08c9b6379a0461e (diff)
mwifiex: recover from skb allocation failures during RX
This patch adds recovery mechanism for SDIO RX during SKB allocation failures. For allocation failures during multiport aggregation, we skip and drop RX packets. For single port read case, we will use preallocated card->mpa_rx.buf to complete cmd53 read. Now we terminate SDIO operations only upon cmd53 failures. CC: James Cameron <quozl@laptop.org> Signed-off-by: Zhaoyang Liu <liuzy@marvell.com> Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/mwifiex')
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 6af7a08253f2..d10320f89bc1 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1317,10 +1317,14 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1317 skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind], 1317 skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind],
1318 GFP_KERNEL | 1318 GFP_KERNEL |
1319 GFP_DMA); 1319 GFP_DMA);
1320 if (!skb_deaggr) 1320 if (!skb_deaggr) {
1321 goto error; 1321 dev_err(adapter->dev, "skb allocation failure drop pkt len=%d type=%d\n",
1322 pkt_len, pkt_type);
1323 curr_ptr += len_arr[pind];
1324 continue;
1325 }
1326
1322 skb_put(skb_deaggr, len_arr[pind]); 1327 skb_put(skb_deaggr, len_arr[pind]);
1323 card->mpa_rx.skb_arr[pind] = skb_deaggr;
1324 1328
1325 if ((pkt_type == MWIFIEX_TYPE_DATA || 1329 if ((pkt_type == MWIFIEX_TYPE_DATA ||
1326 (pkt_type == MWIFIEX_TYPE_AGGR_DATA && 1330 (pkt_type == MWIFIEX_TYPE_AGGR_DATA &&
@@ -1335,7 +1339,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1335 mwifiex_decode_rx_packet(adapter, skb_deaggr, 1339 mwifiex_decode_rx_packet(adapter, skb_deaggr,
1336 pkt_type); 1340 pkt_type);
1337 } else { 1341 } else {
1338 dev_err(adapter->dev, "wrong aggr pkt:\t" 1342 dev_err(adapter->dev, " drop wrong aggr pkt:\t"
1339 "sdio_single_port_rx_aggr=%d\t" 1343 "sdio_single_port_rx_aggr=%d\t"
1340 "type=%d len=%d max_len=%d\n", 1344 "type=%d len=%d max_len=%d\n",
1341 adapter->sdio_rx_aggr_enable, 1345 adapter->sdio_rx_aggr_enable,
@@ -1352,9 +1356,18 @@ rx_curr_single:
1352 if (f_do_rx_cur) { 1356 if (f_do_rx_cur) {
1353 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n", 1357 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
1354 port, rx_len); 1358 port, rx_len);
1359
1355 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA); 1360 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
1356 if (!skb) 1361 if (!skb) {
1357 goto error; 1362 dev_err(adapter->dev, "single skb allocated fail,\t"
1363 "drop pkt port=%d len=%d\n", port, rx_len);
1364 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
1365 card->mpa_rx.buf, rx_len,
1366 adapter->ioport + port))
1367 goto error;
1368 return 0;
1369 }
1370
1358 skb_put(skb, rx_len); 1371 skb_put(skb, rx_len);
1359 1372
1360 if (mwifiex_sdio_card_to_host(adapter, &pkt_type, 1373 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
@@ -1363,10 +1376,11 @@ rx_curr_single:
1363 goto error; 1376 goto error;
1364 if (!adapter->sdio_rx_aggr_enable && 1377 if (!adapter->sdio_rx_aggr_enable &&
1365 pkt_type == MWIFIEX_TYPE_AGGR_DATA) { 1378 pkt_type == MWIFIEX_TYPE_AGGR_DATA) {
1366 dev_err(adapter->dev, "Wrong pkt type %d\t" 1379 dev_err(adapter->dev, "drop wrong pkt type %d\t"
1367 "Current SDIO RX Aggr not enabled\n", 1380 "current SDIO RX Aggr not enabled\n",
1368 pkt_type); 1381 pkt_type);
1369 goto error; 1382 dev_kfree_skb_any(skb);
1383 return 0;
1370 } 1384 }
1371 1385
1372 mwifiex_decode_rx_packet(adapter, skb, pkt_type); 1386 mwifiex_decode_rx_packet(adapter, skb, pkt_type);
@@ -1379,16 +1393,8 @@ rx_curr_single:
1379 1393
1380 return 0; 1394 return 0;
1381error: 1395error:
1382 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1396 if (MP_RX_AGGR_IN_PROGRESS(card))
1383 /* Multiport-aggregation transfer failed - cleanup */
1384 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1385 /* copy pkt to deaggr buf */
1386 skb_deaggr = card->mpa_rx.skb_arr[pind];
1387 if (skb_deaggr)
1388 dev_kfree_skb_any(skb_deaggr);
1389 }
1390 MP_RX_AGGR_BUF_RESET(card); 1397 MP_RX_AGGR_BUF_RESET(card);
1391 }
1392 1398
1393 if (f_do_rx_cur && skb) 1399 if (f_do_rx_cur && skb)
1394 /* Single transfer pending. Free curr buff also */ 1400 /* Single transfer pending. Free curr buff also */