56fead68ea9fc84cab70c15c593678e94f4efb10
[linux-2.6-microblaze.git] / drivers / net / dsa / sja1105 / sja1105_dynamic_config.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
3  */
4 #include "sja1105.h"
5
6 /* In the dynamic configuration interface, the switch exposes a register-like
7  * view of some of the static configuration tables.
8  * Many times the field organization of the dynamic tables is abbreviated (not
9  * all fields are dynamically reconfigurable) and different from the static
10  * ones, but the key reason for having it is that we can spare a switch reset
11  * for settings that can be changed dynamically.
12  *
13  * This file creates a per-switch-family abstraction called
14  * struct sja1105_dynamic_table_ops and two operations that work with it:
15  * - sja1105_dynamic_config_write
16  * - sja1105_dynamic_config_read
17  *
18  * Compared to the struct sja1105_table_ops from sja1105_static_config.c,
19  * the dynamic accessors work with a compound buffer:
20  *
21  * packed_buf
22  *
23  * |
24  * V
25  * +-----------------------------------------+------------------+
26  * |              ENTRY BUFFER               |  COMMAND BUFFER  |
27  * +-----------------------------------------+------------------+
28  *
29  * <----------------------- packed_size ------------------------>
30  *
31  * The ENTRY BUFFER may or may not have the same layout, or size, as its static
32  * configuration table entry counterpart. When it does, the same packing
33  * function is reused (bar exceptional cases - see
34  * sja1105pqrs_dyn_l2_lookup_entry_packing).
35  *
36  * The reason for the COMMAND BUFFER being at the end is to be able to send
37  * a dynamic write command through a single SPI burst. By the time the switch
38  * reacts to the command, the ENTRY BUFFER is already populated with the data
39  * sent by the core.
40  *
41  * The COMMAND BUFFER is always SJA1105_SIZE_DYN_CMD bytes (one 32-bit word) in
42  * size.
43  *
44  * Sometimes the ENTRY BUFFER does not really exist (when the number of fields
45  * that can be reconfigured is small), then the switch repurposes some of the
46  * unused 32 bits of the COMMAND BUFFER to hold ENTRY data.
47  *
48  * The key members of struct sja1105_dynamic_table_ops are:
49  * - .entry_packing: A function that deals with packing an ENTRY structure
50  *                   into an SPI buffer, or retrieving an ENTRY structure
51  *                   from one.
52  *                   The @packed_buf pointer it's given does always point to
53  *                   the ENTRY portion of the buffer.
54  * - .cmd_packing: A function that deals with packing/unpacking the COMMAND
55  *                 structure to/from the SPI buffer.
56  *                 It is given the same @packed_buf pointer as .entry_packing,
57  *                 so most of the time, the @packed_buf points *behind* the
58  *                 COMMAND offset inside the buffer.
59  *                 To access the COMMAND portion of the buffer, the function
60  *                 knows its correct offset.
61  *                 Giving both functions the same pointer is handy because in
62  *                 extreme cases (see sja1105pqrs_dyn_l2_lookup_entry_packing)
63  *                 the .entry_packing is able to jump to the COMMAND portion,
64  *                 or vice-versa (sja1105pqrs_l2_lookup_cmd_packing).
65  * - .access: A bitmap of:
66  *      OP_READ: Set if the hardware manual marks the ENTRY portion of the
67  *               dynamic configuration table buffer as R (readable) after
68  *               an SPI read command (the switch will populate the buffer).
69  *      OP_WRITE: Set if the manual marks the ENTRY portion of the dynamic
70  *                table buffer as W (writable) after an SPI write command
71  *                (the switch will read the fields provided in the buffer).
72  *      OP_DEL: Set if the manual says the VALIDENT bit is supported in the
73  *              COMMAND portion of this dynamic config buffer (i.e. the
74  *              specified entry can be invalidated through a SPI write
75  *              command).
76  *      OP_SEARCH: Set if the manual says that the index of an entry can
77  *                 be retrieved in the COMMAND portion of the buffer based
78  *                 on its ENTRY portion, as a result of a SPI write command.
79  *                 Only the TCAM-based FDB table on SJA1105 P/Q/R/S supports
80  *                 this.
81  *      OP_VALID_ANYWAY: Reading some tables through the dynamic config
82  *                       interface is possible even if the VALIDENT bit is not
83  *                       set in the writeback. So don't error out in that case.
84  * - .max_entry_count: The number of entries, counting from zero, that can be
85  *                     reconfigured through the dynamic interface. If a static
86  *                     table can be reconfigured at all dynamically, this
87  *                     number always matches the maximum number of supported
88  *                     static entries.
89  * - .packed_size: The length in bytes of the compound ENTRY + COMMAND BUFFER.
90  *                 Note that sometimes the compound buffer may contain holes in
91  *                 it (see sja1105_vlan_lookup_cmd_packing). The @packed_buf is
92  *                 contiguous however, so @packed_size includes any unused
93  *                 bytes.
94  * - .addr: The base SPI address at which the buffer must be written to the
95  *          switch's memory. When looking at the hardware manual, this must
96  *          always match the lowest documented address for the ENTRY, and not
97  *          that of the COMMAND, since the other 32-bit words will follow along
98  *          at the correct addresses.
99  */
100
101 #define SJA1105_SIZE_DYN_CMD                                    4
102
103 #define SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD                        \
104         SJA1105_SIZE_DYN_CMD
105
106 #define SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD                      \
107         (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_LOOKUP_ENTRY)
108
109 #define SJA1110_SIZE_VL_POLICING_DYN_CMD                        \
110         (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_POLICING_ENTRY)
111
112 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY                     \
113         SJA1105_SIZE_DYN_CMD
114
115 #define SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD                        \
116         (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_L2_LOOKUP_ENTRY)
117
118 #define SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD                      \
119         (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY)
120
121 #define SJA1110_SIZE_L2_LOOKUP_DYN_CMD                          \
122         (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_ENTRY)
123
124 #define SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD                        \
125         (SJA1105_SIZE_DYN_CMD + 4 + SJA1105_SIZE_VLAN_LOOKUP_ENTRY)
126
127 #define SJA1110_SIZE_VLAN_LOOKUP_DYN_CMD                        \
128         (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_VLAN_LOOKUP_ENTRY)
129
130 #define SJA1105_SIZE_L2_FORWARDING_DYN_CMD                      \
131         (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_FORWARDING_ENTRY)
132
133 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD                       \
134         (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY)
135
136 #define SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD                     \
137         (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY)
138
139 #define SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD                 \
140         SJA1105_SIZE_DYN_CMD
141
142 #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD               \
143         (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY)
144
145 #define SJA1110_SIZE_L2_LOOKUP_PARAMS_DYN_CMD           \
146         (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY)
147
148 #define SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD                   \
149         SJA1105_SIZE_DYN_CMD
150
151 #define SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD                 \
152         (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY)
153
154 #define SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD                     \
155         (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_GENERAL_PARAMS_ENTRY)
156
157 #define SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD                     \
158         (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY)
159
160 #define SJA1105_SIZE_RETAGGING_DYN_CMD                          \
161         (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_RETAGGING_ENTRY)
162
163 #define SJA1105ET_SIZE_CBS_DYN_CMD                              \
164         (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_CBS_ENTRY)
165
166 #define SJA1105PQRS_SIZE_CBS_DYN_CMD                            \
167         (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_CBS_ENTRY)
168
169 #define SJA1110_SIZE_XMII_PARAMS_DYN_CMD                        \
170         SJA1110_SIZE_XMII_PARAMS_ENTRY
171
172 #define SJA1110_SIZE_L2_POLICING_DYN_CMD                        \
173         (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_POLICING_ENTRY)
174
175 #define SJA1110_SIZE_L2_FORWARDING_PARAMS_DYN_CMD               \
176         SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY
177
178 #define SJA1105_MAX_DYN_CMD_SIZE                                \
179         SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD
180
181 struct sja1105_dyn_cmd {
182         bool search;
183         u64 valid;
184         u64 rdwrset;
185         u64 errors;
186         u64 valident;
187         u64 index;
188 };
189
190 enum sja1105_hostcmd {
191         SJA1105_HOSTCMD_SEARCH = 1,
192         SJA1105_HOSTCMD_READ = 2,
193         SJA1105_HOSTCMD_WRITE = 3,
194         SJA1105_HOSTCMD_INVALIDATE = 4,
195 };
196
197 /* Command and entry overlap */
198 static void
199 sja1105et_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
200                                 enum packing_op op)
201 {
202         const int size = SJA1105_SIZE_DYN_CMD;
203
204         sja1105_packing(buf, &cmd->valid,   31, 31, size, op);
205         sja1105_packing(buf, &cmd->errors,  30, 30, size, op);
206         sja1105_packing(buf, &cmd->rdwrset, 29, 29, size, op);
207         sja1105_packing(buf, &cmd->index,    9,  0, size, op);
208 }
209
210 /* Command and entry are separate */
211 static void
212 sja1105pqrs_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
213                                   enum packing_op op)
214 {
215         u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY;
216         const int size = SJA1105_SIZE_DYN_CMD;
217
218         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
219         sja1105_packing(p, &cmd->errors,  30, 30, size, op);
220         sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
221         sja1105_packing(p, &cmd->index,    9,  0, size, op);
222 }
223
224 static void
225 sja1110_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
226                               enum packing_op op)
227 {
228         u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
229         const int size = SJA1105_SIZE_DYN_CMD;
230
231         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
232         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
233         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
234         sja1105_packing(p, &cmd->index,   11,  0, size, op);
235 }
236
237 static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr,
238                                                 enum packing_op op)
239 {
240         struct sja1105_vl_lookup_entry *entry = entry_ptr;
241         const int size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD;
242
243         sja1105_packing(buf, &entry->egrmirr,  21, 17, size, op);
244         sja1105_packing(buf, &entry->ingrmirr, 16, 16, size, op);
245         return size;
246 }
247
248 static void
249 sja1110_vl_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
250                                 enum packing_op op)
251 {
252         u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY;
253         const int size = SJA1105_SIZE_DYN_CMD;
254
255         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
256         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
257         sja1105_packing(p, &cmd->index,   11,  0, size, op);
258 }
259
260 static void
261 sja1105pqrs_common_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
262                                          enum packing_op op, int entry_size)
263 {
264         const int size = SJA1105_SIZE_DYN_CMD;
265         u8 *p = buf + entry_size;
266         u64 hostcmd;
267
268         sja1105_packing(p, &cmd->valid,    31, 31, size, op);
269         sja1105_packing(p, &cmd->rdwrset,  30, 30, size, op);
270         sja1105_packing(p, &cmd->errors,   29, 29, size, op);
271         sja1105_packing(p, &cmd->valident, 27, 27, size, op);
272
273         /* VALIDENT is supposed to indicate "keep or not", but in SJA1105 E/T,
274          * using it to delete a management route was unsupported. UM10944
275          * said about it:
276          *
277          *   In case of a write access with the MGMTROUTE flag set,
278          *   the flag will be ignored. It will always be found cleared
279          *   for read accesses with the MGMTROUTE flag set.
280          *
281          * SJA1105 P/Q/R/S keeps the same behavior w.r.t. VALIDENT, but there
282          * is now another flag called HOSTCMD which does more stuff (quoting
283          * from UM11040):
284          *
285          *   A write request is accepted only when HOSTCMD is set to write host
286          *   or invalid. A read request is accepted only when HOSTCMD is set to
287          *   search host or read host.
288          *
289          * So it is possible to translate a RDWRSET/VALIDENT combination into
290          * HOSTCMD so that we keep the dynamic command API in place, and
291          * at the same time achieve compatibility with the management route
292          * command structure.
293          */
294         if (cmd->rdwrset == SPI_READ) {
295                 if (cmd->search)
296                         hostcmd = SJA1105_HOSTCMD_SEARCH;
297                 else
298                         hostcmd = SJA1105_HOSTCMD_READ;
299         } else {
300                 /* SPI_WRITE */
301                 if (cmd->valident)
302                         hostcmd = SJA1105_HOSTCMD_WRITE;
303                 else
304                         hostcmd = SJA1105_HOSTCMD_INVALIDATE;
305         }
306         sja1105_packing(p, &hostcmd, 25, 23, size, op);
307
308         /* Hack - The hardware takes the 'index' field within
309          * struct sja1105_l2_lookup_entry as the index on which this command
310          * will operate. However it will ignore everything else, so 'index'
311          * is logically part of command but physically part of entry.
312          * Populate the 'index' entry field from within the command callback,
313          * such that our API doesn't need to ask for a full-blown entry
314          * structure when e.g. a delete is requested.
315          */
316         sja1105_packing(buf, &cmd->index, 15, 6,
317                         SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, op);
318 }
319
320 static void
321 sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
322                                   enum packing_op op)
323 {
324         int size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
325
326         return sja1105pqrs_common_l2_lookup_cmd_packing(buf, cmd, op, size);
327 }
328
329 static void
330 sja1110_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
331                               enum packing_op op)
332 {
333         int size = SJA1110_SIZE_L2_LOOKUP_ENTRY;
334
335         return sja1105pqrs_common_l2_lookup_cmd_packing(buf, cmd, op, size);
336 }
337
338 /* The switch is so retarded that it makes our command/entry abstraction
339  * crumble apart.
340  *
341  * On P/Q/R/S, the switch tries to say whether a FDB entry
342  * is statically programmed or dynamically learned via a flag called LOCKEDS.
343  * The hardware manual says about this fiels:
344  *
345  *   On write will specify the format of ENTRY.
346  *   On read the flag will be found cleared at times the VALID flag is found
347  *   set.  The flag will also be found cleared in response to a read having the
348  *   MGMTROUTE flag set.  In response to a read with the MGMTROUTE flag
349  *   cleared, the flag be set if the most recent access operated on an entry
350  *   that was either loaded by configuration or through dynamic reconfiguration
351  *   (as opposed to automatically learned entries).
352  *
353  * The trouble with this flag is that it's part of the *command* to access the
354  * dynamic interface, and not part of the *entry* retrieved from it.
355  * Otherwise said, for a sja1105_dynamic_config_read, LOCKEDS is supposed to be
356  * an output from the switch into the command buffer, and for a
357  * sja1105_dynamic_config_write, the switch treats LOCKEDS as an input
358  * (hence we can write either static, or automatically learned entries, from
359  * the core).
360  * But the manual contradicts itself in the last phrase where it says that on
361  * read, LOCKEDS will be set to 1 for all FDB entries written through the
362  * dynamic interface (therefore, the value of LOCKEDS from the
363  * sja1105_dynamic_config_write is not really used for anything, it'll store a
364  * 1 anyway).
365  * This means you can't really write a FDB entry with LOCKEDS=0 (automatically
366  * learned) into the switch, which kind of makes sense.
367  * As for reading through the dynamic interface, it doesn't make too much sense
368  * to put LOCKEDS into the command, since the switch will inevitably have to
369  * ignore it (otherwise a command would be like "read the FDB entry 123, but
370  * only if it's dynamically learned" <- well how am I supposed to know?) and
371  * just use it as an output buffer for its findings. But guess what... that's
372  * what the entry buffer is for!
373  * Unfortunately, what really breaks this abstraction is the fact that it
374  * wasn't designed having the fact in mind that the switch can output
375  * entry-related data as writeback through the command buffer.
376  * However, whether a FDB entry is statically or dynamically learned *is* part
377  * of the entry and not the command data, no matter what the switch thinks.
378  * In order to do that, we'll need to wrap around the
379  * sja1105pqrs_l2_lookup_entry_packing from sja1105_static_config.c, and take
380  * a peek outside of the caller-supplied @buf (the entry buffer), to reach the
381  * command buffer.
382  */
383 static size_t
384 sja1105pqrs_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
385                                         enum packing_op op)
386 {
387         struct sja1105_l2_lookup_entry *entry = entry_ptr;
388         u8 *cmd = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
389         const int size = SJA1105_SIZE_DYN_CMD;
390
391         sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
392
393         return sja1105pqrs_l2_lookup_entry_packing(buf, entry_ptr, op);
394 }
395
396 static size_t sja1110_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
397                                                   enum packing_op op)
398 {
399         struct sja1105_l2_lookup_entry *entry = entry_ptr;
400         u8 *cmd = buf + SJA1110_SIZE_L2_LOOKUP_ENTRY;
401         const int size = SJA1105_SIZE_DYN_CMD;
402
403         sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
404
405         return sja1110_l2_lookup_entry_packing(buf, entry_ptr, op);
406 }
407
408 static void
409 sja1105et_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
410                                 enum packing_op op)
411 {
412         u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
413         const int size = SJA1105_SIZE_DYN_CMD;
414
415         sja1105_packing(p, &cmd->valid,    31, 31, size, op);
416         sja1105_packing(p, &cmd->rdwrset,  30, 30, size, op);
417         sja1105_packing(p, &cmd->errors,   29, 29, size, op);
418         sja1105_packing(p, &cmd->valident, 27, 27, size, op);
419         /* Hack - see comments above. */
420         sja1105_packing(buf, &cmd->index, 29, 20,
421                         SJA1105ET_SIZE_L2_LOOKUP_ENTRY, op);
422 }
423
424 static size_t sja1105et_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
425                                                     enum packing_op op)
426 {
427         struct sja1105_l2_lookup_entry *entry = entry_ptr;
428         u8 *cmd = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
429         const int size = SJA1105_SIZE_DYN_CMD;
430
431         sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
432
433         return sja1105et_l2_lookup_entry_packing(buf, entry_ptr, op);
434 }
435
436 static void
437 sja1105et_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
438                                  enum packing_op op)
439 {
440         u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
441         u64 mgmtroute = 1;
442
443         sja1105et_l2_lookup_cmd_packing(buf, cmd, op);
444         if (op == PACK)
445                 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD);
446 }
447
448 static size_t sja1105et_mgmt_route_entry_packing(void *buf, void *entry_ptr,
449                                                  enum packing_op op)
450 {
451         struct sja1105_mgmt_entry *entry = entry_ptr;
452         const size_t size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
453
454         /* UM10944: To specify if a PTP egress timestamp shall be captured on
455          * each port upon transmission of the frame, the LSB of VLANID in the
456          * ENTRY field provided by the host must be set.
457          * Bit 1 of VLANID then specifies the register where the timestamp for
458          * this port is stored in.
459          */
460         sja1105_packing(buf, &entry->tsreg,     85, 85, size, op);
461         sja1105_packing(buf, &entry->takets,    84, 84, size, op);
462         sja1105_packing(buf, &entry->macaddr,   83, 36, size, op);
463         sja1105_packing(buf, &entry->destports, 35, 31, size, op);
464         sja1105_packing(buf, &entry->enfport,   30, 30, size, op);
465         return size;
466 }
467
468 static void
469 sja1105pqrs_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
470                                    enum packing_op op)
471 {
472         u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
473         u64 mgmtroute = 1;
474
475         sja1105pqrs_l2_lookup_cmd_packing(buf, cmd, op);
476         if (op == PACK)
477                 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD);
478 }
479
480 static size_t sja1105pqrs_mgmt_route_entry_packing(void *buf, void *entry_ptr,
481                                                    enum packing_op op)
482 {
483         const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
484         struct sja1105_mgmt_entry *entry = entry_ptr;
485
486         /* In P/Q/R/S, enfport got renamed to mgmtvalid, but its purpose
487          * is the same (driver uses it to confirm that frame was sent).
488          * So just keep the name from E/T.
489          */
490         sja1105_packing(buf, &entry->tsreg,     71, 71, size, op);
491         sja1105_packing(buf, &entry->takets,    70, 70, size, op);
492         sja1105_packing(buf, &entry->macaddr,   69, 22, size, op);
493         sja1105_packing(buf, &entry->destports, 21, 17, size, op);
494         sja1105_packing(buf, &entry->enfport,   16, 16, size, op);
495         return size;
496 }
497
498 /* In E/T, entry is at addresses 0x27-0x28. There is a 4 byte gap at 0x29,
499  * and command is at 0x2a. Similarly in P/Q/R/S there is a 1 register gap
500  * between entry (0x2d, 0x2e) and command (0x30).
501  */
502 static void
503 sja1105_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
504                                 enum packing_op op)
505 {
506         u8 *p = buf + SJA1105_SIZE_VLAN_LOOKUP_ENTRY + 4;
507         const int size = SJA1105_SIZE_DYN_CMD;
508
509         sja1105_packing(p, &cmd->valid,    31, 31, size, op);
510         sja1105_packing(p, &cmd->rdwrset,  30, 30, size, op);
511         sja1105_packing(p, &cmd->valident, 27, 27, size, op);
512         /* Hack - see comments above, applied for 'vlanid' field of
513          * struct sja1105_vlan_lookup_entry.
514          */
515         sja1105_packing(buf, &cmd->index, 38, 27,
516                         SJA1105_SIZE_VLAN_LOOKUP_ENTRY, op);
517 }
518
519 /* In SJA1110 there is no gap between the command and the data, yay... */
520 static void
521 sja1110_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
522                                 enum packing_op op)
523 {
524         u8 *p = buf + SJA1110_SIZE_VLAN_LOOKUP_ENTRY;
525         const int size = SJA1105_SIZE_DYN_CMD;
526         u64 type_entry = 0;
527
528         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
529         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
530         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
531         /* Hack: treat 'vlanid' field of struct sja1105_vlan_lookup_entry as
532          * cmd->index.
533          */
534         sja1105_packing(buf, &cmd->index, 38, 27,
535                         SJA1110_SIZE_VLAN_LOOKUP_ENTRY, op);
536
537         /* But the VALIDENT bit has disappeared, now we are supposed to
538          * invalidate an entry through the TYPE_ENTRY field of the entry..
539          * This is a hack to transform the non-zero quality of the TYPE_ENTRY
540          * field into a VALIDENT bit.
541          */
542         if (op == PACK && !cmd->valident) {
543                 sja1105_packing(buf, &type_entry, 40, 39,
544                                 SJA1110_SIZE_VLAN_LOOKUP_ENTRY, PACK);
545         } else if (op == UNPACK) {
546                 sja1105_packing(buf, &type_entry, 40, 39,
547                                 SJA1110_SIZE_VLAN_LOOKUP_ENTRY, UNPACK);
548                 cmd->valident = !!type_entry;
549         }
550 }
551
552 static void
553 sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
554                                   enum packing_op op)
555 {
556         u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY;
557         const int size = SJA1105_SIZE_DYN_CMD;
558
559         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
560         sja1105_packing(p, &cmd->errors,  30, 30, size, op);
561         sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
562         sja1105_packing(p, &cmd->index,    4,  0, size, op);
563 }
564
565 static void
566 sja1110_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
567                                   enum packing_op op)
568 {
569         u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY;
570         const int size = SJA1105_SIZE_DYN_CMD;
571
572         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
573         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
574         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
575         sja1105_packing(p, &cmd->index,    4,  0, size, op);
576 }
577
578 static void
579 sja1105et_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
580                                  enum packing_op op)
581 {
582         const int size = SJA1105_SIZE_DYN_CMD;
583         /* Yup, user manual definitions are reversed */
584         u8 *reg1 = buf + 4;
585
586         sja1105_packing(reg1, &cmd->valid, 31, 31, size, op);
587         sja1105_packing(reg1, &cmd->index, 26, 24, size, op);
588 }
589
590 static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr,
591                                                  enum packing_op op)
592 {
593         const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY;
594         struct sja1105_mac_config_entry *entry = entry_ptr;
595         /* Yup, user manual definitions are reversed */
596         u8 *reg1 = buf + 4;
597         u8 *reg2 = buf;
598
599         sja1105_packing(reg1, &entry->speed,     30, 29, size, op);
600         sja1105_packing(reg1, &entry->drpdtag,   23, 23, size, op);
601         sja1105_packing(reg1, &entry->drpuntag,  22, 22, size, op);
602         sja1105_packing(reg1, &entry->retag,     21, 21, size, op);
603         sja1105_packing(reg1, &entry->dyn_learn, 20, 20, size, op);
604         sja1105_packing(reg1, &entry->egress,    19, 19, size, op);
605         sja1105_packing(reg1, &entry->ingress,   18, 18, size, op);
606         sja1105_packing(reg1, &entry->ing_mirr,  17, 17, size, op);
607         sja1105_packing(reg1, &entry->egr_mirr,  16, 16, size, op);
608         sja1105_packing(reg1, &entry->vlanprio,  14, 12, size, op);
609         sja1105_packing(reg1, &entry->vlanid,    11,  0, size, op);
610         sja1105_packing(reg2, &entry->tp_delin,  31, 16, size, op);
611         sja1105_packing(reg2, &entry->tp_delout, 15,  0, size, op);
612         /* MAC configuration table entries which can't be reconfigured:
613          * top, base, enabled, ifg, maxage, drpnona664
614          */
615         /* Bogus return value, not used anywhere */
616         return 0;
617 }
618
619 static void
620 sja1105pqrs_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
621                                    enum packing_op op)
622 {
623         const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY;
624         u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
625
626         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
627         sja1105_packing(p, &cmd->errors,  30, 30, size, op);
628         sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
629         sja1105_packing(p, &cmd->index,    2,  0, size, op);
630 }
631
632 static void
633 sja1110_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
634                                enum packing_op op)
635 {
636         u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
637         const int size = SJA1105_SIZE_DYN_CMD;
638
639         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
640         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
641         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
642         sja1105_packing(p, &cmd->index,    3,  0, size, op);
643 }
644
645 static void
646 sja1105et_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
647                                        enum packing_op op)
648 {
649         sja1105_packing(buf, &cmd->valid, 31, 31,
650                         SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op);
651 }
652
653 static size_t
654 sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,
655                                          enum packing_op op)
656 {
657         struct sja1105_l2_lookup_params_entry *entry = entry_ptr;
658
659         sja1105_packing(buf, &entry->poly, 7, 0,
660                         SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op);
661         /* Bogus return value, not used anywhere */
662         return 0;
663 }
664
665 static void
666 sja1105pqrs_l2_lookup_params_cmd_packing(void *buf,
667                                          struct sja1105_dyn_cmd *cmd,
668                                          enum packing_op op)
669 {
670         u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY;
671         const int size = SJA1105_SIZE_DYN_CMD;
672
673         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
674         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
675 }
676
677 static void
678 sja1110_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
679                                      enum packing_op op)
680 {
681         u8 *p = buf + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY;
682         const int size = SJA1105_SIZE_DYN_CMD;
683
684         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
685         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
686         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
687 }
688
689 static void
690 sja1105et_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
691                                      enum packing_op op)
692 {
693         const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD;
694
695         sja1105_packing(buf, &cmd->valid,  31, 31, size, op);
696         sja1105_packing(buf, &cmd->errors, 30, 30, size, op);
697 }
698
699 static size_t
700 sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
701                                        enum packing_op op)
702 {
703         struct sja1105_general_params_entry *entry = entry_ptr;
704         const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD;
705
706         sja1105_packing(buf, &entry->mirr_port, 2, 0, size, op);
707         /* Bogus return value, not used anywhere */
708         return 0;
709 }
710
711 static void
712 sja1105pqrs_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
713                                        enum packing_op op)
714 {
715         u8 *p = buf + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY;
716         const int size = SJA1105_SIZE_DYN_CMD;
717
718         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
719         sja1105_packing(p, &cmd->errors,  30, 30, size, op);
720         sja1105_packing(p, &cmd->rdwrset, 28, 28, size, op);
721 }
722
723 static void
724 sja1110_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
725                                    enum packing_op op)
726 {
727         u8 *p = buf + SJA1110_SIZE_GENERAL_PARAMS_ENTRY;
728         const int size = SJA1105_SIZE_DYN_CMD;
729
730         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
731         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
732         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
733 }
734
735 static void
736 sja1105pqrs_avb_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
737                                    enum packing_op op)
738 {
739         u8 *p = buf + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY;
740         const int size = SJA1105_SIZE_DYN_CMD;
741
742         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
743         sja1105_packing(p, &cmd->errors,  30, 30, size, op);
744         sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
745 }
746
747 static void
748 sja1105_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
749                               enum packing_op op)
750 {
751         u8 *p = buf + SJA1105_SIZE_RETAGGING_ENTRY;
752         const int size = SJA1105_SIZE_DYN_CMD;
753
754         sja1105_packing(p, &cmd->valid,    31, 31, size, op);
755         sja1105_packing(p, &cmd->errors,   30, 30, size, op);
756         sja1105_packing(p, &cmd->valident, 29, 29, size, op);
757         sja1105_packing(p, &cmd->rdwrset,  28, 28, size, op);
758         sja1105_packing(p, &cmd->index,     5,  0, size, op);
759 }
760
761 static void
762 sja1110_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
763                               enum packing_op op)
764 {
765         u8 *p = buf + SJA1105_SIZE_RETAGGING_ENTRY;
766         const int size = SJA1105_SIZE_DYN_CMD;
767
768         sja1105_packing(p, &cmd->valid,    31, 31, size, op);
769         sja1105_packing(p, &cmd->rdwrset,  30, 30, size, op);
770         sja1105_packing(p, &cmd->errors,   29, 29, size, op);
771         sja1105_packing(p, &cmd->valident, 28, 28, size, op);
772         sja1105_packing(p, &cmd->index,     4,  0, size, op);
773 }
774
775 static void sja1105et_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
776                                       enum packing_op op)
777 {
778         u8 *p = buf + SJA1105ET_SIZE_CBS_ENTRY;
779         const int size = SJA1105_SIZE_DYN_CMD;
780
781         sja1105_packing(p, &cmd->valid, 31, 31, size, op);
782         sja1105_packing(p, &cmd->index, 19, 16, size, op);
783 }
784
785 static size_t sja1105et_cbs_entry_packing(void *buf, void *entry_ptr,
786                                           enum packing_op op)
787 {
788         const size_t size = SJA1105ET_SIZE_CBS_ENTRY;
789         struct sja1105_cbs_entry *entry = entry_ptr;
790         u8 *cmd = buf + size;
791         u32 *p = buf;
792
793         sja1105_packing(cmd, &entry->port, 5, 3, SJA1105_SIZE_DYN_CMD, op);
794         sja1105_packing(cmd, &entry->prio, 2, 0, SJA1105_SIZE_DYN_CMD, op);
795         sja1105_packing(p + 3, &entry->credit_lo,  31, 0, size, op);
796         sja1105_packing(p + 2, &entry->credit_hi,  31, 0, size, op);
797         sja1105_packing(p + 1, &entry->send_slope, 31, 0, size, op);
798         sja1105_packing(p + 0, &entry->idle_slope, 31, 0, size, op);
799         return size;
800 }
801
802 static void sja1105pqrs_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
803                                         enum packing_op op)
804 {
805         u8 *p = buf + SJA1105PQRS_SIZE_CBS_ENTRY;
806         const int size = SJA1105_SIZE_DYN_CMD;
807
808         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
809         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
810         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
811         sja1105_packing(p, &cmd->index,    3,  0, size, op);
812 }
813
814 static void sja1110_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
815                                     enum packing_op op)
816 {
817         u8 *p = buf + SJA1105PQRS_SIZE_CBS_ENTRY;
818         const int size = SJA1105_SIZE_DYN_CMD;
819
820         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
821         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
822         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
823         sja1105_packing(p, &cmd->index,    7,  0, size, op);
824 }
825
826 static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr,
827                                             enum packing_op op)
828 {
829         const size_t size = SJA1105PQRS_SIZE_CBS_ENTRY;
830         struct sja1105_cbs_entry *entry = entry_ptr;
831
832         sja1105_packing(buf, &entry->port,      159, 157, size, op);
833         sja1105_packing(buf, &entry->prio,      156, 154, size, op);
834         sja1105_packing(buf, &entry->credit_lo, 153, 122, size, op);
835         sja1105_packing(buf, &entry->credit_hi, 121,  90, size, op);
836         sja1105_packing(buf, &entry->send_slope, 89,  58, size, op);
837         sja1105_packing(buf, &entry->idle_slope, 57,  26, size, op);
838         return size;
839 }
840
841 static size_t sja1110_cbs_entry_packing(void *buf, void *entry_ptr,
842                                         enum packing_op op)
843 {
844         const size_t size = SJA1105PQRS_SIZE_CBS_ENTRY;
845         struct sja1105_cbs_entry *entry = entry_ptr;
846         u64 entry_type = SJA1110_CBS_SHAPER;
847
848         sja1105_packing(buf, &entry_type,       159, 159, size, op);
849         sja1105_packing(buf, &entry->credit_lo, 151, 120, size, op);
850         sja1105_packing(buf, &entry->credit_hi, 119,  88, size, op);
851         sja1105_packing(buf, &entry->send_slope, 87,  56, size, op);
852         sja1105_packing(buf, &entry->idle_slope, 55,  24, size, op);
853         return size;
854 }
855
856 static void sja1110_dummy_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
857                                       enum packing_op op)
858 {
859 }
860
861 static void
862 sja1110_l2_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
863                                 enum packing_op op)
864 {
865         u8 *p = buf + SJA1105_SIZE_L2_POLICING_ENTRY;
866         const int size = SJA1105_SIZE_DYN_CMD;
867
868         sja1105_packing(p, &cmd->valid,   31, 31, size, op);
869         sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
870         sja1105_packing(p, &cmd->errors,  29, 29, size, op);
871         sja1105_packing(p, &cmd->index,    6,  0, size, op);
872 }
873
874 #define OP_READ         BIT(0)
875 #define OP_WRITE        BIT(1)
876 #define OP_DEL          BIT(2)
877 #define OP_SEARCH       BIT(3)
878 #define OP_VALID_ANYWAY BIT(4)
879
880 /* SJA1105E/T: First generation */
881 const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
882         [BLK_IDX_VL_LOOKUP] = {
883                 .entry_packing = sja1105et_vl_lookup_entry_packing,
884                 .cmd_packing = sja1105et_vl_lookup_cmd_packing,
885                 .access = OP_WRITE,
886                 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
887                 .packed_size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD,
888                 .addr = 0x35,
889         },
890         [BLK_IDX_L2_LOOKUP] = {
891                 .entry_packing = sja1105et_dyn_l2_lookup_entry_packing,
892                 .cmd_packing = sja1105et_l2_lookup_cmd_packing,
893                 .access = (OP_READ | OP_WRITE | OP_DEL),
894                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
895                 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
896                 .addr = 0x20,
897         },
898         [BLK_IDX_MGMT_ROUTE] = {
899                 .entry_packing = sja1105et_mgmt_route_entry_packing,
900                 .cmd_packing = sja1105et_mgmt_route_cmd_packing,
901                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
902                 .max_entry_count = SJA1105_NUM_PORTS,
903                 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
904                 .addr = 0x20,
905         },
906         [BLK_IDX_VLAN_LOOKUP] = {
907                 .entry_packing = sja1105_vlan_lookup_entry_packing,
908                 .cmd_packing = sja1105_vlan_lookup_cmd_packing,
909                 .access = (OP_WRITE | OP_DEL),
910                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
911                 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD,
912                 .addr = 0x27,
913         },
914         [BLK_IDX_L2_FORWARDING] = {
915                 .entry_packing = sja1105_l2_forwarding_entry_packing,
916                 .cmd_packing = sja1105_l2_forwarding_cmd_packing,
917                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
918                 .access = OP_WRITE,
919                 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD,
920                 .addr = 0x24,
921         },
922         [BLK_IDX_MAC_CONFIG] = {
923                 .entry_packing = sja1105et_mac_config_entry_packing,
924                 .cmd_packing = sja1105et_mac_config_cmd_packing,
925                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
926                 .access = OP_WRITE,
927                 .packed_size = SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD,
928                 .addr = 0x36,
929         },
930         [BLK_IDX_L2_LOOKUP_PARAMS] = {
931                 .entry_packing = sja1105et_l2_lookup_params_entry_packing,
932                 .cmd_packing = sja1105et_l2_lookup_params_cmd_packing,
933                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
934                 .access = OP_WRITE,
935                 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
936                 .addr = 0x38,
937         },
938         [BLK_IDX_GENERAL_PARAMS] = {
939                 .entry_packing = sja1105et_general_params_entry_packing,
940                 .cmd_packing = sja1105et_general_params_cmd_packing,
941                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
942                 .access = OP_WRITE,
943                 .packed_size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD,
944                 .addr = 0x34,
945         },
946         [BLK_IDX_RETAGGING] = {
947                 .entry_packing = sja1105_retagging_entry_packing,
948                 .cmd_packing = sja1105_retagging_cmd_packing,
949                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
950                 .access = (OP_WRITE | OP_DEL),
951                 .packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD,
952                 .addr = 0x31,
953         },
954         [BLK_IDX_CBS] = {
955                 .entry_packing = sja1105et_cbs_entry_packing,
956                 .cmd_packing = sja1105et_cbs_cmd_packing,
957                 .max_entry_count = SJA1105ET_MAX_CBS_COUNT,
958                 .access = OP_WRITE,
959                 .packed_size = SJA1105ET_SIZE_CBS_DYN_CMD,
960                 .addr = 0x2c,
961         },
962 };
963
964 /* SJA1105P/Q/R/S: Second generation */
965 const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
966         [BLK_IDX_VL_LOOKUP] = {
967                 .entry_packing = sja1105_vl_lookup_entry_packing,
968                 .cmd_packing = sja1105pqrs_vl_lookup_cmd_packing,
969                 .access = (OP_READ | OP_WRITE),
970                 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
971                 .packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD,
972                 .addr = 0x47,
973         },
974         [BLK_IDX_L2_LOOKUP] = {
975                 .entry_packing = sja1105pqrs_dyn_l2_lookup_entry_packing,
976                 .cmd_packing = sja1105pqrs_l2_lookup_cmd_packing,
977                 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH),
978                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
979                 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
980                 .addr = 0x24,
981         },
982         [BLK_IDX_MGMT_ROUTE] = {
983                 .entry_packing = sja1105pqrs_mgmt_route_entry_packing,
984                 .cmd_packing = sja1105pqrs_mgmt_route_cmd_packing,
985                 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH | OP_VALID_ANYWAY),
986                 .max_entry_count = SJA1105_NUM_PORTS,
987                 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
988                 .addr = 0x24,
989         },
990         [BLK_IDX_VLAN_LOOKUP] = {
991                 .entry_packing = sja1105_vlan_lookup_entry_packing,
992                 .cmd_packing = sja1105_vlan_lookup_cmd_packing,
993                 .access = (OP_READ | OP_WRITE | OP_DEL),
994                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
995                 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD,
996                 .addr = 0x2D,
997         },
998         [BLK_IDX_L2_FORWARDING] = {
999                 .entry_packing = sja1105_l2_forwarding_entry_packing,
1000                 .cmd_packing = sja1105_l2_forwarding_cmd_packing,
1001                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
1002                 .access = OP_WRITE,
1003                 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD,
1004                 .addr = 0x2A,
1005         },
1006         [BLK_IDX_MAC_CONFIG] = {
1007                 .entry_packing = sja1105pqrs_mac_config_entry_packing,
1008                 .cmd_packing = sja1105pqrs_mac_config_cmd_packing,
1009                 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
1010                 .access = (OP_READ | OP_WRITE),
1011                 .packed_size = SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD,
1012                 .addr = 0x4B,
1013         },
1014         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1015                 .entry_packing = sja1105pqrs_l2_lookup_params_entry_packing,
1016                 .cmd_packing = sja1105pqrs_l2_lookup_params_cmd_packing,
1017                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1018                 .access = (OP_READ | OP_WRITE),
1019                 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
1020                 .addr = 0x54,
1021         },
1022         [BLK_IDX_AVB_PARAMS] = {
1023                 .entry_packing = sja1105pqrs_avb_params_entry_packing,
1024                 .cmd_packing = sja1105pqrs_avb_params_cmd_packing,
1025                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1026                 .access = (OP_READ | OP_WRITE),
1027                 .packed_size = SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD,
1028                 .addr = 0x8003,
1029         },
1030         [BLK_IDX_GENERAL_PARAMS] = {
1031                 .entry_packing = sja1105pqrs_general_params_entry_packing,
1032                 .cmd_packing = sja1105pqrs_general_params_cmd_packing,
1033                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1034                 .access = (OP_READ | OP_WRITE),
1035                 .packed_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD,
1036                 .addr = 0x3B,
1037         },
1038         [BLK_IDX_RETAGGING] = {
1039                 .entry_packing = sja1105_retagging_entry_packing,
1040                 .cmd_packing = sja1105_retagging_cmd_packing,
1041                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1042                 .access = (OP_READ | OP_WRITE | OP_DEL),
1043                 .packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD,
1044                 .addr = 0x38,
1045         },
1046         [BLK_IDX_CBS] = {
1047                 .entry_packing = sja1105pqrs_cbs_entry_packing,
1048                 .cmd_packing = sja1105pqrs_cbs_cmd_packing,
1049                 .max_entry_count = SJA1105PQRS_MAX_CBS_COUNT,
1050                 .access = OP_WRITE,
1051                 .packed_size = SJA1105PQRS_SIZE_CBS_DYN_CMD,
1052                 .addr = 0x32,
1053         },
1054 };
1055
1056 /* SJA1110: Third generation */
1057 const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = {
1058         [BLK_IDX_VL_LOOKUP] = {
1059                 .entry_packing = sja1110_vl_lookup_entry_packing,
1060                 .cmd_packing = sja1110_vl_lookup_cmd_packing,
1061                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1062                 .max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT,
1063                 .packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD,
1064                 .addr = SJA1110_SPI_ADDR(0x124),
1065         },
1066         [BLK_IDX_VL_POLICING] = {
1067                 .entry_packing = sja1110_vl_policing_entry_packing,
1068                 .cmd_packing = sja1110_vl_policing_cmd_packing,
1069                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1070                 .max_entry_count = SJA1110_MAX_VL_POLICING_COUNT,
1071                 .packed_size = SJA1110_SIZE_VL_POLICING_DYN_CMD,
1072                 .addr = SJA1110_SPI_ADDR(0x310),
1073         },
1074         [BLK_IDX_L2_LOOKUP] = {
1075                 .entry_packing = sja1110_dyn_l2_lookup_entry_packing,
1076                 .cmd_packing = sja1110_l2_lookup_cmd_packing,
1077                 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH),
1078                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
1079                 .packed_size = SJA1110_SIZE_L2_LOOKUP_DYN_CMD,
1080                 .addr = SJA1110_SPI_ADDR(0x8c),
1081         },
1082         [BLK_IDX_VLAN_LOOKUP] = {
1083                 .entry_packing = sja1110_vlan_lookup_entry_packing,
1084                 .cmd_packing = sja1110_vlan_lookup_cmd_packing,
1085                 .access = (OP_READ | OP_WRITE | OP_DEL),
1086                 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
1087                 .packed_size = SJA1110_SIZE_VLAN_LOOKUP_DYN_CMD,
1088                 .addr = SJA1110_SPI_ADDR(0xb4),
1089         },
1090         [BLK_IDX_L2_FORWARDING] = {
1091                 .entry_packing = sja1110_l2_forwarding_entry_packing,
1092                 .cmd_packing = sja1110_l2_forwarding_cmd_packing,
1093                 .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT,
1094                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1095                 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD,
1096                 .addr = SJA1110_SPI_ADDR(0xa8),
1097         },
1098         [BLK_IDX_MAC_CONFIG] = {
1099                 .entry_packing = sja1110_mac_config_entry_packing,
1100                 .cmd_packing = sja1110_mac_config_cmd_packing,
1101                 .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT,
1102                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1103                 .packed_size = SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD,
1104                 .addr = SJA1110_SPI_ADDR(0x134),
1105         },
1106         [BLK_IDX_L2_LOOKUP_PARAMS] = {
1107                 .entry_packing = sja1110_l2_lookup_params_entry_packing,
1108                 .cmd_packing = sja1110_l2_lookup_params_cmd_packing,
1109                 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
1110                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1111                 .packed_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
1112                 .addr = SJA1110_SPI_ADDR(0x158),
1113         },
1114         [BLK_IDX_AVB_PARAMS] = {
1115                 .entry_packing = sja1105pqrs_avb_params_entry_packing,
1116                 .cmd_packing = sja1105pqrs_avb_params_cmd_packing,
1117                 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT,
1118                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1119                 .packed_size = SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD,
1120                 .addr = SJA1110_SPI_ADDR(0x2000C),
1121         },
1122         [BLK_IDX_GENERAL_PARAMS] = {
1123                 .entry_packing = sja1110_general_params_entry_packing,
1124                 .cmd_packing = sja1110_general_params_cmd_packing,
1125                 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
1126                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1127                 .packed_size = SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD,
1128                 .addr = SJA1110_SPI_ADDR(0xe8),
1129         },
1130         [BLK_IDX_RETAGGING] = {
1131                 .entry_packing = sja1110_retagging_entry_packing,
1132                 .cmd_packing = sja1110_retagging_cmd_packing,
1133                 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
1134                 .access = (OP_READ | OP_WRITE | OP_DEL),
1135                 .packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD,
1136                 .addr = SJA1110_SPI_ADDR(0xdc),
1137         },
1138         [BLK_IDX_CBS] = {
1139                 .entry_packing = sja1110_cbs_entry_packing,
1140                 .cmd_packing = sja1110_cbs_cmd_packing,
1141                 .max_entry_count = SJA1110_MAX_CBS_COUNT,
1142                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1143                 .packed_size = SJA1105PQRS_SIZE_CBS_DYN_CMD,
1144                 .addr = SJA1110_SPI_ADDR(0xc4),
1145         },
1146         [BLK_IDX_XMII_PARAMS] = {
1147                 .entry_packing = sja1110_xmii_params_entry_packing,
1148                 .cmd_packing = sja1110_dummy_cmd_packing,
1149                 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT,
1150                 .access = (OP_READ | OP_VALID_ANYWAY),
1151                 .packed_size = SJA1110_SIZE_XMII_PARAMS_DYN_CMD,
1152                 .addr = SJA1110_SPI_ADDR(0x3c),
1153         },
1154         [BLK_IDX_L2_POLICING] = {
1155                 .entry_packing = sja1110_l2_policing_entry_packing,
1156                 .cmd_packing = sja1110_l2_policing_cmd_packing,
1157                 .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT,
1158                 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
1159                 .packed_size = SJA1110_SIZE_L2_POLICING_DYN_CMD,
1160                 .addr = SJA1110_SPI_ADDR(0x2fc),
1161         },
1162         [BLK_IDX_L2_FORWARDING_PARAMS] = {
1163                 .entry_packing = sja1110_l2_forwarding_params_entry_packing,
1164                 .cmd_packing = sja1110_dummy_cmd_packing,
1165                 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT,
1166                 .access = (OP_READ | OP_VALID_ANYWAY),
1167                 .packed_size = SJA1110_SIZE_L2_FORWARDING_PARAMS_DYN_CMD,
1168                 .addr = SJA1110_SPI_ADDR(0x20000),
1169         },
1170 };
1171
1172 /* Provides read access to the settings through the dynamic interface
1173  * of the switch.
1174  * @blk_idx     is used as key to select from the sja1105_dynamic_table_ops.
1175  *              The selection is limited by the hardware in respect to which
1176  *              configuration blocks can be read through the dynamic interface.
1177  * @index       is used to retrieve a particular table entry. If negative,
1178  *              (and if the @blk_idx supports the searching operation) a search
1179  *              is performed by the @entry parameter.
1180  * @entry       Type-casted to an unpacked structure that holds a table entry
1181  *              of the type specified in @blk_idx.
1182  *              Usually an output argument. If @index is negative, then this
1183  *              argument is used as input/output: it should be pre-populated
1184  *              with the element to search for. Entries which support the
1185  *              search operation will have an "index" field (not the @index
1186  *              argument to this function) and that is where the found index
1187  *              will be returned (or left unmodified - thus negative - if not
1188  *              found).
1189  */
1190 int sja1105_dynamic_config_read(struct sja1105_private *priv,
1191                                 enum sja1105_blk_idx blk_idx,
1192                                 int index, void *entry)
1193 {
1194         const struct sja1105_dynamic_table_ops *ops;
1195         struct sja1105_dyn_cmd cmd = {0};
1196         /* SPI payload buffer */
1197         u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0};
1198         int retries = 3;
1199         int rc;
1200
1201         if (blk_idx >= BLK_IDX_MAX_DYN)
1202                 return -ERANGE;
1203
1204         ops = &priv->info->dyn_ops[blk_idx];
1205
1206         if (index >= 0 && index >= ops->max_entry_count)
1207                 return -ERANGE;
1208         if (index < 0 && !(ops->access & OP_SEARCH))
1209                 return -EOPNOTSUPP;
1210         if (!(ops->access & OP_READ))
1211                 return -EOPNOTSUPP;
1212         if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE)
1213                 return -ERANGE;
1214         if (!ops->cmd_packing)
1215                 return -EOPNOTSUPP;
1216         if (!ops->entry_packing)
1217                 return -EOPNOTSUPP;
1218
1219         cmd.valid = true; /* Trigger action on table entry */
1220         cmd.rdwrset = SPI_READ; /* Action is read */
1221         if (index < 0) {
1222                 /* Avoid copying a signed negative number to an u64 */
1223                 cmd.index = 0;
1224                 cmd.search = true;
1225         } else {
1226                 cmd.index = index;
1227                 cmd.search = false;
1228         }
1229         cmd.valident = true;
1230         ops->cmd_packing(packed_buf, &cmd, PACK);
1231
1232         if (cmd.search)
1233                 ops->entry_packing(packed_buf, entry, PACK);
1234
1235         /* Send SPI write operation: read config table entry */
1236         rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
1237                               ops->packed_size);
1238         if (rc < 0)
1239                 return rc;
1240
1241         /* Loop until we have confirmation that hardware has finished
1242          * processing the command and has cleared the VALID field
1243          */
1244         do {
1245                 memset(packed_buf, 0, ops->packed_size);
1246
1247                 /* Retrieve the read operation's result */
1248                 rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf,
1249                                       ops->packed_size);
1250                 if (rc < 0)
1251                         return rc;
1252
1253                 cmd = (struct sja1105_dyn_cmd) {0};
1254                 ops->cmd_packing(packed_buf, &cmd, UNPACK);
1255
1256                 if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY))
1257                         return -ENOENT;
1258                 cpu_relax();
1259         } while (cmd.valid && --retries);
1260
1261         if (cmd.valid)
1262                 return -ETIMEDOUT;
1263
1264         /* Don't dereference possibly NULL pointer - maybe caller
1265          * only wanted to see whether the entry existed or not.
1266          */
1267         if (entry)
1268                 ops->entry_packing(packed_buf, entry, UNPACK);
1269         return 0;
1270 }
1271
1272 int sja1105_dynamic_config_write(struct sja1105_private *priv,
1273                                  enum sja1105_blk_idx blk_idx,
1274                                  int index, void *entry, bool keep)
1275 {
1276         const struct sja1105_dynamic_table_ops *ops;
1277         struct sja1105_dyn_cmd cmd = {0};
1278         /* SPI payload buffer */
1279         u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0};
1280         int rc;
1281
1282         if (blk_idx >= BLK_IDX_MAX_DYN)
1283                 return -ERANGE;
1284
1285         ops = &priv->info->dyn_ops[blk_idx];
1286
1287         if (index >= ops->max_entry_count)
1288                 return -ERANGE;
1289         if (index < 0)
1290                 return -ERANGE;
1291         if (!(ops->access & OP_WRITE))
1292                 return -EOPNOTSUPP;
1293         if (!keep && !(ops->access & OP_DEL))
1294                 return -EOPNOTSUPP;
1295         if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE)
1296                 return -ERANGE;
1297
1298         cmd.valident = keep; /* If false, deletes entry */
1299         cmd.valid = true; /* Trigger action on table entry */
1300         cmd.rdwrset = SPI_WRITE; /* Action is write */
1301         cmd.index = index;
1302
1303         if (!ops->cmd_packing)
1304                 return -EOPNOTSUPP;
1305         ops->cmd_packing(packed_buf, &cmd, PACK);
1306
1307         if (!ops->entry_packing)
1308                 return -EOPNOTSUPP;
1309         /* Don't dereference potentially NULL pointer if just
1310          * deleting a table entry is what was requested. For cases
1311          * where 'index' field is physically part of entry structure,
1312          * and needed here, we deal with that in the cmd_packing callback.
1313          */
1314         if (keep)
1315                 ops->entry_packing(packed_buf, entry, PACK);
1316
1317         /* Send SPI write operation: read config table entry */
1318         rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
1319                               ops->packed_size);
1320         if (rc < 0)
1321                 return rc;
1322
1323         cmd = (struct sja1105_dyn_cmd) {0};
1324         ops->cmd_packing(packed_buf, &cmd, UNPACK);
1325         if (cmd.errors)
1326                 return -EINVAL;
1327
1328         return 0;
1329 }
1330
1331 static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly)
1332 {
1333         int i;
1334
1335         for (i = 0; i < 8; i++) {
1336                 if ((crc ^ byte) & (1 << 7)) {
1337                         crc <<= 1;
1338                         crc ^= poly;
1339                 } else {
1340                         crc <<= 1;
1341                 }
1342                 byte <<= 1;
1343         }
1344         return crc;
1345 }
1346
1347 /* CRC8 algorithm with non-reversed input, non-reversed output,
1348  * no input xor and no output xor. Code customized for receiving
1349  * the SJA1105 E/T FDB keys (vlanid, macaddr) as input. CRC polynomial
1350  * is also received as argument in the Koopman notation that the switch
1351  * hardware stores it in.
1352  */
1353 u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid)
1354 {
1355         struct sja1105_l2_lookup_params_entry *l2_lookup_params =
1356                 priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS].entries;
1357         u64 poly_koopman = l2_lookup_params->poly;
1358         /* Convert polynomial from Koopman to 'normal' notation */
1359         u8 poly = (u8)(1 + (poly_koopman << 1));
1360         u64 vlanid = l2_lookup_params->shared_learn ? 0 : vid;
1361         u64 input = (vlanid << 48) | ether_addr_to_u64(addr);
1362         u8 crc = 0; /* seed */
1363         int i;
1364
1365         /* Mask the eight bytes starting from MSB one at a time */
1366         for (i = 56; i >= 0; i -= 8) {
1367                 u8 byte = (input & (0xffull << i)) >> i;
1368
1369                 crc = sja1105_crc8_add(crc, byte, poly);
1370         }
1371         return crc;
1372 }