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

bnx2x_init.h (22977B)


      1/* bnx2x_init.h: Qlogic Everest network driver.
      2 *               Structures and macroes needed during the initialization.
      3 *
      4 * Copyright (c) 2007-2013 Broadcom Corporation
      5 * Copyright (c) 2014 QLogic Corporation
      6 All rights reserved
      7 *
      8 * This program is free software; you can redistribute it and/or modify
      9 * it under the terms of the GNU General Public License as published by
     10 * the Free Software Foundation.
     11 *
     12 * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
     13 * Written by: Eliezer Tamir
     14 * Modified by: Vladislav Zolotarov
     15 */
     16
     17#ifndef BNX2X_INIT_H
     18#define BNX2X_INIT_H
     19
     20/* Init operation types and structures */
     21enum {
     22	OP_RD = 0x1,	/* read a single register */
     23	OP_WR,		/* write a single register */
     24	OP_SW,		/* copy a string to the device */
     25	OP_ZR,		/* clear memory */
     26	OP_ZP,		/* unzip then copy with DMAE */
     27	OP_WR_64,	/* write 64 bit pattern */
     28	OP_WB,		/* copy a string using DMAE */
     29	OP_WB_ZR,	/* Clear a string using DMAE or indirect-wr */
     30	/* Skip the following ops if all of the init modes don't match */
     31	OP_IF_MODE_OR,
     32	/* Skip the following ops if any of the init modes don't match */
     33	OP_IF_MODE_AND,
     34	OP_MAX
     35};
     36
     37enum {
     38	STAGE_START,
     39	STAGE_END,
     40};
     41
     42/* Returns the index of start or end of a specific block stage in ops array*/
     43#define BLOCK_OPS_IDX(block, stage, end) \
     44	(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
     45
     46
     47/* structs for the various opcodes */
     48struct raw_op {
     49	u32 op:8;
     50	u32 offset:24;
     51	u32 raw_data;
     52};
     53
     54struct op_read {
     55	u32 op:8;
     56	u32 offset:24;
     57	u32 val;
     58};
     59
     60struct op_write {
     61	u32 op:8;
     62	u32 offset:24;
     63	u32 val;
     64};
     65
     66struct op_arr_write {
     67	u32 op:8;
     68	u32 offset:24;
     69#ifdef __BIG_ENDIAN
     70	u16 data_len;
     71	u16 data_off;
     72#else /* __LITTLE_ENDIAN */
     73	u16 data_off;
     74	u16 data_len;
     75#endif
     76};
     77
     78struct op_zero {
     79	u32 op:8;
     80	u32 offset:24;
     81	u32 len;
     82};
     83
     84struct op_if_mode {
     85	u32 op:8;
     86	u32 cmd_offset:24;
     87	u32 mode_bit_map;
     88};
     89
     90
     91union init_op {
     92	struct op_read		read;
     93	struct op_write		write;
     94	struct op_arr_write	arr_wr;
     95	struct op_zero		zero;
     96	struct raw_op		raw;
     97	struct op_if_mode	if_mode;
     98};
     99
    100
    101/* Init Phases */
    102enum {
    103	PHASE_COMMON,
    104	PHASE_PORT0,
    105	PHASE_PORT1,
    106	PHASE_PF0,
    107	PHASE_PF1,
    108	PHASE_PF2,
    109	PHASE_PF3,
    110	PHASE_PF4,
    111	PHASE_PF5,
    112	PHASE_PF6,
    113	PHASE_PF7,
    114	NUM_OF_INIT_PHASES
    115};
    116
    117/* Init Modes */
    118enum {
    119	MODE_ASIC                      = 0x00000001,
    120	MODE_FPGA                      = 0x00000002,
    121	MODE_EMUL                      = 0x00000004,
    122	MODE_E2                        = 0x00000008,
    123	MODE_E3                        = 0x00000010,
    124	MODE_PORT2                     = 0x00000020,
    125	MODE_PORT4                     = 0x00000040,
    126	MODE_SF                        = 0x00000080,
    127	MODE_MF                        = 0x00000100,
    128	MODE_MF_SD                     = 0x00000200,
    129	MODE_MF_SI                     = 0x00000400,
    130	MODE_MF_AFEX                   = 0x00000800,
    131	MODE_E3_A0                     = 0x00001000,
    132	MODE_E3_B0                     = 0x00002000,
    133	MODE_COS3                      = 0x00004000,
    134	MODE_COS6                      = 0x00008000,
    135	MODE_LITTLE_ENDIAN             = 0x00010000,
    136	MODE_BIG_ENDIAN                = 0x00020000,
    137};
    138
    139/* Init Blocks */
    140enum {
    141	BLOCK_ATC,
    142	BLOCK_BRB1,
    143	BLOCK_CCM,
    144	BLOCK_CDU,
    145	BLOCK_CFC,
    146	BLOCK_CSDM,
    147	BLOCK_CSEM,
    148	BLOCK_DBG,
    149	BLOCK_DMAE,
    150	BLOCK_DORQ,
    151	BLOCK_HC,
    152	BLOCK_IGU,
    153	BLOCK_MISC,
    154	BLOCK_NIG,
    155	BLOCK_PBF,
    156	BLOCK_PGLUE_B,
    157	BLOCK_PRS,
    158	BLOCK_PXP2,
    159	BLOCK_PXP,
    160	BLOCK_QM,
    161	BLOCK_SRC,
    162	BLOCK_TCM,
    163	BLOCK_TM,
    164	BLOCK_TSDM,
    165	BLOCK_TSEM,
    166	BLOCK_UCM,
    167	BLOCK_UPB,
    168	BLOCK_USDM,
    169	BLOCK_USEM,
    170	BLOCK_XCM,
    171	BLOCK_XPB,
    172	BLOCK_XSDM,
    173	BLOCK_XSEM,
    174	BLOCK_MISC_AEU,
    175	NUM_OF_INIT_BLOCKS
    176};
    177
    178/* QM queue numbers */
    179#define BNX2X_ETH_Q		0
    180#define BNX2X_TOE_Q		3
    181#define BNX2X_TOE_ACK_Q		6
    182#define BNX2X_ISCSI_Q		9
    183#define BNX2X_ISCSI_ACK_Q	11
    184#define BNX2X_FCOE_Q		10
    185
    186/* Vnics per mode */
    187#define BNX2X_PORT2_MODE_NUM_VNICS 4
    188#define BNX2X_PORT4_MODE_NUM_VNICS 2
    189
    190/* COS offset for port1 in E3 B0 4port mode */
    191#define BNX2X_E3B0_PORT1_COS_OFFSET 3
    192
    193/* QM Register addresses */
    194#define BNX2X_Q_VOQ_REG_ADDR(pf_q_num)\
    195	(QM_REG_QVOQIDX_0 + 4 * (pf_q_num))
    196#define BNX2X_VOQ_Q_REG_ADDR(cos, pf_q_num)\
    197	(QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5)))
    198#define BNX2X_Q_CMDQ_REG_ADDR(pf_q_num)\
    199	(QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4))
    200
    201/* extracts the QM queue number for the specified port and vnic */
    202#define BNX2X_PF_Q_NUM(q_num, port, vnic)\
    203	((((port) << 1) | (vnic)) * 16 + (q_num))
    204
    205
    206/* Maps the specified queue to the specified COS */
    207static inline void bnx2x_map_q_cos(struct bnx2x *bp, u32 q_num, u32 new_cos)
    208{
    209	/* find current COS mapping */
    210	u32 curr_cos = REG_RD(bp, QM_REG_QVOQIDX_0 + q_num * 4);
    211
    212	/* check if queue->COS mapping has changed */
    213	if (curr_cos != new_cos) {
    214		u32 num_vnics = BNX2X_PORT2_MODE_NUM_VNICS;
    215		u32 reg_addr, reg_bit_map, vnic;
    216
    217		/* update parameters for 4port mode */
    218		if (INIT_MODE_FLAGS(bp) & MODE_PORT4) {
    219			num_vnics = BNX2X_PORT4_MODE_NUM_VNICS;
    220			if (BP_PORT(bp)) {
    221				curr_cos += BNX2X_E3B0_PORT1_COS_OFFSET;
    222				new_cos += BNX2X_E3B0_PORT1_COS_OFFSET;
    223			}
    224		}
    225
    226		/* change queue mapping for each VNIC */
    227		for (vnic = 0; vnic < num_vnics; vnic++) {
    228			u32 pf_q_num =
    229				BNX2X_PF_Q_NUM(q_num, BP_PORT(bp), vnic);
    230			u32 q_bit_map = 1 << (pf_q_num & 0x1f);
    231
    232			/* overwrite queue->VOQ mapping */
    233			REG_WR(bp, BNX2X_Q_VOQ_REG_ADDR(pf_q_num), new_cos);
    234
    235			/* clear queue bit from current COS bit map */
    236			reg_addr = BNX2X_VOQ_Q_REG_ADDR(curr_cos, pf_q_num);
    237			reg_bit_map = REG_RD(bp, reg_addr);
    238			REG_WR(bp, reg_addr, reg_bit_map & (~q_bit_map));
    239
    240			/* set queue bit in new COS bit map */
    241			reg_addr = BNX2X_VOQ_Q_REG_ADDR(new_cos, pf_q_num);
    242			reg_bit_map = REG_RD(bp, reg_addr);
    243			REG_WR(bp, reg_addr, reg_bit_map | q_bit_map);
    244
    245			/* set/clear queue bit in command-queue bit map
    246			 * (E2/E3A0 only, valid COS values are 0/1)
    247			 */
    248			if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) {
    249				reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num);
    250				reg_bit_map = REG_RD(bp, reg_addr);
    251				q_bit_map = 1 << (2 * (pf_q_num & 0xf));
    252				reg_bit_map = new_cos ?
    253					      (reg_bit_map | q_bit_map) :
    254					      (reg_bit_map & (~q_bit_map));
    255				REG_WR(bp, reg_addr, reg_bit_map);
    256			}
    257		}
    258	}
    259}
    260
    261/* Configures the QM according to the specified per-traffic-type COSes */
    262static inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode,
    263				       struct priority_cos *traffic_cos)
    264{
    265	bnx2x_map_q_cos(bp, BNX2X_FCOE_Q,
    266			traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos);
    267	bnx2x_map_q_cos(bp, BNX2X_ISCSI_Q,
    268			traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
    269	bnx2x_map_q_cos(bp, BNX2X_ISCSI_ACK_Q,
    270		traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
    271	if (mode != STATIC_COS) {
    272		/* required only in backward compatible COS mode */
    273		bnx2x_map_q_cos(bp, BNX2X_ETH_Q,
    274				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
    275		bnx2x_map_q_cos(bp, BNX2X_TOE_Q,
    276				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
    277		bnx2x_map_q_cos(bp, BNX2X_TOE_ACK_Q,
    278				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
    279	}
    280}
    281
    282
    283/* congestion management port init api description
    284 * the api works as follows:
    285 * the driver should pass the cmng_init_input struct, the port_init function
    286 * will prepare the required internal ram structure which will be passed back
    287 * to the driver (cmng_init) that will write it into the internal ram.
    288 *
    289 * IMPORTANT REMARKS:
    290 * 1. the cmng_init struct does not represent the contiguous internal ram
    291 *    structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
    292 *    offset in order to write the port sub struct and the
    293 *    PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
    294 *    words - don't use memcpy!).
    295 * 2. although the cmng_init struct is filled for the maximal vnic number
    296 *    possible, the driver should only write the valid vnics into the internal
    297 *    ram according to the appropriate port mode.
    298 */
    299
    300/* CMNG constants, as derived from system spec calculations */
    301
    302/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
    303#define DEF_MIN_RATE 100
    304
    305/* resolution of the rate shaping timer - 400 usec */
    306#define RS_PERIODIC_TIMEOUT_USEC 400
    307
    308/* number of bytes in single QM arbitration cycle -
    309 * coefficient for calculating the fairness timer
    310 */
    311#define QM_ARB_BYTES 160000
    312
    313/* resolution of Min algorithm 1:100 */
    314#define MIN_RES 100
    315
    316/* how many bytes above threshold for
    317 * the minimal credit of Min algorithm
    318 */
    319#define MIN_ABOVE_THRESH 32768
    320
    321/* Fairness algorithm integration time coefficient -
    322 * for calculating the actual Tfair
    323 */
    324#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
    325
    326/* Memory of fairness algorithm - 2 cycles */
    327#define FAIR_MEM 2
    328#define SAFC_TIMEOUT_USEC 52
    329
    330#define SDM_TICKS 4
    331
    332
    333static inline void bnx2x_init_max(const struct cmng_init_input *input_data,
    334				  u32 r_param, struct cmng_init *ram_data)
    335{
    336	u32 vnic;
    337	struct cmng_vnic *vdata = &ram_data->vnic;
    338	struct cmng_struct_per_port *pdata = &ram_data->port;
    339	/* rate shaping per-port variables
    340	 * 100 micro seconds in SDM ticks = 25
    341	 * since each tick is 4 microSeconds
    342	 */
    343
    344	pdata->rs_vars.rs_periodic_timeout =
    345	RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
    346
    347	/* this is the threshold below which no timer arming will occur.
    348	 * 1.25 coefficient is for the threshold to be a little bigger
    349	 * then the real time to compensate for timer in-accuracy
    350	 */
    351	pdata->rs_vars.rs_threshold =
    352	(5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
    353
    354	/* rate shaping per-vnic variables */
    355	for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
    356		/* global vnic counter */
    357		vdata->vnic_max_rate[vnic].vn_counter.rate =
    358		input_data->vnic_max_rate[vnic];
    359		/* maximal Mbps for this vnic
    360		 * the quota in each timer period - number of bytes
    361		 * transmitted in this period
    362		 */
    363		vdata->vnic_max_rate[vnic].vn_counter.quota =
    364			RS_PERIODIC_TIMEOUT_USEC *
    365			(u32)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
    366	}
    367
    368}
    369
    370static inline void bnx2x_init_min(const struct cmng_init_input *input_data,
    371				  u32 r_param, struct cmng_init *ram_data)
    372{
    373	u32 vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
    374	struct cmng_vnic *vdata = &ram_data->vnic;
    375	struct cmng_struct_per_port *pdata = &ram_data->port;
    376
    377	/* this is the resolution of the fairness timer */
    378	fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
    379
    380	/* fairness per-port variables
    381	 * for 10G it is 1000usec. for 1G it is 10000usec.
    382	 */
    383	tFair = T_FAIR_COEF / input_data->port_rate;
    384
    385	/* this is the threshold below which we won't arm the timer anymore */
    386	pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
    387
    388	/* we multiply by 1e3/8 to get bytes/msec. We don't want the credits
    389	 * to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
    390	 */
    391	pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
    392
    393	/* since each tick is 4 microSeconds */
    394	pdata->fair_vars.fairness_timeout =
    395				fair_periodic_timeout_usec / SDM_TICKS;
    396
    397	/* calculate sum of weights */
    398	vnicWeightSum = 0;
    399
    400	for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++)
    401		vnicWeightSum += input_data->vnic_min_rate[vnic];
    402
    403	/* global vnic counter */
    404	if (vnicWeightSum > 0) {
    405		/* fairness per-vnic variables */
    406		for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
    407			/* this is the credit for each period of the fairness
    408			 * algorithm - number of bytes in T_FAIR (this vnic
    409			 * share of the port rate)
    410			 */
    411			vdata->vnic_min_rate[vnic].vn_credit_delta =
    412				(u32)input_data->vnic_min_rate[vnic] * 100 *
    413				(T_FAIR_COEF / (8 * 100 * vnicWeightSum));
    414			if (vdata->vnic_min_rate[vnic].vn_credit_delta <
    415			    pdata->fair_vars.fair_threshold +
    416			    MIN_ABOVE_THRESH) {
    417				vdata->vnic_min_rate[vnic].vn_credit_delta =
    418					pdata->fair_vars.fair_threshold +
    419					MIN_ABOVE_THRESH;
    420			}
    421		}
    422	}
    423}
    424
    425static inline void bnx2x_init_fw_wrr(const struct cmng_init_input *input_data,
    426				     u32 r_param, struct cmng_init *ram_data)
    427{
    428	u32 vnic, cos;
    429	u32 cosWeightSum = 0;
    430	struct cmng_vnic *vdata = &ram_data->vnic;
    431	struct cmng_struct_per_port *pdata = &ram_data->port;
    432
    433	for (cos = 0; cos < MAX_COS_NUMBER; cos++)
    434		cosWeightSum += input_data->cos_min_rate[cos];
    435
    436	if (cosWeightSum > 0) {
    437
    438		for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) {
    439			/* Since cos and vnic shouldn't work together the rate
    440			 * to divide between the coses is the port rate.
    441			 */
    442			u32 *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
    443			for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
    444				/* this is the credit for each period of
    445				 * the fairness algorithm - number of bytes
    446				 * in T_FAIR (this cos share of the vnic rate)
    447				 */
    448				ccd[cos] =
    449				    (u32)input_data->cos_min_rate[cos] * 100 *
    450				    (T_FAIR_COEF / (8 * 100 * cosWeightSum));
    451				if (ccd[cos] < pdata->fair_vars.fair_threshold
    452						+ MIN_ABOVE_THRESH) {
    453					ccd[cos] =
    454					    pdata->fair_vars.fair_threshold +
    455					    MIN_ABOVE_THRESH;
    456				}
    457			}
    458		}
    459	}
    460}
    461
    462static inline void bnx2x_init_safc(const struct cmng_init_input *input_data,
    463				   struct cmng_init *ram_data)
    464{
    465	/* in microSeconds */
    466	ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
    467}
    468
    469/* Congestion management port init */
    470static inline void bnx2x_init_cmng(const struct cmng_init_input *input_data,
    471				   struct cmng_init *ram_data)
    472{
    473	u32 r_param;
    474	memset(ram_data, 0, sizeof(struct cmng_init));
    475
    476	ram_data->port.flags = input_data->flags;
    477
    478	/* number of bytes transmitted in a rate of 10Gbps
    479	 * in one usec = 1.25KB.
    480	 */
    481	r_param = BITS_TO_BYTES(input_data->port_rate);
    482	bnx2x_init_max(input_data, r_param, ram_data);
    483	bnx2x_init_min(input_data, r_param, ram_data);
    484	bnx2x_init_fw_wrr(input_data, r_param, ram_data);
    485	bnx2x_init_safc(input_data, ram_data);
    486}
    487
    488
    489
    490/* Returns the index of start or end of a specific block stage in ops array */
    491#define BLOCK_OPS_IDX(block, stage, end) \
    492			(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
    493
    494
    495#define INITOP_SET		0	/* set the HW directly */
    496#define INITOP_CLEAR		1	/* clear the HW directly */
    497#define INITOP_INIT		2	/* set the init-value array */
    498
    499/****************************************************************************
    500* ILT management
    501****************************************************************************/
    502struct ilt_line {
    503	dma_addr_t page_mapping;
    504	void *page;
    505	u32 size;
    506};
    507
    508struct ilt_client_info {
    509	u32 page_size;
    510	u16 start;
    511	u16 end;
    512	u16 client_num;
    513	u16 flags;
    514#define ILT_CLIENT_SKIP_INIT	0x1
    515#define ILT_CLIENT_SKIP_MEM	0x2
    516};
    517
    518struct bnx2x_ilt {
    519	u32 start_line;
    520	struct ilt_line		*lines;
    521	struct ilt_client_info	clients[4];
    522#define ILT_CLIENT_CDU	0
    523#define ILT_CLIENT_QM	1
    524#define ILT_CLIENT_SRC	2
    525#define ILT_CLIENT_TM	3
    526};
    527
    528/****************************************************************************
    529* SRC configuration
    530****************************************************************************/
    531struct src_ent {
    532	u8 opaque[56];
    533	u64 next;
    534};
    535
    536/****************************************************************************
    537* Parity configuration
    538****************************************************************************/
    539#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \
    540{ \
    541	block##_REG_##block##_PRTY_MASK, \
    542	block##_REG_##block##_PRTY_STS_CLR, \
    543	en_mask, {m1, m1h, m2, m3}, #block \
    544}
    545
    546#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \
    547{ \
    548	block##_REG_##block##_PRTY_MASK_0, \
    549	block##_REG_##block##_PRTY_STS_CLR_0, \
    550	en_mask, {m1, m1h, m2, m3}, #block"_0" \
    551}
    552
    553#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \
    554{ \
    555	block##_REG_##block##_PRTY_MASK_1, \
    556	block##_REG_##block##_PRTY_STS_CLR_1, \
    557	en_mask, {m1, m1h, m2, m3}, #block"_1" \
    558}
    559
    560static const struct {
    561	u32 mask_addr;
    562	u32 sts_clr_addr;
    563	u32 en_mask;		/* Mask to enable parity attentions */
    564	struct {
    565		u32 e1;		/* 57710 */
    566		u32 e1h;	/* 57711 */
    567		u32 e2;		/* 57712 */
    568		u32 e3;		/* 578xx */
    569	} reg_mask;		/* Register mask (all valid bits) */
    570	char name[8];		/* Block's longest name is 7 characters long
    571				 * (name + suffix)
    572				 */
    573} bnx2x_blocks_parity_data[] = {
    574	/* bit 19 masked */
    575	/* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */
    576	/* bit 5,18,20-31 */
    577	/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */
    578	/* bit 5 */
    579	/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20);	*/
    580	/* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */
    581	/* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */
    582
    583	/* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't
    584	 * want to handle "system kill" flow at the moment.
    585	 */
    586	BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff,
    587			0x7ffffff),
    588	BLOCK_PRTY_INFO_0(PXP2,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    589			  0xffffffff),
    590	BLOCK_PRTY_INFO_1(PXP2,	0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff),
    591	BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0),
    592	BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0),
    593	BLOCK_PRTY_INFO_0(NIG,	0xffffffff, 0, 0, 0xffffffff, 0xffffffff),
    594	BLOCK_PRTY_INFO_1(NIG,	0xffff, 0, 0, 0xff, 0xffff),
    595	BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff),
    596	BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1),
    597	BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff),
    598	BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f),
    599	BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3),
    600	BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3),
    601	{GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
    602		GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf,
    603		{0xf, 0xf, 0xf, 0xf}, "UPB"},
    604	{GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
    605		GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
    606		{0xf, 0xf, 0xf, 0xf}, "XPB"},
    607	BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7),
    608	BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f),
    609	BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f),
    610	BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1),
    611	BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf),
    612	BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf),
    613	BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff, 0xff),
    614	BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff),
    615	BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f),
    616	BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
    617	BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
    618	BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
    619	BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
    620	BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
    621	BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
    622	BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
    623	BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff),
    624	BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
    625			  0xffffffff),
    626	BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
    627	BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
    628			  0xffffffff),
    629	BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
    630	BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
    631			  0xffffffff),
    632	BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
    633	BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
    634			  0xffffffff),
    635	BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
    636};
    637
    638
    639/* [28] MCP Latched rom_parity
    640 * [29] MCP Latched ump_rx_parity
    641 * [30] MCP Latched ump_tx_parity
    642 * [31] MCP Latched scpad_parity
    643 */
    644#define MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS	\
    645	(AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
    646	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
    647	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY)
    648
    649#define MISC_AEU_ENABLE_MCP_PRTY_BITS	\
    650	(MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS | \
    651	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
    652
    653/* Below registers control the MCP parity attention output. When
    654 * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
    655 * enabled, when cleared - disabled.
    656 */
    657static const struct {
    658	u32 addr;
    659	u32 bits;
    660} mcp_attn_ctl_regs[] = {
    661	{ MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
    662		MISC_AEU_ENABLE_MCP_PRTY_BITS },
    663	{ MISC_REG_AEU_ENABLE4_NIG_0,
    664		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
    665	{ MISC_REG_AEU_ENABLE4_PXP_0,
    666		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
    667	{ MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
    668		MISC_AEU_ENABLE_MCP_PRTY_BITS },
    669	{ MISC_REG_AEU_ENABLE4_NIG_1,
    670		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
    671	{ MISC_REG_AEU_ENABLE4_PXP_1,
    672		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }
    673};
    674
    675static inline void bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable)
    676{
    677	int i;
    678	u32 reg_val;
    679
    680	for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) {
    681		reg_val = REG_RD(bp, mcp_attn_ctl_regs[i].addr);
    682
    683		if (enable)
    684			reg_val |= mcp_attn_ctl_regs[i].bits;
    685		else
    686			reg_val &= ~mcp_attn_ctl_regs[i].bits;
    687
    688		REG_WR(bp, mcp_attn_ctl_regs[i].addr, reg_val);
    689	}
    690}
    691
    692static inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx)
    693{
    694	if (CHIP_IS_E1(bp))
    695		return bnx2x_blocks_parity_data[idx].reg_mask.e1;
    696	else if (CHIP_IS_E1H(bp))
    697		return bnx2x_blocks_parity_data[idx].reg_mask.e1h;
    698	else if (CHIP_IS_E2(bp))
    699		return bnx2x_blocks_parity_data[idx].reg_mask.e2;
    700	else /* CHIP_IS_E3 */
    701		return bnx2x_blocks_parity_data[idx].reg_mask.e3;
    702}
    703
    704static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp)
    705{
    706	int i;
    707
    708	for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
    709		u32 dis_mask = bnx2x_parity_reg_mask(bp, i);
    710
    711		if (dis_mask) {
    712			REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
    713			       dis_mask);
    714			DP(NETIF_MSG_HW, "Setting parity mask "
    715						 "for %s to\t\t0x%x\n",
    716				    bnx2x_blocks_parity_data[i].name, dis_mask);
    717		}
    718	}
    719
    720	/* Disable MCP parity attentions */
    721	bnx2x_set_mcp_parity(bp, false);
    722}
    723
    724/* Clear the parity error status registers. */
    725static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp)
    726{
    727	int i;
    728	u32 reg_val, mcp_aeu_bits =
    729		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY |
    730		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY |
    731		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY |
    732		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY;
    733
    734	/* Clear SEM_FAST parities */
    735	REG_WR(bp, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
    736	REG_WR(bp, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
    737	REG_WR(bp, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
    738	REG_WR(bp, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
    739
    740	for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
    741		u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
    742
    743		if (reg_mask) {
    744			reg_val = REG_RD(bp, bnx2x_blocks_parity_data[i].
    745					 sts_clr_addr);
    746			if (reg_val & reg_mask)
    747				DP(NETIF_MSG_HW,
    748					    "Parity errors in %s: 0x%x\n",
    749					    bnx2x_blocks_parity_data[i].name,
    750					    reg_val & reg_mask);
    751		}
    752	}
    753
    754	/* Check if there were parity attentions in MCP */
    755	reg_val = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_MCP);
    756	if (reg_val & mcp_aeu_bits)
    757		DP(NETIF_MSG_HW, "Parity error in MCP: 0x%x\n",
    758		   reg_val & mcp_aeu_bits);
    759
    760	/* Clear parity attentions in MCP:
    761	 * [7]  clears Latched rom_parity
    762	 * [8]  clears Latched ump_rx_parity
    763	 * [9]  clears Latched ump_tx_parity
    764	 * [10] clears Latched scpad_parity (both ports)
    765	 */
    766	REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780);
    767}
    768
    769static inline void bnx2x_enable_blocks_parity(struct bnx2x *bp)
    770{
    771	int i;
    772
    773	for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
    774		u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
    775
    776		if (reg_mask)
    777			REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
    778				bnx2x_blocks_parity_data[i].en_mask & reg_mask);
    779	}
    780
    781	/* Enable MCP parity attentions */
    782	bnx2x_set_mcp_parity(bp, true);
    783}
    784
    785
    786#endif /* BNX2X_INIT_H */
    787