1 /* 2 * aQuantia Corporation Network Driver 3 * Copyright (C) 2019 aQuantia Corporation. 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 10 * copyright notice, this list of conditions and the following 11 * disclaimer. 12 * 13 * (2) Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * (3)The name of the author may not be used to endorse or promote 19 * products derived from this software without specific prior 20 * written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 26 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 28 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 36 #include <sys/cdefs.h> 37 __FBSDID("$FreeBSD$"); 38 39 #include <sys/param.h> 40 #include <sys/malloc.h> 41 #include <sys/socket.h> 42 #include <sys/kernel.h> 43 #include <sys/bus.h> 44 #include <sys/module.h> 45 #include <sys/rman.h> 46 #include <sys/endian.h> 47 #include <sys/sockio.h> 48 #include <sys/priv.h> 49 #include <sys/sysctl.h> 50 #include <sys/sbuf.h> 51 #include <sys/bitstring.h> 52 53 #include <machine/bus.h> 54 #include <machine/resource.h> 55 56 #include <dev/pci/pcireg.h> 57 #include <dev/pci/pcivar.h> 58 59 #include <net/if.h> 60 #include <net/if_media.h> 61 #include <net/if_var.h> 62 #include <net/if_dl.h> 63 #include <net/ethernet.h> 64 #include <net/iflib.h> 65 #include <net/rss_config.h> 66 67 #include "opt_inet.h" 68 #include "opt_inet6.h" 69 #include "opt_rss.h" 70 71 #include "ifdi_if.h" 72 73 #include "aq_device.h" 74 #include "aq_fw.h" 75 #include "aq_hw.h" 76 #include "aq_hw_llh.h" 77 #include "aq_ring.h" 78 #include "aq_dbg.h" 79 80 81 #define AQ_XXX_UNIMPLEMENTED_FUNCTION do { \ 82 printf("atlantic: unimplemented function: %s@%s:%d\n", __func__, \ 83 __FILE__, __LINE__); \ 84 } while (0) 85 86 MALLOC_DEFINE(M_AQ, "aq", "Aquantia"); 87 88 char aq_driver_version[] = AQ_VER; 89 90 #define AQUANTIA_VENDOR_ID 0x1D6A 91 92 #define AQ_DEVICE_ID_0001 0x0001 93 #define AQ_DEVICE_ID_D100 0xD100 94 #define AQ_DEVICE_ID_D107 0xD107 95 #define AQ_DEVICE_ID_D108 0xD108 96 #define AQ_DEVICE_ID_D109 0xD109 97 98 #define AQ_DEVICE_ID_AQC100 0x00B1 99 #define AQ_DEVICE_ID_AQC107 0x07B1 100 #define AQ_DEVICE_ID_AQC108 0x08B1 101 #define AQ_DEVICE_ID_AQC109 0x09B1 102 #define AQ_DEVICE_ID_AQC111 0x11B1 103 #define AQ_DEVICE_ID_AQC112 0x12B1 104 105 #define AQ_DEVICE_ID_AQC100S 0x80B1 106 #define AQ_DEVICE_ID_AQC107S 0x87B1 107 #define AQ_DEVICE_ID_AQC108S 0x88B1 108 #define AQ_DEVICE_ID_AQC109S 0x89B1 109 #define AQ_DEVICE_ID_AQC111S 0x91B1 110 #define AQ_DEVICE_ID_AQC112S 0x92B1 111 112 static pci_vendor_info_t aq_vendor_info_array[] = { 113 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_0001, "Aquantia AQtion 10Gbit Network Adapter"), 114 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_D107, "Aquantia AQtion 10Gbit Network Adapter"), 115 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_D108, "Aquantia AQtion 5Gbit Network Adapter"), 116 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_D109, "Aquantia AQtion 2.5Gbit Network Adapter"), 117 118 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC107, "Aquantia AQtion 10Gbit Network Adapter"), 119 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC108, "Aquantia AQtion 5Gbit Network Adapter"), 120 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC109, "Aquantia AQtion 2.5Gbit Network Adapter"), 121 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC100, "Aquantia AQtion 10Gbit Network Adapter"), 122 123 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC107S, "Aquantia AQtion 10Gbit Network Adapter"), 124 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC108S, "Aquantia AQtion 5Gbit Network Adapter"), 125 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC109S, "Aquantia AQtion 2.5Gbit Network Adapter"), 126 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC100S, "Aquantia AQtion 10Gbit Network Adapter"), 127 128 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC111, "Aquantia AQtion 5Gbit Network Adapter"), 129 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC112, "Aquantia AQtion 2.5Gbit Network Adapter"), 130 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC111S, "Aquantia AQtion 5Gbit Network Adapter"), 131 PVID(AQUANTIA_VENDOR_ID, AQ_DEVICE_ID_AQC112S, "Aquantia AQtion 2.5Gbit Network Adapter"), 132 133 PVID_END 134 }; 135 136 137 /* Device setup, teardown, etc */ 138 static void *aq_register(device_t dev); 139 static int aq_if_attach_pre(if_ctx_t ctx); 140 static int aq_if_attach_post(if_ctx_t ctx); 141 static int aq_if_detach(if_ctx_t ctx); 142 static int aq_if_shutdown(if_ctx_t ctx); 143 static int aq_if_suspend(if_ctx_t ctx); 144 static int aq_if_resume(if_ctx_t ctx); 145 146 /* Soft queue setup and teardown */ 147 static int aq_if_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 148 uint64_t *paddrs, int ntxqs, int ntxqsets); 149 static int aq_if_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 150 uint64_t *paddrs, int nrxqs, int nrxqsets); 151 static void aq_if_queues_free(if_ctx_t ctx); 152 153 /* Device configuration */ 154 static void aq_if_init(if_ctx_t ctx); 155 static void aq_if_stop(if_ctx_t ctx); 156 static void aq_if_multi_set(if_ctx_t ctx); 157 static int aq_if_mtu_set(if_ctx_t ctx, uint32_t mtu); 158 static void aq_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr); 159 static int aq_if_media_change(if_ctx_t ctx); 160 static int aq_if_promisc_set(if_ctx_t ctx, int flags); 161 static uint64_t aq_if_get_counter(if_ctx_t ctx, ift_counter cnt); 162 static void aq_if_timer(if_ctx_t ctx, uint16_t qid); 163 static int aq_hw_capabilities(struct aq_dev *softc); 164 static void aq_add_stats_sysctls(struct aq_dev *softc); 165 166 /* Interrupt enable / disable */ 167 static void aq_if_enable_intr(if_ctx_t ctx); 168 static void aq_if_disable_intr(if_ctx_t ctx); 169 static int aq_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid); 170 static int aq_if_msix_intr_assign(if_ctx_t ctx, int msix); 171 172 /* VLAN support */ 173 static bool aq_is_vlan_promisc_required(struct aq_dev *softc); 174 static void aq_update_vlan_filters(struct aq_dev *softc); 175 static void aq_if_vlan_register(if_ctx_t ctx, uint16_t vtag); 176 static void aq_if_vlan_unregister(if_ctx_t ctx, uint16_t vtag); 177 178 /* Informational/diagnostic */ 179 static void aq_if_led_func(if_ctx_t ctx, int onoff); 180 181 static device_method_t aq_methods[] = { 182 DEVMETHOD(device_register, aq_register), 183 DEVMETHOD(device_probe, iflib_device_probe), 184 DEVMETHOD(device_attach, iflib_device_attach), 185 DEVMETHOD(device_detach, iflib_device_detach), 186 DEVMETHOD(device_shutdown, iflib_device_shutdown), 187 DEVMETHOD(device_suspend, iflib_device_suspend), 188 DEVMETHOD(device_resume, iflib_device_resume), 189 190 DEVMETHOD_END 191 }; 192 193 static driver_t aq_driver = { 194 "aq", aq_methods, sizeof(struct aq_dev), 195 }; 196 197 #if __FreeBSD_version >= 1400058 198 DRIVER_MODULE(atlantic, pci, aq_driver, 0, 0); 199 #else 200 static devclass_t aq_devclass; 201 DRIVER_MODULE(atlantic, pci, aq_driver, aq_devclass, 0, 0); 202 #endif 203 204 MODULE_DEPEND(atlantic, pci, 1, 1, 1); 205 MODULE_DEPEND(atlantic, ether, 1, 1, 1); 206 MODULE_DEPEND(atlantic, iflib, 1, 1, 1); 207 208 IFLIB_PNP_INFO(pci, atlantic, aq_vendor_info_array); 209 210 static device_method_t aq_if_methods[] = { 211 /* Device setup, teardown, etc */ 212 DEVMETHOD(ifdi_attach_pre, aq_if_attach_pre), 213 DEVMETHOD(ifdi_attach_post, aq_if_attach_post), 214 DEVMETHOD(ifdi_detach, aq_if_detach), 215 216 DEVMETHOD(ifdi_shutdown, aq_if_shutdown), 217 DEVMETHOD(ifdi_suspend, aq_if_suspend), 218 DEVMETHOD(ifdi_resume, aq_if_resume), 219 220 /* Soft queue setup and teardown */ 221 DEVMETHOD(ifdi_tx_queues_alloc, aq_if_tx_queues_alloc), 222 DEVMETHOD(ifdi_rx_queues_alloc, aq_if_rx_queues_alloc), 223 DEVMETHOD(ifdi_queues_free, aq_if_queues_free), 224 225 /* Device configuration */ 226 DEVMETHOD(ifdi_init, aq_if_init), 227 DEVMETHOD(ifdi_stop, aq_if_stop), 228 DEVMETHOD(ifdi_multi_set, aq_if_multi_set), 229 DEVMETHOD(ifdi_mtu_set, aq_if_mtu_set), 230 DEVMETHOD(ifdi_media_status, aq_if_media_status), 231 DEVMETHOD(ifdi_media_change, aq_if_media_change), 232 DEVMETHOD(ifdi_promisc_set, aq_if_promisc_set), 233 DEVMETHOD(ifdi_get_counter, aq_if_get_counter), 234 DEVMETHOD(ifdi_update_admin_status, aq_if_update_admin_status), 235 DEVMETHOD(ifdi_timer, aq_if_timer), 236 237 /* Interrupt enable / disable */ 238 DEVMETHOD(ifdi_intr_enable, aq_if_enable_intr), 239 DEVMETHOD(ifdi_intr_disable, aq_if_disable_intr), 240 DEVMETHOD(ifdi_rx_queue_intr_enable, aq_if_rx_queue_intr_enable), 241 DEVMETHOD(ifdi_tx_queue_intr_enable, aq_if_rx_queue_intr_enable), 242 DEVMETHOD(ifdi_msix_intr_assign, aq_if_msix_intr_assign), 243 244 /* VLAN support */ 245 DEVMETHOD(ifdi_vlan_register, aq_if_vlan_register), 246 DEVMETHOD(ifdi_vlan_unregister, aq_if_vlan_unregister), 247 248 /* Informational/diagnostic */ 249 DEVMETHOD(ifdi_led_func, aq_if_led_func), 250 251 DEVMETHOD_END 252 }; 253 254 static driver_t aq_if_driver = { 255 "aq_if", aq_if_methods, sizeof(struct aq_dev) 256 }; 257 258 static struct if_shared_ctx aq_sctx_init = { 259 .isc_magic = IFLIB_MAGIC, 260 .isc_q_align = PAGE_SIZE, 261 .isc_tx_maxsize = HW_ATL_B0_TSO_SIZE, 262 .isc_tx_maxsegsize = HW_ATL_B0_MTU_JUMBO, 263 #if __FreeBSD__ >= 12 264 .isc_tso_maxsize = HW_ATL_B0_TSO_SIZE, 265 .isc_tso_maxsegsize = HW_ATL_B0_MTU_JUMBO, 266 #endif 267 .isc_rx_maxsize = HW_ATL_B0_MTU_JUMBO, 268 .isc_rx_nsegments = 16, 269 .isc_rx_maxsegsize = PAGE_SIZE, 270 .isc_nfl = 1, 271 .isc_nrxqs = 1, 272 .isc_ntxqs = 1, 273 .isc_admin_intrcnt = 1, 274 .isc_vendor_info = aq_vendor_info_array, 275 .isc_driver_version = aq_driver_version, 276 .isc_driver = &aq_if_driver, 277 .isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP | 278 IFLIB_NEED_ZERO_CSUM, 279 280 .isc_nrxd_min = {HW_ATL_B0_MIN_RXD}, 281 .isc_ntxd_min = {HW_ATL_B0_MIN_TXD}, 282 .isc_nrxd_max = {HW_ATL_B0_MAX_RXD}, 283 .isc_ntxd_max = {HW_ATL_B0_MAX_TXD}, 284 .isc_nrxd_default = {PAGE_SIZE / sizeof(aq_txc_desc_t) * 4}, 285 .isc_ntxd_default = {PAGE_SIZE / sizeof(aq_txc_desc_t) * 4}, 286 }; 287 288 /* 289 * TUNEABLE PARAMETERS: 290 */ 291 292 static SYSCTL_NODE(_hw, OID_AUTO, aq, CTLFLAG_RD, 0, "Atlantic driver parameters"); 293 /* UDP Receive-Side Scaling */ 294 static int aq_enable_rss_udp = 1; 295 SYSCTL_INT(_hw_aq, OID_AUTO, enable_rss_udp, CTLFLAG_RDTUN, &aq_enable_rss_udp, 0, 296 "Enable Receive-Side Scaling (RSS) for UDP"); 297 298 299 /* 300 * Device Methods 301 */ 302 static void *aq_register(device_t dev) 303 { 304 return (&aq_sctx_init); 305 } 306 307 static int aq_if_attach_pre(if_ctx_t ctx) 308 { 309 struct aq_dev *softc; 310 struct aq_hw *hw; 311 if_softc_ctx_t scctx; 312 int rc; 313 314 AQ_DBG_ENTER(); 315 softc = iflib_get_softc(ctx); 316 rc = 0; 317 318 softc->ctx = ctx; 319 softc->dev = iflib_get_dev(ctx); 320 softc->media = iflib_get_media(ctx); 321 softc->scctx = iflib_get_softc_ctx(ctx); 322 softc->sctx = iflib_get_sctx(ctx); 323 scctx = softc->scctx; 324 325 softc->mmio_rid = PCIR_BAR(0); 326 softc->mmio_res = bus_alloc_resource_any(softc->dev, SYS_RES_MEMORY, 327 &softc->mmio_rid, RF_ACTIVE|RF_SHAREABLE); 328 if (softc->mmio_res == NULL) { 329 device_printf(softc->dev, 330 "failed to allocate MMIO resources\n"); 331 rc = ENXIO; 332 goto fail; 333 } 334 335 softc->mmio_tag = rman_get_bustag(softc->mmio_res); 336 softc->mmio_handle = rman_get_bushandle(softc->mmio_res); 337 softc->mmio_size = rman_get_size(softc->mmio_res); 338 softc->hw.hw_addr = (u8*) softc->mmio_handle; 339 hw = &softc->hw; 340 hw->link_rate = aq_fw_speed_auto; 341 hw->itr = -1; 342 hw->fc.fc_rx = 1; 343 hw->fc.fc_tx = 1; 344 softc->linkup = 0U; 345 346 /* Look up ops and caps. */ 347 rc = aq_hw_mpi_create(hw); 348 if (rc < 0) { 349 AQ_DBG_ERROR(" %s: aq_hw_mpi_create fail err=%d", __func__, rc); 350 goto fail; 351 } 352 353 if (hw->fast_start_enabled) { 354 if (hw->fw_ops && hw->fw_ops->reset) 355 hw->fw_ops->reset(hw); 356 } else 357 aq_hw_reset(&softc->hw); 358 aq_hw_capabilities(softc); 359 360 if (aq_hw_get_mac_permanent(hw, hw->mac_addr) < 0) { 361 AQ_DBG_ERROR("Unable to get mac addr from hw"); 362 goto fail; 363 }; 364 365 softc->admin_ticks = 0; 366 367 iflib_set_mac(ctx, hw->mac_addr); 368 #if __FreeBSD__ < 13 369 /* since FreeBSD13 deadlock due to calling iflib_led_func() under CTX_LOCK() */ 370 iflib_led_create(ctx); 371 #endif 372 scctx->isc_tx_csum_flags = CSUM_IP | CSUM_TCP | CSUM_UDP | CSUM_TSO; 373 #if __FreeBSD__ >= 12 374 scctx->isc_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_HWCSUM | IFCAP_TSO | 375 IFCAP_JUMBO_MTU | IFCAP_VLAN_HWFILTER | 376 IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | 377 IFCAP_VLAN_HWCSUM; 378 scctx->isc_capenable = scctx->isc_capabilities; 379 #else 380 if_t ifp; 381 ifp = iflib_get_ifp(ctx); 382 if_setcapenable(ifp, IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_HWCSUM | IFCAP_TSO | 383 IFCAP_JUMBO_MTU | IFCAP_VLAN_HWFILTER | 384 IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | 385 IFCAP_VLAN_HWCSUM; 386 #endif 387 scctx->isc_tx_nsegments = 31, 388 scctx->isc_tx_tso_segments_max = 31; 389 scctx->isc_tx_tso_size_max = HW_ATL_B0_TSO_SIZE - sizeof(struct ether_vlan_header); 390 scctx->isc_tx_tso_segsize_max = HW_ATL_B0_MTU_JUMBO; 391 scctx->isc_min_frame_size = 52; 392 scctx->isc_txrx = &aq_txrx; 393 394 scctx->isc_txqsizes[0] = sizeof(aq_tx_desc_t) * scctx->isc_ntxd[0]; 395 scctx->isc_rxqsizes[0] = sizeof(aq_rx_desc_t) * scctx->isc_nrxd[0]; 396 397 scctx->isc_ntxqsets_max = HW_ATL_B0_RINGS_MAX; 398 scctx->isc_nrxqsets_max = HW_ATL_B0_RINGS_MAX; 399 400 /* iflib will map and release this bar */ 401 scctx->isc_msix_bar = pci_msix_table_bar(softc->dev); 402 403 softc->vlan_tags = bit_alloc(4096, M_AQ, M_NOWAIT); 404 405 AQ_DBG_EXIT(rc); 406 return (rc); 407 408 fail: 409 if (softc->mmio_res != NULL) 410 bus_release_resource(softc->dev, SYS_RES_MEMORY, 411 softc->mmio_rid, softc->mmio_res); 412 413 AQ_DBG_EXIT(rc); 414 return (ENXIO); 415 } 416 417 418 static int aq_if_attach_post(if_ctx_t ctx) 419 { 420 struct aq_dev *softc; 421 int rc; 422 423 AQ_DBG_ENTER(); 424 425 softc = iflib_get_softc(ctx); 426 rc = 0; 427 428 aq_update_hw_stats(softc); 429 430 aq_initmedia(softc); 431 432 433 switch (softc->scctx->isc_intr) { 434 case IFLIB_INTR_LEGACY: 435 rc = EOPNOTSUPP; 436 goto exit; 437 goto exit; 438 break; 439 case IFLIB_INTR_MSI: 440 break; 441 case IFLIB_INTR_MSIX: 442 break; 443 default: 444 device_printf(softc->dev, "unknown interrupt mode\n"); 445 rc = EOPNOTSUPP; 446 goto exit; 447 } 448 449 aq_add_stats_sysctls(softc); 450 /* RSS */ 451 arc4rand(softc->rss_key, HW_ATL_RSS_HASHKEY_SIZE, 0); 452 for (int i = ARRAY_SIZE(softc->rss_table); i--;){ 453 softc->rss_table[i] = i & (softc->rx_rings_count - 1); 454 } 455 exit: 456 AQ_DBG_EXIT(rc); 457 return (rc); 458 } 459 460 461 static int aq_if_detach(if_ctx_t ctx) 462 { 463 struct aq_dev *softc; 464 int i; 465 466 AQ_DBG_ENTER(); 467 softc = iflib_get_softc(ctx); 468 469 aq_hw_deinit(&softc->hw); 470 471 for (i = 0; i < softc->scctx->isc_nrxqsets; i++) 472 iflib_irq_free(ctx, &softc->rx_rings[i]->irq); 473 iflib_irq_free(ctx, &softc->irq); 474 475 476 if (softc->mmio_res != NULL) 477 bus_release_resource(softc->dev, SYS_RES_MEMORY, 478 softc->mmio_rid, softc->mmio_res); 479 480 free(softc->vlan_tags, M_AQ); 481 482 AQ_DBG_EXIT(0); 483 return (0); 484 } 485 486 static int aq_if_shutdown(if_ctx_t ctx) 487 { 488 489 AQ_DBG_ENTER(); 490 491 AQ_XXX_UNIMPLEMENTED_FUNCTION; 492 493 AQ_DBG_EXIT(0); 494 return (0); 495 } 496 497 static int aq_if_suspend(if_ctx_t ctx) 498 { 499 AQ_DBG_ENTER(); 500 501 AQ_XXX_UNIMPLEMENTED_FUNCTION; 502 503 AQ_DBG_EXIT(0); 504 return (0); 505 } 506 507 static int aq_if_resume(if_ctx_t ctx) 508 { 509 AQ_DBG_ENTER(); 510 511 AQ_XXX_UNIMPLEMENTED_FUNCTION; 512 513 AQ_DBG_EXIT(0); 514 return (0); 515 } 516 517 /* Soft queue setup and teardown */ 518 static int aq_if_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 519 uint64_t *paddrs, int ntxqs, int ntxqsets) 520 { 521 struct aq_dev *softc; 522 struct aq_ring *ring; 523 int rc = 0, i; 524 525 AQ_DBG_ENTERA("ntxqs=%d, ntxqsets=%d", ntxqs, ntxqsets); 526 softc = iflib_get_softc(ctx); 527 AQ_DBG_PRINT("tx descriptors number %d", softc->scctx->isc_ntxd[0]); 528 529 for (i = 0; i < ntxqsets; i++) { 530 ring = softc->tx_rings[i] = malloc(sizeof(struct aq_ring), 531 M_AQ, M_NOWAIT | M_ZERO); 532 if (!ring){ 533 rc = ENOMEM; 534 device_printf(softc->dev, "atlantic: tx_ring malloc fail\n"); 535 goto fail; 536 } 537 ring->tx_descs = (aq_tx_desc_t*)vaddrs[i]; 538 ring->tx_size = softc->scctx->isc_ntxd[0]; 539 ring->tx_descs_phys = paddrs[i]; 540 ring->tx_head = ring->tx_tail = 0; 541 ring->index = i; 542 ring->dev = softc; 543 544 softc->tx_rings_count++; 545 } 546 547 AQ_DBG_EXIT(rc); 548 return (rc); 549 550 fail: 551 aq_if_queues_free(ctx); 552 AQ_DBG_EXIT(rc); 553 return (rc); 554 } 555 556 static int aq_if_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, 557 uint64_t *paddrs, int nrxqs, int nrxqsets) 558 { 559 struct aq_dev *softc; 560 struct aq_ring *ring; 561 int rc = 0, i; 562 563 AQ_DBG_ENTERA("nrxqs=%d, nrxqsets=%d", nrxqs, nrxqsets); 564 softc = iflib_get_softc(ctx); 565 566 for (i = 0; i < nrxqsets; i++) { 567 ring = softc->rx_rings[i] = malloc(sizeof(struct aq_ring), 568 M_AQ, M_NOWAIT | M_ZERO); 569 if (!ring){ 570 rc = ENOMEM; 571 device_printf(softc->dev, "atlantic: rx_ring malloc fail\n"); 572 goto fail; 573 } 574 575 ring->rx_descs = (aq_rx_desc_t*)vaddrs[i]; 576 ring->rx_descs_phys = paddrs[i]; 577 ring->rx_size = softc->scctx->isc_nrxd[0]; 578 ring->index = i; 579 ring->dev = softc; 580 581 switch (MCLBYTES) { 582 case (4 * 1024): 583 case (8 * 1024): 584 case (16 * 1024): 585 ring->rx_max_frame_size = MCLBYTES; 586 break; 587 default: 588 ring->rx_max_frame_size = 2048; 589 break; 590 } 591 592 softc->rx_rings_count++; 593 } 594 595 AQ_DBG_EXIT(rc); 596 return (rc); 597 598 fail: 599 aq_if_queues_free(ctx); 600 AQ_DBG_EXIT(rc); 601 return (rc); 602 } 603 604 static void aq_if_queues_free(if_ctx_t ctx) 605 { 606 struct aq_dev *softc; 607 int i; 608 609 AQ_DBG_ENTER(); 610 softc = iflib_get_softc(ctx); 611 612 for (i = 0; i < softc->tx_rings_count; i++) { 613 if (softc->tx_rings[i]) { 614 free(softc->tx_rings[i], M_AQ); 615 softc->tx_rings[i] = NULL; 616 } 617 } 618 softc->tx_rings_count = 0; 619 for (i = 0; i < softc->rx_rings_count; i++) { 620 if (softc->rx_rings[i]){ 621 free(softc->rx_rings[i], M_AQ); 622 softc->rx_rings[i] = NULL; 623 } 624 } 625 softc->rx_rings_count = 0; 626 627 AQ_DBG_EXIT(0); 628 return; 629 } 630 631 /* Device configuration */ 632 static void aq_if_init(if_ctx_t ctx) 633 { 634 struct aq_dev *softc; 635 struct aq_hw *hw; 636 struct ifmediareq ifmr; 637 int i, err; 638 639 AQ_DBG_ENTER(); 640 softc = iflib_get_softc(ctx); 641 hw = &softc->hw; 642 643 err = aq_hw_init(&softc->hw, softc->hw.mac_addr, softc->msix, 644 softc->scctx->isc_intr == IFLIB_INTR_MSIX); 645 if (err != EOK) { 646 device_printf(softc->dev, "atlantic: aq_hw_init: %d", err); 647 } 648 649 aq_if_media_status(ctx, &ifmr); 650 651 aq_update_vlan_filters(softc); 652 653 for (i = 0; i < softc->tx_rings_count; i++) { 654 struct aq_ring *ring = softc->tx_rings[i]; 655 err = aq_ring_tx_init(&softc->hw, ring); 656 if (err) { 657 device_printf(softc->dev, "atlantic: aq_ring_tx_init: %d", err); 658 } 659 err = aq_ring_tx_start(hw, ring); 660 if (err != EOK) { 661 device_printf(softc->dev, "atlantic: aq_ring_tx_start: %d", err); 662 } 663 } 664 for (i = 0; i < softc->rx_rings_count; i++) { 665 struct aq_ring *ring = softc->rx_rings[i]; 666 err = aq_ring_rx_init(&softc->hw, ring); 667 if (err) { 668 device_printf(softc->dev, "atlantic: aq_ring_rx_init: %d", err); 669 } 670 err = aq_ring_rx_start(hw, ring); 671 if (err != EOK) { 672 device_printf(softc->dev, "atlantic: aq_ring_rx_start: %d", err); 673 } 674 aq_if_rx_queue_intr_enable(ctx, i); 675 } 676 677 aq_hw_start(hw); 678 aq_if_enable_intr(ctx); 679 aq_hw_rss_hash_set(&softc->hw, softc->rss_key); 680 aq_hw_rss_set(&softc->hw, softc->rss_table); 681 aq_hw_udp_rss_enable(hw, aq_enable_rss_udp); 682 aq_hw_set_link_speed(hw, hw->link_rate); 683 684 AQ_DBG_EXIT(0); 685 } 686 687 688 static void aq_if_stop(if_ctx_t ctx) 689 { 690 struct aq_dev *softc; 691 struct aq_hw *hw; 692 int i; 693 694 AQ_DBG_ENTER(); 695 696 softc = iflib_get_softc(ctx); 697 hw = &softc->hw; 698 699 /* disable interrupt */ 700 aq_if_disable_intr(ctx); 701 702 for (i = 0; i < softc->tx_rings_count; i++) { 703 aq_ring_tx_stop(hw, softc->tx_rings[i]); 704 softc->tx_rings[i]->tx_head = 0; 705 softc->tx_rings[i]->tx_tail = 0; 706 } 707 for (i = 0; i < softc->rx_rings_count; i++) { 708 aq_ring_rx_stop(hw, softc->rx_rings[i]); 709 } 710 711 aq_hw_reset(&softc->hw); 712 memset(&softc->last_stats, 0, sizeof(softc->last_stats)); 713 softc->linkup = false; 714 aq_if_update_admin_status(ctx); 715 AQ_DBG_EXIT(0); 716 } 717 718 static uint64_t aq_if_get_counter(if_ctx_t ctx, ift_counter cnt) 719 { 720 struct aq_dev *softc = iflib_get_softc(ctx); 721 if_t ifp = iflib_get_ifp(ctx); 722 723 switch (cnt) { 724 case IFCOUNTER_IERRORS: 725 return (softc->curr_stats.erpr); 726 case IFCOUNTER_IQDROPS: 727 return (softc->curr_stats.dpc); 728 case IFCOUNTER_OERRORS: 729 return (softc->curr_stats.erpt); 730 default: 731 return (if_get_counter_default(ifp, cnt)); 732 } 733 } 734 735 #if __FreeBSD_version >= 1300054 736 static u_int aq_mc_filter_apply(void *arg, struct sockaddr_dl *dl, u_int count) 737 { 738 struct aq_dev *softc = arg; 739 struct aq_hw *hw = &softc->hw; 740 u8 *mac_addr = NULL; 741 742 if (count == AQ_HW_MAC_MAX) 743 return (0); 744 745 mac_addr = LLADDR(dl); 746 aq_hw_mac_addr_set(hw, mac_addr, count + 1); 747 748 aq_log_detail("set %d mc address %6D", count + 1, mac_addr, ":"); 749 return (1); 750 } 751 #else 752 static int aq_mc_filter_apply(void *arg, struct ifmultiaddr *ifma, int count) 753 { 754 struct aq_dev *softc = arg; 755 struct aq_hw *hw = &softc->hw; 756 u8 *mac_addr = NULL; 757 758 if (ifma->ifma_addr->sa_family != AF_LINK) 759 return (0); 760 if (count == AQ_HW_MAC_MAX) 761 return (0); 762 763 mac_addr = LLADDR((struct sockaddr_dl *)ifma->ifma_addr); 764 aq_hw_mac_addr_set(hw, mac_addr, count + 1); 765 766 aq_log_detail("set %d mc address %6D", count + 1, mac_addr, ":"); 767 return (1); 768 } 769 #endif 770 771 static bool aq_is_mc_promisc_required(struct aq_dev *softc) 772 { 773 return (softc->mcnt >= AQ_HW_MAC_MAX); 774 } 775 776 static void aq_if_multi_set(if_ctx_t ctx) 777 { 778 struct aq_dev *softc = iflib_get_softc(ctx); 779 if_t ifp = iflib_get_ifp(ctx); 780 struct aq_hw *hw = &softc->hw; 781 AQ_DBG_ENTER(); 782 #if __FreeBSD_version >= 1300054 783 softc->mcnt = if_llmaddr_count(iflib_get_ifp(ctx)); 784 #else 785 softc->mcnt = if_multiaddr_count(iflib_get_ifp(ctx), AQ_HW_MAC_MAX); 786 #endif 787 if (softc->mcnt >= AQ_HW_MAC_MAX) 788 { 789 aq_hw_set_promisc(hw, !!(if_getflags(ifp) & IFF_PROMISC), 790 aq_is_vlan_promisc_required(softc), 791 !!(if_getflags(ifp) & IFF_ALLMULTI) || aq_is_mc_promisc_required(softc)); 792 }else{ 793 #if __FreeBSD_version >= 1300054 794 if_foreach_llmaddr(iflib_get_ifp(ctx), &aq_mc_filter_apply, softc); 795 #else 796 if_multi_apply(iflib_get_ifp(ctx), aq_mc_filter_apply, softc); 797 #endif 798 } 799 AQ_DBG_EXIT(0); 800 } 801 802 static int aq_if_mtu_set(if_ctx_t ctx, uint32_t mtu) 803 { 804 int err = 0; 805 AQ_DBG_ENTER(); 806 807 AQ_DBG_EXIT(err); 808 return (err); 809 } 810 811 static void aq_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr) 812 { 813 if_t ifp; 814 815 AQ_DBG_ENTER(); 816 817 ifp = iflib_get_ifp(ctx); 818 819 aq_mediastatus(ifp, ifmr); 820 821 AQ_DBG_EXIT(0); 822 } 823 824 static int aq_if_media_change(if_ctx_t ctx) 825 { 826 struct aq_dev *softc = iflib_get_softc(ctx); 827 if_t ifp = iflib_get_ifp(ctx); 828 int rc = 0; 829 830 AQ_DBG_ENTER(); 831 832 /* Not allowd in UP state, since causes unsync of rings */ 833 if ((if_getflags(ifp) & IFF_UP)){ 834 rc = EPERM; 835 goto exit; 836 } 837 838 ifp = iflib_get_ifp(softc->ctx); 839 840 rc = aq_mediachange(ifp); 841 842 exit: 843 AQ_DBG_EXIT(rc); 844 return (rc); 845 } 846 847 static int aq_if_promisc_set(if_ctx_t ctx, int flags) 848 { 849 struct aq_dev *softc; 850 851 AQ_DBG_ENTER(); 852 853 softc = iflib_get_softc(ctx); 854 855 aq_hw_set_promisc(&softc->hw, !!(flags & IFF_PROMISC), 856 aq_is_vlan_promisc_required(softc), 857 !!(flags & IFF_ALLMULTI) || aq_is_mc_promisc_required(softc)); 858 859 AQ_DBG_EXIT(0); 860 return (0); 861 } 862 863 static void aq_if_timer(if_ctx_t ctx, uint16_t qid) 864 { 865 struct aq_dev *softc; 866 uint64_t ticks_now; 867 868 // AQ_DBG_ENTER(); 869 870 softc = iflib_get_softc(ctx); 871 ticks_now = ticks; 872 873 /* Schedule aqc_if_update_admin_status() once per sec */ 874 if (ticks_now - softc->admin_ticks >= hz) { 875 softc->admin_ticks = ticks_now; 876 iflib_admin_intr_deferred(ctx); 877 } 878 879 // AQ_DBG_EXIT(0); 880 return; 881 882 } 883 884 /* Interrupt enable / disable */ 885 static void aq_if_enable_intr(if_ctx_t ctx) 886 { 887 struct aq_dev *softc = iflib_get_softc(ctx); 888 struct aq_hw *hw = &softc->hw; 889 890 AQ_DBG_ENTER(); 891 892 /* Enable interrupts */ 893 itr_irq_msk_setlsw_set(hw, BIT(softc->msix + 1) - 1); 894 895 AQ_DBG_EXIT(0); 896 } 897 898 static void aq_if_disable_intr(if_ctx_t ctx) 899 { 900 struct aq_dev *softc = iflib_get_softc(ctx); 901 struct aq_hw *hw = &softc->hw; 902 903 AQ_DBG_ENTER(); 904 905 /* Disable interrupts */ 906 itr_irq_msk_clearlsw_set(hw, BIT(softc->msix + 1) - 1); 907 908 AQ_DBG_EXIT(0); 909 } 910 911 static int aq_if_rx_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid) 912 { 913 struct aq_dev *softc = iflib_get_softc(ctx); 914 struct aq_hw *hw = &softc->hw; 915 916 AQ_DBG_ENTER(); 917 918 itr_irq_msk_setlsw_set(hw, BIT(softc->rx_rings[rxqid]->msix)); 919 920 AQ_DBG_EXIT(0); 921 return (0); 922 } 923 924 static int aq_if_msix_intr_assign(if_ctx_t ctx, int msix) 925 { 926 struct aq_dev *softc; 927 int i, vector = 0, rc; 928 char irq_name[16]; 929 int rx_vectors; 930 931 AQ_DBG_ENTER(); 932 softc = iflib_get_softc(ctx); 933 934 for (i = 0; i < softc->rx_rings_count; i++, vector++) { 935 snprintf(irq_name, sizeof(irq_name), "rxq%d", i); 936 rc = iflib_irq_alloc_generic(ctx, &softc->rx_rings[i]->irq, 937 vector + 1, IFLIB_INTR_RX, aq_isr_rx, softc->rx_rings[i], 938 softc->rx_rings[i]->index, irq_name); 939 device_printf(softc->dev, "Assign IRQ %u to rx ring %u\n", 940 vector, softc->rx_rings[i]->index); 941 942 if (rc) { 943 device_printf(softc->dev, "failed to set up RX handler\n"); 944 i--; 945 goto fail; 946 } 947 948 softc->rx_rings[i]->msix = vector; 949 } 950 951 rx_vectors = vector; 952 953 for (i = 0; i < softc->tx_rings_count; i++, vector++) { 954 snprintf(irq_name, sizeof(irq_name), "txq%d", i); 955 iflib_softirq_alloc_generic(ctx, &softc->rx_rings[i]->irq, IFLIB_INTR_TX, 956 softc->tx_rings[i], i, irq_name); 957 958 softc->tx_rings[i]->msix = (vector % softc->rx_rings_count); 959 device_printf(softc->dev, "Assign IRQ %u to tx ring %u\n", 960 softc->tx_rings[i]->msix, softc->tx_rings[i]->index); 961 } 962 963 rc = iflib_irq_alloc_generic(ctx, &softc->irq, rx_vectors + 1, 964 IFLIB_INTR_ADMIN, aq_linkstat_isr, 965 softc, 0, "aq"); 966 softc->msix = rx_vectors; 967 device_printf(softc->dev, "Assign IRQ %u to admin proc \n", 968 rx_vectors); 969 if (rc) { 970 device_printf(iflib_get_dev(ctx), "Failed to register admin handler"); 971 i = softc->rx_rings_count; 972 goto fail; 973 } 974 AQ_DBG_EXIT(0); 975 return (0); 976 977 fail: 978 for (; i >= 0; i--) 979 iflib_irq_free(ctx, &softc->rx_rings[i]->irq); 980 AQ_DBG_EXIT(rc); 981 return (rc); 982 } 983 984 static bool aq_is_vlan_promisc_required(struct aq_dev *softc) 985 { 986 int vlan_tag_count; 987 988 bit_count(softc->vlan_tags, 0, 4096, &vlan_tag_count); 989 990 if (vlan_tag_count <= AQ_HW_VLAN_MAX_FILTERS) 991 return (false); 992 else 993 return (true); 994 995 } 996 997 static void aq_update_vlan_filters(struct aq_dev *softc) 998 { 999 struct aq_rx_filter_vlan aq_vlans[AQ_HW_VLAN_MAX_FILTERS]; 1000 struct aq_hw *hw = &softc->hw; 1001 int bit_pos = 0; 1002 int vlan_tag = -1; 1003 int i; 1004 1005 hw_atl_b0_hw_vlan_promisc_set(hw, true); 1006 for (i = 0; i < AQ_HW_VLAN_MAX_FILTERS; i++) { 1007 bit_ffs_at(softc->vlan_tags, bit_pos, 4096, &vlan_tag); 1008 if (vlan_tag != -1) { 1009 aq_vlans[i].enable = true; 1010 aq_vlans[i].location = i; 1011 aq_vlans[i].queue = 0xFF; 1012 aq_vlans[i].vlan_id = vlan_tag; 1013 bit_pos = vlan_tag; 1014 } else { 1015 aq_vlans[i].enable = false; 1016 } 1017 } 1018 1019 hw_atl_b0_hw_vlan_set(hw, aq_vlans); 1020 hw_atl_b0_hw_vlan_promisc_set(hw, aq_is_vlan_promisc_required(softc)); 1021 } 1022 1023 /* VLAN support */ 1024 static void aq_if_vlan_register(if_ctx_t ctx, uint16_t vtag) 1025 { 1026 struct aq_dev *softc = iflib_get_softc(ctx); 1027 1028 AQ_DBG_ENTERA("%d", vtag); 1029 1030 bit_set(softc->vlan_tags, vtag); 1031 1032 aq_update_vlan_filters(softc); 1033 1034 AQ_DBG_EXIT(0); 1035 } 1036 1037 static void aq_if_vlan_unregister(if_ctx_t ctx, uint16_t vtag) 1038 { 1039 struct aq_dev *softc = iflib_get_softc(ctx); 1040 1041 AQ_DBG_ENTERA("%d", vtag); 1042 1043 bit_clear(softc->vlan_tags, vtag); 1044 1045 aq_update_vlan_filters(softc); 1046 1047 AQ_DBG_EXIT(0); 1048 } 1049 1050 static void aq_if_led_func(if_ctx_t ctx, int onoff) 1051 { 1052 struct aq_dev *softc = iflib_get_softc(ctx); 1053 struct aq_hw *hw = &softc->hw; 1054 1055 AQ_DBG_ENTERA("%d", onoff); 1056 if (hw->fw_ops && hw->fw_ops->led_control) 1057 hw->fw_ops->led_control(hw, onoff); 1058 1059 AQ_DBG_EXIT(0); 1060 } 1061 1062 static int aq_hw_capabilities(struct aq_dev *softc) 1063 { 1064 1065 if (pci_get_vendor(softc->dev) != AQUANTIA_VENDOR_ID) 1066 return (ENXIO); 1067 1068 switch (pci_get_device(softc->dev)) { 1069 case AQ_DEVICE_ID_D100: 1070 case AQ_DEVICE_ID_AQC100: 1071 case AQ_DEVICE_ID_AQC100S: 1072 softc->media_type = AQ_MEDIA_TYPE_FIBRE; 1073 softc->link_speeds = AQ_LINK_ALL & ~AQ_LINK_10G; 1074 break; 1075 1076 case AQ_DEVICE_ID_0001: 1077 case AQ_DEVICE_ID_D107: 1078 case AQ_DEVICE_ID_AQC107: 1079 case AQ_DEVICE_ID_AQC107S: 1080 softc->media_type = AQ_MEDIA_TYPE_TP; 1081 softc->link_speeds = AQ_LINK_ALL; 1082 break; 1083 1084 case AQ_DEVICE_ID_D108: 1085 case AQ_DEVICE_ID_AQC108: 1086 case AQ_DEVICE_ID_AQC108S: 1087 case AQ_DEVICE_ID_AQC111: 1088 case AQ_DEVICE_ID_AQC111S: 1089 softc->media_type = AQ_MEDIA_TYPE_TP; 1090 softc->link_speeds = AQ_LINK_ALL & ~AQ_LINK_10G; 1091 break; 1092 1093 case AQ_DEVICE_ID_D109: 1094 case AQ_DEVICE_ID_AQC109: 1095 case AQ_DEVICE_ID_AQC109S: 1096 case AQ_DEVICE_ID_AQC112: 1097 case AQ_DEVICE_ID_AQC112S: 1098 softc->media_type = AQ_MEDIA_TYPE_TP; 1099 softc->link_speeds = AQ_LINK_ALL & ~(AQ_LINK_10G | AQ_LINK_5G); 1100 break; 1101 1102 default: 1103 return (ENXIO); 1104 } 1105 1106 return (0); 1107 } 1108 1109 static int aq_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS) 1110 { 1111 struct aq_dev *softc = (struct aq_dev *)arg1; 1112 device_t dev = softc->dev; 1113 struct sbuf *buf; 1114 int error = 0; 1115 1116 buf = sbuf_new_for_sysctl(NULL, NULL, 256, req); 1117 if (!buf) { 1118 device_printf(dev, "Could not allocate sbuf for output.\n"); 1119 return (ENOMEM); 1120 } 1121 1122 /* Print out the redirection table */ 1123 sbuf_cat(buf, "\nRSS Indirection table:\n"); 1124 for (int i = 0; i < HW_ATL_RSS_INDIRECTION_TABLE_MAX; i++) { 1125 sbuf_printf(buf, "%d ", softc->rss_table[i]); 1126 if ((i+1) % 10 == 0) 1127 sbuf_printf(buf, "\n"); 1128 } 1129 1130 sbuf_cat(buf, "\nRSS Key:\n"); 1131 for (int i = 0; i < HW_ATL_RSS_HASHKEY_SIZE; i++) { 1132 sbuf_printf(buf, "0x%02x ", softc->rss_key[i]); 1133 } 1134 sbuf_printf(buf, "\n"); 1135 1136 error = sbuf_finish(buf); 1137 if (error) 1138 device_printf(dev, "Error finishing sbuf: %d\n", error); 1139 1140 sbuf_delete(buf); 1141 1142 return (0); 1143 } 1144 1145 static int aq_sysctl_print_tx_head(SYSCTL_HANDLER_ARGS) 1146 { 1147 struct aq_ring *ring = arg1; 1148 int error = 0; 1149 unsigned int val; 1150 1151 if (!ring) 1152 return (0); 1153 1154 val = tdm_tx_desc_head_ptr_get(&ring->dev->hw, ring->index); 1155 1156 error = sysctl_handle_int(oidp, &val, 0, req); 1157 if (error || !req->newptr) 1158 return (error); 1159 1160 return (0); 1161 } 1162 1163 static int aq_sysctl_print_tx_tail(SYSCTL_HANDLER_ARGS) 1164 { 1165 struct aq_ring *ring = arg1; 1166 int error = 0; 1167 unsigned int val; 1168 1169 if (!ring) 1170 return (0); 1171 1172 val = reg_tx_dma_desc_tail_ptr_get(&ring->dev->hw, ring->index); 1173 1174 error = sysctl_handle_int(oidp, &val, 0, req); 1175 if (error || !req->newptr) 1176 return (error); 1177 1178 return (0); 1179 } 1180 1181 static int aq_sysctl_print_rx_head(SYSCTL_HANDLER_ARGS) 1182 { 1183 struct aq_ring *ring = arg1; 1184 int error = 0; 1185 unsigned int val; 1186 1187 if (!ring) 1188 return (0); 1189 1190 val = rdm_rx_desc_head_ptr_get(&ring->dev->hw, ring->index); 1191 1192 error = sysctl_handle_int(oidp, &val, 0, req); 1193 if (error || !req->newptr) 1194 return (error); 1195 1196 return (0); 1197 } 1198 1199 static int aq_sysctl_print_rx_tail(SYSCTL_HANDLER_ARGS) 1200 { 1201 struct aq_ring *ring = arg1; 1202 int error = 0; 1203 unsigned int val; 1204 1205 if (!ring) 1206 return (0); 1207 1208 val = reg_rx_dma_desc_tail_ptr_get(&ring->dev->hw, ring->index); 1209 1210 error = sysctl_handle_int(oidp, &val, 0, req); 1211 if (error || !req->newptr) 1212 return (error); 1213 1214 return (0); 1215 } 1216 1217 static void aq_add_stats_sysctls(struct aq_dev *softc) 1218 { 1219 device_t dev = softc->dev; 1220 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); 1221 struct sysctl_oid *tree = device_get_sysctl_tree(dev); 1222 struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); 1223 struct aq_stats_s *stats = &softc->curr_stats; 1224 struct sysctl_oid *stat_node, *queue_node; 1225 struct sysctl_oid_list *stat_list, *queue_list; 1226 1227 #define QUEUE_NAME_LEN 32 1228 char namebuf[QUEUE_NAME_LEN]; 1229 /* RSS configuration */ 1230 SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "print_rss_config", 1231 CTLTYPE_STRING | CTLFLAG_RD, softc, 0, 1232 aq_sysctl_print_rss_config, "A", "Prints RSS Configuration"); 1233 1234 /* Driver Statistics */ 1235 for (int i = 0; i < softc->tx_rings_count; i++) { 1236 struct aq_ring *ring = softc->tx_rings[i]; 1237 snprintf(namebuf, QUEUE_NAME_LEN, "tx_queue%d", i); 1238 queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, 1239 CTLFLAG_RD, NULL, "Queue Name"); 1240 queue_list = SYSCTL_CHILDREN(queue_node); 1241 1242 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_pkts", 1243 CTLFLAG_RD, &(ring->stats.tx_pkts), "TX Packets"); 1244 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_bytes", 1245 CTLFLAG_RD, &(ring->stats.tx_bytes), "TX Octets"); 1246 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_drops", 1247 CTLFLAG_RD, &(ring->stats.tx_drops), "TX Drops"); 1248 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_queue_full", 1249 CTLFLAG_RD, &(ring->stats.tx_queue_full), "TX Queue Full"); 1250 SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "tx_head", 1251 CTLTYPE_UINT | CTLFLAG_RD, ring, 0, 1252 aq_sysctl_print_tx_head, "IU", "ring head pointer"); 1253 SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "tx_tail", 1254 CTLTYPE_UINT | CTLFLAG_RD, ring, 0, 1255 aq_sysctl_print_tx_tail, "IU", "ring tail pointer"); 1256 } 1257 1258 for (int i = 0; i < softc->rx_rings_count; i++) { 1259 struct aq_ring *ring = softc->rx_rings[i]; 1260 snprintf(namebuf, QUEUE_NAME_LEN, "rx_queue%d", i); 1261 queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf, 1262 CTLFLAG_RD, NULL, "Queue Name"); 1263 queue_list = SYSCTL_CHILDREN(queue_node); 1264 1265 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_pkts", 1266 CTLFLAG_RD, &(ring->stats.rx_pkts), "RX Packets"); 1267 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes", 1268 CTLFLAG_RD, &(ring->stats.rx_bytes), "TX Octets"); 1269 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "jumbo_pkts", 1270 CTLFLAG_RD, &(ring->stats.jumbo_pkts), "Jumbo Packets"); 1271 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_err", 1272 CTLFLAG_RD, &(ring->stats.rx_err), "RX Errors"); 1273 SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irq", 1274 CTLFLAG_RD, &(ring->stats.irq), "RX interrupts"); 1275 SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rx_head", 1276 CTLTYPE_UINT | CTLFLAG_RD, ring, 0, 1277 aq_sysctl_print_rx_head, "IU", "ring head pointer"); 1278 SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rx_tail", 1279 CTLTYPE_UINT | CTLFLAG_RD, ring, 0, 1280 aq_sysctl_print_rx_tail, "IU", " ring tail pointer"); 1281 } 1282 1283 stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac", 1284 CTLFLAG_RD, NULL, "Statistics (read from HW registers)"); 1285 stat_list = SYSCTL_CHILDREN(stat_node); 1286 1287 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd", 1288 CTLFLAG_RD, &stats->prc, "Good Packets Received"); 1289 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_pkts_rcvd", 1290 CTLFLAG_RD, &stats->uprc, "Unicast Packets Received"); 1291 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd", 1292 CTLFLAG_RD, &stats->mprc, "Multicast Packets Received"); 1293 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_rcvd", 1294 CTLFLAG_RD, &stats->bprc, "Broadcast Packets Received"); 1295 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rsc_pkts_rcvd", 1296 CTLFLAG_RD, &stats->cprc, "Coalesced Packets Received"); 1297 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "err_pkts_rcvd", 1298 CTLFLAG_RD, &stats->erpr, "Errors of Packet Receive"); 1299 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "drop_pkts_dma", 1300 CTLFLAG_RD, &stats->dpc, "Dropped Packets in DMA"); 1301 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd", 1302 CTLFLAG_RD, &stats->brc, "Good Octets Received"); 1303 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_octets_rcvd", 1304 CTLFLAG_RD, &stats->ubrc, "Unicast Octets Received"); 1305 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_octets_rcvd", 1306 CTLFLAG_RD, &stats->mbrc, "Multicast Octets Received"); 1307 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_octets_rcvd", 1308 CTLFLAG_RD, &stats->bbrc, "Broadcast Octets Received"); 1309 1310 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd", 1311 CTLFLAG_RD, &stats->ptc, "Good Packets Transmitted"); 1312 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_pkts_txd", 1313 CTLFLAG_RD, &stats->uptc, "Unicast Packets Transmitted"); 1314 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd", 1315 CTLFLAG_RD, &stats->mptc, "Multicast Packets Transmitted"); 1316 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd", 1317 CTLFLAG_RD, &stats->bptc, "Broadcast Packets Transmitted"); 1318 1319 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "err_pkts_txd", 1320 CTLFLAG_RD, &stats->erpt, "Errors of Packet Transmit"); 1321 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", 1322 CTLFLAG_RD, &stats->btc, "Good Octets Transmitted"); 1323 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "ucast_octets_txd", 1324 CTLFLAG_RD, &stats->ubtc, "Unicast Octets Transmitted"); 1325 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_octets_txd", 1326 CTLFLAG_RD, &stats->mbtc, "Multicast Octets Transmitted"); 1327 SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_octets_txd", 1328 CTLFLAG_RD, &stats->bbtc, "Broadcast Octets Transmitted"); 1329 } 1330