xref: /wlan-driver/qca-wifi-host-cmn/cfg/inc/cfg_ucfg_api.h (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /**
21*5113495bSYour Name  * DOC: UCFG APIs for the configuration component.
22*5113495bSYour Name  *
23*5113495bSYour Name  * Logically, configuration exists at the psoc level. This means, each psoc can
24*5113495bSYour Name  * have its own custom configuration, and calls to lookup configuration take a
25*5113495bSYour Name  * psoc parameter for reference. E.g.
26*5113495bSYour Name  *
27*5113495bSYour Name  *	int32_t value = cfg_get(psoc, WLAN_SOME_INTEGER_CONFIG_ID);
28*5113495bSYour Name  *
29*5113495bSYour Name  * Configuration is cascading, and lookups happen in this order:
30*5113495bSYour Name  *
31*5113495bSYour Name  *	1) use psoc value, if configured
32*5113495bSYour Name  *	2) use global value, if configured
33*5113495bSYour Name  *	3) fallback to the default value for the configuration item
34*5113495bSYour Name  *
35*5113495bSYour Name  * This means a psoc configuration is a specialization of the global
36*5113495bSYour Name  * configuration, and does not need to explicitly set the same values if they
37*5113495bSYour Name  * would match the global config.
38*5113495bSYour Name  *
39*5113495bSYour Name  * In order to load and parse the global config, call cfg_parse(). In order to
40*5113495bSYour Name  * load and parse psoc configs, call cfg_psoc_parse(). cfg_parse() MUST be
41*5113495bSYour Name  * called before cfg_psoc_parse(), as global configuration will be consulted
42*5113495bSYour Name  * during the psoc parsing process.
43*5113495bSYour Name  *
44*5113495bSYour Name  * There are two basic lifecycles supported:
45*5113495bSYour Name  *
46*5113495bSYour Name  * 1) The type and number of psocs is *not* known at load time
47*5113495bSYour Name  *
48*5113495bSYour Name  *	// driver is loading
49*5113495bSYour Name  *	cfg_parse("/path/to/config");
50*5113495bSYour Name  *
51*5113495bSYour Name  *	...
52*5113495bSYour Name  *
53*5113495bSYour Name  *	// a psoc has just been created
54*5113495bSYour Name  *	cfg_psoc_parse(psoc, "/path/to/psoc/config");
55*5113495bSYour Name  *
56*5113495bSYour Name  *	...
57*5113495bSYour Name  *
58*5113495bSYour Name  *	// driver is unloading
59*5113495bSYour Name  *	cfg_release();
60*5113495bSYour Name  *
61*5113495bSYour Name  * 2) The type and number of psocs *is* known at load time
62*5113495bSYour Name  *
63*5113495bSYour Name  *	// driver is loading
64*5113495bSYour Name  *	cfg_parse("/path/to/config");
65*5113495bSYour Name  *
66*5113495bSYour Name  *	...
67*5113495bSYour Name  *
68*5113495bSYour Name  *	// for each psoc
69*5113495bSYour Name  *		cfg_psoc_parse(psoc, "/path/to/psoc/config");
70*5113495bSYour Name  *
71*5113495bSYour Name  *	// no further psocs will be created after this point
72*5113495bSYour Name  *	cfg_release();
73*5113495bSYour Name  *
74*5113495bSYour Name  *	...
75*5113495bSYour Name  *
76*5113495bSYour Name  *	// driver is unloaded later
77*5113495bSYour Name  *
78*5113495bSYour Name  * Each configuration store is reference counted to reduce memory footprint, and
79*5113495bSYour Name  * the configuration component itself will hold one ref count on the global
80*5113495bSYour Name  * config store. All psocs for which psoc-specific configurations have *not*
81*5113495bSYour Name  * been provided will reference the global config store. Psocs for which psoc-
82*5113495bSYour Name  * specific configurations *have* been provided will check for existings stores
83*5113495bSYour Name  * with a matching path to use, before parsing the specified configuration file.
84*5113495bSYour Name  *
85*5113495bSYour Name  * If, at some point in time, it is known that no further psocs will ever be
86*5113495bSYour Name  * created, a call to cfg_release() will release the global ref count held by
87*5113495bSYour Name  * the configuration component. For systems which specify psoc-specific configs
88*5113495bSYour Name  * for all psocs, this will release the unnecessary memory used by the global
89*5113495bSYour Name  * config store. Otherwise, calling cfg_release() at unload time will ensure
90*5113495bSYour Name  * the global config store is properly freed.
91*5113495bSYour Name  */
92*5113495bSYour Name 
93*5113495bSYour Name #ifndef __CFG_UCFG_H
94*5113495bSYour Name #define __CFG_UCFG_H
95*5113495bSYour Name 
96*5113495bSYour Name #include "cfg_all.h"
97*5113495bSYour Name #include "cfg_define.h"
98*5113495bSYour Name #include "i_cfg.h"
99*5113495bSYour Name #include "qdf_status.h"
100*5113495bSYour Name #include "qdf_str.h"
101*5113495bSYour Name #include "qdf_types.h"
102*5113495bSYour Name #include "wlan_objmgr_psoc_obj.h"
103*5113495bSYour Name 
104*5113495bSYour Name /**
105*5113495bSYour Name  * cfg_parse() - parse an ini file, and populate the global config storei
106*5113495bSYour Name  * @path: The full file path of the ini file to parse
107*5113495bSYour Name  *
108*5113495bSYour Name  * Note: A matching cfg_release() call is required to release allocated
109*5113495bSYour Name  * resources.
110*5113495bSYour Name  *
111*5113495bSYour Name  * The *.ini file format is a simple format consisting of a list of key/value
112*5113495bSYour Name  * pairs, separated by an '=' character. e.g.
113*5113495bSYour Name  *
114*5113495bSYour Name  *	gConfigItem1=some string value
115*5113495bSYour Name  *	gConfigItem2=0xabc
116*5113495bSYour Name  *
117*5113495bSYour Name  * Comments are also supported, initiated with the '#' character:
118*5113495bSYour Name  *
119*5113495bSYour Name  *	# This is a comment. It will be ignored by the *.ini parser
120*5113495bSYour Name  *	gConfigItem3=aa:bb:cc:dd:ee:ff # this is also a comment
121*5113495bSYour Name  *
122*5113495bSYour Name  * Several datatypes are natively supported:
123*5113495bSYour Name  *
124*5113495bSYour Name  *	gInt=-123 # bin (0b), octal (0o), hex (0x), and decimal supported
125*5113495bSYour Name  *	gUint=123 # a non-negative integer value
126*5113495bSYour Name  *	gBool=y # (1, Y, y) -> true; (0, N, n) -> false
127*5113495bSYour Name  *	gString=any string # strings are useful for representing complex types
128*5113495bSYour Name  *	gMacAddr=aa:bb:cc:dd:ee:ff # colons are optional, upper and lower case
129*5113495bSYour Name  *	gIpv4Addr=127.0.0.1 # uses typical dot-decimal notation
130*5113495bSYour Name  *	gIpv6Addr=::1 # typical notation, supporting zero-compression
131*5113495bSYour Name  *
132*5113495bSYour Name  * Return: QDF_STATUS
133*5113495bSYour Name  */
134*5113495bSYour Name QDF_STATUS cfg_parse(const char *path);
135*5113495bSYour Name 
136*5113495bSYour Name /**
137*5113495bSYour Name  * cfg_release() - release the global configuration store
138*5113495bSYour Name  *
139*5113495bSYour Name  * This API releases the configuration component's reference to the global
140*5113495bSYour Name  * config store.
141*5113495bSYour Name  *
142*5113495bSYour Name  * See also: this file's DOC section.
143*5113495bSYour Name  *
144*5113495bSYour Name  * Return: None
145*5113495bSYour Name  */
146*5113495bSYour Name void cfg_release(void);
147*5113495bSYour Name 
148*5113495bSYour Name /**
149*5113495bSYour Name  * cfg_psoc_parse() - specialize the config store for @psoc by parsing @path
150*5113495bSYour Name  * @psoc: The psoc whose config store should be specialized
151*5113495bSYour Name  * @path: The full file path of the ini file to parse
152*5113495bSYour Name  *
153*5113495bSYour Name  * See also: cfg_parse(), and this file's DOC section.
154*5113495bSYour Name  *
155*5113495bSYour Name  * Return: QDF_STATUS
156*5113495bSYour Name  */
157*5113495bSYour Name QDF_STATUS cfg_psoc_parse(struct wlan_objmgr_psoc *psoc, const char *path);
158*5113495bSYour Name 
159*5113495bSYour Name /**
160*5113495bSYour Name  * cfg_parse_to_psoc_store() - Parse file @path and update psoc ini store
161*5113495bSYour Name  * @psoc: The psoc whose config store should be updated
162*5113495bSYour Name  * @path: The full file path of the ini file to parse
163*5113495bSYour Name  *
164*5113495bSYour Name  * Return: QDF_STATUS
165*5113495bSYour Name  */
166*5113495bSYour Name QDF_STATUS cfg_parse_to_psoc_store(struct wlan_objmgr_psoc *psoc,
167*5113495bSYour Name 				   const char *path);
168*5113495bSYour Name 
169*5113495bSYour Name /**
170*5113495bSYour Name  * cfg_section_parse_to_psoc_store() - Parse specific section from file @path
171*5113495bSYour Name  *                                     and update psoc ini store
172*5113495bSYour Name  * @psoc: The psoc whose config store should be updated
173*5113495bSYour Name  * @path: The full file path of the ini file to parse
174*5113495bSYour Name  * @section_name: Section name to be parsed
175*5113495bSYour Name  *
176*5113495bSYour Name  * Return: QDF_STATUS
177*5113495bSYour Name  */
178*5113495bSYour Name QDF_STATUS cfg_section_parse_to_psoc_store(struct wlan_objmgr_psoc *psoc,
179*5113495bSYour Name 					   const char *path,
180*5113495bSYour Name 					   const char *section_name);
181*5113495bSYour Name 
182*5113495bSYour Name /**
183*5113495bSYour Name  * cfg_parse_to_global_store() - Parse file @path and update global ini store
184*5113495bSYour Name  * @path: The full file path of the ini file to parse
185*5113495bSYour Name  *
186*5113495bSYour Name  * Return: QDF_STATUS
187*5113495bSYour Name  */
188*5113495bSYour Name QDF_STATUS cfg_parse_to_global_store(const char *path);
189*5113495bSYour Name 
190*5113495bSYour Name /**
191*5113495bSYour Name  * ucfg_cfg_store_print() - prints the cfg ini/non ini logs
192*5113495bSYour Name  * @psoc: psoc
193*5113495bSYour Name  *
194*5113495bSYour Name  * Return: QDF_STATUS
195*5113495bSYour Name  */
196*5113495bSYour Name QDF_STATUS ucfg_cfg_store_print(struct wlan_objmgr_psoc *psoc);
197*5113495bSYour Name 
198*5113495bSYour Name /**
199*5113495bSYour Name  * ucfg_cfg_ini_config_print() - prints the cfg ini/non ini to buffer
200*5113495bSYour Name  * @psoc: psoc
201*5113495bSYour Name  * @buf: cache to save ini config
202*5113495bSYour Name  * @plen: the pointer to length
203*5113495bSYour Name  * @buflen: total buf length
204*5113495bSYour Name  *
205*5113495bSYour Name  * Return: QDF_STATUS
206*5113495bSYour Name  */
207*5113495bSYour Name QDF_STATUS ucfg_cfg_ini_config_print(struct wlan_objmgr_psoc *psoc,
208*5113495bSYour Name 				     uint8_t *buf, ssize_t *plen,
209*5113495bSYour Name 				     ssize_t buflen);
210*5113495bSYour Name /**
211*5113495bSYour Name  * cfg_valid_ini_check() - check ini file for invalid characters
212*5113495bSYour Name  * @path: path to ini file
213*5113495bSYour Name  *
214*5113495bSYour Name  * Return: true if no invalid characters found, false otherwise
215*5113495bSYour Name  */
216*5113495bSYour Name bool cfg_valid_ini_check(const char *path);
217*5113495bSYour Name 
218*5113495bSYour Name /**
219*5113495bSYour Name  * cfg_get() - lookup the configured value for @id from @psoc
220*5113495bSYour Name  * @psoc: The psoc from which to lookup the configured value
221*5113495bSYour Name  * @id: The id of the configured value to lookup
222*5113495bSYour Name  *
223*5113495bSYour Name  * E.g.
224*5113495bSYour Name  *
225*5113495bSYour Name  *	int32_t value = cfg_get(psoc, WLAN_SOME_INTEGER_CONFIG_ID);
226*5113495bSYour Name  *
227*5113495bSYour Name  * Return: The configured value
228*5113495bSYour Name  */
229*5113495bSYour Name #define cfg_get(psoc, id) __cfg_get(psoc, __##id)
230*5113495bSYour Name 
231*5113495bSYour Name /* Configuration Access APIs */
232*5113495bSYour Name #define __do_call(op, args...) op(args)
233*5113495bSYour Name #define do_call(op, args) __do_call(op, rm_parens args)
234*5113495bSYour Name 
235*5113495bSYour Name #define cfg_id(id) #id
236*5113495bSYour Name 
237*5113495bSYour Name #define __cfg_mtype(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
238*5113495bSYour Name 	mtype
239*5113495bSYour Name #define cfg_mtype(id) do_call(__cfg_mtype, id)
240*5113495bSYour Name 
241*5113495bSYour Name #define __cfg_type(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
242*5113495bSYour Name 	ctype
243*5113495bSYour Name #define cfg_type(id) do_call(__cfg_type, id)
244*5113495bSYour Name 
245*5113495bSYour Name #define __cfg_name(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
246*5113495bSYour Name 	name
247*5113495bSYour Name #define cfg_name(id) do_call(__cfg_name, id)
248*5113495bSYour Name 
249*5113495bSYour Name #define __cfg_min(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
250*5113495bSYour Name 	min
251*5113495bSYour Name #define cfg_min(id) do_call(__cfg_min, id)
252*5113495bSYour Name 
253*5113495bSYour Name #define __cfg_max(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
254*5113495bSYour Name 	max
255*5113495bSYour Name #define cfg_max(id) do_call(__cfg_max, id)
256*5113495bSYour Name 
257*5113495bSYour Name #define __cfg_fb(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
258*5113495bSYour Name 	fallback
259*5113495bSYour Name #define cfg_fallback(id) do_call(__cfg_fb, id)
260*5113495bSYour Name 
261*5113495bSYour Name #define __cfg_desc(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
262*5113495bSYour Name 	desc
263*5113495bSYour Name #define cfg_description(id) do_call(__cfg_desc, id)
264*5113495bSYour Name 
265*5113495bSYour Name #define __cfg_def(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
266*5113495bSYour Name 	def
267*5113495bSYour Name #define cfg_default(id) do_call(__cfg_def, id)
268*5113495bSYour Name 
269*5113495bSYour Name #define __cfg_str(id...) #id
270*5113495bSYour Name #define cfg_str(id) #id __cfg_str(id)
271*5113495bSYour Name 
272*5113495bSYour Name /* validate APIs */
273*5113495bSYour Name static inline bool
cfg_string_in_range(const char * value,qdf_size_t min_len,qdf_size_t max_len)274*5113495bSYour Name cfg_string_in_range(const char *value, qdf_size_t min_len, qdf_size_t max_len)
275*5113495bSYour Name {
276*5113495bSYour Name 	qdf_size_t len = qdf_str_len(value);
277*5113495bSYour Name 
278*5113495bSYour Name 	return len >= min_len && len <= max_len;
279*5113495bSYour Name }
280*5113495bSYour Name 
281*5113495bSYour Name #define __cfg_INT_in_range(value, min, max) (value >= min && value <= max)
282*5113495bSYour Name #define __cfg_UINT_in_range(value, min, max) (value >= min && value <= max)
283*5113495bSYour Name #define __cfg_STRING_in_range(value, min_len, max_len) \
284*5113495bSYour Name 	cfg_string_in_range(value, min_len, max_len)
285*5113495bSYour Name 
286*5113495bSYour Name #define __cfg_in_range(id, value, mtype) \
287*5113495bSYour Name 	__cfg_ ## mtype ## _in_range(value, cfg_min(id), cfg_max(id))
288*5113495bSYour Name 
289*5113495bSYour Name /* this may look redundant, but forces @mtype to be expanded */
290*5113495bSYour Name #define __cfg_in_range_type(id, value, mtype) \
291*5113495bSYour Name 	__cfg_in_range(id, value, mtype)
292*5113495bSYour Name 
293*5113495bSYour Name #define cfg_in_range(id, value) __cfg_in_range_type(id, value, cfg_mtype(id))
294*5113495bSYour Name 
295*5113495bSYour Name /* Value-or-Default APIs */
296*5113495bSYour Name #define __cfg_value_or_default(id, value, def) \
297*5113495bSYour Name 	(cfg_in_range(id, value) ? value : def)
298*5113495bSYour Name 
299*5113495bSYour Name #define cfg_value_or_default(id, value) \
300*5113495bSYour Name 	__cfg_value_or_default(id, value, cfg_default(id))
301*5113495bSYour Name 
302*5113495bSYour Name /* Value-or-Clamped APIs */
303*5113495bSYour Name #define __cfg_clamp(val, min, max) (val < min ? min : (val > max ? max : val))
304*5113495bSYour Name #define cfg_clamp(id, value) __cfg_clamp(value, cfg_min(id), cfg_max(id))
305*5113495bSYour Name 
306*5113495bSYour Name #endif /* __CFG_UCFG_H */
307*5113495bSYour Name 
308