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,
uint16_t ba_window_size);
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,
uint8_t pdev_id,
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_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_MULTI_RX_REORDER_SETUP_SUPPORT: Whether setting up a group of
* TIDs at a time is supported
* @DP_SOC_PARAM_MAX:
*/
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_RSSI_DBM_CONV_SUPPORT,
DP_SOC_PARAM_UMAC_HW_RESET_SUPPORT,
DP_SOC_PARAM_MULTI_RX_REORDER_SETUP_SUPPORT,
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) ||
qdf_unlikely(txrx_peer->nawds_enabled))
dp_rx_tid_setup_wifi3(
peer, tid,
peer, BIT(tid),
hal_get_rx_max_ba_window(soc->hal_soc,tid),
IEEE80211_SEQ_MAX);
else
dp_rx_tid_setup_wifi3(peer, tid, 1,
dp_rx_tid_setup_wifi3(peer, BIT(tid), 1,
IEEE80211_SEQ_MAX);
}
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
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
/**
* 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);
/**
* dp_peer_rx_reorder_queue_setup_be() - Send reo queue setup wmi cmd to FW
* per peer type
* dp_peer_rx_reorder_queue_setup_be() - Send reo queue
* setup wmi cmd to FW per peer type
* @soc: DP Soc handle
* @peer: dp peer to operate on
* @tid: TID
* @tid_bitmap: TIDs to be set up
* @ba_window_size: BlockAck window size
*
* Return: 0 - success, others - failure
@@ -305,70 +423,17 @@ bool dp_rx_mlo_igmp_handler(struct dp_soc *soc,
static inline
QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc,
struct dp_peer *peer,
int tid,
uint32_t tid_bitmap,
uint32_t ba_window_size)
{
uint8_t i;
struct dp_mld_link_peers link_peers_info;
struct dp_peer *link_peer;
struct dp_rx_tid *rx_tid;
struct dp_soc *link_peer_soc;
int tid;
QDF_STATUS status;
rx_tid = &peer->rx_tid[tid];
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 {
if (hal_reo_shared_qaddr_is_enable(soc->hal_soc)) {
/* Some BE targets dont require WMI and use shared
* 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;
}
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
if (!((1 << tid) & tid_bitmap))
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);
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;
}
#else
static inline
QDF_STATUS dp_peer_rx_reorder_queue_setup_be(struct dp_soc *soc,
struct dp_peer *peer,
int tid,
uint32_t tid_bitmap,
uint32_t ba_window_size)
{
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
if (!rx_tid->hw_qdesc_paddr)
return QDF_STATUS_E_INVAL;
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;
}
}
return QDF_STATUS_SUCCESS;
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);
}
#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",
soc->features.umac_hw_reset_support);
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:
dp_info("not handled param %d ", param);
break;

View File

@@ -2905,10 +2905,10 @@ end:
static inline QDF_STATUS
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,
peer, tid,
peer, tid_bitmap,
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)
dp_peer_rx_reorder_queue_setup(soc, peer,
tid, ba_window_size);
BIT(tid), ba_window_size);
return QDF_STATUS_SUCCESS;
}
@@ -577,7 +577,36 @@ static inline int dp_reo_desc_addr_chk(qdf_dma_addr_t dma_addr)
}
#endif
QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
static inline void
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];
@@ -591,19 +620,6 @@ QDF_STATUS dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
QDF_STATUS status = QDF_STATUS_SUCCESS;
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->ppdu_id_2k = 0;
rx_tid->num_of_addba_req = 0;
@@ -713,37 +729,112 @@ try_desc_alloc:
rx_tid->hw_qdesc_vaddr_unaligned = NULL;
goto try_desc_alloc;
} 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);
status = QDF_STATUS_E_NOMEM;
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:
if (dp_get_peer_vdev_roaming_in_progress(peer)) {
status = QDF_STATUS_E_PERM;
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,
tid, ba_window_size);
tid_bitmap,
ba_window_size);
if (QDF_IS_STATUS_SUCCESS(status))
return status;
error:
if (rx_tid->hw_qdesc_vaddr_unaligned) {
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;
}
dp_rx_tid_setup_error_process(tid_bitmap, peer);
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)
{
int tid;
uint32_t tid_bitmap = 0;
for (tid = 1; tid < DP_MAX_TIDS-1; tid++) {
dp_rx_tid_setup_wifi3(peer, tid, 1, 0);
dp_peer_debug("Setting up TID %d for peer %pK peer->local_id %d",
tid, peer, peer->local_id);
}
for (tid = 1; tid < DP_MAX_TIDS-1; tid++)
tid_bitmap |= BIT(tid);
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
static void dp_peer_setup_remaining_tids(struct dp_peer *peer) {};
#endif
@@ -1159,7 +1253,7 @@ void dp_peer_rx_tid_setup(struct dp_peer *peer)
dp_peer_rx_tids_init(peer);
/* 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.
* 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) ||
qdf_unlikely(txrx_peer->nawds_enabled))
dp_rx_tid_setup_wifi3(
peer, 0,
peer, BIT(0),
hal_get_rx_max_ba_window(soc->hal_soc, 0),
0);
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
@@ -1562,7 +1656,7 @@ int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc,
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_status = DP_RX_BA_INACTIVE;
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);
/**
* dp_rx_tid_setup_wifi3() - Setup receive TID state
* dp_rx_tid_setup_wifi3() - Set up receive TID state
* @peer: Datapath peer handle
* @tid: TID
* @tid_bitmap: TIDs to be set up
* @ba_window_size: BlockAck window size
* @start_seq: Starting sequence number
*
* 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);
/**

View File

@@ -2469,7 +2469,7 @@ struct dp_arch_ops {
enum peer_stats_type stats_type);
QDF_STATUS (*dp_peer_rx_reorder_queue_setup)(struct dp_soc *soc,
struct dp_peer *peer,
int tid,
uint32_t tid_bitmap,
uint32_t ba_window_size);
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.
* @umac_hw_reset_support: UMAC HW reset support
* @wds_ext_ast_override_enable:
* @multi_rx_reorder_q_setup_support: multi rx reorder q setup at a time support
*/
struct dp_soc_features {
uint8_t pn_in_reo_dest:1,
@@ -2579,6 +2580,7 @@ struct dp_soc_features {
bool rssi_dbm_conv_support;
bool umac_hw_reset_support;
bool wds_ext_ast_override_enable;
bool multi_rx_reorder_q_setup_support;
};
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) ||
qdf_unlikely(txrx_peer->nawds_enabled))
dp_rx_tid_setup_wifi3(
peer, tid,
peer, BIT(tid),
hal_get_rx_max_ba_window(soc->hal_soc,tid),
IEEE80211_SEQ_MAX);
else
dp_rx_tid_setup_wifi3(peer, tid, 1,
dp_rx_tid_setup_wifi3(peer, BIT(tid), 1,
IEEE80211_SEQ_MAX);
}
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
QDF_STATUS dp_peer_rx_reorder_queue_setup_li(struct dp_soc *soc,
struct dp_peer *peer,
int tid,
uint32_t tid_bitmap,
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)
return QDF_STATUS_E_INVAL;
if (!soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
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(
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",
dp_peer_err("%pK: Fail to send reo q setup. 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;

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
* @soc: Handle to HAL Soc structure
* @peer: DP peer structure
* @tid: tid id
* @tid_bitmap: tids to be set up
* @ba_window_size: BA window size
*
* Return: None
@@ -208,7 +208,7 @@ void dp_rx_prefetch_hw_sw_nbuf_desc(struct dp_soc *soc,
static inline
QDF_STATUS dp_peer_rx_reorder_queue_setup_rh(struct dp_soc *soc,
struct dp_peer *peer,
int tid,
uint32_t tid_bitmap,
uint32_t ba_window_size)
{
return QDF_STATUS_SUCCESS;

View File

@@ -31,9 +31,11 @@
#include <wlan_objmgr_psoc_obj.h>
#include <target_if.h>
#include <cdp_txrx_ops.h>
#include <wlan_cfg.h>
#define PEER_ROUTING_LMAC_ID_INDEX 6
#define PEER_ROUTING_LMAC_ID_BITS 2
/**
* struct reorder_q_setup - reorder queue setup params
* @psoc: psoc
@@ -58,6 +60,41 @@ struct reorder_q_setup {
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
@@ -88,7 +125,7 @@ target_if_peer_set_default_routing(struct cdp_ctrl_objmgr_psoc *psoc,
bool hash_based, uint8_t ring_num,
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
* @pdev_id: pdev 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,
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
* @psoc: psoc pointer

View File

@@ -1,6 +1,6 @@
/*
* 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
* any purpose with or without fee is hereby granted, provided that the
@@ -155,6 +155,66 @@ out:
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
target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t pdev_id,
@@ -194,8 +254,53 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
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
target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
uint8_t pdev_id,
@@ -238,6 +343,35 @@ target_if_peer_rx_reorder_queue_setup(struct cdp_ctrl_objmgr_psoc *psoc,
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
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);
}
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:
return err_code;
}