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