Commit 9c57d7e3 authored by Vasanthakumar Thiagarajan's avatar Vasanthakumar Thiagarajan Committed by Kalle Valo

ath11k: Setup REO destination ring before sending wmi_init command

Firmware expects all the required REO destination rings setup
while processing wmi_init command. Not doing this causes connected
stations getting disconnected and not able to connect back.
Signed-off-by: default avatarVasanthakumar Thiagarajan <vthiagar@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 0366f426
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ahb.h" #include "ahb.h"
#include "core.h" #include "core.h"
#include "dp_tx.h" #include "dp_tx.h"
#include "dp_rx.h"
#include "debug.h" #include "debug.h"
unsigned int ath11k_debug_mask; unsigned int ath11k_debug_mask;
...@@ -325,6 +326,7 @@ static void ath11k_core_stop(struct ath11k_base *ab) ...@@ -325,6 +326,7 @@ static void ath11k_core_stop(struct ath11k_base *ab)
ath11k_qmi_firmware_stop(ab); ath11k_qmi_firmware_stop(ab);
ath11k_ahb_stop(ab); ath11k_ahb_stop(ab);
ath11k_wmi_detach(ab); ath11k_wmi_detach(ab);
ath11k_dp_pdev_reo_cleanup(ab);
/* De-Init of components as needed */ /* De-Init of components as needed */
} }
...@@ -476,28 +478,38 @@ static int ath11k_core_start(struct ath11k_base *ab, ...@@ -476,28 +478,38 @@ static int ath11k_core_start(struct ath11k_base *ab,
goto err_hif_stop; goto err_hif_stop;
} }
ath11k_dp_pdev_pre_alloc(ab);
ret = ath11k_dp_pdev_reo_setup(ab);
if (ret) {
ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
goto err_mac_destroy;
}
ret = ath11k_wmi_cmd_init(ab); ret = ath11k_wmi_cmd_init(ab);
if (ret) { if (ret) {
ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret); ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
goto err_mac_destroy; goto err_reo_cleanup;
} }
ret = ath11k_wmi_wait_for_unified_ready(ab); ret = ath11k_wmi_wait_for_unified_ready(ab);
if (ret) { if (ret) {
ath11k_err(ab, "failed to receive wmi unified ready event: %d\n", ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
ret); ret);
goto err_mac_destroy; goto err_reo_cleanup;
} }
ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab); ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
if (ret) { if (ret) {
ath11k_err(ab, "failed to send htt version request message: %d\n", ath11k_err(ab, "failed to send htt version request message: %d\n",
ret); ret);
goto err_mac_destroy; goto err_reo_cleanup;
} }
return 0; return 0;
err_reo_cleanup:
ath11k_dp_pdev_reo_cleanup(ab);
err_mac_destroy: err_mac_destroy:
ath11k_mac_destroy(ab); ath11k_mac_destroy(ab);
err_hif_stop: err_hif_stop:
...@@ -561,6 +573,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) ...@@ -561,6 +573,7 @@ static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
ath11k_dp_pdev_free(ab); ath11k_dp_pdev_free(ab);
ath11k_ahb_stop(ab); ath11k_ahb_stop(ab);
ath11k_wmi_detach(ab); ath11k_wmi_detach(ab);
ath11k_dp_pdev_reo_cleanup(ab);
mutex_unlock(&ab->core_lock); mutex_unlock(&ab->core_lock);
ath11k_dp_free(ab); ath11k_dp_free(ab);
......
...@@ -684,11 +684,10 @@ void ath11k_dp_pdev_free(struct ath11k_base *ab) ...@@ -684,11 +684,10 @@ void ath11k_dp_pdev_free(struct ath11k_base *ab)
} }
} }
int ath11k_dp_pdev_alloc(struct ath11k_base *ab) void ath11k_dp_pdev_pre_alloc(struct ath11k_base *ab)
{ {
struct ath11k *ar; struct ath11k *ar;
struct ath11k_pdev_dp *dp; struct ath11k_pdev_dp *dp;
int ret;
int i; int i;
for (i = 0; i < ab->num_radios; i++) { for (i = 0; i < ab->num_radios; i++) {
...@@ -704,6 +703,13 @@ int ath11k_dp_pdev_alloc(struct ath11k_base *ab) ...@@ -704,6 +703,13 @@ int ath11k_dp_pdev_alloc(struct ath11k_base *ab)
idr_init(&dp->rxdma_mon_buf_ring.bufs_idr); idr_init(&dp->rxdma_mon_buf_ring.bufs_idr);
spin_lock_init(&dp->rxdma_mon_buf_ring.idr_lock); spin_lock_init(&dp->rxdma_mon_buf_ring.idr_lock);
} }
}
int ath11k_dp_pdev_alloc(struct ath11k_base *ab)
{
struct ath11k *ar;
int ret;
int i;
/* TODO:Per-pdev rx ring unlike tx ring which is mapped to different AC's */ /* TODO:Per-pdev rx ring unlike tx ring which is mapped to different AC's */
for (i = 0; i < ab->num_radios; i++) { for (i = 0; i < ab->num_radios; i++) {
......
...@@ -1507,6 +1507,7 @@ void ath11k_dp_vdev_tx_attach(struct ath11k *ar, struct ath11k_vif *arvif); ...@@ -1507,6 +1507,7 @@ void ath11k_dp_vdev_tx_attach(struct ath11k *ar, struct ath11k_vif *arvif);
void ath11k_dp_free(struct ath11k_base *ab); void ath11k_dp_free(struct ath11k_base *ab);
int ath11k_dp_alloc(struct ath11k_base *ab); int ath11k_dp_alloc(struct ath11k_base *ab);
int ath11k_dp_pdev_alloc(struct ath11k_base *ab); int ath11k_dp_pdev_alloc(struct ath11k_base *ab);
void ath11k_dp_pdev_pre_alloc(struct ath11k_base *ab);
void ath11k_dp_pdev_free(struct ath11k_base *ab); void ath11k_dp_pdev_free(struct ath11k_base *ab);
int ath11k_dp_tx_htt_srng_setup(struct ath11k_base *ab, u32 ring_id, int ath11k_dp_tx_htt_srng_setup(struct ath11k_base *ab, u32 ring_id,
int mac_id, enum hal_ring_type ring_type); int mac_id, enum hal_ring_type ring_type);
......
...@@ -395,12 +395,51 @@ static void ath11k_dp_rx_pdev_srng_free(struct ath11k *ar) ...@@ -395,12 +395,51 @@ static void ath11k_dp_rx_pdev_srng_free(struct ath11k *ar)
struct ath11k_pdev_dp *dp = &ar->dp; struct ath11k_pdev_dp *dp = &ar->dp;
ath11k_dp_srng_cleanup(ar->ab, &dp->rx_refill_buf_ring.refill_buf_ring); ath11k_dp_srng_cleanup(ar->ab, &dp->rx_refill_buf_ring.refill_buf_ring);
ath11k_dp_srng_cleanup(ar->ab, &dp->reo_dst_ring);
ath11k_dp_srng_cleanup(ar->ab, &dp->rxdma_err_dst_ring); ath11k_dp_srng_cleanup(ar->ab, &dp->rxdma_err_dst_ring);
ath11k_dp_srng_cleanup(ar->ab, &dp->rx_mon_status_refill_ring.refill_buf_ring); ath11k_dp_srng_cleanup(ar->ab, &dp->rx_mon_status_refill_ring.refill_buf_ring);
ath11k_dp_srng_cleanup(ar->ab, &dp->rxdma_mon_buf_ring.refill_buf_ring); ath11k_dp_srng_cleanup(ar->ab, &dp->rxdma_mon_buf_ring.refill_buf_ring);
} }
void ath11k_dp_pdev_reo_cleanup(struct ath11k_base *ab)
{
struct ath11k_pdev_dp *dp;
struct ath11k *ar;
int i;
for (i = 0; i < ab->num_radios; i++) {
ar = ab->pdevs[i].ar;
dp = &ar->dp;
ath11k_dp_srng_cleanup(ab, &dp->reo_dst_ring);
}
}
int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab)
{
struct ath11k *ar;
struct ath11k_pdev_dp *dp;
int ret;
int i;
for (i = 0; i < ab->num_radios; i++) {
ar = ab->pdevs[i].ar;
dp = &ar->dp;
ret = ath11k_dp_srng_setup(ab, &dp->reo_dst_ring, HAL_REO_DST,
dp->mac_id, dp->mac_id,
DP_REO_DST_RING_SIZE);
if (ret) {
ath11k_warn(ar->ab, "failed to setup reo_dst_ring\n");
goto err_reo_cleanup;
}
}
return 0;
err_reo_cleanup:
ath11k_dp_pdev_reo_cleanup(ab);
return ret;
}
static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar) static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar)
{ {
struct ath11k_pdev_dp *dp = &ar->dp; struct ath11k_pdev_dp *dp = &ar->dp;
...@@ -416,14 +455,6 @@ static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar) ...@@ -416,14 +455,6 @@ static int ath11k_dp_rx_pdev_srng_alloc(struct ath11k *ar)
return ret; return ret;
} }
ret = ath11k_dp_srng_setup(ar->ab, &dp->reo_dst_ring, HAL_REO_DST,
dp->mac_id, dp->mac_id,
DP_REO_DST_RING_SIZE);
if (ret) {
ath11k_warn(ar->ab, "failed to setup reo_dst_ring\n");
return ret;
}
ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_err_dst_ring, ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_err_dst_ring,
HAL_RXDMA_DST, 0, dp->mac_id, HAL_RXDMA_DST, 0, dp->mac_id,
DP_RXDMA_ERR_DST_RING_SIZE); DP_RXDMA_ERR_DST_RING_SIZE);
......
...@@ -48,6 +48,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id, ...@@ -48,6 +48,8 @@ int ath11k_peer_rx_tid_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id,
u8 tid, u32 ba_win_sz, u16 ssn); u8 tid, u32 ba_win_sz, u16 ssn);
void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab, void ath11k_dp_htt_htc_t2h_msg_handler(struct ath11k_base *ab,
struct sk_buff *skb); struct sk_buff *skb);
int ath11k_dp_pdev_reo_setup(struct ath11k_base *ab);
void ath11k_dp_pdev_reo_cleanup(struct ath11k_base *ab);
int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int pdev_idx); int ath11k_dp_rx_pdev_alloc(struct ath11k_base *ab, int pdev_idx);
void ath11k_dp_rx_pdev_free(struct ath11k_base *ab, int pdev_idx); void ath11k_dp_rx_pdev_free(struct ath11k_base *ab, int pdev_idx);
void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab); void ath11k_dp_reo_cmd_list_cleanup(struct ath11k_base *ab);
......
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