1 | /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ |
2 | /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */ |
3 | |
4 | #ifndef _MLXSW_ITEM_H |
5 | #define _MLXSW_ITEM_H |
6 | |
7 | #include <linux/types.h> |
8 | #include <linux/string.h> |
9 | #include <linux/bitops.h> |
10 | |
11 | struct mlxsw_item { |
12 | unsigned short offset; /* bytes in container */ |
13 | short step; /* step in bytes for indexed items */ |
14 | unsigned short in_step_offset; /* offset within one step */ |
15 | unsigned char shift; /* shift in bits */ |
16 | unsigned char element_size; /* size of element in bit array */ |
17 | bool no_real_shift; |
18 | union { |
19 | unsigned char bits; |
20 | unsigned short bytes; |
21 | } size; |
22 | const char *name; |
23 | }; |
24 | |
25 | static inline unsigned int |
26 | __mlxsw_item_offset(const struct mlxsw_item *item, unsigned short index, |
27 | size_t typesize) |
28 | { |
29 | BUG_ON(index && !item->step); |
30 | if (item->offset % typesize != 0 || |
31 | item->step % typesize != 0 || |
32 | item->in_step_offset % typesize != 0) { |
33 | pr_err("mlxsw: item bug (name=%s,offset=%x,step=%x,in_step_offset=%x,typesize=%zx)\n" , |
34 | item->name, item->offset, item->step, |
35 | item->in_step_offset, typesize); |
36 | BUG(); |
37 | } |
38 | |
39 | return ((item->offset + item->step * index + item->in_step_offset) / |
40 | typesize); |
41 | } |
42 | |
43 | static inline u8 __mlxsw_item_get8(const char *buf, |
44 | const struct mlxsw_item *item, |
45 | unsigned short index) |
46 | { |
47 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(u8)); |
48 | u8 *b = (u8 *) buf; |
49 | u8 tmp; |
50 | |
51 | tmp = b[offset]; |
52 | tmp >>= item->shift; |
53 | tmp &= GENMASK(item->size.bits - 1, 0); |
54 | if (item->no_real_shift) |
55 | tmp <<= item->shift; |
56 | return tmp; |
57 | } |
58 | |
59 | static inline void __mlxsw_item_set8(char *buf, const struct mlxsw_item *item, |
60 | unsigned short index, u8 val) |
61 | { |
62 | unsigned int offset = __mlxsw_item_offset(item, index, |
63 | typesize: sizeof(u8)); |
64 | u8 *b = (u8 *) buf; |
65 | u8 mask = GENMASK(item->size.bits - 1, 0) << item->shift; |
66 | u8 tmp; |
67 | |
68 | if (!item->no_real_shift) |
69 | val <<= item->shift; |
70 | val &= mask; |
71 | tmp = b[offset]; |
72 | tmp &= ~mask; |
73 | tmp |= val; |
74 | b[offset] = tmp; |
75 | } |
76 | |
77 | static inline u16 __mlxsw_item_get16(const char *buf, |
78 | const struct mlxsw_item *item, |
79 | unsigned short index) |
80 | { |
81 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(u16)); |
82 | __be16 *b = (__be16 *) buf; |
83 | u16 tmp; |
84 | |
85 | tmp = be16_to_cpu(b[offset]); |
86 | tmp >>= item->shift; |
87 | tmp &= GENMASK(item->size.bits - 1, 0); |
88 | if (item->no_real_shift) |
89 | tmp <<= item->shift; |
90 | return tmp; |
91 | } |
92 | |
93 | static inline void __mlxsw_item_set16(char *buf, const struct mlxsw_item *item, |
94 | unsigned short index, u16 val) |
95 | { |
96 | unsigned int offset = __mlxsw_item_offset(item, index, |
97 | typesize: sizeof(u16)); |
98 | __be16 *b = (__be16 *) buf; |
99 | u16 mask = GENMASK(item->size.bits - 1, 0) << item->shift; |
100 | u16 tmp; |
101 | |
102 | if (!item->no_real_shift) |
103 | val <<= item->shift; |
104 | val &= mask; |
105 | tmp = be16_to_cpu(b[offset]); |
106 | tmp &= ~mask; |
107 | tmp |= val; |
108 | b[offset] = cpu_to_be16(tmp); |
109 | } |
110 | |
111 | static inline u32 __mlxsw_item_get32(const char *buf, |
112 | const struct mlxsw_item *item, |
113 | unsigned short index) |
114 | { |
115 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(u32)); |
116 | __be32 *b = (__be32 *) buf; |
117 | u32 tmp; |
118 | |
119 | tmp = be32_to_cpu(b[offset]); |
120 | tmp >>= item->shift; |
121 | tmp &= GENMASK(item->size.bits - 1, 0); |
122 | if (item->no_real_shift) |
123 | tmp <<= item->shift; |
124 | return tmp; |
125 | } |
126 | |
127 | static inline void __mlxsw_item_set32(char *buf, const struct mlxsw_item *item, |
128 | unsigned short index, u32 val) |
129 | { |
130 | unsigned int offset = __mlxsw_item_offset(item, index, |
131 | typesize: sizeof(u32)); |
132 | __be32 *b = (__be32 *) buf; |
133 | u32 mask = GENMASK(item->size.bits - 1, 0) << item->shift; |
134 | u32 tmp; |
135 | |
136 | if (!item->no_real_shift) |
137 | val <<= item->shift; |
138 | val &= mask; |
139 | tmp = be32_to_cpu(b[offset]); |
140 | tmp &= ~mask; |
141 | tmp |= val; |
142 | b[offset] = cpu_to_be32(tmp); |
143 | } |
144 | |
145 | static inline u64 __mlxsw_item_get64(const char *buf, |
146 | const struct mlxsw_item *item, |
147 | unsigned short index) |
148 | { |
149 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(u64)); |
150 | __be64 *b = (__be64 *) buf; |
151 | u64 tmp; |
152 | |
153 | tmp = be64_to_cpu(b[offset]); |
154 | tmp >>= item->shift; |
155 | tmp &= GENMASK_ULL(item->size.bits - 1, 0); |
156 | if (item->no_real_shift) |
157 | tmp <<= item->shift; |
158 | return tmp; |
159 | } |
160 | |
161 | static inline void __mlxsw_item_set64(char *buf, const struct mlxsw_item *item, |
162 | unsigned short index, u64 val) |
163 | { |
164 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(u64)); |
165 | __be64 *b = (__be64 *) buf; |
166 | u64 mask = GENMASK_ULL(item->size.bits - 1, 0) << item->shift; |
167 | u64 tmp; |
168 | |
169 | if (!item->no_real_shift) |
170 | val <<= item->shift; |
171 | val &= mask; |
172 | tmp = be64_to_cpu(b[offset]); |
173 | tmp &= ~mask; |
174 | tmp |= val; |
175 | b[offset] = cpu_to_be64(tmp); |
176 | } |
177 | |
178 | static inline void __mlxsw_item_memcpy_from(const char *buf, char *dst, |
179 | const struct mlxsw_item *item, |
180 | unsigned short index) |
181 | { |
182 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(char)); |
183 | |
184 | memcpy(dst, &buf[offset], item->size.bytes); |
185 | } |
186 | |
187 | static inline void __mlxsw_item_memcpy_to(char *buf, const char *src, |
188 | const struct mlxsw_item *item, |
189 | unsigned short index) |
190 | { |
191 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(char)); |
192 | |
193 | memcpy(&buf[offset], src, item->size.bytes); |
194 | } |
195 | |
196 | static inline char *__mlxsw_item_data(char *buf, const struct mlxsw_item *item, |
197 | unsigned short index) |
198 | { |
199 | unsigned int offset = __mlxsw_item_offset(item, index, typesize: sizeof(char)); |
200 | |
201 | return &buf[offset]; |
202 | } |
203 | |
204 | static inline u16 |
205 | __mlxsw_item_bit_array_offset(const struct mlxsw_item *item, |
206 | u16 index, u8 *shift) |
207 | { |
208 | u16 max_index, be_index; |
209 | u16 offset; /* byte offset inside the array */ |
210 | u8 in_byte_index; |
211 | |
212 | BUG_ON(index && !item->element_size); |
213 | if (item->offset % sizeof(u32) != 0 || |
214 | BITS_PER_BYTE % item->element_size != 0) { |
215 | pr_err("mlxsw: item bug (name=%s,offset=%x,element_size=%x)\n" , |
216 | item->name, item->offset, item->element_size); |
217 | BUG(); |
218 | } |
219 | |
220 | max_index = (item->size.bytes << 3) / item->element_size - 1; |
221 | be_index = max_index - index; |
222 | offset = be_index * item->element_size >> 3; |
223 | in_byte_index = index % (BITS_PER_BYTE / item->element_size); |
224 | *shift = in_byte_index * item->element_size; |
225 | |
226 | return item->offset + offset; |
227 | } |
228 | |
229 | static inline u8 __mlxsw_item_bit_array_get(const char *buf, |
230 | const struct mlxsw_item *item, |
231 | u16 index) |
232 | { |
233 | u8 shift, tmp; |
234 | u16 offset = __mlxsw_item_bit_array_offset(item, index, shift: &shift); |
235 | |
236 | tmp = buf[offset]; |
237 | tmp >>= shift; |
238 | tmp &= GENMASK(item->element_size - 1, 0); |
239 | return tmp; |
240 | } |
241 | |
242 | static inline void __mlxsw_item_bit_array_set(char *buf, |
243 | const struct mlxsw_item *item, |
244 | u16 index, u8 val) |
245 | { |
246 | u8 shift, tmp; |
247 | u16 offset = __mlxsw_item_bit_array_offset(item, index, shift: &shift); |
248 | u8 mask = GENMASK(item->element_size - 1, 0) << shift; |
249 | |
250 | val <<= shift; |
251 | val &= mask; |
252 | tmp = buf[offset]; |
253 | tmp &= ~mask; |
254 | tmp |= val; |
255 | buf[offset] = tmp; |
256 | } |
257 | |
258 | #define __ITEM_NAME(_type, _cname, _iname) \ |
259 | mlxsw_##_type##_##_cname##_##_iname##_item |
260 | |
261 | /* _type: cmd_mbox, reg, etc. |
262 | * _cname: containter name (e.g. command name, register name) |
263 | * _iname: item name within the container |
264 | */ |
265 | |
266 | #define MLXSW_ITEM8(_type, _cname, _iname, _offset, _shift, _sizebits) \ |
267 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
268 | .offset = _offset, \ |
269 | .shift = _shift, \ |
270 | .size = {.bits = _sizebits,}, \ |
271 | .name = #_type "_" #_cname "_" #_iname, \ |
272 | }; \ |
273 | static inline u8 __maybe_unused \ |
274 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ |
275 | { \ |
276 | return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ |
277 | } \ |
278 | static inline void __maybe_unused \ |
279 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u8 val) \ |
280 | { \ |
281 | __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ |
282 | } |
283 | |
284 | #define MLXSW_ITEM8_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ |
285 | _step, _instepoffset, _norealshift) \ |
286 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
287 | .offset = _offset, \ |
288 | .step = _step, \ |
289 | .in_step_offset = _instepoffset, \ |
290 | .shift = _shift, \ |
291 | .no_real_shift = _norealshift, \ |
292 | .size = {.bits = _sizebits,}, \ |
293 | .name = #_type "_" #_cname "_" #_iname, \ |
294 | }; \ |
295 | static inline u8 __maybe_unused \ |
296 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ |
297 | { \ |
298 | return __mlxsw_item_get8(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
299 | index); \ |
300 | } \ |
301 | static inline void __maybe_unused \ |
302 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ |
303 | u8 val) \ |
304 | { \ |
305 | __mlxsw_item_set8(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
306 | index, val); \ |
307 | } |
308 | |
309 | #define MLXSW_ITEM16(_type, _cname, _iname, _offset, _shift, _sizebits) \ |
310 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
311 | .offset = _offset, \ |
312 | .shift = _shift, \ |
313 | .size = {.bits = _sizebits,}, \ |
314 | .name = #_type "_" #_cname "_" #_iname, \ |
315 | }; \ |
316 | static inline u16 __maybe_unused \ |
317 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ |
318 | { \ |
319 | return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ |
320 | } \ |
321 | static inline void __maybe_unused \ |
322 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 val) \ |
323 | { \ |
324 | __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ |
325 | } |
326 | |
327 | #define MLXSW_ITEM16_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ |
328 | _step, _instepoffset, _norealshift) \ |
329 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
330 | .offset = _offset, \ |
331 | .step = _step, \ |
332 | .in_step_offset = _instepoffset, \ |
333 | .shift = _shift, \ |
334 | .no_real_shift = _norealshift, \ |
335 | .size = {.bits = _sizebits,}, \ |
336 | .name = #_type "_" #_cname "_" #_iname, \ |
337 | }; \ |
338 | static inline u16 __maybe_unused \ |
339 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ |
340 | { \ |
341 | return __mlxsw_item_get16(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
342 | index); \ |
343 | } \ |
344 | static inline void __maybe_unused \ |
345 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ |
346 | u16 val) \ |
347 | { \ |
348 | __mlxsw_item_set16(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
349 | index, val); \ |
350 | } |
351 | |
352 | #define MLXSW_ITEM32(_type, _cname, _iname, _offset, _shift, _sizebits) \ |
353 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
354 | .offset = _offset, \ |
355 | .shift = _shift, \ |
356 | .size = {.bits = _sizebits,}, \ |
357 | .name = #_type "_" #_cname "_" #_iname, \ |
358 | }; \ |
359 | static inline u32 __maybe_unused \ |
360 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ |
361 | { \ |
362 | return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ |
363 | } \ |
364 | static inline void __maybe_unused \ |
365 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u32 val) \ |
366 | { \ |
367 | __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ |
368 | } |
369 | |
370 | #define LOCAL_PORT_LSB_SIZE 8 |
371 | #define LOCAL_PORT_MSB_SIZE 2 |
372 | |
373 | #define MLXSW_ITEM32_LP(_type, _cname, _offset1, _shift1, _offset2, _shift2) \ |
374 | static struct mlxsw_item __ITEM_NAME(_type, _cname, local_port) = { \ |
375 | .offset = _offset1, \ |
376 | .shift = _shift1, \ |
377 | .size = {.bits = LOCAL_PORT_LSB_SIZE,}, \ |
378 | .name = #_type "_" #_cname "_local_port", \ |
379 | }; \ |
380 | static struct mlxsw_item __ITEM_NAME(_type, _cname, lp_msb) = { \ |
381 | .offset = _offset2, \ |
382 | .shift = _shift2, \ |
383 | .size = {.bits = LOCAL_PORT_MSB_SIZE,}, \ |
384 | .name = #_type "_" #_cname "_lp_msb", \ |
385 | }; \ |
386 | static inline u32 __maybe_unused \ |
387 | mlxsw_##_type##_##_cname##_local_port_get(const char *buf) \ |
388 | { \ |
389 | u32 local_port, lp_msb; \ |
390 | \ |
391 | local_port = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, \ |
392 | local_port), 0); \ |
393 | lp_msb = __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, lp_msb), \ |
394 | 0); \ |
395 | return (lp_msb << LOCAL_PORT_LSB_SIZE) + local_port; \ |
396 | } \ |
397 | static inline void __maybe_unused \ |
398 | mlxsw_##_type##_##_cname##_local_port_set(char *buf, u32 val) \ |
399 | { \ |
400 | __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, local_port), 0, \ |
401 | val & ((1 << LOCAL_PORT_LSB_SIZE) - 1)); \ |
402 | __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, lp_msb), 0, \ |
403 | val >> LOCAL_PORT_LSB_SIZE); \ |
404 | } |
405 | |
406 | #define MLXSW_ITEM32_INDEXED(_type, _cname, _iname, _offset, _shift, _sizebits, \ |
407 | _step, _instepoffset, _norealshift) \ |
408 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
409 | .offset = _offset, \ |
410 | .step = _step, \ |
411 | .in_step_offset = _instepoffset, \ |
412 | .shift = _shift, \ |
413 | .no_real_shift = _norealshift, \ |
414 | .size = {.bits = _sizebits,}, \ |
415 | .name = #_type "_" #_cname "_" #_iname, \ |
416 | }; \ |
417 | static inline u32 __maybe_unused \ |
418 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ |
419 | { \ |
420 | return __mlxsw_item_get32(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
421 | index); \ |
422 | } \ |
423 | static inline void __maybe_unused \ |
424 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ |
425 | u32 val) \ |
426 | { \ |
427 | __mlxsw_item_set32(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
428 | index, val); \ |
429 | } |
430 | |
431 | #define MLXSW_ITEM64(_type, _cname, _iname, _offset, _shift, _sizebits) \ |
432 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
433 | .offset = _offset, \ |
434 | .shift = _shift, \ |
435 | .size = {.bits = _sizebits,}, \ |
436 | .name = #_type "_" #_cname "_" #_iname, \ |
437 | }; \ |
438 | static inline u64 __maybe_unused \ |
439 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf) \ |
440 | { \ |
441 | return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ |
442 | } \ |
443 | static inline void __maybe_unused \ |
444 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u64 val) \ |
445 | { \ |
446 | __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname), 0, val); \ |
447 | } |
448 | |
449 | #define MLXSW_ITEM64_INDEXED(_type, _cname, _iname, _offset, _shift, \ |
450 | _sizebits, _step, _instepoffset, _norealshift) \ |
451 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
452 | .offset = _offset, \ |
453 | .step = _step, \ |
454 | .in_step_offset = _instepoffset, \ |
455 | .shift = _shift, \ |
456 | .no_real_shift = _norealshift, \ |
457 | .size = {.bits = _sizebits,}, \ |
458 | .name = #_type "_" #_cname "_" #_iname, \ |
459 | }; \ |
460 | static inline u64 __maybe_unused \ |
461 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, unsigned short index)\ |
462 | { \ |
463 | return __mlxsw_item_get64(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
464 | index); \ |
465 | } \ |
466 | static inline void __maybe_unused \ |
467 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, unsigned short index, \ |
468 | u64 val) \ |
469 | { \ |
470 | __mlxsw_item_set64(buf, &__ITEM_NAME(_type, _cname, _iname), \ |
471 | index, val); \ |
472 | } |
473 | |
474 | #define MLXSW_ITEM_BUF(_type, _cname, _iname, _offset, _sizebytes) \ |
475 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
476 | .offset = _offset, \ |
477 | .size = {.bytes = _sizebytes,}, \ |
478 | .name = #_type "_" #_cname "_" #_iname, \ |
479 | }; \ |
480 | static inline void __maybe_unused \ |
481 | mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, char *dst) \ |
482 | { \ |
483 | __mlxsw_item_memcpy_from(buf, dst, \ |
484 | &__ITEM_NAME(_type, _cname, _iname), 0); \ |
485 | } \ |
486 | static inline void __maybe_unused \ |
487 | mlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf, const char *src) \ |
488 | { \ |
489 | __mlxsw_item_memcpy_to(buf, src, \ |
490 | &__ITEM_NAME(_type, _cname, _iname), 0); \ |
491 | } \ |
492 | static inline char * __maybe_unused \ |
493 | mlxsw_##_type##_##_cname##_##_iname##_data(char *buf) \ |
494 | { \ |
495 | return __mlxsw_item_data(buf, &__ITEM_NAME(_type, _cname, _iname), 0); \ |
496 | } |
497 | |
498 | #define MLXSW_ITEM_BUF_INDEXED(_type, _cname, _iname, _offset, _sizebytes, \ |
499 | _step, _instepoffset) \ |
500 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
501 | .offset = _offset, \ |
502 | .step = _step, \ |
503 | .in_step_offset = _instepoffset, \ |
504 | .size = {.bytes = _sizebytes,}, \ |
505 | .name = #_type "_" #_cname "_" #_iname, \ |
506 | }; \ |
507 | static inline void __maybe_unused \ |
508 | mlxsw_##_type##_##_cname##_##_iname##_memcpy_from(const char *buf, \ |
509 | unsigned short index, \ |
510 | char *dst) \ |
511 | { \ |
512 | __mlxsw_item_memcpy_from(buf, dst, \ |
513 | &__ITEM_NAME(_type, _cname, _iname), index); \ |
514 | } \ |
515 | static inline void __maybe_unused \ |
516 | mlxsw_##_type##_##_cname##_##_iname##_memcpy_to(char *buf, \ |
517 | unsigned short index, \ |
518 | const char *src) \ |
519 | { \ |
520 | __mlxsw_item_memcpy_to(buf, src, \ |
521 | &__ITEM_NAME(_type, _cname, _iname), index); \ |
522 | } \ |
523 | static inline char * __maybe_unused \ |
524 | mlxsw_##_type##_##_cname##_##_iname##_data(char *buf, unsigned short index) \ |
525 | { \ |
526 | return __mlxsw_item_data(buf, \ |
527 | &__ITEM_NAME(_type, _cname, _iname), index); \ |
528 | } |
529 | |
530 | #define MLXSW_ITEM_BIT_ARRAY(_type, _cname, _iname, _offset, _sizebytes, \ |
531 | _element_size) \ |
532 | static struct mlxsw_item __ITEM_NAME(_type, _cname, _iname) = { \ |
533 | .offset = _offset, \ |
534 | .element_size = _element_size, \ |
535 | .size = {.bytes = _sizebytes,}, \ |
536 | .name = #_type "_" #_cname "_" #_iname, \ |
537 | }; \ |
538 | static inline u8 __maybe_unused \ |
539 | mlxsw_##_type##_##_cname##_##_iname##_get(const char *buf, u16 index) \ |
540 | { \ |
541 | return __mlxsw_item_bit_array_get(buf, \ |
542 | &__ITEM_NAME(_type, _cname, _iname), \ |
543 | index); \ |
544 | } \ |
545 | static inline void __maybe_unused \ |
546 | mlxsw_##_type##_##_cname##_##_iname##_set(char *buf, u16 index, u8 val) \ |
547 | { \ |
548 | return __mlxsw_item_bit_array_set(buf, \ |
549 | &__ITEM_NAME(_type, _cname, _iname), \ |
550 | index, val); \ |
551 | } \ |
552 | |
553 | #endif |
554 | |