1255736Sdavidch/*- 2265797Sdavidcs * Copyright (c) 2007-2014 QLogic Corporation. All rights reserved. 3255736Sdavidch * 4255736Sdavidch * Redistribution and use in source and binary forms, with or without 5255736Sdavidch * modification, are permitted provided that the following conditions 6255736Sdavidch * are met: 7255736Sdavidch * 8255736Sdavidch * 1. Redistributions of source code must retain the above copyright 9255736Sdavidch * notice, this list of conditions and the following disclaimer. 10255736Sdavidch * 2. Redistributions in binary form must reproduce the above copyright 11255736Sdavidch * notice, this list of conditions and the following disclaimer in the 12255736Sdavidch * documentation and/or other materials provided with the distribution. 13255736Sdavidch * 14255736Sdavidch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' 15255736Sdavidch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16255736Sdavidch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17255736Sdavidch * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 18255736Sdavidch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19255736Sdavidch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20255736Sdavidch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21255736Sdavidch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22255736Sdavidch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23255736Sdavidch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 24255736Sdavidch * THE POSSIBILITY OF SUCH DAMAGE. 25255736Sdavidch */ 26255736Sdavidch 27255736Sdavidch#include <sys/cdefs.h> 28255736Sdavidch__FBSDID("$FreeBSD: releng/10.3/sys/dev/bxe/ecore_init.h 296069 2016-02-25 22:07:32Z davidcs $"); 29255736Sdavidch 30255736Sdavidch#ifndef ECORE_INIT_H 31255736Sdavidch#define ECORE_INIT_H 32255736Sdavidch 33255736Sdavidch/* Init operation types and structures */ 34255736Sdavidchenum { 35255736Sdavidch OP_RD = 0x1, /* read a single register */ 36255736Sdavidch OP_WR, /* write a single register */ 37255736Sdavidch OP_SW, /* copy a string to the device */ 38255736Sdavidch OP_ZR, /* clear memory */ 39255736Sdavidch OP_ZP, /* unzip then copy with DMAE */ 40255736Sdavidch OP_WR_64, /* write 64 bit pattern */ 41255736Sdavidch OP_WB, /* copy a string using DMAE */ 42255736Sdavidch#ifndef FW_ZIP_SUPPORT 43255736Sdavidch OP_FW, /* copy an array from fw data (only used with unzipped FW) */ 44255736Sdavidch#endif 45255736Sdavidch OP_WB_ZR, /* Clear a string using DMAE or indirect-wr */ 46255736Sdavidch OP_IF_MODE_OR, /* Skip the following ops if all init modes don't match */ 47255736Sdavidch OP_IF_MODE_AND, /* Skip the following ops if any init modes don't match */ 48255736Sdavidch OP_IF_PHASE, 49255736Sdavidch OP_RT, 50255736Sdavidch OP_DELAY, 51255736Sdavidch OP_VERIFY, 52255736Sdavidch OP_MAX 53255736Sdavidch}; 54255736Sdavidch 55255736Sdavidchenum { 56255736Sdavidch STAGE_START, 57255736Sdavidch STAGE_END, 58255736Sdavidch}; 59255736Sdavidch 60255736Sdavidch/* Returns the index of start or end of a specific block stage in ops array*/ 61255736Sdavidch#define BLOCK_OPS_IDX(block, stage, end) \ 62255736Sdavidch (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end)) 63255736Sdavidch 64255736Sdavidch 65255736Sdavidch/* structs for the various opcodes */ 66255736Sdavidchstruct raw_op { 67255736Sdavidch uint32_t op:8; 68255736Sdavidch uint32_t offset:24; 69255736Sdavidch uint32_t raw_data; 70255736Sdavidch}; 71255736Sdavidch 72255736Sdavidchstruct op_read { 73255736Sdavidch uint32_t op:8; 74255736Sdavidch uint32_t offset:24; 75255736Sdavidch uint32_t val; 76255736Sdavidch}; 77255736Sdavidch 78255736Sdavidchstruct op_write { 79255736Sdavidch uint32_t op:8; 80255736Sdavidch uint32_t offset:24; 81255736Sdavidch uint32_t val; 82255736Sdavidch}; 83255736Sdavidch 84255736Sdavidchstruct op_arr_write { 85255736Sdavidch uint32_t op:8; 86255736Sdavidch uint32_t offset:24; 87255736Sdavidch#ifdef __BIG_ENDIAN 88255736Sdavidch uint16_t data_len; 89255736Sdavidch uint16_t data_off; 90255736Sdavidch#else /* __LITTLE_ENDIAN */ 91255736Sdavidch uint16_t data_off; 92255736Sdavidch uint16_t data_len; 93255736Sdavidch#endif 94255736Sdavidch}; 95255736Sdavidch 96255736Sdavidchstruct op_zero { 97255736Sdavidch uint32_t op:8; 98255736Sdavidch uint32_t offset:24; 99255736Sdavidch uint32_t len; 100255736Sdavidch}; 101255736Sdavidch 102255736Sdavidchstruct op_if_mode { 103255736Sdavidch uint32_t op:8; 104255736Sdavidch uint32_t cmd_offset:24; 105255736Sdavidch uint32_t mode_bit_map; 106255736Sdavidch}; 107255736Sdavidch 108255736Sdavidchstruct op_if_phase { 109255736Sdavidch uint32_t op:8; 110255736Sdavidch uint32_t cmd_offset:24; 111255736Sdavidch uint32_t phase_bit_map; 112255736Sdavidch}; 113255736Sdavidch 114255736Sdavidchstruct op_delay { 115255736Sdavidch uint32_t op:8; 116255736Sdavidch uint32_t reserved:24; 117255736Sdavidch uint32_t delay; 118255736Sdavidch}; 119255736Sdavidch 120255736Sdavidchunion init_op { 121255736Sdavidch struct op_read read; 122255736Sdavidch struct op_write write; 123255736Sdavidch struct op_arr_write arr_wr; 124255736Sdavidch struct op_zero zero; 125255736Sdavidch struct raw_op raw; 126255736Sdavidch struct op_if_mode if_mode; 127255736Sdavidch struct op_if_phase if_phase; 128255736Sdavidch struct op_delay delay; 129255736Sdavidch}; 130255736Sdavidch 131255736Sdavidch 132255736Sdavidch/* Init Phases */ 133255736Sdavidchenum { 134255736Sdavidch PHASE_COMMON, 135255736Sdavidch PHASE_PORT0, 136255736Sdavidch PHASE_PORT1, 137255736Sdavidch PHASE_PF0, 138255736Sdavidch PHASE_PF1, 139255736Sdavidch PHASE_PF2, 140255736Sdavidch PHASE_PF3, 141255736Sdavidch PHASE_PF4, 142255736Sdavidch PHASE_PF5, 143255736Sdavidch PHASE_PF6, 144255736Sdavidch PHASE_PF7, 145255736Sdavidch NUM_OF_INIT_PHASES 146255736Sdavidch}; 147255736Sdavidch 148255736Sdavidch/* Init Modes */ 149255736Sdavidchenum { 150255736Sdavidch MODE_ASIC = 0x00000001, 151255736Sdavidch MODE_FPGA = 0x00000002, 152255736Sdavidch MODE_EMUL = 0x00000004, 153255736Sdavidch MODE_E2 = 0x00000008, 154255736Sdavidch MODE_E3 = 0x00000010, 155255736Sdavidch MODE_PORT2 = 0x00000020, 156255736Sdavidch MODE_PORT4 = 0x00000040, 157255736Sdavidch MODE_SF = 0x00000080, 158255736Sdavidch MODE_MF = 0x00000100, 159255736Sdavidch MODE_MF_SD = 0x00000200, 160255736Sdavidch MODE_MF_SI = 0x00000400, 161255736Sdavidch MODE_MF_AFEX = 0x00000800, 162255736Sdavidch MODE_E3_A0 = 0x00001000, 163255736Sdavidch MODE_E3_B0 = 0x00002000, 164255736Sdavidch MODE_COS3 = 0x00004000, 165255736Sdavidch MODE_COS6 = 0x00008000, 166255736Sdavidch MODE_LITTLE_ENDIAN = 0x00010000, 167255736Sdavidch MODE_BIG_ENDIAN = 0x00020000, 168255736Sdavidch}; 169255736Sdavidch 170255736Sdavidch/* Init Blocks */ 171255736Sdavidchenum { 172255736Sdavidch BLOCK_ATC, 173255736Sdavidch BLOCK_BRB1, 174255736Sdavidch BLOCK_CCM, 175255736Sdavidch BLOCK_CDU, 176255736Sdavidch BLOCK_CFC, 177255736Sdavidch BLOCK_CSDM, 178255736Sdavidch BLOCK_CSEM, 179255736Sdavidch BLOCK_DBG, 180255736Sdavidch BLOCK_DMAE, 181255736Sdavidch BLOCK_DORQ, 182255736Sdavidch BLOCK_HC, 183255736Sdavidch BLOCK_IGU, 184255736Sdavidch BLOCK_MISC, 185255736Sdavidch BLOCK_NIG, 186255736Sdavidch BLOCK_PBF, 187255736Sdavidch BLOCK_PGLUE_B, 188255736Sdavidch BLOCK_PRS, 189255736Sdavidch BLOCK_PXP2, 190255736Sdavidch BLOCK_PXP, 191255736Sdavidch BLOCK_QM, 192255736Sdavidch BLOCK_SRC, 193255736Sdavidch BLOCK_TCM, 194255736Sdavidch BLOCK_TM, 195255736Sdavidch BLOCK_TSDM, 196255736Sdavidch BLOCK_TSEM, 197255736Sdavidch BLOCK_UCM, 198255736Sdavidch BLOCK_UPB, 199255736Sdavidch BLOCK_USDM, 200255736Sdavidch BLOCK_USEM, 201255736Sdavidch BLOCK_XCM, 202255736Sdavidch BLOCK_XPB, 203255736Sdavidch BLOCK_XSDM, 204255736Sdavidch BLOCK_XSEM, 205255736Sdavidch BLOCK_MISC_AEU, 206255736Sdavidch NUM_OF_INIT_BLOCKS 207255736Sdavidch}; 208255736Sdavidch 209255736Sdavidch 210255736Sdavidch 211255736Sdavidch 212255736Sdavidch 213255736Sdavidch 214255736Sdavidch 215255736Sdavidch 216255736Sdavidch/* Vnics per mode */ 217255736Sdavidch#define ECORE_PORT2_MODE_NUM_VNICS 4 218255736Sdavidch 219255736Sdavidch 220255736Sdavidch/* QM queue numbers */ 221255736Sdavidch#define ECORE_ETH_Q 0 222255736Sdavidch#define ECORE_TOE_Q 3 223255736Sdavidch#define ECORE_TOE_ACK_Q 6 224255736Sdavidch#define ECORE_ISCSI_Q 9 225255736Sdavidch#define ECORE_ISCSI_ACK_Q 11 226255736Sdavidch#define ECORE_FCOE_Q 10 227255736Sdavidch 228255736Sdavidch/* Vnics per mode */ 229255736Sdavidch#define ECORE_PORT4_MODE_NUM_VNICS 2 230255736Sdavidch 231255736Sdavidch/* COS offset for port1 in E3 B0 4port mode */ 232255736Sdavidch#define ECORE_E3B0_PORT1_COS_OFFSET 3 233255736Sdavidch 234255736Sdavidch/* QM Register addresses */ 235255736Sdavidch#define ECORE_Q_VOQ_REG_ADDR(pf_q_num)\ 236255736Sdavidch (QM_REG_QVOQIDX_0 + 4 * (pf_q_num)) 237255736Sdavidch#define ECORE_VOQ_Q_REG_ADDR(cos, pf_q_num)\ 238255736Sdavidch (QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5))) 239255736Sdavidch#define ECORE_Q_CMDQ_REG_ADDR(pf_q_num)\ 240255736Sdavidch (QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4)) 241255736Sdavidch 242255736Sdavidch/* extracts the QM queue number for the specified port and vnic */ 243255736Sdavidch#define ECORE_PF_Q_NUM(q_num, port, vnic)\ 244255736Sdavidch ((((port) << 1) | (vnic)) * 16 + (q_num)) 245255736Sdavidch 246255736Sdavidch 247255736Sdavidch/* Maps the specified queue to the specified COS */ 248255736Sdavidchstatic inline void ecore_map_q_cos(struct bxe_softc *sc, uint32_t q_num, uint32_t new_cos) 249255736Sdavidch{ 250255736Sdavidch /* find current COS mapping */ 251255736Sdavidch uint32_t curr_cos = REG_RD(sc, QM_REG_QVOQIDX_0 + q_num * 4); 252255736Sdavidch 253255736Sdavidch /* check if queue->COS mapping has changed */ 254255736Sdavidch if (curr_cos != new_cos) { 255255736Sdavidch uint32_t num_vnics = ECORE_PORT2_MODE_NUM_VNICS; 256255736Sdavidch uint32_t reg_addr, reg_bit_map, vnic; 257255736Sdavidch 258255736Sdavidch /* update parameters for 4port mode */ 259255736Sdavidch if (INIT_MODE_FLAGS(sc) & MODE_PORT4) { 260255736Sdavidch num_vnics = ECORE_PORT4_MODE_NUM_VNICS; 261255736Sdavidch if (PORT_ID(sc)) { 262255736Sdavidch curr_cos += ECORE_E3B0_PORT1_COS_OFFSET; 263255736Sdavidch new_cos += ECORE_E3B0_PORT1_COS_OFFSET; 264255736Sdavidch } 265255736Sdavidch } 266255736Sdavidch 267255736Sdavidch /* change queue mapping for each VNIC */ 268255736Sdavidch for (vnic = 0; vnic < num_vnics; vnic++) { 269255736Sdavidch uint32_t pf_q_num = 270255736Sdavidch ECORE_PF_Q_NUM(q_num, PORT_ID(sc), vnic); 271255736Sdavidch uint32_t q_bit_map = 1 << (pf_q_num & 0x1f); 272255736Sdavidch 273255736Sdavidch /* overwrite queue->VOQ mapping */ 274255736Sdavidch REG_WR(sc, ECORE_Q_VOQ_REG_ADDR(pf_q_num), new_cos); 275255736Sdavidch 276255736Sdavidch /* clear queue bit from current COS bit map */ 277255736Sdavidch reg_addr = ECORE_VOQ_Q_REG_ADDR(curr_cos, pf_q_num); 278255736Sdavidch reg_bit_map = REG_RD(sc, reg_addr); 279255736Sdavidch REG_WR(sc, reg_addr, reg_bit_map & (~q_bit_map)); 280255736Sdavidch 281255736Sdavidch /* set queue bit in new COS bit map */ 282255736Sdavidch reg_addr = ECORE_VOQ_Q_REG_ADDR(new_cos, pf_q_num); 283255736Sdavidch reg_bit_map = REG_RD(sc, reg_addr); 284255736Sdavidch REG_WR(sc, reg_addr, reg_bit_map | q_bit_map); 285255736Sdavidch 286255736Sdavidch /* set/clear queue bit in command-queue bit map 287255736Sdavidch (E2/E3A0 only, valid COS values are 0/1) */ 288255736Sdavidch if (!(INIT_MODE_FLAGS(sc) & MODE_E3_B0)) { 289255736Sdavidch reg_addr = ECORE_Q_CMDQ_REG_ADDR(pf_q_num); 290255736Sdavidch reg_bit_map = REG_RD(sc, reg_addr); 291255736Sdavidch q_bit_map = 1 << (2 * (pf_q_num & 0xf)); 292255736Sdavidch reg_bit_map = new_cos ? 293255736Sdavidch (reg_bit_map | q_bit_map) : 294255736Sdavidch (reg_bit_map & (~q_bit_map)); 295255736Sdavidch REG_WR(sc, reg_addr, reg_bit_map); 296255736Sdavidch } 297255736Sdavidch } 298255736Sdavidch } 299255736Sdavidch} 300255736Sdavidch 301255736Sdavidch/* Configures the QM according to the specified per-traffic-type COSes */ 302255736Sdavidchstatic inline void ecore_dcb_config_qm(struct bxe_softc *sc, enum cos_mode mode, 303255736Sdavidch struct priority_cos *traffic_cos) 304255736Sdavidch{ 305255736Sdavidch ecore_map_q_cos(sc, ECORE_FCOE_Q, 306255736Sdavidch traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos); 307255736Sdavidch ecore_map_q_cos(sc, ECORE_ISCSI_Q, 308255736Sdavidch traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); 309255736Sdavidch ecore_map_q_cos(sc, ECORE_ISCSI_ACK_Q, 310255736Sdavidch traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos); 311255736Sdavidch if (mode != STATIC_COS) { 312255736Sdavidch /* required only in OVERRIDE_COS mode */ 313255736Sdavidch ecore_map_q_cos(sc, ECORE_ETH_Q, 314255736Sdavidch traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); 315255736Sdavidch ecore_map_q_cos(sc, ECORE_TOE_Q, 316255736Sdavidch traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); 317255736Sdavidch ecore_map_q_cos(sc, ECORE_TOE_ACK_Q, 318255736Sdavidch traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos); 319255736Sdavidch } 320255736Sdavidch} 321255736Sdavidch 322255736Sdavidch 323255736Sdavidch/* 324255736Sdavidch * congestion managment port init api description 325255736Sdavidch * the api works as follows: 326255736Sdavidch * the driver should pass the cmng_init_input struct, the port_init function 327255736Sdavidch * will prepare the required internal ram structure which will be passed back 328255736Sdavidch * to the driver (cmng_init) that will write it into the internal ram. 329255736Sdavidch * 330255736Sdavidch * IMPORTANT REMARKS: 331255736Sdavidch * 1. the cmng_init struct does not represent the contiguous internal ram 332255736Sdavidch * structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET 333255736Sdavidch * offset in order to write the port sub struct and the 334255736Sdavidch * PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other 335255736Sdavidch * words - don't use memcpy!). 336255736Sdavidch * 2. although the cmng_init struct is filled for the maximal vnic number 337255736Sdavidch * possible, the driver should only write the valid vnics into the internal 338255736Sdavidch * ram according to the appropriate port mode. 339255736Sdavidch */ 340255736Sdavidch#define BITS_TO_BYTES(x) ((x)/8) 341255736Sdavidch 342255736Sdavidch/* CMNG constants, as derived from system spec calculations */ 343255736Sdavidch 344255736Sdavidch/* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */ 345255736Sdavidch#define DEF_MIN_RATE 100 346255736Sdavidch 347255736Sdavidch/* resolution of the rate shaping timer - 400 usec */ 348255736Sdavidch#define RS_PERIODIC_TIMEOUT_USEC 400 349255736Sdavidch 350255736Sdavidch/* 351255736Sdavidch * number of bytes in single QM arbitration cycle - 352255736Sdavidch * coefficient for calculating the fairness timer 353255736Sdavidch */ 354255736Sdavidch#define QM_ARB_BYTES 160000 355255736Sdavidch 356255736Sdavidch/* resolution of Min algorithm 1:100 */ 357255736Sdavidch#define MIN_RES 100 358255736Sdavidch 359255736Sdavidch/* 360255736Sdavidch * how many bytes above threshold for 361255736Sdavidch * the minimal credit of Min algorithm 362255736Sdavidch */ 363255736Sdavidch#define MIN_ABOVE_THRESH 32768 364255736Sdavidch 365255736Sdavidch/* 366255736Sdavidch * Fairness algorithm integration time coefficient - 367255736Sdavidch * for calculating the actual Tfair 368255736Sdavidch */ 369255736Sdavidch#define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES) 370255736Sdavidch 371255736Sdavidch/* Memory of fairness algorithm - 2 cycles */ 372255736Sdavidch#define FAIR_MEM 2 373255736Sdavidch#define SAFC_TIMEOUT_USEC 52 374255736Sdavidch 375255736Sdavidch#define SDM_TICKS 4 376255736Sdavidch 377255736Sdavidch 378255736Sdavidchstatic inline void ecore_init_max(const struct cmng_init_input *input_data, 379255736Sdavidch uint32_t r_param, struct cmng_init *ram_data) 380255736Sdavidch{ 381255736Sdavidch uint32_t vnic; 382255736Sdavidch struct cmng_vnic *vdata = &ram_data->vnic; 383255736Sdavidch struct cmng_struct_per_port *pdata = &ram_data->port; 384255736Sdavidch /* 385255736Sdavidch * rate shaping per-port variables 386255736Sdavidch * 100 micro seconds in SDM ticks = 25 387255736Sdavidch * since each tick is 4 microSeconds 388255736Sdavidch */ 389255736Sdavidch 390255736Sdavidch pdata->rs_vars.rs_periodic_timeout = 391255736Sdavidch RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS; 392255736Sdavidch 393255736Sdavidch /* this is the threshold below which no timer arming will occur. 394255736Sdavidch * 1.25 coefficient is for the threshold to be a little bigger 395255736Sdavidch * then the real time to compensate for timer in-accuracy 396255736Sdavidch */ 397255736Sdavidch pdata->rs_vars.rs_threshold = 398255736Sdavidch (5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4; 399255736Sdavidch 400255736Sdavidch /* rate shaping per-vnic variables */ 401255736Sdavidch for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) { 402255736Sdavidch /* global vnic counter */ 403255736Sdavidch vdata->vnic_max_rate[vnic].vn_counter.rate = 404255736Sdavidch input_data->vnic_max_rate[vnic]; 405255736Sdavidch /* 406255736Sdavidch * maximal Mbps for this vnic 407255736Sdavidch * the quota in each timer period - number of bytes 408255736Sdavidch * transmitted in this period 409255736Sdavidch */ 410255736Sdavidch vdata->vnic_max_rate[vnic].vn_counter.quota = 411255736Sdavidch RS_PERIODIC_TIMEOUT_USEC * 412255736Sdavidch (uint32_t)vdata->vnic_max_rate[vnic].vn_counter.rate / 8; 413255736Sdavidch } 414255736Sdavidch 415255736Sdavidch} 416255736Sdavidch 417255736Sdavidchstatic inline void ecore_init_max_per_vn(uint16_t vnic_max_rate, 418255736Sdavidch struct rate_shaping_vars_per_vn *ram_data) 419255736Sdavidch{ 420255736Sdavidch /* global vnic counter */ 421255736Sdavidch ram_data->vn_counter.rate = vnic_max_rate; 422255736Sdavidch 423255736Sdavidch /* 424255736Sdavidch * maximal Mbps for this vnic 425255736Sdavidch * the quota in each timer period - number of bytes 426255736Sdavidch * transmitted in this period 427255736Sdavidch */ 428255736Sdavidch ram_data->vn_counter.quota = 429255736Sdavidch RS_PERIODIC_TIMEOUT_USEC * (uint32_t)vnic_max_rate / 8; 430255736Sdavidch} 431255736Sdavidch 432255736Sdavidchstatic inline void ecore_init_min(const struct cmng_init_input *input_data, 433255736Sdavidch uint32_t r_param, struct cmng_init *ram_data) 434255736Sdavidch{ 435255736Sdavidch uint32_t vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair; 436255736Sdavidch struct cmng_vnic *vdata = &ram_data->vnic; 437255736Sdavidch struct cmng_struct_per_port *pdata = &ram_data->port; 438255736Sdavidch 439255736Sdavidch /* this is the resolution of the fairness timer */ 440255736Sdavidch fair_periodic_timeout_usec = QM_ARB_BYTES / r_param; 441255736Sdavidch 442255736Sdavidch /* 443255736Sdavidch * fairness per-port variables 444255736Sdavidch * for 10G it is 1000usec. for 1G it is 10000usec. 445255736Sdavidch */ 446255736Sdavidch tFair = T_FAIR_COEF / input_data->port_rate; 447255736Sdavidch 448255736Sdavidch /* this is the threshold below which we won't arm the timer anymore */ 449255736Sdavidch pdata->fair_vars.fair_threshold = QM_ARB_BYTES; 450255736Sdavidch 451255736Sdavidch /* 452255736Sdavidch * we multiply by 1e3/8 to get bytes/msec. We don't want the credits 453255736Sdavidch * to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution) 454255736Sdavidch */ 455255736Sdavidch pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM; 456255736Sdavidch 457255736Sdavidch /* since each tick is 4 microSeconds */ 458255736Sdavidch pdata->fair_vars.fairness_timeout = 459255736Sdavidch fair_periodic_timeout_usec / SDM_TICKS; 460255736Sdavidch 461255736Sdavidch /* calculate sum of weights */ 462255736Sdavidch vnicWeightSum = 0; 463255736Sdavidch 464255736Sdavidch for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) 465255736Sdavidch vnicWeightSum += input_data->vnic_min_rate[vnic]; 466255736Sdavidch 467255736Sdavidch /* global vnic counter */ 468255736Sdavidch if (vnicWeightSum > 0) { 469255736Sdavidch /* fairness per-vnic variables */ 470255736Sdavidch for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) { 471255736Sdavidch /* 472255736Sdavidch * this is the credit for each period of the fairness 473255736Sdavidch * algorithm - number of bytes in T_FAIR (this vnic 474255736Sdavidch * share of the port rate) 475255736Sdavidch */ 476255736Sdavidch vdata->vnic_min_rate[vnic].vn_credit_delta = 477255736Sdavidch ((uint32_t)(input_data->vnic_min_rate[vnic]) * 100 * 478255736Sdavidch (T_FAIR_COEF / (8 * 100 * vnicWeightSum))); 479255736Sdavidch if (vdata->vnic_min_rate[vnic].vn_credit_delta < 480255736Sdavidch pdata->fair_vars.fair_threshold + 481255736Sdavidch MIN_ABOVE_THRESH) { 482255736Sdavidch vdata->vnic_min_rate[vnic].vn_credit_delta = 483255736Sdavidch pdata->fair_vars.fair_threshold + 484255736Sdavidch MIN_ABOVE_THRESH; 485255736Sdavidch } 486255736Sdavidch } 487255736Sdavidch } 488255736Sdavidch} 489255736Sdavidch 490255736Sdavidchstatic inline void ecore_init_fw_wrr(const struct cmng_init_input *input_data, 491255736Sdavidch uint32_t r_param, struct cmng_init *ram_data) 492255736Sdavidch{ 493255736Sdavidch uint32_t vnic, cos; 494255736Sdavidch uint32_t cosWeightSum = 0; 495255736Sdavidch struct cmng_vnic *vdata = &ram_data->vnic; 496255736Sdavidch struct cmng_struct_per_port *pdata = &ram_data->port; 497255736Sdavidch 498255736Sdavidch for (cos = 0; cos < MAX_COS_NUMBER; cos++) 499255736Sdavidch cosWeightSum += input_data->cos_min_rate[cos]; 500255736Sdavidch 501255736Sdavidch if (cosWeightSum > 0) { 502255736Sdavidch 503255736Sdavidch for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) { 504255736Sdavidch /* 505255736Sdavidch * Since cos and vnic shouldn't work together the rate 506255736Sdavidch * to divide between the coses is the port rate. 507255736Sdavidch */ 508255736Sdavidch uint32_t *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta; 509255736Sdavidch for (cos = 0; cos < MAX_COS_NUMBER; cos++) { 510255736Sdavidch /* 511255736Sdavidch * this is the credit for each period of 512255736Sdavidch * the fairness algorithm - number of bytes 513255736Sdavidch * in T_FAIR (this cos share of the vnic rate) 514255736Sdavidch */ 515255736Sdavidch ccd[cos] = 516255736Sdavidch ((uint32_t)input_data->cos_min_rate[cos] * 100 * 517255736Sdavidch (T_FAIR_COEF / (8 * 100 * cosWeightSum))); 518255736Sdavidch if (ccd[cos] < pdata->fair_vars.fair_threshold 519255736Sdavidch + MIN_ABOVE_THRESH) { 520255736Sdavidch ccd[cos] = 521255736Sdavidch pdata->fair_vars.fair_threshold + 522255736Sdavidch MIN_ABOVE_THRESH; 523255736Sdavidch } 524255736Sdavidch } 525255736Sdavidch } 526255736Sdavidch } 527255736Sdavidch} 528255736Sdavidch 529255736Sdavidchstatic inline void ecore_init_safc(const struct cmng_init_input *input_data, 530255736Sdavidch struct cmng_init *ram_data) 531255736Sdavidch{ 532255736Sdavidch /* in microSeconds */ 533255736Sdavidch ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC; 534255736Sdavidch} 535255736Sdavidch 536255736Sdavidch/* Congestion management port init */ 537255736Sdavidchstatic inline void ecore_init_cmng(const struct cmng_init_input *input_data, 538255736Sdavidch struct cmng_init *ram_data) 539255736Sdavidch{ 540255736Sdavidch uint32_t r_param; 541255736Sdavidch ECORE_MEMSET(ram_data, 0,sizeof(struct cmng_init)); 542255736Sdavidch 543255736Sdavidch ram_data->port.flags = input_data->flags; 544255736Sdavidch 545255736Sdavidch /* 546255736Sdavidch * number of bytes transmitted in a rate of 10Gbps 547255736Sdavidch * in one usec = 1.25KB. 548255736Sdavidch */ 549255736Sdavidch r_param = BITS_TO_BYTES(input_data->port_rate); 550255736Sdavidch ecore_init_max(input_data, r_param, ram_data); 551255736Sdavidch ecore_init_min(input_data, r_param, ram_data); 552255736Sdavidch ecore_init_fw_wrr(input_data, r_param, ram_data); 553255736Sdavidch ecore_init_safc(input_data, ram_data); 554255736Sdavidch} 555255736Sdavidch 556255736Sdavidch 557255736Sdavidch 558255736Sdavidch 559255736Sdavidch/* Returns the index of start or end of a specific block stage in ops array*/ 560255736Sdavidch#define BLOCK_OPS_IDX(block, stage, end) \ 561255736Sdavidch (2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end)) 562255736Sdavidch 563255736Sdavidch 564255736Sdavidch#define INITOP_SET 0 /* set the HW directly */ 565255736Sdavidch#define INITOP_CLEAR 1 /* clear the HW directly */ 566255736Sdavidch#define INITOP_INIT 2 /* set the init-value array */ 567255736Sdavidch 568255736Sdavidch/**************************************************************************** 569255736Sdavidch* ILT management 570255736Sdavidch****************************************************************************/ 571255736Sdavidchstruct ilt_line { 572255736Sdavidch ecore_dma_addr_t page_mapping; 573255736Sdavidch void *page; 574255736Sdavidch uint32_t size; 575255736Sdavidch}; 576255736Sdavidch 577255736Sdavidchstruct ilt_client_info { 578255736Sdavidch uint32_t page_size; 579255736Sdavidch uint16_t start; 580255736Sdavidch uint16_t end; 581255736Sdavidch uint16_t client_num; 582255736Sdavidch uint16_t flags; 583255736Sdavidch#define ILT_CLIENT_SKIP_INIT 0x1 584255736Sdavidch#define ILT_CLIENT_SKIP_MEM 0x2 585255736Sdavidch}; 586255736Sdavidch 587255736Sdavidchstruct ecore_ilt { 588255736Sdavidch uint32_t start_line; 589255736Sdavidch struct ilt_line *lines; 590255736Sdavidch struct ilt_client_info clients[4]; 591255736Sdavidch#define ILT_CLIENT_CDU 0 592255736Sdavidch#define ILT_CLIENT_QM 1 593255736Sdavidch#define ILT_CLIENT_SRC 2 594255736Sdavidch#define ILT_CLIENT_TM 3 595255736Sdavidch}; 596255736Sdavidch 597255736Sdavidch/**************************************************************************** 598255736Sdavidch* SRC configuration 599255736Sdavidch****************************************************************************/ 600255736Sdavidchstruct src_ent { 601255736Sdavidch uint8_t opaque[56]; 602255736Sdavidch uint64_t next; 603255736Sdavidch}; 604255736Sdavidch 605255736Sdavidch/**************************************************************************** 606255736Sdavidch* Parity configuration 607255736Sdavidch****************************************************************************/ 608255736Sdavidch#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \ 609255736Sdavidch{ \ 610255736Sdavidch block##_REG_##block##_PRTY_MASK, \ 611255736Sdavidch block##_REG_##block##_PRTY_STS_CLR, \ 612255736Sdavidch en_mask, {m1, m1h, m2, m3}, #block \ 613255736Sdavidch} 614255736Sdavidch 615255736Sdavidch#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \ 616255736Sdavidch{ \ 617255736Sdavidch block##_REG_##block##_PRTY_MASK_0, \ 618255736Sdavidch block##_REG_##block##_PRTY_STS_CLR_0, \ 619255736Sdavidch en_mask, {m1, m1h, m2, m3}, #block"_0" \ 620255736Sdavidch} 621255736Sdavidch 622255736Sdavidch#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \ 623255736Sdavidch{ \ 624255736Sdavidch block##_REG_##block##_PRTY_MASK_1, \ 625255736Sdavidch block##_REG_##block##_PRTY_STS_CLR_1, \ 626255736Sdavidch en_mask, {m1, m1h, m2, m3}, #block"_1" \ 627255736Sdavidch} 628255736Sdavidch 629255736Sdavidchstatic const struct { 630255736Sdavidch uint32_t mask_addr; 631255736Sdavidch uint32_t sts_clr_addr; 632255736Sdavidch uint32_t en_mask; /* Mask to enable parity attentions */ 633255736Sdavidch struct { 634255736Sdavidch uint32_t e1; /* 57710 */ 635255736Sdavidch uint32_t e1h; /* 57711 */ 636255736Sdavidch uint32_t e2; /* 57712 */ 637255736Sdavidch uint32_t e3; /* 578xx */ 638255736Sdavidch } reg_mask; /* Register mask (all valid bits) */ 639255736Sdavidch char name[8]; /* Block's longest name is 7 characters long 640255736Sdavidch * (name + suffix) 641255736Sdavidch */ 642255736Sdavidch} ecore_blocks_parity_data[] = { 643255736Sdavidch /* bit 19 masked */ 644255736Sdavidch /* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */ 645255736Sdavidch /* bit 5,18,20-31 */ 646255736Sdavidch /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */ 647255736Sdavidch /* bit 5 */ 648255736Sdavidch /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20); */ 649255736Sdavidch /* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */ 650255736Sdavidch /* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */ 651255736Sdavidch 652255736Sdavidch /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't 653255736Sdavidch * want to handle "system kill" flow at the moment. 654255736Sdavidch */ 655255736Sdavidch BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff, 656255736Sdavidch 0x7ffffff), 657255736Sdavidch BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 658255736Sdavidch 0xffffffff), 659255736Sdavidch BLOCK_PRTY_INFO_1(PXP2, 0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff), 660255736Sdavidch BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0), 661255736Sdavidch BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0), 662255736Sdavidch BLOCK_PRTY_INFO_0(NIG, 0xffffffff, 0, 0, 0xffffffff, 0xffffffff), 663255736Sdavidch BLOCK_PRTY_INFO_1(NIG, 0xffff, 0, 0, 0xff, 0xffff), 664255736Sdavidch BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff), 665255736Sdavidch BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1), 666255736Sdavidch BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff), 667255736Sdavidch BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f), 668255736Sdavidch BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3), 669255736Sdavidch BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3), 670255736Sdavidch {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 671255736Sdavidch GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf, 672255736Sdavidch {0xf, 0xf, 0xf, 0xf}, "UPB"}, 673255736Sdavidch {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 674255736Sdavidch GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0, 675255736Sdavidch {0xf, 0xf, 0xf, 0xf}, "XPB"}, 676255736Sdavidch BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7), 677255736Sdavidch BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f), 678255736Sdavidch BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f), 679255736Sdavidch BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1), 680255736Sdavidch BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf), 681255736Sdavidch BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf), 682255736Sdavidch BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff, 0xff), 683255736Sdavidch BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff), 684255736Sdavidch BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f), 685255736Sdavidch BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 686255736Sdavidch BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 687255736Sdavidch BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 688255736Sdavidch BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff), 689255736Sdavidch BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), 690255736Sdavidch BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), 691255736Sdavidch BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff), 692255736Sdavidch BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff), 693255736Sdavidch BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 694255736Sdavidch 0xffffffff), 695255736Sdavidch BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), 696255736Sdavidch BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 697255736Sdavidch 0xffffffff), 698255736Sdavidch BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f), 699255736Sdavidch BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 700255736Sdavidch 0xffffffff), 701255736Sdavidch BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f), 702255736Sdavidch BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff, 703255736Sdavidch 0xffffffff), 704255736Sdavidch BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f), 705255736Sdavidch}; 706255736Sdavidch 707255736Sdavidch 708255736Sdavidch/* [28] MCP Latched rom_parity 709255736Sdavidch * [29] MCP Latched ump_rx_parity 710255736Sdavidch * [30] MCP Latched ump_tx_parity 711255736Sdavidch * [31] MCP Latched scpad_parity 712255736Sdavidch */ 713258203Sedavis#define MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS \ 714255736Sdavidch (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \ 715255736Sdavidch AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \ 716258203Sedavis AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY) 717258203Sedavis 718258203Sedavis#define MISC_AEU_ENABLE_MCP_PRTY_BITS \ 719258203Sedavis (MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS | \ 720255736Sdavidch AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY) 721255736Sdavidch 722255736Sdavidch/* Below registers control the MCP parity attention output. When 723255736Sdavidch * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are 724255736Sdavidch * enabled, when cleared - disabled. 725255736Sdavidch */ 726258203Sedavisstatic const struct { 727258203Sedavis uint32_t addr; 728258203Sedavis uint32_t bits; 729258203Sedavis} mcp_attn_ctl_regs[] = { 730258203Sedavis { MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 731258203Sedavis MISC_AEU_ENABLE_MCP_PRTY_BITS }, 732258203Sedavis { MISC_REG_AEU_ENABLE4_NIG_0, 733258203Sedavis MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }, 734258203Sedavis { MISC_REG_AEU_ENABLE4_PXP_0, 735258203Sedavis MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }, 736258203Sedavis { MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 737258203Sedavis MISC_AEU_ENABLE_MCP_PRTY_BITS }, 738258203Sedavis { MISC_REG_AEU_ENABLE4_NIG_1, 739258203Sedavis MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }, 740258203Sedavis { MISC_REG_AEU_ENABLE4_PXP_1, 741258203Sedavis MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS } 742255736Sdavidch}; 743255736Sdavidch 744255736Sdavidchstatic inline void ecore_set_mcp_parity(struct bxe_softc *sc, uint8_t enable) 745255736Sdavidch{ 746255736Sdavidch int i; 747255736Sdavidch uint32_t reg_val; 748255736Sdavidch 749255736Sdavidch for (i = 0; i < ARRSIZE(mcp_attn_ctl_regs); i++) { 750258203Sedavis reg_val = REG_RD(sc, mcp_attn_ctl_regs[i].addr); 751255736Sdavidch 752255736Sdavidch if (enable) 753293788Sdavidcs reg_val |= mcp_attn_ctl_regs[i].bits; 754293788Sdavidcs else 755293788Sdavidcs reg_val &= ~mcp_attn_ctl_regs[i].bits; 756255736Sdavidch 757258203Sedavis REG_WR(sc, mcp_attn_ctl_regs[i].addr, reg_val); 758255736Sdavidch } 759255736Sdavidch} 760255736Sdavidch 761255736Sdavidchstatic inline uint32_t ecore_parity_reg_mask(struct bxe_softc *sc, int idx) 762255736Sdavidch{ 763255736Sdavidch if (CHIP_IS_E1(sc)) 764255736Sdavidch return ecore_blocks_parity_data[idx].reg_mask.e1; 765255736Sdavidch else if (CHIP_IS_E1H(sc)) 766255736Sdavidch return ecore_blocks_parity_data[idx].reg_mask.e1h; 767255736Sdavidch else if (CHIP_IS_E2(sc)) 768255736Sdavidch return ecore_blocks_parity_data[idx].reg_mask.e2; 769255736Sdavidch else /* CHIP_IS_E3 */ 770255736Sdavidch return ecore_blocks_parity_data[idx].reg_mask.e3; 771255736Sdavidch} 772255736Sdavidch 773255736Sdavidchstatic inline void ecore_disable_blocks_parity(struct bxe_softc *sc) 774255736Sdavidch{ 775255736Sdavidch int i; 776255736Sdavidch 777255736Sdavidch for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) { 778255736Sdavidch uint32_t dis_mask = ecore_parity_reg_mask(sc, i); 779255736Sdavidch 780255736Sdavidch if (dis_mask) { 781255736Sdavidch REG_WR(sc, ecore_blocks_parity_data[i].mask_addr, 782255736Sdavidch dis_mask); 783255736Sdavidch ECORE_MSG(sc, "Setting parity mask " 784255736Sdavidch "for %s to\t\t0x%x\n", 785255736Sdavidch ecore_blocks_parity_data[i].name, dis_mask); 786255736Sdavidch } 787255736Sdavidch } 788255736Sdavidch 789255736Sdavidch /* Disable MCP parity attentions */ 790255736Sdavidch ecore_set_mcp_parity(sc, FALSE); 791255736Sdavidch} 792255736Sdavidch 793255736Sdavidch/** 794255736Sdavidch * Clear the parity error status registers. 795255736Sdavidch */ 796255736Sdavidchstatic inline void ecore_clear_blocks_parity(struct bxe_softc *sc) 797255736Sdavidch{ 798255736Sdavidch int i; 799255736Sdavidch uint32_t reg_val, mcp_aeu_bits = 800255736Sdavidch AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | 801255736Sdavidch AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY | 802255736Sdavidch AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | 803255736Sdavidch AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY; 804255736Sdavidch 805255736Sdavidch /* Clear SEM_FAST parities */ 806255736Sdavidch REG_WR(sc, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 807255736Sdavidch REG_WR(sc, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 808255736Sdavidch REG_WR(sc, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 809255736Sdavidch REG_WR(sc, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1); 810255736Sdavidch 811255736Sdavidch for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) { 812255736Sdavidch uint32_t reg_mask = ecore_parity_reg_mask(sc, i); 813255736Sdavidch 814255736Sdavidch if (reg_mask) { 815255736Sdavidch reg_val = REG_RD(sc, ecore_blocks_parity_data[i]. 816255736Sdavidch sts_clr_addr); 817255736Sdavidch if (reg_val & reg_mask) 818255736Sdavidch ECORE_MSG(sc, 819255736Sdavidch "Parity errors in %s: 0x%x\n", 820255736Sdavidch ecore_blocks_parity_data[i].name, 821255736Sdavidch reg_val & reg_mask); 822255736Sdavidch } 823255736Sdavidch } 824255736Sdavidch 825255736Sdavidch /* Check if there were parity attentions in MCP */ 826255736Sdavidch reg_val = REG_RD(sc, MISC_REG_AEU_AFTER_INVERT_4_MCP); 827255736Sdavidch if (reg_val & mcp_aeu_bits) 828255736Sdavidch ECORE_MSG(sc, "Parity error in MCP: 0x%x\n", 829255736Sdavidch reg_val & mcp_aeu_bits); 830255736Sdavidch 831255736Sdavidch /* Clear parity attentions in MCP: 832255736Sdavidch * [7] clears Latched rom_parity 833255736Sdavidch * [8] clears Latched ump_rx_parity 834255736Sdavidch * [9] clears Latched ump_tx_parity 835255736Sdavidch * [10] clears Latched scpad_parity (both ports) 836255736Sdavidch */ 837255736Sdavidch REG_WR(sc, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780); 838255736Sdavidch} 839255736Sdavidch 840255736Sdavidchstatic inline void ecore_enable_blocks_parity(struct bxe_softc *sc) 841255736Sdavidch{ 842255736Sdavidch int i; 843255736Sdavidch 844255736Sdavidch for (i = 0; i < ARRSIZE(ecore_blocks_parity_data); i++) { 845255736Sdavidch uint32_t reg_mask = ecore_parity_reg_mask(sc, i); 846255736Sdavidch 847255736Sdavidch if (reg_mask) 848255736Sdavidch REG_WR(sc, ecore_blocks_parity_data[i].mask_addr, 849255736Sdavidch ecore_blocks_parity_data[i].en_mask & reg_mask); 850255736Sdavidch } 851255736Sdavidch 852255736Sdavidch /* Enable MCP parity attentions */ 853255736Sdavidch ecore_set_mcp_parity(sc, TRUE); 854255736Sdavidch} 855255736Sdavidch 856255736Sdavidch 857255736Sdavidch#endif /* ECORE_INIT_H */ 858255736Sdavidch 859