Browse Source

qcacmn: Add support for hash based rx steering

This change includes:
- Adding the hooks to send LRO and hash configuration to the firmware
- Configuring the REO remap registers

Change-Id: I6d83e2a2365647f2c7a6440bd1d4b42fa7df7eff
CRs-Fixed: 1094775
Dhanashri Atre 8 years ago
parent
commit
1404917b6e

+ 26 - 1
dp/inc/cdp_txrx_ops.h

@@ -492,6 +492,30 @@ struct cdp_pflow_ops {
 };
 #endif /* CONFIG_WIN */
 
+#define LRO_IPV4_SEED_ARR_SZ 5
+#define LRO_IPV6_SEED_ARR_SZ 11
+
+/**
+ * struct cdp_lro_config - set LRO init parameters
+ * @lro_enable: indicates whether lro is enabled
+ * @tcp_flag: If the TCP flags from the packet do not match
+ * the values in this field after masking with TCP flags mask
+ * below, packet is not LRO eligible
+ * @tcp_flag_mask: field for comparing the TCP values provided
+ * above with the TCP flags field in the received packet
+ * @toeplitz_hash_ipv4: contains seed needed to compute the flow id
+ * 5-tuple toeplitz hash for ipv4 packets
+ * @toeplitz_hash_ipv6: contains seed needed to compute the flow id
+ * 5-tuple toeplitz hash for ipv6 packets
+ */
+struct cdp_lro_hash_config {
+	uint32_t lro_enable;
+	uint32_t tcp_flag:9,
+		tcp_flag_mask:9;
+	uint32_t toeplitz_hash_ipv4[LRO_IPV4_SEED_ARR_SZ];
+	uint32_t toeplitz_hash_ipv6[LRO_IPV6_SEED_ARR_SZ];
+};
+
 struct ol_if_ops {
 	void (*peer_set_default_routing)(void *scn_handle,
 			uint8_t *peer_macaddr, uint8_t vdev_id,
@@ -513,7 +537,8 @@ struct ol_if_ops {
 			uint32_t flags);
 	void (*peer_del_wds_entry)(void *ol_soc_handle,
 			uint8_t *wds_macaddr);
-
+	QDF_STATUS (*lro_hash_config)(void *scn_handle,
+			struct cdp_lro_hash_config *lro_hash);
 	/* TODO: Add any other control path calls required to OL_IF/WMA layer */
 };
 

+ 81 - 3
dp/wifi3.0/dp_main.c

@@ -18,6 +18,7 @@
 
 #include <qdf_types.h>
 #include <qdf_lock.h>
+#include <qdf_net_types.h>
 #include <hal_api.h>
 #include <hif.h>
 #include <htt.h>
@@ -31,6 +32,7 @@
 #include <cdp_txrx_handle.h>
 #include <wlan_cfg.h>
 #include "cdp_txrx_cmn_struct.h"
+#include <qdf_util.h>
 
 #define DP_INTR_POLL_TIMER_MS	100
 #define DP_MCS_LENGTH (6*MAX_MCS)
@@ -723,6 +725,7 @@ static void dp_hw_link_desc_pool_cleanup(struct dp_soc *soc)
 static int dp_soc_cmn_setup(struct dp_soc *soc)
 {
 	int i;
+	struct hal_reo_params reo_params;
 
 	if (qdf_atomic_read(&soc->cmn_init_done))
 		return 0;
@@ -799,6 +802,9 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
 	if (!wlan_cfg_per_pdev_rx_ring(soc->wlan_cfg_ctx)) {
 		soc->num_reo_dest_rings =
 			wlan_cfg_num_reo_dest_rings(soc->wlan_cfg_ctx);
+		QDF_TRACE(QDF_MODULE_ID_DP,
+			QDF_TRACE_LEVEL_ERROR,
+			FL("num_reo_dest_rings %d\n"), soc->num_reo_dest_rings);
 		for (i = 0; i < soc->num_reo_dest_rings; i++) {
 			if (dp_srng_setup(soc, &soc->reo_dest_ring[i], REO_DST,
 				i, 0, REO_DST_RING_SIZE)) {
@@ -862,8 +868,14 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
 	}
 
 	dp_soc_interrupt_attach(soc);
+
 	/* Setup HW REO */
-	hal_reo_setup(soc->hal_soc);
+	qdf_mem_zero(&reo_params, sizeof(reo_params));
+
+	if (wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx))
+		reo_params.rx_hash_enabled = true;
+
+	hal_reo_setup(soc->hal_soc, &reo_params);
 
 	qdf_atomic_set(&soc->cmn_init_done, 1);
 	return 0;
@@ -878,6 +890,65 @@ fail0:
 
 static void dp_pdev_detach_wifi3(struct cdp_pdev *txrx_pdev, int force);
 
+static void dp_lro_hash_setup(struct dp_soc *soc)
+{
+	struct cdp_lro_hash_config lro_hash;
+
+	if (!wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx) &&
+		!wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx)) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			 FL("LRO disabled RX hash disabled"));
+		return;
+	}
+
+	qdf_mem_zero(&lro_hash, sizeof(lro_hash));
+
+	if (wlan_cfg_is_lro_enabled(soc->wlan_cfg_ctx)) {
+		lro_hash.lro_enable = 1;
+		lro_hash.tcp_flag = QDF_TCPHDR_ACK;
+		lro_hash.tcp_flag_mask = QDF_TCPHDR_FIN | QDF_TCPHDR_SYN |
+				 QDF_TCPHDR_RST | QDF_TCPHDR_ACK | QDF_TCPHDR_URG |
+				 QDF_TCPHDR_ECE | QDF_TCPHDR_CWR;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, FL("enabled"));
+		qdf_get_random_bytes(lro_hash.toeplitz_hash_ipv4,
+		 (sizeof(lro_hash.toeplitz_hash_ipv4[0]) *
+		 LRO_IPV4_SEED_ARR_SZ));
+
+	qdf_get_random_bytes(lro_hash.toeplitz_hash_ipv6,
+		 (sizeof(lro_hash.toeplitz_hash_ipv6[0]) *
+		 LRO_IPV6_SEED_ARR_SZ));
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+		 "lro_hash: lro_enable: 0x%x"
+		 "lro_hash: tcp_flag 0x%x tcp_flag_mask 0x%x",
+		 lro_hash.lro_enable, lro_hash.tcp_flag,
+		 lro_hash.tcp_flag_mask);
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+		FL("lro_hash: toeplitz_hash_ipv4:"));
+	qdf_trace_hex_dump(QDF_MODULE_ID_DP,
+		 QDF_TRACE_LEVEL_ERROR,
+		 (void *)lro_hash.toeplitz_hash_ipv4,
+		 (sizeof(lro_hash.toeplitz_hash_ipv4[0]) *
+		 LRO_IPV4_SEED_ARR_SZ));
+
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+		FL("lro_hash: toeplitz_hash_ipv6:"));
+	qdf_trace_hex_dump(QDF_MODULE_ID_DP,
+		 QDF_TRACE_LEVEL_ERROR,
+		 (void *)lro_hash.toeplitz_hash_ipv6,
+		 (sizeof(lro_hash.toeplitz_hash_ipv6[0]) *
+		 LRO_IPV6_SEED_ARR_SZ));
+
+	qdf_assert(soc->cdp_soc.ol_ops->lro_hash_config);
+
+	if (soc->cdp_soc.ol_ops->lro_hash_config)
+		(void)soc->cdp_soc.ol_ops->lro_hash_config
+			(soc->osif_soc, &lro_hash);
+}
+
 /*
 * dp_rxdma_ring_setup() - configure the RX DMA rings
 * @soc: data path SoC handle
@@ -1046,6 +1117,7 @@ static struct cdp_pdev *dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
 	/* MCL */
 	dp_local_peer_id_pool_init(pdev);
 #endif
+	dp_lro_hash_setup(soc);
 
 	return (struct cdp_pdev *)pdev;
 
@@ -1578,6 +1650,7 @@ static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl)
 	struct dp_vdev *vdev = (struct dp_vdev *)vdev_hdl;
 	struct dp_pdev *pdev;
 	struct dp_soc *soc;
+	bool hash_based = 0;
 
 	/* preconditions */
 	qdf_assert(vdev);
@@ -1592,10 +1665,15 @@ static void dp_peer_setup_wifi3(struct cdp_vdev *vdev_hdl, void *peer_hdl)
 	peer->last_disassoc_rcvd = 0;
 	peer->last_deauth_rcvd = 0;
 
+	hash_based = wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx);
+	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+		FL("hash based steering %d\n"), hash_based);
+
 	if (soc->cdp_soc.ol_ops->peer_set_default_routing) {
 		/* TODO: Check the destination ring number to be passed to FW */
-		soc->cdp_soc.ol_ops->peer_set_default_routing(pdev->osif_pdev,
-			 peer->mac_addr.raw, peer->vdev->vdev_id, 0, 1);
+		soc->cdp_soc.ol_ops->peer_set_default_routing(
+			pdev->osif_pdev, peer->mac_addr.raw,
+			 peer->vdev->vdev_id, hash_based, 1);
 	}
 	return;
 }

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

@@ -639,6 +639,10 @@ done:
 			 * the buffer beginning where the L2 header
 			 * begins.
 			 */
+			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
+				FL("rxhash: flow id toeplitz: 0x%x\n"),
+				hal_rx_msdu_start_toeplitz_get(rx_tlv_hdr));
+
 			l2_hdr_offset =
 				hal_rx_msdu_end_l3_hdr_padding_get(rx_tlv_hdr);
 

+ 23 - 0
dp/wifi3.0/hal_rx.h

@@ -739,6 +739,29 @@ hal_rx_msdu_start_reception_type_get(uint8_t *buf)
 	return reception_type;
 }
 
+#define HAL_RX_MSDU_START_FLOWID_TOEPLITZ_GET(_rx_msdu_start)	\
+	(_HAL_MS((*_OFFSET_TO_WORD_PTR(_rx_msdu_start,		\
+		RX_MSDU_START_4_FLOW_ID_TOEPLITZ_OFFSET)),	\
+		RX_MSDU_START_4_FLOW_ID_TOEPLITZ_MASK,		\
+		RX_MSDU_START_4_FLOW_ID_TOEPLITZ_LSB))
+
+ /**
+ * hal_rx_msdu_start_toeplitz_get: API to get the toeplitz hash
+ * from rx_msdu_start TLV
+ *
+ * @ buf: pointer to the start of RX PKT TLV headers
+ * Return: toeplitz hash
+ */
+static inline uint32_t
+hal_rx_msdu_start_toeplitz_get(uint8_t *buf)
+{
+	struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
+	struct rx_msdu_start *msdu_start =
+			&pkt_tlvs->msdu_start_tlv.rx_msdu_start;
+
+	return HAL_RX_MSDU_START_FLOWID_TOEPLITZ_GET(msdu_start);
+}
+
 /*
  * Get qos_control_valid from RX_MPDU_START
  */

+ 8 - 1
hal/wifi3.0/hal_api.h

@@ -728,12 +728,19 @@ extern void hal_setup_link_idle_list(void *hal_soc,
 	void *scatter_bufs_base_vaddr[], uint32_t num_scatter_bufs,
 	uint32_t scatter_buf_size, uint32_t last_buf_end_offset);
 
+/* REO parameters to be passed to hal_reo_setup */
+struct hal_reo_params {
+	bool rx_hash_enabled;
+};
+
 /**
  * hal_reo_setup - Initialize HW REO block
  *
  * @hal_soc: Opaque HAL SOC handle
+ * @reo_params: parameters needed by HAL for REO config
  */
-extern void hal_reo_setup(void *hal_soc);
+extern void hal_reo_setup(void *hal_soc,
+	 struct hal_reo_params *reo_params);
 
 enum hal_pn_type {
 	HAL_PN_NONE,

+ 63 - 1
hal/wifi3.0/hal_rx.c

@@ -58,6 +58,41 @@ static inline void hal_uniform_desc_hdr_setup(uint32_t *desc, uint32_t owner,
 #endif
 #define HAL_NON_QOS_TID 16
 
+/**
+ * When hash based routing is enabled, routing of the rx packet
+ * is done based on the following value: 1 _ _ _ _ The last 4
+ * bits are based on hash[3:0]. This means the possible values
+ * are 0x10 to 0x1f. This value is used to look-up the
+ * ring ID configured in Destination_Ring_Ctrl_IX_* register.
+ * The Destination_Ring_Ctrl_IX_2 and Destination_Ring_Ctrl_IX_3
+ * registers need to be configured to set-up the 16 entries to
+ * map the hash values to a ring number. There are 3 bits per
+ * hash entry – which are mapped as follows:
+ * 0: TCL, 1:SW1, 2:SW2, * 3:SW3, 4:SW4, 5:Release, 6:FW(WIFI),
+ * 7: NOT_USED.
+*/
+#ifdef IPA_OFFLOAD
+/**
+ * When IPA is enabled, there will be 3 available rings.
+ * Otherwise there will be 4.
+ */
+#define REO_REMAP_REGISTER_2 ( \
+	((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x1 << 9) | \
+	(0x2 << 12) | (0x3 << 15) | (0x1 << 18) | (0x2 << 21)) << 8)
+
+#define REO_REMAP_REGISTER_3 ( \
+	((0x3 << 0) | (0x1 << 3) | (0x2 << 6) | (0x3 << 9) | \
+	(0x1 << 12) | (0x2 << 15) | (0x3 << 18) | (0x1 << 21)) << 8)
+#else
+#define REO_REMAP_REGISTER_2 ( \
+	((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x4 << 9) | \
+	(0x1 << 12) | (0x2 << 15) | (0x3 << 18) | (0x4 << 21)) << 8)
+
+#define REO_REMAP_REGISTER_3 ( \
+	((0x1 << 0) | (0x2 << 3) | (0x3 << 6) | (0x4 << 9) | \
+	(0x1 << 12) | (0x2 << 15) | (0x3 << 18) | (0x4 << 21)) << 8)
+#endif
+
 /**
  * hal_reo_qdesc_setup - Setup HW REO queue descriptor
  *
@@ -222,8 +257,10 @@ void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size,
  * hal_reo_setup - Initialize HW REO block
  *
  * @hal_soc: Opaque HAL SOC handle
+ * @reo_params: parameters needed by HAL for REO config
  */
-void hal_reo_setup(void *hal_soc)
+void hal_reo_setup(void *hal_soc,
+	 struct hal_reo_params *reo_params)
 {
 	struct hal_soc *soc = (struct hal_soc *)hal_soc;
 
@@ -261,6 +298,31 @@ void hal_reo_setup(void *hal_soc)
 		SEQ_WCSS_UMAC_REO_REG_OFFSET),
 		(HAL_DEFAULT_REO_TIMEOUT_MS * 1000));
 
+	if (reo_params->rx_hash_enabled) {
+		HAL_REG_WRITE(soc,
+			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
+			SEQ_WCSS_UMAC_REO_REG_OFFSET),
+			REO_REMAP_REGISTER_2);
+
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR 0x%x\n"),
+			HAL_REG_READ(soc,
+			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_2_ADDR(
+			SEQ_WCSS_UMAC_REO_REG_OFFSET)));
+
+		HAL_REG_WRITE(soc,
+			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
+			SEQ_WCSS_UMAC_REO_REG_OFFSET),
+			REO_REMAP_REGISTER_3);
+
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			FL("HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR 0x%x\n"),
+			HAL_REG_READ(soc,
+			HWIO_REO_R0_DESTINATION_RING_CTRL_IX_3_ADDR(
+			SEQ_WCSS_UMAC_REO_REG_OFFSET)));
+	}
+
+
 	/* TODO: Check if the following registers shoould be setup by host:
 	 * AGING_CONTROL
 	 * HIGH_MEMORY_THRESHOLD

+ 9 - 1
qdf/inc/qdf_net_types.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -70,6 +70,14 @@ typedef struct qdf_net_ethaddr {
 	uint8_t addr[QDF_NET_ETH_LEN];
 } qdf_net_ethaddr_t;
 
+#define QDF_TCPHDR_FIN __QDF_TCPHDR_FIN
+#define QDF_TCPHDR_SYN __QDF_TCPHDR_SYN
+#define QDF_TCPHDR_RST __QDF_TCPHDR_RST
+#define QDF_TCPHDR_PSH __QDF_TCPHDR_PSH
+#define QDF_TCPHDR_ACK __QDF_TCPHDR_ACK
+#define QDF_TCPHDR_URG __QDF_TCPHDR_URG
+#define QDF_TCPHDR_ECE __QDF_TCPHDR_ECE
+#define QDF_TCPHDR_CWR __QDF_TCPHDR_CWR
 
 typedef struct {
 	uint16_t  source;

+ 11 - 0
qdf/inc/qdf_util.h

@@ -535,4 +535,15 @@ int qdf_set_dma_coherent_mask(struct device *dev, uint8_t addr_bits)
 	return __qdf_set_dma_coherent_mask(dev, addr_bits);
 }
 
+/**
+ * qdf_get_random_bytes() - returns nbytes bytes of random
+ * data
+ *
+ * Return: random bytes of data
+ */
+static inline
+void qdf_get_random_bytes(void *buf, int nbytes)
+{
+	return __qdf_get_random_bytes(buf, nbytes);
+}
 #endif /*_QDF_UTIL_H*/

+ 10 - 1
qdf/linux/src/i_qdf_net_types.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
  *
  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
  *
@@ -36,6 +36,7 @@
 #include <qdf_types.h>          /* uint8_t, etc. */
 #include <asm/checksum.h>
 #include <net/ip6_checksum.h>
+#include <net/tcp.h>
 
 typedef struct in6_addr __in6_addr_t;
 typedef __wsum __wsum_t;
@@ -49,4 +50,12 @@ static inline  int32_t __qdf_csum_ipv6(const struct in6_addr *saddr,
 			       (struct in6_addr *)daddr, len, proto, sum);
 }
 
+#define __QDF_TCPHDR_FIN TCPHDR_FIN
+#define __QDF_TCPHDR_SYN TCPHDR_SYN
+#define __QDF_TCPHDR_RST TCPHDR_RST
+#define __QDF_TCPHDR_PSH TCPHDR_PSH
+#define __QDF_TCPHDR_ACK TCPHDR_ACK
+#define __QDF_TCPHDR_URG TCPHDR_URG
+#define __QDF_TCPHDR_ECE TCPHDR_ECE
+#define __QDF_TCPHDR_CWR TCPHDR_CWR
 #endif /* _I_QDF_NET_TYPES_H */

+ 11 - 0
qdf/linux/src/i_qdf_util.h

@@ -397,5 +397,16 @@ int __qdf_set_dma_coherent_mask(struct device *dev, uint8_t addr_bits)
 	return dma_set_coherent_mask(dev, DMA_BIT_MASK(addr_bits));
 }
 #endif
+/**
+ * qdf_get_random_bytes() - returns nbytes bytes of random
+ * data
+ *
+ * Return: random bytes of data
+ */
+static inline
+void __qdf_get_random_bytes(void *buf, int nbytes)
+{
+	return get_random_bytes(buf, nbytes);
+}
 
 #endif /*_I_QDF_UTIL_H*/

+ 20 - 0
wlan_cfg/wlan_cfg.c

@@ -85,6 +85,9 @@
 #define NUM_RXDMA_RINGS_PER_PDEV 1
 #endif
 
+#define WLAN_RX_HASH_ENABLE 0
+#define WLAN_LRO_ENABLE 0
+
 static const int tx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
 						WLAN_CFG_TX_RING_MASK_0,
 						WLAN_CFG_TX_RING_MASK_1,
@@ -125,6 +128,8 @@ static const int rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
  * @int_rx_mon_ring_mask - Bitmap of Rx monitor ring interrupts mapped to each
  *			  NAPI/Intr context
  * @int_ce_ring_mask - Bitmap of CE interrupts mapped to each NAPI/Intr context
+ * @lro_enabled - is LRO enabled
+ * @rx_hash - Enable hash based steering of rx packets
  *
  */
 struct wlan_cfg_dp_soc_ctxt {
@@ -145,6 +150,8 @@ struct wlan_cfg_dp_soc_ctxt {
 	int int_rx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	int int_rx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	int int_ce_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
+	bool lro_enabled;
+	bool rx_hash;
 };
 
 /**
@@ -196,6 +203,9 @@ struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach(void)
 		wlan_cfg_ctx->int_rx_mon_ring_mask[i] = rx_mon_ring_mask[i];
 	}
 
+	wlan_cfg_ctx->rx_hash = WLAN_RX_HASH_ENABLE;
+	wlan_cfg_ctx->lro_enabled = WLAN_LRO_ENABLE;
+
 	return wlan_cfg_ctx;
 }
 
@@ -371,3 +381,13 @@ int wlan_cfg_get_num_mac_rings(struct wlan_cfg_dp_pdev_ctxt *cfg)
 {
 	return  cfg->num_mac_rings;
 }
+
+bool wlan_cfg_is_lro_enabled(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return  cfg->lro_enabled;
+}
+
+bool wlan_cfg_is_rx_hash_enabled(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return  cfg->rx_hash;
+}

+ 17 - 0
wlan_cfg/wlan_cfg.h

@@ -312,4 +312,21 @@ int wlan_cfg_get_rx_dma_buf_ring_size(
  * Return: number of mac DMA rings per pdev
  */
 int wlan_cfg_get_num_mac_rings(struct wlan_cfg_dp_pdev_ctxt *cfg);
+
+/*
+ * wlan_cfg_is_lro_enabled - Return LRO enabled/disabled
+ * @wlan_cfg_pdev_ctx
+ *
+ * Return: true - LRO enabled false - LRO disabled
+ */
+bool wlan_cfg_is_lro_enabled(struct wlan_cfg_dp_soc_ctxt *cfg);
+
+/*
+ * wlan_cfg_is_lro_enabled - Return RX hash enabled/disabled
+ * @wlan_cfg_pdev_ctx
+ *
+ * Return: true - enabled false - disabled
+ */
+bool wlan_cfg_is_rx_hash_enabled(struct wlan_cfg_dp_soc_ctxt *cfg);
+
 #endif