summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cds/inc/cds_config.h2
-rw-r--r--core/dp/htt/htt.c4
-rw-r--r--core/dp/htt/htt_h2t.c92
-rw-r--r--core/dp/htt/htt_internal.h4
-rw-r--r--core/dp/ol/inc/ol_cfg.h31
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h12
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c7
-rw-r--r--core/hdd/src/wlan_hdd_main.c1
-rw-r--r--core/wma/src/wma_main.c5
9 files changed, 158 insertions, 0 deletions
diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h
index e479eadb8c5f..892181b9fc43 100644
--- a/core/cds/inc/cds_config.h
+++ b/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 ) */
diff --git a/core/dp/htt/htt.c b/core/dp/htt/htt.c
index 5962f24152c5..987eeecc7d38 100644
--- a/core/dp/htt/htt.c
+++ b/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);
diff --git a/core/dp/htt/htt_h2t.c b/core/dp/htt/htt_h2t.c
index 6c9ec2bb9a92..b2a8c0393d37 100644
--- a/core/dp/htt/htt_h2t.c
+++ b/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,
diff --git a/core/dp/htt/htt_internal.h b/core/dp/htt/htt_internal.h
index e5d009dc587b..69fe95e44cb5 100644
--- a/core/dp/htt/htt_internal.h
+++ b/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);
diff --git a/core/dp/ol/inc/ol_cfg.h b/core/dp/ol/inc/ol_cfg.h
index 0fbab7f14c40..6f776dd252e5 100644
--- a/core/dp/ol/inc/ol_cfg.h
+++ b/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_ */
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index e1e62e9eb6fd..4a85734d1569 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -2798,6 +2798,17 @@ typedef enum {
#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
* APPS wake up and save more power.
@@ -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;
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index 2859d7552885..71b3dfb8e91b 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/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,
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index 2bb04036b553..e445f1586ddb 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/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);
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index f60f0a545754..30a136907f99 100644
--- a/core/wma/src/wma_main.c
+++ b/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)->