Pārlūkot izejas kodu

qcacld-3.0: clear pmkid cache when ap off

Add logic similar to I5d8ec9e9d4f8a44178b113d370799fe2bc0373fb
in connection manager to flush PMID on HB failure.

Change-Id: Id87b5774a18a377719c56d3f34dc31284f0a39a3
CRs-Fixed: 2928282
Utkarsh Bhatnagar 4 gadi atpakaļ
vecāks
revīzija
d6fc151325

+ 2 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_api.h

@@ -245,6 +245,8 @@ void cm_csr_set_ss_none(uint8_t vdev_id);
 void cm_csr_set_joining(uint8_t vdev_id);
 void cm_csr_set_joined(uint8_t vdev_id);
 void cm_csr_set_idle(uint8_t vdev_id);
+int8_t cm_get_rssi_by_bssid(struct wlan_objmgr_pdev *pdev,
+			    struct qdf_mac_addr *bssid);
 
 #ifndef FEATURE_CM_ENABLE
 /**

+ 2 - 2
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -570,8 +570,8 @@ static void cm_diag_get_auth_type(uint8_t *auth_type,
 	*auth_type = AUTH_OPEN;
 }
 
-static int8_t cm_get_rssi_by_bssid(struct wlan_objmgr_pdev *pdev,
-				   struct qdf_mac_addr *bssid)
+int8_t cm_get_rssi_by_bssid(struct wlan_objmgr_pdev *pdev,
+			    struct qdf_mac_addr *bssid)
 {
 	struct scan_filter *scan_filter;
 	int8_t rssi = 0;

+ 70 - 1
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_disconnect.c

@@ -196,12 +196,74 @@ static inline void cm_disconnect_diag_event(struct wlan_objmgr_vdev *vdev,
 {}
 #endif
 
+/**
+ * cm_clear_pmkid_on_ap_off() - clear pmkid cache when ap off
+ * @psoc: psoc ptr
+ * @pdev: pdev ptr
+ * @vdev: vdev ptr
+ * @req: disconnect req
+ *
+ * In AP side power off/on case, AP security has been cleanup.
+ * The STA side might still cache PMK ID in driver and it will always use
+ * PMK cache to connect to AP and get continuously connect failure in SAE
+ * security. This function is to detect AP off based on FW reported BMISS
+ * event. Meanwhile judge FW reported last RSSI > roaming Low rssi
+ * and not less than 20db of host cached RSSI to avoid some false
+ * alarm such as normal DUT roll in/out roaming.
+ *
+ * Return: void
+ */
+static void cm_clear_pmkid_on_ap_off(struct wlan_objmgr_psoc *psoc,
+				     struct wlan_objmgr_pdev *pdev,
+				     struct wlan_objmgr_vdev *vdev,
+				     struct wlan_cm_disconnect_req *req)
+{
+	int8_t cache_rssi = 0;
+	int32_t bmiss_rssi;
+	uint8_t lookup_threshold = 0;
+	struct wlan_crypto_pmksa *pmksa;
+	int32_t akm;
+	struct cm_roam_values_copy temp;
+
+	if (req->reason_code != REASON_BEACON_MISSED)
+		return;
+
+	akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
+	if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_SAE))
+		return;
+
+	cache_rssi = cm_get_rssi_by_bssid(pdev, &req->bssid);
+	wlan_cm_roam_cfg_get_value(psoc, req->vdev_id,
+				   NEIGHBOUR_LOOKUP_THRESHOLD, &temp);
+	lookup_threshold = temp.uint_value;
+
+	wlan_cm_roam_cfg_get_value(psoc, req->vdev_id,
+				   LOST_LINK_RSSI, &temp);
+	bmiss_rssi = temp.int_value;
+
+	if (!bmiss_rssi || !lookup_threshold || !cache_rssi)
+		return;
+	mlme_nofl_debug("sta bmiss on rssi %d scan rssi %d th %d", bmiss_rssi,
+			cache_rssi, lookup_threshold);
+	if (bmiss_rssi > (lookup_threshold * (-1))) {
+		if (bmiss_rssi + AP_OFF_RSSI_OFFSET > cache_rssi) {
+			pmksa = qdf_mem_malloc(sizeof(*pmksa));
+			if (!pmksa)
+				return;
+			qdf_copy_macaddr(&pmksa->bssid, &req->bssid);
+			wlan_crypto_set_del_pmksa(vdev, pmksa, false);
+			qdf_mem_free(pmksa);
+		}
+	}
+}
+
 QDF_STATUS
 cm_disconnect_complete_ind(struct wlan_objmgr_vdev *vdev,
 			   struct wlan_cm_discon_rsp *rsp)
 {
 	uint8_t vdev_id;
 	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
 	enum QDF_OPMODE op_mode;
 
 	if (!vdev || !rsp) {
@@ -212,12 +274,19 @@ cm_disconnect_complete_ind(struct wlan_objmgr_vdev *vdev,
 
 	vdev_id = wlan_vdev_get_id(vdev);
 	op_mode = wlan_vdev_mlme_get_opmode(vdev);
-	psoc = wlan_vdev_get_psoc(vdev);
+	pdev = wlan_vdev_get_pdev(vdev);
+	if (!pdev) {
+		mlme_err(CM_PREFIX_FMT "pdev not found",
+			 CM_PREFIX_REF(vdev_id, rsp->req.cm_id));
+		return QDF_STATUS_E_INVAL;
+	}
+	psoc = wlan_pdev_get_psoc(pdev);
 	if (!psoc) {
 		mlme_err(CM_PREFIX_FMT "psoc not found",
 			 CM_PREFIX_REF(vdev_id, rsp->req.cm_id));
 		return QDF_STATUS_E_INVAL;
 	}
+	cm_clear_pmkid_on_ap_off(psoc, pdev, vdev, &rsp->req.req);
 	cm_disconnect_diag_event(vdev, rsp);
 	wlan_tdls_notify_sta_disconnect(vdev_id, false, false, vdev);
 	policy_mgr_decr_session_set_pcl(psoc, op_mode, vdev_id);

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

@@ -305,6 +305,7 @@ enum roam_fail_params {
  * @roam_trigger_reason: Roam trigger reason(enum WMI_ROAM_TRIGGER_REASON_ID)
  * @roam_invoke_fail_reason: One of reason id from enum
  * wmi_roam_invoke_status_error in case of forced roam
+ * @lost_link_rssi: lost link RSSI
  */
 struct rso_config {
 	qdf_mutex_t cm_rso_lock;
@@ -342,6 +343,7 @@ struct rso_config {
 	uint32_t roam_fail_reason;
 	uint32_t roam_trigger_reason;
 	uint32_t roam_invoke_fail_reason;
+	int32_t lost_link_rssi;
 };
 
 /**
@@ -445,6 +447,7 @@ struct rso_config_params {
  * @ADAPTIVE_11R_CONNECTION: adaptive 11r
  * @HS_20_AP: Hotspot 2.0 AP
  * @MBO_OCE_ENABLED_AP: MBO/OCE enabled network
+ * @LOST_LINK_RSSI: lost link RSSI
  */
 enum roam_cfg_param {
 	RSSI_CHANGE_THRESHOLD,
@@ -472,6 +475,7 @@ enum roam_cfg_param {
 	HS_20_AP,
 	MBO_OCE_ENABLED_AP,
 	IS_SINGLE_PMK,
+	LOST_LINK_RSSI,
 };
 
 /**

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

@@ -756,6 +756,9 @@ QDF_STATUS wlan_cm_roam_cfg_get_value(struct wlan_objmgr_psoc *psoc,
 	case IS_SINGLE_PMK:
 		dst_config->bool_value = rso_cfg->is_single_pmk;
 		break;
+	case LOST_LINK_RSSI:
+		dst_config->int_value = rso_cfg->lost_link_rssi;
+		break;
 	default:
 		mlme_err("Invalid roam config requested:%d", roam_cfg_type);
 		status = QDF_STATUS_E_FAILURE;
@@ -1129,6 +1132,9 @@ wlan_cm_roam_cfg_set_value(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 	case IS_SINGLE_PMK:
 		rso_cfg->is_single_pmk = src_config->bool_value;
 		break;
+	case LOST_LINK_RSSI:
+		rso_cfg->lost_link_rssi = src_config->int_value;
+		break;
 	default:
 		mlme_err("Invalid roam config requested:%d", roam_cfg_type);
 		status = QDF_STATUS_E_FAILURE;

+ 3 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -1708,6 +1708,7 @@ static void hdd_pmkid_clear_on_ap_off(struct hdd_adapter *adapter)
 	uint8_t lookup_threshold = 0;
 	struct wlan_crypto_pmksa *pmksa;
 
+	/* this is handled by cm_clear_pmkid_on_ap_off for conenction manager */
 	if (sta_ctx->conn_info.auth_type != eCSR_AUTH_TYPE_SAE)
 		return;
 	hdd_get_rssi_snr_by_bssid(adapter, sta_ctx->conn_info.bssid.bytes,
@@ -1846,6 +1847,8 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter,
 						disconnect_ies.ptr,
 						disconnect_ies.len);
 	}
+
+	/* this is handled by cm_clear_pmkid_on_ap_off for conenction manager */
 	if (adapter->device_mode == QDF_STA_MODE &&
 	    roam_status == eCSR_ROAM_LOSTLINK &&
 	    reason_code == REASON_BEACON_MISSED)

+ 15 - 3
core/sme/src/common/sme_api.c

@@ -2268,6 +2268,20 @@ sme_process_twt_notify_event(struct mac_context *mac,
 }
 #endif
 
+static void sme_link_lost_ind(struct mac_context *mac,
+				    struct sir_lost_link_info *ind)
+{
+	struct cm_roam_values_copy src_cfg;
+
+	if (ind) {
+		src_cfg.int_value = ind->rssi;
+		wlan_cm_roam_cfg_set_value(mac->psoc, ind->vdev_id,
+					   LOST_LINK_RSSI, &src_cfg);
+	}
+	if (mac->sme.lost_link_info_cb)
+		mac->sme.lost_link_info_cb(mac->hdd_handle, ind);
+}
+
 QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
@@ -2525,9 +2539,7 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
 		}
 		break;
 	case eWNI_SME_LOST_LINK_INFO_IND:
-		if (mac->sme.lost_link_info_cb)
-			mac->sme.lost_link_info_cb(mac->hdd_handle,
-				(struct sir_lost_link_info *)pMsg->bodyptr);
+		sme_link_lost_ind(mac, pMsg->bodyptr);
 		qdf_mem_free(pMsg->bodyptr);
 		break;
 	case eWNI_SME_RSO_CMD_STATUS_IND: