brintos

brintos / linux-shallow public Read only

0
0
Text · 22.4 KiB · 0a59a09 Raw
788 lines · c
1/* bnx2x_init.h: Qlogic Everest network driver.2 *               Structures and macroes needed during the initialization.3 *4 * Copyright (c) 2007-2013 Broadcom Corporation5 * Copyright (c) 2014 QLogic Corporation6 All rights reserved7 *8 * This program is free software; you can redistribute it and/or modify9 * it under the terms of the GNU General Public License as published by10 * the Free Software Foundation.11 *12 * Maintained by: Ariel Elior <ariel.elior@qlogic.com>13 * Written by: Eliezer Tamir14 * Modified by: Vladislav Zolotarov15 */16 17#ifndef BNX2X_INIT_H18#define BNX2X_INIT_H19 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_MAX35};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_ENDIAN70	u16 data_len;71	u16 data_off;72#else /* __LITTLE_ENDIAN */73	u16 data_off;74	u16 data_len;75#endif76};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_PHASES115};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_BLOCKS176};177 178/* QM queue numbers */179#define BNX2X_ETH_Q		0180#define BNX2X_TOE_Q		3181#define BNX2X_TOE_ACK_Q		6182#define BNX2X_ISCSI_Q		9183#define BNX2X_ISCSI_ACK_Q	11184#define BNX2X_FCOE_Q		10185 186/* Vnics per mode */187#define BNX2X_PORT2_MODE_NUM_VNICS 4188#define BNX2X_PORT4_MODE_NUM_VNICS 2189 190/* COS offset for port1 in E3 B0 4port mode */191#define BNX2X_E3B0_PORT1_COS_OFFSET 3192 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 map246			 * (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 description284 * the api works as follows:285 * the driver should pass the cmng_init_input struct, the port_init function286 * will prepare the required internal ram structure which will be passed back287 * 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 ram291 *    structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET292 *    offset in order to write the port sub struct and the293 *    PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other294 *    words - don't use memcpy!).295 * 2. although the cmng_init struct is filled for the maximal vnic number296 *    possible, the driver should only write the valid vnics into the internal297 *    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 100304 305/* resolution of the rate shaping timer - 400 usec */306#define RS_PERIODIC_TIMEOUT_USEC 400307 308/* number of bytes in single QM arbitration cycle -309 * coefficient for calculating the fairness timer310 */311#define QM_ARB_BYTES 160000312 313/* resolution of Min algorithm 1:100 */314#define MIN_RES 100315 316/* how many bytes above threshold for317 * the minimal credit of Min algorithm318 */319#define MIN_ABOVE_THRESH 32768320 321/* Fairness algorithm integration time coefficient -322 * for calculating the actual Tfair323 */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 2328#define SAFC_TIMEOUT_USEC 52329 330#define SDM_TICKS 4331 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 variables340	 * 100 micro seconds in SDM ticks = 25341	 * since each tick is 4 microSeconds342	 */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 bigger349	 * then the real time to compensate for timer in-accuracy350	 */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 vnic360		 * the quota in each timer period - number of bytes361		 * transmitted in this period362		 */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 variables381	 * 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 credits389	 * 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 fairness408			 * algorithm - number of bytes in T_FAIR (this vnic409			 * 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 rate440			 * 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 of445				 * the fairness algorithm - number of bytes446				 * 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_threshold452						+ 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 10Gbps479	 * 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 management501****************************************************************************/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	0x1515#define ILT_CLIENT_SKIP_MEM	0x2516};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	0523#define ILT_CLIENT_QM	1524#define ILT_CLIENT_SRC	2525#define ILT_CLIENT_TM	3526};527 528/****************************************************************************529* SRC configuration530****************************************************************************/531struct src_ent {532	u8 opaque[56];533	u64 next;534};535 536/****************************************************************************537* Parity configuration538****************************************************************************/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 long571				 * (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't584	 * 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_parity640 * [29] MCP Latched ump_rx_parity641 * [30] MCP Latched ump_tx_parity642 * [31] MCP Latched scpad_parity643 */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. When654 * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are655 * 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		else686			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_parity762	 * [8]  clears Latched ump_rx_parity763	 * [9]  clears Latched ump_tx_parity764	 * [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 788