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