Commit 288c63d5 authored by Dmitry Antipov's avatar Dmitry Antipov Committed by Kalle Valo

wifi: mwifiex: fix error recovery in PCIE buffer descriptor management

Add missing 'kfree_skb()' in 'mwifiex_init_rxq_ring()' and never do
'kfree(card->rxbd_ring_vbase)' because this area is DMAed and should
be released with 'dma_free_coherent()'. The latter is performed in
'mwifiex_pcie_delete_rxbd_ring()', which is now called to recover
from possible errors in 'mwifiex_pcie_create_rxbd_ring()'. Likewise
for 'mwifiex_pcie_init_evt_ring()', 'kfree(card->evtbd_ring_vbase)'
'mwifiex_pcie_delete_evtbd_ring()' and 'mwifiex_pcie_create_rxbd_ring()'.

Fixes: d930faee ("mwifiex: add support for Marvell pcie8766 chipset")
Signed-off-by: default avatarDmitry Antipov <dmantipov@yandex.ru>
Acked-by: default avatarBrian Norris <briannorris@chromium.org>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230731074334.56463-1-dmantipov@yandex.ru
parent 0701519f
...@@ -189,6 +189,8 @@ static int mwifiex_pcie_probe_of(struct device *dev) ...@@ -189,6 +189,8 @@ static int mwifiex_pcie_probe_of(struct device *dev)
} }
static void mwifiex_pcie_work(struct work_struct *work); static void mwifiex_pcie_work(struct work_struct *work);
static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter);
static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter);
static int static int
mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
...@@ -792,14 +794,15 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) ...@@ -792,14 +794,15 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
if (!skb) { if (!skb) {
mwifiex_dbg(adapter, ERROR, mwifiex_dbg(adapter, ERROR,
"Unable to allocate skb for RX ring.\n"); "Unable to allocate skb for RX ring.\n");
kfree(card->rxbd_ring_vbase);
return -ENOMEM; return -ENOMEM;
} }
if (mwifiex_map_pci_memory(adapter, skb, if (mwifiex_map_pci_memory(adapter, skb,
MWIFIEX_RX_DATA_BUF_SIZE, MWIFIEX_RX_DATA_BUF_SIZE,
DMA_FROM_DEVICE)) DMA_FROM_DEVICE)) {
return -1; kfree_skb(skb);
return -ENOMEM;
}
buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
...@@ -849,7 +852,6 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) ...@@ -849,7 +852,6 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
if (!skb) { if (!skb) {
mwifiex_dbg(adapter, ERROR, mwifiex_dbg(adapter, ERROR,
"Unable to allocate skb for EVENT buf.\n"); "Unable to allocate skb for EVENT buf.\n");
kfree(card->evtbd_ring_vbase);
return -ENOMEM; return -ENOMEM;
} }
skb_put(skb, MAX_EVENT_SIZE); skb_put(skb, MAX_EVENT_SIZE);
...@@ -857,8 +859,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) ...@@ -857,8 +859,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
DMA_FROM_DEVICE)) { DMA_FROM_DEVICE)) {
kfree_skb(skb); kfree_skb(skb);
kfree(card->evtbd_ring_vbase); return -ENOMEM;
return -1;
} }
buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
...@@ -1058,6 +1059,7 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) ...@@ -1058,6 +1059,7 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter)
*/ */
static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
{ {
int ret;
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
...@@ -1096,7 +1098,10 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) ...@@ -1096,7 +1098,10 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
(u32)((u64)card->rxbd_ring_pbase >> 32), (u32)((u64)card->rxbd_ring_pbase >> 32),
card->rxbd_ring_size); card->rxbd_ring_size);
return mwifiex_init_rxq_ring(adapter); ret = mwifiex_init_rxq_ring(adapter);
if (ret)
mwifiex_pcie_delete_rxbd_ring(adapter);
return ret;
} }
/* /*
...@@ -1127,6 +1132,7 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) ...@@ -1127,6 +1132,7 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter)
*/ */
static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
{ {
int ret;
struct pcie_service_card *card = adapter->card; struct pcie_service_card *card = adapter->card;
const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
...@@ -1161,7 +1167,10 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) ...@@ -1161,7 +1167,10 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
(u32)((u64)card->evtbd_ring_pbase >> 32), (u32)((u64)card->evtbd_ring_pbase >> 32),
card->evtbd_ring_size); card->evtbd_ring_size);
return mwifiex_pcie_init_evt_ring(adapter); ret = mwifiex_pcie_init_evt_ring(adapter);
if (ret)
mwifiex_pcie_delete_evtbd_ring(adapter);
return ret;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment