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, ®_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, ®_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, ¶m, 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