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:
@@ -4347,6 +4347,27 @@ static void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
|
|||||||
is_wds);
|
is_wds);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@@ -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 HTT_PPDU_DESC_MAX_DEPTH 16
|
||||||
#define DP_SCAN_PEER_ID 0xFFFF
|
#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
|
* 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
|
* to guarantee that a packet on the misclist wont be freed while it
|
||||||
|
@@ -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
|
* 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;
|
status = QDF_STATUS_E_FAILURE;
|
||||||
goto fail;
|
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);
|
dp_check_ba_buffersize(peer, tid, buffersize);
|
||||||
|
|
||||||
if (dp_rx_tid_setup_wifi3(peer, tid,
|
if (dp_rx_tid_setup_wifi3(peer, tid,
|
||||||
@@ -2882,6 +2903,9 @@ int dp_addba_requestprocess_wifi3(struct cdp_soc_t *cdp_soc,
|
|||||||
else
|
else
|
||||||
rx_tid->statuscode = IEEE80211_STATUS_SUCCESS;
|
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);
|
qdf_spin_unlock_bh(&rx_tid->tid_lock);
|
||||||
|
|
||||||
fail:
|
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);
|
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
|
#ifdef DP_PEER_EXTENDED_API
|
||||||
QDF_STATUS dp_register_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
QDF_STATUS dp_register_peer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||||
struct ol_txrx_desc_type *sta_desc)
|
struct ol_txrx_desc_type *sta_desc)
|
||||||
|
@@ -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,
|
void dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id,
|
||||||
enum cdp_sec_type sec_type, int is_unicast,
|
enum cdp_sec_type sec_type, int is_unicast,
|
||||||
u_int32_t *michael_key, u_int32_t *rx_pn);
|
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,
|
uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle,
|
||||||
uint16_t peer_id, uint8_t *peer_mac);
|
uint16_t peer_id, uint8_t *peer_mac);
|
||||||
|
|
||||||
|
@@ -600,6 +600,9 @@ struct dp_rx_tid {
|
|||||||
/* Delba reason code for retries */
|
/* Delba reason code for retries */
|
||||||
uint8_t delba_rcode;
|
uint8_t delba_rcode;
|
||||||
|
|
||||||
|
/* Coex Override preserved windows size 1 based */
|
||||||
|
uint16_t rx_ba_win_size_override;
|
||||||
|
|
||||||
#ifdef WLAN_PEER_JITTER
|
#ifdef WLAN_PEER_JITTER
|
||||||
/* Tx Jitter stats */
|
/* Tx Jitter stats */
|
||||||
uint32_t tx_avg_jitter;
|
uint32_t tx_avg_jitter;
|
||||||
|
Reference in New Issue
Block a user