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