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