1  /*
2   * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
3   *
4   * Permission to use, copy, modify, and/or distribute this software for
5   * any purpose with or without fee is hereby granted, provided that the
6   * above copyright notice and this permission notice appear in all
7   * copies.
8   *
9   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10   * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11   * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12   * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13   * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14   * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15   * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16   * PERFORMANCE OF THIS SOFTWARE.
17   */
18   /**
19    * DOC: wlan_dp_main.c
20    *
21    *
22    */
23  
24  #include "wlan_dp_main.h"
25  #include "wlan_dp_public_struct.h"
26  #include "cfg_ucfg_api.h"
27  #include "wlan_dp_bus_bandwidth.h"
28  #include <wlan_objmgr_psoc_obj_i.h>
29  #include <wlan_nlink_common.h>
30  #include <qdf_net_types.h>
31  #include "wlan_objmgr_vdev_obj.h"
32  #include "wlan_cm_api.h"
33  #include "wlan_dp_nud_tracking.h"
34  #include "target_if_dp_comp.h"
35  #include "wlan_dp_txrx.h"
36  #include "init_deinit_lmac.h"
37  #include <hif.h>
38  #include <htc_api.h>
39  #include <cdp_txrx_cmn_reg.h>
40  #include <cdp_txrx_bus.h>
41  #if defined(WLAN_DP_PROFILE_SUPPORT) || defined(FEATURE_DIRECT_LINK)
42  #include "cdp_txrx_ctrl.h"
43  #endif
44  #ifdef FEATURE_DIRECT_LINK
45  #include "dp_internal.h"
46  #endif
47  #include <cdp_txrx_ctrl.h>
48  
49  #ifdef WLAN_DP_PROFILE_SUPPORT
50  /* Memory profile table based on supported caps */
51  static struct wlan_dp_memory_profile_ctx wlan_dp_1x1_he80_1kqam[] = {
52  	{DP_TX_DESC_NUM_CFG, 1024},
53  	{DP_TX_EXT_DESC_NUM_CFG, 1024},
54  	{DP_TX_RING_SIZE_CFG, 1024},
55  	{DP_TX_COMPL_RING_SIZE_CFG, 1024},
56  	{DP_RX_SW_DESC_NUM_CFG, 1024},
57  	{DP_REO_DST_RING_SIZE_CFG, 1024},
58  	{DP_RXDMA_BUF_RING_SIZE_CFG, 1024},
59  	{DP_RXDMA_REFILL_RING_SIZE_CFG, 1024},
60  	{DP_RX_REFILL_POOL_NUM_CFG, 1024},
61  };
62  
63  /* Global data structure to save profile info */
64  static struct wlan_dp_memory_profile_info g_dp_profile_info;
65  #endif
66  #include <wlan_dp_fisa_rx.h>
67  
68  /* Global DP context */
69  static struct wlan_dp_psoc_context *gp_dp_ctx;
70  
dp_allocate_ctx(void)71  QDF_STATUS dp_allocate_ctx(void)
72  {
73  	struct wlan_dp_psoc_context *dp_ctx;
74  
75  	dp_ctx = qdf_mem_malloc(sizeof(*dp_ctx));
76  	if (!dp_ctx) {
77  		dp_err("Failed to create DP context");
78  		return QDF_STATUS_E_NOMEM;
79  	}
80  
81  	qdf_spinlock_create(&dp_ctx->intf_list_lock);
82  	qdf_spinlock_create(&dp_ctx->dp_link_del_lock);
83  	qdf_list_create(&dp_ctx->intf_list, 0);
84  	TAILQ_INIT(&dp_ctx->inactive_dp_link_list);
85  
86  	dp_attach_ctx(dp_ctx);
87  
88  	return QDF_STATUS_SUCCESS;
89  }
90  
dp_free_ctx(void)91  void dp_free_ctx(void)
92  {
93  	struct wlan_dp_psoc_context *dp_ctx;
94  
95  	dp_ctx =  dp_get_context();
96  
97  	qdf_spinlock_destroy(&dp_ctx->intf_list_lock);
98  	qdf_list_destroy(&dp_ctx->intf_list);
99  	dp_detach_ctx();
100  	qdf_mem_free(dp_ctx);
101  }
102  
dp_get_front_intf_no_lock(struct wlan_dp_psoc_context * dp_ctx,struct wlan_dp_intf ** out_intf)103  QDF_STATUS dp_get_front_intf_no_lock(struct wlan_dp_psoc_context *dp_ctx,
104  				     struct wlan_dp_intf **out_intf)
105  {
106  	QDF_STATUS status;
107  	qdf_list_node_t *node;
108  
109  	*out_intf = NULL;
110  
111  	status = qdf_list_peek_front(&dp_ctx->intf_list, &node);
112  
113  	if (QDF_IS_STATUS_ERROR(status))
114  		return status;
115  
116  	*out_intf = qdf_container_of(node, struct wlan_dp_intf, node);
117  
118  	return QDF_STATUS_SUCCESS;
119  }
120  
dp_get_next_intf_no_lock(struct wlan_dp_psoc_context * dp_ctx,struct wlan_dp_intf * cur_intf,struct wlan_dp_intf ** out_intf)121  QDF_STATUS dp_get_next_intf_no_lock(struct wlan_dp_psoc_context *dp_ctx,
122  				    struct wlan_dp_intf *cur_intf,
123  				    struct wlan_dp_intf **out_intf)
124  {
125  	QDF_STATUS status;
126  	qdf_list_node_t *node;
127  
128  	if (!cur_intf)
129  		return QDF_STATUS_E_INVAL;
130  
131  	*out_intf = NULL;
132  
133  	status = qdf_list_peek_next(&dp_ctx->intf_list,
134  				    &cur_intf->node,
135  				    &node);
136  
137  	if (QDF_IS_STATUS_ERROR(status))
138  		return status;
139  
140  	*out_intf = qdf_container_of(node, struct wlan_dp_intf, node);
141  
142  	return status;
143  }
144  
145  struct wlan_dp_intf*
dp_get_intf_by_macaddr(struct wlan_dp_psoc_context * dp_ctx,struct qdf_mac_addr * addr)146  dp_get_intf_by_macaddr(struct wlan_dp_psoc_context *dp_ctx,
147  		       struct qdf_mac_addr *addr)
148  {
149  	struct wlan_dp_intf *dp_intf;
150  
151  	qdf_spin_lock_bh(&dp_ctx->intf_list_lock);
152  	for (dp_get_front_intf_no_lock(dp_ctx, &dp_intf); dp_intf;
153  	     dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf)) {
154  		if (qdf_is_macaddr_equal(&dp_intf->mac_addr, addr)) {
155  			qdf_spin_unlock_bh(&dp_ctx->intf_list_lock);
156  			return dp_intf;
157  		}
158  	}
159  	qdf_spin_unlock_bh(&dp_ctx->intf_list_lock);
160  
161  	return NULL;
162  }
163  
164  struct wlan_dp_intf*
dp_get_intf_by_netdev(struct wlan_dp_psoc_context * dp_ctx,qdf_netdev_t dev)165  dp_get_intf_by_netdev(struct wlan_dp_psoc_context *dp_ctx, qdf_netdev_t dev)
166  {
167  	struct wlan_dp_intf *dp_intf;
168  
169  	qdf_spin_lock_bh(&dp_ctx->intf_list_lock);
170  	for (dp_get_front_intf_no_lock(dp_ctx, &dp_intf); dp_intf;
171  	     dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf)) {
172  		if (dp_intf->dev == dev) {
173  			qdf_spin_unlock_bh(&dp_ctx->intf_list_lock);
174  			return dp_intf;
175  		}
176  	}
177  	qdf_spin_unlock_bh(&dp_ctx->intf_list_lock);
178  
179  	return NULL;
180  }
181  
182  /**
183   * validate_link_id() - Check if link ID is valid
184   * @link_id: DP link ID
185   *
186   * Return: true on success, false on failure
187   */
validate_link_id(uint8_t link_id)188  static bool validate_link_id(uint8_t link_id)
189  {
190  	if (link_id == WLAN_UMAC_VDEV_ID_MAX) {
191  		dp_err("Interface is not up: %ps", QDF_RET_IP);
192  		return false;
193  	}
194  
195  	if (link_id >= WLAN_MAX_VDEVS) {
196  		dp_err("Bad interface id:%u", link_id);
197  		return false;
198  	}
199  
200  	return true;
201  }
202  
is_dp_intf_valid(struct wlan_dp_intf * dp_intf)203  int is_dp_intf_valid(struct wlan_dp_intf *dp_intf)
204  {
205  	if (!dp_intf) {
206  		dp_err("Interface is NULL");
207  		return -EINVAL;
208  	}
209  
210  	if (!dp_intf->dev) {
211  		dp_err("DP interface net_device is null");
212  		return -EINVAL;
213  	}
214  
215  	if (!(dp_intf->dev->flags & IFF_UP)) {
216  		dp_info_rl("DP interface '%s' is not up %ps",
217  			   dp_intf->dev->name, QDF_RET_IP);
218  		return -EAGAIN;
219  	}
220  
221  	return 0;
222  }
223  
is_dp_link_valid(struct wlan_dp_link * dp_link)224  bool is_dp_link_valid(struct wlan_dp_link *dp_link)
225  {
226  	struct wlan_dp_intf *dp_intf;
227  	int ret;
228  
229  	if (!dp_link) {
230  		dp_err("link is NULL");
231  		return false;
232  	}
233  
234  	if (dp_link->magic != WLAN_DP_LINK_MAGIC) {
235  		dp_err("dp_link %pK bad magic %llx", dp_link, dp_link->magic);
236  		return false;
237  	}
238  
239  	dp_intf = dp_link->dp_intf;
240  	ret = is_dp_intf_valid(dp_intf);
241  	if (ret)
242  		return false;
243  
244  	return validate_link_id(dp_link->link_id);
245  }
246  
dp_get_front_link_no_lock(struct wlan_dp_intf * dp_intf,struct wlan_dp_link ** out_link)247  QDF_STATUS dp_get_front_link_no_lock(struct wlan_dp_intf *dp_intf,
248  				     struct wlan_dp_link **out_link)
249  {
250  	QDF_STATUS status;
251  	qdf_list_node_t *node;
252  
253  	*out_link = NULL;
254  
255  	status = qdf_list_peek_front(&dp_intf->dp_link_list, &node);
256  
257  	if (QDF_IS_STATUS_ERROR(status))
258  		return status;
259  
260  	*out_link = qdf_container_of(node, struct wlan_dp_link, node);
261  
262  	return QDF_STATUS_SUCCESS;
263  }
264  
dp_get_next_link_no_lock(struct wlan_dp_intf * dp_intf,struct wlan_dp_link * cur_link,struct wlan_dp_link ** out_link)265  QDF_STATUS dp_get_next_link_no_lock(struct wlan_dp_intf *dp_intf,
266  				    struct wlan_dp_link *cur_link,
267  				    struct wlan_dp_link **out_link)
268  {
269  	QDF_STATUS status;
270  	qdf_list_node_t *node;
271  
272  	if (!cur_link)
273  		return QDF_STATUS_E_INVAL;
274  
275  	*out_link = NULL;
276  
277  	status = qdf_list_peek_next(&dp_intf->dp_link_list,
278  				    &cur_link->node,
279  				    &node);
280  
281  	if (QDF_IS_STATUS_ERROR(status))
282  		return status;
283  
284  	*out_link = qdf_container_of(node, struct wlan_dp_link, node);
285  
286  	return status;
287  }
288  
289  static QDF_STATUS
dp_intf_wait_for_task_complete(struct wlan_dp_intf * dp_intf)290  dp_intf_wait_for_task_complete(struct wlan_dp_intf *dp_intf)
291  {
292  	int count = DP_TASK_MAX_WAIT_CNT;
293  	int r;
294  
295  	while (count) {
296  		r = atomic_read(&dp_intf->num_active_task);
297  
298  		if (!r)
299  			return QDF_STATUS_SUCCESS;
300  
301  		if (--count) {
302  			dp_err_rl("Waiting for DP task to complete: %d", count);
303  			qdf_sleep(DP_TASK_WAIT_TIME);
304  		}
305  	}
306  
307  	dp_err("Timed-out waiting for DP task completion");
308  	return QDF_STATUS_E_TIMEOUT;
309  }
310  
dp_wait_complete_tasks(struct wlan_dp_psoc_context * dp_ctx)311  void dp_wait_complete_tasks(struct wlan_dp_psoc_context *dp_ctx)
312  {
313  	struct wlan_dp_intf *dp_intf, *dp_intf_next = NULL;
314  
315  	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
316  		/*
317  		 * If timeout happens for one interface better to bail out
318  		 * instead of waiting for other intefaces task completion
319  		 */
320  		if (qdf_atomic_read(&dp_intf->num_active_task))
321  			if (dp_intf_wait_for_task_complete(dp_intf))
322  				break;
323  	}
324  }
325  
326  #ifdef CONFIG_DP_TRACE
327  /**
328   * dp_convert_string_to_array() - used to convert string into u8 array
329   * @str: String to be converted
330   * @array: Array where converted value is stored
331   * @len: Length of the populated array
332   * @array_max_len: Maximum length of the array
333   * @to_hex: true, if conversion required for hex string
334   *
335   * This API is called to convert string (each byte separated by
336   * a comma) into an u8 array
337   *
338   * Return: QDF_STATUS
339   */
dp_convert_string_to_array(char * str,uint8_t * array,uint8_t * len,uint16_t array_max_len,bool to_hex)340  static QDF_STATUS dp_convert_string_to_array(char *str, uint8_t *array,
341  					     uint8_t *len,
342  					     uint16_t array_max_len,
343  					     bool to_hex)
344  {
345  	char *format, *s = str;
346  
347  	if (!str || !array || !len)
348  		return QDF_STATUS_E_INVAL;
349  
350  	format = (to_hex) ? "%02x" : "%d";
351  
352  	*len = 0;
353  	while ((s) && (*len < array_max_len)) {
354  		int val;
355  		/* Increment length only if sscanf successfully extracted
356  		 * one element. Any other return value means error.
357  		 * Ignore it.
358  		 */
359  		if (sscanf(s, format, &val) == 1) {
360  			array[*len] = (uint8_t)val;
361  			*len += 1;
362  		}
363  
364  		s = strpbrk(s, ",");
365  		if (s)
366  			s++;
367  	}
368  
369  	return QDF_STATUS_SUCCESS;
370  }
371  
372  /**
373   * dp_string_to_u8_array() - used to convert string into u8 array
374   * @str: String to be converted
375   * @array: Array where converted value is stored
376   * @len: Length of the populated array
377   * @array_max_len: Maximum length of the array
378   *
379   * Return: QDF_STATUS
380   */
381  static
dp_string_to_u8_array(char * str,uint8_t * array,uint8_t * len,uint16_t array_max_len)382  QDF_STATUS dp_string_to_u8_array(char *str, uint8_t *array,
383  				 uint8_t *len, uint16_t array_max_len)
384  {
385  	return dp_convert_string_to_array(str, array, len,
386  					  array_max_len, false);
387  }
388  
dp_trace_init(struct wlan_objmgr_psoc * psoc)389  void dp_trace_init(struct wlan_objmgr_psoc *psoc)
390  {
391  	struct wlan_dp_psoc_context *dp_ctx;
392  	struct wlan_dp_psoc_cfg *config;
393  	bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
394  	uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
395  	uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
396  	uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
397  	uint32_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
398  	uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
399  	uint8_t num_entries = 0;
400  	uint32_t bw_compute_interval;
401  
402  	dp_ctx = dp_psoc_get_priv(psoc);
403  	if (!dp_ctx) {
404  		dp_err("Unable to get DP context");
405  		return;
406  	}
407  
408  	config = &dp_ctx->dp_cfg;
409  
410  	qdf_dp_set_proto_event_bitmap(config->dp_proto_event_bitmap);
411  
412  	if (!config->enable_dp_trace) {
413  		dp_err("dp trace is disabled from ini");
414  		return;
415  	}
416  
417  	dp_string_to_u8_array(config->dp_trace_config, config_params,
418  			      &num_entries, sizeof(config_params));
419  
420  	/* calculating, num bw timer intervals in a second (1000ms) */
421  	bw_compute_interval = DP_BUS_BW_CFG(config->bus_bw_compute_interval);
422  
423  	if (bw_compute_interval <= 1000 && bw_compute_interval > 0) {
424  		thresh_time_limit = 1000 / bw_compute_interval;
425  	} else if (bw_compute_interval > 1000) {
426  		dp_err("busBandwidthComputeInterval > 1000, using 1000");
427  		thresh_time_limit = 1;
428  	} else {
429  		dp_err("busBandwidthComputeInterval is 0, using defaults");
430  	}
431  
432  	switch (num_entries) {
433  	case 4:
434  		proto_bitmap = config_params[3];
435  		fallthrough;
436  	case 3:
437  		verbosity = config_params[2];
438  		fallthrough;
439  	case 2:
440  		thresh = config_params[1];
441  		fallthrough;
442  	case 1:
443  		live_mode = config_params[0];
444  		fallthrough;
445  	default:
446  		dp_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
447  			 live_mode, thresh, thresh_time_limit,
448  			 verbosity, proto_bitmap);
449  	};
450  
451  	qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
452  			  verbosity, proto_bitmap);
453  }
454  
dp_set_dump_dp_trace(uint16_t cmd_type,uint16_t count)455  void dp_set_dump_dp_trace(uint16_t cmd_type, uint16_t count)
456  {
457  	dp_debug("DUMP_DP_TRACE_LEVEL: %d %d",
458  		 cmd_type, count);
459  	if (cmd_type == DUMP_DP_TRACE)
460  		qdf_dp_trace_dump_all(count, QDF_TRACE_DEFAULT_PDEV_ID);
461  	else if (cmd_type == ENABLE_DP_TRACE_LIVE_MODE)
462  		qdf_dp_trace_enable_live_mode();
463  	else if (cmd_type == CLEAR_DP_TRACE_BUFFER)
464  		qdf_dp_trace_clear_buffer();
465  	else if (cmd_type == DISABLE_DP_TRACE_LIVE_MODE)
466  		qdf_dp_trace_disable_live_mode();
467  }
468  #else
dp_trace_init(struct wlan_objmgr_psoc * psoc)469  void dp_trace_init(struct wlan_objmgr_psoc *psoc)
470  {
471  }
472  
dp_set_dump_dp_trace(uint16_t cmd_type,uint16_t count)473  void dp_set_dump_dp_trace(uint16_t cmd_type, uint16_t count)
474  {
475  }
476  #endif
477  #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
478  /**
479   * dp_ini_bus_bandwidth() - Initialize INIs concerned about bus bandwidth
480   * @config: pointer to dp config
481   * @psoc: pointer to psoc obj
482   *
483   * Return: none
484   */
dp_ini_bus_bandwidth(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)485  static void dp_ini_bus_bandwidth(struct wlan_dp_psoc_cfg *config,
486  				 struct wlan_objmgr_psoc *psoc)
487  {
488  	config->bus_bw_super_high_threshold =
489  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_SUPER_HIGH_THRESHOLD);
490  	config->bus_bw_ultra_high_threshold =
491  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_ULTRA_HIGH_THRESHOLD);
492  	config->bus_bw_very_high_threshold =
493  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_VERY_HIGH_THRESHOLD);
494  	config->bus_bw_dbs_threshold =
495  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_DBS_THRESHOLD);
496  	config->bus_bw_mid_high_threshold =
497  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_MID_HIGH_THRESHOLD);
498  	config->bus_bw_high_threshold =
499  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_HIGH_THRESHOLD);
500  	config->bus_bw_medium_threshold =
501  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_MEDIUM_THRESHOLD);
502  	config->bus_bw_low_threshold =
503  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD);
504  	config->bus_bw_compute_interval =
505  		cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_COMPUTE_INTERVAL);
506  	config->bus_low_cnt_threshold =
507  		cfg_get(psoc, CFG_DP_BUS_LOW_BW_CNT_THRESHOLD);
508  	config->enable_latency_crit_clients =
509  		cfg_get(psoc, CFG_DP_BUS_HANDLE_LATENCY_CRITICAL_CLIENTS);
510  }
511  
512  /**
513   * dp_ini_tcp_settings() - Initialize INIs concerned about tcp settings
514   * @config: pointer to dp config
515   * @psoc: pointer to psoc obj
516   *
517   * Return: none
518   */
dp_ini_tcp_settings(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)519  static void dp_ini_tcp_settings(struct wlan_dp_psoc_cfg *config,
520  				struct wlan_objmgr_psoc *psoc)
521  {
522  	config->enable_tcp_limit_output =
523  		cfg_get(psoc, CFG_DP_ENABLE_TCP_LIMIT_OUTPUT);
524  	config->enable_tcp_adv_win_scale =
525  		cfg_get(psoc, CFG_DP_ENABLE_TCP_ADV_WIN_SCALE);
526  	config->enable_tcp_delack =
527  		cfg_get(psoc, CFG_DP_ENABLE_TCP_DELACK);
528  	config->tcp_delack_thres_high =
529  		cfg_get(psoc, CFG_DP_TCP_DELACK_THRESHOLD_HIGH);
530  	config->tcp_delack_thres_low =
531  		cfg_get(psoc, CFG_DP_TCP_DELACK_THRESHOLD_LOW);
532  	config->tcp_delack_timer_count =
533  		cfg_get(psoc, CFG_DP_TCP_DELACK_TIMER_COUNT);
534  	config->tcp_tx_high_tput_thres =
535  		cfg_get(psoc, CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD);
536  	config->enable_tcp_param_update =
537  		cfg_get(psoc, CFG_DP_ENABLE_TCP_PARAM_UPDATE);
538  }
539  
540  #else
dp_ini_bus_bandwidth(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)541  static void dp_ini_bus_bandwidth(struct wlan_dp_psoc_cfg *config,
542  				 struct wlan_objmgr_psoc *psoc)
543  {
544  }
545  
dp_ini_tcp_settings(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)546  static void dp_ini_tcp_settings(struct wlan_dp_psoc_cfg *config,
547  				struct wlan_objmgr_psoc *psoc)
548  {
549  }
550  #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
551  
552  #ifdef CONFIG_DP_TRACE
553  /**
554   * dp_trace_cfg_update() - initialize DP Trace config
555   * @config : Configuration parameters
556   * @psoc: psoc handle
557   */
558  static void
dp_trace_cfg_update(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)559  dp_trace_cfg_update(struct wlan_dp_psoc_cfg *config,
560  		    struct wlan_objmgr_psoc *psoc)
561  {
562  	qdf_size_t array_out_size;
563  
564  	config->enable_dp_trace = cfg_get(psoc, CFG_DP_ENABLE_DP_TRACE);
565  	qdf_uint8_array_parse(cfg_get(psoc, CFG_DP_DP_TRACE_CONFIG),
566  			      config->dp_trace_config,
567  			      sizeof(config->dp_trace_config), &array_out_size);
568  	config->dp_proto_event_bitmap = cfg_get(psoc,
569  						CFG_DP_PROTO_EVENT_BITMAP);
570  }
571  #else
572  static void
dp_trace_cfg_update(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)573  dp_trace_cfg_update(struct wlan_dp_psoc_cfg *config,
574  		    struct wlan_objmgr_psoc *psoc)
575  {
576  }
577  #endif
578  #ifdef WLAN_NUD_TRACKING
579  /**
580   * dp_nud_tracking_cfg_update() - initialize NUD Tracking config
581   * @config : Configuration parameters
582   * @psoc: psoc handle
583   */
584  static void
dp_nud_tracking_cfg_update(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)585  dp_nud_tracking_cfg_update(struct wlan_dp_psoc_cfg *config,
586  			   struct wlan_objmgr_psoc *psoc)
587  {
588  	config->enable_nud_tracking = cfg_get(psoc, CFG_DP_ENABLE_NUD_TRACKING);
589  }
590  #else
591  static void
dp_nud_tracking_cfg_update(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)592  dp_nud_tracking_cfg_update(struct wlan_dp_psoc_cfg *config,
593  			   struct wlan_objmgr_psoc *psoc)
594  {
595  }
596  #endif
597  
598  #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
599  /**
600   * dp_ini_tcp_del_ack_settings() - initialize TCP delack config
601   * @config : Configuration parameters
602   * @psoc: psoc handle
603   */
dp_ini_tcp_del_ack_settings(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)604  static void dp_ini_tcp_del_ack_settings(struct wlan_dp_psoc_cfg *config,
605  					struct wlan_objmgr_psoc *psoc)
606  {
607  	config->del_ack_threshold_high =
608  		cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_HIGH_THRESHOLD);
609  	config->del_ack_threshold_low =
610  		cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_LOW_THRESHOLD);
611  	config->del_ack_enable =
612  		cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_ENABLE);
613  	config->del_ack_pkt_count =
614  		cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_PKT_CNT);
615  	config->del_ack_timer_value =
616  		cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_TIMER_VALUE);
617  }
618  #else
dp_ini_tcp_del_ack_settings(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)619  static void dp_ini_tcp_del_ack_settings(struct wlan_dp_psoc_cfg *config,
620  					struct wlan_objmgr_psoc *psoc)
621  {
622  }
623  #endif
624  
625  #ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE
626  /**
627   * dp_hl_bundle_cfg_update() - initialize TxRx HL bundle config
628   * @config : Configuration parameters
629   * @psoc: psoc handle
630   */
dp_hl_bundle_cfg_update(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)631  static void dp_hl_bundle_cfg_update(struct wlan_dp_psoc_cfg *config,
632  				    struct wlan_objmgr_psoc *psoc)
633  {
634  	config->pkt_bundle_threshold_high =
635  		cfg_get(psoc, CFG_DP_HL_BUNDLE_HIGH_TH);
636  	config->pkt_bundle_threshold_low =
637  		cfg_get(psoc, CFG_DP_HL_BUNDLE_LOW_TH);
638  	config->pkt_bundle_timer_value =
639  		cfg_get(psoc, CFG_DP_HL_BUNDLE_TIMER_VALUE);
640  	config->pkt_bundle_size =
641  		cfg_get(psoc, CFG_DP_HL_BUNDLE_SIZE);
642  }
643  #else
dp_hl_bundle_cfg_update(struct wlan_dp_psoc_cfg * config,struct wlan_objmgr_psoc * psoc)644  static void dp_hl_bundle_cfg_update(struct wlan_dp_psoc_cfg *config,
645  				    struct wlan_objmgr_psoc *psoc)
646  {
647  }
648  #endif
649  
650  /**
651   * dp_set_rx_mode_value() - set rx_mode values
652   * @dp_ctx: DP context
653   *
654   * Return: none
655   */
dp_set_rx_mode_value(struct wlan_dp_psoc_context * dp_ctx)656  static void dp_set_rx_mode_value(struct wlan_dp_psoc_context *dp_ctx)
657  {
658  	uint32_t rx_mode = dp_ctx->dp_cfg.rx_mode;
659  	enum QDF_GLOBAL_MODE con_mode = 0;
660  
661  	con_mode = cds_get_conparam();
662  
663  	/* RPS has higher priority than dynamic RPS when both bits are set */
664  	if (rx_mode & CFG_ENABLE_RPS && rx_mode & CFG_ENABLE_DYNAMIC_RPS)
665  		rx_mode &= ~CFG_ENABLE_DYNAMIC_RPS;
666  
667  	if (rx_mode & CFG_ENABLE_RX_THREAD && rx_mode & CFG_ENABLE_RPS) {
668  		dp_warn("rx_mode wrong configuration. Make it default");
669  		rx_mode = CFG_RX_MODE_DEFAULT;
670  	}
671  
672  	if (rx_mode & CFG_ENABLE_RX_THREAD) {
673  		dp_ctx->enable_rxthread = true;
674  	} else if (rx_mode & CFG_ENABLE_DP_RX_THREADS) {
675  		if (con_mode == QDF_GLOBAL_MONITOR_MODE)
676  			dp_ctx->enable_dp_rx_threads = false;
677  		else
678  			dp_ctx->enable_dp_rx_threads = true;
679  	}
680  
681  	if (rx_mode & CFG_ENABLE_RPS)
682  		dp_ctx->rps = true;
683  
684  	if (rx_mode & CFG_ENABLE_NAPI)
685  		dp_ctx->napi_enable = true;
686  
687  	if (rx_mode & CFG_ENABLE_DYNAMIC_RPS)
688  		dp_ctx->dynamic_rps = true;
689  
690  	dp_info("rx_mode:%u dp_rx_threads:%u rx_thread:%u napi:%u rps:%u dynamic rps %u",
691  		rx_mode, dp_ctx->enable_dp_rx_threads,
692  		dp_ctx->enable_rxthread, dp_ctx->napi_enable,
693  		dp_ctx->rps, dp_ctx->dynamic_rps);
694  }
695  
696  /**
697   * dp_cfg_init() - initialize target specific configuration
698   * @ctx: dp context handle
699   */
dp_cfg_init(struct wlan_dp_psoc_context * ctx)700  static void dp_cfg_init(struct wlan_dp_psoc_context *ctx)
701  {
702  	struct wlan_dp_psoc_cfg *config = &ctx->dp_cfg;
703  	struct wlan_objmgr_psoc *psoc = ctx->psoc;
704  	uint16_t cfg_len;
705  
706  	cfg_len = qdf_str_len(cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST))
707  		  + 1;
708  	dp_ini_bus_bandwidth(config, psoc);
709  	dp_ini_tcp_settings(config, psoc);
710  
711  	dp_ini_tcp_del_ack_settings(config, psoc);
712  
713  	dp_hl_bundle_cfg_update(config, psoc);
714  
715  	config->rx_thread_ul_affinity_mask =
716  		cfg_get(psoc, CFG_DP_RX_THREAD_UL_CPU_MASK);
717  	config->rx_thread_affinity_mask =
718  		cfg_get(psoc, CFG_DP_RX_THREAD_CPU_MASK);
719  	if (cfg_len < CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN) {
720  		qdf_str_lcopy(config->cpu_map_list,
721  			      cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST),
722  			      cfg_len);
723  	} else {
724  		dp_err("ini string length greater than max size %d",
725  		       CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN);
726  		cfg_len = qdf_str_len(cfg_default(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST));
727  		qdf_str_lcopy(config->cpu_map_list,
728  			      cfg_default(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST),
729  			      cfg_len);
730  	}
731  	config->tx_orphan_enable = cfg_get(psoc, CFG_DP_TX_ORPHAN_ENABLE);
732  	config->rx_mode = cfg_get(psoc, CFG_DP_RX_MODE);
733  	dp_set_rx_mode_value(ctx);
734  	config->multicast_replay_filter =
735  		cfg_get(psoc, CFG_DP_FILTER_MULTICAST_REPLAY);
736  	config->rx_wakelock_timeout =
737  		cfg_get(psoc, CFG_DP_RX_WAKELOCK_TIMEOUT);
738  	config->num_dp_rx_threads = cfg_get(psoc, CFG_DP_NUM_DP_RX_THREADS);
739  	config->icmp_req_to_fw_mark_interval =
740  		cfg_get(psoc, CFG_DP_ICMP_REQ_TO_FW_MARK_INTERVAL);
741  
742  	config->rx_softirq_max_yield_duration_ns =
743  		cfg_get(psoc,
744  			CFG_DP_RX_SOFTIRQ_MAX_YIELD_TIME_NS);
745  
746  	dp_trace_cfg_update(config, psoc);
747  	dp_nud_tracking_cfg_update(config, psoc);
748  	dp_trace_cfg_update(config, psoc);
749  	dp_fisa_cfg_init(config, psoc);
750  }
751  
752  /**
753   * __dp_process_mic_error() - Indicate mic error to supplicant
754   * @dp_intf: Pointer to dp interface
755   *
756   * Return: None
757   */
758  static void
__dp_process_mic_error(struct wlan_dp_intf * dp_intf)759  __dp_process_mic_error(struct wlan_dp_intf *dp_intf)
760  {
761  	struct wlan_dp_psoc_callbacks *ops = &dp_intf->dp_ctx->dp_ops;
762  	struct wlan_objmgr_vdev *vdev;
763  
764  	vdev = dp_objmgr_get_vdev_by_user(dp_intf->def_link, WLAN_DP_ID);
765  	if (!vdev) {
766  		return;
767  	}
768  
769  	if ((dp_intf->device_mode == QDF_STA_MODE ||
770  	     dp_intf->device_mode == QDF_P2P_CLIENT_MODE) &&
771  	    wlan_cm_is_vdev_active(vdev))
772  		ops->osif_dp_process_mic_error(dp_intf->mic_work.info,
773  						   vdev);
774  	else if (dp_intf->device_mode == QDF_SAP_MODE ||
775  		 dp_intf->device_mode == QDF_P2P_GO_MODE)
776  		ops->osif_dp_process_mic_error(dp_intf->mic_work.info,
777  						   vdev);
778  	else
779  		dp_err("Invalid interface type:%d", dp_intf->device_mode);
780  
781  	dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
782  }
783  
784  /**
785   * dp_process_mic_error() - process mic error work
786   * @data: void pointer to dp interface
787   *
788   * Return: None
789   */
790  static void
dp_process_mic_error(void * data)791  dp_process_mic_error(void *data)
792  {
793  	struct wlan_dp_intf *dp_intf = data;
794  
795  	if (is_dp_intf_valid(dp_intf))
796  		goto exit;
797  
798  	__dp_process_mic_error(dp_intf);
799  
800  exit:
801  	qdf_spin_lock_bh(&dp_intf->mic_work.lock);
802  	if (dp_intf->mic_work.info) {
803  		qdf_mem_free(dp_intf->mic_work.info);
804  		dp_intf->mic_work.info = NULL;
805  	}
806  	if (dp_intf->mic_work.status == DP_MIC_SCHEDULED)
807  		dp_intf->mic_work.status = DP_MIC_INITIALIZED;
808  	qdf_spin_unlock_bh(&dp_intf->mic_work.lock);
809  }
810  
811  void
dp_rx_mic_error_ind(struct cdp_ctrl_objmgr_psoc * psoc,uint8_t pdev_id,struct cdp_rx_mic_err_info * mic_failure_info)812  dp_rx_mic_error_ind(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id,
813  		    struct cdp_rx_mic_err_info *mic_failure_info)
814  {
815  	struct dp_mic_error_info *dp_mic_info;
816  	struct wlan_objmgr_vdev *vdev;
817  	struct wlan_dp_intf *dp_intf;
818  	struct wlan_dp_link *dp_link;
819  
820  	if (!psoc)
821  		return;
822  
823  	vdev = wlan_objmgr_get_vdev_by_id_from_psoc((struct wlan_objmgr_psoc *)psoc,
824  						    mic_failure_info->vdev_id,
825  						    WLAN_DP_ID);
826  	if (!vdev)
827  		return;
828  	dp_link = dp_get_vdev_priv_obj(vdev);
829  	if (!dp_link) {
830  		dp_comp_vdev_put_ref(vdev);
831  		return;
832  	}
833  
834  	dp_intf = dp_link->dp_intf;
835  	dp_mic_info = qdf_mem_malloc(sizeof(*dp_mic_info));
836  	if (!dp_mic_info) {
837  		dp_comp_vdev_put_ref(vdev);
838  		return;
839  	}
840  
841  	qdf_copy_macaddr(&dp_mic_info->ta_mac_addr,
842  			 &mic_failure_info->ta_mac_addr);
843  	dp_mic_info->multicast = mic_failure_info->multicast;
844  	dp_mic_info->key_id = mic_failure_info->key_id;
845  	qdf_mem_copy(&dp_mic_info->tsc, &mic_failure_info->tsc,
846  		     SIR_CIPHER_SEQ_CTR_SIZE);
847  	dp_mic_info->vdev_id = mic_failure_info->vdev_id;
848  
849  	qdf_spin_lock_bh(&dp_intf->mic_work.lock);
850  	if (dp_intf->mic_work.status != DP_MIC_INITIALIZED) {
851  		qdf_spin_unlock_bh(&dp_intf->mic_work.lock);
852  		qdf_mem_free(dp_mic_info);
853  		dp_comp_vdev_put_ref(vdev);
854  		return;
855  	}
856  	/*
857  	 * Store mic error info pointer in dp_intf
858  	 * for freeing up the allocated memory in case
859  	 * the work scheduled below is flushed or deinitialized.
860  	 */
861  	dp_intf->mic_work.status = DP_MIC_SCHEDULED;
862  	dp_intf->mic_work.info = dp_mic_info;
863  	qdf_sched_work(0, &dp_intf->mic_work.work);
864  	qdf_spin_unlock_bh(&dp_intf->mic_work.lock);
865  	dp_comp_vdev_put_ref(vdev);
866  }
867  
868  /**
869   * dp_mic_flush_work() - disable and flush pending mic work
870   * @dp_intf: Pointer to dp interface
871   *
872   * Return: None
873   */
874  static void
dp_mic_flush_work(struct wlan_dp_intf * dp_intf)875  dp_mic_flush_work(struct wlan_dp_intf *dp_intf)
876  {
877  	dp_info("Flush the MIC error work");
878  
879  	qdf_spin_lock_bh(&dp_intf->mic_work.lock);
880  	if (dp_intf->mic_work.status != DP_MIC_SCHEDULED) {
881  		qdf_spin_unlock_bh(&dp_intf->mic_work.lock);
882  		return;
883  	}
884  	dp_intf->mic_work.status = DP_MIC_DISABLED;
885  	qdf_spin_unlock_bh(&dp_intf->mic_work.lock);
886  
887  	qdf_flush_work(&dp_intf->mic_work.work);
888  }
889  
890  /**
891   * dp_mic_enable_work() - enable mic error work
892   * @dp_intf: Pointer to dp interface
893   *
894   * Return: None
895   */
dp_mic_enable_work(struct wlan_dp_intf * dp_intf)896  static void dp_mic_enable_work(struct wlan_dp_intf *dp_intf)
897  {
898  	dp_info("Enable the MIC error work");
899  
900  	qdf_spin_lock_bh(&dp_intf->mic_work.lock);
901  	if (dp_intf->mic_work.status == DP_MIC_DISABLED)
902  		dp_intf->mic_work.status = DP_MIC_INITIALIZED;
903  	qdf_spin_unlock_bh(&dp_intf->mic_work.lock);
904  }
905  
dp_mic_deinit_work(struct wlan_dp_intf * dp_intf)906  void dp_mic_deinit_work(struct wlan_dp_intf *dp_intf)
907  {
908  	dp_info("DeInitialize the MIC error work");
909  
910  	if (dp_intf->mic_work.status != DP_MIC_UNINITIALIZED) {
911  		qdf_destroy_work(NULL, &dp_intf->mic_work.work);
912  
913  		qdf_spin_lock_bh(&dp_intf->mic_work.lock);
914  		dp_intf->mic_work.status = DP_MIC_UNINITIALIZED;
915  		if (dp_intf->mic_work.info) {
916  			qdf_mem_free(dp_intf->mic_work.info);
917  			dp_intf->mic_work.info = NULL;
918  		}
919  		qdf_spin_unlock_bh(&dp_intf->mic_work.lock);
920  		qdf_spinlock_destroy(&dp_intf->mic_work.lock);
921  	}
922  }
923  
dp_mic_init_work(struct wlan_dp_intf * dp_intf)924  void dp_mic_init_work(struct wlan_dp_intf *dp_intf)
925  {
926  	qdf_spinlock_create(&dp_intf->mic_work.lock);
927  	qdf_create_work(0, &dp_intf->mic_work.work,
928  			dp_process_mic_error, dp_intf);
929  	dp_intf->mic_work.status = DP_MIC_INITIALIZED;
930  	dp_intf->mic_work.info = NULL;
931  }
932  
933  #ifdef WLAN_FEATURE_11BE_MLO
934  /**
935   * dp_intf_get_next_deflink_candidate() - Get a candidate link from the list of
936   *					  links available in the dp interface.
937   * @dp_intf: DP interface handle
938   * @cur_def_link: Handle to current def_link in the DP interface
939   *
940   * Return: Handle of the candidate for next def_link
941   *	   NULL, if there is no other suitable candidate found.
942   */
943  static struct wlan_dp_link *
dp_intf_get_next_deflink_candidate(struct wlan_dp_intf * dp_intf,struct wlan_dp_link * cur_def_link)944  dp_intf_get_next_deflink_candidate(struct wlan_dp_intf *dp_intf,
945  				   struct wlan_dp_link *cur_def_link)
946  {
947  	struct wlan_dp_link *dp_link, *dp_link_next;
948  
949  	dp_for_each_link_held_safe(dp_intf, dp_link, dp_link_next) {
950  		/*
951  		 * dp_link is removed from the list when its deleted.
952  		 * But check if its valid or not. Additional check to make
953  		 * sure that the next deflink is valid.
954  		 */
955  		if (!is_dp_link_valid(dp_link))
956  			continue;
957  
958  		if (dp_link !=  cur_def_link)
959  			return dp_link;
960  	}
961  
962  	return NULL;
963  }
964  
965  /**
966   * dp_change_def_link() - Change default link for the dp_intf
967   * @dp_intf: DP interface for which default link is to be changed
968   * @dp_link: link on which link switch notification arrived.
969   * @lswitch_req: Link switch request params
970   *
971   * This API is called only when dp_intf->def_link == dp_link,
972   * and there is a need to change the def_link of the dp_intf,
973   * due to any reason.
974   *
975   * Return: QDF_STATUS
976   */
977  static inline QDF_STATUS
dp_change_def_link(struct wlan_dp_intf * dp_intf,struct wlan_dp_link * dp_link,struct wlan_mlo_link_switch_req * lswitch_req)978  dp_change_def_link(struct wlan_dp_intf *dp_intf,
979  		   struct wlan_dp_link *dp_link,
980  		   struct wlan_mlo_link_switch_req *lswitch_req)
981  {
982  	struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx;
983  	struct wlan_dp_link *next_def_link;
984  	cdp_config_param_type peer_param = {0};
985  	QDF_STATUS status;
986  
987  	next_def_link = dp_intf_get_next_deflink_candidate(dp_intf, dp_link);
988  	if (!is_dp_link_valid(next_def_link)) {
989  		/* Unable to get candidate for next def_link */
990  		dp_info("Unable to get next def link %pK", next_def_link);
991  		return QDF_STATUS_E_FAILURE;
992  	}
993  
994  	/*
995  	 * Switch dp_vdev related params
996  	 *  - Change vdev of MLD peer.
997  	 */
998  	dp_info("Peer " QDF_MAC_ADDR_FMT ", change vdev %d -> %d",
999  		QDF_MAC_ADDR_REF(lswitch_req->peer_mld_addr.bytes),
1000  		dp_link->link_id, next_def_link->link_id);
1001  	peer_param.new_vdev_id = next_def_link->link_id;
1002  	status = cdp_txrx_set_peer_param(dp_ctx->cdp_soc,
1003  					 /* Current vdev for remote MLD peer */
1004  					 dp_link->link_id,
1005  					 lswitch_req->peer_mld_addr.bytes,
1006  					 CDP_CONFIG_MLD_PEER_VDEV,
1007  					 peer_param);
1008  
1009  	/*
1010  	 * DP link switch checks and process is completed successfully.
1011  	 * Change the def_link to the partner link
1012  	 */
1013  	if (QDF_IS_STATUS_SUCCESS(status))
1014  		dp_intf->def_link = next_def_link;
1015  
1016  	return status;
1017  }
1018  
1019  QDF_STATUS
dp_link_switch_notification(struct wlan_objmgr_vdev * vdev,struct wlan_mlo_link_switch_req * lswitch_req,enum wlan_mlo_link_switch_notify_reason notify_reason)1020  dp_link_switch_notification(struct wlan_objmgr_vdev *vdev,
1021  			    struct wlan_mlo_link_switch_req *lswitch_req,
1022  			    enum wlan_mlo_link_switch_notify_reason notify_reason)
1023  {
1024  	/* Add prints to string and print it at last, so we have only 1 print */
1025  	struct wlan_dp_psoc_context *dp_ctx;
1026  	struct wlan_dp_intf *dp_intf;
1027  	struct wlan_dp_link *dp_link;
1028  	QDF_STATUS status = QDF_STATUS_SUCCESS;
1029  
1030  	/*
1031  	 * Currently DP handles link switch notification only if the command
1032  	 * is in serialization's active queue.
1033  	 * Return success for other notify reasons which are not handled in DP.
1034  	 */
1035  	if (notify_reason != MLO_LINK_SWITCH_NOTIFY_REASON_PRE_START_POST_SER)
1036  		return QDF_STATUS_SUCCESS;
1037  
1038  	dp_ctx = dp_get_context();
1039  
1040  	dp_link = dp_get_vdev_priv_obj(vdev);
1041  	if (!is_dp_link_valid(dp_link)) {
1042  		dp_err("dp_link from vdev %pK is invalid", vdev);
1043  		return QDF_STATUS_E_INVAL;
1044  	}
1045  
1046  	dp_intf = dp_link->dp_intf;
1047  	dp_info("Link switch req for dp_link %pK id %d (" QDF_MAC_ADDR_FMT
1048  		"), dp_intf %pK (" QDF_MAC_ADDR_FMT
1049  		") cur_def_link %pK id %d device_mode %d num_links %d",
1050  		dp_link, dp_link->link_id,
1051  		QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes),
1052  		dp_intf, QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes),
1053  		dp_intf->def_link, dp_intf->def_link->link_id,
1054  		dp_intf->device_mode, dp_intf->num_links);
1055  
1056  	if (dp_intf->device_mode != QDF_STA_MODE) {
1057  		/* Link switch supported only for STA mode */
1058  		status = QDF_STATUS_E_INVAL;
1059  		goto exit;
1060  	}
1061  
1062  	if (dp_intf->num_links == 1) {
1063  		/* There is only one link, so we cannot switch */
1064  		status = QDF_STATUS_E_CANCELED;
1065  		goto exit;
1066  	}
1067  
1068  	if (dp_link != dp_intf->def_link) {
1069  		/* default link is not being switched, so DP is fine */
1070  		goto exit;
1071  	}
1072  
1073  	/* Recipe to be done before switching a default link */
1074  	status = dp_change_def_link(dp_intf, dp_link, lswitch_req);
1075  	if (QDF_IS_STATUS_ERROR(status)) {
1076  		/* Failed to switch default link */
1077  		dp_info("Failed to change def_link for dp_intf %pK", dp_intf);
1078  		goto exit;
1079  	}
1080  
1081  exit:
1082  	dp_info("Link switch req %s (ret %d) for dp_link %pK id %d ("
1083  		QDF_MAC_ADDR_FMT "), dp_intf %pK (" QDF_MAC_ADDR_FMT
1084  		") cur_def_link %pK id %d device_mode %d num_links %d",
1085  		QDF_IS_STATUS_ERROR(status) ? "Failed" : "Successful",
1086  		status, dp_link, dp_link->link_id,
1087  		QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes),
1088  		dp_intf, QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes),
1089  		dp_intf->def_link, dp_intf->def_link->link_id,
1090  		dp_intf->device_mode, dp_intf->num_links);
1091  
1092  	return status;
1093  }
1094  #else
1095  static struct wlan_dp_link *
dp_intf_get_next_deflink_candidate(struct wlan_dp_intf * dp_intf,struct wlan_dp_link * cur_def_link)1096  dp_intf_get_next_deflink_candidate(struct wlan_dp_intf *dp_intf,
1097  				   struct wlan_dp_link *cur_def_link)
1098  {
1099  	return NULL;
1100  }
1101  #endif
1102  
1103  QDF_STATUS
dp_peer_obj_create_notification(struct wlan_objmgr_peer * peer,void * arg)1104  dp_peer_obj_create_notification(struct wlan_objmgr_peer *peer, void *arg)
1105  {
1106  	struct wlan_dp_sta_info *sta_info;
1107  	QDF_STATUS status;
1108  
1109  	sta_info = qdf_mem_malloc(sizeof(*sta_info));
1110  	if (!sta_info)
1111  		return QDF_STATUS_E_NOMEM;
1112  
1113  	status = wlan_objmgr_peer_component_obj_attach(peer, WLAN_COMP_DP,
1114  						       sta_info,
1115  						       QDF_STATUS_SUCCESS);
1116  	if (QDF_IS_STATUS_ERROR(status)) {
1117  		dp_err("DP peer ("QDF_MAC_ADDR_FMT") attach failed",
1118  			QDF_MAC_ADDR_REF(peer->macaddr));
1119  		qdf_mem_free(sta_info);
1120  		return status;
1121  	}
1122  
1123  	qdf_mem_copy(sta_info->sta_mac.bytes, peer->macaddr,
1124  		     QDF_MAC_ADDR_SIZE);
1125  	sta_info->pending_eap_frm_type = 0;
1126  	sta_info->dhcp_phase = DHCP_PHASE_ACK;
1127  	sta_info->dhcp_nego_status = DHCP_NEGO_STOP;
1128  
1129  	dp_info("sta info created mac:" QDF_MAC_ADDR_FMT,
1130  		QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes));
1131  
1132  	return status;
1133  }
1134  
1135  QDF_STATUS
dp_peer_obj_destroy_notification(struct wlan_objmgr_peer * peer,void * arg)1136  dp_peer_obj_destroy_notification(struct wlan_objmgr_peer *peer, void *arg)
1137  {
1138  	struct wlan_dp_sta_info *sta_info;
1139  	QDF_STATUS status;
1140  
1141  	sta_info = dp_get_peer_priv_obj(peer);
1142  	if (!sta_info) {
1143  		dp_err("DP_peer_obj is NULL");
1144  		return QDF_STATUS_E_FAULT;
1145  	}
1146  
1147  	status = wlan_objmgr_peer_component_obj_detach(peer, WLAN_COMP_DP,
1148  						       sta_info);
1149  	if (QDF_IS_STATUS_ERROR(status))
1150  		dp_err("DP peer ("QDF_MAC_ADDR_FMT") detach failed",
1151  			QDF_MAC_ADDR_REF(peer->macaddr));
1152  
1153  	qdf_mem_free(sta_info);
1154  
1155  	return status;
1156  }
1157  
1158  QDF_STATUS
dp_vdev_obj_create_notification(struct wlan_objmgr_vdev * vdev,void * arg)1159  dp_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, void *arg)
1160  {
1161  	struct wlan_objmgr_psoc *psoc;
1162  	struct wlan_dp_psoc_context *dp_ctx;
1163  	struct wlan_dp_intf *dp_intf;
1164  	struct wlan_dp_link *dp_link;
1165  	QDF_STATUS status = QDF_STATUS_SUCCESS;
1166  	struct qdf_mac_addr *mac_addr;
1167  	qdf_netdev_t dev;
1168  
1169  	dp_info("DP VDEV OBJ create notification, vdev_id %d",
1170  		wlan_vdev_get_id(vdev));
1171  
1172  	psoc = wlan_vdev_get_psoc(vdev);
1173  	if (!psoc) {
1174  		dp_err("Failed to get psoc");
1175  		return QDF_STATUS_E_INVAL;
1176  	}
1177  
1178  	dp_ctx =  dp_psoc_get_priv(psoc);
1179  	mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev);
1180  
1181  	dev = dp_ctx->dp_ops.dp_get_netdev_by_vdev_mac(mac_addr);
1182  	if (!dev) {
1183  		dp_err("Failed to get intf mac:" QDF_MAC_ADDR_FMT,
1184  		       QDF_MAC_ADDR_REF(mac_addr->bytes));
1185  		return QDF_STATUS_E_INVAL;
1186  	}
1187  
1188  	dp_intf = dp_get_intf_by_netdev(dp_ctx, dev);
1189  	if (!dp_intf) {
1190  		dp_err("Failed to get dp intf dev: %s",
1191  		       qdf_netdev_get_devname(dev));
1192  
1193  		return QDF_STATUS_E_INVAL;
1194  	}
1195  
1196  	dp_link = qdf_mem_malloc(sizeof(*dp_link));
1197  	if (!dp_link) {
1198  		dp_err("DP link(" QDF_MAC_ADDR_FMT ") memory alloc failed",
1199  		       QDF_MAC_ADDR_REF(mac_addr->bytes));
1200  		return QDF_STATUS_E_NOMEM;
1201  	}
1202  
1203  	/* Update Parent interface details */
1204  	dp_link->magic = WLAN_DP_LINK_MAGIC;
1205  	dp_link->destroyed = 0;
1206  	dp_link->cdp_vdev_deleted = 0;
1207  	dp_link->dp_intf = dp_intf;
1208  	qdf_spin_lock_bh(&dp_intf->dp_link_list_lock);
1209  	qdf_list_insert_front(&dp_intf->dp_link_list, &dp_link->node);
1210  	dp_intf->num_links++;
1211  	qdf_spin_unlock_bh(&dp_intf->dp_link_list_lock);
1212  
1213  	qdf_copy_macaddr(&dp_link->mac_addr, mac_addr);
1214  	qdf_spinlock_create(&dp_link->vdev_lock);
1215  
1216  	qdf_spin_lock_bh(&dp_link->vdev_lock);
1217  	dp_link->link_id = vdev->vdev_objmgr.vdev_id;
1218  	dp_link->vdev = vdev;
1219  	qdf_spin_unlock_bh(&dp_link->vdev_lock);
1220  
1221  	status = wlan_objmgr_vdev_component_obj_attach(vdev,
1222  						       WLAN_COMP_DP,
1223  						       (void *)dp_link,
1224  						       QDF_STATUS_SUCCESS);
1225  	if (QDF_IS_STATUS_ERROR(status)) {
1226  		dp_err("Failed to attach dp_link with vdev");
1227  		return status;
1228  	}
1229  
1230  	if (dp_intf->num_links == 1) {
1231  		/*
1232  		 * Interface level operations to be done only
1233  		 * when the first link is created
1234  		 */
1235  		dp_intf->def_link = dp_link;
1236  		dp_intf->device_mode = wlan_vdev_mlme_get_opmode(vdev);
1237  		qdf_atomic_init(&dp_intf->num_active_task);
1238  		dp_nud_ignore_tracking(dp_intf, false);
1239  		dp_mic_enable_work(dp_intf);
1240  
1241  		if (dp_intf->device_mode == QDF_SAP_MODE ||
1242  		    dp_intf->device_mode == QDF_P2P_GO_MODE) {
1243  			dp_intf->sap_tx_block_mask = DP_TX_FN_CLR |
1244  						     DP_TX_SAP_STOP;
1245  
1246  			status = qdf_event_create(&dp_intf->qdf_sta_eap_frm_done_event);
1247  			if (!QDF_IS_STATUS_SUCCESS(status)) {
1248  				dp_err("eap frm done event init failed!!");
1249  				return status;
1250  			}
1251  			qdf_mem_zero(&dp_intf->stats,
1252  				     sizeof(qdf_net_dev_stats));
1253  		}
1254  	}
1255  
1256  	return status;
1257  }
1258  
dp_link_handle_cdp_vdev_delete(struct wlan_dp_psoc_context * dp_ctx,struct wlan_dp_link * dp_link)1259  static void dp_link_handle_cdp_vdev_delete(struct wlan_dp_psoc_context *dp_ctx,
1260  					   struct wlan_dp_link *dp_link)
1261  {
1262  	qdf_spin_lock_bh(&dp_ctx->dp_link_del_lock);
1263  
1264  	dp_info("CDP vdev registered %d, vdev deleted %d",
1265  		dp_link->cdp_vdev_registered,
1266  		dp_link->cdp_vdev_deleted);
1267  
1268  	if (!dp_link->cdp_vdev_registered || dp_link->cdp_vdev_deleted) {
1269  		/* CDP vdev is not created/registered or already deleted */
1270  		dp_info("Free dp_link %pK id %d (" QDF_MAC_ADDR_FMT ")",
1271  			dp_link, dp_link->link_id,
1272  			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
1273  		dp_link->magic = 0;
1274  		qdf_mem_free(dp_link);
1275  	} else {
1276  		/*
1277  		 * Add it to inactive dp_link list, and it will be freed when
1278  		 * the CDP vdev gets deleted
1279  		 */
1280  		dp_info("Add to inactive list dp_link %pK id %d ("
1281  			QDF_MAC_ADDR_FMT ")",
1282  			dp_link, dp_link->link_id,
1283  			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
1284  		TAILQ_INSERT_TAIL(&dp_ctx->inactive_dp_link_list, dp_link,
1285  				  inactive_list_elem);
1286  		dp_link->destroyed = 1;
1287  	}
1288  
1289  	qdf_spin_unlock_bh(&dp_ctx->dp_link_del_lock);
1290  }
1291  
1292  QDF_STATUS
dp_vdev_obj_destroy_notification(struct wlan_objmgr_vdev * vdev,void * arg)1293  dp_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg)
1294  
1295  {
1296  	struct wlan_dp_psoc_context *dp_ctx;
1297  	struct wlan_dp_intf *dp_intf;
1298  	struct wlan_dp_link *dp_link;
1299  	QDF_STATUS status = QDF_STATUS_SUCCESS;
1300  
1301  	dp_info("DP VDEV OBJ destroy notification, vdev_id %d",
1302  		wlan_vdev_get_id(vdev));
1303  
1304  	dp_link = dp_get_vdev_priv_obj(vdev);
1305  	if (!dp_link) {
1306  		dp_err("Failed to get DP link obj");
1307  		return QDF_STATUS_E_INVAL;
1308  	}
1309  
1310  	dp_intf = dp_link->dp_intf;
1311  	dp_ctx = dp_intf->dp_ctx;
1312  
1313  	qdf_spin_lock_bh(&dp_intf->dp_link_list_lock);
1314  	qdf_list_remove_node(&dp_intf->dp_link_list, &dp_link->node);
1315  	dp_intf->num_links--;
1316  	qdf_spin_unlock_bh(&dp_intf->dp_link_list_lock);
1317  
1318  	if (dp_intf->num_links == 0) {
1319  		/*
1320  		 * Interface level operations are stopped when last
1321  		 * link is deleted
1322  		 */
1323  		dp_nud_ignore_tracking(dp_intf, true);
1324  		dp_nud_reset_tracking(dp_intf);
1325  		dp_nud_flush_work(dp_intf);
1326  		dp_mic_flush_work(dp_intf);
1327  
1328  		if (dp_intf->device_mode == QDF_SAP_MODE ||
1329  		    dp_intf->device_mode == QDF_P2P_GO_MODE) {
1330  			status = qdf_event_destroy(&dp_intf->qdf_sta_eap_frm_done_event);
1331  			if (!QDF_IS_STATUS_SUCCESS(status)) {
1332  				dp_err("eap frm done event destroy failed!!");
1333  				return status;
1334  			}
1335  			dp_intf->txrx_ops.tx.tx = NULL;
1336  			dp_intf->sap_tx_block_mask |= DP_TX_FN_CLR;
1337  		}
1338  	}
1339  
1340  	qdf_mem_zero(&dp_link->conn_info, sizeof(struct wlan_dp_conn_info));
1341  
1342  	/*
1343  	 * If the dp_link which is being destroyed is the default link,
1344  	 * then find a new link to be made the default link
1345  	 */
1346  	if (dp_intf->def_link == dp_link)
1347  		dp_intf->def_link =
1348  			dp_intf_get_next_deflink_candidate(dp_intf, dp_link);
1349  
1350  	/*
1351  	 * Change this to link level, since during link switch,
1352  	 * it might not go to 0
1353  	 */
1354  	status = dp_intf_wait_for_task_complete(dp_intf);
1355  	if (QDF_IS_STATUS_ERROR(status))
1356  		return status;
1357  
1358  	qdf_spin_lock_bh(&dp_link->vdev_lock);
1359  	dp_link->vdev = NULL;
1360  	qdf_spin_unlock_bh(&dp_link->vdev_lock);
1361  
1362  	qdf_spinlock_destroy(&dp_link->vdev_lock);
1363  
1364  	status = wlan_objmgr_vdev_component_obj_detach(vdev,
1365  						       WLAN_COMP_DP,
1366  						       (void *)dp_link);
1367  	if (QDF_IS_STATUS_ERROR(status)) {
1368  		dp_err("Failed to detach dp_link with vdev");
1369  		return status;
1370  	}
1371  
1372  	dp_link_handle_cdp_vdev_delete(dp_ctx, dp_link);
1373  
1374  	return status;
1375  }
1376  
1377  QDF_STATUS
dp_pdev_obj_create_notification(struct wlan_objmgr_pdev * pdev,void * arg)1378  dp_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev, void *arg)
1379  {
1380  	struct wlan_objmgr_psoc *psoc;
1381  	struct wlan_dp_psoc_context *dp_ctx;
1382  	QDF_STATUS status;
1383  
1384  	dp_info("DP PDEV OBJ create notification");
1385  	psoc = wlan_pdev_get_psoc(pdev);
1386  	if (!psoc) {
1387  		obj_mgr_err("psoc is NULL in pdev");
1388  		return QDF_STATUS_E_FAILURE;
1389  	}
1390  	dp_ctx =  dp_psoc_get_priv(psoc);
1391  	if (!dp_ctx) {
1392  		dp_err("Failed to get dp_ctx from psoc");
1393  		return QDF_STATUS_E_FAILURE;
1394  	}
1395  	status = wlan_objmgr_pdev_component_obj_attach(pdev,
1396  						       WLAN_COMP_DP,
1397  						       (void *)dp_ctx,
1398  						       QDF_STATUS_SUCCESS);
1399  	if (QDF_IS_STATUS_ERROR(status)) {
1400  		dp_err("Failed to attach dp_ctx to pdev");
1401  		return status;
1402  	}
1403  
1404  	dp_ctx->pdev = pdev;
1405  	return status;
1406  }
1407  
1408  QDF_STATUS
dp_pdev_obj_destroy_notification(struct wlan_objmgr_pdev * pdev,void * arg)1409  dp_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, void *arg)
1410  {
1411  	struct wlan_objmgr_psoc *psoc;
1412  	struct wlan_dp_psoc_context *dp_ctx;
1413  	QDF_STATUS status;
1414  
1415  	dp_info("DP PDEV OBJ destroy notification");
1416  	psoc = wlan_pdev_get_psoc(pdev);
1417  	if (!psoc) {
1418  		obj_mgr_err("psoc is NULL in pdev");
1419  		return QDF_STATUS_E_FAILURE;
1420  	}
1421  
1422  	dp_ctx = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_COMP_DP);
1423  	if (!dp_ctx) {
1424  		dp_err("Failed to get dp_ctx from pdev");
1425  		return QDF_STATUS_E_FAILURE;
1426  	}
1427  	status = wlan_objmgr_pdev_component_obj_detach(pdev,
1428  						       WLAN_COMP_DP,
1429  						       dp_ctx);
1430  	if (QDF_IS_STATUS_ERROR(status)) {
1431  		dp_err("Failed to detach dp_ctx from pdev");
1432  		return status;
1433  	}
1434  	if (!dp_ctx->pdev)
1435  		dp_err("DP Pdev is NULL");
1436  
1437  	dp_ctx->pdev = NULL;
1438  	return status;
1439  }
1440  
1441  QDF_STATUS
dp_psoc_obj_create_notification(struct wlan_objmgr_psoc * psoc,void * arg)1442  dp_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg)
1443  {
1444  	struct wlan_dp_psoc_context *dp_ctx = gp_dp_ctx;
1445  	QDF_STATUS status;
1446  
1447  	status = wlan_objmgr_psoc_component_obj_attach(
1448  				psoc, WLAN_COMP_DP,
1449  				dp_ctx, QDF_STATUS_SUCCESS);
1450  	if (QDF_IS_STATUS_ERROR(status)) {
1451  		dp_err("Failed to attach psoc component obj");
1452  		return status;
1453  	}
1454  
1455  	dp_ctx->psoc = psoc;
1456  	dp_cfg_init(dp_ctx);
1457  	target_if_dp_register_tx_ops(&dp_ctx->sb_ops);
1458  	target_if_dp_register_rx_ops(&dp_ctx->nb_ops);
1459  
1460  	return status;
1461  }
1462  
1463  QDF_STATUS
dp_psoc_obj_destroy_notification(struct wlan_objmgr_psoc * psoc,void * arg)1464  dp_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg)
1465  {
1466  	struct wlan_dp_psoc_context *dp_ctx;
1467  	QDF_STATUS status;
1468  
1469  	dp_ctx = dp_psoc_get_priv(psoc);
1470  	if (!dp_ctx) {
1471  		dp_err("psoc priv is NULL");
1472  		return QDF_STATUS_E_FAILURE;
1473  	}
1474  
1475  	status = wlan_objmgr_psoc_component_obj_detach(
1476  					psoc, WLAN_COMP_DP,
1477  					dp_ctx);
1478  	if (QDF_IS_STATUS_ERROR(status)) {
1479  		dp_err("Failed to detach psoc component obj");
1480  		return status;
1481  	}
1482  
1483  	dp_reset_all_intfs_connectivity_stats(dp_ctx);
1484  
1485  	return status;
1486  }
1487  
dp_attach_ctx(struct wlan_dp_psoc_context * dp_ctx)1488  void dp_attach_ctx(struct wlan_dp_psoc_context *dp_ctx)
1489  {
1490  	if (gp_dp_ctx)
1491  		dp_debug("already attached global dp ctx");
1492  	gp_dp_ctx = dp_ctx;
1493  }
1494  
dp_detach_ctx(void)1495  void dp_detach_ctx(void)
1496  {
1497  	if (!gp_dp_ctx) {
1498  		dp_err("global dp ctx is already detached");
1499  		return;
1500  	}
1501  	gp_dp_ctx = NULL;
1502  }
1503  
dp_get_context(void)1504  struct wlan_dp_psoc_context *dp_get_context(void)
1505  {
1506  	return gp_dp_ctx;
1507  }
1508  
1509  /**
1510   * dp_hex_string_to_u16_array() - convert a hex string to a uint16 array
1511   * @str: input string
1512   * @int_array: pointer to input array of type uint16
1513   * @len: pointer to number of elements which the function adds to the array
1514   * @int_array_max_len: maximum number of elements in input uint16 array
1515   *
1516   * This function is used to convert a space separated hex string to an array of
1517   * uint16_t. For example, an input string str = "a b c d" would be converted to
1518   * a unint16 array, int_array = {0xa, 0xb, 0xc, 0xd}, *len = 4.
1519   * This assumes that input value int_array_max_len >= 4.
1520   *
1521   * Return: QDF_STATUS_SUCCESS - if the conversion is successful
1522   *         non zero value     - if the conversion is a failure
1523   */
1524  static QDF_STATUS
dp_hex_string_to_u16_array(char * str,uint16_t * int_array,uint8_t * len,uint8_t int_array_max_len)1525  dp_hex_string_to_u16_array(char *str, uint16_t *int_array, uint8_t *len,
1526  			   uint8_t int_array_max_len)
1527  {
1528  	char *s = str;
1529  	uint32_t val = 0;
1530  
1531  	if (!str || !int_array || !len)
1532  		return QDF_STATUS_E_INVAL;
1533  
1534  	dp_debug("str %pK intArray %pK intArrayMaxLen %d",
1535  		 s, int_array, int_array_max_len);
1536  
1537  	*len = 0;
1538  
1539  	while ((s) && (*len < int_array_max_len)) {
1540  		/*
1541  		 * Increment length only if sscanf successfully extracted one
1542  		 * element. Any other return value means error. Ignore it.
1543  		 */
1544  		if (sscanf(s, "%x", &val) == 1) {
1545  			int_array[*len] = (uint16_t)val;
1546  			dp_debug("s %pK val %x intArray[%d]=0x%x",
1547  				 s, val, *len, int_array[*len]);
1548  			*len += 1;
1549  		}
1550  		s = strpbrk(s, " ");
1551  		if (s)
1552  			s++;
1553  	}
1554  	return QDF_STATUS_SUCCESS;
1555  }
1556  
1557  /**
1558   * dp_get_interface() - to get dp interface matching the mode
1559   * @dp_ctx: dp context
1560   * @mode: interface mode
1561   *
1562   * This routine will return the pointer to dp interface matching
1563   * with the passed mode.
1564   *
1565   * Return: pointer to interface or null
1566   */
1567  static struct
dp_get_interface(struct wlan_dp_psoc_context * dp_ctx,enum QDF_OPMODE mode)1568  wlan_dp_intf *dp_get_interface(struct wlan_dp_psoc_context *dp_ctx,
1569  			       enum QDF_OPMODE mode)
1570  {
1571  	struct wlan_dp_intf *dp_intf;
1572  	struct wlan_dp_intf *dp_intf_next;
1573  
1574  	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
1575  		if (!dp_intf)
1576  			continue;
1577  
1578  		if (dp_intf->device_mode == mode)
1579  			return dp_intf;
1580  	}
1581  
1582  	return NULL;
1583  }
1584  
dp_send_rps_ind(struct wlan_dp_intf * dp_intf)1585  void dp_send_rps_ind(struct wlan_dp_intf *dp_intf)
1586  {
1587  	int i;
1588  	uint8_t cpu_map_list_len = 0;
1589  	struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx;
1590  	struct wlan_rps_data rps_data;
1591  	struct cds_config_info *cds_cfg;
1592  
1593  	cds_cfg = cds_get_ini_config();
1594  	if (!cds_cfg) {
1595  		dp_err("cds_cfg is NULL");
1596  		return;
1597  	}
1598  
1599  	rps_data.num_queues = NUM_RX_QUEUES;
1600  
1601  	dp_info("cpu_map_list '%s'", dp_ctx->dp_cfg.cpu_map_list);
1602  
1603  	/* in case no cpu map list is provided, simply return */
1604  	if (!strlen(dp_ctx->dp_cfg.cpu_map_list)) {
1605  		dp_info("no cpu map list found");
1606  		goto err;
1607  	}
1608  
1609  	if (QDF_STATUS_SUCCESS !=
1610  		dp_hex_string_to_u16_array(dp_ctx->dp_cfg.cpu_map_list,
1611  					   rps_data.cpu_map_list,
1612  					   &cpu_map_list_len,
1613  					   WLAN_SVC_IFACE_NUM_QUEUES)) {
1614  		dp_err("invalid cpu map list");
1615  		goto err;
1616  	}
1617  
1618  	rps_data.num_queues =
1619  		(cpu_map_list_len < rps_data.num_queues) ?
1620  				cpu_map_list_len : rps_data.num_queues;
1621  
1622  	for (i = 0; i < rps_data.num_queues; i++) {
1623  		dp_info("cpu_map_list[%d] = 0x%x",
1624  			i, rps_data.cpu_map_list[i]);
1625  	}
1626  
1627  	strlcpy(rps_data.ifname, qdf_netdev_get_devname(dp_intf->dev),
1628  		sizeof(rps_data.ifname));
1629  	dp_ctx->dp_ops.dp_send_svc_nlink_msg(cds_get_radio_index(),
1630  					     WLAN_SVC_RPS_ENABLE_IND,
1631  					     &rps_data, sizeof(rps_data));
1632  
1633  	cds_cfg->rps_enabled = true;
1634  
1635  	return;
1636  
1637  err:
1638  	dp_info("Wrong RPS configuration. enabling rx_thread");
1639  	cds_cfg->rps_enabled = false;
1640  }
1641  
dp_try_send_rps_ind(struct wlan_objmgr_vdev * vdev)1642  void dp_try_send_rps_ind(struct wlan_objmgr_vdev *vdev)
1643  {
1644  	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
1645  	struct wlan_dp_intf *dp_intf;
1646  
1647  	if (!dp_link) {
1648  		dp_err("dp link is NULL");
1649  		return;
1650  	}
1651  
1652  	dp_intf = dp_link->dp_intf;
1653  	if (dp_intf->dp_ctx->rps)
1654  		dp_send_rps_ind(dp_intf);
1655  }
1656  
dp_send_rps_disable_ind(struct wlan_dp_intf * dp_intf)1657  void dp_send_rps_disable_ind(struct wlan_dp_intf *dp_intf)
1658  {
1659  	struct wlan_rps_data rps_data;
1660  	struct cds_config_info *cds_cfg;
1661  
1662  	cds_cfg = cds_get_ini_config();
1663  
1664  	if (!cds_cfg) {
1665  		dp_err("cds_cfg is NULL");
1666  		return;
1667  	}
1668  
1669  	rps_data.num_queues = NUM_RX_QUEUES;
1670  
1671  	dp_info("Set cpu_map_list 0");
1672  
1673  	qdf_mem_zero(&rps_data.cpu_map_list, sizeof(rps_data.cpu_map_list));
1674  
1675  	strlcpy(rps_data.ifname, qdf_netdev_get_devname(dp_intf->dev),
1676  		sizeof(rps_data.ifname));
1677  	dp_intf->dp_ctx->dp_ops.dp_send_svc_nlink_msg(cds_get_radio_index(),
1678  				    WLAN_SVC_RPS_ENABLE_IND,
1679  				    &rps_data, sizeof(rps_data));
1680  
1681  	cds_cfg->rps_enabled = false;
1682  }
1683  
1684  #ifdef QCA_CONFIG_RPS
dp_set_rps(uint8_t vdev_id,bool enable)1685  void dp_set_rps(uint8_t vdev_id, bool enable)
1686  {
1687  	struct wlan_objmgr_vdev *vdev;
1688  	struct wlan_dp_psoc_context *dp_ctx;
1689  	struct wlan_dp_intf *dp_intf;
1690  	struct wlan_dp_link *dp_link;
1691  
1692  	dp_ctx = dp_get_context();
1693  	if (!dp_ctx)
1694  		return;
1695  
1696  	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(dp_ctx->psoc,
1697  						    vdev_id, WLAN_DP_ID);
1698  	if (!vdev)
1699  		return;
1700  
1701  	dp_link = dp_get_vdev_priv_obj(vdev);
1702  	if (!dp_link) {
1703  		dp_comp_vdev_put_ref(vdev);
1704  		dp_err_rl("DP link not found for vdev_id: %d", vdev_id);
1705  		return;
1706  	}
1707  
1708  	dp_intf = dp_link->dp_intf;
1709  
1710  	dp_info("Set RPS to %d for vdev_id %d", enable, vdev_id);
1711  	if (!dp_ctx->rps) {
1712  		if (enable)
1713  			dp_send_rps_ind(dp_intf);
1714  		else
1715  			dp_send_rps_disable_ind(dp_intf);
1716  	}
1717  	dp_comp_vdev_put_ref(vdev);
1718  }
1719  #endif
1720  
dp_set_rx_mode_rps(bool enable)1721  void dp_set_rx_mode_rps(bool enable)
1722  {
1723  	struct wlan_dp_psoc_context *dp_ctx;
1724  	struct wlan_dp_intf *dp_intf;
1725  	struct cds_config_info *cds_cfg;
1726  
1727  	dp_ctx = dp_get_context();
1728  	cds_cfg = cds_get_ini_config();
1729  	if (!dp_ctx || !cds_cfg)
1730  		return;
1731  
1732  	dp_intf = dp_get_interface(dp_ctx, QDF_SAP_MODE);
1733  	if (!dp_intf)
1734  		return;
1735  
1736  	if (!dp_intf->dp_ctx->rps && cds_cfg->uc_offload_enabled) {
1737  		if (enable && !cds_cfg->rps_enabled)
1738  			dp_send_rps_ind(dp_intf);
1739  		else if (!enable && cds_cfg->rps_enabled)
1740  			dp_send_rps_disable_ind(dp_intf);
1741  	}
1742  }
1743  
dp_set_rps_cpu_mask(struct wlan_dp_psoc_context * dp_ctx)1744  void dp_set_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx)
1745  {
1746  	struct wlan_dp_intf *dp_intf;
1747  	struct wlan_dp_intf *dp_intf_next;
1748  
1749  	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
1750  		if (!dp_intf)
1751  			continue;
1752  
1753  		dp_send_rps_ind(dp_intf);
1754  	}
1755  }
1756  
dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc * psoc)1757  void dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc *psoc)
1758  {
1759  	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
1760  
1761  	if (!dp_ctx) {
1762  		dp_err("dp context is NULL");
1763  		return;
1764  	}
1765  
1766  	if (dp_ctx->dynamic_rps)
1767  		dp_set_rps_cpu_mask(dp_ctx);
1768  }
1769  
dp_clear_rps_cpu_mask(struct wlan_dp_psoc_context * dp_ctx)1770  void dp_clear_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx)
1771  {
1772  	struct wlan_dp_intf *dp_intf;
1773  	struct wlan_dp_intf *dp_intf_next;
1774  
1775  	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
1776  		if (!dp_intf)
1777  			continue;
1778  
1779  		dp_send_rps_disable_ind(dp_intf);
1780  	}
1781  }
1782  
dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc * psoc,struct dp_rsp_stats * rsp)1783  QDF_STATUS dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc,
1784  					  struct dp_rsp_stats *rsp)
1785  {
1786  	struct wlan_dp_intf *dp_intf;
1787  	struct wlan_dp_link *dp_link;
1788  	struct wlan_objmgr_vdev *vdev;
1789  
1790  	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
1791  						    rsp->vdev_id,
1792  						    WLAN_DP_ID);
1793  	if (!vdev) {
1794  		dp_err("Can't get vdev by vdev_id:%d", rsp->vdev_id);
1795  		return QDF_STATUS_E_INVAL;
1796  	}
1797  
1798  	dp_link = dp_get_vdev_priv_obj(vdev);
1799  	if (!dp_link) {
1800  		dp_err("Unable to get DP link for vdev_id %d", rsp->vdev_id);
1801  		wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID);
1802  		return QDF_STATUS_E_INVAL;
1803  	}
1804  
1805  	dp_intf = dp_link->dp_intf;
1806  
1807  	dp_info("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
1808  	dp_info("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
1809  	dp_info("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
1810  	dp_info("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
1811  	dp_info("rsp->out_of_order_arp_rsp_drop_cnt :%x",
1812  		rsp->out_of_order_arp_rsp_drop_cnt);
1813  	dp_info("rsp->dad_detected :%x", rsp->dad_detected);
1814  	dp_info("rsp->connect_status :%x", rsp->connect_status);
1815  	dp_info("rsp->ba_session_establishment_status :%x",
1816  		rsp->ba_session_establishment_status);
1817  
1818  	dp_intf->dp_stats.arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
1819  	dp_intf->dad |= rsp->dad_detected;
1820  	dp_intf->con_status = rsp->connect_status;
1821  
1822  	/* Flag true indicates connectivity check stats present. */
1823  	if (rsp->connect_stats_present) {
1824  		dp_info("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
1825  		dp_info("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
1826  		dp_intf->dp_stats.tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
1827  		dp_intf->dp_stats.icmpv4_stats.rx_fw_cnt =
1828  							rsp->icmpv4_rsp_recvd;
1829  	}
1830  
1831  	wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID);
1832  	return QDF_STATUS_SUCCESS;
1833  }
1834  
1835  #ifdef WLAN_OBJMGR_REF_ID_TRACE
1836  struct wlan_objmgr_vdev *
__dp_objmgr_get_vdev_by_user(struct wlan_dp_link * dp_link,wlan_objmgr_ref_dbgid id,const char * func,int line)1837  __dp_objmgr_get_vdev_by_user(struct wlan_dp_link *dp_link,
1838  			     wlan_objmgr_ref_dbgid id,
1839  			     const char *func, int line)
1840  {
1841  	struct wlan_objmgr_vdev *vdev;
1842  	QDF_STATUS status;
1843  
1844  	if (!dp_link)
1845  		return NULL;
1846  
1847  	qdf_spin_lock_bh(&dp_link->vdev_lock);
1848  	vdev = dp_link->vdev;
1849  	if (vdev) {
1850  		status = wlan_objmgr_vdev_try_get_ref_debug(vdev, id, func,
1851  							    line);
1852  		if (QDF_IS_STATUS_ERROR(status))
1853  			vdev = NULL;
1854  	}
1855  	qdf_spin_unlock_bh(&dp_link->vdev_lock);
1856  
1857  	if (!vdev)
1858  		dp_debug("VDEV is NULL (via %s, id %d)", func, id);
1859  
1860  	return vdev;
1861  }
1862  
1863  void
__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func,int line)1864  __dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
1865  			     wlan_objmgr_ref_dbgid id, const char *func,
1866  			     int line)
1867  {
1868  	if (!vdev) {
1869  		dp_err("VDEV is NULL (via %s, id %d)", func, id);
1870  		return;
1871  	}
1872  
1873  	wlan_objmgr_vdev_release_ref_debug(vdev, id, func, line);
1874  }
1875  #else
1876  struct wlan_objmgr_vdev *
__dp_objmgr_get_vdev_by_user(struct wlan_dp_link * dp_link,wlan_objmgr_ref_dbgid id,const char * func)1877  __dp_objmgr_get_vdev_by_user(struct wlan_dp_link *dp_link,
1878  			     wlan_objmgr_ref_dbgid id,
1879  			     const char *func)
1880  {
1881  	struct wlan_objmgr_vdev *vdev;
1882  	QDF_STATUS status;
1883  
1884  	if (!dp_link)
1885  		return NULL;
1886  
1887  	qdf_spin_lock_bh(&dp_link->vdev_lock);
1888  	vdev = dp_link->vdev;
1889  	if (vdev) {
1890  		status = wlan_objmgr_vdev_try_get_ref(vdev, id);
1891  		if (QDF_IS_STATUS_ERROR(status))
1892  			vdev = NULL;
1893  	}
1894  	qdf_spin_unlock_bh(&dp_link->vdev_lock);
1895  
1896  	if (!vdev)
1897  		dp_debug("VDEV is NULL (via %s, id %d)", func, id);
1898  
1899  	return vdev;
1900  }
1901  
1902  void
__dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev * vdev,wlan_objmgr_ref_dbgid id,const char * func)1903  __dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev,
1904  			     wlan_objmgr_ref_dbgid id, const char *func)
1905  {
1906  	if (!vdev) {
1907  		dp_err("VDEV is NULL (via %s, id %d)", func, id);
1908  		return;
1909  	}
1910  
1911  	wlan_objmgr_vdev_release_ref(vdev, id);
1912  }
1913  #endif /* WLAN_OBJMGR_REF_ID_TRACE */
1914  
dp_is_data_stall_event_enabled(uint32_t evt)1915  bool dp_is_data_stall_event_enabled(uint32_t evt)
1916  {
1917  	uint32_t bitmap = cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
1918  				      cfg_dp_enable_data_stall);
1919  
1920  	if (bitmap & DP_DATA_STALL_ENABLE || bitmap & evt)
1921  		return true;
1922  
1923  	return false;
1924  }
1925  
1926  #ifdef WLAN_SUPPORT_RX_FISA
1927  static inline QDF_STATUS
wlan_dp_rx_fisa_attach_target(struct wlan_dp_psoc_context * dp_ctx)1928  wlan_dp_rx_fisa_attach_target(struct wlan_dp_psoc_context *dp_ctx)
1929  {
1930  	QDF_STATUS status;
1931  
1932  	status = dp_rx_fst_target_config(dp_ctx);
1933  	if (status != QDF_STATUS_SUCCESS &&
1934  	    status != QDF_STATUS_E_NOSUPPORT) {
1935  		dp_err("Failed to send htt fst setup config message to target");
1936  		return status;
1937  	}
1938  
1939  	/* return success to let init process go */
1940  	if (status == QDF_STATUS_E_NOSUPPORT)
1941  		return QDF_STATUS_SUCCESS;
1942  
1943  	if (status == QDF_STATUS_SUCCESS) {
1944  		status = dp_rx_fisa_config(dp_ctx);
1945  		if (QDF_IS_STATUS_ERROR(status)) {
1946  			dp_err("Failed to send htt FISA config message to target");
1947  			return status;
1948  		}
1949  	}
1950  
1951  	return status;
1952  }
1953  
1954  static inline QDF_STATUS
wlan_dp_rx_fisa_attach(struct wlan_dp_psoc_context * dp_ctx)1955  wlan_dp_rx_fisa_attach(struct wlan_dp_psoc_context *dp_ctx)
1956  {
1957  	return dp_rx_fst_attach(dp_ctx);
1958  }
1959  
wlan_dp_rx_fisa_detach(struct wlan_dp_psoc_context * dp_ctx)1960  static inline void wlan_dp_rx_fisa_detach(struct wlan_dp_psoc_context *dp_ctx)
1961  {
1962  	return dp_rx_fst_detach(dp_ctx);
1963  }
1964  
1965  static inline void
wlan_dp_rx_fisa_cmem_attach(struct wlan_dp_psoc_context * dp_ctx)1966  wlan_dp_rx_fisa_cmem_attach(struct wlan_dp_psoc_context *dp_ctx)
1967  {
1968  	dp_ctx->fst_cmem_base = cdp_get_fst_cem_base(dp_ctx->cdp_soc,
1969  						     DP_CMEM_FST_SIZE);
1970  }
1971  
1972  static inline QDF_STATUS
wlan_dp_fisa_suspend(struct wlan_dp_psoc_context * dp_ctx)1973  wlan_dp_fisa_suspend(struct wlan_dp_psoc_context *dp_ctx)
1974  {
1975  	dp_suspend_fse_cache_flush(dp_ctx);
1976  	dp_rx_fst_update_pm_suspend_status(dp_ctx, true);
1977  
1978  	return QDF_STATUS_SUCCESS;
1979  }
1980  
1981  static inline QDF_STATUS
wlan_dp_fisa_resume(struct wlan_dp_psoc_context * dp_ctx)1982  wlan_dp_fisa_resume(struct wlan_dp_psoc_context *dp_ctx)
1983  {
1984  	dp_resume_fse_cache_flush(dp_ctx);
1985  	dp_rx_fst_update_pm_suspend_status(dp_ctx, false);
1986  	dp_rx_fst_requeue_wq(dp_ctx);
1987  
1988  	return QDF_STATUS_SUCCESS;
1989  }
1990  #else
1991  static inline QDF_STATUS
wlan_dp_rx_fisa_attach_target(struct wlan_dp_psoc_context * dp_ctx)1992  wlan_dp_rx_fisa_attach_target(struct wlan_dp_psoc_context *dp_ctx)
1993  {
1994  	return QDF_STATUS_SUCCESS;
1995  }
1996  
1997  static inline QDF_STATUS
wlan_dp_rx_fisa_attach(struct wlan_dp_psoc_context * dp_ctx)1998  wlan_dp_rx_fisa_attach(struct wlan_dp_psoc_context *dp_ctx)
1999  {
2000  	return QDF_STATUS_SUCCESS;
2001  }
2002  
2003  static inline QDF_STATUS
wlan_dp_rx_fisa_detach(struct wlan_dp_psoc_context * dp_ctx)2004  wlan_dp_rx_fisa_detach(struct wlan_dp_psoc_context *dp_ctx)
2005  {
2006  	return QDF_STATUS_SUCCESS;
2007  }
2008  
2009  static inline void
wlan_dp_rx_fisa_cmem_attach(struct wlan_dp_psoc_context * dp_ctx)2010  wlan_dp_rx_fisa_cmem_attach(struct wlan_dp_psoc_context *dp_ctx)
2011  {
2012  }
2013  
2014  static inline QDF_STATUS
wlan_dp_fisa_suspend(struct wlan_dp_psoc_context * dp_ctx)2015  wlan_dp_fisa_suspend(struct wlan_dp_psoc_context *dp_ctx)
2016  {
2017  	return QDF_STATUS_SUCCESS;
2018  }
2019  
2020  static inline QDF_STATUS
wlan_dp_fisa_resume(struct wlan_dp_psoc_context * dp_ctx)2021  wlan_dp_fisa_resume(struct wlan_dp_psoc_context *dp_ctx)
2022  {
2023  	return QDF_STATUS_SUCCESS;
2024  }
2025  #endif
2026  
wlan_dp_link_cdp_vdev_delete_notification(void * context)2027  void wlan_dp_link_cdp_vdev_delete_notification(void *context)
2028  {
2029  	struct wlan_dp_link *dp_link = (struct wlan_dp_link *)context;
2030  	struct wlan_dp_link *tmp_dp_link;
2031  	struct wlan_dp_intf *dp_intf = NULL;
2032  	struct wlan_dp_psoc_context *dp_ctx = NULL;
2033  	uint8_t found = 0;
2034  
2035  	/* dp_link will not be freed before this point. */
2036  	if (!dp_link) {
2037  		dp_info("dp_link is null");
2038  		return;
2039  	}
2040  
2041  	dp_info("dp_link %pK id %d", dp_link, dp_link->link_id);
2042  	dp_intf = dp_link->dp_intf;
2043  	dp_ctx = dp_intf->dp_ctx;
2044  
2045  	qdf_spin_lock_bh(&dp_ctx->dp_link_del_lock);
2046  
2047  	if (dp_link->destroyed) {
2048  		/*
2049  		 * dp_link has been destroyed as a part of vdev_obj_destroy
2050  		 * notification and will be present in inactive list
2051  		 */
2052  		TAILQ_FOREACH(tmp_dp_link, &dp_ctx->inactive_dp_link_list,
2053  			      inactive_list_elem) {
2054  			if (tmp_dp_link == dp_link) {
2055  				found = 1;
2056  				break;
2057  			}
2058  		}
2059  
2060  		if (found)
2061  			TAILQ_REMOVE(&dp_ctx->inactive_dp_link_list, dp_link,
2062  				     inactive_list_elem);
2063  		else
2064  			qdf_assert_always(0);
2065  
2066  		dp_info("Free dp_link %pK id %d (" QDF_MAC_ADDR_FMT ")",
2067  			dp_link, dp_link->link_id,
2068  			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
2069  		dp_link->magic = 0;
2070  		qdf_mem_free(dp_link);
2071  	} else {
2072  		/* dp_link not yet destroyed */
2073  		dp_info("CDP vdev delete for dp_link %pK id %d ("
2074  			QDF_MAC_ADDR_FMT ")",
2075  			dp_link, dp_link->link_id,
2076  			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
2077  		dp_link->cdp_vdev_deleted = 1;
2078  	}
2079  
2080  	qdf_spin_unlock_bh(&dp_ctx->dp_link_del_lock);
2081  }
2082  
__wlan_dp_runtime_suspend(ol_txrx_soc_handle soc,uint8_t pdev_id)2083  QDF_STATUS __wlan_dp_runtime_suspend(ol_txrx_soc_handle soc, uint8_t pdev_id)
2084  {
2085  	struct wlan_dp_psoc_context *dp_ctx;
2086  	QDF_STATUS status;
2087  
2088  	dp_ctx = dp_get_context();
2089  	status = cdp_runtime_suspend(soc, pdev_id);
2090  	if (QDF_IS_STATUS_ERROR(status))
2091  		return status;
2092  
2093  	status = wlan_dp_fisa_suspend(dp_ctx);
2094  
2095  	return status;
2096  }
2097  
__wlan_dp_runtime_resume(ol_txrx_soc_handle soc,uint8_t pdev_id)2098  QDF_STATUS __wlan_dp_runtime_resume(ol_txrx_soc_handle soc, uint8_t pdev_id)
2099  {
2100  	struct wlan_dp_psoc_context *dp_ctx;
2101  	QDF_STATUS status;
2102  
2103  	dp_ctx = dp_get_context();
2104  	status = cdp_runtime_resume(soc, pdev_id);
2105  	if (QDF_IS_STATUS_ERROR(status))
2106  		return status;
2107  
2108  	status = wlan_dp_fisa_resume(dp_ctx);
2109  
2110  	return status;
2111  }
2112  
__wlan_dp_bus_suspend(ol_txrx_soc_handle soc,uint8_t pdev_id)2113  QDF_STATUS __wlan_dp_bus_suspend(ol_txrx_soc_handle soc, uint8_t pdev_id)
2114  {
2115  	struct wlan_dp_psoc_context *dp_ctx;
2116  	QDF_STATUS status;
2117  
2118  	dp_ctx = dp_get_context();
2119  
2120  	status = cdp_bus_suspend(soc, pdev_id);
2121  	if (QDF_IS_STATUS_ERROR(status))
2122  		return status;
2123  
2124  	status = wlan_dp_fisa_suspend(dp_ctx);
2125  	if (QDF_IS_STATUS_ERROR(status))
2126  		return status;
2127  
2128  	return status;
2129  }
2130  
__wlan_dp_bus_resume(ol_txrx_soc_handle soc,uint8_t pdev_id)2131  QDF_STATUS __wlan_dp_bus_resume(ol_txrx_soc_handle soc, uint8_t pdev_id)
2132  {
2133  	struct wlan_dp_psoc_context *dp_ctx;
2134  	QDF_STATUS status;
2135  
2136  	dp_ctx = dp_get_context();
2137  
2138  	status = cdp_bus_resume(soc, pdev_id);
2139  	if (QDF_IS_STATUS_ERROR(status))
2140  		return status;
2141  
2142  	status = wlan_dp_fisa_resume(dp_ctx);
2143  	if (QDF_IS_STATUS_ERROR(status))
2144  		return status;
2145  
2146  	return status;
2147  }
2148  
wlan_dp_txrx_soc_attach(struct dp_txrx_soc_attach_params * params,bool * is_wifi3_0_target)2149  void *wlan_dp_txrx_soc_attach(struct dp_txrx_soc_attach_params *params,
2150  			      bool *is_wifi3_0_target)
2151  {
2152  	struct wlan_dp_psoc_context *dp_ctx;
2153  	void *dp_soc = NULL;
2154  	struct hif_opaque_softc *hif_context;
2155  	HTC_HANDLE htc_ctx = cds_get_context(QDF_MODULE_ID_HTC);
2156  	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2157  
2158  	dp_ctx = dp_get_context();
2159  	hif_context = cds_get_context(QDF_MODULE_ID_HIF);
2160  
2161  	if (TARGET_TYPE_QCA6290 == params->target_type ||
2162  	    TARGET_TYPE_QCA6390 == params->target_type ||
2163  	    TARGET_TYPE_QCA6490 == params->target_type ||
2164  	    TARGET_TYPE_QCA6750 == params->target_type) {
2165  		dp_soc = cdp_soc_attach(LITHIUM_DP, hif_context,
2166  					params->target_psoc, htc_ctx,
2167  					qdf_ctx, params->dp_ol_if_ops);
2168  
2169  		if (dp_soc)
2170  			if (!cdp_soc_init(dp_soc, LITHIUM_DP,
2171  					  hif_context, params->target_psoc,
2172  					  htc_ctx, qdf_ctx,
2173  					  params->dp_ol_if_ops))
2174  				goto err_soc_detach;
2175  		*is_wifi3_0_target = true;
2176  	} else if (params->target_type == TARGET_TYPE_KIWI ||
2177  		   params->target_type == TARGET_TYPE_MANGO ||
2178  		   params->target_type == TARGET_TYPE_PEACH) {
2179  		dp_soc = cdp_soc_attach(BERYLLIUM_DP, hif_context,
2180  					params->target_psoc,
2181  					htc_ctx, qdf_ctx,
2182  					params->dp_ol_if_ops);
2183  		if (dp_soc)
2184  			if (!cdp_soc_init(dp_soc, BERYLLIUM_DP, hif_context,
2185  					  params->target_psoc, htc_ctx,
2186  					  qdf_ctx, params->dp_ol_if_ops))
2187  				goto err_soc_detach;
2188  		*is_wifi3_0_target = true;
2189  	} else if (params->target_type == TARGET_TYPE_WCN6450) {
2190  		dp_soc =
2191  			cdp_soc_attach(RHINE_DP, hif_context,
2192  				       params->target_psoc, htc_ctx,
2193  				       qdf_ctx, params->dp_ol_if_ops);
2194  		if (dp_soc)
2195  			if (!cdp_soc_init(dp_soc, RHINE_DP, hif_context,
2196  					  params->target_psoc, htc_ctx,
2197  					  qdf_ctx, params->dp_ol_if_ops))
2198  				goto err_soc_detach;
2199  		*is_wifi3_0_target = true;
2200  	} else {
2201  		dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP, hif_context,
2202  					params->target_psoc, htc_ctx, qdf_ctx,
2203  					params->dp_ol_if_ops);
2204  	}
2205  
2206  	if (!dp_soc)
2207  		return NULL;
2208  
2209  	dp_ctx->cdp_soc = dp_soc;
2210  	wlan_dp_rx_fisa_cmem_attach(dp_ctx);
2211  
2212  	return dp_soc;
2213  
2214  err_soc_detach:
2215  	cdp_soc_detach(dp_soc);
2216  	dp_soc = NULL;
2217  
2218  	return dp_soc;
2219  }
2220  
wlan_dp_txrx_soc_detach(ol_txrx_soc_handle soc)2221  void wlan_dp_txrx_soc_detach(ol_txrx_soc_handle soc)
2222  {
2223  	cdp_soc_deinit(soc);
2224  	cdp_soc_detach(soc);
2225  }
2226  
wlan_dp_txrx_attach_target(ol_txrx_soc_handle soc,uint8_t pdev_id)2227  QDF_STATUS wlan_dp_txrx_attach_target(ol_txrx_soc_handle soc, uint8_t pdev_id)
2228  {
2229  	struct wlan_dp_psoc_context *dp_ctx;
2230  	QDF_STATUS qdf_status;
2231  	int errno;
2232  
2233  	dp_ctx = dp_get_context();
2234  
2235  	qdf_status = cdp_soc_attach_target(soc);
2236  	if (QDF_IS_STATUS_ERROR(qdf_status)) {
2237  		dp_err("Failed to attach soc target; status:%d", qdf_status);
2238  		return qdf_status;
2239  	}
2240  
2241  	qdf_status = wlan_dp_rx_fisa_attach_target(dp_ctx);
2242  	if (QDF_IS_STATUS_ERROR(qdf_status))
2243  		return qdf_status;
2244  
2245  	errno = cdp_pdev_attach_target(soc, pdev_id);
2246  	if (errno) {
2247  		dp_err("Failed to attach pdev target; errno:%d", errno);
2248  		qdf_status = QDF_STATUS_E_FAILURE;
2249  		goto err_soc_detach_target;
2250  	}
2251  
2252  	return qdf_status;
2253  
2254  err_soc_detach_target:
2255  	/* NOP */
2256  	return qdf_status;
2257  }
2258  
wlan_dp_txrx_pdev_attach(ol_txrx_soc_handle soc)2259  QDF_STATUS wlan_dp_txrx_pdev_attach(ol_txrx_soc_handle soc)
2260  {
2261  	struct wlan_dp_psoc_context *dp_ctx;
2262  	struct cdp_pdev_attach_params pdev_params = { 0 };
2263  	QDF_STATUS qdf_status;
2264  
2265  	dp_ctx = dp_get_context();
2266  
2267  	pdev_params.htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
2268  	pdev_params.qdf_osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2269  	pdev_params.pdev_id = 0;
2270  
2271  	qdf_status = cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC),
2272  				     &pdev_params);
2273  	if (QDF_IS_STATUS_ERROR(qdf_status))
2274  		return qdf_status;
2275  
2276  	/* FISA Attach */
2277  	qdf_status = wlan_dp_rx_fisa_attach(dp_ctx);
2278  	if (QDF_IS_STATUS_ERROR(qdf_status)) {
2279  		/* return success to let init process go */
2280  		if (qdf_status == QDF_STATUS_E_NOSUPPORT)
2281  			return QDF_STATUS_SUCCESS;
2282  
2283  		wlan_dp_txrx_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC),
2284  					 OL_TXRX_PDEV_ID, false);
2285  		return qdf_status;
2286  	}
2287  
2288  	return qdf_status;
2289  }
2290  
wlan_dp_txrx_pdev_detach(ol_txrx_soc_handle soc,uint8_t pdev_id,int force)2291  QDF_STATUS wlan_dp_txrx_pdev_detach(ol_txrx_soc_handle soc, uint8_t pdev_id,
2292  				    int force)
2293  {
2294  	struct wlan_dp_psoc_context *dp_ctx;
2295  
2296  	dp_ctx =  dp_get_context();
2297  	wlan_dp_rx_fisa_detach(dp_ctx);
2298  	return cdp_pdev_detach(soc, pdev_id, force);
2299  }
2300  
2301  #ifdef FEATURE_DIRECT_LINK
2302  /**
2303   * dp_lpass_h2t_tx_complete() - Copy completion handler for LPASS data
2304   * message service
2305   * @ctx: DP Direct Link context
2306   * @pkt: htc packet
2307   *
2308   * Return: None
2309   */
dp_lpass_h2t_tx_complete(void * ctx,HTC_PACKET * pkt)2310  static void dp_lpass_h2t_tx_complete(void *ctx, HTC_PACKET *pkt)
2311  {
2312  	dp_info("Unexpected lpass tx complete trigger");
2313  	qdf_assert(0);
2314  }
2315  
2316  /**
2317   * dp_lpass_t2h_msg_handler() - target to host message handler for LPASS data
2318   * message service
2319   * @ctx: DP Direct Link context
2320   * @pkt: htc packet
2321   *
2322   * Return: None
2323   */
dp_lpass_t2h_msg_handler(void * ctx,HTC_PACKET * pkt)2324  static void dp_lpass_t2h_msg_handler(void *ctx, HTC_PACKET *pkt)
2325  {
2326  	dp_info("Unexpected receive msg trigger for lpass service");
2327  	qdf_assert(0);
2328  }
2329  
2330  /**
2331   * dp_lpass_connect_htc_service() - Connect lpass data message htc service
2332   * @dp_direct_link_ctx: DP Direct Link context
2333   *
2334   * Return: QDF status
2335   */
2336  static QDF_STATUS
dp_lpass_connect_htc_service(struct dp_direct_link_context * dp_direct_link_ctx)2337  dp_lpass_connect_htc_service(struct dp_direct_link_context *dp_direct_link_ctx)
2338  {
2339  	struct htc_service_connect_req connect = {0};
2340  	struct htc_service_connect_resp response = {0};
2341  	HTC_HANDLE htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
2342  	QDF_STATUS status;
2343  
2344  	if (!htc_handle)
2345  		return QDF_STATUS_E_FAILURE;
2346  
2347  	connect.EpCallbacks.pContext = dp_direct_link_ctx;
2348  	connect.EpCallbacks.EpTxComplete = dp_lpass_h2t_tx_complete;
2349  	connect.EpCallbacks.EpRecv = dp_lpass_t2h_msg_handler;
2350  
2351  	/* disable flow control for LPASS data message service */
2352  	connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
2353  	connect.service_id = LPASS_DATA_MSG_SVC;
2354  
2355  	status = htc_connect_service(htc_handle, &connect, &response);
2356  
2357  	if (status != QDF_STATUS_SUCCESS) {
2358  		dp_err("LPASS_DATA_MSG connect service failed");
2359  		return status;
2360  	}
2361  
2362  	dp_direct_link_ctx->lpass_ep_id = response.Endpoint;
2363  
2364  	dp_err("LPASS_DATA_MSG connect service successful");
2365  
2366  	return status;
2367  }
2368  
2369  /**
2370   * dp_direct_link_refill_ring_init() - Initialize refill ring that would be used
2371   *  for Direct Link DP
2372   * @direct_link_ctx: DP Direct Link context
2373   *
2374   * Return: QDF status
2375   */
2376  static QDF_STATUS
dp_direct_link_refill_ring_init(struct dp_direct_link_context * direct_link_ctx)2377  dp_direct_link_refill_ring_init(struct dp_direct_link_context *direct_link_ctx)
2378  {
2379  	struct cdp_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC);
2380  	uint8_t pdev_id;
2381  
2382  	if (!soc)
2383  		return QDF_STATUS_E_FAILURE;
2384  
2385  	pdev_id = wlan_objmgr_pdev_get_pdev_id(direct_link_ctx->dp_ctx->pdev);
2386  
2387  	direct_link_ctx->direct_link_refill_ring_hdl =
2388  				dp_setup_direct_link_refill_ring(soc,
2389  								 pdev_id);
2390  	if (!direct_link_ctx->direct_link_refill_ring_hdl) {
2391  		dp_err("Refill ring init for Direct Link failed");
2392  		return QDF_STATUS_E_FAILURE;
2393  	}
2394  
2395  	return QDF_STATUS_SUCCESS;
2396  }
2397  
2398  /**
2399   * dp_direct_link_refill_ring_deinit() - De-initialize refill ring that would be
2400   *  used for Direct Link DP
2401   * @dlink_ctx: DP Direct Link context
2402   *
2403   * Return: None
2404   */
2405  static void
dp_direct_link_refill_ring_deinit(struct dp_direct_link_context * dlink_ctx)2406  dp_direct_link_refill_ring_deinit(struct dp_direct_link_context *dlink_ctx)
2407  {
2408  	struct cdp_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC);
2409  	uint8_t pdev_id;
2410  
2411  	if (!soc)
2412  		return;
2413  
2414  	pdev_id = wlan_objmgr_pdev_get_pdev_id(dlink_ctx->dp_ctx->pdev);
2415  	dp_destroy_direct_link_refill_ring(soc, pdev_id);
2416  	dlink_ctx->direct_link_refill_ring_hdl = NULL;
2417  }
2418  
dp_direct_link_init(struct wlan_dp_psoc_context * dp_ctx)2419  QDF_STATUS dp_direct_link_init(struct wlan_dp_psoc_context *dp_ctx)
2420  {
2421  	struct dp_direct_link_context *dp_direct_link_ctx;
2422  	QDF_STATUS status;
2423  
2424  	if (!pld_is_direct_link_supported(dp_ctx->qdf_dev->dev)) {
2425  		dp_info("FW does not support Direct Link");
2426  		return QDF_STATUS_SUCCESS;
2427  	}
2428  
2429  	dp_direct_link_ctx = qdf_mem_malloc(sizeof(*dp_direct_link_ctx));
2430  	if (!dp_direct_link_ctx) {
2431  		dp_err("Failed to allocate memory for DP Direct Link context");
2432  		return QDF_STATUS_E_NOMEM;
2433  	}
2434  
2435  	dp_direct_link_ctx->dp_ctx = dp_ctx;
2436  
2437  	status = dp_lpass_connect_htc_service(dp_direct_link_ctx);
2438  	if (QDF_IS_STATUS_ERROR(status)) {
2439  		dp_err("Failed to connect to LPASS data msg service");
2440  		qdf_mem_free(dp_direct_link_ctx);
2441  		return status;
2442  	}
2443  
2444  	status = dp_direct_link_refill_ring_init(dp_direct_link_ctx);
2445  	if (QDF_IS_STATUS_ERROR(status)) {
2446  		qdf_mem_free(dp_direct_link_ctx);
2447  		return status;
2448  	}
2449  
2450  	status = dp_wfds_init(dp_direct_link_ctx);
2451  	if (QDF_IS_STATUS_ERROR(status)) {
2452  		dp_err("Failed to initialize QMI for Direct Link");
2453  		dp_direct_link_refill_ring_deinit(dp_ctx->dp_direct_link_ctx);
2454  		qdf_mem_free(dp_direct_link_ctx);
2455  		return status;
2456  	}
2457  	qdf_mutex_create(&dp_ctx->dp_direct_link_lock);
2458  
2459  	dp_ctx->dp_direct_link_ctx = dp_direct_link_ctx;
2460  
2461  	return status;
2462  }
2463  
dp_direct_link_deinit(struct wlan_dp_psoc_context * dp_ctx,bool is_ssr)2464  void dp_direct_link_deinit(struct wlan_dp_psoc_context *dp_ctx, bool is_ssr)
2465  {
2466  	struct wlan_dp_intf *dp_intf;
2467  
2468  	if (!pld_is_direct_link_supported(dp_ctx->qdf_dev->dev))
2469  		return;
2470  
2471  	if (!dp_ctx->dp_direct_link_ctx)
2472  		return;
2473  
2474  	for (dp_get_front_intf_no_lock(dp_ctx, &dp_intf); dp_intf;
2475  	     dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf)) {
2476  		if (dp_intf->device_mode == QDF_SAP_MODE)
2477  			dp_config_direct_link(dp_intf, false, false);
2478  	}
2479  
2480  	dp_wfds_deinit(dp_ctx->dp_direct_link_ctx, is_ssr);
2481  	dp_direct_link_refill_ring_deinit(dp_ctx->dp_direct_link_ctx);
2482  	qdf_mutex_destroy(&dp_ctx->dp_direct_link_lock);
2483  	qdf_mem_free(dp_ctx->dp_direct_link_ctx);
2484  	dp_ctx->dp_direct_link_ctx = NULL;
2485  }
2486  
dp_config_direct_link(struct wlan_dp_intf * dp_intf,bool config_direct_link,bool enable_low_latency)2487  QDF_STATUS dp_config_direct_link(struct wlan_dp_intf *dp_intf,
2488  				 bool config_direct_link,
2489  				 bool enable_low_latency)
2490  {
2491  	struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx;
2492  	struct direct_link_info *config = &dp_intf->direct_link_config;
2493  	struct wlan_dp_link *dp_link, *dp_link_next;
2494  	void *htc_handle;
2495  	bool prev_ll, update_ll, vote_link;
2496  	cdp_config_param_type vdev_param = {0};
2497  	QDF_STATUS status;
2498  
2499  	if (!dp_ctx || !dp_ctx->psoc) {
2500  		dp_err("DP Handle is NULL");
2501  		return QDF_STATUS_E_CANCELED;
2502  	}
2503  
2504  	if (!dp_ctx->dp_direct_link_ctx) {
2505  		dp_err("Direct link not enabled");
2506  		return QDF_STATUS_SUCCESS;
2507  	}
2508  
2509  	htc_handle = lmac_get_htc_hdl(dp_ctx->psoc);
2510  	if (!htc_handle) {
2511  		dp_err("HTC handle is NULL");
2512  		return QDF_STATUS_E_EMPTY;
2513  	}
2514  
2515  	qdf_mutex_acquire(&dp_ctx->dp_direct_link_lock);
2516  	prev_ll = config->low_latency;
2517  	update_ll = config_direct_link ? enable_low_latency : prev_ll;
2518  	vote_link = config->config_set ^ config_direct_link;
2519  	config->config_set = config_direct_link;
2520  	config->low_latency = enable_low_latency;
2521  	dp_for_each_link_held_safe(dp_intf, dp_link, dp_link_next) {
2522  		vdev_param.cdp_vdev_tx_to_fw = config_direct_link;
2523  		status = cdp_txrx_set_vdev_param(
2524  				wlan_psoc_get_dp_handle(dp_ctx->psoc),
2525  				dp_link->link_id, CDP_VDEV_TX_TO_FW,
2526  				vdev_param);
2527  		if (QDF_IS_STATUS_ERROR(status))
2528  			break;
2529  	}
2530  
2531  	if (config_direct_link) {
2532  		if (vote_link)
2533  			htc_vote_link_up(htc_handle,
2534  					 HTC_LINK_VOTE_DIRECT_LINK_USER_ID);
2535  		if (update_ll)
2536  			hif_prevent_link_low_power_states(
2537  						htc_get_hif_device(htc_handle));
2538  		else if (prev_ll)
2539  			hif_allow_link_low_power_states(
2540  						htc_get_hif_device(htc_handle));
2541  		dp_info("Direct link config set. Low link latency enabled: %d",
2542  			enable_low_latency);
2543  	} else {
2544  		if (vote_link)
2545  			htc_vote_link_down(htc_handle,
2546  					   HTC_LINK_VOTE_DIRECT_LINK_USER_ID);
2547  		if (update_ll)
2548  			hif_allow_link_low_power_states(
2549  						htc_get_hif_device(htc_handle));
2550  		dp_info("Direct link config cleared.");
2551  	}
2552  	qdf_mutex_release(&dp_ctx->dp_direct_link_lock);
2553  
2554  	return status;
2555  }
2556  #endif
2557  
2558  #ifdef WLAN_DP_PROFILE_SUPPORT
2559  struct wlan_dp_memory_profile_info *
wlan_dp_get_profile_info(void)2560  wlan_dp_get_profile_info(void)
2561  {
2562  	return &g_dp_profile_info;
2563  }
2564  
wlan_dp_select_profile_cfg(struct wlan_objmgr_psoc * psoc)2565  QDF_STATUS wlan_dp_select_profile_cfg(struct wlan_objmgr_psoc *psoc)
2566  {
2567  	struct pld_soc_info info = {0};
2568  	struct pld_wlan_hw_cap_info *hw_cap_info;
2569  	qdf_device_t qdf_dev;
2570  	bool apply_profile = false;
2571  	int ret;
2572  
2573  	apply_profile = cfg_get(psoc,
2574  				CFG_DP_APPLY_MEM_PROFILE);
2575  	if (!apply_profile)
2576  		return QDF_STATUS_E_NOSUPPORT;
2577  
2578  	qdf_dev = wlan_psoc_get_qdf_dev(psoc);
2579  	if (!qdf_dev)
2580  		return QDF_STATUS_E_FAILURE;
2581  
2582  	ret = pld_get_soc_info(qdf_dev->dev, &info);
2583  	if (ret) {
2584  		dp_err("profile selection failed unable to H.W caps reason:%u",
2585  		       qdf_status_from_os_return(ret));
2586  		return qdf_status_from_os_return(ret);
2587  	}
2588  
2589  	hw_cap_info = &info.hw_cap_info;
2590  	/* Based on supported H.W caps select required memory profile */
2591  	if (hw_cap_info->nss == PLD_WLAN_HW_CAP_NSS_1x1 &&
2592  	    hw_cap_info->bw == PLD_WLAN_HW_CHANNEL_BW_80MHZ &&
2593  	    hw_cap_info->qam == PLD_WLAN_HW_QAM_1K) {
2594  		g_dp_profile_info.is_selected = true;
2595  		g_dp_profile_info.ctx = wlan_dp_1x1_he80_1kqam;
2596  		g_dp_profile_info.size = QDF_ARRAY_SIZE(wlan_dp_1x1_he80_1kqam);
2597  		dp_info("DP profile selected is 1x1_HE80_1KQAM based");
2598  	}
2599  
2600  	return QDF_STATUS_SUCCESS;
2601  }
2602  
2603  #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL
2604  static void
wlan_dp_rx_refill_pool_cfg_sync_profile(struct cdp_soc_t * cdp_soc,struct wlan_dp_memory_profile_ctx * profile_ctx)2605  wlan_dp_rx_refill_pool_cfg_sync_profile(struct cdp_soc_t *cdp_soc,
2606  				struct wlan_dp_memory_profile_ctx *profile_ctx)
2607  {
2608  	cdp_config_param_type val;
2609  	QDF_STATUS status;
2610  	int cur_val;
2611  
2612  	status = cdp_txrx_get_psoc_param(cdp_soc, CDP_CFG_RX_REFILL_POOL_NUM,
2613  					 &val);
2614  	if (QDF_IS_STATUS_SUCCESS(status) &&
2615  	    val.cdp_rx_refill_buf_pool_size != profile_ctx->size) {
2616  		cur_val = val.cdp_rx_refill_buf_pool_size;
2617  		val.cdp_rx_refill_buf_pool_size = profile_ctx->size;
2618  		if (cdp_txrx_set_psoc_param(cdp_soc,
2619  					    CDP_CFG_RX_REFILL_POOL_NUM, val)) {
2620  			dp_err("unable to sync param type:%u", profile_ctx->param_type);
2621  			return;
2622  		}
2623  		dp_info("current Rx refill pool size:%u synced with profile:%u",
2624  			cur_val, profile_ctx->size);
2625  	}
2626  }
2627  #else
2628  static inline void
wlan_dp_rx_refill_pool_cfg_sync_profile(struct cdp_soc_t * cdp_soc,struct wlan_dp_memory_profile_ctx * profile_ctx)2629  wlan_dp_rx_refill_pool_cfg_sync_profile(struct cdp_soc_t *cdp_soc,
2630  				struct wlan_dp_memory_profile_ctx *profile_ctx)
2631  {
2632  }
2633  #endif
2634  
wlan_dp_soc_cfg_sync_profile(struct cdp_soc_t * cdp_soc)2635  void wlan_dp_soc_cfg_sync_profile(struct cdp_soc_t *cdp_soc)
2636  {
2637  	struct wlan_dp_memory_profile_info *profile_info;
2638  	struct wlan_dp_memory_profile_ctx *profile_ctx;
2639  	cdp_config_param_type val = {0};
2640  	QDF_STATUS status;
2641  	int cur_val, i;
2642  
2643  	profile_info = wlan_dp_get_profile_info();
2644  	if (!profile_info->is_selected)
2645  		return;
2646  
2647  	for (i = 0; i < profile_info->size; i++) {
2648  		profile_ctx = &profile_info->ctx[i];
2649  	       qdf_mem_zero(&val, sizeof(cdp_config_param_type));
2650  
2651  		switch (profile_ctx->param_type) {
2652  		case DP_TX_DESC_NUM_CFG:
2653  			status = cdp_txrx_get_psoc_param(cdp_soc,
2654  						CDP_CFG_TX_DESC_NUM, &val);
2655  			if (QDF_IS_STATUS_SUCCESS(status) &&
2656  			    val.cdp_tx_desc_num != profile_ctx->size) {
2657  				cur_val = val.cdp_tx_desc_num;
2658  				val.cdp_tx_desc_num = profile_ctx->size;
2659  				if (cdp_txrx_set_psoc_param(cdp_soc,
2660  						CDP_CFG_TX_DESC_NUM, val)) {
2661  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2662  					break;
2663  				}
2664  				dp_info("current Tx desc num:%u synced with profile:%u", cur_val, profile_ctx->size);
2665  			}
2666  			break;
2667  		case DP_TX_EXT_DESC_NUM_CFG:
2668  			status = cdp_txrx_get_psoc_param(cdp_soc,
2669  						CDP_CFG_TX_EXT_DESC_NUM, &val);
2670  			if (QDF_IS_STATUS_SUCCESS(status) &&
2671  			    val.cdp_tx_ext_desc_num != profile_ctx->size) {
2672  				cur_val = val.cdp_tx_ext_desc_num;
2673  				val.cdp_tx_ext_desc_num = profile_ctx->size;
2674  				if (cdp_txrx_set_psoc_param(cdp_soc,
2675  						CDP_CFG_TX_EXT_DESC_NUM, val)) {
2676  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2677  					break;
2678  				}
2679  				dp_info("current Ext Tx desc num:%u synced with profile:%u", cur_val, profile_ctx->size);
2680  			}
2681  			break;
2682  		case DP_TX_RING_SIZE_CFG:
2683  			status = cdp_txrx_get_psoc_param(cdp_soc,
2684  						CDP_CFG_TX_RING_SIZE, &val);
2685  			if (QDF_IS_STATUS_SUCCESS(status) &&
2686  			    val.cdp_tx_ring_size != profile_ctx->size) {
2687  				cur_val = val.cdp_tx_ring_size;
2688  				val.cdp_tx_ring_size = profile_ctx->size;
2689  				if (cdp_txrx_set_psoc_param(cdp_soc,
2690  						CDP_CFG_TX_RING_SIZE, val)) {
2691  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2692  					break;
2693  				}
2694  				dp_info("current Tx Ring size:%u synced with profile:%u", cur_val, profile_ctx->size);
2695  			}
2696  			break;
2697  		case DP_TX_COMPL_RING_SIZE_CFG:
2698  			status = cdp_txrx_get_psoc_param(cdp_soc,
2699  						CDP_CFG_TX_COMPL_RING_SIZE, &val);
2700  			if (QDF_IS_STATUS_SUCCESS(status) &&
2701  			    val.cdp_tx_comp_ring_size != profile_ctx->size) {
2702  				cur_val = val.cdp_tx_comp_ring_size;
2703  				val.cdp_tx_comp_ring_size = profile_ctx->size;
2704  				if (cdp_txrx_set_psoc_param(cdp_soc,
2705  							    CDP_CFG_TX_COMPL_RING_SIZE, val)) {
2706  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2707  					break;
2708  				}
2709  				dp_info("current Tx Comp Ring size:%u synced with profile:%u", cur_val, profile_ctx->size);
2710  			}
2711  			break;
2712  		case DP_RX_SW_DESC_NUM_CFG:
2713  			status = cdp_txrx_get_psoc_param(cdp_soc,
2714  						CDP_CFG_RX_SW_DESC_NUM, &val);
2715  			if (QDF_IS_STATUS_SUCCESS(status) &&
2716  			    val.cdp_rx_sw_desc_num != profile_ctx->size) {
2717  				cur_val = val.cdp_rx_sw_desc_num;
2718  				val.cdp_rx_sw_desc_num = profile_ctx->size;
2719  				if (cdp_txrx_set_psoc_param(cdp_soc,
2720  							    CDP_CFG_RX_SW_DESC_NUM, val)) {
2721  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2722  					break;
2723  				}
2724  				dp_info("current Rx desc num:%u synced with profile:%u", cur_val, profile_ctx->size);
2725  			}
2726  			break;
2727  		case DP_REO_DST_RING_SIZE_CFG:
2728  			status = cdp_txrx_get_psoc_param(cdp_soc,
2729  						CDP_CFG_REO_DST_RING_SIZE, &val);
2730  			if (QDF_IS_STATUS_SUCCESS(status) &&
2731  			    val.cdp_reo_dst_ring_size != profile_ctx->size) {
2732  				cur_val = val.cdp_reo_dst_ring_size;
2733  				val.cdp_reo_dst_ring_size = profile_ctx->size;
2734  				if (cdp_txrx_set_psoc_param(cdp_soc,
2735  							    CDP_CFG_REO_DST_RING_SIZE, val)) {
2736  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2737  					break;
2738  				}
2739  				dp_info("current Rx Ring size:%u synced with profile:%u", cur_val, profile_ctx->size);
2740  			}
2741  			break;
2742  		case DP_RXDMA_REFILL_RING_SIZE_CFG:
2743  			status = cdp_txrx_get_psoc_param(cdp_soc,
2744  						CDP_CFG_RXDMA_REFILL_RING_SIZE, &val);
2745  			if (QDF_IS_STATUS_SUCCESS(status) &&
2746  			    val.cdp_rxdma_refill_ring_size != profile_ctx->size) {
2747  				cur_val = val.cdp_rxdma_refill_ring_size;
2748  				val.cdp_rxdma_refill_ring_size = profile_ctx->size;
2749  				if (cdp_txrx_set_psoc_param(cdp_soc,
2750  							    CDP_CFG_RXDMA_REFILL_RING_SIZE, val)) {
2751  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2752  					break;
2753  				}
2754  				dp_info("current RXDMA refill ring size:%u synced with profile:%u", cur_val, profile_ctx->size);
2755  			}
2756  			break;
2757  		case DP_RX_REFILL_POOL_NUM_CFG:
2758  			wlan_dp_rx_refill_pool_cfg_sync_profile(cdp_soc,
2759  								profile_ctx);
2760  			break;
2761  		default:
2762  			dp_debug("Unknown profile param type:%u", profile_ctx->param_type);
2763  			break;
2764  		}
2765  	}
2766  }
2767  
wlan_dp_pdev_cfg_sync_profile(struct cdp_soc_t * cdp_soc,uint8_t pdev_id)2768  void wlan_dp_pdev_cfg_sync_profile(struct cdp_soc_t *cdp_soc, uint8_t pdev_id)
2769  {
2770  	struct wlan_dp_memory_profile_info *profile_info;
2771  	struct wlan_dp_memory_profile_ctx *profile_ctx;
2772  	cdp_config_param_type val = {0};
2773  	QDF_STATUS status;
2774  	int cur_val, i;
2775  
2776  	profile_info = wlan_dp_get_profile_info();
2777  	if (!profile_info->is_selected)
2778  		return;
2779  
2780  	for (i = 0; i < profile_info->size; i++) {
2781  		profile_ctx = &profile_info->ctx[i];
2782  		if (profile_ctx->param_type == DP_RXDMA_BUF_RING_SIZE_CFG) {
2783  			status = cdp_txrx_get_pdev_param(cdp_soc, pdev_id,
2784  					CDP_CONFIG_RXDMA_BUF_RING_SIZE, &val);
2785  			if (QDF_IS_STATUS_SUCCESS(status) &&
2786  			    val.cdp_rxdma_buf_ring_size != profile_ctx->size) {
2787  				cur_val = val.cdp_rxdma_buf_ring_size;
2788  				val.cdp_rxdma_buf_ring_size = profile_ctx->size;
2789  				if (cdp_txrx_set_pdev_param(cdp_soc, pdev_id,
2790  							    CDP_CONFIG_RXDMA_BUF_RING_SIZE, val)) {
2791  					dp_err("unable to sync param type:%u", profile_ctx->param_type);
2792  					return;
2793  				}
2794  				dp_info("current RXDMA buf ring size:%u synced with profile:%u", cur_val, profile_ctx->size);
2795  			}
2796  			return;
2797  		}
2798  	}
2799  
2800  	dp_err("pdev based config item not found in profile table");
2801  }
2802  #endif
2803  
__wlan_dp_update_def_link(struct wlan_objmgr_psoc * psoc,struct qdf_mac_addr * intf_mac,struct wlan_objmgr_vdev * vdev)2804  void __wlan_dp_update_def_link(struct wlan_objmgr_psoc *psoc,
2805  			       struct qdf_mac_addr *intf_mac,
2806  			       struct wlan_objmgr_vdev *vdev)
2807  {
2808  	struct wlan_dp_intf *dp_intf;
2809  	struct wlan_dp_link *dp_link;
2810  	struct wlan_dp_psoc_context *dp_ctx;
2811  	struct qdf_mac_addr zero_addr = QDF_MAC_ADDR_ZERO_INIT;
2812  
2813  	dp_ctx =  dp_psoc_get_priv(psoc);
2814  
2815  	dp_intf = dp_get_intf_by_macaddr(dp_ctx, intf_mac);
2816  	if (!dp_intf) {
2817  		dp_err("DP interface not found addr:" QDF_MAC_ADDR_FMT,
2818  		       QDF_MAC_ADDR_REF(intf_mac->bytes));
2819  		QDF_BUG(0);
2820  		return;
2821  	}
2822  
2823  	dp_link = dp_get_vdev_priv_obj(vdev);
2824  	if (dp_link && dp_link->dp_intf == dp_intf) {
2825  		dp_info("change dp_intf %pK(" QDF_MAC_ADDR_FMT
2826  			") def_link %d(" QDF_MAC_ADDR_FMT ") -> %d("
2827  			 QDF_MAC_ADDR_FMT ")",
2828  			dp_intf, QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes),
2829  			dp_intf->def_link->link_id,
2830  			QDF_MAC_ADDR_REF(dp_intf->def_link->mac_addr.bytes),
2831  			dp_link->link_id,
2832  			QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
2833  		dp_intf->def_link = dp_link;
2834  		return;
2835  	}
2836  
2837  	dp_info("Update failed dp_intf %pK(" QDF_MAC_ADDR_FMT ") from %pK("
2838  		QDF_MAC_ADDR_FMT ") to %pK(" QDF_MAC_ADDR_FMT ") (intf %pK("
2839  		QDF_MAC_ADDR_FMT ") id %d) ",
2840  		dp_intf, QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes),
2841  		dp_intf->def_link,
2842  		QDF_MAC_ADDR_REF(dp_intf->def_link->mac_addr.bytes),
2843  		dp_link, dp_link ? QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes) :
2844  					QDF_MAC_ADDR_REF(zero_addr.bytes),
2845  		dp_link ? dp_link->dp_intf : NULL,
2846  		dp_link ? QDF_MAC_ADDR_REF(dp_link->dp_intf->mac_addr.bytes) :
2847  				QDF_MAC_ADDR_REF(zero_addr.bytes),
2848  		dp_link ? dp_link->link_id : WLAN_INVALID_LINK_ID);
2849  }
2850