Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
0002 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
0003 
0004 #ifndef _MLXSW_ITEM_H
0005 #define _MLXSW_ITEM_H
0006 
0007 #include <linux/types.h>
0008 #include <linux/string.h>
0009 #include <linux/bitops.h>
0010 
0011 struct mlxsw_item {
0012     unsigned short  offset;     /* bytes in container */
0013     short       step;       /* step in bytes for indexed items */
0014     unsigned short  in_step_offset; /* offset within one step */
0015     unsigned char   shift;      /* shift in bits */
0016     unsigned char   element_size;   /* size of element in bit array */
0017     bool        no_real_shift;
0018     union {
0019         unsigned char   bits;
0020         unsigned short  bytes;
0021     } size;
0022     const char  *name;
0023 };
0024 
0025 static inline unsigned int
0026 __mlxsw_item_offset(const struct mlxsw_item *item, unsigned short index,
0027             size_t typesize)
0028 {
0029     BUG_ON(index && !item->step);
0030     if (item->offset % typesize != 0 ||
0031         item->step % typesize != 0 ||
0032         item->in_step_offset % typesize != 0) {
0033         pr_err("mlxsw: item bug (name=%s,offset=%x,step=%x,in_step_offset=%x,typesize=%zx)\n",
0034                item->name, item->offset, item->step,
0035                item->in_step_offset, typesize);
0036         BUG();
0037     }
0038 
0039     return ((item->offset + item->step * index + item->in_step_offset) /
0040         typesize);
0041 }
0042 
0043 static inline u8 __mlxsw_item_get8(const char *buf,
0044                    const struct mlxsw_item *item,
0045                    unsigned short index)
0046 {
0047     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u8));
0048     u8 *b = (u8 *) buf;
0049     u8 tmp;
0050 
0051     tmp = b[offset];
0052     tmp >>= item->shift;
0053     tmp &= GENMASK(item->size.bits - 1, 0);
0054     if (item->no_real_shift)
0055         tmp <<= item->shift;
0056     return tmp;
0057 }
0058 
0059 static inline void __mlxsw_item_set8(char *buf, const struct mlxsw_item *item,
0060                      unsigned short index, u8 val)
0061 {
0062     unsigned int offset = __mlxsw_item_offset(item, index,
0063                           sizeof(u8));
0064     u8 *b = (u8 *) buf;
0065     u8 mask = GENMASK(item->size.bits - 1, 0) << item->shift;
0066     u8 tmp;
0067 
0068     if (!item->no_real_shift)
0069         val <<= item->shift;
0070     val &= mask;
0071     tmp = b[offset];
0072     tmp &= ~mask;
0073     tmp |= val;
0074     b[offset] = tmp;
0075 }
0076 
0077 static inline u16 __mlxsw_item_get16(const char *buf,
0078                      const struct mlxsw_item *item,
0079                      unsigned short index)
0080 {
0081     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u16));
0082     __be16 *b = (__be16 *) buf;
0083     u16 tmp;
0084 
0085     tmp = be16_to_cpu(b[offset]);
0086     tmp >>= item->shift;
0087     tmp &= GENMASK(item->size.bits - 1, 0);
0088     if (item->no_real_shift)
0089         tmp <<= item->shift;
0090     return tmp;
0091 }
0092 
0093 static inline void __mlxsw_item_set16(char *buf, const struct mlxsw_item *item,
0094                       unsigned short index, u16 val)
0095 {
0096     unsigned int offset = __mlxsw_item_offset(item, index,
0097                           sizeof(u16));
0098     __be16 *b = (__be16 *) buf;
0099     u16 mask = GENMASK(item->size.bits - 1, 0) << item->shift;
0100     u16 tmp;
0101 
0102     if (!item->no_real_shift)
0103         val <<= item->shift;
0104     val &= mask;
0105     tmp = be16_to_cpu(b[offset]);
0106     tmp &= ~mask;
0107     tmp |= val;
0108     b[offset] = cpu_to_be16(tmp);
0109 }
0110 
0111 static inline u32 __mlxsw_item_get32(const char *buf,
0112                      const struct mlxsw_item *item,
0113                      unsigned short index)
0114 {
0115     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u32));
0116     __be32 *b = (__be32 *) buf;
0117     u32 tmp;
0118 
0119     tmp = be32_to_cpu(b[offset]);
0120     tmp >>= item->shift;
0121     tmp &= GENMASK(item->size.bits - 1, 0);
0122     if (item->no_real_shift)
0123         tmp <<= item->shift;
0124     return tmp;
0125 }
0126 
0127 static inline void __mlxsw_item_set32(char *buf, const struct mlxsw_item *item,
0128                       unsigned short index, u32 val)
0129 {
0130     unsigned int offset = __mlxsw_item_offset(item, index,
0131                           sizeof(u32));
0132     __be32 *b = (__be32 *) buf;
0133     u32 mask = GENMASK(item->size.bits - 1, 0) << item->shift;
0134     u32 tmp;
0135 
0136     if (!item->no_real_shift)
0137         val <<= item->shift;
0138     val &= mask;
0139     tmp = be32_to_cpu(b[offset]);
0140     tmp &= ~mask;
0141     tmp |= val;
0142     b[offset] = cpu_to_be32(tmp);
0143 }
0144 
0145 static inline u64 __mlxsw_item_get64(const char *buf,
0146                      const struct mlxsw_item *item,
0147                      unsigned short index)
0148 {
0149     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64));
0150     __be64 *b = (__be64 *) buf;
0151     u64 tmp;
0152 
0153     tmp = be64_to_cpu(b[offset]);
0154     tmp >>= item->shift;
0155     tmp &= GENMASK_ULL(item->size.bits - 1, 0);
0156     if (item->no_real_shift)
0157         tmp <<= item->shift;
0158     return tmp;
0159 }
0160 
0161 static inline void __mlxsw_item_set64(char *buf, const struct mlxsw_item *item,
0162                       unsigned short index, u64 val)
0163 {
0164     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(u64));
0165     __be64 *b = (__be64 *) buf;
0166     u64 mask = GENMASK_ULL(item->size.bits - 1, 0) << item->shift;
0167     u64 tmp;
0168 
0169     if (!item->no_real_shift)
0170         val <<= item->shift;
0171     val &= mask;
0172     tmp = be64_to_cpu(b[offset]);
0173     tmp &= ~mask;
0174     tmp |= val;
0175     b[offset] = cpu_to_be64(tmp);
0176 }
0177 
0178 static inline void __mlxsw_item_memcpy_from(const char *buf, char *dst,
0179                         const struct mlxsw_item *item,
0180                         unsigned short index)
0181 {
0182     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char));
0183 
0184     memcpy(dst, &buf[offset], item->size.bytes);
0185 }
0186 
0187 static inline void __mlxsw_item_memcpy_to(char *buf, const char *src,
0188                       const struct mlxsw_item *item,
0189                       unsigned short index)
0190 {
0191     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char));
0192 
0193     memcpy(&buf[offset], src, item->size.bytes);
0194 }
0195 
0196 static inline char *__mlxsw_item_data(char *buf, const struct mlxsw_item *item,
0197                       unsigned short index)
0198 {
0199     unsigned int offset = __mlxsw_item_offset(item, index, sizeof(char));
0200 
0201     return &buf[offset];
0202 }
0203 
0204 static inline u16
0205 __mlxsw_item_bit_array_offset(const struct mlxsw_item *item,
0206                   u16 index, u8 *shift)
0207 {
0208     u16 max_index, be_index;
0209     u16 offset;     /* byte offset inside the array */
0210     u8 in_byte_index;
0211 
0212     BUG_ON(index && !item->element_size);
0213     if (item->offset % sizeof(u32) != 0 ||
0214         BITS_PER_BYTE % item->element_size != 0) {
0215         pr_err("mlxsw: item bug (name=%s,offset=%x,element_size=%x)\n",
0216                item->name, item->offset, item->element_size);
0217         BUG();
0218     }
0219 
0220     max_index = (item->size.bytes << 3) / item->element_size - 1;
0221     be_index = max_index - index;
0222     offset = be_index * item->element_size >> 3;
0223     in_byte_index  = index % (BITS_PER_BYTE / item->element_size);
0224     *shift = in_byte_index * item->element_size;
0225 
0226     return item->offset + offset;
0227 }
0228 
0229 static inline u8 __mlxsw_item_bit_array_get(const char *buf,
0230                         const struct mlxsw_item *item,
0231                         u16 index)
0232 {
0233     u8 shift, tmp;
0234     u16 offset = __mlxsw_item_bit_array_offset(item, index, &shift);
0235 
0236     tmp = buf[offset];
0237     tmp >>= shift;
0238     tmp &= GENMASK(item->element_size - 1, 0);
0239     return tmp;
0240 }
0241 
0242 static inline void __mlxsw_item_bit_array_set(char *buf,
0243                           const struct mlxsw_item *item,
0244                           u16 index, u8 val)
0245 {
0246     u8 shift, tmp;
0247     u16 offset = __mlxsw_item_bit_array_offset(item, index, &shift);
0248     u8 mask = GENMASK(item->element_size - 1, 0) << shift;
0249 
0250     val <<= shift;
0251     val &= mask;
0252     tmp = buf[offset];
0253     tmp &= ~mask;
0254     tmp |= val;
0255     buf[offset] = tmp;
0256 }
0257 
0258 #define __ITEM_NAME(_type, _cname, _iname)                  \
0259     mlxsw_##_type##_##_cname##_##_iname##_item
0260 
0261 /* _type: cmd_mbox, reg, etc.
0262  * _cname: containter name (e.g. command name, register name)
0263  * _iname: item name within the container
0264  */
0265 
0266 #define MLXSW_ITEM8(_type, _cname, _iname, _offset, _shift, _sizebits)      \
0267 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0268     .offset = _offset,                          \
0269     .shift = _shift,                            \
0270     .size = {.bits = _sizebits,},                       \
0271     .name = #_type "_" #_cname "_" #_iname,                 \
0272 };                                      \
0273 static inline u8 __maybe_unused                         \
0274 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf)          \
0275 {                                       \
0276     return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname), 0);  \
0277 }                                       \
0278 static inline void __maybe_unused                       \
0279 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u8 val)            \
0280 {                                       \
0281     __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val);    \
0282 }
0283 
0284 #define MLXSW_ITEM8_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits,  \
0285                 _step, _instepoffset, _norealshift)         \
0286 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0287     .offset = _offset,                          \
0288     .step = _step,                              \
0289     .in_step_offset = _instepoffset,                    \
0290     .shift = _shift,                            \
0291     .no_real_shift = _norealshift,                      \
0292     .size = {.bits = _sizebits,},                       \
0293     .name = #_type "_" #_cname "_" #_iname,                 \
0294 };                                      \
0295 static inline u8 __maybe_unused                         \
0296 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\
0297 {                                       \
0298     return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname),  \
0299                  index);                    \
0300 }                                       \
0301 static inline void __maybe_unused                       \
0302 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index,  \
0303                       u8 val)               \
0304 {                                       \
0305     __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname),     \
0306               index, val);                      \
0307 }
0308 
0309 #define MLXSW_ITEM16(_type, _cname, _iname, _offset, _shift, _sizebits)     \
0310 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0311     .offset = _offset,                          \
0312     .shift = _shift,                            \
0313     .size = {.bits = _sizebits,},                       \
0314     .name = #_type "_" #_cname "_" #_iname,                 \
0315 };                                      \
0316 static inline u16 __maybe_unused                        \
0317 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf)          \
0318 {                                       \
0319     return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \
0320 }                                       \
0321 static inline void __maybe_unused                       \
0322 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 val)           \
0323 {                                       \
0324     __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val);   \
0325 }
0326 
0327 #define MLXSW_ITEM16_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \
0328                  _step, _instepoffset, _norealshift)        \
0329 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0330     .offset = _offset,                          \
0331     .step = _step,                              \
0332     .in_step_offset = _instepoffset,                    \
0333     .shift = _shift,                            \
0334     .no_real_shift = _norealshift,                      \
0335     .size = {.bits = _sizebits,},                       \
0336     .name = #_type "_" #_cname "_" #_iname,                 \
0337 };                                      \
0338 static inline u16 __maybe_unused                        \
0339 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\
0340 {                                       \
0341     return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), \
0342                   index);                   \
0343 }                                       \
0344 static inline void __maybe_unused                       \
0345 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index,  \
0346                       u16 val)              \
0347 {                                       \
0348     __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname),        \
0349                index, val);                     \
0350 }
0351 
0352 #define MLXSW_ITEM32(_type, _cname, _iname, _offset, _shift, _sizebits)     \
0353 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0354     .offset = _offset,                          \
0355     .shift = _shift,                            \
0356     .size = {.bits = _sizebits,},                       \
0357     .name = #_type "_" #_cname "_" #_iname,                 \
0358 };                                      \
0359 static inline u32 __maybe_unused                        \
0360 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf)          \
0361 {                                       \
0362     return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \
0363 }                                       \
0364 static inline void __maybe_unused                       \
0365 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u32 val)           \
0366 {                                       \
0367     __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val);   \
0368 }
0369 
0370 #define LOCAL_PORT_LSB_SIZE 8
0371 #define LOCAL_PORT_MSB_SIZE 2
0372 
0373 #define MLXSW_ITEM32_LP(_type, _cname, _offset1, _shift1, _offset2, _shift2)    \
0374 static struct mlxsw_item __ITEM_NAME(_type, _cname, local_port) = {     \
0375     .offset = _offset1,                         \
0376     .shift = _shift1,                           \
0377     .size = {.bits = LOCAL_PORT_LSB_SIZE,},                 \
0378     .name = #_type "_" #_cname "_local_port",               \
0379 };                                      \
0380 static struct mlxsw_item __ITEM_NAME(_type, _cname, lp_msb) = {         \
0381     .offset = _offset2,                         \
0382     .shift = _shift2,                           \
0383     .size = {.bits = LOCAL_PORT_MSB_SIZE,},                 \
0384     .name = #_type "_" #_cname "_lp_msb",                   \
0385 };                                      \
0386 static inline u32 __maybe_unused                        \
0387 mlxsw_##_type##_##_cname##_local_port_get(const char *buf)          \
0388 {                                       \
0389     u32 local_port, lp_msb;                         \
0390                                         \
0391     local_port = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname,    \
0392                     local_port), 0);            \
0393     lp_msb = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, lp_msb),   \
0394                    0);                      \
0395     return (lp_msb << LOCAL_PORT_LSB_SIZE) + local_port;            \
0396 }                                       \
0397 static inline void __maybe_unused                       \
0398 mlxsw_##_type##_##_cname##_local_port_set(char *buf, u32 val)           \
0399 {                                       \
0400     __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, local_port), 0, \
0401                val & ((1 << LOCAL_PORT_LSB_SIZE) - 1));     \
0402     __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, lp_msb), 0,     \
0403                val >> LOCAL_PORT_LSB_SIZE);             \
0404 }
0405 
0406 #define MLXSW_ITEM32_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \
0407                  _step, _instepoffset, _norealshift)        \
0408 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0409     .offset = _offset,                          \
0410     .step = _step,                              \
0411     .in_step_offset = _instepoffset,                    \
0412     .shift = _shift,                            \
0413     .no_real_shift = _norealshift,                      \
0414     .size = {.bits = _sizebits,},                       \
0415     .name = #_type "_" #_cname "_" #_iname,                 \
0416 };                                      \
0417 static inline u32 __maybe_unused                        \
0418 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\
0419 {                                       \
0420     return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), \
0421                   index);                   \
0422 }                                       \
0423 static inline void __maybe_unused                       \
0424 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index,  \
0425                       u32 val)              \
0426 {                                       \
0427     __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname),        \
0428                index, val);                     \
0429 }
0430 
0431 #define MLXSW_ITEM64(_type, _cname, _iname, _offset, _shift, _sizebits)     \
0432 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0433     .offset = _offset,                          \
0434     .shift = _shift,                            \
0435     .size = {.bits = _sizebits,},                       \
0436     .name = #_type "_" #_cname "_" #_iname,                 \
0437 };                                      \
0438 static inline u64 __maybe_unused                        \
0439 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf)          \
0440 {                                       \
0441     return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \
0442 }                                       \
0443 static inline void __maybe_unused                       \
0444 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u64 val)           \
0445 {                                       \
0446     __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val);   \
0447 }
0448 
0449 #define MLXSW_ITEM64_INDEXED(_type, _cname, _iname, _offset, _shift,        \
0450                  _sizebits, _step, _instepoffset, _norealshift) \
0451 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0452     .offset = _offset,                          \
0453     .step = _step,                              \
0454     .in_step_offset = _instepoffset,                    \
0455     .shift = _shift,                            \
0456     .no_real_shift = _norealshift,                      \
0457     .size = {.bits = _sizebits,},                       \
0458     .name = #_type "_" #_cname "_" #_iname,                 \
0459 };                                      \
0460 static inline u64 __maybe_unused                        \
0461 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\
0462 {                                       \
0463     return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), \
0464                   index);                   \
0465 }                                       \
0466 static inline void __maybe_unused                       \
0467 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index,  \
0468                       u64 val)              \
0469 {                                       \
0470     __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname),        \
0471                index, val);                     \
0472 }
0473 
0474 #define MLXSW_ITEM_BUF(_type, _cname, _iname, _offset, _sizebytes)      \
0475 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0476     .offset = _offset,                          \
0477     .size = {.bytes = _sizebytes,},                     \
0478     .name = #_type "_" #_cname "_" #_iname,                 \
0479 };                                      \
0480 static inline void __maybe_unused                       \
0481 mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, char *dst)   \
0482 {                                       \
0483     __mlxsw_item_memcpy_from(buf, dst,                  \
0484                  &__ITEM_NAME(_type, _cname, _iname), 0);   \
0485 }                                       \
0486 static inline void __maybe_unused                       \
0487 mlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf, const char *src) \
0488 {                                       \
0489     __mlxsw_item_memcpy_to(buf, src,                    \
0490                    &__ITEM_NAME(_type, _cname, _iname), 0);     \
0491 }                                       \
0492 static inline char * __maybe_unused                     \
0493 mlxsw_##_type##_##_cname##_##_iname##_data(char *buf)               \
0494 {                                       \
0495     return __mlxsw_item_data(buf, &__ITEM_NAME(_type, _cname, _iname), 0);  \
0496 }
0497 
0498 #define MLXSW_ITEM_BUF_INDEXED(_type, _cname, _iname, _offset, _sizebytes,  \
0499                    _step, _instepoffset)                \
0500 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0501     .offset = _offset,                          \
0502     .step = _step,                              \
0503     .in_step_offset = _instepoffset,                    \
0504     .size = {.bytes = _sizebytes,},                     \
0505     .name = #_type "_" #_cname "_" #_iname,                 \
0506 };                                      \
0507 static inline void __maybe_unused                       \
0508 mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf,      \
0509                           unsigned short index,     \
0510                           char *dst)            \
0511 {                                       \
0512     __mlxsw_item_memcpy_from(buf, dst,                  \
0513                  &__ITEM_NAME(_type, _cname, _iname), index);   \
0514 }                                       \
0515 static inline void __maybe_unused                       \
0516 mlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf,          \
0517                         unsigned short index,       \
0518                         const char *src)        \
0519 {                                       \
0520     __mlxsw_item_memcpy_to(buf, src,                    \
0521                    &__ITEM_NAME(_type, _cname, _iname), index); \
0522 }                                       \
0523 static inline char * __maybe_unused                     \
0524 mlxsw_##_type##_##_cname##_##_iname##_data(char *buf, unsigned short index) \
0525 {                                       \
0526     return __mlxsw_item_data(buf,                       \
0527                  &__ITEM_NAME(_type, _cname, _iname), index);   \
0528 }
0529 
0530 #define MLXSW_ITEM_BIT_ARRAY(_type, _cname, _iname, _offset, _sizebytes,    \
0531                  _element_size)                 \
0532 static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = {         \
0533     .offset = _offset,                          \
0534     .element_size = _element_size,                      \
0535     .size = {.bytes = _sizebytes,},                     \
0536     .name = #_type "_" #_cname "_" #_iname,                 \
0537 };                                      \
0538 static inline u8 __maybe_unused                         \
0539 mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, u16 index)       \
0540 {                                       \
0541     return __mlxsw_item_bit_array_get(buf,                  \
0542                       &__ITEM_NAME(_type, _cname, _iname),  \
0543                       index);               \
0544 }                                       \
0545 static inline void __maybe_unused                       \
0546 mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 index, u8 val)     \
0547 {                                       \
0548     return __mlxsw_item_bit_array_set(buf,                  \
0549                       &__ITEM_NAME(_type, _cname, _iname),  \
0550                       index, val);              \
0551 }                                       \
0552 
0553 #endif