1 // SPDX-License-Identifier: BSD-3-Clause 2 /* Copyright (c) 2016-2018, NXP Semiconductors 3 * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com> 4 */ 5 #include "sja1105_static_config.h" 6 #include <linux/crc32.h> 7 #include <linux/slab.h> 8 #include <linux/string.h> 9 #include <linux/errno.h> 10 11 /* Convenience wrappers over the generic packing functions. These take into 12 * account the SJA1105 memory layout quirks and provide some level of 13 * programmer protection against incorrect API use. The errors are not expected 14 * to occur durring runtime, therefore printing and swallowing them here is 15 * appropriate instead of clutterring up higher-level code. 16 */ 17 void sja1105_pack(void *buf, const u64 *val, int start, int end, size_t len) 18 { 19 int rc = packing(buf, (u64 *)val, start, end, len, 20 PACK, QUIRK_LSW32_IS_FIRST); 21 22 if (likely(!rc)) 23 return; 24 25 if (rc == -EINVAL) { 26 pr_err("Start bit (%d) expected to be larger than end (%d)\n", 27 start, end); 28 } else if (rc == -ERANGE) { 29 if ((start - end + 1) > 64) 30 pr_err("Field %d-%d too large for 64 bits!\n", 31 start, end); 32 else 33 pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n", 34 *val, start, end); 35 } 36 dump_stack(); 37 } 38 39 void sja1105_unpack(const void *buf, u64 *val, int start, int end, size_t len) 40 { 41 int rc = packing((void *)buf, val, start, end, len, 42 UNPACK, QUIRK_LSW32_IS_FIRST); 43 44 if (likely(!rc)) 45 return; 46 47 if (rc == -EINVAL) 48 pr_err("Start bit (%d) expected to be larger than end (%d)\n", 49 start, end); 50 else if (rc == -ERANGE) 51 pr_err("Field %d-%d too large for 64 bits!\n", 52 start, end); 53 dump_stack(); 54 } 55 56 void sja1105_packing(void *buf, u64 *val, int start, int end, 57 size_t len, enum packing_op op) 58 { 59 int rc = packing(buf, val, start, end, len, op, QUIRK_LSW32_IS_FIRST); 60 61 if (likely(!rc)) 62 return; 63 64 if (rc == -EINVAL) { 65 pr_err("Start bit (%d) expected to be larger than end (%d)\n", 66 start, end); 67 } else if (rc == -ERANGE) { 68 if ((start - end + 1) > 64) 69 pr_err("Field %d-%d too large for 64 bits!\n", 70 start, end); 71 else 72 pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n", 73 *val, start, end); 74 } 75 dump_stack(); 76 } 77 78 /* Little-endian Ethernet CRC32 of data packed as big-endian u32 words */ 79 u32 sja1105_crc32(const void *buf, size_t len) 80 { 81 unsigned int i; 82 u64 word; 83 u32 crc; 84 85 /* seed */ 86 crc = ~0; 87 for (i = 0; i < len; i += 4) { 88 sja1105_unpack(buf + i, &word, 31, 0, 4); 89 crc = crc32_le(crc, (u8 *)&word, 4); 90 } 91 return ~crc; 92 } 93 94 static size_t sja1105et_avb_params_entry_packing(void *buf, void *entry_ptr, 95 enum packing_op op) 96 { 97 const size_t size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY; 98 struct sja1105_avb_params_entry *entry = entry_ptr; 99 100 sja1105_packing(buf, &entry->destmeta, 95, 48, size, op); 101 sja1105_packing(buf, &entry->srcmeta, 47, 0, size, op); 102 return size; 103 } 104 105 size_t sja1105pqrs_avb_params_entry_packing(void *buf, void *entry_ptr, 106 enum packing_op op) 107 { 108 const size_t size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY; 109 struct sja1105_avb_params_entry *entry = entry_ptr; 110 111 sja1105_packing(buf, &entry->cas_master, 126, 126, size, op); 112 sja1105_packing(buf, &entry->destmeta, 125, 78, size, op); 113 sja1105_packing(buf, &entry->srcmeta, 77, 30, size, op); 114 return size; 115 } 116 117 static size_t sja1105et_general_params_entry_packing(void *buf, void *entry_ptr, 118 enum packing_op op) 119 { 120 const size_t size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY; 121 struct sja1105_general_params_entry *entry = entry_ptr; 122 123 sja1105_packing(buf, &entry->vllupformat, 319, 319, size, op); 124 sja1105_packing(buf, &entry->mirr_ptacu, 318, 318, size, op); 125 sja1105_packing(buf, &entry->switchid, 317, 315, size, op); 126 sja1105_packing(buf, &entry->hostprio, 314, 312, size, op); 127 sja1105_packing(buf, &entry->mac_fltres1, 311, 264, size, op); 128 sja1105_packing(buf, &entry->mac_fltres0, 263, 216, size, op); 129 sja1105_packing(buf, &entry->mac_flt1, 215, 168, size, op); 130 sja1105_packing(buf, &entry->mac_flt0, 167, 120, size, op); 131 sja1105_packing(buf, &entry->incl_srcpt1, 119, 119, size, op); 132 sja1105_packing(buf, &entry->incl_srcpt0, 118, 118, size, op); 133 sja1105_packing(buf, &entry->send_meta1, 117, 117, size, op); 134 sja1105_packing(buf, &entry->send_meta0, 116, 116, size, op); 135 sja1105_packing(buf, &entry->casc_port, 115, 113, size, op); 136 sja1105_packing(buf, &entry->host_port, 112, 110, size, op); 137 sja1105_packing(buf, &entry->mirr_port, 109, 107, size, op); 138 sja1105_packing(buf, &entry->vlmarker, 106, 75, size, op); 139 sja1105_packing(buf, &entry->vlmask, 74, 43, size, op); 140 sja1105_packing(buf, &entry->tpid, 42, 27, size, op); 141 sja1105_packing(buf, &entry->ignore2stf, 26, 26, size, op); 142 sja1105_packing(buf, &entry->tpid2, 25, 10, size, op); 143 return size; 144 } 145 146 /* TPID and TPID2 are intentionally reversed so that semantic 147 * compatibility with E/T is kept. 148 */ 149 size_t sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, 150 enum packing_op op) 151 { 152 const size_t size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY; 153 struct sja1105_general_params_entry *entry = entry_ptr; 154 155 sja1105_packing(buf, &entry->vllupformat, 351, 351, size, op); 156 sja1105_packing(buf, &entry->mirr_ptacu, 350, 350, size, op); 157 sja1105_packing(buf, &entry->switchid, 349, 347, size, op); 158 sja1105_packing(buf, &entry->hostprio, 346, 344, size, op); 159 sja1105_packing(buf, &entry->mac_fltres1, 343, 296, size, op); 160 sja1105_packing(buf, &entry->mac_fltres0, 295, 248, size, op); 161 sja1105_packing(buf, &entry->mac_flt1, 247, 200, size, op); 162 sja1105_packing(buf, &entry->mac_flt0, 199, 152, size, op); 163 sja1105_packing(buf, &entry->incl_srcpt1, 151, 151, size, op); 164 sja1105_packing(buf, &entry->incl_srcpt0, 150, 150, size, op); 165 sja1105_packing(buf, &entry->send_meta1, 149, 149, size, op); 166 sja1105_packing(buf, &entry->send_meta0, 148, 148, size, op); 167 sja1105_packing(buf, &entry->casc_port, 147, 145, size, op); 168 sja1105_packing(buf, &entry->host_port, 144, 142, size, op); 169 sja1105_packing(buf, &entry->mirr_port, 141, 139, size, op); 170 sja1105_packing(buf, &entry->vlmarker, 138, 107, size, op); 171 sja1105_packing(buf, &entry->vlmask, 106, 75, size, op); 172 sja1105_packing(buf, &entry->tpid2, 74, 59, size, op); 173 sja1105_packing(buf, &entry->ignore2stf, 58, 58, size, op); 174 sja1105_packing(buf, &entry->tpid, 57, 42, size, op); 175 sja1105_packing(buf, &entry->queue_ts, 41, 41, size, op); 176 sja1105_packing(buf, &entry->egrmirrvid, 40, 29, size, op); 177 sja1105_packing(buf, &entry->egrmirrpcp, 28, 26, size, op); 178 sja1105_packing(buf, &entry->egrmirrdei, 25, 25, size, op); 179 sja1105_packing(buf, &entry->replay_port, 24, 22, size, op); 180 return size; 181 } 182 183 size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr, 184 enum packing_op op) 185 { 186 struct sja1105_general_params_entry *entry = entry_ptr; 187 const size_t size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY; 188 189 sja1105_packing(buf, &entry->vllupformat, 447, 447, size, op); 190 sja1105_packing(buf, &entry->mirr_ptacu, 446, 446, size, op); 191 sja1105_packing(buf, &entry->switchid, 445, 442, size, op); 192 sja1105_packing(buf, &entry->hostprio, 441, 439, size, op); 193 sja1105_packing(buf, &entry->mac_fltres1, 438, 391, size, op); 194 sja1105_packing(buf, &entry->mac_fltres0, 390, 343, size, op); 195 sja1105_packing(buf, &entry->mac_flt1, 342, 295, size, op); 196 sja1105_packing(buf, &entry->mac_flt0, 294, 247, size, op); 197 sja1105_packing(buf, &entry->incl_srcpt1, 246, 246, size, op); 198 sja1105_packing(buf, &entry->incl_srcpt0, 245, 245, size, op); 199 sja1105_packing(buf, &entry->send_meta1, 244, 244, size, op); 200 sja1105_packing(buf, &entry->send_meta0, 243, 243, size, op); 201 sja1105_packing(buf, &entry->casc_port, 242, 232, size, op); 202 sja1105_packing(buf, &entry->host_port, 231, 228, size, op); 203 sja1105_packing(buf, &entry->mirr_port, 227, 224, size, op); 204 sja1105_packing(buf, &entry->vlmarker, 223, 192, size, op); 205 sja1105_packing(buf, &entry->vlmask, 191, 160, size, op); 206 sja1105_packing(buf, &entry->tpid2, 159, 144, size, op); 207 sja1105_packing(buf, &entry->ignore2stf, 143, 143, size, op); 208 sja1105_packing(buf, &entry->tpid, 142, 127, size, op); 209 sja1105_packing(buf, &entry->queue_ts, 126, 126, size, op); 210 sja1105_packing(buf, &entry->egrmirrvid, 125, 114, size, op); 211 sja1105_packing(buf, &entry->egrmirrpcp, 113, 111, size, op); 212 sja1105_packing(buf, &entry->egrmirrdei, 110, 110, size, op); 213 sja1105_packing(buf, &entry->replay_port, 109, 106, size, op); 214 sja1105_packing(buf, &entry->tdmaconfigidx, 70, 67, size, op); 215 sja1105_packing(buf, &entry->header_type, 64, 49, size, op); 216 sja1105_packing(buf, &entry->tte_en, 16, 16, size, op); 217 return size; 218 } 219 220 static size_t 221 sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, 222 enum packing_op op) 223 { 224 const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY; 225 struct sja1105_l2_forwarding_params_entry *entry = entry_ptr; 226 int offset, i; 227 228 sja1105_packing(buf, &entry->max_dynp, 95, 93, size, op); 229 for (i = 0, offset = 13; i < 8; i++, offset += 10) 230 sja1105_packing(buf, &entry->part_spc[i], 231 offset + 9, offset + 0, size, op); 232 return size; 233 } 234 235 size_t sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, 236 enum packing_op op) 237 { 238 struct sja1105_l2_forwarding_params_entry *entry = entry_ptr; 239 const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY; 240 int offset, i; 241 242 sja1105_packing(buf, &entry->max_dynp, 95, 93, size, op); 243 for (i = 0, offset = 5; i < 8; i++, offset += 11) 244 sja1105_packing(buf, &entry->part_spc[i], 245 offset + 10, offset + 0, size, op); 246 return size; 247 } 248 249 size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr, 250 enum packing_op op) 251 { 252 const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY; 253 struct sja1105_l2_forwarding_entry *entry = entry_ptr; 254 int offset, i; 255 256 sja1105_packing(buf, &entry->bc_domain, 63, 59, size, op); 257 sja1105_packing(buf, &entry->reach_port, 58, 54, size, op); 258 sja1105_packing(buf, &entry->fl_domain, 53, 49, size, op); 259 for (i = 0, offset = 25; i < 8; i++, offset += 3) 260 sja1105_packing(buf, &entry->vlan_pmap[i], 261 offset + 2, offset + 0, size, op); 262 return size; 263 } 264 265 size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr, 266 enum packing_op op) 267 { 268 struct sja1105_l2_forwarding_entry *entry = entry_ptr; 269 const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY; 270 int offset, i; 271 272 if (entry->type_egrpcp2outputq) { 273 for (i = 0, offset = 31; i < SJA1110_NUM_PORTS; 274 i++, offset += 3) { 275 sja1105_packing(buf, &entry->vlan_pmap[i], 276 offset + 2, offset + 0, size, op); 277 } 278 } else { 279 sja1105_packing(buf, &entry->bc_domain, 63, 53, size, op); 280 sja1105_packing(buf, &entry->reach_port, 52, 42, size, op); 281 sja1105_packing(buf, &entry->fl_domain, 41, 31, size, op); 282 } 283 return size; 284 } 285 286 static size_t 287 sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, 288 enum packing_op op) 289 { 290 const size_t size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY; 291 struct sja1105_l2_lookup_params_entry *entry = entry_ptr; 292 293 sja1105_packing(buf, &entry->maxage, 31, 17, size, op); 294 sja1105_packing(buf, &entry->dyn_tbsz, 16, 14, size, op); 295 sja1105_packing(buf, &entry->poly, 13, 6, size, op); 296 sja1105_packing(buf, &entry->shared_learn, 5, 5, size, op); 297 sja1105_packing(buf, &entry->no_enf_hostprt, 4, 4, size, op); 298 sja1105_packing(buf, &entry->no_mgmt_learn, 3, 3, size, op); 299 return size; 300 } 301 302 size_t sja1105pqrs_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, 303 enum packing_op op) 304 { 305 const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY; 306 struct sja1105_l2_lookup_params_entry *entry = entry_ptr; 307 int offset, i; 308 309 for (i = 0, offset = 58; i < 5; i++, offset += 11) 310 sja1105_packing(buf, &entry->maxaddrp[i], 311 offset + 10, offset + 0, size, op); 312 sja1105_packing(buf, &entry->maxage, 57, 43, size, op); 313 sja1105_packing(buf, &entry->start_dynspc, 42, 33, size, op); 314 sja1105_packing(buf, &entry->drpnolearn, 32, 28, size, op); 315 sja1105_packing(buf, &entry->shared_learn, 27, 27, size, op); 316 sja1105_packing(buf, &entry->no_enf_hostprt, 26, 26, size, op); 317 sja1105_packing(buf, &entry->no_mgmt_learn, 25, 25, size, op); 318 sja1105_packing(buf, &entry->use_static, 24, 24, size, op); 319 sja1105_packing(buf, &entry->owr_dyn, 23, 23, size, op); 320 sja1105_packing(buf, &entry->learn_once, 22, 22, size, op); 321 return size; 322 } 323 324 size_t sja1110_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, 325 enum packing_op op) 326 { 327 struct sja1105_l2_lookup_params_entry *entry = entry_ptr; 328 const size_t size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY; 329 int offset, i; 330 331 for (i = 0, offset = 70; i < SJA1110_NUM_PORTS; i++, offset += 11) 332 sja1105_packing(buf, &entry->maxaddrp[i], 333 offset + 10, offset + 0, size, op); 334 sja1105_packing(buf, &entry->maxage, 69, 55, size, op); 335 sja1105_packing(buf, &entry->start_dynspc, 54, 45, size, op); 336 sja1105_packing(buf, &entry->drpnolearn, 44, 34, size, op); 337 sja1105_packing(buf, &entry->shared_learn, 33, 33, size, op); 338 sja1105_packing(buf, &entry->no_enf_hostprt, 32, 32, size, op); 339 sja1105_packing(buf, &entry->no_mgmt_learn, 31, 31, size, op); 340 sja1105_packing(buf, &entry->use_static, 30, 30, size, op); 341 sja1105_packing(buf, &entry->owr_dyn, 29, 29, size, op); 342 sja1105_packing(buf, &entry->learn_once, 28, 28, size, op); 343 return size; 344 } 345 346 size_t sja1105et_l2_lookup_entry_packing(void *buf, void *entry_ptr, 347 enum packing_op op) 348 { 349 const size_t size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY; 350 struct sja1105_l2_lookup_entry *entry = entry_ptr; 351 352 sja1105_packing(buf, &entry->vlanid, 95, 84, size, op); 353 sja1105_packing(buf, &entry->macaddr, 83, 36, size, op); 354 sja1105_packing(buf, &entry->destports, 35, 31, size, op); 355 sja1105_packing(buf, &entry->enfport, 30, 30, size, op); 356 sja1105_packing(buf, &entry->index, 29, 20, size, op); 357 return size; 358 } 359 360 size_t sja1105pqrs_l2_lookup_entry_packing(void *buf, void *entry_ptr, 361 enum packing_op op) 362 { 363 const size_t size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; 364 struct sja1105_l2_lookup_entry *entry = entry_ptr; 365 366 if (entry->lockeds) { 367 sja1105_packing(buf, &entry->tsreg, 159, 159, size, op); 368 sja1105_packing(buf, &entry->mirrvlan, 158, 147, size, op); 369 sja1105_packing(buf, &entry->takets, 146, 146, size, op); 370 sja1105_packing(buf, &entry->mirr, 145, 145, size, op); 371 sja1105_packing(buf, &entry->retag, 144, 144, size, op); 372 } else { 373 sja1105_packing(buf, &entry->touched, 159, 159, size, op); 374 sja1105_packing(buf, &entry->age, 158, 144, size, op); 375 } 376 sja1105_packing(buf, &entry->mask_iotag, 143, 143, size, op); 377 sja1105_packing(buf, &entry->mask_vlanid, 142, 131, size, op); 378 sja1105_packing(buf, &entry->mask_macaddr, 130, 83, size, op); 379 sja1105_packing(buf, &entry->iotag, 82, 82, size, op); 380 sja1105_packing(buf, &entry->vlanid, 81, 70, size, op); 381 sja1105_packing(buf, &entry->macaddr, 69, 22, size, op); 382 sja1105_packing(buf, &entry->destports, 21, 17, size, op); 383 sja1105_packing(buf, &entry->enfport, 16, 16, size, op); 384 sja1105_packing(buf, &entry->index, 15, 6, size, op); 385 return size; 386 } 387 388 size_t sja1110_l2_lookup_entry_packing(void *buf, void *entry_ptr, 389 enum packing_op op) 390 { 391 const size_t size = SJA1110_SIZE_L2_LOOKUP_ENTRY; 392 struct sja1105_l2_lookup_entry *entry = entry_ptr; 393 394 if (entry->lockeds) { 395 sja1105_packing(buf, &entry->trap, 168, 168, size, op); 396 sja1105_packing(buf, &entry->mirrvlan, 167, 156, size, op); 397 sja1105_packing(buf, &entry->takets, 155, 155, size, op); 398 sja1105_packing(buf, &entry->mirr, 154, 154, size, op); 399 sja1105_packing(buf, &entry->retag, 153, 153, size, op); 400 } else { 401 sja1105_packing(buf, &entry->touched, 168, 168, size, op); 402 sja1105_packing(buf, &entry->age, 167, 153, size, op); 403 } 404 sja1105_packing(buf, &entry->mask_iotag, 152, 152, size, op); 405 sja1105_packing(buf, &entry->mask_vlanid, 151, 140, size, op); 406 sja1105_packing(buf, &entry->mask_macaddr, 139, 92, size, op); 407 sja1105_packing(buf, &entry->mask_srcport, 91, 88, size, op); 408 sja1105_packing(buf, &entry->iotag, 87, 87, size, op); 409 sja1105_packing(buf, &entry->vlanid, 86, 75, size, op); 410 sja1105_packing(buf, &entry->macaddr, 74, 27, size, op); 411 sja1105_packing(buf, &entry->srcport, 26, 23, size, op); 412 sja1105_packing(buf, &entry->destports, 22, 12, size, op); 413 sja1105_packing(buf, &entry->enfport, 11, 11, size, op); 414 sja1105_packing(buf, &entry->index, 10, 1, size, op); 415 return size; 416 } 417 418 static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr, 419 enum packing_op op) 420 { 421 const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY; 422 struct sja1105_l2_policing_entry *entry = entry_ptr; 423 424 sja1105_packing(buf, &entry->sharindx, 63, 58, size, op); 425 sja1105_packing(buf, &entry->smax, 57, 42, size, op); 426 sja1105_packing(buf, &entry->rate, 41, 26, size, op); 427 sja1105_packing(buf, &entry->maxlen, 25, 15, size, op); 428 sja1105_packing(buf, &entry->partition, 14, 12, size, op); 429 return size; 430 } 431 432 size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr, 433 enum packing_op op) 434 { 435 struct sja1105_l2_policing_entry *entry = entry_ptr; 436 const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY; 437 438 sja1105_packing(buf, &entry->sharindx, 63, 57, size, op); 439 sja1105_packing(buf, &entry->smax, 56, 39, size, op); 440 sja1105_packing(buf, &entry->rate, 38, 21, size, op); 441 sja1105_packing(buf, &entry->maxlen, 20, 10, size, op); 442 sja1105_packing(buf, &entry->partition, 9, 7, size, op); 443 return size; 444 } 445 446 static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr, 447 enum packing_op op) 448 { 449 const size_t size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY; 450 struct sja1105_mac_config_entry *entry = entry_ptr; 451 int offset, i; 452 453 for (i = 0, offset = 72; i < 8; i++, offset += 19) { 454 sja1105_packing(buf, &entry->enabled[i], 455 offset + 0, offset + 0, size, op); 456 sja1105_packing(buf, &entry->base[i], 457 offset + 9, offset + 1, size, op); 458 sja1105_packing(buf, &entry->top[i], 459 offset + 18, offset + 10, size, op); 460 } 461 sja1105_packing(buf, &entry->ifg, 71, 67, size, op); 462 sja1105_packing(buf, &entry->speed, 66, 65, size, op); 463 sja1105_packing(buf, &entry->tp_delin, 64, 49, size, op); 464 sja1105_packing(buf, &entry->tp_delout, 48, 33, size, op); 465 sja1105_packing(buf, &entry->maxage, 32, 25, size, op); 466 sja1105_packing(buf, &entry->vlanprio, 24, 22, size, op); 467 sja1105_packing(buf, &entry->vlanid, 21, 10, size, op); 468 sja1105_packing(buf, &entry->ing_mirr, 9, 9, size, op); 469 sja1105_packing(buf, &entry->egr_mirr, 8, 8, size, op); 470 sja1105_packing(buf, &entry->drpnona664, 7, 7, size, op); 471 sja1105_packing(buf, &entry->drpdtag, 6, 6, size, op); 472 sja1105_packing(buf, &entry->drpuntag, 5, 5, size, op); 473 sja1105_packing(buf, &entry->retag, 4, 4, size, op); 474 sja1105_packing(buf, &entry->dyn_learn, 3, 3, size, op); 475 sja1105_packing(buf, &entry->egress, 2, 2, size, op); 476 sja1105_packing(buf, &entry->ingress, 1, 1, size, op); 477 return size; 478 } 479 480 size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr, 481 enum packing_op op) 482 { 483 const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY; 484 struct sja1105_mac_config_entry *entry = entry_ptr; 485 int offset, i; 486 487 for (i = 0, offset = 104; i < 8; i++, offset += 19) { 488 sja1105_packing(buf, &entry->enabled[i], 489 offset + 0, offset + 0, size, op); 490 sja1105_packing(buf, &entry->base[i], 491 offset + 9, offset + 1, size, op); 492 sja1105_packing(buf, &entry->top[i], 493 offset + 18, offset + 10, size, op); 494 } 495 sja1105_packing(buf, &entry->ifg, 103, 99, size, op); 496 sja1105_packing(buf, &entry->speed, 98, 97, size, op); 497 sja1105_packing(buf, &entry->tp_delin, 96, 81, size, op); 498 sja1105_packing(buf, &entry->tp_delout, 80, 65, size, op); 499 sja1105_packing(buf, &entry->maxage, 64, 57, size, op); 500 sja1105_packing(buf, &entry->vlanprio, 56, 54, size, op); 501 sja1105_packing(buf, &entry->vlanid, 53, 42, size, op); 502 sja1105_packing(buf, &entry->ing_mirr, 41, 41, size, op); 503 sja1105_packing(buf, &entry->egr_mirr, 40, 40, size, op); 504 sja1105_packing(buf, &entry->drpnona664, 39, 39, size, op); 505 sja1105_packing(buf, &entry->drpdtag, 38, 38, size, op); 506 sja1105_packing(buf, &entry->drpuntag, 35, 35, size, op); 507 sja1105_packing(buf, &entry->retag, 34, 34, size, op); 508 sja1105_packing(buf, &entry->dyn_learn, 33, 33, size, op); 509 sja1105_packing(buf, &entry->egress, 32, 32, size, op); 510 sja1105_packing(buf, &entry->ingress, 31, 31, size, op); 511 return size; 512 } 513 514 size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr, 515 enum packing_op op) 516 { 517 const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY; 518 struct sja1105_mac_config_entry *entry = entry_ptr; 519 int offset, i; 520 521 for (i = 0, offset = 104; i < 8; i++, offset += 19) { 522 sja1105_packing(buf, &entry->enabled[i], 523 offset + 0, offset + 0, size, op); 524 sja1105_packing(buf, &entry->base[i], 525 offset + 9, offset + 1, size, op); 526 sja1105_packing(buf, &entry->top[i], 527 offset + 18, offset + 10, size, op); 528 } 529 sja1105_packing(buf, &entry->speed, 98, 96, size, op); 530 sja1105_packing(buf, &entry->tp_delin, 95, 80, size, op); 531 sja1105_packing(buf, &entry->tp_delout, 79, 64, size, op); 532 sja1105_packing(buf, &entry->maxage, 63, 56, size, op); 533 sja1105_packing(buf, &entry->vlanprio, 55, 53, size, op); 534 sja1105_packing(buf, &entry->vlanid, 52, 41, size, op); 535 sja1105_packing(buf, &entry->ing_mirr, 40, 40, size, op); 536 sja1105_packing(buf, &entry->egr_mirr, 39, 39, size, op); 537 sja1105_packing(buf, &entry->drpnona664, 38, 38, size, op); 538 sja1105_packing(buf, &entry->drpdtag, 37, 37, size, op); 539 sja1105_packing(buf, &entry->drpuntag, 34, 34, size, op); 540 sja1105_packing(buf, &entry->retag, 33, 33, size, op); 541 sja1105_packing(buf, &entry->dyn_learn, 32, 32, size, op); 542 sja1105_packing(buf, &entry->egress, 31, 31, size, op); 543 sja1105_packing(buf, &entry->ingress, 30, 30, size, op); 544 sja1105_packing(buf, &entry->ifg, 10, 5, size, op); 545 return size; 546 } 547 548 static size_t 549 sja1105_schedule_entry_points_params_entry_packing(void *buf, void *entry_ptr, 550 enum packing_op op) 551 { 552 struct sja1105_schedule_entry_points_params_entry *entry = entry_ptr; 553 const size_t size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY; 554 555 sja1105_packing(buf, &entry->clksrc, 31, 30, size, op); 556 sja1105_packing(buf, &entry->actsubsch, 29, 27, size, op); 557 return size; 558 } 559 560 static size_t 561 sja1105_schedule_entry_points_entry_packing(void *buf, void *entry_ptr, 562 enum packing_op op) 563 { 564 struct sja1105_schedule_entry_points_entry *entry = entry_ptr; 565 const size_t size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY; 566 567 sja1105_packing(buf, &entry->subschindx, 31, 29, size, op); 568 sja1105_packing(buf, &entry->delta, 28, 11, size, op); 569 sja1105_packing(buf, &entry->address, 10, 1, size, op); 570 return size; 571 } 572 573 static size_t 574 sja1110_schedule_entry_points_entry_packing(void *buf, void *entry_ptr, 575 enum packing_op op) 576 { 577 struct sja1105_schedule_entry_points_entry *entry = entry_ptr; 578 const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY; 579 580 sja1105_packing(buf, &entry->subschindx, 63, 61, size, op); 581 sja1105_packing(buf, &entry->delta, 60, 43, size, op); 582 sja1105_packing(buf, &entry->address, 42, 31, size, op); 583 return size; 584 } 585 586 static size_t sja1105_schedule_params_entry_packing(void *buf, void *entry_ptr, 587 enum packing_op op) 588 { 589 const size_t size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY; 590 struct sja1105_schedule_params_entry *entry = entry_ptr; 591 int offset, i; 592 593 for (i = 0, offset = 16; i < 8; i++, offset += 10) 594 sja1105_packing(buf, &entry->subscheind[i], 595 offset + 9, offset + 0, size, op); 596 return size; 597 } 598 599 static size_t sja1110_schedule_params_entry_packing(void *buf, void *entry_ptr, 600 enum packing_op op) 601 { 602 struct sja1105_schedule_params_entry *entry = entry_ptr; 603 const size_t size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY; 604 int offset, i; 605 606 for (i = 0, offset = 0; i < 8; i++, offset += 12) 607 sja1105_packing(buf, &entry->subscheind[i], 608 offset + 11, offset + 0, size, op); 609 return size; 610 } 611 612 static size_t sja1105_schedule_entry_packing(void *buf, void *entry_ptr, 613 enum packing_op op) 614 { 615 const size_t size = SJA1105_SIZE_SCHEDULE_ENTRY; 616 struct sja1105_schedule_entry *entry = entry_ptr; 617 618 sja1105_packing(buf, &entry->winstindex, 63, 54, size, op); 619 sja1105_packing(buf, &entry->winend, 53, 53, size, op); 620 sja1105_packing(buf, &entry->winst, 52, 52, size, op); 621 sja1105_packing(buf, &entry->destports, 51, 47, size, op); 622 sja1105_packing(buf, &entry->setvalid, 46, 46, size, op); 623 sja1105_packing(buf, &entry->txen, 45, 45, size, op); 624 sja1105_packing(buf, &entry->resmedia_en, 44, 44, size, op); 625 sja1105_packing(buf, &entry->resmedia, 43, 36, size, op); 626 sja1105_packing(buf, &entry->vlindex, 35, 26, size, op); 627 sja1105_packing(buf, &entry->delta, 25, 8, size, op); 628 return size; 629 } 630 631 static size_t sja1110_schedule_entry_packing(void *buf, void *entry_ptr, 632 enum packing_op op) 633 { 634 const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY; 635 struct sja1105_schedule_entry *entry = entry_ptr; 636 637 sja1105_packing(buf, &entry->winstindex, 95, 84, size, op); 638 sja1105_packing(buf, &entry->winend, 83, 83, size, op); 639 sja1105_packing(buf, &entry->winst, 82, 82, size, op); 640 sja1105_packing(buf, &entry->destports, 81, 71, size, op); 641 sja1105_packing(buf, &entry->setvalid, 70, 70, size, op); 642 sja1105_packing(buf, &entry->txen, 69, 69, size, op); 643 sja1105_packing(buf, &entry->resmedia_en, 68, 68, size, op); 644 sja1105_packing(buf, &entry->resmedia, 67, 60, size, op); 645 sja1105_packing(buf, &entry->vlindex, 59, 48, size, op); 646 sja1105_packing(buf, &entry->delta, 47, 30, size, op); 647 return size; 648 } 649 650 static size_t 651 sja1105_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr, 652 enum packing_op op) 653 { 654 struct sja1105_vl_forwarding_params_entry *entry = entry_ptr; 655 const size_t size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY; 656 int offset, i; 657 658 for (i = 0, offset = 16; i < 8; i++, offset += 10) 659 sja1105_packing(buf, &entry->partspc[i], 660 offset + 9, offset + 0, size, op); 661 sja1105_packing(buf, &entry->debugen, 15, 15, size, op); 662 return size; 663 } 664 665 static size_t 666 sja1110_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr, 667 enum packing_op op) 668 { 669 struct sja1105_vl_forwarding_params_entry *entry = entry_ptr; 670 const size_t size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY; 671 int offset, i; 672 673 for (i = 0, offset = 8; i < 8; i++, offset += 11) 674 sja1105_packing(buf, &entry->partspc[i], 675 offset + 10, offset + 0, size, op); 676 sja1105_packing(buf, &entry->debugen, 7, 7, size, op); 677 return size; 678 } 679 680 static size_t sja1105_vl_forwarding_entry_packing(void *buf, void *entry_ptr, 681 enum packing_op op) 682 { 683 struct sja1105_vl_forwarding_entry *entry = entry_ptr; 684 const size_t size = SJA1105_SIZE_VL_FORWARDING_ENTRY; 685 686 sja1105_packing(buf, &entry->type, 31, 31, size, op); 687 sja1105_packing(buf, &entry->priority, 30, 28, size, op); 688 sja1105_packing(buf, &entry->partition, 27, 25, size, op); 689 sja1105_packing(buf, &entry->destports, 24, 20, size, op); 690 return size; 691 } 692 693 static size_t sja1110_vl_forwarding_entry_packing(void *buf, void *entry_ptr, 694 enum packing_op op) 695 { 696 struct sja1105_vl_forwarding_entry *entry = entry_ptr; 697 const size_t size = SJA1105_SIZE_VL_FORWARDING_ENTRY; 698 699 sja1105_packing(buf, &entry->type, 31, 31, size, op); 700 sja1105_packing(buf, &entry->priority, 30, 28, size, op); 701 sja1105_packing(buf, &entry->partition, 27, 25, size, op); 702 sja1105_packing(buf, &entry->destports, 24, 14, size, op); 703 return size; 704 } 705 706 size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr, 707 enum packing_op op) 708 { 709 struct sja1105_vl_lookup_entry *entry = entry_ptr; 710 const size_t size = SJA1105_SIZE_VL_LOOKUP_ENTRY; 711 712 if (entry->format == SJA1105_VL_FORMAT_PSFP) { 713 /* Interpreting vllupformat as 0 */ 714 sja1105_packing(buf, &entry->destports, 715 95, 91, size, op); 716 sja1105_packing(buf, &entry->iscritical, 717 90, 90, size, op); 718 sja1105_packing(buf, &entry->macaddr, 719 89, 42, size, op); 720 sja1105_packing(buf, &entry->vlanid, 721 41, 30, size, op); 722 sja1105_packing(buf, &entry->port, 723 29, 27, size, op); 724 sja1105_packing(buf, &entry->vlanprior, 725 26, 24, size, op); 726 } else { 727 /* Interpreting vllupformat as 1 */ 728 sja1105_packing(buf, &entry->egrmirr, 729 95, 91, size, op); 730 sja1105_packing(buf, &entry->ingrmirr, 731 90, 90, size, op); 732 sja1105_packing(buf, &entry->vlid, 733 57, 42, size, op); 734 sja1105_packing(buf, &entry->port, 735 29, 27, size, op); 736 } 737 return size; 738 } 739 740 size_t sja1110_vl_lookup_entry_packing(void *buf, void *entry_ptr, 741 enum packing_op op) 742 { 743 struct sja1105_vl_lookup_entry *entry = entry_ptr; 744 const size_t size = SJA1105_SIZE_VL_LOOKUP_ENTRY; 745 746 if (entry->format == SJA1105_VL_FORMAT_PSFP) { 747 /* Interpreting vllupformat as 0 */ 748 sja1105_packing(buf, &entry->destports, 749 94, 84, size, op); 750 sja1105_packing(buf, &entry->iscritical, 751 83, 83, size, op); 752 sja1105_packing(buf, &entry->macaddr, 753 82, 35, size, op); 754 sja1105_packing(buf, &entry->vlanid, 755 34, 23, size, op); 756 sja1105_packing(buf, &entry->port, 757 22, 19, size, op); 758 sja1105_packing(buf, &entry->vlanprior, 759 18, 16, size, op); 760 } else { 761 /* Interpreting vllupformat as 1 */ 762 sja1105_packing(buf, &entry->egrmirr, 763 94, 84, size, op); 764 sja1105_packing(buf, &entry->ingrmirr, 765 83, 83, size, op); 766 sja1105_packing(buf, &entry->vlid, 767 50, 35, size, op); 768 sja1105_packing(buf, &entry->port, 769 22, 19, size, op); 770 } 771 return size; 772 } 773 774 static size_t sja1105_vl_policing_entry_packing(void *buf, void *entry_ptr, 775 enum packing_op op) 776 { 777 struct sja1105_vl_policing_entry *entry = entry_ptr; 778 const size_t size = SJA1105_SIZE_VL_POLICING_ENTRY; 779 780 sja1105_packing(buf, &entry->type, 63, 63, size, op); 781 sja1105_packing(buf, &entry->maxlen, 62, 52, size, op); 782 sja1105_packing(buf, &entry->sharindx, 51, 42, size, op); 783 if (entry->type == 0) { 784 sja1105_packing(buf, &entry->bag, 41, 28, size, op); 785 sja1105_packing(buf, &entry->jitter, 27, 18, size, op); 786 } 787 return size; 788 } 789 790 size_t sja1110_vl_policing_entry_packing(void *buf, void *entry_ptr, 791 enum packing_op op) 792 { 793 struct sja1105_vl_policing_entry *entry = entry_ptr; 794 const size_t size = SJA1105_SIZE_VL_POLICING_ENTRY; 795 796 sja1105_packing(buf, &entry->type, 63, 63, size, op); 797 sja1105_packing(buf, &entry->maxlen, 62, 52, size, op); 798 sja1105_packing(buf, &entry->sharindx, 51, 40, size, op); 799 if (entry->type == 0) { 800 sja1105_packing(buf, &entry->bag, 41, 28, size, op); 801 sja1105_packing(buf, &entry->jitter, 27, 18, size, op); 802 } 803 return size; 804 } 805 806 size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr, 807 enum packing_op op) 808 { 809 const size_t size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY; 810 struct sja1105_vlan_lookup_entry *entry = entry_ptr; 811 812 sja1105_packing(buf, &entry->ving_mirr, 63, 59, size, op); 813 sja1105_packing(buf, &entry->vegr_mirr, 58, 54, size, op); 814 sja1105_packing(buf, &entry->vmemb_port, 53, 49, size, op); 815 sja1105_packing(buf, &entry->vlan_bc, 48, 44, size, op); 816 sja1105_packing(buf, &entry->tag_port, 43, 39, size, op); 817 sja1105_packing(buf, &entry->vlanid, 38, 27, size, op); 818 return size; 819 } 820 821 size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr, 822 enum packing_op op) 823 { 824 struct sja1105_vlan_lookup_entry *entry = entry_ptr; 825 const size_t size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY; 826 827 sja1105_packing(buf, &entry->ving_mirr, 95, 85, size, op); 828 sja1105_packing(buf, &entry->vegr_mirr, 84, 74, size, op); 829 sja1105_packing(buf, &entry->vmemb_port, 73, 63, size, op); 830 sja1105_packing(buf, &entry->vlan_bc, 62, 52, size, op); 831 sja1105_packing(buf, &entry->tag_port, 51, 41, size, op); 832 sja1105_packing(buf, &entry->type_entry, 40, 39, size, op); 833 sja1105_packing(buf, &entry->vlanid, 38, 27, size, op); 834 return size; 835 } 836 837 static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr, 838 enum packing_op op) 839 { 840 const size_t size = SJA1105_SIZE_XMII_PARAMS_ENTRY; 841 struct sja1105_xmii_params_entry *entry = entry_ptr; 842 int offset, i; 843 844 for (i = 0, offset = 17; i < 5; i++, offset += 3) { 845 sja1105_packing(buf, &entry->xmii_mode[i], 846 offset + 1, offset + 0, size, op); 847 sja1105_packing(buf, &entry->phy_mac[i], 848 offset + 2, offset + 2, size, op); 849 } 850 return size; 851 } 852 853 size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr, 854 enum packing_op op) 855 { 856 const size_t size = SJA1110_SIZE_XMII_PARAMS_ENTRY; 857 struct sja1105_xmii_params_entry *entry = entry_ptr; 858 int offset, i; 859 860 for (i = 0, offset = 20; i < SJA1110_NUM_PORTS; i++, offset += 4) { 861 sja1105_packing(buf, &entry->xmii_mode[i], 862 offset + 1, offset + 0, size, op); 863 sja1105_packing(buf, &entry->phy_mac[i], 864 offset + 2, offset + 2, size, op); 865 sja1105_packing(buf, &entry->special[i], 866 offset + 3, offset + 3, size, op); 867 } 868 return size; 869 } 870 871 size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr, 872 enum packing_op op) 873 { 874 struct sja1105_retagging_entry *entry = entry_ptr; 875 const size_t size = SJA1105_SIZE_RETAGGING_ENTRY; 876 877 sja1105_packing(buf, &entry->egr_port, 63, 59, size, op); 878 sja1105_packing(buf, &entry->ing_port, 58, 54, size, op); 879 sja1105_packing(buf, &entry->vlan_ing, 53, 42, size, op); 880 sja1105_packing(buf, &entry->vlan_egr, 41, 30, size, op); 881 sja1105_packing(buf, &entry->do_not_learn, 29, 29, size, op); 882 sja1105_packing(buf, &entry->use_dest_ports, 28, 28, size, op); 883 sja1105_packing(buf, &entry->destports, 27, 23, size, op); 884 return size; 885 } 886 887 size_t sja1110_retagging_entry_packing(void *buf, void *entry_ptr, 888 enum packing_op op) 889 { 890 struct sja1105_retagging_entry *entry = entry_ptr; 891 const size_t size = SJA1105_SIZE_RETAGGING_ENTRY; 892 893 sja1105_packing(buf, &entry->egr_port, 63, 53, size, op); 894 sja1105_packing(buf, &entry->ing_port, 52, 42, size, op); 895 sja1105_packing(buf, &entry->vlan_ing, 41, 30, size, op); 896 sja1105_packing(buf, &entry->vlan_egr, 29, 18, size, op); 897 sja1105_packing(buf, &entry->do_not_learn, 17, 17, size, op); 898 sja1105_packing(buf, &entry->use_dest_ports, 16, 16, size, op); 899 sja1105_packing(buf, &entry->destports, 15, 5, size, op); 900 return size; 901 } 902 903 static size_t sja1110_pcp_remapping_entry_packing(void *buf, void *entry_ptr, 904 enum packing_op op) 905 { 906 struct sja1110_pcp_remapping_entry *entry = entry_ptr; 907 const size_t size = SJA1110_SIZE_PCP_REMAPPING_ENTRY; 908 int offset, i; 909 910 for (i = 0, offset = 8; i < SJA1105_NUM_TC; i++, offset += 3) 911 sja1105_packing(buf, &entry->egrpcp[i], 912 offset + 2, offset + 0, size, op); 913 914 return size; 915 } 916 917 size_t sja1105_table_header_packing(void *buf, void *entry_ptr, 918 enum packing_op op) 919 { 920 const size_t size = SJA1105_SIZE_TABLE_HEADER; 921 struct sja1105_table_header *entry = entry_ptr; 922 923 sja1105_packing(buf, &entry->block_id, 31, 24, size, op); 924 sja1105_packing(buf, &entry->len, 55, 32, size, op); 925 sja1105_packing(buf, &entry->crc, 95, 64, size, op); 926 return size; 927 } 928 929 /* WARNING: the *hdr pointer is really non-const, because it is 930 * modifying the CRC of the header for a 2-stage packing operation 931 */ 932 void 933 sja1105_table_header_pack_with_crc(void *buf, struct sja1105_table_header *hdr) 934 { 935 /* First pack the table as-is, then calculate the CRC, and 936 * finally put the proper CRC into the packed buffer 937 */ 938 memset(buf, 0, SJA1105_SIZE_TABLE_HEADER); 939 sja1105_table_header_packing(buf, hdr, PACK); 940 hdr->crc = sja1105_crc32(buf, SJA1105_SIZE_TABLE_HEADER - 4); 941 sja1105_pack(buf + SJA1105_SIZE_TABLE_HEADER - 4, &hdr->crc, 31, 0, 4); 942 } 943 944 static void sja1105_table_write_crc(u8 *table_start, u8 *crc_ptr) 945 { 946 u64 computed_crc; 947 int len_bytes; 948 949 len_bytes = (uintptr_t)(crc_ptr - table_start); 950 computed_crc = sja1105_crc32(table_start, len_bytes); 951 sja1105_pack(crc_ptr, &computed_crc, 31, 0, 4); 952 } 953 954 /* The block IDs that the switches support are unfortunately sparse, so keep a 955 * mapping table to "block indices" and translate back and forth so that we 956 * don't waste useless memory in struct sja1105_static_config. 957 * Also, since the block id comes from essentially untrusted input (unpacking 958 * the static config from userspace) it has to be sanitized (range-checked) 959 * before blindly indexing kernel memory with the blk_idx. 960 */ 961 static u64 blk_id_map[BLK_IDX_MAX] = { 962 [BLK_IDX_SCHEDULE] = BLKID_SCHEDULE, 963 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = BLKID_SCHEDULE_ENTRY_POINTS, 964 [BLK_IDX_VL_LOOKUP] = BLKID_VL_LOOKUP, 965 [BLK_IDX_VL_POLICING] = BLKID_VL_POLICING, 966 [BLK_IDX_VL_FORWARDING] = BLKID_VL_FORWARDING, 967 [BLK_IDX_L2_LOOKUP] = BLKID_L2_LOOKUP, 968 [BLK_IDX_L2_POLICING] = BLKID_L2_POLICING, 969 [BLK_IDX_VLAN_LOOKUP] = BLKID_VLAN_LOOKUP, 970 [BLK_IDX_L2_FORWARDING] = BLKID_L2_FORWARDING, 971 [BLK_IDX_MAC_CONFIG] = BLKID_MAC_CONFIG, 972 [BLK_IDX_SCHEDULE_PARAMS] = BLKID_SCHEDULE_PARAMS, 973 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = BLKID_SCHEDULE_ENTRY_POINTS_PARAMS, 974 [BLK_IDX_VL_FORWARDING_PARAMS] = BLKID_VL_FORWARDING_PARAMS, 975 [BLK_IDX_L2_LOOKUP_PARAMS] = BLKID_L2_LOOKUP_PARAMS, 976 [BLK_IDX_L2_FORWARDING_PARAMS] = BLKID_L2_FORWARDING_PARAMS, 977 [BLK_IDX_AVB_PARAMS] = BLKID_AVB_PARAMS, 978 [BLK_IDX_GENERAL_PARAMS] = BLKID_GENERAL_PARAMS, 979 [BLK_IDX_RETAGGING] = BLKID_RETAGGING, 980 [BLK_IDX_XMII_PARAMS] = BLKID_XMII_PARAMS, 981 [BLK_IDX_PCP_REMAPPING] = BLKID_PCP_REMAPPING, 982 }; 983 984 const char *sja1105_static_config_error_msg[] = { 985 [SJA1105_CONFIG_OK] = "", 986 [SJA1105_TTETHERNET_NOT_SUPPORTED] = 987 "schedule-table present, but TTEthernet is " 988 "only supported on T and Q/S", 989 [SJA1105_INCORRECT_TTETHERNET_CONFIGURATION] = 990 "schedule-table present, but one of " 991 "schedule-entry-points-table, schedule-parameters-table or " 992 "schedule-entry-points-parameters table is empty", 993 [SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION] = 994 "vl-lookup-table present, but one of vl-policing-table, " 995 "vl-forwarding-table or vl-forwarding-parameters-table is empty", 996 [SJA1105_MISSING_L2_POLICING_TABLE] = 997 "l2-policing-table needs to have at least one entry", 998 [SJA1105_MISSING_L2_FORWARDING_TABLE] = 999 "l2-forwarding-table is either missing or incomplete", 1000 [SJA1105_MISSING_L2_FORWARDING_PARAMS_TABLE] = 1001 "l2-forwarding-parameters-table is missing", 1002 [SJA1105_MISSING_GENERAL_PARAMS_TABLE] = 1003 "general-parameters-table is missing", 1004 [SJA1105_MISSING_VLAN_TABLE] = 1005 "vlan-lookup-table needs to have at least the default untagged VLAN", 1006 [SJA1105_MISSING_XMII_TABLE] = 1007 "xmii-table is missing", 1008 [SJA1105_MISSING_MAC_TABLE] = 1009 "mac-configuration-table needs to contain an entry for each port", 1010 [SJA1105_OVERCOMMITTED_FRAME_MEMORY] = 1011 "Not allowed to overcommit frame memory. L2 memory partitions " 1012 "and VL memory partitions share the same space. The sum of all " 1013 "16 memory partitions is not allowed to be larger than 929 " 1014 "128-byte blocks (or 910 with retagging). Please adjust " 1015 "l2-forwarding-parameters-table.part_spc and/or " 1016 "vl-forwarding-parameters-table.partspc.", 1017 }; 1018 1019 static sja1105_config_valid_t 1020 static_config_check_memory_size(const struct sja1105_table *tables, int max_mem) 1021 { 1022 const struct sja1105_l2_forwarding_params_entry *l2_fwd_params; 1023 const struct sja1105_vl_forwarding_params_entry *vl_fwd_params; 1024 int i, mem = 0; 1025 1026 l2_fwd_params = tables[BLK_IDX_L2_FORWARDING_PARAMS].entries; 1027 1028 for (i = 0; i < 8; i++) 1029 mem += l2_fwd_params->part_spc[i]; 1030 1031 if (tables[BLK_IDX_VL_FORWARDING_PARAMS].entry_count) { 1032 vl_fwd_params = tables[BLK_IDX_VL_FORWARDING_PARAMS].entries; 1033 for (i = 0; i < 8; i++) 1034 mem += vl_fwd_params->partspc[i]; 1035 } 1036 1037 if (tables[BLK_IDX_RETAGGING].entry_count) 1038 max_mem -= SJA1105_FRAME_MEMORY_RETAGGING_OVERHEAD; 1039 1040 if (mem > max_mem) 1041 return SJA1105_OVERCOMMITTED_FRAME_MEMORY; 1042 1043 return SJA1105_CONFIG_OK; 1044 } 1045 1046 sja1105_config_valid_t 1047 sja1105_static_config_check_valid(const struct sja1105_static_config *config, 1048 int max_mem) 1049 { 1050 const struct sja1105_table *tables = config->tables; 1051 #define IS_FULL(blk_idx) \ 1052 (tables[blk_idx].entry_count == tables[blk_idx].ops->max_entry_count) 1053 1054 if (tables[BLK_IDX_SCHEDULE].entry_count) { 1055 if (!tables[BLK_IDX_SCHEDULE].ops->max_entry_count) 1056 return SJA1105_TTETHERNET_NOT_SUPPORTED; 1057 1058 if (tables[BLK_IDX_SCHEDULE_ENTRY_POINTS].entry_count == 0) 1059 return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION; 1060 1061 if (!IS_FULL(BLK_IDX_SCHEDULE_PARAMS)) 1062 return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION; 1063 1064 if (!IS_FULL(BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS)) 1065 return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION; 1066 } 1067 if (tables[BLK_IDX_VL_LOOKUP].entry_count) { 1068 struct sja1105_vl_lookup_entry *vl_lookup; 1069 bool has_critical_links = false; 1070 int i; 1071 1072 vl_lookup = tables[BLK_IDX_VL_LOOKUP].entries; 1073 1074 for (i = 0; i < tables[BLK_IDX_VL_LOOKUP].entry_count; i++) { 1075 if (vl_lookup[i].iscritical) { 1076 has_critical_links = true; 1077 break; 1078 } 1079 } 1080 1081 if (tables[BLK_IDX_VL_POLICING].entry_count == 0 && 1082 has_critical_links) 1083 return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION; 1084 1085 if (tables[BLK_IDX_VL_FORWARDING].entry_count == 0 && 1086 has_critical_links) 1087 return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION; 1088 1089 if (tables[BLK_IDX_VL_FORWARDING_PARAMS].entry_count == 0 && 1090 has_critical_links) 1091 return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION; 1092 } 1093 1094 if (tables[BLK_IDX_L2_POLICING].entry_count == 0) 1095 return SJA1105_MISSING_L2_POLICING_TABLE; 1096 1097 if (tables[BLK_IDX_VLAN_LOOKUP].entry_count == 0) 1098 return SJA1105_MISSING_VLAN_TABLE; 1099 1100 if (!IS_FULL(BLK_IDX_L2_FORWARDING)) 1101 return SJA1105_MISSING_L2_FORWARDING_TABLE; 1102 1103 if (!IS_FULL(BLK_IDX_MAC_CONFIG)) 1104 return SJA1105_MISSING_MAC_TABLE; 1105 1106 if (!IS_FULL(BLK_IDX_L2_FORWARDING_PARAMS)) 1107 return SJA1105_MISSING_L2_FORWARDING_PARAMS_TABLE; 1108 1109 if (!IS_FULL(BLK_IDX_GENERAL_PARAMS)) 1110 return SJA1105_MISSING_GENERAL_PARAMS_TABLE; 1111 1112 if (!IS_FULL(BLK_IDX_XMII_PARAMS)) 1113 return SJA1105_MISSING_XMII_TABLE; 1114 1115 return static_config_check_memory_size(tables, max_mem); 1116 #undef IS_FULL 1117 } 1118 1119 void 1120 sja1105_static_config_pack(void *buf, struct sja1105_static_config *config) 1121 { 1122 struct sja1105_table_header header = {0}; 1123 enum sja1105_blk_idx i; 1124 char *p = buf; 1125 int j; 1126 1127 sja1105_pack(p, &config->device_id, 31, 0, 4); 1128 p += SJA1105_SIZE_DEVICE_ID; 1129 1130 for (i = 0; i < BLK_IDX_MAX; i++) { 1131 const struct sja1105_table *table; 1132 char *table_start; 1133 1134 table = &config->tables[i]; 1135 if (!table->entry_count) 1136 continue; 1137 1138 header.block_id = blk_id_map[i]; 1139 header.len = table->entry_count * 1140 table->ops->packed_entry_size / 4; 1141 sja1105_table_header_pack_with_crc(p, &header); 1142 p += SJA1105_SIZE_TABLE_HEADER; 1143 table_start = p; 1144 for (j = 0; j < table->entry_count; j++) { 1145 u8 *entry_ptr = table->entries; 1146 1147 entry_ptr += j * table->ops->unpacked_entry_size; 1148 memset(p, 0, table->ops->packed_entry_size); 1149 table->ops->packing(p, entry_ptr, PACK); 1150 p += table->ops->packed_entry_size; 1151 } 1152 sja1105_table_write_crc(table_start, p); 1153 p += 4; 1154 } 1155 /* Final header: 1156 * Block ID does not matter 1157 * Length of 0 marks that header is final 1158 * CRC will be replaced on-the-fly on "config upload" 1159 */ 1160 header.block_id = 0; 1161 header.len = 0; 1162 header.crc = 0xDEADBEEF; 1163 memset(p, 0, SJA1105_SIZE_TABLE_HEADER); 1164 sja1105_table_header_packing(p, &header, PACK); 1165 } 1166 1167 size_t 1168 sja1105_static_config_get_length(const struct sja1105_static_config *config) 1169 { 1170 unsigned int sum; 1171 unsigned int header_count; 1172 enum sja1105_blk_idx i; 1173 1174 /* Ending header */ 1175 header_count = 1; 1176 sum = SJA1105_SIZE_DEVICE_ID; 1177 1178 /* Tables (headers and entries) */ 1179 for (i = 0; i < BLK_IDX_MAX; i++) { 1180 const struct sja1105_table *table; 1181 1182 table = &config->tables[i]; 1183 if (table->entry_count) 1184 header_count++; 1185 1186 sum += table->ops->packed_entry_size * table->entry_count; 1187 } 1188 /* Headers have an additional CRC at the end */ 1189 sum += header_count * (SJA1105_SIZE_TABLE_HEADER + 4); 1190 /* Last header does not have an extra CRC because there is no data */ 1191 sum -= 4; 1192 1193 return sum; 1194 } 1195 1196 /* Compatibility matrices */ 1197 1198 /* SJA1105E: First generation, no TTEthernet */ 1199 const struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = { 1200 [BLK_IDX_L2_LOOKUP] = { 1201 .packing = sja1105et_l2_lookup_entry_packing, 1202 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1203 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY, 1204 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1205 }, 1206 [BLK_IDX_L2_POLICING] = { 1207 .packing = sja1105_l2_policing_entry_packing, 1208 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1209 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1210 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1211 }, 1212 [BLK_IDX_VLAN_LOOKUP] = { 1213 .packing = sja1105_vlan_lookup_entry_packing, 1214 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1215 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1216 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1217 }, 1218 [BLK_IDX_L2_FORWARDING] = { 1219 .packing = sja1105_l2_forwarding_entry_packing, 1220 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1221 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1222 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1223 }, 1224 [BLK_IDX_MAC_CONFIG] = { 1225 .packing = sja1105et_mac_config_entry_packing, 1226 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1227 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY, 1228 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1229 }, 1230 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1231 .packing = sja1105et_l2_lookup_params_entry_packing, 1232 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1233 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1234 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1235 }, 1236 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1237 .packing = sja1105_l2_forwarding_params_entry_packing, 1238 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1239 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1240 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1241 }, 1242 [BLK_IDX_AVB_PARAMS] = { 1243 .packing = sja1105et_avb_params_entry_packing, 1244 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1245 .packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY, 1246 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1247 }, 1248 [BLK_IDX_GENERAL_PARAMS] = { 1249 .packing = sja1105et_general_params_entry_packing, 1250 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1251 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY, 1252 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1253 }, 1254 [BLK_IDX_RETAGGING] = { 1255 .packing = sja1105_retagging_entry_packing, 1256 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1257 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1258 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1259 }, 1260 [BLK_IDX_XMII_PARAMS] = { 1261 .packing = sja1105_xmii_params_entry_packing, 1262 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1263 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1264 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1265 }, 1266 }; 1267 1268 /* SJA1105T: First generation, TTEthernet */ 1269 const struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX] = { 1270 [BLK_IDX_SCHEDULE] = { 1271 .packing = sja1105_schedule_entry_packing, 1272 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1273 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY, 1274 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT, 1275 }, 1276 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1277 .packing = sja1105_schedule_entry_points_entry_packing, 1278 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1279 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1280 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1281 }, 1282 [BLK_IDX_VL_LOOKUP] = { 1283 .packing = sja1105_vl_lookup_entry_packing, 1284 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1285 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1286 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 1287 }, 1288 [BLK_IDX_VL_POLICING] = { 1289 .packing = sja1105_vl_policing_entry_packing, 1290 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1291 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1292 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT, 1293 }, 1294 [BLK_IDX_VL_FORWARDING] = { 1295 .packing = sja1105_vl_forwarding_entry_packing, 1296 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1297 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1298 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT, 1299 }, 1300 [BLK_IDX_L2_LOOKUP] = { 1301 .packing = sja1105et_l2_lookup_entry_packing, 1302 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1303 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY, 1304 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1305 }, 1306 [BLK_IDX_L2_POLICING] = { 1307 .packing = sja1105_l2_policing_entry_packing, 1308 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1309 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1310 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1311 }, 1312 [BLK_IDX_VLAN_LOOKUP] = { 1313 .packing = sja1105_vlan_lookup_entry_packing, 1314 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1315 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1316 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1317 }, 1318 [BLK_IDX_L2_FORWARDING] = { 1319 .packing = sja1105_l2_forwarding_entry_packing, 1320 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1321 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1322 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1323 }, 1324 [BLK_IDX_MAC_CONFIG] = { 1325 .packing = sja1105et_mac_config_entry_packing, 1326 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1327 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY, 1328 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1329 }, 1330 [BLK_IDX_SCHEDULE_PARAMS] = { 1331 .packing = sja1105_schedule_params_entry_packing, 1332 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1333 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1334 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1335 }, 1336 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1337 .packing = sja1105_schedule_entry_points_params_entry_packing, 1338 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1339 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1340 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1341 }, 1342 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1343 .packing = sja1105_vl_forwarding_params_entry_packing, 1344 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1345 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1346 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1347 }, 1348 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1349 .packing = sja1105et_l2_lookup_params_entry_packing, 1350 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1351 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1352 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1353 }, 1354 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1355 .packing = sja1105_l2_forwarding_params_entry_packing, 1356 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1357 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1358 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1359 }, 1360 [BLK_IDX_AVB_PARAMS] = { 1361 .packing = sja1105et_avb_params_entry_packing, 1362 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1363 .packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY, 1364 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1365 }, 1366 [BLK_IDX_GENERAL_PARAMS] = { 1367 .packing = sja1105et_general_params_entry_packing, 1368 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1369 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY, 1370 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1371 }, 1372 [BLK_IDX_RETAGGING] = { 1373 .packing = sja1105_retagging_entry_packing, 1374 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1375 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1376 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1377 }, 1378 [BLK_IDX_XMII_PARAMS] = { 1379 .packing = sja1105_xmii_params_entry_packing, 1380 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1381 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1382 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1383 }, 1384 }; 1385 1386 /* SJA1105P: Second generation, no TTEthernet, no SGMII */ 1387 const struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = { 1388 [BLK_IDX_L2_LOOKUP] = { 1389 .packing = sja1105pqrs_l2_lookup_entry_packing, 1390 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1391 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1392 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1393 }, 1394 [BLK_IDX_L2_POLICING] = { 1395 .packing = sja1105_l2_policing_entry_packing, 1396 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1397 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1398 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1399 }, 1400 [BLK_IDX_VLAN_LOOKUP] = { 1401 .packing = sja1105_vlan_lookup_entry_packing, 1402 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1403 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1404 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1405 }, 1406 [BLK_IDX_L2_FORWARDING] = { 1407 .packing = sja1105_l2_forwarding_entry_packing, 1408 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1409 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1410 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1411 }, 1412 [BLK_IDX_MAC_CONFIG] = { 1413 .packing = sja1105pqrs_mac_config_entry_packing, 1414 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1415 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1416 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1417 }, 1418 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1419 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1420 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1421 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1422 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1423 }, 1424 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1425 .packing = sja1105_l2_forwarding_params_entry_packing, 1426 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1427 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1428 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1429 }, 1430 [BLK_IDX_AVB_PARAMS] = { 1431 .packing = sja1105pqrs_avb_params_entry_packing, 1432 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1433 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1434 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1435 }, 1436 [BLK_IDX_GENERAL_PARAMS] = { 1437 .packing = sja1105pqrs_general_params_entry_packing, 1438 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1439 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1440 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1441 }, 1442 [BLK_IDX_RETAGGING] = { 1443 .packing = sja1105_retagging_entry_packing, 1444 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1445 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1446 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1447 }, 1448 [BLK_IDX_XMII_PARAMS] = { 1449 .packing = sja1105_xmii_params_entry_packing, 1450 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1451 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1452 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1453 }, 1454 }; 1455 1456 /* SJA1105Q: Second generation, TTEthernet, no SGMII */ 1457 const struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX] = { 1458 [BLK_IDX_SCHEDULE] = { 1459 .packing = sja1105_schedule_entry_packing, 1460 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1461 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY, 1462 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT, 1463 }, 1464 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1465 .packing = sja1105_schedule_entry_points_entry_packing, 1466 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1467 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1468 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1469 }, 1470 [BLK_IDX_VL_LOOKUP] = { 1471 .packing = sja1105_vl_lookup_entry_packing, 1472 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1473 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1474 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 1475 }, 1476 [BLK_IDX_VL_POLICING] = { 1477 .packing = sja1105_vl_policing_entry_packing, 1478 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1479 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1480 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT, 1481 }, 1482 [BLK_IDX_VL_FORWARDING] = { 1483 .packing = sja1105_vl_forwarding_entry_packing, 1484 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1485 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1486 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT, 1487 }, 1488 [BLK_IDX_L2_LOOKUP] = { 1489 .packing = sja1105pqrs_l2_lookup_entry_packing, 1490 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1491 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1492 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1493 }, 1494 [BLK_IDX_L2_POLICING] = { 1495 .packing = sja1105_l2_policing_entry_packing, 1496 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1497 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1498 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1499 }, 1500 [BLK_IDX_VLAN_LOOKUP] = { 1501 .packing = sja1105_vlan_lookup_entry_packing, 1502 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1503 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1504 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1505 }, 1506 [BLK_IDX_L2_FORWARDING] = { 1507 .packing = sja1105_l2_forwarding_entry_packing, 1508 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1509 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1510 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1511 }, 1512 [BLK_IDX_MAC_CONFIG] = { 1513 .packing = sja1105pqrs_mac_config_entry_packing, 1514 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1515 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1516 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1517 }, 1518 [BLK_IDX_SCHEDULE_PARAMS] = { 1519 .packing = sja1105_schedule_params_entry_packing, 1520 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1521 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1522 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1523 }, 1524 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1525 .packing = sja1105_schedule_entry_points_params_entry_packing, 1526 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1527 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1528 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1529 }, 1530 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1531 .packing = sja1105_vl_forwarding_params_entry_packing, 1532 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1533 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1534 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1535 }, 1536 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1537 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1538 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1539 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1540 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1541 }, 1542 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1543 .packing = sja1105_l2_forwarding_params_entry_packing, 1544 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1545 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1546 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1547 }, 1548 [BLK_IDX_AVB_PARAMS] = { 1549 .packing = sja1105pqrs_avb_params_entry_packing, 1550 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1551 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1552 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1553 }, 1554 [BLK_IDX_GENERAL_PARAMS] = { 1555 .packing = sja1105pqrs_general_params_entry_packing, 1556 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1557 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1558 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1559 }, 1560 [BLK_IDX_RETAGGING] = { 1561 .packing = sja1105_retagging_entry_packing, 1562 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1563 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1564 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1565 }, 1566 [BLK_IDX_XMII_PARAMS] = { 1567 .packing = sja1105_xmii_params_entry_packing, 1568 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1569 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1570 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1571 }, 1572 }; 1573 1574 /* SJA1105R: Second generation, no TTEthernet, SGMII */ 1575 const struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = { 1576 [BLK_IDX_L2_LOOKUP] = { 1577 .packing = sja1105pqrs_l2_lookup_entry_packing, 1578 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1579 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1580 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1581 }, 1582 [BLK_IDX_L2_POLICING] = { 1583 .packing = sja1105_l2_policing_entry_packing, 1584 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1585 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1586 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1587 }, 1588 [BLK_IDX_VLAN_LOOKUP] = { 1589 .packing = sja1105_vlan_lookup_entry_packing, 1590 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1591 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1592 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1593 }, 1594 [BLK_IDX_L2_FORWARDING] = { 1595 .packing = sja1105_l2_forwarding_entry_packing, 1596 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1597 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1598 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1599 }, 1600 [BLK_IDX_MAC_CONFIG] = { 1601 .packing = sja1105pqrs_mac_config_entry_packing, 1602 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1603 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1604 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1605 }, 1606 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1607 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1608 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1609 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1610 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1611 }, 1612 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1613 .packing = sja1105_l2_forwarding_params_entry_packing, 1614 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1615 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1616 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1617 }, 1618 [BLK_IDX_AVB_PARAMS] = { 1619 .packing = sja1105pqrs_avb_params_entry_packing, 1620 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1621 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1622 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1623 }, 1624 [BLK_IDX_GENERAL_PARAMS] = { 1625 .packing = sja1105pqrs_general_params_entry_packing, 1626 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1627 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1628 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1629 }, 1630 [BLK_IDX_RETAGGING] = { 1631 .packing = sja1105_retagging_entry_packing, 1632 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1633 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1634 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1635 }, 1636 [BLK_IDX_XMII_PARAMS] = { 1637 .packing = sja1105_xmii_params_entry_packing, 1638 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1639 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1640 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1641 }, 1642 }; 1643 1644 /* SJA1105S: Second generation, TTEthernet, SGMII */ 1645 const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = { 1646 [BLK_IDX_SCHEDULE] = { 1647 .packing = sja1105_schedule_entry_packing, 1648 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1649 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY, 1650 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT, 1651 }, 1652 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1653 .packing = sja1105_schedule_entry_points_entry_packing, 1654 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1655 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1656 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1657 }, 1658 [BLK_IDX_VL_LOOKUP] = { 1659 .packing = sja1105_vl_lookup_entry_packing, 1660 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1661 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1662 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 1663 }, 1664 [BLK_IDX_VL_POLICING] = { 1665 .packing = sja1105_vl_policing_entry_packing, 1666 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1667 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1668 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT, 1669 }, 1670 [BLK_IDX_VL_FORWARDING] = { 1671 .packing = sja1105_vl_forwarding_entry_packing, 1672 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1673 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1674 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT, 1675 }, 1676 [BLK_IDX_L2_LOOKUP] = { 1677 .packing = sja1105pqrs_l2_lookup_entry_packing, 1678 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1679 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1680 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1681 }, 1682 [BLK_IDX_L2_POLICING] = { 1683 .packing = sja1105_l2_policing_entry_packing, 1684 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1685 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1686 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1687 }, 1688 [BLK_IDX_VLAN_LOOKUP] = { 1689 .packing = sja1105_vlan_lookup_entry_packing, 1690 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1691 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1692 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1693 }, 1694 [BLK_IDX_L2_FORWARDING] = { 1695 .packing = sja1105_l2_forwarding_entry_packing, 1696 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1697 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1698 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1699 }, 1700 [BLK_IDX_MAC_CONFIG] = { 1701 .packing = sja1105pqrs_mac_config_entry_packing, 1702 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1703 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1704 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1705 }, 1706 [BLK_IDX_SCHEDULE_PARAMS] = { 1707 .packing = sja1105_schedule_params_entry_packing, 1708 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1709 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1710 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1711 }, 1712 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1713 .packing = sja1105_schedule_entry_points_params_entry_packing, 1714 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1715 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1716 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1717 }, 1718 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1719 .packing = sja1105_vl_forwarding_params_entry_packing, 1720 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1721 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1722 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1723 }, 1724 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1725 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1726 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1727 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1728 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1729 }, 1730 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1731 .packing = sja1105_l2_forwarding_params_entry_packing, 1732 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1733 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1734 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1735 }, 1736 [BLK_IDX_AVB_PARAMS] = { 1737 .packing = sja1105pqrs_avb_params_entry_packing, 1738 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1739 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1740 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1741 }, 1742 [BLK_IDX_GENERAL_PARAMS] = { 1743 .packing = sja1105pqrs_general_params_entry_packing, 1744 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1745 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1746 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1747 }, 1748 [BLK_IDX_RETAGGING] = { 1749 .packing = sja1105_retagging_entry_packing, 1750 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1751 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1752 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1753 }, 1754 [BLK_IDX_XMII_PARAMS] = { 1755 .packing = sja1105_xmii_params_entry_packing, 1756 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1757 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1758 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1759 }, 1760 }; 1761 1762 /* SJA1110A: Third generation */ 1763 const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX] = { 1764 [BLK_IDX_SCHEDULE] = { 1765 .packing = sja1110_schedule_entry_packing, 1766 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1767 .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY, 1768 .max_entry_count = SJA1110_MAX_SCHEDULE_COUNT, 1769 }, 1770 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1771 .packing = sja1110_schedule_entry_points_entry_packing, 1772 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1773 .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1774 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1775 }, 1776 [BLK_IDX_VL_LOOKUP] = { 1777 .packing = sja1110_vl_lookup_entry_packing, 1778 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1779 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1780 .max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT, 1781 }, 1782 [BLK_IDX_VL_POLICING] = { 1783 .packing = sja1110_vl_policing_entry_packing, 1784 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1785 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1786 .max_entry_count = SJA1110_MAX_VL_POLICING_COUNT, 1787 }, 1788 [BLK_IDX_VL_FORWARDING] = { 1789 .packing = sja1110_vl_forwarding_entry_packing, 1790 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1791 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1792 .max_entry_count = SJA1110_MAX_VL_FORWARDING_COUNT, 1793 }, 1794 [BLK_IDX_L2_LOOKUP] = { 1795 .packing = sja1110_l2_lookup_entry_packing, 1796 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1797 .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_ENTRY, 1798 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1799 }, 1800 [BLK_IDX_L2_POLICING] = { 1801 .packing = sja1110_l2_policing_entry_packing, 1802 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1803 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1804 .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT, 1805 }, 1806 [BLK_IDX_VLAN_LOOKUP] = { 1807 .packing = sja1110_vlan_lookup_entry_packing, 1808 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1809 .packed_entry_size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY, 1810 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1811 }, 1812 [BLK_IDX_L2_FORWARDING] = { 1813 .packing = sja1110_l2_forwarding_entry_packing, 1814 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1815 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1816 .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT, 1817 }, 1818 [BLK_IDX_MAC_CONFIG] = { 1819 .packing = sja1110_mac_config_entry_packing, 1820 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1821 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1822 .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT, 1823 }, 1824 [BLK_IDX_SCHEDULE_PARAMS] = { 1825 .packing = sja1110_schedule_params_entry_packing, 1826 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1827 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1828 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1829 }, 1830 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1831 .packing = sja1105_schedule_entry_points_params_entry_packing, 1832 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1833 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1834 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1835 }, 1836 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1837 .packing = sja1110_vl_forwarding_params_entry_packing, 1838 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1839 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1840 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1841 }, 1842 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1843 .packing = sja1110_l2_lookup_params_entry_packing, 1844 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1845 .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1846 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1847 }, 1848 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1849 .packing = sja1110_l2_forwarding_params_entry_packing, 1850 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1851 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1852 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1853 }, 1854 [BLK_IDX_AVB_PARAMS] = { 1855 .packing = sja1105pqrs_avb_params_entry_packing, 1856 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1857 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1858 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1859 }, 1860 [BLK_IDX_GENERAL_PARAMS] = { 1861 .packing = sja1110_general_params_entry_packing, 1862 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1863 .packed_entry_size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY, 1864 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1865 }, 1866 [BLK_IDX_RETAGGING] = { 1867 .packing = sja1110_retagging_entry_packing, 1868 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1869 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1870 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1871 }, 1872 [BLK_IDX_XMII_PARAMS] = { 1873 .packing = sja1110_xmii_params_entry_packing, 1874 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1875 .packed_entry_size = SJA1110_SIZE_XMII_PARAMS_ENTRY, 1876 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1877 }, 1878 [BLK_IDX_PCP_REMAPPING] = { 1879 .packing = sja1110_pcp_remapping_entry_packing, 1880 .unpacked_entry_size = sizeof(struct sja1110_pcp_remapping_entry), 1881 .packed_entry_size = SJA1110_SIZE_PCP_REMAPPING_ENTRY, 1882 .max_entry_count = SJA1110_MAX_PCP_REMAPPING_COUNT, 1883 }, 1884 }; 1885 1886 int sja1105_static_config_init(struct sja1105_static_config *config, 1887 const struct sja1105_table_ops *static_ops, 1888 u64 device_id) 1889 { 1890 enum sja1105_blk_idx i; 1891 1892 *config = (struct sja1105_static_config) {0}; 1893 1894 /* Transfer static_ops array from priv into per-table ops 1895 * for handier access 1896 */ 1897 for (i = 0; i < BLK_IDX_MAX; i++) 1898 config->tables[i].ops = &static_ops[i]; 1899 1900 config->device_id = device_id; 1901 return 0; 1902 } 1903 1904 void sja1105_static_config_free(struct sja1105_static_config *config) 1905 { 1906 enum sja1105_blk_idx i; 1907 1908 for (i = 0; i < BLK_IDX_MAX; i++) { 1909 if (config->tables[i].entry_count) { 1910 kfree(config->tables[i].entries); 1911 config->tables[i].entry_count = 0; 1912 } 1913 } 1914 } 1915 1916 int sja1105_table_delete_entry(struct sja1105_table *table, int i) 1917 { 1918 size_t entry_size = table->ops->unpacked_entry_size; 1919 u8 *entries = table->entries; 1920 1921 if (i > table->entry_count) 1922 return -ERANGE; 1923 1924 memmove(entries + i * entry_size, entries + (i + 1) * entry_size, 1925 (table->entry_count - i) * entry_size); 1926 1927 table->entry_count--; 1928 1929 return 0; 1930 } 1931 1932 /* No pointers to table->entries should be kept when this is called. */ 1933 int sja1105_table_resize(struct sja1105_table *table, size_t new_count) 1934 { 1935 size_t entry_size = table->ops->unpacked_entry_size; 1936 void *new_entries, *old_entries = table->entries; 1937 1938 if (new_count > table->ops->max_entry_count) 1939 return -ERANGE; 1940 1941 new_entries = kcalloc(new_count, entry_size, GFP_KERNEL); 1942 if (!new_entries) 1943 return -ENOMEM; 1944 1945 memcpy(new_entries, old_entries, min(new_count, table->entry_count) * 1946 entry_size); 1947 1948 table->entries = new_entries; 1949 table->entry_count = new_count; 1950 kfree(old_entries); 1951 return 0; 1952 } 1953