浏览代码

qcacmn: Skip special frame rate info update

To avoid unmeaningful rate fluctuation, when report
rx linkspeed to upper layer, exclude special frames:
arp/ssdp/dhcp/eapol/ipv6 NA/NS/DHCPV6 in low rate.

Change-Id: I4bc49a808a02b4bc8c687f70690922045d65e739
CRs-Fixed: 3198484
jinbliu 3 年之前
父节点
当前提交
a8f2b81354
共有 7 个文件被更改,包括 231 次插入0 次删除
  1. 1 0
      dp/cmn_dp_api/dp_ratetable.c
  2. 53 0
      dp/inc/cdp_txrx_misc.h
  3. 8 0
      dp/inc/cdp_txrx_ops.h
  4. 37 0
      dp/wifi3.0/dp_main.c
  5. 70 0
      dp/wifi3.0/dp_rx.c
  6. 58 0
      dp/wifi3.0/dp_rx.h
  7. 4 0
      dp/wifi3.0/dp_types.h

+ 1 - 0
dp/cmn_dp_api/dp_ratetable.c

@@ -17,6 +17,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <qdf_types.h>
 #include "dp_ratetable.h"
 #include "qdf_module.h"
 #include "cdp_txrx_mon_struct.h"

+ 53 - 0
dp/inc/cdp_txrx_misc.h

@@ -994,4 +994,57 @@ cdp_set_peer_txq_flush_config(ol_txrx_soc_handle soc, uint8_t vdev_id,
 	return 0;
 }
 #endif /* WLAN_FEATURE_PEER_TXQ_FLUSH_CONF */
+#ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+/**
+ * cdp_set_bus_vote_lvl() - have a vote on bus bandwidth lvl
+ * @soc: datapath soc handle
+ * @high: whether TPUT level is high or not
+ *
+ * Return: void
+ */
+static inline void
+cdp_set_bus_vote_lvl_high(ol_txrx_soc_handle soc, bool high)
+{
+	if (!soc || !soc->ops || !soc->ops->misc_ops ||
+	    !soc->ops->misc_ops->set_bus_vote_lvl_high) {
+		dp_cdp_debug("Invalid Instance:");
+		return;
+	}
+
+	soc->ops->misc_ops->set_bus_vote_lvl_high(soc, high);
+}
+
+/**
+ * cdp_get_bus_vote_lvl() - get bus bandwidth lvl from dp
+ * @soc: datapath soc handle
+ *
+ * Return: bool, whether TPUT level is high or not
+ */
+static inline bool
+cdp_get_bus_lvl_high(ol_txrx_soc_handle soc)
+{
+	if (!soc || !soc->ops || !soc->ops->misc_ops ||
+	    !soc->ops->misc_ops->get_bus_vote_lvl_high) {
+		dp_cdp_debug("Invalid Instance:");
+		return false;
+	}
+
+	return soc->ops->misc_ops->get_bus_vote_lvl_high(soc);
+}
+#else
+static inline void
+cdp_set_bus_vote_lvl_high(ol_txrx_soc_handle soc, bool high)
+{
+}
+
+static inline bool
+cdp_get_bus_lvl_high(ol_txrx_soc_handle soc)
+{
+	/*
+	 * default bus lvl is high to
+	 * make sure not affect tput
+	 */
+	return true;
+}
+#endif
 #endif /* _CDP_TXRX_MISC_H_ */

+ 8 - 0
dp/inc/cdp_txrx_ops.h

@@ -1513,6 +1513,10 @@ struct ol_if_ops {
  * @set_tx_flush_pending: Configures the ac/tid to be flushed and policy
  *			  to flush.
  *
+ * set_bus_vote_lvl_high: The bus lvl is set to high or low based on tput
+ * get_bus_vote_lvl_high: Get bus lvl to determine whether or not get
+ *                        rx rate stats
+ *
  * Function pointers for miscellaneous soc/pdev/vdev related operations.
  */
 struct cdp_misc_ops {
@@ -1610,6 +1614,10 @@ struct cdp_misc_ops {
 					 uint8_t ac, uint32_t tid,
 					 enum cdp_peer_txq_flush_policy policy);
 #endif
+#ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+	void (*set_bus_vote_lvl_high)(struct cdp_soc_t *soc_hdl, bool high);
+	bool (*get_bus_vote_lvl_high)(struct cdp_soc_t *soc_hdl);
+#endif
 };
 
 /**

+ 37 - 0
dp/wifi3.0/dp_main.c

@@ -13591,6 +13591,37 @@ void dp_deregister_packetdump_callback(struct cdp_soc_t *soc_hdl,
 }
 #endif
 
+#ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+/**
+ * dp_set_bus_vote_lvl_high() - Take a vote on bus bandwidth from dp
+ * @soc_hdl: Datapath soc handle
+ * @high: whether the bus bw is high or not
+ *
+ * Return: void
+ */
+static void
+dp_set_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl, bool high)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+
+	soc->high_throughput = high;
+}
+
+/**
+ * dp_get_bus_vote_lvl_high() - get bus bandwidth vote to dp
+ * @soc_hdl: Datapath soc handle
+ *
+ * Return: bool
+ */
+static bool
+dp_get_bus_vote_lvl_high(ol_txrx_soc_handle soc_hdl)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+
+	return soc->high_throughput;
+}
+#endif
+
 #ifdef DP_PEER_EXTENDED_API
 static struct cdp_misc_ops dp_ops_misc = {
 #ifdef FEATURE_WLAN_TDLS
@@ -13631,6 +13662,10 @@ static struct cdp_misc_ops dp_ops_misc = {
 	.register_pktdump_cb = dp_register_packetdump_callback,
 	.unregister_pktdump_cb = dp_deregister_packetdump_callback,
 #endif
+#ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+	.set_bus_vote_lvl_high = dp_set_bus_vote_lvl_high,
+	.get_bus_vote_lvl_high = dp_get_bus_vote_lvl_high,
+#endif
 };
 #endif
 
@@ -15532,6 +15567,8 @@ static void dp_soc_cfg_init(struct dp_soc *soc)
 
 		soc->wlan_cfg_ctx->rxdma1_enable = 0;
 		soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev = 1;
+		/* use only MAC0 status ring */
+		soc->wlan_cfg_ctx->num_rxdma_status_rings_per_pdev = 1;
 		break;
 	case TARGET_TYPE_QCA8074:
 		wlan_cfg_set_raw_mode_war(soc->wlan_cfg_ctx, true);

+ 70 - 0
dp/wifi3.0/dp_rx.c

@@ -39,6 +39,9 @@
 #ifdef FEATURE_WDS
 #include "dp_txrx_wds.h"
 #endif
+#ifdef DP_RATETABLE_SUPPORT
+#include "dp_ratetable.h"
+#endif
 
 #ifdef DUP_RX_DESC_WAR
 void dp_rx_dump_info_and_assert(struct dp_soc *soc,
@@ -2073,6 +2076,70 @@ QDF_STATUS dp_rx_eapol_deliver_to_stack(struct dp_soc *soc,
 #define dp_rx_msdu_stats_update_prot_cnts(vdev_hdl, nbuf, txrx_peer)
 #endif
 
+#ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+/**
+ * dp_rx_rates_stats_update() - update rate stats
+ * from rx msdu.
+ * @soc: datapath soc handle
+ * @nbuf: received msdu buffer
+ * @rx_tlv_hdr: rx tlv header
+ * @txrx_peer: datapath txrx_peer handle
+ * @sgi: Short Guard Interval
+ * @mcs: Modulation and Coding Set
+ * @nss: Number of Spatial Streams
+ * @bw: BandWidth
+ * @pkt_type: Corresponds to preamble
+ *
+ * To be precisely record rates, following factors are considered:
+ * Exclude specific frames, ARP, DHCP, ssdp, etc.
+ * Make sure to affect rx throughput as least as possible.
+ *
+ * Return: void
+ */
+static void
+dp_rx_rates_stats_update(struct dp_soc *soc, qdf_nbuf_t nbuf,
+			 uint8_t *rx_tlv_hdr, struct dp_txrx_peer *txrx_peer,
+			 uint32_t sgi, uint32_t mcs,
+			 uint32_t nss, uint32_t bw, uint32_t pkt_type)
+{
+	uint32_t rix;
+	uint16_t ratecode;
+	uint32_t avg_rx_rate;
+	uint32_t ratekbps;
+	enum cdp_punctured_modes punc_mode = NO_PUNCTURE;
+
+	if (soc->high_throughput ||
+	    dp_rx_data_is_specific(soc->hal_soc, rx_tlv_hdr, nbuf)) {
+		return;
+	}
+
+	DP_PEER_EXTD_STATS_UPD(txrx_peer, rx.rx_rate, mcs);
+
+	/* here pkt_type corresponds to preamble */
+	ratekbps = dp_getrateindex(sgi,
+				   mcs,
+				   nss,
+				   pkt_type,
+				   bw,
+				   punc_mode,
+				   &rix,
+				   &ratecode);
+	DP_PEER_EXTD_STATS_UPD(txrx_peer, rx.last_rx_rate, ratekbps);
+	avg_rx_rate =
+		dp_ath_rate_lpf(txrx_peer->stats.extd_stats.rx.avg_rx_rate,
+				ratekbps);
+	DP_PEER_EXTD_STATS_UPD(txrx_peer, rx.avg_rx_rate, avg_rx_rate);
+}
+#else
+static void
+dp_rx_rates_stats_update(struct dp_soc *soc, qdf_nbuf_t nbuf,
+			 uint8_t *rx_tlv_hdr, struct dp_txrx_peer *txrx_peer,
+			 uint32_t sgi, uint32_t mcs,
+			 uint32_t nss, uint32_t bw, uint32_t pkt_type)
+{
+}
+#endif /* FEATURE_RX_LINKSPEED_ROAM_TRIGGER */
+
 #ifndef QCA_ENHANCED_STATS_SUPPORT
 /**
  * dp_rx_msdu_extd_stats_update(): Update Rx extended path stats for peer
@@ -2141,6 +2208,9 @@ void dp_rx_msdu_extd_stats_update(struct dp_soc *soc, qdf_nbuf_t nbuf,
 		DP_PEER_EXTD_STATS_INC(txrx_peer,
 				       rx.pkt_type[pkt_type].mcs_count[dst_mcs_idx],
 				       1);
+
+	dp_rx_rates_stats_update(soc, nbuf, rx_tlv_hdr, txrx_peer,
+				 sgi, mcs, nss, bw, pkt_type);
 }
 #else
 static inline

+ 58 - 0
dp/wifi3.0/dp_rx.h

@@ -279,6 +279,64 @@ bool dp_rx_deliver_special_frame(struct dp_soc *soc, struct dp_txrx_peer *peer,
 }
 #endif
 
+#ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+/**
+ * dp_rx_data_is_specific() - Used to exclude specific frames
+ *                            not practical for getting rx
+ *                            stats like rate, mcs, nss, etc.
+ *
+ * @hal-soc_hdl: soc handler
+ * @rx_tlv_hdr: rx tlv header
+ * @nbuf: RX skb pointer
+ *
+ * Return: true - a specific frame  not suitable
+ *                for getting rx stats from it.
+ *         false - a common frame suitable for
+ *                 getting rx stats from it.
+ */
+static inline
+bool dp_rx_data_is_specific(hal_soc_handle_t hal_soc_hdl,
+			    uint8_t *rx_tlv_hdr,
+			    qdf_nbuf_t nbuf)
+{
+	if (qdf_unlikely(qdf_nbuf_is_da_mcbc(nbuf)))
+		return true;
+
+	if (!hal_rx_tlv_first_mpdu_get(hal_soc_hdl, rx_tlv_hdr))
+		return true;
+
+	if (!hal_rx_msdu_end_first_msdu_get(hal_soc_hdl, rx_tlv_hdr))
+		return true;
+
+	/* ARP, EAPOL is neither IPV6 ETH nor IPV4 ETH from L3 level */
+	if (qdf_likely(hal_rx_tlv_l3_type_get(hal_soc_hdl, rx_tlv_hdr) ==
+	    QDF_NBUF_TRAC_IPV4_ETH_TYPE)) {
+		if (qdf_nbuf_is_ipv4_dhcp_pkt(nbuf))
+			return true;
+	} else if (qdf_likely(hal_rx_tlv_l3_type_get(hal_soc_hdl, rx_tlv_hdr) ==
+		   QDF_NBUF_TRAC_IPV6_ETH_TYPE)) {
+		if (qdf_nbuf_is_ipv6_dhcp_pkt(nbuf))
+			return true;
+	} else {
+		return true;
+	}
+	return false;
+}
+#else
+static inline
+bool dp_rx_data_is_specific(hal_soc_handle_t hal_soc_hdl,
+			    uint8_t *rx_tlv_hdr,
+			    qdf_nbuf_t nbuf)
+
+{
+	/*
+	 * default return is true to make sure that rx stats
+	 * will not be handled when this feature is disabled
+	 */
+	return true;
+}
+#endif /* FEATURE_RX_LINKSPEED_ROAM_TRIGGER */
+
 #ifndef QCA_HOST_MODE_WIFI_DISABLED
 #ifdef DP_RX_DISABLE_NDI_MDNS_FORWARDING
 static inline

+ 4 - 0
dp/wifi3.0/dp_types.h

@@ -2441,6 +2441,10 @@ struct dp_soc {
 	/* PPDU to link_id mapping parameters */
 	uint8_t link_id_offset;
 	uint8_t link_id_bits;
+#ifdef FEATURE_RX_LINKSPEED_ROAM_TRIGGER
+	/* A flag using to decide the switch of rx link speed  */
+	bool high_throughput;
+#endif
 };
 
 #ifdef IPA_OFFLOAD