blob: 6fcb0b78544fbea1ecba2bf8f35726bde0bab37f [file] [log] [blame]
Nachiket Kukade98f562a2017-12-15 12:18:07 +05301/*
2 * Copyright (c) 2018 The Linux Foundation. All rights reserved.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/**
20 * DOC: This file contains various object manager related wrappers and helpers
21 */
22
23#ifndef _WLAN_DISA_OBJMGR_H
24#define _WLAN_DISA_OBJMGR_H
25
26#include "wlan_cmn.h"
27#include "wlan_objmgr_cmn.h"
28#include "wlan_objmgr_vdev_obj.h"
29#include "wlan_objmgr_pdev_obj.h"
30#include "wlan_objmgr_psoc_obj.h"
31#include "wlan_disa_obj_mgmt_public_struct.h"
32
33/* Get/Put Ref */
34
35/**
36 * disa_psoc_get_ref() - DISA wrapper to increment ref count, if allowed
37 * @psoc: PSOC object
38 *
39 * DISA wrapper to increment ref count after checking valid object state
40 *
41 * Return: SUCCESS/FAILURE
42 */
43static inline QDF_STATUS disa_psoc_get_ref(struct wlan_objmgr_psoc *psoc)
44{
45 return wlan_objmgr_psoc_try_get_ref(psoc, WLAN_DISA_ID);
46}
47
48/**
49 * disa_psoc_put_ref() - DISA wrapper to decrement ref count
50 * @psoc: PSOC object
51 *
52 * DISA wrapper to decrement ref count of psoc
53 *
54 * Return: SUCCESS/FAILURE
55 */
56static inline void disa_psoc_put_ref(struct wlan_objmgr_psoc *psoc)
57{
58 return wlan_objmgr_psoc_release_ref(psoc, WLAN_DISA_ID);
59}
60
61/* Private Data */
62
63/**
64 * disa_psoc_get_priv_nolock(): DISA wrapper to retrieve component object
65 * @psoc: Psoc pointer
66 *
67 * DISA wrapper used to get the component private object pointer
68 *
69 * Return: Component private object
70 */
71static inline void *disa_psoc_get_priv_nolock(struct wlan_objmgr_psoc *psoc)
72{
73 return wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_DISA);
74}
75
76/* Ids */
77static inline uint8_t
78disa_vdev_get_id(struct wlan_objmgr_vdev *vdev)
79{
80 uint8_t vdev_id;
81
82 vdev_id = wlan_vdev_get_id(vdev);
83 QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
84
85 return vdev_id;
86}
87
88/* Tree Navigation */
89
90/**
91 * !PLEASE READ!
92 *
93 * The following are objmgr navigation helpers for traversing objmgr object
94 * trees.
95 *
96 * Objmgr ensures parents of an objmgr object cannot be freed while a valid
97 * reference to one of its children is held. Based on this fact, all of these
98 * navigation helpers make the following assumptions to ensure safe usage:
99 *
100 * 1) The caller must hold a valid reference to the input objmgr object!
101 * E.g. Use disa_[peer|vdev|pdev|psoc]_get_ref() on the input objmgr
102 * object before using these APIs
103 * 2) Given assumption #1, the caller does not need to hold a reference to the
104 * parents of the input objmgr object
105 * 3) Given assumption #1, parents of the input objmgr object cannot be null
106 * 4) Given assumption #1, private contexts of any parent of the input objmgr
107 * object cannot be null
108 *
109 * These characteristics remove the need for most sanity checks when dealing
110 * with objmgr objects. However, please note that if you ever walk the tree
111 * from parent to child, references must be acquired all the way down!
112 *
113 * Example #1:
114 *
115 * psoc = disa_vdev_get_psoc(vdev);
116 * if (!psoc)
117 * // this is dead code
118 *
119 * Example #2:
120 *
121 * psoc_priv = disa_psoc_get_priv(psoc);
122 * if (!psoc_priv)
123 * // this is dead code
124 *
125 * Example #3:
126 *
127 * status = disa_psoc_get_ref(psoc);
128 *
129 * ...
130 *
131 * psoc = disa_vdev_get_psoc(vdev);
132 *
133 * // the next line is redundant, don't do it!
134 * status = disa_psoc_get_ref(psoc);
135 */
136
137/* Tree Navigation: psoc */
138static inline struct disa_psoc_priv_obj *
139disa_psoc_get_priv(struct wlan_objmgr_psoc *psoc)
140{
141 struct disa_psoc_priv_obj *psoc_priv;
142
143 psoc_priv = disa_psoc_get_priv_nolock(psoc);
144 QDF_BUG(psoc_priv);
145
146 return psoc_priv;
147}
148
149static inline struct wlan_objmgr_vdev *
150disa_psoc_get_vdev(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
151{
152 struct wlan_objmgr_vdev *vdev;
153
154 QDF_BUG(vdev_id < WLAN_UMAC_PSOC_MAX_VDEVS);
155 if (vdev_id >= WLAN_UMAC_PSOC_MAX_VDEVS)
156 return NULL;
157
158 wlan_psoc_obj_lock(psoc);
159 vdev = psoc->soc_objmgr.wlan_vdev_list[vdev_id];
160 wlan_psoc_obj_unlock(psoc);
161
162 return vdev;
163}
164
165/* Tree Navigation: pdev */
166static inline struct wlan_objmgr_psoc *
167disa_pdev_get_psoc(struct wlan_objmgr_pdev *pdev)
168{
169 struct wlan_objmgr_psoc *psoc;
170
171 psoc = wlan_pdev_get_psoc(pdev);
172 QDF_BUG(psoc);
173
174 return psoc;
175}
176
177/* Tree Navigation: vdev */
178static inline struct wlan_objmgr_pdev *
179disa_vdev_get_pdev(struct wlan_objmgr_vdev *vdev)
180{
181 struct wlan_objmgr_pdev *pdev;
182
183 pdev = wlan_vdev_get_pdev(vdev);
184 QDF_BUG(pdev);
185
186 return pdev;
187}
188
189static inline struct wlan_objmgr_psoc *
190disa_vdev_get_psoc(struct wlan_objmgr_vdev *vdev)
191{
192 return disa_pdev_get_psoc(disa_vdev_get_pdev(vdev));
193}
194
195#endif /* _WLAN_DISA_OBJMGR_H */