1 /******************************************************************************* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright 2014 QLogic Corporation 22 * The contents of this file are subject to the terms of the 23 * QLogic End User License (the "License"). 24 * You may not use this file except in compliance with the License. 25 * 26 * You can obtain a copy of the License at 27 * http://www.qlogic.com/Resources/Documents/DriverDownloadHelp/ 28 * QLogic_End_User_Software_License.txt 29 * See the License for the specific language governing permissions 30 * and limitations under the License. 31 * 32 * 33 * Module Description: 34 * This file contains functions that handle HW and FW attention 35 * 36 ******************************************************************************/ 37 38 #include "lm5710.h" 39 #include "general_atten_bits.h" 40 #include "aeu_inputs.h" 41 #include "command.h" 42 43 static INLINE void lm_inc_er_debug_idx(lm_device_t * pdev) 44 { 45 pdev->debug_info.curr_er_debug_idx++; 46 if (pdev->debug_info.curr_er_debug_idx == MAX_ER_DEBUG_ENTRIES) 47 { 48 pdev->debug_info.curr_er_debug_idx=0; 49 } 50 } 51 52 /** 53 * @description 54 * called from attention handling routines, checks if the 55 * attention received is an error which is recoverable via 56 * process kill. If error recovery is disabled this 57 * function always returns FALSE; 58 * 59 * @param pdev 60 * @param attn_sig : values of the after_invert registers read 61 * in the misc that indicate which attention 62 * occured 63 * 64 * 65 * @return u8_t TRUE: attention requires process_kill. FALSE o/w 66 */ 67 u8_t lm_recoverable_error(lm_device_t *pdev, u32_t * attn_sig, u32_t arr_size) 68 { 69 lm_er_debug_info_t * debug_info = NULL; 70 u32_t i; 71 72 if (!pdev->params.enable_error_recovery || CHIP_IS_E1x(pdev)) 73 { 74 return FALSE; 75 } 76 77 ASSERT_STATIC(ARRSIZE(debug_info->attn_sig) >= MAX_ATTN_REGS); 78 DbgBreakIf(arr_size < MAX_ATTN_REGS); 79 80 if ((attn_sig[0] & HW_PRTY_ASSERT_SET_0) || (attn_sig[1] & HW_PRTY_ASSERT_SET_1) || 81 (attn_sig[2] & HW_PRTY_ASSERT_SET_2) || (attn_sig[3] & HW_PRTY_ASSERT_SET_3)) 82 { 83 /* Parity Error... Assuming we only enable parities we can deal with 84 * this is a recoverable error... 85 */ 86 debug_info = &((pdev)->debug_info.er_debug_info[pdev->debug_info.curr_er_debug_idx]); 87 for (i = 0; i < arr_size; i++) 88 { 89 debug_info->attn_sig[i] = attn_sig[i]; 90 } 91 lm_inc_er_debug_idx(pdev); 92 93 /* TODO: maybe get GRCDump here in the future... */ 94 DbgMessage(pdev, FATAL, "lm_recoverable_error: funcid:%d, 0:0x%x, 0:0x%x, 0:0x%x, 0:0x%x\n", 95 ABS_FUNC_ID(pdev), attn_sig[0], attn_sig[1], attn_sig[2], attn_sig[3]); 96 97 return TRUE; 98 } 99 100 /* HW Attentions (other than parity ) */ 101 if (attn_sig[1] & HW_INTERRUT_ASSERT_SET_1) 102 { 103 /* QM Interrupt is recoverable */ 104 if (attn_sig[1] & AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT) 105 { 106 debug_info = &((pdev)->debug_info.er_debug_info[pdev->debug_info.curr_er_debug_idx]); 107 for (i = 0; i < arr_size; i++) 108 { 109 debug_info->attn_sig[i] = attn_sig[i]; 110 } 111 lm_inc_er_debug_idx(pdev); 112 113 DbgMessage(pdev, FATAL, "lm_recoverable_error: funcid:%d, 0:0x%x, 0:0x%x, 0:0x%x, 0:0x%x\n", 114 ABS_FUNC_ID(pdev), attn_sig[0], attn_sig[1], attn_sig[2], attn_sig[3]); 115 return TRUE; 116 } 117 118 } 119 120 if (attn_sig[3] & EVEREST_GEN_ATTN_IN_USE_MASK) 121 { 122 if ( GENERAL_ATTEN_OFFSET(ERROR_RECOVERY_ATTENTION_BIT) & attn_sig[3]) 123 { 124 debug_info = &((pdev)->debug_info.er_debug_info[pdev->debug_info.curr_er_debug_idx]); 125 for (i = 0; i < arr_size; i++) 126 { 127 debug_info->attn_sig[i] = attn_sig[i]; 128 } 129 lm_inc_er_debug_idx(pdev); 130 131 DbgMessage(pdev, FATAL, "lm_recoverable_error: funcid:%d, 0:0x%x, 0:0x%x, 0:0x%x, 0:0x%x\n", 132 ABS_FUNC_ID(pdev), attn_sig[0], attn_sig[1], attn_sig[2], attn_sig[3]); 133 return TRUE; 134 } 135 } 136 137 return FALSE; 138 } 139 140 void enable_blocks_attention(struct _lm_device_t *pdev) 141 { 142 u32_t val = 0; 143 144 REG_WR(pdev,PXP_REG_PXP_INT_MASK_0,0); 145 if (!CHIP_IS_E1x(pdev)) 146 { 147 REG_WR(pdev,PXP_REG_PXP_INT_MASK_1, (PXP_PXP_INT_MASK_1_REG_HST_INCORRECT_ACCESS 148 | PXP_PXP_INT_MASK_1_REG_HST_VF_DISABLED_ACCESS /*Temporary solution*/ 149 | PXP_PXP_INT_MASK_1_REG_HST_PERMISSION_VIOLATION) /*Win8 MMIO (security test)???*/); 150 } 151 REG_WR(pdev,DORQ_REG_DORQ_INT_MASK,0); 152 /* CFC_REG_CFC_INT_MASK see in init_cfc_common */ 153 154 155 //mask read length error interrupts in brb for parser (parsing unit and 'checksum and crc' unit) 156 //these errors are legal (PU reads fixe length and CAC can cause read length error on truncated packets) 157 REG_WR(pdev,BRB1_REG_BRB1_INT_MASK ,0xFC00); 158 159 REG_WR(pdev,QM_REG_QM_INT_MASK ,0); 160 REG_WR(pdev,TM_REG_TM_INT_MASK ,0); 161 REG_WR(pdev,XSDM_REG_XSDM_INT_MASK_0 ,0); 162 REG_WR(pdev,XSDM_REG_XSDM_INT_MASK_1 ,0); 163 REG_WR(pdev,XCM_REG_XCM_INT_MASK ,0); 164 //REG_WR(pdev,XSEM_REG_XSEM_INT_MASK_0 ,0); 165 //REG_WR(pdev,XSEM_REG_XSEM_INT_MASK_1 ,0); 166 REG_WR(pdev,USDM_REG_USDM_INT_MASK_0 ,0); 167 REG_WR(pdev,USDM_REG_USDM_INT_MASK_1 ,0); 168 REG_WR(pdev,UCM_REG_UCM_INT_MASK ,0); 169 //REG_WR(pdev,USEM_REG_USEM_INT_MASK_0 ,0); 170 //REG_WR(pdev,USEM_REG_USEM_INT_MASK_1 ,0); 171 REG_WR(pdev,GRCBASE_UPB+PB_REG_PB_INT_MASK ,0); 172 REG_WR(pdev,CSDM_REG_CSDM_INT_MASK_0 ,0); 173 REG_WR(pdev,CSDM_REG_CSDM_INT_MASK_1 ,0); 174 REG_WR(pdev,CCM_REG_CCM_INT_MASK ,0); 175 //REG_WR(pdev,CSEM_REG_CSEM_INT_MASK_0 ,0); 176 //REG_WR(pdev,CSEM_REG_CSEM_INT_MASK_1 ,0); 177 val = PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT | 178 PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF | 179 PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN; 180 if (!CHIP_IS_E1x(pdev)) 181 { 182 val |= PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED | 183 PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED; 184 } 185 REG_WR(pdev, PXP2_REG_PXP2_INT_MASK_0, val); 186 187 REG_WR(pdev,TSDM_REG_TSDM_INT_MASK_0 ,0); 188 REG_WR(pdev,TSDM_REG_TSDM_INT_MASK_1 ,0); 189 REG_WR(pdev,TCM_REG_TCM_INT_MASK ,0); 190 //REG_WR(pdev,TSEM_REG_TSEM_INT_MASK_0 ,0); 191 //REG_WR(pdev,TSEM_REG_TSEM_INT_MASK_1 ,0); 192 REG_WR(pdev,CDU_REG_CDU_INT_MASK ,0); 193 REG_WR(pdev,DMAE_REG_DMAE_INT_MASK ,0); 194 //REG_WR(pdev,GRCBASE_MISC+MISC_REGISTERS_MISC_INT_MASK ,0); 195 //MASK BIT 3,4 196 REG_WR(pdev,PBF_REG_PBF_INT_MASK ,0X18); 197 198 } 199 200 void disable_blocks_attention(struct _lm_device_t *pdev) 201 { 202 #define MASK_VALUE_GENERATE(_val) ((u32_t)((((u64_t)0x1)<<_val)-1)) 203 typedef struct _block_mask_info_t 204 { 205 u32_t reg_offset; /* the register offset */ 206 u32_t mask_value[3]; /* the mask value per hw (e1 =0 /e1.5 = 1/e2 = 2)*/ 207 } block_mask_info_t; 208 209 u8_t chip_idx = 0; 210 u32_t mask_idx = 0; 211 u32_t val = 0; 212 u32_t offset = 0; 213 u32_t mask_value = 0; 214 215 static const block_mask_info_t init_mask_values_arr[] = 216 { 217 { ATC_REG_ATC_INT_MASK, { 0, 218 0, 219 6 } }, 220 221 { BRB1_REG_BRB1_INT_MASK, { 19, 222 19, 223 19} }, 224 225 { CCM_REG_CCM_INT_MASK, { 11, 226 11, 227 11 } }, 228 229 { CDU_REG_CDU_INT_MASK, { 7, 230 7, 231 7 } }, 232 233 { CFC_REG_CFC_INT_MASK, { 2, 234 2, 235 2 } }, 236 237 { CSDM_REG_CSDM_INT_MASK_0, { 32, 238 32, 239 32 } }, 240 241 { CSDM_REG_CSDM_INT_MASK_1, { 10, 242 10, 243 11 } }, 244 245 #if 0 246 { CSEM_REG_CSEM_INT_MASK_0, { 32, 247 32, 248 32 } }, 249 250 { CSEM_REG_CSEM_INT_MASK_1, { 10, 251 11, 252 11} }, 253 254 { DBG_REG_DBG_INT_MASK, { 2, 255 2, 256 2 } }, 257 #endif //0 258 259 { DMAE_REG_DMAE_INT_MASK, { 2, 260 2, 261 2 } }, 262 263 { DORQ_REG_DORQ_INT_MASK, { 5, 264 5, 265 6 } }, 266 #if 0 267 { HC_REG_HC_INT_MASK, { 7, 268 7, 269 7 } }, 270 #endif //0 271 272 { IGU_REG_IGU_INT_MASK, { 0, 273 0, 274 11 } }, 275 #if 0 276 { MISC_REGISTERS_MISC_INT_MASK, { 4, 277 4, 278 8 } }, 279 280 { NIG_REGISTERS_NIG_INT_MASK_0, { 32, 281 32, 282 32 } }, 283 284 { NIG_REGISTERS_NIG_INT_MASK_1, { 2, 285 4, 286 14 } }, 287 288 { PB_REGISTERS_PB_INT_MASK, { 2, 289 2, 290 2} }, 291 #endif // 0 292 293 { PBF_REG_PBF_INT_MASK, { 5, 294 5, 295 7 } }, 296 297 { PGLUE_B_REG_PGLUE_B_INT_MASK, { 0, 298 0, 299 9 } }, 300 #if 0 301 { PRS_REG_PRS_INT_MASK, { 1, 302 1, 303 1 } }, 304 #endif // 0 305 306 { PXP2_REG_PXP2_INT_MASK_0, { 25, 307 32, 308 32 } }, 309 310 #if 0 311 { PXP2_REG_PXP2_INT_MASK_1, { 0, 312 6, 313 16} }, 314 #endif //0 315 316 { PXP_REG_PXP_INT_MASK_0, { 32, 317 32, 318 32 } }, 319 320 { PXP_REG_PXP_INT_MASK_1, { 5, 321 5, 322 8 } }, 323 324 { QM_REG_QM_INT_MASK, { 2, 325 2, 326 14 } }, 327 #if 0 328 { SEM_FAST_REG_SEM_FAST_INT_MASK, { 1, // This offset is actually 4 different registers (per SEM) 329 1, 330 1} }, 331 332 { SRC_REG_SRC_INT_MASK, { 1, 333 3, 334 3 } }, 335 #endif //0 336 337 { TCM_REG_TCM_INT_MASK, { 11, 338 11, 339 11 } }, 340 341 { TM_REG_TM_INT_MASK, { 1, 342 1, 343 1} }, 344 345 { TSDM_REG_TSDM_INT_MASK_0, { 32, 346 32, 347 32 } }, 348 349 { TSDM_REG_TSDM_INT_MASK_1, { 10, 350 10, 351 11 } }, 352 #if 0 353 { TSEM_REG_TSEM_INT_MASK_0, { 32, 354 32, 355 32 } }, 356 357 { TSEM_REG_TSEM_INT_MASK_1, { 10, 358 11, 359 13 } }, 360 #endif // 0 361 362 { UCM_REG_UCM_INT_MASK, { 11, 363 11, 364 11} }, 365 366 { USDM_REG_USDM_INT_MASK_0, { 32, 367 32, 368 32 } }, 369 370 { USDM_REG_USDM_INT_MASK_1, { 10, 371 10, 372 11 } }, 373 #if 0 374 { USEM_REG_USEM_INT_MASK_0, { 32, 375 32, 376 32 } }, 377 378 { USEM_REG_USEM_INT_MASK_1, { 10, 379 11, 380 11 } }, 381 #endif //0 382 383 { VFC_REG_VFC_INT_MASK, { 0, 384 0, 385 1 } }, 386 387 { XCM_REG_XCM_INT_MASK, { 14, 388 14, 389 14 } }, 390 391 { XSDM_REG_XSDM_INT_MASK_0, { 32, 392 32, 393 32 } }, 394 395 { XSDM_REG_XSDM_INT_MASK_1, { 10, 396 10, 397 11} }, 398 #if 0 399 { XSEM_REG_XSEM_INT_MASK_0, { 32, 400 32, 401 32 } }, 402 403 { XSEM_REG_XSEM_INT_MASK_1, { 10, 404 11, 405 13 } } , 406 #endif // 0 407 }; // init_mask_values_arr 408 409 if (IS_VFDEV(pdev)) 410 { 411 return; 412 } 413 if CHIP_IS_E1( pdev ) 414 { 415 chip_idx = 0; // E1.0 416 } 417 else if CHIP_IS_E1H(pdev) 418 { 419 chip_idx = 1; // E1.5 420 } 421 else if CHIP_IS_E2E3(pdev) 422 { 423 chip_idx = 2; // E2 424 } 425 else 426 { 427 // New chip!!! 428 DbgBreakIf(1); // E?? 429 } 430 431 DbgBreakIf( chip_idx >= ARRSIZE( init_mask_values_arr[0].mask_value ) ); 432 433 for( mask_idx = 0; mask_idx < ARRSIZE(init_mask_values_arr); mask_idx++ ) 434 { 435 mask_value = init_mask_values_arr[mask_idx].mask_value[chip_idx] ; 436 437 if( mask_value ) 438 { 439 val = MASK_VALUE_GENERATE(mask_value); 440 offset = init_mask_values_arr[mask_idx].reg_offset; 441 REG_WR(pdev, offset, val ); 442 } 443 } 444 /* 445 446 REG_WR(pdev,PXP_REG_PXP_INT_MASK_0,0xffffffff); 447 if (IS_E2(pdev)) { 448 REG_WR(pdev,PXP_REG_PXP_INT_MASK_1,0xff); 449 } else { 450 REG_WR(pdev,PXP_REG_PXP_INT_MASK_1,0x1f); 451 } 452 REG_WR(pdev,DORQ_REG_DORQ_INT_MASK,0x1f); 453 REG_WR(pdev,CFC_REG_CFC_INT_MASK ,0x3); 454 REG_WR(pdev,QM_REG_QM_INT_MASK ,0x3); 455 REG_WR(pdev,TM_REG_TM_INT_MASK ,0x1); 456 REG_WR(pdev,XSDM_REG_XSDM_INT_MASK_0 ,0xffffffff); 457 REG_WR(pdev,XSDM_REG_XSDM_INT_MASK_1 ,0x3ff); 458 REG_WR(pdev,XCM_REG_XCM_INT_MASK,0x3fff); 459 //REG_WR(pdev,XSEM_REG_XSEM_INT_MASK_0 ,0); 460 //REG_WR(pdev,XSEM_REG_XSEM_INT_MASK_1 ,0); 461 REG_WR(pdev,USDM_REG_USDM_INT_MASK_0 ,0xffffffff); 462 REG_WR(pdev,USDM_REG_USDM_INT_MASK_1 ,0x3ff); 463 REG_WR(pdev,UCM_REG_UCM_INT_MASK ,0x7ff); 464 //REG_WR(pdev,USEM_REG_USEM_INT_MASK_0 ,0); 465 //REG_WR(pdev,USEM_REG_USEM_INT_MASK_1 ,0); 466 REG_WR(pdev,GRCBASE_UPB+PB_REG_PB_INT_MASK ,0x3); 467 REG_WR(pdev,CSDM_REG_CSDM_INT_MASK_0 ,0xffffffff); 468 REG_WR(pdev,CSDM_REG_CSDM_INT_MASK_1 ,0x3ff); 469 REG_WR(pdev,CCM_REG_CCM_INT_MASK ,0x7ff); 470 //REG_WR(pdev,CSEM_REG_CSEM_INT_MASK_0 ,0); 471 //REG_WR(pdev,CSEM_REG_CSEM_INT_MASK_1 ,0); 472 473 REG_WR(pdev,PXP2_REG_PXP2_INT_MASK_0,0xffffffff); 474 475 REG_WR(pdev,TSDM_REG_TSDM_INT_MASK_0 ,0xffffffff); 476 REG_WR(pdev,TSDM_REG_TSDM_INT_MASK_1 ,0x3ff); 477 REG_WR(pdev,TCM_REG_TCM_INT_MASK ,0x7ff); 478 //REG_WR(pdev,TSEM_REG_TSEM_INT_MASK_0 ,0); 479 //REG_WR(pdev,TSEM_REG_TSEM_INT_MASK_1 ,0); 480 REG_WR(pdev,CDU_REG_CDU_INT_MASK ,0x7f); 481 REG_WR(pdev,DMAE_REG_DMAE_INT_MASK ,0x3); 482 //REG_WR(pdev,GRCBASE_MISC+MISC_REGISTERS_MISC_INT_MASK ,0); 483 //MASK BIT 3,4 484 REG_WR(pdev,PBF_REG_PBF_INT_MASK ,0x1f); 485 */ 486 487 // disable MCP's attentions 488 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,0); 489 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_1,0); 490 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2,0); 491 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_3,0); 492 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,0); 493 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_1,0); 494 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2,0); 495 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_3,0); 496 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4,0); 497 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5,0); 498 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6,0); 499 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7,0); 500 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4,0); 501 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5,0); 502 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6,0); 503 REG_WR(pdev,MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7,0); 504 } 505 506 void lm_reset_mask_attn(struct _lm_device_t *pdev) 507 { 508 // mask the pxp attentions 509 REG_WR(pdev,PXP_REG_PXP_INT_MASK_0,0xffffffff); // 32 bits 510 if (CHIP_IS_E1x(pdev)) 511 { 512 REG_WR(pdev,PXP_REG_PXP_INT_MASK_1,0x1f); // 5 bits 513 } 514 else 515 { 516 REG_WR(pdev,PXP_REG_PXP_INT_MASK_1,0xff); // 8 bits 517 } 518 REG_WR(pdev,PXP2_REG_PXP2_INT_MASK_0,0xffffffff); // 32 bits 519 520 /* We never unmask this register so no need to re-mask it*/ 521 //REG_WR(pdev,PXP2_REG_PXP2_INT_MASK_1,0x3f); // 32 bits 522 } 523 524 static void lm_latch_attn_everest_processing(lm_device_t *pdev, u32_t sig_word_aft_inv) 525 { 526 u32_t latch_bit_to_clr = 0; 527 u32_t val = 0; 528 u32_t offset = 0; 529 530 //pass over all latched attentions 531 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCR); 532 if ( offset & sig_word_aft_inv) 533 { 534 latch_bit_to_clr = 0x1; 535 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 536 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_RBCR received!!!\n"); 537 DbgBreakIfAll(1); 538 } 539 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCT); 540 if ( offset & sig_word_aft_inv) 541 { 542 latch_bit_to_clr = 0x2; 543 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 544 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_RBCT received!!!\n"); 545 DbgBreakIfAll(1); 546 } 547 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCN); 548 if ( offset & sig_word_aft_inv) 549 { 550 latch_bit_to_clr = 0x4; 551 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 552 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_RBCN received!!!\n"); 553 DbgBreakIfAll(1); 554 } 555 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCU); 556 if ( offset & sig_word_aft_inv) 557 { 558 latch_bit_to_clr = 0x8; 559 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 560 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_RBCU received!!!\n"); 561 DbgBreakIfAll(1); 562 } 563 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RBCP); 564 if ( offset & sig_word_aft_inv) 565 { 566 latch_bit_to_clr = 0x10; 567 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 568 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_RBCP received!!! \n"); 569 DbgBreakIfAll(1); 570 } 571 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_TIMEOUT_GRC); 572 if ( offset & sig_word_aft_inv) 573 { 574 #define GRC_TIMEOUT_MASK_ADDRESS(_val) ( (_val) & ((1<<19)-1)) // 0x000fffff 575 #define GRC_TIMEOUT_MASK_FUNCTION(_val) ( (_val>>20) & ((1<<3)-1)) // 0x00700000 576 #define GRC_TIMEOUT_MASK_MASTER(_val) ( (_val>>24) & ((1<<4)-1)) // 0x0f000000 577 578 u32_t addr = 0; 579 u32_t func = 0; 580 u32_t master = 0; 581 u32_t grc_timeout_cnt = 0; 582 u8_t b_assert = TRUE; 583 u8_t b_nig_reset_called = lm_is_nig_reset_called(pdev); 584 const u32_t grc_timeout_max_ignore = pdev->params.grc_timeout_max_ignore; 585 586 latch_bit_to_clr = 0x20; 587 588 // we check if nig reset was done 589 if( b_nig_reset_called ) 590 { 591 b_assert = FALSE; 592 } 593 594 if (!CHIP_IS_E1(pdev)) 595 { 596 val = REG_RD(pdev, MISC_REG_GRC_TIMEOUT_ATTN); 597 addr = GRC_TIMEOUT_MASK_ADDRESS(val); 598 func = GRC_TIMEOUT_MASK_FUNCTION(val); 599 master = GRC_TIMEOUT_MASK_MASTER(val); 600 601 // in non E1 we can verify it is mcp cause (due to nig probably) 602 if( 2 != master ) // 2 is mcp cause 603 { 604 b_assert = TRUE; 605 } 606 } 607 608 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 609 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_TIMEOUT_GRC received!!! val=0x%08x master=0x%x func=0x%x addr=0x%xx4=0x%X)\n" 610 ,val, master, func, addr, addr*4 ); 611 612 // NOTE: we ignore b_nig_reset_called and ASSERT only according to grc_timeout_max_ignore value (default is 0x10) 613 614 grc_timeout_cnt = lm_inc_cnt_grc_timeout_ignore(pdev, val); 615 // if we are here it means we ignore the ASSERT inc counter 616 if( grc_timeout_cnt >= grc_timeout_max_ignore ) 617 { 618 b_assert = TRUE; 619 } 620 else 621 { 622 b_assert = FALSE; 623 } 624 625 if( b_assert ) 626 { 627 DbgBreakIf(1); 628 } 629 630 if( b_nig_reset_called ) 631 { 632 // we reset the flag (we "allow" one timeout after nig reset) 633 lm_clear_nig_reset_called(pdev); 634 } 635 } 636 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_RSVD_GRC); 637 if ( offset & sig_word_aft_inv) 638 { 639 latch_bit_to_clr = 0x40; 640 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 641 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_RSVD_GRC received!!!\n"); 642 DbgBreakIfAll(1); 643 } 644 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_ROM_PARITY_MCP); 645 if ( offset & sig_word_aft_inv) 646 { 647 latch_bit_to_clr = 0x80; 648 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 649 val = lm_mcp_check(pdev); 650 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_ROM_PARITY_MCP received!!!\n"); 651 /* For E2, at the time this code was written (e2-bringup ) the parity is (somehow) expected */ 652 if (CHIP_IS_E1x(pdev)) 653 { 654 DbgBreakIfAll(1); 655 } 656 else 657 { 658 DbgBreakIf(1); 659 } 660 } 661 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_UM_RX_PARITY_MCP); 662 if ( offset & sig_word_aft_inv) 663 { 664 latch_bit_to_clr = 0x100; 665 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 666 val = lm_mcp_check(pdev); 667 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_UM_RX_PARITY_MCP received!!!\n"); 668 DbgBreakIfAll(1); 669 } 670 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_UM_TX_PARITY_MCP); 671 if ( offset & sig_word_aft_inv) 672 { 673 latch_bit_to_clr = 0x200; 674 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 675 val = lm_mcp_check(pdev); 676 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_UM_TX_PARITY_MCP received!!!\n"); 677 DbgBreakIfAll(1); 678 } 679 offset = GENERAL_ATTEN_OFFSET(LATCHED_ATTN_SCPAD_PARITY_MCP); 680 if ( offset & sig_word_aft_inv) 681 { 682 latch_bit_to_clr = 0x400; 683 REG_WR(pdev, MISC_REG_AEU_CLR_LATCH_SIGNAL, latch_bit_to_clr); 684 val = lm_mcp_check(pdev); 685 DbgMessage(pdev, FATAL, "lm_latch_attn_everest_processing: LATCHED_ATTN_SCPAD_PARITY_MCP received!!!\n"); 686 DbgBreakIfAll(1); 687 } 688 } 689 690 static void lm_hard_wired_processing(lm_device_t *pdev, u16_t assertion_proc_flgs) 691 { 692 /* processing of highest 8-15 bits of 8 "hard-wired" attention signals toward IGU. 693 Excluding NIG & PXP "close the gates" 694 695 ! No need to lock here since this is an uncommon group whether there is a recovery procedure or not. 696 697 Signal name Bit position SOURCE Type Required Destination 698 ----------------------------------------------------------------------------- 699 NIG attention for port0 D8 NIG Event MCP/Driver0(PHY) 700 SW timer#4 port0 D9 MISC Event MCP -> Ignore! 701 GPIO#2 port0 D10 MISC Event MCP 702 GPIO#3 port0 D11 MISC Event MCP 703 GPIO#4 port0 D12 MISC Event MCP 704 General attn1 D13 GRC mapped Attention MCP/Driver0/Driver1 -> ASSERT! 705 General attn2 D14 GRC mapped Attention MCP/Driver0/Driver1 -> ASSERT! 706 General attn3 D15 GRC mapped Attention MCP/Driver0/Driver1 -> ASSERT! 707 */ 708 //TODO: for the required attn signals, need to "clean the hw block" (INT_STS_CLR..) 709 if (PORT_ID(pdev) == 0) 710 { 711 #if 0 // Timer 4 is being used by OCBB now 712 if (assertion_proc_flgs & ATTN_SW_TIMER_4_FUNC) 713 { 714 //DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_SW_TIMER_4_FUNC!\n"); 715 //to deal with this signal, add dispatch func call here 716 } 717 #endif 718 if (assertion_proc_flgs & GPIO_2_FUNC) 719 { 720 DbgMessage(pdev, WARN, "lm_hard_wired_processing: GPIO_1_FUNC!\n"); 721 //to deal with this signal, add dispatch func call here 722 } 723 if (assertion_proc_flgs & GPIO_3_FUNC) 724 { 725 DbgMessage(pdev, WARN, "lm_hard_wired_processing: GPIO_2_FUNC!\n"); 726 //to deal with this signal, add dispatch func call here 727 } 728 if (assertion_proc_flgs & GPIO_4_FUNC) 729 { 730 DbgMessage(pdev, WARN, "lm_hard_wired_processing: GPIO_3_FUNC0!\n"); 731 // Will be handled in deassertion 732 } 733 if (assertion_proc_flgs & ATTN_GENERAL_ATTN_1) 734 { 735 DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_GENERAL_ATTN_1! and clean it!!!\n"); 736 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_1,0x0); 737 } 738 if (assertion_proc_flgs & ATTN_GENERAL_ATTN_2) 739 { 740 DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_GENERAL_ATTN_2! and clean it!!!\n"); 741 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_2,0x0); 742 } 743 if (assertion_proc_flgs & ATTN_GENERAL_ATTN_3) 744 { 745 DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_GENERAL_ATTN_3! and clean it!!!\n"); 746 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_3,0x0); 747 } 748 } 749 else 750 { 751 DbgBreakIf(PORT_ID(pdev) != 1); 752 753 if (assertion_proc_flgs & ATTN_SW_TIMER_4_FUNC1) 754 { 755 //DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_SW_TIMER_4_FUNC1!\n"); 756 //to deal with this signal, add dispatch func call here 757 } 758 if (assertion_proc_flgs & GPIO_2_FUNC1) 759 { 760 DbgMessage(pdev, WARN, "lm_hard_wired_processing: GPIO_1_FUNC1!\n"); 761 //to deal with this signal, add dispatch func call here 762 } 763 if (assertion_proc_flgs & GPIO_3_FUNC1) 764 { 765 DbgMessage(pdev, WARN, "lm_hard_wired_processing: GPIO_2_FUNC1!\n"); 766 //to deal with this signal, add dispatch func call here 767 } 768 if (assertion_proc_flgs & GPIO_4_FUNC1) 769 { 770 DbgMessage(pdev, WARN, "lm_hard_wired_processing: GPIO_3_FUNC1!\n"); 771 // Will be handled in deassertion 772 } 773 if (assertion_proc_flgs & ATTN_GENERAL_ATTN_4) 774 { 775 DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_GENERAL_ATTN_4! and clean it!!!\n"); 776 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_4,0x0); 777 } 778 if (assertion_proc_flgs & ATTN_GENERAL_ATTN_5) 779 { 780 DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_GENERAL_ATTN_5! and clean it!!!\n"); 781 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_5,0x0); 782 } 783 if (assertion_proc_flgs & ATTN_GENERAL_ATTN_6) 784 { 785 DbgMessage(pdev, FATAL, "lm_hard_wired_processing: ATTN_GENERAL_ATTN_6! and clean it!!!\n"); 786 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_6,0x0); 787 } 788 } 789 } 790 791 static void lm_nig_processing(lm_device_t *pdev) 792 { 793 u32_t nig_status_port = 0; 794 u32_t unicore_val = 0; 795 u32_t is_unicore_intr_asserted = 0; 796 // save nig interrupt mask and set it back later 797 lm_link_update(pdev); 798 if (PORT_ID(pdev) == 0) 799 { 800 //read the status interrupt of the NIG for the appropriate port (will do read-modify-write) 801 nig_status_port = REG_RD(pdev, NIG_REG_STATUS_INTERRUPT_PORT0); 802 803 //pass over each of the 24 NIG REG to find out why the NIG attention was asserted. 804 //every unicore interrupt read, in case it differs from the corresponding bit in the 805 //NIG_REG_STATUS_INTERRUPT_PORT0, then we need to assign the value read into the apporpriate bit 806 // in NIG_REG_STATUS_INTERRUPT_PORT0 register. 807 808 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC0_STATUS_MISC_MI_INT, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT_SIZE); 809 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC0_STATUS_MISC_MI_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_COMPLETE_SIZE); 810 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC0_STATUS_MISC_CFG_CHANGE, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_CFG_CHANGE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_CFG_CHANGE_SIZE); 811 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC0_STATUS_MISC_LINK_STATUS, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_LINK_STATUS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_LINK_STATUS_SIZE); 812 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC0_STATUS_MISC_LINK_CHANGE, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_LINK_CHANGE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_LINK_CHANGE_SIZE); 813 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC0_STATUS_MISC_ATTN, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_ATTN, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_ATTN_SIZE); 814 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_MAC_CRS, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_MAC_CRS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_MAC_CRS_SIZE); 815 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_AUTONEG_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_AUTONEG_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_AUTONEG_COMPLETE_SIZE); 816 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_FIBER_RXACT, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_FIBER_RXACT, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_FIBER_RXACT_SIZE); 817 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_LINK_STATUS, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS_SIZE); 818 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_MR_PAGE_RX_SIZE); 819 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_CL73_AN_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_CL73_AN_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_CL73_AN_COMPLETE_SIZE); 820 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_CL73_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_CL73_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_CL73_MR_PAGE_RX_SIZE); 821 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES0_STATUS_RX_SIGDET, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_RX_SIGDET, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_RX_SIGDET_SIZE); 822 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_REMOTEMDIOREQ, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_REMOTEMDIOREQ, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_REMOTEMDIOREQ_SIZE); 823 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_LINK10G, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G_SIZE); 824 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_AUTONEG_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_AUTONEG_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_AUTONEG_COMPLETE_SIZE); 825 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_FIBER_RXACT, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_FIBER_RXACT, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_FIBER_RXACT_SIZE); 826 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_LINK_STATUS, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE); 827 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_MR_PAGE_RX_SIZE); 828 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_CL73_AN_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_CL73_AN_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_CL73_AN_COMPLETE_SIZE); 829 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_CL73_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_CL73_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_CL73_MR_PAGE_RX_SIZE); 830 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_RX_SIGDET, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_RX_SIGDET, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_RX_SIGDET_SIZE); 831 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS0_STATUS_MAC_CRS, &unicore_val, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_MAC_CRS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_MAC_CRS_SIZE); 832 833 //write back the updated status interrupt of the NIG for the appropriate port. 834 REG_WR(pdev, NIG_REG_STATUS_INTERRUPT_PORT0, nig_status_port); 835 } 836 else 837 { 838 DbgBreakIf(PORT_ID(pdev) != 1); 839 nig_status_port = REG_RD(pdev, NIG_REG_STATUS_INTERRUPT_PORT1); 840 841 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC1_STATUS_MISC_MI_INT, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_MI_INT, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_MI_INT_SIZE); 842 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC1_STATUS_MISC_MI_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_MI_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_MI_COMPLETE_SIZE); 843 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC1_STATUS_MISC_CFG_CHANGE, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_CFG_CHANGE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_CFG_CHANGE_SIZE); 844 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC1_STATUS_MISC_LINK_STATUS, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_LINK_STATUS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_LINK_STATUS_SIZE); 845 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC1_STATUS_MISC_LINK_CHANGE, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_LINK_CHANGE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_LINK_CHANGE_SIZE); 846 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_EMAC1_STATUS_MISC_ATTN, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_ATTN, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_EMAC1_MISC_ATTN_SIZE); 847 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_MAC_CRS, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_MAC_CRS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_MAC_CRS_SIZE); 848 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_AUTONEG_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_AUTONEG_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_AUTONEG_COMPLETE_SIZE); 849 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_FIBER_RXACT, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_FIBER_RXACT, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_FIBER_RXACT_SIZE); 850 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_LINK_STATUS, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_LINK_STATUS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_LINK_STATUS_SIZE); 851 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_MR_PAGE_RX_SIZE); 852 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_CL73_AN_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_CL73_AN_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_CL73_AN_COMPLETE_SIZE); 853 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_CL73_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_CL73_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_CL73_MR_PAGE_RX_SIZE); 854 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_SERDES1_STATUS_RX_SIGDET, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_RX_SIGDET, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_SERDES1_RX_SIGDET_SIZE); 855 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_REMOTEMDIOREQ, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_REMOTEMDIOREQ, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_REMOTEMDIOREQ_SIZE); 856 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_LINK10G, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_LINK10G, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_LINK10G_SIZE); 857 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_AUTONEG_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_AUTONEG_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_AUTONEG_COMPLETE_SIZE); 858 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_FIBER_RXACT, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_FIBER_RXACT, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_FIBER_RXACT_SIZE); 859 //HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_LINK_STATUS, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_LINK_STATUS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_LINK_STATUS_SIZE); 860 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_MR_PAGE_RX_SIZE); 861 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_CL73_AN_COMPLETE, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_CL73_AN_COMPLETE, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_CL73_AN_COMPLETE_SIZE); 862 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_CL73_MR_PAGE_RX, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_CL73_MR_PAGE_RX, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_CL73_MR_PAGE_RX_SIZE); 863 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_RX_SIGDET, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_RX_SIGDET, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_RX_SIGDET_SIZE); 864 HANDLE_UNICORE_INT_ASSERTED(pdev, NIG_REG_XGXS1_STATUS_MAC_CRS, &unicore_val, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_MAC_CRS, &nig_status_port, &is_unicore_intr_asserted, NIG_STATUS_INTERRUPT_PORT1_REG_STATUS_XGXS1_MAC_CRS_SIZE); 865 866 REG_WR(pdev, NIG_REG_STATUS_INTERRUPT_PORT1, nig_status_port); 867 868 } 869 } 870 871 void lm_handle_assertion_processing(lm_device_t *pdev, u16_t assertion_proc_flgs) 872 { 873 u32_t val = 0; 874 u32_t port_reg_name = 0; 875 u32_t mask_val = 0; 876 u32_t nig_mask = 0; 877 878 DbgMessage(pdev, INFORM, "lm_handle_assertion_processing: assertion_proc_flgs:%d\n", assertion_proc_flgs); 879 880 //mask only appropriate attention output signals from configured routing and unifier logic toward IGU. 881 //This is for driver/chip sync to eventually return to '00' monitored state 882 //in both leading & trailing latch. 883 //mask non-hard-wired dynamic groups only 884 885 DbgBreakIf(pdev->vars.attn_state & assertion_proc_flgs); 886 887 //mask relevant AEU attn lines 888 // mask assert_flgs new mask 889 //legal: 0 0 -> 0 890 // 1 0 -> 1 891 // 1 1 -> 0 892 //ASSERT: 0 1 -> this won't change us thanks to & ~ 893 894 ASSERT_STATIC( HW_LOCK_RESOURCE_PORT0_ATT_MASK +1 == HW_LOCK_RESOURCE_PORT1_ATT_MASK ); 895 ASSERT_STATIC( NIG_REG_MASK_INTERRUPT_PORT0 + 4 == NIG_REG_MASK_INTERRUPT_PORT1 ); 896 897 lm_hw_lock(pdev, HW_LOCK_RESOURCE_PORT0_ATT_MASK + PORT_ID(pdev), TRUE); 898 port_reg_name = PORT_ID(pdev) ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : MISC_REG_AEU_MASK_ATTN_FUNC_0; 899 // read the hw current mask value 900 mask_val=REG_RD(pdev, port_reg_name); 901 //changed rrom XOR to & ~ 902 pdev->vars.aeu_mask_attn_func = mask_val & 0xff; 903 DbgMessage(pdev, INFORM, "lm_handle_assertion_processing: BEFORE: aeu_mask_attn_func:0x%x\n", pdev->vars.aeu_mask_attn_func); 904 //changed rrom XOR to & ~ 905 pdev->vars.aeu_mask_attn_func &= ~(assertion_proc_flgs & 0xff); 906 REG_WR(pdev, port_reg_name, pdev->vars.aeu_mask_attn_func); 907 DbgMessage(pdev, INFORM, "lm_handle_assertion_processing: AFTER : aeu_mask_attn_func:0x%x\n", pdev->vars.aeu_mask_attn_func); 908 lm_hw_unlock(pdev, HW_LOCK_RESOURCE_PORT0_ATT_MASK + PORT_ID(pdev)); 909 //update the bits states 910 911 // state assert_flgs new state 912 //legal: 0 0 -> 0 913 // 0 1 -> 1 914 // 1 0 -> 1 915 //error: 1 1 -> this won't change us thanks to | 916 DbgMessage(pdev, INFORM, "lm_handle_assertion_processing: BEFORE: attn_state:0x%x\n", pdev->vars.attn_state); 917 //changed from XOR to OR for safety 918 pdev->vars.attn_state |= assertion_proc_flgs; 919 920 DbgMessage(pdev, INFORM, "lm_handle_assertion_processing: AFTER : attn_state:0x%x\n", pdev->vars.attn_state); 921 //process only hard-wired lines in case any got up 922 if (assertion_proc_flgs & ATTN_HARD_WIRED_MASK) 923 { 924 lm_hard_wired_processing(pdev, assertion_proc_flgs); 925 } 926 927 // now handle nig 928 if (assertion_proc_flgs & ATTN_NIG_FOR_FUNC) 929 { 930 MM_ACQUIRE_PHY_LOCK(pdev); 931 // save nig interrupt mask and set it back later 932 nig_mask = REG_RD(pdev, NIG_REG_MASK_INTERRUPT_PORT0 + 4*PORT_ID(pdev)); 933 REG_WR(pdev, NIG_REG_MASK_INTERRUPT_PORT0 + 4*PORT_ID(pdev), 0); 934 935 // we'll handle the attention only if mask is not 0 936 // if mask is 0, it means that "old" and irrelevant is sent 937 // and we should not hnalde it (e.g. CQ48990 - got link down event after loopback mode was set). 938 if( nig_mask ) 939 { 940 lm_nig_processing(pdev); 941 } 942 else 943 { 944 DbgMessage(pdev, WARN, "lm_handle_deassertion_processing: got attention when nig_mask is 0\n" ); 945 } 946 } 947 948 //parallel write to IGU to set the attn_ack for _all asserted_ lines. 949 val = assertion_proc_flgs; 950 951 // attntion bits set 952 if (INTR_BLK_TYPE(pdev) == INTR_BLK_HC) 953 { 954 REG_WR(pdev, HC_REG_COMMAND_REG + PORT_ID(pdev)*32 + COMMAND_REG_ATTN_BITS_SET,val); 955 } 956 else 957 { 958 u32_t cmd_addr = IGU_CMD_ATTN_BIT_SET_UPPER; 959 if (INTR_BLK_ACCESS(pdev) == INTR_BLK_ACCESS_IGUMEM) 960 { 961 REG_WR(pdev, BAR_IGU_INTMEM + cmd_addr*8, val); 962 } 963 else 964 { 965 struct igu_ctrl_reg cmd_ctrl; 966 u8_t igu_func_id = 0; 967 /* GRC ACCESS: */ 968 /* Write the Data, then the control */ 969 /* [18:12] - FID (if VF - [18] = 0; [17:12] = VF number; if PF - [18] = 1; [17:14] = 0; [13:12] = PF number) */ 970 igu_func_id = IGU_FUNC_ID(pdev); 971 cmd_ctrl.ctrl_data = 972 ((cmd_addr << IGU_CTRL_REG_ADDRESS_SHIFT) | 973 (igu_func_id << IGU_CTRL_REG_FID_SHIFT) | 974 (IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT)); 975 976 REG_WR(pdev, IGU_REG_COMMAND_REG_32LSB_DATA, val); 977 REG_WR(pdev, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl.ctrl_data); 978 } 979 } 980 981 // now set back the mask 982 if (assertion_proc_flgs & ATTN_NIG_FOR_FUNC) 983 { 984 u8_t blk_type = INTR_BLK_TYPE(pdev); 985 u8_t blk_access = INTR_BLK_ACCESS(pdev); 986 987 if ( ( blk_type != INTR_BLK_HC ) && ( blk_access == INTR_BLK_ACCESS_IGUMEM )) 988 { 989 u32 cnt = 0; 990 // Verify that IGU ack through BAR was written before restoring NIG mask. 991 // This loop should exit after 2-3 iterations max. 992 do 993 { 994 val = REG_RD(pdev, IGU_REG_ATTENTION_ACK_BITS); 995 } 996 while (((val & ATTN_NIG_FOR_FUNC) == 0) && (++cnt < MAX_IGU_ATTN_ACK_TO)); 997 998 if (!val) 999 { 1000 DbgMessage(pdev, FATAL, "Failed to verify IGU ack on time\n"); 1001 } 1002 } 1003 REG_WR(pdev, NIG_REG_MASK_INTERRUPT_PORT0 + 4*PORT_ID(pdev), nig_mask); 1004 MM_RELEASE_PHY_LOCK(pdev); 1005 } 1006 } 1007 1008 static u32_t lm_cfc_attn_everest_processing(lm_device_t *pdev) 1009 { 1010 u32_t val, valc; 1011 val = REG_RD(pdev,CFC_REG_CFC_INT_STS); 1012 1013 // TODO add defines here 1014 DbgMessage(pdev, FATAL, "CFC hw attention 0x%x\n",val); 1015 if (val) { 1016 pdev->vars.cfc_int_status_cnt++; 1017 // CFC error attention 1018 if (val & 0x2) 1019 { 1020 //DbgBreakIfAll(1); 1021 } 1022 } 1023 valc = REG_RD(pdev,CFC_REG_CFC_INT_STS_CLR); 1024 return val; 1025 } 1026 static void lm_pxp_attn_everest_processing(lm_device_t *pdev) 1027 { 1028 u32_t val = REG_RD(pdev,PXP_REG_PXP_INT_STS_0); 1029 1030 // TODO add defines here 1031 DbgMessage(pdev, FATAL, "PXP hw attention 0x%x\n",val); 1032 // RQ_USDMDP_FIFO_OVERFLOW attention 1033 if (val & 0x18000) 1034 { 1035 DbgBreakIfAll(1); 1036 } 1037 1038 } 1039 /* 1040 *Function Name:lm_spio5_attn_everest_processing 1041 * 1042 *Parameters: 1043 * 1044 *Description: 1045 * Indicates fan failure on specific external_phy_config (PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) 1046 *Returns: 1047 * 1048 */ 1049 static void lm_spio5_attn_everest_processing(lm_device_t *pdev) 1050 { 1051 u32_t val = 0; 1052 u32_t offset = 0; 1053 u32_t ext_phy_config = 0; 1054 const u8_t port_id = PORT_ID(pdev); 1055 1056 // Special fan failure handling for boards with external PHY SFX7101 (which include fan) 1057 PHY_HW_LOCK(pdev); 1058 elink_hw_reset_phy(&pdev->params.link); 1059 PHY_HW_UNLOCK(pdev); 1060 1061 offset = ( 0 == port_id ) ? MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 ; 1062 1063 val = REG_RD(pdev, offset ); 1064 1065 DbgMessage(pdev, FATAL, "lm_spio5_attn_everest_processing: SPIO5 hw attention 0x%x\n",val); 1066 1067 // mask flags so we won't get this attention anymore 1068 RESET_FLAGS(val, AEU_INPUTS_ATTN_BITS_SPIO5 ) ; 1069 REG_WR(pdev, offset, val ) ; 1070 1071 // change phy_type to type failure (under phy lock) 1072 MM_ACQUIRE_PHY_LOCK(pdev); 1073 1074 offset = OFFSETOF(shmem_region_t,dev_info.port_hw_config[port_id].external_phy_config); 1075 1076 LM_SHMEM_READ(pdev, offset, &ext_phy_config); 1077 1078 RESET_FLAGS(ext_phy_config, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK ) ; 1079 SET_FLAGS(ext_phy_config, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE ) ; 1080 1081 // Set external phy type to failure for MCP to know about the failure 1082 LM_SHMEM_WRITE(pdev, offset, ext_phy_config); 1083 1084 DbgMessage(pdev, WARN, "lm_spio5_attn_everest_processing: external_phy_type 0x%x\n",ext_phy_config); 1085 1086 // Indicate "link-down". elink_hw_reset_phy takes care of the physical part, but part of the function 1087 // masks attentions, which means we won't get a link event from anywhere else. Therefore we need to 1088 // indicate link down at this point to OS... to supress traffic and upload toe connections... 1089 // we do this under lock since we change the link status... 1090 pdev->vars.link_status = LM_STATUS_LINK_DOWN; 1091 1092 mm_indicate_link(pdev, pdev->vars.link_status, pdev->vars.medium); 1093 1094 MM_RELEASE_PHY_LOCK(pdev); 1095 1096 // write to the event log! 1097 mm_event_log_generic( pdev, LM_LOG_ID_FAN_FAILURE ); 1098 1099 mm_indicate_hw_failure(pdev); 1100 } 1101 1102 // Check current fan failure state - report in case signaled. 1103 void lm_check_fan_failure(struct _lm_device_t *pdev) 1104 { 1105 u32_t val = 0; 1106 1107 if (IS_VFDEV(pdev)) 1108 { 1109 return; 1110 } 1111 1112 val = REG_RD(pdev, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + PORT_ID(pdev)*4); 1113 1114 if( GET_FLAGS(val, AEU_INPUTS_ATTN_BITS_SPIO5)) 1115 { 1116 lm_spio5_attn_everest_processing(pdev); 1117 } 1118 } 1119 1120 // Change PMF or link change 1121 // PMF sent link updates to all func (but himself) OR I become a PMF from MCP notification 1122 // on some cases PMF sends link event to himself as well if errors occured in the mac. 1123 static void lm_pmf_or_link_event(lm_device_t *pdev, u32_t drv_status) 1124 { 1125 u32_t val = 0; 1126 1127 1128 DbgMessage(pdev, WARN, "lm_pmf_or_link_event: sync general attention received!!! for func%d\n",FUNC_ID(pdev)); 1129 1130 // sync with link 1131 MM_ACQUIRE_PHY_LOCK(pdev); 1132 elink_link_status_update(&pdev->params.link,&pdev->vars.link); 1133 lm_link_report(pdev); 1134 MM_RELEASE_PHY_LOCK(pdev); 1135 1136 if (!IS_PMF(pdev) && GET_FLAGS(drv_status,DRV_STATUS_PMF)) 1137 { 1138 //pmf migration 1139 pdev->vars.is_pmf = PMF_MIGRATION; 1140 // load stat from MCP 1141 MM_ACQUIRE_PHY_LOCK(pdev); 1142 lm_stats_on_pmf_update(pdev,TRUE); 1143 MM_RELEASE_PHY_LOCK(pdev); 1144 1145 // Connect to NIG attentions 1146 val = (0xff0f | (1 << (VNIC_ID(pdev) + 4))); 1147 if (INTR_BLK_TYPE(pdev) == INTR_BLK_HC) 1148 { 1149 REG_WR(pdev, (PORT_ID(pdev) ? HC_REG_TRAILING_EDGE_1 : HC_REG_TRAILING_EDGE_0), val); 1150 REG_WR(pdev, (PORT_ID(pdev) ? HC_REG_LEADING_EDGE_1 : HC_REG_LEADING_EDGE_0) , val); 1151 } 1152 else 1153 { 1154 if (CHIP_IS_E3(pdev)) 1155 { 1156 val &= ~ATTN_SW_TIMER_4_FUNC; // To prevent Timer4 expiration attention 1157 } 1158 REG_WR(pdev, IGU_REG_TRAILING_EDGE_LATCH, val); 1159 REG_WR(pdev, IGU_REG_LEADING_EDGE_LATCH, val); 1160 } 1161 1162 if(TRUE == IS_DCB_ENABLED(pdev)) 1163 { 1164 lm_dcbx_pmf_migration(pdev); 1165 } 1166 } 1167 } 1168 1169 static void lm_dcc_event(lm_device_t *pdev, u32_t dcc_event) 1170 { 1171 u32_t val = 0; 1172 u32_t event_val_current = 0; 1173 u32_t fw_resp = 0 ; 1174 lm_status_t lm_status = LM_STATUS_FAILURE ; 1175 1176 DbgMessage(pdev, WARN, "lm_dcc_event: dcc_event=0x%x\n",dcc_event); 1177 1178 if( !IS_MULTI_VNIC(pdev) ) 1179 { 1180 DbgBreakIf(1); 1181 return; 1182 } 1183 1184 // read shemem 1185 1186 // Read new mf config from shemem 1187 LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].config), &val); 1188 1189 pdev->hw_info.mf_info.func_mf_cfg = val ; 1190 1191 // is it enable/disable 1192 event_val_current = DRV_STATUS_DCC_DISABLE_ENABLE_PF ; 1193 1194 if GET_FLAGS( dcc_event, event_val_current ) 1195 { 1196 if( GET_FLAGS( pdev->hw_info.mf_info.func_mf_cfg, FUNC_MF_CFG_FUNC_DISABLED ) ) 1197 { 1198 DbgMessage(pdev, WARN, "lm_dcc_event: mf_cfg function disabled val=0x%x\n",val); 1199 1200 // TODO - receive packets fronm another machine when link is down - expected - miniport drop packets 1201 // TBD - disable RX & TX 1202 } 1203 else 1204 { 1205 DbgMessage(pdev, WARN, "lm_dcc_event: mf_cfg function enabled val=0x%x\n",val); 1206 // TBD - enable RX & TX 1207 } 1208 lm_status = LM_STATUS_SUCCESS ; 1209 RESET_FLAGS( dcc_event, event_val_current ); 1210 } 1211 1212 event_val_current = DRV_STATUS_DCC_BANDWIDTH_ALLOCATION ; 1213 1214 if GET_FLAGS(dcc_event, event_val_current) 1215 { 1216 if( !IS_PMF(pdev) ) 1217 { 1218 DbgBreakIf(1); 1219 return; 1220 } 1221 lm_status = LM_STATUS_SUCCESS ; 1222 RESET_FLAGS( dcc_event, event_val_current ); 1223 } 1224 1225 /* Report results to MCP */ 1226 if (dcc_event) 1227 { 1228 // unknown event 1229 lm_status = lm_mcp_cmd_send_recieve( pdev, lm_mcp_mb_header, DRV_MSG_CODE_DCC_FAILURE, 0, MCP_CMD_DEFAULT_TIMEOUT, &fw_resp ) ; 1230 } 1231 else 1232 { 1233 // we are done 1234 if( LM_STATUS_SUCCESS == lm_status ) 1235 { 1236 // sync with link --> update min max/link for all function 1237 MM_ACQUIRE_PHY_LOCK(pdev); 1238 elink_link_status_update(&pdev->params.link,&pdev->vars.link); 1239 lm_link_report(pdev); 1240 MM_RELEASE_PHY_LOCK(pdev); 1241 } 1242 lm_status = lm_mcp_cmd_send_recieve( pdev, lm_mcp_mb_header, DRV_MSG_CODE_DCC_OK, 0, MCP_CMD_DEFAULT_TIMEOUT, &fw_resp ) ; 1243 //bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); 1244 } 1245 DbgBreakIf( lm_status != LM_STATUS_SUCCESS ); 1246 } 1247 1248 static lm_status_t lm_set_bandwidth_event(lm_device_t *pdev) 1249 { 1250 u32_t mcp_resp = 0; 1251 lm_status_t lm_status = LM_STATUS_SUCCESS; 1252 1253 DbgBreakIf(!IS_SD_UFP_MODE(pdev) && (!IS_MULTI_VNIC(pdev) || !pdev->vars.is_pmf)); 1254 1255 MM_ACQUIRE_PHY_LOCK(pdev); 1256 1257 //update CMNG data from SHMEM 1258 lm_reload_link_and_cmng(pdev); 1259 1260 //acknoledge the MCP event 1261 lm_mcp_cmd_send_recieve(pdev,lm_mcp_mb_header, DRV_MSG_CODE_SET_MF_BW_ACK, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp); 1262 1263 if ( mcp_resp != FW_MSG_CODE_SET_MF_BW_DONE) 1264 { 1265 DbgBreakIf(mcp_resp != FW_MSG_CODE_SET_MF_BW_DONE); 1266 lm_status = LM_STATUS_FAILURE; 1267 goto _exit; 1268 } 1269 1270 //indicate link change to OS, since sync_link_status does not generate a link event for the PMF. 1271 mm_indicate_link(pdev, pdev->vars.link_status, pdev->vars.medium); 1272 1273 //notify all functions 1274 sync_link_status(pdev); 1275 1276 _exit: 1277 MM_RELEASE_PHY_LOCK(pdev); 1278 return lm_status; 1279 } 1280 1281 typedef enum drv_info_opcode drv_info_opcode_t; 1282 1283 lm_status_t lm_stats_drv_info_to_mfw_event( struct _lm_device_t* pdev ) 1284 { 1285 u32_t val = 0; 1286 u32_t drv_msg = 0; 1287 u32_t ver = 0; 1288 u32_t fw_resp = 0 ; 1289 lm_status_t lm_status = LM_STATUS_SUCCESS ; 1290 drv_info_opcode_t drv_info_op = -1; 1291 1292 if( !LM_SHMEM2_HAS(pdev, drv_info_control) ) 1293 { 1294 // We should never get here... 1295 DbgBreakIfAll(!LM_SHMEM2_HAS(pdev, drv_info_control)); 1296 return LM_STATUS_FAILURE; 1297 } 1298 1299 LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t, drv_info_control), &val ); 1300 1301 ver = ( GET_FLAGS( val, DRV_INFO_CONTROL_VER_MASK ) ) >> DRV_INFO_CONTROL_VER_SHIFT ; 1302 1303 do 1304 { 1305 if( DRV_INFO_CUR_VER != ver ) 1306 { 1307 // We don't support this interface verison 1308 drv_msg = DRV_MSG_CODE_DRV_INFO_NACK; 1309 break; 1310 } 1311 1312 drv_info_op = ( GET_FLAGS( val, DRV_INFO_CONTROL_OP_CODE_MASK ) ) >> DRV_INFO_CONTROL_OP_CODE_SHIFT; 1313 1314 lm_status = lm_stats_drv_info_to_mfw_assign(pdev, drv_info_op ); 1315 1316 if( LM_STATUS_SUCCESS != lm_status ) 1317 { 1318 // We don't support this interface verison/opcode 1319 drv_msg = DRV_MSG_CODE_DRV_INFO_NACK; 1320 break; 1321 } 1322 1323 LM_SHMEM2_WRITE(pdev, OFFSETOF(shmem2_region_t, drv_info_host_addr_lo), pdev->vars.stats.stats_collect.drv_info_to_mfw.drv_info_to_mfw_phys_addr.as_u32.low ); 1324 LM_SHMEM2_WRITE(pdev, OFFSETOF(shmem2_region_t, drv_info_host_addr_hi), pdev->vars.stats.stats_collect.drv_info_to_mfw.drv_info_to_mfw_phys_addr.as_u32.high ); 1325 1326 drv_msg = DRV_MSG_CODE_DRV_INFO_ACK; 1327 1328 } while(0); 1329 1330 lm_status = lm_mcp_cmd_send_recieve( pdev, lm_mcp_mb_header, drv_msg, 0, MCP_CMD_DEFAULT_TIMEOUT, &fw_resp ); 1331 1332 return lm_status; 1333 } 1334 1335 static lm_status_t lm_ufp_pf_disable(lm_device_t *pdev) 1336 { 1337 lm_status_t status = LM_STATUS_SUCCESS; 1338 u32_t mcp_resp = 0; 1339 1340 /*TODO: Have to do some processing based on fi the pF is enabled or disabled*/ 1341 ///indicate "link-down" 1342 MM_ACQUIRE_PHY_LOCK(pdev); 1343 1344 pdev->vars.link_status = LM_STATUS_LINK_DOWN; 1345 mm_indicate_link(pdev, pdev->vars.link_status, pdev->vars.medium); 1346 1347 MM_RELEASE_PHY_LOCK(pdev); 1348 1349 /* Report results to MCP */ 1350 ///ACK the MCP message 1351 if(status == LM_STATUS_SUCCESS) 1352 lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_OEM_OK, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp); 1353 else 1354 lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_OEM_FAILURE, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp); 1355 1356 DbgBreakIf(mcp_resp != FW_MSG_CODE_OEM_ACK); 1357 return status; 1358 } 1359 1360 static void lm_ufp_pf_enable(lm_device_t *pdev) 1361 { 1362 lm_status_t status = LM_STATUS_SUCCESS; 1363 u32_t mcp_resp = 0; 1364 struct function_update_data *data = LM_SLOWPATH(pdev, ufp_function_update_data); 1365 const lm_address_t data_phys = LM_SLOWPATH_PHYS(pdev, ufp_function_update_data); 1366 lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info; 1367 u32_t tag = 0; 1368 1369 //Reconfigure rate-limit 1370 MM_ACQUIRE_PHY_LOCK(pdev); 1371 lm_reload_link_and_cmng(pdev); 1372 MM_RELEASE_PHY_LOCK(pdev); 1373 1374 /* Other than vlan tag what are other UFP specific data? 1375 * Should we read the priority etc 1376 */ 1377 1378 /* get ovlan if we're in switch-dependent mode... */ 1379 LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].e1hov_tag),&tag); 1380 mf_info->ext_id = (u16_t)tag; 1381 pdev->params.ovlan = (u16_t)tag; 1382 1383 /* modify the NIG LLH registers */ 1384 init_nig_func(pdev); 1385 1386 DbgBreakIf(pdev->slowpath_info.ufp_func_ramrod_state != UFP_RAMROD_NOT_POSTED); 1387 1388 /* send function update ramrod to change the tag in the FW */ 1389 data->sd_vlan_tag_change_flg = TRUE; 1390 data->sd_vlan_tag = mm_cpu_to_le16((u16_t)tag); 1391 data->echo = FUNC_UPDATE_RAMROD_SOURCE_UFP; 1392 1393 status = lm_eq_ramrod_post_sync(pdev, 1394 RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 1395 data_phys.as_u64,CMD_PRIORITY_NORMAL, 1396 &pdev->slowpath_info.ufp_func_ramrod_state, 1397 UFP_RAMROD_PF_LINK_UPDATE_POSTED, 1398 UFP_RAMROD_COMPLETED); 1399 1400 /* Report results to MCP */ 1401 ///ACK the MCP message 1402 if(status == LM_STATUS_SUCCESS) 1403 lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_OEM_OK, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp); 1404 else 1405 lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_OEM_FAILURE, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp); 1406 1407 DbgBreakIf(mcp_resp != FW_MSG_CODE_OEM_ACK); 1408 1409 pdev->slowpath_info.ufp_func_ramrod_state = UFP_RAMROD_NOT_POSTED; 1410 } 1411 1412 static lm_status_t lm_oem_event(lm_device_t *pdev, u32_t event) 1413 { 1414 lm_status_t lm_status = LM_STATUS_SUCCESS; 1415 const u32_t offset = OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].config); 1416 u32_t config = 0; 1417 1418 DbgMessage(pdev, INFORM, "oem_event 0x%x\n", event); 1419 1420 ///read FUNC-DISABLED and FUNC-DELETED from func_mf_cfg 1421 LM_MFCFG_READ(pdev, offset, &config); 1422 pdev->hw_info.mf_info.func_mf_cfg = config ; 1423 1424 if (event & DRV_STATUS_OEM_DISABLE_ENABLE_PF) 1425 { 1426 if((config & FUNC_MF_CFG_FUNC_DISABLED) || (config & FUNC_MF_CFG_FUNC_DELETED)) 1427 { 1428 lm_status = lm_ufp_pf_disable(pdev); 1429 if (lm_status != LM_STATUS_SUCCESS) 1430 { 1431 DbgBreakIf(lm_status != LM_STATUS_SUCCESS); 1432 return lm_status; 1433 } 1434 } 1435 else 1436 { 1437 #ifdef EDIAG 1438 lm_ufp_pf_enable(pdev); 1439 #else 1440 lm_status = MM_REGISTER_LPME(pdev, lm_ufp_pf_enable, TRUE, TRUE); 1441 #endif 1442 if (lm_status != LM_STATUS_SUCCESS) 1443 { 1444 DbgBreakIf(lm_status != LM_STATUS_SUCCESS); 1445 return lm_status; 1446 } 1447 } 1448 } 1449 else if (event & DRV_STATUS_OEM_BANDWIDTH_ALLOCATION) 1450 { 1451 //lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info; 1452 1453 ///* get min/max bw */ 1454 //mf_info->min_bw[vnic] = (GET_FLAGS(config, FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT); 1455 //mf_info->max_bw[vnic] = (GET_FLAGS(config, FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT); 1456 1457 /* this function reads the bw configuration and does the necessary processing.. 1458 * only drawback is it reads the configuration for all the functions? 1459 *. todo check if we should be using this or not... 1460 */ 1461 lm_status = lm_set_bandwidth_event(pdev); 1462 if (lm_status != LM_STATUS_SUCCESS) 1463 { 1464 DbgBreakIf(lm_status != LM_STATUS_SUCCESS); 1465 return lm_status; 1466 } 1467 } 1468 1469 return lm_status; 1470 } 1471 1472 static void lm_update_svid(lm_device_t *pdev) 1473 { 1474 lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info; 1475 u32_t tag = 0; 1476 u32_t mcp_resp = 0; 1477 lm_status_t lm_status = LM_STATUS_SUCCESS; 1478 struct function_update_data *data = LM_SLOWPATH(pdev, ufp_function_update_data); 1479 const lm_address_t data_phys = LM_SLOWPATH_PHYS(pdev, ufp_function_update_data); 1480 1481 /* get ovlan if we're in switch-dependent mode... */ 1482 LM_MFCFG_READ(pdev, OFFSETOF(mf_cfg_t, func_mf_config[ABS_FUNC_ID(pdev)].e1hov_tag),&tag); 1483 mf_info->ext_id = (u16_t)tag; 1484 pdev->params.ovlan = (u16_t)tag; 1485 1486 /* modify the NIG LLH registers */ 1487 init_nig_func(pdev); 1488 1489 DbgBreakIf(pdev->slowpath_info.ufp_func_ramrod_state != UFP_RAMROD_NOT_POSTED); 1490 1491 /* send function update ramrod to change the tag in the FW */ 1492 data->sd_vlan_tag_change_flg = TRUE; 1493 data->sd_vlan_tag = mm_cpu_to_le16((u16_t)tag); 1494 data->echo = FUNC_UPDATE_RAMROD_SOURCE_UFP; 1495 1496 lm_status = lm_eq_ramrod_post_sync(pdev, 1497 RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 1498 data_phys.as_u64,CMD_PRIORITY_NORMAL, 1499 &pdev->slowpath_info.ufp_func_ramrod_state, 1500 UFP_RAMROD_PF_UPDATE_POSTED, 1501 UFP_RAMROD_COMPLETED); 1502 1503 /* Report results to MCP */ 1504 if(lm_status == LM_STATUS_SUCCESS) 1505 lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_OEM_UPDATE_SVID_OK, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp); 1506 else 1507 lm_mcp_cmd_send_recieve(pdev, lm_mcp_mb_header, DRV_MSG_CODE_OEM_UPDATE_SVID_FAILURE, 0, MCP_CMD_DEFAULT_TIMEOUT, &mcp_resp); 1508 1509 DbgBreakIf(mcp_resp != DRV_MSG_CODE_OEM_UPDATE_SVID_ACK); 1510 pdev->slowpath_info.ufp_func_ramrod_state = UFP_RAMROD_NOT_POSTED; 1511 } 1512 1513 #ifndef EDIAG 1514 static void lm_ufp_update_priority(lm_device_t *pdev) 1515 { 1516 lm_hardware_mf_info_t *mf_info = &pdev->hw_info.mf_info; 1517 u32_t new_priority = 0; 1518 u32_t mcp_resp = 0; 1519 lm_status_t lm_status = LM_STATUS_SUCCESS; 1520 struct function_update_data *data = LM_SLOWPATH(pdev, ufp_function_update_data); 1521 const lm_address_t data_phys = LM_SLOWPATH_PHYS(pdev, ufp_function_update_data); 1522 1523 DbgBreakIf(pdev->slowpath_info.ufp_func_ramrod_state != UFP_RAMROD_NOT_POSTED); 1524 1525 /* Todo get the priority from somewhere */ 1526 1527 /* send function update ramrod to change the tag in the FW */ 1528 data->sd_vlan_force_pri_change_flg = TRUE; 1529 data->sd_vlan_force_pri_flg = TRUE; 1530 //data->sd_vlan_force_pri_val = mm_cpu_to_le16((u16_t)new_priority); 1531 1532 data->echo = FUNC_UPDATE_RAMROD_SOURCE_UFP; 1533 1534 lm_status = lm_eq_ramrod_post_sync(pdev, 1535 RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 1536 data_phys.as_u64,CMD_PRIORITY_NORMAL, 1537 &pdev->slowpath_info.ufp_func_ramrod_state, 1538 UFP_RAMROD_PF_UPDATE_POSTED, 1539 UFP_RAMROD_COMPLETED); 1540 /*Todo Report results to mcp?*/ 1541 pdev->slowpath_info.ufp_func_ramrod_state = UFP_RAMROD_NOT_POSTED; 1542 } 1543 #endif 1544 1545 static lm_status_t lm_svid_event(lm_device_t *pdev) 1546 { 1547 lm_status_t lm_status = LM_STATUS_SUCCESS; 1548 #ifdef EDIAG 1549 lm_update_svid(pdev); 1550 #else 1551 lm_status = MM_REGISTER_LPME(pdev, lm_update_svid, TRUE, TRUE); 1552 #endif 1553 if (lm_status != LM_STATUS_SUCCESS) 1554 { 1555 DbgBreakIf(lm_status != LM_STATUS_SUCCESS); 1556 return lm_status; 1557 } 1558 1559 return lm_status; 1560 } 1561 1562 static void lm_generic_event(lm_device_t *pdev) 1563 { 1564 u32_t val = 0; 1565 u32_t offset = 0; // for debugging convenient 1566 u8_t call_pmf_or_link = FALSE; 1567 const u8_t func_id = FUNC_ID(pdev); 1568 1569 1570 offset = MISC_REG_AEU_GENERAL_ATTN_12 + 4*func_id; 1571 1572 // reset attention 1573 REG_WR(pdev, offset ,0x0); 1574 1575 offset = OFFSETOF(shmem_region_t, func_mb[FUNC_MAILBOX_ID(pdev)].drv_status) ; 1576 1577 // drv_status 1578 LM_SHMEM_READ(pdev, 1579 offset, 1580 &val); 1581 1582 // E1H NIG status sync attention mapped to group 4-7 1583 1584 if (GET_FLAGS( val, DRV_STATUS_VF_DISABLED)) 1585 { 1586 u32_t mcp_vf_disabled[E2_VF_MAX / 32] = {0}; 1587 u32_t i, fw_resp = 0; 1588 1589 // Read VFs 1590 for (i = 0; i < ARRSIZE(mcp_vf_disabled); i++) 1591 { 1592 LM_SHMEM2_READ(pdev, OFFSETOF(shmem2_region_t,mcp_vf_disabled[i]), &mcp_vf_disabled[i]); 1593 } 1594 DbgMessage(pdev, FATAL, "lm_generic_event: DRV_STATUS_VF_DISABLED received for vfs bitmap %x %x!!!\n", mcp_vf_disabled[0], mcp_vf_disabled[1]); 1595 1596 // SHMULIK, PLACE YOUR CODE HERE ( Handle only VFs of this PF ) 1597 1598 // Acknoledge the VFs you handled ( This array is per PF driver on path ) 1599 for (i = 0; i < ARRSIZE(mcp_vf_disabled) ; i++) 1600 { 1601 LM_SHMEM2_WRITE(pdev, OFFSETOF(shmem2_region_t,drv_ack_vf_disabled[FUNC_MAILBOX_ID(pdev)][i]), mcp_vf_disabled[i]); 1602 } 1603 lm_mcp_cmd_send_recieve( pdev, 1604 lm_mcp_mb_header, 1605 DRV_MSG_CODE_VF_DISABLED_DONE, 1606 0, 1607 MCP_CMD_DEFAULT_TIMEOUT, 1608 &fw_resp); 1609 return; // YANIV - DEBUG @@@!!! 1610 } 1611 if(IS_MULTI_VNIC(pdev)) 1612 { 1613 if( GET_FLAGS( val, DRV_STATUS_DCC_EVENT_MASK ) ) 1614 { 1615 lm_dcc_event(pdev, (DRV_STATUS_DCC_EVENT_MASK & val) ); 1616 } 1617 1618 if (GET_FLAGS(val, DRV_STATUS_SET_MF_BW )) 1619 { 1620 lm_set_bandwidth_event(pdev); 1621 } 1622 1623 //if val has any NIV event flags, call lm_niv_event 1624 if ( GET_FLAGS(val, DRV_STATUS_AFEX_EVENT_MASK) ) 1625 { 1626 lm_niv_event(pdev, GET_FLAGS(val, DRV_STATUS_AFEX_EVENT_MASK) ); 1627 } 1628 } 1629 1630 if GET_FLAGS(val, DRV_STATUS_DRV_INFO_REQ) 1631 { 1632 lm_stats_drv_info_to_mfw_event(pdev); 1633 } 1634 1635 // NOTE: 1636 // once we have events such as DCC and NIV, this condition doesn't stand anymore 1637 // we might get here TRUE although we are in MULTI_VNIC AND we are not PMF 1638 // and this is not for link change or pmf migration 1639 // the potential problem (redundant link report to OS CQ60223) 1640 // is resolved in "lm_link_report" function that check current link 1641 // with previous reported link 1642 1643 /* Check if pmf or link event function should be called: */ 1644 call_pmf_or_link = IS_MULTI_VNIC(pdev) && !pdev->vars.is_pmf; 1645 1646 1647 /* PMF or link event */ 1648 if (GET_FLAGS(pdev->vars.link.periodic_flags, ELINK_PERIODIC_FLAGS_LINK_EVENT)) 1649 { 1650 DbgMessage(pdev, WARN, "lm_generic_event: ELINK_PERIODIC_FLAGS_LINK_EVENT func_id=%d!!!\n", func_id ); 1651 1652 /* sync with link */ 1653 MM_ACQUIRE_PHY_LOCK_DPC(pdev); 1654 RESET_FLAGS(pdev->vars.link.periodic_flags, ELINK_PERIODIC_FLAGS_LINK_EVENT); 1655 MM_RELEASE_PHY_LOCK_DPC(pdev); 1656 1657 call_pmf_or_link = TRUE; 1658 } 1659 1660 if(call_pmf_or_link) 1661 { 1662 lm_pmf_or_link_event(pdev, val); 1663 } 1664 1665 if GET_FLAGS(val, DRV_STATUS_OEM_EVENT_MASK) 1666 { 1667 lm_oem_event(pdev, val); 1668 } 1669 1670 if GET_FLAGS(val, DRV_STATUS_OEM_UPDATE_SVID) 1671 { 1672 lm_svid_event(pdev); 1673 } 1674 1675 lm_dcbx_event(pdev,val); 1676 } 1677 1678 static void lm_gen_attn_everest_processing(lm_device_t *pdev, u32_t sig_word_aft_inv) 1679 { 1680 u32_t offset = 0; // for debugging convenient 1681 u32_t val = 0; 1682 1683 //pass over all attention generals which are wired to a dynamic group of the lower 8 bits 1684 offset = GENERAL_ATTEN_OFFSET(TSTORM_FATAL_ASSERT_ATTENTION_BIT) ; 1685 if ( offset & sig_word_aft_inv) 1686 { 1687 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_7,0x0); 1688 DbgMessage(pdev, FATAL, "lm_gen_attn_everest_processing: TSTORM_FATAL_ASSERT_ATTENTION_BIT received!!!\n"); 1689 DbgBreakIfAll(1); 1690 } 1691 offset = GENERAL_ATTEN_OFFSET(USTORM_FATAL_ASSERT_ATTENTION_BIT); 1692 if ( offset & sig_word_aft_inv) 1693 { 1694 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_8,0x0); 1695 DbgMessage(pdev, FATAL, "lm_gen_attn_everest_processing: USTORM_FATAL_ASSERT_ATTENTION_BIT received!!!\n"); 1696 DbgBreakIfAll(1); 1697 } 1698 offset = GENERAL_ATTEN_OFFSET(CSTORM_FATAL_ASSERT_ATTENTION_BIT); 1699 if ( offset & sig_word_aft_inv) 1700 { 1701 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_9,0x0); 1702 DbgMessage(pdev, FATAL, "lm_gen_attn_everest_processing: CSTORM_FATAL_ASSERT_ATTENTION_BIT received!!!\n"); 1703 DbgBreakIfAll(1); 1704 } 1705 offset = GENERAL_ATTEN_OFFSET(XSTORM_FATAL_ASSERT_ATTENTION_BIT); 1706 if ( offset & sig_word_aft_inv) 1707 { 1708 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_10,0x0); 1709 DbgMessage(pdev, FATAL, "lm_gen_attn_everest_processing: XSTORM_FATAL_ASSERT_ATTENTION_BIT received!!!\n"); 1710 DbgBreakIfAll(1); 1711 } 1712 offset = GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT); 1713 if ( offset & sig_word_aft_inv) 1714 { 1715 REG_WR(pdev,MISC_REG_AEU_GENERAL_ATTN_11,0x0); 1716 val = lm_mcp_check(pdev); 1717 DbgMessage(pdev, FATAL, "lm_gen_attn_everest_processing: MCP_FATAL_ASSERT_ATTENTION_BIT received mcp_check=0x%x!!!\n" , val); 1718 DbgBreakIfAll(1); 1719 } 1720 // E1H NIG status sync attention mapped to group 4-7 1721 if (!CHIP_IS_E1(pdev)) 1722 { 1723 // PMF change or link update 1724 offset = GENERAL_ATTEN_OFFSET(LINK_SYNC_ATTENTION_BIT_FUNC_0 + FUNC_ID(pdev)); 1725 1726 if ( offset & sig_word_aft_inv) 1727 { 1728 lm_generic_event(pdev); 1729 } 1730 } 1731 } 1732 1733 void lm_read_attn_regs(lm_device_t *pdev, u32_t * attn_sig_af_inv_arr, u32_t arr_size) 1734 { 1735 u8_t i; 1736 DbgBreakIf( pdev->vars.num_attn_sig_regs > arr_size ); 1737 DbgBreakIf( pdev->vars.num_attn_sig_regs > ARRSIZE(pdev->vars.attn_sig_af_inv_reg_addr) ); 1738 1739 //Read the 128 attn signals bits after inverter 1740 for (i = 0; i < pdev->vars.num_attn_sig_regs; i++) 1741 { 1742 attn_sig_af_inv_arr[i] = REG_RD(pdev, pdev->vars.attn_sig_af_inv_reg_addr[i]); 1743 } 1744 1745 DbgMessage(pdev, INFORM, "lm_handle_deassertion_processing: attn_sig_aft_invert_1:0x%x; attn_sig_aft_invert_2:0x%x; attn_sig_aft_invert_3:0x%x; attn_sig_aft_invert_4:0x%x,attn_sig_aft_invert_5:0x%x\n", 1746 attn_sig_af_inv_arr[0], 1747 attn_sig_af_inv_arr[1], 1748 attn_sig_af_inv_arr[2], 1749 attn_sig_af_inv_arr[3], 1750 attn_sig_af_inv_arr[4]); 1751 } 1752 1753 1754 1755 void lm_get_attn_info(lm_device_t *pdev, u16_t *attn_bits, u16_t *attn_ack) 1756 { 1757 volatile struct atten_sp_status_block * attention_sb = NULL; 1758 u16_t lcl_attn_sb_index = 0; 1759 1760 DbgBreakIf(!(pdev && attn_bits && attn_ack)); 1761 1762 attention_sb = lm_get_attention_status_block(pdev); 1763 1764 //guard against dynamic change of attn lines - 15 interations max 1765 //the main idea here is to assure that we work on synchronized snapshots of the attn_bits and 1766 //attn_ack and avoid a faulty scenario where attn_ack we read in sanpshot #2 corresponds to attn_bits 1767 //of snapshot #1 which occured on different time frames. 1768 do 1769 { 1770 lcl_attn_sb_index = mm_le16_to_cpu(attention_sb->attn_bits_index); 1771 *attn_bits = (u16_t)mm_le32_to_cpu(attention_sb->attn_bits); 1772 *attn_ack = (u16_t)mm_le32_to_cpu(attention_sb->attn_bits_ack); 1773 1774 } while (lcl_attn_sb_index != mm_le16_to_cpu(attention_sb->attn_bits_index)); 1775 //the lcl_attn_sb_index differs from the real local attn_index in the pdev since in this while loop it could 1776 //have been changed, we don't save it locally, and thus we will definitely receive an interrupt in case the 1777 //while condition is met. 1778 1779 DbgMessage(pdev, 1780 INFORMi, 1781 "lm_get_attn_info: def_sb->attn_bits:0x%x, def_sb->attn_ack:0x%x, attn_bits:0x%x, attn_ack:0x%x\n", 1782 mm_le32_to_cpu(attention_sb->attn_bits), 1783 mm_le32_to_cpu(attention_sb->attn_bits_ack), 1784 *attn_bits, 1785 *attn_ack); 1786 } 1787 1788 1789 static u32_t lm_dq_attn_everest_processing(lm_device_t *pdev) 1790 { 1791 u32_t val,valc; 1792 val=REG_RD(pdev,DORQ_REG_DORQ_INT_STS); 1793 // TODO add defines here 1794 DbgMessage(pdev, FATAL, "DB hw attention 0x%x\n",val); 1795 if (val) { 1796 pdev->vars.dq_int_status_cnt++; 1797 if (val & DORQ_DORQ_INT_STS_REG_DB_DISCARD) 1798 { 1799 // DORQ discard attention 1800 pdev->vars.dq_int_status_discard_cnt++;//DbgBreakIfAll(1); 1801 } 1802 if (val & DORQ_DORQ_INT_STS_REG_TYPE_VAL_ERR) 1803 { 1804 // DORQ discard attention 1805 pdev->vars.dq_int_status_vf_val_err_cnt++;//DbgBreakIfAll(1); 1806 pdev->vars.dq_vf_type_val_err_fid = REG_RD(pdev,DORQ_REG_VF_TYPE_VAL_ERR_FID); 1807 pdev->vars.dq_vf_type_val_err_mcid = REG_RD(pdev,DORQ_REG_VF_TYPE_VAL_ERR_MCID); 1808 } 1809 } 1810 valc = REG_RD(pdev,DORQ_REG_DORQ_INT_STS_CLR); 1811 return val; 1812 } 1813 1814 void lm_handle_deassertion_processing(lm_device_t *pdev, u16_t deassertion_proc_flgs) 1815 { 1816 lm_status_t lm_status = LM_STATUS_SUCCESS; 1817 u32_t val = 0; 1818 u32_t port_reg_name = 0; 1819 u8_t index = 0; 1820 u8_t i = 0; 1821 u32_t mask_val = 0; 1822 u32_t attn_sig_af_inv_arr[MAX_ATTN_REGS] = {0}; 1823 u32_t group_mask_arr[MAX_ATTN_REGS] = {0}; 1824 u32_t mask_arr_val[MAX_ATTN_REGS] = {0}; 1825 u32_t dq_int_sts, cfc_int_sts; 1826 1827 DbgBreakIf(!pdev); 1828 DbgMessage(pdev, INFORM, "lm_handle_deassertion_processing: deassertion_proc_flgs:%d\n", deassertion_proc_flgs); 1829 1830 1831 //acquire split lock for attention signals handling 1832 acquire_split_alr(pdev); 1833 1834 lm_read_attn_regs(pdev, attn_sig_af_inv_arr, ARRSIZE(attn_sig_af_inv_arr)); 1835 1836 if (lm_recoverable_error(pdev, attn_sig_af_inv_arr,ARRSIZE(attn_sig_af_inv_arr))) 1837 { 1838 DbgMessage(pdev, WARNer, "Starting lm recover flow "); 1839 lm_status = mm_er_initiate_recovery(pdev); 1840 if (lm_status == LM_STATUS_SUCCESS) 1841 { 1842 /* Continue only on success... */ 1843 /* Disable HW interrupts */ 1844 lm_disable_int(pdev); 1845 1846 release_split_alr(pdev); 1847 /* In case of recoverable error don't handle attention so that 1848 * other functions get this parity as well. 1849 */ 1850 return; 1851 } 1852 DbgMessage(pdev, WARNer, "mm_er_initiate_recovery returned status %d ", lm_status); 1853 1854 /* Recovery failed... we'll keep going, and eventually hit 1855 * the attnetion and assert... 1856 */ 1857 } 1858 1859 //For all deasserted groups, pass over entire attn_bits after inverter and if they 1860 // are members of that particular gruop, treat each one of them accordingly. 1861 for (index = 0; index < ARRSIZE(pdev->vars.attn_groups_output); index++) 1862 { 1863 if (deassertion_proc_flgs & (1 << index)) 1864 { 1865 for (i = 0; i < ARRSIZE(group_mask_arr); i++) 1866 { 1867 group_mask_arr[i] = pdev->vars.attn_groups_output[index].attn_sig_dword[i]; 1868 } 1869 1870 DbgMessage(pdev, WARN, "lm_handle_deassertion_processing: group #%d got attention on it!\n", index); 1871 DbgMessage(pdev, WARN, "lm_handle_deassertion_processing: mask1:0x%x, mask2:0x%x, mask3:0x%x, mask4:0x%x,mask5:0x%x\n", 1872 group_mask_arr[0], 1873 group_mask_arr[1], 1874 group_mask_arr[2], 1875 group_mask_arr[3], 1876 group_mask_arr[4]); 1877 DbgMessage(pdev, WARN, "lm_handle_deassertion_processing: attn1:0x%x, attn2:0x%x, attn3:0x%x, attn4:0x%x,attn5:0x%x\n", 1878 attn_sig_af_inv_arr[0], 1879 attn_sig_af_inv_arr[1], 1880 attn_sig_af_inv_arr[2], 1881 attn_sig_af_inv_arr[3], 1882 attn_sig_af_inv_arr[4]); 1883 1884 if (attn_sig_af_inv_arr[3] & EVEREST_GEN_ATTN_IN_USE_MASK & group_mask_arr[3]) 1885 { 1886 lm_gen_attn_everest_processing(pdev, attn_sig_af_inv_arr[3]); 1887 } 1888 1889 // DQ attn 1890 if (attn_sig_af_inv_arr[1] & AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT & group_mask_arr[1]) 1891 { 1892 dq_int_sts = lm_dq_attn_everest_processing(pdev); 1893 } 1894 // CFC attn 1895 if (attn_sig_af_inv_arr[2] & AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT & group_mask_arr[2]) 1896 { 1897 cfc_int_sts = lm_cfc_attn_everest_processing(pdev); 1898 } 1899 // PXP attn 1900 if (attn_sig_af_inv_arr[2] & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT & group_mask_arr[2]) 1901 { 1902 lm_pxp_attn_everest_processing(pdev); 1903 } 1904 // SPIO 5 bit in register 0 1905 if (attn_sig_af_inv_arr[0] & AEU_INPUTS_ATTN_BITS_SPIO5 & group_mask_arr[0]) 1906 { 1907 lm_spio5_attn_everest_processing(pdev); 1908 } 1909 1910 // GPIO3 bits in register 0 1911 if (attn_sig_af_inv_arr[0] & pdev->vars.link.aeu_int_mask & group_mask_arr[0]) 1912 { 1913 // Handle it only for PMF 1914 if (IS_PMF(pdev)) 1915 { 1916 MM_ACQUIRE_PHY_LOCK(pdev); 1917 PHY_HW_LOCK(pdev); 1918 elink_handle_module_detect_int(&pdev->params.link); 1919 PHY_HW_UNLOCK(pdev); 1920 MM_RELEASE_PHY_LOCK(pdev); 1921 } 1922 } 1923 1924 //TODO: attribute each attention signal arrived and which is a member of a group and give it its own 1925 // specific treatment. later, for each attn, do "clean the hw block" via the INT_STS_CLR. 1926 1927 //Check for lattched attn signals 1928 if (attn_sig_af_inv_arr[3] & EVEREST_LATCHED_ATTN_IN_USE_MASK & group_mask_arr[3]) 1929 { 1930 lm_latch_attn_everest_processing(pdev, attn_sig_af_inv_arr[3]); 1931 } 1932 1933 // general hw block attention 1934 i = 0; 1935 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_INTERRUT_ASSERT_SET_0 & group_mask_arr[i]; 1936 i = 1; 1937 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_INTERRUT_ASSERT_SET_1 & group_mask_arr[i]; 1938 i = 2; 1939 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_INTERRUT_ASSERT_SET_2 & group_mask_arr[i]; 1940 i = 4; 1941 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_INTERRUT_ASSERT_SET_4 & group_mask_arr[i]; 1942 1943 if (mask_arr_val[2] & AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { 1944 pdev->vars.pxp_hw_interrupts_cnt++; 1945 } 1946 1947 if ( (mask_arr_val[0]) || 1948 (mask_arr_val[1] & ~AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT) || 1949 (mask_arr_val[2] & ~(AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT | AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT)) || 1950 (mask_arr_val[4]) ) 1951 { 1952 DbgMessage(pdev, FATAL, "hw block attention:\n"); 1953 DbgMessage(pdev, FATAL, "0: 0x%08x\n", mask_arr_val[0]); 1954 DbgMessage(pdev, FATAL, "1: 0x%08x\n", mask_arr_val[1]); 1955 DbgMessage(pdev, FATAL, "2: 0x%08x\n", mask_arr_val[2]); 1956 DbgMessage(pdev, FATAL, "4: 0x%08x\n", mask_arr_val[4]); 1957 DbgBreakIfAll(1); 1958 } 1959 // general hw block mem prty 1960 i = 0; 1961 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_PRTY_ASSERT_SET_0 & group_mask_arr[i]; 1962 i = 1; 1963 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_PRTY_ASSERT_SET_1 & group_mask_arr[i]; 1964 i = 2; 1965 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_PRTY_ASSERT_SET_2 & group_mask_arr[i]; 1966 i = 4; 1967 mask_arr_val[i] = attn_sig_af_inv_arr[i] & HW_PRTY_ASSERT_SET_4 & group_mask_arr[i]; 1968 1969 if ( (mask_arr_val[0]) || 1970 (mask_arr_val[1]) || 1971 (mask_arr_val[2]) || 1972 (mask_arr_val[4]) ) 1973 { 1974 DbgMessage(pdev, FATAL, "hw block parity attention\n"); 1975 DbgMessage(pdev, FATAL, "0: 0x%08x\n", mask_arr_val[0]); 1976 DbgMessage(pdev, FATAL, "1: 0x%08x\n", mask_arr_val[1]); 1977 DbgMessage(pdev, FATAL, "2: 0x%08x\n", mask_arr_val[2]); 1978 DbgMessage(pdev, FATAL, "4: 0x%08x\n", mask_arr_val[4]); 1979 DbgBreakIfAll(1); 1980 } 1981 } 1982 } 1983 1984 //release split lock 1985 release_split_alr(pdev); 1986 1987 //TODO: the attn_ack bits to clear must be passed with '0' 1988 //val = deassertion_proc_flgs; 1989 val = ~deassertion_proc_flgs; 1990 // attntion bits clear 1991 if (INTR_BLK_TYPE(pdev) == INTR_BLK_HC) 1992 { 1993 REG_WR(pdev, HC_REG_COMMAND_REG + PORT_ID(pdev)*32 + COMMAND_REG_ATTN_BITS_CLR,val); 1994 } 1995 else 1996 { 1997 u32_t cmd_addr = IGU_CMD_ATTN_BIT_CLR_UPPER; 1998 1999 if (INTR_BLK_ACCESS(pdev) == INTR_BLK_ACCESS_IGUMEM) 2000 { 2001 REG_WR(pdev, BAR_IGU_INTMEM + cmd_addr*8, val); 2002 } 2003 else 2004 { 2005 struct igu_ctrl_reg cmd_ctrl; 2006 u8_t igu_func_id = 0; 2007 2008 /* GRC ACCESS: */ 2009 /* Write the Data, then the control */ 2010 /* [18:12] - FID (if VF - [18] = 0; [17:12] = VF number; if PF - [18] = 1; [17:14] = 0; [13:12] = PF number) */ 2011 igu_func_id = IGU_FUNC_ID(pdev); 2012 cmd_ctrl.ctrl_data = 2013 ((cmd_addr << IGU_CTRL_REG_ADDRESS_SHIFT) | 2014 (igu_func_id << IGU_CTRL_REG_FID_SHIFT) | 2015 (IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT)); 2016 2017 REG_WR(pdev, IGU_REG_COMMAND_REG_32LSB_DATA, val); 2018 REG_WR(pdev, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl.ctrl_data); 2019 } 2020 } 2021 2022 //unmask only appropriate attention output signals from configured routing and unifier logic toward IGU. 2023 //This is for driver/chip sync to eventually return to '00' monitored state 2024 //in both leading & trailing latch. 2025 //unmask non-hard-wired dynamic groups only 2026 2027 DbgBreakIf(~pdev->vars.attn_state & deassertion_proc_flgs); 2028 2029 //unmask relevant AEU attn lines 2030 // mask deassert_flgs new mask 2031 //legal: 0 0 -> 0 2032 // 0 1 -> 1 2033 // 1 0 -> 1 2034 //ASSERT: 1 1 -> this won't change us thanks to the | 2035 2036 port_reg_name = PORT_ID(pdev) ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : MISC_REG_AEU_MASK_ATTN_FUNC_0; 2037 2038 lm_hw_lock(pdev, HW_LOCK_RESOURCE_PORT0_ATT_MASK + PORT_ID(pdev), TRUE); 2039 2040 mask_val = REG_RD(pdev, port_reg_name); 2041 2042 pdev->vars.aeu_mask_attn_func = mask_val & 0xff; 2043 2044 DbgMessage(pdev, INFORM, "lm_handle_deassertion_processing: BEFORE: aeu_mask_attn_func:0x%x\n", pdev->vars.aeu_mask_attn_func); 2045 //changed from XOR to OR for safely 2046 pdev->vars.aeu_mask_attn_func |= (deassertion_proc_flgs & 0xff); 2047 2048 DbgMessage(pdev, INFORM, "lm_handle_deassertion_processing: AFTER : aeu_mask_attn_func:0x%x\n", pdev->vars.aeu_mask_attn_func); 2049 2050 REG_WR(pdev, port_reg_name, pdev->vars.aeu_mask_attn_func); 2051 lm_hw_unlock(pdev, HW_LOCK_RESOURCE_PORT0_ATT_MASK + PORT_ID(pdev)); 2052 //update the attn bits states 2053 // state deassert_flgs new state 2054 //legal: 0 0 -> 0 2055 // 1 0 -> 1 2056 // 1 1 -> 0 2057 //ASSERT: 0 1 -> this won't change our state thanks to & ~ ! 2058 DbgMessage(pdev, INFORM, "lm_handle_deassertion_processing: BEFORE: attn_state:0x%x\n", pdev->vars.attn_state); 2059 2060 //changed from XOR to : AND ~ for safety 2061 pdev->vars.attn_state &= ~deassertion_proc_flgs; 2062 2063 DbgMessage(pdev, INFORM, "lm_handle_deassertion_processing: AFTER : attn_state:0x%x\n", pdev->vars.attn_state); 2064 } 2065