summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/wcn36xx/dxe.c
diff options
context:
space:
mode:
authorDaniel Mack <daniel@zonque.org>2018-04-03 19:51:53 +0300
committerKalle Valo <kvalo@codeaurora.org>2018-04-10 17:34:14 +0300
commit271f1e65ff38f18aa440fec17c759e70a6adfa4e (patch)
treeaab76853c94a375f9b7c7bf75b49ae64afc17e74 /drivers/net/wireless/ath/wcn36xx/dxe.c
parent7cae35199bee1cd661926f2d68ac46d07682fc54 (diff)
downloadlinux-271f1e65ff38f18aa440fec17c759e70a6adfa4e.tar.xz
wcn36xx: don't keep reference to skb if transmission failed
When wcn36xx_dxe_tx_frame() fails to transmit the TX frame, the driver will call into ieee80211_free_txskb() for the skb in flight, so it'll no longer be valid. Hence, we shouldn't keep a reference to it in ctl->skb. Also, if the skb has IEEE80211_TX_CTL_REQ_TX_STATUS set, a pointer to it will currently remain in wcn->tx_ack_skb, which will potentially lead to a crash if accessed later. Fix this by checking the return value of wcn36xx_dxe_tx_frame(), and nullify wcn->tx_ack_skb again in case of errors. Move the assignment of ctl->skb in wcn36xx_dxe_tx_frame() so it only happens when the transmission is successful. Signed-off-by: Daniel Mack <daniel@zonque.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/wcn36xx/dxe.c')
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 405d350f8708..2cedb5a4f9e3 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -693,7 +693,6 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
/* Set source address of the SKB we send */
ctl = ctl->next;
- ctl->skb = skb;
desc = ctl->desc;
if (ctl->bd_cpu_addr) {
wcn36xx_err("bd_cpu_addr cannot be NULL for skb DXE\n");
@@ -702,8 +701,8 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
}
desc->src_addr_l = dma_map_single(wcn->dev,
- ctl->skb->data,
- ctl->skb->len,
+ skb->data,
+ skb->len,
DMA_TO_DEVICE);
if (dma_mapping_error(wcn->dev, desc->src_addr_l)) {
dev_err(wcn->dev, "unable to DMA map src_addr_l\n");
@@ -711,6 +710,7 @@ int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
goto unlock;
}
+ ctl->skb = skb;
desc->dst_addr_l = ch->dxe_wq;
desc->fr_len = ctl->skb->len;