xref: /freebsd-src/sys/dev/bxe/ecore_init.h (revision 685dc743dc3b5645e34836464128e1c0558b404b)
14e400768SDavid Christensen /*-
2*7282444bSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause
3*7282444bSPedro F. Giffuni  *
44ef8ebfdSDavid C Somayajulu  * Copyright (c) 2007-2017 QLogic Corporation. All rights reserved.
54e400768SDavid Christensen  *
64e400768SDavid Christensen  * Redistribution and use in source and binary forms, with or without
74e400768SDavid Christensen  * modification, are permitted provided that the following conditions
84e400768SDavid Christensen  * are met:
94e400768SDavid Christensen  *
104e400768SDavid Christensen  * 1. Redistributions of source code must retain the above copyright
114e400768SDavid Christensen  *    notice, this list of conditions and the following disclaimer.
124e400768SDavid Christensen  * 2. Redistributions in binary form must reproduce the above copyright
134e400768SDavid Christensen  *    notice, this list of conditions and the following disclaimer in the
144e400768SDavid Christensen  *    documentation and/or other materials provided with the distribution.
154e400768SDavid Christensen  *
164ef8ebfdSDavid C Somayajulu  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
174e400768SDavid Christensen  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
184e400768SDavid Christensen  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
194e400768SDavid Christensen  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
204e400768SDavid Christensen  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
214e400768SDavid Christensen  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
224e400768SDavid Christensen  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
234e400768SDavid Christensen  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
244e400768SDavid Christensen  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
254e400768SDavid Christensen  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
264e400768SDavid Christensen  * THE POSSIBILITY OF SUCH DAMAGE.
274e400768SDavid Christensen  */
284e400768SDavid Christensen 
294e400768SDavid Christensen #include <sys/cdefs.h>
304e400768SDavid Christensen #ifndef ECORE_INIT_H
314e400768SDavid Christensen #define ECORE_INIT_H
324e400768SDavid Christensen 
334e400768SDavid Christensen /* Init operation types and structures */
344e400768SDavid Christensen enum {
354e400768SDavid Christensen 	OP_RD = 0x1,	/* read a single register */
364e400768SDavid Christensen 	OP_WR,		/* write a single register */
374e400768SDavid Christensen 	OP_SW,		/* copy a string to the device */
384e400768SDavid Christensen 	OP_ZR,		/* clear memory */
394e400768SDavid Christensen 	OP_ZP,		/* unzip then copy with DMAE */
404e400768SDavid Christensen 	OP_WR_64,	/* write 64 bit pattern */
414e400768SDavid Christensen 	OP_WB,		/* copy a string using DMAE */
424e400768SDavid Christensen #ifndef FW_ZIP_SUPPORT
434e400768SDavid Christensen 	OP_FW,		/* copy an array from fw data (only used with unzipped FW) */
444e400768SDavid Christensen #endif
454e400768SDavid Christensen 	OP_WB_ZR,	/* Clear a string using DMAE or indirect-wr */
464e400768SDavid Christensen 	OP_IF_MODE_OR,  /* Skip the following ops if all init modes don't match */
474e400768SDavid Christensen 	OP_IF_MODE_AND, /* Skip the following ops if any init modes don't match */
484e400768SDavid Christensen 	OP_IF_PHASE,
494e400768SDavid Christensen 	OP_RT,
504e400768SDavid Christensen 	OP_DELAY,
514e400768SDavid Christensen 	OP_VERIFY,
524e400768SDavid Christensen 	OP_MAX
534e400768SDavid Christensen };
544e400768SDavid Christensen 
554e400768SDavid Christensen enum {
564e400768SDavid Christensen 	STAGE_START,
574e400768SDavid Christensen 	STAGE_END,
584e400768SDavid Christensen };
594e400768SDavid Christensen 
604e400768SDavid Christensen /* Returns the index of start or end of a specific block stage in ops array*/
614e400768SDavid Christensen #define BLOCK_OPS_IDX(block, stage, end) \
624e400768SDavid Christensen 	(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
634e400768SDavid Christensen 
644e400768SDavid Christensen 
654e400768SDavid Christensen /* structs for the various opcodes */
664e400768SDavid Christensen struct raw_op {
674e400768SDavid Christensen 	uint32_t op:8;
684e400768SDavid Christensen 	uint32_t offset:24;
694e400768SDavid Christensen 	uint32_t raw_data;
704e400768SDavid Christensen };
714e400768SDavid Christensen 
724e400768SDavid Christensen struct op_read {
734e400768SDavid Christensen 	uint32_t op:8;
744e400768SDavid Christensen 	uint32_t offset:24;
754e400768SDavid Christensen 	uint32_t val;
764e400768SDavid Christensen };
774e400768SDavid Christensen 
784e400768SDavid Christensen struct op_write {
794e400768SDavid Christensen 	uint32_t op:8;
804e400768SDavid Christensen 	uint32_t offset:24;
814e400768SDavid Christensen 	uint32_t val;
824e400768SDavid Christensen };
834e400768SDavid Christensen 
844e400768SDavid Christensen struct op_arr_write {
854e400768SDavid Christensen 	uint32_t op:8;
864e400768SDavid Christensen 	uint32_t offset:24;
874e400768SDavid Christensen #ifdef __BIG_ENDIAN
884e400768SDavid Christensen 	uint16_t data_len;
894e400768SDavid Christensen 	uint16_t data_off;
904e400768SDavid Christensen #else /* __LITTLE_ENDIAN */
914e400768SDavid Christensen 	uint16_t data_off;
924e400768SDavid Christensen 	uint16_t data_len;
934e400768SDavid Christensen #endif
944e400768SDavid Christensen };
954e400768SDavid Christensen 
964e400768SDavid Christensen struct op_zero {
974e400768SDavid Christensen 	uint32_t op:8;
984e400768SDavid Christensen 	uint32_t offset:24;
994e400768SDavid Christensen 	uint32_t len;
1004e400768SDavid Christensen };
1014e400768SDavid Christensen 
1024e400768SDavid Christensen struct op_if_mode {
1034e400768SDavid Christensen 	uint32_t op:8;
1044e400768SDavid Christensen 	uint32_t cmd_offset:24;
1054e400768SDavid Christensen 	uint32_t mode_bit_map;
1064e400768SDavid Christensen };
1074e400768SDavid Christensen 
1084e400768SDavid Christensen struct op_if_phase {
1094e400768SDavid Christensen 	uint32_t op:8;
1104e400768SDavid Christensen 	uint32_t cmd_offset:24;
1114e400768SDavid Christensen 	uint32_t phase_bit_map;
1124e400768SDavid Christensen };
1134e400768SDavid Christensen 
1144e400768SDavid Christensen struct op_delay {
1154e400768SDavid Christensen 	uint32_t op:8;
1164e400768SDavid Christensen 	uint32_t reserved:24;
1174e400768SDavid Christensen 	uint32_t delay;
1184e400768SDavid Christensen };
1194e400768SDavid Christensen 
1204e400768SDavid Christensen union init_op {
1214e400768SDavid Christensen 	struct op_read		read;
1224e400768SDavid Christensen 	struct op_write		write;
1234e400768SDavid Christensen 	struct op_arr_write	arr_wr;
1244e400768SDavid Christensen 	struct op_zero		zero;
1254e400768SDavid Christensen 	struct raw_op		raw;
1264e400768SDavid Christensen 	struct op_if_mode	if_mode;
1274e400768SDavid Christensen 	struct op_if_phase	if_phase;
1284e400768SDavid Christensen 	struct op_delay		delay;
1294e400768SDavid Christensen };
1304e400768SDavid Christensen 
1314e400768SDavid Christensen 
1324e400768SDavid Christensen /* Init Phases */
1334e400768SDavid Christensen enum {
1344e400768SDavid Christensen 	PHASE_COMMON,
1354e400768SDavid Christensen 	PHASE_PORT0,
1364e400768SDavid Christensen 	PHASE_PORT1,
1374e400768SDavid Christensen 	PHASE_PF0,
1384e400768SDavid Christensen 	PHASE_PF1,
1394e400768SDavid Christensen 	PHASE_PF2,
1404e400768SDavid Christensen 	PHASE_PF3,
1414e400768SDavid Christensen 	PHASE_PF4,
1424e400768SDavid Christensen 	PHASE_PF5,
1434e400768SDavid Christensen 	PHASE_PF6,
1444e400768SDavid Christensen 	PHASE_PF7,
1454e400768SDavid Christensen 	NUM_OF_INIT_PHASES
1464e400768SDavid Christensen };
1474e400768SDavid Christensen 
1484e400768SDavid Christensen /* Init Modes */
1494e400768SDavid Christensen enum {
1504e400768SDavid Christensen 	MODE_ASIC                      = 0x00000001,
1514e400768SDavid Christensen 	MODE_FPGA                      = 0x00000002,
1524e400768SDavid Christensen 	MODE_EMUL                      = 0x00000004,
1534e400768SDavid Christensen 	MODE_E2                        = 0x00000008,
1544e400768SDavid Christensen 	MODE_E3                        = 0x00000010,
1554e400768SDavid Christensen 	MODE_PORT2                     = 0x00000020,
1564e400768SDavid Christensen 	MODE_PORT4                     = 0x00000040,
1574e400768SDavid Christensen 	MODE_SF                        = 0x00000080,
1584e400768SDavid Christensen 	MODE_MF                        = 0x00000100,
1594e400768SDavid Christensen 	MODE_MF_SD                     = 0x00000200,
1604e400768SDavid Christensen 	MODE_MF_SI                     = 0x00000400,
1614e400768SDavid Christensen 	MODE_MF_AFEX                   = 0x00000800,
1624e400768SDavid Christensen 	MODE_E3_A0                     = 0x00001000,
1634e400768SDavid Christensen 	MODE_E3_B0                     = 0x00002000,
1644e400768SDavid Christensen 	MODE_COS3                      = 0x00004000,
1654e400768SDavid Christensen 	MODE_COS6                      = 0x00008000,
1664e400768SDavid Christensen 	MODE_LITTLE_ENDIAN             = 0x00010000,
1674e400768SDavid Christensen 	MODE_BIG_ENDIAN                = 0x00020000,
1684e400768SDavid Christensen };
1694e400768SDavid Christensen 
1704e400768SDavid Christensen /* Init Blocks */
1714e400768SDavid Christensen enum {
1724e400768SDavid Christensen 	BLOCK_ATC,
1734e400768SDavid Christensen 	BLOCK_BRB1,
1744e400768SDavid Christensen 	BLOCK_CCM,
1754e400768SDavid Christensen 	BLOCK_CDU,
1764e400768SDavid Christensen 	BLOCK_CFC,
1774e400768SDavid Christensen 	BLOCK_CSDM,
1784e400768SDavid Christensen 	BLOCK_CSEM,
1794e400768SDavid Christensen 	BLOCK_DBG,
1804e400768SDavid Christensen 	BLOCK_DMAE,
1814e400768SDavid Christensen 	BLOCK_DORQ,
1824e400768SDavid Christensen 	BLOCK_HC,
1834e400768SDavid Christensen 	BLOCK_IGU,
1844e400768SDavid Christensen 	BLOCK_MISC,
1854e400768SDavid Christensen 	BLOCK_NIG,
1864e400768SDavid Christensen 	BLOCK_PBF,
1874e400768SDavid Christensen 	BLOCK_PGLUE_B,
1884e400768SDavid Christensen 	BLOCK_PRS,
1894e400768SDavid Christensen 	BLOCK_PXP2,
1904e400768SDavid Christensen 	BLOCK_PXP,
1914e400768SDavid Christensen 	BLOCK_QM,
1924e400768SDavid Christensen 	BLOCK_SRC,
1934e400768SDavid Christensen 	BLOCK_TCM,
1944e400768SDavid Christensen 	BLOCK_TM,
1954e400768SDavid Christensen 	BLOCK_TSDM,
1964e400768SDavid Christensen 	BLOCK_TSEM,
1974e400768SDavid Christensen 	BLOCK_UCM,
1984e400768SDavid Christensen 	BLOCK_UPB,
1994e400768SDavid Christensen 	BLOCK_USDM,
2004e400768SDavid Christensen 	BLOCK_USEM,
2014e400768SDavid Christensen 	BLOCK_XCM,
2024e400768SDavid Christensen 	BLOCK_XPB,
2034e400768SDavid Christensen 	BLOCK_XSDM,
2044e400768SDavid Christensen 	BLOCK_XSEM,
2054e400768SDavid Christensen 	BLOCK_MISC_AEU,
2064e400768SDavid Christensen 	NUM_OF_INIT_BLOCKS
2074e400768SDavid Christensen };
2084e400768SDavid Christensen 
2094e400768SDavid Christensen 
2104e400768SDavid Christensen 
2114e400768SDavid Christensen 
2124e400768SDavid Christensen 
2134e400768SDavid Christensen 
2144e400768SDavid Christensen 
2154e400768SDavid Christensen 
2164e400768SDavid Christensen /* Vnics per mode */
2174e400768SDavid Christensen #define ECORE_PORT2_MODE_NUM_VNICS 4
2184e400768SDavid Christensen 
2194e400768SDavid Christensen 
2204e400768SDavid Christensen /* QM queue numbers */
2214e400768SDavid Christensen #define ECORE_ETH_Q		0
2224e400768SDavid Christensen #define ECORE_TOE_Q		3
2234e400768SDavid Christensen #define ECORE_TOE_ACK_Q		6
2244e400768SDavid Christensen #define ECORE_ISCSI_Q		9
2254e400768SDavid Christensen #define ECORE_ISCSI_ACK_Q	11
2264e400768SDavid Christensen #define ECORE_FCOE_Q		10
2274e400768SDavid Christensen 
2284e400768SDavid Christensen /* Vnics per mode */
2294e400768SDavid Christensen #define ECORE_PORT4_MODE_NUM_VNICS 2
2304e400768SDavid Christensen 
2314e400768SDavid Christensen /* COS offset for port1 in E3 B0 4port mode */
2324e400768SDavid Christensen #define ECORE_E3B0_PORT1_COS_OFFSET 3
2334e400768SDavid Christensen 
2344e400768SDavid Christensen /* QM Register addresses */
2354e400768SDavid Christensen #define ECORE_Q_VOQ_REG_ADDR(pf_q_num)\
2364e400768SDavid Christensen 	(QM_REG_QVOQIDX_0 + 4 * (pf_q_num))
2374e400768SDavid Christensen #define ECORE_VOQ_Q_REG_ADDR(cos, pf_q_num)\
2384e400768SDavid Christensen 	(QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5)))
2394e400768SDavid Christensen #define ECORE_Q_CMDQ_REG_ADDR(pf_q_num)\
2404e400768SDavid Christensen 	(QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4))
2414e400768SDavid Christensen 
2424e400768SDavid Christensen /* extracts the QM queue number for the specified port and vnic */
2434e400768SDavid Christensen #define ECORE_PF_Q_NUM(q_num, port, vnic)\
2444e400768SDavid Christensen 	((((port) << 1) | (vnic)) * 16 + (q_num))
2454e400768SDavid Christensen 
2464e400768SDavid Christensen 
2474e400768SDavid Christensen /* Maps the specified queue to the specified COS */
ecore_map_q_cos(struct bxe_softc * sc,uint32_t q_num,uint32_t new_cos)2484e400768SDavid Christensen static inline void ecore_map_q_cos(struct bxe_softc *sc, uint32_t q_num, uint32_t new_cos)
2494e400768SDavid Christensen {
2504e400768SDavid Christensen 	/* find current COS mapping */
2514e400768SDavid Christensen 	uint32_t curr_cos = REG_RD(sc, QM_REG_QVOQIDX_0 + q_num * 4);
2524e400768SDavid Christensen 
2534e400768SDavid Christensen 	/* check if queue->COS mapping has changed */
2544e400768SDavid Christensen 	if (curr_cos != new_cos) {
2554e400768SDavid Christensen 		uint32_t num_vnics = ECORE_PORT2_MODE_NUM_VNICS;
2564e400768SDavid Christensen 		uint32_t reg_addr, reg_bit_map, vnic;
2574e400768SDavid Christensen 
2584e400768SDavid Christensen 		/* update parameters for 4port mode */
2594e400768SDavid Christensen 		if (INIT_MODE_FLAGS(sc) & MODE_PORT4) {
2604e400768SDavid Christensen 			num_vnics = ECORE_PORT4_MODE_NUM_VNICS;
2614e400768SDavid Christensen 			if (PORT_ID(sc)) {
2624e400768SDavid Christensen 				curr_cos += ECORE_E3B0_PORT1_COS_OFFSET;
2634e400768SDavid Christensen 				new_cos += ECORE_E3B0_PORT1_COS_OFFSET;
2644e400768SDavid Christensen 			}
2654e400768SDavid Christensen 		}
2664e400768SDavid Christensen 
2674e400768SDavid Christensen 		/* change queue mapping for each VNIC */
2684e400768SDavid Christensen 		for (vnic = 0; vnic < num_vnics; vnic++) {
2694e400768SDavid Christensen 			uint32_t pf_q_num =
2704e400768SDavid Christensen 				ECORE_PF_Q_NUM(q_num, PORT_ID(sc), vnic);
2714e400768SDavid Christensen 			uint32_t q_bit_map = 1 << (pf_q_num & 0x1f);
2724e400768SDavid Christensen 
2734e400768SDavid Christensen 			/* overwrite queue->VOQ mapping */
2744e400768SDavid Christensen 			REG_WR(sc, ECORE_Q_VOQ_REG_ADDR(pf_q_num), new_cos);
2754e400768SDavid Christensen 
2764e400768SDavid Christensen 			/* clear queue bit from current COS bit map */
2774e400768SDavid Christensen 			reg_addr = ECORE_VOQ_Q_REG_ADDR(curr_cos, pf_q_num);
2784e400768SDavid Christensen 			reg_bit_map = REG_RD(sc, reg_addr);
2794e400768SDavid Christensen 			REG_WR(sc, reg_addr, reg_bit_map & (~q_bit_map));
2804e400768SDavid Christensen 
2814e400768SDavid Christensen 			/* set queue bit in new COS bit map */
2824e400768SDavid Christensen 			reg_addr = ECORE_VOQ_Q_REG_ADDR(new_cos, pf_q_num);
2834e400768SDavid Christensen 			reg_bit_map = REG_RD(sc, reg_addr);
2844e400768SDavid Christensen 			REG_WR(sc, reg_addr, reg_bit_map | q_bit_map);
2854e400768SDavid Christensen 
2864e400768SDavid Christensen 			/* set/clear queue bit in command-queue bit map
2874e400768SDavid Christensen 			(E2/E3A0 only, valid COS values are 0/1) */
2884e400768SDavid Christensen 			if (!(INIT_MODE_FLAGS(sc) & MODE_E3_B0)) {
2894e400768SDavid Christensen 				reg_addr = ECORE_Q_CMDQ_REG_ADDR(pf_q_num);
2904e400768SDavid Christensen 				reg_bit_map = REG_RD(sc, reg_addr);
2914e400768SDavid Christensen 				q_bit_map = 1 << (2 * (pf_q_num & 0xf));
2924e400768SDavid Christensen 				reg_bit_map = new_cos ?
2934e400768SDavid Christensen 					      (reg_bit_map | q_bit_map) :
2944e400768SDavid Christensen 					      (reg_bit_map & (~q_bit_map));
2954e400768SDavid Christensen 				REG_WR(sc, reg_addr, reg_bit_map);
2964e400768SDavid Christensen 			}
2974e400768SDavid Christensen 		}
2984e400768SDavid Christensen 	}
2994e400768SDavid Christensen }
3004e400768SDavid Christensen 
3014e400768SDavid Christensen /* Configures the QM according to the specified per-traffic-type COSes */
ecore_dcb_config_qm(struct bxe_softc * sc,enum cos_mode mode,struct priority_cos * traffic_cos)3024e400768SDavid Christensen static inline void ecore_dcb_config_qm(struct bxe_softc *sc, enum cos_mode mode,
3034e400768SDavid Christensen 				       struct priority_cos *traffic_cos)
3044e400768SDavid Christensen {
3054e400768SDavid Christensen 	ecore_map_q_cos(sc, ECORE_FCOE_Q,
3064e400768SDavid Christensen 			traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos);
3074e400768SDavid Christensen 	ecore_map_q_cos(sc, ECORE_ISCSI_Q,
3084e400768SDavid Christensen 			traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
3094e400768SDavid Christensen 	ecore_map_q_cos(sc, ECORE_ISCSI_ACK_Q,
3104e400768SDavid Christensen 		traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
3114e400768SDavid Christensen 	if (mode != STATIC_COS) {
3124e400768SDavid Christensen 		/* required only in OVERRIDE_COS mode */
3134e400768SDavid Christensen 		ecore_map_q_cos(sc, ECORE_ETH_Q,
3144e400768SDavid Christensen 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
3154e400768SDavid Christensen 		ecore_map_q_cos(sc, ECORE_TOE_Q,
3164e400768SDavid Christensen 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
3174e400768SDavid Christensen 		ecore_map_q_cos(sc, ECORE_TOE_ACK_Q,
3184e400768SDavid Christensen 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
3194e400768SDavid Christensen 	}
3204e400768SDavid Christensen }
3214e400768SDavid Christensen 
3224e400768SDavid Christensen 
3234e400768SDavid Christensen /*
324453130d9SPedro F. Giffuni  * congestion management port init api description
3254e400768SDavid Christensen  * the api works as follows:
3264e400768SDavid Christensen  * the driver should pass the cmng_init_input struct, the port_init function
3274e400768SDavid Christensen  * will prepare the required internal ram structure which will be passed back
3284e400768SDavid Christensen  * to the driver (cmng_init) that will write it into the internal ram.
3294e400768SDavid Christensen  *
3304e400768SDavid Christensen  * IMPORTANT REMARKS:
3314e400768SDavid Christensen  * 1. the cmng_init struct does not represent the contiguous internal ram
3324e400768SDavid Christensen  *    structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
3334e400768SDavid Christensen  *    offset in order to write the port sub struct and the
3344e400768SDavid Christensen  *    PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
3354e400768SDavid Christensen  *    words - don't use memcpy!).
3364e400768SDavid Christensen  * 2. although the cmng_init struct is filled for the maximal vnic number
3374e400768SDavid Christensen  *    possible, the driver should only write the valid vnics into the internal
3384e400768SDavid Christensen  *    ram according to the appropriate port mode.
3394e400768SDavid Christensen  */
3404e400768SDavid Christensen #define BITS_TO_BYTES(x) ((x)/8)
3414e400768SDavid Christensen 
3424e400768SDavid Christensen /* CMNG constants, as derived from system spec calculations */
3434e400768SDavid Christensen 
3444e400768SDavid Christensen /* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
3454e400768SDavid Christensen #define DEF_MIN_RATE 100
3464e400768SDavid Christensen 
3474e400768SDavid Christensen /* resolution of the rate shaping timer - 400 usec */
3484e400768SDavid Christensen #define RS_PERIODIC_TIMEOUT_USEC 400
3494e400768SDavid Christensen 
3504e400768SDavid Christensen /*
3514e400768SDavid Christensen  *  number of bytes in single QM arbitration cycle -
3524e400768SDavid Christensen  *  coefficient for calculating the fairness timer
3534e400768SDavid Christensen  */
3544e400768SDavid Christensen #define QM_ARB_BYTES 160000
3554e400768SDavid Christensen 
3564e400768SDavid Christensen /* resolution of Min algorithm 1:100 */
3574e400768SDavid Christensen #define MIN_RES 100
3584e400768SDavid Christensen 
3594e400768SDavid Christensen /*
3604e400768SDavid Christensen  *  how many bytes above threshold for
3614e400768SDavid Christensen  *  the minimal credit of Min algorithm
3624e400768SDavid Christensen  */
3634e400768SDavid Christensen #define MIN_ABOVE_THRESH 32768
3644e400768SDavid Christensen 
3654e400768SDavid Christensen /*
3664e400768SDavid Christensen  *  Fairness algorithm integration time coefficient -
3674e400768SDavid Christensen  *  for calculating the actual Tfair
3684e400768SDavid Christensen  */
3694e400768SDavid Christensen #define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
3704e400768SDavid Christensen 
3714e400768SDavid Christensen /* Memory of fairness algorithm - 2 cycles */
3724e400768SDavid Christensen #define FAIR_MEM 2
3734e400768SDavid Christensen #define SAFC_TIMEOUT_USEC 52
3744e400768SDavid Christensen 
3754e400768SDavid Christensen #define SDM_TICKS 4
3764e400768SDavid Christensen 
3774e400768SDavid Christensen 
ecore_init_max(const struct cmng_init_input * input_data,uint32_t r_param,struct cmng_init * ram_data)3784e400768SDavid Christensen static inline void ecore_init_max(const struct cmng_init_input *input_data,
3794e400768SDavid Christensen 				  uint32_t r_param, struct cmng_init *ram_data)
3804e400768SDavid Christensen {
3814e400768SDavid Christensen 	uint32_t vnic;
3824e400768SDavid Christensen 	struct cmng_vnic *vdata = &ram_data->vnic;
3834e400768SDavid Christensen 	struct cmng_struct_per_port *pdata = &ram_data->port;
3844e400768SDavid Christensen 	/*
3854e400768SDavid Christensen 	 * rate shaping per-port variables
3864e400768SDavid Christensen 	 *  100 micro seconds in SDM ticks = 25
3874e400768SDavid Christensen 	 *  since each tick is 4 microSeconds
3884e400768SDavid Christensen 	 */
3894e400768SDavid Christensen 
3904e400768SDavid Christensen 	pdata->rs_vars.rs_periodic_timeout =
3914e400768SDavid Christensen 	RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
3924e400768SDavid Christensen 
3934e400768SDavid Christensen 	/* this is the threshold below which no timer arming will occur.
3944e400768SDavid Christensen 	 *  1.25 coefficient is for the threshold to be a little bigger
3954e400768SDavid Christensen 	 *  then the real time to compensate for timer in-accuracy
3964e400768SDavid Christensen 	 */
3974e400768SDavid Christensen 	pdata->rs_vars.rs_threshold =
3984e400768SDavid Christensen 	(5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
3994e400768SDavid Christensen 
4004e400768SDavid Christensen 	/* rate shaping per-vnic variables */
4014e400768SDavid Christensen 	for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
4024e400768SDavid Christensen 		/* global vnic counter */
4034e400768SDavid Christensen 		vdata->vnic_max_rate[vnic].vn_counter.rate =
4044e400768SDavid Christensen 		input_data->vnic_max_rate[vnic];
4054e400768SDavid Christensen 		/*
4064e400768SDavid Christensen 		 * maximal Mbps for this vnic
4074e400768SDavid Christensen 		 * the quota in each timer period - number of bytes
4084e400768SDavid Christensen 		 * transmitted in this period
4094e400768SDavid Christensen 		 */
4104e400768SDavid Christensen 		vdata->vnic_max_rate[vnic].vn_counter.quota =
4114e400768SDavid Christensen 			RS_PERIODIC_TIMEOUT_USEC *
4124e400768SDavid Christensen 			(uint32_t)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
4134e400768SDavid Christensen 	}
4144e400768SDavid Christensen 
4154e400768SDavid Christensen }
4164e400768SDavid Christensen 
ecore_init_max_per_vn(uint16_t vnic_max_rate,struct rate_shaping_vars_per_vn * ram_data)4174e400768SDavid Christensen static inline void ecore_init_max_per_vn(uint16_t vnic_max_rate,
4184e400768SDavid Christensen 				  struct rate_shaping_vars_per_vn *ram_data)
4194e400768SDavid Christensen {
4204e400768SDavid Christensen 	/* global vnic counter */
4214e400768SDavid Christensen 	ram_data->vn_counter.rate = vnic_max_rate;
4224e400768SDavid Christensen 
4234e400768SDavid Christensen 	/*
4244e400768SDavid Christensen 	* maximal Mbps for this vnic
4254e400768SDavid Christensen 	* the quota in each timer period - number of bytes
4264e400768SDavid Christensen 	* transmitted in this period
4274e400768SDavid Christensen 	*/
4284e400768SDavid Christensen 	ram_data->vn_counter.quota =
4294e400768SDavid Christensen 		RS_PERIODIC_TIMEOUT_USEC * (uint32_t)vnic_max_rate / 8;
4304e400768SDavid Christensen }
4314e400768SDavid Christensen 
ecore_init_min(const struct cmng_init_input * input_data,uint32_t r_param,struct cmng_init * ram_data)4324e400768SDavid Christensen static inline void ecore_init_min(const struct cmng_init_input *input_data,
4334e400768SDavid Christensen 				  uint32_t r_param, struct cmng_init *ram_data)
4344e400768SDavid Christensen {
4354e400768SDavid Christensen 	uint32_t vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
4364e400768SDavid Christensen 	struct cmng_vnic *vdata = &ram_data->vnic;
4374e400768SDavid Christensen 	struct cmng_struct_per_port *pdata = &ram_data->port;
4384e400768SDavid Christensen 
4394e400768SDavid Christensen 	/* this is the resolution of the fairness timer */
4404e400768SDavid Christensen 	fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
4414e400768SDavid Christensen 
4424e400768SDavid Christensen 	/*
4434e400768SDavid Christensen 	 * fairness per-port variables
4444e400768SDavid Christensen 	 * for 10G it is 1000usec. for 1G it is 10000usec.
4454e400768SDavid Christensen 	 */
4464e400768SDavid Christensen 	tFair = T_FAIR_COEF / input_data->port_rate;
4474e400768SDavid Christensen 
4484e400768SDavid Christensen 	/* this is the threshold below which we won't arm the timer anymore */
4494e400768SDavid Christensen 	pdata->fair_vars.fair_threshold = QM_ARB_BYTES;
4504e400768SDavid Christensen 
4514e400768SDavid Christensen 	/*
4524e400768SDavid Christensen 	 *  we multiply by 1e3/8 to get bytes/msec. We don't want the credits
4534e400768SDavid Christensen 	 *  to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
4544e400768SDavid Christensen 	 */
4554e400768SDavid Christensen 	pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
4564e400768SDavid Christensen 
4574e400768SDavid Christensen 	/* since each tick is 4 microSeconds */
4584e400768SDavid Christensen 	pdata->fair_vars.fairness_timeout =
4594e400768SDavid Christensen 				fair_periodic_timeout_usec / SDM_TICKS;
4604e400768SDavid Christensen 
4614e400768SDavid Christensen 	/* calculate sum of weights */
4624e400768SDavid Christensen 	vnicWeightSum = 0;
4634e400768SDavid Christensen 
4644e400768SDavid Christensen 	for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++)
4654e400768SDavid Christensen 		vnicWeightSum += input_data->vnic_min_rate[vnic];
4664e400768SDavid Christensen 
4674e400768SDavid Christensen 	/* global vnic counter */
4684e400768SDavid Christensen 	if (vnicWeightSum > 0) {
4694e400768SDavid Christensen 		/* fairness per-vnic variables */
4704e400768SDavid Christensen 		for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
4714e400768SDavid Christensen 			/*
4724e400768SDavid Christensen 			 *  this is the credit for each period of the fairness
4734e400768SDavid Christensen 			 *  algorithm - number of bytes in T_FAIR (this vnic
4744e400768SDavid Christensen 			 *  share of the port rate)
4754e400768SDavid Christensen 			 */
4764e400768SDavid Christensen 			vdata->vnic_min_rate[vnic].vn_credit_delta =
4774e400768SDavid Christensen 				((uint32_t)(input_data->vnic_min_rate[vnic]) * 100 *
4784e400768SDavid Christensen 				(T_FAIR_COEF / (8 * 100 * vnicWeightSum)));
4794e400768SDavid Christensen 			if (vdata->vnic_min_rate[vnic].vn_credit_delta <
4804e400768SDavid Christensen 			    pdata->fair_vars.fair_threshold +
4814e400768SDavid Christensen 			    MIN_ABOVE_THRESH) {
4824e400768SDavid Christensen 				vdata->vnic_min_rate[vnic].vn_credit_delta =
4834e400768SDavid Christensen 					pdata->fair_vars.fair_threshold +
4844e400768SDavid Christensen 					MIN_ABOVE_THRESH;
4854e400768SDavid Christensen 			}
4864e400768SDavid Christensen 		}
4874e400768SDavid Christensen 	}
4884e400768SDavid Christensen }
4894e400768SDavid Christensen 
ecore_init_fw_wrr(const struct cmng_init_input * input_data,uint32_t r_param,struct cmng_init * ram_data)4904e400768SDavid Christensen static inline void ecore_init_fw_wrr(const struct cmng_init_input *input_data,
4914e400768SDavid Christensen 				     uint32_t r_param, struct cmng_init *ram_data)
4924e400768SDavid Christensen {
4934e400768SDavid Christensen 	uint32_t vnic, cos;
4944e400768SDavid Christensen 	uint32_t cosWeightSum = 0;
4954e400768SDavid Christensen 	struct cmng_vnic *vdata = &ram_data->vnic;
4964e400768SDavid Christensen 	struct cmng_struct_per_port *pdata = &ram_data->port;
4974e400768SDavid Christensen 
4984e400768SDavid Christensen 	for (cos = 0; cos < MAX_COS_NUMBER; cos++)
4994e400768SDavid Christensen 		cosWeightSum += input_data->cos_min_rate[cos];
5004e400768SDavid Christensen 
5014e400768SDavid Christensen 	if (cosWeightSum > 0) {
5024e400768SDavid Christensen 
5034e400768SDavid Christensen 		for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
5044e400768SDavid Christensen 			/*
5054e400768SDavid Christensen 			 *  Since cos and vnic shouldn't work together the rate
5064e400768SDavid Christensen 			 *  to divide between the coses is the port rate.
5074e400768SDavid Christensen 			 */
5084e400768SDavid Christensen 			uint32_t *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
5094e400768SDavid Christensen 			for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
5104e400768SDavid Christensen 				/*
5114e400768SDavid Christensen 				 * this is the credit for each period of
5124e400768SDavid Christensen 				 * the fairness algorithm - number of bytes
5134e400768SDavid Christensen 				 * in T_FAIR (this cos share of the vnic rate)
5144e400768SDavid Christensen 				 */
5154e400768SDavid Christensen 				ccd[cos] =
5164e400768SDavid Christensen 				    ((uint32_t)input_data->cos_min_rate[cos] * 100 *
5174e400768SDavid Christensen 				    (T_FAIR_COEF / (8 * 100 * cosWeightSum)));
5184e400768SDavid Christensen 				 if (ccd[cos] < pdata->fair_vars.fair_threshold
5194e400768SDavid Christensen 						+ MIN_ABOVE_THRESH) {
5204e400768SDavid Christensen 					ccd[cos] =
5214e400768SDavid Christensen 					    pdata->fair_vars.fair_threshold +
5224e400768SDavid Christensen 					    MIN_ABOVE_THRESH;
5234e400768SDavid Christensen 				}
5244e400768SDavid Christensen 			}
5254e400768SDavid Christensen 		}
5264e400768SDavid Christensen 	}
5274e400768SDavid Christensen }
5284e400768SDavid Christensen 
ecore_init_safc(const struct cmng_init_input * input_data,struct cmng_init * ram_data)5294e400768SDavid Christensen static inline void ecore_init_safc(const struct cmng_init_input *input_data,
5304e400768SDavid Christensen 				   struct cmng_init *ram_data)
5314e400768SDavid Christensen {
5324e400768SDavid Christensen 	/* in microSeconds */
5334e400768SDavid Christensen 	ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
5344e400768SDavid Christensen }
5354e400768SDavid Christensen 
5364e400768SDavid Christensen /* Congestion management port init */
ecore_init_cmng(const struct cmng_init_input * input_data,struct cmng_init * ram_data)5374e400768SDavid Christensen static inline void ecore_init_cmng(const struct cmng_init_input *input_data,
5384e400768SDavid Christensen 				   struct cmng_init *ram_data)
5394e400768SDavid Christensen {
5404e400768SDavid Christensen 	uint32_t r_param;
5414e400768SDavid Christensen 	ECORE_MEMSET(ram_data, 0,sizeof(struct cmng_init));
5424e400768SDavid Christensen 
5434e400768SDavid Christensen 	ram_data->port.flags = input_data->flags;
5444e400768SDavid Christensen 
5454e400768SDavid Christensen 	/*
5464e400768SDavid Christensen 	 *  number of bytes transmitted in a rate of 10Gbps
5474e400768SDavid Christensen 	 *  in one usec = 1.25KB.
5484e400768SDavid Christensen 	 */
5494e400768SDavid Christensen 	r_param = BITS_TO_BYTES(input_data->port_rate);
5504e400768SDavid Christensen 	ecore_init_max(input_data, r_param, ram_data);
5514e400768SDavid Christensen 	ecore_init_min(input_data, r_param, ram_data);
5524e400768SDavid Christensen 	ecore_init_fw_wrr(input_data, r_param, ram_data);
5534e400768SDavid Christensen 	ecore_init_safc(input_data, ram_data);
5544e400768SDavid Christensen }
5554e400768SDavid Christensen 
5564e400768SDavid Christensen 
5574e400768SDavid Christensen 
5584e400768SDavid Christensen 
5594e400768SDavid Christensen /* Returns the index of start or end of a specific block stage in ops array*/
5604e400768SDavid Christensen #define BLOCK_OPS_IDX(block, stage, end) \
5614e400768SDavid Christensen 			(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
5624e400768SDavid Christensen 
5634e400768SDavid Christensen 
5644e400768SDavid Christensen #define INITOP_SET		0	/* set the HW directly */
5654e400768SDavid Christensen #define INITOP_CLEAR		1	/* clear the HW directly */
5664e400768SDavid Christensen #define INITOP_INIT		2	/* set the init-value array */
5674e400768SDavid Christensen 
5684e400768SDavid Christensen /****************************************************************************
5694e400768SDavid Christensen * ILT management
5704e400768SDavid Christensen ****************************************************************************/
5714e400768SDavid Christensen struct ilt_line {
5724e400768SDavid Christensen 	ecore_dma_addr_t page_mapping;
5734e400768SDavid Christensen 	void *page;
5744e400768SDavid Christensen 	uint32_t size;
5754e400768SDavid Christensen };
5764e400768SDavid Christensen 
5774e400768SDavid Christensen struct ilt_client_info {
5784e400768SDavid Christensen 	uint32_t page_size;
5794e400768SDavid Christensen 	uint16_t start;
5804e400768SDavid Christensen 	uint16_t end;
5814e400768SDavid Christensen 	uint16_t client_num;
5824e400768SDavid Christensen 	uint16_t flags;
5834e400768SDavid Christensen #define ILT_CLIENT_SKIP_INIT	0x1
5844e400768SDavid Christensen #define ILT_CLIENT_SKIP_MEM	0x2
5854e400768SDavid Christensen };
5864e400768SDavid Christensen 
5874e400768SDavid Christensen struct ecore_ilt {
5884e400768SDavid Christensen 	uint32_t start_line;
5894e400768SDavid Christensen 	struct ilt_line		*lines;
5904e400768SDavid Christensen 	struct ilt_client_info	clients[4];
5914e400768SDavid Christensen #define ILT_CLIENT_CDU	0
5924e400768SDavid Christensen #define ILT_CLIENT_QM	1
5934e400768SDavid Christensen #define ILT_CLIENT_SRC	2
5944e400768SDavid Christensen #define ILT_CLIENT_TM	3
5954e400768SDavid Christensen };
5964e400768SDavid Christensen 
5974e400768SDavid Christensen /****************************************************************************
5984e400768SDavid Christensen * SRC configuration
5994e400768SDavid Christensen ****************************************************************************/
6004e400768SDavid Christensen struct src_ent {
6014e400768SDavid Christensen 	uint8_t opaque[56];
6024e400768SDavid Christensen 	uint64_t next;
6034e400768SDavid Christensen };
6044e400768SDavid Christensen 
6054e400768SDavid Christensen /****************************************************************************
6064e400768SDavid Christensen * Parity configuration
6074e400768SDavid Christensen ****************************************************************************/
6084e400768SDavid Christensen #define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \
6094e400768SDavid Christensen { \
6104e400768SDavid Christensen 	block##_REG_##block##_PRTY_MASK, \
6114e400768SDavid Christensen 	block##_REG_##block##_PRTY_STS_CLR, \
6124e400768SDavid Christensen 	en_mask, {m1, m1h, m2, m3}, #block \
6134e400768SDavid Christensen }
6144e400768SDavid Christensen 
6154e400768SDavid Christensen #define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \
6164e400768SDavid Christensen { \
6174e400768SDavid Christensen 	block##_REG_##block##_PRTY_MASK_0, \
6184e400768SDavid Christensen 	block##_REG_##block##_PRTY_STS_CLR_0, \
6194e400768SDavid Christensen 	en_mask, {m1, m1h, m2, m3}, #block"_0" \
6204e400768SDavid Christensen }
6214e400768SDavid Christensen 
6224e400768SDavid Christensen #define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \
6234e400768SDavid Christensen { \
6244e400768SDavid Christensen 	block##_REG_##block##_PRTY_MASK_1, \
6254e400768SDavid Christensen 	block##_REG_##block##_PRTY_STS_CLR_1, \
6264e400768SDavid Christensen 	en_mask, {m1, m1h, m2, m3}, #block"_1" \
6274e400768SDavid Christensen }
6284e400768SDavid Christensen 
6294e400768SDavid Christensen static const struct {
6304e400768SDavid Christensen 	uint32_t mask_addr;
6314e400768SDavid Christensen 	uint32_t sts_clr_addr;
6324e400768SDavid Christensen 	uint32_t en_mask;		/* Mask to enable parity attentions */
6334e400768SDavid Christensen 	struct {
6344e400768SDavid Christensen 		uint32_t e1;		/* 57710 */
6354e400768SDavid Christensen 		uint32_t e1h;	/* 57711 */
6364e400768SDavid Christensen 		uint32_t e2;		/* 57712 */
6374e400768SDavid Christensen 		uint32_t e3;		/* 578xx */
6384e400768SDavid Christensen 	} reg_mask;		/* Register mask (all valid bits) */
6394e400768SDavid Christensen 	char name[8];		/* Block's longest name is 7 characters long
6404e400768SDavid Christensen 				 * (name + suffix)
6414e400768SDavid Christensen 				 */
6424e400768SDavid Christensen } ecore_blocks_parity_data[] = {
6434e400768SDavid Christensen 	/* bit 19 masked */
6444e400768SDavid Christensen 	/* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */
6454e400768SDavid Christensen 	/* bit 5,18,20-31 */
6464e400768SDavid Christensen 	/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */
6474e400768SDavid Christensen 	/* bit 5 */
6484e400768SDavid Christensen 	/* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20);	*/
6494e400768SDavid Christensen 	/* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */
6504e400768SDavid Christensen 	/* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */
6514e400768SDavid Christensen 
6524e400768SDavid Christensen 	/* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't
6534e400768SDavid Christensen 	 * want to handle "system kill" flow at the moment.
6544e400768SDavid Christensen 	 */
6554e400768SDavid Christensen 	BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff,
6564e400768SDavid Christensen 			0x7ffffff),
6574e400768SDavid Christensen 	BLOCK_PRTY_INFO_0(PXP2,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
6584e400768SDavid Christensen 			  0xffffffff),
6594e400768SDavid Christensen 	BLOCK_PRTY_INFO_1(PXP2,	0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff),
6604e400768SDavid Christensen 	BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0),
6614e400768SDavid Christensen 	BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0),
6624e400768SDavid Christensen 	BLOCK_PRTY_INFO_0(NIG,	0xffffffff, 0, 0, 0xffffffff, 0xffffffff),
6634e400768SDavid Christensen 	BLOCK_PRTY_INFO_1(NIG,	0xffff, 0, 0, 0xff, 0xffff),
6644e400768SDavid Christensen 	BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff),
6654e400768SDavid Christensen 	BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1),
6664e400768SDavid Christensen 	BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff),
6674e400768SDavid Christensen 	BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f),
6684e400768SDavid Christensen 	BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3),
6694e400768SDavid Christensen 	BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3),
6704e400768SDavid Christensen 	{GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
6714e400768SDavid Christensen 		GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf,
6724e400768SDavid Christensen 		{0xf, 0xf, 0xf, 0xf}, "UPB"},
6734e400768SDavid Christensen 	{GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
6744e400768SDavid Christensen 		GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
6754e400768SDavid Christensen 		{0xf, 0xf, 0xf, 0xf}, "XPB"},
6764e400768SDavid Christensen 	BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7),
6774e400768SDavid Christensen 	BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f),
6784e400768SDavid Christensen 	BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f),
6794e400768SDavid Christensen 	BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1),
6804e400768SDavid Christensen 	BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf),
6814e400768SDavid Christensen 	BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf),
6824e400768SDavid Christensen 	BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff, 0xff),
6834e400768SDavid Christensen 	BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff),
6844e400768SDavid Christensen 	BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f),
6854e400768SDavid Christensen 	BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
6864e400768SDavid Christensen 	BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
6874e400768SDavid Christensen 	BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
6884e400768SDavid Christensen 	BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
6894e400768SDavid Christensen 	BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
6904e400768SDavid Christensen 	BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
6914e400768SDavid Christensen 	BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
6924e400768SDavid Christensen 	BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff),
6934e400768SDavid Christensen 	BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
6944e400768SDavid Christensen 			  0xffffffff),
6954e400768SDavid Christensen 	BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
6964e400768SDavid Christensen 	BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
6974e400768SDavid Christensen 			  0xffffffff),
6984e400768SDavid Christensen 	BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
6994e400768SDavid Christensen 	BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
7004e400768SDavid Christensen 			  0xffffffff),
7014e400768SDavid Christensen 	BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
7024e400768SDavid Christensen 	BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
7034e400768SDavid Christensen 			  0xffffffff),
7044e400768SDavid Christensen 	BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
7054e400768SDavid Christensen };
7064e400768SDavid Christensen 
7074e400768SDavid Christensen 
7084e400768SDavid Christensen /* [28] MCP Latched rom_parity
7094e400768SDavid Christensen  * [29] MCP Latched ump_rx_parity
7104e400768SDavid Christensen  * [30] MCP Latched ump_tx_parity
7114e400768SDavid Christensen  * [31] MCP Latched scpad_parity
7124e400768SDavid Christensen  */
7135e33becaSEric Davis #define MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS	\
7144e400768SDavid Christensen 	(AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
7154e400768SDavid Christensen 	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
7165e33becaSEric Davis 	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY)
7175e33becaSEric Davis 
7185e33becaSEric Davis #define MISC_AEU_ENABLE_MCP_PRTY_BITS	\
7195e33becaSEric Davis 	(MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS | \
7204e400768SDavid Christensen 	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
7214e400768SDavid Christensen 
7224e400768SDavid Christensen /* Below registers control the MCP parity attention output. When
7234e400768SDavid Christensen  * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
7244e400768SDavid Christensen  * enabled, when cleared - disabled.
7254e400768SDavid Christensen  */
7265e33becaSEric Davis static const struct {
7275e33becaSEric Davis 	uint32_t addr;
7285e33becaSEric Davis 	uint32_t bits;
7295e33becaSEric Davis } mcp_attn_ctl_regs[] = {
7305e33becaSEric Davis 	{ MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
7315e33becaSEric Davis 		MISC_AEU_ENABLE_MCP_PRTY_BITS },
7325e33becaSEric Davis 	{ MISC_REG_AEU_ENABLE4_NIG_0,
7335e33becaSEric Davis 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
7345e33becaSEric Davis 	{ MISC_REG_AEU_ENABLE4_PXP_0,
7355e33becaSEric Davis 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
7365e33becaSEric Davis 	{ MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
7375e33becaSEric Davis 		MISC_AEU_ENABLE_MCP_PRTY_BITS },
7385e33becaSEric Davis 	{ MISC_REG_AEU_ENABLE4_NIG_1,
7395e33becaSEric Davis 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
7405e33becaSEric Davis 	{ MISC_REG_AEU_ENABLE4_PXP_1,
7415e33becaSEric Davis 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }
7424e400768SDavid Christensen };
7434e400768SDavid Christensen 
ecore_set_mcp_parity(struct bxe_softc * sc,uint8_t enable)7444e400768SDavid Christensen static inline void ecore_set_mcp_parity(struct bxe_softc *sc, uint8_t enable)
7454e400768SDavid Christensen {
7464e400768SDavid Christensen 	int i;
7474e400768SDavid Christensen 	uint32_t reg_val;
7484e400768SDavid Christensen 
7494e400768SDavid Christensen 	for (i = 0; i < ARRSIZE(mcp_attn_ctl_regs); i++) {
7505e33becaSEric Davis 		reg_val = REG_RD(sc, mcp_attn_ctl_regs[i].addr);
7514e400768SDavid Christensen 
75229e60198SDavid C Somayajulu 		if (enable)
7534ef8ebfdSDavid C Somayajulu 			reg_val |= MISC_AEU_ENABLE_MCP_PRTY_BITS; /* Linux is using mcp_attn_ctl_regs[i].bits */
75429e60198SDavid C Somayajulu 		else
7554ef8ebfdSDavid C Somayajulu 			reg_val &= ~MISC_AEU_ENABLE_MCP_PRTY_BITS; /* Linux is using mcp_attn_ctl_regs[i].bits */
7564e400768SDavid Christensen 
7575e33becaSEric Davis 		REG_WR(sc, mcp_attn_ctl_regs[i].addr, reg_val);
7584e400768SDavid Christensen 	}
7594e400768SDavid Christensen }
7604e400768SDavid Christensen 
ecore_parity_reg_mask(struct bxe_softc * sc,int idx)7614e400768SDavid Christensen static inline uint32_t ecore_parity_reg_mask(struct bxe_softc *sc, int idx)
7624e400768SDavid Christensen {
7634e400768SDavid Christensen 	if (CHIP_IS_E1(sc))
7644e400768SDavid Christensen 		return ecore_blocks_parity_data[idx].reg_mask.e1;
7654e400768SDavid Christensen 	else if (CHIP_IS_E1H(sc))
7664e400768SDavid Christensen 		return ecore_blocks_parity_data[idx].reg_mask.e1h;
7674e400768SDavid Christensen 	else if (CHIP_IS_E2(sc))
7684e400768SDavid Christensen 		return ecore_blocks_parity_data[idx].reg_mask.e2;
7694e400768SDavid Christensen 	else /* CHIP_IS_E3 */
7704e400768SDavid Christensen 		return ecore_blocks_parity_data[idx].reg_mask.e3;
7714e400768SDavid Christensen }
7724e400768SDavid Christensen 
ecore_disable_blocks_parity(struct bxe_softc * sc)7734e400768SDavid Christensen static inline void ecore_disable_blocks_parity(struct bxe_softc *sc)
7744e400768SDavid Christensen {
7754e400768SDavid Christensen 	int i;
7764e400768SDavid Christensen 
7774e400768SDavid Christensen 	for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) {
7784e400768SDavid Christensen 		uint32_t dis_mask = ecore_parity_reg_mask(sc, i);
7794e400768SDavid Christensen 
7804e400768SDavid Christensen 		if (dis_mask) {
7814e400768SDavid Christensen 			REG_WR(sc, ecore_blocks_parity_data[i].mask_addr,
7824e400768SDavid Christensen 			       dis_mask);
7834e400768SDavid Christensen 			ECORE_MSG(sc, "Setting parity mask "
7844e400768SDavid Christensen 						 "for %s to\t\t0x%x\n",
7854e400768SDavid Christensen 				    ecore_blocks_parity_data[i].name, dis_mask);
7864e400768SDavid Christensen 		}
7874e400768SDavid Christensen 	}
7884e400768SDavid Christensen 
7894e400768SDavid Christensen 	/* Disable MCP parity attentions */
7904e400768SDavid Christensen 	ecore_set_mcp_parity(sc, FALSE);
7914e400768SDavid Christensen }
7924e400768SDavid Christensen 
7934e400768SDavid Christensen /**
7944e400768SDavid Christensen  * Clear the parity error status registers.
7954e400768SDavid Christensen  */
ecore_clear_blocks_parity(struct bxe_softc * sc)7964e400768SDavid Christensen static inline void ecore_clear_blocks_parity(struct bxe_softc *sc)
7974e400768SDavid Christensen {
7984e400768SDavid Christensen 	int i;
7994e400768SDavid Christensen 	uint32_t reg_val, mcp_aeu_bits =
8004e400768SDavid Christensen 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY |
8014e400768SDavid Christensen 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY |
8024e400768SDavid Christensen 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY |
8034e400768SDavid Christensen 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY;
8044e400768SDavid Christensen 
8054e400768SDavid Christensen 	/* Clear SEM_FAST parities */
8064e400768SDavid Christensen 	REG_WR(sc, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
8074e400768SDavid Christensen 	REG_WR(sc, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
8084e400768SDavid Christensen 	REG_WR(sc, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
8094e400768SDavid Christensen 	REG_WR(sc, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
8104e400768SDavid Christensen 
8114e400768SDavid Christensen 	for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) {
8124e400768SDavid Christensen 		uint32_t reg_mask = ecore_parity_reg_mask(sc, i);
8134e400768SDavid Christensen 
8144e400768SDavid Christensen 		if (reg_mask) {
8154e400768SDavid Christensen 			reg_val = REG_RD(sc, ecore_blocks_parity_data[i].
8164e400768SDavid Christensen 					 sts_clr_addr);
8174e400768SDavid Christensen 			if (reg_val & reg_mask)
8184e400768SDavid Christensen 				ECORE_MSG(sc,
8194e400768SDavid Christensen 					   "Parity errors in %s: 0x%x\n",
8204e400768SDavid Christensen 					   ecore_blocks_parity_data[i].name,
8214e400768SDavid Christensen 					   reg_val & reg_mask);
8224e400768SDavid Christensen 		}
8234e400768SDavid Christensen 	}
8244e400768SDavid Christensen 
8254e400768SDavid Christensen 	/* Check if there were parity attentions in MCP */
8264e400768SDavid Christensen 	reg_val = REG_RD(sc, MISC_REG_AEU_AFTER_INVERT_4_MCP);
8274e400768SDavid Christensen 	if (reg_val & mcp_aeu_bits)
8284e400768SDavid Christensen 		ECORE_MSG(sc, "Parity error in MCP: 0x%x\n",
8294e400768SDavid Christensen 			   reg_val & mcp_aeu_bits);
8304e400768SDavid Christensen 
8314e400768SDavid Christensen 	/* Clear parity attentions in MCP:
8324e400768SDavid Christensen 	 * [7]  clears Latched rom_parity
8334e400768SDavid Christensen 	 * [8]  clears Latched ump_rx_parity
8344e400768SDavid Christensen 	 * [9]  clears Latched ump_tx_parity
8354e400768SDavid Christensen 	 * [10] clears Latched scpad_parity (both ports)
8364e400768SDavid Christensen 	 */
8374e400768SDavid Christensen 	REG_WR(sc, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780);
8384e400768SDavid Christensen }
8394e400768SDavid Christensen 
ecore_enable_blocks_parity(struct bxe_softc * sc)8404e400768SDavid Christensen static inline void ecore_enable_blocks_parity(struct bxe_softc *sc)
8414e400768SDavid Christensen {
8424e400768SDavid Christensen 	int i;
8434e400768SDavid Christensen 
8444e400768SDavid Christensen 	for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) {
8454e400768SDavid Christensen 		uint32_t reg_mask = ecore_parity_reg_mask(sc, i);
8464e400768SDavid Christensen 
8474e400768SDavid Christensen 		if (reg_mask)
8484e400768SDavid Christensen 			REG_WR(sc, ecore_blocks_parity_data[i].mask_addr,
8494e400768SDavid Christensen 				ecore_blocks_parity_data[i].en_mask & reg_mask);
8504e400768SDavid Christensen 	}
8514e400768SDavid Christensen 
8524e400768SDavid Christensen 	/* Enable MCP parity attentions */
8534e400768SDavid Christensen 	ecore_set_mcp_parity(sc, TRUE);
8544e400768SDavid Christensen }
8554e400768SDavid Christensen 
8564e400768SDavid Christensen 
8574e400768SDavid Christensen #endif /* ECORE_INIT_H */
8584e400768SDavid Christensen 
859