Переглянути джерело

qcacmn: Support for MIN rates for criticial frames

Add support in BE to send special frames(EAPOL, ARP, DHCP) at minimum
rates.

Change-Id: I2c141cd8ef16d93fb9e99d7c48dd921913627b0b
CRs-Fixed: 3114311
Mohit Khanna 3 роки тому
батько
коміт
211fb195c9

+ 9 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -865,6 +865,14 @@ typedef qdf_nbuf_t (*ol_txrx_tx_exc_fp)(struct cdp_soc_t *soc, uint8_t vdev_id,
  */
 typedef void (*ol_txrx_completion_fp)(qdf_nbuf_t skb,
 				      void *osif_dev, uint16_t flag);
+
+/**
+ * ol_txrx_classify_critical_pkt_fp - classification cb for critical frames
+ * @osif_dev: the virtual device's OS shim object
+ * @skb: skb data
+ */
+typedef void (*ol_txrx_classify_critical_pkt_fp)(void *osif_dev,
+						 qdf_nbuf_t skb);
 /**
  * ol_txrx_tx_flow_control_fp - tx flow control notification
  * function from txrx to OS shim
@@ -1066,6 +1074,7 @@ struct ol_txrx_ops {
 		ol_txrx_tx_exc_fp     tx_exception;
 		ol_txrx_tx_free_ext_fp tx_free_ext;
 		ol_txrx_completion_fp tx_comp;
+		ol_txrx_classify_critical_pkt_fp tx_classify_critical_pkt_cb;
 	} tx;
 
 	/* rx function pointers - specified by OS shim, stored by txrx */

+ 47 - 0
dp/wifi3.0/be/dp_be_tx.c

@@ -368,6 +368,50 @@ static inline uint8_t dp_tx_get_rbm_id_be(struct dp_soc *soc,
 	return rbm;
 }
 #endif
+#ifdef QCA_SUPPORT_TX_MIN_RATES_FOR_SPECIAL_FRAMES
+
+/*
+ * dp_tx_set_min_rates_for_critical_frames()- sets min-rates for critical pkts
+ * @dp_soc - DP soc structure pointer
+ * @hal_tx_desc - HAL descriptor where fields are set
+ * nbuf - skb to be considered for min rates
+ *
+ * The function relies on upper layers to set QDF_NBUF_CB_TX_EXTRA_IS_CRITICAL
+ * and uses it to determine if the frame is critical. For a critical frame,
+ * flow override bits are set to classify the frame into HW's high priority
+ * queue. The HW will pick pre-configured min rates for such packets.
+ *
+ * Return - None
+ */
+static void
+dp_tx_set_min_rates_for_critical_frames(struct dp_soc *soc,
+					uint32_t *hal_tx_desc,
+					qdf_nbuf_t nbuf)
+{
+/*
+ * Critical frames should be queued to the high priority queue for the TID on
+ * on which they are sent out (for the concerned peer).
+ * FW is using HTT_MSDU_Q_IDX 2 for HOL (high priority) queue.
+ * htt_msdu_idx = (2 * who_classify_info_sel) + flow_override
+ * Hence, using who_classify_info_sel = 1, flow_override = 0 to select
+ * HOL queue.
+ */
+	if (QDF_NBUF_CB_TX_EXTRA_IS_CRITICAL(nbuf)) {
+		hal_tx_desc_set_flow_override_enable(hal_tx_desc, 1);
+		hal_tx_desc_set_flow_override(hal_tx_desc, 0);
+		hal_tx_desc_set_who_classify_info_sel(hal_tx_desc, 1);
+		hal_tx_desc_set_tx_notify_frame(hal_tx_desc,
+						TX_SEMI_HARD_NOTIFY_E);
+	}
+}
+#else
+static inline void
+dp_tx_set_min_rates_for_critical_frames(struct dp_soc *soc,
+					uint32_t *hal_tx_desc_cached,
+					qdf_nbuf_t nbuf)
+{
+}
+#endif
 
 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) && \
 	defined(WLAN_MCAST_MLO)
@@ -534,6 +578,9 @@ dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
 	if (tid != HTT_TX_EXT_TID_INVALID)
 		hal_tx_desc_set_hlos_tid(hal_tx_desc_cached, tid);
 
+	dp_tx_set_min_rates_for_critical_frames(soc, hal_tx_desc_cached,
+						tx_desc->nbuf);
+
 	if (qdf_unlikely(vdev->pdev->delay_stats_flag) ||
 	    qdf_unlikely(wlan_cfg_is_peer_ext_stats_enabled(soc->wlan_cfg_ctx)) ||
 	    qdf_unlikely(soc->rdkstats_enabled) ||

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

@@ -6471,6 +6471,8 @@ static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc_hdl,
 	vdev->osif_tx_free_ext = txrx_ops->tx.tx_free_ext;
 	vdev->tx_comp = txrx_ops->tx.tx_comp;
 	vdev->stats_cb = txrx_ops->rx.stats_rx;
+	vdev->tx_classify_critical_pkt_cb =
+		txrx_ops->tx.tx_classify_critical_pkt_cb;
 #ifdef notyet
 #if ATH_SUPPORT_WAPI
 	vdev->osif_check_wai = txrx_ops->rx.wai_check;

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

@@ -804,6 +804,35 @@ void dp_rx_da_learn(struct dp_soc *soc, uint8_t *rx_tlv_hdr,
 }
 #endif
 
+#ifdef QCA_SUPPORT_TX_MIN_RATES_FOR_SPECIAL_FRAMES
+/*
+ * dp_classify_critical_pkts() - API for marking critical packets
+ * @soc: dp_soc context
+ * @vdev: vdev on which packet is to be sent
+ * @nbuf: nbuf that has to be classified
+ *
+ * The function parses the packet, identifies whether its a critical frame and
+ * marks QDF_NBUF_CB_TX_EXTRA_IS_CRITICAL bit in qdf_nbuf_cb for the nbuf.
+ * Code for marking which frames are CRITICAL is accessed via callback.
+ * EAPOL, ARP, DHCP, DHCPv6, ICMPv6 NS/NA are the typical critical frames.
+ *
+ * Return: None
+ */
+static
+void dp_classify_critical_pkts(struct dp_soc *soc, struct dp_vdev *vdev,
+			       qdf_nbuf_t nbuf)
+{
+	if (vdev->tx_classify_critical_pkt_cb)
+		vdev->tx_classify_critical_pkt_cb(vdev->osif_vdev, nbuf);
+}
+#else
+static inline
+void dp_classify_critical_pkts(struct dp_soc *soc, struct dp_vdev *vdev,
+			       qdf_nbuf_t nbuf)
+{
+}
+#endif
+
 /*
  * dp_rx_intrabss_mcbc_fwd() - Does intrabss forward for mcast packets
  *
@@ -840,8 +869,12 @@ bool dp_rx_intrabss_mcbc_fwd(struct dp_soc *soc, struct dp_txrx_peer *ta_peer,
 		return false;
 
 	len = QDF_NBUF_CB_RX_PKT_LEN(nbuf);
+
 	qdf_nbuf_set_tx_fctx_type(nbuf_copy, &ta_peer->peer_id,
 				  CB_FTYPE_INTRABSS_FWD);
+
+	dp_classify_critical_pkts(soc, ta_peer->vdev, nbuf_copy);
+
 	if (dp_tx_send((struct cdp_soc_t *)soc,
 		       ta_peer->vdev->vdev_id, nbuf_copy)) {
 		DP_PEER_PER_PKT_STATS_INC_PKT(ta_peer, rx.intra_bss.fail, 1,
@@ -899,6 +932,8 @@ bool dp_rx_intrabss_ucast_fwd(struct dp_soc *soc, struct dp_txrx_peer *ta_peer,
 		}
 	}
 
+	dp_classify_critical_pkts(soc, ta_peer->vdev, nbuf);
+
 	if (!dp_tx_send((struct cdp_soc_t *)soc,
 			tx_vdev_id, nbuf)) {
 		DP_PEER_PER_PKT_STATS_INC_PKT(ta_peer, rx.intra_bss.pkts, 1,

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

@@ -3002,6 +3002,9 @@ struct dp_vdev {
 
 	ol_txrx_get_tsf_time get_tsf_time;
 
+	/* callback to classify critical packets */
+	ol_txrx_classify_critical_pkt_fp tx_classify_critical_pkt_cb;
+
 	/* deferred vdev deletion state */
 	struct {
 		/* VDEV delete pending */