1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2013-2016 Qlogic Corporation 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 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * File: ql_isr.c 32 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 33 */ 34 35 #include <sys/cdefs.h> 36 __FBSDID("$FreeBSD$"); 37 38 39 #include "ql_os.h" 40 #include "ql_hw.h" 41 #include "ql_def.h" 42 #include "ql_inline.h" 43 #include "ql_ver.h" 44 #include "ql_glbl.h" 45 #include "ql_dbg.h" 46 47 static void qla_replenish_normal_rx(qla_host_t *ha, qla_sds_t *sdsp, 48 uint32_t r_idx); 49 50 static void 51 qla_rcv_error(qla_host_t *ha) 52 { 53 ha->stop_rcv = 1; 54 QL_INITIATE_RECOVERY(ha); 55 } 56 57 58 /* 59 * Name: qla_rx_intr 60 * Function: Handles normal ethernet frames received 61 */ 62 static void 63 qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_t *sgc, uint32_t sds_idx) 64 { 65 qla_rx_buf_t *rxb; 66 struct mbuf *mp = NULL, *mpf = NULL, *mpl = NULL; 67 struct ifnet *ifp = ha->ifp; 68 qla_sds_t *sdsp; 69 struct ether_vlan_header *eh; 70 uint32_t i, rem_len = 0; 71 uint32_t r_idx = 0; 72 qla_rx_ring_t *rx_ring; 73 struct lro_ctrl *lro; 74 75 lro = &ha->hw.sds[sds_idx].lro; 76 77 if (ha->hw.num_rds_rings > 1) 78 r_idx = sds_idx; 79 80 ha->hw.rds[r_idx].count++; 81 82 sdsp = &ha->hw.sds[sds_idx]; 83 rx_ring = &ha->rx_ring[r_idx]; 84 85 for (i = 0; i < sgc->num_handles; i++) { 86 rxb = &rx_ring->rx_buf[sgc->handle[i] & 0x7FFF]; 87 88 QL_ASSERT(ha, (rxb != NULL), 89 ("%s: [sds_idx]=[%d] rxb != NULL\n", __func__,\ 90 sds_idx)); 91 92 if ((rxb == NULL) || QL_ERR_INJECT(ha, INJCT_RX_RXB_INVAL)) { 93 /* log the error */ 94 device_printf(ha->pci_dev, 95 "%s invalid rxb[%d, %d, 0x%04x]\n", 96 __func__, sds_idx, i, sgc->handle[i]); 97 qla_rcv_error(ha); 98 return; 99 } 100 101 mp = rxb->m_head; 102 if (i == 0) 103 mpf = mp; 104 105 QL_ASSERT(ha, (mp != NULL), 106 ("%s: [sds_idx]=[%d] mp != NULL\n", __func__,\ 107 sds_idx)); 108 109 bus_dmamap_sync(ha->rx_tag, rxb->map, BUS_DMASYNC_POSTREAD); 110 111 rxb->m_head = NULL; 112 rxb->next = sdsp->rxb_free; 113 sdsp->rxb_free = rxb; 114 sdsp->rx_free++; 115 116 if ((mp == NULL) || QL_ERR_INJECT(ha, INJCT_RX_MP_NULL)) { 117 /* log the error */ 118 device_printf(ha->pci_dev, 119 "%s mp == NULL [%d, %d, 0x%04x]\n", 120 __func__, sds_idx, i, sgc->handle[i]); 121 qla_rcv_error(ha); 122 return; 123 } 124 125 if (i == 0) { 126 mpl = mpf = mp; 127 mp->m_flags |= M_PKTHDR; 128 mp->m_pkthdr.len = sgc->pkt_length; 129 mp->m_pkthdr.rcvif = ifp; 130 rem_len = mp->m_pkthdr.len; 131 } else { 132 mp->m_flags &= ~M_PKTHDR; 133 mpl->m_next = mp; 134 mpl = mp; 135 rem_len = rem_len - mp->m_len; 136 } 137 } 138 139 mpl->m_len = rem_len; 140 141 eh = mtod(mpf, struct ether_vlan_header *); 142 143 if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 144 uint32_t *data = (uint32_t *)eh; 145 146 mpf->m_pkthdr.ether_vtag = ntohs(eh->evl_tag); 147 mpf->m_flags |= M_VLANTAG; 148 149 *(data + 3) = *(data + 2); 150 *(data + 2) = *(data + 1); 151 *(data + 1) = *data; 152 153 m_adj(mpf, ETHER_VLAN_ENCAP_LEN); 154 } 155 156 if (sgc->chksum_status == Q8_STAT_DESC_STATUS_CHKSUM_OK) { 157 mpf->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID | 158 CSUM_DATA_VALID | CSUM_PSEUDO_HDR; 159 mpf->m_pkthdr.csum_data = 0xFFFF; 160 } else { 161 mpf->m_pkthdr.csum_flags = 0; 162 } 163 164 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 165 166 mpf->m_pkthdr.flowid = sgc->rss_hash; 167 168 #if __FreeBSD_version >= 1100000 169 M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE_HASH); 170 #else 171 #if (__FreeBSD_version >= 903511 && __FreeBSD_version < 1100000) 172 M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE); 173 #else 174 M_HASHTYPE_SET(mpf, M_HASHTYPE_NONE); 175 #endif 176 #endif /* #if __FreeBSD_version >= 1100000 */ 177 178 if (ha->hw.enable_soft_lro) { 179 180 #if (__FreeBSD_version >= 1100101) 181 182 tcp_lro_queue_mbuf(lro, mpf); 183 184 #else 185 if (tcp_lro_rx(lro, mpf, 0)) 186 (*ifp->if_input)(ifp, mpf); 187 188 #endif /* #if (__FreeBSD_version >= 1100101) */ 189 190 191 } else { 192 (*ifp->if_input)(ifp, mpf); 193 } 194 195 if (sdsp->rx_free > ha->std_replenish) 196 qla_replenish_normal_rx(ha, sdsp, r_idx); 197 198 return; 199 } 200 201 #define QLA_TCP_HDR_SIZE 20 202 #define QLA_TCP_TS_OPTION_SIZE 12 203 204 /* 205 * Name: qla_lro_intr 206 * Function: Handles normal ethernet frames received 207 */ 208 static int 209 qla_lro_intr(qla_host_t *ha, qla_sgl_lro_t *sgc, uint32_t sds_idx) 210 { 211 qla_rx_buf_t *rxb; 212 struct mbuf *mp = NULL, *mpf = NULL, *mpl = NULL; 213 struct ifnet *ifp = ha->ifp; 214 qla_sds_t *sdsp; 215 struct ether_vlan_header *eh; 216 uint32_t i, rem_len = 0, pkt_length, iplen; 217 struct tcphdr *th; 218 struct ip *ip = NULL; 219 struct ip6_hdr *ip6 = NULL; 220 uint16_t etype; 221 uint32_t r_idx = 0; 222 qla_rx_ring_t *rx_ring; 223 224 if (ha->hw.num_rds_rings > 1) 225 r_idx = sds_idx; 226 227 ha->hw.rds[r_idx].count++; 228 229 rx_ring = &ha->rx_ring[r_idx]; 230 231 ha->hw.rds[r_idx].lro_pkt_count++; 232 233 sdsp = &ha->hw.sds[sds_idx]; 234 235 pkt_length = sgc->payload_length + sgc->l4_offset; 236 237 if (sgc->flags & Q8_LRO_COMP_TS) { 238 pkt_length += QLA_TCP_HDR_SIZE + QLA_TCP_TS_OPTION_SIZE; 239 } else { 240 pkt_length += QLA_TCP_HDR_SIZE; 241 } 242 ha->hw.rds[r_idx].lro_bytes += pkt_length; 243 244 for (i = 0; i < sgc->num_handles; i++) { 245 rxb = &rx_ring->rx_buf[sgc->handle[i] & 0x7FFF]; 246 247 QL_ASSERT(ha, (rxb != NULL), 248 ("%s: [sds_idx]=[%d] rxb != NULL\n", __func__,\ 249 sds_idx)); 250 251 if ((rxb == NULL) || QL_ERR_INJECT(ha, INJCT_LRO_RXB_INVAL)) { 252 /* log the error */ 253 device_printf(ha->pci_dev, 254 "%s invalid rxb[%d, %d, 0x%04x]\n", 255 __func__, sds_idx, i, sgc->handle[i]); 256 qla_rcv_error(ha); 257 return (0); 258 } 259 260 mp = rxb->m_head; 261 if (i == 0) 262 mpf = mp; 263 264 QL_ASSERT(ha, (mp != NULL), 265 ("%s: [sds_idx]=[%d] mp != NULL\n", __func__,\ 266 sds_idx)); 267 268 bus_dmamap_sync(ha->rx_tag, rxb->map, BUS_DMASYNC_POSTREAD); 269 270 rxb->m_head = NULL; 271 rxb->next = sdsp->rxb_free; 272 sdsp->rxb_free = rxb; 273 sdsp->rx_free++; 274 275 if ((mp == NULL) || QL_ERR_INJECT(ha, INJCT_LRO_MP_NULL)) { 276 /* log the error */ 277 device_printf(ha->pci_dev, 278 "%s mp == NULL [%d, %d, 0x%04x]\n", 279 __func__, sds_idx, i, sgc->handle[i]); 280 qla_rcv_error(ha); 281 return (0); 282 } 283 284 if (i == 0) { 285 mpl = mpf = mp; 286 mp->m_flags |= M_PKTHDR; 287 mp->m_pkthdr.len = pkt_length; 288 mp->m_pkthdr.rcvif = ifp; 289 rem_len = mp->m_pkthdr.len; 290 } else { 291 mp->m_flags &= ~M_PKTHDR; 292 mpl->m_next = mp; 293 mpl = mp; 294 rem_len = rem_len - mp->m_len; 295 } 296 } 297 298 mpl->m_len = rem_len; 299 300 th = (struct tcphdr *)(mpf->m_data + sgc->l4_offset); 301 302 if (sgc->flags & Q8_LRO_COMP_PUSH_BIT) 303 th->th_flags |= TH_PUSH; 304 305 m_adj(mpf, sgc->l2_offset); 306 307 eh = mtod(mpf, struct ether_vlan_header *); 308 309 if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 310 uint32_t *data = (uint32_t *)eh; 311 312 mpf->m_pkthdr.ether_vtag = ntohs(eh->evl_tag); 313 mpf->m_flags |= M_VLANTAG; 314 315 *(data + 3) = *(data + 2); 316 *(data + 2) = *(data + 1); 317 *(data + 1) = *data; 318 319 m_adj(mpf, ETHER_VLAN_ENCAP_LEN); 320 321 etype = ntohs(eh->evl_proto); 322 } else { 323 etype = ntohs(eh->evl_encap_proto); 324 } 325 326 if (etype == ETHERTYPE_IP) { 327 ip = (struct ip *)(mpf->m_data + ETHER_HDR_LEN); 328 329 iplen = (ip->ip_hl << 2) + (th->th_off << 2) + 330 sgc->payload_length; 331 332 ip->ip_len = htons(iplen); 333 334 ha->ipv4_lro++; 335 336 M_HASHTYPE_SET(mpf, M_HASHTYPE_RSS_TCP_IPV4); 337 338 } else if (etype == ETHERTYPE_IPV6) { 339 ip6 = (struct ip6_hdr *)(mpf->m_data + ETHER_HDR_LEN); 340 341 iplen = (th->th_off << 2) + sgc->payload_length; 342 343 ip6->ip6_plen = htons(iplen); 344 345 ha->ipv6_lro++; 346 347 M_HASHTYPE_SET(mpf, M_HASHTYPE_RSS_TCP_IPV6); 348 349 } else { 350 m_freem(mpf); 351 352 if (sdsp->rx_free > ha->std_replenish) 353 qla_replenish_normal_rx(ha, sdsp, r_idx); 354 return 0; 355 } 356 357 mpf->m_pkthdr.csum_flags = CSUM_IP_CHECKED | CSUM_IP_VALID | 358 CSUM_DATA_VALID | CSUM_PSEUDO_HDR; 359 mpf->m_pkthdr.csum_data = 0xFFFF; 360 361 mpf->m_pkthdr.flowid = sgc->rss_hash; 362 363 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 364 365 (*ifp->if_input)(ifp, mpf); 366 367 if (sdsp->rx_free > ha->std_replenish) 368 qla_replenish_normal_rx(ha, sdsp, r_idx); 369 370 return (0); 371 } 372 373 static int 374 qla_rcv_cont_sds(qla_host_t *ha, uint32_t sds_idx, uint32_t comp_idx, 375 uint32_t dcount, uint16_t *handle, uint16_t *nhandles) 376 { 377 uint32_t i; 378 uint16_t num_handles; 379 q80_stat_desc_t *sdesc; 380 uint32_t opcode; 381 382 *nhandles = 0; 383 dcount--; 384 385 for (i = 0; i < dcount; i++) { 386 comp_idx = (comp_idx + 1) & (NUM_STATUS_DESCRIPTORS-1); 387 sdesc = (q80_stat_desc_t *) 388 &ha->hw.sds[sds_idx].sds_ring_base[comp_idx]; 389 390 opcode = Q8_STAT_DESC_OPCODE((sdesc->data[1])); 391 392 if (!opcode || QL_ERR_INJECT(ha, INJCT_INV_CONT_OPCODE)) { 393 device_printf(ha->pci_dev, "%s: opcode=0 %p %p\n", 394 __func__, (void *)sdesc->data[0], 395 (void *)sdesc->data[1]); 396 return -1; 397 } 398 399 num_handles = Q8_SGL_STAT_DESC_NUM_HANDLES((sdesc->data[1])); 400 if (!num_handles) { 401 device_printf(ha->pci_dev, "%s: opcode=0 %p %p\n", 402 __func__, (void *)sdesc->data[0], 403 (void *)sdesc->data[1]); 404 return -1; 405 } 406 407 if (QL_ERR_INJECT(ha, INJCT_NUM_HNDLE_INVALID)) 408 num_handles = -1; 409 410 switch (num_handles) { 411 412 case 1: 413 *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0])); 414 break; 415 416 case 2: 417 *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0])); 418 *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0])); 419 break; 420 421 case 3: 422 *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0])); 423 *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0])); 424 *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0])); 425 break; 426 427 case 4: 428 *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0])); 429 *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0])); 430 *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0])); 431 *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0])); 432 break; 433 434 case 5: 435 *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0])); 436 *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0])); 437 *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0])); 438 *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0])); 439 *handle++ = Q8_SGL_STAT_DESC_HANDLE5((sdesc->data[1])); 440 break; 441 442 case 6: 443 *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0])); 444 *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0])); 445 *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0])); 446 *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0])); 447 *handle++ = Q8_SGL_STAT_DESC_HANDLE5((sdesc->data[1])); 448 *handle++ = Q8_SGL_STAT_DESC_HANDLE6((sdesc->data[1])); 449 break; 450 451 case 7: 452 *handle++ = Q8_SGL_STAT_DESC_HANDLE1((sdesc->data[0])); 453 *handle++ = Q8_SGL_STAT_DESC_HANDLE2((sdesc->data[0])); 454 *handle++ = Q8_SGL_STAT_DESC_HANDLE3((sdesc->data[0])); 455 *handle++ = Q8_SGL_STAT_DESC_HANDLE4((sdesc->data[0])); 456 *handle++ = Q8_SGL_STAT_DESC_HANDLE5((sdesc->data[1])); 457 *handle++ = Q8_SGL_STAT_DESC_HANDLE6((sdesc->data[1])); 458 *handle++ = Q8_SGL_STAT_DESC_HANDLE7((sdesc->data[1])); 459 break; 460 461 default: 462 device_printf(ha->pci_dev, 463 "%s: invalid num handles %p %p\n", 464 __func__, (void *)sdesc->data[0], 465 (void *)sdesc->data[1]); 466 467 QL_ASSERT(ha, (0),\ 468 ("%s: %s [nh, sds, d0, d1]=[%d, %d, %p, %p]\n", 469 __func__, "invalid num handles", sds_idx, num_handles, 470 (void *)sdesc->data[0],(void *)sdesc->data[1])); 471 472 qla_rcv_error(ha); 473 return 0; 474 } 475 *nhandles = *nhandles + num_handles; 476 } 477 return 0; 478 } 479 480 /* 481 * Name: ql_rcv_isr 482 * Function: Main Interrupt Service Routine 483 */ 484 uint32_t 485 ql_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count) 486 { 487 device_t dev; 488 qla_hw_t *hw; 489 uint32_t comp_idx, c_idx = 0, desc_count = 0, opcode; 490 volatile q80_stat_desc_t *sdesc, *sdesc0 = NULL; 491 uint32_t ret = 0; 492 qla_sgl_comp_t sgc; 493 uint16_t nhandles; 494 uint32_t sds_replenish_threshold = 0; 495 uint32_t r_idx = 0; 496 qla_sds_t *sdsp; 497 498 dev = ha->pci_dev; 499 hw = &ha->hw; 500 501 hw->sds[sds_idx].rcv_active = 1; 502 if (ha->stop_rcv) { 503 hw->sds[sds_idx].rcv_active = 0; 504 return 0; 505 } 506 507 QL_DPRINT2(ha, (dev, "%s: [%d]enter\n", __func__, sds_idx)); 508 509 /* 510 * receive interrupts 511 */ 512 comp_idx = hw->sds[sds_idx].sdsr_next; 513 514 while (count-- && !ha->stop_rcv) { 515 516 sdesc = (q80_stat_desc_t *) 517 &hw->sds[sds_idx].sds_ring_base[comp_idx]; 518 519 opcode = Q8_STAT_DESC_OPCODE((sdesc->data[1])); 520 521 if (!opcode) 522 break; 523 524 switch (opcode) { 525 526 case Q8_STAT_DESC_OPCODE_RCV_PKT: 527 528 desc_count = 1; 529 530 bzero(&sgc, sizeof(qla_sgl_comp_t)); 531 532 sgc.rcv.pkt_length = 533 Q8_STAT_DESC_TOTAL_LENGTH((sdesc->data[0])); 534 sgc.rcv.num_handles = 1; 535 sgc.rcv.handle[0] = 536 Q8_STAT_DESC_HANDLE((sdesc->data[0])); 537 sgc.rcv.chksum_status = 538 Q8_STAT_DESC_STATUS((sdesc->data[1])); 539 540 sgc.rcv.rss_hash = 541 Q8_STAT_DESC_RSS_HASH((sdesc->data[0])); 542 543 if (Q8_STAT_DESC_VLAN((sdesc->data[1]))) { 544 sgc.rcv.vlan_tag = 545 Q8_STAT_DESC_VLAN_ID((sdesc->data[1])); 546 } 547 qla_rx_intr(ha, &sgc.rcv, sds_idx); 548 break; 549 550 case Q8_STAT_DESC_OPCODE_SGL_RCV: 551 552 desc_count = 553 Q8_STAT_DESC_COUNT_SGL_RCV((sdesc->data[1])); 554 555 if (desc_count > 1) { 556 c_idx = (comp_idx + desc_count -1) & 557 (NUM_STATUS_DESCRIPTORS-1); 558 sdesc0 = (q80_stat_desc_t *) 559 &hw->sds[sds_idx].sds_ring_base[c_idx]; 560 561 if ((Q8_STAT_DESC_OPCODE((sdesc0->data[1])) != 562 Q8_STAT_DESC_OPCODE_CONT) || 563 QL_ERR_INJECT(ha, INJCT_SGL_RCV_INV_DESC_COUNT)) { 564 desc_count = 0; 565 break; 566 } 567 } 568 569 bzero(&sgc, sizeof(qla_sgl_comp_t)); 570 571 sgc.rcv.pkt_length = 572 Q8_STAT_DESC_TOTAL_LENGTH_SGL_RCV(\ 573 (sdesc->data[0])); 574 sgc.rcv.chksum_status = 575 Q8_STAT_DESC_STATUS((sdesc->data[1])); 576 577 sgc.rcv.rss_hash = 578 Q8_STAT_DESC_RSS_HASH((sdesc->data[0])); 579 580 if (Q8_STAT_DESC_VLAN((sdesc->data[1]))) { 581 sgc.rcv.vlan_tag = 582 Q8_STAT_DESC_VLAN_ID((sdesc->data[1])); 583 } 584 585 QL_ASSERT(ha, (desc_count <= 2) ,\ 586 ("%s: [sds_idx, data0, data1]="\ 587 "%d, %p, %p]\n", __func__, sds_idx,\ 588 (void *)sdesc->data[0],\ 589 (void *)sdesc->data[1])); 590 591 sgc.rcv.num_handles = 1; 592 sgc.rcv.handle[0] = 593 Q8_STAT_DESC_HANDLE((sdesc->data[0])); 594 595 if (qla_rcv_cont_sds(ha, sds_idx, comp_idx, desc_count, 596 &sgc.rcv.handle[1], &nhandles)) { 597 device_printf(dev, 598 "%s: [sds_idx, dcount, data0, data1]=" 599 "[%d, %d, 0x%llx, 0x%llx]\n", 600 __func__, sds_idx, desc_count, 601 (long long unsigned int)sdesc->data[0], 602 (long long unsigned int)sdesc->data[1]); 603 desc_count = 0; 604 break; 605 } 606 607 sgc.rcv.num_handles += nhandles; 608 609 qla_rx_intr(ha, &sgc.rcv, sds_idx); 610 611 break; 612 613 case Q8_STAT_DESC_OPCODE_SGL_LRO: 614 615 desc_count = 616 Q8_STAT_DESC_COUNT_SGL_LRO((sdesc->data[1])); 617 618 if (desc_count > 1) { 619 c_idx = (comp_idx + desc_count -1) & 620 (NUM_STATUS_DESCRIPTORS-1); 621 sdesc0 = (q80_stat_desc_t *) 622 &hw->sds[sds_idx].sds_ring_base[c_idx]; 623 624 if ((Q8_STAT_DESC_OPCODE((sdesc0->data[1])) != 625 Q8_STAT_DESC_OPCODE_CONT) || 626 QL_ERR_INJECT(ha, INJCT_SGL_LRO_INV_DESC_COUNT)) { 627 desc_count = 0; 628 break; 629 } 630 } 631 bzero(&sgc, sizeof(qla_sgl_comp_t)); 632 633 sgc.lro.payload_length = 634 Q8_STAT_DESC_TOTAL_LENGTH_SGL_RCV((sdesc->data[0])); 635 636 sgc.lro.rss_hash = 637 Q8_STAT_DESC_RSS_HASH((sdesc->data[0])); 638 639 sgc.lro.num_handles = 1; 640 sgc.lro.handle[0] = 641 Q8_STAT_DESC_HANDLE((sdesc->data[0])); 642 643 if (Q8_SGL_LRO_STAT_TS((sdesc->data[1]))) 644 sgc.lro.flags |= Q8_LRO_COMP_TS; 645 646 if (Q8_SGL_LRO_STAT_PUSH_BIT((sdesc->data[1]))) 647 sgc.lro.flags |= Q8_LRO_COMP_PUSH_BIT; 648 649 sgc.lro.l2_offset = 650 Q8_SGL_LRO_STAT_L2_OFFSET((sdesc->data[1])); 651 sgc.lro.l4_offset = 652 Q8_SGL_LRO_STAT_L4_OFFSET((sdesc->data[1])); 653 654 if (Q8_STAT_DESC_VLAN((sdesc->data[1]))) { 655 sgc.lro.vlan_tag = 656 Q8_STAT_DESC_VLAN_ID((sdesc->data[1])); 657 } 658 659 QL_ASSERT(ha, (desc_count <= 7) ,\ 660 ("%s: [sds_idx, data0, data1]="\ 661 "[%d, 0x%llx, 0x%llx]\n",\ 662 __func__, sds_idx,\ 663 (long long unsigned int)sdesc->data[0],\ 664 (long long unsigned int)sdesc->data[1])); 665 666 if (qla_rcv_cont_sds(ha, sds_idx, comp_idx, 667 desc_count, &sgc.lro.handle[1], &nhandles)) { 668 device_printf(dev, 669 "%s: [sds_idx, data0, data1]="\ 670 "[%d, 0x%llx, 0x%llx]\n",\ 671 __func__, sds_idx,\ 672 (long long unsigned int)sdesc->data[0],\ 673 (long long unsigned int)sdesc->data[1]); 674 675 desc_count = 0; 676 break; 677 } 678 679 sgc.lro.num_handles += nhandles; 680 681 if (qla_lro_intr(ha, &sgc.lro, sds_idx)) { 682 device_printf(dev, 683 "%s: [sds_idx, data0, data1]="\ 684 "[%d, 0x%llx, 0x%llx]\n",\ 685 __func__, sds_idx,\ 686 (long long unsigned int)sdesc->data[0],\ 687 (long long unsigned int)sdesc->data[1]); 688 device_printf(dev, 689 "%s: [comp_idx, c_idx, dcount, nhndls]="\ 690 "[%d, %d, %d, %d]\n",\ 691 __func__, comp_idx, c_idx, desc_count, 692 sgc.lro.num_handles); 693 if (desc_count > 1) { 694 device_printf(dev, 695 "%s: [sds_idx, data0, data1]="\ 696 "[%d, 0x%llx, 0x%llx]\n",\ 697 __func__, sds_idx,\ 698 (long long unsigned int)sdesc0->data[0],\ 699 (long long unsigned int)sdesc0->data[1]); 700 } 701 } 702 703 break; 704 705 default: 706 desc_count = 0; 707 device_printf(dev, "%s: default 0x%llx!\n", __func__, 708 (long long unsigned int)sdesc->data[0]); 709 break; 710 } 711 712 if (desc_count == 0) 713 break; 714 715 sds_replenish_threshold += desc_count; 716 717 718 while (desc_count--) { 719 sdesc->data[0] = 0ULL; 720 sdesc->data[1] = 0ULL; 721 comp_idx = (comp_idx + 1) & (NUM_STATUS_DESCRIPTORS-1); 722 sdesc = (q80_stat_desc_t *) 723 &hw->sds[sds_idx].sds_ring_base[comp_idx]; 724 } 725 726 if (sds_replenish_threshold > ha->hw.sds_cidx_thres) { 727 sds_replenish_threshold = 0; 728 if (hw->sds[sds_idx].sdsr_next != comp_idx) { 729 QL_UPDATE_SDS_CONSUMER_INDEX(ha, sds_idx,\ 730 comp_idx); 731 } 732 hw->sds[sds_idx].sdsr_next = comp_idx; 733 } 734 } 735 736 if (ha->hw.enable_soft_lro) { 737 struct lro_ctrl *lro; 738 739 lro = &ha->hw.sds[sds_idx].lro; 740 741 #if (__FreeBSD_version >= 1100101) 742 743 tcp_lro_flush_all(lro); 744 745 #else 746 struct lro_entry *queued; 747 748 while ((!SLIST_EMPTY(&lro->lro_active))) { 749 queued = SLIST_FIRST(&lro->lro_active); 750 SLIST_REMOVE_HEAD(&lro->lro_active, next); 751 tcp_lro_flush(lro, queued); 752 } 753 754 #endif /* #if (__FreeBSD_version >= 1100101) */ 755 756 } 757 758 if (ha->stop_rcv) 759 goto ql_rcv_isr_exit; 760 761 if (hw->sds[sds_idx].sdsr_next != comp_idx) { 762 QL_UPDATE_SDS_CONSUMER_INDEX(ha, sds_idx, comp_idx); 763 hw->sds[sds_idx].sdsr_next = comp_idx; 764 } else { 765 if (ha->hw.num_rds_rings > 1) 766 r_idx = sds_idx; 767 768 sdsp = &ha->hw.sds[sds_idx]; 769 770 if (sdsp->rx_free > ha->std_replenish) 771 qla_replenish_normal_rx(ha, sdsp, r_idx); 772 } 773 774 sdesc = (q80_stat_desc_t *)&hw->sds[sds_idx].sds_ring_base[comp_idx]; 775 opcode = Q8_STAT_DESC_OPCODE((sdesc->data[1])); 776 777 if (opcode) 778 ret = -1; 779 780 ql_rcv_isr_exit: 781 hw->sds[sds_idx].rcv_active = 0; 782 783 return (ret); 784 } 785 786 void 787 ql_mbx_isr(void *arg) 788 { 789 qla_host_t *ha; 790 uint32_t data; 791 uint32_t prev_link_state; 792 793 ha = arg; 794 795 if (ha == NULL) { 796 printf("%s: arg == NULL\n", __func__); 797 return; 798 } 799 800 data = READ_REG32(ha, Q8_FW_MBOX_CNTRL); 801 if ((data & 0x3) != 0x1) { 802 WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0); 803 return; 804 } 805 806 data = READ_REG32(ha, Q8_FW_MBOX0); 807 808 if ((data & 0xF000) != 0x8000) 809 return; 810 811 data = data & 0xFFFF; 812 813 switch (data) { 814 815 case 0x8001: /* It's an AEN */ 816 817 ha->hw.cable_oui = READ_REG32(ha, (Q8_FW_MBOX0 + 4)); 818 819 data = READ_REG32(ha, (Q8_FW_MBOX0 + 8)); 820 ha->hw.cable_length = data & 0xFFFF; 821 822 data = data >> 16; 823 ha->hw.link_speed = data & 0xFFF; 824 825 data = READ_REG32(ha, (Q8_FW_MBOX0 + 12)); 826 827 prev_link_state = ha->hw.link_up; 828 829 data = (((data & 0xFF) == 0) ? 0 : 1); 830 atomic_store_rel_8(&ha->hw.link_up, (uint8_t)data); 831 832 device_printf(ha->pci_dev, 833 "%s: AEN[0x8001] data = 0x%08x, prev_link_state = 0x%08x\n", 834 __func__, data, prev_link_state); 835 836 if (prev_link_state != ha->hw.link_up) { 837 if (ha->hw.link_up) 838 if_link_state_change(ha->ifp, LINK_STATE_UP); 839 else 840 if_link_state_change(ha->ifp, LINK_STATE_DOWN); 841 } 842 843 844 ha->hw.module_type = ((data >> 8) & 0xFF); 845 ha->hw.fduplex = (((data & 0xFF0000) == 0) ? 0 : 1); 846 ha->hw.autoneg = (((data & 0xFF000000) == 0) ? 0 : 1); 847 848 data = READ_REG32(ha, (Q8_FW_MBOX0 + 16)); 849 ha->hw.loopback_mode = data & 0x03; 850 851 ha->hw.link_faults = (data >> 3) & 0xFF; 852 853 break; 854 855 case 0x8100: 856 device_printf(ha->pci_dev, "%s: AEN[0x%08x]\n", __func__, data); 857 ha->hw.imd_compl=1; 858 break; 859 860 case 0x8101: 861 ha->async_event = 1; 862 ha->hw.aen_mb0 = 0x8101; 863 ha->hw.aen_mb1 = READ_REG32(ha, (Q8_FW_MBOX0 + 4)); 864 ha->hw.aen_mb2 = READ_REG32(ha, (Q8_FW_MBOX0 + 8)); 865 ha->hw.aen_mb3 = READ_REG32(ha, (Q8_FW_MBOX0 + 12)); 866 ha->hw.aen_mb4 = READ_REG32(ha, (Q8_FW_MBOX0 + 16)); 867 device_printf(ha->pci_dev, "%s: AEN[0x%08x 0x%08x 0x%08x 0%08x 0x%08x]\n", 868 __func__, data, ha->hw.aen_mb1, ha->hw.aen_mb2, 869 ha->hw.aen_mb3, ha->hw.aen_mb4); 870 break; 871 872 case 0x8110: 873 /* for now just dump the registers */ 874 { 875 uint32_t ombx[5]; 876 877 ombx[0] = READ_REG32(ha, (Q8_FW_MBOX0 + 4)); 878 ombx[1] = READ_REG32(ha, (Q8_FW_MBOX0 + 8)); 879 ombx[2] = READ_REG32(ha, (Q8_FW_MBOX0 + 12)); 880 ombx[3] = READ_REG32(ha, (Q8_FW_MBOX0 + 16)); 881 ombx[4] = READ_REG32(ha, (Q8_FW_MBOX0 + 20)); 882 883 device_printf(ha->pci_dev, "%s: " 884 "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 885 __func__, data, ombx[0], ombx[1], ombx[2], 886 ombx[3], ombx[4]); 887 } 888 889 break; 890 891 case 0x8130: 892 /* sfp insertion aen */ 893 device_printf(ha->pci_dev, "%s: sfp inserted [0x%08x]\n", 894 __func__, READ_REG32(ha, (Q8_FW_MBOX0 + 4))); 895 break; 896 897 case 0x8131: 898 /* sfp removal aen */ 899 device_printf(ha->pci_dev, "%s: sfp removed]\n", __func__); 900 break; 901 902 case 0x8140: 903 { 904 uint32_t ombx[3]; 905 906 ombx[0] = READ_REG32(ha, (Q8_FW_MBOX0 + 4)); 907 ombx[1] = READ_REG32(ha, (Q8_FW_MBOX0 + 8)); 908 ombx[2] = READ_REG32(ha, (Q8_FW_MBOX0 + 12)); 909 910 device_printf(ha->pci_dev, "%s: " 911 "0x%08x 0x%08x 0x%08x 0x%08x \n", 912 __func__, data, ombx[0], ombx[1], ombx[2]); 913 } 914 break; 915 916 default: 917 device_printf(ha->pci_dev, "%s: AEN[0x%08x]\n", __func__, data); 918 break; 919 } 920 WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0); 921 WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0); 922 return; 923 } 924 925 926 static void 927 qla_replenish_normal_rx(qla_host_t *ha, qla_sds_t *sdsp, uint32_t r_idx) 928 { 929 qla_rx_buf_t *rxb; 930 int count = sdsp->rx_free; 931 uint32_t rx_next; 932 qla_rdesc_t *rdesc; 933 934 /* we can play with this value via a sysctl */ 935 uint32_t replenish_thresh = ha->hw.rds_pidx_thres; 936 937 rdesc = &ha->hw.rds[r_idx]; 938 939 rx_next = rdesc->rx_next; 940 941 while (count--) { 942 rxb = sdsp->rxb_free; 943 944 if (rxb == NULL) 945 break; 946 947 sdsp->rxb_free = rxb->next; 948 sdsp->rx_free--; 949 950 if (ql_get_mbuf(ha, rxb, NULL) == 0) { 951 qla_set_hw_rcv_desc(ha, r_idx, rdesc->rx_in, 952 rxb->handle, 953 rxb->paddr, (rxb->m_head)->m_pkthdr.len); 954 rdesc->rx_in++; 955 if (rdesc->rx_in == NUM_RX_DESCRIPTORS) 956 rdesc->rx_in = 0; 957 rdesc->rx_next++; 958 if (rdesc->rx_next == NUM_RX_DESCRIPTORS) 959 rdesc->rx_next = 0; 960 } else { 961 device_printf(ha->pci_dev, 962 "%s: qla_get_mbuf [(%d),(%d),(%d)] failed\n", 963 __func__, r_idx, rdesc->rx_in, rxb->handle); 964 965 rxb->m_head = NULL; 966 rxb->next = sdsp->rxb_free; 967 sdsp->rxb_free = rxb; 968 sdsp->rx_free++; 969 970 break; 971 } 972 if (replenish_thresh-- == 0) { 973 QL_UPDATE_RDS_PRODUCER_INDEX(ha, rdesc->prod_std, 974 rdesc->rx_next); 975 rx_next = rdesc->rx_next; 976 replenish_thresh = ha->hw.rds_pidx_thres; 977 } 978 } 979 980 if (rx_next != rdesc->rx_next) { 981 QL_UPDATE_RDS_PRODUCER_INDEX(ha, rdesc->prod_std, 982 rdesc->rx_next); 983 } 984 } 985 986 void 987 ql_isr(void *arg) 988 { 989 qla_ivec_t *ivec = arg; 990 qla_host_t *ha ; 991 int idx; 992 qla_hw_t *hw; 993 struct ifnet *ifp; 994 qla_tx_fp_t *fp; 995 996 ha = ivec->ha; 997 hw = &ha->hw; 998 ifp = ha->ifp; 999 1000 if ((idx = ivec->sds_idx) >= ha->hw.num_sds_rings) 1001 return; 1002 1003 fp = &ha->tx_fp[idx]; 1004 hw->sds[idx].intr_count++; 1005 1006 if ((fp->fp_taskqueue != NULL) && 1007 (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1008 taskqueue_enqueue(fp->fp_taskqueue, &fp->fp_task); 1009 1010 return; 1011 } 1012 1013