xref: /wlan-dirver/qca-wifi-host-cmn/umac/mlme/mlme_utils/wlan_vdev_mlme_ser_if.c (revision dd4dc88b837a295134aa9869114a2efee0f4894b)
1 /*
2  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /**
18  * @file wlan_vdev_mlme_ser.c
19  * This file contains the APIs to support interface between vdev_mlme and
20  * serialization module
21  */
22 
23 #include <qdf_types.h>
24 #include <qdf_status.h>
25 #include <qdf_mem.h>
26 #include <wlan_serialization_api.h>
27 #include <wlan_objmgr_vdev_obj.h>
28 #include <wlan_cmn.h>
29 #include <wlan_mlme_dbg.h>
30 #include <include/wlan_mlme_cmn.h>
31 #include <wlan_vdev_mlme_api.h>
32 #include <wlan_vdev_mlme_ser_if.h>
33 
34 enum wlan_serialization_status
35 wlan_vdev_mlme_ser_start_bss(struct wlan_serialization_command *cmd)
36 {
37 	struct vdev_mlme_obj *vdev_mlme;
38 
39 	if (!cmd || !cmd->vdev) {
40 		mlme_err("Null input");
41 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
42 	}
43 
44 	/*
45 	 * Serialization command filtering logic
46 	 * a. Cancel any existing start bss cmd in the pending queue
47 	 * b. If there is an start bss cmd in active queue and
48 	 * there is no stop bss cmd in pending queue,
49 	 * then explicitly enqueue a stop bss cmd to avoid back to
50 	 * back execution of UP cmd.
51 	 * c. Enqueue the new start bss cmd with serialization
52 	 */
53 	wlan_vdev_mlme_ser_cancel_request(
54 			cmd->vdev,
55 			WLAN_SER_CMD_VDEV_START_BSS,
56 			WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE);
57 
58 	if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) {
59 		vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(cmd->vdev);
60 		if (mlme_vdev_enqueue_exp_ser_cmd(vdev_mlme,
61 						  WLAN_SER_CMD_VDEV_STOP_BSS)) {
62 			mlme_err("Unable to add the exception cmd request");
63 			return WLAN_SER_CMD_DENIED_UNSPECIFIED;
64 		}
65 	}
66 
67 	return wlan_serialization_request(cmd);
68 }
69 
70 enum wlan_serialization_status
71 wlan_vdev_mlme_ser_stop_bss(struct wlan_serialization_command *cmd)
72 {
73 	uint8_t stop_cmd_pending;
74 	uint8_t ret;
75 
76 	if (!cmd || !cmd->vdev) {
77 		mlme_err("Null input");
78 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
79 	}
80 	/*
81 	 * Serialization command filtering logic
82 	 * a. Cancel any existing start/stop/restart command in the pending
83 	 *  queue.
84 	 * b. If there is a stop cmd in active queue then return
85 	 * c. Else enqueue the cmd
86 	 * d. If stop cmd already existed in pending queue then return with
87 	 *  already exists else return the enqueued return value.
88 	 */
89 	stop_cmd_pending =
90 		wlan_serialization_is_cmd_present_in_pending_queue(NULL, cmd);
91 	wlan_vdev_mlme_ser_cancel_request(cmd->vdev,
92 					  WLAN_SER_CMD_NONSCAN,
93 					  WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD);
94 
95 	if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) {
96 		mlme_debug("Cmd already exist in the active queue");
97 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
98 	}
99 
100 	ret = wlan_serialization_request(cmd);
101 
102 	if (stop_cmd_pending && ret == WLAN_SER_CMD_PENDING)
103 		return WLAN_SER_CMD_ALREADY_EXISTS;
104 	else
105 		return ret;
106 }
107 
108 enum wlan_serialization_status
109 wlan_vdev_mlme_ser_restart_bss(struct wlan_serialization_command *cmd)
110 {
111 	if (!cmd || !cmd->vdev) {
112 		mlme_err("Null input");
113 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
114 	}
115 	/*
116 	 * Serialization command filtering logic
117 	 * a. Cancel any existing RESTART cmd in the pending queue
118 	 * b. Enqueue the new RESTART cmd
119 	 */
120 	wlan_vdev_mlme_ser_cancel_request(
121 			cmd->vdev,
122 			WLAN_SER_CMD_VDEV_RESTART,
123 			WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE);
124 	return wlan_serialization_request(cmd);
125 }
126 
127 enum wlan_serialization_status
128 wlan_vdev_mlme_ser_connect(struct wlan_serialization_command *cmd)
129 {
130 	struct vdev_mlme_obj *vdev_mlme;
131 
132 	if (!cmd || !cmd->vdev) {
133 		mlme_err("Null input");
134 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
135 	}
136 	/*
137 	 * Serialization command filtering logic
138 	 * a. Cancel any existing CONNECT cmd in the pending queue
139 	 * b. If there is an CONNECT cmd in active queue and there is no
140 	 * DISCONNECT cmd in pending queue, then explicitly enqueue a
141 	 * DISCONNECT cmd to avoid back to back execution of CONNECT cmd.
142 	 * c. Enqueue the new CONNECT cmd to the pending queue
143 	 */
144 	wlan_vdev_mlme_ser_cancel_request(
145 			cmd->vdev,
146 			WLAN_SER_CMD_VDEV_CONNECT,
147 			WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD_TYPE);
148 
149 	if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) {
150 		vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(cmd->vdev);
151 		if (mlme_vdev_enqueue_exp_ser_cmd(vdev_mlme,
152 					WLAN_SER_CMD_VDEV_DISCONNECT)) {
153 			mlme_err("Unable to add the exception cmd request");
154 			return WLAN_SER_CMD_DENIED_UNSPECIFIED;
155 		}
156 	}
157 
158 	return wlan_serialization_request(cmd);
159 }
160 
161 enum wlan_serialization_status
162 wlan_vdev_mlme_ser_disconnect(struct wlan_serialization_command *cmd)
163 {
164 	if (!cmd || !cmd->vdev) {
165 		mlme_err("Null input");
166 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
167 	}
168 	/*
169 	 * Serialization command filtering logic
170 	 * a.Cancel any existing CONNECT/DISCONNECT/RESTART command in the
171 	 * pending queue
172 	 * b.If there is a DISCONNECT cmd in active queue then return
173 	 * c.Else enqueue the DISCONNECT cmd
174 	 */
175 	wlan_vdev_mlme_ser_cancel_request(cmd->vdev,
176 					  WLAN_SER_CMD_NONSCAN,
177 					  WLAN_SER_CANCEL_VDEV_NON_SCAN_CMD);
178 
179 	if (wlan_serialization_is_cmd_present_in_active_queue(NULL, cmd)) {
180 		mlme_debug("Cmd already exist in the active queue");
181 		return WLAN_SER_CMD_DENIED_UNSPECIFIED;
182 	}
183 
184 	return wlan_serialization_request(cmd);
185 }
186 
187 void
188 wlan_vdev_mlme_ser_remove_request(struct wlan_objmgr_vdev *vdev,
189 				  uint32_t cmd_id,
190 				  enum wlan_serialization_cmd_type cmd_type)
191 {
192 	struct wlan_serialization_queued_cmd_info cmd = {0};
193 
194 	mlme_debug("Remove the cmd type:%d", cmd_type);
195 
196 	cmd.vdev = vdev;
197 	cmd.cmd_id = cmd_id;
198 	cmd.cmd_type = cmd_type;
199 	cmd.requestor = WLAN_UMAC_COMP_MLME;
200 	cmd.req_type = WLAN_SER_CANCEL_NON_SCAN_CMD;
201 	cmd.queue_type = WLAN_SERIALIZATION_ACTIVE_QUEUE;
202 
203 	/* Inform serialization for command completion */
204 	wlan_serialization_remove_cmd(&cmd);
205 }
206 
207 void
208 wlan_vdev_mlme_ser_cancel_request(struct wlan_objmgr_vdev *vdev,
209 				  enum wlan_serialization_cmd_type cmd_type,
210 				  enum wlan_serialization_cancel_type req_type)
211 {
212 	struct wlan_serialization_queued_cmd_info cmd = {0};
213 
214 	cmd.vdev = vdev;
215 	cmd.cmd_type = cmd_type;
216 	cmd.req_type = req_type;
217 	cmd.requestor = WLAN_UMAC_COMP_MLME;
218 	cmd.queue_type = WLAN_SERIALIZATION_PENDING_QUEUE;
219 
220 	wlan_serialization_cancel_request(&cmd);
221 }
222 
223 void
224 mlme_ser_inc_act_cmd_timeout(struct wlan_serialization_command *cmd)
225 {
226 	mlme_debug("Increase timeout of cmd type:%d", cmd->cmd_type);
227 	wlan_serialization_update_timer(cmd);
228 }
229