xref: /wlan-dirver/qca-wifi-host-cmn/umac/cp_stats/core/src/wlan_cp_stats_comp_handler.c (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
1 /*
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: wlan_cp_stats_comp_handler.c
21  *
22  * This file maintain definitions to APIs which handle attach/detach of other
23  * UMAC component specific cp stat object to cp stats
24  */
25 #include "wlan_cp_stats_comp_handler.h"
26 #include "wlan_cp_stats_defs.h"
27 #include <wlan_cp_stats_ucfg_api.h>
28 #include <wlan_cp_stats_utils_api.h>
29 
30 static QDF_STATUS
31 wlan_cp_stats_psoc_comp_obj_config
32 (struct wlan_objmgr_psoc *psoc, enum wlan_cp_stats_comp_id comp_id,
33 	enum wlan_cp_stats_cfg_state cfg_state, void *comp_priv_obj)
34 {
35 	struct psoc_cp_stats *psoc_cs;
36 
37 	psoc_cs = wlan_cp_stats_get_psoc_stats_obj(psoc);
38 	if (!psoc_cs) {
39 		cp_stats_err("psoc cp stats object is null");
40 		return QDF_STATUS_E_INVAL;
41 	}
42 
43 	wlan_cp_stats_psoc_obj_lock(psoc_cs);
44 	if (cfg_state == WLAN_CP_STATS_OBJ_ATTACH) {
45 		if (psoc_cs->psoc_comp_priv_obj[comp_id]) {
46 			wlan_cp_stats_psoc_obj_unlock(psoc_cs);
47 			return QDF_STATUS_E_EXISTS;
48 		}
49 		psoc_cs->psoc_comp_priv_obj[comp_id] = comp_priv_obj;
50 	} else if (cfg_state == WLAN_CP_STATS_OBJ_DETACH) {
51 		if (psoc_cs->psoc_comp_priv_obj[comp_id] != comp_priv_obj) {
52 			wlan_cp_stats_psoc_obj_unlock(psoc_cs);
53 			return QDF_STATUS_E_INVAL;
54 		}
55 		psoc_cs->psoc_comp_priv_obj[comp_id] = NULL;
56 	}
57 
58 	wlan_cp_stats_psoc_obj_unlock(psoc_cs);
59 	return QDF_STATUS_SUCCESS;
60 }
61 
62 static QDF_STATUS
63 wlan_cp_stats_pdev_comp_obj_config
64 (struct wlan_objmgr_pdev *pdev, enum wlan_cp_stats_comp_id comp_id,
65 	enum wlan_cp_stats_cfg_state cfg_state, void *comp_priv_obj)
66 {
67 	struct pdev_cp_stats *pdev_cs;
68 
69 	pdev_cs = wlan_cp_stats_get_pdev_stats_obj(pdev);
70 	if (!pdev_cs) {
71 		cp_stats_err("pdev cp stats object is null");
72 		return QDF_STATUS_E_INVAL;
73 	}
74 
75 	wlan_cp_stats_pdev_obj_lock(pdev_cs);
76 	if (cfg_state == WLAN_CP_STATS_OBJ_ATTACH) {
77 		if (pdev_cs->pdev_comp_priv_obj[comp_id]) {
78 			wlan_cp_stats_pdev_obj_unlock(pdev_cs);
79 			return QDF_STATUS_E_EXISTS;
80 		}
81 		pdev_cs->pdev_comp_priv_obj[comp_id] = comp_priv_obj;
82 	} else if (cfg_state == WLAN_CP_STATS_OBJ_DETACH) {
83 		if (pdev_cs->pdev_comp_priv_obj[comp_id] != comp_priv_obj) {
84 			wlan_cp_stats_pdev_obj_unlock(pdev_cs);
85 			return QDF_STATUS_E_INVAL;
86 		}
87 		pdev_cs->pdev_comp_priv_obj[comp_id] = NULL;
88 	}
89 
90 	wlan_cp_stats_pdev_obj_unlock(pdev_cs);
91 	return QDF_STATUS_SUCCESS;
92 }
93 
94 static QDF_STATUS
95 wlan_cp_stats_vdev_comp_obj_config
96 (struct wlan_objmgr_vdev *vdev, enum wlan_cp_stats_comp_id comp_id,
97 	enum wlan_cp_stats_cfg_state cfg_state, void *comp_priv_obj)
98 {
99 	struct vdev_cp_stats *vdev_cs;
100 
101 	vdev_cs = wlan_cp_stats_get_vdev_stats_obj(vdev);
102 	if (!vdev_cs) {
103 		cp_stats_err("vdev cp stats object is null");
104 		return QDF_STATUS_E_INVAL;
105 	}
106 
107 	wlan_cp_stats_vdev_obj_lock(vdev_cs);
108 	if (cfg_state == WLAN_CP_STATS_OBJ_ATTACH) {
109 		if (vdev_cs->vdev_comp_priv_obj[comp_id]) {
110 			wlan_cp_stats_vdev_obj_unlock(vdev_cs);
111 			return QDF_STATUS_E_EXISTS;
112 		}
113 		vdev_cs->vdev_comp_priv_obj[comp_id] = comp_priv_obj;
114 	} else if (cfg_state == WLAN_CP_STATS_OBJ_DETACH) {
115 		if (vdev_cs->vdev_comp_priv_obj[comp_id] != comp_priv_obj) {
116 			wlan_cp_stats_vdev_obj_unlock(vdev_cs);
117 			return QDF_STATUS_E_INVAL;
118 		}
119 		vdev_cs->vdev_comp_priv_obj[comp_id] = NULL;
120 	}
121 
122 	wlan_cp_stats_vdev_obj_unlock(vdev_cs);
123 	return QDF_STATUS_SUCCESS;
124 }
125 
126 static QDF_STATUS
127 wlan_cp_stats_peer_comp_obj_config
128 (struct wlan_objmgr_peer *peer, enum wlan_cp_stats_comp_id comp_id,
129 	enum wlan_cp_stats_cfg_state cfg_state, void *comp_priv_obj)
130 {
131 	struct peer_cp_stats *peer_cs;
132 
133 	peer_cs = wlan_cp_stats_get_peer_stats_obj(peer);
134 	if (!peer_cs) {
135 		cp_stats_err("peer cp stats object is null");
136 		return QDF_STATUS_E_INVAL;
137 	}
138 
139 	wlan_cp_stats_peer_obj_lock(peer_cs);
140 	if (cfg_state == WLAN_CP_STATS_OBJ_ATTACH) {
141 		if (peer_cs->peer_comp_priv_obj[comp_id]) {
142 			wlan_cp_stats_peer_obj_unlock(peer_cs);
143 			return QDF_STATUS_E_EXISTS;
144 		}
145 		peer_cs->peer_comp_priv_obj[comp_id] = comp_priv_obj;
146 	} else if (cfg_state == WLAN_CP_STATS_OBJ_DETACH) {
147 		if (peer_cs->peer_comp_priv_obj[comp_id] != comp_priv_obj) {
148 			wlan_cp_stats_peer_obj_unlock(peer_cs);
149 			return QDF_STATUS_E_INVAL;
150 		}
151 		peer_cs->peer_comp_priv_obj[comp_id] = NULL;
152 	}
153 
154 	wlan_cp_stats_peer_obj_unlock(peer_cs);
155 	return QDF_STATUS_SUCCESS;
156 }
157 
158 QDF_STATUS
159 wlan_cp_stats_comp_obj_config(enum wlan_objmgr_obj_type obj_type,
160 				enum wlan_cp_stats_cfg_state cfg_state,
161 				enum wlan_cp_stats_comp_id comp_id,
162 				void *cmn_obj, void *comp_priv_obj)
163 {
164 	QDF_STATUS status;
165 
166 	if (!cmn_obj) {
167 		cp_stats_err("Common object is NULL");
168 		return QDF_STATUS_E_INVAL;
169 	}
170 
171 	/* component id is invalid */
172 	if (comp_id >= WLAN_CP_STATS_MAX_COMPONENTS) {
173 		cp_stats_err("Invalid component Id");
174 		return QDF_STATUS_MAXCOMP_FAIL;
175 	}
176 
177 	switch (obj_type) {
178 	case WLAN_PSOC_OP:
179 		status =
180 			wlan_cp_stats_psoc_comp_obj_config(
181 					(struct wlan_objmgr_psoc *)cmn_obj,
182 					comp_id, cfg_state, comp_priv_obj);
183 		break;
184 	case WLAN_PDEV_OP:
185 		status =
186 			wlan_cp_stats_pdev_comp_obj_config(
187 					(struct wlan_objmgr_pdev *)cmn_obj,
188 					comp_id, cfg_state, comp_priv_obj);
189 		break;
190 	case WLAN_VDEV_OP:
191 		status =
192 			wlan_cp_stats_vdev_comp_obj_config(
193 					(struct wlan_objmgr_vdev *)cmn_obj,
194 					comp_id, cfg_state, comp_priv_obj);
195 		break;
196 	case WLAN_PEER_OP:
197 		status =
198 			wlan_cp_stats_peer_comp_obj_config(
199 					(struct wlan_objmgr_peer *)cmn_obj,
200 					comp_id, cfg_state, comp_priv_obj);
201 		break;
202 	default:
203 		cp_stats_err("Invalid common object");
204 		return QDF_STATUS_E_INVAL;
205 	}
206 
207 	return status;
208 }
209