File Index
Files and directories
Sign in
FILE

fbnic_tlv.h

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/meta/fbnic/fbnic_tlv.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/* Copyright (c) Meta Platforms, Inc. and affiliates. */
  3
  4#ifndef _FBNIC_TLV_H_
  5#define _FBNIC_TLV_H_
  6
  7#include <asm/byteorder.h>
  8#include <linux/bits.h>
  9#include <linux/const.h>
 10#include <linux/types.h>
 11
 12#define FBNIC_TLV_MSG_ALIGN(len)	ALIGN(len, sizeof(u32))
 13#define FBNIC_TLV_MSG_SIZE(len)		\
 14		(FBNIC_TLV_MSG_ALIGN(len) / sizeof(u32))
 15
 16/* TLV Header Format
 17 *    3			  2		      1
 18 *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 19 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 20 * |		Length		   |M|I|RSV|	   Type / ID	   |
 21 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 22 *
 23 * The TLV header format described above will be used for transferring
 24 * messages between the host and the firmware. To ensure byte ordering
 25 * we have defined all fields as being little endian.
 26 * Type/ID: Identifier for message and/or attribute
 27 * RSV: Reserved field for future use, likely as additional flags
 28 * I: cannot_ignore flag, identifies if unrecognized attribute can be ignored
 29 * M: is_msg, indicates that this is the start of a new message
 30 * Length: Total length of message in dwords including header
 31 *		or
 32 *	   Total length of attribute in bytes including header
 33 */
 34struct fbnic_tlv_hdr {
 35#if defined(__LITTLE_ENDIAN_BITFIELD)
 36	u16 type		: 12; /* 0 .. 11  Type / ID */
 37	u16 rsvd		: 2;  /* 12 .. 13 Reserved for future use */
 38	u16 cannot_ignore	: 1;  /* 14	  Attribute can be ignored */
 39	u16 is_msg		: 1;  /* 15	  Header belongs to message */
 40#elif defined(__BIG_ENDIAN_BITFIELD)
 41	u16 is_msg		: 1;  /* 15	  Header belongs to message */
 42	u16 cannot_ignore	: 1;  /* 14	  Attribute can be ignored */
 43	u16 rsvd		: 2;  /* 13 .. 12 Reserved for future use */
 44	u16 type		: 12; /* 11 .. 0  Type / ID */
 45#else
 46#error "Missing defines from byteorder.h"
 47#endif
 48	__le16 len;		/* 16 .. 32	length including TLV header */
 49};
 50
 51#define FBNIC_TLV_RESULTS_MAX		32
 52
 53struct fbnic_tlv_msg {
 54	struct fbnic_tlv_hdr	hdr;
 55	__le32			value[];
 56};
 57
 58#define FBNIC_TLV_MSG_ID_UNKNOWN		USHRT_MAX
 59
 60enum fbnic_tlv_type {
 61	FBNIC_TLV_STRING,
 62	FBNIC_TLV_FLAG,
 63	FBNIC_TLV_UNSIGNED,
 64	FBNIC_TLV_SIGNED,
 65	FBNIC_TLV_BINARY,
 66	FBNIC_TLV_NESTED,
 67	FBNIC_TLV_ARRAY,
 68	__FBNIC_TLV_MAX_TYPE
 69};
 70
 71/* TLV Index
 72 * Defines the relationship between the attribute IDs and their types.
 73 * For each entry in the index there will be a size and type associated
 74 * with it so that we can use this to parse the data and verify it matches
 75 * the expected layout.
 76 */
 77struct fbnic_tlv_index {
 78	u16			id;
 79	u16			len;
 80	enum fbnic_tlv_type	type;
 81};
 82
 83#define TLV_MAX_DATA			((PAGE_SIZE - 512) & 0xFFFF)
 84#define FBNIC_TLV_ATTR_ID_UNKNOWN	USHRT_MAX
 85#define FBNIC_TLV_ATTR_STRING(id, len)	{ id, len, FBNIC_TLV_STRING }
 86#define FBNIC_TLV_ATTR_FLAG(id)		{ id, 0, FBNIC_TLV_FLAG }
 87#define FBNIC_TLV_ATTR_U32(id)		{ id, sizeof(u32), FBNIC_TLV_UNSIGNED }
 88#define FBNIC_TLV_ATTR_U64(id)		{ id, sizeof(u64), FBNIC_TLV_UNSIGNED }
 89#define FBNIC_TLV_ATTR_S32(id)		{ id, sizeof(s32), FBNIC_TLV_SIGNED }
 90#define FBNIC_TLV_ATTR_S64(id)		{ id, sizeof(s64), FBNIC_TLV_SIGNED }
 91#define FBNIC_TLV_ATTR_MAC_ADDR(id)	{ id, ETH_ALEN, FBNIC_TLV_BINARY }
 92#define FBNIC_TLV_ATTR_NESTED(id)	{ id, 0, FBNIC_TLV_NESTED }
 93#define FBNIC_TLV_ATTR_ARRAY(id)	{ id, 0, FBNIC_TLV_ARRAY }
 94#define FBNIC_TLV_ATTR_RAW_DATA(id)	{ id, TLV_MAX_DATA, FBNIC_TLV_BINARY }
 95#define FBNIC_TLV_ATTR_LAST		{ FBNIC_TLV_ATTR_ID_UNKNOWN, 0, 0 }
 96
 97struct fbnic_tlv_parser {
 98	u16				id;
 99	const struct fbnic_tlv_index	*attr;
100	int				(*func)(void *opaque,
101						struct fbnic_tlv_msg **results);
102};
103
104#define FBNIC_TLV_PARSER(id, attr, func) { FBNIC_TLV_MSG_ID_##id, attr, func }
105
106static inline void *
107fbnic_tlv_attr_get_value_ptr(struct fbnic_tlv_msg *attr)
108{
109	return (void *)&attr->value[0];
110}
111
112static inline bool fbnic_tlv_attr_get_bool(struct fbnic_tlv_msg *attr)
113{
114	return !!attr;
115}
116
117u64 fbnic_tlv_attr_get_unsigned(struct fbnic_tlv_msg *attr, u64 def);
118s64 fbnic_tlv_attr_get_signed(struct fbnic_tlv_msg *attr, s64 def);
119ssize_t fbnic_tlv_attr_get_string(struct fbnic_tlv_msg *attr, char *dst,
120				  size_t dstsize);
121struct fbnic_tlv_msg *fbnic_tlv_msg_alloc(u16 msg_id);
122int fbnic_tlv_attr_put_flag(struct fbnic_tlv_msg *msg, const u16 attr_id);
123int fbnic_tlv_attr_put_value(struct fbnic_tlv_msg *msg, const u16 attr_id,
124			     const void *value, const int len);
125int __fbnic_tlv_attr_put_int(struct fbnic_tlv_msg *msg, const u16 attr_id,
126			     s64 value, const int len);
127#define fbnic_tlv_attr_put_int(msg, attr_id, value) \
128	__fbnic_tlv_attr_put_int(msg, attr_id, value, \
129				 FBNIC_TLV_MSG_ALIGN(sizeof(value)))
130int fbnic_tlv_attr_put_mac_addr(struct fbnic_tlv_msg *msg, const u16 attr_id,
131				const u8 *mac_addr);
132int fbnic_tlv_attr_put_string(struct fbnic_tlv_msg *msg, u16 attr_id,
133			      const char *string);
134struct fbnic_tlv_msg *fbnic_tlv_attr_nest_start(struct fbnic_tlv_msg *msg,
135						u16 attr_id);
136void fbnic_tlv_attr_nest_stop(struct fbnic_tlv_msg *msg);
137void fbnic_tlv_attr_addr_copy(u8 *dest, struct fbnic_tlv_msg *src);
138int fbnic_tlv_attr_parse_array(struct fbnic_tlv_msg *attr, int len,
139			       struct fbnic_tlv_msg **results,
140			       const struct fbnic_tlv_index *tlv_index,
141			       u16 tlv_attr_id, size_t array_len);
142int fbnic_tlv_attr_parse(struct fbnic_tlv_msg *attr, int len,
143			 struct fbnic_tlv_msg **results,
144			 const struct fbnic_tlv_index *tlv_index);
145int fbnic_tlv_msg_parse(void *opaque, struct fbnic_tlv_msg *msg,
146			const struct fbnic_tlv_parser *parser);
147int fbnic_tlv_parser_error(void *opaque, struct fbnic_tlv_msg **results);
148
149#define fta_get_uint(_results, _id) \
150	fbnic_tlv_attr_get_unsigned(_results[_id], 0)
151#define fta_get_sint(_results, _id) \
152	fbnic_tlv_attr_get_signed(_results[_id], 0)
153#define fta_get_str(_results, _id, _dst, _dstsize) \
154	fbnic_tlv_attr_get_string(_results[_id], _dst, _dstsize)
155
156#define FBNIC_TLV_MSG_ERROR \
157	FBNIC_TLV_PARSER(UNKNOWN, NULL, fbnic_tlv_parser_error)
158#endif /* _FBNIC_TLV_H_ */
~/ Read-only file preview.