162306a36Sopenharmony_ci/* bnx2x_init.h: Qlogic Everest network driver.
262306a36Sopenharmony_ci *               Structures and macroes needed during the initialization.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (c) 2007-2013 Broadcom Corporation
562306a36Sopenharmony_ci * Copyright (c) 2014 QLogic Corporation
662306a36Sopenharmony_ci All rights reserved
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify
962306a36Sopenharmony_ci * it under the terms of the GNU General Public License as published by
1062306a36Sopenharmony_ci * the Free Software Foundation.
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
1362306a36Sopenharmony_ci * Written by: Eliezer Tamir
1462306a36Sopenharmony_ci * Modified by: Vladislav Zolotarov
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#ifndef BNX2X_INIT_H
1862306a36Sopenharmony_ci#define BNX2X_INIT_H
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* Init operation types and structures */
2162306a36Sopenharmony_cienum {
2262306a36Sopenharmony_ci	OP_RD = 0x1,	/* read a single register */
2362306a36Sopenharmony_ci	OP_WR,		/* write a single register */
2462306a36Sopenharmony_ci	OP_SW,		/* copy a string to the device */
2562306a36Sopenharmony_ci	OP_ZR,		/* clear memory */
2662306a36Sopenharmony_ci	OP_ZP,		/* unzip then copy with DMAE */
2762306a36Sopenharmony_ci	OP_WR_64,	/* write 64 bit pattern */
2862306a36Sopenharmony_ci	OP_WB,		/* copy a string using DMAE */
2962306a36Sopenharmony_ci	OP_WB_ZR,	/* Clear a string using DMAE or indirect-wr */
3062306a36Sopenharmony_ci	/* Skip the following ops if all of the init modes don't match */
3162306a36Sopenharmony_ci	OP_IF_MODE_OR,
3262306a36Sopenharmony_ci	/* Skip the following ops if any of the init modes don't match */
3362306a36Sopenharmony_ci	OP_IF_MODE_AND,
3462306a36Sopenharmony_ci	OP_MAX
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cienum {
3862306a36Sopenharmony_ci	STAGE_START,
3962306a36Sopenharmony_ci	STAGE_END,
4062306a36Sopenharmony_ci};
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci/* Returns the index of start or end of a specific block stage in ops array*/
4362306a36Sopenharmony_ci#define BLOCK_OPS_IDX(block, stage, end) \
4462306a36Sopenharmony_ci	(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/* structs for the various opcodes */
4862306a36Sopenharmony_cistruct raw_op {
4962306a36Sopenharmony_ci	u32 op:8;
5062306a36Sopenharmony_ci	u32 offset:24;
5162306a36Sopenharmony_ci	u32 raw_data;
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistruct op_read {
5562306a36Sopenharmony_ci	u32 op:8;
5662306a36Sopenharmony_ci	u32 offset:24;
5762306a36Sopenharmony_ci	u32 val;
5862306a36Sopenharmony_ci};
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistruct op_write {
6162306a36Sopenharmony_ci	u32 op:8;
6262306a36Sopenharmony_ci	u32 offset:24;
6362306a36Sopenharmony_ci	u32 val;
6462306a36Sopenharmony_ci};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistruct op_arr_write {
6762306a36Sopenharmony_ci	u32 op:8;
6862306a36Sopenharmony_ci	u32 offset:24;
6962306a36Sopenharmony_ci#ifdef __BIG_ENDIAN
7062306a36Sopenharmony_ci	u16 data_len;
7162306a36Sopenharmony_ci	u16 data_off;
7262306a36Sopenharmony_ci#else /* __LITTLE_ENDIAN */
7362306a36Sopenharmony_ci	u16 data_off;
7462306a36Sopenharmony_ci	u16 data_len;
7562306a36Sopenharmony_ci#endif
7662306a36Sopenharmony_ci};
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistruct op_zero {
7962306a36Sopenharmony_ci	u32 op:8;
8062306a36Sopenharmony_ci	u32 offset:24;
8162306a36Sopenharmony_ci	u32 len;
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistruct op_if_mode {
8562306a36Sopenharmony_ci	u32 op:8;
8662306a36Sopenharmony_ci	u32 cmd_offset:24;
8762306a36Sopenharmony_ci	u32 mode_bit_map;
8862306a36Sopenharmony_ci};
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciunion init_op {
9262306a36Sopenharmony_ci	struct op_read		read;
9362306a36Sopenharmony_ci	struct op_write		write;
9462306a36Sopenharmony_ci	struct op_arr_write	arr_wr;
9562306a36Sopenharmony_ci	struct op_zero		zero;
9662306a36Sopenharmony_ci	struct raw_op		raw;
9762306a36Sopenharmony_ci	struct op_if_mode	if_mode;
9862306a36Sopenharmony_ci};
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci/* Init Phases */
10262306a36Sopenharmony_cienum {
10362306a36Sopenharmony_ci	PHASE_COMMON,
10462306a36Sopenharmony_ci	PHASE_PORT0,
10562306a36Sopenharmony_ci	PHASE_PORT1,
10662306a36Sopenharmony_ci	PHASE_PF0,
10762306a36Sopenharmony_ci	PHASE_PF1,
10862306a36Sopenharmony_ci	PHASE_PF2,
10962306a36Sopenharmony_ci	PHASE_PF3,
11062306a36Sopenharmony_ci	PHASE_PF4,
11162306a36Sopenharmony_ci	PHASE_PF5,
11262306a36Sopenharmony_ci	PHASE_PF6,
11362306a36Sopenharmony_ci	PHASE_PF7,
11462306a36Sopenharmony_ci	NUM_OF_INIT_PHASES
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci/* Init Modes */
11862306a36Sopenharmony_cienum {
11962306a36Sopenharmony_ci	MODE_ASIC                      = 0x00000001,
12062306a36Sopenharmony_ci	MODE_FPGA                      = 0x00000002,
12162306a36Sopenharmony_ci	MODE_EMUL                      = 0x00000004,
12262306a36Sopenharmony_ci	MODE_E2                        = 0x00000008,
12362306a36Sopenharmony_ci	MODE_E3                        = 0x00000010,
12462306a36Sopenharmony_ci	MODE_PORT2                     = 0x00000020,
12562306a36Sopenharmony_ci	MODE_PORT4                     = 0x00000040,
12662306a36Sopenharmony_ci	MODE_SF                        = 0x00000080,
12762306a36Sopenharmony_ci	MODE_MF                        = 0x00000100,
12862306a36Sopenharmony_ci	MODE_MF_SD                     = 0x00000200,
12962306a36Sopenharmony_ci	MODE_MF_SI                     = 0x00000400,
13062306a36Sopenharmony_ci	MODE_MF_AFEX                   = 0x00000800,
13162306a36Sopenharmony_ci	MODE_E3_A0                     = 0x00001000,
13262306a36Sopenharmony_ci	MODE_E3_B0                     = 0x00002000,
13362306a36Sopenharmony_ci	MODE_COS3                      = 0x00004000,
13462306a36Sopenharmony_ci	MODE_COS6                      = 0x00008000,
13562306a36Sopenharmony_ci	MODE_LITTLE_ENDIAN             = 0x00010000,
13662306a36Sopenharmony_ci	MODE_BIG_ENDIAN                = 0x00020000,
13762306a36Sopenharmony_ci};
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/* Init Blocks */
14062306a36Sopenharmony_cienum {
14162306a36Sopenharmony_ci	BLOCK_ATC,
14262306a36Sopenharmony_ci	BLOCK_BRB1,
14362306a36Sopenharmony_ci	BLOCK_CCM,
14462306a36Sopenharmony_ci	BLOCK_CDU,
14562306a36Sopenharmony_ci	BLOCK_CFC,
14662306a36Sopenharmony_ci	BLOCK_CSDM,
14762306a36Sopenharmony_ci	BLOCK_CSEM,
14862306a36Sopenharmony_ci	BLOCK_DBG,
14962306a36Sopenharmony_ci	BLOCK_DMAE,
15062306a36Sopenharmony_ci	BLOCK_DORQ,
15162306a36Sopenharmony_ci	BLOCK_HC,
15262306a36Sopenharmony_ci	BLOCK_IGU,
15362306a36Sopenharmony_ci	BLOCK_MISC,
15462306a36Sopenharmony_ci	BLOCK_NIG,
15562306a36Sopenharmony_ci	BLOCK_PBF,
15662306a36Sopenharmony_ci	BLOCK_PGLUE_B,
15762306a36Sopenharmony_ci	BLOCK_PRS,
15862306a36Sopenharmony_ci	BLOCK_PXP2,
15962306a36Sopenharmony_ci	BLOCK_PXP,
16062306a36Sopenharmony_ci	BLOCK_QM,
16162306a36Sopenharmony_ci	BLOCK_SRC,
16262306a36Sopenharmony_ci	BLOCK_TCM,
16362306a36Sopenharmony_ci	BLOCK_TM,
16462306a36Sopenharmony_ci	BLOCK_TSDM,
16562306a36Sopenharmony_ci	BLOCK_TSEM,
16662306a36Sopenharmony_ci	BLOCK_UCM,
16762306a36Sopenharmony_ci	BLOCK_UPB,
16862306a36Sopenharmony_ci	BLOCK_USDM,
16962306a36Sopenharmony_ci	BLOCK_USEM,
17062306a36Sopenharmony_ci	BLOCK_XCM,
17162306a36Sopenharmony_ci	BLOCK_XPB,
17262306a36Sopenharmony_ci	BLOCK_XSDM,
17362306a36Sopenharmony_ci	BLOCK_XSEM,
17462306a36Sopenharmony_ci	BLOCK_MISC_AEU,
17562306a36Sopenharmony_ci	NUM_OF_INIT_BLOCKS
17662306a36Sopenharmony_ci};
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci/* QM queue numbers */
17962306a36Sopenharmony_ci#define BNX2X_ETH_Q		0
18062306a36Sopenharmony_ci#define BNX2X_TOE_Q		3
18162306a36Sopenharmony_ci#define BNX2X_TOE_ACK_Q		6
18262306a36Sopenharmony_ci#define BNX2X_ISCSI_Q		9
18362306a36Sopenharmony_ci#define BNX2X_ISCSI_ACK_Q	11
18462306a36Sopenharmony_ci#define BNX2X_FCOE_Q		10
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci/* Vnics per mode */
18762306a36Sopenharmony_ci#define BNX2X_PORT2_MODE_NUM_VNICS 4
18862306a36Sopenharmony_ci#define BNX2X_PORT4_MODE_NUM_VNICS 2
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci/* COS offset for port1 in E3 B0 4port mode */
19162306a36Sopenharmony_ci#define BNX2X_E3B0_PORT1_COS_OFFSET 3
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci/* QM Register addresses */
19462306a36Sopenharmony_ci#define BNX2X_Q_VOQ_REG_ADDR(pf_q_num)\
19562306a36Sopenharmony_ci	(QM_REG_QVOQIDX_0 + 4 * (pf_q_num))
19662306a36Sopenharmony_ci#define BNX2X_VOQ_Q_REG_ADDR(cos, pf_q_num)\
19762306a36Sopenharmony_ci	(QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5)))
19862306a36Sopenharmony_ci#define BNX2X_Q_CMDQ_REG_ADDR(pf_q_num)\
19962306a36Sopenharmony_ci	(QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4))
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci/* extracts the QM queue number for the specified port and vnic */
20262306a36Sopenharmony_ci#define BNX2X_PF_Q_NUM(q_num, port, vnic)\
20362306a36Sopenharmony_ci	((((port) << 1) | (vnic)) * 16 + (q_num))
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci/* Maps the specified queue to the specified COS */
20762306a36Sopenharmony_cistatic inline void bnx2x_map_q_cos(struct bnx2x *bp, u32 q_num, u32 new_cos)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	/* find current COS mapping */
21062306a36Sopenharmony_ci	u32 curr_cos = REG_RD(bp, QM_REG_QVOQIDX_0 + q_num * 4);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	/* check if queue->COS mapping has changed */
21362306a36Sopenharmony_ci	if (curr_cos != new_cos) {
21462306a36Sopenharmony_ci		u32 num_vnics = BNX2X_PORT2_MODE_NUM_VNICS;
21562306a36Sopenharmony_ci		u32 reg_addr, reg_bit_map, vnic;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci		/* update parameters for 4port mode */
21862306a36Sopenharmony_ci		if (INIT_MODE_FLAGS(bp) & MODE_PORT4) {
21962306a36Sopenharmony_ci			num_vnics = BNX2X_PORT4_MODE_NUM_VNICS;
22062306a36Sopenharmony_ci			if (BP_PORT(bp)) {
22162306a36Sopenharmony_ci				curr_cos += BNX2X_E3B0_PORT1_COS_OFFSET;
22262306a36Sopenharmony_ci				new_cos += BNX2X_E3B0_PORT1_COS_OFFSET;
22362306a36Sopenharmony_ci			}
22462306a36Sopenharmony_ci		}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci		/* change queue mapping for each VNIC */
22762306a36Sopenharmony_ci		for (vnic = 0; vnic < num_vnics; vnic++) {
22862306a36Sopenharmony_ci			u32 pf_q_num =
22962306a36Sopenharmony_ci				BNX2X_PF_Q_NUM(q_num, BP_PORT(bp), vnic);
23062306a36Sopenharmony_ci			u32 q_bit_map = 1 << (pf_q_num & 0x1f);
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci			/* overwrite queue->VOQ mapping */
23362306a36Sopenharmony_ci			REG_WR(bp, BNX2X_Q_VOQ_REG_ADDR(pf_q_num), new_cos);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci			/* clear queue bit from current COS bit map */
23662306a36Sopenharmony_ci			reg_addr = BNX2X_VOQ_Q_REG_ADDR(curr_cos, pf_q_num);
23762306a36Sopenharmony_ci			reg_bit_map = REG_RD(bp, reg_addr);
23862306a36Sopenharmony_ci			REG_WR(bp, reg_addr, reg_bit_map & (~q_bit_map));
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci			/* set queue bit in new COS bit map */
24162306a36Sopenharmony_ci			reg_addr = BNX2X_VOQ_Q_REG_ADDR(new_cos, pf_q_num);
24262306a36Sopenharmony_ci			reg_bit_map = REG_RD(bp, reg_addr);
24362306a36Sopenharmony_ci			REG_WR(bp, reg_addr, reg_bit_map | q_bit_map);
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci			/* set/clear queue bit in command-queue bit map
24662306a36Sopenharmony_ci			 * (E2/E3A0 only, valid COS values are 0/1)
24762306a36Sopenharmony_ci			 */
24862306a36Sopenharmony_ci			if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) {
24962306a36Sopenharmony_ci				reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num);
25062306a36Sopenharmony_ci				reg_bit_map = REG_RD(bp, reg_addr);
25162306a36Sopenharmony_ci				q_bit_map = 1 << (2 * (pf_q_num & 0xf));
25262306a36Sopenharmony_ci				reg_bit_map = new_cos ?
25362306a36Sopenharmony_ci					      (reg_bit_map | q_bit_map) :
25462306a36Sopenharmony_ci					      (reg_bit_map & (~q_bit_map));
25562306a36Sopenharmony_ci				REG_WR(bp, reg_addr, reg_bit_map);
25662306a36Sopenharmony_ci			}
25762306a36Sopenharmony_ci		}
25862306a36Sopenharmony_ci	}
25962306a36Sopenharmony_ci}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci/* Configures the QM according to the specified per-traffic-type COSes */
26262306a36Sopenharmony_cistatic inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode,
26362306a36Sopenharmony_ci				       struct priority_cos *traffic_cos)
26462306a36Sopenharmony_ci{
26562306a36Sopenharmony_ci	bnx2x_map_q_cos(bp, BNX2X_FCOE_Q,
26662306a36Sopenharmony_ci			traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos);
26762306a36Sopenharmony_ci	bnx2x_map_q_cos(bp, BNX2X_ISCSI_Q,
26862306a36Sopenharmony_ci			traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
26962306a36Sopenharmony_ci	bnx2x_map_q_cos(bp, BNX2X_ISCSI_ACK_Q,
27062306a36Sopenharmony_ci		traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
27162306a36Sopenharmony_ci	if (mode != STATIC_COS) {
27262306a36Sopenharmony_ci		/* required only in backward compatible COS mode */
27362306a36Sopenharmony_ci		bnx2x_map_q_cos(bp, BNX2X_ETH_Q,
27462306a36Sopenharmony_ci				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
27562306a36Sopenharmony_ci		bnx2x_map_q_cos(bp, BNX2X_TOE_Q,
27662306a36Sopenharmony_ci				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
27762306a36Sopenharmony_ci		bnx2x_map_q_cos(bp, BNX2X_TOE_ACK_Q,
27862306a36Sopenharmony_ci				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
27962306a36Sopenharmony_ci	}
28062306a36Sopenharmony_ci}
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci/* congestion management port init api description
28462306a36Sopenharmony_ci * the api works as follows:
28562306a36Sopenharmony_ci * the driver should pass the cmng_init_input struct, the port_init function
28662306a36Sopenharmony_ci * will prepare the required internal ram structure which will be passed back
28762306a36Sopenharmony_ci * to the driver (cmng_init) that will write it into the internal ram.
28862306a36Sopenharmony_ci *
28962306a36Sopenharmony_ci * IMPORTANT REMARKS:
29062306a36Sopenharmony_ci * 1. the cmng_init struct does not represent the contiguous internal ram
29162306a36Sopenharmony_ci *    structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
29262306a36Sopenharmony_ci *    offset in order to write the port sub struct and the
29362306a36Sopenharmony_ci *    PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
29462306a36Sopenharmony_ci *    words - don't use memcpy!).
29562306a36Sopenharmony_ci * 2. although the cmng_init struct is filled for the maximal vnic number
29662306a36Sopenharmony_ci *    possible, the driver should only write the valid vnics into the internal
29762306a36Sopenharmony_ci *    ram according to the appropriate port mode.
29862306a36Sopenharmony_ci */
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci/* CMNG constants, as derived from system spec calculations */
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
30362306a36Sopenharmony_ci#define DEF_MIN_RATE 100
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci/* resolution of the rate shaping timer - 400 usec */
30662306a36Sopenharmony_ci#define RS_PERIODIC_TIMEOUT_USEC 400
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci/* number of bytes in single QM arbitration cycle -
30962306a36Sopenharmony_ci * coefficient for calculating the fairness timer
31062306a36Sopenharmony_ci */
31162306a36Sopenharmony_ci#define QM_ARB_BYTES 160000
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci/* resolution of Min algorithm 1:100 */
31462306a36Sopenharmony_ci#define MIN_RES 100
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci/* how many bytes above threshold for
31762306a36Sopenharmony_ci * the minimal credit of Min algorithm
31862306a36Sopenharmony_ci */
31962306a36Sopenharmony_ci#define MIN_ABOVE_THRESH 32768
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci/* Fairness algorithm integration time coefficient -
32262306a36Sopenharmony_ci * for calculating the actual Tfair
32362306a36Sopenharmony_ci */
32462306a36Sopenharmony_ci#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci/* Memory of fairness algorithm - 2 cycles */
32762306a36Sopenharmony_ci#define FAIR_MEM 2
32862306a36Sopenharmony_ci#define SAFC_TIMEOUT_USEC 52
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci#define SDM_TICKS 4
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic inline void bnx2x_init_max(const struct cmng_init_input *input_data,
33462306a36Sopenharmony_ci				  u32 r_param, struct cmng_init *ram_data)
33562306a36Sopenharmony_ci{
33662306a36Sopenharmony_ci	u32 vnic;
33762306a36Sopenharmony_ci	struct cmng_vnic *vdata = &ram_data->vnic;
33862306a36Sopenharmony_ci	struct cmng_struct_per_port *pdata = &ram_data->port;
33962306a36Sopenharmony_ci	/* rate shaping per-port variables
34062306a36Sopenharmony_ci	 * 100 micro seconds in SDM ticks = 25
34162306a36Sopenharmony_ci	 * since each tick is 4 microSeconds
34262306a36Sopenharmony_ci	 */
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci	pdata->rs_vars.rs_periodic_timeout =
34562306a36Sopenharmony_ci	RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	/* this is the threshold below which no timer arming will occur.
34862306a36Sopenharmony_ci	 * 1.25 coefficient is for the threshold to be a little bigger
34962306a36Sopenharmony_ci	 * then the real time to compensate for timer in-accuracy
35062306a36Sopenharmony_ci	 */
35162306a36Sopenharmony_ci	pdata->rs_vars.rs_threshold =
35262306a36Sopenharmony_ci	(5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	/* rate shaping per-vnic variables */
35562306a36Sopenharmony_ci	for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
35662306a36Sopenharmony_ci		/* global vnic counter */
35762306a36Sopenharmony_ci		vdata->vnic_max_rate[vnic].vn_counter.rate =
35862306a36Sopenharmony_ci		input_data->vnic_max_rate[vnic];
35962306a36Sopenharmony_ci		/* maximal Mbps for this vnic
36062306a36Sopenharmony_ci		 * the quota in each timer period - number of bytes
36162306a36Sopenharmony_ci		 * transmitted in this period
36262306a36Sopenharmony_ci		 */
36362306a36Sopenharmony_ci		vdata->vnic_max_rate[vnic].vn_counter.quota =
36462306a36Sopenharmony_ci			RS_PERIODIC_TIMEOUT_USEC *
36562306a36Sopenharmony_ci			(u32)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
36662306a36Sopenharmony_ci	}
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_cistatic inline void bnx2x_init_min(const struct cmng_init_input *input_data,
37162306a36Sopenharmony_ci				  u32 r_param, struct cmng_init *ram_data)
37262306a36Sopenharmony_ci{
37362306a36Sopenharmony_ci	u32 vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
37462306a36Sopenharmony_ci	struct cmng_vnic *vdata = &ram_data->vnic;
37562306a36Sopenharmony_ci	struct cmng_struct_per_port *pdata = &ram_data->port;
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	/* this is the resolution of the fairness timer */
37862306a36Sopenharmony_ci	fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	/* fairness per-port variables
38162306a36Sopenharmony_ci	 * for 10G it is 1000usec. for 1G it is 10000usec.
38262306a36Sopenharmony_ci	 */
38362306a36Sopenharmony_ci	tFair = T_FAIR_COEF / input_data->port_rate;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	/* this is the threshold below which we won't arm the timer anymore */
38662306a36Sopenharmony_ci	pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	/* we multiply by 1e3/8 to get bytes/msec. We don't want the credits
38962306a36Sopenharmony_ci	 * to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
39062306a36Sopenharmony_ci	 */
39162306a36Sopenharmony_ci	pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	/* since each tick is 4 microSeconds */
39462306a36Sopenharmony_ci	pdata->fair_vars.fairness_timeout =
39562306a36Sopenharmony_ci				fair_periodic_timeout_usec / SDM_TICKS;
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	/* calculate sum of weights */
39862306a36Sopenharmony_ci	vnicWeightSum = 0;
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++)
40162306a36Sopenharmony_ci		vnicWeightSum += input_data->vnic_min_rate[vnic];
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	/* global vnic counter */
40462306a36Sopenharmony_ci	if (vnicWeightSum > 0) {
40562306a36Sopenharmony_ci		/* fairness per-vnic variables */
40662306a36Sopenharmony_ci		for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
40762306a36Sopenharmony_ci			/* this is the credit for each period of the fairness
40862306a36Sopenharmony_ci			 * algorithm - number of bytes in T_FAIR (this vnic
40962306a36Sopenharmony_ci			 * share of the port rate)
41062306a36Sopenharmony_ci			 */
41162306a36Sopenharmony_ci			vdata->vnic_min_rate[vnic].vn_credit_delta =
41262306a36Sopenharmony_ci				(u32)input_data->vnic_min_rate[vnic] * 100 *
41362306a36Sopenharmony_ci				(T_FAIR_COEF / (8 * 100 * vnicWeightSum));
41462306a36Sopenharmony_ci			if (vdata->vnic_min_rate[vnic].vn_credit_delta <
41562306a36Sopenharmony_ci			    pdata->fair_vars.fair_threshold +
41662306a36Sopenharmony_ci			    MIN_ABOVE_THRESH) {
41762306a36Sopenharmony_ci				vdata->vnic_min_rate[vnic].vn_credit_delta =
41862306a36Sopenharmony_ci					pdata->fair_vars.fair_threshold +
41962306a36Sopenharmony_ci					MIN_ABOVE_THRESH;
42062306a36Sopenharmony_ci			}
42162306a36Sopenharmony_ci		}
42262306a36Sopenharmony_ci	}
42362306a36Sopenharmony_ci}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_cistatic inline void bnx2x_init_fw_wrr(const struct cmng_init_input *input_data,
42662306a36Sopenharmony_ci				     u32 r_param, struct cmng_init *ram_data)
42762306a36Sopenharmony_ci{
42862306a36Sopenharmony_ci	u32 vnic, cos;
42962306a36Sopenharmony_ci	u32 cosWeightSum = 0;
43062306a36Sopenharmony_ci	struct cmng_vnic *vdata = &ram_data->vnic;
43162306a36Sopenharmony_ci	struct cmng_struct_per_port *pdata = &ram_data->port;
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	for (cos = 0; cos < MAX_COS_NUMBER; cos++)
43462306a36Sopenharmony_ci		cosWeightSum += input_data->cos_min_rate[cos];
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	if (cosWeightSum > 0) {
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci		for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
43962306a36Sopenharmony_ci			/* Since cos and vnic shouldn't work together the rate
44062306a36Sopenharmony_ci			 * to divide between the coses is the port rate.
44162306a36Sopenharmony_ci			 */
44262306a36Sopenharmony_ci			u32 *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
44362306a36Sopenharmony_ci			for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
44462306a36Sopenharmony_ci				/* this is the credit for each period of
44562306a36Sopenharmony_ci				 * the fairness algorithm - number of bytes
44662306a36Sopenharmony_ci				 * in T_FAIR (this cos share of the vnic rate)
44762306a36Sopenharmony_ci				 */
44862306a36Sopenharmony_ci				ccd[cos] =
44962306a36Sopenharmony_ci				    (u32)input_data->cos_min_rate[cos] * 100 *
45062306a36Sopenharmony_ci				    (T_FAIR_COEF / (8 * 100 * cosWeightSum));
45162306a36Sopenharmony_ci				if (ccd[cos] < pdata->fair_vars.fair_threshold
45262306a36Sopenharmony_ci						+ MIN_ABOVE_THRESH) {
45362306a36Sopenharmony_ci					ccd[cos] =
45462306a36Sopenharmony_ci					    pdata->fair_vars.fair_threshold +
45562306a36Sopenharmony_ci					    MIN_ABOVE_THRESH;
45662306a36Sopenharmony_ci				}
45762306a36Sopenharmony_ci			}
45862306a36Sopenharmony_ci		}
45962306a36Sopenharmony_ci	}
46062306a36Sopenharmony_ci}
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_cistatic inline void bnx2x_init_safc(const struct cmng_init_input *input_data,
46362306a36Sopenharmony_ci				   struct cmng_init *ram_data)
46462306a36Sopenharmony_ci{
46562306a36Sopenharmony_ci	/* in microSeconds */
46662306a36Sopenharmony_ci	ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci/* Congestion management port init */
47062306a36Sopenharmony_cistatic inline void bnx2x_init_cmng(const struct cmng_init_input *input_data,
47162306a36Sopenharmony_ci				   struct cmng_init *ram_data)
47262306a36Sopenharmony_ci{
47362306a36Sopenharmony_ci	u32 r_param;
47462306a36Sopenharmony_ci	memset(ram_data, 0, sizeof(struct cmng_init));
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	ram_data->port.flags = input_data->flags;
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	/* number of bytes transmitted in a rate of 10Gbps
47962306a36Sopenharmony_ci	 * in one usec = 1.25KB.
48062306a36Sopenharmony_ci	 */
48162306a36Sopenharmony_ci	r_param = BITS_TO_BYTES(input_data->port_rate);
48262306a36Sopenharmony_ci	bnx2x_init_max(input_data, r_param, ram_data);
48362306a36Sopenharmony_ci	bnx2x_init_min(input_data, r_param, ram_data);
48462306a36Sopenharmony_ci	bnx2x_init_fw_wrr(input_data, r_param, ram_data);
48562306a36Sopenharmony_ci	bnx2x_init_safc(input_data, ram_data);
48662306a36Sopenharmony_ci}
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci/* Returns the index of start or end of a specific block stage in ops array */
49162306a36Sopenharmony_ci#define BLOCK_OPS_IDX(block, stage, end) \
49262306a36Sopenharmony_ci			(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci#define INITOP_SET		0	/* set the HW directly */
49662306a36Sopenharmony_ci#define INITOP_CLEAR		1	/* clear the HW directly */
49762306a36Sopenharmony_ci#define INITOP_INIT		2	/* set the init-value array */
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci/****************************************************************************
50062306a36Sopenharmony_ci* ILT management
50162306a36Sopenharmony_ci****************************************************************************/
50262306a36Sopenharmony_cistruct ilt_line {
50362306a36Sopenharmony_ci	dma_addr_t page_mapping;
50462306a36Sopenharmony_ci	void *page;
50562306a36Sopenharmony_ci	u32 size;
50662306a36Sopenharmony_ci};
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_cistruct ilt_client_info {
50962306a36Sopenharmony_ci	u32 page_size;
51062306a36Sopenharmony_ci	u16 start;
51162306a36Sopenharmony_ci	u16 end;
51262306a36Sopenharmony_ci	u16 client_num;
51362306a36Sopenharmony_ci	u16 flags;
51462306a36Sopenharmony_ci#define ILT_CLIENT_SKIP_INIT	0x1
51562306a36Sopenharmony_ci#define ILT_CLIENT_SKIP_MEM	0x2
51662306a36Sopenharmony_ci};
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_cistruct bnx2x_ilt {
51962306a36Sopenharmony_ci	u32 start_line;
52062306a36Sopenharmony_ci	struct ilt_line		*lines;
52162306a36Sopenharmony_ci	struct ilt_client_info	clients[4];
52262306a36Sopenharmony_ci#define ILT_CLIENT_CDU	0
52362306a36Sopenharmony_ci#define ILT_CLIENT_QM	1
52462306a36Sopenharmony_ci#define ILT_CLIENT_SRC	2
52562306a36Sopenharmony_ci#define ILT_CLIENT_TM	3
52662306a36Sopenharmony_ci};
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci/****************************************************************************
52962306a36Sopenharmony_ci* SRC configuration
53062306a36Sopenharmony_ci****************************************************************************/
53162306a36Sopenharmony_cistruct src_ent {
53262306a36Sopenharmony_ci	u8 opaque[56];
53362306a36Sopenharmony_ci	u64 next;
53462306a36Sopenharmony_ci};
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci/****************************************************************************
53762306a36Sopenharmony_ci* Parity configuration
53862306a36Sopenharmony_ci****************************************************************************/
53962306a36Sopenharmony_ci#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \
54062306a36Sopenharmony_ci{ \
54162306a36Sopenharmony_ci	block##_REG_##block##_PRTY_MASK, \
54262306a36Sopenharmony_ci	block##_REG_##block##_PRTY_STS_CLR, \
54362306a36Sopenharmony_ci	en_mask, {m1, m1h, m2, m3}, #block \
54462306a36Sopenharmony_ci}
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \
54762306a36Sopenharmony_ci{ \
54862306a36Sopenharmony_ci	block##_REG_##block##_PRTY_MASK_0, \
54962306a36Sopenharmony_ci	block##_REG_##block##_PRTY_STS_CLR_0, \
55062306a36Sopenharmony_ci	en_mask, {m1, m1h, m2, m3}, #block"_0" \
55162306a36Sopenharmony_ci}
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \
55462306a36Sopenharmony_ci{ \
55562306a36Sopenharmony_ci	block##_REG_##block##_PRTY_MASK_1, \
55662306a36Sopenharmony_ci	block##_REG_##block##_PRTY_STS_CLR_1, \
55762306a36Sopenharmony_ci	en_mask, {m1, m1h, m2, m3}, #block"_1" \
55862306a36Sopenharmony_ci}
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_cistatic const struct {
56162306a36Sopenharmony_ci	u32 mask_addr;
56262306a36Sopenharmony_ci	u32 sts_clr_addr;
56362306a36Sopenharmony_ci	u32 en_mask;		/* Mask to enable parity attentions */
56462306a36Sopenharmony_ci	struct {
56562306a36Sopenharmony_ci		u32 e1;		/* 57710 */
56662306a36Sopenharmony_ci		u32 e1h;	/* 57711 */
56762306a36Sopenharmony_ci		u32 e2;		/* 57712 */
56862306a36Sopenharmony_ci		u32 e3;		/* 578xx */
56962306a36Sopenharmony_ci	} reg_mask;		/* Register mask (all valid bits) */
57062306a36Sopenharmony_ci	char name[8];		/* Block's longest name is 7 characters long
57162306a36Sopenharmony_ci				 * (name + suffix)
57262306a36Sopenharmony_ci				 */
57362306a36Sopenharmony_ci} bnx2x_blocks_parity_data[] = {
57462306a36Sopenharmony_ci	/* bit 19 masked */
57562306a36Sopenharmony_ci	/* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */
57662306a36Sopenharmony_ci	/* bit 5,18,20-31 */
57762306a36Sopenharmony_ci	/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */
57862306a36Sopenharmony_ci	/* bit 5 */
57962306a36Sopenharmony_ci	/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20);	*/
58062306a36Sopenharmony_ci	/* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */
58162306a36Sopenharmony_ci	/* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	/* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't
58462306a36Sopenharmony_ci	 * want to handle "system kill" flow at the moment.
58562306a36Sopenharmony_ci	 */
58662306a36Sopenharmony_ci	BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff,
58762306a36Sopenharmony_ci			0x7ffffff),
58862306a36Sopenharmony_ci	BLOCK_PRTY_INFO_0(PXP2,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
58962306a36Sopenharmony_ci			  0xffffffff),
59062306a36Sopenharmony_ci	BLOCK_PRTY_INFO_1(PXP2,	0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff),
59162306a36Sopenharmony_ci	BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0),
59262306a36Sopenharmony_ci	BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0),
59362306a36Sopenharmony_ci	BLOCK_PRTY_INFO_0(NIG,	0xffffffff, 0, 0, 0xffffffff, 0xffffffff),
59462306a36Sopenharmony_ci	BLOCK_PRTY_INFO_1(NIG,	0xffff, 0, 0, 0xff, 0xffff),
59562306a36Sopenharmony_ci	BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff),
59662306a36Sopenharmony_ci	BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1),
59762306a36Sopenharmony_ci	BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff),
59862306a36Sopenharmony_ci	BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f),
59962306a36Sopenharmony_ci	BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3),
60062306a36Sopenharmony_ci	BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3),
60162306a36Sopenharmony_ci	{GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
60262306a36Sopenharmony_ci		GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf,
60362306a36Sopenharmony_ci		{0xf, 0xf, 0xf, 0xf}, "UPB"},
60462306a36Sopenharmony_ci	{GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
60562306a36Sopenharmony_ci		GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
60662306a36Sopenharmony_ci		{0xf, 0xf, 0xf, 0xf}, "XPB"},
60762306a36Sopenharmony_ci	BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7),
60862306a36Sopenharmony_ci	BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f),
60962306a36Sopenharmony_ci	BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f),
61062306a36Sopenharmony_ci	BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1),
61162306a36Sopenharmony_ci	BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf),
61262306a36Sopenharmony_ci	BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf),
61362306a36Sopenharmony_ci	BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff, 0xff),
61462306a36Sopenharmony_ci	BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff),
61562306a36Sopenharmony_ci	BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f),
61662306a36Sopenharmony_ci	BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
61762306a36Sopenharmony_ci	BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
61862306a36Sopenharmony_ci	BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
61962306a36Sopenharmony_ci	BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
62062306a36Sopenharmony_ci	BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
62162306a36Sopenharmony_ci	BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
62262306a36Sopenharmony_ci	BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
62362306a36Sopenharmony_ci	BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff),
62462306a36Sopenharmony_ci	BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
62562306a36Sopenharmony_ci			  0xffffffff),
62662306a36Sopenharmony_ci	BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
62762306a36Sopenharmony_ci	BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
62862306a36Sopenharmony_ci			  0xffffffff),
62962306a36Sopenharmony_ci	BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
63062306a36Sopenharmony_ci	BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
63162306a36Sopenharmony_ci			  0xffffffff),
63262306a36Sopenharmony_ci	BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
63362306a36Sopenharmony_ci	BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
63462306a36Sopenharmony_ci			  0xffffffff),
63562306a36Sopenharmony_ci	BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
63662306a36Sopenharmony_ci};
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci/* [28] MCP Latched rom_parity
64062306a36Sopenharmony_ci * [29] MCP Latched ump_rx_parity
64162306a36Sopenharmony_ci * [30] MCP Latched ump_tx_parity
64262306a36Sopenharmony_ci * [31] MCP Latched scpad_parity
64362306a36Sopenharmony_ci */
64462306a36Sopenharmony_ci#define MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS	\
64562306a36Sopenharmony_ci	(AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
64662306a36Sopenharmony_ci	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
64762306a36Sopenharmony_ci	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY)
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci#define MISC_AEU_ENABLE_MCP_PRTY_BITS	\
65062306a36Sopenharmony_ci	(MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS | \
65162306a36Sopenharmony_ci	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci/* Below registers control the MCP parity attention output. When
65462306a36Sopenharmony_ci * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
65562306a36Sopenharmony_ci * enabled, when cleared - disabled.
65662306a36Sopenharmony_ci */
65762306a36Sopenharmony_cistatic const struct {
65862306a36Sopenharmony_ci	u32 addr;
65962306a36Sopenharmony_ci	u32 bits;
66062306a36Sopenharmony_ci} mcp_attn_ctl_regs[] = {
66162306a36Sopenharmony_ci	{ MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
66262306a36Sopenharmony_ci		MISC_AEU_ENABLE_MCP_PRTY_BITS },
66362306a36Sopenharmony_ci	{ MISC_REG_AEU_ENABLE4_NIG_0,
66462306a36Sopenharmony_ci		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
66562306a36Sopenharmony_ci	{ MISC_REG_AEU_ENABLE4_PXP_0,
66662306a36Sopenharmony_ci		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
66762306a36Sopenharmony_ci	{ MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
66862306a36Sopenharmony_ci		MISC_AEU_ENABLE_MCP_PRTY_BITS },
66962306a36Sopenharmony_ci	{ MISC_REG_AEU_ENABLE4_NIG_1,
67062306a36Sopenharmony_ci		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
67162306a36Sopenharmony_ci	{ MISC_REG_AEU_ENABLE4_PXP_1,
67262306a36Sopenharmony_ci		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }
67362306a36Sopenharmony_ci};
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_cistatic inline void bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable)
67662306a36Sopenharmony_ci{
67762306a36Sopenharmony_ci	int i;
67862306a36Sopenharmony_ci	u32 reg_val;
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) {
68162306a36Sopenharmony_ci		reg_val = REG_RD(bp, mcp_attn_ctl_regs[i].addr);
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci		if (enable)
68462306a36Sopenharmony_ci			reg_val |= mcp_attn_ctl_regs[i].bits;
68562306a36Sopenharmony_ci		else
68662306a36Sopenharmony_ci			reg_val &= ~mcp_attn_ctl_regs[i].bits;
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci		REG_WR(bp, mcp_attn_ctl_regs[i].addr, reg_val);
68962306a36Sopenharmony_ci	}
69062306a36Sopenharmony_ci}
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_cistatic inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx)
69362306a36Sopenharmony_ci{
69462306a36Sopenharmony_ci	if (CHIP_IS_E1(bp))
69562306a36Sopenharmony_ci		return bnx2x_blocks_parity_data[idx].reg_mask.e1;
69662306a36Sopenharmony_ci	else if (CHIP_IS_E1H(bp))
69762306a36Sopenharmony_ci		return bnx2x_blocks_parity_data[idx].reg_mask.e1h;
69862306a36Sopenharmony_ci	else if (CHIP_IS_E2(bp))
69962306a36Sopenharmony_ci		return bnx2x_blocks_parity_data[idx].reg_mask.e2;
70062306a36Sopenharmony_ci	else /* CHIP_IS_E3 */
70162306a36Sopenharmony_ci		return bnx2x_blocks_parity_data[idx].reg_mask.e3;
70262306a36Sopenharmony_ci}
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_cistatic inline void bnx2x_disable_blocks_parity(struct bnx2x *bp)
70562306a36Sopenharmony_ci{
70662306a36Sopenharmony_ci	int i;
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
70962306a36Sopenharmony_ci		u32 dis_mask = bnx2x_parity_reg_mask(bp, i);
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci		if (dis_mask) {
71262306a36Sopenharmony_ci			REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
71362306a36Sopenharmony_ci			       dis_mask);
71462306a36Sopenharmony_ci			DP(NETIF_MSG_HW, "Setting parity mask "
71562306a36Sopenharmony_ci						 "for %s to\t\t0x%x\n",
71662306a36Sopenharmony_ci				    bnx2x_blocks_parity_data[i].name, dis_mask);
71762306a36Sopenharmony_ci		}
71862306a36Sopenharmony_ci	}
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	/* Disable MCP parity attentions */
72162306a36Sopenharmony_ci	bnx2x_set_mcp_parity(bp, false);
72262306a36Sopenharmony_ci}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci/* Clear the parity error status registers. */
72562306a36Sopenharmony_cistatic inline void bnx2x_clear_blocks_parity(struct bnx2x *bp)
72662306a36Sopenharmony_ci{
72762306a36Sopenharmony_ci	int i;
72862306a36Sopenharmony_ci	u32 reg_val, mcp_aeu_bits =
72962306a36Sopenharmony_ci		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY |
73062306a36Sopenharmony_ci		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY |
73162306a36Sopenharmony_ci		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY |
73262306a36Sopenharmony_ci		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci	/* Clear SEM_FAST parities */
73562306a36Sopenharmony_ci	REG_WR(bp, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
73662306a36Sopenharmony_ci	REG_WR(bp, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
73762306a36Sopenharmony_ci	REG_WR(bp, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
73862306a36Sopenharmony_ci	REG_WR(bp, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
74162306a36Sopenharmony_ci		u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci		if (reg_mask) {
74462306a36Sopenharmony_ci			reg_val = REG_RD(bp, bnx2x_blocks_parity_data[i].
74562306a36Sopenharmony_ci					 sts_clr_addr);
74662306a36Sopenharmony_ci			if (reg_val & reg_mask)
74762306a36Sopenharmony_ci				DP(NETIF_MSG_HW,
74862306a36Sopenharmony_ci					    "Parity errors in %s: 0x%x\n",
74962306a36Sopenharmony_ci					    bnx2x_blocks_parity_data[i].name,
75062306a36Sopenharmony_ci					    reg_val & reg_mask);
75162306a36Sopenharmony_ci		}
75262306a36Sopenharmony_ci	}
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci	/* Check if there were parity attentions in MCP */
75562306a36Sopenharmony_ci	reg_val = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_MCP);
75662306a36Sopenharmony_ci	if (reg_val & mcp_aeu_bits)
75762306a36Sopenharmony_ci		DP(NETIF_MSG_HW, "Parity error in MCP: 0x%x\n",
75862306a36Sopenharmony_ci		   reg_val & mcp_aeu_bits);
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_ci	/* Clear parity attentions in MCP:
76162306a36Sopenharmony_ci	 * [7]  clears Latched rom_parity
76262306a36Sopenharmony_ci	 * [8]  clears Latched ump_rx_parity
76362306a36Sopenharmony_ci	 * [9]  clears Latched ump_tx_parity
76462306a36Sopenharmony_ci	 * [10] clears Latched scpad_parity (both ports)
76562306a36Sopenharmony_ci	 */
76662306a36Sopenharmony_ci	REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780);
76762306a36Sopenharmony_ci}
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_cistatic inline void bnx2x_enable_blocks_parity(struct bnx2x *bp)
77062306a36Sopenharmony_ci{
77162306a36Sopenharmony_ci	int i;
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
77462306a36Sopenharmony_ci		u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci		if (reg_mask)
77762306a36Sopenharmony_ci			REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
77862306a36Sopenharmony_ci				bnx2x_blocks_parity_data[i].en_mask & reg_mask);
77962306a36Sopenharmony_ci	}
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci	/* Enable MCP parity attentions */
78262306a36Sopenharmony_ci	bnx2x_set_mcp_parity(bp, true);
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci#endif /* BNX2X_INIT_H */
78762306a36Sopenharmony_ci
788