Merge changes into win_wlan_host.1.0
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/src/target_if_cfr_6018.c b/target_if/cfr/src/target_if_cfr_6018.c
index 06933c9..afea3aa 100644
--- a/target_if/cfr/src/target_if_cfr_6018.c
+++ b/target_if/cfr/src/target_if_cfr_6018.c
@@ -262,8 +262,8 @@
uint8_t *usermac = NULL;
cfr_debug("<METADATA><%u>\n"
- "start_magic_num = %d\n"
- "vendorid = %d\n"
+ "start_magic_num = 0x%x\n"
+ "vendorid = 0x%x\n"
"cfr_metadata_version = %d\n"
"cfr_data_version = %d\n"
"chip_type = %d\n"
@@ -279,7 +279,7 @@
"cfr_capture_type = %d\n"
"sts_count = %d\n"
"num_rx_chain = %d\n"
- "timestamp = %d\n"
+ "timestamp = 0x%x\n"
"length = %d\n"
"is_mu_ppdu = %d\n"
"num_users = %d\n",
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;
}