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:
@@ -774,7 +774,6 @@ struct dp_tx_desc_s *dp_tx_prepare_desc_single(struct dp_vdev *vdev,
|
|||||||
uint8_t align_pad;
|
uint8_t align_pad;
|
||||||
uint8_t is_exception = 0;
|
uint8_t is_exception = 0;
|
||||||
uint8_t htt_hdr_size;
|
uint8_t htt_hdr_size;
|
||||||
qdf_ether_header_t *eh;
|
|
||||||
struct dp_tx_desc_s *tx_desc;
|
struct dp_tx_desc_s *tx_desc;
|
||||||
struct dp_pdev *pdev = vdev->pdev;
|
struct dp_pdev *pdev = vdev->pdev;
|
||||||
struct dp_soc *soc = pdev->soc;
|
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;
|
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 !TQM_BYPASS_WAR
|
||||||
if (is_exception || tx_exc_metadata)
|
if (is_exception || tx_exc_metadata)
|
||||||
#endif
|
#endif
|
||||||
@@ -1663,9 +1654,8 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
} else
|
} else
|
||||||
htt_tcl_metadata = vdev->htt_tcl_metadata;
|
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);
|
HTT_TX_TCL_METADATA_VALID_HTT_SET(htt_tcl_metadata, 1);
|
||||||
}
|
|
||||||
|
|
||||||
if (qdf_unlikely(QDF_STATUS_SUCCESS !=
|
if (qdf_unlikely(QDF_STATUS_SUCCESS !=
|
||||||
qdf_nbuf_map_nbytes_single(vdev->osdev, nbuf,
|
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
|
#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
|
* dp_tx_send() - Transmit a frame on a given VAP
|
||||||
* @soc: DP soc handle
|
* @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 =
|
struct dp_vdev *vdev =
|
||||||
dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
|
dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
|
||||||
vdev_id);
|
vdev_id);
|
||||||
|
|
||||||
if (qdf_unlikely(!vdev))
|
if (qdf_unlikely(!vdev))
|
||||||
return nbuf;
|
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 */
|
/* Single linear frame */
|
||||||
/*
|
/*
|
||||||
* If nbuf is a simple linear frame, use send_single function to
|
* 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 = tx_desc->nbuf;
|
||||||
qdf_nbuf_t nbuf_copy = NULL;
|
qdf_nbuf_t nbuf_copy = NULL;
|
||||||
struct dp_tx_msdu_info_s msdu_info;
|
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;
|
struct dp_soc *soc = NULL;
|
||||||
qdf_ether_header_t *eh = (qdf_ether_header_t *)qdf_nbuf_data(nbuf);
|
|
||||||
#ifdef WDS_VENDOR_EXTENSION
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
int is_mcast = 0, is_ucast = 0;
|
int is_mcast = 0, is_ucast = 0;
|
||||||
int num_peers_3addr = 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,
|
DP_STATS_INC_PKT(vdev, tx_i.reinject_pkts, 1,
|
||||||
qdf_nbuf_len(tx_desc->nbuf));
|
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
|
#ifdef WDS_VENDOR_EXTENSION
|
||||||
if (qdf_unlikely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) {
|
if (qdf_unlikely(vdev->tx_encap_type != htt_cmn_pkt_type_raw)) {
|
||||||
is_mcast = (IS_MULTICAST(wh->i_addr1)) ? 1 : 0;
|
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))))) {
|
(is_ucast && peer->wds_ecm.wds_tx_ucast_4addr))))) {
|
||||||
#else
|
#else
|
||||||
((peer->bss_peer &&
|
((peer->bss_peer &&
|
||||||
!(vdev->osif_proxy_arp(vdev->osif_vdev, nbuf))) ||
|
!(vdev->osif_proxy_arp(vdev->osif_vdev, nbuf))))) {
|
||||||
peer->nawds_enabled)) {
|
|
||||||
#endif
|
#endif
|
||||||
peer_id = DP_INVALID_PEER;
|
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);
|
nbuf_copy = qdf_nbuf_copy(nbuf);
|
||||||
|
|
||||||
if (!nbuf_copy) {
|
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) {
|
qdf_nbuf_free(nbuf);
|
||||||
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);
|
|
||||||
|
|
||||||
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user