1 /* 2 * Copyright (c) 2007-2015 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31 #include "efx.h" 32 #include "efx_impl.h" 33 34 35 #if EFSYS_OPT_SIENA 36 37 static __checkReturn efx_rc_t 38 siena_intr_init( 39 __in efx_nic_t *enp, 40 __in efx_intr_type_t type, 41 __in efsys_mem_t *esmp); 42 43 static void 44 siena_intr_enable( 45 __in efx_nic_t *enp); 46 47 static void 48 siena_intr_disable( 49 __in efx_nic_t *enp); 50 51 static void 52 siena_intr_disable_unlocked( 53 __in efx_nic_t *enp); 54 55 static __checkReturn efx_rc_t 56 siena_intr_trigger( 57 __in efx_nic_t *enp, 58 __in unsigned int level); 59 60 static void 61 siena_intr_fini( 62 __in efx_nic_t *enp); 63 64 static void 65 siena_intr_status_line( 66 __in efx_nic_t *enp, 67 __out boolean_t *fatalp, 68 __out uint32_t *qmaskp); 69 70 static void 71 siena_intr_status_message( 72 __in efx_nic_t *enp, 73 __in unsigned int message, 74 __out boolean_t *fatalp); 75 76 static void 77 siena_intr_fatal( 78 __in efx_nic_t *enp); 79 80 static __checkReturn boolean_t 81 siena_intr_check_fatal( 82 __in efx_nic_t *enp); 83 84 85 #endif /* EFSYS_OPT_SIENA */ 86 87 88 #if EFSYS_OPT_SIENA 89 static const efx_intr_ops_t __efx_intr_siena_ops = { 90 siena_intr_init, /* eio_init */ 91 siena_intr_enable, /* eio_enable */ 92 siena_intr_disable, /* eio_disable */ 93 siena_intr_disable_unlocked, /* eio_disable_unlocked */ 94 siena_intr_trigger, /* eio_trigger */ 95 siena_intr_status_line, /* eio_status_line */ 96 siena_intr_status_message, /* eio_status_message */ 97 siena_intr_fatal, /* eio_fatal */ 98 siena_intr_fini, /* eio_fini */ 99 }; 100 #endif /* EFSYS_OPT_SIENA */ 101 102 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 103 static const efx_intr_ops_t __efx_intr_ef10_ops = { 104 ef10_intr_init, /* eio_init */ 105 ef10_intr_enable, /* eio_enable */ 106 ef10_intr_disable, /* eio_disable */ 107 ef10_intr_disable_unlocked, /* eio_disable_unlocked */ 108 ef10_intr_trigger, /* eio_trigger */ 109 ef10_intr_status_line, /* eio_status_line */ 110 ef10_intr_status_message, /* eio_status_message */ 111 ef10_intr_fatal, /* eio_fatal */ 112 ef10_intr_fini, /* eio_fini */ 113 }; 114 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 115 116 __checkReturn efx_rc_t 117 efx_intr_init( 118 __in efx_nic_t *enp, 119 __in efx_intr_type_t type, 120 __in efsys_mem_t *esmp) 121 { 122 efx_intr_t *eip = &(enp->en_intr); 123 const efx_intr_ops_t *eiop; 124 efx_rc_t rc; 125 126 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 127 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 128 129 if (enp->en_mod_flags & EFX_MOD_INTR) { 130 rc = EINVAL; 131 goto fail1; 132 } 133 134 eip->ei_esmp = esmp; 135 eip->ei_type = type; 136 eip->ei_level = 0; 137 138 enp->en_mod_flags |= EFX_MOD_INTR; 139 140 switch (enp->en_family) { 141 #if EFSYS_OPT_SIENA 142 case EFX_FAMILY_SIENA: 143 eiop = &__efx_intr_siena_ops; 144 break; 145 #endif /* EFSYS_OPT_SIENA */ 146 147 #if EFSYS_OPT_HUNTINGTON 148 case EFX_FAMILY_HUNTINGTON: 149 eiop = &__efx_intr_ef10_ops; 150 break; 151 #endif /* EFSYS_OPT_HUNTINGTON */ 152 153 #if EFSYS_OPT_MEDFORD 154 case EFX_FAMILY_MEDFORD: 155 eiop = &__efx_intr_ef10_ops; 156 break; 157 #endif /* EFSYS_OPT_MEDFORD */ 158 159 default: 160 EFSYS_ASSERT(B_FALSE); 161 rc = ENOTSUP; 162 goto fail2; 163 } 164 165 if ((rc = eiop->eio_init(enp, type, esmp)) != 0) 166 goto fail3; 167 168 eip->ei_eiop = eiop; 169 170 return (0); 171 172 fail3: 173 EFSYS_PROBE(fail3); 174 fail2: 175 EFSYS_PROBE(fail2); 176 fail1: 177 EFSYS_PROBE1(fail1, efx_rc_t, rc); 178 179 return (rc); 180 } 181 182 void 183 efx_intr_fini( 184 __in efx_nic_t *enp) 185 { 186 efx_intr_t *eip = &(enp->en_intr); 187 const efx_intr_ops_t *eiop = eip->ei_eiop; 188 189 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 190 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC); 191 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 192 193 eiop->eio_fini(enp); 194 195 enp->en_mod_flags &= ~EFX_MOD_INTR; 196 } 197 198 void 199 efx_intr_enable( 200 __in efx_nic_t *enp) 201 { 202 efx_intr_t *eip = &(enp->en_intr); 203 const efx_intr_ops_t *eiop = eip->ei_eiop; 204 205 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 206 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 207 208 eiop->eio_enable(enp); 209 } 210 211 void 212 efx_intr_disable( 213 __in efx_nic_t *enp) 214 { 215 efx_intr_t *eip = &(enp->en_intr); 216 const efx_intr_ops_t *eiop = eip->ei_eiop; 217 218 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 219 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 220 221 eiop->eio_disable(enp); 222 } 223 224 void 225 efx_intr_disable_unlocked( 226 __in efx_nic_t *enp) 227 { 228 efx_intr_t *eip = &(enp->en_intr); 229 const efx_intr_ops_t *eiop = eip->ei_eiop; 230 231 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 232 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 233 234 eiop->eio_disable_unlocked(enp); 235 } 236 237 238 __checkReturn efx_rc_t 239 efx_intr_trigger( 240 __in efx_nic_t *enp, 241 __in unsigned int level) 242 { 243 efx_intr_t *eip = &(enp->en_intr); 244 const efx_intr_ops_t *eiop = eip->ei_eiop; 245 246 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 247 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 248 249 return (eiop->eio_trigger(enp, level)); 250 } 251 252 void 253 efx_intr_status_line( 254 __in efx_nic_t *enp, 255 __out boolean_t *fatalp, 256 __out uint32_t *qmaskp) 257 { 258 efx_intr_t *eip = &(enp->en_intr); 259 const efx_intr_ops_t *eiop = eip->ei_eiop; 260 261 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 262 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 263 264 eiop->eio_status_line(enp, fatalp, qmaskp); 265 } 266 267 void 268 efx_intr_status_message( 269 __in efx_nic_t *enp, 270 __in unsigned int message, 271 __out boolean_t *fatalp) 272 { 273 efx_intr_t *eip = &(enp->en_intr); 274 const efx_intr_ops_t *eiop = eip->ei_eiop; 275 276 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 277 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 278 279 eiop->eio_status_message(enp, message, fatalp); 280 } 281 282 void 283 efx_intr_fatal( 284 __in efx_nic_t *enp) 285 { 286 efx_intr_t *eip = &(enp->en_intr); 287 const efx_intr_ops_t *eiop = eip->ei_eiop; 288 289 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 290 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 291 292 eiop->eio_fatal(enp); 293 } 294 295 296 /* ************************************************************************* */ 297 /* ************************************************************************* */ 298 /* ************************************************************************* */ 299 300 #if EFSYS_OPT_SIENA 301 302 static __checkReturn efx_rc_t 303 siena_intr_init( 304 __in efx_nic_t *enp, 305 __in efx_intr_type_t type, 306 __in efsys_mem_t *esmp) 307 { 308 efx_intr_t *eip = &(enp->en_intr); 309 efx_oword_t oword; 310 311 /* 312 * bug17213 workaround. 313 * 314 * Under legacy interrupts, don't share a level between fatal 315 * interrupts and event queue interrupts. Under MSI-X, they 316 * must share, or we won't get an interrupt. 317 */ 318 if (enp->en_family == EFX_FAMILY_SIENA && 319 eip->ei_type == EFX_INTR_LINE) 320 eip->ei_level = 0x1f; 321 else 322 eip->ei_level = 0; 323 324 /* Enable all the genuinely fatal interrupts */ 325 EFX_SET_OWORD(oword); 326 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0); 327 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0); 328 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0); 329 if (enp->en_family >= EFX_FAMILY_SIENA) 330 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0); 331 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword); 332 333 /* Set up the interrupt address register */ 334 EFX_POPULATE_OWORD_3(oword, 335 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0, 336 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff, 337 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32); 338 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 339 340 return (0); 341 } 342 343 static void 344 siena_intr_enable( 345 __in efx_nic_t *enp) 346 { 347 efx_intr_t *eip = &(enp->en_intr); 348 efx_oword_t oword; 349 350 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 351 352 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 353 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1); 354 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 355 } 356 357 static void 358 siena_intr_disable( 359 __in efx_nic_t *enp) 360 { 361 efx_oword_t oword; 362 363 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 364 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 365 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 366 367 EFSYS_SPIN(10); 368 } 369 370 static void 371 siena_intr_disable_unlocked( 372 __in efx_nic_t *enp) 373 { 374 efx_oword_t oword; 375 376 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 377 &oword, B_FALSE); 378 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0); 379 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST, 380 &oword, B_FALSE); 381 } 382 383 static __checkReturn efx_rc_t 384 siena_intr_trigger( 385 __in efx_nic_t *enp, 386 __in unsigned int level) 387 { 388 efx_intr_t *eip = &(enp->en_intr); 389 efx_oword_t oword; 390 unsigned int count; 391 uint32_t sel; 392 efx_rc_t rc; 393 394 /* bug16757: No event queues can be initialized */ 395 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV)); 396 397 if (level >= EFX_NINTR_SIENA) { 398 rc = EINVAL; 399 goto fail1; 400 } 401 402 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL)) 403 return (ENOTSUP); /* avoid EFSYS_PROBE() */ 404 405 sel = level; 406 407 /* Trigger a test interrupt */ 408 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 409 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel); 410 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1); 411 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 412 413 /* 414 * Wait up to 100ms for the interrupt to be raised before restoring 415 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will 416 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL 417 */ 418 count = 0; 419 do { 420 EFSYS_SPIN(100); /* 100us */ 421 422 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword); 423 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000); 424 425 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level); 426 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword); 427 428 return (0); 429 430 fail1: 431 EFSYS_PROBE1(fail1, efx_rc_t, rc); 432 433 return (rc); 434 } 435 436 static __checkReturn boolean_t 437 siena_intr_check_fatal( 438 __in efx_nic_t *enp) 439 { 440 efx_intr_t *eip = &(enp->en_intr); 441 efsys_mem_t *esmp = eip->ei_esmp; 442 efx_oword_t oword; 443 444 /* Read the syndrome */ 445 EFSYS_MEM_READO(esmp, 0, &oword); 446 447 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) { 448 EFSYS_PROBE(fatal); 449 450 /* Clear the fatal interrupt condition */ 451 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0); 452 EFSYS_MEM_WRITEO(esmp, 0, &oword); 453 454 return (B_TRUE); 455 } 456 457 return (B_FALSE); 458 } 459 460 static void 461 siena_intr_status_line( 462 __in efx_nic_t *enp, 463 __out boolean_t *fatalp, 464 __out uint32_t *qmaskp) 465 { 466 efx_intr_t *eip = &(enp->en_intr); 467 efx_dword_t dword; 468 469 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 470 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 471 472 /* 473 * Read the queue mask and implicitly acknowledge the 474 * interrupt. 475 */ 476 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE); 477 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 478 479 EFSYS_PROBE1(qmask, uint32_t, *qmaskp); 480 481 if (*qmaskp & (1U << eip->ei_level)) 482 *fatalp = siena_intr_check_fatal(enp); 483 else 484 *fatalp = B_FALSE; 485 } 486 487 static void 488 siena_intr_status_message( 489 __in efx_nic_t *enp, 490 __in unsigned int message, 491 __out boolean_t *fatalp) 492 { 493 efx_intr_t *eip = &(enp->en_intr); 494 495 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 496 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 497 498 if (message == eip->ei_level) 499 *fatalp = siena_intr_check_fatal(enp); 500 else 501 *fatalp = B_FALSE; 502 } 503 504 505 static void 506 siena_intr_fatal( 507 __in efx_nic_t *enp) 508 { 509 #if EFSYS_OPT_DECODE_INTR_FATAL 510 efx_oword_t fatal; 511 efx_oword_t mem_per; 512 513 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal); 514 EFX_ZERO_OWORD(mem_per); 515 516 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 || 517 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 518 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per); 519 520 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0) 521 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0); 522 523 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0) 524 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0); 525 526 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0) 527 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR, 528 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 529 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 530 531 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0) 532 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0); 533 534 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0) 535 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0); 536 537 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0) 538 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0); 539 540 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0) 541 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0); 542 543 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0) 544 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0); 545 546 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0) 547 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0); 548 549 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0) 550 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0); 551 552 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0) 553 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR, 554 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0), 555 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1)); 556 #else 557 EFSYS_ASSERT(0); 558 #endif 559 } 560 561 static void 562 siena_intr_fini( 563 __in efx_nic_t *enp) 564 { 565 efx_oword_t oword; 566 567 /* Clear the interrupt address register */ 568 EFX_ZERO_OWORD(oword); 569 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword); 570 } 571 572 #endif /* EFSYS_OPT_SIENA */ 573