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