Browse Source

qcacld-3.0: Support transmit addr for roam pre-auth

When roam from SAE legacy to SAE MLO, pre-auth TA is MLD address,
while peer AP expects link address, pre-auth fails.
Parse transmit address field from firmware roam_preauth_start_event and
include it when send NL80211_EXTERNAL_AUTH_START to wpa supplicant for
SAE roaming cases.
If transmit address is all zeros, wpa_supplicant will not do ML sae
auth, use MLD address as TA.
If transmit address is not zeros, wpa_supplicant will do ML sae auth,
use 'transmit address' as TA.

Since self peer is created with mld address, when roam from legacy to
MLO, try to get peer by mld address during pre-auth tx since bss peer
absent, or TX fails for no peer.

Change-Id: I99ed846e94165bfe01e1d1e8c620f035751c7056
CRs-Fixed: 3289987
Jianmin Zhu 2 years ago
parent
commit
76b7b34cdd

+ 2 - 0
components/mlme/core/inc/wlan_mlme_main.h

@@ -223,6 +223,7 @@ struct wlan_mlme_roaming_config {
  * @roam_config: Roaming configurations structure
  * @sae_single_pmk: Details for sae roaming using single pmk
  * @set_pmk_pending: RSO update status of PMK from set_key
+ * @sae_auth_ta: SAE pre-auth tx address
  */
 struct wlan_mlme_roam {
 	struct wlan_mlme_roam_state_info roam_sm;
@@ -231,6 +232,7 @@ struct wlan_mlme_roam {
 	struct wlan_mlme_sae_single_pmk sae_single_pmk;
 #endif
 	bool set_pmk_pending;
+	struct qdf_mac_addr sae_auth_ta;
 };
 
 #ifdef WLAN_FEATURE_MSCS

+ 24 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1672,4 +1672,28 @@ bool wlan_cm_same_band_sta_allowed(struct wlan_objmgr_psoc *psoc);
 QDF_STATUS cm_cleanup_mlo_link(struct wlan_objmgr_vdev *vdev);
 
 bool wlan_is_roaming_enabled(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id);
+
+/**
+ * wlan_cm_set_sae_auth_ta() - Set SAE auth tx address
+ * @vdev_id : Vdev id
+ * @sae_auth_ta: SAE auth tx address
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_cm_set_sae_auth_ta(struct wlan_objmgr_pdev *pdev,
+			uint8_t vdev_id,
+			struct qdf_mac_addr sae_auth_ta);
+
+/**
+ * wlan_cm_get_sae_auth_ta() - Get SAE auth tx address
+ * @vdev_id: Vdev id
+ * @sae_auth_ta: SAE auth tx address
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_cm_get_sae_auth_ta(struct wlan_objmgr_pdev *pdev,
+			uint8_t vdev_id,
+			struct qdf_mac_addr *sae_auth_ta);
 #endif  /* WLAN_CM_ROAM_API_H__ */

+ 3 - 1
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -2296,11 +2296,13 @@ struct roam_stats_event {
 /*
  * struct auth_offload_event - offload data carried by roam event
  * @vdev_id: vdev id
- * @ap_bssid: SAE authentication offload MAC Addess
+ * @ap_bssid: SAE authentication offload AP MAC Addess
+ * @ta: SAE authentication offload Tx MAC Addess
  */
 struct auth_offload_event {
 	uint8_t vdev_id;
 	struct qdf_mac_addr ap_bssid;
+	struct qdf_mac_addr ta;
 };
 
 /*

+ 14 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_ucfg_api.h

@@ -401,4 +401,18 @@ ucfg_cm_roam_is_vendor_handoff_control_enable(struct wlan_objmgr_psoc *psoc)
 }
 #endif
 
+/**
+ * ucfg_cm_get_sae_auth_ta() - Get SAE auth tx address
+ * @vdev_id: Vdev id
+ * @sae_auth_ta: SAE auth tx address
+ *
+ * Return: QDF_STATUS
+ */
+static inline QDF_STATUS
+ucfg_cm_get_sae_auth_ta(struct wlan_objmgr_pdev *pdev,
+			uint8_t vdev_id,
+			struct qdf_mac_addr *sae_auth_ta)
+{
+	return wlan_cm_get_sae_auth_ta(pdev, vdev_id, sae_auth_ta);
+}
 #endif /* _WLAN_CM_ROAM_UCFG_API_H_ */

+ 58 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -3675,3 +3675,61 @@ bool wlan_is_roaming_enabled(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id)
 
 	return false;
 }
+
+QDF_STATUS
+wlan_cm_set_sae_auth_ta(struct wlan_objmgr_pdev *pdev,
+			uint8_t vdev_id,
+			struct qdf_mac_addr sae_auth_ta)
+{
+	struct mlme_legacy_priv *mlme_priv;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!pdev)
+		return QDF_STATUS_E_INVAL;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+	qdf_mem_copy(mlme_priv->mlme_roam.sae_auth_ta.bytes, sae_auth_ta.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_cm_get_sae_auth_ta(struct wlan_objmgr_pdev *pdev,
+			uint8_t vdev_id,
+			struct qdf_mac_addr *sae_auth_ta)
+{
+	struct mlme_legacy_priv *mlme_priv;
+	struct wlan_objmgr_vdev *vdev;
+
+	if (!pdev)
+		return QDF_STATUS_E_INVAL;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev)
+		return QDF_STATUS_E_INVAL;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_legacy_err("vdev legacy private object is NULL");
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+		return QDF_STATUS_E_INVAL;
+	}
+	qdf_mem_copy(sae_auth_ta->bytes, mlme_priv->mlme_roam.sae_auth_ta.bytes,
+		     QDF_MAC_ADDR_SIZE);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+
+	return QDF_STATUS_SUCCESS;
+}

+ 7 - 2
components/wmi/src/wmi_unified_roam_tlv.c

@@ -3234,6 +3234,8 @@ extract_auth_offload_event_tlv(wmi_unified_t wmi_handle,
 
 	WMI_MAC_ADDR_TO_CHAR_ARRAY(&rso_auth_start_ev->candidate_ap_bssid,
 				   auth_event->ap_bssid.bytes);
+	WMI_MAC_ADDR_TO_CHAR_ARRAY(&rso_auth_start_ev->transmit_addr,
+				   auth_event->ta.bytes);
 	if (qdf_is_macaddr_zero(&auth_event->ap_bssid) ||
 	    qdf_is_macaddr_broadcast(&auth_event->ap_bssid) ||
 	    qdf_is_macaddr_group(&auth_event->ap_bssid)) {
@@ -3241,8 +3243,11 @@ extract_auth_offload_event_tlv(wmi_unified_t wmi_handle,
 		return -EINVAL;
 	}
 
-	wmi_debug("Received Roam auth offload event for bss:"QDF_MAC_ADDR_FMT" vdev_id:%d",
-		  QDF_MAC_ADDR_REF(auth_event->ap_bssid.bytes), auth_event->vdev_id);
+	wmi_debug("Received Roam auth offload event for bss:"
+		  QDF_MAC_ADDR_FMT " ta:" QDF_MAC_ADDR_FMT " vdev_id: %d",
+		  QDF_MAC_ADDR_REF(auth_event->ap_bssid.bytes),
+		  QDF_MAC_ADDR_REF(auth_event->ta.bytes),
+		  auth_event->vdev_id);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 19 - 6
core/hdd/src/wlan_hdd_assoc.c

@@ -219,9 +219,22 @@ static const int beacon_filter_table[] = {
 #if defined (CFG80211_SAE_AUTH_TA_ADDR_SUPPORT)
 static inline
 void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params,
-			       struct hdd_adapter *adapter)
-{
-	if (wlan_vdev_mlme_is_mlo_vdev(adapter->vdev)) {
+			       struct hdd_adapter *adapter,
+			       struct sir_sae_info *sae_info)
+{
+	struct qdf_mac_addr ta = QDF_MAC_ADDR_ZERO_INIT;
+	bool roaming;
+
+	roaming = wlan_cm_roaming_in_progress(adapter->hdd_ctx->pdev,
+					      sae_info->vdev_id);
+	if (roaming) {
+		ucfg_cm_get_sae_auth_ta(adapter->hdd_ctx->pdev,
+					sae_info->vdev_id,
+					&ta);
+		qdf_mem_copy(params->tx_addr, ta.bytes, QDF_MAC_ADDR_SIZE);
+		hdd_debug("ta:" QDF_MAC_ADDR_FMT,
+			  QDF_MAC_ADDR_REF(params->tx_addr));
+	} else if (wlan_vdev_mlme_is_mlo_vdev(adapter->vdev)) {
 		qdf_mem_copy(params->tx_addr,
 			     wlan_vdev_mlme_get_linkaddr(adapter->vdev),
 			     QDF_MAC_ADDR_SIZE);
@@ -230,7 +243,8 @@ void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params,
 #else
 static inline
 void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params,
-			       struct hdd_adapter *adapter)
+			       struct hdd_adapter *adapter,
+			       struct sir_sae_info *sae_info)
 {
 }
 #endif
@@ -269,8 +283,7 @@ static void wlan_hdd_sae_callback(struct hdd_adapter *adapter,
 	params.action = NL80211_EXTERNAL_AUTH_START;
 	qdf_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes,
 		     QDF_MAC_ADDR_SIZE);
-
-	wlan_hdd_sae_copy_ta_addr(&params, adapter);
+	wlan_hdd_sae_copy_ta_addr(&params, adapter, sae_info);
 
 	qdf_mem_copy(params.ssid.ssid, sae_info->ssid.ssId,
 		     sae_info->ssid.length);

+ 16 - 14
core/wma/src/wma_data.c

@@ -2728,21 +2728,23 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
 				cds_packet_free((void *)tx_frame);
 				goto error;
 			}
-			if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
-				mld_addr = wlan_vdev_mlme_get_mldaddr(vdev);
-				if (!mld_addr) {
-					wma_err("mld addr is null");
-					wlan_objmgr_vdev_release_ref(vdev, WLAN_MGMT_NB_ID);
-					cds_packet_free((void *)tx_frame);
-					goto error;
-				}
-				peer = wlan_objmgr_get_peer(psoc, pdev_id,
-							    mld_addr,
-							    WLAN_MGMT_NB_ID);
-				wma_debug("mld mac addr " QDF_MAC_ADDR_FMT,
-					  QDF_MAC_ADDR_REF(mld_addr));
-			}
+			mld_addr = wlan_vdev_mlme_get_mldaddr(vdev);
 			wlan_objmgr_vdev_release_ref(vdev, WLAN_MGMT_NB_ID);
+			if (!mld_addr) {
+				wma_err("mld addr is null");
+				cds_packet_free((void *)tx_frame);
+				goto error;
+			}
+			wma_debug("mld mac addr " QDF_MAC_ADDR_FMT,
+				  QDF_MAC_ADDR_REF(mld_addr));
+			peer = wlan_objmgr_get_peer(psoc, pdev_id,
+						    mld_addr,
+						    WLAN_MGMT_NB_ID);
+			if (!peer) {
+				wma_err("peer is null");
+				cds_packet_free((void *)tx_frame);
+				goto error;
+			}
 		}
 	}
 

+ 3 - 1
core/wma/src/wma_scan_roam.c

@@ -291,7 +291,9 @@ cm_handle_auth_offload(struct auth_offload_event *auth_event)
 			       WMA_ROAM_HO_WAKE_LOCK_DURATION);
 
 	lim_sae_auth_cleanup_retry(mac_ctx, auth_event->vdev_id);
-
+	wlan_cm_set_sae_auth_ta(mac_ctx->pdev,
+				auth_event->vdev_id,
+				auth_event->ta);
 	status = wma->csr_roam_auth_event_handle_cb(mac_ctx, auth_event->vdev_id,
 						    auth_event->ap_bssid);
 	if (QDF_IS_STATUS_ERROR(status)) {