cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fman_keygen.c (22879B)


      1/*
      2 * Copyright 2017 NXP
      3 *
      4 * Redistribution and use in source and binary forms, with or without
      5 * modification, are permitted provided that the following conditions are met:
      6 *     * Redistributions of source code must retain the above copyright
      7 *       notice, this list of conditions and the following disclaimer.
      8 *     * Redistributions in binary form must reproduce the above copyright
      9 *       notice, this list of conditions and the following disclaimer in the
     10 *       documentation and/or other materials provided with the distribution.
     11 *     * Neither the name of NXP nor the
     12 *       names of its contributors may be used to endorse or promote products
     13 *       derived from this software without specific prior written permission.
     14 *
     15 *
     16 * ALTERNATIVELY, this software may be distributed under the terms of the
     17 * GNU General Public License ("GPL") as published by the Free Software
     18 * Foundation, either version 2 of that License or (at your option) any
     19 * later version.
     20 *
     21 * THIS SOFTWARE IS PROVIDED BY NXP ``AS IS'' AND ANY
     22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     24 * DISCLAIMED. IN NO EVENT SHALL NXP BE LIABLE FOR ANY
     25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31 */
     32
     33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     34
     35#include <linux/slab.h>
     36
     37#include "fman_keygen.h"
     38
     39/* Maximum number of HW Ports */
     40#define FMAN_MAX_NUM_OF_HW_PORTS		64
     41
     42/* Maximum number of KeyGen Schemes */
     43#define FM_KG_MAX_NUM_OF_SCHEMES		32
     44
     45/* Number of generic KeyGen Generic Extract Command Registers */
     46#define FM_KG_NUM_OF_GENERIC_REGS		8
     47
     48/* Dummy port ID */
     49#define DUMMY_PORT_ID				0
     50
     51/* Select Scheme Value Register */
     52#define KG_SCH_DEF_USE_KGSE_DV_0		2
     53#define KG_SCH_DEF_USE_KGSE_DV_1		3
     54
     55/* Registers Shifting values */
     56#define FM_KG_KGAR_NUM_SHIFT			16
     57#define KG_SCH_DEF_L4_PORT_SHIFT		8
     58#define KG_SCH_DEF_IP_ADDR_SHIFT		18
     59#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT		24
     60
     61/* KeyGen Registers bit field masks: */
     62
     63/* Enable bit field mask for KeyGen General Configuration Register */
     64#define FM_KG_KGGCR_EN				0x80000000
     65
     66/* KeyGen Global Registers bit field masks */
     67#define FM_KG_KGAR_GO				0x80000000
     68#define FM_KG_KGAR_READ				0x40000000
     69#define FM_KG_KGAR_WRITE			0x00000000
     70#define FM_KG_KGAR_SEL_SCHEME_ENTRY		0x00000000
     71#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT		0x00008000
     72
     73#define FM_KG_KGAR_ERR				0x20000000
     74#define FM_KG_KGAR_SEL_CLS_PLAN_ENTRY		0x01000000
     75#define FM_KG_KGAR_SEL_PORT_ENTRY		0x02000000
     76#define FM_KG_KGAR_SEL_PORT_WSEL_SP		0x00008000
     77#define FM_KG_KGAR_SEL_PORT_WSEL_CPP		0x00004000
     78
     79/* Error events exceptions */
     80#define FM_EX_KG_DOUBLE_ECC			0x80000000
     81#define FM_EX_KG_KEYSIZE_OVERFLOW		0x40000000
     82
     83/* Scheme Registers bit field masks */
     84#define KG_SCH_MODE_EN				0x80000000
     85#define KG_SCH_VSP_NO_KSP_EN			0x80000000
     86#define KG_SCH_HASH_CONFIG_SYM			0x40000000
     87
     88/* Known Protocol field codes */
     89#define KG_SCH_KN_PORT_ID		0x80000000
     90#define KG_SCH_KN_MACDST		0x40000000
     91#define KG_SCH_KN_MACSRC		0x20000000
     92#define KG_SCH_KN_TCI1			0x10000000
     93#define KG_SCH_KN_TCI2			0x08000000
     94#define KG_SCH_KN_ETYPE			0x04000000
     95#define KG_SCH_KN_PPPSID		0x02000000
     96#define KG_SCH_KN_PPPID			0x01000000
     97#define KG_SCH_KN_MPLS1			0x00800000
     98#define KG_SCH_KN_MPLS2			0x00400000
     99#define KG_SCH_KN_MPLS_LAST		0x00200000
    100#define KG_SCH_KN_IPSRC1		0x00100000
    101#define KG_SCH_KN_IPDST1		0x00080000
    102#define KG_SCH_KN_PTYPE1		0x00040000
    103#define KG_SCH_KN_IPTOS_TC1		0x00020000
    104#define KG_SCH_KN_IPV6FL1		0x00010000
    105#define KG_SCH_KN_IPSRC2		0x00008000
    106#define KG_SCH_KN_IPDST2		0x00004000
    107#define KG_SCH_KN_PTYPE2		0x00002000
    108#define KG_SCH_KN_IPTOS_TC2		0x00001000
    109#define KG_SCH_KN_IPV6FL2		0x00000800
    110#define KG_SCH_KN_GREPTYPE		0x00000400
    111#define KG_SCH_KN_IPSEC_SPI		0x00000200
    112#define KG_SCH_KN_IPSEC_NH		0x00000100
    113#define KG_SCH_KN_IPPID			0x00000080
    114#define KG_SCH_KN_L4PSRC		0x00000004
    115#define KG_SCH_KN_L4PDST		0x00000002
    116#define KG_SCH_KN_TFLG			0x00000001
    117
    118/* NIA values */
    119#define NIA_ENG_BMI			0x00500000
    120#define NIA_BMI_AC_ENQ_FRAME		0x00000002
    121#define ENQUEUE_KG_DFLT_NIA		(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
    122
    123/* Hard-coded configuration:
    124 * These values are used as hard-coded values for KeyGen configuration
    125 * and they replace user selections for this hard-coded version
    126 */
    127
    128/* Hash distribution shift */
    129#define DEFAULT_HASH_DIST_FQID_SHIFT		0
    130
    131/* Hash shift */
    132#define DEFAULT_HASH_SHIFT			0
    133
    134/* Symmetric hash usage:
    135 * Warning:
    136 * - the value for symmetric hash usage must be in accordance with hash
    137 *	key defined below
    138 * - according to tests performed, spreading is not working if symmetric
    139 *	hash is set on true
    140 * So ultimately symmetric hash functionality should be always disabled:
    141 */
    142#define DEFAULT_SYMMETRIC_HASH			false
    143
    144/* Hash Key extraction fields: */
    145#define DEFAULT_HASH_KEY_EXTRACT_FIELDS		\
    146	(KG_SCH_KN_IPSRC1 | KG_SCH_KN_IPDST1 | \
    147	 KG_SCH_KN_L4PSRC | KG_SCH_KN_L4PDST | \
    148	 KG_SCH_KN_IPSEC_SPI)
    149
    150/* Default values to be used as hash key in case IPv4 or L4 (TCP, UDP)
    151 * don't exist in the frame
    152 */
    153/* Default IPv4 address */
    154#define DEFAULT_HASH_KEY_IPv4_ADDR		0x0A0A0A0A
    155/* Default L4 port */
    156#define DEFAULT_HASH_KEY_L4_PORT		0x0B0B0B0B
    157
    158/* KeyGen Memory Mapped Registers: */
    159
    160/* Scheme Configuration RAM Registers */
    161struct fman_kg_scheme_regs {
    162	u32 kgse_mode;		/* 0x100: MODE */
    163	u32 kgse_ekfc;		/* 0x104: Extract Known Fields Command */
    164	u32 kgse_ekdv;		/* 0x108: Extract Known Default Value */
    165	u32 kgse_bmch;		/* 0x10C: Bit Mask Command High */
    166	u32 kgse_bmcl;		/* 0x110: Bit Mask Command Low */
    167	u32 kgse_fqb;		/* 0x114: Frame Queue Base */
    168	u32 kgse_hc;		/* 0x118: Hash Command */
    169	u32 kgse_ppc;		/* 0x11C: Policer Profile Command */
    170	u32 kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
    171			/* 0x120: Generic Extract Command */
    172	u32 kgse_spc;
    173		/* 0x140: KeyGen Scheme Entry Statistic Packet Counter */
    174	u32 kgse_dv0;	/* 0x144: KeyGen Scheme Entry Default Value 0 */
    175	u32 kgse_dv1;	/* 0x148: KeyGen Scheme Entry Default Value 1 */
    176	u32 kgse_ccbs;
    177		/* 0x14C: KeyGen Scheme Entry Coarse Classification Bit*/
    178	u32 kgse_mv;	/* 0x150: KeyGen Scheme Entry Match vector */
    179	u32 kgse_om;	/* 0x154: KeyGen Scheme Entry Operation Mode bits */
    180	u32 kgse_vsp;
    181		/* 0x158: KeyGen Scheme Entry Virtual Storage Profile */
    182};
    183
    184/* Port Partition Configuration Registers */
    185struct fman_kg_pe_regs {
    186	u32 fmkg_pe_sp;		/* 0x100: KeyGen Port entry Scheme Partition */
    187	u32 fmkg_pe_cpp;
    188		/* 0x104: KeyGen Port Entry Classification Plan Partition */
    189};
    190
    191/* General Configuration and Status Registers
    192 * Global Statistic Counters
    193 * KeyGen Global Registers
    194 */
    195struct fman_kg_regs {
    196	u32 fmkg_gcr;	/* 0x000: KeyGen General Configuration Register */
    197	u32 res004;	/* 0x004: Reserved */
    198	u32 res008;	/* 0x008: Reserved */
    199	u32 fmkg_eer;	/* 0x00C: KeyGen Error Event Register */
    200	u32 fmkg_eeer;	/* 0x010: KeyGen Error Event Enable Register */
    201	u32 res014;	/* 0x014: Reserved */
    202	u32 res018;	/* 0x018: Reserved */
    203	u32 fmkg_seer;	/* 0x01C: KeyGen Scheme Error Event Register */
    204	u32 fmkg_seeer;	/* 0x020: KeyGen Scheme Error Event Enable Register */
    205	u32 fmkg_gsr;	/* 0x024: KeyGen Global Status Register */
    206	u32 fmkg_tpc;	/* 0x028: Total Packet Counter Register */
    207	u32 fmkg_serc;	/* 0x02C: Soft Error Capture Register */
    208	u32 res030[4];	/* 0x030: Reserved */
    209	u32 fmkg_fdor;	/* 0x034: Frame Data Offset Register */
    210	u32 fmkg_gdv0r;	/* 0x038: Global Default Value Register 0 */
    211	u32 fmkg_gdv1r;	/* 0x03C: Global Default Value Register 1 */
    212	u32 res04c[6];	/* 0x040: Reserved */
    213	u32 fmkg_feer;	/* 0x044: Force Error Event Register */
    214	u32 res068[38];	/* 0x048: Reserved */
    215	union {
    216		u32 fmkg_indirect[63];	/* 0x100: Indirect Access Registers */
    217		struct fman_kg_scheme_regs fmkg_sch; /* Scheme Registers */
    218		struct fman_kg_pe_regs fmkg_pe; /* Port Partition Registers */
    219	};
    220	u32 fmkg_ar;	/* 0x1FC: KeyGen Action Register */
    221};
    222
    223/* KeyGen Scheme data */
    224struct keygen_scheme {
    225	bool used;	/* Specifies if this scheme is used */
    226	u8 hw_port_id;
    227		/* Hardware port ID
    228		 * schemes sharing between multiple ports is not
    229		 * currently supported
    230		 * so we have only one port id bound to a scheme
    231		 */
    232	u32 base_fqid;
    233		/* Base FQID:
    234		 * Must be between 1 and 2^24-1
    235		 * If hash is used and an even distribution is
    236		 * expected according to hash_fqid_count,
    237		 * base_fqid must be aligned to hash_fqid_count
    238		 */
    239	u32 hash_fqid_count;
    240		/* FQ range for hash distribution:
    241		 * Must be a power of 2
    242		 * Represents the range of queues for spreading
    243		 */
    244	bool use_hashing;	/* Usage of Hashing and spreading over FQ */
    245	bool symmetric_hash;	/* Symmetric Hash option usage */
    246	u8 hashShift;
    247		/* Hash result right shift.
    248		 * Select the 24 bits out of the 64 hash result.
    249		 * 0 means using the 24 LSB's, otherwise
    250		 * use the 24 LSB's after shifting right
    251		 */
    252	u32 match_vector;	/* Match Vector */
    253};
    254
    255/* KeyGen driver data */
    256struct fman_keygen {
    257	struct keygen_scheme schemes[FM_KG_MAX_NUM_OF_SCHEMES];
    258				/* Array of schemes */
    259	struct fman_kg_regs __iomem *keygen_regs;	/* KeyGen registers */
    260};
    261
    262/* keygen_write_ar_wait
    263 *
    264 * Write Action Register with specified value, wait for GO bit field to be
    265 * idle and then read the error
    266 *
    267 * regs: KeyGen registers
    268 * fmkg_ar: Action Register value
    269 *
    270 * Return: Zero for success or error code in case of failure
    271 */
    272static int keygen_write_ar_wait(struct fman_kg_regs __iomem *regs, u32 fmkg_ar)
    273{
    274	iowrite32be(fmkg_ar, &regs->fmkg_ar);
    275
    276	/* Wait for GO bit field to be idle */
    277	while (fmkg_ar & FM_KG_KGAR_GO)
    278		fmkg_ar = ioread32be(&regs->fmkg_ar);
    279
    280	if (fmkg_ar & FM_KG_KGAR_ERR)
    281		return -EINVAL;
    282
    283	return 0;
    284}
    285
    286/* build_ar_scheme
    287 *
    288 * Build Action Register value for scheme settings
    289 *
    290 * scheme_id: Scheme ID
    291 * update_counter: update scheme counter
    292 * write: true for action to write the scheme or false for read action
    293 *
    294 * Return: AR value
    295 */
    296static u32 build_ar_scheme(u8 scheme_id, bool update_counter, bool write)
    297{
    298	u32 rw = (u32)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
    299
    300	return (u32)(FM_KG_KGAR_GO |
    301			rw |
    302			FM_KG_KGAR_SEL_SCHEME_ENTRY |
    303			DUMMY_PORT_ID |
    304			((u32)scheme_id << FM_KG_KGAR_NUM_SHIFT) |
    305			(update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
    306}
    307
    308/* build_ar_bind_scheme
    309 *
    310 * Build Action Register value for port binding to schemes
    311 *
    312 * hwport_id: HW Port ID
    313 * write: true for action to write the bind or false for read action
    314 *
    315 * Return: AR value
    316 */
    317static u32 build_ar_bind_scheme(u8 hwport_id, bool write)
    318{
    319	u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;
    320
    321	return (u32)(FM_KG_KGAR_GO |
    322			rw |
    323			FM_KG_KGAR_SEL_PORT_ENTRY |
    324			hwport_id |
    325			FM_KG_KGAR_SEL_PORT_WSEL_SP);
    326}
    327
    328/* keygen_write_sp
    329 *
    330 * Write Scheme Partition Register with specified value
    331 *
    332 * regs: KeyGen Registers
    333 * sp: Scheme Partition register value
    334 * add: true to add a scheme partition or false to clear
    335 *
    336 * Return: none
    337 */
    338static void keygen_write_sp(struct fman_kg_regs __iomem *regs, u32 sp, bool add)
    339{
    340	u32 tmp;
    341
    342	tmp = ioread32be(&regs->fmkg_pe.fmkg_pe_sp);
    343
    344	if (add)
    345		tmp |= sp;
    346	else
    347		tmp &= ~sp;
    348
    349	iowrite32be(tmp, &regs->fmkg_pe.fmkg_pe_sp);
    350}
    351
    352/* build_ar_bind_cls_plan
    353 *
    354 * Build Action Register value for Classification Plan
    355 *
    356 * hwport_id: HW Port ID
    357 * write: true for action to write the CP or false for read action
    358 *
    359 * Return: AR value
    360 */
    361static u32 build_ar_bind_cls_plan(u8 hwport_id, bool write)
    362{
    363	u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;
    364
    365	return (u32)(FM_KG_KGAR_GO |
    366			rw |
    367			FM_KG_KGAR_SEL_PORT_ENTRY |
    368			hwport_id |
    369			FM_KG_KGAR_SEL_PORT_WSEL_CPP);
    370}
    371
    372/* keygen_write_cpp
    373 *
    374 * Write Classification Plan Partition Register with specified value
    375 *
    376 * regs: KeyGen Registers
    377 * cpp: CPP register value
    378 *
    379 * Return: none
    380 */
    381static void keygen_write_cpp(struct fman_kg_regs __iomem *regs, u32 cpp)
    382{
    383	iowrite32be(cpp, &regs->fmkg_pe.fmkg_pe_cpp);
    384}
    385
    386/* keygen_write_scheme
    387 *
    388 * Write all Schemes Registers with specified values
    389 *
    390 * regs: KeyGen Registers
    391 * scheme_id: Scheme ID
    392 * scheme_regs: Scheme registers values desired to be written
    393 * update_counter: update scheme counter
    394 *
    395 * Return: Zero for success or error code in case of failure
    396 */
    397static int keygen_write_scheme(struct fman_kg_regs __iomem *regs, u8 scheme_id,
    398			       struct fman_kg_scheme_regs *scheme_regs,
    399				bool update_counter)
    400{
    401	u32 ar_reg;
    402	int err, i;
    403
    404	/* Write indirect scheme registers */
    405	iowrite32be(scheme_regs->kgse_mode, &regs->fmkg_sch.kgse_mode);
    406	iowrite32be(scheme_regs->kgse_ekfc, &regs->fmkg_sch.kgse_ekfc);
    407	iowrite32be(scheme_regs->kgse_ekdv, &regs->fmkg_sch.kgse_ekdv);
    408	iowrite32be(scheme_regs->kgse_bmch, &regs->fmkg_sch.kgse_bmch);
    409	iowrite32be(scheme_regs->kgse_bmcl, &regs->fmkg_sch.kgse_bmcl);
    410	iowrite32be(scheme_regs->kgse_fqb, &regs->fmkg_sch.kgse_fqb);
    411	iowrite32be(scheme_regs->kgse_hc, &regs->fmkg_sch.kgse_hc);
    412	iowrite32be(scheme_regs->kgse_ppc, &regs->fmkg_sch.kgse_ppc);
    413	iowrite32be(scheme_regs->kgse_spc, &regs->fmkg_sch.kgse_spc);
    414	iowrite32be(scheme_regs->kgse_dv0, &regs->fmkg_sch.kgse_dv0);
    415	iowrite32be(scheme_regs->kgse_dv1, &regs->fmkg_sch.kgse_dv1);
    416	iowrite32be(scheme_regs->kgse_ccbs, &regs->fmkg_sch.kgse_ccbs);
    417	iowrite32be(scheme_regs->kgse_mv, &regs->fmkg_sch.kgse_mv);
    418	iowrite32be(scheme_regs->kgse_om, &regs->fmkg_sch.kgse_om);
    419	iowrite32be(scheme_regs->kgse_vsp, &regs->fmkg_sch.kgse_vsp);
    420
    421	for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
    422		iowrite32be(scheme_regs->kgse_gec[i],
    423			    &regs->fmkg_sch.kgse_gec[i]);
    424
    425	/* Write AR (Action register) */
    426	ar_reg = build_ar_scheme(scheme_id, update_counter, true);
    427	err = keygen_write_ar_wait(regs, ar_reg);
    428	if (err != 0) {
    429		pr_err("Writing Action Register failed\n");
    430		return err;
    431	}
    432
    433	return err;
    434}
    435
    436/* get_free_scheme_id
    437 *
    438 * Find the first free scheme available to be used
    439 *
    440 * keygen: KeyGen handle
    441 * scheme_id: pointer to scheme id
    442 *
    443 * Return: 0 on success, -EINVAL when the are no available free schemes
    444 */
    445static int get_free_scheme_id(struct fman_keygen *keygen, u8 *scheme_id)
    446{
    447	u8 i;
    448
    449	for (i = 0; i < FM_KG_MAX_NUM_OF_SCHEMES; i++)
    450		if (!keygen->schemes[i].used) {
    451			*scheme_id = i;
    452			return 0;
    453		}
    454
    455	return -EINVAL;
    456}
    457
    458/* get_scheme
    459 *
    460 * Provides the scheme for specified ID
    461 *
    462 * keygen: KeyGen handle
    463 * scheme_id: Scheme ID
    464 *
    465 * Return: handle to required scheme
    466 */
    467static struct keygen_scheme *get_scheme(struct fman_keygen *keygen,
    468					u8 scheme_id)
    469{
    470	if (scheme_id >= FM_KG_MAX_NUM_OF_SCHEMES)
    471		return NULL;
    472	return &keygen->schemes[scheme_id];
    473}
    474
    475/* keygen_bind_port_to_schemes
    476 *
    477 * Bind the port to schemes
    478 *
    479 * keygen: KeyGen handle
    480 * scheme_id: id of the scheme to bind to
    481 * bind: true to bind the port or false to unbind it
    482 *
    483 * Return: Zero for success or error code in case of failure
    484 */
    485static int keygen_bind_port_to_schemes(struct fman_keygen *keygen,
    486				       u8 scheme_id,
    487					bool bind)
    488{
    489	struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;
    490	struct keygen_scheme *scheme;
    491	u32 ar_reg;
    492	u32 schemes_vector = 0;
    493	int err;
    494
    495	scheme = get_scheme(keygen, scheme_id);
    496	if (!scheme) {
    497		pr_err("Requested Scheme does not exist\n");
    498		return -EINVAL;
    499	}
    500	if (!scheme->used) {
    501		pr_err("Cannot bind port to an invalid scheme\n");
    502		return -EINVAL;
    503	}
    504
    505	schemes_vector |= 1 << (31 - scheme_id);
    506
    507	ar_reg = build_ar_bind_scheme(scheme->hw_port_id, false);
    508	err = keygen_write_ar_wait(keygen_regs, ar_reg);
    509	if (err != 0) {
    510		pr_err("Reading Action Register failed\n");
    511		return err;
    512	}
    513
    514	keygen_write_sp(keygen_regs, schemes_vector, bind);
    515
    516	ar_reg = build_ar_bind_scheme(scheme->hw_port_id, true);
    517	err = keygen_write_ar_wait(keygen_regs, ar_reg);
    518	if (err != 0) {
    519		pr_err("Writing Action Register failed\n");
    520		return err;
    521	}
    522
    523	return 0;
    524}
    525
    526/* keygen_scheme_setup
    527 *
    528 * Setup the scheme according to required configuration
    529 *
    530 * keygen: KeyGen handle
    531 * scheme_id: scheme ID
    532 * enable: true to enable scheme or false to disable it
    533 *
    534 * Return: Zero for success or error code in case of failure
    535 */
    536static int keygen_scheme_setup(struct fman_keygen *keygen, u8 scheme_id,
    537			       bool enable)
    538{
    539	struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;
    540	struct fman_kg_scheme_regs scheme_regs;
    541	struct keygen_scheme *scheme;
    542	u32 tmp_reg;
    543	int err;
    544
    545	scheme = get_scheme(keygen, scheme_id);
    546	if (!scheme) {
    547		pr_err("Requested Scheme does not exist\n");
    548		return -EINVAL;
    549	}
    550	if (enable && scheme->used) {
    551		pr_err("The requested Scheme is already used\n");
    552		return -EINVAL;
    553	}
    554
    555	/* Clear scheme registers */
    556	memset(&scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
    557
    558	/* Setup all scheme registers: */
    559	tmp_reg = 0;
    560
    561	if (enable) {
    562		/* Enable Scheme */
    563		tmp_reg |= KG_SCH_MODE_EN;
    564		/* Enqueue frame NIA */
    565		tmp_reg |= ENQUEUE_KG_DFLT_NIA;
    566	}
    567
    568	scheme_regs.kgse_mode = tmp_reg;
    569
    570	scheme_regs.kgse_mv = scheme->match_vector;
    571
    572	/* Scheme don't override StorageProfile:
    573	 * valid only for DPAA_VERSION >= 11
    574	 */
    575	scheme_regs.kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
    576
    577	/* Configure Hard-Coded Rx Hashing: */
    578
    579	if (scheme->use_hashing) {
    580		/* configure kgse_ekfc */
    581		scheme_regs.kgse_ekfc = DEFAULT_HASH_KEY_EXTRACT_FIELDS;
    582
    583		/* configure kgse_ekdv */
    584		tmp_reg = 0;
    585		tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_0 <<
    586				KG_SCH_DEF_IP_ADDR_SHIFT);
    587		tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_1 <<
    588				KG_SCH_DEF_L4_PORT_SHIFT);
    589		scheme_regs.kgse_ekdv = tmp_reg;
    590
    591		/* configure kgse_dv0 */
    592		scheme_regs.kgse_dv0 = DEFAULT_HASH_KEY_IPv4_ADDR;
    593		/* configure kgse_dv1 */
    594		scheme_regs.kgse_dv1 = DEFAULT_HASH_KEY_L4_PORT;
    595
    596		/* configure kgse_hc  */
    597		tmp_reg = 0;
    598		tmp_reg |= ((scheme->hash_fqid_count - 1) <<
    599				DEFAULT_HASH_DIST_FQID_SHIFT);
    600		tmp_reg |= scheme->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
    601
    602		if (scheme->symmetric_hash) {
    603			/* Normally extraction key should be verified if
    604			 * complies with symmetric hash
    605			 * But because extraction is hard-coded, we are sure
    606			 * the key is symmetric
    607			 */
    608			tmp_reg |= KG_SCH_HASH_CONFIG_SYM;
    609		}
    610		scheme_regs.kgse_hc = tmp_reg;
    611	} else {
    612		scheme_regs.kgse_ekfc = 0;
    613		scheme_regs.kgse_hc = 0;
    614		scheme_regs.kgse_ekdv = 0;
    615		scheme_regs.kgse_dv0 = 0;
    616		scheme_regs.kgse_dv1 = 0;
    617	}
    618
    619	/* configure kgse_fqb: Scheme FQID base */
    620	tmp_reg = 0;
    621	tmp_reg |= scheme->base_fqid;
    622	scheme_regs.kgse_fqb = tmp_reg;
    623
    624	/* features not used by hard-coded configuration */
    625	scheme_regs.kgse_bmch = 0;
    626	scheme_regs.kgse_bmcl = 0;
    627	scheme_regs.kgse_spc = 0;
    628
    629	/* Write scheme registers */
    630	err = keygen_write_scheme(keygen_regs, scheme_id, &scheme_regs, true);
    631	if (err != 0) {
    632		pr_err("Writing scheme registers failed\n");
    633		return err;
    634	}
    635
    636	/* Update used field for Scheme */
    637	scheme->used = enable;
    638
    639	return 0;
    640}
    641
    642/* keygen_init
    643 *
    644 * KeyGen initialization:
    645 * Initializes and enables KeyGen, allocate driver memory, setup registers,
    646 * clear port bindings, invalidate all schemes
    647 *
    648 * keygen_regs: KeyGen registers base address
    649 *
    650 * Return: Handle to KeyGen driver
    651 */
    652struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs)
    653{
    654	struct fman_keygen *keygen;
    655	u32 ar;
    656	int i;
    657
    658	/* Allocate memory for KeyGen driver */
    659	keygen = kzalloc(sizeof(*keygen), GFP_KERNEL);
    660	if (!keygen)
    661		return NULL;
    662
    663	keygen->keygen_regs = keygen_regs;
    664
    665	/* KeyGen initialization (for Master partition):
    666	 * Setup KeyGen registers
    667	 */
    668	iowrite32be(ENQUEUE_KG_DFLT_NIA, &keygen_regs->fmkg_gcr);
    669
    670	iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
    671		    &keygen_regs->fmkg_eer);
    672
    673	iowrite32be(0, &keygen_regs->fmkg_fdor);
    674	iowrite32be(0, &keygen_regs->fmkg_gdv0r);
    675	iowrite32be(0, &keygen_regs->fmkg_gdv1r);
    676
    677	/* Clear binding between ports to schemes and classification plans
    678	 * so that all ports are not bound to any scheme/classification plan
    679	 */
    680	for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
    681		/* Clear all pe sp schemes registers */
    682		keygen_write_sp(keygen_regs, 0xffffffff, false);
    683		ar = build_ar_bind_scheme(i, true);
    684		keygen_write_ar_wait(keygen_regs, ar);
    685
    686		/* Clear all pe cpp classification plans registers */
    687		keygen_write_cpp(keygen_regs, 0);
    688		ar = build_ar_bind_cls_plan(i, true);
    689		keygen_write_ar_wait(keygen_regs, ar);
    690	}
    691
    692	/* Enable all scheme interrupts */
    693	iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seer);
    694	iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seeer);
    695
    696	/* Enable KyeGen */
    697	iowrite32be(ioread32be(&keygen_regs->fmkg_gcr) | FM_KG_KGGCR_EN,
    698		    &keygen_regs->fmkg_gcr);
    699
    700	return keygen;
    701}
    702EXPORT_SYMBOL(keygen_init);
    703
    704/* keygen_port_hashing_init
    705 *
    706 * Initializes a port for Rx Hashing with specified configuration parameters
    707 *
    708 * keygen: KeyGen handle
    709 * hw_port_id: HW Port ID
    710 * hash_base_fqid: Hashing Base FQID used for spreading
    711 * hash_size: Hashing size
    712 *
    713 * Return: Zero for success or error code in case of failure
    714 */
    715int keygen_port_hashing_init(struct fman_keygen *keygen, u8 hw_port_id,
    716			     u32 hash_base_fqid, u32 hash_size)
    717{
    718	struct keygen_scheme *scheme;
    719	u8 scheme_id;
    720	int err;
    721
    722	/* Validate Scheme configuration parameters */
    723	if (hash_base_fqid == 0 || (hash_base_fqid & ~0x00FFFFFF)) {
    724		pr_err("Base FQID must be between 1 and 2^24-1\n");
    725		return -EINVAL;
    726	}
    727	if (hash_size == 0 || (hash_size & (hash_size - 1)) != 0) {
    728		pr_err("Hash size must be power of two\n");
    729		return -EINVAL;
    730	}
    731
    732	/* Find a free scheme */
    733	err = get_free_scheme_id(keygen, &scheme_id);
    734	if (err) {
    735		pr_err("The maximum number of available Schemes has been exceeded\n");
    736		return -EINVAL;
    737	}
    738
    739	/* Create and configure Hard-Coded Scheme: */
    740
    741	scheme = get_scheme(keygen, scheme_id);
    742	if (!scheme) {
    743		pr_err("Requested Scheme does not exist\n");
    744		return -EINVAL;
    745	}
    746	if (scheme->used) {
    747		pr_err("The requested Scheme is already used\n");
    748		return -EINVAL;
    749	}
    750
    751	/* Clear all scheme fields because the scheme may have been
    752	 * previously used
    753	 */
    754	memset(scheme, 0, sizeof(struct keygen_scheme));
    755
    756	/* Setup scheme: */
    757	scheme->hw_port_id = hw_port_id;
    758	scheme->use_hashing = true;
    759	scheme->base_fqid = hash_base_fqid;
    760	scheme->hash_fqid_count = hash_size;
    761	scheme->symmetric_hash = DEFAULT_SYMMETRIC_HASH;
    762	scheme->hashShift = DEFAULT_HASH_SHIFT;
    763
    764	/* All Schemes in hard-coded configuration
    765	 * are Indirect Schemes
    766	 */
    767	scheme->match_vector = 0;
    768
    769	err = keygen_scheme_setup(keygen, scheme_id, true);
    770	if (err != 0) {
    771		pr_err("Scheme setup failed\n");
    772		return err;
    773	}
    774
    775	/* Bind Rx port to Scheme */
    776	err = keygen_bind_port_to_schemes(keygen, scheme_id, true);
    777	if (err != 0) {
    778		pr_err("Binding port to schemes failed\n");
    779		return err;
    780	}
    781
    782	return 0;
    783}
    784EXPORT_SYMBOL(keygen_port_hashing_init);