18c2ecf20Sopenharmony_ci/* bnx2x_init.h: Qlogic Everest network driver. 28c2ecf20Sopenharmony_ci * Structures and macroes needed during the initialization. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (c) 2007-2013 Broadcom Corporation 58c2ecf20Sopenharmony_ci * Copyright (c) 2014 QLogic Corporation 68c2ecf20Sopenharmony_ci All rights reserved 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 98c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by 108c2ecf20Sopenharmony_ci * the Free Software Foundation. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * Maintained by: Ariel Elior <ariel.elior@qlogic.com> 138c2ecf20Sopenharmony_ci * Written by: Eliezer Tamir 148c2ecf20Sopenharmony_ci * Modified by: Vladislav Zolotarov 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifndef BNX2X_INIT_H 188c2ecf20Sopenharmony_ci#define BNX2X_INIT_H 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* Init operation types and structures */ 218c2ecf20Sopenharmony_cienum { 228c2ecf20Sopenharmony_ci OP_RD = 0x1, /* read a single register */ 238c2ecf20Sopenharmony_ci OP_WR, /* write a single register */ 248c2ecf20Sopenharmony_ci OP_SW, /* copy a string to the device */ 258c2ecf20Sopenharmony_ci OP_ZR, /* clear memory */ 268c2ecf20Sopenharmony_ci OP_ZP, /* unzip then copy with DMAE */ 278c2ecf20Sopenharmony_ci OP_WR_64, /* write 64 bit pattern */ 288c2ecf20Sopenharmony_ci OP_WB, /* copy a string using DMAE */ 298c2ecf20Sopenharmony_ci OP_WB_ZR, /* Clear a string using DMAE or indirect-wr */ 308c2ecf20Sopenharmony_ci /* Skip the following ops if all of the init modes don't match */ 318c2ecf20Sopenharmony_ci OP_IF_MODE_OR, 328c2ecf20Sopenharmony_ci /* Skip the following ops if any of the init modes don't match */ 338c2ecf20Sopenharmony_ci OP_IF_MODE_AND, 348c2ecf20Sopenharmony_ci OP_MAX 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cienum { 388c2ecf20Sopenharmony_ci STAGE_START, 398c2ecf20Sopenharmony_ci STAGE_END, 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* Returns the index of start or end of a specific block stage in ops array*/ 438c2ecf20Sopenharmony_ci#define BLOCK_OPS_IDX(block, stage, end) \ 448c2ecf20Sopenharmony_ci (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end)) 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* structs for the various opcodes */ 488c2ecf20Sopenharmony_cistruct raw_op { 498c2ecf20Sopenharmony_ci u32 op:8; 508c2ecf20Sopenharmony_ci u32 offset:24; 518c2ecf20Sopenharmony_ci u32 raw_data; 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cistruct op_read { 558c2ecf20Sopenharmony_ci u32 op:8; 568c2ecf20Sopenharmony_ci u32 offset:24; 578c2ecf20Sopenharmony_ci u32 val; 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistruct op_write { 618c2ecf20Sopenharmony_ci u32 op:8; 628c2ecf20Sopenharmony_ci u32 offset:24; 638c2ecf20Sopenharmony_ci u32 val; 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistruct op_arr_write { 678c2ecf20Sopenharmony_ci u32 op:8; 688c2ecf20Sopenharmony_ci u32 offset:24; 698c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN 708c2ecf20Sopenharmony_ci u16 data_len; 718c2ecf20Sopenharmony_ci u16 data_off; 728c2ecf20Sopenharmony_ci#else /* __LITTLE_ENDIAN */ 738c2ecf20Sopenharmony_ci u16 data_off; 748c2ecf20Sopenharmony_ci u16 data_len; 758c2ecf20Sopenharmony_ci#endif 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistruct op_zero { 798c2ecf20Sopenharmony_ci u32 op:8; 808c2ecf20Sopenharmony_ci u32 offset:24; 818c2ecf20Sopenharmony_ci u32 len; 828c2ecf20Sopenharmony_ci}; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistruct op_if_mode { 858c2ecf20Sopenharmony_ci u32 op:8; 868c2ecf20Sopenharmony_ci u32 cmd_offset:24; 878c2ecf20Sopenharmony_ci u32 mode_bit_map; 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciunion init_op { 928c2ecf20Sopenharmony_ci struct op_read read; 938c2ecf20Sopenharmony_ci struct op_write write; 948c2ecf20Sopenharmony_ci struct op_arr_write arr_wr; 958c2ecf20Sopenharmony_ci struct op_zero zero; 968c2ecf20Sopenharmony_ci struct raw_op raw; 978c2ecf20Sopenharmony_ci struct op_if_mode if_mode; 988c2ecf20Sopenharmony_ci}; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci/* Init Phases */ 1028c2ecf20Sopenharmony_cienum { 1038c2ecf20Sopenharmony_ci PHASE_COMMON, 1048c2ecf20Sopenharmony_ci PHASE_PORT0, 1058c2ecf20Sopenharmony_ci PHASE_PORT1, 1068c2ecf20Sopenharmony_ci PHASE_PF0, 1078c2ecf20Sopenharmony_ci PHASE_PF1, 1088c2ecf20Sopenharmony_ci PHASE_PF2, 1098c2ecf20Sopenharmony_ci PHASE_PF3, 1108c2ecf20Sopenharmony_ci PHASE_PF4, 1118c2ecf20Sopenharmony_ci PHASE_PF5, 1128c2ecf20Sopenharmony_ci PHASE_PF6, 1138c2ecf20Sopenharmony_ci PHASE_PF7, 1148c2ecf20Sopenharmony_ci NUM_OF_INIT_PHASES 1158c2ecf20Sopenharmony_ci}; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci/* Init Modes */ 1188c2ecf20Sopenharmony_cienum { 1198c2ecf20Sopenharmony_ci MODE_ASIC = 0x00000001, 1208c2ecf20Sopenharmony_ci MODE_FPGA = 0x00000002, 1218c2ecf20Sopenharmony_ci MODE_EMUL = 0x00000004, 1228c2ecf20Sopenharmony_ci MODE_E2 = 0x00000008, 1238c2ecf20Sopenharmony_ci MODE_E3 = 0x00000010, 1248c2ecf20Sopenharmony_ci MODE_PORT2 = 0x00000020, 1258c2ecf20Sopenharmony_ci MODE_PORT4 = 0x00000040, 1268c2ecf20Sopenharmony_ci MODE_SF = 0x00000080, 1278c2ecf20Sopenharmony_ci MODE_MF = 0x00000100, 1288c2ecf20Sopenharmony_ci MODE_MF_SD = 0x00000200, 1298c2ecf20Sopenharmony_ci MODE_MF_SI = 0x00000400, 1308c2ecf20Sopenharmony_ci MODE_MF_AFEX = 0x00000800, 1318c2ecf20Sopenharmony_ci MODE_E3_A0 = 0x00001000, 1328c2ecf20Sopenharmony_ci MODE_E3_B0 = 0x00002000, 1338c2ecf20Sopenharmony_ci MODE_COS3 = 0x00004000, 1348c2ecf20Sopenharmony_ci MODE_COS6 = 0x00008000, 1358c2ecf20Sopenharmony_ci MODE_LITTLE_ENDIAN = 0x00010000, 1368c2ecf20Sopenharmony_ci MODE_BIG_ENDIAN = 0x00020000, 1378c2ecf20Sopenharmony_ci}; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci/* Init Blocks */ 1408c2ecf20Sopenharmony_cienum { 1418c2ecf20Sopenharmony_ci BLOCK_ATC, 1428c2ecf20Sopenharmony_ci BLOCK_BRB1, 1438c2ecf20Sopenharmony_ci BLOCK_CCM, 1448c2ecf20Sopenharmony_ci BLOCK_CDU, 1458c2ecf20Sopenharmony_ci BLOCK_CFC, 1468c2ecf20Sopenharmony_ci BLOCK_CSDM, 1478c2ecf20Sopenharmony_ci BLOCK_CSEM, 1488c2ecf20Sopenharmony_ci BLOCK_DBG, 1498c2ecf20Sopenharmony_ci BLOCK_DMAE, 1508c2ecf20Sopenharmony_ci BLOCK_DORQ, 1518c2ecf20Sopenharmony_ci BLOCK_HC, 1528c2ecf20Sopenharmony_ci BLOCK_IGU, 1538c2ecf20Sopenharmony_ci BLOCK_MISC, 1548c2ecf20Sopenharmony_ci BLOCK_NIG, 1558c2ecf20Sopenharmony_ci BLOCK_PBF, 1568c2ecf20Sopenharmony_ci BLOCK_PGLUE_B, 1578c2ecf20Sopenharmony_ci BLOCK_PRS, 1588c2ecf20Sopenharmony_ci BLOCK_PXP2, 1598c2ecf20Sopenharmony_ci BLOCK_PXP, 1608c2ecf20Sopenharmony_ci BLOCK_QM, 1618c2ecf20Sopenharmony_ci BLOCK_SRC, 1628c2ecf20Sopenharmony_ci BLOCK_TCM, 1638c2ecf20Sopenharmony_ci BLOCK_TM, 1648c2ecf20Sopenharmony_ci BLOCK_TSDM, 1658c2ecf20Sopenharmony_ci BLOCK_TSEM, 1668c2ecf20Sopenharmony_ci BLOCK_UCM, 1678c2ecf20Sopenharmony_ci BLOCK_UPB, 1688c2ecf20Sopenharmony_ci BLOCK_USDM, 1698c2ecf20Sopenharmony_ci BLOCK_USEM, 1708c2ecf20Sopenharmony_ci BLOCK_XCM, 1718c2ecf20Sopenharmony_ci BLOCK_XPB, 1728c2ecf20Sopenharmony_ci BLOCK_XSDM, 1738c2ecf20Sopenharmony_ci BLOCK_XSEM, 1748c2ecf20Sopenharmony_ci BLOCK_MISC_AEU, 1758c2ecf20Sopenharmony_ci NUM_OF_INIT_BLOCKS 1768c2ecf20Sopenharmony_ci}; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci/* QM queue numbers */ 1798c2ecf20Sopenharmony_ci#define BNX2X_ETH_Q 0 1808c2ecf20Sopenharmony_ci#define BNX2X_TOE_Q 3 1818c2ecf20Sopenharmony_ci#define BNX2X_TOE_ACK_Q 6 1828c2ecf20Sopenharmony_ci#define BNX2X_ISCSI_Q 9 1838c2ecf20Sopenharmony_ci#define BNX2X_ISCSI_ACK_Q 11 1848c2ecf20Sopenharmony_ci#define BNX2X_FCOE_Q 10 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci/* Vnics per mode */ 1878c2ecf20Sopenharmony_ci#define BNX2X_PORT2_MODE_NUM_VNICS 4 1888c2ecf20Sopenharmony_ci#define BNX2X_PORT4_MODE_NUM_VNICS 2 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci/* COS offset for port1 in E3 B0 4port mode */ 1918c2ecf20Sopenharmony_ci#define BNX2X_E3B0_PORT1_COS_OFFSET 3 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci/* QM Register addresses */ 1948c2ecf20Sopenharmony_ci#define BNX2X_Q_VOQ_REG_ADDR(pf_q_num)\ 1958c2ecf20Sopenharmony_ci (QM_REG_QVOQIDX_0 + 4 * (pf_q_num)) 1968c2ecf20Sopenharmony_ci#define BNX2X_VOQ_Q_REG_ADDR(cos, pf_q_num)\ 1978c2ecf20Sopenharmony_ci (QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5))) 1988c2ecf20Sopenharmony_ci#define BNX2X_Q_CMDQ_REG_ADDR(pf_q_num)\ 1998c2ecf20Sopenharmony_ci (QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4)) 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/* extracts the QM queue number for the specified port and vnic */ 2028c2ecf20Sopenharmony_ci#define BNX2X_PF_Q_NUM(q_num, port, vnic)\ 2038c2ecf20Sopenharmony_ci ((((port) << 1) | (vnic)) * 16 + (q_num)) 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci/* Maps the specified queue to the specified COS */ 2078c2ecf20Sopenharmony_cistatic inline void bnx2x_map_q_cos(struct bnx2x *bp, u32 q_num, u32 new_cos) 2088c2ecf20Sopenharmony_ci{ 2098c2ecf20Sopenharmony_ci /* find current COS mapping */ 2108c2ecf20Sopenharmony_ci u32 curr_cos = REG_RD(bp, QM_REG_QVOQIDX_0 + q_num * 4); 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci /* check if queue->COS mapping has changed */ 2138c2ecf20Sopenharmony_ci if (curr_cos != new_cos) { 2148c2ecf20Sopenharmony_ci u32 num_vnics = BNX2X_PORT2_MODE_NUM_VNICS; 2158c2ecf20Sopenharmony_ci u32 reg_addr, reg_bit_map, vnic; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci /* update parameters for 4port mode */ 2188c2ecf20Sopenharmony_ci if (INIT_MODE_FLAGS(bp) & MODE_PORT4) { 2198c2ecf20Sopenharmony_ci num_vnics = BNX2X_PORT4_MODE_NUM_VNICS; 2208c2ecf20Sopenharmony_ci if (BP_PORT(bp)) { 2218c2ecf20Sopenharmony_ci curr_cos += BNX2X_E3B0_PORT1_COS_OFFSET; 2228c2ecf20Sopenharmony_ci new_cos += BNX2X_E3B0_PORT1_COS_OFFSET; 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci } 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci /* change queue mapping for each VNIC */ 2278c2ecf20Sopenharmony_ci for (vnic = 0; vnic < num_vnics; vnic++) { 2288c2ecf20Sopenharmony_ci u32 pf_q_num = 2298c2ecf20Sopenharmony_ci BNX2X_PF_Q_NUM(q_num, BP_PORT(bp), vnic); 2308c2ecf20Sopenharmony_ci u32 q_bit_map = 1 << (pf_q_num & 0x1f); 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci /* overwrite queue->VOQ mapping */ 2338c2ecf20Sopenharmony_ci REG_WR(bp, BNX2X_Q_VOQ_REG_ADDR(pf_q_num), new_cos); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci /* clear queue bit from current COS bit map */ 2368c2ecf20Sopenharmony_ci reg_addr = BNX2X_VOQ_Q_REG_ADDR(curr_cos, pf_q_num); 2378c2ecf20Sopenharmony_ci reg_bit_map = REG_RD(bp, reg_addr); 2388c2ecf20Sopenharmony_ci REG_WR(bp, reg_addr, reg_bit_map & (~q_bit_map)); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci /* set queue bit in new COS bit map */ 2418c2ecf20Sopenharmony_ci reg_addr = BNX2X_VOQ_Q_REG_ADDR(new_cos, pf_q_num); 2428c2ecf20Sopenharmony_ci reg_bit_map = REG_RD(bp, reg_addr); 2438c2ecf20Sopenharmony_ci REG_WR(bp, reg_addr, reg_bit_map | q_bit_map); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci /* set/clear queue bit in command-queue bit map 2468c2ecf20Sopenharmony_ci * (E2/E3A0 only, valid COS values are 0/1) 2478c2ecf20Sopenharmony_ci */ 2488c2ecf20Sopenharmony_ci if (!(INIT_MODE_FLAGS(bp) & MODE_E3_B0)) { 2498c2ecf20Sopenharmony_ci reg_addr = BNX2X_Q_CMDQ_REG_ADDR(pf_q_num); 2508c2ecf20Sopenharmony_ci reg_bit_map = REG_RD(bp, reg_addr); 2518c2ecf20Sopenharmony_ci q_bit_map = 1 << (2 * (pf_q_num & 0xf)); 2528c2ecf20Sopenharmony_ci reg_bit_map = new_cos ? 2538c2ecf20Sopenharmony_ci (reg_bit_map | q_bit_map) : 2548c2ecf20Sopenharmony_ci (reg_bit_map & (~q_bit_map)); 2558c2ecf20Sopenharmony_ci REG_WR(bp, reg_addr, reg_bit_map); 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci } 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci} 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci/* Configures the QM according to the specified per-traffic-type COSes */ 2628c2ecf20Sopenharmony_cistatic inline void bnx2x_dcb_config_qm(struct bnx2x *bp, enum cos_mode mode, 2638c2ecf20Sopenharmony_ci struct priority_cos *traffic_cos) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci bnx2x_map_q_cos(bp, BNX2X_FCOE_Q, 2668c2ecf20Sopenharmony_ci traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos); 2678c2ecf20Sopenharmony_ci bnx2x_map_q_cos(bp, BNX2X_ISCSI_Q, 2688c2ecf20Sopenharmony_ci traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); 2698c2ecf20Sopenharmony_ci bnx2x_map_q_cos(bp, BNX2X_ISCSI_ACK_Q, 2708c2ecf20Sopenharmony_ci traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); 2718c2ecf20Sopenharmony_ci if (mode != STATIC_COS) { 2728c2ecf20Sopenharmony_ci /* required only in backward compatible COS mode */ 2738c2ecf20Sopenharmony_ci bnx2x_map_q_cos(bp, BNX2X_ETH_Q, 2748c2ecf20Sopenharmony_ci traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); 2758c2ecf20Sopenharmony_ci bnx2x_map_q_cos(bp, BNX2X_TOE_Q, 2768c2ecf20Sopenharmony_ci traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); 2778c2ecf20Sopenharmony_ci bnx2x_map_q_cos(bp, BNX2X_TOE_ACK_Q, 2788c2ecf20Sopenharmony_ci traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci/* congestion management port init api description 2848c2ecf20Sopenharmony_ci * the api works as follows: 2858c2ecf20Sopenharmony_ci * the driver should pass the cmng_init_input struct, the port_init function 2868c2ecf20Sopenharmony_ci * will prepare the required internal ram structure which will be passed back 2878c2ecf20Sopenharmony_ci * to the driver (cmng_init) that will write it into the internal ram. 2888c2ecf20Sopenharmony_ci * 2898c2ecf20Sopenharmony_ci * IMPORTANT REMARKS: 2908c2ecf20Sopenharmony_ci * 1. the cmng_init struct does not represent the contiguous internal ram 2918c2ecf20Sopenharmony_ci * structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET 2928c2ecf20Sopenharmony_ci * offset in order to write the port sub struct and the 2938c2ecf20Sopenharmony_ci * PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other 2948c2ecf20Sopenharmony_ci * words - don't use memcpy!). 2958c2ecf20Sopenharmony_ci * 2. although the cmng_init struct is filled for the maximal vnic number 2968c2ecf20Sopenharmony_ci * possible, the driver should only write the valid vnics into the internal 2978c2ecf20Sopenharmony_ci * ram according to the appropriate port mode. 2988c2ecf20Sopenharmony_ci */ 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci/* CMNG constants, as derived from system spec calculations */ 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */ 3038c2ecf20Sopenharmony_ci#define DEF_MIN_RATE 100 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci/* resolution of the rate shaping timer - 400 usec */ 3068c2ecf20Sopenharmony_ci#define RS_PERIODIC_TIMEOUT_USEC 400 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci/* number of bytes in single QM arbitration cycle - 3098c2ecf20Sopenharmony_ci * coefficient for calculating the fairness timer 3108c2ecf20Sopenharmony_ci */ 3118c2ecf20Sopenharmony_ci#define QM_ARB_BYTES 160000 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci/* resolution of Min algorithm 1:100 */ 3148c2ecf20Sopenharmony_ci#define MIN_RES 100 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci/* how many bytes above threshold for 3178c2ecf20Sopenharmony_ci * the minimal credit of Min algorithm 3188c2ecf20Sopenharmony_ci */ 3198c2ecf20Sopenharmony_ci#define MIN_ABOVE_THRESH 32768 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* Fairness algorithm integration time coefficient - 3228c2ecf20Sopenharmony_ci * for calculating the actual Tfair 3238c2ecf20Sopenharmony_ci */ 3248c2ecf20Sopenharmony_ci#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES) 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci/* Memory of fairness algorithm - 2 cycles */ 3278c2ecf20Sopenharmony_ci#define FAIR_MEM 2 3288c2ecf20Sopenharmony_ci#define SAFC_TIMEOUT_USEC 52 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci#define SDM_TICKS 4 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_cistatic inline void bnx2x_init_max(const struct cmng_init_input *input_data, 3348c2ecf20Sopenharmony_ci u32 r_param, struct cmng_init *ram_data) 3358c2ecf20Sopenharmony_ci{ 3368c2ecf20Sopenharmony_ci u32 vnic; 3378c2ecf20Sopenharmony_ci struct cmng_vnic *vdata = &ram_data->vnic; 3388c2ecf20Sopenharmony_ci struct cmng_struct_per_port *pdata = &ram_data->port; 3398c2ecf20Sopenharmony_ci /* rate shaping per-port variables 3408c2ecf20Sopenharmony_ci * 100 micro seconds in SDM ticks = 25 3418c2ecf20Sopenharmony_ci * since each tick is 4 microSeconds 3428c2ecf20Sopenharmony_ci */ 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci pdata->rs_vars.rs_periodic_timeout = 3458c2ecf20Sopenharmony_ci RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci /* this is the threshold below which no timer arming will occur. 3488c2ecf20Sopenharmony_ci * 1.25 coefficient is for the threshold to be a little bigger 3498c2ecf20Sopenharmony_ci * then the real time to compensate for timer in-accuracy 3508c2ecf20Sopenharmony_ci */ 3518c2ecf20Sopenharmony_ci pdata->rs_vars.rs_threshold = 3528c2ecf20Sopenharmony_ci (5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci /* rate shaping per-vnic variables */ 3558c2ecf20Sopenharmony_ci for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) { 3568c2ecf20Sopenharmony_ci /* global vnic counter */ 3578c2ecf20Sopenharmony_ci vdata->vnic_max_rate[vnic].vn_counter.rate = 3588c2ecf20Sopenharmony_ci input_data->vnic_max_rate[vnic]; 3598c2ecf20Sopenharmony_ci /* maximal Mbps for this vnic 3608c2ecf20Sopenharmony_ci * the quota in each timer period - number of bytes 3618c2ecf20Sopenharmony_ci * transmitted in this period 3628c2ecf20Sopenharmony_ci */ 3638c2ecf20Sopenharmony_ci vdata->vnic_max_rate[vnic].vn_counter.quota = 3648c2ecf20Sopenharmony_ci RS_PERIODIC_TIMEOUT_USEC * 3658c2ecf20Sopenharmony_ci (u32)vdata->vnic_max_rate[vnic].vn_counter.rate / 8; 3668c2ecf20Sopenharmony_ci } 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic inline void bnx2x_init_min(const struct cmng_init_input *input_data, 3718c2ecf20Sopenharmony_ci u32 r_param, struct cmng_init *ram_data) 3728c2ecf20Sopenharmony_ci{ 3738c2ecf20Sopenharmony_ci u32 vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair; 3748c2ecf20Sopenharmony_ci struct cmng_vnic *vdata = &ram_data->vnic; 3758c2ecf20Sopenharmony_ci struct cmng_struct_per_port *pdata = &ram_data->port; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci /* this is the resolution of the fairness timer */ 3788c2ecf20Sopenharmony_ci fair_periodic_timeout_usec = QM_ARB_BYTES / r_param; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci /* fairness per-port variables 3818c2ecf20Sopenharmony_ci * for 10G it is 1000usec. for 1G it is 10000usec. 3828c2ecf20Sopenharmony_ci */ 3838c2ecf20Sopenharmony_ci tFair = T_FAIR_COEF / input_data->port_rate; 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci /* this is the threshold below which we won't arm the timer anymore */ 3868c2ecf20Sopenharmony_ci pdata->fair_vars.fair_threshold = QM_ARB_BYTES; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci /* we multiply by 1e3/8 to get bytes/msec. We don't want the credits 3898c2ecf20Sopenharmony_ci * to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution) 3908c2ecf20Sopenharmony_ci */ 3918c2ecf20Sopenharmony_ci pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* since each tick is 4 microSeconds */ 3948c2ecf20Sopenharmony_ci pdata->fair_vars.fairness_timeout = 3958c2ecf20Sopenharmony_ci fair_periodic_timeout_usec / SDM_TICKS; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci /* calculate sum of weights */ 3988c2ecf20Sopenharmony_ci vnicWeightSum = 0; 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) 4018c2ecf20Sopenharmony_ci vnicWeightSum += input_data->vnic_min_rate[vnic]; 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci /* global vnic counter */ 4048c2ecf20Sopenharmony_ci if (vnicWeightSum > 0) { 4058c2ecf20Sopenharmony_ci /* fairness per-vnic variables */ 4068c2ecf20Sopenharmony_ci for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) { 4078c2ecf20Sopenharmony_ci /* this is the credit for each period of the fairness 4088c2ecf20Sopenharmony_ci * algorithm - number of bytes in T_FAIR (this vnic 4098c2ecf20Sopenharmony_ci * share of the port rate) 4108c2ecf20Sopenharmony_ci */ 4118c2ecf20Sopenharmony_ci vdata->vnic_min_rate[vnic].vn_credit_delta = 4128c2ecf20Sopenharmony_ci (u32)input_data->vnic_min_rate[vnic] * 100 * 4138c2ecf20Sopenharmony_ci (T_FAIR_COEF / (8 * 100 * vnicWeightSum)); 4148c2ecf20Sopenharmony_ci if (vdata->vnic_min_rate[vnic].vn_credit_delta < 4158c2ecf20Sopenharmony_ci pdata->fair_vars.fair_threshold + 4168c2ecf20Sopenharmony_ci MIN_ABOVE_THRESH) { 4178c2ecf20Sopenharmony_ci vdata->vnic_min_rate[vnic].vn_credit_delta = 4188c2ecf20Sopenharmony_ci pdata->fair_vars.fair_threshold + 4198c2ecf20Sopenharmony_ci MIN_ABOVE_THRESH; 4208c2ecf20Sopenharmony_ci } 4218c2ecf20Sopenharmony_ci } 4228c2ecf20Sopenharmony_ci } 4238c2ecf20Sopenharmony_ci} 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_cistatic inline void bnx2x_init_fw_wrr(const struct cmng_init_input *input_data, 4268c2ecf20Sopenharmony_ci u32 r_param, struct cmng_init *ram_data) 4278c2ecf20Sopenharmony_ci{ 4288c2ecf20Sopenharmony_ci u32 vnic, cos; 4298c2ecf20Sopenharmony_ci u32 cosWeightSum = 0; 4308c2ecf20Sopenharmony_ci struct cmng_vnic *vdata = &ram_data->vnic; 4318c2ecf20Sopenharmony_ci struct cmng_struct_per_port *pdata = &ram_data->port; 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci for (cos = 0; cos < MAX_COS_NUMBER; cos++) 4348c2ecf20Sopenharmony_ci cosWeightSum += input_data->cos_min_rate[cos]; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci if (cosWeightSum > 0) { 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci for (vnic = 0; vnic < BNX2X_PORT2_MODE_NUM_VNICS; vnic++) { 4398c2ecf20Sopenharmony_ci /* Since cos and vnic shouldn't work together the rate 4408c2ecf20Sopenharmony_ci * to divide between the coses is the port rate. 4418c2ecf20Sopenharmony_ci */ 4428c2ecf20Sopenharmony_ci u32 *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta; 4438c2ecf20Sopenharmony_ci for (cos = 0; cos < MAX_COS_NUMBER; cos++) { 4448c2ecf20Sopenharmony_ci /* this is the credit for each period of 4458c2ecf20Sopenharmony_ci * the fairness algorithm - number of bytes 4468c2ecf20Sopenharmony_ci * in T_FAIR (this cos share of the vnic rate) 4478c2ecf20Sopenharmony_ci */ 4488c2ecf20Sopenharmony_ci ccd[cos] = 4498c2ecf20Sopenharmony_ci (u32)input_data->cos_min_rate[cos] * 100 * 4508c2ecf20Sopenharmony_ci (T_FAIR_COEF / (8 * 100 * cosWeightSum)); 4518c2ecf20Sopenharmony_ci if (ccd[cos] < pdata->fair_vars.fair_threshold 4528c2ecf20Sopenharmony_ci + MIN_ABOVE_THRESH) { 4538c2ecf20Sopenharmony_ci ccd[cos] = 4548c2ecf20Sopenharmony_ci pdata->fair_vars.fair_threshold + 4558c2ecf20Sopenharmony_ci MIN_ABOVE_THRESH; 4568c2ecf20Sopenharmony_ci } 4578c2ecf20Sopenharmony_ci } 4588c2ecf20Sopenharmony_ci } 4598c2ecf20Sopenharmony_ci } 4608c2ecf20Sopenharmony_ci} 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistatic inline void bnx2x_init_safc(const struct cmng_init_input *input_data, 4638c2ecf20Sopenharmony_ci struct cmng_init *ram_data) 4648c2ecf20Sopenharmony_ci{ 4658c2ecf20Sopenharmony_ci /* in microSeconds */ 4668c2ecf20Sopenharmony_ci ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC; 4678c2ecf20Sopenharmony_ci} 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci/* Congestion management port init */ 4708c2ecf20Sopenharmony_cistatic inline void bnx2x_init_cmng(const struct cmng_init_input *input_data, 4718c2ecf20Sopenharmony_ci struct cmng_init *ram_data) 4728c2ecf20Sopenharmony_ci{ 4738c2ecf20Sopenharmony_ci u32 r_param; 4748c2ecf20Sopenharmony_ci memset(ram_data, 0, sizeof(struct cmng_init)); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci ram_data->port.flags = input_data->flags; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* number of bytes transmitted in a rate of 10Gbps 4798c2ecf20Sopenharmony_ci * in one usec = 1.25KB. 4808c2ecf20Sopenharmony_ci */ 4818c2ecf20Sopenharmony_ci r_param = BITS_TO_BYTES(input_data->port_rate); 4828c2ecf20Sopenharmony_ci bnx2x_init_max(input_data, r_param, ram_data); 4838c2ecf20Sopenharmony_ci bnx2x_init_min(input_data, r_param, ram_data); 4848c2ecf20Sopenharmony_ci bnx2x_init_fw_wrr(input_data, r_param, ram_data); 4858c2ecf20Sopenharmony_ci bnx2x_init_safc(input_data, ram_data); 4868c2ecf20Sopenharmony_ci} 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci/* Returns the index of start or end of a specific block stage in ops array */ 4918c2ecf20Sopenharmony_ci#define BLOCK_OPS_IDX(block, stage, end) \ 4928c2ecf20Sopenharmony_ci (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end)) 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci#define INITOP_SET 0 /* set the HW directly */ 4968c2ecf20Sopenharmony_ci#define INITOP_CLEAR 1 /* clear the HW directly */ 4978c2ecf20Sopenharmony_ci#define INITOP_INIT 2 /* set the init-value array */ 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci/**************************************************************************** 5008c2ecf20Sopenharmony_ci* ILT management 5018c2ecf20Sopenharmony_ci****************************************************************************/ 5028c2ecf20Sopenharmony_cistruct ilt_line { 5038c2ecf20Sopenharmony_ci dma_addr_t page_mapping; 5048c2ecf20Sopenharmony_ci void *page; 5058c2ecf20Sopenharmony_ci u32 size; 5068c2ecf20Sopenharmony_ci}; 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_cistruct ilt_client_info { 5098c2ecf20Sopenharmony_ci u32 page_size; 5108c2ecf20Sopenharmony_ci u16 start; 5118c2ecf20Sopenharmony_ci u16 end; 5128c2ecf20Sopenharmony_ci u16 client_num; 5138c2ecf20Sopenharmony_ci u16 flags; 5148c2ecf20Sopenharmony_ci#define ILT_CLIENT_SKIP_INIT 0x1 5158c2ecf20Sopenharmony_ci#define ILT_CLIENT_SKIP_MEM 0x2 5168c2ecf20Sopenharmony_ci}; 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_cistruct bnx2x_ilt { 5198c2ecf20Sopenharmony_ci u32 start_line; 5208c2ecf20Sopenharmony_ci struct ilt_line *lines; 5218c2ecf20Sopenharmony_ci struct ilt_client_info clients[4]; 5228c2ecf20Sopenharmony_ci#define ILT_CLIENT_CDU 0 5238c2ecf20Sopenharmony_ci#define ILT_CLIENT_QM 1 5248c2ecf20Sopenharmony_ci#define ILT_CLIENT_SRC 2 5258c2ecf20Sopenharmony_ci#define ILT_CLIENT_TM 3 5268c2ecf20Sopenharmony_ci}; 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci/**************************************************************************** 5298c2ecf20Sopenharmony_ci* SRC configuration 5308c2ecf20Sopenharmony_ci****************************************************************************/ 5318c2ecf20Sopenharmony_cistruct src_ent { 5328c2ecf20Sopenharmony_ci u8 opaque[56]; 5338c2ecf20Sopenharmony_ci u64 next; 5348c2ecf20Sopenharmony_ci}; 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci/**************************************************************************** 5378c2ecf20Sopenharmony_ci* Parity configuration 5388c2ecf20Sopenharmony_ci****************************************************************************/ 5398c2ecf20Sopenharmony_ci#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \ 5408c2ecf20Sopenharmony_ci{ \ 5418c2ecf20Sopenharmony_ci block##_REG_##block##_PRTY_MASK, \ 5428c2ecf20Sopenharmony_ci block##_REG_##block##_PRTY_STS_CLR, \ 5438c2ecf20Sopenharmony_ci en_mask, {m1, m1h, m2, m3}, #block \ 5448c2ecf20Sopenharmony_ci} 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \ 5478c2ecf20Sopenharmony_ci{ \ 5488c2ecf20Sopenharmony_ci block##_REG_##block##_PRTY_MASK_0, \ 5498c2ecf20Sopenharmony_ci block##_REG_##block##_PRTY_STS_CLR_0, \ 5508c2ecf20Sopenharmony_ci en_mask, {m1, m1h, m2, m3}, #block"_0" \ 5518c2ecf20Sopenharmony_ci} 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \ 5548c2ecf20Sopenharmony_ci{ \ 5558c2ecf20Sopenharmony_ci block##_REG_##block##_PRTY_MASK_1, \ 5568c2ecf20Sopenharmony_ci block##_REG_##block##_PRTY_STS_CLR_1, \ 5578c2ecf20Sopenharmony_ci en_mask, {m1, m1h, m2, m3}, #block"_1" \ 5588c2ecf20Sopenharmony_ci} 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_cistatic const struct { 5618c2ecf20Sopenharmony_ci u32 mask_addr; 5628c2ecf20Sopenharmony_ci u32 sts_clr_addr; 5638c2ecf20Sopenharmony_ci u32 en_mask; /* Mask to enable parity attentions */ 5648c2ecf20Sopenharmony_ci struct { 5658c2ecf20Sopenharmony_ci u32 e1; /* 57710 */ 5668c2ecf20Sopenharmony_ci u32 e1h; /* 57711 */ 5678c2ecf20Sopenharmony_ci u32 e2; /* 57712 */ 5688c2ecf20Sopenharmony_ci u32 e3; /* 578xx */ 5698c2ecf20Sopenharmony_ci } reg_mask; /* Register mask (all valid bits) */ 5708c2ecf20Sopenharmony_ci char name[8]; /* Block's longest name is 7 characters long 5718c2ecf20Sopenharmony_ci * (name + suffix) 5728c2ecf20Sopenharmony_ci */ 5738c2ecf20Sopenharmony_ci} bnx2x_blocks_parity_data[] = { 5748c2ecf20Sopenharmony_ci /* bit 19 masked */ 5758c2ecf20Sopenharmony_ci /* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */ 5768c2ecf20Sopenharmony_ci /* bit 5,18,20-31 */ 5778c2ecf20Sopenharmony_ci /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */ 5788c2ecf20Sopenharmony_ci /* bit 5 */ 5798c2ecf20Sopenharmony_ci /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20); */ 5808c2ecf20Sopenharmony_ci /* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */ 5818c2ecf20Sopenharmony_ci /* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */ 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't 5848c2ecf20Sopenharmony_ci * want to handle "system kill" flow at the moment. 5858c2ecf20Sopenharmony_ci */ 5868c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff, 5878c2ecf20Sopenharmony_ci 0x7ffffff), 5888c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 5898c2ecf20Sopenharmony_ci 0xffffffff), 5908c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_1(PXP2, 0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff), 5918c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0), 5928c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0), 5938c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff, 0xffffffff), 5948c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xff, 0xffff), 5958c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff), 5968c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1), 5978c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff), 5988c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f), 5998c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3), 6008c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3), 6018c2ecf20Sopenharmony_ci {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 6028c2ecf20Sopenharmony_ci GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf, 6038c2ecf20Sopenharmony_ci {0xf, 0xf, 0xf, 0xf}, "UPB"}, 6048c2ecf20Sopenharmony_ci {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 6058c2ecf20Sopenharmony_ci GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0, 6068c2ecf20Sopenharmony_ci {0xf, 0xf, 0xf, 0xf}, "XPB"}, 6078c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7), 6088c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f), 6098c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f), 6108c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1), 6118c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf), 6128c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf), 6138c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff, 0xff), 6148c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff), 6158c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f), 6168c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 6178c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 6188c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 6198c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 6208c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), 6218c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), 6228c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), 6238c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff), 6248c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 6258c2ecf20Sopenharmony_ci 0xffffffff), 6268c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), 6278c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 6288c2ecf20Sopenharmony_ci 0xffffffff), 6298c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f), 6308c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 6318c2ecf20Sopenharmony_ci 0xffffffff), 6328c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f), 6338c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 6348c2ecf20Sopenharmony_ci 0xffffffff), 6358c2ecf20Sopenharmony_ci BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), 6368c2ecf20Sopenharmony_ci}; 6378c2ecf20Sopenharmony_ci 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci/* [28] MCP Latched rom_parity 6408c2ecf20Sopenharmony_ci * [29] MCP Latched ump_rx_parity 6418c2ecf20Sopenharmony_ci * [30] MCP Latched ump_tx_parity 6428c2ecf20Sopenharmony_ci * [31] MCP Latched scpad_parity 6438c2ecf20Sopenharmony_ci */ 6448c2ecf20Sopenharmony_ci#define MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS \ 6458c2ecf20Sopenharmony_ci (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \ 6468c2ecf20Sopenharmony_ci AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \ 6478c2ecf20Sopenharmony_ci AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY) 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci#define MISC_AEU_ENABLE_MCP_PRTY_BITS \ 6508c2ecf20Sopenharmony_ci (MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS | \ 6518c2ecf20Sopenharmony_ci AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY) 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci/* Below registers control the MCP parity attention output. When 6548c2ecf20Sopenharmony_ci * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are 6558c2ecf20Sopenharmony_ci * enabled, when cleared - disabled. 6568c2ecf20Sopenharmony_ci */ 6578c2ecf20Sopenharmony_cistatic const struct { 6588c2ecf20Sopenharmony_ci u32 addr; 6598c2ecf20Sopenharmony_ci u32 bits; 6608c2ecf20Sopenharmony_ci} mcp_attn_ctl_regs[] = { 6618c2ecf20Sopenharmony_ci { MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 6628c2ecf20Sopenharmony_ci MISC_AEU_ENABLE_MCP_PRTY_BITS }, 6638c2ecf20Sopenharmony_ci { MISC_REG_AEU_ENABLE4_NIG_0, 6648c2ecf20Sopenharmony_ci MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }, 6658c2ecf20Sopenharmony_ci { MISC_REG_AEU_ENABLE4_PXP_0, 6668c2ecf20Sopenharmony_ci MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }, 6678c2ecf20Sopenharmony_ci { MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 6688c2ecf20Sopenharmony_ci MISC_AEU_ENABLE_MCP_PRTY_BITS }, 6698c2ecf20Sopenharmony_ci { MISC_REG_AEU_ENABLE4_NIG_1, 6708c2ecf20Sopenharmony_ci MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }, 6718c2ecf20Sopenharmony_ci { MISC_REG_AEU_ENABLE4_PXP_1, 6728c2ecf20Sopenharmony_ci MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS } 6738c2ecf20Sopenharmony_ci}; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_cistatic inline void bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable) 6768c2ecf20Sopenharmony_ci{ 6778c2ecf20Sopenharmony_ci int i; 6788c2ecf20Sopenharmony_ci u32 reg_val; 6798c2ecf20Sopenharmony_ci 6808c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) { 6818c2ecf20Sopenharmony_ci reg_val = REG_RD(bp, mcp_attn_ctl_regs[i].addr); 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci if (enable) 6848c2ecf20Sopenharmony_ci reg_val |= mcp_attn_ctl_regs[i].bits; 6858c2ecf20Sopenharmony_ci else 6868c2ecf20Sopenharmony_ci reg_val &= ~mcp_attn_ctl_regs[i].bits; 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci REG_WR(bp, mcp_attn_ctl_regs[i].addr, reg_val); 6898c2ecf20Sopenharmony_ci } 6908c2ecf20Sopenharmony_ci} 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_cistatic inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx) 6938c2ecf20Sopenharmony_ci{ 6948c2ecf20Sopenharmony_ci if (CHIP_IS_E1(bp)) 6958c2ecf20Sopenharmony_ci return bnx2x_blocks_parity_data[idx].reg_mask.e1; 6968c2ecf20Sopenharmony_ci else if (CHIP_IS_E1H(bp)) 6978c2ecf20Sopenharmony_ci return bnx2x_blocks_parity_data[idx].reg_mask.e1h; 6988c2ecf20Sopenharmony_ci else if (CHIP_IS_E2(bp)) 6998c2ecf20Sopenharmony_ci return bnx2x_blocks_parity_data[idx].reg_mask.e2; 7008c2ecf20Sopenharmony_ci else /* CHIP_IS_E3 */ 7018c2ecf20Sopenharmony_ci return bnx2x_blocks_parity_data[idx].reg_mask.e3; 7028c2ecf20Sopenharmony_ci} 7038c2ecf20Sopenharmony_ci 7048c2ecf20Sopenharmony_cistatic inline void bnx2x_disable_blocks_parity(struct bnx2x *bp) 7058c2ecf20Sopenharmony_ci{ 7068c2ecf20Sopenharmony_ci int i; 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) { 7098c2ecf20Sopenharmony_ci u32 dis_mask = bnx2x_parity_reg_mask(bp, i); 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci if (dis_mask) { 7128c2ecf20Sopenharmony_ci REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr, 7138c2ecf20Sopenharmony_ci dis_mask); 7148c2ecf20Sopenharmony_ci DP(NETIF_MSG_HW, "Setting parity mask " 7158c2ecf20Sopenharmony_ci "for %s to\t\t0x%x\n", 7168c2ecf20Sopenharmony_ci bnx2x_blocks_parity_data[i].name, dis_mask); 7178c2ecf20Sopenharmony_ci } 7188c2ecf20Sopenharmony_ci } 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci /* Disable MCP parity attentions */ 7218c2ecf20Sopenharmony_ci bnx2x_set_mcp_parity(bp, false); 7228c2ecf20Sopenharmony_ci} 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci/* Clear the parity error status registers. */ 7258c2ecf20Sopenharmony_cistatic inline void bnx2x_clear_blocks_parity(struct bnx2x *bp) 7268c2ecf20Sopenharmony_ci{ 7278c2ecf20Sopenharmony_ci int i; 7288c2ecf20Sopenharmony_ci u32 reg_val, mcp_aeu_bits = 7298c2ecf20Sopenharmony_ci AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | 7308c2ecf20Sopenharmony_ci AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY | 7318c2ecf20Sopenharmony_ci AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | 7328c2ecf20Sopenharmony_ci AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci /* Clear SEM_FAST parities */ 7358c2ecf20Sopenharmony_ci REG_WR(bp, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 7368c2ecf20Sopenharmony_ci REG_WR(bp, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 7378c2ecf20Sopenharmony_ci REG_WR(bp, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 7388c2ecf20Sopenharmony_ci REG_WR(bp, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 7398c2ecf20Sopenharmony_ci 7408c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) { 7418c2ecf20Sopenharmony_ci u32 reg_mask = bnx2x_parity_reg_mask(bp, i); 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci if (reg_mask) { 7448c2ecf20Sopenharmony_ci reg_val = REG_RD(bp, bnx2x_blocks_parity_data[i]. 7458c2ecf20Sopenharmony_ci sts_clr_addr); 7468c2ecf20Sopenharmony_ci if (reg_val & reg_mask) 7478c2ecf20Sopenharmony_ci DP(NETIF_MSG_HW, 7488c2ecf20Sopenharmony_ci "Parity errors in %s: 0x%x\n", 7498c2ecf20Sopenharmony_ci bnx2x_blocks_parity_data[i].name, 7508c2ecf20Sopenharmony_ci reg_val & reg_mask); 7518c2ecf20Sopenharmony_ci } 7528c2ecf20Sopenharmony_ci } 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci /* Check if there were parity attentions in MCP */ 7558c2ecf20Sopenharmony_ci reg_val = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_MCP); 7568c2ecf20Sopenharmony_ci if (reg_val & mcp_aeu_bits) 7578c2ecf20Sopenharmony_ci DP(NETIF_MSG_HW, "Parity error in MCP: 0x%x\n", 7588c2ecf20Sopenharmony_ci reg_val & mcp_aeu_bits); 7598c2ecf20Sopenharmony_ci 7608c2ecf20Sopenharmony_ci /* Clear parity attentions in MCP: 7618c2ecf20Sopenharmony_ci * [7] clears Latched rom_parity 7628c2ecf20Sopenharmony_ci * [8] clears Latched ump_rx_parity 7638c2ecf20Sopenharmony_ci * [9] clears Latched ump_tx_parity 7648c2ecf20Sopenharmony_ci * [10] clears Latched scpad_parity (both ports) 7658c2ecf20Sopenharmony_ci */ 7668c2ecf20Sopenharmony_ci REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780); 7678c2ecf20Sopenharmony_ci} 7688c2ecf20Sopenharmony_ci 7698c2ecf20Sopenharmony_cistatic inline void bnx2x_enable_blocks_parity(struct bnx2x *bp) 7708c2ecf20Sopenharmony_ci{ 7718c2ecf20Sopenharmony_ci int i; 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) { 7748c2ecf20Sopenharmony_ci u32 reg_mask = bnx2x_parity_reg_mask(bp, i); 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci if (reg_mask) 7778c2ecf20Sopenharmony_ci REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr, 7788c2ecf20Sopenharmony_ci bnx2x_blocks_parity_data[i].en_mask & reg_mask); 7798c2ecf20Sopenharmony_ci } 7808c2ecf20Sopenharmony_ci 7818c2ecf20Sopenharmony_ci /* Enable MCP parity attentions */ 7828c2ecf20Sopenharmony_ci bnx2x_set_mcp_parity(bp, true); 7838c2ecf20Sopenharmony_ci} 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci 7868c2ecf20Sopenharmony_ci#endif /* BNX2X_INIT_H */ 7878c2ecf20Sopenharmony_ci 788