Browse Source

qcacmn: Use vdev instead of pdev as parameter

For the case that there is leakage of vdev due to incorrect reference
count usage, and another vdev for the adapter is created, get ref of
vdev by mac address might get the incorrect vdev object since both vdevs
will have the same mac address and the leak one will be first matched
since it is created first.

To address this issue, use vdev pointer in adapter instead of pdev as
input parameter of related functions.

Change-Id: I855497358b5dabf3fc5c0f71a859dd7cae1b450a
CRs-Fixed: 2312155
Min Liu 6 years ago
parent
commit
2fa0775090

+ 10 - 14
os_if/linux/scan/inc/wlan_cfg80211_scan.h

@@ -153,27 +153,23 @@ struct wlan_cfg80211_inform_bss {
 #ifdef FEATURE_WLAN_SCAN_PNO
 /**
  * wlan_cfg80211_sched_scan_start() - cfg80211 scheduled scan(pno) start
- * @pdev: pdev pointer
- * @dev: Pointer network device
+ * @vdev: vdev pointer
  * @request: Pointer to cfg80211 scheduled scan start request
  * @scan_backoff_multiplier: multiply scan period by this after max cycles
  *
  * Return: 0 for success, non zero for failure
  */
-int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
-	struct net_device *dev,
-	struct cfg80211_sched_scan_request *request,
-	uint8_t scan_backoff_multiplier);
+int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev,
+				   struct cfg80211_sched_scan_request *request,
+				   uint8_t scan_backoff_multiplier);
 
 /**
  * wlan_cfg80211_sched_scan_stop() - cfg80211 scheduled scan(pno) stop
- * @pdev: pdev pointer
- * @dev: Pointer network device
+ * @vdev: vdev pointer
  *
  * Return: 0 for success, non zero for failure
  */
-int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_pdev *pdev,
-	struct net_device *dev);
+int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_vdev *vdev);
 #endif
 
 /**
@@ -221,7 +217,7 @@ QDF_STATUS wlan_cfg80211_scan_priv_deinit(
 
 /**
  * wlan_cfg80211_scan() - API to process cfg80211 scan request
- * @pdev: Pointer to pdev
+ * @vdev: Pointer to vdev
  * @request: Pointer to scan request
  * @params: scan params
  *
@@ -231,9 +227,9 @@ QDF_STATUS wlan_cfg80211_scan_priv_deinit(
  *
  * Return: 0 for success, non zero for failure
  */
-int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
-		struct cfg80211_scan_request *request,
-		struct scan_params *params);
+int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
+		       struct cfg80211_scan_request *request,
+		       struct scan_params *params);
 
 /**
  * wlan_cfg80211_inform_bss_frame_data() - API to inform beacon to cfg80211

+ 9 - 50
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -370,29 +370,20 @@ static inline void wlan_hdd_sched_scan_update_relative_rssi(
 }
 #endif
 
-int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
-	struct net_device *dev,
-	struct cfg80211_sched_scan_request *request,
-	uint8_t scan_backoff_multiplier)
+int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev,
+				   struct cfg80211_sched_scan_request *request,
+				   uint8_t scan_backoff_multiplier)
 {
 	struct pno_scan_req_params *req;
 	int i, j, ret = 0;
 	QDF_STATUS status;
 	uint8_t num_chan = 0, channel;
-	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
 	struct wlan_objmgr_psoc *psoc;
 	uint32_t valid_ch[SCAN_PNO_MAX_NETW_CHANNELS_EX] = {0};
 
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr,
-		WLAN_OSIF_ID);
-	if (!vdev) {
-		cfg80211_err("vdev object is NULL");
-		return -EIO;
-	}
-
 	if (ucfg_scan_get_pno_in_progress(vdev)) {
 		cfg80211_debug("pno is already in progress");
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		return -EBUSY;
 	}
 
@@ -403,7 +394,6 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
 				INVAL_VDEV_ID, INVAL_SCAN_ID, true);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			cfg80211_err("aborting the existing scan is unsuccessful");
-			wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 			return -EBUSY;
 		}
 	}
@@ -411,7 +401,6 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
 	req = qdf_mem_malloc(sizeof(*req));
 	if (!req) {
 		cfg80211_err("req malloc failed");
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		return -ENOMEM;
 	}
 
@@ -579,30 +568,13 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_pdev *pdev,
 	cfg80211_info("PNO scan request offloaded");
 
 error:
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 	qdf_mem_free(req);
 	return ret;
 }
 
-int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_pdev *pdev,
-	struct net_device *dev)
+int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_vdev *vdev)
 {
 	QDF_STATUS status;
-	struct wlan_objmgr_vdev *vdev;
-
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr,
-		WLAN_OSIF_ID);
-	if (!vdev) {
-	/*
-	 * cfg80211 expects sched_scan_stop command to always succeed.
-	 * There can be recovery or any other error in the driver between the
-	 * sched_scan_start and sched_scan_stop commands. If driver does
-	 * not return success in this case there is a possibility of further
-	 * sched_scan_start request might not be received again.
-	 */
-		cfg80211_err("vdev object is NULL");
-		return 0;
-	}
 
 	status = ucfg_scan_pno_stop(vdev);
 	if (QDF_IS_STATUS_ERROR(status))
@@ -610,7 +582,6 @@ int wlan_cfg80211_sched_scan_stop(struct wlan_objmgr_pdev *pdev,
 	else
 		cfg80211_info("PNO scan disabled");
 
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 	return 0;
 }
 #endif /*FEATURE_WLAN_SCAN_PNO */
@@ -1189,18 +1160,17 @@ static inline void wlan_cfg80211_update_scan_policy_type_flags(
 }
 #endif
 
-int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
-		struct cfg80211_scan_request *request,
-		struct scan_params *params)
+int wlan_cfg80211_scan(struct wlan_objmgr_vdev *vdev,
+		       struct cfg80211_scan_request *request,
+		       struct scan_params *params)
 {
-	struct net_device *dev = request->wdev->netdev;
 	struct scan_start_request *req;
 	struct wlan_ssid *pssid;
 	uint8_t i;
 	int ret = 0;
 	uint8_t num_chan = 0, channel;
 	uint32_t c_freq;
-	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
 	wlan_scan_requester req_id;
 	struct pdev_osif_priv *osif_priv;
 	struct wlan_objmgr_psoc *psoc;
@@ -1210,22 +1180,13 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
 	struct net_device *netdev = NULL;
 	QDF_STATUS qdf_status;
 
-	/* Get the vdev object */
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr,
-		WLAN_OSIF_ID);
-	if (vdev == NULL) {
-		cfg80211_err("vdev object is NULL");
-		return -EIO;
-	}
 	psoc = wlan_pdev_get_psoc(pdev);
 	if (!psoc) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		cfg80211_err("Invalid psoc object");
 		return -EINVAL;
 	}
 	req = qdf_mem_malloc(sizeof(*req));
 	if (!req) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		cfg80211_err("Failed to allocate scan request memory");
 		return -EINVAL;
 	}
@@ -1237,7 +1198,6 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
 	req_id = osif_priv->osif_scan->req_id;
 	scan_id = ucfg_scan_get_scan_id(psoc);
 	if (!scan_id) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		cfg80211_err("Invalid scan id");
 		qdf_mem_free(req);
 		return -EINVAL;
@@ -1434,7 +1394,6 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
 	ret = qdf_status_to_os_return(qdf_status);
 
 end:
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 	return ret;
 }
 

+ 13 - 19
os_if/linux/tdls/inc/wlan_cfg80211_tdls.h

@@ -108,26 +108,23 @@ void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv);
 
 /**
  * wlan_cfg80211_tdls_add_peer() - process cfg80211 add TDLS peer request
- * @pdev: pdev object
- * @dev: Pointer to net device
+ * @vdev: vdev object
  * @mac: MAC address for TDLS peer
  *
  * Return: 0 for success; negative errno otherwise
  */
-int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev,
-				struct net_device *dev, const uint8_t *mac);
+int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
+				const uint8_t *mac);
 
 /**
  * wlan_cfg80211_tdls_update_peer() - process cfg80211 update TDLS peer request
- * @pdev: pdev object
- * @dev: Pointer to net device
+ * @vdev: vdev object
  * @mac: MAC address for TDLS peer
  * @params: Pointer to station parameters
  *
  * Return: 0 for success; negative errno otherwise
  */
-int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev,
-				   struct net_device *dev,
+int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
 				   const uint8_t *mac,
 				   struct station_parameters *params);
 
@@ -143,15 +140,13 @@ int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev,
 
 /**
  * wlan_cfg80211_tdls_oper() - process cfg80211 operation on an TDLS peer
- * @pdev: pdev object
- * @dev: net device
+ * @vdev: vdev object
  * @peer: MAC address of the TDLS peer
  * @oper: cfg80211 TDLS operation
  *
  * Return: 0 on success; negative errno otherwise
  */
-int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev,
-			    struct net_device *dev,
+int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
 			    const uint8_t *peer,
 			    enum nl80211_tdls_operation oper);
 
@@ -168,8 +163,7 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
 
 /**
  * wlan_cfg80211_tdls_mgmt() - process tdls management frames from the supplicant
- * @pdev: pdev object
- * @dev: net device
+ * @vdev: vdev object
  * @peer: MAC address of the TDLS peer
  * @action_code: type of TDLS mgmt frame to be sent
  * @dialog_token: dialog token used in the frame
@@ -181,11 +175,11 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
  *
  * Return: 0 on success; negative errno otherwise
  */
-int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev,
-				struct net_device *dev, const uint8_t *peer,
-				uint8_t action_code, uint8_t dialog_token,
-				uint16_t status_code, uint32_t peer_capability,
-				const uint8_t *buf, size_t len);
+int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
+			    const uint8_t *peer,
+			    uint8_t action_code, uint8_t dialog_token,
+			    uint16_t status_code, uint32_t peer_capability,
+			    const uint8_t *buf, size_t len);
 
 /**
  * wlan_tdls_antenna_switch() - process tdls antenna switch

+ 10 - 62
os_if/linux/tdls/src/wlan_cfg80211_tdls.c

@@ -181,10 +181,10 @@ void hdd_notify_sta_disconnect(uint8_t session_id,
 	notify_info.user_disconnect = user_disconnect;
 	ucfg_tdls_notify_sta_disconnect(&notify_info);
 }
-int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev,
-				struct net_device *dev, const uint8_t *mac)
+
+int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev,
+				const uint8_t *mac)
 {
-	struct wlan_objmgr_vdev *vdev;
 	struct tdls_add_peer_params *add_peer_req;
 	int status;
 	struct vdev_osif_priv *osif_priv;
@@ -198,16 +198,9 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev,
 
 	cfg80211_debug("Add TDLS peer " QDF_MAC_ADDR_STR,
 		       QDF_MAC_ADDR_ARRAY(mac));
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr,
-							 WLAN_OSIF_ID);
-	if (vdev == NULL) {
-		cfg80211_err("vdev object is NULL");
-		return -EIO;
-	}
 
 	add_peer_req = qdf_mem_malloc(sizeof(*add_peer_req));
 	if (!add_peer_req) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		cfg80211_err("Failed to allocate tdls add peer request mem");
 		return -EINVAL;
 	}
@@ -242,7 +235,6 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev,
 	}
 error:
 	qdf_mem_free(add_peer_req);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 	return status;
 }
 
@@ -394,12 +386,10 @@ wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info,
 		req_info->is_qos_wmm_sta = true;
 }
 
-int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev,
-				   struct net_device *dev,
+int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev,
 				   const uint8_t *mac,
 				   struct station_parameters *params)
 {
-	struct wlan_objmgr_vdev *vdev;
 	struct tdls_update_peer_params *req_info;
 	int status;
 	struct vdev_osif_priv *osif_priv;
@@ -413,16 +403,9 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev,
 
 	cfg80211_debug("Update TDLS peer " QDF_MAC_ADDR_STR,
 		       QDF_MAC_ADDR_ARRAY(mac));
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr,
-							 WLAN_OSIF_ID);
-	if (vdev == NULL) {
-		cfg80211_err("vdev object is NULL");
-		return -EIO;
-	}
 
 	req_info = qdf_mem_malloc(sizeof(*req_info));
 	if (!req_info) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		cfg80211_err("Failed to allocate tdls add peer request mem");
 		return -EINVAL;
 	}
@@ -457,7 +440,6 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev,
 	}
 error:
 	qdf_mem_free(req_info);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 	return status;
 }
 
@@ -526,12 +508,10 @@ int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev,
 	return status;
 }
 
-int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev,
-			    struct net_device *dev,
+int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev,
 			    const uint8_t *peer,
 			    enum nl80211_tdls_operation oper)
 {
-	struct wlan_objmgr_vdev *vdev;
 	struct vdev_osif_priv *osif_priv;
 	struct osif_tdls_vdev *tdls_priv;
 	int status;
@@ -549,14 +529,6 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev,
 		return -ENOTSUPP;
 	}
 
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev,
-							 dev->dev_addr,
-							 WLAN_OSIF_ID);
-	if (vdev == NULL) {
-		cfg80211_err("vdev object is NULL");
-		return -EIO;
-	}
-
 	cfg80211_debug("%s start", tdls_oper_to_str(oper));
 	cmd = tdls_oper_to_cmd(oper);
 	switch (oper) {
@@ -596,8 +568,6 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev,
 	}
 
 error:
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
-
 	return status;
 }
 
@@ -674,13 +644,6 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
 	QDF_STATUS status;
 	unsigned long rc;
 
-	if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID) !=
-							QDF_STATUS_SUCCESS) {
-		len = scnprintf(buf, buflen,
-				"\nNo TDLS VDEV is null\n");
-		return len;
-	}
-
 	osif_priv = wlan_vdev_get_ospriv(vdev);
 	tdls_priv = osif_priv->osif_tdls;
 
@@ -711,17 +674,15 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
 	len = tdls_priv->tdls_user_cmd_len;
 
 error_get_tdls_peers:
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 	return len;
 }
 
-int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev,
-				struct net_device *dev, const uint8_t *peer_mac,
-				uint8_t action_code, uint8_t dialog_token,
-				uint16_t status_code, uint32_t peer_capability,
-				const uint8_t *buf, size_t len)
+int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev,
+			    const uint8_t *peer_mac,
+			    uint8_t action_code, uint8_t dialog_token,
+			    uint16_t status_code, uint32_t peer_capability,
+			    const uint8_t *buf, size_t len)
 {
-	struct wlan_objmgr_vdev *vdev;
 	struct tdls_action_frame_request mgmt_req;
 	struct vdev_osif_priv *osif_priv;
 	struct osif_tdls_vdev *tdls_priv;
@@ -736,14 +697,6 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev,
 	if (status)
 		return status;
 
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev,
-							 dev->dev_addr,
-							 WLAN_OSIF_ID);
-	if (vdev == NULL) {
-		cfg80211_err("vdev object is NULL");
-		return -EIO;
-	}
-
 	osif_priv = wlan_vdev_get_ospriv(vdev);
 
 	tdls_priv = osif_priv->osif_tdls;
@@ -752,7 +705,6 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev,
 	if (TDLS_VDEV_MAGIC == tdls_priv->mgmt_tx_completion_status) {
 		cfg80211_err(QDF_MAC_ADDR_STR " action %d couldn't sent, as one is pending. return EBUSY",
 			     QDF_MAC_ADDR_ARRAY(peer_mac), action_code);
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 		return -EBUSY;
 	}
 
@@ -838,7 +790,6 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev,
 	}
 
 error_mgmt_req:
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 	return status;
 }
 
@@ -853,7 +804,6 @@ int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode)
 		cfg80211_err("vdev is NULL");
 		return -EAGAIN;
 	}
-	wlan_objmgr_vdev_get_ref(vdev, WLAN_OSIF_ID);
 
 	osif_priv = wlan_vdev_get_ospriv(vdev);
 	tdls_priv = osif_priv->osif_tdls;
@@ -878,8 +828,6 @@ int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode)
 	ret = tdls_priv->tdls_antenna_switch_status;
 	cfg80211_debug("tdls antenna switch status:%d", ret);
 error:
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
-
 	return ret;
 }