qcacmn: Implement send DELBA per HTT event

Is some cases, FW wants to adjust BA session parameters
FW sends a HTT event and HOST helps to send out DELBA
and modify BA win size in the next round of ADDBA req/resp
exchange to reduce following RX AMPDU aggr-size

Change-Id: I97777ff59a18346f2cd4e2e562c8ae6acdcd69d7
CRs-Fixed: 2644641
This commit is contained in:
Yu Tian
2020-03-20 17:58:33 +08:00
committed by nshrivas
parent d5d364a58d
commit 8abdbcc616
5 changed files with 117 additions and 0 deletions

View File

@@ -4347,6 +4347,27 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
is_wds);
break;
}
case HTT_T2H_MSG_TYPE_RX_DELBA:
{
uint16_t peer_id;
uint8_t tid;
uint8_t win_sz;
QDF_STATUS status;
peer_id = HTT_RX_DELBA_PEER_ID_GET(*msg_word);
tid = HTT_RX_DELBA_TID_GET(*msg_word);
win_sz = HTT_RX_DELBA_WIN_SIZE_GET(*msg_word);
status = dp_rx_delba_ind_handler(
soc->dp_soc,
peer_id, tid, win_sz);
QDF_TRACE(QDF_MODULE_ID_TXRX,
QDF_TRACE_LEVEL_INFO,
FL("DELBA PeerID %d BAW %d TID %d stat %d"),
peer_id, win_sz, tid, status);
break;
}
default:
break;
};

View File

@@ -95,6 +95,12 @@ int htt_wbm_event_record(struct htt_logger *h, uint8_t tx_status,
#define HTT_PPDU_DESC_MAX_DEPTH 16
#define DP_SCAN_PEER_ID 0xFFFF
#define HTT_RX_DELBA_WIN_SIZE_M 0x0000FC00
#define HTT_RX_DELBA_WIN_SIZE_S 10
#define HTT_RX_DELBA_WIN_SIZE_GET(word) \
(((word) & HTT_RX_DELBA_WIN_SIZE_M) >> HTT_RX_DELBA_WIN_SIZE_S)
/*
* Set the base misclist size to HTT copy engine source ring size
* to guarantee that a packet on the misclist wont be freed while it

View File

@@ -2812,6 +2812,8 @@ static void dp_check_ba_buffersize(struct dp_peer *peer,
}
}
#define DP_RX_BA_SESSION_DISABLE 1
/*
* dp_addba_requestprocess_wifi3() - Process ADDBA request from peer
*
@@ -2863,6 +2865,25 @@ int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc,
status = QDF_STATUS_E_FAILURE;
goto fail;
}
if (rx_tid->rx_ba_win_size_override == DP_RX_BA_SESSION_DISABLE) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s disable BA session",
__func__);
buffersize = 1;
} else if (rx_tid->rx_ba_win_size_override) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s override BA win to %d", __func__,
rx_tid->rx_ba_win_size_override);
buffersize = rx_tid->rx_ba_win_size_override;
} else {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s restore BA win %d based on addba req",
__func__, buffersize);
}
dp_check_ba_buffersize(peer, tid, buffersize);
if (dp_rx_tid_setup_wifi3(peer, tid,
@@ -2882,6 +2903,9 @@ int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc,
else
rx_tid->statuscode = IEEE80211_STATUS_SUCCESS;
if (rx_tid->rx_ba_win_size_override == DP_RX_BA_SESSION_DISABLE)
rx_tid->statuscode = IEEE80211_STATUS_REFUSED;
qdf_spin_unlock_bh(&rx_tid->tid_lock);
fail:
@@ -3279,6 +3303,65 @@ dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id,
dp_peer_unref_del_find_by_id(peer);
}
QDF_STATUS
dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id,
uint8_t tid, uint16_t win_sz)
{
struct dp_soc *soc = (struct dp_soc *)soc_handle;
struct dp_peer *peer;
struct dp_rx_tid *rx_tid;
QDF_STATUS status = QDF_STATUS_SUCCESS;
peer = dp_peer_find_by_id(soc, peer_id);
if (!peer) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"Couldn't find peer from ID %d",
peer_id);
return QDF_STATUS_E_FAILURE;
}
qdf_assert_always(tid < DP_MAX_TIDS);
rx_tid = &peer->rx_tid[tid];
if (rx_tid->hw_qdesc_vaddr_unaligned) {
if (!rx_tid->delba_tx_status) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s: PEER_ID: %d TID: %d, BA win: %d ",
__func__, peer_id, tid, win_sz);
qdf_spin_lock_bh(&rx_tid->tid_lock);
rx_tid->delba_tx_status = 1;
rx_tid->rx_ba_win_size_override =
qdf_min((uint16_t)63, win_sz);
rx_tid->delba_rcode =
IEEE80211_REASON_QOS_SETUP_REQUIRED;
qdf_spin_unlock_bh(&rx_tid->tid_lock);
if (soc->cdp_soc.ol_ops->send_delba)
soc->cdp_soc.ol_ops->send_delba(
peer->vdev->pdev->soc->ctrl_psoc,
peer->vdev->vdev_id,
peer->mac_addr.raw,
tid,
rx_tid->delba_rcode);
}
} else {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"BA session is not setup for TID:%d ", tid);
status = QDF_STATUS_E_FAILURE;
}
dp_peer_unref_del_find_by_id(peer);
return status;
}
#ifdef DP_PEER_EXTENDED_API
QDF_STATUS dp_register_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
struct ol_txrx_desc_type *sta_desc)

View File

@@ -100,6 +100,10 @@ void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id,
void dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id,
enum cdp_sec_type sec_type, int is_unicast,
u_int32_t *michael_key, u_int32_t *rx_pn);
QDF_STATUS dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id,
uint8_t tid, uint16_t win_sz);
uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle,
uint16_t peer_id, uint8_t *peer_mac);

View File

@@ -600,6 +600,9 @@ struct dp_rx_tid {
/* Delba reason code for retries */
uint8_t delba_rcode;
/* Coex Override preserved windows size 1 based */
uint16_t rx_ba_win_size_override;
#ifdef WLAN_PEER_JITTER
/* Tx Jitter stats */
uint32_t tx_avg_jitter;