qcacmn: wifi DP TX optimization for RMNET pkts

pkts from rmnet device are sent as SG, we see poor
throughput when transmitting these SG frames using
an MSDU extension descriptor. to resolve this issue
we identify if the frame is from RMNET device and if so
copy the headers from skb linear address to the frag
address and provide the frag address to HW for transmission

CRs-Fixed: 3337822
Change-Id: Ic1b7d9f861dcd4f838509772c45e47d3917fc59f
This commit is contained in:
Tallapragada Kalyan
2022-11-10 10:34:29 +05:30
committed by Madan Koyyalamudi
parent bb7ee725be
commit 075b483358
3 changed files with 81 additions and 2 deletions

View File

@@ -2001,6 +2001,70 @@ void dp_tx_nbuf_unmap_regular(struct dp_soc *soc, struct dp_tx_desc_s *desc)
desc->length); 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) #if defined(QCA_DP_TX_NBUF_NO_MAP_UNMAP) && !defined(BUILD_X86)
static inline static inline
qdf_dma_addr_t dp_tx_nbuf_map(struct dp_vdev *vdev, 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, void dp_tx_nbuf_unmap(struct dp_soc *soc,
struct dp_tx_desc_s *desc) 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); return dp_tx_nbuf_unmap_regular(soc, desc);
} }
#else #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); 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) { if (!paddr) {
/* Handle failure */ /* Handle failure */
dp_err("qdf_nbuf_map failed"); 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 { } else {
struct dp_tx_seg_info_s seg_info = {0}; 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, nbuf = dp_tx_prepare_sg(vdev, nbuf, &seg_info,
&msdu_info); &msdu_info);
if (!nbuf) 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)); 1, qdf_nbuf_len(nbuf));
} }
send_single:
/* 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

View File

@@ -60,6 +60,7 @@
#define DP_TX_DESC_FLAG_TX_COMP_ERR 0x1000 #define DP_TX_DESC_FLAG_TX_COMP_ERR 0x1000
#define DP_TX_DESC_FLAG_FLUSH 0x2000 #define DP_TX_DESC_FLAG_FLUSH 0x2000
#define DP_TX_DESC_FLAG_TRAFFIC_END_IND 0x4000 #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 * 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 * 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 #ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
uint8_t skip_hp_update; uint8_t skip_hp_update;
#endif #endif
#ifdef QCA_DP_TX_RMNET_OPTIMIZATION
uint16_t buf_len;
uint8_t *payload_addr;
#endif
}; };
#ifndef QCA_HOST_MODE_WIFI_DISABLED #ifndef QCA_HOST_MODE_WIFI_DISABLED

View File

@@ -357,6 +357,7 @@ enum dp_tx_frm_type {
dp_tx_frm_audio, dp_tx_frm_audio,
dp_tx_frm_me, dp_tx_frm_me,
dp_tx_frm_raw, dp_tx_frm_raw,
dp_tx_frm_rmnet,
}; };
/** /**