blob: df39148aa095e6005d4f4454351d34ad42454569 [file] [log] [blame]
Wu Gao76b2a2f2017-03-15 19:12:20 +08001/*
Abhishek Ambure74709762019-05-27 19:43:26 +05302 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
Wu Gao76b2a2f2017-03-15 19:12:20 +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: offload lmac interface APIs definitions for P2P
21 */
22
23#include <wmi_unified_api.h>
24#include <wlan_p2p_public_struct.h>
25#include "target_if.h"
26#include "target_if_p2p.h"
Akshay Kosigi6e91ab82018-02-28 22:37:24 +053027#include "init_deinit_lmac.h"
Wu Gao76b2a2f2017-03-15 19:12:20 +080028
29static inline struct wlan_lmac_if_p2p_rx_ops *
30target_if_psoc_get_p2p_rx_ops(struct wlan_objmgr_psoc *psoc)
31{
32 return &(psoc->soc_cb.rx_ops.p2p);
33}
34
Rachit Kankane8c188ac2018-07-31 16:26:38 +053035#ifdef FEATURE_P2P_LISTEN_OFFLOAD
36static inline void
37target_if_p2p_lo_register_tx_ops(struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops)
38{
39 p2p_tx_ops->lo_start = target_if_p2p_lo_start;
40 p2p_tx_ops->lo_stop = target_if_p2p_lo_stop;
41 p2p_tx_ops->reg_lo_ev_handler =
42 target_if_p2p_register_lo_event_handler;
43 p2p_tx_ops->unreg_lo_ev_handler =
44 target_if_p2p_unregister_lo_event_handler;
45}
46
Wu Gao76b2a2f2017-03-15 19:12:20 +080047/**
48 * target_p2p_lo_event_handler() - WMI callback for lo stop event
Wu Gao31675f52017-03-13 20:17:34 +080049 * @scn: pointer to scn
Wu Gao76b2a2f2017-03-15 19:12:20 +080050 * @event_buf: event buffer
Wu Gao31675f52017-03-13 20:17:34 +080051 * @len: buffer length
Wu Gao76b2a2f2017-03-15 19:12:20 +080052 *
53 * This function gets called from WMI when triggered wmi event
54 * wmi_p2p_lo_stop_event_id.
55 *
56 * Return: 0 - success
57 * others - failure
58 */
59static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data,
60 uint32_t datalen)
61{
62 struct wlan_objmgr_psoc *psoc;
63 struct wmi_unified *wmi_handle;
64 struct p2p_lo_event *event_info;
65 struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops;
66 QDF_STATUS status = QDF_STATUS_E_FAILURE;
67
Jeff Johnsond1f5b2d2017-09-18 10:09:05 -070068 target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, data, datalen);
Wu Gao76b2a2f2017-03-15 19:12:20 +080069
70 if (!scn || !data) {
Jeff Johnsond1f5b2d2017-09-18 10:09:05 -070071 target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
Wu Gao76b2a2f2017-03-15 19:12:20 +080072 return -EINVAL;
73 }
74
75 psoc = target_if_get_psoc_from_scn_hdl(scn);
76 if (!psoc) {
77 target_if_err("null psoc");
78 return -EINVAL;
79 }
80
Akshay Kosigi59cc7652018-02-06 16:02:25 +053081 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
Wu Gao76b2a2f2017-03-15 19:12:20 +080082 if (!wmi_handle) {
83 target_if_err("null wmi handle");
84 return -EINVAL;
85 }
86
87 event_info = qdf_mem_malloc(sizeof(*event_info));
88 if (!event_info) {
89 target_if_err("Failed to allocate p2p lo event");
90 return -ENOMEM;
91 }
92
Wu Gao31675f52017-03-13 20:17:34 +080093 if (wmi_extract_p2p_lo_stop_ev_param(wmi_handle, data,
94 event_info)) {
95 target_if_err("Failed to extract wmi p2p lo stop event");
96 qdf_mem_free(event_info);
97 return -EINVAL;
98 }
Wu Gao76b2a2f2017-03-15 19:12:20 +080099
100 p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc);
101 if (p2p_rx_ops->lo_ev_handler) {
102 status = p2p_rx_ops->lo_ev_handler(psoc, event_info);
103 target_if_debug("call lo event handler, status:%d",
104 status);
Wu Gaoe2142702017-05-09 19:47:37 +0800105 } else {
106 qdf_mem_free(event_info);
107 target_if_debug("no valid lo event handler");
Wu Gao76b2a2f2017-03-15 19:12:20 +0800108 }
109
110 return qdf_status_to_os_return(status);
111}
112
Rachit Kankane8c188ac2018-07-31 16:26:38 +0530113QDF_STATUS target_if_p2p_register_lo_event_handler(
114 struct wlan_objmgr_psoc *psoc, void *arg)
115{
116 int status;
117 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
118
119 target_if_debug("psoc:%pK, arg:%pK", psoc, arg);
120
121 if (!wmi_handle) {
122 target_if_err("Invalid wmi handle");
123 return QDF_STATUS_E_INVAL;
124 }
125
126 status = wmi_unified_register_event(wmi_handle,
127 wmi_p2p_lo_stop_event_id,
128 target_p2p_lo_event_handler);
129
130 target_if_debug("wmi register lo event handle, status:%d", status);
131
132 return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
133}
134
135QDF_STATUS target_if_p2p_unregister_lo_event_handler(
136 struct wlan_objmgr_psoc *psoc, void *arg)
137{
138 int status;
139 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
140
141 target_if_debug("psoc:%pK, arg:%pK", psoc, arg);
142
143 if (!wmi_handle) {
144 target_if_err("Invalid wmi handle");
145 return QDF_STATUS_E_INVAL;
146 }
147
148 status = wmi_unified_unregister_event(wmi_handle,
149 wmi_p2p_lo_stop_event_id);
150
151 target_if_debug("wmi unregister lo event handle, status:%d", status);
152
153 return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
154}
155
156QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc,
157 struct p2p_lo_start *lo_start)
158{
159 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
160
161 if (!wmi_handle) {
162 target_if_err("Invalid wmi handle");
163 return QDF_STATUS_E_INVAL;
164 }
165
166 if (!lo_start) {
167 target_if_err("lo start parameters is null");
168 return QDF_STATUS_E_INVAL;
169 }
170 target_if_debug("psoc:%pK, vdev_id:%d", psoc, lo_start->vdev_id);
171
172 return wmi_unified_p2p_lo_start_cmd(wmi_handle, lo_start);
173}
174
175QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc,
176 uint32_t vdev_id)
177{
178 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
179
180 target_if_debug("psoc:%pK, vdev_id:%d", psoc, vdev_id);
181
182 if (!wmi_handle) {
183 target_if_err("Invalid wmi handle");
184 return QDF_STATUS_E_INVAL;
185 }
186
187 return wmi_unified_p2p_lo_stop_cmd(wmi_handle,
188 (uint8_t)vdev_id);
189}
190#else
191static inline void
192target_if_p2p_lo_register_tx_ops(struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops)
193{
194}
195#endif /* FEATURE_P2P_LISTEN_OFFLOAD */
196
Wu Gao76b2a2f2017-03-15 19:12:20 +0800197/**
198 * target_p2p_noa_event_handler() - WMI callback for noa event
Wu Gao31675f52017-03-13 20:17:34 +0800199 * @scn: pointer to scn
Wu Gao76b2a2f2017-03-15 19:12:20 +0800200 * @event_buf: event buffer
Wu Gao31675f52017-03-13 20:17:34 +0800201 * @len: buffer length
Wu Gao76b2a2f2017-03-15 19:12:20 +0800202 *
203 * This function gets called from WMI when triggered WMI event
204 * wmi_p2p_noa_event_id.
205 *
206 * Return: 0 - success
207 * others - failure
208 */
209static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data,
210 uint32_t datalen)
211{
212 struct wlan_objmgr_psoc *psoc;
213 struct wmi_unified *wmi_handle;
214 struct p2p_noa_info *event_info;
215 struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops;
216 QDF_STATUS status = QDF_STATUS_E_FAILURE;
217
Jeff Johnsond1f5b2d2017-09-18 10:09:05 -0700218 target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, data, datalen);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800219
220 if (!scn || !data) {
Jeff Johnsond1f5b2d2017-09-18 10:09:05 -0700221 target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800222 return -EINVAL;
223 }
224
225 psoc = target_if_get_psoc_from_scn_hdl(scn);
226 if (!psoc) {
227 target_if_err("null psoc");
228 return -EINVAL;
229 }
230
Akshay Kosigi59cc7652018-02-06 16:02:25 +0530231 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800232 if (!wmi_handle) {
233 target_if_err("null wmi handle");
234 return -EINVAL;
235 }
236
237 event_info = qdf_mem_malloc(sizeof(*event_info));
238 if (!event_info) {
Wu Gao31675f52017-03-13 20:17:34 +0800239 target_if_err("failed to allocate p2p noa information");
Wu Gao76b2a2f2017-03-15 19:12:20 +0800240 return -ENOMEM;
241 }
242
Wu Gao31675f52017-03-13 20:17:34 +0800243 if (wmi_extract_p2p_noa_ev_param(wmi_handle, data,
244 event_info)) {
245 target_if_err("failed to extract wmi p2p noa event");
246 qdf_mem_free(event_info);
247 return -EINVAL;
248 }
Wu Gao76b2a2f2017-03-15 19:12:20 +0800249
250 p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc);
251 if (p2p_rx_ops->noa_ev_handler) {
252 status = p2p_rx_ops->noa_ev_handler(psoc, event_info);
253 target_if_debug("call noa event handler, status:%d",
254 status);
Wu Gaoe2142702017-05-09 19:47:37 +0800255 } else {
256 qdf_mem_free(event_info);
257 target_if_debug("no valid noa event handler");
Wu Gao76b2a2f2017-03-15 19:12:20 +0800258 }
259
260 return qdf_status_to_os_return(status);
261}
262
Wu Gao76b2a2f2017-03-15 19:12:20 +0800263QDF_STATUS target_if_p2p_register_noa_event_handler(
264 struct wlan_objmgr_psoc *psoc, void *arg)
265{
266 int status;
Akshay Kosigi6e91ab82018-02-28 22:37:24 +0530267 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800268
Jeff Johnsond1f5b2d2017-09-18 10:09:05 -0700269 target_if_debug("psoc:%pK, arg:%pK", psoc, arg);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800270
271 if (!wmi_handle) {
272 target_if_err("Invalid wmi handle");
273 return QDF_STATUS_E_INVAL;
274 }
275
Wu Gao8ae831e2017-03-27 13:34:18 +0800276 status = wmi_unified_register_event(wmi_handle,
277 wmi_p2p_noa_event_id,
278 target_p2p_noa_event_handler);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800279
Wu Gao31675f52017-03-13 20:17:34 +0800280 target_if_debug("wmi register noa event handle, status:%d",
Wu Gao76b2a2f2017-03-15 19:12:20 +0800281 status);
282
283 return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
284}
285
Wu Gao76b2a2f2017-03-15 19:12:20 +0800286QDF_STATUS target_if_p2p_unregister_noa_event_handler(
287 struct wlan_objmgr_psoc *psoc, void *arg)
288{
289 int status;
Akshay Kosigi6e91ab82018-02-28 22:37:24 +0530290 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800291
Jeff Johnsond1f5b2d2017-09-18 10:09:05 -0700292 target_if_debug("psoc:%pK, arg:%pK", psoc, arg);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800293
294 if (!wmi_handle) {
295 target_if_err("Invalid wmi handle");
296 return QDF_STATUS_E_INVAL;
297 }
298
Wu Gao8ae831e2017-03-27 13:34:18 +0800299 status = wmi_unified_unregister_event(wmi_handle,
300 wmi_p2p_noa_event_id);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800301
Wu Gao31675f52017-03-13 20:17:34 +0800302 target_if_debug("wmi unregister noa event handle, status:%d",
Wu Gao76b2a2f2017-03-15 19:12:20 +0800303 status);
304
305 return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
306}
307
308QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc,
309 struct p2p_ps_config *ps_config)
310{
Wu Gao31675f52017-03-13 20:17:34 +0800311 struct p2p_ps_params cmd;
312 QDF_STATUS status;
Akshay Kosigi6e91ab82018-02-28 22:37:24 +0530313 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
Wu Gao31675f52017-03-13 20:17:34 +0800314
Wu Gao31675f52017-03-13 20:17:34 +0800315 if (!wmi_handle) {
316 target_if_err("Invalid wmi handle");
317 return QDF_STATUS_E_INVAL;
318 }
319
320 if (!ps_config) {
321 target_if_err("ps config parameters is null");
322 return QDF_STATUS_E_INVAL;
323 }
324
Varun Reddy Yeturu21399d22018-01-04 16:25:06 -0800325 target_if_debug("psoc:%pK, vdev_id:%d, opp_ps:%d", psoc,
326 ps_config->vdev_id, ps_config->opp_ps);
327
Wu Gao31675f52017-03-13 20:17:34 +0800328 cmd.opp_ps = ps_config->opp_ps;
329 cmd.ctwindow = ps_config->ct_window;
330 cmd.count = ps_config->count;
331 cmd.duration = ps_config->duration;
332 cmd.interval = ps_config->interval;
333 cmd.single_noa_duration = ps_config->single_noa_duration;
334 cmd.ps_selection = ps_config->ps_selection;
335 cmd.session_id = ps_config->vdev_id;
336
337 if (ps_config->opp_ps)
338 status = wmi_unified_set_p2pgo_oppps_req(wmi_handle,
339 &cmd);
340 else
341 status = wmi_unified_set_p2pgo_noa_req_cmd(wmi_handle,
342 &cmd);
343
344 if (status != QDF_STATUS_SUCCESS)
345 target_if_err("Failed to send set uapsd param, %d",
346 status);
347
348 return status;
Wu Gao76b2a2f2017-03-15 19:12:20 +0800349}
350
Rachit Kankane289076b2017-04-19 11:49:18 +0530351QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc,
352 uint32_t vdev_id, bool disable_noa)
353{
354 struct vdev_set_params param;
Akshay Kosigi6e91ab82018-02-28 22:37:24 +0530355 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
Rachit Kankane289076b2017-04-19 11:49:18 +0530356
357 if (!wmi_handle) {
358 target_if_err("Invalid wmi handle");
359 return QDF_STATUS_E_INVAL;
360 }
361
Jeff Johnsond1f5b2d2017-09-18 10:09:05 -0700362 target_if_debug("psoc:%pK, vdev_id:%d disable_noa:%d",
Rachit Kankane289076b2017-04-19 11:49:18 +0530363 psoc, vdev_id, disable_noa);
Abhishek Ambure74709762019-05-27 19:43:26 +0530364 param.vdev_id = vdev_id;
Rachit Kankane289076b2017-04-19 11:49:18 +0530365 param.param_id = WMI_VDEV_PARAM_DISABLE_NOA_P2P_GO;
366 param.param_value = (uint32_t)disable_noa;
367
368 return wmi_unified_vdev_set_param_send(wmi_handle, &param);
369}
370
Liangwei Dongf0f79ff2018-09-19 23:35:14 -0400371static int target_p2p_mac_rx_filter_event_handler(ol_scn_t scn, uint8_t *data,
372 uint32_t datalen)
373{
374 struct wlan_objmgr_psoc *psoc;
375 struct wmi_unified *wmi_handle;
376 struct p2p_set_mac_filter_evt event_info;
377 struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops;
378 QDF_STATUS status = QDF_STATUS_E_FAILURE;
379
380 if (!scn || !data) {
381 target_if_err("scn: 0x%pK, data: 0x%pK", scn, data);
382 return -EINVAL;
383 }
384
385 psoc = target_if_get_psoc_from_scn_hdl(scn);
386 if (!psoc) {
387 target_if_err("null psoc");
388 return -EINVAL;
389 }
390
391 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc);
392 if (!wmi_handle) {
393 target_if_err("null wmi handle");
394 return -EINVAL;
395 }
396
397 if (wmi_extract_mac_addr_rx_filter_evt_param(wmi_handle, data,
398 &event_info)) {
399 target_if_err("failed to extract wmi p2p noa event");
400 return -EINVAL;
401 }
402 target_if_debug("vdev_id %d status %d", event_info.vdev_id,
403 event_info.status);
404 p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc);
405 if (p2p_rx_ops && p2p_rx_ops->add_mac_addr_filter_evt_handler)
406 status = p2p_rx_ops->add_mac_addr_filter_evt_handler(
407 psoc, &event_info);
408 else
409 target_if_debug("no add mac addr filter event handler");
410
411 return qdf_status_to_os_return(status);
412}
413
414static QDF_STATUS target_if_p2p_register_macaddr_rx_filter_evt_handler(
415 struct wlan_objmgr_psoc *psoc, bool reg)
416{
417 int status;
418 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
419
420 target_if_debug("psoc:%pK, register %d mac addr rx evt", psoc, reg);
421
422 if (!wmi_handle) {
423 target_if_err("Invalid wmi handle");
424 return QDF_STATUS_E_INVAL;
425 }
426 if (reg)
427 status = wmi_unified_register_event(
428 wmi_handle,
429 wmi_vdev_add_macaddr_rx_filter_event_id,
430 target_p2p_mac_rx_filter_event_handler);
431 else
432 status = wmi_unified_unregister_event(
433 wmi_handle,
434 wmi_vdev_add_macaddr_rx_filter_event_id);
435
436 return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
437}
438
439static QDF_STATUS target_if_p2p_set_mac_addr_rx_filter_cmd(
440 struct wlan_objmgr_psoc *psoc, struct p2p_set_mac_filter *param)
441{
442 wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc);
443
444 if (!wmi_handle) {
445 target_if_err("Invalid wmi handle");
446 return QDF_STATUS_E_INVAL;
447 }
448
449 return wmi_send_set_mac_addr_rx_filter_cmd(wmi_handle, param);
450}
451
Wu Gao76b2a2f2017-03-15 19:12:20 +0800452void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
453{
454 struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops;
455
456 if (!tx_ops) {
457 target_if_err("lmac tx_ops is null");
458 return;
459 }
460
461 p2p_tx_ops = &tx_ops->p2p;
462 p2p_tx_ops->set_ps = target_if_p2p_set_ps;
Rachit Kankane289076b2017-04-19 11:49:18 +0530463 p2p_tx_ops->set_noa = target_if_p2p_set_noa;
Wu Gao76b2a2f2017-03-15 19:12:20 +0800464 p2p_tx_ops->reg_noa_ev_handler =
465 target_if_p2p_register_noa_event_handler;
Wu Gao76b2a2f2017-03-15 19:12:20 +0800466 p2p_tx_ops->unreg_noa_ev_handler =
467 target_if_p2p_unregister_noa_event_handler;
Liangwei Dongf0f79ff2018-09-19 23:35:14 -0400468 p2p_tx_ops->reg_mac_addr_rx_filter_handler =
469 target_if_p2p_register_macaddr_rx_filter_evt_handler;
470 p2p_tx_ops->set_mac_addr_rx_filter_cmd =
471 target_if_p2p_set_mac_addr_rx_filter_cmd;
Rachit Kankane8c188ac2018-07-31 16:26:38 +0530472 /* register P2P listen offload callbacks */
473 target_if_p2p_lo_register_tx_ops(p2p_tx_ops);
Wu Gao76b2a2f2017-03-15 19:12:20 +0800474}