xref: /wlan-driver/qcacld-3.0/core/hdd/src/wlan_hdd_son.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name 
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name /**
19*5113495bSYour Name  * DOC: contains son hdd API implementation
20*5113495bSYour Name  */
21*5113495bSYour Name 
22*5113495bSYour Name #include <qdf_types.h>
23*5113495bSYour Name #include <wlan_hdd_main.h>
24*5113495bSYour Name #include <wlan_hdd_sta_info.h>
25*5113495bSYour Name #include <wlan_hdd_regulatory.h>
26*5113495bSYour Name #include <os_if_son.h>
27*5113495bSYour Name #include <sap_internal.h>
28*5113495bSYour Name #include <wma_api.h>
29*5113495bSYour Name #include <wlan_hdd_hostapd.h>
30*5113495bSYour Name #include <wlan_reg_services_api.h>
31*5113495bSYour Name #include <son_ucfg_api.h>
32*5113495bSYour Name #include <wlan_hdd_son.h>
33*5113495bSYour Name #include <wlan_hdd_object_manager.h>
34*5113495bSYour Name #include <wlan_hdd_stats.h>
35*5113495bSYour Name #include "wlan_cfg80211_mc_cp_stats.h"
36*5113495bSYour Name 
37*5113495bSYour Name static const struct son_chan_width {
38*5113495bSYour Name 	enum ieee80211_cwm_width son_chwidth;
39*5113495bSYour Name 	enum phy_ch_width phy_chwidth;
40*5113495bSYour Name } son_chwidth_info[] = {
41*5113495bSYour Name 	{
42*5113495bSYour Name 		.son_chwidth = IEEE80211_CWM_WIDTH20,
43*5113495bSYour Name 		.phy_chwidth = CH_WIDTH_20MHZ,
44*5113495bSYour Name 	},
45*5113495bSYour Name 	{
46*5113495bSYour Name 		.son_chwidth = IEEE80211_CWM_WIDTH40,
47*5113495bSYour Name 		.phy_chwidth = CH_WIDTH_40MHZ,
48*5113495bSYour Name 	},
49*5113495bSYour Name 	{
50*5113495bSYour Name 		.son_chwidth = IEEE80211_CWM_WIDTH80,
51*5113495bSYour Name 		.phy_chwidth = CH_WIDTH_80MHZ,
52*5113495bSYour Name 	},
53*5113495bSYour Name 	{
54*5113495bSYour Name 		.son_chwidth = IEEE80211_CWM_WIDTH160,
55*5113495bSYour Name 		.phy_chwidth = CH_WIDTH_160MHZ,
56*5113495bSYour Name 	},
57*5113495bSYour Name 	{
58*5113495bSYour Name 		.son_chwidth = IEEE80211_CWM_WIDTH80_80,
59*5113495bSYour Name 		.phy_chwidth = CH_WIDTH_80P80MHZ,
60*5113495bSYour Name 	},
61*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
62*5113495bSYour Name 	{
63*5113495bSYour Name 		.son_chwidth = IEEE80211_CWM_WIDTH320,
64*5113495bSYour Name 		.phy_chwidth = CH_WIDTH_320MHZ,
65*5113495bSYour Name 	},
66*5113495bSYour Name #endif
67*5113495bSYour Name };
68*5113495bSYour Name 
69*5113495bSYour Name /**
70*5113495bSYour Name  * hdd_son_is_acs_in_progress() - whether acs is in progress or not
71*5113495bSYour Name  * @vdev: vdev
72*5113495bSYour Name  *
73*5113495bSYour Name  * Return: true if acs is in progress
74*5113495bSYour Name  */
hdd_son_is_acs_in_progress(struct wlan_objmgr_vdev * vdev)75*5113495bSYour Name static uint32_t hdd_son_is_acs_in_progress(struct wlan_objmgr_vdev *vdev)
76*5113495bSYour Name {
77*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
78*5113495bSYour Name 	bool in_progress = false;
79*5113495bSYour Name 
80*5113495bSYour Name 	if (!vdev) {
81*5113495bSYour Name 		hdd_err("null vdev");
82*5113495bSYour Name 		return in_progress;
83*5113495bSYour Name 	}
84*5113495bSYour Name 
85*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
86*5113495bSYour Name 	if (!link_info) {
87*5113495bSYour Name 		hdd_err("null adapter");
88*5113495bSYour Name 		return in_progress;
89*5113495bSYour Name 	}
90*5113495bSYour Name 
91*5113495bSYour Name 	if (!hdd_adapter_is_ap(link_info->adapter)) {
92*5113495bSYour Name 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
93*5113495bSYour Name 		return in_progress;
94*5113495bSYour Name 	}
95*5113495bSYour Name 
96*5113495bSYour Name 	in_progress = qdf_atomic_read(&link_info->session.ap.acs_in_progress);
97*5113495bSYour Name 
98*5113495bSYour Name 	return in_progress;
99*5113495bSYour Name }
100*5113495bSYour Name 
101*5113495bSYour Name /**
102*5113495bSYour Name  * hdd_son_chan_width_to_chan_width() - translate son chan width
103*5113495bSYour Name  *                                      to mac chan width
104*5113495bSYour Name  * @son_chwidth: son chan width
105*5113495bSYour Name  *
106*5113495bSYour Name  * Return: mac chan width
107*5113495bSYour Name  */
hdd_son_chan_width_to_chan_width(enum ieee80211_cwm_width son_chwidth)108*5113495bSYour Name static enum eSirMacHTChannelWidth hdd_son_chan_width_to_chan_width(
109*5113495bSYour Name 				enum ieee80211_cwm_width son_chwidth)
110*5113495bSYour Name {
111*5113495bSYour Name 	enum eSirMacHTChannelWidth chwidth;
112*5113495bSYour Name 
113*5113495bSYour Name 	switch (son_chwidth) {
114*5113495bSYour Name 	case IEEE80211_CWM_WIDTH20:
115*5113495bSYour Name 		chwidth = eHT_CHANNEL_WIDTH_20MHZ;
116*5113495bSYour Name 		break;
117*5113495bSYour Name 	case IEEE80211_CWM_WIDTH40:
118*5113495bSYour Name 		chwidth = eHT_CHANNEL_WIDTH_40MHZ;
119*5113495bSYour Name 		break;
120*5113495bSYour Name 	case IEEE80211_CWM_WIDTH80:
121*5113495bSYour Name 		chwidth = eHT_CHANNEL_WIDTH_80MHZ;
122*5113495bSYour Name 		break;
123*5113495bSYour Name 	case IEEE80211_CWM_WIDTH160:
124*5113495bSYour Name 		chwidth = eHT_CHANNEL_WIDTH_160MHZ;
125*5113495bSYour Name 		break;
126*5113495bSYour Name 	case IEEE80211_CWM_WIDTH80_80:
127*5113495bSYour Name 		chwidth = eHT_CHANNEL_WIDTH_80P80MHZ;
128*5113495bSYour Name 		break;
129*5113495bSYour Name 	default:
130*5113495bSYour Name 		chwidth = eHT_MAX_CHANNEL_WIDTH;
131*5113495bSYour Name 	}
132*5113495bSYour Name 
133*5113495bSYour Name 	return chwidth;
134*5113495bSYour Name }
135*5113495bSYour Name 
136*5113495bSYour Name /**
137*5113495bSYour Name  * hdd_son_set_chwidth() - set son chan width
138*5113495bSYour Name  * @vdev: vdev
139*5113495bSYour Name  * @son_chwidth: son chan width
140*5113495bSYour Name  *
141*5113495bSYour Name  * Return: 0 on success, negative errno on failure
142*5113495bSYour Name  */
hdd_son_set_chwidth(struct wlan_objmgr_vdev * vdev,enum ieee80211_cwm_width son_chwidth)143*5113495bSYour Name static int hdd_son_set_chwidth(struct wlan_objmgr_vdev *vdev,
144*5113495bSYour Name 			       enum ieee80211_cwm_width son_chwidth)
145*5113495bSYour Name {
146*5113495bSYour Name 	enum eSirMacHTChannelWidth chwidth;
147*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
148*5113495bSYour Name 	uint8_t link_id = 0xFF;
149*5113495bSYour Name 
150*5113495bSYour Name 	if (!vdev) {
151*5113495bSYour Name 		hdd_err("null vdev");
152*5113495bSYour Name 		return -EINVAL;
153*5113495bSYour Name 	}
154*5113495bSYour Name 
155*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
156*5113495bSYour Name 	if (!link_info) {
157*5113495bSYour Name 		hdd_err("null adapter for %d", wlan_vdev_get_id(vdev));
158*5113495bSYour Name 		return -EINVAL;
159*5113495bSYour Name 	}
160*5113495bSYour Name 
161*5113495bSYour Name 	chwidth = hdd_son_chan_width_to_chan_width(son_chwidth);
162*5113495bSYour Name 
163*5113495bSYour Name 	return hdd_set_mac_chan_width(link_info, chwidth, link_id, false);
164*5113495bSYour Name }
165*5113495bSYour Name 
166*5113495bSYour Name /**
167*5113495bSYour Name  * hdd_chan_width_to_son_chwidth() - translate mac chan width
168*5113495bSYour Name  *                                   to son chan width
169*5113495bSYour Name  * @chwidth: mac chan width
170*5113495bSYour Name  *
171*5113495bSYour Name  * Return: son chan width
172*5113495bSYour Name  */
hdd_chan_width_to_son_chwidth(enum eSirMacHTChannelWidth chwidth)173*5113495bSYour Name static enum ieee80211_cwm_width hdd_chan_width_to_son_chwidth(
174*5113495bSYour Name 				enum eSirMacHTChannelWidth chwidth)
175*5113495bSYour Name {
176*5113495bSYour Name 	enum ieee80211_cwm_width son_chwidth;
177*5113495bSYour Name 
178*5113495bSYour Name 	switch (chwidth) {
179*5113495bSYour Name 	case eHT_CHANNEL_WIDTH_20MHZ:
180*5113495bSYour Name 		son_chwidth = IEEE80211_CWM_WIDTH20;
181*5113495bSYour Name 		break;
182*5113495bSYour Name 	case eHT_CHANNEL_WIDTH_40MHZ:
183*5113495bSYour Name 		son_chwidth = IEEE80211_CWM_WIDTH40;
184*5113495bSYour Name 		break;
185*5113495bSYour Name 	case eHT_CHANNEL_WIDTH_80MHZ:
186*5113495bSYour Name 		son_chwidth = IEEE80211_CWM_WIDTH80;
187*5113495bSYour Name 		break;
188*5113495bSYour Name 	case eHT_CHANNEL_WIDTH_160MHZ:
189*5113495bSYour Name 		son_chwidth = IEEE80211_CWM_WIDTH160;
190*5113495bSYour Name 		break;
191*5113495bSYour Name 	case eHT_CHANNEL_WIDTH_80P80MHZ:
192*5113495bSYour Name 		son_chwidth = IEEE80211_CWM_WIDTH80_80;
193*5113495bSYour Name 		break;
194*5113495bSYour Name 	default:
195*5113495bSYour Name 		son_chwidth = IEEE80211_CWM_WIDTHINVALID;
196*5113495bSYour Name 	}
197*5113495bSYour Name 
198*5113495bSYour Name 	return son_chwidth;
199*5113495bSYour Name }
200*5113495bSYour Name 
201*5113495bSYour Name /**
202*5113495bSYour Name  * hdd_phy_chwidth_to_son_chwidth() - translate phy chan width
203*5113495bSYour Name  *                                    to son chan width
204*5113495bSYour Name  * @chwidth: phy chan width
205*5113495bSYour Name  *
206*5113495bSYour Name  * Return: son chan width
207*5113495bSYour Name  */
208*5113495bSYour Name static enum ieee80211_cwm_width
hdd_phy_chwidth_to_son_chwidth(enum phy_ch_width chwidth)209*5113495bSYour Name hdd_phy_chwidth_to_son_chwidth(enum phy_ch_width chwidth)
210*5113495bSYour Name {
211*5113495bSYour Name 	int i;
212*5113495bSYour Name 
213*5113495bSYour Name 	for (i = 0; i < ARRAY_SIZE(son_chwidth_info); i++) {
214*5113495bSYour Name 		if (son_chwidth_info[i].phy_chwidth == chwidth)
215*5113495bSYour Name 			return son_chwidth_info[i].son_chwidth;
216*5113495bSYour Name 	}
217*5113495bSYour Name 
218*5113495bSYour Name 	hdd_err("Unsupported channel width %d", chwidth);
219*5113495bSYour Name 	return IEEE80211_CWM_WIDTHINVALID;
220*5113495bSYour Name }
221*5113495bSYour Name 
222*5113495bSYour Name /**
223*5113495bSYour Name  * hdd_son_get_chwidth() - get chan width
224*5113495bSYour Name  * @vdev: vdev
225*5113495bSYour Name  *
226*5113495bSYour Name  * Return: son chan width
227*5113495bSYour Name  */
hdd_son_get_chwidth(struct wlan_objmgr_vdev * vdev)228*5113495bSYour Name static enum ieee80211_cwm_width hdd_son_get_chwidth(
229*5113495bSYour Name 						struct wlan_objmgr_vdev *vdev)
230*5113495bSYour Name {
231*5113495bSYour Name 	struct wlan_channel *des_chan;
232*5113495bSYour Name 
233*5113495bSYour Name 	if (!vdev) {
234*5113495bSYour Name 		hdd_err("null vdev");
235*5113495bSYour Name 		return IEEE80211_CWM_WIDTHINVALID;
236*5113495bSYour Name 	}
237*5113495bSYour Name 
238*5113495bSYour Name 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
239*5113495bSYour Name 
240*5113495bSYour Name 	return hdd_phy_chwidth_to_son_chwidth(des_chan->ch_width);
241*5113495bSYour Name }
242*5113495bSYour Name 
243*5113495bSYour Name /**
244*5113495bSYour Name  * hdd_son_chan_ext_offset_to_chan_type() - translate son chan extend offset
245*5113495bSYour Name  *                                          to chan type
246*5113495bSYour Name  * @son_chan_ext_offset: son chan ext offset
247*5113495bSYour Name  *
248*5113495bSYour Name  * Return: tSirMacHTChannelType
249*5113495bSYour Name  */
hdd_son_chan_ext_offset_to_chan_type(enum sec20_chan_offset son_chan_ext_offset)250*5113495bSYour Name static tSirMacHTChannelType hdd_son_chan_ext_offset_to_chan_type(
251*5113495bSYour Name 				enum sec20_chan_offset son_chan_ext_offset)
252*5113495bSYour Name {
253*5113495bSYour Name 	tSirMacHTChannelType chan_type;
254*5113495bSYour Name 
255*5113495bSYour Name 	switch (son_chan_ext_offset) {
256*5113495bSYour Name 	case EXT_CHAN_OFFSET_ABOVE:
257*5113495bSYour Name 		chan_type = eHT_CHAN_HT40PLUS;
258*5113495bSYour Name 		break;
259*5113495bSYour Name 	case EXT_CHAN_OFFSET_BELOW:
260*5113495bSYour Name 		chan_type = eHT_CHAN_HT40MINUS;
261*5113495bSYour Name 		break;
262*5113495bSYour Name 	default:
263*5113495bSYour Name 		chan_type = eHT_CHAN_HT20;
264*5113495bSYour Name 		break;
265*5113495bSYour Name 	}
266*5113495bSYour Name 
267*5113495bSYour Name 	return chan_type;
268*5113495bSYour Name }
269*5113495bSYour Name 
270*5113495bSYour Name /**
271*5113495bSYour Name  * hdd_son_set_chan_ext_offset() - set son chan extend offset
272*5113495bSYour Name  * @vdev: vdev
273*5113495bSYour Name  * @son_chan_ext_offset: son chan extend offset
274*5113495bSYour Name  *
275*5113495bSYour Name  * Return: 0 on success, negative errno on failure
276*5113495bSYour Name  */
hdd_son_set_chan_ext_offset(struct wlan_objmgr_vdev * vdev,enum sec20_chan_offset son_chan_ext_offset)277*5113495bSYour Name static int hdd_son_set_chan_ext_offset(
278*5113495bSYour Name 				struct wlan_objmgr_vdev *vdev,
279*5113495bSYour Name 				enum sec20_chan_offset son_chan_ext_offset)
280*5113495bSYour Name {
281*5113495bSYour Name 	enum eSirMacHTChannelType chan_type;
282*5113495bSYour Name 	QDF_STATUS status;
283*5113495bSYour Name 	int retval = -EINVAL;
284*5113495bSYour Name 	struct hdd_adapter *adapter;
285*5113495bSYour Name 
286*5113495bSYour Name 	if (!vdev) {
287*5113495bSYour Name 		hdd_err("null vdev");
288*5113495bSYour Name 		return retval;
289*5113495bSYour Name 	}
290*5113495bSYour Name 
291*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
292*5113495bSYour Name 	if (!link_info) {
293*5113495bSYour Name 		hdd_err("null adapter");
294*5113495bSYour Name 		return retval;
295*5113495bSYour Name 	}
296*5113495bSYour Name 
297*5113495bSYour Name 	if (!hdd_adapter_is_ap(link_info->adapter)) {
298*5113495bSYour Name 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
299*5113495bSYour Name 		return retval;
300*5113495bSYour Name 	}
301*5113495bSYour Name 
302*5113495bSYour Name 	retval = 0;
303*5113495bSYour Name 	chan_type = hdd_son_chan_ext_offset_to_chan_type(son_chan_ext_offset);
304*5113495bSYour Name 	status = hdd_set_sap_ht2040_mode(link_info->adapter, chan_type);
305*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
306*5113495bSYour Name 		hdd_err("Cannot set SAP HT20/40 mode!");
307*5113495bSYour Name 		retval = -EINVAL;
308*5113495bSYour Name 	}
309*5113495bSYour Name 
310*5113495bSYour Name 	return retval;
311*5113495bSYour Name }
312*5113495bSYour Name 
313*5113495bSYour Name /**
314*5113495bSYour Name  * hdd_chan_type_to_son_chan_ext_offset() - translate tSirMacHTChannelType
315*5113495bSYour Name  *                                          to son chan extend offset
316*5113495bSYour Name  * @chan_type: tSirMacHTChannelType
317*5113495bSYour Name  *
318*5113495bSYour Name  * Return: son chan extend offset
319*5113495bSYour Name  */
hdd_chan_type_to_son_chan_ext_offset(tSirMacHTChannelType chan_type)320*5113495bSYour Name static enum sec20_chan_offset hdd_chan_type_to_son_chan_ext_offset(
321*5113495bSYour Name 				tSirMacHTChannelType chan_type)
322*5113495bSYour Name {
323*5113495bSYour Name 	enum sec20_chan_offset son_chan_ext_offset;
324*5113495bSYour Name 
325*5113495bSYour Name 	switch (chan_type) {
326*5113495bSYour Name 	case eHT_CHAN_HT40PLUS:
327*5113495bSYour Name 		son_chan_ext_offset = EXT_CHAN_OFFSET_ABOVE;
328*5113495bSYour Name 		break;
329*5113495bSYour Name 	case eHT_CHAN_HT40MINUS:
330*5113495bSYour Name 		son_chan_ext_offset = EXT_CHAN_OFFSET_BELOW;
331*5113495bSYour Name 		break;
332*5113495bSYour Name 	default:
333*5113495bSYour Name 		son_chan_ext_offset = EXT_CHAN_OFFSET_NA;
334*5113495bSYour Name 		break;
335*5113495bSYour Name 	}
336*5113495bSYour Name 
337*5113495bSYour Name 	return son_chan_ext_offset;
338*5113495bSYour Name }
339*5113495bSYour Name 
340*5113495bSYour Name /**
341*5113495bSYour Name  * hdd_son_get_chan_ext_offset() - get chan extend offset
342*5113495bSYour Name  * @vdev: vdev
343*5113495bSYour Name  *
344*5113495bSYour Name  * Return: enum sec20_chan_offset
345*5113495bSYour Name  */
hdd_son_get_chan_ext_offset(struct wlan_objmgr_vdev * vdev)346*5113495bSYour Name static enum sec20_chan_offset hdd_son_get_chan_ext_offset(
347*5113495bSYour Name 						struct wlan_objmgr_vdev *vdev)
348*5113495bSYour Name {
349*5113495bSYour Name 	enum eSirMacHTChannelType chan_type;
350*5113495bSYour Name 	QDF_STATUS status;
351*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
352*5113495bSYour Name 
353*5113495bSYour Name 	if (!vdev) {
354*5113495bSYour Name 		hdd_err("null vdev");
355*5113495bSYour Name 		return 0;
356*5113495bSYour Name 	}
357*5113495bSYour Name 
358*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
359*5113495bSYour Name 	if (!link_info) {
360*5113495bSYour Name 		hdd_err("null adapter");
361*5113495bSYour Name 		return 0;
362*5113495bSYour Name 	}
363*5113495bSYour Name 
364*5113495bSYour Name 	if (!hdd_adapter_is_ap(link_info->adapter)) {
365*5113495bSYour Name 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
366*5113495bSYour Name 		return 0;
367*5113495bSYour Name 	}
368*5113495bSYour Name 
369*5113495bSYour Name 	status = hdd_get_sap_ht2040_mode(link_info->adapter, &chan_type);
370*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
371*5113495bSYour Name 		hdd_err("Cannot set SAP HT20/40 mode!");
372*5113495bSYour Name 		return 0;
373*5113495bSYour Name 	}
374*5113495bSYour Name 
375*5113495bSYour Name 	return hdd_chan_type_to_son_chan_ext_offset(chan_type);
376*5113495bSYour Name }
377*5113495bSYour Name 
378*5113495bSYour Name /**
379*5113495bSYour Name  * hdd_son_bandwidth_to_phymode() - get new eCsrPhyMode according
380*5113495bSYour Name  *                                  to son band width
381*5113495bSYour Name  * @son_bandwidth: son band width
382*5113495bSYour Name  * @old_phymode: old eCsrPhyMode
383*5113495bSYour Name  * @phymode: new eCsrPhyMode to get
384*5113495bSYour Name  *
385*5113495bSYour Name  * Return: void
386*5113495bSYour Name  */
hdd_son_bandwidth_to_phymode(uint32_t son_bandwidth,eCsrPhyMode old_phymode,eCsrPhyMode * phymode)387*5113495bSYour Name static void hdd_son_bandwidth_to_phymode(uint32_t son_bandwidth,
388*5113495bSYour Name 					 eCsrPhyMode old_phymode,
389*5113495bSYour Name 					 eCsrPhyMode *phymode)
390*5113495bSYour Name {
391*5113495bSYour Name 	*phymode = old_phymode;
392*5113495bSYour Name 
393*5113495bSYour Name 	switch (son_bandwidth) {
394*5113495bSYour Name 	case HT20:
395*5113495bSYour Name 	case HT40:
396*5113495bSYour Name 		*phymode = eCSR_DOT11_MODE_11n;
397*5113495bSYour Name 		break;
398*5113495bSYour Name 	case VHT20:
399*5113495bSYour Name 	case VHT40:
400*5113495bSYour Name 	case VHT80:
401*5113495bSYour Name 	case VHT160:
402*5113495bSYour Name 	case VHT80_80:
403*5113495bSYour Name 		*phymode = eCSR_DOT11_MODE_11ac;
404*5113495bSYour Name 		break;
405*5113495bSYour Name 	case HE20:
406*5113495bSYour Name 	case HE40:
407*5113495bSYour Name 	case HE80:
408*5113495bSYour Name 	case HE160:
409*5113495bSYour Name 	case HE80_80:
410*5113495bSYour Name 		*phymode = eCSR_DOT11_MODE_11ax;
411*5113495bSYour Name 		break;
412*5113495bSYour Name 	default:
413*5113495bSYour Name 		break;
414*5113495bSYour Name 	}
415*5113495bSYour Name }
416*5113495bSYour Name 
417*5113495bSYour Name /**
418*5113495bSYour Name  * hdd_son_bandwidth_to_bonding_mode() - son band with to bonding mode
419*5113495bSYour Name  * @son_bandwidth: son band width
420*5113495bSYour Name  * @bonding_mode: bonding mode to get
421*5113495bSYour Name  *
422*5113495bSYour Name  * Return: void
423*5113495bSYour Name  */
hdd_son_bandwidth_to_bonding_mode(uint32_t son_bandwidth,uint32_t * bonding_mode)424*5113495bSYour Name static void hdd_son_bandwidth_to_bonding_mode(uint32_t son_bandwidth,
425*5113495bSYour Name 					      uint32_t *bonding_mode)
426*5113495bSYour Name {
427*5113495bSYour Name 	switch (son_bandwidth) {
428*5113495bSYour Name 	case HT40:
429*5113495bSYour Name 	case VHT40:
430*5113495bSYour Name 	case VHT80:
431*5113495bSYour Name 	case VHT160:
432*5113495bSYour Name 	case VHT80_80:
433*5113495bSYour Name 	case HE40:
434*5113495bSYour Name 	case HE80:
435*5113495bSYour Name 	case HE160:
436*5113495bSYour Name 	case HE80_80:
437*5113495bSYour Name 		*bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_ENABLE;
438*5113495bSYour Name 		break;
439*5113495bSYour Name 	default:
440*5113495bSYour Name 		*bonding_mode = WNI_CFG_CHANNEL_BONDING_MODE_DISABLE;
441*5113495bSYour Name 	}
442*5113495bSYour Name }
443*5113495bSYour Name 
444*5113495bSYour Name /**
445*5113495bSYour Name  * hdd_son_set_bandwidth() - set band width
446*5113495bSYour Name  * @vdev: vdev
447*5113495bSYour Name  * @son_bandwidth: son band width
448*5113495bSYour Name  *
449*5113495bSYour Name  * Return: 0 on success, negative errno on failure
450*5113495bSYour Name  */
hdd_son_set_bandwidth(struct wlan_objmgr_vdev * vdev,uint32_t son_bandwidth)451*5113495bSYour Name static int hdd_son_set_bandwidth(struct wlan_objmgr_vdev *vdev,
452*5113495bSYour Name 				 uint32_t son_bandwidth)
453*5113495bSYour Name {
454*5113495bSYour Name 	eCsrPhyMode phymode;
455*5113495bSYour Name 	eCsrPhyMode old_phymode;
456*5113495bSYour Name 	uint8_t supported_band;
457*5113495bSYour Name 	uint32_t bonding_mode;
458*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
459*5113495bSYour Name 	struct hdd_context *hdd_ctx;
460*5113495bSYour Name 
461*5113495bSYour Name 	if (!vdev) {
462*5113495bSYour Name 		hdd_err("null vdev");
463*5113495bSYour Name 		return -EINVAL;
464*5113495bSYour Name 	}
465*5113495bSYour Name 
466*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
467*5113495bSYour Name 	if (!link_info) {
468*5113495bSYour Name 		hdd_err("null adapter");
469*5113495bSYour Name 		return -EINVAL;
470*5113495bSYour Name 	}
471*5113495bSYour Name 
472*5113495bSYour Name 	hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
473*5113495bSYour Name 	if (!hdd_ctx) {
474*5113495bSYour Name 		hdd_err("null hdd ctx");
475*5113495bSYour Name 		return -EINVAL;
476*5113495bSYour Name 	}
477*5113495bSYour Name 	old_phymode = sme_get_phy_mode(hdd_ctx->mac_handle);
478*5113495bSYour Name 
479*5113495bSYour Name 	hdd_son_bandwidth_to_phymode(son_bandwidth, old_phymode, &phymode);
480*5113495bSYour Name 
481*5113495bSYour Name 	if (wlan_reg_is_6ghz_supported(hdd_ctx->psoc))
482*5113495bSYour Name 		supported_band = REG_BAND_MASK_ALL;
483*5113495bSYour Name 	else
484*5113495bSYour Name 		supported_band = BIT(REG_BAND_2G) | BIT(REG_BAND_5G);
485*5113495bSYour Name 
486*5113495bSYour Name 	hdd_son_bandwidth_to_bonding_mode(son_bandwidth, &bonding_mode);
487*5113495bSYour Name 
488*5113495bSYour Name 	return hdd_update_phymode(link_info->adapter, phymode,
489*5113495bSYour Name 				  supported_band, bonding_mode);
490*5113495bSYour Name }
491*5113495bSYour Name 
492*5113495bSYour Name /**
493*5113495bSYour Name  * hdd_phymode_chwidth_to_son_bandwidth() - get son bandwidth from
494*5113495bSYour Name  *                                          phymode and chwidth
495*5113495bSYour Name  * @phymode: eCsrPhyMode
496*5113495bSYour Name  * @chwidth: eSirMacHTChannelWidth
497*5113495bSYour Name  *
498*5113495bSYour Name  * Return: son bandwidth
499*5113495bSYour Name  */
hdd_phymode_chwidth_to_son_bandwidth(eCsrPhyMode phymode,enum eSirMacHTChannelWidth chwidth)500*5113495bSYour Name static uint32_t hdd_phymode_chwidth_to_son_bandwidth(
501*5113495bSYour Name 					eCsrPhyMode phymode,
502*5113495bSYour Name 					enum eSirMacHTChannelWidth chwidth)
503*5113495bSYour Name {
504*5113495bSYour Name 	uint32_t son_bandwidth = NONHT;
505*5113495bSYour Name 
506*5113495bSYour Name 	switch (phymode) {
507*5113495bSYour Name 	case eCSR_DOT11_MODE_abg:
508*5113495bSYour Name 	case eCSR_DOT11_MODE_11a:
509*5113495bSYour Name 	case eCSR_DOT11_MODE_11b:
510*5113495bSYour Name 	case eCSR_DOT11_MODE_11g:
511*5113495bSYour Name 	case eCSR_DOT11_MODE_11g_ONLY:
512*5113495bSYour Name 	case eCSR_DOT11_MODE_11b_ONLY:
513*5113495bSYour Name 		son_bandwidth = NONHT;
514*5113495bSYour Name 		break;
515*5113495bSYour Name 	case eCSR_DOT11_MODE_11n:
516*5113495bSYour Name 	case eCSR_DOT11_MODE_11n_ONLY:
517*5113495bSYour Name 		son_bandwidth = HT20;
518*5113495bSYour Name 		if (chwidth == eHT_CHANNEL_WIDTH_40MHZ)
519*5113495bSYour Name 			son_bandwidth = HT40;
520*5113495bSYour Name 		break;
521*5113495bSYour Name 	case eCSR_DOT11_MODE_11ac:
522*5113495bSYour Name 	case eCSR_DOT11_MODE_11ac_ONLY:
523*5113495bSYour Name 		son_bandwidth = VHT20;
524*5113495bSYour Name 		if (chwidth == eHT_CHANNEL_WIDTH_40MHZ)
525*5113495bSYour Name 			son_bandwidth = VHT40;
526*5113495bSYour Name 		else if (chwidth == eHT_CHANNEL_WIDTH_80MHZ)
527*5113495bSYour Name 			son_bandwidth = VHT80;
528*5113495bSYour Name 		else if (chwidth == eHT_CHANNEL_WIDTH_160MHZ)
529*5113495bSYour Name 			son_bandwidth = VHT160;
530*5113495bSYour Name 		else if (chwidth == eHT_CHANNEL_WIDTH_80P80MHZ)
531*5113495bSYour Name 			son_bandwidth = VHT80_80;
532*5113495bSYour Name 		break;
533*5113495bSYour Name 	case eCSR_DOT11_MODE_11ax:
534*5113495bSYour Name 	case eCSR_DOT11_MODE_11ax_ONLY:
535*5113495bSYour Name 	case eCSR_DOT11_MODE_AUTO:
536*5113495bSYour Name 		son_bandwidth = HE20;
537*5113495bSYour Name 		if (chwidth == eHT_CHANNEL_WIDTH_40MHZ)
538*5113495bSYour Name 			son_bandwidth = HE40;
539*5113495bSYour Name 		else if (chwidth == eHT_CHANNEL_WIDTH_80MHZ)
540*5113495bSYour Name 			son_bandwidth = HE80;
541*5113495bSYour Name 		else if (chwidth == eHT_CHANNEL_WIDTH_160MHZ)
542*5113495bSYour Name 			son_bandwidth = HE160;
543*5113495bSYour Name 		else if (chwidth == eHT_CHANNEL_WIDTH_80P80MHZ)
544*5113495bSYour Name 			son_bandwidth = HE80_80;
545*5113495bSYour Name 		break;
546*5113495bSYour Name 	default:
547*5113495bSYour Name 		break;
548*5113495bSYour Name 	}
549*5113495bSYour Name 
550*5113495bSYour Name 	return son_bandwidth;
551*5113495bSYour Name }
552*5113495bSYour Name 
553*5113495bSYour Name /**
554*5113495bSYour Name  * hdd_son_get_bandwidth() - get band width
555*5113495bSYour Name  * @vdev: vdev
556*5113495bSYour Name  *
557*5113495bSYour Name  * Return: band width
558*5113495bSYour Name  */
hdd_son_get_bandwidth(struct wlan_objmgr_vdev * vdev)559*5113495bSYour Name static uint32_t hdd_son_get_bandwidth(struct wlan_objmgr_vdev *vdev)
560*5113495bSYour Name {
561*5113495bSYour Name 	enum eSirMacHTChannelWidth chwidth;
562*5113495bSYour Name 	eCsrPhyMode phymode;
563*5113495bSYour Name 	struct hdd_context *hdd_ctx;
564*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
565*5113495bSYour Name 
566*5113495bSYour Name 	if (!vdev) {
567*5113495bSYour Name 		hdd_err("null vdev");
568*5113495bSYour Name 		return NONHT;
569*5113495bSYour Name 	}
570*5113495bSYour Name 
571*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
572*5113495bSYour Name 	if (!link_info) {
573*5113495bSYour Name 		hdd_err("null adapter");
574*5113495bSYour Name 		return NONHT;
575*5113495bSYour Name 	}
576*5113495bSYour Name 
577*5113495bSYour Name 	chwidth = wma_cli_get_command(link_info->vdev_id,
578*5113495bSYour Name 				      wmi_vdev_param_chwidth, VDEV_CMD);
579*5113495bSYour Name 
580*5113495bSYour Name 	if (chwidth < 0) {
581*5113495bSYour Name 		hdd_err("Failed to get chwidth");
582*5113495bSYour Name 		return NONHT;
583*5113495bSYour Name 	}
584*5113495bSYour Name 
585*5113495bSYour Name 	hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
586*5113495bSYour Name 	if (!hdd_ctx) {
587*5113495bSYour Name 		hdd_err("null hdd ctx");
588*5113495bSYour Name 		return -NONHT;
589*5113495bSYour Name 	}
590*5113495bSYour Name 
591*5113495bSYour Name 	phymode = sme_get_phy_mode(hdd_ctx->mac_handle);
592*5113495bSYour Name 
593*5113495bSYour Name 	return hdd_phymode_chwidth_to_son_bandwidth(phymode, chwidth);
594*5113495bSYour Name }
595*5113495bSYour Name 
596*5113495bSYour Name /**
597*5113495bSYour Name  * hdd_son_band_to_band() - translate SON band mode to reg_wifi_band
598*5113495bSYour Name  * @band: given enum wlan_band_id
599*5113495bSYour Name  *
600*5113495bSYour Name  * Return: reg_wifi_band
601*5113495bSYour Name  */
hdd_son_band_to_band(enum wlan_band_id band)602*5113495bSYour Name static enum reg_wifi_band hdd_son_band_to_band(enum wlan_band_id band)
603*5113495bSYour Name {
604*5113495bSYour Name 	enum reg_wifi_band reg_band = REG_BAND_UNKNOWN;
605*5113495bSYour Name 
606*5113495bSYour Name 	switch (band) {
607*5113495bSYour Name 	case WLAN_BAND_2GHZ:
608*5113495bSYour Name 		reg_band = REG_BAND_2G;
609*5113495bSYour Name 		break;
610*5113495bSYour Name 	case WLAN_BAND_5GHZ:
611*5113495bSYour Name 		reg_band = REG_BAND_5G;
612*5113495bSYour Name 		break;
613*5113495bSYour Name 	case WLAN_BAND_6GHZ:
614*5113495bSYour Name 		reg_band = REG_BAND_6G;
615*5113495bSYour Name 		break;
616*5113495bSYour Name 	default:
617*5113495bSYour Name 		break;
618*5113495bSYour Name 	}
619*5113495bSYour Name 
620*5113495bSYour Name 	return reg_band;
621*5113495bSYour Name }
622*5113495bSYour Name 
623*5113495bSYour Name /**
624*5113495bSYour Name  * hdd_son_set_chan() - set chan
625*5113495bSYour Name  * @vdev: vdev
626*5113495bSYour Name  * @chan: given chan
627*5113495bSYour Name  * @son_band: given enum wlan_band_id
628*5113495bSYour Name  *
629*5113495bSYour Name  * Return: 0 on success, negative errno on failure
630*5113495bSYour Name  */
hdd_son_set_chan(struct wlan_objmgr_vdev * vdev,int chan,enum wlan_band_id son_band)631*5113495bSYour Name static int hdd_son_set_chan(struct wlan_objmgr_vdev *vdev, int chan,
632*5113495bSYour Name 			    enum wlan_band_id son_band)
633*5113495bSYour Name {
634*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
635*5113495bSYour Name 	enum reg_wifi_band band = hdd_son_band_to_band(son_band);
636*5113495bSYour Name 	bool status;
637*5113495bSYour Name 	qdf_freq_t freq;
638*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
639*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
640*5113495bSYour Name 
641*5113495bSYour Name 	if (!vdev) {
642*5113495bSYour Name 		hdd_err("null vdev");
643*5113495bSYour Name 		return -EINVAL;
644*5113495bSYour Name 	}
645*5113495bSYour Name 
646*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
647*5113495bSYour Name 	if (!link_info) {
648*5113495bSYour Name 		hdd_err("null adapter");
649*5113495bSYour Name 		return -EINVAL;
650*5113495bSYour Name 	}
651*5113495bSYour Name 
652*5113495bSYour Name 	if (!hdd_adapter_is_ap(link_info->adapter)) {
653*5113495bSYour Name 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
654*5113495bSYour Name 		return -ENOTSUPP;
655*5113495bSYour Name 	}
656*5113495bSYour Name 
657*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
658*5113495bSYour Name 	if (!pdev) {
659*5113495bSYour Name 		hdd_err("null pdev");
660*5113495bSYour Name 		return -EINVAL;
661*5113495bSYour Name 	}
662*5113495bSYour Name 
663*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
664*5113495bSYour Name 	if (!psoc) {
665*5113495bSYour Name 		hdd_err("null psoc");
666*5113495bSYour Name 		return -EINVAL;
667*5113495bSYour Name 	}
668*5113495bSYour Name 
669*5113495bSYour Name 	freq = wlan_reg_chan_band_to_freq(pdev, chan, BIT(band));
670*5113495bSYour Name 	status = policy_mgr_is_sap_allowed_on_dfs_freq(pdev, link_info->vdev_id,
671*5113495bSYour Name 						       freq);
672*5113495bSYour Name 	if (!status) {
673*5113495bSYour Name 		hdd_err("sap_allowed_on_dfs_freq check fails");
674*5113495bSYour Name 		return -EINVAL;
675*5113495bSYour Name 	}
676*5113495bSYour Name 	wlan_hdd_set_sap_csa_reason(psoc, link_info->vdev_id,
677*5113495bSYour Name 				    CSA_REASON_USER_INITIATED);
678*5113495bSYour Name 
679*5113495bSYour Name 	return hdd_softap_set_channel_change(link_info->adapter->dev, freq,
680*5113495bSYour Name 					     CH_WIDTH_MAX, false);
681*5113495bSYour Name }
682*5113495bSYour Name 
683*5113495bSYour Name /**
684*5113495bSYour Name  * hdd_son_set_country() - set country code
685*5113495bSYour Name  * @vdev: vdev
686*5113495bSYour Name  * @country_code:pointer to country code
687*5113495bSYour Name  *
688*5113495bSYour Name  * Return: 0 if country code is set successfully
689*5113495bSYour Name  */
hdd_son_set_country(struct wlan_objmgr_vdev * vdev,char * country_code)690*5113495bSYour Name static int hdd_son_set_country(struct wlan_objmgr_vdev *vdev,
691*5113495bSYour Name 			       char *country_code)
692*5113495bSYour Name {
693*5113495bSYour Name 	struct hdd_context *hdd_ctx;
694*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
695*5113495bSYour Name 
696*5113495bSYour Name 	if (!vdev) {
697*5113495bSYour Name 		hdd_err("null vdev");
698*5113495bSYour Name 		return -EINVAL;
699*5113495bSYour Name 	}
700*5113495bSYour Name 
701*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
702*5113495bSYour Name 	if (!link_info) {
703*5113495bSYour Name 		hdd_err("null adapter");
704*5113495bSYour Name 		return -EINVAL;
705*5113495bSYour Name 	}
706*5113495bSYour Name 
707*5113495bSYour Name 	hdd_ctx = WLAN_HDD_GET_CTX(link_info->adapter);
708*5113495bSYour Name 	if (!hdd_ctx) {
709*5113495bSYour Name 		hdd_err("null hdd ctx");
710*5113495bSYour Name 		return -EINVAL;
711*5113495bSYour Name 	}
712*5113495bSYour Name 
713*5113495bSYour Name 	return hdd_reg_set_country(hdd_ctx, country_code);
714*5113495bSYour Name }
715*5113495bSYour Name 
716*5113495bSYour Name /**
717*5113495bSYour Name  * hdd_son_set_candidate_freq() - set candidate freq. Switch to this freq
718*5113495bSYour Name  *                                after radar is detected
719*5113495bSYour Name  * @vdev: vdev
720*5113495bSYour Name  * @freq: candidate frequency
721*5113495bSYour Name  *
722*5113495bSYour Name  * Return: 0 if candidate freq is set successfully.
723*5113495bSYour Name  */
hdd_son_set_candidate_freq(struct wlan_objmgr_vdev * vdev,qdf_freq_t freq)724*5113495bSYour Name static int hdd_son_set_candidate_freq(struct wlan_objmgr_vdev *vdev,
725*5113495bSYour Name 				      qdf_freq_t freq)
726*5113495bSYour Name {
727*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
728*5113495bSYour Name 	struct sap_context *sap_ctx;
729*5113495bSYour Name 
730*5113495bSYour Name 	if (!vdev) {
731*5113495bSYour Name 		hdd_err("null vdev");
732*5113495bSYour Name 		return -EINVAL;
733*5113495bSYour Name 	}
734*5113495bSYour Name 
735*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
736*5113495bSYour Name 	if (!link_info) {
737*5113495bSYour Name 		hdd_err("null adapter");
738*5113495bSYour Name 		return -EINVAL;
739*5113495bSYour Name 	}
740*5113495bSYour Name 	if (!hdd_adapter_is_ap(link_info->adapter)) {
741*5113495bSYour Name 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
742*5113495bSYour Name 		return -EINVAL;
743*5113495bSYour Name 	}
744*5113495bSYour Name 
745*5113495bSYour Name 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
746*5113495bSYour Name 	if (!sap_ctx) {
747*5113495bSYour Name 		hdd_err("null sap_ctx");
748*5113495bSYour Name 		return -EINVAL;
749*5113495bSYour Name 	}
750*5113495bSYour Name 
751*5113495bSYour Name 	sap_ctx->candidate_freq = freq;
752*5113495bSYour Name 
753*5113495bSYour Name 	return 0;
754*5113495bSYour Name }
755*5113495bSYour Name 
756*5113495bSYour Name /**
757*5113495bSYour Name  * hdd_son_get_candidate_freq() - get candidate freq
758*5113495bSYour Name  * @vdev: vdev
759*5113495bSYour Name  *
760*5113495bSYour Name  * Return: candidate freq
761*5113495bSYour Name  */
hdd_son_get_candidate_freq(struct wlan_objmgr_vdev * vdev)762*5113495bSYour Name static qdf_freq_t hdd_son_get_candidate_freq(struct wlan_objmgr_vdev *vdev)
763*5113495bSYour Name {
764*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
765*5113495bSYour Name 	struct sap_context *sap_ctx;
766*5113495bSYour Name 	qdf_freq_t freq = 0;
767*5113495bSYour Name 
768*5113495bSYour Name 	if (!vdev) {
769*5113495bSYour Name 		hdd_err("null vdev");
770*5113495bSYour Name 		return freq;
771*5113495bSYour Name 	}
772*5113495bSYour Name 
773*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
774*5113495bSYour Name 	if (!link_info) {
775*5113495bSYour Name 		hdd_err("null adapter");
776*5113495bSYour Name 		return freq;
777*5113495bSYour Name 	}
778*5113495bSYour Name 	if (!hdd_adapter_is_ap(link_info->adapter)) {
779*5113495bSYour Name 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
780*5113495bSYour Name 		return freq;
781*5113495bSYour Name 	}
782*5113495bSYour Name 
783*5113495bSYour Name 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
784*5113495bSYour Name 	if (!sap_ctx) {
785*5113495bSYour Name 		hdd_err("null sap_ctx");
786*5113495bSYour Name 		return freq;
787*5113495bSYour Name 	}
788*5113495bSYour Name 	freq = sap_ctx->candidate_freq;
789*5113495bSYour Name 
790*5113495bSYour Name 	return freq;
791*5113495bSYour Name }
792*5113495bSYour Name 
793*5113495bSYour Name /**
794*5113495bSYour Name  * hdd_son_phy_mode_to_vendor_phy_mode() - translate son phy mode to
795*5113495bSYour Name  *                                         vendor_phy_mode
796*5113495bSYour Name  * @mode: son phy mode
797*5113495bSYour Name  *
798*5113495bSYour Name  * Return: qca_wlan_vendor_phy_mode
799*5113495bSYour Name  */
hdd_son_phy_mode_to_vendor_phy_mode(enum ieee80211_phymode mode)800*5113495bSYour Name static enum qca_wlan_vendor_phy_mode hdd_son_phy_mode_to_vendor_phy_mode(
801*5113495bSYour Name 						enum ieee80211_phymode mode)
802*5113495bSYour Name {
803*5113495bSYour Name 	enum qca_wlan_vendor_phy_mode vendor_mode;
804*5113495bSYour Name 
805*5113495bSYour Name 	switch (mode) {
806*5113495bSYour Name 	case IEEE80211_MODE_AUTO:
807*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_AUTO;
808*5113495bSYour Name 		break;
809*5113495bSYour Name 	case IEEE80211_MODE_11A:
810*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11A;
811*5113495bSYour Name 		break;
812*5113495bSYour Name 	case IEEE80211_MODE_11B:
813*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11B;
814*5113495bSYour Name 		break;
815*5113495bSYour Name 	case IEEE80211_MODE_11G:
816*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11G;
817*5113495bSYour Name 		break;
818*5113495bSYour Name 	case IEEE80211_MODE_11NA_HT20:
819*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT20;
820*5113495bSYour Name 		break;
821*5113495bSYour Name 	case IEEE80211_MODE_11NG_HT20:
822*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT20;
823*5113495bSYour Name 		break;
824*5113495bSYour Name 	case IEEE80211_MODE_11NA_HT40PLUS:
825*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40PLUS;
826*5113495bSYour Name 		break;
827*5113495bSYour Name 	case IEEE80211_MODE_11NA_HT40MINUS:
828*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40MINUS;
829*5113495bSYour Name 		break;
830*5113495bSYour Name 	case IEEE80211_MODE_11NG_HT40PLUS:
831*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40PLUS;
832*5113495bSYour Name 		break;
833*5113495bSYour Name 	case IEEE80211_MODE_11NG_HT40MINUS:
834*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40MINUS;
835*5113495bSYour Name 		break;
836*5113495bSYour Name 	case IEEE80211_MODE_11NG_HT40:
837*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
838*5113495bSYour Name 		break;
839*5113495bSYour Name 	case IEEE80211_MODE_11NA_HT40:
840*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
841*5113495bSYour Name 		break;
842*5113495bSYour Name 	case IEEE80211_MODE_11AC_VHT20:
843*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT20;
844*5113495bSYour Name 		break;
845*5113495bSYour Name 	case IEEE80211_MODE_11AC_VHT40PLUS:
846*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40PLUS;
847*5113495bSYour Name 		break;
848*5113495bSYour Name 	case IEEE80211_MODE_11AC_VHT40MINUS:
849*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40MINUS;
850*5113495bSYour Name 		break;
851*5113495bSYour Name 	case IEEE80211_MODE_11AC_VHT40:
852*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT40;
853*5113495bSYour Name 		break;
854*5113495bSYour Name 	case IEEE80211_MODE_11AC_VHT80:
855*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
856*5113495bSYour Name 		break;
857*5113495bSYour Name 	case IEEE80211_MODE_11AC_VHT160:
858*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT160;
859*5113495bSYour Name 		break;
860*5113495bSYour Name 	case IEEE80211_MODE_11AC_VHT80_80:
861*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80P80;
862*5113495bSYour Name 		break;
863*5113495bSYour Name 	case IEEE80211_MODE_11AXA_HE20:
864*5113495bSYour Name 	case IEEE80211_MODE_11AXG_HE20:
865*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE20;
866*5113495bSYour Name 		break;
867*5113495bSYour Name 	case IEEE80211_MODE_11AXA_HE40PLUS:
868*5113495bSYour Name 	case IEEE80211_MODE_11AXG_HE40PLUS:
869*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40PLUS;
870*5113495bSYour Name 		break;
871*5113495bSYour Name 	case IEEE80211_MODE_11AXA_HE40MINUS:
872*5113495bSYour Name 	case IEEE80211_MODE_11AXG_HE40MINUS:
873*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40MINUS;
874*5113495bSYour Name 		break;
875*5113495bSYour Name 	case IEEE80211_MODE_11AXA_HE40:
876*5113495bSYour Name 	case IEEE80211_MODE_11AXG_HE40:
877*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE40;
878*5113495bSYour Name 		break;
879*5113495bSYour Name 	case IEEE80211_MODE_11AXA_HE80:
880*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80;
881*5113495bSYour Name 		break;
882*5113495bSYour Name 	case IEEE80211_MODE_11AXA_HE160:
883*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE160;
884*5113495bSYour Name 		break;
885*5113495bSYour Name 	case IEEE80211_MODE_11AXA_HE80_80:
886*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_11AX_HE80P80;
887*5113495bSYour Name 		break;
888*5113495bSYour Name 	default:
889*5113495bSYour Name 		hdd_err("Invalid config phy mode %d, set it as auto", mode);
890*5113495bSYour Name 		vendor_mode = QCA_WLAN_VENDOR_PHY_MODE_AUTO;
891*5113495bSYour Name 		break;
892*5113495bSYour Name 	}
893*5113495bSYour Name 
894*5113495bSYour Name 	return vendor_mode;
895*5113495bSYour Name }
896*5113495bSYour Name 
897*5113495bSYour Name /**
898*5113495bSYour Name  * hdd_son_set_phymode() - set son phy mode
899*5113495bSYour Name  * @vdev: vdev
900*5113495bSYour Name  * @mode: son phy mode to set
901*5113495bSYour Name  *
902*5113495bSYour Name  * Return: 0 on success, negative errno on failure
903*5113495bSYour Name  */
hdd_son_set_phymode(struct wlan_objmgr_vdev * vdev,enum ieee80211_phymode mode)904*5113495bSYour Name static int hdd_son_set_phymode(struct wlan_objmgr_vdev *vdev,
905*5113495bSYour Name 			       enum ieee80211_phymode mode)
906*5113495bSYour Name {
907*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
908*5113495bSYour Name 	enum qca_wlan_vendor_phy_mode vendor_phy_mode;
909*5113495bSYour Name 	QDF_STATUS status;
910*5113495bSYour Name 	struct hdd_ap_ctx *hdd_ap_ctx;
911*5113495bSYour Name 	struct sap_config *sap_config;
912*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
913*5113495bSYour Name 
914*5113495bSYour Name 	if (!vdev) {
915*5113495bSYour Name 		hdd_err("null vdev");
916*5113495bSYour Name 		return -EINVAL;
917*5113495bSYour Name 	}
918*5113495bSYour Name 
919*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
920*5113495bSYour Name 	if (!link_info) {
921*5113495bSYour Name 		hdd_err("Invalid VDEV %d", wlan_vdev_get_id(vdev));
922*5113495bSYour Name 		return -EINVAL;
923*5113495bSYour Name 	}
924*5113495bSYour Name 
925*5113495bSYour Name 	if (!hdd_adapter_is_ap(link_info->adapter)) {
926*5113495bSYour Name 		hdd_err("vdev id %d is not AP", link_info->vdev_id);
927*5113495bSYour Name 		return -EINVAL;
928*5113495bSYour Name 	}
929*5113495bSYour Name 
930*5113495bSYour Name 	vendor_phy_mode = hdd_son_phy_mode_to_vendor_phy_mode(mode);
931*5113495bSYour Name 
932*5113495bSYour Name 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(link_info);
933*5113495bSYour Name 	sap_config = &hdd_ap_ctx->sap_config;
934*5113495bSYour Name 	status = wlansap_son_update_sap_config_phymode(vdev, sap_config,
935*5113495bSYour Name 						       vendor_phy_mode);
936*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
937*5113495bSYour Name 		hdd_err("update son phy mode error");
938*5113495bSYour Name 		return -EINVAL;
939*5113495bSYour Name 	}
940*5113495bSYour Name 
941*5113495bSYour Name 	hdd_restart_sap(link_info);
942*5113495bSYour Name 
943*5113495bSYour Name 	return 0;
944*5113495bSYour Name }
945*5113495bSYour Name 
946*5113495bSYour Name /**
947*5113495bSYour Name  * hdd_wlan_phymode_to_son_phymode() - get son phymode from wlan_phymode phymode
948*5113495bSYour Name  * @phymode: wlan_phymode phymode
949*5113495bSYour Name  *
950*5113495bSYour Name  * Return: ieee80211_phymode
951*5113495bSYour Name  */
hdd_wlan_phymode_to_son_phymode(enum wlan_phymode phymode)952*5113495bSYour Name static enum ieee80211_phymode hdd_wlan_phymode_to_son_phymode(
953*5113495bSYour Name 					enum wlan_phymode phymode)
954*5113495bSYour Name {
955*5113495bSYour Name 	enum ieee80211_phymode son_phymode;
956*5113495bSYour Name 
957*5113495bSYour Name 	switch (phymode) {
958*5113495bSYour Name 	case WLAN_PHYMODE_AUTO:
959*5113495bSYour Name 		son_phymode = IEEE80211_MODE_AUTO;
960*5113495bSYour Name 		break;
961*5113495bSYour Name 	case WLAN_PHYMODE_11A:
962*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11A;
963*5113495bSYour Name 		break;
964*5113495bSYour Name 	case WLAN_PHYMODE_11B:
965*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11B;
966*5113495bSYour Name 		break;
967*5113495bSYour Name 	case WLAN_PHYMODE_11G:
968*5113495bSYour Name 	case WLAN_PHYMODE_11G_ONLY:
969*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11G;
970*5113495bSYour Name 		break;
971*5113495bSYour Name 	case WLAN_PHYMODE_11NA_HT20:
972*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11NA_HT20;
973*5113495bSYour Name 		break;
974*5113495bSYour Name 	case WLAN_PHYMODE_11NG_HT20:
975*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11NG_HT20;
976*5113495bSYour Name 		break;
977*5113495bSYour Name 	case WLAN_PHYMODE_11NA_HT40:
978*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11NA_HT40;
979*5113495bSYour Name 		break;
980*5113495bSYour Name 	case WLAN_PHYMODE_11NG_HT40PLUS:
981*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11NG_HT40PLUS;
982*5113495bSYour Name 		break;
983*5113495bSYour Name 	case WLAN_PHYMODE_11NG_HT40MINUS:
984*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11NG_HT40MINUS;
985*5113495bSYour Name 		break;
986*5113495bSYour Name 	case WLAN_PHYMODE_11NG_HT40:
987*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11NG_HT40;
988*5113495bSYour Name 		break;
989*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT20:
990*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT20_2G:
991*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AC_VHT20;
992*5113495bSYour Name 		break;
993*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT40:
994*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT40_2G:
995*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AC_VHT40;
996*5113495bSYour Name 		break;
997*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT40PLUS_2G:
998*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AC_VHT40PLUS;
999*5113495bSYour Name 		break;
1000*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT40MINUS_2G:
1001*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AC_VHT40MINUS;
1002*5113495bSYour Name 		break;
1003*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT80:
1004*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT80_2G:
1005*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AC_VHT80;
1006*5113495bSYour Name 		break;
1007*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT160:
1008*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AC_VHT160;
1009*5113495bSYour Name 		break;
1010*5113495bSYour Name 	case WLAN_PHYMODE_11AC_VHT80_80:
1011*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AC_VHT80_80;
1012*5113495bSYour Name 		break;
1013*5113495bSYour Name 	case WLAN_PHYMODE_11AXA_HE20:
1014*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXA_HE20;
1015*5113495bSYour Name 		break;
1016*5113495bSYour Name 	case WLAN_PHYMODE_11AXG_HE20:
1017*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXG_HE20;
1018*5113495bSYour Name 		break;
1019*5113495bSYour Name 	case WLAN_PHYMODE_11AXA_HE40:
1020*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXA_HE40;
1021*5113495bSYour Name 		break;
1022*5113495bSYour Name 	case WLAN_PHYMODE_11AXG_HE40PLUS:
1023*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXG_HE40PLUS;
1024*5113495bSYour Name 		break;
1025*5113495bSYour Name 	case WLAN_PHYMODE_11AXG_HE40MINUS:
1026*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXG_HE40MINUS;
1027*5113495bSYour Name 		break;
1028*5113495bSYour Name 	case WLAN_PHYMODE_11AXG_HE40:
1029*5113495bSYour Name 	case WLAN_PHYMODE_11AXG_HE80:
1030*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXG_HE40;
1031*5113495bSYour Name 		break;
1032*5113495bSYour Name 	case WLAN_PHYMODE_11AXA_HE80:
1033*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXA_HE80;
1034*5113495bSYour Name 		break;
1035*5113495bSYour Name 	case WLAN_PHYMODE_11AXA_HE160:
1036*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXA_HE160;
1037*5113495bSYour Name 		break;
1038*5113495bSYour Name 	case WLAN_PHYMODE_11AXA_HE80_80:
1039*5113495bSYour Name 		son_phymode = IEEE80211_MODE_11AXA_HE80_80;
1040*5113495bSYour Name 		break;
1041*5113495bSYour Name 	default:
1042*5113495bSYour Name 		son_phymode = IEEE80211_MODE_AUTO;
1043*5113495bSYour Name 		break;
1044*5113495bSYour Name 	}
1045*5113495bSYour Name 
1046*5113495bSYour Name 	return son_phymode;
1047*5113495bSYour Name }
1048*5113495bSYour Name 
1049*5113495bSYour Name /**
1050*5113495bSYour Name  * hdd_son_get_phymode() - get son phy mode
1051*5113495bSYour Name  * @vdev: vdev
1052*5113495bSYour Name  *
1053*5113495bSYour Name  * Return: enum ieee80211_phymode
1054*5113495bSYour Name  */
hdd_son_get_phymode(struct wlan_objmgr_vdev * vdev)1055*5113495bSYour Name static enum ieee80211_phymode hdd_son_get_phymode(struct wlan_objmgr_vdev *vdev)
1056*5113495bSYour Name {
1057*5113495bSYour Name 	struct wlan_channel *des_chan;
1058*5113495bSYour Name 
1059*5113495bSYour Name 	if (!vdev) {
1060*5113495bSYour Name 		hdd_err("null vdev");
1061*5113495bSYour Name 		return IEEE80211_MODE_AUTO;
1062*5113495bSYour Name 	}
1063*5113495bSYour Name 	des_chan = wlan_vdev_mlme_get_des_chan(vdev);
1064*5113495bSYour Name 	if (!des_chan) {
1065*5113495bSYour Name 		hdd_err("null des_chan");
1066*5113495bSYour Name 		return IEEE80211_MODE_AUTO;
1067*5113495bSYour Name 	}
1068*5113495bSYour Name 
1069*5113495bSYour Name 	return hdd_wlan_phymode_to_son_phymode(des_chan->ch_phymode);
1070*5113495bSYour Name }
1071*5113495bSYour Name 
1072*5113495bSYour Name /**
1073*5113495bSYour Name  * hdd_son_per_sta_len() - get sta information length
1074*5113495bSYour Name  * @sta_info: pointer to hdd_station_info
1075*5113495bSYour Name  *
1076*5113495bSYour Name  * TD: Certain IE may be provided for sta info
1077*5113495bSYour Name  *
1078*5113495bSYour Name  * Return: the size which is needed for given sta info
1079*5113495bSYour Name  */
hdd_son_per_sta_len(struct hdd_station_info * sta_info)1080*5113495bSYour Name static uint32_t hdd_son_per_sta_len(struct hdd_station_info *sta_info)
1081*5113495bSYour Name {
1082*5113495bSYour Name 	return qdf_roundup(sizeof(struct ieee80211req_sta_info),
1083*5113495bSYour Name 			   sizeof(uint32_t));
1084*5113495bSYour Name }
1085*5113495bSYour Name 
1086*5113495bSYour Name /**
1087*5113495bSYour Name  * hdd_son_get_sta_space() - how many space are needed for given vdev
1088*5113495bSYour Name  * @vdev: vdev
1089*5113495bSYour Name  *
1090*5113495bSYour Name  * Return: space needed for given vdev to provide sta info
1091*5113495bSYour Name  */
hdd_son_get_sta_space(struct wlan_objmgr_vdev * vdev)1092*5113495bSYour Name static uint32_t hdd_son_get_sta_space(struct wlan_objmgr_vdev *vdev)
1093*5113495bSYour Name {
1094*5113495bSYour Name 	struct hdd_adapter *adapter;
1095*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1096*5113495bSYour Name 	struct hdd_station_info *sta_info, *tmp = NULL;
1097*5113495bSYour Name 	uint32_t space = 0;
1098*5113495bSYour Name 
1099*5113495bSYour Name 	if (!vdev) {
1100*5113495bSYour Name 		hdd_err("null vdev");
1101*5113495bSYour Name 		return space;
1102*5113495bSYour Name 	}
1103*5113495bSYour Name 
1104*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1105*5113495bSYour Name 	if (!link_info) {
1106*5113495bSYour Name 		hdd_err("null adapter");
1107*5113495bSYour Name 		return space;
1108*5113495bSYour Name 	}
1109*5113495bSYour Name 
1110*5113495bSYour Name 	adapter = link_info->adapter;
1111*5113495bSYour Name 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
1112*5113495bSYour Name 				  STA_INFO_SOFTAP_GET_STA_INFO) {
1113*5113495bSYour Name 		if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac))
1114*5113495bSYour Name 			space += hdd_son_per_sta_len(sta_info);
1115*5113495bSYour Name 
1116*5113495bSYour Name 		hdd_put_sta_info_ref(&adapter->sta_info_list,
1117*5113495bSYour Name 				     &sta_info, true,
1118*5113495bSYour Name 				     STA_INFO_SOFTAP_GET_STA_INFO);
1119*5113495bSYour Name 	}
1120*5113495bSYour Name 	hdd_debug("sta list space %u", space);
1121*5113495bSYour Name 
1122*5113495bSYour Name 	return space;
1123*5113495bSYour Name }
1124*5113495bSYour Name 
1125*5113495bSYour Name /**
1126*5113495bSYour Name  * hdd_son_get_sta_list() - get connected station list
1127*5113495bSYour Name  * @vdev: vdev
1128*5113495bSYour Name  * @si: pointer to ieee80211req_sta_info
1129*5113495bSYour Name  * @space: space left
1130*5113495bSYour Name  *
1131*5113495bSYour Name  * Return: void
1132*5113495bSYour Name  */
hdd_son_get_sta_list(struct wlan_objmgr_vdev * vdev,struct ieee80211req_sta_info * si,uint32_t * space)1133*5113495bSYour Name static void hdd_son_get_sta_list(struct wlan_objmgr_vdev *vdev,
1134*5113495bSYour Name 				 struct ieee80211req_sta_info *si,
1135*5113495bSYour Name 				 uint32_t *space)
1136*5113495bSYour Name {
1137*5113495bSYour Name 	struct hdd_adapter *adapter;
1138*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1139*5113495bSYour Name 	struct hdd_station_info *sta_info, *tmp = NULL;
1140*5113495bSYour Name 	uint32_t len;
1141*5113495bSYour Name 	qdf_time_t current_ts;
1142*5113495bSYour Name 
1143*5113495bSYour Name 	if (!vdev) {
1144*5113495bSYour Name 		hdd_err("null vdev");
1145*5113495bSYour Name 		return;
1146*5113495bSYour Name 	}
1147*5113495bSYour Name 
1148*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1149*5113495bSYour Name 	if (!link_info) {
1150*5113495bSYour Name 		hdd_err("null adapter");
1151*5113495bSYour Name 		return;
1152*5113495bSYour Name 	}
1153*5113495bSYour Name 
1154*5113495bSYour Name 	adapter = link_info->adapter;
1155*5113495bSYour Name 	hdd_for_each_sta_ref_safe(adapter->sta_info_list, sta_info, tmp,
1156*5113495bSYour Name 				  STA_INFO_SOFTAP_GET_STA_INFO) {
1157*5113495bSYour Name 		if (!qdf_is_macaddr_broadcast(&sta_info->sta_mac)) {
1158*5113495bSYour Name 			len = hdd_son_per_sta_len(sta_info);
1159*5113495bSYour Name 
1160*5113495bSYour Name 			if (len > *space) {
1161*5113495bSYour Name 				/* no more space if left */
1162*5113495bSYour Name 				hdd_put_sta_info_ref(
1163*5113495bSYour Name 					&adapter->sta_info_list,
1164*5113495bSYour Name 					&sta_info, true,
1165*5113495bSYour Name 					STA_INFO_SOFTAP_GET_STA_INFO);
1166*5113495bSYour Name 
1167*5113495bSYour Name 				if (tmp)
1168*5113495bSYour Name 					hdd_put_sta_info_ref(
1169*5113495bSYour Name 						&adapter->sta_info_list,
1170*5113495bSYour Name 						&tmp, true,
1171*5113495bSYour Name 						STA_INFO_SOFTAP_GET_STA_INFO);
1172*5113495bSYour Name 
1173*5113495bSYour Name 				hdd_err("space %u, length %u", *space, len);
1174*5113495bSYour Name 
1175*5113495bSYour Name 				return;
1176*5113495bSYour Name 			}
1177*5113495bSYour Name 
1178*5113495bSYour Name 			qdf_mem_copy(si->isi_macaddr, &sta_info->sta_mac,
1179*5113495bSYour Name 				     QDF_MAC_ADDR_SIZE);
1180*5113495bSYour Name 			si->isi_ext_cap = sta_info->ext_cap;
1181*5113495bSYour Name 			si->isi_beacon_measurement_support =
1182*5113495bSYour Name 					!!(sta_info->capability &
1183*5113495bSYour Name 					   WLAN_CAPABILITY_RADIO_MEASURE);
1184*5113495bSYour Name 			si->isi_operating_bands = sta_info->supported_band;
1185*5113495bSYour Name 			si->isi_assoc_time = sta_info->assoc_ts;
1186*5113495bSYour Name 			current_ts = qdf_system_ticks();
1187*5113495bSYour Name 			jiffies_to_timespec(current_ts - sta_info->assoc_ts,
1188*5113495bSYour Name 					    &si->isi_tr069_assoc_time);
1189*5113495bSYour Name 			si->isi_rssi = sta_info->rssi;
1190*5113495bSYour Name 			si->isi_len = len;
1191*5113495bSYour Name 			si->isi_ie_len = 0;
1192*5113495bSYour Name 			hdd_debug("sta " QDF_MAC_ADDR_FMT " ext_cap 0x%x op band %u rssi %d len %u, assoc ts %lu, curr ts %lu rrm %d",
1193*5113495bSYour Name 				  QDF_MAC_ADDR_REF(si->isi_macaddr),
1194*5113495bSYour Name 				  si->isi_ext_cap, si->isi_operating_bands,
1195*5113495bSYour Name 				  si->isi_rssi, si->isi_len, sta_info->assoc_ts,
1196*5113495bSYour Name 				  current_ts,
1197*5113495bSYour Name 				  si->isi_beacon_measurement_support);
1198*5113495bSYour Name 			si = (struct ieee80211req_sta_info *)(((uint8_t *)si) +
1199*5113495bSYour Name 			     len);
1200*5113495bSYour Name 			*space -= len;
1201*5113495bSYour Name 		}
1202*5113495bSYour Name 		hdd_put_sta_info_ref(&adapter->sta_info_list,
1203*5113495bSYour Name 				     &sta_info, true,
1204*5113495bSYour Name 				     STA_INFO_SOFTAP_GET_STA_INFO);
1205*5113495bSYour Name 	}
1206*5113495bSYour Name }
1207*5113495bSYour Name 
1208*5113495bSYour Name /**
1209*5113495bSYour Name  * hdd_son_set_acl_policy() - set son acl policy
1210*5113495bSYour Name  * @vdev: vdev
1211*5113495bSYour Name  * @son_acl_policy: enum ieee80211_acl_cmd
1212*5113495bSYour Name  *
1213*5113495bSYour Name  * Return: QDF_STATUS
1214*5113495bSYour Name  */
hdd_son_set_acl_policy(struct wlan_objmgr_vdev * vdev,ieee80211_acl_cmd son_acl_policy)1215*5113495bSYour Name static QDF_STATUS hdd_son_set_acl_policy(struct wlan_objmgr_vdev *vdev,
1216*5113495bSYour Name 					 ieee80211_acl_cmd son_acl_policy)
1217*5113495bSYour Name {
1218*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1219*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_INVAL;
1220*5113495bSYour Name 	struct sap_context *sap_context;
1221*5113495bSYour Name 
1222*5113495bSYour Name 	if (!vdev) {
1223*5113495bSYour Name 		hdd_err("null vdev");
1224*5113495bSYour Name 		return status;
1225*5113495bSYour Name 	}
1226*5113495bSYour Name 
1227*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1228*5113495bSYour Name 	if (!link_info) {
1229*5113495bSYour Name 		hdd_err("null adapter");
1230*5113495bSYour Name 		return status;
1231*5113495bSYour Name 	}
1232*5113495bSYour Name 
1233*5113495bSYour Name 	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
1234*5113495bSYour Name 	switch (son_acl_policy) {
1235*5113495bSYour Name 	case IEEE80211_MACCMD_POLICY_OPEN:
1236*5113495bSYour Name 		status = wlansap_set_acl_mode(sap_context, eSAP_ALLOW_ALL);
1237*5113495bSYour Name 		break;
1238*5113495bSYour Name 	case IEEE80211_MACCMD_POLICY_ALLOW:
1239*5113495bSYour Name 		status = wlansap_set_acl_mode(sap_context,
1240*5113495bSYour Name 					      eSAP_DENY_UNLESS_ACCEPTED);
1241*5113495bSYour Name 		break;
1242*5113495bSYour Name 	case IEEE80211_MACCMD_POLICY_DENY:
1243*5113495bSYour Name 		status = wlansap_set_acl_mode(sap_context,
1244*5113495bSYour Name 					      eSAP_ACCEPT_UNLESS_DENIED);
1245*5113495bSYour Name 		break;
1246*5113495bSYour Name 	case IEEE80211_MACCMD_FLUSH:
1247*5113495bSYour Name 	case IEEE80211_MACCMD_DETACH:
1248*5113495bSYour Name 		status = wlansap_clear_acl(sap_context);
1249*5113495bSYour Name 		break;
1250*5113495bSYour Name 	default:
1251*5113495bSYour Name 		hdd_err("invalid son acl policy %d", son_acl_policy);
1252*5113495bSYour Name 		break;
1253*5113495bSYour Name 	}
1254*5113495bSYour Name 
1255*5113495bSYour Name 	return status;
1256*5113495bSYour Name }
1257*5113495bSYour Name 
1258*5113495bSYour Name /**
1259*5113495bSYour Name  * hdd_acl_policy_to_son_acl_policy() - convert acl policy to son acl policy
1260*5113495bSYour Name  * @acl_policy: acl policy
1261*5113495bSYour Name  *
1262*5113495bSYour Name  * Return: son acl policy. enum ieee80211_acl_cmd
1263*5113495bSYour Name  */
hdd_acl_policy_to_son_acl_policy(eSapMacAddrACL acl_policy)1264*5113495bSYour Name static ieee80211_acl_cmd hdd_acl_policy_to_son_acl_policy(
1265*5113495bSYour Name 						eSapMacAddrACL acl_policy)
1266*5113495bSYour Name {
1267*5113495bSYour Name 	ieee80211_acl_cmd son_acl_policy = IEEE80211_MACCMD_DETACH;
1268*5113495bSYour Name 
1269*5113495bSYour Name 	switch (acl_policy) {
1270*5113495bSYour Name 	case eSAP_ACCEPT_UNLESS_DENIED:
1271*5113495bSYour Name 		son_acl_policy = IEEE80211_MACCMD_POLICY_DENY;
1272*5113495bSYour Name 		break;
1273*5113495bSYour Name 	case eSAP_DENY_UNLESS_ACCEPTED:
1274*5113495bSYour Name 		son_acl_policy = IEEE80211_MACCMD_POLICY_ALLOW;
1275*5113495bSYour Name 		break;
1276*5113495bSYour Name 	case eSAP_ALLOW_ALL:
1277*5113495bSYour Name 		son_acl_policy = IEEE80211_MACCMD_POLICY_OPEN;
1278*5113495bSYour Name 		break;
1279*5113495bSYour Name 	default:
1280*5113495bSYour Name 		hdd_err("invalid acl policy %d", acl_policy);
1281*5113495bSYour Name 		break;
1282*5113495bSYour Name 	}
1283*5113495bSYour Name 
1284*5113495bSYour Name 	return son_acl_policy;
1285*5113495bSYour Name }
1286*5113495bSYour Name 
1287*5113495bSYour Name /**
1288*5113495bSYour Name  * hdd_son_get_acl_policy() - get son acl policy
1289*5113495bSYour Name  * @vdev: vdev
1290*5113495bSYour Name  *
1291*5113495bSYour Name  * Return: son acl policy. enum ieee80211_acl_cmd
1292*5113495bSYour Name  */
hdd_son_get_acl_policy(struct wlan_objmgr_vdev * vdev)1293*5113495bSYour Name static ieee80211_acl_cmd hdd_son_get_acl_policy(struct wlan_objmgr_vdev *vdev)
1294*5113495bSYour Name {
1295*5113495bSYour Name 	eSapMacAddrACL acl_policy;
1296*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1297*5113495bSYour Name 	ieee80211_acl_cmd son_acl_policy = IEEE80211_MACCMD_DETACH;
1298*5113495bSYour Name 
1299*5113495bSYour Name 	if (!vdev) {
1300*5113495bSYour Name 		hdd_err("null vdev");
1301*5113495bSYour Name 		return son_acl_policy;
1302*5113495bSYour Name 	}
1303*5113495bSYour Name 
1304*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1305*5113495bSYour Name 	if (!link_info) {
1306*5113495bSYour Name 		hdd_err("null adapter");
1307*5113495bSYour Name 		return son_acl_policy;
1308*5113495bSYour Name 	}
1309*5113495bSYour Name 
1310*5113495bSYour Name 	wlansap_get_acl_mode(WLAN_HDD_GET_SAP_CTX_PTR(link_info), &acl_policy);
1311*5113495bSYour Name 
1312*5113495bSYour Name 	son_acl_policy = hdd_acl_policy_to_son_acl_policy(acl_policy);
1313*5113495bSYour Name 
1314*5113495bSYour Name 	return son_acl_policy;
1315*5113495bSYour Name }
1316*5113495bSYour Name 
1317*5113495bSYour Name /**
1318*5113495bSYour Name  * hdd_son_add_acl_mac() - add mac to access control list(ACL)
1319*5113495bSYour Name  * @vdev: vdev
1320*5113495bSYour Name  * @acl_mac: mac address to add
1321*5113495bSYour Name  *
1322*5113495bSYour Name  * Return: 0 on success, negative errno on failure
1323*5113495bSYour Name  */
hdd_son_add_acl_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * acl_mac)1324*5113495bSYour Name static int hdd_son_add_acl_mac(struct wlan_objmgr_vdev *vdev,
1325*5113495bSYour Name 			       struct qdf_mac_addr *acl_mac)
1326*5113495bSYour Name {
1327*5113495bSYour Name 	eSapACLType list_type;
1328*5113495bSYour Name 	QDF_STATUS qdf_status;
1329*5113495bSYour Name 	eSapMacAddrACL acl_policy;
1330*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1331*5113495bSYour Name 	struct sap_context *sap_context;
1332*5113495bSYour Name 
1333*5113495bSYour Name 	if (!vdev) {
1334*5113495bSYour Name 		hdd_err("null vdev");
1335*5113495bSYour Name 		return -EINVAL;
1336*5113495bSYour Name 	}
1337*5113495bSYour Name 	if (!acl_mac) {
1338*5113495bSYour Name 		hdd_err("null acl_mac");
1339*5113495bSYour Name 		return -EINVAL;
1340*5113495bSYour Name 	}
1341*5113495bSYour Name 
1342*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1343*5113495bSYour Name 	if (!link_info) {
1344*5113495bSYour Name 		hdd_err("null adapter");
1345*5113495bSYour Name 		return -EINVAL;
1346*5113495bSYour Name 	}
1347*5113495bSYour Name 
1348*5113495bSYour Name 	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
1349*5113495bSYour Name 	wlansap_get_acl_mode(sap_context, &acl_policy);
1350*5113495bSYour Name 
1351*5113495bSYour Name 	if (acl_policy == eSAP_ACCEPT_UNLESS_DENIED) {
1352*5113495bSYour Name 		list_type = SAP_DENY_LIST;
1353*5113495bSYour Name 	} else if (acl_policy == eSAP_DENY_UNLESS_ACCEPTED) {
1354*5113495bSYour Name 		list_type = SAP_ALLOW_LIST;
1355*5113495bSYour Name 	} else {
1356*5113495bSYour Name 		hdd_err("Invalid ACL policy %d.", acl_policy);
1357*5113495bSYour Name 		return -EINVAL;
1358*5113495bSYour Name 	}
1359*5113495bSYour Name 	qdf_status = wlansap_modify_acl(sap_context, acl_mac->bytes, list_type,
1360*5113495bSYour Name 					ADD_STA_TO_ACL_NO_DEAUTH);
1361*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
1362*5113495bSYour Name 		hdd_err("Modify ACL failed");
1363*5113495bSYour Name 		return -EIO;
1364*5113495bSYour Name 	}
1365*5113495bSYour Name 
1366*5113495bSYour Name 	return 0;
1367*5113495bSYour Name }
1368*5113495bSYour Name 
1369*5113495bSYour Name /**
1370*5113495bSYour Name  * hdd_son_del_acl_mac() - delete mac from acl
1371*5113495bSYour Name  * @vdev: vdev
1372*5113495bSYour Name  * @acl_mac: mac to remove
1373*5113495bSYour Name  *
1374*5113495bSYour Name  * Return: 0 on success, negative errno on failure
1375*5113495bSYour Name  */
hdd_son_del_acl_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * acl_mac)1376*5113495bSYour Name static int hdd_son_del_acl_mac(struct wlan_objmgr_vdev *vdev,
1377*5113495bSYour Name 			       struct qdf_mac_addr *acl_mac)
1378*5113495bSYour Name {
1379*5113495bSYour Name 	eSapACLType list_type;
1380*5113495bSYour Name 	QDF_STATUS qdf_status;
1381*5113495bSYour Name 	eSapMacAddrACL acl_policy;
1382*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1383*5113495bSYour Name 	struct sap_context *sap_ctx;
1384*5113495bSYour Name 
1385*5113495bSYour Name 	if (!vdev) {
1386*5113495bSYour Name 		hdd_err("null vdev");
1387*5113495bSYour Name 		return -EINVAL;
1388*5113495bSYour Name 	}
1389*5113495bSYour Name 	if (!acl_mac) {
1390*5113495bSYour Name 		hdd_err("null acl_mac");
1391*5113495bSYour Name 		return -EINVAL;
1392*5113495bSYour Name 	}
1393*5113495bSYour Name 
1394*5113495bSYour Name 	lin_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1395*5113495bSYour Name 	if (!link_info) {
1396*5113495bSYour Name 		hdd_err("null adapter");
1397*5113495bSYour Name 		return -EINVAL;
1398*5113495bSYour Name 	}
1399*5113495bSYour Name 
1400*5113495bSYour Name 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
1401*5113495bSYour Name 	if (!sap_ctx) {
1402*5113495bSYour Name 		hdd_err("null sap ctx");
1403*5113495bSYour Name 		return -EINVAL;
1404*5113495bSYour Name 	}
1405*5113495bSYour Name 
1406*5113495bSYour Name 	wlansap_get_acl_mode(sap_ctx, &acl_policy);
1407*5113495bSYour Name 
1408*5113495bSYour Name 	if (acl_policy == eSAP_ACCEPT_UNLESS_DENIED) {
1409*5113495bSYour Name 		list_type = SAP_DENY_LIST;
1410*5113495bSYour Name 	} else if (acl_policy == eSAP_DENY_UNLESS_ACCEPTED) {
1411*5113495bSYour Name 		list_type = SAP_ALLOW_LIST;
1412*5113495bSYour Name 	} else {
1413*5113495bSYour Name 		hdd_err("Invalid ACL policy %d.", acl_policy);
1414*5113495bSYour Name 		return -EINVAL;
1415*5113495bSYour Name 	}
1416*5113495bSYour Name 	qdf_status = wlansap_modify_acl(sap_ctx, acl_mac->bytes, list_type,
1417*5113495bSYour Name 					DELETE_STA_FROM_ACL_NO_DEAUTH);
1418*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(qdf_status)) {
1419*5113495bSYour Name 		hdd_err("Modify ACL failed");
1420*5113495bSYour Name 		return -EIO;
1421*5113495bSYour Name 	}
1422*5113495bSYour Name 
1423*5113495bSYour Name 	return 0;
1424*5113495bSYour Name }
1425*5113495bSYour Name 
1426*5113495bSYour Name /**
1427*5113495bSYour Name  * hdd_son_kickout_mac() - kickout sta with given mac
1428*5113495bSYour Name  * @vdev: vdev
1429*5113495bSYour Name  * @mac: sta mac to kickout
1430*5113495bSYour Name  *
1431*5113495bSYour Name  * Return: 0 on success, negative errno on failure
1432*5113495bSYour Name  */
hdd_son_kickout_mac(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * mac)1433*5113495bSYour Name static int hdd_son_kickout_mac(struct wlan_objmgr_vdev *vdev,
1434*5113495bSYour Name 			       struct qdf_mac_addr *mac)
1435*5113495bSYour Name {
1436*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1437*5113495bSYour Name 
1438*5113495bSYour Name 	if (!vdev) {
1439*5113495bSYour Name 		hdd_err("null vdev");
1440*5113495bSYour Name 		return -EINVAL;
1441*5113495bSYour Name 	}
1442*5113495bSYour Name 
1443*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1444*5113495bSYour Name 	if (!link_info) {
1445*5113495bSYour Name 		hdd_err("null adapter");
1446*5113495bSYour Name 		return -EINVAL;
1447*5113495bSYour Name 	}
1448*5113495bSYour Name 
1449*5113495bSYour Name 	if (mac)
1450*5113495bSYour Name 		return wlan_hdd_del_station(link_info->adapter, mac->bytes);
1451*5113495bSYour Name 	else
1452*5113495bSYour Name 		return wlan_hdd_del_station(link_info->adapter, NULL);
1453*5113495bSYour Name }
1454*5113495bSYour Name 
hdd_son_get_rx_nss(struct wlan_objmgr_vdev * vdev)1455*5113495bSYour Name static uint8_t hdd_son_get_rx_nss(struct wlan_objmgr_vdev *vdev)
1456*5113495bSYour Name {
1457*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1458*5113495bSYour Name 	uint8_t rx_nss = 0;
1459*5113495bSYour Name 
1460*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1461*5113495bSYour Name 	if (!link_info) {
1462*5113495bSYour Name 		hdd_err("null adapter");
1463*5113495bSYour Name 		return 0;
1464*5113495bSYour Name 	}
1465*5113495bSYour Name 
1466*5113495bSYour Name 	hdd_get_rx_nss(link_info->adapter, &rx_nss);
1467*5113495bSYour Name 	return rx_nss;
1468*5113495bSYour Name }
1469*5113495bSYour Name 
hdd_son_deauth_sta(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac,bool ignore_frame)1470*5113495bSYour Name static void hdd_son_deauth_sta(struct wlan_objmgr_vdev *vdev,
1471*5113495bSYour Name 			       uint8_t *peer_mac,
1472*5113495bSYour Name 			       bool ignore_frame)
1473*5113495bSYour Name {
1474*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1475*5113495bSYour Name 	struct csr_del_sta_params param;
1476*5113495bSYour Name 	QDF_STATUS status;
1477*5113495bSYour Name 
1478*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1479*5113495bSYour Name 	if (!link_info) {
1480*5113495bSYour Name 		hdd_err("null adapter");
1481*5113495bSYour Name 		return;
1482*5113495bSYour Name 	}
1483*5113495bSYour Name 
1484*5113495bSYour Name 	qdf_mem_copy(param.peerMacAddr.bytes, peer_mac, QDF_MAC_ADDR_SIZE);
1485*5113495bSYour Name 	param.subtype = SIR_MAC_MGMT_DEAUTH;
1486*5113495bSYour Name 	param.reason_code = ignore_frame ? REASON_HOST_TRIGGERED_SILENT_DEAUTH
1487*5113495bSYour Name 					 : REASON_UNSPEC_FAILURE;
1488*5113495bSYour Name 	hdd_debug("Peer - "QDF_MAC_ADDR_FMT" Ignore Frame - %u",
1489*5113495bSYour Name 		  QDF_MAC_ADDR_REF(peer_mac), ignore_frame);
1490*5113495bSYour Name 
1491*5113495bSYour Name 	status = hdd_softap_sta_deauth(link_info->adapter, &param);
1492*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
1493*5113495bSYour Name 		hdd_err("Error in deauthenticating peer");
1494*5113495bSYour Name }
1495*5113495bSYour Name 
hdd_son_modify_acl(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac,bool allow_auth)1496*5113495bSYour Name static void hdd_son_modify_acl(struct wlan_objmgr_vdev *vdev,
1497*5113495bSYour Name 			       uint8_t *peer_mac,
1498*5113495bSYour Name 			       bool allow_auth)
1499*5113495bSYour Name {
1500*5113495bSYour Name 	QDF_STATUS status;
1501*5113495bSYour Name 	struct sap_context *sap_context;
1502*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1503*5113495bSYour Name 
1504*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1505*5113495bSYour Name 	if (!link_info) {
1506*5113495bSYour Name 		hdd_err("null adapter");
1507*5113495bSYour Name 		return;
1508*5113495bSYour Name 	}
1509*5113495bSYour Name 
1510*5113495bSYour Name 	hdd_debug("Peer - " QDF_MAC_ADDR_FMT " Allow Auth - %u",
1511*5113495bSYour Name 		  QDF_MAC_ADDR_REF(peer_mac), allow_auth);
1512*5113495bSYour Name 
1513*5113495bSYour Name 	sap_context = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
1514*5113495bSYour Name 	if (allow_auth) {
1515*5113495bSYour Name 		status = wlansap_modify_acl(sap_context, peer_mac,
1516*5113495bSYour Name 					    SAP_DENY_LIST, DELETE_STA_FROM_ACL);
1517*5113495bSYour Name 		status = wlansap_modify_acl(sap_context, peer_mac,
1518*5113495bSYour Name 					    SAP_ALLOW_LIST, ADD_STA_TO_ACL);
1519*5113495bSYour Name 	} else {
1520*5113495bSYour Name 		status = wlansap_modify_acl(sap_context, peer_mac,
1521*5113495bSYour Name 					    SAP_ALLOW_LIST,
1522*5113495bSYour Name 					    DELETE_STA_FROM_ACL);
1523*5113495bSYour Name 		status = wlansap_modify_acl(sap_context, peer_mac,
1524*5113495bSYour Name 					    SAP_DENY_LIST, ADD_STA_TO_ACL);
1525*5113495bSYour Name 	}
1526*5113495bSYour Name }
1527*5113495bSYour Name 
hdd_son_send_cfg_event(struct wlan_objmgr_vdev * vdev,uint32_t event_id,uint32_t event_len,const uint8_t * event_buf)1528*5113495bSYour Name static int hdd_son_send_cfg_event(struct wlan_objmgr_vdev *vdev,
1529*5113495bSYour Name 				  uint32_t event_id,
1530*5113495bSYour Name 				  uint32_t event_len,
1531*5113495bSYour Name 				  const uint8_t *event_buf)
1532*5113495bSYour Name {
1533*5113495bSYour Name 	struct hdd_adapter *adapter;
1534*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1535*5113495bSYour Name 	uint32_t len;
1536*5113495bSYour Name 	uint32_t idx;
1537*5113495bSYour Name 	struct sk_buff *skb;
1538*5113495bSYour Name 
1539*5113495bSYour Name 	if (!event_buf) {
1540*5113495bSYour Name 		hdd_err("invalid event buf");
1541*5113495bSYour Name 		return -EINVAL;
1542*5113495bSYour Name 	}
1543*5113495bSYour Name 
1544*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1545*5113495bSYour Name 	if (!link_info) {
1546*5113495bSYour Name 		hdd_err("null adapter");
1547*5113495bSYour Name 		return -EINVAL;
1548*5113495bSYour Name 	}
1549*5113495bSYour Name 
1550*5113495bSYour Name 	adapter = link_info->adapter;
1551*5113495bSYour Name 	len = nla_total_size(sizeof(event_id)) +
1552*5113495bSYour Name 			nla_total_size(event_len) +
1553*5113495bSYour Name 			NLMSG_HDRLEN;
1554*5113495bSYour Name 	idx = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION_INDEX;
1555*5113495bSYour Name 	skb = wlan_cfg80211_vendor_event_alloc(adapter->hdd_ctx->wiphy,
1556*5113495bSYour Name 					       &adapter->wdev,
1557*5113495bSYour Name 					       len, idx, GFP_KERNEL);
1558*5113495bSYour Name 	if (!skb) {
1559*5113495bSYour Name 		hdd_err("failed to alloc cfg80211 vendor event");
1560*5113495bSYour Name 		return -EINVAL;
1561*5113495bSYour Name 	}
1562*5113495bSYour Name 
1563*5113495bSYour Name 	if (nla_put_u32(skb,
1564*5113495bSYour Name 			QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_COMMAND,
1565*5113495bSYour Name 			event_id)) {
1566*5113495bSYour Name 		hdd_err("failed to put attr config generic command");
1567*5113495bSYour Name 		wlan_cfg80211_vendor_free_skb(skb);
1568*5113495bSYour Name 		return -EINVAL;
1569*5113495bSYour Name 	}
1570*5113495bSYour Name 
1571*5113495bSYour Name 	if (nla_put(skb,
1572*5113495bSYour Name 		    QCA_WLAN_VENDOR_ATTR_CONFIG_GENERIC_DATA,
1573*5113495bSYour Name 		    event_len,
1574*5113495bSYour Name 		    event_buf)) {
1575*5113495bSYour Name 		hdd_err("failed to put attr config generic data");
1576*5113495bSYour Name 		wlan_cfg80211_vendor_free_skb(skb);
1577*5113495bSYour Name 		return -EINVAL;
1578*5113495bSYour Name 	}
1579*5113495bSYour Name 
1580*5113495bSYour Name 	wlan_cfg80211_vendor_event(skb, GFP_KERNEL);
1581*5113495bSYour Name 
1582*5113495bSYour Name 	return 0;
1583*5113495bSYour Name }
1584*5113495bSYour Name 
hdd_son_deliver_opmode(struct wlan_objmgr_vdev * vdev,uint32_t event_len,const uint8_t * event_buf)1585*5113495bSYour Name static int hdd_son_deliver_opmode(struct wlan_objmgr_vdev *vdev,
1586*5113495bSYour Name 				  uint32_t event_len,
1587*5113495bSYour Name 				  const uint8_t *event_buf)
1588*5113495bSYour Name {
1589*5113495bSYour Name 	return hdd_son_send_cfg_event(vdev,
1590*5113495bSYour Name 				      QCA_NL80211_VENDOR_SUBCMD_OPMODE_UPDATE,
1591*5113495bSYour Name 				      event_len,
1592*5113495bSYour Name 				      event_buf);
1593*5113495bSYour Name }
1594*5113495bSYour Name 
hdd_son_deliver_smps(struct wlan_objmgr_vdev * vdev,uint32_t event_len,const uint8_t * event_buf)1595*5113495bSYour Name static int hdd_son_deliver_smps(struct wlan_objmgr_vdev *vdev,
1596*5113495bSYour Name 				uint32_t event_len,
1597*5113495bSYour Name 				const uint8_t *event_buf)
1598*5113495bSYour Name {
1599*5113495bSYour Name 	return hdd_son_send_cfg_event(vdev,
1600*5113495bSYour Name 				      QCA_NL80211_VENDOR_SUBCMD_SMPS_UPDATE,
1601*5113495bSYour Name 				      event_len,
1602*5113495bSYour Name 				      event_buf);
1603*5113495bSYour Name }
1604*5113495bSYour Name 
1605*5113495bSYour Name /**
1606*5113495bSYour Name  * hdd_son_get_vdev_by_netdev() - get vdev from net device
1607*5113495bSYour Name  * @dev: struct net_device dev
1608*5113495bSYour Name  *
1609*5113495bSYour Name  * Return: vdev on success, NULL on failure
1610*5113495bSYour Name  */
1611*5113495bSYour Name static struct wlan_objmgr_vdev *
hdd_son_get_vdev_by_netdev(struct net_device * dev)1612*5113495bSYour Name hdd_son_get_vdev_by_netdev(struct net_device *dev)
1613*5113495bSYour Name {
1614*5113495bSYour Name 	struct hdd_adapter *adapter;
1615*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1616*5113495bSYour Name 
1617*5113495bSYour Name 	if (!dev)
1618*5113495bSYour Name 		return NULL;
1619*5113495bSYour Name 
1620*5113495bSYour Name 	adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1621*5113495bSYour Name 	if (!adapter || (adapter && adapter->delete_in_progress))
1622*5113495bSYour Name 		return NULL;
1623*5113495bSYour Name 
1624*5113495bSYour Name 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_SON_ID);
1625*5113495bSYour Name 	if (!vdev)
1626*5113495bSYour Name 		return NULL;
1627*5113495bSYour Name 
1628*5113495bSYour Name 	return vdev;
1629*5113495bSYour Name }
1630*5113495bSYour Name 
1631*5113495bSYour Name /**
1632*5113495bSYour Name  * son_trigger_vdev_obj_creation() - Trigger vdev object creation
1633*5113495bSYour Name  * @psoc: psoc object
1634*5113495bSYour Name  * @object: vdev object
1635*5113495bSYour Name  * @arg: component id
1636*5113495bSYour Name  *
1637*5113495bSYour Name  * Return: void
1638*5113495bSYour Name  */
1639*5113495bSYour Name static void
son_trigger_vdev_obj_creation(struct wlan_objmgr_psoc * psoc,void * object,void * arg)1640*5113495bSYour Name son_trigger_vdev_obj_creation(struct wlan_objmgr_psoc *psoc,
1641*5113495bSYour Name 			      void *object, void *arg)
1642*5113495bSYour Name {
1643*5113495bSYour Name 	QDF_STATUS ret;
1644*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1645*5113495bSYour Name 	enum wlan_umac_comp_id *id;
1646*5113495bSYour Name 
1647*5113495bSYour Name 	vdev = object;
1648*5113495bSYour Name 	id = arg;
1649*5113495bSYour Name 
1650*5113495bSYour Name 	ret = wlan_objmgr_trigger_vdev_comp_priv_object_creation(vdev, *id);
1651*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1652*5113495bSYour Name 		hdd_err("vdev obj creation trigger failed");
1653*5113495bSYour Name }
1654*5113495bSYour Name 
1655*5113495bSYour Name /**
1656*5113495bSYour Name  * son_trigger_pdev_obj_creation() - Trigger pdev object creation
1657*5113495bSYour Name  * @psoc: psoc object
1658*5113495bSYour Name  * @object: pdev object
1659*5113495bSYour Name  * @arg: component id
1660*5113495bSYour Name  *
1661*5113495bSYour Name  * Return: void
1662*5113495bSYour Name  */
1663*5113495bSYour Name static void
son_trigger_pdev_obj_creation(struct wlan_objmgr_psoc * psoc,void * object,void * arg)1664*5113495bSYour Name son_trigger_pdev_obj_creation(struct wlan_objmgr_psoc *psoc,
1665*5113495bSYour Name 			      void *object, void *arg)
1666*5113495bSYour Name {
1667*5113495bSYour Name 	QDF_STATUS ret;
1668*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
1669*5113495bSYour Name 	enum wlan_umac_comp_id *id;
1670*5113495bSYour Name 
1671*5113495bSYour Name 	pdev = object;
1672*5113495bSYour Name 	id = arg;
1673*5113495bSYour Name 
1674*5113495bSYour Name 	ret = wlan_objmgr_trigger_pdev_comp_priv_object_creation(pdev, *id);
1675*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1676*5113495bSYour Name 		hdd_err("pdev obj creation trigger failed");
1677*5113495bSYour Name }
1678*5113495bSYour Name 
1679*5113495bSYour Name /**
1680*5113495bSYour Name  * son_trigger_pdev_obj_deletion() - Trigger pdev object deletion
1681*5113495bSYour Name  * @psoc: psoc object
1682*5113495bSYour Name  * @object: pdev object
1683*5113495bSYour Name  * @arg: component id
1684*5113495bSYour Name  *
1685*5113495bSYour Name  * Return: void
1686*5113495bSYour Name  */
1687*5113495bSYour Name static void
son_trigger_pdev_obj_deletion(struct wlan_objmgr_psoc * psoc,void * object,void * arg)1688*5113495bSYour Name son_trigger_pdev_obj_deletion(struct wlan_objmgr_psoc *psoc,
1689*5113495bSYour Name 			      void *object, void *arg)
1690*5113495bSYour Name {
1691*5113495bSYour Name 	QDF_STATUS ret;
1692*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
1693*5113495bSYour Name 	enum wlan_umac_comp_id *id;
1694*5113495bSYour Name 
1695*5113495bSYour Name 	pdev = object;
1696*5113495bSYour Name 	id = arg;
1697*5113495bSYour Name 
1698*5113495bSYour Name 	ret = wlan_objmgr_trigger_pdev_comp_priv_object_deletion(pdev, *id);
1699*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1700*5113495bSYour Name 		hdd_err("pdev obj delete trigger failed");
1701*5113495bSYour Name }
1702*5113495bSYour Name 
1703*5113495bSYour Name /**
1704*5113495bSYour Name  * hdd_son_trigger_objmgr_object_creation() - Trigger objmgr object creation
1705*5113495bSYour Name  * @id: umac component id
1706*5113495bSYour Name  *
1707*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success otherwise failure
1708*5113495bSYour Name  */
1709*5113495bSYour Name static QDF_STATUS
hdd_son_trigger_objmgr_object_creation(enum wlan_umac_comp_id id)1710*5113495bSYour Name hdd_son_trigger_objmgr_object_creation(enum wlan_umac_comp_id id)
1711*5113495bSYour Name {
1712*5113495bSYour Name 	QDF_STATUS ret;
1713*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1714*5113495bSYour Name 
1715*5113495bSYour Name 	psoc = wlan_objmgr_get_psoc_by_id(0, WLAN_SON_ID);
1716*5113495bSYour Name 	if (!psoc) {
1717*5113495bSYour Name 		hdd_err("psoc null");
1718*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1719*5113495bSYour Name 	}
1720*5113495bSYour Name 
1721*5113495bSYour Name 	ret = wlan_objmgr_trigger_psoc_comp_priv_object_creation(psoc, id);
1722*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1723*5113495bSYour Name 		hdd_err("psoc object create trigger failed");
1724*5113495bSYour Name 		goto out;
1725*5113495bSYour Name 	}
1726*5113495bSYour Name 
1727*5113495bSYour Name 	ret = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
1728*5113495bSYour Name 					   son_trigger_pdev_obj_creation,
1729*5113495bSYour Name 					   &id, 0, id);
1730*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1731*5113495bSYour Name 		hdd_err("pdev object create trigger failed");
1732*5113495bSYour Name 		goto fail;
1733*5113495bSYour Name 	}
1734*5113495bSYour Name 
1735*5113495bSYour Name 	ret = wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
1736*5113495bSYour Name 					   son_trigger_vdev_obj_creation,
1737*5113495bSYour Name 					   &id, 0, id);
1738*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret)) {
1739*5113495bSYour Name 		hdd_err("vdev object create trigger failed");
1740*5113495bSYour Name 		goto fail1;
1741*5113495bSYour Name 	}
1742*5113495bSYour Name 	wlan_objmgr_psoc_release_ref(psoc, WLAN_SON_ID);
1743*5113495bSYour Name 	return ret;
1744*5113495bSYour Name 
1745*5113495bSYour Name fail1:
1746*5113495bSYour Name 	ret = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
1747*5113495bSYour Name 					   son_trigger_pdev_obj_deletion,
1748*5113495bSYour Name 					   &id, 0, id);
1749*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1750*5113495bSYour Name 		hdd_err("pdev object delete trigger failed");
1751*5113495bSYour Name fail:
1752*5113495bSYour Name 	ret = wlan_objmgr_trigger_psoc_comp_priv_object_deletion(psoc, id);
1753*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1754*5113495bSYour Name 		hdd_err("psoc object delete trigger failed");
1755*5113495bSYour Name out:
1756*5113495bSYour Name 	wlan_objmgr_psoc_release_ref(psoc, WLAN_SON_ID);
1757*5113495bSYour Name 	return ret;
1758*5113495bSYour Name }
1759*5113495bSYour Name 
1760*5113495bSYour Name /**
1761*5113495bSYour Name  * son_trigger_peer_obj_deletion() - Trigger peer object deletion
1762*5113495bSYour Name  * @psoc: psoc object
1763*5113495bSYour Name  * @object: peer object
1764*5113495bSYour Name  * @arg: component id
1765*5113495bSYour Name  *
1766*5113495bSYour Name  * Return: void
1767*5113495bSYour Name  */
1768*5113495bSYour Name static void
son_trigger_peer_obj_deletion(struct wlan_objmgr_psoc * psoc,void * object,void * arg)1769*5113495bSYour Name son_trigger_peer_obj_deletion(struct wlan_objmgr_psoc *psoc,
1770*5113495bSYour Name 			      void *object, void *arg)
1771*5113495bSYour Name {
1772*5113495bSYour Name 	QDF_STATUS ret;
1773*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
1774*5113495bSYour Name 	enum wlan_umac_comp_id *id;
1775*5113495bSYour Name 
1776*5113495bSYour Name 	peer = object;
1777*5113495bSYour Name 	id = arg;
1778*5113495bSYour Name 
1779*5113495bSYour Name 	ret = wlan_objmgr_trigger_peer_comp_priv_object_deletion(peer, *id);
1780*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1781*5113495bSYour Name 		hdd_err("peer obj delete trigger failed");
1782*5113495bSYour Name }
1783*5113495bSYour Name 
1784*5113495bSYour Name /**
1785*5113495bSYour Name  * son_trigger_vdev_obj_deletion() - Trigger vdev object deletion
1786*5113495bSYour Name  * @psoc: psoc object
1787*5113495bSYour Name  * @object: vdev object
1788*5113495bSYour Name  * @arg: component id
1789*5113495bSYour Name  *
1790*5113495bSYour Name  * Return: void
1791*5113495bSYour Name  */
1792*5113495bSYour Name static void
son_trigger_vdev_obj_deletion(struct wlan_objmgr_psoc * psoc,void * object,void * arg)1793*5113495bSYour Name son_trigger_vdev_obj_deletion(struct wlan_objmgr_psoc *psoc,
1794*5113495bSYour Name 			      void *object, void *arg)
1795*5113495bSYour Name {
1796*5113495bSYour Name 	QDF_STATUS ret;
1797*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
1798*5113495bSYour Name 	enum wlan_umac_comp_id *id;
1799*5113495bSYour Name 
1800*5113495bSYour Name 	vdev = object;
1801*5113495bSYour Name 	id = arg;
1802*5113495bSYour Name 
1803*5113495bSYour Name 	ret = wlan_objmgr_trigger_vdev_comp_priv_object_deletion(vdev, *id);
1804*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1805*5113495bSYour Name 		hdd_err("vdev obj deletion trigger failed");
1806*5113495bSYour Name }
1807*5113495bSYour Name 
1808*5113495bSYour Name /**
1809*5113495bSYour Name  * hdd_son_trigger_objmgr_object_deletion() - Trigger objmgr object deletion
1810*5113495bSYour Name  * @id: umac component id
1811*5113495bSYour Name  *
1812*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on success otherwise failure
1813*5113495bSYour Name  */
1814*5113495bSYour Name static QDF_STATUS
hdd_son_trigger_objmgr_object_deletion(enum wlan_umac_comp_id id)1815*5113495bSYour Name hdd_son_trigger_objmgr_object_deletion(enum wlan_umac_comp_id id)
1816*5113495bSYour Name {
1817*5113495bSYour Name 	QDF_STATUS ret;
1818*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
1819*5113495bSYour Name 
1820*5113495bSYour Name 	psoc = wlan_objmgr_get_psoc_by_id(0, WLAN_SON_ID);
1821*5113495bSYour Name 	if (!psoc) {
1822*5113495bSYour Name 		hdd_err("psoc null");
1823*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1824*5113495bSYour Name 	}
1825*5113495bSYour Name 
1826*5113495bSYour Name 	ret = wlan_objmgr_iterate_obj_list(psoc, WLAN_PEER_OP,
1827*5113495bSYour Name 					   son_trigger_peer_obj_deletion,
1828*5113495bSYour Name 					   &id, 0, id);
1829*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1830*5113495bSYour Name 		hdd_err("peer object deletion trigger failed");
1831*5113495bSYour Name 
1832*5113495bSYour Name 	ret = wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP,
1833*5113495bSYour Name 					   son_trigger_vdev_obj_deletion,
1834*5113495bSYour Name 					   &id, 0, id);
1835*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1836*5113495bSYour Name 		hdd_err("vdev object deletion trigger failed");
1837*5113495bSYour Name 
1838*5113495bSYour Name 	ret = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
1839*5113495bSYour Name 					   son_trigger_pdev_obj_deletion,
1840*5113495bSYour Name 					   &id, 0, id);
1841*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1842*5113495bSYour Name 		hdd_err("pdev object delete trigger failed");
1843*5113495bSYour Name 
1844*5113495bSYour Name 	ret = wlan_objmgr_trigger_psoc_comp_priv_object_deletion(psoc, id);
1845*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(ret))
1846*5113495bSYour Name 		hdd_err("psoc object delete trigger failed");
1847*5113495bSYour Name 
1848*5113495bSYour Name 	wlan_objmgr_psoc_release_ref(psoc, WLAN_SON_ID);
1849*5113495bSYour Name 	return ret;
1850*5113495bSYour Name }
1851*5113495bSYour Name 
1852*5113495bSYour Name /*
1853*5113495bSYour Name  * hdd_son_init_acs_channels() -initializes acs configs
1854*5113495bSYour Name  *
1855*5113495bSYour Name  * @adapter: pointer to hdd adapter
1856*5113495bSYour Name  * @hdd_ctx: pointer to hdd context
1857*5113495bSYour Name  * @acs_cfg: pointer to acs configs
1858*5113495bSYour Name  *
1859*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if ACS configuration is initialized,
1860*5113495bSYour Name  */
hdd_son_init_acs_channels(struct hdd_adapter * adapter,struct hdd_context * hdd_ctx,struct sap_acs_cfg * acs_cfg)1861*5113495bSYour Name static QDF_STATUS hdd_son_init_acs_channels(struct hdd_adapter *adapter,
1862*5113495bSYour Name 					    struct hdd_context *hdd_ctx,
1863*5113495bSYour Name 					    struct sap_acs_cfg *acs_cfg)
1864*5113495bSYour Name {
1865*5113495bSYour Name 	enum policy_mgr_con_mode pm_mode;
1866*5113495bSYour Name 	uint32_t freq_list[NUM_CHANNELS], num_channels, i;
1867*5113495bSYour Name 
1868*5113495bSYour Name 	if (!hdd_ctx || !acs_cfg) {
1869*5113495bSYour Name 		hdd_err("Null pointer!!! hdd_ctx or acs_cfg");
1870*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1871*5113495bSYour Name 	}
1872*5113495bSYour Name 	if (acs_cfg->freq_list) {
1873*5113495bSYour Name 		hdd_debug("ACS config is already there, no need to init again");
1874*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1875*5113495bSYour Name 	}
1876*5113495bSYour Name 	/* Setting ACS config */
1877*5113495bSYour Name 	qdf_mem_zero(acs_cfg, sizeof(*acs_cfg));
1878*5113495bSYour Name 	acs_cfg->ch_width = CH_WIDTH_20MHZ;
1879*5113495bSYour Name 	policy_mgr_get_valid_chans(hdd_ctx->psoc, freq_list, &num_channels);
1880*5113495bSYour Name 	/* convert and store channel to freq */
1881*5113495bSYour Name 	if (!num_channels) {
1882*5113495bSYour Name 		hdd_err("No Valid channel for ACS");
1883*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1884*5113495bSYour Name 	}
1885*5113495bSYour Name 	acs_cfg->freq_list = qdf_mem_malloc(sizeof(*acs_cfg->freq_list) *
1886*5113495bSYour Name 					    num_channels);
1887*5113495bSYour Name 	if (!acs_cfg->freq_list) {
1888*5113495bSYour Name 		hdd_err("Mem-alloc failed for acs_cfg->freq_list");
1889*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1890*5113495bSYour Name 	}
1891*5113495bSYour Name 	acs_cfg->master_freq_list =
1892*5113495bSYour Name 			qdf_mem_malloc(sizeof(*acs_cfg->master_freq_list) *
1893*5113495bSYour Name 				       num_channels);
1894*5113495bSYour Name 	if (!acs_cfg->master_freq_list) {
1895*5113495bSYour Name 		hdd_err("Mem-alloc failed for acs_cfg->master_freq_list");
1896*5113495bSYour Name 		qdf_mem_free(acs_cfg->freq_list);
1897*5113495bSYour Name 		acs_cfg->freq_list = NULL;
1898*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1899*5113495bSYour Name 	}
1900*5113495bSYour Name 
1901*5113495bSYour Name 	pm_mode =
1902*5113495bSYour Name 	      policy_mgr_qdf_opmode_to_pm_con_mode(hdd_ctx->psoc,
1903*5113495bSYour Name 						   adapter->device_mode,
1904*5113495bSYour Name 						   adapter->deflink->vdev_id);
1905*5113495bSYour Name 	/* convert channel to freq */
1906*5113495bSYour Name 	for (i = 0; i < num_channels; i++) {
1907*5113495bSYour Name 		acs_cfg->freq_list[i] = freq_list[i];
1908*5113495bSYour Name 		acs_cfg->master_freq_list[i] = freq_list[i];
1909*5113495bSYour Name 	}
1910*5113495bSYour Name 	acs_cfg->ch_list_count = num_channels;
1911*5113495bSYour Name 	acs_cfg->master_ch_list_count = num_channels;
1912*5113495bSYour Name 	if (policy_mgr_is_force_scc(hdd_ctx->psoc) &&
1913*5113495bSYour Name 	    policy_mgr_get_connection_count(hdd_ctx->psoc)) {
1914*5113495bSYour Name 		policy_mgr_get_pcl(hdd_ctx->psoc, pm_mode,
1915*5113495bSYour Name 				   acs_cfg->pcl_chan_freq,
1916*5113495bSYour Name 				   &acs_cfg->pcl_ch_count,
1917*5113495bSYour Name 				   acs_cfg->pcl_channels_weight_list,
1918*5113495bSYour Name 				   NUM_CHANNELS, adapter->deflink->vdev_id);
1919*5113495bSYour Name 		wlan_hdd_trim_acs_channel_list(acs_cfg->pcl_chan_freq,
1920*5113495bSYour Name 					       acs_cfg->pcl_ch_count,
1921*5113495bSYour Name 					       acs_cfg->freq_list,
1922*5113495bSYour Name 					       &acs_cfg->ch_list_count);
1923*5113495bSYour Name 		if (!acs_cfg->ch_list_count && acs_cfg->master_ch_list_count)
1924*5113495bSYour Name 			wlan_hdd_handle_zero_acs_list
1925*5113495bSYour Name 					       (hdd_ctx,
1926*5113495bSYour Name 						acs_cfg->freq_list,
1927*5113495bSYour Name 						&acs_cfg->ch_list_count,
1928*5113495bSYour Name 						acs_cfg->master_freq_list,
1929*5113495bSYour Name 						acs_cfg->master_ch_list_count);
1930*5113495bSYour Name 	}
1931*5113495bSYour Name 	acs_cfg->start_ch_freq = acs_cfg->freq_list[0];
1932*5113495bSYour Name 	acs_cfg->end_ch_freq = acs_cfg->freq_list[acs_cfg->ch_list_count - 1];
1933*5113495bSYour Name 	acs_cfg->hw_mode = eCSR_DOT11_MODE_abg;
1934*5113495bSYour Name 
1935*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1936*5113495bSYour Name }
1937*5113495bSYour Name 
1938*5113495bSYour Name /**
1939*5113495bSYour Name  * hdd_son_start_acs() -Trigers ACS
1940*5113495bSYour Name  *
1941*5113495bSYour Name  * @vdev: pointer to object mgr vdev
1942*5113495bSYour Name  * @enable: True to trigger ACS
1943*5113495bSYour Name  *
1944*5113495bSYour Name  * Return: 0 on success
1945*5113495bSYour Name  */
hdd_son_start_acs(struct wlan_objmgr_vdev * vdev,uint8_t enable)1946*5113495bSYour Name static int hdd_son_start_acs(struct wlan_objmgr_vdev *vdev, uint8_t enable)
1947*5113495bSYour Name {
1948*5113495bSYour Name 	struct hdd_adapter *adapter;
1949*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
1950*5113495bSYour Name 	struct sap_config *sap_config;
1951*5113495bSYour Name 	struct hdd_context *hdd_ctx;
1952*5113495bSYour Name 
1953*5113495bSYour Name 	if (!enable) {
1954*5113495bSYour Name 		hdd_err("ACS Start report with disabled flag");
1955*5113495bSYour Name 		return -EINVAL;
1956*5113495bSYour Name 	}
1957*5113495bSYour Name 
1958*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
1959*5113495bSYour Name 	if (!link_info) {
1960*5113495bSYour Name 		hdd_err("Invalid VDEV %d", wlan_vdev_get_id(vdev));
1961*5113495bSYour Name 		return -EINVAL;
1962*5113495bSYour Name 	}
1963*5113495bSYour Name 
1964*5113495bSYour Name 	adapter = link_info->adapter;
1965*5113495bSYour Name 	if (adapter->device_mode != QDF_SAP_MODE) {
1966*5113495bSYour Name 		hdd_err("Invalid device mode %d", adapter->device_mode);
1967*5113495bSYour Name 		return -EINVAL;
1968*5113495bSYour Name 	}
1969*5113495bSYour Name 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1970*5113495bSYour Name 	if (!hdd_ctx) {
1971*5113495bSYour Name 		hdd_err("null hdd_ctx");
1972*5113495bSYour Name 		return -EINVAL;
1973*5113495bSYour Name 	}
1974*5113495bSYour Name 	if (qdf_atomic_read(&link_info->session.ap.acs_in_progress)) {
1975*5113495bSYour Name 		hdd_err("ACS is in-progress");
1976*5113495bSYour Name 		return -EAGAIN;
1977*5113495bSYour Name 	}
1978*5113495bSYour Name 	wlan_hdd_undo_acs(link_info);
1979*5113495bSYour Name 	sap_config = &link_info->session.ap.sap_config;
1980*5113495bSYour Name 	hdd_debug("ACS Config country %s hw_mode %d ACS_BW: %d START_CH: %d END_CH: %d band %d",
1981*5113495bSYour Name 		  hdd_ctx->reg.alpha2, sap_config->acs_cfg.hw_mode,
1982*5113495bSYour Name 		  sap_config->acs_cfg.ch_width,
1983*5113495bSYour Name 		  sap_config->acs_cfg.start_ch_freq,
1984*5113495bSYour Name 		  sap_config->acs_cfg.end_ch_freq, sap_config->acs_cfg.band);
1985*5113495bSYour Name 	sap_dump_acs_channel(&sap_config->acs_cfg);
1986*5113495bSYour Name 
1987*5113495bSYour Name 	wlan_hdd_cfg80211_start_acs(link_info);
1988*5113495bSYour Name 
1989*5113495bSYour Name 	return 0;
1990*5113495bSYour Name }
1991*5113495bSYour Name 
1992*5113495bSYour Name #define ACS_SET_CHAN_LIST_APPEND 0xFF
1993*5113495bSYour Name #define ACS_SNR_NEAR_RANGE_MIN 60
1994*5113495bSYour Name #define ACS_SNR_MID_RANGE_MIN 30
1995*5113495bSYour Name #define ACS_SNR_FAR_RANGE_MIN 0
1996*5113495bSYour Name 
1997*5113495bSYour Name /**
1998*5113495bSYour Name  * hdd_son_set_acs_channels() - Sets Channels for ACS
1999*5113495bSYour Name  *
2000*5113495bSYour Name  * @vdev: pointer to object mgr vdev
2001*5113495bSYour Name  * @req: target channels
2002*5113495bSYour Name  *
2003*5113495bSYour Name  * Return: 0 on success
2004*5113495bSYour Name  */
hdd_son_set_acs_channels(struct wlan_objmgr_vdev * vdev,struct ieee80211req_athdbg * req)2005*5113495bSYour Name static int hdd_son_set_acs_channels(struct wlan_objmgr_vdev *vdev,
2006*5113495bSYour Name 				    struct ieee80211req_athdbg *req)
2007*5113495bSYour Name {
2008*5113495bSYour Name 	struct sap_config *sap_config;
2009*5113495bSYour Name 	/* Append the new channels with existing channel list */
2010*5113495bSYour Name 	bool append;
2011*5113495bSYour Name 	/* Duplicate */
2012*5113495bSYour Name 	bool dup;
2013*5113495bSYour Name 	uint32_t freq_list[ACS_MAX_CHANNEL_COUNT];
2014*5113495bSYour Name 	uint32_t num_channels;
2015*5113495bSYour Name 	uint32_t chan_idx = 0;
2016*5113495bSYour Name 	uint32_t tmp;
2017*5113495bSYour Name 	uint16_t chan_start = 0;
2018*5113495bSYour Name 	uint16_t i, j;
2019*5113495bSYour Name 	uint16_t acs_chan_count = 0;
2020*5113495bSYour Name 	uint32_t *prev_acs_list;
2021*5113495bSYour Name 	struct ieee80211_chan_def *chans = req->data.user_chanlist.chans;
2022*5113495bSYour Name 	uint16_t nchans = req->data.user_chanlist.n_chan;
2023*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
2024*5113495bSYour Name 	struct hdd_adapter *adapter;
2025*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
2026*5113495bSYour Name 	struct hdd_context *hdd_ctx;
2027*5113495bSYour Name 
2028*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
2029*5113495bSYour Name 	if (!link_info || !req) {
2030*5113495bSYour Name 		hdd_err("null adapter or req");
2031*5113495bSYour Name 		return -EINVAL;
2032*5113495bSYour Name 	}
2033*5113495bSYour Name 
2034*5113495bSYour Name 	adapter = link_info->adapter;
2035*5113495bSYour Name 	if (adapter->device_mode != QDF_SAP_MODE) {
2036*5113495bSYour Name 		hdd_err("Invalid device mode %d", adapter->device_mode);
2037*5113495bSYour Name 		return -EINVAL;
2038*5113495bSYour Name 	}
2039*5113495bSYour Name 	if (!nchans) {
2040*5113495bSYour Name 		hdd_err("No channels are sent to be set");
2041*5113495bSYour Name 		return -EINVAL;
2042*5113495bSYour Name 	}
2043*5113495bSYour Name 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2044*5113495bSYour Name 	if (!hdd_ctx) {
2045*5113495bSYour Name 		hdd_err("null hdd_ctx");
2046*5113495bSYour Name 		return -EINVAL;
2047*5113495bSYour Name 	}
2048*5113495bSYour Name 	sap_config = &link_info->session.ap.sap_config;
2049*5113495bSYour Name 	/* initialize with default channels */
2050*5113495bSYour Name 	if (hdd_son_init_acs_channels(adapter, hdd_ctx, &sap_config->acs_cfg)
2051*5113495bSYour Name 						       != QDF_STATUS_SUCCESS) {
2052*5113495bSYour Name 		hdd_err("Failed to start the ACS");
2053*5113495bSYour Name 		return -EAGAIN;
2054*5113495bSYour Name 	}
2055*5113495bSYour Name 	append = (chans[0].chan == ACS_SET_CHAN_LIST_APPEND);
2056*5113495bSYour Name 	if (append) {
2057*5113495bSYour Name 		chan_start = 1;
2058*5113495bSYour Name 		acs_chan_count = sap_config->acs_cfg.ch_list_count;
2059*5113495bSYour Name 	}
2060*5113495bSYour Name 	prev_acs_list = sap_config->acs_cfg.freq_list;
2061*5113495bSYour Name 	for (i = chan_start; i < nchans; i++) {
2062*5113495bSYour Name 		tmp = wlan_reg_legacy_chan_to_freq(pdev, chans[i].chan);
2063*5113495bSYour Name 		if (append) {
2064*5113495bSYour Name 			for (j = 0; j < acs_chan_count; j++) {
2065*5113495bSYour Name 				if (prev_acs_list[j] == tmp) {
2066*5113495bSYour Name 					dup = true;
2067*5113495bSYour Name 					break;
2068*5113495bSYour Name 				}
2069*5113495bSYour Name 			}
2070*5113495bSYour Name 		}
2071*5113495bSYour Name 		/* Remove duplicate */
2072*5113495bSYour Name 		if (!dup) {
2073*5113495bSYour Name 			freq_list[chan_idx] = tmp;
2074*5113495bSYour Name 			chan_idx++;
2075*5113495bSYour Name 		} else {
2076*5113495bSYour Name 			dup = false;
2077*5113495bSYour Name 		}
2078*5113495bSYour Name 	}
2079*5113495bSYour Name 	num_channels = chan_idx + acs_chan_count;
2080*5113495bSYour Name 	sap_config->acs_cfg.ch_list_count = num_channels;
2081*5113495bSYour Name 	sap_config->acs_cfg.freq_list =
2082*5113495bSYour Name 			qdf_mem_malloc(num_channels *
2083*5113495bSYour Name 				       sizeof(*sap_config->acs_cfg.freq_list));
2084*5113495bSYour Name 	if (!sap_config->acs_cfg.freq_list) {
2085*5113495bSYour Name 		hdd_err("Error in allocating memory, failed to set channels");
2086*5113495bSYour Name 		sap_config->acs_cfg.freq_list = prev_acs_list;
2087*5113495bSYour Name 		sap_config->acs_cfg.ch_list_count = acs_chan_count;
2088*5113495bSYour Name 		return -ENOMEM;
2089*5113495bSYour Name 	}
2090*5113495bSYour Name 	if (append)
2091*5113495bSYour Name 		qdf_mem_copy(sap_config->acs_cfg.freq_list, prev_acs_list,
2092*5113495bSYour Name 			     sizeof(uint32_t) * acs_chan_count);
2093*5113495bSYour Name 	qdf_mem_copy(&sap_config->acs_cfg.freq_list[acs_chan_count], freq_list,
2094*5113495bSYour Name 		     sizeof(uint32_t) * chan_idx);
2095*5113495bSYour Name 	qdf_mem_free(prev_acs_list);
2096*5113495bSYour Name 
2097*5113495bSYour Name 	return 0;
2098*5113495bSYour Name }
2099*5113495bSYour Name 
2100*5113495bSYour Name static enum wlan_band_id
reg_wifi_band_to_wlan_band_id(enum reg_wifi_band reg_wifi_band)2101*5113495bSYour Name reg_wifi_band_to_wlan_band_id(enum reg_wifi_band reg_wifi_band)
2102*5113495bSYour Name {
2103*5113495bSYour Name 	enum wlan_band_id wlan_band;
2104*5113495bSYour Name 	const uint32_t reg_wifi_band_to_wlan_band_id_map[] = {
2105*5113495bSYour Name 		[REG_BAND_2G] = WLAN_BAND_2GHZ,
2106*5113495bSYour Name 		[REG_BAND_5G] = WLAN_BAND_5GHZ,
2107*5113495bSYour Name 		[REG_BAND_6G] = WLAN_BAND_6GHZ,
2108*5113495bSYour Name 		[REG_BAND_UNKNOWN] = WLAN_BAND_MAX,};
2109*5113495bSYour Name 
2110*5113495bSYour Name 	wlan_band = reg_wifi_band_to_wlan_band_id_map[reg_wifi_band];
2111*5113495bSYour Name 	if (wlan_band == WLAN_BAND_MAX) {
2112*5113495bSYour Name 		hdd_err("Invalid wlan_band_id %d, reg_wifi_band: %d",
2113*5113495bSYour Name 			wlan_band, reg_wifi_band);
2114*5113495bSYour Name 		return -EINVAL;
2115*5113495bSYour Name 	}
2116*5113495bSYour Name 
2117*5113495bSYour Name 	return wlan_band;
2118*5113495bSYour Name }
2119*5113495bSYour Name 
2120*5113495bSYour Name /**
2121*5113495bSYour Name  * get_son_acs_report_values() - Gets ACS report for target channel
2122*5113495bSYour Name  *
2123*5113495bSYour Name  * @vdev: pointer to object mgr vdev
2124*5113495bSYour Name  * @acs_r: pointer to acs_dbg
2125*5113495bSYour Name  * @mac_handle: Handle to MAC
2126*5113495bSYour Name  * @chan_freq: Channel frequency
2127*5113495bSYour Name  *
2128*5113495bSYour Name  * Return: void
2129*5113495bSYour Name  */
get_son_acs_report_values(struct wlan_objmgr_vdev * vdev,struct ieee80211_acs_dbg * acs_r,mac_handle_t mac_handle,uint16_t chan_freq)2130*5113495bSYour Name static void get_son_acs_report_values(struct wlan_objmgr_vdev *vdev,
2131*5113495bSYour Name 				      struct ieee80211_acs_dbg *acs_r,
2132*5113495bSYour Name 				      mac_handle_t mac_handle,
2133*5113495bSYour Name 				      uint16_t chan_freq)
2134*5113495bSYour Name {
2135*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
2136*5113495bSYour Name 	struct scan_filter *filter = qdf_mem_malloc(sizeof(*filter));
2137*5113495bSYour Name 	struct scan_cache_node *cur_node;
2138*5113495bSYour Name 	struct scan_cache_entry *se;
2139*5113495bSYour Name 	enum ieee80211_phymode phymode_se;
2140*5113495bSYour Name 	struct ieee80211_ie_hecap *hecap_ie;
2141*5113495bSYour Name 	struct ieee80211_ie_srp_extie *srp_ie;
2142*5113495bSYour Name 	qdf_list_node_t *cur_lst = NULL, *next_lst = NULL;
2143*5113495bSYour Name 	uint32_t srps = 0;
2144*5113495bSYour Name 	qdf_list_t *scan_list = NULL;
2145*5113495bSYour Name 	uint8_t snr_se, *hecap_phy_ie;
2146*5113495bSYour Name 
2147*5113495bSYour Name 	if (!filter)
2148*5113495bSYour Name 		return;
2149*5113495bSYour Name 	filter->num_of_channels = 1;
2150*5113495bSYour Name 	filter->chan_freq_list[0] = chan_freq;
2151*5113495bSYour Name 	scan_list = ucfg_scan_get_result(pdev, filter);
2152*5113495bSYour Name 	acs_r->chan_nbss = qdf_list_size(scan_list);
2153*5113495bSYour Name 
2154*5113495bSYour Name 	acs_r->chan_maxrssi = 0;
2155*5113495bSYour Name 	acs_r->chan_minrssi = 0;
2156*5113495bSYour Name 	acs_r->chan_nbss_near = 0;
2157*5113495bSYour Name 	acs_r->chan_nbss_mid = 0;
2158*5113495bSYour Name 	acs_r->chan_nbss_far = 0;
2159*5113495bSYour Name 	acs_r->chan_nbss_srp = 0;
2160*5113495bSYour Name 	qdf_list_peek_front(scan_list, &cur_lst);
2161*5113495bSYour Name 	while (cur_lst) {
2162*5113495bSYour Name 		qdf_list_peek_next(scan_list, cur_lst, &next_lst);
2163*5113495bSYour Name 		cur_node = qdf_container_of(cur_lst,
2164*5113495bSYour Name 					    struct scan_cache_node, node);
2165*5113495bSYour Name 		se = cur_node->entry;
2166*5113495bSYour Name 		snr_se = util_scan_entry_snr(se);
2167*5113495bSYour Name 		hecap_ie = (struct ieee80211_ie_hecap *)
2168*5113495bSYour Name 			   util_scan_entry_hecap(se);
2169*5113495bSYour Name 		srp_ie = (struct ieee80211_ie_srp_extie *)
2170*5113495bSYour Name 			 util_scan_entry_spatial_reuse_parameter(se);
2171*5113495bSYour Name 		phymode_se = util_scan_entry_phymode(se);
2172*5113495bSYour Name 
2173*5113495bSYour Name 		if (hecap_ie) {
2174*5113495bSYour Name 			hecap_phy_ie = &hecap_ie->hecap_phyinfo[0];
2175*5113495bSYour Name 			srps = hecap_phy_ie[HECAP_PHYBYTE_IDX7] &
2176*5113495bSYour Name 			       HECAP_PHY_SRP_SR_BITS;
2177*5113495bSYour Name 		}
2178*5113495bSYour Name 
2179*5113495bSYour Name 		if (acs_r->chan_maxrssi < snr_se)
2180*5113495bSYour Name 			acs_r->chan_maxrssi = snr_se;
2181*5113495bSYour Name 		else if (acs_r->chan_minrssi > snr_se)
2182*5113495bSYour Name 			acs_r->chan_minrssi = snr_se;
2183*5113495bSYour Name 		if (snr_se > ACS_SNR_NEAR_RANGE_MIN)
2184*5113495bSYour Name 			acs_r->chan_nbss_near += 1;
2185*5113495bSYour Name 		else if (snr_se > ACS_SNR_MID_RANGE_MIN)
2186*5113495bSYour Name 			acs_r->chan_nbss_mid += 1;
2187*5113495bSYour Name 		else
2188*5113495bSYour Name 			acs_r->chan_nbss_far += 1;
2189*5113495bSYour Name 		if (srp_ie &&
2190*5113495bSYour Name 		    (!(srp_ie->sr_control &
2191*5113495bSYour Name 		       IEEE80211_SRP_SRCTRL_OBSS_PD_DISALLOWED_MASK) || srps))
2192*5113495bSYour Name 			acs_r->chan_nbss_srp++;
2193*5113495bSYour Name 
2194*5113495bSYour Name 		cur_lst = next_lst;
2195*5113495bSYour Name 		next_lst = NULL;
2196*5113495bSYour Name 	}
2197*5113495bSYour Name 	acs_r->chan_80211_b_duration = sme_get_11b_data_duration(mac_handle,
2198*5113495bSYour Name 								 chan_freq);
2199*5113495bSYour Name 	acs_r->chan_nbss_eff = 100 + (acs_r->chan_nbss_near * 50)
2200*5113495bSYour Name 				   + (acs_r->chan_nbss_mid * 50)
2201*5113495bSYour Name 				   + (acs_r->chan_nbss_far * 25);
2202*5113495bSYour Name 	acs_r->chan_srp_load = acs_r->chan_nbss_srp * 4;
2203*5113495bSYour Name 	acs_r->chan_efficiency = (1000 + acs_r->chan_grade) /
2204*5113495bSYour Name 				  acs_r->chan_nbss_eff;
2205*5113495bSYour Name 	ucfg_scan_purge_results(scan_list);
2206*5113495bSYour Name 
2207*5113495bSYour Name 	qdf_mem_free(filter);
2208*5113495bSYour Name }
2209*5113495bSYour Name 
2210*5113495bSYour Name /**
2211*5113495bSYour Name  * hdd_son_get_acs_report() - Gets ACS report
2212*5113495bSYour Name  *
2213*5113495bSYour Name  * @vdev: pointer to object mgr vdev
2214*5113495bSYour Name  * @acs_report: pointer to acs_dbg
2215*5113495bSYour Name  *
2216*5113495bSYour Name  * Return: 0 on success
2217*5113495bSYour Name  */
hdd_son_get_acs_report(struct wlan_objmgr_vdev * vdev,struct ieee80211_acs_dbg * acs_report)2218*5113495bSYour Name static int hdd_son_get_acs_report(struct wlan_objmgr_vdev *vdev,
2219*5113495bSYour Name 				  struct ieee80211_acs_dbg *acs_report)
2220*5113495bSYour Name {
2221*5113495bSYour Name 	struct hdd_adapter *adapter;
2222*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
2223*5113495bSYour Name 	uint8_t  acs_entry_id = 0;
2224*5113495bSYour Name 	ACS_LIST_TYPE acs_type = 0;
2225*5113495bSYour Name 	int ret = 0, i = 0;
2226*5113495bSYour Name 	struct sap_acs_cfg *acs_cfg;
2227*5113495bSYour Name 	struct hdd_context *hdd_ctx;
2228*5113495bSYour Name 	struct ieee80211_acs_dbg *acs_r = NULL;
2229*5113495bSYour Name 	struct sap_context *sap_ctx;
2230*5113495bSYour Name 	qdf_size_t not_copied;
2231*5113495bSYour Name 
2232*5113495bSYour Name 	if (!acs_report) {
2233*5113495bSYour Name 		hdd_err("null acs_report");
2234*5113495bSYour Name 		ret = -EINVAL;
2235*5113495bSYour Name 		goto end;
2236*5113495bSYour Name 	}
2237*5113495bSYour Name 
2238*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
2239*5113495bSYour Name 	if (!link_info) {
2240*5113495bSYour Name 		hdd_err("null adapter");
2241*5113495bSYour Name 		ret = -EINVAL;
2242*5113495bSYour Name 		goto end;
2243*5113495bSYour Name 	}
2244*5113495bSYour Name 
2245*5113495bSYour Name 	adapter = link_info->adapter;
2246*5113495bSYour Name 	if (adapter->device_mode != QDF_SAP_MODE) {
2247*5113495bSYour Name 		hdd_err("Invalid device mode %d", adapter->device_mode);
2248*5113495bSYour Name 		ret = -EINVAL;
2249*5113495bSYour Name 		goto end;
2250*5113495bSYour Name 	}
2251*5113495bSYour Name 	if (hdd_son_is_acs_in_progress(vdev)) {
2252*5113495bSYour Name 		acs_report->nchans = 0;
2253*5113495bSYour Name 		hdd_err("ACS is in-progress");
2254*5113495bSYour Name 		ret = -EAGAIN;
2255*5113495bSYour Name 		goto end;
2256*5113495bSYour Name 	}
2257*5113495bSYour Name 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2258*5113495bSYour Name 	if (!hdd_ctx) {
2259*5113495bSYour Name 		hdd_err("null hdd_ctx");
2260*5113495bSYour Name 		ret = -EINVAL;
2261*5113495bSYour Name 		goto end;
2262*5113495bSYour Name 	}
2263*5113495bSYour Name 	acs_r = qdf_mem_malloc(sizeof(*acs_r));
2264*5113495bSYour Name 	if (!acs_r) {
2265*5113495bSYour Name 		hdd_err("Failed to allocate memory");
2266*5113495bSYour Name 		ret = -ENOMEM;
2267*5113495bSYour Name 		goto end;
2268*5113495bSYour Name 	}
2269*5113495bSYour Name 	sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(link_info);
2270*5113495bSYour Name 	acs_cfg = &link_info->session.ap.sap_config.acs_cfg;
2271*5113495bSYour Name 	if (!acs_cfg->freq_list &&
2272*5113495bSYour Name 	    (hdd_son_init_acs_channels(adapter, hdd_ctx,
2273*5113495bSYour Name 				       acs_cfg) != QDF_STATUS_SUCCESS)) {
2274*5113495bSYour Name 		hdd_err("Failed to start the ACS");
2275*5113495bSYour Name 		ret = -EAGAIN;
2276*5113495bSYour Name 		goto end_acs_r_free;
2277*5113495bSYour Name 	}
2278*5113495bSYour Name 	acs_r->nchans = acs_cfg->ch_list_count;
2279*5113495bSYour Name 	ret = copy_from_user(&acs_entry_id, &acs_report->entry_id,
2280*5113495bSYour Name 			     sizeof(acs_report->entry_id));
2281*5113495bSYour Name 	hdd_debug("acs entry id: %u num of channels: %u",
2282*5113495bSYour Name 		  acs_entry_id, acs_r->nchans);
2283*5113495bSYour Name 	if (acs_entry_id > acs_r->nchans) {
2284*5113495bSYour Name 		ret = -EINVAL;
2285*5113495bSYour Name 		goto end_acs_r_free;
2286*5113495bSYour Name 	}
2287*5113495bSYour Name 	ret = copy_from_user(&acs_type, &acs_report->acs_type,
2288*5113495bSYour Name 			     sizeof(acs_report->acs_type));
2289*5113495bSYour Name 
2290*5113495bSYour Name 	acs_r->acs_status = ACS_DEFAULT;
2291*5113495bSYour Name 	acs_r->chan_freq = acs_cfg->freq_list[acs_entry_id];
2292*5113495bSYour Name 	acs_r->chan_band = reg_wifi_band_to_wlan_band_id
2293*5113495bSYour Name 				(wlan_reg_freq_to_band(acs_r->chan_freq));
2294*5113495bSYour Name 	hdd_debug("acs type: %d", acs_type);
2295*5113495bSYour Name 	if (acs_type == ACS_CHAN_STATS) {
2296*5113495bSYour Name 		acs_r->ieee_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
2297*5113495bSYour Name 							 acs_r->chan_freq);
2298*5113495bSYour Name 		acs_r->chan_width = IEEE80211_CWM_WIDTH20;
2299*5113495bSYour Name 		acs_r->channel_loading = 0;
2300*5113495bSYour Name 		acs_r->chan_availability = 100;
2301*5113495bSYour Name 		acs_r->chan_grade = 100; /* as hw_chan_grade is 100 in WIN 8 */
2302*5113495bSYour Name 		acs_r->sec_chan = false;
2303*5113495bSYour Name 		acs_r->chan_radar_noise =
2304*5113495bSYour Name 		    wlansap_is_channel_in_nol_list(sap_ctx, acs_r->chan_freq,
2305*5113495bSYour Name 						   PHY_SINGLE_CHANNEL_CENTERED);
2306*5113495bSYour Name 		get_son_acs_report_values(vdev, acs_r, hdd_ctx->mac_handle,
2307*5113495bSYour Name 					  acs_r->chan_freq);
2308*5113495bSYour Name 		acs_r->chan_load = 0;
2309*5113495bSYour Name 		acs_r->noisefloor = -254; /* NF_INVALID */
2310*5113495bSYour Name 		for (i = 0; i < SIR_MAX_NUM_CHANNELS; i++) {
2311*5113495bSYour Name 			if (hdd_ctx->chan_info[i].freq == acs_r->chan_freq) {
2312*5113495bSYour Name 				acs_r->noisefloor =
2313*5113495bSYour Name 					hdd_ctx->chan_info[i].noise_floor;
2314*5113495bSYour Name 				acs_r->chan_load =
2315*5113495bSYour Name 					hdd_ctx->chan_info[i].rx_clear_count;
2316*5113495bSYour Name 				break;
2317*5113495bSYour Name 			}
2318*5113495bSYour Name 		}
2319*5113495bSYour Name 		not_copied = copy_to_user(acs_report, acs_r, sizeof(*acs_r));
2320*5113495bSYour Name 		if (not_copied)
2321*5113495bSYour Name 			hdd_debug("%ul is not copied", not_copied);
2322*5113495bSYour Name 	} else if (acs_type == ACS_CHAN_NF_STATS) {
2323*5113495bSYour Name 	} else if (acs_type == ACS_NEIGHBOUR_GET_LIST_COUNT ||
2324*5113495bSYour Name 		   acs_type == ACS_NEIGHBOUR_GET_LIST) {
2325*5113495bSYour Name 	}
2326*5113495bSYour Name end_acs_r_free:
2327*5113495bSYour Name 	qdf_mem_free(acs_r);
2328*5113495bSYour Name end:
2329*5113495bSYour Name 	return ret;
2330*5113495bSYour Name }
2331*5113495bSYour Name 
2332*5113495bSYour Name static const uint8_t wlanphymode2ieeephymode[WLAN_PHYMODE_MAX] = {
2333*5113495bSYour Name 	[WLAN_PHYMODE_AUTO] = IEEE80211_MODE_AUTO,
2334*5113495bSYour Name 	[WLAN_PHYMODE_11A] = IEEE80211_MODE_11A,
2335*5113495bSYour Name 	[WLAN_PHYMODE_11B] = IEEE80211_MODE_11B,
2336*5113495bSYour Name 	[WLAN_PHYMODE_11G] = IEEE80211_MODE_11G,
2337*5113495bSYour Name 	[WLAN_PHYMODE_11G_ONLY] = IEEE80211_MODE_11G,
2338*5113495bSYour Name 	[WLAN_PHYMODE_11NA_HT20] = IEEE80211_MODE_11NA_HT20,
2339*5113495bSYour Name 	[WLAN_PHYMODE_11NG_HT20] = IEEE80211_MODE_11NG_HT20,
2340*5113495bSYour Name 	[WLAN_PHYMODE_11NA_HT40] = IEEE80211_MODE_11NA_HT40,
2341*5113495bSYour Name 	[WLAN_PHYMODE_11NG_HT40PLUS] = IEEE80211_MODE_11NG_HT40PLUS,
2342*5113495bSYour Name 	[WLAN_PHYMODE_11NG_HT40MINUS] = IEEE80211_MODE_11NG_HT40MINUS,
2343*5113495bSYour Name 	[WLAN_PHYMODE_11NG_HT40] = IEEE80211_MODE_11NG_HT40,
2344*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT20] = IEEE80211_MODE_11AC_VHT20,
2345*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT20_2G] = IEEE80211_MODE_11AC_VHT20,
2346*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT40] = IEEE80211_MODE_11AC_VHT40,
2347*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT40PLUS_2G] = IEEE80211_MODE_11AC_VHT40PLUS,
2348*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT40MINUS_2G] = IEEE80211_MODE_11AC_VHT40MINUS,
2349*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT40_2G] = IEEE80211_MODE_11AC_VHT40,
2350*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT80] = IEEE80211_MODE_11AC_VHT80,
2351*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT80_2G] = IEEE80211_MODE_11AC_VHT80,
2352*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT160] = IEEE80211_MODE_11AC_VHT160,
2353*5113495bSYour Name 	[WLAN_PHYMODE_11AC_VHT80_80] = IEEE80211_MODE_11AC_VHT80_80,
2354*5113495bSYour Name 	[WLAN_PHYMODE_11AXA_HE20] = IEEE80211_MODE_11AXA_HE20,
2355*5113495bSYour Name 	[WLAN_PHYMODE_11AXG_HE20] = IEEE80211_MODE_11AXG_HE20,
2356*5113495bSYour Name 	[WLAN_PHYMODE_11AXA_HE40] = IEEE80211_MODE_11AXA_HE40,
2357*5113495bSYour Name 	[WLAN_PHYMODE_11AXG_HE40PLUS] = IEEE80211_MODE_11AXG_HE40PLUS,
2358*5113495bSYour Name 	[WLAN_PHYMODE_11AXG_HE40MINUS] = IEEE80211_MODE_11AXG_HE40MINUS,
2359*5113495bSYour Name 	[WLAN_PHYMODE_11AXG_HE40] = IEEE80211_MODE_11AXG_HE40,
2360*5113495bSYour Name 	[WLAN_PHYMODE_11AXA_HE80] = IEEE80211_MODE_11AXA_HE80,
2361*5113495bSYour Name 	[WLAN_PHYMODE_11AXA_HE160] = IEEE80211_MODE_11AXA_HE160,
2362*5113495bSYour Name 	[WLAN_PHYMODE_11AXA_HE80_80] = IEEE80211_MODE_11AXA_HE80_80,
2363*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
2364*5113495bSYour Name 	[WLAN_PHYMODE_11BEA_EHT20] = IEEE80211_MODE_11BEA_EHT20,
2365*5113495bSYour Name 	[WLAN_PHYMODE_11BEG_EHT20] = IEEE80211_MODE_11BEG_EHT20,
2366*5113495bSYour Name 	[WLAN_PHYMODE_11BEA_EHT40MINUS] = IEEE80211_MODE_11BEA_EHT40,
2367*5113495bSYour Name 	[WLAN_PHYMODE_11BEG_EHT40PLUS] = IEEE80211_MODE_11BEG_EHT40PLUS,
2368*5113495bSYour Name 	[WLAN_PHYMODE_11BEG_EHT40MINUS] = IEEE80211_MODE_11BEG_EHT40MINUS,
2369*5113495bSYour Name 	[WLAN_PHYMODE_11BEG_EHT40] = IEEE80211_MODE_11BEG_EHT40,
2370*5113495bSYour Name 	[WLAN_PHYMODE_11BEA_EHT80] = IEEE80211_MODE_11BEA_EHT80,
2371*5113495bSYour Name 	[WLAN_PHYMODE_11BEG_EHT80] = 0,
2372*5113495bSYour Name 	[WLAN_PHYMODE_11BEA_EHT160] = IEEE80211_MODE_11BEA_EHT160,
2373*5113495bSYour Name 	[WLAN_PHYMODE_11BEA_EHT320] = IEEE80211_MODE_11BEA_EHT320,
2374*5113495bSYour Name #endif /* WLAN_FEATURE_11BE */
2375*5113495bSYour Name };
2376*5113495bSYour Name 
2377*5113495bSYour Name static enum ieee80211_phymode
wlan_hdd_son_get_ieee_phymode(enum wlan_phymode wlan_phymode)2378*5113495bSYour Name wlan_hdd_son_get_ieee_phymode(enum wlan_phymode wlan_phymode)
2379*5113495bSYour Name {
2380*5113495bSYour Name 	if (wlan_phymode >= WLAN_PHYMODE_MAX)
2381*5113495bSYour Name 		return IEEE80211_MODE_AUTO;
2382*5113495bSYour Name 
2383*5113495bSYour Name 	return wlanphymode2ieeephymode[wlan_phymode];
2384*5113495bSYour Name }
2385*5113495bSYour Name 
2386*5113495bSYour Name /**
2387*5113495bSYour Name  * hdd_son_get_peer_tx_rate() - Get peer tx rate from FW
2388*5113495bSYour Name  * @vdev: pointer to object mgr vdev
2389*5113495bSYour Name  * @peer_macaddr: peer mac address
2390*5113495bSYour Name  *
2391*5113495bSYour Name  * Return: tx rate in Kbps
2392*5113495bSYour Name  */
hdd_son_get_peer_tx_rate(struct wlan_objmgr_vdev * vdev,uint8_t * peer_macaddr)2393*5113495bSYour Name static uint32_t hdd_son_get_peer_tx_rate(struct wlan_objmgr_vdev *vdev,
2394*5113495bSYour Name 					 uint8_t *peer_macaddr)
2395*5113495bSYour Name {
2396*5113495bSYour Name 	uint32_t tx_rate = 0;
2397*5113495bSYour Name 	struct stats_event *stats;
2398*5113495bSYour Name 	int retval = 0;
2399*5113495bSYour Name 
2400*5113495bSYour Name 	stats = wlan_cfg80211_mc_cp_stats_get_peer_stats(vdev,
2401*5113495bSYour Name 							 peer_macaddr,
2402*5113495bSYour Name 							 &retval);
2403*5113495bSYour Name 	if (retval || !stats) {
2404*5113495bSYour Name 		if (stats)
2405*5113495bSYour Name 			wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
2406*5113495bSYour Name 		hdd_err("Unable to get peer tx rate from fw");
2407*5113495bSYour Name 		return tx_rate;
2408*5113495bSYour Name 	}
2409*5113495bSYour Name 
2410*5113495bSYour Name 	tx_rate = stats->peer_stats_info_ext->tx_rate;
2411*5113495bSYour Name 	wlan_cfg80211_mc_cp_stats_free_stats_event(stats);
2412*5113495bSYour Name 
2413*5113495bSYour Name 	return tx_rate;
2414*5113495bSYour Name }
2415*5113495bSYour Name 
hdd_son_get_node_info_sta(struct wlan_objmgr_vdev * vdev,uint8_t * mac_addr,wlan_node_info * node_info)2416*5113495bSYour Name static QDF_STATUS hdd_son_get_node_info_sta(struct wlan_objmgr_vdev *vdev,
2417*5113495bSYour Name 					    uint8_t *mac_addr,
2418*5113495bSYour Name 					    wlan_node_info *node_info)
2419*5113495bSYour Name {
2420*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
2421*5113495bSYour Name 
2422*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
2423*5113495bSYour Name 	if (!link_info ||
2424*5113495bSYour Name 	    wlan_hdd_validate_context(link_info->adapter->hdd_ctx))
2425*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2426*5113495bSYour Name 
2427*5113495bSYour Name 	if (!hdd_cm_is_vdev_associated(link_info)) {
2428*5113495bSYour Name 		hdd_debug_rl("STA VDEV not connected");
2429*5113495bSYour Name 		/* Still return success and framework will see default stats */
2430*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2431*5113495bSYour Name 	}
2432*5113495bSYour Name 
2433*5113495bSYour Name 	node_info->tx_bitrate = hdd_son_get_peer_tx_rate(vdev, mac_addr);
2434*5113495bSYour Name 	/* convert it to Mbps */
2435*5113495bSYour Name 	node_info->tx_bitrate = qdf_do_div(node_info->tx_bitrate, 1000);
2436*5113495bSYour Name 	hdd_debug_rl("tx_bitrate %u", node_info->tx_bitrate);
2437*5113495bSYour Name 
2438*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2439*5113495bSYour Name }
2440*5113495bSYour Name 
hdd_son_get_node_info_sap(struct wlan_objmgr_vdev * vdev,uint8_t * mac_addr,wlan_node_info * node_info)2441*5113495bSYour Name static QDF_STATUS hdd_son_get_node_info_sap(struct wlan_objmgr_vdev *vdev,
2442*5113495bSYour Name 					    uint8_t *mac_addr,
2443*5113495bSYour Name 					    wlan_node_info *node_info)
2444*5113495bSYour Name {
2445*5113495bSYour Name 	struct hdd_adapter *adapter;
2446*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
2447*5113495bSYour Name 	struct hdd_station_info *sta_info;
2448*5113495bSYour Name 	enum wlan_phymode peer_phymode;
2449*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
2450*5113495bSYour Name 
2451*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
2452*5113495bSYour Name 	if (!link_info) {
2453*5113495bSYour Name 		hdd_debug("NULL adapter");
2454*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2455*5113495bSYour Name 	}
2456*5113495bSYour Name 
2457*5113495bSYour Name 	adapter = link_info->adapter;
2458*5113495bSYour Name 	sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list, mac_addr,
2459*5113495bSYour Name 					   STA_INFO_SON_GET_DATRATE_INFO);
2460*5113495bSYour Name 	if (!sta_info) {
2461*5113495bSYour Name 		hdd_err("Sta info is null");
2462*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2463*5113495bSYour Name 	}
2464*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
2465*5113495bSYour Name 	if (!psoc) {
2466*5113495bSYour Name 		hdd_err("null psoc");
2467*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2468*5113495bSYour Name 	}
2469*5113495bSYour Name 
2470*5113495bSYour Name 	node_info->tx_bitrate = hdd_son_get_peer_tx_rate(vdev, mac_addr);
2471*5113495bSYour Name 	/* convert it to Mbps */
2472*5113495bSYour Name 	node_info->tx_bitrate = qdf_do_div(node_info->tx_bitrate, 1000);
2473*5113495bSYour Name 	node_info->max_chwidth =
2474*5113495bSYour Name 			hdd_chan_width_to_son_chwidth(sta_info->ch_width);
2475*5113495bSYour Name 	node_info->num_streams = sta_info->nss;
2476*5113495bSYour Name 	ucfg_mlme_get_peer_phymode(psoc, mac_addr, &peer_phymode);
2477*5113495bSYour Name 	node_info->phymode = wlan_hdd_son_get_ieee_phymode(peer_phymode);
2478*5113495bSYour Name 	node_info->max_txpower = ucfg_son_get_tx_power(sta_info->assoc_req_ies);
2479*5113495bSYour Name 	node_info->max_MCS = sta_info->max_real_mcs_idx;
2480*5113495bSYour Name 	if (node_info->max_MCS == INVALID_MCS_NSS_INDEX) {
2481*5113495bSYour Name 		hdd_err("invalid mcs");
2482*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2483*5113495bSYour Name 	}
2484*5113495bSYour Name 	if (sta_info->vht_present)
2485*5113495bSYour Name 		node_info->is_mu_mimo_supported =
2486*5113495bSYour Name 				sta_info->vht_caps.vht_cap_info
2487*5113495bSYour Name 				& IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
2488*5113495bSYour Name 	if (sta_info->ht_present)
2489*5113495bSYour Name 		node_info->is_static_smps = ((sta_info->ht_caps.cap_info
2490*5113495bSYour Name 				& IEEE80211_HTCAP_C_SM_MASK) ==
2491*5113495bSYour Name 				IEEE80211_HTCAP_C_SMPOWERSAVE_STATIC);
2492*5113495bSYour Name 	hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
2493*5113495bSYour Name 			     STA_INFO_SON_GET_DATRATE_INFO);
2494*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2495*5113495bSYour Name }
2496*5113495bSYour Name 
hdd_son_get_node_info(struct wlan_objmgr_vdev * vdev,uint8_t * mac_addr,wlan_node_info * node_info)2497*5113495bSYour Name static QDF_STATUS hdd_son_get_node_info(struct wlan_objmgr_vdev *vdev,
2498*5113495bSYour Name 					uint8_t *mac_addr,
2499*5113495bSYour Name 					wlan_node_info *node_info)
2500*5113495bSYour Name {
2501*5113495bSYour Name 	struct hdd_adapter *adapter;
2502*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
2503*5113495bSYour Name 
2504*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
2505*5113495bSYour Name 	if (!link_info) {
2506*5113495bSYour Name 		hdd_debug("NULL adapter");
2507*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2508*5113495bSYour Name 	}
2509*5113495bSYour Name 
2510*5113495bSYour Name 	adapter = link_info->adapter;
2511*5113495bSYour Name 	if (adapter->device_mode == QDF_STA_MODE)
2512*5113495bSYour Name 		return hdd_son_get_node_info_sta(vdev, mac_addr, node_info);
2513*5113495bSYour Name 	else if (adapter->device_mode == QDF_SAP_MODE)
2514*5113495bSYour Name 		return hdd_son_get_node_info_sap(vdev, mac_addr, node_info);
2515*5113495bSYour Name 	else
2516*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2517*5113495bSYour Name }
2518*5113495bSYour Name 
hdd_son_get_peer_capability(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer,wlan_peer_cap * peer_cap)2519*5113495bSYour Name static QDF_STATUS hdd_son_get_peer_capability(struct wlan_objmgr_vdev *vdev,
2520*5113495bSYour Name 					      struct wlan_objmgr_peer *peer,
2521*5113495bSYour Name 					      wlan_peer_cap *peer_cap)
2522*5113495bSYour Name {
2523*5113495bSYour Name 	struct hdd_station_info *sta_info;
2524*5113495bSYour Name 	struct hdd_adapter *adapter;
2525*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
2526*5113495bSYour Name 	bool b_meas_supported;
2527*5113495bSYour Name 	QDF_STATUS status;
2528*5113495bSYour Name 
2529*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
2530*5113495bSYour Name 	if (!link_info) {
2531*5113495bSYour Name 		hdd_err("null adapter");
2532*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2533*5113495bSYour Name 	}
2534*5113495bSYour Name 
2535*5113495bSYour Name 	adapter = link_info->adapter;
2536*5113495bSYour Name 	sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
2537*5113495bSYour Name 					   peer->macaddr,
2538*5113495bSYour Name 					   STA_INFO_SOFTAP_GET_STA_INFO);
2539*5113495bSYour Name 	if (!sta_info) {
2540*5113495bSYour Name 		hdd_err("sta_info NULL");
2541*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2542*5113495bSYour Name 	}
2543*5113495bSYour Name 
2544*5113495bSYour Name 	hdd_info("Getting peer capability from sta_info");
2545*5113495bSYour Name 	qdf_mem_copy(peer_cap->bssid, vdev->vdev_mlme.macaddr,
2546*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
2547*5113495bSYour Name 	peer_cap->is_BTM_Supported = !!(sta_info->ext_cap &
2548*5113495bSYour Name 				   BIT(19/*BSS_TRANSITION*/));
2549*5113495bSYour Name 	peer_cap->is_RRM_Supported = !!(sta_info->capability &
2550*5113495bSYour Name 				   WLAN_CAPABILITY_RADIO_MEASURE);
2551*5113495bSYour Name 
2552*5113495bSYour Name 	peer_cap->band_cap = sta_info->supported_band;
2553*5113495bSYour Name 	if (sta_info->assoc_req_ies.len) {
2554*5113495bSYour Name 		status = ucfg_son_get_peer_rrm_info(sta_info->assoc_req_ies,
2555*5113495bSYour Name 						    peer_cap->rrmcaps,
2556*5113495bSYour Name 						    &(b_meas_supported));
2557*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS)
2558*5113495bSYour Name 			peer_cap->is_beacon_meas_supported = b_meas_supported;
2559*5113495bSYour Name 	}
2560*5113495bSYour Name 	if (sta_info->ht_present)
2561*5113495bSYour Name 		peer_cap->htcap = sta_info->ht_caps.cap_info;
2562*5113495bSYour Name 	if (sta_info->vht_present)
2563*5113495bSYour Name 		peer_cap->vhtcap = sta_info->vht_caps.vht_cap_info;
2564*5113495bSYour Name 
2565*5113495bSYour Name 	qdf_mem_zero(&peer_cap->hecap, sizeof(wlan_client_he_capabilities));
2566*5113495bSYour Name 
2567*5113495bSYour Name 	os_if_son_get_node_datarate_info(vdev, peer->macaddr,
2568*5113495bSYour Name 					 &peer_cap->info);
2569*5113495bSYour Name 
2570*5113495bSYour Name 	hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
2571*5113495bSYour Name 			     STA_INFO_SOFTAP_GET_STA_INFO);
2572*5113495bSYour Name 
2573*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2574*5113495bSYour Name }
2575*5113495bSYour Name 
hdd_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_peer * peer)2576*5113495bSYour Name uint32_t hdd_son_get_peer_max_mcs_idx(struct wlan_objmgr_vdev *vdev,
2577*5113495bSYour Name 				      struct wlan_objmgr_peer *peer)
2578*5113495bSYour Name {
2579*5113495bSYour Name 	uint32_t ret = 0;
2580*5113495bSYour Name 	struct hdd_station_info *sta_info = NULL;
2581*5113495bSYour Name 	struct hdd_adapter *adapter;
2582*5113495bSYour Name 	struct wlan_hdd_link_info *link_info;
2583*5113495bSYour Name 
2584*5113495bSYour Name 	link_info = wlan_hdd_get_link_info_from_objmgr(vdev);
2585*5113495bSYour Name 	if (!link_info) {
2586*5113495bSYour Name 		hdd_err("null adapter");
2587*5113495bSYour Name 		return ret;
2588*5113495bSYour Name 	}
2589*5113495bSYour Name 
2590*5113495bSYour Name 	adapter = link_info->adapter;
2591*5113495bSYour Name 	sta_info = hdd_get_sta_info_by_mac(&adapter->sta_info_list,
2592*5113495bSYour Name 					   peer->macaddr,
2593*5113495bSYour Name 					   STA_INFO_SOFTAP_GET_STA_INFO);
2594*5113495bSYour Name 	if (!sta_info) {
2595*5113495bSYour Name 		hdd_err("sta_info NULL");
2596*5113495bSYour Name 		return ret;
2597*5113495bSYour Name 	}
2598*5113495bSYour Name 
2599*5113495bSYour Name 	ret = sta_info->max_real_mcs_idx;
2600*5113495bSYour Name 
2601*5113495bSYour Name 	hdd_put_sta_info_ref(&adapter->sta_info_list, &sta_info, true,
2602*5113495bSYour Name 			     STA_INFO_SOFTAP_GET_STA_INFO);
2603*5113495bSYour Name 	hdd_debug("Peer " QDF_MAC_ADDR_FMT " max MCS index: %u",
2604*5113495bSYour Name 		  QDF_MAC_ADDR_REF(peer->macaddr), ret);
2605*5113495bSYour Name 
2606*5113495bSYour Name 	return ret;
2607*5113495bSYour Name }
2608*5113495bSYour Name 
2609*5113495bSYour Name /**
2610*5113495bSYour Name  * hdd_son_get_sta_stats() - get connected sta rssi and estimated data rate
2611*5113495bSYour Name  * @vdev: pointer to vdev
2612*5113495bSYour Name  * @mac_addr: connected sta mac addr
2613*5113495bSYour Name  * @stats: pointer to ieee80211_nodestats
2614*5113495bSYour Name  *
2615*5113495bSYour Name  * Return: 0 on success, negative errno on failure
2616*5113495bSYour Name  */
hdd_son_get_sta_stats(struct wlan_objmgr_vdev * vdev,uint8_t * mac_addr,struct ieee80211_nodestats * stats)2617*5113495bSYour Name static int hdd_son_get_sta_stats(struct wlan_objmgr_vdev *vdev,
2618*5113495bSYour Name 				 uint8_t *mac_addr,
2619*5113495bSYour Name 				 struct ieee80211_nodestats *stats)
2620*5113495bSYour Name {
2621*5113495bSYour Name 	struct stats_event *stats_info;
2622*5113495bSYour Name 	int ret = 0;
2623*5113495bSYour Name 
2624*5113495bSYour Name 	stats_info = wlan_cfg80211_mc_cp_stats_get_peer_rssi(
2625*5113495bSYour Name 			vdev, mac_addr, &ret);
2626*5113495bSYour Name 	if (ret || !stats_info) {
2627*5113495bSYour Name 		hdd_err("get peer rssi fail");
2628*5113495bSYour Name 		wlan_cfg80211_mc_cp_stats_free_stats_event(stats_info);
2629*5113495bSYour Name 		return ret;
2630*5113495bSYour Name 	}
2631*5113495bSYour Name 	stats->ns_rssi = stats_info->peer_stats[0].peer_rssi;
2632*5113495bSYour Name 	stats->ns_last_tx_rate = stats_info->peer_stats[0].tx_rate;
2633*5113495bSYour Name 	stats->ns_last_rx_rate = stats_info->peer_stats[0].rx_rate;
2634*5113495bSYour Name 	hdd_debug("sta " QDF_MAC_ADDR_FMT " rssi %d tx %u kbps, rx %u kbps",
2635*5113495bSYour Name 		  QDF_MAC_ADDR_REF(mac_addr), stats->ns_rssi,
2636*5113495bSYour Name 		  stats->ns_last_tx_rate,
2637*5113495bSYour Name 		  stats->ns_last_rx_rate);
2638*5113495bSYour Name 	wlan_cfg80211_mc_cp_stats_free_stats_event(stats_info);
2639*5113495bSYour Name 
2640*5113495bSYour Name 	return ret;
2641*5113495bSYour Name }
2642*5113495bSYour Name 
hdd_son_register_callbacks(struct hdd_context * hdd_ctx)2643*5113495bSYour Name void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
2644*5113495bSYour Name {
2645*5113495bSYour Name 	struct son_callbacks cb_obj = {0};
2646*5113495bSYour Name 
2647*5113495bSYour Name 	cb_obj.os_if_is_acs_in_progress = hdd_son_is_acs_in_progress;
2648*5113495bSYour Name 	cb_obj.os_if_set_chan_ext_offset = hdd_son_set_chan_ext_offset;
2649*5113495bSYour Name 	cb_obj.os_if_get_chan_ext_offset = hdd_son_get_chan_ext_offset;
2650*5113495bSYour Name 	cb_obj.os_if_set_bandwidth = hdd_son_set_bandwidth;
2651*5113495bSYour Name 	cb_obj.os_if_get_bandwidth = hdd_son_get_bandwidth;
2652*5113495bSYour Name 	cb_obj.os_if_set_chan = hdd_son_set_chan;
2653*5113495bSYour Name 	cb_obj.os_if_set_acl_policy = hdd_son_set_acl_policy;
2654*5113495bSYour Name 	cb_obj.os_if_get_acl_policy = hdd_son_get_acl_policy;
2655*5113495bSYour Name 	cb_obj.os_if_add_acl_mac = hdd_son_add_acl_mac;
2656*5113495bSYour Name 	cb_obj.os_if_del_acl_mac = hdd_son_del_acl_mac;
2657*5113495bSYour Name 	cb_obj.os_if_kickout_mac = hdd_son_kickout_mac;
2658*5113495bSYour Name 	cb_obj.os_if_set_country_code = hdd_son_set_country;
2659*5113495bSYour Name 	cb_obj.os_if_set_candidate_freq = hdd_son_set_candidate_freq;
2660*5113495bSYour Name 	cb_obj.os_if_get_candidate_freq = hdd_son_get_candidate_freq;
2661*5113495bSYour Name 	cb_obj.os_if_set_phymode = hdd_son_set_phymode;
2662*5113495bSYour Name 	cb_obj.os_if_get_phymode = hdd_son_get_phymode;
2663*5113495bSYour Name 	cb_obj.os_if_get_rx_nss = hdd_son_get_rx_nss;
2664*5113495bSYour Name 	cb_obj.os_if_set_chwidth = hdd_son_set_chwidth;
2665*5113495bSYour Name 	cb_obj.os_if_get_chwidth = hdd_son_get_chwidth;
2666*5113495bSYour Name 	cb_obj.os_if_deauth_sta = hdd_son_deauth_sta;
2667*5113495bSYour Name 	cb_obj.os_if_modify_acl = hdd_son_modify_acl;
2668*5113495bSYour Name 	cb_obj.os_if_get_sta_list = hdd_son_get_sta_list;
2669*5113495bSYour Name 	cb_obj.os_if_get_sta_space = hdd_son_get_sta_space;
2670*5113495bSYour Name 	cb_obj.os_if_get_vdev_by_netdev = hdd_son_get_vdev_by_netdev;
2671*5113495bSYour Name 	cb_obj.os_if_trigger_objmgr_object_creation =
2672*5113495bSYour Name 				hdd_son_trigger_objmgr_object_creation;
2673*5113495bSYour Name 	cb_obj.os_if_trigger_objmgr_object_deletion =
2674*5113495bSYour Name 				hdd_son_trigger_objmgr_object_deletion;
2675*5113495bSYour Name 	cb_obj.os_if_start_acs = hdd_son_start_acs;
2676*5113495bSYour Name 	cb_obj.os_if_set_acs_channels = hdd_son_set_acs_channels;
2677*5113495bSYour Name 	cb_obj.os_if_get_acs_report = hdd_son_get_acs_report;
2678*5113495bSYour Name 	cb_obj.os_if_get_node_info = hdd_son_get_node_info;
2679*5113495bSYour Name 	cb_obj.os_if_get_peer_capability = hdd_son_get_peer_capability;
2680*5113495bSYour Name 	cb_obj.os_if_get_peer_max_mcs_idx = hdd_son_get_peer_max_mcs_idx;
2681*5113495bSYour Name 	cb_obj.os_if_get_sta_stats = hdd_son_get_sta_stats;
2682*5113495bSYour Name 
2683*5113495bSYour Name 	os_if_son_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
2684*5113495bSYour Name 
2685*5113495bSYour Name 	ucfg_son_register_deliver_opmode_cb(hdd_ctx->psoc,
2686*5113495bSYour Name 					    hdd_son_deliver_opmode);
2687*5113495bSYour Name 	ucfg_son_register_deliver_smps_cb(hdd_ctx->psoc,
2688*5113495bSYour Name 					  hdd_son_deliver_smps);
2689*5113495bSYour Name }
2690*5113495bSYour Name 
hdd_son_deliver_acs_complete_event(struct hdd_adapter * adapter)2691*5113495bSYour Name int hdd_son_deliver_acs_complete_event(struct hdd_adapter *adapter)
2692*5113495bSYour Name {
2693*5113495bSYour Name 	int ret = -EINVAL;
2694*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2695*5113495bSYour Name 
2696*5113495bSYour Name 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_SON_ID);
2697*5113495bSYour Name 	if (!vdev) {
2698*5113495bSYour Name 		hdd_err("null vdev");
2699*5113495bSYour Name 		return ret;
2700*5113495bSYour Name 	}
2701*5113495bSYour Name 	ret = os_if_son_deliver_ald_event(vdev, NULL, MLME_EVENT_ACS_COMPLETE,
2702*5113495bSYour Name 					  NULL);
2703*5113495bSYour Name 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2704*5113495bSYour Name 	return ret;
2705*5113495bSYour Name }
2706*5113495bSYour Name 
hdd_son_deliver_cac_status_event(struct hdd_adapter * adapter,qdf_freq_t freq,bool radar_detected)2707*5113495bSYour Name int hdd_son_deliver_cac_status_event(struct hdd_adapter *adapter,
2708*5113495bSYour Name 				     qdf_freq_t freq, bool radar_detected)
2709*5113495bSYour Name {
2710*5113495bSYour Name 	int ret = -EINVAL;
2711*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2712*5113495bSYour Name 	struct son_ald_cac_info cac_info;
2713*5113495bSYour Name 
2714*5113495bSYour Name 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_SON_ID);
2715*5113495bSYour Name 	if (!vdev) {
2716*5113495bSYour Name 		hdd_err("null vdev");
2717*5113495bSYour Name 		return ret;
2718*5113495bSYour Name 	}
2719*5113495bSYour Name 	cac_info.freq = freq;
2720*5113495bSYour Name 	cac_info.radar_detected = radar_detected;
2721*5113495bSYour Name 	ret = os_if_son_deliver_ald_event(vdev, NULL, MLME_EVENT_CAC_STATUS,
2722*5113495bSYour Name 					  &cac_info);
2723*5113495bSYour Name 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2724*5113495bSYour Name 
2725*5113495bSYour Name 	return ret;
2726*5113495bSYour Name }
2727*5113495bSYour Name 
hdd_son_deliver_assoc_disassoc_event(struct hdd_adapter * adapter,struct qdf_mac_addr sta_mac,uint32_t reason_code,enum assoc_disassoc_event flag)2728*5113495bSYour Name int hdd_son_deliver_assoc_disassoc_event(struct hdd_adapter *adapter,
2729*5113495bSYour Name 					 struct qdf_mac_addr sta_mac,
2730*5113495bSYour Name 					 uint32_t reason_code,
2731*5113495bSYour Name 					 enum assoc_disassoc_event flag)
2732*5113495bSYour Name {
2733*5113495bSYour Name 	int ret = -EINVAL;
2734*5113495bSYour Name 	struct son_ald_assoc_event_info info;
2735*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2736*5113495bSYour Name 
2737*5113495bSYour Name 	qdf_mem_zero(&info, sizeof(info));
2738*5113495bSYour Name 	memcpy(info.macaddr, &sta_mac.bytes, QDF_MAC_ADDR_SIZE);
2739*5113495bSYour Name 	info.flag = flag;
2740*5113495bSYour Name 	info.reason = reason_code;
2741*5113495bSYour Name 
2742*5113495bSYour Name 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_SON_ID);
2743*5113495bSYour Name 	if (!vdev) {
2744*5113495bSYour Name 		hdd_err("null vdev");
2745*5113495bSYour Name 		return ret;
2746*5113495bSYour Name 	}
2747*5113495bSYour Name 	ret = os_if_son_deliver_ald_event(vdev, NULL, MLME_EVENT_ASSOC_DISASSOC,
2748*5113495bSYour Name 					  &info);
2749*5113495bSYour Name 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2750*5113495bSYour Name 	return ret;
2751*5113495bSYour Name }
2752*5113495bSYour Name 
hdd_son_deliver_peer_authorize_event(struct wlan_hdd_link_info * link_info,uint8_t * peer_mac)2753*5113495bSYour Name void hdd_son_deliver_peer_authorize_event(struct wlan_hdd_link_info *link_info,
2754*5113495bSYour Name 					  uint8_t *peer_mac)
2755*5113495bSYour Name {
2756*5113495bSYour Name 	struct wlan_objmgr_peer *peer;
2757*5113495bSYour Name 	int ret;
2758*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2759*5113495bSYour Name 	struct wlan_objmgr_psoc *psoc;
2760*5113495bSYour Name 
2761*5113495bSYour Name 	if (link_info->adapter->device_mode != QDF_SAP_MODE) {
2762*5113495bSYour Name 		hdd_err("Non SAP vdev");
2763*5113495bSYour Name 		return;
2764*5113495bSYour Name 	}
2765*5113495bSYour Name 	vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_SON_ID);
2766*5113495bSYour Name 	if (!vdev) {
2767*5113495bSYour Name 		hdd_err("null vdev");
2768*5113495bSYour Name 		return;
2769*5113495bSYour Name 	}
2770*5113495bSYour Name 	psoc = wlan_vdev_get_psoc(vdev);
2771*5113495bSYour Name 	if (!psoc) {
2772*5113495bSYour Name 		hdd_err("null psoc");
2773*5113495bSYour Name 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2774*5113495bSYour Name 		return;
2775*5113495bSYour Name 	}
2776*5113495bSYour Name 	peer = wlan_objmgr_get_peer_by_mac(psoc, peer_mac, WLAN_UMAC_COMP_SON);
2777*5113495bSYour Name 	if (!peer) {
2778*5113495bSYour Name 		hdd_err("No peer object for sta" QDF_MAC_ADDR_FMT,
2779*5113495bSYour Name 			QDF_MAC_ADDR_REF(peer_mac));
2780*5113495bSYour Name 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2781*5113495bSYour Name 		return;
2782*5113495bSYour Name 	}
2783*5113495bSYour Name 
2784*5113495bSYour Name 	ret = os_if_son_deliver_ald_event(vdev, peer,
2785*5113495bSYour Name 					  MLME_EVENT_CLIENT_ASSOCIATED, NULL);
2786*5113495bSYour Name 	if (ret)
2787*5113495bSYour Name 		hdd_err("ALD ASSOCIATED Event failed for" QDF_MAC_ADDR_FMT,
2788*5113495bSYour Name 			QDF_MAC_ADDR_REF(peer_mac));
2789*5113495bSYour Name 
2790*5113495bSYour Name 	wlan_objmgr_peer_release_ref(peer, WLAN_UMAC_COMP_SON);
2791*5113495bSYour Name 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2792*5113495bSYour Name }
2793*5113495bSYour Name 
hdd_son_deliver_chan_change_event(struct hdd_adapter * adapter,qdf_freq_t freq)2794*5113495bSYour Name int hdd_son_deliver_chan_change_event(struct hdd_adapter *adapter,
2795*5113495bSYour Name 				      qdf_freq_t freq)
2796*5113495bSYour Name {
2797*5113495bSYour Name 	int ret = -EINVAL;
2798*5113495bSYour Name 	struct wlan_objmgr_vdev *vdev;
2799*5113495bSYour Name 	struct son_ald_chan_change_info chan_info;
2800*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
2801*5113495bSYour Name 
2802*5113495bSYour Name 	if (!adapter) {
2803*5113495bSYour Name 		hdd_err("null adapter");
2804*5113495bSYour Name 		return ret;
2805*5113495bSYour Name 	}
2806*5113495bSYour Name 	vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_SON_ID);
2807*5113495bSYour Name 	if (!vdev) {
2808*5113495bSYour Name 		hdd_err("null vdev");
2809*5113495bSYour Name 		return ret;
2810*5113495bSYour Name 	}
2811*5113495bSYour Name 	pdev = wlan_vdev_get_pdev(vdev);
2812*5113495bSYour Name 	if (!pdev) {
2813*5113495bSYour Name 		hdd_err("null pdev");
2814*5113495bSYour Name 		hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2815*5113495bSYour Name 		return ret;
2816*5113495bSYour Name 	}
2817*5113495bSYour Name 	chan_info.freq = freq;
2818*5113495bSYour Name 	chan_info.chan_num = wlan_reg_freq_to_chan(pdev, freq);
2819*5113495bSYour Name 	ret = os_if_son_deliver_ald_event(vdev, NULL,
2820*5113495bSYour Name 					  MLME_EVENT_CHAN_CHANGE,
2821*5113495bSYour Name 					  &chan_info);
2822*5113495bSYour Name 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_SON_ID);
2823*5113495bSYour Name 
2824*5113495bSYour Name 	return ret;
2825*5113495bSYour Name }
2826*5113495bSYour Name 
hdd_son_send_set_wifi_generic_command(struct wiphy * wiphy,struct wireless_dev * wdev,struct nlattr ** tb)2827*5113495bSYour Name int hdd_son_send_set_wifi_generic_command(struct wiphy *wiphy,
2828*5113495bSYour Name 					  struct wireless_dev *wdev,
2829*5113495bSYour Name 					  struct nlattr **tb)
2830*5113495bSYour Name {
2831*5113495bSYour Name 	return os_if_son_parse_generic_nl_cmd(wiphy, wdev, tb,
2832*5113495bSYour Name 					      OS_IF_SON_VENDOR_SET_CMD);
2833*5113495bSYour Name }
2834*5113495bSYour Name 
hdd_son_send_get_wifi_generic_command(struct wiphy * wiphy,struct wireless_dev * wdev,struct nlattr ** tb)2835*5113495bSYour Name int hdd_son_send_get_wifi_generic_command(struct wiphy *wiphy,
2836*5113495bSYour Name 					  struct wireless_dev *wdev,
2837*5113495bSYour Name 					  struct nlattr **tb)
2838*5113495bSYour Name {
2839*5113495bSYour Name 	return os_if_son_parse_generic_nl_cmd(wiphy, wdev, tb,
2840*5113495bSYour Name 					      OS_IF_SON_VENDOR_GET_CMD);
2841*5113495bSYour Name }
2842