|
@@ -4204,10 +4204,12 @@ bool wlan_cm_is_roam_sync_in_progress(struct wlan_objmgr_psoc *psoc,
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie)
|
|
|
+wlan_cm_get_set_roam_offload_bssid(struct wlan_objmgr_vdev *vdev,
|
|
|
+ struct qdf_mac_addr *bssid,
|
|
|
+ bool set)
|
|
|
{
|
|
|
struct mlme_legacy_priv *mlme_priv;
|
|
|
- uint8_t ssid_len = ssid_ie[1];
|
|
|
+ struct qdf_mac_addr *mlme_bssid;
|
|
|
|
|
|
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
|
|
if (!mlme_priv) {
|
|
@@ -4215,14 +4217,49 @@ wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (ssid_len > WLAN_SSID_MAX_LEN)
|
|
|
- ssid_len = WLAN_SSID_MAX_LEN;
|
|
|
+ mlme_bssid = &(mlme_priv->cm_roam.sae_offload.bssid);
|
|
|
|
|
|
- qdf_mem_zero(&mlme_priv->cm_roam.sae_offload_ssid,
|
|
|
- sizeof(struct wlan_ssid));
|
|
|
- qdf_mem_copy(mlme_priv->cm_roam.sae_offload_ssid.ssid,
|
|
|
- &ssid_ie[2], ssid_len);
|
|
|
- mlme_priv->cm_roam.sae_offload_ssid.length = ssid_len;
|
|
|
+ if (set) {
|
|
|
+ if (!bssid || qdf_is_macaddr_zero(bssid)) {
|
|
|
+ mlme_err("NULL BSSID");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ qdf_mem_copy(mlme_bssid->bytes, bssid->bytes,
|
|
|
+ QDF_MAC_ADDR_SIZE);
|
|
|
+ } else {
|
|
|
+ /* Get the BSSID present in sae_offload_param */
|
|
|
+ if (!bssid)
|
|
|
+ return;
|
|
|
+ qdf_mem_copy(bssid->bytes, mlme_bssid->bytes,
|
|
|
+ QDF_MAC_ADDR_SIZE);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev,
|
|
|
+ uint8_t *ssid, uint8_t len)
|
|
|
+{
|
|
|
+ struct mlme_legacy_priv *mlme_priv;
|
|
|
+ struct wlan_ssid *mlme_ssid;
|
|
|
+
|
|
|
+ mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
|
|
+ if (!mlme_priv) {
|
|
|
+ mlme_err("vdev legacy private object is NULL");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ mlme_ssid = &mlme_priv->cm_roam.sae_offload.ssid;
|
|
|
+
|
|
|
+ if (len > WLAN_SSID_MAX_LEN)
|
|
|
+ len = WLAN_SSID_MAX_LEN;
|
|
|
+
|
|
|
+ qdf_mem_zero(mlme_ssid, sizeof(struct wlan_ssid));
|
|
|
+ qdf_mem_copy(&mlme_ssid->ssid[0], ssid, len);
|
|
|
+ mlme_ssid->length = len;
|
|
|
+
|
|
|
+ mlme_debug("Set roam offload ssid: " QDF_SSID_FMT,
|
|
|
+ QDF_SSID_REF(mlme_ssid->length,
|
|
|
+ mlme_ssid->ssid));
|
|
|
}
|
|
|
|
|
|
void
|
|
@@ -4231,6 +4268,7 @@ wlan_cm_get_roam_offload_ssid(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
|
|
{
|
|
|
struct wlan_objmgr_vdev *vdev;
|
|
|
struct mlme_legacy_priv *mlme_priv;
|
|
|
+ struct wlan_ssid *mlme_ssid;
|
|
|
|
|
|
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
|
|
WLAN_MLME_CM_ID);
|
|
@@ -4245,9 +4283,10 @@ wlan_cm_get_roam_offload_ssid(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
|
|
|
goto ret;
|
|
|
}
|
|
|
|
|
|
- qdf_mem_copy(ssid, mlme_priv->cm_roam.sae_offload_ssid.ssid,
|
|
|
- mlme_priv->cm_roam.sae_offload_ssid.length);
|
|
|
- *len = mlme_priv->cm_roam.sae_offload_ssid.length;
|
|
|
+ mlme_ssid = &mlme_priv->cm_roam.sae_offload.ssid;
|
|
|
+
|
|
|
+ qdf_mem_copy(ssid, mlme_ssid->ssid, mlme_ssid->length);
|
|
|
+ *len = mlme_ssid->length;
|
|
|
|
|
|
ret:
|
|
|
wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
|
|
@@ -4535,3 +4574,81 @@ bool wlan_cm_is_self_mld_roam_supported(struct wlan_objmgr_psoc *psoc)
|
|
|
return wmi_service_enabled(wmi_handle,
|
|
|
wmi_service_self_mld_roam_between_dbs_and_hbs);
|
|
|
}
|
|
|
+
|
|
|
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
|
|
|
+QDF_STATUS
|
|
|
+wlan_cm_set_offload_ssid(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
|
|
|
+ struct qdf_mac_addr *ap_bssid)
|
|
|
+{
|
|
|
+ struct wlan_objmgr_vdev *vdev;
|
|
|
+ struct wlan_objmgr_psoc *psoc;
|
|
|
+ qdf_list_t *list = NULL;
|
|
|
+ struct scan_cache_node *first_node = NULL;
|
|
|
+ struct scan_filter *scan_filter;
|
|
|
+ struct scan_cache_entry *entry;
|
|
|
+ struct qdf_mac_addr cache_bssid;
|
|
|
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
|
|
|
+
|
|
|
+ psoc = wlan_pdev_get_psoc(pdev);
|
|
|
+ if (!psoc)
|
|
|
+ return QDF_STATUS_E_NULL_VALUE;
|
|
|
+
|
|
|
+ vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
|
|
|
+ WLAN_MLME_OBJMGR_ID);
|
|
|
+ if (!vdev)
|
|
|
+ return QDF_STATUS_E_NULL_VALUE;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * sae_offload ssid, bssid would have already been cached
|
|
|
+ * from the tx profile of the roam_candidate_frame from FW,
|
|
|
+ * but if the roam offload is received for a non-tx BSSID,
|
|
|
+ * then the ssid stored in mlme_priv would be incorrect.
|
|
|
+ *
|
|
|
+ * If the bssid cached in sae_offload_param doesn't match
|
|
|
+ * with the bssid received in roam_offload_event, then
|
|
|
+ * get the scan entry from scan table to save the proper
|
|
|
+ * ssid, bssid.
|
|
|
+ */
|
|
|
+ wlan_cm_get_set_roam_offload_bssid(vdev, &cache_bssid, false);
|
|
|
+ if (!qdf_mem_cmp(cache_bssid.bytes, ap_bssid->bytes, QDF_MAC_ADDR_SIZE))
|
|
|
+ goto end;
|
|
|
+
|
|
|
+ mlme_debug("Update the roam offload ssid from scan cache");
|
|
|
+
|
|
|
+ scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
|
|
|
+ if (!scan_filter) {
|
|
|
+ status = QDF_STATUS_E_NOMEM;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ scan_filter->num_of_bssid = 1;
|
|
|
+ qdf_mem_copy(scan_filter->bssid_list[0].bytes,
|
|
|
+ ap_bssid, sizeof(struct qdf_mac_addr));
|
|
|
+
|
|
|
+ list = wlan_scan_get_result(pdev, scan_filter);
|
|
|
+ qdf_mem_free(scan_filter);
|
|
|
+
|
|
|
+ if (!list || !qdf_list_size(list)) {
|
|
|
+ QDF_ASSERT(0);
|
|
|
+ mlme_err("Scan result is empty, candidate entry not found");
|
|
|
+ status = QDF_STATUS_E_FAILURE;
|
|
|
+ goto end;
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_list_peek_front(list, (qdf_list_node_t **)&first_node);
|
|
|
+ if (first_node && first_node->entry) {
|
|
|
+ entry = first_node->entry;
|
|
|
+ wlan_cm_set_roam_offload_ssid(vdev,
|
|
|
+ &entry->ssid.ssid[0],
|
|
|
+ entry->ssid.length);
|
|
|
+ wlan_cm_get_set_roam_offload_bssid(vdev, ap_bssid, true);
|
|
|
+ }
|
|
|
+
|
|
|
+end:
|
|
|
+ if (list)
|
|
|
+ wlan_scan_purge_results(list);
|
|
|
+
|
|
|
+ wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
|
|
|
+ return status;
|
|
|
+}
|
|
|
+#endif
|