qcacmn: NAWDS Tx reinject optimization

During the packet transfer from HOST to Transmit Classifier Layer,
if NAWDS is enabled, send peer id of NAWDS peer.
This is to avoid re-injection from FW to Host.

Change-Id: Ic0e5c46fff3bbe1a3e8ea3a01986478c925452f5
CRs-Fixed: 2628703
This commit is contained in:
Shivani Soni
2020-02-26 14:09:41 +05:30
committed by nshrivas
parent 046f3623de
commit 3ba8fe5a21

View File

@@ -774,7 +774,6 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev,
uint8_t align_pad;
uint8_t is_exception = 0;
uint8_t htt_hdr_size;
qdf_ether_header_t *eh;
struct dp_tx_desc_s *tx_desc;
struct dp_pdev *pdev = vdev->pdev;
struct dp_soc *soc = pdev->soc;
@@ -867,14 +866,6 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev,
is_exception = 1;
}
if (qdf_unlikely(vdev->nawds_enabled)) {
eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf);
if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost)) {
tx_desc->flags |= DP_TX_DESC_FLAG_TO_FW;
is_exception = 1;
}
}
#if !TQM_BYPASS_WAR
if (is_exception || tx_exc_metadata)
#endif
@@ -1663,9 +1654,8 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
} else
htt_tcl_metadata = vdev->htt_tcl_metadata;
if (msdu_info->exception_fw) {
if (msdu_info->exception_fw)
HTT_TX_TCL_METADATA_VALID_HTT_SET(htt_tcl_metadata, 1);
}
if (qdf_unlikely(QDF_STATUS_SUCCESS !=
qdf_nbuf_map_nbytes_single(vdev->osdev, nbuf,
@@ -2282,6 +2272,88 @@ qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id,
#endif
/**
* dp_tx_nawds_handler() - NAWDS handler
*
* @soc: DP soc handle
* @vdev_id: id of DP vdev handle
* @msdu_info: msdu_info required to create HTT metadata
* @nbuf: skb
*
* This API transfers the multicast frames with the peer id
* on NAWDS enabled peer.
* Return: none
*/
static inline
void dp_tx_nawds_handler(struct cdp_soc_t *soc, struct dp_vdev *vdev,
struct dp_tx_msdu_info_s *msdu_info, qdf_nbuf_t nbuf)
{
struct dp_peer *peer = NULL;
qdf_nbuf_t nbuf_clone = NULL;
struct dp_soc *dp_soc = (struct dp_soc *)soc;
uint16_t peer_id = DP_INVALID_PEER;
struct dp_peer *sa_peer = NULL;
struct dp_ast_entry *ast_entry = NULL;
qdf_ether_header_t *eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf);
if (qdf_nbuf_get_tx_ftype(nbuf) == CB_FTYPE_INTRABSS_FWD) {
qdf_spin_lock_bh(&dp_soc->ast_lock);
ast_entry = dp_peer_ast_hash_find_by_pdevid
(dp_soc,
(uint8_t *)(eh->ether_shost),
vdev->pdev->pdev_id);
if (ast_entry)
sa_peer = ast_entry->peer;
qdf_spin_unlock_bh(&dp_soc->ast_lock);
}
qdf_spin_lock_bh(&dp_soc->peer_ref_mutex);
TAILQ_FOREACH(peer, &vdev->peer_list, peer_list_elem) {
if (!peer->bss_peer && peer->nawds_enabled) {
peer_id = peer->peer_ids[0];
/* Multicast packets needs to be
* dropped in case of intra bss forwarding
*/
if (sa_peer == peer) {
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG,
" %s: multicast packet", __func__);
DP_STATS_INC(peer, tx.nawds_mcast_drop, 1);
continue;
}
nbuf_clone = qdf_nbuf_clone(nbuf);
if (!nbuf_clone) {
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_ERROR,
FL("nbuf clone failed"));
break;
}
nbuf_clone = dp_tx_send_msdu_single(vdev, nbuf_clone,
msdu_info, peer_id,
NULL);
if (nbuf_clone) {
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG,
FL("pkt send failed"));
qdf_nbuf_free(nbuf_clone);
} else {
if (peer_id != DP_INVALID_PEER)
DP_STATS_INC_PKT(peer, tx.nawds_mcast,
1, qdf_nbuf_len(nbuf));
}
}
}
qdf_spin_unlock_bh(&dp_soc->peer_ref_mutex);
}
/**
* dp_tx_send() - Transmit a frame on a given VAP
* @soc: DP soc handle
@@ -2306,7 +2378,6 @@ qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf)
struct dp_vdev *vdev =
dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
vdev_id);
if (qdf_unlikely(!vdev))
return nbuf;
@@ -2422,6 +2493,17 @@ qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf)
}
if (qdf_unlikely(vdev->nawds_enabled)) {
qdf_ether_header_t *eh = (qdf_ether_header_t *)
qdf_nbuf_data(nbuf);
if (DP_FRAME_IS_MULTICAST((eh)->ether_dhost))
dp_tx_nawds_handler(soc, vdev, &msdu_info, nbuf);
peer_id = DP_INVALID_PEER;
DP_STATS_INC_PKT(vdev, tx_i.nawds_mcast,
1, qdf_nbuf_len(nbuf));
}
/* Single linear frame */
/*
* If nbuf is a simple linear frame, use send_single function to
@@ -2460,10 +2542,7 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
qdf_nbuf_t nbuf = tx_desc->nbuf;
qdf_nbuf_t nbuf_copy = NULL;
struct dp_tx_msdu_info_s msdu_info;
struct dp_peer *sa_peer = NULL;
struct dp_ast_entry *ast_entry = NULL;
struct dp_soc *soc = NULL;
qdf_ether_header_t *eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf);
#ifdef WDS_VENDOR_EXTENSION
int is_mcast = 0, is_ucast = 0;
int num_peers_3addr = 0;
@@ -2486,18 +2565,6 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1,
qdf_nbuf_len(tx_desc->nbuf));
qdf_spin_lock_bh(&(soc->ast_lock));
ast_entry = dp_peer_ast_hash_find_by_pdevid
(soc,
(uint8_t *)(eh->ether_shost),
vdev->pdev->pdev_id);
if (ast_entry)
sa_peer = ast_entry->peer;
qdf_spin_unlock_bh(&(soc->ast_lock));
#ifdef WDS_VENDOR_EXTENSION
if (qdf_unlikely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) {
is_mcast = (IS_MULTICAST(wh->i_addr1)) ? 1 : 0;
@@ -2542,25 +2609,10 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
(is_ucast && peer->wds_ecm.wds_tx_ucast_4addr))))) {
#else
((peer->bss_peer &&
!(vdev->osif_proxy_arp(vdev->osif_vdev, nbuf))) ||
peer->nawds_enabled)) {
!(vdev->osif_proxy_arp(vdev->osif_vdev, nbuf))))) {
#endif
peer_id = DP_INVALID_PEER;
if (peer->nawds_enabled) {
peer_id = peer->peer_ids[0];
if (sa_peer == peer) {
QDF_TRACE(
QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG,
" %s: multicast packet",
__func__);
DP_STATS_INC(peer,
tx.nawds_mcast_drop, 1);
continue;
}
}
nbuf_copy = qdf_nbuf_copy(nbuf);
if (!nbuf_copy) {
@@ -2591,25 +2643,7 @@ void dp_tx_reinject_handler(struct dp_tx_desc_s *tx_desc, uint8_t *status)
}
}
if (vdev->nawds_enabled) {
peer_id = DP_INVALID_PEER;
DP_STATS_INC_PKT(vdev, tx_i.nawds_mcast,
1, qdf_nbuf_len(nbuf));
nbuf = dp_tx_send_msdu_single(vdev,
nbuf,
&msdu_info,
peer_id, NULL);
if (nbuf) {
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_DEBUG,
FL("pkt send failed"));
qdf_nbuf_free(nbuf);
}
} else
qdf_nbuf_free(nbuf);
qdf_nbuf_free(nbuf);
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
}