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 * - .max_entry_count: The number of entries, counting from zero, that can be 82 * reconfigured through the dynamic interface. If a static 83 * table can be reconfigured at all dynamically, this 84 * number always matches the maximum number of supported 85 * static entries. 86 * - .packed_size: The length in bytes of the compound ENTRY + COMMAND BUFFER. 87 * Note that sometimes the compound buffer may contain holes in 88 * it (see sja1105_vlan_lookup_cmd_packing). The @packed_buf is 89 * contiguous however, so @packed_size includes any unused 90 * bytes. 91 * - .addr: The base SPI address at which the buffer must be written to the 92 * switch's memory. When looking at the hardware manual, this must 93 * always match the lowest documented address for the ENTRY, and not 94 * that of the COMMAND, since the other 32-bit words will follow along 95 * at the correct addresses. 96 */ 97 98 #define SJA1105_SIZE_DYN_CMD 4 99 100 #define SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD \ 101 SJA1105_SIZE_DYN_CMD 102 103 #define SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD \ 104 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_LOOKUP_ENTRY) 105 106 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY \ 107 SJA1105_SIZE_DYN_CMD 108 109 #define SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD \ 110 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_L2_LOOKUP_ENTRY) 111 112 #define SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD \ 113 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY) 114 115 #define SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD \ 116 (SJA1105_SIZE_DYN_CMD + 4 + SJA1105_SIZE_VLAN_LOOKUP_ENTRY) 117 118 #define SJA1105_SIZE_L2_FORWARDING_DYN_CMD \ 119 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_FORWARDING_ENTRY) 120 121 #define SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD \ 122 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY) 123 124 #define SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD \ 125 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY) 126 127 #define SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \ 128 SJA1105_SIZE_DYN_CMD 129 130 #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \ 131 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY) 132 133 #define SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD \ 134 SJA1105_SIZE_DYN_CMD 135 136 #define SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD \ 137 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY) 138 139 #define SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD \ 140 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY) 141 142 #define SJA1105_SIZE_RETAGGING_DYN_CMD \ 143 (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_RETAGGING_ENTRY) 144 145 #define SJA1105ET_SIZE_CBS_DYN_CMD \ 146 (SJA1105_SIZE_DYN_CMD + SJA1105ET_SIZE_CBS_ENTRY) 147 148 #define SJA1105PQRS_SIZE_CBS_DYN_CMD \ 149 (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_CBS_ENTRY) 150 151 #define SJA1105_MAX_DYN_CMD_SIZE \ 152 SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD 153 154 struct sja1105_dyn_cmd { 155 bool search; 156 u64 valid; 157 u64 rdwrset; 158 u64 errors; 159 u64 valident; 160 u64 index; 161 }; 162 163 enum sja1105_hostcmd { 164 SJA1105_HOSTCMD_SEARCH = 1, 165 SJA1105_HOSTCMD_READ = 2, 166 SJA1105_HOSTCMD_WRITE = 3, 167 SJA1105_HOSTCMD_INVALIDATE = 4, 168 }; 169 170 static void 171 sja1105_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 172 enum packing_op op) 173 { 174 const int size = SJA1105_SIZE_DYN_CMD; 175 176 sja1105_packing(buf, &cmd->valid, 31, 31, size, op); 177 sja1105_packing(buf, &cmd->errors, 30, 30, size, op); 178 sja1105_packing(buf, &cmd->rdwrset, 29, 29, size, op); 179 sja1105_packing(buf, &cmd->index, 9, 0, size, op); 180 } 181 182 static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr, 183 enum packing_op op) 184 { 185 struct sja1105_vl_lookup_entry *entry = entry_ptr; 186 const int size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD; 187 188 sja1105_packing(buf, &entry->egrmirr, 21, 17, size, op); 189 sja1105_packing(buf, &entry->ingrmirr, 16, 16, size, op); 190 return size; 191 } 192 193 static void 194 sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 195 enum packing_op op) 196 { 197 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; 198 const int size = SJA1105_SIZE_DYN_CMD; 199 u64 hostcmd; 200 201 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 202 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); 203 sja1105_packing(p, &cmd->errors, 29, 29, size, op); 204 sja1105_packing(p, &cmd->valident, 27, 27, size, op); 205 206 /* VALIDENT is supposed to indicate "keep or not", but in SJA1105 E/T, 207 * using it to delete a management route was unsupported. UM10944 208 * said about it: 209 * 210 * In case of a write access with the MGMTROUTE flag set, 211 * the flag will be ignored. It will always be found cleared 212 * for read accesses with the MGMTROUTE flag set. 213 * 214 * SJA1105 P/Q/R/S keeps the same behavior w.r.t. VALIDENT, but there 215 * is now another flag called HOSTCMD which does more stuff (quoting 216 * from UM11040): 217 * 218 * A write request is accepted only when HOSTCMD is set to write host 219 * or invalid. A read request is accepted only when HOSTCMD is set to 220 * search host or read host. 221 * 222 * So it is possible to translate a RDWRSET/VALIDENT combination into 223 * HOSTCMD so that we keep the dynamic command API in place, and 224 * at the same time achieve compatibility with the management route 225 * command structure. 226 */ 227 if (cmd->rdwrset == SPI_READ) { 228 if (cmd->search) 229 hostcmd = SJA1105_HOSTCMD_SEARCH; 230 else 231 hostcmd = SJA1105_HOSTCMD_READ; 232 } else { 233 /* SPI_WRITE */ 234 if (cmd->valident) 235 hostcmd = SJA1105_HOSTCMD_WRITE; 236 else 237 hostcmd = SJA1105_HOSTCMD_INVALIDATE; 238 } 239 sja1105_packing(p, &hostcmd, 25, 23, size, op); 240 241 /* Hack - The hardware takes the 'index' field within 242 * struct sja1105_l2_lookup_entry as the index on which this command 243 * will operate. However it will ignore everything else, so 'index' 244 * is logically part of command but physically part of entry. 245 * Populate the 'index' entry field from within the command callback, 246 * such that our API doesn't need to ask for a full-blown entry 247 * structure when e.g. a delete is requested. 248 */ 249 sja1105_packing(buf, &cmd->index, 15, 6, 250 SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, op); 251 } 252 253 /* The switch is so retarded that it makes our command/entry abstraction 254 * crumble apart. 255 * 256 * On P/Q/R/S, the switch tries to say whether a FDB entry 257 * is statically programmed or dynamically learned via a flag called LOCKEDS. 258 * The hardware manual says about this fiels: 259 * 260 * On write will specify the format of ENTRY. 261 * On read the flag will be found cleared at times the VALID flag is found 262 * set. The flag will also be found cleared in response to a read having the 263 * MGMTROUTE flag set. In response to a read with the MGMTROUTE flag 264 * cleared, the flag be set if the most recent access operated on an entry 265 * that was either loaded by configuration or through dynamic reconfiguration 266 * (as opposed to automatically learned entries). 267 * 268 * The trouble with this flag is that it's part of the *command* to access the 269 * dynamic interface, and not part of the *entry* retrieved from it. 270 * Otherwise said, for a sja1105_dynamic_config_read, LOCKEDS is supposed to be 271 * an output from the switch into the command buffer, and for a 272 * sja1105_dynamic_config_write, the switch treats LOCKEDS as an input 273 * (hence we can write either static, or automatically learned entries, from 274 * the core). 275 * But the manual contradicts itself in the last phrase where it says that on 276 * read, LOCKEDS will be set to 1 for all FDB entries written through the 277 * dynamic interface (therefore, the value of LOCKEDS from the 278 * sja1105_dynamic_config_write is not really used for anything, it'll store a 279 * 1 anyway). 280 * This means you can't really write a FDB entry with LOCKEDS=0 (automatically 281 * learned) into the switch, which kind of makes sense. 282 * As for reading through the dynamic interface, it doesn't make too much sense 283 * to put LOCKEDS into the command, since the switch will inevitably have to 284 * ignore it (otherwise a command would be like "read the FDB entry 123, but 285 * only if it's dynamically learned" <- well how am I supposed to know?) and 286 * just use it as an output buffer for its findings. But guess what... that's 287 * what the entry buffer is for! 288 * Unfortunately, what really breaks this abstraction is the fact that it 289 * wasn't designed having the fact in mind that the switch can output 290 * entry-related data as writeback through the command buffer. 291 * However, whether a FDB entry is statically or dynamically learned *is* part 292 * of the entry and not the command data, no matter what the switch thinks. 293 * In order to do that, we'll need to wrap around the 294 * sja1105pqrs_l2_lookup_entry_packing from sja1105_static_config.c, and take 295 * a peek outside of the caller-supplied @buf (the entry buffer), to reach the 296 * command buffer. 297 */ 298 static size_t 299 sja1105pqrs_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr, 300 enum packing_op op) 301 { 302 struct sja1105_l2_lookup_entry *entry = entry_ptr; 303 u8 *cmd = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; 304 const int size = SJA1105_SIZE_DYN_CMD; 305 306 sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op); 307 308 return sja1105pqrs_l2_lookup_entry_packing(buf, entry_ptr, op); 309 } 310 311 static void 312 sja1105et_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 313 enum packing_op op) 314 { 315 u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY; 316 const int size = SJA1105_SIZE_DYN_CMD; 317 318 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 319 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); 320 sja1105_packing(p, &cmd->errors, 29, 29, size, op); 321 sja1105_packing(p, &cmd->valident, 27, 27, size, op); 322 /* Hack - see comments above. */ 323 sja1105_packing(buf, &cmd->index, 29, 20, 324 SJA1105ET_SIZE_L2_LOOKUP_ENTRY, op); 325 } 326 327 static size_t sja1105et_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr, 328 enum packing_op op) 329 { 330 struct sja1105_l2_lookup_entry *entry = entry_ptr; 331 u8 *cmd = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY; 332 const int size = SJA1105_SIZE_DYN_CMD; 333 334 sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op); 335 336 return sja1105et_l2_lookup_entry_packing(buf, entry_ptr, op); 337 } 338 339 static void 340 sja1105et_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 341 enum packing_op op) 342 { 343 u8 *p = buf + SJA1105ET_SIZE_L2_LOOKUP_ENTRY; 344 u64 mgmtroute = 1; 345 346 sja1105et_l2_lookup_cmd_packing(buf, cmd, op); 347 if (op == PACK) 348 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD); 349 } 350 351 static size_t sja1105et_mgmt_route_entry_packing(void *buf, void *entry_ptr, 352 enum packing_op op) 353 { 354 struct sja1105_mgmt_entry *entry = entry_ptr; 355 const size_t size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY; 356 357 /* UM10944: To specify if a PTP egress timestamp shall be captured on 358 * each port upon transmission of the frame, the LSB of VLANID in the 359 * ENTRY field provided by the host must be set. 360 * Bit 1 of VLANID then specifies the register where the timestamp for 361 * this port is stored in. 362 */ 363 sja1105_packing(buf, &entry->tsreg, 85, 85, size, op); 364 sja1105_packing(buf, &entry->takets, 84, 84, size, op); 365 sja1105_packing(buf, &entry->macaddr, 83, 36, size, op); 366 sja1105_packing(buf, &entry->destports, 35, 31, size, op); 367 sja1105_packing(buf, &entry->enfport, 30, 30, size, op); 368 return size; 369 } 370 371 static void 372 sja1105pqrs_mgmt_route_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 373 enum packing_op op) 374 { 375 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; 376 u64 mgmtroute = 1; 377 378 sja1105pqrs_l2_lookup_cmd_packing(buf, cmd, op); 379 if (op == PACK) 380 sja1105_pack(p, &mgmtroute, 26, 26, SJA1105_SIZE_DYN_CMD); 381 } 382 383 static size_t sja1105pqrs_mgmt_route_entry_packing(void *buf, void *entry_ptr, 384 enum packing_op op) 385 { 386 const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; 387 struct sja1105_mgmt_entry *entry = entry_ptr; 388 389 /* In P/Q/R/S, enfport got renamed to mgmtvalid, but its purpose 390 * is the same (driver uses it to confirm that frame was sent). 391 * So just keep the name from E/T. 392 */ 393 sja1105_packing(buf, &entry->tsreg, 71, 71, size, op); 394 sja1105_packing(buf, &entry->takets, 70, 70, size, op); 395 sja1105_packing(buf, &entry->macaddr, 69, 22, size, op); 396 sja1105_packing(buf, &entry->destports, 21, 17, size, op); 397 sja1105_packing(buf, &entry->enfport, 16, 16, size, op); 398 return size; 399 } 400 401 /* In E/T, entry is at addresses 0x27-0x28. There is a 4 byte gap at 0x29, 402 * and command is at 0x2a. Similarly in P/Q/R/S there is a 1 register gap 403 * between entry (0x2d, 0x2e) and command (0x30). 404 */ 405 static void 406 sja1105_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 407 enum packing_op op) 408 { 409 u8 *p = buf + SJA1105_SIZE_VLAN_LOOKUP_ENTRY + 4; 410 const int size = SJA1105_SIZE_DYN_CMD; 411 412 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 413 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); 414 sja1105_packing(p, &cmd->valident, 27, 27, size, op); 415 /* Hack - see comments above, applied for 'vlanid' field of 416 * struct sja1105_vlan_lookup_entry. 417 */ 418 sja1105_packing(buf, &cmd->index, 38, 27, 419 SJA1105_SIZE_VLAN_LOOKUP_ENTRY, op); 420 } 421 422 static void 423 sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 424 enum packing_op op) 425 { 426 u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY; 427 const int size = SJA1105_SIZE_DYN_CMD; 428 429 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 430 sja1105_packing(p, &cmd->errors, 30, 30, size, op); 431 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op); 432 sja1105_packing(p, &cmd->index, 4, 0, size, op); 433 } 434 435 static void 436 sja1105et_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 437 enum packing_op op) 438 { 439 const int size = SJA1105_SIZE_DYN_CMD; 440 /* Yup, user manual definitions are reversed */ 441 u8 *reg1 = buf + 4; 442 443 sja1105_packing(reg1, &cmd->valid, 31, 31, size, op); 444 sja1105_packing(reg1, &cmd->index, 26, 24, size, op); 445 } 446 447 static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr, 448 enum packing_op op) 449 { 450 const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY; 451 struct sja1105_mac_config_entry *entry = entry_ptr; 452 /* Yup, user manual definitions are reversed */ 453 u8 *reg1 = buf + 4; 454 u8 *reg2 = buf; 455 456 sja1105_packing(reg1, &entry->speed, 30, 29, size, op); 457 sja1105_packing(reg1, &entry->drpdtag, 23, 23, size, op); 458 sja1105_packing(reg1, &entry->drpuntag, 22, 22, size, op); 459 sja1105_packing(reg1, &entry->retag, 21, 21, size, op); 460 sja1105_packing(reg1, &entry->dyn_learn, 20, 20, size, op); 461 sja1105_packing(reg1, &entry->egress, 19, 19, size, op); 462 sja1105_packing(reg1, &entry->ingress, 18, 18, size, op); 463 sja1105_packing(reg1, &entry->ing_mirr, 17, 17, size, op); 464 sja1105_packing(reg1, &entry->egr_mirr, 16, 16, size, op); 465 sja1105_packing(reg1, &entry->vlanprio, 14, 12, size, op); 466 sja1105_packing(reg1, &entry->vlanid, 11, 0, size, op); 467 sja1105_packing(reg2, &entry->tp_delin, 31, 16, size, op); 468 sja1105_packing(reg2, &entry->tp_delout, 15, 0, size, op); 469 /* MAC configuration table entries which can't be reconfigured: 470 * top, base, enabled, ifg, maxage, drpnona664 471 */ 472 /* Bogus return value, not used anywhere */ 473 return 0; 474 } 475 476 static void 477 sja1105pqrs_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 478 enum packing_op op) 479 { 480 const int size = SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY; 481 u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY; 482 483 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 484 sja1105_packing(p, &cmd->errors, 30, 30, size, op); 485 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op); 486 sja1105_packing(p, &cmd->index, 2, 0, size, op); 487 } 488 489 static void 490 sja1105et_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 491 enum packing_op op) 492 { 493 sja1105_packing(buf, &cmd->valid, 31, 31, 494 SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op); 495 } 496 497 static size_t 498 sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, 499 enum packing_op op) 500 { 501 struct sja1105_l2_lookup_params_entry *entry = entry_ptr; 502 503 sja1105_packing(buf, &entry->poly, 7, 0, 504 SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, op); 505 /* Bogus return value, not used anywhere */ 506 return 0; 507 } 508 509 static void 510 sja1105pqrs_l2_lookup_params_cmd_packing(void *buf, 511 struct sja1105_dyn_cmd *cmd, 512 enum packing_op op) 513 { 514 u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY; 515 const int size = SJA1105_SIZE_DYN_CMD; 516 517 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 518 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); 519 } 520 521 static void 522 sja1105et_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 523 enum packing_op op) 524 { 525 const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD; 526 527 sja1105_packing(buf, &cmd->valid, 31, 31, size, op); 528 sja1105_packing(buf, &cmd->errors, 30, 30, size, op); 529 } 530 531 static size_t 532 sja1105et_general_params_entry_packing(void *buf, void *entry_ptr, 533 enum packing_op op) 534 { 535 struct sja1105_general_params_entry *entry = entry_ptr; 536 const int size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD; 537 538 sja1105_packing(buf, &entry->mirr_port, 2, 0, size, op); 539 /* Bogus return value, not used anywhere */ 540 return 0; 541 } 542 543 static void 544 sja1105pqrs_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 545 enum packing_op op) 546 { 547 u8 *p = buf + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY; 548 const int size = SJA1105_SIZE_DYN_CMD; 549 550 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 551 sja1105_packing(p, &cmd->errors, 30, 30, size, op); 552 sja1105_packing(p, &cmd->rdwrset, 28, 28, size, op); 553 } 554 555 static void 556 sja1105pqrs_avb_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 557 enum packing_op op) 558 { 559 u8 *p = buf + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY; 560 const int size = SJA1105_SIZE_DYN_CMD; 561 562 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 563 sja1105_packing(p, &cmd->errors, 30, 30, size, op); 564 sja1105_packing(p, &cmd->rdwrset, 29, 29, size, op); 565 } 566 567 static void 568 sja1105_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 569 enum packing_op op) 570 { 571 u8 *p = buf + SJA1105_SIZE_RETAGGING_ENTRY; 572 const int size = SJA1105_SIZE_DYN_CMD; 573 574 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 575 sja1105_packing(p, &cmd->errors, 30, 30, size, op); 576 sja1105_packing(p, &cmd->valident, 29, 29, size, op); 577 sja1105_packing(p, &cmd->rdwrset, 28, 28, size, op); 578 sja1105_packing(p, &cmd->index, 5, 0, size, op); 579 } 580 581 static void sja1105et_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 582 enum packing_op op) 583 { 584 u8 *p = buf + SJA1105ET_SIZE_CBS_ENTRY; 585 const int size = SJA1105_SIZE_DYN_CMD; 586 587 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 588 sja1105_packing(p, &cmd->index, 19, 16, size, op); 589 } 590 591 static size_t sja1105et_cbs_entry_packing(void *buf, void *entry_ptr, 592 enum packing_op op) 593 { 594 const size_t size = SJA1105ET_SIZE_CBS_ENTRY; 595 struct sja1105_cbs_entry *entry = entry_ptr; 596 u8 *cmd = buf + size; 597 u32 *p = buf; 598 599 sja1105_packing(cmd, &entry->port, 5, 3, SJA1105_SIZE_DYN_CMD, op); 600 sja1105_packing(cmd, &entry->prio, 2, 0, SJA1105_SIZE_DYN_CMD, op); 601 sja1105_packing(p + 3, &entry->credit_lo, 31, 0, size, op); 602 sja1105_packing(p + 2, &entry->credit_hi, 31, 0, size, op); 603 sja1105_packing(p + 1, &entry->send_slope, 31, 0, size, op); 604 sja1105_packing(p + 0, &entry->idle_slope, 31, 0, size, op); 605 return size; 606 } 607 608 static void sja1105pqrs_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, 609 enum packing_op op) 610 { 611 u8 *p = buf + SJA1105PQRS_SIZE_CBS_ENTRY; 612 const int size = SJA1105_SIZE_DYN_CMD; 613 614 sja1105_packing(p, &cmd->valid, 31, 31, size, op); 615 sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); 616 sja1105_packing(p, &cmd->errors, 29, 29, size, op); 617 sja1105_packing(p, &cmd->index, 3, 0, size, op); 618 } 619 620 static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr, 621 enum packing_op op) 622 { 623 const size_t size = SJA1105PQRS_SIZE_CBS_ENTRY; 624 struct sja1105_cbs_entry *entry = entry_ptr; 625 626 sja1105_packing(buf, &entry->port, 159, 157, size, op); 627 sja1105_packing(buf, &entry->prio, 156, 154, size, op); 628 sja1105_packing(buf, &entry->credit_lo, 153, 122, size, op); 629 sja1105_packing(buf, &entry->credit_hi, 121, 90, size, op); 630 sja1105_packing(buf, &entry->send_slope, 89, 58, size, op); 631 sja1105_packing(buf, &entry->idle_slope, 57, 26, size, op); 632 return size; 633 } 634 635 #define OP_READ BIT(0) 636 #define OP_WRITE BIT(1) 637 #define OP_DEL BIT(2) 638 #define OP_SEARCH BIT(3) 639 640 /* SJA1105E/T: First generation */ 641 const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = { 642 [BLK_IDX_VL_LOOKUP] = { 643 .entry_packing = sja1105et_vl_lookup_entry_packing, 644 .cmd_packing = sja1105_vl_lookup_cmd_packing, 645 .access = OP_WRITE, 646 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 647 .packed_size = SJA1105ET_SIZE_VL_LOOKUP_DYN_CMD, 648 .addr = 0x35, 649 }, 650 [BLK_IDX_L2_LOOKUP] = { 651 .entry_packing = sja1105et_dyn_l2_lookup_entry_packing, 652 .cmd_packing = sja1105et_l2_lookup_cmd_packing, 653 .access = (OP_READ | OP_WRITE | OP_DEL), 654 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 655 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD, 656 .addr = 0x20, 657 }, 658 [BLK_IDX_MGMT_ROUTE] = { 659 .entry_packing = sja1105et_mgmt_route_entry_packing, 660 .cmd_packing = sja1105et_mgmt_route_cmd_packing, 661 .access = (OP_READ | OP_WRITE), 662 .max_entry_count = SJA1105_NUM_PORTS, 663 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD, 664 .addr = 0x20, 665 }, 666 [BLK_IDX_VLAN_LOOKUP] = { 667 .entry_packing = sja1105_vlan_lookup_entry_packing, 668 .cmd_packing = sja1105_vlan_lookup_cmd_packing, 669 .access = (OP_WRITE | OP_DEL), 670 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 671 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD, 672 .addr = 0x27, 673 }, 674 [BLK_IDX_L2_FORWARDING] = { 675 .entry_packing = sja1105_l2_forwarding_entry_packing, 676 .cmd_packing = sja1105_l2_forwarding_cmd_packing, 677 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 678 .access = OP_WRITE, 679 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD, 680 .addr = 0x24, 681 }, 682 [BLK_IDX_MAC_CONFIG] = { 683 .entry_packing = sja1105et_mac_config_entry_packing, 684 .cmd_packing = sja1105et_mac_config_cmd_packing, 685 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 686 .access = OP_WRITE, 687 .packed_size = SJA1105ET_SIZE_MAC_CONFIG_DYN_CMD, 688 .addr = 0x36, 689 }, 690 [BLK_IDX_L2_LOOKUP_PARAMS] = { 691 .entry_packing = sja1105et_l2_lookup_params_entry_packing, 692 .cmd_packing = sja1105et_l2_lookup_params_cmd_packing, 693 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 694 .access = OP_WRITE, 695 .packed_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, 696 .addr = 0x38, 697 }, 698 [BLK_IDX_GENERAL_PARAMS] = { 699 .entry_packing = sja1105et_general_params_entry_packing, 700 .cmd_packing = sja1105et_general_params_cmd_packing, 701 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 702 .access = OP_WRITE, 703 .packed_size = SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD, 704 .addr = 0x34, 705 }, 706 [BLK_IDX_RETAGGING] = { 707 .entry_packing = sja1105_retagging_entry_packing, 708 .cmd_packing = sja1105_retagging_cmd_packing, 709 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 710 .access = (OP_WRITE | OP_DEL), 711 .packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD, 712 .addr = 0x31, 713 }, 714 [BLK_IDX_CBS] = { 715 .entry_packing = sja1105et_cbs_entry_packing, 716 .cmd_packing = sja1105et_cbs_cmd_packing, 717 .max_entry_count = SJA1105ET_MAX_CBS_COUNT, 718 .access = OP_WRITE, 719 .packed_size = SJA1105ET_SIZE_CBS_DYN_CMD, 720 .addr = 0x2c, 721 }, 722 }; 723 724 /* SJA1105P/Q/R/S: Second generation */ 725 const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = { 726 [BLK_IDX_VL_LOOKUP] = { 727 .entry_packing = sja1105_vl_lookup_entry_packing, 728 .cmd_packing = sja1105_vl_lookup_cmd_packing, 729 .access = (OP_READ | OP_WRITE), 730 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 731 .packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD, 732 .addr = 0x47, 733 }, 734 [BLK_IDX_L2_LOOKUP] = { 735 .entry_packing = sja1105pqrs_dyn_l2_lookup_entry_packing, 736 .cmd_packing = sja1105pqrs_l2_lookup_cmd_packing, 737 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH), 738 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 739 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD, 740 .addr = 0x24, 741 }, 742 [BLK_IDX_MGMT_ROUTE] = { 743 .entry_packing = sja1105pqrs_mgmt_route_entry_packing, 744 .cmd_packing = sja1105pqrs_mgmt_route_cmd_packing, 745 .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH), 746 .max_entry_count = SJA1105_NUM_PORTS, 747 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD, 748 .addr = 0x24, 749 }, 750 [BLK_IDX_VLAN_LOOKUP] = { 751 .entry_packing = sja1105_vlan_lookup_entry_packing, 752 .cmd_packing = sja1105_vlan_lookup_cmd_packing, 753 .access = (OP_READ | OP_WRITE | OP_DEL), 754 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 755 .packed_size = SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD, 756 .addr = 0x2D, 757 }, 758 [BLK_IDX_L2_FORWARDING] = { 759 .entry_packing = sja1105_l2_forwarding_entry_packing, 760 .cmd_packing = sja1105_l2_forwarding_cmd_packing, 761 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 762 .access = OP_WRITE, 763 .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD, 764 .addr = 0x2A, 765 }, 766 [BLK_IDX_MAC_CONFIG] = { 767 .entry_packing = sja1105pqrs_mac_config_entry_packing, 768 .cmd_packing = sja1105pqrs_mac_config_cmd_packing, 769 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 770 .access = (OP_READ | OP_WRITE), 771 .packed_size = SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD, 772 .addr = 0x4B, 773 }, 774 [BLK_IDX_L2_LOOKUP_PARAMS] = { 775 .entry_packing = sja1105pqrs_l2_lookup_params_entry_packing, 776 .cmd_packing = sja1105pqrs_l2_lookup_params_cmd_packing, 777 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 778 .access = (OP_READ | OP_WRITE), 779 .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, 780 .addr = 0x54, 781 }, 782 [BLK_IDX_AVB_PARAMS] = { 783 .entry_packing = sja1105pqrs_avb_params_entry_packing, 784 .cmd_packing = sja1105pqrs_avb_params_cmd_packing, 785 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 786 .access = (OP_READ | OP_WRITE), 787 .packed_size = SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD, 788 .addr = 0x8003, 789 }, 790 [BLK_IDX_GENERAL_PARAMS] = { 791 .entry_packing = sja1105pqrs_general_params_entry_packing, 792 .cmd_packing = sja1105pqrs_general_params_cmd_packing, 793 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 794 .access = (OP_READ | OP_WRITE), 795 .packed_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD, 796 .addr = 0x3B, 797 }, 798 [BLK_IDX_RETAGGING] = { 799 .entry_packing = sja1105_retagging_entry_packing, 800 .cmd_packing = sja1105_retagging_cmd_packing, 801 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 802 .access = (OP_READ | OP_WRITE | OP_DEL), 803 .packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD, 804 .addr = 0x38, 805 }, 806 [BLK_IDX_CBS] = { 807 .entry_packing = sja1105pqrs_cbs_entry_packing, 808 .cmd_packing = sja1105pqrs_cbs_cmd_packing, 809 .max_entry_count = SJA1105PQRS_MAX_CBS_COUNT, 810 .access = OP_WRITE, 811 .packed_size = SJA1105PQRS_SIZE_CBS_DYN_CMD, 812 .addr = 0x32, 813 }, 814 }; 815 816 /* Provides read access to the settings through the dynamic interface 817 * of the switch. 818 * @blk_idx is used as key to select from the sja1105_dynamic_table_ops. 819 * The selection is limited by the hardware in respect to which 820 * configuration blocks can be read through the dynamic interface. 821 * @index is used to retrieve a particular table entry. If negative, 822 * (and if the @blk_idx supports the searching operation) a search 823 * is performed by the @entry parameter. 824 * @entry Type-casted to an unpacked structure that holds a table entry 825 * of the type specified in @blk_idx. 826 * Usually an output argument. If @index is negative, then this 827 * argument is used as input/output: it should be pre-populated 828 * with the element to search for. Entries which support the 829 * search operation will have an "index" field (not the @index 830 * argument to this function) and that is where the found index 831 * will be returned (or left unmodified - thus negative - if not 832 * found). 833 */ 834 int sja1105_dynamic_config_read(struct sja1105_private *priv, 835 enum sja1105_blk_idx blk_idx, 836 int index, void *entry) 837 { 838 const struct sja1105_dynamic_table_ops *ops; 839 struct sja1105_dyn_cmd cmd = {0}; 840 /* SPI payload buffer */ 841 u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0}; 842 int retries = 3; 843 int rc; 844 845 if (blk_idx >= BLK_IDX_MAX_DYN) 846 return -ERANGE; 847 848 ops = &priv->info->dyn_ops[blk_idx]; 849 850 if (index >= 0 && index >= ops->max_entry_count) 851 return -ERANGE; 852 if (index < 0 && !(ops->access & OP_SEARCH)) 853 return -EOPNOTSUPP; 854 if (!(ops->access & OP_READ)) 855 return -EOPNOTSUPP; 856 if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE) 857 return -ERANGE; 858 if (!ops->cmd_packing) 859 return -EOPNOTSUPP; 860 if (!ops->entry_packing) 861 return -EOPNOTSUPP; 862 863 cmd.valid = true; /* Trigger action on table entry */ 864 cmd.rdwrset = SPI_READ; /* Action is read */ 865 if (index < 0) { 866 /* Avoid copying a signed negative number to an u64 */ 867 cmd.index = 0; 868 cmd.search = true; 869 } else { 870 cmd.index = index; 871 cmd.search = false; 872 } 873 cmd.valident = true; 874 ops->cmd_packing(packed_buf, &cmd, PACK); 875 876 if (cmd.search) 877 ops->entry_packing(packed_buf, entry, PACK); 878 879 /* Send SPI write operation: read config table entry */ 880 rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, 881 ops->packed_size); 882 if (rc < 0) 883 return rc; 884 885 /* Loop until we have confirmation that hardware has finished 886 * processing the command and has cleared the VALID field 887 */ 888 do { 889 memset(packed_buf, 0, ops->packed_size); 890 891 /* Retrieve the read operation's result */ 892 rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, 893 ops->packed_size); 894 if (rc < 0) 895 return rc; 896 897 cmd = (struct sja1105_dyn_cmd) {0}; 898 ops->cmd_packing(packed_buf, &cmd, UNPACK); 899 /* UM10944: [valident] will always be found cleared 900 * during a read access with MGMTROUTE set. 901 * So don't error out in that case. 902 */ 903 if (!cmd.valident && blk_idx != BLK_IDX_MGMT_ROUTE) 904 return -ENOENT; 905 cpu_relax(); 906 } while (cmd.valid && --retries); 907 908 if (cmd.valid) 909 return -ETIMEDOUT; 910 911 /* Don't dereference possibly NULL pointer - maybe caller 912 * only wanted to see whether the entry existed or not. 913 */ 914 if (entry) 915 ops->entry_packing(packed_buf, entry, UNPACK); 916 return 0; 917 } 918 919 int sja1105_dynamic_config_write(struct sja1105_private *priv, 920 enum sja1105_blk_idx blk_idx, 921 int index, void *entry, bool keep) 922 { 923 const struct sja1105_dynamic_table_ops *ops; 924 struct sja1105_dyn_cmd cmd = {0}; 925 /* SPI payload buffer */ 926 u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0}; 927 int rc; 928 929 if (blk_idx >= BLK_IDX_MAX_DYN) 930 return -ERANGE; 931 932 ops = &priv->info->dyn_ops[blk_idx]; 933 934 if (index >= ops->max_entry_count) 935 return -ERANGE; 936 if (index < 0) 937 return -ERANGE; 938 if (!(ops->access & OP_WRITE)) 939 return -EOPNOTSUPP; 940 if (!keep && !(ops->access & OP_DEL)) 941 return -EOPNOTSUPP; 942 if (ops->packed_size > SJA1105_MAX_DYN_CMD_SIZE) 943 return -ERANGE; 944 945 cmd.valident = keep; /* If false, deletes entry */ 946 cmd.valid = true; /* Trigger action on table entry */ 947 cmd.rdwrset = SPI_WRITE; /* Action is write */ 948 cmd.index = index; 949 950 if (!ops->cmd_packing) 951 return -EOPNOTSUPP; 952 ops->cmd_packing(packed_buf, &cmd, PACK); 953 954 if (!ops->entry_packing) 955 return -EOPNOTSUPP; 956 /* Don't dereference potentially NULL pointer if just 957 * deleting a table entry is what was requested. For cases 958 * where 'index' field is physically part of entry structure, 959 * and needed here, we deal with that in the cmd_packing callback. 960 */ 961 if (keep) 962 ops->entry_packing(packed_buf, entry, PACK); 963 964 /* Send SPI write operation: read config table entry */ 965 rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, 966 ops->packed_size); 967 if (rc < 0) 968 return rc; 969 970 cmd = (struct sja1105_dyn_cmd) {0}; 971 ops->cmd_packing(packed_buf, &cmd, UNPACK); 972 if (cmd.errors) 973 return -EINVAL; 974 975 return 0; 976 } 977 978 static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly) 979 { 980 int i; 981 982 for (i = 0; i < 8; i++) { 983 if ((crc ^ byte) & (1 << 7)) { 984 crc <<= 1; 985 crc ^= poly; 986 } else { 987 crc <<= 1; 988 } 989 byte <<= 1; 990 } 991 return crc; 992 } 993 994 /* CRC8 algorithm with non-reversed input, non-reversed output, 995 * no input xor and no output xor. Code customized for receiving 996 * the SJA1105 E/T FDB keys (vlanid, macaddr) as input. CRC polynomial 997 * is also received as argument in the Koopman notation that the switch 998 * hardware stores it in. 999 */ 1000 u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid) 1001 { 1002 struct sja1105_l2_lookup_params_entry *l2_lookup_params = 1003 priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS].entries; 1004 u64 poly_koopman = l2_lookup_params->poly; 1005 /* Convert polynomial from Koopman to 'normal' notation */ 1006 u8 poly = (u8)(1 + (poly_koopman << 1)); 1007 u64 vlanid = l2_lookup_params->shared_learn ? 0 : vid; 1008 u64 input = (vlanid << 48) | ether_addr_to_u64(addr); 1009 u8 crc = 0; /* seed */ 1010 int i; 1011 1012 /* Mask the eight bytes starting from MSB one at a time */ 1013 for (i = 56; i >= 0; i -= 8) { 1014 u8 byte = (input & (0xffull << i)) >> i; 1015 1016 crc = sja1105_crc8_add(crc, byte, poly); 1017 } 1018 return crc; 1019 } 1020