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