bcmiov.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. * bcmiov.h
  3. * Common iovar handling/parsing support - batching, parsing, sub-cmd dispatch etc.
  4. * To be used in firmware and host apps or dhd - reducing code size,
  5. * duplication, and maintenance overhead.
  6. *
  7. * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
  8. *
  9. * Copyright (C) 1999-2020, Broadcom Corporation
  10. *
  11. * Unless you and Broadcom execute a separate written software license
  12. * agreement governing use of this software, this software is licensed to you
  13. * under the terms of the GNU General Public License version 2 (the "GPL"),
  14. * available at http://www.broadcom.com/licenses/GPLv2.php, with the
  15. * following added to such license:
  16. *
  17. * As a special exception, the copyright holders of this software give you
  18. * permission to link this software with independent modules, and to copy and
  19. * distribute the resulting executable under terms of your choice, provided that
  20. * you also meet, for each linked independent module, the terms and conditions of
  21. * the license of that module. An independent module is a module which is not
  22. * derived from this software. The special exception does not apply to any
  23. * modifications of the software.
  24. *
  25. * Notwithstanding the above, under no circumstances may you combine this
  26. * software in any way with any other Broadcom software provided under a license
  27. * other than the GPL, without Broadcom's express prior written consent.
  28. *
  29. *
  30. * <<Broadcom-WL-IPTag/Open:>>
  31. *
  32. * $Id$
  33. */
  34. #ifndef _bcmiov_h_
  35. #define _bcmiov_h_
  36. #include <typedefs.h>
  37. #include <bcmutils.h>
  38. #include <wlioctl.h>
  39. #ifdef BCMDRIVER
  40. #include <osl.h>
  41. #else
  42. #include <stddef.h> /* For size_t */
  43. #endif /* BCMDRIVER */
  44. /* Forward declarations */
  45. typedef uint16 bcm_iov_cmd_id_t;
  46. typedef uint16 bcm_iov_cmd_flags_t;
  47. typedef uint16 bcm_iov_cmd_mflags_t;
  48. typedef struct bcm_iov_cmd_info bcm_iov_cmd_info_t;
  49. typedef struct bcm_iov_cmd_digest bcm_iov_cmd_digest_t;
  50. typedef struct bcm_iov_cmd_tlv_info bcm_iov_cmd_tlv_info_t;
  51. typedef struct bcm_iov_buf bcm_iov_buf_t;
  52. typedef struct bcm_iov_batch_buf bcm_iov_batch_buf_t;
  53. typedef struct bcm_iov_parse_context bcm_iov_parse_context_t;
  54. typedef struct bcm_iov_sub_cmd_context bcm_iov_sub_cmd_context_t;
  55. typedef void* (*bcm_iov_malloc_t)(void* alloc_ctx, size_t len);
  56. typedef void (*bcm_iov_free_t)(void* alloc_ctx, void *buf, size_t len);
  57. typedef uint8 bcm_iov_tlp_data_type_t;
  58. typedef struct bcm_iov_tlp bcm_iov_tlp_t;
  59. typedef struct bcm_iov_tlp_node bcm_iov_tlp_node_t;
  60. typedef struct bcm_iov_batch_subcmd bcm_iov_batch_subcmd_t;
  61. /*
  62. * iov validation handler - All the common checks that are required
  63. * for processing of iovars for any given command.
  64. */
  65. typedef int (*bcm_iov_cmd_validate_t)(const bcm_iov_cmd_digest_t *dig,
  66. uint32 actionid, const uint8* ibuf, size_t ilen, uint8 *obuf, size_t *olen);
  67. /* iov get handler - process subcommand specific input and return output.
  68. * input and output may overlap, so the callee needs to check if
  69. * that is supported. For xtlv data a tlv digest is provided to make
  70. * parsing simpler. Output tlvs may be packed into output buffer using
  71. * bcm xtlv support. olen is input/output parameter. On input contains
  72. * max available obuf length and callee must fill the correct length
  73. * to represent the length of output returned.
  74. */
  75. typedef int (*bcm_iov_cmd_get_t)(const bcm_iov_cmd_digest_t *dig,
  76. const uint8* ibuf, size_t ilen, uint8 *obuf, size_t *olen);
  77. /* iov set handler - process subcommand specific input and return output
  78. * input and output may overlap, so the callee needs to check if
  79. * that is supported. olen is input/output parameter. On input contains
  80. * max available obuf length and callee must fill the correct length
  81. * to represent the length of output returned.
  82. */
  83. typedef int (*bcm_iov_cmd_set_t)(const bcm_iov_cmd_digest_t *dig,
  84. const uint8* ibuf, size_t ilen, uint8 *obuf, size_t *olen);
  85. /* iov (sub-cmd) batch - a vector of commands. count can be zero
  86. * to support a version query. Each command is a tlv - whose data
  87. * portion may have an optional return status, followed by a fixed
  88. * length data header, optionally followed by tlvs.
  89. * cmd = type|length|<status|options>[header][tlvs]
  90. */
  91. /*
  92. * Batch sub-commands have status length included in the
  93. * response length packed in TLV.
  94. */
  95. #define BCM_IOV_STATUS_LEN sizeof(uint32)
  96. /* batch version is indicated by setting high bit. */
  97. #define BCM_IOV_BATCH_MASK 0x8000
  98. /*
  99. * Batched commands will have the following memory layout
  100. * +--------+---------+--------+-------+
  101. * |version |count | is_set |sub-cmd|
  102. * +--------+---------+--------+-------+
  103. * version >= 0x8000
  104. * count = number of sub-commands encoded in the iov buf
  105. * sub-cmd one or more sub-commands for processing
  106. * Where sub-cmd is padded byte buffer with memory layout as follows
  107. * +--------+---------+-----------------------+-------------+------
  108. * |cmd-id |length |IN(options) OUT(status)|command data |......
  109. * +--------+---------+-----------------------+-------------+------
  110. * cmd-id =sub-command ID
  111. * length = length of this sub-command
  112. * IN(options) = On input processing options/flags for this command
  113. * OUT(status) on output processing status for this command
  114. * command data = encapsulated IOVAR data as a single structure or packed TLVs for each
  115. * individual sub-command.
  116. */
  117. struct bcm_iov_batch_subcmd {
  118. uint16 id;
  119. uint16 len;
  120. union {
  121. uint32 options;
  122. uint32 status;
  123. } u;
  124. uint8 data[1];
  125. };
  126. struct bcm_iov_batch_buf {
  127. uint16 version;
  128. uint8 count;
  129. uint8 is_set; /* to differentiate set or get */
  130. struct bcm_iov_batch_subcmd cmds[0];
  131. };
  132. /* non-batched command version = major|minor w/ major <= 127 */
  133. struct bcm_iov_buf {
  134. uint16 version;
  135. uint16 len;
  136. bcm_iov_cmd_id_t id;
  137. uint16 data[1]; /* 32 bit alignment may be repurposed by the command */
  138. /* command specific data follows */
  139. };
  140. /* iov options flags */
  141. enum {
  142. BCM_IOV_CMD_OPT_ALIGN_NONE = 0x0000,
  143. BCM_IOV_CMD_OPT_ALIGN32 = 0x0001,
  144. BCM_IOV_CMD_OPT_TERMINATE_SUB_CMDS = 0x0002
  145. };
  146. /* iov command flags */
  147. enum {
  148. BCM_IOV_CMD_FLAG_NONE = 0,
  149. BCM_IOV_CMD_FLAG_STATUS_PRESENT = (1 << 0), /* status present at data start - output only */
  150. BCM_IOV_CMD_FLAG_XTLV_DATA = (1 << 1), /* data is a set of xtlvs */
  151. BCM_IOV_CMD_FLAG_HDR_IN_LEN = (1 << 2), /* length starts at version - non-bacthed only */
  152. BCM_IOV_CMD_FLAG_NOPAD = (1 << 3) /* No padding needed after iov_buf */
  153. };
  154. /* information about the command, xtlv options and xtlvs_off are meaningful
  155. * only if XTLV_DATA cmd flag is selected
  156. */
  157. struct bcm_iov_cmd_info {
  158. bcm_iov_cmd_id_t cmd; /* the (sub)command - module specific */
  159. bcm_iov_cmd_flags_t flags; /* checked by bcmiov but set by module */
  160. bcm_iov_cmd_mflags_t mflags; /* owned and checked by module */
  161. bcm_xtlv_opts_t xtlv_opts;
  162. bcm_iov_cmd_validate_t validate_h; /* command validation handler */
  163. bcm_iov_cmd_get_t get_h;
  164. bcm_iov_cmd_set_t set_h;
  165. uint16 xtlvs_off; /* offset to beginning of xtlvs in cmd data */
  166. uint16 min_len_set;
  167. uint16 max_len_set;
  168. uint16 min_len_get;
  169. uint16 max_len_get;
  170. };
  171. /* tlv digest to support parsing of xtlvs for commands w/ tlv data; the tlv
  172. * digest is available in the handler for the command. The count and order in
  173. * which tlvs appear in the digest are exactly the same as the order of tlvs
  174. * passed in the registration for the command. Unknown tlvs are ignored.
  175. * If registered tlvs are missing datap will be NULL. common iov rocessing
  176. * acquires an input digest to process input buffer. The handler is responsible
  177. * for constructing an output digest and use packing functions to generate
  178. * the output buffer. The handler may use the input digest as output digest once
  179. * the tlv data is extracted and used. Multiple tlv support involves allocation of
  180. * tlp nodes, except the first, as required,
  181. */
  182. /* tlp data type indicates if the data is not used/invalid, input or output */
  183. enum {
  184. BCM_IOV_TLP_NODE_INVALID = 0,
  185. BCM_IOV_TLP_NODE_IN = 1,
  186. BCM_IOV_TLP_NODE_OUT = 2
  187. };
  188. struct bcm_iov_tlp {
  189. uint16 type;
  190. uint16 len;
  191. uint16 nodeix; /* node index */
  192. };
  193. /* tlp data for a given tlv - multiple tlvs of same type chained */
  194. struct bcm_iov_tlp_node {
  195. uint8 *next; /* multiple tlv support */
  196. bcm_iov_tlp_data_type_t type;
  197. uint8 *data; /* pointer to data in buffer or state */
  198. };
  199. struct bcm_iov_cmd_digest {
  200. uint32 version; /* Version */
  201. void *cmd_ctx;
  202. struct wlc_bsscfg *bsscfg;
  203. const bcm_iov_cmd_info_t *cmd_info;
  204. uint16 max_tlps; /* number of tlps allocated */
  205. uint16 max_nodes; /* number of nods allocated */
  206. uint16 num_tlps; /* number of tlps valid */
  207. uint16 num_nodes; /* number of nods valid */
  208. uint16 tlps_off; /* offset to tlps */
  209. uint16 nodes_off; /* offset to nodes */
  210. /*
  211. * bcm_iov_tlp_t tlps[max_tlps];
  212. * bcm_iov_tlp_node_t nodes[max_nodes]
  213. */
  214. };
  215. /* get length callback - default length is min_len taken from digest */
  216. typedef size_t (*bcm_iov_xtlv_get_len_t)(const bcm_iov_cmd_digest_t *dig,
  217. const bcm_iov_cmd_tlv_info_t *tlv_info);
  218. /* pack to buffer data callback. under some conditions it might
  219. * not be a straight copy and can refer to context(ual) information and
  220. * endian conversions...
  221. */
  222. typedef void (*bcm_iov_xtlv_pack_t)(const bcm_iov_cmd_digest_t *dig,
  223. const bcm_iov_cmd_tlv_info_t *tlv_info,
  224. uint8 *out_buf, const uint8 *in_data, size_t len);
  225. struct bcm_iov_cmd_tlv_info {
  226. uint16 id;
  227. uint16 min_len; /* inclusive */
  228. uint16 max_len; /* inclusive */
  229. bcm_iov_xtlv_get_len_t get_len;
  230. bcm_iov_xtlv_pack_t pack;
  231. };
  232. /*
  233. * module private parse context. Default version type len is uint16
  234. */
  235. enum {
  236. BCM_IOV_PARSE_CMD_NONE = 0
  237. };
  238. typedef uint32 parse_context_opts_t;
  239. /* get digest callback */
  240. typedef int (*bcm_iov_get_digest_t)(void *cmd_ctx, bcm_iov_cmd_digest_t **dig);
  241. typedef struct bcm_iov_parse_config {
  242. parse_context_opts_t options; /* to handle different ver lengths */
  243. bcm_iov_malloc_t alloc_fn;
  244. bcm_iov_free_t free_fn;
  245. bcm_iov_get_digest_t dig_fn;
  246. int max_regs;
  247. void *alloc_ctx;
  248. } bcm_iov_parse_config_t;
  249. /* API */
  250. /* All calls return an integer status code BCME_* unless otherwise indicated */
  251. /* return length of allocation for 'num_cmds' commands. data_len
  252. * includes length of data for all the commands excluding the headers
  253. */
  254. size_t bcm_iov_get_alloc_len(int num_cmds, size_t data_len);
  255. /* create parsing context using allocator provided; max_regs provides
  256. * the number of allowed registrations for commands using the context
  257. * sub-components of a module may register their own commands indepdently
  258. * using the parsing context. If digest callback is NULL or returns NULL,
  259. * the (input) digest is allocated using the provided allocators and released on
  260. * completion of processing.
  261. */
  262. int bcm_iov_create_parse_context(const bcm_iov_parse_config_t *parse_cfg,
  263. bcm_iov_parse_context_t **parse_ctx);
  264. /* free the parsing context; ctx is set to NULL on exit */
  265. int bcm_iov_free_parse_context(bcm_iov_parse_context_t **ctx, bcm_iov_free_t free_fn);
  266. /* Return the command context for the module */
  267. void *bcm_iov_get_cmd_ctx_info(bcm_iov_parse_context_t *parse_ctx);
  268. /* register a command info vector along with supported tlvs. Each command
  269. * may support a subset of tlvs
  270. */
  271. int bcm_iov_register_commands(bcm_iov_parse_context_t *parse_ctx, void *cmd_ctx,
  272. const bcm_iov_cmd_info_t *info, size_t num_cmds,
  273. const bcm_iov_cmd_tlv_info_t *tlv_info, size_t num_tlvs);
  274. /* pack the xtlvs provided in the digest. may returns BCME_BUFTOOSHORT, but the
  275. * out_len is set to required length in that case.
  276. */
  277. int bcm_iov_pack_xtlvs(const bcm_iov_cmd_digest_t *dig, bcm_xtlv_opts_t xtlv_opts,
  278. uint8 *out_buf, size_t out_size, size_t *out_len);
  279. #ifdef BCMDRIVER
  280. /* wlc modules register their iovar(s) using the parsing context w/ wlc layer
  281. * during attach.
  282. */
  283. struct wlc_if;
  284. struct wlc_info;
  285. extern struct wlc_bsscfg *bcm_iov_bsscfg_find_from_wlcif(struct wlc_info *wlc,
  286. struct wlc_if *wlcif);
  287. int bcm_iov_doiovar(void *parse_ctx, uint32 id, void *params, uint params_len,
  288. void *arg, uint arg_len, uint vsize, struct wlc_if *intf);
  289. #endif /* BCMDRIVER */
  290. /* parsing context helpers */
  291. /* get the maximum number of tlvs - can be used to allocate digest for all
  292. * commands. the digest can be shared. Negative values are BCM_*, >=0, the
  293. * number of tlvs
  294. */
  295. int bcm_iov_parse_get_max_tlvs(const bcm_iov_parse_context_t *ctx);
  296. /* common packing support */
  297. /* pack a buffer of uint8s - memcpy wrapper */
  298. int bcm_iov_pack_buf(const bcm_iov_cmd_digest_t *dig, uint8 *buf,
  299. const uint8 *data, size_t len);
  300. #define bcm_iov_packv_u8 bcm_iov_pack_buf
  301. /*
  302. * pack a buffer with uint16s - serialized in LE order, data points to uint16
  303. * length is not checked.
  304. */
  305. int bcm_iov_packv_u16(const bcm_iov_cmd_digest_t *dig, uint8 *buf,
  306. const uint16 *data, int n);
  307. /*
  308. * pack a buffer with uint32s - serialized in LE order - data points to uint32
  309. * length is not checked.
  310. */
  311. int bcm_iov_packv_u32(const bcm_iov_cmd_digest_t *dig, uint8 *buf,
  312. const uint32 *data, int n);
  313. #endif /* _bcmiov_h_ */