brintos

brintos / linux-shallow public Read only

0
0
Text · 20.8 KiB · e73f6ef Raw
758 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later2/*3 * Copyright 2017 NXP4 */5 6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt7 8#include <linux/slab.h>9 10#include "fman_keygen.h"11 12/* Maximum number of HW Ports */13#define FMAN_MAX_NUM_OF_HW_PORTS		6414 15/* Maximum number of KeyGen Schemes */16#define FM_KG_MAX_NUM_OF_SCHEMES		3217 18/* Number of generic KeyGen Generic Extract Command Registers */19#define FM_KG_NUM_OF_GENERIC_REGS		820 21/* Dummy port ID */22#define DUMMY_PORT_ID				023 24/* Select Scheme Value Register */25#define KG_SCH_DEF_USE_KGSE_DV_0		226#define KG_SCH_DEF_USE_KGSE_DV_1		327 28/* Registers Shifting values */29#define FM_KG_KGAR_NUM_SHIFT			1630#define KG_SCH_DEF_L4_PORT_SHIFT		831#define KG_SCH_DEF_IP_ADDR_SHIFT		1832#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT		2433 34/* KeyGen Registers bit field masks: */35 36/* Enable bit field mask for KeyGen General Configuration Register */37#define FM_KG_KGGCR_EN				0x8000000038 39/* KeyGen Global Registers bit field masks */40#define FM_KG_KGAR_GO				0x8000000041#define FM_KG_KGAR_READ				0x4000000042#define FM_KG_KGAR_WRITE			0x0000000043#define FM_KG_KGAR_SEL_SCHEME_ENTRY		0x0000000044#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT		0x0000800045 46#define FM_KG_KGAR_ERR				0x2000000047#define FM_KG_KGAR_SEL_CLS_PLAN_ENTRY		0x0100000048#define FM_KG_KGAR_SEL_PORT_ENTRY		0x0200000049#define FM_KG_KGAR_SEL_PORT_WSEL_SP		0x0000800050#define FM_KG_KGAR_SEL_PORT_WSEL_CPP		0x0000400051 52/* Error events exceptions */53#define FM_EX_KG_DOUBLE_ECC			0x8000000054#define FM_EX_KG_KEYSIZE_OVERFLOW		0x4000000055 56/* Scheme Registers bit field masks */57#define KG_SCH_MODE_EN				0x8000000058#define KG_SCH_VSP_NO_KSP_EN			0x8000000059#define KG_SCH_HASH_CONFIG_SYM			0x4000000060 61/* Known Protocol field codes */62#define KG_SCH_KN_PORT_ID		0x8000000063#define KG_SCH_KN_MACDST		0x4000000064#define KG_SCH_KN_MACSRC		0x2000000065#define KG_SCH_KN_TCI1			0x1000000066#define KG_SCH_KN_TCI2			0x0800000067#define KG_SCH_KN_ETYPE			0x0400000068#define KG_SCH_KN_PPPSID		0x0200000069#define KG_SCH_KN_PPPID			0x0100000070#define KG_SCH_KN_MPLS1			0x0080000071#define KG_SCH_KN_MPLS2			0x0040000072#define KG_SCH_KN_MPLS_LAST		0x0020000073#define KG_SCH_KN_IPSRC1		0x0010000074#define KG_SCH_KN_IPDST1		0x0008000075#define KG_SCH_KN_PTYPE1		0x0004000076#define KG_SCH_KN_IPTOS_TC1		0x0002000077#define KG_SCH_KN_IPV6FL1		0x0001000078#define KG_SCH_KN_IPSRC2		0x0000800079#define KG_SCH_KN_IPDST2		0x0000400080#define KG_SCH_KN_PTYPE2		0x0000200081#define KG_SCH_KN_IPTOS_TC2		0x0000100082#define KG_SCH_KN_IPV6FL2		0x0000080083#define KG_SCH_KN_GREPTYPE		0x0000040084#define KG_SCH_KN_IPSEC_SPI		0x0000020085#define KG_SCH_KN_IPSEC_NH		0x0000010086#define KG_SCH_KN_IPPID			0x0000008087#define KG_SCH_KN_L4PSRC		0x0000000488#define KG_SCH_KN_L4PDST		0x0000000289#define KG_SCH_KN_TFLG			0x0000000190 91/* NIA values */92#define NIA_ENG_BMI			0x0050000093#define NIA_BMI_AC_ENQ_FRAME		0x0000000294#define ENQUEUE_KG_DFLT_NIA		(NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)95 96/* Hard-coded configuration:97 * These values are used as hard-coded values for KeyGen configuration98 * and they replace user selections for this hard-coded version99 */100 101/* Hash distribution shift */102#define DEFAULT_HASH_DIST_FQID_SHIFT		0103 104/* Hash shift */105#define DEFAULT_HASH_SHIFT			0106 107/* Symmetric hash usage:108 * Warning:109 * - the value for symmetric hash usage must be in accordance with hash110 *	key defined below111 * - according to tests performed, spreading is not working if symmetric112 *	hash is set on true113 * So ultimately symmetric hash functionality should be always disabled:114 */115#define DEFAULT_SYMMETRIC_HASH			false116 117/* Hash Key extraction fields: */118#define DEFAULT_HASH_KEY_EXTRACT_FIELDS		\119	(KG_SCH_KN_IPSRC1 | KG_SCH_KN_IPDST1 | \120	 KG_SCH_KN_L4PSRC | KG_SCH_KN_L4PDST | \121	 KG_SCH_KN_IPSEC_SPI)122 123/* Default values to be used as hash key in case IPv4 or L4 (TCP, UDP)124 * don't exist in the frame125 */126/* Default IPv4 address */127#define DEFAULT_HASH_KEY_IPv4_ADDR		0x0A0A0A0A128/* Default L4 port */129#define DEFAULT_HASH_KEY_L4_PORT		0x0B0B0B0B130 131/* KeyGen Memory Mapped Registers: */132 133/* Scheme Configuration RAM Registers */134struct fman_kg_scheme_regs {135	u32 kgse_mode;		/* 0x100: MODE */136	u32 kgse_ekfc;		/* 0x104: Extract Known Fields Command */137	u32 kgse_ekdv;		/* 0x108: Extract Known Default Value */138	u32 kgse_bmch;		/* 0x10C: Bit Mask Command High */139	u32 kgse_bmcl;		/* 0x110: Bit Mask Command Low */140	u32 kgse_fqb;		/* 0x114: Frame Queue Base */141	u32 kgse_hc;		/* 0x118: Hash Command */142	u32 kgse_ppc;		/* 0x11C: Policer Profile Command */143	u32 kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];144			/* 0x120: Generic Extract Command */145	u32 kgse_spc;146		/* 0x140: KeyGen Scheme Entry Statistic Packet Counter */147	u32 kgse_dv0;	/* 0x144: KeyGen Scheme Entry Default Value 0 */148	u32 kgse_dv1;	/* 0x148: KeyGen Scheme Entry Default Value 1 */149	u32 kgse_ccbs;150		/* 0x14C: KeyGen Scheme Entry Coarse Classification Bit*/151	u32 kgse_mv;	/* 0x150: KeyGen Scheme Entry Match vector */152	u32 kgse_om;	/* 0x154: KeyGen Scheme Entry Operation Mode bits */153	u32 kgse_vsp;154		/* 0x158: KeyGen Scheme Entry Virtual Storage Profile */155};156 157/* Port Partition Configuration Registers */158struct fman_kg_pe_regs {159	u32 fmkg_pe_sp;		/* 0x100: KeyGen Port entry Scheme Partition */160	u32 fmkg_pe_cpp;161		/* 0x104: KeyGen Port Entry Classification Plan Partition */162};163 164/* General Configuration and Status Registers165 * Global Statistic Counters166 * KeyGen Global Registers167 */168struct fman_kg_regs {169	u32 fmkg_gcr;	/* 0x000: KeyGen General Configuration Register */170	u32 res004;	/* 0x004: Reserved */171	u32 res008;	/* 0x008: Reserved */172	u32 fmkg_eer;	/* 0x00C: KeyGen Error Event Register */173	u32 fmkg_eeer;	/* 0x010: KeyGen Error Event Enable Register */174	u32 res014;	/* 0x014: Reserved */175	u32 res018;	/* 0x018: Reserved */176	u32 fmkg_seer;	/* 0x01C: KeyGen Scheme Error Event Register */177	u32 fmkg_seeer;	/* 0x020: KeyGen Scheme Error Event Enable Register */178	u32 fmkg_gsr;	/* 0x024: KeyGen Global Status Register */179	u32 fmkg_tpc;	/* 0x028: Total Packet Counter Register */180	u32 fmkg_serc;	/* 0x02C: Soft Error Capture Register */181	u32 res030[4];	/* 0x030: Reserved */182	u32 fmkg_fdor;	/* 0x034: Frame Data Offset Register */183	u32 fmkg_gdv0r;	/* 0x038: Global Default Value Register 0 */184	u32 fmkg_gdv1r;	/* 0x03C: Global Default Value Register 1 */185	u32 res04c[6];	/* 0x040: Reserved */186	u32 fmkg_feer;	/* 0x044: Force Error Event Register */187	u32 res068[38];	/* 0x048: Reserved */188	union {189		u32 fmkg_indirect[63];	/* 0x100: Indirect Access Registers */190		struct fman_kg_scheme_regs fmkg_sch; /* Scheme Registers */191		struct fman_kg_pe_regs fmkg_pe; /* Port Partition Registers */192	};193	u32 fmkg_ar;	/* 0x1FC: KeyGen Action Register */194};195 196/* KeyGen Scheme data */197struct keygen_scheme {198	bool used;	/* Specifies if this scheme is used */199	u8 hw_port_id;200		/* Hardware port ID201		 * schemes sharing between multiple ports is not202		 * currently supported203		 * so we have only one port id bound to a scheme204		 */205	u32 base_fqid;206		/* Base FQID:207		 * Must be between 1 and 2^24-1208		 * If hash is used and an even distribution is209		 * expected according to hash_fqid_count,210		 * base_fqid must be aligned to hash_fqid_count211		 */212	u32 hash_fqid_count;213		/* FQ range for hash distribution:214		 * Must be a power of 2215		 * Represents the range of queues for spreading216		 */217	bool use_hashing;	/* Usage of Hashing and spreading over FQ */218	bool symmetric_hash;	/* Symmetric Hash option usage */219	u8 hashShift;220		/* Hash result right shift.221		 * Select the 24 bits out of the 64 hash result.222		 * 0 means using the 24 LSB's, otherwise223		 * use the 24 LSB's after shifting right224		 */225	u32 match_vector;	/* Match Vector */226};227 228/* KeyGen driver data */229struct fman_keygen {230	struct keygen_scheme schemes[FM_KG_MAX_NUM_OF_SCHEMES];231				/* Array of schemes */232	struct fman_kg_regs __iomem *keygen_regs;	/* KeyGen registers */233};234 235/* keygen_write_ar_wait236 *237 * Write Action Register with specified value, wait for GO bit field to be238 * idle and then read the error239 *240 * regs: KeyGen registers241 * fmkg_ar: Action Register value242 *243 * Return: Zero for success or error code in case of failure244 */245static int keygen_write_ar_wait(struct fman_kg_regs __iomem *regs, u32 fmkg_ar)246{247	iowrite32be(fmkg_ar, &regs->fmkg_ar);248 249	/* Wait for GO bit field to be idle */250	while (fmkg_ar & FM_KG_KGAR_GO)251		fmkg_ar = ioread32be(&regs->fmkg_ar);252 253	if (fmkg_ar & FM_KG_KGAR_ERR)254		return -EINVAL;255 256	return 0;257}258 259/* build_ar_scheme260 *261 * Build Action Register value for scheme settings262 *263 * scheme_id: Scheme ID264 * update_counter: update scheme counter265 * write: true for action to write the scheme or false for read action266 *267 * Return: AR value268 */269static u32 build_ar_scheme(u8 scheme_id, bool update_counter, bool write)270{271	u32 rw = (u32)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);272 273	return (u32)(FM_KG_KGAR_GO |274			rw |275			FM_KG_KGAR_SEL_SCHEME_ENTRY |276			DUMMY_PORT_ID |277			((u32)scheme_id << FM_KG_KGAR_NUM_SHIFT) |278			(update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));279}280 281/* build_ar_bind_scheme282 *283 * Build Action Register value for port binding to schemes284 *285 * hwport_id: HW Port ID286 * write: true for action to write the bind or false for read action287 *288 * Return: AR value289 */290static u32 build_ar_bind_scheme(u8 hwport_id, bool write)291{292	u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;293 294	return (u32)(FM_KG_KGAR_GO |295			rw |296			FM_KG_KGAR_SEL_PORT_ENTRY |297			hwport_id |298			FM_KG_KGAR_SEL_PORT_WSEL_SP);299}300 301/* keygen_write_sp302 *303 * Write Scheme Partition Register with specified value304 *305 * regs: KeyGen Registers306 * sp: Scheme Partition register value307 * add: true to add a scheme partition or false to clear308 *309 * Return: none310 */311static void keygen_write_sp(struct fman_kg_regs __iomem *regs, u32 sp, bool add)312{313	u32 tmp;314 315	tmp = ioread32be(&regs->fmkg_pe.fmkg_pe_sp);316 317	if (add)318		tmp |= sp;319	else320		tmp &= ~sp;321 322	iowrite32be(tmp, &regs->fmkg_pe.fmkg_pe_sp);323}324 325/* build_ar_bind_cls_plan326 *327 * Build Action Register value for Classification Plan328 *329 * hwport_id: HW Port ID330 * write: true for action to write the CP or false for read action331 *332 * Return: AR value333 */334static u32 build_ar_bind_cls_plan(u8 hwport_id, bool write)335{336	u32 rw = write ? (u32)FM_KG_KGAR_WRITE : (u32)FM_KG_KGAR_READ;337 338	return (u32)(FM_KG_KGAR_GO |339			rw |340			FM_KG_KGAR_SEL_PORT_ENTRY |341			hwport_id |342			FM_KG_KGAR_SEL_PORT_WSEL_CPP);343}344 345/* keygen_write_cpp346 *347 * Write Classification Plan Partition Register with specified value348 *349 * regs: KeyGen Registers350 * cpp: CPP register value351 *352 * Return: none353 */354static void keygen_write_cpp(struct fman_kg_regs __iomem *regs, u32 cpp)355{356	iowrite32be(cpp, &regs->fmkg_pe.fmkg_pe_cpp);357}358 359/* keygen_write_scheme360 *361 * Write all Schemes Registers with specified values362 *363 * regs: KeyGen Registers364 * scheme_id: Scheme ID365 * scheme_regs: Scheme registers values desired to be written366 * update_counter: update scheme counter367 *368 * Return: Zero for success or error code in case of failure369 */370static int keygen_write_scheme(struct fman_kg_regs __iomem *regs, u8 scheme_id,371			       struct fman_kg_scheme_regs *scheme_regs,372				bool update_counter)373{374	u32 ar_reg;375	int err, i;376 377	/* Write indirect scheme registers */378	iowrite32be(scheme_regs->kgse_mode, &regs->fmkg_sch.kgse_mode);379	iowrite32be(scheme_regs->kgse_ekfc, &regs->fmkg_sch.kgse_ekfc);380	iowrite32be(scheme_regs->kgse_ekdv, &regs->fmkg_sch.kgse_ekdv);381	iowrite32be(scheme_regs->kgse_bmch, &regs->fmkg_sch.kgse_bmch);382	iowrite32be(scheme_regs->kgse_bmcl, &regs->fmkg_sch.kgse_bmcl);383	iowrite32be(scheme_regs->kgse_fqb, &regs->fmkg_sch.kgse_fqb);384	iowrite32be(scheme_regs->kgse_hc, &regs->fmkg_sch.kgse_hc);385	iowrite32be(scheme_regs->kgse_ppc, &regs->fmkg_sch.kgse_ppc);386	iowrite32be(scheme_regs->kgse_spc, &regs->fmkg_sch.kgse_spc);387	iowrite32be(scheme_regs->kgse_dv0, &regs->fmkg_sch.kgse_dv0);388	iowrite32be(scheme_regs->kgse_dv1, &regs->fmkg_sch.kgse_dv1);389	iowrite32be(scheme_regs->kgse_ccbs, &regs->fmkg_sch.kgse_ccbs);390	iowrite32be(scheme_regs->kgse_mv, &regs->fmkg_sch.kgse_mv);391	iowrite32be(scheme_regs->kgse_om, &regs->fmkg_sch.kgse_om);392	iowrite32be(scheme_regs->kgse_vsp, &regs->fmkg_sch.kgse_vsp);393 394	for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)395		iowrite32be(scheme_regs->kgse_gec[i],396			    &regs->fmkg_sch.kgse_gec[i]);397 398	/* Write AR (Action register) */399	ar_reg = build_ar_scheme(scheme_id, update_counter, true);400	err = keygen_write_ar_wait(regs, ar_reg);401	if (err != 0) {402		pr_err("Writing Action Register failed\n");403		return err;404	}405 406	return err;407}408 409/* get_free_scheme_id410 *411 * Find the first free scheme available to be used412 *413 * keygen: KeyGen handle414 * scheme_id: pointer to scheme id415 *416 * Return: 0 on success, -EINVAL when the are no available free schemes417 */418static int get_free_scheme_id(struct fman_keygen *keygen, u8 *scheme_id)419{420	u8 i;421 422	for (i = 0; i < FM_KG_MAX_NUM_OF_SCHEMES; i++)423		if (!keygen->schemes[i].used) {424			*scheme_id = i;425			return 0;426		}427 428	return -EINVAL;429}430 431/* get_scheme432 *433 * Provides the scheme for specified ID434 *435 * keygen: KeyGen handle436 * scheme_id: Scheme ID437 *438 * Return: handle to required scheme439 */440static struct keygen_scheme *get_scheme(struct fman_keygen *keygen,441					u8 scheme_id)442{443	if (scheme_id >= FM_KG_MAX_NUM_OF_SCHEMES)444		return NULL;445	return &keygen->schemes[scheme_id];446}447 448/* keygen_bind_port_to_schemes449 *450 * Bind the port to schemes451 *452 * keygen: KeyGen handle453 * scheme_id: id of the scheme to bind to454 * bind: true to bind the port or false to unbind it455 *456 * Return: Zero for success or error code in case of failure457 */458static int keygen_bind_port_to_schemes(struct fman_keygen *keygen,459				       u8 scheme_id,460					bool bind)461{462	struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;463	struct keygen_scheme *scheme;464	u32 ar_reg;465	u32 schemes_vector = 0;466	int err;467 468	scheme = get_scheme(keygen, scheme_id);469	if (!scheme) {470		pr_err("Requested Scheme does not exist\n");471		return -EINVAL;472	}473	if (!scheme->used) {474		pr_err("Cannot bind port to an invalid scheme\n");475		return -EINVAL;476	}477 478	schemes_vector |= 1 << (31 - scheme_id);479 480	ar_reg = build_ar_bind_scheme(scheme->hw_port_id, false);481	err = keygen_write_ar_wait(keygen_regs, ar_reg);482	if (err != 0) {483		pr_err("Reading Action Register failed\n");484		return err;485	}486 487	keygen_write_sp(keygen_regs, schemes_vector, bind);488 489	ar_reg = build_ar_bind_scheme(scheme->hw_port_id, true);490	err = keygen_write_ar_wait(keygen_regs, ar_reg);491	if (err != 0) {492		pr_err("Writing Action Register failed\n");493		return err;494	}495 496	return 0;497}498 499/* keygen_scheme_setup500 *501 * Setup the scheme according to required configuration502 *503 * keygen: KeyGen handle504 * scheme_id: scheme ID505 * enable: true to enable scheme or false to disable it506 *507 * Return: Zero for success or error code in case of failure508 */509static int keygen_scheme_setup(struct fman_keygen *keygen, u8 scheme_id,510			       bool enable)511{512	struct fman_kg_regs __iomem *keygen_regs = keygen->keygen_regs;513	struct fman_kg_scheme_regs scheme_regs;514	struct keygen_scheme *scheme;515	u32 tmp_reg;516	int err;517 518	scheme = get_scheme(keygen, scheme_id);519	if (!scheme) {520		pr_err("Requested Scheme does not exist\n");521		return -EINVAL;522	}523	if (enable && scheme->used) {524		pr_err("The requested Scheme is already used\n");525		return -EINVAL;526	}527 528	/* Clear scheme registers */529	memset(&scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));530 531	/* Setup all scheme registers: */532	tmp_reg = 0;533 534	if (enable) {535		/* Enable Scheme */536		tmp_reg |= KG_SCH_MODE_EN;537		/* Enqueue frame NIA */538		tmp_reg |= ENQUEUE_KG_DFLT_NIA;539	}540 541	scheme_regs.kgse_mode = tmp_reg;542 543	scheme_regs.kgse_mv = scheme->match_vector;544 545	/* Scheme don't override StorageProfile:546	 * valid only for DPAA_VERSION >= 11547	 */548	scheme_regs.kgse_vsp = KG_SCH_VSP_NO_KSP_EN;549 550	/* Configure Hard-Coded Rx Hashing: */551 552	if (scheme->use_hashing) {553		/* configure kgse_ekfc */554		scheme_regs.kgse_ekfc = DEFAULT_HASH_KEY_EXTRACT_FIELDS;555 556		/* configure kgse_ekdv */557		tmp_reg = 0;558		tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_0 <<559				KG_SCH_DEF_IP_ADDR_SHIFT);560		tmp_reg |= (KG_SCH_DEF_USE_KGSE_DV_1 <<561				KG_SCH_DEF_L4_PORT_SHIFT);562		scheme_regs.kgse_ekdv = tmp_reg;563 564		/* configure kgse_dv0 */565		scheme_regs.kgse_dv0 = DEFAULT_HASH_KEY_IPv4_ADDR;566		/* configure kgse_dv1 */567		scheme_regs.kgse_dv1 = DEFAULT_HASH_KEY_L4_PORT;568 569		/* configure kgse_hc  */570		tmp_reg = 0;571		tmp_reg |= ((scheme->hash_fqid_count - 1) <<572				DEFAULT_HASH_DIST_FQID_SHIFT);573		tmp_reg |= scheme->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;574 575		if (scheme->symmetric_hash) {576			/* Normally extraction key should be verified if577			 * complies with symmetric hash578			 * But because extraction is hard-coded, we are sure579			 * the key is symmetric580			 */581			tmp_reg |= KG_SCH_HASH_CONFIG_SYM;582		}583		scheme_regs.kgse_hc = tmp_reg;584	} else {585		scheme_regs.kgse_ekfc = 0;586		scheme_regs.kgse_hc = 0;587		scheme_regs.kgse_ekdv = 0;588		scheme_regs.kgse_dv0 = 0;589		scheme_regs.kgse_dv1 = 0;590	}591 592	/* configure kgse_fqb: Scheme FQID base */593	tmp_reg = 0;594	tmp_reg |= scheme->base_fqid;595	scheme_regs.kgse_fqb = tmp_reg;596 597	/* features not used by hard-coded configuration */598	scheme_regs.kgse_bmch = 0;599	scheme_regs.kgse_bmcl = 0;600	scheme_regs.kgse_spc = 0;601 602	/* Write scheme registers */603	err = keygen_write_scheme(keygen_regs, scheme_id, &scheme_regs, true);604	if (err != 0) {605		pr_err("Writing scheme registers failed\n");606		return err;607	}608 609	/* Update used field for Scheme */610	scheme->used = enable;611 612	return 0;613}614 615/* keygen_init616 *617 * KeyGen initialization:618 * Initializes and enables KeyGen, allocate driver memory, setup registers,619 * clear port bindings, invalidate all schemes620 *621 * keygen_regs: KeyGen registers base address622 *623 * Return: Handle to KeyGen driver624 */625struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs)626{627	struct fman_keygen *keygen;628	u32 ar;629	int i;630 631	/* Allocate memory for KeyGen driver */632	keygen = kzalloc(sizeof(*keygen), GFP_KERNEL);633	if (!keygen)634		return NULL;635 636	keygen->keygen_regs = keygen_regs;637 638	/* KeyGen initialization (for Master partition):639	 * Setup KeyGen registers640	 */641	iowrite32be(ENQUEUE_KG_DFLT_NIA, &keygen_regs->fmkg_gcr);642 643	iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,644		    &keygen_regs->fmkg_eer);645 646	iowrite32be(0, &keygen_regs->fmkg_fdor);647	iowrite32be(0, &keygen_regs->fmkg_gdv0r);648	iowrite32be(0, &keygen_regs->fmkg_gdv1r);649 650	/* Clear binding between ports to schemes and classification plans651	 * so that all ports are not bound to any scheme/classification plan652	 */653	for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {654		/* Clear all pe sp schemes registers */655		keygen_write_sp(keygen_regs, 0xffffffff, false);656		ar = build_ar_bind_scheme(i, true);657		keygen_write_ar_wait(keygen_regs, ar);658 659		/* Clear all pe cpp classification plans registers */660		keygen_write_cpp(keygen_regs, 0);661		ar = build_ar_bind_cls_plan(i, true);662		keygen_write_ar_wait(keygen_regs, ar);663	}664 665	/* Enable all scheme interrupts */666	iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seer);667	iowrite32be(0xFFFFFFFF, &keygen_regs->fmkg_seeer);668 669	/* Enable KyeGen */670	iowrite32be(ioread32be(&keygen_regs->fmkg_gcr) | FM_KG_KGGCR_EN,671		    &keygen_regs->fmkg_gcr);672 673	return keygen;674}675EXPORT_SYMBOL(keygen_init);676 677/* keygen_port_hashing_init678 *679 * Initializes a port for Rx Hashing with specified configuration parameters680 *681 * keygen: KeyGen handle682 * hw_port_id: HW Port ID683 * hash_base_fqid: Hashing Base FQID used for spreading684 * hash_size: Hashing size685 *686 * Return: Zero for success or error code in case of failure687 */688int keygen_port_hashing_init(struct fman_keygen *keygen, u8 hw_port_id,689			     u32 hash_base_fqid, u32 hash_size)690{691	struct keygen_scheme *scheme;692	u8 scheme_id;693	int err;694 695	/* Validate Scheme configuration parameters */696	if (hash_base_fqid == 0 || (hash_base_fqid & ~0x00FFFFFF)) {697		pr_err("Base FQID must be between 1 and 2^24-1\n");698		return -EINVAL;699	}700	if (hash_size == 0 || (hash_size & (hash_size - 1)) != 0) {701		pr_err("Hash size must be power of two\n");702		return -EINVAL;703	}704 705	/* Find a free scheme */706	err = get_free_scheme_id(keygen, &scheme_id);707	if (err) {708		pr_err("The maximum number of available Schemes has been exceeded\n");709		return -EINVAL;710	}711 712	/* Create and configure Hard-Coded Scheme: */713 714	scheme = get_scheme(keygen, scheme_id);715	if (!scheme) {716		pr_err("Requested Scheme does not exist\n");717		return -EINVAL;718	}719	if (scheme->used) {720		pr_err("The requested Scheme is already used\n");721		return -EINVAL;722	}723 724	/* Clear all scheme fields because the scheme may have been725	 * previously used726	 */727	memset(scheme, 0, sizeof(struct keygen_scheme));728 729	/* Setup scheme: */730	scheme->hw_port_id = hw_port_id;731	scheme->use_hashing = true;732	scheme->base_fqid = hash_base_fqid;733	scheme->hash_fqid_count = hash_size;734	scheme->symmetric_hash = DEFAULT_SYMMETRIC_HASH;735	scheme->hashShift = DEFAULT_HASH_SHIFT;736 737	/* All Schemes in hard-coded configuration738	 * are Indirect Schemes739	 */740	scheme->match_vector = 0;741 742	err = keygen_scheme_setup(keygen, scheme_id, true);743	if (err != 0) {744		pr_err("Scheme setup failed\n");745		return err;746	}747 748	/* Bind Rx port to Scheme */749	err = keygen_bind_port_to_schemes(keygen, scheme_id, true);750	if (err != 0) {751		pr_err("Binding port to schemes failed\n");752		return err;753	}754 755	return 0;756}757EXPORT_SYMBOL(keygen_port_hashing_init);758