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