xref: /wlan-driver/qcacld-3.0/components/p2p/core/src/wlan_p2p_off_chan_tx.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * DOC: This file contains off channel tx API definitions
22  */
23 
24 #include <wmi_unified_api.h>
25 #include <wlan_mgmt_txrx_utils_api.h>
26 #include <wlan_objmgr_psoc_obj.h>
27 #include <wlan_objmgr_peer_obj.h>
28 #include <wlan_utility.h>
29 #include <scheduler_api.h>
30 #include "wlan_p2p_public_struct.h"
31 #include "wlan_p2p_tgt_api.h"
32 #include "wlan_p2p_ucfg_api.h"
33 #include "wlan_p2p_roc.h"
34 #include "wlan_p2p_main.h"
35 #include "wlan_p2p_off_chan_tx.h"
36 #include "wlan_osif_request_manager.h"
37 #include <wlan_mlme_main.h>
38 #include "wlan_mlme_api.h"
39 #include <wlan_cm_api.h>
40 #include <wlan_mlo_mgr_sta.h>
41 
42 /**
43  * p2p_psoc_get_tx_ops() - get p2p tx ops
44  * @psoc:        psoc object
45  *
46  * This function returns p2p tx ops callbacks.
47  *
48  * Return: wlan_lmac_if_p2p_tx_ops
49  */
50 static inline struct wlan_lmac_if_p2p_tx_ops *
p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc * psoc)51 p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc)
52 {
53 	return &psoc->soc_cb.tx_ops->p2p;
54 }
55 
56 /**
57  * p2p_tx_context_check_valid() - check tx action context
58  * @tx_ctx:         tx context
59  *
60  * This function check if tx action context and parameters are valid.
61  *
62  * Return: QDF_STATUS_SUCCESS - in case of success
63  */
p2p_tx_context_check_valid(struct tx_action_context * tx_ctx)64 static QDF_STATUS p2p_tx_context_check_valid(struct tx_action_context *tx_ctx)
65 {
66 	struct wlan_objmgr_psoc *psoc;
67 	struct p2p_soc_priv_obj *p2p_soc_obj;
68 
69 	if (!tx_ctx) {
70 		p2p_err("null tx action context");
71 		return QDF_STATUS_E_INVAL;
72 	}
73 
74 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
75 	if (!p2p_soc_obj) {
76 		p2p_err("null p2p soc private object");
77 		return QDF_STATUS_E_INVAL;
78 	}
79 
80 	psoc = p2p_soc_obj->soc;
81 	if (!psoc) {
82 		p2p_err("null p2p soc object");
83 		return QDF_STATUS_E_INVAL;
84 	}
85 
86 	if (!tx_ctx->buf) {
87 		p2p_err("null tx buffer");
88 		return QDF_STATUS_E_INVAL;
89 	}
90 
91 	return QDF_STATUS_SUCCESS;
92 }
93 
94 /**
95  * p2p_vdev_check_valid() - check vdev and vdev mode
96  * @tx_ctx:         tx context
97  *
98  * This function check if vdev and vdev mode are valid. It will drop
99  * probe response in sta mode.
100  *
101  * Return: QDF_STATUS_SUCCESS - in case of success
102  */
103 #ifdef SUPPORT_P2P_BY_ONE_INTF_WLAN
p2p_vdev_check_valid(struct tx_action_context * tx_ctx)104 static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx)
105 {
106 	enum QDF_OPMODE mode;
107 	struct wlan_objmgr_vdev *vdev;
108 	struct wlan_objmgr_psoc *psoc;
109 	struct p2p_soc_priv_obj *p2p_soc_obj;
110 	QDF_STATUS status = QDF_STATUS_SUCCESS;
111 
112 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
113 	psoc = p2p_soc_obj->soc;
114 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
115 			psoc, tx_ctx->vdev_id, WLAN_P2P_ID);
116 	if (!vdev) {
117 		p2p_err("null vdev object");
118 		return QDF_STATUS_E_INVAL;
119 	}
120 
121 	mode = wlan_vdev_mlme_get_opmode(vdev);
122 	p2p_debug("vdev mode:%d", mode);
123 
124 	/* drop probe response/disassoc/deauth for go, sap */
125 	if ((mode == QDF_SAP_MODE ||
126 	     mode == QDF_P2P_GO_MODE) &&
127 	    ((tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) ||
128 	     (tx_ctx->frame_info.sub_type == P2P_MGMT_DISASSOC) ||
129 	     (tx_ctx->frame_info.sub_type == P2P_MGMT_DEAUTH))) {
130 		p2p_debug("drop frame, mode:%d, sub type:%d", mode,
131 			  tx_ctx->frame_info.sub_type);
132 		status = QDF_STATUS_E_FAILURE;
133 	}
134 
135 	/* drop action frame for sap */
136 	if ((mode == QDF_SAP_MODE) &&
137 	    (tx_ctx->frame_info.sub_type == P2P_MGMT_ACTION) &&
138 	    (tx_ctx->frame_info.public_action_type ==
139 	     P2P_PUBLIC_ACTION_NOT_SUPPORT) &&
140 	    (tx_ctx->frame_info.action_type == P2P_ACTION_NOT_SUPPORT) &&
141 	    !(wlan_vdev_mlme_feat_cap_get(vdev, WLAN_VDEV_F_SON) &&
142 	      !tx_ctx->off_chan)) {
143 		p2p_debug("drop action frame for SAP");
144 		status = QDF_STATUS_E_FAILURE;
145 	}
146 
147 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
148 
149 	return status;
150 }
151 #else
p2p_vdev_check_valid(struct tx_action_context * tx_ctx)152 static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx)
153 {
154 	enum QDF_OPMODE mode;
155 	struct wlan_objmgr_vdev *vdev;
156 	struct wlan_objmgr_psoc *psoc;
157 	struct p2p_soc_priv_obj *p2p_soc_obj;
158 	QDF_STATUS status = QDF_STATUS_SUCCESS;
159 
160 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
161 	psoc = p2p_soc_obj->soc;
162 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
163 			psoc, tx_ctx->vdev_id, WLAN_P2P_ID);
164 	if (!vdev) {
165 		p2p_err("null vdev object");
166 		return QDF_STATUS_E_INVAL;
167 	}
168 
169 	mode = wlan_vdev_mlme_get_opmode(vdev);
170 	p2p_debug("vdev mode:%d", mode);
171 
172 	/* drop probe response/disassoc/deauth for sta, go, sap */
173 	if ((mode == QDF_STA_MODE &&
174 	     tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) ||
175 	    ((mode == QDF_SAP_MODE || mode == QDF_P2P_GO_MODE) &&
176 	     ((tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) ||
177 	     (tx_ctx->frame_info.sub_type == P2P_MGMT_DISASSOC) ||
178 	     (tx_ctx->frame_info.sub_type == P2P_MGMT_DEAUTH)))) {
179 		p2p_debug("drop frame, mode:%d, sub type:%d", mode,
180 			  tx_ctx->frame_info.sub_type);
181 		status = QDF_STATUS_E_FAILURE;
182 	}
183 
184 	/* drop ation frame for sap */
185 	if ((mode == QDF_SAP_MODE) &&
186 	    (tx_ctx->frame_info.sub_type == P2P_MGMT_ACTION) &&
187 	    (tx_ctx->frame_info.public_action_type ==
188 	     P2P_PUBLIC_ACTION_NOT_SUPPORT) &&
189 	    (tx_ctx->frame_info.action_type == P2P_ACTION_NOT_SUPPORT) &&
190 	    !(wlan_vdev_mlme_feat_cap_get(vdev, WLAN_VDEV_F_SON) &&
191 	      !tx_ctx->off_chan)) {
192 		p2p_debug("drop action frame for SAP");
193 		status = QDF_STATUS_E_FAILURE;
194 	}
195 
196 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
197 
198 	return status;
199 }
200 #endif /* SUPPORT_P2P_BY_ONE_INTF_WLAN */
201 
202 /**
203  * p2p_check_and_update_channel() - check and update tx channel
204  * @tx_ctx:         tx context
205  *
206  * This function checks and updates tx channel if channel is 0 in tx context.
207  * It will update channel to current roc channel if vdev mode is
208  * P2P DEVICE/CLIENT/GO.
209  *
210  * Return: QDF_STATUS_SUCCESS - in case of success
211  */
p2p_check_and_update_channel(struct tx_action_context * tx_ctx)212 static QDF_STATUS p2p_check_and_update_channel(struct tx_action_context *tx_ctx)
213 {
214 	enum QDF_OPMODE mode;
215 	struct wlan_objmgr_vdev *vdev;
216 	struct wlan_objmgr_psoc *psoc;
217 	struct p2p_soc_priv_obj *p2p_soc_obj;
218 	struct p2p_roc_context *curr_roc_ctx;
219 
220 	if (!tx_ctx || tx_ctx->chan_freq) {
221 		p2p_err("NULL tx ctx or channel valid");
222 		return QDF_STATUS_E_INVAL;
223 	}
224 
225 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
226 	psoc = p2p_soc_obj->soc;
227 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
228 			psoc, tx_ctx->vdev_id, WLAN_P2P_ID);
229 	if (!vdev) {
230 		p2p_err("null vdev object");
231 		return QDF_STATUS_E_INVAL;
232 	}
233 
234 	mode = wlan_vdev_mlme_get_opmode(vdev);
235 	curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
236 
237 	if (curr_roc_ctx &&
238 	    (mode == QDF_P2P_DEVICE_MODE ||
239 	     mode == QDF_P2P_CLIENT_MODE ||
240 	     mode == QDF_P2P_GO_MODE))
241 		tx_ctx->chan_freq = curr_roc_ctx->chan_freq;
242 
243 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
244 
245 	return QDF_STATUS_SUCCESS;
246 }
247 
248 /**
249  * p2p_get_p2pie_ptr() - get the pointer to p2p ie
250  * @ie:      source ie
251  * @ie_len:  source ie length
252  *
253  * This function finds out p2p ie by p2p oui and return the pointer.
254  *
255  * Return: pointer to p2p ie
256  */
p2p_get_p2pie_ptr(const uint8_t * ie,uint16_t ie_len)257 const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len)
258 {
259 	return wlan_get_vendor_ie_ptr_from_oui(P2P_OUI,
260 			P2P_OUI_SIZE, ie, ie_len);
261 }
262 
263 /**
264  * p2p_get_p2pie_from_probe_rsp() - get the pointer to p2p ie from
265  * probe response
266  * @tx_ctx:      tx context
267  *
268  * This function finds out p2p ie and return the pointer if it is a
269  * probe response frame.
270  *
271  * Return: pointer to p2p ie
272  */
p2p_get_p2pie_from_probe_rsp(struct tx_action_context * tx_ctx)273 static const uint8_t *p2p_get_p2pie_from_probe_rsp(
274 	struct tx_action_context *tx_ctx)
275 {
276 	const uint8_t *ie;
277 	const uint8_t *p2p_ie;
278 	const uint8_t *tmp_p2p_ie = NULL;
279 	uint16_t ie_len;
280 
281 	if (tx_ctx->buf_len <= PROBE_RSP_IE_OFFSET) {
282 		p2p_err("Invalid header len for probe response");
283 		return NULL;
284 	}
285 
286 	ie = tx_ctx->buf + PROBE_RSP_IE_OFFSET;
287 	ie_len = tx_ctx->buf_len - PROBE_RSP_IE_OFFSET;
288 	p2p_ie = p2p_get_p2pie_ptr(ie, ie_len);
289 	while ((p2p_ie) &&
290 		(WLAN_MAX_IE_LEN == p2p_ie[1])) {
291 		ie_len = tx_ctx->buf_len - (p2p_ie - tx_ctx->buf);
292 		if (ie_len > 2) {
293 			ie = p2p_ie + WLAN_MAX_IE_LEN + 2;
294 			tmp_p2p_ie = p2p_get_p2pie_ptr(ie, ie_len);
295 		}
296 
297 		if (tmp_p2p_ie) {
298 			p2p_ie = tmp_p2p_ie;
299 			tmp_p2p_ie = NULL;
300 		} else {
301 			break;
302 		}
303 	}
304 
305 	return p2p_ie;
306 }
307 
308 /**
309  * p2p_get_presence_noa_attr() - get the pointer to noa attr
310  * @pies:      source ie
311  * @length:    source ie length
312  *
313  * This function finds out noa attr by noa eid and return the pointer.
314  *
315  * Return: pointer to noa attr
316  */
p2p_get_presence_noa_attr(const uint8_t * pies,int length)317 static const uint8_t *p2p_get_presence_noa_attr(const uint8_t *pies, int length)
318 {
319 	int left = length;
320 	const uint8_t *ptr = pies;
321 	uint8_t elem_id;
322 	uint16_t elem_len;
323 
324 	p2p_debug("pies:%pK, length:%d", pies, length);
325 
326 	while (left >= 3) {
327 		elem_id = ptr[0];
328 		elem_len = ((uint16_t) ptr[1]) | (ptr[2] << 8);
329 
330 		left -= 3;
331 		if (elem_len > left) {
332 			p2p_err("****Invalid IEs, elem_len=%d left=%d*****",
333 				elem_len, left);
334 			return NULL;
335 		}
336 		if (elem_id == P2P_NOA_ATTR)
337 			return ptr;
338 
339 		left -= elem_len;
340 		ptr += (elem_len + 3);
341 	}
342 
343 	return NULL;
344 }
345 
346 /**
347  * p2p_get_noa_attr_stream_in_mult_p2p_ies() - get the pointer to noa
348  * attr from multi p2p ie
349  * @noa_stream:      noa stream
350  * @noa_len:         noa stream length
351  * @overflow_len:    overflow length
352  *
353  * This function finds out noa attr from multi p2p ies.
354  *
355  * Return: noa length
356  */
p2p_get_noa_attr_stream_in_mult_p2p_ies(uint8_t * noa_stream,uint8_t noa_len,uint8_t overflow_len)357 static uint8_t p2p_get_noa_attr_stream_in_mult_p2p_ies(uint8_t *noa_stream,
358 	uint8_t noa_len, uint8_t overflow_len)
359 {
360 	uint8_t overflow_p2p_stream[P2P_MAX_NOA_ATTR_LEN];
361 
362 	p2p_debug("noa_stream:%pK, noa_len:%d, overflow_len:%d",
363 		noa_stream, noa_len, overflow_len);
364 	if ((noa_len <= (P2P_MAX_NOA_ATTR_LEN + P2P_IE_HEADER_LEN)) &&
365 	    (noa_len >= overflow_len) &&
366 	    (overflow_len <= P2P_MAX_NOA_ATTR_LEN)) {
367 		qdf_mem_copy(overflow_p2p_stream,
368 			     noa_stream + noa_len - overflow_len,
369 			     overflow_len);
370 		noa_stream[noa_len - overflow_len] =
371 			P2P_EID_VENDOR;
372 		noa_stream[noa_len - overflow_len + 1] =
373 			overflow_len + P2P_OUI_SIZE;
374 		qdf_mem_copy(noa_stream + noa_len - overflow_len + 2,
375 			P2P_OUI, P2P_OUI_SIZE);
376 		qdf_mem_copy(noa_stream + noa_len + 2 + P2P_OUI_SIZE -
377 			overflow_len, overflow_p2p_stream,
378 			overflow_len);
379 	}
380 
381 	return noa_len + P2P_IE_HEADER_LEN;
382 }
383 
384 /**
385  * p2p_get_vdev_noa_info() - get vdev noa information
386  * @tx_ctx:         tx context
387  *
388  * This function gets vdev noa information
389  *
390  * Return: pointer to noa information
391  */
p2p_get_vdev_noa_info(struct tx_action_context * tx_ctx)392 static struct p2p_noa_info *p2p_get_vdev_noa_info(
393 	struct tx_action_context *tx_ctx)
394 {
395 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
396 	struct p2p_soc_priv_obj *p2p_soc_obj;
397 	struct wlan_objmgr_vdev *vdev;
398 	struct wlan_objmgr_psoc *psoc;
399 	enum QDF_OPMODE mode;
400 	struct p2p_noa_info *noa_info = NULL;
401 
402 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
403 	psoc = p2p_soc_obj->soc;
404 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
405 			tx_ctx->vdev_id, WLAN_P2P_ID);
406 	if (!vdev) {
407 		p2p_err("vdev obj is NULL");
408 		return NULL;
409 	}
410 
411 	mode = wlan_vdev_mlme_get_opmode(vdev);
412 	p2p_debug("vdev mode:%d", mode);
413 	if (mode != QDF_P2P_GO_MODE) {
414 		p2p_debug("invalid p2p vdev mode:%d", mode);
415 		goto fail;
416 	}
417 
418 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
419 			WLAN_UMAC_COMP_P2P);
420 
421 	if (!p2p_vdev_obj || !(p2p_vdev_obj->noa_info)) {
422 		p2p_debug("null noa info");
423 		goto fail;
424 	}
425 
426 	noa_info = p2p_vdev_obj->noa_info;
427 
428 fail:
429 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
430 
431 	return noa_info;
432 }
433 
434 /**
435  * p2p_get_noa_attr_stream() - get noa stream from p2p vdev object
436  * @tx_ctx:         tx context
437  * @pnoa_stream:    pointer to noa stream
438  *
439  * This function finds out noa stream from p2p vdev object
440  *
441  * Return: noa stream length
442  */
p2p_get_noa_attr_stream(struct tx_action_context * tx_ctx,uint8_t * pnoa_stream)443 static uint8_t p2p_get_noa_attr_stream(
444 	struct tx_action_context *tx_ctx, uint8_t *pnoa_stream)
445 {
446 	struct p2p_noa_info *noa_info;
447 	struct noa_descriptor *noa_desc_0;
448 	struct noa_descriptor *noa_desc_1;
449 	uint8_t *pbody = pnoa_stream;
450 	uint8_t len = 0;
451 
452 	noa_info = p2p_get_vdev_noa_info(tx_ctx);
453 	if (!noa_info) {
454 		p2p_debug("not valid noa information");
455 		return 0;
456 	}
457 
458 	noa_desc_0 = &(noa_info->noa_desc[0]);
459 	noa_desc_1 = &(noa_info->noa_desc[1]);
460 	if ((!(noa_desc_0->duration)) &&
461 		(!(noa_desc_1->duration)) &&
462 		(!noa_info->opps_ps)) {
463 		p2p_debug("opps ps and duration are 0");
464 		return 0;
465 	}
466 
467 	pbody[0] = P2P_NOA_ATTR;
468 	pbody[3] = noa_info->index;
469 	pbody[4] = noa_info->ct_window | (noa_info->opps_ps << 7);
470 	len = 5;
471 	pbody += len;
472 
473 	if (noa_desc_0->duration) {
474 		*pbody = noa_desc_0->type_count;
475 		pbody += 1;
476 		len += 1;
477 
478 		*((uint32_t *) (pbody)) = noa_desc_0->duration;
479 		pbody += sizeof(uint32_t);
480 		len += 4;
481 
482 		*((uint32_t *) (pbody)) = noa_desc_0->interval;
483 		pbody += sizeof(uint32_t);
484 		len += 4;
485 
486 		*((uint32_t *) (pbody)) = noa_desc_0->start_time;
487 		pbody += sizeof(uint32_t);
488 		len += 4;
489 	}
490 
491 	if (noa_desc_1->duration) {
492 		*pbody = noa_desc_1->type_count;
493 		pbody += 1;
494 		len += 1;
495 
496 		*((uint32_t *) (pbody)) = noa_desc_1->duration;
497 		pbody += sizeof(uint32_t);
498 		len += 4;
499 
500 		*((uint32_t *) (pbody)) = noa_desc_1->interval;
501 		pbody += sizeof(uint32_t);
502 		len += 4;
503 
504 		*((uint32_t *) (pbody)) = noa_desc_1->start_time;
505 		pbody += sizeof(uint32_t);
506 		len += 4;
507 	}
508 
509 	pbody = pnoa_stream + 1;
510 	 /* one byte for Attr and 2 bytes for length */
511 	*((uint16_t *) (pbody)) = len - 3;
512 
513 	return len;
514 }
515 
516 /**
517  * p2p_update_noa_stream() - update noa stream
518  * @tx_ctx:       tx context
519  * @p2p_ie:       pointer to p2p ie
520  * @noa_attr:     pointer to noa attr
521  * @total_len:    pointer to total length of ie
522  * @noa_stream:   noa stream
523  *
524  * This function updates noa stream.
525  *
526  * Return: noa stream length
527  */
p2p_update_noa_stream(struct tx_action_context * tx_ctx,uint8_t * p2p_ie,const uint8_t * noa_attr,uint32_t * total_len,uint8_t * noa_stream)528 static uint16_t p2p_update_noa_stream(struct tx_action_context *tx_ctx,
529 	uint8_t *p2p_ie, const uint8_t *noa_attr, uint32_t *total_len,
530 	uint8_t *noa_stream)
531 {
532 	uint16_t noa_len;
533 	uint16_t overflow_len;
534 	uint8_t orig_len;
535 	uint32_t nbytes_copy;
536 	uint32_t buf_len = *total_len;
537 
538 	noa_len = p2p_get_noa_attr_stream(tx_ctx, noa_stream);
539 	if (noa_len <= 0) {
540 		p2p_debug("do not find out noa attr");
541 		return 0;
542 	}
543 
544 	orig_len = p2p_ie[1];
545 	if (noa_attr) {
546 		noa_len = noa_attr[1] | (noa_attr[2] << 8);
547 		orig_len -= (noa_len + 1 + 2);
548 		buf_len -= (noa_len + 1 + 2);
549 		p2p_ie[1] = orig_len;
550 	}
551 
552 	if ((p2p_ie[1] + noa_len) > WLAN_MAX_IE_LEN) {
553 		overflow_len = p2p_ie[1] + noa_len -
554 				WLAN_MAX_IE_LEN;
555 		noa_len = p2p_get_noa_attr_stream_in_mult_p2p_ies(
556 				noa_stream, noa_len, overflow_len);
557 		p2p_ie[1] = WLAN_MAX_IE_LEN;
558 	} else {
559 		/* increment the length of P2P IE */
560 		p2p_ie[1] += noa_len;
561 	}
562 
563 	*total_len = buf_len;
564 	nbytes_copy = (p2p_ie + orig_len + 2) - tx_ctx->buf;
565 
566 	p2p_debug("noa_len=%d orig_len=%d p2p_ie=%pK buf_len=%d nbytes copy=%d ",
567 		noa_len, orig_len, p2p_ie, buf_len, nbytes_copy);
568 
569 	return noa_len;
570 }
571 
572 /**
573  * p2p_set_ht_caps() - set ht capability
574  * @tx_ctx:         tx context
575  * @num_bytes:      number bytes
576  *
577  * This function sets ht capability
578  *
579  * Return: None
580  */
p2p_set_ht_caps(struct tx_action_context * tx_ctx,uint32_t num_bytes)581 static void p2p_set_ht_caps(struct tx_action_context *tx_ctx,
582 	uint32_t num_bytes)
583 {
584 }
585 
586 /**
587  * p2p_get_next_seq_num() - get next sequence number to fill mac header
588  * @peer:   PEER object
589  * @tx_ctx: tx context
590  * @ta : transmitter address
591  *
592  * API to get next sequence number of action frame for the peer.
593  *
594  * Return: Next sequence number of the peer
595  */
p2p_get_next_seq_num(struct wlan_objmgr_peer * peer,struct tx_action_context * tx_ctx,uint8_t * ta)596 static uint16_t p2p_get_next_seq_num(struct wlan_objmgr_peer *peer,
597 				     struct tx_action_context *tx_ctx,
598 				     uint8_t *ta)
599 {
600 	uint16_t random_num, random_num_bitmask = 0x03FF;
601 	uint16_t seq_num, seq_num_bitmask = 0x0FFF;
602 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
603 	struct wlan_objmgr_vdev *vdev;
604 	bool is_new_random_ta;
605 
606 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(tx_ctx->p2p_soc_obj->soc,
607 						    tx_ctx->vdev_id,
608 						    WLAN_P2P_ID);
609 	if (!vdev) {
610 		p2p_debug("vdev is null");
611 		return false;
612 	}
613 
614 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
615 						vdev, WLAN_UMAC_COMP_P2P);
616 	if (!p2p_vdev_obj) {
617 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
618 		p2p_debug("p2p vdev object is NULL");
619 		return false;
620 	}
621 
622 	is_new_random_ta = qdf_mem_cmp(p2p_vdev_obj->prev_action_frame_addr2,
623 				       ta, QDF_MAC_ADDR_SIZE);
624 	if (is_new_random_ta &&
625 	    tx_ctx->p2p_soc_obj->param.is_random_seq_num_enabled) {
626 		/**
627 		 * Increment the previous sequence number with 10-bits
628 		 * random number to get the next sequence number.
629 		 */
630 
631 		qdf_get_random_bytes(&random_num, sizeof(random_num));
632 		random_num &= random_num_bitmask;
633 		seq_num = (peer->peer_mlme.seq_num + random_num) &
634 			  seq_num_bitmask;
635 		peer->peer_mlme.seq_num = seq_num;
636 
637 		qdf_mem_copy(p2p_vdev_obj->prev_action_frame_addr2, ta,
638 			     QDF_MAC_ADDR_SIZE);
639 
640 	} else {
641 		seq_num = wlan_peer_mlme_get_next_seq_num(peer);
642 	}
643 
644 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
645 
646 	return seq_num;
647 }
648 
649 /**
650  * p2p_populate_mac_header() - update sequence number
651  * @tx_ctx:      tx context
652  *
653  * This function updates sequence number of this mgmt frame
654  *
655  * Return: QDF_STATUS_SUCCESS - in case of success
656  */
p2p_populate_mac_header(struct tx_action_context * tx_ctx)657 static QDF_STATUS p2p_populate_mac_header(
658 	struct tx_action_context *tx_ctx)
659 {
660 	struct wlan_seq_ctl *seq_ctl;
661 	struct wlan_frame_hdr *wh;
662 	struct wlan_objmgr_peer *peer;
663 	struct wlan_objmgr_psoc *psoc;
664 	void *mac_addr;
665 	uint16_t seq_num;
666 	uint8_t pdev_id;
667 	struct wlan_objmgr_vdev *vdev;
668 	enum QDF_OPMODE opmode;
669 
670 	psoc = tx_ctx->p2p_soc_obj->soc;
671 
672 	wh = (struct wlan_frame_hdr *)tx_ctx->buf;
673 	/*
674 	 * Remove the WEP bit if already set, p2p_populate_rmf_field will set it
675 	 * if required.
676 	 */
677 	wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
678 	mac_addr = wh->i_addr1;
679 	pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, tx_ctx->vdev_id,
680 						WLAN_P2P_ID);
681 	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_P2P_ID);
682 	if (!peer) {
683 		mac_addr = wh->i_addr2;
684 		peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
685 					    WLAN_P2P_ID);
686 	}
687 	if (!peer) {
688 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
689 							    tx_ctx->vdev_id,
690 							    WLAN_P2P_ID);
691 		if (vdev) {
692 			opmode = wlan_vdev_mlme_get_opmode(vdev);
693 			/*
694 			 * For NAN iface, retrieves mac address from vdev
695 			 * as it is self peer. Also, rand_mac_tx would be
696 			 * false as tx channel is not available.
697 			 */
698 			if (opmode == QDF_NAN_DISC_MODE ||
699 			    tx_ctx->rand_mac_tx) {
700 				mac_addr = wlan_vdev_mlme_get_macaddr(vdev);
701 				peer = wlan_objmgr_get_peer(psoc, pdev_id,
702 							    mac_addr,
703 							    WLAN_P2P_ID);
704 			}
705 
706 			wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
707 		}
708 	}
709 	if (!peer) {
710 		p2p_err("no valid peer");
711 		return QDF_STATUS_E_INVAL;
712 	}
713 	seq_num = (uint16_t)p2p_get_next_seq_num(peer, tx_ctx, wh->i_addr2);
714 	seq_ctl = (struct wlan_seq_ctl *)(tx_ctx->buf +
715 			WLAN_SEQ_CTL_OFFSET);
716 	seq_ctl->seq_num_lo = (seq_num & WLAN_LOW_SEQ_NUM_MASK);
717 	seq_ctl->seq_num_hi = ((seq_num & WLAN_HIGH_SEQ_NUM_MASK) >>
718 				WLAN_HIGH_SEQ_NUM_OFFSET);
719 	p2p_debug("seq num: %d", seq_num);
720 
721 	wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID);
722 
723 	return QDF_STATUS_SUCCESS;
724 }
725 
726 /**
727  * p2p_get_frame_type_str() - parse frame type to string
728  * @frame_info: frame information
729  *
730  * This function parse frame type to string.
731  *
732  * Return: command string
733  */
p2p_get_frame_type_str(struct p2p_frame_info * frame_info)734 static char *p2p_get_frame_type_str(struct p2p_frame_info *frame_info)
735 {
736 	if (frame_info->type == P2P_FRAME_NOT_SUPPORT)
737 		return "Not support frame";
738 
739 	if (frame_info->sub_type == P2P_MGMT_NOT_SUPPORT)
740 		return "Not support sub frame";
741 
742 	if (frame_info->action_type == P2P_ACTION_PRESENCE_REQ)
743 		return "P2P action presence request";
744 	if (frame_info->action_type == P2P_ACTION_PRESENCE_RSP)
745 		return "P2P action presence response";
746 
747 	switch (frame_info->public_action_type) {
748 	case P2P_PUBLIC_ACTION_NEG_REQ:
749 		return "GO negotiation request frame";
750 	case P2P_PUBLIC_ACTION_NEG_RSP:
751 		return "GO negotiation response frame";
752 	case P2P_PUBLIC_ACTION_NEG_CNF:
753 		return "GO negotiation confirm frame";
754 	case P2P_PUBLIC_ACTION_INVIT_REQ:
755 		return "P2P invitation request";
756 	case P2P_PUBLIC_ACTION_INVIT_RSP:
757 		return "P2P invitation response";
758 	case P2P_PUBLIC_ACTION_DEV_DIS_REQ:
759 		return "Device discoverability request";
760 	case P2P_PUBLIC_ACTION_DEV_DIS_RSP:
761 		return "Device discoverability response";
762 	case P2P_PUBLIC_ACTION_PROV_DIS_REQ:
763 		return "Provision discovery request";
764 	case P2P_PUBLIC_ACTION_PROV_DIS_RSP:
765 		return "Provision discovery response";
766 	case P2P_PUBLIC_ACTION_GAS_INIT_REQ:
767 		return "GAS init request";
768 	case P2P_PUBLIC_ACTION_GAS_INIT_RSP:
769 		return "GAS init response";
770 	case P2P_PUBLIC_ACTION_GAS_COMB_REQ:
771 		return "GAS come back request";
772 	case P2P_PUBLIC_ACTION_GAS_COMB_RSP:
773 		return "GAS come back response";
774 	case P2P_PUBLIC_ACTION_WNM_BTM_REQ:
775 		return "BTM request";
776 	case P2P_PUBLIC_ACTION_RRM_BEACON_REQ:
777 		return "BEACON request";
778 	case P2P_PUBLIC_ACTION_RRM_NEIGHBOR_RSP:
779 		return "NEIGHBOR response";
780 	default:
781 		return "Other frame";
782 	}
783 }
784 
785 /**
786  * p2p_init_frame_info() - init frame information structure
787  * @frame_info:     pointer to frame information
788  *
789  * This function init frame information structure.
790  *
791  * Return: None
792  */
p2p_init_frame_info(struct p2p_frame_info * frame_info)793 static void p2p_init_frame_info(struct p2p_frame_info *frame_info)
794 {
795 	frame_info->type = P2P_FRAME_NOT_SUPPORT;
796 	frame_info->sub_type = P2P_MGMT_NOT_SUPPORT;
797 	frame_info->public_action_type =
798 				P2P_PUBLIC_ACTION_NOT_SUPPORT;
799 	frame_info->action_type = P2P_ACTION_NOT_SUPPORT;
800 }
801 
802 /**
803  * p2p_get_frame_info() - get frame information from packet
804  * @data_buf:          data buffer address
805  * @length:            buffer length
806  * @frame_info:        frame information
807  *
808  * This function gets frame information from packet.
809  *
810  * Return: QDF_STATUS_SUCCESS - in case of success
811  */
p2p_get_frame_info(uint8_t * data_buf,uint32_t length,struct p2p_frame_info * frame_info)812 QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length,
813 			      struct p2p_frame_info *frame_info)
814 {
815 	uint8_t type;
816 	uint8_t sub_type;
817 	uint8_t action_type;
818 	uint8_t *buf = data_buf;
819 
820 	p2p_init_frame_info(frame_info);
821 
822 	if (length < P2P_ACTION_OFFSET + 1) {
823 		p2p_err("invalid p2p mgmt hdr len");
824 		return QDF_STATUS_E_INVAL;
825 	}
826 
827 	type = P2P_GET_TYPE_FRM_FC(buf[0]);
828 	sub_type = P2P_GET_SUBTYPE_FRM_FC(buf[0]);
829 	if (type != P2P_FRAME_MGMT) {
830 		p2p_err("just support mgmt frame");
831 		return QDF_STATUS_E_FAILURE;
832 	}
833 
834 	frame_info->type = type;
835 	frame_info->sub_type = sub_type;
836 
837 	if (sub_type != P2P_MGMT_ACTION)
838 		return QDF_STATUS_SUCCESS;
839 
840 	buf += P2P_ACTION_OFFSET;
841 	if (length > P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET) {
842 		switch (buf[0]) {
843 		case P2P_PUBLIC_ACTION_FRAME:
844 			if (buf[1] == P2P_PUBLIC_ACTION_VENDOR_SPECIFIC &&
845 			    !qdf_mem_cmp(&buf[2], P2P_OUI, P2P_OUI_SIZE)) {
846 				buf = data_buf +
847 					P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET;
848 				action_type = buf[0];
849 				if (action_type > P2P_PUBLIC_ACTION_PROV_DIS_RSP)
850 					frame_info->public_action_type =
851 						P2P_PUBLIC_ACTION_NOT_SUPPORT;
852 				else
853 					frame_info->public_action_type =
854 						action_type;
855 			}
856 			break;
857 		case WNM_ACTION_FRAME:
858 			if (buf[1] == WNM_BSS_TM_REQUEST) {
859 				action_type = buf[0];
860 				frame_info->public_action_type =
861 					P2P_PUBLIC_ACTION_WNM_BTM_REQ;
862 			}
863 			break;
864 		case RRM_ACTION_FRAME:
865 			if (buf[1] == RRM_RADIO_MEASURE_REQ) {
866 				action_type = buf[0];
867 				frame_info->public_action_type =
868 					P2P_PUBLIC_ACTION_RRM_BEACON_REQ;
869 			} else if (buf[1] == RRM_NEIGHBOR_RPT) {
870 				action_type = buf[0];
871 				frame_info->public_action_type =
872 					P2P_PUBLIC_ACTION_RRM_NEIGHBOR_RSP;
873 			}
874 			break;
875 		default:
876 			break;
877 		}
878 	} else if (length > P2P_ACTION_FRAME_TYPE_OFFSET &&
879 		   buf[0] == P2P_ACTION_VENDOR_SPECIFIC_CATEGORY &&
880 		   !qdf_mem_cmp(&buf[1], P2P_OUI, P2P_OUI_SIZE)) {
881 		buf = data_buf +
882 			P2P_ACTION_FRAME_TYPE_OFFSET;
883 		action_type = buf[0];
884 		if (action_type == P2P_ACTION_PRESENCE_REQ)
885 			frame_info->action_type =
886 				P2P_ACTION_PRESENCE_REQ;
887 		if (action_type == P2P_ACTION_PRESENCE_RSP)
888 			frame_info->action_type =
889 				P2P_ACTION_PRESENCE_RSP;
890 	} else {
891 		p2p_debug("this is not vendor specific p2p action frame");
892 		return QDF_STATUS_SUCCESS;
893 	}
894 
895 	p2p_debug("%s", p2p_get_frame_type_str(frame_info));
896 
897 	return QDF_STATUS_SUCCESS;
898 }
899 
p2p_is_action_frame_of_p2p_type(uint8_t * data_buf,uint32_t length)900 bool p2p_is_action_frame_of_p2p_type(uint8_t *data_buf, uint32_t length)
901 {
902 	struct p2p_frame_info frame_info = {0};
903 	QDF_STATUS status;
904 
905 	status = p2p_get_frame_info(data_buf, length, &frame_info);
906 	if (QDF_IS_STATUS_ERROR(status))
907 		return false;
908 
909 	if (frame_info.public_action_type != P2P_PUBLIC_ACTION_NOT_SUPPORT ||
910 	    frame_info.action_type != P2P_ACTION_NOT_SUPPORT)
911 		return true;
912 
913 	return false;
914 }
915 
916 #ifdef WLAN_FEATURE_P2P_DEBUG
917 /**
918  * p2p_tx_update_connection_status() - Update P2P connection status
919  * with tx frame
920  * @p2p_soc_obj:        P2P soc private object
921  * @tx_frame_info:      frame information
922  * @mac_to:              Pointer to dest MAC address
923  *
924  * This function updates P2P connection status with tx frame.
925  *
926  * Return: QDF_STATUS_SUCCESS - in case of success
927  */
p2p_tx_update_connection_status(struct p2p_soc_priv_obj * p2p_soc_obj,struct p2p_frame_info * tx_frame_info,uint8_t * mac_to)928 static QDF_STATUS p2p_tx_update_connection_status(
929 	struct p2p_soc_priv_obj *p2p_soc_obj,
930 	struct p2p_frame_info *tx_frame_info,
931 	uint8_t *mac_to)
932 {
933 	if (!p2p_soc_obj || !tx_frame_info || !mac_to) {
934 		p2p_err("invalid p2p_soc_obj:%pK or tx_frame_info:%pK or mac_to:%pK",
935 			p2p_soc_obj, tx_frame_info, mac_to);
936 		return QDF_STATUS_E_INVAL;
937 	}
938 
939 	if (tx_frame_info->public_action_type !=
940 		P2P_PUBLIC_ACTION_NOT_SUPPORT)
941 		p2p_debug("%s ---> OTA to " QDF_MAC_ADDR_FMT,
942 			  p2p_get_frame_type_str(tx_frame_info),
943 			  QDF_MAC_ADDR_REF(mac_to));
944 
945 	if ((tx_frame_info->public_action_type ==
946 	     P2P_PUBLIC_ACTION_PROV_DIS_REQ) ||
947 	    (tx_frame_info->public_action_type ==
948 	     P2P_PUBLIC_ACTION_INVIT_REQ) ||
949 	    (tx_frame_info->public_action_type ==
950 	     P2P_PUBLIC_ACTION_NEG_REQ) ||
951 	     (tx_frame_info->public_action_type ==
952 	     P2P_PUBLIC_ACTION_NEG_RSP)) {
953 		p2p_status_update(p2p_soc_obj, P2P_GO_NEG_PROCESS);
954 		p2p_debug("[P2P State]Inactive state to GO negotiation progress state");
955 	} else if ((tx_frame_info->public_action_type ==
956 		    P2P_PUBLIC_ACTION_NEG_CNF) ||
957 		   (tx_frame_info->public_action_type ==
958 		    P2P_PUBLIC_ACTION_INVIT_RSP)) {
959 		p2p_status_update(p2p_soc_obj, P2P_GO_NEG_COMPLETED);
960 		p2p_debug("[P2P State]GO nego progress to GO nego completed state");
961 	}
962 
963 	return QDF_STATUS_SUCCESS;
964 }
965 
966 /**
967  * p2p_rx_update_connection_status() - Update P2P connection status
968  * with rx frame
969  * @p2p_soc_obj:        P2P soc private object
970  * @rx_frame_info:      frame information
971  * @mac_from:            Pointer to source MAC address
972  *
973  * This function updates P2P connection status with rx frame.
974  *
975  * Return: QDF_STATUS_SUCCESS - in case of success
976  */
p2p_rx_update_connection_status(struct p2p_soc_priv_obj * p2p_soc_obj,struct p2p_frame_info * rx_frame_info,uint8_t * mac_from)977 static QDF_STATUS p2p_rx_update_connection_status(
978 	struct p2p_soc_priv_obj *p2p_soc_obj,
979 	struct p2p_frame_info *rx_frame_info,
980 	uint8_t *mac_from)
981 {
982 	if (!p2p_soc_obj || !rx_frame_info || !mac_from) {
983 		p2p_err("invalid p2p_soc_obj:%pK or rx_frame_info:%pK, mac_from:%pK",
984 			p2p_soc_obj, rx_frame_info, mac_from);
985 		return QDF_STATUS_E_INVAL;
986 	}
987 
988 	if (rx_frame_info->public_action_type !=
989 		P2P_PUBLIC_ACTION_NOT_SUPPORT)
990 		p2p_info_rl("%s <--- OTA from " QDF_MAC_ADDR_FMT,
991 			    p2p_get_frame_type_str(rx_frame_info),
992 			    QDF_MAC_ADDR_REF(mac_from));
993 
994 	if ((rx_frame_info->public_action_type ==
995 			P2P_PUBLIC_ACTION_PROV_DIS_REQ) ||
996 	    (rx_frame_info->public_action_type ==
997 			P2P_PUBLIC_ACTION_NEG_REQ) ||
998 	    (rx_frame_info->public_action_type ==
999 			P2P_PUBLIC_ACTION_NEG_RSP)) {
1000 		p2p_status_update(p2p_soc_obj, P2P_GO_NEG_PROCESS);
1001 		p2p_info_rl("[P2P State]Inactive state to GO negotiation progress state");
1002 	} else if (((rx_frame_info->public_action_type ==
1003 		     P2P_PUBLIC_ACTION_NEG_CNF) ||
1004 		   (rx_frame_info->public_action_type ==
1005 		     P2P_PUBLIC_ACTION_INVIT_RSP)) &&
1006 		   (p2p_soc_obj->connection_status ==
1007 		    P2P_GO_NEG_PROCESS)) {
1008 		p2p_status_update(p2p_soc_obj, P2P_GO_NEG_COMPLETED);
1009 		p2p_info_rl("[P2P State]GO negotiation progress to GO negotiation completed state");
1010 	} else if ((rx_frame_info->public_action_type ==
1011 		    P2P_PUBLIC_ACTION_INVIT_REQ) &&
1012 		   (p2p_soc_obj->connection_status == P2P_NOT_ACTIVE)) {
1013 		p2p_status_update(p2p_soc_obj, P2P_GO_NEG_COMPLETED);
1014 		p2p_info_rl("[P2P State]Inactive state to GO negotiation completed state Autonomous GO formation");
1015 	}
1016 
1017 	return QDF_STATUS_SUCCESS;
1018 }
1019 #else
p2p_tx_update_connection_status(struct p2p_soc_priv_obj * p2p_soc_obj,struct p2p_frame_info * tx_frame_info,uint8_t * mac_to)1020 static QDF_STATUS p2p_tx_update_connection_status(
1021 	struct p2p_soc_priv_obj *p2p_soc_obj,
1022 	struct p2p_frame_info *tx_frame_info,
1023 	uint8_t *mac_to)
1024 {
1025 	return QDF_STATUS_SUCCESS;
1026 }
1027 
p2p_rx_update_connection_status(struct p2p_soc_priv_obj * p2p_soc_obj,struct p2p_frame_info * rx_frame_info,uint8_t * mac_from)1028 static QDF_STATUS p2p_rx_update_connection_status(
1029 	struct p2p_soc_priv_obj *p2p_soc_obj,
1030 	struct p2p_frame_info *rx_frame_info,
1031 	uint8_t *mac_from)
1032 {
1033 	return QDF_STATUS_SUCCESS;
1034 }
1035 #endif
1036 
1037 /**
1038  * p2p_packet_alloc() - allocate qdf nbuf
1039  * @size:         buffe size
1040  * @data:         pointer to qdf nbuf data point
1041  * @ppPacket:     pointer to qdf nbuf point
1042  *
1043  * This function allocates qdf nbuf.
1044  *
1045  * Return: QDF_STATUS_SUCCESS - in case of success
1046  */
p2p_packet_alloc(uint16_t size,void ** data,qdf_nbuf_t * ppPacket)1047 static QDF_STATUS p2p_packet_alloc(uint16_t size, void **data,
1048 	qdf_nbuf_t *ppPacket)
1049 {
1050 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1051 	qdf_nbuf_t nbuf;
1052 
1053 	nbuf = qdf_nbuf_alloc(NULL,
1054 			roundup(size + P2P_TX_PKT_MIN_HEADROOM, 4),
1055 			P2P_TX_PKT_MIN_HEADROOM, sizeof(uint32_t),
1056 			false);
1057 
1058 	if (nbuf) {
1059 		qdf_nbuf_put_tail(nbuf, size);
1060 		qdf_nbuf_set_protocol(nbuf, ETH_P_CONTROL);
1061 		*ppPacket = nbuf;
1062 		*data = qdf_nbuf_data(nbuf);
1063 		qdf_mem_zero(*data, size);
1064 		status = QDF_STATUS_SUCCESS;
1065 	}
1066 
1067 	return status;
1068 }
1069 
1070 /**
1071  * p2p_send_tx_conf() - send tx confirm
1072  * @tx_ctx:        tx context
1073  * @status:        tx status
1074  *
1075  * This function send tx confirm to osif
1076  *
1077  * Return: QDF_STATUS_SUCCESS - pointer to tx context
1078  */
p2p_send_tx_conf(struct tx_action_context * tx_ctx,bool status)1079 static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx,
1080 	bool status)
1081 {
1082 	struct p2p_tx_cnf tx_cnf;
1083 	struct p2p_soc_priv_obj *p2p_soc_obj;
1084 	struct p2p_start_param *start_param;
1085 
1086 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
1087 
1088 	if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) {
1089 		p2p_err("Invalid p2p soc object or start parameters");
1090 		return QDF_STATUS_E_INVAL;
1091 	}
1092 
1093 	start_param = p2p_soc_obj->start_param;
1094 	if (!(start_param->tx_cnf_cb)) {
1095 		p2p_err("no tx confirm callback");
1096 		return QDF_STATUS_E_INVAL;
1097 	}
1098 
1099 	if (tx_ctx->no_ack)
1100 		tx_cnf.action_cookie = 0;
1101 	else
1102 		tx_cnf.action_cookie = (uint64_t)tx_ctx->id;
1103 
1104 	tx_cnf.vdev_id = tx_ctx->vdev_id;
1105 	tx_cnf.buf = tx_ctx->buf;
1106 	tx_cnf.buf_len = tx_ctx->buf_len;
1107 	tx_cnf.status = status ? 0 : 1;
1108 
1109 	p2p_debug("soc:%pK, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%pK",
1110 		p2p_soc_obj->soc, tx_cnf.vdev_id,
1111 		tx_cnf.action_cookie, tx_cnf.buf_len,
1112 		tx_cnf.status, tx_cnf.buf);
1113 
1114 	p2p_rand_mac_tx_done(p2p_soc_obj->soc, tx_ctx);
1115 
1116 	start_param->tx_cnf_cb(start_param->tx_cnf_cb_data, &tx_cnf);
1117 
1118 	return QDF_STATUS_SUCCESS;
1119 }
1120 
1121 /**
1122  * p2p_get_hw_retry_count() - Get hw tx retry count from config store
1123  * @psoc:          psoc object
1124  * @tx_ctx:        tx context
1125  *
1126  * This function return the hw tx retry count for p2p action frame.
1127  * 0 value means target will use fw default mgmt tx retry count 15.
1128  *
1129  * Return: frame hw tx retry count
1130  */
p2p_get_hw_retry_count(struct wlan_objmgr_psoc * psoc,struct tx_action_context * tx_ctx)1131 static uint8_t p2p_get_hw_retry_count(struct wlan_objmgr_psoc *psoc,
1132 				      struct tx_action_context *tx_ctx)
1133 {
1134 	if (tx_ctx->frame_info.type != P2P_FRAME_MGMT)
1135 		return 0;
1136 
1137 	if (tx_ctx->frame_info.sub_type != P2P_MGMT_ACTION)
1138 		return 0;
1139 
1140 	switch (tx_ctx->frame_info.public_action_type) {
1141 	case P2P_PUBLIC_ACTION_NEG_REQ:
1142 		return wlan_mlme_get_mgmt_hw_tx_retry_count(
1143 					psoc,
1144 					CFG_GO_NEGOTIATION_REQ_FRAME_TYPE);
1145 	case P2P_PUBLIC_ACTION_INVIT_REQ:
1146 		return wlan_mlme_get_mgmt_hw_tx_retry_count(
1147 					psoc,
1148 					CFG_P2P_INVITATION_REQ_FRAME_TYPE);
1149 	case P2P_PUBLIC_ACTION_PROV_DIS_REQ:
1150 		return wlan_mlme_get_mgmt_hw_tx_retry_count(
1151 					psoc,
1152 					CFG_PROVISION_DISCOVERY_REQ_FRAME_TYPE);
1153 	default:
1154 		return 0;
1155 	}
1156 }
1157 
1158 #define GET_HW_RETRY_LIMIT(count) QDF_GET_BITS(count, 0, 4)
1159 #define GET_HW_RETRY_LIMIT_EXT(count) QDF_GET_BITS(count, 4, 3)
1160 
1161 /**
1162  * p2p_mgmt_set_hw_retry_count() - Set mgmt hw tx retry count
1163  * @psoc:          psoc object
1164  * @tx_ctx:        tx context
1165  * @mgmt_param:    mgmt frame tx parameter
1166  *
1167  * This function will set mgmt frame hw tx retry count to tx parameter
1168  *
1169  * Return: void
1170  */
1171 static void
p2p_mgmt_set_hw_retry_count(struct wlan_objmgr_psoc * psoc,struct tx_action_context * tx_ctx,struct wmi_mgmt_params * mgmt_param)1172 p2p_mgmt_set_hw_retry_count(struct wlan_objmgr_psoc *psoc,
1173 			    struct tx_action_context *tx_ctx,
1174 			    struct wmi_mgmt_params *mgmt_param)
1175 {
1176 	uint8_t retry_count = p2p_get_hw_retry_count(psoc, tx_ctx);
1177 
1178 	mgmt_param->tx_param.retry_limit = GET_HW_RETRY_LIMIT(retry_count);
1179 	mgmt_param->tx_param.retry_limit_ext =
1180 					GET_HW_RETRY_LIMIT_EXT(retry_count);
1181 	if (mgmt_param->tx_param.retry_limit ||
1182 	    mgmt_param->tx_param.retry_limit_ext)
1183 		mgmt_param->tx_params_valid = true;
1184 }
1185 
1186 /**
1187  * p2p_mgmt_tx() - call mgmt tx api
1188  * @tx_ctx:        tx context
1189  * @buf_len:       buffer length
1190  * @packet:        pointer to qdf nbuf
1191  * @frame:         pointer to qdf nbuf data
1192  *
1193  * This function call mgmt tx api to tx this action frame.
1194  *
1195  * Return: QDF_STATUS_SUCCESS - in case of success
1196  */
p2p_mgmt_tx(struct tx_action_context * tx_ctx,uint32_t buf_len,qdf_nbuf_t packet,uint8_t * frame)1197 static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx,
1198 	uint32_t buf_len, qdf_nbuf_t packet, uint8_t *frame)
1199 {
1200 	QDF_STATUS status;
1201 	mgmt_tx_download_comp_cb tx_comp_cb;
1202 	mgmt_ota_comp_cb tx_ota_comp_cb;
1203 	struct wlan_frame_hdr *wh;
1204 	struct wlan_objmgr_peer *peer = NULL;
1205 	struct wmi_mgmt_params mgmt_param = { 0 };
1206 	struct wlan_objmgr_psoc *psoc;
1207 	void *mac_addr;
1208 	uint8_t pdev_id;
1209 	struct wlan_objmgr_vdev *vdev;
1210 	enum QDF_OPMODE opmode;
1211 	bool mlo_link_agnostic;
1212 
1213 	psoc = tx_ctx->p2p_soc_obj->soc;
1214 	mgmt_param.tx_frame = packet;
1215 	mgmt_param.frm_len = buf_len;
1216 	mgmt_param.vdev_id = tx_ctx->vdev_id;
1217 	mgmt_param.pdata = frame;
1218 	mgmt_param.chanfreq = tx_ctx->chan_freq;
1219 	mgmt_param.qdf_ctx = wlan_psoc_get_qdf_dev(psoc);
1220 	if (!(mgmt_param.qdf_ctx)) {
1221 		p2p_err("qdf ctx is null");
1222 		return QDF_STATUS_E_INVAL;
1223 	}
1224 	p2p_mgmt_set_hw_retry_count(psoc, tx_ctx, &mgmt_param);
1225 
1226 	wh = (struct wlan_frame_hdr *)frame;
1227 	mac_addr = wh->i_addr1;
1228 	pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, tx_ctx->vdev_id,
1229 						WLAN_P2P_ID);
1230 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, tx_ctx->vdev_id,
1231 						    WLAN_P2P_ID);
1232 	if (!vdev) {
1233 		p2p_err("VDEV null");
1234 		return QDF_STATUS_E_INVAL;
1235 	}
1236 
1237 	mlo_link_agnostic = wlan_get_mlo_link_agnostic_flag(vdev, mac_addr);
1238 
1239 	peer = wlan_objmgr_get_peer(psoc, pdev_id,  mac_addr, WLAN_P2P_ID);
1240 	if (!peer) {
1241 		mac_addr = wh->i_addr2;
1242 		peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1243 					    WLAN_P2P_ID);
1244 	}
1245 	if (!peer) {
1246 		opmode = wlan_vdev_mlme_get_opmode(vdev);
1247 		/*
1248 		 * For NAN iface, retrieves mac address from vdev
1249 		 * as it is self peer. Also, rand_mac_tx would be
1250 		 * false as tx channel is not available.
1251 		 */
1252 		if (opmode == QDF_NAN_DISC_MODE || tx_ctx->rand_mac_tx) {
1253 			mac_addr = wlan_vdev_mlme_get_mldaddr(vdev);
1254 			/* for non-MLO case, mld address will zero */
1255 			if (qdf_is_macaddr_zero(
1256 				(struct qdf_mac_addr *)mac_addr))
1257 				mac_addr = wlan_vdev_mlme_get_macaddr(vdev);
1258 
1259 			peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
1260 						    WLAN_P2P_ID);
1261 		}
1262 	}
1263 	if (!peer) {
1264 		p2p_err("no valid peer");
1265 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
1266 		return QDF_STATUS_E_INVAL;
1267 	}
1268 
1269 	if (tx_ctx->no_ack) {
1270 		tx_comp_cb = tgt_p2p_mgmt_download_comp_cb;
1271 		tx_ota_comp_cb = NULL;
1272 	} else {
1273 		tx_comp_cb = NULL;
1274 		tx_ota_comp_cb = tgt_p2p_mgmt_ota_comp_cb;
1275 	}
1276 
1277 	p2p_debug("length:%d, chanfreq:%d retry count:%d(%d, %d)",
1278 		  mgmt_param.frm_len, mgmt_param.chanfreq,
1279 		  (mgmt_param.tx_param.retry_limit_ext << 4) |
1280 		  mgmt_param.tx_param.retry_limit,
1281 		  mgmt_param.tx_param.retry_limit,
1282 		  mgmt_param.tx_param.retry_limit_ext);
1283 
1284 	tx_ctx->nbuf = packet;
1285 
1286 	if (mlo_is_mld_sta(vdev) && tx_ctx->frame_info.type == P2P_FRAME_MGMT &&
1287 	    tx_ctx->frame_info.sub_type == P2P_MGMT_ACTION &&
1288 	    mlo_link_agnostic) {
1289 		mgmt_param.mlo_link_agnostic = true;
1290 	}
1291 	status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx->p2p_soc_obj,
1292 			packet, tx_comp_cb, tx_ota_comp_cb,
1293 			WLAN_UMAC_COMP_P2P, &mgmt_param);
1294 
1295 	wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID);
1296 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
1297 
1298 	return status;
1299 }
1300 
1301 /**
1302  * p2p_roc_req_for_tx_action() - new a roc request for tx
1303  * @tx_ctx:        tx context
1304  *
1305  * This function new a roc request for tx and call roc api to process
1306  * this new roc request.
1307  *
1308  * Return: QDF_STATUS_SUCCESS - in case of success
1309  */
p2p_roc_req_for_tx_action(struct tx_action_context * tx_ctx)1310 static QDF_STATUS p2p_roc_req_for_tx_action(
1311 	struct tx_action_context *tx_ctx)
1312 {
1313 	struct p2p_soc_priv_obj *p2p_soc_obj;
1314 	struct p2p_roc_context *roc_ctx;
1315 	QDF_STATUS status;
1316 
1317 	roc_ctx = qdf_mem_malloc(sizeof(struct p2p_roc_context));
1318 	if (!roc_ctx)
1319 		return QDF_STATUS_E_NOMEM;
1320 
1321 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
1322 	roc_ctx->p2p_soc_obj = p2p_soc_obj;
1323 	roc_ctx->vdev_id = tx_ctx->vdev_id;
1324 	roc_ctx->chan_freq = tx_ctx->chan_freq;
1325 	roc_ctx->duration = tx_ctx->duration;
1326 	roc_ctx->roc_state = ROC_STATE_IDLE;
1327 	roc_ctx->roc_type = OFF_CHANNEL_TX;
1328 	roc_ctx->tx_ctx = tx_ctx;
1329 	roc_ctx->id = tx_ctx->id;
1330 	tx_ctx->roc_cookie = (uintptr_t)roc_ctx;
1331 
1332 	p2p_debug("create roc request for off channel tx, tx ctx:%pK, roc ctx:%pK",
1333 		tx_ctx, roc_ctx);
1334 
1335 	status = p2p_process_roc_req(roc_ctx);
1336 	if (status != QDF_STATUS_SUCCESS) {
1337 		p2p_err("request roc for tx action frrame fail");
1338 		return status;
1339 	}
1340 
1341 	status = qdf_list_insert_back(&p2p_soc_obj->tx_q_roc,
1342 		&tx_ctx->node);
1343 	if (status != QDF_STATUS_SUCCESS)
1344 		p2p_err("Failed to insert off chan tx context to wait roc req queue");
1345 
1346 	return status;
1347 }
1348 
1349 /**
1350  * p2p_find_tx_ctx() - find tx context by cookie
1351  * @p2p_soc_obj:        p2p soc object
1352  * @cookie:          cookie to this p2p tx context
1353  * @is_roc_q:        it is in waiting for roc queue
1354  * @is_ack_q:        it is in waiting for ack queue
1355  *
1356  * This function finds out tx context by cookie.
1357  *
1358  * Return: pointer to tx context
1359  */
p2p_find_tx_ctx(struct p2p_soc_priv_obj * p2p_soc_obj,uint64_t cookie,bool * is_roc_q,bool * is_ack_q)1360 static struct tx_action_context *p2p_find_tx_ctx(
1361 	struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie,
1362 	bool *is_roc_q, bool *is_ack_q)
1363 {
1364 	struct tx_action_context *cur_tx_ctx;
1365 	qdf_list_node_t *p_node;
1366 	QDF_STATUS status;
1367 	*is_roc_q = false;
1368 	*is_ack_q = false;
1369 
1370 	p2p_debug("Start to find tx ctx, p2p soc_obj:%pK, cookie:%llx",
1371 		p2p_soc_obj, cookie);
1372 
1373 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node);
1374 	while (QDF_IS_STATUS_SUCCESS(status)) {
1375 		cur_tx_ctx = qdf_container_of(p_node,
1376 				struct tx_action_context, node);
1377 		if ((uintptr_t) cur_tx_ctx == cookie) {
1378 			*is_roc_q = true;
1379 			p2p_debug("find tx ctx, cookie:%llx", cookie);
1380 			return cur_tx_ctx;
1381 		}
1382 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc,
1383 						p_node, &p_node);
1384 	}
1385 
1386 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node);
1387 	while (QDF_IS_STATUS_SUCCESS(status)) {
1388 		cur_tx_ctx = qdf_container_of(p_node,
1389 				struct tx_action_context, node);
1390 		if ((uintptr_t) cur_tx_ctx == cookie) {
1391 			*is_ack_q = true;
1392 			p2p_debug("find tx ctx, cookie:%llx", cookie);
1393 			return cur_tx_ctx;
1394 		}
1395 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack,
1396 						p_node, &p_node);
1397 	}
1398 
1399 	return NULL;
1400 }
1401 
1402 /**
1403  * p2p_find_tx_ctx_by_roc() - find tx context by roc
1404  * @p2p_soc_obj:        p2p soc object
1405  * @cookie:          cookie to roc context
1406  *
1407  * This function finds out tx context by roc context.
1408  *
1409  * Return: pointer to tx context
1410  */
p2p_find_tx_ctx_by_roc(struct p2p_soc_priv_obj * p2p_soc_obj,uint64_t cookie)1411 static struct tx_action_context *p2p_find_tx_ctx_by_roc(
1412 	struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie)
1413 {
1414 	struct tx_action_context *cur_tx_ctx;
1415 	qdf_list_node_t *p_node;
1416 	QDF_STATUS status;
1417 
1418 	p2p_debug("Start to find tx ctx, p2p soc_obj:%pK, cookie:%llx",
1419 		p2p_soc_obj, cookie);
1420 
1421 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node);
1422 	while (QDF_IS_STATUS_SUCCESS(status)) {
1423 		cur_tx_ctx = qdf_container_of(p_node,
1424 					struct tx_action_context, node);
1425 		if (cur_tx_ctx->roc_cookie == cookie) {
1426 			p2p_debug("find tx ctx, cookie:%llx", cookie);
1427 			return cur_tx_ctx;
1428 		}
1429 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc,
1430 						p_node, &p_node);
1431 	}
1432 
1433 	return NULL;
1434 }
1435 
1436 /**
1437  * p2p_move_tx_context_to_ack_queue() - move tx context to tx_q_ack
1438  * @tx_ctx:        tx context
1439  *
1440  * This function moves tx context to waiting for ack queue.
1441  *
1442  * Return: QDF_STATUS_SUCCESS - in case of success
1443  */
p2p_move_tx_context_to_ack_queue(struct tx_action_context * tx_ctx)1444 static QDF_STATUS p2p_move_tx_context_to_ack_queue(
1445 	struct tx_action_context *tx_ctx)
1446 {
1447 	bool is_roc_q = false;
1448 	bool is_ack_q = false;
1449 	struct p2p_soc_priv_obj *p2p_soc_obj = tx_ctx->p2p_soc_obj;
1450 	struct tx_action_context *cur_tx_ctx;
1451 	QDF_STATUS status;
1452 
1453 	cur_tx_ctx = p2p_find_tx_ctx(p2p_soc_obj, (uintptr_t)tx_ctx,
1454 					&is_roc_q, &is_ack_q);
1455 	if (cur_tx_ctx) {
1456 		if (is_roc_q) {
1457 			p2p_debug("find in wait for roc queue");
1458 			status = qdf_list_remove_node(
1459 				&p2p_soc_obj->tx_q_roc,
1460 				(qdf_list_node_t *)tx_ctx);
1461 			if (status != QDF_STATUS_SUCCESS)
1462 				p2p_err("Failed to remove off chan tx context from wait roc req queue");
1463 		}
1464 
1465 		if (is_ack_q) {
1466 			p2p_debug("Already in waiting for ack queue");
1467 			return QDF_STATUS_SUCCESS;
1468 		}
1469 	}
1470 
1471 	status = qdf_list_insert_back(
1472 				&p2p_soc_obj->tx_q_ack,
1473 				&tx_ctx->node);
1474 	if (status != QDF_STATUS_SUCCESS)
1475 		p2p_err("Failed to insert off chan tx context to wait ack req queue");
1476 
1477 	return status;
1478 }
1479 
1480 /**
1481  * p2p_extend_roc_timer() - extend roc timer
1482  * @p2p_soc_obj:   p2p soc private object
1483  * @frame_info:    pointer to frame information
1484  *
1485  * This function extends roc timer for some of p2p public action frame.
1486  *
1487  * Return: QDF_STATUS_SUCCESS - in case of success
1488  */
p2p_extend_roc_timer(struct p2p_soc_priv_obj * p2p_soc_obj,struct p2p_frame_info * frame_info)1489 static QDF_STATUS p2p_extend_roc_timer(
1490 	struct p2p_soc_priv_obj *p2p_soc_obj,
1491 	struct p2p_frame_info *frame_info)
1492 {
1493 	struct p2p_roc_context *curr_roc_ctx;
1494 	uint32_t extend_time;
1495 
1496 	curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
1497 	if (!curr_roc_ctx) {
1498 		p2p_debug("no running roc request currently");
1499 		return QDF_STATUS_SUCCESS;
1500 	}
1501 
1502 	if (!frame_info) {
1503 		p2p_err("invalid frame information");
1504 		return QDF_STATUS_E_INVAL;
1505 	}
1506 
1507 	switch (frame_info->public_action_type) {
1508 	case P2P_PUBLIC_ACTION_NEG_REQ:
1509 	case P2P_PUBLIC_ACTION_NEG_RSP:
1510 		extend_time = 2 * P2P_ACTION_FRAME_DEFAULT_WAIT;
1511 		break;
1512 	case P2P_PUBLIC_ACTION_INVIT_REQ:
1513 	case P2P_PUBLIC_ACTION_DEV_DIS_REQ:
1514 		extend_time = P2P_ACTION_FRAME_DEFAULT_WAIT;
1515 		break;
1516 	default:
1517 		extend_time = 0;
1518 		break;
1519 	}
1520 
1521 	if (extend_time) {
1522 		p2p_debug("extend roc timer, duration:%d", extend_time);
1523 		curr_roc_ctx->duration = extend_time;
1524 		return p2p_restart_roc_timer(curr_roc_ctx);
1525 	}
1526 
1527 	return QDF_STATUS_SUCCESS;
1528 }
1529 
1530 /**
1531  * p2p_adjust_tx_wait() - adjust tx wait
1532  * @tx_ctx:        tx context
1533  *
1534  * This function adjust wait time of this tx context
1535  *
1536  * Return: None
1537  */
p2p_adjust_tx_wait(struct tx_action_context * tx_ctx)1538 static void p2p_adjust_tx_wait(struct tx_action_context *tx_ctx)
1539 {
1540 	struct p2p_frame_info *frame_info;
1541 
1542 	frame_info = &(tx_ctx->frame_info);
1543 	switch (frame_info->public_action_type) {
1544 	case P2P_PUBLIC_ACTION_NEG_RSP:
1545 	case P2P_PUBLIC_ACTION_PROV_DIS_RSP:
1546 		tx_ctx->duration += P2P_ACTION_FRAME_RSP_WAIT;
1547 		break;
1548 	case P2P_PUBLIC_ACTION_NEG_CNF:
1549 	case P2P_PUBLIC_ACTION_INVIT_RSP:
1550 		tx_ctx->duration += P2P_ACTION_FRAME_ACK_WAIT;
1551 		break;
1552 	default:
1553 		break;
1554 	}
1555 }
1556 
1557 /**
1558  * p2p_remove_tx_context() - remove tx ctx from queue
1559  * @tx_ctx:        tx context
1560  *
1561  * This function remove tx context from waiting for roc queue or
1562  * waiting for ack queue.
1563  *
1564  * Return: QDF_STATUS_SUCCESS - in case of success
1565  */
p2p_remove_tx_context(struct tx_action_context * tx_ctx)1566 static QDF_STATUS p2p_remove_tx_context(
1567 	struct tx_action_context *tx_ctx)
1568 {
1569 	bool is_roc_q = false;
1570 	bool is_ack_q = false;
1571 	struct tx_action_context *cur_tx_ctx;
1572 	uint64_t cookie = (uintptr_t)tx_ctx;
1573 	struct p2p_soc_priv_obj *p2p_soc_obj = tx_ctx->p2p_soc_obj;
1574 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1575 
1576 	p2p_debug("tx context:%pK", tx_ctx);
1577 
1578 	cur_tx_ctx = p2p_find_tx_ctx(p2p_soc_obj, cookie, &is_roc_q,
1579 					&is_ack_q);
1580 
1581 	/* for not off channel tx case, won't find from queue */
1582 	if (!cur_tx_ctx) {
1583 		p2p_debug("Do not find tx context from queue");
1584 		goto end;
1585 	}
1586 
1587 	if (is_roc_q) {
1588 		status = qdf_list_remove_node(
1589 			&p2p_soc_obj->tx_q_roc,
1590 			(qdf_list_node_t *)cur_tx_ctx);
1591 		if (status != QDF_STATUS_SUCCESS)
1592 			p2p_err("Failed to  tx context from wait roc req queue");
1593 	}
1594 
1595 	if (is_ack_q) {
1596 		status = qdf_list_remove_node(
1597 			&p2p_soc_obj->tx_q_ack,
1598 			(qdf_list_node_t *)cur_tx_ctx);
1599 		if (status != QDF_STATUS_SUCCESS)
1600 			p2p_err("Failed to  tx context from wait ack req queue");
1601 	}
1602 
1603 end:
1604 	if (!tx_ctx->roc_cookie)
1605 		qdf_idr_remove(&p2p_soc_obj->p2p_idr, tx_ctx->id);
1606 	qdf_mem_free(tx_ctx->buf);
1607 	qdf_mem_free(tx_ctx);
1608 
1609 	return status;
1610 }
1611 
1612 /**
1613  * p2p_tx_timeout() - Callback for tx timeout
1614  * @pdata: pointer to tx context
1615  *
1616  * This function is callback for tx time out.
1617  *
1618  * Return: None
1619  */
p2p_tx_timeout(void * pdata)1620 static void p2p_tx_timeout(void *pdata)
1621 {
1622 	QDF_STATUS status, ret;
1623 	qdf_list_node_t *p_node;
1624 	struct tx_action_context *tx_ctx;
1625 	struct p2p_soc_priv_obj *p2p_soc_obj;
1626 
1627 	p2p_info("pdata:%pK", pdata);
1628 	p2p_soc_obj = (struct p2p_soc_priv_obj *)pdata;
1629 	if (!p2p_soc_obj) {
1630 		p2p_err("null p2p soc obj");
1631 		return;
1632 	}
1633 
1634 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node);
1635 	while (QDF_IS_STATUS_SUCCESS(status)) {
1636 		tx_ctx = qdf_container_of(p_node,
1637 					  struct tx_action_context, node);
1638 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack,
1639 					    p_node, &p_node);
1640 		if (QDF_TIMER_STATE_STOPPED ==
1641 		    qdf_mc_timer_get_current_state(&tx_ctx->tx_timer)) {
1642 			ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_ack,
1643 						   &tx_ctx->node);
1644 			if (ret == QDF_STATUS_SUCCESS) {
1645 				qdf_mc_timer_destroy(&tx_ctx->tx_timer);
1646 				p2p_send_tx_conf(tx_ctx, false);
1647 				qdf_mem_free(tx_ctx->buf);
1648 				qdf_mem_free(tx_ctx);
1649 			} else
1650 				p2p_err("remove %pK from roc_q fail",
1651 					tx_ctx);
1652 		}
1653 	}
1654 }
1655 
1656 /**
1657  * p2p_enable_tx_timer() - enable tx timer
1658  * @tx_ctx:         tx context
1659  *
1660  * This function enable tx timer for action frame required ota tx.
1661  *
1662  * Return: QDF_STATUS_SUCCESS - in case of success
1663  */
p2p_enable_tx_timer(struct tx_action_context * tx_ctx)1664 static QDF_STATUS p2p_enable_tx_timer(struct tx_action_context *tx_ctx)
1665 {
1666 	QDF_STATUS status;
1667 
1668 	status = qdf_mc_timer_init(&tx_ctx->tx_timer,
1669 				   QDF_TIMER_TYPE_SW, p2p_tx_timeout,
1670 				   tx_ctx->p2p_soc_obj);
1671 	if (status != QDF_STATUS_SUCCESS) {
1672 		p2p_err("failed to init tx timer tx_ctx:%pK", tx_ctx);
1673 		return status;
1674 	}
1675 
1676 	status = qdf_mc_timer_start(&tx_ctx->tx_timer,
1677 				    P2P_ACTION_FRAME_TX_TIMEOUT);
1678 	if (status != QDF_STATUS_SUCCESS)
1679 		p2p_err("tx timer start failed tx_ctx:%pK", tx_ctx);
1680 
1681 	return status;
1682 }
1683 
1684 /**
1685  * p2p_disable_tx_timer() - disable tx timer
1686  * @tx_ctx:         tx context
1687  *
1688  * This function disable tx timer for action frame required ota tx.
1689  *
1690  * Return: QDF_STATUS_SUCCESS - in case of success
1691  */
p2p_disable_tx_timer(struct tx_action_context * tx_ctx)1692 static QDF_STATUS p2p_disable_tx_timer(struct tx_action_context *tx_ctx)
1693 {
1694 	QDF_STATUS status;
1695 
1696 	p2p_debug("tx context:%pK", tx_ctx);
1697 
1698 	status = qdf_mc_timer_stop(&tx_ctx->tx_timer);
1699 	if (status != QDF_STATUS_SUCCESS)
1700 		p2p_err("Failed to stop tx timer, status:%d", status);
1701 
1702 	status = qdf_mc_timer_destroy(&tx_ctx->tx_timer);
1703 	if (status != QDF_STATUS_SUCCESS)
1704 		p2p_err("Failed to destroy tx timer, status:%d", status);
1705 
1706 	return status;
1707 }
1708 
1709 /**
1710  * p2p_populate_rmf_field() - populate unicast rmf frame
1711  * @tx_ctx: tx_action_context
1712  * @size: input size of frame, and output new size
1713  * @ppbuf: input frame ptr, and output new frame
1714  * @ppkt: input pkt, output new pkt.
1715  *
1716  * This function allocates new pkt for rmf frame. The
1717  * new frame has extra space for ccmp field.
1718  *
1719  * Return: QDF_STATUS_SUCCESS - in case of success
1720  */
p2p_populate_rmf_field(struct tx_action_context * tx_ctx,uint32_t * size,uint8_t ** ppbuf,qdf_nbuf_t * ppkt)1721 static QDF_STATUS p2p_populate_rmf_field(struct tx_action_context *tx_ctx,
1722 	uint32_t *size, uint8_t **ppbuf, qdf_nbuf_t *ppkt)
1723 {
1724 	struct wlan_frame_hdr *wh, *rmf_wh;
1725 	struct action_frm_hdr *action_hdr;
1726 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1727 	qdf_nbuf_t pkt = NULL;
1728 	uint8_t *frame;
1729 	uint32_t frame_len;
1730 	struct p2p_soc_priv_obj *p2p_soc_obj;
1731 	uint8_t action_category;
1732 
1733 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
1734 
1735 	if (tx_ctx->frame_info.sub_type != P2P_MGMT_ACTION ||
1736 	    !p2p_soc_obj->p2p_cb.is_mgmt_protected)
1737 		return QDF_STATUS_SUCCESS;
1738 	if (*size < (sizeof(struct wlan_frame_hdr) +
1739 	    sizeof(struct action_frm_hdr))) {
1740 		return QDF_STATUS_E_INVAL;
1741 	}
1742 
1743 	wh = (struct wlan_frame_hdr *)(*ppbuf);
1744 	action_hdr = (struct action_frm_hdr *)(*ppbuf + sizeof(*wh));
1745 
1746 	/*
1747 	 * For Action frame which are not handled, the resp is sent back to the
1748 	 * source without change, except that MSB of the Category set to 1, so
1749 	 * to get the actual action category we need to ignore the MSB.
1750 	 */
1751 	action_category = action_hdr->action_category & 0x7f;
1752 	if (!wlan_mgmt_is_rmf_mgmt_action_frame(action_category)) {
1753 		p2p_debug("non rmf act frame 0x%x category %x",
1754 			  tx_ctx->frame_info.sub_type,
1755 			  action_hdr->action_category);
1756 		return QDF_STATUS_SUCCESS;
1757 	}
1758 
1759 	if (!p2p_soc_obj->p2p_cb.is_mgmt_protected(
1760 		tx_ctx->vdev_id, wh->i_addr1)) {
1761 		p2p_debug("non rmf connection vdev %d "QDF_MAC_ADDR_FMT,
1762 			  tx_ctx->vdev_id, QDF_MAC_ADDR_REF(wh->i_addr1));
1763 		return QDF_STATUS_SUCCESS;
1764 	}
1765 	if (!qdf_is_macaddr_group((struct qdf_mac_addr *)wh->i_addr1) &&
1766 	    !qdf_is_macaddr_broadcast((struct qdf_mac_addr *)wh->i_addr1)) {
1767 		uint8_t mic_len, mic_hdr_len, pdev_id;
1768 
1769 		pdev_id =
1770 			wlan_get_pdev_id_from_vdev_id(tx_ctx->p2p_soc_obj->soc,
1771 						      tx_ctx->vdev_id,
1772 						      WLAN_P2P_ID);
1773 		status = mlme_get_peer_mic_len(p2p_soc_obj->soc, pdev_id,
1774 					       wh->i_addr1, &mic_len,
1775 					       &mic_hdr_len);
1776 		if (QDF_IS_STATUS_ERROR(status)) {
1777 			p2p_err("Failed to get peer mic length.");
1778 			return status;
1779 		}
1780 
1781 		frame_len = *size + mic_hdr_len + mic_len;
1782 		status = p2p_packet_alloc((uint16_t)frame_len, (void **)&frame,
1783 			 &pkt);
1784 		if (status != QDF_STATUS_SUCCESS) {
1785 			p2p_err("Failed to allocate %d bytes for rmf frame.",
1786 				frame_len);
1787 			return QDF_STATUS_E_NOMEM;
1788 		}
1789 
1790 		qdf_mem_copy(frame, wh, sizeof(*wh));
1791 		qdf_mem_copy(frame + sizeof(*wh) + mic_hdr_len,
1792 			     *ppbuf + sizeof(*wh),
1793 			     *size - sizeof(*wh));
1794 		rmf_wh = (struct wlan_frame_hdr *)frame;
1795 		(rmf_wh)->i_fc[1] |= IEEE80211_FC1_WEP;
1796 		p2p_debug("set protection 0x%x cat %d "QDF_MAC_ADDR_FMT,
1797 			  tx_ctx->frame_info.sub_type,
1798 			  action_hdr->action_category,
1799 			  QDF_MAC_ADDR_REF(wh->i_addr1));
1800 
1801 		qdf_nbuf_free(*ppkt);
1802 		*ppbuf = frame;
1803 		*ppkt = pkt;
1804 		*size = frame_len;
1805 		/*
1806 		 * Some target which support sending mgmt frame based on htt
1807 		 * would DMA write this PMF tx frame buffer, it may cause smmu
1808 		 * check permission fault, set a flag to do bi-direction DMA
1809 		 * map, normal tx unmap is enough for this case.
1810 		 */
1811 		QDF_NBUF_CB_TX_DMA_BI_MAP(pkt) = 1;
1812 	}
1813 
1814 	return status;
1815 }
1816 
1817 /**
1818  * p2p_execute_tx_action_frame() - execute tx action frame
1819  * @tx_ctx:        tx context
1820  *
1821  * This function modify p2p ie and tx this action frame.
1822  *
1823  * Return: QDF_STATUS_SUCCESS - in case of success
1824  */
p2p_execute_tx_action_frame(struct tx_action_context * tx_ctx)1825 static QDF_STATUS p2p_execute_tx_action_frame(
1826 	struct tx_action_context *tx_ctx)
1827 {
1828 	uint8_t *frame;
1829 	qdf_nbuf_t packet;
1830 	QDF_STATUS status;
1831 	uint8_t noa_len = 0;
1832 	uint8_t noa_stream[P2P_NOA_STREAM_ARR_SIZE];
1833 	uint8_t orig_len = 0;
1834 	const uint8_t *ie;
1835 	uint8_t ie_len;
1836 	uint8_t *p2p_ie = NULL;
1837 	const uint8_t *presence_noa_attr = NULL;
1838 	uint32_t nbytes_copy;
1839 	uint32_t buf_len = tx_ctx->buf_len;
1840 	struct p2p_frame_info *frame_info;
1841 	struct wlan_objmgr_vdev *vdev;
1842 
1843 	frame_info = &(tx_ctx->frame_info);
1844 	if (frame_info->sub_type == P2P_MGMT_PROBE_RSP) {
1845 		p2p_ie = (uint8_t *)p2p_get_p2pie_from_probe_rsp(tx_ctx);
1846 	} else if (frame_info->action_type ==
1847 			P2P_ACTION_PRESENCE_RSP) {
1848 		ie = tx_ctx->buf +
1849 			P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET;
1850 		ie_len = tx_ctx->buf_len -
1851 			P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET;
1852 		p2p_ie = (uint8_t *)p2p_get_p2pie_ptr(ie, ie_len);
1853 		if (p2p_ie) {
1854 			/* extract the presence of NoA attribute inside
1855 			 * P2P IE */
1856 			ie = p2p_ie + P2P_IE_HEADER_LEN;
1857 			ie_len = p2p_ie[1];
1858 			presence_noa_attr = p2p_get_presence_noa_attr(
1859 						ie, ie_len);
1860 		}
1861 	} else if (frame_info->type == P2P_FRAME_MGMT &&
1862 		   frame_info->sub_type == P2P_MGMT_ACTION) {
1863 		vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
1864 				tx_ctx->p2p_soc_obj->soc, tx_ctx->vdev_id,
1865 				WLAN_P2P_ID);
1866 
1867 		if (vdev) {
1868 			wlan_mlo_update_action_frame_from_user(vdev,
1869 							       tx_ctx->buf,
1870 							       tx_ctx->buf_len);
1871 			wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
1872 		}
1873 	}
1874 
1875 	if ((frame_info->sub_type != P2P_MGMT_NOT_SUPPORT) &&
1876 		p2p_ie) {
1877 		orig_len = p2p_ie[1];
1878 		noa_len = p2p_update_noa_stream(tx_ctx, p2p_ie,
1879 				presence_noa_attr, &buf_len,
1880 				noa_stream);
1881 		buf_len += noa_len;
1882 	}
1883 
1884 	if (frame_info->sub_type == P2P_MGMT_PROBE_RSP)
1885 		p2p_set_ht_caps(tx_ctx, buf_len);
1886 
1887 		/* Ok-- try to allocate some memory: */
1888 	status = p2p_packet_alloc((uint16_t) buf_len, (void **)&frame,
1889 			&packet);
1890 	if (status != QDF_STATUS_SUCCESS) {
1891 		p2p_err("Failed to allocate %d bytes for a Probe Request.",
1892 			buf_len);
1893 		return status;
1894 	}
1895 
1896 	/*
1897 	 * Add sequence number to action frames
1898 	 * Frames are handed over in .11 format by supplicant already
1899 	 */
1900 	p2p_populate_mac_header(tx_ctx);
1901 
1902 	if ((noa_len > 0) && p2p_ie
1903 		&& (noa_len < (P2P_MAX_NOA_ATTR_LEN +
1904 				P2P_IE_HEADER_LEN))) {
1905 		/* Add 2 bytes for length and Arribute field */
1906 		nbytes_copy = (p2p_ie + orig_len + 2) - tx_ctx->buf;
1907 		qdf_mem_copy(frame, tx_ctx->buf, nbytes_copy);
1908 		qdf_mem_copy((frame + nbytes_copy), noa_stream,
1909 				noa_len);
1910 		qdf_mem_copy((frame + nbytes_copy + noa_len),
1911 			tx_ctx->buf + nbytes_copy,
1912 			buf_len - nbytes_copy - noa_len);
1913 	} else {
1914 		qdf_mem_copy(frame, tx_ctx->buf, buf_len);
1915 	}
1916 
1917 	status = p2p_populate_rmf_field(tx_ctx, &buf_len, &frame, &packet);
1918 	if (status != QDF_STATUS_SUCCESS) {
1919 		p2p_err("failed to populate rmf frame");
1920 		qdf_nbuf_free(packet);
1921 		return status;
1922 	}
1923 
1924 	status = p2p_mgmt_tx(tx_ctx, buf_len, packet, frame);
1925 	if (status == QDF_STATUS_SUCCESS) {
1926 		if (tx_ctx->no_ack) {
1927 			p2p_send_tx_conf(tx_ctx, true);
1928 			p2p_remove_tx_context(tx_ctx);
1929 		} else {
1930 			p2p_enable_tx_timer(tx_ctx);
1931 			p2p_move_tx_context_to_ack_queue(tx_ctx);
1932 		}
1933 	} else {
1934 		p2p_err("failed to tx mgmt frame");
1935 		qdf_nbuf_free(packet);
1936 	}
1937 
1938 	return status;
1939 }
1940 
p2p_find_tx_ctx_by_nbuf(struct p2p_soc_priv_obj * p2p_soc_obj,void * nbuf)1941 struct tx_action_context *p2p_find_tx_ctx_by_nbuf(
1942 	struct p2p_soc_priv_obj *p2p_soc_obj, void *nbuf)
1943 {
1944 	struct tx_action_context *cur_tx_ctx;
1945 	qdf_list_node_t *p_node;
1946 	QDF_STATUS status;
1947 
1948 	if (!p2p_soc_obj) {
1949 		p2p_err("invalid p2p soc object");
1950 		return NULL;
1951 	}
1952 
1953 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node);
1954 	while (QDF_IS_STATUS_SUCCESS(status)) {
1955 		cur_tx_ctx =
1956 			qdf_container_of(p_node, struct tx_action_context, node);
1957 		if (cur_tx_ctx->nbuf == nbuf) {
1958 			p2p_debug("find tx ctx, nbuf:%pK", nbuf);
1959 			return cur_tx_ctx;
1960 		}
1961 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack,
1962 						p_node, &p_node);
1963 	}
1964 
1965 	return NULL;
1966 }
1967 
p2p_dump_tx_queue(struct p2p_soc_priv_obj * p2p_soc_obj)1968 void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj)
1969 {
1970 	struct tx_action_context *tx_ctx;
1971 	qdf_list_node_t *p_node;
1972 	QDF_STATUS status;
1973 
1974 	p2p_debug("dump tx queue wait for roc, p2p soc obj:%pK, size:%d",
1975 		p2p_soc_obj, qdf_list_size(&p2p_soc_obj->tx_q_roc));
1976 
1977 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node);
1978 	while (QDF_IS_STATUS_SUCCESS(status)) {
1979 		tx_ctx = qdf_container_of(p_node,
1980 				struct tx_action_context, node);
1981 		p2p_debug("p2p soc object:%pK, tx ctx:%pK, vdev_id:%d, "
1982 			  "scan_id:%d, roc_cookie:%llx, freq:%d, buf:%pK, "
1983 			  "len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d",
1984 			  p2p_soc_obj, tx_ctx,
1985 			  tx_ctx->vdev_id, tx_ctx->scan_id,
1986 			  tx_ctx->roc_cookie, tx_ctx->chan_freq,
1987 			  tx_ctx->buf, tx_ctx->buf_len,
1988 			  tx_ctx->off_chan, tx_ctx->no_cck,
1989 			  tx_ctx->no_ack, tx_ctx->duration);
1990 
1991 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc,
1992 						p_node, &p_node);
1993 	}
1994 
1995 	p2p_debug("dump tx queue wait for ack, size:%d",
1996 		qdf_list_size(&p2p_soc_obj->tx_q_ack));
1997 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node);
1998 	while (QDF_IS_STATUS_SUCCESS(status)) {
1999 		tx_ctx = qdf_container_of(p_node,
2000 				struct tx_action_context, node);
2001 		p2p_debug("p2p soc object:%pK, tx_ctx:%pK, vdev_id:%d, "
2002 			  "scan_id:%d, roc_cookie:%llx, freq:%d, buf:%pK, "
2003 			  "len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d",
2004 			  p2p_soc_obj, tx_ctx,
2005 			  tx_ctx->vdev_id, tx_ctx->scan_id,
2006 			  tx_ctx->roc_cookie, tx_ctx->chan_freq,
2007 			  tx_ctx->buf, tx_ctx->buf_len,
2008 			  tx_ctx->off_chan, tx_ctx->no_cck,
2009 			  tx_ctx->no_ack, tx_ctx->duration);
2010 
2011 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack,
2012 						p_node, &p_node);
2013 	}
2014 }
2015 
p2p_ready_to_tx_frame(struct p2p_soc_priv_obj * p2p_soc_obj,uint64_t cookie)2016 QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj,
2017 	uint64_t cookie)
2018 {
2019 	struct tx_action_context *cur_tx_ctx;
2020 	QDF_STATUS status = QDF_STATUS_SUCCESS;
2021 
2022 	cur_tx_ctx = p2p_find_tx_ctx_by_roc(p2p_soc_obj, cookie);
2023 
2024 	while (cur_tx_ctx) {
2025 		p2p_debug("tx_ctx:%pK", cur_tx_ctx);
2026 		status = p2p_execute_tx_action_frame(cur_tx_ctx);
2027 		if (status != QDF_STATUS_SUCCESS) {
2028 			p2p_send_tx_conf(cur_tx_ctx, false);
2029 			p2p_remove_tx_context(cur_tx_ctx);
2030 		}
2031 		cur_tx_ctx = p2p_find_tx_ctx_by_roc(p2p_soc_obj, cookie);
2032 	}
2033 
2034 	return status;
2035 }
2036 
p2p_cleanup_tx_sync(struct p2p_soc_priv_obj * p2p_soc_obj,struct wlan_objmgr_vdev * vdev)2037 QDF_STATUS p2p_cleanup_tx_sync(
2038 	struct p2p_soc_priv_obj *p2p_soc_obj,
2039 	struct wlan_objmgr_vdev *vdev)
2040 {
2041 	struct scheduler_msg msg = {0};
2042 	struct p2p_cleanup_param *param;
2043 	QDF_STATUS status;
2044 	uint32_t vdev_id;
2045 
2046 	if (!p2p_soc_obj) {
2047 		p2p_err("p2p soc context is NULL");
2048 		return QDF_STATUS_E_FAILURE;
2049 	}
2050 
2051 	p2p_debug("p2p_soc_obj:%pK, vdev:%pK", p2p_soc_obj, vdev);
2052 	param = qdf_mem_malloc(sizeof(*param));
2053 	if (!param)
2054 		return QDF_STATUS_E_NOMEM;
2055 
2056 	param->p2p_soc_obj = p2p_soc_obj;
2057 	if (vdev)
2058 		vdev_id = (uint32_t)wlan_vdev_get_id(vdev);
2059 	else
2060 		vdev_id = P2P_INVALID_VDEV_ID;
2061 	param->vdev_id = vdev_id;
2062 	qdf_event_reset(&p2p_soc_obj->cleanup_tx_done);
2063 	msg.type = P2P_CLEANUP_TX;
2064 	msg.bodyptr = param;
2065 	msg.callback = p2p_process_cmd;
2066 	status = scheduler_post_message(QDF_MODULE_ID_P2P,
2067 					QDF_MODULE_ID_P2P,
2068 					QDF_MODULE_ID_OS_IF, &msg);
2069 	if (status != QDF_STATUS_SUCCESS) {
2070 		qdf_mem_free(param);
2071 		return status;
2072 	}
2073 
2074 	status = qdf_wait_single_event(
2075 			&p2p_soc_obj->cleanup_tx_done,
2076 			P2P_WAIT_CLEANUP_ROC);
2077 
2078 	if (status != QDF_STATUS_SUCCESS)
2079 		p2p_err("wait for cleanup tx timeout, %d", status);
2080 
2081 	return status;
2082 }
2083 
p2p_process_cleanup_tx_queue(struct p2p_cleanup_param * param)2084 QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param)
2085 {
2086 	struct tx_action_context *curr_tx_ctx;
2087 	qdf_list_node_t *p_node;
2088 	struct p2p_soc_priv_obj *p2p_soc_obj;
2089 	uint32_t vdev_id;
2090 	QDF_STATUS status, ret;
2091 
2092 	if (!param || !(param->p2p_soc_obj)) {
2093 		p2p_err("Invalid cleanup param");
2094 		return QDF_STATUS_E_FAILURE;
2095 	}
2096 
2097 	p2p_soc_obj = param->p2p_soc_obj;
2098 	vdev_id = param->vdev_id;
2099 
2100 	p2p_debug("clean up tx queue wait for roc, size:%d, vdev_id:%d",
2101 		  qdf_list_size(&p2p_soc_obj->tx_q_roc), vdev_id);
2102 
2103 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node);
2104 	while (QDF_IS_STATUS_SUCCESS(status)) {
2105 		curr_tx_ctx = qdf_container_of(p_node,
2106 					struct tx_action_context, node);
2107 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc,
2108 					    p_node, &p_node);
2109 		if ((vdev_id == P2P_INVALID_VDEV_ID) ||
2110 		    (vdev_id == curr_tx_ctx->vdev_id)) {
2111 			ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_roc,
2112 						   &curr_tx_ctx->node);
2113 			if (ret == QDF_STATUS_SUCCESS) {
2114 				p2p_send_tx_conf(curr_tx_ctx, false);
2115 				qdf_mem_free(curr_tx_ctx->buf);
2116 				qdf_mem_free(curr_tx_ctx);
2117 			} else
2118 				p2p_err("remove %pK from roc_q fail",
2119 					curr_tx_ctx);
2120 		}
2121 	}
2122 
2123 	p2p_debug("clean up tx queue wait for ack, size:%d",
2124 		  qdf_list_size(&p2p_soc_obj->tx_q_ack));
2125 
2126 	status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node);
2127 	while (QDF_IS_STATUS_SUCCESS(status)) {
2128 		curr_tx_ctx = qdf_container_of(p_node,
2129 					struct tx_action_context, node);
2130 		status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack,
2131 					    p_node, &p_node);
2132 		if ((vdev_id == P2P_INVALID_VDEV_ID) ||
2133 		    (vdev_id == curr_tx_ctx->vdev_id)) {
2134 			ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_ack,
2135 						   &curr_tx_ctx->node);
2136 			if (ret == QDF_STATUS_SUCCESS) {
2137 				p2p_disable_tx_timer(curr_tx_ctx);
2138 				p2p_send_tx_conf(curr_tx_ctx, false);
2139 				qdf_mem_free(curr_tx_ctx->buf);
2140 				qdf_mem_free(curr_tx_ctx);
2141 			} else
2142 				p2p_err("remove %pK from roc_q fail",
2143 					curr_tx_ctx);
2144 		}
2145 	}
2146 
2147 	qdf_event_set(&p2p_soc_obj->cleanup_tx_done);
2148 
2149 	return QDF_STATUS_SUCCESS;
2150 }
2151 
p2p_check_random_mac(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * random_mac_addr)2152 bool p2p_check_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
2153 			  uint8_t *random_mac_addr)
2154 {
2155 	uint32_t i = 0;
2156 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2157 	struct wlan_objmgr_vdev *vdev;
2158 
2159 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID);
2160 	if (!vdev) {
2161 		p2p_debug("vdev is null");
2162 		return false;
2163 	}
2164 
2165 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
2166 				vdev, WLAN_UMAC_COMP_P2P);
2167 	if (!p2p_vdev_obj) {
2168 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2169 		p2p_debug("p2p vdev object is NULL");
2170 		return false;
2171 	}
2172 
2173 	qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2174 	for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
2175 		if ((p2p_vdev_obj->random_mac[i].in_use) &&
2176 		    (!qdf_mem_cmp(p2p_vdev_obj->random_mac[i].addr,
2177 				  random_mac_addr, QDF_MAC_ADDR_SIZE))) {
2178 			qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2179 			wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2180 			return true;
2181 		}
2182 	}
2183 	qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2184 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2185 
2186 	return false;
2187 }
2188 
2189 /**
2190  * find_action_frame_cookie() - Checks for action cookie in cookie list
2191  * @cookie_list: List of cookies
2192  * @rnd_cookie: Cookie to be searched
2193  *
2194  * Return: If search is successful return pointer to action_frame_cookie
2195  * object in which cookie item is encapsulated.
2196  */
2197 static struct action_frame_cookie *
find_action_frame_cookie(qdf_list_t * cookie_list,uint64_t rnd_cookie)2198 find_action_frame_cookie(qdf_list_t *cookie_list, uint64_t rnd_cookie)
2199 {
2200 	struct action_frame_cookie *action_cookie;
2201 
2202 	qdf_list_for_each(cookie_list, action_cookie, cookie_node) {
2203 		if (action_cookie->cookie == rnd_cookie)
2204 			return action_cookie;
2205 	}
2206 
2207 	return NULL;
2208 }
2209 
2210 /**
2211  * allocate_action_frame_cookie() - Allocate and add action cookie to
2212  * given list
2213  * @cookie_list: List of cookies
2214  * @rnd_cookie: Cookie to be added
2215  *
2216  * Return: If allocation and addition is successful return pointer to
2217  * action_frame_cookie object in which cookie item is encapsulated.
2218  */
2219 static struct action_frame_cookie *
allocate_action_frame_cookie(qdf_list_t * cookie_list,uint64_t rnd_cookie)2220 allocate_action_frame_cookie(qdf_list_t *cookie_list, uint64_t rnd_cookie)
2221 {
2222 	struct action_frame_cookie *action_cookie;
2223 
2224 	action_cookie = qdf_mem_malloc(sizeof(*action_cookie));
2225 	if (!action_cookie)
2226 		return NULL;
2227 
2228 	action_cookie->cookie = rnd_cookie;
2229 	qdf_list_insert_front(cookie_list, &action_cookie->cookie_node);
2230 
2231 	return action_cookie;
2232 }
2233 
2234 /**
2235  * delete_action_frame_cookie() - Delete the cookie from given list
2236  * @cookie_list: List of cookies
2237  * @action_cookie: Cookie to be deleted
2238  *
2239  * This function deletes the cookie item from given list and corresponding
2240  * object in which it is encapsulated.
2241  *
2242  * Return: None
2243  */
2244 static void
delete_action_frame_cookie(qdf_list_t * cookie_list,struct action_frame_cookie * action_cookie)2245 delete_action_frame_cookie(qdf_list_t *cookie_list,
2246 			   struct action_frame_cookie *action_cookie)
2247 {
2248 	qdf_list_remove_node(cookie_list, &action_cookie->cookie_node);
2249 	qdf_mem_free(action_cookie);
2250 }
2251 
2252 /**
2253  * delete_all_action_frame_cookie() - Delete all the cookies to given list
2254  * @cookie_list: List of cookies
2255  *
2256  * This function deletes all the cookies from from given list.
2257  *
2258  * Return: None
2259  */
2260 static void
delete_all_action_frame_cookie(qdf_list_t * cookie_list)2261 delete_all_action_frame_cookie(qdf_list_t *cookie_list)
2262 {
2263 	qdf_list_node_t *node = NULL;
2264 
2265 	p2p_debug("Delete cookie list %pK, size %d", cookie_list,
2266 		  qdf_list_size(cookie_list));
2267 
2268 	while (!qdf_list_empty(cookie_list)) {
2269 		qdf_list_remove_front(cookie_list, &node);
2270 		qdf_mem_free(node);
2271 	}
2272 }
2273 
2274 /**
2275  * append_action_frame_cookie() - Append action cookie to given list
2276  * @cookie_list: List of cookies
2277  * @rnd_cookie: Cookie to be append
2278  *
2279  * This is a wrapper function which invokes allocate_action_frame_cookie
2280  * if the cookie to be added is not duplicate
2281  *
2282  * Return: true - for successful case
2283  *             false - failed.
2284  */
2285 static bool
append_action_frame_cookie(qdf_list_t * cookie_list,uint64_t rnd_cookie)2286 append_action_frame_cookie(qdf_list_t *cookie_list, uint64_t rnd_cookie)
2287 {
2288 	struct action_frame_cookie *action_cookie;
2289 
2290 	/*
2291 	 * There should be no mac entry with empty cookie list,
2292 	 * check and ignore if duplicate
2293 	 */
2294 	action_cookie = find_action_frame_cookie(cookie_list, rnd_cookie);
2295 	if (action_cookie)
2296 		/* random mac address is already programmed */
2297 		return true;
2298 
2299 	/* insert new cookie in cookie list */
2300 	action_cookie = allocate_action_frame_cookie(cookie_list, rnd_cookie);
2301 	if (!action_cookie)
2302 		return false;
2303 
2304 	return true;
2305 }
2306 
2307 /**
2308  * p2p_add_random_mac() - add or append random mac to given vdev rand mac list
2309  * @soc: soc object
2310  * @vdev_id: vdev id
2311  * @mac: mac addr to be added or append
2312  * @freq: frequency
2313  * @rnd_cookie: random mac mgmt tx cookie
2314  *
2315  * This function will add or append the mac addr entry to vdev random mac list.
2316  * Once the mac addr filter is not needed, it can be removed by
2317  * p2p_del_random_mac.
2318  *
2319  * Return: QDF_STATUS_E_EXISTS - append to existing list
2320  *             QDF_STATUS_SUCCESS - add a new entry.
2321  *             other : failed to add the mac address entry.
2322  */
2323 static QDF_STATUS
p2p_add_random_mac(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * mac,uint32_t freq,uint64_t rnd_cookie)2324 p2p_add_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
2325 		   uint8_t *mac, uint32_t freq, uint64_t rnd_cookie)
2326 {
2327 	uint32_t i;
2328 	uint32_t first_unused = MAX_RANDOM_MAC_ADDRS;
2329 	struct action_frame_cookie *action_cookie;
2330 	int32_t append_ret;
2331 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2332 	struct wlan_objmgr_vdev *vdev;
2333 
2334 	p2p_debug("random_mac:vdev %d mac_addr:"QDF_MAC_ADDR_FMT" rnd_cookie=%llu freq = %u",
2335 		  vdev_id, QDF_MAC_ADDR_REF(mac), rnd_cookie, freq);
2336 
2337 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID);
2338 	if (!vdev) {
2339 		p2p_debug("vdev is null");
2340 
2341 		return QDF_STATUS_E_INVAL;
2342 	}
2343 
2344 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
2345 				vdev, WLAN_UMAC_COMP_P2P);
2346 	if (!p2p_vdev_obj) {
2347 		p2p_debug("random_mac:p2p vdev object is NULL");
2348 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2349 
2350 		return QDF_STATUS_E_INVAL;
2351 	}
2352 
2353 	qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2354 	/*
2355 	 * Following loop checks whether random mac entry is already
2356 	 * present, if present get the index of matched entry else
2357 	 * get the first unused slot to store this new random mac
2358 	 */
2359 	for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
2360 		if (!p2p_vdev_obj->random_mac[i].in_use) {
2361 			if (first_unused == MAX_RANDOM_MAC_ADDRS)
2362 				first_unused = i;
2363 			continue;
2364 		}
2365 
2366 		if (!qdf_mem_cmp(p2p_vdev_obj->random_mac[i].addr, mac,
2367 				 QDF_MAC_ADDR_SIZE))
2368 			break;
2369 	}
2370 
2371 	if (i != MAX_RANDOM_MAC_ADDRS) {
2372 		append_ret = append_action_frame_cookie(
2373 				&p2p_vdev_obj->random_mac[i].cookie_list,
2374 				rnd_cookie);
2375 		qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2376 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2377 		p2p_debug("random_mac:append %d vdev %d freq %d "QDF_MAC_ADDR_FMT" rnd_cookie %llu",
2378 			  append_ret, vdev_id, freq, QDF_MAC_ADDR_REF(mac), rnd_cookie);
2379 		if (!append_ret) {
2380 			p2p_debug("random_mac:failed to append rnd_cookie");
2381 			return QDF_STATUS_E_NOMEM;
2382 		}
2383 
2384 		return QDF_STATUS_E_EXISTS;
2385 	}
2386 
2387 	if (first_unused == MAX_RANDOM_MAC_ADDRS) {
2388 		qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2389 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2390 		p2p_debug("random_mac:Reached the limit of Max random addresses");
2391 
2392 		return QDF_STATUS_E_RESOURCES;
2393 	}
2394 
2395 	/* get the first unused buf and store new random mac */
2396 	i = first_unused;
2397 
2398 	action_cookie = allocate_action_frame_cookie(
2399 				&p2p_vdev_obj->random_mac[i].cookie_list,
2400 				rnd_cookie);
2401 	if (!action_cookie) {
2402 		qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2403 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2404 		p2p_err("random_mac:failed to alloc rnd cookie");
2405 
2406 		return QDF_STATUS_E_NOMEM;
2407 	}
2408 	qdf_mem_copy(p2p_vdev_obj->random_mac[i].addr, mac, QDF_MAC_ADDR_SIZE);
2409 	p2p_vdev_obj->random_mac[i].in_use = true;
2410 	p2p_vdev_obj->random_mac[i].freq = freq;
2411 	qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2412 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2413 	p2p_debug("random_mac:add vdev %d freq %d "QDF_MAC_ADDR_FMT" rnd_cookie %llu",
2414 		  vdev_id, freq, QDF_MAC_ADDR_REF(mac), rnd_cookie);
2415 
2416 	return QDF_STATUS_SUCCESS;
2417 }
2418 
2419 QDF_STATUS
p2p_del_random_mac(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint64_t rnd_cookie)2420 p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
2421 		   uint64_t rnd_cookie)
2422 {
2423 	uint32_t i;
2424 	struct action_frame_cookie *action_cookie;
2425 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2426 	struct wlan_objmgr_vdev *vdev;
2427 
2428 	p2p_debug("random_mac:vdev %d cookie %llu", vdev_id, rnd_cookie);
2429 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id,
2430 						    WLAN_P2P_ID);
2431 	if (!vdev) {
2432 		p2p_debug("vdev is null");
2433 		return QDF_STATUS_E_INVAL;
2434 	}
2435 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
2436 				vdev, WLAN_UMAC_COMP_P2P);
2437 	if (!p2p_vdev_obj) {
2438 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2439 		p2p_debug("p2p vdev object is NULL");
2440 		return QDF_STATUS_E_INVAL;
2441 	}
2442 
2443 	qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2444 	for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
2445 		struct action_frame_random_mac *random_mac;
2446 		qdf_freq_t freq;
2447 		uint8_t addr[QDF_MAC_ADDR_SIZE];
2448 
2449 		random_mac = &p2p_vdev_obj->random_mac[i];
2450 		if (!random_mac->in_use)
2451 			continue;
2452 
2453 		action_cookie = find_action_frame_cookie(
2454 				&random_mac->cookie_list, rnd_cookie);
2455 		if (!action_cookie)
2456 			continue;
2457 
2458 		delete_action_frame_cookie(
2459 			&random_mac->cookie_list,
2460 			action_cookie);
2461 
2462 		if (qdf_list_empty(&random_mac->cookie_list)) {
2463 			random_mac->in_use = false;
2464 			freq = random_mac->freq;
2465 			qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE);
2466 			qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2467 			if (qdf_mc_timer_get_current_state(
2468 					&random_mac->clear_timer) ==
2469 			    QDF_TIMER_STATE_RUNNING) {
2470 				p2p_debug("random_mac:stop timer on vdev %d addr " QDF_MAC_ADDR_FMT,
2471 					  vdev_id, QDF_MAC_ADDR_REF(addr));
2472 				qdf_mc_timer_stop(&random_mac->clear_timer);
2473 			}
2474 
2475 			p2p_clear_mac_filter(
2476 					wlan_vdev_get_psoc(p2p_vdev_obj->vdev),
2477 					vdev_id, addr, freq);
2478 
2479 			qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2480 			p2p_debug("random_mac:noref on vdev %d addr "QDF_MAC_ADDR_FMT,
2481 				  vdev_id, QDF_MAC_ADDR_REF(addr));
2482 		}
2483 		break;
2484 	}
2485 	qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2486 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2487 
2488 	return QDF_STATUS_SUCCESS;
2489 }
2490 
2491 QDF_STATUS
p2p_random_mac_handle_tx_done(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint64_t rnd_cookie,uint32_t duration)2492 p2p_random_mac_handle_tx_done(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
2493 			      uint64_t rnd_cookie, uint32_t duration)
2494 {
2495 	uint32_t i;
2496 	struct action_frame_cookie *action_cookie;
2497 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2498 	struct wlan_objmgr_vdev *vdev;
2499 
2500 	p2p_debug("random_mac:vdev %d cookie %llu duration %d", vdev_id,
2501 		  rnd_cookie, duration);
2502 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID);
2503 	if (!vdev) {
2504 		p2p_debug("vdev is null");
2505 		return QDF_STATUS_E_INVAL;
2506 	}
2507 
2508 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
2509 						vdev, WLAN_UMAC_COMP_P2P);
2510 	if (!p2p_vdev_obj) {
2511 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2512 		p2p_debug("p2p vdev object is NULL");
2513 		return QDF_STATUS_E_INVAL;
2514 	}
2515 
2516 	qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2517 	for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
2518 		struct action_frame_random_mac *random_mac;
2519 		qdf_freq_t freq;
2520 		uint8_t addr[QDF_MAC_ADDR_SIZE];
2521 
2522 		random_mac = &p2p_vdev_obj->random_mac[i];
2523 		if (!random_mac->in_use)
2524 			continue;
2525 		action_cookie = find_action_frame_cookie(
2526 					&random_mac->cookie_list, rnd_cookie);
2527 		if (!action_cookie)
2528 			continue;
2529 
2530 		/* If duration is zero then remove the cookie and also remove
2531 		 * the filter from firmware.
2532 		 */
2533 		if (!duration) {
2534 			delete_action_frame_cookie(&random_mac->cookie_list,
2535 						   action_cookie);
2536 			p2p_debug("random mac:clear mac addr on vdev %d addr " QDF_MAC_ADDR_FMT,
2537 				  vdev_id, QDF_MAC_ADDR_REF(random_mac->addr));
2538 
2539 			if (qdf_list_empty(&random_mac->cookie_list)) {
2540 				random_mac->in_use = false;
2541 				freq = random_mac->freq;
2542 				qdf_mem_copy(addr, random_mac->addr,
2543 					     QDF_MAC_ADDR_SIZE);
2544 				qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2545 				p2p_clear_mac_filter(
2546 					wlan_vdev_get_psoc(p2p_vdev_obj->vdev),
2547 					vdev_id, addr, freq);
2548 				qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2549 			}
2550 		} else {
2551 			/* As duration is non zero start the timer for this
2552 			 * duration. while the timer is running if tx cancel
2553 			 * comes from supplicant then cookie will be removed
2554 			 * and random mac filter will be removed from firmware.
2555 			 * same thing will happen if timer expires without tx
2556 			 * cancel from supplicant
2557 			 */
2558 			qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE);
2559 
2560 			qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2561 			if (qdf_mc_timer_get_current_state(
2562 				&random_mac->clear_timer) ==
2563 				QDF_TIMER_STATE_RUNNING)
2564 				qdf_mc_timer_stop(&random_mac->clear_timer);
2565 			qdf_mc_timer_start(&random_mac->clear_timer, duration);
2566 			p2p_debug("random_mac:start timer on vdev %d addr " QDF_MAC_ADDR_FMT,
2567 				  vdev_id, QDF_MAC_ADDR_REF(addr));
2568 
2569 			qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2570 		}
2571 	}
2572 	qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2573 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2574 
2575 	return QDF_STATUS_SUCCESS;
2576 }
2577 
p2p_del_all_rand_mac_vdev(struct wlan_objmgr_vdev * vdev)2578 void p2p_del_all_rand_mac_vdev(struct wlan_objmgr_vdev *vdev)
2579 {
2580 	int32_t i;
2581 	uint32_t freq;
2582 	uint8_t addr[QDF_MAC_ADDR_SIZE];
2583 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2584 
2585 	if (!vdev)
2586 		return;
2587 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
2588 				vdev, WLAN_UMAC_COMP_P2P);
2589 	if (!p2p_vdev_obj)
2590 		return;
2591 
2592 	qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2593 	for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
2594 		struct action_frame_cookie *action_cookie;
2595 		struct action_frame_cookie *action_cookie_next;
2596 
2597 		if (!p2p_vdev_obj->random_mac[i].in_use)
2598 			continue;
2599 
2600 		/* empty the list and clear random addr */
2601 		qdf_list_for_each_del(&p2p_vdev_obj->random_mac[i].cookie_list,
2602 				      action_cookie, action_cookie_next,
2603 				      cookie_node) {
2604 			qdf_list_remove_node(
2605 				&p2p_vdev_obj->random_mac[i].cookie_list,
2606 				&action_cookie->cookie_node);
2607 			qdf_mem_free(action_cookie);
2608 		}
2609 
2610 		p2p_vdev_obj->random_mac[i].in_use = false;
2611 		freq = p2p_vdev_obj->random_mac[i].freq;
2612 		qdf_mem_copy(addr, p2p_vdev_obj->random_mac[i].addr,
2613 			     QDF_MAC_ADDR_SIZE);
2614 		qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2615 		qdf_mc_timer_stop(&p2p_vdev_obj->random_mac[i].clear_timer);
2616 		p2p_clear_mac_filter(wlan_vdev_get_psoc(vdev),
2617 				     wlan_vdev_get_id(vdev), addr, freq);
2618 		p2p_debug("random_mac:delall vdev %d freq %d addr "QDF_MAC_ADDR_FMT,
2619 			  wlan_vdev_get_id(vdev), freq, QDF_MAC_ADDR_REF(addr));
2620 
2621 		qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
2622 	}
2623 	qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
2624 }
2625 
2626 static void
p2p_del_rand_mac_vdev_enum_handler(struct wlan_objmgr_psoc * psoc,void * obj,void * arg)2627 p2p_del_rand_mac_vdev_enum_handler(struct wlan_objmgr_psoc *psoc,
2628 				   void *obj, void *arg)
2629 {
2630 	struct wlan_objmgr_vdev *vdev = obj;
2631 
2632 	if (!vdev) {
2633 		p2p_err("random_mac:invalid vdev");
2634 		return;
2635 	}
2636 
2637 	if (!p2p_is_vdev_support_rand_mac(vdev))
2638 		return;
2639 
2640 	p2p_del_all_rand_mac_vdev(vdev);
2641 }
2642 
p2p_del_all_rand_mac_soc(struct wlan_objmgr_psoc * soc)2643 void p2p_del_all_rand_mac_soc(struct wlan_objmgr_psoc *soc)
2644 {
2645 	if (!soc) {
2646 		p2p_err("random_mac:soc object is NULL");
2647 		return;
2648 	}
2649 
2650 	wlan_objmgr_iterate_obj_list(soc, WLAN_VDEV_OP,
2651 				     p2p_del_rand_mac_vdev_enum_handler,
2652 				     NULL, 0, WLAN_P2P_ID);
2653 }
2654 
2655 /**
2656  * p2p_is_random_mac() - check mac addr is random mac for vdev
2657  * @soc: soc object
2658  * @vdev_id: vdev id
2659  * @mac: mac addr to be added or append
2660  *
2661  * This function will check the source mac addr same as vdev's mac addr or not.
2662  * If not same, then the source mac addr should be random mac addr.
2663  *
2664  * Return: true if mac is random mac, otherwise false
2665  */
2666 static bool
p2p_is_random_mac(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * mac)2667 p2p_is_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, uint8_t *mac)
2668 {
2669 	bool ret = false;
2670 	struct wlan_objmgr_vdev *vdev;
2671 
2672 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID);
2673 	if (!vdev) {
2674 		p2p_debug("random_mac:vdev is null");
2675 		return false;
2676 	}
2677 
2678 	if (qdf_mem_cmp(wlan_vdev_mlme_get_macaddr(vdev),
2679 			mac, QDF_MAC_ADDR_SIZE))
2680 		ret = true;
2681 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2682 
2683 	return ret;
2684 }
2685 
p2p_set_mac_filter_callback(bool result,void * context)2686 static void p2p_set_mac_filter_callback(bool result, void *context)
2687 {
2688 	struct osif_request *request;
2689 	struct random_mac_priv *priv;
2690 
2691 	p2p_debug("random_mac:set random mac filter result %d", result);
2692 	request = osif_request_get(context);
2693 	if (!request) {
2694 		p2p_err("random_mac:invalid response");
2695 		return;
2696 	}
2697 
2698 	priv = osif_request_priv(request);
2699 	priv->result = result;
2700 
2701 	osif_request_complete(request);
2702 	osif_request_put(request);
2703 }
2704 
p2p_process_set_rand_mac_rsp(struct p2p_mac_filter_rsp * resp)2705 QDF_STATUS p2p_process_set_rand_mac_rsp(struct p2p_mac_filter_rsp *resp)
2706 {
2707 	struct wlan_objmgr_psoc *soc;
2708 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2709 	struct wlan_objmgr_vdev *vdev;
2710 
2711 	if (!resp || !resp->p2p_soc_obj || !resp->p2p_soc_obj->soc) {
2712 		p2p_debug("random_mac:set_filter_req is null");
2713 		return QDF_STATUS_E_INVAL;
2714 	}
2715 	p2p_debug("random_mac:process rsp on vdev %d status %d", resp->vdev_id,
2716 		  resp->status);
2717 	soc = resp->p2p_soc_obj->soc;
2718 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, resp->vdev_id,
2719 						    WLAN_P2P_ID);
2720 	if (!vdev) {
2721 		p2p_debug("random_mac:vdev is null vdev %d", resp->vdev_id);
2722 		return QDF_STATUS_E_INVAL;
2723 	}
2724 
2725 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
2726 				vdev, WLAN_UMAC_COMP_P2P);
2727 	if (!p2p_vdev_obj) {
2728 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2729 		p2p_debug("random_mac:p2p_vdev_obj is null vdev %d",
2730 			  resp->vdev_id);
2731 		return QDF_STATUS_E_INVAL;
2732 	}
2733 	if (!p2p_vdev_obj->pending_req.soc) {
2734 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2735 		p2p_debug("random_mac:no pending set req for vdev %d",
2736 			  resp->vdev_id);
2737 		return QDF_STATUS_E_INVAL;
2738 	}
2739 
2740 	p2p_debug("random_mac:get pending req on vdev %d set %d mac filter "QDF_MAC_ADDR_FMT" freq %d",
2741 		  p2p_vdev_obj->pending_req.vdev_id,
2742 		  p2p_vdev_obj->pending_req.set,
2743 		  QDF_MAC_ADDR_REF(p2p_vdev_obj->pending_req.mac),
2744 		  p2p_vdev_obj->pending_req.freq);
2745 	if (p2p_vdev_obj->pending_req.cb)
2746 		p2p_vdev_obj->pending_req.cb(
2747 			!!resp->status, p2p_vdev_obj->pending_req.req_cookie);
2748 
2749 	qdf_mem_zero(&p2p_vdev_obj->pending_req,
2750 		     sizeof(p2p_vdev_obj->pending_req));
2751 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2752 
2753 	return QDF_STATUS_SUCCESS;
2754 }
2755 
2756 QDF_STATUS
p2p_process_set_rand_mac(struct p2p_set_mac_filter_req * set_filter_req)2757 p2p_process_set_rand_mac(struct p2p_set_mac_filter_req *set_filter_req)
2758 {
2759 	struct wlan_objmgr_psoc *soc;
2760 	struct wlan_lmac_if_p2p_tx_ops *p2p_ops;
2761 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2762 	struct set_rx_mac_filter param;
2763 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2764 	struct wlan_objmgr_vdev *vdev;
2765 
2766 	if (!set_filter_req || !set_filter_req->soc) {
2767 		p2p_debug("random_mac:set_filter_req is null");
2768 		return QDF_STATUS_E_INVAL;
2769 	}
2770 	p2p_debug("random_mac:vdev %d set %d mac filter "QDF_MAC_ADDR_FMT" freq %d",
2771 		  set_filter_req->vdev_id, set_filter_req->set,
2772 		  QDF_MAC_ADDR_REF(set_filter_req->mac), set_filter_req->freq);
2773 
2774 	soc = set_filter_req->soc;
2775 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
2776 				soc, set_filter_req->vdev_id, WLAN_P2P_ID);
2777 	if (!vdev) {
2778 		p2p_debug("random_mac:vdev is null vdev %d",
2779 			  set_filter_req->vdev_id);
2780 		goto get_vdev_failed;
2781 	}
2782 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
2783 				vdev, WLAN_UMAC_COMP_P2P);
2784 	if (!p2p_vdev_obj) {
2785 		p2p_debug("random_mac:p2p_vdev_obj is null vdev %d",
2786 			  set_filter_req->vdev_id);
2787 		goto get_p2p_obj_failed;
2788 	}
2789 	if (p2p_vdev_obj->pending_req.soc) {
2790 		p2p_debug("random_mac:Busy on vdev %d set %d mac filter "QDF_MAC_ADDR_FMT" freq %d",
2791 			  p2p_vdev_obj->pending_req.vdev_id,
2792 			  p2p_vdev_obj->pending_req.set,
2793 			  QDF_MAC_ADDR_REF(p2p_vdev_obj->pending_req.mac),
2794 			  p2p_vdev_obj->pending_req.freq);
2795 		goto get_p2p_obj_failed;
2796 	}
2797 
2798 	p2p_ops = p2p_psoc_get_tx_ops(soc);
2799 	if (p2p_ops && p2p_ops->set_mac_addr_rx_filter_cmd) {
2800 		qdf_mem_zero(&param,  sizeof(param));
2801 		param.vdev_id = set_filter_req->vdev_id;
2802 		qdf_mem_copy(param.mac, set_filter_req->mac,
2803 			     QDF_MAC_ADDR_SIZE);
2804 		param.freq = set_filter_req->freq;
2805 		param.set = set_filter_req->set;
2806 		status = p2p_ops->set_mac_addr_rx_filter_cmd(soc, &param);
2807 		if (status == QDF_STATUS_SUCCESS && set_filter_req->set)
2808 			qdf_mem_copy(&p2p_vdev_obj->pending_req,
2809 				     set_filter_req, sizeof(*set_filter_req));
2810 		p2p_debug("random_mac:p2p set mac addr rx filter, status:%d",
2811 			  status);
2812 	}
2813 
2814 get_p2p_obj_failed:
2815 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2816 
2817 get_vdev_failed:
2818 	if (status != QDF_STATUS_SUCCESS &&
2819 	    set_filter_req->cb)
2820 		set_filter_req->cb(false, set_filter_req->req_cookie);
2821 
2822 	return status;
2823 }
2824 
2825 /**
2826  * p2p_set_mac_filter() - send set mac addr filter cmd
2827  * @soc: soc
2828  * @vdev_id: vdev id
2829  * @mac: mac addr
2830  * @freq: freq
2831  * @set: set or clear
2832  * @cb: callback func to be called when the request completed.
2833  * @req_cookie: cookie to be returned
2834  *
2835  * This function send set random mac addr filter command to p2p component
2836  * msg core
2837  *
2838  * Return: QDF_STATUS_SUCCESS - if sent successfully.
2839  *         otherwise : failed.
2840  */
2841 static QDF_STATUS
p2p_set_mac_filter(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * mac,uint32_t freq,bool set,p2p_request_mgr_callback_t cb,void * req_cookie)2842 p2p_set_mac_filter(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
2843 		   uint8_t *mac, uint32_t freq, bool set,
2844 		   p2p_request_mgr_callback_t cb, void *req_cookie)
2845 {
2846 	struct p2p_set_mac_filter_req *set_filter_req;
2847 	struct scheduler_msg msg = {0};
2848 	QDF_STATUS status;
2849 
2850 	p2p_debug("random_mac:vdev %d freq %d set %d "QDF_MAC_ADDR_FMT,
2851 		  vdev_id, freq, set, QDF_MAC_ADDR_REF(mac));
2852 
2853 	set_filter_req = qdf_mem_malloc(sizeof(*set_filter_req));
2854 	if (!set_filter_req)
2855 		return QDF_STATUS_E_NOMEM;
2856 
2857 	set_filter_req->soc = soc;
2858 	set_filter_req->vdev_id = vdev_id;
2859 	set_filter_req->freq = freq;
2860 	qdf_mem_copy(set_filter_req->mac, mac, QDF_MAC_ADDR_SIZE);
2861 	set_filter_req->set = set;
2862 	set_filter_req->cb = cb;
2863 	set_filter_req->req_cookie = req_cookie;
2864 
2865 	msg.type = P2P_SET_RANDOM_MAC;
2866 	msg.bodyptr = set_filter_req;
2867 	msg.callback = p2p_process_cmd;
2868 	status = scheduler_post_message(QDF_MODULE_ID_P2P, QDF_MODULE_ID_P2P,
2869 					QDF_MODULE_ID_OS_IF, &msg);
2870 	if (status != QDF_STATUS_SUCCESS)
2871 		qdf_mem_free(set_filter_req);
2872 
2873 	return status;
2874 }
2875 
2876 QDF_STATUS
p2p_clear_mac_filter(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * mac,uint32_t freq)2877 p2p_clear_mac_filter(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
2878 		     uint8_t *mac, uint32_t freq)
2879 {
2880 	return p2p_set_mac_filter(soc, vdev_id, mac, freq, false, NULL, NULL);
2881 }
2882 
2883 bool
p2p_is_vdev_support_rand_mac(struct wlan_objmgr_vdev * vdev)2884 p2p_is_vdev_support_rand_mac(struct wlan_objmgr_vdev *vdev)
2885 {
2886 	enum QDF_OPMODE mode;
2887 
2888 	mode = wlan_vdev_mlme_get_opmode(vdev);
2889 	if (mode == QDF_STA_MODE ||
2890 	    mode == QDF_P2P_CLIENT_MODE ||
2891 	    mode == QDF_P2P_DEVICE_MODE ||
2892 	    mode == QDF_NAN_DISC_MODE)
2893 		return true;
2894 	return false;
2895 }
2896 
2897 /**
2898  * p2p_is_vdev_support_rand_mac_by_id() - check vdev type support random mac
2899  * mgmt tx or not
2900  * @soc: soc obj
2901  * @vdev_id: vdev id
2902  *
2903  * Return: true: support random mac mgmt tx
2904  *             false: not support random mac mgmt tx.
2905  */
2906 static bool
p2p_is_vdev_support_rand_mac_by_id(struct wlan_objmgr_psoc * soc,uint32_t vdev_id)2907 p2p_is_vdev_support_rand_mac_by_id(struct wlan_objmgr_psoc *soc,
2908 				   uint32_t vdev_id)
2909 {
2910 	struct wlan_objmgr_vdev *vdev;
2911 	bool ret = false;
2912 
2913 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID);
2914 	if (!vdev)
2915 		return false;
2916 	ret = p2p_is_vdev_support_rand_mac(vdev);
2917 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
2918 
2919 	return ret;
2920 }
2921 
2922 /**
2923  * p2p_set_rand_mac() - set random mac address rx filter
2924  * @soc: soc
2925  * @vdev_id: vdev id
2926  * @mac: mac addr
2927  * @freq: freq
2928  * @rnd_cookie: cookie to be returned
2929  *
2930  * This function will post msg to p2p core to set random mac addr rx filter.
2931  * It will wait the respone and return the result to caller.
2932  *
2933  * Return: true: set successfully
2934  *             false: failed
2935  */
2936 static bool
p2p_set_rand_mac(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * mac,uint32_t freq,uint64_t rnd_cookie)2937 p2p_set_rand_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
2938 		 uint8_t *mac, uint32_t freq, uint64_t rnd_cookie)
2939 {
2940 	bool ret = false;
2941 	int err;
2942 	QDF_STATUS status;
2943 	struct osif_request *request;
2944 	static const struct osif_request_params params = {
2945 		.priv_size = sizeof(struct random_mac_priv),
2946 		.timeout_ms = WLAN_WAIT_TIME_SET_RND,
2947 	};
2948 	void *req_cookie;
2949 	struct random_mac_priv *priv;
2950 
2951 	request = osif_request_alloc(&params);
2952 	if (!request) {
2953 		p2p_err("Request allocation failure");
2954 		return false;
2955 	}
2956 
2957 	req_cookie = osif_request_cookie(request);
2958 
2959 	status = p2p_set_mac_filter(soc, vdev_id, mac, freq, true,
2960 				    p2p_set_mac_filter_callback, req_cookie);
2961 	if (status != QDF_STATUS_SUCCESS) {
2962 		p2p_err("random_mac:set mac filter failure %d", status);
2963 	} else {
2964 		err = osif_request_wait_for_response(request);
2965 		if (err) {
2966 			p2p_err("random_mac:timeout for set mac filter %d",
2967 				err);
2968 		} else {
2969 			priv = osif_request_priv(request);
2970 			ret = priv->result;
2971 			p2p_debug("random_mac:vdev %d freq %d result %d "QDF_MAC_ADDR_FMT" rnd_cookie %llu",
2972 				  vdev_id, freq, priv->result,
2973 				  QDF_MAC_ADDR_REF(mac), rnd_cookie);
2974 		}
2975 	}
2976 	osif_request_put(request);
2977 
2978 	return ret;
2979 }
2980 
2981 /**
2982  * p2p_mac_clear_timeout() - clear random mac filter timeout
2983  * @context: timer context
2984  *
2985  * This function will clear the mac addr rx filter in target if no
2986  * reference to it.
2987  *
2988  * Return: void
2989  */
p2p_mac_clear_timeout(void * context)2990 static void p2p_mac_clear_timeout(void *context)
2991 {
2992 	struct action_frame_random_mac *random_mac = context;
2993 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
2994 	uint32_t freq;
2995 	uint8_t addr[QDF_MAC_ADDR_SIZE];
2996 	uint32_t vdev_id;
2997 
2998 	if (!random_mac || !random_mac->p2p_vdev_obj) {
2999 		p2p_err("invalid context for mac_clear timeout");
3000 		return;
3001 	}
3002 	p2p_vdev_obj = random_mac->p2p_vdev_obj;
3003 	if (!p2p_vdev_obj || !p2p_vdev_obj->vdev)
3004 		return;
3005 
3006 	qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
3007 
3008 	delete_all_action_frame_cookie(&random_mac->cookie_list);
3009 	random_mac->in_use = false;
3010 	freq = random_mac->freq;
3011 	qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE);
3012 	qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
3013 
3014 	vdev_id = wlan_vdev_get_id(p2p_vdev_obj->vdev);
3015 	p2p_debug("random_mac:clear timeout vdev %d " QDF_MAC_ADDR_FMT " freq %d",
3016 		  vdev_id, QDF_MAC_ADDR_REF(addr), freq);
3017 
3018 	p2p_clear_mac_filter(wlan_vdev_get_psoc(p2p_vdev_obj->vdev),
3019 			     vdev_id, addr, freq);
3020 }
3021 
3022 /**
3023  * p2p_request_random_mac() - request random mac mgmt tx
3024  * @soc: soc
3025  * @vdev_id: vdev id
3026  * @mac: mac addr
3027  * @freq: freq
3028  * @rnd_cookie: cookie to be returned
3029  * @duration: duration of tx timeout
3030  *
3031  * This function will add/append the random mac addr filter entry to vdev.
3032  * If it is new added entry, it will request to set filter in target.
3033  *
3034  * Return: QDF_STATUS_SUCCESS: request successfully
3035  *             other: failed
3036  */
3037 static QDF_STATUS
p2p_request_random_mac(struct wlan_objmgr_psoc * soc,uint32_t vdev_id,uint8_t * mac,uint32_t freq,uint64_t rnd_cookie,uint32_t duration)3038 p2p_request_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id,
3039 		       uint8_t *mac, uint32_t freq, uint64_t rnd_cookie,
3040 		       uint32_t duration)
3041 {
3042 	QDF_STATUS status;
3043 	uint32_t i;
3044 	struct wlan_objmgr_vdev *vdev;
3045 	struct p2p_vdev_priv_obj *p2p_vdev_obj;
3046 
3047 	status = p2p_add_random_mac(soc, vdev_id, mac, freq, rnd_cookie);
3048 	if (status == QDF_STATUS_E_EXISTS)
3049 		return QDF_STATUS_SUCCESS;
3050 
3051 	else if (status != QDF_STATUS_SUCCESS)
3052 		return status;
3053 
3054 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID);
3055 	if (!vdev) {
3056 		p2p_debug("vdev is null");
3057 		return QDF_STATUS_E_INVAL;
3058 	}
3059 
3060 	p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(
3061 						vdev, WLAN_UMAC_COMP_P2P);
3062 	if (!p2p_vdev_obj) {
3063 		p2p_debug("random_mac:p2p vdev object is NULL");
3064 		wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
3065 		return QDF_STATUS_E_INVAL;
3066 	}
3067 
3068 	if (!p2p_set_rand_mac(soc, vdev_id, mac, freq, rnd_cookie)) {
3069 		p2p_debug("random mac: failed to set rand mac address");
3070 
3071 		qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
3072 		for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
3073 			if (!qdf_mem_cmp(p2p_vdev_obj->random_mac[i].addr, mac,
3074 					 QDF_MAC_ADDR_SIZE)) {
3075 				qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
3076 				p2p_mac_clear_timeout(
3077 						&p2p_vdev_obj->random_mac[i]);
3078 				status = QDF_STATUS_SUCCESS;
3079 				qdf_spin_lock(&p2p_vdev_obj->random_mac_lock);
3080 				break;
3081 			}
3082 		}
3083 		qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock);
3084 	}
3085 
3086 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
3087 	return status;
3088 }
3089 
p2p_rand_mac_tx(struct wlan_objmgr_pdev * pdev,struct tx_action_context * tx_action)3090 void p2p_rand_mac_tx(struct wlan_objmgr_pdev *pdev,
3091 		     struct tx_action_context *tx_action)
3092 {
3093 	struct wlan_objmgr_psoc *soc;
3094 	struct wlan_objmgr_vdev *vdev;
3095 	QDF_STATUS status;
3096 	bool is_vdev_up;
3097 
3098 	if (!tx_action || !tx_action->p2p_soc_obj ||
3099 	    !tx_action->p2p_soc_obj->soc)
3100 		return;
3101 	soc = tx_action->p2p_soc_obj->soc;
3102 
3103 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, tx_action->vdev_id,
3104 						    WLAN_P2P_ID);
3105 	if (!vdev) {
3106 		p2p_err("vdev is null id:%d", tx_action->vdev_id);
3107 		return;
3108 	}
3109 
3110 	/*
3111 	 * For PASN authentication frames, fw may request PASN authentication
3112 	 * with source address same as vdev mac address when vdev is not already
3113 	 * started. Allow RX_FILTER configuration for vdev mac address also if
3114 	 * vdev is not started to prevent PASN authentication frame drops.
3115 	 */
3116 	is_vdev_up = QDF_IS_STATUS_SUCCESS(wlan_vdev_is_up(vdev));
3117 	if (!tx_action->no_ack && tx_action->chan_freq &&
3118 	    tx_action->buf_len > MIN_MAC_HEADER_LEN &&
3119 	    p2p_is_vdev_support_rand_mac_by_id(soc, tx_action->vdev_id) &&
3120 	    (p2p_is_random_mac(soc, tx_action->vdev_id,
3121 			      &tx_action->buf[SRC_MAC_ADDR_OFFSET]) ||
3122 	     !is_vdev_up)) {
3123 		status = p2p_request_random_mac(
3124 			soc, tx_action->vdev_id,
3125 			&tx_action->buf[SRC_MAC_ADDR_OFFSET],
3126 			tx_action->chan_freq,
3127 			tx_action->id,
3128 			tx_action->duration);
3129 		if (status == QDF_STATUS_SUCCESS)
3130 			tx_action->rand_mac_tx = true;
3131 		else
3132 			tx_action->rand_mac_tx = false;
3133 	}
3134 
3135 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
3136 }
3137 
3138 void
p2p_rand_mac_tx_done(struct wlan_objmgr_psoc * soc,struct tx_action_context * tx_ctx)3139 p2p_rand_mac_tx_done(struct wlan_objmgr_psoc *soc,
3140 		     struct tx_action_context *tx_ctx)
3141 {
3142 	if (!tx_ctx || !tx_ctx->rand_mac_tx || !soc)
3143 		return;
3144 
3145 	p2p_random_mac_handle_tx_done(soc, tx_ctx->vdev_id, tx_ctx->id,
3146 				      tx_ctx->duration);
3147 }
3148 
p2p_init_random_mac_vdev(struct p2p_vdev_priv_obj * p2p_vdev_obj)3149 void p2p_init_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj)
3150 {
3151 	int32_t i;
3152 
3153 	qdf_spinlock_create(&p2p_vdev_obj->random_mac_lock);
3154 	for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
3155 		qdf_mem_zero(&p2p_vdev_obj->random_mac[i],
3156 			     sizeof(struct action_frame_random_mac));
3157 		p2p_vdev_obj->random_mac[i].in_use = false;
3158 		p2p_vdev_obj->random_mac[i].p2p_vdev_obj = p2p_vdev_obj;
3159 		qdf_list_create(&p2p_vdev_obj->random_mac[i].cookie_list, 0);
3160 		qdf_mc_timer_init(&p2p_vdev_obj->random_mac[i].clear_timer,
3161 				  QDF_TIMER_TYPE_SW, p2p_mac_clear_timeout,
3162 				  &p2p_vdev_obj->random_mac[i]);
3163 	}
3164 }
3165 
p2p_deinit_random_mac_vdev(struct p2p_vdev_priv_obj * p2p_vdev_obj)3166 void p2p_deinit_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj)
3167 {
3168 	int32_t i;
3169 
3170 	p2p_del_all_rand_mac_vdev(p2p_vdev_obj->vdev);
3171 	for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) {
3172 		qdf_mc_timer_destroy(&p2p_vdev_obj->random_mac[i].clear_timer);
3173 		qdf_list_destroy(&p2p_vdev_obj->random_mac[i].cookie_list);
3174 	}
3175 	qdf_spinlock_destroy(&p2p_vdev_obj->random_mac_lock);
3176 }
3177 
p2p_process_mgmt_tx(struct tx_action_context * tx_ctx)3178 QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx)
3179 {
3180 	struct p2p_soc_priv_obj *p2p_soc_obj;
3181 	struct p2p_roc_context *curr_roc_ctx;
3182 	uint8_t *mac_to;
3183 	enum QDF_OPMODE mode;
3184 	struct wlan_objmgr_vdev *vdev;
3185 	QDF_STATUS status;
3186 	bool is_vdev_connected = false;
3187 
3188 	status = p2p_tx_context_check_valid(tx_ctx);
3189 	if (status != QDF_STATUS_SUCCESS) {
3190 		p2p_err("invalid tx action context");
3191 		if (tx_ctx) {
3192 			if (tx_ctx->buf) {
3193 				p2p_send_tx_conf(tx_ctx, false);
3194 				qdf_mem_free(tx_ctx->buf);
3195 			}
3196 			qdf_mem_free(tx_ctx);
3197 		}
3198 		return QDF_STATUS_E_INVAL;
3199 	}
3200 
3201 	p2p_soc_obj = tx_ctx->p2p_soc_obj;
3202 
3203 	p2p_debug("soc:%pK, tx_ctx:%pK, vdev_id:%d, scan_id:%d, "
3204 		  "roc_cookie:%llx, freq:%d, buf:%pK, len:%d, "
3205 		  "off_chan:%d, cck:%d, ack:%d, duration:%d",
3206 		  p2p_soc_obj->soc, tx_ctx, tx_ctx->vdev_id,
3207 		  tx_ctx->scan_id, tx_ctx->roc_cookie, tx_ctx->chan_freq,
3208 		  tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan,
3209 		  tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration);
3210 
3211 	status = p2p_get_frame_info(tx_ctx->buf, tx_ctx->buf_len,
3212 			&(tx_ctx->frame_info));
3213 	if (status != QDF_STATUS_SUCCESS) {
3214 		p2p_err("unsupported frame");
3215 		status = QDF_STATUS_E_INVAL;
3216 		goto fail;
3217 	}
3218 
3219 	/* update P2P connection status with tx frame info */
3220 	mac_to = &(tx_ctx->buf[DST_MAC_ADDR_OFFSET]);
3221 	p2p_tx_update_connection_status(p2p_soc_obj,
3222 		&(tx_ctx->frame_info), mac_to);
3223 
3224 	status = p2p_vdev_check_valid(tx_ctx);
3225 	if (status != QDF_STATUS_SUCCESS) {
3226 		p2p_debug("invalid vdev or vdev mode");
3227 		status = QDF_STATUS_E_INVAL;
3228 		goto fail;
3229 	}
3230 
3231 	/* Do not wait for ack for probe response */
3232 	if (tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP &&
3233 		!(tx_ctx->no_ack)) {
3234 		p2p_debug("Force set no ack to 1");
3235 		tx_ctx->no_ack = 1;
3236 	}
3237 
3238 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
3239 			p2p_soc_obj->soc, tx_ctx->vdev_id, WLAN_P2P_ID);
3240 	if (!vdev) {
3241 		p2p_err("null vdev object");
3242 		goto fail;
3243 	}
3244 
3245 	mode = wlan_vdev_mlme_get_opmode(vdev);
3246 	if (mode == QDF_STA_MODE)
3247 		is_vdev_connected = wlan_cm_is_vdev_connected(vdev);
3248 
3249 	wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
3250 
3251 	if (!tx_ctx->off_chan || !tx_ctx->chan_freq) {
3252 		if (!tx_ctx->chan_freq)
3253 			p2p_check_and_update_channel(tx_ctx);
3254 		if (!tx_ctx->chan_freq && mode == QDF_STA_MODE &&
3255 		    !is_vdev_connected) {
3256 			p2p_debug("chan freq is zero, drop tx mgmt frame");
3257 			goto fail;
3258 		}
3259 		status = p2p_execute_tx_action_frame(tx_ctx);
3260 		if (status != QDF_STATUS_SUCCESS) {
3261 			p2p_err("execute tx fail");
3262 			goto fail;
3263 		} else
3264 			return QDF_STATUS_SUCCESS;
3265 	}
3266 
3267 	/* For off channel tx case */
3268 	curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj);
3269 	if (curr_roc_ctx && (curr_roc_ctx->chan_freq == tx_ctx->chan_freq)) {
3270 		if ((curr_roc_ctx->roc_state == ROC_STATE_REQUESTED) ||
3271 		    (curr_roc_ctx->roc_state == ROC_STATE_STARTED)) {
3272 			tx_ctx->roc_cookie = (uintptr_t)curr_roc_ctx;
3273 			status = qdf_list_insert_back(
3274 					&p2p_soc_obj->tx_q_roc,
3275 					&tx_ctx->node);
3276 			if (status != QDF_STATUS_SUCCESS) {
3277 				p2p_err("Failed to insert off chan tx context to wait roc req queue");
3278 				goto fail;
3279 			} else
3280 				return QDF_STATUS_SUCCESS;
3281 		} else if (curr_roc_ctx->roc_state == ROC_STATE_ON_CHAN) {
3282 			p2p_adjust_tx_wait(tx_ctx);
3283 			if (curr_roc_ctx->duration < tx_ctx->duration)
3284 				curr_roc_ctx->duration = tx_ctx->duration;
3285 			status = p2p_restart_roc_timer(curr_roc_ctx);
3286 			curr_roc_ctx->tx_ctx = tx_ctx;
3287 			if (status != QDF_STATUS_SUCCESS) {
3288 				p2p_err("restart roc timer fail");
3289 				goto fail;
3290 			}
3291 			status = p2p_execute_tx_action_frame(tx_ctx);
3292 			if (status != QDF_STATUS_SUCCESS) {
3293 				p2p_err("execute tx fail");
3294 				goto fail;
3295 			} else
3296 				return QDF_STATUS_SUCCESS;
3297 		}
3298 	}
3299 
3300 	curr_roc_ctx = p2p_find_roc_by_chan_freq(p2p_soc_obj,
3301 						 tx_ctx->chan_freq);
3302 	if (curr_roc_ctx && (curr_roc_ctx->roc_state == ROC_STATE_IDLE)) {
3303 		tx_ctx->roc_cookie = (uintptr_t)curr_roc_ctx;
3304 		status = qdf_list_insert_back(
3305 				&p2p_soc_obj->tx_q_roc,
3306 				&tx_ctx->node);
3307 		if (status != QDF_STATUS_SUCCESS) {
3308 			p2p_err("Failed to insert off chan tx context to wait roc req queue");
3309 			goto fail;
3310 		} else {
3311 			return QDF_STATUS_SUCCESS;
3312 		}
3313 	}
3314 
3315 	if (!tx_ctx->duration) {
3316 		tx_ctx->duration = P2P_ACTION_FRAME_DEFAULT_WAIT;
3317 		p2p_debug("use default wait %d",
3318 			  P2P_ACTION_FRAME_DEFAULT_WAIT);
3319 	}
3320 	status = p2p_roc_req_for_tx_action(tx_ctx);
3321 	if (status != QDF_STATUS_SUCCESS) {
3322 		p2p_err("Failed to request roc before off chan tx");
3323 		goto fail;
3324 	}
3325 
3326 	return QDF_STATUS_SUCCESS;
3327 
3328 fail:
3329 	p2p_send_tx_conf(tx_ctx, false);
3330 	qdf_idr_remove(&p2p_soc_obj->p2p_idr, tx_ctx->id);
3331 	qdf_mem_free(tx_ctx->buf);
3332 	qdf_mem_free(tx_ctx);
3333 
3334 	return status;
3335 }
3336 
p2p_process_mgmt_tx_cancel(struct cancel_roc_context * cancel_tx)3337 QDF_STATUS p2p_process_mgmt_tx_cancel(
3338 	struct cancel_roc_context *cancel_tx)
3339 {
3340 	bool is_roc_q = false;
3341 	bool is_ack_q = false;
3342 	struct tx_action_context *cur_tx_ctx;
3343 	struct p2p_roc_context *cur_roc_ctx;
3344 	struct cancel_roc_context cancel_roc;
3345 
3346 	if (!cancel_tx || !(cancel_tx->cookie)) {
3347 		p2p_info("invalid cancel info");
3348 		return QDF_STATUS_SUCCESS;
3349 	}
3350 
3351 	cur_tx_ctx = p2p_find_tx_ctx(cancel_tx->p2p_soc_obj,
3352 			cancel_tx->cookie, &is_roc_q, &is_ack_q);
3353 	if (cur_tx_ctx) {
3354 		if (is_roc_q) {
3355 			cancel_roc.p2p_soc_obj =
3356 					cancel_tx->p2p_soc_obj;
3357 			cancel_roc.cookie =
3358 					cur_tx_ctx->roc_cookie;
3359 			p2p_remove_tx_context(cur_tx_ctx);
3360 			return p2p_process_cancel_roc_req(&cancel_roc);
3361 		}
3362 		if (is_ack_q) {
3363 			/*Has tx action frame, waiting for ack*/
3364 			p2p_debug("Waiting for ack, cookie %llx",
3365 				cancel_tx->cookie);
3366 		}
3367 	} else {
3368 		p2p_debug("Failed to find tx ctx by cookie, cookie %llx",
3369 			cancel_tx->cookie);
3370 
3371 		cur_roc_ctx = p2p_find_roc_by_tx_ctx(cancel_tx->p2p_soc_obj,
3372 					cancel_tx->cookie);
3373 		if (cur_roc_ctx) {
3374 			p2p_debug("tx ctx:%llx, roc:%pK",
3375 				cancel_tx->cookie, cur_roc_ctx);
3376 			cancel_roc.p2p_soc_obj =
3377 					cancel_tx->p2p_soc_obj;
3378 			cancel_roc.cookie = (uintptr_t) cur_roc_ctx;
3379 			return p2p_process_cancel_roc_req(&cancel_roc);
3380 		}
3381 
3382 		p2p_debug("Failed to find roc by tx ctx");
3383 		return QDF_STATUS_E_INVAL;
3384 	}
3385 
3386 	return QDF_STATUS_SUCCESS;
3387 }
3388 
p2p_process_mgmt_tx_ack_cnf(struct p2p_tx_conf_event * tx_cnf_event)3389 QDF_STATUS p2p_process_mgmt_tx_ack_cnf(
3390 	struct p2p_tx_conf_event *tx_cnf_event)
3391 {
3392 	struct p2p_tx_cnf tx_cnf;
3393 	struct tx_action_context *tx_ctx;
3394 	struct p2p_soc_priv_obj *p2p_soc_obj;
3395 	struct p2p_start_param *start_param;
3396 
3397 	p2p_soc_obj = tx_cnf_event->p2p_soc_obj;
3398 
3399 	if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) {
3400 		qdf_nbuf_free(tx_cnf_event->nbuf);
3401 		p2p_err("Invalid p2p soc object or start parameters");
3402 		return QDF_STATUS_E_INVAL;
3403 	}
3404 
3405 	tx_ctx = p2p_find_tx_ctx_by_nbuf(p2p_soc_obj, tx_cnf_event->nbuf);
3406 	qdf_nbuf_free(tx_cnf_event->nbuf);
3407 	if (!tx_ctx) {
3408 		p2p_err("can't find tx_ctx, tx ack comes late");
3409 		return QDF_STATUS_SUCCESS;
3410 	}
3411 
3412 	/* disable tx timer */
3413 	p2p_disable_tx_timer(tx_ctx);
3414 	tx_cnf.vdev_id = tx_ctx->vdev_id;
3415 	tx_cnf.action_cookie = (uint64_t)tx_ctx->id;
3416 	tx_cnf.buf = tx_ctx->buf;
3417 	tx_cnf.buf_len = tx_ctx->buf_len;
3418 	tx_cnf.status = tx_cnf_event->status;
3419 
3420 	p2p_debug("soc:%pK, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%pK",
3421 		p2p_soc_obj->soc, tx_cnf.vdev_id,
3422 		tx_cnf.action_cookie, tx_cnf.buf_len,
3423 		tx_cnf.status, tx_cnf.buf);
3424 
3425 	p2p_rand_mac_tx_done(p2p_soc_obj->soc, tx_ctx);
3426 
3427 	start_param = p2p_soc_obj->start_param;
3428 	if (start_param->tx_cnf_cb)
3429 		start_param->tx_cnf_cb(start_param->tx_cnf_cb_data,
3430 					&tx_cnf);
3431 	else
3432 		p2p_debug("Got tx conf, but no valid up layer callback");
3433 
3434 	p2p_remove_tx_context(tx_ctx);
3435 
3436 	return QDF_STATUS_SUCCESS;
3437 }
3438 
3439 #define P2P_IS_SOCIAL_CHANNEL(center_freq)	\
3440 	(((center_freq) == 2412) || ((center_freq) == 2437) || \
3441 		((center_freq) == 2462))
3442 
p2p_process_rx_mgmt(struct p2p_rx_mgmt_event * rx_mgmt_event)3443 QDF_STATUS p2p_process_rx_mgmt(
3444 	struct p2p_rx_mgmt_event *rx_mgmt_event)
3445 {
3446 	struct p2p_rx_mgmt_frame *rx_mgmt;
3447 	struct p2p_soc_priv_obj *p2p_soc_obj;
3448 	struct p2p_start_param *start_param;
3449 	struct p2p_frame_info frame_info;
3450 	uint8_t *mac_from;
3451 
3452 	p2p_soc_obj = rx_mgmt_event->p2p_soc_obj;
3453 	rx_mgmt = rx_mgmt_event->rx_mgmt;
3454 
3455 	if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) {
3456 		p2p_err("Invalid psoc object or start parameters");
3457 		qdf_mem_free(rx_mgmt);
3458 		return QDF_STATUS_E_INVAL;
3459 	}
3460 
3461 	p2p_debug("soc:%pK, frame_len:%d, rx_freq:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK",
3462 		  p2p_soc_obj->soc, rx_mgmt->frame_len,
3463 		  rx_mgmt->rx_freq, rx_mgmt->vdev_id, rx_mgmt->frm_type,
3464 		  rx_mgmt->rx_rssi, rx_mgmt->buf);
3465 
3466 	if (rx_mgmt->frm_type == MGMT_ACTION_VENDOR_SPECIFIC) {
3467 		p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len,
3468 				&frame_info);
3469 
3470 		/* update P2P connection status with rx frame info */
3471 		mac_from = &(rx_mgmt->buf[SRC_MAC_ADDR_OFFSET]);
3472 		p2p_rx_update_connection_status(p2p_soc_obj,
3473 						&frame_info, mac_from);
3474 
3475 		p2p_debug("action_sub_type %u, action_type %d",
3476 				frame_info.public_action_type,
3477 				frame_info.action_type);
3478 
3479 		if ((frame_info.public_action_type ==
3480 			P2P_PUBLIC_ACTION_NOT_SUPPORT) &&
3481 		   (frame_info.action_type ==
3482 			P2P_ACTION_NOT_SUPPORT)) {
3483 			p2p_debug("non-p2p frame, drop it");
3484 			qdf_mem_free(rx_mgmt);
3485 			return QDF_STATUS_SUCCESS;
3486 		} else {
3487 			p2p_debug("p2p frame, extend roc accordingly");
3488 			p2p_extend_roc_timer(p2p_soc_obj, &frame_info);
3489 		}
3490 
3491 		if (frame_info.public_action_type ==
3492 		    P2P_PUBLIC_ACTION_NEG_REQ &&
3493 		    wlan_reg_is_24ghz_ch_freq(rx_mgmt->rx_freq) &&
3494 		    !P2P_IS_SOCIAL_CHANNEL(rx_mgmt->rx_freq)) {
3495 			p2p_debug("Drop P2P Negotiation Req due to non-Social channel: %d",
3496 				  rx_mgmt->rx_freq);
3497 			qdf_mem_free(rx_mgmt);
3498 			return QDF_STATUS_SUCCESS;
3499 		}
3500 	}
3501 
3502 	if (rx_mgmt->frm_type == MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC)
3503 		p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len,
3504 				&frame_info);
3505 
3506 	start_param = p2p_soc_obj->start_param;
3507 	if (start_param->rx_cb)
3508 		start_param->rx_cb(start_param->rx_cb_data, rx_mgmt);
3509 	else
3510 		p2p_debug("rx mgmt, but no valid up layer callback");
3511 
3512 	qdf_mem_free(rx_mgmt);
3513 
3514 	return QDF_STATUS_SUCCESS;
3515 }
3516