Merge "qca-wifi: CFR: Change format-specifiers while printing CFR metadata"
diff --git a/configs/wlan_cfg/ap_wlan_cfg.config b/configs/wlan_cfg/ap_wlan_cfg.config
index 525791c..dd0ffb8 100644
--- a/configs/wlan_cfg/ap_wlan_cfg.config
+++ b/configs/wlan_cfg/ap_wlan_cfg.config
@@ -34,3 +34,6 @@
EXTRA_CFLAGS += -DRX_DATA_BUFFER_SIZE=1792
EXTRA_CFLAGS += -DRX_DATA_BUFFER_ALIGNMENT=0
endif
+
+EXTRA_CFLAGS += -DWLAN_PSOC_MAX_VDEVS=60
+EXTRA_CFLAGS += -DWLAN_PDEV_MAX_VDEVS=30
diff --git a/dp/wifi3.0/dp_rx_mon_feature.c b/dp/wifi3.0/dp_rx_mon_feature.c
index 121714e..4a4c66b 100644
--- a/dp/wifi3.0/dp_rx_mon_feature.c
+++ b/dp/wifi3.0/dp_rx_mon_feature.c
@@ -684,9 +684,19 @@
return dp_mon_filter_update(pdev);
}
-void
-dp_peer_set_rx_capture_enabled(struct dp_peer *peer, bool value)
+QDF_STATUS
+dp_peer_set_rx_capture_enabled(struct dp_pdev *pdev, struct dp_peer *peer,
+ bool value, uint8_t *mac_addr)
{
+ if (!peer) {
+ dp_err("Invalid Peer");
+ if (value)
+ return QDF_STATUS_E_FAILURE;
+ return QDF_STATUS_SUCCESS;
+ }
+
peer->rx_cap_enabled = value;
+
+ return QDF_STATUS_SUCCESS;
}
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
diff --git a/dp/wifi3.0/dp_rx_mon_feature.h b/dp/wifi3.0/dp_rx_mon_feature.h
index f21135a..41b2296 100644
--- a/dp/wifi3.0/dp_rx_mon_feature.h
+++ b/dp/wifi3.0/dp_rx_mon_feature.h
@@ -76,12 +76,15 @@
/**
* dp_peer_set_rx_capture_enabled: Set rx_cap_enabled bit in peer
+ * @pdev: DP_PDEV handle
* @peer_handle: Peer handle
* @value: Enable/disable setting for rx_cap_enabled
+ * @mac_addr: peer mac address
*
- * Return: None
+ * Return: status
*/
-void
-dp_peer_set_rx_capture_enabled(struct dp_peer *peer, bool value);
+QDF_STATUS dp_peer_set_rx_capture_enabled(struct dp_pdev *pdev,
+ struct dp_peer *peer_handle,
+ bool value, uint8_t *mac_addr);
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
#endif /* _DP_RX_MON_FEATURE_H_ */
diff --git a/dp/wifi3.0/dp_rx_tag.c b/dp/wifi3.0/dp_rx_tag.c
index 0b3f600..9eb5e0a 100644
--- a/dp/wifi3.0/dp_rx_tag.c
+++ b/dp/wifi3.0/dp_rx_tag.c
@@ -284,7 +284,7 @@
if (qdf_likely(1 != dp_pdev->ppdu_info.rx_status.rxpcu_filter_pass))
return;
- msdu_ppdu_id = hal_rx_hw_desc_get_ppduid_get(soc->hal_soc, rx_desc);
+ msdu_ppdu_id = hal_rx_get_ppdu_id(soc->hal_soc, rx_desc);
if (msdu_ppdu_id != dp_pdev->ppdu_info.com_info.ppdu_id) {
QDF_TRACE(QDF_MODULE_ID_DP,
diff --git a/dp/wifi3.0/dp_tx_capture.c b/dp/wifi3.0/dp_tx_capture.c
index 8d2ac96..e54de49 100644
--- a/dp/wifi3.0/dp_tx_capture.c
+++ b/dp/wifi3.0/dp_tx_capture.c
@@ -34,7 +34,8 @@
#define MAX_MONITOR_HEADER (512)
#define MAX_DUMMY_FRM_BODY (128)
#define DP_BA_ACK_FRAME_SIZE (sizeof(struct ieee80211_ctlframe_addr2) + 36)
-#define DP_ACK_FRAME_SIZE (struct ieee80211_frame_min_one)
+#define DP_ACK_FRAME_SIZE (sizeof(struct ieee80211_frame_min_one))
+#define DP_CTS_FRAME_SIZE (sizeof(struct ieee80211_frame_min_one))
#define DP_MAX_MPDU_64 64
#define DP_NUM_WORDS_PER_PPDU_BITMAP_64 (DP_MAX_MPDU_64 >> 5)
#define DP_NUM_BYTES_PER_PPDU_BITMAP_64 (DP_MAX_MPDU_64 >> 3)
@@ -154,20 +155,27 @@
* based on global per-pdev setting or per-peer setting
* @pdev: Datapath pdev handle
* @peer: Datapath peer
+ * @mac_addr: peer mac address
*
* Return: true if feature is enabled on a per-pdev basis or if
* enabled for the given peer when per-peer mode is set, false otherwise
*/
inline bool
dp_peer_or_pdev_tx_cap_enabled(struct dp_pdev *pdev,
- struct dp_peer *peer)
+ struct dp_peer *peer, uint8_t *mac_addr)
{
if ((pdev->tx_capture_enabled ==
CDP_TX_ENH_CAPTURE_ENABLE_ALL_PEERS) ||
- ((pdev->tx_capture_enabled ==
- CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER) &&
- peer->tx_cap_enabled))
- return true;
+ (pdev->tx_capture_enabled ==
+ CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER)) {
+ if (peer && peer->tx_cap_enabled)
+ return true;
+
+ /* do search based on mac address */
+ return is_dp_peer_mgmt_pkt_filter(pdev,
+ HTT_INVALID_PEER,
+ mac_addr);
+ }
return false;
}
@@ -304,6 +312,11 @@
return;
}
+ if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL, wh->i_addr1)) {
+ qdf_nbuf_free(nbuf);
+ return;
+ }
+
qdf_spin_lock_bh(
&pdev->tx_capture.ctl_mgmt_lock[type][subtype]);
qdf_nbuf_queue_add(&pdev->tx_capture.ctl_mgmt_q[type][subtype],
@@ -317,6 +330,208 @@
}
}
+static inline int dp_peer_compare_mac_addr(void *addr1, void *addr2)
+{
+ union dp_align_mac_addr *mac_addr1 = (union dp_align_mac_addr *)addr1;
+ union dp_align_mac_addr *mac_addr2 = (union dp_align_mac_addr *)addr2;
+
+ return !((mac_addr1->align4.bytes_abcd == mac_addr2->align4.bytes_abcd)
+ & (mac_addr1->align4.bytes_ef == mac_addr2->align4.bytes_ef));
+}
+
+/*
+ * dp_peer_tx_cap_search: filter mgmt pkt based on peer and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on matched and false on not found
+ */
+static
+bool dp_peer_tx_cap_search(struct dp_pdev *pdev,
+ uint16_t peer_id, uint8_t *mac_addr)
+{
+ struct dp_pdev_tx_capture *tx_capture;
+ struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+ uint8_t i = 0;
+ bool found = false;
+
+ tx_capture = &pdev->tx_capture;
+
+ /* search based on mac address */
+ for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+ uint8_t *peer_mac_addr;
+
+ ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+ if (ptr_peer_mgmt_list->avail)
+ continue;
+ peer_mac_addr = ptr_peer_mgmt_list->mac_addr;
+ if (!dp_peer_compare_mac_addr(mac_addr,
+ peer_mac_addr)) {
+ found = true;
+ break;
+ }
+ }
+ return found;
+}
+
+/*
+ * dp_peer_tx_cap_add_filter: add peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_peer_tx_cap_add_filter(struct dp_pdev *pdev,
+ uint16_t peer_id, uint8_t *mac_addr)
+{
+ struct dp_pdev_tx_capture *tx_capture;
+ struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+ uint8_t i = 0;
+ bool status = false;
+
+ tx_capture = &pdev->tx_capture;
+
+ if (dp_peer_tx_cap_search(pdev, peer_id, mac_addr)) {
+ /* mac address and peer_id already there */
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "%s: %d peer_id[%d] mac_addr[%pM] already there\n",
+ __func__, __LINE__, peer_id, mac_addr);
+ return status;
+ }
+
+ for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+ ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+ if (!ptr_peer_mgmt_list->avail)
+ continue;
+ qdf_mem_copy(ptr_peer_mgmt_list->mac_addr,
+ mac_addr, QDF_MAC_ADDR_SIZE);
+ ptr_peer_mgmt_list->avail = false;
+ ptr_peer_mgmt_list->peer_id = peer_id;
+ status = true;
+ break;
+ }
+
+ return status;
+}
+
+/*
+ * dp_peer_tx_cap_del_all_filter: delete all peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: void
+ */
+void dp_peer_tx_cap_del_all_filter(struct dp_pdev *pdev)
+{
+ struct dp_pdev_tx_capture *tx_capture;
+ struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+ uint8_t i = 0;
+
+ tx_capture = &pdev->tx_capture;
+
+ for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+ ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+ ptr_peer_mgmt_list->avail = true;
+ ptr_peer_mgmt_list->peer_id = HTT_INVALID_PEER;
+ qdf_mem_zero(ptr_peer_mgmt_list->mac_addr, QDF_MAC_ADDR_SIZE);
+ }
+}
+
+/*
+ * dp_peer_tx_cap_del_filter: delete peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_peer_tx_cap_del_filter(struct dp_pdev *pdev,
+ uint16_t peer_id, uint8_t *mac_addr)
+{
+ struct dp_pdev_tx_capture *tx_capture;
+ struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+ uint8_t i = 0;
+ bool status = false;
+
+ tx_capture = &pdev->tx_capture;
+
+ for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+ ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+ if (!dp_peer_compare_mac_addr(mac_addr,
+ ptr_peer_mgmt_list->mac_addr) &&
+ (!ptr_peer_mgmt_list->avail)) {
+ ptr_peer_mgmt_list->avail = true;
+ ptr_peer_mgmt_list->peer_id = HTT_INVALID_PEER;
+ qdf_mem_zero(ptr_peer_mgmt_list->mac_addr,
+ QDF_MAC_ADDR_SIZE);
+ status = true;
+ break;
+ }
+ }
+
+ if (!status)
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "unable to delete peer[%d] mac[%pM] filter list",
+ peer_id, mac_addr);
+ return status;
+}
+
+/*
+ * dp_peer_tx_cap_print_mgmt_filter: pradd peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+void dp_peer_tx_cap_print_mgmt_filter(struct dp_pdev *pdev,
+ uint16_t peer_id, uint8_t *mac_addr)
+{
+ struct dp_pdev_tx_capture *tx_capture;
+ struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+ uint8_t i = 0;
+
+ tx_capture = &pdev->tx_capture;
+
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "peer filter list:");
+ for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+ ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "peer_id[%d] mac_addr[%pM] avail[%d]",
+ ptr_peer_mgmt_list->peer_id,
+ ptr_peer_mgmt_list->mac_addr,
+ ptr_peer_mgmt_list->avail);
+ }
+}
+
+/*
+ * dp_peer_mgmt_pkt_filter: filter mgmt pkt based on peer and mac address
+ * @pdev: DP PDEV handle
+ * @nbuf: buffer containing the ppdu_desc
+ *
+ * return: status
+ */
+bool is_dp_peer_mgmt_pkt_filter(struct dp_pdev *pdev,
+ uint32_t peer_id, uint8_t *mac_addr)
+{
+ bool found = false;
+
+ found = dp_peer_tx_cap_search(pdev, peer_id, mac_addr);
+ QDF_TRACE(QDF_MODULE_ID_TX_CAPTURE, QDF_TRACE_LEVEL_INFO_LOW,
+ "%s: %d peer_id[%d] mac_addr[%pM] found[%d]!",
+ __func__, __LINE__, peer_id, mac_addr, found);
+
+ return found;
+}
+
/**
* dp_tx_ppdu_stats_attach - Initialize Tx PPDU stats and enhanced capture
* @pdev: DP PDEV
@@ -325,7 +540,11 @@
*/
void dp_tx_ppdu_stats_attach(struct dp_pdev *pdev)
{
+ struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
+ struct dp_pdev_tx_capture *tx_capture;
int i, j;
+
+ tx_capture = &pdev->tx_capture;
/* Work queue setup for HTT stats and tx capture handling */
qdf_create_work(0, &pdev->tx_capture.ppdu_stats_work,
dp_tx_ppdu_stats_process,
@@ -349,6 +568,14 @@
}
qdf_mem_zero(&pdev->tx_capture.dummy_ppdu_desc,
sizeof(struct cdp_tx_completion_ppdu));
+
+ pdev->tx_capture.ptr_peer_mgmt_list = (struct dp_peer_mgmt_list *)
+ qdf_mem_malloc(sizeof(struct dp_peer_mgmt_list) *
+ MAX_MGMT_PEER_FILTER);
+ for (i = 0; i < MAX_MGMT_PEER_FILTER; i++) {
+ ptr_peer_mgmt_list = &tx_capture->ptr_peer_mgmt_list[i];
+ ptr_peer_mgmt_list->avail = true;
+ }
}
/**
@@ -399,6 +626,8 @@
&pdev->tx_capture.ctl_mgmt_lock[i][j]);
}
}
+
+ qdf_mem_free(pdev->tx_capture.ptr_peer_mgmt_list);
}
/**
@@ -498,14 +727,15 @@
struct dp_peer *peer)
{
int ret = QDF_STATUS_E_FAILURE;
+ struct dp_pdev *pdev = desc->pdev;
- if (peer && dp_peer_or_pdev_tx_cap_enabled(desc->pdev, peer) &&
+ if (peer &&
+ dp_peer_or_pdev_tx_cap_enabled(pdev, peer, peer->mac_addr.raw) &&
((ts->status == HAL_TX_TQM_RR_FRAME_ACKED) ||
(ts->status == HAL_TX_TQM_RR_REM_CMD_TX) ||
- ((ts->status == HAL_TX_TQM_RR_REM_CMD_AGED) && ts->transmit_cnt))) {
- ret = dp_update_msdu_to_list(soc, desc->pdev,
- peer, ts, desc->nbuf);
- }
+ ((ts->status == HAL_TX_TQM_RR_REM_CMD_AGED) && ts->transmit_cnt)))
+ ret = dp_update_msdu_to_list(soc, pdev, peer, ts, desc->nbuf);
+
return ret;
}
@@ -666,6 +896,8 @@
int tid;
struct dp_tx_tid *tx_tid;
+ /* set peer tx cap enabled to 0, when feature disable */
+ peer->tx_cap_enabled = 0;
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
qdf_nbuf_t ppdu_nbuf = NULL;
struct cdp_tx_completion_ppdu *ppdu_desc =
@@ -742,6 +974,7 @@
&pdev->tx_capture.ctl_mgmt_lock[i][j]);
}
}
+ dp_peer_tx_cap_del_all_filter(pdev);
}
qdf_spin_unlock(&pdev->tx_capture.config_lock);
@@ -1411,6 +1644,7 @@
void *desc)
{
struct dp_peer *peer;
+ struct dp_vdev *vdev = NULL;
struct cdp_tx_completion_ppdu *ppdu_desc = desc;
struct cdp_tx_completion_ppdu_user *user = &ppdu_desc->user[0];
struct ieee80211_ctlframe_addr2 *wh_min;
@@ -1497,15 +1731,17 @@
else {
peer = dp_peer_find_by_id(pdev->soc, user->peer_id);
if (peer) {
- struct dp_vdev *vdev = NULL;
-
vdev = peer->vdev;
- if (vdev)
- qdf_mem_copy(wh_min->i_addr2,
- vdev->mac_addr.raw,
- QDF_MAC_ADDR_SIZE);
dp_peer_unref_del_find_by_id(peer);
+ } else {
+ vdev =
+ dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
+ ppdu_desc->vdev_id);
}
+ if (vdev)
+ qdf_mem_copy(wh_min->i_addr2,
+ vdev->mac_addr.raw,
+ QDF_MAC_ADDR_SIZE);
qdf_nbuf_set_pktlen(tx_capture_info.mpdu_nbuf, sizeof(*wh_min));
}
@@ -1544,6 +1780,7 @@
struct dp_pdev_tx_capture *ptr_tx_cap;
struct dp_peer *peer;
uint8_t rts_send;
+ struct dp_vdev *vdev = NULL;
rts_send = 0;
ptr_tx_cap = &pdev->tx_capture;
@@ -1595,16 +1832,20 @@
peer = dp_peer_find_by_id(pdev->soc,
cur_ppdu_desc->user[0].peer_id);
if (peer) {
- struct dp_vdev *vdev = NULL;
-
vdev = peer->vdev;
- if (vdev)
- qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
- vdev->mac_addr.raw,
- QDF_MAC_ADDR_SIZE);
dp_peer_unref_del_find_by_id(peer);
+ } else {
+ uint8_t vdev_id;
+
+ vdev_id = ppdu_desc->vdev_id;
+ vdev = dp_get_vdev_from_soc_vdev_id_wifi3(pdev->soc,
+ vdev_id);
}
+ if (vdev)
+ qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
+ vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE);
+
dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc);
}
}
@@ -1730,7 +1971,9 @@
qdf_nbuf_free(tx_capture_info.mpdu_nbuf);
}
- if (ppdu_desc->resp_type == HTT_PPDU_STATS_ACK_EXPECTED_E)
+ if (ppdu_desc->resp_type == HTT_PPDU_STATS_ACK_EXPECTED_E &&
+ ppdu_desc->user[0].completion_status ==
+ HTT_PPDU_STATS_USER_STATUS_OK)
dp_gen_ack_rx_frame(pdev, &tx_capture_info);
}
@@ -2198,6 +2441,12 @@
subtype = 0;
}
+ if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL,
+ ppdu_desc->user[0].mac_addr)) {
+ qdf_nbuf_free(nbuf_ppdu_desc);
+ status = 0;
+ goto free_ppdu_desc;
+ }
switch (ppdu_desc->htt_frame_type) {
case HTT_STATS_FTYPE_TIDQ_DATA_SU:
case HTT_STATS_FTYPE_TIDQ_DATA_MU:
@@ -2275,7 +2524,7 @@
HTT_PPDU_STATS_USER_STATUS_FILTERED) {
qdf_nbuf_free(nbuf_ppdu_desc);
status = 0;
- goto free_ppdu_desc;
+ goto insert_mgmt_buf_to_queue;
}
/*
@@ -2284,6 +2533,7 @@
qdf_nbuf_queue_add(retries_q, nbuf_ppdu_desc);
status = 0;
+insert_mgmt_buf_to_queue:
/*
* insert the mgmt_ctl buffer back to
* the queue
@@ -2874,6 +3124,7 @@
uint16_t tid = 0;
uint32_t num_msdu = 0;
uint32_t qlen = 0;
+ uint16_t peer_id;
qdf_nbuf_queue_init(&head_msdu);
qdf_nbuf_queue_init(&head_xretries);
@@ -2937,19 +3188,19 @@
continue;
}
- peer = dp_peer_find_by_id(pdev->soc,
- ppdu_desc->user[0].peer_id);
- /**
- * peer can be NULL
- */
- if (!peer) {
- qdf_nbuf_free(nbuf);
- continue;
- }
-
if ((ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA) ||
(ppdu_desc->num_mpdu &&
ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR)) {
+ peer_id = ppdu_desc->user[0].peer_id;
+ peer = dp_peer_find_by_id(pdev->soc, peer_id);
+ /**
+ * peer can be NULL
+ */
+ if (!peer) {
+ qdf_nbuf_free(nbuf);
+ continue;
+ }
+
/**
* check whether it is bss peer,
* if bss_peer no need to process further
@@ -2958,7 +3209,7 @@
*/
if (peer->bss_peer ||
!dp_peer_or_pdev_tx_cap_enabled(pdev,
- peer)) {
+ peer, peer->mac_addr.raw)) {
dp_peer_unref_del_find_by_id(peer);
qdf_nbuf_free(nbuf);
continue;
@@ -3065,6 +3316,8 @@
ppdu_desc->user[0].start_seq,
ppdu_cnt,
ppdu_desc_cnt);
+
+ dp_peer_unref_del_find_by_id(peer);
} else {
/*
* other packet frame also added to
@@ -3073,7 +3326,6 @@
nbuf_ppdu_desc_list[ppdu_desc_cnt++] = nbuf;
}
- dp_peer_unref_del_find_by_id(peer);
}
/*
@@ -3263,6 +3515,107 @@
(frm - (uint8_t *)qdf_nbuf_data(mpdu_nbuf)));
}
+static void dp_gen_cts_frame(struct hal_rx_ppdu_info *ppdu_info,
+ struct dp_peer *peer,
+ qdf_nbuf_t mpdu_nbuf)
+{
+ struct ieee80211_frame_min_one *wh_addr1;
+ uint16_t duration;
+
+ wh_addr1 = (struct ieee80211_frame_min_one *)
+ qdf_nbuf_data(mpdu_nbuf);
+
+ wh_addr1->i_fc[0] = 0;
+ wh_addr1->i_fc[1] = 0;
+ wh_addr1->i_fc[0] = IEEE80211_FC0_VERSION_0 |
+ IEEE80211_FC0_TYPE_CTL |
+ IEEE80211_FC0_SUBTYPE_CTS;
+ qdf_mem_copy(wh_addr1->i_addr1, &peer->mac_addr.raw[0],
+ QDF_MAC_ADDR_SIZE);
+ duration = (ppdu_info->rx_status.duration > SIFS_INTERVAL) ?
+ ppdu_info->rx_status.duration - SIFS_INTERVAL : 0;
+ wh_addr1->i_dur[0] = duration & 0xff;
+ wh_addr1->i_dur[1] = (duration >> 8) & 0xff;
+ qdf_nbuf_set_pktlen(mpdu_nbuf, sizeof(*wh_addr1));
+}
+
+/**
+ * dp_send_cts_frame_to_stack(): Function to deliver HW generated CTS frame
+ * in reponse to RTS
+ * @soc: core txrx main context
+ * @pdev: DP pdev object
+ * @ppdu_info: HAL RX PPDU info retrieved from status ring TLV
+ *
+ * return: status
+ */
+QDF_STATUS dp_send_cts_frame_to_stack(struct dp_soc *soc,
+ struct dp_pdev *pdev,
+ struct hal_rx_ppdu_info *ppdu_info)
+{
+ struct cdp_tx_indication_info tx_capture_info;
+ struct mon_rx_user_status *rx_user_status =
+ &ppdu_info->rx_user_status[0];
+ struct dp_ast_entry *ast_entry;
+ uint32_t peer_id;
+ struct dp_peer *peer;
+
+ if (rx_user_status->ast_index >=
+ wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) {
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ qdf_spin_lock_bh(&soc->ast_lock);
+ ast_entry = soc->ast_table[rx_user_status->ast_index];
+ if (!ast_entry) {
+ qdf_spin_unlock_bh(&soc->ast_lock);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ peer = ast_entry->peer;
+ if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) {
+ qdf_spin_unlock_bh(&soc->ast_lock);
+ return QDF_STATUS_E_FAILURE;
+ }
+ peer_id = peer->peer_ids[0];
+ qdf_spin_unlock_bh(&soc->ast_lock);
+
+ peer = dp_peer_find_by_id(soc, peer_id);
+ if (!peer)
+ return QDF_STATUS_E_FAILURE;
+
+ if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL, peer->mac_addr.raw)) {
+ dp_peer_unref_del_find_by_id(peer);
+ return QDF_STATUS_E_FAILURE;
+ }
+
+ set_mpdu_info(&tx_capture_info,
+ &ppdu_info->rx_status, rx_user_status);
+ tx_capture_info.mpdu_info.mcs = rx_user_status->mcs;
+ /* ppdu_desc is not required for legacy frames */
+ tx_capture_info.ppdu_desc = NULL;
+
+ tx_capture_info.mpdu_nbuf =
+ qdf_nbuf_alloc(pdev->soc->osdev,
+ MAX_MONITOR_HEADER +
+ DP_CTS_FRAME_SIZE,
+ MAX_MONITOR_HEADER,
+ 4, FALSE);
+
+ if (!tx_capture_info.mpdu_nbuf) {
+ dp_peer_unref_del_find_by_id(peer);
+ return QDF_STATUS_E_NOMEM;
+ }
+
+ dp_gen_cts_frame(ppdu_info, peer,
+ tx_capture_info.mpdu_nbuf);
+ dp_peer_unref_del_find_by_id(peer);
+ dp_wdi_event_handler(WDI_EVENT_TX_DATA, pdev->soc,
+ &tx_capture_info, HTT_INVALID_PEER,
+ WDI_NO_VAL, pdev->pdev_id);
+
+ return QDF_STATUS_SUCCESS;
+}
+
/**
* dp_send_ack_frame_to_stack(): Function to generate BA or ACK frame and
* send to upper layer on received unicast frame
@@ -3286,6 +3639,7 @@
uint32_t ast_index;
uint32_t i;
bool bar_frame;
+ uint8_t *ptr_mac_addr;
rx_status = &ppdu_info->rx_status;
@@ -3301,6 +3655,10 @@
return QDF_STATUS_SUCCESS;
}
+ if (ppdu_info->sw_frame_group_id ==
+ HAL_MPDU_SW_FRAME_GROUP_CTRL_RTS)
+ return dp_send_cts_frame_to_stack(soc, pdev, ppdu_info);
+
if (ppdu_info->sw_frame_group_id == HAL_MPDU_SW_FRAME_GROUP_CTRL_BAR)
bar_frame = true;
else
@@ -3324,6 +3682,10 @@
ast_index = rx_user_status->ast_index;
if (ast_index >=
wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) {
+ ptr_mac_addr = &ppdu_info->nac_info.mac_addr2[0];
+ if (!dp_peer_or_pdev_tx_cap_enabled(pdev,
+ NULL, ptr_mac_addr))
+ continue;
set_mpdu_info(&tx_capture_info,
rx_status, rx_user_status);
tx_capture_info.mpdu_nbuf =
@@ -3362,7 +3724,8 @@
continue;
if (!dp_peer_or_pdev_tx_cap_enabled(pdev,
- peer)) {
+ NULL,
+ peer->mac_addr.raw)) {
dp_peer_unref_del_find_by_id(peer);
continue;
}
@@ -3406,16 +3769,56 @@
/**
* dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
+ * @pdev: DP PDEV handle
* @peer: Peer handle
* @value: Enable/disable setting for tx_cap_enabled
+ * @peer_mac: peer mac address
*
- * Return: None
+ * Return: QDF_STATUS
*/
-void
-dp_peer_set_tx_capture_enabled(struct dp_peer *peer, bool value)
+QDF_STATUS
+dp_peer_set_tx_capture_enabled(struct dp_pdev *pdev,
+ struct dp_peer *peer, uint8_t value,
+ uint8_t *peer_mac)
{
- peer->tx_cap_enabled = value;
- if (!value)
- dp_peer_tx_cap_tid_queue_flush(peer);
+ uint32_t peer_id = HTT_INVALID_PEER;
+ QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+ if (value) {
+ if (dp_peer_tx_cap_add_filter(pdev, peer_id, peer_mac)) {
+ if (peer)
+ peer->tx_cap_enabled = value;
+ status = QDF_STATUS_SUCCESS;
+ }
+ } else {
+ if (dp_peer_tx_cap_del_filter(pdev, peer_id, peer_mac)) {
+ if (peer)
+ peer->tx_cap_enabled = value;
+ status = QDF_STATUS_SUCCESS;
+ }
+ }
+
+ return status;
+}
+
+/*
+ * dp_peer_tx_capture_filter_check: check filter is enable for the filter
+ * and update tx_cap_enabled flag
+ * @pdev: DP PDEV handle
+ * @peer: DP PEER handle
+ *
+ * return: void
+ */
+void dp_peer_tx_capture_filter_check(struct dp_pdev *pdev,
+ struct dp_peer *peer)
+{
+ if (!peer)
+ return;
+
+ if (dp_peer_tx_cap_search(pdev, peer->peer_ids[0],
+ peer->mac_addr.raw)) {
+ peer->tx_cap_enabled = 1;
+ }
+ return;
}
#endif
diff --git a/dp/wifi3.0/dp_tx_capture.h b/dp/wifi3.0/dp_tx_capture.h
index 6f85eaf..016675c 100644
--- a/dp/wifi3.0/dp_tx_capture.h
+++ b/dp/wifi3.0/dp_tx_capture.h
@@ -35,6 +35,16 @@
#define TXCAP_MAX_SUBTYPE \
((IEEE80211_FC0_SUBTYPE_MASK >> IEEE80211_FC0_SUBTYPE_SHIFT) + 1)
+#define SIFS_INTERVAL 16
+
+#define MAX_MGMT_PEER_FILTER 16
+struct dp_peer_mgmt_list {
+ uint8_t mac_addr[QDF_MAC_ADDR_SIZE];
+ uint32_t mgmt_pkt_counter;
+ uint16_t peer_id;
+ bool avail;
+};
+
struct dp_pdev_tx_capture {
/* For deferred PPDU status processing */
qdf_spinlock_t ppdu_stats_lock;
@@ -60,6 +70,7 @@
qdf_spinlock_t config_lock;
uint32_t htt_frame_type[TX_CAP_HTT_MAX_FTYPE];
struct cdp_tx_completion_ppdu dummy_ppdu_desc;
+ struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
};
/* Tx TID */
@@ -261,12 +272,73 @@
/**
* dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
+ * @pdev: DP PDEV handle
* @peer: Peer handle
* @value: Enable/disable setting for tx_cap_enabled
+ * @peer_mac: peer_mac Enable/disable setting for tx_cap_enabled
*
- * Return: None
+ * Return: QDF_STATUS
*/
-void
-dp_peer_set_tx_capture_enabled(struct dp_peer *peer, bool value);
+QDF_STATUS
+dp_peer_set_tx_capture_enabled(struct dp_pdev *pdev,
+ struct dp_peer *peer, uint8_t value,
+ uint8_t *peer_mac);
+
+/*
+ * dp_peer_tx_cap_add_filter: add peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_pdev_tx_cap_add_filter(struct dp_pdev *pdev,
+ uint16_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_tx_cap_del_filter: delete peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+bool dp_peer_tx_cap_del_filter(struct dp_pdev *pdev,
+ uint16_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_tx_cap_print_mgmt_filter: pradd peer filter mgmt pkt based on peer
+ * and mac address
+ * @pdev: DP PDEV handle
+ * @peer_id: DP PEER ID
+ * @mac_addr: pointer to mac address
+ *
+ * return: true on added and false on not failed
+ */
+void dp_peer_tx_cap_print_mgmt_filter(struct dp_pdev *pdev,
+ uint16_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_mgmt_pkt_filter: filter mgmt pkt based on peer and mac address
+ * @pdev: DP PDEV handle
+ * @nbuf: buffer containing the ppdu_desc
+ *
+ * return: status
+ */
+bool is_dp_peer_mgmt_pkt_filter(struct dp_pdev *pdev,
+ uint32_t peer_id, uint8_t *mac_addr);
+
+/*
+ * dp_peer_tx_capture_filter_check: check filter is enable for the filter
+ * and update tx_cap_enabled flag
+ * @pdev: DP PDEV handle
+ * @peer: DP PEER handle
+ *
+ * return: void
+ */
+void dp_peer_tx_capture_filter_check(struct dp_pdev *pdev,
+ struct dp_peer *peer);
#endif
#endif
diff --git a/target_if/cfr/inc/target_if_cfr_6018.h b/target_if/cfr/inc/target_if_cfr_6018.h
index 5acbefd..510ad1d 100644
--- a/target_if/cfr/inc/target_if_cfr_6018.h
+++ b/target_if/cfr/inc/target_if_cfr_6018.h
@@ -59,8 +59,8 @@
#define CYP_MAX_HEADER_LENGTH_WORDS 16
-/* Max(2048, 16016, 10240) */
-#define CYP_MAX_DATA_LENGTH_BYTES 16016
+/* payload_len = Max(2048, 16016, 10240) = 16064 (64-bit alignment) */
+#define CYP_MAX_DATA_LENGTH_BYTES 16064
/* in ms */
#define LUT_AGE_TIMER 3000
diff --git a/target_if/cfr/src/target_if_cfr_6018.c b/target_if/cfr/src/target_if_cfr_6018.c
index 8568749..afea3aa 100644
--- a/target_if/cfr/src/target_if_cfr_6018.c
+++ b/target_if/cfr/src/target_if_cfr_6018.c
@@ -171,60 +171,6 @@
}
/**
- * cfr_free_all_lut_entries() - Flush all pending DBR and TXRX events.
- * @pdev: objmgr pdev
- *
- * return: none
- */
-void cfr_free_all_lut_entries(struct wlan_objmgr_pdev *pdev)
-{
- struct pdev_cfr *pcfr;
- struct look_up_table *lut = NULL;
- int i = 0;
- QDF_STATUS retval = 0;
- qdf_dma_addr_t buf_addr = 0, buf_addr_temp = 0;
-
- retval = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
- if (retval != QDF_STATUS_SUCCESS) {
- cfr_err("failed to get pdev reference");
- return;
- }
-
- pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
- WLAN_UMAC_COMP_CFR);
- if (!pcfr) {
- cfr_err("pdev object for CFR is null");
- wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
- return;
- }
-
- for (i = 0; i < NUM_LUT_ENTRIES; i++) {
- lut = get_lut_entry(pcfr, i);
- if (!lut)
- continue;
-
- if (lut->dbr_recv && !lut->tx_recv) {
- target_if_dbr_buf_release(pdev, DBR_MODULE_CFR,
- lut->dbr_address,
- i, 0);
- pcfr->flush_all_dbr_cnt++;
- release_lut_entry_enh(pdev, lut);
- } else if (lut->tx_recv && !lut->dbr_recv) {
- buf_addr_temp = (lut->tx_address2 & 0x0f);
- buf_addr = (lut->tx_address1
- | ((uint64_t)buf_addr_temp << 32));
- target_if_dbr_buf_release(pdev,
- DBR_MODULE_CFR,
- buf_addr,
- i, 0);
- pcfr->flush_all_txrx_cnt++;
- release_lut_entry_enh(pdev, lut);
- }
- }
- wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
-}
-
-/**
* dump_freeze_tlv() - Dump freeze TLV sent in enhanced DMA header
* @freeze_tlv: Freeze TLV sent from MAC to PHY
* @cookie: Index into lookup table
@@ -544,6 +490,8 @@
WLAN_UMAC_COMP_CFR);
if (module_id == CORRELATE_TXRX_EV_MODULE_ID) {
+ if (lut->tx_recv)
+ pcfr->cfr_dma_aborts++;
lut->tx_recv = true;
} else if (module_id == CORRELATE_DBR_MODULE_ID) {
pcfr->dbr_evt_cnt++;
@@ -584,8 +532,13 @@
pcfr->invalid_dma_length_cnt++;
cfr_err("<CORRELATE><%u>:CFR buffers "
"received with invalid length "
- "length : ppdu_id:0x%04x\n",
- cookie, lut->tx_ppdu_id);
+ "header_length_words = %d "
+ "cfr_payload_length_bytes = %d "
+ "ppdu_id:0x%04x\n",
+ cookie,
+ lut->header_length,
+ lut->payload_length,
+ lut->tx_ppdu_id);
/*
* Assert here as length exceeding the allowed
* limit would anyway manifest as random crash
@@ -606,6 +559,7 @@
lut->tx_recv = false;
lut->tx_ppdu_id = 0;
pcfr->clear_txrx_event++;
+ pcfr->cfr_dma_aborts++;
status = STATUS_HOLD;
}
} else {
@@ -739,7 +693,7 @@
vdev = wlan_objmgr_pdev_get_first_vdev(pdev, WLAN_CFR_ID);
if (qdf_unlikely(!vdev)) {
- cfr_err("vdev is null\n");
+ cfr_debug("vdev is null\n");
goto done;
}
@@ -1253,6 +1207,7 @@
}
pcfr->tx_evt_cnt++;
+ pcfr->total_tx_evt_cnt++;
lut->tx_ppdu_id = (tx_evt_param.correlation_info_2 >> 16);
lut->tx_address1 = tx_evt_param.correlation_info_1;
@@ -1444,7 +1399,7 @@
if (lut->dbr_recv && !lut->tx_recv) {
diff = cur_tstamp - lut->dbr_tstamp;
if (diff > LUT_AGE_THRESHOLD) {
- cfr_err("<%d>TXRX event not received for "
+ cfr_debug("<%d>TXRX event not received for "
"%llu ms, release lut entry : "
"dma_addr = 0x%pK\n", i, diff,
(void *)((uintptr_t)lut->dbr_address));
@@ -1457,6 +1412,8 @@
}
}
+ if (pcfr->lut_timer_init)
+ qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER);
wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
}
@@ -1474,7 +1431,9 @@
pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_CFR);
- qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER);
+ if (pcfr->lut_timer_init)
+ qdf_timer_mod(&pcfr->lut_age_timer, LUT_AGE_TIMER);
+
return QDF_STATUS_SUCCESS;
}
@@ -1492,7 +1451,9 @@
pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_CFR);
- qdf_timer_stop(&pcfr->lut_age_timer);
+ if (pcfr->lut_timer_init)
+ qdf_timer_stop(&pcfr->lut_age_timer);
+
return QDF_STATUS_SUCCESS;
}
@@ -1535,6 +1496,7 @@
return status;
}
+ pcfr->is_cfr_rcc_capable = 1;
pcfr->rcc_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
pcfr->rcc_param.modified_in_curr_session = MAX_RESET_CFG_ENTRY;
pcfr->rcc_param.num_grp_tlvs = MAX_TA_RA_ENTRIES;
@@ -1561,14 +1523,6 @@
pcfr->lut_timer_init = 1;
}
- pcfr->cfr_data_subscriber = (wdi_event_subscribe *)
- qdf_mem_malloc(sizeof(wdi_event_subscribe));
- if (!pcfr->cfr_data_subscriber) {
- cfr_err("Failed to alloc cfr_data_subscriber object\n");
- return QDF_STATUS_E_NULL_VALUE;
- }
-
-
return status;
}
@@ -1593,6 +1547,7 @@
}
if (pcfr->lut_timer_init) {
+ qdf_timer_stop(&pcfr->lut_age_timer);
qdf_timer_free(&(pcfr->lut_age_timer));
pcfr->lut_timer_init = 0;
}
@@ -1600,16 +1555,16 @@
pcfr->tx_evt_cnt = 0;
pcfr->dbr_evt_cnt = 0;
pcfr->release_cnt = 0;
+ pcfr->total_tx_evt_cnt = 0;
pcfr->rx_tlv_evt_cnt = 0;
pcfr->flush_dbr_cnt = 0;
- pcfr->flush_all_dbr_cnt = 0;
- pcfr->flush_all_txrx_cnt = 0;
pcfr->flush_timeout_dbr_cnt = 0;
pcfr->invalid_dma_length_cnt = 0;
pcfr->clear_txrx_event = 0;
pcfr->bb_captured_channel_cnt = 0;
pcfr->bb_captured_timeout_cnt = 0;
pcfr->rx_loc_info_valid_cnt = 0;
+ pcfr->cfr_dma_aborts = 0;
qdf_mem_zero(&pcfr->chan_capture_status,
sizeof(uint64_t) * NUM_CHAN_CAPTURE_STATUS);
qdf_mem_zero(&pcfr->bb_captured_reason_cnt,
@@ -1628,11 +1583,5 @@
if (status != QDF_STATUS_SUCCESS)
cfr_err("Failed to register with dbr");
- if (pcfr->cfr_data_subscriber) {
- qdf_mem_free(pcfr->cfr_data_subscriber);
- pcfr->cfr_data_subscriber = NULL;
- }
-
-
return status;
}
diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h
index f467559..772b366 100644
--- a/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h
+++ b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h
@@ -444,10 +444,26 @@
* pdev_obj: pointer to pdev object
* is_cfr_capable: flag to determine if cfr is enabled or not
* cfr_timer_enable: flag to enable/disable timer
+ * cfr_mem_chunk: Region of memory used for storing cfr data
+ * cfr_max_sta_count: Maximum stations supported in one-shot capture mode
+ * num_subbufs: No. of sub-buffers used in relayfs
+ * subbuf_size: Size of sub-buffer used in relayfs
+ * chan_ptr: Channel in relayfs
+ * dir_ptr: Parent directory of relayfs file
+ * lut: lookup table used to store asynchronous DBR and TX/RX events for
+ * correlation
+ * dbr_buf_size: Size of DBR completion buffer
+ * dbr_num_bufs: No. of DBR completions
+ * tx_evt_cnt: No. of TX completion events till CFR stop was issued
+ * total_tx_evt_cnt: No. of Tx completion events since wifi was up
+ * dbr_evt_cnt: No. of WMI DBR completion events
+ * release_cnt: No. of CFR data buffers relayed to userspace
+ * rcc_param: Structure to store CFR config for the current commit session
+ * global: Structure to store accumulated CFR config
* rx_tlv_evt_cnt: Number of CFR WDI events from datapath
* lut_age_timer: Timer to flush pending TXRX/DBR events in lookup table
* lut_timer_init: flag to determine if lut_age_timer is initialized or not
- * cfr_data_subscriber: CFR WDI subscriber object
+ * is_cfr_rcc_capable: Flag to determine if RCC is enabled or not.
* bb_captured_channel_cnt: No. of PPDUs for which MAC sent Freeze TLV to PHY
* bb_captured_timeout_cnt: No. of PPDUs for which CFR filter criteria matched
* but MAC did not send Freeze TLV to PHY as time exceeded freeze tlv delay
@@ -466,10 +482,17 @@
* [3] - No. PPDUs filtered due to freeze_reason_TA_RA_TYPE_FILTER
* [4] - No. PPDUs filtered due to freeze_reason_NDPA_NDP
* [5] - No. PPDUs filtered due to freeze_reason_ALL_PACKET
- * release_err_cnt: No. of lookup table entries freed due to invalid CFR data
- * length
+ * flush_dbr_cnt: No. of un-correlated DBR completions flushed when a newer PPDU
+ * is correlated successfully with newer DBR completion
+ * invalid_dma_length_cnt: No. of buffers for which CFR DMA header length (or)
+ * data length was invalid
+ * flush_timeout_dbr_cnt: No. of DBR completion flushed out in ageout logic
+ * clear_txrx_event: No. of PPDU status TLVs over-written in LUT
+ * unassoc_pool: Pool of un-associated clients used when capture method is
+ * CFR_CAPTURE_METHOD_PROBE_RESPONSE
* last_success_tstamp: DBR timestamp which indicates that both DBR and TX/RX
* events have been received successfully.
+ * cfr_dma_aborts: No. of CFR DMA aborts in ucode
*/
/*
* To be extended if we get more capbality info
@@ -490,6 +513,7 @@
uint32_t dbr_buf_size;
uint32_t dbr_num_bufs;
uint64_t tx_evt_cnt;
+ uint64_t total_tx_evt_cnt;
uint64_t dbr_evt_cnt;
uint64_t release_cnt;
#ifdef WLAN_ENH_CFR_ENABLE
@@ -498,19 +522,18 @@
uint64_t rx_tlv_evt_cnt;
qdf_timer_t lut_age_timer;
uint8_t lut_timer_init;
- void *cfr_data_subscriber;
+ uint8_t is_cfr_rcc_capable;
uint64_t bb_captured_channel_cnt;
uint64_t bb_captured_timeout_cnt;
uint64_t rx_loc_info_valid_cnt;
uint64_t chan_capture_status[CAPTURE_MAX];
uint64_t bb_captured_reason_cnt[FREEZE_REASON_MAX];
uint64_t flush_dbr_cnt;
- uint64_t flush_all_dbr_cnt;
- uint64_t flush_all_txrx_cnt;
uint64_t invalid_dma_length_cnt;
uint64_t flush_timeout_dbr_cnt;
uint64_t clear_txrx_event;
uint64_t last_success_tstamp;
+ uint64_t cfr_dma_aborts;
#endif
struct unassoc_pool_entry unassoc_pool[MAX_CFR_ENABLED_CLIENTS];
};
diff --git a/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c
index c112b72..66da03a 100644
--- a/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c
+++ b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c
@@ -312,7 +312,7 @@
return QDF_STATUS_E_NULL_VALUE;
}
- if (!(*ppcfr)->is_cfr_capable) {
+ if (!(*ppcfr)->is_cfr_rcc_capable) {
cfr_err("cfr is not supported on this chip\n");
wlan_objmgr_pdev_release_ref(*ppdev, WLAN_CFR_ID);
return QDF_STATUS_E_NOSUPPORT;
@@ -800,33 +800,31 @@
return status;
cfr_err("bb_captured_channel_cnt = %llu\n",
- pcfr->bb_captured_channel_cnt);
+ pcfr->bb_captured_channel_cnt);
cfr_err("bb_captured_timeout_cnt = %llu\n",
- pcfr->bb_captured_timeout_cnt);
+ pcfr->bb_captured_timeout_cnt);
cfr_err("rx_loc_info_valid_cnt = %llu\n",
- pcfr->rx_loc_info_valid_cnt);
- cfr_err("tx_evt_cnt = %llu\n",
- pcfr->tx_evt_cnt);
+ pcfr->rx_loc_info_valid_cnt);
+ cfr_err("total_tx_evt_cnt = %llu\n",
+ pcfr->total_tx_evt_cnt);
cfr_err("dbr_evt_cnt = %llu\n",
- pcfr->dbr_evt_cnt);
+ pcfr->dbr_evt_cnt);
cfr_err("rx_tlv_evt_cnt = %llu\n",
- pcfr->rx_tlv_evt_cnt);
+ pcfr->rx_tlv_evt_cnt);
cfr_err("release_cnt = %llu\n",
- pcfr->release_cnt);
+ pcfr->release_cnt);
cfr_err("Error cnt:\n");
cfr_err("flush_dbr_cnt = %llu\n",
- pcfr->flush_dbr_cnt);
+ pcfr->flush_dbr_cnt);
cfr_err("invalid_dma_length_cnt = %llu\n",
- pcfr->invalid_dma_length_cnt);
- cfr_err("flush_all_dbr_cnt = %llu\n",
- pcfr->flush_all_dbr_cnt);
- cfr_err("flush_all_txrx_cnt = %llu\n",
- pcfr->flush_all_txrx_cnt);
+ pcfr->invalid_dma_length_cnt);
cfr_err("flush_timeout_dbr_cnt = %llu\n",
- pcfr->flush_timeout_dbr_cnt);
+ pcfr->flush_timeout_dbr_cnt);
cfr_err("PPDU id mismatch for same cookie:\n");
cfr_err("clear_txrx_event = %llu\n",
- pcfr->clear_txrx_event);
+ pcfr->clear_txrx_event);
+ cfr_err("cfr_dma_aborts = %llu\n",
+ pcfr->cfr_dma_aborts);
cfr_err("Channel capture status:\n");
for (counter = 0; counter < CAPTURE_MAX; counter++) {
@@ -919,6 +917,7 @@
{
struct pdev_cfr *pcfr = NULL;
struct wlan_objmgr_pdev *pdev = NULL;
+ struct wlan_objmgr_psoc *psoc = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct cdp_monitor_filter filter_val = {0};
@@ -926,6 +925,12 @@
if (status != QDF_STATUS_SUCCESS)
return status;
+ psoc = wlan_pdev_get_psoc(pdev);
+
+ if (!psoc) {
+ cfr_err("psoc is null!");
+ return QDF_STATUS_E_NULL_VALUE;
+ }
/*
* If capture mode is valid, then Host:
* Subscribes for PPDU status TLVs in monitor status ring.
@@ -990,11 +995,15 @@
filter_val.fp_ctrl |= FILTER_CTRL_VHT_NDP;
}
+ if (!cdp_get_cfr_rcc(wlan_psoc_get_dp_handle(psoc),
+ wlan_objmgr_pdev_get_pdev_id(pdev)))
+ tgt_cfr_start_lut_age_timer(pdev);
cfr_set_filter(pdev, 1, &filter_val);
- tgt_cfr_start_lut_age_timer(pdev);
} else {
+ if (cdp_get_cfr_rcc(wlan_psoc_get_dp_handle(psoc),
+ wlan_objmgr_pdev_get_pdev_id(pdev)))
+ tgt_cfr_stop_lut_age_timer(pdev);
cfr_set_filter(pdev, 0, &filter_val);
- tgt_cfr_stop_lut_age_timer(pdev);
}
/* Trigger wmi to start the TLV processing. */
diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h
index 2831f2a..bfea671 100644
--- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h
+++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_ucfg_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, 2020 The Linux Foundation. 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
@@ -398,6 +398,10 @@
UCFG_VDEV_CP_STATS_GET_FUNCS(rx_wrongbss);
UCFG_VDEV_CP_STATS_GET_FUNCS(rx_wrongdir);
UCFG_VDEV_CP_STATS_GET_FUNCS(rx_ssid_mismatch);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_req);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_resp);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_all_req);
+UCFG_VDEV_CP_STATS_GET_FUNCS(peer_delete_all_resp);
#define UCFG_VDEV_UCAST_CP_STATS_SET_FUNCS(field) \
static inline void \
diff --git a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h
index 0722380..002c0b7 100644
--- a/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h
+++ b/umac/cp_stats/dispatcher/inc/wlan_cp_stats_ic_utils_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018, 2020 The Linux Foundation. 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
@@ -276,6 +276,10 @@
VDEV_CP_STATS_GET_FUNCS(rx_wrongbss);
VDEV_CP_STATS_GET_FUNCS(rx_wrongdir);
VDEV_CP_STATS_GET_FUNCS(rx_ssid_mismatch);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_req);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_resp);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_all_req);
+VDEV_CP_STATS_GET_FUNCS(peer_delete_all_resp);
static inline void vdev_cp_stats_reset(struct wlan_objmgr_vdev *vdev)
{
diff --git a/wmi/src/wmi_unified_ap_tlv.c b/wmi/src/wmi_unified_ap_tlv.c
index 9a1397e..cd60c68 100644
--- a/wmi/src/wmi_unified_ap_tlv.c
+++ b/wmi/src/wmi_unified_ap_tlv.c
@@ -2540,14 +2540,15 @@
if (!param_buf->num_vdev_ids_bitmap)
return QDF_STATUS_E_FAILURE;
- if (param_buf->num_vdev_ids_bitmap > sizeof(param->vdev_id_bmap)) {
+ if ((param_buf->num_vdev_ids_bitmap * sizeof(uint32_t)) >
+ sizeof(param->vdev_id_bmap)) {
WMI_LOGE("vdevId bitmap overflow size:%d",
param_buf->num_vdev_ids_bitmap);
return QDF_STATUS_E_FAILURE;
}
qdf_mem_copy(param->vdev_id_bmap, param_buf->vdev_ids_bitmap,
- param_buf->num_vdev_ids_bitmap);
+ param_buf->num_vdev_ids_bitmap * sizeof(uint32_t));
WMI_LOGD("vdev_id_bmap :0x%x%x", param->vdev_id_bmap[1],
param->vdev_id_bmap[0]);
diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c
index 6a1c80d..2bfcbd3 100644
--- a/wmi/src/wmi_unified_non_tlv.c
+++ b/wmi/src/wmi_unified_non_tlv.c
@@ -10690,7 +10690,9 @@
wmi_service[wmi_service_cfr_capture_support] =
WMI_SERVICE_CFR_CAPTURE_SUPPORT;
wmi_service[wmi_service_rx_fse_support] = WMI_SERVICE_UNAVAILABLE;
- wmi_service[wmi_service_bw_165mhz_support] =
+ wmi_service[wmi_service_bw_restricted_80p80_support] =
+ WMI_SERVICE_UNAVAILABLE;
+ wmi_service[wmi_service_nss_ratio_to_host_support] =
WMI_SERVICE_UNAVAILABLE;
}