cfg_ucfg_api.h 9.8 KB

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