brintos

brintos / linux-shallow public Read only

0
0
Text · 74.3 KiB · baba204 Raw
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