This source file includes following definitions.
- sja1105pqrs_l2_lookup_cmd_packing
- sja1105pqrs_dyn_l2_lookup_entry_packing
- sja1105et_l2_lookup_cmd_packing
- sja1105et_dyn_l2_lookup_entry_packing
- sja1105et_mgmt_route_cmd_packing
- sja1105et_mgmt_route_entry_packing
- sja1105pqrs_mgmt_route_cmd_packing
- sja1105pqrs_mgmt_route_entry_packing
- sja1105_vlan_lookup_cmd_packing
- sja1105_l2_forwarding_cmd_packing
- sja1105et_mac_config_cmd_packing
- sja1105et_mac_config_entry_packing
- sja1105pqrs_mac_config_cmd_packing
- sja1105et_l2_lookup_params_cmd_packing
- sja1105et_l2_lookup_params_entry_packing
- sja1105et_general_params_cmd_packing
- sja1105et_general_params_entry_packing
- sja1105_dynamic_config_read
- sja1105_dynamic_config_write
- sja1105_crc8_add
- sja1105et_fdb_hash
1
2
3
4 #include "sja1105.h"
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 #define SJA1105_SIZE_DYN_CMD 4
99
100 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY \
101 SJA1105_SIZE_DYN_CMD
102
103 #define SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD \
104 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_L2_LOOKUP_ENTRY)
105
106 #define SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD \
107 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY)
108
109 #define SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD \
110 (SJA1105_SIZE_DYN_CMD + 4 + SJA1105_SIZE_VLAN_LOOKUP_ENTRY)
111
112 #define SJA1105_SIZE_L2_FORWARDING_DYN_CMD \
113 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_FORWARDING_ENTRY)
114
115 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD \
116 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY)
117
118 #define SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD \
119 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY)
120
121 #define SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \
122 SJA1105_SIZE_DYN_CMD
123
124 #define SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD \
125 SJA1105_SIZE_DYN_CMD
126
127 #define SJA1105_MAX_DYN_CMD_SIZE \
128 SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD
129
130 struct sja1105_dyn_cmd {
131 bool search;
132 u64 valid;
133 u64 rdwrset;
134 u64 errors;
135 u64 valident;
136 u64 index;
137 };
138
139 enum sja1105_hostcmd {
140 SJA1105_HOSTCMD_SEARCH = 1,
141 SJA1105_HOSTCMD_READ = 2,
142 SJA1105_HOSTCMD_WRITE = 3,
143 SJA1105_HOSTCMD_INVALIDATE = 4,
144 };
145
146 static void
147 sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
148 enum packing_op op)
149 {
150 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
151 const int size = SJA1105_SIZE_DYN_CMD;
152 u64 hostcmd;
153
154 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
155 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
156 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
157 sja1105_packing(p, &cmd->valident, 27, 27, size, op);
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180 if (cmd->rdwrset == SPI_READ) {
181 if (cmd->search)
182 hostcmd = SJA1105_HOSTCMD_SEARCH;
183 else
184 hostcmd = SJA1105_HOSTCMD_READ;
185 } else {
186
187 if (cmd->valident)
188 hostcmd = SJA1105_HOSTCMD_WRITE;
189 else
190 hostcmd = SJA1105_HOSTCMD_INVALIDATE;
191 }
192 sja1105_packing(p, &hostcmd, 25, 23, size, op);
193
194
195
196
197
198
199
200
201
202 sja1105_packing(buf, &cmd->index, 15, 6,
203 SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, op);
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 static size_t
252 sja1105pqrs_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
253 enum packing_op op)
254 {
255 struct sja1105_l2_lookup_entry *entry = entry_ptr;
256 u8 *cmd = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
257 const int size = SJA1105_SIZE_DYN_CMD;
258
259 sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
260
261 return sja1105pqrs_l2_lookup_entry_packing(buf, entry_ptr, op);
262 }
263
264 static void
265 sja1105et_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
266 enum packing_op op)
267 {
268 u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
269 const int size = SJA1105_SIZE_DYN_CMD;
270
271 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
272 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
273 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
274 sja1105_packing(p, &cmd->valident, 27, 27, size, op);
275
276 sja1105_packing(buf, &cmd->index, 29, 20,
277 SJA1105ET_SIZE_L2_LOOKUP_ENTRY, op);
278 }
279
280 static size_t sja1105et_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
281 enum packing_op op)
282 {
283 struct sja1105_l2_lookup_entry *entry = entry_ptr;
284 u8 *cmd = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
285 const int size = SJA1105_SIZE_DYN_CMD;
286
287 sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
288
289 return sja1105et_l2_lookup_entry_packing(buf, entry_ptr, op);
290 }
291
292 static void
293 sja1105et_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
294 enum packing_op op)
295 {
296 u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
297 u64 mgmtroute = 1;
298
299 sja1105et_l2_lookup_cmd_packing(buf, cmd, op);
300 if (op == PACK)
301 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD);
302 }
303
304 static size_t sja1105et_mgmt_route_entry_packing(void *buf, void *entry_ptr,
305 enum packing_op op)
306 {
307 struct sja1105_mgmt_entry *entry = entry_ptr;
308 const size_t size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
309
310
311
312
313
314
315
316 sja1105_packing(buf, &entry->tsreg, 85, 85, size, op);
317 sja1105_packing(buf, &entry->takets, 84, 84, size, op);
318 sja1105_packing(buf, &entry->macaddr, 83, 36, size, op);
319 sja1105_packing(buf, &entry->destports, 35, 31, size, op);
320 sja1105_packing(buf, &entry->enfport, 30, 30, size, op);
321 return size;
322 }
323
324 static void
325 sja1105pqrs_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
326 enum packing_op op)
327 {
328 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
329 u64 mgmtroute = 1;
330
331 sja1105pqrs_l2_lookup_cmd_packing(buf, cmd, op);
332 if (op == PACK)
333 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD);
334 }
335
336 static size_t sja1105pqrs_mgmt_route_entry_packing(void *buf, void *entry_ptr,
337 enum packing_op op)
338 {
339 const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
340 struct sja1105_mgmt_entry *entry = entry_ptr;
341
342
343
344
345
346 sja1105_packing(buf, &entry->tsreg, 71, 71, size, op);
347 sja1105_packing(buf, &entry->takets, 70, 70, size, op);
348 sja1105_packing(buf, &entry->macaddr, 69, 22, size, op);
349 sja1105_packing(buf, &entry->destports, 21, 17, size, op);
350 sja1105_packing(buf, &entry->enfport, 16, 16, size, op);
351 return size;
352 }
353
354
355
356
357
358 static void
359 sja1105_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
360 enum packing_op op)
361 {
362 u8 *p = buf + SJA1105_SIZE_VLAN_LOOKUP_ENTRY + 4;
363 const int size = SJA1105_SIZE_DYN_CMD;
364
365 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
366 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
367 sja1105_packing(p, &cmd->valident, 27, 27, size, op);
368
369
370
371 sja1105_packing(buf, &cmd->index, 38, 27,
372 SJA1105_SIZE_VLAN_LOOKUP_ENTRY, op);
373 }
374
375 static void
376 sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
377 enum packing_op op)
378 {
379 u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY;
380 const int size = SJA1105_SIZE_DYN_CMD;
381
382 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
383 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
384 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
385 sja1105_packing(p, &cmd->index, 4, 0, size, op);
386 }
387
388 static void
389 sja1105et_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
390 enum packing_op op)
391 {
392 const int size = SJA1105_SIZE_DYN_CMD;
393
394 u8 *reg1 = buf + 4;
395
396 sja1105_packing(reg1, &cmd->valid, 31, 31, size, op);
397 sja1105_packing(reg1, &cmd->index, 26, 24, size, op);
398 }
399
400 static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr,
401 enum packing_op op)
402 {
403 const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY;
404 struct sja1105_mac_config_entry *entry = entry_ptr;
405
406 u8 *reg1 = buf + 4;
407 u8 *reg2 = buf;
408
409 sja1105_packing(reg1, &entry->speed, 30, 29, size, op);
410 sja1105_packing(reg1, &entry->drpdtag, 23, 23, size, op);
411 sja1105_packing(reg1, &entry->drpuntag, 22, 22, size, op);
412 sja1105_packing(reg1, &entry->retag, 21, 21, size, op);
413 sja1105_packing(reg1, &entry->dyn_learn, 20, 20, size, op);
414 sja1105_packing(reg1, &entry->egress, 19, 19, size, op);
415 sja1105_packing(reg1, &entry->ingress, 18, 18, size, op);
416 sja1105_packing(reg1, &entry->ing_mirr, 17, 17, size, op);
417 sja1105_packing(reg1, &entry->egr_mirr, 16, 16, size, op);
418 sja1105_packing(reg1, &entry->vlanprio, 14, 12, size, op);
419 sja1105_packing(reg1, &entry->vlanid, 11, 0, size, op);
420 sja1105_packing(reg2, &entry->tp_delin, 31, 16, size, op);
421 sja1105_packing(reg2, &entry->tp_delout, 15, 0, size, op);
422
423
424
425
426 return 0;
427 }
428
429 static void
430 sja1105pqrs_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
431 enum packing_op op)
432 {
433 const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY;
434 u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
435
436 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
437 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
438 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
439 sja1105_packing(p, &cmd->index, 2, 0, size, op);
440 }
441
442 static void
443 sja1105et_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
444 enum packing_op op)
445 {
446 sja1105_packing(buf, &cmd->valid, 31, 31,
447 SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op);
448 }
449
450 static size_t
451 sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,
452 enum packing_op op)
453 {
454 struct sja1105_l2_lookup_params_entry *entry = entry_ptr;
455
456 sja1105_packing(buf, &entry->poly, 7, 0,
457 SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op);
458
459 return 0;
460 }
461
462 static void
463 sja1105et_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
464 enum packing_op op)
465 {
466 const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD;
467
468 sja1105_packing(buf, &cmd->valid, 31, 31, size, op);
469 sja1105_packing(buf, &cmd->errors, 30, 30, size, op);
470 }
471
472 static size_t
473 sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
474 enum packing_op op)
475 {
476 struct sja1105_general_params_entry *entry = entry_ptr;
477 const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD;
478
479 sja1105_packing(buf, &entry->mirr_port, 2, 0, size, op);
480
481 return 0;
482 }
483
484 #define OP_READ BIT(0)
485 #define OP_WRITE BIT(1)
486 #define OP_DEL BIT(2)
487 #define OP_SEARCH BIT(3)
488
489
490 struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
491 [BLK_IDX_SCHEDULE] = {0},
492 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {0},
493 [BLK_IDX_L2_LOOKUP] = {
494 .entry_packing = sja1105et_dyn_l2_lookup_entry_packing,
495 .cmd_packing = sja1105et_l2_lookup_cmd_packing,
496 .access = (OP_READ | OP_WRITE | OP_DEL),
497 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
498 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
499 .addr = 0x20,
500 },
501 [BLK_IDX_MGMT_ROUTE] = {
502 .entry_packing = sja1105et_mgmt_route_entry_packing,
503 .cmd_packing = sja1105et_mgmt_route_cmd_packing,
504 .access = (OP_READ | OP_WRITE),
505 .max_entry_count = SJA1105_NUM_PORTS,
506 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
507 .addr = 0x20,
508 },
509 [BLK_IDX_L2_POLICING] = {0},
510 [BLK_IDX_VLAN_LOOKUP] = {
511 .entry_packing = sja1105_vlan_lookup_entry_packing,
512 .cmd_packing = sja1105_vlan_lookup_cmd_packing,
513 .access = (OP_WRITE | OP_DEL),
514 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
515 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD,
516 .addr = 0x27,
517 },
518 [BLK_IDX_L2_FORWARDING] = {
519 .entry_packing = sja1105_l2_forwarding_entry_packing,
520 .cmd_packing = sja1105_l2_forwarding_cmd_packing,
521 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
522 .access = OP_WRITE,
523 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD,
524 .addr = 0x24,
525 },
526 [BLK_IDX_MAC_CONFIG] = {
527 .entry_packing = sja1105et_mac_config_entry_packing,
528 .cmd_packing = sja1105et_mac_config_cmd_packing,
529 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
530 .access = OP_WRITE,
531 .packed_size = SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD,
532 .addr = 0x36,
533 },
534 [BLK_IDX_SCHEDULE_PARAMS] = {0},
535 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {0},
536 [BLK_IDX_L2_LOOKUP_PARAMS] = {
537 .entry_packing = sja1105et_l2_lookup_params_entry_packing,
538 .cmd_packing = sja1105et_l2_lookup_params_cmd_packing,
539 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
540 .access = OP_WRITE,
541 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
542 .addr = 0x38,
543 },
544 [BLK_IDX_L2_FORWARDING_PARAMS] = {0},
545 [BLK_IDX_AVB_PARAMS] = {0},
546 [BLK_IDX_GENERAL_PARAMS] = {
547 .entry_packing = sja1105et_general_params_entry_packing,
548 .cmd_packing = sja1105et_general_params_cmd_packing,
549 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
550 .access = OP_WRITE,
551 .packed_size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD,
552 .addr = 0x34,
553 },
554 [BLK_IDX_XMII_PARAMS] = {0},
555 };
556
557
558 struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
559 [BLK_IDX_SCHEDULE] = {0},
560 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = {0},
561 [BLK_IDX_L2_LOOKUP] = {
562 .entry_packing = sja1105pqrs_dyn_l2_lookup_entry_packing,
563 .cmd_packing = sja1105pqrs_l2_lookup_cmd_packing,
564 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH),
565 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
566 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
567 .addr = 0x24,
568 },
569 [BLK_IDX_MGMT_ROUTE] = {
570 .entry_packing = sja1105pqrs_mgmt_route_entry_packing,
571 .cmd_packing = sja1105pqrs_mgmt_route_cmd_packing,
572 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH),
573 .max_entry_count = SJA1105_NUM_PORTS,
574 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
575 .addr = 0x24,
576 },
577 [BLK_IDX_L2_POLICING] = {0},
578 [BLK_IDX_VLAN_LOOKUP] = {
579 .entry_packing = sja1105_vlan_lookup_entry_packing,
580 .cmd_packing = sja1105_vlan_lookup_cmd_packing,
581 .access = (OP_READ | OP_WRITE | OP_DEL),
582 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
583 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD,
584 .addr = 0x2D,
585 },
586 [BLK_IDX_L2_FORWARDING] = {
587 .entry_packing = sja1105_l2_forwarding_entry_packing,
588 .cmd_packing = sja1105_l2_forwarding_cmd_packing,
589 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
590 .access = OP_WRITE,
591 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD,
592 .addr = 0x2A,
593 },
594 [BLK_IDX_MAC_CONFIG] = {
595 .entry_packing = sja1105pqrs_mac_config_entry_packing,
596 .cmd_packing = sja1105pqrs_mac_config_cmd_packing,
597 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
598 .access = (OP_READ | OP_WRITE),
599 .packed_size = SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD,
600 .addr = 0x4B,
601 },
602 [BLK_IDX_SCHEDULE_PARAMS] = {0},
603 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = {0},
604 [BLK_IDX_L2_LOOKUP_PARAMS] = {
605 .entry_packing = sja1105et_l2_lookup_params_entry_packing,
606 .cmd_packing = sja1105et_l2_lookup_params_cmd_packing,
607 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
608 .access = (OP_READ | OP_WRITE),
609 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
610 .addr = 0x38,
611 },
612 [BLK_IDX_L2_FORWARDING_PARAMS] = {0},
613 [BLK_IDX_AVB_PARAMS] = {0},
614 [BLK_IDX_GENERAL_PARAMS] = {
615 .entry_packing = sja1105et_general_params_entry_packing,
616 .cmd_packing = sja1105et_general_params_cmd_packing,
617 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
618 .access = OP_WRITE,
619 .packed_size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD,
620 .addr = 0x34,
621 },
622 [BLK_IDX_XMII_PARAMS] = {0},
623 };
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643 int sja1105_dynamic_config_read(struct sja1105_private *priv,
644 enum sja1105_blk_idx blk_idx,
645 int index, void *entry)
646 {
647 const struct sja1105_dynamic_table_ops *ops;
648 struct sja1105_dyn_cmd cmd = {0};
649
650 u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0};
651 int retries = 3;
652 int rc;
653
654 if (blk_idx >= BLK_IDX_MAX_DYN)
655 return -ERANGE;
656
657 ops = &priv->info->dyn_ops[blk_idx];
658
659 if (index >= 0 && index >= ops->max_entry_count)
660 return -ERANGE;
661 if (index < 0 && !(ops->access & OP_SEARCH))
662 return -EOPNOTSUPP;
663 if (!(ops->access & OP_READ))
664 return -EOPNOTSUPP;
665 if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE)
666 return -ERANGE;
667 if (!ops->cmd_packing)
668 return -EOPNOTSUPP;
669 if (!ops->entry_packing)
670 return -EOPNOTSUPP;
671
672 cmd.valid = true;
673 cmd.rdwrset = SPI_READ;
674 if (index < 0) {
675
676 cmd.index = 0;
677 cmd.search = true;
678 } else {
679 cmd.index = index;
680 cmd.search = false;
681 }
682 cmd.valident = true;
683 ops->cmd_packing(packed_buf, &cmd, PACK);
684
685 if (cmd.search)
686 ops->entry_packing(packed_buf, entry, PACK);
687
688
689 rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE, ops->addr,
690 packed_buf, ops->packed_size);
691 if (rc < 0)
692 return rc;
693
694
695
696
697 do {
698 memset(packed_buf, 0, ops->packed_size);
699
700
701 rc = sja1105_spi_send_packed_buf(priv, SPI_READ, ops->addr,
702 packed_buf, ops->packed_size);
703 if (rc < 0)
704 return rc;
705
706 cmd = (struct sja1105_dyn_cmd) {0};
707 ops->cmd_packing(packed_buf, &cmd, UNPACK);
708
709
710
711
712 if (!cmd.valident && blk_idx != BLK_IDX_MGMT_ROUTE)
713 return -ENOENT;
714 cpu_relax();
715 } while (cmd.valid && --retries);
716
717 if (cmd.valid)
718 return -ETIMEDOUT;
719
720
721
722
723 if (entry)
724 ops->entry_packing(packed_buf, entry, UNPACK);
725 return 0;
726 }
727
728 int sja1105_dynamic_config_write(struct sja1105_private *priv,
729 enum sja1105_blk_idx blk_idx,
730 int index, void *entry, bool keep)
731 {
732 const struct sja1105_dynamic_table_ops *ops;
733 struct sja1105_dyn_cmd cmd = {0};
734
735 u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0};
736 int rc;
737
738 if (blk_idx >= BLK_IDX_MAX_DYN)
739 return -ERANGE;
740
741 ops = &priv->info->dyn_ops[blk_idx];
742
743 if (index >= ops->max_entry_count)
744 return -ERANGE;
745 if (index < 0)
746 return -ERANGE;
747 if (!(ops->access & OP_WRITE))
748 return -EOPNOTSUPP;
749 if (!keep && !(ops->access & OP_DEL))
750 return -EOPNOTSUPP;
751 if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE)
752 return -ERANGE;
753
754 cmd.valident = keep;
755 cmd.valid = true;
756 cmd.rdwrset = SPI_WRITE;
757 cmd.index = index;
758
759 if (!ops->cmd_packing)
760 return -EOPNOTSUPP;
761 ops->cmd_packing(packed_buf, &cmd, PACK);
762
763 if (!ops->entry_packing)
764 return -EOPNOTSUPP;
765
766
767
768
769
770 if (keep)
771 ops->entry_packing(packed_buf, entry, PACK);
772
773
774 rc = sja1105_spi_send_packed_buf(priv, SPI_WRITE, ops->addr,
775 packed_buf, ops->packed_size);
776 if (rc < 0)
777 return rc;
778
779 cmd = (struct sja1105_dyn_cmd) {0};
780 ops->cmd_packing(packed_buf, &cmd, UNPACK);
781 if (cmd.errors)
782 return -EINVAL;
783
784 return 0;
785 }
786
787 static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly)
788 {
789 int i;
790
791 for (i = 0; i < 8; i++) {
792 if ((crc ^ byte) & (1 << 7)) {
793 crc <<= 1;
794 crc ^= poly;
795 } else {
796 crc <<= 1;
797 }
798 byte <<= 1;
799 }
800 return crc;
801 }
802
803
804
805
806
807
808
809 u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid)
810 {
811 struct sja1105_l2_lookup_params_entry *l2_lookup_params =
812 priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS].entries;
813 u64 poly_koopman = l2_lookup_params->poly;
814
815 u8 poly = (u8)(1 + (poly_koopman << 1));
816 u64 vlanid = l2_lookup_params->shared_learn ? 0 : vid;
817 u64 input = (vlanid << 48) | ether_addr_to_u64(addr);
818 u8 crc = 0;
819 int i;
820
821
822 for (i = 56; i >= 0; i -= 8) {
823 u8 byte = (input & (0xffull << i)) >> i;
824
825 crc = sja1105_crc8_add(crc, byte, poly);
826 }
827 return crc;
828 }