qcacmn: Support roam sync ind in CM
Add support for roam sync indication in connection manager. Change-Id: I750403aa0dfa6c615f9bca832898c63af608d28d CRs-Fixed: 2901863
This commit is contained in:

committed by
snandini

parent
80d5b0dc18
commit
5c1ca03ebe
@@ -276,9 +276,9 @@ struct osif_cm_ops {
|
||||
#ifdef CONN_MGR_ADV_FEATURE
|
||||
osif_cm_netif_queue_ctrl_cb netif_queue_control_cb;
|
||||
os_if_cm_napi_serialize_ctrl_cb napi_serialize_control_cb;
|
||||
osif_cm_save_gtk_cb save_gtk_cb;
|
||||
#endif
|
||||
#ifdef WLAN_FEATURE_FILS_SK
|
||||
osif_cm_save_gtk_cb save_gtk_cb;
|
||||
osif_cm_set_hlp_data_cb set_hlp_data_cb;
|
||||
#endif
|
||||
};
|
||||
@@ -343,9 +343,7 @@ QDF_STATUS osif_cm_netif_queue_ind(struct wlan_objmgr_vdev *vdev,
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS osif_cm_napi_serialize(bool action);
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_FILS_SK
|
||||
/**
|
||||
* osif_cm_save_gtk() - Function to save gtk in legacy module
|
||||
* @vdev: vdev pointer
|
||||
@@ -358,7 +356,9 @@ QDF_STATUS osif_cm_napi_serialize(bool action);
|
||||
*/
|
||||
QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_connect_resp *rsp);
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_FILS_SK
|
||||
/**
|
||||
* osif_cm_set_hlp_data() - Function to set hlp data for dhcp in legacy module
|
||||
* @dev: Pointer to net device
|
||||
|
@@ -28,6 +28,10 @@
|
||||
#include <osif_cm_util.h>
|
||||
#include <wlan_cfg80211.h>
|
||||
#include <wlan_cfg80211_scan.h>
|
||||
#ifdef CONN_MGR_ADV_FEATURE
|
||||
#include "wlan_mlme_ucfg_api.h"
|
||||
#endif
|
||||
#include "wlan_crypto_global_api.h"
|
||||
|
||||
#ifdef CONN_MGR_ADV_FEATURE
|
||||
#ifdef WLAN_FEATURE_FILS_SK
|
||||
@@ -85,6 +89,291 @@ static inline void osif_roamed_ind(struct net_device *dev,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
||||
#ifdef WLAN_FEATURE_FILS_SK
|
||||
/**
|
||||
* wlan_hdd_add_fils_params_roam_auth_event() - Adds FILS params in roam auth
|
||||
* @skb: SK buffer
|
||||
* @roam_info: Roam info
|
||||
*
|
||||
* API adds fils params[pmk, pmkid, next sequence number] to roam auth event
|
||||
*
|
||||
* Return: zero on success, error code on failure
|
||||
*/
|
||||
static int
|
||||
osif_add_fils_params_roam_auth_event(struct sk_buff *skb,
|
||||
struct wlan_roam_sync_info *roam_info)
|
||||
{
|
||||
if (roam_info->pmk_len &&
|
||||
nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK,
|
||||
roam_info->pmk_len, roam_info->pmk)) {
|
||||
osif_err("pmk send fail");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID,
|
||||
PMKID_LEN, roam_info->pmkid)) {
|
||||
osif_err("pmkid send fail");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
osif_debug("Update ERP Seq Num %d, Next ERP Seq Num %d",
|
||||
roam_info->update_erp_next_seq_num,
|
||||
roam_info->next_erp_seq_num);
|
||||
if (roam_info->update_erp_next_seq_num &&
|
||||
nla_put_u16(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM,
|
||||
roam_info->next_erp_seq_num)) {
|
||||
osif_err("ERP seq num send fail");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int
|
||||
osif_add_fils_params_roam_auth_event(struct sk_buff *skb,
|
||||
struct wlan_roam_sync_info *roam_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* osif_get_roam_reason() - convert wmi roam reason to
|
||||
* enum qca_roam_reason
|
||||
* @roam_scan_trigger: wmi roam scan trigger ID
|
||||
*
|
||||
* Return: Meaningful qca_roam_reason from enum WMI_ROAM_TRIGGER_REASON_ID
|
||||
*/
|
||||
static enum qca_roam_reason osif_get_roam_reason(uint16_t roam_scan_trigger)
|
||||
{
|
||||
switch (roam_scan_trigger) {
|
||||
case ROAM_TRIGGER_REASON_PER:
|
||||
return QCA_ROAM_REASON_PER;
|
||||
case ROAM_TRIGGER_REASON_BMISS:
|
||||
return QCA_ROAM_REASON_BEACON_MISS;
|
||||
case ROAM_TRIGGER_REASON_LOW_RSSI:
|
||||
case ROAM_TRIGGER_REASON_BACKGROUND:
|
||||
return QCA_ROAM_REASON_POOR_RSSI;
|
||||
case ROAM_TRIGGER_REASON_HIGH_RSSI:
|
||||
return QCA_ROAM_REASON_BETTER_RSSI;
|
||||
case ROAM_TRIGGER_REASON_DENSE:
|
||||
return QCA_ROAM_REASON_CONGESTION;
|
||||
case ROAM_TRIGGER_REASON_FORCED:
|
||||
return QCA_ROAM_REASON_USER_TRIGGER;
|
||||
case ROAM_TRIGGER_REASON_BTM:
|
||||
return QCA_ROAM_REASON_BTM;
|
||||
case ROAM_TRIGGER_REASON_BSS_LOAD:
|
||||
return QCA_ROAM_REASON_BSS_LOAD;
|
||||
default:
|
||||
return QCA_ROAM_REASON_UNKNOWN;
|
||||
}
|
||||
|
||||
return QCA_ROAM_REASON_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* osif_send_roam_auth_event() - API to send roam auth event response to kernel
|
||||
* @vdev: vdev pointer
|
||||
* @osif_priv: OS private structure of vdev
|
||||
* @rsp: Connection manager response
|
||||
*
|
||||
* This is called when wlan driver needs to send the roaming and
|
||||
* authorization information after roaming.
|
||||
*
|
||||
* The information that would be sent is the request RSN IE, response
|
||||
* RSN IE and BSSID of the newly roamed AP.
|
||||
*
|
||||
* If the Authorized status is authenticated, then additional parameters
|
||||
* like PTK's KCK and KEK and Replay Counter would also be passed to the
|
||||
* supplicant.
|
||||
*
|
||||
* The supplicant upon receiving this event would ignore the legacy
|
||||
* cfg80211_roamed call and use the entire information from this event.
|
||||
* The cfg80211_roamed should still co-exist since the kernel will
|
||||
* make use of the parameters even if the supplicant ignores it.
|
||||
*
|
||||
*
|
||||
* Context: Any context.
|
||||
* Return: int
|
||||
*/
|
||||
static 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)
|
||||
{
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
uint32_t fils_params_len;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct wlan_roam_sync_info *roaming_info;
|
||||
int status;
|
||||
int32_t akm;
|
||||
bool roam_offload_enable;
|
||||
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
ucfg_mlme_get_roaming_offload(psoc, &roam_offload_enable);
|
||||
|
||||
if (!roam_offload_enable)
|
||||
return 0;
|
||||
|
||||
roaming_info = rsp->roaming_info;
|
||||
|
||||
/*
|
||||
* PMK is sent from FW in Roam Synch Event for FILS Roaming.
|
||||
* In that case, add three more NL attributes.ie. PMK, PMKID
|
||||
* and ERP next sequence number. Add corresponding lengths
|
||||
* with 3 extra NL message headers for each of the
|
||||
* aforementioned params.
|
||||
*/
|
||||
fils_params_len = roaming_info->pmk_len + PMKID_LEN +
|
||||
sizeof(uint16_t) + (3 * NLMSG_HDRLEN);
|
||||
|
||||
skb = cfg80211_vendor_event_alloc(osif_priv->wdev->wiphy,
|
||||
osif_priv->wdev,
|
||||
ETH_ALEN + req_ie_len +
|
||||
resp_ie_len +
|
||||
sizeof(uint8_t) + REPLAY_CTR_LEN +
|
||||
KCK_KEY_LEN + roaming_info->kek_len +
|
||||
sizeof(uint16_t) + sizeof(uint8_t) +
|
||||
(9 * NLMSG_HDRLEN) + fils_params_len,
|
||||
QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!skb) {
|
||||
osif_err("cfg80211_vendor_event_alloc failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
|
||||
ETH_ALEN, rsp->bssid.bytes) ||
|
||||
nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
|
||||
req_ie_len, req_ie) ||
|
||||
nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
|
||||
resp_ie_len, resp_ie)) {
|
||||
osif_err("nla put fail");
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if (roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED) {
|
||||
osif_debug("Include Auth Params TLV's");
|
||||
if (nla_put_u8(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
|
||||
true)) {
|
||||
osif_err("nla put fail");
|
||||
goto nla_put_failure;
|
||||
}
|
||||
akm = wlan_crypto_get_param(vdev,
|
||||
WLAN_CRYPTO_PARAM_KEY_MGMT);
|
||||
/* if FT or CCKM connection: dont send replay counter */
|
||||
if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X) &&
|
||||
!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_PSK) &&
|
||||
!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_SAE) &&
|
||||
!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_FT_IEEE8021X_SHA384) &&
|
||||
!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_CCKM) &&
|
||||
nla_put(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
|
||||
REPLAY_CTR_LEN,
|
||||
roaming_info->replay_ctr)) {
|
||||
osif_err("non FT/non CCKM connection");
|
||||
osif_err("failed to send replay counter");
|
||||
goto nla_put_failure;
|
||||
}
|
||||
if (roaming_info->kek_len > MAX_KEK_LENGTH ||
|
||||
nla_put(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
|
||||
roaming_info->kck_len, roaming_info->kck) ||
|
||||
nla_put(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
|
||||
roaming_info->kek_len, roaming_info->kek)) {
|
||||
osif_err("nla put fail, kek_len %d",
|
||||
roaming_info->kek_len);
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if (nla_put_u16(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON,
|
||||
osif_get_roam_reason(roaming_info->roam_reason))) {
|
||||
osif_err("roam reason send failure");
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
status = osif_add_fils_params_roam_auth_event(skb,
|
||||
roaming_info);
|
||||
if (status)
|
||||
goto nla_put_failure;
|
||||
/*
|
||||
* Save the gtk rekey parameters in HDD STA context. They will
|
||||
* be used next time when host enables GTK offload and goes
|
||||
* into power save state.
|
||||
*/
|
||||
osif_cm_save_gtk(vdev, rsp);
|
||||
osif_debug("roam_info_ptr->replay_ctr 0x%llx",
|
||||
*((uint64_t *)roaming_info->replay_ctr));
|
||||
|
||||
} else {
|
||||
osif_debug("No Auth Params TLV's");
|
||||
if (nla_put_u8(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
|
||||
false)) {
|
||||
osif_err("nla put fail");
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
|
||||
osif_debug("Auth Status = %d Subnet Change Status = %d",
|
||||
roaming_info->auth_status,
|
||||
roaming_info->subnet_change_status);
|
||||
/*
|
||||
* Add subnet change status if subnet has changed
|
||||
* 0 = unchanged
|
||||
* 1 = changed
|
||||
* 2 = unknown
|
||||
*/
|
||||
if (roaming_info->subnet_change_status) {
|
||||
if (nla_put_u8(skb,
|
||||
QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS,
|
||||
roaming_info->subnet_change_status)) {
|
||||
osif_err("nla put fail");
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
|
||||
cfg80211_vendor_event(skb, GFP_KERNEL);
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
kfree_skb(skb);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void osif_cm_get_reassoc_req_ie_data(struct element_info *assoc_req,
|
||||
size_t *ie_data_len,
|
||||
const uint8_t **ie_data_ptr)
|
||||
{
|
||||
/* Validate IE and length */
|
||||
if (!assoc_req->len || !assoc_req->ptr ||
|
||||
assoc_req->len <= WLAN_REASSOC_REQ_IES_OFFSET)
|
||||
return;
|
||||
|
||||
*ie_data_len = assoc_req->len - WLAN_REASSOC_REQ_IES_OFFSET;
|
||||
*ie_data_ptr = assoc_req->ptr + WLAN_REASSOC_REQ_IES_OFFSET;
|
||||
}
|
||||
|
||||
void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
|
||||
struct vdev_osif_priv *osif_priv,
|
||||
struct wlan_cm_connect_resp *rsp)
|
||||
@@ -96,10 +385,18 @@ void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
|
||||
const uint8_t *rsp_ie = NULL;
|
||||
struct cfg80211_bss *bss;
|
||||
struct ieee80211_channel *chan;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
bool roam_offload = false;
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(rsp->connect_status))
|
||||
return;
|
||||
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
if (!psoc)
|
||||
return;
|
||||
|
||||
ucfg_mlme_is_roam_scan_offload_enabled(psoc, &roam_offload);
|
||||
|
||||
chan = ieee80211_get_channel(osif_priv->wdev->wiphy,
|
||||
rsp->freq);
|
||||
bss = wlan_cfg80211_get_bss(osif_priv->wdev->wiphy, chan,
|
||||
@@ -107,15 +404,17 @@ void osif_indicate_reassoc_results(struct wlan_objmgr_vdev *vdev,
|
||||
rsp->ssid.length);
|
||||
if (!bss)
|
||||
osif_warn("not able to find bss");
|
||||
osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
|
||||
&req_len, &req_ie);
|
||||
if (!roam_offload || rsp->is_ft)
|
||||
osif_cm_get_assoc_req_ie_data(&rsp->connect_ies.assoc_req,
|
||||
&req_len, &req_ie);
|
||||
else
|
||||
osif_cm_get_reassoc_req_ie_data(&rsp->connect_ies.assoc_req,
|
||||
&req_len, &req_ie);
|
||||
osif_cm_get_assoc_rsp_ie_data(&rsp->connect_ies.assoc_rsp,
|
||||
&rsp_len, &rsp_ie);
|
||||
osif_roamed_ind(dev, bss, req_ie, req_len, rsp_ie, rsp_len);
|
||||
|
||||
osif_cm_save_gtk(vdev, rsp);
|
||||
|
||||
/* Add osif_send_roam_auth_event (wlan_hdd_send_roam_auth_event) */
|
||||
osif_send_roam_auth_event(vdev, osif_priv, rsp, req_ie, req_len, rsp_ie,
|
||||
rsp_len);
|
||||
|
||||
osif_update_fils_hlp_data(dev, vdev, rsp);
|
||||
}
|
||||
|
@@ -336,7 +336,7 @@ osif_cm_roam_start_cb(struct wlan_objmgr_vdev *vdev)
|
||||
* @vdev: vdev pointer
|
||||
*
|
||||
* This callback indicates os_if that roaming has been aborted
|
||||
* so that os_if can stop all the activity on this connection
|
||||
* so that os_if can resume all the activity on this connection
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
@@ -348,6 +348,42 @@ osif_cm_roam_abort_cb(struct wlan_objmgr_vdev *vdev)
|
||||
WLAN_WAKE_ALL_NETIF_QUEUE,
|
||||
WLAN_CONTROL_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* osif_cm_roam_sync_cb() - Roam sync callback
|
||||
* @vdev: vdev pointer
|
||||
*
|
||||
* This callback indicates os_if that roam sync ind received
|
||||
* so that os_if can stop all the activity on this connection
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
|
||||
static QDF_STATUS
|
||||
osif_cm_roam_sync_cb(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
osif_cm_napi_serialize(true);
|
||||
return osif_cm_netif_queue_ind(vdev,
|
||||
WLAN_STOP_ALL_NETIF_QUEUE,
|
||||
WLAN_CONTROL_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* osif_cm_roam_cmpl_cb() - Roam sync complete callback
|
||||
* @vdev: vdev pointer
|
||||
* @rsp: connect rsp
|
||||
*
|
||||
* This callback indicates os_if that roam sync is complete
|
||||
* so that os_if can stop all the activity on this connection
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
|
||||
static QDF_STATUS
|
||||
osif_cm_roam_cmpl_cb(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return osif_cm_napi_serialize(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct mlme_cm_ops cm_ops = {
|
||||
@@ -359,6 +395,8 @@ static struct mlme_cm_ops cm_ops = {
|
||||
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
||||
.mlme_cm_roam_start_cb = osif_cm_roam_start_cb,
|
||||
.mlme_cm_roam_abort_cb = osif_cm_roam_abort_cb,
|
||||
.mlme_cm_roam_sync_cb = osif_cm_roam_sync_cb,
|
||||
.mlme_cm_roam_cmpl_cb = osif_cm_roam_cmpl_cb,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -472,8 +510,7 @@ QDF_STATUS osif_cm_napi_serialize(bool action)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef WLAN_FEATURE_FILS_SK
|
||||
|
||||
QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_connect_resp *rsp)
|
||||
{
|
||||
@@ -487,7 +524,9 @@ QDF_STATUS osif_cm_save_gtk(struct wlan_objmgr_vdev *vdev,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_FILS_SK
|
||||
QDF_STATUS osif_cm_set_hlp_data(struct net_device *dev,
|
||||
struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_cm_connect_resp *rsp)
|
||||
|
Reference in New Issue
Block a user