| From 3b054c2cf3b252cfb0abf8798963382bd394421a Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 5 Jun 2021 18:33:47 +0100 |
| Subject: wcn36xx: Move hal_buf allocation to devm_kmalloc in probe |
| |
| From: Bryan O'Donoghue <bryan.odonoghue@linaro.org> |
| |
| [ Upstream commit ef48667557c53d4b51a1ee3090eab7699324c9de ] |
| |
| Right now wcn->hal_buf is allocated in wcn36xx_start(). This is a problem |
| since we should have setup all of the buffers we required by the time |
| ieee80211_register_hw() is called. |
| |
| struct ieee80211_ops callbacks may run prior to mac_start() and therefore |
| wcn->hal_buf must be initialized. |
| |
| This is easily remediated by moving the allocation to probe() taking the |
| opportunity to tidy up freeing memory by using devm_kmalloc(). |
| |
| Fixes: 8e84c2582169 ("wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware") |
| Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Link: https://lore.kernel.org/r/20210605173347.2266003-1-bryan.odonoghue@linaro.org |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/wireless/ath/wcn36xx/main.c | 21 ++++++++------------- |
| 1 file changed, 8 insertions(+), 13 deletions(-) |
| |
| diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c |
| index 706728fba72d..9f8e44210e89 100644 |
| --- a/drivers/net/wireless/ath/wcn36xx/main.c |
| +++ b/drivers/net/wireless/ath/wcn36xx/main.c |
| @@ -293,23 +293,16 @@ static int wcn36xx_start(struct ieee80211_hw *hw) |
| goto out_free_dxe_pool; |
| } |
| |
| - wcn->hal_buf = kmalloc(WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); |
| - if (!wcn->hal_buf) { |
| - wcn36xx_err("Failed to allocate smd buf\n"); |
| - ret = -ENOMEM; |
| - goto out_free_dxe_ctl; |
| - } |
| - |
| ret = wcn36xx_smd_load_nv(wcn); |
| if (ret) { |
| wcn36xx_err("Failed to push NV to chip\n"); |
| - goto out_free_smd_buf; |
| + goto out_free_dxe_ctl; |
| } |
| |
| ret = wcn36xx_smd_start(wcn); |
| if (ret) { |
| wcn36xx_err("Failed to start chip\n"); |
| - goto out_free_smd_buf; |
| + goto out_free_dxe_ctl; |
| } |
| |
| if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { |
| @@ -336,8 +329,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw) |
| |
| out_smd_stop: |
| wcn36xx_smd_stop(wcn); |
| -out_free_smd_buf: |
| - kfree(wcn->hal_buf); |
| out_free_dxe_ctl: |
| wcn36xx_dxe_free_ctl_blks(wcn); |
| out_free_dxe_pool: |
| @@ -372,8 +363,6 @@ static void wcn36xx_stop(struct ieee80211_hw *hw) |
| |
| wcn36xx_dxe_free_mem_pools(wcn); |
| wcn36xx_dxe_free_ctl_blks(wcn); |
| - |
| - kfree(wcn->hal_buf); |
| } |
| |
| static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable) |
| @@ -1398,6 +1387,12 @@ static int wcn36xx_probe(struct platform_device *pdev) |
| mutex_init(&wcn->hal_mutex); |
| mutex_init(&wcn->scan_lock); |
| |
| + wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); |
| + if (!wcn->hal_buf) { |
| + ret = -ENOMEM; |
| + goto out_wq; |
| + } |
| + |
| ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32)); |
| if (ret < 0) { |
| wcn36xx_err("failed to set DMA mask: %d\n", ret); |
| -- |
| 2.30.2 |
| |