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