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 (config->device_id != SJA1105T_DEVICE_ID && 1056 config->device_id != SJA1105QS_DEVICE_ID) 1057 return SJA1105_TTETHERNET_NOT_SUPPORTED; 1058 1059 if (tables[BLK_IDX_SCHEDULE_ENTRY_POINTS].entry_count == 0) 1060 return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION; 1061 1062 if (!IS_FULL(BLK_IDX_SCHEDULE_PARAMS)) 1063 return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION; 1064 1065 if (!IS_FULL(BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS)) 1066 return SJA1105_INCORRECT_TTETHERNET_CONFIGURATION; 1067 } 1068 if (tables[BLK_IDX_VL_LOOKUP].entry_count) { 1069 struct sja1105_vl_lookup_entry *vl_lookup; 1070 bool has_critical_links = false; 1071 int i; 1072 1073 vl_lookup = tables[BLK_IDX_VL_LOOKUP].entries; 1074 1075 for (i = 0; i < tables[BLK_IDX_VL_LOOKUP].entry_count; i++) { 1076 if (vl_lookup[i].iscritical) { 1077 has_critical_links = true; 1078 break; 1079 } 1080 } 1081 1082 if (tables[BLK_IDX_VL_POLICING].entry_count == 0 && 1083 has_critical_links) 1084 return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION; 1085 1086 if (tables[BLK_IDX_VL_FORWARDING].entry_count == 0 && 1087 has_critical_links) 1088 return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION; 1089 1090 if (tables[BLK_IDX_VL_FORWARDING_PARAMS].entry_count == 0 && 1091 has_critical_links) 1092 return SJA1105_INCORRECT_VIRTUAL_LINK_CONFIGURATION; 1093 } 1094 1095 if (tables[BLK_IDX_L2_POLICING].entry_count == 0) 1096 return SJA1105_MISSING_L2_POLICING_TABLE; 1097 1098 if (tables[BLK_IDX_VLAN_LOOKUP].entry_count == 0) 1099 return SJA1105_MISSING_VLAN_TABLE; 1100 1101 if (!IS_FULL(BLK_IDX_L2_FORWARDING)) 1102 return SJA1105_MISSING_L2_FORWARDING_TABLE; 1103 1104 if (!IS_FULL(BLK_IDX_MAC_CONFIG)) 1105 return SJA1105_MISSING_MAC_TABLE; 1106 1107 if (!IS_FULL(BLK_IDX_L2_FORWARDING_PARAMS)) 1108 return SJA1105_MISSING_L2_FORWARDING_PARAMS_TABLE; 1109 1110 if (!IS_FULL(BLK_IDX_GENERAL_PARAMS)) 1111 return SJA1105_MISSING_GENERAL_PARAMS_TABLE; 1112 1113 if (!IS_FULL(BLK_IDX_XMII_PARAMS)) 1114 return SJA1105_MISSING_XMII_TABLE; 1115 1116 return static_config_check_memory_size(tables, max_mem); 1117 #undef IS_FULL 1118 } 1119 1120 void 1121 sja1105_static_config_pack(void *buf, struct sja1105_static_config *config) 1122 { 1123 struct sja1105_table_header header = {0}; 1124 enum sja1105_blk_idx i; 1125 char *p = buf; 1126 int j; 1127 1128 sja1105_pack(p, &config->device_id, 31, 0, 4); 1129 p += SJA1105_SIZE_DEVICE_ID; 1130 1131 for (i = 0; i < BLK_IDX_MAX; i++) { 1132 const struct sja1105_table *table; 1133 char *table_start; 1134 1135 table = &config->tables[i]; 1136 if (!table->entry_count) 1137 continue; 1138 1139 header.block_id = blk_id_map[i]; 1140 header.len = table->entry_count * 1141 table->ops->packed_entry_size / 4; 1142 sja1105_table_header_pack_with_crc(p, &header); 1143 p += SJA1105_SIZE_TABLE_HEADER; 1144 table_start = p; 1145 for (j = 0; j < table->entry_count; j++) { 1146 u8 *entry_ptr = table->entries; 1147 1148 entry_ptr += j * table->ops->unpacked_entry_size; 1149 memset(p, 0, table->ops->packed_entry_size); 1150 table->ops->packing(p, entry_ptr, PACK); 1151 p += table->ops->packed_entry_size; 1152 } 1153 sja1105_table_write_crc(table_start, p); 1154 p += 4; 1155 } 1156 /* Final header: 1157 * Block ID does not matter 1158 * Length of 0 marks that header is final 1159 * CRC will be replaced on-the-fly on "config upload" 1160 */ 1161 header.block_id = 0; 1162 header.len = 0; 1163 header.crc = 0xDEADBEEF; 1164 memset(p, 0, SJA1105_SIZE_TABLE_HEADER); 1165 sja1105_table_header_packing(p, &header, PACK); 1166 } 1167 1168 size_t 1169 sja1105_static_config_get_length(const struct sja1105_static_config *config) 1170 { 1171 unsigned int sum; 1172 unsigned int header_count; 1173 enum sja1105_blk_idx i; 1174 1175 /* Ending header */ 1176 header_count = 1; 1177 sum = SJA1105_SIZE_DEVICE_ID; 1178 1179 /* Tables (headers and entries) */ 1180 for (i = 0; i < BLK_IDX_MAX; i++) { 1181 const struct sja1105_table *table; 1182 1183 table = &config->tables[i]; 1184 if (table->entry_count) 1185 header_count++; 1186 1187 sum += table->ops->packed_entry_size * table->entry_count; 1188 } 1189 /* Headers have an additional CRC at the end */ 1190 sum += header_count * (SJA1105_SIZE_TABLE_HEADER + 4); 1191 /* Last header does not have an extra CRC because there is no data */ 1192 sum -= 4; 1193 1194 return sum; 1195 } 1196 1197 /* Compatibility matrices */ 1198 1199 /* SJA1105E: First generation, no TTEthernet */ 1200 const struct sja1105_table_ops sja1105e_table_ops[BLK_IDX_MAX] = { 1201 [BLK_IDX_L2_LOOKUP] = { 1202 .packing = sja1105et_l2_lookup_entry_packing, 1203 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1204 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY, 1205 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1206 }, 1207 [BLK_IDX_L2_POLICING] = { 1208 .packing = sja1105_l2_policing_entry_packing, 1209 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1210 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1211 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1212 }, 1213 [BLK_IDX_VLAN_LOOKUP] = { 1214 .packing = sja1105_vlan_lookup_entry_packing, 1215 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1216 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1217 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1218 }, 1219 [BLK_IDX_L2_FORWARDING] = { 1220 .packing = sja1105_l2_forwarding_entry_packing, 1221 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1222 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1223 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1224 }, 1225 [BLK_IDX_MAC_CONFIG] = { 1226 .packing = sja1105et_mac_config_entry_packing, 1227 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1228 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY, 1229 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1230 }, 1231 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1232 .packing = sja1105et_l2_lookup_params_entry_packing, 1233 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1234 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1235 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1236 }, 1237 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1238 .packing = sja1105_l2_forwarding_params_entry_packing, 1239 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1240 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1241 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1242 }, 1243 [BLK_IDX_AVB_PARAMS] = { 1244 .packing = sja1105et_avb_params_entry_packing, 1245 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1246 .packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY, 1247 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1248 }, 1249 [BLK_IDX_GENERAL_PARAMS] = { 1250 .packing = sja1105et_general_params_entry_packing, 1251 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1252 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY, 1253 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1254 }, 1255 [BLK_IDX_RETAGGING] = { 1256 .packing = sja1105_retagging_entry_packing, 1257 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1258 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1259 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1260 }, 1261 [BLK_IDX_XMII_PARAMS] = { 1262 .packing = sja1105_xmii_params_entry_packing, 1263 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1264 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1265 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1266 }, 1267 }; 1268 1269 /* SJA1105T: First generation, TTEthernet */ 1270 const struct sja1105_table_ops sja1105t_table_ops[BLK_IDX_MAX] = { 1271 [BLK_IDX_SCHEDULE] = { 1272 .packing = sja1105_schedule_entry_packing, 1273 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1274 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY, 1275 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT, 1276 }, 1277 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1278 .packing = sja1105_schedule_entry_points_entry_packing, 1279 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1280 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1281 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1282 }, 1283 [BLK_IDX_VL_LOOKUP] = { 1284 .packing = sja1105_vl_lookup_entry_packing, 1285 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1286 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1287 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 1288 }, 1289 [BLK_IDX_VL_POLICING] = { 1290 .packing = sja1105_vl_policing_entry_packing, 1291 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1292 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1293 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT, 1294 }, 1295 [BLK_IDX_VL_FORWARDING] = { 1296 .packing = sja1105_vl_forwarding_entry_packing, 1297 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1298 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1299 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT, 1300 }, 1301 [BLK_IDX_L2_LOOKUP] = { 1302 .packing = sja1105et_l2_lookup_entry_packing, 1303 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1304 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_ENTRY, 1305 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1306 }, 1307 [BLK_IDX_L2_POLICING] = { 1308 .packing = sja1105_l2_policing_entry_packing, 1309 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1310 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1311 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1312 }, 1313 [BLK_IDX_VLAN_LOOKUP] = { 1314 .packing = sja1105_vlan_lookup_entry_packing, 1315 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1316 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1317 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1318 }, 1319 [BLK_IDX_L2_FORWARDING] = { 1320 .packing = sja1105_l2_forwarding_entry_packing, 1321 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1322 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1323 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1324 }, 1325 [BLK_IDX_MAC_CONFIG] = { 1326 .packing = sja1105et_mac_config_entry_packing, 1327 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1328 .packed_entry_size = SJA1105ET_SIZE_MAC_CONFIG_ENTRY, 1329 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1330 }, 1331 [BLK_IDX_SCHEDULE_PARAMS] = { 1332 .packing = sja1105_schedule_params_entry_packing, 1333 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1334 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1335 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1336 }, 1337 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1338 .packing = sja1105_schedule_entry_points_params_entry_packing, 1339 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1340 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1341 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1342 }, 1343 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1344 .packing = sja1105_vl_forwarding_params_entry_packing, 1345 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1346 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1347 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1348 }, 1349 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1350 .packing = sja1105et_l2_lookup_params_entry_packing, 1351 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1352 .packed_entry_size = SJA1105ET_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1353 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1354 }, 1355 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1356 .packing = sja1105_l2_forwarding_params_entry_packing, 1357 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1358 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1359 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1360 }, 1361 [BLK_IDX_AVB_PARAMS] = { 1362 .packing = sja1105et_avb_params_entry_packing, 1363 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1364 .packed_entry_size = SJA1105ET_SIZE_AVB_PARAMS_ENTRY, 1365 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1366 }, 1367 [BLK_IDX_GENERAL_PARAMS] = { 1368 .packing = sja1105et_general_params_entry_packing, 1369 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1370 .packed_entry_size = SJA1105ET_SIZE_GENERAL_PARAMS_ENTRY, 1371 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1372 }, 1373 [BLK_IDX_RETAGGING] = { 1374 .packing = sja1105_retagging_entry_packing, 1375 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1376 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1377 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1378 }, 1379 [BLK_IDX_XMII_PARAMS] = { 1380 .packing = sja1105_xmii_params_entry_packing, 1381 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1382 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1383 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1384 }, 1385 }; 1386 1387 /* SJA1105P: Second generation, no TTEthernet, no SGMII */ 1388 const struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX] = { 1389 [BLK_IDX_L2_LOOKUP] = { 1390 .packing = sja1105pqrs_l2_lookup_entry_packing, 1391 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1392 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1393 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1394 }, 1395 [BLK_IDX_L2_POLICING] = { 1396 .packing = sja1105_l2_policing_entry_packing, 1397 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1398 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1399 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1400 }, 1401 [BLK_IDX_VLAN_LOOKUP] = { 1402 .packing = sja1105_vlan_lookup_entry_packing, 1403 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1404 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1405 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1406 }, 1407 [BLK_IDX_L2_FORWARDING] = { 1408 .packing = sja1105_l2_forwarding_entry_packing, 1409 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1410 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1411 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1412 }, 1413 [BLK_IDX_MAC_CONFIG] = { 1414 .packing = sja1105pqrs_mac_config_entry_packing, 1415 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1416 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1417 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1418 }, 1419 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1420 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1421 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1422 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1423 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1424 }, 1425 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1426 .packing = sja1105_l2_forwarding_params_entry_packing, 1427 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1428 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1429 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1430 }, 1431 [BLK_IDX_AVB_PARAMS] = { 1432 .packing = sja1105pqrs_avb_params_entry_packing, 1433 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1434 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1435 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1436 }, 1437 [BLK_IDX_GENERAL_PARAMS] = { 1438 .packing = sja1105pqrs_general_params_entry_packing, 1439 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1440 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1441 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1442 }, 1443 [BLK_IDX_RETAGGING] = { 1444 .packing = sja1105_retagging_entry_packing, 1445 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1446 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1447 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1448 }, 1449 [BLK_IDX_XMII_PARAMS] = { 1450 .packing = sja1105_xmii_params_entry_packing, 1451 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1452 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1453 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1454 }, 1455 }; 1456 1457 /* SJA1105Q: Second generation, TTEthernet, no SGMII */ 1458 const struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX] = { 1459 [BLK_IDX_SCHEDULE] = { 1460 .packing = sja1105_schedule_entry_packing, 1461 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1462 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY, 1463 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT, 1464 }, 1465 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1466 .packing = sja1105_schedule_entry_points_entry_packing, 1467 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1468 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1469 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1470 }, 1471 [BLK_IDX_VL_LOOKUP] = { 1472 .packing = sja1105_vl_lookup_entry_packing, 1473 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1474 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1475 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 1476 }, 1477 [BLK_IDX_VL_POLICING] = { 1478 .packing = sja1105_vl_policing_entry_packing, 1479 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1480 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1481 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT, 1482 }, 1483 [BLK_IDX_VL_FORWARDING] = { 1484 .packing = sja1105_vl_forwarding_entry_packing, 1485 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1486 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1487 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT, 1488 }, 1489 [BLK_IDX_L2_LOOKUP] = { 1490 .packing = sja1105pqrs_l2_lookup_entry_packing, 1491 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1492 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1493 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1494 }, 1495 [BLK_IDX_L2_POLICING] = { 1496 .packing = sja1105_l2_policing_entry_packing, 1497 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1498 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1499 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1500 }, 1501 [BLK_IDX_VLAN_LOOKUP] = { 1502 .packing = sja1105_vlan_lookup_entry_packing, 1503 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1504 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1505 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1506 }, 1507 [BLK_IDX_L2_FORWARDING] = { 1508 .packing = sja1105_l2_forwarding_entry_packing, 1509 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1510 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1511 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1512 }, 1513 [BLK_IDX_MAC_CONFIG] = { 1514 .packing = sja1105pqrs_mac_config_entry_packing, 1515 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1516 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1517 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1518 }, 1519 [BLK_IDX_SCHEDULE_PARAMS] = { 1520 .packing = sja1105_schedule_params_entry_packing, 1521 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1522 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1523 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1524 }, 1525 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1526 .packing = sja1105_schedule_entry_points_params_entry_packing, 1527 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1528 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1529 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1530 }, 1531 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1532 .packing = sja1105_vl_forwarding_params_entry_packing, 1533 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1534 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1535 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1536 }, 1537 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1538 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1539 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1540 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1541 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1542 }, 1543 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1544 .packing = sja1105_l2_forwarding_params_entry_packing, 1545 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1546 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1547 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1548 }, 1549 [BLK_IDX_AVB_PARAMS] = { 1550 .packing = sja1105pqrs_avb_params_entry_packing, 1551 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1552 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1553 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1554 }, 1555 [BLK_IDX_GENERAL_PARAMS] = { 1556 .packing = sja1105pqrs_general_params_entry_packing, 1557 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1558 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1559 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1560 }, 1561 [BLK_IDX_RETAGGING] = { 1562 .packing = sja1105_retagging_entry_packing, 1563 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1564 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1565 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1566 }, 1567 [BLK_IDX_XMII_PARAMS] = { 1568 .packing = sja1105_xmii_params_entry_packing, 1569 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1570 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1571 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1572 }, 1573 }; 1574 1575 /* SJA1105R: Second generation, no TTEthernet, SGMII */ 1576 const struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX] = { 1577 [BLK_IDX_L2_LOOKUP] = { 1578 .packing = sja1105pqrs_l2_lookup_entry_packing, 1579 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1580 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1581 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1582 }, 1583 [BLK_IDX_L2_POLICING] = { 1584 .packing = sja1105_l2_policing_entry_packing, 1585 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1586 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1587 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1588 }, 1589 [BLK_IDX_VLAN_LOOKUP] = { 1590 .packing = sja1105_vlan_lookup_entry_packing, 1591 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1592 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1593 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1594 }, 1595 [BLK_IDX_L2_FORWARDING] = { 1596 .packing = sja1105_l2_forwarding_entry_packing, 1597 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1598 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1599 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1600 }, 1601 [BLK_IDX_MAC_CONFIG] = { 1602 .packing = sja1105pqrs_mac_config_entry_packing, 1603 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1604 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1605 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1606 }, 1607 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1608 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1609 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1610 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1611 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1612 }, 1613 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1614 .packing = sja1105_l2_forwarding_params_entry_packing, 1615 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1616 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1617 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1618 }, 1619 [BLK_IDX_AVB_PARAMS] = { 1620 .packing = sja1105pqrs_avb_params_entry_packing, 1621 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1622 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1623 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1624 }, 1625 [BLK_IDX_GENERAL_PARAMS] = { 1626 .packing = sja1105pqrs_general_params_entry_packing, 1627 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1628 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1629 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1630 }, 1631 [BLK_IDX_RETAGGING] = { 1632 .packing = sja1105_retagging_entry_packing, 1633 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1634 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1635 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1636 }, 1637 [BLK_IDX_XMII_PARAMS] = { 1638 .packing = sja1105_xmii_params_entry_packing, 1639 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1640 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1641 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1642 }, 1643 }; 1644 1645 /* SJA1105S: Second generation, TTEthernet, SGMII */ 1646 const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = { 1647 [BLK_IDX_SCHEDULE] = { 1648 .packing = sja1105_schedule_entry_packing, 1649 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1650 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY, 1651 .max_entry_count = SJA1105_MAX_SCHEDULE_COUNT, 1652 }, 1653 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1654 .packing = sja1105_schedule_entry_points_entry_packing, 1655 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1656 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1657 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1658 }, 1659 [BLK_IDX_VL_LOOKUP] = { 1660 .packing = sja1105_vl_lookup_entry_packing, 1661 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1662 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1663 .max_entry_count = SJA1105_MAX_VL_LOOKUP_COUNT, 1664 }, 1665 [BLK_IDX_VL_POLICING] = { 1666 .packing = sja1105_vl_policing_entry_packing, 1667 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1668 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1669 .max_entry_count = SJA1105_MAX_VL_POLICING_COUNT, 1670 }, 1671 [BLK_IDX_VL_FORWARDING] = { 1672 .packing = sja1105_vl_forwarding_entry_packing, 1673 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1674 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1675 .max_entry_count = SJA1105_MAX_VL_FORWARDING_COUNT, 1676 }, 1677 [BLK_IDX_L2_LOOKUP] = { 1678 .packing = sja1105pqrs_l2_lookup_entry_packing, 1679 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1680 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY, 1681 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1682 }, 1683 [BLK_IDX_L2_POLICING] = { 1684 .packing = sja1105_l2_policing_entry_packing, 1685 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1686 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1687 .max_entry_count = SJA1105_MAX_L2_POLICING_COUNT, 1688 }, 1689 [BLK_IDX_VLAN_LOOKUP] = { 1690 .packing = sja1105_vlan_lookup_entry_packing, 1691 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1692 .packed_entry_size = SJA1105_SIZE_VLAN_LOOKUP_ENTRY, 1693 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1694 }, 1695 [BLK_IDX_L2_FORWARDING] = { 1696 .packing = sja1105_l2_forwarding_entry_packing, 1697 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1698 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1699 .max_entry_count = SJA1105_MAX_L2_FORWARDING_COUNT, 1700 }, 1701 [BLK_IDX_MAC_CONFIG] = { 1702 .packing = sja1105pqrs_mac_config_entry_packing, 1703 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1704 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1705 .max_entry_count = SJA1105_MAX_MAC_CONFIG_COUNT, 1706 }, 1707 [BLK_IDX_SCHEDULE_PARAMS] = { 1708 .packing = sja1105_schedule_params_entry_packing, 1709 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1710 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1711 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1712 }, 1713 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1714 .packing = sja1105_schedule_entry_points_params_entry_packing, 1715 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1716 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1717 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1718 }, 1719 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1720 .packing = sja1105_vl_forwarding_params_entry_packing, 1721 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1722 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1723 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1724 }, 1725 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1726 .packing = sja1105pqrs_l2_lookup_params_entry_packing, 1727 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1728 .packed_entry_size = SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1729 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1730 }, 1731 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1732 .packing = sja1105_l2_forwarding_params_entry_packing, 1733 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1734 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1735 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1736 }, 1737 [BLK_IDX_AVB_PARAMS] = { 1738 .packing = sja1105pqrs_avb_params_entry_packing, 1739 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1740 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1741 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1742 }, 1743 [BLK_IDX_GENERAL_PARAMS] = { 1744 .packing = sja1105pqrs_general_params_entry_packing, 1745 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1746 .packed_entry_size = SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY, 1747 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1748 }, 1749 [BLK_IDX_RETAGGING] = { 1750 .packing = sja1105_retagging_entry_packing, 1751 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1752 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1753 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1754 }, 1755 [BLK_IDX_XMII_PARAMS] = { 1756 .packing = sja1105_xmii_params_entry_packing, 1757 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1758 .packed_entry_size = SJA1105_SIZE_XMII_PARAMS_ENTRY, 1759 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1760 }, 1761 }; 1762 1763 /* SJA1110A: Third generation */ 1764 const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX] = { 1765 [BLK_IDX_SCHEDULE] = { 1766 .packing = sja1110_schedule_entry_packing, 1767 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), 1768 .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY, 1769 .max_entry_count = SJA1110_MAX_SCHEDULE_COUNT, 1770 }, 1771 [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { 1772 .packing = sja1110_schedule_entry_points_entry_packing, 1773 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), 1774 .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, 1775 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, 1776 }, 1777 [BLK_IDX_VL_LOOKUP] = { 1778 .packing = sja1110_vl_lookup_entry_packing, 1779 .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), 1780 .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, 1781 .max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT, 1782 }, 1783 [BLK_IDX_VL_POLICING] = { 1784 .packing = sja1110_vl_policing_entry_packing, 1785 .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), 1786 .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, 1787 .max_entry_count = SJA1110_MAX_VL_POLICING_COUNT, 1788 }, 1789 [BLK_IDX_VL_FORWARDING] = { 1790 .packing = sja1110_vl_forwarding_entry_packing, 1791 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), 1792 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, 1793 .max_entry_count = SJA1110_MAX_VL_FORWARDING_COUNT, 1794 }, 1795 [BLK_IDX_L2_LOOKUP] = { 1796 .packing = sja1110_l2_lookup_entry_packing, 1797 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), 1798 .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_ENTRY, 1799 .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, 1800 }, 1801 [BLK_IDX_L2_POLICING] = { 1802 .packing = sja1110_l2_policing_entry_packing, 1803 .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), 1804 .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, 1805 .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT, 1806 }, 1807 [BLK_IDX_VLAN_LOOKUP] = { 1808 .packing = sja1110_vlan_lookup_entry_packing, 1809 .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), 1810 .packed_entry_size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY, 1811 .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, 1812 }, 1813 [BLK_IDX_L2_FORWARDING] = { 1814 .packing = sja1110_l2_forwarding_entry_packing, 1815 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), 1816 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, 1817 .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT, 1818 }, 1819 [BLK_IDX_MAC_CONFIG] = { 1820 .packing = sja1110_mac_config_entry_packing, 1821 .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), 1822 .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, 1823 .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT, 1824 }, 1825 [BLK_IDX_SCHEDULE_PARAMS] = { 1826 .packing = sja1110_schedule_params_entry_packing, 1827 .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), 1828 .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, 1829 .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, 1830 }, 1831 [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { 1832 .packing = sja1105_schedule_entry_points_params_entry_packing, 1833 .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), 1834 .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, 1835 .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, 1836 }, 1837 [BLK_IDX_VL_FORWARDING_PARAMS] = { 1838 .packing = sja1110_vl_forwarding_params_entry_packing, 1839 .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), 1840 .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, 1841 .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, 1842 }, 1843 [BLK_IDX_L2_LOOKUP_PARAMS] = { 1844 .packing = sja1110_l2_lookup_params_entry_packing, 1845 .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), 1846 .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY, 1847 .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, 1848 }, 1849 [BLK_IDX_L2_FORWARDING_PARAMS] = { 1850 .packing = sja1110_l2_forwarding_params_entry_packing, 1851 .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), 1852 .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, 1853 .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, 1854 }, 1855 [BLK_IDX_AVB_PARAMS] = { 1856 .packing = sja1105pqrs_avb_params_entry_packing, 1857 .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), 1858 .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, 1859 .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, 1860 }, 1861 [BLK_IDX_GENERAL_PARAMS] = { 1862 .packing = sja1110_general_params_entry_packing, 1863 .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), 1864 .packed_entry_size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY, 1865 .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, 1866 }, 1867 [BLK_IDX_RETAGGING] = { 1868 .packing = sja1110_retagging_entry_packing, 1869 .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), 1870 .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, 1871 .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, 1872 }, 1873 [BLK_IDX_XMII_PARAMS] = { 1874 .packing = sja1110_xmii_params_entry_packing, 1875 .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), 1876 .packed_entry_size = SJA1110_SIZE_XMII_PARAMS_ENTRY, 1877 .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, 1878 }, 1879 [BLK_IDX_PCP_REMAPPING] = { 1880 .packing = sja1110_pcp_remapping_entry_packing, 1881 .unpacked_entry_size = sizeof(struct sja1110_pcp_remapping_entry), 1882 .packed_entry_size = SJA1110_SIZE_PCP_REMAPPING_ENTRY, 1883 .max_entry_count = SJA1110_MAX_PCP_REMAPPING_COUNT, 1884 }, 1885 }; 1886 1887 int sja1105_static_config_init(struct sja1105_static_config *config, 1888 const struct sja1105_table_ops *static_ops, 1889 u64 device_id) 1890 { 1891 enum sja1105_blk_idx i; 1892 1893 *config = (struct sja1105_static_config) {0}; 1894 1895 /* Transfer static_ops array from priv into per-table ops 1896 * for handier access 1897 */ 1898 for (i = 0; i < BLK_IDX_MAX; i++) 1899 config->tables[i].ops = &static_ops[i]; 1900 1901 config->device_id = device_id; 1902 return 0; 1903 } 1904 1905 void sja1105_static_config_free(struct sja1105_static_config *config) 1906 { 1907 enum sja1105_blk_idx i; 1908 1909 for (i = 0; i < BLK_IDX_MAX; i++) { 1910 if (config->tables[i].entry_count) { 1911 kfree(config->tables[i].entries); 1912 config->tables[i].entry_count = 0; 1913 } 1914 } 1915 } 1916 1917 int sja1105_table_delete_entry(struct sja1105_table *table, int i) 1918 { 1919 size_t entry_size = table->ops->unpacked_entry_size; 1920 u8 *entries = table->entries; 1921 1922 if (i > table->entry_count) 1923 return -ERANGE; 1924 1925 memmove(entries + i * entry_size, entries + (i + 1) * entry_size, 1926 (table->entry_count - i) * entry_size); 1927 1928 table->entry_count--; 1929 1930 return 0; 1931 } 1932 1933 /* No pointers to table->entries should be kept when this is called. */ 1934 int sja1105_table_resize(struct sja1105_table *table, size_t new_count) 1935 { 1936 size_t entry_size = table->ops->unpacked_entry_size; 1937 void *new_entries, *old_entries = table->entries; 1938 1939 if (new_count > table->ops->max_entry_count) 1940 return -ERANGE; 1941 1942 new_entries = kcalloc(new_count, entry_size, GFP_KERNEL); 1943 if (!new_entries) 1944 return -ENOMEM; 1945 1946 memcpy(new_entries, old_entries, min(new_count, table->entry_count) * 1947 entry_size); 1948 1949 table->entries = new_entries; 1950 table->entry_count = new_count; 1951 kfree(old_entries); 1952 return 0; 1953 } 1954