From 1404917b6e72390956a663a05c49a3832320a820 Mon Sep 17 00:00:00 2001 From: Dhanashri Atre Date: Fri, 11 Nov 2016 18:32:36 -0800 Subject: [PATCH] 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 --- dp/inc/cdp_txrx_ops.h | 27 ++++++++++- dp/wifi3.0/dp_main.c | 84 +++++++++++++++++++++++++++++++-- dp/wifi3.0/dp_rx.c | 4 ++ dp/wifi3.0/hal_rx.h | 23 +++++++++ hal/wifi3.0/hal_api.h | 9 +++- hal/wifi3.0/hal_rx.c | 64 ++++++++++++++++++++++++- qdf/inc/qdf_net_types.h | 10 +++- qdf/inc/qdf_util.h | 11 +++++ qdf/linux/src/i_qdf_net_types.h | 11 ++++- qdf/linux/src/i_qdf_util.h | 11 +++++ wlan_cfg/wlan_cfg.c | 20 ++++++++ wlan_cfg/wlan_cfg.h | 17 +++++++ 12 files changed, 283 insertions(+), 8 deletions(-) diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index cc17014df8..2becb0565e 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/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 */ }; diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index de3a8775ed..108b1fb314 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include #include "cdp_txrx_cmn_struct.h" +#include #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; } diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 7415028545..6ca9788c2b 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/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); diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index e81d9ba694..d188e2fde9 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/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 */ diff --git a/hal/wifi3.0/hal_api.h b/hal/wifi3.0/hal_api.h index 28fe0504e9..d06ec3b70f 100644 --- a/hal/wifi3.0/hal_api.h +++ b/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, diff --git a/hal/wifi3.0/hal_rx.c b/hal/wifi3.0/hal_rx.c index 8f4b7a0d07..c3170c0174 100644 --- a/hal/wifi3.0/hal_rx.c +++ b/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 diff --git a/qdf/inc/qdf_net_types.h b/qdf/inc/qdf_net_types.h index 9b4fd6d0ea..386f72fcf6 100644 --- a/qdf/inc/qdf_net_types.h +++ b/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; diff --git a/qdf/inc/qdf_util.h b/qdf/inc/qdf_util.h index 8e8eda8de7..aabd1c3923 100644 --- a/qdf/inc/qdf_util.h +++ b/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*/ diff --git a/qdf/linux/src/i_qdf_net_types.h b/qdf/linux/src/i_qdf_net_types.h index 0ec7d75fba..031a023206 100644 --- a/qdf/linux/src/i_qdf_net_types.h +++ b/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 /* uint8_t, etc. */ #include #include +#include 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 */ diff --git a/qdf/linux/src/i_qdf_util.h b/qdf/linux/src/i_qdf_util.h index 312010cd78..52cefb0ebc 100644 --- a/qdf/linux/src/i_qdf_util.h +++ b/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*/ diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index c978b8d335..2e7e348efa 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/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; +} diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 15eb5b11ac..2b08ecf805 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/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