1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (C) 2013 Emulex 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 are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 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 * 3. Neither the name of the Emulex Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived from 19 * this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * Contact Information: 34 * freebsd-drivers@emulex.com 35 * 36 * Emulex 37 * 3333 Susan Street 38 * Costa Mesa, CA 92626 39 */ 40 41 /* $FreeBSD$ */ 42 43 44 #include "oce_if.h" 45 46 static int oce_POST(POCE_SOFTC sc); 47 48 /** 49 * @brief Function to post status 50 * @param sc software handle to the device 51 */ 52 static int 53 oce_POST(POCE_SOFTC sc) 54 { 55 mpu_ep_semaphore_t post_status; 56 int tmo = 60000; 57 58 /* read semaphore CSR */ 59 post_status.dw0 = OCE_READ_CSR_MPU(sc, csr, MPU_EP_SEMAPHORE(sc)); 60 61 /* if host is ready then wait for fw ready else send POST */ 62 if (post_status.bits.stage <= POST_STAGE_AWAITING_HOST_RDY) { 63 post_status.bits.stage = POST_STAGE_CHIP_RESET; 64 OCE_WRITE_CSR_MPU(sc, csr, MPU_EP_SEMAPHORE(sc), post_status.dw0); 65 } 66 67 /* wait for FW ready */ 68 for (;;) { 69 if (--tmo == 0) 70 break; 71 72 DELAY(1000); 73 74 post_status.dw0 = OCE_READ_CSR_MPU(sc, csr, MPU_EP_SEMAPHORE(sc)); 75 if (post_status.bits.error) { 76 device_printf(sc->dev, 77 "POST failed: %x\n", post_status.dw0); 78 return ENXIO; 79 } 80 if (post_status.bits.stage == POST_STAGE_ARMFW_READY) 81 return 0; 82 } 83 84 device_printf(sc->dev, "POST timed out: %x\n", post_status.dw0); 85 86 return ENXIO; 87 } 88 89 /** 90 * @brief Function for hardware initialization 91 * @param sc software handle to the device 92 */ 93 int 94 oce_hw_init(POCE_SOFTC sc) 95 { 96 int rc = 0; 97 98 rc = oce_POST(sc); 99 if (rc) 100 return rc; 101 102 /* create the bootstrap mailbox */ 103 rc = oce_dma_alloc(sc, sizeof(struct oce_bmbx), &sc->bsmbx, 0); 104 if (rc) { 105 device_printf(sc->dev, "Mailbox alloc failed\n"); 106 return rc; 107 } 108 109 rc = oce_reset_fun(sc); 110 if (rc) 111 goto error; 112 113 114 rc = oce_mbox_init(sc); 115 if (rc) 116 goto error; 117 118 119 rc = oce_get_fw_version(sc); 120 if (rc) 121 goto error; 122 123 124 rc = oce_get_fw_config(sc); 125 if (rc) 126 goto error; 127 128 129 sc->macaddr.size_of_struct = 6; 130 rc = oce_read_mac_addr(sc, 0, 1, MAC_ADDRESS_TYPE_NETWORK, 131 &sc->macaddr); 132 if (rc) 133 goto error; 134 135 if ((IS_BE(sc) && (sc->flags & OCE_FLAGS_BE3)) || IS_SH(sc)) { 136 rc = oce_mbox_check_native_mode(sc); 137 if (rc) 138 goto error; 139 } else 140 sc->be3_native = 0; 141 142 return rc; 143 144 error: 145 oce_dma_free(sc, &sc->bsmbx); 146 device_printf(sc->dev, "Hardware initialisation failed\n"); 147 return rc; 148 } 149 150 151 152 /** 153 * @brief Releases the obtained pci resources 154 * @param sc software handle to the device 155 */ 156 void 157 oce_hw_pci_free(POCE_SOFTC sc) 158 { 159 int pci_cfg_barnum = 0; 160 161 if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2)) 162 pci_cfg_barnum = OCE_DEV_BE2_CFG_BAR; 163 else 164 pci_cfg_barnum = OCE_DEV_CFG_BAR; 165 166 if (sc->devcfg_res != NULL) { 167 bus_release_resource(sc->dev, 168 SYS_RES_MEMORY, 169 PCIR_BAR(pci_cfg_barnum), sc->devcfg_res); 170 sc->devcfg_res = (struct resource *)NULL; 171 sc->devcfg_btag = (bus_space_tag_t) 0; 172 sc->devcfg_bhandle = (bus_space_handle_t)0; 173 sc->devcfg_vhandle = (void *)NULL; 174 } 175 176 if (sc->csr_res != NULL) { 177 bus_release_resource(sc->dev, 178 SYS_RES_MEMORY, 179 PCIR_BAR(OCE_PCI_CSR_BAR), sc->csr_res); 180 sc->csr_res = (struct resource *)NULL; 181 sc->csr_btag = (bus_space_tag_t)0; 182 sc->csr_bhandle = (bus_space_handle_t)0; 183 sc->csr_vhandle = (void *)NULL; 184 } 185 186 if (sc->db_res != NULL) { 187 bus_release_resource(sc->dev, 188 SYS_RES_MEMORY, 189 PCIR_BAR(OCE_PCI_DB_BAR), sc->db_res); 190 sc->db_res = (struct resource *)NULL; 191 sc->db_btag = (bus_space_tag_t)0; 192 sc->db_bhandle = (bus_space_handle_t)0; 193 sc->db_vhandle = (void *)NULL; 194 } 195 } 196 197 198 199 200 /** 201 * @brief Function to get the PCI capabilities 202 * @param sc software handle to the device 203 */ 204 static 205 void oce_get_pci_capabilities(POCE_SOFTC sc) 206 { 207 uint32_t val; 208 209 if (pci_find_cap(sc->dev, PCIY_PCIX, &val) == 0) { 210 if (val != 0) 211 sc->flags |= OCE_FLAGS_PCIX; 212 } 213 214 if (pci_find_cap(sc->dev, PCIY_EXPRESS, &val) == 0) { 215 if (val != 0) { 216 uint16_t link_status = 217 pci_read_config(sc->dev, val + 0x12, 2); 218 219 sc->flags |= OCE_FLAGS_PCIE; 220 sc->pcie_link_speed = link_status & 0xf; 221 sc->pcie_link_width = (link_status >> 4) & 0x3f; 222 } 223 } 224 225 if (pci_find_cap(sc->dev, PCIY_MSI, &val) == 0) { 226 if (val != 0) 227 sc->flags |= OCE_FLAGS_MSI_CAPABLE; 228 } 229 230 if (pci_find_cap(sc->dev, PCIY_MSIX, &val) == 0) { 231 if (val != 0) { 232 val = pci_msix_count(sc->dev); 233 sc->flags |= OCE_FLAGS_MSIX_CAPABLE; 234 } 235 } 236 } 237 238 /** 239 * @brief Allocate PCI resources. 240 * 241 * @param sc software handle to the device 242 * @returns 0 if successful, or error 243 */ 244 int 245 oce_hw_pci_alloc(POCE_SOFTC sc) 246 { 247 int rr, pci_cfg_barnum = 0; 248 pci_sli_intf_t intf; 249 250 pci_enable_busmaster(sc->dev); 251 252 oce_get_pci_capabilities(sc); 253 254 sc->fn = pci_get_function(sc->dev); 255 256 /* setup the device config region */ 257 if (IS_BE(sc) && (sc->flags & OCE_FLAGS_BE2)) 258 pci_cfg_barnum = OCE_DEV_BE2_CFG_BAR; 259 else 260 pci_cfg_barnum = OCE_DEV_CFG_BAR; 261 262 rr = PCIR_BAR(pci_cfg_barnum); 263 264 if (IS_BE(sc) || IS_SH(sc)) 265 sc->devcfg_res = bus_alloc_resource_any(sc->dev, 266 SYS_RES_MEMORY, &rr, 267 RF_ACTIVE|RF_SHAREABLE); 268 else 269 sc->devcfg_res = bus_alloc_resource_anywhere(sc->dev, 270 SYS_RES_MEMORY, &rr, 32768, 271 RF_ACTIVE|RF_SHAREABLE); 272 273 if (!sc->devcfg_res) 274 goto error; 275 276 sc->devcfg_btag = rman_get_bustag(sc->devcfg_res); 277 sc->devcfg_bhandle = rman_get_bushandle(sc->devcfg_res); 278 sc->devcfg_vhandle = rman_get_virtual(sc->devcfg_res); 279 280 /* Read the SLI_INTF register and determine whether we 281 * can use this port and its features 282 */ 283 intf.dw0 = pci_read_config((sc)->dev,OCE_INTF_REG_OFFSET,4); 284 285 if (intf.bits.sli_valid != OCE_INTF_VALID_SIG) 286 goto error; 287 288 if (intf.bits.sli_rev != OCE_INTF_SLI_REV4) { 289 device_printf(sc->dev, "Adapter doesnt support SLI4\n"); 290 goto error; 291 } 292 293 if (intf.bits.sli_if_type == OCE_INTF_IF_TYPE_1) 294 sc->flags |= OCE_FLAGS_MBOX_ENDIAN_RQD; 295 296 if (intf.bits.sli_hint1 == OCE_INTF_FUNC_RESET_REQD) 297 sc->flags |= OCE_FLAGS_FUNCRESET_RQD; 298 299 if (intf.bits.sli_func_type == OCE_INTF_VIRT_FUNC) 300 sc->flags |= OCE_FLAGS_VIRTUAL_PORT; 301 302 /* Lancer has one BAR (CFG) but BE3 has three (CFG, CSR, DB) */ 303 if (IS_BE(sc) || IS_SH(sc)) { 304 /* set up CSR region */ 305 rr = PCIR_BAR(OCE_PCI_CSR_BAR); 306 sc->csr_res = bus_alloc_resource_any(sc->dev, 307 SYS_RES_MEMORY, &rr, RF_ACTIVE|RF_SHAREABLE); 308 if (!sc->csr_res) 309 goto error; 310 sc->csr_btag = rman_get_bustag(sc->csr_res); 311 sc->csr_bhandle = rman_get_bushandle(sc->csr_res); 312 sc->csr_vhandle = rman_get_virtual(sc->csr_res); 313 314 /* set up DB doorbell region */ 315 rr = PCIR_BAR(OCE_PCI_DB_BAR); 316 sc->db_res = bus_alloc_resource_any(sc->dev, 317 SYS_RES_MEMORY, &rr, RF_ACTIVE|RF_SHAREABLE); 318 if (!sc->db_res) 319 goto error; 320 sc->db_btag = rman_get_bustag(sc->db_res); 321 sc->db_bhandle = rman_get_bushandle(sc->db_res); 322 sc->db_vhandle = rman_get_virtual(sc->db_res); 323 } 324 325 return 0; 326 327 error: 328 oce_hw_pci_free(sc); 329 return ENXIO; 330 } 331 332 333 /** 334 * @brief Function for device shutdown 335 * @param sc software handle to the device 336 * @returns 0 on success, error otherwise 337 */ 338 void 339 oce_hw_shutdown(POCE_SOFTC sc) 340 { 341 342 oce_stats_free(sc); 343 /* disable hardware interrupts */ 344 oce_hw_intr_disable(sc); 345 #if defined(INET6) || defined(INET) 346 /* Free LRO resources */ 347 oce_free_lro(sc); 348 #endif 349 /* Release queue*/ 350 oce_queue_release_all(sc); 351 /*Delete Network Interface*/ 352 oce_delete_nw_interface(sc); 353 /* After fw clean we dont send any cmds to fw.*/ 354 oce_fw_clean(sc); 355 /* release intr resources */ 356 oce_intr_free(sc); 357 /* release PCI resources */ 358 oce_hw_pci_free(sc); 359 /* free mbox specific resources */ 360 LOCK_DESTROY(&sc->bmbx_lock); 361 LOCK_DESTROY(&sc->dev_lock); 362 363 oce_dma_free(sc, &sc->bsmbx); 364 } 365 366 367 /** 368 * @brief Function for creating nw interface. 369 * @param sc software handle to the device 370 * @returns 0 on success, error otherwise 371 */ 372 int 373 oce_create_nw_interface(POCE_SOFTC sc) 374 { 375 int rc; 376 uint32_t capab_flags; 377 uint32_t capab_en_flags; 378 379 /* interface capabilities to give device when creating interface */ 380 capab_flags = OCE_CAPAB_FLAGS; 381 382 /* capabilities to enable by default (others set dynamically) */ 383 capab_en_flags = OCE_CAPAB_ENABLE; 384 385 if (IS_XE201(sc)) { 386 /* LANCER A0 workaround */ 387 capab_en_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR; 388 capab_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR; 389 } 390 391 if (IS_SH(sc) || IS_XE201(sc)) 392 capab_flags |= MBX_RX_IFACE_FLAGS_MULTICAST; 393 394 if (sc->enable_hwlro) { 395 capab_flags |= MBX_RX_IFACE_FLAGS_LRO; 396 capab_en_flags |= MBX_RX_IFACE_FLAGS_LRO; 397 } 398 399 /* enable capabilities controlled via driver startup parameters */ 400 if (is_rss_enabled(sc)) 401 capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS; 402 else { 403 capab_en_flags &= ~MBX_RX_IFACE_FLAGS_RSS; 404 capab_flags &= ~MBX_RX_IFACE_FLAGS_RSS; 405 } 406 407 rc = oce_if_create(sc, 408 capab_flags, 409 capab_en_flags, 410 0, &sc->macaddr.mac_addr[0], &sc->if_id); 411 if (rc) 412 return rc; 413 414 atomic_inc_32(&sc->nifs); 415 416 sc->if_cap_flags = capab_en_flags; 417 418 /* set default flow control */ 419 rc = oce_set_flow_control(sc, sc->flow_control); 420 if (rc) 421 goto error; 422 423 rc = oce_rxf_set_promiscuous(sc, sc->promisc); 424 if (rc) 425 goto error; 426 427 return rc; 428 429 error: 430 oce_delete_nw_interface(sc); 431 return rc; 432 433 } 434 435 /** 436 * @brief Function to delete a nw interface. 437 * @param sc software handle to the device 438 */ 439 void 440 oce_delete_nw_interface(POCE_SOFTC sc) 441 { 442 /* currently only single interface is implmeneted */ 443 if (sc->nifs > 0) { 444 oce_if_del(sc, sc->if_id); 445 atomic_dec_32(&sc->nifs); 446 } 447 } 448 449 /** 450 * @brief Soft reset. 451 * @param sc software handle to the device 452 * @returns 0 on success, error otherwise 453 */ 454 int 455 oce_pci_soft_reset(POCE_SOFTC sc) 456 { 457 int rc; 458 mpu_ep_control_t ctrl; 459 460 ctrl.dw0 = OCE_READ_CSR_MPU(sc, csr, MPU_EP_CONTROL); 461 ctrl.bits.cpu_reset = 1; 462 OCE_WRITE_CSR_MPU(sc, csr, MPU_EP_CONTROL, ctrl.dw0); 463 DELAY(50); 464 rc=oce_POST(sc); 465 466 return rc; 467 } 468 469 /** 470 * @brief Function for hardware start 471 * @param sc software handle to the device 472 * @returns 0 on success, error otherwise 473 */ 474 int 475 oce_hw_start(POCE_SOFTC sc) 476 { 477 struct link_status link = { 0 }; 478 int rc = 0; 479 480 rc = oce_get_link_status(sc, &link); 481 if (rc) 482 return 1; 483 484 if (link.logical_link_status == NTWK_LOGICAL_LINK_UP) { 485 sc->link_status = NTWK_LOGICAL_LINK_UP; 486 if_link_state_change(sc->ifp, LINK_STATE_UP); 487 } else { 488 sc->link_status = NTWK_LOGICAL_LINK_DOWN; 489 if_link_state_change(sc->ifp, LINK_STATE_DOWN); 490 } 491 492 sc->link_speed = link.phys_port_speed; 493 sc->qos_link_speed = (uint32_t )link.qos_link_speed * 10; 494 495 rc = oce_start_mq(sc->mq); 496 497 /* we need to get MCC aync events. So enable intrs and arm 498 first EQ, Other EQs will be armed after interface is UP 499 */ 500 oce_hw_intr_enable(sc); 501 oce_arm_eq(sc, sc->eq[0]->eq_id, 0, TRUE, FALSE); 502 503 /* Send first mcc cmd and after that we get gracious 504 MCC notifications from FW 505 */ 506 oce_first_mcc_cmd(sc); 507 508 return rc; 509 } 510 511 512 /** 513 * @brief Function for hardware enable interupts. 514 * @param sc software handle to the device 515 */ 516 void 517 oce_hw_intr_enable(POCE_SOFTC sc) 518 { 519 uint32_t reg; 520 521 reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL); 522 reg |= HOSTINTR_MASK; 523 OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg); 524 525 } 526 527 528 /** 529 * @brief Function for hardware disable interupts 530 * @param sc software handle to the device 531 */ 532 void 533 oce_hw_intr_disable(POCE_SOFTC sc) 534 { 535 uint32_t reg; 536 537 reg = OCE_READ_REG32(sc, devcfg, PCICFG_INTR_CTRL); 538 reg &= ~HOSTINTR_MASK; 539 OCE_WRITE_REG32(sc, devcfg, PCICFG_INTR_CTRL, reg); 540 } 541 542 543 static u_int 544 oce_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) 545 { 546 struct mbx_set_common_iface_multicast *req = arg; 547 548 if (req->params.req.num_mac == OCE_MAX_MC_FILTER_SIZE) 549 return (0); 550 551 bcopy(LLADDR(sdl), &req->params.req.mac[req->params.req.num_mac++], 552 ETHER_ADDR_LEN); 553 554 return (1); 555 } 556 557 558 /** 559 * @brief Function for hardware update multicast filter 560 * @param sc software handle to the device 561 */ 562 int 563 oce_hw_update_multicast(POCE_SOFTC sc) 564 { 565 struct ifnet *ifp = sc->ifp; 566 struct mbx_set_common_iface_multicast *req = NULL; 567 OCE_DMA_MEM dma; 568 int rc = 0; 569 570 /* Allocate DMA mem*/ 571 if (oce_dma_alloc(sc, sizeof(struct mbx_set_common_iface_multicast), 572 &dma, 0)) 573 return ENOMEM; 574 575 req = OCE_DMAPTR(&dma, struct mbx_set_common_iface_multicast); 576 bzero(req, sizeof(struct mbx_set_common_iface_multicast)); 577 578 if_foreach_llmaddr(ifp, oce_copy_maddr, req); 579 if (req->params.req.num_mac == OCE_MAX_MC_FILTER_SIZE) { 580 /*More multicast addresses than our hardware table 581 So Enable multicast promiscus in our hardware to 582 accept all multicat packets 583 */ 584 req->params.req.promiscuous = 1; 585 } 586 587 req->params.req.if_id = sc->if_id; 588 rc = oce_update_multicast(sc, &dma); 589 oce_dma_free(sc, &dma); 590 return rc; 591 } 592 593