diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index 754578c710..486cbfcd99 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -2001,6 +2001,70 @@ void dp_tx_nbuf_unmap_regular(struct dp_soc *soc, struct dp_tx_desc_s *desc) desc->length); } +#ifdef QCA_DP_TX_RMNET_OPTIMIZATION +static inline bool +is_nbuf_frm_rmnet(qdf_nbuf_t nbuf, struct dp_tx_msdu_info_s *msdu_info) +{ + struct net_device *ingress_dev; + skb_frag_t *frag; + uint16_t buf_len = 0; + uint16_t linear_data_len = 0; + uint8_t *payload_addr = NULL; + + ingress_dev = dev_get_by_index(dev_net(nbuf->dev), nbuf->skb_iif); + + if ((ingress_dev->priv_flags & IFF_PHONY_HEADROOM)) { + dev_put(ingress_dev); + frag = &(skb_shinfo(nbuf)->frags[0]); + buf_len = skb_frag_size(frag); + payload_addr = (uint8_t *)skb_frag_address(frag); + linear_data_len = skb_headlen(nbuf); + + buf_len += linear_data_len; + payload_addr = payload_addr - linear_data_len; + memcpy(payload_addr, nbuf->data, linear_data_len); + + msdu_info->frm_type = dp_tx_frm_rmnet; + msdu_info->buf_len = buf_len; + msdu_info->payload_addr = payload_addr; + + return true; + } + dev_put(ingress_dev); + return false; +} + +static inline +qdf_dma_addr_t dp_tx_rmnet_nbuf_map(struct dp_tx_msdu_info_s *msdu_info, + struct dp_tx_desc_s *tx_desc) +{ + qdf_dma_addr_t paddr; + + paddr = (qdf_dma_addr_t)qdf_mem_virt_to_phys(msdu_info->payload_addr); + tx_desc->length = msdu_info->buf_len; + + qdf_nbuf_dma_clean_range((void *)msdu_info->payload_addr, + (void *)(msdu_info->payload_addr + + msdu_info->buf_len)); + + tx_desc->flags |= DP_TX_DESC_FLAG_RMNET; + return paddr; +} +#else +static inline bool +is_nbuf_frm_rmnet(qdf_nbuf_t nbuf, struct dp_tx_msdu_info_s *msdu_info) +{ + return false; +} + +static inline +qdf_dma_addr_t dp_tx_rmnet_nbuf_map(struct dp_tx_msdu_info_s *msdu_info, + struct dp_tx_desc_s *tx_desc) +{ + return 0; +} +#endif + #if defined(QCA_DP_TX_NBUF_NO_MAP_UNMAP) && !defined(BUILD_X86) static inline qdf_dma_addr_t dp_tx_nbuf_map(struct dp_vdev *vdev, @@ -2020,7 +2084,8 @@ static inline void dp_tx_nbuf_unmap(struct dp_soc *soc, struct dp_tx_desc_s *desc) { - if (qdf_unlikely(!(desc->flags & DP_TX_DESC_FLAG_SIMPLE))) + if (qdf_unlikely(!(desc->flags & + (DP_TX_DESC_FLAG_SIMPLE | DP_TX_DESC_FLAG_RMNET)))) return dp_tx_nbuf_unmap_regular(soc, desc); } #else @@ -2322,7 +2387,11 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf, dp_tx_update_mesh_flags(soc, vdev, tx_desc); - paddr = dp_tx_nbuf_map(vdev, tx_desc, nbuf); + if (qdf_unlikely(msdu_info->frm_type == dp_tx_frm_rmnet)) + paddr = dp_tx_rmnet_nbuf_map(msdu_info, tx_desc); + else + paddr = dp_tx_nbuf_map(vdev, tx_desc, nbuf); + if (!paddr) { /* Handle failure */ dp_err("qdf_nbuf_map failed"); @@ -3612,6 +3681,9 @@ qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, } else { struct dp_tx_seg_info_s seg_info = {0}; + if (qdf_unlikely(is_nbuf_frm_rmnet(nbuf, &msdu_info))) + goto send_single; + nbuf = dp_tx_prepare_sg(vdev, nbuf, &seg_info, &msdu_info); if (!nbuf) @@ -3670,6 +3742,7 @@ qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc_hdl, uint8_t vdev_id, 1, qdf_nbuf_len(nbuf)); } +send_single: /* Single linear frame */ /* * If nbuf is a simple linear frame, use send_single function to diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h index df8d8d9349..727336dc20 100644 --- a/dp/wifi3.0/dp_tx.h +++ b/dp/wifi3.0/dp_tx.h @@ -60,6 +60,7 @@ #define DP_TX_DESC_FLAG_TX_COMP_ERR 0x1000 #define DP_TX_DESC_FLAG_FLUSH 0x2000 #define DP_TX_DESC_FLAG_TRAFFIC_END_IND 0x4000 +#define DP_TX_DESC_FLAG_RMNET 0x8000 /* * Since the Tx descriptor flag is of only 16-bit and no more bit is free for * any new flag, therefore for time being overloading PPEDS flag with that of @@ -224,6 +225,10 @@ struct dp_tx_msdu_info_s { #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR uint8_t skip_hp_update; #endif +#ifdef QCA_DP_TX_RMNET_OPTIMIZATION + uint16_t buf_len; + uint8_t *payload_addr; +#endif }; #ifndef QCA_HOST_MODE_WIFI_DISABLED diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index a3a0be1ead..8cdfcd9bec 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -357,6 +357,7 @@ enum dp_tx_frm_type { dp_tx_frm_audio, dp_tx_frm_me, dp_tx_frm_raw, + dp_tx_frm_rmnet, }; /**