Browse Source

qcacmn: Support REO2SW ring pointer update threshold configuration

Support REO2SW ring pointer update threshold configuration,
it is helpful for PCIe utilization improvement.
timer based threshold - M: issue pointer updates when M micro
seconds has elapsed.
number based threshold - N: issue pointer updates when N entries
updates occur.

Change-Id: I49ed388520fd52e97e303d6ea9c04ced6cb5cf5f
CRs-Fixed: 3420101
Jinwei Chen 2 năm trước cách đây
mục cha
commit
c2c0f7f7f9

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

@@ -1891,6 +1891,37 @@ static void dp_print_peer_table(struct dp_vdev *vdev)
 			     DP_MOD_ID_GENERIC_STATS);
 }
 
+/**
+ * dp_srng_configure_pointer_update_thresholds() - Retrieve pointer
+ * update threshold value from wlan_cfg_ctx
+ * @soc: device handle
+ * @ring_params: per ring specific parameters
+ * @ring_type: Ring type
+ * @ring_num: Ring number for a given ring type
+ * @num_entries: number of entries to fill
+ *
+ * Fill the ring params with the pointer update threshold
+ * configuration parameters available in wlan_cfg_ctx
+ *
+ * Return: None
+ */
+static void
+dp_srng_configure_pointer_update_thresholds(
+				struct dp_soc *soc,
+				struct hal_srng_params *ring_params,
+				int ring_type, int ring_num,
+				int num_entries)
+{
+	if (ring_type == REO_DST) {
+		ring_params->pointer_timer_threshold =
+			wlan_cfg_get_pointer_timer_threshold_rx(
+						soc->wlan_cfg_ctx);
+		ring_params->pointer_num_threshold =
+			wlan_cfg_get_pointer_num_threshold_rx(
+						soc->wlan_cfg_ctx);
+	}
+}
+
 #ifdef WLAN_DP_PER_RING_TYPE_CONFIG
 /**
  * dp_srng_configure_interrupt_thresholds() - Retrieve interrupt
@@ -2407,6 +2438,9 @@ QDF_STATUS dp_srng_init_idx(struct dp_soc *soc, struct dp_srng *srng,
 					       srng->num_entries);
 
 	dp_srng_set_nf_thresholds(soc, srng, &ring_params);
+	dp_srng_configure_pointer_update_thresholds(soc, &ring_params,
+						    ring_type, ring_num,
+						    srng->num_entries);
 
 	if (srng->cached)
 		ring_params.flags |= HAL_SRNG_CACHED_DESC;

+ 4 - 0
hal/wifi3.0/hal_api.h

@@ -1021,6 +1021,10 @@ struct hal_srng_params {
 	/* Safe threshold */
 	uint16_t safe_thresh;
 #endif
+	/* Timer threshold to issue ring pointer update - in micro seconds */
+	uint16_t pointer_timer_threshold;
+	/* Number threshold of ring entries to issue pointer update */
+	uint8_t pointer_num_threshold;
 };
 
 /**

+ 7 - 0
hal/wifi3.0/hal_hw_headers.h

@@ -193,6 +193,7 @@
 #define ID_GROUP R0
 #define STATUS_GROUP R0
 #define MISC_GROUP R0
+#define MISC_1_GROUP R0
 #define HP_ADDR_LSB_GROUP R0
 #define HP_ADDR_MSB_GROUP R0
 #define PRODUCER_INT_SETUP_GROUP R0
@@ -244,13 +245,19 @@
 
 #define _SRNG_DST_FLD(_reg_group, _reg_fld) \
 	HAL_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg_fld
+#define _SRNG_DST_HW_FLD(_reg_group, _reg_fld) \
+	HWIO_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg_fld
 #define _SRNG_SRC_FLD(_reg_group, _reg_fld) \
 	HWIO_TCL_ ## _reg_group ## _SW2TCL1_RING_ ## _reg_fld
 
 #define _SRNG_FLD(_reg_group, _reg_fld, _dir) \
 	_SRNG_ ## _dir ## _FLD(_reg_group, _reg_fld)
+#define _SRNG_HW_FLD(_reg_group, _reg_fld, _dir) \
+	_SRNG_ ## _dir ## _HW_FLD(_reg_group, _reg_fld)
 
 #define SRNG_DST_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, DST)
+#define SRNG_DST_HW_FLD(_reg, _f) \
+	_SRNG_HW_FLD(_reg ## _GROUP, _reg ## _ ## _f, DST)
 #define SRNG_SRC_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, SRC)
 
 #define SRNG_SRC_R0_START_OFFSET SRNG_SRC_REG_OFFSET(BASE_LSB, R0)

+ 5 - 0
hal/wifi3.0/hal_internal.h

@@ -368,6 +368,7 @@ enum SRNG_REGISTERS {
 	DST_MSI1_BASE_LSB,
 	DST_MSI1_BASE_MSB,
 	DST_MSI1_DATA,
+	DST_MISC_1,
 #ifdef CONFIG_BERYLLIUM
 	DST_MSI2_BASE_LSB,
 	DST_MSI2_BASE_MSB,
@@ -800,6 +801,10 @@ struct hal_srng {
 #ifdef WLAN_DP_SRNG_USAGE_WM_TRACKING
 	struct hal_srng_high_wm_info high_wm;
 #endif
+	/* Timer threshold to issue ring pointer update - in micro seconds */
+	uint16_t pointer_timer_threshold;
+	/* Number threshold of ring entries to issue pointer update */
+	uint8_t pointer_num_threshold;
 };
 
 /* HW SRNG configuration table */

+ 5 - 0
hal/wifi3.0/hal_srng.c

@@ -1559,6 +1559,11 @@ void *hal_srng_setup_idx(void *hal_soc, int ring_type, int ring_num, int mac_id,
 	srng->intr_timer_thres_us = ring_params->intr_timer_thres_us;
 	srng->intr_batch_cntr_thres_entries =
 		ring_params->intr_batch_cntr_thres_entries;
+	srng->pointer_timer_threshold =
+		ring_params->pointer_timer_threshold;
+	srng->pointer_num_threshold =
+		ring_params->pointer_num_threshold;
+
 	if (!idle_check)
 		srng->prefetch_timer = ring_params->prefetch_timer;
 	srng->hal_soc = hal_soc;

+ 77 - 1
hal/wifi3.0/kiwi/hal_kiwi.c

@@ -2009,10 +2009,85 @@ static QDF_STATUS hal_rx_reo_ent_get_src_link_id_kiwi(hal_rxdma_desc_t rx_desc,
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef QCA_WIFI_KIWI_V2
+/**
+ * hal_srng_dst_hw_init_misc_1_kiwi() - Function to initialize MISC_1 register
+ *                                      of destination ring HW
+ * @srng: SRNG ring pointer
+ *
+ * Return: None
+ */
+static inline
+void hal_srng_dst_hw_init_misc_1_kiwi(struct hal_srng *srng)
+{
+	uint32_t reg_val = 0;
+
+	/* number threshold for pointer update */
+	if (srng->pointer_num_threshold)
+		reg_val |= SRNG_SM(SRNG_DST_HW_FLD(MISC_1,
+						   NUM_THRESHOLD_TO_UPDATE),
+				   srng->pointer_num_threshold);
+	/* timer threshold for pointer update */
+	if (srng->pointer_timer_threshold)
+		reg_val |= SRNG_SM(SRNG_DST_HW_FLD(MISC_1,
+						   TIME_THRESHOLD_TO_UPDATE),
+				   srng->pointer_timer_threshold);
+
+	if (reg_val)
+		SRNG_DST_REG_WRITE(srng, MISC_1, reg_val);
+}
+
+/**
+ * hal_srng_hw_reg_offset_init_misc_1_kiwi() - Initialize the HW srng register
+ *                                             offset of MISC_1
+ * @hal_soc: HAL Soc handle
+ *
+ * Return: None
+ */
+static inline
+void hal_srng_hw_reg_offset_init_misc_1_kiwi(struct hal_soc *hal_soc)
+{
+	int32_t *hw_reg_offset = hal_soc->hal_hw_reg_offset;
+
+	hw_reg_offset[DST_MISC_1] = REG_OFFSET(DST, MISC_1);
+}
+#else
+static inline
+void hal_srng_dst_hw_init_misc_1_kiwi(struct hal_srng *srng)
+{
+}
+
+static inline
+void hal_srng_hw_reg_offset_init_misc_1_kiwi(struct hal_soc *hal_soc)
+{
+}
+#endif
+
+/**
+ * hal_srng_dst_hw_init_kiwi() - Function to initialize SRNG
+ *                               destination ring HW
+ * @hal_soc: HAL SOC handle
+ * @srng: SRNG ring pointer
+ * @idle_check: Check if ring is idle
+ * @idx: Ring index
+ *
+ * Return: None
+ */
+static inline
+void hal_srng_dst_hw_init_kiwi(struct hal_soc *hal_soc,
+			       struct hal_srng *srng,
+			       bool idle_check,
+			       uint32_t idx)
+{
+	hal_srng_dst_hw_init_misc_1_kiwi(srng);
+
+	hal_srng_dst_hw_init_generic(hal_soc, srng, idle_check, idx);
+}
+
 static void hal_hw_txrx_ops_attach_kiwi(struct hal_soc *hal_soc)
 {
 	/* init and setup */
-	hal_soc->ops->hal_srng_dst_hw_init = hal_srng_dst_hw_init_generic;
+	hal_soc->ops->hal_srng_dst_hw_init = hal_srng_dst_hw_init_kiwi;
 	hal_soc->ops->hal_srng_src_hw_init = hal_srng_src_hw_init_generic;
 	hal_soc->ops->hal_get_hw_hptp = hal_get_hw_hptp_generic;
 	hal_soc->ops->hal_get_window_address = hal_get_window_address_kiwi;
@@ -2706,6 +2781,7 @@ static inline void hal_srng_hw_reg_offset_init_kiwi(struct hal_soc *hal_soc)
 	hw_reg_offset[DST_MSI2_DATA] = REG_OFFSET(DST, MSI2_DATA),
 	hw_reg_offset[DST_PRODUCER_INT2_SETUP] =
 					REG_OFFSET(DST, PRODUCER_INT2_SETUP);
+	hal_srng_hw_reg_offset_init_misc_1_kiwi(hal_soc);
 }
 
 void hal_kiwi_attach(struct hal_soc *hal_soc)

+ 13 - 1
wlan_cfg/cfg_dp.h

@@ -1354,6 +1354,16 @@
 	CFG_INI_BOOL("tx_litemon_sw_peer_filtering", false, \
 		     "Enable SW based tx monitor peer fitlering")
 
+#define CFG_DP_POINTER_TIMER_THRESHOLD_RX \
+	CFG_INI_UINT("dp_rx_ptr_timer_threshold", \
+	0, 0xFFFF, 0, \
+	CFG_VALUE_OR_DEFAULT, "RX pointer update timer threshold")
+
+#define CFG_DP_POINTER_NUM_THRESHOLD_RX \
+	CFG_INI_UINT("dp_rx_ptr_num_threshold", \
+	0, 63, 0, \
+	CFG_VALUE_OR_DEFAULT, "RX pointer update entries number threshold")
+
 /*
  * <ini>
  * dp_rx_fisa_enable - Control Rx datapath FISA
@@ -2015,5 +2025,7 @@
 		CFG_DP_SAWF_STATS_CONFIG \
 		CFG(CFG_DP_HANDLE_INVALID_DECAP_TYPE_DISABLE) \
 		CFG(CFG_DP_TXMON_SW_PEER_FILTERING) \
-		CFG_TX_PKT_INSPECT_FOR_ILP_CFG
+		CFG_TX_PKT_INSPECT_FOR_ILP_CFG \
+		CFG(CFG_DP_POINTER_TIMER_THRESHOLD_RX) \
+		CFG(CFG_DP_POINTER_NUM_THRESHOLD_RX)
 #endif /* _CFG_DP_H_ */

+ 16 - 0
wlan_cfg/wlan_cfg.c

@@ -3119,6 +3119,10 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc)
 			cfg_get(psoc, CFG_DP_HANDLE_INVALID_DECAP_TYPE_DISABLE);
 	wlan_cfg_ctx->txmon_sw_peer_filtering =
 			cfg_get(psoc, CFG_DP_TXMON_SW_PEER_FILTERING);
+	wlan_cfg_ctx->pointer_timer_threshold_rx =
+			cfg_get(psoc, CFG_DP_POINTER_TIMER_THRESHOLD_RX);
+	wlan_cfg_ctx->pointer_num_threshold_rx =
+			cfg_get(psoc, CFG_DP_POINTER_NUM_THRESHOLD_RX);
 	wlan_soc_tx_packet_inspect_attach(psoc, wlan_cfg_ctx);
 
 	return wlan_cfg_ctx;
@@ -4465,3 +4469,15 @@ bool wlan_cfg_get_txmon_sw_peer_filtering(struct wlan_cfg_dp_soc_ctxt *cfg)
 }
 
 qdf_export_symbol(wlan_cfg_get_txmon_sw_peer_filtering);
+
+uint16_t
+wlan_cfg_get_pointer_timer_threshold_rx(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return cfg->pointer_timer_threshold_rx;
+}
+
+uint8_t
+wlan_cfg_get_pointer_num_threshold_rx(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return cfg->pointer_num_threshold_rx;
+}

+ 25 - 0
wlan_cfg/wlan_cfg.h

@@ -335,6 +335,8 @@ struct wlan_srng_cfg {
  *                                         type handling is disabled
  * @tx_pkt_inspect_for_ilp: flag to indicate if TX packet inspection for HW
  *			    based ILP feature is enabled
+ * @pointer_timer_threshold_rx: RX REO2SW ring pointer update timer threshold
+ * @pointer_num_threshold_rx: RX REO2SW ring pointer update entries threshold
  */
 struct wlan_cfg_dp_soc_ctxt {
 	int num_int_ctxts;
@@ -531,6 +533,8 @@ struct wlan_cfg_dp_soc_ctxt {
 #ifdef DP_TX_PACKET_INSPECT_FOR_ILP
 	bool tx_pkt_inspect_for_ilp;
 #endif
+	uint16_t pointer_timer_threshold_rx;
+	uint8_t pointer_num_threshold_rx;
 };
 
 /**
@@ -2451,4 +2455,25 @@ uint8_t wlan_cfg_get_napi_scale_factor(struct wlan_cfg_dp_soc_ctxt *cfg);
 void
 wlan_cfg_soc_update_tgt_params(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx,
 			       struct cdp_ctrl_objmgr_psoc *ctrl_obj);
+
+/**
+ * wlan_cfg_get_pointer_timer_threshold_rx() - Get timer threshold for RX
+ *                                             pointer update
+ * @cfg: soc configuration context
+ *
+ * Return: timer threshold for RX REO Dest ring  pointer update
+ */
+uint16_t
+wlan_cfg_get_pointer_timer_threshold_rx(struct wlan_cfg_dp_soc_ctxt *cfg);
+
+/**
+ * wlan_cfg_get_pointer_num_threshold_rx() - Get number threshold for RX
+ *                                           pointer update
+ * @cfg: soc configuration context
+ *
+ * Return: entries number threshold for RX REO Dest ring  pointer update
+ */
+uint8_t
+wlan_cfg_get_pointer_num_threshold_rx(struct wlan_cfg_dp_soc_ctxt *cfg);
+
 #endif /*__WLAN_CFG_H*/