xref: /wlan-driver/qcacld-3.0/components/dp/core/src/wlan_dp_bus_bandwidth.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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 /**
20  * DOC: wlan_dp_bus_bandwidth.c
21  *
22  * Bus Bandwidth Manager implementation
23  */
24 
25 #include "wlan_dp_bus_bandwidth.h"
26 #include "wlan_dp_main.h"
27 #include <wlan_objmgr_psoc_obj_i.h>
28 #include "pld_common.h"
29 #include "cds_api.h"
30 #include <wlan_nlink_common.h>
31 #include "wlan_ipa_ucfg_api.h"
32 #include "wlan_dp_rx_thread.h"
33 #include "wlan_mlme_vdev_mgr_interface.h"
34 #include "hif.h"
35 #include "qdf_trace.h"
36 #include <wlan_cm_api.h>
37 #include <qdf_threads.h>
38 #include <qdf_net_stats.h>
39 #include "wlan_dp_periodic_sta_stats.h"
40 #include "wlan_mlme_api.h"
41 #include "wlan_dp_txrx.h"
42 #include "cdp_txrx_host_stats.h"
43 #include "wlan_cm_roam_api.h"
44 #include "hif_main.h"
45 
46 #ifdef FEATURE_BUS_BANDWIDTH_MGR
47 /*
48  * bus_bw_table_default: default table which provides bus
49  * bandwidth level corresponding to a given connection mode and throughput
50  * level.
51  */
52 static bus_bw_table_type bus_bw_table_default = {
53 	[QCA_WLAN_802_11_MODE_11B] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
54 				      BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
55 				      BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
56 				      BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
57 				      BUS_BW_LEVEL_9},
58 	[QCA_WLAN_802_11_MODE_11G] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_5,
59 				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
60 				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
61 				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
62 				      BUS_BW_LEVEL_5},
63 	[QCA_WLAN_802_11_MODE_11A] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_5,
64 				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
65 				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
66 				      BUS_BW_LEVEL_5, BUS_BW_LEVEL_5,
67 				      BUS_BW_LEVEL_5},
68 	[QCA_WLAN_802_11_MODE_11N] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
69 				      BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
70 				      BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
71 				      BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
72 				      BUS_BW_LEVEL_9},
73 	[QCA_WLAN_802_11_MODE_11AC] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
74 				       BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
75 				       BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
76 				       BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
77 				       BUS_BW_LEVEL_9},
78 	[QCA_WLAN_802_11_MODE_11AX] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
79 				       BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
80 				       BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
81 				       BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
82 				       BUS_BW_LEVEL_9},
83 	[QCA_WLAN_802_11_MODE_11BE] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_1,
84 				       BUS_BW_LEVEL_2, BUS_BW_LEVEL_3,
85 				       BUS_BW_LEVEL_4, BUS_BW_LEVEL_6,
86 				       BUS_BW_LEVEL_7, BUS_BW_LEVEL_8,
87 				       BUS_BW_LEVEL_9},
88 };
89 
90 /*
91  * bus_bw_table_low_latency: table which provides bus
92  * bandwidth level corresponding to a given connection mode and throughput
93  * level in low latency setting.
94  */
95 static bus_bw_table_type bus_bw_table_low_latency = {
96 	[QCA_WLAN_802_11_MODE_11B] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
97 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
98 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
99 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
100 				      BUS_BW_LEVEL_9},
101 	[QCA_WLAN_802_11_MODE_11G] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
102 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
103 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
104 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
105 				      BUS_BW_LEVEL_9},
106 	[QCA_WLAN_802_11_MODE_11A] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
107 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
108 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
109 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
110 				      BUS_BW_LEVEL_9},
111 	[QCA_WLAN_802_11_MODE_11N] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
112 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
113 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
114 				      BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
115 				      BUS_BW_LEVEL_9},
116 	[QCA_WLAN_802_11_MODE_11AC] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
117 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
118 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
119 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
120 				       BUS_BW_LEVEL_9},
121 	[QCA_WLAN_802_11_MODE_11AX] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
122 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
123 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
124 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
125 				       BUS_BW_LEVEL_9},
126 	[QCA_WLAN_802_11_MODE_11BE] = {BUS_BW_LEVEL_NONE, BUS_BW_LEVEL_9,
127 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
128 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
129 				       BUS_BW_LEVEL_9, BUS_BW_LEVEL_9,
130 				       BUS_BW_LEVEL_9},
131 };
132 
133 /**
134  * bbm_convert_to_pld_bus_lvl() - Convert from internal bus vote level to
135  *  PLD bus vote level
136  * @vote_lvl: internal bus bw vote level
137  *
138  * Returns: PLD bus vote level
139  */
140 static enum pld_bus_width_type
bbm_convert_to_pld_bus_lvl(enum bus_bw_level vote_lvl)141 bbm_convert_to_pld_bus_lvl(enum bus_bw_level vote_lvl)
142 {
143 	switch (vote_lvl) {
144 	case BUS_BW_LEVEL_1:
145 		return PLD_BUS_WIDTH_IDLE;
146 	case BUS_BW_LEVEL_2:
147 		return PLD_BUS_WIDTH_LOW;
148 	case BUS_BW_LEVEL_3:
149 		return PLD_BUS_WIDTH_MEDIUM;
150 	case BUS_BW_LEVEL_4:
151 		return PLD_BUS_WIDTH_HIGH;
152 	case BUS_BW_LEVEL_5:
153 		return PLD_BUS_WIDTH_LOW_LATENCY;
154 	case BUS_BW_LEVEL_6:
155 		return PLD_BUS_WIDTH_MID_HIGH;
156 	case BUS_BW_LEVEL_7:
157 		return PLD_BUS_WIDTH_VERY_HIGH;
158 	case BUS_BW_LEVEL_8:
159 		return PLD_BUS_WIDTH_ULTRA_HIGH;
160 	case BUS_BW_LEVEL_9:
161 		return PLD_BUS_WIDTH_MAX;
162 	case BUS_BW_LEVEL_NONE:
163 	default:
164 		return PLD_BUS_WIDTH_NONE;
165 	}
166 }
167 
168 /**
169  * bbm_get_bus_bw_level_vote() - Select bus bw vote level per interface based
170  *  on connection mode and throughput level
171  * @dp_intf: DP Interface, caller assure that interface is valid.
172  * @tput_level: throughput level
173  *
174  * Returns: Bus bw level
175  */
176 static enum bus_bw_level
bbm_get_bus_bw_level_vote(struct wlan_dp_intf * dp_intf,enum tput_level tput_level)177 bbm_get_bus_bw_level_vote(struct wlan_dp_intf *dp_intf,
178 			  enum tput_level tput_level)
179 {
180 	enum qca_wlan_802_11_mode i;
181 	enum qca_wlan_802_11_mode dot11_mode;
182 	enum bus_bw_level vote_lvl = BUS_BW_LEVEL_NONE;
183 	struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx;
184 	struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx;
185 	bus_bw_table_type *lkp_table = bbm_ctx->curr_bus_bw_lookup_table;
186 	uint16_t client_count[QCA_WLAN_802_11_MODE_INVALID];
187 	struct wlan_dp_psoc_callbacks *cb_obj = &dp_ctx->dp_ops;
188 	hdd_cb_handle ctx = cb_obj->callback_ctx;
189 
190 	if (tput_level >= TPUT_LEVEL_MAX) {
191 		dp_err("invalid tput level %d", tput_level);
192 		return  BUS_BW_LEVEL_NONE;
193 	}
194 
195 	switch (dp_intf->device_mode) {
196 	case QDF_STA_MODE:
197 	case QDF_P2P_CLIENT_MODE:
198 		if (!cb_obj->wlan_dp_sta_get_dot11mode(ctx,
199 						       dp_intf->dev,
200 						       &dot11_mode))
201 			break;
202 
203 		if (dot11_mode >= QCA_WLAN_802_11_MODE_INVALID)
204 			break;
205 
206 		return (*lkp_table)[dot11_mode][tput_level];
207 	case QDF_SAP_MODE:
208 	case QDF_P2P_GO_MODE:
209 		if (!cb_obj->wlan_dp_get_ap_client_count(ctx,
210 							 dp_intf->dev,
211 							 client_count))
212 			break;
213 
214 		for (i = QCA_WLAN_802_11_MODE_11B;
215 		     i < QCA_WLAN_802_11_MODE_INVALID; i++) {
216 			if (client_count[i] &&
217 			    (*lkp_table)[i][tput_level] > vote_lvl)
218 				vote_lvl = (*lkp_table)[i][tput_level];
219 		}
220 
221 		return vote_lvl;
222 	case QDF_NDI_MODE:
223 		if (!cb_obj->wlan_dp_sta_ndi_connected(ctx,
224 						       dp_intf->dev))
225 			break;
226 
227 		/*
228 		 * If the tput levels are between mid to high range, then
229 		 * apply next SNOC voting level BUS_BW_LEVEL_5 which maps
230 		 * to PLD_BUS_WIDTH_LOW_LATENCY.
231 		 *
232 		 * NDI dot11mode is currently hardcoded to 11AC in driver and
233 		 * since the bus bw levels in table do not differ between 11AC
234 		 * and 11AX, using max supported mode instead. Dot11mode of the
235 		 * peers are not saved in driver and legacy modes are not
236 		 * supported in NAN.
237 		 */
238 		if (tput_level <= TPUT_LEVEL_HIGH)
239 			return BUS_BW_LEVEL_5;
240 		else
241 			return (*lkp_table)[QCA_WLAN_802_11_MODE_11AX][tput_level];
242 	default:
243 		break;
244 	}
245 
246 	return vote_lvl;
247 }
248 
249 /**
250  * bbm_apply_tput_policy() - Apply tput BBM policy by considering
251  *  throughput level and connection modes across adapters
252  * @dp_ctx: DP context
253  * @tput_level: throughput level
254  *
255  * Returns: None
256  */
257 static void
bbm_apply_tput_policy(struct wlan_dp_psoc_context * dp_ctx,enum tput_level tput_level)258 bbm_apply_tput_policy(struct wlan_dp_psoc_context *dp_ctx,
259 		      enum tput_level tput_level)
260 {
261 	struct wlan_dp_intf *dp_intf;
262 	struct wlan_dp_intf *dp_intf_next;
263 	struct wlan_objmgr_psoc *psoc;
264 	enum bus_bw_level next_vote = BUS_BW_LEVEL_NONE;
265 	enum bus_bw_level tmp_vote;
266 	struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx;
267 	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
268 
269 	if (tput_level == TPUT_LEVEL_NONE) {
270 		/*
271 		 * This is to handle the scenario where bus bw periodic work
272 		 * is force cancelled
273 		 */
274 		if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
275 			bbm_ctx->per_policy_vote[BBM_TPUT_POLICY] = next_vote;
276 		return;
277 	}
278 
279 	psoc = dp_ctx->psoc;
280 	if (!psoc) {
281 		dp_err("psoc is NULL");
282 		return;
283 	}
284 
285 	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
286 		if (dp_intf->num_links == 0)
287 			continue;
288 
289 		tmp_vote = bbm_get_bus_bw_level_vote(dp_intf, tput_level);
290 		if (tmp_vote > next_vote)
291 			next_vote = tmp_vote;
292 	}
293 
294 	bbm_ctx->per_policy_vote[BBM_TPUT_POLICY] = next_vote;
295 }
296 
297 /**
298  * bbm_apply_driver_mode_policy() - Apply driver mode BBM policy
299  * @bbm_ctx: bus bw mgr context
300  * @driver_mode: global driver mode
301  *
302  * Returns: None
303  */
304 static void
bbm_apply_driver_mode_policy(struct bbm_context * bbm_ctx,enum QDF_GLOBAL_MODE driver_mode)305 bbm_apply_driver_mode_policy(struct bbm_context *bbm_ctx,
306 			     enum QDF_GLOBAL_MODE driver_mode)
307 {
308 	switch (driver_mode) {
309 	case QDF_GLOBAL_MONITOR_MODE:
310 	case QDF_GLOBAL_FTM_MODE:
311 		bbm_ctx->per_policy_vote[BBM_DRIVER_MODE_POLICY] =
312 							    BUS_BW_LEVEL_7;
313 		return;
314 	default:
315 		bbm_ctx->per_policy_vote[BBM_DRIVER_MODE_POLICY] =
316 							 BUS_BW_LEVEL_NONE;
317 		return;
318 	}
319 }
320 
321 /**
322  * bbm_apply_non_persistent_policy() - Apply non persistent policy and set
323  *  the bus bandwidth
324  * @dp_ctx: DP context
325  * @flag: flag
326  *
327  * Returns: None
328  */
329 static void
bbm_apply_non_persistent_policy(struct wlan_dp_psoc_context * dp_ctx,enum bbm_non_per_flag flag)330 bbm_apply_non_persistent_policy(struct wlan_dp_psoc_context *dp_ctx,
331 				enum bbm_non_per_flag flag)
332 {
333 	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
334 
335 	switch (flag) {
336 	case BBM_APPS_RESUME:
337 		if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx)) {
338 			dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_RESUME;
339 			pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev,
340 			       bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_RESUME));
341 		} else {
342 			dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_NONE;
343 			pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev,
344 				 bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_NONE));
345 		}
346 		return;
347 	case BBM_APPS_SUSPEND:
348 		dp_ctx->bbm_ctx->curr_vote_level = BUS_BW_LEVEL_NONE;
349 		pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev,
350 			    bbm_convert_to_pld_bus_lvl(BUS_BW_LEVEL_NONE));
351 		return;
352 	default:
353 		dp_info("flag %d not handled in res/sus BBM policy", flag);
354 		return;
355 	}
356 }
357 
358 /**
359  * bbm_apply_wlm_policy() - Apply WLM based BBM policy by selecting
360  *  lookup tables based on the latency level
361  * @bbm_ctx: Bus BW mgr context
362  * @wlm_level: WLM latency level
363  *
364  * Returns: None
365  */
366 static void
bbm_apply_wlm_policy(struct bbm_context * bbm_ctx,enum wlm_ll_level wlm_level)367 bbm_apply_wlm_policy(struct bbm_context *bbm_ctx, enum wlm_ll_level wlm_level)
368 {
369 	switch (wlm_level) {
370 	case WLM_LL_NORMAL:
371 		bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_default;
372 		break;
373 	case WLM_LL_LOW:
374 		bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_low_latency;
375 		break;
376 	default:
377 		dp_info("wlm level %d not handled in BBM WLM policy",
378 			wlm_level);
379 		break;
380 	}
381 }
382 
383 /**
384  * bbm_apply_user_policy() - Apply user specified bus voting
385  *  level
386  * @bbm_ctx: Bus BW mgr context
387  * @set: set or reset flag
388  * @user_level: user bus vote level
389  *
390  * Returns: qdf status
391  */
392 static QDF_STATUS
bbm_apply_user_policy(struct bbm_context * bbm_ctx,bool set,enum bus_bw_level user_level)393 bbm_apply_user_policy(struct bbm_context *bbm_ctx, bool set,
394 		      enum bus_bw_level user_level)
395 {
396 	if (user_level >= BUS_BW_LEVEL_MAX) {
397 		dp_err("Invalid user vote level %d", user_level);
398 		return QDF_STATUS_E_FAILURE;
399 	}
400 
401 	if (set)
402 		bbm_ctx->per_policy_vote[BBM_USER_POLICY] = user_level;
403 	else
404 		bbm_ctx->per_policy_vote[BBM_USER_POLICY] = BUS_BW_LEVEL_NONE;
405 
406 	return QDF_STATUS_SUCCESS;
407 }
408 
409 /**
410  * bbm_request_bus_bandwidth() - Set bus bandwidth level
411  * @dp_ctx: DP context
412  *
413  * Returns: None
414  */
415 static void
bbm_request_bus_bandwidth(struct wlan_dp_psoc_context * dp_ctx)416 bbm_request_bus_bandwidth(struct wlan_dp_psoc_context *dp_ctx)
417 {
418 	enum bbm_policy i;
419 	enum bus_bw_level next_vote = BUS_BW_LEVEL_NONE;
420 	enum pld_bus_width_type pld_vote;
421 	struct bbm_context *bbm_ctx = dp_ctx->bbm_ctx;
422 
423 	for (i = BBM_DRIVER_MODE_POLICY; i < BBM_MAX_POLICY; i++) {
424 		if (bbm_ctx->per_policy_vote[i] > next_vote)
425 			next_vote = bbm_ctx->per_policy_vote[i];
426 	}
427 
428 	if (next_vote != bbm_ctx->curr_vote_level) {
429 		pld_vote = bbm_convert_to_pld_bus_lvl(next_vote);
430 		dp_info("Bus bandwidth vote level change from %d to %d pld_vote: %d",
431 			bbm_ctx->curr_vote_level, next_vote, pld_vote);
432 		bbm_ctx->curr_vote_level = next_vote;
433 		pld_request_bus_bandwidth(dp_ctx->qdf_dev->dev, pld_vote);
434 	}
435 }
436 
dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc * psoc,struct bbm_params * params)437 void dp_bbm_apply_independent_policy(struct wlan_objmgr_psoc *psoc,
438 				     struct bbm_params *params)
439 {
440 	struct wlan_dp_psoc_context *dp_ctx;
441 	struct bbm_context *bbm_ctx;
442 	QDF_STATUS status;
443 
444 	dp_ctx = dp_psoc_get_priv(psoc);
445 	if (!dp_ctx || !params)
446 		return;
447 
448 	bbm_ctx = dp_ctx->bbm_ctx;
449 
450 	qdf_mutex_acquire(&bbm_ctx->bbm_lock);
451 
452 	switch (params->policy) {
453 	case BBM_TPUT_POLICY:
454 		bbm_apply_tput_policy(dp_ctx, params->policy_info.tput_level);
455 		break;
456 	case BBM_NON_PERSISTENT_POLICY:
457 		bbm_apply_non_persistent_policy(dp_ctx,
458 						params->policy_info.flag);
459 		goto done;
460 	case BBM_DRIVER_MODE_POLICY:
461 		bbm_apply_driver_mode_policy(bbm_ctx,
462 					     params->policy_info.driver_mode);
463 		break;
464 	case BBM_SELECT_TABLE_POLICY:
465 		bbm_apply_wlm_policy(bbm_ctx, params->policy_info.wlm_level);
466 		goto done;
467 	case BBM_USER_POLICY:
468 		/*
469 		 * This policy is not used currently.
470 		 */
471 		status = bbm_apply_user_policy(bbm_ctx,
472 					       params->policy_info.usr.set,
473 					       params->policy_info.usr.user_level);
474 		if (QDF_IS_STATUS_ERROR(status))
475 			goto done;
476 		break;
477 	default:
478 		dp_info("BBM policy %d not handled", params->policy);
479 		goto done;
480 	}
481 
482 	bbm_request_bus_bandwidth(dp_ctx);
483 
484 done:
485 	qdf_mutex_release(&bbm_ctx->bbm_lock);
486 }
487 
dp_bbm_context_init(struct wlan_objmgr_psoc * psoc)488 int dp_bbm_context_init(struct wlan_objmgr_psoc *psoc)
489 {
490 	struct wlan_dp_psoc_context *dp_ctx;
491 	struct bbm_context *bbm_ctx;
492 	QDF_STATUS status;
493 
494 	dp_ctx = dp_psoc_get_priv(psoc);
495 	if (!dp_ctx)
496 		return -EINVAL;
497 	bbm_ctx = qdf_mem_malloc(sizeof(*bbm_ctx));
498 	if (!bbm_ctx)
499 		return -ENOMEM;
500 
501 	bbm_ctx->curr_bus_bw_lookup_table = &bus_bw_table_default;
502 
503 	status = qdf_mutex_create(&bbm_ctx->bbm_lock);
504 	if (QDF_IS_STATUS_ERROR(status))
505 		goto free_ctx;
506 
507 	dp_ctx->bbm_ctx = bbm_ctx;
508 
509 	return 0;
510 
511 free_ctx:
512 	qdf_mem_free(bbm_ctx);
513 
514 	return qdf_status_to_os_return(status);
515 }
516 
dp_bbm_context_deinit(struct wlan_objmgr_psoc * psoc)517 void dp_bbm_context_deinit(struct wlan_objmgr_psoc *psoc)
518 {
519 	struct wlan_dp_psoc_context *dp_ctx;
520 	struct bbm_context *bbm_ctx;
521 
522 	dp_ctx = dp_psoc_get_priv(psoc);
523 	if (!dp_ctx)
524 		return;
525 	bbm_ctx = dp_ctx->bbm_ctx;
526 	if (!bbm_ctx)
527 		return;
528 
529 	dp_ctx->bbm_ctx = NULL;
530 	qdf_mutex_destroy(&bbm_ctx->bbm_lock);
531 
532 	qdf_mem_free(bbm_ctx);
533 }
534 #endif /* FEATURE_BUS_BANDWIDTH_MGR */
535 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
536 #ifdef FEATURE_RUNTIME_PM
dp_rtpm_tput_policy_init(struct wlan_objmgr_psoc * psoc)537 void dp_rtpm_tput_policy_init(struct wlan_objmgr_psoc *psoc)
538 {
539 	struct wlan_dp_psoc_context *dp_ctx;
540 	struct dp_rtpm_tput_policy_context *ctx;
541 
542 	dp_ctx = dp_psoc_get_priv(psoc);
543 	if (!dp_ctx) {
544 		dp_err("Unable to get DP context");
545 		return;
546 	}
547 
548 	ctx = &dp_ctx->rtpm_tput_policy_ctx;
549 	qdf_runtime_lock_init(&ctx->rtpm_lock);
550 	ctx->curr_state = DP_RTPM_TPUT_POLICY_STATE_REQUIRED;
551 	qdf_atomic_init(&ctx->high_tput_vote);
552 }
553 
dp_rtpm_tput_policy_deinit(struct wlan_objmgr_psoc * psoc)554 void dp_rtpm_tput_policy_deinit(struct wlan_objmgr_psoc *psoc)
555 {
556 	struct wlan_dp_psoc_context *dp_ctx;
557 	struct dp_rtpm_tput_policy_context *ctx;
558 
559 	dp_ctx = dp_psoc_get_priv(psoc);
560 	if (!dp_ctx) {
561 		dp_err("Unable to get DP context");
562 		return;
563 	}
564 
565 	ctx = &dp_ctx->rtpm_tput_policy_ctx;
566 	ctx->curr_state = DP_RTPM_TPUT_POLICY_STATE_INVALID;
567 	qdf_runtime_lock_deinit(&ctx->rtpm_lock);
568 }
569 
570 /**
571  * dp_rtpm_tput_policy_prevent() - prevent a runtime bus suspend
572  * @dp_ctx: DP handle
573  *
574  * return: None
575  */
dp_rtpm_tput_policy_prevent(struct wlan_dp_psoc_context * dp_ctx)576 static void dp_rtpm_tput_policy_prevent(struct wlan_dp_psoc_context *dp_ctx)
577 {
578 	struct dp_rtpm_tput_policy_context *ctx;
579 
580 	ctx = &dp_ctx->rtpm_tput_policy_ctx;
581 	qdf_runtime_pm_prevent_suspend(&ctx->rtpm_lock);
582 }
583 
584 /**
585  * dp_rtpm_tput_policy_allow() - allow a runtime bus suspend
586  * @dp_ctx: DP handle
587  *
588  * return: None
589  */
dp_rtpm_tput_policy_allow(struct wlan_dp_psoc_context * dp_ctx)590 static void dp_rtpm_tput_policy_allow(struct wlan_dp_psoc_context *dp_ctx)
591 {
592 	struct dp_rtpm_tput_policy_context *ctx;
593 
594 	ctx = &dp_ctx->rtpm_tput_policy_ctx;
595 	qdf_runtime_pm_allow_suspend(&ctx->rtpm_lock);
596 }
597 
598 #define DP_RTPM_POLICY_HIGH_TPUT_THRESH TPUT_LEVEL_MEDIUM
599 
dp_rtpm_tput_policy_apply(struct wlan_dp_psoc_context * dp_ctx,enum tput_level tput_level)600 void dp_rtpm_tput_policy_apply(struct wlan_dp_psoc_context *dp_ctx,
601 			       enum tput_level tput_level)
602 {
603 	int vote;
604 	enum dp_rtpm_tput_policy_state temp_state;
605 	struct dp_rtpm_tput_policy_context *ctx;
606 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
607 
608 	if (qdf_unlikely(!soc))
609 		return;
610 
611 	ctx = &dp_ctx->rtpm_tput_policy_ctx;
612 
613 	if (tput_level >= DP_RTPM_POLICY_HIGH_TPUT_THRESH)
614 		temp_state = DP_RTPM_TPUT_POLICY_STATE_NOT_REQUIRED;
615 	else
616 		temp_state = DP_RTPM_TPUT_POLICY_STATE_REQUIRED;
617 
618 	if (ctx->curr_state == temp_state)
619 		return;
620 
621 	if (temp_state == DP_RTPM_TPUT_POLICY_STATE_REQUIRED) {
622 		cdp_set_rtpm_tput_policy_requirement(soc, false);
623 		qdf_atomic_dec(&ctx->high_tput_vote);
624 		dp_rtpm_tput_policy_allow(dp_ctx);
625 	} else {
626 		cdp_set_rtpm_tput_policy_requirement(soc, true);
627 		qdf_atomic_inc(&ctx->high_tput_vote);
628 		dp_rtpm_tput_policy_prevent(dp_ctx);
629 	}
630 
631 	ctx->curr_state = temp_state;
632 	vote = qdf_atomic_read(&ctx->high_tput_vote);
633 
634 	if (vote < 0 || vote > 1) {
635 		dp_alert_rl("Incorrect vote!");
636 		QDF_BUG(0);
637 	}
638 }
639 
dp_rtpm_tput_policy_get_vote(struct wlan_dp_psoc_context * dp_ctx)640 int dp_rtpm_tput_policy_get_vote(struct wlan_dp_psoc_context *dp_ctx)
641 {
642 	struct dp_rtpm_tput_policy_context *ctx;
643 
644 	ctx = &dp_ctx->rtpm_tput_policy_ctx;
645 	return qdf_atomic_read(&ctx->high_tput_vote);
646 }
647 #endif /* FEATURE_RUNTIME_PM */
648 
dp_reset_tcp_delack(struct wlan_objmgr_psoc * psoc)649 void dp_reset_tcp_delack(struct wlan_objmgr_psoc *psoc)
650 {
651 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
652 
653 	enum wlan_tp_level next_level = WLAN_SVC_TP_LOW;
654 	struct wlan_rx_tp_data rx_tp_data = {0};
655 
656 	if (!dp_ctx) {
657 		dp_err("Unable to get DP context");
658 		return;
659 	}
660 
661 	if (!dp_ctx->en_tcp_delack_no_lro)
662 		return;
663 
664 	rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
665 	rx_tp_data.level = next_level;
666 	dp_ctx->rx_high_ind_cnt = 0;
667 	wlan_dp_update_tcp_rx_param(dp_ctx, &rx_tp_data);
668 }
669 
670 /**
671  * dp_reset_tcp_adv_win_scale() - Reset TCP advance window scaling
672  * value to default
673  * @dp_ctx: pointer to DP context (Should not be NULL)
674  *
675  * Function used to reset TCP advance window scaling
676  * value to its default value
677  *
678  * Return: None
679  */
dp_reset_tcp_adv_win_scale(struct wlan_dp_psoc_context * dp_ctx)680 static void dp_reset_tcp_adv_win_scale(struct wlan_dp_psoc_context *dp_ctx)
681 {
682 	enum wlan_tp_level next_level = WLAN_SVC_TP_NONE;
683 	struct wlan_rx_tp_data rx_tp_data = {0};
684 
685 	if (!dp_ctx->dp_cfg.enable_tcp_adv_win_scale)
686 		return;
687 
688 	rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
689 	rx_tp_data.level = next_level;
690 	dp_ctx->cur_rx_level = WLAN_SVC_TP_NONE;
691 	wlan_dp_update_tcp_rx_param(dp_ctx, &rx_tp_data);
692 }
693 
wlan_dp_update_tcp_rx_param(struct wlan_dp_psoc_context * dp_ctx,struct wlan_rx_tp_data * data)694 void wlan_dp_update_tcp_rx_param(struct wlan_dp_psoc_context *dp_ctx,
695 				 struct wlan_rx_tp_data *data)
696 {
697 	struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops;
698 
699 	if (!dp_ctx) {
700 		dp_err("psoc is null");
701 		return;
702 	}
703 
704 	if (!data) {
705 		dp_err("Data is null");
706 		return;
707 	}
708 
709 	if (dp_ctx->dp_cfg.enable_tcp_param_update)
710 		dp_ops->osif_dp_send_tcp_param_update_event(dp_ctx->psoc,
711 							    (union wlan_tp_data *)data,
712 							    1);
713 	else
714 		dp_ops->dp_send_svc_nlink_msg(cds_get_radio_index(),
715 					      WLAN_SVC_WLAN_TP_IND,
716 					      (void *)data,
717 					      sizeof(struct wlan_rx_tp_data));
718 }
719 
720 /**
721  * wlan_dp_update_tcp_tx_param() - update TCP param in Tx dir
722  * @dp_ctx: Pointer to DP context
723  * @data: Parameters to update
724  *
725  * Return: None
726  */
wlan_dp_update_tcp_tx_param(struct wlan_dp_psoc_context * dp_ctx,struct wlan_tx_tp_data * data)727 static void wlan_dp_update_tcp_tx_param(struct wlan_dp_psoc_context *dp_ctx,
728 					struct wlan_tx_tp_data *data)
729 {
730 	enum wlan_tp_level next_tx_level;
731 	struct wlan_tx_tp_data *tx_tp_data;
732 	struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops;
733 
734 	if (!dp_ctx) {
735 		dp_err("psoc is null");
736 		return;
737 	}
738 
739 	if (!data) {
740 		dp_err("Data is null");
741 		return;
742 	}
743 
744 	tx_tp_data = (struct wlan_tx_tp_data *)data;
745 	next_tx_level = tx_tp_data->level;
746 
747 	if (dp_ctx->dp_cfg.enable_tcp_param_update)
748 		dp_ops->osif_dp_send_tcp_param_update_event(dp_ctx->psoc,
749 							    (union wlan_tp_data *)data,
750 							    0);
751 	else
752 		dp_ops->dp_send_svc_nlink_msg(cds_get_radio_index(),
753 					      WLAN_SVC_WLAN_TP_TX_IND,
754 					      &next_tx_level,
755 					      sizeof(next_tx_level));
756 }
757 
758 /**
759  * dp_low_tput_gro_flush_skip_handler() - adjust GRO flush for low tput
760  * @dp_ctx: dp_ctx object
761  * @next_vote_level: next bus bandwidth level
762  * @legacy_client: legacy connection mode active
763  *
764  * If bus bandwidth level is PLD_BUS_WIDTH_LOW consistently and hit
765  * the bus_low_cnt_threshold, set flag to skip GRO flush.
766  * If bus bandwidth keeps going to PLD_BUS_WIDTH_IDLE, perform a GRO
767  * flush to avoid TCP traffic stall
768  *
769  * Return: none
770  */
dp_low_tput_gro_flush_skip_handler(struct wlan_dp_psoc_context * dp_ctx,enum pld_bus_width_type next_vote_level,bool legacy_client)771 static inline void dp_low_tput_gro_flush_skip_handler(
772 			struct wlan_dp_psoc_context *dp_ctx,
773 			enum pld_bus_width_type next_vote_level,
774 			bool legacy_client)
775 {
776 	uint32_t threshold = dp_ctx->dp_cfg.bus_low_cnt_threshold;
777 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
778 	int i;
779 
780 	if (next_vote_level == PLD_BUS_WIDTH_LOW && legacy_client) {
781 		if (++dp_ctx->bus_low_vote_cnt >= threshold)
782 			qdf_atomic_set(&dp_ctx->low_tput_gro_enable, 1);
783 	} else {
784 		if (qdf_atomic_read(&dp_ctx->low_tput_gro_enable) &&
785 		    dp_ctx->enable_dp_rx_threads) {
786 			/* flush pending rx pkts when LOW->IDLE */
787 			dp_info("flush queued GRO pkts");
788 			for (i = 0; i < cdp_get_num_rx_contexts(soc); i++) {
789 				dp_rx_gro_flush_ind(soc, i,
790 						    DP_RX_GRO_NORMAL_FLUSH);
791 			}
792 		}
793 
794 		dp_ctx->bus_low_vote_cnt = 0;
795 		qdf_atomic_set(&dp_ctx->low_tput_gro_enable, 0);
796 	}
797 }
798 
799 #ifdef WDI3_STATS_UPDATE
800 /**
801  * dp_ipa_set_perf_level() - set IPA perf level
802  * @dp_ctx: handle to dp context
803  * @tx_pkts: transmit packet count
804  * @rx_pkts: receive packet count
805  * @ipa_tx_pkts: IPA transmit packet count
806  * @ipa_rx_pkts: IPA receive packet count
807  *
808  * Return: none
809  */
810 static inline
dp_ipa_set_perf_level(struct wlan_dp_psoc_context * dp_ctx,uint64_t * tx_pkts,uint64_t * rx_pkts,uint32_t * ipa_tx_pkts,uint32_t * ipa_rx_pkts)811 void dp_ipa_set_perf_level(struct wlan_dp_psoc_context *dp_ctx,
812 			   uint64_t *tx_pkts, uint64_t *rx_pkts,
813 			   uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
814 {
815 }
816 #else
dp_ipa_set_perf_level(struct wlan_dp_psoc_context * dp_ctx,uint64_t * tx_pkts,uint64_t * rx_pkts,uint32_t * ipa_tx_pkts,uint32_t * ipa_rx_pkts)817 static void dp_ipa_set_perf_level(struct wlan_dp_psoc_context *dp_ctx,
818 				  uint64_t *tx_pkts, uint64_t *rx_pkts,
819 				  uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
820 {
821 	if (ucfg_ipa_is_fw_wdi_activated(dp_ctx->pdev)) {
822 		ucfg_ipa_uc_stat_query(dp_ctx->pdev, ipa_tx_pkts,
823 				       ipa_rx_pkts);
824 		*tx_pkts += *ipa_tx_pkts;
825 		*rx_pkts += *ipa_rx_pkts;
826 
827 		ucfg_ipa_set_perf_level(dp_ctx->pdev, *tx_pkts, *rx_pkts);
828 		ucfg_ipa_uc_stat_request(dp_ctx->pdev, 2);
829 	}
830 }
831 #endif /* WDI3_STATS_UPDATE */
832 
833 #ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE
834 /**
835  * dp_set_vdev_bundle_require_flag() - set vdev bundle require flag
836  * @vdev_id: vdev id
837  * @dp_ctx: handle to dp context
838  * @tx_bytes: Tx bytes
839  *
840  * Return: none
841  */
842 static inline
dp_set_vdev_bundle_require_flag(uint16_t vdev_id,struct wlan_dp_psoc_context * dp_ctx,uint64_t tx_bytes)843 void dp_set_vdev_bundle_require_flag(uint16_t vdev_id,
844 				     struct wlan_dp_psoc_context *dp_ctx,
845 				     uint64_t tx_bytes)
846 {
847 	struct wlan_dp_psoc_cfg *cfg = dp_ctx->dp_cfg;
848 
849 	cdp_vdev_set_bundle_require_flag(cds_get_context(QDF_MODULE_ID_SOC),
850 					 vdev_id, tx_bytes,
851 					 cfg->bus_bw_compute_interval,
852 					 cfg->pkt_bundle_threshold_high,
853 					 cfg->pkt_bundle_threshold_low);
854 }
855 #else
856 static inline
dp_set_vdev_bundle_require_flag(uint16_t vdev_id,struct wlan_dp_psoc_context * dp_ctx,uint64_t tx_bytes)857 void dp_set_vdev_bundle_require_flag(uint16_t vdev_id,
858 				     struct wlan_dp_psoc_context *dp_ctx,
859 				     uint64_t tx_bytes)
860 {
861 }
862 #endif /* WLAN_SUPPORT_TXRX_HL_BUNDLE */
863 
864 #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
865 /**
866  * dp_set_driver_del_ack_enable() - set driver delayed ack enabled flag
867  * @vdev_id: vdev id
868  * @dp_ctx: handle to dp context
869  * @rx_packets: receive packet count
870  *
871  * Return: none
872  */
873 static inline
dp_set_driver_del_ack_enable(uint16_t vdev_id,struct wlan_dp_psoc_context * dp_ctx,uint64_t rx_packets)874 void dp_set_driver_del_ack_enable(uint16_t vdev_id,
875 				  struct wlan_dp_psoc_context *dp_ctx,
876 				  uint64_t rx_packets)
877 {
878 	struct wlan_dp_psoc_cfg *cfg = dp_ctx->dp_cfg;
879 
880 	cdp_vdev_set_driver_del_ack_enable(cds_get_context(QDF_MODULE_ID_SOC),
881 					   vdev_id, rx_packets,
882 					   cfg->bus_bw_compute_interval,
883 					   cfg->del_ack_threshold_high,
884 					   cfg->del_ack_threshold_low);
885 }
886 #else
887 static inline
dp_set_driver_del_ack_enable(uint16_t vdev_id,struct wlan_dp_psoc_context * dp_ctx,uint64_t rx_packets)888 void dp_set_driver_del_ack_enable(uint16_t vdev_id,
889 				  struct wlan_dp_psoc_context *dp_ctx,
890 				  uint64_t rx_packets)
891 {
892 }
893 #endif /* QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK */
894 
895 #define DP_BW_GET_DIFF(_x, _y) ((unsigned long)((ULONG_MAX - (_y)) + (_x) + 1))
896 
897 #ifdef RX_PERFORMANCE
dp_is_current_high_throughput(struct wlan_dp_psoc_context * dp_ctx)898 bool dp_is_current_high_throughput(struct wlan_dp_psoc_context *dp_ctx)
899 {
900 	if (dp_ctx->cur_vote_level < PLD_BUS_WIDTH_MEDIUM)
901 		return false;
902 	else
903 		return true;
904 }
905 #endif /* RX_PERFORMANCE */
906 
907 /**
908  * wlan_dp_validate_context() - check the DP context
909  * @dp_ctx: Global DP context pointer
910  *
911  * Return: 0 if the context is valid. Error code otherwise
912  */
wlan_dp_validate_context(struct wlan_dp_psoc_context * dp_ctx)913 static int wlan_dp_validate_context(struct wlan_dp_psoc_context *dp_ctx)
914 {
915 	if (!dp_ctx) {
916 		dp_err("DP context is null");
917 		return -ENODEV;
918 	}
919 
920 	if (cds_is_driver_recovering()) {
921 		dp_info("Recovery in progress; state:0x%x",
922 			cds_get_driver_state());
923 		return -EAGAIN;
924 	}
925 
926 	if (cds_is_load_or_unload_in_progress()) {
927 		dp_info("Load/unload in progress; state:0x%x",
928 			cds_get_driver_state());
929 		return -EAGAIN;
930 	}
931 
932 	if (cds_is_driver_in_bad_state()) {
933 		dp_info("Driver in bad state; state:0x%x",
934 			cds_get_driver_state());
935 		return -EAGAIN;
936 	}
937 
938 	if (cds_is_fw_down()) {
939 		dp_info("FW is down; state:0x%x", cds_get_driver_state());
940 		return -EAGAIN;
941 	}
942 
943 	return 0;
944 }
945 
946 /**
947  * dp_tp_level_to_str() - Convert TPUT level to string
948  * @level: TPUT level
949  *
950  * Return: converted string
951  */
dp_tp_level_to_str(uint32_t level)952 static uint8_t *dp_tp_level_to_str(uint32_t level)
953 {
954 	switch (level) {
955 	/* initialize the wlan sub system */
956 	case WLAN_SVC_TP_NONE:
957 		return "NONE";
958 	case WLAN_SVC_TP_LOW:
959 		return "LOW";
960 	case WLAN_SVC_TP_MEDIUM:
961 		return "MED";
962 	case WLAN_SVC_TP_HIGH:
963 		return "HIGH";
964 	default:
965 		return "INVAL";
966 	}
967 }
968 
wlan_dp_display_tx_rx_histogram(struct wlan_objmgr_psoc * psoc)969 void wlan_dp_display_tx_rx_histogram(struct wlan_objmgr_psoc *psoc)
970 {
971 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
972 	int i;
973 
974 	if (!dp_ctx) {
975 		dp_err("Unable to get DP context");
976 		return;
977 	}
978 
979 	dp_nofl_info("BW compute Interval: %d ms",
980 		     dp_ctx->dp_cfg.bus_bw_compute_interval);
981 	dp_nofl_info("BW TH - Very High: %d Mid High: %d High: %d Med: %d Low: %d DBS: %d",
982 		     dp_ctx->dp_cfg.bus_bw_very_high_threshold,
983 		     dp_ctx->dp_cfg.bus_bw_mid_high_threshold,
984 		     dp_ctx->dp_cfg.bus_bw_high_threshold,
985 		     dp_ctx->dp_cfg.bus_bw_medium_threshold,
986 		     dp_ctx->dp_cfg.bus_bw_low_threshold,
987 		     dp_ctx->dp_cfg.bus_bw_dbs_threshold);
988 	dp_nofl_info("Enable TCP DEL ACK: %d",
989 		     dp_ctx->en_tcp_delack_no_lro);
990 	dp_nofl_info("TCP DEL High TH: %d TCP DEL Low TH: %d",
991 		     dp_ctx->dp_cfg.tcp_delack_thres_high,
992 		     dp_ctx->dp_cfg.tcp_delack_thres_low);
993 	dp_nofl_info("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_lim)",
994 		     dp_ctx->dp_cfg.tcp_tx_high_tput_thres);
995 
996 	dp_nofl_info("Total entries: %d Current index: %d",
997 		     NUM_TX_RX_HISTOGRAM, dp_ctx->txrx_hist_idx);
998 
999 	if (dp_ctx->txrx_hist) {
1000 		dp_nofl_info("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level, Rx:Tx pm_qos");
1001 
1002 		for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
1003 			struct tx_rx_histogram *hist;
1004 
1005 			/* using dp_log to avoid printing function name */
1006 			if (dp_ctx->txrx_hist[i].qtime <= 0)
1007 				continue;
1008 			hist = &dp_ctx->txrx_hist[i];
1009 			dp_nofl_info("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s, %s:%s",
1010 				     i, hist->qtime, hist->interval_rx,
1011 				     hist->interval_tx,
1012 				     pld_bus_width_type_to_str(hist->next_vote_level),
1013 				     dp_tp_level_to_str(hist->next_rx_level),
1014 				     dp_tp_level_to_str(hist->next_tx_level),
1015 				     hist->is_rx_pm_qos_high ? "HIGH" : "LOW",
1016 				     hist->is_tx_pm_qos_high ? "HIGH" : "LOW");
1017 		}
1018 	}
1019 }
1020 
wlan_dp_clear_tx_rx_histogram(struct wlan_objmgr_psoc * psoc)1021 void wlan_dp_clear_tx_rx_histogram(struct wlan_objmgr_psoc *psoc)
1022 {
1023 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
1024 
1025 	if (!dp_ctx) {
1026 		dp_err("Unable to get DP context");
1027 		return;
1028 	}
1029 
1030 	dp_ctx->txrx_hist_idx = 0;
1031 	if (dp_ctx->txrx_hist)
1032 		qdf_mem_zero(dp_ctx->txrx_hist,
1033 			     (sizeof(struct tx_rx_histogram) *
1034 			     NUM_TX_RX_HISTOGRAM));
1035 }
1036 
1037 /**
1038  * wlan_dp_init_tx_rx_histogram() - init tx/rx histogram stats
1039  * @dp_ctx: dp context
1040  *
1041  * Return: 0 for success or error code
1042  */
wlan_dp_init_tx_rx_histogram(struct wlan_dp_psoc_context * dp_ctx)1043 static int wlan_dp_init_tx_rx_histogram(struct wlan_dp_psoc_context *dp_ctx)
1044 {
1045 	dp_ctx->txrx_hist = qdf_mem_malloc(
1046 		(sizeof(struct tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
1047 	if (!dp_ctx->txrx_hist)
1048 		return -ENOMEM;
1049 
1050 	return 0;
1051 }
1052 
1053 /**
1054  * wlan_dp_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
1055  * @dp_ctx: dp context
1056  *
1057  * Return: none
1058  */
wlan_dp_deinit_tx_rx_histogram(struct wlan_dp_psoc_context * dp_ctx)1059 static void wlan_dp_deinit_tx_rx_histogram(struct wlan_dp_psoc_context *dp_ctx)
1060 {
1061 	if (!dp_ctx || !dp_ctx->txrx_hist)
1062 		return;
1063 
1064 	qdf_mem_free(dp_ctx->txrx_hist);
1065 	dp_ctx->txrx_hist = NULL;
1066 }
1067 
1068 /**
1069  * wlan_dp_display_txrx_stats() - Display tx/rx histogram stats
1070  * @dp_ctx: dp context
1071  *
1072  * Return: none
1073  */
wlan_dp_display_txrx_stats(struct wlan_dp_psoc_context * dp_ctx)1074 static void wlan_dp_display_txrx_stats(struct wlan_dp_psoc_context *dp_ctx)
1075 {
1076 	struct wlan_dp_intf *dp_intf = NULL, *next_dp_intf = NULL;
1077 	struct dp_tx_rx_stats *stats;
1078 	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
1079 	int i = 0;
1080 	uint32_t total_rx_pkt, total_rx_dropped,
1081 		 total_rx_delv, total_rx_refused;
1082 	uint32_t total_tx_pkt;
1083 	uint32_t total_tx_dropped;
1084 	uint32_t total_tx_orphaned;
1085 
1086 	dp_for_each_intf_held_safe(dp_ctx, dp_intf, next_dp_intf) {
1087 		total_rx_pkt = 0;
1088 		total_rx_dropped = 0;
1089 		total_rx_delv = 0;
1090 		total_rx_refused = 0;
1091 		total_tx_pkt = 0;
1092 		total_tx_dropped = 0;
1093 		total_tx_orphaned = 0;
1094 		stats = &dp_intf->dp_stats.tx_rx_stats;
1095 
1096 		if (!dp_intf->num_links)
1097 			continue;
1098 
1099 		dp_info("dp_intf: " QDF_MAC_ADDR_FMT,
1100 			QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes));
1101 		for (i = 0; i < NUM_CPUS; i++) {
1102 			total_rx_pkt += stats->per_cpu[i].rx_packets;
1103 			total_rx_dropped += stats->per_cpu[i].rx_dropped;
1104 			total_rx_delv += stats->per_cpu[i].rx_delivered;
1105 			total_rx_refused += stats->per_cpu[i].rx_refused;
1106 			total_tx_pkt += stats->per_cpu[i].tx_called;
1107 			total_tx_dropped += stats->per_cpu[i].tx_dropped;
1108 			total_tx_orphaned += stats->per_cpu[i].tx_orphaned;
1109 		}
1110 
1111 		for (i = 0; i < NUM_CPUS; i++) {
1112 			if (!stats->per_cpu[i].tx_called)
1113 				continue;
1114 
1115 			dp_info("Tx CPU[%d]: called %u, dropped %u, orphaned %u",
1116 				i, stats->per_cpu[i].tx_called,
1117 				stats->per_cpu[i].tx_dropped,
1118 				stats->per_cpu[i].tx_orphaned);
1119 		}
1120 
1121 		dp_info("TX - called %u, dropped %u orphan %u",
1122 			total_tx_pkt, total_tx_dropped,
1123 			total_tx_orphaned);
1124 
1125 		dp_ctx->dp_ops.wlan_dp_display_tx_multiq_stats(ctx,
1126 							       dp_intf->dev);
1127 
1128 		for (i = 0; i < NUM_CPUS; i++) {
1129 			if (stats->per_cpu[i].rx_packets == 0)
1130 				continue;
1131 			dp_info("Rx CPU[%d]: packets %u, dropped %u, delivered %u, refused %u",
1132 				i, stats->per_cpu[i].rx_packets,
1133 				stats->per_cpu[i].rx_dropped,
1134 				stats->per_cpu[i].rx_delivered,
1135 				stats->per_cpu[i].rx_refused);
1136 		}
1137 
1138 		dp_info("RX - packets %u, dropped %u, unsol_arp_mcast_drp %u, delivered %u, refused %u GRO - agg %u drop %u non-agg %u flush_skip %u low_tput_flush %u disabled(conc %u low-tput %u)",
1139 			total_rx_pkt, total_rx_dropped,
1140 			qdf_atomic_read(&stats->rx_usolict_arp_n_mcast_drp),
1141 			total_rx_delv,
1142 			total_rx_refused, stats->rx_aggregated,
1143 			stats->rx_gro_dropped, stats->rx_non_aggregated,
1144 			stats->rx_gro_flush_skip,
1145 			stats->rx_gro_low_tput_flush,
1146 			qdf_atomic_read(&dp_ctx->disable_rx_ol_in_concurrency),
1147 			qdf_atomic_read(&dp_ctx->disable_rx_ol_in_low_tput));
1148 	}
1149 }
1150 
1151 /**
1152  * dp_display_periodic_stats() - Function to display periodic stats
1153  * @dp_ctx: handle to dp context
1154  * @data_in_interval: true, if data detected in bw time interval
1155  *
1156  * The periodicity is determined by dp_ctx->dp_cfg->periodic_stats_disp_time.
1157  * Stats show up in wlan driver logs.
1158  *
1159  * Returns: None
1160  */
dp_display_periodic_stats(struct wlan_dp_psoc_context * dp_ctx,bool data_in_interval)1161 static void dp_display_periodic_stats(struct wlan_dp_psoc_context *dp_ctx,
1162 				      bool data_in_interval)
1163 {
1164 	static uint32_t counter;
1165 	static bool data_in_time_period;
1166 	ol_txrx_soc_handle soc;
1167 	uint32_t periodic_stats_disp_time = 0;
1168 	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
1169 
1170 	wlan_mlme_stats_get_periodic_display_time(dp_ctx->psoc,
1171 						  &periodic_stats_disp_time);
1172 	if (!periodic_stats_disp_time)
1173 		return;
1174 
1175 	soc = cds_get_context(QDF_MODULE_ID_SOC);
1176 	if (!soc)
1177 		return;
1178 
1179 	counter++;
1180 	if (data_in_interval)
1181 		data_in_time_period = data_in_interval;
1182 
1183 	if (counter * dp_ctx->dp_cfg.bus_bw_compute_interval >=
1184 		periodic_stats_disp_time * 1000) {
1185 		hif_rtpm_display_last_busy_hist(cds_get_context(QDF_MODULE_ID_HIF));
1186 		if (data_in_time_period) {
1187 			wlan_dp_display_txrx_stats(dp_ctx);
1188 			dp_txrx_ext_dump_stats(soc, CDP_DP_RX_THREAD_STATS);
1189 			cdp_display_stats(soc,
1190 					  CDP_RX_RING_STATS,
1191 					  QDF_STATS_VERBOSITY_LEVEL_LOW);
1192 			cdp_display_stats(soc,
1193 					  CDP_DP_NAPI_STATS,
1194 					  QDF_STATS_VERBOSITY_LEVEL_LOW);
1195 			cdp_display_stats(soc,
1196 					  CDP_TXRX_PATH_STATS,
1197 					  QDF_STATS_VERBOSITY_LEVEL_LOW);
1198 			cdp_display_stats(soc,
1199 					  CDP_DUMP_TX_FLOW_POOL_INFO,
1200 					  QDF_STATS_VERBOSITY_LEVEL_LOW);
1201 			cdp_display_stats(soc,
1202 					  CDP_DP_SWLM_STATS,
1203 					  QDF_STATS_VERBOSITY_LEVEL_LOW);
1204 			dp_ctx->dp_ops.wlan_dp_display_netif_queue_history
1205 				(ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
1206 			cdp_display_txrx_hw_info(soc);
1207 			qdf_dp_trace_dump_stats();
1208 		}
1209 		counter = 0;
1210 		data_in_time_period = false;
1211 	}
1212 }
1213 
1214 /**
1215  * dp_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting
1216  * @mask: return variable of cpumask for the TPUT
1217  * @enable_perf_cluster: Enable PERF cluster or not
1218  *
1219  * By default, the function sets CPU mask for silver cluster unless
1220  * enable_perf_cluster is set as true.
1221  *
1222  * Return: none
1223  */
dp_pm_qos_update_cpu_mask(qdf_cpu_mask * mask,bool enable_perf_cluster)1224 static inline void dp_pm_qos_update_cpu_mask(qdf_cpu_mask *mask,
1225 					     bool enable_perf_cluster)
1226 {
1227 	int package_id;
1228 	unsigned int cpus;
1229 	int perf_cpu_cluster = hif_get_perf_cluster_bitmap();
1230 	int little_cpu_cluster = BIT(CPU_CLUSTER_TYPE_LITTLE);
1231 
1232 	qdf_cpumask_clear(mask);
1233 	qdf_for_each_online_cpu(cpus) {
1234 		package_id = qdf_topology_physical_package_id(cpus);
1235 		if (package_id >= 0 &&
1236 		    (BIT(package_id) & little_cpu_cluster ||
1237 		     (enable_perf_cluster &&
1238 		      BIT(package_id) & perf_cpu_cluster))) {
1239 			qdf_cpumask_set_cpu(cpus, mask);
1240 		}
1241 	}
1242 }
1243 
1244 /**
1245  * dp_bus_bandwidth_work_tune_rx() - Function to tune for RX
1246  * @dp_ctx: handle to dp context
1247  * @rx_packets: receive packet count in last bus bandwidth interval
1248  * @diff_us: delta time since last invocation.
1249  * @next_rx_level: pointer to next_rx_level to be filled
1250  * @cpu_mask: pm_qos cpu_mask needed for RX, to be filled
1251  * @is_rx_pm_qos_high: pointer indicating if high qos is needed, to be filled
1252  *
1253  * The function tunes various aspects of driver based on a running average
1254  * of RX packets received in last bus bandwidth interval.
1255  *
1256  * Returns: true if RX level has changed, else return false
1257  */
1258 static
dp_bus_bandwidth_work_tune_rx(struct wlan_dp_psoc_context * dp_ctx,const uint64_t rx_packets,uint64_t diff_us,enum wlan_tp_level * next_rx_level,qdf_cpu_mask * cpu_mask,bool * is_rx_pm_qos_high)1259 bool dp_bus_bandwidth_work_tune_rx(struct wlan_dp_psoc_context *dp_ctx,
1260 				   const uint64_t rx_packets,
1261 				   uint64_t diff_us,
1262 				   enum wlan_tp_level *next_rx_level,
1263 				   qdf_cpu_mask *cpu_mask,
1264 				   bool *is_rx_pm_qos_high)
1265 {
1266 	bool rx_level_change = false;
1267 	bool rxthread_high_tput_req;
1268 	uint32_t bw_interval_us;
1269 	uint32_t delack_timer_cnt = dp_ctx->dp_cfg.tcp_delack_timer_count;
1270 	uint64_t avg_rx;
1271 	uint64_t no_rx_offload_pkts, avg_no_rx_offload_pkts;
1272 	uint64_t rx_offload_pkts, avg_rx_offload_pkts;
1273 
1274 	bw_interval_us = dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
1275 	no_rx_offload_pkts = dp_ctx->no_rx_offload_pkt_cnt;
1276 	dp_ctx->no_rx_offload_pkt_cnt = 0;
1277 
1278 	/* adjust for any sched delays */
1279 	no_rx_offload_pkts = no_rx_offload_pkts * bw_interval_us;
1280 	no_rx_offload_pkts = qdf_do_div(no_rx_offload_pkts, (uint32_t)diff_us);
1281 
1282 	/* average no-offload RX packets over last 2 BW intervals */
1283 	avg_no_rx_offload_pkts = (no_rx_offload_pkts +
1284 				  dp_ctx->prev_no_rx_offload_pkts) / 2;
1285 	dp_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
1286 
1287 	if (rx_packets >= no_rx_offload_pkts)
1288 		rx_offload_pkts = rx_packets - no_rx_offload_pkts;
1289 	else
1290 		rx_offload_pkts = 0;
1291 
1292 	/* average offloaded RX packets over last 2 BW intervals */
1293 	avg_rx_offload_pkts = (rx_offload_pkts +
1294 			       dp_ctx->prev_rx_offload_pkts) / 2;
1295 	dp_ctx->prev_rx_offload_pkts = rx_offload_pkts;
1296 
1297 	avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
1298 
1299 	qdf_cpumask_clear(cpu_mask);
1300 
1301 	if (avg_no_rx_offload_pkts > dp_ctx->dp_cfg.bus_bw_high_threshold) {
1302 		rxthread_high_tput_req = true;
1303 		*is_rx_pm_qos_high = true;
1304 		/*Todo: move hdd implementation to qdf */
1305 		dp_pm_qos_update_cpu_mask(cpu_mask, true);
1306 	} else if (avg_rx > dp_ctx->dp_cfg.bus_bw_high_threshold) {
1307 		rxthread_high_tput_req = false;
1308 		*is_rx_pm_qos_high = false;
1309 		dp_pm_qos_update_cpu_mask(cpu_mask, false);
1310 	} else {
1311 		*is_rx_pm_qos_high = false;
1312 		rxthread_high_tput_req = false;
1313 	}
1314 
1315 	/*
1316 	 * Takes care to set Rx_thread affinity for below case
1317 	 * 1)LRO/GRO not supported ROME case
1318 	 * 2)when rx_ol is disabled in cases like concurrency etc
1319 	 * 3)For UDP cases
1320 	 */
1321 	if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
1322 		dp_warn("Rx thread high_tput(%d) affinity request failed",
1323 			rxthread_high_tput_req);
1324 
1325 	/* fine-tuning parameters for RX Flows */
1326 	if (avg_rx > dp_ctx->dp_cfg.tcp_delack_thres_high) {
1327 		if (dp_ctx->cur_rx_level != WLAN_SVC_TP_HIGH &&
1328 		    ++dp_ctx->rx_high_ind_cnt == delack_timer_cnt) {
1329 			*next_rx_level = WLAN_SVC_TP_HIGH;
1330 		}
1331 	} else {
1332 		dp_ctx->rx_high_ind_cnt = 0;
1333 		*next_rx_level = WLAN_SVC_TP_LOW;
1334 	}
1335 
1336 	if (dp_ctx->cur_rx_level != *next_rx_level) {
1337 		struct wlan_rx_tp_data rx_tp_data = {0};
1338 
1339 		dp_ctx->cur_rx_level = *next_rx_level;
1340 		rx_level_change = true;
1341 		/* Send throughput indication only if it is enabled.
1342 		 * Disabling tcp_del_ack will revert the tcp stack behavior
1343 		 * to default delayed ack. Note that this will disable the
1344 		 * dynamic delayed ack mechanism across the system
1345 		 */
1346 		if (dp_ctx->en_tcp_delack_no_lro)
1347 			rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
1348 
1349 		if (dp_ctx->dp_cfg.enable_tcp_adv_win_scale)
1350 			rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
1351 
1352 		rx_tp_data.level = *next_rx_level;
1353 		wlan_dp_update_tcp_rx_param(dp_ctx, &rx_tp_data);
1354 	}
1355 
1356 	return rx_level_change;
1357 }
1358 
1359 /**
1360  * dp_bus_bandwidth_work_tune_tx() - Function to tune for TX
1361  * @dp_ctx: handle to dp context
1362  * @tx_packets: transmit packet count in last bus bandwidth interval
1363  * @diff_us: delta time since last invocation.
1364  * @next_tx_level: pointer to next_tx_level to be filled
1365  * @cpu_mask: pm_qos cpu_mask needed for TX, to be filled
1366  * @is_tx_pm_qos_high: pointer indicating if high qos is needed, to be filled
1367  *
1368  * The function tunes various aspects of the driver based on a running average
1369  * of TX packets received in last bus bandwidth interval.
1370  *
1371  * Returns: true if TX level has changed, else return false
1372  */
1373 static
dp_bus_bandwidth_work_tune_tx(struct wlan_dp_psoc_context * dp_ctx,const uint64_t tx_packets,uint64_t diff_us,enum wlan_tp_level * next_tx_level,qdf_cpu_mask * cpu_mask,bool * is_tx_pm_qos_high)1374 bool dp_bus_bandwidth_work_tune_tx(struct wlan_dp_psoc_context *dp_ctx,
1375 				   const uint64_t tx_packets,
1376 				   uint64_t diff_us,
1377 				   enum wlan_tp_level *next_tx_level,
1378 				   qdf_cpu_mask *cpu_mask,
1379 				   bool *is_tx_pm_qos_high)
1380 {
1381 	bool tx_level_change = false;
1382 	uint32_t bw_interval_us;
1383 	uint64_t no_tx_offload_pkts, avg_no_tx_offload_pkts;
1384 	uint64_t tx_offload_pkts, avg_tx_offload_pkts;
1385 	uint64_t avg_tx;
1386 
1387 	bw_interval_us = dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
1388 	no_tx_offload_pkts = dp_ctx->no_tx_offload_pkt_cnt;
1389 
1390 	/* adjust for any sched delays */
1391 	no_tx_offload_pkts = no_tx_offload_pkts * bw_interval_us;
1392 	no_tx_offload_pkts = qdf_do_div(no_tx_offload_pkts, (uint32_t)diff_us);
1393 
1394 	/* average no-offload TX packets over last 2 BW intervals */
1395 	avg_no_tx_offload_pkts = (no_tx_offload_pkts +
1396 				  dp_ctx->prev_no_tx_offload_pkts) / 2;
1397 	dp_ctx->no_tx_offload_pkt_cnt = 0;
1398 	dp_ctx->prev_no_tx_offload_pkts = no_tx_offload_pkts;
1399 
1400 	if (tx_packets >= no_tx_offload_pkts)
1401 		tx_offload_pkts = tx_packets - no_tx_offload_pkts;
1402 	else
1403 		tx_offload_pkts = 0;
1404 
1405 	/* average offloaded TX packets over last 2 BW intervals */
1406 	avg_tx_offload_pkts = (tx_offload_pkts +
1407 			       dp_ctx->prev_tx_offload_pkts) / 2;
1408 	dp_ctx->prev_tx_offload_pkts = tx_offload_pkts;
1409 
1410 	avg_tx = avg_no_tx_offload_pkts + avg_tx_offload_pkts;
1411 
1412 	/* fine-tuning parameters for TX Flows */
1413 	dp_ctx->prev_tx = tx_packets;
1414 
1415 	qdf_cpumask_clear(cpu_mask);
1416 
1417 	if (avg_no_tx_offload_pkts >
1418 		dp_ctx->dp_cfg.bus_bw_very_high_threshold) {
1419 		dp_pm_qos_update_cpu_mask(cpu_mask, true);
1420 		*is_tx_pm_qos_high = true;
1421 	} else if (avg_tx > dp_ctx->dp_cfg.bus_bw_high_threshold) {
1422 		dp_pm_qos_update_cpu_mask(cpu_mask, false);
1423 		*is_tx_pm_qos_high = false;
1424 	} else {
1425 		*is_tx_pm_qos_high = false;
1426 	}
1427 
1428 	if (avg_tx > dp_ctx->dp_cfg.tcp_tx_high_tput_thres)
1429 		*next_tx_level = WLAN_SVC_TP_HIGH;
1430 	else
1431 		*next_tx_level = WLAN_SVC_TP_LOW;
1432 
1433 	if (dp_ctx->dp_cfg.enable_tcp_limit_output &&
1434 	    dp_ctx->cur_tx_level != *next_tx_level) {
1435 		struct wlan_tx_tp_data tx_tp_data = {0};
1436 
1437 		dp_ctx->cur_tx_level = *next_tx_level;
1438 		tx_level_change = true;
1439 		tx_tp_data.level = *next_tx_level;
1440 		tx_tp_data.tcp_limit_output = true;
1441 		wlan_dp_update_tcp_tx_param(dp_ctx, &tx_tp_data);
1442 	}
1443 
1444 	return tx_level_change;
1445 }
1446 
1447 /**
1448  * dp_sap_p2p_update_mid_high_tput() - Update mid high BW for SAP and P2P mode
1449  * @dp_ctx: DP context
1450  * @total_pkts: Total Tx and Rx packets
1451  *
1452  * Return: True if mid high threshold is set and opmode is SAP or P2P GO
1453  */
1454 static inline
dp_sap_p2p_update_mid_high_tput(struct wlan_dp_psoc_context * dp_ctx,uint64_t total_pkts)1455 bool dp_sap_p2p_update_mid_high_tput(struct wlan_dp_psoc_context *dp_ctx,
1456 				     uint64_t total_pkts)
1457 {
1458 	struct wlan_dp_intf *dp_intf = NULL;
1459 	struct wlan_dp_intf *dp_intf_next = NULL;
1460 
1461 	if (dp_ctx->dp_cfg.bus_bw_mid_high_threshold &&
1462 	    total_pkts > dp_ctx->dp_cfg.bus_bw_mid_high_threshold) {
1463 		dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
1464 			if (dp_intf->device_mode == QDF_SAP_MODE ||
1465 			    dp_intf->device_mode == QDF_P2P_GO_MODE)
1466 				return true;
1467 		}
1468 	}
1469 
1470 	return false;
1471 }
1472 
1473 /**
1474  * dp_pld_request_bus_bandwidth() - Function to control bus bandwidth
1475  * @dp_ctx: handle to DP context
1476  * @tx_packets: transmit packet count received in BW interval
1477  * @rx_packets: receive packet count received in BW interval
1478  * @diff_us: delta time since last invocation.
1479  *
1480  * The function controls the bus bandwidth and dynamic control of
1481  * tcp delayed ack configuration.
1482  *
1483  * Returns: None
1484  */
dp_pld_request_bus_bandwidth(struct wlan_dp_psoc_context * dp_ctx,const uint64_t tx_packets,const uint64_t rx_packets,const uint64_t diff_us)1485 static void dp_pld_request_bus_bandwidth(struct wlan_dp_psoc_context *dp_ctx,
1486 					 const uint64_t tx_packets,
1487 					 const uint64_t rx_packets,
1488 					 const uint64_t diff_us)
1489 {
1490 	uint16_t index;
1491 	bool vote_level_change = false;
1492 	bool rx_level_change;
1493 	bool tx_level_change;
1494 	bool dptrace_high_tput_req;
1495 	u64 total_pkts = tx_packets + rx_packets;
1496 	enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_IDLE;
1497 	static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
1498 	enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
1499 	qdf_cpu_mask pm_qos_cpu_mask_tx, pm_qos_cpu_mask_rx, pm_qos_cpu_mask;
1500 	bool is_rx_pm_qos_high;
1501 	bool is_tx_pm_qos_high;
1502 	bool pmqos_on_low_tput = false;
1503 	enum tput_level tput_level;
1504 	bool is_tput_level_high;
1505 	struct bbm_params param = {0};
1506 	bool legacy_client = false;
1507 	void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
1508 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
1509 	static enum tput_level prev_tput_level = TPUT_LEVEL_NONE;
1510 	struct wlan_dp_psoc_callbacks *dp_ops = &dp_ctx->dp_ops;
1511 	hdd_cb_handle ctx = dp_ops->callback_ctx;
1512 
1513 	if (!soc)
1514 		return;
1515 
1516 	if (dp_ctx->high_bus_bw_request) {
1517 		next_vote_level = PLD_BUS_WIDTH_VERY_HIGH;
1518 		tput_level = TPUT_LEVEL_VERY_HIGH;
1519 	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_super_high_threshold) {
1520 		next_vote_level = PLD_BUS_WIDTH_MAX;
1521 		tput_level = TPUT_LEVEL_SUPER_HIGH;
1522 	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_ultra_high_threshold) {
1523 		next_vote_level = PLD_BUS_WIDTH_ULTRA_HIGH;
1524 		tput_level = TPUT_LEVEL_ULTRA_HIGH;
1525 	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_very_high_threshold) {
1526 		next_vote_level = PLD_BUS_WIDTH_VERY_HIGH;
1527 		tput_level = TPUT_LEVEL_VERY_HIGH;
1528 	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_high_threshold) {
1529 		next_vote_level = PLD_BUS_WIDTH_HIGH;
1530 		tput_level = TPUT_LEVEL_HIGH;
1531 		if (dp_sap_p2p_update_mid_high_tput(dp_ctx, total_pkts)) {
1532 			next_vote_level = PLD_BUS_WIDTH_MID_HIGH;
1533 			tput_level = TPUT_LEVEL_MID_HIGH;
1534 		}
1535 	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_medium_threshold) {
1536 		next_vote_level = PLD_BUS_WIDTH_MEDIUM;
1537 		tput_level = TPUT_LEVEL_MEDIUM;
1538 	} else if (total_pkts > dp_ctx->dp_cfg.bus_bw_low_threshold) {
1539 		next_vote_level = PLD_BUS_WIDTH_LOW;
1540 		tput_level = TPUT_LEVEL_LOW;
1541 	} else {
1542 		next_vote_level = PLD_BUS_WIDTH_IDLE;
1543 		tput_level = TPUT_LEVEL_IDLE;
1544 	}
1545 
1546 	/*
1547 	 * DBS mode requires more DDR/SNOC resources, vote to ultra high
1548 	 * only when TPUT can reach VHT80 KPI and IPA is disabled,
1549 	 * for other cases, follow general voting logic
1550 	 */
1551 	if (!ucfg_ipa_is_fw_wdi_activated(dp_ctx->pdev) &&
1552 	    policy_mgr_is_current_hwmode_dbs(dp_ctx->psoc) &&
1553 	    (total_pkts > dp_ctx->dp_cfg.bus_bw_dbs_threshold) &&
1554 	    (tput_level < TPUT_LEVEL_SUPER_HIGH)) {
1555 		next_vote_level = PLD_BUS_WIDTH_ULTRA_HIGH;
1556 		tput_level = TPUT_LEVEL_ULTRA_HIGH;
1557 	}
1558 
1559 	param.policy = BBM_TPUT_POLICY;
1560 	param.policy_info.tput_level = tput_level;
1561 	dp_bbm_apply_independent_policy(dp_ctx->psoc, &param);
1562 
1563 	dp_rtpm_tput_policy_apply(dp_ctx, tput_level);
1564 
1565 	dptrace_high_tput_req =
1566 			next_vote_level > PLD_BUS_WIDTH_IDLE ? true : false;
1567 
1568 	if (qdf_atomic_read(&dp_ctx->num_latency_critical_clients))
1569 		legacy_client = true;
1570 
1571 	dp_low_tput_gro_flush_skip_handler(dp_ctx, next_vote_level,
1572 					   legacy_client);
1573 
1574 	if (dp_ctx->cur_vote_level != next_vote_level) {
1575 		/* Set affinity for tx completion grp interrupts */
1576 		if (tput_level >= TPUT_LEVEL_VERY_HIGH &&
1577 		    prev_tput_level < TPUT_LEVEL_VERY_HIGH)
1578 			hif_set_grp_intr_affinity(hif_ctx,
1579 				cdp_get_tx_rings_grp_bitmap(soc), true);
1580 		else if (tput_level < TPUT_LEVEL_VERY_HIGH &&
1581 			 prev_tput_level >= TPUT_LEVEL_VERY_HIGH)
1582 			hif_set_grp_intr_affinity(hif_ctx,
1583 				cdp_get_tx_rings_grp_bitmap(soc),
1584 				false);
1585 
1586 		prev_tput_level = tput_level;
1587 		dp_ctx->cur_vote_level = next_vote_level;
1588 		vote_level_change = true;
1589 
1590 		if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
1591 		    (next_vote_level == PLD_BUS_WIDTH_IDLE)) {
1592 			dp_ops->dp_pld_remove_pm_qos(ctx);
1593 			if (dp_ctx->dynamic_rps)
1594 				dp_clear_rps_cpu_mask(dp_ctx);
1595 		} else {
1596 			dp_ops->dp_pld_request_pm_qos(ctx);
1597 			if (dp_ctx->dynamic_rps)
1598 				/*Todo : check once hdd_set_rps_cpu_mask */
1599 				dp_set_rps_cpu_mask(dp_ctx);
1600 		}
1601 
1602 		if (dp_ctx->dp_cfg.rx_thread_ul_affinity_mask) {
1603 			if (next_vote_level == PLD_BUS_WIDTH_HIGH &&
1604 			    tx_packets >
1605 			    dp_ctx->dp_cfg.bus_bw_high_threshold &&
1606 			    rx_packets >
1607 			    dp_ctx->dp_cfg.bus_bw_low_threshold)
1608 				cds_sched_handle_rx_thread_affinity_req(true);
1609 			else if (next_vote_level != PLD_BUS_WIDTH_HIGH)
1610 				cds_sched_handle_rx_thread_affinity_req(false);
1611 		}
1612 
1613 		dp_ops->dp_napi_apply_throughput_policy(ctx,
1614 							tx_packets,
1615 							rx_packets);
1616 
1617 		if (rx_packets < dp_ctx->dp_cfg.bus_bw_low_threshold)
1618 			dp_disable_rx_ol_for_low_tput(dp_ctx, true);
1619 		else
1620 			dp_disable_rx_ol_for_low_tput(dp_ctx, false);
1621 
1622 		/*
1623 		 * force disable pktlog and only re-enable based
1624 		 * on ini config
1625 		 */
1626 		if (next_vote_level >= PLD_BUS_WIDTH_HIGH)
1627 			dp_ops->dp_pktlog_enable_disable(ctx,
1628 							 false, 0, 0);
1629 		else if (cds_is_packet_log_enabled())
1630 			dp_ops->dp_pktlog_enable_disable(ctx,
1631 							 true, 0, 0);
1632 	}
1633 
1634 	qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
1635 
1636 	rx_level_change = dp_bus_bandwidth_work_tune_rx(dp_ctx,
1637 							rx_packets,
1638 							diff_us,
1639 							&next_rx_level,
1640 							&pm_qos_cpu_mask_rx,
1641 							&is_rx_pm_qos_high);
1642 
1643 	tx_level_change = dp_bus_bandwidth_work_tune_tx(dp_ctx,
1644 							tx_packets,
1645 							diff_us,
1646 							&next_tx_level,
1647 							&pm_qos_cpu_mask_tx,
1648 							&is_tx_pm_qos_high);
1649 
1650 	index = dp_ctx->txrx_hist_idx;
1651 
1652 	if (vote_level_change) {
1653 		/* Clear mask if BW is not HIGH or more */
1654 		if (next_vote_level < PLD_BUS_WIDTH_HIGH) {
1655 			is_rx_pm_qos_high = false;
1656 			is_tx_pm_qos_high = false;
1657 			qdf_cpumask_clear(&pm_qos_cpu_mask);
1658 			if (next_vote_level == PLD_BUS_WIDTH_LOW &&
1659 			    rx_packets > tx_packets &&
1660 			    !legacy_client) {
1661 				pmqos_on_low_tput = true;
1662 				dp_pm_qos_update_cpu_mask(&pm_qos_cpu_mask,
1663 							  false);
1664 			}
1665 		} else {
1666 			qdf_cpumask_clear(&pm_qos_cpu_mask);
1667 			qdf_cpumask_or(&pm_qos_cpu_mask,
1668 				       &pm_qos_cpu_mask_tx,
1669 				       &pm_qos_cpu_mask_rx);
1670 
1671 			/* Default mask in case throughput is high */
1672 			if (qdf_cpumask_empty(&pm_qos_cpu_mask))
1673 				dp_pm_qos_update_cpu_mask(&pm_qos_cpu_mask,
1674 							  false);
1675 		}
1676 		dp_ops->dp_pm_qos_update_request(ctx, &pm_qos_cpu_mask);
1677 		is_tput_level_high =
1678 			tput_level >= TPUT_LEVEL_HIGH ? true : false;
1679 		cdp_set_bus_vote_lvl_high(soc, is_tput_level_high);
1680 	}
1681 
1682 	if (vote_level_change || tx_level_change || rx_level_change) {
1683 		dp_info("tx:%llu[%llu(off)+%llu(no-off)] rx:%llu[%llu(off)+%llu(no-off)] next_level(vote %u rx %u tx %u rtpm %d) pm_qos(rx:%u,%*pb tx:%u,%*pb on_low_tput:%u)",
1684 			tx_packets,
1685 			dp_ctx->prev_tx_offload_pkts,
1686 			dp_ctx->prev_no_tx_offload_pkts,
1687 			rx_packets,
1688 			dp_ctx->prev_rx_offload_pkts,
1689 			dp_ctx->prev_no_rx_offload_pkts,
1690 			next_vote_level, next_rx_level, next_tx_level,
1691 			dp_rtpm_tput_policy_get_vote(dp_ctx),
1692 			is_rx_pm_qos_high,
1693 			qdf_cpumask_pr_args(&pm_qos_cpu_mask_rx),
1694 			is_tx_pm_qos_high,
1695 			qdf_cpumask_pr_args(&pm_qos_cpu_mask_tx),
1696 			pmqos_on_low_tput);
1697 
1698 		if (dp_ctx->txrx_hist) {
1699 			dp_ctx->txrx_hist[index].next_tx_level = next_tx_level;
1700 			dp_ctx->txrx_hist[index].next_rx_level = next_rx_level;
1701 			dp_ctx->txrx_hist[index].is_rx_pm_qos_high =
1702 				is_rx_pm_qos_high;
1703 			dp_ctx->txrx_hist[index].is_tx_pm_qos_high =
1704 				is_tx_pm_qos_high;
1705 			dp_ctx->txrx_hist[index].next_vote_level =
1706 				next_vote_level;
1707 			dp_ctx->txrx_hist[index].interval_rx = rx_packets;
1708 			dp_ctx->txrx_hist[index].interval_tx = tx_packets;
1709 			dp_ctx->txrx_hist[index].qtime =
1710 				qdf_get_log_timestamp();
1711 			dp_ctx->txrx_hist_idx++;
1712 			dp_ctx->txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
1713 		}
1714 	}
1715 
1716 	/* Roaming is a high priority job but gets processed in scheduler
1717 	 * thread, bypassing printing stats so that kworker exits quickly and
1718 	 * scheduler thread can utilize CPU.
1719 	 */
1720 	if (!dp_ops->dp_is_roaming_in_progress(ctx)) {
1721 		dp_display_periodic_stats(dp_ctx, (total_pkts > 0) ?
1722 					  true : false);
1723 		dp_periodic_sta_stats_display(dp_ctx);
1724 	}
1725 
1726 	hif_affinity_mgr_set_affinity(hif_ctx);
1727 }
1728 
1729 #ifdef WLAN_FEATURE_DYNAMIC_RX_AGGREGATION
1730 /**
1731  * dp_rx_check_qdisc_for_intf() - Check if any ingress qdisc is configured
1732  *  for given adapter
1733  * @dp_intf: pointer to DP interface context
1734  *
1735  * The function checks if ingress qdisc is registered for a given
1736  * net device.
1737  *
1738  * Return: None
1739  */
1740 static void
dp_rx_check_qdisc_for_intf(struct wlan_dp_intf * dp_intf)1741 dp_rx_check_qdisc_for_intf(struct wlan_dp_intf *dp_intf)
1742 {
1743 	struct wlan_dp_psoc_callbacks *dp_ops;
1744 	QDF_STATUS status;
1745 
1746 	dp_ops = &dp_intf->dp_ctx->dp_ops;
1747 	status = dp_ops->dp_rx_check_qdisc_configured(dp_intf->dev,
1748 				 dp_intf->dp_ctx->dp_agg_param.tc_ingress_prio);
1749 	if (QDF_IS_STATUS_SUCCESS(status)) {
1750 		if (qdf_likely(qdf_atomic_read(&dp_intf->gro_disallowed)))
1751 			return;
1752 
1753 		dp_debug("ingress qdisc/filter configured disable GRO");
1754 		qdf_atomic_set(&dp_intf->gro_disallowed, 1);
1755 
1756 		return;
1757 	} else if (status == QDF_STATUS_E_NOSUPPORT) {
1758 		if (qdf_unlikely(qdf_atomic_read(&dp_intf->gro_disallowed))) {
1759 			dp_debug("ingress qdisc/filter removed enable GRO");
1760 			qdf_atomic_set(&dp_intf->gro_disallowed, 0);
1761 		}
1762 	}
1763 }
1764 #else
1765 static void
dp_rx_check_qdisc_for_intf(struct wlan_dp_intf * dp_intf)1766 dp_rx_check_qdisc_for_intf(struct wlan_dp_intf *dp_intf)
1767 {
1768 }
1769 #endif
1770 
1771 #define NO_RX_PKT_LINK_SPEED_AGEOUT_COUNT 50
1772 static void
dp_link_monitoring(struct wlan_dp_psoc_context * dp_ctx,struct wlan_dp_intf * dp_intf)1773 dp_link_monitoring(struct wlan_dp_psoc_context *dp_ctx,
1774 		   struct wlan_dp_intf *dp_intf)
1775 {
1776 	struct cdp_peer_stats *peer_stats;
1777 	QDF_STATUS status;
1778 	ol_txrx_soc_handle soc;
1779 	struct wlan_objmgr_peer *bss_peer;
1780 	static uint32_t no_rx_times;
1781 	uint64_t  rx_packets;
1782 	uint32_t link_speed;
1783 	struct wlan_objmgr_psoc *psoc;
1784 	struct link_monitoring link_mon;
1785 	struct wlan_dp_link *def_link = dp_intf->def_link;
1786 
1787 	/*
1788 	 *  If throughput is high, link speed should be good,  don't check it
1789 	 *  to avoid performance penalty
1790 	 */
1791 	soc = cds_get_context(QDF_MODULE_ID_SOC);
1792 	if (cdp_get_bus_lvl_high(soc) == true)
1793 		return;
1794 
1795 	link_mon = dp_intf->link_monitoring;
1796 	if (!dp_ctx->dp_ops.link_monitoring_cb)
1797 		return;
1798 
1799 	psoc = dp_ctx->psoc;
1800 	/* If no rx packets received for N sec, set link speed to poor */
1801 	if (link_mon.is_rx_linkspeed_good) {
1802 		rx_packets = DP_BW_GET_DIFF(
1803 			qdf_net_stats_get_rx_pkts(&dp_intf->stats),
1804 			dp_intf->prev_rx_packets);
1805 		if (!rx_packets)
1806 			no_rx_times++;
1807 		else
1808 			no_rx_times = 0;
1809 		if (no_rx_times >= NO_RX_PKT_LINK_SPEED_AGEOUT_COUNT) {
1810 			no_rx_times = 0;
1811 			dp_ctx->dp_ops.link_monitoring_cb(psoc,
1812 							  def_link->link_id,
1813 							  false);
1814 			dp_intf->link_monitoring.is_rx_linkspeed_good = false;
1815 
1816 			return;
1817 		}
1818 	}
1819 	/* Get rx link speed from dp peer */
1820 	peer_stats = qdf_mem_malloc(sizeof(*peer_stats));
1821 	if (!peer_stats)
1822 		return;
1823 
1824 	/* TODO - Temp WAR, check what to do here */
1825 	/* Peer stats for any link peer is going to return the
1826 	 * stats from MLD peer, so its okay to query deflink
1827 	 */
1828 	bss_peer = wlan_vdev_get_bsspeer(def_link->vdev);
1829 	if (!bss_peer) {
1830 		dp_debug("Invalid bss peer");
1831 		qdf_mem_free(peer_stats);
1832 		return;
1833 	}
1834 
1835 	status = cdp_host_get_peer_stats(soc, def_link->link_id,
1836 					 bss_peer->macaddr,
1837 					 peer_stats);
1838 	if (QDF_IS_STATUS_ERROR(status)) {
1839 		qdf_mem_free(peer_stats);
1840 		return;
1841 	}
1842 	/* Convert rx linkspeed from kbps to mbps to compare with threshold */
1843 	link_speed = peer_stats->rx.last_rx_rate / 1000;
1844 
1845 	/*
1846 	 * When found current rx link speed becomes good(above threshold) or
1847 	 * poor, update to firmware.
1848 	 * If the current RX link speed is above the threshold, low rssi
1849 	 * roaming is not needed. If linkspeed_threshold is set to 0, the
1850 	 * firmware will not consider RX link speed in the roaming decision,
1851 	 * driver will send rx link speed poor state to firmware.
1852 	 */
1853 	if (!link_mon.rx_linkspeed_threshold) {
1854 		dp_ctx->dp_ops.link_monitoring_cb(psoc, def_link->link_id,
1855 						  false);
1856 		dp_intf->link_monitoring.is_rx_linkspeed_good = false;
1857 	} else if (link_speed > link_mon.rx_linkspeed_threshold &&
1858 	     !link_mon.is_rx_linkspeed_good) {
1859 		dp_ctx->dp_ops.link_monitoring_cb(psoc, def_link->link_id,
1860 						  true);
1861 		dp_intf->link_monitoring.is_rx_linkspeed_good = true;
1862 	} else if (link_speed < link_mon.rx_linkspeed_threshold &&
1863 		   link_mon.is_rx_linkspeed_good) {
1864 		dp_ctx->dp_ops.link_monitoring_cb(psoc, def_link->link_id,
1865 						  false);
1866 		dp_intf->link_monitoring.is_rx_linkspeed_good = false;
1867 	}
1868 
1869 	qdf_mem_free(peer_stats);
1870 }
1871 
1872 /**
1873  * __dp_bus_bw_work_handler() - Bus bandwidth work handler
1874  * @dp_ctx: handle to DP context
1875  *
1876  * The function handles the bus bandwidth work schedule
1877  *
1878  * Returns: None
1879  */
__dp_bus_bw_work_handler(struct wlan_dp_psoc_context * dp_ctx)1880 static void __dp_bus_bw_work_handler(struct wlan_dp_psoc_context *dp_ctx)
1881 {
1882 	struct wlan_objmgr_vdev *vdev;
1883 	struct wlan_dp_intf *dp_intf = NULL, *con_sap_dp_intf = NULL;
1884 	struct wlan_dp_intf *dp_intf_next = NULL;
1885 	struct wlan_dp_link *dp_link = NULL;
1886 	struct wlan_dp_link *dp_link_next;
1887 	uint64_t tx_packets = 0, rx_packets = 0, tx_bytes = 0;
1888 	uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
1889 	uint64_t fwd_tx_packets_temp = 0, fwd_rx_packets_temp = 0;
1890 	uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
1891 	uint64_t total_tx = 0, total_rx = 0;
1892 	A_STATUS ret;
1893 	bool connected = false;
1894 	uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
1895 	uint64_t sta_tx_bytes = 0, sap_tx_bytes = 0;
1896 	uint64_t diff_us;
1897 	uint64_t curr_time_us;
1898 	uint32_t bw_interval_us;
1899 	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
1900 
1901 	if (wlan_dp_validate_context(dp_ctx))
1902 		goto stop_work;
1903 
1904 	if (dp_ctx->is_suspend)
1905 		return;
1906 
1907 	bw_interval_us = dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
1908 
1909 	curr_time_us = qdf_get_log_timestamp();
1910 	diff_us = qdf_log_timestamp_to_usecs(
1911 			curr_time_us - dp_ctx->bw_vote_time);
1912 	dp_ctx->bw_vote_time = curr_time_us;
1913 
1914 	dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) {
1915 		vdev = dp_objmgr_get_vdev_by_user(dp_intf->def_link,
1916 						  WLAN_DP_ID);
1917 		if (!vdev)
1918 			continue;
1919 
1920 		if ((dp_intf->device_mode == QDF_STA_MODE ||
1921 		     dp_intf->device_mode == QDF_P2P_CLIENT_MODE) &&
1922 		    !wlan_cm_is_vdev_active(vdev)) {
1923 			dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
1924 			continue;
1925 		}
1926 
1927 		if ((dp_intf->device_mode == QDF_SAP_MODE ||
1928 		     dp_intf->device_mode == QDF_P2P_GO_MODE) &&
1929 		     !dp_ctx->dp_ops.dp_is_ap_active(ctx,
1930 						     dp_intf->dev)) {
1931 			dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
1932 			continue;
1933 		}
1934 
1935 		if (dp_ctx->dp_agg_param.tc_based_dyn_gro)
1936 			dp_rx_check_qdisc_for_intf(dp_intf);
1937 
1938 		tx_packets += DP_BW_GET_DIFF(
1939 			qdf_net_stats_get_tx_pkts(&dp_intf->stats),
1940 			dp_intf->prev_tx_packets);
1941 		rx_packets += DP_BW_GET_DIFF(
1942 			qdf_net_stats_get_rx_pkts(&dp_intf->stats),
1943 			dp_intf->prev_rx_packets);
1944 		tx_bytes = DP_BW_GET_DIFF(
1945 			qdf_net_stats_get_tx_bytes(&dp_intf->stats),
1946 			dp_intf->prev_tx_bytes);
1947 
1948 		if (dp_intf->device_mode == QDF_STA_MODE &&
1949 		    wlan_cm_is_vdev_active(vdev)) {
1950 			dp_ctx->dp_ops.dp_send_mscs_action_frame(ctx,
1951 							dp_intf->dev);
1952 			if (dp_intf->link_monitoring.enabled)
1953 				dp_link_monitoring(dp_ctx, dp_intf);
1954 		}
1955 
1956 		ret = A_ERROR;
1957 		fwd_tx_packets = 0;
1958 		fwd_rx_packets = 0;
1959 		if (dp_intf->device_mode == QDF_SAP_MODE ||
1960 		    dp_intf->device_mode == QDF_P2P_GO_MODE ||
1961 		    dp_intf->device_mode == QDF_NDI_MODE) {
1962 			dp_for_each_link_held_safe(dp_intf, dp_link,
1963 						   dp_link_next) {
1964 				ret = cdp_get_intra_bss_fwd_pkts_count(
1965 					cds_get_context(QDF_MODULE_ID_SOC),
1966 					dp_link->link_id,
1967 					&fwd_tx_packets_temp,
1968 					&fwd_rx_packets_temp);
1969 				if (ret == A_OK) {
1970 					fwd_tx_packets += fwd_tx_packets_temp;
1971 					fwd_rx_packets += fwd_rx_packets_temp;
1972 				} else {
1973 					break;
1974 				}
1975 			}
1976 		}
1977 
1978 		if (ret == A_OK) {
1979 			fwd_tx_packets_diff += DP_BW_GET_DIFF(
1980 				fwd_tx_packets,
1981 				dp_intf->prev_fwd_tx_packets);
1982 			fwd_rx_packets_diff += DP_BW_GET_DIFF(
1983 				fwd_rx_packets,
1984 				dp_intf->prev_fwd_rx_packets);
1985 		}
1986 
1987 		if (dp_intf->device_mode == QDF_SAP_MODE) {
1988 			con_sap_dp_intf = dp_intf;
1989 			sap_tx_bytes =
1990 				qdf_net_stats_get_tx_bytes(&dp_intf->stats);
1991 		}
1992 
1993 		if (dp_intf->device_mode == QDF_STA_MODE)
1994 			sta_tx_bytes =
1995 				qdf_net_stats_get_tx_bytes(&dp_intf->stats);
1996 
1997 		dp_for_each_link_held_safe(dp_intf, dp_link, dp_link_next) {
1998 			dp_set_driver_del_ack_enable(dp_link->link_id, dp_ctx,
1999 						     rx_packets);
2000 
2001 			dp_set_vdev_bundle_require_flag(dp_link->link_id,
2002 							dp_ctx, tx_bytes);
2003 		}
2004 
2005 		total_rx += qdf_net_stats_get_rx_pkts(&dp_intf->stats);
2006 		total_tx += qdf_net_stats_get_tx_pkts(&dp_intf->stats);
2007 
2008 		qdf_spin_lock_bh(&dp_ctx->bus_bw_lock);
2009 		dp_intf->prev_tx_packets =
2010 			qdf_net_stats_get_tx_pkts(&dp_intf->stats);
2011 		dp_intf->prev_rx_packets =
2012 			qdf_net_stats_get_rx_pkts(&dp_intf->stats);
2013 		dp_intf->prev_fwd_tx_packets = fwd_tx_packets;
2014 		dp_intf->prev_fwd_rx_packets = fwd_rx_packets;
2015 		dp_intf->prev_tx_bytes =
2016 			qdf_net_stats_get_tx_bytes(&dp_intf->stats);
2017 		qdf_spin_unlock_bh(&dp_ctx->bus_bw_lock);
2018 		connected = true;
2019 
2020 		dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
2021 	}
2022 
2023 	if (!connected) {
2024 		dp_err("bus bandwidth timer running in disconnected state");
2025 		goto stop_work;
2026 	}
2027 
2028 	/* add intra bss forwarded tx and rx packets */
2029 	tx_packets += fwd_tx_packets_diff;
2030 	rx_packets += fwd_rx_packets_diff;
2031 
2032 	/* Send embedded Tx packet bytes on STA & SAP interface to IPA driver */
2033 	ucfg_ipa_update_tx_stats(dp_ctx->pdev, sta_tx_bytes, sap_tx_bytes);
2034 
2035 	dp_ipa_set_perf_level(dp_ctx, &tx_packets, &rx_packets,
2036 			      &ipa_tx_packets, &ipa_rx_packets);
2037 	if (con_sap_dp_intf) {
2038 		qdf_net_stats_add_tx_pkts(&con_sap_dp_intf->stats,
2039 					  ipa_tx_packets);
2040 		qdf_net_stats_add_rx_pkts(&con_sap_dp_intf->stats,
2041 					  ipa_rx_packets);
2042 	}
2043 
2044 	tx_packets = tx_packets * bw_interval_us;
2045 	tx_packets = qdf_do_div(tx_packets, (uint32_t)diff_us);
2046 
2047 	rx_packets = rx_packets * bw_interval_us;
2048 	rx_packets = qdf_do_div(rx_packets, (uint32_t)diff_us);
2049 
2050 	dp_pld_request_bus_bandwidth(dp_ctx, tx_packets, rx_packets, diff_us);
2051 
2052 	return;
2053 
2054 stop_work:
2055 	qdf_periodic_work_stop_async(&dp_ctx->bus_bw_work);
2056 }
2057 
2058 /**
2059  * dp_bus_bw_work_handler() - Bus bandwidth work handler
2060  * @context: handle to DP context
2061  *
2062  * The function handles the bus bandwidth work schedule
2063  *
2064  * Returns: None
2065  */
dp_bus_bw_work_handler(void * context)2066 static void dp_bus_bw_work_handler(void *context)
2067 {
2068 	struct wlan_dp_psoc_context *dp_ctx = context;
2069 	struct qdf_op_sync *op_sync;
2070 
2071 	if (!dp_ctx) {
2072 		dp_err("Unable to get DP context");
2073 		return;
2074 	}
2075 
2076 	if (qdf_op_protect(&op_sync))
2077 		return;
2078 
2079 	__dp_bus_bw_work_handler(dp_ctx);
2080 
2081 	qdf_op_unprotect(op_sync);
2082 }
2083 
dp_bus_bandwidth_init(struct wlan_objmgr_psoc * psoc)2084 int dp_bus_bandwidth_init(struct wlan_objmgr_psoc *psoc)
2085 {
2086 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2087 	hdd_cb_handle ctx = dp_ctx->dp_ops.callback_ctx;
2088 	QDF_STATUS status;
2089 
2090 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
2091 		return QDF_STATUS_SUCCESS;
2092 
2093 	dp_enter();
2094 
2095 	qdf_spinlock_create(&dp_ctx->bus_bw_lock);
2096 
2097 	dp_ctx->dp_ops.dp_pm_qos_add_request(ctx);
2098 
2099 	wlan_dp_init_tx_rx_histogram(dp_ctx);
2100 	status = qdf_periodic_work_create(&dp_ctx->bus_bw_work,
2101 					  dp_bus_bw_work_handler,
2102 					  dp_ctx);
2103 
2104 	dp_exit();
2105 
2106 	return qdf_status_to_os_return(status);
2107 }
2108 
dp_bus_bandwidth_deinit(struct wlan_objmgr_psoc * psoc)2109 void dp_bus_bandwidth_deinit(struct wlan_objmgr_psoc *psoc)
2110 {
2111 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2112 	hdd_cb_handle ctx;
2113 
2114 	if (!dp_ctx) {
2115 		dp_err("Unable to get DP context");
2116 		return;
2117 	}
2118 
2119 	ctx = dp_ctx->dp_ops.callback_ctx;
2120 
2121 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
2122 		return;
2123 
2124 	dp_enter();
2125 
2126 	/* it is expecting the timer has been stopped or not started
2127 	 * when coming deinit.
2128 	 */
2129 	QDF_BUG(!qdf_periodic_work_stop_sync(&dp_ctx->bus_bw_work));
2130 
2131 	qdf_periodic_work_destroy(&dp_ctx->bus_bw_work);
2132 	qdf_spinlock_destroy(&dp_ctx->bus_bw_lock);
2133 	wlan_dp_deinit_tx_rx_histogram(dp_ctx);
2134 	dp_ctx->dp_ops.dp_pm_qos_remove_request(ctx);
2135 
2136 	dp_exit();
2137 }
2138 
2139 /**
2140  * __dp_bus_bw_compute_timer_start() - start the bus bandwidth timer
2141  * @psoc: psoc handle
2142  *
2143  * Return: None
2144  */
__dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc * psoc)2145 static void __dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc)
2146 {
2147 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2148 
2149 	if (!dp_ctx) {
2150 		dp_err("Unable to get DP context");
2151 		return;
2152 	}
2153 
2154 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
2155 		return;
2156 
2157 	qdf_periodic_work_start(&dp_ctx->bus_bw_work,
2158 				dp_ctx->dp_cfg.bus_bw_compute_interval);
2159 	dp_ctx->bw_vote_time = qdf_get_log_timestamp();
2160 }
2161 
dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc * psoc)2162 void dp_bus_bw_compute_timer_start(struct wlan_objmgr_psoc *psoc)
2163 {
2164 	dp_enter();
2165 
2166 	__dp_bus_bw_compute_timer_start(psoc);
2167 
2168 	dp_exit();
2169 }
2170 
dp_bus_bw_compute_timer_try_start(struct wlan_objmgr_psoc * psoc)2171 void dp_bus_bw_compute_timer_try_start(struct wlan_objmgr_psoc *psoc)
2172 {
2173 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2174 	hdd_cb_handle ctx;
2175 
2176 	dp_enter();
2177 
2178 	if (!dp_ctx) {
2179 		dp_err("Unable to get DP context");
2180 		return;
2181 	}
2182 
2183 	ctx = dp_ctx->dp_ops.callback_ctx;
2184 
2185 	if (dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
2186 		__dp_bus_bw_compute_timer_start(psoc);
2187 
2188 	dp_exit();
2189 }
2190 
2191 /**
2192  * __dp_bus_bw_compute_timer_stop() - stop the bus bandwidth timer
2193  * @psoc: psoc handle
2194  *
2195  * Return: None
2196  */
__dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc * psoc)2197 static void __dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc *psoc)
2198 {
2199 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2200 	hdd_cb_handle ctx;
2201 	ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
2202 
2203 	struct bbm_params param = {0};
2204 	bool is_any_adapter_conn;
2205 
2206 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
2207 		return;
2208 
2209 	if (!dp_ctx || !soc)
2210 		return;
2211 
2212 	ctx = dp_ctx->dp_ops.callback_ctx;
2213 	is_any_adapter_conn = dp_ctx->dp_ops.dp_any_adapter_connected(ctx);
2214 
2215 	if (!qdf_periodic_work_stop_sync(&dp_ctx->bus_bw_work))
2216 		goto exit;
2217 
2218 	ucfg_ipa_set_perf_level(dp_ctx->pdev, 0, 0);
2219 
2220 	dp_reset_tcp_delack(psoc);
2221 
2222 	if (!is_any_adapter_conn)
2223 		dp_reset_tcp_adv_win_scale(dp_ctx);
2224 
2225 	cdp_pdev_reset_driver_del_ack(cds_get_context(QDF_MODULE_ID_SOC),
2226 				      OL_TXRX_PDEV_ID);
2227 	cdp_pdev_reset_bundle_require_flag(cds_get_context(QDF_MODULE_ID_SOC),
2228 					   OL_TXRX_PDEV_ID);
2229 
2230 	cdp_set_bus_vote_lvl_high(soc, false);
2231 	dp_ctx->bw_vote_time = 0;
2232 
2233 exit:
2234 	/**
2235 	 * This check if for the case where the bus bw timer is forcibly
2236 	 * stopped. We should remove the bus bw voting, if no adapter is
2237 	 * connected
2238 	 */
2239 	if (!is_any_adapter_conn) {
2240 		uint64_t interval_us =
2241 			dp_ctx->dp_cfg.bus_bw_compute_interval * 1000;
2242 		qdf_atomic_set(&dp_ctx->num_latency_critical_clients, 0);
2243 		dp_pld_request_bus_bandwidth(dp_ctx, 0, 0, interval_us);
2244 	}
2245 	param.policy = BBM_TPUT_POLICY;
2246 	param.policy_info.tput_level = TPUT_LEVEL_NONE;
2247 	dp_bbm_apply_independent_policy(psoc, &param);
2248 }
2249 
dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc * psoc)2250 void dp_bus_bw_compute_timer_stop(struct wlan_objmgr_psoc *psoc)
2251 {
2252 	dp_enter();
2253 
2254 	__dp_bus_bw_compute_timer_stop(psoc);
2255 
2256 	dp_exit();
2257 }
2258 
dp_bus_bw_compute_timer_try_stop(struct wlan_objmgr_psoc * psoc)2259 void dp_bus_bw_compute_timer_try_stop(struct wlan_objmgr_psoc *psoc)
2260 {
2261 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2262 	hdd_cb_handle ctx;
2263 
2264 	dp_enter();
2265 
2266 	if (!dp_ctx) {
2267 		dp_err("Unable to get DP context");
2268 		return;
2269 	}
2270 
2271 	ctx = dp_ctx->dp_ops.callback_ctx;
2272 
2273 	if (!dp_ctx->dp_ops.dp_any_adapter_connected(ctx))
2274 		__dp_bus_bw_compute_timer_stop(psoc);
2275 
2276 	dp_exit();
2277 }
2278 
dp_bus_bw_compute_prev_txrx_stats(struct wlan_objmgr_vdev * vdev)2279 void dp_bus_bw_compute_prev_txrx_stats(struct wlan_objmgr_vdev *vdev)
2280 {
2281 	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
2282 	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
2283 	struct wlan_dp_intf *dp_intf;
2284 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2285 
2286 	if (!dp_link) {
2287 		dp_err("No dp_link for objmgr vdev %pK", vdev);
2288 		return;
2289 	}
2290 
2291 	dp_intf = dp_link->dp_intf;
2292 	if (!dp_intf) {
2293 		dp_err("Invalid dp_intf for dp_link %pK (" QDF_MAC_ADDR_FMT ")",
2294 		       dp_link, QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
2295 		return;
2296 	}
2297 
2298 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
2299 		return;
2300 
2301 	qdf_spin_lock_bh(&dp_ctx->bus_bw_lock);
2302 	dp_intf->prev_tx_packets = qdf_net_stats_get_tx_pkts(&dp_intf->stats);
2303 	dp_intf->prev_rx_packets = qdf_net_stats_get_rx_pkts(&dp_intf->stats);
2304 	dp_intf->prev_tx_bytes = qdf_net_stats_get_tx_bytes(&dp_intf->stats);
2305 
2306 	/*
2307 	 * TODO - Should the prev_fwd_tx_packets and
2308 	 * such stats be per link ??
2309 	 */
2310 	cdp_get_intra_bss_fwd_pkts_count(cds_get_context(QDF_MODULE_ID_SOC),
2311 					 dp_link->link_id,
2312 					 &dp_intf->prev_fwd_tx_packets,
2313 					 &dp_intf->prev_fwd_rx_packets);
2314 	qdf_spin_unlock_bh(&dp_ctx->bus_bw_lock);
2315 }
2316 
dp_bus_bw_compute_reset_prev_txrx_stats(struct wlan_objmgr_vdev * vdev)2317 void dp_bus_bw_compute_reset_prev_txrx_stats(struct wlan_objmgr_vdev *vdev)
2318 {
2319 	struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
2320 	struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev);
2321 	struct wlan_dp_intf *dp_intf;
2322 	struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc);
2323 
2324 	if (!dp_link) {
2325 		dp_err("No dp_link for objmgr vdev %pK", vdev);
2326 		return;
2327 	}
2328 
2329 	dp_intf = dp_link->dp_intf;
2330 	if (!dp_intf) {
2331 		dp_err("Invalid dp_intf for dp_link %pK (" QDF_MAC_ADDR_FMT ")",
2332 		       dp_link, QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes));
2333 		return;
2334 	}
2335 
2336 	if (QDF_GLOBAL_FTM_MODE == cds_get_conparam())
2337 		return;
2338 
2339 	qdf_spin_lock_bh(&dp_ctx->bus_bw_lock);
2340 	dp_intf->prev_tx_packets = 0;
2341 	dp_intf->prev_rx_packets = 0;
2342 	dp_intf->prev_fwd_tx_packets = 0;
2343 	dp_intf->prev_fwd_rx_packets = 0;
2344 	dp_intf->prev_tx_bytes = 0;
2345 	qdf_spin_unlock_bh(&dp_ctx->bus_bw_lock);
2346 }
2347 #endif /* WLAN_FEATURE_DP_BUS_BANDWIDTH */
2348