1 /* 2 * Copyright (c) 2013-2014 Qlogic Corporation 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 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * File: qls_hw.c 30 * Author : David C Somayajulu, Qlogic Corporation, Aliso Viejo, CA 92656. 31 * Content: Contains Hardware dependant functions 32 */ 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 37 38 #include "qls_os.h" 39 #include "qls_hw.h" 40 #include "qls_def.h" 41 #include "qls_inline.h" 42 #include "qls_ver.h" 43 #include "qls_glbl.h" 44 #include "qls_dbg.h" 45 46 /* 47 * Static Functions 48 */ 49 static int qls_wait_for_mac_proto_idx_ready(qla_host_t *ha, uint32_t op); 50 static int qls_config_unicast_mac_addr(qla_host_t *ha, uint32_t add_mac); 51 static int qls_config_mcast_mac_addr(qla_host_t *ha, uint8_t *mac_addr, 52 uint32_t add_mac, uint32_t index); 53 54 static int qls_init_rss(qla_host_t *ha); 55 static int qls_init_comp_queue(qla_host_t *ha, int cid); 56 static int qls_init_work_queue(qla_host_t *ha, int wid); 57 static int qls_init_fw_routing_table(qla_host_t *ha); 58 static int qls_hw_add_all_mcast(qla_host_t *ha); 59 static int qls_hw_add_mcast(qla_host_t *ha, uint8_t *mta); 60 static int qls_hw_del_mcast(qla_host_t *ha, uint8_t *mta); 61 static int qls_wait_for_flash_ready(qla_host_t *ha); 62 63 static int qls_sem_lock(qla_host_t *ha, uint32_t mask, uint32_t value); 64 static void qls_sem_unlock(qla_host_t *ha, uint32_t mask); 65 66 static void qls_free_tx_dma(qla_host_t *ha); 67 static int qls_alloc_tx_dma(qla_host_t *ha); 68 static void qls_free_rx_dma(qla_host_t *ha); 69 static int qls_alloc_rx_dma(qla_host_t *ha); 70 static void qls_free_mpi_dma(qla_host_t *ha); 71 static int qls_alloc_mpi_dma(qla_host_t *ha); 72 static void qls_free_rss_dma(qla_host_t *ha); 73 static int qls_alloc_rss_dma(qla_host_t *ha); 74 75 static int qls_flash_validate(qla_host_t *ha, const char *signature); 76 77 78 static int qls_wait_for_proc_addr_ready(qla_host_t *ha); 79 static int qls_proc_addr_rd_reg(qla_host_t *ha, uint32_t addr_module, 80 uint32_t reg, uint32_t *data); 81 static int qls_proc_addr_wr_reg(qla_host_t *ha, uint32_t addr_module, 82 uint32_t reg, uint32_t data); 83 84 static int qls_hw_reset(qla_host_t *ha); 85 86 /* 87 * MPI Related Functions 88 */ 89 static int qls_mbx_cmd(qla_host_t *ha, uint32_t *in_mbx, uint32_t i_count, 90 uint32_t *out_mbx, uint32_t o_count); 91 static int qls_mbx_set_mgmt_ctrl(qla_host_t *ha, uint32_t t_ctrl); 92 static int qls_mbx_get_mgmt_ctrl(qla_host_t *ha, uint32_t *t_status); 93 static void qls_mbx_get_link_status(qla_host_t *ha); 94 static void qls_mbx_about_fw(qla_host_t *ha); 95 96 int 97 qls_get_msix_count(qla_host_t *ha) 98 { 99 return (ha->num_rx_rings); 100 } 101 102 static int 103 qls_syctl_mpi_dump(SYSCTL_HANDLER_ARGS) 104 { 105 int err = 0, ret; 106 qla_host_t *ha; 107 108 err = sysctl_handle_int(oidp, &ret, 0, req); 109 110 if (err || !req->newptr) 111 return (err); 112 113 114 if (ret == 1) { 115 ha = (qla_host_t *)arg1; 116 qls_mpi_core_dump(ha); 117 } 118 return (err); 119 } 120 121 static int 122 qls_syctl_link_status(SYSCTL_HANDLER_ARGS) 123 { 124 int err = 0, ret; 125 qla_host_t *ha; 126 127 err = sysctl_handle_int(oidp, &ret, 0, req); 128 129 if (err || !req->newptr) 130 return (err); 131 132 133 if (ret == 1) { 134 ha = (qla_host_t *)arg1; 135 qls_mbx_get_link_status(ha); 136 qls_mbx_about_fw(ha); 137 } 138 return (err); 139 } 140 141 void 142 qls_hw_add_sysctls(qla_host_t *ha) 143 { 144 device_t dev; 145 146 dev = ha->pci_dev; 147 148 ha->num_rx_rings = MAX_RX_RINGS; ha->num_tx_rings = MAX_TX_RINGS; 149 150 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 151 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 152 OID_AUTO, "num_rx_rings", CTLFLAG_RD, &ha->num_rx_rings, 153 ha->num_rx_rings, "Number of Completion Queues"); 154 155 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), 156 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 157 OID_AUTO, "num_tx_rings", CTLFLAG_RD, &ha->num_tx_rings, 158 ha->num_tx_rings, "Number of Transmit Rings"); 159 160 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 161 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 162 OID_AUTO, "mpi_dump", CTLTYPE_INT | CTLFLAG_RW, 163 (void *)ha, 0, 164 qls_syctl_mpi_dump, "I", "MPI Dump"); 165 166 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 167 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 168 OID_AUTO, "link_status", CTLTYPE_INT | CTLFLAG_RW, 169 (void *)ha, 0, 170 qls_syctl_link_status, "I", "Link Status"); 171 } 172 173 /* 174 * Name: qls_free_dma 175 * Function: Frees the DMA'able memory allocated in qls_alloc_dma() 176 */ 177 void 178 qls_free_dma(qla_host_t *ha) 179 { 180 qls_free_rss_dma(ha); 181 qls_free_mpi_dma(ha); 182 qls_free_tx_dma(ha); 183 qls_free_rx_dma(ha); 184 return; 185 } 186 187 /* 188 * Name: qls_alloc_dma 189 * Function: Allocates DMA'able memory for Tx/Rx Rings, Tx/Rx Contexts. 190 */ 191 int 192 qls_alloc_dma(qla_host_t *ha) 193 { 194 if (qls_alloc_rx_dma(ha)) 195 return (-1); 196 197 if (qls_alloc_tx_dma(ha)) { 198 qls_free_rx_dma(ha); 199 return (-1); 200 } 201 202 if (qls_alloc_mpi_dma(ha)) { 203 qls_free_tx_dma(ha); 204 qls_free_rx_dma(ha); 205 return (-1); 206 } 207 208 if (qls_alloc_rss_dma(ha)) { 209 qls_free_mpi_dma(ha); 210 qls_free_tx_dma(ha); 211 qls_free_rx_dma(ha); 212 return (-1); 213 } 214 215 return (0); 216 } 217 218 219 static int 220 qls_wait_for_mac_proto_idx_ready(qla_host_t *ha, uint32_t op) 221 { 222 uint32_t data32; 223 uint32_t count = 3; 224 225 while (count--) { 226 data32 = READ_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX); 227 228 if (data32 & op) 229 return (0); 230 231 QLA_USEC_DELAY(100); 232 } 233 ha->qla_initiate_recovery = 1; 234 return (-1); 235 } 236 237 /* 238 * Name: qls_config_unicast_mac_addr 239 * Function: binds/unbinds a unicast MAC address to the interface. 240 */ 241 static int 242 qls_config_unicast_mac_addr(qla_host_t *ha, uint32_t add_mac) 243 { 244 int ret = 0; 245 uint32_t mac_upper = 0; 246 uint32_t mac_lower = 0; 247 uint32_t value = 0, index; 248 249 if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_MAC_SERDES, 250 Q81_CTL_SEM_SET_MAC_SERDES)) { 251 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 252 return(-1); 253 } 254 255 if (add_mac) { 256 mac_upper = (ha->mac_addr[0] << 8) | ha->mac_addr[1]; 257 mac_lower = (ha->mac_addr[2] << 24) | (ha->mac_addr[3] << 16) | 258 (ha->mac_addr[4] << 8) | ha->mac_addr[5]; 259 } 260 ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW); 261 if (ret) 262 goto qls_config_unicast_mac_addr_exit; 263 264 index = 128 * (ha->pci_func & 0x1); /* index */ 265 266 value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) | 267 Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC; 268 269 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value); 270 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_lower); 271 272 ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW); 273 if (ret) 274 goto qls_config_unicast_mac_addr_exit; 275 276 value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) | 277 Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC | 0x1; 278 279 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value); 280 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_upper); 281 282 ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW); 283 if (ret) 284 goto qls_config_unicast_mac_addr_exit; 285 286 value = (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) | 287 Q81_CTL_MAC_PROTO_AI_TYPE_CAM_MAC | 0x2; 288 289 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value); 290 291 value = Q81_CAM_MAC_OFF2_ROUTE_NIC | 292 ((ha->pci_func & 0x1) << Q81_CAM_MAC_OFF2_FUNC_SHIFT) | 293 (0 << Q81_CAM_MAC_OFF2_CQID_SHIFT); 294 295 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, value); 296 297 qls_config_unicast_mac_addr_exit: 298 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_MAC_SERDES); 299 return (ret); 300 } 301 302 /* 303 * Name: qls_config_mcast_mac_addr 304 * Function: binds/unbinds a multicast MAC address to the interface. 305 */ 306 static int 307 qls_config_mcast_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac, 308 uint32_t index) 309 { 310 int ret = 0; 311 uint32_t mac_upper = 0; 312 uint32_t mac_lower = 0; 313 uint32_t value = 0; 314 315 if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_MAC_SERDES, 316 Q81_CTL_SEM_SET_MAC_SERDES)) { 317 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 318 return(-1); 319 } 320 321 if (add_mac) { 322 mac_upper = (mac_addr[0] << 8) | mac_addr[1]; 323 mac_lower = (mac_addr[2] << 24) | (mac_addr[3] << 16) | 324 (mac_addr[4] << 8) | mac_addr[5]; 325 } 326 ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW); 327 if (ret) 328 goto qls_config_mcast_mac_addr_exit; 329 330 value = Q81_CTL_MAC_PROTO_AI_E | 331 (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) | 332 Q81_CTL_MAC_PROTO_AI_TYPE_MCAST ; 333 334 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value); 335 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_lower); 336 337 ret = qls_wait_for_mac_proto_idx_ready(ha, Q81_CTL_MAC_PROTO_AI_MW); 338 if (ret) 339 goto qls_config_mcast_mac_addr_exit; 340 341 value = Q81_CTL_MAC_PROTO_AI_E | 342 (index << Q81_CTL_MAC_PROTO_AI_IDX_SHIFT) | 343 Q81_CTL_MAC_PROTO_AI_TYPE_MCAST | 0x1; 344 345 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX, value); 346 WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_DATA, mac_upper); 347 348 qls_config_mcast_mac_addr_exit: 349 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_MAC_SERDES); 350 351 return (ret); 352 } 353 354 /* 355 * Name: qls_set_mac_rcv_mode 356 * Function: Enable/Disable AllMulticast and Promiscous Modes. 357 */ 358 static int 359 qls_wait_for_route_idx_ready(qla_host_t *ha, uint32_t op) 360 { 361 uint32_t data32; 362 uint32_t count = 3; 363 364 while (count--) { 365 data32 = READ_REG32(ha, Q81_CTL_ROUTING_INDEX); 366 367 if (data32 & op) 368 return (0); 369 370 QLA_USEC_DELAY(100); 371 } 372 ha->qla_initiate_recovery = 1; 373 return (-1); 374 } 375 376 static int 377 qls_load_route_idx_reg(qla_host_t *ha, uint32_t index, uint32_t data) 378 { 379 int ret = 0; 380 381 ret = qls_wait_for_route_idx_ready(ha, Q81_CTL_RI_MW); 382 383 if (ret) { 384 device_printf(ha->pci_dev, "%s: [0x%08x, 0x%08x] failed\n", 385 __func__, index, data); 386 goto qls_load_route_idx_reg_exit; 387 } 388 389 390 WRITE_REG32(ha, Q81_CTL_ROUTING_INDEX, index); 391 WRITE_REG32(ha, Q81_CTL_ROUTING_DATA, data); 392 393 qls_load_route_idx_reg_exit: 394 return (ret); 395 } 396 397 static int 398 qls_load_route_idx_reg_locked(qla_host_t *ha, uint32_t index, uint32_t data) 399 { 400 int ret = 0; 401 402 if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG, 403 Q81_CTL_SEM_SET_RIDX_DATAREG)) { 404 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 405 return(-1); 406 } 407 408 ret = qls_load_route_idx_reg(ha, index, data); 409 410 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG); 411 412 return (ret); 413 } 414 415 static int 416 qls_clear_routing_table(qla_host_t *ha) 417 { 418 int i, ret = 0; 419 420 if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG, 421 Q81_CTL_SEM_SET_RIDX_DATAREG)) { 422 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 423 return(-1); 424 } 425 426 for (i = 0; i < 16; i++) { 427 ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_TYPE_NICQMASK| 428 (i << 8) | Q81_CTL_RI_DST_DFLTQ), 0); 429 if (ret) 430 break; 431 } 432 433 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG); 434 435 return (ret); 436 } 437 438 int 439 qls_set_promisc(qla_host_t *ha) 440 { 441 int ret; 442 443 ret = qls_load_route_idx_reg_locked(ha, 444 (Q81_CTL_RI_E | Q81_CTL_RI_TYPE_NICQMASK | 445 Q81_CTL_RI_IDX_PROMISCUOUS | Q81_CTL_RI_DST_DFLTQ), 446 Q81_CTL_RD_VALID_PKT); 447 return (ret); 448 } 449 450 void 451 qls_reset_promisc(qla_host_t *ha) 452 { 453 int ret; 454 455 ret = qls_load_route_idx_reg_locked(ha, (Q81_CTL_RI_TYPE_NICQMASK | 456 Q81_CTL_RI_IDX_PROMISCUOUS | Q81_CTL_RI_DST_DFLTQ), 0); 457 return; 458 } 459 460 int 461 qls_set_allmulti(qla_host_t *ha) 462 { 463 int ret; 464 465 ret = qls_load_route_idx_reg_locked(ha, 466 (Q81_CTL_RI_E | Q81_CTL_RI_TYPE_NICQMASK | 467 Q81_CTL_RI_IDX_ALLMULTI | Q81_CTL_RI_DST_DFLTQ), 468 Q81_CTL_RD_MCAST); 469 return (ret); 470 } 471 472 void 473 qls_reset_allmulti(qla_host_t *ha) 474 { 475 int ret; 476 477 ret = qls_load_route_idx_reg_locked(ha, (Q81_CTL_RI_TYPE_NICQMASK | 478 Q81_CTL_RI_IDX_ALLMULTI | Q81_CTL_RI_DST_DFLTQ), 0); 479 return; 480 } 481 482 483 static int 484 qls_init_fw_routing_table(qla_host_t *ha) 485 { 486 int ret = 0; 487 488 ret = qls_clear_routing_table(ha); 489 if (ret) 490 return (-1); 491 492 if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG, 493 Q81_CTL_SEM_SET_RIDX_DATAREG)) { 494 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 495 return(-1); 496 } 497 498 ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DROP | 499 Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_ALL_ERROR), 500 Q81_CTL_RD_ERROR_PKT); 501 if (ret) 502 goto qls_init_fw_routing_table_exit; 503 504 ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ | 505 Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_BCAST), 506 Q81_CTL_RD_BCAST); 507 if (ret) 508 goto qls_init_fw_routing_table_exit; 509 510 if (ha->num_rx_rings > 1 ) { 511 ret = qls_load_route_idx_reg(ha, 512 (Q81_CTL_RI_E | Q81_CTL_RI_DST_RSS | 513 Q81_CTL_RI_TYPE_NICQMASK | 514 Q81_CTL_RI_IDX_RSS_MATCH), 515 Q81_CTL_RD_RSS_MATCH); 516 if (ret) 517 goto qls_init_fw_routing_table_exit; 518 } 519 520 ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ | 521 Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_MCAST_MATCH), 522 Q81_CTL_RD_MCAST_REG_MATCH); 523 if (ret) 524 goto qls_init_fw_routing_table_exit; 525 526 ret = qls_load_route_idx_reg(ha, (Q81_CTL_RI_E | Q81_CTL_RI_DST_DFLTQ | 527 Q81_CTL_RI_TYPE_NICQMASK | Q81_CTL_RI_IDX_CAM_HIT), 528 Q81_CTL_RD_CAM_HIT); 529 if (ret) 530 goto qls_init_fw_routing_table_exit; 531 532 qls_init_fw_routing_table_exit: 533 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_RIDX_DATAREG); 534 return (ret); 535 } 536 537 static int 538 qls_tx_tso_chksum(qla_host_t *ha, struct mbuf *mp, q81_tx_tso_t *tx_mac) 539 { 540 struct ether_vlan_header *eh; 541 struct ip *ip; 542 struct ip6_hdr *ip6; 543 struct tcphdr *th; 544 uint32_t ehdrlen, ip_hlen; 545 int ret = 0; 546 uint16_t etype; 547 device_t dev; 548 uint8_t buf[sizeof(struct ip6_hdr)]; 549 550 dev = ha->pci_dev; 551 552 eh = mtod(mp, struct ether_vlan_header *); 553 554 if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 555 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 556 etype = ntohs(eh->evl_proto); 557 } else { 558 ehdrlen = ETHER_HDR_LEN; 559 etype = ntohs(eh->evl_encap_proto); 560 } 561 562 switch (etype) { 563 case ETHERTYPE_IP: 564 ip = (struct ip *)(mp->m_data + ehdrlen); 565 566 ip_hlen = sizeof (struct ip); 567 568 if (mp->m_len < (ehdrlen + ip_hlen)) { 569 m_copydata(mp, ehdrlen, sizeof(struct ip), buf); 570 ip = (struct ip *)buf; 571 } 572 tx_mac->opcode = Q81_IOCB_TX_TSO; 573 tx_mac->flags |= Q81_TX_TSO_FLAGS_IPV4 ; 574 575 tx_mac->phdr_offsets = ehdrlen; 576 577 tx_mac->phdr_offsets |= ((ehdrlen + ip_hlen) << 578 Q81_TX_TSO_PHDR_SHIFT); 579 580 ip->ip_sum = 0; 581 582 if (mp->m_pkthdr.csum_flags & CSUM_TSO) { 583 tx_mac->flags |= Q81_TX_TSO_FLAGS_LSO; 584 585 th = (struct tcphdr *)(ip + 1); 586 587 th->th_sum = in_pseudo(ip->ip_src.s_addr, 588 ip->ip_dst.s_addr, 589 htons(IPPROTO_TCP)); 590 tx_mac->mss = mp->m_pkthdr.tso_segsz; 591 tx_mac->phdr_length = ip_hlen + ehdrlen + 592 (th->th_off << 2); 593 break; 594 } 595 tx_mac->vlan_off |= Q81_TX_TSO_VLAN_OFF_IC ; 596 597 598 if (ip->ip_p == IPPROTO_TCP) { 599 tx_mac->flags |= Q81_TX_TSO_FLAGS_TC; 600 } else if (ip->ip_p == IPPROTO_UDP) { 601 tx_mac->flags |= Q81_TX_TSO_FLAGS_UC; 602 } 603 break; 604 605 case ETHERTYPE_IPV6: 606 ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); 607 608 ip_hlen = sizeof(struct ip6_hdr); 609 610 if (mp->m_len < (ehdrlen + ip_hlen)) { 611 m_copydata(mp, ehdrlen, sizeof (struct ip6_hdr), 612 buf); 613 ip6 = (struct ip6_hdr *)buf; 614 } 615 616 tx_mac->opcode = Q81_IOCB_TX_TSO; 617 tx_mac->flags |= Q81_TX_TSO_FLAGS_IPV6 ; 618 tx_mac->vlan_off |= Q81_TX_TSO_VLAN_OFF_IC ; 619 620 tx_mac->phdr_offsets = ehdrlen; 621 tx_mac->phdr_offsets |= ((ehdrlen + ip_hlen) << 622 Q81_TX_TSO_PHDR_SHIFT); 623 624 if (ip6->ip6_nxt == IPPROTO_TCP) { 625 tx_mac->flags |= Q81_TX_TSO_FLAGS_TC; 626 } else if (ip6->ip6_nxt == IPPROTO_UDP) { 627 tx_mac->flags |= Q81_TX_TSO_FLAGS_UC; 628 } 629 break; 630 631 default: 632 ret = -1; 633 break; 634 } 635 636 return (ret); 637 } 638 639 #define QLA_TX_MIN_FREE 2 640 int 641 qls_hw_tx_done(qla_host_t *ha, uint32_t txr_idx) 642 { 643 uint32_t txr_done, txr_next; 644 645 txr_done = ha->tx_ring[txr_idx].txr_done; 646 txr_next = ha->tx_ring[txr_idx].txr_next; 647 648 if (txr_done == txr_next) { 649 ha->tx_ring[txr_idx].txr_free = NUM_TX_DESCRIPTORS; 650 } else if (txr_done > txr_next) { 651 ha->tx_ring[txr_idx].txr_free = txr_done - txr_next; 652 } else { 653 ha->tx_ring[txr_idx].txr_free = NUM_TX_DESCRIPTORS + 654 txr_done - txr_next; 655 } 656 657 if (ha->tx_ring[txr_idx].txr_free <= QLA_TX_MIN_FREE) 658 return (-1); 659 660 return (0); 661 } 662 663 /* 664 * Name: qls_hw_send 665 * Function: Transmits a packet. It first checks if the packet is a 666 * candidate for Large TCP Segment Offload and then for UDP/TCP checksum 667 * offload. If either of these creteria are not met, it is transmitted 668 * as a regular ethernet frame. 669 */ 670 int 671 qls_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs, 672 uint32_t txr_next, struct mbuf *mp, uint32_t txr_idx) 673 { 674 q81_tx_mac_t *tx_mac; 675 q81_txb_desc_t *tx_desc; 676 uint32_t total_length = 0; 677 uint32_t i; 678 device_t dev; 679 int ret = 0; 680 681 dev = ha->pci_dev; 682 683 total_length = mp->m_pkthdr.len; 684 685 if (total_length > QLA_MAX_TSO_FRAME_SIZE) { 686 device_printf(dev, "%s: total length exceeds maxlen(%d)\n", 687 __func__, total_length); 688 return (-1); 689 } 690 691 if (ha->tx_ring[txr_idx].txr_free <= (NUM_TX_DESCRIPTORS >> 2)) { 692 if (qls_hw_tx_done(ha, txr_idx)) { 693 device_printf(dev, "%s: tx_free[%d] = %d\n", 694 __func__, txr_idx, 695 ha->tx_ring[txr_idx].txr_free); 696 return (-1); 697 } 698 } 699 700 tx_mac = (q81_tx_mac_t *)&ha->tx_ring[txr_idx].wq_vaddr[txr_next]; 701 702 bzero(tx_mac, sizeof(q81_tx_mac_t)); 703 704 if ((mp->m_pkthdr.csum_flags & 705 (CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO)) != 0) { 706 707 ret = qls_tx_tso_chksum(ha, mp, (q81_tx_tso_t *)tx_mac); 708 if (ret) 709 return (EINVAL); 710 711 if (mp->m_pkthdr.csum_flags & CSUM_TSO) 712 ha->tx_ring[txr_idx].tx_tso_frames++; 713 else 714 ha->tx_ring[txr_idx].tx_frames++; 715 716 } else { 717 tx_mac->opcode = Q81_IOCB_TX_MAC; 718 } 719 720 if (mp->m_flags & M_VLANTAG) { 721 722 tx_mac->vlan_tci = mp->m_pkthdr.ether_vtag; 723 tx_mac->vlan_off |= Q81_TX_MAC_VLAN_OFF_V; 724 725 ha->tx_ring[txr_idx].tx_vlan_frames++; 726 } 727 728 tx_mac->frame_length = total_length; 729 730 tx_mac->tid_lo = txr_next; 731 732 if (nsegs <= MAX_TX_MAC_DESC) { 733 734 QL_DPRINT2((dev, "%s: 1 [%d, %d]\n", __func__, total_length, 735 tx_mac->tid_lo)); 736 737 for (i = 0; i < nsegs; i++) { 738 tx_mac->txd[i].baddr = segs->ds_addr; 739 tx_mac->txd[i].length = segs->ds_len; 740 segs++; 741 } 742 tx_mac->txd[(nsegs - 1)].flags = Q81_RXB_DESC_FLAGS_E; 743 744 } else { 745 QL_DPRINT2((dev, "%s: 2 [%d, %d]\n", __func__, total_length, 746 tx_mac->tid_lo)); 747 748 tx_mac->txd[0].baddr = 749 ha->tx_ring[txr_idx].tx_buf[txr_next].oal_paddr; 750 tx_mac->txd[0].length = 751 nsegs * (sizeof(q81_txb_desc_t)); 752 tx_mac->txd[0].flags = Q81_RXB_DESC_FLAGS_C; 753 754 tx_desc = ha->tx_ring[txr_idx].tx_buf[txr_next].oal_vaddr; 755 756 for (i = 0; i < nsegs; i++) { 757 tx_desc->baddr = segs->ds_addr; 758 tx_desc->length = segs->ds_len; 759 760 if (i == (nsegs -1)) 761 tx_desc->flags = Q81_RXB_DESC_FLAGS_E; 762 else 763 tx_desc->flags = 0; 764 765 segs++; 766 tx_desc++; 767 } 768 } 769 txr_next = (txr_next + 1) & (NUM_TX_DESCRIPTORS - 1); 770 ha->tx_ring[txr_idx].txr_next = txr_next; 771 772 ha->tx_ring[txr_idx].txr_free--; 773 774 Q81_WR_WQ_PROD_IDX(txr_idx, txr_next); 775 776 return (0); 777 } 778 779 /* 780 * Name: qls_del_hw_if 781 * Function: Destroys the hardware specific entities corresponding to an 782 * Ethernet Interface 783 */ 784 void 785 qls_del_hw_if(qla_host_t *ha) 786 { 787 uint32_t value; 788 int i; 789 //int count; 790 791 if (ha->hw_init == 0) { 792 qls_hw_reset(ha); 793 return; 794 } 795 796 for (i = 0; i < ha->num_tx_rings; i++) { 797 Q81_SET_WQ_INVALID(i); 798 } 799 for (i = 0; i < ha->num_rx_rings; i++) { 800 Q81_SET_CQ_INVALID(i); 801 } 802 803 for (i = 0; i < ha->num_rx_rings; i++) { 804 Q81_DISABLE_INTR(ha, i); /* MSI-x i */ 805 } 806 807 value = (Q81_CTL_INTRE_IHD << Q81_CTL_INTRE_MASK_SHIFT); 808 WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value); 809 810 value = (Q81_CTL_INTRE_EI << Q81_CTL_INTRE_MASK_SHIFT); 811 WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value); 812 ha->flags.intr_enable = 0; 813 814 qls_hw_reset(ha); 815 816 return; 817 } 818 819 /* 820 * Name: qls_init_hw_if 821 * Function: Creates the hardware specific entities corresponding to an 822 * Ethernet Interface - Transmit and Receive Contexts. Sets the MAC Address 823 * corresponding to the interface. Enables LRO if allowed. 824 */ 825 int 826 qls_init_hw_if(qla_host_t *ha) 827 { 828 device_t dev; 829 uint32_t value; 830 int ret = 0; 831 int i; 832 833 834 QL_DPRINT2((ha->pci_dev, "%s:enter\n", __func__)); 835 836 dev = ha->pci_dev; 837 838 ret = qls_hw_reset(ha); 839 if (ret) 840 goto qls_init_hw_if_exit; 841 842 ha->vm_pgsize = 4096; 843 844 /* Enable FAE and EFE bits in System Register */ 845 value = Q81_CTL_SYSTEM_ENABLE_FAE | Q81_CTL_SYSTEM_ENABLE_EFE; 846 value = (value << Q81_CTL_SYSTEM_MASK_SHIFT) | value; 847 848 WRITE_REG32(ha, Q81_CTL_SYSTEM, value); 849 850 /* Set Default Completion Queue_ID in NIC Rcv Configuration Register */ 851 value = (Q81_CTL_NIC_RCVC_DCQ_MASK << Q81_CTL_NIC_RCVC_MASK_SHIFT); 852 WRITE_REG32(ha, Q81_CTL_NIC_RCV_CONFIG, value); 853 854 /* Function Specific Control Register - Set Page Size and Enable NIC */ 855 value = Q81_CTL_FUNC_SPECIFIC_FE | 856 Q81_CTL_FUNC_SPECIFIC_VM_PGSIZE_MASK | 857 Q81_CTL_FUNC_SPECIFIC_EPC_O | 858 Q81_CTL_FUNC_SPECIFIC_EPC_I | 859 Q81_CTL_FUNC_SPECIFIC_EC; 860 value = (value << Q81_CTL_FUNC_SPECIFIC_MASK_SHIFT) | 861 Q81_CTL_FUNC_SPECIFIC_FE | 862 Q81_CTL_FUNC_SPECIFIC_VM_PGSIZE_4K | 863 Q81_CTL_FUNC_SPECIFIC_EPC_O | 864 Q81_CTL_FUNC_SPECIFIC_EPC_I | 865 Q81_CTL_FUNC_SPECIFIC_EC; 866 867 WRITE_REG32(ha, Q81_CTL_FUNC_SPECIFIC, value); 868 869 /* Interrupt Mask Register */ 870 value = Q81_CTL_INTRM_PI; 871 value = (value << Q81_CTL_INTRM_MASK_SHIFT) | value; 872 873 WRITE_REG32(ha, Q81_CTL_INTR_MASK, value); 874 875 /* Initialiatize Completion Queue */ 876 for (i = 0; i < ha->num_rx_rings; i++) { 877 ret = qls_init_comp_queue(ha, i); 878 if (ret) 879 goto qls_init_hw_if_exit; 880 } 881 882 if (ha->num_rx_rings > 1 ) { 883 ret = qls_init_rss(ha); 884 if (ret) 885 goto qls_init_hw_if_exit; 886 } 887 888 /* Initialize Work Queue */ 889 890 for (i = 0; i < ha->num_tx_rings; i++) { 891 ret = qls_init_work_queue(ha, i); 892 if (ret) 893 goto qls_init_hw_if_exit; 894 } 895 896 if (ret) 897 goto qls_init_hw_if_exit; 898 899 /* Set up CAM RAM with MAC Address */ 900 ret = qls_config_unicast_mac_addr(ha, 1); 901 if (ret) 902 goto qls_init_hw_if_exit; 903 904 ret = qls_hw_add_all_mcast(ha); 905 if (ret) 906 goto qls_init_hw_if_exit; 907 908 /* Initialize Firmware Routing Table */ 909 ret = qls_init_fw_routing_table(ha); 910 if (ret) 911 goto qls_init_hw_if_exit; 912 913 /* Get Chip Revision ID */ 914 ha->rev_id = READ_REG32(ha, Q81_CTL_REV_ID); 915 916 /* Enable Global Interrupt */ 917 value = Q81_CTL_INTRE_EI; 918 value = (value << Q81_CTL_INTRE_MASK_SHIFT) | value; 919 920 WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value); 921 922 /* Enable Interrupt Handshake Disable */ 923 value = Q81_CTL_INTRE_IHD; 924 value = (value << Q81_CTL_INTRE_MASK_SHIFT) | value; 925 926 WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, value); 927 928 /* Enable Completion Interrupt */ 929 930 ha->flags.intr_enable = 1; 931 932 for (i = 0; i < ha->num_rx_rings; i++) { 933 Q81_ENABLE_INTR(ha, i); /* MSI-x i */ 934 } 935 936 ha->hw_init = 1; 937 938 qls_mbx_get_link_status(ha); 939 940 QL_DPRINT2((ha->pci_dev, "%s:rxr [0x%08x]\n", __func__, 941 ha->rx_ring[0].cq_db_offset)); 942 QL_DPRINT2((ha->pci_dev, "%s:txr [0x%08x]\n", __func__, 943 ha->tx_ring[0].wq_db_offset)); 944 945 for (i = 0; i < ha->num_rx_rings; i++) { 946 947 Q81_WR_CQ_CONS_IDX(i, 0); 948 Q81_WR_LBQ_PROD_IDX(i, ha->rx_ring[i].lbq_in); 949 Q81_WR_SBQ_PROD_IDX(i, ha->rx_ring[i].sbq_in); 950 951 QL_DPRINT2((dev, "%s: [wq_idx, cq_idx, lbq_idx, sbq_idx]" 952 "[0x%08x, 0x%08x, 0x%08x, 0x%08x]\n", __func__, 953 Q81_RD_WQ_IDX(i), Q81_RD_CQ_IDX(i), Q81_RD_LBQ_IDX(i), 954 Q81_RD_SBQ_IDX(i))); 955 } 956 957 for (i = 0; i < ha->num_rx_rings; i++) { 958 Q81_SET_CQ_VALID(i); 959 } 960 961 qls_init_hw_if_exit: 962 QL_DPRINT2((ha->pci_dev, "%s:exit\n", __func__)); 963 return (ret); 964 } 965 966 static int 967 qls_wait_for_config_reg_bits(qla_host_t *ha, uint32_t bits, uint32_t value) 968 { 969 uint32_t data32; 970 uint32_t count = 3; 971 972 while (count--) { 973 974 data32 = READ_REG32(ha, Q81_CTL_CONFIG); 975 976 if ((data32 & bits) == value) 977 return (0); 978 979 QLA_USEC_DELAY(100); 980 } 981 ha->qla_initiate_recovery = 1; 982 device_printf(ha->pci_dev, "%s: failed\n", __func__); 983 return (-1); 984 } 985 986 static uint8_t q81_hash_key[] = { 987 0xda, 0x56, 0x5a, 0x6d, 988 0xc2, 0x0e, 0x5b, 0x25, 989 0x3d, 0x25, 0x67, 0x41, 990 0xb0, 0x8f, 0xa3, 0x43, 991 0xcb, 0x2b, 0xca, 0xd0, 992 0xb4, 0x30, 0x7b, 0xae, 993 0xa3, 0x2d, 0xcb, 0x77, 994 0x0c, 0xf2, 0x30, 0x80, 995 0x3b, 0xb7, 0x42, 0x6a, 996 0xfa, 0x01, 0xac, 0xbe }; 997 998 static int 999 qls_init_rss(qla_host_t *ha) 1000 { 1001 q81_rss_icb_t *rss_icb; 1002 int ret = 0; 1003 int i; 1004 uint32_t value; 1005 1006 rss_icb = ha->rss_dma.dma_b; 1007 1008 bzero(rss_icb, sizeof (q81_rss_icb_t)); 1009 1010 rss_icb->flags_base_cq_num = Q81_RSS_ICB_FLAGS_L4K | 1011 Q81_RSS_ICB_FLAGS_L6K | Q81_RSS_ICB_FLAGS_LI | 1012 Q81_RSS_ICB_FLAGS_LB | Q81_RSS_ICB_FLAGS_LM | 1013 Q81_RSS_ICB_FLAGS_RT4 | Q81_RSS_ICB_FLAGS_RT6; 1014 1015 rss_icb->mask = 0x3FF; 1016 1017 for (i = 0; i < Q81_RSS_ICB_NUM_INDTBL_ENTRIES; i++) { 1018 rss_icb->cq_id[i] = (i & (ha->num_rx_rings - 1)); 1019 } 1020 1021 memcpy(rss_icb->ipv6_rss_hash_key, q81_hash_key, 40); 1022 memcpy(rss_icb->ipv4_rss_hash_key, q81_hash_key, 16); 1023 1024 ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LR, 0); 1025 1026 if (ret) 1027 goto qls_init_rss_exit; 1028 1029 ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB); 1030 1031 if (ret) { 1032 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 1033 goto qls_init_rss_exit; 1034 } 1035 1036 value = (uint32_t)ha->rss_dma.dma_addr; 1037 WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value); 1038 1039 value = (uint32_t)(ha->rss_dma.dma_addr >> 32); 1040 WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value); 1041 1042 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB); 1043 1044 value = (Q81_CTL_CONFIG_LR << Q81_CTL_CONFIG_MASK_SHIFT) | 1045 Q81_CTL_CONFIG_LR; 1046 1047 WRITE_REG32(ha, Q81_CTL_CONFIG, value); 1048 1049 ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LR, 0); 1050 1051 qls_init_rss_exit: 1052 return (ret); 1053 } 1054 1055 static int 1056 qls_init_comp_queue(qla_host_t *ha, int cid) 1057 { 1058 q81_cq_icb_t *cq_icb; 1059 qla_rx_ring_t *rxr; 1060 int ret = 0; 1061 uint32_t value; 1062 1063 rxr = &ha->rx_ring[cid]; 1064 1065 rxr->cq_db_offset = ha->vm_pgsize * (128 + cid); 1066 1067 cq_icb = rxr->cq_icb_vaddr; 1068 1069 bzero(cq_icb, sizeof (q81_cq_icb_t)); 1070 1071 cq_icb->msix_vector = cid; 1072 cq_icb->flags = Q81_CQ_ICB_FLAGS_LC | 1073 Q81_CQ_ICB_FLAGS_LI | 1074 Q81_CQ_ICB_FLAGS_LL | 1075 Q81_CQ_ICB_FLAGS_LS | 1076 Q81_CQ_ICB_FLAGS_LV; 1077 1078 cq_icb->length_v = NUM_CQ_ENTRIES; 1079 1080 cq_icb->cq_baddr_lo = (rxr->cq_base_paddr & 0xFFFFFFFF); 1081 cq_icb->cq_baddr_hi = (rxr->cq_base_paddr >> 32) & 0xFFFFFFFF; 1082 1083 cq_icb->cqi_addr_lo = (rxr->cqi_paddr & 0xFFFFFFFF); 1084 cq_icb->cqi_addr_hi = (rxr->cqi_paddr >> 32) & 0xFFFFFFFF; 1085 1086 cq_icb->pkt_idelay = 10; 1087 cq_icb->idelay = 100; 1088 1089 cq_icb->lbq_baddr_lo = (rxr->lbq_addr_tbl_paddr & 0xFFFFFFFF); 1090 cq_icb->lbq_baddr_hi = (rxr->lbq_addr_tbl_paddr >> 32) & 0xFFFFFFFF; 1091 1092 cq_icb->lbq_bsize = QLA_LGB_SIZE; 1093 cq_icb->lbq_length = QLA_NUM_LGB_ENTRIES; 1094 1095 cq_icb->sbq_baddr_lo = (rxr->sbq_addr_tbl_paddr & 0xFFFFFFFF); 1096 cq_icb->sbq_baddr_hi = (rxr->sbq_addr_tbl_paddr >> 32) & 0xFFFFFFFF; 1097 1098 cq_icb->sbq_bsize = (uint16_t)ha->msize; 1099 cq_icb->sbq_length = QLA_NUM_SMB_ENTRIES; 1100 1101 QL_DUMP_CQ(ha); 1102 1103 ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LCQ, 0); 1104 1105 if (ret) 1106 goto qls_init_comp_queue_exit; 1107 1108 ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB); 1109 1110 if (ret) { 1111 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 1112 goto qls_init_comp_queue_exit; 1113 } 1114 1115 value = (uint32_t)rxr->cq_icb_paddr; 1116 WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value); 1117 1118 value = (uint32_t)(rxr->cq_icb_paddr >> 32); 1119 WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value); 1120 1121 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB); 1122 1123 value = Q81_CTL_CONFIG_LCQ | Q81_CTL_CONFIG_Q_NUM_MASK; 1124 value = (value << Q81_CTL_CONFIG_MASK_SHIFT) | Q81_CTL_CONFIG_LCQ; 1125 value |= (cid << Q81_CTL_CONFIG_Q_NUM_SHIFT); 1126 WRITE_REG32(ha, Q81_CTL_CONFIG, value); 1127 1128 ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LCQ, 0); 1129 1130 rxr->cq_next = 0; 1131 rxr->lbq_next = rxr->lbq_free = 0; 1132 rxr->sbq_next = rxr->sbq_free = 0; 1133 rxr->rx_free = rxr->rx_next = 0; 1134 rxr->lbq_in = (QLA_NUM_LGB_ENTRIES - 1) & ~0xF; 1135 rxr->sbq_in = (QLA_NUM_SMB_ENTRIES - 1) & ~0xF; 1136 1137 qls_init_comp_queue_exit: 1138 return (ret); 1139 } 1140 1141 static int 1142 qls_init_work_queue(qla_host_t *ha, int wid) 1143 { 1144 q81_wq_icb_t *wq_icb; 1145 qla_tx_ring_t *txr; 1146 int ret = 0; 1147 uint32_t value; 1148 1149 txr = &ha->tx_ring[wid]; 1150 1151 txr->wq_db_addr = (struct resource *)((uint8_t *)ha->pci_reg1 1152 + (ha->vm_pgsize * wid)); 1153 1154 txr->wq_db_offset = (ha->vm_pgsize * wid); 1155 1156 wq_icb = txr->wq_icb_vaddr; 1157 bzero(wq_icb, sizeof (q81_wq_icb_t)); 1158 1159 wq_icb->length_v = NUM_TX_DESCRIPTORS | 1160 Q81_WQ_ICB_VALID; 1161 1162 wq_icb->flags = Q81_WQ_ICB_FLAGS_LO | Q81_WQ_ICB_FLAGS_LI | 1163 Q81_WQ_ICB_FLAGS_LB | Q81_WQ_ICB_FLAGS_LC; 1164 1165 wq_icb->wqcqid_rss = wid; 1166 1167 wq_icb->baddr_lo = txr->wq_paddr & 0xFFFFFFFF; 1168 wq_icb->baddr_hi = (txr->wq_paddr >> 32)& 0xFFFFFFFF; 1169 1170 wq_icb->ci_addr_lo = txr->txr_cons_paddr & 0xFFFFFFFF; 1171 wq_icb->ci_addr_hi = (txr->txr_cons_paddr >> 32)& 0xFFFFFFFF; 1172 1173 ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LRQ, 0); 1174 1175 if (ret) 1176 goto qls_init_wq_exit; 1177 1178 ret = qls_sem_lock(ha, Q81_CTL_SEM_MASK_ICB, Q81_CTL_SEM_SET_ICB); 1179 1180 if (ret) { 1181 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 1182 goto qls_init_wq_exit; 1183 } 1184 1185 value = (uint32_t)txr->wq_icb_paddr; 1186 WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_LO, value); 1187 1188 value = (uint32_t)(txr->wq_icb_paddr >> 32); 1189 WRITE_REG32(ha, Q81_CTL_ICB_ACCESS_ADDR_HI, value); 1190 1191 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_ICB); 1192 1193 value = Q81_CTL_CONFIG_LRQ | Q81_CTL_CONFIG_Q_NUM_MASK; 1194 value = (value << Q81_CTL_CONFIG_MASK_SHIFT) | Q81_CTL_CONFIG_LRQ; 1195 value |= (wid << Q81_CTL_CONFIG_Q_NUM_SHIFT); 1196 WRITE_REG32(ha, Q81_CTL_CONFIG, value); 1197 1198 ret = qls_wait_for_config_reg_bits(ha, Q81_CTL_CONFIG_LRQ, 0); 1199 1200 txr->txr_free = NUM_TX_DESCRIPTORS; 1201 txr->txr_next = 0; 1202 txr->txr_done = 0; 1203 1204 qls_init_wq_exit: 1205 return (ret); 1206 } 1207 1208 static int 1209 qls_hw_add_all_mcast(qla_host_t *ha) 1210 { 1211 int i, nmcast; 1212 1213 nmcast = ha->nmcast; 1214 1215 for (i = 0 ; ((i < Q8_MAX_NUM_MULTICAST_ADDRS) && nmcast); i++) { 1216 if ((ha->mcast[i].addr[0] != 0) || 1217 (ha->mcast[i].addr[1] != 0) || 1218 (ha->mcast[i].addr[2] != 0) || 1219 (ha->mcast[i].addr[3] != 0) || 1220 (ha->mcast[i].addr[4] != 0) || 1221 (ha->mcast[i].addr[5] != 0)) { 1222 1223 if (qls_config_mcast_mac_addr(ha, ha->mcast[i].addr, 1224 1, i)) { 1225 device_printf(ha->pci_dev, "%s: failed\n", 1226 __func__); 1227 return (-1); 1228 } 1229 1230 nmcast--; 1231 } 1232 } 1233 return 0; 1234 } 1235 1236 static int 1237 qls_hw_add_mcast(qla_host_t *ha, uint8_t *mta) 1238 { 1239 int i; 1240 1241 for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) { 1242 1243 if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0) 1244 return 0; /* its been already added */ 1245 } 1246 1247 for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) { 1248 1249 if ((ha->mcast[i].addr[0] == 0) && 1250 (ha->mcast[i].addr[1] == 0) && 1251 (ha->mcast[i].addr[2] == 0) && 1252 (ha->mcast[i].addr[3] == 0) && 1253 (ha->mcast[i].addr[4] == 0) && 1254 (ha->mcast[i].addr[5] == 0)) { 1255 1256 if (qls_config_mcast_mac_addr(ha, mta, 1, i)) 1257 return (-1); 1258 1259 bcopy(mta, ha->mcast[i].addr, Q8_MAC_ADDR_LEN); 1260 ha->nmcast++; 1261 1262 return 0; 1263 } 1264 } 1265 return 0; 1266 } 1267 1268 static int 1269 qls_hw_del_mcast(qla_host_t *ha, uint8_t *mta) 1270 { 1271 int i; 1272 1273 for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) { 1274 if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0) { 1275 1276 if (qls_config_mcast_mac_addr(ha, mta, 0, i)) 1277 return (-1); 1278 1279 ha->mcast[i].addr[0] = 0; 1280 ha->mcast[i].addr[1] = 0; 1281 ha->mcast[i].addr[2] = 0; 1282 ha->mcast[i].addr[3] = 0; 1283 ha->mcast[i].addr[4] = 0; 1284 ha->mcast[i].addr[5] = 0; 1285 1286 ha->nmcast--; 1287 1288 return 0; 1289 } 1290 } 1291 return 0; 1292 } 1293 1294 /* 1295 * Name: qls_hw_set_multi 1296 * Function: Sets the Multicast Addresses provided the host O.S into the 1297 * hardware (for the given interface) 1298 */ 1299 void 1300 qls_hw_set_multi(qla_host_t *ha, uint8_t *mta, uint32_t mcnt, 1301 uint32_t add_mac) 1302 { 1303 int i; 1304 1305 for (i = 0; i < mcnt; i++) { 1306 if (add_mac) { 1307 if (qls_hw_add_mcast(ha, mta)) 1308 break; 1309 } else { 1310 if (qls_hw_del_mcast(ha, mta)) 1311 break; 1312 } 1313 1314 mta += Q8_MAC_ADDR_LEN; 1315 } 1316 return; 1317 } 1318 1319 void 1320 qls_update_link_state(qla_host_t *ha) 1321 { 1322 uint32_t link_state; 1323 uint32_t prev_link_state; 1324 1325 if (!(ha->ifp->if_drv_flags & IFF_DRV_RUNNING)) { 1326 ha->link_up = 0; 1327 return; 1328 } 1329 link_state = READ_REG32(ha, Q81_CTL_STATUS); 1330 1331 prev_link_state = ha->link_up; 1332 1333 if ((ha->pci_func & 0x1) == 0) 1334 ha->link_up = ((link_state & Q81_CTL_STATUS_PL0)? 1 : 0); 1335 else 1336 ha->link_up = ((link_state & Q81_CTL_STATUS_PL1)? 1 : 0); 1337 1338 if (prev_link_state != ha->link_up) { 1339 1340 1341 if (ha->link_up) { 1342 if_link_state_change(ha->ifp, LINK_STATE_UP); 1343 } else { 1344 if_link_state_change(ha->ifp, LINK_STATE_DOWN); 1345 } 1346 } 1347 return; 1348 } 1349 1350 static void 1351 qls_free_tx_ring_dma(qla_host_t *ha, int r_idx) 1352 { 1353 if (ha->tx_ring[r_idx].flags.wq_dma) { 1354 qls_free_dmabuf(ha, &ha->tx_ring[r_idx].wq_dma); 1355 ha->tx_ring[r_idx].flags.wq_dma = 0; 1356 } 1357 1358 if (ha->tx_ring[r_idx].flags.privb_dma) { 1359 qls_free_dmabuf(ha, &ha->tx_ring[r_idx].privb_dma); 1360 ha->tx_ring[r_idx].flags.privb_dma = 0; 1361 } 1362 return; 1363 } 1364 1365 static void 1366 qls_free_tx_dma(qla_host_t *ha) 1367 { 1368 int i, j; 1369 qla_tx_buf_t *txb; 1370 1371 for (i = 0; i < ha->num_tx_rings; i++) { 1372 1373 qls_free_tx_ring_dma(ha, i); 1374 1375 for (j = 0; j < NUM_TX_DESCRIPTORS; j++) { 1376 1377 txb = &ha->tx_ring[i].tx_buf[j]; 1378 1379 if (txb->map) { 1380 bus_dmamap_destroy(ha->tx_tag, txb->map); 1381 } 1382 } 1383 } 1384 1385 if (ha->tx_tag != NULL) { 1386 bus_dma_tag_destroy(ha->tx_tag); 1387 ha->tx_tag = NULL; 1388 } 1389 1390 return; 1391 } 1392 1393 static int 1394 qls_alloc_tx_ring_dma(qla_host_t *ha, int ridx) 1395 { 1396 int ret = 0, i; 1397 uint8_t *v_addr; 1398 bus_addr_t p_addr; 1399 qla_tx_buf_t *txb; 1400 device_t dev = ha->pci_dev; 1401 1402 ha->tx_ring[ridx].wq_dma.alignment = 8; 1403 ha->tx_ring[ridx].wq_dma.size = 1404 NUM_TX_DESCRIPTORS * (sizeof (q81_tx_cmd_t)); 1405 1406 ret = qls_alloc_dmabuf(ha, &ha->tx_ring[ridx].wq_dma); 1407 1408 if (ret) { 1409 device_printf(dev, "%s: [%d] txr failed\n", __func__, ridx); 1410 goto qls_alloc_tx_ring_dma_exit; 1411 } 1412 ha->tx_ring[ridx].flags.wq_dma = 1; 1413 1414 ha->tx_ring[ridx].privb_dma.alignment = 8; 1415 ha->tx_ring[ridx].privb_dma.size = QLA_TX_PRIVATE_BSIZE; 1416 1417 ret = qls_alloc_dmabuf(ha, &ha->tx_ring[ridx].privb_dma); 1418 1419 if (ret) { 1420 device_printf(dev, "%s: [%d] oalb failed\n", __func__, ridx); 1421 goto qls_alloc_tx_ring_dma_exit; 1422 } 1423 1424 ha->tx_ring[ridx].flags.privb_dma = 1; 1425 1426 ha->tx_ring[ridx].wq_vaddr = ha->tx_ring[ridx].wq_dma.dma_b; 1427 ha->tx_ring[ridx].wq_paddr = ha->tx_ring[ridx].wq_dma.dma_addr; 1428 1429 v_addr = ha->tx_ring[ridx].privb_dma.dma_b; 1430 p_addr = ha->tx_ring[ridx].privb_dma.dma_addr; 1431 1432 ha->tx_ring[ridx].wq_icb_vaddr = v_addr; 1433 ha->tx_ring[ridx].wq_icb_paddr = p_addr; 1434 1435 ha->tx_ring[ridx].txr_cons_vaddr = 1436 (uint32_t *)(v_addr + (PAGE_SIZE >> 1)); 1437 ha->tx_ring[ridx].txr_cons_paddr = p_addr + (PAGE_SIZE >> 1); 1438 1439 v_addr = v_addr + (PAGE_SIZE >> 1); 1440 p_addr = p_addr + (PAGE_SIZE >> 1); 1441 1442 txb = ha->tx_ring[ridx].tx_buf; 1443 1444 for (i = 0; i < NUM_TX_DESCRIPTORS; i++) { 1445 1446 txb[i].oal_vaddr = v_addr; 1447 txb[i].oal_paddr = p_addr; 1448 1449 v_addr = v_addr + QLA_OAL_BLK_SIZE; 1450 p_addr = p_addr + QLA_OAL_BLK_SIZE; 1451 } 1452 1453 qls_alloc_tx_ring_dma_exit: 1454 return (ret); 1455 } 1456 1457 static int 1458 qls_alloc_tx_dma(qla_host_t *ha) 1459 { 1460 int i, j; 1461 int ret = 0; 1462 qla_tx_buf_t *txb; 1463 1464 if (bus_dma_tag_create(NULL, /* parent */ 1465 1, 0, /* alignment, bounds */ 1466 BUS_SPACE_MAXADDR, /* lowaddr */ 1467 BUS_SPACE_MAXADDR, /* highaddr */ 1468 NULL, NULL, /* filter, filterarg */ 1469 QLA_MAX_TSO_FRAME_SIZE, /* maxsize */ 1470 QLA_MAX_SEGMENTS, /* nsegments */ 1471 PAGE_SIZE, /* maxsegsize */ 1472 BUS_DMA_ALLOCNOW, /* flags */ 1473 NULL, /* lockfunc */ 1474 NULL, /* lockfuncarg */ 1475 &ha->tx_tag)) { 1476 device_printf(ha->pci_dev, "%s: tx_tag alloc failed\n", 1477 __func__); 1478 return (ENOMEM); 1479 } 1480 1481 for (i = 0; i < ha->num_tx_rings; i++) { 1482 1483 ret = qls_alloc_tx_ring_dma(ha, i); 1484 1485 if (ret) { 1486 qls_free_tx_dma(ha); 1487 break; 1488 } 1489 1490 for (j = 0; j < NUM_TX_DESCRIPTORS; j++) { 1491 1492 txb = &ha->tx_ring[i].tx_buf[j]; 1493 1494 ret = bus_dmamap_create(ha->tx_tag, 1495 BUS_DMA_NOWAIT, &txb->map); 1496 if (ret) { 1497 ha->err_tx_dmamap_create++; 1498 device_printf(ha->pci_dev, 1499 "%s: bus_dmamap_create failed[%d, %d, %d]\n", 1500 __func__, ret, i, j); 1501 1502 qls_free_tx_dma(ha); 1503 1504 return (ret); 1505 } 1506 } 1507 } 1508 1509 return (ret); 1510 } 1511 1512 static void 1513 qls_free_rss_dma(qla_host_t *ha) 1514 { 1515 qls_free_dmabuf(ha, &ha->rss_dma); 1516 ha->flags.rss_dma = 0; 1517 } 1518 1519 static int 1520 qls_alloc_rss_dma(qla_host_t *ha) 1521 { 1522 int ret = 0; 1523 1524 ha->rss_dma.alignment = 4; 1525 ha->rss_dma.size = PAGE_SIZE; 1526 1527 ret = qls_alloc_dmabuf(ha, &ha->rss_dma); 1528 1529 if (ret) 1530 device_printf(ha->pci_dev, "%s: failed\n", __func__); 1531 else 1532 ha->flags.rss_dma = 1; 1533 1534 return (ret); 1535 } 1536 1537 static void 1538 qls_free_mpi_dma(qla_host_t *ha) 1539 { 1540 qls_free_dmabuf(ha, &ha->mpi_dma); 1541 ha->flags.mpi_dma = 0; 1542 } 1543 1544 static int 1545 qls_alloc_mpi_dma(qla_host_t *ha) 1546 { 1547 int ret = 0; 1548 1549 ha->mpi_dma.alignment = 4; 1550 ha->mpi_dma.size = (0x4000 * 4); 1551 1552 ret = qls_alloc_dmabuf(ha, &ha->mpi_dma); 1553 if (ret) 1554 device_printf(ha->pci_dev, "%s: failed\n", __func__); 1555 else 1556 ha->flags.mpi_dma = 1; 1557 1558 return (ret); 1559 } 1560 1561 static void 1562 qls_free_rx_ring_dma(qla_host_t *ha, int ridx) 1563 { 1564 if (ha->rx_ring[ridx].flags.cq_dma) { 1565 qls_free_dmabuf(ha, &ha->rx_ring[ridx].cq_dma); 1566 ha->rx_ring[ridx].flags.cq_dma = 0; 1567 } 1568 1569 if (ha->rx_ring[ridx].flags.lbq_dma) { 1570 qls_free_dmabuf(ha, &ha->rx_ring[ridx].lbq_dma); 1571 ha->rx_ring[ridx].flags.lbq_dma = 0; 1572 } 1573 1574 if (ha->rx_ring[ridx].flags.sbq_dma) { 1575 qls_free_dmabuf(ha, &ha->rx_ring[ridx].sbq_dma); 1576 ha->rx_ring[ridx].flags.sbq_dma = 0; 1577 } 1578 1579 if (ha->rx_ring[ridx].flags.lb_dma) { 1580 qls_free_dmabuf(ha, &ha->rx_ring[ridx].lb_dma); 1581 ha->rx_ring[ridx].flags.lb_dma = 0; 1582 } 1583 return; 1584 } 1585 1586 static void 1587 qls_free_rx_dma(qla_host_t *ha) 1588 { 1589 int i; 1590 1591 for (i = 0; i < ha->num_rx_rings; i++) { 1592 qls_free_rx_ring_dma(ha, i); 1593 } 1594 1595 if (ha->rx_tag != NULL) { 1596 bus_dma_tag_destroy(ha->rx_tag); 1597 ha->rx_tag = NULL; 1598 } 1599 1600 return; 1601 } 1602 1603 static int 1604 qls_alloc_rx_ring_dma(qla_host_t *ha, int ridx) 1605 { 1606 int i, ret = 0; 1607 uint8_t *v_addr; 1608 bus_addr_t p_addr; 1609 volatile q81_bq_addr_e_t *bq_e; 1610 device_t dev = ha->pci_dev; 1611 1612 ha->rx_ring[ridx].cq_dma.alignment = 128; 1613 ha->rx_ring[ridx].cq_dma.size = 1614 (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t))) + PAGE_SIZE; 1615 1616 ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].cq_dma); 1617 1618 if (ret) { 1619 device_printf(dev, "%s: [%d] cq failed\n", __func__, ridx); 1620 goto qls_alloc_rx_ring_dma_exit; 1621 } 1622 ha->rx_ring[ridx].flags.cq_dma = 1; 1623 1624 ha->rx_ring[ridx].lbq_dma.alignment = 8; 1625 ha->rx_ring[ridx].lbq_dma.size = QLA_LGBQ_AND_TABLE_SIZE; 1626 1627 ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].lbq_dma); 1628 1629 if (ret) { 1630 device_printf(dev, "%s: [%d] lbq failed\n", __func__, ridx); 1631 goto qls_alloc_rx_ring_dma_exit; 1632 } 1633 ha->rx_ring[ridx].flags.lbq_dma = 1; 1634 1635 ha->rx_ring[ridx].sbq_dma.alignment = 8; 1636 ha->rx_ring[ridx].sbq_dma.size = QLA_SMBQ_AND_TABLE_SIZE; 1637 1638 ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].sbq_dma); 1639 1640 if (ret) { 1641 device_printf(dev, "%s: [%d] sbq failed\n", __func__, ridx); 1642 goto qls_alloc_rx_ring_dma_exit; 1643 } 1644 ha->rx_ring[ridx].flags.sbq_dma = 1; 1645 1646 ha->rx_ring[ridx].lb_dma.alignment = 8; 1647 ha->rx_ring[ridx].lb_dma.size = (QLA_LGB_SIZE * QLA_NUM_LGB_ENTRIES); 1648 1649 ret = qls_alloc_dmabuf(ha, &ha->rx_ring[ridx].lb_dma); 1650 if (ret) { 1651 device_printf(dev, "%s: [%d] lb failed\n", __func__, ridx); 1652 goto qls_alloc_rx_ring_dma_exit; 1653 } 1654 ha->rx_ring[ridx].flags.lb_dma = 1; 1655 1656 bzero(ha->rx_ring[ridx].cq_dma.dma_b, ha->rx_ring[ridx].cq_dma.size); 1657 bzero(ha->rx_ring[ridx].lbq_dma.dma_b, ha->rx_ring[ridx].lbq_dma.size); 1658 bzero(ha->rx_ring[ridx].sbq_dma.dma_b, ha->rx_ring[ridx].sbq_dma.size); 1659 bzero(ha->rx_ring[ridx].lb_dma.dma_b, ha->rx_ring[ridx].lb_dma.size); 1660 1661 /* completion queue */ 1662 ha->rx_ring[ridx].cq_base_vaddr = ha->rx_ring[ridx].cq_dma.dma_b; 1663 ha->rx_ring[ridx].cq_base_paddr = ha->rx_ring[ridx].cq_dma.dma_addr; 1664 1665 v_addr = ha->rx_ring[ridx].cq_dma.dma_b; 1666 p_addr = ha->rx_ring[ridx].cq_dma.dma_addr; 1667 1668 v_addr = v_addr + (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t))); 1669 p_addr = p_addr + (NUM_CQ_ENTRIES * (sizeof (q81_cq_e_t))); 1670 1671 /* completion queue icb */ 1672 ha->rx_ring[ridx].cq_icb_vaddr = v_addr; 1673 ha->rx_ring[ridx].cq_icb_paddr = p_addr; 1674 1675 v_addr = v_addr + (PAGE_SIZE >> 2); 1676 p_addr = p_addr + (PAGE_SIZE >> 2); 1677 1678 /* completion queue index register */ 1679 ha->rx_ring[ridx].cqi_vaddr = (uint32_t *)v_addr; 1680 ha->rx_ring[ridx].cqi_paddr = p_addr; 1681 1682 v_addr = ha->rx_ring[ridx].lbq_dma.dma_b; 1683 p_addr = ha->rx_ring[ridx].lbq_dma.dma_addr; 1684 1685 /* large buffer queue address table */ 1686 ha->rx_ring[ridx].lbq_addr_tbl_vaddr = v_addr; 1687 ha->rx_ring[ridx].lbq_addr_tbl_paddr = p_addr; 1688 1689 /* large buffer queue */ 1690 ha->rx_ring[ridx].lbq_vaddr = v_addr + PAGE_SIZE; 1691 ha->rx_ring[ridx].lbq_paddr = p_addr + PAGE_SIZE; 1692 1693 v_addr = ha->rx_ring[ridx].sbq_dma.dma_b; 1694 p_addr = ha->rx_ring[ridx].sbq_dma.dma_addr; 1695 1696 /* small buffer queue address table */ 1697 ha->rx_ring[ridx].sbq_addr_tbl_vaddr = v_addr; 1698 ha->rx_ring[ridx].sbq_addr_tbl_paddr = p_addr; 1699 1700 /* small buffer queue */ 1701 ha->rx_ring[ridx].sbq_vaddr = v_addr + PAGE_SIZE; 1702 ha->rx_ring[ridx].sbq_paddr = p_addr + PAGE_SIZE; 1703 1704 ha->rx_ring[ridx].lb_vaddr = ha->rx_ring[ridx].lb_dma.dma_b; 1705 ha->rx_ring[ridx].lb_paddr = ha->rx_ring[ridx].lb_dma.dma_addr; 1706 1707 /* Initialize Large Buffer Queue Table */ 1708 1709 p_addr = ha->rx_ring[ridx].lbq_paddr; 1710 bq_e = ha->rx_ring[ridx].lbq_addr_tbl_vaddr; 1711 1712 bq_e->addr_lo = p_addr & 0xFFFFFFFF; 1713 bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF; 1714 1715 p_addr = ha->rx_ring[ridx].lb_paddr; 1716 bq_e = ha->rx_ring[ridx].lbq_vaddr; 1717 1718 for (i = 0; i < QLA_NUM_LGB_ENTRIES; i++) { 1719 bq_e->addr_lo = p_addr & 0xFFFFFFFF; 1720 bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF; 1721 1722 p_addr = p_addr + QLA_LGB_SIZE; 1723 bq_e++; 1724 } 1725 1726 /* Initialize Small Buffer Queue Table */ 1727 1728 p_addr = ha->rx_ring[ridx].sbq_paddr; 1729 bq_e = ha->rx_ring[ridx].sbq_addr_tbl_vaddr; 1730 1731 for (i =0; i < (QLA_SBQ_SIZE/QLA_PAGE_SIZE); i++) { 1732 bq_e->addr_lo = p_addr & 0xFFFFFFFF; 1733 bq_e->addr_hi = (p_addr >> 32) & 0xFFFFFFFF; 1734 1735 p_addr = p_addr + QLA_PAGE_SIZE; 1736 bq_e++; 1737 } 1738 1739 qls_alloc_rx_ring_dma_exit: 1740 return (ret); 1741 } 1742 1743 static int 1744 qls_alloc_rx_dma(qla_host_t *ha) 1745 { 1746 int i; 1747 int ret = 0; 1748 1749 if (bus_dma_tag_create(NULL, /* parent */ 1750 1, 0, /* alignment, bounds */ 1751 BUS_SPACE_MAXADDR, /* lowaddr */ 1752 BUS_SPACE_MAXADDR, /* highaddr */ 1753 NULL, NULL, /* filter, filterarg */ 1754 MJUM9BYTES, /* maxsize */ 1755 1, /* nsegments */ 1756 MJUM9BYTES, /* maxsegsize */ 1757 BUS_DMA_ALLOCNOW, /* flags */ 1758 NULL, /* lockfunc */ 1759 NULL, /* lockfuncarg */ 1760 &ha->rx_tag)) { 1761 1762 device_printf(ha->pci_dev, "%s: rx_tag alloc failed\n", 1763 __func__); 1764 1765 return (ENOMEM); 1766 } 1767 1768 for (i = 0; i < ha->num_rx_rings; i++) { 1769 ret = qls_alloc_rx_ring_dma(ha, i); 1770 1771 if (ret) { 1772 qls_free_rx_dma(ha); 1773 break; 1774 } 1775 } 1776 1777 return (ret); 1778 } 1779 1780 static int 1781 qls_wait_for_flash_ready(qla_host_t *ha) 1782 { 1783 uint32_t data32; 1784 uint32_t count = 3; 1785 1786 while (count--) { 1787 1788 data32 = READ_REG32(ha, Q81_CTL_FLASH_ADDR); 1789 1790 if (data32 & Q81_CTL_FLASH_ADDR_ERR) 1791 goto qls_wait_for_flash_ready_exit; 1792 1793 if (data32 & Q81_CTL_FLASH_ADDR_RDY) 1794 return (0); 1795 1796 QLA_USEC_DELAY(100); 1797 } 1798 1799 qls_wait_for_flash_ready_exit: 1800 QL_DPRINT1((ha->pci_dev, "%s: failed\n", __func__)); 1801 1802 return (-1); 1803 } 1804 1805 /* 1806 * Name: qls_rd_flash32 1807 * Function: Read Flash Memory 1808 */ 1809 int 1810 qls_rd_flash32(qla_host_t *ha, uint32_t addr, uint32_t *data) 1811 { 1812 int ret; 1813 1814 ret = qls_wait_for_flash_ready(ha); 1815 1816 if (ret) 1817 return (ret); 1818 1819 WRITE_REG32(ha, Q81_CTL_FLASH_ADDR, (addr | Q81_CTL_FLASH_ADDR_R)); 1820 1821 ret = qls_wait_for_flash_ready(ha); 1822 1823 if (ret) 1824 return (ret); 1825 1826 *data = READ_REG32(ha, Q81_CTL_FLASH_DATA); 1827 1828 return 0; 1829 } 1830 1831 static int 1832 qls_flash_validate(qla_host_t *ha, const char *signature) 1833 { 1834 uint16_t csum16 = 0; 1835 uint16_t *data16; 1836 int i; 1837 1838 if (bcmp(ha->flash.id, signature, 4)) { 1839 QL_DPRINT1((ha->pci_dev, "%s: invalid signature " 1840 "%x:%x:%x:%x %s\n", __func__, ha->flash.id[0], 1841 ha->flash.id[1], ha->flash.id[2], ha->flash.id[3], 1842 signature)); 1843 return(-1); 1844 } 1845 1846 data16 = (uint16_t *)&ha->flash; 1847 1848 for (i = 0; i < (sizeof (q81_flash_t) >> 1); i++) { 1849 csum16 += *data16++; 1850 } 1851 1852 if (csum16) { 1853 QL_DPRINT1((ha->pci_dev, "%s: invalid checksum\n", __func__)); 1854 return(-1); 1855 } 1856 return(0); 1857 } 1858 1859 int 1860 qls_rd_nic_params(qla_host_t *ha) 1861 { 1862 int i, ret = 0; 1863 uint32_t faddr; 1864 uint32_t *qflash; 1865 1866 if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_FLASH, Q81_CTL_SEM_SET_FLASH)) { 1867 QL_DPRINT1((ha->pci_dev, "%s: semlock failed\n", __func__)); 1868 return(-1); 1869 } 1870 1871 if ((ha->pci_func & 0x1) == 0) 1872 faddr = Q81_F0_FLASH_OFFSET >> 2; 1873 else 1874 faddr = Q81_F1_FLASH_OFFSET >> 2; 1875 1876 qflash = (uint32_t *)&ha->flash; 1877 1878 for (i = 0; i < (sizeof(q81_flash_t) >> 2) ; i++) { 1879 1880 ret = qls_rd_flash32(ha, faddr, qflash); 1881 1882 if (ret) 1883 goto qls_rd_flash_data_exit; 1884 1885 faddr++; 1886 qflash++; 1887 } 1888 1889 QL_DUMP_BUFFER8(ha, __func__, (&ha->flash), (sizeof (q81_flash_t))); 1890 1891 ret = qls_flash_validate(ha, Q81_FLASH_ID); 1892 1893 if (ret) 1894 goto qls_rd_flash_data_exit; 1895 1896 bcopy(ha->flash.mac_addr0, ha->mac_addr, ETHER_ADDR_LEN); 1897 1898 QL_DPRINT1((ha->pci_dev, "%s: mac %02x:%02x:%02x:%02x:%02x:%02x\n", 1899 __func__, ha->mac_addr[0], ha->mac_addr[1], ha->mac_addr[2], 1900 ha->mac_addr[3], ha->mac_addr[4], ha->mac_addr[5])); 1901 1902 qls_rd_flash_data_exit: 1903 1904 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_FLASH); 1905 1906 return(ret); 1907 } 1908 1909 static int 1910 qls_sem_lock(qla_host_t *ha, uint32_t mask, uint32_t value) 1911 { 1912 uint32_t count = 30; 1913 uint32_t data; 1914 1915 while (count--) { 1916 WRITE_REG32(ha, Q81_CTL_SEMAPHORE, (mask|value)); 1917 1918 data = READ_REG32(ha, Q81_CTL_SEMAPHORE); 1919 1920 if (data & value) { 1921 return (0); 1922 } else { 1923 QLA_USEC_DELAY(100); 1924 } 1925 } 1926 ha->qla_initiate_recovery = 1; 1927 return (-1); 1928 } 1929 1930 static void 1931 qls_sem_unlock(qla_host_t *ha, uint32_t mask) 1932 { 1933 WRITE_REG32(ha, Q81_CTL_SEMAPHORE, mask); 1934 } 1935 1936 static int 1937 qls_wait_for_proc_addr_ready(qla_host_t *ha) 1938 { 1939 uint32_t data32; 1940 uint32_t count = 3; 1941 1942 while (count--) { 1943 1944 data32 = READ_REG32(ha, Q81_CTL_PROC_ADDR); 1945 1946 if (data32 & Q81_CTL_PROC_ADDR_ERR) 1947 goto qls_wait_for_proc_addr_ready_exit; 1948 1949 if (data32 & Q81_CTL_PROC_ADDR_RDY) 1950 return (0); 1951 1952 QLA_USEC_DELAY(100); 1953 } 1954 1955 qls_wait_for_proc_addr_ready_exit: 1956 QL_DPRINT1((ha->pci_dev, "%s: failed\n", __func__)); 1957 1958 ha->qla_initiate_recovery = 1; 1959 return (-1); 1960 } 1961 1962 static int 1963 qls_proc_addr_rd_reg(qla_host_t *ha, uint32_t addr_module, uint32_t reg, 1964 uint32_t *data) 1965 { 1966 int ret; 1967 uint32_t value; 1968 1969 ret = qls_wait_for_proc_addr_ready(ha); 1970 1971 if (ret) 1972 goto qls_proc_addr_rd_reg_exit; 1973 1974 value = addr_module | reg | Q81_CTL_PROC_ADDR_READ; 1975 1976 WRITE_REG32(ha, Q81_CTL_PROC_ADDR, value); 1977 1978 ret = qls_wait_for_proc_addr_ready(ha); 1979 1980 if (ret) 1981 goto qls_proc_addr_rd_reg_exit; 1982 1983 *data = READ_REG32(ha, Q81_CTL_PROC_DATA); 1984 1985 qls_proc_addr_rd_reg_exit: 1986 return (ret); 1987 } 1988 1989 static int 1990 qls_proc_addr_wr_reg(qla_host_t *ha, uint32_t addr_module, uint32_t reg, 1991 uint32_t data) 1992 { 1993 int ret; 1994 uint32_t value; 1995 1996 ret = qls_wait_for_proc_addr_ready(ha); 1997 1998 if (ret) 1999 goto qls_proc_addr_wr_reg_exit; 2000 2001 WRITE_REG32(ha, Q81_CTL_PROC_DATA, data); 2002 2003 value = addr_module | reg; 2004 2005 WRITE_REG32(ha, Q81_CTL_PROC_ADDR, value); 2006 2007 ret = qls_wait_for_proc_addr_ready(ha); 2008 2009 qls_proc_addr_wr_reg_exit: 2010 return (ret); 2011 } 2012 2013 static int 2014 qls_hw_nic_reset(qla_host_t *ha) 2015 { 2016 int count; 2017 uint32_t data; 2018 device_t dev = ha->pci_dev; 2019 2020 ha->hw_init = 0; 2021 2022 data = (Q81_CTL_RESET_FUNC << Q81_CTL_RESET_MASK_SHIFT) | 2023 Q81_CTL_RESET_FUNC; 2024 WRITE_REG32(ha, Q81_CTL_RESET, data); 2025 2026 count = 10; 2027 while (count--) { 2028 data = READ_REG32(ha, Q81_CTL_RESET); 2029 if ((data & Q81_CTL_RESET_FUNC) == 0) 2030 break; 2031 QLA_USEC_DELAY(10); 2032 } 2033 if (count == 0) { 2034 device_printf(dev, "%s: Bit 15 not cleared after Reset\n", 2035 __func__); 2036 return (-1); 2037 } 2038 return (0); 2039 } 2040 2041 static int 2042 qls_hw_reset(qla_host_t *ha) 2043 { 2044 device_t dev = ha->pci_dev; 2045 int ret; 2046 int count; 2047 uint32_t data; 2048 2049 QL_DPRINT2((ha->pci_dev, "%s:enter[%d]\n", __func__, ha->hw_init)); 2050 2051 if (ha->hw_init == 0) { 2052 ret = qls_hw_nic_reset(ha); 2053 goto qls_hw_reset_exit; 2054 } 2055 2056 ret = qls_clear_routing_table(ha); 2057 if (ret) 2058 goto qls_hw_reset_exit; 2059 2060 ret = qls_mbx_set_mgmt_ctrl(ha, Q81_MBX_SET_MGMT_CTL_STOP); 2061 if (ret) 2062 goto qls_hw_reset_exit; 2063 2064 /* 2065 * Wait for FIFO to empty 2066 */ 2067 count = 5; 2068 while (count--) { 2069 data = READ_REG32(ha, Q81_CTL_STATUS); 2070 if (data & Q81_CTL_STATUS_NFE) 2071 break; 2072 qls_mdelay(__func__, 100); 2073 } 2074 if (count == 0) { 2075 device_printf(dev, "%s: NFE bit not set\n", __func__); 2076 goto qls_hw_reset_exit; 2077 } 2078 2079 count = 5; 2080 while (count--) { 2081 (void)qls_mbx_get_mgmt_ctrl(ha, &data); 2082 2083 if ((data & Q81_MBX_GET_MGMT_CTL_FIFO_EMPTY) && 2084 (data & Q81_MBX_GET_MGMT_CTL_SET_MGMT)) 2085 break; 2086 qls_mdelay(__func__, 100); 2087 } 2088 if (count == 0) 2089 goto qls_hw_reset_exit; 2090 2091 /* 2092 * Reset the NIC function 2093 */ 2094 ret = qls_hw_nic_reset(ha); 2095 if (ret) 2096 goto qls_hw_reset_exit; 2097 2098 ret = qls_mbx_set_mgmt_ctrl(ha, Q81_MBX_SET_MGMT_CTL_RESUME); 2099 2100 qls_hw_reset_exit: 2101 if (ret) 2102 device_printf(dev, "%s: failed\n", __func__); 2103 2104 return (ret); 2105 } 2106 2107 /* 2108 * MPI Related Functions 2109 */ 2110 int 2111 qls_mpi_risc_rd_reg(qla_host_t *ha, uint32_t reg, uint32_t *data) 2112 { 2113 int ret; 2114 2115 ret = qls_proc_addr_rd_reg(ha, Q81_CTL_PROC_ADDR_MPI_RISC, 2116 reg, data); 2117 return (ret); 2118 } 2119 2120 int 2121 qls_mpi_risc_wr_reg(qla_host_t *ha, uint32_t reg, uint32_t data) 2122 { 2123 int ret; 2124 2125 ret = qls_proc_addr_wr_reg(ha, Q81_CTL_PROC_ADDR_MPI_RISC, 2126 reg, data); 2127 return (ret); 2128 } 2129 2130 int 2131 qls_mbx_rd_reg(qla_host_t *ha, uint32_t reg, uint32_t *data) 2132 { 2133 int ret; 2134 2135 if ((ha->pci_func & 0x1) == 0) 2136 reg += Q81_FUNC0_MBX_OUT_REG0; 2137 else 2138 reg += Q81_FUNC1_MBX_OUT_REG0; 2139 2140 ret = qls_mpi_risc_rd_reg(ha, reg, data); 2141 2142 return (ret); 2143 } 2144 2145 int 2146 qls_mbx_wr_reg(qla_host_t *ha, uint32_t reg, uint32_t data) 2147 { 2148 int ret; 2149 2150 if ((ha->pci_func & 0x1) == 0) 2151 reg += Q81_FUNC0_MBX_IN_REG0; 2152 else 2153 reg += Q81_FUNC1_MBX_IN_REG0; 2154 2155 ret = qls_mpi_risc_wr_reg(ha, reg, data); 2156 2157 return (ret); 2158 } 2159 2160 2161 static int 2162 qls_mbx_cmd(qla_host_t *ha, uint32_t *in_mbx, uint32_t i_count, 2163 uint32_t *out_mbx, uint32_t o_count) 2164 { 2165 int i, ret = -1; 2166 uint32_t data32, mbx_cmd = 0; 2167 uint32_t count = 50; 2168 2169 QL_DPRINT2((ha->pci_dev, "%s: enter[0x%08x 0x%08x 0x%08x]\n", 2170 __func__, *in_mbx, *(in_mbx + 1), *(in_mbx + 2))); 2171 2172 data32 = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS); 2173 2174 if (data32 & Q81_CTL_HCS_HTR_INTR) { 2175 device_printf(ha->pci_dev, "%s: cmd_status[0x%08x]\n", 2176 __func__, data32); 2177 goto qls_mbx_cmd_exit; 2178 } 2179 2180 if (qls_sem_lock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV, 2181 Q81_CTL_SEM_SET_PROC_ADDR_NIC_RCV)) { 2182 device_printf(ha->pci_dev, "%s: semlock failed\n", __func__); 2183 goto qls_mbx_cmd_exit; 2184 } 2185 2186 ha->mbx_done = 0; 2187 2188 mbx_cmd = *in_mbx; 2189 2190 for (i = 0; i < i_count; i++) { 2191 2192 ret = qls_mbx_wr_reg(ha, i, *in_mbx); 2193 2194 if (ret) { 2195 device_printf(ha->pci_dev, 2196 "%s: mbx_wr[%d, 0x%08x] failed\n", __func__, 2197 i, *in_mbx); 2198 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV); 2199 goto qls_mbx_cmd_exit; 2200 } 2201 2202 in_mbx++; 2203 } 2204 WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS, Q81_CTL_HCS_CMD_SET_HTR_INTR); 2205 2206 qls_sem_unlock(ha, Q81_CTL_SEM_MASK_PROC_ADDR_NIC_RCV); 2207 2208 ret = -1; 2209 ha->mbx_done = 0; 2210 2211 while (count--) { 2212 2213 if (ha->flags.intr_enable == 0) { 2214 data32 = READ_REG32(ha, Q81_CTL_STATUS); 2215 2216 if (!(data32 & Q81_CTL_STATUS_PI)) { 2217 qls_mdelay(__func__, 100); 2218 continue; 2219 } 2220 2221 ret = qls_mbx_rd_reg(ha, 0, &data32); 2222 2223 if (ret == 0 ) { 2224 if ((data32 & 0xF000) == 0x4000) { 2225 2226 out_mbx[0] = data32; 2227 2228 for (i = 1; i < o_count; i++) { 2229 ret = qls_mbx_rd_reg(ha, i, 2230 &data32); 2231 if (ret) { 2232 device_printf( 2233 ha->pci_dev, 2234 "%s: mbx_rd[%d]" 2235 " failed\n", 2236 __func__, i); 2237 break; 2238 } 2239 out_mbx[i] = data32; 2240 } 2241 break; 2242 } else if ((data32 & 0xF000) == 0x8000) { 2243 count = 50; 2244 WRITE_REG32(ha,\ 2245 Q81_CTL_HOST_CMD_STATUS,\ 2246 Q81_CTL_HCS_CMD_CLR_RTH_INTR); 2247 } 2248 } 2249 } else { 2250 if (ha->mbx_done) { 2251 for (i = 1; i < o_count; i++) { 2252 out_mbx[i] = ha->mbox[i]; 2253 } 2254 ret = 0; 2255 break; 2256 } 2257 } 2258 qls_mdelay(__func__, 1000); 2259 } 2260 2261 qls_mbx_cmd_exit: 2262 2263 if (ha->flags.intr_enable == 0) { 2264 WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\ 2265 Q81_CTL_HCS_CMD_CLR_RTH_INTR); 2266 } 2267 2268 if (ret) { 2269 ha->qla_initiate_recovery = 1; 2270 } 2271 2272 QL_DPRINT2((ha->pci_dev, "%s: exit[%d]\n", __func__, ret)); 2273 return (ret); 2274 } 2275 2276 static int 2277 qls_mbx_set_mgmt_ctrl(qla_host_t *ha, uint32_t t_ctrl) 2278 { 2279 uint32_t *mbox; 2280 device_t dev = ha->pci_dev; 2281 2282 mbox = ha->mbox; 2283 bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS)); 2284 2285 mbox[0] = Q81_MBX_SET_MGMT_CTL; 2286 mbox[1] = t_ctrl; 2287 2288 if (qls_mbx_cmd(ha, mbox, 2, mbox, 1)) { 2289 device_printf(dev, "%s failed\n", __func__); 2290 return (-1); 2291 } 2292 2293 if ((mbox[0] == Q81_MBX_CMD_COMPLETE) || 2294 ((t_ctrl == Q81_MBX_SET_MGMT_CTL_STOP) && 2295 (mbox[0] == Q81_MBX_CMD_ERROR))){ 2296 return (0); 2297 } 2298 device_printf(dev, "%s failed [0x%08x]\n", __func__, mbox[0]); 2299 return (-1); 2300 2301 } 2302 2303 static int 2304 qls_mbx_get_mgmt_ctrl(qla_host_t *ha, uint32_t *t_status) 2305 { 2306 uint32_t *mbox; 2307 device_t dev = ha->pci_dev; 2308 2309 *t_status = 0; 2310 2311 mbox = ha->mbox; 2312 bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS)); 2313 2314 mbox[0] = Q81_MBX_GET_MGMT_CTL; 2315 2316 if (qls_mbx_cmd(ha, mbox, 1, mbox, 2)) { 2317 device_printf(dev, "%s failed\n", __func__); 2318 return (-1); 2319 } 2320 2321 *t_status = mbox[1]; 2322 2323 return (0); 2324 } 2325 2326 static void 2327 qls_mbx_get_link_status(qla_host_t *ha) 2328 { 2329 uint32_t *mbox; 2330 device_t dev = ha->pci_dev; 2331 2332 mbox = ha->mbox; 2333 bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS)); 2334 2335 mbox[0] = Q81_MBX_GET_LNK_STATUS; 2336 2337 if (qls_mbx_cmd(ha, mbox, 1, mbox, 6)) { 2338 device_printf(dev, "%s failed\n", __func__); 2339 return; 2340 } 2341 2342 ha->link_status = mbox[1]; 2343 ha->link_down_info = mbox[2]; 2344 ha->link_hw_info = mbox[3]; 2345 ha->link_dcbx_counters = mbox[4]; 2346 ha->link_change_counters = mbox[5]; 2347 2348 device_printf(dev, "%s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 2349 __func__, mbox[0],mbox[1],mbox[2],mbox[3],mbox[4],mbox[5]); 2350 2351 return; 2352 } 2353 2354 static void 2355 qls_mbx_about_fw(qla_host_t *ha) 2356 { 2357 uint32_t *mbox; 2358 device_t dev = ha->pci_dev; 2359 2360 mbox = ha->mbox; 2361 bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS)); 2362 2363 mbox[0] = Q81_MBX_ABOUT_FW; 2364 2365 if (qls_mbx_cmd(ha, mbox, 1, mbox, 6)) { 2366 device_printf(dev, "%s failed\n", __func__); 2367 return; 2368 } 2369 2370 device_printf(dev, "%s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 2371 __func__, mbox[0],mbox[1],mbox[2],mbox[3],mbox[4],mbox[5]); 2372 } 2373 2374 int 2375 qls_mbx_dump_risc_ram(qla_host_t *ha, void *buf, uint32_t r_addr, 2376 uint32_t r_size) 2377 { 2378 bus_addr_t b_paddr; 2379 uint32_t *mbox; 2380 device_t dev = ha->pci_dev; 2381 2382 mbox = ha->mbox; 2383 bzero(mbox, (sizeof (uint32_t) * Q81_NUM_MBX_REGISTERS)); 2384 2385 bzero(ha->mpi_dma.dma_b,(r_size << 2)); 2386 b_paddr = ha->mpi_dma.dma_addr; 2387 2388 mbox[0] = Q81_MBX_DUMP_RISC_RAM; 2389 mbox[1] = r_addr & 0xFFFF; 2390 mbox[2] = ((uint32_t)(b_paddr >> 16)) & 0xFFFF; 2391 mbox[3] = ((uint32_t)b_paddr) & 0xFFFF; 2392 mbox[4] = (r_size >> 16) & 0xFFFF; 2393 mbox[5] = r_size & 0xFFFF; 2394 mbox[6] = ((uint32_t)(b_paddr >> 48)) & 0xFFFF; 2395 mbox[7] = ((uint32_t)(b_paddr >> 32)) & 0xFFFF; 2396 mbox[8] = (r_addr >> 16) & 0xFFFF; 2397 2398 bus_dmamap_sync(ha->mpi_dma.dma_tag, ha->mpi_dma.dma_map, 2399 BUS_DMASYNC_PREREAD); 2400 2401 if (qls_mbx_cmd(ha, mbox, 9, mbox, 1)) { 2402 device_printf(dev, "%s failed\n", __func__); 2403 return (-1); 2404 } 2405 if (mbox[0] != 0x4000) { 2406 device_printf(ha->pci_dev, "%s: failed!\n", __func__); 2407 return (-1); 2408 } else { 2409 bus_dmamap_sync(ha->mpi_dma.dma_tag, ha->mpi_dma.dma_map, 2410 BUS_DMASYNC_POSTREAD); 2411 bcopy(ha->mpi_dma.dma_b, buf, (r_size << 2)); 2412 } 2413 2414 return (0); 2415 } 2416 2417 int 2418 qls_mpi_reset(qla_host_t *ha) 2419 { 2420 int count; 2421 uint32_t data; 2422 device_t dev = ha->pci_dev; 2423 2424 WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\ 2425 Q81_CTL_HCS_CMD_SET_RISC_RESET); 2426 2427 count = 10; 2428 while (count--) { 2429 data = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS); 2430 if (data & Q81_CTL_HCS_RISC_RESET) { 2431 WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS,\ 2432 Q81_CTL_HCS_CMD_CLR_RISC_RESET); 2433 break; 2434 } 2435 qls_mdelay(__func__, 10); 2436 } 2437 if (count == 0) { 2438 device_printf(dev, "%s: failed\n", __func__); 2439 return (-1); 2440 } 2441 return (0); 2442 } 2443 2444