1 /* 2 * Copyright (c) 2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #ifndef _DP_MON_2_0_H_ 19 #define _DP_MON_2_0_H_ 20 21 #if !defined(DISABLE_MON_CONFIG) 22 #include <qdf_lock.h> 23 #include <dp_types.h> 24 #include <dp_mon.h> 25 #include <dp_mon_filter.h> 26 #include <dp_htt.h> 27 #include <dp_mon.h> 28 #include <dp_tx_mon_2.0.h> 29 30 #define DP_MON_RING_FILL_LEVEL_DEFAULT 2048 31 #define DP_MON_DATA_BUFFER_SIZE 2048 32 #define DP_MON_DESC_MAGIC 0xdeadabcd 33 #define DP_MON_MAX_STATUS_BUF 1200 34 #define DP_MON_QUEUE_DEPTH_MAX 16 35 #define DP_MON_MSDU_LOGGING 0 36 #define DP_MON_MPDU_LOGGING 1 37 38 #define DP_MON_DECAP_FORMAT_INVALID 0xff 39 #define DP_MON_MIN_FRAGS_FOR_RESTITCH 2 40 41 /* monitor frame filter modes */ 42 enum dp_mon_frm_filter_mode { 43 /* mode filter pass */ 44 DP_MON_FRM_FILTER_MODE_FP = 0, 45 /* mode monitor direct */ 46 DP_MON_FRM_FILTER_MODE_MD = 1, 47 /* mode monitor other */ 48 DP_MON_FRM_FILTER_MODE_MO = 2, 49 /* mode filter pass monitor other */ 50 DP_MON_FRM_FILTER_MODE_FP_MO = 3, 51 }; 52 53 /* mpdu filter categories */ 54 enum dp_mpdu_filter_category { 55 /* category filter pass */ 56 DP_MPDU_FILTER_CATEGORY_FP = 0, 57 /* category monitor direct */ 58 DP_MPDU_FILTER_CATEGORY_MD = 1, 59 /* category monitor other */ 60 DP_MPDU_FILTER_CATEGORY_MO = 2, 61 /* category filter pass monitor override */ 62 DP_MPDU_FILTER_CATEGORY_FP_MO = 3, 63 }; 64 65 /** 66 * struct dp_mon_filter_be - Monitor TLV filter 67 * @rx_tlv_filter: Rx MON TLV filter 68 * @tx_tlv_filter: Tx MON TLV filter 69 * @tx_valid: enable/disable Tx Mon TLV filter 70 */ 71 struct dp_mon_filter_be { 72 struct dp_mon_filter rx_tlv_filter; 73 #ifdef QCA_MONITOR_2_0_SUPPORT 74 struct htt_tx_ring_tlv_filter tx_tlv_filter; 75 #endif 76 bool tx_valid; 77 }; 78 79 /** 80 * struct dp_mon_desc 81 * 82 * @buf_addr: virtual address 83 * @paddr: physical address 84 * @in_use: desc is in use 85 * @unmapped: used to mark desc an unmapped if the corresponding 86 * nbuf is already unmapped 87 * @end_offset: offset in status buffer where DMA ended 88 * @cookie: unique desc identifier 89 * @magic: magic number to validate desc data 90 */ 91 struct dp_mon_desc { 92 uint8_t *buf_addr; 93 qdf_dma_addr_t paddr; 94 uint8_t in_use:1, 95 unmapped:1; 96 uint16_t end_offset; 97 uint32_t cookie; 98 uint32_t magic; 99 }; 100 101 /** 102 * struct dp_mon_desc_list_elem_t 103 * @next: Next pointer to form free list 104 * @mon_desc: DP mon descriptor 105 */ 106 union dp_mon_desc_list_elem_t { 107 union dp_mon_desc_list_elem_t *next; 108 struct dp_mon_desc mon_desc; 109 }; 110 111 /** 112 * struct dp_mon_desc_pool - monitor desc pool 113 * @pool_size: number of descriptor in the pool 114 * @array: pointer to array of descriptor 115 * @freelist: pointer to free descriptor list 116 * @lock: Protection for the descriptor pool 117 * @owner: owner for nbuf 118 * @buf_size: Buffer size 119 * @buf_alignment: Buffer alignment 120 * @pf_cache: page frag cache 121 */ 122 struct dp_mon_desc_pool { 123 uint32_t pool_size; 124 union dp_mon_desc_list_elem_t *array; 125 union dp_mon_desc_list_elem_t *freelist; 126 qdf_spinlock_t lock; 127 uint8_t owner; 128 uint16_t buf_size; 129 uint8_t buf_alignment; 130 qdf_frag_cache_t pf_cache; 131 }; 132 133 /** 134 * struct dp_mon_pdev_be - BE specific monitor pdev object 135 * @mon_pdev: monitor pdev structure 136 * @filter_be: filters sent to fw 137 * @tx_mon_mode: tx monitor mode 138 * @tx_mon_filter_length: tx monitor filter length 139 * @tx_monitor_be: pointer to tx monitor be structure 140 * @tx_stats: tx monitor drop stats 141 * @rx_mon_wq_lock: Rx mon workqueue lock 142 * @rx_mon_workqueue: Rx mon workqueue 143 * @rx_mon_work: Rx mon work 144 * @rx_mon_queue: RxMON queue 145 * @rx_mon_queue_depth: RxMON queue depth 146 * @desc_count: reaped status desc count 147 * @status: reaped status buffer per ppdu 148 */ 149 struct dp_mon_pdev_be { 150 struct dp_mon_pdev mon_pdev; 151 struct dp_mon_filter_be **filter_be; 152 uint8_t tx_mon_mode; 153 uint8_t tx_mon_filter_length; 154 struct dp_pdev_tx_monitor_be tx_monitor_be; 155 struct dp_tx_monitor_drop_stats tx_stats; 156 qdf_spinlock_t rx_mon_wq_lock; 157 qdf_workqueue_t *rx_mon_workqueue; 158 qdf_work_t rx_mon_work; 159 160 TAILQ_HEAD(, hal_rx_ppdu_info) rx_mon_queue; 161 uint16_t rx_mon_queue_depth; 162 uint16_t desc_count; 163 struct dp_mon_desc *status[DP_MON_MAX_STATUS_BUF]; 164 #ifdef QCA_SUPPORT_LITE_MONITOR 165 struct dp_lite_mon_rx_config *lite_mon_rx_config; 166 struct dp_lite_mon_tx_config *lite_mon_tx_config; 167 #endif 168 void *prev_rxmon_desc; 169 uint32_t prev_rxmon_cookie; 170 }; 171 172 /** 173 * struct dp_mon_soc_be - BE specific monitor soc 174 * @mon_soc: Monitor soc structure 175 * @tx_mon_buf_ring: TxMon replenish ring 176 * @tx_mon_dst_ring: TxMon Destination ring 177 * @tx_desc_mon: descriptor pool for tx mon src ring 178 * @rx_desc_mon: descriptor pool for rx mon src ring 179 * @rx_mon_ring_fill_level: rx mon ring refill level 180 * @tx_mon_ring_fill_level: tx mon ring refill level 181 * @tx_low_thresh_intrs: number of tx mon low threshold interrupts received 182 * @rx_low_thresh_intrs: number of rx mon low threshold interrupts received 183 * @is_dp_mon_soc_initialized: flag to indicate soc is initialized 184 */ 185 struct dp_mon_soc_be { 186 struct dp_mon_soc mon_soc; 187 /* Source ring for Tx monitor */ 188 struct dp_srng tx_mon_buf_ring; 189 struct dp_srng tx_mon_dst_ring[MAX_NUM_LMAC_HW]; 190 191 /* Sw descriptor pool for tx mon source ring */ 192 struct dp_mon_desc_pool tx_desc_mon; 193 /* Sw descriptor pool for rx mon source ring */ 194 struct dp_mon_desc_pool rx_desc_mon; 195 196 uint16_t rx_mon_ring_fill_level; 197 uint16_t tx_mon_ring_fill_level; 198 uint32_t tx_low_thresh_intrs; 199 uint32_t rx_low_thresh_intrs; 200 201 bool is_dp_mon_soc_initialized; 202 }; 203 #endif 204 205 /** 206 * dp_mon_desc_pool_init() - Monitor descriptor pool init 207 * @mon_desc_pool: mon desc pool 208 * @pool_size 209 * 210 * Return: non-zero for failure, zero for success 211 */ 212 QDF_STATUS 213 dp_mon_desc_pool_init(struct dp_mon_desc_pool *mon_desc_pool, 214 uint32_t pool_size); 215 216 /* 217 * dp_mon_desc_pool_deinit()- monitor descriptor pool deinit 218 * @mon_desc_pool: mon desc pool 219 * 220 * Return: None 221 * 222 */ 223 void dp_mon_desc_pool_deinit(struct dp_mon_desc_pool *mon_desc_pool); 224 225 /* 226 * dp_mon_desc_pool_free()- monitor descriptor pool free 227 * @mon_desc_pool: mon desc pool 228 * 229 * Return: None 230 * 231 */ 232 void dp_mon_desc_pool_free(struct dp_mon_desc_pool *mon_desc_pool); 233 234 /** 235 * dp_mon_desc_pool_alloc() - Monitor descriptor pool alloc 236 * @mon_desc_pool: mon desc pool 237 * @pool_size: Pool size 238 * 239 * Return: non-zero for failure, zero for success 240 */ 241 QDF_STATUS dp_mon_desc_pool_alloc(uint32_t pool_size, 242 struct dp_mon_desc_pool *mon_desc_pool); 243 244 /* 245 * dp_mon_pool_frag_unmap_and_free() - free the mon desc frag called during 246 * de-initialization of wifi module. 247 * 248 * @soc: DP soc handle 249 * @mon_desc_pool: monitor descriptor pool pointer 250 * 251 * Return: None 252 */ 253 void dp_mon_pool_frag_unmap_and_free(struct dp_soc *dp_soc, 254 struct dp_mon_desc_pool *mon_desc_pool); 255 256 /* 257 * dp_mon_buffers_replenish() - replenish monitor ring with nbufs 258 * 259 * @soc: core txrx main context 260 * @dp_mon_srng: dp monitor circular ring 261 * @mon_desc_pool: Pointer to free mon descriptor pool 262 * @num_req_buffers: number of buffer to be replenished 263 * @desc_list: list of descs if called from dp_rx_process 264 * or NULL during dp rx initialization or out of buffer 265 * interrupt. 266 * @tail: tail of descs list 267 * @relenish_cnt_ref: pointer to update replenish_cnt 268 * 269 * Return: return success or failure 270 */ 271 QDF_STATUS dp_mon_buffers_replenish(struct dp_soc *dp_soc, 272 struct dp_srng *dp_mon_srng, 273 struct dp_mon_desc_pool *mon_desc_pool, 274 uint32_t num_req_buffers, 275 union dp_mon_desc_list_elem_t **desc_list, 276 union dp_mon_desc_list_elem_t **tail, 277 uint32_t *replenish_cnt_ref); 278 279 /** 280 * dp_mon_filter_show_tx_filter_be() - Show the set filters 281 * @mode: The filter modes 282 * @tlv_filter: tlv filter 283 */ 284 void dp_mon_filter_show_tx_filter_be(enum dp_mon_filter_mode mode, 285 struct dp_mon_filter_be *filter); 286 287 /** 288 * dp_mon_filter_show_rx_filter_be() - Show the set filters 289 * @mode: The filter modes 290 * @tlv_filter: tlv filter 291 */ 292 void dp_mon_filter_show_rx_filter_be(enum dp_mon_filter_mode mode, 293 struct dp_mon_filter_be *filter); 294 295 /** 296 * dp_vdev_set_monitor_mode_buf_rings_tx_2_0() - Add buffers to tx ring 297 * @pdev: Pointer to dp_pdev object 298 * 299 * Return: QDF_STATUS 300 */ 301 QDF_STATUS dp_vdev_set_monitor_mode_buf_rings_tx_2_0(struct dp_pdev *pdev); 302 303 /** 304 * dp_vdev_set_monitor_mode_buf_rings_rx_2_0() - Add buffers to rx ring 305 * @pdev: Pointer to dp_pdev object 306 * 307 * Return: QDF_STATUS 308 */ 309 QDF_STATUS dp_vdev_set_monitor_mode_buf_rings_rx_2_0(struct dp_pdev *pdev); 310 311 #ifdef QCA_ENHANCED_STATS_SUPPORT 312 /** 313 * dp_mon_get_puncture_type() - Get puncture type 314 * @puncture_pattern: puncture bitmap 315 * @bw: Bandwidth 316 */ 317 enum cdp_punctured_modes 318 dp_mon_get_puncture_type(uint16_t puncture_pattern, uint8_t bw); 319 #endif 320 321 /* 322 * dp_mon_desc_get() - get monitor sw descriptor 323 * 324 * @cookie: cookie 325 * 326 * Return: dp_mon_desc 327 */ 328 static inline 329 struct dp_mon_desc *dp_mon_desc_get(uint64_t *cookie) 330 { 331 return (struct dp_mon_desc *)cookie; 332 } 333 334 /** 335 * dp_rx_add_to_free_desc_list() - Adds to a local free descriptor list 336 * 337 * @head: pointer to the head of local free list 338 * @tail: pointer to the tail of local free list 339 * @new: new descriptor that is added to the free list 340 * @func_name: caller func name 341 * 342 * Return: void 343 */ 344 static inline 345 void __dp_mon_add_to_free_desc_list(union dp_mon_desc_list_elem_t **head, 346 union dp_mon_desc_list_elem_t **tail, 347 struct dp_mon_desc *new, 348 const char *func_name) 349 { 350 qdf_assert(head && new); 351 352 new->buf_addr = NULL; 353 new->in_use = 0; 354 355 ((union dp_mon_desc_list_elem_t *)new)->next = *head; 356 *head = (union dp_mon_desc_list_elem_t *)new; 357 /* reset tail if head->next is NULL */ 358 if (!*tail || !(*head)->next) 359 *tail = *head; 360 } 361 362 #define dp_mon_add_to_free_desc_list(head, tail, new) \ 363 __dp_mon_add_to_free_desc_list(head, tail, new, __func__) 364 365 /* 366 * dp_mon_add_desc_list_to_free_list() - append unused desc_list back to 367 * freelist. 368 * 369 * @soc: core txrx main context 370 * @local_desc_list: local desc list provided by the caller 371 * @tail: attach the point to last desc of local desc list 372 * @mon_desc_pool: monitor descriptor pool pointer 373 */ 374 375 void 376 dp_mon_add_desc_list_to_free_list(struct dp_soc *soc, 377 union dp_mon_desc_list_elem_t **local_desc_list, 378 union dp_mon_desc_list_elem_t **tail, 379 struct dp_mon_desc_pool *mon_desc_pool); 380 381 /** 382 * dp_rx_mon_add_frag_to_skb () - Add page frag to skb 383 * 384 * @ppdu_info: PPDU status info 385 * @nbuf: SKB to which frag need to be added 386 * @status_frag: Frag to add 387 * 388 * Return: void 389 */ 390 static inline void 391 dp_rx_mon_add_frag_to_skb(struct hal_rx_ppdu_info *ppdu_info, 392 qdf_nbuf_t nbuf, 393 qdf_frag_t status_frag) 394 { 395 uint16_t num_frags; 396 397 num_frags = qdf_nbuf_get_nr_frags(nbuf); 398 if (num_frags < QDF_NBUF_MAX_FRAGS) { 399 qdf_nbuf_add_rx_frag(status_frag, nbuf, 400 ppdu_info->data - (unsigned char *)status_frag, 401 ppdu_info->hdr_len, 402 RX_MONITOR_BUFFER_SIZE, 403 false); 404 } else { 405 dp_mon_err("num_frags exceeding MAX frags"); 406 qdf_assert_always(0); 407 } 408 } 409 410 #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) ||\ 411 defined(WLAN_SUPPORT_RX_FLOW_TAG) 412 /** dp_mon_rx_update_rx_err_protocol_tag_stats() - Update mon protocols's 413 * statistics from given protocol 414 * type 415 * @pdev: pdev handle 416 * @protocol_index: Protocol index for which the stats should be incremented 417 * 418 * Return: void 419 */ 420 void dp_mon_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev, 421 uint16_t protocol_index); 422 #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ 423 424 #endif /* _DP_MON_2_0_H_ */ 425