File Index
Files and directories
Sign in
FILE

sja1105_static_config.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/dsa/sja1105/sja1105_static_config.c C
   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 */
  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		pr_err("Field %d-%d too large for 64 bits!\n",
  30		       start, end);
  31	}
  32	dump_stack();
  33}
  34
  35void 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
  52void 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 */
  75u32 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
  90static 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
 101size_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
 113static 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 */
 145size_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
 179size_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
 216static size_t
 217sja1105_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
 231size_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
 245size_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
 261size_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
 282static size_t
 283sja1105et_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
 298size_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
 320size_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
 342size_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
 356size_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
 384size_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
 414static 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
 428size_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
 442static 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
 476size_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
 510size_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
 544static size_t
 545sja1105_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
 556static size_t
 557sja1105_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
 569static size_t
 570sja1110_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
 582static 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
 595static 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
 608static 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
 627static 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
 646static size_t
 647sja1105_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
 661static size_t
 662sja1110_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
 676static 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
 689static 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
 702size_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
 736size_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
 770static 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
 786size_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
 802size_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
 817size_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
 833static 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
 849size_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
 867size_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
 883size_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
 899static 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
 913size_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 */
 928void
 929sja1105_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
 940static 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 */
 957static 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
 980const 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
1015static sja1105_config_valid_t
1016static_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
1042sja1105_config_valid_t
1043sja1105_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
1115void
1116sja1105_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
1163size_t
1164sja1105_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 */
1195const 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 */
1265const 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 */
1383const 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 */
1453const 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 */
1571const 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 */
1641const 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 */
1759const 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
1882int 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
1900void 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
1912int 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	if (i + 1 < table->entry_count) {
1921		memmove(entries + i * entry_size, entries + (i + 1) * entry_size,
1922			(table->entry_count - i - 1) * entry_size);
1923	}
1924
1925	table->entry_count--;
1926
1927	return 0;
1928}
1929
1930/* No pointers to table->entries should be kept when this is called. */
1931int sja1105_table_resize(struct sja1105_table *table, size_t new_count)
1932{
1933	size_t entry_size = table->ops->unpacked_entry_size;
1934	void *new_entries, *old_entries = table->entries;
1935
1936	if (new_count > table->ops->max_entry_count)
1937		return -ERANGE;
1938
1939	new_entries = kcalloc(new_count, entry_size, GFP_KERNEL);
1940	if (!new_entries)
1941		return -ENOMEM;
1942
1943	memcpy(new_entries, old_entries, min(new_count, table->entry_count) *
1944		entry_size);
1945
1946	table->entries = new_entries;
1947	table->entry_count = new_count;
1948	kfree(old_entries);
1949	return 0;
1950}
~/ Read-only file preview.