164#if EFSYS_OPT_SIENA 165 case EFX_FAMILY_SIENA: 166 eiop = (efx_intr_ops_t *)&__efx_intr_siena_ops; 167 break; 168#endif /* EFSYS_OPT_SIENA */ 169 170#if EFSYS_OPT_HUNTINGTON 171 case EFX_FAMILY_HUNTINGTON: 172 eiop = (efx_intr_ops_t *)&__efx_intr_ef10_ops; 173 break; 174#endif /* EFSYS_OPT_HUNTINGTON */ 175 176#if EFSYS_OPT_MEDFORD 177 case EFX_FAMILY_MEDFORD: 178 eiop = (efx_intr_ops_t *)&__efx_intr_ef10_ops; 179 break; 180#endif /* EFSYS_OPT_MEDFORD */ 181 182 default: 183 EFSYS_ASSERT(B_FALSE); 184 rc = ENOTSUP; 185 goto fail2; 186 } 187 188 if ((rc = eiop->eio_init(enp, type, esmp)) != 0) 189 goto fail3; 190 191 eip->ei_eiop = eiop; 192 193 return (0); 194 195fail3: 196 EFSYS_PROBE(fail3); 197fail2: 198 EFSYS_PROBE(fail2); 199fail1: 200 EFSYS_PROBE1(fail1, efx_rc_t, rc); 201 202 return (rc); 203} 204 205 void 206efx_intr_fini( 207 __in efx_nic_t *enp) 208{ 209 efx_intr_t *eip = &(enp->en_intr); 210 efx_intr_ops_t *eiop = eip->ei_eiop; 211 212 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 213 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 214 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 215 216 eiop->eio_fini(enp); 217 218 enp->en_mod_flags &= ~EFX_MOD_INTR; 219} 220 221 void 222efx_intr_enable( 223 __in efx_nic_t *enp) 224{ 225 efx_intr_t *eip = &(enp->en_intr); 226 efx_intr_ops_t *eiop = eip->ei_eiop; 227 228 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 229 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 230 231 eiop->eio_enable(enp); 232} 233 234 void 235efx_intr_disable( 236 __in efx_nic_t *enp) 237{ 238 efx_intr_t *eip = &(enp->en_intr); 239 efx_intr_ops_t *eiop = eip->ei_eiop; 240 241 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 242 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 243 244 eiop->eio_disable(enp); 245} 246 247 void 248efx_intr_disable_unlocked( 249 __in efx_nic_t *enp) 250{ 251 efx_intr_t *eip = &(enp->en_intr); 252 efx_intr_ops_t *eiop = eip->ei_eiop; 253 254 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 255 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 256 257 eiop->eio_disable_unlocked(enp); 258} 259 260 261 __checkReturn efx_rc_t 262efx_intr_trigger( 263 __in efx_nic_t *enp, 264 __in unsigned int level) 265{ 266 efx_intr_t *eip = &(enp->en_intr); 267 efx_intr_ops_t *eiop = eip->ei_eiop; 268 269 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 270 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 271 272 return (eiop->eio_trigger(enp, level)); 273} 274 275 void 276efx_intr_status_line( 277 __in efx_nic_t *enp, 278 __out boolean_t *fatalp, 279 __out uint32_t *qmaskp) 280{ 281 efx_intr_t *eip = &(enp->en_intr); 282 efx_intr_ops_t *eiop = eip->ei_eiop; 283 284 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 285 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 286 287 eiop->eio_status_line(enp, fatalp, qmaskp); 288} 289 290 void 291efx_intr_status_message( 292 __in efx_nic_t *enp, 293 __in unsigned int message, 294 __out boolean_t *fatalp) 295{ 296 efx_intr_t *eip = &(enp->en_intr); 297 efx_intr_ops_t *eiop = eip->ei_eiop; 298 299 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 300 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 301 302 eiop->eio_status_message(enp, message, fatalp); 303} 304 305 void 306efx_intr_fatal( 307 __in efx_nic_t *enp) 308{ 309 efx_intr_t *eip = &(enp->en_intr); 310 efx_intr_ops_t *eiop = eip->ei_eiop; 311 312 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 313 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 314 315 eiop->eio_fatal(enp); 316} 317 318 319/* ************************************************************************* */ 320/* ************************************************************************* */ 321/* ************************************************************************* */ 322
| 144#if EFSYS_OPT_SIENA 145 case EFX_FAMILY_SIENA: 146 eiop = (efx_intr_ops_t *)&__efx_intr_siena_ops; 147 break; 148#endif /* EFSYS_OPT_SIENA */ 149 150#if EFSYS_OPT_HUNTINGTON 151 case EFX_FAMILY_HUNTINGTON: 152 eiop = (efx_intr_ops_t *)&__efx_intr_ef10_ops; 153 break; 154#endif /* EFSYS_OPT_HUNTINGTON */ 155 156#if EFSYS_OPT_MEDFORD 157 case EFX_FAMILY_MEDFORD: 158 eiop = (efx_intr_ops_t *)&__efx_intr_ef10_ops; 159 break; 160#endif /* EFSYS_OPT_MEDFORD */ 161 162 default: 163 EFSYS_ASSERT(B_FALSE); 164 rc = ENOTSUP; 165 goto fail2; 166 } 167 168 if ((rc = eiop->eio_init(enp, type, esmp)) != 0) 169 goto fail3; 170 171 eip->ei_eiop = eiop; 172 173 return (0); 174 175fail3: 176 EFSYS_PROBE(fail3); 177fail2: 178 EFSYS_PROBE(fail2); 179fail1: 180 EFSYS_PROBE1(fail1, efx_rc_t, rc); 181 182 return (rc); 183} 184 185 void 186efx_intr_fini( 187 __in efx_nic_t *enp) 188{ 189 efx_intr_t *eip = &(enp->en_intr); 190 efx_intr_ops_t *eiop = eip->ei_eiop; 191 192 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 193 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 194 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 195 196 eiop->eio_fini(enp); 197 198 enp->en_mod_flags &= ~EFX_MOD_INTR; 199} 200 201 void 202efx_intr_enable( 203 __in efx_nic_t *enp) 204{ 205 efx_intr_t *eip = &(enp->en_intr); 206 efx_intr_ops_t *eiop = eip->ei_eiop; 207 208 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 209 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 210 211 eiop->eio_enable(enp); 212} 213 214 void 215efx_intr_disable( 216 __in efx_nic_t *enp) 217{ 218 efx_intr_t *eip = &(enp->en_intr); 219 efx_intr_ops_t *eiop = eip->ei_eiop; 220 221 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 222 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 223 224 eiop->eio_disable(enp); 225} 226 227 void 228efx_intr_disable_unlocked( 229 __in efx_nic_t *enp) 230{ 231 efx_intr_t *eip = &(enp->en_intr); 232 efx_intr_ops_t *eiop = eip->ei_eiop; 233 234 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 235 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 236 237 eiop->eio_disable_unlocked(enp); 238} 239 240 241 __checkReturn efx_rc_t 242efx_intr_trigger( 243 __in efx_nic_t *enp, 244 __in unsigned int level) 245{ 246 efx_intr_t *eip = &(enp->en_intr); 247 efx_intr_ops_t *eiop = eip->ei_eiop; 248 249 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 250 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 251 252 return (eiop->eio_trigger(enp, level)); 253} 254 255 void 256efx_intr_status_line( 257 __in efx_nic_t *enp, 258 __out boolean_t *fatalp, 259 __out uint32_t *qmaskp) 260{ 261 efx_intr_t *eip = &(enp->en_intr); 262 efx_intr_ops_t *eiop = eip->ei_eiop; 263 264 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 265 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 266 267 eiop->eio_status_line(enp, fatalp, qmaskp); 268} 269 270 void 271efx_intr_status_message( 272 __in efx_nic_t *enp, 273 __in unsigned int message, 274 __out boolean_t *fatalp) 275{ 276 efx_intr_t *eip = &(enp->en_intr); 277 efx_intr_ops_t *eiop = eip->ei_eiop; 278 279 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 280 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 281 282 eiop->eio_status_message(enp, message, fatalp); 283} 284 285 void 286efx_intr_fatal( 287 __in efx_nic_t *enp) 288{ 289 efx_intr_t *eip = &(enp->en_intr); 290 efx_intr_ops_t *eiop = eip->ei_eiop; 291 292 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 293 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 294 295 eiop->eio_fatal(enp); 296} 297 298 299/* ************************************************************************* */ 300/* ************************************************************************* */ 301/* ************************************************************************* */ 302
|
324 325static __checkReturn efx_rc_t 326falconsiena_intr_init( 327 __in efx_nic_t *enp, 328 __in efx_intr_type_t type, 329 __in efsys_mem_t *esmp) 330{ 331 efx_intr_t *eip = &(enp->en_intr); 332 efx_oword_t oword; 333 334 /* 335 * bug17213 workaround. 336 * 337 * Under legacy interrupts, don't share a level between fatal 338 * interrupts and event queue interrupts. Under MSI-X, they 339 * must share, or we won't get an interrupt. 340 */ 341 if (enp->en_family == EFX_FAMILY_SIENA && 342 eip->ei_type == EFX_INTR_LINE) 343 eip->ei_level = 0x1f; 344 else 345 eip->ei_level = 0; 346 347 /* Enable all the genuinely fatal interrupts */ 348 EFX_SET_OWORD(oword); 349 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0); 350 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0); 351 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0); 352 if (enp->en_family >= EFX_FAMILY_SIENA) 353 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0); 354 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword); 355 356 /* Set up the interrupt address register */ 357 EFX_POPULATE_OWORD_3(oword, 358 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0, 359 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff, 360 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32); 361 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 362 363 return (0); 364} 365 366static void 367falconsiena_intr_enable( 368 __in efx_nic_t *enp) 369{ 370 efx_intr_t *eip = &(enp->en_intr); 371 efx_oword_t oword; 372 373 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 374 375 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 376 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1); 377 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 378} 379 380static void 381falconsiena_intr_disable( 382 __in efx_nic_t *enp) 383{ 384 efx_oword_t oword; 385 386 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 387 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 388 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 389 390 EFSYS_SPIN(10); 391} 392 393static void 394falconsiena_intr_disable_unlocked( 395 __in efx_nic_t *enp) 396{ 397 efx_oword_t oword; 398 399 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 400 &oword, B_FALSE); 401 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 402 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 403 &oword, B_FALSE); 404} 405 406static __checkReturn efx_rc_t 407falconsiena_intr_trigger( 408 __in efx_nic_t *enp, 409 __in unsigned int level) 410{ 411 efx_intr_t *eip = &(enp->en_intr); 412 efx_oword_t oword; 413 unsigned int count; 414 uint32_t sel; 415 efx_rc_t rc; 416 417 /* bug16757: No event queues can be initialized */ 418 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 419 420 switch (enp->en_family) { 421 case EFX_FAMILY_FALCON: 422 if (level >= EFX_NINTR_FALCON) { 423 rc = EINVAL; 424 goto fail1; 425 } 426 break; 427 428 case EFX_FAMILY_SIENA: 429 if (level >= EFX_NINTR_SIENA) { 430 rc = EINVAL; 431 goto fail1; 432 } 433 break; 434 435 default: 436 EFSYS_ASSERT(B_FALSE); 437 break; 438 } 439 440 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL)) 441 return (ENOTSUP); /* avoid EFSYS_PROBE() */ 442 443 sel = level; 444 445 /* Trigger a test interrupt */ 446 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 447 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel); 448 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1); 449 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 450 451 /* 452 * Wait up to 100ms for the interrupt to be raised before restoring 453 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will 454 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL 455 */ 456 count = 0; 457 do { 458 EFSYS_SPIN(100); /* 100us */ 459 460 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 461 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000); 462 463 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 464 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 465 466 return (0); 467 468fail1: 469 EFSYS_PROBE1(fail1, efx_rc_t, rc); 470 471 return (rc); 472} 473 474static __checkReturn boolean_t 475falconsiena_intr_check_fatal( 476 __in efx_nic_t *enp) 477{ 478 efx_intr_t *eip = &(enp->en_intr); 479 efsys_mem_t *esmp = eip->ei_esmp; 480 efx_oword_t oword; 481 482 /* Read the syndrome */ 483 EFSYS_MEM_READO(esmp, 0, &oword); 484 485 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) { 486 EFSYS_PROBE(fatal); 487 488 /* Clear the fatal interrupt condition */ 489 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0); 490 EFSYS_MEM_WRITEO(esmp, 0, &oword); 491 492 return (B_TRUE); 493 } 494 495 return (B_FALSE); 496} 497 498static void 499falconsiena_intr_status_line( 500 __in efx_nic_t *enp, 501 __out boolean_t *fatalp, 502 __out uint32_t *qmaskp) 503{ 504 efx_intr_t *eip = &(enp->en_intr); 505 efx_dword_t dword; 506 507 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 508 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 509 510 /* 511 * Read the queue mask and implicitly acknowledge the 512 * interrupt. 513 */ 514 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE); 515 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 516 517 EFSYS_PROBE1(qmask, uint32_t, *qmaskp); 518 519 if (*qmaskp & (1U << eip->ei_level)) 520 *fatalp = falconsiena_intr_check_fatal(enp); 521 else 522 *fatalp = B_FALSE; 523} 524 525static void 526falconsiena_intr_status_message( 527 __in efx_nic_t *enp, 528 __in unsigned int message, 529 __out boolean_t *fatalp) 530{ 531 efx_intr_t *eip = &(enp->en_intr); 532 533 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 534 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 535 536 if (message == eip->ei_level) 537 *fatalp = falconsiena_intr_check_fatal(enp); 538 else 539 *fatalp = B_FALSE; 540} 541 542 543static void 544falconsiena_intr_fatal( 545 __in efx_nic_t *enp) 546{ 547#if EFSYS_OPT_DECODE_INTR_FATAL 548 efx_oword_t fatal; 549 efx_oword_t mem_per; 550 551 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal); 552 EFX_ZERO_OWORD(mem_per); 553 554 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 || 555 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 556 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per); 557 558 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0) 559 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0); 560 561 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0) 562 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0); 563 564 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 565 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR, 566 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 567 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 568 569 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0) 570 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0); 571 572 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0) 573 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0); 574 575 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0) 576 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0); 577 578 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0) 579 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0); 580 581 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0) 582 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0); 583 584 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0) 585 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0); 586 587 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0) 588 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0); 589 590 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0) 591 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR, 592 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 593 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 594#else 595 EFSYS_ASSERT(0); 596#endif 597} 598 599static void 600falconsiena_intr_fini( 601 __in efx_nic_t *enp) 602{ 603 efx_oword_t oword; 604 605 /* Clear the interrupt address register */ 606 EFX_ZERO_OWORD(oword); 607 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 608} 609
| 304 305static __checkReturn efx_rc_t 306falconsiena_intr_init( 307 __in efx_nic_t *enp, 308 __in efx_intr_type_t type, 309 __in efsys_mem_t *esmp) 310{ 311 efx_intr_t *eip = &(enp->en_intr); 312 efx_oword_t oword; 313 314 /* 315 * bug17213 workaround. 316 * 317 * Under legacy interrupts, don't share a level between fatal 318 * interrupts and event queue interrupts. Under MSI-X, they 319 * must share, or we won't get an interrupt. 320 */ 321 if (enp->en_family == EFX_FAMILY_SIENA && 322 eip->ei_type == EFX_INTR_LINE) 323 eip->ei_level = 0x1f; 324 else 325 eip->ei_level = 0; 326 327 /* Enable all the genuinely fatal interrupts */ 328 EFX_SET_OWORD(oword); 329 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0); 330 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0); 331 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0); 332 if (enp->en_family >= EFX_FAMILY_SIENA) 333 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0); 334 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword); 335 336 /* Set up the interrupt address register */ 337 EFX_POPULATE_OWORD_3(oword, 338 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0, 339 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff, 340 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32); 341 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 342 343 return (0); 344} 345 346static void 347falconsiena_intr_enable( 348 __in efx_nic_t *enp) 349{ 350 efx_intr_t *eip = &(enp->en_intr); 351 efx_oword_t oword; 352 353 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 354 355 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 356 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1); 357 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 358} 359 360static void 361falconsiena_intr_disable( 362 __in efx_nic_t *enp) 363{ 364 efx_oword_t oword; 365 366 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 367 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 368 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 369 370 EFSYS_SPIN(10); 371} 372 373static void 374falconsiena_intr_disable_unlocked( 375 __in efx_nic_t *enp) 376{ 377 efx_oword_t oword; 378 379 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 380 &oword, B_FALSE); 381 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 382 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 383 &oword, B_FALSE); 384} 385 386static __checkReturn efx_rc_t 387falconsiena_intr_trigger( 388 __in efx_nic_t *enp, 389 __in unsigned int level) 390{ 391 efx_intr_t *eip = &(enp->en_intr); 392 efx_oword_t oword; 393 unsigned int count; 394 uint32_t sel; 395 efx_rc_t rc; 396 397 /* bug16757: No event queues can be initialized */ 398 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 399 400 switch (enp->en_family) { 401 case EFX_FAMILY_FALCON: 402 if (level >= EFX_NINTR_FALCON) { 403 rc = EINVAL; 404 goto fail1; 405 } 406 break; 407 408 case EFX_FAMILY_SIENA: 409 if (level >= EFX_NINTR_SIENA) { 410 rc = EINVAL; 411 goto fail1; 412 } 413 break; 414 415 default: 416 EFSYS_ASSERT(B_FALSE); 417 break; 418 } 419 420 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL)) 421 return (ENOTSUP); /* avoid EFSYS_PROBE() */ 422 423 sel = level; 424 425 /* Trigger a test interrupt */ 426 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 427 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel); 428 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1); 429 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 430 431 /* 432 * Wait up to 100ms for the interrupt to be raised before restoring 433 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will 434 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL 435 */ 436 count = 0; 437 do { 438 EFSYS_SPIN(100); /* 100us */ 439 440 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 441 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000); 442 443 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 444 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 445 446 return (0); 447 448fail1: 449 EFSYS_PROBE1(fail1, efx_rc_t, rc); 450 451 return (rc); 452} 453 454static __checkReturn boolean_t 455falconsiena_intr_check_fatal( 456 __in efx_nic_t *enp) 457{ 458 efx_intr_t *eip = &(enp->en_intr); 459 efsys_mem_t *esmp = eip->ei_esmp; 460 efx_oword_t oword; 461 462 /* Read the syndrome */ 463 EFSYS_MEM_READO(esmp, 0, &oword); 464 465 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) { 466 EFSYS_PROBE(fatal); 467 468 /* Clear the fatal interrupt condition */ 469 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0); 470 EFSYS_MEM_WRITEO(esmp, 0, &oword); 471 472 return (B_TRUE); 473 } 474 475 return (B_FALSE); 476} 477 478static void 479falconsiena_intr_status_line( 480 __in efx_nic_t *enp, 481 __out boolean_t *fatalp, 482 __out uint32_t *qmaskp) 483{ 484 efx_intr_t *eip = &(enp->en_intr); 485 efx_dword_t dword; 486 487 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 488 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 489 490 /* 491 * Read the queue mask and implicitly acknowledge the 492 * interrupt. 493 */ 494 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE); 495 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 496 497 EFSYS_PROBE1(qmask, uint32_t, *qmaskp); 498 499 if (*qmaskp & (1U << eip->ei_level)) 500 *fatalp = falconsiena_intr_check_fatal(enp); 501 else 502 *fatalp = B_FALSE; 503} 504 505static void 506falconsiena_intr_status_message( 507 __in efx_nic_t *enp, 508 __in unsigned int message, 509 __out boolean_t *fatalp) 510{ 511 efx_intr_t *eip = &(enp->en_intr); 512 513 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 514 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 515 516 if (message == eip->ei_level) 517 *fatalp = falconsiena_intr_check_fatal(enp); 518 else 519 *fatalp = B_FALSE; 520} 521 522 523static void 524falconsiena_intr_fatal( 525 __in efx_nic_t *enp) 526{ 527#if EFSYS_OPT_DECODE_INTR_FATAL 528 efx_oword_t fatal; 529 efx_oword_t mem_per; 530 531 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal); 532 EFX_ZERO_OWORD(mem_per); 533 534 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 || 535 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 536 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per); 537 538 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0) 539 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0); 540 541 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0) 542 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0); 543 544 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 545 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR, 546 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 547 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 548 549 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0) 550 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0); 551 552 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0) 553 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0); 554 555 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0) 556 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0); 557 558 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0) 559 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0); 560 561 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0) 562 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0); 563 564 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0) 565 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0); 566 567 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0) 568 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0); 569 570 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0) 571 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR, 572 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 573 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 574#else 575 EFSYS_ASSERT(0); 576#endif 577} 578 579static void 580falconsiena_intr_fini( 581 __in efx_nic_t *enp) 582{ 583 efx_oword_t oword; 584 585 /* Clear the interrupt address register */ 586 EFX_ZERO_OWORD(oword); 587 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 588} 589
|