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