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, ®s->fmkg_ar);248 249 /* Wait for GO bit field to be idle */250 while (fmkg_ar & FM_KG_KGAR_GO)251 fmkg_ar = ioread32be(®s->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(®s->fmkg_pe.fmkg_pe_sp);316 317 if (add)318 tmp |= sp;319 else320 tmp &= ~sp;321 322 iowrite32be(tmp, ®s->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, ®s->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, ®s->fmkg_sch.kgse_mode);379 iowrite32be(scheme_regs->kgse_ekfc, ®s->fmkg_sch.kgse_ekfc);380 iowrite32be(scheme_regs->kgse_ekdv, ®s->fmkg_sch.kgse_ekdv);381 iowrite32be(scheme_regs->kgse_bmch, ®s->fmkg_sch.kgse_bmch);382 iowrite32be(scheme_regs->kgse_bmcl, ®s->fmkg_sch.kgse_bmcl);383 iowrite32be(scheme_regs->kgse_fqb, ®s->fmkg_sch.kgse_fqb);384 iowrite32be(scheme_regs->kgse_hc, ®s->fmkg_sch.kgse_hc);385 iowrite32be(scheme_regs->kgse_ppc, ®s->fmkg_sch.kgse_ppc);386 iowrite32be(scheme_regs->kgse_spc, ®s->fmkg_sch.kgse_spc);387 iowrite32be(scheme_regs->kgse_dv0, ®s->fmkg_sch.kgse_dv0);388 iowrite32be(scheme_regs->kgse_dv1, ®s->fmkg_sch.kgse_dv1);389 iowrite32be(scheme_regs->kgse_ccbs, ®s->fmkg_sch.kgse_ccbs);390 iowrite32be(scheme_regs->kgse_mv, ®s->fmkg_sch.kgse_mv);391 iowrite32be(scheme_regs->kgse_om, ®s->fmkg_sch.kgse_om);392 iowrite32be(scheme_regs->kgse_vsp, ®s->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 ®s->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