summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wcn36xx/dxe.h
diff options
context:
space:
mode:
authorLoic Poulain <loic.poulain@linaro.org>2018-03-27 10:26:57 +0200
committerKalle Valo <kvalo@codeaurora.org>2018-03-29 10:57:19 +0200
commite5f9908155c96d945b6d1053701b6168c4e8decc (patch)
tree8db4be4b6eb3c1940ef73d71045669d1f218ddf5 /drivers/net/wireless/ath/wcn36xx/dxe.h
parentwcn36xx: turn off probe response offloading (diff)
downloadlinux-e5f9908155c96d945b6d1053701b6168c4e8decc.tar.xz
linux-e5f9908155c96d945b6d1053701b6168c4e8decc.zip
wcn36xx: Fix firmware crash due to corrupted buffer address
wcn36xx_start_tx function retrieves the buffer descriptor from the channel control queue to start filling tx buffer information. However, nothing prevents this same buffer to be concurrently accessed in a concurent tx call, leading to potential buffer coruption and firmware crash (observed during iperf test). The channel control queue should only be accessed and updated with the channel lock. Fix this issue by using a local buffer descriptor which will be copied in the thread-safe wcn36xx_dxe_tx_frame. Note that buffer descriptor size is few bytes so the introduced copy overhead is insignificant. Moreover, this allows to keep the locked section minimal. Signed-off-by: Loic Poulain <loic.poulain@linaro.org> Signed-off-by: Ramon Fried <rfried@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/wcn36xx/dxe.h')
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h
index 2bc376c5391b..ce580960d109 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.h
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.h
@@ -452,6 +452,7 @@ struct wcn36xx_dxe_mem_pool {
dma_addr_t phy_addr;
};
+struct wcn36xx_tx_bd;
struct wcn36xx_vif;
int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn);
void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn);
@@ -463,8 +464,8 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn);
int wcn36xx_dxe_init_channels(struct wcn36xx *wcn);
int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn,
struct wcn36xx_vif *vif_priv,
+ struct wcn36xx_tx_bd *bd,
struct sk_buff *skb,
bool is_low);
void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status);
-void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low);
#endif /* _DXE_H_ */