|
@@ -239,6 +239,14 @@ static QDF_STATUS wlansap_owe_init(struct sap_context *sap_ctx)
|
|
|
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)
|
|
|
{
|
|
|
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)
|
|
|
{
|
|
|
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,
|
|
|
enum QDF_OPMODE mode,
|
|
|
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");
|
|
|
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;
|
|
@@ -351,9 +418,10 @@ QDF_STATUS sap_deinit_ctx(struct sap_context *sap_ctx)
|
|
|
return QDF_STATUS_E_FAULT;
|
|
|
}
|
|
|
|
|
|
+ wlansap_ft_cleanup(sap_ctx);
|
|
|
+ wlansap_ft_deinit(sap_ctx);
|
|
|
wlansap_owe_cleanup(sap_ctx);
|
|
|
wlansap_owe_deinit(sap_ctx);
|
|
|
-
|
|
|
mac = sap_get_mac_context();
|
|
|
if (!mac) {
|
|
|
sap_err("Invalid MAC context");
|
|
@@ -3000,6 +3068,71 @@ QDF_STATUS wlansap_update_owe_info(struct sap_context *sap_ctx,
|
|
|
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,
|
|
|
uint32_t *ch_freq_list,
|
|
|
uint8_t ch_count)
|