xref: /wlan-driver/qcacld-3.0/core/hdd/src/wlan_hdd_lpass.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-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
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  *  DOC: wlan_hdd_lpass.c
22*5113495bSYour Name  *
23*5113495bSYour Name  *  WLAN Host Device Driver LPASS feature implementation
24*5113495bSYour Name  *
25*5113495bSYour Name  */
26*5113495bSYour Name 
27*5113495bSYour Name /* Include Files */
28*5113495bSYour Name #include "wlan_hdd_main.h"
29*5113495bSYour Name #include "wlan_hdd_lpass.h"
30*5113495bSYour Name #include "wlan_hdd_oemdata.h"
31*5113495bSYour Name #include <cds_utils.h>
32*5113495bSYour Name #include "qwlan_version.h"
33*5113495bSYour Name 
34*5113495bSYour Name /**
35*5113495bSYour Name  * wlan_hdd_get_channel_info() - Get channel info
36*5113495bSYour Name  * @hdd_ctx: HDD context
37*5113495bSYour Name  * @chan_info: Pointer to the structure that stores channel info
38*5113495bSYour Name  * @chan_freq: Channel freq
39*5113495bSYour Name  *
40*5113495bSYour Name  * Fill in the channel info to chan_info structure.
41*5113495bSYour Name  */
wlan_hdd_get_channel_info(struct hdd_context * hdd_ctx,struct svc_channel_info * chan_info,uint32_t chan_freq)42*5113495bSYour Name static void wlan_hdd_get_channel_info(struct hdd_context *hdd_ctx,
43*5113495bSYour Name 				      struct svc_channel_info *chan_info,
44*5113495bSYour Name 				      uint32_t chan_freq)
45*5113495bSYour Name {
46*5113495bSYour Name 	uint32_t reg_info_1;
47*5113495bSYour Name 	uint32_t reg_info_2;
48*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
49*5113495bSYour Name 
50*5113495bSYour Name 	status = sme_get_reg_info(hdd_ctx->mac_handle, chan_freq,
51*5113495bSYour Name 				  &reg_info_1, &reg_info_2);
52*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS)
53*5113495bSYour Name 		return;
54*5113495bSYour Name 
55*5113495bSYour Name 	chan_info->mhz = chan_freq;
56*5113495bSYour Name 	chan_info->band_center_freq1 = chan_info->mhz;
57*5113495bSYour Name 	chan_info->band_center_freq2 = 0;
58*5113495bSYour Name 	chan_info->info = 0;
59*5113495bSYour Name 	if (CHANNEL_STATE_DFS ==
60*5113495bSYour Name 	    wlan_reg_get_channel_state_for_pwrmode(hdd_ctx->pdev, chan_freq,
61*5113495bSYour Name 						   REG_CURRENT_PWR_MODE))
62*5113495bSYour Name 		WMI_SET_CHANNEL_FLAG(chan_info,
63*5113495bSYour Name 				     WMI_CHAN_FLAG_DFS);
64*5113495bSYour Name 	hdd_update_channel_bw_info(hdd_ctx, chan_freq,
65*5113495bSYour Name 				   chan_info);
66*5113495bSYour Name 	chan_info->reg_info_1 = reg_info_1;
67*5113495bSYour Name 	chan_info->reg_info_2 = reg_info_2;
68*5113495bSYour Name }
69*5113495bSYour Name 
70*5113495bSYour Name /**
71*5113495bSYour Name  * wlan_hdd_gen_wlan_status_pack() - Create lpass adapter status package
72*5113495bSYour Name  * @data: Status data record to be created
73*5113495bSYour Name  * @link_info: Link info pointer in HDD adapter
74*5113495bSYour Name  * @sta_ctx: Station-specific context of @adapter
75*5113495bSYour Name  * @is_on: Is wlan driver loaded?
76*5113495bSYour Name  * @is_connected: Is @adapter connected to an AP?
77*5113495bSYour Name  *
78*5113495bSYour Name  * Generate a wlan vdev status package. The status info includes wlan
79*5113495bSYour Name  * on/off status, vdev ID, vdev mode, supported channels, etc.
80*5113495bSYour Name  *
81*5113495bSYour Name  * Return: 0 if package was created, otherwise a negative errno
82*5113495bSYour Name  */
wlan_hdd_gen_wlan_status_pack(struct wlan_status_data * data,struct wlan_hdd_link_info * link_info,struct hdd_station_ctx * sta_ctx,uint8_t is_on,uint8_t is_connected)83*5113495bSYour Name static int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data,
84*5113495bSYour Name 					 struct wlan_hdd_link_info *link_info,
85*5113495bSYour Name 					 struct hdd_station_ctx *sta_ctx,
86*5113495bSYour Name 					 uint8_t is_on, uint8_t is_connected)
87*5113495bSYour Name {
88*5113495bSYour Name 	struct hdd_context *hdd_ctx = NULL;
89*5113495bSYour Name 	int i;
90*5113495bSYour Name 	uint32_t chan_id;
91*5113495bSYour Name 	uint32_t *chan_freq_list, chan_freq_len;
92*5113495bSYour Name 	struct svc_channel_info *chan_info;
93*5113495bSYour Name 	bool lpass_support, wls_6ghz_capable = false;
94*5113495bSYour Name 	QDF_STATUS status;
95*5113495bSYour Name 	struct hdd_adapter *adapter;
96*5113495bSYour Name 
97*5113495bSYour Name 	if (!data) {
98*5113495bSYour Name 		hdd_err("invalid data pointer");
99*5113495bSYour Name 		return -EINVAL;
100*5113495bSYour Name 	}
101*5113495bSYour Name 	if (!link_info) {
102*5113495bSYour Name 		if (is_on) {
103*5113495bSYour Name 			/* no active interface */
104*5113495bSYour Name 			data->lpss_support = 0;
105*5113495bSYour Name 			data->is_on = is_on;
106*5113495bSYour Name 			return 0;
107*5113495bSYour Name 		}
108*5113495bSYour Name 		hdd_err("invalid adapter pointer");
109*5113495bSYour Name 		return -EINVAL;
110*5113495bSYour Name 	}
111*5113495bSYour Name 
112*5113495bSYour Name 	if (wlan_hdd_validate_vdev_id(link_info->vdev_id))
113*5113495bSYour Name 		return -EINVAL;
114*5113495bSYour Name 
115*5113495bSYour Name 	adapter = link_info->adapter;
116*5113495bSYour Name 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
117*5113495bSYour Name 
118*5113495bSYour Name 	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
119*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
120*5113495bSYour Name 		hdd_err("Failed to get LPASS support config");
121*5113495bSYour Name 		return -EIO;
122*5113495bSYour Name 	}
123*5113495bSYour Name 	ucfg_mlme_get_wls_6ghz_cap(hdd_ctx->psoc, &wls_6ghz_capable);
124*5113495bSYour Name 	if (hdd_ctx->lpss_support && lpass_support)
125*5113495bSYour Name 		data->lpss_support = 1;
126*5113495bSYour Name 	else
127*5113495bSYour Name 		data->lpss_support = 0;
128*5113495bSYour Name 
129*5113495bSYour Name 	chan_freq_list =
130*5113495bSYour Name 		qdf_mem_malloc(sizeof(uint32_t) * WLAN_SVC_MAX_NUM_CHAN);
131*5113495bSYour Name 	if (!chan_freq_list)
132*5113495bSYour Name 		return -ENOMEM;
133*5113495bSYour Name 
134*5113495bSYour Name 	chan_freq_len = WLAN_SVC_MAX_NUM_CHAN;
135*5113495bSYour Name 	sme_get_cfg_valid_channels(chan_freq_list, &chan_freq_len);
136*5113495bSYour Name 
137*5113495bSYour Name 	data->numChannels = 0;
138*5113495bSYour Name 	for (i = 0; i < chan_freq_len; i++) {
139*5113495bSYour Name 		if (!wls_6ghz_capable &&
140*5113495bSYour Name 		    wlan_reg_is_6ghz_chan_freq(chan_freq_list[i]))
141*5113495bSYour Name 			continue;
142*5113495bSYour Name 
143*5113495bSYour Name 		chan_id = wlan_reg_freq_to_chan(hdd_ctx->pdev,
144*5113495bSYour Name 						chan_freq_list[i]);
145*5113495bSYour Name 		if (!chan_id)
146*5113495bSYour Name 			continue;
147*5113495bSYour Name 
148*5113495bSYour Name 		chan_info = &data->channel_info[data->numChannels];
149*5113495bSYour Name 		data->channel_list[data->numChannels] = chan_id;
150*5113495bSYour Name 		chan_info->chan_id = chan_id;
151*5113495bSYour Name 		wlan_hdd_get_channel_info(hdd_ctx,
152*5113495bSYour Name 					  chan_info,
153*5113495bSYour Name 					  chan_freq_list[i]);
154*5113495bSYour Name 		data->numChannels++;
155*5113495bSYour Name 	}
156*5113495bSYour Name 
157*5113495bSYour Name 	qdf_mem_free(chan_freq_list);
158*5113495bSYour Name 
159*5113495bSYour Name 	wlan_reg_get_cc_and_src(hdd_ctx->psoc, data->country_code);
160*5113495bSYour Name 	data->is_on = is_on;
161*5113495bSYour Name 	data->vdev_id = link_info->vdev_id;
162*5113495bSYour Name 	data->vdev_mode = adapter->device_mode;
163*5113495bSYour Name 	if (sta_ctx) {
164*5113495bSYour Name 		data->is_connected = is_connected;
165*5113495bSYour Name 		data->rssi = link_info->rssi;
166*5113495bSYour Name 		data->freq = sta_ctx->conn_info.chan_freq;
167*5113495bSYour Name 		if (WLAN_SVC_MAX_SSID_LEN >=
168*5113495bSYour Name 		    sta_ctx->conn_info.ssid.SSID.length) {
169*5113495bSYour Name 			data->ssid_len = sta_ctx->conn_info.ssid.SSID.length;
170*5113495bSYour Name 			memcpy(data->ssid,
171*5113495bSYour Name 			       sta_ctx->conn_info.ssid.SSID.ssId,
172*5113495bSYour Name 			       sta_ctx->conn_info.ssid.SSID.length);
173*5113495bSYour Name 		}
174*5113495bSYour Name 		if (QDF_MAC_ADDR_SIZE >= sizeof(sta_ctx->conn_info.bssid))
175*5113495bSYour Name 			memcpy(data->bssid, sta_ctx->conn_info.bssid.bytes,
176*5113495bSYour Name 			       QDF_MAC_ADDR_SIZE);
177*5113495bSYour Name 	}
178*5113495bSYour Name 	return 0;
179*5113495bSYour Name }
180*5113495bSYour Name 
181*5113495bSYour Name /**
182*5113495bSYour Name  * wlan_hdd_gen_wlan_version_pack() - Create lpass version package
183*5113495bSYour Name  * @data: Version data record to be created
184*5113495bSYour Name  * @fw_version: Version code from firmware
185*5113495bSYour Name  * @chip_id: WLAN chip ID
186*5113495bSYour Name  * @chip_name: WLAN chip name
187*5113495bSYour Name  *
188*5113495bSYour Name  * Generate a wlan software/hw version info package. The version info
189*5113495bSYour Name  * includes wlan host driver version, wlan fw driver version, wlan hw
190*5113495bSYour Name  * chip id & wlan hw chip name.
191*5113495bSYour Name  *
192*5113495bSYour Name  * Return: 0 if package was created, otherwise a negative errno
193*5113495bSYour Name  */
wlan_hdd_gen_wlan_version_pack(struct wlan_version_data * data,uint32_t fw_version,uint32_t chip_id,const char * chip_name)194*5113495bSYour Name static int wlan_hdd_gen_wlan_version_pack(struct wlan_version_data *data,
195*5113495bSYour Name 					  uint32_t fw_version,
196*5113495bSYour Name 					  uint32_t chip_id,
197*5113495bSYour Name 					  const char *chip_name)
198*5113495bSYour Name {
199*5113495bSYour Name 	if (!data) {
200*5113495bSYour Name 		hdd_err("invalid data pointer");
201*5113495bSYour Name 		return -EINVAL;
202*5113495bSYour Name 	}
203*5113495bSYour Name 
204*5113495bSYour Name 	data->chip_id = chip_id;
205*5113495bSYour Name 	strlcpy(data->chip_name, chip_name, WLAN_SVC_MAX_STR_LEN);
206*5113495bSYour Name 	if (strncmp(chip_name, "Unknown", 7))
207*5113495bSYour Name 		strlcpy(data->chip_from, "Qualcomm", WLAN_SVC_MAX_STR_LEN);
208*5113495bSYour Name 	else
209*5113495bSYour Name 		strlcpy(data->chip_from, "Unknown", WLAN_SVC_MAX_STR_LEN);
210*5113495bSYour Name 	strlcpy(data->host_version, QWLAN_VERSIONSTR, WLAN_SVC_MAX_STR_LEN);
211*5113495bSYour Name 	scnprintf(data->fw_version, WLAN_SVC_MAX_STR_LEN, "%d.%d.%d.%d",
212*5113495bSYour Name 		  (fw_version & 0xf0000000) >> 28,
213*5113495bSYour Name 		  (fw_version & 0xf000000) >> 24,
214*5113495bSYour Name 		  (fw_version & 0xf00000) >> 20, (fw_version & 0x7fff));
215*5113495bSYour Name 	return 0;
216*5113495bSYour Name }
217*5113495bSYour Name 
218*5113495bSYour Name /**
219*5113495bSYour Name  * wlan_hdd_send_status_pkg() - Send adapter status to lpass
220*5113495bSYour Name  * @link_info: Link info pointer in HDD adapter
221*5113495bSYour Name  * @sta_ctx: Station-specific context of @adapter
222*5113495bSYour Name  * @is_on: Is @adapter enabled
223*5113495bSYour Name  * @is_connected: Is @adapter connected
224*5113495bSYour Name  *
225*5113495bSYour Name  * Generate wlan vdev status package and send it to a user space
226*5113495bSYour Name  * daemon through netlink.
227*5113495bSYour Name  *
228*5113495bSYour Name  * Return: none
229*5113495bSYour Name  */
wlan_hdd_send_status_pkg(struct wlan_hdd_link_info * link_info,struct hdd_station_ctx * sta_ctx,uint8_t is_on,uint8_t is_connected)230*5113495bSYour Name static void wlan_hdd_send_status_pkg(struct wlan_hdd_link_info *link_info,
231*5113495bSYour Name 				     struct hdd_station_ctx *sta_ctx,
232*5113495bSYour Name 				     uint8_t is_on, uint8_t is_connected)
233*5113495bSYour Name {
234*5113495bSYour Name 	int ret = 0;
235*5113495bSYour Name 	struct wlan_status_data *data = NULL;
236*5113495bSYour Name 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
237*5113495bSYour Name 
238*5113495bSYour Name 	if (!hdd_ctx)
239*5113495bSYour Name 		return;
240*5113495bSYour Name 
241*5113495bSYour Name 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
242*5113495bSYour Name 		return;
243*5113495bSYour Name 
244*5113495bSYour Name 	data = kzalloc(sizeof(*data), GFP_KERNEL);
245*5113495bSYour Name 	if (!data)
246*5113495bSYour Name 		return;
247*5113495bSYour Name 
248*5113495bSYour Name 	if (is_on)
249*5113495bSYour Name 		ret = wlan_hdd_gen_wlan_status_pack(data, link_info,
250*5113495bSYour Name 						    sta_ctx, is_on,
251*5113495bSYour Name 						    is_connected);
252*5113495bSYour Name 
253*5113495bSYour Name 	if (!ret)
254*5113495bSYour Name 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
255*5113495bSYour Name 					    WLAN_SVC_WLAN_STATUS_IND,
256*5113495bSYour Name 					    data, sizeof(*data));
257*5113495bSYour Name 	kfree(data);
258*5113495bSYour Name }
259*5113495bSYour Name 
260*5113495bSYour Name /**
261*5113495bSYour Name  * wlan_hdd_send_version_pkg() - report version information to lpass
262*5113495bSYour Name  * @fw_version: Version code from firmware
263*5113495bSYour Name  * @chip_id: WLAN chip ID
264*5113495bSYour Name  * @chip_name: WLAN chip name
265*5113495bSYour Name  *
266*5113495bSYour Name  * Generate a wlan sw/hw version info package and send it to a user
267*5113495bSYour Name  * space daemon through netlink.
268*5113495bSYour Name  *
269*5113495bSYour Name  * Return: none
270*5113495bSYour Name  */
wlan_hdd_send_version_pkg(uint32_t fw_version,uint32_t chip_id,const char * chip_name)271*5113495bSYour Name static void wlan_hdd_send_version_pkg(uint32_t fw_version,
272*5113495bSYour Name 				      uint32_t chip_id,
273*5113495bSYour Name 				      const char *chip_name)
274*5113495bSYour Name {
275*5113495bSYour Name 	int ret = 0;
276*5113495bSYour Name 	struct wlan_version_data data;
277*5113495bSYour Name 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
278*5113495bSYour Name 
279*5113495bSYour Name 	if (!hdd_ctx)
280*5113495bSYour Name 		return;
281*5113495bSYour Name 
282*5113495bSYour Name 	if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
283*5113495bSYour Name 		return;
284*5113495bSYour Name 
285*5113495bSYour Name 	memset(&data, 0, sizeof(struct wlan_version_data));
286*5113495bSYour Name 	ret = wlan_hdd_gen_wlan_version_pack(&data, fw_version, chip_id,
287*5113495bSYour Name 					     chip_name);
288*5113495bSYour Name 	if (!ret)
289*5113495bSYour Name 		wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
290*5113495bSYour Name 					WLAN_SVC_WLAN_VERSION_IND,
291*5113495bSYour Name 					    &data, sizeof(data));
292*5113495bSYour Name }
293*5113495bSYour Name 
294*5113495bSYour Name /**
295*5113495bSYour Name  * wlan_hdd_send_scan_intf_info() - report scan interfaces to lpass
296*5113495bSYour Name  * @link_info: Link info pointer in HDD adapter
297*5113495bSYour Name  *
298*5113495bSYour Name  * This function indicates adapter that supports scanning to lpass.
299*5113495bSYour Name  *
300*5113495bSYour Name  * Return: none
301*5113495bSYour Name  */
302*5113495bSYour Name static inline void
wlan_hdd_send_scan_intf_info(struct wlan_hdd_link_info * link_info)303*5113495bSYour Name wlan_hdd_send_scan_intf_info(struct wlan_hdd_link_info *link_info)
304*5113495bSYour Name {
305*5113495bSYour Name 	wlan_hdd_send_status_pkg(link_info, NULL, 1, 0);
306*5113495bSYour Name }
307*5113495bSYour Name 
308*5113495bSYour Name /*
309*5113495bSYour Name  * hdd_lpass_target_config() - Handle LPASS target configuration
310*5113495bSYour Name  * (public function documented in wlan_hdd_lpass.h)
311*5113495bSYour Name  */
hdd_lpass_target_config(struct hdd_context * hdd_ctx,struct wma_tgt_cfg * target_config)312*5113495bSYour Name void hdd_lpass_target_config(struct hdd_context *hdd_ctx,
313*5113495bSYour Name 			     struct wma_tgt_cfg *target_config)
314*5113495bSYour Name {
315*5113495bSYour Name 	hdd_ctx->lpss_support = target_config->lpss_support;
316*5113495bSYour Name }
317*5113495bSYour Name 
318*5113495bSYour Name /*
319*5113495bSYour Name  * hdd_lpass_populate_cds_config() - Populate LPASS configuration
320*5113495bSYour Name  * (public function documented in wlan_hdd_lpass.h)
321*5113495bSYour Name  */
hdd_lpass_populate_cds_config(struct cds_config_info * cds_config,struct hdd_context * hdd_ctx)322*5113495bSYour Name void hdd_lpass_populate_cds_config(struct cds_config_info *cds_config,
323*5113495bSYour Name 				   struct hdd_context *hdd_ctx)
324*5113495bSYour Name {
325*5113495bSYour Name 	bool lpass_support = false;
326*5113495bSYour Name 	QDF_STATUS status;
327*5113495bSYour Name 
328*5113495bSYour Name 	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
329*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
330*5113495bSYour Name 		hdd_err("Failed to get LPASS support config");
331*5113495bSYour Name 
332*5113495bSYour Name 	cds_config->is_lpass_enabled = lpass_support;
333*5113495bSYour Name }
334*5113495bSYour Name 
335*5113495bSYour Name /*
336*5113495bSYour Name  * hdd_lpass_populate_pmo_config() - Populate LPASS configuration
337*5113495bSYour Name  * (public function documented in wlan_hdd_lpass.h)
338*5113495bSYour Name  */
hdd_lpass_populate_pmo_config(struct pmo_psoc_cfg * pmo_config,struct hdd_context * hdd_ctx)339*5113495bSYour Name void hdd_lpass_populate_pmo_config(struct pmo_psoc_cfg *pmo_config,
340*5113495bSYour Name 				   struct hdd_context *hdd_ctx)
341*5113495bSYour Name {
342*5113495bSYour Name 	bool lpass_support = false;
343*5113495bSYour Name 	QDF_STATUS status;
344*5113495bSYour Name 
345*5113495bSYour Name 	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
346*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
347*5113495bSYour Name 		hdd_err("Failed to get LPASS support config");
348*5113495bSYour Name 
349*5113495bSYour Name 	pmo_config->lpass_enable = lpass_support;
350*5113495bSYour Name }
351*5113495bSYour Name 
hdd_lpass_notify_connect(struct wlan_hdd_link_info * link_info)352*5113495bSYour Name void hdd_lpass_notify_connect(struct wlan_hdd_link_info *link_info)
353*5113495bSYour Name {
354*5113495bSYour Name 	struct hdd_station_ctx *sta_ctx;
355*5113495bSYour Name 
356*5113495bSYour Name 	/* only send once per connection */
357*5113495bSYour Name 	if (link_info->rssi_send)
358*5113495bSYour Name 		return;
359*5113495bSYour Name 
360*5113495bSYour Name 	/* don't send if driver is unloading */
361*5113495bSYour Name 	if (cds_is_driver_unloading())
362*5113495bSYour Name 		return;
363*5113495bSYour Name 
364*5113495bSYour Name 	link_info->rssi_send = true;
365*5113495bSYour Name 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
366*5113495bSYour Name 	wlan_hdd_send_status_pkg(link_info, sta_ctx, 1, 1);
367*5113495bSYour Name }
368*5113495bSYour Name 
hdd_lpass_notify_disconnect(struct wlan_hdd_link_info * link_info)369*5113495bSYour Name void hdd_lpass_notify_disconnect(struct wlan_hdd_link_info *link_info)
370*5113495bSYour Name {
371*5113495bSYour Name 	struct hdd_station_ctx *sta_ctx;
372*5113495bSYour Name 
373*5113495bSYour Name 	link_info->rssi_send = false;
374*5113495bSYour Name 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
375*5113495bSYour Name 	wlan_hdd_send_status_pkg(link_info, sta_ctx, 1, 0);
376*5113495bSYour Name }
377*5113495bSYour Name 
hdd_lpass_notify_mode_change(struct wlan_hdd_link_info * link_info)378*5113495bSYour Name void hdd_lpass_notify_mode_change(struct wlan_hdd_link_info *link_info)
379*5113495bSYour Name {
380*5113495bSYour Name 	if (link_info->adapter->device_mode != QDF_STA_MODE)
381*5113495bSYour Name 		return;
382*5113495bSYour Name 
383*5113495bSYour Name 	hdd_debug("Sending Lpass mode change notification");
384*5113495bSYour Name 
385*5113495bSYour Name 	wlan_hdd_send_scan_intf_info(link_info);
386*5113495bSYour Name }
387*5113495bSYour Name 
388*5113495bSYour Name /*
389*5113495bSYour Name  * hdd_lpass_notify_wlan_version() - Notify LPASS WLAN Host/FW version
390*5113495bSYour Name  *
391*5113495bSYour Name  * implementation note: Notify LPASS for the WLAN host/firmware version.
392*5113495bSYour Name  */
hdd_lpass_notify_wlan_version(struct hdd_context * hdd_ctx)393*5113495bSYour Name void hdd_lpass_notify_wlan_version(struct hdd_context *hdd_ctx)
394*5113495bSYour Name {
395*5113495bSYour Name 	hdd_enter();
396*5113495bSYour Name 
397*5113495bSYour Name 	wlan_hdd_send_version_pkg(hdd_ctx->target_fw_version,
398*5113495bSYour Name 				  hdd_ctx->target_hw_version,
399*5113495bSYour Name 				  hdd_ctx->target_hw_name);
400*5113495bSYour Name 
401*5113495bSYour Name 	hdd_exit();
402*5113495bSYour Name }
403*5113495bSYour Name 
hdd_lpass_notify_start(struct wlan_hdd_link_info * link_info)404*5113495bSYour Name void hdd_lpass_notify_start(struct wlan_hdd_link_info *link_info)
405*5113495bSYour Name {
406*5113495bSYour Name 	hdd_enter();
407*5113495bSYour Name 
408*5113495bSYour Name 	if (link_info->adapter->device_mode != QDF_STA_MODE)
409*5113495bSYour Name 		return;
410*5113495bSYour Name 
411*5113495bSYour Name 	hdd_debug("Sending Start Lpass notification");
412*5113495bSYour Name 
413*5113495bSYour Name 	wlan_hdd_send_scan_intf_info(link_info);
414*5113495bSYour Name 
415*5113495bSYour Name 	hdd_exit();
416*5113495bSYour Name }
417*5113495bSYour Name 
hdd_lpass_notify_stop(struct hdd_context * hdd_ctx)418*5113495bSYour Name void hdd_lpass_notify_stop(struct hdd_context *hdd_ctx)
419*5113495bSYour Name {
420*5113495bSYour Name 	hdd_debug("Sending Lpass stop notification");
421*5113495bSYour Name 	wlan_hdd_send_status_pkg(NULL, NULL, 0, 0);
422*5113495bSYour Name }
423*5113495bSYour Name 
424*5113495bSYour Name /*
425*5113495bSYour Name  * hdd_lpass_is_supported() - Is lpass feature supported?
426*5113495bSYour Name  * (public function documented in wlan_hdd_lpass.h)
427*5113495bSYour Name  */
hdd_lpass_is_supported(struct hdd_context * hdd_ctx)428*5113495bSYour Name bool hdd_lpass_is_supported(struct hdd_context *hdd_ctx)
429*5113495bSYour Name {
430*5113495bSYour Name 	bool lpass_support = false;
431*5113495bSYour Name 	QDF_STATUS status;
432*5113495bSYour Name 
433*5113495bSYour Name 	status = ucfg_mlme_get_lpass_support(hdd_ctx->psoc, &lpass_support);
434*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
435*5113495bSYour Name 		hdd_err("Failed to get LPASS support config");
436*5113495bSYour Name 
437*5113495bSYour Name 	return lpass_support;
438*5113495bSYour Name }
439