mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
qcacmn: Block Ack state machine enhancement in DP
Move the state to in_progress when we process addba request and upon tx comletion of addba response, move the state to active. Any addba request received during in_progress is ignored and reo queue is updated with window size 1 and set to inactive. Change-Id: I69cfbc162d873f9e6842ca3e7971146dafba2695 Crs-fixed: 2188927
This commit is contained in:
parent
121589c105
commit
1c61e0664d
6 changed files with 153 additions and 22 deletions
|
|
@ -951,6 +951,35 @@ cdp_soc_detach(ol_txrx_soc_handle soc)
|
|||
soc->ops->cmn_drv_ops->txrx_soc_detach((void *)soc);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_addba_resp_tx_completion() - Indicate addba response tx
|
||||
* completion to dp to change tid state.
|
||||
* @soc: soc handle
|
||||
* @peer_handle: peer handle
|
||||
* @tid: tid
|
||||
* @status: Tx completion status
|
||||
*
|
||||
* Return: success/failure of tid update
|
||||
*/
|
||||
static inline int cdp_addba_resp_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->addba_resp_tx_completion)
|
||||
return 0;
|
||||
|
||||
return soc->ops->cmn_drv_ops->addba_resp_tx_completion(peer_handle, tid,
|
||||
status);
|
||||
}
|
||||
|
||||
static inline int cdp_addba_requestprocess(ol_txrx_soc_handle soc,
|
||||
void *peer_handle, uint8_t dialogtoken, uint16_t tid,
|
||||
uint16_t batimeout, uint16_t buffersize, uint16_t startseqnum)
|
||||
|
|
|
|||
|
|
@ -250,9 +250,13 @@ struct cdp_cmn_ops {
|
|||
|
||||
void (*txrx_soc_detach)(void *soc);
|
||||
|
||||
int (*addba_resp_tx_completion)(void *peer_handle, uint8_t tid,
|
||||
int status);
|
||||
|
||||
int (*addba_requestprocess)(void *peer_handle, uint8_t dialogtoken,
|
||||
uint16_t tid, uint16_t batimeout, uint16_t buffersize,
|
||||
uint16_t startseqnum);
|
||||
uint16_t tid, uint16_t batimeout,
|
||||
uint16_t buffersize,
|
||||
uint16_t startseqnum);
|
||||
|
||||
void (*addba_responsesetup)(void *peer_handle, uint8_t tid,
|
||||
uint8_t *dialogtoken, uint16_t *statuscode,
|
||||
|
|
|
|||
|
|
@ -383,6 +383,8 @@ void dp_local_peer_id_free(struct dp_pdev *pdev, struct dp_peer *peer)
|
|||
{
|
||||
}
|
||||
#endif
|
||||
int dp_addba_resp_tx_completion_wifi3(void *peer_handle, uint8_t tid,
|
||||
int status);
|
||||
extern int dp_addba_requestprocess_wifi3(void *peer_handle,
|
||||
uint8_t dialogtoken, uint16_t tid, uint16_t batimeout,
|
||||
uint16_t buffersize, uint16_t startseqnum);
|
||||
|
|
|
|||
|
|
@ -3879,7 +3879,8 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle,
|
|||
peer->bss_peer = 1;
|
||||
vdev->vap_bss_peer = peer;
|
||||
}
|
||||
|
||||
for (i = 0; i < DP_MAX_TIDS; i++)
|
||||
qdf_spinlock_create(&peer->rx_tid[i].tid_lock);
|
||||
|
||||
dp_local_peer_id_alloc(pdev, peer);
|
||||
DP_STATS_INIT(peer);
|
||||
|
|
@ -7335,6 +7336,7 @@ static struct cdp_cmn_ops dp_ops_cmn = {
|
|||
.txrx_ath_getstats = dp_get_device_stats,
|
||||
.addba_requestprocess = dp_addba_requestprocess_wifi3,
|
||||
.addba_responsesetup = dp_addba_responsesetup_wifi3,
|
||||
.addba_resp_tx_completion = dp_addba_resp_tx_completion_wifi3,
|
||||
.delba_process = dp_delba_process_wifi3,
|
||||
.set_addba_response = dp_set_addba_response,
|
||||
.get_peer_mac_addr_frm_id = dp_get_peer_mac_addr_frm_id,
|
||||
|
|
|
|||
|
|
@ -892,6 +892,10 @@ void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
|
|||
|
||||
DP_PRINT_STATS("Num of Addba Req = %d\n", rx_tid->num_of_addba_req);
|
||||
DP_PRINT_STATS("Num of Addba Resp = %d\n", rx_tid->num_of_addba_resp);
|
||||
DP_PRINT_STATS("Num of Addba Resp successful = %d\n",
|
||||
rx_tid->num_addba_rsp_success);
|
||||
DP_PRINT_STATS("Num of Addba Resp failed = %d\n",
|
||||
rx_tid->num_addba_rsp_failed);
|
||||
DP_PRINT_STATS("Num of Delba Req = %d\n", rx_tid->num_of_delba_req);
|
||||
DP_PRINT_STATS("BA window size = %d\n", rx_tid->ba_win_size);
|
||||
DP_PRINT_STATS("Pn size = %d\n", rx_tid->pn_size);
|
||||
|
|
@ -1132,6 +1136,8 @@ static int dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
|
|||
dp_set_ssn_valid_flag(¶ms, 0);
|
||||
|
||||
dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, ¶ms, dp_rx_tid_update_cb, rx_tid);
|
||||
|
||||
rx_tid->ba_win_size = ba_window_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1219,6 +1225,8 @@ int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||
rx_tid->num_of_addba_req = 0;
|
||||
rx_tid->num_of_delba_req = 0;
|
||||
rx_tid->num_of_addba_resp = 0;
|
||||
rx_tid->num_addba_rsp_failed = 0;
|
||||
rx_tid->num_addba_rsp_success = 0;
|
||||
#ifdef notyet
|
||||
hw_qdesc_size = hal_get_reo_qdesc_size(soc->hal_soc, ba_window_size);
|
||||
#else
|
||||
|
|
@ -1570,6 +1578,9 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
|
|||
int tid;
|
||||
uint32_t tid_delete_mask = 0;
|
||||
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
|
||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||
if (peer->rx_tid[tid].hw_qdesc_vaddr_unaligned != NULL) {
|
||||
dp_rx_tid_delete_wifi3(peer, tid);
|
||||
|
||||
|
|
@ -1579,6 +1590,7 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
|
|||
|
||||
tid_delete_mask |= (1 << tid);
|
||||
}
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
}
|
||||
#ifdef notyet /* See if FW can remove queues as part of peer cleanup */
|
||||
if (soc->ol_ops->peer_rx_reorder_queue_remove) {
|
||||
|
|
@ -1587,6 +1599,8 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
|
|||
tid_delete_mask);
|
||||
}
|
||||
#endif
|
||||
for (tid = 0; tid < DP_MAX_TIDS; tid++)
|
||||
qdf_spinlock_destroy(&peer->rx_tid[tid].tid_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1606,42 +1620,52 @@ void dp_peer_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
|
|||
}
|
||||
|
||||
/*
|
||||
* dp_rx_addba_requestprocess_wifi3() – Process ADDBA request from peer
|
||||
* dp_rx_addba_resp_tx_completion_wifi3() – Update Rx Tid State
|
||||
*
|
||||
* @peer: Datapath peer handle
|
||||
* @dialogtoken: dialogtoken from ADDBA frame
|
||||
* @tid: TID number
|
||||
* @startseqnum: Start seq. number received in BA sequence control
|
||||
* in ADDBA frame
|
||||
*
|
||||
* @status: tx completion status
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
int dp_addba_requestprocess_wifi3(void *peer_handle,
|
||||
uint8_t dialogtoken, uint16_t tid, uint16_t batimeout,
|
||||
uint16_t buffersize, uint16_t startseqnum)
|
||||
int dp_addba_resp_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 = &peer->rx_tid[tid];
|
||||
|
||||
if ((rx_tid->ba_status == DP_RX_BA_ACTIVE) &&
|
||||
(rx_tid->hw_qdesc_vaddr_unaligned != NULL))
|
||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||
if (status) {
|
||||
rx_tid->num_addba_rsp_failed++;
|
||||
dp_rx_tid_update_wifi3(peer, tid, 1, 0);
|
||||
rx_tid->ba_status = DP_RX_BA_INACTIVE;
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: Rx Tid- %d addba rsp tx completion failed!",
|
||||
__func__, tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dp_rx_tid_setup_wifi3(peer, tid, buffersize,
|
||||
startseqnum)) {
|
||||
/* TODO: Should we send addba reject in this case */
|
||||
rx_tid->num_addba_rsp_success++;
|
||||
if (rx_tid->ba_status == DP_RX_BA_INACTIVE) {
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: Rx Tid- %d hw qdesc is not in IN_PROGRESS",
|
||||
__func__, tid);
|
||||
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->dialogtoken = dialogtoken;
|
||||
rx_tid->ba_status = DP_RX_BA_ACTIVE;
|
||||
rx_tid->num_of_addba_req++;
|
||||
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1662,12 +1686,63 @@ void dp_addba_responsesetup_wifi3(void *peer_handle, uint8_t tid,
|
|||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
|
||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||
rx_tid->num_of_addba_resp++;
|
||||
/* setup ADDBA response parameters */
|
||||
*dialogtoken = rx_tid->dialogtoken;
|
||||
*statuscode = rx_tid->statuscode;
|
||||
*buffersize = rx_tid->ba_win_size;
|
||||
*batimeout = 0;
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_addba_requestprocess_wifi3() - Process ADDBA request from peer
|
||||
*
|
||||
* @peer: Datapath peer handle
|
||||
* @dialogtoken: dialogtoken from ADDBA frame
|
||||
* @tid: TID number
|
||||
* @batimeout: BA timeout
|
||||
* @buffersize: BA window size
|
||||
* @startseqnum: Start seq. number received in BA sequence control
|
||||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
int dp_addba_requestprocess_wifi3(void *peer_handle,
|
||||
uint8_t dialogtoken,
|
||||
uint16_t tid, uint16_t batimeout,
|
||||
uint16_t buffersize,
|
||||
uint16_t startseqnum)
|
||||
{
|
||||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
|
||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||
rx_tid->num_of_addba_req++;
|
||||
if ((rx_tid->ba_status == DP_RX_BA_ACTIVE &&
|
||||
rx_tid->hw_qdesc_vaddr_unaligned != NULL) ||
|
||||
(rx_tid->ba_status == DP_RX_BA_IN_PROGRESS)) {
|
||||
dp_rx_tid_update_wifi3(peer, tid, 1, 0);
|
||||
rx_tid->ba_status = DP_RX_BA_INACTIVE;
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: Rx Tid- %d hw qdesc is already setup",
|
||||
__func__, tid);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (dp_rx_tid_setup_wifi3(peer, tid, 1, 0)) {
|
||||
rx_tid->ba_status = DP_RX_BA_INACTIVE;
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
rx_tid->ba_status = DP_RX_BA_IN_PROGRESS;
|
||||
|
||||
rx_tid->ba_win_size = buffersize;
|
||||
rx_tid->dialogtoken = dialogtoken;
|
||||
rx_tid->startseqnum = startseqnum;
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1683,7 +1758,9 @@ void dp_set_addba_response(void *peer_handle, uint8_t tid,
|
|||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
|
||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||
rx_tid->userstatuscode = statuscode;
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1700,9 +1777,11 @@ int dp_delba_process_wifi3(void *peer_handle,
|
|||
struct dp_peer *peer = (struct dp_peer *)peer_handle;
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
|
||||
if (rx_tid->ba_status != DP_RX_BA_ACTIVE)
|
||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||
if (rx_tid->ba_status == DP_RX_BA_INACTIVE) {
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
}
|
||||
/* TODO: See if we can delete the existing REO queue descriptor and
|
||||
* replace with a new one without queue extenstion descript to save
|
||||
* memory
|
||||
|
|
@ -1711,7 +1790,7 @@ int dp_delba_process_wifi3(void *peer_handle,
|
|||
dp_rx_tid_update_wifi3(peer, tid, 1, 0);
|
||||
|
||||
rx_tid->ba_status = DP_RX_BA_INACTIVE;
|
||||
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1805,6 +1884,7 @@ dp_set_pn_check_wifi3(struct cdp_vdev *vdev_handle, struct cdp_peer *peer_handle
|
|||
|
||||
for (i = 0; i < DP_MAX_TIDS; i++) {
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[i];
|
||||
qdf_spin_lock_bh(&rx_tid->tid_lock);
|
||||
if (rx_tid->hw_qdesc_vaddr_unaligned != NULL) {
|
||||
params.std.addr_lo =
|
||||
rx_tid->hw_qdesc_paddr & 0xffffffff;
|
||||
|
|
@ -1832,6 +1912,7 @@ dp_set_pn_check_wifi3(struct cdp_vdev *vdev_handle, struct cdp_peer *peer_handle
|
|||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
"PN Check not setup for TID :%d \n", i);
|
||||
}
|
||||
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -410,6 +410,7 @@ struct dp_rx_reorder_array_elem {
|
|||
|
||||
#define DP_RX_BA_INACTIVE 0
|
||||
#define DP_RX_BA_ACTIVE 1
|
||||
#define DP_RX_BA_IN_PROGRESS 2
|
||||
struct dp_reo_cmd_info {
|
||||
uint16_t cmd;
|
||||
enum hal_reo_cmd_type cmd_type;
|
||||
|
|
@ -432,6 +433,12 @@ struct dp_rx_tid {
|
|||
/* Num of delba requests */
|
||||
uint32_t num_of_delba_req;
|
||||
|
||||
/* Num of addba responses successful */
|
||||
uint32_t num_addba_rsp_success;
|
||||
|
||||
/* Num of addba responses failed */
|
||||
uint32_t num_addba_rsp_failed;
|
||||
|
||||
/* pn size */
|
||||
uint8_t pn_size;
|
||||
/* REO TID queue descriptors */
|
||||
|
|
@ -446,6 +453,9 @@ struct dp_rx_tid {
|
|||
/* RX BA window size */
|
||||
uint16_t ba_win_size;
|
||||
|
||||
/* Starting sequence number in Addba request */
|
||||
uint16_t startseqnum;
|
||||
|
||||
/* TODO: Check the following while adding defragmentation support */
|
||||
struct dp_rx_reorder_array_elem *array;
|
||||
/* base - single rx reorder element used for non-aggr cases */
|
||||
|
|
@ -458,6 +468,9 @@ struct dp_rx_tid {
|
|||
void *dst_ring_desc;
|
||||
struct dp_rx_desc *head_frag_desc;
|
||||
|
||||
/* rx_tid lock */
|
||||
qdf_spinlock_t tid_lock;
|
||||
|
||||
/* Sequence and fragments that are being processed currently */
|
||||
uint32_t curr_seq_num;
|
||||
uint32_t curr_frag_num;
|
||||
|
|
|
|||
Loading…
Reference in a new issue