1280182Sjfv/****************************************************************************** 2280182Sjfv 3280182Sjfv Copyright (c) 2001-2015, Intel Corporation 4280182Sjfv All rights reserved. 5280182Sjfv 6280182Sjfv Redistribution and use in source and binary forms, with or without 7280182Sjfv modification, are permitted provided that the following conditions are met: 8280182Sjfv 9280182Sjfv 1. Redistributions of source code must retain the above copyright notice, 10280182Sjfv this list of conditions and the following disclaimer. 11280182Sjfv 12280182Sjfv 2. Redistributions in binary form must reproduce the above copyright 13280182Sjfv notice, this list of conditions and the following disclaimer in the 14280182Sjfv documentation and/or other materials provided with the distribution. 15280182Sjfv 16280182Sjfv 3. Neither the name of the Intel Corporation nor the names of its 17280182Sjfv contributors may be used to endorse or promote products derived from 18280182Sjfv this software without specific prior written permission. 19280182Sjfv 20280182Sjfv THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21280182Sjfv AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22280182Sjfv IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23280182Sjfv ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24280182Sjfv LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25280182Sjfv CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26280182Sjfv SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27280182Sjfv INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28280182Sjfv CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29280182Sjfv ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30280182Sjfv POSSIBILITY OF SUCH DAMAGE. 31280182Sjfv 32280182Sjfv******************************************************************************/ 33280182Sjfv/*$FreeBSD: releng/10.3/sys/dev/ixgbe/if_ixv.c 295524 2016-02-11 16:16:10Z sbruno $*/ 34280182Sjfv 35280182Sjfv 36280182Sjfv#ifndef IXGBE_STANDALONE_BUILD 37280182Sjfv#include "opt_inet.h" 38280182Sjfv#include "opt_inet6.h" 39280182Sjfv#endif 40280182Sjfv 41280182Sjfv#include "ixgbe.h" 42280182Sjfv 43280182Sjfv/********************************************************************* 44280182Sjfv * Driver version 45280182Sjfv *********************************************************************/ 46295524Ssbrunochar ixv_driver_version[] = "1.4.6-k"; 47280182Sjfv 48280182Sjfv/********************************************************************* 49280182Sjfv * PCI Device ID Table 50280182Sjfv * 51280182Sjfv * Used by probe to select devices to load on 52280182Sjfv * Last field stores an index into ixv_strings 53280182Sjfv * Last entry must be all 0s 54280182Sjfv * 55280182Sjfv * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index } 56280182Sjfv *********************************************************************/ 57280182Sjfv 58280182Sjfvstatic ixgbe_vendor_info_t ixv_vendor_info_array[] = 59280182Sjfv{ 60280182Sjfv {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_82599_VF, 0, 0, 0}, 61280182Sjfv {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540_VF, 0, 0, 0}, 62280182Sjfv {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550_VF, 0, 0, 0}, 63280182Sjfv {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_VF, 0, 0, 0}, 64280182Sjfv /* required last entry */ 65280182Sjfv {0, 0, 0, 0, 0} 66280182Sjfv}; 67280182Sjfv 68280182Sjfv/********************************************************************* 69280182Sjfv * Table of branding strings 70280182Sjfv *********************************************************************/ 71280182Sjfv 72280182Sjfvstatic char *ixv_strings[] = { 73280182Sjfv "Intel(R) PRO/10GbE Virtual Function Network Driver" 74280182Sjfv}; 75280182Sjfv 76280182Sjfv/********************************************************************* 77280182Sjfv * Function prototypes 78280182Sjfv *********************************************************************/ 79280182Sjfvstatic int ixv_probe(device_t); 80280182Sjfvstatic int ixv_attach(device_t); 81280182Sjfvstatic int ixv_detach(device_t); 82280182Sjfvstatic int ixv_shutdown(device_t); 83280182Sjfvstatic int ixv_ioctl(struct ifnet *, u_long, caddr_t); 84280182Sjfvstatic void ixv_init(void *); 85280182Sjfvstatic void ixv_init_locked(struct adapter *); 86280182Sjfvstatic void ixv_stop(void *); 87280182Sjfvstatic void ixv_media_status(struct ifnet *, struct ifmediareq *); 88280182Sjfvstatic int ixv_media_change(struct ifnet *); 89280182Sjfvstatic void ixv_identify_hardware(struct adapter *); 90280182Sjfvstatic int ixv_allocate_pci_resources(struct adapter *); 91280182Sjfvstatic int ixv_allocate_msix(struct adapter *); 92280182Sjfvstatic int ixv_setup_msix(struct adapter *); 93280182Sjfvstatic void ixv_free_pci_resources(struct adapter *); 94280182Sjfvstatic void ixv_local_timer(void *); 95280182Sjfvstatic void ixv_setup_interface(device_t, struct adapter *); 96280182Sjfvstatic void ixv_config_link(struct adapter *); 97280182Sjfv 98280182Sjfvstatic void ixv_initialize_transmit_units(struct adapter *); 99280182Sjfvstatic void ixv_initialize_receive_units(struct adapter *); 100280182Sjfv 101280182Sjfvstatic void ixv_enable_intr(struct adapter *); 102280182Sjfvstatic void ixv_disable_intr(struct adapter *); 103280182Sjfvstatic void ixv_set_multi(struct adapter *); 104280182Sjfvstatic void ixv_update_link_status(struct adapter *); 105280182Sjfvstatic int ixv_sysctl_debug(SYSCTL_HANDLER_ARGS); 106280182Sjfvstatic void ixv_set_ivar(struct adapter *, u8, u8, s8); 107280182Sjfvstatic void ixv_configure_ivars(struct adapter *); 108280182Sjfvstatic u8 * ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); 109280182Sjfv 110280182Sjfvstatic void ixv_setup_vlan_support(struct adapter *); 111280182Sjfvstatic void ixv_register_vlan(void *, struct ifnet *, u16); 112280182Sjfvstatic void ixv_unregister_vlan(void *, struct ifnet *, u16); 113280182Sjfv 114280182Sjfvstatic void ixv_save_stats(struct adapter *); 115280182Sjfvstatic void ixv_init_stats(struct adapter *); 116280182Sjfvstatic void ixv_update_stats(struct adapter *); 117280182Sjfvstatic void ixv_add_stats_sysctls(struct adapter *); 118294034Ssbrunostatic void ixv_set_sysctl_value(struct adapter *, const char *, 119294034Ssbruno const char *, int *, int); 120280182Sjfv 121280182Sjfv/* The MSI/X Interrupt handlers */ 122280182Sjfvstatic void ixv_msix_que(void *); 123280182Sjfvstatic void ixv_msix_mbx(void *); 124280182Sjfv 125280182Sjfv/* Deferred interrupt tasklets */ 126280182Sjfvstatic void ixv_handle_que(void *, int); 127280182Sjfvstatic void ixv_handle_mbx(void *, int); 128280182Sjfv 129295008Ssbruno#ifdef DEV_NETMAP 130295008Ssbruno/* 131295008Ssbruno * This is defined in <dev/netmap/ixgbe_netmap.h>, which is included by 132295008Ssbruno * if_ix.c. 133295008Ssbruno */ 134295008Ssbrunoextern void ixgbe_netmap_attach(struct adapter *adapter); 135295008Ssbruno 136295008Ssbruno#include <net/netmap.h> 137295008Ssbruno#include <sys/selinfo.h> 138295008Ssbruno#include <dev/netmap/netmap_kern.h> 139295008Ssbruno#endif /* DEV_NETMAP */ 140295008Ssbruno 141280182Sjfv/********************************************************************* 142280182Sjfv * FreeBSD Device Interface Entry Points 143280182Sjfv *********************************************************************/ 144280182Sjfv 145280182Sjfvstatic device_method_t ixv_methods[] = { 146280182Sjfv /* Device interface */ 147280182Sjfv DEVMETHOD(device_probe, ixv_probe), 148280182Sjfv DEVMETHOD(device_attach, ixv_attach), 149280182Sjfv DEVMETHOD(device_detach, ixv_detach), 150280182Sjfv DEVMETHOD(device_shutdown, ixv_shutdown), 151280182Sjfv DEVMETHOD_END 152280182Sjfv}; 153280182Sjfv 154280182Sjfvstatic driver_t ixv_driver = { 155280182Sjfv "ixv", ixv_methods, sizeof(struct adapter), 156280182Sjfv}; 157280182Sjfv 158283620Serjdevclass_t ixv_devclass; 159283620SerjDRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0); 160280182SjfvMODULE_DEPEND(ixv, pci, 1, 1, 1); 161280182SjfvMODULE_DEPEND(ixv, ether, 1, 1, 1); 162295008Ssbruno#ifdef DEV_NETMAP 163295008SsbrunoMODULE_DEPEND(ix, netmap, 1, 1, 1); 164295008Ssbruno#endif /* DEV_NETMAP */ 165283620Serj/* XXX depend on 'ix' ? */ 166280182Sjfv 167280182Sjfv/* 168280182Sjfv** TUNEABLE PARAMETERS: 169280182Sjfv*/ 170280182Sjfv 171295008Ssbruno/* Number of Queues - do not exceed MSIX vectors - 1 */ 172295008Ssbrunostatic int ixv_num_queues = 1; 173295008SsbrunoTUNABLE_INT("hw.ixv.num_queues", &ixv_num_queues); 174295008Ssbruno 175280182Sjfv/* 176280182Sjfv** AIM: Adaptive Interrupt Moderation 177280182Sjfv** which means that the interrupt rate 178280182Sjfv** is varied over time based on the 179280182Sjfv** traffic for that interrupt vector 180280182Sjfv*/ 181280182Sjfvstatic int ixv_enable_aim = FALSE; 182280182SjfvTUNABLE_INT("hw.ixv.enable_aim", &ixv_enable_aim); 183280182Sjfv 184280182Sjfv/* How many packets rxeof tries to clean at a time */ 185280182Sjfvstatic int ixv_rx_process_limit = 256; 186280182SjfvTUNABLE_INT("hw.ixv.rx_process_limit", &ixv_rx_process_limit); 187280182Sjfv 188280182Sjfv/* How many packets txeof tries to clean at a time */ 189280182Sjfvstatic int ixv_tx_process_limit = 256; 190280182SjfvTUNABLE_INT("hw.ixv.tx_process_limit", &ixv_tx_process_limit); 191280182Sjfv 192280182Sjfv/* Flow control setting, default to full */ 193280182Sjfvstatic int ixv_flow_control = ixgbe_fc_full; 194280182SjfvTUNABLE_INT("hw.ixv.flow_control", &ixv_flow_control); 195280182Sjfv 196280182Sjfv/* 197280182Sjfv * Header split: this causes the hardware to DMA 198280182Sjfv * the header into a seperate mbuf from the payload, 199280182Sjfv * it can be a performance win in some workloads, but 200280182Sjfv * in others it actually hurts, its off by default. 201280182Sjfv */ 202280182Sjfvstatic int ixv_header_split = FALSE; 203280182SjfvTUNABLE_INT("hw.ixv.hdr_split", &ixv_header_split); 204280182Sjfv 205280182Sjfv/* 206280182Sjfv** Number of TX descriptors per ring, 207280182Sjfv** setting higher than RX as this seems 208280182Sjfv** the better performing choice. 209280182Sjfv*/ 210280182Sjfvstatic int ixv_txd = DEFAULT_TXD; 211280182SjfvTUNABLE_INT("hw.ixv.txd", &ixv_txd); 212280182Sjfv 213280182Sjfv/* Number of RX descriptors per ring */ 214280182Sjfvstatic int ixv_rxd = DEFAULT_RXD; 215280182SjfvTUNABLE_INT("hw.ixv.rxd", &ixv_rxd); 216280182Sjfv 217280182Sjfv/* 218280182Sjfv** Shadow VFTA table, this is needed because 219280182Sjfv** the real filter table gets cleared during 220280182Sjfv** a soft reset and we need to repopulate it. 221280182Sjfv*/ 222280182Sjfvstatic u32 ixv_shadow_vfta[IXGBE_VFTA_SIZE]; 223280182Sjfv 224280182Sjfv/********************************************************************* 225280182Sjfv * Device identification routine 226280182Sjfv * 227280182Sjfv * ixv_probe determines if the driver should be loaded on 228280182Sjfv * adapter based on PCI vendor/device id of the adapter. 229280182Sjfv * 230280182Sjfv * return BUS_PROBE_DEFAULT on success, positive on failure 231280182Sjfv *********************************************************************/ 232280182Sjfv 233280182Sjfvstatic int 234280182Sjfvixv_probe(device_t dev) 235280182Sjfv{ 236280182Sjfv ixgbe_vendor_info_t *ent; 237280182Sjfv 238280182Sjfv u16 pci_vendor_id = 0; 239280182Sjfv u16 pci_device_id = 0; 240280182Sjfv u16 pci_subvendor_id = 0; 241280182Sjfv u16 pci_subdevice_id = 0; 242280182Sjfv char adapter_name[256]; 243280182Sjfv 244280182Sjfv 245280182Sjfv pci_vendor_id = pci_get_vendor(dev); 246280182Sjfv if (pci_vendor_id != IXGBE_INTEL_VENDOR_ID) 247280182Sjfv return (ENXIO); 248280182Sjfv 249280182Sjfv pci_device_id = pci_get_device(dev); 250280182Sjfv pci_subvendor_id = pci_get_subvendor(dev); 251280182Sjfv pci_subdevice_id = pci_get_subdevice(dev); 252280182Sjfv 253280182Sjfv ent = ixv_vendor_info_array; 254280182Sjfv while (ent->vendor_id != 0) { 255280182Sjfv if ((pci_vendor_id == ent->vendor_id) && 256280182Sjfv (pci_device_id == ent->device_id) && 257280182Sjfv 258280182Sjfv ((pci_subvendor_id == ent->subvendor_id) || 259280182Sjfv (ent->subvendor_id == 0)) && 260280182Sjfv 261280182Sjfv ((pci_subdevice_id == ent->subdevice_id) || 262280182Sjfv (ent->subdevice_id == 0))) { 263280182Sjfv sprintf(adapter_name, "%s, Version - %s", 264280182Sjfv ixv_strings[ent->index], 265280182Sjfv ixv_driver_version); 266280182Sjfv device_set_desc_copy(dev, adapter_name); 267280182Sjfv return (BUS_PROBE_DEFAULT); 268280182Sjfv } 269280182Sjfv ent++; 270280182Sjfv } 271280182Sjfv return (ENXIO); 272280182Sjfv} 273280182Sjfv 274280182Sjfv/********************************************************************* 275280182Sjfv * Device initialization routine 276280182Sjfv * 277280182Sjfv * The attach entry point is called when the driver is being loaded. 278280182Sjfv * This routine identifies the type of hardware, allocates all resources 279280182Sjfv * and initializes the hardware. 280280182Sjfv * 281280182Sjfv * return 0 on success, positive on failure 282280182Sjfv *********************************************************************/ 283280182Sjfv 284280182Sjfvstatic int 285280182Sjfvixv_attach(device_t dev) 286280182Sjfv{ 287280182Sjfv struct adapter *adapter; 288280182Sjfv struct ixgbe_hw *hw; 289280182Sjfv int error = 0; 290280182Sjfv 291280182Sjfv INIT_DEBUGOUT("ixv_attach: begin"); 292280182Sjfv 293280182Sjfv /* Allocate, clear, and link in our adapter structure */ 294280182Sjfv adapter = device_get_softc(dev); 295295524Ssbruno adapter->dev = dev; 296280182Sjfv hw = &adapter->hw; 297280182Sjfv 298295524Ssbruno#ifdef DEV_NETMAP 299295524Ssbruno adapter->init_locked = ixv_init_locked; 300295524Ssbruno adapter->stop_locked = ixv_stop; 301295524Ssbruno#endif 302295524Ssbruno 303280182Sjfv /* Core Lock Init*/ 304280182Sjfv IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); 305280182Sjfv 306280182Sjfv /* SYSCTL APIs */ 307280182Sjfv SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 308280182Sjfv SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 309280182Sjfv OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW, 310280182Sjfv adapter, 0, ixv_sysctl_debug, "I", "Debug Info"); 311280182Sjfv 312280182Sjfv SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), 313280182Sjfv SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 314283620Serj OID_AUTO, "enable_aim", CTLFLAG_RW, 315280182Sjfv &ixv_enable_aim, 1, "Interrupt Moderation"); 316280182Sjfv 317280182Sjfv /* Set up the timer callout */ 318280182Sjfv callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); 319280182Sjfv 320280182Sjfv /* Determine hardware revision */ 321280182Sjfv ixv_identify_hardware(adapter); 322280182Sjfv 323280182Sjfv /* Do base PCI setup - map BAR0 */ 324280182Sjfv if (ixv_allocate_pci_resources(adapter)) { 325295524Ssbruno device_printf(dev, "ixv_allocate_pci_resources() failed!\n"); 326280182Sjfv error = ENXIO; 327280182Sjfv goto err_out; 328280182Sjfv } 329280182Sjfv 330294034Ssbruno /* Sysctls for limiting the amount of work done in the taskqueues */ 331294034Ssbruno ixv_set_sysctl_value(adapter, "rx_processing_limit", 332294034Ssbruno "max number of rx packets to process", 333294034Ssbruno &adapter->rx_process_limit, ixv_rx_process_limit); 334294034Ssbruno 335294034Ssbruno ixv_set_sysctl_value(adapter, "tx_processing_limit", 336294034Ssbruno "max number of tx packets to process", 337294034Ssbruno &adapter->tx_process_limit, ixv_tx_process_limit); 338294034Ssbruno 339295008Ssbruno /* Sysctls for limiting the amount of work done in the taskqueues */ 340295008Ssbruno ixv_set_sysctl_value(adapter, "rx_processing_limit", 341295008Ssbruno "max number of rx packets to process", 342295008Ssbruno &adapter->rx_process_limit, ixv_rx_process_limit); 343295008Ssbruno 344295008Ssbruno ixv_set_sysctl_value(adapter, "tx_processing_limit", 345295008Ssbruno "max number of tx packets to process", 346295008Ssbruno &adapter->tx_process_limit, ixv_tx_process_limit); 347295008Ssbruno 348280182Sjfv /* Do descriptor calc and sanity checks */ 349280182Sjfv if (((ixv_txd * sizeof(union ixgbe_adv_tx_desc)) % DBA_ALIGN) != 0 || 350280182Sjfv ixv_txd < MIN_TXD || ixv_txd > MAX_TXD) { 351280182Sjfv device_printf(dev, "TXD config issue, using default!\n"); 352280182Sjfv adapter->num_tx_desc = DEFAULT_TXD; 353280182Sjfv } else 354280182Sjfv adapter->num_tx_desc = ixv_txd; 355280182Sjfv 356280182Sjfv if (((ixv_rxd * sizeof(union ixgbe_adv_rx_desc)) % DBA_ALIGN) != 0 || 357280182Sjfv ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD) { 358280182Sjfv device_printf(dev, "RXD config issue, using default!\n"); 359280182Sjfv adapter->num_rx_desc = DEFAULT_RXD; 360280182Sjfv } else 361280182Sjfv adapter->num_rx_desc = ixv_rxd; 362280182Sjfv 363280182Sjfv /* Allocate our TX/RX Queues */ 364280182Sjfv if (ixgbe_allocate_queues(adapter)) { 365295524Ssbruno device_printf(dev, "ixgbe_allocate_queues() failed!\n"); 366280182Sjfv error = ENOMEM; 367280182Sjfv goto err_out; 368280182Sjfv } 369280182Sjfv 370280182Sjfv /* 371280182Sjfv ** Initialize the shared code: its 372280182Sjfv ** at this point the mac type is set. 373280182Sjfv */ 374280182Sjfv error = ixgbe_init_shared_code(hw); 375280182Sjfv if (error) { 376295524Ssbruno device_printf(dev, "ixgbe_init_shared_code() failed!\n"); 377280182Sjfv error = EIO; 378280182Sjfv goto err_late; 379280182Sjfv } 380280182Sjfv 381280182Sjfv /* Setup the mailbox */ 382280182Sjfv ixgbe_init_mbx_params_vf(hw); 383280182Sjfv 384295524Ssbruno /* Reset mbox api to 1.0 */ 385295524Ssbruno error = ixgbe_reset_hw(hw); 386295524Ssbruno if (error == IXGBE_ERR_RESET_FAILED) 387295524Ssbruno device_printf(dev, "ixgbe_reset_hw() failure: Reset Failed!\n"); 388295524Ssbruno else if (error) 389295524Ssbruno device_printf(dev, "ixgbe_reset_hw() failed with error %d\n", error); 390295524Ssbruno if (error) { 391295524Ssbruno error = EIO; 392295524Ssbruno goto err_late; 393295524Ssbruno } 394280182Sjfv 395295524Ssbruno /* Negotiate mailbox API version */ 396295524Ssbruno error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11); 397295524Ssbruno if (error) { 398295524Ssbruno device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error); 399295524Ssbruno error = EIO; 400295524Ssbruno goto err_late; 401295524Ssbruno } 402295008Ssbruno 403280182Sjfv error = ixgbe_init_hw(hw); 404280182Sjfv if (error) { 405295524Ssbruno device_printf(dev, "ixgbe_init_hw() failed!\n"); 406280182Sjfv error = EIO; 407280182Sjfv goto err_late; 408280182Sjfv } 409280182Sjfv 410280182Sjfv error = ixv_allocate_msix(adapter); 411295524Ssbruno if (error) { 412295524Ssbruno device_printf(dev, "ixv_allocate_msix() failed!\n"); 413280182Sjfv goto err_late; 414295524Ssbruno } 415280182Sjfv 416280182Sjfv /* If no mac address was assigned, make a random one */ 417280182Sjfv if (!ixv_check_ether_addr(hw->mac.addr)) { 418280182Sjfv u8 addr[ETHER_ADDR_LEN]; 419280182Sjfv arc4rand(&addr, sizeof(addr), 0); 420280182Sjfv addr[0] &= 0xFE; 421280182Sjfv addr[0] |= 0x02; 422280182Sjfv bcopy(addr, hw->mac.addr, sizeof(addr)); 423280182Sjfv } 424280182Sjfv 425280182Sjfv /* Setup OS specific network interface */ 426280182Sjfv ixv_setup_interface(dev, adapter); 427280182Sjfv 428280182Sjfv /* Do the stats setup */ 429280182Sjfv ixv_save_stats(adapter); 430280182Sjfv ixv_init_stats(adapter); 431280182Sjfv ixv_add_stats_sysctls(adapter); 432280182Sjfv 433280182Sjfv /* Register for VLAN events */ 434280182Sjfv adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, 435280182Sjfv ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST); 436280182Sjfv adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, 437280182Sjfv ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); 438280182Sjfv 439295008Ssbruno#ifdef DEV_NETMAP 440295008Ssbruno ixgbe_netmap_attach(adapter); 441295008Ssbruno#endif /* DEV_NETMAP */ 442280182Sjfv INIT_DEBUGOUT("ixv_attach: end"); 443280182Sjfv return (0); 444280182Sjfv 445280182Sjfverr_late: 446280182Sjfv ixgbe_free_transmit_structures(adapter); 447280182Sjfv ixgbe_free_receive_structures(adapter); 448280182Sjfverr_out: 449280182Sjfv ixv_free_pci_resources(adapter); 450280182Sjfv return (error); 451280182Sjfv 452280182Sjfv} 453280182Sjfv 454280182Sjfv/********************************************************************* 455280182Sjfv * Device removal routine 456280182Sjfv * 457280182Sjfv * The detach entry point is called when the driver is being removed. 458280182Sjfv * This routine stops the adapter and deallocates all the resources 459280182Sjfv * that were allocated for driver operation. 460280182Sjfv * 461280182Sjfv * return 0 on success, positive on failure 462280182Sjfv *********************************************************************/ 463280182Sjfv 464280182Sjfvstatic int 465280182Sjfvixv_detach(device_t dev) 466280182Sjfv{ 467280182Sjfv struct adapter *adapter = device_get_softc(dev); 468280182Sjfv struct ix_queue *que = adapter->queues; 469280182Sjfv 470280182Sjfv INIT_DEBUGOUT("ixv_detach: begin"); 471280182Sjfv 472280182Sjfv /* Make sure VLANS are not using driver */ 473280182Sjfv if (adapter->ifp->if_vlantrunk != NULL) { 474295524Ssbruno device_printf(dev, "Vlan in use, detach first\n"); 475280182Sjfv return (EBUSY); 476280182Sjfv } 477280182Sjfv 478280182Sjfv IXGBE_CORE_LOCK(adapter); 479280182Sjfv ixv_stop(adapter); 480280182Sjfv IXGBE_CORE_UNLOCK(adapter); 481280182Sjfv 482280182Sjfv for (int i = 0; i < adapter->num_queues; i++, que++) { 483280182Sjfv if (que->tq) { 484280182Sjfv struct tx_ring *txr = que->txr; 485280182Sjfv taskqueue_drain(que->tq, &txr->txq_task); 486280182Sjfv taskqueue_drain(que->tq, &que->que_task); 487280182Sjfv taskqueue_free(que->tq); 488280182Sjfv } 489280182Sjfv } 490280182Sjfv 491280182Sjfv /* Drain the Mailbox(link) queue */ 492280182Sjfv if (adapter->tq) { 493280182Sjfv taskqueue_drain(adapter->tq, &adapter->link_task); 494280182Sjfv taskqueue_free(adapter->tq); 495280182Sjfv } 496280182Sjfv 497280182Sjfv /* Unregister VLAN events */ 498280182Sjfv if (adapter->vlan_attach != NULL) 499280182Sjfv EVENTHANDLER_DEREGISTER(vlan_config, adapter->vlan_attach); 500280182Sjfv if (adapter->vlan_detach != NULL) 501280182Sjfv EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); 502280182Sjfv 503280182Sjfv ether_ifdetach(adapter->ifp); 504280182Sjfv callout_drain(&adapter->timer); 505295008Ssbruno#ifdef DEV_NETMAP 506295008Ssbruno netmap_detach(adapter->ifp); 507295008Ssbruno#endif /* DEV_NETMAP */ 508280182Sjfv ixv_free_pci_resources(adapter); 509280182Sjfv bus_generic_detach(dev); 510280182Sjfv if_free(adapter->ifp); 511280182Sjfv 512280182Sjfv ixgbe_free_transmit_structures(adapter); 513280182Sjfv ixgbe_free_receive_structures(adapter); 514280182Sjfv 515280182Sjfv IXGBE_CORE_LOCK_DESTROY(adapter); 516280182Sjfv return (0); 517280182Sjfv} 518280182Sjfv 519280182Sjfv/********************************************************************* 520280182Sjfv * 521280182Sjfv * Shutdown entry point 522280182Sjfv * 523280182Sjfv **********************************************************************/ 524280182Sjfvstatic int 525280182Sjfvixv_shutdown(device_t dev) 526280182Sjfv{ 527280182Sjfv struct adapter *adapter = device_get_softc(dev); 528280182Sjfv IXGBE_CORE_LOCK(adapter); 529280182Sjfv ixv_stop(adapter); 530280182Sjfv IXGBE_CORE_UNLOCK(adapter); 531280182Sjfv return (0); 532280182Sjfv} 533280182Sjfv 534280182Sjfv 535280182Sjfv/********************************************************************* 536280182Sjfv * Ioctl entry point 537280182Sjfv * 538280182Sjfv * ixv_ioctl is called when the user wants to configure the 539280182Sjfv * interface. 540280182Sjfv * 541280182Sjfv * return 0 on success, positive on failure 542280182Sjfv **********************************************************************/ 543280182Sjfv 544280182Sjfvstatic int 545280182Sjfvixv_ioctl(struct ifnet * ifp, u_long command, caddr_t data) 546280182Sjfv{ 547280182Sjfv struct adapter *adapter = ifp->if_softc; 548280182Sjfv struct ifreq *ifr = (struct ifreq *) data; 549280182Sjfv#if defined(INET) || defined(INET6) 550280182Sjfv struct ifaddr *ifa = (struct ifaddr *) data; 551280182Sjfv bool avoid_reset = FALSE; 552280182Sjfv#endif 553280182Sjfv int error = 0; 554280182Sjfv 555280182Sjfv switch (command) { 556280182Sjfv 557280182Sjfv case SIOCSIFADDR: 558280182Sjfv#ifdef INET 559280182Sjfv if (ifa->ifa_addr->sa_family == AF_INET) 560280182Sjfv avoid_reset = TRUE; 561280182Sjfv#endif 562280182Sjfv#ifdef INET6 563280182Sjfv if (ifa->ifa_addr->sa_family == AF_INET6) 564280182Sjfv avoid_reset = TRUE; 565280182Sjfv#endif 566280182Sjfv#if defined(INET) || defined(INET6) 567280182Sjfv /* 568280182Sjfv ** Calling init results in link renegotiation, 569280182Sjfv ** so we avoid doing it when possible. 570280182Sjfv */ 571280182Sjfv if (avoid_reset) { 572280182Sjfv ifp->if_flags |= IFF_UP; 573280182Sjfv if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) 574280182Sjfv ixv_init(adapter); 575280182Sjfv if (!(ifp->if_flags & IFF_NOARP)) 576280182Sjfv arp_ifinit(ifp, ifa); 577280182Sjfv } else 578280182Sjfv error = ether_ioctl(ifp, command, data); 579280182Sjfv break; 580280182Sjfv#endif 581280182Sjfv case SIOCSIFMTU: 582280182Sjfv IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); 583295524Ssbruno if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR) { 584280182Sjfv error = EINVAL; 585280182Sjfv } else { 586280182Sjfv IXGBE_CORE_LOCK(adapter); 587280182Sjfv ifp->if_mtu = ifr->ifr_mtu; 588280182Sjfv adapter->max_frame_size = 589295524Ssbruno ifp->if_mtu + IXGBE_MTU_HDR; 590280182Sjfv ixv_init_locked(adapter); 591280182Sjfv IXGBE_CORE_UNLOCK(adapter); 592280182Sjfv } 593280182Sjfv break; 594280182Sjfv case SIOCSIFFLAGS: 595280182Sjfv IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)"); 596280182Sjfv IXGBE_CORE_LOCK(adapter); 597280182Sjfv if (ifp->if_flags & IFF_UP) { 598280182Sjfv if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 599280182Sjfv ixv_init_locked(adapter); 600280182Sjfv } else 601280182Sjfv if (ifp->if_drv_flags & IFF_DRV_RUNNING) 602280182Sjfv ixv_stop(adapter); 603280182Sjfv adapter->if_flags = ifp->if_flags; 604280182Sjfv IXGBE_CORE_UNLOCK(adapter); 605280182Sjfv break; 606280182Sjfv case SIOCADDMULTI: 607280182Sjfv case SIOCDELMULTI: 608280182Sjfv IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI"); 609280182Sjfv if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 610280182Sjfv IXGBE_CORE_LOCK(adapter); 611280182Sjfv ixv_disable_intr(adapter); 612280182Sjfv ixv_set_multi(adapter); 613280182Sjfv ixv_enable_intr(adapter); 614280182Sjfv IXGBE_CORE_UNLOCK(adapter); 615280182Sjfv } 616280182Sjfv break; 617280182Sjfv case SIOCSIFMEDIA: 618280182Sjfv case SIOCGIFMEDIA: 619280182Sjfv IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)"); 620280182Sjfv error = ifmedia_ioctl(ifp, ifr, &adapter->media, command); 621280182Sjfv break; 622280182Sjfv case SIOCSIFCAP: 623280182Sjfv { 624280182Sjfv int mask = ifr->ifr_reqcap ^ ifp->if_capenable; 625280182Sjfv IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)"); 626280182Sjfv if (mask & IFCAP_HWCSUM) 627280182Sjfv ifp->if_capenable ^= IFCAP_HWCSUM; 628280182Sjfv if (mask & IFCAP_TSO4) 629280182Sjfv ifp->if_capenable ^= IFCAP_TSO4; 630280182Sjfv if (mask & IFCAP_LRO) 631280182Sjfv ifp->if_capenable ^= IFCAP_LRO; 632280182Sjfv if (mask & IFCAP_VLAN_HWTAGGING) 633280182Sjfv ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; 634280182Sjfv if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 635280182Sjfv IXGBE_CORE_LOCK(adapter); 636280182Sjfv ixv_init_locked(adapter); 637280182Sjfv IXGBE_CORE_UNLOCK(adapter); 638280182Sjfv } 639280182Sjfv VLAN_CAPABILITIES(ifp); 640280182Sjfv break; 641280182Sjfv } 642280182Sjfv 643280182Sjfv default: 644280182Sjfv IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command); 645280182Sjfv error = ether_ioctl(ifp, command, data); 646280182Sjfv break; 647280182Sjfv } 648280182Sjfv 649280182Sjfv return (error); 650280182Sjfv} 651280182Sjfv 652280182Sjfv/********************************************************************* 653280182Sjfv * Init entry point 654280182Sjfv * 655280182Sjfv * This routine is used in two ways. It is used by the stack as 656280182Sjfv * init entry point in network interface structure. It is also used 657280182Sjfv * by the driver as a hw/sw initialization routine to get to a 658280182Sjfv * consistent state. 659280182Sjfv * 660280182Sjfv * return 0 on success, positive on failure 661280182Sjfv **********************************************************************/ 662280182Sjfv#define IXGBE_MHADD_MFS_SHIFT 16 663280182Sjfv 664280182Sjfvstatic void 665280182Sjfvixv_init_locked(struct adapter *adapter) 666280182Sjfv{ 667280182Sjfv struct ifnet *ifp = adapter->ifp; 668280182Sjfv device_t dev = adapter->dev; 669280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 670295524Ssbruno int error = 0; 671280182Sjfv 672295524Ssbruno INIT_DEBUGOUT("ixv_init_locked: begin"); 673280182Sjfv mtx_assert(&adapter->core_mtx, MA_OWNED); 674280182Sjfv hw->adapter_stopped = FALSE; 675280182Sjfv ixgbe_stop_adapter(hw); 676280182Sjfv callout_stop(&adapter->timer); 677280182Sjfv 678280182Sjfv /* reprogram the RAR[0] in case user changed it. */ 679280182Sjfv ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); 680280182Sjfv 681280182Sjfv /* Get the latest mac address, User can use a LAA */ 682280182Sjfv bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr, 683280182Sjfv IXGBE_ETH_LENGTH_OF_ADDRESS); 684280182Sjfv ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1); 685280182Sjfv hw->addr_ctrl.rar_used_count = 1; 686280182Sjfv 687280182Sjfv /* Prepare transmit descriptors and buffers */ 688280182Sjfv if (ixgbe_setup_transmit_structures(adapter)) { 689295524Ssbruno device_printf(dev, "Could not setup transmit structures\n"); 690280182Sjfv ixv_stop(adapter); 691280182Sjfv return; 692280182Sjfv } 693280182Sjfv 694295524Ssbruno /* Reset VF and renegotiate mailbox API version */ 695280182Sjfv ixgbe_reset_hw(hw); 696295524Ssbruno error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11); 697295524Ssbruno if (error) 698295524Ssbruno device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error); 699295524Ssbruno 700280182Sjfv ixv_initialize_transmit_units(adapter); 701280182Sjfv 702280182Sjfv /* Setup Multicast table */ 703280182Sjfv ixv_set_multi(adapter); 704280182Sjfv 705280182Sjfv /* 706280182Sjfv ** Determine the correct mbuf pool 707280182Sjfv ** for doing jumbo/headersplit 708280182Sjfv */ 709280182Sjfv if (ifp->if_mtu > ETHERMTU) 710280182Sjfv adapter->rx_mbuf_sz = MJUMPAGESIZE; 711280182Sjfv else 712280182Sjfv adapter->rx_mbuf_sz = MCLBYTES; 713280182Sjfv 714280182Sjfv /* Prepare receive descriptors and buffers */ 715280182Sjfv if (ixgbe_setup_receive_structures(adapter)) { 716295524Ssbruno device_printf(dev, "Could not setup receive structures\n"); 717280182Sjfv ixv_stop(adapter); 718280182Sjfv return; 719280182Sjfv } 720280182Sjfv 721280182Sjfv /* Configure RX settings */ 722280182Sjfv ixv_initialize_receive_units(adapter); 723280182Sjfv 724280182Sjfv /* Set the various hardware offload abilities */ 725280182Sjfv ifp->if_hwassist = 0; 726280182Sjfv if (ifp->if_capenable & IFCAP_TSO4) 727280182Sjfv ifp->if_hwassist |= CSUM_TSO; 728280182Sjfv if (ifp->if_capenable & IFCAP_TXCSUM) { 729280182Sjfv ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); 730280182Sjfv#if __FreeBSD_version >= 800000 731280182Sjfv ifp->if_hwassist |= CSUM_SCTP; 732280182Sjfv#endif 733280182Sjfv } 734280182Sjfv 735280182Sjfv /* Set up VLAN offload and filter */ 736280182Sjfv ixv_setup_vlan_support(adapter); 737280182Sjfv 738280182Sjfv /* Set up MSI/X routing */ 739280182Sjfv ixv_configure_ivars(adapter); 740280182Sjfv 741280182Sjfv /* Set up auto-mask */ 742280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, IXGBE_EICS_RTX_QUEUE); 743280182Sjfv 744280182Sjfv /* Set moderation on the Link interrupt */ 745280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR); 746280182Sjfv 747280182Sjfv /* Stats init */ 748280182Sjfv ixv_init_stats(adapter); 749280182Sjfv 750280182Sjfv /* Config/Enable Link */ 751280182Sjfv ixv_config_link(adapter); 752280182Sjfv 753295524Ssbruno /* Start watchdog */ 754295524Ssbruno callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); 755295524Ssbruno 756280182Sjfv /* And now turn on interrupts */ 757280182Sjfv ixv_enable_intr(adapter); 758280182Sjfv 759280182Sjfv /* Now inform the stack we're ready */ 760280182Sjfv ifp->if_drv_flags |= IFF_DRV_RUNNING; 761280182Sjfv ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 762280182Sjfv 763280182Sjfv return; 764280182Sjfv} 765280182Sjfv 766280182Sjfvstatic void 767280182Sjfvixv_init(void *arg) 768280182Sjfv{ 769280182Sjfv struct adapter *adapter = arg; 770280182Sjfv 771280182Sjfv IXGBE_CORE_LOCK(adapter); 772280182Sjfv ixv_init_locked(adapter); 773280182Sjfv IXGBE_CORE_UNLOCK(adapter); 774280182Sjfv return; 775280182Sjfv} 776280182Sjfv 777280182Sjfv 778280182Sjfv/* 779280182Sjfv** 780280182Sjfv** MSIX Interrupt Handlers and Tasklets 781280182Sjfv** 782280182Sjfv*/ 783280182Sjfv 784280182Sjfvstatic inline void 785280182Sjfvixv_enable_queue(struct adapter *adapter, u32 vector) 786280182Sjfv{ 787280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 788280182Sjfv u32 queue = 1 << vector; 789280182Sjfv u32 mask; 790280182Sjfv 791280182Sjfv mask = (IXGBE_EIMS_RTX_QUEUE & queue); 792280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); 793280182Sjfv} 794280182Sjfv 795280182Sjfvstatic inline void 796280182Sjfvixv_disable_queue(struct adapter *adapter, u32 vector) 797280182Sjfv{ 798280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 799280182Sjfv u64 queue = (u64)(1 << vector); 800280182Sjfv u32 mask; 801280182Sjfv 802280182Sjfv mask = (IXGBE_EIMS_RTX_QUEUE & queue); 803280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEIMC, mask); 804280182Sjfv} 805280182Sjfv 806280182Sjfvstatic inline void 807280182Sjfvixv_rearm_queues(struct adapter *adapter, u64 queues) 808280182Sjfv{ 809280182Sjfv u32 mask = (IXGBE_EIMS_RTX_QUEUE & queues); 810280182Sjfv IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEICS, mask); 811280182Sjfv} 812280182Sjfv 813280182Sjfv 814280182Sjfvstatic void 815280182Sjfvixv_handle_que(void *context, int pending) 816280182Sjfv{ 817280182Sjfv struct ix_queue *que = context; 818280182Sjfv struct adapter *adapter = que->adapter; 819280182Sjfv struct tx_ring *txr = que->txr; 820280182Sjfv struct ifnet *ifp = adapter->ifp; 821280182Sjfv bool more; 822280182Sjfv 823280182Sjfv if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 824280182Sjfv more = ixgbe_rxeof(que); 825280182Sjfv IXGBE_TX_LOCK(txr); 826280182Sjfv ixgbe_txeof(txr); 827280182Sjfv#if __FreeBSD_version >= 800000 828280182Sjfv if (!drbr_empty(ifp, txr->br)) 829280182Sjfv ixgbe_mq_start_locked(ifp, txr); 830280182Sjfv#else 831280182Sjfv if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 832280182Sjfv ixgbe_start_locked(txr, ifp); 833280182Sjfv#endif 834280182Sjfv IXGBE_TX_UNLOCK(txr); 835280182Sjfv if (more) { 836280182Sjfv taskqueue_enqueue(que->tq, &que->que_task); 837280182Sjfv return; 838280182Sjfv } 839280182Sjfv } 840280182Sjfv 841280182Sjfv /* Reenable this interrupt */ 842280182Sjfv ixv_enable_queue(adapter, que->msix); 843280182Sjfv return; 844280182Sjfv} 845280182Sjfv 846280182Sjfv/********************************************************************* 847280182Sjfv * 848280182Sjfv * MSI Queue Interrupt Service routine 849280182Sjfv * 850280182Sjfv **********************************************************************/ 851280182Sjfvvoid 852280182Sjfvixv_msix_que(void *arg) 853280182Sjfv{ 854280182Sjfv struct ix_queue *que = arg; 855280182Sjfv struct adapter *adapter = que->adapter; 856280182Sjfv struct ifnet *ifp = adapter->ifp; 857280182Sjfv struct tx_ring *txr = que->txr; 858280182Sjfv struct rx_ring *rxr = que->rxr; 859280182Sjfv bool more; 860280182Sjfv u32 newitr = 0; 861280182Sjfv 862280182Sjfv ixv_disable_queue(adapter, que->msix); 863280182Sjfv ++que->irqs; 864280182Sjfv 865280182Sjfv more = ixgbe_rxeof(que); 866280182Sjfv 867280182Sjfv IXGBE_TX_LOCK(txr); 868280182Sjfv ixgbe_txeof(txr); 869280182Sjfv /* 870280182Sjfv ** Make certain that if the stack 871280182Sjfv ** has anything queued the task gets 872280182Sjfv ** scheduled to handle it. 873280182Sjfv */ 874280182Sjfv#ifdef IXGBE_LEGACY_TX 875280182Sjfv if (!IFQ_DRV_IS_EMPTY(&adapter->ifp->if_snd)) 876280182Sjfv ixgbe_start_locked(txr, ifp); 877280182Sjfv#else 878280182Sjfv if (!drbr_empty(adapter->ifp, txr->br)) 879280182Sjfv ixgbe_mq_start_locked(ifp, txr); 880280182Sjfv#endif 881280182Sjfv IXGBE_TX_UNLOCK(txr); 882280182Sjfv 883280182Sjfv /* Do AIM now? */ 884280182Sjfv 885280182Sjfv if (ixv_enable_aim == FALSE) 886280182Sjfv goto no_calc; 887280182Sjfv /* 888280182Sjfv ** Do Adaptive Interrupt Moderation: 889280182Sjfv ** - Write out last calculated setting 890280182Sjfv ** - Calculate based on average size over 891280182Sjfv ** the last interval. 892280182Sjfv */ 893280182Sjfv if (que->eitr_setting) 894280182Sjfv IXGBE_WRITE_REG(&adapter->hw, 895280182Sjfv IXGBE_VTEITR(que->msix), 896280182Sjfv que->eitr_setting); 897280182Sjfv 898280182Sjfv que->eitr_setting = 0; 899280182Sjfv 900280182Sjfv /* Idle, do nothing */ 901280182Sjfv if ((txr->bytes == 0) && (rxr->bytes == 0)) 902280182Sjfv goto no_calc; 903280182Sjfv 904280182Sjfv if ((txr->bytes) && (txr->packets)) 905280182Sjfv newitr = txr->bytes/txr->packets; 906280182Sjfv if ((rxr->bytes) && (rxr->packets)) 907280182Sjfv newitr = max(newitr, 908280182Sjfv (rxr->bytes / rxr->packets)); 909280182Sjfv newitr += 24; /* account for hardware frame, crc */ 910280182Sjfv 911280182Sjfv /* set an upper boundary */ 912280182Sjfv newitr = min(newitr, 3000); 913280182Sjfv 914280182Sjfv /* Be nice to the mid range */ 915280182Sjfv if ((newitr > 300) && (newitr < 1200)) 916280182Sjfv newitr = (newitr / 3); 917280182Sjfv else 918280182Sjfv newitr = (newitr / 2); 919280182Sjfv 920280182Sjfv newitr |= newitr << 16; 921280182Sjfv 922280182Sjfv /* save for next interrupt */ 923280182Sjfv que->eitr_setting = newitr; 924280182Sjfv 925280182Sjfv /* Reset state */ 926280182Sjfv txr->bytes = 0; 927280182Sjfv txr->packets = 0; 928280182Sjfv rxr->bytes = 0; 929280182Sjfv rxr->packets = 0; 930280182Sjfv 931280182Sjfvno_calc: 932280182Sjfv if (more) 933280182Sjfv taskqueue_enqueue(que->tq, &que->que_task); 934280182Sjfv else /* Reenable this interrupt */ 935280182Sjfv ixv_enable_queue(adapter, que->msix); 936280182Sjfv return; 937280182Sjfv} 938280182Sjfv 939280182Sjfvstatic void 940280182Sjfvixv_msix_mbx(void *arg) 941280182Sjfv{ 942280182Sjfv struct adapter *adapter = arg; 943280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 944280182Sjfv u32 reg; 945280182Sjfv 946283620Serj ++adapter->link_irq; 947280182Sjfv 948280182Sjfv /* First get the cause */ 949280182Sjfv reg = IXGBE_READ_REG(hw, IXGBE_VTEICS); 950280182Sjfv /* Clear interrupt with write */ 951280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEICR, reg); 952280182Sjfv 953280182Sjfv /* Link status change */ 954280182Sjfv if (reg & IXGBE_EICR_LSC) 955280182Sjfv taskqueue_enqueue(adapter->tq, &adapter->link_task); 956280182Sjfv 957280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, IXGBE_EIMS_OTHER); 958280182Sjfv return; 959280182Sjfv} 960280182Sjfv 961280182Sjfv/********************************************************************* 962280182Sjfv * 963280182Sjfv * Media Ioctl callback 964280182Sjfv * 965280182Sjfv * This routine is called whenever the user queries the status of 966280182Sjfv * the interface using ifconfig. 967280182Sjfv * 968280182Sjfv **********************************************************************/ 969280182Sjfvstatic void 970280182Sjfvixv_media_status(struct ifnet * ifp, struct ifmediareq * ifmr) 971280182Sjfv{ 972280182Sjfv struct adapter *adapter = ifp->if_softc; 973280182Sjfv 974280182Sjfv INIT_DEBUGOUT("ixv_media_status: begin"); 975280182Sjfv IXGBE_CORE_LOCK(adapter); 976280182Sjfv ixv_update_link_status(adapter); 977280182Sjfv 978280182Sjfv ifmr->ifm_status = IFM_AVALID; 979280182Sjfv ifmr->ifm_active = IFM_ETHER; 980280182Sjfv 981280182Sjfv if (!adapter->link_active) { 982280182Sjfv IXGBE_CORE_UNLOCK(adapter); 983280182Sjfv return; 984280182Sjfv } 985280182Sjfv 986280182Sjfv ifmr->ifm_status |= IFM_ACTIVE; 987280182Sjfv 988280182Sjfv switch (adapter->link_speed) { 989280182Sjfv case IXGBE_LINK_SPEED_1GB_FULL: 990280182Sjfv ifmr->ifm_active |= IFM_1000_T | IFM_FDX; 991280182Sjfv break; 992280182Sjfv case IXGBE_LINK_SPEED_10GB_FULL: 993280182Sjfv ifmr->ifm_active |= IFM_FDX; 994280182Sjfv break; 995280182Sjfv } 996280182Sjfv 997280182Sjfv IXGBE_CORE_UNLOCK(adapter); 998280182Sjfv 999280182Sjfv return; 1000280182Sjfv} 1001280182Sjfv 1002280182Sjfv/********************************************************************* 1003280182Sjfv * 1004280182Sjfv * Media Ioctl callback 1005280182Sjfv * 1006280182Sjfv * This routine is called when the user changes speed/duplex using 1007280182Sjfv * media/mediopt option with ifconfig. 1008280182Sjfv * 1009280182Sjfv **********************************************************************/ 1010280182Sjfvstatic int 1011280182Sjfvixv_media_change(struct ifnet * ifp) 1012280182Sjfv{ 1013280182Sjfv struct adapter *adapter = ifp->if_softc; 1014280182Sjfv struct ifmedia *ifm = &adapter->media; 1015280182Sjfv 1016280182Sjfv INIT_DEBUGOUT("ixv_media_change: begin"); 1017280182Sjfv 1018280182Sjfv if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) 1019280182Sjfv return (EINVAL); 1020280182Sjfv 1021280182Sjfv switch (IFM_SUBTYPE(ifm->ifm_media)) { 1022280182Sjfv case IFM_AUTO: 1023280182Sjfv break; 1024280182Sjfv default: 1025280182Sjfv device_printf(adapter->dev, "Only auto media type\n"); 1026280182Sjfv return (EINVAL); 1027280182Sjfv } 1028280182Sjfv 1029280182Sjfv return (0); 1030280182Sjfv} 1031280182Sjfv 1032280182Sjfv 1033280182Sjfv/********************************************************************* 1034280182Sjfv * Multicast Update 1035280182Sjfv * 1036280182Sjfv * This routine is called whenever multicast address list is updated. 1037280182Sjfv * 1038280182Sjfv **********************************************************************/ 1039280182Sjfv#define IXGBE_RAR_ENTRIES 16 1040280182Sjfv 1041280182Sjfvstatic void 1042280182Sjfvixv_set_multi(struct adapter *adapter) 1043280182Sjfv{ 1044280182Sjfv u8 mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS]; 1045280182Sjfv u8 *update_ptr; 1046280182Sjfv struct ifmultiaddr *ifma; 1047280182Sjfv int mcnt = 0; 1048280182Sjfv struct ifnet *ifp = adapter->ifp; 1049280182Sjfv 1050280182Sjfv IOCTL_DEBUGOUT("ixv_set_multi: begin"); 1051280182Sjfv 1052280182Sjfv#if __FreeBSD_version < 800000 1053280182Sjfv IF_ADDR_LOCK(ifp); 1054280182Sjfv#else 1055280182Sjfv if_maddr_rlock(ifp); 1056280182Sjfv#endif 1057280182Sjfv TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1058280182Sjfv if (ifma->ifma_addr->sa_family != AF_LINK) 1059280182Sjfv continue; 1060280182Sjfv bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), 1061280182Sjfv &mta[mcnt * IXGBE_ETH_LENGTH_OF_ADDRESS], 1062280182Sjfv IXGBE_ETH_LENGTH_OF_ADDRESS); 1063280182Sjfv mcnt++; 1064280182Sjfv } 1065280182Sjfv#if __FreeBSD_version < 800000 1066280182Sjfv IF_ADDR_UNLOCK(ifp); 1067280182Sjfv#else 1068280182Sjfv if_maddr_runlock(ifp); 1069280182Sjfv#endif 1070280182Sjfv 1071280182Sjfv update_ptr = mta; 1072280182Sjfv 1073280182Sjfv ixgbe_update_mc_addr_list(&adapter->hw, 1074280182Sjfv update_ptr, mcnt, ixv_mc_array_itr, TRUE); 1075280182Sjfv 1076280182Sjfv return; 1077280182Sjfv} 1078280182Sjfv 1079280182Sjfv/* 1080280182Sjfv * This is an iterator function now needed by the multicast 1081280182Sjfv * shared code. It simply feeds the shared code routine the 1082280182Sjfv * addresses in the array of ixv_set_multi() one by one. 1083280182Sjfv */ 1084280182Sjfvstatic u8 * 1085280182Sjfvixv_mc_array_itr(struct ixgbe_hw *hw, u8 **update_ptr, u32 *vmdq) 1086280182Sjfv{ 1087280182Sjfv u8 *addr = *update_ptr; 1088280182Sjfv u8 *newptr; 1089280182Sjfv *vmdq = 0; 1090280182Sjfv 1091280182Sjfv newptr = addr + IXGBE_ETH_LENGTH_OF_ADDRESS; 1092280182Sjfv *update_ptr = newptr; 1093280182Sjfv return addr; 1094280182Sjfv} 1095280182Sjfv 1096280182Sjfv/********************************************************************* 1097280182Sjfv * Timer routine 1098280182Sjfv * 1099280182Sjfv * This routine checks for link status,updates statistics, 1100280182Sjfv * and runs the watchdog check. 1101280182Sjfv * 1102280182Sjfv **********************************************************************/ 1103280182Sjfv 1104280182Sjfvstatic void 1105280182Sjfvixv_local_timer(void *arg) 1106280182Sjfv{ 1107280182Sjfv struct adapter *adapter = arg; 1108280182Sjfv device_t dev = adapter->dev; 1109280182Sjfv struct ix_queue *que = adapter->queues; 1110280182Sjfv u64 queues = 0; 1111280182Sjfv int hung = 0; 1112280182Sjfv 1113280182Sjfv mtx_assert(&adapter->core_mtx, MA_OWNED); 1114280182Sjfv 1115280182Sjfv ixv_update_link_status(adapter); 1116280182Sjfv 1117280182Sjfv /* Stats Update */ 1118280182Sjfv ixv_update_stats(adapter); 1119280182Sjfv 1120280182Sjfv /* 1121280182Sjfv ** Check the TX queues status 1122280182Sjfv ** - mark hung queues so we don't schedule on them 1123280182Sjfv ** - watchdog only if all queues show hung 1124280182Sjfv */ 1125280182Sjfv for (int i = 0; i < adapter->num_queues; i++, que++) { 1126280182Sjfv /* Keep track of queues with work for soft irq */ 1127280182Sjfv if (que->txr->busy) 1128280182Sjfv queues |= ((u64)1 << que->me); 1129280182Sjfv /* 1130280182Sjfv ** Each time txeof runs without cleaning, but there 1131280182Sjfv ** are uncleaned descriptors it increments busy. If 1132280182Sjfv ** we get to the MAX we declare it hung. 1133280182Sjfv */ 1134280182Sjfv if (que->busy == IXGBE_QUEUE_HUNG) { 1135280182Sjfv ++hung; 1136280182Sjfv /* Mark the queue as inactive */ 1137280182Sjfv adapter->active_queues &= ~((u64)1 << que->me); 1138280182Sjfv continue; 1139280182Sjfv } else { 1140280182Sjfv /* Check if we've come back from hung */ 1141280182Sjfv if ((adapter->active_queues & ((u64)1 << que->me)) == 0) 1142280182Sjfv adapter->active_queues |= ((u64)1 << que->me); 1143280182Sjfv } 1144280182Sjfv if (que->busy >= IXGBE_MAX_TX_BUSY) { 1145280182Sjfv device_printf(dev,"Warning queue %d " 1146280182Sjfv "appears to be hung!\n", i); 1147280182Sjfv que->txr->busy = IXGBE_QUEUE_HUNG; 1148280182Sjfv ++hung; 1149280182Sjfv } 1150280182Sjfv 1151280182Sjfv } 1152280182Sjfv 1153280182Sjfv /* Only truely watchdog if all queues show hung */ 1154280182Sjfv if (hung == adapter->num_queues) 1155280182Sjfv goto watchdog; 1156280182Sjfv else if (queues != 0) { /* Force an IRQ on queues with work */ 1157280182Sjfv ixv_rearm_queues(adapter, queues); 1158280182Sjfv } 1159280182Sjfv 1160280182Sjfv callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); 1161280182Sjfv return; 1162280182Sjfv 1163280182Sjfvwatchdog: 1164280182Sjfv device_printf(adapter->dev, "Watchdog timeout -- resetting\n"); 1165280182Sjfv adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1166280182Sjfv adapter->watchdog_events++; 1167280182Sjfv ixv_init_locked(adapter); 1168280182Sjfv} 1169280182Sjfv 1170280182Sjfv/* 1171280182Sjfv** Note: this routine updates the OS on the link state 1172280182Sjfv** the real check of the hardware only happens with 1173280182Sjfv** a link interrupt. 1174280182Sjfv*/ 1175280182Sjfvstatic void 1176280182Sjfvixv_update_link_status(struct adapter *adapter) 1177280182Sjfv{ 1178280182Sjfv struct ifnet *ifp = adapter->ifp; 1179280182Sjfv device_t dev = adapter->dev; 1180280182Sjfv 1181280182Sjfv if (adapter->link_up){ 1182280182Sjfv if (adapter->link_active == FALSE) { 1183280182Sjfv if (bootverbose) 1184280182Sjfv device_printf(dev,"Link is up %d Gbps %s \n", 1185280182Sjfv ((adapter->link_speed == 128)? 10:1), 1186280182Sjfv "Full Duplex"); 1187280182Sjfv adapter->link_active = TRUE; 1188280182Sjfv if_link_state_change(ifp, LINK_STATE_UP); 1189280182Sjfv } 1190280182Sjfv } else { /* Link down */ 1191280182Sjfv if (adapter->link_active == TRUE) { 1192280182Sjfv if (bootverbose) 1193280182Sjfv device_printf(dev,"Link is Down\n"); 1194280182Sjfv if_link_state_change(ifp, LINK_STATE_DOWN); 1195280182Sjfv adapter->link_active = FALSE; 1196280182Sjfv } 1197280182Sjfv } 1198280182Sjfv 1199280182Sjfv return; 1200280182Sjfv} 1201280182Sjfv 1202280182Sjfv 1203280182Sjfv/********************************************************************* 1204280182Sjfv * 1205280182Sjfv * This routine disables all traffic on the adapter by issuing a 1206280182Sjfv * global reset on the MAC and deallocates TX/RX buffers. 1207280182Sjfv * 1208280182Sjfv **********************************************************************/ 1209280182Sjfv 1210280182Sjfvstatic void 1211280182Sjfvixv_stop(void *arg) 1212280182Sjfv{ 1213280182Sjfv struct ifnet *ifp; 1214280182Sjfv struct adapter *adapter = arg; 1215280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1216280182Sjfv ifp = adapter->ifp; 1217280182Sjfv 1218280182Sjfv mtx_assert(&adapter->core_mtx, MA_OWNED); 1219280182Sjfv 1220280182Sjfv INIT_DEBUGOUT("ixv_stop: begin\n"); 1221280182Sjfv ixv_disable_intr(adapter); 1222280182Sjfv 1223280182Sjfv /* Tell the stack that the interface is no longer active */ 1224280182Sjfv ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 1225280182Sjfv 1226280182Sjfv ixgbe_reset_hw(hw); 1227280182Sjfv adapter->hw.adapter_stopped = FALSE; 1228280182Sjfv ixgbe_stop_adapter(hw); 1229280182Sjfv callout_stop(&adapter->timer); 1230280182Sjfv 1231280182Sjfv /* reprogram the RAR[0] in case user changed it. */ 1232280182Sjfv ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); 1233280182Sjfv 1234280182Sjfv return; 1235280182Sjfv} 1236280182Sjfv 1237280182Sjfv 1238280182Sjfv/********************************************************************* 1239280182Sjfv * 1240280182Sjfv * Determine hardware revision. 1241280182Sjfv * 1242280182Sjfv **********************************************************************/ 1243280182Sjfvstatic void 1244280182Sjfvixv_identify_hardware(struct adapter *adapter) 1245280182Sjfv{ 1246280182Sjfv device_t dev = adapter->dev; 1247280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1248280182Sjfv 1249280182Sjfv /* 1250280182Sjfv ** Make sure BUSMASTER is set, on a VM under 1251280182Sjfv ** KVM it may not be and will break things. 1252280182Sjfv */ 1253280182Sjfv pci_enable_busmaster(dev); 1254280182Sjfv 1255280182Sjfv /* Save off the information about this board */ 1256280182Sjfv hw->vendor_id = pci_get_vendor(dev); 1257280182Sjfv hw->device_id = pci_get_device(dev); 1258280182Sjfv hw->revision_id = pci_read_config(dev, PCIR_REVID, 1); 1259280182Sjfv hw->subsystem_vendor_id = 1260280182Sjfv pci_read_config(dev, PCIR_SUBVEND_0, 2); 1261280182Sjfv hw->subsystem_device_id = 1262280182Sjfv pci_read_config(dev, PCIR_SUBDEV_0, 2); 1263280182Sjfv 1264280182Sjfv /* We need this to determine device-specific things */ 1265280182Sjfv ixgbe_set_mac_type(hw); 1266280182Sjfv 1267280182Sjfv /* Set the right number of segments */ 1268280182Sjfv adapter->num_segs = IXGBE_82599_SCATTER; 1269280182Sjfv 1270280182Sjfv return; 1271280182Sjfv} 1272280182Sjfv 1273280182Sjfv/********************************************************************* 1274280182Sjfv * 1275280182Sjfv * Setup MSIX Interrupt resources and handlers 1276280182Sjfv * 1277280182Sjfv **********************************************************************/ 1278280182Sjfvstatic int 1279280182Sjfvixv_allocate_msix(struct adapter *adapter) 1280280182Sjfv{ 1281280182Sjfv device_t dev = adapter->dev; 1282280182Sjfv struct ix_queue *que = adapter->queues; 1283280182Sjfv struct tx_ring *txr = adapter->tx_rings; 1284280182Sjfv int error, rid, vector = 0; 1285280182Sjfv 1286280182Sjfv for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) { 1287280182Sjfv rid = vector + 1; 1288280182Sjfv que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 1289280182Sjfv RF_SHAREABLE | RF_ACTIVE); 1290280182Sjfv if (que->res == NULL) { 1291280182Sjfv device_printf(dev,"Unable to allocate" 1292280182Sjfv " bus resource: que interrupt [%d]\n", vector); 1293280182Sjfv return (ENXIO); 1294280182Sjfv } 1295280182Sjfv /* Set the handler function */ 1296280182Sjfv error = bus_setup_intr(dev, que->res, 1297280182Sjfv INTR_TYPE_NET | INTR_MPSAFE, NULL, 1298280182Sjfv ixv_msix_que, que, &que->tag); 1299280182Sjfv if (error) { 1300280182Sjfv que->res = NULL; 1301280182Sjfv device_printf(dev, "Failed to register QUE handler"); 1302280182Sjfv return (error); 1303280182Sjfv } 1304280182Sjfv#if __FreeBSD_version >= 800504 1305280182Sjfv bus_describe_intr(dev, que->res, que->tag, "que %d", i); 1306280182Sjfv#endif 1307280182Sjfv que->msix = vector; 1308280182Sjfv adapter->active_queues |= (u64)(1 << que->msix); 1309280182Sjfv /* 1310280182Sjfv ** Bind the msix vector, and thus the 1311280182Sjfv ** ring to the corresponding cpu. 1312280182Sjfv */ 1313280182Sjfv if (adapter->num_queues > 1) 1314280182Sjfv bus_bind_intr(dev, que->res, i); 1315280182Sjfv TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr); 1316280182Sjfv TASK_INIT(&que->que_task, 0, ixv_handle_que, que); 1317280182Sjfv que->tq = taskqueue_create_fast("ixv_que", M_NOWAIT, 1318280182Sjfv taskqueue_thread_enqueue, &que->tq); 1319280182Sjfv taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", 1320280182Sjfv device_get_nameunit(adapter->dev)); 1321280182Sjfv } 1322280182Sjfv 1323280182Sjfv /* and Mailbox */ 1324280182Sjfv rid = vector + 1; 1325280182Sjfv adapter->res = bus_alloc_resource_any(dev, 1326280182Sjfv SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); 1327280182Sjfv if (!adapter->res) { 1328280182Sjfv device_printf(dev,"Unable to allocate" 1329280182Sjfv " bus resource: MBX interrupt [%d]\n", rid); 1330280182Sjfv return (ENXIO); 1331280182Sjfv } 1332280182Sjfv /* Set the mbx handler function */ 1333280182Sjfv error = bus_setup_intr(dev, adapter->res, 1334280182Sjfv INTR_TYPE_NET | INTR_MPSAFE, NULL, 1335280182Sjfv ixv_msix_mbx, adapter, &adapter->tag); 1336280182Sjfv if (error) { 1337280182Sjfv adapter->res = NULL; 1338280182Sjfv device_printf(dev, "Failed to register LINK handler"); 1339280182Sjfv return (error); 1340280182Sjfv } 1341280182Sjfv#if __FreeBSD_version >= 800504 1342280182Sjfv bus_describe_intr(dev, adapter->res, adapter->tag, "mbx"); 1343280182Sjfv#endif 1344280182Sjfv adapter->vector = vector; 1345280182Sjfv /* Tasklets for Mailbox */ 1346280182Sjfv TASK_INIT(&adapter->link_task, 0, ixv_handle_mbx, adapter); 1347280182Sjfv adapter->tq = taskqueue_create_fast("ixv_mbx", M_NOWAIT, 1348280182Sjfv taskqueue_thread_enqueue, &adapter->tq); 1349280182Sjfv taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s mbxq", 1350280182Sjfv device_get_nameunit(adapter->dev)); 1351280182Sjfv /* 1352280182Sjfv ** Due to a broken design QEMU will fail to properly 1353280182Sjfv ** enable the guest for MSIX unless the vectors in 1354280182Sjfv ** the table are all set up, so we must rewrite the 1355280182Sjfv ** ENABLE in the MSIX control register again at this 1356280182Sjfv ** point to cause it to successfully initialize us. 1357280182Sjfv */ 1358280182Sjfv if (adapter->hw.mac.type == ixgbe_mac_82599_vf) { 1359280182Sjfv int msix_ctrl; 1360280182Sjfv pci_find_cap(dev, PCIY_MSIX, &rid); 1361280182Sjfv rid += PCIR_MSIX_CTRL; 1362280182Sjfv msix_ctrl = pci_read_config(dev, rid, 2); 1363280182Sjfv msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE; 1364280182Sjfv pci_write_config(dev, rid, msix_ctrl, 2); 1365280182Sjfv } 1366280182Sjfv 1367280182Sjfv return (0); 1368280182Sjfv} 1369280182Sjfv 1370280182Sjfv/* 1371280182Sjfv * Setup MSIX resources, note that the VF 1372280182Sjfv * device MUST use MSIX, there is no fallback. 1373280182Sjfv */ 1374280182Sjfvstatic int 1375280182Sjfvixv_setup_msix(struct adapter *adapter) 1376280182Sjfv{ 1377280182Sjfv device_t dev = adapter->dev; 1378295008Ssbruno int rid, want, msgs; 1379280182Sjfv 1380280182Sjfv 1381295008Ssbruno /* Must have at least 2 MSIX vectors */ 1382295008Ssbruno msgs = pci_msix_count(dev); 1383295008Ssbruno if (msgs < 2) 1384295008Ssbruno goto out; 1385280182Sjfv rid = PCIR_BAR(3); 1386280182Sjfv adapter->msix_mem = bus_alloc_resource_any(dev, 1387280182Sjfv SYS_RES_MEMORY, &rid, RF_ACTIVE); 1388280182Sjfv if (adapter->msix_mem == NULL) { 1389280182Sjfv device_printf(adapter->dev, 1390280182Sjfv "Unable to map MSIX table \n"); 1391280182Sjfv goto out; 1392280182Sjfv } 1393280182Sjfv 1394280182Sjfv /* 1395295008Ssbruno ** Want vectors for the queues, 1396280182Sjfv ** plus an additional for mailbox. 1397280182Sjfv */ 1398295008Ssbruno want = adapter->num_queues + 1; 1399295008Ssbruno if (want > msgs) { 1400295008Ssbruno want = msgs; 1401295008Ssbruno adapter->num_queues = msgs - 1; 1402295008Ssbruno } else 1403295008Ssbruno msgs = want; 1404295008Ssbruno if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) { 1405280182Sjfv device_printf(adapter->dev, 1406280182Sjfv "Using MSIX interrupts with %d vectors\n", want); 1407280182Sjfv return (want); 1408280182Sjfv } 1409280182Sjfv /* Release in case alloc was insufficient */ 1410280182Sjfv pci_release_msi(dev); 1411280182Sjfvout: 1412280182Sjfv if (adapter->msix_mem != NULL) { 1413280182Sjfv bus_release_resource(dev, SYS_RES_MEMORY, 1414280182Sjfv rid, adapter->msix_mem); 1415280182Sjfv adapter->msix_mem = NULL; 1416280182Sjfv } 1417280182Sjfv device_printf(adapter->dev,"MSIX config error\n"); 1418280182Sjfv return (ENXIO); 1419280182Sjfv} 1420280182Sjfv 1421280182Sjfv 1422280182Sjfvstatic int 1423280182Sjfvixv_allocate_pci_resources(struct adapter *adapter) 1424280182Sjfv{ 1425280182Sjfv int rid; 1426280182Sjfv device_t dev = adapter->dev; 1427280182Sjfv 1428280182Sjfv rid = PCIR_BAR(0); 1429280182Sjfv adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 1430280182Sjfv &rid, RF_ACTIVE); 1431280182Sjfv 1432280182Sjfv if (!(adapter->pci_mem)) { 1433295524Ssbruno device_printf(dev, "Unable to allocate bus resource: memory\n"); 1434280182Sjfv return (ENXIO); 1435280182Sjfv } 1436280182Sjfv 1437280182Sjfv adapter->osdep.mem_bus_space_tag = 1438280182Sjfv rman_get_bustag(adapter->pci_mem); 1439280182Sjfv adapter->osdep.mem_bus_space_handle = 1440280182Sjfv rman_get_bushandle(adapter->pci_mem); 1441295524Ssbruno adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle; 1442280182Sjfv 1443295008Ssbruno /* Pick up the tuneable queues */ 1444295008Ssbruno adapter->num_queues = ixv_num_queues; 1445295524Ssbruno adapter->hw.back = adapter; 1446295008Ssbruno 1447280182Sjfv /* 1448280182Sjfv ** Now setup MSI/X, should 1449280182Sjfv ** return us the number of 1450280182Sjfv ** configured vectors. 1451280182Sjfv */ 1452280182Sjfv adapter->msix = ixv_setup_msix(adapter); 1453280182Sjfv if (adapter->msix == ENXIO) 1454280182Sjfv return (ENXIO); 1455280182Sjfv else 1456280182Sjfv return (0); 1457280182Sjfv} 1458280182Sjfv 1459280182Sjfvstatic void 1460280182Sjfvixv_free_pci_resources(struct adapter * adapter) 1461280182Sjfv{ 1462280182Sjfv struct ix_queue *que = adapter->queues; 1463280182Sjfv device_t dev = adapter->dev; 1464280182Sjfv int rid, memrid; 1465280182Sjfv 1466280182Sjfv memrid = PCIR_BAR(MSIX_82598_BAR); 1467280182Sjfv 1468280182Sjfv /* 1469280182Sjfv ** There is a slight possibility of a failure mode 1470280182Sjfv ** in attach that will result in entering this function 1471280182Sjfv ** before interrupt resources have been initialized, and 1472280182Sjfv ** in that case we do not want to execute the loops below 1473280182Sjfv ** We can detect this reliably by the state of the adapter 1474280182Sjfv ** res pointer. 1475280182Sjfv */ 1476280182Sjfv if (adapter->res == NULL) 1477280182Sjfv goto mem; 1478280182Sjfv 1479280182Sjfv /* 1480280182Sjfv ** Release all msix queue resources: 1481280182Sjfv */ 1482280182Sjfv for (int i = 0; i < adapter->num_queues; i++, que++) { 1483280182Sjfv rid = que->msix + 1; 1484280182Sjfv if (que->tag != NULL) { 1485280182Sjfv bus_teardown_intr(dev, que->res, que->tag); 1486280182Sjfv que->tag = NULL; 1487280182Sjfv } 1488280182Sjfv if (que->res != NULL) 1489280182Sjfv bus_release_resource(dev, SYS_RES_IRQ, rid, que->res); 1490280182Sjfv } 1491280182Sjfv 1492280182Sjfv 1493280182Sjfv /* Clean the Legacy or Link interrupt last */ 1494280182Sjfv if (adapter->vector) /* we are doing MSIX */ 1495280182Sjfv rid = adapter->vector + 1; 1496280182Sjfv else 1497280182Sjfv (adapter->msix != 0) ? (rid = 1):(rid = 0); 1498280182Sjfv 1499280182Sjfv if (adapter->tag != NULL) { 1500280182Sjfv bus_teardown_intr(dev, adapter->res, adapter->tag); 1501280182Sjfv adapter->tag = NULL; 1502280182Sjfv } 1503280182Sjfv if (adapter->res != NULL) 1504280182Sjfv bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res); 1505280182Sjfv 1506280182Sjfvmem: 1507280182Sjfv if (adapter->msix) 1508280182Sjfv pci_release_msi(dev); 1509280182Sjfv 1510280182Sjfv if (adapter->msix_mem != NULL) 1511280182Sjfv bus_release_resource(dev, SYS_RES_MEMORY, 1512280182Sjfv memrid, adapter->msix_mem); 1513280182Sjfv 1514280182Sjfv if (adapter->pci_mem != NULL) 1515280182Sjfv bus_release_resource(dev, SYS_RES_MEMORY, 1516280182Sjfv PCIR_BAR(0), adapter->pci_mem); 1517280182Sjfv 1518280182Sjfv return; 1519280182Sjfv} 1520280182Sjfv 1521280182Sjfv/********************************************************************* 1522280182Sjfv * 1523280182Sjfv * Setup networking device structure and register an interface. 1524280182Sjfv * 1525280182Sjfv **********************************************************************/ 1526280182Sjfvstatic void 1527280182Sjfvixv_setup_interface(device_t dev, struct adapter *adapter) 1528280182Sjfv{ 1529280182Sjfv struct ifnet *ifp; 1530280182Sjfv 1531280182Sjfv INIT_DEBUGOUT("ixv_setup_interface: begin"); 1532280182Sjfv 1533280182Sjfv ifp = adapter->ifp = if_alloc(IFT_ETHER); 1534280182Sjfv if (ifp == NULL) 1535280182Sjfv panic("%s: can not if_alloc()\n", device_get_nameunit(dev)); 1536280182Sjfv if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 1537280182Sjfv ifp->if_baudrate = 1000000000; 1538280182Sjfv ifp->if_init = ixv_init; 1539280182Sjfv ifp->if_softc = adapter; 1540280182Sjfv ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1541280182Sjfv ifp->if_ioctl = ixv_ioctl; 1542280182Sjfv#if __FreeBSD_version >= 800000 1543280182Sjfv ifp->if_transmit = ixgbe_mq_start; 1544280182Sjfv ifp->if_qflush = ixgbe_qflush; 1545280182Sjfv#else 1546280182Sjfv ifp->if_start = ixgbe_start; 1547280182Sjfv#endif 1548280182Sjfv ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2; 1549280182Sjfv 1550280182Sjfv ether_ifattach(ifp, adapter->hw.mac.addr); 1551280182Sjfv 1552280182Sjfv adapter->max_frame_size = 1553295524Ssbruno ifp->if_mtu + IXGBE_MTU_HDR_VLAN; 1554280182Sjfv 1555280182Sjfv /* 1556280182Sjfv * Tell the upper layer(s) we support long frames. 1557280182Sjfv */ 1558280182Sjfv ifp->if_hdrlen = sizeof(struct ether_vlan_header); 1559280182Sjfv 1560280182Sjfv ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM; 1561280182Sjfv ifp->if_capabilities |= IFCAP_JUMBO_MTU; 1562280182Sjfv ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING 1563280182Sjfv | IFCAP_VLAN_HWTSO 1564280182Sjfv | IFCAP_VLAN_MTU; 1565280182Sjfv ifp->if_capabilities |= IFCAP_LRO; 1566280182Sjfv ifp->if_capenable = ifp->if_capabilities; 1567280182Sjfv 1568280182Sjfv /* 1569280182Sjfv * Specify the media types supported by this adapter and register 1570280182Sjfv * callbacks to update media and link information 1571280182Sjfv */ 1572280182Sjfv ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change, 1573280182Sjfv ixv_media_status); 1574280182Sjfv ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); 1575280182Sjfv ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); 1576280182Sjfv 1577280182Sjfv return; 1578280182Sjfv} 1579280182Sjfv 1580280182Sjfvstatic void 1581280182Sjfvixv_config_link(struct adapter *adapter) 1582280182Sjfv{ 1583280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1584295524Ssbruno u32 autoneg; 1585280182Sjfv 1586280182Sjfv if (hw->mac.ops.check_link) 1587295524Ssbruno hw->mac.ops.check_link(hw, &autoneg, 1588280182Sjfv &adapter->link_up, FALSE); 1589280182Sjfv} 1590280182Sjfv 1591280182Sjfv 1592280182Sjfv/********************************************************************* 1593280182Sjfv * 1594280182Sjfv * Enable transmit unit. 1595280182Sjfv * 1596280182Sjfv **********************************************************************/ 1597280182Sjfvstatic void 1598280182Sjfvixv_initialize_transmit_units(struct adapter *adapter) 1599280182Sjfv{ 1600280182Sjfv struct tx_ring *txr = adapter->tx_rings; 1601280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1602280182Sjfv 1603280182Sjfv 1604280182Sjfv for (int i = 0; i < adapter->num_queues; i++, txr++) { 1605280182Sjfv u64 tdba = txr->txdma.dma_paddr; 1606280182Sjfv u32 txctrl, txdctl; 1607280182Sjfv 1608280182Sjfv /* Set WTHRESH to 8, burst writeback */ 1609280182Sjfv txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); 1610280182Sjfv txdctl |= (8 << 16); 1611280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl); 1612280182Sjfv 1613280182Sjfv /* Set the HW Tx Head and Tail indices */ 1614280182Sjfv IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(i), 0); 1615280182Sjfv IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(i), 0); 1616280182Sjfv 1617280182Sjfv /* Set Tx Tail register */ 1618280182Sjfv txr->tail = IXGBE_VFTDT(i); 1619280182Sjfv 1620280182Sjfv /* Set Ring parameters */ 1621280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFTDBAL(i), 1622280182Sjfv (tdba & 0x00000000ffffffffULL)); 1623280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFTDBAH(i), (tdba >> 32)); 1624280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFTDLEN(i), 1625280182Sjfv adapter->num_tx_desc * 1626280182Sjfv sizeof(struct ixgbe_legacy_tx_desc)); 1627280182Sjfv txctrl = IXGBE_READ_REG(hw, IXGBE_VFDCA_TXCTRL(i)); 1628280182Sjfv txctrl &= ~IXGBE_DCA_TXCTRL_DESC_WRO_EN; 1629280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFDCA_TXCTRL(i), txctrl); 1630280182Sjfv 1631280182Sjfv /* Now enable */ 1632280182Sjfv txdctl = IXGBE_READ_REG(hw, IXGBE_VFTXDCTL(i)); 1633280182Sjfv txdctl |= IXGBE_TXDCTL_ENABLE; 1634280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFTXDCTL(i), txdctl); 1635280182Sjfv } 1636280182Sjfv 1637280182Sjfv return; 1638280182Sjfv} 1639280182Sjfv 1640280182Sjfv 1641280182Sjfv/********************************************************************* 1642280182Sjfv * 1643280182Sjfv * Setup receive registers and features. 1644280182Sjfv * 1645280182Sjfv **********************************************************************/ 1646280182Sjfv#define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 1647280182Sjfv 1648280182Sjfvstatic void 1649280182Sjfvixv_initialize_receive_units(struct adapter *adapter) 1650280182Sjfv{ 1651280182Sjfv struct rx_ring *rxr = adapter->rx_rings; 1652280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1653295008Ssbruno struct ifnet *ifp = adapter->ifp; 1654295008Ssbruno u32 bufsz, rxcsum, psrtype; 1655280182Sjfv 1656295008Ssbruno if (ifp->if_mtu > ETHERMTU) 1657280182Sjfv bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; 1658295008Ssbruno else 1659280182Sjfv bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; 1660280182Sjfv 1661295008Ssbruno psrtype = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR | 1662295008Ssbruno IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR | 1663295008Ssbruno IXGBE_PSRTYPE_L2HDR; 1664295008Ssbruno 1665295008Ssbruno IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); 1666295008Ssbruno 1667295524Ssbruno /* Tell PF our max_frame size */ 1668295524Ssbruno ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size); 1669295008Ssbruno 1670280182Sjfv for (int i = 0; i < adapter->num_queues; i++, rxr++) { 1671280182Sjfv u64 rdba = rxr->rxdma.dma_paddr; 1672280182Sjfv u32 reg, rxdctl; 1673280182Sjfv 1674295008Ssbruno /* Disable the queue */ 1675295008Ssbruno rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); 1676295524Ssbruno rxdctl &= ~IXGBE_RXDCTL_ENABLE; 1677295008Ssbruno IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); 1678295008Ssbruno for (int j = 0; j < 10; j++) { 1679295008Ssbruno if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & 1680295008Ssbruno IXGBE_RXDCTL_ENABLE) 1681295008Ssbruno msec_delay(1); 1682295008Ssbruno else 1683295008Ssbruno break; 1684295008Ssbruno } 1685295008Ssbruno wmb(); 1686280182Sjfv /* Setup the Base and Length of the Rx Descriptor Ring */ 1687280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFRDBAL(i), 1688280182Sjfv (rdba & 0x00000000ffffffffULL)); 1689280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(i), 1690280182Sjfv (rdba >> 32)); 1691280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFRDLEN(i), 1692280182Sjfv adapter->num_rx_desc * sizeof(union ixgbe_adv_rx_desc)); 1693280182Sjfv 1694295008Ssbruno /* Reset the ring indices */ 1695295008Ssbruno IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0); 1696295008Ssbruno IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 0); 1697295008Ssbruno 1698280182Sjfv /* Set up the SRRCTL register */ 1699280182Sjfv reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); 1700280182Sjfv reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; 1701280182Sjfv reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; 1702280182Sjfv reg |= bufsz; 1703280182Sjfv reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; 1704280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), reg); 1705280182Sjfv 1706295524Ssbruno /* Capture Rx Tail register */ 1707280182Sjfv rxr->tail = IXGBE_VFRDT(rxr->me); 1708280182Sjfv 1709280182Sjfv /* Do the queue enabling last */ 1710295524Ssbruno rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; 1711280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); 1712280182Sjfv for (int k = 0; k < 10; k++) { 1713280182Sjfv if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & 1714280182Sjfv IXGBE_RXDCTL_ENABLE) 1715280182Sjfv break; 1716280182Sjfv else 1717280182Sjfv msec_delay(1); 1718280182Sjfv } 1719280182Sjfv wmb(); 1720295008Ssbruno 1721295008Ssbruno /* Set the Tail Pointer */ 1722295008Ssbruno#ifdef DEV_NETMAP 1723295008Ssbruno /* 1724295008Ssbruno * In netmap mode, we must preserve the buffers made 1725295008Ssbruno * available to userspace before the if_init() 1726295008Ssbruno * (this is true by default on the TX side, because 1727295008Ssbruno * init makes all buffers available to userspace). 1728295008Ssbruno * 1729295008Ssbruno * netmap_reset() and the device specific routines 1730295008Ssbruno * (e.g. ixgbe_setup_receive_rings()) map these 1731295008Ssbruno * buffers at the end of the NIC ring, so here we 1732295008Ssbruno * must set the RDT (tail) register to make sure 1733295008Ssbruno * they are not overwritten. 1734295008Ssbruno * 1735295008Ssbruno * In this driver the NIC ring starts at RDH = 0, 1736295008Ssbruno * RDT points to the last slot available for reception (?), 1737295008Ssbruno * so RDT = num_rx_desc - 1 means the whole ring is available. 1738295008Ssbruno */ 1739295008Ssbruno if (ifp->if_capenable & IFCAP_NETMAP) { 1740295008Ssbruno struct netmap_adapter *na = NA(adapter->ifp); 1741295008Ssbruno struct netmap_kring *kring = &na->rx_rings[i]; 1742295008Ssbruno int t = na->num_rx_desc - 1 - nm_kr_rxspace(kring); 1743295008Ssbruno 1744295008Ssbruno IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), t); 1745295008Ssbruno } else 1746295008Ssbruno#endif /* DEV_NETMAP */ 1747295008Ssbruno IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), 1748295008Ssbruno adapter->num_rx_desc - 1); 1749280182Sjfv } 1750280182Sjfv 1751280182Sjfv rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); 1752280182Sjfv 1753280182Sjfv if (ifp->if_capenable & IFCAP_RXCSUM) 1754280182Sjfv rxcsum |= IXGBE_RXCSUM_PCSD; 1755280182Sjfv 1756280182Sjfv if (!(rxcsum & IXGBE_RXCSUM_PCSD)) 1757280182Sjfv rxcsum |= IXGBE_RXCSUM_IPPCSE; 1758280182Sjfv 1759280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); 1760280182Sjfv 1761280182Sjfv return; 1762280182Sjfv} 1763280182Sjfv 1764280182Sjfvstatic void 1765280182Sjfvixv_setup_vlan_support(struct adapter *adapter) 1766280182Sjfv{ 1767280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1768280182Sjfv u32 ctrl, vid, vfta, retry; 1769295524Ssbruno struct rx_ring *rxr; 1770280182Sjfv 1771280182Sjfv /* 1772280182Sjfv ** We get here thru init_locked, meaning 1773280182Sjfv ** a soft reset, this has already cleared 1774280182Sjfv ** the VFTA and other state, so if there 1775280182Sjfv ** have been no vlan's registered do nothing. 1776280182Sjfv */ 1777280182Sjfv if (adapter->num_vlans == 0) 1778280182Sjfv return; 1779280182Sjfv 1780280182Sjfv /* Enable the queues */ 1781280182Sjfv for (int i = 0; i < adapter->num_queues; i++) { 1782280182Sjfv ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); 1783280182Sjfv ctrl |= IXGBE_RXDCTL_VME; 1784280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl); 1785295524Ssbruno /* 1786295524Ssbruno * Let Rx path know that it needs to store VLAN tag 1787295524Ssbruno * as part of extra mbuf info. 1788295524Ssbruno */ 1789295524Ssbruno rxr = &adapter->rx_rings[i]; 1790295524Ssbruno rxr->vtag_strip = TRUE; 1791280182Sjfv } 1792280182Sjfv 1793280182Sjfv /* 1794280182Sjfv ** A soft reset zero's out the VFTA, so 1795280182Sjfv ** we need to repopulate it now. 1796280182Sjfv */ 1797280182Sjfv for (int i = 0; i < IXGBE_VFTA_SIZE; i++) { 1798280182Sjfv if (ixv_shadow_vfta[i] == 0) 1799280182Sjfv continue; 1800280182Sjfv vfta = ixv_shadow_vfta[i]; 1801280182Sjfv /* 1802280182Sjfv ** Reconstruct the vlan id's 1803280182Sjfv ** based on the bits set in each 1804280182Sjfv ** of the array ints. 1805280182Sjfv */ 1806295524Ssbruno for (int j = 0; j < 32; j++) { 1807280182Sjfv retry = 0; 1808280182Sjfv if ((vfta & (1 << j)) == 0) 1809280182Sjfv continue; 1810280182Sjfv vid = (i * 32) + j; 1811280182Sjfv /* Call the shared code mailbox routine */ 1812280182Sjfv while (ixgbe_set_vfta(hw, vid, 0, TRUE)) { 1813280182Sjfv if (++retry > 5) 1814280182Sjfv break; 1815280182Sjfv } 1816280182Sjfv } 1817280182Sjfv } 1818280182Sjfv} 1819280182Sjfv 1820280182Sjfv/* 1821280182Sjfv** This routine is run via an vlan config EVENT, 1822280182Sjfv** it enables us to use the HW Filter table since 1823280182Sjfv** we can get the vlan id. This just creates the 1824280182Sjfv** entry in the soft version of the VFTA, init will 1825280182Sjfv** repopulate the real table. 1826280182Sjfv*/ 1827280182Sjfvstatic void 1828280182Sjfvixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) 1829280182Sjfv{ 1830280182Sjfv struct adapter *adapter = ifp->if_softc; 1831280182Sjfv u16 index, bit; 1832280182Sjfv 1833295524Ssbruno if (ifp->if_softc != arg) /* Not our event */ 1834280182Sjfv return; 1835280182Sjfv 1836295524Ssbruno if ((vtag == 0) || (vtag > 4095)) /* Invalid */ 1837280182Sjfv return; 1838280182Sjfv 1839280182Sjfv IXGBE_CORE_LOCK(adapter); 1840280182Sjfv index = (vtag >> 5) & 0x7F; 1841280182Sjfv bit = vtag & 0x1F; 1842280182Sjfv ixv_shadow_vfta[index] |= (1 << bit); 1843280182Sjfv ++adapter->num_vlans; 1844280182Sjfv /* Re-init to load the changes */ 1845280182Sjfv ixv_init_locked(adapter); 1846280182Sjfv IXGBE_CORE_UNLOCK(adapter); 1847280182Sjfv} 1848280182Sjfv 1849280182Sjfv/* 1850280182Sjfv** This routine is run via an vlan 1851280182Sjfv** unconfig EVENT, remove our entry 1852280182Sjfv** in the soft vfta. 1853280182Sjfv*/ 1854280182Sjfvstatic void 1855280182Sjfvixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) 1856280182Sjfv{ 1857280182Sjfv struct adapter *adapter = ifp->if_softc; 1858280182Sjfv u16 index, bit; 1859280182Sjfv 1860280182Sjfv if (ifp->if_softc != arg) 1861280182Sjfv return; 1862280182Sjfv 1863280182Sjfv if ((vtag == 0) || (vtag > 4095)) /* Invalid */ 1864280182Sjfv return; 1865280182Sjfv 1866280182Sjfv IXGBE_CORE_LOCK(adapter); 1867280182Sjfv index = (vtag >> 5) & 0x7F; 1868280182Sjfv bit = vtag & 0x1F; 1869280182Sjfv ixv_shadow_vfta[index] &= ~(1 << bit); 1870280182Sjfv --adapter->num_vlans; 1871280182Sjfv /* Re-init to load the changes */ 1872280182Sjfv ixv_init_locked(adapter); 1873280182Sjfv IXGBE_CORE_UNLOCK(adapter); 1874280182Sjfv} 1875280182Sjfv 1876280182Sjfvstatic void 1877280182Sjfvixv_enable_intr(struct adapter *adapter) 1878280182Sjfv{ 1879280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1880280182Sjfv struct ix_queue *que = adapter->queues; 1881280182Sjfv u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); 1882280182Sjfv 1883280182Sjfv 1884280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); 1885280182Sjfv 1886280182Sjfv mask = IXGBE_EIMS_ENABLE_MASK; 1887280182Sjfv mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC); 1888280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask); 1889280182Sjfv 1890280182Sjfv for (int i = 0; i < adapter->num_queues; i++, que++) 1891280182Sjfv ixv_enable_queue(adapter, que->msix); 1892280182Sjfv 1893280182Sjfv IXGBE_WRITE_FLUSH(hw); 1894280182Sjfv 1895280182Sjfv return; 1896280182Sjfv} 1897280182Sjfv 1898280182Sjfvstatic void 1899280182Sjfvixv_disable_intr(struct adapter *adapter) 1900280182Sjfv{ 1901280182Sjfv IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIAC, 0); 1902280182Sjfv IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEIMC, ~0); 1903280182Sjfv IXGBE_WRITE_FLUSH(&adapter->hw); 1904280182Sjfv return; 1905280182Sjfv} 1906280182Sjfv 1907280182Sjfv/* 1908280182Sjfv** Setup the correct IVAR register for a particular MSIX interrupt 1909280182Sjfv** - entry is the register array entry 1910280182Sjfv** - vector is the MSIX vector for this queue 1911280182Sjfv** - type is RX/TX/MISC 1912280182Sjfv*/ 1913280182Sjfvstatic void 1914280182Sjfvixv_set_ivar(struct adapter *adapter, u8 entry, u8 vector, s8 type) 1915280182Sjfv{ 1916280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1917280182Sjfv u32 ivar, index; 1918280182Sjfv 1919280182Sjfv vector |= IXGBE_IVAR_ALLOC_VAL; 1920280182Sjfv 1921280182Sjfv if (type == -1) { /* MISC IVAR */ 1922280182Sjfv ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR_MISC); 1923280182Sjfv ivar &= ~0xFF; 1924280182Sjfv ivar |= vector; 1925280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTIVAR_MISC, ivar); 1926280182Sjfv } else { /* RX/TX IVARS */ 1927280182Sjfv index = (16 * (entry & 1)) + (8 * type); 1928280182Sjfv ivar = IXGBE_READ_REG(hw, IXGBE_VTIVAR(entry >> 1)); 1929280182Sjfv ivar &= ~(0xFF << index); 1930280182Sjfv ivar |= (vector << index); 1931280182Sjfv IXGBE_WRITE_REG(hw, IXGBE_VTIVAR(entry >> 1), ivar); 1932280182Sjfv } 1933280182Sjfv} 1934280182Sjfv 1935280182Sjfvstatic void 1936280182Sjfvixv_configure_ivars(struct adapter *adapter) 1937280182Sjfv{ 1938280182Sjfv struct ix_queue *que = adapter->queues; 1939280182Sjfv 1940280182Sjfv for (int i = 0; i < adapter->num_queues; i++, que++) { 1941280182Sjfv /* First the RX queue entry */ 1942280182Sjfv ixv_set_ivar(adapter, i, que->msix, 0); 1943280182Sjfv /* ... and the TX */ 1944280182Sjfv ixv_set_ivar(adapter, i, que->msix, 1); 1945280182Sjfv /* Set an initial value in EITR */ 1946280182Sjfv IXGBE_WRITE_REG(&adapter->hw, 1947280182Sjfv IXGBE_VTEITR(que->msix), IXV_EITR_DEFAULT); 1948280182Sjfv } 1949280182Sjfv 1950280182Sjfv /* For the mailbox interrupt */ 1951280182Sjfv ixv_set_ivar(adapter, 1, adapter->vector, -1); 1952280182Sjfv} 1953280182Sjfv 1954280182Sjfv 1955280182Sjfv/* 1956280182Sjfv** Tasklet handler for MSIX MBX interrupts 1957280182Sjfv** - do outside interrupt since it might sleep 1958280182Sjfv*/ 1959280182Sjfvstatic void 1960280182Sjfvixv_handle_mbx(void *context, int pending) 1961280182Sjfv{ 1962280182Sjfv struct adapter *adapter = context; 1963280182Sjfv 1964280182Sjfv ixgbe_check_link(&adapter->hw, 1965280182Sjfv &adapter->link_speed, &adapter->link_up, 0); 1966280182Sjfv ixv_update_link_status(adapter); 1967280182Sjfv} 1968280182Sjfv 1969280182Sjfv/* 1970280182Sjfv** The VF stats registers never have a truely virgin 1971280182Sjfv** starting point, so this routine tries to make an 1972280182Sjfv** artificial one, marking ground zero on attach as 1973280182Sjfv** it were. 1974280182Sjfv*/ 1975280182Sjfvstatic void 1976280182Sjfvixv_save_stats(struct adapter *adapter) 1977280182Sjfv{ 1978280182Sjfv if (adapter->stats.vf.vfgprc || adapter->stats.vf.vfgptc) { 1979280182Sjfv adapter->stats.vf.saved_reset_vfgprc += 1980280182Sjfv adapter->stats.vf.vfgprc - adapter->stats.vf.base_vfgprc; 1981280182Sjfv adapter->stats.vf.saved_reset_vfgptc += 1982280182Sjfv adapter->stats.vf.vfgptc - adapter->stats.vf.base_vfgptc; 1983280182Sjfv adapter->stats.vf.saved_reset_vfgorc += 1984280182Sjfv adapter->stats.vf.vfgorc - adapter->stats.vf.base_vfgorc; 1985280182Sjfv adapter->stats.vf.saved_reset_vfgotc += 1986280182Sjfv adapter->stats.vf.vfgotc - adapter->stats.vf.base_vfgotc; 1987280182Sjfv adapter->stats.vf.saved_reset_vfmprc += 1988280182Sjfv adapter->stats.vf.vfmprc - adapter->stats.vf.base_vfmprc; 1989280182Sjfv } 1990280182Sjfv} 1991280182Sjfv 1992280182Sjfvstatic void 1993280182Sjfvixv_init_stats(struct adapter *adapter) 1994280182Sjfv{ 1995280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 1996280182Sjfv 1997280182Sjfv adapter->stats.vf.last_vfgprc = IXGBE_READ_REG(hw, IXGBE_VFGPRC); 1998280182Sjfv adapter->stats.vf.last_vfgorc = IXGBE_READ_REG(hw, IXGBE_VFGORC_LSB); 1999280182Sjfv adapter->stats.vf.last_vfgorc |= 2000280182Sjfv (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGORC_MSB))) << 32); 2001280182Sjfv 2002280182Sjfv adapter->stats.vf.last_vfgptc = IXGBE_READ_REG(hw, IXGBE_VFGPTC); 2003280182Sjfv adapter->stats.vf.last_vfgotc = IXGBE_READ_REG(hw, IXGBE_VFGOTC_LSB); 2004280182Sjfv adapter->stats.vf.last_vfgotc |= 2005280182Sjfv (((u64)(IXGBE_READ_REG(hw, IXGBE_VFGOTC_MSB))) << 32); 2006280182Sjfv 2007280182Sjfv adapter->stats.vf.last_vfmprc = IXGBE_READ_REG(hw, IXGBE_VFMPRC); 2008280182Sjfv 2009280182Sjfv adapter->stats.vf.base_vfgprc = adapter->stats.vf.last_vfgprc; 2010280182Sjfv adapter->stats.vf.base_vfgorc = adapter->stats.vf.last_vfgorc; 2011280182Sjfv adapter->stats.vf.base_vfgptc = adapter->stats.vf.last_vfgptc; 2012280182Sjfv adapter->stats.vf.base_vfgotc = adapter->stats.vf.last_vfgotc; 2013280182Sjfv adapter->stats.vf.base_vfmprc = adapter->stats.vf.last_vfmprc; 2014280182Sjfv} 2015280182Sjfv 2016280182Sjfv#define UPDATE_STAT_32(reg, last, count) \ 2017280182Sjfv{ \ 2018280182Sjfv u32 current = IXGBE_READ_REG(hw, reg); \ 2019280182Sjfv if (current < last) \ 2020280182Sjfv count += 0x100000000LL; \ 2021280182Sjfv last = current; \ 2022280182Sjfv count &= 0xFFFFFFFF00000000LL; \ 2023280182Sjfv count |= current; \ 2024280182Sjfv} 2025280182Sjfv 2026280182Sjfv#define UPDATE_STAT_36(lsb, msb, last, count) \ 2027280182Sjfv{ \ 2028280182Sjfv u64 cur_lsb = IXGBE_READ_REG(hw, lsb); \ 2029280182Sjfv u64 cur_msb = IXGBE_READ_REG(hw, msb); \ 2030280182Sjfv u64 current = ((cur_msb << 32) | cur_lsb); \ 2031280182Sjfv if (current < last) \ 2032280182Sjfv count += 0x1000000000LL; \ 2033280182Sjfv last = current; \ 2034280182Sjfv count &= 0xFFFFFFF000000000LL; \ 2035280182Sjfv count |= current; \ 2036280182Sjfv} 2037280182Sjfv 2038280182Sjfv/* 2039280182Sjfv** ixv_update_stats - Update the board statistics counters. 2040280182Sjfv*/ 2041280182Sjfvvoid 2042280182Sjfvixv_update_stats(struct adapter *adapter) 2043280182Sjfv{ 2044280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 2045280182Sjfv 2046280182Sjfv UPDATE_STAT_32(IXGBE_VFGPRC, adapter->stats.vf.last_vfgprc, 2047280182Sjfv adapter->stats.vf.vfgprc); 2048280182Sjfv UPDATE_STAT_32(IXGBE_VFGPTC, adapter->stats.vf.last_vfgptc, 2049280182Sjfv adapter->stats.vf.vfgptc); 2050280182Sjfv UPDATE_STAT_36(IXGBE_VFGORC_LSB, IXGBE_VFGORC_MSB, 2051280182Sjfv adapter->stats.vf.last_vfgorc, adapter->stats.vf.vfgorc); 2052280182Sjfv UPDATE_STAT_36(IXGBE_VFGOTC_LSB, IXGBE_VFGOTC_MSB, 2053280182Sjfv adapter->stats.vf.last_vfgotc, adapter->stats.vf.vfgotc); 2054280182Sjfv UPDATE_STAT_32(IXGBE_VFMPRC, adapter->stats.vf.last_vfmprc, 2055280182Sjfv adapter->stats.vf.vfmprc); 2056280182Sjfv} 2057280182Sjfv 2058280182Sjfv/* 2059280182Sjfv * Add statistic sysctls for the VF. 2060280182Sjfv */ 2061280182Sjfvstatic void 2062280182Sjfvixv_add_stats_sysctls(struct adapter *adapter) 2063280182Sjfv{ 2064280182Sjfv device_t dev = adapter->dev; 2065280182Sjfv struct ix_queue *que = &adapter->queues[0]; 2066280182Sjfv struct tx_ring *txr = que->txr; 2067280182Sjfv struct rx_ring *rxr = que->rxr; 2068280182Sjfv 2069280182Sjfv struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); 2070280182Sjfv struct sysctl_oid *tree = device_get_sysctl_tree(dev); 2071280182Sjfv struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree); 2072280182Sjfv struct ixgbevf_hw_stats *stats = &adapter->stats.vf; 2073280182Sjfv 2074280182Sjfv struct sysctl_oid *stat_node, *queue_node; 2075280182Sjfv struct sysctl_oid_list *stat_list, *queue_list; 2076280182Sjfv 2077280182Sjfv /* Driver Statistics */ 2078283620Serj SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped", 2079280182Sjfv CTLFLAG_RD, &adapter->dropped_pkts, 2080280182Sjfv "Driver dropped packets"); 2081283620Serj SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_failed", 2082280182Sjfv CTLFLAG_RD, &adapter->mbuf_defrag_failed, 2083280182Sjfv "m_defrag() failed"); 2084283620Serj SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_events", 2085280182Sjfv CTLFLAG_RD, &adapter->watchdog_events, 2086280182Sjfv "Watchdog timeouts"); 2087280182Sjfv 2088280182Sjfv stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac", 2089280182Sjfv CTLFLAG_RD, NULL, 2090280182Sjfv "VF Statistics (read from HW registers)"); 2091280182Sjfv stat_list = SYSCTL_CHILDREN(stat_node); 2092280182Sjfv 2093280182Sjfv SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_rcvd", 2094280182Sjfv CTLFLAG_RD, &stats->vfgprc, 2095280182Sjfv "Good Packets Received"); 2096280182Sjfv SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_rcvd", 2097280182Sjfv CTLFLAG_RD, &stats->vfgorc, 2098280182Sjfv "Good Octets Received"); 2099280182Sjfv SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_rcvd", 2100280182Sjfv CTLFLAG_RD, &stats->vfmprc, 2101280182Sjfv "Multicast Packets Received"); 2102280182Sjfv SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd", 2103280182Sjfv CTLFLAG_RD, &stats->vfgptc, 2104280182Sjfv "Good Packets Transmitted"); 2105280182Sjfv SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd", 2106280182Sjfv CTLFLAG_RD, &stats->vfgotc, 2107280182Sjfv "Good Octets Transmitted"); 2108280182Sjfv 2109280182Sjfv queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "que", 2110280182Sjfv CTLFLAG_RD, NULL, 2111280182Sjfv "Queue Statistics (collected by SW)"); 2112280182Sjfv queue_list = SYSCTL_CHILDREN(queue_node); 2113280182Sjfv 2114280182Sjfv SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs", 2115280182Sjfv CTLFLAG_RD, &(que->irqs), 2116280182Sjfv "IRQs on queue"); 2117280182Sjfv SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_irqs", 2118280182Sjfv CTLFLAG_RD, &(rxr->rx_irq), 2119280182Sjfv "RX irqs on queue"); 2120280182Sjfv SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets", 2121280182Sjfv CTLFLAG_RD, &(rxr->rx_packets), 2122280182Sjfv "RX packets"); 2123280182Sjfv SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes", 2124280182Sjfv CTLFLAG_RD, &(rxr->rx_bytes), 2125280182Sjfv "RX bytes"); 2126280182Sjfv SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_discarded", 2127280182Sjfv CTLFLAG_RD, &(rxr->rx_discarded), 2128280182Sjfv "Discarded RX packets"); 2129280182Sjfv 2130280182Sjfv SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets", 2131280182Sjfv CTLFLAG_RD, &(txr->total_packets), 2132280182Sjfv "TX Packets"); 2133283620Serj SYSCTL_ADD_UINT(ctx, queue_list, OID_AUTO, "tx_bytes", 2134283620Serj CTLFLAG_RD, &(txr->bytes), 0, 2135280182Sjfv "TX Bytes"); 2136280182Sjfv SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc", 2137280182Sjfv CTLFLAG_RD, &(txr->no_desc_avail), 2138280182Sjfv "# of times not enough descriptors were available during TX"); 2139280182Sjfv} 2140280182Sjfv 2141294034Ssbrunostatic void 2142294034Ssbrunoixv_set_sysctl_value(struct adapter *adapter, const char *name, 2143294034Ssbruno const char *description, int *limit, int value) 2144294034Ssbruno{ 2145294034Ssbruno *limit = value; 2146294034Ssbruno SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), 2147294034Ssbruno SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), 2148294034Ssbruno OID_AUTO, name, CTLFLAG_RW, limit, value, description); 2149294034Ssbruno} 2150294034Ssbruno 2151280182Sjfv/********************************************************************** 2152280182Sjfv * 2153280182Sjfv * This routine is called only when em_display_debug_stats is enabled. 2154280182Sjfv * This routine provides a way to take a look at important statistics 2155280182Sjfv * maintained by the driver and hardware. 2156280182Sjfv * 2157280182Sjfv **********************************************************************/ 2158280182Sjfvstatic void 2159280182Sjfvixv_print_debug_info(struct adapter *adapter) 2160280182Sjfv{ 2161280182Sjfv device_t dev = adapter->dev; 2162280182Sjfv struct ixgbe_hw *hw = &adapter->hw; 2163280182Sjfv struct ix_queue *que = adapter->queues; 2164280182Sjfv struct rx_ring *rxr; 2165280182Sjfv struct tx_ring *txr; 2166280182Sjfv struct lro_ctrl *lro; 2167280182Sjfv 2168280182Sjfv device_printf(dev,"Error Byte Count = %u \n", 2169280182Sjfv IXGBE_READ_REG(hw, IXGBE_ERRBC)); 2170280182Sjfv 2171280182Sjfv for (int i = 0; i < adapter->num_queues; i++, que++) { 2172280182Sjfv txr = que->txr; 2173280182Sjfv rxr = que->rxr; 2174280182Sjfv lro = &rxr->lro; 2175280182Sjfv device_printf(dev,"QUE(%d) IRQs Handled: %lu\n", 2176280182Sjfv que->msix, (long)que->irqs); 2177280182Sjfv device_printf(dev,"RX(%d) Packets Received: %lld\n", 2178280182Sjfv rxr->me, (long long)rxr->rx_packets); 2179280182Sjfv device_printf(dev,"RX(%d) Bytes Received: %lu\n", 2180280182Sjfv rxr->me, (long)rxr->rx_bytes); 2181280182Sjfv device_printf(dev,"RX(%d) LRO Queued= %d\n", 2182280182Sjfv rxr->me, lro->lro_queued); 2183280182Sjfv device_printf(dev,"RX(%d) LRO Flushed= %d\n", 2184280182Sjfv rxr->me, lro->lro_flushed); 2185280182Sjfv device_printf(dev,"TX(%d) Packets Sent: %lu\n", 2186280182Sjfv txr->me, (long)txr->total_packets); 2187280182Sjfv device_printf(dev,"TX(%d) NO Desc Avail: %lu\n", 2188280182Sjfv txr->me, (long)txr->no_desc_avail); 2189280182Sjfv } 2190280182Sjfv 2191280182Sjfv device_printf(dev,"MBX IRQ Handled: %lu\n", 2192283620Serj (long)adapter->link_irq); 2193280182Sjfv return; 2194280182Sjfv} 2195280182Sjfv 2196280182Sjfvstatic int 2197280182Sjfvixv_sysctl_debug(SYSCTL_HANDLER_ARGS) 2198280182Sjfv{ 2199280182Sjfv int error, result; 2200280182Sjfv struct adapter *adapter; 2201280182Sjfv 2202280182Sjfv result = -1; 2203280182Sjfv error = sysctl_handle_int(oidp, &result, 0, req); 2204280182Sjfv 2205280182Sjfv if (error || !req->newptr) 2206280182Sjfv return (error); 2207280182Sjfv 2208280182Sjfv if (result == 1) { 2209280182Sjfv adapter = (struct adapter *) arg1; 2210280182Sjfv ixv_print_debug_info(adapter); 2211280182Sjfv } 2212280182Sjfv return error; 2213280182Sjfv} 2214280182Sjfv 2215