qcacld-3.0: Support SAP fast BSS transition in driver
When driver receive auth request frame with FT algorithm, offload it to hostapd. When driver receive (re)assoc request whith FT-PSK in RSN IE. offload it to hostapd. Filter FT related IE from hostapd, and append it to the end of the (re)assoc response frame Change-Id: Id11cce6898615bb6b0cb361ea7b23ea2014f0bae CRs-Fixed: 4202696
Este commit está contenido en:

cometido por
Madan Koyyalamudi

padre
cd67bc5cfa
commit
dafdfb98ff
@@ -835,6 +835,7 @@ struct hdd_fw_txrx_stats {
|
|||||||
* @acs_in_progress: In progress acs flag for an adapter
|
* @acs_in_progress: In progress acs flag for an adapter
|
||||||
* @client_count: client count per dot11_mode
|
* @client_count: client count per dot11_mode
|
||||||
* @country_ie_updated: country ie is updated or not by hdd hostapd
|
* @country_ie_updated: country ie is updated or not by hdd hostapd
|
||||||
|
* @during_auth_offload: auth mgmt frame is offloading to hostapd
|
||||||
*/
|
*/
|
||||||
struct hdd_ap_ctx {
|
struct hdd_ap_ctx {
|
||||||
struct hdd_hostapd_state hostapd_state;
|
struct hdd_hostapd_state hostapd_state;
|
||||||
@@ -855,6 +856,7 @@ struct hdd_ap_ctx {
|
|||||||
qdf_atomic_t acs_in_progress;
|
qdf_atomic_t acs_in_progress;
|
||||||
uint16_t client_count[QCA_WLAN_802_11_MODE_INVALID];
|
uint16_t client_count[QCA_WLAN_802_11_MODE_INVALID];
|
||||||
bool country_ie_updated;
|
bool country_ie_updated;
|
||||||
|
bool during_auth_offload;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2244,6 +2244,50 @@ static inline void hdd_translate_sae_rsn_to_csr_auth(int8_t auth_suite[4],
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void *hdd_filter_ft_info(const uint8_t *frame, size_t len,
|
||||||
|
uint32_t *ft_info_len)
|
||||||
|
{
|
||||||
|
uint32_t ft_ie_len, md_ie_len, rsn_ie_len, ie_len;
|
||||||
|
const uint8_t *rsn_ie, *md_ie, *ft_ie;
|
||||||
|
void *ft_info;
|
||||||
|
|
||||||
|
ft_ie_len = 0;
|
||||||
|
md_ie_len = 0;
|
||||||
|
rsn_ie_len = 0;
|
||||||
|
ie_len = len - DOT11F_FF_CAPABILITIES_LEN - DOT11F_FF_STATUS_LEN
|
||||||
|
- DOT11F_IE_AID_MAX_LEN - sizeof(tSirMacMgmtHdr);
|
||||||
|
rsn_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_RSN, frame, ie_len);
|
||||||
|
|
||||||
|
if (rsn_ie) {
|
||||||
|
rsn_ie_len = rsn_ie[1] + 2;
|
||||||
|
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
(void *)rsn_ie, rsn_ie_len);
|
||||||
|
}
|
||||||
|
md_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_MOBILITYDOMAIN,
|
||||||
|
frame, ie_len);
|
||||||
|
if (md_ie) {
|
||||||
|
md_ie_len = md_ie[1] + 2;
|
||||||
|
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
(void *)md_ie, md_ie_len);
|
||||||
|
}
|
||||||
|
ft_ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_FTINFO, frame, ie_len);
|
||||||
|
if (ft_ie)
|
||||||
|
ft_ie_len = ft_ie[1] + 2;
|
||||||
|
|
||||||
|
*ft_info_len = rsn_ie_len + md_ie_len + ft_ie_len;
|
||||||
|
ft_info = qdf_mem_malloc(*ft_info_len);
|
||||||
|
if (!ft_info)
|
||||||
|
return NULL;
|
||||||
|
if (rsn_ie_len)
|
||||||
|
qdf_mem_copy(ft_info, rsn_ie, rsn_ie_len);
|
||||||
|
if (md_ie_len)
|
||||||
|
qdf_mem_copy(ft_info + rsn_ie_len, md_ie, md_ie_len);
|
||||||
|
if (ft_ie_len)
|
||||||
|
qdf_mem_copy(ft_info + rsn_ie_len + md_ie_len,
|
||||||
|
ft_ie, ft_ie_len);
|
||||||
|
return ft_info;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
|
* hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
|
||||||
* @auth_suite: auth suite
|
* @auth_suite: auth suite
|
||||||
|
@@ -20304,6 +20304,7 @@ static int wlan_hdd_add_key_vdev(mac_handle_t mac_handle,
|
|||||||
int errno;
|
int errno;
|
||||||
enum wlan_crypto_cipher_type cipher;
|
enum wlan_crypto_cipher_type cipher;
|
||||||
bool ft_mode = false;
|
bool ft_mode = false;
|
||||||
|
struct hdd_ap_ctx *hdd_ap_ctx;
|
||||||
|
|
||||||
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||||
|
|
||||||
@@ -20355,6 +20356,11 @@ static int wlan_hdd_add_key_vdev(mac_handle_t mac_handle,
|
|||||||
switch (adapter->device_mode) {
|
switch (adapter->device_mode) {
|
||||||
case QDF_SAP_MODE:
|
case QDF_SAP_MODE:
|
||||||
case QDF_P2P_GO_MODE:
|
case QDF_P2P_GO_MODE:
|
||||||
|
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
|
||||||
|
if (hdd_ap_ctx->during_auth_offload) {
|
||||||
|
hdd_err("don't need install key during auth");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
errno = wlan_hdd_add_key_sap(adapter, pairwise,
|
errno = wlan_hdd_add_key_sap(adapter, pairwise,
|
||||||
key_index, cipher);
|
key_index, cipher);
|
||||||
break;
|
break;
|
||||||
|
@@ -4880,8 +4880,9 @@ int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter)
|
|||||||
WLAN_EID_INTERWORKING);
|
WLAN_EID_INTERWORKING);
|
||||||
wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
|
wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
|
||||||
WLAN_EID_ADVERTISEMENT_PROTOCOL);
|
WLAN_EID_ADVERTISEMENT_PROTOCOL);
|
||||||
|
|
||||||
wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, WLAN_ELEMID_RSNXE);
|
wlan_hdd_add_extra_ie(adapter, genie, &total_ielen, WLAN_ELEMID_RSNXE);
|
||||||
|
wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
|
||||||
|
WLAN_ELEMID_MOBILITY_DOMAIN);
|
||||||
#ifdef FEATURE_WLAN_WAPI
|
#ifdef FEATURE_WLAN_WAPI
|
||||||
if (QDF_SAP_MODE == adapter->device_mode) {
|
if (QDF_SAP_MODE == adapter->device_mode) {
|
||||||
wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
|
wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
|
||||||
@@ -4918,6 +4919,8 @@ int wlan_hdd_cfg80211_update_apies(struct hdd_adapter *adapter)
|
|||||||
&proberesp_ies_len);
|
&proberesp_ies_len);
|
||||||
wlan_hdd_add_extra_ie(adapter, proberesp_ies, &proberesp_ies_len,
|
wlan_hdd_add_extra_ie(adapter, proberesp_ies, &proberesp_ies_len,
|
||||||
WLAN_ELEMID_RSNXE);
|
WLAN_ELEMID_RSNXE);
|
||||||
|
wlan_hdd_add_extra_ie(adapter, proberesp_ies, &proberesp_ies_len,
|
||||||
|
WLAN_ELEMID_MOBILITY_DOMAIN);
|
||||||
|
|
||||||
if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
|
if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
|
||||||
update_ie.ieBufferlength = proberesp_ies_len;
|
update_ie.ieBufferlength = proberesp_ies_len;
|
||||||
|
@@ -44,6 +44,20 @@ struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
|
|||||||
enum csr_akm_type
|
enum csr_akm_type
|
||||||
hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]);
|
hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hdd_filter_ft_info() -
|
||||||
|
* This function to filter fast BSS transition related IE
|
||||||
|
* @frame: pointer to the input frame.
|
||||||
|
* @len: input frame length.
|
||||||
|
* @ft_info_len: store the total length of FT related IE.
|
||||||
|
*
|
||||||
|
* Return: pointer to a buffer which stored the FT related IE
|
||||||
|
* This is a malloced memory that must be freed by the caller
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *hdd_filter_ft_info(const uint8_t *frame,
|
||||||
|
size_t len, uint32_t *ft_info_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hdd_softap_set_channel_change() -
|
* hdd_softap_set_channel_change() -
|
||||||
* This function to support SAP channel change with CSA IE
|
* This function to support SAP channel change with CSA IE
|
||||||
|
@@ -290,6 +290,10 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
uint16_t auth_algo;
|
uint16_t auth_algo;
|
||||||
QDF_STATUS qdf_status;
|
QDF_STATUS qdf_status;
|
||||||
int ret;
|
int ret;
|
||||||
|
uint32_t ft_info_len = 0;
|
||||||
|
const uint8_t *assoc_resp;
|
||||||
|
void *ft_info;
|
||||||
|
struct hdd_ap_ctx *hdd_ap_ctx;
|
||||||
|
|
||||||
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
|
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
|
||||||
hdd_err("Command not allowed in FTM mode");
|
hdd_err("Command not allowed in FTM mode");
|
||||||
@@ -305,6 +309,7 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
|
|
||||||
type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
|
type = WLAN_HDD_GET_TYPE_FRM_FC(buf[0]);
|
||||||
sub_type = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
|
sub_type = WLAN_HDD_GET_SUBTYPE_FRM_FC(buf[0]);
|
||||||
|
hdd_debug("type %d, sub_type %d", type, sub_type);
|
||||||
|
|
||||||
/* When frame to be transmitted is auth mgmt, then trigger
|
/* When frame to be transmitted is auth mgmt, then trigger
|
||||||
* sme_send_mgmt_tx to send auth frame without need for policy manager.
|
* sme_send_mgmt_tx to send auth frame without need for policy manager.
|
||||||
@@ -326,6 +331,12 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
sizeof(struct wlan_frame_hdr));
|
sizeof(struct wlan_frame_hdr));
|
||||||
if (auth_algo == eSIR_AUTH_TYPE_PASN)
|
if (auth_algo == eSIR_AUTH_TYPE_PASN)
|
||||||
goto off_chan_tx;
|
goto off_chan_tx;
|
||||||
|
if ((auth_algo == eSIR_FT_AUTH) &&
|
||||||
|
(adapter->device_mode == QDF_SAP_MODE ||
|
||||||
|
adapter->device_mode == QDF_P2P_GO_MODE)) {
|
||||||
|
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
|
||||||
|
hdd_ap_ctx->during_auth_offload = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_SME,
|
qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_SME,
|
||||||
@@ -335,7 +346,32 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||||||
adapter->vdev_id, buf, len);
|
adapter->vdev_id, buf, len);
|
||||||
|
|
||||||
if (QDF_IS_STATUS_SUCCESS(qdf_status))
|
if (QDF_IS_STATUS_SUCCESS(qdf_status))
|
||||||
return 0;
|
return qdf_status_to_os_return(qdf_status);
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/* Only when SAP working on Fast BSS transition mode. Driver offload
|
||||||
|
* (re)assoc request to hostapd. Here driver receive (re)assoc response
|
||||||
|
* frame from hostapd.
|
||||||
|
*/
|
||||||
|
if ((adapter->device_mode == QDF_SAP_MODE ||
|
||||||
|
adapter->device_mode == QDF_P2P_GO_MODE) &&
|
||||||
|
(type == SIR_MAC_MGMT_FRAME) &&
|
||||||
|
(sub_type == SIR_MAC_MGMT_ASSOC_RSP ||
|
||||||
|
sub_type == SIR_MAC_MGMT_REASSOC_RSP)) {
|
||||||
|
assoc_resp = &((struct ieee80211_mgmt *)buf)->u.assoc_resp.variable[0];
|
||||||
|
ft_info = hdd_filter_ft_info(assoc_resp, len, &ft_info_len);
|
||||||
|
if (!ft_info || !ft_info_len)
|
||||||
|
return -EINVAL;
|
||||||
|
hdd_debug("get ft_info_len from Assoc rsp :%d", ft_info_len);
|
||||||
|
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
|
||||||
|
qdf_status = wlansap_update_ft_info(hdd_ap_ctx->sap_context,
|
||||||
|
((struct ieee80211_mgmt *)buf)->da,
|
||||||
|
ft_info, ft_info_len, 0);
|
||||||
|
qdf_mem_free(ft_info);
|
||||||
|
|
||||||
|
if (QDF_IS_STATUS_SUCCESS(qdf_status))
|
||||||
|
return qdf_status_to_os_return(qdf_status);
|
||||||
else
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1064,6 +1100,7 @@ __hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter,
|
|||||||
bool is_pasn_auth_frame = false;
|
bool is_pasn_auth_frame = false;
|
||||||
struct hdd_adapter *assoc_adapter;
|
struct hdd_adapter *assoc_adapter;
|
||||||
bool eht_capab;
|
bool eht_capab;
|
||||||
|
struct hdd_ap_ctx *hdd_ap_ctx;
|
||||||
|
|
||||||
hdd_debug("Frame Type = %d Frame Length = %d freq = %d",
|
hdd_debug("Frame Type = %d Frame Length = %d freq = %d",
|
||||||
frame_type, frm_len, rx_freq);
|
frame_type, frm_len, rx_freq);
|
||||||
@@ -1092,8 +1129,15 @@ __hdd_indicate_mgmt_frame_to_user(struct hdd_adapter *adapter,
|
|||||||
WLAN_AUTH_FRAME_MIN_LEN)) {
|
WLAN_AUTH_FRAME_MIN_LEN)) {
|
||||||
auth_algo = *(uint16_t *)(pb_frames +
|
auth_algo = *(uint16_t *)(pb_frames +
|
||||||
sizeof(struct wlan_frame_hdr));
|
sizeof(struct wlan_frame_hdr));
|
||||||
if (auth_algo == eSIR_AUTH_TYPE_PASN)
|
if (auth_algo == eSIR_AUTH_TYPE_PASN) {
|
||||||
is_pasn_auth_frame = true;
|
is_pasn_auth_frame = true;
|
||||||
|
} else if (auth_algo == eSIR_FT_AUTH) {
|
||||||
|
if (adapter->device_mode == QDF_SAP_MODE ||
|
||||||
|
adapter->device_mode == QDF_P2P_GO_MODE) {
|
||||||
|
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
|
||||||
|
hdd_ap_ctx->during_auth_offload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get adapter from Destination mac address of the frame */
|
/* Get adapter from Destination mac address of the frame */
|
||||||
|
@@ -1085,6 +1085,9 @@ struct assoc_ind {
|
|||||||
const uint8_t *owe_ie;
|
const uint8_t *owe_ie;
|
||||||
uint32_t owe_ie_len;
|
uint32_t owe_ie_len;
|
||||||
uint16_t owe_status;
|
uint16_t owe_status;
|
||||||
|
const uint8_t *ft_ie;
|
||||||
|
uint32_t ft_ie_len;
|
||||||
|
uint16_t ft_status;
|
||||||
bool need_assoc_rsp_tx_cb;
|
bool need_assoc_rsp_tx_cb;
|
||||||
tSirMacAddr peer_mld_addr;
|
tSirMacAddr peer_mld_addr;
|
||||||
};
|
};
|
||||||
@@ -1099,6 +1102,16 @@ struct owe_assoc_ind {
|
|||||||
struct assoc_ind *assoc_ind;
|
struct assoc_ind *assoc_ind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct ft_assoc_ind - ft association indication
|
||||||
|
* @node: List entry element
|
||||||
|
* @assoc_ind: pointer to assoc ind
|
||||||
|
*/
|
||||||
|
struct ft_assoc_ind {
|
||||||
|
qdf_list_node_t node;
|
||||||
|
struct assoc_ind *assoc_ind;
|
||||||
|
};
|
||||||
|
|
||||||
/* / Definition for Association confirm */
|
/* / Definition for Association confirm */
|
||||||
/* / ---> MAC */
|
/* / ---> MAC */
|
||||||
struct assoc_cnf {
|
struct assoc_cnf {
|
||||||
@@ -1111,6 +1124,8 @@ struct assoc_cnf {
|
|||||||
enum wlan_status_code mac_status_code;
|
enum wlan_status_code mac_status_code;
|
||||||
uint8_t *owe_ie;
|
uint8_t *owe_ie;
|
||||||
uint32_t owe_ie_len;
|
uint32_t owe_ie_len;
|
||||||
|
uint8_t *ft_ie;
|
||||||
|
uint32_t ft_ie_len;
|
||||||
bool need_assoc_rsp_tx_cb;
|
bool need_assoc_rsp_tx_cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -136,6 +136,7 @@ typedef enum eLimMlmStates {
|
|||||||
eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE,
|
eLIM_MLM_WT_ADD_BSS_RSP_FT_REASSOC_STATE,
|
||||||
eLIM_MLM_WT_FT_REASSOC_RSP_STATE,
|
eLIM_MLM_WT_FT_REASSOC_RSP_STATE,
|
||||||
eLIM_MLM_WT_SAE_AUTH_STATE,
|
eLIM_MLM_WT_SAE_AUTH_STATE,
|
||||||
|
eLIM_MLM_WT_FT_AUTH_STATE,
|
||||||
} tLimMlmStates;
|
} tLimMlmStates;
|
||||||
|
|
||||||
/* 11h channel switch states */
|
/* 11h channel switch states */
|
||||||
@@ -246,6 +247,8 @@ typedef struct tLimPreAuthTable {
|
|||||||
* @he_capable: 802.11ax HE capability
|
* @he_capable: 802.11ax HE capability
|
||||||
* @owe_ie: Pointer to OWE IE
|
* @owe_ie: Pointer to OWE IE
|
||||||
* @owe_ie_len: Length of OWE IE
|
* @owe_ie_len: Length of OWE IE
|
||||||
|
* @ft_ie: Pointer to FT related IE
|
||||||
|
* @ft_ie_len: Length of FT related IE
|
||||||
* @eht_capable: 802.11be EHT capability
|
* @eht_capable: 802.11be EHT capability
|
||||||
*/
|
*/
|
||||||
struct lim_sta_context {
|
struct lim_sta_context {
|
||||||
@@ -272,6 +275,8 @@ struct lim_sta_context {
|
|||||||
bool force_1x1;
|
bool force_1x1;
|
||||||
uint8_t *owe_ie;
|
uint8_t *owe_ie;
|
||||||
uint32_t owe_ie_len;
|
uint32_t owe_ie_len;
|
||||||
|
uint8_t *ft_ie;
|
||||||
|
uint32_t ft_ie_len;
|
||||||
#ifdef WLAN_FEATURE_11BE
|
#ifdef WLAN_FEATURE_11BE
|
||||||
bool eht_capable;
|
bool eht_capable;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2668,6 +2668,14 @@ void lim_process_assoc_req_frame(struct mac_context *mac_ctx,
|
|||||||
sub_type, GET_LIM_SYSTEM_ROLE(session),
|
sub_type, GET_LIM_SYSTEM_ROLE(session),
|
||||||
QDF_MAC_ADDR_REF(hdr->sa));
|
QDF_MAC_ADDR_REF(hdr->sa));
|
||||||
return;
|
return;
|
||||||
|
} else if (sta_ds->mlmStaContext.akm_type == ANI_AKM_TYPE_FT_RSN_PSK) {
|
||||||
|
pe_debug("FT Assoc Req, delete STA hash entry");
|
||||||
|
lim_release_peer_idx(mac_ctx, sta_ds->assocId, session);
|
||||||
|
if (dph_delete_hash_entry(mac_ctx, hdr->sa,
|
||||||
|
sta_ds->assocId,
|
||||||
|
&session->dph.dphHashTable)
|
||||||
|
!= QDF_STATUS_SUCCESS)
|
||||||
|
pe_err("error deleting hash entry");
|
||||||
} else if (!sta_ds->rmfEnabled && (sub_type == LIM_REASSOC)) {
|
} else if (!sta_ds->rmfEnabled && (sub_type == LIM_REASSOC)) {
|
||||||
/*
|
/*
|
||||||
* SAP should send reassoc response with reject code
|
* SAP should send reassoc response with reject code
|
||||||
@@ -3442,6 +3450,15 @@ QDF_STATUS lim_send_mlm_assoc_ind(struct mac_context *mac_ctx,
|
|||||||
qdf_mem_free(assoc_ind);
|
qdf_mem_free(assoc_ind);
|
||||||
return QDF_STATUS_E_INVAL;
|
return QDF_STATUS_E_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pe_debug("assoc_ind->akm_type:%d ", assoc_ind->akm_type);
|
||||||
|
if (assoc_ind->akm_type == ANI_AKM_TYPE_FT_RSN_PSK) {
|
||||||
|
lim_send_sme_mgmt_frame_ind(mac_ctx, sub_type,
|
||||||
|
qdf_nbuf_data(assoc_req->assoc_req_buf),
|
||||||
|
qdf_nbuf_len(assoc_req->assoc_req_buf),
|
||||||
|
session_entry->smeSessionId,
|
||||||
|
0, 0, RXMGMT_FLAG_NONE);
|
||||||
|
}
|
||||||
lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
|
lim_post_sme_message(mac_ctx, LIM_MLM_ASSOC_IND,
|
||||||
(uint32_t *)assoc_ind);
|
(uint32_t *)assoc_ind);
|
||||||
qdf_mem_free(assoc_ind);
|
qdf_mem_free(assoc_ind);
|
||||||
|
@@ -508,6 +508,73 @@ static inline void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
|
|||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void lim_process_ft_auth_frame(struct mac_context *mac_ctx,
|
||||||
|
uint8_t *rx_pkt_info,
|
||||||
|
struct pe_session *pe_session)
|
||||||
|
{
|
||||||
|
tpSirMacMgmtHdr mac_hdr;
|
||||||
|
uint32_t frame_len;
|
||||||
|
uint8_t *body_ptr;
|
||||||
|
enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE;
|
||||||
|
uint16_t auth_algo;
|
||||||
|
|
||||||
|
mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
|
||||||
|
body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
|
||||||
|
frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
|
||||||
|
|
||||||
|
pe_debug("FT Auth RX type %d subtype %d from " QDF_MAC_ADDR_FMT,
|
||||||
|
mac_hdr->fc.type, mac_hdr->fc.subType,
|
||||||
|
QDF_MAC_ADDR_REF(mac_hdr->sa));
|
||||||
|
|
||||||
|
if (LIM_IS_AP_ROLE(pe_session)) {
|
||||||
|
struct tLimPreAuthNode *sta_pre_auth_ctx;
|
||||||
|
|
||||||
|
rx_flags = RXMGMT_FLAG_EXTERNAL_AUTH;
|
||||||
|
/* Extract pre-auth context for the STA, if any. */
|
||||||
|
sta_pre_auth_ctx = lim_search_pre_auth_list(mac_ctx,
|
||||||
|
mac_hdr->sa);
|
||||||
|
if (sta_pre_auth_ctx) {
|
||||||
|
pe_debug("STA Auth ctx have ininted");
|
||||||
|
/* Pre-auth context exists for the STA */
|
||||||
|
if (sta_pre_auth_ctx->mlmState == eLIM_MLM_WT_FT_AUTH_STATE) {
|
||||||
|
pe_warn("previous Auth not completed, don't process this auth frame");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create entry for this STA in pre-auth list */
|
||||||
|
sta_pre_auth_ctx = lim_acquire_free_pre_auth_node(mac_ctx,
|
||||||
|
&mac_ctx->lim.gLimPreAuthTimerTable);
|
||||||
|
if (!sta_pre_auth_ctx) {
|
||||||
|
pe_warn("Max pre-auth nodes reached ");
|
||||||
|
lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGW);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pe_debug("Alloc new data: %pK peer", sta_pre_auth_ctx);
|
||||||
|
auth_algo = *(uint16_t *)body_ptr;
|
||||||
|
lim_print_mac_addr(mac_ctx, mac_hdr->sa, LOGD);
|
||||||
|
qdf_mem_copy((uint8_t *)sta_pre_auth_ctx->peerMacAddr,
|
||||||
|
mac_hdr->sa, sizeof(tSirMacAddr));
|
||||||
|
sta_pre_auth_ctx->mlmState = eLIM_MLM_WT_FT_AUTH_STATE;
|
||||||
|
sta_pre_auth_ctx->authType = (tAniAuthType) auth_algo;
|
||||||
|
sta_pre_auth_ctx->fSeen = 0;
|
||||||
|
sta_pre_auth_ctx->fTimerStarted = 0;
|
||||||
|
sta_pre_auth_ctx->seq_num =
|
||||||
|
((mac_hdr->seqControl.seqNumHi << 4) |
|
||||||
|
(mac_hdr->seqControl.seqNumLo));
|
||||||
|
sta_pre_auth_ctx->timestamp = qdf_mc_timer_get_system_ticks();
|
||||||
|
lim_add_pre_auth_node(mac_ctx, sta_pre_auth_ctx);
|
||||||
|
lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
|
||||||
|
(uint8_t *)mac_hdr,
|
||||||
|
frame_len + sizeof(tSirMacMgmtHdr),
|
||||||
|
pe_session->smeSessionId,
|
||||||
|
WMA_GET_RX_FREQ(rx_pkt_info),
|
||||||
|
WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
|
||||||
|
rx_flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t
|
static uint8_t
|
||||||
lim_get_pasn_peer_vdev_id(struct mac_context *mac, uint8_t *bssid)
|
lim_get_pasn_peer_vdev_id(struct mac_context *mac, uint8_t *bssid)
|
||||||
{
|
{
|
||||||
@@ -1669,6 +1736,11 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
|
|||||||
lim_process_pasn_auth_frame(mac_ctx, pe_session->vdev_id,
|
lim_process_pasn_auth_frame(mac_ctx, pe_session->vdev_id,
|
||||||
rx_pkt_info);
|
rx_pkt_info);
|
||||||
goto free;
|
goto free;
|
||||||
|
} else if (auth_alg == eSIR_FT_AUTH && LIM_IS_AP_ROLE(pe_session)) {
|
||||||
|
pe_debug("Auth Frame auth_alg eSIR_FT_AUTH");
|
||||||
|
lim_process_ft_auth_frame(mac_ctx,
|
||||||
|
rx_pkt_info, pe_session);
|
||||||
|
goto free;
|
||||||
} else if ((sir_convert_auth_frame2_struct(mac_ctx, body_ptr,
|
} else if ((sir_convert_auth_frame2_struct(mac_ctx, body_ptr,
|
||||||
frame_len, rx_auth_frame) != QDF_STATUS_SUCCESS)
|
frame_len, rx_auth_frame) != QDF_STATUS_SUCCESS)
|
||||||
|| (!is_auth_valid(mac_ctx, rx_auth_frame,
|
|| (!is_auth_valid(mac_ctx, rx_auth_frame,
|
||||||
|
@@ -6638,6 +6638,8 @@ void __lim_process_sme_assoc_cnf_new(struct mac_context *mac_ctx, uint32_t msg_t
|
|||||||
eLIM_MLM_LINK_ESTABLISHED_STATE;
|
eLIM_MLM_LINK_ESTABLISHED_STATE;
|
||||||
sta_ds->mlmStaContext.owe_ie = assoc_cnf.owe_ie;
|
sta_ds->mlmStaContext.owe_ie = assoc_cnf.owe_ie;
|
||||||
sta_ds->mlmStaContext.owe_ie_len = assoc_cnf.owe_ie_len;
|
sta_ds->mlmStaContext.owe_ie_len = assoc_cnf.owe_ie_len;
|
||||||
|
sta_ds->mlmStaContext.ft_ie = assoc_cnf.ft_ie;
|
||||||
|
sta_ds->mlmStaContext.ft_ie_len = assoc_cnf.ft_ie_len;
|
||||||
pe_debug("sending Assoc Rsp frame to STA assoc id=%d, tx cb %d",
|
pe_debug("sending Assoc Rsp frame to STA assoc id=%d, tx cb %d",
|
||||||
sta_ds->assocId, assoc_cnf.need_assoc_rsp_tx_cb);
|
sta_ds->assocId, assoc_cnf.need_assoc_rsp_tx_cb);
|
||||||
lim_send_assoc_rsp_mgmt_frame(
|
lim_send_assoc_rsp_mgmt_frame(
|
||||||
@@ -6648,6 +6650,8 @@ void __lim_process_sme_assoc_cnf_new(struct mac_context *mac_ctx, uint32_t msg_t
|
|||||||
assoc_cnf.need_assoc_rsp_tx_cb);
|
assoc_cnf.need_assoc_rsp_tx_cb);
|
||||||
sta_ds->mlmStaContext.owe_ie = NULL;
|
sta_ds->mlmStaContext.owe_ie = NULL;
|
||||||
sta_ds->mlmStaContext.owe_ie_len = 0;
|
sta_ds->mlmStaContext.owe_ie_len = 0;
|
||||||
|
sta_ds->mlmStaContext.ft_ie = NULL;
|
||||||
|
sta_ds->mlmStaContext.ft_ie_len = 0;
|
||||||
goto end;
|
goto end;
|
||||||
} else {
|
} else {
|
||||||
uint8_t add_pre_auth_context = true;
|
uint8_t add_pre_auth_context = true;
|
||||||
@@ -6691,6 +6695,7 @@ end:
|
|||||||
session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
|
session_entry->parsedAssocReq[sta_ds->assocId] = NULL;
|
||||||
}
|
}
|
||||||
qdf_mem_free(assoc_cnf.owe_ie);
|
qdf_mem_free(assoc_cnf.owe_ie);
|
||||||
|
qdf_mem_free(assoc_cnf.ft_ie);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -1906,9 +1906,10 @@ lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx,
|
|||||||
|
|
||||||
bytes += sizeof(tSirMacMgmtHdr) + payload + mlo_ie_len;
|
bytes += sizeof(tSirMacMgmtHdr) + payload + mlo_ie_len;
|
||||||
|
|
||||||
if (sta)
|
if (sta) {
|
||||||
bytes += sta->mlmStaContext.owe_ie_len;
|
bytes += sta->mlmStaContext.owe_ie_len;
|
||||||
|
bytes += sta->mlmStaContext.ft_ie_len;
|
||||||
|
}
|
||||||
qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
|
qdf_status = cds_packet_alloc((uint16_t) bytes, (void **)&frame,
|
||||||
(void **)&packet);
|
(void **)&packet);
|
||||||
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
||||||
@@ -2028,6 +2029,13 @@ lim_send_assoc_rsp_mgmt_frame(struct mac_context *mac_ctx,
|
|||||||
payload += sta->mlmStaContext.owe_ie_len;
|
payload += sta->mlmStaContext.owe_ie_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sta && sta->mlmStaContext.ft_ie_len) {
|
||||||
|
qdf_mem_copy(frame + sizeof(tSirMacMgmtHdr) + payload,
|
||||||
|
sta->mlmStaContext.ft_ie,
|
||||||
|
sta->mlmStaContext.ft_ie_len);
|
||||||
|
payload += sta->mlmStaContext.ft_ie_len;
|
||||||
|
}
|
||||||
|
|
||||||
if (sta && mlo_ie_len) {
|
if (sta && mlo_ie_len) {
|
||||||
qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len,
|
qdf_status = lim_fill_complete_mlo_ie(pe_session, mlo_ie_len,
|
||||||
frame + sizeof(tSirMacMgmtHdr) + payload);
|
frame + sizeof(tSirMacMgmtHdr) + payload);
|
||||||
@@ -6610,6 +6618,19 @@ void lim_send_mgmt_frame_tx(struct mac_context *mac_ctx,
|
|||||||
if (auth_algo == eSIR_AUTH_TYPE_SAE)
|
if (auth_algo == eSIR_AUTH_TYPE_SAE)
|
||||||
lim_handle_sae_auth_retry(mac_ctx, vdev_id,
|
lim_handle_sae_auth_retry(mac_ctx, vdev_id,
|
||||||
mb_msg->data, msg_len);
|
mb_msg->data, msg_len);
|
||||||
|
if (auth_algo == eSIR_FT_AUTH) {
|
||||||
|
struct tLimPreAuthNode *sta_pre_auth_ctx;
|
||||||
|
|
||||||
|
sta_pre_auth_ctx = lim_search_pre_auth_list(mac_ctx,
|
||||||
|
((tpSirMacMgmtHdr)(mb_msg->data))->da);
|
||||||
|
pe_debug("FT Auth TX to " QDF_MAC_ADDR_FMT,
|
||||||
|
QDF_MAC_ADDR_REF(((tpSirMacMgmtHdr)(mb_msg->data))->da));
|
||||||
|
if (sta_pre_auth_ctx) {
|
||||||
|
pe_debug("STA is AUTHENTICATED_STATE");
|
||||||
|
sta_pre_auth_ctx->mlmState =
|
||||||
|
eLIM_MLM_AUTHENTICATED_STATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD;
|
mac_ctx->auth_ack_status = LIM_ACK_NOT_RCD;
|
||||||
lim_send_frame(mac_ctx, vdev_id, mb_msg->data, msg_len);
|
lim_send_frame(mac_ctx, vdev_id, mb_msg->data, msg_len);
|
||||||
|
@@ -1501,6 +1501,20 @@ QDF_STATUS wlansap_update_owe_info(struct sap_context *sap_ctx,
|
|||||||
uint8_t *peer, const uint8_t *ie,
|
uint8_t *peer, const uint8_t *ie,
|
||||||
uint32_t ie_len, uint16_t owe_status);
|
uint32_t ie_len, uint16_t owe_status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wlansap_update_ft_info() - Update FT info
|
||||||
|
* @sap_ctx: sap context
|
||||||
|
* @peer: peer mac
|
||||||
|
* @ie: IE from hostapd
|
||||||
|
* @ie_len: IE length
|
||||||
|
* @ft_status: wlan status codes
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
QDF_STATUS wlansap_update_ft_info(struct sap_context *sap_ctx,
|
||||||
|
uint8_t *peer, const uint8_t *ie,
|
||||||
|
uint32_t ie_len, uint16_t ft_status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wlansap_filter_ch_based_acs() -filter out channel based on acs
|
* wlansap_filter_ch_based_acs() -filter out channel based on acs
|
||||||
* @sap_ctx: sap context
|
* @sap_ctx: sap context
|
||||||
|
@@ -1898,6 +1898,27 @@ static bool sap_save_owe_pending_assoc_ind(struct sap_context *sap_ctx,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sap_save_ft_pending_assoc_ind(struct sap_context *sap_ctx,
|
||||||
|
struct assoc_ind *sme_assoc_ind)
|
||||||
|
{
|
||||||
|
struct ft_assoc_ind *assoc_ind;
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
assoc_ind = qdf_mem_malloc(sizeof(*assoc_ind));
|
||||||
|
if (!assoc_ind)
|
||||||
|
return false;
|
||||||
|
assoc_ind->assoc_ind = sme_assoc_ind;
|
||||||
|
status = qdf_list_insert_back(&sap_ctx->ft_pending_assoc_ind_list,
|
||||||
|
&assoc_ind->node);
|
||||||
|
if (QDF_STATUS_SUCCESS != status) {
|
||||||
|
qdf_mem_free(assoc_ind);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
qdf_event_set(&sap_ctx->ft_pending_event);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef FEATURE_RADAR_HISTORY
|
#ifdef FEATURE_RADAR_HISTORY
|
||||||
/* Last cac result */
|
/* Last cac result */
|
||||||
static struct prev_cac_result prev_cac_history;
|
static struct prev_cac_result prev_cac_history;
|
||||||
@@ -2313,6 +2334,18 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx,
|
|||||||
}
|
}
|
||||||
csr_roaminfo->owe_pending_assoc_ind = NULL;
|
csr_roaminfo->owe_pending_assoc_ind = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (csr_roaminfo->ft_pending_assoc_ind) {
|
||||||
|
if (!sap_save_ft_pending_assoc_ind(sap_ctx,
|
||||||
|
csr_roaminfo->ft_pending_assoc_ind)) {
|
||||||
|
sap_err("Failed to save ft assoc ind");
|
||||||
|
qdf_mem_free(csr_roaminfo->ft_pending_assoc_ind);
|
||||||
|
csr_roaminfo->ft_pending_assoc_ind = NULL;
|
||||||
|
qdf_mem_free(sap_ap_event);
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
csr_roaminfo->ft_pending_assoc_ind = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case eSAP_START_BSS_EVENT:
|
case eSAP_START_BSS_EVENT:
|
||||||
sap_ap_event->sapHddEventCode = eSAP_START_BSS_EVENT;
|
sap_ap_event->sapHddEventCode = eSAP_START_BSS_EVENT;
|
||||||
|
@@ -229,6 +229,8 @@ struct sap_context {
|
|||||||
/* Disabled mcs13 by sap or not */
|
/* Disabled mcs13 by sap or not */
|
||||||
bool disabled_mcs13;
|
bool disabled_mcs13;
|
||||||
qdf_list_t owe_pending_assoc_ind_list;
|
qdf_list_t owe_pending_assoc_ind_list;
|
||||||
|
qdf_list_t ft_pending_assoc_ind_list;
|
||||||
|
qdf_event_t ft_pending_event;
|
||||||
uint32_t freq_before_ch_switch;
|
uint32_t freq_before_ch_switch;
|
||||||
#ifdef WLAN_FEATURE_P2P_P2P_STA
|
#ifdef WLAN_FEATURE_P2P_P2P_STA
|
||||||
/*
|
/*
|
||||||
|
@@ -239,6 +239,14 @@ static QDF_STATUS wlansap_owe_init(struct sap_context *sap_ctx)
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QDF_STATUS wlansap_ft_init(struct sap_context *sap_ctx)
|
||||||
|
{
|
||||||
|
qdf_list_create(&sap_ctx->ft_pending_assoc_ind_list, 0);
|
||||||
|
qdf_event_create(&sap_ctx->ft_pending_event);
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static void wlansap_owe_cleanup(struct sap_context *sap_ctx)
|
static void wlansap_owe_cleanup(struct sap_context *sap_ctx)
|
||||||
{
|
{
|
||||||
struct mac_context *mac;
|
struct mac_context *mac;
|
||||||
@@ -289,11 +297,65 @@ static void wlansap_owe_cleanup(struct sap_context *sap_ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wlansap_ft_cleanup(struct sap_context *sap_ctx)
|
||||||
|
{
|
||||||
|
struct mac_context *mac;
|
||||||
|
struct ft_assoc_ind *ft_assoc_ind;
|
||||||
|
struct assoc_ind *assoc_ind = NULL;
|
||||||
|
qdf_list_node_t *node = NULL, *next_node = NULL;
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
if (!sap_ctx) {
|
||||||
|
sap_err("Invalid SAP context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mac = sap_get_mac_context();
|
||||||
|
if (!mac) {
|
||||||
|
sap_err("Invalid MAC context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QDF_STATUS_SUCCESS !=
|
||||||
|
qdf_list_peek_front(&sap_ctx->ft_pending_assoc_ind_list,
|
||||||
|
&node)) {
|
||||||
|
sap_debug("Failed to find assoc ind list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
qdf_list_peek_next(&sap_ctx->ft_pending_assoc_ind_list,
|
||||||
|
node, &next_node);
|
||||||
|
ft_assoc_ind = qdf_container_of(node, struct ft_assoc_ind,
|
||||||
|
node);
|
||||||
|
status = qdf_list_remove_node(
|
||||||
|
&sap_ctx->ft_pending_assoc_ind_list, node);
|
||||||
|
if (status == QDF_STATUS_SUCCESS) {
|
||||||
|
assoc_ind = ft_assoc_ind->assoc_ind;
|
||||||
|
qdf_mem_free(ft_assoc_ind);
|
||||||
|
assoc_ind->ft_ie = NULL;
|
||||||
|
assoc_ind->ft_ie_len = 0;
|
||||||
|
assoc_ind->ft_status = STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
qdf_mem_free(assoc_ind);
|
||||||
|
} else {
|
||||||
|
sap_err("Failed to remove assoc ind");
|
||||||
|
}
|
||||||
|
node = next_node;
|
||||||
|
next_node = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void wlansap_owe_deinit(struct sap_context *sap_ctx)
|
static void wlansap_owe_deinit(struct sap_context *sap_ctx)
|
||||||
{
|
{
|
||||||
qdf_list_destroy(&sap_ctx->owe_pending_assoc_ind_list);
|
qdf_list_destroy(&sap_ctx->owe_pending_assoc_ind_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wlansap_ft_deinit(struct sap_context *sap_ctx)
|
||||||
|
{
|
||||||
|
qdf_list_destroy(&sap_ctx->ft_pending_assoc_ind_list);
|
||||||
|
qdf_event_destroy(&sap_ctx->ft_pending_event);
|
||||||
|
}
|
||||||
|
|
||||||
QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
|
QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
|
||||||
enum QDF_OPMODE mode,
|
enum QDF_OPMODE mode,
|
||||||
uint8_t *addr, uint32_t session_id, bool reinit)
|
uint8_t *addr, uint32_t session_id, bool reinit)
|
||||||
@@ -334,6 +396,11 @@ QDF_STATUS sap_init_ctx(struct sap_context *sap_ctx,
|
|||||||
sap_err("OWE init failed");
|
sap_err("OWE init failed");
|
||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
}
|
}
|
||||||
|
status = wlansap_ft_init(sap_ctx);
|
||||||
|
if (QDF_STATUS_SUCCESS != status) {
|
||||||
|
sap_err("FT init failed");
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
@@ -351,9 +418,10 @@ QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx)
|
|||||||
return QDF_STATUS_E_FAULT;
|
return QDF_STATUS_E_FAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wlansap_ft_cleanup(sap_ctx);
|
||||||
|
wlansap_ft_deinit(sap_ctx);
|
||||||
wlansap_owe_cleanup(sap_ctx);
|
wlansap_owe_cleanup(sap_ctx);
|
||||||
wlansap_owe_deinit(sap_ctx);
|
wlansap_owe_deinit(sap_ctx);
|
||||||
|
|
||||||
mac = sap_get_mac_context();
|
mac = sap_get_mac_context();
|
||||||
if (!mac) {
|
if (!mac) {
|
||||||
sap_err("Invalid MAC context");
|
sap_err("Invalid MAC context");
|
||||||
@@ -3000,6 +3068,71 @@ QDF_STATUS wlansap_update_owe_info(struct sap_context *sap_ctx,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDF_STATUS wlansap_update_ft_info(struct sap_context *sap_ctx,
|
||||||
|
uint8_t *peer, const uint8_t *ie,
|
||||||
|
uint32_t ie_len, uint16_t ft_status)
|
||||||
|
{
|
||||||
|
struct mac_context *mac;
|
||||||
|
struct ft_assoc_ind *ft_assoc_ind;
|
||||||
|
struct assoc_ind *assoc_ind = NULL;
|
||||||
|
qdf_list_node_t *node = NULL, *next_node = NULL;
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
if (!sap_ctx) {
|
||||||
|
sap_err("Invalid SAP context");
|
||||||
|
return QDF_STATUS_E_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
mac = sap_get_mac_context();
|
||||||
|
if (!mac) {
|
||||||
|
sap_err("Invalid MAC context");
|
||||||
|
return QDF_STATUS_E_FAULT;
|
||||||
|
}
|
||||||
|
status = qdf_wait_single_event(&sap_ctx->ft_pending_event,
|
||||||
|
500);
|
||||||
|
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||||
|
sap_err("wait for ft pending event timeout");
|
||||||
|
wlansap_ft_cleanup(sap_ctx);
|
||||||
|
return QDF_STATUS_E_FAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QDF_STATUS_SUCCESS !=
|
||||||
|
qdf_list_peek_front(&sap_ctx->ft_pending_assoc_ind_list,
|
||||||
|
&next_node)) {
|
||||||
|
sap_err("Failed to find ft assoc ind list");
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
node = next_node;
|
||||||
|
ft_assoc_ind = qdf_container_of(node, struct ft_assoc_ind, node);
|
||||||
|
if (qdf_mem_cmp(peer,
|
||||||
|
ft_assoc_ind->assoc_ind->peerMacAddr,
|
||||||
|
QDF_MAC_ADDR_SIZE) == 0) {
|
||||||
|
status = qdf_list_remove_node(&sap_ctx->ft_pending_assoc_ind_list,
|
||||||
|
node);
|
||||||
|
if (status != QDF_STATUS_SUCCESS) {
|
||||||
|
sap_err("Failed to remove ft assoc ind");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
assoc_ind = ft_assoc_ind->assoc_ind;
|
||||||
|
qdf_mem_free(ft_assoc_ind);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (QDF_STATUS_SUCCESS ==
|
||||||
|
qdf_list_peek_next(&sap_ctx->ft_pending_assoc_ind_list,
|
||||||
|
node, &next_node));
|
||||||
|
|
||||||
|
if (assoc_ind) {
|
||||||
|
assoc_ind->ft_ie = ie;
|
||||||
|
assoc_ind->ft_ie_len = ie_len;
|
||||||
|
assoc_ind->ft_status = ft_status;
|
||||||
|
status = sme_update_ft_info(mac, assoc_ind);
|
||||||
|
qdf_mem_free(assoc_ind);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
bool wlansap_is_channel_present_in_acs_list(uint32_t freq,
|
bool wlansap_is_channel_present_in_acs_list(uint32_t freq,
|
||||||
uint32_t *ch_freq_list,
|
uint32_t *ch_freq_list,
|
||||||
uint8_t ch_count)
|
uint8_t ch_count)
|
||||||
|
@@ -593,6 +593,8 @@ struct csr_roam_info {
|
|||||||
struct sir_sae_info *sae_info;
|
struct sir_sae_info *sae_info;
|
||||||
#endif
|
#endif
|
||||||
struct assoc_ind *owe_pending_assoc_ind;
|
struct assoc_ind *owe_pending_assoc_ind;
|
||||||
|
struct assoc_ind *ft_pending_assoc_ind;
|
||||||
|
|
||||||
struct qdf_mac_addr peer_mld;
|
struct qdf_mac_addr peer_mld;
|
||||||
#ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
|
#ifdef WLAN_FEATURE_SAP_ACS_OPTIMIZE
|
||||||
uint32_t chan_info_freq;
|
uint32_t chan_info_freq;
|
||||||
@@ -859,6 +861,17 @@ static inline void csr_packetdump_timer_start(void) {}
|
|||||||
QDF_STATUS csr_update_owe_info(struct mac_context *mac,
|
QDF_STATUS csr_update_owe_info(struct mac_context *mac,
|
||||||
struct assoc_ind *assoc_ind);
|
struct assoc_ind *assoc_ind);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* csr_update_ft_info() - Update FT info
|
||||||
|
* @mac: mac context
|
||||||
|
* @assoc_ind: assoc ind
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
|
||||||
|
QDF_STATUS csr_update_ft_info(struct mac_context *mac,
|
||||||
|
struct assoc_ind *assoc_ind);
|
||||||
|
|
||||||
typedef void (*csr_ani_callback)(int8_t *ani, void *context);
|
typedef void (*csr_ani_callback)(int8_t *ani, void *context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -4236,6 +4236,17 @@ QDF_STATUS sme_update_hidden_ssid_status_cb(mac_handle_t mac_handle,
|
|||||||
QDF_STATUS sme_update_owe_info(struct mac_context *mac,
|
QDF_STATUS sme_update_owe_info(struct mac_context *mac,
|
||||||
struct assoc_ind *assoc_ind);
|
struct assoc_ind *assoc_ind);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sme_update_ft_info() - Update FT info
|
||||||
|
* @mac: mac context
|
||||||
|
* @assoc_ind: assoc ind
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
|
||||||
|
QDF_STATUS sme_update_ft_info(struct mac_context *mac,
|
||||||
|
struct assoc_ind *assoc_ind);
|
||||||
|
|
||||||
#ifdef WLAN_MWS_INFO_DEBUGFS
|
#ifdef WLAN_MWS_INFO_DEBUGFS
|
||||||
/**
|
/**
|
||||||
* sme_get_mws_coex_info() - SME API to get the coex information
|
* sme_get_mws_coex_info() - SME API to get the coex information
|
||||||
|
@@ -15765,6 +15765,20 @@ QDF_STATUS sme_update_owe_info(struct mac_context *mac,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDF_STATUS sme_update_ft_info(struct mac_context *mac,
|
||||||
|
struct assoc_ind *assoc_ind)
|
||||||
|
{
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
status = sme_acquire_global_lock(&mac->sme);
|
||||||
|
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||||
|
status = csr_update_ft_info(mac, assoc_ind);
|
||||||
|
sme_release_global_lock(&mac->sme);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WLAN_MWS_INFO_DEBUGFS
|
#ifdef WLAN_MWS_INFO_DEBUGFS
|
||||||
QDF_STATUS
|
QDF_STATUS
|
||||||
sme_get_mws_coex_info(mac_handle_t mac_handle, uint32_t vdev_id,
|
sme_get_mws_coex_info(mac_handle_t mac_handle, uint32_t vdev_id,
|
||||||
|
@@ -4006,12 +4006,19 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|||||||
} else {
|
} else {
|
||||||
roam_info->fAuthRequired = true;
|
roam_info->fAuthRequired = true;
|
||||||
}
|
}
|
||||||
|
sme_debug("Receive AUTH_TYPE of %d", csr_akm_type);
|
||||||
if (csr_akm_type == eCSR_AUTH_TYPE_OWE) {
|
if (csr_akm_type == eCSR_AUTH_TYPE_OWE) {
|
||||||
roam_info->owe_pending_assoc_ind = qdf_mem_malloc(
|
roam_info->owe_pending_assoc_ind = qdf_mem_malloc(
|
||||||
sizeof(*pAssocInd));
|
sizeof(*pAssocInd));
|
||||||
if (roam_info->owe_pending_assoc_ind)
|
if (roam_info->owe_pending_assoc_ind)
|
||||||
qdf_mem_copy(roam_info->owe_pending_assoc_ind,
|
qdf_mem_copy(roam_info->owe_pending_assoc_ind,
|
||||||
pAssocInd, sizeof(*pAssocInd));
|
pAssocInd, sizeof(*pAssocInd));
|
||||||
|
} else if (csr_akm_type == eCSR_AUTH_TYPE_FT_RSN_PSK) {
|
||||||
|
roam_info->ft_pending_assoc_ind = qdf_mem_malloc(
|
||||||
|
sizeof(*pAssocInd));
|
||||||
|
if (roam_info->ft_pending_assoc_ind)
|
||||||
|
qdf_mem_copy(roam_info->ft_pending_assoc_ind,
|
||||||
|
pAssocInd, sizeof(*pAssocInd));
|
||||||
}
|
}
|
||||||
status = csr_roam_call_callback(mac_ctx, sessionId,
|
status = csr_roam_call_callback(mac_ctx, sessionId,
|
||||||
roam_info, eCSR_ROAM_INFRA_IND,
|
roam_info, eCSR_ROAM_INFRA_IND,
|
||||||
@@ -4042,8 +4049,10 @@ csr_roam_chk_lnk_assoc_ind(struct mac_context *mac_ctx, tSirSmeRsp *msg_ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sme_debug("csr_akm_type: %d", csr_akm_type);
|
||||||
|
|
||||||
if (csr_akm_type != eCSR_AUTH_TYPE_OWE) {
|
if (csr_akm_type != eCSR_AUTH_TYPE_OWE &&
|
||||||
|
csr_akm_type != eCSR_AUTH_TYPE_FT_RSN_PSK) {
|
||||||
if ((opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) &&
|
if ((opmode == QDF_SAP_MODE || opmode == QDF_P2P_GO_MODE) &&
|
||||||
roam_info->status_code != eSIR_SME_ASSOC_REFUSED)
|
roam_info->status_code != eSIR_SME_ASSOC_REFUSED)
|
||||||
pAssocInd->need_assoc_rsp_tx_cb = true;
|
pAssocInd->need_assoc_rsp_tx_cb = true;
|
||||||
@@ -6140,6 +6149,15 @@ QDF_STATUS csr_send_assoc_cnf_msg(struct mac_context *mac,
|
|||||||
pAssocInd->owe_ie_len);
|
pAssocInd->owe_ie_len);
|
||||||
pMsg->owe_ie_len = pAssocInd->owe_ie_len;
|
pMsg->owe_ie_len = pAssocInd->owe_ie_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pAssocInd->ft_ie_len) {
|
||||||
|
pMsg->ft_ie = qdf_mem_malloc(pAssocInd->ft_ie_len);
|
||||||
|
if (!pMsg->ft_ie)
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
qdf_mem_copy(pMsg->ft_ie, pAssocInd->ft_ie,
|
||||||
|
pAssocInd->ft_ie_len);
|
||||||
|
pMsg->ft_ie_len = pAssocInd->ft_ie_len;
|
||||||
|
}
|
||||||
pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb;
|
pMsg->need_assoc_rsp_tx_cb = pAssocInd->need_assoc_rsp_tx_cb;
|
||||||
|
|
||||||
msg.type = pMsg->messageType;
|
msg.type = pMsg->messageType;
|
||||||
@@ -7713,6 +7731,19 @@ QDF_STATUS csr_update_owe_info(struct mac_context *mac,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDF_STATUS csr_update_ft_info(struct mac_context *mac,
|
||||||
|
struct assoc_ind *assoc_ind)
|
||||||
|
{
|
||||||
|
QDF_STATUS status;
|
||||||
|
|
||||||
|
/* Send Association completion message to PE */
|
||||||
|
status = assoc_ind->ft_status ? QDF_STATUS_E_INVAL : QDF_STATUS_SUCCESS;
|
||||||
|
assoc_ind->need_assoc_rsp_tx_cb = true;
|
||||||
|
status = csr_send_assoc_cnf_msg(mac, assoc_ind, status,
|
||||||
|
assoc_ind->ft_status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* csr_set_sap_ser_params() - API to fill serialization parameters for
|
* csr_set_sap_ser_params() - API to fill serialization parameters for
|
||||||
* SAP requests
|
* SAP requests
|
||||||
|
Referencia en una nueva incidencia
Block a user