Jelajahi Sumber

qcacld-3.0: Add roaming support in hdd for conenction manager

Add roaming support in hdd for conenction manager.

Change-Id: Id93e3411ab8dedca89768042b5fc96b318447846
CRs-fixed: 2881820
gaurank kathpalia 4 tahun lalu
induk
melakukan
a06175edf3

+ 4 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -115,6 +115,10 @@
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 #define ROAM_SCAN_PSK_SIZE    48
 #define ROAM_R0KH_ID_MAX_LEN  48
+/* connected but not authenticated */
+#define ROAM_AUTH_STATUS_CONNECTED      0x1
+/* connected and authenticated */
+#define ROAM_AUTH_STATUS_AUTHENTICATED  0x2
 #endif
 
 /*

+ 14 - 0
core/hdd/inc/wlan_hdd_assoc.h

@@ -208,6 +208,20 @@ struct hdd_context;
 bool hdd_is_fils_connection(struct hdd_context *hdd_ctx,
 			    struct hdd_adapter *adapter);
 
+/**
+ * hdd_conn_set_authenticated() - set authentication state
+ * @adapter: pointer to the adapter
+ * @auth_state: authentication state
+ *
+ * This function updates the global HDD station context
+ * authentication state. And to start auto powersave timer
+ * if ptk installed case and open security case.
+ *
+ * Return: none
+ */
+void
+hdd_conn_set_authenticated(struct hdd_adapter *adapter, uint8_t auth_state);
+
 /**
  * hdd_conn_set_connection_state() - set connection state
  * @adapter: pointer to the adapter

+ 8 - 96
core/hdd/src/wlan_hdd_assoc.c

@@ -283,19 +283,7 @@ static void hdd_start_powersave_timer_on_associated(struct hdd_adapter *adapter)
 				    timeout);
 }
 
-/**
- * hdd_conn_set_authenticated() - set authentication state
- * @adapter: pointer to the adapter
- * @auth_state: authentication state
- *
- * This function updates the global HDD station context
- * authentication state. And to start auto powersave timer
- * if ptk installed case and open security case.
- *
- * Return: none
- */
-static void
-hdd_conn_set_authenticated(struct hdd_adapter *adapter, uint8_t auth_state)
+void hdd_conn_set_authenticated(struct hdd_adapter *adapter, uint8_t auth_state)
 {
 	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 	char *auth_time;
@@ -2034,21 +2022,6 @@ QDF_STATUS hdd_update_dp_vdev_flags(void *cbk_data,
 	return status;
 }
 
-/**
- * hdd_conn_change_peer_state() - Change the state of the peer
- * @adapter: pointer to adapter
- * @mac_addr: peer mac address
- * @sta_state: peer state
- *
- * Return: QDF_STATUS enumeration
- */
-static QDF_STATUS hdd_conn_change_peer_state(struct hdd_adapter *adapter,
-					     uint8_t *mac_addr,
-					     enum ol_txrx_peer_state sta_state)
-{
-	return hdd_change_peer_state(adapter, mac_addr, sta_state);
-}
-
 #if defined(WLAN_SUPPORT_RX_FISA)
 /**
  * hdd_rx_register_fisa_ops() - FISA callback functions
@@ -2143,31 +2116,8 @@ QDF_STATUS hdd_roam_register_sta(struct hdd_adapter *adapter,
 		return qdf_status;
 	}
 
-	if (!is_auth_required) {
-		/*
-		 * Connections that do not need Upper layer auth, transition
-		 * TLSHIM directly to 'Authenticated' state
-		 */
-		qdf_status = hdd_conn_change_peer_state(
-						adapter,
-						txrx_desc.peer_addr.bytes,
-						OL_TXRX_PEER_STATE_AUTH);
-
-		hdd_conn_set_authenticated(adapter, true);
-		hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true);
-	} else {
-		hdd_debug("ULA auth Sta: " QDF_MAC_ADDR_FMT
-			  " Changing TL state to CONNECTED at Join time",
-			  QDF_MAC_ADDR_REF(txrx_desc.peer_addr.bytes));
-
-		qdf_status = hdd_conn_change_peer_state(
-						adapter,
-						txrx_desc.peer_addr.bytes,
-						OL_TXRX_PEER_STATE_CONN);
+	hdd_cm_set_peer_authenticate(adapter, bssid, is_auth_required);
 
-		hdd_conn_set_authenticated(adapter, false);
-		hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, false);
-	}
 	return qdf_status;
 }
 
@@ -2440,24 +2390,15 @@ done:
 static int hdd_change_sta_state_authenticated(struct hdd_adapter *adapter,
 					      struct csr_roam_info *roaminfo)
 {
-	QDF_STATUS status;
 	uint8_t *mac_addr;
 	struct hdd_station_ctx *hddstactx =
 		WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 
 	mac_addr = hddstactx->conn_info.bssid.bytes;
-	hdd_debug("Changing Peer state to AUTHENTICATED for Sta = "
-		  QDF_MAC_ADDR_FMT, QDF_MAC_ADDR_REF(mac_addr));
+	hdd_cm_set_peer_authenticate(adapter, &hddstactx->conn_info.bssid,
+				     false);
 
-	/* Connections that do not need Upper layer authentication,
-	 * transition TL to 'Authenticated' state after the keys are set
-	 */
-	status = hdd_change_peer_state(adapter, mac_addr,
-				       OL_TXRX_PEER_STATE_AUTH);
-	hdd_conn_set_authenticated(adapter, true);
-	hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, true);
-
-	return qdf_status_to_os_return(status);
+	return 0;
 }
 
 /**
@@ -3061,38 +3002,9 @@ hdd_association_completion_handler(struct hdd_adapter *adapter,
 			hdd_send_re_assoc_event(dev, adapter, roam_info,
 						reqRsnIe, reqRsnLength);
 			/* Reassoc successfully */
-			if (roam_info->fAuthRequired) {
-				qdf_status =
-					hdd_change_peer_state(adapter,
-						roam_info->bssid.bytes,
-						OL_TXRX_PEER_STATE_CONN);
-				hdd_conn_set_authenticated(adapter, false);
-				hdd_objmgr_set_peer_mlme_auth_state(
-							adapter->vdev,
-							false);
-			} else {
-				hdd_debug("sta: " QDF_MAC_ADDR_FMT
-					  "Changing TL state to AUTHENTICATED",
-					  QDF_MAC_ADDR_REF(
-					  roam_info->bssid.bytes));
-				qdf_status =
-					hdd_change_peer_state(adapter,
-						roam_info->bssid.bytes,
-						OL_TXRX_PEER_STATE_AUTH);
-				hdd_conn_set_authenticated(adapter, true);
-				hdd_objmgr_set_peer_mlme_auth_state(
-							adapter->vdev,
-							true);
-			}
-
-			if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
-				/*
-				 * Perform any WMM-related association
-				 * processing
-				 */
-				hdd_wmm_assoc(adapter, true,
-					      uapsd_mask);
-			}
+			hdd_cm_set_peer_authenticate(adapter, &roam_info->bssid,
+						     roam_info->fAuthRequired);
+			hdd_wmm_assoc(adapter, true, uapsd_mask);
 
 			/* Start the tx queues */
 			hdd_debug("Enabling queues");

+ 1 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -6747,7 +6747,7 @@ int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter, uint8_t *bssid,
 		goto nla_put_failure;
 	}
 	if (roam_info_ptr->synchAuthStatus ==
-			CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
+			ROAM_AUTH_STATUS_AUTHENTICATED) {
 		hdd_debug("Include Auth Params TLV's");
 		if (nla_put_u8(skb,
 			QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, true)) {

+ 12 - 0
core/hdd/src/wlan_hdd_cm_api.h

@@ -166,6 +166,18 @@ void __hdd_cm_disconnect_handler_pre_user_update(struct hdd_adapter *adapter);
  */
 void __hdd_cm_disconnect_handler_post_user_update(struct hdd_adapter *adapter);
 
+/**
+ * hdd_cm_set_peer_authenticate() - set peer as authenticated
+ * @adapter: pointer to adapter
+ * @bssid: bssid of the connection
+ * @is_auth_required: is upper layer authenticatoin required
+ *
+ * Return: QDF_STATUS enumeration
+ */
+void hdd_cm_set_peer_authenticate(struct hdd_adapter *adapter,
+				  struct qdf_mac_addr *bssid,
+				  bool is_auth_required);
+
 /**
  * hdd_cm_update_rssi_snr_by_bssid() - update rsi and snr into adapter
  * @adapter: Pointer to adapter

+ 93 - 27
core/hdd/src/wlan_hdd_cm_connect.c

@@ -171,6 +171,22 @@ bool hdd_cm_is_disconnecting(struct hdd_adapter *adapter)
 }
 #endif
 
+void hdd_cm_set_peer_authenticate(struct hdd_adapter *adapter,
+				  struct qdf_mac_addr *bssid,
+				  bool is_auth_required)
+{
+	hdd_debug("sta: " QDF_MAC_ADDR_FMT "Changing TL state to %s",
+		  QDF_MAC_ADDR_REF(bssid->bytes),
+		  is_auth_required ? "CONNECTED" : "AUTHENTICATED");
+
+	hdd_change_peer_state(adapter, bssid->bytes,
+			      is_auth_required ?
+			      OL_TXRX_PEER_STATE_CONN :
+			      OL_TXRX_PEER_STATE_AUTH);
+	hdd_conn_set_authenticated(adapter, !is_auth_required);
+	hdd_objmgr_set_peer_mlme_auth_state(adapter->vdev, !is_auth_required);
+}
+
 void hdd_cm_update_rssi_snr_by_bssid(struct hdd_adapter *adapter)
 {
 	struct hdd_station_ctx *sta_ctx;
@@ -442,9 +458,13 @@ hdd_cm_connect_failure_post_user_update(struct wlan_objmgr_vdev *vdev,
 	struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
 	struct hdd_adapter *adapter = hdd_get_adapter_by_vdev(hdd_ctx,
 						wlan_vdev_get_id(vdev));
+	bool is_roam = false;
 
-	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
-	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+	if (!is_roam) {
+		/* call only for connect */
+		qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
+		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+	}
 	sme_reset_key(hdd_ctx->mac_handle, adapter->vdev_id);
 	hdd_wmm_dscp_initial_state(adapter);
 	hdd_debug("Disabling queues");
@@ -763,6 +783,7 @@ hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev *vdev,
 	uint32_t ie_len;
 	uint8_t *ie_field;
 	mac_handle_t mac_handle;
+	bool is_roam = false;
 
 	hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
 	if (!hdd_ctx) {
@@ -844,31 +865,33 @@ hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev *vdev,
 			wlan_hdd_set_mas(adapter, hdd_ctx->miracast_value);
 	}
 
-	/* Initialize the Linkup event completion variable */
-	INIT_COMPLETION(adapter->linkup_event_var);
+	if (!is_roam) {
+		/* Initialize the Linkup event completion variable */
+		INIT_COMPLETION(adapter->linkup_event_var);
 
-	/*
-	 * Enable Linkup Event Servicing which allows the net
-	 * device notifier to set the linkup event variable.
-	 */
-	adapter->is_link_up_service_needed = true;
+		/*
+		 * Enable Linkup Event Servicing which allows the net
+		 * device notifier to set the linkup event variable.
+		 */
+		adapter->is_link_up_service_needed = true;
 
-	/* Switch on the Carrier to activate the device */
-	wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_CARRIER_ON,
-				     WLAN_CONTROL_PATH);
+		/* Switch on the Carrier to activate the device */
+		wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_CARRIER_ON,
+					     WLAN_CONTROL_PATH);
 
-	/*
-	 * Wait for the Link to up to ensure all the queues
-	 * are set properly by the kernel.
-	 */
-	rc = wait_for_completion_timeout(
-				&adapter->linkup_event_var,
-				 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT));
-	/*
-	 * Disable Linkup Event Servicing - no more service
-	 * required from the net device notifier call.
-	 */
-	adapter->is_link_up_service_needed = false;
+		/*
+		 * Wait for the Link to up to ensure all the queues
+		 * are set properly by the kernel.
+		 */
+		rc = wait_for_completion_timeout(
+					&adapter->linkup_event_var,
+					 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT));
+		/*
+		 * Disable Linkup Event Servicing - no more service
+		 * required from the net device notifier call.
+		 */
+		adapter->is_link_up_service_needed = false;
+	}
 
 	if (ucfg_ipa_is_enabled())
 		ucfg_ipa_wlan_evt(hdd_ctx->pdev, adapter->dev,
@@ -884,6 +907,8 @@ hdd_cm_connect_success_pre_user_update(struct wlan_objmgr_vdev *vdev,
 		QDF_TRACE_DEFAULT_PDEV_ID,
 		QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
 
+	if (is_roam)
+		hdd_nud_indicate_roam(adapter);
 	 /* hdd_objmgr_set_peer_mlme_auth_state */
 }
 
@@ -900,6 +925,28 @@ bool hdd_cm_is_fils_connection(struct wlan_cm_connect_resp *rsp)
 }
 #endif
 
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx,
+					 struct wlan_cm_connect_resp *rsp)
+{
+#if 0
+	if (!rsp->roaming_info)
+		return false;
+
+	if (rsp->roaming_info->auth_status == ROAM_AUTH_STATUS_AUTHENTICATED ||
+	    sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_SAE ||
+	    sta_ctx->conn_info.auth_type == eCSR_AUTH_TYPE_OWE)
+		return false;
+#endif
+	return true;
+}
+#else
+static bool hdd_cm_is_roam_auth_required(struct hdd_station_ctx *sta_ctx,
+					 struct wlan_cm_connect_resp *rsp)
+{
+	return true;
+}
+#endif
 
 static void
 hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev *vdev,
@@ -914,9 +961,17 @@ hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev *vdev,
 	uint8_t uapsd_mask =
 		mlme_obj->ext_vdev_ptr->connect_info.uapsd_per_ac_bitmask;
 	bool is_auth_required = true;
+	bool is_roam_offload = false;
+	bool is_roam = false;
 
-	qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
-	hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+	if (is_roam) {
+		/* If roaming is set check if FW roaming/LFR3  */
+		ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &is_roam_offload);
+	} else {
+		/* call only for connect */
+		qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
+		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
+	}
 
 	cdp_hl_fc_set_td_limit(soc, adapter->vdev_id,
 			       sta_ctx->conn_info.chan_freq);
@@ -929,7 +984,18 @@ hdd_cm_connect_success_post_user_update(struct wlan_objmgr_vdev *vdev,
 	     hdd_cm_is_fils_connection(rsp)))
 		is_auth_required = false;
 
-	hdd_roam_register_sta(adapter, &rsp->bssid, is_auth_required);
+	if (is_roam_offload || !is_roam) {
+		/* For FW_ROAM/LFR3 OR connect */
+		/* for LFR 3 get authenticated info from resp */
+		if (is_roam)
+			is_auth_required =
+				hdd_cm_is_roam_auth_required(sta_ctx, rsp);
+		hdd_roam_register_sta(adapter, &rsp->bssid, is_auth_required);
+	} else {
+		/* for host roam/LFR2 */
+		hdd_cm_set_peer_authenticate(adapter, &rsp->bssid,
+					     is_auth_required);
+	}
 
 	hdd_debug("Enabling queues");
 	hdd_cm_netif_queue_enable(adapter);

+ 1 - 2
core/mac/inc/sir_api.h

@@ -126,7 +126,6 @@ typedef uint8_t tSirVersionString[SIR_VERSION_STRING_LEN];
 #define KEK_256BIT_KEY_LEN 32
 
 #define SIR_REPLAY_CTR_LEN 8
-#define SIR_PMK_LEN  48
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 #define SIR_UAPSD_BITOFFSET_ACVO     0
 #define SIR_UAPSD_BITOFFSET_ACVI     1
@@ -2523,7 +2522,7 @@ struct roam_offload_synch_ind {
 	uint32_t kek_len;
 	uint8_t kek[SIR_KEK_KEY_LEN_FILS];
 	uint32_t   pmk_len;
-	uint8_t    pmk[SIR_PMK_LEN];
+	uint8_t    pmk[MAX_PMK_LEN];
 	uint8_t    pmkid[PMKID_LEN];
 	bool update_erp_next_seq_num;
 	uint16_t next_erp_seq_num;

+ 1 - 1
core/mac/src/pe/lim/lim_api.c

@@ -2545,7 +2545,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx,
 
 
 	if (roam_sync_ind_ptr->authStatus ==
-	    CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
+	    ROAM_AUTH_STATUS_AUTHENTICATED) {
 		ft_session_ptr->is_key_installed = true;
 		curr_sta_ds->is_key_installed = true;
 	}

+ 1 - 8
core/sme/inc/csr_api.h

@@ -807,13 +807,6 @@ struct csr_config_params {
 #define DEFAULT_REASSOC_FAILURE_TIMEOUT 1000
 #endif
 
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-/* connected but not authenticated */
-#define CSR_ROAM_AUTH_STATUS_CONNECTED      0x1
-/* connected and authenticated */
-#define CSR_ROAM_AUTH_STATUS_AUTHENTICATED  0x2
-#endif
-
 struct csr_roam_info {
 	struct csr_roam_profile *pProfile;
 	struct bss_description *bss_desc;
@@ -887,7 +880,7 @@ struct csr_roam_info {
 	uint8_t kek[SIR_KEK_KEY_LEN_FILS];
 	uint8_t kek_len;
 	uint32_t pmk_len;
-	uint8_t pmk[SIR_PMK_LEN];
+	uint8_t pmk[MAX_PMK_LEN];
 	uint8_t pmkid[PMKID_LEN];
 	bool update_erp_next_seq_num;
 	uint16_t next_erp_seq_num;

+ 2 - 2
core/sme/src/csr/csr_api_roam.c

@@ -17538,7 +17538,7 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 		vdev_roam_params->roam_invoke_in_progress = false;
 
 		if (roam_synch_data->authStatus ==
-		    CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
+		    ROAM_AUTH_STATUS_AUTHENTICATED) {
 			wlan_cm_roam_state_change(mac_ctx->pdev, session_id,
 						   WLAN_ROAM_RSO_ENABLED,
 						   REASON_CONNECT);
@@ -17655,7 +17655,7 @@ csr_process_roam_sync_callback(struct mac_context *mac_ctx,
 	 * eapol. So the session->psk_pmk will be stale in PMKSA cached
 	 * SAE/OWE roaming case.
 	 */
-	if (roam_synch_data->authStatus == CSR_ROAM_AUTH_STATUS_AUTHENTICATED ||
+	if (roam_synch_data->authStatus == ROAM_AUTH_STATUS_AUTHENTICATED ||
 	    session->pCurRoamProfile->negotiatedAuthType ==
 	    eCSR_AUTH_TYPE_SAE ||
 	    session->pCurRoamProfile->negotiatedAuthType ==

+ 2 - 2
core/wma/src/wma_scan_roam.c

@@ -831,7 +831,7 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma,
 	fils_info = param_buf->roam_fils_synch_info;
 	if (fils_info) {
 		if ((fils_info->kek_len > SIR_KEK_KEY_LEN_FILS) ||
-		    (fils_info->pmk_len > SIR_PMK_LEN)) {
+		    (fils_info->pmk_len > MAX_PMK_LEN)) {
 			wma_err("Invalid kek_len %d or pmk_len %d",
 				 fils_info->kek_len,
 				 fils_info->pmk_len);
@@ -862,7 +862,7 @@ static int wma_fill_roam_synch_buffer(tp_wma_handle wma,
 
 	pmk_cache_info = param_buf->roam_pmk_cache_synch_info;
 	if (pmk_cache_info && (pmk_cache_info->pmk_len)) {
-		if (pmk_cache_info->pmk_len > SIR_PMK_LEN) {
+		if (pmk_cache_info->pmk_len > MAX_PMK_LEN) {
 			wma_err("Invalid pmk_len %d",
 				 pmk_cache_info->pmk_len);
 			wma_free_roam_synch_frame_ind(iface);