Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[platform/kernel/linux-rpi.git] / drivers / net / dsa / sja1105 / sja1105_static_config.c
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2016-2018 NXP
3  * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
4  */
5 #include "sja1105_static_config.h"
6 #include <linux/crc32.h>
7 #include <linux/slab.h>
8 #include <linux/string.h>
9 #include <linux/errno.h>
10
11 /* Convenience wrappers over the generic packing functions. These take into
12  * account the SJA1105 memory layout quirks and provide some level of
13  * programmer protection against incorrect API use. The errors are not expected
14  * to occur durring runtime, therefore printing and swallowing them here is
15  * appropriate instead of clutterring up higher-level code.
16  */
17 void sja1105_pack(void *buf, const u64 *val, int start, int end, size_t len)
18 {
19         int rc = packing(buf, (u64 *)val, start, end, len,
20                          PACK, QUIRK_LSW32_IS_FIRST);
21
22         if (likely(!rc))
23                 return;
24
25         if (rc == -EINVAL) {
26                 pr_err("Start bit (%d) expected to be larger than end (%d)\n",
27                        start, end);
28         } else if (rc == -ERANGE) {
29                 if ((start - end + 1) > 64)
30                         pr_err("Field %d-%d too large for 64 bits!\n",
31                                start, end);
32                 else
33                         pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n",
34                                *val, start, end);
35         }
36         dump_stack();
37 }
38
39 void sja1105_unpack(const void *buf, u64 *val, int start, int end, size_t len)
40 {
41         int rc = packing((void *)buf, val, start, end, len,
42                          UNPACK, QUIRK_LSW32_IS_FIRST);
43
44         if (likely(!rc))
45                 return;
46
47         if (rc == -EINVAL)
48                 pr_err("Start bit (%d) expected to be larger than end (%d)\n",
49                        start, end);
50         else if (rc == -ERANGE)
51                 pr_err("Field %d-%d too large for 64 bits!\n",
52                        start, end);
53         dump_stack();
54 }
55
56 void sja1105_packing(void *buf, u64 *val, int start, int end,
57                      size_t len, enum packing_op op)
58 {
59         int rc = packing(buf, val, start, end, len, op, QUIRK_LSW32_IS_FIRST);
60
61         if (likely(!rc))
62                 return;
63
64         if (rc == -EINVAL) {
65                 pr_err("Start bit (%d) expected to be larger than end (%d)\n",
66                        start, end);
67         } else if (rc == -ERANGE) {
68                 if ((start - end + 1) > 64)
69                         pr_err("Field %d-%d too large for 64 bits!\n",
70                                start, end);
71                 else
72                         pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n",
73                                *val, start, end);
74         }
75         dump_stack();
76 }
77
78 /* Little-endian Ethernet CRC32 of data packed as big-endian u32 words */
79 u32 sja1105_crc32(const void *buf, size_t len)
80 {
81         unsigned int i;
82         u64 word;
83         u32 crc;
84
85         /* seed */
86         crc = ~0;
87         for (i = 0; i < len; i += 4) {
88                 sja1105_unpack(buf + i, &word, 31, 0, 4);
89                 crc = crc32_le(crc, (u8 *)&word, 4);
90         }
91         return ~crc;
92 }
93
94 static size_t sja1105et_avb_params_entry_packing(void *buf, void *entry_ptr,
95                                                  enum packing_op op)
96 {
97         const size_t size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY;
98         struct sja1105_avb_params_entry *entry = entry_ptr;
99
100         sja1105_packing(buf, &entry->destmeta, 95, 48, size, op);
101         sja1105_packing(buf, &entry->srcmeta,  47,  0, size, op);
102         return size;
103 }
104
105 size_t sja1105pqrs_avb_params_entry_packing(void *buf, void *entry_ptr,
106                                             enum packing_op op)
107 {
108         const size_t size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY;
109         struct sja1105_avb_params_entry *entry = entry_ptr;
110
111         sja1105_packing(buf, &entry->cas_master, 126, 126, size, op);
112         sja1105_packing(buf, &entry->destmeta,   125,  78, size, op);
113         sja1105_packing(buf, &entry->srcmeta,     77,  30, size, op);
114         return size;
115 }
116
117 static size_t sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
118                                                      enum packing_op op)
119 {
120         const size_t size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY;
121         struct sja1105_general_params_entry *entry = entry_ptr;
122
123         sja1105_packing(buf, &entry->vllupformat, 319, 319, size, op);
124         sja1105_packing(buf, &entry->mirr_ptacu,  318, 318, size, op);
125         sja1105_packing(buf, &entry->switchid,    317, 315, size, op);
126         sja1105_packing(buf, &entry->hostprio,    314, 312, size, op);
127         sja1105_packing(buf, &entry->mac_fltres1, 311, 264, size, op);
128         sja1105_packing(buf, &entry->mac_fltres0, 263, 216, size, op);
129         sja1105_packing(buf, &entry->mac_flt1,    215, 168, size, op);
130         sja1105_packing(buf, &entry->mac_flt0,    167, 120, size, op);
131         sja1105_packing(buf, &entry->incl_srcpt1, 119, 119, size, op);
132         sja1105_packing(buf, &entry->incl_srcpt0, 118, 118, size, op);
133         sja1105_packing(buf, &entry->send_meta1,  117, 117, size, op);
134         sja1105_packing(buf, &entry->send_meta0,  116, 116, size, op);
135         sja1105_packing(buf, &entry->casc_port,   115, 113, size, op);
136         sja1105_packing(buf, &entry->host_port,   112, 110, size, op);
137         sja1105_packing(buf, &entry->mirr_port,   109, 107, size, op);
138         sja1105_packing(buf, &entry->vlmarker,    106,  75, size, op);
139         sja1105_packing(buf, &entry->vlmask,       74,  43, size, op);
140         sja1105_packing(buf, &entry->tpid,         42,  27, size, op);
141         sja1105_packing(buf, &entry->ignore2stf,   26,  26, size, op);
142         sja1105_packing(buf, &entry->tpid2,        25,  10, size, op);
143         return size;
144 }
145
146 /* TPID and TPID2 are intentionally reversed so that semantic
147  * compatibility with E/T is kept.
148  */
149 size_t sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr,
150                                                 enum packing_op op)
151 {
152         const size_t size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY;
153         struct sja1105_general_params_entry *entry = entry_ptr;
154
155         sja1105_packing(buf, &entry->vllupformat, 351, 351, size, op);
156         sja1105_packing(buf, &entry->mirr_ptacu,  350, 350, size, op);
157         sja1105_packing(buf, &entry->switchid,    349, 347, size, op);
158         sja1105_packing(buf, &entry->hostprio,    346, 344, size, op);
159         sja1105_packing(buf, &entry->mac_fltres1, 343, 296, size, op);
160         sja1105_packing(buf, &entry->mac_fltres0, 295, 248, size, op);
161         sja1105_packing(buf, &entry->mac_flt1,    247, 200, size, op);
162         sja1105_packing(buf, &entry->mac_flt0,    199, 152, size, op);
163         sja1105_packing(buf, &entry->incl_srcpt1, 151, 151, size, op);
164         sja1105_packing(buf, &entry->incl_srcpt0, 150, 150, size, op);
165         sja1105_packing(buf, &entry->send_meta1,  149, 149, size, op);
166         sja1105_packing(buf, &entry->send_meta0,  148, 148, size, op);
167         sja1105_packing(buf, &entry->casc_port,   147, 145, size, op);
168         sja1105_packing(buf, &entry->host_port,   144, 142, size, op);
169         sja1105_packing(buf, &entry->mirr_port,   141, 139, size, op);
170         sja1105_packing(buf, &entry->vlmarker,    138, 107, size, op);
171         sja1105_packing(buf, &entry->vlmask,      106,  75, size, op);
172         sja1105_packing(buf, &entry->tpid2,        74,  59, size, op);
173         sja1105_packing(buf, &entry->ignore2stf,   58,  58, size, op);
174         sja1105_packing(buf, &entry->tpid,         57,  42, size, op);
175         sja1105_packing(buf, &entry->queue_ts,     41,  41, size, op);
176         sja1105_packing(buf, &entry->egrmirrvid,   40,  29, size, op);
177         sja1105_packing(buf, &entry->egrmirrpcp,   28,  26, size, op);
178         sja1105_packing(buf, &entry->egrmirrdei,   25,  25, size, op);
179         sja1105_packing(buf, &entry->replay_port,  24,  22, size, op);
180         return size;
181 }
182
183 size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr,
184                                             enum packing_op op)
185 {
186         struct sja1105_general_params_entry *entry = entry_ptr;
187         const size_t size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY;
188
189         sja1105_packing(buf, &entry->vllupformat,  447, 447, size, op);
190         sja1105_packing(buf, &entry->mirr_ptacu,   446, 446, size, op);
191         sja1105_packing(buf, &entry->switchid,     445, 442, size, op);
192         sja1105_packing(buf, &entry->hostprio,     441, 439, size, op);
193         sja1105_packing(buf, &entry->mac_fltres1,  438, 391, size, op);
194         sja1105_packing(buf, &entry->mac_fltres0,  390, 343, size, op);
195         sja1105_packing(buf, &entry->mac_flt1,     342, 295, size, op);
196         sja1105_packing(buf, &entry->mac_flt0,     294, 247, size, op);
197         sja1105_packing(buf, &entry->incl_srcpt1,  246, 246, size, op);
198         sja1105_packing(buf, &entry->incl_srcpt0,  245, 245, size, op);
199         sja1105_packing(buf, &entry->send_meta1,   244, 244, size, op);
200         sja1105_packing(buf, &entry->send_meta0,   243, 243, size, op);
201         sja1105_packing(buf, &entry->casc_port,    242, 232, size, op);
202         sja1105_packing(buf, &entry->host_port,    231, 228, size, op);
203         sja1105_packing(buf, &entry->mirr_port,    227, 224, size, op);
204         sja1105_packing(buf, &entry->vlmarker,     223, 192, size, op);
205         sja1105_packing(buf, &entry->vlmask,       191, 160, size, op);
206         sja1105_packing(buf, &entry->tpid2,        159, 144, size, op);
207         sja1105_packing(buf, &entry->ignore2stf,   143, 143, size, op);
208         sja1105_packing(buf, &entry->tpid,         142, 127, size, op);
209         sja1105_packing(buf, &entry->queue_ts,     126, 126, size, op);
210         sja1105_packing(buf, &entry->egrmirrvid,   125, 114, size, op);
211         sja1105_packing(buf, &entry->egrmirrpcp,   113, 111, size, op);
212         sja1105_packing(buf, &entry->egrmirrdei,   110, 110, size, op);
213         sja1105_packing(buf, &entry->replay_port,  109, 106, size, op);
214         sja1105_packing(buf, &entry->tdmaconfigidx, 70,  67, size, op);
215         sja1105_packing(buf, &entry->header_type,   64,  49, size, op);
216         sja1105_packing(buf, &entry->tte_en,        16,  16, size, op);
217         return size;
218 }
219
220 static size_t
221 sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,
222                                            enum packing_op op)
223 {
224         const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY;
225         struct sja1105_l2_forwarding_params_entry *entry = entry_ptr;
226         int offset, i;
227
228         sja1105_packing(buf, &entry->max_dynp, 95, 93, size, op);
229         for (i = 0, offset = 13; i < 8; i++, offset += 10)
230                 sja1105_packing(buf, &entry->part_spc[i],
231                                 offset + 9, offset + 0, size, op);
232         return size;
233 }
234
235 size_t sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,
236                                                   enum packing_op op)
237 {
238         struct sja1105_l2_forwarding_params_entry *entry = entry_ptr;
239         const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY;
240         int offset, i;
241
242         sja1105_packing(buf, &entry->max_dynp, 95, 93, size, op);
243         for (i = 0, offset = 5; i < 8; i++, offset += 11)
244                 sja1105_packing(buf, &entry->part_spc[i],
245                                 offset + 10, offset + 0, size, op);
246         return size;
247 }
248
249 size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
250                                            enum packing_op op)
251 {
252         const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY;
253         struct sja1105_l2_forwarding_entry *entry = entry_ptr;
254         int offset, i;
255
256         sja1105_packing(buf, &entry->bc_domain,  63, 59, size, op);
257         sja1105_packing(buf, &entry->reach_port, 58, 54, size, op);
258         sja1105_packing(buf, &entry->fl_domain,  53, 49, size, op);
259         for (i = 0, offset = 25; i < 8; i++, offset += 3)
260                 sja1105_packing(buf, &entry->vlan_pmap[i],
261                                 offset + 2, offset + 0, size, op);
262         return size;
263 }
264
265 size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
266                                            enum packing_op op)
267 {
268         struct sja1105_l2_forwarding_entry *entry = entry_ptr;
269         const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY;
270         int offset, i;
271
272         if (entry->type_egrpcp2outputq) {
273                 for (i = 0, offset = 31; i < SJA1110_NUM_PORTS;
274                      i++, offset += 3) {
275                         sja1105_packing(buf, &entry->vlan_pmap[i],
276                                         offset + 2, offset + 0, size, op);
277                 }
278         } else {
279                 sja1105_packing(buf, &entry->bc_domain,  63, 53, size, op);
280                 sja1105_packing(buf, &entry->reach_port, 52, 42, size, op);
281                 sja1105_packing(buf, &entry->fl_domain,  41, 31, size, op);
282         }
283         return size;
284 }
285
286 static size_t
287 sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,
288                                          enum packing_op op)
289 {
290         const size_t size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY;
291         struct sja1105_l2_lookup_params_entry *entry = entry_ptr;
292
293         sja1105_packing(buf, &entry->maxage,         31, 17, size, op);
294         sja1105_packing(buf, &entry->dyn_tbsz,       16, 14, size, op);
295         sja1105_packing(buf, &entry->poly,           13,  6, size, op);
296         sja1105_packing(buf, &entry->shared_learn,    5,  5, size, op);
297         sja1105_packing(buf, &entry->no_enf_hostprt,  4,  4, size, op);
298         sja1105_packing(buf, &entry->no_mgmt_learn,   3,  3, size, op);
299         return size;
300 }
301
302 size_t sja1105pqrs_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,
303                                                   enum packing_op op)
304 {
305         const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY;
306         struct sja1105_l2_lookup_params_entry *entry = entry_ptr;
307         int offset, i;
308
309         for (i = 0, offset = 58; i < 5; i++, offset += 11)
310                 sja1105_packing(buf, &entry->maxaddrp[i],
311                                 offset + 10, offset + 0, size, op);
312         sja1105_packing(buf, &entry->maxage,         57,  43, size, op);
313         sja1105_packing(buf, &entry->start_dynspc,   42,  33, size, op);
314         sja1105_packing(buf, &entry->drpnolearn,     32,  28, size, op);
315         sja1105_packing(buf, &entry->shared_learn,   27,  27, size, op);
316         sja1105_packing(buf, &entry->no_enf_hostprt, 26,  26, size, op);
317         sja1105_packing(buf, &entry->no_mgmt_learn,  25,  25, size, op);
318         sja1105_packing(buf, &entry->use_static,     24,  24, size, op);
319         sja1105_packing(buf, &entry->owr_dyn,        23,  23, size, op);
320         sja1105_packing(buf, &entry->learn_once,     22,  22, size, op);
321         return size;
322 }
323
324 size_t sja1110_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,
325                                               enum packing_op op)
326 {
327         struct sja1105_l2_lookup_params_entry *entry = entry_ptr;
328         const size_t size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY;
329         int offset, i;
330
331         for (i = 0, offset = 70; i < SJA1110_NUM_PORTS; i++, offset += 11)
332                 sja1105_packing(buf, &entry->maxaddrp[i],
333                                 offset + 10, offset + 0, size, op);
334         sja1105_packing(buf, &entry->maxage,         69,  55, size, op);
335         sja1105_packing(buf, &entry->start_dynspc,   54,  45, size, op);
336         sja1105_packing(buf, &entry->drpnolearn,     44,  34, size, op);
337         sja1105_packing(buf, &entry->shared_learn,   33,  33, size, op);
338         sja1105_packing(buf, &entry->no_enf_hostprt, 32,  32, size, op);
339         sja1105_packing(buf, &entry->no_mgmt_learn,  31,  31, size, op);
340         sja1105_packing(buf, &entry->use_static,     30,  30, size, op);
341         sja1105_packing(buf, &entry->owr_dyn,        29,  29, size, op);
342         sja1105_packing(buf, &entry->learn_once,     28,  28, size, op);
343         return size;
344 }
345
346 size_t sja1105et_l2_lookup_entry_packing(void *buf, void *entry_ptr,
347                                          enum packing_op op)
348 {
349         const size_t size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
350         struct sja1105_l2_lookup_entry *entry = entry_ptr;
351
352         sja1105_packing(buf, &entry->vlanid,    95, 84, size, op);
353         sja1105_packing(buf, &entry->macaddr,   83, 36, size, op);
354         sja1105_packing(buf, &entry->destports, 35, 31, size, op);
355         sja1105_packing(buf, &entry->enfport,   30, 30, size, op);
356         sja1105_packing(buf, &entry->index,     29, 20, size, op);
357         return size;
358 }
359
360 size_t sja1105pqrs_l2_lookup_entry_packing(void *buf, void *entry_ptr,
361                                            enum packing_op op)
362 {
363         const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
364         struct sja1105_l2_lookup_entry *entry = entry_ptr;
365
366         if (entry->lockeds) {
367                 sja1105_packing(buf, &entry->tsreg,    159, 159, size, op);
368                 sja1105_packing(buf, &entry->mirrvlan, 158, 147, size, op);
369                 sja1105_packing(buf, &entry->takets,   146, 146, size, op);
370                 sja1105_packing(buf, &entry->mirr,     145, 145, size, op);
371                 sja1105_packing(buf, &entry->retag,    144, 144, size, op);
372         } else {
373                 sja1105_packing(buf, &entry->touched,  159, 159, size, op);
374                 sja1105_packing(buf, &entry->age,      158, 144, size, op);
375         }
376         sja1105_packing(buf, &entry->mask_iotag,   143, 143, size, op);
377         sja1105_packing(buf, &entry->mask_vlanid,  142, 131, size, op);
378         sja1105_packing(buf, &entry->mask_macaddr, 130,  83, size, op);
379         sja1105_packing(buf, &entry->iotag,         82,  82, size, op);
380         sja1105_packing(buf, &entry->vlanid,        81,  70, size, op);
381         sja1105_packing(buf, &entry->macaddr,       69,  22, size, op);
382         sja1105_packing(buf, &entry->destports,     21,  17, size, op);
383         sja1105_packing(buf, &entry->enfport,       16,  16, size, op);
384         sja1105_packing(buf, &entry->index,         15,   6, size, op);
385         return size;
386 }
387
388 size_t sja1110_l2_lookup_entry_packing(void *buf, void *entry_ptr,
389                                        enum packing_op op)
390 {
391         const size_t size = SJA1110_SIZE_L2_LOOKUP_ENTRY;
392         struct sja1105_l2_lookup_entry *entry = entry_ptr;
393
394         if (entry->lockeds) {
395                 sja1105_packing(buf, &entry->trap,     168, 168, size, op);
396                 sja1105_packing(buf, &entry->mirrvlan, 167, 156, size, op);
397                 sja1105_packing(buf, &entry->takets,   155, 155, size, op);
398                 sja1105_packing(buf, &entry->mirr,     154, 154, size, op);
399                 sja1105_packing(buf, &entry->retag,    153, 153, size, op);
400         } else {
401                 sja1105_packing(buf, &entry->touched,  168, 168, size, op);
402                 sja1105_packing(buf, &entry->age,      167, 153, size, op);
403         }
404         sja1105_packing(buf, &entry->mask_iotag,   152, 152, size, op);
405         sja1105_packing(buf, &entry->mask_vlanid,  151, 140, size, op);
406         sja1105_packing(buf, &entry->mask_macaddr, 139,  92, size, op);
407         sja1105_packing(buf, &entry->mask_srcport,  91,  88, size, op);
408         sja1105_packing(buf, &entry->iotag,         87,  87, size, op);
409         sja1105_packing(buf, &entry->vlanid,        86,  75, size, op);
410         sja1105_packing(buf, &entry->macaddr,       74,  27, size, op);
411         sja1105_packing(buf, &entry->srcport,       26,  23, size, op);
412         sja1105_packing(buf, &entry->destports,     22,  12, size, op);
413         sja1105_packing(buf, &entry->enfport,       11,  11, size, op);
414         sja1105_packing(buf, &entry->index,         10,   1, size, op);
415         return size;
416 }
417
418 static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr,
419                                                 enum packing_op op)
420 {
421         const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY;
422         struct sja1105_l2_policing_entry *entry = entry_ptr;
423
424         sja1105_packing(buf, &entry->sharindx,  63, 58, size, op);
425         sja1105_packing(buf, &entry->smax,      57, 42, size, op);
426         sja1105_packing(buf, &entry->rate,      41, 26, size, op);
427         sja1105_packing(buf, &entry->maxlen,    25, 15, size, op);
428         sja1105_packing(buf, &entry->partition, 14, 12, size, op);
429         return size;
430 }
431
432 size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr,
433                                          enum packing_op op)
434 {
435         struct sja1105_l2_policing_entry *entry = entry_ptr;
436         const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY;
437
438         sja1105_packing(buf, &entry->sharindx, 63, 57, size, op);
439         sja1105_packing(buf, &entry->smax,     56, 39, size, op);
440         sja1105_packing(buf, &entry->rate,     38, 21, size, op);
441         sja1105_packing(buf, &entry->maxlen,   20, 10, size, op);
442         sja1105_packing(buf, &entry->partition, 9,  7, size, op);
443         return size;
444 }
445
446 static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr,
447                                                  enum packing_op op)
448 {
449         const size_t size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY;
450         struct sja1105_mac_config_entry *entry = entry_ptr;
451         int offset, i;
452
453         for (i = 0, offset = 72; i < 8; i++, offset += 19) {
454                 sja1105_packing(buf, &entry->enabled[i],
455                                 offset +  0, offset +  0, size, op);
456                 sja1105_packing(buf, &entry->base[i],
457                                 offset +  9, offset +  1, size, op);
458                 sja1105_packing(buf, &entry->top[i],
459                                 offset + 18, offset + 10, size, op);
460         }
461         sja1105_packing(buf, &entry->ifg,       71, 67, size, op);
462         sja1105_packing(buf, &entry->speed,     66, 65, size, op);
463         sja1105_packing(buf, &entry->tp_delin,  64, 49, size, op);
464         sja1105_packing(buf, &entry->tp_delout, 48, 33, size, op);
465         sja1105_packing(buf, &entry->maxage,    32, 25, size, op);
466         sja1105_packing(buf, &entry->vlanprio,  24, 22, size, op);
467         sja1105_packing(buf, &entry->vlanid,    21, 10, size, op);
468         sja1105_packing(buf, &entry->ing_mirr,   9,  9, size, op);
469         sja1105_packing(buf, &entry->egr_mirr,   8,  8, size, op);
470         sja1105_packing(buf, &entry->drpnona664, 7,  7, size, op);
471         sja1105_packing(buf, &entry->drpdtag,    6,  6, size, op);
472         sja1105_packing(buf, &entry->drpuntag,   5,  5, size, op);
473         sja1105_packing(buf, &entry->retag,      4,  4, size, op);
474         sja1105_packing(buf, &entry->dyn_learn,  3,  3, size, op);
475         sja1105_packing(buf, &entry->egress,     2,  2, size, op);
476         sja1105_packing(buf, &entry->ingress,    1,  1, size, op);
477         return size;
478 }
479
480 size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr,
481                                             enum packing_op op)
482 {
483         const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
484         struct sja1105_mac_config_entry *entry = entry_ptr;
485         int offset, i;
486
487         for (i = 0, offset = 104; i < 8; i++, offset += 19) {
488                 sja1105_packing(buf, &entry->enabled[i],
489                                 offset +  0, offset +  0, size, op);
490                 sja1105_packing(buf, &entry->base[i],
491                                 offset +  9, offset +  1, size, op);
492                 sja1105_packing(buf, &entry->top[i],
493                                 offset + 18, offset + 10, size, op);
494         }
495         sja1105_packing(buf, &entry->ifg,       103, 99, size, op);
496         sja1105_packing(buf, &entry->speed,      98, 97, size, op);
497         sja1105_packing(buf, &entry->tp_delin,   96, 81, size, op);
498         sja1105_packing(buf, &entry->tp_delout,  80, 65, size, op);
499         sja1105_packing(buf, &entry->maxage,     64, 57, size, op);
500         sja1105_packing(buf, &entry->vlanprio,   56, 54, size, op);
501         sja1105_packing(buf, &entry->vlanid,     53, 42, size, op);
502         sja1105_packing(buf, &entry->ing_mirr,   41, 41, size, op);
503         sja1105_packing(buf, &entry->egr_mirr,   40, 40, size, op);
504         sja1105_packing(buf, &entry->drpnona664, 39, 39, size, op);
505         sja1105_packing(buf, &entry->drpdtag,    38, 38, size, op);
506         sja1105_packing(buf, &entry->drpuntag,   35, 35, size, op);
507         sja1105_packing(buf, &entry->retag,      34, 34, size, op);
508         sja1105_packing(buf, &entry->dyn_learn,  33, 33, size, op);
509         sja1105_packing(buf, &entry->egress,     32, 32, size, op);
510         sja1105_packing(buf, &entry->ingress,    31, 31, size, op);
511         return size;
512 }
513
514 size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr,
515                                         enum packing_op op)
516 {
517         const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
518         struct sja1105_mac_config_entry *entry = entry_ptr;
519         int offset, i;
520
521         for (i = 0, offset = 104; i < 8; i++, offset += 19) {
522                 sja1105_packing(buf, &entry->enabled[i],
523                                 offset +  0, offset +  0, size, op);
524                 sja1105_packing(buf, &entry->base[i],
525                                 offset +  9, offset +  1, size, op);
526                 sja1105_packing(buf, &entry->top[i],
527                                 offset + 18, offset + 10, size, op);
528         }
529         sja1105_packing(buf, &entry->speed,      98, 96, size, op);
530         sja1105_packing(buf, &entry->tp_delin,   95, 80, size, op);
531         sja1105_packing(buf, &entry->tp_delout,  79, 64, size, op);
532         sja1105_packing(buf, &entry->maxage,     63, 56, size, op);
533         sja1105_packing(buf, &entry->vlanprio,   55, 53, size, op);
534         sja1105_packing(buf, &entry->vlanid,     52, 41, size, op);
535         sja1105_packing(buf, &entry->ing_mirr,   40, 40, size, op);
536         sja1105_packing(buf, &entry->egr_mirr,   39, 39, size, op);
537         sja1105_packing(buf, &entry->drpnona664, 38, 38, size, op);
538         sja1105_packing(buf, &entry->drpdtag,    37, 37, size, op);
539         sja1105_packing(buf, &entry->drpuntag,   34, 34, size, op);
540         sja1105_packing(buf, &entry->retag,      33, 33, size, op);
541         sja1105_packing(buf, &entry->dyn_learn,  32, 32, size, op);
542         sja1105_packing(buf, &entry->egress,     31, 31, size, op);
543         sja1105_packing(buf, &entry->ingress,    30, 30, size, op);
544         sja1105_packing(buf, &entry->ifg,        10,  5, size, op);
545         return size;
546 }
547
548 static size_t
549 sja1105_schedule_entry_points_params_entry_packing(void *buf, void *entry_ptr,
550                                                    enum packing_op op)
551 {
552         struct sja1105_schedule_entry_points_params_entry *entry = entry_ptr;
553         const size_t size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY;
554
555         sja1105_packing(buf, &entry->clksrc,    31, 30, size, op);
556         sja1105_packing(buf, &entry->actsubsch, 29, 27, size, op);
557         return size;
558 }
559
560 static size_t
561 sja1105_schedule_entry_points_entry_packing(void *buf, void *entry_ptr,
562                                             enum packing_op op)
563 {
564         struct sja1105_schedule_entry_points_entry *entry = entry_ptr;
565         const size_t size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY;
566
567         sja1105_packing(buf, &entry->subschindx, 31, 29, size, op);
568         sja1105_packing(buf, &entry->delta,      28, 11, size, op);
569         sja1105_packing(buf, &entry->address,    10, 1,  size, op);
570         return size;
571 }
572
573 static size_t
574 sja1110_schedule_entry_points_entry_packing(void *buf, void *entry_ptr,
575                                             enum packing_op op)
576 {
577         struct sja1105_schedule_entry_points_entry *entry = entry_ptr;
578         const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY;
579
580         sja1105_packing(buf, &entry->subschindx, 63, 61, size, op);
581         sja1105_packing(buf, &entry->delta,      60, 43, size, op);
582         sja1105_packing(buf, &entry->address,    42, 31, size, op);
583         return size;
584 }
585
586 static size_t sja1105_schedule_params_entry_packing(void *buf, void *entry_ptr,
587                                                     enum packing_op op)
588 {
589         const size_t size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY;
590         struct sja1105_schedule_params_entry *entry = entry_ptr;
591         int offset, i;
592
593         for (i = 0, offset = 16; i < 8; i++, offset += 10)
594                 sja1105_packing(buf, &entry->subscheind[i],
595                                 offset + 9, offset + 0, size, op);
596         return size;
597 }
598
599 static size_t sja1110_schedule_params_entry_packing(void *buf, void *entry_ptr,
600                                                     enum packing_op op)
601 {
602         struct sja1105_schedule_params_entry *entry = entry_ptr;
603         const size_t size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY;
604         int offset, i;
605
606         for (i = 0, offset = 0; i < 8; i++, offset += 12)
607                 sja1105_packing(buf, &entry->subscheind[i],
608                                 offset + 11, offset + 0, size, op);
609         return size;
610 }
611
612 static size_t sja1105_schedule_entry_packing(void *buf, void *entry_ptr,
613                                              enum packing_op op)
614 {
615         const size_t size = SJA1105_SIZE_SCHEDULE_ENTRY;
616         struct sja1105_schedule_entry *entry = entry_ptr;
617
618         sja1105_packing(buf, &entry->winstindex,  63, 54, size, op);
619         sja1105_packing(buf, &entry->winend,      53, 53, size, op);
620         sja1105_packing(buf, &entry->winst,       52, 52, size, op);
621         sja1105_packing(buf, &entry->destports,   51, 47, size, op);
622         sja1105_packing(buf, &entry->setvalid,    46, 46, size, op);
623         sja1105_packing(buf, &entry->txen,        45, 45, size, op);
624         sja1105_packing(buf, &entry->resmedia_en, 44, 44, size, op);
625         sja1105_packing(buf, &entry->resmedia,    43, 36, size, op);
626         sja1105_packing(buf, &entry->vlindex,     35, 26, size, op);
627         sja1105_packing(buf, &entry->delta,       25, 8,  size, op);
628         return size;
629 }
630
631 static size_t sja1110_schedule_entry_packing(void *buf, void *entry_ptr,
632                                              enum packing_op op)
633 {
634         const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY;
635         struct sja1105_schedule_entry *entry = entry_ptr;
636
637         sja1105_packing(buf, &entry->winstindex,  95, 84, size, op);
638         sja1105_packing(buf, &entry->winend,      83, 83, size, op);
639         sja1105_packing(buf, &entry->winst,       82, 82, size, op);
640         sja1105_packing(buf, &entry->destports,   81, 71, size, op);
641         sja1105_packing(buf, &entry->setvalid,    70, 70, size, op);
642         sja1105_packing(buf, &entry->txen,        69, 69, size, op);
643         sja1105_packing(buf, &entry->resmedia_en, 68, 68, size, op);
644         sja1105_packing(buf, &entry->resmedia,    67, 60, size, op);
645         sja1105_packing(buf, &entry->vlindex,     59, 48, size, op);
646         sja1105_packing(buf, &entry->delta,       47, 30, size, op);
647         return size;
648 }
649
650 static size_t
651 sja1105_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr,
652                                            enum packing_op op)
653 {
654         struct sja1105_vl_forwarding_params_entry *entry = entry_ptr;
655         const size_t size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY;
656         int offset, i;
657
658         for (i = 0, offset = 16; i < 8; i++, offset += 10)
659                 sja1105_packing(buf, &entry->partspc[i],
660                                 offset + 9, offset + 0, size, op);
661         sja1105_packing(buf, &entry->debugen, 15, 15, size, op);
662         return size;
663 }
664
665 static size_t
666 sja1110_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr,
667                                            enum packing_op op)
668 {
669         struct sja1105_vl_forwarding_params_entry *entry = entry_ptr;
670         const size_t size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY;
671         int offset, i;
672
673         for (i = 0, offset = 8; i < 8; i++, offset += 11)
674                 sja1105_packing(buf, &entry->partspc[i],
675                                 offset + 10, offset + 0, size, op);
676         sja1105_packing(buf, &entry->debugen, 7, 7, size, op);
677         return size;
678 }
679
680 static size_t sja1105_vl_forwarding_entry_packing(void *buf, void *entry_ptr,
681                                                   enum packing_op op)
682 {
683         struct sja1105_vl_forwarding_entry *entry = entry_ptr;
684         const size_t size = SJA1105_SIZE_VL_FORWARDING_ENTRY;
685
686         sja1105_packing(buf, &entry->type,      31, 31, size, op);
687         sja1105_packing(buf, &entry->priority,  30, 28, size, op);
688         sja1105_packing(buf, &entry->partition, 27, 25, size, op);
689         sja1105_packing(buf, &entry->destports, 24, 20, size, op);
690         return size;
691 }
692
693 static size_t sja1110_vl_forwarding_entry_packing(void *buf, void *entry_ptr,
694                                                   enum packing_op op)
695 {
696         struct sja1105_vl_forwarding_entry *entry = entry_ptr;
697         const size_t size = SJA1105_SIZE_VL_FORWARDING_ENTRY;
698
699         sja1105_packing(buf, &entry->type,      31, 31, size, op);
700         sja1105_packing(buf, &entry->priority,  30, 28, size, op);
701         sja1105_packing(buf, &entry->partition, 27, 25, size, op);
702         sja1105_packing(buf, &entry->destports, 24, 14, size, op);
703         return size;
704 }
705
706 size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr,
707                                        enum packing_op op)
708 {
709         struct sja1105_vl_lookup_entry *entry = entry_ptr;
710         const size_t size = SJA1105_SIZE_VL_LOOKUP_ENTRY;
711
712         if (entry->format == SJA1105_VL_FORMAT_PSFP) {
713                 /* Interpreting vllupformat as 0 */
714                 sja1105_packing(buf, &entry->destports,
715                                 95, 91, size, op);
716                 sja1105_packing(buf, &entry->iscritical,
717                                 90, 90, size, op);
718                 sja1105_packing(buf, &entry->macaddr,
719                                 89, 42, size, op);
720                 sja1105_packing(buf, &entry->vlanid,
721                                 41, 30, size, op);
722                 sja1105_packing(buf, &entry->port,
723                                 29, 27, size, op);
724                 sja1105_packing(buf, &entry->vlanprior,
725                                 26, 24, size, op);
726         } else {
727                 /* Interpreting vllupformat as 1 */
728                 sja1105_packing(buf, &entry->egrmirr,
729                                 95, 91, size, op);
730                 sja1105_packing(buf, &entry->ingrmirr,
731                                 90, 90, size, op);
732                 sja1105_packing(buf, &entry->vlid,
733                                 57, 42, size, op);
734                 sja1105_packing(buf, &entry->port,
735                                 29, 27, size, op);
736         }
737         return size;
738 }
739
740 size_t sja1110_vl_lookup_entry_packing(void *buf, void *entry_ptr,
741                                        enum packing_op op)
742 {
743         struct sja1105_vl_lookup_entry *entry = entry_ptr;
744         const size_t size = SJA1105_SIZE_VL_LOOKUP_ENTRY;
745
746         if (entry->format == SJA1105_VL_FORMAT_PSFP) {
747                 /* Interpreting vllupformat as 0 */
748                 sja1105_packing(buf, &entry->destports,
749                                 94, 84, size, op);
750                 sja1105_packing(buf, &entry->iscritical,
751                                 83, 83, size, op);
752                 sja1105_packing(buf, &entry->macaddr,
753                                 82, 35, size, op);
754                 sja1105_packing(buf, &entry->vlanid,
755                                 34, 23, size, op);
756                 sja1105_packing(buf, &entry->port,
757                                 22, 19, size, op);
758                 sja1105_packing(buf, &entry->vlanprior,
759                                 18, 16, size, op);
760         } else {
761                 /* Interpreting vllupformat as 1 */
762                 sja1105_packing(buf, &entry->egrmirr,
763                                 94, 84, size, op);
764                 sja1105_packing(buf, &entry->ingrmirr,
765                                 83, 83, size, op);
766                 sja1105_packing(buf, &entry->vlid,
767                                 50, 35, size, op);
768                 sja1105_packing(buf, &entry->port,
769                                 22, 19, size, op);
770         }
771         return size;
772 }
773
774 static size_t sja1105_vl_policing_entry_packing(void *buf, void *entry_ptr,
775                                                 enum packing_op op)
776 {
777         struct sja1105_vl_policing_entry *entry = entry_ptr;
778         const size_t size = SJA1105_SIZE_VL_POLICING_ENTRY;
779
780         sja1105_packing(buf, &entry->type,      63, 63, size, op);
781         sja1105_packing(buf, &entry->maxlen,    62, 52, size, op);
782         sja1105_packing(buf, &entry->sharindx,  51, 42, size, op);
783         if (entry->type == 0) {
784                 sja1105_packing(buf, &entry->bag,    41, 28, size, op);
785                 sja1105_packing(buf, &entry->jitter, 27, 18, size, op);
786         }
787         return size;
788 }
789
790 size_t sja1110_vl_policing_entry_packing(void *buf, void *entry_ptr,
791                                          enum packing_op op)
792 {
793         struct sja1105_vl_policing_entry *entry = entry_ptr;
794         const size_t size = SJA1105_SIZE_VL_POLICING_ENTRY;
795
796         sja1105_packing(buf, &entry->type,      63, 63, size, op);
797         sja1105_packing(buf, &entry->maxlen,    62, 52, size, op);
798         sja1105_packing(buf, &entry->sharindx,  51, 40, size, op);
799         if (entry->type == 0) {
800                 sja1105_packing(buf, &entry->bag,    41, 28, size, op);
801                 sja1105_packing(buf, &entry->jitter, 27, 18, size, op);
802         }
803         return size;
804 }
805
806 size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr,
807                                          enum packing_op op)
808 {
809         const size_t size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY;
810         struct sja1105_vlan_lookup_entry *entry = entry_ptr;
811
812         sja1105_packing(buf, &entry->ving_mirr,  63, 59, size, op);
813         sja1105_packing(buf, &entry->vegr_mirr,  58, 54, size, op);
814         sja1105_packing(buf, &entry->vmemb_port, 53, 49, size, op);
815         sja1105_packing(buf, &entry->vlan_bc,    48, 44, size, op);
816         sja1105_packing(buf, &entry->tag_port,   43, 39, size, op);
817         sja1105_packing(buf, &entry->vlanid,     38, 27, size, op);
818         return size;
819 }
820
821 size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr,
822                                          enum packing_op op)
823 {
824         struct sja1105_vlan_lookup_entry *entry = entry_ptr;
825         const size_t size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY;
826
827         sja1105_packing(buf, &entry->ving_mirr,  95, 85, size, op);
828         sja1105_packing(buf, &entry->vegr_mirr,  84, 74, size, op);
829         sja1105_packing(buf, &entry->vmemb_port, 73, 63, size, op);
830         sja1105_packing(buf, &entry->vlan_bc,    62, 52, size, op);
831         sja1105_packing(buf, &entry->tag_port,   51, 41, size, op);
832         sja1105_packing(buf, &entry->type_entry, 40, 39, size, op);
833         sja1105_packing(buf, &entry->vlanid,     38, 27, size, op);
834         return size;
835 }
836
837 static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr,
838                                                 enum packing_op op)
839 {
840         const size_t size = SJA1105_SIZE_XMII_PARAMS_ENTRY;
841         struct sja1105_xmii_params_entry *entry = entry_ptr;
842         int offset, i;
843
844         for (i = 0, offset = 17; i < 5; i++, offset += 3) {
845                 sja1105_packing(buf, &entry->xmii_mode[i],
846                                 offset + 1, offset + 0, size, op);
847                 sja1105_packing(buf, &entry->phy_mac[i],
848                                 offset + 2, offset + 2, size, op);
849         }
850         return size;
851 }
852
853 size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr,
854                                          enum packing_op op)
855 {
856         const size_t size = SJA1110_SIZE_XMII_PARAMS_ENTRY;
857         struct sja1105_xmii_params_entry *entry = entry_ptr;
858         int offset, i;
859
860         for (i = 0, offset = 20; i < SJA1110_NUM_PORTS; i++, offset += 4) {
861                 sja1105_packing(buf, &entry->xmii_mode[i],
862                                 offset + 1, offset + 0, size, op);
863                 sja1105_packing(buf, &entry->phy_mac[i],
864                                 offset + 2, offset + 2, size, op);
865                 sja1105_packing(buf, &entry->special[i],
866                                 offset + 3, offset + 3, size, op);
867         }
868         return size;
869 }
870
871 size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr,
872                                        enum packing_op op)
873 {
874         struct sja1105_retagging_entry *entry = entry_ptr;
875         const size_t size = SJA1105_SIZE_RETAGGING_ENTRY;
876
877         sja1105_packing(buf, &entry->egr_port,       63, 59, size, op);
878         sja1105_packing(buf, &entry->ing_port,       58, 54, size, op);
879         sja1105_packing(buf, &entry->vlan_ing,       53, 42, size, op);
880         sja1105_packing(buf, &entry->vlan_egr,       41, 30, size, op);
881         sja1105_packing(buf, &entry->do_not_learn,   29, 29, size, op);
882         sja1105_packing(buf, &entry->use_dest_ports, 28, 28, size, op);
883         sja1105_packing(buf, &entry->destports,      27, 23, size, op);
884         return size;
885 }
886
887 size_t sja1110_retagging_entry_packing(void *buf, void *entry_ptr,
888                                        enum packing_op op)
889 {
890         struct sja1105_retagging_entry *entry = entry_ptr;
891         const size_t size = SJA1105_SIZE_RETAGGING_ENTRY;
892
893         sja1105_packing(buf, &entry->egr_port,       63, 53, size, op);
894         sja1105_packing(buf, &entry->ing_port,       52, 42, size, op);
895         sja1105_packing(buf, &entry->vlan_ing,       41, 30, size, op);
896         sja1105_packing(buf, &entry->vlan_egr,       29, 18, size, op);
897         sja1105_packing(buf, &entry->do_not_learn,   17, 17, size, op);
898         sja1105_packing(buf, &entry->use_dest_ports, 16, 16, size, op);
899         sja1105_packing(buf, &entry->destports,      15, 5, size, op);
900         return size;
901 }
902
903 static size_t sja1110_pcp_remapping_entry_packing(void *buf, void *entry_ptr,
904                                                   enum packing_op op)
905 {
906         struct sja1110_pcp_remapping_entry *entry = entry_ptr;
907         const size_t size = SJA1110_SIZE_PCP_REMAPPING_ENTRY;
908         int offset, i;
909
910         for (i = 0, offset = 8; i < SJA1105_NUM_TC; i++, offset += 3)
911                 sja1105_packing(buf, &entry->egrpcp[i],
912                                 offset + 2, offset + 0, size, op);
913
914         return size;
915 }
916
917 size_t sja1105_table_header_packing(void *buf, void *entry_ptr,
918                                     enum packing_op op)
919 {
920         const size_t size = SJA1105_SIZE_TABLE_HEADER;
921         struct sja1105_table_header *entry = entry_ptr;
922
923         sja1105_packing(buf, &entry->block_id, 31, 24, size, op);
924         sja1105_packing(buf, &entry->len,      55, 32, size, op);
925         sja1105_packing(buf, &entry->crc,      95, 64, size, op);
926         return size;
927 }
928
929 /* WARNING: the *hdr pointer is really non-const, because it is
930  * modifying the CRC of the header for a 2-stage packing operation
931  */
932 void
933 sja1105_table_header_pack_with_crc(void *buf, struct sja1105_table_header *hdr)
934 {
935         /* First pack the table as-is, then calculate the CRC, and
936          * finally put the proper CRC into the packed buffer
937          */
938         memset(buf, 0, SJA1105_SIZE_TABLE_HEADER);
939         sja1105_table_header_packing(buf, hdr, PACK);
940         hdr->crc = sja1105_crc32(buf, SJA1105_SIZE_TABLE_HEADER - 4);
941         sja1105_pack(buf + SJA1105_SIZE_TABLE_HEADER - 4, &hdr->crc, 31, 0, 4);
942 }
943
944 static void sja1105_table_write_crc(u8 *table_start, u8 *crc_ptr)
945 {
946         u64 computed_crc;
947         int len_bytes;
948
949         len_bytes = (uintptr_t)(crc_ptr - table_start);
950         computed_crc = sja1105_crc32(table_start, len_bytes);
951         sja1105_pack(crc_ptr, &computed_crc, 31, 0, 4);
952 }
953
954 /* The block IDs that the switches support are unfortunately sparse, so keep a
955  * mapping table to "block indices" and translate back and forth so that we
956  * don't waste useless memory in struct sja1105_static_config.
957  * Also, since the block id comes from essentially untrusted input (unpacking
958  * the static config from userspace) it has to be sanitized (range-checked)
959  * before blindly indexing kernel memory with the blk_idx.
960  */
961 static u64 blk_id_map[BLK_IDX_MAX] = {
962         [BLK_IDX_SCHEDULE] = BLKID_SCHEDULE,
963         [BLK_IDX_SCHEDULE_ENTRY_POINTS] = BLKID_SCHEDULE_ENTRY_POINTS,
964         [BLK_IDX_VL_LOOKUP] = BLKID_VL_LOOKUP,
965         [BLK_IDX_VL_POLICING] = BLKID_VL_POLICING,
966         [BLK_IDX_VL_FORWARDING] = BLKID_VL_FORWARDING,
967         [BLK_IDX_L2_LOOKUP] = BLKID_L2_LOOKUP,
968         [BLK_IDX_L2_POLICING] = BLKID_L2_POLICING,
969         [BLK_IDX_VLAN_LOOKUP] = BLKID_VLAN_LOOKUP,
970         [BLK_IDX_L2_FORWARDING] = BLKID_L2_FORWARDING,
971         [BLK_IDX_MAC_CONFIG] = BLKID_MAC_CONFIG,
972         [BLK_IDX_SCHEDULE_PARAMS] = BLKID_SCHEDULE_PARAMS,
973         [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = BLKID_SCHEDULE_ENTRY_POINTS_PARAMS,
974         [BLK_IDX_VL_FORWARDING_PARAMS] = BLKID_VL_FORWARDING_PARAMS,
975         [BLK_IDX_L2_LOOKUP_PARAMS] = BLKID_L2_LOOKUP_PARAMS,
976         [BLK_IDX_L2_FORWARDING_PARAMS] = BLKID_L2_FORWARDING_PARAMS,
977         [BLK_IDX_AVB_PARAMS] = BLKID_AVB_PARAMS,
978         [BLK_IDX_GENERAL_PARAMS] = BLKID_GENERAL_PARAMS,
979         [BLK_IDX_RETAGGING] = BLKID_RETAGGING,
980         [BLK_IDX_XMII_PARAMS] = BLKID_XMII_PARAMS,
981         [BLK_IDX_PCP_REMAPPING] = BLKID_PCP_REMAPPING,
982 };
983
984 const char *sja1105_static_config_error_msg[] = {
985         [SJA1105_CONFIG_OK] = "",
986         [SJA1105_TTETHERNET_NOT_SUPPORTED] =
987                 "schedule-table present, but TTEthernet is "
988                 "only supported on T and Q/S",
989         [SJA1105_INCORRECT_TTETHERNET_CONFIGURATION] =
990                 "schedule-table present, but one of "
991                 "schedule-entry-points-table, schedule-parameters-table or "
992                 "schedule-entry-points-parameters table is empty",
993         [SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION] =
994                 "vl-lookup-table present, but one of vl-policing-table, "
995                 "vl-forwarding-table or vl-forwarding-parameters-table is empty",
996         [SJA1105_MISSING_L2_POLICING_TABLE] =
997                 "l2-policing-table needs to have at least one entry",
998         [SJA1105_MISSING_L2_FORWARDING_TABLE] =
999                 "l2-forwarding-table is either missing or incomplete",
1000         [SJA1105_MISSING_L2_FORWARDING_PARAMS_TABLE] =
1001                 "l2-forwarding-parameters-table is missing",
1002         [SJA1105_MISSING_GENERAL_PARAMS_TABLE] =
1003                 "general-parameters-table is missing",
1004         [SJA1105_MISSING_VLAN_TABLE] =
1005                 "vlan-lookup-table needs to have at least the default untagged VLAN",
1006         [SJA1105_MISSING_XMII_TABLE] =
1007                 "xmii-table is missing",
1008         [SJA1105_MISSING_MAC_TABLE] =
1009                 "mac-configuration-table needs to contain an entry for each port",
1010         [SJA1105_OVERCOMMITTED_FRAME_MEMORY] =
1011                 "Not allowed to overcommit frame memory. L2 memory partitions "
1012                 "and VL memory partitions share the same space. The sum of all "
1013                 "16 memory partitions is not allowed to be larger than 929 "
1014                 "128-byte blocks (or 910 with retagging). Please adjust "
1015                 "l2-forwarding-parameters-table.part_spc and/or "
1016                 "vl-forwarding-parameters-table.partspc.",
1017 };
1018
1019 static sja1105_config_valid_t
1020 static_config_check_memory_size(const struct sja1105_table *tables, int max_mem)
1021 {
1022         const struct sja1105_l2_forwarding_params_entry *l2_fwd_params;
1023         const struct sja1105_vl_forwarding_params_entry *vl_fwd_params;
1024         int i, mem = 0;
1025
1026         l2_fwd_params = tables[BLK_IDX_L2_FORWARDING_PARAMS].entries;
1027
1028         for (i = 0; i < 8; i++)
1029                 mem += l2_fwd_params->part_spc[i];
1030
1031         if (tables[BLK_IDX_VL_FORWARDING_PARAMS].entry_count) {
1032                 vl_fwd_params = tables[BLK_IDX_VL_FORWARDING_PARAMS].entries;
1033                 for (i = 0; i < 8; i++)
1034                         mem += vl_fwd_params->partspc[i];
1035         }
1036
1037         if (tables[BLK_IDX_RETAGGING].entry_count)
1038                 max_mem -= SJA1105_FRAME_MEMORY_RETAGGING_OVERHEAD;
1039
1040         if (mem > max_mem)
1041                 return SJA1105_OVERCOMMITTED_FRAME_MEMORY;
1042
1043         return SJA1105_CONFIG_OK;
1044 }
1045
1046 sja1105_config_valid_t
1047 sja1105_static_config_check_valid(const struct sja1105_static_config *config,
1048                                   int max_mem)
1049 {
1050         const struct sja1105_table *tables = config->tables;
1051 #define IS_FULL(blk_idx) \
1052         (tables[blk_idx].entry_count == tables[blk_idx].ops->max_entry_count)
1053
1054         if (tables[BLK_IDX_SCHEDULE].entry_count) {
1055                 if (!tables[BLK_IDX_SCHEDULE].ops->max_entry_count)
1056                         return SJA1105_TTETHERNET_NOT_SUPPORTED;
1057
1058                 if (tables[BLK_IDX_SCHEDULE_ENTRY_POINTS].entry_count == 0)
1059                         return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION;
1060
1061                 if (!IS_FULL(BLK_IDX_SCHEDULE_PARAMS))
1062                         return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION;
1063
1064                 if (!IS_FULL(BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS))
1065                         return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION;
1066         }
1067         if (tables[BLK_IDX_VL_LOOKUP].entry_count) {
1068                 struct sja1105_vl_lookup_entry *vl_lookup;
1069                 bool has_critical_links = false;
1070                 int i;
1071
1072                 vl_lookup = tables[BLK_IDX_VL_LOOKUP].entries;
1073
1074                 for (i = 0; i < tables[BLK_IDX_VL_LOOKUP].entry_count; i++) {
1075                         if (vl_lookup[i].iscritical) {
1076                                 has_critical_links = true;
1077                                 break;
1078                         }
1079                 }
1080
1081                 if (tables[BLK_IDX_VL_POLICING].entry_count == 0 &&
1082                     has_critical_links)
1083                         return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION;
1084
1085                 if (tables[BLK_IDX_VL_FORWARDING].entry_count == 0 &&
1086                     has_critical_links)
1087                         return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION;
1088
1089                 if (tables[BLK_IDX_VL_FORWARDING_PARAMS].entry_count == 0 &&
1090                     has_critical_links)
1091                         return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION;
1092         }
1093
1094         if (tables[BLK_IDX_L2_POLICING].entry_count == 0)
1095                 return SJA1105_MISSING_L2_POLICING_TABLE;
1096
1097         if (tables[BLK_IDX_VLAN_LOOKUP].entry_count == 0)
1098                 return SJA1105_MISSING_VLAN_TABLE;
1099
1100         if (!IS_FULL(BLK_IDX_L2_FORWARDING))
1101                 return SJA1105_MISSING_L2_FORWARDING_TABLE;
1102
1103         if (!IS_FULL(BLK_IDX_MAC_CONFIG))
1104                 return SJA1105_MISSING_MAC_TABLE;
1105
1106         if (!IS_FULL(BLK_IDX_L2_FORWARDING_PARAMS))
1107                 return SJA1105_MISSING_L2_FORWARDING_PARAMS_TABLE;
1108
1109         if (!IS_FULL(BLK_IDX_GENERAL_PARAMS))
1110                 return SJA1105_MISSING_GENERAL_PARAMS_TABLE;
1111
1112         if (!IS_FULL(BLK_IDX_XMII_PARAMS))
1113                 return SJA1105_MISSING_XMII_TABLE;
1114
1115         return static_config_check_memory_size(tables, max_mem);
1116 #undef IS_FULL
1117 }
1118
1119 void
1120 sja1105_static_config_pack(void *buf, struct sja1105_static_config *config)
1121 {
1122         struct sja1105_table_header header = {0};
1123         enum sja1105_blk_idx i;
1124         char *p = buf;
1125         int j;
1126
1127         sja1105_pack(p, &config->device_id, 31, 0, 4);
1128         p += SJA1105_SIZE_DEVICE_ID;
1129
1130         for (i = 0; i < BLK_IDX_MAX; i++) {
1131                 const struct sja1105_table *table;
1132                 char *table_start;
1133
1134                 table = &config->tables[i];
1135                 if (!table->entry_count)
1136                         continue;
1137
1138                 header.block_id = blk_id_map[i];
1139                 header.len = table->entry_count *
1140                              table->ops->packed_entry_size / 4;
1141                 sja1105_table_header_pack_with_crc(p, &header);
1142                 p += SJA1105_SIZE_TABLE_HEADER;
1143                 table_start = p;
1144                 for (j = 0; j < table->entry_count; j++) {
1145                         u8 *entry_ptr = table->entries;
1146
1147                         entry_ptr += j * table->ops->unpacked_entry_size;
1148                         memset(p, 0, table->ops->packed_entry_size);
1149                         table->ops->packing(p, entry_ptr, PACK);
1150                         p += table->ops->packed_entry_size;
1151                 }
1152                 sja1105_table_write_crc(table_start, p);
1153                 p += 4;
1154         }
1155         /* Final header:
1156          * Block ID does not matter
1157          * Length of 0 marks that header is final
1158          * CRC will be replaced on-the-fly on "config upload"
1159          */
1160         header.block_id = 0;
1161         header.len = 0;
1162         header.crc = 0xDEADBEEF;
1163         memset(p, 0, SJA1105_SIZE_TABLE_HEADER);
1164         sja1105_table_header_packing(p, &header, PACK);
1165 }
1166
1167 size_t
1168 sja1105_static_config_get_length(const struct sja1105_static_config *config)
1169 {
1170         unsigned int sum;
1171         unsigned int header_count;
1172         enum sja1105_blk_idx i;
1173
1174         /* Ending header */
1175         header_count = 1;
1176         sum = SJA1105_SIZE_DEVICE_ID;
1177
1178         /* Tables (headers and entries) */
1179         for (i = 0; i < BLK_IDX_MAX; i++) {
1180                 const struct sja1105_table *table;
1181
1182                 table = &config->tables[i];
1183                 if (table->entry_count)
1184                         header_count++;
1185
1186                 sum += table->ops->packed_entry_size * table->entry_count;
1187         }
1188         /* Headers have an additional CRC at the end */
1189         sum += header_count * (SJA1105_SIZE_TABLE_HEADER + 4);
1190         /* Last header does not have an extra CRC because there is no data */
1191         sum -= 4;
1192
1193         return sum;
1194 }
1195
1196 /* Compatibility matrices */
1197
1198 /* SJA1105E: First generation, no TTEthernet */
1199 const struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = {
1200         [BLK_IDX_L2_LOOKUP] = {
1201                 .packing = sja1105et_l2_lookup_entry_packing,
1202                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
1203                 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY,
1204                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1205         },
1206         [BLK_IDX_L2_POLICING] = {
1207                 .packing = sja1105_l2_policing_entry_packing,
1208                 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1209                 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1210                 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1211         },
1212         [BLK_IDX_VLAN_LOOKUP] = {
1213                 .packing = sja1105_vlan_lookup_entry_packing,
1214                 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1215                 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1216                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1217         },
1218         [BLK_IDX_L2_FORWARDING] = {
1219                 .packing = sja1105_l2_forwarding_entry_packing,
1220                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1221                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1222                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1223         },
1224         [BLK_IDX_MAC_CONFIG] = {
1225                 .packing = sja1105et_mac_config_entry_packing,
1226                 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1227                 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY,
1228                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1229         },
1230         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1231                 .packing = sja1105et_l2_lookup_params_entry_packing,
1232                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
1233                 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY,
1234                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1235         },
1236         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1237                 .packing = sja1105_l2_forwarding_params_entry_packing,
1238                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1239                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1240                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1241         },
1242         [BLK_IDX_AVB_PARAMS] = {
1243                 .packing = sja1105et_avb_params_entry_packing,
1244                 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
1245                 .packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY,
1246                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1247         },
1248         [BLK_IDX_GENERAL_PARAMS] = {
1249                 .packing = sja1105et_general_params_entry_packing,
1250                 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1251                 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY,
1252                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1253         },
1254         [BLK_IDX_RETAGGING] = {
1255                 .packing = sja1105_retagging_entry_packing,
1256                 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry),
1257                 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY,
1258                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1259         },
1260         [BLK_IDX_XMII_PARAMS] = {
1261                 .packing = sja1105_xmii_params_entry_packing,
1262                 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1263                 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1264                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1265         },
1266 };
1267
1268 /* SJA1105T: First generation, TTEthernet */
1269 const struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX] = {
1270         [BLK_IDX_SCHEDULE] = {
1271                 .packing = sja1105_schedule_entry_packing,
1272                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry),
1273                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY,
1274                 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT,
1275         },
1276         [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {
1277                 .packing = sja1105_schedule_entry_points_entry_packing,
1278                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry),
1279                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY,
1280                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT,
1281         },
1282         [BLK_IDX_VL_LOOKUP] = {
1283                 .packing = sja1105_vl_lookup_entry_packing,
1284                 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry),
1285                 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY,
1286                 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
1287         },
1288         [BLK_IDX_VL_POLICING] = {
1289                 .packing = sja1105_vl_policing_entry_packing,
1290                 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry),
1291                 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY,
1292                 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT,
1293         },
1294         [BLK_IDX_VL_FORWARDING] = {
1295                 .packing = sja1105_vl_forwarding_entry_packing,
1296                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry),
1297                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY,
1298                 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT,
1299         },
1300         [BLK_IDX_L2_LOOKUP] = {
1301                 .packing = sja1105et_l2_lookup_entry_packing,
1302                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
1303                 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY,
1304                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1305         },
1306         [BLK_IDX_L2_POLICING] = {
1307                 .packing = sja1105_l2_policing_entry_packing,
1308                 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1309                 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1310                 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1311         },
1312         [BLK_IDX_VLAN_LOOKUP] = {
1313                 .packing = sja1105_vlan_lookup_entry_packing,
1314                 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1315                 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1316                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1317         },
1318         [BLK_IDX_L2_FORWARDING] = {
1319                 .packing = sja1105_l2_forwarding_entry_packing,
1320                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1321                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1322                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1323         },
1324         [BLK_IDX_MAC_CONFIG] = {
1325                 .packing = sja1105et_mac_config_entry_packing,
1326                 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1327                 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY,
1328                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1329         },
1330         [BLK_IDX_SCHEDULE_PARAMS] = {
1331                 .packing = sja1105_schedule_params_entry_packing,
1332                 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry),
1333                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY,
1334                 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT,
1335         },
1336         [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {
1337                 .packing = sja1105_schedule_entry_points_params_entry_packing,
1338                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry),
1339                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY,
1340                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT,
1341         },
1342         [BLK_IDX_VL_FORWARDING_PARAMS] = {
1343                 .packing = sja1105_vl_forwarding_params_entry_packing,
1344                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry),
1345                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY,
1346                 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT,
1347         },
1348         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1349                 .packing = sja1105et_l2_lookup_params_entry_packing,
1350                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
1351                 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY,
1352                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1353         },
1354         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1355                 .packing = sja1105_l2_forwarding_params_entry_packing,
1356                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1357                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1358                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1359         },
1360         [BLK_IDX_AVB_PARAMS] = {
1361                 .packing = sja1105et_avb_params_entry_packing,
1362                 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
1363                 .packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY,
1364                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1365         },
1366         [BLK_IDX_GENERAL_PARAMS] = {
1367                 .packing = sja1105et_general_params_entry_packing,
1368                 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1369                 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY,
1370                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1371         },
1372         [BLK_IDX_RETAGGING] = {
1373                 .packing = sja1105_retagging_entry_packing,
1374                 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry),
1375                 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY,
1376                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1377         },
1378         [BLK_IDX_XMII_PARAMS] = {
1379                 .packing = sja1105_xmii_params_entry_packing,
1380                 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1381                 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1382                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1383         },
1384 };
1385
1386 /* SJA1105P: Second generation, no TTEthernet, no SGMII */
1387 const struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = {
1388         [BLK_IDX_L2_LOOKUP] = {
1389                 .packing = sja1105pqrs_l2_lookup_entry_packing,
1390                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
1391                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY,
1392                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1393         },
1394         [BLK_IDX_L2_POLICING] = {
1395                 .packing = sja1105_l2_policing_entry_packing,
1396                 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1397                 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1398                 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1399         },
1400         [BLK_IDX_VLAN_LOOKUP] = {
1401                 .packing = sja1105_vlan_lookup_entry_packing,
1402                 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1403                 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1404                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1405         },
1406         [BLK_IDX_L2_FORWARDING] = {
1407                 .packing = sja1105_l2_forwarding_entry_packing,
1408                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1409                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1410                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1411         },
1412         [BLK_IDX_MAC_CONFIG] = {
1413                 .packing = sja1105pqrs_mac_config_entry_packing,
1414                 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1415                 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1416                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1417         },
1418         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1419                 .packing = sja1105pqrs_l2_lookup_params_entry_packing,
1420                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
1421                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY,
1422                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1423         },
1424         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1425                 .packing = sja1105_l2_forwarding_params_entry_packing,
1426                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1427                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1428                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1429         },
1430         [BLK_IDX_AVB_PARAMS] = {
1431                 .packing = sja1105pqrs_avb_params_entry_packing,
1432                 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
1433                 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
1434                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1435         },
1436         [BLK_IDX_GENERAL_PARAMS] = {
1437                 .packing = sja1105pqrs_general_params_entry_packing,
1438                 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1439                 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY,
1440                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1441         },
1442         [BLK_IDX_RETAGGING] = {
1443                 .packing = sja1105_retagging_entry_packing,
1444                 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry),
1445                 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY,
1446                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1447         },
1448         [BLK_IDX_XMII_PARAMS] = {
1449                 .packing = sja1105_xmii_params_entry_packing,
1450                 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1451                 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1452                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1453         },
1454 };
1455
1456 /* SJA1105Q: Second generation, TTEthernet, no SGMII */
1457 const struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX] = {
1458         [BLK_IDX_SCHEDULE] = {
1459                 .packing = sja1105_schedule_entry_packing,
1460                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry),
1461                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY,
1462                 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT,
1463         },
1464         [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {
1465                 .packing = sja1105_schedule_entry_points_entry_packing,
1466                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry),
1467                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY,
1468                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT,
1469         },
1470         [BLK_IDX_VL_LOOKUP] = {
1471                 .packing = sja1105_vl_lookup_entry_packing,
1472                 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry),
1473                 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY,
1474                 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
1475         },
1476         [BLK_IDX_VL_POLICING] = {
1477                 .packing = sja1105_vl_policing_entry_packing,
1478                 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry),
1479                 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY,
1480                 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT,
1481         },
1482         [BLK_IDX_VL_FORWARDING] = {
1483                 .packing = sja1105_vl_forwarding_entry_packing,
1484                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry),
1485                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY,
1486                 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT,
1487         },
1488         [BLK_IDX_L2_LOOKUP] = {
1489                 .packing = sja1105pqrs_l2_lookup_entry_packing,
1490                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
1491                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY,
1492                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1493         },
1494         [BLK_IDX_L2_POLICING] = {
1495                 .packing = sja1105_l2_policing_entry_packing,
1496                 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1497                 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1498                 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1499         },
1500         [BLK_IDX_VLAN_LOOKUP] = {
1501                 .packing = sja1105_vlan_lookup_entry_packing,
1502                 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1503                 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1504                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1505         },
1506         [BLK_IDX_L2_FORWARDING] = {
1507                 .packing = sja1105_l2_forwarding_entry_packing,
1508                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1509                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1510                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1511         },
1512         [BLK_IDX_MAC_CONFIG] = {
1513                 .packing = sja1105pqrs_mac_config_entry_packing,
1514                 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1515                 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1516                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1517         },
1518         [BLK_IDX_SCHEDULE_PARAMS] = {
1519                 .packing = sja1105_schedule_params_entry_packing,
1520                 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry),
1521                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY,
1522                 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT,
1523         },
1524         [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {
1525                 .packing = sja1105_schedule_entry_points_params_entry_packing,
1526                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry),
1527                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY,
1528                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT,
1529         },
1530         [BLK_IDX_VL_FORWARDING_PARAMS] = {
1531                 .packing = sja1105_vl_forwarding_params_entry_packing,
1532                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry),
1533                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY,
1534                 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT,
1535         },
1536         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1537                 .packing = sja1105pqrs_l2_lookup_params_entry_packing,
1538                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
1539                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY,
1540                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1541         },
1542         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1543                 .packing = sja1105_l2_forwarding_params_entry_packing,
1544                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1545                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1546                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1547         },
1548         [BLK_IDX_AVB_PARAMS] = {
1549                 .packing = sja1105pqrs_avb_params_entry_packing,
1550                 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
1551                 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
1552                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1553         },
1554         [BLK_IDX_GENERAL_PARAMS] = {
1555                 .packing = sja1105pqrs_general_params_entry_packing,
1556                 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1557                 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY,
1558                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1559         },
1560         [BLK_IDX_RETAGGING] = {
1561                 .packing = sja1105_retagging_entry_packing,
1562                 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry),
1563                 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY,
1564                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1565         },
1566         [BLK_IDX_XMII_PARAMS] = {
1567                 .packing = sja1105_xmii_params_entry_packing,
1568                 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1569                 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1570                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1571         },
1572 };
1573
1574 /* SJA1105R: Second generation, no TTEthernet, SGMII */
1575 const struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = {
1576         [BLK_IDX_L2_LOOKUP] = {
1577                 .packing = sja1105pqrs_l2_lookup_entry_packing,
1578                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
1579                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY,
1580                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1581         },
1582         [BLK_IDX_L2_POLICING] = {
1583                 .packing = sja1105_l2_policing_entry_packing,
1584                 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1585                 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1586                 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1587         },
1588         [BLK_IDX_VLAN_LOOKUP] = {
1589                 .packing = sja1105_vlan_lookup_entry_packing,
1590                 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1591                 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1592                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1593         },
1594         [BLK_IDX_L2_FORWARDING] = {
1595                 .packing = sja1105_l2_forwarding_entry_packing,
1596                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1597                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1598                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1599         },
1600         [BLK_IDX_MAC_CONFIG] = {
1601                 .packing = sja1105pqrs_mac_config_entry_packing,
1602                 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1603                 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1604                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1605         },
1606         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1607                 .packing = sja1105pqrs_l2_lookup_params_entry_packing,
1608                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
1609                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY,
1610                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1611         },
1612         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1613                 .packing = sja1105_l2_forwarding_params_entry_packing,
1614                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1615                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1616                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1617         },
1618         [BLK_IDX_AVB_PARAMS] = {
1619                 .packing = sja1105pqrs_avb_params_entry_packing,
1620                 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
1621                 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
1622                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1623         },
1624         [BLK_IDX_GENERAL_PARAMS] = {
1625                 .packing = sja1105pqrs_general_params_entry_packing,
1626                 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1627                 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY,
1628                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1629         },
1630         [BLK_IDX_RETAGGING] = {
1631                 .packing = sja1105_retagging_entry_packing,
1632                 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry),
1633                 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY,
1634                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1635         },
1636         [BLK_IDX_XMII_PARAMS] = {
1637                 .packing = sja1105_xmii_params_entry_packing,
1638                 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1639                 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1640                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1641         },
1642 };
1643
1644 /* SJA1105S: Second generation, TTEthernet, SGMII */
1645 const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = {
1646         [BLK_IDX_SCHEDULE] = {
1647                 .packing = sja1105_schedule_entry_packing,
1648                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry),
1649                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY,
1650                 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT,
1651         },
1652         [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {
1653                 .packing = sja1105_schedule_entry_points_entry_packing,
1654                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry),
1655                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY,
1656                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT,
1657         },
1658         [BLK_IDX_VL_LOOKUP] = {
1659                 .packing = sja1105_vl_lookup_entry_packing,
1660                 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry),
1661                 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY,
1662                 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
1663         },
1664         [BLK_IDX_VL_POLICING] = {
1665                 .packing = sja1105_vl_policing_entry_packing,
1666                 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry),
1667                 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY,
1668                 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT,
1669         },
1670         [BLK_IDX_VL_FORWARDING] = {
1671                 .packing = sja1105_vl_forwarding_entry_packing,
1672                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry),
1673                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY,
1674                 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT,
1675         },
1676         [BLK_IDX_L2_LOOKUP] = {
1677                 .packing = sja1105pqrs_l2_lookup_entry_packing,
1678                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
1679                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY,
1680                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1681         },
1682         [BLK_IDX_L2_POLICING] = {
1683                 .packing = sja1105_l2_policing_entry_packing,
1684                 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1685                 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1686                 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT,
1687         },
1688         [BLK_IDX_VLAN_LOOKUP] = {
1689                 .packing = sja1105_vlan_lookup_entry_packing,
1690                 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1691                 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY,
1692                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1693         },
1694         [BLK_IDX_L2_FORWARDING] = {
1695                 .packing = sja1105_l2_forwarding_entry_packing,
1696                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1697                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1698                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1699         },
1700         [BLK_IDX_MAC_CONFIG] = {
1701                 .packing = sja1105pqrs_mac_config_entry_packing,
1702                 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1703                 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1704                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1705         },
1706         [BLK_IDX_SCHEDULE_PARAMS] = {
1707                 .packing = sja1105_schedule_params_entry_packing,
1708                 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry),
1709                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY,
1710                 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT,
1711         },
1712         [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {
1713                 .packing = sja1105_schedule_entry_points_params_entry_packing,
1714                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry),
1715                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY,
1716                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT,
1717         },
1718         [BLK_IDX_VL_FORWARDING_PARAMS] = {
1719                 .packing = sja1105_vl_forwarding_params_entry_packing,
1720                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry),
1721                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY,
1722                 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT,
1723         },
1724         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1725                 .packing = sja1105pqrs_l2_lookup_params_entry_packing,
1726                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
1727                 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY,
1728                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1729         },
1730         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1731                 .packing = sja1105_l2_forwarding_params_entry_packing,
1732                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1733                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1734                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1735         },
1736         [BLK_IDX_AVB_PARAMS] = {
1737                 .packing = sja1105pqrs_avb_params_entry_packing,
1738                 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
1739                 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
1740                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1741         },
1742         [BLK_IDX_GENERAL_PARAMS] = {
1743                 .packing = sja1105pqrs_general_params_entry_packing,
1744                 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1745                 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY,
1746                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1747         },
1748         [BLK_IDX_RETAGGING] = {
1749                 .packing = sja1105_retagging_entry_packing,
1750                 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry),
1751                 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY,
1752                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1753         },
1754         [BLK_IDX_XMII_PARAMS] = {
1755                 .packing = sja1105_xmii_params_entry_packing,
1756                 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1757                 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY,
1758                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1759         },
1760 };
1761
1762 /* SJA1110A: Third generation */
1763 const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX] = {
1764         [BLK_IDX_SCHEDULE] = {
1765                 .packing = sja1110_schedule_entry_packing,
1766                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry),
1767                 .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY,
1768                 .max_entry_count = SJA1110_MAX_SCHEDULE_COUNT,
1769         },
1770         [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {
1771                 .packing = sja1110_schedule_entry_points_entry_packing,
1772                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry),
1773                 .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY,
1774                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT,
1775         },
1776         [BLK_IDX_VL_LOOKUP] = {
1777                 .packing = sja1110_vl_lookup_entry_packing,
1778                 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry),
1779                 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY,
1780                 .max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT,
1781         },
1782         [BLK_IDX_VL_POLICING] = {
1783                 .packing = sja1110_vl_policing_entry_packing,
1784                 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry),
1785                 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY,
1786                 .max_entry_count = SJA1110_MAX_VL_POLICING_COUNT,
1787         },
1788         [BLK_IDX_VL_FORWARDING] = {
1789                 .packing = sja1110_vl_forwarding_entry_packing,
1790                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry),
1791                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY,
1792                 .max_entry_count = SJA1110_MAX_VL_FORWARDING_COUNT,
1793         },
1794         [BLK_IDX_L2_LOOKUP] = {
1795                 .packing = sja1110_l2_lookup_entry_packing,
1796                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry),
1797                 .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_ENTRY,
1798                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1799         },
1800         [BLK_IDX_L2_POLICING] = {
1801                 .packing = sja1110_l2_policing_entry_packing,
1802                 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry),
1803                 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY,
1804                 .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT,
1805         },
1806         [BLK_IDX_VLAN_LOOKUP] = {
1807                 .packing = sja1110_vlan_lookup_entry_packing,
1808                 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry),
1809                 .packed_entry_size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY,
1810                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1811         },
1812         [BLK_IDX_L2_FORWARDING] = {
1813                 .packing = sja1110_l2_forwarding_entry_packing,
1814                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry),
1815                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY,
1816                 .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT,
1817         },
1818         [BLK_IDX_MAC_CONFIG] = {
1819                 .packing = sja1110_mac_config_entry_packing,
1820                 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry),
1821                 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY,
1822                 .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT,
1823         },
1824         [BLK_IDX_SCHEDULE_PARAMS] = {
1825                 .packing = sja1110_schedule_params_entry_packing,
1826                 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry),
1827                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY,
1828                 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT,
1829         },
1830         [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {
1831                 .packing = sja1105_schedule_entry_points_params_entry_packing,
1832                 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry),
1833                 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY,
1834                 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT,
1835         },
1836         [BLK_IDX_VL_FORWARDING_PARAMS] = {
1837                 .packing = sja1110_vl_forwarding_params_entry_packing,
1838                 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry),
1839                 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY,
1840                 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT,
1841         },
1842         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1843                 .packing = sja1110_l2_lookup_params_entry_packing,
1844                 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry),
1845                 .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY,
1846                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1847         },
1848         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1849                 .packing = sja1110_l2_forwarding_params_entry_packing,
1850                 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry),
1851                 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY,
1852                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1853         },
1854         [BLK_IDX_AVB_PARAMS] = {
1855                 .packing = sja1105pqrs_avb_params_entry_packing,
1856                 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry),
1857                 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY,
1858                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1859         },
1860         [BLK_IDX_GENERAL_PARAMS] = {
1861                 .packing = sja1110_general_params_entry_packing,
1862                 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry),
1863                 .packed_entry_size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY,
1864                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1865         },
1866         [BLK_IDX_RETAGGING] = {
1867                 .packing = sja1110_retagging_entry_packing,
1868                 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry),
1869                 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY,
1870                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1871         },
1872         [BLK_IDX_XMII_PARAMS] = {
1873                 .packing = sja1110_xmii_params_entry_packing,
1874                 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry),
1875                 .packed_entry_size = SJA1110_SIZE_XMII_PARAMS_ENTRY,
1876                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1877         },
1878         [BLK_IDX_PCP_REMAPPING] = {
1879                 .packing = sja1110_pcp_remapping_entry_packing,
1880                 .unpacked_entry_size = sizeof(struct sja1110_pcp_remapping_entry),
1881                 .packed_entry_size = SJA1110_SIZE_PCP_REMAPPING_ENTRY,
1882                 .max_entry_count = SJA1110_MAX_PCP_REMAPPING_COUNT,
1883         },
1884 };
1885
1886 int sja1105_static_config_init(struct sja1105_static_config *config,
1887                                const struct sja1105_table_ops *static_ops,
1888                                u64 device_id)
1889 {
1890         enum sja1105_blk_idx i;
1891
1892         *config = (struct sja1105_static_config) {0};
1893
1894         /* Transfer static_ops array from priv into per-table ops
1895          * for handier access
1896          */
1897         for (i = 0; i < BLK_IDX_MAX; i++)
1898                 config->tables[i].ops = &static_ops[i];
1899
1900         config->device_id = device_id;
1901         return 0;
1902 }
1903
1904 void sja1105_static_config_free(struct sja1105_static_config *config)
1905 {
1906         enum sja1105_blk_idx i;
1907
1908         for (i = 0; i < BLK_IDX_MAX; i++) {
1909                 if (config->tables[i].entry_count) {
1910                         kfree(config->tables[i].entries);
1911                         config->tables[i].entry_count = 0;
1912                 }
1913         }
1914 }
1915
1916 int sja1105_table_delete_entry(struct sja1105_table *table, int i)
1917 {
1918         size_t entry_size = table->ops->unpacked_entry_size;
1919         u8 *entries = table->entries;
1920
1921         if (i > table->entry_count)
1922                 return -ERANGE;
1923
1924         memmove(entries + i * entry_size, entries + (i + 1) * entry_size,
1925                 (table->entry_count - i) * entry_size);
1926
1927         table->entry_count--;
1928
1929         return 0;
1930 }
1931
1932 /* No pointers to table->entries should be kept when this is called. */
1933 int sja1105_table_resize(struct sja1105_table *table, size_t new_count)
1934 {
1935         size_t entry_size = table->ops->unpacked_entry_size;
1936         void *new_entries, *old_entries = table->entries;
1937
1938         if (new_count > table->ops->max_entry_count)
1939                 return -ERANGE;
1940
1941         new_entries = kcalloc(new_count, entry_size, GFP_KERNEL);
1942         if (!new_entries)
1943                 return -ENOMEM;
1944
1945         memcpy(new_entries, old_entries, min(new_count, table->entry_count) *
1946                 entry_size);
1947
1948         table->entries = new_entries;
1949         table->entry_count = new_count;
1950         kfree(old_entries);
1951         return 0;
1952 }