1 /*
2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 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 /**
21 * DOC: This file contains various object manager related wrappers and helpers
22 */
23
24 #ifndef _WLAN_PMO_OBJMGR_H
25 #define _WLAN_PMO_OBJMGR_H
26
27 #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
28
29 #include "wlan_cmn.h"
30 #include "wlan_objmgr_cmn.h"
31 #include "wlan_objmgr_peer_obj.h"
32 #include "wlan_objmgr_vdev_obj.h"
33 #include "wlan_objmgr_pdev_obj.h"
34 #include "wlan_objmgr_psoc_obj.h"
35 #include "wlan_pmo_obj_mgmt_public_struct.h"
36 #include "wlan_utility.h"
37
38
39 /* Get/Put Ref */
40
41 #define pmo_peer_get_ref(peer) wlan_objmgr_peer_try_get_ref(peer, WLAN_PMO_ID)
42 #define pmo_peer_put_ref(peer) wlan_objmgr_peer_release_ref(peer, WLAN_PMO_ID)
43
44 #define pmo_vdev_get_ref(vdev) wlan_objmgr_vdev_try_get_ref(vdev, WLAN_PMO_ID)
45
46 #define pmo_pdev_get_ref(pdev) wlan_objmgr_pdev_try_get_ref(pdev, WLAN_PMO_ID)
47 #define pmo_pdev_put_ref(pdev) wlan_objmgr_pdev_release_ref(pdev, WLAN_PMO_ID)
48
49 #define pmo_psoc_get_ref(psoc) wlan_objmgr_psoc_try_get_ref(psoc, WLAN_PMO_ID)
50 #define pmo_psoc_put_ref(psoc) wlan_objmgr_psoc_release_ref(psoc, WLAN_PMO_ID)
51
52 /* Private Data */
53
54 #define pmo_vdev_get_priv_nolock(vdev) \
55 wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_PMO)
56 #define pmo_psoc_get_priv_nolock(psoc) \
57 wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_PMO)
58
59 /* Ids */
60
61 static inline uint8_t
pmo_vdev_get_id(struct wlan_objmgr_vdev * vdev)62 pmo_vdev_get_id(struct wlan_objmgr_vdev *vdev)
63 {
64 uint8_t vdev_id;
65
66 vdev_id = wlan_vdev_get_id(vdev);
67 QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
68
69 return vdev_id;
70 }
71
72 /* Tree Navigation */
73
74 /*
75 * !PLEASE READ!
76 *
77 * The following are objmgr naviation helpers for traversing objmgr object
78 * trees.
79 *
80 * Objmgr ensures parents of an objmgr object cannot be freed while a valid
81 * reference to one of its children is held. Based on this fact, all of these
82 * navigation helpers make the following assumptions to ensure safe usage:
83 *
84 * 1) The caller must hold a valid reference to the input objmgr object!
85 * E.g. Use pmo_[peer|vdev|pdev|psoc]_get_ref() on the input objmgr object
86 * before using these APIs
87 * 2) Given assumption #1, the caller does not need to hold a reference to the
88 * parents of the input objmgr object
89 * 3) Given assumption #1, parents of the input objmgr object cannot be null
90 * 4) Given assumption #1, private contexts of any parent of the input objmgr
91 * object cannot be null
92 *
93 * These characteristics remove the need for most sanity checks when dealing
94 * with objmgr objects. However, please note that if you ever walk the tree
95 * from parent to child, references must be acquired all the way down!
96 *
97 * Example #1:
98 *
99 * psoc = pmo_vdev_get_psoc(vdev);
100 * if (!psoc)
101 * // this is dead code
102 *
103 * Example #2:
104 *
105 * psoc_priv = pmo_psoc_get_priv(psoc);
106 * if (!psoci_priv)
107 * // this is dead code
108 *
109 * Example #3:
110 *
111 * status = pmo_vdev_get_ref(vdev);
112 *
113 * ...
114 *
115 * psoc = pmo_vdev_get_psoc(vdev);
116 *
117 * // the next line is redundant, don't do it!
118 * status = pmo_psoc_get_ref(psoc);
119 */
120
121 /* Tree Navigation: psoc */
122
123 static inline struct pmo_psoc_priv_obj *
pmo_psoc_get_priv(struct wlan_objmgr_psoc * psoc)124 pmo_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
125 {
126 struct pmo_psoc_priv_obj *psoc_priv;
127
128 psoc_priv = pmo_psoc_get_priv_nolock(psoc);
129 QDF_BUG(psoc_priv);
130
131 return psoc_priv;
132 }
133
__pmo_spinlock_bh_safe(struct pmo_psoc_priv_obj * psoc_ctx)134 static inline bool __pmo_spinlock_bh_safe(struct pmo_psoc_priv_obj *psoc_ctx)
135 {
136 if (!psoc_ctx)
137 return false;
138
139 qdf_spin_lock_bh(&psoc_ctx->lock);
140
141 return true;
142 }
143
144 #define pmo_psoc_with_ctx(psoc, cursor) \
145 for (cursor = pmo_psoc_get_priv(psoc); \
146 __pmo_spinlock_bh_safe(cursor); \
147 qdf_spin_unlock_bh(&cursor->lock), cursor = NULL)
148
149 /* Tree Navigation: pdev */
150
151 static inline struct wlan_objmgr_psoc *
pmo_pdev_get_psoc(struct wlan_objmgr_pdev * pdev)152 pmo_pdev_get_psoc(struct wlan_objmgr_pdev *pdev)
153 {
154 struct wlan_objmgr_psoc *psoc;
155
156 psoc = wlan_pdev_get_psoc(pdev);
157 QDF_BUG(psoc);
158
159 return psoc;
160 }
161
162 static inline struct pmo_psoc_priv_obj *
pmo_pdev_get_psoc_priv(struct wlan_objmgr_pdev * pdev)163 pmo_pdev_get_psoc_priv(struct wlan_objmgr_pdev *pdev)
164 {
165 return pmo_psoc_get_priv(pmo_pdev_get_psoc(pdev));
166 }
167
168 /* Tree Navigation: vdev */
169
170 static inline struct pmo_vdev_priv_obj *
pmo_vdev_get_priv(struct wlan_objmgr_vdev * vdev)171 pmo_vdev_get_priv(struct wlan_objmgr_vdev *vdev)
172 {
173 struct pmo_vdev_priv_obj *vdev_priv;
174
175 vdev_priv = pmo_vdev_get_priv_nolock(vdev);
176 QDF_BUG(vdev_priv);
177
178 return vdev_priv;
179 }
180
181 static inline struct wlan_objmgr_pdev *
pmo_vdev_get_pdev(struct wlan_objmgr_vdev * vdev)182 pmo_vdev_get_pdev(struct wlan_objmgr_vdev *vdev)
183 {
184 struct wlan_objmgr_pdev *pdev;
185
186 pdev = wlan_vdev_get_pdev(vdev);
187 QDF_BUG(pdev);
188
189 return pdev;
190 }
191
192 static inline struct wlan_objmgr_psoc *
pmo_vdev_get_psoc(struct wlan_objmgr_vdev * vdev)193 pmo_vdev_get_psoc(struct wlan_objmgr_vdev *vdev)
194 {
195 return pmo_pdev_get_psoc(pmo_vdev_get_pdev(vdev));
196 }
197
198 static inline struct pmo_psoc_priv_obj *
pmo_vdev_get_psoc_priv(struct wlan_objmgr_vdev * vdev)199 pmo_vdev_get_psoc_priv(struct wlan_objmgr_vdev *vdev)
200 {
201 return pmo_psoc_get_priv(pmo_pdev_get_psoc(pmo_vdev_get_pdev(vdev)));
202 }
203
204 #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */
205
206 #endif /* _WLAN_PMO_OBJMGR_H */
207