summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex
diff options
context:
space:
mode:
authorZhaoyang Liu <liuzy@marvell.com>2015-03-23 15:20:56 +0100
committerKalle Valo <kvalo@codeaurora.org>2015-03-30 10:34:51 +0200
commit4acaf048b1d27cb6e1b214d370ed993bb2aac664 (patch)
treeda59e666cca69ad9029485a97c1f7832ecc3db0a /drivers/net/wireless/mwifiex
parentmwifiex: stop command path in suspend handler (diff)
downloadlinux-4acaf048b1d27cb6e1b214d370ed993bb2aac664.tar.xz
linux-4acaf048b1d27cb6e1b214d370ed993bb2aac664.zip
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,
skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind],
GFP_KERNEL |
GFP_DMA);
- if (!skb_deaggr)
- goto error;
+ if (!skb_deaggr) {
+ dev_err(adapter->dev, "skb allocation failure drop pkt len=%d type=%d\n",
+ pkt_len, pkt_type);
+ curr_ptr += len_arr[pind];
+ continue;
+ }
+
skb_put(skb_deaggr, len_arr[pind]);
- card->mpa_rx.skb_arr[pind] = skb_deaggr;
if ((pkt_type == MWIFIEX_TYPE_DATA ||
(pkt_type == MWIFIEX_TYPE_AGGR_DATA &&
@@ -1335,7 +1339,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
mwifiex_decode_rx_packet(adapter, skb_deaggr,
pkt_type);
} else {
- dev_err(adapter->dev, "wrong aggr pkt:\t"
+ dev_err(adapter->dev, " drop wrong aggr pkt:\t"
"sdio_single_port_rx_aggr=%d\t"
"type=%d len=%d max_len=%d\n",
adapter->sdio_rx_aggr_enable,
@@ -1352,9 +1356,18 @@ rx_curr_single:
if (f_do_rx_cur) {
dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
port, rx_len);
+
skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
- if (!skb)
- goto error;
+ if (!skb) {
+ dev_err(adapter->dev, "single skb allocated fail,\t"
+ "drop pkt port=%d len=%d\n", port, rx_len);
+ if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
+ card->mpa_rx.buf, rx_len,
+ adapter->ioport + port))
+ goto error;
+ return 0;
+ }
+
skb_put(skb, rx_len);
if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
@@ -1363,10 +1376,11 @@ rx_curr_single:
goto error;
if (!adapter->sdio_rx_aggr_enable &&
pkt_type == MWIFIEX_TYPE_AGGR_DATA) {
- dev_err(adapter->dev, "Wrong pkt type %d\t"
- "Current SDIO RX Aggr not enabled\n",
+ dev_err(adapter->dev, "drop wrong pkt type %d\t"
+ "current SDIO RX Aggr not enabled\n",
pkt_type);
- goto error;
+ dev_kfree_skb_any(skb);
+ return 0;
}
mwifiex_decode_rx_packet(adapter, skb, pkt_type);
@@ -1379,16 +1393,8 @@ rx_curr_single:
return 0;
error:
- if (MP_RX_AGGR_IN_PROGRESS(card)) {
- /* Multiport-aggregation transfer failed - cleanup */
- for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
- /* copy pkt to deaggr buf */
- skb_deaggr = card->mpa_rx.skb_arr[pind];
- if (skb_deaggr)
- dev_kfree_skb_any(skb_deaggr);
- }
+ if (MP_RX_AGGR_IN_PROGRESS(card))
MP_RX_AGGR_BUF_RESET(card);
- }
if (f_do_rx_cur && skb)
/* Single transfer pending. Free curr buff also */