1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2012-2015,2020-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name *
5*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name *
9*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name */
17*5113495bSYour Name
18*5113495bSYour Name /**
19*5113495bSYour Name * DOC: osif_cm_req.c
20*5113495bSYour Name *
21*5113495bSYour Name * This file maintains definitaions of connect, disconnect, roam
22*5113495bSYour Name * request apis.
23*5113495bSYour Name */
24*5113495bSYour Name
25*5113495bSYour Name #include "wlan_osif_priv.h"
26*5113495bSYour Name #include "osif_cm_req.h"
27*5113495bSYour Name #include "wlan_cm_ucfg_api.h"
28*5113495bSYour Name #include "wlan_nl_to_crypto_params.h"
29*5113495bSYour Name #include <wlan_cfg80211.h>
30*5113495bSYour Name #include "osif_cm_util.h"
31*5113495bSYour Name #ifdef WLAN_FEATURE_FILS_SK
32*5113495bSYour Name #include <wlan_mlme_ucfg_api.h>
33*5113495bSYour Name #endif
34*5113495bSYour Name #include <wlan_mlo_mgr_sta.h>
35*5113495bSYour Name #include <utils_mlo.h>
36*5113495bSYour Name #include <wlan_mgmt_txrx_rx_reo_utils_api.h>
37*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP)
38*5113495bSYour Name #include <wlan_mlo_mgr_setup.h>
39*5113495bSYour Name #endif
40*5113495bSYour Name
41*5113495bSYour Name #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) && \
42*5113495bSYour Name LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) && \
43*5113495bSYour Name !defined(CFG80211_CRYPTO_WEP_KEYS_REMOVED)
44*5113495bSYour Name static QDF_STATUS
osif_cm_update_wep_seq_info(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)45*5113495bSYour Name osif_cm_update_wep_seq_info(struct wlan_cm_connect_req *connect_req,
46*5113495bSYour Name const struct cfg80211_connect_params *req)
47*5113495bSYour Name {
48*5113495bSYour Name if (req->crypto.wep_keys->seq_len) {
49*5113495bSYour Name connect_req->crypto.wep_keys.seq_len =
50*5113495bSYour Name req->crypto.wep_keys->seq_len;
51*5113495bSYour Name connect_req->crypto.wep_keys.seq =
52*5113495bSYour Name qdf_mem_malloc(connect_req->crypto.wep_keys.seq_len);
53*5113495bSYour Name if (!connect_req->crypto.wep_keys.seq) {
54*5113495bSYour Name ucfg_cm_free_wep_key_params(connect_req);
55*5113495bSYour Name return QDF_STATUS_E_NOMEM;
56*5113495bSYour Name }
57*5113495bSYour Name qdf_mem_copy(connect_req->crypto.wep_keys.seq,
58*5113495bSYour Name req->crypto.wep_keys->seq,
59*5113495bSYour Name connect_req->crypto.wep_keys.seq_len);
60*5113495bSYour Name }
61*5113495bSYour Name return QDF_STATUS_SUCCESS;
62*5113495bSYour Name }
63*5113495bSYour Name #else
64*5113495bSYour Name static inline QDF_STATUS
osif_cm_update_wep_seq_info(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)65*5113495bSYour Name osif_cm_update_wep_seq_info(struct wlan_cm_connect_req *connect_req,
66*5113495bSYour Name const struct cfg80211_connect_params *req)
67*5113495bSYour Name {
68*5113495bSYour Name return QDF_STATUS_SUCCESS;
69*5113495bSYour Name }
70*5113495bSYour Name #endif
71*5113495bSYour Name
72*5113495bSYour Name #if !defined(CFG80211_CRYPTO_WEP_KEYS_REMOVED)
73*5113495bSYour Name static QDF_STATUS
osif_cm_set_wep_key_params(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)74*5113495bSYour Name osif_cm_set_wep_key_params(struct wlan_cm_connect_req *connect_req,
75*5113495bSYour Name const struct cfg80211_connect_params *req)
76*5113495bSYour Name {
77*5113495bSYour Name if (!req->key_len)
78*5113495bSYour Name return QDF_STATUS_SUCCESS;
79*5113495bSYour Name
80*5113495bSYour Name connect_req->crypto.wep_keys.key_len = req->key_len;
81*5113495bSYour Name connect_req->crypto.wep_keys.key_idx = req->key_idx;
82*5113495bSYour Name
83*5113495bSYour Name connect_req->crypto.wep_keys.key =
84*5113495bSYour Name qdf_mem_malloc(connect_req->crypto.wep_keys.key_len);
85*5113495bSYour Name if (!connect_req->crypto.wep_keys.key)
86*5113495bSYour Name return QDF_STATUS_E_NOMEM;
87*5113495bSYour Name
88*5113495bSYour Name qdf_mem_copy(connect_req->crypto.wep_keys.key, req->key,
89*5113495bSYour Name connect_req->crypto.wep_keys.key_len);
90*5113495bSYour Name
91*5113495bSYour Name return osif_cm_update_wep_seq_info(connect_req, req);
92*5113495bSYour Name }
93*5113495bSYour Name #else
94*5113495bSYour Name static QDF_STATUS
osif_cm_set_wep_key_params(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)95*5113495bSYour Name osif_cm_set_wep_key_params(struct wlan_cm_connect_req *connect_req,
96*5113495bSYour Name const struct cfg80211_connect_params *req)
97*5113495bSYour Name {
98*5113495bSYour Name return QDF_STATUS_SUCCESS;
99*5113495bSYour Name }
100*5113495bSYour Name #endif
101*5113495bSYour Name
osif_cm_set_auth_type(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)102*5113495bSYour Name static void osif_cm_set_auth_type(struct wlan_cm_connect_req *connect_req,
103*5113495bSYour Name const struct cfg80211_connect_params *req)
104*5113495bSYour Name {
105*5113495bSYour Name wlan_crypto_auth_mode crypto_auth_type =
106*5113495bSYour Name osif_nl_to_crypto_auth_type(req->auth_type);
107*5113495bSYour Name
108*5113495bSYour Name /* For auto check wpa version to decide WPA or RSNA */
109*5113495bSYour Name if (crypto_auth_type == WLAN_CRYPTO_AUTH_AUTO &&
110*5113495bSYour Name req->crypto.wpa_versions) {
111*5113495bSYour Name if (req->crypto.wpa_versions & NL80211_WPA_VERSION_1)
112*5113495bSYour Name crypto_auth_type = WLAN_CRYPTO_AUTH_WPA;
113*5113495bSYour Name else
114*5113495bSYour Name crypto_auth_type = WLAN_CRYPTO_AUTH_RSNA;
115*5113495bSYour Name } else if (!req->crypto.n_ciphers_pairwise) {
116*5113495bSYour Name crypto_auth_type = WLAN_CRYPTO_AUTH_OPEN;
117*5113495bSYour Name }
118*5113495bSYour Name
119*5113495bSYour Name QDF_SET_PARAM(connect_req->crypto.auth_type, crypto_auth_type);
120*5113495bSYour Name }
121*5113495bSYour Name
122*5113495bSYour Name static int
osif_cm_get_num_akm_suites(const struct cfg80211_connect_params * req)123*5113495bSYour Name osif_cm_get_num_akm_suites(const struct cfg80211_connect_params *req)
124*5113495bSYour Name {
125*5113495bSYour Name return req->crypto.n_akm_suites;
126*5113495bSYour Name }
127*5113495bSYour Name
128*5113495bSYour Name static uint32_t*
osif_cm_get_akm_suites(const struct cfg80211_connect_params * req)129*5113495bSYour Name osif_cm_get_akm_suites(const struct cfg80211_connect_params *req)
130*5113495bSYour Name {
131*5113495bSYour Name return (uint32_t *)req->crypto.akm_suites;
132*5113495bSYour Name }
133*5113495bSYour Name
134*5113495bSYour Name #ifdef CFG80211_MULTI_AKM_CONNECT_SUPPORT
135*5113495bSYour Name #define MAX_AKM_SUITES WLAN_CM_MAX_CONNECT_AKMS
136*5113495bSYour Name #else
137*5113495bSYour Name #define MAX_AKM_SUITES NL80211_MAX_NR_AKM_SUITES
138*5113495bSYour Name #endif
139*5113495bSYour Name static void
osif_cm_set_akm_params(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)140*5113495bSYour Name osif_cm_set_akm_params(struct wlan_cm_connect_req *connect_req,
141*5113495bSYour Name const struct cfg80211_connect_params *req)
142*5113495bSYour Name {
143*5113495bSYour Name uint32_t i;
144*5113495bSYour Name wlan_crypto_key_mgmt akm;
145*5113495bSYour Name
146*5113495bSYour Name /* Fill AKM suites */
147*5113495bSYour Name if (req->crypto.n_akm_suites) {
148*5113495bSYour Name for (i = 0; i < req->crypto.n_akm_suites &&
149*5113495bSYour Name i < MAX_AKM_SUITES; i++) {
150*5113495bSYour Name akm = osif_nl_to_crypto_akm_type(
151*5113495bSYour Name req->crypto.akm_suites[i]);
152*5113495bSYour Name QDF_SET_PARAM(connect_req->crypto.akm_suites, akm);
153*5113495bSYour Name }
154*5113495bSYour Name } else {
155*5113495bSYour Name QDF_SET_PARAM(connect_req->crypto.akm_suites,
156*5113495bSYour Name WLAN_CRYPTO_KEY_MGMT_NONE);
157*5113495bSYour Name }
158*5113495bSYour Name }
159*5113495bSYour Name
160*5113495bSYour Name static inline
osif_cm_get_rsn_cap_mfp(enum nl80211_mfp mfp_state)161*5113495bSYour Name uint8_t osif_cm_get_rsn_cap_mfp(enum nl80211_mfp mfp_state)
162*5113495bSYour Name {
163*5113495bSYour Name switch (mfp_state) {
164*5113495bSYour Name case NL80211_MFP_REQUIRED:
165*5113495bSYour Name return RSN_CAP_MFP_REQUIRED;
166*5113495bSYour Name case NL80211_MFP_OPTIONAL:
167*5113495bSYour Name return RSN_CAP_MFP_CAPABLE;
168*5113495bSYour Name default:
169*5113495bSYour Name return RSN_CAP_MFP_DISABLED;
170*5113495bSYour Name }
171*5113495bSYour Name }
172*5113495bSYour Name
173*5113495bSYour Name #ifdef CONNECTIVITY_DIAG_EVENT
174*5113495bSYour Name /**
175*5113495bSYour Name * osif_cm_populate_user_crypto_param() - API to cache crypto param
176*5113495bSYour Name * received from the userspace.
177*5113495bSYour Name * @connect_req: Connect request buffer to cache parameter
178*5113495bSYour Name * @req: Connection request parameter received from userspace.
179*5113495bSYour Name *
180*5113495bSYour Name * Return: None
181*5113495bSYour Name */
182*5113495bSYour Name static void
osif_cm_populate_user_crypto_param(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)183*5113495bSYour Name osif_cm_populate_user_crypto_param(struct wlan_cm_connect_req *connect_req,
184*5113495bSYour Name const struct cfg80211_connect_params *req)
185*5113495bSYour Name {
186*5113495bSYour Name connect_req->crypto.user_cipher_pairwise =
187*5113495bSYour Name req->crypto.ciphers_pairwise[0];
188*5113495bSYour Name connect_req->crypto.user_akm_suite = req->crypto.akm_suites[0];
189*5113495bSYour Name connect_req->crypto.user_auth_type = req->auth_type;
190*5113495bSYour Name connect_req->crypto.user_grp_cipher = req->crypto.cipher_group;
191*5113495bSYour Name }
192*5113495bSYour Name #else
193*5113495bSYour Name static void
osif_cm_populate_user_crypto_param(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)194*5113495bSYour Name osif_cm_populate_user_crypto_param(struct wlan_cm_connect_req *connect_req,
195*5113495bSYour Name const struct cfg80211_connect_params *req)
196*5113495bSYour Name {
197*5113495bSYour Name }
198*5113495bSYour Name #endif
199*5113495bSYour Name
200*5113495bSYour Name static
osif_cm_set_crypto_params(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)201*5113495bSYour Name QDF_STATUS osif_cm_set_crypto_params(struct wlan_cm_connect_req *connect_req,
202*5113495bSYour Name const struct cfg80211_connect_params *req)
203*5113495bSYour Name {
204*5113495bSYour Name uint32_t i;
205*5113495bSYour Name QDF_STATUS status;
206*5113495bSYour Name wlan_crypto_cipher_type cipher = WLAN_CRYPTO_CIPHER_NONE;
207*5113495bSYour Name
208*5113495bSYour Name connect_req->crypto.wpa_versions = req->crypto.wpa_versions;
209*5113495bSYour Name
210*5113495bSYour Name osif_cm_set_auth_type(connect_req, req);
211*5113495bSYour Name
212*5113495bSYour Name if (req->crypto.cipher_group)
213*5113495bSYour Name cipher =
214*5113495bSYour Name osif_nl_to_crypto_cipher_type(req->crypto.cipher_group);
215*5113495bSYour Name
216*5113495bSYour Name QDF_SET_PARAM(connect_req->crypto.group_cipher, cipher);
217*5113495bSYour Name
218*5113495bSYour Name /* Fill Pairwise ciphers */
219*5113495bSYour Name if (req->crypto.n_ciphers_pairwise) {
220*5113495bSYour Name for (i = 0; i < req->crypto.n_ciphers_pairwise &&
221*5113495bSYour Name i < NL80211_MAX_NR_CIPHER_SUITES; i++) {
222*5113495bSYour Name cipher = osif_nl_to_crypto_cipher_type(
223*5113495bSYour Name req->crypto.ciphers_pairwise[i]);
224*5113495bSYour Name QDF_SET_PARAM(connect_req->crypto.ciphers_pairwise,
225*5113495bSYour Name cipher);
226*5113495bSYour Name }
227*5113495bSYour Name } else {
228*5113495bSYour Name QDF_SET_PARAM(connect_req->crypto.ciphers_pairwise,
229*5113495bSYour Name WLAN_CRYPTO_CIPHER_NONE);
230*5113495bSYour Name }
231*5113495bSYour Name
232*5113495bSYour Name /* Fill AKM suites */
233*5113495bSYour Name osif_cm_set_akm_params(connect_req, req);
234*5113495bSYour Name
235*5113495bSYour Name /* Fill WEP Key information */
236*5113495bSYour Name status = osif_cm_set_wep_key_params(connect_req, req);
237*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
238*5113495bSYour Name osif_err("set wep key params failed");
239*5113495bSYour Name
240*5113495bSYour Name /* Copy user configured MFP capability */
241*5113495bSYour Name connect_req->crypto.user_mfp = osif_cm_get_rsn_cap_mfp(req->mfp);
242*5113495bSYour Name
243*5113495bSYour Name osif_cm_populate_user_crypto_param(connect_req, req);
244*5113495bSYour Name
245*5113495bSYour Name return status;
246*5113495bSYour Name }
247*5113495bSYour Name
248*5113495bSYour Name #ifdef WLAN_FEATURE_FILS_SK
osif_cm_is_akm_suite_fils(uint32_t key_mgmt)249*5113495bSYour Name static bool osif_cm_is_akm_suite_fils(uint32_t key_mgmt)
250*5113495bSYour Name {
251*5113495bSYour Name switch (key_mgmt) {
252*5113495bSYour Name case WLAN_AKM_SUITE_FILS_SHA256:
253*5113495bSYour Name case WLAN_AKM_SUITE_FILS_SHA384:
254*5113495bSYour Name case WLAN_AKM_SUITE_FT_FILS_SHA256:
255*5113495bSYour Name case WLAN_AKM_SUITE_FT_FILS_SHA384:
256*5113495bSYour Name osif_debug("Fils AKM : %x", key_mgmt);
257*5113495bSYour Name return true;
258*5113495bSYour Name default:
259*5113495bSYour Name return false;
260*5113495bSYour Name }
261*5113495bSYour Name }
262*5113495bSYour Name
osif_cm_is_conn_type_fils(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)263*5113495bSYour Name static bool osif_cm_is_conn_type_fils(struct wlan_cm_connect_req *connect_req,
264*5113495bSYour Name const struct cfg80211_connect_params *req)
265*5113495bSYour Name {
266*5113495bSYour Name int num_akm_suites;
267*5113495bSYour Name uint32_t *akm_suites;
268*5113495bSYour Name uint8_t i;
269*5113495bSYour Name
270*5113495bSYour Name num_akm_suites = osif_cm_get_num_akm_suites(req);
271*5113495bSYour Name akm_suites = osif_cm_get_akm_suites(req);
272*5113495bSYour Name
273*5113495bSYour Name if (num_akm_suites <= 0)
274*5113495bSYour Name return false;
275*5113495bSYour Name
276*5113495bSYour Name /*
277*5113495bSYour Name * Auth type will be either be OPEN or FILS type for a FILS connection
278*5113495bSYour Name */
279*5113495bSYour Name if (connect_req->fils_info.auth_type == FILS_PK_MAX &&
280*5113495bSYour Name req->auth_type != NL80211_AUTHTYPE_OPEN_SYSTEM)
281*5113495bSYour Name return false;
282*5113495bSYour Name
283*5113495bSYour Name for (i = 0; i < num_akm_suites; i++) {
284*5113495bSYour Name if (!osif_cm_is_akm_suite_fils(akm_suites[i]))
285*5113495bSYour Name continue;
286*5113495bSYour Name return true;
287*5113495bSYour Name }
288*5113495bSYour Name
289*5113495bSYour Name
290*5113495bSYour Name return false;
291*5113495bSYour Name }
292*5113495bSYour Name
293*5113495bSYour Name enum wlan_fils_auth_type
osif_cm_get_fils_auth_type(enum nl80211_auth_type auth)294*5113495bSYour Name osif_cm_get_fils_auth_type(enum nl80211_auth_type auth)
295*5113495bSYour Name {
296*5113495bSYour Name switch (auth) {
297*5113495bSYour Name case NL80211_AUTHTYPE_FILS_SK:
298*5113495bSYour Name return FILS_SK_WITHOUT_PFS;
299*5113495bSYour Name case NL80211_AUTHTYPE_FILS_SK_PFS:
300*5113495bSYour Name return FILS_SK_WITH_PFS;
301*5113495bSYour Name case NL80211_AUTHTYPE_FILS_PK:
302*5113495bSYour Name return FILS_PK_AUTH;
303*5113495bSYour Name default:
304*5113495bSYour Name return FILS_PK_MAX;
305*5113495bSYour Name }
306*5113495bSYour Name }
307*5113495bSYour Name
308*5113495bSYour Name static QDF_STATUS
osif_cm_set_fils_info(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)309*5113495bSYour Name osif_cm_set_fils_info(struct wlan_objmgr_vdev *vdev,
310*5113495bSYour Name struct wlan_cm_connect_req *connect_req,
311*5113495bSYour Name const struct cfg80211_connect_params *req)
312*5113495bSYour Name {
313*5113495bSYour Name bool value = 0;
314*5113495bSYour Name QDF_STATUS status;
315*5113495bSYour Name uint8_t *buf;
316*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
317*5113495bSYour Name
318*5113495bSYour Name psoc = wlan_vdev_get_psoc(vdev);
319*5113495bSYour Name if (!psoc)
320*5113495bSYour Name return -QDF_STATUS_E_INVAL;
321*5113495bSYour Name
322*5113495bSYour Name connect_req->fils_info.auth_type =
323*5113495bSYour Name osif_cm_get_fils_auth_type(req->auth_type);
324*5113495bSYour Name connect_req->fils_info.is_fils_connection =
325*5113495bSYour Name osif_cm_is_conn_type_fils(connect_req,
326*5113495bSYour Name req);
327*5113495bSYour Name osif_debug("auth type %d is fils %d",
328*5113495bSYour Name connect_req->fils_info.auth_type,
329*5113495bSYour Name connect_req->fils_info.is_fils_connection);
330*5113495bSYour Name if (!connect_req->fils_info.is_fils_connection)
331*5113495bSYour Name return QDF_STATUS_SUCCESS;
332*5113495bSYour Name
333*5113495bSYour Name status = ucfg_mlme_get_fils_enabled_info(psoc, &value);
334*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status) || !value) {
335*5113495bSYour Name osif_err("get_fils_enabled status: %d fils_enabled: %d",
336*5113495bSYour Name status, value);
337*5113495bSYour Name return QDF_STATUS_E_INVAL;
338*5113495bSYour Name }
339*5113495bSYour Name
340*5113495bSYour Name /*
341*5113495bSYour Name * The initial connection for FILS may happen with an OPEN
342*5113495bSYour Name * auth type. Hence we need to allow the connection to go
343*5113495bSYour Name * through in that case as well.
344*5113495bSYour Name */
345*5113495bSYour Name if (req->auth_type != NL80211_AUTHTYPE_FILS_SK) {
346*5113495bSYour Name osif_debug("set is fils false for initial connection");
347*5113495bSYour Name connect_req->fils_info.is_fils_connection = false;
348*5113495bSYour Name return QDF_STATUS_SUCCESS;
349*5113495bSYour Name }
350*5113495bSYour Name
351*5113495bSYour Name connect_req->fils_info.realm_len = req->fils_erp_realm_len;
352*5113495bSYour Name
353*5113495bSYour Name if (connect_req->fils_info.realm_len > WLAN_CM_FILS_MAX_REALM_LEN) {
354*5113495bSYour Name osif_err("Invalid fils realm len %d",
355*5113495bSYour Name connect_req->fils_info.realm_len);
356*5113495bSYour Name return QDF_STATUS_E_INVAL;
357*5113495bSYour Name }
358*5113495bSYour Name qdf_mem_zero(connect_req->fils_info.realm, WLAN_CM_FILS_MAX_REALM_LEN);
359*5113495bSYour Name qdf_mem_copy(connect_req->fils_info.realm, req->fils_erp_realm,
360*5113495bSYour Name connect_req->fils_info.realm_len);
361*5113495bSYour Name
362*5113495bSYour Name connect_req->fils_info.next_seq_num = req->fils_erp_next_seq_num + 1;
363*5113495bSYour Name
364*5113495bSYour Name connect_req->fils_info.rrk_len = req->fils_erp_rrk_len;
365*5113495bSYour Name
366*5113495bSYour Name if (connect_req->fils_info.rrk_len > WLAN_CM_FILS_MAX_RRK_LENGTH) {
367*5113495bSYour Name osif_err("Invalid fils rrk len %d",
368*5113495bSYour Name connect_req->fils_info.rrk_len);
369*5113495bSYour Name return QDF_STATUS_E_INVAL;
370*5113495bSYour Name }
371*5113495bSYour Name qdf_mem_zero(connect_req->fils_info.rrk, WLAN_CM_FILS_MAX_RRK_LENGTH);
372*5113495bSYour Name qdf_mem_copy(connect_req->fils_info.rrk, req->fils_erp_rrk,
373*5113495bSYour Name connect_req->fils_info.rrk_len);
374*5113495bSYour Name
375*5113495bSYour Name connect_req->fils_info.username_len = req->fils_erp_username_len +
376*5113495bSYour Name sizeof(char) + req->fils_erp_realm_len;
377*5113495bSYour Name osif_debug("usrname len %d = usrname recv len %zu + realm len %d + %zu",
378*5113495bSYour Name connect_req->fils_info.username_len,
379*5113495bSYour Name req->fils_erp_username_len,
380*5113495bSYour Name connect_req->fils_info.realm_len, sizeof(char));
381*5113495bSYour Name
382*5113495bSYour Name if (connect_req->fils_info.username_len >
383*5113495bSYour Name WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH) {
384*5113495bSYour Name osif_err("Invalid fils username len %d",
385*5113495bSYour Name connect_req->fils_info.username_len);
386*5113495bSYour Name return QDF_STATUS_E_INVAL;
387*5113495bSYour Name }
388*5113495bSYour Name if (!req->fils_erp_username_len) {
389*5113495bSYour Name osif_info("FILS_PMKSA: No ERP username, return success");
390*5113495bSYour Name return QDF_STATUS_SUCCESS;
391*5113495bSYour Name }
392*5113495bSYour Name buf = connect_req->fils_info.username;
393*5113495bSYour Name qdf_mem_zero(connect_req->fils_info.username,
394*5113495bSYour Name WLAN_CM_FILS_MAX_KEYNAME_NAI_LENGTH);
395*5113495bSYour Name qdf_mem_copy(buf, req->fils_erp_username, req->fils_erp_username_len);
396*5113495bSYour Name buf += req->fils_erp_username_len;
397*5113495bSYour Name *buf++ = '@';
398*5113495bSYour Name qdf_mem_copy(buf, req->fils_erp_realm, req->fils_erp_realm_len);
399*5113495bSYour Name
400*5113495bSYour Name return QDF_STATUS_SUCCESS;
401*5113495bSYour Name }
402*5113495bSYour Name #else
403*5113495bSYour Name static inline
osif_cm_set_fils_info(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)404*5113495bSYour Name QDF_STATUS osif_cm_set_fils_info(struct wlan_objmgr_vdev *vdev,
405*5113495bSYour Name struct wlan_cm_connect_req *connect_req,
406*5113495bSYour Name const struct cfg80211_connect_params *req)
407*5113495bSYour Name {
408*5113495bSYour Name return QDF_STATUS_SUCCESS;
409*5113495bSYour Name }
410*5113495bSYour Name #endif
411*5113495bSYour Name
412*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
413*5113495bSYour Name static inline void
osif_cm_set_prev_bssid(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)414*5113495bSYour Name osif_cm_set_prev_bssid(struct wlan_cm_connect_req *connect_req,
415*5113495bSYour Name const struct cfg80211_connect_params *req)
416*5113495bSYour Name {
417*5113495bSYour Name if (req->prev_bssid)
418*5113495bSYour Name qdf_mem_copy(connect_req->prev_bssid.bytes, req->prev_bssid,
419*5113495bSYour Name QDF_MAC_ADDR_SIZE);
420*5113495bSYour Name }
421*5113495bSYour Name
422*5113495bSYour Name static inline
osif_cm_dump_prev_bssid(const struct cfg80211_connect_params * req)423*5113495bSYour Name void osif_cm_dump_prev_bssid(const struct cfg80211_connect_params *req)
424*5113495bSYour Name {
425*5113495bSYour Name if (req->prev_bssid)
426*5113495bSYour Name osif_nofl_debug("prev BSSID "QDF_MAC_ADDR_FMT,
427*5113495bSYour Name QDF_MAC_ADDR_REF(req->prev_bssid));
428*5113495bSYour Name }
429*5113495bSYour Name
430*5113495bSYour Name #else
431*5113495bSYour Name static inline void
osif_cm_set_prev_bssid(struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)432*5113495bSYour Name osif_cm_set_prev_bssid(struct wlan_cm_connect_req *connect_req,
433*5113495bSYour Name const struct cfg80211_connect_params *req)
434*5113495bSYour Name {
435*5113495bSYour Name }
436*5113495bSYour Name
437*5113495bSYour Name static inline
osif_cm_dump_prev_bssid(const struct cfg80211_connect_params * req)438*5113495bSYour Name void osif_cm_dump_prev_bssid(const struct cfg80211_connect_params *req)
439*5113495bSYour Name {
440*5113495bSYour Name }
441*5113495bSYour Name
442*5113495bSYour Name #endif
443*5113495bSYour Name
444*5113495bSYour Name static inline void
osif_cm_dump_connect_req(struct net_device * dev,uint8_t vdev_id,const struct cfg80211_connect_params * req)445*5113495bSYour Name osif_cm_dump_connect_req(struct net_device *dev, uint8_t vdev_id,
446*5113495bSYour Name const struct cfg80211_connect_params *req)
447*5113495bSYour Name {
448*5113495bSYour Name uint32_t i;
449*5113495bSYour Name uint32_t num_akm_suites;
450*5113495bSYour Name uint32_t *akm_suites;
451*5113495bSYour Name
452*5113495bSYour Name num_akm_suites = osif_cm_get_num_akm_suites(req);
453*5113495bSYour Name akm_suites = osif_cm_get_akm_suites(req);
454*5113495bSYour Name
455*5113495bSYour Name osif_nofl_debug("connect req for %s(vdevid-%d) freq %d SSID " QDF_SSID_FMT " auth type %d WPA ver %d n_akm %d n_cipher %d grp_cipher %x mfp %d freq hint %d",
456*5113495bSYour Name dev->name, vdev_id,
457*5113495bSYour Name req->channel ? req->channel->center_freq : 0,
458*5113495bSYour Name QDF_SSID_REF((int)req->ssid_len, req->ssid),
459*5113495bSYour Name req->auth_type, req->crypto.wpa_versions,
460*5113495bSYour Name num_akm_suites,
461*5113495bSYour Name req->crypto.n_ciphers_pairwise,
462*5113495bSYour Name req->crypto.cipher_group, req->mfp,
463*5113495bSYour Name req->channel_hint ? req->channel_hint->center_freq : 0);
464*5113495bSYour Name if (req->bssid)
465*5113495bSYour Name osif_nofl_debug("BSSID "QDF_MAC_ADDR_FMT,
466*5113495bSYour Name QDF_MAC_ADDR_REF(req->bssid));
467*5113495bSYour Name if (req->bssid_hint)
468*5113495bSYour Name osif_nofl_debug("BSSID hint "QDF_MAC_ADDR_FMT,
469*5113495bSYour Name QDF_MAC_ADDR_REF(req->bssid_hint));
470*5113495bSYour Name osif_cm_dump_prev_bssid(req);
471*5113495bSYour Name
472*5113495bSYour Name for (i = 0; i < num_akm_suites; i++)
473*5113495bSYour Name osif_nofl_debug("akm[%d] = %x", i, akm_suites[i]);
474*5113495bSYour Name
475*5113495bSYour Name for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
476*5113495bSYour Name osif_nofl_debug("cipher_pairwise[%d] = %x", i,
477*5113495bSYour Name req->crypto.ciphers_pairwise[i]);
478*5113495bSYour Name }
479*5113495bSYour Name
480*5113495bSYour Name static void
osif_cm_fill_connect_params(struct wlan_cm_connect_req * req,const struct osif_connect_params * params)481*5113495bSYour Name osif_cm_fill_connect_params(struct wlan_cm_connect_req *req,
482*5113495bSYour Name const struct osif_connect_params *params)
483*5113495bSYour Name {
484*5113495bSYour Name if (!params)
485*5113495bSYour Name return;
486*5113495bSYour Name
487*5113495bSYour Name if (params->scan_ie.len) {
488*5113495bSYour Name req->scan_ie.ptr = qdf_mem_malloc(params->scan_ie.len);
489*5113495bSYour Name if (req->scan_ie.ptr) {
490*5113495bSYour Name qdf_mem_copy(req->scan_ie.ptr, params->scan_ie.ptr,
491*5113495bSYour Name params->scan_ie.len);
492*5113495bSYour Name req->scan_ie.len = params->scan_ie.len;
493*5113495bSYour Name }
494*5113495bSYour Name }
495*5113495bSYour Name req->dot11mode_filter = params->dot11mode_filter;
496*5113495bSYour Name req->force_rsne_override = params->force_rsne_override;
497*5113495bSYour Name req->sae_pwe = params->sae_pwe;
498*5113495bSYour Name
499*5113495bSYour Name if (!qdf_is_macaddr_zero((struct qdf_mac_addr *)¶ms->prev_bssid))
500*5113495bSYour Name qdf_copy_macaddr(&req->prev_bssid,
501*5113495bSYour Name (struct qdf_mac_addr *)¶ms->prev_bssid);
502*5113495bSYour Name }
503*5113495bSYour Name
504*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
505*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
506*5113495bSYour Name static inline
osif_update_mlo_partner_info(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)507*5113495bSYour Name QDF_STATUS osif_update_mlo_partner_info(
508*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
509*5113495bSYour Name struct wlan_cm_connect_req *connect_req,
510*5113495bSYour Name const struct cfg80211_connect_params *req)
511*5113495bSYour Name {
512*5113495bSYour Name return QDF_STATUS_SUCCESS;
513*5113495bSYour Name }
514*5113495bSYour Name #else
515*5113495bSYour Name static inline
osif_update_partner_vdev_info(struct wlan_objmgr_vdev * vdev,struct mlo_partner_info partner_info)516*5113495bSYour Name void osif_update_partner_vdev_info(struct wlan_objmgr_vdev *vdev,
517*5113495bSYour Name struct mlo_partner_info partner_info)
518*5113495bSYour Name {
519*5113495bSYour Name struct wlan_objmgr_vdev *tmp_vdev;
520*5113495bSYour Name struct wlan_mlo_dev_context *ml_dev = NULL;
521*5113495bSYour Name uint8_t i;
522*5113495bSYour Name uint8_t link_id;
523*5113495bSYour Name
524*5113495bSYour Name if (!vdev)
525*5113495bSYour Name return;
526*5113495bSYour Name
527*5113495bSYour Name ml_dev = vdev->mlo_dev_ctx;
528*5113495bSYour Name if (!ml_dev)
529*5113495bSYour Name return;
530*5113495bSYour Name
531*5113495bSYour Name for (i = 0; i < partner_info.num_partner_links; i++) {
532*5113495bSYour Name tmp_vdev = mlo_get_ml_vdev_by_mac(
533*5113495bSYour Name vdev,
534*5113495bSYour Name &partner_info.partner_link_info[i].link_addr);
535*5113495bSYour Name if (tmp_vdev) {
536*5113495bSYour Name mlo_update_connect_req_links(tmp_vdev, 1);
537*5113495bSYour Name wlan_vdev_mlme_set_mlo_vdev(tmp_vdev);
538*5113495bSYour Name wlan_vdev_mlme_set_mlo_link_vdev(tmp_vdev);
539*5113495bSYour Name /* Set link id for bridge sta vap */
540*5113495bSYour Name if (mlo_is_sta_bridge_vdev(tmp_vdev)) {
541*5113495bSYour Name link_id = ml_dev->bridge_sta_ctx->bridge_link_id;
542*5113495bSYour Name wlan_vdev_set_link_id(tmp_vdev, link_id);
543*5113495bSYour Name } else
544*5113495bSYour Name wlan_vdev_set_link_id(
545*5113495bSYour Name tmp_vdev,
546*5113495bSYour Name partner_info.partner_link_info[i].link_id);
547*5113495bSYour Name osif_debug("link id %d",
548*5113495bSYour Name tmp_vdev->vdev_mlme.mlo_link_id);
549*5113495bSYour Name }
550*5113495bSYour Name }
551*5113495bSYour Name }
552*5113495bSYour Name
553*5113495bSYour Name static inline
osif_update_mlo_partner_info(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)554*5113495bSYour Name QDF_STATUS osif_update_mlo_partner_info(
555*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
556*5113495bSYour Name struct wlan_cm_connect_req *connect_req,
557*5113495bSYour Name const struct cfg80211_connect_params *req)
558*5113495bSYour Name {
559*5113495bSYour Name /* Update ml partner info from connect req*/
560*5113495bSYour Name uint8_t *ptr = NULL;
561*5113495bSYour Name uint8_t *ml_ie = NULL;
562*5113495bSYour Name qdf_size_t ml_ie_len = 0;
563*5113495bSYour Name struct mlo_partner_info partner_info = {0};
564*5113495bSYour Name bool ml_ie_found = false, linkidfound = false;
565*5113495bSYour Name uint8_t linkid = 0;
566*5113495bSYour Name uint8_t aplinks = 0;
567*5113495bSYour Name enum wlan_ml_variant variant;
568*5113495bSYour Name QDF_STATUS status = QDF_STATUS_SUCCESS;
569*5113495bSYour Name struct wlan_objmgr_pdev *pdev = NULL;
570*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
571*5113495bSYour Name struct wlan_mlo_dev_context *ml_dev = NULL;
572*5113495bSYour Name
573*5113495bSYour Name if (!vdev || !connect_req || !req)
574*5113495bSYour Name return status;
575*5113495bSYour Name
576*5113495bSYour Name ml_dev = vdev->mlo_dev_ctx;
577*5113495bSYour Name if (!ml_dev) {
578*5113495bSYour Name osif_debug("ML ctx is NULL, ignore ML IE");
579*5113495bSYour Name return QDF_STATUS_SUCCESS;
580*5113495bSYour Name }
581*5113495bSYour Name pdev = wlan_vdev_get_pdev(vdev);
582*5113495bSYour Name
583*5113495bSYour Name if (!pdev) {
584*5113495bSYour Name osif_debug("null pdev");
585*5113495bSYour Name return QDF_STATUS_SUCCESS;
586*5113495bSYour Name }
587*5113495bSYour Name psoc = wlan_pdev_get_psoc(pdev);
588*5113495bSYour Name
589*5113495bSYour Name if (!psoc) {
590*5113495bSYour Name osif_debug("null psoc");
591*5113495bSYour Name return QDF_STATUS_SUCCESS;
592*5113495bSYour Name }
593*5113495bSYour Name
594*5113495bSYour Name if (!wlan_mlo_get_psoc_capable(psoc))
595*5113495bSYour Name return QDF_STATUS_SUCCESS;
596*5113495bSYour Name
597*5113495bSYour Name osif_debug("ML IE search start");
598*5113495bSYour Name if (req->ie_len) {
599*5113495bSYour Name ptr = (uint8_t *)req->ie;
600*5113495bSYour Name status = util_find_mlie(ptr, req->ie_len, &ml_ie, &ml_ie_len);
601*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status) || !ml_ie) {
602*5113495bSYour Name osif_debug("ML IE not found");
603*5113495bSYour Name /* Return success since ML is not mandatory for a
604*5113495bSYour Name * connect request
605*5113495bSYour Name */
606*5113495bSYour Name return QDF_STATUS_SUCCESS;
607*5113495bSYour Name }
608*5113495bSYour Name
609*5113495bSYour Name osif_debug("ML IE found length %d", (int)ml_ie_len);
610*5113495bSYour Name qdf_trace_hex_dump(QDF_MODULE_ID_OS_IF, QDF_TRACE_LEVEL_DEBUG,
611*5113495bSYour Name ml_ie, (int)ml_ie_len);
612*5113495bSYour Name ml_ie_found = true;
613*5113495bSYour Name
614*5113495bSYour Name status = util_get_mlie_variant(ml_ie, ml_ie_len,
615*5113495bSYour Name (int *)&variant);
616*5113495bSYour Name if (status != QDF_STATUS_SUCCESS) {
617*5113495bSYour Name osif_err("Unable to get Multi-Link element variant");
618*5113495bSYour Name return status;
619*5113495bSYour Name }
620*5113495bSYour Name
621*5113495bSYour Name if (variant != WLAN_ML_VARIANT_BASIC) {
622*5113495bSYour Name osif_err("Invalid Multi-Link element variant %u",
623*5113495bSYour Name variant);
624*5113495bSYour Name return status;
625*5113495bSYour Name }
626*5113495bSYour Name
627*5113495bSYour Name status = util_get_bvmlie_primary_linkid(ml_ie, ml_ie_len,
628*5113495bSYour Name &linkidfound, &linkid);
629*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
630*5113495bSYour Name osif_err("Unable to find primary link ID in ML IE");
631*5113495bSYour Name return status;
632*5113495bSYour Name }
633*5113495bSYour Name
634*5113495bSYour Name status = util_get_bvmlie_persta_partner_info(ml_ie, ml_ie_len,
635*5113495bSYour Name &partner_info);
636*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status)) {
637*5113495bSYour Name osif_err("Unable to find per-sta profile in ML IE");
638*5113495bSYour Name return status;
639*5113495bSYour Name }
640*5113495bSYour Name
641*5113495bSYour Name if (partner_info.num_partner_links + 1 >
642*5113495bSYour Name WLAN_UMAC_MLO_ASSOC_MAX_SUPPORTED_LINKS) {
643*5113495bSYour Name osif_err("Rejecting connect for more than %d Assoc links",
644*5113495bSYour Name WLAN_UMAC_MLO_ASSOC_MAX_SUPPORTED_LINKS);
645*5113495bSYour Name return QDF_STATUS_E_FAILURE;
646*5113495bSYour Name }
647*5113495bSYour Name
648*5113495bSYour Name wlan_vdev_set_link_id(vdev, linkid);
649*5113495bSYour Name wlan_vdev_mlme_set_mlo_vdev(vdev);
650*5113495bSYour Name }
651*5113495bSYour Name
652*5113495bSYour Name qdf_mem_copy(&connect_req->ml_parnter_info,
653*5113495bSYour Name &partner_info, sizeof(struct mlo_partner_info));
654*5113495bSYour Name /* Get total number of links in association */
655*5113495bSYour Name aplinks = partner_info.num_partner_links + 1;
656*5113495bSYour Name if (ml_ie_found) {
657*5113495bSYour Name mlo_clear_connect_req_links_bmap(vdev);
658*5113495bSYour Name /* Handle 4 LINK RDP Case*/
659*5113495bSYour Name if (mlo_check_topology(pdev, vdev, aplinks) != QDF_STATUS_SUCCESS) {
660*5113495bSYour Name osif_err("Topology check failed prevent association\n");
661*5113495bSYour Name return QDF_STATUS_E_FAILURE;
662*5113495bSYour Name }
663*5113495bSYour Name
664*5113495bSYour Name if (mlo_sta_bridge_exists(vdev))
665*5113495bSYour Name mlo_update_partner_bridge_info(ml_dev, &partner_info);
666*5113495bSYour Name
667*5113495bSYour Name mlo_update_connect_req_links(vdev, 1);
668*5113495bSYour Name osif_update_partner_vdev_info(vdev, partner_info);
669*5113495bSYour Name mlo_mlme_sta_op_class(vdev, ml_ie);
670*5113495bSYour Name }
671*5113495bSYour Name
672*5113495bSYour Name return QDF_STATUS_SUCCESS;
673*5113495bSYour Name }
674*5113495bSYour Name #endif /* WLAN_FEATURE_11BE_MLO_ADV_FEATURE */
675*5113495bSYour Name #else
676*5113495bSYour Name static inline
osif_update_mlo_partner_info(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_req * connect_req,const struct cfg80211_connect_params * req)677*5113495bSYour Name QDF_STATUS osif_update_mlo_partner_info(
678*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
679*5113495bSYour Name struct wlan_cm_connect_req *connect_req,
680*5113495bSYour Name const struct cfg80211_connect_params *req)
681*5113495bSYour Name {
682*5113495bSYour Name return QDF_STATUS_SUCCESS;
683*5113495bSYour Name }
684*5113495bSYour Name #endif
685*5113495bSYour Name
osif_cm_connect(struct net_device * dev,struct wlan_objmgr_vdev * vdev,const struct cfg80211_connect_params * req,const struct osif_connect_params * params)686*5113495bSYour Name int osif_cm_connect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
687*5113495bSYour Name const struct cfg80211_connect_params *req,
688*5113495bSYour Name const struct osif_connect_params *params)
689*5113495bSYour Name {
690*5113495bSYour Name struct wlan_cm_connect_req *connect_req;
691*5113495bSYour Name const u8 *bssid_hint = req->bssid_hint;
692*5113495bSYour Name uint8_t vdev_id = vdev->vdev_objmgr.vdev_id;
693*5113495bSYour Name QDF_STATUS status;
694*5113495bSYour Name struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
695*5113495bSYour Name struct wlan_objmgr_vdev *temp_vdev;
696*5113495bSYour Name
697*5113495bSYour Name if (req->bssid)
698*5113495bSYour Name qdf_mem_copy(bssid.bytes, req->bssid,
699*5113495bSYour Name QDF_MAC_ADDR_SIZE);
700*5113495bSYour Name else if (bssid_hint)
701*5113495bSYour Name qdf_mem_copy(bssid.bytes, req->bssid_hint,
702*5113495bSYour Name QDF_MAC_ADDR_SIZE);
703*5113495bSYour Name
704*5113495bSYour Name temp_vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(
705*5113495bSYour Name wlan_vdev_get_pdev(vdev),
706*5113495bSYour Name bssid.bytes,
707*5113495bSYour Name WLAN_OSIF_CM_ID);
708*5113495bSYour Name
709*5113495bSYour Name if (temp_vdev) {
710*5113495bSYour Name osif_err("vdev %d already exist with same mac address"
711*5113495bSYour Name QDF_MAC_ADDR_FMT, wlan_vdev_get_id(temp_vdev),
712*5113495bSYour Name QDF_MAC_ADDR_REF(bssid.bytes));
713*5113495bSYour Name wlan_objmgr_vdev_release_ref(temp_vdev, WLAN_OSIF_CM_ID);
714*5113495bSYour Name return -EINVAL;
715*5113495bSYour Name }
716*5113495bSYour Name osif_cm_dump_connect_req(dev, vdev_id, req);
717*5113495bSYour Name
718*5113495bSYour Name status = osif_cm_reset_id_and_src(vdev);
719*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
720*5113495bSYour Name return qdf_status_to_os_return(status);
721*5113495bSYour Name
722*5113495bSYour Name connect_req = qdf_mem_malloc(sizeof(*connect_req));
723*5113495bSYour Name if (!connect_req)
724*5113495bSYour Name return -ENOMEM;
725*5113495bSYour Name
726*5113495bSYour Name connect_req->vdev_id = vdev_id;
727*5113495bSYour Name connect_req->source = CM_OSIF_CONNECT;
728*5113495bSYour Name if (req->bssid)
729*5113495bSYour Name qdf_mem_copy(connect_req->bssid.bytes, req->bssid,
730*5113495bSYour Name QDF_MAC_ADDR_SIZE);
731*5113495bSYour Name else if (bssid_hint)
732*5113495bSYour Name qdf_mem_copy(connect_req->bssid_hint.bytes, req->bssid_hint,
733*5113495bSYour Name QDF_MAC_ADDR_SIZE);
734*5113495bSYour Name
735*5113495bSYour Name osif_cm_set_prev_bssid(connect_req, req);
736*5113495bSYour Name
737*5113495bSYour Name connect_req->ssid.length = req->ssid_len;
738*5113495bSYour Name if (connect_req->ssid.length > WLAN_SSID_MAX_LEN) {
739*5113495bSYour Name osif_err("Invalid ssid len %zu", req->ssid_len);
740*5113495bSYour Name ucfg_cm_free_connect_req(connect_req);
741*5113495bSYour Name return -EINVAL;
742*5113495bSYour Name }
743*5113495bSYour Name
744*5113495bSYour Name qdf_mem_copy(connect_req->ssid.ssid, req->ssid,
745*5113495bSYour Name connect_req->ssid.length);
746*5113495bSYour Name
747*5113495bSYour Name if (req->channel)
748*5113495bSYour Name connect_req->chan_freq = req->channel->center_freq;
749*5113495bSYour Name
750*5113495bSYour Name if (req->channel_hint)
751*5113495bSYour Name connect_req->chan_freq_hint = req->channel_hint->center_freq;
752*5113495bSYour Name
753*5113495bSYour Name status = osif_cm_set_crypto_params(connect_req, req);
754*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
755*5113495bSYour Name goto connect_start_fail;
756*5113495bSYour Name
757*5113495bSYour Name connect_req->ht_caps = req->ht_capa.cap_info;
758*5113495bSYour Name connect_req->ht_caps_mask = req->ht_capa_mask.cap_info;
759*5113495bSYour Name connect_req->vht_caps = req->vht_capa.vht_cap_info;
760*5113495bSYour Name connect_req->vht_caps_mask = req->vht_capa_mask.vht_cap_info;
761*5113495bSYour Name
762*5113495bSYour Name /* Copy complete ie */
763*5113495bSYour Name if (req->ie_len) {
764*5113495bSYour Name connect_req->assoc_ie.len = req->ie_len;
765*5113495bSYour Name connect_req->assoc_ie.ptr = qdf_mem_malloc(req->ie_len);
766*5113495bSYour Name if (!connect_req->assoc_ie.ptr) {
767*5113495bSYour Name connect_req->assoc_ie.len = 0;
768*5113495bSYour Name status = QDF_STATUS_E_NOMEM;
769*5113495bSYour Name goto connect_start_fail;
770*5113495bSYour Name }
771*5113495bSYour Name qdf_mem_copy(connect_req->assoc_ie.ptr, req->ie,
772*5113495bSYour Name connect_req->assoc_ie.len);
773*5113495bSYour Name }
774*5113495bSYour Name
775*5113495bSYour Name status = osif_cm_set_fils_info(vdev, connect_req, req);
776*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
777*5113495bSYour Name goto connect_start_fail;
778*5113495bSYour Name
779*5113495bSYour Name osif_cm_fill_connect_params(connect_req, params);
780*5113495bSYour Name
781*5113495bSYour Name status = osif_update_mlo_partner_info(vdev, connect_req, req);
782*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
783*5113495bSYour Name goto connect_start_fail;
784*5113495bSYour Name
785*5113495bSYour Name status = mlo_connect(vdev, connect_req);
786*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
787*5113495bSYour Name osif_err("Connect failed with status %d", status);
788*5113495bSYour Name
789*5113495bSYour Name connect_start_fail:
790*5113495bSYour Name ucfg_cm_free_connect_req(connect_req);
791*5113495bSYour Name
792*5113495bSYour Name return qdf_status_to_os_return(status);
793*5113495bSYour Name }
794*5113495bSYour Name
osif_cm_disconnect(struct net_device * dev,struct wlan_objmgr_vdev * vdev,uint16_t reason)795*5113495bSYour Name int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
796*5113495bSYour Name uint16_t reason)
797*5113495bSYour Name {
798*5113495bSYour Name uint8_t vdev_id = wlan_vdev_get_id(vdev);
799*5113495bSYour Name QDF_STATUS status;
800*5113495bSYour Name
801*5113495bSYour Name osif_info("%s(vdevid-%d): Received Disconnect reason:%d %s",
802*5113495bSYour Name dev->name, vdev_id, reason,
803*5113495bSYour Name ucfg_cm_reason_code_to_str(reason));
804*5113495bSYour Name
805*5113495bSYour Name status = mlo_disconnect(vdev, CM_OSIF_DISCONNECT, reason, NULL);
806*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
807*5113495bSYour Name osif_err("Disconnect failed with status %d", status);
808*5113495bSYour Name
809*5113495bSYour Name return qdf_status_to_os_return(status);
810*5113495bSYour Name }
811*5113495bSYour Name
osif_cm_disconnect_sync(struct wlan_objmgr_vdev * vdev,uint16_t reason)812*5113495bSYour Name int osif_cm_disconnect_sync(struct wlan_objmgr_vdev *vdev, uint16_t reason)
813*5113495bSYour Name {
814*5113495bSYour Name uint8_t vdev_id = wlan_vdev_get_id(vdev);
815*5113495bSYour Name QDF_STATUS status;
816*5113495bSYour Name
817*5113495bSYour Name osif_info("vdevid-%d: Received Disconnect reason:%d %s",
818*5113495bSYour Name vdev_id, reason, ucfg_cm_reason_code_to_str(reason));
819*5113495bSYour Name
820*5113495bSYour Name status = mlo_sync_disconnect(vdev, CM_OSIF_DISCONNECT, reason, NULL);
821*5113495bSYour Name
822*5113495bSYour Name return qdf_status_to_os_return(status);
823*5113495bSYour Name }
824