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 }