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