1  /*
2   * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
3   * Copyright (c) 2023-2024 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   * DOC: declare various api which shall be used by
21   * pmo user configuration and target interface
22   */
23  
24  #ifndef _WLAN_PMO_MAIN_H_
25  #define _WLAN_PMO_MAIN_H_
26  
27  #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
28  
29  #include "wlan_pmo_common_public_struct.h"
30  #include "wlan_pmo_obj_mgmt_public_struct.h"
31  #include "wlan_pmo_priv.h"
32  #include "wlan_pmo_objmgr.h"
33  
34  #define pmo_fatal(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_PMO, params)
35  #define pmo_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_PMO, params)
36  #define pmo_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_PMO, params)
37  #define pmo_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_PMO, params)
38  #define pmo_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_PMO, params)
39  
40  #define pmo_nofl_fatal(params...) \
41  	QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_PMO, params)
42  #define pmo_nofl_err(params...) \
43  	QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_PMO, params)
44  #define pmo_nofl_warn(params...) \
45  	QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_PMO, params)
46  #define pmo_nofl_info(params...) \
47  	QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_PMO, params)
48  #define pmo_nofl_debug(params...) \
49  	QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_PMO, params)
50  
51  #define pmo_enter() QDF_TRACE_ENTER(QDF_MODULE_ID_PMO, "enter")
52  #define pmo_exit() QDF_TRACE_EXIT(QDF_MODULE_ID_PMO, "exit")
53  
54  #define PMO_VDEV_IN_STA_MODE(mode) \
55  	((mode) == QDF_STA_MODE || (mode) == QDF_P2P_CLIENT_MODE ? 1 : 0)
56  
pmo_get_vdev_opmode(struct wlan_objmgr_vdev * vdev)57  static inline enum QDF_OPMODE pmo_get_vdev_opmode(struct wlan_objmgr_vdev *vdev)
58  {
59  	return wlan_vdev_mlme_get_opmode(vdev);
60  }
61  
62  /**
63   * pmo_allocate_ctx() - Api to allocate pmo ctx
64   *
65   * Helper function to allocate pmo ctx
66   *
67   * Return: Success or failure.
68   */
69  QDF_STATUS pmo_allocate_ctx(void);
70  
71  /**
72   * pmo_free_ctx() - to free pmo context
73   *
74   * Helper function to free pmo context
75   *
76   * Return: None.
77   */
78  void pmo_free_ctx(void);
79  
80  /**
81   * pmo_get_context() - to get pmo context
82   *
83   * Helper function to get pmo context
84   *
85   * Return: pmo context.
86   */
87  struct wlan_pmo_ctx *pmo_get_context(void);
88  
89  /**
90   * pmo_psoc_open() - pmo psoc object open
91   * @psoc: objmgr vdev
92   *.
93   * This function used to open pmo psoc object
94   *
95   * Return: Success or failure
96   */
97  QDF_STATUS pmo_psoc_open(struct wlan_objmgr_psoc *psoc);
98  
99  /**
100   * pmo_psoc_close() - pmo psoc object close
101   * @psoc: objmgr vdev
102   *.
103   * This function used to close pmo psoc object
104   *
105   * Return: Success or failure
106   */
107  QDF_STATUS pmo_psoc_close(struct wlan_objmgr_psoc *psoc);
108  
109  /**
110   * pmo_get_vdev_bss_peer_mac_addr() - API to get bss peer mac address
111   * @vdev: objmgr vdev
112   * @bss_peer_mac_address: bss peer mac address
113   *
114   * Helper function to  get bss peer mac address
115   *
116   * Return: if success pmo vdev ctx else NULL
117   */
118  QDF_STATUS pmo_get_vdev_bss_peer_mac_addr(struct wlan_objmgr_vdev *vdev,
119  		struct qdf_mac_addr *bss_peer_mac_address);
120  
121  /**
122   * pmo_is_vdev_in_beaconning_mode() - check if vdev is in a beaconning mode
123   * @vdev_opmode: vdev opmode
124   *
125   * Helper function to know whether given vdev
126   * is in a beaconning mode or not.
127   *
128   * Return: True if vdev needs to beacon.
129   */
130  bool pmo_is_vdev_in_beaconning_mode(enum QDF_OPMODE vdev_opmode);
131  
132  /**
133   * pmo_core_is_ap_mode_supports_arp_ns() - To check ap mode supports arp/ns
134   * @psoc: objmgr psoc handle
135   * @vdev_opmode: vdev opmode
136   *
137   * API to check if ap mode supports arp/ns offload
138   *
139   * Return: True  if ap mode supports arp/ns offload
140   */
141  
142  bool pmo_core_is_ap_mode_supports_arp_ns(struct wlan_objmgr_psoc *psoc,
143  	enum QDF_OPMODE vdev_opmode);
144  
145  /**
146   * pmo_core_is_vdev_supports_offload() - Check offload is supported on vdev
147   * @vdev: objmgr vdev
148   *
149   * Return: true in case success else false
150   */
151  bool pmo_core_is_vdev_supports_offload(struct wlan_objmgr_vdev *vdev);
152  
153  /**
154   * pmo_core_get_psoc_config(): API to get the psoc user configurations of pmo
155   * @psoc: objmgr psoc handle
156   * @psoc_cfg: fill the current psoc user configurations.
157   *
158   * Return pmo psoc configurations
159   */
160  QDF_STATUS pmo_core_get_psoc_config(struct wlan_objmgr_psoc *psoc,
161  		struct pmo_psoc_cfg *psoc_cfg);
162  
163  /**
164   * pmo_core_update_psoc_config(): API to update the psoc user configurations
165   * @psoc: objmgr psoc handle
166   * @psoc_cfg: pmo psoc configurations
167   *
168   * This api shall be used for soc config initialization as well update.
169   * In case of update caller must first call pmo_get_psoc_cfg to get
170   * current config and then apply changes on top of current config.
171   *
172   * Return QDF_STATUS -in case of success else return error
173   */
174  QDF_STATUS pmo_core_update_psoc_config(struct wlan_objmgr_psoc *psoc,
175  		struct pmo_psoc_cfg *psoc_cfg);
176  
177  /**
178   * pmo_psoc_set_caps() - overwrite configured device capability flags
179   * @psoc: the psoc for which the capabilities apply
180   * @caps: the cabability information to configure
181   *
182   * Return: None
183   */
184  void pmo_psoc_set_caps(struct wlan_objmgr_psoc *psoc,
185  		       struct pmo_device_caps *caps);
186  
187  /**
188   * pmo_core_get_vdev_op_mode(): API to get the vdev operation mode
189   * @vdev: objmgr vdev handle
190   *
191   * API to get the vdev operation mode
192   *
193   * Return QDF_MAX_NO_OF_MODE - in case of error else return vdev opmode
194   */
pmo_core_get_vdev_op_mode(struct wlan_objmgr_vdev * vdev)195  static inline enum QDF_OPMODE pmo_core_get_vdev_op_mode(
196  					struct wlan_objmgr_vdev *vdev)
197  {
198  	enum QDF_OPMODE op_mode = QDF_MAX_NO_OF_MODE;
199  
200  	if (!vdev)
201  		return op_mode;
202  	op_mode = wlan_vdev_mlme_get_opmode(vdev);
203  
204  	return op_mode;
205  }
206  
207  /**
208   * pmo_core_psoc_update_dp_handle() - update psoc data path handle
209   * @psoc: objmgr psoc handle
210   * @dp_hdl: psoc data path handle
211   *
212   * Return: None
213   */
214  static inline void
pmo_core_psoc_update_dp_handle(struct wlan_objmgr_psoc * psoc,void * dp_hdl)215  pmo_core_psoc_update_dp_handle(struct wlan_objmgr_psoc *psoc, void *dp_hdl)
216  {
217  	struct pmo_psoc_priv_obj *psoc_ctx;
218  
219  	pmo_psoc_with_ctx(psoc, psoc_ctx) {
220  		psoc_ctx->dp_hdl = dp_hdl;
221  	}
222  }
223  
224  /**
225   * pmo_core_psoc_get_dp_handle() - Get psoc data path handle
226   * @psoc: objmgr psoc handle
227   *
228   * Return: psoc data path handle
229   */
pmo_core_psoc_get_dp_handle(struct wlan_objmgr_psoc * psoc)230  static inline void *pmo_core_psoc_get_dp_handle(struct wlan_objmgr_psoc *psoc)
231  {
232  	void *dp_hdl = NULL;
233  	struct pmo_psoc_priv_obj *psoc_ctx;
234  
235  	pmo_psoc_with_ctx(psoc, psoc_ctx) {
236  		dp_hdl = psoc_ctx->dp_hdl;
237  	}
238  
239  	return dp_hdl;
240  }
241  
242  /**
243   * pmo_core_vdev_get_dp_handle() - Get vdev data path handle
244   * @psoc_ctx: pmo psoc private context
245   * @vdev_id: vdev id config to get data path handle
246   *
247   * Return: Vdev data path handle
248   */
249  static inline
pmo_core_vdev_get_dp_handle(struct pmo_psoc_priv_obj * psoc_ctx,uint8_t vdev_id)250  struct cdp_vdev *pmo_core_vdev_get_dp_handle(struct pmo_psoc_priv_obj *psoc_ctx,
251  					     uint8_t vdev_id)
252  {
253  	struct cdp_vdev *dp_hdl = NULL;
254  	pmo_get_vdev_dp_handle handler;
255  
256  	qdf_spin_lock_bh(&psoc_ctx->lock);
257  	handler = psoc_ctx->get_vdev_dp_handle;
258  	qdf_spin_unlock_bh(&psoc_ctx->lock);
259  
260  	if (handler)
261  		dp_hdl = handler(vdev_id);
262  
263  	return dp_hdl;
264  }
265  
266  /**
267   * pmo_core_psoc_update_htc_handle() - update psoc htc layer handle
268   * @psoc: objmgr psoc handle
269   * @htc_hdl: psoc htc layer handle
270   *
271   * Return: None
272   */
273  static inline void
pmo_core_psoc_update_htc_handle(struct wlan_objmgr_psoc * psoc,void * htc_hdl)274  pmo_core_psoc_update_htc_handle(struct wlan_objmgr_psoc *psoc, void *htc_hdl)
275  {
276  	struct pmo_psoc_priv_obj *psoc_ctx;
277  
278  	pmo_psoc_with_ctx(psoc, psoc_ctx) {
279  		psoc_ctx->htc_hdl = htc_hdl;
280  	}
281  }
282  
283  /**
284   * pmo_core_psoc_get_htc_handle() - Get psoc htc layer handle
285   * @psoc: objmgr psoc handle
286   *
287   * Return: psoc htc layer handle
288   */
pmo_core_psoc_get_htc_handle(struct wlan_objmgr_psoc * psoc)289  static inline void *pmo_core_psoc_get_htc_handle(struct wlan_objmgr_psoc *psoc)
290  {
291  	void *htc_hdl = NULL;
292  	struct pmo_psoc_priv_obj *psoc_ctx;
293  
294  	pmo_psoc_with_ctx(psoc, psoc_ctx) {
295  		htc_hdl = psoc_ctx->htc_hdl;
296  	}
297  
298  	return htc_hdl;
299  }
300  
301  /**
302   * pmo_core_psoc_set_hif_handle() - update psoc hif layer handle
303   * @psoc: objmgr psoc handle
304   * @hif_hdl: hif context handle
305   *
306   * Return: None
307   */
308  void pmo_core_psoc_set_hif_handle(struct wlan_objmgr_psoc *psoc,
309  				  void *hif_hdl);
310  
311  /**
312   * pmo_core_psoc_get_hif_handle() - Get psoc hif layer handle
313   * @psoc: objmgr psoc handle
314   *
315   * Return: psoc hif layer handle
316   */
317  void *pmo_core_psoc_get_hif_handle(struct wlan_objmgr_psoc *psoc);
318  
319  /**
320   * pmo_core_psoc_set_txrx_pdev_id() - update psoc pdev txrx layer handle
321   * @psoc: objmgr psoc handle
322   * @txrx_pdev_id: txrx pdev identifier
323   *
324   * Return: None
325   */
326  void pmo_core_psoc_set_txrx_pdev_id(struct wlan_objmgr_psoc *psoc,
327  				    uint8_t txrx_pdev_id);
328  
329  /**
330   * pmo_core_psoc_get_txrx_handle() - Get psoc pdev txrx handle
331   * @psoc: objmgr psoc handle
332   *
333   * Return: txrx pdev identifier
334   */
335  uint8_t pmo_core_psoc_get_txrx_handle(struct wlan_objmgr_psoc *psoc);
336  
337  /**
338   * pmo_intersect_arp_ns_offload() - intersect config and firmware capability for
339   *	the ARP/NS Offload feature
340   * @psoc_ctx: A PMO psoc context
341   *
342   * Note: The caller is expected to grab the PMO context lock.
343   *
344   * Return: True if firmware supports and configuration has enabled the feature
345   */
346  static inline bool
pmo_intersect_arp_ns_offload(struct pmo_psoc_priv_obj * psoc_ctx)347  pmo_intersect_arp_ns_offload(struct pmo_psoc_priv_obj *psoc_ctx)
348  {
349  	struct pmo_psoc_cfg *cfg = &psoc_ctx->psoc_cfg;
350  	bool arp_ns_enabled =
351  		cfg->ns_offload_enable_static ||
352  		cfg->ns_offload_enable_dynamic ||
353  		cfg->arp_offload_enable;
354  
355  	return arp_ns_enabled && psoc_ctx->caps.arp_ns_offload;
356  }
357  
358  /**
359   * pmo_intersect_apf() - intersect config and firmware capability for
360   *	the APF feature
361   * @psoc_ctx: A PMO psoc context
362   *
363   * Note: The caller is expected to grab the PMO context lock.
364   *
365   * Return: True if firmware supports and configuration has enabled the feature
366   */
pmo_intersect_apf(struct pmo_psoc_priv_obj * psoc_ctx)367  static inline bool pmo_intersect_apf(struct pmo_psoc_priv_obj *psoc_ctx)
368  {
369  	return psoc_ctx->psoc_cfg.apf_enable && psoc_ctx->caps.apf;
370  }
371  
372  /**
373   * pmo_intersect_packet_filter() - intersect config and firmware capability for
374   *	the APF feature
375   * @psoc_ctx: A PMO psoc context
376   *
377   * Note: The caller is expected to grab the PMO context lock.
378   *
379   * Return: True if firmware supports and configuration has enabled the feature
380   */
381  static inline bool
pmo_intersect_packet_filter(struct pmo_psoc_priv_obj * psoc_ctx)382  pmo_intersect_packet_filter(struct pmo_psoc_priv_obj *psoc_ctx)
383  {
384  	return psoc_ctx->psoc_cfg.packet_filter_enabled &&
385  		psoc_ctx->caps.packet_filter;
386  }
387  
388  /*
389   * pmo_host_action_on_page_fault() - Returns action host will take on page fault
390   * @psoc: PSOC object manager pointer.
391   *
392   * Returns: Host action on page fault event
393   */
394  enum pmo_page_fault_action
395  pmo_host_action_on_page_fault(struct wlan_objmgr_psoc *psoc);
396  
397  #define pmo_is_host_pagefault_action(_psoc, _action) \
398  		(pmo_host_action_on_page_fault(_psoc) == (_action))
399  
pmo_no_op_on_page_fault(struct wlan_objmgr_psoc * psoc)400  static inline bool pmo_no_op_on_page_fault(struct wlan_objmgr_psoc *psoc)
401  {
402  	return pmo_is_host_pagefault_action(psoc, PMO_PF_HOST_ACTION_NO_OP);
403  }
404  
pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc * psoc)405  static inline bool pmo_enable_ssr_on_page_fault(struct wlan_objmgr_psoc *psoc)
406  {
407  	return pmo_is_host_pagefault_action(psoc, PMO_PF_HOST_ACTION_TRIGGER_SSR);
408  }
409  
410  /*
411   * pmo_get_min_pagefault_wakeups_for_action() - get pagefault wakeups for host
412   * to initiate action
413   * @psoc: objmgr psoc
414   *
415   * Return: Min wakeups interval for host action on pagefault
416   */
417  uint8_t
418  pmo_get_min_pagefault_wakeups_for_action(struct wlan_objmgr_psoc *psoc);
419  
420  /*
421   * pmo_get_interval_for_pagefault_wakeup_counts: get ssr interval for pagefault
422   * @psoc: objmgr psoc
423   *
424   * Return: SSR interval for pagefault
425   */
426  uint32_t
427  pmo_get_interval_for_pagefault_wakeup_counts(struct wlan_objmgr_psoc *psoc);
428  
429  /*
430   * pmo_get_ssr_frequency_on_pagefault: get ssr frequency on pagefault
431   * @psoc: objmgr psoc
432   *
433   * Return: SSR frequency on pagefault
434   */
435  uint32_t pmo_get_ssr_frequency_on_pagefault(struct wlan_objmgr_psoc *psoc);
436  
437  /**
438   * pmo_get_vdev_bridge_addr() - API to get Bridge mac address
439   * @vdev: vdev object
440   * @bridgeaddr: Bridge mac address
441   *
442   * Helper function to get Bridge mac address
443   *
444   * Return: if success pmo vdev ctx else NULL
445   */
446  QDF_STATUS pmo_get_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
447  				    struct qdf_mac_addr *bridgeaddr);
448  
449  /**
450   * pmo_set_vdev_bridge_addr() - API to set Bridge mac address
451   * @vdev: vdev object
452   * @bridgeaddr: Bridge mac address
453   *
454   * API to set the Bridge MAC address
455   *
456   * Return: if success pmo vdev ctx else NULL
457   */
458  QDF_STATUS pmo_set_vdev_bridge_addr(struct wlan_objmgr_vdev *vdev,
459  				    struct qdf_mac_addr *bridgeaddr);
460  
461  #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
462  
463  /**
464   * pmo_core_get_listen_interval() - function to get configured
465   * listen interval
466   * @vdev: vdev objmgr vdev
467   * @listen_interval: Pointer variable to return listen interval
468   *
469   * This function allows get configured listen interval
470   *
471   * Return: QDF_STATUS
472   */
473  QDF_STATUS pmo_core_get_listen_interval(struct wlan_objmgr_vdev *vdev,
474  					uint32_t *listen_interval);
475  
476  #endif /* end  of _WLAN_PMO_MAIN_H_ */
477