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 <sys/cdefs.h> 32 __FBSDID("$FreeBSD$"); 33 34 #include "efx.h" 35 #include "efx_impl.h" 36 #if EFSYS_OPT_MON_MCDI 37 #include "mcdi_mon.h" 38 #endif 39 40 #if EFSYS_OPT_QSTATS 41 #define EFX_EV_QSTAT_INCR(_eep, _stat) \ 42 do { \ 43 (_eep)->ee_stat[_stat]++; \ 44 _NOTE(CONSTANTCONDITION) \ 45 } while (B_FALSE) 46 #else 47 #define EFX_EV_QSTAT_INCR(_eep, _stat) 48 #endif 49 50 #define EFX_EV_PRESENT(_qword) \ 51 (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff && \ 52 EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff) 53 54 55 56 #if EFSYS_OPT_SIENA 57 58 static __checkReturn efx_rc_t 59 siena_ev_init( 60 __in efx_nic_t *enp); 61 62 static void 63 siena_ev_fini( 64 __in efx_nic_t *enp); 65 66 static __checkReturn efx_rc_t 67 siena_ev_qcreate( 68 __in efx_nic_t *enp, 69 __in unsigned int index, 70 __in efsys_mem_t *esmp, 71 __in size_t n, 72 __in uint32_t id, 73 __in efx_evq_t *eep); 74 75 static void 76 siena_ev_qdestroy( 77 __in efx_evq_t *eep); 78 79 static __checkReturn efx_rc_t 80 siena_ev_qprime( 81 __in efx_evq_t *eep, 82 __in unsigned int count); 83 84 static void 85 siena_ev_qpoll( 86 __in efx_evq_t *eep, 87 __inout unsigned int *countp, 88 __in const efx_ev_callbacks_t *eecp, 89 __in_opt void *arg); 90 91 static void 92 siena_ev_qpost( 93 __in efx_evq_t *eep, 94 __in uint16_t data); 95 96 static __checkReturn efx_rc_t 97 siena_ev_qmoderate( 98 __in efx_evq_t *eep, 99 __in unsigned int us); 100 101 #if EFSYS_OPT_QSTATS 102 static void 103 siena_ev_qstats_update( 104 __in efx_evq_t *eep, 105 __inout_ecount(EV_NQSTATS) efsys_stat_t *stat); 106 107 #endif 108 109 #endif /* EFSYS_OPT_SIENA */ 110 111 #if EFSYS_OPT_SIENA 112 static const efx_ev_ops_t __efx_ev_siena_ops = { 113 siena_ev_init, /* eevo_init */ 114 siena_ev_fini, /* eevo_fini */ 115 siena_ev_qcreate, /* eevo_qcreate */ 116 siena_ev_qdestroy, /* eevo_qdestroy */ 117 siena_ev_qprime, /* eevo_qprime */ 118 siena_ev_qpost, /* eevo_qpost */ 119 siena_ev_qmoderate, /* eevo_qmoderate */ 120 #if EFSYS_OPT_QSTATS 121 siena_ev_qstats_update, /* eevo_qstats_update */ 122 #endif 123 }; 124 #endif /* EFSYS_OPT_SIENA */ 125 126 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 127 static const efx_ev_ops_t __efx_ev_ef10_ops = { 128 ef10_ev_init, /* eevo_init */ 129 ef10_ev_fini, /* eevo_fini */ 130 ef10_ev_qcreate, /* eevo_qcreate */ 131 ef10_ev_qdestroy, /* eevo_qdestroy */ 132 ef10_ev_qprime, /* eevo_qprime */ 133 ef10_ev_qpost, /* eevo_qpost */ 134 ef10_ev_qmoderate, /* eevo_qmoderate */ 135 #if EFSYS_OPT_QSTATS 136 ef10_ev_qstats_update, /* eevo_qstats_update */ 137 #endif 138 }; 139 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 140 141 142 __checkReturn efx_rc_t 143 efx_ev_init( 144 __in efx_nic_t *enp) 145 { 146 const efx_ev_ops_t *eevop; 147 efx_rc_t rc; 148 149 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 150 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 151 152 if (enp->en_mod_flags & EFX_MOD_EV) { 153 rc = EINVAL; 154 goto fail1; 155 } 156 157 switch (enp->en_family) { 158 #if EFSYS_OPT_SIENA 159 case EFX_FAMILY_SIENA: 160 eevop = &__efx_ev_siena_ops; 161 break; 162 #endif /* EFSYS_OPT_SIENA */ 163 164 #if EFSYS_OPT_HUNTINGTON 165 case EFX_FAMILY_HUNTINGTON: 166 eevop = &__efx_ev_ef10_ops; 167 break; 168 #endif /* EFSYS_OPT_HUNTINGTON */ 169 170 #if EFSYS_OPT_MEDFORD 171 case EFX_FAMILY_MEDFORD: 172 eevop = &__efx_ev_ef10_ops; 173 break; 174 #endif /* EFSYS_OPT_MEDFORD */ 175 176 default: 177 EFSYS_ASSERT(0); 178 rc = ENOTSUP; 179 goto fail1; 180 } 181 182 EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0); 183 184 if ((rc = eevop->eevo_init(enp)) != 0) 185 goto fail2; 186 187 enp->en_eevop = eevop; 188 enp->en_mod_flags |= EFX_MOD_EV; 189 return (0); 190 191 fail2: 192 EFSYS_PROBE(fail2); 193 194 fail1: 195 EFSYS_PROBE1(fail1, efx_rc_t, rc); 196 197 enp->en_eevop = NULL; 198 enp->en_mod_flags &= ~EFX_MOD_EV; 199 return (rc); 200 } 201 202 void 203 efx_ev_fini( 204 __in efx_nic_t *enp) 205 { 206 const efx_ev_ops_t *eevop = enp->en_eevop; 207 208 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 209 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR); 210 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV); 211 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX)); 212 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX)); 213 EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0); 214 215 eevop->eevo_fini(enp); 216 217 enp->en_eevop = NULL; 218 enp->en_mod_flags &= ~EFX_MOD_EV; 219 } 220 221 222 __checkReturn efx_rc_t 223 efx_ev_qcreate( 224 __in efx_nic_t *enp, 225 __in unsigned int index, 226 __in efsys_mem_t *esmp, 227 __in size_t n, 228 __in uint32_t id, 229 __deref_out efx_evq_t **eepp) 230 { 231 const efx_ev_ops_t *eevop = enp->en_eevop; 232 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 233 efx_evq_t *eep; 234 efx_rc_t rc; 235 236 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 237 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV); 238 239 EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <, encp->enc_evq_limit); 240 241 /* Allocate an EVQ object */ 242 EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep); 243 if (eep == NULL) { 244 rc = ENOMEM; 245 goto fail1; 246 } 247 248 eep->ee_magic = EFX_EVQ_MAGIC; 249 eep->ee_enp = enp; 250 eep->ee_index = index; 251 eep->ee_mask = n - 1; 252 eep->ee_esmp = esmp; 253 254 if ((rc = eevop->eevo_qcreate(enp, index, esmp, n, id, eep)) != 0) 255 goto fail2; 256 257 enp->en_ev_qcount++; 258 *eepp = eep; 259 260 return (0); 261 262 fail2: 263 EFSYS_PROBE(fail2); 264 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep); 265 fail1: 266 EFSYS_PROBE1(fail1, efx_rc_t, rc); 267 return (rc); 268 } 269 270 void 271 efx_ev_qdestroy( 272 __in efx_evq_t *eep) 273 { 274 efx_nic_t *enp = eep->ee_enp; 275 const efx_ev_ops_t *eevop = enp->en_eevop; 276 277 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 278 279 EFSYS_ASSERT(enp->en_ev_qcount != 0); 280 --enp->en_ev_qcount; 281 282 eevop->eevo_qdestroy(eep); 283 284 /* Free the EVQ object */ 285 EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep); 286 } 287 288 __checkReturn efx_rc_t 289 efx_ev_qprime( 290 __in efx_evq_t *eep, 291 __in unsigned int count) 292 { 293 efx_nic_t *enp = eep->ee_enp; 294 const efx_ev_ops_t *eevop = enp->en_eevop; 295 efx_rc_t rc; 296 297 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 298 299 if (!(enp->en_mod_flags & EFX_MOD_INTR)) { 300 rc = EINVAL; 301 goto fail1; 302 } 303 304 if ((rc = eevop->eevo_qprime(eep, count)) != 0) 305 goto fail2; 306 307 return (0); 308 309 fail2: 310 EFSYS_PROBE(fail2); 311 fail1: 312 EFSYS_PROBE1(fail1, efx_rc_t, rc); 313 return (rc); 314 } 315 316 __checkReturn boolean_t 317 efx_ev_qpending( 318 __in efx_evq_t *eep, 319 __in unsigned int count) 320 { 321 size_t offset; 322 efx_qword_t qword; 323 324 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 325 326 offset = (count & eep->ee_mask) * sizeof (efx_qword_t); 327 EFSYS_MEM_READQ(eep->ee_esmp, offset, &qword); 328 329 return (EFX_EV_PRESENT(qword)); 330 } 331 332 #if EFSYS_OPT_EV_PREFETCH 333 334 void 335 efx_ev_qprefetch( 336 __in efx_evq_t *eep, 337 __in unsigned int count) 338 { 339 efx_nic_t *enp = eep->ee_enp; 340 unsigned int offset; 341 342 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 343 344 offset = (count & eep->ee_mask) * sizeof (efx_qword_t); 345 EFSYS_MEM_PREFETCH(eep->ee_esmp, offset); 346 } 347 348 #endif /* EFSYS_OPT_EV_PREFETCH */ 349 350 void 351 efx_ev_qpoll( 352 __in efx_evq_t *eep, 353 __inout unsigned int *countp, 354 __in const efx_ev_callbacks_t *eecp, 355 __in_opt void *arg) 356 { 357 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 358 359 /* 360 * FIXME: Huntington will require support for hardware event batching 361 * and merging, which will need a different ev_qpoll implementation. 362 * 363 * Without those features the Falcon/Siena code can be used unchanged. 364 */ 365 EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_LBN == FSF_AZ_EV_CODE_LBN); 366 EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_WIDTH == FSF_AZ_EV_CODE_WIDTH); 367 368 EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_RX_EV == FSE_AZ_EV_CODE_RX_EV); 369 EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_TX_EV == FSE_AZ_EV_CODE_TX_EV); 370 EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRIVER_EV == FSE_AZ_EV_CODE_DRIVER_EV); 371 EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRV_GEN_EV == 372 FSE_AZ_EV_CODE_DRV_GEN_EV); 373 #if EFSYS_OPT_MCDI 374 EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_MCDI_EV == 375 FSE_AZ_EV_CODE_MCDI_EVRESPONSE); 376 #endif 377 siena_ev_qpoll(eep, countp, eecp, arg); 378 } 379 380 void 381 efx_ev_qpost( 382 __in efx_evq_t *eep, 383 __in uint16_t data) 384 { 385 efx_nic_t *enp = eep->ee_enp; 386 const efx_ev_ops_t *eevop = enp->en_eevop; 387 388 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 389 390 EFSYS_ASSERT(eevop != NULL && 391 eevop->eevo_qpost != NULL); 392 393 eevop->eevo_qpost(eep, data); 394 } 395 396 __checkReturn efx_rc_t 397 efx_ev_qmoderate( 398 __in efx_evq_t *eep, 399 __in unsigned int us) 400 { 401 efx_nic_t *enp = eep->ee_enp; 402 const efx_ev_ops_t *eevop = enp->en_eevop; 403 efx_rc_t rc; 404 405 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 406 407 if ((rc = eevop->eevo_qmoderate(eep, us)) != 0) 408 goto fail1; 409 410 return (0); 411 412 fail1: 413 EFSYS_PROBE1(fail1, efx_rc_t, rc); 414 return (rc); 415 } 416 417 #if EFSYS_OPT_QSTATS 418 void 419 efx_ev_qstats_update( 420 __in efx_evq_t *eep, 421 __inout_ecount(EV_NQSTATS) efsys_stat_t *stat) 422 423 { efx_nic_t *enp = eep->ee_enp; 424 const efx_ev_ops_t *eevop = enp->en_eevop; 425 426 EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC); 427 428 eevop->eevo_qstats_update(eep, stat); 429 } 430 431 #endif /* EFSYS_OPT_QSTATS */ 432 433 #if EFSYS_OPT_SIENA 434 435 static __checkReturn efx_rc_t 436 siena_ev_init( 437 __in efx_nic_t *enp) 438 { 439 efx_oword_t oword; 440 441 /* 442 * Program the event queue for receive and transmit queue 443 * flush events. 444 */ 445 EFX_BAR_READO(enp, FR_AZ_DP_CTRL_REG, &oword); 446 EFX_SET_OWORD_FIELD(oword, FRF_AZ_FLS_EVQ_ID, 0); 447 EFX_BAR_WRITEO(enp, FR_AZ_DP_CTRL_REG, &oword); 448 449 return (0); 450 451 } 452 453 static __checkReturn boolean_t 454 siena_ev_rx_not_ok( 455 __in efx_evq_t *eep, 456 __in efx_qword_t *eqp, 457 __in uint32_t label, 458 __in uint32_t id, 459 __inout uint16_t *flagsp) 460 { 461 boolean_t ignore = B_FALSE; 462 463 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TOBE_DISC) != 0) { 464 EFX_EV_QSTAT_INCR(eep, EV_RX_TOBE_DISC); 465 EFSYS_PROBE(tobe_disc); 466 /* 467 * Assume this is a unicast address mismatch, unless below 468 * we find either FSF_AZ_RX_EV_ETH_CRC_ERR or 469 * EV_RX_PAUSE_FRM_ERR is set. 470 */ 471 (*flagsp) |= EFX_ADDR_MISMATCH; 472 } 473 474 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_FRM_TRUNC) != 0) { 475 EFSYS_PROBE2(frm_trunc, uint32_t, label, uint32_t, id); 476 EFX_EV_QSTAT_INCR(eep, EV_RX_FRM_TRUNC); 477 (*flagsp) |= EFX_DISCARD; 478 479 #if EFSYS_OPT_RX_SCATTER 480 /* 481 * Lookout for payload queue ran dry errors and ignore them. 482 * 483 * Sadly for the header/data split cases, the descriptor 484 * pointer in this event refers to the header queue and 485 * therefore cannot be easily detected as duplicate. 486 * So we drop these and rely on the receive processing seeing 487 * a subsequent packet with FSF_AZ_RX_EV_SOP set to discard 488 * the partially received packet. 489 */ 490 if ((EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_SOP) == 0) && 491 (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_JUMBO_CONT) == 0) && 492 (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT) == 0)) 493 ignore = B_TRUE; 494 #endif /* EFSYS_OPT_RX_SCATTER */ 495 } 496 497 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_ETH_CRC_ERR) != 0) { 498 EFX_EV_QSTAT_INCR(eep, EV_RX_ETH_CRC_ERR); 499 EFSYS_PROBE(crc_err); 500 (*flagsp) &= ~EFX_ADDR_MISMATCH; 501 (*flagsp) |= EFX_DISCARD; 502 } 503 504 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PAUSE_FRM_ERR) != 0) { 505 EFX_EV_QSTAT_INCR(eep, EV_RX_PAUSE_FRM_ERR); 506 EFSYS_PROBE(pause_frm_err); 507 (*flagsp) &= ~EFX_ADDR_MISMATCH; 508 (*flagsp) |= EFX_DISCARD; 509 } 510 511 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BUF_OWNER_ID_ERR) != 0) { 512 EFX_EV_QSTAT_INCR(eep, EV_RX_BUF_OWNER_ID_ERR); 513 EFSYS_PROBE(owner_id_err); 514 (*flagsp) |= EFX_DISCARD; 515 } 516 517 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_HDR_CHKSUM_ERR) != 0) { 518 EFX_EV_QSTAT_INCR(eep, EV_RX_IPV4_HDR_CHKSUM_ERR); 519 EFSYS_PROBE(ipv4_err); 520 (*flagsp) &= ~EFX_CKSUM_IPV4; 521 } 522 523 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_TCP_UDP_CHKSUM_ERR) != 0) { 524 EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_UDP_CHKSUM_ERR); 525 EFSYS_PROBE(udp_chk_err); 526 (*flagsp) &= ~EFX_CKSUM_TCPUDP; 527 } 528 529 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_IP_FRAG_ERR) != 0) { 530 EFX_EV_QSTAT_INCR(eep, EV_RX_IP_FRAG_ERR); 531 532 /* 533 * If IP is fragmented FSF_AZ_RX_EV_IP_FRAG_ERR is set. This 534 * causes FSF_AZ_RX_EV_PKT_OK to be clear. This is not an error 535 * condition. 536 */ 537 (*flagsp) &= ~(EFX_PKT_TCP | EFX_PKT_UDP | EFX_CKSUM_TCPUDP); 538 } 539 540 return (ignore); 541 } 542 543 static __checkReturn boolean_t 544 siena_ev_rx( 545 __in efx_evq_t *eep, 546 __in efx_qword_t *eqp, 547 __in const efx_ev_callbacks_t *eecp, 548 __in_opt void *arg) 549 { 550 uint32_t id; 551 uint32_t size; 552 uint32_t label; 553 boolean_t ok; 554 #if EFSYS_OPT_RX_SCATTER 555 boolean_t sop; 556 boolean_t jumbo_cont; 557 #endif /* EFSYS_OPT_RX_SCATTER */ 558 uint32_t hdr_type; 559 boolean_t is_v6; 560 uint16_t flags; 561 boolean_t ignore; 562 boolean_t should_abort; 563 564 EFX_EV_QSTAT_INCR(eep, EV_RX); 565 566 /* Basic packet information */ 567 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_DESC_PTR); 568 size = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_BYTE_CNT); 569 label = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_Q_LABEL); 570 ok = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_OK) != 0); 571 572 #if EFSYS_OPT_RX_SCATTER 573 sop = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_SOP) != 0); 574 jumbo_cont = (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_JUMBO_CONT) != 0); 575 #endif /* EFSYS_OPT_RX_SCATTER */ 576 577 hdr_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_HDR_TYPE); 578 579 is_v6 = (EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_IPV6_PKT) != 0); 580 581 /* 582 * If packet is marked as OK and packet type is TCP/IP or 583 * UDP/IP or other IP, then we can rely on the hardware checksums. 584 */ 585 switch (hdr_type) { 586 case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_TCP: 587 flags = EFX_PKT_TCP | EFX_CKSUM_TCPUDP; 588 if (is_v6) { 589 EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV6); 590 flags |= EFX_PKT_IPV6; 591 } else { 592 EFX_EV_QSTAT_INCR(eep, EV_RX_TCP_IPV4); 593 flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4; 594 } 595 break; 596 597 case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_UDP: 598 flags = EFX_PKT_UDP | EFX_CKSUM_TCPUDP; 599 if (is_v6) { 600 EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV6); 601 flags |= EFX_PKT_IPV6; 602 } else { 603 EFX_EV_QSTAT_INCR(eep, EV_RX_UDP_IPV4); 604 flags |= EFX_PKT_IPV4 | EFX_CKSUM_IPV4; 605 } 606 break; 607 608 case FSE_AZ_RX_EV_HDR_TYPE_IPV4V6_OTHER: 609 if (is_v6) { 610 EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV6); 611 flags = EFX_PKT_IPV6; 612 } else { 613 EFX_EV_QSTAT_INCR(eep, EV_RX_OTHER_IPV4); 614 flags = EFX_PKT_IPV4 | EFX_CKSUM_IPV4; 615 } 616 break; 617 618 case FSE_AZ_RX_EV_HDR_TYPE_OTHER: 619 EFX_EV_QSTAT_INCR(eep, EV_RX_NON_IP); 620 flags = 0; 621 break; 622 623 default: 624 EFSYS_ASSERT(B_FALSE); 625 flags = 0; 626 break; 627 } 628 629 #if EFSYS_OPT_RX_SCATTER 630 /* Report scatter and header/lookahead split buffer flags */ 631 if (sop) 632 flags |= EFX_PKT_START; 633 if (jumbo_cont) 634 flags |= EFX_PKT_CONT; 635 #endif /* EFSYS_OPT_RX_SCATTER */ 636 637 /* Detect errors included in the FSF_AZ_RX_EV_PKT_OK indication */ 638 if (!ok) { 639 ignore = siena_ev_rx_not_ok(eep, eqp, label, id, &flags); 640 if (ignore) { 641 EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id, 642 uint32_t, size, uint16_t, flags); 643 644 return (B_FALSE); 645 } 646 } 647 648 /* If we're not discarding the packet then it is ok */ 649 if (~flags & EFX_DISCARD) 650 EFX_EV_QSTAT_INCR(eep, EV_RX_OK); 651 652 /* Detect multicast packets that didn't match the filter */ 653 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_PKT) != 0) { 654 EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_PKT); 655 656 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_MCAST_HASH_MATCH) != 0) { 657 EFX_EV_QSTAT_INCR(eep, EV_RX_MCAST_HASH_MATCH); 658 } else { 659 EFSYS_PROBE(mcast_mismatch); 660 flags |= EFX_ADDR_MISMATCH; 661 } 662 } else { 663 flags |= EFX_PKT_UNICAST; 664 } 665 666 /* 667 * The packet parser in Siena can abort parsing packets under 668 * certain error conditions, setting the PKT_NOT_PARSED bit 669 * (which clears PKT_OK). If this is set, then don't trust 670 * the PKT_TYPE field. 671 */ 672 if (!ok) { 673 uint32_t parse_err; 674 675 parse_err = EFX_QWORD_FIELD(*eqp, FSF_CZ_RX_EV_PKT_NOT_PARSED); 676 if (parse_err != 0) 677 flags |= EFX_CHECK_VLAN; 678 } 679 680 if (~flags & EFX_CHECK_VLAN) { 681 uint32_t pkt_type; 682 683 pkt_type = EFX_QWORD_FIELD(*eqp, FSF_AZ_RX_EV_PKT_TYPE); 684 if (pkt_type >= FSE_AZ_RX_EV_PKT_TYPE_VLAN) 685 flags |= EFX_PKT_VLAN_TAGGED; 686 } 687 688 EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id, 689 uint32_t, size, uint16_t, flags); 690 691 EFSYS_ASSERT(eecp->eec_rx != NULL); 692 should_abort = eecp->eec_rx(arg, label, id, size, flags); 693 694 return (should_abort); 695 } 696 697 static __checkReturn boolean_t 698 siena_ev_tx( 699 __in efx_evq_t *eep, 700 __in efx_qword_t *eqp, 701 __in const efx_ev_callbacks_t *eecp, 702 __in_opt void *arg) 703 { 704 uint32_t id; 705 uint32_t label; 706 boolean_t should_abort; 707 708 EFX_EV_QSTAT_INCR(eep, EV_TX); 709 710 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0 && 711 EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) == 0 && 712 EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) == 0 && 713 EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) == 0) { 714 715 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_DESC_PTR); 716 label = EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_Q_LABEL); 717 718 EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id); 719 720 EFSYS_ASSERT(eecp->eec_tx != NULL); 721 should_abort = eecp->eec_tx(arg, label, id); 722 723 return (should_abort); 724 } 725 726 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_COMP) != 0) 727 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index, 728 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1), 729 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0)); 730 731 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_ERR) != 0) 732 EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_ERR); 733 734 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_PKT_TOO_BIG) != 0) 735 EFX_EV_QSTAT_INCR(eep, EV_TX_PKT_TOO_BIG); 736 737 if (EFX_QWORD_FIELD(*eqp, FSF_AZ_TX_EV_WQ_FF_FULL) != 0) 738 EFX_EV_QSTAT_INCR(eep, EV_TX_WQ_FF_FULL); 739 740 EFX_EV_QSTAT_INCR(eep, EV_TX_UNEXPECTED); 741 return (B_FALSE); 742 } 743 744 static __checkReturn boolean_t 745 siena_ev_global( 746 __in efx_evq_t *eep, 747 __in efx_qword_t *eqp, 748 __in const efx_ev_callbacks_t *eecp, 749 __in_opt void *arg) 750 { 751 _NOTE(ARGUNUSED(eqp, eecp, arg)) 752 753 EFX_EV_QSTAT_INCR(eep, EV_GLOBAL); 754 755 return (B_FALSE); 756 } 757 758 static __checkReturn boolean_t 759 siena_ev_driver( 760 __in efx_evq_t *eep, 761 __in efx_qword_t *eqp, 762 __in const efx_ev_callbacks_t *eecp, 763 __in_opt void *arg) 764 { 765 boolean_t should_abort; 766 767 EFX_EV_QSTAT_INCR(eep, EV_DRIVER); 768 should_abort = B_FALSE; 769 770 switch (EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBCODE)) { 771 case FSE_AZ_TX_DESCQ_FLS_DONE_EV: { 772 uint32_t txq_index; 773 774 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE); 775 776 txq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); 777 778 EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index); 779 780 EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL); 781 should_abort = eecp->eec_txq_flush_done(arg, txq_index); 782 783 break; 784 } 785 case FSE_AZ_RX_DESCQ_FLS_DONE_EV: { 786 uint32_t rxq_index; 787 uint32_t failed; 788 789 rxq_index = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_DESCQ_ID); 790 failed = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL); 791 792 EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL); 793 EFSYS_ASSERT(eecp->eec_rxq_flush_failed != NULL); 794 795 if (failed) { 796 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_FAILED); 797 798 EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, rxq_index); 799 800 should_abort = eecp->eec_rxq_flush_failed(arg, 801 rxq_index); 802 } else { 803 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE); 804 805 EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index); 806 807 should_abort = eecp->eec_rxq_flush_done(arg, rxq_index); 808 } 809 810 break; 811 } 812 case FSE_AZ_EVQ_INIT_DONE_EV: 813 EFSYS_ASSERT(eecp->eec_initialized != NULL); 814 should_abort = eecp->eec_initialized(arg); 815 816 break; 817 818 case FSE_AZ_EVQ_NOT_EN_EV: 819 EFSYS_PROBE(evq_not_en); 820 break; 821 822 case FSE_AZ_SRM_UPD_DONE_EV: { 823 uint32_t code; 824 825 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_SRM_UPD_DONE); 826 827 code = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); 828 829 EFSYS_ASSERT(eecp->eec_sram != NULL); 830 should_abort = eecp->eec_sram(arg, code); 831 832 break; 833 } 834 case FSE_AZ_WAKE_UP_EV: { 835 uint32_t id; 836 837 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); 838 839 EFSYS_ASSERT(eecp->eec_wake_up != NULL); 840 should_abort = eecp->eec_wake_up(arg, id); 841 842 break; 843 } 844 case FSE_AZ_TX_PKT_NON_TCP_UDP: 845 EFSYS_PROBE(tx_pkt_non_tcp_udp); 846 break; 847 848 case FSE_AZ_TIMER_EV: { 849 uint32_t id; 850 851 id = EFX_QWORD_FIELD(*eqp, FSF_AZ_DRIVER_EV_SUBDATA); 852 853 EFSYS_ASSERT(eecp->eec_timer != NULL); 854 should_abort = eecp->eec_timer(arg, id); 855 856 break; 857 } 858 case FSE_AZ_RX_DSC_ERROR_EV: 859 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DSC_ERROR); 860 861 EFSYS_PROBE(rx_dsc_error); 862 863 EFSYS_ASSERT(eecp->eec_exception != NULL); 864 should_abort = eecp->eec_exception(arg, 865 EFX_EXCEPTION_RX_DSC_ERROR, 0); 866 867 break; 868 869 case FSE_AZ_TX_DSC_ERROR_EV: 870 EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DSC_ERROR); 871 872 EFSYS_PROBE(tx_dsc_error); 873 874 EFSYS_ASSERT(eecp->eec_exception != NULL); 875 should_abort = eecp->eec_exception(arg, 876 EFX_EXCEPTION_TX_DSC_ERROR, 0); 877 878 break; 879 880 default: 881 break; 882 } 883 884 return (should_abort); 885 } 886 887 static __checkReturn boolean_t 888 siena_ev_drv_gen( 889 __in efx_evq_t *eep, 890 __in efx_qword_t *eqp, 891 __in const efx_ev_callbacks_t *eecp, 892 __in_opt void *arg) 893 { 894 uint32_t data; 895 boolean_t should_abort; 896 897 EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN); 898 899 data = EFX_QWORD_FIELD(*eqp, FSF_AZ_EV_DATA_DW0); 900 if (data >= ((uint32_t)1 << 16)) { 901 EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index, 902 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1), 903 uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0)); 904 return (B_TRUE); 905 } 906 907 EFSYS_ASSERT(eecp->eec_software != NULL); 908 should_abort = eecp->eec_software(arg, (uint16_t)data); 909 910 return (should_abort); 911 } 912 913 #if EFSYS_OPT_MCDI 914 915 static __checkReturn boolean_t 916 siena_ev_mcdi( 917 __in efx_evq_t *eep, 918 __in efx_qword_t *eqp, 919 __in const efx_ev_callbacks_t *eecp, 920 __in_opt void *arg) 921 { 922 efx_nic_t *enp = eep->ee_enp; 923 unsigned code; 924 boolean_t should_abort = B_FALSE; 925 926 EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA); 927 928 if (enp->en_family != EFX_FAMILY_SIENA) 929 goto out; 930 931 EFSYS_ASSERT(eecp->eec_link_change != NULL); 932 EFSYS_ASSERT(eecp->eec_exception != NULL); 933 #if EFSYS_OPT_MON_STATS 934 EFSYS_ASSERT(eecp->eec_monitor != NULL); 935 #endif 936 937 EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE); 938 939 code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE); 940 switch (code) { 941 case MCDI_EVENT_CODE_BADSSERT: 942 efx_mcdi_ev_death(enp, EINTR); 943 break; 944 945 case MCDI_EVENT_CODE_CMDDONE: 946 efx_mcdi_ev_cpl(enp, 947 MCDI_EV_FIELD(eqp, CMDDONE_SEQ), 948 MCDI_EV_FIELD(eqp, CMDDONE_DATALEN), 949 MCDI_EV_FIELD(eqp, CMDDONE_ERRNO)); 950 break; 951 952 case MCDI_EVENT_CODE_LINKCHANGE: { 953 efx_link_mode_t link_mode; 954 955 siena_phy_link_ev(enp, eqp, &link_mode); 956 should_abort = eecp->eec_link_change(arg, link_mode); 957 break; 958 } 959 case MCDI_EVENT_CODE_SENSOREVT: { 960 #if EFSYS_OPT_MON_STATS 961 efx_mon_stat_t id; 962 efx_mon_stat_value_t value; 963 efx_rc_t rc; 964 965 if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) 966 should_abort = eecp->eec_monitor(arg, id, value); 967 else if (rc == ENOTSUP) { 968 should_abort = eecp->eec_exception(arg, 969 EFX_EXCEPTION_UNKNOWN_SENSOREVT, 970 MCDI_EV_FIELD(eqp, DATA)); 971 } else 972 EFSYS_ASSERT(rc == ENODEV); /* Wrong port */ 973 #else 974 should_abort = B_FALSE; 975 #endif 976 break; 977 } 978 case MCDI_EVENT_CODE_SCHEDERR: 979 /* Informational only */ 980 break; 981 982 case MCDI_EVENT_CODE_REBOOT: 983 efx_mcdi_ev_death(enp, EIO); 984 break; 985 986 case MCDI_EVENT_CODE_MAC_STATS_DMA: 987 #if EFSYS_OPT_MAC_STATS 988 if (eecp->eec_mac_stats != NULL) { 989 eecp->eec_mac_stats(arg, 990 MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION)); 991 } 992 #endif 993 break; 994 995 case MCDI_EVENT_CODE_FWALERT: { 996 uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON); 997 998 if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS) 999 should_abort = eecp->eec_exception(arg, 1000 EFX_EXCEPTION_FWALERT_SRAM, 1001 MCDI_EV_FIELD(eqp, FWALERT_DATA)); 1002 else 1003 should_abort = eecp->eec_exception(arg, 1004 EFX_EXCEPTION_UNKNOWN_FWALERT, 1005 MCDI_EV_FIELD(eqp, DATA)); 1006 break; 1007 } 1008 1009 default: 1010 EFSYS_PROBE1(mc_pcol_error, int, code); 1011 break; 1012 } 1013 1014 out: 1015 return (should_abort); 1016 } 1017 1018 #endif /* EFSYS_OPT_MCDI */ 1019 1020 static __checkReturn efx_rc_t 1021 siena_ev_qprime( 1022 __in efx_evq_t *eep, 1023 __in unsigned int count) 1024 { 1025 efx_nic_t *enp = eep->ee_enp; 1026 uint32_t rptr; 1027 efx_dword_t dword; 1028 1029 rptr = count & eep->ee_mask; 1030 1031 EFX_POPULATE_DWORD_1(dword, FRF_AZ_EVQ_RPTR, rptr); 1032 1033 EFX_BAR_TBL_WRITED(enp, FR_AZ_EVQ_RPTR_REG, eep->ee_index, 1034 &dword, B_FALSE); 1035 1036 return (0); 1037 } 1038 1039 #define EFX_EV_BATCH 8 1040 1041 static void 1042 siena_ev_qpoll( 1043 __in efx_evq_t *eep, 1044 __inout unsigned int *countp, 1045 __in const efx_ev_callbacks_t *eecp, 1046 __in_opt void *arg) 1047 { 1048 efx_qword_t ev[EFX_EV_BATCH]; 1049 unsigned int batch; 1050 unsigned int total; 1051 unsigned int count; 1052 unsigned int index; 1053 size_t offset; 1054 1055 EFSYS_ASSERT(countp != NULL); 1056 EFSYS_ASSERT(eecp != NULL); 1057 1058 count = *countp; 1059 do { 1060 /* Read up until the end of the batch period */ 1061 batch = EFX_EV_BATCH - (count & (EFX_EV_BATCH - 1)); 1062 offset = (count & eep->ee_mask) * sizeof (efx_qword_t); 1063 for (total = 0; total < batch; ++total) { 1064 EFSYS_MEM_READQ(eep->ee_esmp, offset, &(ev[total])); 1065 1066 if (!EFX_EV_PRESENT(ev[total])) 1067 break; 1068 1069 EFSYS_PROBE3(event, unsigned int, eep->ee_index, 1070 uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_1), 1071 uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_0)); 1072 1073 offset += sizeof (efx_qword_t); 1074 } 1075 1076 #if EFSYS_OPT_EV_PREFETCH && (EFSYS_OPT_EV_PREFETCH_PERIOD > 1) 1077 /* 1078 * Prefetch the next batch when we get within PREFETCH_PERIOD 1079 * of a completed batch. If the batch is smaller, then prefetch 1080 * immediately. 1081 */ 1082 if (total == batch && total < EFSYS_OPT_EV_PREFETCH_PERIOD) 1083 EFSYS_MEM_PREFETCH(eep->ee_esmp, offset); 1084 #endif /* EFSYS_OPT_EV_PREFETCH */ 1085 1086 /* Process the batch of events */ 1087 for (index = 0; index < total; ++index) { 1088 boolean_t should_abort; 1089 uint32_t code; 1090 1091 #if EFSYS_OPT_EV_PREFETCH 1092 /* Prefetch if we've now reached the batch period */ 1093 if (total == batch && 1094 index + EFSYS_OPT_EV_PREFETCH_PERIOD == total) { 1095 offset = (count + batch) & eep->ee_mask; 1096 offset *= sizeof (efx_qword_t); 1097 1098 EFSYS_MEM_PREFETCH(eep->ee_esmp, offset); 1099 } 1100 #endif /* EFSYS_OPT_EV_PREFETCH */ 1101 1102 EFX_EV_QSTAT_INCR(eep, EV_ALL); 1103 1104 code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE); 1105 switch (code) { 1106 case FSE_AZ_EV_CODE_RX_EV: 1107 should_abort = eep->ee_rx(eep, 1108 &(ev[index]), eecp, arg); 1109 break; 1110 case FSE_AZ_EV_CODE_TX_EV: 1111 should_abort = eep->ee_tx(eep, 1112 &(ev[index]), eecp, arg); 1113 break; 1114 case FSE_AZ_EV_CODE_DRIVER_EV: 1115 should_abort = eep->ee_driver(eep, 1116 &(ev[index]), eecp, arg); 1117 break; 1118 case FSE_AZ_EV_CODE_DRV_GEN_EV: 1119 should_abort = eep->ee_drv_gen(eep, 1120 &(ev[index]), eecp, arg); 1121 break; 1122 #if EFSYS_OPT_MCDI 1123 case FSE_AZ_EV_CODE_MCDI_EVRESPONSE: 1124 should_abort = eep->ee_mcdi(eep, 1125 &(ev[index]), eecp, arg); 1126 break; 1127 #endif 1128 case FSE_AZ_EV_CODE_GLOBAL_EV: 1129 if (eep->ee_global) { 1130 should_abort = eep->ee_global(eep, 1131 &(ev[index]), eecp, arg); 1132 break; 1133 } 1134 /* else fallthrough */ 1135 default: 1136 EFSYS_PROBE3(bad_event, 1137 unsigned int, eep->ee_index, 1138 uint32_t, 1139 EFX_QWORD_FIELD(ev[index], EFX_DWORD_1), 1140 uint32_t, 1141 EFX_QWORD_FIELD(ev[index], EFX_DWORD_0)); 1142 1143 EFSYS_ASSERT(eecp->eec_exception != NULL); 1144 (void) eecp->eec_exception(arg, 1145 EFX_EXCEPTION_EV_ERROR, code); 1146 should_abort = B_TRUE; 1147 } 1148 if (should_abort) { 1149 /* Ignore subsequent events */ 1150 total = index + 1; 1151 break; 1152 } 1153 } 1154 1155 /* 1156 * Now that the hardware has most likely moved onto dma'ing 1157 * into the next cache line, clear the processed events. Take 1158 * care to only clear out events that we've processed 1159 */ 1160 EFX_SET_QWORD(ev[0]); 1161 offset = (count & eep->ee_mask) * sizeof (efx_qword_t); 1162 for (index = 0; index < total; ++index) { 1163 EFSYS_MEM_WRITEQ(eep->ee_esmp, offset, &(ev[0])); 1164 offset += sizeof (efx_qword_t); 1165 } 1166 1167 count += total; 1168 1169 } while (total == batch); 1170 1171 *countp = count; 1172 } 1173 1174 static void 1175 siena_ev_qpost( 1176 __in efx_evq_t *eep, 1177 __in uint16_t data) 1178 { 1179 efx_nic_t *enp = eep->ee_enp; 1180 efx_qword_t ev; 1181 efx_oword_t oword; 1182 1183 EFX_POPULATE_QWORD_2(ev, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV, 1184 FSF_AZ_EV_DATA_DW0, (uint32_t)data); 1185 1186 EFX_POPULATE_OWORD_3(oword, FRF_AZ_DRV_EV_QID, eep->ee_index, 1187 EFX_DWORD_0, EFX_QWORD_FIELD(ev, EFX_DWORD_0), 1188 EFX_DWORD_1, EFX_QWORD_FIELD(ev, EFX_DWORD_1)); 1189 1190 EFX_BAR_WRITEO(enp, FR_AZ_DRV_EV_REG, &oword); 1191 } 1192 1193 static __checkReturn efx_rc_t 1194 siena_ev_qmoderate( 1195 __in efx_evq_t *eep, 1196 __in unsigned int us) 1197 { 1198 efx_nic_t *enp = eep->ee_enp; 1199 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1200 unsigned int locked; 1201 efx_dword_t dword; 1202 efx_rc_t rc; 1203 1204 if (us > encp->enc_evq_timer_max_us) { 1205 rc = EINVAL; 1206 goto fail1; 1207 } 1208 1209 /* If the value is zero then disable the timer */ 1210 if (us == 0) { 1211 EFX_POPULATE_DWORD_2(dword, 1212 FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_DIS, 1213 FRF_CZ_TC_TIMER_VAL, 0); 1214 } else { 1215 uint32_t timer_val; 1216 1217 /* Calculate the timer value in quanta */ 1218 timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns; 1219 1220 /* Moderation value is base 0 so we need to deduct 1 */ 1221 if (timer_val > 0) 1222 timer_val--; 1223 1224 EFX_POPULATE_DWORD_2(dword, 1225 FRF_CZ_TC_TIMER_MODE, FFE_CZ_TIMER_MODE_INT_HLDOFF, 1226 FRF_CZ_TC_TIMER_VAL, timer_val); 1227 } 1228 1229 locked = (eep->ee_index == 0) ? 1 : 0; 1230 1231 EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0, 1232 eep->ee_index, &dword, locked); 1233 1234 return (0); 1235 1236 fail1: 1237 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1238 1239 return (rc); 1240 } 1241 1242 static __checkReturn efx_rc_t 1243 siena_ev_qcreate( 1244 __in efx_nic_t *enp, 1245 __in unsigned int index, 1246 __in efsys_mem_t *esmp, 1247 __in size_t n, 1248 __in uint32_t id, 1249 __in efx_evq_t *eep) 1250 { 1251 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 1252 uint32_t size; 1253 efx_oword_t oword; 1254 efx_rc_t rc; 1255 1256 EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS)); 1257 EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS)); 1258 1259 if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) { 1260 rc = EINVAL; 1261 goto fail1; 1262 } 1263 if (index >= encp->enc_evq_limit) { 1264 rc = EINVAL; 1265 goto fail2; 1266 } 1267 #if EFSYS_OPT_RX_SCALE 1268 if (enp->en_intr.ei_type == EFX_INTR_LINE && 1269 index >= EFX_MAXRSS_LEGACY) { 1270 rc = EINVAL; 1271 goto fail3; 1272 } 1273 #endif 1274 for (size = 0; (1 << size) <= (EFX_EVQ_MAXNEVS / EFX_EVQ_MINNEVS); 1275 size++) 1276 if ((1 << size) == (int)(n / EFX_EVQ_MINNEVS)) 1277 break; 1278 if (id + (1 << size) >= encp->enc_buftbl_limit) { 1279 rc = EINVAL; 1280 goto fail4; 1281 } 1282 1283 /* Set up the handler table */ 1284 eep->ee_rx = siena_ev_rx; 1285 eep->ee_tx = siena_ev_tx; 1286 eep->ee_driver = siena_ev_driver; 1287 eep->ee_global = siena_ev_global; 1288 eep->ee_drv_gen = siena_ev_drv_gen; 1289 #if EFSYS_OPT_MCDI 1290 eep->ee_mcdi = siena_ev_mcdi; 1291 #endif /* EFSYS_OPT_MCDI */ 1292 1293 /* Set up the new event queue */ 1294 EFX_POPULATE_OWORD_1(oword, FRF_CZ_TIMER_Q_EN, 1); 1295 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword, B_TRUE); 1296 1297 EFX_POPULATE_OWORD_3(oword, FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, size, 1298 FRF_AZ_EVQ_BUF_BASE_ID, id); 1299 1300 EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword, B_TRUE); 1301 1302 return (0); 1303 1304 fail4: 1305 EFSYS_PROBE(fail4); 1306 #if EFSYS_OPT_RX_SCALE 1307 fail3: 1308 EFSYS_PROBE(fail3); 1309 #endif 1310 fail2: 1311 EFSYS_PROBE(fail2); 1312 fail1: 1313 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1314 1315 return (rc); 1316 } 1317 1318 #endif /* EFSYS_OPT_SIENA */ 1319 1320 #if EFSYS_OPT_QSTATS 1321 #if EFSYS_OPT_NAMES 1322 /* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock b693ddf85aee1bfd */ 1323 static const char *__efx_ev_qstat_name[] = { 1324 "all", 1325 "rx", 1326 "rx_ok", 1327 "rx_frm_trunc", 1328 "rx_tobe_disc", 1329 "rx_pause_frm_err", 1330 "rx_buf_owner_id_err", 1331 "rx_ipv4_hdr_chksum_err", 1332 "rx_tcp_udp_chksum_err", 1333 "rx_eth_crc_err", 1334 "rx_ip_frag_err", 1335 "rx_mcast_pkt", 1336 "rx_mcast_hash_match", 1337 "rx_tcp_ipv4", 1338 "rx_tcp_ipv6", 1339 "rx_udp_ipv4", 1340 "rx_udp_ipv6", 1341 "rx_other_ipv4", 1342 "rx_other_ipv6", 1343 "rx_non_ip", 1344 "rx_batch", 1345 "tx", 1346 "tx_wq_ff_full", 1347 "tx_pkt_err", 1348 "tx_pkt_too_big", 1349 "tx_unexpected", 1350 "global", 1351 "global_mnt", 1352 "driver", 1353 "driver_srm_upd_done", 1354 "driver_tx_descq_fls_done", 1355 "driver_rx_descq_fls_done", 1356 "driver_rx_descq_fls_failed", 1357 "driver_rx_dsc_error", 1358 "driver_tx_dsc_error", 1359 "drv_gen", 1360 "mcdi_response", 1361 }; 1362 /* END MKCONFIG GENERATED EfxEventQueueStatNamesBlock */ 1363 1364 const char * 1365 efx_ev_qstat_name( 1366 __in efx_nic_t *enp, 1367 __in unsigned int id) 1368 { 1369 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 1370 EFSYS_ASSERT3U(id, <, EV_NQSTATS); 1371 1372 return (__efx_ev_qstat_name[id]); 1373 } 1374 #endif /* EFSYS_OPT_NAMES */ 1375 #endif /* EFSYS_OPT_QSTATS */ 1376 1377 #if EFSYS_OPT_SIENA 1378 1379 #if EFSYS_OPT_QSTATS 1380 static void 1381 siena_ev_qstats_update( 1382 __in efx_evq_t *eep, 1383 __inout_ecount(EV_NQSTATS) efsys_stat_t *stat) 1384 { 1385 unsigned int id; 1386 1387 for (id = 0; id < EV_NQSTATS; id++) { 1388 efsys_stat_t *essp = &stat[id]; 1389 1390 EFSYS_STAT_INCR(essp, eep->ee_stat[id]); 1391 eep->ee_stat[id] = 0; 1392 } 1393 } 1394 #endif /* EFSYS_OPT_QSTATS */ 1395 1396 static void 1397 siena_ev_qdestroy( 1398 __in efx_evq_t *eep) 1399 { 1400 efx_nic_t *enp = eep->ee_enp; 1401 efx_oword_t oword; 1402 1403 /* Purge event queue */ 1404 EFX_ZERO_OWORD(oword); 1405 1406 EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, 1407 eep->ee_index, &oword, B_TRUE); 1408 1409 EFX_ZERO_OWORD(oword); 1410 EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, eep->ee_index, &oword, B_TRUE); 1411 } 1412 1413 static void 1414 siena_ev_fini( 1415 __in efx_nic_t *enp) 1416 { 1417 _NOTE(ARGUNUSED(enp)) 1418 } 1419 1420 #endif /* EFSYS_OPT_SIENA */ 1421