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