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 #include "osif_sync.h"
21 #include "qdf_str.h"
22 #include "qdf_trace.h"
23 #include "qdf_types.h"
24 #include "wlan_osif_priv.h"
25 #include <net/cfg80211.h>
26 #include "wlan_cfg80211.h"
27 #include "wlan_objmgr_psoc_obj.h"
28 #include "wlan_objmgr_pdev_obj.h"
29 #include "wlan_objmgr_vdev_obj.h"
30 #include "wlan_utility.h"
31 #include "wlan_osif_request_manager.h"
32 #include "wlan_mlme_ucfg_api.h"
33 #include "wlan_pkt_capture_ucfg_api.h"
34 #include "os_if_pkt_capture.h"
35 #include "wlan_hdd_main.h"
36 #include "cfg_ucfg_api.h"
37 #include "wlan_hdd_object_manager.h"
38
39 #ifdef WLAN_FEATURE_PKT_CAPTURE
40
41 const struct nla_policy
42 set_monitor_mode_policy[SET_MONITOR_MODE_CONFIG_MAX + 1] = {
43 [SET_MONITOR_MODE_INVALID] = {
44 .type = NLA_U32
45 },
46 [SET_MONITOR_MODE_DATA_TX_FRAME_TYPE] = {
47 .type = NLA_U32
48 },
49 [SET_MONITOR_MODE_DATA_RX_FRAME_TYPE] = {
50 .type = NLA_U32
51 },
52 [SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE] = {
53 .type = NLA_U32
54 },
55 [SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE] = {
56 .type = NLA_U32
57 },
58 [SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE] = {
59 .type = NLA_U32
60 },
61 [SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE] = {
62 .type = NLA_U32
63 },
64 [SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL] = {
65 .type = NLA_U32
66 },
67 };
68
os_if_monitor_mode_configure(struct hdd_adapter * adapter,const void * data,int data_len)69 QDF_STATUS os_if_monitor_mode_configure(struct hdd_adapter *adapter,
70 const void *data, int data_len)
71 {
72 struct pkt_capture_frame_filter frame_filter = {0};
73 struct wlan_objmgr_vdev *vdev;
74 struct nlattr *tb[SET_MONITOR_MODE_CONFIG_MAX + 1];
75 QDF_STATUS status;
76
77 vdev = hdd_objmgr_get_vdev_by_user(adapter->deflink,
78 WLAN_PKT_CAPTURE_ID);
79 if (!vdev)
80 return QDF_STATUS_E_INVAL;
81
82 if (wlan_cfg80211_nla_parse(tb, SET_MONITOR_MODE_CONFIG_MAX,
83 data, data_len, set_monitor_mode_policy)) {
84 osif_err("invalid monitor attr");
85 hdd_objmgr_put_vdev_by_user(vdev, WLAN_PKT_CAPTURE_ID);
86 return QDF_STATUS_E_INVAL;
87 }
88
89 if (tb[SET_MONITOR_MODE_INVALID]) {
90 hdd_objmgr_put_vdev_by_user(vdev, WLAN_PKT_CAPTURE_ID);
91 return QDF_STATUS_E_FAILURE;
92 }
93
94 if (tb[SET_MONITOR_MODE_DATA_TX_FRAME_TYPE] &&
95 nla_get_u32(tb[SET_MONITOR_MODE_DATA_TX_FRAME_TYPE]) <
96 PACKET_CAPTURE_DATA_MAX_FILTER) {
97 frame_filter.data_tx_frame_filter =
98 nla_get_u32(tb[SET_MONITOR_MODE_DATA_TX_FRAME_TYPE]);
99 frame_filter.vendor_attr_to_set =
100 BIT(SET_MONITOR_MODE_DATA_TX_FRAME_TYPE);
101 }
102
103 if (tb[SET_MONITOR_MODE_DATA_RX_FRAME_TYPE] &&
104 nla_get_u32(tb[SET_MONITOR_MODE_DATA_RX_FRAME_TYPE]) <
105 PACKET_CAPTURE_DATA_MAX_FILTER) {
106 frame_filter.data_rx_frame_filter =
107 nla_get_u32(tb[SET_MONITOR_MODE_DATA_RX_FRAME_TYPE]);
108 frame_filter.vendor_attr_to_set |=
109 BIT(SET_MONITOR_MODE_DATA_RX_FRAME_TYPE);
110 }
111
112 if (tb[SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE] &&
113 nla_get_u32(tb[SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE]) <
114 PACKET_CAPTURE_MGMT_MAX_FILTER) {
115 frame_filter.mgmt_tx_frame_filter =
116 nla_get_u32(tb[SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE]);
117 frame_filter.vendor_attr_to_set |=
118 BIT(SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE);
119 }
120
121 if (tb[SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE] &&
122 nla_get_u32(tb[SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE]) <
123 PACKET_CAPTURE_MGMT_MAX_FILTER) {
124 frame_filter.mgmt_rx_frame_filter =
125 nla_get_u32(tb[SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE]);
126 frame_filter.vendor_attr_to_set |=
127 BIT(SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE);
128 }
129
130 if (tb[SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE] &&
131 nla_get_u32(tb[SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE]) <
132 PACKET_CAPTURE_CTRL_MAX_FILTER) {
133 frame_filter.ctrl_tx_frame_filter =
134 nla_get_u32(tb[SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE]);
135 frame_filter.vendor_attr_to_set |=
136 BIT(SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE);
137 }
138
139 if (tb[SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE] &&
140 nla_get_u32(tb[SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE]) <
141 PACKET_CAPTURE_CTRL_MAX_FILTER) {
142 frame_filter.ctrl_rx_frame_filter =
143 nla_get_u32(tb[SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE]);
144 frame_filter.vendor_attr_to_set |=
145 BIT(SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE);
146 }
147
148 if (tb[SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL]) {
149 frame_filter.connected_beacon_interval =
150 nla_get_u32(tb[SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL]);
151 frame_filter.vendor_attr_to_set |=
152 BIT(SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL);
153 }
154
155 osif_debug("Monitor mode config data tx %d data rx %d mgmt tx %d mgmt rx %d ctrl tx %d ctrl rx %d bi %d\n",
156 frame_filter.data_tx_frame_filter,
157 frame_filter.data_rx_frame_filter,
158 frame_filter.mgmt_tx_frame_filter,
159 frame_filter.mgmt_rx_frame_filter,
160 frame_filter.ctrl_tx_frame_filter,
161 frame_filter.ctrl_rx_frame_filter,
162 frame_filter.connected_beacon_interval);
163
164 status = ucfg_pkt_capture_set_filter(frame_filter, vdev);
165 hdd_objmgr_put_vdev_by_user(vdev, WLAN_PKT_CAPTURE_ID);
166
167 return status;
168 }
169
170 #undef SET_MONITOR_MODE_CONFIG_MAX
171 #undef SET_MONITOR_MODE_INVALID
172 #undef SET_MONITOR_MODE_DATA_TX_FRAME_TYPE
173 #undef SET_MONITOR_MODE_DATA_RX_FRAME_TYPE
174 #undef SET_MONITOR_MODE_MGMT_TX_FRAME_TYPE
175 #undef SET_MONITOR_MODE_MGMT_RX_FRAME_TYPE
176 #undef SET_MONITOR_MODE_CTRL_TX_FRAME_TYPE
177 #undef SET_MONITOR_MODE_CTRL_RX_FRAME_TYPE
178 #undef SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL
179
180 #endif
181