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