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