qca-wifi: Support mgmt packet filter based on mac address
tx capture mgmt packet peer filter are filtered based on RA mac address. Change-Id: Ib5a5b4d6fc8170e711127e3d15b4389330da9f11
This commit is contained in:
@@ -684,9 +684,19 @@ dp_config_enh_rx_capture(struct dp_pdev *pdev, uint32_t val)
|
|||||||
return dp_mon_filter_update(pdev);
|
return dp_mon_filter_update(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
QDF_STATUS
|
||||||
dp_peer_set_rx_capture_enabled(struct dp_peer *peer, bool value)
|
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;
|
peer->rx_cap_enabled = value;
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
|
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
|
||||||
|
@@ -76,12 +76,15 @@ dp_config_enh_rx_capture(struct dp_pdev *pdev, uint8_t val);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_peer_set_rx_capture_enabled: Set rx_cap_enabled bit in peer
|
* dp_peer_set_rx_capture_enabled: Set rx_cap_enabled bit in peer
|
||||||
|
* @pdev: DP_PDEV handle
|
||||||
* @peer_handle: Peer handle
|
* @peer_handle: Peer handle
|
||||||
* @value: Enable/disable setting for rx_cap_enabled
|
* @value: Enable/disable setting for rx_cap_enabled
|
||||||
|
* @mac_addr: peer mac address
|
||||||
*
|
*
|
||||||
* Return: None
|
* Return: status
|
||||||
*/
|
*/
|
||||||
void
|
QDF_STATUS dp_peer_set_rx_capture_enabled(struct dp_pdev *pdev,
|
||||||
dp_peer_set_rx_capture_enabled(struct dp_peer *peer, bool value);
|
struct dp_peer *peer_handle,
|
||||||
|
bool value, uint8_t *mac_addr);
|
||||||
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
|
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
|
||||||
#endif /* _DP_RX_MON_FEATURE_H_ */
|
#endif /* _DP_RX_MON_FEATURE_H_ */
|
||||||
|
@@ -155,20 +155,27 @@ void dp_print_pdev_tx_capture_stats(struct dp_pdev *pdev)
|
|||||||
* based on global per-pdev setting or per-peer setting
|
* based on global per-pdev setting or per-peer setting
|
||||||
* @pdev: Datapath pdev handle
|
* @pdev: Datapath pdev handle
|
||||||
* @peer: Datapath peer
|
* @peer: Datapath peer
|
||||||
|
* @mac_addr: peer mac address
|
||||||
*
|
*
|
||||||
* Return: true if feature is enabled on a per-pdev basis or if
|
* 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
|
* enabled for the given peer when per-peer mode is set, false otherwise
|
||||||
*/
|
*/
|
||||||
inline bool
|
inline bool
|
||||||
dp_peer_or_pdev_tx_cap_enabled(struct dp_pdev *pdev,
|
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 ==
|
if ((pdev->tx_capture_enabled ==
|
||||||
CDP_TX_ENH_CAPTURE_ENABLE_ALL_PEERS) ||
|
CDP_TX_ENH_CAPTURE_ENABLE_ALL_PEERS) ||
|
||||||
((pdev->tx_capture_enabled ==
|
(pdev->tx_capture_enabled ==
|
||||||
CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER) &&
|
CDP_TX_ENH_CAPTURE_ENDIS_PER_PEER)) {
|
||||||
peer->tx_cap_enabled))
|
if (peer && peer->tx_cap_enabled)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* do search based on mac address */
|
||||||
|
return is_dp_peer_mgmt_pkt_filter(pdev,
|
||||||
|
HTT_INVALID_PEER,
|
||||||
|
mac_addr);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +312,11 @@ void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL, wh->i_addr1)) {
|
||||||
|
qdf_nbuf_free(nbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qdf_spin_lock_bh(
|
qdf_spin_lock_bh(
|
||||||
&pdev->tx_capture.ctl_mgmt_lock[type][subtype]);
|
&pdev->tx_capture.ctl_mgmt_lock[type][subtype]);
|
||||||
qdf_nbuf_queue_add(&pdev->tx_capture.ctl_mgmt_q[type][subtype],
|
qdf_nbuf_queue_add(&pdev->tx_capture.ctl_mgmt_q[type][subtype],
|
||||||
@@ -318,6 +330,208 @@ void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
* dp_tx_ppdu_stats_attach - Initialize Tx PPDU stats and enhanced capture
|
||||||
* @pdev: DP PDEV
|
* @pdev: DP PDEV
|
||||||
@@ -326,7 +540,11 @@ void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
|
|||||||
*/
|
*/
|
||||||
void dp_tx_ppdu_stats_attach(struct dp_pdev *pdev)
|
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;
|
int i, j;
|
||||||
|
|
||||||
|
tx_capture = &pdev->tx_capture;
|
||||||
/* Work queue setup for HTT stats and tx capture handling */
|
/* Work queue setup for HTT stats and tx capture handling */
|
||||||
qdf_create_work(0, &pdev->tx_capture.ppdu_stats_work,
|
qdf_create_work(0, &pdev->tx_capture.ppdu_stats_work,
|
||||||
dp_tx_ppdu_stats_process,
|
dp_tx_ppdu_stats_process,
|
||||||
@@ -350,6 +568,14 @@ void dp_tx_ppdu_stats_attach(struct dp_pdev *pdev)
|
|||||||
}
|
}
|
||||||
qdf_mem_zero(&pdev->tx_capture.dummy_ppdu_desc,
|
qdf_mem_zero(&pdev->tx_capture.dummy_ppdu_desc,
|
||||||
sizeof(struct cdp_tx_completion_ppdu));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -400,6 +626,8 @@ void dp_tx_ppdu_stats_detach(struct dp_pdev *pdev)
|
|||||||
&pdev->tx_capture.ctl_mgmt_lock[i][j]);
|
&pdev->tx_capture.ctl_mgmt_lock[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qdf_mem_free(pdev->tx_capture.ptr_peer_mgmt_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -499,14 +727,15 @@ QDF_STATUS dp_tx_add_to_comp_queue(struct dp_soc *soc,
|
|||||||
struct dp_peer *peer)
|
struct dp_peer *peer)
|
||||||
{
|
{
|
||||||
int ret = QDF_STATUS_E_FAILURE;
|
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_FRAME_ACKED) ||
|
||||||
(ts->status == HAL_TX_TQM_RR_REM_CMD_TX) ||
|
(ts->status == HAL_TX_TQM_RR_REM_CMD_TX) ||
|
||||||
((ts->status == HAL_TX_TQM_RR_REM_CMD_AGED) && ts->transmit_cnt))) {
|
((ts->status == HAL_TX_TQM_RR_REM_CMD_AGED) && ts->transmit_cnt)))
|
||||||
ret = dp_update_msdu_to_list(soc, desc->pdev,
|
ret = dp_update_msdu_to_list(soc, pdev, peer, ts, desc->nbuf);
|
||||||
peer, ts, desc->nbuf);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,6 +896,8 @@ static void dp_iterate_free_peer_msdu_q(void *pdev_hdl)
|
|||||||
int tid;
|
int tid;
|
||||||
struct dp_tx_tid *tx_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++) {
|
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
|
||||||
qdf_nbuf_t ppdu_nbuf = NULL;
|
qdf_nbuf_t ppdu_nbuf = NULL;
|
||||||
struct cdp_tx_completion_ppdu *ppdu_desc =
|
struct cdp_tx_completion_ppdu *ppdu_desc =
|
||||||
@@ -743,6 +974,7 @@ dp_config_enh_tx_capture(struct dp_pdev *pdev, uint8_t val)
|
|||||||
&pdev->tx_capture.ctl_mgmt_lock[i][j]);
|
&pdev->tx_capture.ctl_mgmt_lock[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dp_peer_tx_cap_del_all_filter(pdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_spin_unlock(&pdev->tx_capture.config_lock);
|
qdf_spin_unlock(&pdev->tx_capture.config_lock);
|
||||||
@@ -1412,6 +1644,7 @@ QDF_STATUS dp_send_dummy_mpdu_info_to_stack(struct dp_pdev *pdev,
|
|||||||
void *desc)
|
void *desc)
|
||||||
{
|
{
|
||||||
struct dp_peer *peer;
|
struct dp_peer *peer;
|
||||||
|
struct dp_vdev *vdev = NULL;
|
||||||
struct cdp_tx_completion_ppdu *ppdu_desc = desc;
|
struct cdp_tx_completion_ppdu *ppdu_desc = desc;
|
||||||
struct cdp_tx_completion_ppdu_user *user = &ppdu_desc->user[0];
|
struct cdp_tx_completion_ppdu_user *user = &ppdu_desc->user[0];
|
||||||
struct ieee80211_ctlframe_addr2 *wh_min;
|
struct ieee80211_ctlframe_addr2 *wh_min;
|
||||||
@@ -1498,15 +1731,17 @@ QDF_STATUS dp_send_dummy_mpdu_info_to_stack(struct dp_pdev *pdev,
|
|||||||
else {
|
else {
|
||||||
peer = dp_peer_find_by_id(pdev->soc, user->peer_id);
|
peer = dp_peer_find_by_id(pdev->soc, user->peer_id);
|
||||||
if (peer) {
|
if (peer) {
|
||||||
struct dp_vdev *vdev = NULL;
|
|
||||||
|
|
||||||
vdev = peer->vdev;
|
vdev = peer->vdev;
|
||||||
|
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)
|
if (vdev)
|
||||||
qdf_mem_copy(wh_min->i_addr2,
|
qdf_mem_copy(wh_min->i_addr2,
|
||||||
vdev->mac_addr.raw,
|
vdev->mac_addr.raw,
|
||||||
QDF_MAC_ADDR_SIZE);
|
QDF_MAC_ADDR_SIZE);
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
}
|
|
||||||
qdf_nbuf_set_pktlen(tx_capture_info.mpdu_nbuf, sizeof(*wh_min));
|
qdf_nbuf_set_pktlen(tx_capture_info.mpdu_nbuf, sizeof(*wh_min));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1545,6 +1780,7 @@ void dp_send_dummy_rts_cts_frame(struct dp_pdev *pdev,
|
|||||||
struct dp_pdev_tx_capture *ptr_tx_cap;
|
struct dp_pdev_tx_capture *ptr_tx_cap;
|
||||||
struct dp_peer *peer;
|
struct dp_peer *peer;
|
||||||
uint8_t rts_send;
|
uint8_t rts_send;
|
||||||
|
struct dp_vdev *vdev = NULL;
|
||||||
|
|
||||||
rts_send = 0;
|
rts_send = 0;
|
||||||
ptr_tx_cap = &pdev->tx_capture;
|
ptr_tx_cap = &pdev->tx_capture;
|
||||||
@@ -1596,15 +1832,19 @@ void dp_send_dummy_rts_cts_frame(struct dp_pdev *pdev,
|
|||||||
peer = dp_peer_find_by_id(pdev->soc,
|
peer = dp_peer_find_by_id(pdev->soc,
|
||||||
cur_ppdu_desc->user[0].peer_id);
|
cur_ppdu_desc->user[0].peer_id);
|
||||||
if (peer) {
|
if (peer) {
|
||||||
struct dp_vdev *vdev = NULL;
|
|
||||||
|
|
||||||
vdev = peer->vdev;
|
vdev = peer->vdev;
|
||||||
|
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)
|
if (vdev)
|
||||||
qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
|
qdf_mem_copy(&ppdu_desc->user[0].mac_addr,
|
||||||
vdev->mac_addr.raw,
|
vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE);
|
||||||
QDF_MAC_ADDR_SIZE);
|
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
}
|
|
||||||
|
|
||||||
dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc);
|
dp_send_dummy_mpdu_info_to_stack(pdev, ppdu_desc);
|
||||||
}
|
}
|
||||||
@@ -2201,6 +2441,12 @@ dp_check_mgmt_ctrl_ppdu(struct dp_pdev *pdev,
|
|||||||
subtype = 0;
|
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) {
|
switch (ppdu_desc->htt_frame_type) {
|
||||||
case HTT_STATS_FTYPE_TIDQ_DATA_SU:
|
case HTT_STATS_FTYPE_TIDQ_DATA_SU:
|
||||||
case HTT_STATS_FTYPE_TIDQ_DATA_MU:
|
case HTT_STATS_FTYPE_TIDQ_DATA_MU:
|
||||||
@@ -2278,7 +2524,7 @@ get_mgmt_pkt_from_queue:
|
|||||||
HTT_PPDU_STATS_USER_STATUS_FILTERED) {
|
HTT_PPDU_STATS_USER_STATUS_FILTERED) {
|
||||||
qdf_nbuf_free(nbuf_ppdu_desc);
|
qdf_nbuf_free(nbuf_ppdu_desc);
|
||||||
status = 0;
|
status = 0;
|
||||||
goto free_ppdu_desc;
|
goto insert_mgmt_buf_to_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2287,6 +2533,7 @@ get_mgmt_pkt_from_queue:
|
|||||||
qdf_nbuf_queue_add(retries_q, nbuf_ppdu_desc);
|
qdf_nbuf_queue_add(retries_q, nbuf_ppdu_desc);
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
|
insert_mgmt_buf_to_queue:
|
||||||
/*
|
/*
|
||||||
* insert the mgmt_ctl buffer back to
|
* insert the mgmt_ctl buffer back to
|
||||||
* the queue
|
* the queue
|
||||||
@@ -2877,6 +3124,7 @@ void dp_tx_ppdu_stats_process(void *context)
|
|||||||
uint16_t tid = 0;
|
uint16_t tid = 0;
|
||||||
uint32_t num_msdu = 0;
|
uint32_t num_msdu = 0;
|
||||||
uint32_t qlen = 0;
|
uint32_t qlen = 0;
|
||||||
|
uint16_t peer_id;
|
||||||
|
|
||||||
qdf_nbuf_queue_init(&head_msdu);
|
qdf_nbuf_queue_init(&head_msdu);
|
||||||
qdf_nbuf_queue_init(&head_xretries);
|
qdf_nbuf_queue_init(&head_xretries);
|
||||||
@@ -2940,8 +3188,11 @@ void dp_tx_ppdu_stats_process(void *context)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer = dp_peer_find_by_id(pdev->soc,
|
if ((ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA) ||
|
||||||
ppdu_desc->user[0].peer_id);
|
(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
|
* peer can be NULL
|
||||||
*/
|
*/
|
||||||
@@ -2950,9 +3201,6 @@ void dp_tx_ppdu_stats_process(void *context)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA) ||
|
|
||||||
(ppdu_desc->num_mpdu &&
|
|
||||||
ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR)) {
|
|
||||||
/**
|
/**
|
||||||
* check whether it is bss peer,
|
* check whether it is bss peer,
|
||||||
* if bss_peer no need to process further
|
* if bss_peer no need to process further
|
||||||
@@ -2961,7 +3209,7 @@ void dp_tx_ppdu_stats_process(void *context)
|
|||||||
*/
|
*/
|
||||||
if (peer->bss_peer ||
|
if (peer->bss_peer ||
|
||||||
!dp_peer_or_pdev_tx_cap_enabled(pdev,
|
!dp_peer_or_pdev_tx_cap_enabled(pdev,
|
||||||
peer)) {
|
peer, peer->mac_addr.raw)) {
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
dp_peer_unref_del_find_by_id(peer);
|
||||||
qdf_nbuf_free(nbuf);
|
qdf_nbuf_free(nbuf);
|
||||||
continue;
|
continue;
|
||||||
@@ -3068,6 +3316,8 @@ dequeue_msdu_again:
|
|||||||
ppdu_desc->user[0].start_seq,
|
ppdu_desc->user[0].start_seq,
|
||||||
ppdu_cnt,
|
ppdu_cnt,
|
||||||
ppdu_desc_cnt);
|
ppdu_desc_cnt);
|
||||||
|
|
||||||
|
dp_peer_unref_del_find_by_id(peer);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* other packet frame also added to
|
* other packet frame also added to
|
||||||
@@ -3076,7 +3326,6 @@ dequeue_msdu_again:
|
|||||||
nbuf_ppdu_desc_list[ppdu_desc_cnt++] = nbuf;
|
nbuf_ppdu_desc_list[ppdu_desc_cnt++] = nbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3334,8 +3583,7 @@ QDF_STATUS dp_send_cts_frame_to_stack(struct dp_soc *soc,
|
|||||||
if (!peer)
|
if (!peer)
|
||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
|
||||||
if (!dp_peer_or_pdev_tx_cap_enabled(pdev,
|
if (!dp_peer_or_pdev_tx_cap_enabled(pdev, NULL, peer->mac_addr.raw)) {
|
||||||
peer)) {
|
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
dp_peer_unref_del_find_by_id(peer);
|
||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -3391,6 +3639,7 @@ QDF_STATUS dp_send_ack_frame_to_stack(struct dp_soc *soc,
|
|||||||
uint32_t ast_index;
|
uint32_t ast_index;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
bool bar_frame;
|
bool bar_frame;
|
||||||
|
uint8_t *ptr_mac_addr;
|
||||||
|
|
||||||
rx_status = &ppdu_info->rx_status;
|
rx_status = &ppdu_info->rx_status;
|
||||||
|
|
||||||
@@ -3433,6 +3682,10 @@ QDF_STATUS dp_send_ack_frame_to_stack(struct dp_soc *soc,
|
|||||||
ast_index = rx_user_status->ast_index;
|
ast_index = rx_user_status->ast_index;
|
||||||
if (ast_index >=
|
if (ast_index >=
|
||||||
wlan_cfg_get_max_ast_idx(soc->wlan_cfg_ctx)) {
|
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,
|
set_mpdu_info(&tx_capture_info,
|
||||||
rx_status, rx_user_status);
|
rx_status, rx_user_status);
|
||||||
tx_capture_info.mpdu_nbuf =
|
tx_capture_info.mpdu_nbuf =
|
||||||
@@ -3471,7 +3724,8 @@ QDF_STATUS dp_send_ack_frame_to_stack(struct dp_soc *soc,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!dp_peer_or_pdev_tx_cap_enabled(pdev,
|
if (!dp_peer_or_pdev_tx_cap_enabled(pdev,
|
||||||
peer)) {
|
NULL,
|
||||||
|
peer->mac_addr.raw)) {
|
||||||
dp_peer_unref_del_find_by_id(peer);
|
dp_peer_unref_del_find_by_id(peer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -3515,16 +3769,56 @@ QDF_STATUS dp_send_ack_frame_to_stack(struct dp_soc *soc,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
|
* dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
|
||||||
|
* @pdev: DP PDEV handle
|
||||||
* @peer: Peer handle
|
* @peer: Peer handle
|
||||||
* @value: Enable/disable setting for tx_cap_enabled
|
* @value: Enable/disable setting for tx_cap_enabled
|
||||||
|
* @peer_mac: peer mac address
|
||||||
*
|
*
|
||||||
* Return: None
|
* Return: QDF_STATUS
|
||||||
*/
|
*/
|
||||||
void
|
QDF_STATUS
|
||||||
dp_peer_set_tx_capture_enabled(struct dp_peer *peer, bool value)
|
dp_peer_set_tx_capture_enabled(struct dp_pdev *pdev,
|
||||||
|
struct dp_peer *peer, uint8_t value,
|
||||||
|
uint8_t *peer_mac)
|
||||||
{
|
{
|
||||||
|
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;
|
peer->tx_cap_enabled = value;
|
||||||
if (!value)
|
status = QDF_STATUS_SUCCESS;
|
||||||
dp_peer_tx_cap_tid_queue_flush(peer);
|
}
|
||||||
|
} 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
|
#endif
|
||||||
|
@@ -37,6 +37,14 @@ struct dp_tx_desc_s;
|
|||||||
|
|
||||||
#define SIFS_INTERVAL 16
|
#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 {
|
struct dp_pdev_tx_capture {
|
||||||
/* For deferred PPDU status processing */
|
/* For deferred PPDU status processing */
|
||||||
qdf_spinlock_t ppdu_stats_lock;
|
qdf_spinlock_t ppdu_stats_lock;
|
||||||
@@ -62,6 +70,7 @@ struct dp_pdev_tx_capture {
|
|||||||
qdf_spinlock_t config_lock;
|
qdf_spinlock_t config_lock;
|
||||||
uint32_t htt_frame_type[TX_CAP_HTT_MAX_FTYPE];
|
uint32_t htt_frame_type[TX_CAP_HTT_MAX_FTYPE];
|
||||||
struct cdp_tx_completion_ppdu dummy_ppdu_desc;
|
struct cdp_tx_completion_ppdu dummy_ppdu_desc;
|
||||||
|
struct dp_peer_mgmt_list *ptr_peer_mgmt_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tx TID */
|
/* Tx TID */
|
||||||
@@ -263,12 +272,73 @@ QDF_STATUS dp_send_ack_frame_to_stack(struct dp_soc *soc,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
|
* dp_peer_set_tx_capture_enabled: Set tx_cap_enabled bit in peer
|
||||||
|
* @pdev: DP PDEV handle
|
||||||
* @peer: Peer handle
|
* @peer: Peer handle
|
||||||
* @value: Enable/disable setting for tx_cap_enabled
|
* @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
|
QDF_STATUS
|
||||||
dp_peer_set_tx_capture_enabled(struct dp_peer *peer, bool value);
|
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
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user