Prechádzať zdrojové kódy

qcacld-3.0: Add option to control Rx flow steering

Add ini configuration to enable/disable Rx flow steering.
Add HTT message to configure RX flow steering.

Change-Id: I80aab262c754716b28bfdae561d1cbf5e1d38e4d
CRs-Fixed: 1055179
Manjunathappa Prakash 8 rokov pred
rodič
commit
fff753c12e

+ 2 - 0
core/cds/inc/cds_config.h

@@ -95,6 +95,7 @@ enum cfg_sub_20_channel_width {
  * @tx_chain_mask_cck: Tx chain mask enabled or not
  * @self_gen_frm_pwr: Self gen from power
  * @sub_20_channel_width: Sub 20 MHz ch width, ini intersected with fw cap
+ * @flow_steering_enabled: Receive flow steering.
  * Structure for holding cds ini parameters.
  */
 
@@ -145,5 +146,6 @@ struct cds_config_info {
 	bool tx_chain_mask_cck;
 	uint16_t self_gen_frm_pwr;
 	enum cfg_sub_20_channel_width sub_20_channel_width;
+	bool flow_steering_enabled;
 };
 #endif /* !defined( __CDS_CONFIG_H ) */

+ 4 - 0
core/dp/htt/htt.c

@@ -50,6 +50,7 @@
 #define HTT_HTC_PKT_POOL_INIT_SIZE 100  /* enough for a large A-MPDU */
 
 QDF_STATUS(*htt_h2t_rx_ring_cfg_msg)(struct htt_pdev_t *pdev);
+QDF_STATUS(*htt_h2t_rx_ring_rfs_cfg_msg)(struct htt_pdev_t *pdev);
 
 #ifdef IPA_OFFLOAD
 A_STATUS htt_ipa_config(htt_pdev_handle pdev, A_STATUS status)
@@ -425,6 +426,7 @@ htt_attach(struct htt_pdev_t *pdev, int desc_pool_size)
 					- HTT_RX_IND_HL_BYTES);
 
 		htt_h2t_rx_ring_cfg_msg = htt_h2t_rx_ring_cfg_msg_hl;
+		htt_h2t_rx_ring_rfs_cfg_msg = htt_h2t_rx_ring_rfs_cfg_msg_hl;
 
 		/* initialize the txrx credit count */
 		ol_tx_target_credit_update(
@@ -497,6 +499,7 @@ htt_attach(struct htt_pdev_t *pdev, int desc_pool_size)
 		pdev->rx_fw_desc_offset = RX_STD_DESC_FW_MSDU_OFFSET;
 
 		htt_h2t_rx_ring_cfg_msg = htt_h2t_rx_ring_cfg_msg_ll;
+		htt_h2t_rx_ring_rfs_cfg_msg = htt_h2t_rx_ring_rfs_cfg_msg_ll;
 	}
 
 	return 0;
@@ -533,6 +536,7 @@ A_STATUS htt_attach_target(htt_pdev_handle pdev)
 	 * handshaking.
 	 */
 
+	status = htt_h2t_rx_ring_rfs_cfg_msg(pdev);
 	status = htt_h2t_rx_ring_cfg_msg(pdev);
 	status = HTT_IPA_CONFIG(pdev, status);
 

+ 92 - 0
core/dp/htt/htt_h2t.c

@@ -292,6 +292,85 @@ A_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev)
 	return A_OK;
 }
 
+#if defined(HELIUMPLUS)
+/**
+ * htt_h2t_rx_ring_rfs_cfg_msg_ll() - Configure receive flow steering
+ * @pdev: handle to the HTT instance
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *         A_NO_MEMORY No memory fail
+ */
+QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev)
+{
+	struct htt_htc_pkt *pkt;
+	qdf_nbuf_t msg;
+	uint32_t *msg_word;
+
+	qdf_print("Receive flow steering configuration, disable gEnableFlowSteering(=0) in ini if FW doesnot support it\n");
+	pkt = htt_htc_pkt_alloc(pdev);
+	if (!pkt)
+		return QDF_STATUS_E_NOMEM; /* failure */
+
+	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
+	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
+
+	/* reserve room for the HTC header */
+	msg = qdf_nbuf_alloc(pdev->osdev,
+			     HTT_MSG_BUF_SIZE(HTT_RFS_CFG_REQ_BYTES),
+			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
+			     true);
+	if (!msg) {
+		htt_htc_pkt_free(pdev, pkt);
+		return QDF_STATUS_E_NOMEM; /* failure */
+	}
+	/*
+	 * Set the length of the message.
+	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
+	 * separately during the below call to qdf_nbuf_push_head.
+	 * The contribution from the HTC header is added separately inside HTC.
+	 */
+	qdf_nbuf_put_tail(msg, HTT_RFS_CFG_REQ_BYTES);
+
+	/* fill in the message contents */
+	msg_word = (uint32_t *) qdf_nbuf_data(msg);
+
+	/* rewind beyond alignment pad to get to the HTC header reserved area */
+	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
+
+	*msg_word = 0;
+	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RFS_CONFIG);
+	if (ol_cfg_is_flow_steering_enabled(pdev->ctrl_pdev)) {
+		HTT_RX_RFS_CONFIG_SET(*msg_word, 1);
+	    qdf_print("Enable Rx flow steering\n");
+	} else {
+	    qdf_print("Disable Rx flow steering\n");
+	}
+
+	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
+			       htt_h2t_send_complete_free_netbuf,
+			       qdf_nbuf_data(msg), qdf_nbuf_len(msg),
+			       pdev->htc_tx_endpoint,
+			       1); /* tag - not relevant here */
+
+	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
+	HTT_SEND_HTC_PKT(pdev, pkt);
+	return QDF_STATUS_SUCCESS;
+}
+#else
+/**
+ * htt_h2t_rx_ring_rfs_cfg_msg_ll() - Configure receive flow steering
+ * @pdev: handle to the HTT instance
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *         A_NO_MEMORY No memory fail
+ */
+QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev)
+{
+	qdf_print("Doesnot support receive flow steering configuration\n");
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* HELIUMPLUS */
+
 QDF_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev)
 {
 	struct htt_htc_pkt *pkt;
@@ -636,6 +715,19 @@ htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev)
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * htt_h2t_rx_ring_rfs_cfg_msg_hl() - Configure receive flow steering
+ * @pdev: handle to the HTT instance
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ *         A_NO_MEMORY No memory fail
+ */
+QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_hl(struct htt_pdev_t *pdev)
+{
+	qdf_print("Doesnot support Receive flow steering configuration\n");
+	return QDF_STATUS_SUCCESS;
+}
+
 int
 htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
 		      uint32_t stats_type_upload_mask,

+ 4 - 0
core/dp/htt/htt_internal.h

@@ -480,6 +480,10 @@ htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev);
 
 extern QDF_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev);
 
+extern QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev);
+
+extern QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_hl(struct htt_pdev_t *pdev);
+
 extern QDF_STATUS htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev);
 
 extern QDF_STATUS (*htt_h2t_rx_ring_cfg_msg)(struct htt_pdev_t *pdev);

+ 31 - 0
core/dp/ol/inc/ol_cfg.h

@@ -93,6 +93,7 @@ struct txrx_pdev_cfg_t {
 	uint32_t tx_flow_stop_queue_th;
 	uint32_t tx_flow_start_queue_offset;
 #endif
+	bool flow_steering_enabled;
 };
 
 /**
@@ -546,4 +547,34 @@ static inline unsigned int ol_cfg_ipa_uc_tx_partition_base(
 	return 0;
 }
 #endif /* IPA_OFFLOAD */
+
+/**
+ * ol_set_cfg_flow_steering - Set Rx flow steering config based on CFG ini
+ *			      config.
+ *
+ * @pdev - handle to the physical device
+ * @val - 0 - disable, 1 - enable
+ *
+ * Return: None
+ */
+static inline void ol_set_cfg_flow_steering(ol_pdev_handle pdev, uint8_t val)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev;
+
+	cfg->flow_steering_enabled = val;
+}
+
+/**
+ * ol_cfg_is_flow_steering_enabled - Return Rx flow steering config.
+ *
+ * @pdev - handle to the physical device
+ *
+ * Return: value of configured flow steering value.
+ */
+static inline uint8_t ol_cfg_is_flow_steering_enabled(ol_pdev_handle pdev)
+{
+	struct txrx_pdev_cfg_t *cfg = (struct txrx_pdev_cfg_t *)pdev;
+
+	return cfg->flow_steering_enabled;
+}
 #endif /* _OL_CFG__H_ */

+ 12 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -2797,6 +2797,17 @@ typedef enum {
 #define CFG_LRO_ENABLED_MAX            (1)
 #define CFG_LRO_ENABLED_DEFAULT        (0)
 
+/*
+ * Enable Rx traffic flow steering to enable Rx interrupts on multiple CEs based
+ * on the flows. Different CEs<==>different IRQs<==>probably different CPUs.
+ * Parallel Rx paths.
+ * 1 - enable  0 - disable
+ */
+#define CFG_FLOW_STEERING_ENABLED_NAME        "gEnableFlowSteering"
+#define CFG_FLOW_STEERING_ENABLED_MIN         (0)
+#define CFG_FLOW_STEERING_ENABLED_MAX         (1)
+#define CFG_FLOW_STEERING_ENABLED_DEFAULT     (0)
+
 /*
  * In static display use case when APPS is in stand alone power save mode enable
  * active offload mode which helps FW to filter out MC/BC data packets to avoid
@@ -4092,6 +4103,7 @@ struct hdd_config {
 	bool sendDeauthBeforeCon;
 	bool tso_enable;
 	bool lro_enable;
+	bool flow_steering_enable;
 	bool active_mode_offload;
 	bool bpf_packet_filter_enable;
 	uint32_t fine_time_meas_cap;

+ 7 - 0
core/hdd/src/wlan_hdd_cfg.c

@@ -3520,6 +3520,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_BPF_PACKET_FILTER_OFFLOAD_MIN,
 		     CFG_BPF_PACKET_FILTER_OFFLOAD_MAX),
 
+	REG_VARIABLE(CFG_FLOW_STEERING_ENABLED_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, flow_steering_enable,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_FLOW_STEERING_ENABLED_DEFAULT,
+		     CFG_FLOW_STEERING_ENABLED_MIN,
+		     CFG_FLOW_STEERING_ENABLED_MAX),
+
 	REG_VARIABLE(CFG_ACTIVE_MODE_OFFLOAD, WLAN_PARAM_Integer,
 		     struct hdd_config, active_mode_offload,
 		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,

+ 1 - 0
core/hdd/src/wlan_hdd_main.c

@@ -6640,6 +6640,7 @@ int hdd_update_cds_config(hdd_context_t *hdd_ctx)
 	cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
 	cds_cfg->max_station = hdd_ctx->config->maxNumberOfPeers;
 	cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
+	cds_cfg->flow_steering_enabled = hdd_ctx->config->flow_steering_enable;
 
 	hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
 	hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);

+ 5 - 0
core/wma/src/wma_main.c

@@ -1781,6 +1781,11 @@ QDF_STATUS wma_open(void *cds_context,
 				   ((p_cds_contextType) cds_context)->cfg_ctx,
 				   (uint8_t) cds_cfg->ap_disable_intrabss_fwd);
 
+	/* Configure Receive flow steering */
+	ol_set_cfg_flow_steering((ol_pdev_handle)
+				 ((p_cds_contextType)cds_context)->cfg_ctx,
+				 cds_cfg->flow_steering_enabled);
+
 	/* adjust the packet log enable default value based on CFG INI setting */
 	ol_set_cfg_packet_log_enabled((ol_pdev_handle)
 					((p_cds_contextType) cds_context)->