Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 34de9f1d authored by Dmitry Antipov's avatar Dmitry Antipov Committed by Greg Kroah-Hartman
Browse files

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



[ Upstream commit 288c63d5cb4667a51a04668b3e2bb0ea499bc5f4 ]

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


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 87f8c544
Loading
Loading
Loading
Loading
+17 −8
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ static int mwifiex_pcie_probe_of(struct device *dev)
}

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
mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
@@ -627,14 +629,15 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
		if (!skb) {
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb for RX ring.\n");
			kfree(card->rxbd_ring_vbase);
			return -ENOMEM;
		}

		if (mwifiex_map_pci_memory(adapter, skb,
					   MWIFIEX_RX_DATA_BUF_SIZE,
					   DMA_FROM_DEVICE))
			return -1;
					   DMA_FROM_DEVICE)) {
			kfree_skb(skb);
			return -ENOMEM;
		}

		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);

@@ -684,7 +687,6 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
		if (!skb) {
			mwifiex_dbg(adapter, ERROR,
				    "Unable to allocate skb for EVENT buf.\n");
			kfree(card->evtbd_ring_vbase);
			return -ENOMEM;
		}
		skb_put(skb, MAX_EVENT_SIZE);
@@ -692,8 +694,7 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter)
		if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE,
					   DMA_FROM_DEVICE)) {
			kfree_skb(skb);
			kfree(card->evtbd_ring_vbase);
			return -1;
			return -ENOMEM;
		}

		buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
@@ -892,6 +893,7 @@ static int mwifiex_pcie_delete_txbd_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;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

@@ -930,7 +932,10 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter)
		    (u32)((u64)card->rxbd_ring_pbase >> 32),
		    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;
}

/*
@@ -961,6 +966,7 @@ static int mwifiex_pcie_delete_rxbd_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;
	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;

@@ -995,7 +1001,10 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter)
		    (u32)((u64)card->evtbd_ring_pbase >> 32),
		    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;
}

/*