1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  *
4*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
5*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
6*5113495bSYour Name  * above copyright notice and this permission notice appear in all
7*5113495bSYour Name  * copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
17*5113495bSYour Name  */
18*5113495bSYour Name /**
19*5113495bSYour Name  * DOC: wlan_serialization_legacy_api.c
20*5113495bSYour Name  * This file provides prototypes of the routines needed for the
21*5113495bSYour Name  * legacy mcl serialization to utilize the services provided by the
22*5113495bSYour Name  * serialization component.
23*5113495bSYour Name  */
24*5113495bSYour Name 
25*5113495bSYour Name #include "wlan_serialization_legacy_api.h"
26*5113495bSYour Name #include "wlan_serialization_main_i.h"
27*5113495bSYour Name #include "wlan_serialization_utils_i.h"
28*5113495bSYour Name #include "wlan_objmgr_vdev_obj.h"
29*5113495bSYour Name #include "wlan_serialization_internal_i.h"
30*5113495bSYour Name #include "wlan_serialization_scan_i.h"
31*5113495bSYour Name #include "wlan_serialization_non_scan_i.h"
32*5113495bSYour Name 
wlan_serialization_get_first_pdev(struct wlan_objmgr_psoc * psoc)33*5113495bSYour Name static struct wlan_objmgr_pdev *wlan_serialization_get_first_pdev(
34*5113495bSYour Name 			struct wlan_objmgr_psoc *psoc)
35*5113495bSYour Name {
36*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev;
37*5113495bSYour Name 	uint8_t i = 0;
38*5113495bSYour Name 
39*5113495bSYour Name 	if (!psoc) {
40*5113495bSYour Name 		ser_err("invalid psoc");
41*5113495bSYour Name 		return NULL;
42*5113495bSYour Name 	}
43*5113495bSYour Name 	for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) {
44*5113495bSYour Name 		pdev = wlan_objmgr_get_pdev_by_id(psoc, i,
45*5113495bSYour Name 					WLAN_SERIALIZATION_ID);
46*5113495bSYour Name 		if (pdev)
47*5113495bSYour Name 			break;
48*5113495bSYour Name 	}
49*5113495bSYour Name 
50*5113495bSYour Name 	return pdev;
51*5113495bSYour Name }
52*5113495bSYour Name 
53*5113495bSYour Name static struct wlan_ser_pdev_obj *
wlan_serialization_get_pdev_priv_obj_using_psoc(struct wlan_objmgr_psoc * psoc)54*5113495bSYour Name wlan_serialization_get_pdev_priv_obj_using_psoc(struct wlan_objmgr_psoc *psoc)
55*5113495bSYour Name {
56*5113495bSYour Name 	struct wlan_objmgr_pdev *pdev = NULL;
57*5113495bSYour Name 	struct wlan_ser_pdev_obj *ser_pdev_obj;
58*5113495bSYour Name 
59*5113495bSYour Name 	if (!psoc) {
60*5113495bSYour Name 		ser_err("invalid psoc");
61*5113495bSYour Name 		return NULL;
62*5113495bSYour Name 	}
63*5113495bSYour Name 
64*5113495bSYour Name 	pdev = wlan_serialization_get_first_pdev(psoc);
65*5113495bSYour Name 	if (!pdev) {
66*5113495bSYour Name 		ser_err("invalid pdev");
67*5113495bSYour Name 		return NULL;
68*5113495bSYour Name 	}
69*5113495bSYour Name 
70*5113495bSYour Name 	ser_pdev_obj =  wlan_serialization_get_pdev_obj(pdev);
71*5113495bSYour Name 	wlan_objmgr_pdev_release_ref(pdev, WLAN_SERIALIZATION_ID);
72*5113495bSYour Name 	if (!ser_pdev_obj) {
73*5113495bSYour Name 		ser_err("invalid ser_pdev_obj");
74*5113495bSYour Name 		return NULL;
75*5113495bSYour Name 	}
76*5113495bSYour Name 
77*5113495bSYour Name 	return ser_pdev_obj;
78*5113495bSYour Name }
79*5113495bSYour Name 
wlan_serialization_get_pending_list_count(struct wlan_objmgr_psoc * psoc,uint8_t is_cmd_from_pending_scan_queue)80*5113495bSYour Name uint32_t wlan_serialization_get_pending_list_count(
81*5113495bSYour Name 				struct wlan_objmgr_psoc *psoc,
82*5113495bSYour Name 				uint8_t is_cmd_from_pending_scan_queue)
83*5113495bSYour Name {
84*5113495bSYour Name 	struct wlan_ser_pdev_obj *ser_pdev_obj;
85*5113495bSYour Name 	qdf_list_t *queue;
86*5113495bSYour Name 	uint32_t count = 0;
87*5113495bSYour Name 	struct wlan_serialization_pdev_queue  *pdev_queue;
88*5113495bSYour Name 
89*5113495bSYour Name 	ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc);
90*5113495bSYour Name 	if (!ser_pdev_obj) {
91*5113495bSYour Name 		ser_err("invalid ser_pdev_obj");
92*5113495bSYour Name 		return 0;
93*5113495bSYour Name 	}
94*5113495bSYour Name 
95*5113495bSYour Name 	if (is_cmd_from_pending_scan_queue)
96*5113495bSYour Name 		pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
97*5113495bSYour Name 	else
98*5113495bSYour Name 		pdev_queue =
99*5113495bSYour Name 		&ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
100*5113495bSYour Name 	queue = &pdev_queue->pending_list;
101*5113495bSYour Name 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
102*5113495bSYour Name 	count = qdf_list_size(queue);
103*5113495bSYour Name 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
104*5113495bSYour Name 
105*5113495bSYour Name 	return count;
106*5113495bSYour Name }
107*5113495bSYour Name 
108*5113495bSYour Name struct wlan_serialization_command*
wlan_serialization_peek_head_active_cmd_using_psoc(struct wlan_objmgr_psoc * psoc,uint8_t is_cmd_from_active_scan_queue)109*5113495bSYour Name wlan_serialization_peek_head_active_cmd_using_psoc(
110*5113495bSYour Name 			struct wlan_objmgr_psoc *psoc,
111*5113495bSYour Name 			uint8_t is_cmd_from_active_scan_queue)
112*5113495bSYour Name {
113*5113495bSYour Name 	struct wlan_ser_pdev_obj *ser_pdev_obj;
114*5113495bSYour Name 	struct wlan_serialization_command_list *cmd_list = NULL;
115*5113495bSYour Name 	struct wlan_serialization_command *cmd = NULL;
116*5113495bSYour Name 	qdf_list_node_t *nnode = NULL;
117*5113495bSYour Name 	qdf_list_t *queue;
118*5113495bSYour Name 	struct wlan_serialization_pdev_queue  *pdev_queue;
119*5113495bSYour Name 
120*5113495bSYour Name 	ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc);
121*5113495bSYour Name 	if (!ser_pdev_obj) {
122*5113495bSYour Name 		ser_err("invalid ser_pdev_obj");
123*5113495bSYour Name 		return NULL;
124*5113495bSYour Name 	}
125*5113495bSYour Name 
126*5113495bSYour Name 	if (is_cmd_from_active_scan_queue)
127*5113495bSYour Name 		pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
128*5113495bSYour Name 	else
129*5113495bSYour Name 		pdev_queue =
130*5113495bSYour Name 		&ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
131*5113495bSYour Name 	queue = &pdev_queue->active_list;
132*5113495bSYour Name 	if (wlan_serialization_list_empty(queue)) {
133*5113495bSYour Name 		ser_debug_rl("Empty Queue");
134*5113495bSYour Name 		goto end;
135*5113495bSYour Name 	}
136*5113495bSYour Name 
137*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != wlan_serialization_get_cmd_from_queue(queue,
138*5113495bSYour Name 						&nnode)) {
139*5113495bSYour Name 		ser_err("Can't get command from queue");
140*5113495bSYour Name 		goto end;
141*5113495bSYour Name 	}
142*5113495bSYour Name 
143*5113495bSYour Name 	cmd_list = qdf_container_of(nnode,
144*5113495bSYour Name 			struct wlan_serialization_command_list, pdev_node);
145*5113495bSYour Name 	cmd = &cmd_list->cmd;
146*5113495bSYour Name 
147*5113495bSYour Name end:
148*5113495bSYour Name 	return cmd;
149*5113495bSYour Name }
150*5113495bSYour Name 
151*5113495bSYour Name struct wlan_serialization_command*
wlan_serialization_peek_head_pending_cmd_using_psoc(struct wlan_objmgr_psoc * psoc,uint8_t is_cmd_from_pending_scan_queue)152*5113495bSYour Name wlan_serialization_peek_head_pending_cmd_using_psoc(
153*5113495bSYour Name 			struct wlan_objmgr_psoc *psoc,
154*5113495bSYour Name 			uint8_t is_cmd_from_pending_scan_queue)
155*5113495bSYour Name {
156*5113495bSYour Name 	struct wlan_ser_pdev_obj *ser_pdev_obj;
157*5113495bSYour Name 	struct wlan_serialization_command_list *cmd_list = NULL;
158*5113495bSYour Name 	struct wlan_serialization_command *cmd = NULL;
159*5113495bSYour Name 	qdf_list_node_t *nnode = NULL;
160*5113495bSYour Name 	qdf_list_t *queue;
161*5113495bSYour Name 	struct wlan_serialization_pdev_queue  *pdev_queue;
162*5113495bSYour Name 
163*5113495bSYour Name 	ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc);
164*5113495bSYour Name 	if (!ser_pdev_obj) {
165*5113495bSYour Name 		ser_err("invalid ser_pdev_obj");
166*5113495bSYour Name 		return NULL;
167*5113495bSYour Name 	}
168*5113495bSYour Name 	if (is_cmd_from_pending_scan_queue)
169*5113495bSYour Name 		pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
170*5113495bSYour Name 	else
171*5113495bSYour Name 		pdev_queue =
172*5113495bSYour Name 		&ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
173*5113495bSYour Name 	queue = &pdev_queue->pending_list;
174*5113495bSYour Name 	if (wlan_serialization_list_empty(queue))
175*5113495bSYour Name 		goto end;
176*5113495bSYour Name 
177*5113495bSYour Name 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
178*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != wlan_serialization_get_cmd_from_queue(
179*5113495bSYour Name 							queue,
180*5113495bSYour Name 							&nnode)) {
181*5113495bSYour Name 		wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
182*5113495bSYour Name 		ser_err("Can't get command from queue");
183*5113495bSYour Name 		goto end;
184*5113495bSYour Name 	}
185*5113495bSYour Name 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
186*5113495bSYour Name 	cmd_list = qdf_container_of(nnode,
187*5113495bSYour Name 			struct wlan_serialization_command_list, pdev_node);
188*5113495bSYour Name 	cmd = &cmd_list->cmd;
189*5113495bSYour Name 	ser_debug("cmd_type[%d] cmd_id[%d]matched",
190*5113495bSYour Name 		  cmd_list->cmd.cmd_type, cmd_list->cmd.cmd_id);
191*5113495bSYour Name 
192*5113495bSYour Name end:
193*5113495bSYour Name 	return cmd;
194*5113495bSYour Name }
195*5113495bSYour Name 
196*5113495bSYour Name static struct wlan_serialization_command*
wlan_serialization_get_list_next_node(qdf_list_t * queue,struct wlan_serialization_command * cmd,struct wlan_ser_pdev_obj * ser_pdev_obj)197*5113495bSYour Name wlan_serialization_get_list_next_node(qdf_list_t *queue,
198*5113495bSYour Name 			struct wlan_serialization_command *cmd,
199*5113495bSYour Name 			struct wlan_ser_pdev_obj *ser_pdev_obj)
200*5113495bSYour Name {
201*5113495bSYour Name 	struct wlan_serialization_command_list *cmd_list = NULL;
202*5113495bSYour Name 	qdf_list_node_t *pnode = NULL, *nnode = NULL;
203*5113495bSYour Name 	bool found = false;
204*5113495bSYour Name 	uint32_t i = 0;
205*5113495bSYour Name 	QDF_STATUS status;
206*5113495bSYour Name 	struct wlan_serialization_command *ret_cmd = NULL;
207*5113495bSYour Name 
208*5113495bSYour Name 	i = wlan_serialization_list_size(queue);
209*5113495bSYour Name 	if (i == 0) {
210*5113495bSYour Name 		ser_err("Empty Queue");
211*5113495bSYour Name 		return NULL;
212*5113495bSYour Name 	}
213*5113495bSYour Name 	while (i--) {
214*5113495bSYour Name 		if (!cmd_list)
215*5113495bSYour Name 			status = wlan_serialization_peek_front(queue, &nnode);
216*5113495bSYour Name 		else
217*5113495bSYour Name 			status = wlan_serialization_peek_next(queue, pnode,
218*5113495bSYour Name 							      &nnode);
219*5113495bSYour Name 
220*5113495bSYour Name 		if ((status != QDF_STATUS_SUCCESS) || found)
221*5113495bSYour Name 			break;
222*5113495bSYour Name 
223*5113495bSYour Name 		pnode = nnode;
224*5113495bSYour Name 		cmd_list = qdf_container_of(
225*5113495bSYour Name 					nnode,
226*5113495bSYour Name 					struct wlan_serialization_command_list,
227*5113495bSYour Name 					pdev_node);
228*5113495bSYour Name 		if (wlan_serialization_match_cmd_id_type(
229*5113495bSYour Name 				nnode, cmd, WLAN_SER_PDEV_NODE) &&
230*5113495bSYour Name 		    wlan_serialization_match_cmd_vdev(nnode,
231*5113495bSYour Name 						      cmd->vdev,
232*5113495bSYour Name 						      WLAN_SER_PDEV_NODE)) {
233*5113495bSYour Name 			found = true;
234*5113495bSYour Name 		}
235*5113495bSYour Name 		nnode = NULL;
236*5113495bSYour Name 	}
237*5113495bSYour Name 	if (nnode && found) {
238*5113495bSYour Name 		cmd_list = qdf_container_of(
239*5113495bSYour Name 				nnode,
240*5113495bSYour Name 				struct wlan_serialization_command_list,
241*5113495bSYour Name 				pdev_node);
242*5113495bSYour Name 		ret_cmd = &cmd_list->cmd;
243*5113495bSYour Name 	}
244*5113495bSYour Name 	if (!found) {
245*5113495bSYour Name 		ser_err("Can't locate next command");
246*5113495bSYour Name 		return NULL;
247*5113495bSYour Name 	}
248*5113495bSYour Name 	if (!nnode) {
249*5113495bSYour Name 		ser_debug("next node is empty, so fine");
250*5113495bSYour Name 		return NULL;
251*5113495bSYour Name 	}
252*5113495bSYour Name 
253*5113495bSYour Name 	return ret_cmd;
254*5113495bSYour Name }
255*5113495bSYour Name 
256*5113495bSYour Name struct wlan_serialization_command*
wlan_serialization_get_pending_list_next_node_using_psoc(struct wlan_objmgr_psoc * psoc,struct wlan_serialization_command * prev_cmd,uint8_t is_cmd_for_pending_scan_queue)257*5113495bSYour Name wlan_serialization_get_pending_list_next_node_using_psoc(
258*5113495bSYour Name 			struct wlan_objmgr_psoc *psoc,
259*5113495bSYour Name 			struct wlan_serialization_command *prev_cmd,
260*5113495bSYour Name 			uint8_t is_cmd_for_pending_scan_queue)
261*5113495bSYour Name {
262*5113495bSYour Name 	struct wlan_ser_pdev_obj *ser_pdev_obj;
263*5113495bSYour Name 	qdf_list_t *queue;
264*5113495bSYour Name 	struct wlan_serialization_pdev_queue  *pdev_queue;
265*5113495bSYour Name 	struct wlan_serialization_command *cmd;
266*5113495bSYour Name 
267*5113495bSYour Name 	if (!prev_cmd) {
268*5113495bSYour Name 		ser_err("invalid prev_cmd");
269*5113495bSYour Name 		return NULL;
270*5113495bSYour Name 	}
271*5113495bSYour Name 
272*5113495bSYour Name 	ser_pdev_obj = wlan_serialization_get_pdev_priv_obj_using_psoc(psoc);
273*5113495bSYour Name 	if (!ser_pdev_obj) {
274*5113495bSYour Name 		ser_err("invalid ser_pdev_obj");
275*5113495bSYour Name 		return NULL;
276*5113495bSYour Name 	}
277*5113495bSYour Name 	if (is_cmd_for_pending_scan_queue)
278*5113495bSYour Name 		pdev_queue = &ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_SCAN];
279*5113495bSYour Name 	else
280*5113495bSYour Name 		pdev_queue =
281*5113495bSYour Name 		&ser_pdev_obj->pdev_q[SER_PDEV_QUEUE_COMP_NON_SCAN];
282*5113495bSYour Name 	queue = &pdev_queue->pending_list;
283*5113495bSYour Name 
284*5113495bSYour Name 	wlan_serialization_acquire_lock(&pdev_queue->pdev_queue_lock);
285*5113495bSYour Name 	cmd = wlan_serialization_get_list_next_node(queue, prev_cmd,
286*5113495bSYour Name 						    ser_pdev_obj);
287*5113495bSYour Name 	wlan_serialization_release_lock(&pdev_queue->pdev_queue_lock);
288*5113495bSYour Name 
289*5113495bSYour Name 	return cmd;
290*5113495bSYour Name }
291