qcacmn: Handle 2k exception and rate limit delba
Upon receiving 2k jump exception, send delba and track delba tx status and retries. Change-Id: Ida35256233869dfa390c40030c9296b9c48481ce Crs-fixed: 2239856
This commit is contained in:
@@ -1061,6 +1061,36 @@ static inline int cdp_delba_process(ol_txrx_soc_handle soc,
|
|||||||
tid, reasoncode);
|
tid, reasoncode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cdp_delba_tx_completion() - Handle delba tx completion
|
||||||
|
* to update stats and retry transmission if failed.
|
||||||
|
* @soc: soc handle
|
||||||
|
* @peer_handle: peer handle
|
||||||
|
* @tid: Tid number
|
||||||
|
* @status: Tx completion status
|
||||||
|
*
|
||||||
|
* Return: 0 on Success, 1 on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline int cdp_delba_tx_completion(ol_txrx_soc_handle soc,
|
||||||
|
void *peer_handle,
|
||||||
|
uint8_t tid, int status)
|
||||||
|
{
|
||||||
|
if (!soc || !soc->ops) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
"%s: Invalid Instance:", __func__);
|
||||||
|
QDF_BUG(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!soc->ops->cmn_drv_ops ||
|
||||||
|
!soc->ops->cmn_drv_ops->delba_tx_completion)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return soc->ops->cmn_drv_ops->delba_tx_completion(peer_handle,
|
||||||
|
tid, status);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void cdp_set_addbaresponse(ol_txrx_soc_handle soc,
|
static inline void cdp_set_addbaresponse(ol_txrx_soc_handle soc,
|
||||||
void *peer_handle, int tid, uint16_t statuscode)
|
void *peer_handle, int tid, uint16_t statuscode)
|
||||||
{
|
{
|
||||||
|
@@ -271,6 +271,17 @@ struct cdp_cmn_ops {
|
|||||||
int (*delba_process)(void *peer_handle,
|
int (*delba_process)(void *peer_handle,
|
||||||
int tid, uint16_t reasoncode);
|
int tid, uint16_t reasoncode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delba_tx_completion() - Indicate delba tx status
|
||||||
|
* @peer_handle: Peer handle
|
||||||
|
* @tid: Tid number
|
||||||
|
* @status: Tx completion status
|
||||||
|
*
|
||||||
|
* Return: 0 on Success, 1 on failure
|
||||||
|
*/
|
||||||
|
int (*delba_tx_completion)(void *peer_handle,
|
||||||
|
uint8_t tid, int status);
|
||||||
|
|
||||||
void (*set_addba_response)(void *peer_handle,
|
void (*set_addba_response)(void *peer_handle,
|
||||||
uint8_t tid, uint16_t statuscode);
|
uint8_t tid, uint16_t statuscode);
|
||||||
|
|
||||||
@@ -806,6 +817,17 @@ struct ol_if_ops {
|
|||||||
#endif
|
#endif
|
||||||
int (*peer_sta_kickout)(void *ctrl_pdev, uint8_t *peer_macaddr);
|
int (*peer_sta_kickout)(void *ctrl_pdev, uint8_t *peer_macaddr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send_delba() - Send delba to peer
|
||||||
|
* @pdev_handle: Dp pdev handle
|
||||||
|
* @ctrl_peer: Peer handle
|
||||||
|
* @peer_macaddr: Peer mac addr
|
||||||
|
* @tid: Tid number
|
||||||
|
*
|
||||||
|
* Return: 0 for success, non-zero for failure
|
||||||
|
*/
|
||||||
|
int (*send_delba)(void *pdev_handle, void *ctrl_peer,
|
||||||
|
uint8_t *peer_macaddr, uint8_t tid, void *vdev_handle);
|
||||||
/* TODO: Add any other control path calls required to OL_IF/WMA layer */
|
/* TODO: Add any other control path calls required to OL_IF/WMA layer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -656,7 +656,18 @@ extern void dp_set_addba_response(void *peer_handle, uint8_t tid,
|
|||||||
uint16_t statuscode);
|
uint16_t statuscode);
|
||||||
extern int dp_delba_process_wifi3(void *peer_handle,
|
extern int dp_delba_process_wifi3(void *peer_handle,
|
||||||
int tid, uint16_t reasoncode);
|
int tid, uint16_t reasoncode);
|
||||||
|
/*
|
||||||
|
* dp_delba_tx_completion_wifi3() - Handle delba tx completion
|
||||||
|
*
|
||||||
|
* @peer_handle: Peer handle
|
||||||
|
* @tid: Tid number
|
||||||
|
* @status: Tx completion status
|
||||||
|
* Indicate status of delba Tx to DP for stats update and retry
|
||||||
|
* delba if tx failed.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int dp_delba_tx_completion_wifi3(void *peer_handle, uint8_t tid,
|
||||||
|
int status);
|
||||||
extern int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
extern int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
||||||
uint32_t ba_window_size, uint32_t start_seq);
|
uint32_t ba_window_size, uint32_t start_seq);
|
||||||
|
|
||||||
|
@@ -7607,6 +7607,7 @@ static struct cdp_cmn_ops dp_ops_cmn = {
|
|||||||
.txrx_peer_flush_ast_table = dp_wds_flush_ast_table_wifi3,
|
.txrx_peer_flush_ast_table = dp_wds_flush_ast_table_wifi3,
|
||||||
.txrx_peer_map_attach = dp_peer_map_attach_wifi3,
|
.txrx_peer_map_attach = dp_peer_map_attach_wifi3,
|
||||||
.txrx_pdev_set_ctrl_pdev = dp_pdev_set_ctrl_pdev,
|
.txrx_pdev_set_ctrl_pdev = dp_pdev_set_ctrl_pdev,
|
||||||
|
.delba_tx_completion = dp_delba_tx_completion_wifi3,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cdp_ctrl_ops dp_ops_ctrl = {
|
static struct cdp_ctrl_ops dp_ops_ctrl = {
|
||||||
|
@@ -900,15 +900,24 @@ void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
|
|||||||
queue_status->late_recv_mpdu_cnt, queue_status->win_jump_2k,
|
queue_status->late_recv_mpdu_cnt, queue_status->win_jump_2k,
|
||||||
queue_status->hole_cnt);
|
queue_status->hole_cnt);
|
||||||
|
|
||||||
DP_PRINT_STATS("Num of Addba Req = %d\n", rx_tid->num_of_addba_req);
|
DP_PRINT_STATS("Addba Req : %d\n"
|
||||||
DP_PRINT_STATS("Num of Addba Resp = %d\n", rx_tid->num_of_addba_resp);
|
"Addba Resp : %d\n"
|
||||||
DP_PRINT_STATS("Num of Addba Resp successful = %d\n",
|
"Addba Resp success : %d\n"
|
||||||
rx_tid->num_addba_rsp_success);
|
"Addba Resp failed : %d\n"
|
||||||
DP_PRINT_STATS("Num of Addba Resp failed = %d\n",
|
"Delba Req received : %d\n"
|
||||||
rx_tid->num_addba_rsp_failed);
|
"Delba Tx success : %d\n"
|
||||||
DP_PRINT_STATS("Num of Delba Req = %d\n", rx_tid->num_of_delba_req);
|
"Delba Tx Fail : %d\n"
|
||||||
DP_PRINT_STATS("BA window size = %d\n", rx_tid->ba_win_size);
|
"BA window size : %d\n"
|
||||||
DP_PRINT_STATS("Pn size = %d\n", rx_tid->pn_size);
|
"Pn size : %d\n",
|
||||||
|
rx_tid->num_of_addba_req,
|
||||||
|
rx_tid->num_of_addba_resp,
|
||||||
|
rx_tid->num_addba_rsp_success,
|
||||||
|
rx_tid->num_addba_rsp_failed,
|
||||||
|
rx_tid->num_of_delba_req,
|
||||||
|
rx_tid->delba_tx_success_cnt,
|
||||||
|
rx_tid->delba_tx_fail_cnt,
|
||||||
|
rx_tid->ba_win_size,
|
||||||
|
rx_tid->pn_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc,
|
static inline struct dp_peer *dp_peer_find_add_id(struct dp_soc *soc,
|
||||||
@@ -1239,11 +1248,16 @@ int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||||||
if (rx_tid->hw_qdesc_vaddr_unaligned != NULL)
|
if (rx_tid->hw_qdesc_vaddr_unaligned != NULL)
|
||||||
return dp_rx_tid_update_wifi3(peer, tid, ba_window_size,
|
return dp_rx_tid_update_wifi3(peer, tid, ba_window_size,
|
||||||
start_seq);
|
start_seq);
|
||||||
|
rx_tid->delba_tx_status = 0;
|
||||||
|
rx_tid->ppdu_id_2k = 0;
|
||||||
rx_tid->num_of_addba_req = 0;
|
rx_tid->num_of_addba_req = 0;
|
||||||
rx_tid->num_of_delba_req = 0;
|
rx_tid->num_of_delba_req = 0;
|
||||||
rx_tid->num_of_addba_resp = 0;
|
rx_tid->num_of_addba_resp = 0;
|
||||||
rx_tid->num_addba_rsp_failed = 0;
|
rx_tid->num_addba_rsp_failed = 0;
|
||||||
rx_tid->num_addba_rsp_success = 0;
|
rx_tid->num_addba_rsp_success = 0;
|
||||||
|
rx_tid->delba_tx_success_cnt = 0;
|
||||||
|
rx_tid->delba_tx_fail_cnt = 0;
|
||||||
|
rx_tid->statuscode = 0;
|
||||||
#ifdef notyet
|
#ifdef notyet
|
||||||
hw_qdesc_size = hal_get_reo_qdesc_size(soc->hal_soc, ba_window_size);
|
hw_qdesc_size = hal_get_reo_qdesc_size(soc->hal_soc, ba_window_size);
|
||||||
#else
|
#else
|
||||||
@@ -1648,8 +1662,14 @@ int dp_addba_resp_tx_completion_wifi3(void *peer_handle,
|
|||||||
uint8_t tid, int status)
|
uint8_t tid, int status)
|
||||||
{
|
{
|
||||||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
struct dp_rx_tid *rx_tid = NULL;
|
||||||
|
|
||||||
|
if (!peer || peer->delete_in_progress) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
"%s: Peer is NULL!\n", __func__);
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
rx_tid = &peer->rx_tid[tid];
|
||||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||||
if (status) {
|
if (status) {
|
||||||
rx_tid->num_addba_rsp_failed++;
|
rx_tid->num_addba_rsp_failed++;
|
||||||
@@ -1659,7 +1679,7 @@ int dp_addba_resp_tx_completion_wifi3(void *peer_handle,
|
|||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
"%s: Rx Tid- %d addba rsp tx completion failed!",
|
"%s: Rx Tid- %d addba rsp tx completion failed!",
|
||||||
__func__, tid);
|
__func__, tid);
|
||||||
return 0;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
rx_tid->num_addba_rsp_success++;
|
rx_tid->num_addba_rsp_success++;
|
||||||
@@ -1671,19 +1691,9 @@ int dp_addba_resp_tx_completion_wifi3(void *peer_handle,
|
|||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp_rx_tid_update_wifi3(peer, tid, rx_tid->ba_win_size,
|
|
||||||
rx_tid->startseqnum)) {
|
|
||||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
|
||||||
return QDF_STATUS_E_FAILURE;
|
|
||||||
}
|
|
||||||
if (rx_tid->userstatuscode != IEEE80211_STATUS_SUCCESS)
|
|
||||||
rx_tid->statuscode = rx_tid->userstatuscode;
|
|
||||||
else
|
|
||||||
rx_tid->statuscode = IEEE80211_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
rx_tid->ba_status = DP_RX_BA_ACTIVE;
|
rx_tid->ba_status = DP_RX_BA_ACTIVE;
|
||||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
return 0;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1701,8 +1711,14 @@ void dp_addba_responsesetup_wifi3(void *peer_handle, uint8_t tid,
|
|||||||
uint16_t *buffersize, uint16_t *batimeout)
|
uint16_t *buffersize, uint16_t *batimeout)
|
||||||
{
|
{
|
||||||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
struct dp_rx_tid *rx_tid = NULL;
|
||||||
|
|
||||||
|
if (!peer || peer->delete_in_progress) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
"%s: Peer is NULL!\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rx_tid = &peer->rx_tid[tid];
|
||||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||||
rx_tid->num_of_addba_resp++;
|
rx_tid->num_of_addba_resp++;
|
||||||
/* setup ADDBA response parameters */
|
/* setup ADDBA response parameters */
|
||||||
@@ -1732,8 +1748,14 @@ int dp_addba_requestprocess_wifi3(void *peer_handle,
|
|||||||
uint16_t startseqnum)
|
uint16_t startseqnum)
|
||||||
{
|
{
|
||||||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
struct dp_rx_tid *rx_tid = NULL;
|
||||||
|
|
||||||
|
if (!peer || peer->delete_in_progress) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
"%s: Peer is NULL!\n", __func__);
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
rx_tid = &peer->rx_tid[tid];
|
||||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||||
rx_tid->num_of_addba_req++;
|
rx_tid->num_of_addba_req++;
|
||||||
if ((rx_tid->ba_status == DP_RX_BA_ACTIVE &&
|
if ((rx_tid->ba_status == DP_RX_BA_ACTIVE &&
|
||||||
@@ -1748,7 +1770,7 @@ int dp_addba_requestprocess_wifi3(void *peer_handle,
|
|||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp_rx_tid_setup_wifi3(peer, tid, 1, 0)) {
|
if (dp_rx_tid_setup_wifi3(peer, tid, buffersize, 0)) {
|
||||||
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);
|
||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
@@ -1758,8 +1780,15 @@ int dp_addba_requestprocess_wifi3(void *peer_handle,
|
|||||||
rx_tid->ba_win_size = buffersize;
|
rx_tid->ba_win_size = buffersize;
|
||||||
rx_tid->dialogtoken = dialogtoken;
|
rx_tid->dialogtoken = dialogtoken;
|
||||||
rx_tid->startseqnum = startseqnum;
|
rx_tid->startseqnum = startseqnum;
|
||||||
|
|
||||||
|
if (rx_tid->userstatuscode != IEEE80211_STATUS_SUCCESS)
|
||||||
|
rx_tid->statuscode = rx_tid->userstatuscode;
|
||||||
|
else
|
||||||
|
rx_tid->statuscode = IEEE80211_STATUS_SUCCESS;
|
||||||
|
|
||||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
return 0;
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1811,6 +1840,53 @@ int dp_delba_process_wifi3(void *peer_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dp_rx_delba_tx_completion_wifi3() – Send Delba Request
|
||||||
|
*
|
||||||
|
* @peer: Datapath peer handle
|
||||||
|
* @tid: TID number
|
||||||
|
* @status: tx completion status
|
||||||
|
* Return: 0 on success, error code on failure
|
||||||
|
*/
|
||||||
|
|
||||||
|
int dp_delba_tx_completion_wifi3(void *peer_handle,
|
||||||
|
uint8_t tid, int status)
|
||||||
|
{
|
||||||
|
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||||
|
struct dp_rx_tid *rx_tid = NULL;
|
||||||
|
|
||||||
|
if (!peer || peer->delete_in_progress) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
"%s: Peer is NULL!", __func__);
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
rx_tid = &peer->rx_tid[tid];
|
||||||
|
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||||
|
if (status) {
|
||||||
|
rx_tid->delba_tx_fail_cnt++;
|
||||||
|
if (rx_tid->delba_tx_retry >= DP_MAX_DELBA_RETRY) {
|
||||||
|
rx_tid->delba_tx_retry = 0;
|
||||||
|
rx_tid->delba_tx_status = 0;
|
||||||
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
|
} else {
|
||||||
|
rx_tid->delba_tx_retry++;
|
||||||
|
rx_tid->delba_tx_status = 1;
|
||||||
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
|
peer->vdev->pdev->soc->cdp_soc.ol_ops->send_delba(
|
||||||
|
peer->vdev->pdev->ctrl_pdev, peer->ctrl_peer,
|
||||||
|
peer->mac_addr.raw, tid, peer->vdev->ctrl_vdev);
|
||||||
|
}
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
} else {
|
||||||
|
rx_tid->delba_tx_success_cnt++;
|
||||||
|
rx_tid->delba_tx_retry = 0;
|
||||||
|
rx_tid->delba_tx_status = 0;
|
||||||
|
}
|
||||||
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
void dp_rx_discard(struct dp_vdev *vdev, struct dp_peer *peer, unsigned tid,
|
void dp_rx_discard(struct dp_vdev *vdev, struct dp_peer *peer, unsigned tid,
|
||||||
qdf_nbuf_t msdu_list)
|
qdf_nbuf_t msdu_list)
|
||||||
{
|
{
|
||||||
|
@@ -468,6 +468,73 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr,
|
|||||||
return mpdu_done;
|
return mpdu_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dp_2k_jump_handle() - Function to handle 2k jump exception
|
||||||
|
* on WBM ring
|
||||||
|
*
|
||||||
|
* @soc: core DP main context
|
||||||
|
* @nbuf: buffer pointer
|
||||||
|
* @rx_tlv_hdr: start of rx tlv header
|
||||||
|
* @peer_id: peer id of first msdu
|
||||||
|
* @tid: Tid for which exception occurred
|
||||||
|
*
|
||||||
|
* This function handles 2k jump violations arising out
|
||||||
|
* of receiving aggregates in non BA case. This typically
|
||||||
|
* may happen if aggregates are received on a QOS enabled TID
|
||||||
|
* while Rx window size is still initialized to value of 2. Or
|
||||||
|
* it may also happen if negotiated window size is 1 but peer
|
||||||
|
* sends aggregates.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
dp_2k_jump_handle(struct dp_soc *soc,
|
||||||
|
qdf_nbuf_t nbuf,
|
||||||
|
uint8_t *rx_tlv_hdr,
|
||||||
|
uint16_t peer_id,
|
||||||
|
uint8_t tid)
|
||||||
|
{
|
||||||
|
uint32_t ppdu_id;
|
||||||
|
struct dp_peer *peer = NULL;
|
||||||
|
struct dp_rx_tid *rx_tid = NULL;
|
||||||
|
|
||||||
|
peer = dp_peer_find_by_id(soc, peer_id);
|
||||||
|
if (!peer || peer->delete_in_progress) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"peer not found");
|
||||||
|
goto free_nbuf;
|
||||||
|
}
|
||||||
|
rx_tid = &peer->rx_tid[tid];
|
||||||
|
if (qdf_unlikely(rx_tid == NULL)) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"rx_tid is NULL!!");
|
||||||
|
goto free_nbuf;
|
||||||
|
}
|
||||||
|
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||||
|
ppdu_id = hal_rx_attn_phy_ppdu_id_get(rx_tlv_hdr);
|
||||||
|
if (rx_tid->ppdu_id_2k != ppdu_id) {
|
||||||
|
rx_tid->ppdu_id_2k = ppdu_id;
|
||||||
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
|
goto free_nbuf;
|
||||||
|
}
|
||||||
|
if (!rx_tid->delba_tx_status) {
|
||||||
|
rx_tid->delba_tx_retry++;
|
||||||
|
rx_tid->delba_tx_status = 1;
|
||||||
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
|
soc->cdp_soc.ol_ops->send_delba(peer->vdev->pdev->ctrl_pdev,
|
||||||
|
peer->ctrl_peer,
|
||||||
|
peer->mac_addr.raw,
|
||||||
|
tid,
|
||||||
|
peer->vdev->ctrl_vdev);
|
||||||
|
} else {
|
||||||
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_nbuf:
|
||||||
|
qdf_nbuf_free(nbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_rx_null_q_desc_handle() - Function to handle NULL Queue
|
* dp_rx_null_q_desc_handle() - Function to handle NULL Queue
|
||||||
* descriptor violation on either a
|
* descriptor violation on either a
|
||||||
@@ -1053,6 +1120,8 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
|
|||||||
qdf_nbuf_t nbuf, next;
|
qdf_nbuf_t nbuf, next;
|
||||||
struct hal_wbm_err_desc_info wbm_err_info = { 0 };
|
struct hal_wbm_err_desc_info wbm_err_info = { 0 };
|
||||||
uint8_t pool_id;
|
uint8_t pool_id;
|
||||||
|
uint16_t peer_id = 0xFFFF;
|
||||||
|
uint8_t tid = 0;
|
||||||
|
|
||||||
/* Debug -- Remove later */
|
/* Debug -- Remove later */
|
||||||
qdf_assert(soc && hal_ring);
|
qdf_assert(soc && hal_ring);
|
||||||
@@ -1190,10 +1259,25 @@ done:
|
|||||||
continue;
|
continue;
|
||||||
/* TODO */
|
/* TODO */
|
||||||
/* Add per error code accounting */
|
/* Add per error code accounting */
|
||||||
|
case HAL_REO_ERR_REGULAR_FRAME_2K_JUMP:
|
||||||
|
pool_id = wbm_err_info.pool_id;
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"Got pkt with REO ERROR: %d",
|
||||||
|
wbm_err_info.reo_err_code);
|
||||||
|
if (hal_rx_msdu_end_first_msdu_get(rx_tlv_hdr)) {
|
||||||
|
peer_id =
|
||||||
|
hal_rx_mpdu_start_sw_peer_id_get(rx_tlv_hdr);
|
||||||
|
tid =
|
||||||
|
hal_rx_mpdu_start_tid_get(hal_soc, rx_tlv_hdr);
|
||||||
|
}
|
||||||
|
dp_2k_jump_handle(soc, nbuf, rx_tlv_hdr,
|
||||||
|
peer_id, tid);
|
||||||
|
nbuf = next;
|
||||||
|
continue;
|
||||||
default:
|
default:
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
QDF_TRACE_LEVEL_DEBUG,
|
QDF_TRACE_LEVEL_ERROR,
|
||||||
"REO error %d detected",
|
"REO error %d detected",
|
||||||
wbm_err_info.reo_err_code);
|
wbm_err_info.reo_err_code);
|
||||||
}
|
}
|
||||||
|
@@ -92,6 +92,9 @@
|
|||||||
|
|
||||||
#define DP_MAX_INTERRUPT_CONTEXTS 8
|
#define DP_MAX_INTERRUPT_CONTEXTS 8
|
||||||
|
|
||||||
|
/* Maximum retries for Delba per tid per peer */
|
||||||
|
#define DP_MAX_DELBA_RETRY 3
|
||||||
|
|
||||||
#ifndef REMOVE_PKT_LOG
|
#ifndef REMOVE_PKT_LOG
|
||||||
enum rx_pktlog_mode {
|
enum rx_pktlog_mode {
|
||||||
DP_RX_PKTLOG_DISABLED = 0,
|
DP_RX_PKTLOG_DISABLED = 0,
|
||||||
@@ -480,6 +483,20 @@ struct dp_rx_tid {
|
|||||||
uint16_t statuscode;
|
uint16_t statuscode;
|
||||||
/* user defined ADDBA response status code */
|
/* user defined ADDBA response status code */
|
||||||
uint16_t userstatuscode;
|
uint16_t userstatuscode;
|
||||||
|
|
||||||
|
/* Store ppdu_id when 2k exception is received */
|
||||||
|
uint32_t ppdu_id_2k;
|
||||||
|
|
||||||
|
/* Delba Tx completion status */
|
||||||
|
uint8_t delba_tx_status;
|
||||||
|
|
||||||
|
/* Delba Tx retry count */
|
||||||
|
uint8_t delba_tx_retry;
|
||||||
|
|
||||||
|
/* Delba stats */
|
||||||
|
uint32_t delba_tx_success_cnt;
|
||||||
|
uint32_t delba_tx_fail_cnt;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* per interrupt context */
|
/* per interrupt context */
|
||||||
|
@@ -496,7 +496,13 @@ inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc,
|
|||||||
|
|
||||||
if (p->ba_window_size < 1)
|
if (p->ba_window_size < 1)
|
||||||
p->ba_window_size = 1;
|
p->ba_window_size = 1;
|
||||||
|
/*
|
||||||
|
* WAR to get 2k exception in Non BA case.
|
||||||
|
* Setting window size to 2 to get 2k jump exception
|
||||||
|
* when we receive aggregates in Non BA case
|
||||||
|
*/
|
||||||
|
if (p->ba_window_size == 1)
|
||||||
|
p->ba_window_size++;
|
||||||
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_4,
|
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_4,
|
||||||
BA_WINDOW_SIZE, p->ba_window_size - 1);
|
BA_WINDOW_SIZE, p->ba_window_size - 1);
|
||||||
|
|
||||||
|
@@ -105,7 +105,13 @@ void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size,
|
|||||||
|
|
||||||
if (ba_window_size < 1)
|
if (ba_window_size < 1)
|
||||||
ba_window_size = 1;
|
ba_window_size = 1;
|
||||||
|
/*
|
||||||
|
* WAR to get 2k exception in Non BA case.
|
||||||
|
* Setting window size to 2 to get 2k jump exception
|
||||||
|
* when we receive aggregates in Non BA case
|
||||||
|
*/
|
||||||
|
if (ba_window_size == 1)
|
||||||
|
ba_window_size++;
|
||||||
/* Set RTY bit for non-BA case. Duplicate detection is currently not
|
/* Set RTY bit for non-BA case. Duplicate detection is currently not
|
||||||
* done by HW in non-BA case if RTY bit is not set.
|
* done by HW in non-BA case if RTY bit is not set.
|
||||||
* TODO: This is a temporary War and should be removed once HW fix is
|
* TODO: This is a temporary War and should be removed once HW fix is
|
||||||
|
Reference in New Issue
Block a user