0001
0002
0003
0004 #include "sja1105.h"
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 #define SJA1105_SIZE_DYN_CMD 4
0102
0103 #define SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD \
0104 SJA1105_SIZE_DYN_CMD
0105
0106 #define SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD \
0107 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_LOOKUP_ENTRY)
0108
0109 #define SJA1110_SIZE_VL_POLICING_DYN_CMD \
0110 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_POLICING_ENTRY)
0111
0112 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY \
0113 SJA1105_SIZE_DYN_CMD
0114
0115 #define SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD \
0116 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_L2_LOOKUP_ENTRY)
0117
0118 #define SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD \
0119 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY)
0120
0121 #define SJA1110_SIZE_L2_LOOKUP_DYN_CMD \
0122 (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_ENTRY)
0123
0124 #define SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD \
0125 (SJA1105_SIZE_DYN_CMD + 4 + SJA1105_SIZE_VLAN_LOOKUP_ENTRY)
0126
0127 #define SJA1110_SIZE_VLAN_LOOKUP_DYN_CMD \
0128 (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_VLAN_LOOKUP_ENTRY)
0129
0130 #define SJA1105_SIZE_L2_FORWARDING_DYN_CMD \
0131 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_FORWARDING_ENTRY)
0132
0133 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD \
0134 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY)
0135
0136 #define SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD \
0137 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY)
0138
0139 #define SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \
0140 SJA1105_SIZE_DYN_CMD
0141
0142 #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \
0143 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY)
0144
0145 #define SJA1110_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \
0146 (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY)
0147
0148 #define SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD \
0149 SJA1105_SIZE_DYN_CMD
0150
0151 #define SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD \
0152 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY)
0153
0154 #define SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD \
0155 (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_GENERAL_PARAMS_ENTRY)
0156
0157 #define SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD \
0158 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY)
0159
0160 #define SJA1105_SIZE_RETAGGING_DYN_CMD \
0161 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_RETAGGING_ENTRY)
0162
0163 #define SJA1105ET_SIZE_CBS_DYN_CMD \
0164 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_CBS_ENTRY)
0165
0166 #define SJA1105PQRS_SIZE_CBS_DYN_CMD \
0167 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_CBS_ENTRY)
0168
0169 #define SJA1110_SIZE_XMII_PARAMS_DYN_CMD \
0170 SJA1110_SIZE_XMII_PARAMS_ENTRY
0171
0172 #define SJA1110_SIZE_L2_POLICING_DYN_CMD \
0173 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_POLICING_ENTRY)
0174
0175 #define SJA1110_SIZE_L2_FORWARDING_PARAMS_DYN_CMD \
0176 SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY
0177
0178 #define SJA1105_MAX_DYN_CMD_SIZE \
0179 SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD
0180
0181 struct sja1105_dyn_cmd {
0182 bool search;
0183 u64 valid;
0184 u64 rdwrset;
0185 u64 errors;
0186 u64 valident;
0187 u64 index;
0188 };
0189
0190 enum sja1105_hostcmd {
0191 SJA1105_HOSTCMD_SEARCH = 1,
0192 SJA1105_HOSTCMD_READ = 2,
0193 SJA1105_HOSTCMD_WRITE = 3,
0194 SJA1105_HOSTCMD_INVALIDATE = 4,
0195 };
0196
0197
0198 static void
0199 sja1105et_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0200 enum packing_op op)
0201 {
0202 const int size = SJA1105_SIZE_DYN_CMD;
0203
0204 sja1105_packing(buf, &cmd->valid, 31, 31, size, op);
0205 sja1105_packing(buf, &cmd->errors, 30, 30, size, op);
0206 sja1105_packing(buf, &cmd->rdwrset, 29, 29, size, op);
0207 sja1105_packing(buf, &cmd->index, 9, 0, size, op);
0208 }
0209
0210
0211 static void
0212 sja1105pqrs_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0213 enum packing_op op)
0214 {
0215 u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY;
0216 const int size = SJA1105_SIZE_DYN_CMD;
0217
0218 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0219 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
0220 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
0221 sja1105_packing(p, &cmd->index, 9, 0, size, op);
0222 }
0223
0224 static void
0225 sja1110_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0226 enum packing_op op)
0227 {
0228 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
0229 const int size = SJA1105_SIZE_DYN_CMD;
0230
0231 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0232 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0233 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0234 sja1105_packing(p, &cmd->index, 11, 0, size, op);
0235 }
0236
0237 static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr,
0238 enum packing_op op)
0239 {
0240 struct sja1105_vl_lookup_entry *entry = entry_ptr;
0241 const int size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD;
0242
0243 sja1105_packing(buf, &entry->egrmirr, 21, 17, size, op);
0244 sja1105_packing(buf, &entry->ingrmirr, 16, 16, size, op);
0245 return size;
0246 }
0247
0248 static void
0249 sja1110_vl_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0250 enum packing_op op)
0251 {
0252 u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY;
0253 const int size = SJA1105_SIZE_DYN_CMD;
0254
0255 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0256 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0257 sja1105_packing(p, &cmd->index, 11, 0, size, op);
0258 }
0259
0260 static void
0261 sja1105pqrs_common_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0262 enum packing_op op, int entry_size)
0263 {
0264 const int size = SJA1105_SIZE_DYN_CMD;
0265 u8 *p = buf + entry_size;
0266 u64 hostcmd;
0267
0268 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0269 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0270 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0271 sja1105_packing(p, &cmd->valident, 27, 27, size, op);
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294 if (cmd->rdwrset == SPI_READ) {
0295 if (cmd->search)
0296 hostcmd = SJA1105_HOSTCMD_SEARCH;
0297 else
0298 hostcmd = SJA1105_HOSTCMD_READ;
0299 } else {
0300
0301 if (cmd->valident)
0302 hostcmd = SJA1105_HOSTCMD_WRITE;
0303 else
0304 hostcmd = SJA1105_HOSTCMD_INVALIDATE;
0305 }
0306 sja1105_packing(p, &hostcmd, 25, 23, size, op);
0307 }
0308
0309 static void
0310 sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0311 enum packing_op op)
0312 {
0313 int entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
0314
0315 sja1105pqrs_common_l2_lookup_cmd_packing(buf, cmd, op, entry_size);
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325 sja1105_packing(buf, &cmd->index, 15, 6, entry_size, op);
0326 }
0327
0328 static void
0329 sja1110_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0330 enum packing_op op)
0331 {
0332 int entry_size = SJA1110_SIZE_L2_LOOKUP_ENTRY;
0333
0334 sja1105pqrs_common_l2_lookup_cmd_packing(buf, cmd, op, entry_size);
0335
0336 sja1105_packing(buf, &cmd->index, 10, 1, entry_size, op);
0337 }
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384 static size_t
0385 sja1105pqrs_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
0386 enum packing_op op)
0387 {
0388 struct sja1105_l2_lookup_entry *entry = entry_ptr;
0389 u8 *cmd = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
0390 const int size = SJA1105_SIZE_DYN_CMD;
0391
0392 sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
0393
0394 return sja1105pqrs_l2_lookup_entry_packing(buf, entry_ptr, op);
0395 }
0396
0397 static size_t sja1110_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
0398 enum packing_op op)
0399 {
0400 struct sja1105_l2_lookup_entry *entry = entry_ptr;
0401 u8 *cmd = buf + SJA1110_SIZE_L2_LOOKUP_ENTRY;
0402 const int size = SJA1105_SIZE_DYN_CMD;
0403
0404 sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
0405
0406 return sja1110_l2_lookup_entry_packing(buf, entry_ptr, op);
0407 }
0408
0409 static void
0410 sja1105et_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0411 enum packing_op op)
0412 {
0413 u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
0414 const int size = SJA1105_SIZE_DYN_CMD;
0415
0416 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0417 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0418 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0419 sja1105_packing(p, &cmd->valident, 27, 27, size, op);
0420
0421 sja1105_packing(buf, &cmd->index, 29, 20,
0422 SJA1105ET_SIZE_L2_LOOKUP_ENTRY, op);
0423 }
0424
0425 static size_t sja1105et_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,
0426 enum packing_op op)
0427 {
0428 struct sja1105_l2_lookup_entry *entry = entry_ptr;
0429 u8 *cmd = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
0430 const int size = SJA1105_SIZE_DYN_CMD;
0431
0432 sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op);
0433
0434 return sja1105et_l2_lookup_entry_packing(buf, entry_ptr, op);
0435 }
0436
0437 static void
0438 sja1105et_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0439 enum packing_op op)
0440 {
0441 u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
0442 u64 mgmtroute = 1;
0443
0444 sja1105et_l2_lookup_cmd_packing(buf, cmd, op);
0445 if (op == PACK)
0446 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD);
0447 }
0448
0449 static size_t sja1105et_mgmt_route_entry_packing(void *buf, void *entry_ptr,
0450 enum packing_op op)
0451 {
0452 struct sja1105_mgmt_entry *entry = entry_ptr;
0453 const size_t size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY;
0454
0455
0456
0457
0458
0459
0460
0461 sja1105_packing(buf, &entry->tsreg, 85, 85, size, op);
0462 sja1105_packing(buf, &entry->takets, 84, 84, size, op);
0463 sja1105_packing(buf, &entry->macaddr, 83, 36, size, op);
0464 sja1105_packing(buf, &entry->destports, 35, 31, size, op);
0465 sja1105_packing(buf, &entry->enfport, 30, 30, size, op);
0466 return size;
0467 }
0468
0469 static void
0470 sja1105pqrs_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0471 enum packing_op op)
0472 {
0473 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
0474 u64 mgmtroute = 1;
0475
0476 sja1105pqrs_l2_lookup_cmd_packing(buf, cmd, op);
0477 if (op == PACK)
0478 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD);
0479 }
0480
0481 static size_t sja1105pqrs_mgmt_route_entry_packing(void *buf, void *entry_ptr,
0482 enum packing_op op)
0483 {
0484 const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY;
0485 struct sja1105_mgmt_entry *entry = entry_ptr;
0486
0487
0488
0489
0490
0491 sja1105_packing(buf, &entry->tsreg, 71, 71, size, op);
0492 sja1105_packing(buf, &entry->takets, 70, 70, size, op);
0493 sja1105_packing(buf, &entry->macaddr, 69, 22, size, op);
0494 sja1105_packing(buf, &entry->destports, 21, 17, size, op);
0495 sja1105_packing(buf, &entry->enfport, 16, 16, size, op);
0496 return size;
0497 }
0498
0499
0500
0501
0502
0503 static void
0504 sja1105_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0505 enum packing_op op)
0506 {
0507 u8 *p = buf + SJA1105_SIZE_VLAN_LOOKUP_ENTRY + 4;
0508 const int size = SJA1105_SIZE_DYN_CMD;
0509
0510 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0511 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0512 sja1105_packing(p, &cmd->valident, 27, 27, size, op);
0513
0514
0515
0516 sja1105_packing(buf, &cmd->index, 38, 27,
0517 SJA1105_SIZE_VLAN_LOOKUP_ENTRY, op);
0518 }
0519
0520
0521 static void
0522 sja1110_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0523 enum packing_op op)
0524 {
0525 u8 *p = buf + SJA1110_SIZE_VLAN_LOOKUP_ENTRY;
0526 const int size = SJA1105_SIZE_DYN_CMD;
0527 u64 type_entry = 0;
0528
0529 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0530 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0531 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0532
0533
0534
0535 sja1105_packing(buf, &cmd->index, 38, 27,
0536 SJA1110_SIZE_VLAN_LOOKUP_ENTRY, op);
0537
0538
0539
0540
0541
0542
0543 if (op == PACK && !cmd->valident) {
0544 sja1105_packing(buf, &type_entry, 40, 39,
0545 SJA1110_SIZE_VLAN_LOOKUP_ENTRY, PACK);
0546 } else if (op == UNPACK) {
0547 sja1105_packing(buf, &type_entry, 40, 39,
0548 SJA1110_SIZE_VLAN_LOOKUP_ENTRY, UNPACK);
0549 cmd->valident = !!type_entry;
0550 }
0551 }
0552
0553 static void
0554 sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0555 enum packing_op op)
0556 {
0557 u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY;
0558 const int size = SJA1105_SIZE_DYN_CMD;
0559
0560 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0561 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
0562 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
0563 sja1105_packing(p, &cmd->index, 4, 0, size, op);
0564 }
0565
0566 static void
0567 sja1110_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0568 enum packing_op op)
0569 {
0570 u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY;
0571 const int size = SJA1105_SIZE_DYN_CMD;
0572
0573 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0574 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0575 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0576 sja1105_packing(p, &cmd->index, 4, 0, size, op);
0577 }
0578
0579 static void
0580 sja1105et_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0581 enum packing_op op)
0582 {
0583 const int size = SJA1105_SIZE_DYN_CMD;
0584
0585 u8 *reg1 = buf + 4;
0586
0587 sja1105_packing(reg1, &cmd->valid, 31, 31, size, op);
0588 sja1105_packing(reg1, &cmd->index, 26, 24, size, op);
0589 }
0590
0591 static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr,
0592 enum packing_op op)
0593 {
0594 const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY;
0595 struct sja1105_mac_config_entry *entry = entry_ptr;
0596
0597 u8 *reg1 = buf + 4;
0598 u8 *reg2 = buf;
0599
0600 sja1105_packing(reg1, &entry->speed, 30, 29, size, op);
0601 sja1105_packing(reg1, &entry->drpdtag, 23, 23, size, op);
0602 sja1105_packing(reg1, &entry->drpuntag, 22, 22, size, op);
0603 sja1105_packing(reg1, &entry->retag, 21, 21, size, op);
0604 sja1105_packing(reg1, &entry->dyn_learn, 20, 20, size, op);
0605 sja1105_packing(reg1, &entry->egress, 19, 19, size, op);
0606 sja1105_packing(reg1, &entry->ingress, 18, 18, size, op);
0607 sja1105_packing(reg1, &entry->ing_mirr, 17, 17, size, op);
0608 sja1105_packing(reg1, &entry->egr_mirr, 16, 16, size, op);
0609 sja1105_packing(reg1, &entry->vlanprio, 14, 12, size, op);
0610 sja1105_packing(reg1, &entry->vlanid, 11, 0, size, op);
0611 sja1105_packing(reg2, &entry->tp_delin, 31, 16, size, op);
0612 sja1105_packing(reg2, &entry->tp_delout, 15, 0, size, op);
0613
0614
0615
0616
0617 return 0;
0618 }
0619
0620 static void
0621 sja1105pqrs_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0622 enum packing_op op)
0623 {
0624 const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY;
0625 u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
0626
0627 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0628 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
0629 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
0630 sja1105_packing(p, &cmd->index, 2, 0, size, op);
0631 }
0632
0633 static void
0634 sja1110_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0635 enum packing_op op)
0636 {
0637 u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY;
0638 const int size = SJA1105_SIZE_DYN_CMD;
0639
0640 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0641 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0642 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0643 sja1105_packing(p, &cmd->index, 3, 0, size, op);
0644 }
0645
0646 static void
0647 sja1105et_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0648 enum packing_op op)
0649 {
0650 sja1105_packing(buf, &cmd->valid, 31, 31,
0651 SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op);
0652 }
0653
0654 static size_t
0655 sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,
0656 enum packing_op op)
0657 {
0658 struct sja1105_l2_lookup_params_entry *entry = entry_ptr;
0659
0660 sja1105_packing(buf, &entry->poly, 7, 0,
0661 SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op);
0662
0663 return 0;
0664 }
0665
0666 static void
0667 sja1105pqrs_l2_lookup_params_cmd_packing(void *buf,
0668 struct sja1105_dyn_cmd *cmd,
0669 enum packing_op op)
0670 {
0671 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY;
0672 const int size = SJA1105_SIZE_DYN_CMD;
0673
0674 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0675 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0676 }
0677
0678 static void
0679 sja1110_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0680 enum packing_op op)
0681 {
0682 u8 *p = buf + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY;
0683 const int size = SJA1105_SIZE_DYN_CMD;
0684
0685 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0686 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0687 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0688 }
0689
0690 static void
0691 sja1105et_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0692 enum packing_op op)
0693 {
0694 const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD;
0695
0696 sja1105_packing(buf, &cmd->valid, 31, 31, size, op);
0697 sja1105_packing(buf, &cmd->errors, 30, 30, size, op);
0698 }
0699
0700 static size_t
0701 sja1105et_general_params_entry_packing(void *buf, void *entry_ptr,
0702 enum packing_op op)
0703 {
0704 struct sja1105_general_params_entry *entry = entry_ptr;
0705 const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD;
0706
0707 sja1105_packing(buf, &entry->mirr_port, 2, 0, size, op);
0708
0709 return 0;
0710 }
0711
0712 static void
0713 sja1105pqrs_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0714 enum packing_op op)
0715 {
0716 u8 *p = buf + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY;
0717 const int size = SJA1105_SIZE_DYN_CMD;
0718
0719 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0720 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
0721 sja1105_packing(p, &cmd->rdwrset, 28, 28, size, op);
0722 }
0723
0724 static void
0725 sja1110_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0726 enum packing_op op)
0727 {
0728 u8 *p = buf + SJA1110_SIZE_GENERAL_PARAMS_ENTRY;
0729 const int size = SJA1105_SIZE_DYN_CMD;
0730
0731 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0732 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0733 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0734 }
0735
0736 static void
0737 sja1105pqrs_avb_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0738 enum packing_op op)
0739 {
0740 u8 *p = buf + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY;
0741 const int size = SJA1105_SIZE_DYN_CMD;
0742
0743 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0744 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
0745 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op);
0746 }
0747
0748 static void
0749 sja1105_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0750 enum packing_op op)
0751 {
0752 u8 *p = buf + SJA1105_SIZE_RETAGGING_ENTRY;
0753 const int size = SJA1105_SIZE_DYN_CMD;
0754
0755 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0756 sja1105_packing(p, &cmd->errors, 30, 30, size, op);
0757 sja1105_packing(p, &cmd->valident, 29, 29, size, op);
0758 sja1105_packing(p, &cmd->rdwrset, 28, 28, size, op);
0759 sja1105_packing(p, &cmd->index, 5, 0, size, op);
0760 }
0761
0762 static void
0763 sja1110_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0764 enum packing_op op)
0765 {
0766 u8 *p = buf + SJA1105_SIZE_RETAGGING_ENTRY;
0767 const int size = SJA1105_SIZE_DYN_CMD;
0768
0769 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0770 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0771 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0772 sja1105_packing(p, &cmd->valident, 28, 28, size, op);
0773 sja1105_packing(p, &cmd->index, 4, 0, size, op);
0774 }
0775
0776 static void sja1105et_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0777 enum packing_op op)
0778 {
0779 u8 *p = buf + SJA1105ET_SIZE_CBS_ENTRY;
0780 const int size = SJA1105_SIZE_DYN_CMD;
0781
0782 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0783 sja1105_packing(p, &cmd->index, 19, 16, size, op);
0784 }
0785
0786 static size_t sja1105et_cbs_entry_packing(void *buf, void *entry_ptr,
0787 enum packing_op op)
0788 {
0789 const size_t size = SJA1105ET_SIZE_CBS_ENTRY;
0790 struct sja1105_cbs_entry *entry = entry_ptr;
0791 u8 *cmd = buf + size;
0792 u32 *p = buf;
0793
0794 sja1105_packing(cmd, &entry->port, 5, 3, SJA1105_SIZE_DYN_CMD, op);
0795 sja1105_packing(cmd, &entry->prio, 2, 0, SJA1105_SIZE_DYN_CMD, op);
0796 sja1105_packing(p + 3, &entry->credit_lo, 31, 0, size, op);
0797 sja1105_packing(p + 2, &entry->credit_hi, 31, 0, size, op);
0798 sja1105_packing(p + 1, &entry->send_slope, 31, 0, size, op);
0799 sja1105_packing(p + 0, &entry->idle_slope, 31, 0, size, op);
0800 return size;
0801 }
0802
0803 static void sja1105pqrs_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0804 enum packing_op op)
0805 {
0806 u8 *p = buf + SJA1105PQRS_SIZE_CBS_ENTRY;
0807 const int size = SJA1105_SIZE_DYN_CMD;
0808
0809 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0810 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0811 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0812 sja1105_packing(p, &cmd->index, 3, 0, size, op);
0813 }
0814
0815 static void sja1110_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0816 enum packing_op op)
0817 {
0818 u8 *p = buf + SJA1105PQRS_SIZE_CBS_ENTRY;
0819 const int size = SJA1105_SIZE_DYN_CMD;
0820
0821 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0822 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0823 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0824 sja1105_packing(p, &cmd->index, 7, 0, size, op);
0825 }
0826
0827 static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr,
0828 enum packing_op op)
0829 {
0830 const size_t size = SJA1105PQRS_SIZE_CBS_ENTRY;
0831 struct sja1105_cbs_entry *entry = entry_ptr;
0832
0833 sja1105_packing(buf, &entry->port, 159, 157, size, op);
0834 sja1105_packing(buf, &entry->prio, 156, 154, size, op);
0835 sja1105_packing(buf, &entry->credit_lo, 153, 122, size, op);
0836 sja1105_packing(buf, &entry->credit_hi, 121, 90, size, op);
0837 sja1105_packing(buf, &entry->send_slope, 89, 58, size, op);
0838 sja1105_packing(buf, &entry->idle_slope, 57, 26, size, op);
0839 return size;
0840 }
0841
0842 static size_t sja1110_cbs_entry_packing(void *buf, void *entry_ptr,
0843 enum packing_op op)
0844 {
0845 const size_t size = SJA1105PQRS_SIZE_CBS_ENTRY;
0846 struct sja1105_cbs_entry *entry = entry_ptr;
0847 u64 entry_type = SJA1110_CBS_SHAPER;
0848
0849 sja1105_packing(buf, &entry_type, 159, 159, size, op);
0850 sja1105_packing(buf, &entry->credit_lo, 151, 120, size, op);
0851 sja1105_packing(buf, &entry->credit_hi, 119, 88, size, op);
0852 sja1105_packing(buf, &entry->send_slope, 87, 56, size, op);
0853 sja1105_packing(buf, &entry->idle_slope, 55, 24, size, op);
0854 return size;
0855 }
0856
0857 static void sja1110_dummy_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0858 enum packing_op op)
0859 {
0860 }
0861
0862 static void
0863 sja1110_l2_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,
0864 enum packing_op op)
0865 {
0866 u8 *p = buf + SJA1105_SIZE_L2_POLICING_ENTRY;
0867 const int size = SJA1105_SIZE_DYN_CMD;
0868
0869 sja1105_packing(p, &cmd->valid, 31, 31, size, op);
0870 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op);
0871 sja1105_packing(p, &cmd->errors, 29, 29, size, op);
0872 sja1105_packing(p, &cmd->index, 6, 0, size, op);
0873 }
0874
0875 #define OP_READ BIT(0)
0876 #define OP_WRITE BIT(1)
0877 #define OP_DEL BIT(2)
0878 #define OP_SEARCH BIT(3)
0879 #define OP_VALID_ANYWAY BIT(4)
0880
0881
0882 const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = {
0883 [BLK_IDX_VL_LOOKUP] = {
0884 .entry_packing = sja1105et_vl_lookup_entry_packing,
0885 .cmd_packing = sja1105et_vl_lookup_cmd_packing,
0886 .access = OP_WRITE,
0887 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
0888 .packed_size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD,
0889 .addr = 0x35,
0890 },
0891 [BLK_IDX_L2_LOOKUP] = {
0892 .entry_packing = sja1105et_dyn_l2_lookup_entry_packing,
0893 .cmd_packing = sja1105et_l2_lookup_cmd_packing,
0894 .access = (OP_READ | OP_WRITE | OP_DEL),
0895 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
0896 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
0897 .addr = 0x20,
0898 },
0899 [BLK_IDX_MGMT_ROUTE] = {
0900 .entry_packing = sja1105et_mgmt_route_entry_packing,
0901 .cmd_packing = sja1105et_mgmt_route_cmd_packing,
0902 .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY),
0903 .max_entry_count = SJA1105_NUM_PORTS,
0904 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD,
0905 .addr = 0x20,
0906 },
0907 [BLK_IDX_VLAN_LOOKUP] = {
0908 .entry_packing = sja1105_vlan_lookup_entry_packing,
0909 .cmd_packing = sja1105_vlan_lookup_cmd_packing,
0910 .access = (OP_WRITE | OP_DEL),
0911 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
0912 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD,
0913 .addr = 0x27,
0914 },
0915 [BLK_IDX_L2_FORWARDING] = {
0916 .entry_packing = sja1105_l2_forwarding_entry_packing,
0917 .cmd_packing = sja1105_l2_forwarding_cmd_packing,
0918 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT,
0919 .access = OP_WRITE,
0920 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD,
0921 .addr = 0x24,
0922 },
0923 [BLK_IDX_MAC_CONFIG] = {
0924 .entry_packing = sja1105et_mac_config_entry_packing,
0925 .cmd_packing = sja1105et_mac_config_cmd_packing,
0926 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT,
0927 .access = OP_WRITE,
0928 .packed_size = SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD,
0929 .addr = 0x36,
0930 },
0931 [BLK_IDX_L2_LOOKUP_PARAMS] = {
0932 .entry_packing = sja1105et_l2_lookup_params_entry_packing,
0933 .cmd_packing = sja1105et_l2_lookup_params_cmd_packing,
0934 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT,
0935 .access = OP_WRITE,
0936 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD,
0937 .addr = 0x38,
0938 },
0939 [BLK_IDX_GENERAL_PARAMS] = {
0940 .entry_packing = sja1105et_general_params_entry_packing,
0941 .cmd_packing = sja1105et_general_params_cmd_packing,
0942 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT,
0943 .access = OP_WRITE,
0944 .packed_size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD,
0945 .addr = 0x34,
0946 },
0947 [BLK_IDX_RETAGGING] = {
0948 .entry_packing = sja1105_retagging_entry_packing,
0949 .cmd_packing = sja1105_retagging_cmd_packing,
0950 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT,
0951 .access = (OP_WRITE | OP_DEL),
0952 .packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD,
0953 .addr = 0x31,
0954 },
0955 [BLK_IDX_CBS] = {
0956 .entry_packing = sja1105et_cbs_entry_packing,
0957 .cmd_packing = sja1105et_cbs_cmd_packing,
0958 .max_entry_count = SJA1105ET_MAX_CBS_COUNT,
0959 .access = OP_WRITE,
0960 .packed_size = SJA1105ET_SIZE_CBS_DYN_CMD,
0961 .addr = 0x2c,
0962 },
0963 };
0964
0965
0966 const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {
0967 [BLK_IDX_VL_LOOKUP] = {
0968 .entry_packing = sja1105_vl_lookup_entry_packing,
0969 .cmd_packing = sja1105pqrs_vl_lookup_cmd_packing,
0970 .access = (OP_READ | OP_WRITE),
0971 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT,
0972 .packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD,
0973 .addr = 0x47,
0974 },
0975 [BLK_IDX_L2_LOOKUP] = {
0976 .entry_packing = sja1105pqrs_dyn_l2_lookup_entry_packing,
0977 .cmd_packing = sja1105pqrs_l2_lookup_cmd_packing,
0978 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH),
0979 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT,
0980 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
0981 .addr = 0x24,
0982 },
0983 [BLK_IDX_MGMT_ROUTE] = {
0984 .entry_packing = sja1105pqrs_mgmt_route_entry_packing,
0985 .cmd_packing = sja1105pqrs_mgmt_route_cmd_packing,
0986 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH | OP_VALID_ANYWAY),
0987 .max_entry_count = SJA1105_NUM_PORTS,
0988 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD,
0989 .addr = 0x24,
0990 },
0991 [BLK_IDX_VLAN_LOOKUP] = {
0992 .entry_packing = sja1105_vlan_lookup_entry_packing,
0993 .cmd_packing = sja1105_vlan_lookup_cmd_packing,
0994 .access = (OP_READ | OP_WRITE | OP_DEL),
0995 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT,
0996 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD,
0997 .addr = 0x2D,
0998 },
0999 [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
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 #define SJA1105_DYNAMIC_CONFIG_SLEEP_US 10
1174 #define SJA1105_DYNAMIC_CONFIG_TIMEOUT_US 100000
1175
1176 static int
1177 sja1105_dynamic_config_poll_valid(struct sja1105_private *priv,
1178 struct sja1105_dyn_cmd *cmd,
1179 const struct sja1105_dynamic_table_ops *ops)
1180 {
1181 u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {};
1182 int rc;
1183
1184
1185
1186
1187
1188
1189
1190 rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf,
1191 ops->packed_size);
1192 if (rc)
1193 return rc;
1194
1195
1196
1197
1198 memset(cmd, 0, sizeof(*cmd));
1199 ops->cmd_packing(packed_buf, cmd, UNPACK);
1200
1201
1202 return cmd->valid ? -EAGAIN : 0;
1203 }
1204
1205
1206
1207
1208
1209 static int
1210 sja1105_dynamic_config_wait_complete(struct sja1105_private *priv,
1211 struct sja1105_dyn_cmd *cmd,
1212 const struct sja1105_dynamic_table_ops *ops)
1213 {
1214 int rc;
1215
1216 return read_poll_timeout(sja1105_dynamic_config_poll_valid,
1217 rc, rc != -EAGAIN,
1218 SJA1105_DYNAMIC_CONFIG_SLEEP_US,
1219 SJA1105_DYNAMIC_CONFIG_TIMEOUT_US,
1220 false, priv, cmd, ops);
1221 }
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241 int sja1105_dynamic_config_read(struct sja1105_private *priv,
1242 enum sja1105_blk_idx blk_idx,
1243 int index, void *entry)
1244 {
1245 const struct sja1105_dynamic_table_ops *ops;
1246 struct sja1105_dyn_cmd cmd = {0};
1247
1248 u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0};
1249 int rc;
1250
1251 if (blk_idx >= BLK_IDX_MAX_DYN)
1252 return -ERANGE;
1253
1254 ops = &priv->info->dyn_ops[blk_idx];
1255
1256 if (index >= 0 && index >= ops->max_entry_count)
1257 return -ERANGE;
1258 if (index < 0 && !(ops->access & OP_SEARCH))
1259 return -EOPNOTSUPP;
1260 if (!(ops->access & OP_READ))
1261 return -EOPNOTSUPP;
1262 if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE)
1263 return -ERANGE;
1264 if (!ops->cmd_packing)
1265 return -EOPNOTSUPP;
1266 if (!ops->entry_packing)
1267 return -EOPNOTSUPP;
1268
1269 cmd.valid = true;
1270 cmd.rdwrset = SPI_READ;
1271 if (index < 0) {
1272
1273 cmd.index = 0;
1274 cmd.search = true;
1275 } else {
1276 cmd.index = index;
1277 cmd.search = false;
1278 }
1279 cmd.valident = true;
1280 ops->cmd_packing(packed_buf, &cmd, PACK);
1281
1282 if (cmd.search)
1283 ops->entry_packing(packed_buf, entry, PACK);
1284
1285
1286 mutex_lock(&priv->dynamic_config_lock);
1287 rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
1288 ops->packed_size);
1289 if (rc < 0) {
1290 mutex_unlock(&priv->dynamic_config_lock);
1291 return rc;
1292 }
1293
1294 rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops);
1295 mutex_unlock(&priv->dynamic_config_lock);
1296 if (rc < 0)
1297 return rc;
1298
1299 if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY))
1300 return -ENOENT;
1301
1302
1303
1304
1305 if (entry)
1306 ops->entry_packing(packed_buf, entry, UNPACK);
1307 return 0;
1308 }
1309
1310 int sja1105_dynamic_config_write(struct sja1105_private *priv,
1311 enum sja1105_blk_idx blk_idx,
1312 int index, void *entry, bool keep)
1313 {
1314 const struct sja1105_dynamic_table_ops *ops;
1315 struct sja1105_dyn_cmd cmd = {0};
1316
1317 u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0};
1318 int rc;
1319
1320 if (blk_idx >= BLK_IDX_MAX_DYN)
1321 return -ERANGE;
1322
1323 ops = &priv->info->dyn_ops[blk_idx];
1324
1325 if (index >= ops->max_entry_count)
1326 return -ERANGE;
1327 if (index < 0)
1328 return -ERANGE;
1329 if (!(ops->access & OP_WRITE))
1330 return -EOPNOTSUPP;
1331 if (!keep && !(ops->access & OP_DEL))
1332 return -EOPNOTSUPP;
1333 if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE)
1334 return -ERANGE;
1335
1336 cmd.valident = keep;
1337 cmd.valid = true;
1338 cmd.rdwrset = SPI_WRITE;
1339 cmd.index = index;
1340
1341 if (!ops->cmd_packing)
1342 return -EOPNOTSUPP;
1343 ops->cmd_packing(packed_buf, &cmd, PACK);
1344
1345 if (!ops->entry_packing)
1346 return -EOPNOTSUPP;
1347
1348
1349
1350
1351
1352 if (keep)
1353 ops->entry_packing(packed_buf, entry, PACK);
1354
1355
1356 mutex_lock(&priv->dynamic_config_lock);
1357 rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf,
1358 ops->packed_size);
1359 if (rc < 0) {
1360 mutex_unlock(&priv->dynamic_config_lock);
1361 return rc;
1362 }
1363
1364 rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops);
1365 mutex_unlock(&priv->dynamic_config_lock);
1366 if (rc < 0)
1367 return rc;
1368
1369 cmd = (struct sja1105_dyn_cmd) {0};
1370 ops->cmd_packing(packed_buf, &cmd, UNPACK);
1371 if (cmd.errors)
1372 return -EINVAL;
1373
1374 return 0;
1375 }
1376
1377 static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly)
1378 {
1379 int i;
1380
1381 for (i = 0; i < 8; i++) {
1382 if ((crc ^ byte) & (1 << 7)) {
1383 crc <<= 1;
1384 crc ^= poly;
1385 } else {
1386 crc <<= 1;
1387 }
1388 byte <<= 1;
1389 }
1390 return crc;
1391 }
1392
1393
1394
1395
1396
1397
1398
1399 u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid)
1400 {
1401 struct sja1105_l2_lookup_params_entry *l2_lookup_params =
1402 priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS].entries;
1403 u64 input, poly_koopman = l2_lookup_params->poly;
1404
1405 u8 poly = (u8)(1 + (poly_koopman << 1));
1406 u8 crc = 0;
1407 int i;
1408
1409 input = ((u64)vid << 48) | ether_addr_to_u64(addr);
1410
1411
1412 for (i = 56; i >= 0; i -= 8) {
1413 u8 byte = (input & (0xffull << i)) >> i;
1414
1415 crc = sja1105_crc8_add(crc, byte, poly);
1416 }
1417 return crc;
1418 }