1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2012-2015,2020-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name * Copyright (c) 2022-2024 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_roam_rsp.c
20*5113495bSYour Name *
21*5113495bSYour Name * This file maintains definitaions of roam response apis.
22*5113495bSYour Name */
23*5113495bSYour Name
24*5113495bSYour Name #include <linux/version.h>
25*5113495bSYour Name #include <linux/nl80211.h>
26*5113495bSYour Name #include <net/cfg80211.h>
27*5113495bSYour Name #include <wlan_osif_priv.h>
28*5113495bSYour Name #include "osif_cm_rsp.h"
29*5113495bSYour Name #include <osif_cm_util.h>
30*5113495bSYour Name #include <wlan_cfg80211.h>
31*5113495bSYour Name #include <wlan_cfg80211_scan.h>
32*5113495bSYour Name #include "wlan_mlo_mgr_sta.h"
33*5113495bSYour Name #include "wlan_mlo_mgr_link_switch.h"
34*5113495bSYour Name #ifdef CONN_MGR_ADV_FEATURE
35*5113495bSYour Name #include "wlan_mlme_ucfg_api.h"
36*5113495bSYour Name #endif
37*5113495bSYour Name #include "wlan_crypto_global_api.h"
38*5113495bSYour Name #include <osif_cm_req.h>
39*5113495bSYour Name
40*5113495bSYour Name #ifdef CONN_MGR_ADV_FEATURE
41*5113495bSYour Name #ifdef WLAN_FEATURE_FILS_SK
osif_update_fils_hlp_data(struct net_device * dev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)42*5113495bSYour Name static inline void osif_update_fils_hlp_data(struct net_device *dev,
43*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
44*5113495bSYour Name struct wlan_cm_connect_resp *rsp)
45*5113495bSYour Name {
46*5113495bSYour Name if (rsp->connect_ies.fils_ie && rsp->connect_ies.fils_ie->hlp_data_len)
47*5113495bSYour Name osif_cm_set_hlp_data(dev, vdev, rsp);
48*5113495bSYour Name }
49*5113495bSYour Name #else
osif_update_fils_hlp_data(struct net_device * dev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp)50*5113495bSYour Name static inline void osif_update_fils_hlp_data(struct net_device *dev,
51*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
52*5113495bSYour Name struct wlan_cm_connect_resp *rsp)
53*5113495bSYour Name {
54*5113495bSYour Name }
55*5113495bSYour Name #endif
56*5113495bSYour Name
57*5113495bSYour Name #if defined CFG80211_ROAMED_API_UNIFIED || \
58*5113495bSYour Name (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
59*5113495bSYour Name #ifdef CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT
60*5113495bSYour Name static
osif_copy_roamed_info(struct cfg80211_roam_info * info,struct cfg80211_bss * bss)61*5113495bSYour Name void osif_copy_roamed_info(struct cfg80211_roam_info *info,
62*5113495bSYour Name struct cfg80211_bss *bss)
63*5113495bSYour Name {
64*5113495bSYour Name info->links[0].bss = bss;
65*5113495bSYour Name }
66*5113495bSYour Name #else
67*5113495bSYour Name static
osif_copy_roamed_info(struct cfg80211_roam_info * info,struct cfg80211_bss * bss)68*5113495bSYour Name void osif_copy_roamed_info(struct cfg80211_roam_info *info,
69*5113495bSYour Name struct cfg80211_bss *bss)
70*5113495bSYour Name {
71*5113495bSYour Name info->bss = bss;
72*5113495bSYour Name }
73*5113495bSYour Name #endif
74*5113495bSYour Name
75*5113495bSYour Name #if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
76*5113495bSYour Name static void
osif_roam_populate_mlo_info_for_link(struct wlan_objmgr_vdev * roamed_vdev,struct cfg80211_roam_info * roam_info,uint8_t link_id,struct cfg80211_bss * bss,uint8_t * self_link_addr)77*5113495bSYour Name osif_roam_populate_mlo_info_for_link(struct wlan_objmgr_vdev *roamed_vdev,
78*5113495bSYour Name struct cfg80211_roam_info *roam_info,
79*5113495bSYour Name uint8_t link_id, struct cfg80211_bss *bss,
80*5113495bSYour Name uint8_t *self_link_addr)
81*5113495bSYour Name {
82*5113495bSYour Name if (bss) {
83*5113495bSYour Name osif_debug("Link_id :%d", link_id);
84*5113495bSYour Name roam_info->valid_links |= BIT(link_id);
85*5113495bSYour Name roam_info->links[link_id].bssid = bss->bssid;
86*5113495bSYour Name roam_info->links[link_id].bss = bss;
87*5113495bSYour Name roam_info->links[link_id].addr = self_link_addr;
88*5113495bSYour Name }
89*5113495bSYour Name
90*5113495bSYour Name mlo_mgr_osif_update_connect_info(roamed_vdev, link_id);
91*5113495bSYour Name }
92*5113495bSYour Name
93*5113495bSYour Name static void
osif_populate_partner_links_roam_mlo_params(struct wlan_objmgr_vdev * roamed_vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_roam_info * roam_info_params)94*5113495bSYour Name osif_populate_partner_links_roam_mlo_params(struct wlan_objmgr_vdev *roamed_vdev,
95*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
96*5113495bSYour Name struct cfg80211_roam_info *roam_info_params)
97*5113495bSYour Name {
98*5113495bSYour Name struct wlan_objmgr_pdev *pdev;
99*5113495bSYour Name struct mlo_link_info *rsp_partner_info;
100*5113495bSYour Name struct mlo_partner_info assoc_partner_info = {0};
101*5113495bSYour Name struct cfg80211_bss *bss = NULL;
102*5113495bSYour Name QDF_STATUS qdf_status;
103*5113495bSYour Name uint8_t link_id = 0, num_links;
104*5113495bSYour Name int i;
105*5113495bSYour Name
106*5113495bSYour Name pdev = wlan_vdev_get_pdev(roamed_vdev);
107*5113495bSYour Name if (!pdev)
108*5113495bSYour Name return;
109*5113495bSYour Name
110*5113495bSYour Name qdf_status = osif_get_partner_info_from_mlie(rsp, &assoc_partner_info);
111*5113495bSYour Name if (QDF_IS_STATUS_ERROR(qdf_status))
112*5113495bSYour Name return;
113*5113495bSYour Name
114*5113495bSYour Name num_links = rsp->ml_parnter_info.num_partner_links;
115*5113495bSYour Name for (i = 0 ; i < num_links; i++) {
116*5113495bSYour Name struct mlo_link_info *link_info;
117*5113495bSYour Name rsp_partner_info = &rsp->ml_parnter_info.partner_link_info[i];
118*5113495bSYour Name
119*5113495bSYour Name qdf_status = osif_get_link_id_from_assoc_ml_ie(rsp_partner_info,
120*5113495bSYour Name &assoc_partner_info,
121*5113495bSYour Name &link_id);
122*5113495bSYour Name if (QDF_IS_STATUS_ERROR(qdf_status))
123*5113495bSYour Name continue;
124*5113495bSYour Name
125*5113495bSYour Name link_info = mlo_mgr_get_ap_link_by_link_id(
126*5113495bSYour Name roamed_vdev->mlo_dev_ctx,
127*5113495bSYour Name link_id);
128*5113495bSYour Name if (!link_info) {
129*5113495bSYour Name osif_debug("link info not found for link_id:%d",
130*5113495bSYour Name link_id);
131*5113495bSYour Name continue;
132*5113495bSYour Name }
133*5113495bSYour Name
134*5113495bSYour Name bss = osif_get_chan_bss_from_kernel(roamed_vdev,
135*5113495bSYour Name rsp_partner_info, rsp);
136*5113495bSYour Name
137*5113495bSYour Name osif_roam_populate_mlo_info_for_link(roamed_vdev,
138*5113495bSYour Name roam_info_params,
139*5113495bSYour Name link_id, bss,
140*5113495bSYour Name link_info->link_addr.bytes);
141*5113495bSYour Name }
142*5113495bSYour Name }
143*5113495bSYour Name
144*5113495bSYour Name static QDF_STATUS
osif_fill_peer_mld_mac_roam_info(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_roam_info * roam_info_params)145*5113495bSYour Name osif_fill_peer_mld_mac_roam_info(struct wlan_objmgr_vdev *vdev,
146*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
147*5113495bSYour Name struct cfg80211_roam_info *roam_info_params)
148*5113495bSYour Name {
149*5113495bSYour Name struct wlan_objmgr_peer *peer_obj;
150*5113495bSYour Name
151*5113495bSYour Name peer_obj = wlan_objmgr_get_peer_by_mac(wlan_vdev_get_psoc(vdev),
152*5113495bSYour Name rsp->bssid.bytes, WLAN_OSIF_ID);
153*5113495bSYour Name if (!peer_obj)
154*5113495bSYour Name return QDF_STATUS_E_INVAL;
155*5113495bSYour Name
156*5113495bSYour Name roam_info_params->ap_mld_addr = wlan_peer_mlme_get_mldaddr(peer_obj);
157*5113495bSYour Name
158*5113495bSYour Name wlan_objmgr_peer_release_ref(peer_obj, WLAN_OSIF_ID);
159*5113495bSYour Name
160*5113495bSYour Name return QDF_STATUS_SUCCESS;
161*5113495bSYour Name }
162*5113495bSYour Name
osif_fill_mlo_roam_params(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,struct cfg80211_roam_info * info)163*5113495bSYour Name static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev,
164*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
165*5113495bSYour Name struct cfg80211_bss *bss,
166*5113495bSYour Name struct cfg80211_roam_info *info)
167*5113495bSYour Name {
168*5113495bSYour Name QDF_STATUS qdf_status;
169*5113495bSYour Name uint8_t assoc_link_id;
170*5113495bSYour Name
171*5113495bSYour Name if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
172*5113495bSYour Name return;
173*5113495bSYour Name
174*5113495bSYour Name qdf_status = osif_fill_peer_mld_mac_roam_info(vdev, rsp,
175*5113495bSYour Name info);
176*5113495bSYour Name if (QDF_IS_STATUS_ERROR(qdf_status)) {
177*5113495bSYour Name osif_err("Unable to fill peer mld address: %d", qdf_status);
178*5113495bSYour Name return;
179*5113495bSYour Name }
180*5113495bSYour Name
181*5113495bSYour Name assoc_link_id = wlan_vdev_get_link_id(vdev);
182*5113495bSYour Name osif_roam_populate_mlo_info_for_link(vdev, info,
183*5113495bSYour Name assoc_link_id, bss,
184*5113495bSYour Name wlan_vdev_mlme_get_macaddr(vdev));
185*5113495bSYour Name
186*5113495bSYour Name osif_populate_partner_links_roam_mlo_params(vdev, rsp, info);
187*5113495bSYour Name }
188*5113495bSYour Name #else
osif_fill_mlo_roam_params(struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,struct cfg80211_roam_info * info)189*5113495bSYour Name static void osif_fill_mlo_roam_params(struct wlan_objmgr_vdev *vdev,
190*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
191*5113495bSYour Name struct cfg80211_bss *bss,
192*5113495bSYour Name struct cfg80211_roam_info *info)
193*5113495bSYour Name {}
194*5113495bSYour Name #endif
195*5113495bSYour Name /**
196*5113495bSYour Name * osif_roamed_ind() - send roamed indication to cfg80211
197*5113495bSYour Name * @dev: network device
198*5113495bSYour Name * @vdev: vdev object
199*5113495bSYour Name * @rsp: CM connect response
200*5113495bSYour Name * @bss: cfg80211 roamed bss pointer
201*5113495bSYour Name * @req_ie: IEs used in reassociation request
202*5113495bSYour Name * @req_ie_len: Length of the @req_ie
203*5113495bSYour Name * @resp_ie: IEs received in successful reassociation response
204*5113495bSYour Name * @resp_ie_len: Length of @resp_ie
205*5113495bSYour Name *
206*5113495bSYour Name * Return: none
207*5113495bSYour Name */
osif_roamed_ind(struct net_device * dev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,const uint8_t * req_ie,size_t req_ie_len,const uint8_t * resp_ie,size_t resp_ie_len)208*5113495bSYour Name static void osif_roamed_ind(struct net_device *dev,
209*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
210*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
211*5113495bSYour Name struct cfg80211_bss *bss,
212*5113495bSYour Name const uint8_t *req_ie,
213*5113495bSYour Name size_t req_ie_len, const uint8_t *resp_ie,
214*5113495bSYour Name size_t resp_ie_len)
215*5113495bSYour Name {
216*5113495bSYour Name struct cfg80211_roam_info info = {0};
217*5113495bSYour Name
218*5113495bSYour Name osif_copy_roamed_info(&info, bss);
219*5113495bSYour Name info.req_ie = req_ie;
220*5113495bSYour Name info.req_ie_len = req_ie_len;
221*5113495bSYour Name info.resp_ie = resp_ie;
222*5113495bSYour Name info.resp_ie_len = resp_ie_len;
223*5113495bSYour Name osif_fill_mlo_roam_params(vdev, rsp, bss, &info);
224*5113495bSYour Name cfg80211_roamed(dev, &info, qdf_mem_malloc_flags());
225*5113495bSYour Name }
226*5113495bSYour Name #else
osif_roamed_ind(struct net_device * dev,struct wlan_objmgr_vdev * vdev,struct wlan_cm_connect_resp * rsp,struct cfg80211_bss * bss,const uint8_t * req_ie,size_t req_ie_len,const uint8_t * resp_ie,size_t resp_ie_len)227*5113495bSYour Name static inline void osif_roamed_ind(struct net_device *dev,
228*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
229*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
230*5113495bSYour Name struct cfg80211_bss *bss,
231*5113495bSYour Name const uint8_t *req_ie,
232*5113495bSYour Name size_t req_ie_len, const uint8_t *resp_ie,
233*5113495bSYour Name size_t resp_ie_len)
234*5113495bSYour Name
235*5113495bSYour Name {
236*5113495bSYour Name cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie, resp_ie_len,
237*5113495bSYour Name qdf_mem_malloc_flags());
238*5113495bSYour Name }
239*5113495bSYour Name #endif
240*5113495bSYour Name
241*5113495bSYour Name #ifdef WLAN_FEATURE_ROAM_OFFLOAD
242*5113495bSYour Name #ifdef WLAN_FEATURE_FILS_SK
243*5113495bSYour Name /**
244*5113495bSYour Name * osif_add_fils_params_roam_auth_event() - Adds FILS params in roam auth
245*5113495bSYour Name * @skb: SK buffer
246*5113495bSYour Name * @roam_info: Roam info
247*5113495bSYour Name *
248*5113495bSYour Name * API adds fils params[pmk, pmkid, next sequence number] to roam auth event
249*5113495bSYour Name *
250*5113495bSYour Name * Return: zero on success, error code on failure
251*5113495bSYour Name */
252*5113495bSYour Name static int
osif_add_fils_params_roam_auth_event(struct sk_buff * skb,struct wlan_roam_sync_info * roam_info)253*5113495bSYour Name osif_add_fils_params_roam_auth_event(struct sk_buff *skb,
254*5113495bSYour Name struct wlan_roam_sync_info *roam_info)
255*5113495bSYour Name {
256*5113495bSYour Name if (roam_info->pmk_len &&
257*5113495bSYour Name nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK,
258*5113495bSYour Name roam_info->pmk_len, roam_info->pmk)) {
259*5113495bSYour Name osif_err("pmk send fail");
260*5113495bSYour Name return -EINVAL;
261*5113495bSYour Name }
262*5113495bSYour Name
263*5113495bSYour Name if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID,
264*5113495bSYour Name PMKID_LEN, roam_info->pmkid)) {
265*5113495bSYour Name osif_err("pmkid send fail");
266*5113495bSYour Name return -EINVAL;
267*5113495bSYour Name }
268*5113495bSYour Name
269*5113495bSYour Name osif_debug("Update ERP Seq Num %d, Next ERP Seq Num %d",
270*5113495bSYour Name roam_info->update_erp_next_seq_num,
271*5113495bSYour Name roam_info->next_erp_seq_num);
272*5113495bSYour Name if (roam_info->update_erp_next_seq_num &&
273*5113495bSYour Name nla_put_u16(skb,
274*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM,
275*5113495bSYour Name roam_info->next_erp_seq_num)) {
276*5113495bSYour Name osif_err("ERP seq num send fail");
277*5113495bSYour Name return -EINVAL;
278*5113495bSYour Name }
279*5113495bSYour Name
280*5113495bSYour Name return 0;
281*5113495bSYour Name }
282*5113495bSYour Name #else
283*5113495bSYour Name static inline int
osif_add_fils_params_roam_auth_event(struct sk_buff * skb,struct wlan_roam_sync_info * roam_info)284*5113495bSYour Name osif_add_fils_params_roam_auth_event(struct sk_buff *skb,
285*5113495bSYour Name struct wlan_roam_sync_info *roam_info)
286*5113495bSYour Name {
287*5113495bSYour Name return 0;
288*5113495bSYour Name }
289*5113495bSYour Name #endif
290*5113495bSYour Name
291*5113495bSYour Name /**
292*5113495bSYour Name * osif_get_roam_reason() - convert wmi roam reason to
293*5113495bSYour Name * enum qca_roam_reason
294*5113495bSYour Name * @roam_scan_trigger: wmi roam scan trigger ID
295*5113495bSYour Name *
296*5113495bSYour Name * Return: Meaningful qca_roam_reason from enum WMI_ROAM_TRIGGER_REASON_ID
297*5113495bSYour Name */
osif_get_roam_reason(uint16_t roam_scan_trigger)298*5113495bSYour Name static enum qca_roam_reason osif_get_roam_reason(uint16_t roam_scan_trigger)
299*5113495bSYour Name {
300*5113495bSYour Name switch (roam_scan_trigger) {
301*5113495bSYour Name case ROAM_TRIGGER_REASON_PER:
302*5113495bSYour Name return QCA_ROAM_REASON_PER;
303*5113495bSYour Name case ROAM_TRIGGER_REASON_BMISS:
304*5113495bSYour Name return QCA_ROAM_REASON_BEACON_MISS;
305*5113495bSYour Name case ROAM_TRIGGER_REASON_LOW_RSSI:
306*5113495bSYour Name case ROAM_TRIGGER_REASON_BACKGROUND:
307*5113495bSYour Name return QCA_ROAM_REASON_POOR_RSSI;
308*5113495bSYour Name case ROAM_TRIGGER_REASON_HIGH_RSSI:
309*5113495bSYour Name return QCA_ROAM_REASON_BETTER_RSSI;
310*5113495bSYour Name case ROAM_TRIGGER_REASON_DENSE:
311*5113495bSYour Name return QCA_ROAM_REASON_CONGESTION;
312*5113495bSYour Name case ROAM_TRIGGER_REASON_FORCED:
313*5113495bSYour Name return QCA_ROAM_REASON_USER_TRIGGER;
314*5113495bSYour Name case ROAM_TRIGGER_REASON_BTM:
315*5113495bSYour Name return QCA_ROAM_REASON_BTM;
316*5113495bSYour Name case ROAM_TRIGGER_REASON_BSS_LOAD:
317*5113495bSYour Name return QCA_ROAM_REASON_BSS_LOAD;
318*5113495bSYour Name default:
319*5113495bSYour Name return QCA_ROAM_REASON_UNKNOWN;
320*5113495bSYour Name }
321*5113495bSYour Name
322*5113495bSYour Name return QCA_ROAM_REASON_UNKNOWN;
323*5113495bSYour Name }
324*5113495bSYour Name
325*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
326*5113495bSYour Name
osif_get_bss_mac_addr(struct wlan_objmgr_vdev * vdev)327*5113495bSYour Name static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev)
328*5113495bSYour Name {
329*5113495bSYour Name struct wlan_objmgr_peer *peer;
330*5113495bSYour Name
331*5113495bSYour Name peer = wlan_vdev_get_bsspeer(vdev);
332*5113495bSYour Name if (peer)
333*5113495bSYour Name if (wlan_vdev_mlme_is_mlo_vdev(vdev))
334*5113495bSYour Name return wlan_peer_mlme_get_mldaddr(peer);
335*5113495bSYour Name else
336*5113495bSYour Name return wlan_peer_get_macaddr(peer);
337*5113495bSYour Name else
338*5113495bSYour Name return NULL;
339*5113495bSYour Name }
340*5113495bSYour Name
341*5113495bSYour Name /**
342*5113495bSYour Name * osif_send_roam_auth_mlo_links_event() - API to send roam auth mlo
343*5113495bSYour Name * links event response to kernel
344*5113495bSYour Name * @skb : sk buffer pointer
345*5113495bSYour Name * @vdev: vdev pointer
346*5113495bSYour Name * @osif_priv: osif vdev private data
347*5113495bSYour Name * @rsp: Connection manager response
348*5113495bSYour Name *
349*5113495bSYour Name * This is called when wlan driver needs to send the mlo links roaming
350*5113495bSYour Name * information after roaming.
351*5113495bSYour Name *
352*5113495bSYour Name * Context: Any context.
353*5113495bSYour Name * Return: int
354*5113495bSYour Name */
355*5113495bSYour Name static int
osif_send_roam_auth_mlo_links_event(struct sk_buff * skb,struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)356*5113495bSYour Name osif_send_roam_auth_mlo_links_event(struct sk_buff *skb,
357*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
358*5113495bSYour Name struct vdev_osif_priv *osif_priv,
359*5113495bSYour Name struct wlan_cm_connect_resp *rsp)
360*5113495bSYour Name {
361*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
362*5113495bSYour Name bool roam_offload_enable;
363*5113495bSYour Name uint8_t i;
364*5113495bSYour Name struct nlattr *mlo_links;
365*5113495bSYour Name struct nlattr *mlo_links_info;
366*5113495bSYour Name struct wlan_objmgr_vdev *link_vdev;
367*5113495bSYour Name uint8_t link_vdev_id, link_id;
368*5113495bSYour Name struct qdf_mac_addr link_addr;
369*5113495bSYour Name
370*5113495bSYour Name if (!vdev)
371*5113495bSYour Name return -EINVAL;
372*5113495bSYour Name
373*5113495bSYour Name psoc = wlan_vdev_get_psoc(vdev);
374*5113495bSYour Name ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable);
375*5113495bSYour Name
376*5113495bSYour Name if (!roam_offload_enable)
377*5113495bSYour Name return -EINVAL;
378*5113495bSYour Name
379*5113495bSYour Name mlo_links = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MLO_LINKS);
380*5113495bSYour Name if (!mlo_links) {
381*5113495bSYour Name osif_err("nla_nest_start error");
382*5113495bSYour Name return -EINVAL;
383*5113495bSYour Name }
384*5113495bSYour Name
385*5113495bSYour Name for (i = 0; i < rsp->ml_parnter_info.num_partner_links; i++) {
386*5113495bSYour Name mlo_links_info = nla_nest_start(skb, i);
387*5113495bSYour Name if (!mlo_links_info) {
388*5113495bSYour Name osif_err("nla nest start fail");
389*5113495bSYour Name return -EINVAL;
390*5113495bSYour Name }
391*5113495bSYour Name
392*5113495bSYour Name osif_debug("send roam auth for partner link:%d",
393*5113495bSYour Name rsp->ml_parnter_info.partner_link_info[i].link_id);
394*5113495bSYour Name if (nla_put_u8(skb,
395*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID,
396*5113495bSYour Name rsp->ml_parnter_info.partner_link_info[i].link_id)) {
397*5113495bSYour Name osif_err("nla put fail");
398*5113495bSYour Name return -EINVAL;
399*5113495bSYour Name }
400*5113495bSYour Name
401*5113495bSYour Name if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_BSSID,
402*5113495bSYour Name ETH_ALEN,
403*5113495bSYour Name (void *)&rsp->ml_parnter_info.partner_link_info[i].link_addr)) {
404*5113495bSYour Name osif_err("nla put fail");
405*5113495bSYour Name return -EINVAL;
406*5113495bSYour Name }
407*5113495bSYour Name
408*5113495bSYour Name link_vdev_id =
409*5113495bSYour Name rsp->ml_parnter_info.partner_link_info[i].vdev_id;
410*5113495bSYour Name link_id = rsp->ml_parnter_info.partner_link_info[i].link_id;
411*5113495bSYour Name
412*5113495bSYour Name /* Standby link */
413*5113495bSYour Name if (link_vdev_id == WLAN_INVALID_VDEV_ID) {
414*5113495bSYour Name struct mlo_link_info *standby_info =
415*5113495bSYour Name mlo_mgr_get_ap_link_by_link_id(
416*5113495bSYour Name vdev->mlo_dev_ctx,
417*5113495bSYour Name link_id);
418*5113495bSYour Name if (standby_info) {
419*5113495bSYour Name link_addr = standby_info->link_addr;
420*5113495bSYour Name } else {
421*5113495bSYour Name osif_err("link addr is null for id:%d",
422*5113495bSYour Name link_id);
423*5113495bSYour Name return -EINVAL;
424*5113495bSYour Name }
425*5113495bSYour Name } else {
426*5113495bSYour Name link_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
427*5113495bSYour Name psoc, link_vdev_id,
428*5113495bSYour Name WLAN_OSIF_CM_ID);
429*5113495bSYour Name if (!link_vdev) {
430*5113495bSYour Name osif_err("link vdev is null");
431*5113495bSYour Name return -EINVAL;
432*5113495bSYour Name }
433*5113495bSYour Name
434*5113495bSYour Name qdf_copy_macaddr(&link_addr,
435*5113495bSYour Name (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(link_vdev));
436*5113495bSYour Name wlan_objmgr_vdev_release_ref(link_vdev,
437*5113495bSYour Name WLAN_OSIF_CM_ID);
438*5113495bSYour Name }
439*5113495bSYour Name
440*5113495bSYour Name if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_MLO_LINK_MAC_ADDR,
441*5113495bSYour Name ETH_ALEN, link_addr.bytes)) {
442*5113495bSYour Name osif_err("nla put fail");
443*5113495bSYour Name return -EINVAL;
444*5113495bSYour Name }
445*5113495bSYour Name nla_nest_end(skb, mlo_links_info);
446*5113495bSYour Name }
447*5113495bSYour Name
448*5113495bSYour Name nla_nest_end(skb, mlo_links);
449*5113495bSYour Name
450*5113495bSYour Name return 0;
451*5113495bSYour Name }
452*5113495bSYour Name #else
osif_get_bss_mac_addr(struct wlan_objmgr_vdev * vdev)453*5113495bSYour Name static uint8_t *osif_get_bss_mac_addr(struct wlan_objmgr_vdev *vdev)
454*5113495bSYour Name {
455*5113495bSYour Name struct wlan_objmgr_peer *peer;
456*5113495bSYour Name
457*5113495bSYour Name peer = wlan_vdev_get_bsspeer(vdev);
458*5113495bSYour Name if (peer)
459*5113495bSYour Name return wlan_peer_get_macaddr(peer);
460*5113495bSYour Name else
461*5113495bSYour Name return NULL;
462*5113495bSYour Name }
463*5113495bSYour Name
464*5113495bSYour Name static inline int
osif_send_roam_auth_mlo_links_event(struct sk_buff * skb,struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)465*5113495bSYour Name osif_send_roam_auth_mlo_links_event(struct sk_buff *skb,
466*5113495bSYour Name struct wlan_objmgr_vdev *vdev,
467*5113495bSYour Name struct vdev_osif_priv *osif_priv,
468*5113495bSYour Name struct wlan_cm_connect_resp *rsp)
469*5113495bSYour Name {
470*5113495bSYour Name return 0;
471*5113495bSYour Name }
472*5113495bSYour Name #endif
473*5113495bSYour Name
474*5113495bSYour Name /**
475*5113495bSYour Name * osif_send_roam_auth_event() - API to send roam auth event response to kernel
476*5113495bSYour Name * @vdev: vdev pointer
477*5113495bSYour Name * @osif_priv: OS private structure of vdev
478*5113495bSYour Name * @rsp: Connection manager response
479*5113495bSYour Name * @req_ie: request IE
480*5113495bSYour Name * @req_ie_len: request IE length
481*5113495bSYour Name * @resp_ie: response IE
482*5113495bSYour Name * @resp_ie_len: response IE length
483*5113495bSYour Name *
484*5113495bSYour Name * This is called when wlan driver needs to send the roaming and
485*5113495bSYour Name * authorization information after roaming.
486*5113495bSYour Name *
487*5113495bSYour Name * The information that would be sent is the request RSN IE, response
488*5113495bSYour Name * RSN IE and BSSID of the newly roamed AP.
489*5113495bSYour Name *
490*5113495bSYour Name * If the Authorized status is authenticated, then additional parameters
491*5113495bSYour Name * like PTK's KCK and KEK and Replay Counter would also be passed to the
492*5113495bSYour Name * supplicant.
493*5113495bSYour Name *
494*5113495bSYour Name * The supplicant upon receiving this event would ignore the legacy
495*5113495bSYour Name * cfg80211_roamed call and use the entire information from this event.
496*5113495bSYour Name * The cfg80211_roamed should still co-exist since the kernel will
497*5113495bSYour Name * make use of the parameters even if the supplicant ignores it.
498*5113495bSYour Name *
499*5113495bSYour Name *
500*5113495bSYour Name * Context: Any context.
501*5113495bSYour Name * Return: int
502*5113495bSYour Name */
osif_send_roam_auth_event(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp,const uint8_t * req_ie,size_t req_ie_len,const uint8_t * resp_ie,size_t resp_ie_len)503*5113495bSYour Name static int osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev,
504*5113495bSYour Name struct vdev_osif_priv *osif_priv,
505*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
506*5113495bSYour Name const uint8_t *req_ie,
507*5113495bSYour Name size_t req_ie_len, const uint8_t *resp_ie,
508*5113495bSYour Name size_t resp_ie_len)
509*5113495bSYour Name {
510*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
511*5113495bSYour Name uint32_t fils_params_len;
512*5113495bSYour Name struct sk_buff *skb = NULL;
513*5113495bSYour Name struct wlan_roam_sync_info *roaming_info;
514*5113495bSYour Name int status;
515*5113495bSYour Name int32_t akm;
516*5113495bSYour Name bool roam_offload_enable;
517*5113495bSYour Name uint8_t *bss_mac_addr;
518*5113495bSYour Name uint8_t num_of_links = 0;
519*5113495bSYour Name
520*5113495bSYour Name psoc = wlan_vdev_get_psoc(vdev);
521*5113495bSYour Name ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable);
522*5113495bSYour Name
523*5113495bSYour Name if (!roam_offload_enable)
524*5113495bSYour Name return 0;
525*5113495bSYour Name
526*5113495bSYour Name roaming_info = rsp->roaming_info;
527*5113495bSYour Name
528*5113495bSYour Name /*
529*5113495bSYour Name * PMK is sent from FW in Roam Synch Event for FILS Roaming.
530*5113495bSYour Name * In that case, add three more NL attributes.ie. PMK, PMKID
531*5113495bSYour Name * and ERP next sequence number. Add corresponding lengths
532*5113495bSYour Name * with 3 extra NL message headers for each of the
533*5113495bSYour Name * aforementioned params.
534*5113495bSYour Name */
535*5113495bSYour Name fils_params_len = roaming_info->pmk_len + PMKID_LEN +
536*5113495bSYour Name sizeof(uint16_t) + (3 * NLMSG_HDRLEN);
537*5113495bSYour Name
538*5113495bSYour Name if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
539*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
540*5113495bSYour Name num_of_links = rsp->ml_parnter_info.num_partner_links;
541*5113495bSYour Name #endif
542*5113495bSYour Name skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
543*5113495bSYour Name osif_priv->wdev,
544*5113495bSYour Name (ETH_ALEN * num_of_links) +
545*5113495bSYour Name (sizeof(uint8_t) * num_of_links) +
546*5113495bSYour Name (ETH_ALEN * num_of_links) +
547*5113495bSYour Name req_ie_len + resp_ie_len +
548*5113495bSYour Name sizeof(uint8_t) + REPLAY_CTR_LEN +
549*5113495bSYour Name roaming_info->kck_len + roaming_info->kek_len +
550*5113495bSYour Name sizeof(uint16_t) + sizeof(uint8_t) +
551*5113495bSYour Name (9 * NLMSG_HDRLEN) + fils_params_len,
552*5113495bSYour Name QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
553*5113495bSYour Name qdf_mem_malloc_flags());
554*5113495bSYour Name } else {
555*5113495bSYour Name skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
556*5113495bSYour Name osif_priv->wdev,
557*5113495bSYour Name ETH_ALEN + req_ie_len +
558*5113495bSYour Name resp_ie_len +
559*5113495bSYour Name sizeof(uint8_t) + REPLAY_CTR_LEN +
560*5113495bSYour Name roaming_info->kck_len + roaming_info->kek_len +
561*5113495bSYour Name sizeof(uint16_t) + sizeof(uint8_t) +
562*5113495bSYour Name (9 * NLMSG_HDRLEN) + fils_params_len,
563*5113495bSYour Name QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
564*5113495bSYour Name qdf_mem_malloc_flags());
565*5113495bSYour Name }
566*5113495bSYour Name if (!skb) {
567*5113495bSYour Name osif_err("cfg80211_vendor_event_alloc failed");
568*5113495bSYour Name return -1;
569*5113495bSYour Name }
570*5113495bSYour Name
571*5113495bSYour Name bss_mac_addr = osif_get_bss_mac_addr(vdev);
572*5113495bSYour Name if (!bss_mac_addr) {
573*5113495bSYour Name osif_err("Invalid bss mac addr");
574*5113495bSYour Name goto nla_put_failure;
575*5113495bSYour Name }
576*5113495bSYour Name if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
577*5113495bSYour Name ETH_ALEN, bss_mac_addr) ||
578*5113495bSYour Name nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
579*5113495bSYour Name req_ie_len, req_ie) ||
580*5113495bSYour Name nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
581*5113495bSYour Name resp_ie_len, resp_ie)) {
582*5113495bSYour Name osif_err("nla put fail");
583*5113495bSYour Name goto nla_put_failure;
584*5113495bSYour Name }
585*5113495bSYour Name
586*5113495bSYour Name if (roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED) {
587*5113495bSYour Name osif_debug("Include Auth Params TLV's");
588*5113495bSYour Name if (nla_put_u8(skb,
589*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
590*5113495bSYour Name true)) {
591*5113495bSYour Name osif_err("nla put fail");
592*5113495bSYour Name goto nla_put_failure;
593*5113495bSYour Name }
594*5113495bSYour Name akm = wlan_crypto_get_param(vdev,
595*5113495bSYour Name WLAN_CRYPTO_PARAM_KEY_MGMT);
596*5113495bSYour Name /* if FT or CCKM connection: dont send replay counter */
597*5113495bSYour Name if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) &&
598*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK) &&
599*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) &&
600*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) &&
601*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM) &&
602*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE_EXT_KEY) &&
603*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA256) &&
604*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_FILS_SHA384) &&
605*5113495bSYour Name !QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_PSK_SHA384) &&
606*5113495bSYour Name nla_put(skb,
607*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
608*5113495bSYour Name REPLAY_CTR_LEN,
609*5113495bSYour Name roaming_info->replay_ctr)) {
610*5113495bSYour Name osif_err("non FT/non CCKM connection");
611*5113495bSYour Name osif_err("failed to send replay counter");
612*5113495bSYour Name goto nla_put_failure;
613*5113495bSYour Name }
614*5113495bSYour Name if (roaming_info->kek_len > MAX_KEK_LENGTH ||
615*5113495bSYour Name roaming_info->kck_len > MAX_KCK_LEN ||
616*5113495bSYour Name nla_put(skb,
617*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
618*5113495bSYour Name roaming_info->kck_len, roaming_info->kck) ||
619*5113495bSYour Name nla_put(skb,
620*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
621*5113495bSYour Name roaming_info->kek_len, roaming_info->kek)) {
622*5113495bSYour Name osif_err("nla put fail, kek_len %d",
623*5113495bSYour Name roaming_info->kek_len);
624*5113495bSYour Name goto nla_put_failure;
625*5113495bSYour Name }
626*5113495bSYour Name
627*5113495bSYour Name if (nla_put_u16(skb,
628*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON,
629*5113495bSYour Name osif_get_roam_reason(roaming_info->roam_reason))) {
630*5113495bSYour Name osif_err("roam reason send failure");
631*5113495bSYour Name goto nla_put_failure;
632*5113495bSYour Name }
633*5113495bSYour Name
634*5113495bSYour Name status = osif_add_fils_params_roam_auth_event(skb,
635*5113495bSYour Name roaming_info);
636*5113495bSYour Name if (status)
637*5113495bSYour Name goto nla_put_failure;
638*5113495bSYour Name /*
639*5113495bSYour Name * Save the gtk rekey parameters in HDD STA context. They will
640*5113495bSYour Name * be used next time when host enables GTK offload and goes
641*5113495bSYour Name * into power save state.
642*5113495bSYour Name */
643*5113495bSYour Name osif_cm_save_gtk(vdev, rsp);
644*5113495bSYour Name osif_debug("replay_ctr 0x%llx kck %d kek %d",
645*5113495bSYour Name *((uint64_t *)roaming_info->replay_ctr),
646*5113495bSYour Name roaming_info->kck_len,
647*5113495bSYour Name roaming_info->kek_len);
648*5113495bSYour Name
649*5113495bSYour Name } else {
650*5113495bSYour Name osif_debug("No Auth Params TLV's");
651*5113495bSYour Name if (nla_put_u8(skb,
652*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
653*5113495bSYour Name false)) {
654*5113495bSYour Name osif_err("nla put fail");
655*5113495bSYour Name goto nla_put_failure;
656*5113495bSYour Name }
657*5113495bSYour Name }
658*5113495bSYour Name
659*5113495bSYour Name osif_debug("Auth Status = %d Subnet Change Status = %d",
660*5113495bSYour Name roaming_info->auth_status,
661*5113495bSYour Name roaming_info->subnet_change_status);
662*5113495bSYour Name /*
663*5113495bSYour Name * Add subnet change status if subnet has changed
664*5113495bSYour Name * 0 = unchanged
665*5113495bSYour Name * 1 = changed
666*5113495bSYour Name * 2 = unknown
667*5113495bSYour Name */
668*5113495bSYour Name if (roaming_info->subnet_change_status) {
669*5113495bSYour Name if (nla_put_u8(skb,
670*5113495bSYour Name QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS,
671*5113495bSYour Name roaming_info->subnet_change_status)) {
672*5113495bSYour Name osif_err("nla put fail");
673*5113495bSYour Name goto nla_put_failure;
674*5113495bSYour Name }
675*5113495bSYour Name }
676*5113495bSYour Name
677*5113495bSYour Name if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
678*5113495bSYour Name status = osif_send_roam_auth_mlo_links_event(skb, vdev,
679*5113495bSYour Name osif_priv,
680*5113495bSYour Name rsp);
681*5113495bSYour Name if (status) {
682*5113495bSYour Name osif_err("Send mlo link fail");
683*5113495bSYour Name goto nla_put_failure;
684*5113495bSYour Name }
685*5113495bSYour Name }
686*5113495bSYour Name cfg80211_vendor_event(skb, qdf_mem_malloc_flags());
687*5113495bSYour Name return 0;
688*5113495bSYour Name
689*5113495bSYour Name nla_put_failure:
690*5113495bSYour Name kfree_skb(skb);
691*5113495bSYour Name return -1;
692*5113495bSYour Name }
693*5113495bSYour Name #else
694*5113495bSYour Name static inline int
osif_send_roam_auth_event(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp,const uint8_t * req_ie,size_t req_ie_len,const uint8_t * resp_ie,size_t resp_ie_len)695*5113495bSYour Name osif_send_roam_auth_event(struct wlan_objmgr_vdev *vdev,
696*5113495bSYour Name struct vdev_osif_priv *osif_priv,
697*5113495bSYour Name struct wlan_cm_connect_resp *rsp,
698*5113495bSYour Name const uint8_t *req_ie,
699*5113495bSYour Name size_t req_ie_len, const uint8_t *resp_ie,
700*5113495bSYour Name size_t resp_ie_len)
701*5113495bSYour Name {
702*5113495bSYour Name return 0;
703*5113495bSYour Name }
704*5113495bSYour Name #endif
705*5113495bSYour Name
osif_cm_get_reassoc_req_ie_data(struct element_info * assoc_req,size_t * ie_data_len,const uint8_t ** ie_data_ptr)706*5113495bSYour Name static void osif_cm_get_reassoc_req_ie_data(struct element_info *assoc_req,
707*5113495bSYour Name size_t *ie_data_len,
708*5113495bSYour Name const uint8_t **ie_data_ptr)
709*5113495bSYour Name {
710*5113495bSYour Name /* Validate IE and length */
711*5113495bSYour Name if (!assoc_req->len || !assoc_req->ptr ||
712*5113495bSYour Name assoc_req->len <= WLAN_REASSOC_REQ_IES_OFFSET)
713*5113495bSYour Name return;
714*5113495bSYour Name
715*5113495bSYour Name *ie_data_len = assoc_req->len - WLAN_REASSOC_REQ_IES_OFFSET;
716*5113495bSYour Name *ie_data_ptr = assoc_req->ptr + WLAN_REASSOC_REQ_IES_OFFSET;
717*5113495bSYour Name }
718*5113495bSYour Name
osif_indicate_reassoc_results(struct wlan_objmgr_vdev * vdev,struct vdev_osif_priv * osif_priv,struct wlan_cm_connect_resp * rsp)719*5113495bSYour Name void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
720*5113495bSYour Name struct vdev_osif_priv *osif_priv,
721*5113495bSYour Name struct wlan_cm_connect_resp *rsp)
722*5113495bSYour Name {
723*5113495bSYour Name struct net_device *dev = osif_priv->wdev->netdev;
724*5113495bSYour Name size_t req_len = 0;
725*5113495bSYour Name const uint8_t *req_ie = NULL;
726*5113495bSYour Name size_t rsp_len = 0;
727*5113495bSYour Name const uint8_t *rsp_ie = NULL;
728*5113495bSYour Name struct cfg80211_bss *bss;
729*5113495bSYour Name struct ieee80211_channel *chan;
730*5113495bSYour Name struct wlan_objmgr_psoc *psoc;
731*5113495bSYour Name QDF_STATUS status;
732*5113495bSYour Name
733*5113495bSYour Name if (wlan_vdev_mlme_is_mlo_vdev(vdev) &&
734*5113495bSYour Name wlan_vdev_mlme_is_mlo_link_vdev(vdev))
735*5113495bSYour Name return;
736*5113495bSYour Name
737*5113495bSYour Name if (QDF_IS_STATUS_ERROR(rsp->connect_status))
738*5113495bSYour Name return;
739*5113495bSYour Name
740*5113495bSYour Name psoc = wlan_vdev_get_psoc(vdev);
741*5113495bSYour Name if (!psoc)
742*5113495bSYour Name return;
743*5113495bSYour Name
744*5113495bSYour Name chan = ieee80211_get_channel(osif_priv->wdev->wiphy, rsp->freq);
745*5113495bSYour Name
746*5113495bSYour Name bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
747*5113495bSYour Name rsp->bssid.bytes, rsp->ssid.ssid,
748*5113495bSYour Name rsp->ssid.length);
749*5113495bSYour Name if (!bss) {
750*5113495bSYour Name osif_warn("BSS "QDF_MAC_ADDR_FMT" is null, issue disconnect",
751*5113495bSYour Name QDF_MAC_ADDR_REF(rsp->bssid.bytes));
752*5113495bSYour Name goto issue_disconnect;
753*5113495bSYour Name }
754*5113495bSYour Name
755*5113495bSYour Name if (rsp->is_assoc)
756*5113495bSYour Name osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
757*5113495bSYour Name &req_len, &req_ie);
758*5113495bSYour Name else
759*5113495bSYour Name osif_cm_get_reassoc_req_ie_data(&rsp->connect_ies.assoc_req,
760*5113495bSYour Name &req_len, &req_ie);
761*5113495bSYour Name osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
762*5113495bSYour Name &rsp_len, &rsp_ie);
763*5113495bSYour Name osif_roamed_ind(dev, vdev, rsp, bss, req_ie, req_len, rsp_ie, rsp_len);
764*5113495bSYour Name osif_send_roam_auth_event(vdev, osif_priv, rsp, req_ie, req_len, rsp_ie,
765*5113495bSYour Name rsp_len);
766*5113495bSYour Name
767*5113495bSYour Name osif_update_fils_hlp_data(dev, vdev, rsp);
768*5113495bSYour Name return;
769*5113495bSYour Name
770*5113495bSYour Name issue_disconnect:
771*5113495bSYour Name status = osif_cm_disconnect(dev, vdev, REASON_UNSPEC_FAILURE);
772*5113495bSYour Name if (QDF_IS_STATUS_ERROR(status))
773*5113495bSYour Name osif_err("Disconnect failed with status %d", status);
774*5113495bSYour Name }
775*5113495bSYour Name
776*5113495bSYour Name QDF_STATUS
osif_pmksa_candidate_notify(struct wlan_objmgr_vdev * vdev,struct qdf_mac_addr * bssid,int index,bool preauth)777*5113495bSYour Name osif_pmksa_candidate_notify(struct wlan_objmgr_vdev *vdev,
778*5113495bSYour Name struct qdf_mac_addr *bssid,
779*5113495bSYour Name int index, bool preauth)
780*5113495bSYour Name {
781*5113495bSYour Name struct vdev_osif_priv *osif_priv = wlan_vdev_get_ospriv(vdev);
782*5113495bSYour Name struct wireless_dev *wdev;
783*5113495bSYour Name
784*5113495bSYour Name if (!osif_priv) {
785*5113495bSYour Name osif_err("Invalid vdev osif priv");
786*5113495bSYour Name return QDF_STATUS_E_INVAL;
787*5113495bSYour Name }
788*5113495bSYour Name
789*5113495bSYour Name wdev = osif_priv->wdev;
790*5113495bSYour Name if (!wdev) {
791*5113495bSYour Name osif_err("wdev is null");
792*5113495bSYour Name return QDF_STATUS_E_INVAL;
793*5113495bSYour Name }
794*5113495bSYour Name
795*5113495bSYour Name osif_debug("is going to notify supplicant of:");
796*5113495bSYour Name osif_info(QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(bssid->bytes));
797*5113495bSYour Name
798*5113495bSYour Name cfg80211_pmksa_candidate_notify(wdev->netdev, index,
799*5113495bSYour Name bssid->bytes,
800*5113495bSYour Name preauth, qdf_mem_malloc_flags());
801*5113495bSYour Name return QDF_STATUS_SUCCESS;
802*5113495bSYour Name }
803*5113495bSYour Name #endif /* CONN_MGR_ADV_FEATURE */
804