blob: 733b4d675b72f0906ec6691c1e4b8d5b105e7656 [file] [log] [blame]
Wu Gao53531c52017-02-16 11:39:12 +08001/*
Bala Venkatesh448e8cd2019-02-26 14:10:50 +05302 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
Wu Gao53531c52017-02-16 11:39:12 +08003 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/**
20 * DOC: This file contains main P2P function definitions
21 */
22
23#include <scheduler_api.h>
24#include <wlan_objmgr_psoc_obj.h>
25#include <wlan_objmgr_global_obj.h>
26#include <wlan_objmgr_pdev_obj.h>
27#include <wlan_objmgr_vdev_obj.h>
28#include <wlan_objmgr_peer_obj.h>
Wu Gao01309ad2017-03-15 17:27:59 +080029#include <wlan_scan_ucfg_api.h>
Wu Gao53531c52017-02-16 11:39:12 +080030#include "wlan_p2p_public_struct.h"
31#include "wlan_p2p_ucfg_api.h"
32#include "wlan_p2p_tgt_api.h"
Wu Gao88c1dd02017-03-05 20:36:03 +080033#include "wlan_p2p_main.h"
34#include "wlan_p2p_roc.h"
35#include "wlan_p2p_off_chan_tx.h"
Wu Gao9a677282018-06-14 18:58:40 +080036#include "wlan_p2p_cfg.h"
37#include "cfg_ucfg_api.h"
Wu Gao88c1dd02017-03-05 20:36:03 +080038
39/**
40 * p2p_get_cmd_type_str() - parse cmd to string
41 * @cmd_type: P2P cmd type
42 *
43 * This function parse P2P cmd to string.
44 *
45 * Return: command string
46 */
47static char *p2p_get_cmd_type_str(enum p2p_cmd_type cmd_type)
48{
49 switch (cmd_type) {
50 case P2P_ROC_REQ:
51 return "P2P roc request";
52 case P2P_CANCEL_ROC_REQ:
53 return "P2P cancel roc request";
54 case P2P_MGMT_TX:
55 return "P2P mgmt tx request";
56 case P2P_MGMT_TX_CANCEL:
57 return "P2P cancel mgmt tx request";
Wu Gao62b15032018-03-26 10:26:00 +080058 case P2P_CLEANUP_ROC:
59 return "P2P cleanup roc";
60 case P2P_CLEANUP_TX:
61 return "P2P cleanup tx";
Liangwei Dongd89c5d52018-09-19 23:35:14 -040062 case P2P_SET_RANDOM_MAC:
63 return "P2P set random mac";
Wu Gao88c1dd02017-03-05 20:36:03 +080064 default:
65 return "Invalid P2P command";
66 }
67}
68
69/**
70 * p2p_get_event_type_str() - parase event to string
71 * @event_type: P2P event type
72 *
73 * This function parse P2P event to string.
74 *
75 * Return: event string
76 */
77static char *p2p_get_event_type_str(enum p2p_event_type event_type)
78{
79 switch (event_type) {
80 case P2P_EVENT_SCAN_EVENT:
81 return "P2P scan event";
82 case P2P_EVENT_MGMT_TX_ACK_CNF:
83 return "P2P mgmt tx ack event";
84 case P2P_EVENT_RX_MGMT:
85 return "P2P mgmt rx event";
86 case P2P_EVENT_LO_STOPPED:
87 return "P2P lo stop event";
88 case P2P_EVENT_NOA:
89 return "P2P noa event";
Liangwei Dongd89c5d52018-09-19 23:35:14 -040090 case P2P_EVENT_ADD_MAC_RSP:
91 return "P2P add mac filter resp event";
Wu Gao88c1dd02017-03-05 20:36:03 +080092 default:
93 return "Invalid P2P event";
94 }
95}
Wu Gao53531c52017-02-16 11:39:12 +080096
97/**
98 * p2p_psoc_obj_create_notification() - Function to allocate per P2P
99 * soc private object
100 * @soc: soc context
101 * @data: Pointer to data
102 *
103 * This function gets called from object manager when psoc is being
104 * created and creates p2p soc context.
105 *
106 * Return: QDF_STATUS_SUCCESS - in case of success
107 */
108static QDF_STATUS p2p_psoc_obj_create_notification(
109 struct wlan_objmgr_psoc *soc, void *data)
110{
111 struct p2p_soc_priv_obj *p2p_soc_obj;
112 QDF_STATUS status;
113
Wu Gaod16c4e52017-03-06 14:00:02 +0800114 if (!soc) {
Wu Gao53531c52017-02-16 11:39:12 +0800115 p2p_err("psoc context passed is NULL");
116 return QDF_STATUS_E_INVAL;
117 }
118
119 p2p_soc_obj = qdf_mem_malloc(sizeof(*p2p_soc_obj));
Wu Gaod16c4e52017-03-06 14:00:02 +0800120 if (!p2p_soc_obj) {
Wu Gao53531c52017-02-16 11:39:12 +0800121 p2p_err("Failed to allocate p2p soc private object");
122 return QDF_STATUS_E_NOMEM;
123 }
Wu Gao88c1dd02017-03-05 20:36:03 +0800124
Wu Gao53531c52017-02-16 11:39:12 +0800125 p2p_soc_obj->soc = soc;
126
127 status = wlan_objmgr_psoc_component_obj_attach(soc,
128 WLAN_UMAC_COMP_P2P, p2p_soc_obj,
129 QDF_STATUS_SUCCESS);
130 if (status != QDF_STATUS_SUCCESS) {
131 qdf_mem_free(p2p_soc_obj);
132 p2p_err("Failed to attach p2p component, %d", status);
133 return status;
134 }
135
Jeff Johnsondc3f8222017-09-18 10:07:54 -0700136 p2p_debug("p2p soc object create successful, %pK", p2p_soc_obj);
Wu Gao88c1dd02017-03-05 20:36:03 +0800137
Wu Gao53531c52017-02-16 11:39:12 +0800138 return QDF_STATUS_SUCCESS;
139}
140
141/**
142 * p2p_psoc_obj_destroy_notification() - Free soc private object
143 * @soc: soc context
144 * @data: Pointer to data
145 *
146 * This function gets called from object manager when psoc is being
147 * deleted and delete p2p soc context.
148 *
149 * Return: QDF_STATUS_SUCCESS - in case of success
150 */
151static QDF_STATUS p2p_psoc_obj_destroy_notification(
152 struct wlan_objmgr_psoc *soc, void *data)
153{
154 struct p2p_soc_priv_obj *p2p_soc_obj;
155 QDF_STATUS status;
156
Wu Gaod16c4e52017-03-06 14:00:02 +0800157 if (!soc) {
Wu Gao53531c52017-02-16 11:39:12 +0800158 p2p_err("psoc context passed is NULL");
159 return QDF_STATUS_E_INVAL;
160 }
161
162 p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
163 WLAN_UMAC_COMP_P2P);
Wu Gaod16c4e52017-03-06 14:00:02 +0800164 if (!p2p_soc_obj) {
Wu Gao53531c52017-02-16 11:39:12 +0800165 p2p_err("p2p soc private object is NULL");
166 return QDF_STATUS_E_FAILURE;
167 }
168
Wu Gao88c1dd02017-03-05 20:36:03 +0800169 p2p_soc_obj->soc = NULL;
170
Wu Gao53531c52017-02-16 11:39:12 +0800171 status = wlan_objmgr_psoc_component_obj_detach(soc,
172 WLAN_UMAC_COMP_P2P, p2p_soc_obj);
173 if (status != QDF_STATUS_SUCCESS) {
174 p2p_err("Failed to detach p2p component, %d", status);
175 return status;
176 }
Wu Gao88c1dd02017-03-05 20:36:03 +0800177
Jeff Johnsondc3f8222017-09-18 10:07:54 -0700178 p2p_debug("destroy p2p soc object, %pK", p2p_soc_obj);
Wu Gao88c1dd02017-03-05 20:36:03 +0800179
Wu Gao53531c52017-02-16 11:39:12 +0800180 qdf_mem_free(p2p_soc_obj);
181
182 return QDF_STATUS_SUCCESS;
183}
184
185/**
186 * p2p_vdev_obj_create_notification() - Allocate per p2p vdev object
187 * @vdev: vdev context
188 * @data: Pointer to data
189 *
190 * This function gets called from object manager when vdev is being
191 * created and creates p2p vdev context.
192 *
193 * Return: QDF_STATUS_SUCCESS - in case of success
194 */
195static QDF_STATUS p2p_vdev_obj_create_notification(
196 struct wlan_objmgr_vdev *vdev, void *data)
197{
198 struct p2p_vdev_priv_obj *p2p_vdev_obj;
199 QDF_STATUS status;
Jeff Johnson8713e342017-11-09 09:54:12 -0800200 enum QDF_OPMODE mode;
Wu Gao53531c52017-02-16 11:39:12 +0800201
Wu Gaod16c4e52017-03-06 14:00:02 +0800202 if (!vdev) {
Wu Gao53531c52017-02-16 11:39:12 +0800203 p2p_err("vdev context passed is NULL");
204 return QDF_STATUS_E_INVAL;
205 }
206
Wu Gaod16c4e52017-03-06 14:00:02 +0800207 mode = wlan_vdev_mlme_get_opmode(vdev);
Yeshwanth Sriram Guntukaa49ef632018-08-23 18:25:28 +0530208 p2p_debug("vdev mode:%d", mode);
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400209 if (mode != QDF_P2P_GO_MODE &&
210 mode != QDF_STA_MODE &&
211 mode != QDF_P2P_CLIENT_MODE &&
212 mode != QDF_P2P_DEVICE_MODE) {
213 p2p_debug("won't create p2p vdev private object for mode %d",
214 mode);
Wu Gaod16c4e52017-03-06 14:00:02 +0800215 return QDF_STATUS_SUCCESS;
216 }
217
218 p2p_vdev_obj =
219 qdf_mem_malloc(sizeof(*p2p_vdev_obj));
220 if (!p2p_vdev_obj) {
Wu Gao53531c52017-02-16 11:39:12 +0800221 p2p_err("Failed to allocate p2p vdev object");
222 return QDF_STATUS_E_NOMEM;
223 }
Wu Gao88c1dd02017-03-05 20:36:03 +0800224
Wu Gao53531c52017-02-16 11:39:12 +0800225 p2p_vdev_obj->vdev = vdev;
Rachit Kankane3abaf942017-04-19 11:49:18 +0530226 p2p_vdev_obj->noa_status = true;
227 p2p_vdev_obj->non_p2p_peer_count = 0;
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400228 p2p_init_random_mac_vdev(p2p_vdev_obj);
Wu Gao88c1dd02017-03-05 20:36:03 +0800229
Wu Gao53531c52017-02-16 11:39:12 +0800230 status = wlan_objmgr_vdev_component_obj_attach(vdev,
231 WLAN_UMAC_COMP_P2P, p2p_vdev_obj,
232 QDF_STATUS_SUCCESS);
233 if (status != QDF_STATUS_SUCCESS) {
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400234 p2p_deinit_random_mac_vdev(p2p_vdev_obj);
Wu Gao53531c52017-02-16 11:39:12 +0800235 qdf_mem_free(p2p_vdev_obj);
236 p2p_err("Failed to attach p2p component to vdev, %d",
237 status);
238 return status;
239 }
240
Jeff Johnsondc3f8222017-09-18 10:07:54 -0700241 p2p_debug("p2p vdev object create successful, %pK", p2p_vdev_obj);
Wu Gao88c1dd02017-03-05 20:36:03 +0800242
Wu Gao53531c52017-02-16 11:39:12 +0800243 return QDF_STATUS_SUCCESS;
244}
245
246/**
247 * p2p_vdev_obj_destroy_notification() - Free per P2P vdev object
248 * @vdev: vdev context
249 * @data: Pointer to data
250 *
251 * This function gets called from object manager when vdev is being
252 * deleted and delete p2p vdev context.
253 *
254 * Return: QDF_STATUS_SUCCESS - in case of success
255 */
256static QDF_STATUS p2p_vdev_obj_destroy_notification(
257 struct wlan_objmgr_vdev *vdev, void *data)
258{
259 struct p2p_vdev_priv_obj *p2p_vdev_obj;
260 QDF_STATUS status;
Jeff Johnson8713e342017-11-09 09:54:12 -0800261 enum QDF_OPMODE mode;
Wu Gao53531c52017-02-16 11:39:12 +0800262
Wu Gaod16c4e52017-03-06 14:00:02 +0800263 if (!vdev) {
Wu Gao53531c52017-02-16 11:39:12 +0800264 p2p_err("vdev context passed is NULL");
265 return QDF_STATUS_E_INVAL;
266 }
267
Wu Gaod16c4e52017-03-06 14:00:02 +0800268 mode = wlan_vdev_mlme_get_opmode(vdev);
Sandeep Puligillaa78776f2018-08-18 12:42:41 -0700269 p2p_debug("vdev mode:%d", mode);
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400270 if (mode != QDF_P2P_GO_MODE &&
271 mode != QDF_STA_MODE &&
272 mode != QDF_P2P_CLIENT_MODE &&
273 mode != QDF_P2P_DEVICE_MODE){
274 p2p_debug("no p2p vdev private object for mode %d", mode);
Wu Gaod16c4e52017-03-06 14:00:02 +0800275 return QDF_STATUS_SUCCESS;
276 }
277
Wu Gao53531c52017-02-16 11:39:12 +0800278 p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
279 WLAN_UMAC_COMP_P2P);
Wu Gaod16c4e52017-03-06 14:00:02 +0800280 if (!p2p_vdev_obj) {
281 p2p_debug("p2p vdev object is NULL");
282 return QDF_STATUS_SUCCESS;
Wu Gao53531c52017-02-16 11:39:12 +0800283 }
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400284 p2p_deinit_random_mac_vdev(p2p_vdev_obj);
Wu Gao53531c52017-02-16 11:39:12 +0800285
Wu Gao88c1dd02017-03-05 20:36:03 +0800286 p2p_vdev_obj->vdev = NULL;
287
Wu Gao53531c52017-02-16 11:39:12 +0800288 status = wlan_objmgr_vdev_component_obj_detach(vdev,
289 WLAN_UMAC_COMP_P2P, p2p_vdev_obj);
290 if (status != QDF_STATUS_SUCCESS) {
291 p2p_err("Failed to detach p2p component, %d", status);
292 return status;
293 }
294
Jeff Johnsondc3f8222017-09-18 10:07:54 -0700295 p2p_debug("destroy p2p vdev object, p2p vdev obj:%pK, noa info:%pK",
Wu Gao88c1dd02017-03-05 20:36:03 +0800296 p2p_vdev_obj, p2p_vdev_obj->noa_info);
297
298 if (p2p_vdev_obj->noa_info)
299 qdf_mem_free(p2p_vdev_obj->noa_info);
300
Wu Gao53531c52017-02-16 11:39:12 +0800301 qdf_mem_free(p2p_vdev_obj);
302
303 return QDF_STATUS_SUCCESS;
304}
305
Wu Gaod16c4e52017-03-06 14:00:02 +0800306/**
Rachit Kankane3abaf942017-04-19 11:49:18 +0530307 * p2p_peer_obj_create_notification() - manages peer details per vdev
308 * @peer: peer object
309 * @arg: Pointer to private argument - NULL
310 *
311 * This function gets called from object manager when peer is being
312 * created.
313 *
314 * Return: QDF_STATUS_SUCCESS - in case of success
315 */
316static QDF_STATUS p2p_peer_obj_create_notification(
317 struct wlan_objmgr_peer *peer, void *arg)
318{
319 struct wlan_objmgr_vdev *vdev;
Jeff Johnson8713e342017-11-09 09:54:12 -0800320 enum QDF_OPMODE mode;
Rachit Kankane3abaf942017-04-19 11:49:18 +0530321
322 if (!peer) {
323 p2p_err("peer context passed is NULL");
324 return QDF_STATUS_E_INVAL;
325 }
326
Rachit Kankane3abaf942017-04-19 11:49:18 +0530327 vdev = wlan_peer_get_vdev(peer);
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400328 mode = wlan_vdev_mlme_get_opmode(vdev);
329 if (mode != QDF_P2P_GO_MODE)
330 return QDF_STATUS_SUCCESS;
331
Rachit Kankane3abaf942017-04-19 11:49:18 +0530332 p2p_debug("p2p peer object create successful");
333
334 return QDF_STATUS_SUCCESS;
335}
336
337/**
338 * p2p_peer_obj_destroy_notification() - clears peer details per vdev
339 * @peer: peer object
340 * @arg: Pointer to private argument - NULL
341 *
342 * This function gets called from object manager when peer is being
343 * destroyed.
344 *
345 * Return: QDF_STATUS_SUCCESS - in case of success
346 */
347static QDF_STATUS p2p_peer_obj_destroy_notification(
348 struct wlan_objmgr_peer *peer, void *arg)
349{
350 struct wlan_objmgr_vdev *vdev;
351 struct p2p_vdev_priv_obj *p2p_vdev_obj;
352 struct wlan_objmgr_psoc *psoc;
Jeff Johnson8713e342017-11-09 09:54:12 -0800353 enum QDF_OPMODE mode;
Rachit Kankane3abaf942017-04-19 11:49:18 +0530354 enum wlan_peer_type peer_type;
355 uint8_t vdev_id;
356
357 if (!peer) {
358 p2p_err("peer context passed is NULL");
359 return QDF_STATUS_E_INVAL;
360 }
361
Rachit Kankane3abaf942017-04-19 11:49:18 +0530362 vdev = wlan_peer_get_vdev(peer);
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400363 mode = wlan_vdev_mlme_get_opmode(vdev);
364 if (mode != QDF_P2P_GO_MODE)
365 return QDF_STATUS_SUCCESS;
366
Rachit Kankane3abaf942017-04-19 11:49:18 +0530367 p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
368 WLAN_UMAC_COMP_P2P);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530369 psoc = wlan_vdev_get_psoc(vdev);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530370 if (!p2p_vdev_obj || !psoc) {
Yeshwanth Sriram Guntukaa49ef632018-08-23 18:25:28 +0530371 p2p_debug("p2p_vdev_obj:%pK psoc:%pK", p2p_vdev_obj, psoc);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530372 return QDF_STATUS_E_INVAL;
373 }
374
Rachit Kankane3abaf942017-04-19 11:49:18 +0530375 mode = wlan_vdev_mlme_get_opmode(vdev);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530376
Rachit Kankane3abaf942017-04-19 11:49:18 +0530377 peer_type = wlan_peer_get_peer_type(peer);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530378
379 if ((peer_type == WLAN_PEER_STA) && (mode == QDF_P2P_GO_MODE)) {
380
381 p2p_vdev_obj->non_p2p_peer_count--;
382
383 if (!p2p_vdev_obj->non_p2p_peer_count &&
384 (p2p_vdev_obj->noa_status == false)) {
385
Rachit Kankane3abaf942017-04-19 11:49:18 +0530386 vdev_id = wlan_vdev_get_id(vdev);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530387
388 if (ucfg_p2p_set_noa(psoc, vdev_id,
389 false) == QDF_STATUS_SUCCESS)
390 p2p_vdev_obj->noa_status = true;
391 else
392 p2p_vdev_obj->noa_status = false;
393
394 p2p_debug("Non p2p peer disconnected from GO,NOA status: %d.",
395 p2p_vdev_obj->noa_status);
396 }
397 p2p_debug("Non P2P peer count: %d",
398 p2p_vdev_obj->non_p2p_peer_count);
399 }
400 p2p_debug("p2p peer object destroy successful");
401
402 return QDF_STATUS_SUCCESS;
403}
404
405/**
Wu Gaod16c4e52017-03-06 14:00:02 +0800406 * p2p_send_noa_to_pe() - send noa information to pe
407 * @noa_info: vdev context
408 *
409 * This function sends noa information to pe since MCL layer need noa
410 * event.
411 *
412 * Return: QDF_STATUS_SUCCESS - in case of success
413 */
414static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info)
415{
416 struct p2p_noa_attr *noa_attr;
Rajeev Kumar9d0085e2017-04-17 17:00:41 -0700417 struct scheduler_msg msg = {0};
Wu Gao43520ac2018-10-30 18:43:57 +0800418 QDF_STATUS status;
Wu Gaod16c4e52017-03-06 14:00:02 +0800419
420 if (!noa_info) {
421 p2p_err("noa info is null");
422 return QDF_STATUS_E_INVAL;
423 }
424
425 noa_attr = qdf_mem_malloc(sizeof(*noa_attr));
426 if (!noa_attr) {
427 p2p_err("Failed to allocate memory for tSirP2PNoaAttr");
428 return QDF_STATUS_E_NOMEM;
429 }
430
431 noa_attr->index = noa_info->index;
432 noa_attr->opps_ps = noa_info->opps_ps;
433 noa_attr->ct_win = noa_info->ct_window;
434 if (!noa_info->num_desc) {
435 p2p_debug("Zero noa descriptors");
436 } else {
437 p2p_debug("%d noa descriptors", noa_info->num_desc);
438
439 noa_attr->noa1_count =
440 noa_info->noa_desc[0].type_count;
441 noa_attr->noa1_duration =
442 noa_info->noa_desc[0].duration;
443 noa_attr->noa1_interval =
444 noa_info->noa_desc[0].interval;
445 noa_attr->noa1_start_time =
446 noa_info->noa_desc[0].start_time;
447 if (noa_info->num_desc > 1) {
448 noa_attr->noa2_count =
449 noa_info->noa_desc[1].type_count;
450 noa_attr->noa2_duration =
451 noa_info->noa_desc[1].duration;
452 noa_attr->noa2_interval =
453 noa_info->noa_desc[1].interval;
454 noa_attr->noa2_start_time =
455 noa_info->noa_desc[1].start_time;
456 }
457 }
458
459 p2p_debug("Sending P2P_NOA_ATTR_IND to pe");
460
461 msg.type = P2P_NOA_ATTR_IND;
462 msg.bodyval = 0;
463 msg.bodyptr = noa_attr;
Wu Gao43520ac2018-10-30 18:43:57 +0800464 status = scheduler_post_message(QDF_MODULE_ID_P2P,
465 QDF_MODULE_ID_P2P,
466 QDF_MODULE_ID_PE,
467 &msg);
468 if (QDF_IS_STATUS_ERROR(status)) {
469 qdf_mem_free(noa_attr);
470 p2p_err("post msg fail:%d", status);
471 }
Wu Gaod16c4e52017-03-06 14:00:02 +0800472
Wu Gao43520ac2018-10-30 18:43:57 +0800473 return status;
Wu Gaod16c4e52017-03-06 14:00:02 +0800474}
475
Rachit Kankane3abaf942017-04-19 11:49:18 +0530476/**
477 * process_peer_for_noa() - disable NoA
478 * @vdev: vdev object
479 * @psoc: soc object
480 * @peer: peer object
481 *
482 * This function disables NoA
483 *
484 *
485 * Return: QDF_STATUS
486 */
487static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev,
488 struct wlan_objmgr_psoc *psoc,
489 struct wlan_objmgr_peer *peer)
490{
491 struct p2p_vdev_priv_obj *p2p_vdev_obj = NULL;
Jeff Johnson8713e342017-11-09 09:54:12 -0800492 enum QDF_OPMODE mode;
Rachit Kankane3abaf942017-04-19 11:49:18 +0530493 enum wlan_peer_type peer_type;
494 bool disable_noa;
495 uint8_t vdev_id;
496
497 if (!vdev || !psoc || !peer) {
Jeff Johnsondc3f8222017-09-18 10:07:54 -0700498 p2p_err("vdev:%pK psoc:%pK peer:%pK", vdev, psoc, peer);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530499 return QDF_STATUS_E_INVAL;
500 }
501 p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
502 WLAN_UMAC_COMP_P2P);
503 if (!p2p_vdev_obj) {
Jeff Johnsondc3f8222017-09-18 10:07:54 -0700504 p2p_err("p2p_vdev_obj:%pK", p2p_vdev_obj);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530505 return QDF_STATUS_E_INVAL;
506 }
Rachit Kankane3abaf942017-04-19 11:49:18 +0530507 mode = wlan_vdev_mlme_get_opmode(vdev);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530508
Rachit Kankane3abaf942017-04-19 11:49:18 +0530509 peer_type = wlan_peer_get_peer_type(peer);
Jayachandran Sreekumaran2613f322019-03-01 19:05:59 +0530510 if (peer_type == WLAN_PEER_STA)
511 p2p_vdev_obj->non_p2p_peer_count++;
Rachit Kankane3abaf942017-04-19 11:49:18 +0530512
513 disable_noa = ((mode == QDF_P2P_GO_MODE)
514 && p2p_vdev_obj->non_p2p_peer_count
515 && p2p_vdev_obj->noa_status);
516
517 if (disable_noa && (peer_type == WLAN_PEER_STA)) {
518
Rachit Kankane3abaf942017-04-19 11:49:18 +0530519 vdev_id = wlan_vdev_get_id(vdev);
Rachit Kankane3abaf942017-04-19 11:49:18 +0530520
521 if (ucfg_p2p_set_noa(psoc, vdev_id,
522 true) == QDF_STATUS_SUCCESS) {
523 p2p_vdev_obj->noa_status = false;
524 } else {
525 p2p_vdev_obj->noa_status = true;
526 }
527 p2p_debug("NoA status: %d", p2p_vdev_obj->noa_status);
528 }
529 p2p_debug("process_peer_for_noa");
530
531 return QDF_STATUS_SUCCESS;
532}
533
Wu Gao9a677282018-06-14 18:58:40 +0800534/**
535 * p2p_object_init_params() - init parameters for p2p object
536 * @psoc: pointer to psoc object
537 * @p2p_soc_obj: pointer to p2p psoc object
538 *
539 * This function init parameters for p2p object
540 */
541static QDF_STATUS p2p_object_init_params(
542 struct wlan_objmgr_psoc *psoc,
543 struct p2p_soc_priv_obj *p2p_soc_obj)
544{
545 if (!psoc || !p2p_soc_obj) {
546 p2p_err("invalid param");
547 return QDF_STATUS_E_INVAL;
548 }
549
550 p2p_soc_obj->param.go_keepalive_period =
551 cfg_get(psoc, CFG_GO_KEEP_ALIVE_PERIOD);
552 p2p_soc_obj->param.go_link_monitor_period =
553 cfg_get(psoc, CFG_GO_LINK_MONITOR_PERIOD);
554 p2p_soc_obj->param.p2p_device_addr_admin =
555 cfg_get(psoc, CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED);
Wu Gao9a677282018-06-14 18:58:40 +0800556 return QDF_STATUS_SUCCESS;
557}
558
Wu Gao8f099b82017-09-07 17:42:15 +0800559#ifdef WLAN_FEATURE_P2P_DEBUG
560/**
561 * wlan_p2p_init_connection_status() - init connection status
562 * @p2p_soc_obj: pointer to p2p psoc object
563 *
564 * This function initial p2p connection status.
565 *
566 * Return: None
567 */
568static void wlan_p2p_init_connection_status(
569 struct p2p_soc_priv_obj *p2p_soc_obj)
570{
571 if (!p2p_soc_obj) {
572 p2p_err("invalid p2p soc obj");
573 return;
574 }
575
576 p2p_soc_obj->connection_status = P2P_NOT_ACTIVE;
577}
578#else
579static void wlan_p2p_init_connection_status(
580 struct p2p_soc_priv_obj *p2p_soc_obj)
581{
582}
583#endif /* WLAN_FEATURE_P2P_DEBUG */
584
Wu Gao53531c52017-02-16 11:39:12 +0800585QDF_STATUS p2p_component_init(void)
586{
587 QDF_STATUS status;
588
589 status = wlan_objmgr_register_psoc_create_handler(
590 WLAN_UMAC_COMP_P2P,
591 p2p_psoc_obj_create_notification,
592 NULL);
593 if (status != QDF_STATUS_SUCCESS) {
594 p2p_err("Failed to register p2p obj create handler");
595 goto err_reg_psoc_create;
596 }
597
Wu Gao88c1dd02017-03-05 20:36:03 +0800598 status = wlan_objmgr_register_psoc_destroy_handler(
Wu Gao53531c52017-02-16 11:39:12 +0800599 WLAN_UMAC_COMP_P2P,
600 p2p_psoc_obj_destroy_notification,
601 NULL);
602 if (status != QDF_STATUS_SUCCESS) {
603 p2p_err("Failed to register p2p obj delete handler");
604 goto err_reg_psoc_delete;
605 }
606
607 status = wlan_objmgr_register_vdev_create_handler(
608 WLAN_UMAC_COMP_P2P,
609 p2p_vdev_obj_create_notification,
610 NULL);
611 if (status != QDF_STATUS_SUCCESS) {
612 p2p_err("Failed to register p2p vdev create handler");
613 goto err_reg_vdev_create;
614 }
615
Wu Gao88c1dd02017-03-05 20:36:03 +0800616 status = wlan_objmgr_register_vdev_destroy_handler(
Wu Gao53531c52017-02-16 11:39:12 +0800617 WLAN_UMAC_COMP_P2P,
618 p2p_vdev_obj_destroy_notification,
619 NULL);
620 if (status != QDF_STATUS_SUCCESS) {
621 p2p_err("Failed to register p2p vdev delete handler");
622 goto err_reg_vdev_delete;
623 }
624
Rachit Kankane3abaf942017-04-19 11:49:18 +0530625 status = wlan_objmgr_register_peer_create_handler(
626 WLAN_UMAC_COMP_P2P,
627 p2p_peer_obj_create_notification,
628 NULL);
629 if (status != QDF_STATUS_SUCCESS) {
630 p2p_err("Failed to register p2p peer create handler");
631 goto err_reg_peer_create;
632 }
633
634 status = wlan_objmgr_register_peer_destroy_handler(
635 WLAN_UMAC_COMP_P2P,
636 p2p_peer_obj_destroy_notification,
637 NULL);
638 if (status != QDF_STATUS_SUCCESS) {
639 p2p_err("Failed to register p2p peer destroy handler");
640 goto err_reg_peer_destroy;
641 }
642
Wu Gao53531c52017-02-16 11:39:12 +0800643 p2p_debug("Register p2p obj handler successful");
644
645 return QDF_STATUS_SUCCESS;
Rachit Kankane3abaf942017-04-19 11:49:18 +0530646err_reg_peer_destroy:
647 wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_P2P,
648 p2p_peer_obj_create_notification, NULL);
649err_reg_peer_create:
650 wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_P2P,
651 p2p_vdev_obj_destroy_notification, NULL);
Wu Gao53531c52017-02-16 11:39:12 +0800652err_reg_vdev_delete:
653 wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_P2P,
654 p2p_vdev_obj_create_notification, NULL);
655err_reg_vdev_create:
Wu Gao88c1dd02017-03-05 20:36:03 +0800656 wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_P2P,
Wu Gao53531c52017-02-16 11:39:12 +0800657 p2p_psoc_obj_destroy_notification, NULL);
658err_reg_psoc_delete:
659 wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_P2P,
660 p2p_psoc_obj_create_notification, NULL);
661err_reg_psoc_create:
662 return status;
663}
664
665QDF_STATUS p2p_component_deinit(void)
666{
667 QDF_STATUS status;
668 QDF_STATUS ret_status = QDF_STATUS_SUCCESS;
669
670 status = wlan_objmgr_unregister_vdev_create_handler(
671 WLAN_UMAC_COMP_P2P,
672 p2p_vdev_obj_create_notification,
673 NULL);
674 if (status != QDF_STATUS_SUCCESS) {
675 p2p_err("Failed to unregister p2p vdev create handler, %d",
676 status);
677 ret_status = status;
678 }
679
Wu Gao88c1dd02017-03-05 20:36:03 +0800680 status = wlan_objmgr_unregister_vdev_destroy_handler(
Wu Gao53531c52017-02-16 11:39:12 +0800681 WLAN_UMAC_COMP_P2P,
682 p2p_vdev_obj_destroy_notification,
683 NULL);
684 if (status != QDF_STATUS_SUCCESS) {
685 p2p_err("Failed to unregister p2p vdev delete handler, %d",
686 status);
687 ret_status = status;
688 }
689
690 status = wlan_objmgr_unregister_psoc_create_handler(
691 WLAN_UMAC_COMP_P2P,
692 p2p_psoc_obj_create_notification,
693 NULL);
694 if (status != QDF_STATUS_SUCCESS) {
695 p2p_err("Failed to unregister p2p obj create handler, %d",
696 status);
697 ret_status = status;
698 }
699
Wu Gao88c1dd02017-03-05 20:36:03 +0800700 status = wlan_objmgr_unregister_psoc_destroy_handler(
Wu Gao53531c52017-02-16 11:39:12 +0800701 WLAN_UMAC_COMP_P2P,
702 p2p_psoc_obj_destroy_notification,
703 NULL);
704 if (status != QDF_STATUS_SUCCESS) {
705 p2p_err("Failed to unregister p2p obj delete handler, %d",
706 status);
707 ret_status = status;
708 }
709
710 p2p_debug("Unregister p2p obj handler complete");
711
712 return ret_status;
713}
714
Wu Gao88c1dd02017-03-05 20:36:03 +0800715QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc)
Wu Gao53531c52017-02-16 11:39:12 +0800716{
Wu Gao0b3198c2017-04-19 18:50:51 +0800717 QDF_STATUS status;
Wu Gao53531c52017-02-16 11:39:12 +0800718 struct p2p_soc_priv_obj *p2p_soc_obj;
719
Wu Gaod16c4e52017-03-06 14:00:02 +0800720 if (!soc) {
Wu Gao53531c52017-02-16 11:39:12 +0800721 p2p_err("psoc context passed is NULL");
722 return QDF_STATUS_E_INVAL;
723 }
724
725 p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
726 WLAN_UMAC_COMP_P2P);
Wu Gaod16c4e52017-03-06 14:00:02 +0800727 if (!p2p_soc_obj) {
Wu Gao53531c52017-02-16 11:39:12 +0800728 p2p_err("p2p soc priviate object is NULL");
729 return QDF_STATUS_E_FAILURE;
730 }
731
Wu Gao9a677282018-06-14 18:58:40 +0800732 p2p_object_init_params(soc, p2p_soc_obj);
Wu Gao53531c52017-02-16 11:39:12 +0800733 qdf_list_create(&p2p_soc_obj->roc_q, MAX_QUEUE_LENGTH);
734 qdf_list_create(&p2p_soc_obj->tx_q_roc, MAX_QUEUE_LENGTH);
735 qdf_list_create(&p2p_soc_obj->tx_q_ack, MAX_QUEUE_LENGTH);
Wu Gao0b3198c2017-04-19 18:50:51 +0800736
737 status = qdf_event_create(&p2p_soc_obj->cancel_roc_done);
738 if (status != QDF_STATUS_SUCCESS) {
739 p2p_err("failed to create cancel roc done event");
Wu Gao62b15032018-03-26 10:26:00 +0800740 goto fail_cancel_roc;
741 }
742
743 status = qdf_event_create(&p2p_soc_obj->cleanup_roc_done);
744 if (status != QDF_STATUS_SUCCESS) {
745 p2p_err("failed to create cleanup roc done event");
746 goto fail_cleanup_roc;
747 }
748
749 status = qdf_event_create(&p2p_soc_obj->cleanup_tx_done);
750 if (status != QDF_STATUS_SUCCESS) {
751 p2p_err("failed to create cleanup roc done event");
752 goto fail_cleanup_tx;
Wu Gao0b3198c2017-04-19 18:50:51 +0800753 }
Prashanth Bhattabcd34812017-01-19 15:33:43 -0800754
755 qdf_runtime_lock_init(&p2p_soc_obj->roc_runtime_lock);
Wu Gao410dd642018-01-19 22:58:32 +0530756 p2p_soc_obj->cur_roc_vdev_id = P2P_INVALID_VDEV_ID;
Wu Gaoc3b7af02018-05-04 19:03:50 +0800757 qdf_idr_create(&p2p_soc_obj->p2p_idr);
Wu Gao53531c52017-02-16 11:39:12 +0800758
759 p2p_debug("p2p psoc object open successful");
760
761 return QDF_STATUS_SUCCESS;
Wu Gao0b3198c2017-04-19 18:50:51 +0800762
Wu Gao62b15032018-03-26 10:26:00 +0800763fail_cleanup_tx:
764 qdf_event_destroy(&p2p_soc_obj->cleanup_roc_done);
765
766fail_cleanup_roc:
767 qdf_event_destroy(&p2p_soc_obj->cancel_roc_done);
768
769fail_cancel_roc:
Wu Gao0b3198c2017-04-19 18:50:51 +0800770 qdf_list_destroy(&p2p_soc_obj->tx_q_ack);
771 qdf_list_destroy(&p2p_soc_obj->tx_q_roc);
772 qdf_list_destroy(&p2p_soc_obj->roc_q);
773
774 return status;
Wu Gao53531c52017-02-16 11:39:12 +0800775}
776
Wu Gao88c1dd02017-03-05 20:36:03 +0800777QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc)
Wu Gao53531c52017-02-16 11:39:12 +0800778{
779 struct p2p_soc_priv_obj *p2p_soc_obj;
780
Wu Gaod16c4e52017-03-06 14:00:02 +0800781 if (!soc) {
Wu Gao53531c52017-02-16 11:39:12 +0800782 p2p_err("psoc context passed is NULL");
783 return QDF_STATUS_E_INVAL;
784 }
785
786 p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
787 WLAN_UMAC_COMP_P2P);
Wu Gaod16c4e52017-03-06 14:00:02 +0800788 if (!p2p_soc_obj) {
Wu Gao53531c52017-02-16 11:39:12 +0800789 p2p_err("p2p soc object is NULL");
790 return QDF_STATUS_E_FAILURE;
791 }
792
Wu Gaoc3b7af02018-05-04 19:03:50 +0800793 qdf_idr_destroy(&p2p_soc_obj->p2p_idr);
Prashanth Bhattabcd34812017-01-19 15:33:43 -0800794 qdf_runtime_lock_deinit(&p2p_soc_obj->roc_runtime_lock);
Wu Gao62b15032018-03-26 10:26:00 +0800795 qdf_event_destroy(&p2p_soc_obj->cleanup_tx_done);
796 qdf_event_destroy(&p2p_soc_obj->cleanup_roc_done);
Wu Gaod16c4e52017-03-06 14:00:02 +0800797 qdf_event_destroy(&p2p_soc_obj->cancel_roc_done);
Wu Gao53531c52017-02-16 11:39:12 +0800798 qdf_list_destroy(&p2p_soc_obj->tx_q_ack);
Wu Gaod16c4e52017-03-06 14:00:02 +0800799 qdf_list_destroy(&p2p_soc_obj->tx_q_roc);
800 qdf_list_destroy(&p2p_soc_obj->roc_q);
Wu Gao53531c52017-02-16 11:39:12 +0800801
802 p2p_debug("p2p psoc object close successful");
803
804 return QDF_STATUS_SUCCESS;
805}
806
Rachit Kankanea06b0282018-07-31 16:26:38 +0530807#ifdef FEATURE_P2P_LISTEN_OFFLOAD
808static inline void p2p_init_lo_event(struct p2p_start_param *start_param,
809 struct p2p_start_param *req)
810{
811 start_param->lo_event_cb = req->lo_event_cb;
812 start_param->lo_event_cb_data = req->lo_event_cb_data;
813}
814#else
815static inline void p2p_init_lo_event(struct p2p_start_param *start_param,
816 struct p2p_start_param *req)
817{
818}
819#endif
820
Wu Gao53531c52017-02-16 11:39:12 +0800821QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc,
822 struct p2p_start_param *req)
823{
824 struct p2p_soc_priv_obj *p2p_soc_obj;
825 struct p2p_start_param *start_param;
826
Wu Gaod16c4e52017-03-06 14:00:02 +0800827 if (!soc) {
Wu Gao53531c52017-02-16 11:39:12 +0800828 p2p_err("psoc context passed is NULL");
829 return QDF_STATUS_E_INVAL;
830 }
831
832 p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
833 WLAN_UMAC_COMP_P2P);
Wu Gaod16c4e52017-03-06 14:00:02 +0800834 if (!p2p_soc_obj) {
Wu Gao53531c52017-02-16 11:39:12 +0800835 p2p_err("P2P soc object is NULL");
836 return QDF_STATUS_E_FAILURE;
837 }
838
839 start_param = qdf_mem_malloc(sizeof(*start_param));
Wu Gaod16c4e52017-03-06 14:00:02 +0800840 if (!start_param) {
Wu Gao53531c52017-02-16 11:39:12 +0800841 p2p_err("Failed to allocate start params");
842 return QDF_STATUS_E_NOMEM;
843 }
844 start_param->rx_cb = req->rx_cb;
845 start_param->rx_cb_data = req->rx_cb_data;
846 start_param->event_cb = req->event_cb;
847 start_param->event_cb_data = req->event_cb_data;
848 start_param->tx_cnf_cb = req->tx_cnf_cb;
849 start_param->tx_cnf_cb_data = req->tx_cnf_cb_data;
Rachit Kankanea06b0282018-07-31 16:26:38 +0530850 p2p_init_lo_event(start_param, req);
Wu Gao53531c52017-02-16 11:39:12 +0800851 p2p_soc_obj->start_param = start_param;
852
Wu Gao8f099b82017-09-07 17:42:15 +0800853 wlan_p2p_init_connection_status(p2p_soc_obj);
854
Wu Gaod16c4e52017-03-06 14:00:02 +0800855 /* register p2p lo stop and noa event */
856 tgt_p2p_register_lo_ev_handler(soc);
857 tgt_p2p_register_noa_ev_handler(soc);
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400858 tgt_p2p_register_macaddr_rx_filter_evt_handler(soc, true);
Wu Gaod16c4e52017-03-06 14:00:02 +0800859
Wu Gao01309ad2017-03-15 17:27:59 +0800860 /* register scan request id */
861 p2p_soc_obj->scan_req_id = ucfg_scan_register_requester(
862 soc, P2P_MODULE_NAME, tgt_p2p_scan_event_cb,
863 p2p_soc_obj);
864
Wu Gao152c8742017-04-24 19:17:12 +0800865 /* register rx action frame */
866 p2p_mgmt_rx_action_ops(soc, true);
867
Wu Gao01309ad2017-03-15 17:27:59 +0800868 p2p_debug("p2p psoc start successful, scan request id:%d",
869 p2p_soc_obj->scan_req_id);
Wu Gao53531c52017-02-16 11:39:12 +0800870
871 return QDF_STATUS_SUCCESS;
872}
873
874QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc)
875{
876 struct p2p_soc_priv_obj *p2p_soc_obj;
877 struct p2p_start_param *start_param;
878
Wu Gaod16c4e52017-03-06 14:00:02 +0800879 if (!soc) {
Wu Gao53531c52017-02-16 11:39:12 +0800880 p2p_err("psoc context passed is NULL");
881 return QDF_STATUS_E_INVAL;
882 }
883
884 p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
885 WLAN_UMAC_COMP_P2P);
Wu Gaod16c4e52017-03-06 14:00:02 +0800886 if (!p2p_soc_obj) {
Wu Gao53531c52017-02-16 11:39:12 +0800887 p2p_err("P2P soc object is NULL");
888 return QDF_STATUS_E_FAILURE;
889 }
890
891 start_param = p2p_soc_obj->start_param;
892 p2p_soc_obj->start_param = NULL;
Wu Gaod16c4e52017-03-06 14:00:02 +0800893 if (!start_param) {
Wu Gao53531c52017-02-16 11:39:12 +0800894 p2p_err("start parameters is NULL");
895 return QDF_STATUS_E_FAILURE;
896 }
897
Wu Gao152c8742017-04-24 19:17:12 +0800898 /* unregister rx action frame */
899 p2p_mgmt_rx_action_ops(soc, false);
900
Wu Gao01309ad2017-03-15 17:27:59 +0800901 /* clean up queue of p2p psoc private object */
Wu Gao62b15032018-03-26 10:26:00 +0800902 p2p_cleanup_tx_sync(p2p_soc_obj, NULL);
903 p2p_cleanup_roc_sync(p2p_soc_obj, NULL);
Wu Gao01309ad2017-03-15 17:27:59 +0800904
905 /* unrgister scan request id*/
906 ucfg_scan_unregister_requester(soc, p2p_soc_obj->scan_req_id);
907
Wu Gaod16c4e52017-03-06 14:00:02 +0800908 /* unregister p2p lo stop and noa event */
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400909 tgt_p2p_register_macaddr_rx_filter_evt_handler(soc, false);
Wu Gaod16c4e52017-03-06 14:00:02 +0800910 tgt_p2p_unregister_lo_ev_handler(soc);
911 tgt_p2p_unregister_noa_ev_handler(soc);
912
Wu Gao53531c52017-02-16 11:39:12 +0800913 start_param->rx_cb = NULL;
914 start_param->rx_cb_data = NULL;
915 start_param->event_cb = NULL;
916 start_param->event_cb_data = NULL;
917 start_param->tx_cnf_cb = NULL;
918 start_param->tx_cnf_cb_data = NULL;
919 qdf_mem_free(start_param);
920
921 p2p_debug("p2p psoc stop successful");
922
923 return QDF_STATUS_SUCCESS;
924}
925
926QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg)
927{
928 QDF_STATUS status;
929
Wu Gaod16c4e52017-03-06 14:00:02 +0800930 p2p_debug("msg type %d, %s", msg->type,
Wu Gao88c1dd02017-03-05 20:36:03 +0800931 p2p_get_cmd_type_str(msg->type));
932
Wu Gaod16c4e52017-03-06 14:00:02 +0800933 if (!(msg->bodyptr)) {
Wu Gao53531c52017-02-16 11:39:12 +0800934 p2p_err("Invalid message body");
935 return QDF_STATUS_E_INVAL;
936 }
937 switch (msg->type) {
938 case P2P_ROC_REQ:
939 status = p2p_process_roc_req(
940 (struct p2p_roc_context *)
941 msg->bodyptr);
942 break;
943 case P2P_CANCEL_ROC_REQ:
944 status = p2p_process_cancel_roc_req(
945 (struct cancel_roc_context *)
946 msg->bodyptr);
Wu Gao01309ad2017-03-15 17:27:59 +0800947 qdf_mem_free(msg->bodyptr);
Wu Gao53531c52017-02-16 11:39:12 +0800948 break;
949 case P2P_MGMT_TX:
950 status = p2p_process_mgmt_tx(
951 (struct tx_action_context *)
952 msg->bodyptr);
953 break;
954 case P2P_MGMT_TX_CANCEL:
955 status = p2p_process_mgmt_tx_cancel(
956 (struct cancel_roc_context *)
957 msg->bodyptr);
Wu Gao01309ad2017-03-15 17:27:59 +0800958 qdf_mem_free(msg->bodyptr);
Wu Gao53531c52017-02-16 11:39:12 +0800959 break;
Wu Gao62b15032018-03-26 10:26:00 +0800960 case P2P_CLEANUP_ROC:
961 status = p2p_process_cleanup_roc_queue(
962 (struct p2p_cleanup_param *)
963 msg->bodyptr);
964 qdf_mem_free(msg->bodyptr);
965 break;
966 case P2P_CLEANUP_TX:
967 status = p2p_process_cleanup_tx_queue(
968 (struct p2p_cleanup_param *)
969 msg->bodyptr);
970 qdf_mem_free(msg->bodyptr);
971 break;
Liangwei Dongd89c5d52018-09-19 23:35:14 -0400972 case P2P_SET_RANDOM_MAC:
973 status = p2p_process_set_rand_mac(msg->bodyptr);
974 qdf_mem_free(msg->bodyptr);
975 break;
976
Wu Gao53531c52017-02-16 11:39:12 +0800977 default:
978 p2p_err("drop unexpected message received %d",
979 msg->type);
980 status = QDF_STATUS_E_INVAL;
981 break;
982 }
983
Wu Gao53531c52017-02-16 11:39:12 +0800984 return status;
985}
986
987QDF_STATUS p2p_process_evt(struct scheduler_msg *msg)
988{
989 QDF_STATUS status;
990
Wu Gaod16c4e52017-03-06 14:00:02 +0800991 p2p_debug("msg type %d, %s", msg->type,
Wu Gao88c1dd02017-03-05 20:36:03 +0800992 p2p_get_event_type_str(msg->type));
993
Wu Gaod16c4e52017-03-06 14:00:02 +0800994 if (!(msg->bodyptr)) {
Wu Gao53531c52017-02-16 11:39:12 +0800995 p2p_err("Invalid message body");
996 return QDF_STATUS_E_INVAL;
997 }
998
999 switch (msg->type) {
1000 case P2P_EVENT_MGMT_TX_ACK_CNF:
1001 status = p2p_process_mgmt_tx_ack_cnf(
1002 (struct p2p_tx_conf_event *)
1003 msg->bodyptr);
1004 break;
1005 case P2P_EVENT_RX_MGMT:
1006 status = p2p_process_rx_mgmt(
1007 (struct p2p_rx_mgmt_event *)
1008 msg->bodyptr);
1009 break;
1010 case P2P_EVENT_LO_STOPPED:
1011 status = p2p_process_lo_stop(
1012 (struct p2p_lo_stop_event *)
1013 msg->bodyptr);
1014 break;
1015 case P2P_EVENT_NOA:
1016 status = p2p_process_noa(
1017 (struct p2p_noa_event *)
1018 msg->bodyptr);
1019 break;
Liangwei Dongd89c5d52018-09-19 23:35:14 -04001020 case P2P_EVENT_ADD_MAC_RSP:
1021 status = p2p_process_set_rand_mac_rsp(
1022 (struct p2p_mac_filter_rsp *)
1023 msg->bodyptr);
1024 break;
Wu Gao53531c52017-02-16 11:39:12 +08001025 default:
1026 p2p_err("Drop unexpected message received %d",
1027 msg->type);
1028 status = QDF_STATUS_E_INVAL;
1029 break;
1030 }
1031
1032 qdf_mem_free(msg->bodyptr);
1033 msg->bodyptr = NULL;
1034
1035 return status;
1036}
1037
Wu Gao43520ac2018-10-30 18:43:57 +08001038QDF_STATUS p2p_msg_flush_callback(struct scheduler_msg *msg)
1039{
1040 struct tx_action_context *tx_action;
1041
1042 if (!msg || !(msg->bodyptr)) {
1043 p2p_err("invalid msg");
1044 return QDF_STATUS_E_INVAL;
1045 }
1046
1047 p2p_debug("flush msg, type:%d", msg->type);
1048 switch (msg->type) {
1049 case P2P_MGMT_TX:
1050 tx_action = (struct tx_action_context *)msg->bodyptr;
1051 qdf_mem_free(tx_action->buf);
1052 qdf_mem_free(tx_action);
1053 break;
1054 default:
1055 qdf_mem_free(msg->bodyptr);
1056 break;
1057 }
1058
1059 return QDF_STATUS_SUCCESS;
1060}
1061
1062QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg)
1063{
1064 struct p2p_noa_event *noa_event;
1065 struct p2p_rx_mgmt_event *rx_mgmt_event;
1066 struct p2p_tx_conf_event *tx_conf_event;
1067 struct p2p_lo_stop_event *lo_stop_event;
1068
1069 if (!msg || !(msg->bodyptr)) {
1070 p2p_err("invalid msg");
1071 return QDF_STATUS_E_INVAL;
1072 }
1073
1074 p2p_debug("flush event, type:%d", msg->type);
1075 switch (msg->type) {
1076 case P2P_EVENT_NOA:
1077 noa_event = (struct p2p_noa_event *)msg->bodyptr;
1078 qdf_mem_free(noa_event->noa_info);
1079 qdf_mem_free(noa_event);
1080 break;
1081 case P2P_EVENT_RX_MGMT:
1082 rx_mgmt_event = (struct p2p_rx_mgmt_event *)msg->bodyptr;
1083 qdf_mem_free(rx_mgmt_event->rx_mgmt);
1084 qdf_mem_free(rx_mgmt_event);
1085 break;
1086 case P2P_EVENT_MGMT_TX_ACK_CNF:
1087 tx_conf_event = (struct p2p_tx_conf_event *)msg->bodyptr;
1088 qdf_mem_free(tx_conf_event);
1089 qdf_nbuf_free(tx_conf_event->nbuf);
1090 break;
1091 case P2P_EVENT_LO_STOPPED:
1092 lo_stop_event = (struct p2p_lo_stop_event *)msg->bodyptr;
1093 qdf_mem_free(lo_stop_event->lo_event);
1094 qdf_mem_free(lo_stop_event);
1095 break;
1096 default:
1097 qdf_mem_free(msg->bodyptr);
1098 break;
1099 }
1100
1101 return QDF_STATUS_SUCCESS;
1102}
1103
Pragaspathi Thilagarajb3472f02019-06-04 14:10:44 +05301104bool p2p_check_oui_and_force_1x1(uint8_t *assoc_ie, uint32_t assoc_ie_len)
1105{
1106 const uint8_t *vendor_ie, *p2p_ie, *pos;
1107 uint8_t rem_len, attr;
1108 uint16_t attr_len;
1109
1110 vendor_ie = (uint8_t *)p2p_get_p2pie_ptr(assoc_ie, assoc_ie_len);
1111 if (!vendor_ie) {
1112 p2p_debug("P2P IE not found");
1113 return false;
1114 }
1115
1116 rem_len = vendor_ie[1];
1117 if (rem_len < (2 + OUI_SIZE_P2P) || rem_len > WLAN_MAX_IE_LEN) {
1118 p2p_err("Invalid IE len %d", rem_len);
1119 return false;
1120 }
1121
1122 p2p_ie = vendor_ie + HEADER_LEN_P2P_IE;
1123 rem_len -= OUI_SIZE_P2P;
1124
1125 while (rem_len) {
1126 attr = p2p_ie[0];
1127 attr_len = LE_READ_2(&p2p_ie[1]);
1128 if (attr_len > rem_len) {
1129 p2p_err("Invalid len %d for elem:%d", attr_len, attr);
1130 return false;
1131 }
1132
1133 switch (attr) {
1134 case P2P_ATTR_CAPABILITY:
1135 case P2P_ATTR_DEVICE_ID:
1136 case P2P_ATTR_GROUP_OWNER_INTENT:
1137 case P2P_ATTR_STATUS:
1138 case P2P_ATTR_LISTEN_CHANNEL:
1139 case P2P_ATTR_OPERATING_CHANNEL:
1140 case P2P_ATTR_GROUP_INFO:
1141 case P2P_ATTR_MANAGEABILITY:
1142 case P2P_ATTR_CHANNEL_LIST:
1143 break;
1144
1145 case P2P_ATTR_DEVICE_INFO:
1146 if (attr_len < (QDF_MAC_ADDR_SIZE +
1147 MAX_CONFIG_METHODS_LEN + 8 +
1148 DEVICE_CATEGORY_MAX_LEN)) {
1149 p2p_err("Invalid Device info attr len %d",
1150 attr_len);
1151 return false;
1152 }
1153
1154 /* move by attr id and 2 bytes of attr len */
1155 pos = p2p_ie + 3;
1156
1157 /*
1158 * the P2P Device info is of format:
1159 * attr_id - 1 byte
1160 * attr_len - 2 bytes
1161 * device mac addr - 6 bytes
1162 * config methods - 2 bytes
1163 * primary device type - 8bytes
1164 * -primary device type category - 1 byte
1165 * -primary device type oui - 4bytes
1166 * number of secondary device type - 2 bytes
1167 */
1168 pos += ETH_ALEN + MAX_CONFIG_METHODS_LEN +
1169 DEVICE_CATEGORY_MAX_LEN;
1170
1171 if (!qdf_mem_cmp(pos, P2P_1X1_WAR_OUI,
1172 P2P_1X1_OUI_LEN))
1173 return true;
1174
1175 break;
1176 default:
1177 p2p_err("Invalid P2P attribute");
1178 break;
1179 }
1180 p2p_ie += (3 + attr_len);
1181 rem_len -= (3 + attr_len);
1182 }
1183
1184 return false;
1185}
1186
Rachit Kankanea06b0282018-07-31 16:26:38 +05301187#ifdef FEATURE_P2P_LISTEN_OFFLOAD
Wu Gao53531c52017-02-16 11:39:12 +08001188QDF_STATUS p2p_process_lo_stop(
1189 struct p2p_lo_stop_event *lo_stop_event)
1190{
Wu Gaod16c4e52017-03-06 14:00:02 +08001191 struct p2p_lo_event *lo_evt;
1192 struct p2p_soc_priv_obj *p2p_soc_obj;
1193 struct p2p_start_param *start_param;
1194
1195 if (!lo_stop_event) {
1196 p2p_err("invalid lo stop event");
1197 return QDF_STATUS_E_INVAL;
1198 }
Wu Gao295b1002017-11-02 11:53:50 +08001199
Wu Gaod16c4e52017-03-06 14:00:02 +08001200 lo_evt = lo_stop_event->lo_event;
Wu Gao295b1002017-11-02 11:53:50 +08001201 if (!lo_evt) {
1202 p2p_err("invalid lo event");
1203 return QDF_STATUS_E_INVAL;
1204 }
1205
Wu Gaod16c4e52017-03-06 14:00:02 +08001206 p2p_soc_obj = lo_stop_event->p2p_soc_obj;
1207
1208 p2p_debug("vdev_id %d, reason %d",
1209 lo_evt->vdev_id, lo_evt->reason_code);
1210
1211 if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) {
1212 p2p_err("Invalid p2p soc object or start parameters");
Wu Gao295b1002017-11-02 11:53:50 +08001213 qdf_mem_free(lo_evt);
Wu Gaod16c4e52017-03-06 14:00:02 +08001214 return QDF_STATUS_E_INVAL;
1215 }
1216 start_param = p2p_soc_obj->start_param;
1217 if (start_param->lo_event_cb)
1218 start_param->lo_event_cb(
1219 start_param->lo_event_cb_data, lo_evt);
1220 else
1221 p2p_err("Invalid p2p soc obj or hdd lo event callback");
1222
1223 qdf_mem_free(lo_evt);
1224
Wu Gao53531c52017-02-16 11:39:12 +08001225 return QDF_STATUS_SUCCESS;
1226}
Rachit Kankanea06b0282018-07-31 16:26:38 +05301227#endif
Wu Gao53531c52017-02-16 11:39:12 +08001228
1229QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event)
1230{
Wu Gaod16c4e52017-03-06 14:00:02 +08001231 QDF_STATUS status = QDF_STATUS_SUCCESS;
1232 struct p2p_noa_info *noa_info;
1233 struct p2p_vdev_priv_obj *p2p_vdev_obj;
1234 struct p2p_soc_priv_obj *p2p_soc_obj;
1235 struct wlan_objmgr_vdev *vdev;
1236 struct wlan_objmgr_psoc *psoc;
Jeff Johnson8713e342017-11-09 09:54:12 -08001237 enum QDF_OPMODE mode;
Wu Gaod16c4e52017-03-06 14:00:02 +08001238
1239 if (!noa_event) {
1240 p2p_err("invalid noa event");
1241 return QDF_STATUS_E_INVAL;
1242 }
1243 noa_info = noa_event->noa_info;
1244 p2p_soc_obj = noa_event->p2p_soc_obj;
1245 psoc = p2p_soc_obj->soc;
1246
Jeff Johnsondc3f8222017-09-18 10:07:54 -07001247 p2p_debug("psoc:%pK, index:%d, opps_ps:%d, ct_window:%d, num_desc:%d, vdev_id:%d",
Wu Gaod16c4e52017-03-06 14:00:02 +08001248 psoc, noa_info->index, noa_info->opps_ps,
1249 noa_info->ct_window, noa_info->num_desc,
1250 noa_info->vdev_id);
1251
1252 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc,
1253 noa_info->vdev_id, WLAN_P2P_ID);
1254 if (!vdev) {
1255 p2p_err("vdev obj is NULL");
1256 qdf_mem_free(noa_event->noa_info);
1257 return QDF_STATUS_E_INVAL;
1258 }
1259
Wu Gaod16c4e52017-03-06 14:00:02 +08001260 mode = wlan_vdev_mlme_get_opmode(vdev);
Wu Gaod16c4e52017-03-06 14:00:02 +08001261 p2p_debug("vdev mode:%d", mode);
1262 if (mode != QDF_P2P_GO_MODE) {
1263 p2p_err("invalid p2p vdev mode:%d", mode);
1264 status = QDF_STATUS_E_INVAL;
1265 goto fail;
1266 }
1267
1268 /* must send noa to pe since of limitation*/
1269 p2p_send_noa_to_pe(noa_info);
1270
1271 p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev,
1272 WLAN_UMAC_COMP_P2P);
1273 if (!(p2p_vdev_obj->noa_info)) {
1274 p2p_vdev_obj->noa_info =
1275 qdf_mem_malloc(sizeof(struct p2p_noa_info));
1276 if (!(p2p_vdev_obj->noa_info)) {
1277 p2p_err("Failed to allocate p2p noa info");
1278 status = QDF_STATUS_E_NOMEM;
1279 goto fail;
1280 }
1281 }
1282 qdf_mem_copy(p2p_vdev_obj->noa_info, noa_info,
1283 sizeof(struct p2p_noa_info));
1284fail:
1285 qdf_mem_free(noa_event->noa_info);
1286 wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID);
1287
1288 return status;
Wu Gao53531c52017-02-16 11:39:12 +08001289}
Rachit Kankane3abaf942017-04-19 11:49:18 +05301290
1291void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr)
1292{
1293 QDF_STATUS status;
1294 struct wlan_objmgr_psoc *psoc;
1295 struct wlan_objmgr_peer *peer;
Amir Patel0b19b4b2018-05-03 23:01:08 +05301296 uint8_t pdev_id;
Rachit Kankane3abaf942017-04-19 11:49:18 +05301297
1298 if (!vdev) {
Jeff Johnsondc3f8222017-09-18 10:07:54 -07001299 p2p_err("vdev:%pK", vdev);
Rachit Kankane3abaf942017-04-19 11:49:18 +05301300 return;
1301 }
Rachit Kankane3abaf942017-04-19 11:49:18 +05301302 psoc = wlan_vdev_get_psoc(vdev);
Rachit Kankane3abaf942017-04-19 11:49:18 +05301303 if (!psoc) {
Jeff Johnsondc3f8222017-09-18 10:07:54 -07001304 p2p_err("psoc:%pK", psoc);
Rachit Kankane3abaf942017-04-19 11:49:18 +05301305 return;
1306 }
Amir Patel0b19b4b2018-05-03 23:01:08 +05301307 pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev));
1308 peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_P2P_ID);
Rachit Kankane3abaf942017-04-19 11:49:18 +05301309 if (!peer) {
1310 p2p_debug("peer info not found");
1311 return;
1312 }
1313 status = process_peer_for_noa(vdev, psoc, peer);
1314 wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID);
1315
1316 if (status != QDF_STATUS_SUCCESS) {
1317 p2p_err("status:%u", status);
1318 return;
1319 }
1320 p2p_debug("peer is authorized");
1321}
Wu Gao8f099b82017-09-07 17:42:15 +08001322
1323#ifdef WLAN_FEATURE_P2P_DEBUG
1324static struct p2p_soc_priv_obj *
1325get_p2p_soc_obj_by_vdev(struct wlan_objmgr_vdev *vdev)
1326{
1327 struct p2p_soc_priv_obj *p2p_soc_obj;
1328 struct wlan_objmgr_psoc *soc;
1329
1330 if (!vdev) {
1331 p2p_err("vdev context passed is NULL");
1332 return NULL;
1333 }
1334
1335 soc = wlan_vdev_get_psoc(vdev);
1336 if (!soc) {
1337 p2p_err("soc context is NULL");
1338 return NULL;
1339 }
1340
1341 p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc,
1342 WLAN_UMAC_COMP_P2P);
1343 if (!p2p_soc_obj)
1344 p2p_err("P2P soc context is NULL");
1345
1346 return p2p_soc_obj;
1347}
1348
1349QDF_STATUS p2p_status_scan(struct wlan_objmgr_vdev *vdev)
1350{
1351 struct p2p_soc_priv_obj *p2p_soc_obj;
Jeff Johnson8713e342017-11-09 09:54:12 -08001352 enum QDF_OPMODE mode;
Wu Gao8f099b82017-09-07 17:42:15 +08001353
1354 p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev);
1355 if (!p2p_soc_obj) {
1356 p2p_err("P2P soc context is NULL");
1357 return QDF_STATUS_E_FAILURE;
1358 }
1359
1360 mode = wlan_vdev_mlme_get_opmode(vdev);
1361 if (mode != QDF_P2P_CLIENT_MODE &&
1362 mode != QDF_P2P_DEVICE_MODE) {
1363 p2p_debug("this is not P2P CLIENT or DEVICE, mode:%d",
1364 mode);
1365 return QDF_STATUS_SUCCESS;
1366 }
1367
1368 p2p_debug("connection status:%d", p2p_soc_obj->connection_status);
1369 switch (p2p_soc_obj->connection_status) {
1370 case P2P_GO_NEG_COMPLETED:
1371 case P2P_GO_NEG_PROCESS:
1372 p2p_soc_obj->connection_status =
1373 P2P_CLIENT_CONNECTING_STATE_1;
1374 p2p_debug("[P2P State] Changing state from Go nego completed to Connection is started");
1375 p2p_debug("P2P Scanning is started for 8way Handshake");
1376 break;
1377 case P2P_CLIENT_DISCONNECTED_STATE:
1378 p2p_soc_obj->connection_status =
1379 P2P_CLIENT_CONNECTING_STATE_2;
1380 p2p_debug("[P2P State] Changing state from Disconnected state to Connection is started");
1381 p2p_debug("P2P Scanning is started for 4way Handshake");
1382 break;
1383 default:
1384 break;
1385 }
1386
1387 return QDF_STATUS_SUCCESS;
1388}
1389
1390QDF_STATUS p2p_status_connect(struct wlan_objmgr_vdev *vdev)
1391{
1392 struct p2p_soc_priv_obj *p2p_soc_obj;
Jeff Johnson8713e342017-11-09 09:54:12 -08001393 enum QDF_OPMODE mode;
Wu Gao8f099b82017-09-07 17:42:15 +08001394
1395 p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev);
1396 if (!p2p_soc_obj) {
1397 p2p_err("P2P soc context is NULL");
1398 return QDF_STATUS_E_FAILURE;
1399 }
1400
1401 mode = wlan_vdev_mlme_get_opmode(vdev);
1402 if (mode != QDF_P2P_CLIENT_MODE) {
1403 p2p_debug("this is not P2P CLIENT, mode:%d", mode);
1404 return QDF_STATUS_SUCCESS;
1405 }
1406
1407 p2p_debug("connection status:%d", p2p_soc_obj->connection_status);
1408 switch (p2p_soc_obj->connection_status) {
1409 case P2P_CLIENT_CONNECTING_STATE_1:
1410 p2p_soc_obj->connection_status =
1411 P2P_CLIENT_CONNECTED_STATE_1;
1412 p2p_debug("[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
1413 break;
1414 case P2P_CLIENT_DISCONNECTED_STATE:
1415 p2p_debug("No scan before 4-way handshake");
1416 /*
1417 * Fall thru since no scan before 4-way handshake and
1418 * won't enter state P2P_CLIENT_CONNECTING_STATE_2:
1419 */
1420 case P2P_CLIENT_CONNECTING_STATE_2:
1421 p2p_soc_obj->connection_status =
1422 P2P_CLIENT_COMPLETED_STATE;
1423 p2p_debug("[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
1424 break;
1425 default:
1426 break;
1427 }
1428
1429 return QDF_STATUS_SUCCESS;
1430}
1431
1432QDF_STATUS p2p_status_disconnect(struct wlan_objmgr_vdev *vdev)
1433{
1434 struct p2p_soc_priv_obj *p2p_soc_obj;
Jeff Johnson8713e342017-11-09 09:54:12 -08001435 enum QDF_OPMODE mode;
Wu Gao8f099b82017-09-07 17:42:15 +08001436
1437 p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev);
1438 if (!p2p_soc_obj) {
1439 p2p_err("P2P soc context is NULL");
1440 return QDF_STATUS_E_FAILURE;
1441 }
1442
1443 mode = wlan_vdev_mlme_get_opmode(vdev);
1444 if (mode != QDF_P2P_CLIENT_MODE) {
1445 p2p_debug("this is not P2P CLIENT, mode:%d", mode);
1446 return QDF_STATUS_SUCCESS;
1447 }
1448
1449 p2p_debug("connection status:%d", p2p_soc_obj->connection_status);
1450 switch (p2p_soc_obj->connection_status) {
1451 case P2P_CLIENT_CONNECTED_STATE_1:
1452 p2p_soc_obj->connection_status =
1453 P2P_CLIENT_DISCONNECTED_STATE;
1454 p2p_debug("[P2P State] 8 way Handshake completed and moved to disconnected state");
1455 break;
1456 case P2P_CLIENT_COMPLETED_STATE:
1457 p2p_soc_obj->connection_status = P2P_NOT_ACTIVE;
1458 p2p_debug("[P2P State] P2P Client is removed and moved to inactive state");
1459 break;
1460 default:
1461 break;
1462 }
1463
1464 return QDF_STATUS_SUCCESS;
1465}
1466
1467QDF_STATUS p2p_status_start_bss(struct wlan_objmgr_vdev *vdev)
1468{
1469 struct p2p_soc_priv_obj *p2p_soc_obj;
Jeff Johnson8713e342017-11-09 09:54:12 -08001470 enum QDF_OPMODE mode;
Wu Gao8f099b82017-09-07 17:42:15 +08001471
1472 p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev);
1473 if (!p2p_soc_obj) {
1474 p2p_err("P2P soc context is NULL");
1475 return QDF_STATUS_E_FAILURE;
1476 }
1477
1478 mode = wlan_vdev_mlme_get_opmode(vdev);
1479 if (mode != QDF_P2P_GO_MODE) {
1480 p2p_debug("this is not P2P GO, mode:%d", mode);
1481 return QDF_STATUS_SUCCESS;
1482 }
1483
1484 p2p_debug("connection status:%d", p2p_soc_obj->connection_status);
1485 switch (p2p_soc_obj->connection_status) {
1486 case P2P_GO_NEG_COMPLETED:
1487 p2p_soc_obj->connection_status =
1488 P2P_GO_COMPLETED_STATE;
1489 p2p_debug("[P2P State] From Go nego completed to Non-autonomous Group started");
1490 break;
1491 case P2P_NOT_ACTIVE:
1492 p2p_soc_obj->connection_status =
1493 P2P_GO_COMPLETED_STATE;
1494 p2p_debug("[P2P State] From Inactive to Autonomous Group started");
1495 break;
1496 default:
1497 break;
1498 }
1499
1500 return QDF_STATUS_SUCCESS;
1501}
1502
1503QDF_STATUS p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev)
1504{
1505 struct p2p_soc_priv_obj *p2p_soc_obj;
Jeff Johnson8713e342017-11-09 09:54:12 -08001506 enum QDF_OPMODE mode;
Wu Gao8f099b82017-09-07 17:42:15 +08001507
1508 p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev);
1509 if (!p2p_soc_obj) {
1510 p2p_err("P2P soc context is NULL");
1511 return QDF_STATUS_E_FAILURE;
1512 }
1513
1514 mode = wlan_vdev_mlme_get_opmode(vdev);
1515 if (mode != QDF_P2P_GO_MODE) {
1516 p2p_debug("this is not P2P GO, mode:%d", mode);
1517 return QDF_STATUS_SUCCESS;
1518 }
1519
1520 p2p_debug("connection status:%d", p2p_soc_obj->connection_status);
1521 if (p2p_soc_obj->connection_status == P2P_GO_COMPLETED_STATE) {
1522 p2p_soc_obj->connection_status = P2P_NOT_ACTIVE;
1523 p2p_debug("[P2P State] From GO completed to Inactive state GO got removed");
1524 }
1525
1526 return QDF_STATUS_SUCCESS;
1527}
Pragaspathi Thilagarajb3472f02019-06-04 14:10:44 +05301528
Wu Gao8f099b82017-09-07 17:42:15 +08001529#endif /* WLAN_FEATURE_P2P_DEBUG */