diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index abc2acaaa7..a965f178f1 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -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); }