1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8 
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 /**
19  * DOC: os_if_son.c
20  *
21  * WLAN Host Device Driver file for son (Self Organizing Network)
22  * support.
23  *
24  */
25 
26 #include <os_if_son.h>
27 #include <qdf_trace.h>
28 #include <qdf_module.h>
29 #include <wlan_cfg80211.h>
30 #include <son_ucfg_api.h>
31 #include <wlan_dfs_ucfg_api.h>
32 #include <wlan_reg_ucfg_api.h>
33 #include <wlan_vdev_mgr_ucfg_api.h>
34 #include <wlan_mlme_ucfg_api.h>
35 #include <wlan_reg_services_api.h>
36 #include <wlan_scan_ucfg_api.h>
37 #include <wlan_dcs_ucfg_api.h>
38 
39 static struct son_callbacks g_son_os_if_cb;
40 static struct wlan_os_if_son_ops g_son_os_if_txrx_ops;
41 static void (*os_if_son_ops_cb)(struct wlan_os_if_son_ops *son_ops);
42 
os_if_son_register_hdd_callbacks(struct wlan_objmgr_psoc * psoc,struct son_callbacks * cb_obj)43 void os_if_son_register_hdd_callbacks(struct wlan_objmgr_psoc *psoc,
44 				      struct son_callbacks *cb_obj)
45 {
46 	g_son_os_if_cb = *cb_obj;
47 }
48 
os_if_son_get_freq(struct wlan_objmgr_vdev * vdev)49 qdf_freq_t os_if_son_get_freq(struct wlan_objmgr_vdev *vdev)
50 {
51 	struct wlan_objmgr_pdev *pdev;
52 	qdf_freq_t freq;
53 
54 	if (!vdev) {
55 		osif_err("null vdev");
56 		return 0;
57 	}
58 
59 	pdev = wlan_vdev_get_pdev(vdev);
60 	if (!pdev) {
61 		osif_err("null pdev");
62 		return 0;
63 	}
64 
65 	freq = ucfg_son_get_operation_chan_freq_vdev_id(pdev,
66 							wlan_vdev_get_id(vdev));
67 	osif_debug("vdev %d get freq %d", wlan_vdev_get_id(vdev), freq);
68 
69 	return freq;
70 }
71 qdf_export_symbol(os_if_son_get_freq);
72 
os_if_son_is_acs_in_progress(struct wlan_objmgr_vdev * vdev)73 uint32_t os_if_son_is_acs_in_progress(struct wlan_objmgr_vdev *vdev)
74 {
75 	uint32_t acs_in_progress;
76 
77 	if (!vdev) {
78 		osif_err("null vdev");
79 		return 0;
80 	}
81 
82 	acs_in_progress = g_son_os_if_cb.os_if_is_acs_in_progress(vdev);
83 	osif_debug("vdev %d acs_in_progress %d",
84 		   wlan_vdev_get_id(vdev), acs_in_progress);
85 
86 	return acs_in_progress;
87 }
88 qdf_export_symbol(os_if_son_is_acs_in_progress);
89 
os_if_son_is_cac_in_progress(struct wlan_objmgr_vdev * vdev)90 uint32_t os_if_son_is_cac_in_progress(struct wlan_objmgr_vdev *vdev)
91 {
92 	uint32_t cac_in_progress;
93 
94 	if (!vdev) {
95 		osif_err("null vdev");
96 		return 0;
97 	}
98 
99 	cac_in_progress = ucfg_son_is_cac_in_progress(vdev);
100 	osif_debug("vdev %d cac_in_progress %d",
101 		   wlan_vdev_get_id(vdev), cac_in_progress);
102 
103 	return cac_in_progress;
104 }
105 qdf_export_symbol(os_if_son_is_cac_in_progress);
106 
os_if_son_set_chan_ext_offset(struct wlan_objmgr_vdev * vdev,enum sec20_chan_offset son_chan_ext_offset)107 int os_if_son_set_chan_ext_offset(struct wlan_objmgr_vdev *vdev,
108 				  enum sec20_chan_offset son_chan_ext_offset)
109 {
110 	int ret;
111 
112 	if (!vdev) {
113 		osif_err("null vdev");
114 		return 0;
115 	}
116 
117 	ret = g_son_os_if_cb.os_if_set_chan_ext_offset(vdev,
118 						       son_chan_ext_offset);
119 	osif_debug("vdev %d set_chan_ext_offset %d, ret %d",
120 		   wlan_vdev_get_id(vdev), son_chan_ext_offset, ret);
121 
122 	return ret;
123 }
124 qdf_export_symbol(os_if_son_set_chan_ext_offset);
125 
os_if_son_get_chan_ext_offset(struct wlan_objmgr_vdev * vdev)126 enum sec20_chan_offset os_if_son_get_chan_ext_offset(
127 						struct wlan_objmgr_vdev *vdev)
128 {
129 	enum sec20_chan_offset chan_ext_offset;
130 
131 	if (!vdev) {
132 		osif_err("null vdev");
133 		return 0;
134 	}
135 
136 	chan_ext_offset = g_son_os_if_cb.os_if_get_chan_ext_offset(vdev);
137 	osif_debug("vdev %d chan_ext_offset %d",
138 		   wlan_vdev_get_id(vdev), chan_ext_offset);
139 
140 	return chan_ext_offset;
141 }
142 qdf_export_symbol(os_if_son_get_chan_ext_offset);
143 
os_if_son_set_bandwidth(struct wlan_objmgr_vdev * vdev,uint32_t son_bandwidth)144 int os_if_son_set_bandwidth(struct wlan_objmgr_vdev *vdev,
145 			    uint32_t son_bandwidth)
146 {
147 	int ret;
148 
149 	if (!vdev) {
150 		osif_err("null vdev");
151 		return -EINVAL;
152 	}
153 
154 	ret = g_son_os_if_cb.os_if_set_bandwidth(vdev, son_bandwidth);
155 	osif_debug("vdev %d son_bandwidth %d ret %d",
156 		   wlan_vdev_get_id(vdev), son_bandwidth, ret);
157 
158 	return ret;
159 }
160 qdf_export_symbol(os_if_son_set_bandwidth);
161 
os_if_son_get_bandwidth(struct wlan_objmgr_vdev * vdev)162 uint32_t os_if_son_get_bandwidth(struct wlan_objmgr_vdev *vdev)
163 {
164 	uint32_t bandwidth;
165 
166 	if (!vdev) {
167 		osif_err("null vdev");
168 		return NONHT;
169 	}
170 
171 	bandwidth = g_son_os_if_cb.os_if_get_bandwidth(vdev);
172 	osif_debug("vdev %d son_bandwidth %d",
173 		   wlan_vdev_get_id(vdev), bandwidth);
174 
175 	return bandwidth;
176 }
177 qdf_export_symbol(os_if_son_get_bandwidth);
178 
os_if_band_bitmap_to_son_band_info(uint32_t reg_wifi_band_bitmap)179 static uint32_t os_if_band_bitmap_to_son_band_info(
180 					uint32_t reg_wifi_band_bitmap)
181 {
182 	uint32_t son_band_info = FULL_BAND_RADIO;
183 
184 	if (!(reg_wifi_band_bitmap & BIT(REG_BAND_5G)) &&
185 	    !(reg_wifi_band_bitmap & BIT(REG_BAND_6G)))
186 		return NON_5G_RADIO;
187 	if (reg_wifi_band_bitmap & BIT(REG_BAND_6G) &&
188 	    !(reg_wifi_band_bitmap & BIT(REG_BAND_2G)) &&
189 	    !(reg_wifi_band_bitmap & BIT(REG_BAND_5G)))
190 		return BAND_6G_RADIO;
191 
192 	return son_band_info;
193 }
194 
os_if_son_get_band_info(struct wlan_objmgr_vdev * vdev)195 uint32_t os_if_son_get_band_info(struct wlan_objmgr_vdev *vdev)
196 {
197 	QDF_STATUS status = QDF_STATUS_SUCCESS;
198 	struct wlan_objmgr_pdev *pdev;
199 	uint32_t reg_wifi_band_bitmap;
200 	uint32_t band_info;
201 
202 	if (!vdev) {
203 		osif_err("null vdev");
204 		return NO_BAND_INFORMATION_AVAILABLE;
205 	}
206 	pdev = wlan_vdev_get_pdev(vdev);
207 	if (!pdev) {
208 		osif_err("null pdev");
209 		return NO_BAND_INFORMATION_AVAILABLE;
210 	}
211 
212 	status = ucfg_reg_get_band(pdev, &reg_wifi_band_bitmap);
213 	if (!QDF_IS_STATUS_SUCCESS(status)) {
214 		osif_err("failed to get band");
215 		return NO_BAND_INFORMATION_AVAILABLE;
216 	}
217 
218 	band_info = os_if_band_bitmap_to_son_band_info(reg_wifi_band_bitmap);
219 	osif_debug("vdev %d band_info %d",
220 		   wlan_vdev_get_id(vdev), band_info);
221 
222 	return band_info;
223 }
224 qdf_export_symbol(os_if_son_get_band_info);
225 
226 #define BW_WITHIN(min, bw, max) ((min) <= (bw) && (bw) <= (max))
227 /**
228  * os_if_son_fill_chan_info() - fill chan info
229  * @chan_info: chan info to fill
230  * @chan_num: chan number
231  * @primary_freq: chan frequency
232  * @ch_num_seg1: channel number for segment 1
233  * @ch_num_seg2: channel number for segment 2
234  *
235  * Return: void
236  */
os_if_son_fill_chan_info(struct ieee80211_channel_info * chan_info,uint8_t chan_num,qdf_freq_t primary_freq,uint8_t ch_num_seg1,uint8_t ch_num_seg2)237 static void os_if_son_fill_chan_info(struct ieee80211_channel_info *chan_info,
238 				     uint8_t chan_num, qdf_freq_t primary_freq,
239 				     uint8_t ch_num_seg1, uint8_t ch_num_seg2)
240 {
241 	chan_info->ieee = chan_num;
242 	chan_info->freq = primary_freq;
243 	chan_info->vhtop_ch_num_seg1 = ch_num_seg1;
244 	chan_info->vhtop_ch_num_seg2 = ch_num_seg2;
245 }
246 
247 /**
248  * os_if_son_update_chan_info() - update chan info
249  * @pdev: pdev
250  * @flag_160: flag indicating the API to fill the center frequencies of 160MHz.
251  * @cur_chan_list: pointer to regulatory_channel
252  * @chan_info: chan info to fill
253  * @half_and_quarter_rate_flags: half and quarter rate flags
254  *
255  * Return: void
256  */
os_if_son_update_chan_info(struct wlan_objmgr_pdev * pdev,bool flag_160,struct regulatory_channel * cur_chan_list,struct ieee80211_channel_info * chan_info,uint64_t half_and_quarter_rate_flags)257 static void os_if_son_update_chan_info(
258 			struct wlan_objmgr_pdev *pdev, bool flag_160,
259 			struct regulatory_channel *cur_chan_list,
260 			struct ieee80211_channel_info *chan_info,
261 			uint64_t half_and_quarter_rate_flags)
262 {
263 	qdf_freq_t primary_freq = cur_chan_list->center_freq;
264 	struct ch_params chan_params = {0};
265 
266 	if (!chan_info) {
267 		osif_err("null chan info");
268 		return;
269 	}
270 	if (cur_chan_list->chan_flags & REGULATORY_CHAN_NO_OFDM)
271 		chan_info->flags |=
272 			VENDOR_CHAN_FLAG2(QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_B);
273 	else
274 		chan_info->flags |= ucfg_son_get_chan_flag(pdev, primary_freq,
275 							   flag_160,
276 							   &chan_params);
277 	if (cur_chan_list->chan_flags & REGULATORY_CHAN_RADAR) {
278 		chan_info->flags_ext |=
279 			QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DFS;
280 		chan_info->flags_ext |=
281 			QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_DISALLOW_ADHOC;
282 		chan_info->flags |= QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_PASSIVE;
283 	} else if (cur_chan_list->chan_flags & REGULATORY_CHAN_NO_IR) {
284 		/* For 2Ghz passive channels. */
285 		chan_info->flags |= QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_PASSIVE;
286 	}
287 
288 	if (WLAN_REG_IS_6GHZ_PSC_CHAN_FREQ(primary_freq))
289 		chan_info->flags_ext |=
290 			QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_EXT_PSC;
291 
292 	os_if_son_fill_chan_info(chan_info, cur_chan_list->chan_num,
293 				 primary_freq,
294 				 chan_params.center_freq_seg0,
295 				 chan_params.center_freq_seg1);
296 }
297 
os_if_son_get_chan_list(struct wlan_objmgr_vdev * vdev,struct ieee80211_ath_channel * chan_list,struct ieee80211_channel_info * chan_info,uint8_t * nchans,bool flag_160,bool flag_6ghz)298 int os_if_son_get_chan_list(struct wlan_objmgr_vdev *vdev,
299 			    struct ieee80211_ath_channel *chan_list,
300 			    struct ieee80211_channel_info *chan_info,
301 			    uint8_t *nchans, bool flag_160, bool flag_6ghz)
302 {
303 	struct regulatory_channel *cur_chan_list;
304 	int i;
305 	uint32_t phybitmap;
306 	uint32_t reg_wifi_band_bitmap;
307 	QDF_STATUS status = QDF_STATUS_SUCCESS;
308 	struct wlan_objmgr_pdev *pdev;
309 	struct wlan_objmgr_psoc *psoc;
310 	struct regulatory_channel *chan;
311 
312 	if (!vdev) {
313 		osif_err("null vdev");
314 		return -EINVAL;
315 	}
316 
317 	if (!chan_info) {
318 		osif_err("null chan info");
319 		return -EINVAL;
320 	}
321 
322 	pdev = wlan_vdev_get_pdev(vdev);
323 	if (!pdev) {
324 		osif_err("null pdev");
325 		return -EINVAL;
326 	}
327 
328 	psoc = wlan_vdev_get_psoc(vdev);
329 	if (!psoc) {
330 		osif_err("null psoc");
331 		return -EINVAL;
332 	}
333 
334 	status = ucfg_reg_get_band(pdev, &reg_wifi_band_bitmap);
335 	if (!QDF_IS_STATUS_SUCCESS(status)) {
336 		osif_err("failed to get band");
337 		return -EINVAL;
338 	}
339 
340 	cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
341 			sizeof(struct regulatory_channel));
342 	if (!cur_chan_list) {
343 		osif_err("cur_chan_list allocation fails");
344 		return -EINVAL;
345 	}
346 
347 	if (wlan_reg_get_current_chan_list(
348 	    pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
349 		qdf_mem_free(cur_chan_list);
350 		osif_err("fail to get current chan list");
351 		return -EINVAL;
352 	}
353 
354 	ucfg_reg_get_band(pdev, &phybitmap);
355 
356 	for (i = 0; i < NUM_CHANNELS; i++) {
357 		uint64_t band_flags;
358 		qdf_freq_t primary_freq = cur_chan_list[i].center_freq;
359 		uint64_t half_and_quarter_rate_flags = 0;
360 
361 		chan = &cur_chan_list[i];
362 		if ((chan->chan_flags & REGULATORY_CHAN_DISABLED) &&
363 		    chan->state == CHANNEL_STATE_DISABLE &&
364 		    !chan->nol_chan && !chan->nol_history)
365 			continue;
366 		if (WLAN_REG_IS_6GHZ_CHAN_FREQ(primary_freq)) {
367 			if (!flag_6ghz ||
368 			    !(reg_wifi_band_bitmap & BIT(REG_BAND_6G)))
369 				continue;
370 			band_flags = VENDOR_CHAN_FLAG2(
371 				QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_6GHZ);
372 		} else if (WLAN_REG_IS_24GHZ_CH_FREQ(primary_freq)) {
373 			if (!(reg_wifi_band_bitmap & BIT(REG_BAND_2G)))
374 				continue;
375 			band_flags = QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_2GHZ;
376 		} else if (WLAN_REG_IS_5GHZ_CH_FREQ(primary_freq)) {
377 			if (!(reg_wifi_band_bitmap & BIT(REG_BAND_5G)))
378 				continue;
379 			band_flags = QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_5GHZ;
380 		} else if (WLAN_REG_IS_49GHZ_FREQ(primary_freq)) {
381 			if (!(reg_wifi_band_bitmap & BIT(REG_BAND_5G)))
382 				continue;
383 			band_flags = QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_5GHZ;
384 			/**
385 			 * If 4.9G Half and Quarter rates are supported
386 			 * by the channel, update them as separate entries
387 			 * to the list
388 			 */
389 			if (BW_WITHIN(chan->min_bw, BW_10_MHZ, chan->max_bw)) {
390 				os_if_son_fill_chan_info(&chan_info[*nchans],
391 							 chan->chan_num,
392 							 primary_freq, 0, 0);
393 				chan_info[*nchans].flags |=
394 					QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_HALF;
395 				chan_info[*nchans].flags |=
396 					VENDOR_CHAN_FLAG2(
397 					QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_A);
398 				half_and_quarter_rate_flags =
399 					chan_info[*nchans].flags;
400 				if (++(*nchans) >= IEEE80211_CHAN_MAX)
401 					break;
402 			}
403 			if (BW_WITHIN(chan->min_bw, BW_5_MHZ, chan->max_bw)) {
404 				os_if_son_fill_chan_info(&chan_info[*nchans],
405 							 chan->chan_num,
406 							 primary_freq, 0, 0);
407 				chan_info[*nchans].flags |=
408 				    QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_QUARTER;
409 				chan_info[*nchans].flags |=
410 					VENDOR_CHAN_FLAG2(
411 					QCA_WLAN_VENDOR_CHANNEL_PROP_FLAG_A);
412 				half_and_quarter_rate_flags =
413 					chan_info[*nchans].flags;
414 				if (++(*nchans) >= IEEE80211_CHAN_MAX)
415 					break;
416 			}
417 		} else {
418 			continue;
419 		}
420 
421 		os_if_son_update_chan_info(pdev, flag_160, chan,
422 					   &chan_info[*nchans],
423 					   half_and_quarter_rate_flags);
424 
425 		if (++(*nchans) >= IEEE80211_CHAN_MAX)
426 			break;
427 	}
428 
429 	qdf_mem_free(cur_chan_list);
430 	osif_debug("vdev %d channel_info exit", wlan_vdev_get_id(vdev));
431 
432 	return 0;
433 }
434 qdf_export_symbol(os_if_son_get_chan_list);
435 
os_if_son_get_sta_count(struct wlan_objmgr_vdev * vdev)436 uint32_t os_if_son_get_sta_count(struct wlan_objmgr_vdev *vdev)
437 {
438 	uint32_t sta_count;
439 
440 	if (!vdev) {
441 		osif_err("null vdev");
442 		return 0;
443 	}
444 
445 	sta_count = ucfg_son_get_sta_count(vdev);
446 	osif_debug("vdev %d sta count %d", wlan_vdev_get_id(vdev), sta_count);
447 
448 	return sta_count;
449 }
450 qdf_export_symbol(os_if_son_get_sta_count);
451 
os_if_son_get_bssid(struct wlan_objmgr_vdev * vdev,uint8_t bssid[QDF_MAC_ADDR_SIZE])452 int os_if_son_get_bssid(struct wlan_objmgr_vdev *vdev,
453 			uint8_t bssid[QDF_MAC_ADDR_SIZE])
454 {
455 	if (!vdev) {
456 		osif_err("null vdev");
457 		return -EINVAL;
458 	}
459 
460 	ucfg_wlan_vdev_mgr_get_param_bssid(vdev, bssid);
461 	osif_debug("vdev %d bssid " QDF_MAC_ADDR_FMT,
462 		   wlan_vdev_get_id(vdev), QDF_MAC_ADDR_REF(bssid));
463 
464 	return 0;
465 }
466 qdf_export_symbol(os_if_son_get_bssid);
467 
os_if_son_get_ssid(struct wlan_objmgr_vdev * vdev,char ssid[WLAN_SSID_MAX_LEN+1],uint8_t * ssid_len)468 int os_if_son_get_ssid(struct wlan_objmgr_vdev *vdev,
469 		       char ssid[WLAN_SSID_MAX_LEN + 1],
470 		       uint8_t *ssid_len)
471 {
472 	if (!vdev) {
473 		osif_err("null vdev");
474 		return -EINVAL;
475 	}
476 
477 	ucfg_wlan_vdev_mgr_get_param_ssid(vdev, ssid, ssid_len);
478 	osif_debug("vdev %d ssid " QDF_SSID_FMT,
479 		   wlan_vdev_get_id(vdev),
480 		   QDF_SSID_REF(*ssid_len, ssid));
481 
482 	return 0;
483 }
484 qdf_export_symbol(os_if_son_get_ssid);
485 
os_if_son_set_chan(struct wlan_objmgr_vdev * vdev,int chan,enum wlan_band_id son_band)486 int os_if_son_set_chan(struct wlan_objmgr_vdev *vdev,
487 		       int chan, enum wlan_band_id son_band)
488 {
489 	int ret;
490 
491 	if (!vdev) {
492 		osif_err("null vdev");
493 		return -EINVAL;
494 	}
495 
496 	ret = g_son_os_if_cb.os_if_set_chan(vdev, chan, son_band);
497 	osif_debug("vdev %d chan %d son_band %d", wlan_vdev_get_id(vdev),
498 		   chan, son_band);
499 
500 	return ret;
501 }
502 qdf_export_symbol(os_if_son_set_chan);
503 
os_if_son_set_cac_timeout(struct wlan_objmgr_vdev * vdev,int cac_timeout)504 int os_if_son_set_cac_timeout(struct wlan_objmgr_vdev *vdev,
505 			      int cac_timeout)
506 {
507 	struct wlan_objmgr_pdev *pdev;
508 	int status;
509 
510 	if (!vdev) {
511 		osif_err("null vdev");
512 		return -EINVAL;
513 	}
514 	pdev = wlan_vdev_get_pdev(vdev);
515 	if (!pdev) {
516 		osif_err("null pdev");
517 		return -EINVAL;
518 	}
519 
520 	if (QDF_IS_STATUS_ERROR(ucfg_dfs_override_cac_timeout(
521 		pdev, cac_timeout, &status))) {
522 		osif_err("cac timeout override fails");
523 		return -EINVAL;
524 	}
525 	osif_debug("vdev %d cac_timeout %d status %d",
526 		   wlan_vdev_get_id(vdev), cac_timeout, status);
527 
528 	return status;
529 }
530 qdf_export_symbol(os_if_son_set_cac_timeout);
531 
os_if_son_get_cac_timeout(struct wlan_objmgr_vdev * vdev,int * cac_timeout)532 int os_if_son_get_cac_timeout(struct wlan_objmgr_vdev *vdev,
533 			      int *cac_timeout)
534 {
535 	struct wlan_objmgr_pdev *pdev;
536 	int status;
537 
538 	if (!vdev) {
539 		osif_err("null vdev");
540 		return -EINVAL;
541 	}
542 	pdev = wlan_vdev_get_pdev(vdev);
543 	if (!pdev) {
544 		osif_err("null pdev");
545 		return -EINVAL;
546 	}
547 
548 	if (QDF_IS_STATUS_ERROR(ucfg_dfs_get_override_cac_timeout(
549 		pdev, cac_timeout, &status))) {
550 		osif_err("fails to get cac timeout");
551 		return -EINVAL;
552 	}
553 	osif_debug("vdev %d cac_timeout %d status %d",
554 		   wlan_vdev_get_id(vdev), *cac_timeout, status);
555 
556 	return status;
557 }
558 qdf_export_symbol(os_if_son_get_cac_timeout);
559 
os_if_son_set_country_code(struct wlan_objmgr_vdev * vdev,char * country_code)560 int os_if_son_set_country_code(struct wlan_objmgr_vdev *vdev,
561 			       char *country_code)
562 {
563 	int ret;
564 
565 	if (!vdev) {
566 		osif_err("null vdev");
567 		return -EINVAL;
568 	}
569 	ret = g_son_os_if_cb.os_if_set_country_code(vdev, country_code);
570 	osif_debug("vdev %d country_code %s ret %d",
571 		   wlan_vdev_get_id(vdev), country_code, ret);
572 
573 	return ret;
574 }
575 qdf_export_symbol(os_if_son_set_country_code);
576 
os_if_son_get_country_code(struct wlan_objmgr_vdev * vdev,char * country_code)577 int os_if_son_get_country_code(struct wlan_objmgr_vdev *vdev,
578 			       char *country_code)
579 {
580 	QDF_STATUS status;
581 	struct wlan_objmgr_psoc *psoc;
582 
583 	if (!vdev) {
584 		osif_err("null vdev");
585 		return -EINVAL;
586 	}
587 	psoc = wlan_vdev_get_psoc(vdev);
588 	if (!psoc) {
589 		osif_err("null psoc");
590 		return -EINVAL;
591 	}
592 	status = ucfg_reg_get_current_country(psoc, country_code);
593 	osif_debug("vdev %d country_code %s status %d",
594 		   wlan_vdev_get_id(vdev), country_code, status);
595 
596 	return qdf_status_to_os_return(status);
597 }
598 qdf_export_symbol(os_if_son_get_country_code);
599 
os_if_son_set_candidate_freq(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq)600 int os_if_son_set_candidate_freq(struct wlan_objmgr_vdev *vdev,
601 				 qdf_freq_t freq)
602 {
603 	int ret;
604 
605 	if (!vdev) {
606 		osif_err("null vdev");
607 		return -EINVAL;
608 	}
609 
610 	ret = g_son_os_if_cb.os_if_set_candidate_freq(vdev, freq);
611 	osif_debug("vdev %d set_candidate_freq %d ret %d",
612 		   wlan_vdev_get_id(vdev), freq, ret);
613 
614 	return ret;
615 }
616 qdf_export_symbol(os_if_son_set_candidate_freq);
617 
os_if_son_get_candidate_freq(struct wlan_objmgr_vdev * vdev)618 qdf_freq_t os_if_son_get_candidate_freq(struct wlan_objmgr_vdev *vdev)
619 {
620 	qdf_freq_t freq;
621 
622 	if (!vdev) {
623 		osif_err("null vdev");
624 		return 0;
625 	}
626 
627 	freq = g_son_os_if_cb.os_if_get_candidate_freq(vdev);
628 	osif_debug("vdev %d candidate_freq %d",
629 		   wlan_vdev_get_id(vdev), freq);
630 
631 	return freq;
632 }
633 qdf_export_symbol(os_if_son_get_candidate_freq);
634 
os_if_son_set_acl_policy(struct wlan_objmgr_vdev * vdev,ieee80211_acl_cmd son_acl_policy)635 QDF_STATUS os_if_son_set_acl_policy(struct wlan_objmgr_vdev *vdev,
636 				    ieee80211_acl_cmd son_acl_policy)
637 {
638 	QDF_STATUS ret;
639 
640 	if (!vdev) {
641 		osif_err("null vdev");
642 		return QDF_STATUS_E_INVAL;
643 	}
644 
645 	ret = g_son_os_if_cb.os_if_set_acl_policy(vdev, son_acl_policy);
646 	osif_debug("set acl policy %d status %d", son_acl_policy, ret);
647 
648 	return ret;
649 }
650 qdf_export_symbol(os_if_son_set_acl_policy);
651 
os_if_son_get_acl_policy(struct wlan_objmgr_vdev * vdev)652 ieee80211_acl_cmd os_if_son_get_acl_policy(struct wlan_objmgr_vdev *vdev)
653 {
654 	ieee80211_acl_cmd son_acl_policy;
655 
656 	if (!vdev) {
657 		osif_err("null vdev");
658 		return IEEE80211_MACCMD_DETACH;
659 	}
660 	son_acl_policy = g_son_os_if_cb.os_if_get_acl_policy(vdev);
661 	osif_debug("get acl policy %d", son_acl_policy);
662 
663 	return son_acl_policy;
664 }
665 qdf_export_symbol(os_if_son_get_acl_policy);
666 
os_if_son_add_acl_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * acl_mac)667 int os_if_son_add_acl_mac(struct wlan_objmgr_vdev *vdev,
668 			  struct qdf_mac_addr *acl_mac)
669 {
670 	int ret;
671 
672 	if (!vdev) {
673 		osif_err("null vdev");
674 		return -EINVAL;
675 	}
676 	ret = g_son_os_if_cb.os_if_add_acl_mac(vdev, acl_mac);
677 	osif_debug("add_acl_mac " QDF_MAC_ADDR_FMT " ret %d",
678 		   QDF_MAC_ADDR_REF(acl_mac->bytes), ret);
679 
680 	return ret;
681 }
682 qdf_export_symbol(os_if_son_add_acl_mac);
683 
os_if_son_del_acl_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * acl_mac)684 int os_if_son_del_acl_mac(struct wlan_objmgr_vdev *vdev,
685 			  struct qdf_mac_addr *acl_mac)
686 {
687 	int ret;
688 
689 	if (!vdev) {
690 		osif_err("null vdev");
691 		return -EINVAL;
692 	}
693 	ret = g_son_os_if_cb.os_if_del_acl_mac(vdev, acl_mac);
694 	osif_debug("del_acl_mac " QDF_MAC_ADDR_FMT " ret %d",
695 		   QDF_MAC_ADDR_REF(acl_mac->bytes), ret);
696 
697 	return ret;
698 }
699 qdf_export_symbol(os_if_son_del_acl_mac);
700 
os_if_son_kickout_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * mac)701 int os_if_son_kickout_mac(struct wlan_objmgr_vdev *vdev,
702 			  struct qdf_mac_addr *mac)
703 {
704 	int ret;
705 
706 	if (!vdev) {
707 		osif_err("null vdev");
708 		return -EINVAL;
709 	}
710 	ret = g_son_os_if_cb.os_if_kickout_mac(vdev, mac);
711 	osif_debug("kickout mac " QDF_MAC_ADDR_FMT " ret %d",
712 		   QDF_MAC_ADDR_REF(mac->bytes), ret);
713 
714 	return ret;
715 }
716 qdf_export_symbol(os_if_son_kickout_mac);
717 
os_if_son_get_chan_util(struct wlan_objmgr_vdev * vdev)718 uint8_t os_if_son_get_chan_util(struct wlan_objmgr_vdev *vdev)
719 {
720 	struct wlan_host_dcs_ch_util_stats dcs_son_stats = {};
721 	struct wlan_objmgr_psoc *psoc;
722 	uint8_t mac_id;
723 	QDF_STATUS status;
724 
725 	if (!vdev) {
726 		osif_err("null vdev");
727 		return 0;
728 	}
729 
730 	psoc = wlan_vdev_get_psoc(vdev);
731 	if (!psoc) {
732 		osif_err("null psoc");
733 		return 0;
734 	}
735 	status = policy_mgr_get_mac_id_by_session_id(psoc,
736 						     wlan_vdev_get_id(vdev),
737 						     &mac_id);
738 	if (QDF_IS_STATUS_ERROR(status)) {
739 		osif_err("Failed to get mac_id");
740 		return 0;
741 	}
742 
743 	ucfg_dcs_get_ch_util(psoc, mac_id, &dcs_son_stats);
744 	osif_debug("get_chan_util %d", dcs_son_stats.total_cu);
745 
746 	return dcs_son_stats.total_cu;
747 }
748 qdf_export_symbol(os_if_son_get_chan_util);
749 
os_if_son_get_phy_stats(struct wlan_objmgr_vdev * vdev,struct ol_ath_radiostats * phy_stats)750 void os_if_son_get_phy_stats(struct wlan_objmgr_vdev *vdev,
751 			     struct ol_ath_radiostats *phy_stats)
752 {
753 	struct wlan_host_dcs_ch_util_stats dcs_son_stats = {};
754 	struct wlan_objmgr_psoc *psoc;
755 	uint8_t mac_id;
756 	QDF_STATUS status;
757 
758 	if (!vdev) {
759 		osif_err("null vdev");
760 		return;
761 	}
762 
763 	psoc = wlan_vdev_get_psoc(vdev);
764 	if (!psoc) {
765 		osif_err("null psoc");
766 		return;
767 	}
768 	status = policy_mgr_get_mac_id_by_session_id(psoc,
769 						     wlan_vdev_get_id(vdev),
770 						     &mac_id);
771 	if (QDF_IS_STATUS_ERROR(status)) {
772 		osif_err("Failed to get mac_id");
773 		return;
774 	}
775 
776 	ucfg_dcs_get_ch_util(psoc, mac_id, &dcs_son_stats);
777 
778 	phy_stats->ap_rx_util = dcs_son_stats.rx_cu;
779 	phy_stats->ap_tx_util = dcs_son_stats.tx_cu;
780 	phy_stats->obss_rx_util = dcs_son_stats.obss_rx_cu;
781 	if (dcs_son_stats.total_cu < 100)
782 		phy_stats->free_medium = 100 - dcs_son_stats.total_cu;
783 	else
784 		phy_stats->free_medium = 0;
785 	phy_stats->chan_nf = dcs_son_stats.chan_nf;
786 	osif_debug("rx_util %d tx_util %d obss_rx_util %d free_medium %d noise floor %d",
787 		   phy_stats->ap_rx_util, phy_stats->ap_tx_util,
788 		   phy_stats->obss_rx_util, phy_stats->free_medium,
789 		   phy_stats->chan_nf);
790 }
791 qdf_export_symbol(os_if_son_get_phy_stats);
792 
os_if_son_cbs_init(void)793 int os_if_son_cbs_init(void)
794 {
795 	int ret;
796 
797 	ret = ucfg_son_cbs_init();
798 
799 	return ret;
800 }
801 
802 qdf_export_symbol(os_if_son_cbs_init);
803 
os_if_son_cbs_deinit(void)804 int os_if_son_cbs_deinit(void)
805 {
806 	int ret;
807 
808 	ret = ucfg_son_cbs_deinit();
809 
810 	return ret;
811 }
812 
813 qdf_export_symbol(os_if_son_cbs_deinit);
814 
os_if_son_set_cbs(struct wlan_objmgr_vdev * vdev,bool enable)815 int os_if_son_set_cbs(struct wlan_objmgr_vdev *vdev,
816 		      bool enable)
817 {
818 	int ret;
819 
820 	ret = ucfg_son_set_cbs(vdev, enable);
821 
822 	return ret;
823 }
824 
825 qdf_export_symbol(os_if_son_set_cbs);
826 
os_if_son_set_cbs_wait_time(struct wlan_objmgr_vdev * vdev,uint32_t val)827 int os_if_son_set_cbs_wait_time(struct wlan_objmgr_vdev *vdev,
828 				uint32_t val)
829 {
830 	int ret;
831 
832 	ret = ucfg_son_set_cbs_wait_time(vdev, val);
833 
834 	return ret;
835 }
836 
837 qdf_export_symbol(os_if_son_set_cbs_wait_time);
838 
os_if_son_set_cbs_dwell_split_time(struct wlan_objmgr_vdev * vdev,uint32_t val)839 int os_if_son_set_cbs_dwell_split_time(struct wlan_objmgr_vdev *vdev,
840 				       uint32_t val)
841 {
842 	int ret;
843 
844 	ret = ucfg_son_set_cbs_dwell_split_time(vdev, val);
845 
846 	return ret;
847 }
848 
849 qdf_export_symbol(os_if_son_set_cbs_dwell_split_time);
850 
os_if_son_set_phymode(struct wlan_objmgr_vdev * vdev,enum ieee80211_phymode mode)851 int os_if_son_set_phymode(struct wlan_objmgr_vdev *vdev,
852 			  enum ieee80211_phymode mode)
853 {
854 	int ret;
855 
856 	if (!vdev) {
857 		osif_err("null vdev");
858 		return 0;
859 	}
860 
861 	ret = g_son_os_if_cb.os_if_set_phymode(vdev, mode);
862 	osif_debug("vdev %d phymode %d ret %d",
863 		   wlan_vdev_get_id(vdev), mode, ret);
864 
865 	return ret;
866 }
867 qdf_export_symbol(os_if_son_set_phymode);
868 
os_if_son_get_phymode(struct wlan_objmgr_vdev * vdev)869 enum ieee80211_phymode os_if_son_get_phymode(struct wlan_objmgr_vdev *vdev)
870 {
871 	enum ieee80211_phymode phymode;
872 
873 	if (!vdev) {
874 		osif_err("null vdev");
875 		return 0;
876 	}
877 
878 	phymode = g_son_os_if_cb.os_if_get_phymode(vdev);
879 	osif_debug("vdev %d phymode %d",
880 		   wlan_vdev_get_id(vdev), phymode);
881 
882 	return phymode;
883 }
884 qdf_export_symbol(os_if_son_get_phymode);
885 
os_if_son_get_apcap(struct wlan_objmgr_vdev * vdev,wlan_ap_cap * apcap)886 static QDF_STATUS os_if_son_get_apcap(struct wlan_objmgr_vdev *vdev,
887 				      wlan_ap_cap *apcap)
888 {
889 	uint32_t num_rx_streams = 0;
890 	uint32_t num_tx_streams = 0;
891 	uint32_t  value;
892 	struct mlme_ht_capabilities_info ht_cap_info;
893 	struct wlan_objmgr_psoc *psoc;
894 	tDot11fIEhe_cap he_cap = {0};
895 	bool enabled;
896 	QDF_STATUS status;
897 	int32_t vht_caps = 0;
898 
899 	/* Number of supported tx and rx streams */
900 	status = ucfg_son_vdev_get_supported_txrx_streams(vdev, &num_tx_streams,
901 							  &num_rx_streams);
902 	if (status != QDF_STATUS_SUCCESS) {
903 		osif_err("Could not get txrx streams");
904 		return status;
905 	}
906 
907 	psoc = wlan_vdev_get_psoc(vdev);
908 	if (!psoc) {
909 		osif_err("null psoc");
910 		return QDF_STATUS_E_NULL_VALUE;
911 	}
912 
913 	/* Fetch HT CAP */
914 	status = ucfg_mlme_get_ht_cap_info(psoc, &ht_cap_info);
915 	if (status == QDF_STATUS_SUCCESS) {
916 		apcap->wlan_ap_ht_capabilities_valid = true;
917 		qdf_mem_copy(&apcap->htcap.htcap, &ht_cap_info,
918 			     sizeof(struct mlme_ht_capabilities_info));
919 		apcap->htcap.max_tx_nss = num_tx_streams;
920 		apcap->htcap.max_rx_nss = num_rx_streams;
921 	}
922 
923 	/* Fetch VHT CAP */
924 	status = ucfg_mlme_get_vht_enable2x2(psoc, &enabled);
925 	if (enabled) {
926 		apcap->wlan_ap_vht_capabilities_valid = 1;
927 		ucfg_mlme_cfg_get_vht_tx_mcs_map(psoc, &value);
928 		apcap->vhtcap.supp_tx_mcs = value;
929 		ucfg_mlme_cfg_get_vht_rx_mcs_map(psoc, &value);
930 		apcap->vhtcap.supp_rx_mcs = value;
931 		apcap->vhtcap.max_tx_nss = num_tx_streams;
932 		apcap->vhtcap.max_rx_nss = num_rx_streams;
933 		if (ucfg_son_get_vht_cap(psoc, &vht_caps) == QDF_STATUS_SUCCESS)
934 			apcap->vhtcap.vhtcap = vht_caps;
935 	}
936 
937 	/* Fetch HE CAP */
938 	ucfg_mlme_cfg_get_he_caps(psoc, &he_cap);
939 	if (he_cap.present) {
940 		apcap->wlan_ap_he_capabilities_valid = 1;
941 		apcap->hecap.num_mcs_entries = MAP_MAX_HE_MCS;
942 		apcap->hecap.max_tx_nss = num_tx_streams;
943 		apcap->hecap.max_rx_nss = num_rx_streams;
944 		apcap->hecap.he_su_ppdu_1x_ltf_800ns_gi =
945 					he_cap.he_1x_ltf_800_gi_ppdu;
946 		apcap->hecap.he_ndp_4x_ltf_3200ns_gi =
947 					he_cap.he_4x_ltf_3200_gi_ndp;
948 		apcap->hecap.he_su_bfer = he_cap.su_beamformer;
949 		apcap->hecap.he_su_bfee = he_cap.su_beamformee;
950 		apcap->hecap.he_mu_bfer = he_cap.mu_beamformer;
951 		apcap->hecap.supported_he_mcs[0] = he_cap.rx_he_mcs_map_lt_80;
952 		apcap->hecap.supported_he_mcs[1] = he_cap.tx_he_mcs_map_lt_80;
953 		apcap->hecap.supported_he_mcs[2] =
954 					he_cap.rx_he_mcs_map_160[0][0] |
955 					(he_cap.rx_he_mcs_map_160[0][1] << 8);
956 		apcap->hecap.supported_he_mcs[3] =
957 					he_cap.tx_he_mcs_map_160[0][0] |
958 					(he_cap.tx_he_mcs_map_160[0][1] << 8);
959 		apcap->hecap.supported_he_mcs[4] =
960 					he_cap.rx_he_mcs_map_80_80[0][0] |
961 					(he_cap.rx_he_mcs_map_80_80[0][1] << 8);
962 		apcap->hecap.supported_he_mcs[5] =
963 					he_cap.tx_he_mcs_map_80_80[0][0] |
964 					(he_cap.tx_he_mcs_map_80_80[0][1] << 8);
965 		apcap->hecap.he_ul_mumimo = QDF_GET_BITS(he_cap.ul_mu, 0, 1);
966 		apcap->hecap.he_ul_muofdma = QDF_GET_BITS(he_cap.ul_mu, 1, 1);
967 		apcap->hecap.he_dl_muofdma = he_cap.dl_mu_mimo_part_bw;
968 	}
969 	return QDF_STATUS_SUCCESS;
970 }
971 
os_if_son_vdev_ops(struct wlan_objmgr_vdev * vdev,enum wlan_mlme_vdev_param type,void * data,void * ret)972 QDF_STATUS os_if_son_vdev_ops(struct wlan_objmgr_vdev *vdev,
973 			      enum wlan_mlme_vdev_param type,
974 			      void *data, void *ret)
975 {
976 	union wlan_mlme_vdev_data *in = (union wlan_mlme_vdev_data *)data;
977 	union wlan_mlme_vdev_data *out = (union wlan_mlme_vdev_data *)ret;
978 
979 	if (!vdev)
980 		return QDF_STATUS_E_INVAL;
981 	switch (type) {
982 	case VDEV_SET_IE:
983 		break;
984 	case VDEV_CLR_IE:
985 		break;
986 	case VDEV_SET_ACL:
987 		break;
988 	case VDEV_CLR_ACL:
989 		break;
990 	case VDEV_SET_ACL_TIMER:
991 		break;
992 	case VDEV_SET_PEER_ACT_STATS:
993 		break;
994 	case VDEV_SET_SEC_STA_WDS:
995 		break;
996 	case VDEV_SET_MEC:
997 		break;
998 	case VDEV_SET_MBO_IE_BSTM:
999 		break;
1000 	case VDEV_SET_WPS_ACL_ENABLE:
1001 		break;
1002 	case VDEV_SET_WNM_BSS_PREF:
1003 		break;
1004 	case VDEV_GET_NSS:
1005 		break;
1006 	case VDEV_GET_CHAN:
1007 		if (!out)
1008 			return QDF_STATUS_E_INVAL;
1009 		qdf_mem_copy(&out->chan,
1010 			     wlan_vdev_get_active_channel(vdev),
1011 			     sizeof(out->chan));
1012 		break;
1013 	case VDEV_GET_CHAN_WIDTH:
1014 		break;
1015 	case VDEV_GET_CHAN_UTIL:
1016 		if (!out)
1017 			return QDF_STATUS_E_INVAL;
1018 		out->chan_util = os_if_son_get_chan_util(vdev);
1019 		break;
1020 	case VDEV_GET_APCAP:
1021 		if (!out)
1022 			return QDF_STATUS_E_INVAL;
1023 		return os_if_son_get_apcap(vdev, &out->apcap);
1024 		break;
1025 	case VDEV_GET_CONNECT_N_TX:
1026 		break;
1027 	case VDEV_GET_SSID:
1028 		break;
1029 	case VDEV_GET_MAX_PHYRATE:
1030 		break;
1031 	case VDEV_GET_ACL:
1032 		break;
1033 	case VDEV_GET_ACL_RSSI_THRESHOLDS:
1034 		break;
1035 	case VDEV_GET_NODE_CAP:
1036 		if (!out || !in)
1037 			return QDF_STATUS_E_INVAL;
1038 		os_if_son_get_node_datarate_info(vdev, in->mac, &out->nodeinfo);
1039 		break;
1040 	case VDEV_GET_WDS:
1041 		break;
1042 	default:
1043 		return QDF_STATUS_E_INVAL;
1044 	}
1045 
1046 	return QDF_STATUS_SUCCESS;
1047 }
1048 
1049 qdf_export_symbol(os_if_son_vdev_ops);
1050 
os_if_son_get_peer_capability(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer,wlan_peer_cap * peer_cap)1051 static QDF_STATUS os_if_son_get_peer_capability(struct wlan_objmgr_vdev *vdev,
1052 						struct wlan_objmgr_peer *peer,
1053 						wlan_peer_cap *peer_cap)
1054 {
1055 	if (g_son_os_if_cb.os_if_get_peer_capability)
1056 		return g_son_os_if_cb.os_if_get_peer_capability(vdev, peer,
1057 								peer_cap);
1058 	return QDF_STATUS_E_INVAL;
1059 }
1060 
os_if_son_peer_ops(struct wlan_objmgr_peer * peer,enum wlan_mlme_peer_param type,union wlan_mlme_peer_data * in,union wlan_mlme_peer_data * out)1061 QDF_STATUS os_if_son_peer_ops(struct wlan_objmgr_peer *peer,
1062 			      enum wlan_mlme_peer_param type,
1063 			      union wlan_mlme_peer_data *in,
1064 			      union wlan_mlme_peer_data *out)
1065 {
1066 	struct wlan_objmgr_vdev *vdev;
1067 	struct wlan_objmgr_pdev *pdev;
1068 	struct wlan_objmgr_psoc *psoc;
1069 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1070 	struct qdf_mac_addr mac;
1071 	int ret_val;
1072 	static uint32_t peer_ext_stats_count;
1073 
1074 	if (!peer) {
1075 		osif_err("null peer");
1076 		return QDF_STATUS_E_INVAL;
1077 	}
1078 
1079 	vdev = wlan_peer_get_vdev(peer);
1080 	if (!vdev) {
1081 		osif_err("null vdev");
1082 		return QDF_STATUS_E_INVAL;
1083 	}
1084 	pdev = wlan_vdev_get_pdev(vdev);
1085 	if (!pdev) {
1086 		osif_err("null pdev");
1087 		return QDF_STATUS_E_INVAL;
1088 	}
1089 
1090 	psoc = wlan_pdev_get_psoc(pdev);
1091 	if (!psoc) {
1092 		osif_err("null psoc");
1093 		return QDF_STATUS_E_INVAL;
1094 	}
1095 	osif_debug("type %d", type);
1096 	/* All PEER MLME operations exported to SON component */
1097 	switch (type) {
1098 	/* SET/CLR API start */
1099 	case PEER_SET_KICKOUT:
1100 		qdf_mem_copy(&mac.bytes, peer->macaddr, QDF_MAC_ADDR_SIZE);
1101 		ret_val =
1102 		    g_son_os_if_cb.os_if_kickout_mac(vdev, &mac);
1103 		if (ret_val) {
1104 			osif_err("Failed to kickout peer " QDF_MAC_ADDR_FMT,
1105 				 QDF_MAC_ADDR_REF(peer->macaddr));
1106 			return QDF_STATUS_E_INVAL;
1107 		}
1108 		break;
1109 	case PEER_SET_KICKOUT_ALLOW:
1110 		if (!in) {
1111 			osif_err("invalid input parameter");
1112 			return QDF_STATUS_E_INVAL;
1113 		}
1114 		status = ucfg_son_set_peer_kickout_allow(vdev, peer,
1115 							 in->enable);
1116 		osif_debug("kickout allow %d, status %d", in->enable, status);
1117 		break;
1118 	case PEER_SET_EXT_STATS:
1119 		if (!in)
1120 			return QDF_STATUS_E_INVAL;
1121 		ret_val = wlan_peer_mlme_flag_get(peer, WLAN_PEER_F_EXT_STATS);
1122 		osif_debug("Enable: %d peer_ext_stats_count: %u ret_val: %d",
1123 			   in->enable, peer_ext_stats_count, ret_val);
1124 		if ((!!ret_val) != in->enable) {
1125 			status =
1126 			     wlan_son_peer_ext_stat_enable(pdev, peer->macaddr,
1127 							   vdev,
1128 							   peer_ext_stats_count,
1129 							   in->enable);
1130 			osif_debug("status: %u", status);
1131 			if (status == QDF_STATUS_SUCCESS) {
1132 				peer_ext_stats_count++;
1133 				wlan_peer_mlme_flag_set(peer,
1134 							WLAN_PEER_F_EXT_STATS);
1135 			} else {
1136 				if (peer_ext_stats_count)
1137 					peer_ext_stats_count--;
1138 				wlan_peer_mlme_flag_clear
1139 						(peer, WLAN_PEER_F_EXT_STATS);
1140 			}
1141 		}
1142 		break;
1143 	case PEER_REQ_INST_STAT:
1144 		status = wlan_son_peer_req_inst_stats(pdev, peer->macaddr,
1145 						      vdev);
1146 		if (status != QDF_STATUS_SUCCESS)
1147 			osif_err("Type: %d is failed", type);
1148 		break;
1149 	case PEER_GET_CAPABILITY:
1150 		if (!out)
1151 			return QDF_STATUS_E_INVAL;
1152 		status = os_if_son_get_peer_capability(vdev, peer,
1153 						       &out->peercap);
1154 		break;
1155 	case PEER_GET_MAX_MCS:
1156 		if (!out)
1157 			return QDF_STATUS_E_INVAL;
1158 		out->mcs = os_if_son_get_peer_max_mcs_idx(vdev, peer);
1159 		break;
1160 	default:
1161 		osif_err("invalid type: %d", type);
1162 		status = QDF_STATUS_E_INVAL;
1163 	}
1164 
1165 	return status;
1166 }
1167 
1168 qdf_export_symbol(os_if_son_peer_ops);
1169 
os_if_son_scan_db_iterate(struct wlan_objmgr_pdev * pdev,scan_iterator_func handler,void * arg)1170 QDF_STATUS os_if_son_scan_db_iterate(struct wlan_objmgr_pdev *pdev,
1171 				     scan_iterator_func handler, void *arg)
1172 {
1173 	return ucfg_scan_db_iterate(pdev, handler, arg);
1174 }
1175 
1176 qdf_export_symbol(os_if_son_scan_db_iterate);
1177 
os_if_son_acl_is_probe_wh_set(struct wlan_objmgr_vdev * vdev,const uint8_t * mac_addr,uint8_t probe_rssi)1178 bool os_if_son_acl_is_probe_wh_set(struct wlan_objmgr_vdev *vdev,
1179 				   const uint8_t *mac_addr,
1180 				   uint8_t probe_rssi)
1181 {
1182 	return false;
1183 }
1184 
1185 qdf_export_symbol(os_if_son_acl_is_probe_wh_set);
1186 
os_if_son_set_chwidth(struct wlan_objmgr_vdev * vdev,enum ieee80211_cwm_width son_chwidth)1187 int os_if_son_set_chwidth(struct wlan_objmgr_vdev *vdev,
1188 			  enum ieee80211_cwm_width son_chwidth)
1189 {
1190 	if (!vdev) {
1191 		osif_err("null vdev");
1192 		return -EINVAL;
1193 	}
1194 
1195 	return g_son_os_if_cb.os_if_set_chwidth(vdev, son_chwidth);
1196 }
1197 qdf_export_symbol(os_if_son_set_chwidth);
1198 
os_if_son_get_chwidth(struct wlan_objmgr_vdev * vdev)1199 enum ieee80211_cwm_width os_if_son_get_chwidth(struct wlan_objmgr_vdev *vdev)
1200 {
1201 	if (!vdev) {
1202 		osif_err("null vdev");
1203 		return 0;
1204 	}
1205 
1206 	return g_son_os_if_cb.os_if_get_chwidth(vdev);
1207 }
1208 qdf_export_symbol(os_if_son_get_chwidth);
1209 
os_if_son_get_rx_streams(struct wlan_objmgr_vdev * vdev)1210 u_int8_t os_if_son_get_rx_streams(struct wlan_objmgr_vdev *vdev)
1211 {
1212 	if (!vdev) {
1213 		osif_err("null vdev");
1214 		return 0;
1215 	}
1216 
1217 	return g_son_os_if_cb.os_if_get_rx_nss(vdev);
1218 }
1219 qdf_export_symbol(os_if_son_get_rx_streams);
1220 
os_if_son_cfg80211_reply(qdf_nbuf_t sk_buf)1221 QDF_STATUS os_if_son_cfg80211_reply(qdf_nbuf_t sk_buf)
1222 {
1223 	return wlan_cfg80211_qal_devcfg_send_response(sk_buf);
1224 }
1225 
1226 qdf_export_symbol(os_if_son_cfg80211_reply);
1227 
os_if_son_vdev_is_wds(struct wlan_objmgr_vdev * vdev)1228 bool os_if_son_vdev_is_wds(struct wlan_objmgr_vdev *vdev)
1229 {
1230 	return true;
1231 }
1232 
1233 qdf_export_symbol(os_if_son_vdev_is_wds);
1234 
os_if_son_get_sta_space(struct wlan_objmgr_vdev * vdev)1235 uint32_t os_if_son_get_sta_space(struct wlan_objmgr_vdev *vdev)
1236 {
1237 	uint32_t sta_space;
1238 
1239 	if (!vdev) {
1240 		osif_err("null vdev");
1241 		return 0;
1242 	}
1243 
1244 	sta_space = g_son_os_if_cb.os_if_get_sta_space(vdev);
1245 	osif_debug("need space %u", sta_space);
1246 
1247 	return sta_space;
1248 }
1249 
1250 qdf_export_symbol(os_if_son_get_sta_space);
1251 
os_if_son_get_sta_list(struct wlan_objmgr_vdev * vdev,struct ieee80211req_sta_info * si,uint32_t * space)1252 void os_if_son_get_sta_list(struct wlan_objmgr_vdev *vdev,
1253 			    struct ieee80211req_sta_info *si, uint32_t *space)
1254 {
1255 	if (!vdev) {
1256 		osif_err("null vdev");
1257 		return;
1258 	}
1259 
1260 	if (!si) {
1261 		osif_err("null si");
1262 		return;
1263 	}
1264 	if (!space || *space == 0) {
1265 		osif_err("invalid input space");
1266 		return;
1267 	}
1268 
1269 	g_son_os_if_cb.os_if_get_sta_list(vdev, si, space);
1270 
1271 	osif_debug("left space %u", *space);
1272 }
1273 
1274 qdf_export_symbol(os_if_son_get_sta_list);
1275 
os_if_son_deauth_peer_sta(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac,bool ignore_frame)1276 void os_if_son_deauth_peer_sta(struct wlan_objmgr_vdev *vdev,
1277 			       uint8_t *peer_mac,
1278 			       bool ignore_frame)
1279 {
1280 	if (!vdev || !peer_mac) {
1281 		osif_err("null vdev / peer_mac");
1282 		return;
1283 	}
1284 	if (g_son_os_if_cb.os_if_deauth_sta)
1285 		g_son_os_if_cb.os_if_deauth_sta(vdev, peer_mac, ignore_frame);
1286 }
1287 
1288 qdf_export_symbol(os_if_son_deauth_peer_sta);
1289 
os_if_son_modify_acl(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac,bool allow_auth)1290 void os_if_son_modify_acl(struct wlan_objmgr_vdev *vdev,
1291 			  uint8_t *peer_mac,
1292 			  bool allow_auth)
1293 {
1294 	if (!vdev || !peer_mac) {
1295 		osif_err("null vdev / peer_mac");
1296 		return;
1297 	}
1298 	if (g_son_os_if_cb.os_if_modify_acl)
1299 		g_son_os_if_cb.os_if_modify_acl(vdev, peer_mac, allow_auth);
1300 }
1301 
1302 qdf_export_symbol(os_if_son_modify_acl);
1303 
1304 static
os_if_son_reg_get_ap_hw_cap(struct wlan_objmgr_pdev * pdev,struct wlan_radio_basic_capabilities * hwcap,bool skip_6ghz)1305 int os_if_son_reg_get_ap_hw_cap(struct wlan_objmgr_pdev *pdev,
1306 				struct wlan_radio_basic_capabilities *hwcap,
1307 				bool skip_6ghz)
1308 {
1309 	QDF_STATUS status;
1310 	uint8_t idx;
1311 	uint8_t max_supp_op_class = REG_MAX_SUPP_OPER_CLASSES;
1312 	uint8_t n_opclasses = 0;
1313 	/* nsoc = Number of supported operating classes */
1314 	uint8_t nsoc = 0;
1315 	struct regdmn_ap_cap_opclass_t *reg_ap_cap;
1316 
1317 	if (!pdev || !hwcap)
1318 		return nsoc;
1319 
1320 	reg_ap_cap = qdf_mem_malloc(max_supp_op_class * sizeof(*reg_ap_cap));
1321 	if (!reg_ap_cap) {
1322 		osif_err("Memory allocation failure");
1323 		return nsoc;
1324 	}
1325 	status = wlan_reg_get_opclass_details(pdev, reg_ap_cap, &n_opclasses,
1326 					      max_supp_op_class, true,
1327 					      REG_CURRENT_PWR_MODE);
1328 	if (status == QDF_STATUS_E_FAILURE) {
1329 		osif_err("Failed to get SAP regulatory capabilities");
1330 		goto end_reg_get_ap_hw_cap;
1331 	}
1332 	osif_debug("n_opclasses: %u", n_opclasses);
1333 
1334 	for (idx = 0; reg_ap_cap[idx].op_class && idx < n_opclasses; idx++) {
1335 		osif_debug("idx: %d op_class: %u ch_width: %d  max_tx_pwr_dbm: %u",
1336 			   idx, reg_ap_cap[idx].op_class,
1337 			   reg_ap_cap[idx].ch_width,
1338 			   reg_ap_cap[idx].max_tx_pwr_dbm);
1339 		if (reg_ap_cap[idx].ch_width == BW_160_MHZ)
1340 			continue;
1341 		if (skip_6ghz &&
1342 		    wlan_reg_is_6ghz_op_class(pdev, reg_ap_cap[idx].op_class)) {
1343 			osif_debug("ignore 6 GHz op_class: %d to son",
1344 				   reg_ap_cap[idx].op_class);
1345 			continue;
1346 		}
1347 		hwcap->opclasses[nsoc].opclass = reg_ap_cap[idx].op_class;
1348 		hwcap->opclasses[nsoc].max_tx_pwr_dbm =
1349 					reg_ap_cap[idx].max_tx_pwr_dbm;
1350 		hwcap->opclasses[nsoc].num_non_oper_chan =
1351 					reg_ap_cap[idx].num_non_supported_chan;
1352 		qdf_mem_copy(hwcap->opclasses[nsoc].non_oper_chan_num,
1353 			     reg_ap_cap[idx].non_sup_chan_list,
1354 			     reg_ap_cap[idx].num_non_supported_chan);
1355 		hwcap->wlan_radio_basic_capabilities_valid = 1;
1356 		nsoc++;
1357 	}
1358 	hwcap->num_supp_op_classes = nsoc;
1359 
1360 end_reg_get_ap_hw_cap:
1361 
1362 	qdf_mem_free(reg_ap_cap);
1363 	return nsoc;
1364 }
1365 
os_if_son_reg_get_op_channels(struct wlan_objmgr_pdev * pdev,struct wlan_op_chan * op_chan,bool dfs_required)1366 static void os_if_son_reg_get_op_channels(struct wlan_objmgr_pdev *pdev,
1367 					  struct wlan_op_chan *op_chan,
1368 					  bool dfs_required)
1369 {
1370 	QDF_STATUS status;
1371 	uint8_t idx;
1372 	uint8_t max_supp_op_class = REG_MAX_SUPP_OPER_CLASSES;
1373 	uint8_t n_opclasses = 0;
1374 	/* nsoc = Number of supported operating classes */
1375 	uint8_t nsoc = 0;
1376 	struct regdmn_ap_cap_opclass_t *reg_ap_cap;
1377 	struct wlan_objmgr_psoc *psoc;
1378 
1379 	if (!pdev || !op_chan) {
1380 		osif_err("invalid input parameters");
1381 		return;
1382 	}
1383 	psoc = wlan_pdev_get_psoc(pdev);
1384 	if (!psoc) {
1385 		osif_err("NULL psoc");
1386 		return;
1387 	}
1388 
1389 	reg_ap_cap = qdf_mem_malloc(max_supp_op_class * sizeof(*reg_ap_cap));
1390 	if (!reg_ap_cap) {
1391 		osif_err("Memory allocation failure");
1392 		return;
1393 	}
1394 	status = wlan_reg_get_opclass_details(pdev, reg_ap_cap, &n_opclasses,
1395 					      max_supp_op_class, true,
1396 					      REG_CURRENT_PWR_MODE);
1397 	if (status == QDF_STATUS_E_FAILURE) {
1398 		osif_err("Failed to get SAP regulatory capabilities");
1399 		goto end_reg_get_op_channels;
1400 	}
1401 	osif_debug("n_opclasses: %u op_chan->opclass: %u",
1402 		   n_opclasses, op_chan->opclass);
1403 	for (idx = 0; reg_ap_cap[idx].op_class && idx < n_opclasses; idx++) {
1404 		if ((reg_ap_cap[idx].ch_width == BW_160_MHZ) ||
1405 		    (op_chan->opclass != reg_ap_cap[idx].op_class))
1406 			continue;
1407 		osif_debug("idx: %d op_class: %u ch_width: %d  max_tx_pwr_dbm: %u",
1408 			   idx, reg_ap_cap[idx].op_class,
1409 			   reg_ap_cap[idx].ch_width,
1410 			   reg_ap_cap[idx].max_tx_pwr_dbm);
1411 		if (reg_ap_cap[idx].op_class == op_chan->opclass) {
1412 			switch (reg_ap_cap[idx].ch_width) {
1413 			case BW_20_MHZ:
1414 			case BW_25_MHZ:
1415 				op_chan->ch_width = CH_WIDTH_20MHZ;
1416 				break;
1417 			case BW_40_MHZ:
1418 				op_chan->ch_width = CH_WIDTH_40MHZ;
1419 				break;
1420 			case BW_80_MHZ:
1421 				if (reg_ap_cap[idx].behav_limit == BIT(BEHAV_BW80_PLUS) &&
1422 				    ucfg_mlme_get_restricted_80p80_bw_supp(psoc))
1423 					op_chan->ch_width = CH_WIDTH_80P80MHZ;
1424 				else
1425 					op_chan->ch_width = CH_WIDTH_80MHZ;
1426 				break;
1427 			case BW_160_MHZ:
1428 				op_chan->ch_width  = CH_WIDTH_160MHZ;
1429 				break;
1430 			default:
1431 				op_chan->ch_width = INVALID_WIDTH;
1432 				break;
1433 			}
1434 			op_chan->num_oper_chan =
1435 					reg_ap_cap[idx].num_supported_chan;
1436 			qdf_mem_copy(op_chan->oper_chan_num,
1437 				     reg_ap_cap[idx].sup_chan_list,
1438 				     reg_ap_cap[idx].num_supported_chan);
1439 		}
1440 	}
1441 	osif_debug("num of supported channel: %u",
1442 		   op_chan->num_oper_chan);
1443 	/*
1444 	 * TBD: DFS channel support needs to be added
1445 	 * Variable nsoc will be update whenever we add DFS
1446 	 * channel support for Easymesh.
1447 	 */
1448 	op_chan->num_supp_op_classes = nsoc;
1449 
1450 end_reg_get_op_channels:
1451 
1452 	qdf_mem_free(reg_ap_cap);
1453 }
1454 
1455 /* size of sec chan offset element */
1456 #define IEEE80211_SEC_CHAN_OFFSET_BYTES             3
1457 /* no secondary channel */
1458 #define IEEE80211_SEC_CHAN_OFFSET_SCN               0
1459 /* secondary channel above */
1460 #define IEEE80211_SEC_CHAN_OFFSET_SCA               1
1461 /* secondary channel below */
1462 #define IEEE80211_SEC_CHAN_OFFSET_SCB               3
1463 
os_if_son_reg_get_opclass_details(struct wlan_objmgr_pdev * pdev,struct wlan_op_class * op_class)1464 static void os_if_son_reg_get_opclass_details(struct wlan_objmgr_pdev *pdev,
1465 					      struct wlan_op_class *op_class)
1466 {
1467 	QDF_STATUS status;
1468 	uint8_t i;
1469 	uint8_t idx;
1470 	uint8_t n_opclasses = 0;
1471 	uint8_t chan_idx;
1472 	uint8_t max_supp_op_class = REG_MAX_SUPP_OPER_CLASSES;
1473 	struct regdmn_ap_cap_opclass_t *reg_ap_cap =
1474 			qdf_mem_malloc(max_supp_op_class * sizeof(*reg_ap_cap));
1475 
1476 	if (!reg_ap_cap) {
1477 		osif_err("Memory allocation failure");
1478 		return;
1479 	}
1480 	status = wlan_reg_get_opclass_details(pdev, reg_ap_cap, &n_opclasses,
1481 					      max_supp_op_class, true,
1482 					      REG_CURRENT_PWR_MODE);
1483 	if (status == QDF_STATUS_E_FAILURE) {
1484 		osif_err("Failed to get SAP regulatory capabilities");
1485 		goto end_reg_get_opclass_details;
1486 	}
1487 	osif_debug("n_opclasses: %u", n_opclasses);
1488 
1489 	for (idx = 0; reg_ap_cap[idx].op_class && idx < n_opclasses; idx++) {
1490 		osif_debug("idx: %d op_class: %u ch_width: %d",
1491 			   idx, reg_ap_cap[idx].op_class,
1492 			   reg_ap_cap[idx].ch_width);
1493 		if ((op_class->opclass != reg_ap_cap[idx].op_class) ||
1494 		    (reg_ap_cap[idx].ch_width == BW_160_MHZ))
1495 			continue;
1496 		switch (reg_ap_cap[idx].ch_width) {
1497 		case BW_20_MHZ:
1498 		case BW_25_MHZ:
1499 			op_class->ch_width = CH_WIDTH_20MHZ;
1500 			break;
1501 		case BW_40_MHZ:
1502 			op_class->ch_width = CH_WIDTH_40MHZ;
1503 			break;
1504 		case BW_80_MHZ:
1505 			if (reg_ap_cap[idx].behav_limit == BIT(BEHAV_BW80_PLUS))
1506 				op_class->ch_width = CH_WIDTH_80P80MHZ;
1507 			else
1508 				op_class->ch_width = CH_WIDTH_80MHZ;
1509 			break;
1510 		case BW_160_MHZ:
1511 			op_class->ch_width  = CH_WIDTH_160MHZ;
1512 			break;
1513 		default:
1514 			op_class->ch_width = CH_WIDTH_INVALID;
1515 			break;
1516 		}
1517 		switch (reg_ap_cap[idx].behav_limit) {
1518 		case BIT(BEHAV_NONE):
1519 			op_class->sc_loc = IEEE80211_SEC_CHAN_OFFSET_SCN;
1520 			break;
1521 		case BIT(BEHAV_BW40_LOW_PRIMARY):
1522 			op_class->sc_loc = IEEE80211_SEC_CHAN_OFFSET_SCA;
1523 			break;
1524 		case BIT(BEHAV_BW40_HIGH_PRIMARY):
1525 			op_class->sc_loc = IEEE80211_SEC_CHAN_OFFSET_SCB;
1526 			break;
1527 		case BIT(BEHAV_BW80_PLUS):
1528 			op_class->sc_loc = IEEE80211_SEC_CHAN_OFFSET_SCN;
1529 			break;
1530 		default:
1531 			op_class->sc_loc = IEEE80211_SEC_CHAN_OFFSET_SCN;
1532 			break;
1533 		}
1534 		osif_debug("num_supported_chan: %u num_non_supported_chan: %u",
1535 			   reg_ap_cap[idx].num_supported_chan,
1536 			   reg_ap_cap[idx].num_non_supported_chan);
1537 		i = 0;
1538 		chan_idx = 0;
1539 		while ((i < reg_ap_cap[idx].num_supported_chan) &&
1540 		       (chan_idx < MAX_CHANNELS_PER_OP_CLASS))
1541 			op_class->channels[chan_idx++] =
1542 				reg_ap_cap[idx].sup_chan_list[i++];
1543 		i = 0;
1544 		while ((i < reg_ap_cap[idx].num_non_supported_chan) &&
1545 		       (chan_idx < MAX_CHANNELS_PER_OP_CLASS))
1546 			op_class->channels[chan_idx++] =
1547 				reg_ap_cap[idx].non_sup_chan_list[i++];
1548 
1549 		 op_class->num_chan = chan_idx;
1550 	}
1551 
1552 end_reg_get_opclass_details:
1553 
1554 	qdf_mem_free(reg_ap_cap);
1555 }
1556 
os_if_son_pdev_ops(struct wlan_objmgr_pdev * pdev,enum wlan_mlme_pdev_param type,void * data,void * ret)1557 QDF_STATUS os_if_son_pdev_ops(struct wlan_objmgr_pdev *pdev,
1558 			      enum wlan_mlme_pdev_param type,
1559 			      void *data, void *ret)
1560 {
1561 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1562 	union wlan_mlme_pdev_data *in = (union wlan_mlme_pdev_data *)data;
1563 	union wlan_mlme_pdev_data *out = (union wlan_mlme_pdev_data *)ret;
1564 	wlan_esp_data *esp_info;
1565 
1566 	if (!out)
1567 		return QDF_STATUS_E_INVAL;
1568 
1569 	osif_debug("Type: %d", type);
1570 	switch (type) {
1571 	case PDEV_GET_ESP_INFO:
1572 		esp_info = &out->esp_info;
1573 		/* BA Window Size of 16 */
1574 		esp_info->per_ac[WME_AC_BE].ba_window_size = ba_window_size_16;
1575 		esp_info->per_ac[WME_AC_BE].est_air_time_fraction = 0;
1576 		/* Default : 250us PPDU Duration in native format */
1577 		esp_info->per_ac[WME_AC_BE].data_ppdu_dur_target =
1578 			MAP_DEFAULT_PPDU_DURATION * MAP_PPDU_DURATION_UNITS;
1579 		break;
1580 	case PDEV_GET_CAPABILITY:
1581 		os_if_son_reg_get_ap_hw_cap(pdev, &out->cap, in->skip_6ghz);
1582 		break;
1583 	case PDEV_GET_OPERABLE_CHAN:
1584 		memcpy(&out->op_chan, &in->op_chan,
1585 		       sizeof(struct wlan_op_chan));
1586 		os_if_son_reg_get_op_channels(pdev, &out->op_chan,
1587 					      in->op_chan.dfs_required);
1588 		break;
1589 	case PDEV_GET_OPERABLE_CLASS:
1590 		memcpy(&out->op_class, &in->op_class,
1591 		       sizeof(struct wlan_op_class));
1592 		os_if_son_reg_get_opclass_details(pdev, &out->op_class);
1593 		break;
1594 	default:
1595 		break;
1596 	}
1597 
1598 	return status;
1599 }
1600 
1601 qdf_export_symbol(os_if_son_pdev_ops);
1602 
os_if_son_deliver_ald_event(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer,enum ieee80211_event_type event,void * event_data)1603 int os_if_son_deliver_ald_event(struct wlan_objmgr_vdev *vdev,
1604 				struct wlan_objmgr_peer *peer,
1605 				enum ieee80211_event_type event,
1606 				void *event_data)
1607 {
1608 	struct wlan_objmgr_psoc *psoc;
1609 	struct wlan_lmac_if_rx_ops *rx_ops;
1610 	int ret;
1611 
1612 	if (!vdev) {
1613 		osif_err("null vdev");
1614 		return -EINVAL;
1615 	}
1616 	psoc = wlan_vdev_get_psoc(vdev);
1617 	if (!psoc) {
1618 		osif_err("null posc");
1619 		return -EINVAL;
1620 	}
1621 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1622 	if (rx_ops && rx_ops->son_rx_ops.deliver_event)
1623 		ret = rx_ops->son_rx_ops.deliver_event(vdev, peer, event,
1624 						       event_data);
1625 	else
1626 		ret = -EINVAL;
1627 
1628 	return ret;
1629 }
1630 
1631 qdf_export_symbol(os_if_son_deliver_ald_event);
1632 
1633 struct wlan_objmgr_vdev *
os_if_son_get_vdev_by_netdev(struct net_device * dev)1634 os_if_son_get_vdev_by_netdev(struct net_device *dev)
1635 {
1636 	return g_son_os_if_cb.os_if_get_vdev_by_netdev(dev);
1637 }
1638 
1639 qdf_export_symbol(os_if_son_get_vdev_by_netdev);
1640 
os_if_son_trigger_objmgr_object_creation(enum wlan_umac_comp_id id)1641 QDF_STATUS os_if_son_trigger_objmgr_object_creation(enum wlan_umac_comp_id id)
1642 {
1643 	return g_son_os_if_cb.os_if_trigger_objmgr_object_creation(id);
1644 }
1645 
1646 qdf_export_symbol(os_if_son_trigger_objmgr_object_creation);
1647 
os_if_son_trigger_objmgr_object_deletion(enum wlan_umac_comp_id id)1648 QDF_STATUS os_if_son_trigger_objmgr_object_deletion(enum wlan_umac_comp_id id)
1649 {
1650 	return g_son_os_if_cb.os_if_trigger_objmgr_object_deletion(id);
1651 }
1652 
1653 qdf_export_symbol(os_if_son_trigger_objmgr_object_deletion);
1654 
os_if_son_start_acs(struct wlan_objmgr_vdev * vdev,uint8_t enable)1655 int os_if_son_start_acs(struct wlan_objmgr_vdev *vdev, uint8_t enable)
1656 {
1657 	if (!vdev) {
1658 		osif_err("null vdev");
1659 		return 0;
1660 	}
1661 
1662 	return g_son_os_if_cb.os_if_start_acs(vdev, enable);
1663 }
1664 
1665 qdf_export_symbol(os_if_son_start_acs);
1666 
os_if_son_set_acs_chan(struct wlan_objmgr_vdev * vdev,struct ieee80211req_athdbg * req)1667 int os_if_son_set_acs_chan(struct wlan_objmgr_vdev *vdev,
1668 			   struct ieee80211req_athdbg *req)
1669 {
1670 	if (!vdev) {
1671 		osif_err("null vdev");
1672 		return 0;
1673 	}
1674 
1675 	return g_son_os_if_cb.os_if_set_acs_channels(vdev, req);
1676 }
1677 
1678 qdf_export_symbol(os_if_son_set_acs_chan);
1679 
os_if_son_get_acs_report(struct wlan_objmgr_vdev * vdev,struct ieee80211_acs_dbg * acs_r)1680 int os_if_son_get_acs_report(struct wlan_objmgr_vdev *vdev,
1681 			     struct ieee80211_acs_dbg *acs_r)
1682 {
1683 	if (!vdev) {
1684 		osif_err("null vdev");
1685 		return 0;
1686 	}
1687 
1688 	return g_son_os_if_cb.os_if_get_acs_report(vdev, acs_r);
1689 }
1690 
1691 qdf_export_symbol(os_if_son_get_acs_report);
1692 
1693 void
wlan_os_if_son_ops_register_cb(void (* handler)(struct wlan_os_if_son_ops *))1694 wlan_os_if_son_ops_register_cb(void (*handler)(struct wlan_os_if_son_ops *))
1695 {
1696 	os_if_son_ops_cb = handler;
1697 }
1698 
1699 qdf_export_symbol(wlan_os_if_son_ops_register_cb);
1700 
wlan_son_register_os_if_ops(struct wlan_os_if_son_ops * son_ops)1701 static void wlan_son_register_os_if_ops(struct wlan_os_if_son_ops *son_ops)
1702 {
1703 	if (os_if_son_ops_cb)
1704 		os_if_son_ops_cb(son_ops);
1705 	else
1706 		osif_err("\n***** OS_IF: SON MODULE NOT LOADED *****\n");
1707 }
1708 
os_if_son_register_lmac_if_ops(struct wlan_objmgr_psoc * psoc)1709 void os_if_son_register_lmac_if_ops(struct wlan_objmgr_psoc *psoc)
1710 {
1711 	struct wlan_lmac_if_rx_ops *rx_ops;
1712 
1713 	if (!psoc) {
1714 		osif_err("psoc is NULL");
1715 		return;
1716 	}
1717 
1718 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
1719 	if (!rx_ops) {
1720 		osif_err("rx_ops is null");
1721 		return;
1722 	}
1723 
1724 	wlan_lmac_if_son_mod_register_rx_ops(rx_ops);
1725 }
1726 
1727 qdf_export_symbol(os_if_son_register_lmac_if_ops);
1728 
os_if_son_register_osif_ops(void)1729 void os_if_son_register_osif_ops(void)
1730 {
1731 	wlan_son_register_os_if_ops(&g_son_os_if_txrx_ops);
1732 }
1733 
1734 qdf_export_symbol(os_if_son_register_osif_ops);
1735 
os_if_son_parse_generic_nl_cmd(struct wiphy * wiphy,struct wireless_dev * wdev,struct nlattr ** tb,enum os_if_son_vendor_cmd_type type)1736 int os_if_son_parse_generic_nl_cmd(struct wiphy *wiphy,
1737 				   struct wireless_dev *wdev,
1738 				   struct nlattr **tb,
1739 				   enum os_if_son_vendor_cmd_type type)
1740 {
1741 	struct os_if_son_rx_ops *rx_ops = &g_son_os_if_txrx_ops.son_osif_rx_ops;
1742 	struct wlan_cfg8011_genric_params param = {};
1743 
1744 	if (!rx_ops->parse_generic_nl_cmd)
1745 		return -EINVAL;
1746 
1747 	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_COMMAND])
1748 		param.command = nla_get_u32(tb
1749 				[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_COMMAND]);
1750 
1751 	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_VALUE])
1752 		param.value = nla_get_u32(tb
1753 				[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_VALUE]);
1754 
1755 	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA]) {
1756 		param.data = nla_data(tb
1757 				[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA]);
1758 		param.data_len = nla_len(tb
1759 				[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA]);
1760 	}
1761 
1762 	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_LENGTH])
1763 		param.length = nla_get_u32(tb
1764 				[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_LENGTH]);
1765 
1766 	if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_FLAGS])
1767 		param.flags = nla_get_u32(tb
1768 				[QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_FLAGS]);
1769 
1770 	return rx_ops->parse_generic_nl_cmd(wiphy, wdev, &param, type);
1771 }
1772 
os_if_son_get_node_datarate_info(struct wlan_objmgr_vdev * vdev,uint8_t * mac_addr,wlan_node_info * node_info)1773 QDF_STATUS os_if_son_get_node_datarate_info(struct wlan_objmgr_vdev *vdev,
1774 					    uint8_t *mac_addr,
1775 					    wlan_node_info *node_info)
1776 {
1777 	int8_t max_tx_power;
1778 	int8_t min_tx_power;
1779 	struct wlan_objmgr_psoc *psoc;
1780 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1781 
1782 	psoc = wlan_vdev_get_psoc(vdev);
1783 	if (!psoc) {
1784 		osif_err("null posc");
1785 		return QDF_STATUS_E_INVAL;
1786 	}
1787 
1788 	if (WLAN_ADDR_EQ(wlan_vdev_mlme_get_macaddr(vdev), mac_addr) ==
1789 							   QDF_STATUS_SUCCESS) {
1790 		node_info->max_chwidth = os_if_son_get_chwidth(vdev);
1791 		node_info->phymode = os_if_son_get_phymode(vdev);
1792 		node_info->num_streams = os_if_son_get_rx_streams(vdev);
1793 		ucfg_son_get_min_and_max_power(psoc, &max_tx_power,
1794 					       &min_tx_power);
1795 		node_info->max_txpower = max_tx_power;
1796 		node_info->max_MCS = ucfg_mlme_get_vdev_max_mcs_idx(vdev);
1797 		if (node_info->max_MCS == INVALID_MCS_NSS_INDEX) {
1798 			osif_err("invalid mcs index");
1799 			return QDF_STATUS_E_INVAL;
1800 		}
1801 		osif_debug("node info: max_chwidth: %u, phymode: %u, num_streams: %d, max_mcs: %d, max_txpower: %d",
1802 			   node_info->max_chwidth, node_info->phymode,
1803 			   node_info->num_streams, node_info->max_MCS,
1804 			   node_info->max_txpower);
1805 	} else {
1806 		if (!g_son_os_if_cb.os_if_get_node_info) {
1807 			osif_err("Callback not registered");
1808 			return QDF_STATUS_E_INVAL;
1809 		}
1810 		status = g_son_os_if_cb.os_if_get_node_info(vdev, mac_addr,
1811 							    node_info);
1812 	}
1813 	return status;
1814 }
1815 
1816 qdf_export_symbol(os_if_son_get_node_datarate_info);
1817 
os_if_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)1818 uint32_t os_if_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev *vdev,
1819 					struct wlan_objmgr_peer *peer)
1820 {
1821 	if (g_son_os_if_cb.os_if_get_peer_max_mcs_idx)
1822 		return g_son_os_if_cb.os_if_get_peer_max_mcs_idx(vdev, peer);
1823 
1824 	return 0;
1825 }
1826 
os_if_son_get_sta_stats(struct wlan_objmgr_vdev * vdev,uint8_t * mac_addr,struct ieee80211_nodestats * stats)1827 int os_if_son_get_sta_stats(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr,
1828 			    struct ieee80211_nodestats *stats)
1829 {
1830 	if (g_son_os_if_cb.os_if_get_sta_stats)
1831 		return g_son_os_if_cb.os_if_get_sta_stats(vdev, mac_addr,
1832 							  stats);
1833 
1834 	return 0;
1835 }
1836 qdf_export_symbol(os_if_son_get_sta_stats);
1837