1 /*
2 * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 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: wma_nan_datapath.c
22 *
23 * WMA NAN Data path API implementation
24 */
25
26 #include "wma.h"
27 #include "wma_api.h"
28 #include "wmi_unified_api.h"
29 #include "wmi_unified.h"
30 #include "wma_nan_datapath.h"
31 #include "wma_internal.h"
32 #include "cds_utils.h"
33 #include "cdp_txrx_peer_ops.h"
34 #include "cdp_txrx_tx_delay.h"
35 #include "cdp_txrx_misc.h"
36 #include <cdp_txrx_handle.h>
37
wma_add_sta_ndi_mode(tp_wma_handle wma,tpAddStaParams add_sta)38 QDF_STATUS wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta)
39 {
40 enum ol_txrx_peer_state state = OL_TXRX_PEER_STATE_CONN;
41 uint8_t pdev_id = WMI_PDEV_ID_SOC;
42 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
43 QDF_STATUS status;
44 struct wma_txrx_node *iface;
45
46 iface = &wma->interfaces[add_sta->smesessionId];
47 wma_debug("vdev: %d, peer_mac_addr: "QDF_MAC_ADDR_FMT,
48 add_sta->smesessionId, QDF_MAC_ADDR_REF(add_sta->staMac));
49
50 if (cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId,
51 add_sta->staMac)) {
52 wma_err("NDI peer already exists, peer_addr "QDF_MAC_ADDR_FMT,
53 QDF_MAC_ADDR_REF(add_sta->staMac));
54 add_sta->status = QDF_STATUS_E_EXISTS;
55 goto send_rsp;
56 }
57
58 /*
59 * The code above only checks the peer existence on its own vdev.
60 * Need to check whether the peer exists on other vDevs because firmware
61 * can't create the peer if the peer with same MAC address already
62 * exists on the pDev. As this peer belongs to other vDevs, just return
63 * here.
64 */
65 if (cdp_find_peer_exist(soc, pdev_id, add_sta->staMac)) {
66 wma_err("peer exists on other vdev with peer_addr "QDF_MAC_ADDR_FMT,
67 QDF_MAC_ADDR_REF(add_sta->staMac));
68 add_sta->status = QDF_STATUS_E_EXISTS;
69 goto send_rsp;
70 }
71
72 status = wma_create_peer(wma, add_sta->staMac,
73 WMI_PEER_TYPE_NAN_DATA, add_sta->smesessionId,
74 NULL, false);
75 if (status != QDF_STATUS_SUCCESS) {
76 wma_err("Failed to create peer for "QDF_MAC_ADDR_FMT,
77 QDF_MAC_ADDR_REF(add_sta->staMac));
78 add_sta->status = status;
79 goto send_rsp;
80 }
81
82 if (!cdp_find_peer_exist_on_vdev(soc, add_sta->smesessionId,
83 add_sta->staMac)) {
84 wma_err("Failed to find peer handle using peer mac "QDF_MAC_ADDR_FMT,
85 QDF_MAC_ADDR_REF(add_sta->staMac));
86 add_sta->status = QDF_STATUS_E_FAILURE;
87 wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId,
88 false);
89 goto send_rsp;
90 }
91
92 wma_debug("Moving peer "QDF_MAC_ADDR_FMT" to state %d",
93 QDF_MAC_ADDR_REF(add_sta->staMac), state);
94 cdp_peer_state_update(soc, add_sta->staMac, state);
95
96 add_sta->nss = iface->nss;
97 add_sta->status = QDF_STATUS_SUCCESS;
98 send_rsp:
99 status = add_sta->status;
100 wma_debug("Sending add sta rsp to umac (mac:"QDF_MAC_ADDR_FMT", status:%d)",
101 QDF_MAC_ADDR_REF(add_sta->staMac), add_sta->status);
102
103 wma_send_msg_high_priority(wma, WMA_ADD_STA_RSP, (void *)add_sta, 0);
104
105 return status;
106 }
107
wma_delete_sta_req_ndi_mode(tp_wma_handle wma,tpDeleteStaParams del_sta)108 QDF_STATUS wma_delete_sta_req_ndi_mode(tp_wma_handle wma,
109 tpDeleteStaParams del_sta)
110 {
111 QDF_STATUS status;
112
113 status = wma_remove_peer(wma, del_sta->staMac,
114 del_sta->smesessionId, false);
115 del_sta->status = QDF_STATUS_SUCCESS;
116
117 if (del_sta->respReqd) {
118 wma_debug("Sending del rsp to umac (status: %d)",
119 del_sta->status);
120 wma_send_msg_high_priority(wma, WMA_DELETE_STA_RSP, del_sta, 0);
121 } else {
122 wma_debug("NDI Del Sta resp not needed");
123 qdf_mem_free(del_sta);
124 }
125
126 return status;
127 }
128