1 /* 2 * Copyright (c) 2017-2018 Cavium, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * File: qlnx_os.c 30 * Author : David C Somayajulu, Cavium, Inc., San Jose, CA 95131. 31 */ 32 33 #include <sys/cdefs.h> 34 #include "qlnx_os.h" 35 #include "bcm_osal.h" 36 #include "reg_addr.h" 37 #include "ecore_gtt_reg_addr.h" 38 #include "ecore.h" 39 #include "ecore_chain.h" 40 #include "ecore_status.h" 41 #include "ecore_hw.h" 42 #include "ecore_rt_defs.h" 43 #include "ecore_init_ops.h" 44 #include "ecore_int.h" 45 #include "ecore_cxt.h" 46 #include "ecore_spq.h" 47 #include "ecore_init_fw_funcs.h" 48 #include "ecore_sp_commands.h" 49 #include "ecore_dev_api.h" 50 #include "ecore_l2_api.h" 51 #include "ecore_mcp.h" 52 #include "ecore_hw_defs.h" 53 #include "mcp_public.h" 54 #include "ecore_iro.h" 55 #include "nvm_cfg.h" 56 #include "ecore_dbg_fw_funcs.h" 57 #include "ecore_iov_api.h" 58 #include "ecore_vf_api.h" 59 60 #include "qlnx_ioctl.h" 61 #include "qlnx_def.h" 62 #include "qlnx_ver.h" 63 64 #ifdef QLNX_ENABLE_IWARP 65 #include "qlnx_rdma.h" 66 #endif /* #ifdef QLNX_ENABLE_IWARP */ 67 68 #ifdef CONFIG_ECORE_SRIOV 69 #include <sys/nv.h> 70 #include <sys/iov_schema.h> 71 #include <dev/pci/pci_iov.h> 72 #endif /* #ifdef CONFIG_ECORE_SRIOV */ 73 74 #include <sys/smp.h> 75 76 /* 77 * static functions 78 */ 79 /* 80 * ioctl related functions 81 */ 82 static void qlnx_add_sysctls(qlnx_host_t *ha); 83 84 /* 85 * main driver 86 */ 87 static void qlnx_release(qlnx_host_t *ha); 88 static void qlnx_fp_isr(void *arg); 89 static void qlnx_init_ifnet(device_t dev, qlnx_host_t *ha); 90 static void qlnx_init(void *arg); 91 static void qlnx_init_locked(qlnx_host_t *ha); 92 static int qlnx_set_multi(qlnx_host_t *ha, uint32_t add_multi); 93 static int qlnx_set_promisc(qlnx_host_t *ha, int enabled); 94 static int qlnx_set_allmulti(qlnx_host_t *ha, int enabled); 95 static int qlnx_ioctl(if_t ifp, u_long cmd, caddr_t data); 96 static int qlnx_media_change(if_t ifp); 97 static void qlnx_media_status(if_t ifp, struct ifmediareq *ifmr); 98 static void qlnx_stop(qlnx_host_t *ha); 99 static int qlnx_send(qlnx_host_t *ha, struct qlnx_fastpath *fp, 100 struct mbuf **m_headp); 101 static int qlnx_get_ifq_snd_maxlen(qlnx_host_t *ha); 102 static uint32_t qlnx_get_optics(qlnx_host_t *ha, 103 struct qlnx_link_output *if_link); 104 static int qlnx_transmit(if_t ifp, struct mbuf *mp); 105 static int qlnx_transmit_locked(if_t ifp, struct qlnx_fastpath *fp, 106 struct mbuf *mp); 107 static void qlnx_qflush(if_t ifp); 108 109 static int qlnx_alloc_parent_dma_tag(qlnx_host_t *ha); 110 static void qlnx_free_parent_dma_tag(qlnx_host_t *ha); 111 static int qlnx_alloc_tx_dma_tag(qlnx_host_t *ha); 112 static void qlnx_free_tx_dma_tag(qlnx_host_t *ha); 113 static int qlnx_alloc_rx_dma_tag(qlnx_host_t *ha); 114 static void qlnx_free_rx_dma_tag(qlnx_host_t *ha); 115 116 static int qlnx_get_mfw_version(qlnx_host_t *ha, uint32_t *mfw_ver); 117 static int qlnx_get_flash_size(qlnx_host_t *ha, uint32_t *flash_size); 118 119 static int qlnx_nic_setup(struct ecore_dev *cdev, 120 struct ecore_pf_params *func_params); 121 static int qlnx_nic_start(struct ecore_dev *cdev); 122 static int qlnx_slowpath_start(qlnx_host_t *ha); 123 static int qlnx_slowpath_stop(qlnx_host_t *ha); 124 static int qlnx_init_hw(qlnx_host_t *ha); 125 static void qlnx_set_id(struct ecore_dev *cdev, char name[NAME_SIZE], 126 char ver_str[VER_SIZE]); 127 static void qlnx_unload(qlnx_host_t *ha); 128 static int qlnx_load(qlnx_host_t *ha); 129 static void qlnx_hw_set_multi(qlnx_host_t *ha, uint8_t *mta, uint32_t mcnt, 130 uint32_t add_mac); 131 static void qlnx_dump_buf8(qlnx_host_t *ha, const char *msg, void *dbuf, 132 uint32_t len); 133 static int qlnx_alloc_rx_buffer(qlnx_host_t *ha, struct qlnx_rx_queue *rxq); 134 static void qlnx_reuse_rx_data(struct qlnx_rx_queue *rxq); 135 static void qlnx_update_rx_prod(struct ecore_hwfn *p_hwfn, 136 struct qlnx_rx_queue *rxq); 137 static int qlnx_set_rx_accept_filter(qlnx_host_t *ha, uint8_t filter); 138 static int qlnx_grc_dumpsize(qlnx_host_t *ha, uint32_t *num_dwords, 139 int hwfn_index); 140 static int qlnx_idle_chk_size(qlnx_host_t *ha, uint32_t *num_dwords, 141 int hwfn_index); 142 static void qlnx_timer(void *arg); 143 static int qlnx_alloc_tx_br(qlnx_host_t *ha, struct qlnx_fastpath *fp); 144 static void qlnx_free_tx_br(qlnx_host_t *ha, struct qlnx_fastpath *fp); 145 static void qlnx_trigger_dump(qlnx_host_t *ha); 146 static uint16_t qlnx_num_tx_compl(qlnx_host_t *ha, struct qlnx_fastpath *fp, 147 struct qlnx_tx_queue *txq); 148 static void qlnx_tx_int(qlnx_host_t *ha, struct qlnx_fastpath *fp, 149 struct qlnx_tx_queue *txq); 150 static int qlnx_rx_int(qlnx_host_t *ha, struct qlnx_fastpath *fp, int budget, 151 int lro_enable); 152 static void qlnx_fp_taskqueue(void *context, int pending); 153 static void qlnx_sample_storm_stats(qlnx_host_t *ha); 154 static int qlnx_alloc_tpa_mbuf(qlnx_host_t *ha, uint16_t rx_buf_size, 155 struct qlnx_agg_info *tpa); 156 static void qlnx_free_tpa_mbuf(qlnx_host_t *ha, struct qlnx_agg_info *tpa); 157 158 static uint64_t qlnx_get_counter(if_t ifp, ift_counter cnt); 159 160 /* 161 * Hooks to the Operating Systems 162 */ 163 static int qlnx_pci_probe (device_t); 164 static int qlnx_pci_attach (device_t); 165 static int qlnx_pci_detach (device_t); 166 167 #ifndef QLNX_VF 168 169 #ifdef CONFIG_ECORE_SRIOV 170 171 static int qlnx_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *params); 172 static void qlnx_iov_uninit(device_t dev); 173 static int qlnx_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params); 174 static void qlnx_initialize_sriov(qlnx_host_t *ha); 175 static void qlnx_pf_taskqueue(void *context, int pending); 176 static int qlnx_create_pf_taskqueues(qlnx_host_t *ha); 177 static void qlnx_destroy_pf_taskqueues(qlnx_host_t *ha); 178 static void qlnx_inform_vf_link_state(struct ecore_hwfn *p_hwfn, qlnx_host_t *ha); 179 180 #endif /* #ifdef CONFIG_ECORE_SRIOV */ 181 182 static device_method_t qlnx_pci_methods[] = { 183 /* Device interface */ 184 DEVMETHOD(device_probe, qlnx_pci_probe), 185 DEVMETHOD(device_attach, qlnx_pci_attach), 186 DEVMETHOD(device_detach, qlnx_pci_detach), 187 188 #ifdef CONFIG_ECORE_SRIOV 189 DEVMETHOD(pci_iov_init, qlnx_iov_init), 190 DEVMETHOD(pci_iov_uninit, qlnx_iov_uninit), 191 DEVMETHOD(pci_iov_add_vf, qlnx_iov_add_vf), 192 #endif /* #ifdef CONFIG_ECORE_SRIOV */ 193 { 0, 0 } 194 }; 195 196 static driver_t qlnx_pci_driver = { 197 "ql", qlnx_pci_methods, sizeof (qlnx_host_t), 198 }; 199 200 MODULE_VERSION(if_qlnxe,1); 201 DRIVER_MODULE(if_qlnxe, pci, qlnx_pci_driver, 0, 0); 202 203 MODULE_DEPEND(if_qlnxe, pci, 1, 1, 1); 204 MODULE_DEPEND(if_qlnxe, ether, 1, 1, 1); 205 206 #else 207 208 static device_method_t qlnxv_pci_methods[] = { 209 /* Device interface */ 210 DEVMETHOD(device_probe, qlnx_pci_probe), 211 DEVMETHOD(device_attach, qlnx_pci_attach), 212 DEVMETHOD(device_detach, qlnx_pci_detach), 213 { 0, 0 } 214 }; 215 216 static driver_t qlnxv_pci_driver = { 217 "ql", qlnxv_pci_methods, sizeof (qlnx_host_t), 218 }; 219 220 MODULE_VERSION(if_qlnxev,1); 221 DRIVER_MODULE(if_qlnxev, pci, qlnxv_pci_driver, 0, 0); 222 223 MODULE_DEPEND(if_qlnxev, pci, 1, 1, 1); 224 MODULE_DEPEND(if_qlnxev, ether, 1, 1, 1); 225 226 #endif /* #ifdef QLNX_VF */ 227 228 MALLOC_DEFINE(M_QLNXBUF, "qlnxbuf", "Buffers for qlnx driver"); 229 230 char qlnx_ver_str[VER_SIZE]; 231 char qlnx_name_str[NAME_SIZE]; 232 233 /* 234 * Some PCI Configuration Space Related Defines 235 */ 236 237 #ifndef PCI_VENDOR_QLOGIC 238 #define PCI_VENDOR_QLOGIC 0x1077 239 #endif 240 241 /* 40G Adapter QLE45xxx*/ 242 #ifndef QLOGIC_PCI_DEVICE_ID_1634 243 #define QLOGIC_PCI_DEVICE_ID_1634 0x1634 244 #endif 245 246 /* 100G Adapter QLE45xxx*/ 247 #ifndef QLOGIC_PCI_DEVICE_ID_1644 248 #define QLOGIC_PCI_DEVICE_ID_1644 0x1644 249 #endif 250 251 /* 25G Adapter QLE45xxx*/ 252 #ifndef QLOGIC_PCI_DEVICE_ID_1656 253 #define QLOGIC_PCI_DEVICE_ID_1656 0x1656 254 #endif 255 256 /* 50G Adapter QLE45xxx*/ 257 #ifndef QLOGIC_PCI_DEVICE_ID_1654 258 #define QLOGIC_PCI_DEVICE_ID_1654 0x1654 259 #endif 260 261 /* 10G/25G/40G Adapter QLE41xxx*/ 262 #ifndef QLOGIC_PCI_DEVICE_ID_8070 263 #define QLOGIC_PCI_DEVICE_ID_8070 0x8070 264 #endif 265 266 /* SRIOV Device (All Speeds) Adapter QLE41xxx*/ 267 #ifndef QLOGIC_PCI_DEVICE_ID_8090 268 #define QLOGIC_PCI_DEVICE_ID_8090 0x8090 269 #endif 270 271 SYSCTL_NODE(_hw, OID_AUTO, qlnxe, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 272 "qlnxe driver parameters"); 273 274 /* Number of Queues: 0 (Auto) or 1 to 32 (fixed queue number) */ 275 static int qlnxe_queue_count = QLNX_DEFAULT_RSS; 276 277 SYSCTL_INT(_hw_qlnxe, OID_AUTO, queue_count, CTLFLAG_RDTUN, 278 &qlnxe_queue_count, 0, "Multi-Queue queue count"); 279 280 /* 281 * Note on RDMA personality setting 282 * 283 * Read the personality configured in NVRAM 284 * If the personality is ETH_ONLY, ETH_IWARP or ETH_ROCE and 285 * the configured personality in sysctl is QLNX_PERSONALITY_DEFAULT 286 * use the personality in NVRAM. 287 288 * Otherwise use t the personality configured in sysctl. 289 * 290 */ 291 #define QLNX_PERSONALITY_DEFAULT 0x0 /* use personality in NVRAM */ 292 #define QLNX_PERSONALITY_ETH_ONLY 0x1 /* Override with ETH_ONLY */ 293 #define QLNX_PERSONALITY_ETH_IWARP 0x2 /* Override with ETH_IWARP */ 294 #define QLNX_PERSONALITY_ETH_ROCE 0x3 /* Override with ETH_ROCE */ 295 #define QLNX_PERSONALITY_BITS_PER_FUNC 4 296 #define QLNX_PERSONALIY_MASK 0xF 297 298 /* RDMA configuration; 64bit field allows setting for 16 physical functions*/ 299 static uint64_t qlnxe_rdma_configuration = 0x22222222; 300 301 SYSCTL_U64(_hw_qlnxe, OID_AUTO, rdma_configuration, CTLFLAG_RDTUN, 302 &qlnxe_rdma_configuration, 0, "RDMA Configuration"); 303 304 int 305 qlnx_vf_device(qlnx_host_t *ha) 306 { 307 uint16_t device_id; 308 309 device_id = ha->device_id; 310 311 if (device_id == QLOGIC_PCI_DEVICE_ID_8090) 312 return 0; 313 314 return -1; 315 } 316 317 static int 318 qlnx_valid_device(qlnx_host_t *ha) 319 { 320 uint16_t device_id; 321 322 device_id = ha->device_id; 323 324 #ifndef QLNX_VF 325 if ((device_id == QLOGIC_PCI_DEVICE_ID_1634) || 326 (device_id == QLOGIC_PCI_DEVICE_ID_1644) || 327 (device_id == QLOGIC_PCI_DEVICE_ID_1656) || 328 (device_id == QLOGIC_PCI_DEVICE_ID_1654) || 329 (device_id == QLOGIC_PCI_DEVICE_ID_8070)) 330 return 0; 331 #else 332 if (device_id == QLOGIC_PCI_DEVICE_ID_8090) 333 return 0; 334 335 #endif /* #ifndef QLNX_VF */ 336 return -1; 337 } 338 339 #ifdef QLNX_ENABLE_IWARP 340 static int 341 qlnx_rdma_supported(struct qlnx_host *ha) 342 { 343 uint16_t device_id; 344 345 device_id = pci_get_device(ha->pci_dev); 346 347 if ((device_id == QLOGIC_PCI_DEVICE_ID_1634) || 348 (device_id == QLOGIC_PCI_DEVICE_ID_1656) || 349 (device_id == QLOGIC_PCI_DEVICE_ID_1654) || 350 (device_id == QLOGIC_PCI_DEVICE_ID_8070)) 351 return (0); 352 353 return (-1); 354 } 355 #endif /* #ifdef QLNX_ENABLE_IWARP */ 356 357 /* 358 * Name: qlnx_pci_probe 359 * Function: Validate the PCI device to be a QLA80XX device 360 */ 361 static int 362 qlnx_pci_probe(device_t dev) 363 { 364 snprintf(qlnx_ver_str, sizeof(qlnx_ver_str), "v%d.%d.%d", 365 QLNX_VERSION_MAJOR, QLNX_VERSION_MINOR, QLNX_VERSION_BUILD); 366 snprintf(qlnx_name_str, sizeof(qlnx_name_str), "qlnx"); 367 368 if (pci_get_vendor(dev) != PCI_VENDOR_QLOGIC) { 369 return (ENXIO); 370 } 371 372 switch (pci_get_device(dev)) { 373 #ifndef QLNX_VF 374 375 case QLOGIC_PCI_DEVICE_ID_1644: 376 device_set_descf(dev, "%s v%d.%d.%d", 377 "Qlogic 100GbE PCI CNA Adapter-Ethernet Function", 378 QLNX_VERSION_MAJOR, QLNX_VERSION_MINOR, 379 QLNX_VERSION_BUILD); 380 break; 381 382 case QLOGIC_PCI_DEVICE_ID_1634: 383 device_set_descf(dev, "%s v%d.%d.%d", 384 "Qlogic 40GbE PCI CNA Adapter-Ethernet Function", 385 QLNX_VERSION_MAJOR, QLNX_VERSION_MINOR, 386 QLNX_VERSION_BUILD); 387 break; 388 389 case QLOGIC_PCI_DEVICE_ID_1656: 390 device_set_descf(dev, "%s v%d.%d.%d", 391 "Qlogic 25GbE PCI CNA Adapter-Ethernet Function", 392 QLNX_VERSION_MAJOR, QLNX_VERSION_MINOR, 393 QLNX_VERSION_BUILD); 394 break; 395 396 case QLOGIC_PCI_DEVICE_ID_1654: 397 device_set_descf(dev, "%s v%d.%d.%d", 398 "Qlogic 50GbE PCI CNA Adapter-Ethernet Function", 399 QLNX_VERSION_MAJOR, QLNX_VERSION_MINOR, 400 QLNX_VERSION_BUILD); 401 break; 402 403 case QLOGIC_PCI_DEVICE_ID_8070: 404 device_set_descf(dev, "%s v%d.%d.%d", 405 "Qlogic 10GbE/25GbE/40GbE PCI CNA (AH)" 406 " Adapter-Ethernet Function", 407 QLNX_VERSION_MAJOR, QLNX_VERSION_MINOR, 408 QLNX_VERSION_BUILD); 409 break; 410 411 #else 412 case QLOGIC_PCI_DEVICE_ID_8090: 413 device_set_descf(dev, "%s v%d.%d.%d", 414 "Qlogic SRIOV PCI CNA (AH) " 415 "Adapter-Ethernet Function", 416 QLNX_VERSION_MAJOR, QLNX_VERSION_MINOR, 417 QLNX_VERSION_BUILD); 418 break; 419 420 #endif /* #ifndef QLNX_VF */ 421 422 default: 423 return (ENXIO); 424 } 425 426 #ifdef QLNX_ENABLE_IWARP 427 qlnx_rdma_init(); 428 #endif /* #ifdef QLNX_ENABLE_IWARP */ 429 430 return (BUS_PROBE_DEFAULT); 431 } 432 433 static uint16_t 434 qlnx_num_tx_compl(qlnx_host_t *ha, struct qlnx_fastpath *fp, 435 struct qlnx_tx_queue *txq) 436 { 437 u16 hw_bd_cons; 438 u16 ecore_cons_idx; 439 440 hw_bd_cons = le16toh(*txq->hw_cons_ptr); 441 442 ecore_cons_idx = ecore_chain_get_cons_idx(&txq->tx_pbl); 443 444 return (hw_bd_cons - ecore_cons_idx); 445 } 446 447 static void 448 qlnx_sp_intr(void *arg) 449 { 450 struct ecore_hwfn *p_hwfn; 451 qlnx_host_t *ha; 452 int i; 453 454 p_hwfn = arg; 455 456 if (p_hwfn == NULL) { 457 printf("%s: spurious slowpath intr\n", __func__); 458 return; 459 } 460 461 ha = (qlnx_host_t *)p_hwfn->p_dev; 462 463 QL_DPRINT2(ha, "enter\n"); 464 465 for (i = 0; i < ha->cdev.num_hwfns; i++) { 466 if (&ha->cdev.hwfns[i] == p_hwfn) { 467 taskqueue_enqueue(ha->sp_taskqueue[i], &ha->sp_task[i]); 468 break; 469 } 470 } 471 QL_DPRINT2(ha, "exit\n"); 472 473 return; 474 } 475 476 static void 477 qlnx_sp_taskqueue(void *context, int pending) 478 { 479 struct ecore_hwfn *p_hwfn; 480 481 p_hwfn = context; 482 483 if (p_hwfn != NULL) { 484 qlnx_sp_isr(p_hwfn); 485 } 486 return; 487 } 488 489 static int 490 qlnx_create_sp_taskqueues(qlnx_host_t *ha) 491 { 492 int i; 493 uint8_t tq_name[32]; 494 495 for (i = 0; i < ha->cdev.num_hwfns; i++) { 496 struct ecore_hwfn *p_hwfn = &ha->cdev.hwfns[i]; 497 498 bzero(tq_name, sizeof (tq_name)); 499 snprintf(tq_name, sizeof (tq_name), "ql_sp_tq_%d", i); 500 501 TASK_INIT(&ha->sp_task[i], 0, qlnx_sp_taskqueue, p_hwfn); 502 503 ha->sp_taskqueue[i] = taskqueue_create(tq_name, M_NOWAIT, 504 taskqueue_thread_enqueue, &ha->sp_taskqueue[i]); 505 506 if (ha->sp_taskqueue[i] == NULL) 507 return (-1); 508 509 taskqueue_start_threads(&ha->sp_taskqueue[i], 1, PI_NET, "%s", 510 tq_name); 511 512 QL_DPRINT1(ha, "%p\n", ha->sp_taskqueue[i]); 513 } 514 515 return (0); 516 } 517 518 static void 519 qlnx_destroy_sp_taskqueues(qlnx_host_t *ha) 520 { 521 int i; 522 523 for (i = 0; i < ha->cdev.num_hwfns; i++) { 524 if (ha->sp_taskqueue[i] != NULL) { 525 taskqueue_drain(ha->sp_taskqueue[i], &ha->sp_task[i]); 526 taskqueue_free(ha->sp_taskqueue[i]); 527 } 528 } 529 return; 530 } 531 532 static void 533 qlnx_fp_taskqueue(void *context, int pending) 534 { 535 struct qlnx_fastpath *fp; 536 qlnx_host_t *ha; 537 if_t ifp; 538 539 fp = context; 540 541 if (fp == NULL) 542 return; 543 544 ha = (qlnx_host_t *)fp->edev; 545 546 ifp = ha->ifp; 547 548 if(if_getdrvflags(ifp) & IFF_DRV_RUNNING) { 549 if (!drbr_empty(ifp, fp->tx_br)) { 550 if(mtx_trylock(&fp->tx_mtx)) { 551 #ifdef QLNX_TRACE_PERF_DATA 552 tx_pkts = fp->tx_pkts_transmitted; 553 tx_compl = fp->tx_pkts_completed; 554 #endif 555 556 qlnx_transmit_locked(ifp, fp, NULL); 557 558 #ifdef QLNX_TRACE_PERF_DATA 559 fp->tx_pkts_trans_fp += 560 (fp->tx_pkts_transmitted - tx_pkts); 561 fp->tx_pkts_compl_fp += 562 (fp->tx_pkts_completed - tx_compl); 563 #endif 564 mtx_unlock(&fp->tx_mtx); 565 } 566 } 567 } 568 569 QL_DPRINT2(ha, "exit \n"); 570 return; 571 } 572 573 static int 574 qlnx_create_fp_taskqueues(qlnx_host_t *ha) 575 { 576 int i; 577 uint8_t tq_name[32]; 578 struct qlnx_fastpath *fp; 579 580 for (i = 0; i < ha->num_rss; i++) { 581 fp = &ha->fp_array[i]; 582 583 bzero(tq_name, sizeof (tq_name)); 584 snprintf(tq_name, sizeof (tq_name), "ql_fp_tq_%d", i); 585 586 TASK_INIT(&fp->fp_task, 0, qlnx_fp_taskqueue, fp); 587 588 fp->fp_taskqueue = taskqueue_create(tq_name, M_NOWAIT, 589 taskqueue_thread_enqueue, 590 &fp->fp_taskqueue); 591 592 if (fp->fp_taskqueue == NULL) 593 return (-1); 594 595 taskqueue_start_threads(&fp->fp_taskqueue, 1, PI_NET, "%s", 596 tq_name); 597 598 QL_DPRINT1(ha, "%p\n",fp->fp_taskqueue); 599 } 600 601 return (0); 602 } 603 604 static void 605 qlnx_destroy_fp_taskqueues(qlnx_host_t *ha) 606 { 607 int i; 608 struct qlnx_fastpath *fp; 609 610 for (i = 0; i < ha->num_rss; i++) { 611 fp = &ha->fp_array[i]; 612 613 if (fp->fp_taskqueue != NULL) { 614 taskqueue_drain(fp->fp_taskqueue, &fp->fp_task); 615 taskqueue_free(fp->fp_taskqueue); 616 fp->fp_taskqueue = NULL; 617 } 618 } 619 return; 620 } 621 622 static void 623 qlnx_drain_fp_taskqueues(qlnx_host_t *ha) 624 { 625 int i; 626 struct qlnx_fastpath *fp; 627 628 for (i = 0; i < ha->num_rss; i++) { 629 fp = &ha->fp_array[i]; 630 631 if (fp->fp_taskqueue != NULL) { 632 QLNX_UNLOCK(ha); 633 taskqueue_drain(fp->fp_taskqueue, &fp->fp_task); 634 QLNX_LOCK(ha); 635 } 636 } 637 return; 638 } 639 640 static void 641 qlnx_get_params(qlnx_host_t *ha) 642 { 643 if ((qlnxe_queue_count < 0) || (qlnxe_queue_count > QLNX_MAX_RSS)) { 644 device_printf(ha->pci_dev, "invalid queue_count value (%d)\n", 645 qlnxe_queue_count); 646 qlnxe_queue_count = 0; 647 } 648 return; 649 } 650 651 static void 652 qlnx_error_recovery_taskqueue(void *context, int pending) 653 { 654 qlnx_host_t *ha; 655 656 ha = context; 657 658 QL_DPRINT2(ha, "enter\n"); 659 660 QLNX_LOCK(ha); 661 qlnx_stop(ha); 662 QLNX_UNLOCK(ha); 663 664 #ifdef QLNX_ENABLE_IWARP 665 qlnx_rdma_dev_remove(ha); 666 #endif /* #ifdef QLNX_ENABLE_IWARP */ 667 668 qlnx_slowpath_stop(ha); 669 qlnx_slowpath_start(ha); 670 671 #ifdef QLNX_ENABLE_IWARP 672 qlnx_rdma_dev_add(ha); 673 #endif /* #ifdef QLNX_ENABLE_IWARP */ 674 675 qlnx_init(ha); 676 677 callout_reset(&ha->qlnx_callout, hz, qlnx_timer, ha); 678 679 QL_DPRINT2(ha, "exit\n"); 680 681 return; 682 } 683 684 static int 685 qlnx_create_error_recovery_taskqueue(qlnx_host_t *ha) 686 { 687 uint8_t tq_name[32]; 688 689 bzero(tq_name, sizeof (tq_name)); 690 snprintf(tq_name, sizeof (tq_name), "ql_err_tq"); 691 692 TASK_INIT(&ha->err_task, 0, qlnx_error_recovery_taskqueue, ha); 693 694 ha->err_taskqueue = taskqueue_create(tq_name, M_NOWAIT, 695 taskqueue_thread_enqueue, &ha->err_taskqueue); 696 697 if (ha->err_taskqueue == NULL) 698 return (-1); 699 700 taskqueue_start_threads(&ha->err_taskqueue, 1, PI_NET, "%s", tq_name); 701 702 QL_DPRINT1(ha, "%p\n",ha->err_taskqueue); 703 704 return (0); 705 } 706 707 static void 708 qlnx_destroy_error_recovery_taskqueue(qlnx_host_t *ha) 709 { 710 if (ha->err_taskqueue != NULL) { 711 taskqueue_drain(ha->err_taskqueue, &ha->err_task); 712 taskqueue_free(ha->err_taskqueue); 713 } 714 715 ha->err_taskqueue = NULL; 716 717 return; 718 } 719 720 /* 721 * Name: qlnx_pci_attach 722 * Function: attaches the device to the operating system 723 */ 724 static int 725 qlnx_pci_attach(device_t dev) 726 { 727 qlnx_host_t *ha = NULL; 728 uint32_t rsrc_len_reg __unused = 0; 729 uint32_t rsrc_len_dbells = 0; 730 uint32_t rsrc_len_msix __unused = 0; 731 int i; 732 uint32_t mfw_ver; 733 uint32_t num_sp_msix = 0; 734 uint32_t num_rdma_irqs = 0; 735 736 if ((ha = device_get_softc(dev)) == NULL) { 737 device_printf(dev, "cannot get softc\n"); 738 return (ENOMEM); 739 } 740 741 memset(ha, 0, sizeof (qlnx_host_t)); 742 743 ha->device_id = pci_get_device(dev); 744 745 if (qlnx_valid_device(ha) != 0) { 746 device_printf(dev, "device is not valid device\n"); 747 return (ENXIO); 748 } 749 ha->pci_func = pci_get_function(dev); 750 751 ha->pci_dev = dev; 752 753 sx_init(&ha->hw_lock, "qlnx_hw_lock"); 754 755 ha->flags.lock_init = 1; 756 757 pci_enable_busmaster(dev); 758 759 /* 760 * map the PCI BARs 761 */ 762 763 ha->reg_rid = PCIR_BAR(0); 764 ha->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &ha->reg_rid, 765 RF_ACTIVE); 766 767 if (ha->pci_reg == NULL) { 768 device_printf(dev, "unable to map BAR0\n"); 769 goto qlnx_pci_attach_err; 770 } 771 772 rsrc_len_reg = (uint32_t) bus_get_resource_count(dev, SYS_RES_MEMORY, 773 ha->reg_rid); 774 775 ha->dbells_rid = PCIR_BAR(2); 776 rsrc_len_dbells = (uint32_t) bus_get_resource_count(dev, 777 SYS_RES_MEMORY, 778 ha->dbells_rid); 779 if (rsrc_len_dbells) { 780 ha->pci_dbells = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 781 &ha->dbells_rid, RF_ACTIVE); 782 783 if (ha->pci_dbells == NULL) { 784 device_printf(dev, "unable to map BAR1\n"); 785 goto qlnx_pci_attach_err; 786 } 787 ha->dbells_phys_addr = (uint64_t) 788 bus_get_resource_start(dev, SYS_RES_MEMORY, ha->dbells_rid); 789 790 ha->dbells_size = rsrc_len_dbells; 791 } else { 792 if (qlnx_vf_device(ha) != 0) { 793 device_printf(dev, " BAR1 size is zero\n"); 794 goto qlnx_pci_attach_err; 795 } 796 } 797 798 ha->msix_rid = PCIR_BAR(4); 799 ha->msix_bar = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 800 &ha->msix_rid, RF_ACTIVE); 801 802 if (ha->msix_bar == NULL) { 803 device_printf(dev, "unable to map BAR2\n"); 804 goto qlnx_pci_attach_err; 805 } 806 807 rsrc_len_msix = (uint32_t) bus_get_resource_count(dev, SYS_RES_MEMORY, 808 ha->msix_rid); 809 810 ha->dbg_level = 0x0000; 811 812 QL_DPRINT1(ha, "\n\t\t\t" 813 "pci_dev = %p pci_reg = %p, reg_len = 0x%08x reg_rid = 0x%08x" 814 "\n\t\t\tdbells = %p, dbells_len = 0x%08x dbells_rid = 0x%08x" 815 "\n\t\t\tmsix = %p, msix_len = 0x%08x msix_rid = 0x%08x" 816 " msix_avail = 0x%x " 817 "\n\t\t\t[ncpus = %d]\n", 818 ha->pci_dev, ha->pci_reg, rsrc_len_reg, 819 ha->reg_rid, ha->pci_dbells, rsrc_len_dbells, ha->dbells_rid, 820 ha->msix_bar, rsrc_len_msix, ha->msix_rid, pci_msix_count(dev), 821 mp_ncpus); 822 /* 823 * allocate dma tags 824 */ 825 826 if (qlnx_alloc_parent_dma_tag(ha)) 827 goto qlnx_pci_attach_err; 828 829 if (qlnx_alloc_tx_dma_tag(ha)) 830 goto qlnx_pci_attach_err; 831 832 if (qlnx_alloc_rx_dma_tag(ha)) 833 goto qlnx_pci_attach_err; 834 835 836 if (qlnx_init_hw(ha) != 0) 837 goto qlnx_pci_attach_err; 838 839 ha->flags.hw_init = 1; 840 841 qlnx_get_params(ha); 842 843 if((pci_get_device(dev) == QLOGIC_PCI_DEVICE_ID_1644) && 844 (qlnxe_queue_count == QLNX_DEFAULT_RSS)) { 845 qlnxe_queue_count = QLNX_MAX_RSS; 846 } 847 848 /* 849 * Allocate MSI-x vectors 850 */ 851 if (qlnx_vf_device(ha) != 0) { 852 if (qlnxe_queue_count == 0) 853 ha->num_rss = QLNX_DEFAULT_RSS; 854 else 855 ha->num_rss = qlnxe_queue_count; 856 857 num_sp_msix = ha->cdev.num_hwfns; 858 } else { 859 uint8_t max_rxq; 860 uint8_t max_txq; 861 862 ecore_vf_get_num_rxqs(&ha->cdev.hwfns[0], &max_rxq); 863 ecore_vf_get_num_rxqs(&ha->cdev.hwfns[0], &max_txq); 864 865 if (max_rxq < max_txq) 866 ha->num_rss = max_rxq; 867 else 868 ha->num_rss = max_txq; 869 870 if (ha->num_rss > QLNX_MAX_VF_RSS) 871 ha->num_rss = QLNX_MAX_VF_RSS; 872 873 num_sp_msix = 0; 874 } 875 876 if (ha->num_rss > mp_ncpus) 877 ha->num_rss = mp_ncpus; 878 879 ha->num_tc = QLNX_MAX_TC; 880 881 ha->msix_count = pci_msix_count(dev); 882 883 #ifdef QLNX_ENABLE_IWARP 884 885 num_rdma_irqs = qlnx_rdma_get_num_irqs(ha); 886 887 #endif /* #ifdef QLNX_ENABLE_IWARP */ 888 889 if (!ha->msix_count || 890 (ha->msix_count < (num_sp_msix + 1 + num_rdma_irqs))) { 891 device_printf(dev, "%s: msix_count[%d] not enough\n", __func__, 892 ha->msix_count); 893 goto qlnx_pci_attach_err; 894 } 895 896 if (ha->msix_count > (ha->num_rss + num_sp_msix + num_rdma_irqs)) 897 ha->msix_count = ha->num_rss + num_sp_msix + num_rdma_irqs; 898 else 899 ha->num_rss = ha->msix_count - (num_sp_msix + num_rdma_irqs); 900 901 QL_DPRINT1(ha, "\n\t\t\t" 902 "pci_reg = %p, reg_len = 0x%08x reg_rid = 0x%08x" 903 "\n\t\t\tdbells = %p, dbells_len = 0x%08x dbells_rid = 0x%08x" 904 "\n\t\t\tmsix = %p, msix_len = 0x%08x msix_rid = 0x%08x" 905 " msix_avail = 0x%x msix_alloc = 0x%x" 906 "\n\t\t\t[ncpus = %d][num_rss = 0x%x] [num_tc = 0x%x]\n", 907 ha->pci_reg, rsrc_len_reg, 908 ha->reg_rid, ha->pci_dbells, rsrc_len_dbells, ha->dbells_rid, 909 ha->msix_bar, rsrc_len_msix, ha->msix_rid, pci_msix_count(dev), 910 ha->msix_count, mp_ncpus, ha->num_rss, ha->num_tc); 911 912 if (pci_alloc_msix(dev, &ha->msix_count)) { 913 device_printf(dev, "%s: pci_alloc_msix[%d] failed\n", __func__, 914 ha->msix_count); 915 ha->msix_count = 0; 916 goto qlnx_pci_attach_err; 917 } 918 919 /* 920 * Initialize slow path interrupt and task queue 921 */ 922 923 if (num_sp_msix) { 924 if (qlnx_create_sp_taskqueues(ha) != 0) 925 goto qlnx_pci_attach_err; 926 927 for (i = 0; i < ha->cdev.num_hwfns; i++) { 928 struct ecore_hwfn *p_hwfn = &ha->cdev.hwfns[i]; 929 930 ha->sp_irq_rid[i] = i + 1; 931 ha->sp_irq[i] = bus_alloc_resource_any(dev, SYS_RES_IRQ, 932 &ha->sp_irq_rid[i], 933 (RF_ACTIVE | RF_SHAREABLE)); 934 if (ha->sp_irq[i] == NULL) { 935 device_printf(dev, 936 "could not allocate mbx interrupt\n"); 937 goto qlnx_pci_attach_err; 938 } 939 940 if (bus_setup_intr(dev, ha->sp_irq[i], 941 (INTR_TYPE_NET | INTR_MPSAFE), NULL, 942 qlnx_sp_intr, p_hwfn, &ha->sp_handle[i])) { 943 device_printf(dev, 944 "could not setup slow path interrupt\n"); 945 goto qlnx_pci_attach_err; 946 } 947 948 QL_DPRINT1(ha, "p_hwfn [%p] sp_irq_rid %d" 949 " sp_irq %p sp_handle %p\n", p_hwfn, 950 ha->sp_irq_rid[i], ha->sp_irq[i], ha->sp_handle[i]); 951 } 952 } 953 954 /* 955 * initialize fast path interrupt 956 */ 957 if (qlnx_create_fp_taskqueues(ha) != 0) 958 goto qlnx_pci_attach_err; 959 960 for (i = 0; i < ha->num_rss; i++) { 961 ha->irq_vec[i].rss_idx = i; 962 ha->irq_vec[i].ha = ha; 963 ha->irq_vec[i].irq_rid = (1 + num_sp_msix) + i; 964 965 ha->irq_vec[i].irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 966 &ha->irq_vec[i].irq_rid, 967 (RF_ACTIVE | RF_SHAREABLE)); 968 969 if (ha->irq_vec[i].irq == NULL) { 970 device_printf(dev, 971 "could not allocate interrupt[%d] irq_rid = %d\n", 972 i, ha->irq_vec[i].irq_rid); 973 goto qlnx_pci_attach_err; 974 } 975 976 if (qlnx_alloc_tx_br(ha, &ha->fp_array[i])) { 977 device_printf(dev, "could not allocate tx_br[%d]\n", i); 978 goto qlnx_pci_attach_err; 979 } 980 } 981 982 if (qlnx_vf_device(ha) != 0) { 983 callout_init(&ha->qlnx_callout, 1); 984 ha->flags.callout_init = 1; 985 986 for (i = 0; i < ha->cdev.num_hwfns; i++) { 987 if (qlnx_grc_dumpsize(ha, &ha->grcdump_size[i], i) != 0) 988 goto qlnx_pci_attach_err; 989 if (ha->grcdump_size[i] == 0) 990 goto qlnx_pci_attach_err; 991 992 ha->grcdump_size[i] = ha->grcdump_size[i] << 2; 993 QL_DPRINT1(ha, "grcdump_size[%d] = 0x%08x\n", 994 i, ha->grcdump_size[i]); 995 996 ha->grcdump[i] = qlnx_zalloc(ha->grcdump_size[i]); 997 if (ha->grcdump[i] == NULL) { 998 device_printf(dev, "grcdump alloc[%d] failed\n", i); 999 goto qlnx_pci_attach_err; 1000 } 1001 1002 if (qlnx_idle_chk_size(ha, &ha->idle_chk_size[i], i) != 0) 1003 goto qlnx_pci_attach_err; 1004 if (ha->idle_chk_size[i] == 0) 1005 goto qlnx_pci_attach_err; 1006 1007 ha->idle_chk_size[i] = ha->idle_chk_size[i] << 2; 1008 QL_DPRINT1(ha, "idle_chk_size[%d] = 0x%08x\n", 1009 i, ha->idle_chk_size[i]); 1010 1011 ha->idle_chk[i] = qlnx_zalloc(ha->idle_chk_size[i]); 1012 1013 if (ha->idle_chk[i] == NULL) { 1014 device_printf(dev, "idle_chk alloc failed\n"); 1015 goto qlnx_pci_attach_err; 1016 } 1017 } 1018 1019 if (qlnx_create_error_recovery_taskqueue(ha) != 0) 1020 goto qlnx_pci_attach_err; 1021 } 1022 1023 if (qlnx_slowpath_start(ha) != 0) 1024 goto qlnx_pci_attach_err; 1025 else 1026 ha->flags.slowpath_start = 1; 1027 1028 if (qlnx_vf_device(ha) != 0) { 1029 if (qlnx_get_flash_size(ha, &ha->flash_size) != 0) { 1030 qlnx_mdelay(__func__, 1000); 1031 qlnx_trigger_dump(ha); 1032 1033 goto qlnx_pci_attach_err0; 1034 } 1035 1036 if (qlnx_get_mfw_version(ha, &mfw_ver) != 0) { 1037 qlnx_mdelay(__func__, 1000); 1038 qlnx_trigger_dump(ha); 1039 1040 goto qlnx_pci_attach_err0; 1041 } 1042 } else { 1043 struct ecore_hwfn *p_hwfn = &ha->cdev.hwfns[0]; 1044 ecore_mcp_get_mfw_ver(p_hwfn, NULL, &mfw_ver, NULL); 1045 } 1046 1047 snprintf(ha->mfw_ver, sizeof(ha->mfw_ver), "%d.%d.%d.%d", 1048 ((mfw_ver >> 24) & 0xFF), ((mfw_ver >> 16) & 0xFF), 1049 ((mfw_ver >> 8) & 0xFF), (mfw_ver & 0xFF)); 1050 snprintf(ha->stormfw_ver, sizeof(ha->stormfw_ver), "%d.%d.%d.%d", 1051 FW_MAJOR_VERSION, FW_MINOR_VERSION, FW_REVISION_VERSION, 1052 FW_ENGINEERING_VERSION); 1053 1054 QL_DPRINT1(ha, "STORM_FW version %s MFW version %s\n", 1055 ha->stormfw_ver, ha->mfw_ver); 1056 1057 qlnx_init_ifnet(dev, ha); 1058 1059 /* 1060 * add sysctls 1061 */ 1062 qlnx_add_sysctls(ha); 1063 1064 qlnx_pci_attach_err0: 1065 /* 1066 * create ioctl device interface 1067 */ 1068 if (qlnx_vf_device(ha) != 0) { 1069 if (qlnx_make_cdev(ha)) { 1070 device_printf(dev, "%s: ql_make_cdev failed\n", __func__); 1071 goto qlnx_pci_attach_err; 1072 } 1073 1074 #ifdef QLNX_ENABLE_IWARP 1075 qlnx_rdma_dev_add(ha); 1076 #endif /* #ifdef QLNX_ENABLE_IWARP */ 1077 } 1078 1079 #ifndef QLNX_VF 1080 #ifdef CONFIG_ECORE_SRIOV 1081 1082 if (qlnx_vf_device(ha) != 0) 1083 qlnx_initialize_sriov(ha); 1084 1085 #endif /* #ifdef CONFIG_ECORE_SRIOV */ 1086 #endif /* #ifdef QLNX_VF */ 1087 1088 QL_DPRINT2(ha, "success\n"); 1089 1090 return (0); 1091 1092 qlnx_pci_attach_err: 1093 1094 qlnx_release(ha); 1095 1096 return (ENXIO); 1097 } 1098 1099 /* 1100 * Name: qlnx_pci_detach 1101 * Function: Unhooks the device from the operating system 1102 */ 1103 static int 1104 qlnx_pci_detach(device_t dev) 1105 { 1106 qlnx_host_t *ha = NULL; 1107 1108 if ((ha = device_get_softc(dev)) == NULL) { 1109 device_printf(dev, "%s: cannot get softc\n", __func__); 1110 return (ENOMEM); 1111 } 1112 1113 if (qlnx_vf_device(ha) != 0) { 1114 #ifdef CONFIG_ECORE_SRIOV 1115 int ret; 1116 1117 ret = pci_iov_detach(dev); 1118 if (ret) { 1119 device_printf(dev, "%s: SRIOV in use\n", __func__); 1120 return (ret); 1121 } 1122 1123 #endif /* #ifdef CONFIG_ECORE_SRIOV */ 1124 1125 #ifdef QLNX_ENABLE_IWARP 1126 if (qlnx_rdma_dev_remove(ha) != 0) 1127 return (EBUSY); 1128 #endif /* #ifdef QLNX_ENABLE_IWARP */ 1129 } 1130 1131 QLNX_LOCK(ha); 1132 qlnx_stop(ha); 1133 QLNX_UNLOCK(ha); 1134 1135 qlnx_release(ha); 1136 1137 return (0); 1138 } 1139 1140 #ifdef QLNX_ENABLE_IWARP 1141 1142 static uint8_t 1143 qlnx_get_personality(uint8_t pci_func) 1144 { 1145 uint8_t personality; 1146 1147 personality = (qlnxe_rdma_configuration >> 1148 (pci_func * QLNX_PERSONALITY_BITS_PER_FUNC)) & 1149 QLNX_PERSONALIY_MASK; 1150 return (personality); 1151 } 1152 1153 static void 1154 qlnx_set_personality(qlnx_host_t *ha) 1155 { 1156 uint8_t personality; 1157 1158 personality = qlnx_get_personality(ha->pci_func); 1159 1160 switch (personality) { 1161 case QLNX_PERSONALITY_DEFAULT: 1162 device_printf(ha->pci_dev, "%s: DEFAULT\n", 1163 __func__); 1164 ha->personality = ECORE_PCI_DEFAULT; 1165 break; 1166 1167 case QLNX_PERSONALITY_ETH_ONLY: 1168 device_printf(ha->pci_dev, "%s: ETH_ONLY\n", 1169 __func__); 1170 ha->personality = ECORE_PCI_ETH; 1171 break; 1172 1173 case QLNX_PERSONALITY_ETH_IWARP: 1174 device_printf(ha->pci_dev, "%s: ETH_IWARP\n", 1175 __func__); 1176 ha->personality = ECORE_PCI_ETH_IWARP; 1177 break; 1178 1179 case QLNX_PERSONALITY_ETH_ROCE: 1180 device_printf(ha->pci_dev, "%s: ETH_ROCE\n", 1181 __func__); 1182 ha->personality = ECORE_PCI_ETH_ROCE; 1183 break; 1184 } 1185 1186 return; 1187 } 1188 1189 #endif /* #ifdef QLNX_ENABLE_IWARP */ 1190 1191 static int 1192 qlnx_init_hw(qlnx_host_t *ha) 1193 { 1194 int rval = 0; 1195 struct ecore_hw_prepare_params params; 1196 1197 ha->cdev.ha = ha; 1198 ecore_init_struct(&ha->cdev); 1199 1200 /* ha->dp_module = ECORE_MSG_PROBE | 1201 ECORE_MSG_INTR | 1202 ECORE_MSG_SP | 1203 ECORE_MSG_LINK | 1204 ECORE_MSG_SPQ | 1205 ECORE_MSG_RDMA; 1206 ha->dp_level = ECORE_LEVEL_VERBOSE;*/ 1207 //ha->dp_module = ECORE_MSG_RDMA | ECORE_MSG_INTR | ECORE_MSG_LL2; 1208 ha->dp_level = ECORE_LEVEL_NOTICE; 1209 //ha->dp_level = ECORE_LEVEL_VERBOSE; 1210 1211 ecore_init_dp(&ha->cdev, ha->dp_module, ha->dp_level, ha->pci_dev); 1212 1213 ha->cdev.regview = ha->pci_reg; 1214 1215 ha->personality = ECORE_PCI_DEFAULT; 1216 1217 if (qlnx_vf_device(ha) == 0) { 1218 ha->cdev.b_is_vf = true; 1219 1220 if (ha->pci_dbells != NULL) { 1221 ha->cdev.doorbells = ha->pci_dbells; 1222 ha->cdev.db_phys_addr = ha->dbells_phys_addr; 1223 ha->cdev.db_size = ha->dbells_size; 1224 } else { 1225 ha->pci_dbells = ha->pci_reg; 1226 } 1227 } else { 1228 ha->cdev.doorbells = ha->pci_dbells; 1229 ha->cdev.db_phys_addr = ha->dbells_phys_addr; 1230 ha->cdev.db_size = ha->dbells_size; 1231 1232 #ifdef QLNX_ENABLE_IWARP 1233 1234 if (qlnx_rdma_supported(ha) == 0) 1235 qlnx_set_personality(ha); 1236 1237 #endif /* #ifdef QLNX_ENABLE_IWARP */ 1238 } 1239 QL_DPRINT2(ha, "%s: %s\n", __func__, 1240 (ha->personality == ECORE_PCI_ETH_IWARP ? "iwarp": "ethernet")); 1241 1242 bzero(¶ms, sizeof (struct ecore_hw_prepare_params)); 1243 1244 params.personality = ha->personality; 1245 1246 params.drv_resc_alloc = false; 1247 params.chk_reg_fifo = false; 1248 params.initiate_pf_flr = true; 1249 params.epoch = 0; 1250 1251 ecore_hw_prepare(&ha->cdev, ¶ms); 1252 1253 qlnx_set_id(&ha->cdev, qlnx_name_str, qlnx_ver_str); 1254 1255 QL_DPRINT1(ha, "ha = %p cdev = %p p_hwfn = %p\n", 1256 ha, &ha->cdev, &ha->cdev.hwfns[0]); 1257 1258 return (rval); 1259 } 1260 1261 static void 1262 qlnx_release(qlnx_host_t *ha) 1263 { 1264 device_t dev; 1265 int i; 1266 1267 dev = ha->pci_dev; 1268 1269 QL_DPRINT2(ha, "enter\n"); 1270 1271 for (i = 0; i < QLNX_MAX_HW_FUNCS; i++) { 1272 if (ha->idle_chk[i] != NULL) { 1273 free(ha->idle_chk[i], M_QLNXBUF); 1274 ha->idle_chk[i] = NULL; 1275 } 1276 1277 if (ha->grcdump[i] != NULL) { 1278 free(ha->grcdump[i], M_QLNXBUF); 1279 ha->grcdump[i] = NULL; 1280 } 1281 } 1282 1283 if (ha->flags.callout_init) 1284 callout_drain(&ha->qlnx_callout); 1285 1286 if (ha->flags.slowpath_start) { 1287 qlnx_slowpath_stop(ha); 1288 } 1289 1290 if (ha->flags.hw_init) 1291 ecore_hw_remove(&ha->cdev); 1292 1293 qlnx_del_cdev(ha); 1294 1295 if (ha->ifp != NULL) 1296 ether_ifdetach(ha->ifp); 1297 1298 qlnx_free_tx_dma_tag(ha); 1299 1300 qlnx_free_rx_dma_tag(ha); 1301 1302 qlnx_free_parent_dma_tag(ha); 1303 1304 if (qlnx_vf_device(ha) != 0) { 1305 qlnx_destroy_error_recovery_taskqueue(ha); 1306 } 1307 1308 for (i = 0; i < ha->num_rss; i++) { 1309 struct qlnx_fastpath *fp = &ha->fp_array[i]; 1310 1311 if (ha->irq_vec[i].handle) { 1312 (void)bus_teardown_intr(dev, ha->irq_vec[i].irq, 1313 ha->irq_vec[i].handle); 1314 } 1315 1316 if (ha->irq_vec[i].irq) { 1317 (void)bus_release_resource(dev, SYS_RES_IRQ, 1318 ha->irq_vec[i].irq_rid, 1319 ha->irq_vec[i].irq); 1320 } 1321 1322 qlnx_free_tx_br(ha, fp); 1323 } 1324 qlnx_destroy_fp_taskqueues(ha); 1325 1326 for (i = 0; i < ha->cdev.num_hwfns; i++) { 1327 if (ha->sp_handle[i]) 1328 (void)bus_teardown_intr(dev, ha->sp_irq[i], 1329 ha->sp_handle[i]); 1330 1331 if (ha->sp_irq[i]) 1332 (void) bus_release_resource(dev, SYS_RES_IRQ, 1333 ha->sp_irq_rid[i], ha->sp_irq[i]); 1334 } 1335 1336 qlnx_destroy_sp_taskqueues(ha); 1337 1338 if (ha->msix_count) 1339 pci_release_msi(dev); 1340 1341 if (ha->flags.lock_init) { 1342 sx_destroy(&ha->hw_lock); 1343 } 1344 1345 if (ha->pci_reg) 1346 (void) bus_release_resource(dev, SYS_RES_MEMORY, ha->reg_rid, 1347 ha->pci_reg); 1348 1349 if (ha->dbells_size && ha->pci_dbells) 1350 (void) bus_release_resource(dev, SYS_RES_MEMORY, ha->dbells_rid, 1351 ha->pci_dbells); 1352 1353 if (ha->msix_bar) 1354 (void) bus_release_resource(dev, SYS_RES_MEMORY, ha->msix_rid, 1355 ha->msix_bar); 1356 1357 QL_DPRINT2(ha, "exit\n"); 1358 return; 1359 } 1360 1361 static void 1362 qlnx_trigger_dump(qlnx_host_t *ha) 1363 { 1364 int i; 1365 1366 if (ha->ifp != NULL) 1367 if_setdrvflagbits(ha->ifp, 0, (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)); 1368 1369 QL_DPRINT2(ha, "enter\n"); 1370 1371 if (qlnx_vf_device(ha) == 0) 1372 return; 1373 1374 ha->error_recovery = 1; 1375 1376 for (i = 0; i < ha->cdev.num_hwfns; i++) { 1377 qlnx_grc_dump(ha, &ha->grcdump_dwords[i], i); 1378 qlnx_idle_chk(ha, &ha->idle_chk_dwords[i], i); 1379 } 1380 1381 QL_DPRINT2(ha, "exit\n"); 1382 1383 return; 1384 } 1385 1386 static int 1387 qlnx_trigger_dump_sysctl(SYSCTL_HANDLER_ARGS) 1388 { 1389 int err, ret = 0; 1390 qlnx_host_t *ha; 1391 1392 err = sysctl_handle_int(oidp, &ret, 0, req); 1393 1394 if (err || !req->newptr) 1395 return (err); 1396 1397 if (ret == 1) { 1398 ha = (qlnx_host_t *)arg1; 1399 qlnx_trigger_dump(ha); 1400 } 1401 return (err); 1402 } 1403 1404 static int 1405 qlnx_set_tx_coalesce(SYSCTL_HANDLER_ARGS) 1406 { 1407 int err, i, ret = 0, usecs = 0; 1408 qlnx_host_t *ha; 1409 struct ecore_hwfn *p_hwfn; 1410 struct qlnx_fastpath *fp; 1411 1412 err = sysctl_handle_int(oidp, &usecs, 0, req); 1413 1414 if (err || !req->newptr || !usecs || (usecs > 255)) 1415 return (err); 1416 1417 ha = (qlnx_host_t *)arg1; 1418 1419 if (qlnx_vf_device(ha) == 0) 1420 return (-1); 1421 1422 for (i = 0; i < ha->num_rss; i++) { 1423 p_hwfn = &ha->cdev.hwfns[(i % ha->cdev.num_hwfns)]; 1424 1425 fp = &ha->fp_array[i]; 1426 1427 if (fp->txq[0]->handle != NULL) { 1428 ret = ecore_set_queue_coalesce(p_hwfn, 0, 1429 (uint16_t)usecs, fp->txq[0]->handle); 1430 } 1431 } 1432 1433 if (!ret) 1434 ha->tx_coalesce_usecs = (uint8_t)usecs; 1435 1436 return (err); 1437 } 1438 1439 static int 1440 qlnx_set_rx_coalesce(SYSCTL_HANDLER_ARGS) 1441 { 1442 int err, i, ret = 0, usecs = 0; 1443 qlnx_host_t *ha; 1444 struct ecore_hwfn *p_hwfn; 1445 struct qlnx_fastpath *fp; 1446 1447 err = sysctl_handle_int(oidp, &usecs, 0, req); 1448 1449 if (err || !req->newptr || !usecs || (usecs > 255)) 1450 return (err); 1451 1452 ha = (qlnx_host_t *)arg1; 1453 1454 if (qlnx_vf_device(ha) == 0) 1455 return (-1); 1456 1457 for (i = 0; i < ha->num_rss; i++) { 1458 p_hwfn = &ha->cdev.hwfns[(i % ha->cdev.num_hwfns)]; 1459 1460 fp = &ha->fp_array[i]; 1461 1462 if (fp->rxq->handle != NULL) { 1463 ret = ecore_set_queue_coalesce(p_hwfn, (uint16_t)usecs, 1464 0, fp->rxq->handle); 1465 } 1466 } 1467 1468 if (!ret) 1469 ha->rx_coalesce_usecs = (uint8_t)usecs; 1470 1471 return (err); 1472 } 1473 1474 static void 1475 qlnx_add_sp_stats_sysctls(qlnx_host_t *ha) 1476 { 1477 struct sysctl_ctx_list *ctx; 1478 struct sysctl_oid_list *children; 1479 struct sysctl_oid *ctx_oid; 1480 1481 ctx = device_get_sysctl_ctx(ha->pci_dev); 1482 children = SYSCTL_CHILDREN(device_get_sysctl_tree(ha->pci_dev)); 1483 1484 ctx_oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "spstat", 1485 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "spstat"); 1486 children = SYSCTL_CHILDREN(ctx_oid); 1487 1488 SYSCTL_ADD_QUAD(ctx, children, 1489 OID_AUTO, "sp_interrupts", 1490 CTLFLAG_RD, &ha->sp_interrupts, 1491 "No. of slowpath interrupts"); 1492 1493 return; 1494 } 1495 1496 static void 1497 qlnx_add_fp_stats_sysctls(qlnx_host_t *ha) 1498 { 1499 struct sysctl_ctx_list *ctx; 1500 struct sysctl_oid_list *children; 1501 struct sysctl_oid_list *node_children; 1502 struct sysctl_oid *ctx_oid; 1503 int i, j; 1504 uint8_t name_str[16]; 1505 1506 ctx = device_get_sysctl_ctx(ha->pci_dev); 1507 children = SYSCTL_CHILDREN(device_get_sysctl_tree(ha->pci_dev)); 1508 1509 ctx_oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "fpstat", 1510 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "fpstat"); 1511 children = SYSCTL_CHILDREN(ctx_oid); 1512 1513 for (i = 0; i < ha->num_rss; i++) { 1514 bzero(name_str, (sizeof(uint8_t) * sizeof(name_str))); 1515 snprintf(name_str, sizeof(name_str), "%d", i); 1516 1517 ctx_oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, name_str, 1518 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, name_str); 1519 node_children = SYSCTL_CHILDREN(ctx_oid); 1520 1521 /* Tx Related */ 1522 1523 SYSCTL_ADD_QUAD(ctx, node_children, 1524 OID_AUTO, "tx_pkts_processed", 1525 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_processed, 1526 "No. of packets processed for transmission"); 1527 1528 SYSCTL_ADD_QUAD(ctx, node_children, 1529 OID_AUTO, "tx_pkts_freed", 1530 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_freed, 1531 "No. of freed packets"); 1532 1533 SYSCTL_ADD_QUAD(ctx, node_children, 1534 OID_AUTO, "tx_pkts_transmitted", 1535 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_transmitted, 1536 "No. of transmitted packets"); 1537 1538 SYSCTL_ADD_QUAD(ctx, node_children, 1539 OID_AUTO, "tx_pkts_completed", 1540 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_completed, 1541 "No. of transmit completions"); 1542 1543 SYSCTL_ADD_QUAD(ctx, node_children, 1544 OID_AUTO, "tx_non_tso_pkts", 1545 CTLFLAG_RD, &ha->fp_array[i].tx_non_tso_pkts, 1546 "No. of non LSO transmited packets"); 1547 1548 #ifdef QLNX_TRACE_PERF_DATA 1549 1550 SYSCTL_ADD_QUAD(ctx, node_children, 1551 OID_AUTO, "tx_pkts_trans_ctx", 1552 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_trans_ctx, 1553 "No. of transmitted packets in transmit context"); 1554 1555 SYSCTL_ADD_QUAD(ctx, node_children, 1556 OID_AUTO, "tx_pkts_compl_ctx", 1557 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_compl_ctx, 1558 "No. of transmit completions in transmit context"); 1559 1560 SYSCTL_ADD_QUAD(ctx, node_children, 1561 OID_AUTO, "tx_pkts_trans_fp", 1562 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_trans_fp, 1563 "No. of transmitted packets in taskqueue"); 1564 1565 SYSCTL_ADD_QUAD(ctx, node_children, 1566 OID_AUTO, "tx_pkts_compl_fp", 1567 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_compl_fp, 1568 "No. of transmit completions in taskqueue"); 1569 1570 SYSCTL_ADD_QUAD(ctx, node_children, 1571 OID_AUTO, "tx_pkts_compl_intr", 1572 CTLFLAG_RD, &ha->fp_array[i].tx_pkts_compl_intr, 1573 "No. of transmit completions in interrupt ctx"); 1574 #endif 1575 1576 SYSCTL_ADD_QUAD(ctx, node_children, 1577 OID_AUTO, "tx_tso_pkts", 1578 CTLFLAG_RD, &ha->fp_array[i].tx_tso_pkts, 1579 "No. of LSO transmited packets"); 1580 1581 SYSCTL_ADD_QUAD(ctx, node_children, 1582 OID_AUTO, "tx_lso_wnd_min_len", 1583 CTLFLAG_RD, &ha->fp_array[i].tx_lso_wnd_min_len, 1584 "tx_lso_wnd_min_len"); 1585 1586 SYSCTL_ADD_QUAD(ctx, node_children, 1587 OID_AUTO, "tx_defrag", 1588 CTLFLAG_RD, &ha->fp_array[i].tx_defrag, 1589 "tx_defrag"); 1590 1591 SYSCTL_ADD_QUAD(ctx, node_children, 1592 OID_AUTO, "tx_nsegs_gt_elem_left", 1593 CTLFLAG_RD, &ha->fp_array[i].tx_nsegs_gt_elem_left, 1594 "tx_nsegs_gt_elem_left"); 1595 1596 SYSCTL_ADD_UINT(ctx, node_children, 1597 OID_AUTO, "tx_tso_max_nsegs", 1598 CTLFLAG_RD, &ha->fp_array[i].tx_tso_max_nsegs, 1599 ha->fp_array[i].tx_tso_max_nsegs, "tx_tso_max_nsegs"); 1600 1601 SYSCTL_ADD_UINT(ctx, node_children, 1602 OID_AUTO, "tx_tso_min_nsegs", 1603 CTLFLAG_RD, &ha->fp_array[i].tx_tso_min_nsegs, 1604 ha->fp_array[i].tx_tso_min_nsegs, "tx_tso_min_nsegs"); 1605 1606 SYSCTL_ADD_UINT(ctx, node_children, 1607 OID_AUTO, "tx_tso_max_pkt_len", 1608 CTLFLAG_RD, &ha->fp_array[i].tx_tso_max_pkt_len, 1609 ha->fp_array[i].tx_tso_max_pkt_len, 1610 "tx_tso_max_pkt_len"); 1611 1612 SYSCTL_ADD_UINT(ctx, node_children, 1613 OID_AUTO, "tx_tso_min_pkt_len", 1614 CTLFLAG_RD, &ha->fp_array[i].tx_tso_min_pkt_len, 1615 ha->fp_array[i].tx_tso_min_pkt_len, 1616 "tx_tso_min_pkt_len"); 1617 1618 for (j = 0; j < QLNX_FP_MAX_SEGS; j++) { 1619 bzero(name_str, (sizeof(uint8_t) * sizeof(name_str))); 1620 snprintf(name_str, sizeof(name_str), 1621 "tx_pkts_nseg_%02d", (j+1)); 1622 1623 SYSCTL_ADD_QUAD(ctx, node_children, 1624 OID_AUTO, name_str, CTLFLAG_RD, 1625 &ha->fp_array[i].tx_pkts[j], name_str); 1626 } 1627 1628 #ifdef QLNX_TRACE_PERF_DATA 1629 for (j = 0; j < 18; j++) { 1630 bzero(name_str, (sizeof(uint8_t) * sizeof(name_str))); 1631 snprintf(name_str, sizeof(name_str), 1632 "tx_pkts_hist_%02d", (j+1)); 1633 1634 SYSCTL_ADD_QUAD(ctx, node_children, 1635 OID_AUTO, name_str, CTLFLAG_RD, 1636 &ha->fp_array[i].tx_pkts_hist[j], name_str); 1637 } 1638 for (j = 0; j < 5; j++) { 1639 bzero(name_str, (sizeof(uint8_t) * sizeof(name_str))); 1640 snprintf(name_str, sizeof(name_str), 1641 "tx_comInt_%02d", (j+1)); 1642 1643 SYSCTL_ADD_QUAD(ctx, node_children, 1644 OID_AUTO, name_str, CTLFLAG_RD, 1645 &ha->fp_array[i].tx_comInt[j], name_str); 1646 } 1647 for (j = 0; j < 18; j++) { 1648 bzero(name_str, (sizeof(uint8_t) * sizeof(name_str))); 1649 snprintf(name_str, sizeof(name_str), 1650 "tx_pkts_q_%02d", (j+1)); 1651 1652 SYSCTL_ADD_QUAD(ctx, node_children, 1653 OID_AUTO, name_str, CTLFLAG_RD, 1654 &ha->fp_array[i].tx_pkts_q[j], name_str); 1655 } 1656 #endif 1657 1658 SYSCTL_ADD_QUAD(ctx, node_children, 1659 OID_AUTO, "err_tx_nsegs_gt_elem_left", 1660 CTLFLAG_RD, &ha->fp_array[i].err_tx_nsegs_gt_elem_left, 1661 "err_tx_nsegs_gt_elem_left"); 1662 1663 SYSCTL_ADD_QUAD(ctx, node_children, 1664 OID_AUTO, "err_tx_dmamap_create", 1665 CTLFLAG_RD, &ha->fp_array[i].err_tx_dmamap_create, 1666 "err_tx_dmamap_create"); 1667 1668 SYSCTL_ADD_QUAD(ctx, node_children, 1669 OID_AUTO, "err_tx_defrag_dmamap_load", 1670 CTLFLAG_RD, &ha->fp_array[i].err_tx_defrag_dmamap_load, 1671 "err_tx_defrag_dmamap_load"); 1672 1673 SYSCTL_ADD_QUAD(ctx, node_children, 1674 OID_AUTO, "err_tx_non_tso_max_seg", 1675 CTLFLAG_RD, &ha->fp_array[i].err_tx_non_tso_max_seg, 1676 "err_tx_non_tso_max_seg"); 1677 1678 SYSCTL_ADD_QUAD(ctx, node_children, 1679 OID_AUTO, "err_tx_dmamap_load", 1680 CTLFLAG_RD, &ha->fp_array[i].err_tx_dmamap_load, 1681 "err_tx_dmamap_load"); 1682 1683 SYSCTL_ADD_QUAD(ctx, node_children, 1684 OID_AUTO, "err_tx_defrag", 1685 CTLFLAG_RD, &ha->fp_array[i].err_tx_defrag, 1686 "err_tx_defrag"); 1687 1688 SYSCTL_ADD_QUAD(ctx, node_children, 1689 OID_AUTO, "err_tx_free_pkt_null", 1690 CTLFLAG_RD, &ha->fp_array[i].err_tx_free_pkt_null, 1691 "err_tx_free_pkt_null"); 1692 1693 SYSCTL_ADD_QUAD(ctx, node_children, 1694 OID_AUTO, "err_tx_cons_idx_conflict", 1695 CTLFLAG_RD, &ha->fp_array[i].err_tx_cons_idx_conflict, 1696 "err_tx_cons_idx_conflict"); 1697 1698 SYSCTL_ADD_QUAD(ctx, node_children, 1699 OID_AUTO, "lro_cnt_64", 1700 CTLFLAG_RD, &ha->fp_array[i].lro_cnt_64, 1701 "lro_cnt_64"); 1702 1703 SYSCTL_ADD_QUAD(ctx, node_children, 1704 OID_AUTO, "lro_cnt_128", 1705 CTLFLAG_RD, &ha->fp_array[i].lro_cnt_128, 1706 "lro_cnt_128"); 1707 1708 SYSCTL_ADD_QUAD(ctx, node_children, 1709 OID_AUTO, "lro_cnt_256", 1710 CTLFLAG_RD, &ha->fp_array[i].lro_cnt_256, 1711 "lro_cnt_256"); 1712 1713 SYSCTL_ADD_QUAD(ctx, node_children, 1714 OID_AUTO, "lro_cnt_512", 1715 CTLFLAG_RD, &ha->fp_array[i].lro_cnt_512, 1716 "lro_cnt_512"); 1717 1718 SYSCTL_ADD_QUAD(ctx, node_children, 1719 OID_AUTO, "lro_cnt_1024", 1720 CTLFLAG_RD, &ha->fp_array[i].lro_cnt_1024, 1721 "lro_cnt_1024"); 1722 1723 /* Rx Related */ 1724 1725 SYSCTL_ADD_QUAD(ctx, node_children, 1726 OID_AUTO, "rx_pkts", 1727 CTLFLAG_RD, &ha->fp_array[i].rx_pkts, 1728 "No. of received packets"); 1729 1730 SYSCTL_ADD_QUAD(ctx, node_children, 1731 OID_AUTO, "tpa_start", 1732 CTLFLAG_RD, &ha->fp_array[i].tpa_start, 1733 "No. of tpa_start packets"); 1734 1735 SYSCTL_ADD_QUAD(ctx, node_children, 1736 OID_AUTO, "tpa_cont", 1737 CTLFLAG_RD, &ha->fp_array[i].tpa_cont, 1738 "No. of tpa_cont packets"); 1739 1740 SYSCTL_ADD_QUAD(ctx, node_children, 1741 OID_AUTO, "tpa_end", 1742 CTLFLAG_RD, &ha->fp_array[i].tpa_end, 1743 "No. of tpa_end packets"); 1744 1745 SYSCTL_ADD_QUAD(ctx, node_children, 1746 OID_AUTO, "err_m_getcl", 1747 CTLFLAG_RD, &ha->fp_array[i].err_m_getcl, 1748 "err_m_getcl"); 1749 1750 SYSCTL_ADD_QUAD(ctx, node_children, 1751 OID_AUTO, "err_m_getjcl", 1752 CTLFLAG_RD, &ha->fp_array[i].err_m_getjcl, 1753 "err_m_getjcl"); 1754 1755 SYSCTL_ADD_QUAD(ctx, node_children, 1756 OID_AUTO, "err_rx_hw_errors", 1757 CTLFLAG_RD, &ha->fp_array[i].err_rx_hw_errors, 1758 "err_rx_hw_errors"); 1759 1760 SYSCTL_ADD_QUAD(ctx, node_children, 1761 OID_AUTO, "err_rx_alloc_errors", 1762 CTLFLAG_RD, &ha->fp_array[i].err_rx_alloc_errors, 1763 "err_rx_alloc_errors"); 1764 } 1765 1766 return; 1767 } 1768 1769 static void 1770 qlnx_add_hw_stats_sysctls(qlnx_host_t *ha) 1771 { 1772 struct sysctl_ctx_list *ctx; 1773 struct sysctl_oid_list *children; 1774 struct sysctl_oid *ctx_oid; 1775 1776 ctx = device_get_sysctl_ctx(ha->pci_dev); 1777 children = SYSCTL_CHILDREN(device_get_sysctl_tree(ha->pci_dev)); 1778 1779 ctx_oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "hwstat", 1780 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "hwstat"); 1781 children = SYSCTL_CHILDREN(ctx_oid); 1782 1783 SYSCTL_ADD_QUAD(ctx, children, 1784 OID_AUTO, "no_buff_discards", 1785 CTLFLAG_RD, &ha->hw_stats.common.no_buff_discards, 1786 "No. of packets discarded due to lack of buffer"); 1787 1788 SYSCTL_ADD_QUAD(ctx, children, 1789 OID_AUTO, "packet_too_big_discard", 1790 CTLFLAG_RD, &ha->hw_stats.common.packet_too_big_discard, 1791 "No. of packets discarded because packet was too big"); 1792 1793 SYSCTL_ADD_QUAD(ctx, children, 1794 OID_AUTO, "ttl0_discard", 1795 CTLFLAG_RD, &ha->hw_stats.common.ttl0_discard, 1796 "ttl0_discard"); 1797 1798 SYSCTL_ADD_QUAD(ctx, children, 1799 OID_AUTO, "rx_ucast_bytes", 1800 CTLFLAG_RD, &ha->hw_stats.common.rx_ucast_bytes, 1801 "rx_ucast_bytes"); 1802 1803 SYSCTL_ADD_QUAD(ctx, children, 1804 OID_AUTO, "rx_mcast_bytes", 1805 CTLFLAG_RD, &ha->hw_stats.common.rx_mcast_bytes, 1806 "rx_mcast_bytes"); 1807 1808 SYSCTL_ADD_QUAD(ctx, children, 1809 OID_AUTO, "rx_bcast_bytes", 1810 CTLFLAG_RD, &ha->hw_stats.common.rx_bcast_bytes, 1811 "rx_bcast_bytes"); 1812 1813 SYSCTL_ADD_QUAD(ctx, children, 1814 OID_AUTO, "rx_ucast_pkts", 1815 CTLFLAG_RD, &ha->hw_stats.common.rx_ucast_pkts, 1816 "rx_ucast_pkts"); 1817 1818 SYSCTL_ADD_QUAD(ctx, children, 1819 OID_AUTO, "rx_mcast_pkts", 1820 CTLFLAG_RD, &ha->hw_stats.common.rx_mcast_pkts, 1821 "rx_mcast_pkts"); 1822 1823 SYSCTL_ADD_QUAD(ctx, children, 1824 OID_AUTO, "rx_bcast_pkts", 1825 CTLFLAG_RD, &ha->hw_stats.common.rx_bcast_pkts, 1826 "rx_bcast_pkts"); 1827 1828 SYSCTL_ADD_QUAD(ctx, children, 1829 OID_AUTO, "mftag_filter_discards", 1830 CTLFLAG_RD, &ha->hw_stats.common.mftag_filter_discards, 1831 "mftag_filter_discards"); 1832 1833 SYSCTL_ADD_QUAD(ctx, children, 1834 OID_AUTO, "mac_filter_discards", 1835 CTLFLAG_RD, &ha->hw_stats.common.mac_filter_discards, 1836 "mac_filter_discards"); 1837 1838 SYSCTL_ADD_QUAD(ctx, children, 1839 OID_AUTO, "tx_ucast_bytes", 1840 CTLFLAG_RD, &ha->hw_stats.common.tx_ucast_bytes, 1841 "tx_ucast_bytes"); 1842 1843 SYSCTL_ADD_QUAD(ctx, children, 1844 OID_AUTO, "tx_mcast_bytes", 1845 CTLFLAG_RD, &ha->hw_stats.common.tx_mcast_bytes, 1846 "tx_mcast_bytes"); 1847 1848 SYSCTL_ADD_QUAD(ctx, children, 1849 OID_AUTO, "tx_bcast_bytes", 1850 CTLFLAG_RD, &ha->hw_stats.common.tx_bcast_bytes, 1851 "tx_bcast_bytes"); 1852 1853 SYSCTL_ADD_QUAD(ctx, children, 1854 OID_AUTO, "tx_ucast_pkts", 1855 CTLFLAG_RD, &ha->hw_stats.common.tx_ucast_pkts, 1856 "tx_ucast_pkts"); 1857 1858 SYSCTL_ADD_QUAD(ctx, children, 1859 OID_AUTO, "tx_mcast_pkts", 1860 CTLFLAG_RD, &ha->hw_stats.common.tx_mcast_pkts, 1861 "tx_mcast_pkts"); 1862 1863 SYSCTL_ADD_QUAD(ctx, children, 1864 OID_AUTO, "tx_bcast_pkts", 1865 CTLFLAG_RD, &ha->hw_stats.common.tx_bcast_pkts, 1866 "tx_bcast_pkts"); 1867 1868 SYSCTL_ADD_QUAD(ctx, children, 1869 OID_AUTO, "tx_err_drop_pkts", 1870 CTLFLAG_RD, &ha->hw_stats.common.tx_err_drop_pkts, 1871 "tx_err_drop_pkts"); 1872 1873 SYSCTL_ADD_QUAD(ctx, children, 1874 OID_AUTO, "tpa_coalesced_pkts", 1875 CTLFLAG_RD, &ha->hw_stats.common.tpa_coalesced_pkts, 1876 "tpa_coalesced_pkts"); 1877 1878 SYSCTL_ADD_QUAD(ctx, children, 1879 OID_AUTO, "tpa_coalesced_events", 1880 CTLFLAG_RD, &ha->hw_stats.common.tpa_coalesced_events, 1881 "tpa_coalesced_events"); 1882 1883 SYSCTL_ADD_QUAD(ctx, children, 1884 OID_AUTO, "tpa_aborts_num", 1885 CTLFLAG_RD, &ha->hw_stats.common.tpa_aborts_num, 1886 "tpa_aborts_num"); 1887 1888 SYSCTL_ADD_QUAD(ctx, children, 1889 OID_AUTO, "tpa_not_coalesced_pkts", 1890 CTLFLAG_RD, &ha->hw_stats.common.tpa_not_coalesced_pkts, 1891 "tpa_not_coalesced_pkts"); 1892 1893 SYSCTL_ADD_QUAD(ctx, children, 1894 OID_AUTO, "tpa_coalesced_bytes", 1895 CTLFLAG_RD, &ha->hw_stats.common.tpa_coalesced_bytes, 1896 "tpa_coalesced_bytes"); 1897 1898 SYSCTL_ADD_QUAD(ctx, children, 1899 OID_AUTO, "rx_64_byte_packets", 1900 CTLFLAG_RD, &ha->hw_stats.common.rx_64_byte_packets, 1901 "rx_64_byte_packets"); 1902 1903 SYSCTL_ADD_QUAD(ctx, children, 1904 OID_AUTO, "rx_65_to_127_byte_packets", 1905 CTLFLAG_RD, &ha->hw_stats.common.rx_65_to_127_byte_packets, 1906 "rx_65_to_127_byte_packets"); 1907 1908 SYSCTL_ADD_QUAD(ctx, children, 1909 OID_AUTO, "rx_128_to_255_byte_packets", 1910 CTLFLAG_RD, &ha->hw_stats.common.rx_128_to_255_byte_packets, 1911 "rx_128_to_255_byte_packets"); 1912 1913 SYSCTL_ADD_QUAD(ctx, children, 1914 OID_AUTO, "rx_256_to_511_byte_packets", 1915 CTLFLAG_RD, &ha->hw_stats.common.rx_256_to_511_byte_packets, 1916 "rx_256_to_511_byte_packets"); 1917 1918 SYSCTL_ADD_QUAD(ctx, children, 1919 OID_AUTO, "rx_512_to_1023_byte_packets", 1920 CTLFLAG_RD, &ha->hw_stats.common.rx_512_to_1023_byte_packets, 1921 "rx_512_to_1023_byte_packets"); 1922 1923 SYSCTL_ADD_QUAD(ctx, children, 1924 OID_AUTO, "rx_1024_to_1518_byte_packets", 1925 CTLFLAG_RD, &ha->hw_stats.common.rx_1024_to_1518_byte_packets, 1926 "rx_1024_to_1518_byte_packets"); 1927 1928 SYSCTL_ADD_QUAD(ctx, children, 1929 OID_AUTO, "rx_1519_to_1522_byte_packets", 1930 CTLFLAG_RD, &ha->hw_stats.bb.rx_1519_to_1522_byte_packets, 1931 "rx_1519_to_1522_byte_packets"); 1932 1933 SYSCTL_ADD_QUAD(ctx, children, 1934 OID_AUTO, "rx_1523_to_2047_byte_packets", 1935 CTLFLAG_RD, &ha->hw_stats.bb.rx_1519_to_2047_byte_packets, 1936 "rx_1523_to_2047_byte_packets"); 1937 1938 SYSCTL_ADD_QUAD(ctx, children, 1939 OID_AUTO, "rx_2048_to_4095_byte_packets", 1940 CTLFLAG_RD, &ha->hw_stats.bb.rx_2048_to_4095_byte_packets, 1941 "rx_2048_to_4095_byte_packets"); 1942 1943 SYSCTL_ADD_QUAD(ctx, children, 1944 OID_AUTO, "rx_4096_to_9216_byte_packets", 1945 CTLFLAG_RD, &ha->hw_stats.bb.rx_4096_to_9216_byte_packets, 1946 "rx_4096_to_9216_byte_packets"); 1947 1948 SYSCTL_ADD_QUAD(ctx, children, 1949 OID_AUTO, "rx_9217_to_16383_byte_packets", 1950 CTLFLAG_RD, &ha->hw_stats.bb.rx_9217_to_16383_byte_packets, 1951 "rx_9217_to_16383_byte_packets"); 1952 1953 SYSCTL_ADD_QUAD(ctx, children, 1954 OID_AUTO, "rx_crc_errors", 1955 CTLFLAG_RD, &ha->hw_stats.common.rx_crc_errors, 1956 "rx_crc_errors"); 1957 1958 SYSCTL_ADD_QUAD(ctx, children, 1959 OID_AUTO, "rx_mac_crtl_frames", 1960 CTLFLAG_RD, &ha->hw_stats.common.rx_mac_crtl_frames, 1961 "rx_mac_crtl_frames"); 1962 1963 SYSCTL_ADD_QUAD(ctx, children, 1964 OID_AUTO, "rx_pause_frames", 1965 CTLFLAG_RD, &ha->hw_stats.common.rx_pause_frames, 1966 "rx_pause_frames"); 1967 1968 SYSCTL_ADD_QUAD(ctx, children, 1969 OID_AUTO, "rx_pfc_frames", 1970 CTLFLAG_RD, &ha->hw_stats.common.rx_pfc_frames, 1971 "rx_pfc_frames"); 1972 1973 SYSCTL_ADD_QUAD(ctx, children, 1974 OID_AUTO, "rx_align_errors", 1975 CTLFLAG_RD, &ha->hw_stats.common.rx_align_errors, 1976 "rx_align_errors"); 1977 1978 SYSCTL_ADD_QUAD(ctx, children, 1979 OID_AUTO, "rx_carrier_errors", 1980 CTLFLAG_RD, &ha->hw_stats.common.rx_carrier_errors, 1981 "rx_carrier_errors"); 1982 1983 SYSCTL_ADD_QUAD(ctx, children, 1984 OID_AUTO, "rx_oversize_packets", 1985 CTLFLAG_RD, &ha->hw_stats.common.rx_oversize_packets, 1986 "rx_oversize_packets"); 1987 1988 SYSCTL_ADD_QUAD(ctx, children, 1989 OID_AUTO, "rx_jabbers", 1990 CTLFLAG_RD, &ha->hw_stats.common.rx_jabbers, 1991 "rx_jabbers"); 1992 1993 SYSCTL_ADD_QUAD(ctx, children, 1994 OID_AUTO, "rx_undersize_packets", 1995 CTLFLAG_RD, &ha->hw_stats.common.rx_undersize_packets, 1996 "rx_undersize_packets"); 1997 1998 SYSCTL_ADD_QUAD(ctx, children, 1999 OID_AUTO, "rx_fragments", 2000 CTLFLAG_RD, &ha->hw_stats.common.rx_fragments, 2001 "rx_fragments"); 2002 2003 SYSCTL_ADD_QUAD(ctx, children, 2004 OID_AUTO, "tx_64_byte_packets", 2005 CTLFLAG_RD, &ha->hw_stats.common.tx_64_byte_packets, 2006 "tx_64_byte_packets"); 2007 2008 SYSCTL_ADD_QUAD(ctx, children, 2009 OID_AUTO, "tx_65_to_127_byte_packets", 2010 CTLFLAG_RD, &ha->hw_stats.common.tx_65_to_127_byte_packets, 2011 "tx_65_to_127_byte_packets"); 2012 2013 SYSCTL_ADD_QUAD(ctx, children, 2014 OID_AUTO, "tx_128_to_255_byte_packets", 2015 CTLFLAG_RD, &ha->hw_stats.common.tx_128_to_255_byte_packets, 2016 "tx_128_to_255_byte_packets"); 2017 2018 SYSCTL_ADD_QUAD(ctx, children, 2019 OID_AUTO, "tx_256_to_511_byte_packets", 2020 CTLFLAG_RD, &ha->hw_stats.common.tx_256_to_511_byte_packets, 2021 "tx_256_to_511_byte_packets"); 2022 2023 SYSCTL_ADD_QUAD(ctx, children, 2024 OID_AUTO, "tx_512_to_1023_byte_packets", 2025 CTLFLAG_RD, &ha->hw_stats.common.tx_512_to_1023_byte_packets, 2026 "tx_512_to_1023_byte_packets"); 2027 2028 SYSCTL_ADD_QUAD(ctx, children, 2029 OID_AUTO, "tx_1024_to_1518_byte_packets", 2030 CTLFLAG_RD, &ha->hw_stats.common.tx_1024_to_1518_byte_packets, 2031 "tx_1024_to_1518_byte_packets"); 2032 2033 SYSCTL_ADD_QUAD(ctx, children, 2034 OID_AUTO, "tx_1519_to_2047_byte_packets", 2035 CTLFLAG_RD, &ha->hw_stats.bb.tx_1519_to_2047_byte_packets, 2036 "tx_1519_to_2047_byte_packets"); 2037 2038 SYSCTL_ADD_QUAD(ctx, children, 2039 OID_AUTO, "tx_2048_to_4095_byte_packets", 2040 CTLFLAG_RD, &ha->hw_stats.bb.tx_2048_to_4095_byte_packets, 2041 "tx_2048_to_4095_byte_packets"); 2042 2043 SYSCTL_ADD_QUAD(ctx, children, 2044 OID_AUTO, "tx_4096_to_9216_byte_packets", 2045 CTLFLAG_RD, &ha->hw_stats.bb.tx_4096_to_9216_byte_packets, 2046 "tx_4096_to_9216_byte_packets"); 2047 2048 SYSCTL_ADD_QUAD(ctx, children, 2049 OID_AUTO, "tx_9217_to_16383_byte_packets", 2050 CTLFLAG_RD, &ha->hw_stats.bb.tx_9217_to_16383_byte_packets, 2051 "tx_9217_to_16383_byte_packets"); 2052 2053 SYSCTL_ADD_QUAD(ctx, children, 2054 OID_AUTO, "tx_pause_frames", 2055 CTLFLAG_RD, &ha->hw_stats.common.tx_pause_frames, 2056 "tx_pause_frames"); 2057 2058 SYSCTL_ADD_QUAD(ctx, children, 2059 OID_AUTO, "tx_pfc_frames", 2060 CTLFLAG_RD, &ha->hw_stats.common.tx_pfc_frames, 2061 "tx_pfc_frames"); 2062 2063 SYSCTL_ADD_QUAD(ctx, children, 2064 OID_AUTO, "tx_lpi_entry_count", 2065 CTLFLAG_RD, &ha->hw_stats.bb.tx_lpi_entry_count, 2066 "tx_lpi_entry_count"); 2067 2068 SYSCTL_ADD_QUAD(ctx, children, 2069 OID_AUTO, "tx_total_collisions", 2070 CTLFLAG_RD, &ha->hw_stats.bb.tx_total_collisions, 2071 "tx_total_collisions"); 2072 2073 SYSCTL_ADD_QUAD(ctx, children, 2074 OID_AUTO, "brb_truncates", 2075 CTLFLAG_RD, &ha->hw_stats.common.brb_truncates, 2076 "brb_truncates"); 2077 2078 SYSCTL_ADD_QUAD(ctx, children, 2079 OID_AUTO, "brb_discards", 2080 CTLFLAG_RD, &ha->hw_stats.common.brb_discards, 2081 "brb_discards"); 2082 2083 SYSCTL_ADD_QUAD(ctx, children, 2084 OID_AUTO, "rx_mac_bytes", 2085 CTLFLAG_RD, &ha->hw_stats.common.rx_mac_bytes, 2086 "rx_mac_bytes"); 2087 2088 SYSCTL_ADD_QUAD(ctx, children, 2089 OID_AUTO, "rx_mac_uc_packets", 2090 CTLFLAG_RD, &ha->hw_stats.common.rx_mac_uc_packets, 2091 "rx_mac_uc_packets"); 2092 2093 SYSCTL_ADD_QUAD(ctx, children, 2094 OID_AUTO, "rx_mac_mc_packets", 2095 CTLFLAG_RD, &ha->hw_stats.common.rx_mac_mc_packets, 2096 "rx_mac_mc_packets"); 2097 2098 SYSCTL_ADD_QUAD(ctx, children, 2099 OID_AUTO, "rx_mac_bc_packets", 2100 CTLFLAG_RD, &ha->hw_stats.common.rx_mac_bc_packets, 2101 "rx_mac_bc_packets"); 2102 2103 SYSCTL_ADD_QUAD(ctx, children, 2104 OID_AUTO, "rx_mac_frames_ok", 2105 CTLFLAG_RD, &ha->hw_stats.common.rx_mac_frames_ok, 2106 "rx_mac_frames_ok"); 2107 2108 SYSCTL_ADD_QUAD(ctx, children, 2109 OID_AUTO, "tx_mac_bytes", 2110 CTLFLAG_RD, &ha->hw_stats.common.tx_mac_bytes, 2111 "tx_mac_bytes"); 2112 2113 SYSCTL_ADD_QUAD(ctx, children, 2114 OID_AUTO, "tx_mac_uc_packets", 2115 CTLFLAG_RD, &ha->hw_stats.common.tx_mac_uc_packets, 2116 "tx_mac_uc_packets"); 2117 2118 SYSCTL_ADD_QUAD(ctx, children, 2119 OID_AUTO, "tx_mac_mc_packets", 2120 CTLFLAG_RD, &ha->hw_stats.common.tx_mac_mc_packets, 2121 "tx_mac_mc_packets"); 2122 2123 SYSCTL_ADD_QUAD(ctx, children, 2124 OID_AUTO, "tx_mac_bc_packets", 2125 CTLFLAG_RD, &ha->hw_stats.common.tx_mac_bc_packets, 2126 "tx_mac_bc_packets"); 2127 2128 SYSCTL_ADD_QUAD(ctx, children, 2129 OID_AUTO, "tx_mac_ctrl_frames", 2130 CTLFLAG_RD, &ha->hw_stats.common.tx_mac_ctrl_frames, 2131 "tx_mac_ctrl_frames"); 2132 return; 2133 } 2134 2135 static void 2136 qlnx_add_sysctls(qlnx_host_t *ha) 2137 { 2138 device_t dev = ha->pci_dev; 2139 struct sysctl_ctx_list *ctx; 2140 struct sysctl_oid_list *children; 2141 2142 ctx = device_get_sysctl_ctx(dev); 2143 children = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); 2144 2145 qlnx_add_fp_stats_sysctls(ha); 2146 qlnx_add_sp_stats_sysctls(ha); 2147 2148 if (qlnx_vf_device(ha) != 0) 2149 qlnx_add_hw_stats_sysctls(ha); 2150 2151 SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "Driver_Version", 2152 CTLFLAG_RD, qlnx_ver_str, 0, 2153 "Driver Version"); 2154 2155 SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "STORMFW_Version", 2156 CTLFLAG_RD, ha->stormfw_ver, 0, 2157 "STORM Firmware Version"); 2158 2159 SYSCTL_ADD_STRING(ctx, children, OID_AUTO, "MFW_Version", 2160 CTLFLAG_RD, ha->mfw_ver, 0, 2161 "Management Firmware Version"); 2162 2163 SYSCTL_ADD_UINT(ctx, children, 2164 OID_AUTO, "personality", CTLFLAG_RD, 2165 &ha->personality, ha->personality, 2166 "\tpersonality = 0 => Ethernet Only\n" 2167 "\tpersonality = 3 => Ethernet and RoCE\n" 2168 "\tpersonality = 4 => Ethernet and iWARP\n" 2169 "\tpersonality = 6 => Default in Shared Memory\n"); 2170 2171 ha->dbg_level = 0; 2172 SYSCTL_ADD_UINT(ctx, children, 2173 OID_AUTO, "debug", CTLFLAG_RW, 2174 &ha->dbg_level, ha->dbg_level, "Debug Level"); 2175 2176 ha->dp_level = 0x01; 2177 SYSCTL_ADD_UINT(ctx, children, 2178 OID_AUTO, "dp_level", CTLFLAG_RW, 2179 &ha->dp_level, ha->dp_level, "DP Level"); 2180 2181 ha->dbg_trace_lro_cnt = 0; 2182 SYSCTL_ADD_UINT(ctx, children, 2183 OID_AUTO, "dbg_trace_lro_cnt", CTLFLAG_RW, 2184 &ha->dbg_trace_lro_cnt, ha->dbg_trace_lro_cnt, 2185 "Trace LRO Counts"); 2186 2187 ha->dbg_trace_tso_pkt_len = 0; 2188 SYSCTL_ADD_UINT(ctx, children, 2189 OID_AUTO, "dbg_trace_tso_pkt_len", CTLFLAG_RW, 2190 &ha->dbg_trace_tso_pkt_len, ha->dbg_trace_tso_pkt_len, 2191 "Trace TSO packet lengths"); 2192 2193 ha->dp_module = 0; 2194 SYSCTL_ADD_UINT(ctx, children, 2195 OID_AUTO, "dp_module", CTLFLAG_RW, 2196 &ha->dp_module, ha->dp_module, "DP Module"); 2197 2198 ha->err_inject = 0; 2199 2200 SYSCTL_ADD_UINT(ctx, children, 2201 OID_AUTO, "err_inject", CTLFLAG_RW, 2202 &ha->err_inject, ha->err_inject, "Error Inject"); 2203 2204 ha->storm_stats_enable = 0; 2205 2206 SYSCTL_ADD_UINT(ctx, children, 2207 OID_AUTO, "storm_stats_enable", CTLFLAG_RW, 2208 &ha->storm_stats_enable, ha->storm_stats_enable, 2209 "Enable Storm Statistics Gathering"); 2210 2211 ha->storm_stats_index = 0; 2212 2213 SYSCTL_ADD_UINT(ctx, children, 2214 OID_AUTO, "storm_stats_index", CTLFLAG_RD, 2215 &ha->storm_stats_index, ha->storm_stats_index, 2216 "Enable Storm Statistics Gathering Current Index"); 2217 2218 ha->grcdump_taken = 0; 2219 SYSCTL_ADD_UINT(ctx, children, 2220 OID_AUTO, "grcdump_taken", CTLFLAG_RD, 2221 &ha->grcdump_taken, ha->grcdump_taken, 2222 "grcdump_taken"); 2223 2224 ha->idle_chk_taken = 0; 2225 SYSCTL_ADD_UINT(ctx, children, 2226 OID_AUTO, "idle_chk_taken", CTLFLAG_RD, 2227 &ha->idle_chk_taken, ha->idle_chk_taken, 2228 "idle_chk_taken"); 2229 2230 SYSCTL_ADD_UINT(ctx, children, 2231 OID_AUTO, "rx_coalesce_usecs", CTLFLAG_RD, 2232 &ha->rx_coalesce_usecs, ha->rx_coalesce_usecs, 2233 "rx_coalesce_usecs"); 2234 2235 SYSCTL_ADD_UINT(ctx, children, 2236 OID_AUTO, "tx_coalesce_usecs", CTLFLAG_RD, 2237 &ha->tx_coalesce_usecs, ha->tx_coalesce_usecs, 2238 "tx_coalesce_usecs"); 2239 2240 SYSCTL_ADD_PROC(ctx, children, 2241 OID_AUTO, "trigger_dump", 2242 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 2243 (void *)ha, 0, qlnx_trigger_dump_sysctl, "I", "trigger_dump"); 2244 2245 SYSCTL_ADD_PROC(ctx, children, 2246 OID_AUTO, "set_rx_coalesce_usecs", 2247 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 2248 (void *)ha, 0, qlnx_set_rx_coalesce, "I", 2249 "rx interrupt coalesce period microseconds"); 2250 2251 SYSCTL_ADD_PROC(ctx, children, 2252 OID_AUTO, "set_tx_coalesce_usecs", 2253 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 2254 (void *)ha, 0, qlnx_set_tx_coalesce, "I", 2255 "tx interrupt coalesce period microseconds"); 2256 2257 ha->rx_pkt_threshold = 128; 2258 SYSCTL_ADD_UINT(ctx, children, 2259 OID_AUTO, "rx_pkt_threshold", CTLFLAG_RW, 2260 &ha->rx_pkt_threshold, ha->rx_pkt_threshold, 2261 "No. of Rx Pkts to process at a time"); 2262 2263 ha->rx_jumbo_buf_eq_mtu = 0; 2264 SYSCTL_ADD_UINT(ctx, children, 2265 OID_AUTO, "rx_jumbo_buf_eq_mtu", CTLFLAG_RW, 2266 &ha->rx_jumbo_buf_eq_mtu, ha->rx_jumbo_buf_eq_mtu, 2267 "== 0 => Rx Jumbo buffers are capped to 4Kbytes\n" 2268 "otherwise Rx Jumbo buffers are set to >= MTU size\n"); 2269 2270 SYSCTL_ADD_QUAD(ctx, children, 2271 OID_AUTO, "err_illegal_intr", CTLFLAG_RD, 2272 &ha->err_illegal_intr, "err_illegal_intr"); 2273 2274 SYSCTL_ADD_QUAD(ctx, children, 2275 OID_AUTO, "err_fp_null", CTLFLAG_RD, 2276 &ha->err_fp_null, "err_fp_null"); 2277 2278 SYSCTL_ADD_QUAD(ctx, children, 2279 OID_AUTO, "err_get_proto_invalid_type", CTLFLAG_RD, 2280 &ha->err_get_proto_invalid_type, "err_get_proto_invalid_type"); 2281 return; 2282 } 2283 2284 /***************************************************************************** 2285 * Operating System Network Interface Functions 2286 *****************************************************************************/ 2287 2288 static void 2289 qlnx_init_ifnet(device_t dev, qlnx_host_t *ha) 2290 { 2291 uint16_t device_id; 2292 if_t ifp; 2293 2294 ifp = ha->ifp = if_alloc(IFT_ETHER); 2295 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 2296 2297 device_id = pci_get_device(ha->pci_dev); 2298 2299 if (device_id == QLOGIC_PCI_DEVICE_ID_1634) 2300 if_setbaudrate(ifp, IF_Gbps(40)); 2301 else if ((device_id == QLOGIC_PCI_DEVICE_ID_1656) || 2302 (device_id == QLOGIC_PCI_DEVICE_ID_8070)) 2303 if_setbaudrate(ifp, IF_Gbps(25)); 2304 else if (device_id == QLOGIC_PCI_DEVICE_ID_1654) 2305 if_setbaudrate(ifp, IF_Gbps(50)); 2306 else if (device_id == QLOGIC_PCI_DEVICE_ID_1644) 2307 if_setbaudrate(ifp, IF_Gbps(100)); 2308 2309 if_setcapabilities(ifp, IFCAP_LINKSTATE); 2310 2311 if_setinitfn(ifp, qlnx_init); 2312 if_setsoftc(ifp, ha); 2313 if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST); 2314 if_setioctlfn(ifp, qlnx_ioctl); 2315 if_settransmitfn(ifp, qlnx_transmit); 2316 if_setqflushfn(ifp, qlnx_qflush); 2317 2318 if_setsendqlen(ifp, qlnx_get_ifq_snd_maxlen(ha)); 2319 if_setsendqready(ifp); 2320 2321 if_setgetcounterfn(ifp, qlnx_get_counter); 2322 2323 ha->max_frame_size = if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN; 2324 2325 memcpy(ha->primary_mac, qlnx_get_mac_addr(ha), ETH_ALEN); 2326 2327 if (!ha->primary_mac[0] && !ha->primary_mac[1] && 2328 !ha->primary_mac[2] && !ha->primary_mac[3] && 2329 !ha->primary_mac[4] && !ha->primary_mac[5]) { 2330 uint32_t rnd; 2331 2332 rnd = arc4random(); 2333 2334 ha->primary_mac[0] = 0x00; 2335 ha->primary_mac[1] = 0x0e; 2336 ha->primary_mac[2] = 0x1e; 2337 ha->primary_mac[3] = rnd & 0xFF; 2338 ha->primary_mac[4] = (rnd >> 8) & 0xFF; 2339 ha->primary_mac[5] = (rnd >> 16) & 0xFF; 2340 } 2341 2342 ether_ifattach(ifp, ha->primary_mac); 2343 bcopy(if_getlladdr(ha->ifp), ha->primary_mac, ETHER_ADDR_LEN); 2344 2345 if_setcapabilities(ifp, IFCAP_HWCSUM); 2346 if_setcapabilitiesbit(ifp, IFCAP_JUMBO_MTU, 0); 2347 2348 if_setcapabilitiesbit(ifp, IFCAP_VLAN_MTU, 0); 2349 if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWTAGGING, 0); 2350 if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWFILTER, 0); 2351 if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWCSUM, 0); 2352 if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWTSO, 0); 2353 if_setcapabilitiesbit(ifp, IFCAP_TSO4, 0); 2354 if_setcapabilitiesbit(ifp, IFCAP_TSO6, 0); 2355 if_setcapabilitiesbit(ifp, IFCAP_LRO, 0); 2356 2357 if_sethwtsomax(ifp, QLNX_MAX_TSO_FRAME_SIZE - 2358 (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN)); 2359 if_sethwtsomaxsegcount(ifp, QLNX_MAX_SEGMENTS - 1); /* hdr */ 2360 if_sethwtsomaxsegsize(ifp, QLNX_MAX_TX_MBUF_SIZE); 2361 2362 if_setcapenable(ifp, if_getcapabilities(ifp)); 2363 2364 if_sethwassist(ifp, CSUM_IP); 2365 if_sethwassistbits(ifp, CSUM_TCP | CSUM_UDP, 0); 2366 if_sethwassistbits(ifp, CSUM_TCP_IPV6 | CSUM_UDP_IPV6, 0); 2367 if_sethwassistbits(ifp, CSUM_TSO, 0); 2368 2369 if_setifheaderlen(ifp, sizeof(struct ether_vlan_header)); 2370 2371 ifmedia_init(&ha->media, IFM_IMASK, qlnx_media_change,\ 2372 qlnx_media_status); 2373 2374 if (device_id == QLOGIC_PCI_DEVICE_ID_1634) { 2375 ifmedia_add(&ha->media, (IFM_ETHER | IFM_40G_LR4), 0, NULL); 2376 ifmedia_add(&ha->media, (IFM_ETHER | IFM_40G_SR4), 0, NULL); 2377 ifmedia_add(&ha->media, (IFM_ETHER | IFM_40G_CR4), 0, NULL); 2378 } else if ((device_id == QLOGIC_PCI_DEVICE_ID_1656) || 2379 (device_id == QLOGIC_PCI_DEVICE_ID_8070)) { 2380 ifmedia_add(&ha->media, (IFM_ETHER | QLNX_IFM_25G_SR), 0, NULL); 2381 ifmedia_add(&ha->media, (IFM_ETHER | QLNX_IFM_25G_CR), 0, NULL); 2382 } else if (device_id == QLOGIC_PCI_DEVICE_ID_1654) { 2383 ifmedia_add(&ha->media, (IFM_ETHER | IFM_50G_KR2), 0, NULL); 2384 ifmedia_add(&ha->media, (IFM_ETHER | IFM_50G_CR2), 0, NULL); 2385 } else if (device_id == QLOGIC_PCI_DEVICE_ID_1644) { 2386 ifmedia_add(&ha->media, 2387 (IFM_ETHER | QLNX_IFM_100G_LR4), 0, NULL); 2388 ifmedia_add(&ha->media, 2389 (IFM_ETHER | QLNX_IFM_100G_SR4), 0, NULL); 2390 ifmedia_add(&ha->media, 2391 (IFM_ETHER | QLNX_IFM_100G_CR4), 0, NULL); 2392 } 2393 2394 ifmedia_add(&ha->media, (IFM_ETHER | IFM_FDX), 0, NULL); 2395 ifmedia_add(&ha->media, (IFM_ETHER | IFM_AUTO), 0, NULL); 2396 2397 ifmedia_set(&ha->media, (IFM_ETHER | IFM_AUTO)); 2398 2399 QL_DPRINT2(ha, "exit\n"); 2400 2401 return; 2402 } 2403 2404 static void 2405 qlnx_init_locked(qlnx_host_t *ha) 2406 { 2407 if_t ifp = ha->ifp; 2408 2409 QL_DPRINT1(ha, "Driver Initialization start \n"); 2410 2411 qlnx_stop(ha); 2412 2413 if (qlnx_load(ha) == 0) { 2414 if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0); 2415 if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE); 2416 2417 #ifdef QLNX_ENABLE_IWARP 2418 if (qlnx_vf_device(ha) != 0) { 2419 qlnx_rdma_dev_open(ha); 2420 } 2421 #endif /* #ifdef QLNX_ENABLE_IWARP */ 2422 } 2423 2424 return; 2425 } 2426 2427 static void 2428 qlnx_init(void *arg) 2429 { 2430 qlnx_host_t *ha; 2431 2432 ha = (qlnx_host_t *)arg; 2433 2434 QL_DPRINT2(ha, "enter\n"); 2435 2436 QLNX_LOCK(ha); 2437 qlnx_init_locked(ha); 2438 QLNX_UNLOCK(ha); 2439 2440 QL_DPRINT2(ha, "exit\n"); 2441 2442 return; 2443 } 2444 2445 static int 2446 qlnx_config_mcast_mac_addr(qlnx_host_t *ha, uint8_t *mac_addr, uint32_t add_mac) 2447 { 2448 struct ecore_filter_mcast *mcast; 2449 struct ecore_dev *cdev; 2450 int rc; 2451 2452 cdev = &ha->cdev; 2453 2454 mcast = &ha->ecore_mcast; 2455 bzero(mcast, sizeof(struct ecore_filter_mcast)); 2456 2457 if (add_mac) 2458 mcast->opcode = ECORE_FILTER_ADD; 2459 else 2460 mcast->opcode = ECORE_FILTER_REMOVE; 2461 2462 mcast->num_mc_addrs = 1; 2463 memcpy(mcast->mac, mac_addr, ETH_ALEN); 2464 2465 rc = ecore_filter_mcast_cmd(cdev, mcast, ECORE_SPQ_MODE_CB, NULL); 2466 2467 return (rc); 2468 } 2469 2470 static int 2471 qlnx_hw_add_mcast(qlnx_host_t *ha, uint8_t *mta) 2472 { 2473 int i; 2474 2475 for (i = 0; i < QLNX_MAX_NUM_MULTICAST_ADDRS; i++) { 2476 if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0) 2477 return 0; /* its been already added */ 2478 } 2479 2480 for (i = 0; i < QLNX_MAX_NUM_MULTICAST_ADDRS; i++) { 2481 if ((ha->mcast[i].addr[0] == 0) && 2482 (ha->mcast[i].addr[1] == 0) && 2483 (ha->mcast[i].addr[2] == 0) && 2484 (ha->mcast[i].addr[3] == 0) && 2485 (ha->mcast[i].addr[4] == 0) && 2486 (ha->mcast[i].addr[5] == 0)) { 2487 if (qlnx_config_mcast_mac_addr(ha, mta, 1)) 2488 return (-1); 2489 2490 bcopy(mta, ha->mcast[i].addr, ETH_ALEN); 2491 ha->nmcast++; 2492 2493 return 0; 2494 } 2495 } 2496 return 0; 2497 } 2498 2499 static int 2500 qlnx_hw_del_mcast(qlnx_host_t *ha, uint8_t *mta) 2501 { 2502 int i; 2503 2504 for (i = 0; i < QLNX_MAX_NUM_MULTICAST_ADDRS; i++) { 2505 if (QL_MAC_CMP(ha->mcast[i].addr, mta) == 0) { 2506 if (qlnx_config_mcast_mac_addr(ha, mta, 0)) 2507 return (-1); 2508 2509 ha->mcast[i].addr[0] = 0; 2510 ha->mcast[i].addr[1] = 0; 2511 ha->mcast[i].addr[2] = 0; 2512 ha->mcast[i].addr[3] = 0; 2513 ha->mcast[i].addr[4] = 0; 2514 ha->mcast[i].addr[5] = 0; 2515 2516 ha->nmcast--; 2517 2518 return 0; 2519 } 2520 } 2521 return 0; 2522 } 2523 2524 /* 2525 * Name: qls_hw_set_multi 2526 * Function: Sets the Multicast Addresses provided the host O.S into the 2527 * hardware (for the given interface) 2528 */ 2529 static void 2530 qlnx_hw_set_multi(qlnx_host_t *ha, uint8_t *mta, uint32_t mcnt, 2531 uint32_t add_mac) 2532 { 2533 int i; 2534 2535 for (i = 0; i < mcnt; i++) { 2536 if (add_mac) { 2537 if (qlnx_hw_add_mcast(ha, mta)) 2538 break; 2539 } else { 2540 if (qlnx_hw_del_mcast(ha, mta)) 2541 break; 2542 } 2543 2544 mta += ETHER_HDR_LEN; 2545 } 2546 return; 2547 } 2548 2549 static u_int 2550 qlnx_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int mcnt) 2551 { 2552 uint8_t *mta = arg; 2553 2554 if (mcnt == QLNX_MAX_NUM_MULTICAST_ADDRS) 2555 return (0); 2556 2557 bcopy(LLADDR(sdl), &mta[mcnt * ETHER_HDR_LEN], ETHER_HDR_LEN); 2558 2559 return (1); 2560 } 2561 2562 static int 2563 qlnx_set_multi(qlnx_host_t *ha, uint32_t add_multi) 2564 { 2565 uint8_t mta[QLNX_MAX_NUM_MULTICAST_ADDRS * ETHER_HDR_LEN]; 2566 if_t ifp = ha->ifp; 2567 u_int mcnt; 2568 2569 if (qlnx_vf_device(ha) == 0) 2570 return (0); 2571 2572 mcnt = if_foreach_llmaddr(ifp, qlnx_copy_maddr, mta); 2573 2574 QLNX_LOCK(ha); 2575 qlnx_hw_set_multi(ha, mta, mcnt, add_multi); 2576 QLNX_UNLOCK(ha); 2577 2578 return (0); 2579 } 2580 2581 static int 2582 qlnx_set_promisc(qlnx_host_t *ha, int enabled) 2583 { 2584 int rc = 0; 2585 uint8_t filter; 2586 2587 if (qlnx_vf_device(ha) == 0) 2588 return (0); 2589 2590 filter = ha->filter; 2591 if (enabled) { 2592 filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 2593 filter |= ECORE_ACCEPT_UCAST_UNMATCHED; 2594 } else { 2595 filter &= ~ECORE_ACCEPT_MCAST_UNMATCHED; 2596 filter &= ~ECORE_ACCEPT_UCAST_UNMATCHED; 2597 } 2598 2599 rc = qlnx_set_rx_accept_filter(ha, filter); 2600 return (rc); 2601 } 2602 2603 static int 2604 qlnx_set_allmulti(qlnx_host_t *ha, int enabled) 2605 { 2606 int rc = 0; 2607 uint8_t filter; 2608 2609 if (qlnx_vf_device(ha) == 0) 2610 return (0); 2611 2612 filter = ha->filter; 2613 if (enabled) { 2614 filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 2615 } else { 2616 filter &= ~ECORE_ACCEPT_MCAST_UNMATCHED; 2617 } 2618 rc = qlnx_set_rx_accept_filter(ha, filter); 2619 2620 return (rc); 2621 } 2622 2623 static int 2624 qlnx_ioctl(if_t ifp, u_long cmd, caddr_t data) 2625 { 2626 int ret = 0, mask; 2627 int flags; 2628 struct ifreq *ifr = (struct ifreq *)data; 2629 #ifdef INET 2630 struct ifaddr *ifa = (struct ifaddr *)data; 2631 #endif 2632 qlnx_host_t *ha; 2633 2634 ha = (qlnx_host_t *)if_getsoftc(ifp); 2635 2636 switch (cmd) { 2637 case SIOCSIFADDR: 2638 QL_DPRINT4(ha, "SIOCSIFADDR (0x%lx)\n", cmd); 2639 2640 #ifdef INET 2641 if (ifa->ifa_addr->sa_family == AF_INET) { 2642 if_setflagbits(ifp, IFF_UP, 0); 2643 if (!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) { 2644 QLNX_LOCK(ha); 2645 qlnx_init_locked(ha); 2646 QLNX_UNLOCK(ha); 2647 } 2648 QL_DPRINT4(ha, "SIOCSIFADDR (0x%lx) ipv4 [0x%08x]\n", 2649 cmd, ntohl(IA_SIN(ifa)->sin_addr.s_addr)); 2650 2651 arp_ifinit(ifp, ifa); 2652 break; 2653 } 2654 #endif 2655 ether_ioctl(ifp, cmd, data); 2656 break; 2657 2658 case SIOCSIFMTU: 2659 QL_DPRINT4(ha, "SIOCSIFMTU (0x%lx)\n", cmd); 2660 2661 if (ifr->ifr_mtu > QLNX_MAX_MTU) { 2662 ret = EINVAL; 2663 } else { 2664 QLNX_LOCK(ha); 2665 if_setmtu(ifp, ifr->ifr_mtu); 2666 ha->max_frame_size = 2667 if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN; 2668 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { 2669 qlnx_init_locked(ha); 2670 } 2671 2672 QLNX_UNLOCK(ha); 2673 } 2674 2675 break; 2676 2677 case SIOCSIFFLAGS: 2678 QL_DPRINT4(ha, "SIOCSIFFLAGS (0x%lx)\n", cmd); 2679 2680 QLNX_LOCK(ha); 2681 flags = if_getflags(ifp); 2682 2683 if (flags & IFF_UP) { 2684 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { 2685 if ((flags ^ ha->if_flags) & 2686 IFF_PROMISC) { 2687 ret = qlnx_set_promisc(ha, flags & IFF_PROMISC); 2688 } else if ((if_getflags(ifp) ^ ha->if_flags) & 2689 IFF_ALLMULTI) { 2690 ret = qlnx_set_allmulti(ha, flags & IFF_ALLMULTI); 2691 } 2692 } else { 2693 ha->max_frame_size = if_getmtu(ifp) + 2694 ETHER_HDR_LEN + ETHER_CRC_LEN; 2695 qlnx_init_locked(ha); 2696 } 2697 } else { 2698 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) 2699 qlnx_stop(ha); 2700 } 2701 2702 ha->if_flags = if_getflags(ifp); 2703 QLNX_UNLOCK(ha); 2704 break; 2705 2706 case SIOCADDMULTI: 2707 QL_DPRINT4(ha, "%s (0x%lx)\n", "SIOCADDMULTI", cmd); 2708 2709 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { 2710 if (qlnx_set_multi(ha, 1)) 2711 ret = EINVAL; 2712 } 2713 break; 2714 2715 case SIOCDELMULTI: 2716 QL_DPRINT4(ha, "%s (0x%lx)\n", "SIOCDELMULTI", cmd); 2717 2718 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) { 2719 if (qlnx_set_multi(ha, 0)) 2720 ret = EINVAL; 2721 } 2722 break; 2723 2724 case SIOCSIFMEDIA: 2725 case SIOCGIFMEDIA: 2726 QL_DPRINT4(ha, "SIOCSIFMEDIA/SIOCGIFMEDIA (0x%lx)\n", cmd); 2727 2728 ret = ifmedia_ioctl(ifp, ifr, &ha->media, cmd); 2729 break; 2730 2731 case SIOCSIFCAP: 2732 2733 mask = ifr->ifr_reqcap ^ if_getcapenable(ifp); 2734 2735 QL_DPRINT4(ha, "SIOCSIFCAP (0x%lx)\n", cmd); 2736 2737 if (mask & IFCAP_HWCSUM) 2738 if_togglecapenable(ifp, IFCAP_HWCSUM); 2739 if (mask & IFCAP_TSO4) 2740 if_togglecapenable(ifp, IFCAP_TSO4); 2741 if (mask & IFCAP_TSO6) 2742 if_togglecapenable(ifp, IFCAP_TSO6); 2743 if (mask & IFCAP_VLAN_HWTAGGING) 2744 if_togglecapenable(ifp, IFCAP_VLAN_HWTAGGING); 2745 if (mask & IFCAP_VLAN_HWTSO) 2746 if_togglecapenable(ifp, IFCAP_VLAN_HWTSO); 2747 if (mask & IFCAP_LRO) 2748 if_togglecapenable(ifp, IFCAP_LRO); 2749 2750 QLNX_LOCK(ha); 2751 2752 if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) 2753 qlnx_init_locked(ha); 2754 2755 QLNX_UNLOCK(ha); 2756 2757 VLAN_CAPABILITIES(ifp); 2758 break; 2759 2760 case SIOCGI2C: 2761 { 2762 struct ifi2creq i2c; 2763 struct ecore_hwfn *p_hwfn = &ha->cdev.hwfns[0]; 2764 struct ecore_ptt *p_ptt; 2765 2766 ret = copyin(ifr_data_get_ptr(ifr), &i2c, sizeof(i2c)); 2767 2768 if (ret) 2769 break; 2770 2771 if ((i2c.len > sizeof (i2c.data)) || 2772 (i2c.dev_addr != 0xA0 && i2c.dev_addr != 0xA2)) { 2773 ret = EINVAL; 2774 break; 2775 } 2776 2777 p_ptt = ecore_ptt_acquire(p_hwfn); 2778 2779 if (!p_ptt) { 2780 QL_DPRINT1(ha, "ecore_ptt_acquire failed\n"); 2781 ret = -1; 2782 break; 2783 } 2784 2785 ret = ecore_mcp_phy_sfp_read(p_hwfn, p_ptt, 2786 (ha->pci_func & 0x1), i2c.dev_addr, i2c.offset, 2787 i2c.len, &i2c.data[0]); 2788 2789 ecore_ptt_release(p_hwfn, p_ptt); 2790 2791 if (ret) { 2792 ret = -1; 2793 break; 2794 } 2795 2796 ret = copyout(&i2c, ifr_data_get_ptr(ifr), sizeof(i2c)); 2797 2798 QL_DPRINT8(ha, "SIOCGI2C copyout ret = %d \ 2799 len = %d addr = 0x%02x offset = 0x%04x \ 2800 data[0..7]=0x%02x 0x%02x 0x%02x 0x%02x 0x%02x \ 2801 0x%02x 0x%02x 0x%02x\n", 2802 ret, i2c.len, i2c.dev_addr, i2c.offset, 2803 i2c.data[0], i2c.data[1], i2c.data[2], i2c.data[3], 2804 i2c.data[4], i2c.data[5], i2c.data[6], i2c.data[7]); 2805 break; 2806 } 2807 2808 default: 2809 QL_DPRINT4(ha, "default (0x%lx)\n", cmd); 2810 ret = ether_ioctl(ifp, cmd, data); 2811 break; 2812 } 2813 2814 return (ret); 2815 } 2816 2817 static int 2818 qlnx_media_change(if_t ifp) 2819 { 2820 qlnx_host_t *ha; 2821 struct ifmedia *ifm; 2822 int ret = 0; 2823 2824 ha = (qlnx_host_t *)if_getsoftc(ifp); 2825 2826 QL_DPRINT2(ha, "enter\n"); 2827 2828 ifm = &ha->media; 2829 2830 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 2831 ret = EINVAL; 2832 2833 QL_DPRINT2(ha, "exit\n"); 2834 2835 return (ret); 2836 } 2837 2838 static void 2839 qlnx_media_status(if_t ifp, struct ifmediareq *ifmr) 2840 { 2841 qlnx_host_t *ha; 2842 2843 ha = (qlnx_host_t *)if_getsoftc(ifp); 2844 2845 QL_DPRINT2(ha, "enter\n"); 2846 2847 ifmr->ifm_status = IFM_AVALID; 2848 ifmr->ifm_active = IFM_ETHER; 2849 2850 if (ha->link_up) { 2851 ifmr->ifm_status |= IFM_ACTIVE; 2852 ifmr->ifm_active |= 2853 (IFM_FDX | qlnx_get_optics(ha, &ha->if_link)); 2854 2855 if (ha->if_link.link_partner_caps & 2856 (QLNX_LINK_CAP_Pause | QLNX_LINK_CAP_Asym_Pause)) 2857 ifmr->ifm_active |= 2858 (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE); 2859 } 2860 2861 QL_DPRINT2(ha, "exit (%s)\n", (ha->link_up ? "link_up" : "link_down")); 2862 2863 return; 2864 } 2865 2866 static void 2867 qlnx_free_tx_pkt(qlnx_host_t *ha, struct qlnx_fastpath *fp, 2868 struct qlnx_tx_queue *txq) 2869 { 2870 u16 idx; 2871 struct mbuf *mp; 2872 bus_dmamap_t map; 2873 int i; 2874 // struct eth_tx_bd *tx_data_bd; 2875 struct eth_tx_1st_bd *first_bd; 2876 int nbds = 0; 2877 2878 idx = txq->sw_tx_cons; 2879 mp = txq->sw_tx_ring[idx].mp; 2880 map = txq->sw_tx_ring[idx].map; 2881 2882 if ((mp == NULL) || QL_ERR_INJECT(ha, QL_ERR_INJCT_TX_INT_MBUF_NULL)){ 2883 QL_RESET_ERR_INJECT(ha, QL_ERR_INJCT_TX_INT_MBUF_NULL); 2884 2885 QL_DPRINT1(ha, "(mp == NULL) " 2886 " tx_idx = 0x%x" 2887 " ecore_prod_idx = 0x%x" 2888 " ecore_cons_idx = 0x%x" 2889 " hw_bd_cons = 0x%x" 2890 " txq_db_last = 0x%x" 2891 " elem_left = 0x%x\n", 2892 fp->rss_id, 2893 ecore_chain_get_prod_idx(&txq->tx_pbl), 2894 ecore_chain_get_cons_idx(&txq->tx_pbl), 2895 le16toh(*txq->hw_cons_ptr), 2896 txq->tx_db.raw, 2897 ecore_chain_get_elem_left(&txq->tx_pbl)); 2898 2899 fp->err_tx_free_pkt_null++; 2900 2901 //DEBUG 2902 qlnx_trigger_dump(ha); 2903 2904 return; 2905 } else { 2906 QLNX_INC_OPACKETS((ha->ifp)); 2907 QLNX_INC_OBYTES((ha->ifp), (mp->m_pkthdr.len)); 2908 2909 bus_dmamap_sync(ha->tx_tag, map, BUS_DMASYNC_POSTWRITE); 2910 bus_dmamap_unload(ha->tx_tag, map); 2911 2912 fp->tx_pkts_freed++; 2913 fp->tx_pkts_completed++; 2914 2915 m_freem(mp); 2916 } 2917 2918 first_bd = (struct eth_tx_1st_bd *)ecore_chain_consume(&txq->tx_pbl); 2919 nbds = first_bd->data.nbds; 2920 2921 // BD_SET_UNMAP_ADDR_LEN(first_bd, 0, 0); 2922 2923 for (i = 1; i < nbds; i++) { 2924 /* tx_data_bd = */ ecore_chain_consume(&txq->tx_pbl); 2925 // BD_SET_UNMAP_ADDR_LEN(tx_data_bd, 0, 0); 2926 } 2927 txq->sw_tx_ring[idx].flags = 0; 2928 txq->sw_tx_ring[idx].mp = NULL; 2929 txq->sw_tx_ring[idx].map = (bus_dmamap_t)0; 2930 2931 return; 2932 } 2933 2934 static void 2935 qlnx_tx_int(qlnx_host_t *ha, struct qlnx_fastpath *fp, 2936 struct qlnx_tx_queue *txq) 2937 { 2938 u16 hw_bd_cons; 2939 u16 ecore_cons_idx; 2940 uint16_t diff; 2941 uint16_t idx, idx2; 2942 2943 hw_bd_cons = le16toh(*txq->hw_cons_ptr); 2944 2945 while (hw_bd_cons != 2946 (ecore_cons_idx = ecore_chain_get_cons_idx(&txq->tx_pbl))) { 2947 diff = hw_bd_cons - ecore_cons_idx; 2948 if ((diff > TX_RING_SIZE) || 2949 QL_ERR_INJECT(ha, QL_ERR_INJCT_TX_INT_DIFF)){ 2950 QL_RESET_ERR_INJECT(ha, QL_ERR_INJCT_TX_INT_DIFF); 2951 2952 QL_DPRINT1(ha, "(diff = 0x%x) " 2953 " tx_idx = 0x%x" 2954 " ecore_prod_idx = 0x%x" 2955 " ecore_cons_idx = 0x%x" 2956 " hw_bd_cons = 0x%x" 2957 " txq_db_last = 0x%x" 2958 " elem_left = 0x%x\n", 2959 diff, 2960 fp->rss_id, 2961 ecore_chain_get_prod_idx(&txq->tx_pbl), 2962 ecore_chain_get_cons_idx(&txq->tx_pbl), 2963 le16toh(*txq->hw_cons_ptr), 2964 txq->tx_db.raw, 2965 ecore_chain_get_elem_left(&txq->tx_pbl)); 2966 2967 fp->err_tx_cons_idx_conflict++; 2968 2969 //DEBUG 2970 qlnx_trigger_dump(ha); 2971 } 2972 2973 idx = (txq->sw_tx_cons + 1) & (TX_RING_SIZE - 1); 2974 idx2 = (txq->sw_tx_cons + 2) & (TX_RING_SIZE - 1); 2975 prefetch(txq->sw_tx_ring[idx].mp); 2976 prefetch(txq->sw_tx_ring[idx2].mp); 2977 2978 qlnx_free_tx_pkt(ha, fp, txq); 2979 2980 txq->sw_tx_cons = (txq->sw_tx_cons + 1) & (TX_RING_SIZE - 1); 2981 } 2982 return; 2983 } 2984 2985 static int 2986 qlnx_transmit_locked(if_t ifp, struct qlnx_fastpath *fp, struct mbuf *mp) 2987 { 2988 int ret = 0; 2989 struct qlnx_tx_queue *txq; 2990 qlnx_host_t * ha; 2991 uint16_t elem_left; 2992 2993 txq = fp->txq[0]; 2994 ha = (qlnx_host_t *)fp->edev; 2995 2996 if ((!(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) || (!ha->link_up)) { 2997 if(mp != NULL) 2998 ret = drbr_enqueue(ifp, fp->tx_br, mp); 2999 return (ret); 3000 } 3001 3002 if(mp != NULL) 3003 ret = drbr_enqueue(ifp, fp->tx_br, mp); 3004 3005 mp = drbr_peek(ifp, fp->tx_br); 3006 3007 while (mp != NULL) { 3008 if (qlnx_send(ha, fp, &mp)) { 3009 if (mp != NULL) { 3010 drbr_putback(ifp, fp->tx_br, mp); 3011 } else { 3012 fp->tx_pkts_processed++; 3013 drbr_advance(ifp, fp->tx_br); 3014 } 3015 goto qlnx_transmit_locked_exit; 3016 3017 } else { 3018 drbr_advance(ifp, fp->tx_br); 3019 fp->tx_pkts_transmitted++; 3020 fp->tx_pkts_processed++; 3021 } 3022 3023 mp = drbr_peek(ifp, fp->tx_br); 3024 } 3025 3026 qlnx_transmit_locked_exit: 3027 if((qlnx_num_tx_compl(ha,fp, fp->txq[0]) > QLNX_TX_COMPL_THRESH) || 3028 ((int)(elem_left = ecore_chain_get_elem_left(&txq->tx_pbl)) 3029 < QLNX_TX_ELEM_MAX_THRESH)) 3030 (void)qlnx_tx_int(ha, fp, fp->txq[0]); 3031 3032 QL_DPRINT2(ha, "%s: exit ret = %d\n", __func__, ret); 3033 return ret; 3034 } 3035 3036 static int 3037 qlnx_transmit(if_t ifp, struct mbuf *mp) 3038 { 3039 qlnx_host_t *ha = (qlnx_host_t *)if_getsoftc(ifp); 3040 struct qlnx_fastpath *fp; 3041 int rss_id = 0, ret = 0; 3042 3043 #ifdef QLNX_TRACEPERF_DATA 3044 uint64_t tx_pkts = 0, tx_compl = 0; 3045 #endif 3046 3047 QL_DPRINT2(ha, "enter\n"); 3048 3049 if (M_HASHTYPE_GET(mp) != M_HASHTYPE_NONE) 3050 rss_id = (mp->m_pkthdr.flowid % ECORE_RSS_IND_TABLE_SIZE) % 3051 ha->num_rss; 3052 3053 fp = &ha->fp_array[rss_id]; 3054 3055 if (fp->tx_br == NULL) { 3056 ret = EINVAL; 3057 goto qlnx_transmit_exit; 3058 } 3059 3060 if (mtx_trylock(&fp->tx_mtx)) { 3061 #ifdef QLNX_TRACEPERF_DATA 3062 tx_pkts = fp->tx_pkts_transmitted; 3063 tx_compl = fp->tx_pkts_completed; 3064 #endif 3065 3066 ret = qlnx_transmit_locked(ifp, fp, mp); 3067 3068 #ifdef QLNX_TRACEPERF_DATA 3069 fp->tx_pkts_trans_ctx += (fp->tx_pkts_transmitted - tx_pkts); 3070 fp->tx_pkts_compl_ctx += (fp->tx_pkts_completed - tx_compl); 3071 #endif 3072 mtx_unlock(&fp->tx_mtx); 3073 } else { 3074 if (mp != NULL && (fp->fp_taskqueue != NULL)) { 3075 ret = drbr_enqueue(ifp, fp->tx_br, mp); 3076 taskqueue_enqueue(fp->fp_taskqueue, &fp->fp_task); 3077 } 3078 } 3079 3080 qlnx_transmit_exit: 3081 3082 QL_DPRINT2(ha, "exit ret = %d\n", ret); 3083 return ret; 3084 } 3085 3086 static void 3087 qlnx_qflush(if_t ifp) 3088 { 3089 int rss_id; 3090 struct qlnx_fastpath *fp; 3091 struct mbuf *mp; 3092 qlnx_host_t *ha; 3093 3094 ha = (qlnx_host_t *)if_getsoftc(ifp); 3095 3096 QL_DPRINT2(ha, "enter\n"); 3097 3098 for (rss_id = 0; rss_id < ha->num_rss; rss_id++) { 3099 fp = &ha->fp_array[rss_id]; 3100 3101 if (fp == NULL) 3102 continue; 3103 3104 if (fp->tx_br) { 3105 mtx_lock(&fp->tx_mtx); 3106 3107 while ((mp = drbr_dequeue(ifp, fp->tx_br)) != NULL) { 3108 fp->tx_pkts_freed++; 3109 m_freem(mp); 3110 } 3111 mtx_unlock(&fp->tx_mtx); 3112 } 3113 } 3114 QL_DPRINT2(ha, "exit\n"); 3115 3116 return; 3117 } 3118 3119 static void 3120 qlnx_txq_doorbell_wr32(qlnx_host_t *ha, void *reg_addr, uint32_t value) 3121 { 3122 uint32_t offset; 3123 3124 offset = (uint32_t)((uint8_t *)reg_addr - (uint8_t *)ha->pci_dbells); 3125 3126 bus_write_4(ha->pci_dbells, offset, value); 3127 bus_barrier(ha->pci_reg, 0, 0, BUS_SPACE_BARRIER_READ); 3128 bus_barrier(ha->pci_dbells, 0, 0, BUS_SPACE_BARRIER_READ); 3129 3130 return; 3131 } 3132 3133 static uint32_t 3134 qlnx_tcp_offset(qlnx_host_t *ha, struct mbuf *mp) 3135 { 3136 struct ether_vlan_header *eh = NULL; 3137 struct ip *ip = NULL; 3138 struct ip6_hdr *ip6 = NULL; 3139 struct tcphdr *th = NULL; 3140 uint32_t ehdrlen = 0, ip_hlen = 0, offset = 0; 3141 uint16_t etype = 0; 3142 uint8_t buf[sizeof(struct ip6_hdr)]; 3143 3144 eh = mtod(mp, struct ether_vlan_header *); 3145 3146 if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) { 3147 ehdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; 3148 etype = ntohs(eh->evl_proto); 3149 } else { 3150 ehdrlen = ETHER_HDR_LEN; 3151 etype = ntohs(eh->evl_encap_proto); 3152 } 3153 3154 switch (etype) { 3155 case ETHERTYPE_IP: 3156 ip = (struct ip *)(mp->m_data + ehdrlen); 3157 3158 ip_hlen = sizeof (struct ip); 3159 3160 if (mp->m_len < (ehdrlen + ip_hlen)) { 3161 m_copydata(mp, ehdrlen, sizeof(struct ip), buf); 3162 ip = (struct ip *)buf; 3163 } 3164 3165 th = (struct tcphdr *)(ip + 1); 3166 offset = ip_hlen + ehdrlen + (th->th_off << 2); 3167 break; 3168 3169 case ETHERTYPE_IPV6: 3170 ip6 = (struct ip6_hdr *)(mp->m_data + ehdrlen); 3171 3172 ip_hlen = sizeof(struct ip6_hdr); 3173 3174 if (mp->m_len < (ehdrlen + ip_hlen)) { 3175 m_copydata(mp, ehdrlen, sizeof (struct ip6_hdr), 3176 buf); 3177 ip6 = (struct ip6_hdr *)buf; 3178 } 3179 th = (struct tcphdr *)(ip6 + 1); 3180 offset = ip_hlen + ehdrlen + (th->th_off << 2); 3181 break; 3182 3183 default: 3184 break; 3185 } 3186 3187 return (offset); 3188 } 3189 3190 static __inline int 3191 qlnx_tso_check(struct qlnx_fastpath *fp, bus_dma_segment_t *segs, int nsegs, 3192 uint32_t offset) 3193 { 3194 int i; 3195 uint32_t sum, nbds_in_hdr = 1; 3196 uint32_t window; 3197 bus_dma_segment_t *s_seg; 3198 3199 /* If the header spans multiple segments, skip those segments */ 3200 3201 if (nsegs < ETH_TX_LSO_WINDOW_BDS_NUM) 3202 return (0); 3203 3204 i = 0; 3205 3206 while ((i < nsegs) && (offset >= segs->ds_len)) { 3207 offset = offset - segs->ds_len; 3208 segs++; 3209 i++; 3210 nbds_in_hdr++; 3211 } 3212 3213 window = ETH_TX_LSO_WINDOW_BDS_NUM - nbds_in_hdr; 3214 3215 nsegs = nsegs - i; 3216 3217 while (nsegs >= window) { 3218 sum = 0; 3219 s_seg = segs; 3220 3221 for (i = 0; i < window; i++){ 3222 sum += s_seg->ds_len; 3223 s_seg++; 3224 } 3225 3226 if (sum < ETH_TX_LSO_WINDOW_MIN_LEN) { 3227 fp->tx_lso_wnd_min_len++; 3228 return (-1); 3229 } 3230 3231 nsegs = nsegs - 1; 3232 segs++; 3233 } 3234 3235 return (0); 3236 } 3237 3238 static int 3239 qlnx_send(qlnx_host_t *ha, struct qlnx_fastpath *fp, struct mbuf **m_headp) 3240 { 3241 bus_dma_segment_t *segs; 3242 bus_dmamap_t map = 0; 3243 uint32_t nsegs = 0; 3244 int ret = -1; 3245 struct mbuf *m_head = *m_headp; 3246 uint16_t idx = 0; 3247 uint16_t elem_left; 3248 3249 uint8_t nbd = 0; 3250 struct qlnx_tx_queue *txq; 3251 3252 struct eth_tx_1st_bd *first_bd; 3253 struct eth_tx_2nd_bd *second_bd; 3254 struct eth_tx_3rd_bd *third_bd; 3255 struct eth_tx_bd *tx_data_bd; 3256 3257 int seg_idx = 0; 3258 uint32_t nbds_in_hdr = 0; 3259 uint32_t offset = 0; 3260 3261 #ifdef QLNX_TRACE_PERF_DATA 3262 uint16_t bd_used; 3263 #endif 3264 3265 QL_DPRINT8(ha, "enter[%d]\n", fp->rss_id); 3266 3267 if (!ha->link_up) 3268 return (-1); 3269 3270 first_bd = NULL; 3271 second_bd = NULL; 3272 third_bd = NULL; 3273 tx_data_bd = NULL; 3274 3275 txq = fp->txq[0]; 3276 3277 if ((int)(elem_left = ecore_chain_get_elem_left(&txq->tx_pbl)) < 3278 QLNX_TX_ELEM_MIN_THRESH) { 3279 fp->tx_nsegs_gt_elem_left++; 3280 fp->err_tx_nsegs_gt_elem_left++; 3281 3282 return (ENOBUFS); 3283 } 3284 3285 idx = txq->sw_tx_prod; 3286 3287 map = txq->sw_tx_ring[idx].map; 3288 segs = txq->segs; 3289 3290 ret = bus_dmamap_load_mbuf_sg(ha->tx_tag, map, m_head, segs, &nsegs, 3291 BUS_DMA_NOWAIT); 3292 3293 if (ha->dbg_trace_tso_pkt_len) { 3294 if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { 3295 if (!fp->tx_tso_min_pkt_len) { 3296 fp->tx_tso_min_pkt_len = m_head->m_pkthdr.len; 3297 fp->tx_tso_min_pkt_len = m_head->m_pkthdr.len; 3298 } else { 3299 if (fp->tx_tso_min_pkt_len > m_head->m_pkthdr.len) 3300 fp->tx_tso_min_pkt_len = 3301 m_head->m_pkthdr.len; 3302 if (fp->tx_tso_max_pkt_len < m_head->m_pkthdr.len) 3303 fp->tx_tso_max_pkt_len = 3304 m_head->m_pkthdr.len; 3305 } 3306 } 3307 } 3308 3309 if (m_head->m_pkthdr.csum_flags & CSUM_TSO) 3310 offset = qlnx_tcp_offset(ha, m_head); 3311 3312 if ((ret == EFBIG) || 3313 ((nsegs > QLNX_MAX_SEGMENTS_NON_TSO) && ( 3314 (!(m_head->m_pkthdr.csum_flags & CSUM_TSO)) || 3315 ((m_head->m_pkthdr.csum_flags & CSUM_TSO) && 3316 qlnx_tso_check(fp, segs, nsegs, offset))))) { 3317 struct mbuf *m; 3318 3319 QL_DPRINT8(ha, "EFBIG [%d]\n", m_head->m_pkthdr.len); 3320 3321 fp->tx_defrag++; 3322 3323 m = m_defrag(m_head, M_NOWAIT); 3324 if (m == NULL) { 3325 fp->err_tx_defrag++; 3326 fp->tx_pkts_freed++; 3327 m_freem(m_head); 3328 *m_headp = NULL; 3329 QL_DPRINT1(ha, "m_defrag() = NULL [%d]\n", ret); 3330 return (ENOBUFS); 3331 } 3332 3333 m_head = m; 3334 *m_headp = m_head; 3335 3336 if ((ret = bus_dmamap_load_mbuf_sg(ha->tx_tag, map, m_head, 3337 segs, &nsegs, BUS_DMA_NOWAIT))) { 3338 fp->err_tx_defrag_dmamap_load++; 3339 3340 QL_DPRINT1(ha, 3341 "bus_dmamap_load_mbuf_sg failed0 [%d, %d]\n", 3342 ret, m_head->m_pkthdr.len); 3343 3344 fp->tx_pkts_freed++; 3345 m_freem(m_head); 3346 *m_headp = NULL; 3347 3348 return (ret); 3349 } 3350 3351 if ((nsegs > QLNX_MAX_SEGMENTS_NON_TSO) && 3352 !(m_head->m_pkthdr.csum_flags & CSUM_TSO)) { 3353 fp->err_tx_non_tso_max_seg++; 3354 3355 QL_DPRINT1(ha, 3356 "(%d) nsegs too many for non-TSO [%d, %d]\n", 3357 ret, nsegs, m_head->m_pkthdr.len); 3358 3359 fp->tx_pkts_freed++; 3360 m_freem(m_head); 3361 *m_headp = NULL; 3362 3363 return (ret); 3364 } 3365 if (m_head->m_pkthdr.csum_flags & CSUM_TSO) 3366 offset = qlnx_tcp_offset(ha, m_head); 3367 3368 } else if (ret) { 3369 fp->err_tx_dmamap_load++; 3370 3371 QL_DPRINT1(ha, "bus_dmamap_load_mbuf_sg failed1 [%d, %d]\n", 3372 ret, m_head->m_pkthdr.len); 3373 fp->tx_pkts_freed++; 3374 m_freem(m_head); 3375 *m_headp = NULL; 3376 return (ret); 3377 } 3378 3379 QL_ASSERT(ha, (nsegs != 0), ("qlnx_send: empty packet")); 3380 3381 if (ha->dbg_trace_tso_pkt_len) { 3382 if (nsegs < QLNX_FP_MAX_SEGS) 3383 fp->tx_pkts[(nsegs - 1)]++; 3384 else 3385 fp->tx_pkts[(QLNX_FP_MAX_SEGS - 1)]++; 3386 } 3387 3388 #ifdef QLNX_TRACE_PERF_DATA 3389 if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { 3390 if(m_head->m_pkthdr.len <= 2048) 3391 fp->tx_pkts_hist[0]++; 3392 else if((m_head->m_pkthdr.len > 2048) && 3393 (m_head->m_pkthdr.len <= 4096)) 3394 fp->tx_pkts_hist[1]++; 3395 else if((m_head->m_pkthdr.len > 4096) && 3396 (m_head->m_pkthdr.len <= 8192)) 3397 fp->tx_pkts_hist[2]++; 3398 else if((m_head->m_pkthdr.len > 8192) && 3399 (m_head->m_pkthdr.len <= 12288 )) 3400 fp->tx_pkts_hist[3]++; 3401 else if((m_head->m_pkthdr.len > 11288) && 3402 (m_head->m_pkthdr.len <= 16394)) 3403 fp->tx_pkts_hist[4]++; 3404 else if((m_head->m_pkthdr.len > 16384) && 3405 (m_head->m_pkthdr.len <= 20480)) 3406 fp->tx_pkts_hist[5]++; 3407 else if((m_head->m_pkthdr.len > 20480) && 3408 (m_head->m_pkthdr.len <= 24576)) 3409 fp->tx_pkts_hist[6]++; 3410 else if((m_head->m_pkthdr.len > 24576) && 3411 (m_head->m_pkthdr.len <= 28672)) 3412 fp->tx_pkts_hist[7]++; 3413 else if((m_head->m_pkthdr.len > 28762) && 3414 (m_head->m_pkthdr.len <= 32768)) 3415 fp->tx_pkts_hist[8]++; 3416 else if((m_head->m_pkthdr.len > 32768) && 3417 (m_head->m_pkthdr.len <= 36864)) 3418 fp->tx_pkts_hist[9]++; 3419 else if((m_head->m_pkthdr.len > 36864) && 3420 (m_head->m_pkthdr.len <= 40960)) 3421 fp->tx_pkts_hist[10]++; 3422 else if((m_head->m_pkthdr.len > 40960) && 3423 (m_head->m_pkthdr.len <= 45056)) 3424 fp->tx_pkts_hist[11]++; 3425 else if((m_head->m_pkthdr.len > 45056) && 3426 (m_head->m_pkthdr.len <= 49152)) 3427 fp->tx_pkts_hist[12]++; 3428 else if((m_head->m_pkthdr.len > 49512) && 3429 m_head->m_pkthdr.len <= 53248)) 3430 fp->tx_pkts_hist[13]++; 3431 else if((m_head->m_pkthdr.len > 53248) && 3432 (m_head->m_pkthdr.len <= 57344)) 3433 fp->tx_pkts_hist[14]++; 3434 else if((m_head->m_pkthdr.len > 53248) && 3435 (m_head->m_pkthdr.len <= 57344)) 3436 fp->tx_pkts_hist[15]++; 3437 else if((m_head->m_pkthdr.len > 57344) && 3438 (m_head->m_pkthdr.len <= 61440)) 3439 fp->tx_pkts_hist[16]++; 3440 else 3441 fp->tx_pkts_hist[17]++; 3442 } 3443 3444 if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { 3445 elem_left = ecore_chain_get_elem_left(&txq->tx_pbl); 3446 bd_used = TX_RING_SIZE - elem_left; 3447 3448 if(bd_used <= 100) 3449 fp->tx_pkts_q[0]++; 3450 else if((bd_used > 100) && (bd_used <= 500)) 3451 fp->tx_pkts_q[1]++; 3452 else if((bd_used > 500) && (bd_used <= 1000)) 3453 fp->tx_pkts_q[2]++; 3454 else if((bd_used > 1000) && (bd_used <= 2000)) 3455 fp->tx_pkts_q[3]++; 3456 else if((bd_used > 3000) && (bd_used <= 4000)) 3457 fp->tx_pkts_q[4]++; 3458 else if((bd_used > 4000) && (bd_used <= 5000)) 3459 fp->tx_pkts_q[5]++; 3460 else if((bd_used > 6000) && (bd_used <= 7000)) 3461 fp->tx_pkts_q[6]++; 3462 else if((bd_used > 7000) && (bd_used <= 8000)) 3463 fp->tx_pkts_q[7]++; 3464 else if((bd_used > 8000) && (bd_used <= 9000)) 3465 fp->tx_pkts_q[8]++; 3466 else if((bd_used > 9000) && (bd_used <= 10000)) 3467 fp->tx_pkts_q[9]++; 3468 else if((bd_used > 10000) && (bd_used <= 11000)) 3469 fp->tx_pkts_q[10]++; 3470 else if((bd_used > 11000) && (bd_used <= 12000)) 3471 fp->tx_pkts_q[11]++; 3472 else if((bd_used > 12000) && (bd_used <= 13000)) 3473 fp->tx_pkts_q[12]++; 3474 else if((bd_used > 13000) && (bd_used <= 14000)) 3475 fp->tx_pkts_q[13]++; 3476 else if((bd_used > 14000) && (bd_used <= 15000)) 3477 fp->tx_pkts_q[14]++; 3478 else if((bd_used > 15000) && (bd_used <= 16000)) 3479 fp->tx_pkts_q[15]++; 3480 else 3481 fp->tx_pkts_q[16]++; 3482 } 3483 3484 #endif /* end of QLNX_TRACE_PERF_DATA */ 3485 3486 if ((nsegs + QLNX_TX_ELEM_RESERVE) > 3487 (int)(elem_left = ecore_chain_get_elem_left(&txq->tx_pbl))) { 3488 QL_DPRINT1(ha, "(%d, 0x%x) insuffient BDs" 3489 " in chain[%d] trying to free packets\n", 3490 nsegs, elem_left, fp->rss_id); 3491 3492 fp->tx_nsegs_gt_elem_left++; 3493 3494 (void)qlnx_tx_int(ha, fp, txq); 3495 3496 if ((nsegs + QLNX_TX_ELEM_RESERVE) > (int)(elem_left = 3497 ecore_chain_get_elem_left(&txq->tx_pbl))) { 3498 QL_DPRINT1(ha, 3499 "(%d, 0x%x) insuffient BDs in chain[%d]\n", 3500 nsegs, elem_left, fp->rss_id); 3501 3502 fp->err_tx_nsegs_gt_elem_left++; 3503 fp->tx_ring_full = 1; 3504 if (ha->storm_stats_enable) 3505 ha->storm_stats_gather = 1; 3506 return (ENOBUFS); 3507 } 3508 } 3509 3510 bus_dmamap_sync(ha->tx_tag, map, BUS_DMASYNC_PREWRITE); 3511 3512 txq->sw_tx_ring[idx].mp = m_head; 3513 3514 first_bd = (struct eth_tx_1st_bd *)ecore_chain_produce(&txq->tx_pbl); 3515 3516 memset(first_bd, 0, sizeof(*first_bd)); 3517 3518 first_bd->data.bd_flags.bitfields = 3519 1 << ETH_TX_1ST_BD_FLAGS_START_BD_SHIFT; 3520 3521 BD_SET_UNMAP_ADDR_LEN(first_bd, segs->ds_addr, segs->ds_len); 3522 3523 nbd++; 3524 3525 if (m_head->m_pkthdr.csum_flags & CSUM_IP) { 3526 first_bd->data.bd_flags.bitfields |= 3527 (1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT); 3528 } 3529 3530 if (m_head->m_pkthdr.csum_flags & 3531 (CSUM_UDP | CSUM_TCP | CSUM_TCP_IPV6 | CSUM_UDP_IPV6)) { 3532 first_bd->data.bd_flags.bitfields |= 3533 (1 << ETH_TX_1ST_BD_FLAGS_L4_CSUM_SHIFT); 3534 } 3535 3536 if (m_head->m_flags & M_VLANTAG) { 3537 first_bd->data.vlan = m_head->m_pkthdr.ether_vtag; 3538 first_bd->data.bd_flags.bitfields |= 3539 (1 << ETH_TX_1ST_BD_FLAGS_VLAN_INSERTION_SHIFT); 3540 } 3541 3542 if (m_head->m_pkthdr.csum_flags & CSUM_TSO) { 3543 first_bd->data.bd_flags.bitfields |= 3544 (1 << ETH_TX_1ST_BD_FLAGS_LSO_SHIFT); 3545 first_bd->data.bd_flags.bitfields |= 3546 (1 << ETH_TX_1ST_BD_FLAGS_IP_CSUM_SHIFT); 3547 3548 nbds_in_hdr = 1; 3549 3550 if (offset == segs->ds_len) { 3551 BD_SET_UNMAP_ADDR_LEN(first_bd, segs->ds_addr, offset); 3552 segs++; 3553 seg_idx++; 3554 3555 second_bd = (struct eth_tx_2nd_bd *) 3556 ecore_chain_produce(&txq->tx_pbl); 3557 memset(second_bd, 0, sizeof(*second_bd)); 3558 nbd++; 3559 3560 if (seg_idx < nsegs) { 3561 BD_SET_UNMAP_ADDR_LEN(second_bd, \ 3562 (segs->ds_addr), (segs->ds_len)); 3563 segs++; 3564 seg_idx++; 3565 } 3566 3567 third_bd = (struct eth_tx_3rd_bd *) 3568 ecore_chain_produce(&txq->tx_pbl); 3569 memset(third_bd, 0, sizeof(*third_bd)); 3570 third_bd->data.lso_mss = m_head->m_pkthdr.tso_segsz; 3571 third_bd->data.bitfields |= 3572 (nbds_in_hdr<<ETH_TX_DATA_3RD_BD_HDR_NBD_SHIFT); 3573 nbd++; 3574 3575 if (seg_idx < nsegs) { 3576 BD_SET_UNMAP_ADDR_LEN(third_bd, \ 3577 (segs->ds_addr), (segs->ds_len)); 3578 segs++; 3579 seg_idx++; 3580 } 3581 3582 for (; seg_idx < nsegs; seg_idx++) { 3583 tx_data_bd = (struct eth_tx_bd *) 3584 ecore_chain_produce(&txq->tx_pbl); 3585 memset(tx_data_bd, 0, sizeof(*tx_data_bd)); 3586 BD_SET_UNMAP_ADDR_LEN(tx_data_bd, \ 3587 segs->ds_addr,\ 3588 segs->ds_len); 3589 segs++; 3590 nbd++; 3591 } 3592 3593 } else if (offset < segs->ds_len) { 3594 BD_SET_UNMAP_ADDR_LEN(first_bd, segs->ds_addr, offset); 3595 3596 second_bd = (struct eth_tx_2nd_bd *) 3597 ecore_chain_produce(&txq->tx_pbl); 3598 memset(second_bd, 0, sizeof(*second_bd)); 3599 BD_SET_UNMAP_ADDR_LEN(second_bd, \ 3600 (segs->ds_addr + offset),\ 3601 (segs->ds_len - offset)); 3602 nbd++; 3603 segs++; 3604 3605 third_bd = (struct eth_tx_3rd_bd *) 3606 ecore_chain_produce(&txq->tx_pbl); 3607 memset(third_bd, 0, sizeof(*third_bd)); 3608 3609 BD_SET_UNMAP_ADDR_LEN(third_bd, \ 3610 segs->ds_addr,\ 3611 segs->ds_len); 3612 third_bd->data.lso_mss = m_head->m_pkthdr.tso_segsz; 3613 third_bd->data.bitfields |= 3614 (nbds_in_hdr<<ETH_TX_DATA_3RD_BD_HDR_NBD_SHIFT); 3615 segs++; 3616 nbd++; 3617 3618 for (seg_idx = 2; seg_idx < nsegs; seg_idx++) { 3619 tx_data_bd = (struct eth_tx_bd *) 3620 ecore_chain_produce(&txq->tx_pbl); 3621 memset(tx_data_bd, 0, sizeof(*tx_data_bd)); 3622 BD_SET_UNMAP_ADDR_LEN(tx_data_bd, \ 3623 segs->ds_addr,\ 3624 segs->ds_len); 3625 segs++; 3626 nbd++; 3627 } 3628 3629 } else { 3630 offset = offset - segs->ds_len; 3631 segs++; 3632 3633 for (seg_idx = 1; seg_idx < nsegs; seg_idx++) { 3634 if (offset) 3635 nbds_in_hdr++; 3636 3637 tx_data_bd = (struct eth_tx_bd *) 3638 ecore_chain_produce(&txq->tx_pbl); 3639 memset(tx_data_bd, 0, sizeof(*tx_data_bd)); 3640 3641 if (second_bd == NULL) { 3642 second_bd = (struct eth_tx_2nd_bd *) 3643 tx_data_bd; 3644 } else if (third_bd == NULL) { 3645 third_bd = (struct eth_tx_3rd_bd *) 3646 tx_data_bd; 3647 } 3648 3649 if (offset && (offset < segs->ds_len)) { 3650 BD_SET_UNMAP_ADDR_LEN(tx_data_bd,\ 3651 segs->ds_addr, offset); 3652 3653 tx_data_bd = (struct eth_tx_bd *) 3654 ecore_chain_produce(&txq->tx_pbl); 3655 3656 memset(tx_data_bd, 0, 3657 sizeof(*tx_data_bd)); 3658 3659 if (second_bd == NULL) { 3660 second_bd = 3661 (struct eth_tx_2nd_bd *)tx_data_bd; 3662 } else if (third_bd == NULL) { 3663 third_bd = 3664 (struct eth_tx_3rd_bd *)tx_data_bd; 3665 } 3666 BD_SET_UNMAP_ADDR_LEN(tx_data_bd,\ 3667 (segs->ds_addr + offset), \ 3668 (segs->ds_len - offset)); 3669 nbd++; 3670 offset = 0; 3671 } else { 3672 if (offset) 3673 offset = offset - segs->ds_len; 3674 BD_SET_UNMAP_ADDR_LEN(tx_data_bd,\ 3675 segs->ds_addr, segs->ds_len); 3676 } 3677 segs++; 3678 nbd++; 3679 } 3680 3681 if (third_bd == NULL) { 3682 third_bd = (struct eth_tx_3rd_bd *) 3683 ecore_chain_produce(&txq->tx_pbl); 3684 memset(third_bd, 0, sizeof(*third_bd)); 3685 } 3686 3687 third_bd->data.lso_mss = m_head->m_pkthdr.tso_segsz; 3688 third_bd->data.bitfields |= 3689 (nbds_in_hdr<<ETH_TX_DATA_3RD_BD_HDR_NBD_SHIFT); 3690 } 3691 fp->tx_tso_pkts++; 3692 } else { 3693 segs++; 3694 for (seg_idx = 1; seg_idx < nsegs; seg_idx++) { 3695 tx_data_bd = (struct eth_tx_bd *) 3696 ecore_chain_produce(&txq->tx_pbl); 3697 memset(tx_data_bd, 0, sizeof(*tx_data_bd)); 3698 BD_SET_UNMAP_ADDR_LEN(tx_data_bd, segs->ds_addr,\ 3699 segs->ds_len); 3700 segs++; 3701 nbd++; 3702 } 3703 first_bd->data.bitfields = 3704 (m_head->m_pkthdr.len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) 3705 << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT; 3706 first_bd->data.bitfields = 3707 htole16(first_bd->data.bitfields); 3708 fp->tx_non_tso_pkts++; 3709 } 3710 3711 first_bd->data.nbds = nbd; 3712 3713 if (ha->dbg_trace_tso_pkt_len) { 3714 if (fp->tx_tso_max_nsegs < nsegs) 3715 fp->tx_tso_max_nsegs = nsegs; 3716 3717 if ((nsegs < fp->tx_tso_min_nsegs) || (!fp->tx_tso_min_nsegs)) 3718 fp->tx_tso_min_nsegs = nsegs; 3719 } 3720 3721 txq->sw_tx_ring[idx].nsegs = nsegs; 3722 txq->sw_tx_prod = (txq->sw_tx_prod + 1) & (TX_RING_SIZE - 1); 3723 3724 txq->tx_db.data.bd_prod = 3725 htole16(ecore_chain_get_prod_idx(&txq->tx_pbl)); 3726 3727 qlnx_txq_doorbell_wr32(ha, txq->doorbell_addr, txq->tx_db.raw); 3728 3729 QL_DPRINT8(ha, "exit[%d]\n", fp->rss_id); 3730 return (0); 3731 } 3732 3733 static void 3734 qlnx_stop(qlnx_host_t *ha) 3735 { 3736 if_t ifp = ha->ifp; 3737 int i; 3738 3739 if_setdrvflagbits(ifp, 0, (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)); 3740 3741 /* 3742 * We simply lock and unlock each fp->tx_mtx to 3743 * propagate the if_drv_flags 3744 * state to each tx thread 3745 */ 3746 QL_DPRINT1(ha, "QLNX STATE = %d\n",ha->state); 3747 3748 if (ha->state == QLNX_STATE_OPEN) { 3749 for (i = 0; i < ha->num_rss; i++) { 3750 struct qlnx_fastpath *fp = &ha->fp_array[i]; 3751 3752 mtx_lock(&fp->tx_mtx); 3753 mtx_unlock(&fp->tx_mtx); 3754 3755 if (fp->fp_taskqueue != NULL) 3756 taskqueue_enqueue(fp->fp_taskqueue, 3757 &fp->fp_task); 3758 } 3759 } 3760 #ifdef QLNX_ENABLE_IWARP 3761 if (qlnx_vf_device(ha) != 0) { 3762 qlnx_rdma_dev_close(ha); 3763 } 3764 #endif /* #ifdef QLNX_ENABLE_IWARP */ 3765 3766 qlnx_unload(ha); 3767 3768 return; 3769 } 3770 3771 static int 3772 qlnx_get_ifq_snd_maxlen(qlnx_host_t *ha) 3773 { 3774 return(TX_RING_SIZE - 1); 3775 } 3776 3777 uint8_t * 3778 qlnx_get_mac_addr(qlnx_host_t *ha) 3779 { 3780 struct ecore_hwfn *p_hwfn; 3781 unsigned char mac[ETHER_ADDR_LEN]; 3782 uint8_t p_is_forced; 3783 3784 p_hwfn = &ha->cdev.hwfns[0]; 3785 3786 if (qlnx_vf_device(ha) != 0) 3787 return (p_hwfn->hw_info.hw_mac_addr); 3788 3789 ecore_vf_read_bulletin(p_hwfn, &p_is_forced); 3790 if (ecore_vf_bulletin_get_forced_mac(p_hwfn, mac, &p_is_forced) == 3791 true) { 3792 device_printf(ha->pci_dev, "%s: p_is_forced = %d" 3793 " mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n", __func__, 3794 p_is_forced, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 3795 memcpy(ha->primary_mac, mac, ETH_ALEN); 3796 } 3797 3798 return (ha->primary_mac); 3799 } 3800 3801 static uint32_t 3802 qlnx_get_optics(qlnx_host_t *ha, struct qlnx_link_output *if_link) 3803 { 3804 uint32_t ifm_type = 0; 3805 3806 switch (if_link->media_type) { 3807 case MEDIA_MODULE_FIBER: 3808 case MEDIA_UNSPECIFIED: 3809 if (if_link->speed == (100 * 1000)) 3810 ifm_type = QLNX_IFM_100G_SR4; 3811 else if (if_link->speed == (40 * 1000)) 3812 ifm_type = IFM_40G_SR4; 3813 else if (if_link->speed == (25 * 1000)) 3814 ifm_type = QLNX_IFM_25G_SR; 3815 else if (if_link->speed == (10 * 1000)) 3816 ifm_type = (IFM_10G_LR | IFM_10G_SR); 3817 else if (if_link->speed == (1 * 1000)) 3818 ifm_type = (IFM_1000_SX | IFM_1000_LX); 3819 3820 break; 3821 3822 case MEDIA_DA_TWINAX: 3823 if (if_link->speed == (100 * 1000)) 3824 ifm_type = QLNX_IFM_100G_CR4; 3825 else if (if_link->speed == (40 * 1000)) 3826 ifm_type = IFM_40G_CR4; 3827 else if (if_link->speed == (25 * 1000)) 3828 ifm_type = QLNX_IFM_25G_CR; 3829 else if (if_link->speed == (10 * 1000)) 3830 ifm_type = IFM_10G_TWINAX; 3831 3832 break; 3833 3834 default : 3835 ifm_type = IFM_UNKNOWN; 3836 break; 3837 } 3838 return (ifm_type); 3839 } 3840 3841 /***************************************************************************** 3842 * Interrupt Service Functions 3843 *****************************************************************************/ 3844 3845 static int 3846 qlnx_rx_jumbo_chain(qlnx_host_t *ha, struct qlnx_fastpath *fp, 3847 struct mbuf *mp_head, uint16_t len) 3848 { 3849 struct mbuf *mp, *mpf, *mpl; 3850 struct sw_rx_data *sw_rx_data; 3851 struct qlnx_rx_queue *rxq; 3852 uint16_t len_in_buffer; 3853 3854 rxq = fp->rxq; 3855 mpf = mpl = mp = NULL; 3856 3857 while (len) { 3858 rxq->sw_rx_cons = (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 3859 3860 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_cons]; 3861 mp = sw_rx_data->data; 3862 3863 if (mp == NULL) { 3864 QL_DPRINT1(ha, "mp = NULL\n"); 3865 fp->err_rx_mp_null++; 3866 rxq->sw_rx_cons = 3867 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 3868 3869 if (mpf != NULL) 3870 m_freem(mpf); 3871 3872 return (-1); 3873 } 3874 bus_dmamap_sync(ha->rx_tag, sw_rx_data->map, 3875 BUS_DMASYNC_POSTREAD); 3876 3877 if (qlnx_alloc_rx_buffer(ha, rxq) != 0) { 3878 QL_DPRINT1(ha, "New buffer allocation failed, dropping" 3879 " incoming packet and reusing its buffer\n"); 3880 3881 qlnx_reuse_rx_data(rxq); 3882 fp->err_rx_alloc_errors++; 3883 3884 if (mpf != NULL) 3885 m_freem(mpf); 3886 3887 return (-1); 3888 } 3889 ecore_chain_consume(&rxq->rx_bd_ring); 3890 3891 if (len > rxq->rx_buf_size) 3892 len_in_buffer = rxq->rx_buf_size; 3893 else 3894 len_in_buffer = len; 3895 3896 len = len - len_in_buffer; 3897 3898 mp->m_flags &= ~M_PKTHDR; 3899 mp->m_next = NULL; 3900 mp->m_len = len_in_buffer; 3901 3902 if (mpf == NULL) 3903 mpf = mpl = mp; 3904 else { 3905 mpl->m_next = mp; 3906 mpl = mp; 3907 } 3908 } 3909 3910 if (mpf != NULL) 3911 mp_head->m_next = mpf; 3912 3913 return (0); 3914 } 3915 3916 static void 3917 qlnx_tpa_start(qlnx_host_t *ha, 3918 struct qlnx_fastpath *fp, 3919 struct qlnx_rx_queue *rxq, 3920 struct eth_fast_path_rx_tpa_start_cqe *cqe) 3921 { 3922 uint32_t agg_index; 3923 if_t ifp = ha->ifp; 3924 struct mbuf *mp; 3925 struct mbuf *mpf = NULL, *mpl = NULL, *mpc = NULL; 3926 struct sw_rx_data *sw_rx_data; 3927 dma_addr_t addr; 3928 bus_dmamap_t map; 3929 struct eth_rx_bd *rx_bd; 3930 int i; 3931 uint8_t hash_type; 3932 3933 agg_index = cqe->tpa_agg_index; 3934 3935 QL_DPRINT7(ha, "[rss_id = %d]: enter\n \ 3936 \t type = 0x%x\n \ 3937 \t bitfields = 0x%x\n \ 3938 \t seg_len = 0x%x\n \ 3939 \t pars_flags = 0x%x\n \ 3940 \t vlan_tag = 0x%x\n \ 3941 \t rss_hash = 0x%x\n \ 3942 \t len_on_first_bd = 0x%x\n \ 3943 \t placement_offset = 0x%x\n \ 3944 \t tpa_agg_index = 0x%x\n \ 3945 \t header_len = 0x%x\n \ 3946 \t ext_bd_len_list[0] = 0x%x\n \ 3947 \t ext_bd_len_list[1] = 0x%x\n \ 3948 \t ext_bd_len_list[2] = 0x%x\n \ 3949 \t ext_bd_len_list[3] = 0x%x\n \ 3950 \t ext_bd_len_list[4] = 0x%x\n", 3951 fp->rss_id, cqe->type, cqe->bitfields, cqe->seg_len, 3952 cqe->pars_flags.flags, cqe->vlan_tag, 3953 cqe->rss_hash, cqe->len_on_first_bd, cqe->placement_offset, 3954 cqe->tpa_agg_index, cqe->header_len, 3955 cqe->ext_bd_len_list[0], cqe->ext_bd_len_list[1], 3956 cqe->ext_bd_len_list[2], cqe->ext_bd_len_list[3], 3957 cqe->ext_bd_len_list[4]); 3958 3959 if (agg_index >= ETH_TPA_MAX_AGGS_NUM) { 3960 fp->err_rx_tpa_invalid_agg_num++; 3961 return; 3962 } 3963 3964 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_cons]; 3965 bus_dmamap_sync(ha->rx_tag, sw_rx_data->map, BUS_DMASYNC_POSTREAD); 3966 mp = sw_rx_data->data; 3967 3968 QL_DPRINT7(ha, "[rss_id = %d]: mp = %p \n ", fp->rss_id, mp); 3969 3970 if (mp == NULL) { 3971 QL_DPRINT7(ha, "[%d]: mp = NULL\n", fp->rss_id); 3972 fp->err_rx_mp_null++; 3973 rxq->sw_rx_cons = (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 3974 3975 return; 3976 } 3977 3978 if ((le16toh(cqe->pars_flags.flags)) & CQE_FLAGS_ERR) { 3979 QL_DPRINT7(ha, "[%d]: CQE in CONS = %u has error," 3980 " flags = %x, dropping incoming packet\n", fp->rss_id, 3981 rxq->sw_rx_cons, le16toh(cqe->pars_flags.flags)); 3982 3983 fp->err_rx_hw_errors++; 3984 3985 qlnx_reuse_rx_data(rxq); 3986 3987 QLNX_INC_IERRORS(ifp); 3988 3989 return; 3990 } 3991 3992 if (qlnx_alloc_rx_buffer(ha, rxq) != 0) { 3993 QL_DPRINT7(ha, "[%d]: New buffer allocation failed," 3994 " dropping incoming packet and reusing its buffer\n", 3995 fp->rss_id); 3996 3997 fp->err_rx_alloc_errors++; 3998 QLNX_INC_IQDROPS(ifp); 3999 4000 /* 4001 * Load the tpa mbuf into the rx ring and save the 4002 * posted mbuf 4003 */ 4004 4005 map = sw_rx_data->map; 4006 addr = sw_rx_data->dma_addr; 4007 4008 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_prod]; 4009 4010 sw_rx_data->data = rxq->tpa_info[agg_index].rx_buf.data; 4011 sw_rx_data->dma_addr = rxq->tpa_info[agg_index].rx_buf.dma_addr; 4012 sw_rx_data->map = rxq->tpa_info[agg_index].rx_buf.map; 4013 4014 rxq->tpa_info[agg_index].rx_buf.data = mp; 4015 rxq->tpa_info[agg_index].rx_buf.dma_addr = addr; 4016 rxq->tpa_info[agg_index].rx_buf.map = map; 4017 4018 rx_bd = (struct eth_rx_bd *) 4019 ecore_chain_produce(&rxq->rx_bd_ring); 4020 4021 rx_bd->addr.hi = htole32(U64_HI(sw_rx_data->dma_addr)); 4022 rx_bd->addr.lo = htole32(U64_LO(sw_rx_data->dma_addr)); 4023 4024 bus_dmamap_sync(ha->rx_tag, sw_rx_data->map, 4025 BUS_DMASYNC_PREREAD); 4026 4027 rxq->sw_rx_prod = (rxq->sw_rx_prod + 1) & (RX_RING_SIZE - 1); 4028 rxq->sw_rx_cons = (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4029 4030 ecore_chain_consume(&rxq->rx_bd_ring); 4031 4032 /* Now reuse any buffers posted in ext_bd_len_list */ 4033 for (i = 0; i < ETH_TPA_CQE_START_LEN_LIST_SIZE; i++) { 4034 if (cqe->ext_bd_len_list[i] == 0) 4035 break; 4036 4037 qlnx_reuse_rx_data(rxq); 4038 } 4039 4040 rxq->tpa_info[agg_index].agg_state = QLNX_AGG_STATE_ERROR; 4041 return; 4042 } 4043 4044 if (rxq->tpa_info[agg_index].agg_state != QLNX_AGG_STATE_NONE) { 4045 QL_DPRINT7(ha, "[%d]: invalid aggregation state," 4046 " dropping incoming packet and reusing its buffer\n", 4047 fp->rss_id); 4048 4049 QLNX_INC_IQDROPS(ifp); 4050 4051 /* if we already have mbuf head in aggregation free it */ 4052 if (rxq->tpa_info[agg_index].mpf) { 4053 m_freem(rxq->tpa_info[agg_index].mpf); 4054 rxq->tpa_info[agg_index].mpl = NULL; 4055 } 4056 rxq->tpa_info[agg_index].mpf = mp; 4057 rxq->tpa_info[agg_index].mpl = NULL; 4058 4059 rxq->sw_rx_cons = (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4060 ecore_chain_consume(&rxq->rx_bd_ring); 4061 4062 /* Now reuse any buffers posted in ext_bd_len_list */ 4063 for (i = 0; i < ETH_TPA_CQE_START_LEN_LIST_SIZE; i++) { 4064 if (cqe->ext_bd_len_list[i] == 0) 4065 break; 4066 4067 qlnx_reuse_rx_data(rxq); 4068 } 4069 rxq->tpa_info[agg_index].agg_state = QLNX_AGG_STATE_ERROR; 4070 4071 return; 4072 } 4073 4074 /* 4075 * first process the ext_bd_len_list 4076 * if this fails then we simply drop the packet 4077 */ 4078 ecore_chain_consume(&rxq->rx_bd_ring); 4079 rxq->sw_rx_cons = (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4080 4081 for (i = 0; i < ETH_TPA_CQE_START_LEN_LIST_SIZE; i++) { 4082 QL_DPRINT7(ha, "[%d]: 4\n ", fp->rss_id); 4083 4084 if (cqe->ext_bd_len_list[i] == 0) 4085 break; 4086 4087 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_cons]; 4088 bus_dmamap_sync(ha->rx_tag, sw_rx_data->map, 4089 BUS_DMASYNC_POSTREAD); 4090 4091 mpc = sw_rx_data->data; 4092 4093 if (mpc == NULL) { 4094 QL_DPRINT7(ha, "[%d]: mpc = NULL\n", fp->rss_id); 4095 fp->err_rx_mp_null++; 4096 if (mpf != NULL) 4097 m_freem(mpf); 4098 mpf = mpl = NULL; 4099 rxq->tpa_info[agg_index].agg_state = 4100 QLNX_AGG_STATE_ERROR; 4101 ecore_chain_consume(&rxq->rx_bd_ring); 4102 rxq->sw_rx_cons = 4103 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4104 continue; 4105 } 4106 4107 if (qlnx_alloc_rx_buffer(ha, rxq) != 0) { 4108 QL_DPRINT7(ha, "[%d]: New buffer allocation failed," 4109 " dropping incoming packet and reusing its" 4110 " buffer\n", fp->rss_id); 4111 4112 qlnx_reuse_rx_data(rxq); 4113 4114 if (mpf != NULL) 4115 m_freem(mpf); 4116 mpf = mpl = NULL; 4117 4118 rxq->tpa_info[agg_index].agg_state = 4119 QLNX_AGG_STATE_ERROR; 4120 4121 ecore_chain_consume(&rxq->rx_bd_ring); 4122 rxq->sw_rx_cons = 4123 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4124 4125 continue; 4126 } 4127 4128 mpc->m_flags &= ~M_PKTHDR; 4129 mpc->m_next = NULL; 4130 mpc->m_len = cqe->ext_bd_len_list[i]; 4131 4132 if (mpf == NULL) { 4133 mpf = mpl = mpc; 4134 } else { 4135 mpl->m_len = ha->rx_buf_size; 4136 mpl->m_next = mpc; 4137 mpl = mpc; 4138 } 4139 4140 ecore_chain_consume(&rxq->rx_bd_ring); 4141 rxq->sw_rx_cons = 4142 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4143 } 4144 4145 if (rxq->tpa_info[agg_index].agg_state != QLNX_AGG_STATE_NONE) { 4146 QL_DPRINT7(ha, "[%d]: invalid aggregation state, dropping" 4147 " incoming packet and reusing its buffer\n", 4148 fp->rss_id); 4149 4150 QLNX_INC_IQDROPS(ifp); 4151 4152 rxq->tpa_info[agg_index].mpf = mp; 4153 rxq->tpa_info[agg_index].mpl = NULL; 4154 4155 return; 4156 } 4157 4158 rxq->tpa_info[agg_index].placement_offset = cqe->placement_offset; 4159 4160 if (mpf != NULL) { 4161 mp->m_len = ha->rx_buf_size; 4162 mp->m_next = mpf; 4163 rxq->tpa_info[agg_index].mpf = mp; 4164 rxq->tpa_info[agg_index].mpl = mpl; 4165 } else { 4166 mp->m_len = cqe->len_on_first_bd + cqe->placement_offset; 4167 rxq->tpa_info[agg_index].mpf = mp; 4168 rxq->tpa_info[agg_index].mpl = mp; 4169 mp->m_next = NULL; 4170 } 4171 4172 mp->m_flags |= M_PKTHDR; 4173 4174 /* assign packet to this interface interface */ 4175 mp->m_pkthdr.rcvif = ifp; 4176 4177 /* assume no hardware checksum has complated */ 4178 mp->m_pkthdr.csum_flags = 0; 4179 4180 //mp->m_pkthdr.flowid = fp->rss_id; 4181 mp->m_pkthdr.flowid = cqe->rss_hash; 4182 4183 hash_type = cqe->bitfields & 4184 (ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_MASK << 4185 ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_SHIFT); 4186 4187 switch (hash_type) { 4188 case RSS_HASH_TYPE_IPV4: 4189 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_IPV4); 4190 break; 4191 4192 case RSS_HASH_TYPE_TCP_IPV4: 4193 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_TCP_IPV4); 4194 break; 4195 4196 case RSS_HASH_TYPE_IPV6: 4197 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_IPV6); 4198 break; 4199 4200 case RSS_HASH_TYPE_TCP_IPV6: 4201 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_TCP_IPV6); 4202 break; 4203 4204 default: 4205 M_HASHTYPE_SET(mp, M_HASHTYPE_OPAQUE); 4206 break; 4207 } 4208 4209 mp->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID | 4210 CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 4211 4212 mp->m_pkthdr.csum_data = 0xFFFF; 4213 4214 if (CQE_HAS_VLAN(cqe->pars_flags.flags)) { 4215 mp->m_pkthdr.ether_vtag = le16toh(cqe->vlan_tag); 4216 mp->m_flags |= M_VLANTAG; 4217 } 4218 4219 rxq->tpa_info[agg_index].agg_state = QLNX_AGG_STATE_START; 4220 4221 QL_DPRINT7(ha, "[%d]: 5\n\tagg_state = %d\n\t mpf = %p mpl = %p\n", 4222 fp->rss_id, rxq->tpa_info[agg_index].agg_state, 4223 rxq->tpa_info[agg_index].mpf, rxq->tpa_info[agg_index].mpl); 4224 4225 return; 4226 } 4227 4228 static void 4229 qlnx_tpa_cont(qlnx_host_t *ha, struct qlnx_fastpath *fp, 4230 struct qlnx_rx_queue *rxq, 4231 struct eth_fast_path_rx_tpa_cont_cqe *cqe) 4232 { 4233 struct sw_rx_data *sw_rx_data; 4234 int i; 4235 struct mbuf *mpf = NULL, *mpl = NULL, *mpc = NULL; 4236 struct mbuf *mp; 4237 uint32_t agg_index; 4238 4239 QL_DPRINT7(ha, "[%d]: enter\n \ 4240 \t type = 0x%x\n \ 4241 \t tpa_agg_index = 0x%x\n \ 4242 \t len_list[0] = 0x%x\n \ 4243 \t len_list[1] = 0x%x\n \ 4244 \t len_list[2] = 0x%x\n \ 4245 \t len_list[3] = 0x%x\n \ 4246 \t len_list[4] = 0x%x\n \ 4247 \t len_list[5] = 0x%x\n", 4248 fp->rss_id, cqe->type, cqe->tpa_agg_index, 4249 cqe->len_list[0], cqe->len_list[1], cqe->len_list[2], 4250 cqe->len_list[3], cqe->len_list[4], cqe->len_list[5]); 4251 4252 agg_index = cqe->tpa_agg_index; 4253 4254 if (agg_index >= ETH_TPA_MAX_AGGS_NUM) { 4255 QL_DPRINT7(ha, "[%d]: 0\n ", fp->rss_id); 4256 fp->err_rx_tpa_invalid_agg_num++; 4257 return; 4258 } 4259 4260 for (i = 0; i < ETH_TPA_CQE_CONT_LEN_LIST_SIZE; i++) { 4261 QL_DPRINT7(ha, "[%d]: 1\n ", fp->rss_id); 4262 4263 if (cqe->len_list[i] == 0) 4264 break; 4265 4266 if (rxq->tpa_info[agg_index].agg_state != 4267 QLNX_AGG_STATE_START) { 4268 qlnx_reuse_rx_data(rxq); 4269 continue; 4270 } 4271 4272 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_cons]; 4273 bus_dmamap_sync(ha->rx_tag, sw_rx_data->map, 4274 BUS_DMASYNC_POSTREAD); 4275 4276 mpc = sw_rx_data->data; 4277 4278 if (mpc == NULL) { 4279 QL_DPRINT7(ha, "[%d]: mpc = NULL\n", fp->rss_id); 4280 4281 fp->err_rx_mp_null++; 4282 if (mpf != NULL) 4283 m_freem(mpf); 4284 mpf = mpl = NULL; 4285 rxq->tpa_info[agg_index].agg_state = 4286 QLNX_AGG_STATE_ERROR; 4287 ecore_chain_consume(&rxq->rx_bd_ring); 4288 rxq->sw_rx_cons = 4289 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4290 continue; 4291 } 4292 4293 if (qlnx_alloc_rx_buffer(ha, rxq) != 0) { 4294 QL_DPRINT7(ha, "[%d]: New buffer allocation failed," 4295 " dropping incoming packet and reusing its" 4296 " buffer\n", fp->rss_id); 4297 4298 qlnx_reuse_rx_data(rxq); 4299 4300 if (mpf != NULL) 4301 m_freem(mpf); 4302 mpf = mpl = NULL; 4303 4304 rxq->tpa_info[agg_index].agg_state = 4305 QLNX_AGG_STATE_ERROR; 4306 4307 ecore_chain_consume(&rxq->rx_bd_ring); 4308 rxq->sw_rx_cons = 4309 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4310 4311 continue; 4312 } 4313 4314 mpc->m_flags &= ~M_PKTHDR; 4315 mpc->m_next = NULL; 4316 mpc->m_len = cqe->len_list[i]; 4317 4318 if (mpf == NULL) { 4319 mpf = mpl = mpc; 4320 } else { 4321 mpl->m_len = ha->rx_buf_size; 4322 mpl->m_next = mpc; 4323 mpl = mpc; 4324 } 4325 4326 ecore_chain_consume(&rxq->rx_bd_ring); 4327 rxq->sw_rx_cons = 4328 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4329 } 4330 4331 QL_DPRINT7(ha, "[%d]: 2\n" "\tmpf = %p mpl = %p\n", 4332 fp->rss_id, mpf, mpl); 4333 4334 if (mpf != NULL) { 4335 mp = rxq->tpa_info[agg_index].mpl; 4336 mp->m_len = ha->rx_buf_size; 4337 mp->m_next = mpf; 4338 rxq->tpa_info[agg_index].mpl = mpl; 4339 } 4340 4341 return; 4342 } 4343 4344 static int 4345 qlnx_tpa_end(qlnx_host_t *ha, struct qlnx_fastpath *fp, 4346 struct qlnx_rx_queue *rxq, 4347 struct eth_fast_path_rx_tpa_end_cqe *cqe) 4348 { 4349 struct sw_rx_data *sw_rx_data; 4350 int i; 4351 struct mbuf *mpf = NULL, *mpl = NULL, *mpc = NULL; 4352 struct mbuf *mp; 4353 uint32_t agg_index; 4354 uint32_t len = 0; 4355 if_t ifp = ha->ifp; 4356 4357 QL_DPRINT7(ha, "[%d]: enter\n \ 4358 \t type = 0x%x\n \ 4359 \t tpa_agg_index = 0x%x\n \ 4360 \t total_packet_len = 0x%x\n \ 4361 \t num_of_bds = 0x%x\n \ 4362 \t end_reason = 0x%x\n \ 4363 \t num_of_coalesced_segs = 0x%x\n \ 4364 \t ts_delta = 0x%x\n \ 4365 \t len_list[0] = 0x%x\n \ 4366 \t len_list[1] = 0x%x\n \ 4367 \t len_list[2] = 0x%x\n \ 4368 \t len_list[3] = 0x%x\n", 4369 fp->rss_id, cqe->type, cqe->tpa_agg_index, 4370 cqe->total_packet_len, cqe->num_of_bds, 4371 cqe->end_reason, cqe->num_of_coalesced_segs, cqe->ts_delta, 4372 cqe->len_list[0], cqe->len_list[1], cqe->len_list[2], 4373 cqe->len_list[3]); 4374 4375 agg_index = cqe->tpa_agg_index; 4376 4377 if (agg_index >= ETH_TPA_MAX_AGGS_NUM) { 4378 QL_DPRINT7(ha, "[%d]: 0\n ", fp->rss_id); 4379 4380 fp->err_rx_tpa_invalid_agg_num++; 4381 return (0); 4382 } 4383 4384 for (i = 0; i < ETH_TPA_CQE_END_LEN_LIST_SIZE; i++) { 4385 QL_DPRINT7(ha, "[%d]: 1\n ", fp->rss_id); 4386 4387 if (cqe->len_list[i] == 0) 4388 break; 4389 4390 if (rxq->tpa_info[agg_index].agg_state != 4391 QLNX_AGG_STATE_START) { 4392 QL_DPRINT7(ha, "[%d]: 2\n ", fp->rss_id); 4393 4394 qlnx_reuse_rx_data(rxq); 4395 continue; 4396 } 4397 4398 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_cons]; 4399 bus_dmamap_sync(ha->rx_tag, sw_rx_data->map, 4400 BUS_DMASYNC_POSTREAD); 4401 4402 mpc = sw_rx_data->data; 4403 4404 if (mpc == NULL) { 4405 QL_DPRINT7(ha, "[%d]: mpc = NULL\n", fp->rss_id); 4406 4407 fp->err_rx_mp_null++; 4408 if (mpf != NULL) 4409 m_freem(mpf); 4410 mpf = mpl = NULL; 4411 rxq->tpa_info[agg_index].agg_state = 4412 QLNX_AGG_STATE_ERROR; 4413 ecore_chain_consume(&rxq->rx_bd_ring); 4414 rxq->sw_rx_cons = 4415 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4416 continue; 4417 } 4418 4419 if (qlnx_alloc_rx_buffer(ha, rxq) != 0) { 4420 QL_DPRINT7(ha, "[%d]: New buffer allocation failed," 4421 " dropping incoming packet and reusing its" 4422 " buffer\n", fp->rss_id); 4423 4424 qlnx_reuse_rx_data(rxq); 4425 4426 if (mpf != NULL) 4427 m_freem(mpf); 4428 mpf = mpl = NULL; 4429 4430 rxq->tpa_info[agg_index].agg_state = 4431 QLNX_AGG_STATE_ERROR; 4432 4433 ecore_chain_consume(&rxq->rx_bd_ring); 4434 rxq->sw_rx_cons = 4435 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4436 4437 continue; 4438 } 4439 4440 mpc->m_flags &= ~M_PKTHDR; 4441 mpc->m_next = NULL; 4442 mpc->m_len = cqe->len_list[i]; 4443 4444 if (mpf == NULL) { 4445 mpf = mpl = mpc; 4446 } else { 4447 mpl->m_len = ha->rx_buf_size; 4448 mpl->m_next = mpc; 4449 mpl = mpc; 4450 } 4451 4452 ecore_chain_consume(&rxq->rx_bd_ring); 4453 rxq->sw_rx_cons = 4454 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4455 } 4456 4457 QL_DPRINT7(ha, "[%d]: 5\n ", fp->rss_id); 4458 4459 if (mpf != NULL) { 4460 QL_DPRINT7(ha, "[%d]: 6\n ", fp->rss_id); 4461 4462 mp = rxq->tpa_info[agg_index].mpl; 4463 mp->m_len = ha->rx_buf_size; 4464 mp->m_next = mpf; 4465 } 4466 4467 if (rxq->tpa_info[agg_index].agg_state != QLNX_AGG_STATE_START) { 4468 QL_DPRINT7(ha, "[%d]: 7\n ", fp->rss_id); 4469 4470 if (rxq->tpa_info[agg_index].mpf != NULL) 4471 m_freem(rxq->tpa_info[agg_index].mpf); 4472 rxq->tpa_info[agg_index].mpf = NULL; 4473 rxq->tpa_info[agg_index].mpl = NULL; 4474 rxq->tpa_info[agg_index].agg_state = QLNX_AGG_STATE_NONE; 4475 return (0); 4476 } 4477 4478 mp = rxq->tpa_info[agg_index].mpf; 4479 m_adj(mp, rxq->tpa_info[agg_index].placement_offset); 4480 mp->m_pkthdr.len = cqe->total_packet_len; 4481 4482 if (mp->m_next == NULL) 4483 mp->m_len = mp->m_pkthdr.len; 4484 else { 4485 /* compute the total packet length */ 4486 mpf = mp; 4487 while (mpf != NULL) { 4488 len += mpf->m_len; 4489 mpf = mpf->m_next; 4490 } 4491 4492 if (cqe->total_packet_len > len) { 4493 mpl = rxq->tpa_info[agg_index].mpl; 4494 mpl->m_len += (cqe->total_packet_len - len); 4495 } 4496 } 4497 4498 QLNX_INC_IPACKETS(ifp); 4499 QLNX_INC_IBYTES(ifp, (cqe->total_packet_len)); 4500 4501 QL_DPRINT7(ha, "[%d]: 8 csum_data = 0x%x csum_flags = 0x%" PRIu64 "\n \ 4502 m_len = 0x%x m_pkthdr_len = 0x%x\n", 4503 fp->rss_id, mp->m_pkthdr.csum_data, 4504 (uint64_t)mp->m_pkthdr.csum_flags, mp->m_len, mp->m_pkthdr.len); 4505 4506 if_input(ifp, mp); 4507 4508 rxq->tpa_info[agg_index].mpf = NULL; 4509 rxq->tpa_info[agg_index].mpl = NULL; 4510 rxq->tpa_info[agg_index].agg_state = QLNX_AGG_STATE_NONE; 4511 4512 return (cqe->num_of_coalesced_segs); 4513 } 4514 4515 static int 4516 qlnx_rx_int(qlnx_host_t *ha, struct qlnx_fastpath *fp, int budget, 4517 int lro_enable) 4518 { 4519 uint16_t hw_comp_cons, sw_comp_cons; 4520 int rx_pkt = 0; 4521 struct qlnx_rx_queue *rxq = fp->rxq; 4522 if_t ifp = ha->ifp; 4523 struct ecore_dev *cdev = &ha->cdev; 4524 struct ecore_hwfn *p_hwfn; 4525 4526 #ifdef QLNX_SOFT_LRO 4527 struct lro_ctrl *lro; 4528 4529 lro = &rxq->lro; 4530 #endif /* #ifdef QLNX_SOFT_LRO */ 4531 4532 hw_comp_cons = le16toh(*rxq->hw_cons_ptr); 4533 sw_comp_cons = ecore_chain_get_cons_idx(&rxq->rx_comp_ring); 4534 4535 p_hwfn = &ha->cdev.hwfns[(fp->rss_id % cdev->num_hwfns)]; 4536 4537 /* Memory barrier to prevent the CPU from doing speculative reads of CQE 4538 * / BD in the while-loop before reading hw_comp_cons. If the CQE is 4539 * read before it is written by FW, then FW writes CQE and SB, and then 4540 * the CPU reads the hw_comp_cons, it will use an old CQE. 4541 */ 4542 4543 /* Loop to complete all indicated BDs */ 4544 while (sw_comp_cons != hw_comp_cons) { 4545 union eth_rx_cqe *cqe; 4546 struct eth_fast_path_rx_reg_cqe *fp_cqe; 4547 struct sw_rx_data *sw_rx_data; 4548 register struct mbuf *mp; 4549 enum eth_rx_cqe_type cqe_type; 4550 uint16_t len, pad, len_on_first_bd; 4551 uint8_t *data; 4552 uint8_t hash_type; 4553 4554 /* Get the CQE from the completion ring */ 4555 cqe = (union eth_rx_cqe *) 4556 ecore_chain_consume(&rxq->rx_comp_ring); 4557 cqe_type = cqe->fast_path_regular.type; 4558 4559 if (cqe_type == ETH_RX_CQE_TYPE_SLOW_PATH) { 4560 QL_DPRINT3(ha, "Got a slowath CQE\n"); 4561 4562 ecore_eth_cqe_completion(p_hwfn, 4563 (struct eth_slow_path_rx_cqe *)cqe); 4564 goto next_cqe; 4565 } 4566 4567 if (cqe_type != ETH_RX_CQE_TYPE_REGULAR) { 4568 switch (cqe_type) { 4569 case ETH_RX_CQE_TYPE_TPA_START: 4570 qlnx_tpa_start(ha, fp, rxq, 4571 &cqe->fast_path_tpa_start); 4572 fp->tpa_start++; 4573 break; 4574 4575 case ETH_RX_CQE_TYPE_TPA_CONT: 4576 qlnx_tpa_cont(ha, fp, rxq, 4577 &cqe->fast_path_tpa_cont); 4578 fp->tpa_cont++; 4579 break; 4580 4581 case ETH_RX_CQE_TYPE_TPA_END: 4582 rx_pkt += qlnx_tpa_end(ha, fp, rxq, 4583 &cqe->fast_path_tpa_end); 4584 fp->tpa_end++; 4585 break; 4586 4587 default: 4588 break; 4589 } 4590 4591 goto next_cqe; 4592 } 4593 4594 /* Get the data from the SW ring */ 4595 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_cons]; 4596 mp = sw_rx_data->data; 4597 4598 if (mp == NULL) { 4599 QL_DPRINT1(ha, "mp = NULL\n"); 4600 fp->err_rx_mp_null++; 4601 rxq->sw_rx_cons = 4602 (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4603 goto next_cqe; 4604 } 4605 bus_dmamap_sync(ha->rx_tag, sw_rx_data->map, 4606 BUS_DMASYNC_POSTREAD); 4607 4608 /* non GRO */ 4609 fp_cqe = &cqe->fast_path_regular;/* MK CR TPA check assembly */ 4610 len = le16toh(fp_cqe->pkt_len); 4611 pad = fp_cqe->placement_offset; 4612 #if 0 4613 QL_DPRINT3(ha, "CQE type = %x, flags = %x, vlan = %x," 4614 " len %u, parsing flags = %d pad = %d\n", 4615 cqe_type, fp_cqe->bitfields, 4616 le16toh(fp_cqe->vlan_tag), 4617 len, le16toh(fp_cqe->pars_flags.flags), pad); 4618 #endif 4619 data = mtod(mp, uint8_t *); 4620 data = data + pad; 4621 4622 if (0) 4623 qlnx_dump_buf8(ha, __func__, data, len); 4624 4625 /* For every Rx BD consumed, we allocate a new BD so the BD ring 4626 * is always with a fixed size. If allocation fails, we take the 4627 * consumed BD and return it to the ring in the PROD position. 4628 * The packet that was received on that BD will be dropped (and 4629 * not passed to the upper stack). 4630 */ 4631 /* If this is an error packet then drop it */ 4632 if ((le16toh(cqe->fast_path_regular.pars_flags.flags)) & 4633 CQE_FLAGS_ERR) { 4634 QL_DPRINT1(ha, "CQE in CONS = %u has error, flags = %x," 4635 " dropping incoming packet\n", sw_comp_cons, 4636 le16toh(cqe->fast_path_regular.pars_flags.flags)); 4637 fp->err_rx_hw_errors++; 4638 4639 qlnx_reuse_rx_data(rxq); 4640 4641 QLNX_INC_IERRORS(ifp); 4642 4643 goto next_cqe; 4644 } 4645 4646 if (qlnx_alloc_rx_buffer(ha, rxq) != 0) { 4647 QL_DPRINT1(ha, "New buffer allocation failed, dropping" 4648 " incoming packet and reusing its buffer\n"); 4649 qlnx_reuse_rx_data(rxq); 4650 4651 fp->err_rx_alloc_errors++; 4652 4653 QLNX_INC_IQDROPS(ifp); 4654 4655 goto next_cqe; 4656 } 4657 4658 ecore_chain_consume(&rxq->rx_bd_ring); 4659 4660 len_on_first_bd = fp_cqe->len_on_first_bd; 4661 m_adj(mp, pad); 4662 mp->m_pkthdr.len = len; 4663 4664 if ((len > 60 ) && (len > len_on_first_bd)) { 4665 mp->m_len = len_on_first_bd; 4666 4667 if (qlnx_rx_jumbo_chain(ha, fp, mp, 4668 (len - len_on_first_bd)) != 0) { 4669 m_freem(mp); 4670 4671 QLNX_INC_IQDROPS(ifp); 4672 4673 goto next_cqe; 4674 } 4675 4676 } else if (len_on_first_bd < len) { 4677 fp->err_rx_jumbo_chain_pkts++; 4678 } else { 4679 mp->m_len = len; 4680 } 4681 4682 mp->m_flags |= M_PKTHDR; 4683 4684 /* assign packet to this interface interface */ 4685 mp->m_pkthdr.rcvif = ifp; 4686 4687 /* assume no hardware checksum has complated */ 4688 mp->m_pkthdr.csum_flags = 0; 4689 4690 mp->m_pkthdr.flowid = fp_cqe->rss_hash; 4691 4692 hash_type = fp_cqe->bitfields & 4693 (ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_MASK << 4694 ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_SHIFT); 4695 4696 switch (hash_type) { 4697 case RSS_HASH_TYPE_IPV4: 4698 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_IPV4); 4699 break; 4700 4701 case RSS_HASH_TYPE_TCP_IPV4: 4702 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_TCP_IPV4); 4703 break; 4704 4705 case RSS_HASH_TYPE_IPV6: 4706 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_IPV6); 4707 break; 4708 4709 case RSS_HASH_TYPE_TCP_IPV6: 4710 M_HASHTYPE_SET(mp, M_HASHTYPE_RSS_TCP_IPV6); 4711 break; 4712 4713 default: 4714 M_HASHTYPE_SET(mp, M_HASHTYPE_OPAQUE); 4715 break; 4716 } 4717 4718 if (CQE_L3_PACKET(fp_cqe->pars_flags.flags)) { 4719 mp->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; 4720 } 4721 4722 if (!(CQE_IP_HDR_ERR(fp_cqe->pars_flags.flags))) { 4723 mp->m_pkthdr.csum_flags |= CSUM_IP_VALID; 4724 } 4725 4726 if (CQE_L4_HAS_CSUM(fp_cqe->pars_flags.flags)) { 4727 mp->m_pkthdr.csum_data = 0xFFFF; 4728 mp->m_pkthdr.csum_flags |= 4729 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 4730 } 4731 4732 if (CQE_HAS_VLAN(fp_cqe->pars_flags.flags)) { 4733 mp->m_pkthdr.ether_vtag = le16toh(fp_cqe->vlan_tag); 4734 mp->m_flags |= M_VLANTAG; 4735 } 4736 4737 QLNX_INC_IPACKETS(ifp); 4738 QLNX_INC_IBYTES(ifp, len); 4739 4740 #ifdef QLNX_SOFT_LRO 4741 if (lro_enable) 4742 tcp_lro_queue_mbuf(lro, mp); 4743 else 4744 if_input(ifp, mp); 4745 #else 4746 4747 if_input(ifp, mp); 4748 4749 #endif /* #ifdef QLNX_SOFT_LRO */ 4750 4751 rx_pkt++; 4752 4753 rxq->sw_rx_cons = (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 4754 4755 next_cqe: /* don't consume bd rx buffer */ 4756 ecore_chain_recycle_consumed(&rxq->rx_comp_ring); 4757 sw_comp_cons = ecore_chain_get_cons_idx(&rxq->rx_comp_ring); 4758 4759 /* CR TPA - revisit how to handle budget in TPA perhaps 4760 increase on "end" */ 4761 if (rx_pkt == budget) 4762 break; 4763 } /* repeat while sw_comp_cons != hw_comp_cons... */ 4764 4765 /* Update producers */ 4766 qlnx_update_rx_prod(p_hwfn, rxq); 4767 4768 return rx_pkt; 4769 } 4770 4771 /* 4772 * fast path interrupt 4773 */ 4774 4775 static void 4776 qlnx_fp_isr(void *arg) 4777 { 4778 qlnx_ivec_t *ivec = arg; 4779 qlnx_host_t *ha; 4780 struct qlnx_fastpath *fp = NULL; 4781 int idx; 4782 4783 ha = ivec->ha; 4784 4785 if (ha->state != QLNX_STATE_OPEN) { 4786 return; 4787 } 4788 4789 idx = ivec->rss_idx; 4790 4791 if ((idx = ivec->rss_idx) >= ha->num_rss) { 4792 QL_DPRINT1(ha, "illegal interrupt[%d]\n", idx); 4793 ha->err_illegal_intr++; 4794 return; 4795 } 4796 fp = &ha->fp_array[idx]; 4797 4798 if (fp == NULL) { 4799 ha->err_fp_null++; 4800 } else { 4801 int rx_int = 0; 4802 #ifdef QLNX_SOFT_LRO 4803 int total_rx_count = 0; 4804 #endif 4805 int lro_enable, tc; 4806 struct qlnx_tx_queue *txq; 4807 uint16_t elem_left; 4808 4809 lro_enable = if_getcapenable(ha->ifp) & IFCAP_LRO; 4810 4811 ecore_sb_ack(fp->sb_info, IGU_INT_DISABLE, 0); 4812 4813 do { 4814 for (tc = 0; tc < ha->num_tc; tc++) { 4815 txq = fp->txq[tc]; 4816 4817 if((int)(elem_left = 4818 ecore_chain_get_elem_left(&txq->tx_pbl)) < 4819 QLNX_TX_ELEM_THRESH) { 4820 if (mtx_trylock(&fp->tx_mtx)) { 4821 #ifdef QLNX_TRACE_PERF_DATA 4822 tx_compl = fp->tx_pkts_completed; 4823 #endif 4824 4825 qlnx_tx_int(ha, fp, fp->txq[tc]); 4826 #ifdef QLNX_TRACE_PERF_DATA 4827 fp->tx_pkts_compl_intr += 4828 (fp->tx_pkts_completed - tx_compl); 4829 if ((fp->tx_pkts_completed - tx_compl) <= 32) 4830 fp->tx_comInt[0]++; 4831 else if (((fp->tx_pkts_completed - tx_compl) > 32) && 4832 ((fp->tx_pkts_completed - tx_compl) <= 64)) 4833 fp->tx_comInt[1]++; 4834 else if(((fp->tx_pkts_completed - tx_compl) > 64) && 4835 ((fp->tx_pkts_completed - tx_compl) <= 128)) 4836 fp->tx_comInt[2]++; 4837 else if(((fp->tx_pkts_completed - tx_compl) > 128)) 4838 fp->tx_comInt[3]++; 4839 #endif 4840 mtx_unlock(&fp->tx_mtx); 4841 } 4842 } 4843 } 4844 4845 rx_int = qlnx_rx_int(ha, fp, ha->rx_pkt_threshold, 4846 lro_enable); 4847 4848 if (rx_int) { 4849 fp->rx_pkts += rx_int; 4850 #ifdef QLNX_SOFT_LRO 4851 total_rx_count += rx_int; 4852 #endif 4853 } 4854 4855 } while (rx_int); 4856 4857 #ifdef QLNX_SOFT_LRO 4858 { 4859 struct lro_ctrl *lro; 4860 4861 lro = &fp->rxq->lro; 4862 4863 if (lro_enable && total_rx_count) { 4864 4865 #ifdef QLNX_TRACE_LRO_CNT 4866 if (lro->lro_mbuf_count & ~1023) 4867 fp->lro_cnt_1024++; 4868 else if (lro->lro_mbuf_count & ~511) 4869 fp->lro_cnt_512++; 4870 else if (lro->lro_mbuf_count & ~255) 4871 fp->lro_cnt_256++; 4872 else if (lro->lro_mbuf_count & ~127) 4873 fp->lro_cnt_128++; 4874 else if (lro->lro_mbuf_count & ~63) 4875 fp->lro_cnt_64++; 4876 #endif /* #ifdef QLNX_TRACE_LRO_CNT */ 4877 4878 tcp_lro_flush_all(lro); 4879 } 4880 } 4881 #endif /* #ifdef QLNX_SOFT_LRO */ 4882 4883 ecore_sb_update_sb_idx(fp->sb_info); 4884 rmb(); 4885 ecore_sb_ack(fp->sb_info, IGU_INT_ENABLE, 1); 4886 } 4887 4888 return; 4889 } 4890 4891 /* 4892 * slow path interrupt processing function 4893 * can be invoked in polled mode or in interrupt mode via taskqueue. 4894 */ 4895 void 4896 qlnx_sp_isr(void *arg) 4897 { 4898 struct ecore_hwfn *p_hwfn; 4899 qlnx_host_t *ha; 4900 4901 p_hwfn = arg; 4902 4903 ha = (qlnx_host_t *)p_hwfn->p_dev; 4904 4905 ha->sp_interrupts++; 4906 4907 QL_DPRINT2(ha, "enter\n"); 4908 4909 ecore_int_sp_dpc(p_hwfn); 4910 4911 QL_DPRINT2(ha, "exit\n"); 4912 4913 return; 4914 } 4915 4916 /***************************************************************************** 4917 * Support Functions for DMA'able Memory 4918 *****************************************************************************/ 4919 4920 static void 4921 qlnx_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 4922 { 4923 *((bus_addr_t *)arg) = 0; 4924 4925 if (error) { 4926 printf("%s: bus_dmamap_load failed (%d)\n", __func__, error); 4927 return; 4928 } 4929 4930 *((bus_addr_t *)arg) = segs[0].ds_addr; 4931 4932 return; 4933 } 4934 4935 static int 4936 qlnx_alloc_dmabuf(qlnx_host_t *ha, qlnx_dma_t *dma_buf) 4937 { 4938 int ret = 0; 4939 bus_addr_t b_addr; 4940 4941 ret = bus_dma_tag_create( 4942 ha->parent_tag,/* parent */ 4943 dma_buf->alignment, 4944 ((bus_size_t)(1ULL << 32)),/* boundary */ 4945 BUS_SPACE_MAXADDR, /* lowaddr */ 4946 BUS_SPACE_MAXADDR, /* highaddr */ 4947 NULL, NULL, /* filter, filterarg */ 4948 dma_buf->size, /* maxsize */ 4949 1, /* nsegments */ 4950 dma_buf->size, /* maxsegsize */ 4951 0, /* flags */ 4952 NULL, NULL, /* lockfunc, lockarg */ 4953 &dma_buf->dma_tag); 4954 4955 if (ret) { 4956 QL_DPRINT1(ha, "could not create dma tag\n"); 4957 goto qlnx_alloc_dmabuf_exit; 4958 } 4959 ret = bus_dmamem_alloc(dma_buf->dma_tag, 4960 (void **)&dma_buf->dma_b, 4961 (BUS_DMA_ZERO | BUS_DMA_COHERENT | BUS_DMA_NOWAIT), 4962 &dma_buf->dma_map); 4963 if (ret) { 4964 bus_dma_tag_destroy(dma_buf->dma_tag); 4965 QL_DPRINT1(ha, "bus_dmamem_alloc failed\n"); 4966 goto qlnx_alloc_dmabuf_exit; 4967 } 4968 4969 ret = bus_dmamap_load(dma_buf->dma_tag, 4970 dma_buf->dma_map, 4971 dma_buf->dma_b, 4972 dma_buf->size, 4973 qlnx_dmamap_callback, 4974 &b_addr, BUS_DMA_NOWAIT); 4975 4976 if (ret || !b_addr) { 4977 bus_dma_tag_destroy(dma_buf->dma_tag); 4978 bus_dmamem_free(dma_buf->dma_tag, dma_buf->dma_b, 4979 dma_buf->dma_map); 4980 ret = -1; 4981 goto qlnx_alloc_dmabuf_exit; 4982 } 4983 4984 dma_buf->dma_addr = b_addr; 4985 4986 qlnx_alloc_dmabuf_exit: 4987 4988 return ret; 4989 } 4990 4991 static void 4992 qlnx_free_dmabuf(qlnx_host_t *ha, qlnx_dma_t *dma_buf) 4993 { 4994 bus_dmamap_unload(dma_buf->dma_tag, dma_buf->dma_map); 4995 bus_dmamem_free(dma_buf->dma_tag, dma_buf->dma_b, dma_buf->dma_map); 4996 bus_dma_tag_destroy(dma_buf->dma_tag); 4997 return; 4998 } 4999 5000 void * 5001 qlnx_dma_alloc_coherent(void *ecore_dev, bus_addr_t *phys, uint32_t size) 5002 { 5003 qlnx_dma_t dma_buf; 5004 qlnx_dma_t *dma_p; 5005 qlnx_host_t *ha __unused; 5006 5007 ha = (qlnx_host_t *)ecore_dev; 5008 5009 size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); 5010 5011 memset(&dma_buf, 0, sizeof (qlnx_dma_t)); 5012 5013 dma_buf.size = size + PAGE_SIZE; 5014 dma_buf.alignment = 8; 5015 5016 if (qlnx_alloc_dmabuf((qlnx_host_t *)ecore_dev, &dma_buf) != 0) 5017 return (NULL); 5018 bzero((uint8_t *)dma_buf.dma_b, dma_buf.size); 5019 5020 *phys = dma_buf.dma_addr; 5021 5022 dma_p = (qlnx_dma_t *)((uint8_t *)dma_buf.dma_b + size); 5023 5024 memcpy(dma_p, &dma_buf, sizeof(qlnx_dma_t)); 5025 5026 QL_DPRINT5(ha, "[%p %p %p %p 0x%08x ]\n", 5027 (void *)dma_buf.dma_map, (void *)dma_buf.dma_tag, 5028 dma_buf.dma_b, (void *)dma_buf.dma_addr, size); 5029 5030 return (dma_buf.dma_b); 5031 } 5032 5033 void 5034 qlnx_dma_free_coherent(void *ecore_dev, void *v_addr, bus_addr_t phys, 5035 uint32_t size) 5036 { 5037 qlnx_dma_t dma_buf, *dma_p; 5038 qlnx_host_t *ha; 5039 5040 ha = (qlnx_host_t *)ecore_dev; 5041 5042 if (v_addr == NULL) 5043 return; 5044 5045 size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); 5046 5047 dma_p = (qlnx_dma_t *)((uint8_t *)v_addr + size); 5048 5049 QL_DPRINT5(ha, "[%p %p %p %p 0x%08x ]\n", 5050 (void *)dma_p->dma_map, (void *)dma_p->dma_tag, 5051 dma_p->dma_b, (void *)dma_p->dma_addr, size); 5052 5053 dma_buf = *dma_p; 5054 5055 if (!ha->qlnxr_debug) 5056 qlnx_free_dmabuf((qlnx_host_t *)ecore_dev, &dma_buf); 5057 return; 5058 } 5059 5060 static int 5061 qlnx_alloc_parent_dma_tag(qlnx_host_t *ha) 5062 { 5063 int ret; 5064 device_t dev; 5065 5066 dev = ha->pci_dev; 5067 5068 /* 5069 * Allocate parent DMA Tag 5070 */ 5071 ret = bus_dma_tag_create( 5072 bus_get_dma_tag(dev), /* parent */ 5073 1,((bus_size_t)(1ULL << 32)),/* alignment, boundary */ 5074 BUS_SPACE_MAXADDR, /* lowaddr */ 5075 BUS_SPACE_MAXADDR, /* highaddr */ 5076 NULL, NULL, /* filter, filterarg */ 5077 BUS_SPACE_MAXSIZE_32BIT,/* maxsize */ 5078 0, /* nsegments */ 5079 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 5080 0, /* flags */ 5081 NULL, NULL, /* lockfunc, lockarg */ 5082 &ha->parent_tag); 5083 5084 if (ret) { 5085 QL_DPRINT1(ha, "could not create parent dma tag\n"); 5086 return (-1); 5087 } 5088 5089 ha->flags.parent_tag = 1; 5090 5091 return (0); 5092 } 5093 5094 static void 5095 qlnx_free_parent_dma_tag(qlnx_host_t *ha) 5096 { 5097 if (ha->parent_tag != NULL) { 5098 bus_dma_tag_destroy(ha->parent_tag); 5099 ha->parent_tag = NULL; 5100 } 5101 return; 5102 } 5103 5104 static int 5105 qlnx_alloc_tx_dma_tag(qlnx_host_t *ha) 5106 { 5107 if (bus_dma_tag_create(NULL, /* parent */ 5108 1, 0, /* alignment, bounds */ 5109 BUS_SPACE_MAXADDR, /* lowaddr */ 5110 BUS_SPACE_MAXADDR, /* highaddr */ 5111 NULL, NULL, /* filter, filterarg */ 5112 QLNX_MAX_TSO_FRAME_SIZE, /* maxsize */ 5113 QLNX_MAX_SEGMENTS, /* nsegments */ 5114 QLNX_MAX_TX_MBUF_SIZE, /* maxsegsize */ 5115 0, /* flags */ 5116 NULL, /* lockfunc */ 5117 NULL, /* lockfuncarg */ 5118 &ha->tx_tag)) { 5119 QL_DPRINT1(ha, "tx_tag alloc failed\n"); 5120 return (-1); 5121 } 5122 5123 return (0); 5124 } 5125 5126 static void 5127 qlnx_free_tx_dma_tag(qlnx_host_t *ha) 5128 { 5129 if (ha->tx_tag != NULL) { 5130 bus_dma_tag_destroy(ha->tx_tag); 5131 ha->tx_tag = NULL; 5132 } 5133 return; 5134 } 5135 5136 static int 5137 qlnx_alloc_rx_dma_tag(qlnx_host_t *ha) 5138 { 5139 if (bus_dma_tag_create(NULL, /* parent */ 5140 1, 0, /* alignment, bounds */ 5141 BUS_SPACE_MAXADDR, /* lowaddr */ 5142 BUS_SPACE_MAXADDR, /* highaddr */ 5143 NULL, NULL, /* filter, filterarg */ 5144 MJUM9BYTES, /* maxsize */ 5145 1, /* nsegments */ 5146 MJUM9BYTES, /* maxsegsize */ 5147 0, /* flags */ 5148 NULL, /* lockfunc */ 5149 NULL, /* lockfuncarg */ 5150 &ha->rx_tag)) { 5151 QL_DPRINT1(ha, " rx_tag alloc failed\n"); 5152 5153 return (-1); 5154 } 5155 return (0); 5156 } 5157 5158 static void 5159 qlnx_free_rx_dma_tag(qlnx_host_t *ha) 5160 { 5161 if (ha->rx_tag != NULL) { 5162 bus_dma_tag_destroy(ha->rx_tag); 5163 ha->rx_tag = NULL; 5164 } 5165 return; 5166 } 5167 5168 /********************************* 5169 * Exported functions 5170 *********************************/ 5171 uint32_t 5172 qlnx_pci_bus_get_bar_size(void *ecore_dev, uint8_t bar_id) 5173 { 5174 uint32_t bar_size; 5175 5176 bar_id = bar_id * 2; 5177 5178 bar_size = bus_get_resource_count(((qlnx_host_t *)ecore_dev)->pci_dev, 5179 SYS_RES_MEMORY, 5180 PCIR_BAR(bar_id)); 5181 5182 return (bar_size); 5183 } 5184 5185 uint32_t 5186 qlnx_pci_read_config_byte(void *ecore_dev, uint32_t pci_reg, uint8_t *reg_value) 5187 { 5188 *reg_value = pci_read_config(((qlnx_host_t *)ecore_dev)->pci_dev, 5189 pci_reg, 1); 5190 return 0; 5191 } 5192 5193 uint32_t 5194 qlnx_pci_read_config_word(void *ecore_dev, uint32_t pci_reg, 5195 uint16_t *reg_value) 5196 { 5197 *reg_value = pci_read_config(((qlnx_host_t *)ecore_dev)->pci_dev, 5198 pci_reg, 2); 5199 return 0; 5200 } 5201 5202 uint32_t 5203 qlnx_pci_read_config_dword(void *ecore_dev, uint32_t pci_reg, 5204 uint32_t *reg_value) 5205 { 5206 *reg_value = pci_read_config(((qlnx_host_t *)ecore_dev)->pci_dev, 5207 pci_reg, 4); 5208 return 0; 5209 } 5210 5211 void 5212 qlnx_pci_write_config_byte(void *ecore_dev, uint32_t pci_reg, uint8_t reg_value) 5213 { 5214 pci_write_config(((qlnx_host_t *)ecore_dev)->pci_dev, 5215 pci_reg, reg_value, 1); 5216 return; 5217 } 5218 5219 void 5220 qlnx_pci_write_config_word(void *ecore_dev, uint32_t pci_reg, 5221 uint16_t reg_value) 5222 { 5223 pci_write_config(((qlnx_host_t *)ecore_dev)->pci_dev, 5224 pci_reg, reg_value, 2); 5225 return; 5226 } 5227 5228 void 5229 qlnx_pci_write_config_dword(void *ecore_dev, uint32_t pci_reg, 5230 uint32_t reg_value) 5231 { 5232 pci_write_config(((qlnx_host_t *)ecore_dev)->pci_dev, 5233 pci_reg, reg_value, 4); 5234 return; 5235 } 5236 5237 int 5238 qlnx_pci_find_capability(void *ecore_dev, int cap) 5239 { 5240 int reg; 5241 qlnx_host_t *ha; 5242 5243 ha = ecore_dev; 5244 5245 if (pci_find_cap(ha->pci_dev, PCIY_EXPRESS, ®) == 0) 5246 return reg; 5247 else { 5248 QL_DPRINT1(ha, "failed\n"); 5249 return 0; 5250 } 5251 } 5252 5253 int 5254 qlnx_pci_find_ext_capability(void *ecore_dev, int ext_cap) 5255 { 5256 int reg; 5257 qlnx_host_t *ha; 5258 5259 ha = ecore_dev; 5260 5261 if (pci_find_extcap(ha->pci_dev, ext_cap, ®) == 0) 5262 return reg; 5263 else { 5264 QL_DPRINT1(ha, "failed\n"); 5265 return 0; 5266 } 5267 } 5268 5269 uint32_t 5270 qlnx_reg_rd32(void *hwfn, uint32_t reg_addr) 5271 { 5272 uint32_t data32; 5273 struct ecore_hwfn *p_hwfn; 5274 5275 p_hwfn = hwfn; 5276 5277 data32 = bus_read_4(((qlnx_host_t *)p_hwfn->p_dev)->pci_reg, \ 5278 (bus_size_t)(p_hwfn->reg_offset + reg_addr)); 5279 5280 return (data32); 5281 } 5282 5283 void 5284 qlnx_reg_wr32(void *hwfn, uint32_t reg_addr, uint32_t value) 5285 { 5286 struct ecore_hwfn *p_hwfn = hwfn; 5287 5288 bus_write_4(((qlnx_host_t *)p_hwfn->p_dev)->pci_reg, \ 5289 (bus_size_t)(p_hwfn->reg_offset + reg_addr), value); 5290 5291 return; 5292 } 5293 5294 void 5295 qlnx_reg_wr16(void *hwfn, uint32_t reg_addr, uint16_t value) 5296 { 5297 struct ecore_hwfn *p_hwfn = hwfn; 5298 5299 bus_write_2(((qlnx_host_t *)p_hwfn->p_dev)->pci_reg, \ 5300 (bus_size_t)(p_hwfn->reg_offset + reg_addr), value); 5301 return; 5302 } 5303 5304 void 5305 qlnx_dbell_wr32_db(void *hwfn, void *reg_addr, uint32_t value) 5306 { 5307 struct ecore_dev *cdev; 5308 struct ecore_hwfn *p_hwfn; 5309 uint32_t offset; 5310 5311 p_hwfn = hwfn; 5312 5313 cdev = p_hwfn->p_dev; 5314 5315 offset = (uint32_t)((uint8_t *)reg_addr - (uint8_t *)(p_hwfn->doorbells)); 5316 bus_write_4(((qlnx_host_t *)cdev)->pci_dbells, offset, value); 5317 5318 return; 5319 } 5320 5321 void 5322 qlnx_dbell_wr32(void *hwfn, uint32_t reg_addr, uint32_t value) 5323 { 5324 struct ecore_hwfn *p_hwfn = hwfn; 5325 5326 bus_write_4(((qlnx_host_t *)p_hwfn->p_dev)->pci_dbells, \ 5327 (bus_size_t)(p_hwfn->db_offset + reg_addr), value); 5328 5329 return; 5330 } 5331 5332 uint32_t 5333 qlnx_direct_reg_rd32(void *p_hwfn, uint32_t *reg_addr) 5334 { 5335 uint32_t data32; 5336 bus_size_t offset; 5337 struct ecore_dev *cdev; 5338 5339 cdev = ((struct ecore_hwfn *)p_hwfn)->p_dev; 5340 offset = (bus_size_t)((uint8_t *)reg_addr - (uint8_t *)(cdev->regview)); 5341 5342 data32 = bus_read_4(((qlnx_host_t *)cdev)->pci_reg, offset); 5343 5344 return (data32); 5345 } 5346 5347 void 5348 qlnx_direct_reg_wr32(void *p_hwfn, void *reg_addr, uint32_t value) 5349 { 5350 bus_size_t offset; 5351 struct ecore_dev *cdev; 5352 5353 cdev = ((struct ecore_hwfn *)p_hwfn)->p_dev; 5354 offset = (bus_size_t)((uint8_t *)reg_addr - (uint8_t *)(cdev->regview)); 5355 5356 bus_write_4(((qlnx_host_t *)cdev)->pci_reg, offset, value); 5357 5358 return; 5359 } 5360 5361 void 5362 qlnx_direct_reg_wr64(void *p_hwfn, void *reg_addr, uint64_t value) 5363 { 5364 bus_size_t offset; 5365 struct ecore_dev *cdev; 5366 5367 cdev = ((struct ecore_hwfn *)p_hwfn)->p_dev; 5368 offset = (bus_size_t)((uint8_t *)reg_addr - (uint8_t *)(cdev->regview)); 5369 5370 bus_write_8(((qlnx_host_t *)cdev)->pci_reg, offset, value); 5371 return; 5372 } 5373 5374 void * 5375 qlnx_zalloc(uint32_t size) 5376 { 5377 caddr_t va; 5378 5379 va = malloc((unsigned long)size, M_QLNXBUF, M_NOWAIT); 5380 bzero(va, size); 5381 return ((void *)va); 5382 } 5383 5384 void 5385 qlnx_barrier(void *p_dev) 5386 { 5387 qlnx_host_t *ha; 5388 5389 ha = ((struct ecore_dev *) p_dev)->ha; 5390 bus_barrier(ha->pci_reg, 0, 0, BUS_SPACE_BARRIER_WRITE); 5391 } 5392 5393 void 5394 qlnx_link_update(void *p_hwfn) 5395 { 5396 qlnx_host_t *ha; 5397 int prev_link_state; 5398 5399 ha = (qlnx_host_t *)((struct ecore_hwfn *)p_hwfn)->p_dev; 5400 5401 qlnx_fill_link(ha, p_hwfn, &ha->if_link); 5402 5403 prev_link_state = ha->link_up; 5404 ha->link_up = ha->if_link.link_up; 5405 5406 if (prev_link_state != ha->link_up) { 5407 if (ha->link_up) { 5408 if_link_state_change(ha->ifp, LINK_STATE_UP); 5409 } else { 5410 if_link_state_change(ha->ifp, LINK_STATE_DOWN); 5411 } 5412 } 5413 #ifndef QLNX_VF 5414 #ifdef CONFIG_ECORE_SRIOV 5415 5416 if (qlnx_vf_device(ha) != 0) { 5417 if (ha->sriov_initialized) 5418 qlnx_inform_vf_link_state(p_hwfn, ha); 5419 } 5420 5421 #endif /* #ifdef CONFIG_ECORE_SRIOV */ 5422 #endif /* #ifdef QLNX_VF */ 5423 5424 return; 5425 } 5426 5427 static void 5428 __qlnx_osal_vf_fill_acquire_resc_req(struct ecore_hwfn *p_hwfn, 5429 struct ecore_vf_acquire_sw_info *p_sw_info) 5430 { 5431 p_sw_info->driver_version = (QLNX_VERSION_MAJOR << 24) | 5432 (QLNX_VERSION_MINOR << 16) | 5433 QLNX_VERSION_BUILD; 5434 p_sw_info->os_type = VFPF_ACQUIRE_OS_FREEBSD; 5435 5436 return; 5437 } 5438 5439 void 5440 qlnx_osal_vf_fill_acquire_resc_req(void *p_hwfn, void *p_resc_req, 5441 void *p_sw_info) 5442 { 5443 __qlnx_osal_vf_fill_acquire_resc_req(p_hwfn, p_sw_info); 5444 5445 return; 5446 } 5447 5448 void 5449 qlnx_fill_link(qlnx_host_t *ha, struct ecore_hwfn *hwfn, 5450 struct qlnx_link_output *if_link) 5451 { 5452 struct ecore_mcp_link_params link_params; 5453 struct ecore_mcp_link_state link_state; 5454 uint8_t p_change; 5455 struct ecore_ptt *p_ptt = NULL; 5456 5457 memset(if_link, 0, sizeof(*if_link)); 5458 memset(&link_params, 0, sizeof(struct ecore_mcp_link_params)); 5459 memset(&link_state, 0, sizeof(struct ecore_mcp_link_state)); 5460 5461 ha = (qlnx_host_t *)hwfn->p_dev; 5462 5463 /* Prepare source inputs */ 5464 /* we only deal with physical functions */ 5465 if (qlnx_vf_device(ha) != 0) { 5466 p_ptt = ecore_ptt_acquire(hwfn); 5467 5468 if (p_ptt == NULL) { 5469 QL_DPRINT1(ha, "ecore_ptt_acquire failed\n"); 5470 return; 5471 } 5472 5473 ecore_mcp_get_media_type(hwfn, p_ptt, &if_link->media_type); 5474 ecore_ptt_release(hwfn, p_ptt); 5475 5476 memcpy(&link_params, ecore_mcp_get_link_params(hwfn), 5477 sizeof(link_params)); 5478 memcpy(&link_state, ecore_mcp_get_link_state(hwfn), 5479 sizeof(link_state)); 5480 } else { 5481 ecore_mcp_get_media_type(hwfn, NULL, &if_link->media_type); 5482 ecore_vf_read_bulletin(hwfn, &p_change); 5483 ecore_vf_get_link_params(hwfn, &link_params); 5484 ecore_vf_get_link_state(hwfn, &link_state); 5485 } 5486 5487 /* Set the link parameters to pass to protocol driver */ 5488 if (link_state.link_up) { 5489 if_link->link_up = true; 5490 if_link->speed = link_state.speed; 5491 } 5492 5493 if_link->supported_caps = QLNX_LINK_CAP_FIBRE; 5494 5495 if (link_params.speed.autoneg) 5496 if_link->supported_caps |= QLNX_LINK_CAP_Autoneg; 5497 5498 if (link_params.pause.autoneg || 5499 (link_params.pause.forced_rx && link_params.pause.forced_tx)) 5500 if_link->supported_caps |= QLNX_LINK_CAP_Asym_Pause; 5501 5502 if (link_params.pause.autoneg || link_params.pause.forced_rx || 5503 link_params.pause.forced_tx) 5504 if_link->supported_caps |= QLNX_LINK_CAP_Pause; 5505 5506 if (link_params.speed.advertised_speeds & 5507 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) 5508 if_link->supported_caps |= QLNX_LINK_CAP_1000baseT_Half | 5509 QLNX_LINK_CAP_1000baseT_Full; 5510 5511 if (link_params.speed.advertised_speeds & 5512 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) 5513 if_link->supported_caps |= QLNX_LINK_CAP_10000baseKR_Full; 5514 5515 if (link_params.speed.advertised_speeds & 5516 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) 5517 if_link->supported_caps |= QLNX_LINK_CAP_25000baseKR_Full; 5518 5519 if (link_params.speed.advertised_speeds & 5520 NVM_CFG1_PORT_DRV_LINK_SPEED_40G) 5521 if_link->supported_caps |= QLNX_LINK_CAP_40000baseLR4_Full; 5522 5523 if (link_params.speed.advertised_speeds & 5524 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) 5525 if_link->supported_caps |= QLNX_LINK_CAP_50000baseKR2_Full; 5526 5527 if (link_params.speed.advertised_speeds & 5528 NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) 5529 if_link->supported_caps |= QLNX_LINK_CAP_100000baseKR4_Full; 5530 5531 if_link->advertised_caps = if_link->supported_caps; 5532 5533 if_link->autoneg = link_params.speed.autoneg; 5534 if_link->duplex = QLNX_LINK_DUPLEX; 5535 5536 /* Link partner capabilities */ 5537 5538 if (link_state.partner_adv_speed & ECORE_LINK_PARTNER_SPEED_1G_HD) 5539 if_link->link_partner_caps |= QLNX_LINK_CAP_1000baseT_Half; 5540 5541 if (link_state.partner_adv_speed & ECORE_LINK_PARTNER_SPEED_1G_FD) 5542 if_link->link_partner_caps |= QLNX_LINK_CAP_1000baseT_Full; 5543 5544 if (link_state.partner_adv_speed & ECORE_LINK_PARTNER_SPEED_10G) 5545 if_link->link_partner_caps |= QLNX_LINK_CAP_10000baseKR_Full; 5546 5547 if (link_state.partner_adv_speed & ECORE_LINK_PARTNER_SPEED_25G) 5548 if_link->link_partner_caps |= QLNX_LINK_CAP_25000baseKR_Full; 5549 5550 if (link_state.partner_adv_speed & ECORE_LINK_PARTNER_SPEED_40G) 5551 if_link->link_partner_caps |= QLNX_LINK_CAP_40000baseLR4_Full; 5552 5553 if (link_state.partner_adv_speed & ECORE_LINK_PARTNER_SPEED_50G) 5554 if_link->link_partner_caps |= QLNX_LINK_CAP_50000baseKR2_Full; 5555 5556 if (link_state.partner_adv_speed & ECORE_LINK_PARTNER_SPEED_100G) 5557 if_link->link_partner_caps |= QLNX_LINK_CAP_100000baseKR4_Full; 5558 5559 if (link_state.an_complete) 5560 if_link->link_partner_caps |= QLNX_LINK_CAP_Autoneg; 5561 5562 if (link_state.partner_adv_pause) 5563 if_link->link_partner_caps |= QLNX_LINK_CAP_Pause; 5564 5565 if ((link_state.partner_adv_pause == 5566 ECORE_LINK_PARTNER_ASYMMETRIC_PAUSE) || 5567 (link_state.partner_adv_pause == 5568 ECORE_LINK_PARTNER_BOTH_PAUSE)) 5569 if_link->link_partner_caps |= QLNX_LINK_CAP_Asym_Pause; 5570 5571 return; 5572 } 5573 5574 void 5575 qlnx_schedule_recovery(void *p_hwfn) 5576 { 5577 qlnx_host_t *ha; 5578 5579 ha = (qlnx_host_t *)((struct ecore_hwfn *)p_hwfn)->p_dev; 5580 5581 if (qlnx_vf_device(ha) != 0) { 5582 taskqueue_enqueue(ha->err_taskqueue, &ha->err_task); 5583 } 5584 5585 return; 5586 } 5587 5588 static int 5589 qlnx_nic_setup(struct ecore_dev *cdev, struct ecore_pf_params *func_params) 5590 { 5591 int rc, i; 5592 5593 for (i = 0; i < cdev->num_hwfns; i++) { 5594 struct ecore_hwfn *p_hwfn = &cdev->hwfns[i]; 5595 p_hwfn->pf_params = *func_params; 5596 5597 #ifdef QLNX_ENABLE_IWARP 5598 if (qlnx_vf_device((qlnx_host_t *)cdev) != 0) { 5599 p_hwfn->using_ll2 = true; 5600 } 5601 #endif /* #ifdef QLNX_ENABLE_IWARP */ 5602 } 5603 5604 rc = ecore_resc_alloc(cdev); 5605 if (rc) 5606 goto qlnx_nic_setup_exit; 5607 5608 ecore_resc_setup(cdev); 5609 5610 qlnx_nic_setup_exit: 5611 5612 return rc; 5613 } 5614 5615 static int 5616 qlnx_nic_start(struct ecore_dev *cdev) 5617 { 5618 int rc; 5619 struct ecore_hw_init_params params; 5620 5621 bzero(¶ms, sizeof (struct ecore_hw_init_params)); 5622 5623 params.p_tunn = NULL; 5624 params.b_hw_start = true; 5625 params.int_mode = cdev->int_mode; 5626 params.allow_npar_tx_switch = true; 5627 params.bin_fw_data = NULL; 5628 5629 rc = ecore_hw_init(cdev, ¶ms); 5630 if (rc) { 5631 ecore_resc_free(cdev); 5632 return rc; 5633 } 5634 5635 return 0; 5636 } 5637 5638 static int 5639 qlnx_slowpath_start(qlnx_host_t *ha) 5640 { 5641 struct ecore_dev *cdev; 5642 struct ecore_pf_params pf_params; 5643 int rc; 5644 5645 memset(&pf_params, 0, sizeof(struct ecore_pf_params)); 5646 pf_params.eth_pf_params.num_cons = 5647 (ha->num_rss) * (ha->num_tc + 1); 5648 5649 #ifdef QLNX_ENABLE_IWARP 5650 if (qlnx_vf_device(ha) != 0) { 5651 if(ha->personality == ECORE_PCI_ETH_IWARP) { 5652 device_printf(ha->pci_dev, "setting parameters required by iWARP dev\n"); 5653 pf_params.rdma_pf_params.num_qps = 1024; 5654 pf_params.rdma_pf_params.num_srqs = 1024; 5655 pf_params.rdma_pf_params.gl_pi = ECORE_ROCE_PROTOCOL_INDEX; 5656 pf_params.rdma_pf_params.rdma_protocol = ECORE_RDMA_PROTOCOL_IWARP; 5657 } else if(ha->personality == ECORE_PCI_ETH_ROCE) { 5658 device_printf(ha->pci_dev, "setting parameters required by RoCE dev\n"); 5659 pf_params.rdma_pf_params.num_qps = 8192; 5660 pf_params.rdma_pf_params.num_srqs = 8192; 5661 //pf_params.rdma_pf_params.min_dpis = 0; 5662 pf_params.rdma_pf_params.min_dpis = 8; 5663 pf_params.rdma_pf_params.roce_edpm_mode = 0; 5664 pf_params.rdma_pf_params.gl_pi = ECORE_ROCE_PROTOCOL_INDEX; 5665 pf_params.rdma_pf_params.rdma_protocol = ECORE_RDMA_PROTOCOL_ROCE; 5666 } 5667 } 5668 #endif /* #ifdef QLNX_ENABLE_IWARP */ 5669 5670 cdev = &ha->cdev; 5671 5672 rc = qlnx_nic_setup(cdev, &pf_params); 5673 if (rc) 5674 goto qlnx_slowpath_start_exit; 5675 5676 cdev->int_mode = ECORE_INT_MODE_MSIX; 5677 cdev->int_coalescing_mode = ECORE_COAL_MODE_ENABLE; 5678 5679 #ifdef QLNX_MAX_COALESCE 5680 cdev->rx_coalesce_usecs = 255; 5681 cdev->tx_coalesce_usecs = 255; 5682 #endif 5683 5684 rc = qlnx_nic_start(cdev); 5685 5686 ha->rx_coalesce_usecs = cdev->rx_coalesce_usecs; 5687 ha->tx_coalesce_usecs = cdev->tx_coalesce_usecs; 5688 5689 #ifdef QLNX_USER_LLDP 5690 (void)qlnx_set_lldp_tlvx(ha, NULL); 5691 #endif /* #ifdef QLNX_USER_LLDP */ 5692 5693 qlnx_slowpath_start_exit: 5694 5695 return (rc); 5696 } 5697 5698 static int 5699 qlnx_slowpath_stop(qlnx_host_t *ha) 5700 { 5701 struct ecore_dev *cdev; 5702 device_t dev = ha->pci_dev; 5703 int i; 5704 5705 cdev = &ha->cdev; 5706 5707 ecore_hw_stop(cdev); 5708 5709 for (i = 0; i < ha->cdev.num_hwfns; i++) { 5710 if (ha->sp_handle[i]) 5711 (void)bus_teardown_intr(dev, ha->sp_irq[i], 5712 ha->sp_handle[i]); 5713 5714 ha->sp_handle[i] = NULL; 5715 5716 if (ha->sp_irq[i]) 5717 (void) bus_release_resource(dev, SYS_RES_IRQ, 5718 ha->sp_irq_rid[i], ha->sp_irq[i]); 5719 ha->sp_irq[i] = NULL; 5720 } 5721 5722 ecore_resc_free(cdev); 5723 5724 return 0; 5725 } 5726 5727 static void 5728 qlnx_set_id(struct ecore_dev *cdev, char name[NAME_SIZE], 5729 char ver_str[VER_SIZE]) 5730 { 5731 int i; 5732 5733 memcpy(cdev->name, name, NAME_SIZE); 5734 5735 for_each_hwfn(cdev, i) { 5736 snprintf(cdev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i); 5737 } 5738 5739 cdev->drv_type = DRV_ID_DRV_TYPE_FREEBSD; 5740 5741 return ; 5742 } 5743 5744 void 5745 qlnx_get_protocol_stats(void *cdev, int proto_type, void *proto_stats) 5746 { 5747 enum ecore_mcp_protocol_type type; 5748 union ecore_mcp_protocol_stats *stats; 5749 struct ecore_eth_stats eth_stats; 5750 qlnx_host_t *ha; 5751 5752 ha = cdev; 5753 stats = proto_stats; 5754 type = proto_type; 5755 5756 switch (type) { 5757 case ECORE_MCP_LAN_STATS: 5758 ecore_get_vport_stats((struct ecore_dev *)cdev, ð_stats); 5759 stats->lan_stats.ucast_rx_pkts = eth_stats.common.rx_ucast_pkts; 5760 stats->lan_stats.ucast_tx_pkts = eth_stats.common.tx_ucast_pkts; 5761 stats->lan_stats.fcs_err = -1; 5762 break; 5763 5764 default: 5765 ha->err_get_proto_invalid_type++; 5766 5767 QL_DPRINT1(ha, "invalid protocol type 0x%x\n", type); 5768 break; 5769 } 5770 return; 5771 } 5772 5773 static int 5774 qlnx_get_mfw_version(qlnx_host_t *ha, uint32_t *mfw_ver) 5775 { 5776 struct ecore_hwfn *p_hwfn; 5777 struct ecore_ptt *p_ptt; 5778 5779 p_hwfn = &ha->cdev.hwfns[0]; 5780 p_ptt = ecore_ptt_acquire(p_hwfn); 5781 5782 if (p_ptt == NULL) { 5783 QL_DPRINT1(ha, "ecore_ptt_acquire failed\n"); 5784 return (-1); 5785 } 5786 ecore_mcp_get_mfw_ver(p_hwfn, p_ptt, mfw_ver, NULL); 5787 5788 ecore_ptt_release(p_hwfn, p_ptt); 5789 5790 return (0); 5791 } 5792 5793 static int 5794 qlnx_get_flash_size(qlnx_host_t *ha, uint32_t *flash_size) 5795 { 5796 struct ecore_hwfn *p_hwfn; 5797 struct ecore_ptt *p_ptt; 5798 5799 p_hwfn = &ha->cdev.hwfns[0]; 5800 p_ptt = ecore_ptt_acquire(p_hwfn); 5801 5802 if (p_ptt == NULL) { 5803 QL_DPRINT1(ha,"ecore_ptt_acquire failed\n"); 5804 return (-1); 5805 } 5806 ecore_mcp_get_flash_size(p_hwfn, p_ptt, flash_size); 5807 5808 ecore_ptt_release(p_hwfn, p_ptt); 5809 5810 return (0); 5811 } 5812 5813 static int 5814 qlnx_alloc_mem_arrays(qlnx_host_t *ha) 5815 { 5816 bzero(&ha->txq_array[0], (sizeof(struct qlnx_tx_queue) * QLNX_MAX_RSS)); 5817 bzero(&ha->rxq_array[0], (sizeof(struct qlnx_rx_queue) * QLNX_MAX_RSS)); 5818 bzero(&ha->sb_array[0], (sizeof(struct ecore_sb_info) * QLNX_MAX_RSS)); 5819 5820 return 0; 5821 } 5822 5823 static void 5824 qlnx_init_fp(qlnx_host_t *ha) 5825 { 5826 int rss_id, txq_array_index, tc; 5827 5828 for (rss_id = 0; rss_id < ha->num_rss; rss_id++) { 5829 struct qlnx_fastpath *fp = &ha->fp_array[rss_id]; 5830 5831 fp->rss_id = rss_id; 5832 fp->edev = ha; 5833 fp->sb_info = &ha->sb_array[rss_id]; 5834 fp->rxq = &ha->rxq_array[rss_id]; 5835 fp->rxq->rxq_id = rss_id; 5836 5837 for (tc = 0; tc < ha->num_tc; tc++) { 5838 txq_array_index = tc * ha->num_rss + rss_id; 5839 fp->txq[tc] = &ha->txq_array[txq_array_index]; 5840 fp->txq[tc]->index = txq_array_index; 5841 } 5842 5843 snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", qlnx_name_str, 5844 rss_id); 5845 5846 fp->tx_ring_full = 0; 5847 5848 /* reset all the statistics counters */ 5849 5850 fp->tx_pkts_processed = 0; 5851 fp->tx_pkts_freed = 0; 5852 fp->tx_pkts_transmitted = 0; 5853 fp->tx_pkts_completed = 0; 5854 5855 #ifdef QLNX_TRACE_PERF_DATA 5856 fp->tx_pkts_trans_ctx = 0; 5857 fp->tx_pkts_compl_ctx = 0; 5858 fp->tx_pkts_trans_fp = 0; 5859 fp->tx_pkts_compl_fp = 0; 5860 fp->tx_pkts_compl_intr = 0; 5861 #endif 5862 fp->tx_lso_wnd_min_len = 0; 5863 fp->tx_defrag = 0; 5864 fp->tx_nsegs_gt_elem_left = 0; 5865 fp->tx_tso_max_nsegs = 0; 5866 fp->tx_tso_min_nsegs = 0; 5867 fp->err_tx_nsegs_gt_elem_left = 0; 5868 fp->err_tx_dmamap_create = 0; 5869 fp->err_tx_defrag_dmamap_load = 0; 5870 fp->err_tx_non_tso_max_seg = 0; 5871 fp->err_tx_dmamap_load = 0; 5872 fp->err_tx_defrag = 0; 5873 fp->err_tx_free_pkt_null = 0; 5874 fp->err_tx_cons_idx_conflict = 0; 5875 5876 fp->rx_pkts = 0; 5877 fp->err_m_getcl = 0; 5878 fp->err_m_getjcl = 0; 5879 } 5880 return; 5881 } 5882 5883 void 5884 qlnx_free_mem_sb(qlnx_host_t *ha, struct ecore_sb_info *sb_info) 5885 { 5886 struct ecore_dev *cdev; 5887 5888 cdev = &ha->cdev; 5889 5890 if (sb_info->sb_virt) { 5891 OSAL_DMA_FREE_COHERENT(cdev, ((void *)sb_info->sb_virt), 5892 (sb_info->sb_phys), (sizeof(*sb_info->sb_virt))); 5893 sb_info->sb_virt = NULL; 5894 } 5895 } 5896 5897 static int 5898 qlnx_sb_init(struct ecore_dev *cdev, struct ecore_sb_info *sb_info, 5899 void *sb_virt_addr, bus_addr_t sb_phy_addr, u16 sb_id) 5900 { 5901 struct ecore_hwfn *p_hwfn; 5902 int hwfn_index, rc; 5903 u16 rel_sb_id; 5904 5905 hwfn_index = sb_id % cdev->num_hwfns; 5906 p_hwfn = &cdev->hwfns[hwfn_index]; 5907 rel_sb_id = sb_id / cdev->num_hwfns; 5908 5909 QL_DPRINT2(((qlnx_host_t *)cdev), 5910 "hwfn_index = %d p_hwfn = %p sb_id = 0x%x rel_sb_id = 0x%x \ 5911 sb_info = %p sb_virt_addr = %p sb_phy_addr = %p\n", 5912 hwfn_index, p_hwfn, sb_id, rel_sb_id, sb_info, 5913 sb_virt_addr, (void *)sb_phy_addr); 5914 5915 rc = ecore_int_sb_init(p_hwfn, p_hwfn->p_main_ptt, sb_info, 5916 sb_virt_addr, sb_phy_addr, rel_sb_id); 5917 5918 return rc; 5919 } 5920 5921 /* This function allocates fast-path status block memory */ 5922 int 5923 qlnx_alloc_mem_sb(qlnx_host_t *ha, struct ecore_sb_info *sb_info, u16 sb_id) 5924 { 5925 struct status_block_e4 *sb_virt; 5926 bus_addr_t sb_phys; 5927 int rc; 5928 uint32_t size; 5929 struct ecore_dev *cdev; 5930 5931 cdev = &ha->cdev; 5932 5933 size = sizeof(*sb_virt); 5934 sb_virt = OSAL_DMA_ALLOC_COHERENT(cdev, (&sb_phys), size); 5935 5936 if (!sb_virt) { 5937 QL_DPRINT1(ha, "Status block allocation failed\n"); 5938 return -ENOMEM; 5939 } 5940 5941 rc = qlnx_sb_init(cdev, sb_info, sb_virt, sb_phys, sb_id); 5942 if (rc) { 5943 OSAL_DMA_FREE_COHERENT(cdev, sb_virt, sb_phys, size); 5944 } 5945 5946 return rc; 5947 } 5948 5949 static void 5950 qlnx_free_rx_buffers(qlnx_host_t *ha, struct qlnx_rx_queue *rxq) 5951 { 5952 int i; 5953 struct sw_rx_data *rx_buf; 5954 5955 for (i = 0; i < rxq->num_rx_buffers; i++) { 5956 rx_buf = &rxq->sw_rx_ring[i]; 5957 5958 if (rx_buf->data != NULL) { 5959 if (rx_buf->map != NULL) { 5960 bus_dmamap_unload(ha->rx_tag, rx_buf->map); 5961 bus_dmamap_destroy(ha->rx_tag, rx_buf->map); 5962 rx_buf->map = NULL; 5963 } 5964 m_freem(rx_buf->data); 5965 rx_buf->data = NULL; 5966 } 5967 } 5968 return; 5969 } 5970 5971 static void 5972 qlnx_free_mem_rxq(qlnx_host_t *ha, struct qlnx_rx_queue *rxq) 5973 { 5974 struct ecore_dev *cdev; 5975 int i; 5976 5977 cdev = &ha->cdev; 5978 5979 qlnx_free_rx_buffers(ha, rxq); 5980 5981 for (i = 0; i < ETH_TPA_MAX_AGGS_NUM; i++) { 5982 qlnx_free_tpa_mbuf(ha, &rxq->tpa_info[i]); 5983 if (rxq->tpa_info[i].mpf != NULL) 5984 m_freem(rxq->tpa_info[i].mpf); 5985 } 5986 5987 bzero((void *)&rxq->sw_rx_ring[0], 5988 (sizeof (struct sw_rx_data) * RX_RING_SIZE)); 5989 5990 /* Free the real RQ ring used by FW */ 5991 if (rxq->rx_bd_ring.p_virt_addr) { 5992 ecore_chain_free(cdev, &rxq->rx_bd_ring); 5993 rxq->rx_bd_ring.p_virt_addr = NULL; 5994 } 5995 5996 /* Free the real completion ring used by FW */ 5997 if (rxq->rx_comp_ring.p_virt_addr && 5998 rxq->rx_comp_ring.pbl_sp.p_virt_table) { 5999 ecore_chain_free(cdev, &rxq->rx_comp_ring); 6000 rxq->rx_comp_ring.p_virt_addr = NULL; 6001 rxq->rx_comp_ring.pbl_sp.p_virt_table = NULL; 6002 } 6003 6004 #ifdef QLNX_SOFT_LRO 6005 { 6006 struct lro_ctrl *lro; 6007 6008 lro = &rxq->lro; 6009 tcp_lro_free(lro); 6010 } 6011 #endif /* #ifdef QLNX_SOFT_LRO */ 6012 6013 return; 6014 } 6015 6016 static int 6017 qlnx_alloc_rx_buffer(qlnx_host_t *ha, struct qlnx_rx_queue *rxq) 6018 { 6019 register struct mbuf *mp; 6020 uint16_t rx_buf_size; 6021 struct sw_rx_data *sw_rx_data; 6022 struct eth_rx_bd *rx_bd; 6023 dma_addr_t dma_addr; 6024 bus_dmamap_t map; 6025 bus_dma_segment_t segs[1]; 6026 int nsegs; 6027 int ret; 6028 6029 rx_buf_size = rxq->rx_buf_size; 6030 6031 mp = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, rx_buf_size); 6032 6033 if (mp == NULL) { 6034 QL_DPRINT1(ha, "Failed to allocate Rx data\n"); 6035 return -ENOMEM; 6036 } 6037 6038 mp->m_len = mp->m_pkthdr.len = rx_buf_size; 6039 6040 map = (bus_dmamap_t)0; 6041 6042 ret = bus_dmamap_load_mbuf_sg(ha->rx_tag, map, mp, segs, &nsegs, 6043 BUS_DMA_NOWAIT); 6044 dma_addr = segs[0].ds_addr; 6045 6046 if (ret || !dma_addr || (nsegs != 1)) { 6047 m_freem(mp); 6048 QL_DPRINT1(ha, "bus_dmamap_load failed[%d, 0x%016llx, %d]\n", 6049 ret, (long long unsigned int)dma_addr, nsegs); 6050 return -ENOMEM; 6051 } 6052 6053 sw_rx_data = &rxq->sw_rx_ring[rxq->sw_rx_prod]; 6054 sw_rx_data->data = mp; 6055 sw_rx_data->dma_addr = dma_addr; 6056 sw_rx_data->map = map; 6057 6058 /* Advance PROD and get BD pointer */ 6059 rx_bd = (struct eth_rx_bd *)ecore_chain_produce(&rxq->rx_bd_ring); 6060 rx_bd->addr.hi = htole32(U64_HI(dma_addr)); 6061 rx_bd->addr.lo = htole32(U64_LO(dma_addr)); 6062 bus_dmamap_sync(ha->rx_tag, map, BUS_DMASYNC_PREREAD); 6063 6064 rxq->sw_rx_prod = (rxq->sw_rx_prod + 1) & (RX_RING_SIZE - 1); 6065 6066 return 0; 6067 } 6068 6069 static int 6070 qlnx_alloc_tpa_mbuf(qlnx_host_t *ha, uint16_t rx_buf_size, 6071 struct qlnx_agg_info *tpa) 6072 { 6073 struct mbuf *mp; 6074 dma_addr_t dma_addr; 6075 bus_dmamap_t map; 6076 bus_dma_segment_t segs[1]; 6077 int nsegs; 6078 int ret; 6079 struct sw_rx_data *rx_buf; 6080 6081 mp = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, rx_buf_size); 6082 6083 if (mp == NULL) { 6084 QL_DPRINT1(ha, "Failed to allocate Rx data\n"); 6085 return -ENOMEM; 6086 } 6087 6088 mp->m_len = mp->m_pkthdr.len = rx_buf_size; 6089 6090 map = (bus_dmamap_t)0; 6091 6092 ret = bus_dmamap_load_mbuf_sg(ha->rx_tag, map, mp, segs, &nsegs, 6093 BUS_DMA_NOWAIT); 6094 dma_addr = segs[0].ds_addr; 6095 6096 if (ret || !dma_addr || (nsegs != 1)) { 6097 m_freem(mp); 6098 QL_DPRINT1(ha, "bus_dmamap_load failed[%d, 0x%016llx, %d]\n", 6099 ret, (long long unsigned int)dma_addr, nsegs); 6100 return -ENOMEM; 6101 } 6102 6103 rx_buf = &tpa->rx_buf; 6104 6105 memset(rx_buf, 0, sizeof (struct sw_rx_data)); 6106 6107 rx_buf->data = mp; 6108 rx_buf->dma_addr = dma_addr; 6109 rx_buf->map = map; 6110 6111 bus_dmamap_sync(ha->rx_tag, map, BUS_DMASYNC_PREREAD); 6112 6113 return (0); 6114 } 6115 6116 static void 6117 qlnx_free_tpa_mbuf(qlnx_host_t *ha, struct qlnx_agg_info *tpa) 6118 { 6119 struct sw_rx_data *rx_buf; 6120 6121 rx_buf = &tpa->rx_buf; 6122 6123 if (rx_buf->data != NULL) { 6124 if (rx_buf->map != NULL) { 6125 bus_dmamap_unload(ha->rx_tag, rx_buf->map); 6126 bus_dmamap_destroy(ha->rx_tag, rx_buf->map); 6127 rx_buf->map = NULL; 6128 } 6129 m_freem(rx_buf->data); 6130 rx_buf->data = NULL; 6131 } 6132 return; 6133 } 6134 6135 /* This function allocates all memory needed per Rx queue */ 6136 static int 6137 qlnx_alloc_mem_rxq(qlnx_host_t *ha, struct qlnx_rx_queue *rxq) 6138 { 6139 int i, rc, num_allocated; 6140 struct ecore_dev *cdev; 6141 6142 cdev = &ha->cdev; 6143 6144 rxq->num_rx_buffers = RX_RING_SIZE; 6145 6146 rxq->rx_buf_size = ha->rx_buf_size; 6147 6148 /* Allocate the parallel driver ring for Rx buffers */ 6149 bzero((void *)&rxq->sw_rx_ring[0], 6150 (sizeof (struct sw_rx_data) * RX_RING_SIZE)); 6151 6152 /* Allocate FW Rx ring */ 6153 6154 rc = ecore_chain_alloc(cdev, 6155 ECORE_CHAIN_USE_TO_CONSUME_PRODUCE, 6156 ECORE_CHAIN_MODE_NEXT_PTR, 6157 ECORE_CHAIN_CNT_TYPE_U16, 6158 RX_RING_SIZE, 6159 sizeof(struct eth_rx_bd), 6160 &rxq->rx_bd_ring, NULL); 6161 6162 if (rc) 6163 goto err; 6164 6165 /* Allocate FW completion ring */ 6166 rc = ecore_chain_alloc(cdev, 6167 ECORE_CHAIN_USE_TO_CONSUME, 6168 ECORE_CHAIN_MODE_PBL, 6169 ECORE_CHAIN_CNT_TYPE_U16, 6170 RX_RING_SIZE, 6171 sizeof(union eth_rx_cqe), 6172 &rxq->rx_comp_ring, NULL); 6173 6174 if (rc) 6175 goto err; 6176 6177 /* Allocate buffers for the Rx ring */ 6178 6179 for (i = 0; i < ETH_TPA_MAX_AGGS_NUM; i++) { 6180 rc = qlnx_alloc_tpa_mbuf(ha, rxq->rx_buf_size, 6181 &rxq->tpa_info[i]); 6182 if (rc) 6183 break; 6184 } 6185 6186 for (i = 0; i < rxq->num_rx_buffers; i++) { 6187 rc = qlnx_alloc_rx_buffer(ha, rxq); 6188 if (rc) 6189 break; 6190 } 6191 num_allocated = i; 6192 if (!num_allocated) { 6193 QL_DPRINT1(ha, "Rx buffers allocation failed\n"); 6194 goto err; 6195 } else if (num_allocated < rxq->num_rx_buffers) { 6196 QL_DPRINT1(ha, "Allocated less buffers than" 6197 " desired (%d allocated)\n", num_allocated); 6198 } 6199 6200 #ifdef QLNX_SOFT_LRO 6201 6202 { 6203 struct lro_ctrl *lro; 6204 6205 lro = &rxq->lro; 6206 6207 if (tcp_lro_init_args(lro, ifp, 0, rxq->num_rx_buffers)) { 6208 QL_DPRINT1(ha, "tcp_lro_init[%d] failed\n", 6209 rxq->rxq_id); 6210 goto err; 6211 } 6212 6213 lro->ifp = ha->ifp; 6214 } 6215 #endif /* #ifdef QLNX_SOFT_LRO */ 6216 return 0; 6217 6218 err: 6219 qlnx_free_mem_rxq(ha, rxq); 6220 return -ENOMEM; 6221 } 6222 6223 static void 6224 qlnx_free_mem_txq(qlnx_host_t *ha, struct qlnx_fastpath *fp, 6225 struct qlnx_tx_queue *txq) 6226 { 6227 struct ecore_dev *cdev; 6228 6229 cdev = &ha->cdev; 6230 6231 bzero((void *)&txq->sw_tx_ring[0], 6232 (sizeof (struct sw_tx_bd) * TX_RING_SIZE)); 6233 6234 /* Free the real RQ ring used by FW */ 6235 if (txq->tx_pbl.p_virt_addr) { 6236 ecore_chain_free(cdev, &txq->tx_pbl); 6237 txq->tx_pbl.p_virt_addr = NULL; 6238 } 6239 return; 6240 } 6241 6242 /* This function allocates all memory needed per Tx queue */ 6243 static int 6244 qlnx_alloc_mem_txq(qlnx_host_t *ha, struct qlnx_fastpath *fp, 6245 struct qlnx_tx_queue *txq) 6246 { 6247 int ret = ECORE_SUCCESS; 6248 union eth_tx_bd_types *p_virt; 6249 struct ecore_dev *cdev; 6250 6251 cdev = &ha->cdev; 6252 6253 bzero((void *)&txq->sw_tx_ring[0], 6254 (sizeof (struct sw_tx_bd) * TX_RING_SIZE)); 6255 6256 /* Allocate the real Tx ring to be used by FW */ 6257 ret = ecore_chain_alloc(cdev, 6258 ECORE_CHAIN_USE_TO_CONSUME_PRODUCE, 6259 ECORE_CHAIN_MODE_PBL, 6260 ECORE_CHAIN_CNT_TYPE_U16, 6261 TX_RING_SIZE, 6262 sizeof(*p_virt), 6263 &txq->tx_pbl, NULL); 6264 6265 if (ret != ECORE_SUCCESS) { 6266 goto err; 6267 } 6268 6269 txq->num_tx_buffers = TX_RING_SIZE; 6270 6271 return 0; 6272 6273 err: 6274 qlnx_free_mem_txq(ha, fp, txq); 6275 return -ENOMEM; 6276 } 6277 6278 static void 6279 qlnx_free_tx_br(qlnx_host_t *ha, struct qlnx_fastpath *fp) 6280 { 6281 struct mbuf *mp; 6282 if_t ifp = ha->ifp; 6283 6284 if (mtx_initialized(&fp->tx_mtx)) { 6285 if (fp->tx_br != NULL) { 6286 mtx_lock(&fp->tx_mtx); 6287 6288 while ((mp = drbr_dequeue(ifp, fp->tx_br)) != NULL) { 6289 fp->tx_pkts_freed++; 6290 m_freem(mp); 6291 } 6292 6293 mtx_unlock(&fp->tx_mtx); 6294 6295 buf_ring_free(fp->tx_br, M_DEVBUF); 6296 fp->tx_br = NULL; 6297 } 6298 mtx_destroy(&fp->tx_mtx); 6299 } 6300 return; 6301 } 6302 6303 static void 6304 qlnx_free_mem_fp(qlnx_host_t *ha, struct qlnx_fastpath *fp) 6305 { 6306 int tc; 6307 6308 qlnx_free_mem_sb(ha, fp->sb_info); 6309 6310 qlnx_free_mem_rxq(ha, fp->rxq); 6311 6312 for (tc = 0; tc < ha->num_tc; tc++) 6313 qlnx_free_mem_txq(ha, fp, fp->txq[tc]); 6314 6315 return; 6316 } 6317 6318 static int 6319 qlnx_alloc_tx_br(qlnx_host_t *ha, struct qlnx_fastpath *fp) 6320 { 6321 snprintf(fp->tx_mtx_name, sizeof(fp->tx_mtx_name), 6322 "qlnx%d_fp%d_tx_mq_lock", ha->dev_unit, fp->rss_id); 6323 6324 mtx_init(&fp->tx_mtx, fp->tx_mtx_name, NULL, MTX_DEF); 6325 6326 fp->tx_br = buf_ring_alloc(TX_RING_SIZE, M_DEVBUF, 6327 M_NOWAIT, &fp->tx_mtx); 6328 if (fp->tx_br == NULL) { 6329 QL_DPRINT1(ha, "buf_ring_alloc failed for fp[%d, %d]\n", 6330 ha->dev_unit, fp->rss_id); 6331 return -ENOMEM; 6332 } 6333 return 0; 6334 } 6335 6336 static int 6337 qlnx_alloc_mem_fp(qlnx_host_t *ha, struct qlnx_fastpath *fp) 6338 { 6339 int rc, tc; 6340 6341 rc = qlnx_alloc_mem_sb(ha, fp->sb_info, fp->rss_id); 6342 if (rc) 6343 goto err; 6344 6345 if (ha->rx_jumbo_buf_eq_mtu) { 6346 if (ha->max_frame_size <= MCLBYTES) 6347 ha->rx_buf_size = MCLBYTES; 6348 else if (ha->max_frame_size <= MJUMPAGESIZE) 6349 ha->rx_buf_size = MJUMPAGESIZE; 6350 else if (ha->max_frame_size <= MJUM9BYTES) 6351 ha->rx_buf_size = MJUM9BYTES; 6352 else if (ha->max_frame_size <= MJUM16BYTES) 6353 ha->rx_buf_size = MJUM16BYTES; 6354 } else { 6355 if (ha->max_frame_size <= MCLBYTES) 6356 ha->rx_buf_size = MCLBYTES; 6357 else 6358 ha->rx_buf_size = MJUMPAGESIZE; 6359 } 6360 6361 rc = qlnx_alloc_mem_rxq(ha, fp->rxq); 6362 if (rc) 6363 goto err; 6364 6365 for (tc = 0; tc < ha->num_tc; tc++) { 6366 rc = qlnx_alloc_mem_txq(ha, fp, fp->txq[tc]); 6367 if (rc) 6368 goto err; 6369 } 6370 6371 return 0; 6372 6373 err: 6374 qlnx_free_mem_fp(ha, fp); 6375 return -ENOMEM; 6376 } 6377 6378 static void 6379 qlnx_free_mem_load(qlnx_host_t *ha) 6380 { 6381 int i; 6382 6383 for (i = 0; i < ha->num_rss; i++) { 6384 struct qlnx_fastpath *fp = &ha->fp_array[i]; 6385 6386 qlnx_free_mem_fp(ha, fp); 6387 } 6388 return; 6389 } 6390 6391 static int 6392 qlnx_alloc_mem_load(qlnx_host_t *ha) 6393 { 6394 int rc = 0, rss_id; 6395 6396 for (rss_id = 0; rss_id < ha->num_rss; rss_id++) { 6397 struct qlnx_fastpath *fp = &ha->fp_array[rss_id]; 6398 6399 rc = qlnx_alloc_mem_fp(ha, fp); 6400 if (rc) 6401 break; 6402 } 6403 return (rc); 6404 } 6405 6406 static int 6407 qlnx_start_vport(struct ecore_dev *cdev, 6408 u8 vport_id, 6409 u16 mtu, 6410 u8 drop_ttl0_flg, 6411 u8 inner_vlan_removal_en_flg, 6412 u8 tx_switching, 6413 u8 hw_lro_enable) 6414 { 6415 int rc, i; 6416 struct ecore_sp_vport_start_params vport_start_params = { 0 }; 6417 qlnx_host_t *ha __unused; 6418 6419 ha = (qlnx_host_t *)cdev; 6420 6421 vport_start_params.remove_inner_vlan = inner_vlan_removal_en_flg; 6422 vport_start_params.tx_switching = 0; 6423 vport_start_params.handle_ptp_pkts = 0; 6424 vport_start_params.only_untagged = 0; 6425 vport_start_params.drop_ttl0 = drop_ttl0_flg; 6426 6427 vport_start_params.tpa_mode = 6428 (hw_lro_enable ? ECORE_TPA_MODE_RSC : ECORE_TPA_MODE_NONE); 6429 vport_start_params.max_buffers_per_cqe = QLNX_TPA_MAX_AGG_BUFFERS; 6430 6431 vport_start_params.vport_id = vport_id; 6432 vport_start_params.mtu = mtu; 6433 6434 QL_DPRINT2(ha, "Setting mtu to %d and VPORT ID = %d\n", mtu, vport_id); 6435 6436 for_each_hwfn(cdev, i) { 6437 struct ecore_hwfn *p_hwfn = &cdev->hwfns[i]; 6438 6439 vport_start_params.concrete_fid = p_hwfn->hw_info.concrete_fid; 6440 vport_start_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 6441 6442 rc = ecore_sp_vport_start(p_hwfn, &vport_start_params); 6443 6444 if (rc) { 6445 QL_DPRINT1(ha, "Failed to start VPORT V-PORT %d" 6446 " with MTU %d\n" , vport_id, mtu); 6447 return -ENOMEM; 6448 } 6449 6450 ecore_hw_start_fastpath(p_hwfn); 6451 6452 QL_DPRINT2(ha, "Started V-PORT %d with MTU %d\n", 6453 vport_id, mtu); 6454 } 6455 return 0; 6456 } 6457 6458 static int 6459 qlnx_update_vport(struct ecore_dev *cdev, 6460 struct qlnx_update_vport_params *params) 6461 { 6462 struct ecore_sp_vport_update_params sp_params; 6463 int rc, i, j, fp_index; 6464 struct ecore_hwfn *p_hwfn; 6465 struct ecore_rss_params *rss; 6466 qlnx_host_t *ha = (qlnx_host_t *)cdev; 6467 struct qlnx_fastpath *fp; 6468 6469 memset(&sp_params, 0, sizeof(sp_params)); 6470 /* Translate protocol params into sp params */ 6471 sp_params.vport_id = params->vport_id; 6472 6473 sp_params.update_vport_active_rx_flg = 6474 params->update_vport_active_rx_flg; 6475 sp_params.vport_active_rx_flg = params->vport_active_rx_flg; 6476 6477 sp_params.update_vport_active_tx_flg = 6478 params->update_vport_active_tx_flg; 6479 sp_params.vport_active_tx_flg = params->vport_active_tx_flg; 6480 6481 sp_params.update_inner_vlan_removal_flg = 6482 params->update_inner_vlan_removal_flg; 6483 sp_params.inner_vlan_removal_flg = params->inner_vlan_removal_flg; 6484 6485 sp_params.sge_tpa_params = params->sge_tpa_params; 6486 6487 /* RSS - is a bit tricky, since upper-layer isn't familiar with hwfns. 6488 * We need to re-fix the rss values per engine for CMT. 6489 */ 6490 if (params->rss_params->update_rss_config) 6491 sp_params.rss_params = params->rss_params; 6492 else 6493 sp_params.rss_params = NULL; 6494 6495 for_each_hwfn(cdev, i) { 6496 p_hwfn = &cdev->hwfns[i]; 6497 6498 if ((cdev->num_hwfns > 1) && 6499 params->rss_params->update_rss_config && 6500 params->rss_params->rss_enable) { 6501 rss = params->rss_params; 6502 6503 for (j = 0; j < ECORE_RSS_IND_TABLE_SIZE; j++) { 6504 fp_index = ((cdev->num_hwfns * j) + i) % 6505 ha->num_rss; 6506 6507 fp = &ha->fp_array[fp_index]; 6508 rss->rss_ind_table[j] = fp->rxq->handle; 6509 } 6510 6511 for (j = 0; j < ECORE_RSS_IND_TABLE_SIZE;) { 6512 QL_DPRINT3(ha, "%p %p %p %p %p %p %p %p \n", 6513 rss->rss_ind_table[j], 6514 rss->rss_ind_table[j+1], 6515 rss->rss_ind_table[j+2], 6516 rss->rss_ind_table[j+3], 6517 rss->rss_ind_table[j+4], 6518 rss->rss_ind_table[j+5], 6519 rss->rss_ind_table[j+6], 6520 rss->rss_ind_table[j+7]); 6521 j += 8; 6522 } 6523 } 6524 6525 sp_params.opaque_fid = p_hwfn->hw_info.opaque_fid; 6526 6527 QL_DPRINT1(ha, "Update sp vport ID=%d\n", params->vport_id); 6528 6529 rc = ecore_sp_vport_update(p_hwfn, &sp_params, 6530 ECORE_SPQ_MODE_EBLOCK, NULL); 6531 if (rc) { 6532 QL_DPRINT1(ha, "Failed to update VPORT\n"); 6533 return rc; 6534 } 6535 6536 QL_DPRINT2(ha, "Updated V-PORT %d: tx_active_flag %d, \ 6537 rx_active_flag %d [tx_update %d], [rx_update %d]\n", 6538 params->vport_id, params->vport_active_tx_flg, 6539 params->vport_active_rx_flg, 6540 params->update_vport_active_tx_flg, 6541 params->update_vport_active_rx_flg); 6542 } 6543 6544 return 0; 6545 } 6546 6547 static void 6548 qlnx_reuse_rx_data(struct qlnx_rx_queue *rxq) 6549 { 6550 struct eth_rx_bd *rx_bd_cons = 6551 ecore_chain_consume(&rxq->rx_bd_ring); 6552 struct eth_rx_bd *rx_bd_prod = 6553 ecore_chain_produce(&rxq->rx_bd_ring); 6554 struct sw_rx_data *sw_rx_data_cons = 6555 &rxq->sw_rx_ring[rxq->sw_rx_cons]; 6556 struct sw_rx_data *sw_rx_data_prod = 6557 &rxq->sw_rx_ring[rxq->sw_rx_prod]; 6558 6559 sw_rx_data_prod->data = sw_rx_data_cons->data; 6560 memcpy(rx_bd_prod, rx_bd_cons, sizeof(struct eth_rx_bd)); 6561 6562 rxq->sw_rx_cons = (rxq->sw_rx_cons + 1) & (RX_RING_SIZE - 1); 6563 rxq->sw_rx_prod = (rxq->sw_rx_prod + 1) & (RX_RING_SIZE - 1); 6564 6565 return; 6566 } 6567 6568 static void 6569 qlnx_update_rx_prod(struct ecore_hwfn *p_hwfn, struct qlnx_rx_queue *rxq) 6570 { 6571 6572 uint16_t bd_prod; 6573 uint16_t cqe_prod; 6574 union { 6575 struct eth_rx_prod_data rx_prod_data; 6576 uint32_t data32; 6577 } rx_prods; 6578 6579 bd_prod = ecore_chain_get_prod_idx(&rxq->rx_bd_ring); 6580 cqe_prod = ecore_chain_get_prod_idx(&rxq->rx_comp_ring); 6581 6582 /* Update producers */ 6583 rx_prods.rx_prod_data.bd_prod = htole16(bd_prod); 6584 rx_prods.rx_prod_data.cqe_prod = htole16(cqe_prod); 6585 6586 /* Make sure that the BD and SGE data is updated before updating the 6587 * producers since FW might read the BD/SGE right after the producer 6588 * is updated. 6589 */ 6590 wmb(); 6591 6592 #ifdef ECORE_CONFIG_DIRECT_HWFN 6593 internal_ram_wr(p_hwfn, rxq->hw_rxq_prod_addr, 6594 sizeof(rx_prods), &rx_prods.data32); 6595 #else 6596 internal_ram_wr(rxq->hw_rxq_prod_addr, 6597 sizeof(rx_prods), &rx_prods.data32); 6598 #endif 6599 6600 /* mmiowb is needed to synchronize doorbell writes from more than one 6601 * processor. It guarantees that the write arrives to the device before 6602 * the napi lock is released and another qlnx_poll is called (possibly 6603 * on another CPU). Without this barrier, the next doorbell can bypass 6604 * this doorbell. This is applicable to IA64/Altix systems. 6605 */ 6606 wmb(); 6607 6608 return; 6609 } 6610 6611 static uint32_t qlnx_hash_key[] = { 6612 ((0x6d << 24)|(0x5a << 16)|(0x56 << 8)|0xda), 6613 ((0x25 << 24)|(0x5b << 16)|(0x0e << 8)|0xc2), 6614 ((0x41 << 24)|(0x67 << 16)|(0x25 << 8)|0x3d), 6615 ((0x43 << 24)|(0xa3 << 16)|(0x8f << 8)|0xb0), 6616 ((0xd0 << 24)|(0xca << 16)|(0x2b << 8)|0xcb), 6617 ((0xae << 24)|(0x7b << 16)|(0x30 << 8)|0xb4), 6618 ((0x77 << 24)|(0xcb << 16)|(0x2d << 8)|0xa3), 6619 ((0x80 << 24)|(0x30 << 16)|(0xf2 << 8)|0x0c), 6620 ((0x6a << 24)|(0x42 << 16)|(0xb7 << 8)|0x3b), 6621 ((0xbe << 24)|(0xac << 16)|(0x01 << 8)|0xfa)}; 6622 6623 static int 6624 qlnx_start_queues(qlnx_host_t *ha) 6625 { 6626 int rc, tc, i, vport_id = 0, 6627 drop_ttl0_flg = 1, vlan_removal_en = 1, 6628 tx_switching = 0, hw_lro_enable = 0; 6629 struct ecore_dev *cdev = &ha->cdev; 6630 struct ecore_rss_params *rss_params = &ha->rss_params; 6631 struct qlnx_update_vport_params vport_update_params; 6632 if_t ifp; 6633 struct ecore_hwfn *p_hwfn; 6634 struct ecore_sge_tpa_params tpa_params; 6635 struct ecore_queue_start_common_params qparams; 6636 struct qlnx_fastpath *fp; 6637 6638 ifp = ha->ifp; 6639 6640 QL_DPRINT1(ha, "Num RSS = %d\n", ha->num_rss); 6641 6642 if (!ha->num_rss) { 6643 QL_DPRINT1(ha, "Cannot update V-VPORT as active as there" 6644 " are no Rx queues\n"); 6645 return -EINVAL; 6646 } 6647 6648 #ifndef QLNX_SOFT_LRO 6649 hw_lro_enable = if_getcapenable(ifp) & IFCAP_LRO; 6650 #endif /* #ifndef QLNX_SOFT_LRO */ 6651 6652 rc = qlnx_start_vport(cdev, vport_id, if_getmtu(ifp), drop_ttl0_flg, 6653 vlan_removal_en, tx_switching, hw_lro_enable); 6654 6655 if (rc) { 6656 QL_DPRINT1(ha, "Start V-PORT failed %d\n", rc); 6657 return rc; 6658 } 6659 6660 QL_DPRINT2(ha, "Start vport ramrod passed, " 6661 "vport_id = %d, MTU = %d, vlan_removal_en = %d\n", 6662 vport_id, (int)(if_getmtu(ifp) + 0xe), vlan_removal_en); 6663 6664 for_each_rss(i) { 6665 struct ecore_rxq_start_ret_params rx_ret_params; 6666 struct ecore_txq_start_ret_params tx_ret_params; 6667 6668 fp = &ha->fp_array[i]; 6669 p_hwfn = &cdev->hwfns[(fp->rss_id % cdev->num_hwfns)]; 6670 6671 bzero(&qparams, sizeof(struct ecore_queue_start_common_params)); 6672 bzero(&rx_ret_params, 6673 sizeof (struct ecore_rxq_start_ret_params)); 6674 6675 qparams.queue_id = i ; 6676 qparams.vport_id = vport_id; 6677 qparams.stats_id = vport_id; 6678 qparams.p_sb = fp->sb_info; 6679 qparams.sb_idx = RX_PI; 6680 6681 6682 rc = ecore_eth_rx_queue_start(p_hwfn, 6683 p_hwfn->hw_info.opaque_fid, 6684 &qparams, 6685 fp->rxq->rx_buf_size, /* bd_max_bytes */ 6686 /* bd_chain_phys_addr */ 6687 fp->rxq->rx_bd_ring.p_phys_addr, 6688 /* cqe_pbl_addr */ 6689 ecore_chain_get_pbl_phys(&fp->rxq->rx_comp_ring), 6690 /* cqe_pbl_size */ 6691 ecore_chain_get_page_cnt(&fp->rxq->rx_comp_ring), 6692 &rx_ret_params); 6693 6694 if (rc) { 6695 QL_DPRINT1(ha, "Start RXQ #%d failed %d\n", i, rc); 6696 return rc; 6697 } 6698 6699 fp->rxq->hw_rxq_prod_addr = rx_ret_params.p_prod; 6700 fp->rxq->handle = rx_ret_params.p_handle; 6701 fp->rxq->hw_cons_ptr = 6702 &fp->sb_info->sb_virt->pi_array[RX_PI]; 6703 6704 qlnx_update_rx_prod(p_hwfn, fp->rxq); 6705 6706 for (tc = 0; tc < ha->num_tc; tc++) { 6707 struct qlnx_tx_queue *txq = fp->txq[tc]; 6708 6709 bzero(&qparams, 6710 sizeof(struct ecore_queue_start_common_params)); 6711 bzero(&tx_ret_params, 6712 sizeof (struct ecore_txq_start_ret_params)); 6713 6714 qparams.queue_id = txq->index / cdev->num_hwfns ; 6715 qparams.vport_id = vport_id; 6716 qparams.stats_id = vport_id; 6717 qparams.p_sb = fp->sb_info; 6718 qparams.sb_idx = TX_PI(tc); 6719 6720 rc = ecore_eth_tx_queue_start(p_hwfn, 6721 p_hwfn->hw_info.opaque_fid, 6722 &qparams, tc, 6723 /* bd_chain_phys_addr */ 6724 ecore_chain_get_pbl_phys(&txq->tx_pbl), 6725 ecore_chain_get_page_cnt(&txq->tx_pbl), 6726 &tx_ret_params); 6727 6728 if (rc) { 6729 QL_DPRINT1(ha, "Start TXQ #%d failed %d\n", 6730 txq->index, rc); 6731 return rc; 6732 } 6733 6734 txq->doorbell_addr = tx_ret_params.p_doorbell; 6735 txq->handle = tx_ret_params.p_handle; 6736 6737 txq->hw_cons_ptr = 6738 &fp->sb_info->sb_virt->pi_array[TX_PI(tc)]; 6739 SET_FIELD(txq->tx_db.data.params, 6740 ETH_DB_DATA_DEST, DB_DEST_XCM); 6741 SET_FIELD(txq->tx_db.data.params, ETH_DB_DATA_AGG_CMD, 6742 DB_AGG_CMD_SET); 6743 SET_FIELD(txq->tx_db.data.params, 6744 ETH_DB_DATA_AGG_VAL_SEL, 6745 DQ_XCM_ETH_TX_BD_PROD_CMD); 6746 6747 txq->tx_db.data.agg_flags = DQ_XCM_ETH_DQ_CF_CMD; 6748 } 6749 } 6750 6751 /* Fill struct with RSS params */ 6752 if (ha->num_rss > 1) { 6753 rss_params->update_rss_config = 1; 6754 rss_params->rss_enable = 1; 6755 rss_params->update_rss_capabilities = 1; 6756 rss_params->update_rss_ind_table = 1; 6757 rss_params->update_rss_key = 1; 6758 rss_params->rss_caps = ECORE_RSS_IPV4 | ECORE_RSS_IPV6 | 6759 ECORE_RSS_IPV4_TCP | ECORE_RSS_IPV6_TCP; 6760 rss_params->rss_table_size_log = 7; /* 2^7 = 128 */ 6761 6762 for (i = 0; i < ECORE_RSS_IND_TABLE_SIZE; i++) { 6763 fp = &ha->fp_array[(i % ha->num_rss)]; 6764 rss_params->rss_ind_table[i] = fp->rxq->handle; 6765 } 6766 6767 for (i = 0; i < ECORE_RSS_KEY_SIZE; i++) 6768 rss_params->rss_key[i] = (__le32)qlnx_hash_key[i]; 6769 6770 } else { 6771 memset(rss_params, 0, sizeof(*rss_params)); 6772 } 6773 6774 /* Prepare and send the vport enable */ 6775 memset(&vport_update_params, 0, sizeof(vport_update_params)); 6776 vport_update_params.vport_id = vport_id; 6777 vport_update_params.update_vport_active_tx_flg = 1; 6778 vport_update_params.vport_active_tx_flg = 1; 6779 vport_update_params.update_vport_active_rx_flg = 1; 6780 vport_update_params.vport_active_rx_flg = 1; 6781 vport_update_params.rss_params = rss_params; 6782 vport_update_params.update_inner_vlan_removal_flg = 1; 6783 vport_update_params.inner_vlan_removal_flg = 1; 6784 6785 if (hw_lro_enable) { 6786 memset(&tpa_params, 0, sizeof (struct ecore_sge_tpa_params)); 6787 6788 tpa_params.max_buffers_per_cqe = QLNX_TPA_MAX_AGG_BUFFERS; 6789 6790 tpa_params.update_tpa_en_flg = 1; 6791 tpa_params.tpa_ipv4_en_flg = 1; 6792 tpa_params.tpa_ipv6_en_flg = 1; 6793 6794 tpa_params.update_tpa_param_flg = 1; 6795 tpa_params.tpa_pkt_split_flg = 0; 6796 tpa_params.tpa_hdr_data_split_flg = 0; 6797 tpa_params.tpa_gro_consistent_flg = 0; 6798 tpa_params.tpa_max_aggs_num = ETH_TPA_MAX_AGGS_NUM; 6799 tpa_params.tpa_max_size = (uint16_t)(-1); 6800 tpa_params.tpa_min_size_to_start = if_getmtu(ifp) / 2; 6801 tpa_params.tpa_min_size_to_cont = if_getmtu(ifp) / 2; 6802 6803 vport_update_params.sge_tpa_params = &tpa_params; 6804 } 6805 6806 rc = qlnx_update_vport(cdev, &vport_update_params); 6807 if (rc) { 6808 QL_DPRINT1(ha, "Update V-PORT failed %d\n", rc); 6809 return rc; 6810 } 6811 6812 return 0; 6813 } 6814 6815 static int 6816 qlnx_drain_txq(qlnx_host_t *ha, struct qlnx_fastpath *fp, 6817 struct qlnx_tx_queue *txq) 6818 { 6819 uint16_t hw_bd_cons; 6820 uint16_t ecore_cons_idx; 6821 6822 QL_DPRINT2(ha, "enter\n"); 6823 6824 hw_bd_cons = le16toh(*txq->hw_cons_ptr); 6825 6826 while (hw_bd_cons != 6827 (ecore_cons_idx = ecore_chain_get_cons_idx(&txq->tx_pbl))) { 6828 mtx_lock(&fp->tx_mtx); 6829 6830 (void)qlnx_tx_int(ha, fp, txq); 6831 6832 mtx_unlock(&fp->tx_mtx); 6833 6834 qlnx_mdelay(__func__, 2); 6835 6836 hw_bd_cons = le16toh(*txq->hw_cons_ptr); 6837 } 6838 6839 QL_DPRINT2(ha, "[%d, %d]: done\n", fp->rss_id, txq->index); 6840 6841 return 0; 6842 } 6843 6844 static int 6845 qlnx_stop_queues(qlnx_host_t *ha) 6846 { 6847 struct qlnx_update_vport_params vport_update_params; 6848 struct ecore_dev *cdev; 6849 struct qlnx_fastpath *fp; 6850 int rc, tc, i; 6851 6852 cdev = &ha->cdev; 6853 6854 /* Disable the vport */ 6855 6856 memset(&vport_update_params, 0, sizeof(vport_update_params)); 6857 6858 vport_update_params.vport_id = 0; 6859 vport_update_params.update_vport_active_tx_flg = 1; 6860 vport_update_params.vport_active_tx_flg = 0; 6861 vport_update_params.update_vport_active_rx_flg = 1; 6862 vport_update_params.vport_active_rx_flg = 0; 6863 vport_update_params.rss_params = &ha->rss_params; 6864 vport_update_params.rss_params->update_rss_config = 0; 6865 vport_update_params.rss_params->rss_enable = 0; 6866 vport_update_params.update_inner_vlan_removal_flg = 0; 6867 vport_update_params.inner_vlan_removal_flg = 0; 6868 6869 QL_DPRINT1(ha, "Update vport ID= %d\n", vport_update_params.vport_id); 6870 6871 rc = qlnx_update_vport(cdev, &vport_update_params); 6872 if (rc) { 6873 QL_DPRINT1(ha, "Failed to update vport\n"); 6874 return rc; 6875 } 6876 6877 /* Flush Tx queues. If needed, request drain from MCP */ 6878 for_each_rss(i) { 6879 fp = &ha->fp_array[i]; 6880 6881 for (tc = 0; tc < ha->num_tc; tc++) { 6882 struct qlnx_tx_queue *txq = fp->txq[tc]; 6883 6884 rc = qlnx_drain_txq(ha, fp, txq); 6885 if (rc) 6886 return rc; 6887 } 6888 } 6889 6890 /* Stop all Queues in reverse order*/ 6891 for (i = ha->num_rss - 1; i >= 0; i--) { 6892 struct ecore_hwfn *p_hwfn = &cdev->hwfns[(i % cdev->num_hwfns)]; 6893 6894 fp = &ha->fp_array[i]; 6895 6896 /* Stop the Tx Queue(s)*/ 6897 for (tc = 0; tc < ha->num_tc; tc++) { 6898 int tx_queue_id __unused; 6899 6900 tx_queue_id = tc * ha->num_rss + i; 6901 rc = ecore_eth_tx_queue_stop(p_hwfn, 6902 fp->txq[tc]->handle); 6903 6904 if (rc) { 6905 QL_DPRINT1(ha, "Failed to stop TXQ #%d\n", 6906 tx_queue_id); 6907 return rc; 6908 } 6909 } 6910 6911 /* Stop the Rx Queue*/ 6912 rc = ecore_eth_rx_queue_stop(p_hwfn, fp->rxq->handle, false, 6913 false); 6914 if (rc) { 6915 QL_DPRINT1(ha, "Failed to stop RXQ #%d\n", i); 6916 return rc; 6917 } 6918 } 6919 6920 /* Stop the vport */ 6921 for_each_hwfn(cdev, i) { 6922 struct ecore_hwfn *p_hwfn = &cdev->hwfns[i]; 6923 6924 rc = ecore_sp_vport_stop(p_hwfn, p_hwfn->hw_info.opaque_fid, 0); 6925 6926 if (rc) { 6927 QL_DPRINT1(ha, "Failed to stop VPORT\n"); 6928 return rc; 6929 } 6930 } 6931 6932 return rc; 6933 } 6934 6935 static int 6936 qlnx_set_ucast_rx_mac(qlnx_host_t *ha, 6937 enum ecore_filter_opcode opcode, 6938 unsigned char mac[ETH_ALEN]) 6939 { 6940 struct ecore_filter_ucast ucast; 6941 struct ecore_dev *cdev; 6942 int rc; 6943 6944 cdev = &ha->cdev; 6945 6946 bzero(&ucast, sizeof(struct ecore_filter_ucast)); 6947 6948 ucast.opcode = opcode; 6949 ucast.type = ECORE_FILTER_MAC; 6950 ucast.is_rx_filter = 1; 6951 ucast.vport_to_add_to = 0; 6952 memcpy(&ucast.mac[0], mac, ETH_ALEN); 6953 6954 rc = ecore_filter_ucast_cmd(cdev, &ucast, ECORE_SPQ_MODE_CB, NULL); 6955 6956 return (rc); 6957 } 6958 6959 static int 6960 qlnx_remove_all_ucast_mac(qlnx_host_t *ha) 6961 { 6962 struct ecore_filter_ucast ucast; 6963 struct ecore_dev *cdev; 6964 int rc; 6965 6966 bzero(&ucast, sizeof(struct ecore_filter_ucast)); 6967 6968 ucast.opcode = ECORE_FILTER_REPLACE; 6969 ucast.type = ECORE_FILTER_MAC; 6970 ucast.is_rx_filter = 1; 6971 6972 cdev = &ha->cdev; 6973 6974 rc = ecore_filter_ucast_cmd(cdev, &ucast, ECORE_SPQ_MODE_CB, NULL); 6975 6976 return (rc); 6977 } 6978 6979 static int 6980 qlnx_remove_all_mcast_mac(qlnx_host_t *ha) 6981 { 6982 struct ecore_filter_mcast *mcast; 6983 struct ecore_dev *cdev; 6984 int rc, i; 6985 6986 cdev = &ha->cdev; 6987 6988 mcast = &ha->ecore_mcast; 6989 bzero(mcast, sizeof(struct ecore_filter_mcast)); 6990 6991 mcast->opcode = ECORE_FILTER_REMOVE; 6992 6993 for (i = 0; i < QLNX_MAX_NUM_MULTICAST_ADDRS; i++) { 6994 if (ha->mcast[i].addr[0] || ha->mcast[i].addr[1] || 6995 ha->mcast[i].addr[2] || ha->mcast[i].addr[3] || 6996 ha->mcast[i].addr[4] || ha->mcast[i].addr[5]) { 6997 memcpy(&mcast->mac[i][0], &ha->mcast[i].addr[0], ETH_ALEN); 6998 mcast->num_mc_addrs++; 6999 } 7000 } 7001 mcast = &ha->ecore_mcast; 7002 7003 rc = ecore_filter_mcast_cmd(cdev, mcast, ECORE_SPQ_MODE_CB, NULL); 7004 7005 bzero(ha->mcast, (sizeof(qlnx_mcast_t) * QLNX_MAX_NUM_MULTICAST_ADDRS)); 7006 ha->nmcast = 0; 7007 7008 return (rc); 7009 } 7010 7011 static int 7012 qlnx_clean_filters(qlnx_host_t *ha) 7013 { 7014 int rc = 0; 7015 7016 /* Remove all unicast macs */ 7017 rc = qlnx_remove_all_ucast_mac(ha); 7018 if (rc) 7019 return rc; 7020 7021 /* Remove all multicast macs */ 7022 rc = qlnx_remove_all_mcast_mac(ha); 7023 if (rc) 7024 return rc; 7025 7026 rc = qlnx_set_ucast_rx_mac(ha, ECORE_FILTER_FLUSH, ha->primary_mac); 7027 7028 return (rc); 7029 } 7030 7031 static int 7032 qlnx_set_rx_accept_filter(qlnx_host_t *ha, uint8_t filter) 7033 { 7034 struct ecore_filter_accept_flags accept; 7035 int rc = 0; 7036 struct ecore_dev *cdev; 7037 7038 cdev = &ha->cdev; 7039 7040 bzero(&accept, sizeof(struct ecore_filter_accept_flags)); 7041 7042 accept.update_rx_mode_config = 1; 7043 accept.rx_accept_filter = filter; 7044 7045 accept.update_tx_mode_config = 1; 7046 accept.tx_accept_filter = ECORE_ACCEPT_UCAST_MATCHED | 7047 ECORE_ACCEPT_MCAST_MATCHED | ECORE_ACCEPT_BCAST; 7048 7049 rc = ecore_filter_accept_cmd(cdev, 0, accept, false, false, 7050 ECORE_SPQ_MODE_CB, NULL); 7051 7052 return (rc); 7053 } 7054 7055 static int 7056 qlnx_set_rx_mode(qlnx_host_t *ha) 7057 { 7058 int rc = 0; 7059 uint8_t filter; 7060 const if_t ifp = ha->ifp; 7061 const struct ifaddr *ifa; 7062 struct sockaddr_dl *sdl; 7063 7064 ifa = if_getifaddr(ifp); 7065 if (if_gettype(ifp) == IFT_ETHER && ifa != NULL && 7066 ifa->ifa_addr != NULL) { 7067 sdl = (struct sockaddr_dl *) ifa->ifa_addr; 7068 7069 rc = qlnx_set_ucast_rx_mac(ha, ECORE_FILTER_REPLACE, LLADDR(sdl)); 7070 } else { 7071 rc = qlnx_set_ucast_rx_mac(ha, ECORE_FILTER_REPLACE, ha->primary_mac); 7072 } 7073 if (rc) 7074 return rc; 7075 7076 rc = qlnx_remove_all_mcast_mac(ha); 7077 if (rc) 7078 return rc; 7079 7080 filter = ECORE_ACCEPT_UCAST_MATCHED | 7081 ECORE_ACCEPT_MCAST_MATCHED | 7082 ECORE_ACCEPT_BCAST; 7083 7084 if (qlnx_vf_device(ha) == 0 || (if_getflags(ha->ifp) & IFF_PROMISC)) { 7085 filter |= ECORE_ACCEPT_UCAST_UNMATCHED; 7086 filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 7087 } else if (if_getflags(ha->ifp) & IFF_ALLMULTI) { 7088 filter |= ECORE_ACCEPT_MCAST_UNMATCHED; 7089 } 7090 ha->filter = filter; 7091 7092 rc = qlnx_set_rx_accept_filter(ha, filter); 7093 7094 return (rc); 7095 } 7096 7097 static int 7098 qlnx_set_link(qlnx_host_t *ha, bool link_up) 7099 { 7100 int i, rc = 0; 7101 struct ecore_dev *cdev; 7102 struct ecore_hwfn *hwfn; 7103 struct ecore_ptt *ptt; 7104 7105 if (qlnx_vf_device(ha) == 0) 7106 return (0); 7107 7108 cdev = &ha->cdev; 7109 7110 for_each_hwfn(cdev, i) { 7111 hwfn = &cdev->hwfns[i]; 7112 7113 ptt = ecore_ptt_acquire(hwfn); 7114 if (!ptt) 7115 return -EBUSY; 7116 7117 rc = ecore_mcp_set_link(hwfn, ptt, link_up); 7118 7119 ecore_ptt_release(hwfn, ptt); 7120 7121 if (rc) 7122 return rc; 7123 } 7124 return (rc); 7125 } 7126 7127 static uint64_t 7128 qlnx_get_counter(if_t ifp, ift_counter cnt) 7129 { 7130 qlnx_host_t *ha; 7131 uint64_t count; 7132 7133 ha = (qlnx_host_t *)if_getsoftc(ifp); 7134 7135 switch (cnt) { 7136 case IFCOUNTER_IPACKETS: 7137 count = ha->hw_stats.common.rx_ucast_pkts + 7138 ha->hw_stats.common.rx_mcast_pkts + 7139 ha->hw_stats.common.rx_bcast_pkts; 7140 break; 7141 7142 case IFCOUNTER_IERRORS: 7143 count = ha->hw_stats.common.rx_crc_errors + 7144 ha->hw_stats.common.rx_align_errors + 7145 ha->hw_stats.common.rx_oversize_packets + 7146 ha->hw_stats.common.rx_undersize_packets; 7147 break; 7148 7149 case IFCOUNTER_OPACKETS: 7150 count = ha->hw_stats.common.tx_ucast_pkts + 7151 ha->hw_stats.common.tx_mcast_pkts + 7152 ha->hw_stats.common.tx_bcast_pkts; 7153 break; 7154 7155 case IFCOUNTER_OERRORS: 7156 count = ha->hw_stats.common.tx_err_drop_pkts; 7157 break; 7158 7159 case IFCOUNTER_COLLISIONS: 7160 return (0); 7161 7162 case IFCOUNTER_IBYTES: 7163 count = ha->hw_stats.common.rx_ucast_bytes + 7164 ha->hw_stats.common.rx_mcast_bytes + 7165 ha->hw_stats.common.rx_bcast_bytes; 7166 break; 7167 7168 case IFCOUNTER_OBYTES: 7169 count = ha->hw_stats.common.tx_ucast_bytes + 7170 ha->hw_stats.common.tx_mcast_bytes + 7171 ha->hw_stats.common.tx_bcast_bytes; 7172 break; 7173 7174 case IFCOUNTER_IMCASTS: 7175 count = ha->hw_stats.common.rx_mcast_bytes; 7176 break; 7177 7178 case IFCOUNTER_OMCASTS: 7179 count = ha->hw_stats.common.tx_mcast_bytes; 7180 break; 7181 7182 case IFCOUNTER_IQDROPS: 7183 case IFCOUNTER_OQDROPS: 7184 case IFCOUNTER_NOPROTO: 7185 7186 default: 7187 return (if_get_counter_default(ifp, cnt)); 7188 } 7189 return (count); 7190 } 7191 7192 static void 7193 qlnx_timer(void *arg) 7194 { 7195 qlnx_host_t *ha; 7196 7197 ha = (qlnx_host_t *)arg; 7198 7199 if (ha->error_recovery) { 7200 ha->error_recovery = 0; 7201 taskqueue_enqueue(ha->err_taskqueue, &ha->err_task); 7202 return; 7203 } 7204 7205 ecore_get_vport_stats(&ha->cdev, &ha->hw_stats); 7206 7207 if (ha->storm_stats_gather) 7208 qlnx_sample_storm_stats(ha); 7209 7210 callout_reset(&ha->qlnx_callout, hz, qlnx_timer, ha); 7211 7212 return; 7213 } 7214 7215 static int 7216 qlnx_load(qlnx_host_t *ha) 7217 { 7218 int i; 7219 int rc = 0; 7220 device_t dev; 7221 7222 dev = ha->pci_dev; 7223 7224 QL_DPRINT2(ha, "enter\n"); 7225 7226 rc = qlnx_alloc_mem_arrays(ha); 7227 if (rc) 7228 goto qlnx_load_exit0; 7229 7230 qlnx_init_fp(ha); 7231 7232 rc = qlnx_alloc_mem_load(ha); 7233 if (rc) 7234 goto qlnx_load_exit1; 7235 7236 QL_DPRINT2(ha, "Allocated %d RSS queues on %d TC/s\n", 7237 ha->num_rss, ha->num_tc); 7238 7239 for (i = 0; i < ha->num_rss; i++) { 7240 if ((rc = bus_setup_intr(dev, ha->irq_vec[i].irq, 7241 (INTR_TYPE_NET | INTR_MPSAFE), 7242 NULL, qlnx_fp_isr, &ha->irq_vec[i], 7243 &ha->irq_vec[i].handle))) { 7244 QL_DPRINT1(ha, "could not setup interrupt\n"); 7245 goto qlnx_load_exit2; 7246 } 7247 7248 QL_DPRINT2(ha, "rss_id = %d irq_rid %d \ 7249 irq %p handle %p\n", i, 7250 ha->irq_vec[i].irq_rid, 7251 ha->irq_vec[i].irq, ha->irq_vec[i].handle); 7252 7253 bus_bind_intr(dev, ha->irq_vec[i].irq, (i % mp_ncpus)); 7254 } 7255 7256 rc = qlnx_start_queues(ha); 7257 if (rc) 7258 goto qlnx_load_exit2; 7259 7260 QL_DPRINT2(ha, "Start VPORT, RXQ and TXQ succeeded\n"); 7261 7262 /* Add primary mac and set Rx filters */ 7263 rc = qlnx_set_rx_mode(ha); 7264 if (rc) 7265 goto qlnx_load_exit2; 7266 7267 /* Ask for link-up using current configuration */ 7268 qlnx_set_link(ha, true); 7269 7270 if (qlnx_vf_device(ha) == 0) 7271 qlnx_link_update(&ha->cdev.hwfns[0]); 7272 7273 ha->state = QLNX_STATE_OPEN; 7274 7275 bzero(&ha->hw_stats, sizeof(struct ecore_eth_stats)); 7276 7277 if (ha->flags.callout_init) 7278 callout_reset(&ha->qlnx_callout, hz, qlnx_timer, ha); 7279 7280 goto qlnx_load_exit0; 7281 7282 qlnx_load_exit2: 7283 qlnx_free_mem_load(ha); 7284 7285 qlnx_load_exit1: 7286 ha->num_rss = 0; 7287 7288 qlnx_load_exit0: 7289 QL_DPRINT2(ha, "exit [%d]\n", rc); 7290 return rc; 7291 } 7292 7293 static void 7294 qlnx_drain_soft_lro(qlnx_host_t *ha) 7295 { 7296 #ifdef QLNX_SOFT_LRO 7297 7298 if_t ifp; 7299 int i; 7300 7301 ifp = ha->ifp; 7302 7303 if (if_getcapenable(ifp) & IFCAP_LRO) { 7304 for (i = 0; i < ha->num_rss; i++) { 7305 struct qlnx_fastpath *fp = &ha->fp_array[i]; 7306 struct lro_ctrl *lro; 7307 7308 lro = &fp->rxq->lro; 7309 7310 tcp_lro_flush_all(lro); 7311 } 7312 } 7313 7314 #endif /* #ifdef QLNX_SOFT_LRO */ 7315 7316 return; 7317 } 7318 7319 static void 7320 qlnx_unload(qlnx_host_t *ha) 7321 { 7322 struct ecore_dev *cdev; 7323 device_t dev; 7324 int i; 7325 7326 cdev = &ha->cdev; 7327 dev = ha->pci_dev; 7328 7329 QL_DPRINT2(ha, "enter\n"); 7330 QL_DPRINT1(ha, " QLNX STATE = %d\n",ha->state); 7331 7332 if (ha->state == QLNX_STATE_OPEN) { 7333 qlnx_set_link(ha, false); 7334 qlnx_clean_filters(ha); 7335 qlnx_stop_queues(ha); 7336 ecore_hw_stop_fastpath(cdev); 7337 7338 for (i = 0; i < ha->num_rss; i++) { 7339 if (ha->irq_vec[i].handle) { 7340 (void)bus_teardown_intr(dev, 7341 ha->irq_vec[i].irq, 7342 ha->irq_vec[i].handle); 7343 ha->irq_vec[i].handle = NULL; 7344 } 7345 } 7346 7347 qlnx_drain_fp_taskqueues(ha); 7348 qlnx_drain_soft_lro(ha); 7349 qlnx_free_mem_load(ha); 7350 } 7351 7352 if (ha->flags.callout_init) 7353 callout_drain(&ha->qlnx_callout); 7354 7355 qlnx_mdelay(__func__, 1000); 7356 7357 ha->state = QLNX_STATE_CLOSED; 7358 7359 QL_DPRINT2(ha, "exit\n"); 7360 return; 7361 } 7362 7363 static int 7364 qlnx_grc_dumpsize(qlnx_host_t *ha, uint32_t *num_dwords, int hwfn_index) 7365 { 7366 int rval = -1; 7367 struct ecore_hwfn *p_hwfn; 7368 struct ecore_ptt *p_ptt; 7369 7370 ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver()); 7371 7372 p_hwfn = &ha->cdev.hwfns[hwfn_index]; 7373 p_ptt = ecore_ptt_acquire(p_hwfn); 7374 7375 if (!p_ptt) { 7376 QL_DPRINT1(ha, "ecore_ptt_acquire failed\n"); 7377 return (rval); 7378 } 7379 7380 rval = ecore_dbg_grc_get_dump_buf_size(p_hwfn, p_ptt, num_dwords); 7381 7382 if (rval == DBG_STATUS_OK) 7383 rval = 0; 7384 else { 7385 QL_DPRINT1(ha, "ecore_dbg_grc_get_dump_buf_size failed" 7386 "[0x%x]\n", rval); 7387 } 7388 7389 ecore_ptt_release(p_hwfn, p_ptt); 7390 7391 return (rval); 7392 } 7393 7394 static int 7395 qlnx_idle_chk_size(qlnx_host_t *ha, uint32_t *num_dwords, int hwfn_index) 7396 { 7397 int rval = -1; 7398 struct ecore_hwfn *p_hwfn; 7399 struct ecore_ptt *p_ptt; 7400 7401 ecore_dbg_set_app_ver(ecore_dbg_get_fw_func_ver()); 7402 7403 p_hwfn = &ha->cdev.hwfns[hwfn_index]; 7404 p_ptt = ecore_ptt_acquire(p_hwfn); 7405 7406 if (!p_ptt) { 7407 QL_DPRINT1(ha, "ecore_ptt_acquire failed\n"); 7408 return (rval); 7409 } 7410 7411 rval = ecore_dbg_idle_chk_get_dump_buf_size(p_hwfn, p_ptt, num_dwords); 7412 7413 if (rval == DBG_STATUS_OK) 7414 rval = 0; 7415 else { 7416 QL_DPRINT1(ha, "ecore_dbg_idle_chk_get_dump_buf_size failed" 7417 " [0x%x]\n", rval); 7418 } 7419 7420 ecore_ptt_release(p_hwfn, p_ptt); 7421 7422 return (rval); 7423 } 7424 7425 static void 7426 qlnx_sample_storm_stats(qlnx_host_t *ha) 7427 { 7428 int i, index; 7429 struct ecore_dev *cdev; 7430 qlnx_storm_stats_t *s_stats; 7431 uint32_t reg; 7432 struct ecore_ptt *p_ptt; 7433 struct ecore_hwfn *hwfn; 7434 7435 if (ha->storm_stats_index >= QLNX_STORM_STATS_SAMPLES_PER_HWFN) { 7436 ha->storm_stats_gather = 0; 7437 return; 7438 } 7439 7440 cdev = &ha->cdev; 7441 7442 for_each_hwfn(cdev, i) { 7443 hwfn = &cdev->hwfns[i]; 7444 7445 p_ptt = ecore_ptt_acquire(hwfn); 7446 if (!p_ptt) 7447 return; 7448 7449 index = ha->storm_stats_index + 7450 (i * QLNX_STORM_STATS_SAMPLES_PER_HWFN); 7451 7452 s_stats = &ha->storm_stats[index]; 7453 7454 /* XSTORM */ 7455 reg = XSEM_REG_FAST_MEMORY + 7456 SEM_FAST_REG_STORM_ACTIVE_CYCLES_BB_K2; 7457 s_stats->xstorm_active_cycles = ecore_rd(hwfn, p_ptt, reg); 7458 7459 reg = XSEM_REG_FAST_MEMORY + 7460 SEM_FAST_REG_STORM_STALL_CYCLES_BB_K2; 7461 s_stats->xstorm_stall_cycles = ecore_rd(hwfn, p_ptt, reg); 7462 7463 reg = XSEM_REG_FAST_MEMORY + 7464 SEM_FAST_REG_IDLE_SLEEPING_CYCLES_BB_K2; 7465 s_stats->xstorm_sleeping_cycles = ecore_rd(hwfn, p_ptt, reg); 7466 7467 reg = XSEM_REG_FAST_MEMORY + 7468 SEM_FAST_REG_IDLE_INACTIVE_CYCLES_BB_K2; 7469 s_stats->xstorm_inactive_cycles = ecore_rd(hwfn, p_ptt, reg); 7470 7471 /* YSTORM */ 7472 reg = YSEM_REG_FAST_MEMORY + 7473 SEM_FAST_REG_STORM_ACTIVE_CYCLES_BB_K2; 7474 s_stats->ystorm_active_cycles = ecore_rd(hwfn, p_ptt, reg); 7475 7476 reg = YSEM_REG_FAST_MEMORY + 7477 SEM_FAST_REG_STORM_STALL_CYCLES_BB_K2; 7478 s_stats->ystorm_stall_cycles = ecore_rd(hwfn, p_ptt, reg); 7479 7480 reg = YSEM_REG_FAST_MEMORY + 7481 SEM_FAST_REG_IDLE_SLEEPING_CYCLES_BB_K2; 7482 s_stats->ystorm_sleeping_cycles = ecore_rd(hwfn, p_ptt, reg); 7483 7484 reg = YSEM_REG_FAST_MEMORY + 7485 SEM_FAST_REG_IDLE_INACTIVE_CYCLES_BB_K2; 7486 s_stats->ystorm_inactive_cycles = ecore_rd(hwfn, p_ptt, reg); 7487 7488 /* PSTORM */ 7489 reg = PSEM_REG_FAST_MEMORY + 7490 SEM_FAST_REG_STORM_ACTIVE_CYCLES_BB_K2; 7491 s_stats->pstorm_active_cycles = ecore_rd(hwfn, p_ptt, reg); 7492 7493 reg = PSEM_REG_FAST_MEMORY + 7494 SEM_FAST_REG_STORM_STALL_CYCLES_BB_K2; 7495 s_stats->pstorm_stall_cycles = ecore_rd(hwfn, p_ptt, reg); 7496 7497 reg = PSEM_REG_FAST_MEMORY + 7498 SEM_FAST_REG_IDLE_SLEEPING_CYCLES_BB_K2; 7499 s_stats->pstorm_sleeping_cycles = ecore_rd(hwfn, p_ptt, reg); 7500 7501 reg = PSEM_REG_FAST_MEMORY + 7502 SEM_FAST_REG_IDLE_INACTIVE_CYCLES_BB_K2; 7503 s_stats->pstorm_inactive_cycles = ecore_rd(hwfn, p_ptt, reg); 7504 7505 /* TSTORM */ 7506 reg = TSEM_REG_FAST_MEMORY + 7507 SEM_FAST_REG_STORM_ACTIVE_CYCLES_BB_K2; 7508 s_stats->tstorm_active_cycles = ecore_rd(hwfn, p_ptt, reg); 7509 7510 reg = TSEM_REG_FAST_MEMORY + 7511 SEM_FAST_REG_STORM_STALL_CYCLES_BB_K2; 7512 s_stats->tstorm_stall_cycles = ecore_rd(hwfn, p_ptt, reg); 7513 7514 reg = TSEM_REG_FAST_MEMORY + 7515 SEM_FAST_REG_IDLE_SLEEPING_CYCLES_BB_K2; 7516 s_stats->tstorm_sleeping_cycles = ecore_rd(hwfn, p_ptt, reg); 7517 7518 reg = TSEM_REG_FAST_MEMORY + 7519 SEM_FAST_REG_IDLE_INACTIVE_CYCLES_BB_K2; 7520 s_stats->tstorm_inactive_cycles = ecore_rd(hwfn, p_ptt, reg); 7521 7522 /* MSTORM */ 7523 reg = MSEM_REG_FAST_MEMORY + 7524 SEM_FAST_REG_STORM_ACTIVE_CYCLES_BB_K2; 7525 s_stats->mstorm_active_cycles = ecore_rd(hwfn, p_ptt, reg); 7526 7527 reg = MSEM_REG_FAST_MEMORY + 7528 SEM_FAST_REG_STORM_STALL_CYCLES_BB_K2; 7529 s_stats->mstorm_stall_cycles = ecore_rd(hwfn, p_ptt, reg); 7530 7531 reg = MSEM_REG_FAST_MEMORY + 7532 SEM_FAST_REG_IDLE_SLEEPING_CYCLES_BB_K2; 7533 s_stats->mstorm_sleeping_cycles = ecore_rd(hwfn, p_ptt, reg); 7534 7535 reg = MSEM_REG_FAST_MEMORY + 7536 SEM_FAST_REG_IDLE_INACTIVE_CYCLES_BB_K2; 7537 s_stats->mstorm_inactive_cycles = ecore_rd(hwfn, p_ptt, reg); 7538 7539 /* USTORM */ 7540 reg = USEM_REG_FAST_MEMORY + 7541 SEM_FAST_REG_STORM_ACTIVE_CYCLES_BB_K2; 7542 s_stats->ustorm_active_cycles = ecore_rd(hwfn, p_ptt, reg); 7543 7544 reg = USEM_REG_FAST_MEMORY + 7545 SEM_FAST_REG_STORM_STALL_CYCLES_BB_K2; 7546 s_stats->ustorm_stall_cycles = ecore_rd(hwfn, p_ptt, reg); 7547 7548 reg = USEM_REG_FAST_MEMORY + 7549 SEM_FAST_REG_IDLE_SLEEPING_CYCLES_BB_K2; 7550 s_stats->ustorm_sleeping_cycles = ecore_rd(hwfn, p_ptt, reg); 7551 7552 reg = USEM_REG_FAST_MEMORY + 7553 SEM_FAST_REG_IDLE_INACTIVE_CYCLES_BB_K2; 7554 s_stats->ustorm_inactive_cycles = ecore_rd(hwfn, p_ptt, reg); 7555 7556 ecore_ptt_release(hwfn, p_ptt); 7557 } 7558 7559 ha->storm_stats_index++; 7560 7561 return; 7562 } 7563 7564 /* 7565 * Name: qlnx_dump_buf8 7566 * Function: dumps a buffer as bytes 7567 */ 7568 static void 7569 qlnx_dump_buf8(qlnx_host_t *ha, const char *msg, void *dbuf, uint32_t len) 7570 { 7571 device_t dev; 7572 uint32_t i = 0; 7573 uint8_t *buf; 7574 7575 dev = ha->pci_dev; 7576 buf = dbuf; 7577 7578 device_printf(dev, "%s: %s 0x%x dump start\n", __func__, msg, len); 7579 7580 while (len >= 16) { 7581 device_printf(dev,"0x%08x:" 7582 " %02x %02x %02x %02x %02x %02x %02x %02x" 7583 " %02x %02x %02x %02x %02x %02x %02x %02x\n", i, 7584 buf[0], buf[1], buf[2], buf[3], 7585 buf[4], buf[5], buf[6], buf[7], 7586 buf[8], buf[9], buf[10], buf[11], 7587 buf[12], buf[13], buf[14], buf[15]); 7588 i += 16; 7589 len -= 16; 7590 buf += 16; 7591 } 7592 switch (len) { 7593 case 1: 7594 device_printf(dev,"0x%08x: %02x\n", i, buf[0]); 7595 break; 7596 case 2: 7597 device_printf(dev,"0x%08x: %02x %02x\n", i, buf[0], buf[1]); 7598 break; 7599 case 3: 7600 device_printf(dev,"0x%08x: %02x %02x %02x\n", 7601 i, buf[0], buf[1], buf[2]); 7602 break; 7603 case 4: 7604 device_printf(dev,"0x%08x: %02x %02x %02x %02x\n", i, 7605 buf[0], buf[1], buf[2], buf[3]); 7606 break; 7607 case 5: 7608 device_printf(dev,"0x%08x:" 7609 " %02x %02x %02x %02x %02x\n", i, 7610 buf[0], buf[1], buf[2], buf[3], buf[4]); 7611 break; 7612 case 6: 7613 device_printf(dev,"0x%08x:" 7614 " %02x %02x %02x %02x %02x %02x\n", i, 7615 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 7616 break; 7617 case 7: 7618 device_printf(dev,"0x%08x:" 7619 " %02x %02x %02x %02x %02x %02x %02x\n", i, 7620 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); 7621 break; 7622 case 8: 7623 device_printf(dev,"0x%08x:" 7624 " %02x %02x %02x %02x %02x %02x %02x %02x\n", i, 7625 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7626 buf[7]); 7627 break; 7628 case 9: 7629 device_printf(dev,"0x%08x:" 7630 " %02x %02x %02x %02x %02x %02x %02x %02x" 7631 " %02x\n", i, 7632 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7633 buf[7], buf[8]); 7634 break; 7635 case 10: 7636 device_printf(dev,"0x%08x:" 7637 " %02x %02x %02x %02x %02x %02x %02x %02x" 7638 " %02x %02x\n", i, 7639 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7640 buf[7], buf[8], buf[9]); 7641 break; 7642 case 11: 7643 device_printf(dev,"0x%08x:" 7644 " %02x %02x %02x %02x %02x %02x %02x %02x" 7645 " %02x %02x %02x\n", i, 7646 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7647 buf[7], buf[8], buf[9], buf[10]); 7648 break; 7649 case 12: 7650 device_printf(dev,"0x%08x:" 7651 " %02x %02x %02x %02x %02x %02x %02x %02x" 7652 " %02x %02x %02x %02x\n", i, 7653 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7654 buf[7], buf[8], buf[9], buf[10], buf[11]); 7655 break; 7656 case 13: 7657 device_printf(dev,"0x%08x:" 7658 " %02x %02x %02x %02x %02x %02x %02x %02x" 7659 " %02x %02x %02x %02x %02x\n", i, 7660 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7661 buf[7], buf[8], buf[9], buf[10], buf[11], buf[12]); 7662 break; 7663 case 14: 7664 device_printf(dev,"0x%08x:" 7665 " %02x %02x %02x %02x %02x %02x %02x %02x" 7666 " %02x %02x %02x %02x %02x %02x\n", i, 7667 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7668 buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], 7669 buf[13]); 7670 break; 7671 case 15: 7672 device_printf(dev,"0x%08x:" 7673 " %02x %02x %02x %02x %02x %02x %02x %02x" 7674 " %02x %02x %02x %02x %02x %02x %02x\n", i, 7675 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 7676 buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], 7677 buf[13], buf[14]); 7678 break; 7679 default: 7680 break; 7681 } 7682 7683 device_printf(dev, "%s: %s dump end\n", __func__, msg); 7684 7685 return; 7686 } 7687 7688 #ifdef CONFIG_ECORE_SRIOV 7689 7690 static void 7691 __qlnx_osal_iov_vf_cleanup(struct ecore_hwfn *p_hwfn, uint8_t rel_vf_id) 7692 { 7693 struct ecore_public_vf_info *vf_info; 7694 7695 vf_info = ecore_iov_get_public_vf_info(p_hwfn, rel_vf_id, false); 7696 7697 if (!vf_info) 7698 return; 7699 7700 /* Clear the VF mac */ 7701 memset(vf_info->forced_mac, 0, ETH_ALEN); 7702 7703 vf_info->forced_vlan = 0; 7704 7705 return; 7706 } 7707 7708 void 7709 qlnx_osal_iov_vf_cleanup(void *p_hwfn, uint8_t relative_vf_id) 7710 { 7711 __qlnx_osal_iov_vf_cleanup(p_hwfn, relative_vf_id); 7712 return; 7713 } 7714 7715 static int 7716 __qlnx_iov_chk_ucast(struct ecore_hwfn *p_hwfn, int vfid, 7717 struct ecore_filter_ucast *params) 7718 { 7719 struct ecore_public_vf_info *vf; 7720 7721 if (!ecore_iov_vf_has_vport_instance(p_hwfn, vfid)) { 7722 QL_DPRINT1(((qlnx_host_t *)p_hwfn->p_dev), 7723 "VF[%d] vport not initialized\n", vfid); 7724 return ECORE_INVAL; 7725 } 7726 7727 vf = ecore_iov_get_public_vf_info(p_hwfn, vfid, true); 7728 if (!vf) 7729 return -EINVAL; 7730 7731 /* No real decision to make; Store the configured MAC */ 7732 if (params->type == ECORE_FILTER_MAC || 7733 params->type == ECORE_FILTER_MAC_VLAN) 7734 memcpy(params->mac, vf->forced_mac, ETH_ALEN); 7735 7736 return 0; 7737 } 7738 7739 int 7740 qlnx_iov_chk_ucast(void *p_hwfn, int vfid, void *params) 7741 { 7742 return (__qlnx_iov_chk_ucast(p_hwfn, vfid, params)); 7743 } 7744 7745 static int 7746 __qlnx_iov_update_vport(struct ecore_hwfn *hwfn, uint8_t vfid, 7747 struct ecore_sp_vport_update_params *params, uint16_t * tlvs) 7748 { 7749 if (!ecore_iov_vf_has_vport_instance(hwfn, vfid)) { 7750 QL_DPRINT1(((qlnx_host_t *)hwfn->p_dev), 7751 "VF[%d] vport not initialized\n", vfid); 7752 return ECORE_INVAL; 7753 } 7754 7755 /* Untrusted VFs can't even be trusted to know that fact. 7756 * Simply indicate everything is configured fine, and trace 7757 * configuration 'behind their back'. 7758 */ 7759 if (!(*tlvs & BIT(ECORE_IOV_VP_UPDATE_ACCEPT_PARAM))) 7760 return 0; 7761 7762 return 0; 7763 7764 } 7765 int 7766 qlnx_iov_update_vport(void *hwfn, uint8_t vfid, void *params, uint16_t *tlvs) 7767 { 7768 return(__qlnx_iov_update_vport(hwfn, vfid, params, tlvs)); 7769 } 7770 7771 static int 7772 qlnx_find_hwfn_index(struct ecore_hwfn *p_hwfn) 7773 { 7774 int i; 7775 struct ecore_dev *cdev; 7776 7777 cdev = p_hwfn->p_dev; 7778 7779 for (i = 0; i < cdev->num_hwfns; i++) { 7780 if (&cdev->hwfns[i] == p_hwfn) 7781 break; 7782 } 7783 7784 if (i >= cdev->num_hwfns) 7785 return (-1); 7786 7787 return (i); 7788 } 7789 7790 static int 7791 __qlnx_pf_vf_msg(struct ecore_hwfn *p_hwfn, uint16_t rel_vf_id) 7792 { 7793 qlnx_host_t *ha = (qlnx_host_t *)p_hwfn->p_dev; 7794 int i; 7795 7796 QL_DPRINT2(ha, "ha = %p cdev = %p p_hwfn = %p rel_vf_id = %d\n", 7797 ha, p_hwfn->p_dev, p_hwfn, rel_vf_id); 7798 7799 if ((i = qlnx_find_hwfn_index(p_hwfn)) == -1) 7800 return (-1); 7801 7802 if (ha->sriov_task[i].pf_taskqueue != NULL) { 7803 atomic_testandset_32(&ha->sriov_task[i].flags, 7804 QLNX_SRIOV_TASK_FLAGS_VF_PF_MSG); 7805 7806 taskqueue_enqueue(ha->sriov_task[i].pf_taskqueue, 7807 &ha->sriov_task[i].pf_task); 7808 } 7809 7810 return (ECORE_SUCCESS); 7811 } 7812 7813 int 7814 qlnx_pf_vf_msg(void *p_hwfn, uint16_t relative_vf_id) 7815 { 7816 return (__qlnx_pf_vf_msg(p_hwfn, relative_vf_id)); 7817 } 7818 7819 static void 7820 __qlnx_vf_flr_update(struct ecore_hwfn *p_hwfn) 7821 { 7822 qlnx_host_t *ha = (qlnx_host_t *)p_hwfn->p_dev; 7823 int i; 7824 7825 if (!ha->sriov_initialized) 7826 return; 7827 7828 QL_DPRINT2(ha, "ha = %p cdev = %p p_hwfn = %p \n", 7829 ha, p_hwfn->p_dev, p_hwfn); 7830 7831 if ((i = qlnx_find_hwfn_index(p_hwfn)) == -1) 7832 return; 7833 7834 if (ha->sriov_task[i].pf_taskqueue != NULL) { 7835 atomic_testandset_32(&ha->sriov_task[i].flags, 7836 QLNX_SRIOV_TASK_FLAGS_VF_FLR_UPDATE); 7837 7838 taskqueue_enqueue(ha->sriov_task[i].pf_taskqueue, 7839 &ha->sriov_task[i].pf_task); 7840 } 7841 7842 return; 7843 } 7844 7845 void 7846 qlnx_vf_flr_update(void *p_hwfn) 7847 { 7848 __qlnx_vf_flr_update(p_hwfn); 7849 7850 return; 7851 } 7852 7853 #ifndef QLNX_VF 7854 7855 static void 7856 qlnx_vf_bulleting_update(struct ecore_hwfn *p_hwfn) 7857 { 7858 qlnx_host_t *ha = (qlnx_host_t *)p_hwfn->p_dev; 7859 int i; 7860 7861 QL_DPRINT2(ha, "ha = %p cdev = %p p_hwfn = %p \n", 7862 ha, p_hwfn->p_dev, p_hwfn); 7863 7864 if ((i = qlnx_find_hwfn_index(p_hwfn)) == -1) 7865 return; 7866 7867 QL_DPRINT2(ha, "ha = %p cdev = %p p_hwfn = %p i = %d\n", 7868 ha, p_hwfn->p_dev, p_hwfn, i); 7869 7870 if (ha->sriov_task[i].pf_taskqueue != NULL) { 7871 atomic_testandset_32(&ha->sriov_task[i].flags, 7872 QLNX_SRIOV_TASK_FLAGS_BULLETIN_UPDATE); 7873 7874 taskqueue_enqueue(ha->sriov_task[i].pf_taskqueue, 7875 &ha->sriov_task[i].pf_task); 7876 } 7877 } 7878 7879 static void 7880 qlnx_initialize_sriov(qlnx_host_t *ha) 7881 { 7882 device_t dev; 7883 nvlist_t *pf_schema, *vf_schema; 7884 int iov_error; 7885 7886 dev = ha->pci_dev; 7887 7888 pf_schema = pci_iov_schema_alloc_node(); 7889 vf_schema = pci_iov_schema_alloc_node(); 7890 7891 pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL); 7892 pci_iov_schema_add_bool(vf_schema, "allow-set-mac", 7893 IOV_SCHEMA_HASDEFAULT, FALSE); 7894 pci_iov_schema_add_bool(vf_schema, "allow-promisc", 7895 IOV_SCHEMA_HASDEFAULT, FALSE); 7896 pci_iov_schema_add_uint16(vf_schema, "num-queues", 7897 IOV_SCHEMA_HASDEFAULT, 1); 7898 7899 iov_error = pci_iov_attach(dev, pf_schema, vf_schema); 7900 7901 if (iov_error != 0) { 7902 ha->sriov_initialized = 0; 7903 } else { 7904 device_printf(dev, "SRIOV initialized\n"); 7905 ha->sriov_initialized = 1; 7906 } 7907 7908 return; 7909 } 7910 7911 static void 7912 qlnx_sriov_disable(qlnx_host_t *ha) 7913 { 7914 struct ecore_dev *cdev; 7915 int i, j; 7916 7917 cdev = &ha->cdev; 7918 7919 ecore_iov_set_vfs_to_disable(cdev, true); 7920 7921 for_each_hwfn(cdev, i) { 7922 struct ecore_hwfn *hwfn = &cdev->hwfns[i]; 7923 struct ecore_ptt *ptt = ecore_ptt_acquire(hwfn); 7924 7925 if (!ptt) { 7926 QL_DPRINT1(ha, "Failed to acquire ptt\n"); 7927 return; 7928 } 7929 /* Clean WFQ db and configure equal weight for all vports */ 7930 ecore_clean_wfq_db(hwfn, ptt); 7931 7932 ecore_for_each_vf(hwfn, j) { 7933 int k = 0; 7934 7935 if (!ecore_iov_is_valid_vfid(hwfn, j, true, false)) 7936 continue; 7937 7938 if (ecore_iov_is_vf_started(hwfn, j)) { 7939 /* Wait until VF is disabled before releasing */ 7940 7941 for (k = 0; k < 100; k++) { 7942 if (!ecore_iov_is_vf_stopped(hwfn, j)) { 7943 qlnx_mdelay(__func__, 10); 7944 } else 7945 break; 7946 } 7947 } 7948 7949 if (k < 100) 7950 ecore_iov_release_hw_for_vf(&cdev->hwfns[i], 7951 ptt, j); 7952 else { 7953 QL_DPRINT1(ha, 7954 "Timeout waiting for VF's FLR to end\n"); 7955 } 7956 } 7957 ecore_ptt_release(hwfn, ptt); 7958 } 7959 7960 ecore_iov_set_vfs_to_disable(cdev, false); 7961 7962 return; 7963 } 7964 7965 static void 7966 qlnx_sriov_enable_qid_config(struct ecore_hwfn *hwfn, u16 vfid, 7967 struct ecore_iov_vf_init_params *params) 7968 { 7969 u16 base, i; 7970 7971 /* Since we have an equal resource distribution per-VF, and we assume 7972 * PF has acquired the ECORE_PF_L2_QUE first queues, we start setting 7973 * sequentially from there. 7974 */ 7975 base = FEAT_NUM(hwfn, ECORE_PF_L2_QUE) + vfid * params->num_queues; 7976 7977 params->rel_vf_id = vfid; 7978 7979 for (i = 0; i < params->num_queues; i++) { 7980 params->req_rx_queue[i] = base + i; 7981 params->req_tx_queue[i] = base + i; 7982 } 7983 7984 /* PF uses indices 0 for itself; Set vport/RSS afterwards */ 7985 params->vport_id = vfid + 1; 7986 params->rss_eng_id = vfid + 1; 7987 7988 return; 7989 } 7990 7991 static int 7992 qlnx_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *nvlist_params) 7993 { 7994 qlnx_host_t *ha; 7995 struct ecore_dev *cdev; 7996 struct ecore_iov_vf_init_params params; 7997 int ret, j, i; 7998 uint32_t max_vfs; 7999 8000 if ((ha = device_get_softc(dev)) == NULL) { 8001 device_printf(dev, "%s: cannot get softc\n", __func__); 8002 return (-1); 8003 } 8004 8005 if (qlnx_create_pf_taskqueues(ha) != 0) 8006 goto qlnx_iov_init_err0; 8007 8008 cdev = &ha->cdev; 8009 8010 max_vfs = RESC_NUM(&cdev->hwfns[0], ECORE_VPORT); 8011 8012 QL_DPRINT2(ha," dev = %p enter num_vfs = %d max_vfs = %d\n", 8013 dev, num_vfs, max_vfs); 8014 8015 if (num_vfs >= max_vfs) { 8016 QL_DPRINT1(ha, "Can start at most %d VFs\n", 8017 (RESC_NUM(&cdev->hwfns[0], ECORE_VPORT) - 1)); 8018 goto qlnx_iov_init_err0; 8019 } 8020 8021 ha->vf_attr = malloc(((sizeof (qlnx_vf_attr_t) * num_vfs)), M_QLNXBUF, 8022 M_NOWAIT); 8023 8024 if (ha->vf_attr == NULL) 8025 goto qlnx_iov_init_err0; 8026 8027 memset(¶ms, 0, sizeof(params)); 8028 8029 /* Initialize HW for VF access */ 8030 for_each_hwfn(cdev, j) { 8031 struct ecore_hwfn *hwfn = &cdev->hwfns[j]; 8032 struct ecore_ptt *ptt = ecore_ptt_acquire(hwfn); 8033 8034 /* Make sure not to use more than 16 queues per VF */ 8035 params.num_queues = min_t(int, 8036 (FEAT_NUM(hwfn, ECORE_VF_L2_QUE) / num_vfs), 8037 16); 8038 8039 if (!ptt) { 8040 QL_DPRINT1(ha, "Failed to acquire ptt\n"); 8041 goto qlnx_iov_init_err1; 8042 } 8043 8044 for (i = 0; i < num_vfs; i++) { 8045 if (!ecore_iov_is_valid_vfid(hwfn, i, false, true)) 8046 continue; 8047 8048 qlnx_sriov_enable_qid_config(hwfn, i, ¶ms); 8049 8050 ret = ecore_iov_init_hw_for_vf(hwfn, ptt, ¶ms); 8051 8052 if (ret) { 8053 QL_DPRINT1(ha, "Failed to enable VF[%d]\n", i); 8054 ecore_ptt_release(hwfn, ptt); 8055 goto qlnx_iov_init_err1; 8056 } 8057 } 8058 8059 ecore_ptt_release(hwfn, ptt); 8060 } 8061 8062 ha->num_vfs = num_vfs; 8063 qlnx_inform_vf_link_state(&cdev->hwfns[0], ha); 8064 8065 QL_DPRINT2(ha," dev = %p exit num_vfs = %d\n", dev, num_vfs); 8066 8067 return (0); 8068 8069 qlnx_iov_init_err1: 8070 qlnx_sriov_disable(ha); 8071 8072 qlnx_iov_init_err0: 8073 qlnx_destroy_pf_taskqueues(ha); 8074 ha->num_vfs = 0; 8075 8076 return (-1); 8077 } 8078 8079 static void 8080 qlnx_iov_uninit(device_t dev) 8081 { 8082 qlnx_host_t *ha; 8083 8084 if ((ha = device_get_softc(dev)) == NULL) { 8085 device_printf(dev, "%s: cannot get softc\n", __func__); 8086 return; 8087 } 8088 8089 QL_DPRINT2(ha," dev = %p enter\n", dev); 8090 8091 qlnx_sriov_disable(ha); 8092 qlnx_destroy_pf_taskqueues(ha); 8093 8094 free(ha->vf_attr, M_QLNXBUF); 8095 ha->vf_attr = NULL; 8096 8097 ha->num_vfs = 0; 8098 8099 QL_DPRINT2(ha," dev = %p exit\n", dev); 8100 return; 8101 } 8102 8103 static int 8104 qlnx_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params) 8105 { 8106 qlnx_host_t *ha; 8107 qlnx_vf_attr_t *vf_attr; 8108 unsigned const char *mac; 8109 size_t size; 8110 struct ecore_hwfn *p_hwfn; 8111 8112 if ((ha = device_get_softc(dev)) == NULL) { 8113 device_printf(dev, "%s: cannot get softc\n", __func__); 8114 return (-1); 8115 } 8116 8117 QL_DPRINT2(ha," dev = %p enter vfnum = %d\n", dev, vfnum); 8118 8119 if (vfnum > (ha->num_vfs - 1)) { 8120 QL_DPRINT1(ha, " VF[%d] is greater than max allowed [%d]\n", 8121 vfnum, (ha->num_vfs - 1)); 8122 } 8123 8124 vf_attr = &ha->vf_attr[vfnum]; 8125 8126 if (nvlist_exists_binary(params, "mac-addr")) { 8127 mac = nvlist_get_binary(params, "mac-addr", &size); 8128 bcopy(mac, vf_attr->mac_addr, ETHER_ADDR_LEN); 8129 device_printf(dev, 8130 "%s: mac_addr = %02x:%02x:%02x:%02x:%02x:%02x\n", 8131 __func__, vf_attr->mac_addr[0], 8132 vf_attr->mac_addr[1], vf_attr->mac_addr[2], 8133 vf_attr->mac_addr[3], vf_attr->mac_addr[4], 8134 vf_attr->mac_addr[5]); 8135 p_hwfn = &ha->cdev.hwfns[0]; 8136 ecore_iov_bulletin_set_mac(p_hwfn, vf_attr->mac_addr, 8137 vfnum); 8138 } 8139 8140 QL_DPRINT2(ha," dev = %p exit vfnum = %d\n", dev, vfnum); 8141 return (0); 8142 } 8143 8144 static void 8145 qlnx_handle_vf_msg(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn) 8146 { 8147 uint64_t events[ECORE_VF_ARRAY_LENGTH]; 8148 struct ecore_ptt *ptt; 8149 int i; 8150 8151 ptt = ecore_ptt_acquire(p_hwfn); 8152 if (!ptt) { 8153 QL_DPRINT1(ha, "Can't acquire PTT; re-scheduling\n"); 8154 __qlnx_pf_vf_msg(p_hwfn, 0); 8155 return; 8156 } 8157 8158 ecore_iov_pf_get_pending_events(p_hwfn, events); 8159 8160 QL_DPRINT2(ha, "Event mask of VF events:" 8161 "0x%" PRIu64 "0x%" PRIu64 " 0x%" PRIu64 "\n", 8162 events[0], events[1], events[2]); 8163 8164 ecore_for_each_vf(p_hwfn, i) { 8165 /* Skip VFs with no pending messages */ 8166 if (!(events[i / 64] & (1ULL << (i % 64)))) 8167 continue; 8168 8169 QL_DPRINT2(ha, 8170 "Handling VF message from VF 0x%02x [Abs 0x%02x]\n", 8171 i, p_hwfn->p_dev->p_iov_info->first_vf_in_pf + i); 8172 8173 /* Copy VF's message to PF's request buffer for that VF */ 8174 if (ecore_iov_copy_vf_msg(p_hwfn, ptt, i)) 8175 continue; 8176 8177 ecore_iov_process_mbx_req(p_hwfn, ptt, i); 8178 } 8179 8180 ecore_ptt_release(p_hwfn, ptt); 8181 8182 return; 8183 } 8184 8185 static void 8186 qlnx_handle_vf_flr_update(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn) 8187 { 8188 struct ecore_ptt *ptt; 8189 int ret; 8190 8191 ptt = ecore_ptt_acquire(p_hwfn); 8192 8193 if (!ptt) { 8194 QL_DPRINT1(ha, "Can't acquire PTT; re-scheduling\n"); 8195 __qlnx_vf_flr_update(p_hwfn); 8196 return; 8197 } 8198 8199 ret = ecore_iov_vf_flr_cleanup(p_hwfn, ptt); 8200 8201 if (ret) { 8202 QL_DPRINT1(ha, "ecore_iov_vf_flr_cleanup failed; re-scheduling\n"); 8203 } 8204 8205 ecore_ptt_release(p_hwfn, ptt); 8206 8207 return; 8208 } 8209 8210 static void 8211 qlnx_handle_bulletin_update(qlnx_host_t *ha, struct ecore_hwfn *p_hwfn) 8212 { 8213 struct ecore_ptt *ptt; 8214 int i; 8215 8216 ptt = ecore_ptt_acquire(p_hwfn); 8217 8218 if (!ptt) { 8219 QL_DPRINT1(ha, "Can't acquire PTT; re-scheduling\n"); 8220 qlnx_vf_bulleting_update(p_hwfn); 8221 return; 8222 } 8223 8224 ecore_for_each_vf(p_hwfn, i) { 8225 QL_DPRINT1(ha, "ecore_iov_post_vf_bulletin[%p, %d]\n", 8226 p_hwfn, i); 8227 ecore_iov_post_vf_bulletin(p_hwfn, i, ptt); 8228 } 8229 8230 ecore_ptt_release(p_hwfn, ptt); 8231 8232 return; 8233 } 8234 8235 static void 8236 qlnx_pf_taskqueue(void *context, int pending) 8237 { 8238 struct ecore_hwfn *p_hwfn; 8239 qlnx_host_t *ha; 8240 int i; 8241 8242 p_hwfn = context; 8243 8244 if (p_hwfn == NULL) 8245 return; 8246 8247 ha = (qlnx_host_t *)(p_hwfn->p_dev); 8248 8249 if ((i = qlnx_find_hwfn_index(p_hwfn)) == -1) 8250 return; 8251 8252 if (atomic_testandclear_32(&ha->sriov_task[i].flags, 8253 QLNX_SRIOV_TASK_FLAGS_VF_PF_MSG)) 8254 qlnx_handle_vf_msg(ha, p_hwfn); 8255 8256 if (atomic_testandclear_32(&ha->sriov_task[i].flags, 8257 QLNX_SRIOV_TASK_FLAGS_VF_FLR_UPDATE)) 8258 qlnx_handle_vf_flr_update(ha, p_hwfn); 8259 8260 if (atomic_testandclear_32(&ha->sriov_task[i].flags, 8261 QLNX_SRIOV_TASK_FLAGS_BULLETIN_UPDATE)) 8262 qlnx_handle_bulletin_update(ha, p_hwfn); 8263 8264 return; 8265 } 8266 8267 static int 8268 qlnx_create_pf_taskqueues(qlnx_host_t *ha) 8269 { 8270 int i; 8271 uint8_t tq_name[32]; 8272 8273 for (i = 0; i < ha->cdev.num_hwfns; i++) { 8274 struct ecore_hwfn *p_hwfn = &ha->cdev.hwfns[i]; 8275 8276 bzero(tq_name, sizeof (tq_name)); 8277 snprintf(tq_name, sizeof (tq_name), "ql_pf_tq_%d", i); 8278 8279 TASK_INIT(&ha->sriov_task[i].pf_task, 0, qlnx_pf_taskqueue, p_hwfn); 8280 8281 ha->sriov_task[i].pf_taskqueue = taskqueue_create(tq_name, M_NOWAIT, 8282 taskqueue_thread_enqueue, 8283 &ha->sriov_task[i].pf_taskqueue); 8284 8285 if (ha->sriov_task[i].pf_taskqueue == NULL) 8286 return (-1); 8287 8288 taskqueue_start_threads(&ha->sriov_task[i].pf_taskqueue, 1, 8289 PI_NET, "%s", tq_name); 8290 8291 QL_DPRINT1(ha, "%p\n", ha->sriov_task[i].pf_taskqueue); 8292 } 8293 8294 return (0); 8295 } 8296 8297 static void 8298 qlnx_destroy_pf_taskqueues(qlnx_host_t *ha) 8299 { 8300 int i; 8301 8302 for (i = 0; i < ha->cdev.num_hwfns; i++) { 8303 if (ha->sriov_task[i].pf_taskqueue != NULL) { 8304 taskqueue_drain(ha->sriov_task[i].pf_taskqueue, 8305 &ha->sriov_task[i].pf_task); 8306 taskqueue_free(ha->sriov_task[i].pf_taskqueue); 8307 ha->sriov_task[i].pf_taskqueue = NULL; 8308 } 8309 } 8310 return; 8311 } 8312 8313 static void 8314 qlnx_inform_vf_link_state(struct ecore_hwfn *p_hwfn, qlnx_host_t *ha) 8315 { 8316 struct ecore_mcp_link_capabilities caps; 8317 struct ecore_mcp_link_params params; 8318 struct ecore_mcp_link_state link; 8319 int i; 8320 8321 if (!p_hwfn->pf_iov_info) 8322 return; 8323 8324 memset(¶ms, 0, sizeof(struct ecore_mcp_link_params)); 8325 memset(&link, 0, sizeof(struct ecore_mcp_link_state)); 8326 memset(&caps, 0, sizeof(struct ecore_mcp_link_capabilities)); 8327 8328 memcpy(&caps, ecore_mcp_get_link_capabilities(p_hwfn), sizeof(caps)); 8329 memcpy(&link, ecore_mcp_get_link_state(p_hwfn), sizeof(link)); 8330 memcpy(¶ms, ecore_mcp_get_link_params(p_hwfn), sizeof(params)); 8331 8332 QL_DPRINT2(ha, "called\n"); 8333 8334 /* Update bulletin of all future possible VFs with link configuration */ 8335 for (i = 0; i < p_hwfn->p_dev->p_iov_info->total_vfs; i++) { 8336 /* Modify link according to the VF's configured link state */ 8337 8338 link.link_up = false; 8339 8340 if (ha->link_up) { 8341 link.link_up = true; 8342 /* Set speed according to maximum supported by HW. 8343 * that is 40G for regular devices and 100G for CMT 8344 * mode devices. 8345 */ 8346 link.speed = (p_hwfn->p_dev->num_hwfns > 1) ? 8347 100000 : link.speed; 8348 } 8349 QL_DPRINT2(ha, "link [%d] = %d\n", i, link.link_up); 8350 ecore_iov_set_link(p_hwfn, i, ¶ms, &link, &caps); 8351 } 8352 8353 qlnx_vf_bulleting_update(p_hwfn); 8354 8355 return; 8356 } 8357 #endif /* #ifndef QLNX_VF */ 8358 #endif /* #ifdef CONFIG_ECORE_SRIOV */ 8359