Browse Source

qcacld-3.0: Refine the extscan set significant change logic

Make the following updates to the extscan set significant change
logic:
1) Exclusively use the Unified WMI data structures.
2) Update the HDD<=>SME interface to enforce the contract that SME
   must not make any assumptions about the buffers provided by HDD.

Change-Id: I916f387cee254c2d8ba57a9182bd927a91eadf0c
CRs-Fixed: 2307374
Jeff Johnson 6 years ago
parent
commit
b43ed03298

+ 56 - 105
core/hdd/src/wlan_hdd_ext_scan.c

@@ -2138,24 +2138,20 @@ int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
  */
 static int
 __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
-						     struct wireless_dev
-						     *wdev, const void *data,
-						     int data_len)
+						   struct wireless_dev *wdev,
+						   const void *data,
+						   int data_len)
 {
-	tpSirExtScanSetSigChangeReqParams pReqMsg = NULL;
+	struct extscan_set_sig_changereq_params *params;
 	struct net_device *dev = wdev->netdev;
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
-	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX +
-			  1];
-	struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
-			   + 1];
-	struct nlattr *apTh;
+	struct nlattr *tb[EXTSCAN_PARAM_MAX + 1];
+	struct nlattr *apth;
 	struct hdd_ext_scan_context *context;
-	uint32_t request_id;
 	QDF_STATUS status;
 	uint8_t i;
-	int rem, retval;
+	int id, rem, retval;
 	unsigned long rc;
 
 	hdd_enter_dev(dev);
@@ -2169,157 +2165,113 @@ __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
 	if (0 != retval)
 		return -EINVAL;
 
-	if (wlan_cfg80211_nla_parse(tb,
-			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
-			   data, data_len, wlan_hdd_extscan_config_policy)) {
+	if (wlan_cfg80211_nla_parse(tb, EXTSCAN_PARAM_MAX,
+				    data, data_len,
+				    wlan_hdd_extscan_config_policy)) {
 		hdd_err("Invalid ATTR");
 		return -EINVAL;
 	}
 
-	pReqMsg = qdf_mem_malloc(sizeof(*pReqMsg));
-	if (!pReqMsg) {
+	params = qdf_mem_malloc(sizeof(*params));
+	if (!params) {
 		hdd_err("qdf_mem_malloc failed");
 		return -ENOMEM;
 	}
 
+	/* assume the worst until proven otherwise */
+	retval = -EINVAL;
+
 	/* Parse and fetch request Id */
-	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID;
+	if (!tb[id]) {
 		hdd_err("attr request id failed");
 		goto fail;
 	}
 
-	pReqMsg->requestId =
-		nla_get_u32(tb
-		 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
-	hdd_debug("Req Id %d", pReqMsg->requestId);
+	params->request_id = nla_get_u32(tb[id]);
+	hdd_debug("Req Id %d", params->request_id);
 
 	/* Parse and fetch RSSI sample size */
-	if (!tb
-	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]) {
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE;
+	if (!tb[id]) {
 		hdd_err("attr RSSI sample size failed");
 		goto fail;
 	}
-	pReqMsg->rssiSampleSize =
-		nla_get_u32(tb
-		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
-	hdd_debug("RSSI sample size %u", pReqMsg->rssiSampleSize);
+	params->rssi_sample_size = nla_get_u32(tb[id]);
+	hdd_debug("RSSI sample size %u", params->rssi_sample_size);
 
 	/* Parse and fetch lost AP sample size */
-	if (!tb
-	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]) {
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE;
+	if (!tb[id]) {
 		hdd_err("attr lost AP sample size failed");
 		goto fail;
 	}
-	pReqMsg->lostApSampleSize =
-		nla_get_u32(tb
-		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
-	hdd_debug("Lost AP sample size %u", pReqMsg->lostApSampleSize);
+	params->lostap_sample_size = nla_get_u32(tb[id]);
+	hdd_debug("Lost AP sample size %u", params->lostap_sample_size);
 
-	/* Parse and fetch AP min breacing */
-	if (!tb
-	    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
+	/* Parse and fetch AP min breaching */
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING;
+	if (!tb[id]) {
 		hdd_err("attr AP min breaching");
 		goto fail;
 	}
-	pReqMsg->minBreaching =
-		nla_get_u32(tb
-		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
-	hdd_debug("AP min breaching %u", pReqMsg->minBreaching);
+	params->min_breaching = nla_get_u32(tb[id]);
+	hdd_debug("AP min breaching %u", params->min_breaching);
 
 	/* Parse and fetch number of APs */
-	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP;
+	if (!tb[id]) {
 		hdd_err("attr number of AP failed");
 		goto fail;
 	}
-	pReqMsg->numAp =
-		nla_get_u32(tb
-		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
-	if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS) {
+	params->num_ap = nla_get_u32(tb[id]);
+	if (params->num_ap > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS) {
 		hdd_err("Number of AP %u exceeds max %u",
-			pReqMsg->numAp,
+			params->num_ap,
 			WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS);
 		goto fail;
 	}
 
-	pReqMsg->sessionId = adapter->session_id;
-	hdd_debug("Number of AP %d Session Id %d",
-		pReqMsg->numAp, pReqMsg->sessionId);
+	params->vdev_id = adapter->session_id;
+	hdd_debug("Number of AP %d Vdev Id %d",
+		  params->num_ap, params->vdev_id);
 
-	if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM]) {
+	id = QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM;
+	if (!tb[id]) {
 		hdd_err("attr ap threshold failed");
 		goto fail;
 	}
 	i = 0;
-	nla_for_each_nested(apTh,
-			    tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM],
-			    rem) {
+	nla_for_each_nested(apth, tb[id], rem) {
 
-		if (i == pReqMsg->numAp) {
+		if (i == params->num_ap) {
 			hdd_warn("Ignoring excess AP");
 			break;
 		}
 
-		if (wlan_cfg80211_nla_parse(tb2,
-			   QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
-			   nla_data(apTh), nla_len(apTh),
-			   wlan_hdd_extscan_config_policy)) {
-			hdd_err("nla_parse failed");
-			goto fail;
-		}
-
-		/* Parse and fetch MAC address */
-		if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
-			hdd_err("attr mac address failed");
-			goto fail;
-		}
-		nla_memcpy(pReqMsg->ap[i].bssid.bytes,
-			   tb2
-			   [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID],
-			   QDF_MAC_ADDR_SIZE);
-		hdd_debug(MAC_ADDRESS_STR,
-		       MAC_ADDR_ARRAY(pReqMsg->ap[i].bssid.bytes));
-
-		/* Parse and fetch low RSSI */
-		if (!tb2
-		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
-			hdd_err("attr low RSSI failed");
-			goto fail;
-		}
-		pReqMsg->ap[i].low =
-			nla_get_s32(tb2
-			    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
-		hdd_debug("RSSI low %d", pReqMsg->ap[i].low);
-
-		/* Parse and fetch high RSSI */
-		if (!tb2
-		    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
-			hdd_err("attr high RSSI failed");
+		retval = hdd_parse_ap_rssi_threshold(apth, &params->ap[i]);
+		if (retval)
 			goto fail;
-		}
-		pReqMsg->ap[i].high =
-			nla_get_s32(tb2
-			    [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
-		hdd_debug("RSSI High %d", pReqMsg->ap[i].high);
 
 		i++;
 	}
-	if (i < pReqMsg->numAp) {
+	if (i < params->num_ap) {
 		hdd_warn("Number of AP %u less than expected %u",
-			 i, pReqMsg->numAp);
-		pReqMsg->numAp = i;
+			 i, params->num_ap);
+		params->num_ap = i;
 	}
 
 	context = &ext_scan_context;
 	spin_lock(&context->context_lock);
 	INIT_COMPLETION(context->response_event);
-	context->request_id = request_id = pReqMsg->requestId;
+	context->request_id = params->request_id;
 	spin_unlock(&context->context_lock);
 
-	status = sme_set_significant_change(hdd_ctx->mac_handle, pReqMsg);
+	status = sme_set_significant_change(hdd_ctx->mac_handle, params);
 	if (!QDF_IS_STATUS_SUCCESS(status)) {
 		hdd_err("sme_set_significant_change failed(err=%d)", status);
-		qdf_mem_free(pReqMsg);
-		return -EINVAL;
+		retval = qdf_status_to_os_return(status);
+		goto fail;
 	}
 
 	/* request was sent -- wait for the response */
@@ -2331,18 +2283,17 @@ __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
 		retval = -ETIMEDOUT;
 	} else {
 		spin_lock(&context->context_lock);
-		if (context->request_id == request_id)
+		if (context->request_id == params->request_id)
 			retval = context->response_status;
 		else
 			retval = -EINVAL;
 		spin_unlock(&context->context_lock);
 	}
 	hdd_exit();
-	return retval;
 
 fail:
-	qdf_mem_free(pReqMsg);
-	return -EINVAL;
+	qdf_mem_free(params);
+	return retval;
 }
 
 /**

+ 0 - 29
core/mac/inc/sir_api.h

@@ -3978,16 +3978,6 @@ enum extscan_configuration_flags {
 	EXTSCAN_LP_EXTENDED_BATCHING = 0x00000001,
 };
 
-typedef struct {
-	struct qdf_mac_addr bssid;
-
-	/* Low threshold */
-	int32_t low;
-
-	/* High threshold */
-	int32_t high;
-} tSirAPThresholdParam, *tpSirAPThresholdParam;
-
 typedef struct {
 	uint32_t requestId;
 	uint8_t sessionId;
@@ -4301,25 +4291,6 @@ typedef struct {
 	uint8_t sessionId;
 } tSirExtScanStopReqParams, *tpSirExtScanStopReqParams;
 
-typedef struct {
-	uint32_t requestId;
-	uint8_t sessionId;
-
-	/* Number of samples for averaging RSSI */
-	uint32_t rssiSampleSize;
-
-	/* Number of missed samples to confirm AP loss */
-	uint32_t lostApSampleSize;
-
-	/* Number of APs breaching threshold required for firmware
-	 * to generate event
-	 */
-	uint32_t minBreaching;
-
-	uint32_t numAp;
-	tSirAPThresholdParam ap[WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS];
-} tSirExtScanSetSigChangeReqParams, *tpSirExtScanSetSigChangeReqParams;
-
 typedef struct {
 	struct qdf_mac_addr bssid;
 	uint32_t channel;

+ 11 - 3
core/sme/inc/sme_api.h

@@ -1022,9 +1022,17 @@ QDF_STATUS
 sme_reset_bss_hotlist(mac_handle_t mac_handle,
 		      struct extscan_bssid_hotlist_reset_params *params);
 
-QDF_STATUS sme_set_significant_change(tHalHandle hHal,
-		tSirExtScanSetSigChangeReqParams *
-		pSetSignificantChangeReq);
+/**
+ * sme_set_significant_change() - SME API to set significant change
+ * @mac_handle: Opaque handle to the MAC context
+ * @params: extscan set significant change structure
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+sme_set_significant_change(mac_handle_t mac_handle,
+			   struct extscan_set_sig_changereq_params *params);
+
 QDF_STATUS sme_reset_significant_change(tHalHandle hHal,
 		tSirExtScanResetSignificantChangeReqParams
 		*pResetReq);

+ 22 - 21
core/sme/src/common/sme_api.c

@@ -11252,36 +11252,37 @@ sme_reset_bss_hotlist(mac_handle_t mac_handle,
 	return status;
 }
 
-/*
- * sme_set_significant_change() -
- * SME API to set significant change
- *
- * hHal
- * pSetSignificantChangeReq: extscan set significant change structure
- * Return QDF_STATUS
- */
-QDF_STATUS sme_set_significant_change(tHalHandle hHal,
-				      tSirExtScanSetSigChangeReqParams *
-				      pSetSignificantChangeReq)
+QDF_STATUS
+sme_set_significant_change(mac_handle_t mac_handle,
+			   struct extscan_set_sig_changereq_params *params)
 {
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
-	tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+	QDF_STATUS status;
+	tpAniSirGlobal mac = MAC_CONTEXT(mac_handle);
 	struct scheduler_msg message = {0};
+	struct extscan_set_sig_changereq_params *bodyptr;
 
-	status = sme_acquire_global_lock(&pMac->sme);
+	/* per contract must make a copy of the params when messaging */
+	bodyptr = qdf_mem_malloc(sizeof(*bodyptr));
+	if (!bodyptr) {
+		sme_err("buffer allocation failure");
+		return QDF_STATUS_E_NOMEM;
+	}
+	*bodyptr = *params;
+
+	status = sme_acquire_global_lock(&mac->sme);
 	if (QDF_IS_STATUS_SUCCESS(status)) {
 		/* Serialize the req through MC thread */
-		message.bodyptr = pSetSignificantChangeReq;
+		message.bodyptr = bodyptr;
 		message.type = WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ;
 		MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_TX_WMA_MSG,
 				 NO_SESSION, message.type));
-		qdf_status = scheduler_post_msg(QDF_MODULE_ID_WMA,
-						 &message);
-		if (!QDF_IS_STATUS_SUCCESS(qdf_status))
-			status = QDF_STATUS_E_FAILURE;
+		status = scheduler_post_msg(QDF_MODULE_ID_WMA, &message);
+		sme_release_global_lock(&mac->sme);
+	}
 
-		sme_release_global_lock(&pMac->sme);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		sme_err("failure: %d", status);
+		qdf_mem_free(bodyptr);
 	}
 	return status;
 }

+ 12 - 3
core/wma/inc/wma_internal.h

@@ -386,9 +386,18 @@ QDF_STATUS wma_extscan_start_hotlist_monitor(tp_wma_handle wma,
 QDF_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma,
 			struct extscan_bssid_hotlist_reset_params *params);
 
-QDF_STATUS wma_extscan_start_change_monitor(tp_wma_handle wma,
-					    tSirExtScanSetSigChangeReqParams *
-					    psigchange);
+/**
+ * wma_extscan_start_change_monitor() - send start change monitor cmd
+ * @wma: wma handle
+ * @params: change monitor request params
+ *
+ * This function sends start change monitor request to fw.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS
+wma_extscan_start_change_monitor(tp_wma_handle wma,
+			struct extscan_set_sig_changereq_params *params);
 
 QDF_STATUS wma_extscan_stop_change_monitor(tp_wma_handle wma,
 		   tSirExtScanResetSignificantChangeReqParams *pResetReq);

+ 1 - 2
core/wma/src/wma_main.c

@@ -8166,8 +8166,7 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg)
 		qdf_mem_free(msg->bodyptr);
 		break;
 	case WMA_EXTSCAN_SET_SIGNF_CHANGE_REQ:
-		wma_extscan_start_change_monitor(wma_handle,
-			(tSirExtScanSetSigChangeReqParams *) msg->bodyptr);
+		wma_extscan_start_change_monitor(wma_handle, msg->bodyptr);
 		qdf_mem_free(msg->bodyptr);
 		break;
 	case WMA_EXTSCAN_RESET_SIGNF_CHANGE_REQ:

+ 8 - 39
core/wma/src/wma_scan_roam.c

@@ -4712,56 +4712,25 @@ QDF_STATUS wma_extscan_stop_hotlist_monitor(tp_wma_handle wma,
 							    params);
 }
 
-/**
- * wma_extscan_start_change_monitor() - send start change monitor cmd
- * @wma: wma handle
- * @psigchange: change monitor request params
- *
- * This function sends start change monitor request to fw.
- *
- * Return: QDF status
- */
-QDF_STATUS wma_extscan_start_change_monitor(tp_wma_handle wma,
-					    tSirExtScanSetSigChangeReqParams *
-					    psigchange)
+QDF_STATUS
+wma_extscan_start_change_monitor(tp_wma_handle wma,
+			struct extscan_set_sig_changereq_params *params)
 {
-	int i = 0;
 	QDF_STATUS status;
-	struct extscan_set_sig_changereq_params *params_ptr;
 
 	if (!wma || !wma->wmi_handle) {
-		WMA_LOGE("%s: WMA is closed,can not issue extscan cmd",
+		WMA_LOGE("%s: WMA is closed,can not issue cmd",
 			 __func__);
 		return QDF_STATUS_E_INVAL;
 	}
 
-	params_ptr = qdf_mem_malloc(sizeof(*params_ptr));
-
-	if (!params_ptr) {
-		WMA_LOGE(
-			"%s: unable to allocate memory for extscan_set_sig_changereq_params",
-			 __func__);
+	if (!params) {
+		WMA_LOGE("%s: NULL params", __func__);
 		return QDF_STATUS_E_NOMEM;
 	}
 
-	params_ptr->request_id = psigchange->requestId;
-	params_ptr->vdev_id = psigchange->sessionId;
-	params_ptr->rssi_sample_size = psigchange->rssiSampleSize;
-	params_ptr->lostap_sample_size = psigchange->lostApSampleSize;
-	params_ptr->min_breaching = psigchange->minBreaching;
-	params_ptr->num_ap = psigchange->numAp;
-	for (i = 0; i < WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS; i++) {
-		qdf_mem_copy(&params_ptr->ap[i].bssid,
-				&psigchange->ap[i].bssid,
-				sizeof(struct qdf_mac_addr));
-		params_ptr->ap[i].high = psigchange->ap[i].high;
-		params_ptr->ap[i].low = psigchange->ap[i].low;
-	}
-
-	status = wmi_unified_extscan_start_change_monitor_cmd
-							(wma->wmi_handle,
-							params_ptr);
-	qdf_mem_free(params_ptr);
+	status = wmi_unified_extscan_start_change_monitor_cmd(wma->wmi_handle,
+							      params);
 	return status;
 }