qcacmn: Optimize rx reorder queue setup

This change optimizes rx reorder queue setup by using
tid_bitmap, which contains a group of tids, to set up
multi tids at a time instead of one tid after another.

Change-Id: I161b0c812c436ef79d2d1db693b8d0ac41505878
CRs-Fixed: 3661593
This commit is contained in:
jinbao liu
2023-11-14 01:57:57 -08:00
committed by Ravindra Konda
parent 7555136c16
commit b4f2073ac3
15 changed files with 571 additions and 143 deletions

View File

@@ -1525,6 +1525,10 @@ struct ol_if_ops {
uint8_t ba_window_size_valid, uint8_t ba_window_size_valid,
uint16_t ba_window_size); uint16_t ba_window_size);
QDF_STATUS QDF_STATUS
(*peer_multi_rx_reorder_queue_setup)(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
uint8_t pdev_id,
struct multi_rx_reorder_queue_setup_params *tid_params);
QDF_STATUS
(*peer_rx_reorder_queue_remove)(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, (*peer_rx_reorder_queue_remove)(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
uint8_t pdev_id, uint8_t pdev_id,
uint8_t vdev_id, uint8_t *peer_macaddr, uint8_t vdev_id, uint8_t *peer_macaddr,

View File

@@ -3329,6 +3329,8 @@ struct cdp_peer_hmwds_ast_add_status {
* @DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT: For sending bulk AST delete * @DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT: For sending bulk AST delete
* @DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT: To set the rssi dbm support bit * @DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT: To set the rssi dbm support bit
* @DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT: Whether target supports UMAC HW reset * @DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT: Whether target supports UMAC HW reset
* @DP_SOC_PARAM_MULTI_RX_REORDER_SETUP_SUPPORT: Whether setting up a group of
* TIDs at a time is supported
* @DP_SOC_PARAM_MAX: * @DP_SOC_PARAM_MAX:
*/ */
enum cdp_soc_param_t { enum cdp_soc_param_t {
@@ -3339,6 +3341,7 @@ enum cdp_soc_param_t {
DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT, DP_SOC_PARAM_MULTI_PEER_GRP_CMD_SUPPORT,
DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT, DP_SOC_PARAM_RSSI_DBM_CONV_SUPPORT,
DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT, DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT,
DP_SOC_PARAM_MULTI_RX_REORDER_SETUP_SUPPORT,
DP_SOC_PARAM_MAX, DP_SOC_PARAM_MAX,
}; };

View File

@@ -2427,11 +2427,11 @@ dp_rx_null_q_desc_handle_be(struct dp_soc *soc, qdf_nbuf_t nbuf,
if (qdf_unlikely(vdev->mesh_vdev) || if (qdf_unlikely(vdev->mesh_vdev) ||
qdf_unlikely(txrx_peer->nawds_enabled)) qdf_unlikely(txrx_peer->nawds_enabled))
dp_rx_tid_setup_wifi3( dp_rx_tid_setup_wifi3(
peer, tid, peer, BIT(tid),
hal_get_rx_max_ba_window(soc->hal_soc,tid), hal_get_rx_max_ba_window(soc->hal_soc,tid),
IEEE80211_SEQ_MAX); IEEE80211_SEQ_MAX);
else else
dp_rx_tid_setup_wifi3(peer, tid, 1, dp_rx_tid_setup_wifi3(peer, BIT(tid), 1,
IEEE80211_SEQ_MAX); IEEE80211_SEQ_MAX);
} }
qdf_spin_unlock_bh(&rx_tid->tid_lock); qdf_spin_unlock_bh(&rx_tid->tid_lock);

View File

@@ -275,6 +275,124 @@ dp_soc_get_num_soc_be(struct dp_soc *soc)
} }
#endif #endif
static inline QDF_STATUS
dp_peer_rx_reorder_q_setup_per_tid(struct dp_peer *peer,
uint32_t tid_bitmap,
uint32_t ba_window_size)
{
int tid;
struct dp_rx_tid *rx_tid;
struct dp_soc *soc = peer->vdev->pdev->soc;
if (!soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
dp_peer_debug("%pK: rx_reorder_queue_setup NULL bitmap 0x%x",
soc, tid_bitmap);
return QDF_STATUS_SUCCESS;
}
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!(BIT(tid) & tid_bitmap))
continue;
rx_tid = &peer->rx_tid[tid];
if (!rx_tid->hw_qdesc_paddr) {
tid_bitmap &= ~BIT(tid);
continue;
}
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup(
soc->ctrl_psoc,
peer->vdev->pdev->pdev_id,
peer->vdev->vdev_id,
peer->mac_addr.raw,
rx_tid->hw_qdesc_paddr,
tid, tid,
1, ba_window_size)) {
dp_peer_err("%pK: Fail to send reo q to FW. tid %d",
soc, tid);
return QDF_STATUS_E_FAILURE;
}
}
if (!tid_bitmap) {
dp_peer_err("tid_bitmap=0. All tids setup fail");
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
dp_peer_multi_tid_params_setup(struct dp_peer *peer,
uint32_t tid_bitmap,
uint32_t ba_window_size,
struct multi_rx_reorder_queue_setup_params *tid_params)
{
struct dp_rx_tid *rx_tid;
int tid;
tid_params->peer_macaddr = peer->mac_addr.raw;
tid_params->tid_bitmap = tid_bitmap;
tid_params->vdev_id = peer->vdev->vdev_id;
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!(BIT(tid) & tid_bitmap))
continue;
rx_tid = &peer->rx_tid[tid];
if (!rx_tid->hw_qdesc_paddr) {
tid_params->tid_bitmap &= ~BIT(tid);
continue;
}
tid_params->tid_num++;
tid_params->queue_params_list[tid].hw_qdesc_paddr =
rx_tid->hw_qdesc_paddr;
tid_params->queue_params_list[tid].queue_no = tid;
tid_params->queue_params_list[tid].ba_window_size_valid = 1;
tid_params->queue_params_list[tid].ba_window_size =
ba_window_size;
}
if (!tid_params->tid_bitmap) {
dp_peer_err("tid_bitmap=0. All tids setup fail");
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
dp_peer_rx_reorder_multi_q_setup(struct dp_peer *peer,
uint32_t tid_bitmap,
uint32_t ba_window_size)
{
QDF_STATUS status;
struct dp_soc *soc = peer->vdev->pdev->soc;
struct multi_rx_reorder_queue_setup_params tid_params = {0};
if (!soc->cdp_soc.ol_ops->peer_multi_rx_reorder_queue_setup) {
dp_peer_debug("%pK: callback NULL", soc);
return QDF_STATUS_SUCCESS;
}
status = dp_peer_multi_tid_params_setup(peer, tid_bitmap,
ba_window_size,
&tid_params);
if (qdf_unlikely(QDF_IS_STATUS_ERROR(status)))
return status;
if (soc->cdp_soc.ol_ops->peer_multi_rx_reorder_queue_setup(
soc->ctrl_psoc,
peer->vdev->pdev->pdev_id,
&tid_params)) {
dp_peer_err("%pK: multi_reorder_q_setup fail. tid_bitmap 0x%x",
soc, tid_bitmap);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS;
}
#ifdef WLAN_FEATURE_11BE_MLO #ifdef WLAN_FEATURE_11BE_MLO
/** /**
* dp_rx_mlo_igmp_handler() - Rx handler for Mcast packets * dp_rx_mlo_igmp_handler() - Rx handler for Mcast packets
@@ -293,11 +411,11 @@ bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
uint8_t link_id); uint8_t link_id);
/** /**
* dp_peer_rx_reorder_queue_setup_be() - Send reo queue setup wmi cmd to FW * dp_peer_rx_reorder_queue_setup_be() - Send reo queue
* per peer type * setup wmi cmd to FW per peer type
* @soc: DP Soc handle * @soc: DP Soc handle
* @peer: dp peer to operate on * @peer: dp peer to operate on
* @tid: TID * @tid_bitmap: TIDs to be set up
* @ba_window_size: BlockAck window size * @ba_window_size: BlockAck window size
* *
* Return: 0 - success, others - failure * Return: 0 - success, others - failure
@@ -305,70 +423,17 @@ bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
static inline static inline
QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc, QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc,
struct dp_peer *peer, struct dp_peer *peer,
int tid, uint32_t tid_bitmap,
uint32_t ba_window_size) uint32_t ba_window_size)
{ {
uint8_t i; uint8_t i;
struct dp_mld_link_peers link_peers_info; struct dp_mld_link_peers link_peers_info;
struct dp_peer *link_peer; struct dp_peer *link_peer;
struct dp_rx_tid *rx_tid; struct dp_rx_tid *rx_tid;
struct dp_soc *link_peer_soc; int tid;
QDF_STATUS status;
rx_tid = &peer->rx_tid[tid]; if (hal_reo_shared_qaddr_is_enable(soc->hal_soc)) {
if (!rx_tid->hw_qdesc_paddr)
return QDF_STATUS_E_INVAL;
if (!hal_reo_shared_qaddr_is_enable(soc->hal_soc)) {
if (IS_MLO_DP_MLD_PEER(peer)) {
/* get link peers with reference */
dp_get_link_peers_ref_from_mld_peer(soc, peer,
&link_peers_info,
DP_MOD_ID_CDP);
/* send WMI cmd to each link peers */
for (i = 0; i < link_peers_info.num_links; i++) {
link_peer = link_peers_info.link_peers[i];
link_peer_soc = link_peer->vdev->pdev->soc;
if (link_peer_soc->cdp_soc.ol_ops->
peer_rx_reorder_queue_setup) {
if (link_peer_soc->cdp_soc.ol_ops->
peer_rx_reorder_queue_setup(
link_peer_soc->ctrl_psoc,
link_peer->vdev->pdev->pdev_id,
link_peer->vdev->vdev_id,
link_peer->mac_addr.raw,
rx_tid->hw_qdesc_paddr,
tid, tid,
1, ba_window_size)) {
dp_peer_err("%pK: Failed to send reo queue setup to FW - tid %d\n",
link_peer_soc, tid);
return QDF_STATUS_E_FAILURE;
}
}
}
/* release link peers reference */
dp_release_link_peers_ref(&link_peers_info,
DP_MOD_ID_CDP);
} else if (peer->peer_type == CDP_LINK_PEER_TYPE) {
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
if (soc->cdp_soc.ol_ops->
peer_rx_reorder_queue_setup(
soc->ctrl_psoc,
peer->vdev->pdev->pdev_id,
peer->vdev->vdev_id,
peer->mac_addr.raw,
rx_tid->hw_qdesc_paddr,
tid, tid,
1, ba_window_size)) {
dp_peer_err("%pK: Failed to send reo queue setup to FW - tid %d\n",
soc, tid);
return QDF_STATUS_E_FAILURE;
}
}
} else {
dp_peer_err("invalid peer type %d", peer->peer_type);
return QDF_STATUS_E_FAILURE;
}
} else {
/* Some BE targets dont require WMI and use shared /* Some BE targets dont require WMI and use shared
* table managed by host for storing Reo queue ref structs * table managed by host for storing Reo queue ref structs
*/ */
@@ -388,38 +453,86 @@ QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc,
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
hal_reo_shared_qaddr_write(soc->hal_soc, for (tid = 0; tid < DP_MAX_TIDS; tid++) {
peer->peer_id, if (!((1 << tid) & tid_bitmap))
tid, peer->rx_tid[tid].hw_qdesc_paddr); continue;
rx_tid = &peer->rx_tid[tid];
if (!rx_tid->hw_qdesc_paddr) {
tid_bitmap &= ~BIT(tid);
continue;
}
hal_reo_shared_qaddr_write(soc->hal_soc,
peer->peer_id,
tid, peer->rx_tid[tid].
hw_qdesc_paddr);
if (!tid_bitmap) {
dp_peer_err("tid_bitmap=0. All tids setup fail");
return QDF_STATUS_E_FAILURE;
}
}
return QDF_STATUS_SUCCESS;
} }
/* when (!hal_reo_shared_qaddr_is_enable(soc->hal_soc)) is true: */
if (IS_MLO_DP_MLD_PEER(peer)) {
/* get link peers with reference */
dp_get_link_peers_ref_from_mld_peer(soc, peer,
&link_peers_info,
DP_MOD_ID_CDP);
/* send WMI cmd to each link peers */
for (i = 0; i < link_peers_info.num_links; i++) {
link_peer = link_peers_info.link_peers[i];
if (soc->features.multi_rx_reorder_q_setup_support)
status = dp_peer_rx_reorder_multi_q_setup(
link_peer, tid_bitmap, ba_window_size);
else
status = dp_peer_rx_reorder_q_setup_per_tid(
link_peer,
tid_bitmap,
ba_window_size);
if (QDF_IS_STATUS_ERROR(status)) {
dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
return status;
}
}
/* release link peers reference */
dp_release_link_peers_ref(&link_peers_info, DP_MOD_ID_CDP);
} else if (peer->peer_type == CDP_LINK_PEER_TYPE) {
if (soc->features.multi_rx_reorder_q_setup_support)
return dp_peer_rx_reorder_multi_q_setup(peer,
tid_bitmap,
ba_window_size);
else
return dp_peer_rx_reorder_q_setup_per_tid(peer,
tid_bitmap,
ba_window_size);
} else {
dp_peer_err("invalid peer type %d", peer->peer_type);
return QDF_STATUS_E_FAILURE;
}
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
#else #else
static inline static inline
QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc, QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc,
struct dp_peer *peer, struct dp_peer *peer,
int tid, uint32_t tid_bitmap,
uint32_t ba_window_size) uint32_t ba_window_size)
{ {
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; if (soc->features.multi_rx_reorder_q_setup_support)
return dp_peer_rx_reorder_multi_q_setup(peer,
if (!rx_tid->hw_qdesc_paddr) tid_bitmap,
return QDF_STATUS_E_INVAL; ba_window_size);
else
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) { return dp_peer_rx_reorder_q_setup_per_tid(peer,
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup( tid_bitmap,
soc->ctrl_psoc, ba_window_size);
peer->vdev->pdev->pdev_id,
peer->vdev->vdev_id,
peer->mac_addr.raw, rx_tid->hw_qdesc_paddr, tid, tid,
1, ba_window_size)) {
dp_peer_err("%pK: Failed to send reo queue setup to FW - tid %d\n",
soc, tid);
return QDF_STATUS_E_FAILURE;
}
}
return QDF_STATUS_SUCCESS;
} }
#endif /* WLAN_FEATURE_11BE_MLO */ #endif /* WLAN_FEATURE_11BE_MLO */

View File

@@ -11222,6 +11222,11 @@ static QDF_STATUS dp_soc_set_param(struct cdp_soc_t *soc_hdl,
dp_info("UMAC HW reset support :%u", dp_info("UMAC HW reset support :%u",
soc->features.umac_hw_reset_support); soc->features.umac_hw_reset_support);
break; break;
case DP_SOC_PARAM_MULTI_RX_REORDER_SETUP_SUPPORT:
soc->features.multi_rx_reorder_q_setup_support = value;
dp_info("Multi rx reorder queue setup support: %u",
soc->features.multi_rx_reorder_q_setup_support);
break;
default: default:
dp_info("not handled param %d ", param); dp_info("not handled param %d ", param);
break; break;

View File

@@ -2905,10 +2905,10 @@ end:
static inline QDF_STATUS static inline QDF_STATUS
dp_peer_rx_reorder_queue_setup(struct dp_soc *soc, struct dp_peer *peer, dp_peer_rx_reorder_queue_setup(struct dp_soc *soc, struct dp_peer *peer,
int tid, uint32_t ba_window_size) uint32_t tid_bitmap, uint32_t ba_window_size)
{ {
return soc->arch_ops.dp_peer_rx_reorder_queue_setup(soc, return soc->arch_ops.dp_peer_rx_reorder_queue_setup(soc,
peer, tid, peer, tid_bitmap,
ba_window_size); ba_window_size);
} }

View File

@@ -391,7 +391,7 @@ dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t ba_window_size,
if (!bar_update) if (!bar_update)
dp_peer_rx_reorder_queue_setup(soc, peer, dp_peer_rx_reorder_queue_setup(soc, peer,
tid, ba_window_size); BIT(tid), ba_window_size);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -577,8 +577,37 @@ static inline int dp_reo_desc_addr_chk(qdf_dma_addr_t dma_addr)
} }
#endif #endif
QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid, static inline void
uint32_t ba_window_size, uint32_t start_seq) dp_rx_tid_setup_error_process(uint32_t tid_bitmap, struct dp_peer *peer)
{
struct dp_rx_tid *rx_tid;
int tid;
struct dp_soc *soc = peer->vdev->pdev->soc;
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!(BIT(tid) & tid_bitmap))
continue;
rx_tid = &peer->rx_tid[tid];
if (!rx_tid->hw_qdesc_vaddr_unaligned)
continue;
if (dp_reo_desc_addr_chk(rx_tid->hw_qdesc_paddr) ==
QDF_STATUS_SUCCESS)
qdf_mem_unmap_nbytes_single(
soc->osdev,
rx_tid->hw_qdesc_paddr,
QDF_DMA_BIDIRECTIONAL,
rx_tid->hw_qdesc_alloc_size);
qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned);
rx_tid->hw_qdesc_vaddr_unaligned = NULL;
rx_tid->hw_qdesc_paddr = 0;
}
}
static QDF_STATUS
dp_single_rx_tid_setup(struct dp_peer *peer, int tid,
uint32_t ba_window_size, uint32_t start_seq)
{ {
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
struct dp_vdev *vdev = peer->vdev; struct dp_vdev *vdev = peer->vdev;
@@ -591,19 +620,6 @@ QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
QDF_STATUS status = QDF_STATUS_SUCCESS; QDF_STATUS status = QDF_STATUS_SUCCESS;
struct dp_txrx_peer *txrx_peer; struct dp_txrx_peer *txrx_peer;
if (!qdf_atomic_read(&peer->is_default_route_set))
return QDF_STATUS_E_FAILURE;
if (!dp_rx_tid_setup_allow(peer)) {
dp_peer_info("skip rx tid setup for peer" QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(peer->mac_addr.raw));
goto send_wmi_reo_cmd;
}
rx_tid->ba_win_size = ba_window_size;
if (rx_tid->hw_qdesc_vaddr_unaligned)
return dp_rx_tid_update_wifi3(peer, tid, ba_window_size,
start_seq, false);
rx_tid->delba_tx_status = 0; rx_tid->delba_tx_status = 0;
rx_tid->ppdu_id_2k = 0; rx_tid->ppdu_id_2k = 0;
rx_tid->num_of_addba_req = 0; rx_tid->num_of_addba_req = 0;
@@ -713,37 +729,112 @@ try_desc_alloc:
rx_tid->hw_qdesc_vaddr_unaligned = NULL; rx_tid->hw_qdesc_vaddr_unaligned = NULL;
goto try_desc_alloc; goto try_desc_alloc;
} else { } else {
dp_peer_err("%pK: Rx tid HW desc alloc failed (lowmem): tid %d", dp_peer_err("%pK: Rx tid %d desc alloc fail (lowmem)",
soc, tid); soc, tid);
status = QDF_STATUS_E_NOMEM; status = QDF_STATUS_E_NOMEM;
goto error; goto error;
} }
} }
return QDF_STATUS_SUCCESS;
error:
dp_rx_tid_setup_error_process(1 << tid, peer);
return status;
}
QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer,
uint32_t tid_bitmap,
uint32_t ba_window_size,
uint32_t start_seq)
{
QDF_STATUS status;
int tid;
struct dp_rx_tid *rx_tid;
struct dp_vdev *vdev = peer->vdev;
struct dp_soc *soc = vdev->pdev->soc;
uint8_t setup_fail_cnt = 0;
if (!qdf_atomic_read(&peer->is_default_route_set))
return QDF_STATUS_E_FAILURE;
if (!dp_rx_tid_setup_allow(peer)) {
dp_peer_info("skip rx tid setup for peer" QDF_MAC_ADDR_FMT,
QDF_MAC_ADDR_REF(peer->mac_addr.raw));
goto send_wmi_reo_cmd;
}
dp_peer_info("tid_bitmap 0x%x, ba_window_size %d, start_seq %d",
tid_bitmap, ba_window_size, start_seq);
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!(BIT(tid) & tid_bitmap))
continue;
rx_tid = &peer->rx_tid[tid];
rx_tid->ba_win_size = ba_window_size;
if (rx_tid->hw_qdesc_vaddr_unaligned) {
status = dp_rx_tid_update_wifi3(peer, tid,
ba_window_size, start_seq, false);
if (QDF_IS_STATUS_ERROR(status)) {
/* Not continue to update other tid(s) and
* return even if they have not been set up.
*/
dp_peer_err("Update tid %d fail", tid);
return status;
}
dp_peer_info("Update tid %d", tid);
tid_bitmap &= ~BIT(tid);
continue;
}
status = dp_single_rx_tid_setup(peer, tid,
ba_window_size, start_seq);
if (QDF_IS_STATUS_ERROR(status)) {
dp_peer_err("Set up tid %d fail, status=%d",
tid, status);
tid_bitmap &= ~BIT(tid);
setup_fail_cnt++;
continue;
}
}
/* tid_bitmap == 0 means there is no tid(s) for further setup */
if (!tid_bitmap) {
dp_peer_info("tid_bitmap=0, no tid setup, setup_fail_cnt %d",
setup_fail_cnt);
/* If setup_fail_cnt==0, all tid(s) has been
* successfully updated, so we return success.
*/
if (!setup_fail_cnt)
return QDF_STATUS_SUCCESS;
else
return QDF_STATUS_E_FAILURE;
}
send_wmi_reo_cmd: send_wmi_reo_cmd:
if (dp_get_peer_vdev_roaming_in_progress(peer)) { if (dp_get_peer_vdev_roaming_in_progress(peer)) {
status = QDF_STATUS_E_PERM; status = QDF_STATUS_E_PERM;
goto error; goto error;
} }
dp_peer_info("peer %pK, tids 0x%x, multi_reo %d, s_seq %d, w_size %d",
peer, tid_bitmap,
soc->features.multi_rx_reorder_q_setup_support,
start_seq, ba_window_size);
status = dp_peer_rx_reorder_queue_setup(soc, peer, status = dp_peer_rx_reorder_queue_setup(soc, peer,
tid, ba_window_size); tid_bitmap,
ba_window_size);
if (QDF_IS_STATUS_SUCCESS(status)) if (QDF_IS_STATUS_SUCCESS(status))
return status; return status;
error: error:
if (rx_tid->hw_qdesc_vaddr_unaligned) { dp_rx_tid_setup_error_process(tid_bitmap, peer);
if (dp_reo_desc_addr_chk(rx_tid->hw_qdesc_paddr) ==
QDF_STATUS_SUCCESS)
qdf_mem_unmap_nbytes_single(
soc->osdev,
rx_tid->hw_qdesc_paddr,
QDF_DMA_BIDIRECTIONAL,
rx_tid->hw_qdesc_alloc_size);
qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned);
rx_tid->hw_qdesc_vaddr_unaligned = NULL;
rx_tid->hw_qdesc_paddr = 0;
}
return status; return status;
} }
@@ -1071,13 +1162,16 @@ static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid)
static void dp_peer_setup_remaining_tids(struct dp_peer *peer) static void dp_peer_setup_remaining_tids(struct dp_peer *peer)
{ {
int tid; int tid;
uint32_t tid_bitmap = 0;
for (tid = 1; tid < DP_MAX_TIDS-1; tid++) { for (tid = 1; tid < DP_MAX_TIDS-1; tid++)
dp_rx_tid_setup_wifi3(peer, tid, 1, 0); tid_bitmap |= BIT(tid);
dp_peer_debug("Setting up TID %d for peer %pK peer->local_id %d",
tid, peer, peer->local_id); dp_peer_info("Sett up tid_bitmap 0x%x for peer %pK peer->local_id %d",
} tid_bitmap, peer, peer->local_id);
dp_rx_tid_setup_wifi3(peer, tid_bitmap, 1, 0);
} }
#else #else
static void dp_peer_setup_remaining_tids(struct dp_peer *peer) {}; static void dp_peer_setup_remaining_tids(struct dp_peer *peer) {};
#endif #endif
@@ -1159,7 +1253,7 @@ void dp_peer_rx_tid_setup(struct dp_peer *peer)
dp_peer_rx_tids_init(peer); dp_peer_rx_tids_init(peer);
/* Setup default (non-qos) rx tid queue */ /* Setup default (non-qos) rx tid queue */
dp_rx_tid_setup_wifi3(peer, DP_NON_QOS_TID, 1, 0); dp_rx_tid_setup_wifi3(peer, BIT(DP_NON_QOS_TID), 1, 0);
/* Setup rx tid queue for TID 0. /* Setup rx tid queue for TID 0.
* Other queues will be setup on receiving first packet, which will cause * Other queues will be setup on receiving first packet, which will cause
@@ -1171,11 +1265,11 @@ void dp_peer_rx_tid_setup(struct dp_peer *peer)
if (qdf_unlikely(vdev->mesh_vdev) || if (qdf_unlikely(vdev->mesh_vdev) ||
qdf_unlikely(txrx_peer->nawds_enabled)) qdf_unlikely(txrx_peer->nawds_enabled))
dp_rx_tid_setup_wifi3( dp_rx_tid_setup_wifi3(
peer, 0, peer, BIT(0),
hal_get_rx_max_ba_window(soc->hal_soc, 0), hal_get_rx_max_ba_window(soc->hal_soc, 0),
0); 0);
else else
dp_rx_tid_setup_wifi3(peer, 0, 1, 0); dp_rx_tid_setup_wifi3(peer, BIT(0), 1, 0);
/* /*
* Setup the rest of TID's to handle LFR * Setup the rest of TID's to handle LFR
@@ -1562,7 +1656,7 @@ int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc,
dp_check_ba_buffersize(peer, tid, buffersize); dp_check_ba_buffersize(peer, tid, buffersize);
if (dp_rx_tid_setup_wifi3(peer, tid, if (dp_rx_tid_setup_wifi3(peer, BIT(tid),
rx_tid->ba_win_size, startseqnum)) { rx_tid->ba_win_size, startseqnum)) {
rx_tid->ba_status = DP_RX_BA_INACTIVE; rx_tid->ba_status = DP_RX_BA_INACTIVE;
qdf_spin_unlock_bh(&rx_tid->tid_lock); qdf_spin_unlock_bh(&rx_tid->tid_lock);

View File

@@ -45,15 +45,15 @@ void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer); void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer);
/** /**
* dp_rx_tid_setup_wifi3() - Setup receive TID state * dp_rx_tid_setup_wifi3() - Set up receive TID state
* @peer: Datapath peer handle * @peer: Datapath peer handle
* @tid: TID * @tid_bitmap: TIDs to be set up
* @ba_window_size: BlockAck window size * @ba_window_size: BlockAck window size
* @start_seq: Starting sequence number * @start_seq: Starting sequence number
* *
* Return: QDF_STATUS code * Return: QDF_STATUS code
*/ */
QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid, QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, uint32_t tid_bitmap,
uint32_t ba_window_size, uint32_t start_seq); uint32_t ba_window_size, uint32_t start_seq);
/** /**

View File

@@ -2469,7 +2469,7 @@ struct dp_arch_ops {
enum peer_stats_type stats_type); enum peer_stats_type stats_type);
QDF_STATUS (*dp_peer_rx_reorder_queue_setup)(struct dp_soc *soc, QDF_STATUS (*dp_peer_rx_reorder_queue_setup)(struct dp_soc *soc,
struct dp_peer *peer, struct dp_peer *peer,
int tid, uint32_t tid_bitmap,
uint32_t ba_window_size); uint32_t ba_window_size);
void (*dp_bank_reconfig)(struct dp_soc *soc, struct dp_vdev *vdev); void (*dp_bank_reconfig)(struct dp_soc *soc, struct dp_vdev *vdev);
@@ -2572,6 +2572,7 @@ struct dp_arch_ops {
* @rssi_dbm_conv_support: Rssi dbm conversion support param. * @rssi_dbm_conv_support: Rssi dbm conversion support param.
* @umac_hw_reset_support: UMAC HW reset support * @umac_hw_reset_support: UMAC HW reset support
* @wds_ext_ast_override_enable: * @wds_ext_ast_override_enable:
* @multi_rx_reorder_q_setup_support: multi rx reorder q setup at a time support
*/ */
struct dp_soc_features { struct dp_soc_features {
uint8_t pn_in_reo_dest:1, uint8_t pn_in_reo_dest:1,
@@ -2579,6 +2580,7 @@ struct dp_soc_features {
bool rssi_dbm_conv_support; bool rssi_dbm_conv_support;
bool umac_hw_reset_support; bool umac_hw_reset_support;
bool wds_ext_ast_override_enable; bool wds_ext_ast_override_enable;
bool multi_rx_reorder_q_setup_support;
}; };
enum sysfs_printing_mode { enum sysfs_printing_mode {

View File

@@ -1528,11 +1528,11 @@ dp_rx_null_q_desc_handle_li(struct dp_soc *soc, qdf_nbuf_t nbuf,
if (qdf_unlikely(vdev->mesh_vdev) || if (qdf_unlikely(vdev->mesh_vdev) ||
qdf_unlikely(txrx_peer->nawds_enabled)) qdf_unlikely(txrx_peer->nawds_enabled))
dp_rx_tid_setup_wifi3( dp_rx_tid_setup_wifi3(
peer, tid, peer, BIT(tid),
hal_get_rx_max_ba_window(soc->hal_soc,tid), hal_get_rx_max_ba_window(soc->hal_soc,tid),
IEEE80211_SEQ_MAX); IEEE80211_SEQ_MAX);
else else
dp_rx_tid_setup_wifi3(peer, tid, 1, dp_rx_tid_setup_wifi3(peer, BIT(tid), 1,
IEEE80211_SEQ_MAX); IEEE80211_SEQ_MAX);
} }
qdf_spin_unlock_bh(&rx_tid->tid_lock); qdf_spin_unlock_bh(&rx_tid->tid_lock);

View File

@@ -261,25 +261,42 @@ void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc,
static inline static inline
QDF_STATUS dp_peer_rx_reorder_queue_setup_li(struct dp_soc *soc, QDF_STATUS dp_peer_rx_reorder_queue_setup_li(struct dp_soc *soc,
struct dp_peer *peer, struct dp_peer *peer,
int tid, uint32_t tid_bitmap,
uint32_t ba_window_size) uint32_t ba_window_size)
{ {
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid]; int tid;
struct dp_rx_tid *rx_tid;
if (!rx_tid->hw_qdesc_paddr) if (!soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
return QDF_STATUS_E_INVAL; dp_peer_debug("peer_rx_reorder_queue_setup NULL");
return QDF_STATUS_SUCCESS;
}
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!(BIT(tid) & tid_bitmap))
continue;
rx_tid = &peer->rx_tid[tid];
if (!rx_tid->hw_qdesc_paddr) {
tid_bitmap &= ~BIT(tid);
continue;
}
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup( if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup(
soc->ctrl_psoc, soc->ctrl_psoc,
peer->vdev->pdev->pdev_id, peer->vdev->pdev->pdev_id,
peer->vdev->vdev_id, peer->vdev->vdev_id,
peer->mac_addr.raw, rx_tid->hw_qdesc_paddr, tid, tid, peer->mac_addr.raw, rx_tid->hw_qdesc_paddr, tid, tid,
1, ba_window_size)) { 1, ba_window_size)) {
dp_peer_err("%pK: Failed to send reo queue setup to FW - tid %d\n", dp_peer_err("%pK: Fail to send reo q setup. tid %d",
soc, tid); soc, tid);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
if (!tid_bitmap) {
dp_peer_err("tid_bitmap=0. All tids setup fail");
return QDF_STATUS_E_FAILURE;
}
} }
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;

View File

@@ -200,7 +200,7 @@ void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc,
* dp_peer_rx_reorder_queue_setup_rh() - NOP for RH arch implementation * dp_peer_rx_reorder_queue_setup_rh() - NOP for RH arch implementation
* @soc: Handle to HAL Soc structure * @soc: Handle to HAL Soc structure
* @peer: DP peer structure * @peer: DP peer structure
* @tid: tid id * @tid_bitmap: tids to be set up
* @ba_window_size: BA window size * @ba_window_size: BA window size
* *
* Return: None * Return: None
@@ -208,7 +208,7 @@ void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc,
static inline static inline
QDF_STATUS dp_peer_rx_reorder_queue_setup_rh(struct dp_soc *soc, QDF_STATUS dp_peer_rx_reorder_queue_setup_rh(struct dp_soc *soc,
struct dp_peer *peer, struct dp_peer *peer,
int tid, uint32_t tid_bitmap,
uint32_t ba_window_size) uint32_t ba_window_size)
{ {
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;

View File

@@ -31,9 +31,11 @@
#include <wlan_objmgr_psoc_obj.h> #include <wlan_objmgr_psoc_obj.h>
#include <target_if.h> #include <target_if.h>
#include <cdp_txrx_ops.h> #include <cdp_txrx_ops.h>
#include <wlan_cfg.h>
#define PEER_ROUTING_LMAC_ID_INDEX 6 #define PEER_ROUTING_LMAC_ID_INDEX 6
#define PEER_ROUTING_LMAC_ID_BITS 2 #define PEER_ROUTING_LMAC_ID_BITS 2
/** /**
* struct reorder_q_setup - reorder queue setup params * struct reorder_q_setup - reorder queue setup params
* @psoc: psoc * @psoc: psoc
@@ -58,6 +60,41 @@ struct reorder_q_setup {
uint16_t ba_window_size; uint16_t ba_window_size;
}; };
/**
* struct reorder_q_setup_list - Specific tid params for each tid
* @hw_qdesc_paddr: hw queue descriptor
* @queue_no: queue number
* @ba_window_size: BA window size
* @ba_window_size_valid: BA window size validity flag
*/
struct reorder_q_setup_list {
qdf_dma_addr_t hw_qdesc_paddr;
uint16_t queue_no;
uint16_t ba_window_size;
uint8_t ba_window_size_valid;
};
/**
* struct multi_reorder_q_setup - multi reorder queue setup
* params for setting up TIDs at a time
* @q_setup_list: An array for recording the specific params for each tid
* @peer_mac: peer mac address
* @psoc: psoc
* @vdev_id: vdev id
* @pdev_id: pdev id
* @tid_num: Total number of TIDs to be set up
* @tid_bitmap: TIDs to be set up
*/
struct multi_reorder_q_setup {
struct reorder_q_setup_list q_setup_list[DP_MAX_TIDS];
uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
struct cdp_ctrl_objmgr_psoc *psoc;
uint8_t vdev_id;
uint8_t pdev_id;
uint8_t tid_num;
uint32_t tid_bitmap;
};
/** /**
* target_if_get_active_mac_phy_number() - Get max MAC-PHY number enabled by * target_if_get_active_mac_phy_number() - Get max MAC-PHY number enabled by
* target * target
@@ -88,7 +125,7 @@ target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc *psoc,
bool hash_based, uint8_t ring_num, bool hash_based, uint8_t ring_num,
uint8_t lmac_peer_id_msb); uint8_t lmac_peer_id_msb);
/** /**
* target_if_peer_rx_reorder_queue_setup() - setup rx reorder queue * target_if_peer_rx_reorder_queue_setup() - set up rx reorder queue
* @psoc: psoc pointer * @psoc: psoc pointer
* @pdev_id: pdev id * @pdev_id: pdev id
* @vdev_id: vdev id * @vdev_id: vdev id
@@ -110,6 +147,20 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t ba_window_size_valid, uint8_t ba_window_size_valid,
uint16_t ba_window_size); uint16_t ba_window_size);
/**
* target_if_peer_multi_rx_reorder_queue_setup() - set up multi rx reorder queue
* @psoc: psoc pointer
* @pdev_id: pdev id
* @tid_params: TIDs with their parameters to be set
*
* return: QDF_STATUS_SUCCESS for success or error code
*/
QDF_STATUS
target_if_peer_multi_rx_reorder_queue_setup(
struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t pdev_id,
struct multi_rx_reorder_queue_setup_params *tid_params);
/** /**
* target_if_peer_rx_reorder_queue_remove() - remove rx reorder queue * target_if_peer_rx_reorder_queue_remove() - remove rx reorder queue
* @psoc: psoc pointer * @psoc: psoc pointer

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for * Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the * any purpose with or without fee is hereby granted, provided that the
@@ -155,6 +155,66 @@ out:
return status; return status;
} }
static QDF_STATUS
target_if_multi_rx_reorder_queue_setup(struct scheduler_msg *msg)
{
struct multi_rx_reorder_queue_setup_params param = {0};
struct wmi_unified *pdev_wmi_handle;
struct multi_reorder_q_setup *q_params;
QDF_STATUS status;
struct wlan_objmgr_pdev *pdev;
struct wlan_objmgr_psoc *psoc;
int tid;
if (!(msg->bodyptr)) {
target_if_err("rx_reorder: Invalid message body");
return QDF_STATUS_E_INVAL;
}
q_params = msg->bodyptr;
psoc = (struct wlan_objmgr_psoc *)q_params->psoc;
pdev = wlan_objmgr_get_pdev_by_id(psoc, q_params->pdev_id,
WLAN_PDEV_TARGET_IF_ID);
if (!pdev) {
target_if_err("pdev with id %d is NULL", q_params->pdev_id);
return QDF_STATUS_E_INVAL;
}
pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
if (!pdev_wmi_handle) {
target_if_err("pdev wmi handle NULL");
status = QDF_STATUS_E_FAILURE;
goto out;
}
param.tid_bitmap = q_params->tid_bitmap;
param.vdev_id = q_params->vdev_id;
param.peer_macaddr = q_params->peer_mac;
param.tid_num = q_params->tid_num;
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!(BIT(tid) & q_params->tid_bitmap))
continue;
param.queue_params_list[tid].hw_qdesc_paddr =
q_params->q_setup_list[tid].hw_qdesc_paddr;
param.queue_params_list[tid].queue_no =
q_params->q_setup_list[tid].queue_no;
param.queue_params_list[tid].ba_window_size_valid =
q_params->q_setup_list[tid].ba_window_size_valid;
param.queue_params_list[tid].ba_window_size =
q_params->q_setup_list[tid].ba_window_size;
}
status = wmi_unified_peer_multi_rx_reorder_queue_setup_send(
pdev_wmi_handle, &param);
out:
wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
qdf_mem_free(q_params);
return status;
}
QDF_STATUS QDF_STATUS
target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc, target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t pdev_id, uint8_t pdev_id,
@@ -194,8 +254,53 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
return status; return status;
} }
#else QDF_STATUS
target_if_peer_multi_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t pdev_id,
struct multi_rx_reorder_queue_setup_params *tid_params)
{
struct scheduler_msg msg = {0};
struct multi_reorder_q_setup *q_params;
QDF_STATUS status;
int tid;
q_params = qdf_mem_malloc(sizeof(*q_params));
if (!q_params)
return QDF_STATUS_E_NOMEM;
q_params->psoc = psoc;
q_params->vdev_id = tid_params->vdev_id;
q_params->pdev_id = pdev_id;
q_params->tid_bitmap = tid_params->tid_bitmap;
q_params->tid_num = tid_params->tid_num;
qdf_mem_copy(q_params->peer_mac, tid_params->peer_macaddr,
QDF_MAC_ADDR_SIZE);
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!(BIT(tid) & tid_params->tid_bitmap))
continue;
q_params->q_setup_list[tid].hw_qdesc_paddr =
tid_params->queue_params_list[tid].hw_qdesc_paddr;
q_params->q_setup_list[tid].queue_no =
tid_params->queue_params_list[tid].queue_no;
q_params->q_setup_list[tid].ba_window_size_valid =
tid_params->queue_params_list[tid].ba_window_size_valid;
q_params->q_setup_list[tid].ba_window_size =
tid_params->queue_params_list[tid].ba_window_size;
}
msg.bodyptr = q_params;
msg.callback = target_if_multi_rx_reorder_queue_setup;
status = scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
QDF_MODULE_ID_TARGET_IF,
QDF_MODULE_ID_TARGET_IF, &msg);
if (status != QDF_STATUS_SUCCESS)
qdf_mem_free(q_params);
return status;
}
#else
QDF_STATUS QDF_STATUS
target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc, target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t pdev_id, uint8_t pdev_id,
@@ -238,6 +343,35 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
return status; return status;
} }
QDF_STATUS
target_if_peer_multi_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t pdev_id,
struct multi_rx_reorder_queue_setup_params *tid_params)
{
struct wmi_unified *pdev_wmi_handle;
QDF_STATUS status;
struct wlan_objmgr_pdev *pdev =
wlan_objmgr_get_pdev_by_id((struct wlan_objmgr_psoc *)psoc,
pdev_id, WLAN_PDEV_TARGET_IF_ID);
if (!pdev) {
target_if_err("pdev with id %d is NULL", pdev_id);
return QDF_STATUS_E_INVAL;
}
pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
if (!pdev_wmi_handle) {
wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
target_if_err("pdev wmi handle NULL");
return QDF_STATUS_E_FAILURE;
}
status = wmi_unified_peer_multi_rx_reorder_queue_setup_send(
pdev_wmi_handle, tid_params);
wlan_objmgr_pdev_release_ref(pdev, WLAN_PDEV_TARGET_IF_ID);
return status;
}
#endif #endif
QDF_STATUS QDF_STATUS

View File

@@ -476,6 +476,11 @@ static int init_deinit_service_ready_event_handler(ol_scn_t scn_handle,
init_deinit_set_send_init_cmd(psoc, tgt_hdl); init_deinit_set_send_init_cmd(psoc, tgt_hdl);
} }
if (wmi_service_enabled(wmi_handle,
wmi_service_multiple_reorder_queue_setup_support))
cdp_soc_set_param(wlan_psoc_get_dp_handle(psoc),
DP_SOC_PARAM_MULTI_RX_REORDER_SETUP_SUPPORT, 1);
exit: exit:
return err_code; return err_code;
} }