linux/drivers/net/dsa/sja1105/sja1105_static_config.c
<<
>>
Prefs
   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                if ((start - end + 1) > 64)
  30                        pr_err("Field %d-%d too large for 64 bits!\n",
  31                               start, end);
  32                else
  33                        pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n",
  34                               *val, start, end);
  35        }
  36        dump_stack();
  37}
  38
  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                else
  72                        pr_err("Cannot store %llx inside bits %d-%d (would truncate)\n",
  73                               *val, start, end);
  74        }
  75        dump_stack();
  76}
  77
  78/* Little-endian Ethernet CRC32 of data packed as big-endian u32 words */
  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 semantic
 147 * 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_t
 221sja1105_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_t
 287sja1105et_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_t
 549sja1105_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_t
 561sja1105_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_t
 574sja1110_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_t
 651sja1105_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_t
 666sja1110_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 is
 930 * modifying the CRC of the header for a 2-stage packing operation
 931 */
 932void
 933sja1105_table_header_pack_with_crc(void *buf, struct sja1105_table_header *hdr)
 934{
 935        /* First pack the table as-is, then calculate the CRC, and
 936         * finally put the proper CRC into the packed buffer
 937         */
 938        memset(buf, 0, SJA1105_SIZE_TABLE_HEADER);
 939        sja1105_table_header_packing(buf, hdr, PACK);
 940        hdr->crc = sja1105_crc32(buf, SJA1105_SIZE_TABLE_HEADER - 4);
 941        sja1105_pack(buf + SJA1105_SIZE_TABLE_HEADER - 4, &hdr->crc, 31, 0, 4);
 942}
 943
 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 a
 955 * mapping table to "block indices" and translate back and forth so that we
 956 * don't waste useless memory in struct sja1105_static_config.
 957 * Also, since the block id comes from essentially untrusted input (unpacking
 958 * the static config from userspace) it has to be sanitized (range-checked)
 959 * before blindly indexing kernel memory with the blk_idx.
 960 */
 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_t
1020static_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_t
1047sja1105_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_FULL
1117}
1118
1119void
1120sja1105_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 matter
1157         * Length of 0 marks that header is final
1158         * 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_t
1168sja1105_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 ops
1895         * for handier access
1896         */
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