1  /*
2   * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2021-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  #ifndef _TARGET_IF_DIRECT_BUF_RX_MAIN_H_
21  #define _TARGET_IF_DIRECT_BUF_RX_MAIN_H_
22  
23  #include "qdf_types.h"
24  #include "qdf_status.h"
25  #include <target_if_direct_buf_rx_api.h>
26  
27  struct wlan_objmgr_psoc;
28  struct wlan_lmac_if_tx_ops;
29  struct direct_buf_rx_data;
30  
31  #define DBR_RING_BASE_ALIGN 8
32  
33  #ifdef DBR_MULTI_SRNG_ENABLE
34  #define DBR_SRNG_NUM 2
35  #define dbr_get_pdev_id(srng_id, pdev_id) (srng_id)
36  #else
37  #define DBR_SRNG_NUM 1
38  #define dbr_get_pdev_id(srng_id, pdev_id) (pdev_id)
39  #endif
40  
41  /**
42   * struct direct_buf_rx_buf_info - direct buffer rx operation info struct
43   * @cookie: SW cookie used to get the virtual address
44   * @paddr: Physical address pointer for DMA operation
45   * @vaddr: Virtual address pointer
46   * @offset: Offset of aligned address from unaligned
47   */
48  struct direct_buf_rx_buf_info {
49  	uint32_t cookie;
50  	qdf_dma_addr_t paddr;
51  	void *vaddr;
52  	uint8_t offset;
53  };
54  
55  /**
56   * struct direct_buf_rx_ring_cfg - DMA ring config parameters
57   * @num_ptr: Depth or the number of physical address pointers in the ring
58   * @ring_alloc_size: Size of the HAL ring
59   * @base_paddr_unaligned: base physical addr unaligned
60   * @base_vaddr_unaligned: base virtual addr unaligned
61   * @base_paddr_aligned: base physical addr aligned
62   * @base_vaddr_aligned: base virtual addr unaligned
63   * @head_idx_addr: head index addr
64   * @tail_idx_addr: tail index addr
65   * @srng: HAL srng context
66   * @buf_size: size of each buffer
67   */
68  struct direct_buf_rx_ring_cfg {
69  	uint32_t num_ptr;
70  	uint32_t ring_alloc_size;
71  	qdf_dma_addr_t base_paddr_unaligned;
72  	void *base_vaddr_unaligned;
73  	qdf_dma_addr_t base_paddr_aligned;
74  	void *base_vaddr_aligned;
75  	qdf_dma_addr_t head_idx_addr;
76  	qdf_dma_addr_t tail_idx_addr;
77  	void *srng;
78  	uint32_t buf_size;
79  };
80  
81  /**
82   * struct direct_buf_rx_ring_cap - DMA ring capabilities
83   * @ring_elems_min: Minimum number of pointers in the ring
84   * @min_buf_size: Minimum size of each buffer entry in the ring
85   * @min_buf_align: Minimum alignment of the addresses in the ring
86   */
87  struct direct_buf_rx_ring_cap {
88  	uint32_t ring_elems_min;
89  	uint32_t min_buf_size;
90  	uint32_t min_buf_align;
91  };
92  
93  /**
94   * enum DBR_RING_DEBUG_EVENT - DMA ring debug event
95   * @DBR_RING_DEBUG_EVENT_NONE: Not a real value, just a place holder for
96   * no entry
97   * @DBR_RING_DEBUG_EVENT_RX: DBR Rx event
98   * @DBR_RING_DEBUG_EVENT_REPLENISH_RING: DBR replenish event
99   * @DBR_RING_DEBUG_EVENT_MAX: Not a real value, just a place holder for max
100   */
101  enum DBR_RING_DEBUG_EVENT {
102  	DBR_RING_DEBUG_EVENT_NONE = 0,
103  	DBR_RING_DEBUG_EVENT_RX,
104  	DBR_RING_DEBUG_EVENT_REPLENISH_RING,
105  	DBR_RING_DEBUG_EVENT_MAX,
106  };
107  
108  #define DIRECT_BUF_RX_MAX_RING_DEBUG_ENTRIES (1024)
109  /**
110   * struct direct_buf_rx_ring_debug_entry - DBR ring debug entry
111   * @head_idx: Head index of the DMA ring
112   * @tail_idx: Tail index of the DMA ring
113   * @timestamp: Timestamp at the time of logging
114   * @event: Name of the event
115   */
116  struct direct_buf_rx_ring_debug_entry {
117  	uint32_t head_idx;
118  	uint32_t tail_idx;
119  	uint64_t timestamp;
120  	enum DBR_RING_DEBUG_EVENT event;
121  };
122  
123  #ifdef WLAN_DEBUGFS
124  /**
125   * struct dbr_debugfs_priv - Private data for DBR ring debugfs
126   * @dbr_pdev_obj: Pointer to the pdev obj of Direct buffer rx module
127   * @mod_id: Pointer to the registered module ID
128   * @srng_id: srng ID
129   */
130  struct dbr_debugfs_priv {
131  	struct direct_buf_rx_pdev_obj *dbr_pdev_obj;
132  	enum DBR_MODULE mod_id;
133  	uint8_t srng_id;
134  };
135  #endif
136  
137  /**
138   * struct direct_buf_rx_ring_debug - DMA ring debug of a module
139   * @entries: Pointer to the array of ring debug entries
140   * @ring_debug_idx: Current index in the array of ring debug entries
141   * @num_ring_debug_entries: Total ring debug entries
142   * @debugfs_entry: Debugfs entry for this ring
143   * @debugfs_fops: Debugfs ops for this ring
144   */
145  struct direct_buf_rx_ring_debug {
146  	struct direct_buf_rx_ring_debug_entry *entries;
147  	uint32_t ring_debug_idx;
148  	uint32_t num_ring_debug_entries;
149  #ifdef WLAN_DEBUGFS
150  	qdf_dentry_t debugfs_entry;
151  	struct qdf_debugfs_fops *debugfs_fops;
152  #endif
153  };
154  
155  /**
156   * struct direct_buf_rx_module_debug - Debug of a module subscribed to DBR
157   * @dbr_ring_debug: Array of ring debug structers corresponding to each srng
158   * @poisoning_enabled: Whether buffer poisoning is enabled for this module
159   * @poison_value: Value with which buffers should be poisoned
160   * @debugfs_entry: Debugfs entry for this module
161   */
162  struct direct_buf_rx_module_debug {
163  	struct direct_buf_rx_ring_debug dbr_ring_debug[DBR_SRNG_NUM];
164  	bool poisoning_enabled;
165  	uint32_t poison_value;
166  #ifdef WLAN_DEBUGFS
167  	qdf_dentry_t debugfs_entry;
168  #endif
169  };
170  
171  /**
172   * struct direct_buf_rx_module_param - DMA module param
173   * @mod_id: Module ID
174   * @pdev_id: pdev ID
175   * @srng_id: SRNG ID
176   * @dbr_config: Pointer to dirct buf rx module configuration struct
177   * @dbr_ring_cap: Pointer to direct buf rx ring capabilities struct
178   * @dbr_ring_cfg: Pointer to direct buf rx ring config struct
179   * @dbr_buf_pool: Pointer to direct buf rx buffer pool struct
180   * @dbr_rsp_handler: Pointer to direct buf rx response handler for the module
181   * @srng_initialized: Whether the DBR ring is successfully initialized for this
182   */
183  struct direct_buf_rx_module_param {
184  	enum DBR_MODULE mod_id;
185  	uint8_t pdev_id;
186  	uint8_t srng_id;
187  	struct dbr_module_config dbr_config;
188  	struct direct_buf_rx_ring_cap *dbr_ring_cap;
189  	struct direct_buf_rx_ring_cfg *dbr_ring_cfg;
190  	struct direct_buf_rx_buf_info *dbr_buf_pool;
191  	bool (*dbr_rsp_handler)(struct wlan_objmgr_pdev *pdev,
192  				struct direct_buf_rx_data *dbr_data);
193  	bool srng_initialized;
194  };
195  
196  /**
197   * struct direct_buf_rx_pdev_obj - Direct Buf RX pdev object struct
198   * @num_modules: Number of modules registered to DBR for the pdev
199   * @dbr_mod_param: Pointer to direct buf rx module param struct
200   * @dbr_mod_debug: Pointer to the array of DBR module debug structures
201   * @debugfs_entry: DBR debugfs entry of this radio
202   */
203  struct direct_buf_rx_pdev_obj {
204  	uint32_t num_modules;
205  	struct direct_buf_rx_module_param (*dbr_mod_param)[DBR_SRNG_NUM];
206  #ifdef DIRECT_BUF_RX_DEBUG
207  	struct direct_buf_rx_module_debug *dbr_mod_debug;
208  #ifdef WLAN_DEBUGFS
209  	qdf_dentry_t debugfs_entry;
210  #endif
211  #endif
212  };
213  
214  /**
215   * struct direct_buf_rx_psoc_obj - Direct Buf RX psoc object struct
216   * @hal_soc: Opaque HAL SOC handle
217   * @osdev: QDF os device handle
218   * @dbr_pdev_obj: array of DBR pdev objects
219   * @mem_list: list for holding the large memories during the entire
220   *  PSOC lifetime
221   * @mem_list_lock: spin lock for the memory list
222   * @handler_ctx: Direct DMA event handler context
223   */
224  struct direct_buf_rx_psoc_obj {
225  	void *hal_soc;
226  	qdf_device_t osdev;
227  	struct direct_buf_rx_pdev_obj *dbr_pdev_obj[WLAN_UMAC_MAX_PDEVS];
228  #if defined(DBR_HOLD_LARGE_MEM) && defined(CNSS_MEM_PRE_ALLOC)
229  	qdf_list_t mem_list[WLAN_UMAC_MAX_PDEVS];
230  	qdf_spinlock_t mem_list_lock;
231  #endif
232  	enum wmi_rx_exec_ctx handler_ctx;
233  };
234  
235  /**
236   * struct module_ring_params - Direct buf ring params for module
237   * @num_bufs: Number of buffers allotted to this module
238   * @buf_size: size of buffers
239   */
240  struct module_ring_params {
241  	uint32_t num_bufs;
242  	uint32_t buf_size;
243  };
244  
245  /**
246   * target_if_direct_buf_rx_register_events() - Register WMI events to direct
247   *                                             buffer rx module
248   * @psoc: pointer to psoc object
249   *
250   * Return : QDF status of operation
251   */
252  QDF_STATUS target_if_direct_buf_rx_register_events(
253  				struct wlan_objmgr_psoc *psoc);
254  
255  /**
256   * target_if_direct_buf_rx_unregister_events() - Unregister WMI events to direct
257   *                                               buffer rx module
258   * @psoc: pointer to psoc object
259   *
260   * Return : QDF status of operation
261   */
262  QDF_STATUS target_if_direct_buf_rx_unregister_events(
263  				struct wlan_objmgr_psoc *psoc);
264  
265  /**
266   * target_if_direct_buf_rx_print_ring_stat() - Print ring status for each
267   *                                             module in the pdev
268   * @pdev: pointer to pdev object
269   *
270   * Return : QDF status of operation
271   */
272  QDF_STATUS target_if_direct_buf_rx_print_ring_stat(
273  				struct wlan_objmgr_pdev *pdev);
274  
275  /**
276   * target_if_direct_buf_rx_pdev_create_handler() - Handler to be invoked for
277   *                                                 direct buffer rx module
278   *                                                 during pdev object create
279   * @pdev: pointer to pdev object
280   * @data: pointer to data
281   *
282   * Return : QDF status of operation
283   */
284  QDF_STATUS target_if_direct_buf_rx_pdev_create_handler(
285  				struct wlan_objmgr_pdev *pdev, void *data);
286  
287  /**
288   * target_if_direct_buf_rx_pdev_destroy_handler() - Handler to be invoked for
289   *                                                  direct buffer rx module
290   *                                                  during pdev object destroy
291   * @pdev: pointer to pdev object
292   * @data: pointer to data
293   *
294   * Return : QDF status of operation
295   */
296  QDF_STATUS target_if_direct_buf_rx_pdev_destroy_handler(
297  				struct wlan_objmgr_pdev *pdev, void *data);
298  
299  /**
300   * target_if_direct_buf_rx_psoc_create_handler() - Handler invoked for
301   *                                                 direct buffer rx module
302   *                                                 during attach
303   * @psoc: pointer to psoc object
304   * @data: callback context provided during registration
305   *
306   * Return : QDF status of operation
307   */
308  QDF_STATUS target_if_direct_buf_rx_psoc_create_handler(
309  				struct wlan_objmgr_psoc *psoc, void *data);
310  
311  /**
312   * target_if_direct_buf_rx_psoc_destroy_handler() - Handler invoked for
313   *                                                  direct buffer rx module
314   *                                                  during detach
315   * @psoc: pointer to psoc object
316   * @data: callback context provided during registration
317   *
318   * Return : QDF status of operation
319   */
320  QDF_STATUS target_if_direct_buf_rx_psoc_destroy_handler(
321  				struct wlan_objmgr_psoc *psoc, void *data);
322  
323  /**
324   * target_if_deinit_dbr_ring() - Function to deinitialize buffers and ring
325   *                               allocated for direct buffer rx module
326   * @pdev: pointer to pdev object
327   * @dbr_pdev_obj: pointer to direct buffer rx module pdev obj
328   * @mod_id: module id indicating the module using direct buffer rx framework
329   * @srng_id: srng ID
330   *
331   * Return : QDF status of operation
332   */
333  QDF_STATUS target_if_deinit_dbr_ring(struct wlan_objmgr_pdev *pdev,
334  				struct direct_buf_rx_pdev_obj *dbr_pdev_obj,
335  				enum DBR_MODULE mod_id, uint8_t srng_id);
336  /**
337   * target_if_direct_buf_rx_module_register() - Function to register to direct
338   *                                             buffer rx module
339   * @pdev: pointer to pdev object
340   * @mod_id: module id indicating the module using direct buffer rx framework
341   * @dbr_config: dbr module configuration params
342   * @dbr_rsp_handler: function pointer pointing to the response handler to be
343   *                   invoked for the module registering to direct buffer rx
344   *                   module
345   *
346   * Return: QDF status of operation
347   */
348  QDF_STATUS target_if_direct_buf_rx_module_register(
349  			struct wlan_objmgr_pdev *pdev, uint8_t mod_id,
350  			struct dbr_module_config *dbr_config,
351  			bool (*dbr_rsp_handler)
352  			     (struct wlan_objmgr_pdev *pdev,
353  			      struct direct_buf_rx_data *dbr_data));
354  
355  /**
356   * target_if_direct_buf_rx_module_unregister() - Function to unregister to
357   *                                               direct buffer rx module
358   * @pdev: pointer to pdev object
359   * @mod_id: module id indicating the module using direct buffer rx framework
360   *
361   * Return: QDF status of operation
362   */
363  QDF_STATUS target_if_direct_buf_rx_module_unregister(
364  			struct wlan_objmgr_pdev *pdev, uint8_t mod_id);
365  
366  /**
367   * target_if_direct_buf_rx_get_ring_params() - Function to get ring parameters
368   *                                             for module_id
369   * @pdev: pointer to pdev object
370   * @param: pointer to store ring params
371   * @mod_id: module idindicating module using direct buffer rx framework
372   * @srng_id: srng ID
373   */
374  QDF_STATUS
375  target_if_direct_buf_rx_get_ring_params(struct wlan_objmgr_pdev *pdev,
376  					struct module_ring_params *param,
377  					uint8_t mod_id, uint8_t srng_id);
378  
379  /**
380   * target_if_dbr_start_ring_debug() - Start DBR ring debug
381   * @pdev: pointer to pdev object
382   * @mod_id: module ID indicating the module using direct buffer rx framework
383   * @num_ring_debug_entries: Size of the ring debug entries
384   */
385  QDF_STATUS target_if_dbr_start_ring_debug(struct wlan_objmgr_pdev *pdev,
386  					  uint8_t mod_id,
387  					  uint32_t num_ring_debug_entries);
388  
389  /**
390   * target_if_dbr_stop_ring_debug() - Stop DBR ring debug
391   * @pdev: pointer to pdev object
392   * @mod_id: module ID indicating the module using direct buffer rx framework
393   */
394  QDF_STATUS target_if_dbr_stop_ring_debug(struct wlan_objmgr_pdev *pdev,
395  					 uint8_t mod_id);
396  
397  /**
398   * target_if_dbr_start_buffer_poisoning() - Start DBR buffer poisoning
399   * @pdev: pointer to pdev object
400   * @mod_id: module ID indicating the module using direct buffer rx framework
401   * @value: Value with which buffers should be poisoned
402   *
403   * Only those buffers which are going to be mapped to the device after this
404   * API call are guaranteed to be poisoned. If user wants all the buffers in
405   * the ring to be poisoned from their creation time then this API should be
406   * called before module's registration to the DBR.
407   *
408   */
409  QDF_STATUS target_if_dbr_start_buffer_poisoning(struct wlan_objmgr_pdev *pdev,
410  						uint8_t mod_id, uint32_t value);
411  
412  /**
413   * target_if_dbr_stop_buffer_poisoning() - Stop DBR buffer poisoning
414   * @pdev: pointer to pdev object
415   * @mod_id: module ID indicating the module using direct buffer rx framework
416   */
417  QDF_STATUS target_if_dbr_stop_buffer_poisoning(struct wlan_objmgr_pdev *pdev,
418  					       uint8_t mod_id);
419  #endif /* _TARGET_IF_DIRECT_BUF_RX_MAIN_H_ */
420