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