瀏覽代碼

qcacmn: Take vdev ref before posting the tdls mgmt tx command

Before posting the TDLS_CMD_TX_ACTION to scheduler thread take the
vdev ref with module id TDLS and release the ref as part of
freeing this command.

Change-Id: Id05962a1c9fc415199f347c5d85d1e0670dc247c
CRs-Fixed: 2338113
Bala Venkatesh 6 年之前
父節點
當前提交
3b427de23b
共有 2 個文件被更改,包括 53 次插入22 次删除
  1. 14 18
      umac/tdls/core/src/wlan_tdls_mgmt.c
  2. 39 4
      umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c

+ 14 - 18
umac/tdls/core/src/wlan_tdls_mgmt.c

@@ -225,15 +225,10 @@ static QDF_STATUS tdls_activate_send_mgmt_request(
 	if (!action_req || !action_req->vdev)
 		return QDF_STATUS_E_NULL_VALUE;
 
-	if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(action_req->vdev,
-						WLAN_TDLS_SB_ID))
-		return QDF_STATUS_E_NULL_VALUE;
-
-
 	tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(action_req->vdev);
 	if (!tdls_soc_obj) {
 		status = QDF_STATUS_E_NULL_VALUE;
-		goto release_mgmt_ref;
+		goto release_cmd;
 	}
 
 	tdls_mgmt_req = qdf_mem_malloc(sizeof(struct tdls_send_mgmt_request) +
@@ -242,7 +237,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request(
 		status = QDF_STATUS_E_NOMEM;
 		tdls_err("mem alloc failed ");
 		QDF_ASSERT(0);
-		goto release_mgmt_ref;
+		goto release_cmd;
 	}
 
 	tdls_debug("session_id %d "
@@ -274,7 +269,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request(
 	status =  wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID);
 	if (QDF_IS_STATUS_ERROR(status)) {
 		qdf_mem_free(tdls_mgmt_req);
-		goto release_mgmt_ref;
+		goto release_cmd;
 	}
 
 	qdf_mem_copy(tdls_mgmt_req->bssid.bytes,
@@ -309,9 +304,8 @@ static QDF_STATUS tdls_activate_send_mgmt_request(
 					QDF_MODULE_ID_PE, &msg);
 
 	wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);
-release_mgmt_ref:
-	wlan_objmgr_vdev_release_ref(action_req->vdev, WLAN_TDLS_SB_ID);
 
+release_cmd:
 	/*update tdls nss infornation based on action code */
 	tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code);
 	if (QDF_IS_STATUS_ERROR(status)) {
@@ -352,13 +346,13 @@ tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd,
 		 */
 		status = tdls_internal_send_mgmt_tx_done(req,
 				QDF_STATUS_E_FAILURE);
-		qdf_mem_free(req);
 		break;
 
 	case WLAN_SER_CB_RELEASE_MEM_CMD:
 		/* command successfully completed.
 		 * release tdls_action_frame_request memory
 		 */
+		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID);
 		qdf_mem_free(req);
 		break;
 
@@ -384,8 +378,7 @@ QDF_STATUS tdls_process_mgmt_req(
 	if (status != QDF_STATUS_SUCCESS) {
 		status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req,
 							 status);
-		qdf_mem_free(tdls_mgmt_req);
-		return status;
+		goto error_mgmt;
 	}
 
 	/* update the responder, status code information
@@ -422,14 +415,17 @@ QDF_STATUS tdls_process_mgmt_req(
 	case WLAN_SER_CMD_DENIED_LIST_FULL:
 	case WLAN_SER_CMD_DENIED_RULES_FAILED:
 	case WLAN_SER_CMD_DENIED_UNSPECIFIED:
-		/* free the request */
-		qdf_mem_free(tdls_mgmt_req);
-		break;
-
+		status = QDF_STATUS_E_FAILURE;
+		goto error_mgmt;
 	default:
 		QDF_ASSERT(0);
 		status = QDF_STATUS_E_INVAL;
-		break;
+		goto error_mgmt;
 	}
 	return status;
+
+error_mgmt:
+	wlan_objmgr_vdev_release_ref(tdls_mgmt_req->vdev, WLAN_TDLS_NB_ID);
+	qdf_mem_free(tdls_mgmt_req);
+	return status;
 }

+ 39 - 4
umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c

@@ -622,11 +622,28 @@ QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev,
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS tdls_send_mgmt_frame_flush_callback(struct scheduler_msg *msg)
+{
+	struct tdls_action_frame_request *req;
+
+	if (!msg || !msg->bodyptr) {
+		tdls_err("msg or msg->bodyptr is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+	req = msg->bodyptr;
+	if (req->vdev)
+		wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID);
+
+	qdf_mem_free(req);
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS ucfg_tdls_send_mgmt_frame(
 				struct tdls_action_frame_request *req)
 {
 	struct scheduler_msg msg = {0, };
 	struct tdls_action_frame_request *mgmt_req;
+	QDF_STATUS status;
 
 	if (!req || !req->vdev) {
 		tdls_err("Invalid mgmt req params %pK", req);
@@ -653,14 +670,32 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame(
 
 	tdls_debug("vdev id: %d, session id : %d", mgmt_req->vdev_id,
 		    mgmt_req->session_id);
+	status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_TDLS_NB_ID);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("Unable to get vdev reference for tdls module");
+		goto mem_free;
+	}
+
 	msg.bodyptr = mgmt_req;
 	msg.callback = tdls_process_cmd;
+	msg.flush_callback = tdls_send_mgmt_frame_flush_callback;
 	msg.type = TDLS_CMD_TX_ACTION;
-	scheduler_post_message(QDF_MODULE_ID_HDD,
-			       QDF_MODULE_ID_TDLS,
-			       QDF_MODULE_ID_OS_IF, &msg);
+	status = scheduler_post_message(QDF_MODULE_ID_HDD,
+					QDF_MODULE_ID_TDLS,
+					QDF_MODULE_ID_OS_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("Failed to post the mgmt tx cmd to scheduler thread");
+		goto release_ref;
+	}
 
-	return QDF_STATUS_SUCCESS;
+	return status;
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID);
+mem_free:
+	qdf_mem_free(mgmt_req);
+	return status;
 }
 
 QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req)