Ver código fonte

qcacmn: Configure the tdls offchannel params through IOCTL

Add support to configure tdls offchannel params
through IOCTL commands.

Change-Id: I90ba90b5ef980f837ce4759755efe190672ad911
CRs-Fixed: 2309185
Bala Venkatesh 6 anos atrás
pai
commit
f0c03be151

+ 80 - 0
umac/tdls/core/src/wlan_tdls_cmds_process.c

@@ -2334,3 +2334,83 @@ QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg)
 
 	return QDF_STATUS_SUCCESS;
 }
+
+void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev)
+{
+	if (!vdev) {
+		tdls_err("vdev is NULL");
+		return;
+	}
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
+}
+
+int tdls_process_set_offchannel(struct tdls_set_offchannel *req)
+{
+	int status;
+	struct tdls_vdev_priv_obj *tdls_vdev_obj;
+	struct tdls_soc_priv_obj *tdls_soc_obj;
+
+	if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) !=
+		QDF_STATUS_SUCCESS) {
+		status = -ENOTSUPP;
+		goto free;
+	}
+
+	tdls_debug("TDLS offchannel to be configured %d", req->offchannel);
+
+	if (req->offchannel)
+		status = tdls_set_tdls_offchannel(tdls_soc_obj,
+						  req->offchannel);
+	else
+		status = -ENOTSUPP;
+
+free:
+
+	if (req->callback)
+		req->callback(req->vdev);
+	qdf_mem_free(req);
+
+	return status;
+}
+
+int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req)
+{
+	int status;
+
+	tdls_debug("TDLS offchan mode to be configured %d", req->offchan_mode);
+	status = tdls_set_tdls_offchannelmode(req->vdev, req->offchan_mode);
+
+	if (req->callback)
+		req->callback(req->vdev);
+	qdf_mem_free(req);
+
+	return status;
+}
+
+int tdls_process_set_secoffchanneloffset(
+		struct tdls_set_secoffchanneloffset *req)
+{
+	int status;
+	struct tdls_vdev_priv_obj *tdls_vdev_obj;
+	struct tdls_soc_priv_obj *tdls_soc_obj;
+
+	if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) !=
+		QDF_STATUS_SUCCESS) {
+		status = -ENOTSUPP;
+		goto free;
+	}
+
+	tdls_debug("TDLS offchannel offset to be configured %d",
+		   req->offchan_offset);
+	status = tdls_set_tdls_secoffchanneloffset(tdls_soc_obj,
+						   req->offchan_offset);
+
+free:
+
+	if (req->callback)
+		req->callback(req->vdev);
+	qdf_mem_free(req);
+
+	return status;
+}

+ 34 - 0
umac/tdls/core/src/wlan_tdls_cmds_process.h

@@ -383,4 +383,38 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req);
  */
 void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj);
 
+/**
+ * wlan_tdls_offchan_parms_callback() - Callback to release ref count
+ * @vdev: vdev object
+ *
+ * Return: none
+ */
+void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev);
+
+/**
+ * tdls_process_set_offchannel() - Handle set offchannel request for TDLS
+ * @req: TDLS set offchannel request
+ *
+ * Return: int status
+ */
+int tdls_process_set_offchannel(struct tdls_set_offchannel *req);
+
+/**
+ * tdls_process_set_offchan_mode() - Handle set offchan mode request for TDLS
+ * @req: TDLS set offchannel mode request
+ *
+ * Return: int status
+ */
+int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req);
+
+/**
+ * tdls_process_set_secoffchanneloffset() - Handle set sec offchannel
+ * offset request for TDLS
+ * @req: TDLS set secoffchannel offchannel request
+ *
+ * Return: int status
+ */
+int tdls_process_set_secoffchanneloffset(
+		struct tdls_set_secoffchanneloffset *req);
+
 #endif

+ 2 - 32
umac/tdls/core/src/wlan_tdls_ct.c

@@ -936,16 +936,6 @@ void tdls_ct_handler(void *user_data)
 				     WLAN_TDLS_NB_ID);
 }
 
-/**
- * tdls_set_tdls_offchannel() - set tdls off-channel number
- * @tdls_soc: tdls soc object
- * @offchanmode: tdls off-channel number
- *
- * This function sets tdls off-channel number
- *
- * Return: 0 on success; negative errno otherwise
- */
-static
 int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc,
 			     int offchannel)
 {
@@ -964,7 +954,7 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc,
 			}
 	} else {
 		tdls_err("Either TDLS or TDLS Off-channel is not enabled");
-		return  -ENOTSUPP;
+		return -ENOTSUPP;
 	}
 	tdls_notice("change tdls off channel from %d to %d",
 		   tdls_soc->tdls_off_channel, offchannel);
@@ -972,16 +962,6 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc,
 	return 0;
 }
 
-/**
- * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset
- * @tdls_soc: tdls soc object
- * @offchanmode: tdls off-channel offset
- *
- * This function sets 2nd tdls off-channel offset
- *
- * Return: 0 on success; negative errno otherwise
- */
-static
 int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc,
 				int offchanoffset)
 {
@@ -1022,16 +1002,6 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc,
 	return 0;
 }
 
-/**
- * tdls_set_tdls_offchannelmode() - set tdls off-channel mode
- * @adapter: Pointer to the HDD adapter
- * @offchanmode: tdls off-channel mode
- *
- * This function sets tdls off-channel mode
- *
- * Return: 0 on success; negative errno otherwise
- */
-static
 int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
 				 int offchanmode)
 {
@@ -1056,7 +1026,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
 		return -EINVAL;
 	}
 
-	if (tdls_is_vdev_connected(vdev)) {
+	if (!tdls_is_vdev_connected(vdev)) {
 		tdls_err("tdls off channel req in not associated state %d",
 			offchanmode);
 		return -EPERM;

+ 38 - 0
umac/tdls/core/src/wlan_tdls_ct.h

@@ -206,4 +206,42 @@ void tdls_disable_offchan_and_teardown_links(
 QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev,
 					  struct tdls_soc_priv_obj *tdls_soc);
 
+/**
+ * tdls_set_tdls_offchannel() - set tdls off-channel number
+ * @tdls_soc: tdls soc object
+ * @offchanmode: tdls off-channel number
+ *
+ * This function sets tdls off-channel number
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc,
+			     int offchannel);
+
+/**
+ * tdls_set_tdls_offchannelmode() - set tdls off-channel mode
+ * @adapter: Pointer to the HDD adapter
+ * @offchannel: tdls off-channel mode
+ *
+ * This function sets tdls off-channel mode
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+
+int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
+				 int offchanmode);
+
+/**
+ * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset
+ * @tdls_soc: tdls soc object
+ * @offchanoffset: tdls off-channel offset
+ *
+ * This function sets secondary tdls off-channel offset
+ *
+ * Return: 0 on success; negative errno otherwise
+ */
+
+int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc,
+				      int offchanoffset);
+
 #endif

+ 9 - 0
umac/tdls/core/src/wlan_tdls_main.c

@@ -322,6 +322,15 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
 	case TDLS_CMD_GET_ALL_PEERS:
 		tdls_get_all_peers_from_list(msg->bodyptr);
 		break;
+	case TDLS_CMD_SET_OFFCHANNEL:
+		tdls_process_set_offchannel(msg->bodyptr);
+		break;
+	case TDLS_CMD_SET_OFFCHANMODE:
+		tdls_process_set_offchan_mode(msg->bodyptr);
+		break;
+	case TDLS_CMD_SET_SECOFFCHANOFFSET:
+		tdls_process_set_secoffchanneloffset(msg->bodyptr);
+		break;
 	default:
 		break;
 	}

+ 41 - 1
umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h

@@ -190,6 +190,9 @@ enum tdls_feature_mode {
  * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapter reset
  * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list
  * @TDLS_CMD_ANTENNA_SWITCH: dynamic tdls antenna switch
+ * @TDLS_CMD_SET_OFFCHANNEL: tdls offchannel
+ * @TDLS_CMD_SET_OFFCHANMODE: tdls offchannel mode
+ * @TDLS_CMD_SET_SECOFFCHANOFFSET: tdls secondary offchannel offset
  */
 enum tdls_command_type {
 	TDLS_CMD_TX_ACTION = 1,
@@ -211,7 +214,10 @@ enum tdls_command_type {
 	TDLS_CMD_TEARDOWN_LINKS,
 	TDLS_NOTIFY_RESET_ADAPTERS,
 	TDLS_CMD_GET_ALL_PEERS,
-	TDLS_CMD_ANTENNA_SWITCH
+	TDLS_CMD_ANTENNA_SWITCH,
+	TDLS_CMD_SET_OFFCHANNEL,
+	TDLS_CMD_SET_OFFCHANMODE,
+	TDLS_CMD_SET_SECOFFCHANOFFSET
 };
 
 /**
@@ -582,6 +588,9 @@ typedef QDF_STATUS
 /* This callback is to release vdev ref for tdls sta notify msg */
 typedef void (*tdls_sta_notify_callback)(struct wlan_objmgr_vdev *vdev);
 
+/* This callback is to release vdev ref for tdls offchan param related msg */
+typedef void (*tdls_offchan_parms_callback)(struct wlan_objmgr_vdev *vdev);
+
 /**
  * struct tdls_start_params - tdls start params
  * @config: tdls user config
@@ -1098,4 +1107,35 @@ struct tdls_antenna_switch_request {
 	struct wlan_objmgr_vdev *vdev;
 	uint32_t mode;
 };
+
+/**
+ * struct tdls_set_offchannel - TDLS set offchannel
+ * @offchannel: Updated tdls offchannel value.
+ */
+struct tdls_set_offchannel {
+	struct wlan_objmgr_vdev *vdev;
+	uint16_t offchannel;
+	tdls_offchan_parms_callback callback;
+};
+
+/**
+ * struct tdls_set_offchan_mode - TDLS set offchannel mode
+ * @offchan_mode: Updated tdls offchannel mode value.
+ */
+struct tdls_set_offchanmode {
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t offchan_mode;
+	tdls_offchan_parms_callback callback;
+};
+
+/**
+ * struct tdls_set_offchan_offset - TDLS set offchannel mode
+ * @offchan_offset: Offchan offset value.
+ */
+struct tdls_set_secoffchanneloffset {
+	struct wlan_objmgr_vdev *vdev;
+	uint8_t offchan_offset;
+	tdls_offchan_parms_callback callback;
+};
+
 #endif

+ 29 - 0
umac/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h

@@ -222,4 +222,33 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
 QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev,
 				    uint32_t mode);
 
+/**
+ * ucfg_set_tdls_offchannel() - Handle TDLS set offchannel
+ * @vdev: vdev object
+ * @offchannel: updated offchannel
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev,
+				    int offchannel);
+
+/**
+ * ucfg_set_tdls_offchan_mode() - Handle TDLS set offchannel mode
+ * @vdev: vdev object
+ * @offchanmode: updated off-channel mode
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev,
+				      int offchanmode);
+
+/**
+ * ucfg_set_tdls_secoffchanneloffset() - Handle TDLS set offchannel offset
+ * @vdev: vdev object
+ * @offchanoffset: tdls off-channel offset
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev,
+					     int offchanoffset);
 #endif

+ 122 - 0
umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c

@@ -870,3 +870,125 @@ error:
 	qdf_mem_free(req);
 	return status;
 }
+
+QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev,
+				    int offchannel)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg = {0, };
+	struct tdls_set_offchannel *req;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req) {
+		tdls_err("mem allocate fail");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("can't get vdev");
+		goto free;
+	}
+
+	req->offchannel = offchannel;
+	req->vdev = vdev;
+	req->callback = wlan_tdls_offchan_parms_callback;
+	msg.bodyptr = req;
+	msg.callback = tdls_process_cmd;
+	msg.type = TDLS_CMD_SET_OFFCHANNEL;
+	status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("post set tdls offchannel msg fail");
+		goto dec_ref;
+	}
+
+	return status;
+
+dec_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
+
+free:
+	qdf_mem_free(req);
+	return status;
+}
+
+QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev,
+				      int offchanmode)
+{
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg = {0, };
+	struct tdls_set_offchanmode *req;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req) {
+		tdls_err("mem allocate fail");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("can't get vdev");
+		goto free;
+	}
+
+	req->offchan_mode = offchanmode;
+	req->vdev = vdev;
+	req->callback = wlan_tdls_offchan_parms_callback;
+	msg.bodyptr = req;
+	msg.callback = tdls_process_cmd;
+	msg.type = TDLS_CMD_SET_OFFCHANMODE;
+	status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("post set offchanmode msg fail");
+		goto dec_ref;
+	}
+
+	return status;
+
+dec_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
+
+free:
+	qdf_mem_free(req);
+	return status;
+}
+
+QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev,
+					     int offchanoffset)
+{
+	int status = QDF_STATUS_SUCCESS;
+	struct scheduler_msg msg = {0, };
+	struct tdls_set_secoffchanneloffset *req;
+
+	req = qdf_mem_malloc(sizeof(*req));
+	if (!req) {
+		tdls_err("mem allocate fail");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("can't get vdev");
+		goto free;
+	}
+
+	req->offchan_offset = offchanoffset;
+	req->vdev = vdev;
+	req->callback = wlan_tdls_offchan_parms_callback;
+	msg.bodyptr = req;
+	msg.callback = tdls_process_cmd;
+	msg.type = TDLS_CMD_SET_SECOFFCHANOFFSET;
+	status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		tdls_err("post set secoffchan offset msg fail");
+		goto dec_ref;
+	}
+	return status;
+
+dec_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
+
+free:
+	qdf_mem_free(req);
+	return status;
+}