diff --git a/components/dp/core/inc/wlan_dp_priv.h b/components/dp/core/inc/wlan_dp_priv.h index 271f908e74..f66d5a1a83 100644 --- a/components/dp/core/inc/wlan_dp_priv.h +++ b/components/dp/core/inc/wlan_dp_priv.h @@ -75,6 +75,8 @@ struct dp_rtpm_tput_policy_context { }; #endif +#define FISA_FLOW_MAX_AGGR_COUNT 16 /* max flow aggregate count */ + /** * struct wlan_dp_psoc_cfg - DP configuration parameters. * @tx_orphan_enable: Enable/Disable tx orphan @@ -336,6 +338,227 @@ struct direct_link_info { bool low_latency; }; +/** + * struct dp_fisa_reo_mismatch_stats - reo mismatch sub-case stats for FISA + * @allow_cce_match: packet allowed due to cce mismatch + * @allow_fse_metdata_mismatch: packet allowed since it belongs to same flow, + * only fse_metadata is not same. + * @allow_non_aggr: packet allowed due to any other reason. + */ +struct dp_fisa_reo_mismatch_stats { + uint32_t allow_cce_match; + uint32_t allow_fse_metdata_mismatch; + uint32_t allow_non_aggr; +}; + +/** + * struct dp_fisa_stats - FISA stats + * @invalid_flow_index: flow index invalid from RX HW TLV + * @update_deferred: workqueue deferred due to suspend + * @reo_mismatch: REO ID mismatch + * @incorrect_rdi: Incorrect REO dest indication in TLV + * (typically used for RDI = 0) + */ +struct dp_fisa_stats { + uint32_t invalid_flow_index; + uint32_t update_deferred; + struct dp_fisa_reo_mismatch_stats reo_mismatch; + uint32_t incorrect_rdi; +}; + +/** + * enum fisa_aggr_ret - FISA aggregation return code + * @FISA_AGGR_DONE: FISA aggregation done + * @FISA_AGGR_NOT_ELIGIBLE: Not eligible for FISA aggregation + * @FISA_FLUSH_FLOW: FISA flow flushed + */ +enum fisa_aggr_ret { + FISA_AGGR_DONE, + FISA_AGGR_NOT_ELIGIBLE, + FISA_FLUSH_FLOW +}; + +/** + * struct fisa_pkt_hist - FISA Packet history structure + * @tlv_hist: array of TLV history + * @ts_hist: array of timestamps of fisa packets + * @idx: index indicating the next location to be used in the array. + */ +struct fisa_pkt_hist { + uint8_t *tlv_hist; + qdf_time_t ts_hist[FISA_FLOW_MAX_AGGR_COUNT]; + uint32_t idx; +}; + +/** + * struct dp_fisa_rx_sw_ft - FISA Flow table entry + * @hw_fse: HAL Rx Flow Search Entry which matches HW definition + * @flow_hash: Flow hash value + * @flow_id_toeplitz: toeplitz hash value + * @flow_id: Flow index, equivalent to hash value truncated to FST size + * @stats: Stats tracking for this flow + * @is_ipv4_addr_entry: Flag indicating whether flow is IPv4 address tuple + * @is_valid: Flag indicating whether flow is valid + * @is_populated: Flag indicating whether flow is populated + * @is_flow_udp: Flag indicating whether flow is UDP stream + * @is_flow_tcp: Flag indicating whether flow is TCP stream + * @head_skb: HEAD skb where flow is aggregated + * @cumulative_l4_checksum: Cumulative L4 checksum + * @adjusted_cumulative_ip_length: Cumulative IP length + * @cur_aggr: Current aggregate length of flow + * @napi_flush_cumulative_l4_checksum: Cumulative L4 chekcsum for current + * NAPI flush + * @napi_flush_cumulative_ip_length: Cumulative IP length + * @last_skb: The last skb aggregated in the FISA flow + * @head_skb_ip_hdr_offset: IP header offset + * @head_skb_l4_hdr_offset: L4 header offset + * @rx_flow_tuple_info: RX tuple information + * @napi_id: NAPI ID (REO ID) on which the flow is being received + * @vdev: VDEV handle corresponding to the FLOW + * @bytes_aggregated: Number of bytes currently aggregated + * @flush_count: Number of Flow flushes done + * @aggr_count: Aggregation count + * @do_not_aggregate: Flag to indicate not to aggregate this flow + * @hal_cumultive_ip_len: HAL cumulative IP length + * @soc_hdl: DP SoC handle + * @last_hal_aggr_count: last aggregate count fetched from RX PKT TLV + * @cur_aggr_gso_size: Current aggreagtesd GSO size + * @head_skb_udp_hdr: UDP header address for HEAD skb + * @frags_cumulative_len: + * @cmem_offset: CMEM offset + * @metadata: + * @reo_dest_indication: REO destination indication for the FLOW + * @flow_init_ts: FLOW init timestamp + * @last_accessed_ts: Timestamp when the flow was last accessed + * @pkt_hist: FISA aggreagtion packets history + */ +struct dp_fisa_rx_sw_ft { + void *hw_fse; + uint32_t flow_hash; + uint32_t flow_id_toeplitz; + uint32_t flow_id; + struct cdp_flow_stats stats; + uint8_t is_ipv4_addr_entry; + uint8_t is_valid; + uint8_t is_populated; + uint8_t is_flow_udp; + uint8_t is_flow_tcp; + qdf_nbuf_t head_skb; + uint16_t cumulative_l4_checksum; + uint16_t adjusted_cumulative_ip_length; + uint16_t cur_aggr; + uint16_t napi_flush_cumulative_l4_checksum; + uint16_t napi_flush_cumulative_ip_length; + qdf_nbuf_t last_skb; + uint32_t head_skb_ip_hdr_offset; + uint32_t head_skb_l4_hdr_offset; + struct cdp_rx_flow_tuple_info rx_flow_tuple_info; + uint8_t napi_id; + struct dp_vdev *vdev; + uint64_t bytes_aggregated; + uint32_t flush_count; + uint32_t aggr_count; + uint8_t do_not_aggregate; + uint16_t hal_cumultive_ip_len; + struct dp_soc *soc_hdl; + uint32_t last_hal_aggr_count; + uint32_t cur_aggr_gso_size; + qdf_net_udphdr_t *head_skb_udp_hdr; + uint16_t frags_cumulative_len; + uint32_t cmem_offset; + uint32_t metadata; + uint32_t reo_dest_indication; + qdf_time_t flow_init_ts; + qdf_time_t last_accessed_ts; +#ifdef WLAN_SUPPORT_RX_FISA_HIST + struct fisa_pkt_hist pkt_hist; +#endif +}; + +#define DP_RX_GET_SW_FT_ENTRY_SIZE sizeof(struct dp_fisa_rx_sw_ft) +#define MAX_FSE_CACHE_FL_HST 10 +/** + * struct fse_cache_flush_history - Debug history cache flush + * @timestamp: Entry update timestamp + * @flows_added: Number of flows added for this flush + * @flows_deleted: Number of flows deleted for this flush + */ +struct fse_cache_flush_history { + uint64_t timestamp; + uint32_t flows_added; + uint32_t flows_deleted; +}; + +/** + * struct dp_rx_fst - FISA handle + * @base: Software (DP) FST + * @dp_ctx: DP component handle + * @hal_rx_fst: Pointer to HAL FST + * @hal_rx_fst_base_paddr: Base physical address of HAL RX HW FST + * @max_entries: Maximum number of flows FSE supports + * @num_entries: Num entries in flow table + * @max_skid_length: SKID Length + * @hash_mask: Hash mask to obtain legitimate hash entry + * @dp_rx_fst_lock: Lock for adding/deleting entries of FST + * @add_flow_count: Num of flows added + * @del_flow_count: Num of flows deleted + * @hash_collision_cnt: Num hash collisions + * @soc_hdl: DP SoC handle + * @fse_cache_flush_posted: Num FSE cache flush cmds posted + * @fse_cache_flush_timer: FSE cache flush timer + * @fse_cache_flush_allow: Flag to indicate if FSE cache flush is allowed + * @cache_fl_rec: FSE cache flush history + * @stats: FISA stats + * @fst_update_work: FST CMEM update work + * @fst_update_wq: FST CMEM update workqueue + * @fst_update_list: List to post event to CMEM update work + * @meta_counter: + * @cmem_ba: + * @dp_rx_sw_ft_lock: SW FST lock + * @cmem_resp_event: CMEM response event indicator + * @flow_deletion_supported: Flag to indicate if flow delete is supported + * @fst_in_cmem: Flag to indicate if FST is stored in CMEM + * @pm_suspended: Flag to indicate if driver is suspended + * @fst_wq_defer: + * @rx_hash_enabled: Flag to indicate if Hash based routing supported + * @rx_toeplitz_hash_key: hash key + */ +struct dp_rx_fst { + uint8_t *base; + struct wlan_dp_psoc_context *dp_ctx; + struct hal_rx_fst *hal_rx_fst; + uint64_t hal_rx_fst_base_paddr; + uint16_t max_entries; + uint16_t num_entries; + uint16_t max_skid_length; + uint32_t hash_mask; + qdf_spinlock_t dp_rx_fst_lock; + uint32_t add_flow_count; + uint32_t del_flow_count; + uint32_t hash_collision_cnt; + struct dp_soc *soc_hdl; + qdf_atomic_t fse_cache_flush_posted; + qdf_timer_t fse_cache_flush_timer; + bool fse_cache_flush_allow; + struct fse_cache_flush_history cache_fl_rec[MAX_FSE_CACHE_FL_HST]; + struct dp_fisa_stats stats; + + /* CMEM params */ + qdf_work_t fst_update_work; + qdf_workqueue_t *fst_update_wq; + qdf_list_t fst_update_list; + uint32_t meta_counter; + uint32_t cmem_ba; + qdf_spinlock_t dp_rx_sw_ft_lock[MAX_REO_DEST_RINGS]; + qdf_event_t cmem_resp_event; + bool flow_deletion_supported; + bool fst_in_cmem; + qdf_atomic_t pm_suspended; + bool fst_wq_defer; + bool rx_hash_enabled; + uint8_t *rx_toeplitz_hash_key; +}; + /** * struct wlan_dp_intf - DP interface object related info * @dp_ctx: DP context reference @@ -529,8 +752,15 @@ struct dp_direct_link_context { * @arp_connectivity_map: ARP connectivity map * @rx_wake_lock: rx wake lock * @ol_enable: Enable/Disable offload + * @rx_fst: FST handle * @fst_cmem_base: FST base in CMEM * @fst_in_cmem: Flag indicating if FST is in CMEM or not + * @fisa_enable: Flag to indicate if FISA is enabled or not + * @fisa_lru_del_enable: Flag to indicate if LRU flow delete is enabled + * @skip_fisa_param: FISA skip params structure + * @skip_fisa_param.skip_fisa: Flag to skip FISA aggr inside @skip_fisa_param + * @skip_fisa_param.fisa_force_flush: Force flush inside @skip_fisa_param + * @fst_cmem_size: CMEM size for FISA flow table */ struct wlan_dp_psoc_context { struct wlan_objmgr_psoc *psoc; @@ -610,8 +840,25 @@ struct wlan_dp_psoc_context { struct dp_direct_link_context *dp_direct_link_ctx; #endif #ifdef WLAN_SUPPORT_RX_FISA + struct dp_rx_fst *rx_fst; uint64_t fst_cmem_base; bool fst_in_cmem; + uint8_t fisa_enable; + uint8_t fisa_lru_del_enable; + /* + * Params used for controlling the fisa aggregation dynamically + */ + struct { + qdf_atomic_t skip_fisa; + uint8_t fisa_force_flush[MAX_REO_DEST_RINGS]; + } skip_fisa_param; + + /* + * CMEM address and size for FST in CMEM, This is the address + * shared during init time. + */ + uint64_t fst_cmem_size; + #endif }; diff --git a/components/dp/core/inc/wlan_dp_txrx.h b/components/dp/core/inc/wlan_dp_txrx.h index fa05b9fdc4..1c57010fcf 100644 --- a/components/dp/core/inc/wlan_dp_txrx.h +++ b/components/dp/core/inc/wlan_dp_txrx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -58,12 +58,12 @@ uint32_t wlan_dp_intf_get_pkt_type_bitmap_value(void *intf_ctx); #if defined(WLAN_SUPPORT_RX_FISA) /** * dp_rx_skip_fisa() - Set flags to skip fisa aggregation - * @cdp_soc: core txrx main context + * @dp_ctx: DP component handle * @value: allow or skip fisa * * Return: None */ -void dp_rx_skip_fisa(struct cdp_soc_t *cdp_soc, uint32_t value); +void dp_rx_skip_fisa(struct wlan_dp_psoc_context *dp_ctx, uint32_t value); #endif /** diff --git a/components/dp/core/src/wlan_dp_fisa_rx.c b/components/dp/core/src/wlan_dp_fisa_rx.c index e10f72f6af..8153e52ae5 100644 --- a/components/dp/core/src/wlan_dp_fisa_rx.c +++ b/components/dp/core/src/wlan_dp_fisa_rx.c @@ -153,33 +153,6 @@ static void nbuf_skip_rx_pkt_tlv(struct dp_soc *soc, qdf_nbuf_t nbuf) qdf_nbuf_pull_head(nbuf, soc->rx_pkt_tlv_size + l2_hdr_offset); } -/** - * print_flow_tuple() - Debug function to dump flow tuple - * @flow_tuple: flow tuple containing tuple info - * @str: destination buffer - * @size: size of @str - * - * Return: NONE - */ -static -void print_flow_tuple(struct cdp_rx_flow_tuple_info *flow_tuple, char *str, - uint32_t size) -{ - qdf_scnprintf(str, size, - "dest 0x%x%x%x%x(0x%x) src 0x%x%x%x%x(0x%x) proto 0x%x", - flow_tuple->dest_ip_127_96, - flow_tuple->dest_ip_95_64, - flow_tuple->dest_ip_63_32, - flow_tuple->dest_ip_31_0, - flow_tuple->dest_port, - flow_tuple->src_ip_127_96, - flow_tuple->src_ip_95_64, - flow_tuple->src_ip_63_32, - flow_tuple->src_ip_31_0, - flow_tuple->src_port, - flow_tuple->l4_protocol); -} - static bool dp_rx_fisa_should_bypass(struct cdp_rx_flow_tuple_info *flow_tuple_info) { @@ -1924,7 +1897,8 @@ QDF_STATUS dp_rx_fisa_flush_by_vdev_ctx_id(struct dp_soc *soc, struct dp_vdev *vdev, uint8_t rx_ctx_id) { - struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + struct dp_rx_fst *fisa_hdl = dp_ctx->rx_fst; struct dp_fisa_rx_sw_ft *sw_ft_entry = (struct dp_fisa_rx_sw_ft *)fisa_hdl->base; int ft_size = fisa_hdl->max_entries; @@ -1971,18 +1945,12 @@ static bool dp_fisa_disallowed_for_vdev(struct dp_soc *soc, return true; } -/** - * dp_fisa_rx() - Entry function to FISA to handle aggregation - * @soc: core txrx main context - * @vdev: Handle DP vdev - * @nbuf_list: List nbufs to be aggregated - * - * Return: Success on aggregation - */ -QDF_STATUS dp_fisa_rx(struct dp_soc *soc, struct dp_vdev *vdev, +QDF_STATUS dp_fisa_rx(struct wlan_dp_psoc_context *dp_ctx, + struct dp_vdev *vdev, qdf_nbuf_t nbuf_list) { - struct dp_rx_fst *dp_fisa_rx_hdl = soc->rx_fst; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(dp_ctx->cdp_soc); + struct dp_rx_fst *dp_fisa_rx_hdl = dp_ctx->rx_fst; qdf_nbuf_t head_nbuf; qdf_nbuf_t next_nbuf; struct dp_fisa_rx_sw_ft *fisa_flow; @@ -2003,21 +1971,21 @@ QDF_STATUS dp_fisa_rx(struct dp_soc *soc, struct dp_vdev *vdev, if (dp_fisa_disallowed_for_vdev(soc, vdev, rx_ctx_id)) goto deliver_nbuf; - if (qdf_atomic_read(&soc->skip_fisa_param.skip_fisa)) { - if (!soc->skip_fisa_param.fisa_force_flush[rx_ctx_id]) { + if (qdf_atomic_read(&dp_ctx->skip_fisa_param.skip_fisa)) { + if (!dp_ctx->skip_fisa_param.fisa_force_flush[rx_ctx_id]) { dp_rx_fisa_flush_by_ctx_id(soc, rx_ctx_id); - soc->skip_fisa_param. + dp_ctx->skip_fisa_param. fisa_force_flush[rx_ctx_id] = 1; } goto deliver_nbuf; - } else if (soc->skip_fisa_param.fisa_force_flush[rx_ctx_id]) { - soc->skip_fisa_param.fisa_force_flush[rx_ctx_id] = 0; + } else if (dp_ctx->skip_fisa_param.fisa_force_flush[rx_ctx_id]) { + dp_ctx->skip_fisa_param.fisa_force_flush[rx_ctx_id] = 0; } qdf_nbuf_push_head(head_nbuf, soc->rx_pkt_tlv_size + QDF_NBUF_CB_RX_PACKET_L3_HDR_PAD(head_nbuf)); - hal_rx_msdu_get_reo_destination_indication(soc->hal_soc, + hal_rx_msdu_get_reo_destination_indication(dp_ctx->hal_soc, (uint8_t *)qdf_nbuf_data(head_nbuf), &tlv_reo_dest_ind); @@ -2078,45 +2046,6 @@ next_msdu: return QDF_STATUS_SUCCESS; } -/* Length of string to store tuple information for printing */ -#define DP_TUPLE_STR_LEN 512 - -QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) -{ - int i; - char tuple_str[DP_TUPLE_STR_LEN] = {'\0'}; - struct dp_rx_fst *rx_fst = soc->rx_fst; - struct dp_fisa_rx_sw_ft *sw_ft_entry = - &((struct dp_fisa_rx_sw_ft *)rx_fst->base)[0]; - int ft_size = rx_fst->max_entries; - - dp_info("#flows added %d evicted %d hash collision %d", - rx_fst->add_flow_count, - rx_fst->del_flow_count, - rx_fst->hash_collision_cnt); - - for (i = 0; i < ft_size; i++, sw_ft_entry++) { - if (!sw_ft_entry->is_populated) - continue; - - print_flow_tuple(&sw_ft_entry->rx_flow_tuple_info, - tuple_str, - sizeof(tuple_str)); - - dp_info("Flow[%d][%s][%s] ring %d msdu-aggr %d flushes %d bytes-agg %llu avg-bytes-aggr %llu", - sw_ft_entry->flow_id, - sw_ft_entry->is_flow_udp ? "udp" : "tcp", - tuple_str, - sw_ft_entry->napi_id, - sw_ft_entry->aggr_count, - sw_ft_entry->flush_count, - sw_ft_entry->bytes_aggregated, - qdf_do_div(sw_ft_entry->bytes_aggregated, - sw_ft_entry->flush_count)); - } - return QDF_STATUS_SUCCESS; -} - /** * dp_rx_fisa_flush_flow_wrap() - flush fisa flow by invoking * dp_rx_fisa_flush_flow() @@ -2143,7 +2072,8 @@ static void dp_rx_fisa_flush_flow_wrap(struct dp_fisa_rx_sw_ft *sw_ft) QDF_STATUS dp_rx_fisa_flush_by_ctx_id(struct dp_soc *soc, int napi_id) { - struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + struct dp_rx_fst *fisa_hdl = dp_ctx->rx_fst; struct dp_fisa_rx_sw_ft *sw_ft_entry = (struct dp_fisa_rx_sw_ft *)fisa_hdl->base; int ft_size = fisa_hdl->max_entries; @@ -2165,7 +2095,8 @@ QDF_STATUS dp_rx_fisa_flush_by_ctx_id(struct dp_soc *soc, int napi_id) QDF_STATUS dp_rx_fisa_flush_by_vdev_id(struct dp_soc *soc, uint8_t vdev_id) { - struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + struct dp_rx_fst *fisa_hdl = dp_ctx->rx_fst; struct dp_fisa_rx_sw_ft *sw_ft_entry = (struct dp_fisa_rx_sw_ft *)fisa_hdl->base; int ft_size = fisa_hdl->max_entries; @@ -2213,10 +2144,9 @@ void dp_set_fisa_disallowed_for_vdev(struct cdp_soc_t *cdp_soc, uint8_t vdev_id, void dp_suspend_fse_cache_flush(struct wlan_dp_psoc_context *dp_ctx) { - struct dp_soc *soc = (struct dp_soc *)dp_ctx->cdp_soc; struct dp_rx_fst *dp_fst; - dp_fst = soc->rx_fst; + dp_fst = dp_ctx->rx_fst; if (dp_fst) { if (qdf_atomic_read(&dp_fst->fse_cache_flush_posted)) qdf_timer_sync_cancel(&dp_fst->fse_cache_flush_timer); @@ -2228,10 +2158,9 @@ void dp_suspend_fse_cache_flush(struct wlan_dp_psoc_context *dp_ctx) void dp_resume_fse_cache_flush(struct wlan_dp_psoc_context *dp_ctx) { - struct dp_soc *soc = (struct dp_soc *)dp_ctx->cdp_soc; struct dp_rx_fst *dp_fst; - dp_fst = soc->rx_fst; + dp_fst = dp_ctx->rx_fst; if (dp_fst) { qdf_atomic_set(&dp_fst->fse_cache_flush_posted, 0); dp_fst->fse_cache_flush_allow = true; diff --git a/components/dp/core/src/wlan_dp_fisa_rx.h b/components/dp/core/src/wlan_dp_fisa_rx.h index a6613cde8d..351f1ceb36 100644 --- a/components/dp/core/src/wlan_dp_fisa_rx.h +++ b/components/dp/core/src/wlan_dp_fisa_rx.h @@ -88,23 +88,16 @@ struct dp_ft_lock_history { struct dp_ft_lock_record ft_lock_rec[DP_FT_LOCK_MAX_RECORDS]; }; -/** - * dp_rx_dump_fisa_stats() - Dump fisa stats - * @soc: core txrx main context - * - * Return: QDF_STATUS - */ -QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc); - /** * dp_fisa_rx() - FISA Rx packet delivery entry function - * @soc: core txrx main context + * @dp_ctx: DP component handle * @vdev: core txrx vdev * @nbuf_list: Delivery list of nbufs * - * Return: QDF_STATUS + * Return: Success on aggregation */ -QDF_STATUS dp_fisa_rx(struct dp_soc *soc, struct dp_vdev *vdev, +QDF_STATUS dp_fisa_rx(struct wlan_dp_psoc_context *dp_ctx, + struct dp_vdev *vdev, qdf_nbuf_t nbuf_list); /** @@ -222,6 +215,8 @@ void dp_rx_fst_update_pm_suspend_status(struct wlan_dp_psoc_context *dp_ctx, */ void dp_rx_fst_requeue_wq(struct wlan_dp_psoc_context *dp_ctx); +void dp_print_fisa_rx_stats(enum cdp_fisa_stats_id stats_id); + /** * dp_fisa_cfg_init() - FISA INI items init * @config: SoC CFG config @@ -231,6 +226,14 @@ void dp_rx_fst_requeue_wq(struct wlan_dp_psoc_context *dp_ctx); */ void dp_fisa_cfg_init(struct wlan_dp_psoc_cfg *config, struct wlan_objmgr_psoc *psoc); + +/** + * dp_set_fst_in_cmem() - Set flag to indicate FST is in CMEM + * @fst_in_cmem: Flag to indicate FST is in CMEM + * + * Return: None + */ +void dp_set_fst_in_cmem(bool fst_in_cmem); #else static inline void dp_rx_fst_update_pm_suspend_status(struct wlan_dp_psoc_context *dp_ctx, @@ -238,12 +241,7 @@ dp_rx_fst_update_pm_suspend_status(struct wlan_dp_psoc_context *dp_ctx, { } -static QDF_STATUS dp_rx_dump_fisa_stats(struct dp_soc *soc) -{ - return QDF_STATUS_SUCCESS; -} - -void dp_rx_dump_fisa_table(struct dp_soc *soc) +static inline void dp_print_fisa_rx_stats(enum cdp_fisa_stats_id stats_id) { } @@ -251,5 +249,9 @@ static inline void dp_fisa_cfg_init(struct wlan_dp_psoc_cfg *config, struct wlan_objmgr_psoc *psoc) { } + +static inline void dp_set_fst_in_cmem(bool fst_in_cmem) +{ +} #endif #endif diff --git a/components/dp/core/src/wlan_dp_prealloc.c b/components/dp/core/src/wlan_dp_prealloc.c index 820086023e..39f63ee4c4 100644 --- a/components/dp/core/src/wlan_dp_prealloc.c +++ b/components/dp/core/src/wlan_dp_prealloc.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include diff --git a/components/dp/core/src/wlan_dp_rx_fst.c b/components/dp/core/src/wlan_dp_rx_fst.c index 3c948c0b3e..845c7aed89 100644 --- a/components/dp/core/src/wlan_dp_rx_fst.c +++ b/components/dp/core/src/wlan_dp_rx_fst.c @@ -37,13 +37,11 @@ #ifdef WLAN_SUPPORT_RX_FISA void dp_fisa_rx_fst_update_work(void *arg); -void dp_rx_dump_fisa_table(struct dp_soc *soc) +static void dp_rx_dump_fisa_table(struct wlan_dp_psoc_context *dp_ctx) { - hal_soc_handle_t hal_soc_hdl = soc->hal_soc; - /* TODO - Make this better */ - struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + hal_soc_handle_t hal_soc_hdl = dp_ctx->hal_soc; struct wlan_dp_psoc_cfg *dp_cfg = &dp_ctx->dp_cfg; - struct dp_rx_fst *fst = soc->rx_fst; + struct dp_rx_fst *fst = dp_ctx->rx_fst; struct dp_fisa_rx_sw_ft *sw_ft_entry; int i; @@ -54,7 +52,7 @@ void dp_rx_dump_fisa_table(struct dp_soc *soc) } if (!fst->fst_in_cmem) - return hal_rx_dump_fse_table(soc->rx_fst->hal_rx_fst); + return hal_rx_dump_fse_table(fst->hal_rx_fst); sw_ft_entry = (struct dp_fisa_rx_sw_ft *)fst->base; @@ -75,12 +73,10 @@ void dp_rx_dump_fisa_table(struct dp_soc *soc) } } -void dp_print_fisa_stats(struct dp_soc *soc) +static void dp_print_fisa_stats(struct wlan_dp_psoc_context *dp_ctx) { - struct dp_rx_fst *fst = soc->rx_fst; - /* TODO - Make this better */ - struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); struct wlan_dp_psoc_cfg *dp_cfg = &dp_ctx->dp_cfg; + struct dp_rx_fst *fst = dp_ctx->rx_fst; /* Check if it is enabled in the INI */ if (!wlan_dp_cfg_is_rx_fisa_enabled(dp_cfg)) @@ -96,6 +92,98 @@ void dp_print_fisa_stats(struct dp_soc *soc) fst->stats.reo_mismatch.allow_non_aggr); } +/* Length of string to store tuple information for printing */ +#define DP_TUPLE_STR_LEN 512 + +/** + * print_flow_tuple() - Debug function to dump flow tuple + * @flow_tuple: flow tuple containing tuple info + * @str: destination buffer + * @size: size of @str + * + * Return: NONE + */ +static +void print_flow_tuple(struct cdp_rx_flow_tuple_info *flow_tuple, char *str, + uint32_t size) +{ + qdf_scnprintf(str, size, + "dest 0x%x%x%x%x(0x%x) src 0x%x%x%x%x(0x%x) proto 0x%x", + flow_tuple->dest_ip_127_96, + flow_tuple->dest_ip_95_64, + flow_tuple->dest_ip_63_32, + flow_tuple->dest_ip_31_0, + flow_tuple->dest_port, + flow_tuple->src_ip_127_96, + flow_tuple->src_ip_95_64, + flow_tuple->src_ip_63_32, + flow_tuple->src_ip_31_0, + flow_tuple->src_port, + flow_tuple->l4_protocol); +} + +static QDF_STATUS dp_rx_dump_fisa_stats(struct wlan_dp_psoc_context *dp_ctx) +{ + char tuple_str[DP_TUPLE_STR_LEN] = {'\0'}; + struct dp_rx_fst *rx_fst = dp_ctx->rx_fst; + struct dp_fisa_rx_sw_ft *sw_ft_entry = + &((struct dp_fisa_rx_sw_ft *)rx_fst->base)[0]; + int ft_size = rx_fst->max_entries; + int i; + + dp_info("#flows added %d evicted %d hash collision %d", + rx_fst->add_flow_count, + rx_fst->del_flow_count, + rx_fst->hash_collision_cnt); + + for (i = 0; i < ft_size; i++, sw_ft_entry++) { + if (!sw_ft_entry->is_populated) + continue; + + print_flow_tuple(&sw_ft_entry->rx_flow_tuple_info, + tuple_str, + sizeof(tuple_str)); + + dp_info("Flow[%d][%s][%s] ring %d msdu-aggr %d flushes %d bytes-agg %llu avg-bytes-aggr %llu", + sw_ft_entry->flow_id, + sw_ft_entry->is_flow_udp ? "udp" : "tcp", + tuple_str, + sw_ft_entry->napi_id, + sw_ft_entry->aggr_count, + sw_ft_entry->flush_count, + sw_ft_entry->bytes_aggregated, + qdf_do_div(sw_ft_entry->bytes_aggregated, + sw_ft_entry->flush_count)); + } + return QDF_STATUS_SUCCESS; +} + +void dp_set_fst_in_cmem(bool fst_in_cmem) +{ + struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + + dp_ctx->fst_in_cmem = fst_in_cmem; +} + +void dp_print_fisa_rx_stats(enum cdp_fisa_stats_id stats_id) +{ + struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + + switch (stats_id) { + case CDP_FISA_STATS_ID_ERR_STATS: + dp_print_fisa_stats(dp_ctx); + break; + case CDP_FISA_STATS_ID_DUMP_HW_FST: + dp_rx_dump_fisa_table(dp_ctx); + break; + case CDP_FISA_STATS_ID_DUMP_SW_FST: + dp_rx_dump_fisa_stats(dp_ctx); + break; + default: + break; + } +} + /** * dp_rx_flow_send_htt_operation_cmd() - Invalidate FSE cache on FT change * @pdev: handle to DP pdev @@ -132,8 +220,10 @@ dp_rx_flow_send_htt_operation_cmd(struct dp_pdev *pdev, */ static void dp_fisa_fse_cache_flush_timer(void *arg) { - struct dp_soc *soc = (struct dp_soc *)arg; - struct dp_rx_fst *fisa_hdl = soc->rx_fst; + struct wlan_dp_psoc_context *dp_ctx = + (struct wlan_dp_psoc_context *)arg; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(dp_ctx->cdp_soc); + struct dp_rx_fst *fisa_hdl = dp_ctx->rx_fst; struct cdp_rx_flow_tuple_info rx_flow_tuple_info = { 0 }; static uint32_t fse_cache_flush_rec_idx; struct fse_cache_flush_history *fse_cache_flush_rec; @@ -306,7 +396,7 @@ QDF_STATUS dp_rx_fst_attach(struct wlan_dp_psoc_context *dp_ctx) return QDF_STATUS_E_NOSUPPORT; } #endif - if (soc->rx_fst) { + if (dp_ctx->rx_fst) { QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, "RX FST already allocated\n"); return QDF_STATUS_SUCCESS; @@ -351,13 +441,13 @@ QDF_STATUS dp_rx_fst_attach(struct wlan_dp_psoc_context *dp_ctx) if (QDF_IS_STATUS_ERROR(status)) goto free_hist; - fst->hal_rx_fst = hal_rx_fst_attach(soc->hal_soc, - soc->osdev, + fst->hal_rx_fst = hal_rx_fst_attach(dp_ctx->hal_soc, + dp_ctx->qdf_dev, &fst->hal_rx_fst_base_paddr, fst->max_entries, fst->max_skid_length, fst->rx_toeplitz_hash_key, - soc->fst_cmem_base); + dp_ctx->fst_cmem_base); if (qdf_unlikely(!fst->hal_rx_fst)) { QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, @@ -368,8 +458,8 @@ QDF_STATUS dp_rx_fst_attach(struct wlan_dp_psoc_context *dp_ctx) qdf_spinlock_create(&fst->dp_rx_fst_lock); - status = qdf_timer_init(soc->osdev, &fst->fse_cache_flush_timer, - dp_fisa_fse_cache_flush_timer, (void *)soc, + status = qdf_timer_init(dp_ctx->qdf_dev, &fst->fse_cache_flush_timer, + dp_fisa_fse_cache_flush_timer, (void *)dp_ctx, QDF_TIMER_TYPE_WAKE_APPS); if (QDF_IS_STATUS_ERROR(status)) { QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, @@ -382,12 +472,13 @@ QDF_STATUS dp_rx_fst_attach(struct wlan_dp_psoc_context *dp_ctx) fst->fse_cache_flush_allow = true; fst->rx_hash_enabled = wlan_cfg_is_rx_hash_enabled(soc->wlan_cfg_ctx); fst->soc_hdl = soc; - soc->rx_fst = fst; - soc->fisa_enable = true; - soc->fisa_lru_del_enable = + fst->dp_ctx = dp_ctx; + dp_ctx->rx_fst = fst; + dp_ctx->fisa_enable = true; + dp_ctx->fisa_lru_del_enable = wlan_dp_cfg_is_rx_fisa_lru_del_enabled(dp_cfg); - qdf_atomic_init(&soc->skip_fisa_param.skip_fisa); + qdf_atomic_init(&dp_ctx->skip_fisa_param.skip_fisa); qdf_atomic_init(&fst->pm_suspended); QDF_TRACE(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_ERROR, @@ -398,8 +489,8 @@ QDF_STATUS dp_rx_fst_attach(struct wlan_dp_psoc_context *dp_ctx) timer_init_fail: qdf_spinlock_destroy(&fst->dp_rx_fst_lock); - hal_rx_fst_detach(soc->hal_soc, fst->hal_rx_fst, soc->osdev, - soc->fst_cmem_base); + hal_rx_fst_detach(dp_ctx->hal_soc, fst->hal_rx_fst, dp_ctx->qdf_dev, + dp_ctx->fst_cmem_base); free_hist: dp_rx_sw_ft_hist_deinit((struct dp_fisa_rx_sw_ft *)fst->base, fst->max_entries); @@ -412,28 +503,29 @@ free_rx_fst: /** * dp_rx_fst_check_cmem_support() - Check if FW can allocate FSE in CMEM, * allocate FSE in DDR if FW doesn't support CMEM allocation - * @soc: DP SoC handle + * @dp_ctx: DP component context * * Return: None */ -static void dp_rx_fst_check_cmem_support(struct dp_soc *soc) +static void dp_rx_fst_check_cmem_support(struct wlan_dp_psoc_context *dp_ctx) { - struct dp_rx_fst *fst = soc->rx_fst; + struct dp_rx_fst *fst = dp_ctx->rx_fst; QDF_STATUS status; /** * FW doesn't support CMEM FSE, keep it in DDR - * soc->fst_cmem_base is non-NULL then CMEM support is already present + * dp_ctx->fst_cmem_base is non-NULL then CMEM support is + * already present */ - if (!soc->fst_in_cmem && (soc->fst_cmem_base == 0)) + if (!dp_ctx->fst_in_cmem && dp_ctx->fst_cmem_base == 0) return; status = dp_rx_fst_cmem_init(fst); if (status != QDF_STATUS_SUCCESS) return; - hal_rx_fst_detach(soc->hal_soc, fst->hal_rx_fst, soc->osdev, - soc->fst_cmem_base); + hal_rx_fst_detach(dp_ctx->hal_soc, fst->hal_rx_fst, dp_ctx->qdf_dev, + dp_ctx->fst_cmem_base); fst->hal_rx_fst = NULL; fst->hal_rx_fst_base_paddr = 0; fst->flow_deletion_supported = true; @@ -444,25 +536,25 @@ QDF_STATUS dp_rx_flow_send_fst_fw_setup(struct dp_soc *soc, struct dp_pdev *pdev) { struct dp_htt_rx_flow_fst_setup fisa_hw_fst_setup_cmd = {0}; - struct dp_rx_fst *fst = soc->rx_fst; /* TODO - Make this better */ struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + struct dp_rx_fst *fst = dp_ctx->rx_fst; QDF_STATUS status; /* check if FW has support to place FST in CMEM */ - dp_rx_fst_check_cmem_support(soc); + dp_rx_fst_check_cmem_support(dp_ctx); /* mac_id = 0 is used to configure both macs with same FT */ fisa_hw_fst_setup_cmd.pdev_id = 0; fisa_hw_fst_setup_cmd.max_entries = fst->max_entries; fisa_hw_fst_setup_cmd.max_search = fst->max_skid_length; - if (soc->fst_cmem_base) { + if (dp_ctx->fst_cmem_base) { fisa_hw_fst_setup_cmd.base_addr_lo = - soc->fst_cmem_base & 0xffffffff; + dp_ctx->fst_cmem_base & 0xffffffff; /* Higher order bits are mostly 0, Always use 0x10 */ fisa_hw_fst_setup_cmd.base_addr_hi = - (soc->fst_cmem_base >> 32) | 0x10; - dp_info("cmem base address 0x%llx", soc->fst_cmem_base); + (dp_ctx->fst_cmem_base >> 32) | 0x10; + dp_info("cmem base address 0x%llx", dp_ctx->fst_cmem_base); } else { fisa_hw_fst_setup_cmd.base_addr_lo = fst->hal_rx_fst_base_paddr & 0xffffffff; @@ -476,7 +568,7 @@ QDF_STATUS dp_rx_flow_send_fst_fw_setup(struct dp_soc *soc, status = dp_htt_rx_flow_fst_setup(pdev, &fisa_hw_fst_setup_cmd); - if (!fst->fst_in_cmem || soc->fst_cmem_base) { + if (!fst->fst_in_cmem || dp_ctx->fst_cmem_base) { /** * Return from here if fst_cmem is not enabled or cmem address * is known at init time @@ -498,14 +590,14 @@ void dp_rx_fst_detach(struct wlan_dp_psoc_context *dp_ctx) struct dp_soc *soc = (struct dp_soc *)dp_ctx->cdp_soc; struct dp_rx_fst *dp_fst; - dp_fst = soc->rx_fst; + dp_fst = dp_ctx->rx_fst; if (qdf_likely(dp_fst)) { qdf_timer_sync_cancel(&dp_fst->fse_cache_flush_timer); if (dp_fst->fst_in_cmem) dp_rx_fst_cmem_deinit(dp_fst); else hal_rx_fst_detach(soc->hal_soc, dp_fst->hal_rx_fst, - soc->osdev, soc->fst_cmem_base); + soc->osdev, dp_ctx->fst_cmem_base); dp_rx_sw_ft_hist_deinit((struct dp_fisa_rx_sw_ft *)dp_fst->base, dp_fst->max_entries); @@ -513,7 +605,8 @@ void dp_rx_fst_detach(struct wlan_dp_psoc_context *dp_ctx) qdf_spinlock_destroy(&dp_fst->dp_rx_fst_lock); qdf_mem_free(dp_fst); } - soc->rx_fst = NULL; + + dp_ctx->rx_fst = NULL; QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG, "Rx FST detached\n"); } @@ -530,22 +623,22 @@ void dp_rx_fst_detach(struct wlan_dp_psoc_context *dp_ctx) void dp_rx_fst_update_cmem_params(struct dp_soc *soc, uint16_t num_entries, uint32_t cmem_ba_lo, uint32_t cmem_ba_hi) { - struct dp_rx_fst *fst = soc->rx_fst; + struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + struct dp_rx_fst *fst = dp_ctx->rx_fst; fst->max_entries = num_entries; fst->hash_mask = fst->max_entries - 1; fst->cmem_ba = cmem_ba_lo; /* Address is not NULL then address is already known during init */ - if (soc->fst_cmem_base == 0) + if (dp_ctx->fst_cmem_base == 0) qdf_event_set(&fst->cmem_resp_event); } void dp_rx_fst_update_pm_suspend_status(struct wlan_dp_psoc_context *dp_ctx, bool suspended) { - struct dp_soc *soc = (struct dp_soc *)dp_ctx->cdp_soc; - struct dp_rx_fst *fst = soc->rx_fst; + struct dp_rx_fst *fst = dp_ctx->rx_fst; if (!fst) return; @@ -558,8 +651,7 @@ void dp_rx_fst_update_pm_suspend_status(struct wlan_dp_psoc_context *dp_ctx, void dp_rx_fst_requeue_wq(struct wlan_dp_psoc_context *dp_ctx) { - struct dp_soc *soc = (struct dp_soc *)dp_ctx->cdp_soc; - struct dp_rx_fst *fst = soc->rx_fst; + struct dp_rx_fst *fst = dp_ctx->rx_fst; if (!fst || !fst->fst_wq_defer) return; @@ -574,12 +666,12 @@ void dp_rx_fst_requeue_wq(struct wlan_dp_psoc_context *dp_ctx) QDF_STATUS dp_rx_fst_target_config(struct wlan_dp_psoc_context *dp_ctx) { - struct dp_soc *soc = (struct dp_soc *)dp_ctx->cdp_soc; + struct dp_soc *soc = cdp_soc_t_to_dp_soc(dp_ctx->cdp_soc); QDF_STATUS status; - struct dp_rx_fst *fst = soc->rx_fst; + struct dp_rx_fst *fst = dp_ctx->rx_fst; /* Check if it is enabled in the INI */ - if (!soc->fisa_enable) { + if (!dp_ctx->fisa_enable) { dp_err("RX FISA feature is disabled"); return QDF_STATUS_E_NOSUPPORT; } diff --git a/components/dp/core/src/wlan_dp_txrx.c b/components/dp/core/src/wlan_dp_txrx.c index 6298a41523..6f99880551 100644 --- a/components/dp/core/src/wlan_dp_txrx.c +++ b/components/dp/core/src/wlan_dp_txrx.c @@ -57,11 +57,9 @@ uint32_t wlan_dp_intf_get_pkt_type_bitmap_value(void *intf_ctx) } #if defined(WLAN_SUPPORT_RX_FISA) -void dp_rx_skip_fisa(struct cdp_soc_t *cdp_soc, uint32_t value) +void dp_rx_skip_fisa(struct wlan_dp_psoc_context *dp_ctx, uint32_t value) { - struct dp_soc *soc = (struct dp_soc *)cdp_soc; - - qdf_atomic_set(&soc->skip_fisa_param.skip_fisa, !value); + qdf_atomic_set(&dp_ctx->skip_fisa_param.skip_fisa, !value); } #endif @@ -1596,8 +1594,9 @@ QDF_STATUS dp_rx_flush_packet_cbk(void *dp_intf_context, uint8_t intf_id) QDF_STATUS wlan_dp_rx_fisa_cbk(void *dp_soc, void *dp_vdev, qdf_nbuf_t nbuf_list) { - return dp_fisa_rx((struct dp_soc *)dp_soc, (struct dp_vdev *)dp_vdev, - nbuf_list); + struct wlan_dp_psoc_context *dp_ctx = dp_get_context(); + + return dp_fisa_rx(dp_ctx, dp_vdev, nbuf_list); } QDF_STATUS wlan_dp_rx_fisa_flush_by_ctx_id(void *dp_soc, int ring_num) diff --git a/components/dp/dispatcher/inc/wlan_dp_api.h b/components/dp/dispatcher/inc/wlan_dp_api.h index 20703a15cf..c89334655a 100644 --- a/components/dp/dispatcher/inc/wlan_dp_api.h +++ b/components/dp/dispatcher/inc/wlan_dp_api.h @@ -21,6 +21,8 @@ #if !defined(_WLAN_DP_API_H_) #define _WLAN_DP_API_H_ +#include + /** * wlan_dp_update_peer_map_unmap_version() - update peer map unmap version * @version: Peer map unmap version pointer to be updated @@ -46,4 +48,20 @@ QDF_STATUS wlan_dp_runtime_suspend(ol_txrx_soc_handle soc, uint8_t pdev_id); * Return: QDF_STATUS */ QDF_STATUS wlan_dp_runtime_resume(ol_txrx_soc_handle soc, uint8_t pdev_id); + +/** + * wlan_dp_print_fisa_rx_stats() - Dump fisa stats + * @stats_id: ID for the stats to be dumped + * + * Return: None + */ +void wlan_dp_print_fisa_rx_stats(enum cdp_fisa_stats_id stats_id); + +/** + * wlan_dp_set_fst_in_cmem() - Set flag to indicate FST is in CMEM + * @fst_in_cmem: Flag to indicate FST is in CMEM + * + * Return: None + */ +void wlan_dp_set_fst_in_cmem(bool fst_in_cmem); #endif diff --git a/components/dp/dispatcher/src/wlan_dp_api.c b/components/dp/dispatcher/src/wlan_dp_api.c index cf41483518..c942c08009 100644 --- a/components/dp/dispatcher/src/wlan_dp_api.c +++ b/components/dp/dispatcher/src/wlan_dp_api.c @@ -20,6 +20,7 @@ #include "wlan_dp_main.h" #include "wlan_dp_api.h" +#include void wlan_dp_update_peer_map_unmap_version(uint8_t *version) { @@ -35,3 +36,13 @@ QDF_STATUS wlan_dp_runtime_resume(ol_txrx_soc_handle soc, uint8_t pdev_id) { return __wlan_dp_runtime_resume(soc, pdev_id); } + +void wlan_dp_print_fisa_rx_stats(enum cdp_fisa_stats_id stats_id) +{ + dp_print_fisa_rx_stats(stats_id); +} + +void wlan_dp_set_fst_in_cmem(bool fst_in_cmem) +{ + dp_set_fst_in_cmem(fst_in_cmem); +} diff --git a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c index 94fd53c917..a253c4b659 100644 --- a/components/dp/dispatcher/src/wlan_dp_ucfg_api.c +++ b/components/dp/dispatcher/src/wlan_dp_ucfg_api.c @@ -2371,12 +2371,12 @@ void ucfg_dp_prealloc_put_multi_pages(uint32_t desc_type, #if defined(WLAN_SUPPORT_RX_FISA) void ucfg_dp_rx_skip_fisa(uint32_t value) { - void *dp_soc; + struct wlan_dp_psoc_context *dp_ctx; - dp_soc = cds_get_context(QDF_MODULE_ID_SOC); + dp_ctx = dp_get_context(); - if (dp_soc) - dp_rx_skip_fisa(dp_soc, value); + if (dp_ctx) + dp_rx_skip_fisa(dp_ctx, value); } #endif diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index 6628867a9f..952cf2f11d 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -87,6 +87,7 @@ #include #include "wlan_dp_ucfg_api.h" #include "wlan_dp_prealloc.h" +#include "wlan_dp_api.h" #include "qdf_ipa.h" /* Preprocessor Definitions and Constants */ @@ -142,6 +143,7 @@ static struct ol_if_ops dp_ol_if_ops = { #endif .dp_get_tx_inqueue = dp_get_tx_inqueue, .dp_send_unit_test_cmd = wma_form_unit_test_cmd_and_send, + .dp_print_fisa_stats = wlan_dp_print_fisa_rx_stats, /* TODO: Add any other control path calls required to OL_IF/WMA layer */ }; #else diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 56db4d78c5..95ce3320cb 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -6620,6 +6620,9 @@ int wma_rx_service_ready_event(void *handle, uint8_t *cmd_param_info, wmi_service_enabled(wmi_handle, wmi_service_lpass); #endif /* WLAN_FEATURE_LPSS */ + if (wmi_service_enabled(wmi_handle, wmi_service_fse_cmem_alloc_support)) + wlan_dp_set_fst_in_cmem(true); + /* * This Service bit is added to check for ARP/NS Offload * support for LL/HL targets