1 /*
2 * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024, Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /**
19 * DOC: hdd_cm_connect.c
20 *
21 * WLAN Host Device Driver connect APIs implementation
22 *
23 */
24
25 #include "wlan_hdd_main.h"
26 #include <wlan_hdd_mlo.h>
27 #include "wlan_hdd_cm_api.h"
28 #include "wlan_hdd_trace.h"
29 #include "wlan_hdd_object_manager.h"
30 #include "wlan_hdd_power.h"
31 #include "wlan_hdd_connectivity_logging.h"
32 #include <osif_cm_req.h>
33 #include <wlan_logging_sock_svc.h>
34 #include <wlan_hdd_green_ap.h>
35 #include <wlan_hdd_p2p.h>
36 #include <wlan_p2p_ucfg_api.h>
37 #include <wlan_pkt_capture_ucfg_api.h>
38 #include <wlan_hdd_ipa.h>
39 #include <wlan_ipa_ucfg_api.h>
40 #include <wlan_hdd_ftm_time_sync.h>
41 #include "wlan_crypto_global_api.h"
42 #include "wlan_vdev_mgr_ucfg_api.h"
43 #include "wlan_hdd_bootup_marker.h"
44 #include "sme_qos_internal.h"
45 #include "wlan_dlm_ucfg_api.h"
46 #include "wlan_hdd_scan.h"
47 #include "wlan_osif_priv.h"
48 #include <enet.h>
49 #include <wlan_mlme_twt_ucfg_api.h>
50 #include "wlan_roam_debug.h"
51 #include <wlan_hdd_regulatory.h>
52 #include "wlan_hdd_hostapd.h"
53 #include <wlan_twt_ucfg_ext_api.h>
54 #include <osif_twt_internal.h>
55 #include "wlan_osif_features.h"
56 #include "wlan_osif_request_manager.h"
57 #include <wlan_dp_ucfg_api.h>
58 #include "wlan_psoc_mlme_ucfg_api.h"
59 #include "wlan_action_oui_ucfg_api.h"
60
hdd_cm_is_vdev_associated(struct wlan_hdd_link_info * link_info)61 bool hdd_cm_is_vdev_associated(struct wlan_hdd_link_info *link_info)
62 {
63 struct wlan_objmgr_vdev *vdev;
64 bool is_vdev_active;
65 enum QDF_OPMODE opmode;
66 struct hdd_station_ctx *sta_ctx;
67
68 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
69 if (link_info->adapter->device_mode == QDF_NDI_MODE)
70 return (sta_ctx->conn_info.conn_state ==
71 eConnectionState_NdiConnected);
72
73 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
74 if (!vdev)
75 return false;
76
77 opmode = wlan_vdev_mlme_get_opmode(vdev);
78 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
79 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
80 return false;
81 }
82 is_vdev_active = ucfg_cm_is_vdev_active(vdev);
83
84 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
85
86 return is_vdev_active;
87 }
88
hdd_cm_is_vdev_connected(struct wlan_hdd_link_info * link_info)89 bool hdd_cm_is_vdev_connected(struct wlan_hdd_link_info *link_info)
90 {
91 struct wlan_objmgr_vdev *vdev;
92 bool is_vdev_connected;
93 struct hdd_station_ctx *sta_ctx;
94 enum QDF_OPMODE opmode = link_info->adapter->device_mode;
95
96 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
97 if (opmode == QDF_NDI_MODE)
98 return (sta_ctx->conn_info.conn_state ==
99 eConnectionState_NdiConnected);
100
101 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE)
102 return false;
103
104 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
105 if (!vdev)
106 return false;
107
108 is_vdev_connected = ucfg_cm_is_vdev_connected(vdev);
109
110 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
111
112 return is_vdev_connected;
113 }
114
hdd_cm_is_connecting(struct wlan_hdd_link_info * link_info)115 bool hdd_cm_is_connecting(struct wlan_hdd_link_info *link_info)
116 {
117 struct wlan_objmgr_vdev *vdev;
118 bool is_vdev_connecting;
119 enum QDF_OPMODE opmode;
120
121 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
122 if (!vdev)
123 return false;
124
125 opmode = wlan_vdev_mlme_get_opmode(vdev);
126 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
127 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
128 return false;
129 }
130 is_vdev_connecting = ucfg_cm_is_vdev_connecting(vdev);
131
132 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
133
134 return is_vdev_connecting;
135 }
136
hdd_cm_is_disconnected(struct wlan_hdd_link_info * link_info)137 bool hdd_cm_is_disconnected(struct wlan_hdd_link_info *link_info)
138 {
139 struct wlan_objmgr_vdev *vdev;
140 bool is_vdev_disconnected;
141 enum QDF_OPMODE opmode;
142
143 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
144 if (!vdev)
145 return false;
146
147 opmode = wlan_vdev_mlme_get_opmode(vdev);
148 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
149 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
150 return false;
151 }
152 is_vdev_disconnected = ucfg_cm_is_vdev_disconnected(vdev);
153
154 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
155
156 return is_vdev_disconnected;
157 }
158
hdd_cm_is_vdev_roaming(struct wlan_hdd_link_info * link_info)159 bool hdd_cm_is_vdev_roaming(struct wlan_hdd_link_info *link_info)
160 {
161 struct wlan_objmgr_vdev *vdev;
162 bool is_vdev_roaming;
163 enum QDF_OPMODE opmode;
164
165 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
166 if (!vdev)
167 return false;
168
169 opmode = wlan_vdev_mlme_get_opmode(vdev);
170 if (opmode != QDF_STA_MODE && opmode != QDF_P2P_CLIENT_MODE) {
171 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
172 return false;
173 }
174 is_vdev_roaming = ucfg_cm_is_vdev_roaming(vdev);
175
176 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
177
178 return is_vdev_roaming;
179 }
180
hdd_cm_set_peer_authenticate(struct wlan_hdd_link_info * link_info,struct qdf_mac_addr * bssid,bool is_auth_required)181 void hdd_cm_set_peer_authenticate(struct wlan_hdd_link_info *link_info,
182 struct qdf_mac_addr *bssid,
183 bool is_auth_required)
184 {
185 hdd_debug("sta: " QDF_MAC_ADDR_FMT "Changing TL state to %s",
186 QDF_MAC_ADDR_REF(bssid->bytes),
187 is_auth_required ? "CONNECTED" : "AUTHENTICATED");
188
189 hdd_change_peer_state(link_info, bssid->bytes,
190 is_auth_required ?
191 OL_TXRX_PEER_STATE_CONN :
192 OL_TXRX_PEER_STATE_AUTH);
193 hdd_conn_set_authenticated(link_info, !is_auth_required);
194 hdd_objmgr_set_peer_mlme_auth_state(link_info->vdev,
195 !is_auth_required);
196 }
197
hdd_cm_update_rssi_snr_by_bssid(struct wlan_hdd_link_info * link_info)198 void hdd_cm_update_rssi_snr_by_bssid(struct wlan_hdd_link_info *link_info)
199 {
200 struct hdd_station_ctx *sta_ctx;
201 int8_t snr = 0;
202 struct hdd_adapter *adapter = link_info->adapter;
203 mac_handle_t mac_handle;
204
205 if (!adapter) {
206 hdd_err_rl("null hdd_adapter pointer");
207 return;
208 }
209
210 mac_handle = hdd_adapter_get_mac_handle(adapter);
211
212 if (!mac_handle) {
213 hdd_err_rl("null mac_handle pointer");
214 return;
215 }
216
217 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
218 hdd_get_rssi_snr_by_bssid(mac_handle,
219 sta_ctx->conn_info.bssid.bytes,
220 &link_info->rssi, &snr);
221
222 /* If RSSi is reported as positive then it is invalid */
223 if (link_info->rssi > 0) {
224 hdd_debug_rl("RSSI invalid %d", link_info->rssi);
225 link_info->rssi = 0;
226 }
227
228 hdd_debug("snr: %d, rssi: %d", snr, link_info->rssi);
229
230 sta_ctx->conn_info.signal = link_info->rssi;
231 sta_ctx->conn_info.noise = sta_ctx->conn_info.signal - snr;
232 sta_ctx->cache_conn_info.signal = sta_ctx->conn_info.signal;
233 sta_ctx->cache_conn_info.noise = sta_ctx->conn_info.noise;
234 }
235
hdd_cm_handle_assoc_event(struct wlan_objmgr_vdev * vdev,uint8_t * peer_mac)236 void hdd_cm_handle_assoc_event(struct wlan_objmgr_vdev *vdev, uint8_t *peer_mac)
237 {
238 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
239 struct wlan_hdd_link_info *link_info;
240 struct hdd_station_ctx *sta_ctx;
241 int ret;
242
243 if (!hdd_ctx) {
244 hdd_err("hdd_ctx is NULL");
245 return;
246 }
247
248 link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev));
249 if (!link_info) {
250 hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev));
251 return;
252 }
253
254 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
255 ret = hdd_objmgr_set_peer_mlme_state(link_info->vdev,
256 WLAN_ASSOC_STATE);
257 if (ret)
258 hdd_err("Peer object " QDF_MAC_ADDR_FMT " fail to set associated state",
259 QDF_MAC_ADDR_REF(peer_mac));
260 ucfg_dp_add_latency_critical_client(vdev,
261 hdd_convert_cfgdot11mode_to_80211mode(
262 sta_ctx->conn_info.dot11mode));
263
264 ucfg_dp_bus_bw_compute_prev_txrx_stats(vdev);
265 ucfg_dp_bus_bw_compute_timer_start(hdd_ctx->psoc);
266
267 if (ucfg_pkt_capture_get_pktcap_mode(hdd_ctx->psoc))
268 ucfg_pkt_capture_record_channel(link_info->vdev);
269 }
270
271 /**
272 * hdd_cm_netif_features_update_required() - Check if feature update
273 * is required
274 * @adapter: pointer to the adapter structure
275 * Returns: true if the connection is legacy and TSO and Checksum offload
276 * enabled or if the connection is not latency and TSO and Checksum
277 * offload are not enabled, false otherwise
278 */
hdd_cm_netif_features_update_required(struct hdd_adapter * adapter)279 static bool hdd_cm_netif_features_update_required(struct hdd_adapter *adapter)
280 {
281 bool is_legacy_connection = hdd_is_legacy_connection(adapter->deflink);
282
283 hdd_debug("Legacy Connection: %d, TSO_CSUM Feature Enabled:%d",
284 is_legacy_connection, adapter->tso_csum_feature_enabled);
285
286 if (adapter->tso_csum_feature_enabled && is_legacy_connection)
287 return true;
288
289 if (!adapter->tso_csum_feature_enabled && !is_legacy_connection)
290 return true;
291
292 return false;
293 }
294
hdd_cm_netif_queue_enable(struct hdd_adapter * adapter)295 void hdd_cm_netif_queue_enable(struct hdd_adapter *adapter)
296 {
297 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
298 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
299
300 if (cdp_cfg_get(soc, cfg_dp_disable_legacy_mode_csum_offload) &&
301 hdd_cm_netif_features_update_required(adapter)) {
302 hdd_adapter_ops_record_event(hdd_ctx,
303 WLAN_HDD_ADAPTER_OPS_WORK_POST,
304 adapter->deflink->vdev_id);
305 qdf_queue_work(0, hdd_ctx->adapter_ops_wq,
306 &adapter->netdev_features_update_work);
307 }
308
309 wlan_hdd_netif_queue_control(adapter,
310 WLAN_WAKE_ALL_NETIF_QUEUE,
311 WLAN_CONTROL_PATH);
312 }
313
hdd_cm_clear_pmf_stats(struct hdd_adapter * adapter)314 void hdd_cm_clear_pmf_stats(struct hdd_adapter *adapter)
315 {
316 qdf_mem_zero(&adapter->deflink->hdd_stats.hdd_pmf_stats,
317 sizeof(adapter->deflink->hdd_stats.hdd_pmf_stats));
318 }
319
hdd_cm_save_connect_status(struct wlan_hdd_link_info * link_info,uint32_t reason_code)320 void hdd_cm_save_connect_status(struct wlan_hdd_link_info *link_info,
321 uint32_t reason_code)
322 {
323 struct hdd_station_ctx *hdd_sta_ctx;
324
325 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
326 link_info->adapter->connect_req_status = reason_code;
327 hdd_sta_ctx->conn_info.assoc_status_code = reason_code;
328 hdd_sta_ctx->cache_conn_info.assoc_status_code = reason_code;
329 }
330
331 #ifdef WLAN_FEATURE_11BE_MLO
hdd_cm_save_connected_links_info(struct qdf_mac_addr * self_mac,struct qdf_mac_addr * bssid,int32_t link_id)332 QDF_STATUS hdd_cm_save_connected_links_info(struct qdf_mac_addr *self_mac,
333 struct qdf_mac_addr *bssid,
334 int32_t link_id)
335 {
336 struct hdd_context *hdd_ctx;
337 struct wlan_hdd_link_info *link_info;
338 struct hdd_station_ctx *sta_ctx;
339
340 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
341 if (!hdd_ctx) {
342 hdd_err("HDD context NULL");
343 return QDF_STATUS_E_INVAL;
344 }
345
346 link_info = hdd_get_link_info_by_link_addr(hdd_ctx, self_mac);
347 if (!link_info) {
348 hdd_err("No link info with MAC: " QDF_MAC_ADDR_FMT,
349 QDF_MAC_ADDR_REF(self_mac->bytes));
350 return QDF_STATUS_E_INVAL;
351 }
352
353 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
354 hdd_cm_set_ieee_link_id(link_info, link_id);
355 qdf_copy_macaddr(&sta_ctx->conn_info.bssid, bssid);
356 return QDF_STATUS_SUCCESS;
357 }
358
359 void
hdd_cm_set_ieee_link_id(struct wlan_hdd_link_info * link_info,uint8_t link_id)360 hdd_cm_set_ieee_link_id(struct wlan_hdd_link_info *link_info, uint8_t link_id)
361 {
362 struct hdd_station_ctx *sta_ctx =
363 WLAN_HDD_GET_STATION_CTX_PTR(link_info);
364
365 hdd_debug("old_link_id:%d new_link_id:%d",
366 sta_ctx->conn_info.ieee_link_id, link_id);
367 sta_ctx->conn_info.ieee_link_id = link_id;
368 }
369
370 void
hdd_cm_clear_ieee_link_id(struct wlan_hdd_link_info * link_info)371 hdd_cm_clear_ieee_link_id(struct wlan_hdd_link_info *link_info)
372 {
373 struct hdd_station_ctx *sta_ctx =
374 WLAN_HDD_GET_STATION_CTX_PTR(link_info);
375
376 hdd_debug("clear link id:%d", sta_ctx->conn_info.ieee_link_id);
377 sta_ctx->conn_info.ieee_link_id = WLAN_INVALID_LINK_ID;
378 }
379 #endif
380
381 #ifdef FEATURE_WLAN_WAPI
hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)382 static bool hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)
383 {
384 if (auth_type == eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ||
385 auth_type == eCSR_AUTH_TYPE_WAPI_WAI_PSK)
386 return true;
387 else
388 return false;
389 }
390 #else
hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)391 static inline bool hdd_cm_is_wapi_sta(enum csr_akm_type auth_type)
392 {
393 return false;
394 }
395 #endif
396
hdd_update_scan_ie_for_connect(struct hdd_adapter * adapter,struct osif_connect_params * params)397 static void hdd_update_scan_ie_for_connect(struct hdd_adapter *adapter,
398 struct osif_connect_params *params)
399 {
400 if (adapter->device_mode == QDF_P2P_CLIENT_MODE) {
401 params->scan_ie.ptr =
402 &adapter->scan_info.scan_add_ie.addIEdata[0];
403 params->scan_ie.len = adapter->scan_info.scan_add_ie.length;
404 } else if (adapter->scan_info.default_scan_ies) {
405 params->scan_ie.ptr = adapter->scan_info.default_scan_ies;
406 params->scan_ie.len = adapter->scan_info.default_scan_ies_len;
407 } else if (adapter->scan_info.scan_add_ie.length) {
408 params->scan_ie.ptr = adapter->scan_info.scan_add_ie.addIEdata;
409 params->scan_ie.len = adapter->scan_info.scan_add_ie.length;
410 }
411 }
412
413 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)) || \
414 defined(CFG80211_11BE_BASIC)) && \
415 defined(WLAN_FEATURE_11BE)
416 /**
417 * hdd_update_action_oui_for_connect() - Update Action OUI for 802.11be AP
418 * @hdd_ctx: hdd context
419 * @req: connect request parameter
420 *
421 * If user sets flag ASSOC_REQ_DISABLE_EHT in connect request, driver
422 * will send action oui "ffffff 00 01" to host mlme and also firmware
423 * for action id ACTION_OUI_11BE_OUI_ALLOW, so that all the AP will
424 * be not matched with this OUI and 802.11be mode will not be allowed,
425 * possibly downgrade to 11ax will happen.
426 * If user doesn't set ASSOC_REQ_DISABLE_EHT, driver/firmware will
427 * recover to default INI setting.
428 *
429 * Returns: void
430 */
431 static void
hdd_update_action_oui_for_connect(struct hdd_context * hdd_ctx,struct cfg80211_connect_params * req)432 hdd_update_action_oui_for_connect(struct hdd_context *hdd_ctx,
433 struct cfg80211_connect_params *req)
434 {
435 QDF_STATUS status;
436 uint8_t *str;
437 bool usr_disable_eht;
438
439 if (!ucfg_action_oui_enabled(hdd_ctx->psoc))
440 return;
441
442 usr_disable_eht = ucfg_mlme_get_usr_disable_sta_eht(hdd_ctx->psoc);
443 if (req->flags & ASSOC_REQ_DISABLE_EHT ||
444 !(req->flags & CONNECT_REQ_MLO_SUPPORT)) {
445 if (usr_disable_eht) {
446 hdd_debug("user eht is disabled already");
447 return;
448 }
449 status = ucfg_action_oui_cleanup(
450 hdd_ctx->psoc, ACTION_OUI_11BE_OUI_ALLOW);
451 if (!QDF_IS_STATUS_SUCCESS(status)) {
452 hdd_err("Failed to cleanup oui id %d",
453 ACTION_OUI_11BE_OUI_ALLOW);
454 return;
455 }
456 status = ucfg_action_oui_parse(hdd_ctx->psoc,
457 ACTION_OUI_INVALID,
458 ACTION_OUI_11BE_OUI_ALLOW);
459 if (!QDF_IS_STATUS_SUCCESS(status)) {
460 hdd_err("Failed to parse action_oui str for id %d",
461 ACTION_OUI_11BE_OUI_ALLOW);
462 return;
463 }
464 } else {
465 if (!usr_disable_eht) {
466 hdd_debug("user eht is enabled already");
467 return;
468 }
469 status = ucfg_action_oui_cleanup(hdd_ctx->psoc,
470 ACTION_OUI_11BE_OUI_ALLOW);
471 if (!QDF_IS_STATUS_SUCCESS(status)) {
472 hdd_err("Failed to cleanup oui id %d",
473 ACTION_OUI_11BE_OUI_ALLOW);
474 return;
475 }
476 str = ucfg_action_oui_get_config(hdd_ctx->psoc,
477 ACTION_OUI_11BE_OUI_ALLOW);
478 if (!qdf_str_len(str))
479 goto send_oui;
480
481 status = ucfg_action_oui_parse(hdd_ctx->psoc,
482 str, ACTION_OUI_11BE_OUI_ALLOW);
483 if (!QDF_IS_STATUS_SUCCESS(status)) {
484 hdd_err("Failed to parse action_oui str for id %d",
485 ACTION_OUI_11BE_OUI_ALLOW);
486 return;
487 }
488 }
489
490 send_oui:
491 status = ucfg_action_oui_send_by_id(hdd_ctx->psoc,
492 ACTION_OUI_11BE_OUI_ALLOW);
493 if (!QDF_IS_STATUS_SUCCESS(status)) {
494 hdd_err("Failed to send oui id %d", ACTION_OUI_11BE_OUI_ALLOW);
495 return;
496 }
497 ucfg_mlme_set_usr_disable_sta_eht(hdd_ctx->psoc, !usr_disable_eht);
498 }
499 #else
500 static void
hdd_update_action_oui_for_connect(struct hdd_context * hdd_ctx,struct cfg80211_connect_params * req)501 hdd_update_action_oui_for_connect(struct hdd_context *hdd_ctx,
502 struct cfg80211_connect_params *req)
503 {
504 }
505 #endif
506
507 #ifdef WLAN_FEATURE_11BE
508 static inline bool
hdd_config_is_dot11mode_11be_only(struct hdd_config * config)509 hdd_config_is_dot11mode_11be_only(struct hdd_config *config)
510 {
511 if (config->dot11Mode == eHDD_DOT11_MODE_11be_ONLY)
512 return true;
513 else
514 return false;
515 }
516 #else
517 static inline bool
hdd_config_is_dot11mode_11be_only(struct hdd_config * config)518 hdd_config_is_dot11mode_11be_only(struct hdd_config *config)
519 {
520 return false;
521 }
522 #endif
523
524 /**
525 * hdd_get_dot11mode_filter() - Get dot11 mode filter
526 * @hdd_ctx: HDD context
527 *
528 * This function is used to get the dot11 mode filter
529 *
530 * Context: Any Context.
531 * Return: dot11_mode_filter
532 */
533 static enum dot11_mode_filter
hdd_get_dot11mode_filter(struct hdd_context * hdd_ctx)534 hdd_get_dot11mode_filter(struct hdd_context *hdd_ctx)
535 {
536 struct hdd_config *config = hdd_ctx->config;
537
538 if (config->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
539 return ALLOW_11N_ONLY;
540 else if (config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
541 return ALLOW_11AC_ONLY;
542 else if (config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
543 return ALLOW_11AX_ONLY;
544 else if (hdd_config_is_dot11mode_11be_only(config))
545 return ALLOW_11BE_ONLY;
546 else
547 return ALLOW_ALL;
548 }
549
550 /**
551 * hdd_get_sap_adapter_of_dfs - Get sap adapter on dfs channel
552 * @hdd_ctx: HDD context
553 *
554 * This function is used to get the sap adapter on dfs channel.
555 *
556 * Return: pointer to adapter or null
557 */
558 static struct hdd_adapter *
hdd_get_sap_adapter_of_dfs(struct hdd_context * hdd_ctx)559 hdd_get_sap_adapter_of_dfs(struct hdd_context *hdd_ctx)
560 {
561 struct hdd_adapter *adapter, *next_adapter = NULL;
562 wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_GET_ADAPTER;
563 struct wlan_channel *chan;
564 struct ch_params ch_params = {0};
565 struct wlan_hdd_link_info *link_info;
566
567 hdd_for_each_adapter_dev_held_safe(hdd_ctx, adapter, next_adapter,
568 dbgid) {
569 if (adapter->device_mode != QDF_SAP_MODE)
570 goto loop_next;
571
572 hdd_adapter_for_each_active_link_info(adapter, link_info) {
573 if (wlan_hdd_validate_vdev_id(link_info->vdev_id))
574 continue;
575
576 /*
577 * sap is not in started state and also not under doing
578 * CAC, so it is fine to go ahead with sta.
579 */
580 if (!test_bit(SOFTAP_BSS_STARTED,
581 &link_info->link_flags) &&
582 hdd_ctx->dev_dfs_cac_status != DFS_CAC_IN_PROGRESS)
583 continue;
584
585 wlan_objmgr_vdev_get_ref(link_info->vdev,
586 WLAN_HDD_ID_OBJ_MGR);
587 chan = wlan_vdev_get_active_channel(link_info->vdev);
588 if (!chan) {
589 hdd_debug("Can not get active channel");
590 wlan_objmgr_vdev_release_ref(link_info->vdev,
591 WLAN_HDD_ID_OBJ_MGR);
592 continue;
593 }
594
595 wlan_objmgr_vdev_release_ref(link_info->vdev,
596 WLAN_HDD_ID_OBJ_MGR);
597
598 if (!wlan_reg_is_5ghz_ch_freq(chan->ch_freq))
599 continue;
600
601 ch_params.ch_width = chan->ch_width;
602 if (ch_params.ch_width == CH_WIDTH_160MHZ)
603 wlan_reg_set_create_punc_bitmap(&ch_params,
604 true);
605
606 if (wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
607 hdd_ctx->pdev,
608 chan->ch_freq,
609 &ch_params,
610 REG_CURRENT_PWR_MODE) ==
611 CHANNEL_STATE_DFS) {
612 hdd_adapter_dev_put_debug(adapter, dbgid);
613 if (next_adapter)
614 hdd_adapter_dev_put_debug(next_adapter,
615 dbgid);
616
617 return adapter;
618 }
619 }
620 loop_next:
621 hdd_adapter_dev_put_debug(adapter, dbgid);
622 }
623
624 return NULL;
625 }
626
627 /**
628 * wlan_hdd_cm_handle_sap_sta_dfs_conc() - to handle SAP STA DFS conc
629 * @hdd_ctx: hdd_ctx
630 * @req: connect req
631 *
632 * This routine will move SAP from dfs to non-dfs, if sta is coming up.
633 *
634 * Return: false if sta-sap conc is not allowed, else return true
635 */
636 static
wlan_hdd_cm_handle_sap_sta_dfs_conc(struct hdd_context * hdd_ctx,struct cfg80211_connect_params * req)637 bool wlan_hdd_cm_handle_sap_sta_dfs_conc(struct hdd_context *hdd_ctx,
638 struct cfg80211_connect_params *req)
639 {
640 struct hdd_adapter *ap_adapter;
641 struct hdd_ap_ctx *hdd_ap_ctx;
642 struct hdd_hostapd_state *hostapd_state;
643 QDF_STATUS status;
644 qdf_freq_t ch_freq = 0;
645 enum phy_ch_width ch_bw;
646 enum channel_state ch_state;
647 struct scan_filter *scan_filter;
648 qdf_list_t *list = NULL;
649 qdf_list_node_t *cur_lst = NULL;
650 struct scan_cache_node *cur_node = NULL;
651 bool is_6ghz_cap = false;
652
653 ap_adapter = hdd_get_sap_adapter_of_dfs(hdd_ctx);
654 /* probably no dfs sap running, no handling required */
655 if (!ap_adapter)
656 return true;
657
658 /* if sap is currently doing CAC then don't allow sta to go further */
659 if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS) {
660 hdd_err("Concurrent SAP is in CAC state, STA is not allowed");
661 return false;
662 }
663
664 /*
665 * log and return error, if we allow STA to go through, we don't
666 * know what is going to happen better stop sta connection
667 */
668 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter->deflink);
669 if (!hdd_ap_ctx) {
670 hdd_err("AP context not found");
671 return false;
672 }
673
674 if (req->channel && req->channel->center_freq) {
675 ch_freq = req->channel->center_freq;
676 goto def_chan;
677 }
678 /*
679 * find out by looking in to scan cache where sta is going to
680 * connect by passing its ssid amd bssid.
681 */
682 scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
683 if (!scan_filter)
684 goto def_chan;
685
686 if (req->bssid) {
687 scan_filter->num_of_bssid = 1;
688 qdf_mem_copy(scan_filter->bssid_list[0].bytes, req->bssid,
689 QDF_MAC_ADDR_SIZE);
690 }
691 if (req->ssid_len > WLAN_SSID_MAX_LEN) {
692 scan_filter->num_of_ssid = 0;
693 hdd_err("req ssid len invalid %zu", req->ssid_len);
694 } else {
695 scan_filter->num_of_ssid = 1;
696 scan_filter->ssid_list[0].length = req->ssid_len;
697 qdf_mem_copy(scan_filter->ssid_list[0].ssid, req->ssid,
698 scan_filter->ssid_list[0].length);
699 }
700 scan_filter->ignore_auth_enc_type = true;
701 list = ucfg_scan_get_result(hdd_ctx->pdev, scan_filter);
702 qdf_mem_free(scan_filter);
703
704 if (!list || (list && !qdf_list_size(list))) {
705 hdd_debug("scan list empty");
706 goto purge_list;
707 }
708 qdf_list_peek_front(list, &cur_lst);
709 if (!cur_lst)
710 goto purge_list;
711
712 cur_node = qdf_container_of(cur_lst, struct scan_cache_node, node);
713 ch_freq = cur_node->entry->channel.chan_freq;
714 purge_list:
715 if (list)
716 ucfg_scan_purge_results(list);
717 def_chan:
718 /*
719 * If the STA's channel is 2.4 GHz, then set pcl with only 2.4 GHz
720 * channels for roaming case.
721 */
722 if (WLAN_REG_IS_24GHZ_CH_FREQ(ch_freq)) {
723 hdd_info("sap is on dfs, new sta conn on 2.4 is allowed");
724 return true;
725 }
726
727 if (policy_mgr_is_hw_sbs_capable(hdd_ctx->psoc) &&
728 ch_freq &&
729 policy_mgr_are_sbs_chan(hdd_ctx->psoc,
730 ch_freq,
731 hdd_ap_ctx->operating_chan_freq)) {
732 hdd_debug("sta freq %d sap freq %d in sbs mode is allowed",
733 ch_freq, hdd_ap_ctx->operating_chan_freq);
734 return true;
735 }
736
737 /*
738 * If channel is 0 or DFS or LTE unsafe then better to call pcl and
739 * find out the best channel. If channel is non-dfs 5 GHz then
740 * better move SAP to STA's channel to make scc, so we have room
741 * for 3port MCC scenario.
742 */
743 ch_bw = hdd_ap_ctx->sap_config.ch_width_orig;
744 if (ch_freq)
745 is_6ghz_cap = policy_mgr_get_ap_6ghz_capable(hdd_ctx->psoc,
746 ap_adapter->deflink->vdev_id,
747 NULL);
748
749 if (!ch_freq || wlan_reg_is_dfs_for_freq(hdd_ctx->pdev, ch_freq) ||
750 !policy_mgr_is_safe_channel(hdd_ctx->psoc, ch_freq) ||
751 wlan_reg_is_passive_for_freq(hdd_ctx->pdev, ch_freq) ||
752 (WLAN_REG_IS_6GHZ_CHAN_FREQ(ch_freq) && !is_6ghz_cap))
753 ch_freq = policy_mgr_get_nondfs_preferred_channel(
754 hdd_ctx->psoc, PM_SAP_MODE,
755 true, ap_adapter->deflink->vdev_id);
756
757 if (WLAN_REG_IS_5GHZ_CH_FREQ(ch_freq) &&
758 ch_bw > CH_WIDTH_20MHZ) {
759 struct ch_params ch_params;
760
761 qdf_mem_zero(&ch_params, sizeof(ch_params));
762 ch_params.ch_width = ch_bw;
763 ch_state =
764 wlan_reg_get_5g_bonded_channel_state_for_pwrmode(
765 hdd_ctx->pdev, ch_freq, &ch_params,
766 REG_CURRENT_PWR_MODE);
767 while (ch_bw > CH_WIDTH_20MHZ &&
768 ch_state != CHANNEL_STATE_ENABLE) {
769 ch_bw =
770 wlan_reg_get_next_lower_bandwidth(ch_bw);
771 ch_params.ch_width = ch_bw;
772 ch_state =
773 wlan_reg_get_5g_bonded_channel_state_for_pwrmode
774 (hdd_ctx->pdev, ch_freq, &ch_params,
775 REG_CURRENT_PWR_MODE);
776 }
777 hdd_debug("bw change from %d to %d",
778 hdd_ap_ctx->sap_config.ch_width_orig,
779 ch_bw);
780 }
781
782 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter->deflink);
783 qdf_event_reset(&hostapd_state->qdf_event);
784 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->deflink->vdev_id,
785 CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS);
786
787 status = wlansap_set_channel_change_with_csa(
788 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter->deflink), ch_freq,
789 ch_bw, false);
790
791 if (QDF_STATUS_SUCCESS != status) {
792 hdd_err("Set channel with CSA IE failed, can't allow STA");
793 return false;
794 }
795
796 /*
797 * wait here for SAP to finish the channel switch. When channel
798 * switch happens, SAP sends few beacons with CSA_IE. After
799 * successfully Transmission of those beacons, it will move its
800 * state from started to disconnected and move to new channel.
801 * once it moves to new channel, sap again moves its state
802 * machine from disconnected to started and set this event.
803 * wait for 10 secs to finish this.
804 */
805 status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
806 10000);
807 if (!QDF_IS_STATUS_SUCCESS(status)) {
808 hdd_err("wait for qdf_event failed, STA not allowed!!");
809 return false;
810 }
811
812 return true;
813 }
814
wlan_hdd_cm_connect(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_connect_params * req)815 int wlan_hdd_cm_connect(struct wiphy *wiphy,
816 struct net_device *ndev,
817 struct cfg80211_connect_params *req)
818 {
819 int status;
820 struct wlan_objmgr_vdev *vdev;
821 struct osif_connect_params params;
822 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
823 struct hdd_context *hdd_ctx;
824 struct hdd_station_ctx *hdd_sta_ctx;
825 qdf_freq_t ch_freq = 0;
826
827 hdd_enter();
828
829 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
830 hdd_err("Command not allowed in FTM mode");
831 return -EINVAL;
832 }
833
834 if (wlan_hdd_validate_vdev_id(adapter->deflink->vdev_id))
835 return -EINVAL;
836
837 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
838 TRACE_CODE_HDD_CFG80211_CONNECT,
839 adapter->deflink->vdev_id, adapter->device_mode);
840
841 if (adapter->device_mode != QDF_STA_MODE &&
842 adapter->device_mode != QDF_P2P_CLIENT_MODE) {
843 hdd_err("Device_mode %s(%d) is not supported",
844 qdf_opmode_str(adapter->device_mode),
845 adapter->device_mode);
846 return -EINVAL;
847 }
848
849 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
850 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
851
852 status = wlan_hdd_validate_context(hdd_ctx);
853 if (status)
854 return status;
855
856 hdd_reg_wait_for_country_change(hdd_ctx);
857
858 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
859 !wlan_hdd_cm_handle_sap_sta_dfs_conc(hdd_ctx, req)) {
860 hdd_err("sap-sta conc will fail, can't allow sta");
861 return -EINVAL;
862 }
863
864 if (req->channel && req->channel->center_freq)
865 ch_freq = req->channel->center_freq;
866
867 if (ch_freq && wlan_reg_is_6ghz_chan_freq(ch_freq) &&
868 !wlan_reg_is_6ghz_band_set(hdd_ctx->pdev)) {
869 hdd_err("6 GHz band disabled");
870 return -EINVAL;
871 }
872
873 qdf_mem_zero(¶ms, sizeof(params));
874 ucfg_dlm_dump_deny_list_ap(hdd_ctx->pdev);
875 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink, WLAN_OSIF_CM_ID);
876 if (!vdev)
877 return -EINVAL;
878
879 ucfg_pmo_flush_gtk_offload_req(vdev);
880 qdf_mem_zero(&hdd_sta_ctx->conn_info.conn_flag,
881 sizeof(hdd_sta_ctx->conn_info.conn_flag));
882
883 /*
884 * Reset the ptk, gtk status flags to avoid using old/previous
885 * connection status.
886 */
887 hdd_sta_ctx->conn_info.gtk_installed = false;
888 hdd_sta_ctx->conn_info.ptk_installed = false;
889 adapter->last_disconnect_reason = 0;
890
891 qdf_runtime_pm_prevent_suspend(&hdd_ctx->runtime_context.connect);
892 hdd_prevent_suspend_timeout(HDD_WAKELOCK_CONNECT_COMPLETE,
893 WIFI_POWER_EVENT_WAKELOCK_CONNECT);
894
895 params.force_rsne_override = hdd_ctx->force_rsne_override;
896 params.dot11mode_filter = hdd_get_dot11mode_filter(hdd_ctx);
897
898 hdd_update_scan_ie_for_connect(adapter, ¶ms);
899 hdd_update_action_oui_for_connect(hdd_ctx, req);
900
901 if (!hdd_cm_is_vdev_associated(adapter->deflink)) {
902 /*
903 * Clear user/wpa_supplicant disabled_roaming flag for new
904 * connection
905 */
906 ucfg_clear_user_disabled_roaming(hdd_ctx->psoc,
907 adapter->deflink->vdev_id);
908 }
909 status = osif_cm_connect(ndev, vdev, req, ¶ms);
910
911 if (status || ucfg_cm_is_vdev_roaming(vdev)) {
912 /* Release suspend and wake lock for failure or roam invoke */
913 if (status)
914 hdd_err("Vdev %d connect failed status %d",
915 adapter->deflink->vdev_id, status);
916 else
917 hdd_debug("Vdev %d: connect lead to roam invoke",
918 adapter->deflink->vdev_id);
919 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
920 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
921 }
922
923 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
924 return status;
925 }
926
hdd_cm_rec_connect_info(struct wlan_cm_connect_resp * rsp)927 static void hdd_cm_rec_connect_info(struct wlan_cm_connect_resp *rsp)
928 {
929 if (rsp->is_reassoc)
930 wlan_rec_conn_info(rsp->vdev_id, DEBUG_CONN_ROAMED_IND,
931 rsp->bssid.bytes, rsp->cm_id, 0);
932 else
933 wlan_rec_conn_info(rsp->vdev_id, DEBUG_CONN_CONNECT_RESULT,
934 rsp->bssid.bytes, rsp->cm_id << 16 |
935 rsp->reason,
936 rsp->status_code);
937 }
938
939 static void
hdd_cm_connect_failure_pre_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)940 hdd_cm_connect_failure_pre_user_update(struct wlan_objmgr_vdev *vdev,
941 struct wlan_cm_connect_resp *rsp)
942 {
943 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
944 struct hdd_adapter *adapter;
945 struct hdd_station_ctx *hdd_sta_ctx;
946 uint32_t time_buffer_size;
947 struct wlan_hdd_link_info *link_info;
948 bool is_link_switch =
949 wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev);
950
951 if (!hdd_ctx) {
952 hdd_err("hdd_ctx is NULL");
953 return;
954 }
955
956 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
957 if (!link_info) {
958 hdd_err("adapter is NULL vdev %d", rsp->vdev_id);
959 return;
960 }
961
962 adapter = link_info->adapter;
963 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
964 time_buffer_size = sizeof(hdd_sta_ctx->conn_info.connect_time);
965 qdf_mem_zero(hdd_sta_ctx->conn_info.connect_time, time_buffer_size);
966 hdd_init_scan_reject_params(hdd_ctx);
967 hdd_cm_save_connect_status(link_info, rsp->status_code);
968 if (!is_link_switch) {
969 /* For link switch connection failure, do not clear existing
970 * connection info in OSIF.
971 */
972 hdd_conn_remove_connect_info(hdd_sta_ctx);
973 hdd_adapter_reset_station_ctx(adapter);
974 }
975
976 ucfg_dp_remove_conn_info(vdev);
977 hdd_cm_update_rssi_snr_by_bssid(link_info);
978 hdd_cm_rec_connect_info(rsp);
979 hdd_debug("Invoking packetdump deregistration API");
980 wlan_deregister_txrx_packetdump(OL_TXRX_PDEV_ID);
981 }
982
983 static void
hdd_cm_connect_failure_post_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)984 hdd_cm_connect_failure_post_user_update(struct wlan_objmgr_vdev *vdev,
985 struct wlan_cm_connect_resp *rsp)
986 {
987 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
988 struct hdd_adapter *adapter;
989 struct wlan_hdd_link_info *link_info;
990 bool is_roam = rsp->is_reassoc;
991
992 if (!hdd_ctx) {
993 hdd_err("hdd_ctx is NULL");
994 return;
995 }
996
997 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
998 if (!link_info) {
999 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
1000 return;
1001 }
1002 if (!is_roam) {
1003 /* call only for connect */
1004 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
1005 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
1006 }
1007
1008 adapter = link_info->adapter;
1009 wlan_hdd_connectivity_fail_event(vdev, rsp);
1010 hdd_clear_roam_profile_ie(adapter);
1011 ucfg_cm_reset_key(hdd_ctx->pdev, link_info->vdev_id);
1012 hdd_wmm_dscp_initial_state(adapter);
1013
1014 /*
1015 * If connect failure is due to link switch, do not disable the
1016 * netdev queues as it will lead to data stall/NUD failure.
1017 */
1018 if (!(rsp->cm_id & CM_ID_LSWITCH_BIT)) {
1019 hdd_debug("Disabling queues");
1020 wlan_hdd_netif_queue_control(adapter,
1021 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
1022 WLAN_CONTROL_PATH);
1023 }
1024
1025 ucfg_dp_periodic_sta_stats_start(vdev);
1026 wlan_twt_concurrency_update(hdd_ctx);
1027 }
1028
hdd_cm_connect_failure(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,enum osif_cb_type type)1029 static void hdd_cm_connect_failure(struct wlan_objmgr_vdev *vdev,
1030 struct wlan_cm_connect_resp *rsp,
1031 enum osif_cb_type type)
1032 {
1033 switch (type) {
1034 case OSIF_PRE_USERSPACE_UPDATE:
1035 hdd_cm_connect_failure_pre_user_update(vdev, rsp);
1036 break;
1037 case OSIF_POST_USERSPACE_UPDATE:
1038 hdd_cm_connect_failure_post_user_update(vdev, rsp);
1039 break;
1040 default:
1041 hdd_cm_connect_failure_pre_user_update(vdev, rsp);
1042 hdd_cm_connect_failure_post_user_update(vdev, rsp);
1043 }
1044 }
1045
1046 /**
1047 * hdd_cm_update_prev_ap_ie() - Update the connected AP IEs
1048 * @hdd_sta_ctx: Station context.
1049 * @rsp: Connect response
1050 *
1051 * This API updates the connected ap beacon IEs to station context connection
1052 * info.
1053 *
1054 * Return: None
1055 */
hdd_cm_update_prev_ap_ie(struct hdd_station_ctx * hdd_sta_ctx,struct wlan_cm_connect_resp * rsp)1056 static void hdd_cm_update_prev_ap_ie(struct hdd_station_ctx *hdd_sta_ctx,
1057 struct wlan_cm_connect_resp *rsp)
1058 {
1059 struct element_info *bcn_probe_rsp = &rsp->connect_ies.bcn_probe_rsp;
1060 struct element_info *bcn_ie;
1061 uint32_t len;
1062
1063 bcn_ie = &hdd_sta_ctx->conn_info.prev_ap_bcn_ie;
1064 if (bcn_ie->ptr) {
1065 qdf_mem_free(bcn_ie->ptr);
1066 bcn_ie->ptr = NULL;
1067 bcn_ie->len = 0;
1068 }
1069
1070 if (bcn_probe_rsp->ptr &&
1071 bcn_probe_rsp->len > sizeof(struct wlan_frame_hdr)) {
1072 len = bcn_probe_rsp->len - sizeof(struct wlan_frame_hdr);
1073 bcn_ie->ptr = qdf_mem_malloc(len);
1074 if (!bcn_ie->ptr) {
1075 bcn_ie->len = 0;
1076 return;
1077 }
1078 qdf_mem_copy(bcn_ie->ptr, bcn_probe_rsp->ptr +
1079 sizeof(struct wlan_frame_hdr), len);
1080 bcn_ie->len = len;
1081 }
1082 }
1083
hdd_cm_save_bss_info(struct wlan_hdd_link_info * link_info,struct wlan_cm_connect_resp * rsp)1084 static void hdd_cm_save_bss_info(struct wlan_hdd_link_info *link_info,
1085 struct wlan_cm_connect_resp *rsp)
1086 {
1087 struct hdd_context *hdd_ctx;
1088 struct hdd_station_ctx *hdd_sta_ctx;
1089 QDF_STATUS status;
1090 struct hdd_adapter *adapter = link_info->adapter;
1091 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
1092 struct sDot11fAssocResponse *assoc_resp;
1093
1094 if (!mac_handle) {
1095 hdd_err("mac handle is null");
1096 return;
1097 }
1098
1099 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
1100 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1101
1102 assoc_resp = qdf_mem_malloc(sizeof(struct sDot11fAssocResponse));
1103 if (!assoc_resp)
1104 return;
1105
1106 qdf_mem_zero(&hdd_sta_ctx->conn_info.hs20vendor_ie,
1107 sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie));
1108 if (rsp->connect_ies.bcn_probe_rsp.ptr)
1109 sme_get_hs20vendor_ie(mac_handle,
1110 rsp->connect_ies.bcn_probe_rsp.ptr,
1111 rsp->connect_ies.bcn_probe_rsp.len,
1112 &hdd_sta_ctx->conn_info.hs20vendor_ie);
1113
1114 status = sme_unpack_assoc_rsp(mac_handle, rsp, assoc_resp);
1115 if (QDF_IS_STATUS_ERROR(status)) {
1116 hdd_err("could not parse assoc response");
1117 qdf_mem_free(assoc_resp);
1118 return;
1119 }
1120
1121 if (assoc_resp->VHTCaps.present) {
1122 hdd_sta_ctx->conn_info.conn_flag.vht_present = true;
1123 hdd_copy_vht_caps(&hdd_sta_ctx->conn_info.vht_caps,
1124 &assoc_resp->VHTCaps);
1125 } else {
1126 hdd_sta_ctx->conn_info.conn_flag.vht_present = false;
1127 }
1128 if (assoc_resp->HTCaps.present) {
1129 hdd_sta_ctx->conn_info.conn_flag.ht_present = true;
1130 hdd_copy_ht_caps(&hdd_sta_ctx->conn_info.ht_caps,
1131 &assoc_resp->HTCaps);
1132 } else {
1133 hdd_sta_ctx->conn_info.conn_flag.ht_present = false;
1134 }
1135 if (rsp->is_reassoc)
1136 hdd_sta_ctx->conn_info.roam_count++;
1137
1138 if (assoc_resp->HTInfo.present) {
1139 hdd_sta_ctx->conn_info.conn_flag.ht_op_present = true;
1140 hdd_copy_ht_operation(hdd_sta_ctx, &assoc_resp->HTInfo);
1141 } else {
1142 hdd_sta_ctx->conn_info.conn_flag.ht_op_present = false;
1143 }
1144 if (assoc_resp->VHTOperation.present) {
1145 hdd_sta_ctx->conn_info.conn_flag.vht_op_present = true;
1146 hdd_copy_vht_operation(hdd_sta_ctx, &assoc_resp->VHTOperation);
1147 } else {
1148 hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false;
1149 }
1150
1151 if (assoc_resp->he_cap.present)
1152 hdd_sta_ctx->conn_info.conn_flag.he_present = true;
1153 else
1154 hdd_sta_ctx->conn_info.conn_flag.he_present = false;
1155
1156 if (assoc_resp->eht_cap.present)
1157 hdd_sta_ctx->conn_info.conn_flag.eht_present = true;
1158 else
1159 hdd_sta_ctx->conn_info.conn_flag.eht_present = false;
1160
1161 if (assoc_resp->eht_op.present)
1162 hdd_sta_ctx->conn_info.conn_flag.eht_op_present = true;
1163 else
1164 hdd_sta_ctx->conn_info.conn_flag.eht_op_present = false;
1165
1166 /*
1167 * Cache connection info only in case of station
1168 */
1169 if (adapter->device_mode == QDF_STA_MODE) {
1170 /* Cleanup already existing he info */
1171 hdd_cleanup_conn_info(link_info);
1172
1173 hdd_copy_eht_operation(hdd_sta_ctx, &assoc_resp->eht_op);
1174 /* Cache last connection info */
1175 qdf_mem_copy(&hdd_sta_ctx->cache_conn_info,
1176 &hdd_sta_ctx->conn_info,
1177 sizeof(hdd_sta_ctx->cache_conn_info));
1178
1179 hdd_copy_he_operation(hdd_sta_ctx, &assoc_resp->he_op);
1180 hdd_cm_update_prev_ap_ie(hdd_sta_ctx, rsp);
1181 }
1182
1183 qdf_mem_free(assoc_resp);
1184 }
1185
1186 #ifdef FEATURE_WLAN_ESE
hdd_is_ese_assoc(enum csr_akm_type auth_type,tDot11fBeaconIEs * bcn_ie,struct mac_context * mac_ctx)1187 static bool hdd_is_ese_assoc(enum csr_akm_type auth_type,
1188 tDot11fBeaconIEs *bcn_ie,
1189 struct mac_context *mac_ctx)
1190 {
1191 if ((csr_is_auth_type_ese(auth_type) ||
1192 (bcn_ie->ESEVersion.present &&
1193 auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM)) &&
1194 mac_ctx->mlme_cfg->lfr.ese_enabled) {
1195 return true;
1196 }
1197
1198 return false;
1199 }
1200 #else
hdd_is_ese_assoc(enum csr_akm_type auth_type,tDot11fBeaconIEs * bcn_ie,struct mac_context * mac_ctx)1201 static bool hdd_is_ese_assoc(enum csr_akm_type auth_type,
1202 tDot11fBeaconIEs *bcn_ie,
1203 struct mac_context *mac_ctx)
1204 {
1205 return false;
1206 }
1207 #endif
1208
1209 static const uint8_t acm_mask_bit[WLAN_MAX_AC] = {
1210 0x4, /* SME_AC_BK */
1211 0x8, /* SME_AC_BE */
1212 0x2, /* SME_AC_VI */
1213 0x1 /* SME_AC_VO */
1214 };
1215
hdd_wmm_cm_connect(struct wlan_objmgr_vdev * vdev,struct hdd_adapter * adapter,tDot11fBeaconIEs * bcn_ie,enum csr_akm_type auth_type)1216 static void hdd_wmm_cm_connect(struct wlan_objmgr_vdev *vdev,
1217 struct hdd_adapter *adapter,
1218 tDot11fBeaconIEs *bcn_ie,
1219 enum csr_akm_type auth_type)
1220 {
1221 int ac;
1222 bool qap;
1223 bool qos_connection;
1224 uint8_t acm_mask = 0;
1225 struct vdev_mlme_obj *vdev_mlme;
1226 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
1227 struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
1228
1229 if (!mac_handle) {
1230 hdd_err("mac handle is null");
1231 return;
1232 }
1233
1234 vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
1235 if (!vdev_mlme) {
1236 hdd_err("vdev component object is NULL");
1237 return;
1238 }
1239 if (CSR_IS_QOS_BSS(bcn_ie) || bcn_ie->HTCaps.present)
1240 /* Some HT AP's dont send WMM IE so in that case we
1241 * assume all HT Ap's are Qos Enabled AP's
1242 */
1243 qap = true;
1244 else
1245 qap = false;
1246
1247 qos_connection = vdev_mlme->ext_vdev_ptr->connect_info.qos_enabled;
1248
1249 acm_mask = sme_qos_get_acm_mask(mac_ctx, NULL, bcn_ie);
1250
1251 hdd_debug("qap is %d, qos_connection is %d, acm_mask is 0x%x",
1252 qap, qos_connection, acm_mask);
1253
1254 adapter->hdd_wmm_status.qap = qap;
1255 adapter->hdd_wmm_status.qos_connection = qos_connection;
1256
1257 if (acm_mask)
1258 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG,
1259 (uint8_t *)acm_mask_bit, WLAN_MAX_AC);
1260
1261 for (ac = 0; ac < WLAN_MAX_AC; ac++) {
1262 if (qap && qos_connection && (acm_mask & acm_mask_bit[ac])) {
1263
1264 /* admission is required */
1265 adapter->hdd_wmm_status.ac_status[ac].
1266 is_access_required = true;
1267 adapter->hdd_wmm_status.ac_status[ac].
1268 is_access_allowed = false;
1269 adapter->hdd_wmm_status.ac_status[ac].
1270 was_access_granted = false;
1271 /* after reassoc if we have valid tspec, allow access */
1272 if (adapter->hdd_wmm_status.ac_status[ac].
1273 is_tspec_valid &&
1274 (adapter->hdd_wmm_status.ac_status[ac].
1275 tspec.ts_info.direction !=
1276 SME_QOS_WMM_TS_DIR_DOWNLINK)) {
1277 adapter->hdd_wmm_status.ac_status[ac].
1278 is_access_allowed = true;
1279 }
1280 if (!sme_neighbor_roam_is11r_assoc(
1281 mac_handle,
1282 adapter->deflink->vdev_id) &&
1283 !hdd_is_ese_assoc(auth_type, bcn_ie, mac_ctx)) {
1284 adapter->hdd_wmm_status.ac_status[ac].
1285 is_tspec_valid = false;
1286 adapter->hdd_wmm_status.ac_status[ac].
1287 is_access_allowed = false;
1288 }
1289 } else {
1290 /* admission is not required so access is allowed */
1291 adapter->hdd_wmm_status.ac_status[ac].
1292 is_access_required = false;
1293 adapter->hdd_wmm_status.ac_status[ac].
1294 is_access_allowed = true;
1295 }
1296 }
1297 }
1298
hdd_cm_save_connect_info(struct wlan_hdd_link_info * link_info,struct wlan_cm_connect_resp * rsp)1299 static void hdd_cm_save_connect_info(struct wlan_hdd_link_info *link_info,
1300 struct wlan_cm_connect_resp *rsp)
1301 {
1302 struct hdd_station_ctx *sta_ctx;
1303 struct wlan_crypto_params *crypto_params;
1304 struct wlan_channel *des_chan;
1305 struct wlan_objmgr_vdev *vdev;
1306 uint8_t *ie_field;
1307 uint32_t ie_len, status;
1308 tDot11fBeaconIEs *bcn_ie;
1309 struct s_ext_cap *p_ext_cap = NULL;
1310 struct hdd_adapter *adapter = link_info->adapter;
1311 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
1312 uint32_t phymode;
1313
1314 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1315 bcn_ie = qdf_mem_malloc(sizeof(*bcn_ie));
1316 if (!bcn_ie)
1317 return;
1318
1319 qdf_copy_macaddr(&sta_ctx->conn_info.bssid, &rsp->bssid);
1320 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_DP_ID);
1321 if (vdev) {
1322 ucfg_dp_conn_info_set_bssid(vdev, &rsp->bssid);
1323 hdd_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID);
1324 }
1325
1326 phymode = wlan_reg_get_max_phymode(adapter->hdd_ctx->pdev,
1327 REG_PHYMODE_MAX,
1328 rsp->freq);
1329
1330 sta_ctx->reg_phymode = csr_convert_from_reg_phy_mode(phymode);
1331
1332 sta_ctx->conn_info.assoc_status_code = rsp->status_code;
1333
1334 crypto_params =
1335 wlan_crypto_vdev_get_crypto_params(link_info->vdev);
1336
1337 if (crypto_params) {
1338 sme_fill_enc_type(&sta_ctx->conn_info.uc_encrypt_type,
1339 crypto_params->ucastcipherset);
1340
1341 sme_fill_auth_type(&sta_ctx->conn_info.auth_type,
1342 crypto_params->authmodeset,
1343 crypto_params->key_mgmt,
1344 crypto_params->ucastcipherset);
1345 sta_ctx->conn_info.last_auth_type =
1346 sta_ctx->conn_info.auth_type;
1347 }
1348 des_chan = wlan_vdev_mlme_get_des_chan(link_info->vdev);
1349
1350 sta_ctx->conn_info.chan_freq = rsp->freq;
1351
1352 /* Save the ssid for the connection */
1353 qdf_mem_copy(&sta_ctx->conn_info.ssid.SSID.ssId,
1354 &rsp->ssid.ssid,
1355 rsp->ssid.length);
1356 qdf_mem_copy(&sta_ctx->conn_info.last_ssid.SSID.ssId,
1357 &rsp->ssid.ssid,
1358 rsp->ssid.length);
1359 sta_ctx->conn_info.ssid.SSID.length = rsp->ssid.length;
1360 sta_ctx->conn_info.last_ssid.SSID.length = rsp->ssid.length;
1361
1362 sta_ctx->conn_info.dot11mode =
1363 sme_phy_mode_to_dot11mode(des_chan->ch_phymode);
1364
1365 sta_ctx->conn_info.ch_width = des_chan->ch_width;
1366 if (!rsp->connect_ies.bcn_probe_rsp.ptr ||
1367 (rsp->connect_ies.bcn_probe_rsp.len <
1368 (sizeof(struct wlan_frame_hdr) +
1369 offsetof(struct wlan_bcn_frame, ie)))) {
1370 hdd_err("beacon len is invalid %d",
1371 rsp->connect_ies.bcn_probe_rsp.len);
1372 qdf_mem_free(bcn_ie);
1373 return;
1374 }
1375
1376 ie_len = (rsp->connect_ies.bcn_probe_rsp.len -
1377 sizeof(struct wlan_frame_hdr) -
1378 offsetof(struct wlan_bcn_frame, ie));
1379 ie_field = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr +
1380 sizeof(struct wlan_frame_hdr) +
1381 offsetof(struct wlan_bcn_frame, ie));
1382
1383 status = dot11f_unpack_beacon_i_es(MAC_CONTEXT(mac_handle), ie_field,
1384 ie_len, bcn_ie, false);
1385
1386 if (DOT11F_FAILED(status)) {
1387 hdd_err("Failed to parse beacon ie");
1388 qdf_mem_free(bcn_ie);
1389 return;
1390 }
1391 if (bcn_ie->ExtCap.present) {
1392 p_ext_cap = (struct s_ext_cap *)bcn_ie->ExtCap.bytes;
1393 sta_ctx->conn_info.proxy_arp_service =
1394 p_ext_cap->proxy_arp_service;
1395
1396 }
1397
1398 vdev = hdd_objmgr_get_vdev_by_user(link_info, WLAN_OSIF_CM_ID);
1399 if (vdev) {
1400 sta_ctx->conn_info.nss = wlan_vdev_mlme_get_nss(vdev);
1401 ucfg_wlan_vdev_mgr_get_param(vdev, WLAN_MLME_CFG_RATE_FLAGS,
1402 &sta_ctx->conn_info.rate_flags);
1403 hdd_wmm_cm_connect(vdev, adapter, bcn_ie,
1404 sta_ctx->conn_info.auth_type);
1405
1406 if (p_ext_cap)
1407 ucfg_dp_conn_info_set_arp_service(vdev,
1408 p_ext_cap->proxy_arp_service);
1409
1410 hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_CM_ID);
1411 }
1412 qdf_mem_free(bcn_ie);
1413
1414 hdd_cm_save_bss_info(link_info, rsp);
1415 }
1416
1417 #ifdef WLAN_FEATURE_FILS_SK
hdd_cm_is_fils_connection(struct wlan_cm_connect_resp * rsp)1418 static bool hdd_cm_is_fils_connection(struct wlan_cm_connect_resp *rsp)
1419 {
1420 return rsp->is_fils_connection;
1421 }
1422 #else
1423 static inline
hdd_cm_is_fils_connection(struct wlan_cm_connect_resp * rsp)1424 bool hdd_cm_is_fils_connection(struct wlan_cm_connect_resp *rsp)
1425 {
1426 return false;
1427 }
1428 #endif
1429
1430 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
hdd_cm_is_roam_auth_required(struct hdd_station_ctx * sta_ctx,struct wlan_cm_connect_resp * rsp)1431 static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx,
1432 struct wlan_cm_connect_resp *rsp)
1433 {
1434 if (!rsp->roaming_info)
1435 return false;
1436
1437 if (rsp->roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED)
1438 return false;
1439
1440 return true;
1441 }
1442 #else
hdd_cm_is_roam_auth_required(struct hdd_station_ctx * sta_ctx,struct wlan_cm_connect_resp * rsp)1443 static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx,
1444 struct wlan_cm_connect_resp *rsp)
1445 {
1446 return true;
1447 }
1448 #endif
1449
1450 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
1451 #ifndef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
hdd_get_assoc_link_adapter(struct hdd_adapter * ml_adapter)1452 struct hdd_adapter *hdd_get_assoc_link_adapter(struct hdd_adapter *ml_adapter)
1453 {
1454 int i;
1455 bool eht_capab;
1456 struct hdd_adapter *link_adapter;
1457 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ml_adapter);
1458
1459 ucfg_psoc_mlme_get_11be_capab(hdd_ctx->psoc, &eht_capab);
1460 if (!eht_capab || hdd_adapter_is_sl_ml_adapter(ml_adapter))
1461 return ml_adapter;
1462
1463 for (i = 0; i < WLAN_MAX_MLD; i++) {
1464 link_adapter = ml_adapter->mlo_adapter_info.link_adapter[i];
1465 if (link_adapter) {
1466 if (hdd_adapter_is_associated_with_ml_adapter(
1467 link_adapter))
1468 return link_adapter;
1469 }
1470 }
1471
1472 return NULL;
1473 }
1474 #endif
1475
1476 #ifdef WLAN_HDD_MULTI_VDEV_SINGLE_NDEV
hdd_set_immediate_power_save(struct hdd_adapter * adapter,bool is_immediate_powersave)1477 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter,
1478 bool is_immediate_powersave)
1479 {
1480 struct hdd_station_ctx *sta_ctx;
1481 struct wlan_hdd_link_info *link_info;
1482
1483 hdd_adapter_for_each_active_link_info(adapter, link_info) {
1484 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1485 sta_ctx->ap_supports_immediate_power_save =
1486 is_immediate_powersave;
1487 }
1488 }
1489 #else
hdd_set_immediate_power_save(struct hdd_adapter * adapter,bool is_immediate_powersave)1490 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter,
1491 bool is_immediate_powersave)
1492 {
1493 struct hdd_adapter *link_adapter;
1494 struct hdd_mlo_adapter_info *mlo_adapter_info;
1495 struct hdd_station_ctx *sta_ctx;
1496 int i;
1497
1498 if (!hdd_adapter_is_ml_adapter(adapter))
1499 goto update_non_ml;
1500
1501 mlo_adapter_info = &adapter->mlo_adapter_info;
1502 for (i = 0; i < WLAN_MAX_MLD; i++) {
1503 link_adapter = mlo_adapter_info->link_adapter[i];
1504 if (!link_adapter)
1505 continue;
1506
1507 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_adapter->deflink);
1508 sta_ctx->ap_supports_immediate_power_save =
1509 is_immediate_powersave;
1510 }
1511
1512 update_non_ml:
1513 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
1514 sta_ctx->ap_supports_immediate_power_save = is_immediate_powersave;
1515 }
1516 #endif
1517 #else
hdd_set_immediate_power_save(struct hdd_adapter * adapter,bool is_immediate_powersave)1518 static void hdd_set_immediate_power_save(struct hdd_adapter *adapter,
1519 bool is_immediate_powersave)
1520 {
1521 struct hdd_station_ctx *sta_ctx;
1522
1523 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter->deflink);
1524 sta_ctx->ap_supports_immediate_power_save = is_immediate_powersave;
1525 }
1526 #endif
1527
1528 #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_HDD_MULTI_VDEV_SINGLE_NDEV)
1529 static QDF_STATUS
hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter * adapter,struct wlan_objmgr_vdev * vdev)1530 hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter *adapter,
1531 struct wlan_objmgr_vdev *vdev)
1532 {
1533 struct wlan_objmgr_psoc *psoc;
1534 struct wlan_hdd_link_info *link_info;
1535 struct hdd_station_ctx *sta_ctx;
1536 uint8_t link_id = wlan_vdev_get_link_id(vdev);
1537 uint8_t ch_width;
1538 enum phy_ch_width connection_ch_width = CH_WIDTH_INVALID;
1539
1540 psoc = wlan_vdev_get_psoc(vdev);
1541 if (!psoc) {
1542 hdd_err("Failed to get PSOC Object");
1543 return QDF_STATUS_E_INVAL;
1544 }
1545
1546 link_info = hdd_get_link_info_by_ieee_link_id(adapter, link_id);
1547 if (!link_info) {
1548 hdd_err("Link info not found by linkid:%u", link_id);
1549 return QDF_STATUS_E_INVAL;
1550 }
1551 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1552 ch_width = sta_ctx->user_cfg_chn_width;
1553
1554 wlan_mlme_get_sta_ch_width(vdev, &connection_ch_width);
1555
1556 if (ch_width == CH_WIDTH_INVALID) {
1557 hdd_debug("no cached bandwidth for the link %u", link_id);
1558 return QDF_STATUS_SUCCESS;
1559 }
1560
1561 if (ch_width == connection_ch_width) {
1562 hdd_debug("user config max bd same as connection ch bw:%u",
1563 ch_width);
1564 return QDF_STATUS_SUCCESS;
1565 }
1566
1567 hdd_debug("send vdev id:%u, chwidth:%u", link_info->vdev_id,
1568 ch_width);
1569
1570 wlan_mlme_send_ch_width_update_with_notify(psoc, vdev,
1571 link_info->vdev_id,
1572 ch_width);
1573 return QDF_STATUS_SUCCESS;
1574 }
1575 #else
1576 static QDF_STATUS
hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter * adapter,struct wlan_objmgr_vdev * vdev)1577 hdd_cm_mlme_send_standby_link_chn_width(struct hdd_adapter *adapter,
1578 struct wlan_objmgr_vdev *vdev)
1579 {
1580 return QDF_STATUS_SUCCESS;
1581 }
1582 #endif
1583
1584 static void
hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1585 hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev *vdev,
1586 struct wlan_cm_connect_resp *rsp)
1587 {
1588 struct hdd_context *hdd_ctx;
1589 struct hdd_adapter *adapter;
1590 struct hdd_station_ctx *sta_ctx;
1591 struct vdev_mlme_obj *vdev_mlme;
1592 unsigned long rc;
1593 uint32_t ie_len;
1594 uint8_t *ie_field;
1595 mac_handle_t mac_handle;
1596 bool is_auth_required = true;
1597 bool is_roam_offload = false;
1598 bool is_roam = rsp->is_reassoc;
1599 ol_txrx_soc_handle soc = cds_get_context(QDF_MODULE_ID_SOC);
1600 uint8_t uapsd_mask = 0;
1601 uint32_t time_buffer_size;
1602 struct hdd_adapter *assoc_link_adapter;
1603 bool is_immediate_power_save;
1604 struct wlan_hdd_link_info *link_info;
1605 QDF_STATUS status = QDF_STATUS_E_INVAL;
1606 bool alt_pipe;
1607
1608 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1609 if (!hdd_ctx) {
1610 hdd_err("hdd_ctx is NULL");
1611 return;
1612 }
1613
1614 link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev));
1615 if (!link_info) {
1616 hdd_err("Invalid vdev");
1617 return;
1618 }
1619
1620 adapter = link_info->adapter;
1621 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(link_info);
1622 mac_handle = hdd_adapter_get_mac_handle(adapter);
1623
1624 wlan_hdd_ft_set_key_delay(vdev);
1625 hdd_cm_update_rssi_snr_by_bssid(link_info);
1626 hdd_cm_save_connect_status(link_info, rsp->status_code);
1627
1628 hdd_init_scan_reject_params(hdd_ctx);
1629 time_buffer_size = sizeof(sta_ctx->conn_info.connect_time);
1630 qdf_mem_zero(sta_ctx->conn_info.connect_time, time_buffer_size);
1631 qdf_get_time_of_the_day_in_hr_min_sec_usec(sta_ctx->conn_info.connect_time,
1632 time_buffer_size);
1633 hdd_start_tsf_sync(adapter);
1634 hdd_cm_rec_connect_info(rsp);
1635
1636 hdd_cm_save_connect_info(link_info, rsp);
1637 if (adapter->device_mode == QDF_STA_MODE &&
1638 hdd_adapter_is_ml_adapter(adapter)) {
1639 /* Save connection info in assoc link adapter as well */
1640 assoc_link_adapter = hdd_get_assoc_link_adapter(adapter);
1641 if (assoc_link_adapter)
1642 hdd_cm_save_connect_info(assoc_link_adapter->deflink,
1643 rsp);
1644 }
1645 if (hdd_add_beacon_filter(adapter) != 0)
1646 hdd_err("add beacon filter failed");
1647
1648 adapter->wapi_info.is_wapi_sta = hdd_cm_is_wapi_sta(
1649 sta_ctx->conn_info.auth_type);
1650 if (adapter->device_mode == QDF_STA_MODE &&
1651 rsp->connect_ies.bcn_probe_rsp.ptr &&
1652 (rsp->connect_ies.bcn_probe_rsp.len >
1653 (sizeof(struct wlan_frame_hdr) +
1654 offsetof(struct wlan_bcn_frame, ie)))) {
1655 ie_len = (rsp->connect_ies.bcn_probe_rsp.len -
1656 sizeof(struct wlan_frame_hdr) -
1657 offsetof(struct wlan_bcn_frame, ie));
1658
1659 ie_field = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr +
1660 sizeof(struct wlan_frame_hdr) +
1661 offsetof(struct wlan_bcn_frame, ie));
1662 is_immediate_power_save =
1663 wlan_hdd_is_ap_supports_immediate_power_save(
1664 ie_field, ie_len);
1665 hdd_set_immediate_power_save(adapter, is_immediate_power_save);
1666 hdd_debug("ap_supports_immediate_power_save flag [%d]",
1667 sta_ctx->ap_supports_immediate_power_save);
1668 }
1669 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, true);
1670
1671 hdd_cm_handle_assoc_event(vdev, rsp->bssid.bytes);
1672
1673 if (ucfg_cm_is_link_switch_connect_resp(rsp)) {
1674 if (hdd_cm_mlme_send_standby_link_chn_width(adapter, vdev))
1675 hdd_debug("send standby link chn width fail");
1676 }
1677
1678 /*
1679 * check update hdd_send_update_beacon_ies_event,
1680 * hdd_send_ft_assoc_response,
1681 */
1682
1683 wlan_hdd_set_tx_flow_info();
1684 hdd_place_marker(adapter, "ASSOCIATION COMPLETE", NULL);
1685
1686 if (policy_mgr_is_mcc_in_24G(hdd_ctx->psoc)) {
1687 if (hdd_ctx->miracast_value)
1688 wlan_hdd_set_mas(adapter, hdd_ctx->miracast_value);
1689 }
1690
1691 if (!is_roam) {
1692 /* Initialize the Linkup event completion variable */
1693 INIT_COMPLETION(adapter->linkup_event_var);
1694
1695 /*
1696 * Enable Linkup Event Servicing which allows the net
1697 * device notifier to set the linkup event variable.
1698 */
1699 adapter->is_link_up_service_needed = true;
1700
1701 /* Switch on the Carrier to activate the device */
1702 wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_CARRIER_ON,
1703 WLAN_CONTROL_PATH);
1704
1705 /*
1706 * Wait for the Link to up to ensure all the queues
1707 * are set properly by the kernel.
1708 */
1709 rc = wait_for_completion_timeout(
1710 &adapter->linkup_event_var,
1711 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT));
1712 /*
1713 * Disable Linkup Event Servicing - no more service
1714 * required from the net device notifier call.
1715 */
1716 adapter->is_link_up_service_needed = false;
1717 }
1718
1719 vdev_mlme = wlan_objmgr_vdev_get_comp_private_obj(vdev,
1720 WLAN_UMAC_COMP_MLME);
1721 if (vdev_mlme)
1722 uapsd_mask =
1723 vdev_mlme->ext_vdev_ptr->connect_info.uapsd_per_ac_bitmask;
1724
1725 cdp_hl_fc_set_td_limit(soc, link_info->vdev_id,
1726 sta_ctx->conn_info.chan_freq);
1727 hdd_wmm_assoc(adapter, false, uapsd_mask);
1728
1729 if (!rsp->is_wps_connection &&
1730 !rsp->is_osen_connection &&
1731 (sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_NONE ||
1732 sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_OPEN_SYSTEM ||
1733 sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_SHARED_KEY ||
1734 hdd_cm_is_fils_connection(rsp)))
1735 is_auth_required = false;
1736
1737 if (is_roam)
1738 /* If roaming is set check if FW roaming/LFR3 */
1739 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &is_roam_offload);
1740
1741 if (is_roam_offload || !is_roam) {
1742 /* For FW_ROAM/LFR3 OR connect */
1743 /* for LFR 3 get authenticated info from resp */
1744 if (is_roam) {
1745 is_auth_required =
1746 hdd_cm_is_roam_auth_required(sta_ctx, rsp);
1747 if (is_auth_required)
1748 wlan_acquire_peer_key_wakelock(hdd_ctx->pdev,
1749 rsp->bssid.bytes);
1750 }
1751 hdd_debug("is_roam_offload %d, is_roam %d, is_auth_required %d",
1752 is_roam_offload, is_roam, is_auth_required);
1753 hdd_roam_register_sta(link_info, &rsp->bssid, is_auth_required);
1754 } else {
1755 /* for host roam/LFR2 */
1756 hdd_cm_set_peer_authenticate(link_info,
1757 &rsp->bssid, is_auth_required);
1758 }
1759
1760 hdd_debug("Enabling queues");
1761 hdd_cm_netif_queue_enable(adapter);
1762
1763 /* send peer status indication to oem app */
1764 if (vdev_mlme) {
1765 hdd_send_peer_status_ind_to_app(
1766 &rsp->bssid,
1767 ePeerConnected,
1768 vdev_mlme->ext_vdev_ptr->connect_info.timing_meas_cap,
1769 link_info->vdev_id,
1770 &vdev_mlme->ext_vdev_ptr->connect_info.chan_info,
1771 adapter->device_mode);
1772 }
1773
1774 if (ucfg_ipa_is_enabled() && !is_auth_required) {
1775 status = hdd_ipa_get_tx_pipe(hdd_ctx, link_info, &alt_pipe);
1776 if (!QDF_IS_STATUS_SUCCESS(status)) {
1777 hdd_debug("Failed to get alternate pipe for vdev %d",
1778 link_info->vdev_id);
1779 alt_pipe = false;
1780 }
1781
1782 ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
1783 adapter->device_mode,
1784 link_info->vdev_id,
1785 WLAN_IPA_STA_CONNECT,
1786 rsp->bssid.bytes,
1787 alt_pipe);
1788 }
1789
1790 if (adapter->device_mode == QDF_STA_MODE)
1791 cdp_reset_rx_hw_ext_stats(soc);
1792
1793 wlan_hdd_auto_shutdown_enable(hdd_ctx, false);
1794
1795 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1796 link_info->vdev_id, QDF_TRACE_DEFAULT_PDEV_ID,
1797 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
1798
1799 if (is_roam)
1800 ucfg_dp_nud_indicate_roam(vdev);
1801 /* hdd_objmgr_set_peer_mlme_auth_state */
1802
1803 if (adapter->keep_alive_interval)
1804 hdd_vdev_send_sta_keep_alive_interval(link_info, hdd_ctx,
1805 adapter->keep_alive_interval);
1806 }
1807
1808 static void
hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)1809 hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev *vdev,
1810 struct wlan_cm_connect_resp *rsp)
1811 {
1812 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1813 struct hdd_adapter *adapter;
1814 struct wlan_hdd_link_info *link_info;
1815 bool is_roam = rsp->is_reassoc;
1816
1817 if (!hdd_ctx) {
1818 hdd_err("hdd_ctx is NULL");
1819 return;
1820 }
1821
1822 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
1823 if (!link_info) {
1824 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
1825 return;
1826 }
1827
1828 if (!is_roam) {
1829 /* call only for connect */
1830 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
1831 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
1832 }
1833
1834 adapter = link_info->adapter;
1835 hdd_cm_clear_pmf_stats(adapter);
1836
1837 if (adapter->device_mode == QDF_STA_MODE) {
1838 /* Inform FTM TIME SYNC about the connection with AP */
1839 hdd_ftm_time_sync_sta_state_notify(adapter,
1840 FTM_TIME_SYNC_STA_CONNECTED);
1841 ucfg_mlme_init_twt_context(hdd_ctx->psoc,
1842 &rsp->bssid,
1843 TWT_ALL_SESSIONS_DIALOG_ID);
1844 ucfg_twt_init_context(hdd_ctx->psoc,
1845 &rsp->bssid,
1846 TWT_ALL_SESSIONS_DIALOG_ID);
1847 }
1848 ucfg_dp_periodic_sta_stats_start(vdev);
1849 wlan_twt_concurrency_update(hdd_ctx);
1850
1851 if (wlan_vdev_mlme_is_mlo_link_switch_in_progress(vdev))
1852 hdd_send_ps_config_to_fw(adapter);
1853 }
1854
hdd_cm_connect_success(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,enum osif_cb_type type)1855 static void hdd_cm_connect_success(struct wlan_objmgr_vdev *vdev,
1856 struct wlan_cm_connect_resp *rsp,
1857 enum osif_cb_type type)
1858 {
1859 switch (type) {
1860 case OSIF_PRE_USERSPACE_UPDATE:
1861 hdd_cm_connect_success_pre_user_update(vdev, rsp);
1862 break;
1863 case OSIF_POST_USERSPACE_UPDATE:
1864 hdd_cm_connect_success_post_user_update(vdev, rsp);
1865 break;
1866 default:
1867 hdd_cm_connect_success_pre_user_update(vdev, rsp);
1868 hdd_cm_connect_success_post_user_update(vdev, rsp);
1869 }
1870 }
1871
1872 #if defined(WLAN_FEATURE_11BE_MLO) && defined(CFG80211_11BE_BASIC)
hdd_cm_connect_active_notify(uint8_t vdev_id)1873 void hdd_cm_connect_active_notify(uint8_t vdev_id)
1874 {
1875 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1876 struct wlan_hdd_link_info *link_info;
1877
1878 if (!hdd_ctx) {
1879 hdd_err("HDD context is NULL");
1880 return;
1881 }
1882
1883 link_info = hdd_get_link_info_by_vdev(hdd_ctx, vdev_id);
1884 if (!link_info) {
1885 hdd_err("Link info not found for vdev %d", vdev_id);
1886 return;
1887 }
1888
1889 if (hdd_adapter_restore_link_vdev_map(link_info->adapter, true))
1890 hdd_adapter_update_mlo_mgr_mac_addr(link_info->adapter);
1891 }
1892 #endif
1893
hdd_cm_connect_complete(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,enum osif_cb_type type)1894 QDF_STATUS hdd_cm_connect_complete(struct wlan_objmgr_vdev *vdev,
1895 struct wlan_cm_connect_resp *rsp,
1896 enum osif_cb_type type)
1897 {
1898 if (QDF_IS_STATUS_ERROR(rsp->connect_status))
1899 hdd_cm_connect_failure(vdev, rsp, type);
1900 else
1901 hdd_cm_connect_success(vdev, rsp, type);
1902
1903 return QDF_STATUS_SUCCESS;
1904 }
1905
hdd_cm_send_vdev_keys(struct wlan_objmgr_vdev * vdev,u8 key_index,bool pairwise,enum wlan_crypto_cipher_type cipher_type)1906 QDF_STATUS hdd_cm_send_vdev_keys(struct wlan_objmgr_vdev *vdev,
1907 u8 key_index, bool pairwise,
1908 enum wlan_crypto_cipher_type cipher_type)
1909 {
1910 return wlan_hdd_send_key_vdev(vdev, key_index, pairwise, cipher_type);
1911 }
1912
1913 #ifdef WLAN_VENDOR_HANDOFF_CONTROL
1914 #define WLAN_WAIT_TIME_HANDOFF_PARAMS 1000
hdd_cm_get_handoff_param(struct wlan_objmgr_psoc * psoc,uint8_t vdev_id,enum vendor_control_roam_param param_id)1915 QDF_STATUS hdd_cm_get_handoff_param(struct wlan_objmgr_psoc *psoc,
1916 uint8_t vdev_id,
1917 enum vendor_control_roam_param param_id)
1918 {
1919 QDF_STATUS status;
1920 int retval;
1921 void *vendor_handoff_context;
1922 struct osif_request *request;
1923 static const struct osif_request_params params = {
1924 .priv_size = 0,
1925 .timeout_ms = WLAN_WAIT_TIME_HANDOFF_PARAMS,
1926 };
1927
1928 request = osif_request_alloc(¶ms);
1929 if (!request) {
1930 hdd_err("Request allocation failure");
1931 status = QDF_STATUS_E_NOMEM;
1932 goto error;
1933 }
1934
1935 vendor_handoff_context = osif_request_cookie(request);
1936
1937 hdd_debug("sending vendor handoff param request for :0x%x", param_id);
1938 status = ucfg_cm_roam_send_vendor_handoff_param_req(psoc, vdev_id,
1939 param_id,
1940 vendor_handoff_context);
1941 if (QDF_IS_STATUS_ERROR(status)) {
1942 hdd_err("Unable to get vendor handoff param");
1943 goto error;
1944 }
1945
1946 retval = osif_request_wait_for_response(request);
1947 if (retval) {
1948 hdd_err("Target response timed out");
1949 status = qdf_status_from_os_return(retval);
1950 }
1951 error:
1952 if (request)
1953 osif_request_put(request);
1954
1955 return status;
1956 }
1957
1958 QDF_STATUS
hdd_cm_get_vendor_handoff_params(struct wlan_objmgr_psoc * psoc,void * vendor_handoff_context)1959 hdd_cm_get_vendor_handoff_params(struct wlan_objmgr_psoc *psoc,
1960 void *vendor_handoff_context)
1961 {
1962 struct osif_request *request;
1963
1964 hdd_debug("Received vendor handoff event from FW");
1965
1966 request = osif_request_get(vendor_handoff_context);
1967 if (!request) {
1968 hdd_err("Invalid request");
1969 return QDF_STATUS_E_FAILURE;
1970 }
1971
1972 osif_request_complete(request);
1973 osif_request_put(request);
1974
1975 hdd_exit();
1976
1977 return QDF_STATUS_SUCCESS;
1978 }
1979 #endif
1980
1981 QDF_STATUS
hdd_cm_get_scan_ie_params(struct wlan_objmgr_vdev * vdev,struct element_info * scan_ie,enum dot11_mode_filter * dot11mode_filter)1982 hdd_cm_get_scan_ie_params(struct wlan_objmgr_vdev *vdev,
1983 struct element_info *scan_ie,
1984 enum dot11_mode_filter *dot11mode_filter)
1985 {
1986 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
1987 struct wlan_hdd_link_info *link_info;
1988 struct hdd_scan_info *scan_info;
1989
1990 if (!hdd_ctx) {
1991 hdd_err("hdd_ctx is NULL");
1992 return QDF_STATUS_E_INVAL;
1993 }
1994
1995 link_info = hdd_get_link_info_by_vdev(hdd_ctx, wlan_vdev_get_id(vdev));
1996 if (!link_info) {
1997 hdd_err("adapter is NULL for vdev %d", wlan_vdev_get_id(vdev));
1998 return QDF_STATUS_E_INVAL;
1999 }
2000
2001 scan_info = &link_info->adapter->scan_info;
2002 if (link_info->adapter->device_mode == QDF_P2P_CLIENT_MODE) {
2003 scan_ie->ptr = &scan_info->scan_add_ie.addIEdata[0];
2004 scan_ie->len = scan_info->scan_add_ie.length;
2005 } else if (scan_info->default_scan_ies) {
2006 scan_ie->ptr = scan_info->default_scan_ies;
2007 scan_ie->len = scan_info->default_scan_ies_len;
2008 } else if (scan_info->scan_add_ie.length) {
2009 scan_ie->ptr = scan_info->scan_add_ie.addIEdata;
2010 scan_ie->len = scan_info->scan_add_ie.length;
2011 }
2012
2013 *dot11mode_filter = hdd_get_dot11mode_filter(hdd_ctx);
2014
2015 return QDF_STATUS_SUCCESS;
2016 }
2017
2018 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
2019 #ifdef WLAN_FEATURE_FILS_SK
hdd_cm_save_gtk(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2020 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
2021 struct wlan_cm_connect_resp *rsp)
2022 {
2023 uint8_t *kek;
2024 uint32_t kek_len;
2025 uint8_t *kck = NULL;
2026 uint8_t kck_len = 0;
2027 uint8_t replay_ctr_def[REPLAY_CTR_LEN] = {0};
2028 uint8_t *replay_ctr;
2029 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2030 struct wlan_hdd_link_info *link_info;
2031
2032 if (!hdd_ctx) {
2033 hdd_err("hdd_ctx is NULL");
2034 return QDF_STATUS_E_INVAL;
2035 }
2036
2037 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
2038 if (!link_info) {
2039 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
2040 return QDF_STATUS_E_INVAL;
2041 }
2042
2043 if (rsp->is_reassoc && rsp->roaming_info) {
2044 kek = rsp->roaming_info->kek;
2045 kek_len = rsp->roaming_info->kek_len;
2046 kck = rsp->roaming_info->kck;
2047 kck_len = rsp->roaming_info->kck_len;
2048 replay_ctr = rsp->roaming_info->replay_ctr;
2049 } else if (rsp->connect_ies.fils_ie) {
2050 kek = rsp->connect_ies.fils_ie->kek;
2051 kek_len = rsp->connect_ies.fils_ie->kek_len;
2052 replay_ctr = replay_ctr_def;
2053 } else {
2054 return QDF_STATUS_SUCCESS;
2055 }
2056 wlan_hdd_save_gtk_offload_params(link_info->adapter, kck, kck_len,
2057 kek, kek_len, replay_ctr, true);
2058
2059 return QDF_STATUS_SUCCESS;
2060 }
2061 #else
hdd_cm_save_gtk(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2062 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
2063 struct wlan_cm_connect_resp *rsp)
2064 {
2065 uint8_t *kek;
2066 uint32_t kek_len;
2067 uint8_t *kck = NULL;
2068 uint8_t kck_len = 0;
2069 uint8_t *replay_ctr;
2070 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2071 struct wlan_hdd_link_info *link_info;
2072
2073 if (!hdd_ctx) {
2074 hdd_err("hdd_ctx is NULL");
2075 return QDF_STATUS_E_INVAL;
2076 }
2077
2078 link_info = hdd_get_link_info_by_vdev(hdd_ctx, rsp->vdev_id);
2079 if (!link_info) {
2080 hdd_err("adapter is NULL for vdev %d", rsp->vdev_id);
2081 return QDF_STATUS_E_INVAL;
2082 }
2083
2084 if (rsp->is_reassoc && rsp->roaming_info) {
2085 kek = rsp->roaming_info.kek;
2086 kek_len = rsp->roaming_info.kek_len;
2087 kck = rsp->roaming_info.kck;
2088 kck_len = rsp->roaming_info.kck_len;
2089 replay_ctr = rsp->roaming_info.replay_ctr;
2090 } else {
2091 return QDF_STATUS_SUCCESS;
2092 }
2093 wlan_hdd_save_gtk_offload_params(link_info->adapter, kck, kck_len,
2094 kek, kek_len, replay_ctr, true);
2095
2096 return QDF_STATUS_SUCCESS;
2097 }
2098 #endif /* WLAN_FEATURE_FILS_SK*/
2099 #else
hdd_cm_save_gtk(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2100 QDF_STATUS hdd_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
2101 struct wlan_cm_connect_resp *rsp)
2102 {
2103 return QDF_STATUS_SUCCESS;
2104 }
2105 #endif
2106
2107 #ifdef WLAN_FEATURE_FILS_SK
hdd_update_hlp_info(struct net_device * dev,struct wlan_cm_connect_resp * rsp)2108 static void hdd_update_hlp_info(struct net_device *dev,
2109 struct wlan_cm_connect_resp *rsp)
2110 {
2111 struct sk_buff *skb;
2112 uint16_t skb_len;
2113 struct llc_snap_hdr_t *llc_hdr;
2114 QDF_STATUS status;
2115 uint8_t *hlp_data;
2116 uint16_t hlp_data_len;
2117 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2118
2119 if (!rsp || !rsp->connect_ies.fils_ie) {
2120 return;
2121 }
2122
2123 if (!rsp->connect_ies.fils_ie->hlp_data_len) {
2124 return;
2125 }
2126
2127 hlp_data = rsp->connect_ies.fils_ie->hlp_data;
2128 hlp_data_len = rsp->connect_ies.fils_ie->hlp_data_len;
2129
2130 /* Calculate skb length */
2131 skb_len = (2 * ETH_ALEN) + hlp_data_len;
2132 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
2133 if (!skb) {
2134 hdd_err("HLP packet nbuf alloc fails");
2135 return;
2136 }
2137
2138 qdf_mem_copy(skb_put(skb, ETH_ALEN),
2139 rsp->connect_ies.fils_ie->dst_mac.bytes,
2140 QDF_MAC_ADDR_SIZE);
2141 qdf_mem_copy(skb_put(skb, ETH_ALEN),
2142 rsp->connect_ies.fils_ie->src_mac.bytes,
2143 QDF_MAC_ADDR_SIZE);
2144
2145 llc_hdr = (struct llc_snap_hdr_t *)hlp_data;
2146 if (IS_SNAP(llc_hdr)) {
2147 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
2148 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
2149 }
2150
2151 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
2152
2153 /*
2154 * This HLP packet is formed from HLP info encapsulated
2155 * in assoc response frame which is AEAD encrypted.
2156 * Hence, this checksum validation can be set unnecessary.
2157 * i.e. network layer need not worry about checksum.
2158 */
2159 skb->ip_summed = CHECKSUM_UNNECESSARY;
2160
2161 /*
2162 * adapter->deflink->vdev is directly dereferenced because in per packet
2163 * path usage of hdd_get_vdev_by_user is costly operation as it
2164 * involves lock access. And it is guaranteed during TX/RX operations
2165 * vdev will be active will not deleted.
2166 */
2167 status = ucfg_dp_rx_packet_cbk(adapter->deflink->vdev, (qdf_nbuf_t)skb);
2168 if (QDF_IS_STATUS_ERROR(status)) {
2169 hdd_err("Sending HLP packet fails");
2170 return;
2171 }
2172 hdd_debug("send HLP packet to netif successfully");
2173 }
2174
hdd_cm_set_hlp_data(struct net_device * dev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)2175 QDF_STATUS hdd_cm_set_hlp_data(struct net_device *dev,
2176 struct wlan_objmgr_vdev *vdev,
2177 struct wlan_cm_connect_resp *rsp)
2178 {
2179 hdd_update_hlp_info(dev, rsp);
2180 return QDF_STATUS_SUCCESS;
2181 }
2182 #endif
2183
2184 #ifdef WLAN_FEATURE_PREAUTH_ENABLE
2185 /**
2186 * hdd_cm_get_ft_preauth_response() - get ft preauth response
2187 * related information
2188 * @vdev: vdev pointer
2189 * @rsp: preauth response
2190 * @ft_ie: ft ie
2191 * @ft_ie_ip_len: ft ie ip length
2192 * @ft_ie_length: ft ies length
2193 *
2194 * This function is used to get ft ie related information
2195 *
2196 * Return: none
2197 */
2198 static void
hdd_cm_get_ft_preauth_response(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp,uint8_t * ft_ie,uint32_t ft_ie_ip_len,uint16_t * ft_ie_length)2199 hdd_cm_get_ft_preauth_response(struct wlan_objmgr_vdev *vdev,
2200 struct wlan_preauth_rsp *rsp, uint8_t *ft_ie,
2201 uint32_t ft_ie_ip_len, uint16_t *ft_ie_length)
2202 {
2203 struct mlme_legacy_priv *mlme_priv;
2204
2205 *ft_ie_length = 0;
2206
2207 if (!vdev)
2208 return;
2209
2210 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
2211 if (!mlme_priv)
2212 return;
2213
2214 /* All or nothing - proceed only if both BSSID and FT IE fit */
2215 if ((QDF_MAC_ADDR_SIZE + rsp->ft_ie_length) > ft_ie_ip_len)
2216 return;
2217 /*
2218 * hdd needs to pack the bssid also along with the
2219 * auth response to supplicant
2220 */
2221 qdf_mem_copy(ft_ie, rsp->pre_auth_bssid.bytes, QDF_MAC_ADDR_SIZE);
2222
2223 /* Copy the auth resp FTIEs */
2224 qdf_mem_copy(&ft_ie[QDF_MAC_ADDR_SIZE],
2225 rsp->ft_ie, rsp->ft_ie_length);
2226
2227 *ft_ie_length = QDF_MAC_ADDR_SIZE + rsp->ft_ie_length;
2228
2229 hdd_debug("Filled auth resp: %d", *ft_ie_length);
2230 }
2231
2232 #if defined(KERNEL_SUPPORT_11R_CFG80211)
hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)2233 QDF_STATUS hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev *vdev,
2234 struct wlan_preauth_rsp *rsp)
2235 {
2236 mac_handle_t mac_handle;
2237 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
2238 struct wireless_dev *wdev;
2239 uint16_t auth_resp_len = 0;
2240 uint32_t ric_ies_length = 0;
2241 struct cfg80211_ft_event_params ft_event = {0};
2242 uint8_t ft_ie[DOT11F_IE_FTINFO_MAX_LEN] = {0};
2243 uint8_t ric_ies[DOT11F_IE_RICDESCRIPTOR_MAX_LEN] = {0};
2244
2245 mac_handle = cds_get_context(QDF_MODULE_ID_SME);
2246 if (!mac_handle) {
2247 hdd_err("mac_handle is null");
2248 return QDF_STATUS_E_INVAL;
2249 }
2250
2251 if (!osif_priv) {
2252 hdd_err("Invalid vdev osif priv");
2253 return QDF_STATUS_E_INVAL;
2254 }
2255
2256 wdev = osif_priv->wdev;
2257 if (!wdev) {
2258 hdd_err("wdev is null");
2259 return QDF_STATUS_E_INVAL;
2260 }
2261
2262 if (rsp->ric_ies_length &&
2263 rsp->ric_ies_length <= DOT11F_IE_RICDESCRIPTOR_MAX_LEN) {
2264 qdf_mem_copy(ric_ies, rsp->ric_ies, rsp->ric_ies_length);
2265 ric_ies_length = rsp->ric_ies_length;
2266 } else {
2267 hdd_warn("Do not send RIC IEs as length is 0");
2268 }
2269
2270 if (ric_ies_length) {
2271 ft_event.ric_ies = ric_ies;
2272 ft_event.ric_ies_len = ric_ies_length;
2273 }
2274 hdd_debug("RIC IEs is of length %d", ric_ies_length);
2275
2276 hdd_cm_get_ft_preauth_response(vdev, rsp, ft_ie,
2277 DOT11F_IE_FTINFO_MAX_LEN,
2278 &auth_resp_len);
2279 if (!auth_resp_len) {
2280 hdd_debug("AuthRsp FTIES is of length 0");
2281 return QDF_STATUS_E_FAILURE;
2282 }
2283
2284 ucfg_cm_set_ft_pre_auth_state(vdev, true);
2285
2286 ft_event.target_ap = ft_ie;
2287 ft_event.ies = (u8 *)(ft_ie + QDF_MAC_ADDR_SIZE);
2288 ft_event.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
2289
2290 hdd_debug("ftEvent.ies_len %zu", ft_event.ies_len);
2291 hdd_debug("ftEvent.ric_ies_len %zu", ft_event.ric_ies_len);
2292 hdd_debug("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x",
2293 ft_event.target_ap[0], ft_event.target_ap[1],
2294 ft_event.target_ap[2], ft_event.target_ap[3],
2295 ft_event.target_ap[4], ft_event.target_ap[5]);
2296
2297 (void)cfg80211_ft_event(wdev->netdev, &ft_event);
2298
2299 return QDF_STATUS_SUCCESS;
2300 }
2301 #else
hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)2302 QDF_STATUS hdd_cm_ft_preauth_complete(struct wlan_objmgr_vdev *vdev,
2303 struct wlan_preauth_rsp *rsp)
2304 {
2305 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
2306 struct wireless_dev *wdev;
2307 uint16_t auth_resp_len = 0;
2308 uint32_t ric_ies_length = 0;
2309 char *buff;
2310 union iwreq_data wrqu;
2311 uint16_t str_len;
2312
2313 if (!osif_priv) {
2314 hdd_err("Invalid vdev osif priv");
2315 return QDF_STATUS_E_INVAL;
2316 }
2317
2318 wdev = osif_priv->wdev;
2319 if (!wdev) {
2320 hdd_err("wdev is null");
2321 return QDF_STATUS_E_INVAL;
2322 }
2323
2324 /* need to send the IEs to the supplicant */
2325 buff = qdf_mem_malloc(IW_CUSTOM_MAX);
2326 if (!buff)
2327 return QDF_STATUS_E_NOMEM;
2328
2329 /* need to send the RIC IEs first */
2330 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
2331 if (rsp->ric_ies_length &&
2332 (rsp->ric_ies_length <= (IW_CUSTOM_MAX - str_len))) {
2333 qdf_mem_copy(&buff[str_len], rsp->ric_ies,
2334 rsp->ric_ies_length);
2335 ric_ies_length = rsp->ric_ies_length;
2336 wrqu.data.length = str_len + ric_ies_length;
2337 hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buff);
2338 } else {
2339 hdd_warn("Do not send RIC IEs as length is 0");
2340 }
2341
2342 /* need to provide the Auth Resp */
2343 qdf_mem_zero(buff, IW_CUSTOM_MAX);
2344 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
2345 hdd_cm_get_ft_preauth_response(vdev, rsp, &buff[str_len],
2346 (IW_CUSTOM_MAX - str_len),
2347 &auth_resp_len);
2348 if (!auth_resp_len) {
2349 qdf_mem_free(buff);
2350 hdd_debug("AuthRsp FTIES is of length 0");
2351 return QDF_STATUS_E_FAILURE;
2352 }
2353
2354 wrqu.data.length = str_len + auth_resp_len;
2355 hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buff);
2356
2357 qdf_mem_free(buff);
2358 return QDF_STATUS_SUCCESS;
2359 }
2360 #endif
2361
2362 #ifdef FEATURE_WLAN_ESE
hdd_cm_cckm_preauth_complete(struct wlan_objmgr_vdev * vdev,struct wlan_preauth_rsp * rsp)2363 QDF_STATUS hdd_cm_cckm_preauth_complete(struct wlan_objmgr_vdev *vdev,
2364 struct wlan_preauth_rsp *rsp)
2365 {
2366 struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
2367 struct wireless_dev *wdev;
2368 union iwreq_data wrqu;
2369 char buf[IW_CUSTOM_MAX + 1];
2370 char *pos = buf;
2371 int nbytes = 0, freebytes = IW_CUSTOM_MAX;
2372
2373 if (!osif_priv) {
2374 hdd_err("Invalid vdev osif priv");
2375 return QDF_STATUS_E_INVAL;
2376 }
2377
2378 wdev = osif_priv->wdev;
2379 if (!wdev) {
2380 hdd_err("wdev is null");
2381 return QDF_STATUS_E_INVAL;
2382 }
2383
2384 /* create the event */
2385 memset(&wrqu, '\0', sizeof(wrqu));
2386 memset(buf, '\0', sizeof(buf));
2387
2388 /* timestamp0 is lower 32 bits and timestamp1 is upper 32 bits */
2389 hdd_debug("CCXPREAUTHNOTIFY=" QDF_MAC_ADDR_FMT " %d:%d",
2390 QDF_MAC_ADDR_REF(rsp->pre_auth_bssid.bytes),
2391 rsp->timestamp[0], rsp->timestamp[1]);
2392
2393 nbytes = snprintf(pos, freebytes, "CCXPREAUTHNOTIFY=");
2394 pos += nbytes;
2395 freebytes -= nbytes;
2396
2397 qdf_mem_copy(pos, rsp->pre_auth_bssid.bytes, QDF_MAC_ADDR_SIZE);
2398 pos += QDF_MAC_ADDR_SIZE;
2399 freebytes -= QDF_MAC_ADDR_SIZE;
2400
2401 nbytes = snprintf(pos, freebytes, " %u:%u",
2402 rsp->timestamp[0], rsp->timestamp[1]);
2403 freebytes -= nbytes;
2404
2405 wrqu.data.pointer = buf;
2406 wrqu.data.length = (IW_CUSTOM_MAX - freebytes);
2407
2408 /* send the event */
2409 hdd_wext_send_event(wdev->netdev, IWEVCUSTOM, &wrqu, buf);
2410
2411 return QDF_STATUS_SUCCESS;
2412 }
2413 #endif /* FEATURE_WLAN_ESE */
2414 #endif /* WLAN_FEATURE_PREAUTH_ENABLE */
2415