Deleted Added
full compact
3c3
< Copyright (c) 2001-2015, Intel Corporation
---
> Copyright (c) 2001-2017, Intel Corporation
5,6c5,6
<
< Redistribution and use in source and binary forms, with or without
---
>
> Redistribution and use in source and binary forms, with or without
8,9c8,9
<
< 1. Redistributions of source code must retain the above copyright notice,
---
>
> 1. Redistributions of source code must retain the above copyright notice,
11,13c11,13
<
< 2. Redistributions in binary form must reproduce the above copyright
< notice, this list of conditions and the following disclaimer in the
---
>
> 2. Redistributions in binary form must reproduce the above copyright
> notice, this list of conditions and the following disclaimer in the
15,17c15,17
<
< 3. Neither the name of the Intel Corporation nor the names of its
< contributors may be used to endorse or promote products derived from
---
>
> 3. Neither the name of the Intel Corporation nor the names of its
> contributors may be used to endorse or promote products derived from
19c19
<
---
>
21,28c21,28
< AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
< IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
< ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
< LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
< CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
< SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
< INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
< CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
---
> AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
> LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
> INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33c33
< /*$FreeBSD: stable/11/sys/dev/ixgbe/if_ixv.c 302384 2016-07-07 03:39:18Z sbruno $*/
---
> /*$FreeBSD: stable/11/sys/dev/ixgbe/if_ixv.c 320897 2017-07-11 21:25:07Z erj $*/
43,46c43,46
< /*********************************************************************
< * Driver version
< *********************************************************************/
< char ixv_driver_version[] = "1.4.6-k";
---
> /************************************************************************
> * Driver version
> ************************************************************************/
> char ixv_driver_version[] = "1.5.13-k";
48,49c48,49
< /*********************************************************************
< * PCI Device ID Table
---
> /************************************************************************
> * PCI Device ID Table
51,53c51,53
< * Used by probe to select devices to load on
< * Last field stores an index into ixv_strings
< * Last entry must be all 0s
---
> * Used by probe to select devices to load on
> * Last field stores an index into ixv_strings
> * Last entry must be all 0s
55,57c55,56
< * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
< *********************************************************************/
<
---
> * { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
> ************************************************************************/
63a63
> {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_A_VF, 0, 0, 0},
68,72c68,71
< /*********************************************************************
< * Table of branding strings
< *********************************************************************/
<
< static char *ixv_strings[] = {
---
> /************************************************************************
> * Table of branding strings
> ************************************************************************/
> static char *ixv_strings[] = {
76,78c75,77
< /*********************************************************************
< * Function prototypes
< *********************************************************************/
---
> /************************************************************************
> * Function prototypes
> ************************************************************************/
84,85c83,84
< static void ixv_init(void *);
< static void ixv_init_locked(struct adapter *);
---
> static void ixv_init(void *);
> static void ixv_init_locked(struct adapter *);
86a86,87
> static uint64_t ixv_get_counter(struct ifnet *, ift_counter);
> static void ixv_init_device_features(struct adapter *);
89d89
< static void ixv_identify_hardware(struct adapter *);
92,93c92,93
< static int ixv_setup_msix(struct adapter *);
< static void ixv_free_pci_resources(struct adapter *);
---
> static int ixv_configure_interrupts(struct adapter *);
> static void ixv_free_pci_resources(struct adapter *);
96d95
< static void ixv_config_link(struct adapter *);
99a99,100
> static void ixv_initialize_rss_mapping(struct adapter *);
> static void ixv_check_link(struct adapter *);
105,108c106,109
< static int ixv_sysctl_debug(SYSCTL_HANDLER_ARGS);
< static void ixv_set_ivar(struct adapter *, u8, u8, s8);
< static void ixv_configure_ivars(struct adapter *);
< static u8 * ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
---
> static int ixv_sysctl_debug(SYSCTL_HANDLER_ARGS);
> static void ixv_set_ivar(struct adapter *, u8, u8, s8);
> static void ixv_configure_ivars(struct adapter *);
> static u8 *ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
110,112c111,113
< static void ixv_setup_vlan_support(struct adapter *);
< static void ixv_register_vlan(void *, struct ifnet *, u16);
< static void ixv_unregister_vlan(void *, struct ifnet *, u16);
---
> static void ixv_setup_vlan_support(struct adapter *);
> static void ixv_register_vlan(void *, struct ifnet *, u16);
> static void ixv_unregister_vlan(void *, struct ifnet *, u16);
114,119c115,120
< static void ixv_save_stats(struct adapter *);
< static void ixv_init_stats(struct adapter *);
< static void ixv_update_stats(struct adapter *);
< static void ixv_add_stats_sysctls(struct adapter *);
< static void ixv_set_sysctl_value(struct adapter *, const char *,
< const char *, int *, int);
---
> static void ixv_save_stats(struct adapter *);
> static void ixv_init_stats(struct adapter *);
> static void ixv_update_stats(struct adapter *);
> static void ixv_add_stats_sysctls(struct adapter *);
> static void ixv_set_sysctl_value(struct adapter *, const char *,
> const char *, int *, int);
121,123c122,124
< /* The MSI/X Interrupt handlers */
< static void ixv_msix_que(void *);
< static void ixv_msix_mbx(void *);
---
> /* The MSI-X Interrupt handlers */
> static void ixv_msix_que(void *);
> static void ixv_msix_mbx(void *);
126,127c127,128
< static void ixv_handle_que(void *, int);
< static void ixv_handle_mbx(void *, int);
---
> static void ixv_handle_que(void *, int);
> static void ixv_handle_link(void *, int);
129,144c130,132
< #ifdef DEV_NETMAP
< /*
< * This is defined in <dev/netmap/ixgbe_netmap.h>, which is included by
< * if_ix.c.
< */
< extern void ixgbe_netmap_attach(struct adapter *adapter);
<
< #include <net/netmap.h>
< #include <sys/selinfo.h>
< #include <dev/netmap/netmap_kern.h>
< #endif /* DEV_NETMAP */
<
< /*********************************************************************
< * FreeBSD Device Interface Entry Points
< *********************************************************************/
<
---
> /************************************************************************
> * FreeBSD Device Interface Entry Points
> ************************************************************************/
162,165c150
< #ifdef DEV_NETMAP
< MODULE_DEPEND(ix, netmap, 1, 1, 1);
< #endif /* DEV_NETMAP */
< /* XXX depend on 'ix' ? */
---
> MODULE_DEPEND(ixv, netmap, 1, 1, 1);
168,169c153,154
< ** TUNEABLE PARAMETERS:
< */
---
> * TUNEABLE PARAMETERS:
> */
171c156
< /* Number of Queues - do not exceed MSIX vectors - 1 */
---
> /* Number of Queues - do not exceed MSI-X vectors - 1 */
176,180c161,165
< ** AIM: Adaptive Interrupt Moderation
< ** which means that the interrupt rate
< ** is varied over time based on the
< ** traffic for that interrupt vector
< */
---
> * AIM: Adaptive Interrupt Moderation
> * which means that the interrupt rate
> * is varied over time based on the
> * traffic for that interrupt vector
> */
206,209c191,194
< ** Number of TX descriptors per ring,
< ** setting higher than RX as this seems
< ** the better performing choice.
< */
---
> * Number of TX descriptors per ring,
> * setting higher than RX as this seems
> * the better performing choice.
> */
216a202,205
> /* Legacy Transmit (single queue) */
> static int ixv_enable_legacy_tx = 0;
> TUNABLE_INT("hw.ixv.enable_legacy_tx", &ixv_enable_legacy_tx);
>
218,221c207,210
< ** Shadow VFTA table, this is needed because
< ** the real filter table gets cleared during
< ** a soft reset and we need to repopulate it.
< */
---
> * Shadow VFTA table, this is needed because
> * the real filter table gets cleared during
> * a soft reset and we need to repopulate it.
> */
224,225c213,217
< /*********************************************************************
< * Device identification routine
---
> static int (*ixv_start_locked)(struct ifnet *, struct tx_ring *);
> static int (*ixv_ring_empty)(struct ifnet *, struct buf_ring *);
>
> /************************************************************************
> * ixv_probe - Device identification routine
227,228c219,220
< * ixv_probe determines if the driver should be loaded on
< * adapter based on PCI vendor/device id of the adapter.
---
> * Determines if the driver should be loaded on
> * adapter based on its PCI vendor/device ID.
230,232c222,223
< * return BUS_PROBE_DEFAULT on success, positive on failure
< *********************************************************************/
<
---
> * return BUS_PROBE_DEFAULT on success, positive on failure
> ************************************************************************/
236a228,232
> u16 pci_vendor_id = 0;
> u16 pci_device_id = 0;
> u16 pci_subvendor_id = 0;
> u16 pci_subdevice_id = 0;
> char adapter_name[256];
238,242d233
< u16 pci_vendor_id = 0;
< u16 pci_device_id = 0;
< u16 pci_subvendor_id = 0;
< u16 pci_subdevice_id = 0;
< char adapter_name[256];
244d234
<
257d246
<
260d248
<
264,265c252
< ixv_strings[ent->index],
< ixv_driver_version);
---
> ixv_strings[ent->index], ixv_driver_version);
270a258
>
272c260
< }
---
> } /* ixv_probe */
274,275c262,263
< /*********************************************************************
< * Device initialization routine
---
> /************************************************************************
> * ixv_attach - Device initialization routine
277,279c265,267
< * The attach entry point is called when the driver is being loaded.
< * This routine identifies the type of hardware, allocates all resources
< * and initializes the hardware.
---
> * Called when the driver is being loaded.
> * Identifies the type of hardware, allocates all resources
> * and initializes the hardware.
281,283c269,270
< * return 0 on success, positive on failure
< *********************************************************************/
<
---
> * return 0 on success, positive on failure
> ************************************************************************/
287c274
< struct adapter *adapter;
---
> struct adapter *adapter;
292a280,285
> /*
> * Make sure BUSMASTER is set, on a VM under
> * KVM it may not be and will break things.
> */
> pci_enable_busmaster(dev);
>
295a289
> adapter->hw.back = adapter;
298d291
< #ifdef DEV_NETMAP
301d293
< #endif
305a298,304
> /* Do base PCI setup - map BAR0 */
> if (ixv_allocate_pci_resources(adapter)) {
> device_printf(dev, "ixv_allocate_pci_resources() failed!\n");
> error = ENXIO;
> goto err_out;
> }
>
308,310c307,309
< SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
< OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW,
< adapter, 0, ixv_sysctl_debug, "I", "Debug Info");
---
> SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "debug",
> CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixv_sysctl_debug, "I",
> "Debug Info");
313,315c312,314
< SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
< OID_AUTO, "enable_aim", CTLFLAG_RW,
< &ixv_enable_aim, 1, "Interrupt Moderation");
---
> SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
> "enable_aim", CTLFLAG_RW, &ixv_enable_aim, 1,
> "Interrupt Moderation");
320,321c319,324
< /* Determine hardware revision */
< ixv_identify_hardware(adapter);
---
> /* Save off the information about this board */
> hw->vendor_id = pci_get_vendor(dev);
> hw->device_id = pci_get_device(dev);
> hw->revision_id = pci_get_revid(dev);
> hw->subsystem_vendor_id = pci_get_subvendor(dev);
> hw->subsystem_device_id = pci_get_subdevice(dev);
323,325c326,345
< /* Do base PCI setup - map BAR0 */
< if (ixv_allocate_pci_resources(adapter)) {
< device_printf(dev, "ixv_allocate_pci_resources() failed!\n");
---
> /* A subset of set_mac_type */
> switch (hw->device_id) {
> case IXGBE_DEV_ID_82599_VF:
> hw->mac.type = ixgbe_mac_82599_vf;
> break;
> case IXGBE_DEV_ID_X540_VF:
> hw->mac.type = ixgbe_mac_X540_vf;
> break;
> case IXGBE_DEV_ID_X550_VF:
> hw->mac.type = ixgbe_mac_X550_vf;
> break;
> case IXGBE_DEV_ID_X550EM_X_VF:
> hw->mac.type = ixgbe_mac_X550EM_x_vf;
> break;
> case IXGBE_DEV_ID_X550EM_A_VF:
> hw->mac.type = ixgbe_mac_X550EM_a_vf;
> break;
> default:
> /* Shouldn't get here since probe succeeded */
> device_printf(dev, "Unknown device ID!\n");
327a348
> break;
329a351,410
> ixv_init_device_features(adapter);
>
> /* Initialize the shared code */
> error = ixgbe_init_ops_vf(hw);
> if (error) {
> device_printf(dev, "ixgbe_init_ops_vf() failed!\n");
> error = EIO;
> goto err_out;
> }
>
> /* Setup the mailbox */
> ixgbe_init_mbx_params_vf(hw);
>
> /* Set the right number of segments */
> adapter->num_segs = IXGBE_82599_SCATTER;
>
> error = hw->mac.ops.reset_hw(hw);
> if (error == IXGBE_ERR_RESET_FAILED)
> device_printf(dev, "...reset_hw() failure: Reset Failed!\n");
> else if (error)
> device_printf(dev, "...reset_hw() failed with error %d\n",
> error);
> if (error) {
> error = EIO;
> goto err_out;
> }
>
> error = hw->mac.ops.init_hw(hw);
> if (error) {
> device_printf(dev, "...init_hw() failed with error %d\n",
> error);
> error = EIO;
> goto err_out;
> }
>
> /* Negotiate mailbox API version */
> error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12);
> if (error) {
> device_printf(dev, "MBX API 1.2 negotiation failed! Error %d\n",
> error);
> error = EIO;
> goto err_out;
> }
>
> /* If no mac address was assigned, make a random one */
> if (!ixv_check_ether_addr(hw->mac.addr)) {
> u8 addr[ETHER_ADDR_LEN];
> arc4rand(&addr, sizeof(addr), 0);
> addr[0] &= 0xFE;
> addr[0] |= 0x02;
> bcopy(addr, hw->mac.addr, sizeof(addr));
> bcopy(addr, hw->mac.perm_addr, sizeof(addr));
> }
>
> /* Register for VLAN events */
> adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
> ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
> adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
> ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
>
353a435,439
> /* Setup MSI-X */
> error = ixv_configure_interrupts(adapter);
> if (error)
> goto err_out;
>
361,370c447,448
< /*
< ** Initialize the shared code: its
< ** at this point the mac type is set.
< */
< error = ixgbe_init_shared_code(hw);
< if (error) {
< device_printf(dev, "ixgbe_init_shared_code() failed!\n");
< error = EIO;
< goto err_late;
< }
---
> /* Setup OS specific network interface */
> ixv_setup_interface(dev, adapter);
372,380c450
< /* Setup the mailbox */
< ixgbe_init_mbx_params_vf(hw);
<
< /* Reset mbox api to 1.0 */
< error = ixgbe_reset_hw(hw);
< if (error == IXGBE_ERR_RESET_FAILED)
< device_printf(dev, "ixgbe_reset_hw() failure: Reset Failed!\n");
< else if (error)
< device_printf(dev, "ixgbe_reset_hw() failed with error %d\n", error);
---
> error = ixv_allocate_msix(adapter);
382,402d451
< error = EIO;
< goto err_late;
< }
<
< /* Negotiate mailbox API version */
< error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11);
< if (error) {
< device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error);
< error = EIO;
< goto err_late;
< }
<
< error = ixgbe_init_hw(hw);
< if (error) {
< device_printf(dev, "ixgbe_init_hw() failed!\n");
< error = EIO;
< goto err_late;
< }
<
< error = ixv_allocate_msix(adapter);
< if (error) {
407,418d455
< /* If no mac address was assigned, make a random one */
< if (!ixv_check_ether_addr(hw->mac.addr)) {
< u8 addr[ETHER_ADDR_LEN];
< arc4rand(&addr, sizeof(addr), 0);
< addr[0] &= 0xFE;
< addr[0] |= 0x02;
< bcopy(addr, hw->mac.addr, sizeof(addr));
< }
<
< /* Setup OS specific network interface */
< ixv_setup_interface(dev, adapter);
<
424,428c461,462
< /* Register for VLAN events */
< adapter->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
< ixv_register_vlan, adapter, EVENTHANDLER_PRI_FIRST);
< adapter->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
< ixv_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST);
---
> if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
> ixgbe_netmap_attach(adapter);
430,432d463
< #ifdef DEV_NETMAP
< ixgbe_netmap_attach(adapter);
< #endif /* DEV_NETMAP */
433a465
>
438a471
> free(adapter->queues, M_DEVBUF);
440a474,475
> IXGBE_CORE_LOCK_DESTROY(adapter);
>
441a477
> } /* ixv_attach */
443,446c479,480
< }
<
< /*********************************************************************
< * Device removal routine
---
> /************************************************************************
> * ixv_detach - Device removal routine
448,450c482,484
< * The detach entry point is called when the driver is being removed.
< * This routine stops the adapter and deallocates all the resources
< * that were allocated for driver operation.
---
> * Called when the driver is being removed.
> * Stops the adapter and deallocates all the resources
> * that were allocated for driver operation.
452,454c486,487
< * return 0 on success, positive on failure
< *********************************************************************/
<
---
> * return 0 on success, positive on failure
> ************************************************************************/
458c491
< struct adapter *adapter = device_get_softc(dev);
---
> struct adapter *adapter = device_get_softc(dev);
468a502
> ether_ifdetach(adapter->ifp);
494d527
< ether_ifdetach(adapter->ifp);
496,498c529,532
< #ifdef DEV_NETMAP
< netmap_detach(adapter->ifp);
< #endif /* DEV_NETMAP */
---
>
> if (adapter->feat_en & IXGBE_FEATURE_NETMAP)
> netmap_detach(adapter->ifp);
>
504a539
> free(adapter->queues, M_DEVBUF);
507,508d541
< return (0);
< }
510,521d542
< /*********************************************************************
< *
< * Shutdown entry point
< *
< **********************************************************************/
< static int
< ixv_shutdown(device_t dev)
< {
< struct adapter *adapter = device_get_softc(dev);
< IXGBE_CORE_LOCK(adapter);
< ixv_stop(adapter);
< IXGBE_CORE_UNLOCK(adapter);
523c544
< }
---
> } /* ixv_detach */
525,527c546,547
<
< /*********************************************************************
< * Ioctl entry point
---
> /************************************************************************
> * ixv_init_locked - Init entry point
529,530c549,552
< * ixv_ioctl is called when the user wants to configure the
< * interface.
---
> * Used in two ways: It is used by the stack as an init entry
> * point in network interface structure. It is also used
> * by the driver as a hw/sw initialization routine to get
> * to a consistent state.
532,656c554,556
< * return 0 on success, positive on failure
< **********************************************************************/
<
< static int
< ixv_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
< {
< struct adapter *adapter = ifp->if_softc;
< struct ifreq *ifr = (struct ifreq *) data;
< #if defined(INET) || defined(INET6)
< struct ifaddr *ifa = (struct ifaddr *) data;
< bool avoid_reset = FALSE;
< #endif
< int error = 0;
<
< switch (command) {
<
< case SIOCSIFADDR:
< #ifdef INET
< if (ifa->ifa_addr->sa_family == AF_INET)
< avoid_reset = TRUE;
< #endif
< #ifdef INET6
< if (ifa->ifa_addr->sa_family == AF_INET6)
< avoid_reset = TRUE;
< #endif
< #if defined(INET) || defined(INET6)
< /*
< ** Calling init results in link renegotiation,
< ** so we avoid doing it when possible.
< */
< if (avoid_reset) {
< ifp->if_flags |= IFF_UP;
< if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
< ixv_init(adapter);
< if (!(ifp->if_flags & IFF_NOARP))
< arp_ifinit(ifp, ifa);
< } else
< error = ether_ioctl(ifp, command, data);
< break;
< #endif
< case SIOCSIFMTU:
< IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
< if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR) {
< error = EINVAL;
< } else {
< IXGBE_CORE_LOCK(adapter);
< ifp->if_mtu = ifr->ifr_mtu;
< adapter->max_frame_size =
< ifp->if_mtu + IXGBE_MTU_HDR;
< if (ifp->if_drv_flags & IFF_DRV_RUNNING)
< ixv_init_locked(adapter);
< IXGBE_CORE_UNLOCK(adapter);
< }
< break;
< case SIOCSIFFLAGS:
< IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
< IXGBE_CORE_LOCK(adapter);
< if (ifp->if_flags & IFF_UP) {
< if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
< ixv_init_locked(adapter);
< } else
< if (ifp->if_drv_flags & IFF_DRV_RUNNING)
< ixv_stop(adapter);
< adapter->if_flags = ifp->if_flags;
< IXGBE_CORE_UNLOCK(adapter);
< break;
< case SIOCADDMULTI:
< case SIOCDELMULTI:
< IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI");
< if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
< IXGBE_CORE_LOCK(adapter);
< ixv_disable_intr(adapter);
< ixv_set_multi(adapter);
< ixv_enable_intr(adapter);
< IXGBE_CORE_UNLOCK(adapter);
< }
< break;
< case SIOCSIFMEDIA:
< case SIOCGIFMEDIA:
< IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
< error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
< break;
< case SIOCSIFCAP:
< {
< int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
< IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)");
< if (mask & IFCAP_HWCSUM)
< ifp->if_capenable ^= IFCAP_HWCSUM;
< if (mask & IFCAP_TSO4)
< ifp->if_capenable ^= IFCAP_TSO4;
< if (mask & IFCAP_LRO)
< ifp->if_capenable ^= IFCAP_LRO;
< if (mask & IFCAP_VLAN_HWTAGGING)
< ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
< if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
< IXGBE_CORE_LOCK(adapter);
< ixv_init_locked(adapter);
< IXGBE_CORE_UNLOCK(adapter);
< }
< VLAN_CAPABILITIES(ifp);
< break;
< }
<
< default:
< IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command);
< error = ether_ioctl(ifp, command, data);
< break;
< }
<
< return (error);
< }
<
< /*********************************************************************
< * Init entry point
< *
< * This routine is used in two ways. It is used by the stack as
< * init entry point in network interface structure. It is also used
< * by the driver as a hw/sw initialization routine to get to a
< * consistent state.
< *
< * return 0 on success, positive on failure
< **********************************************************************/
< #define IXGBE_MHADD_MFS_SHIFT 16
<
< static void
---
> * return 0 on success, positive on failure
> ************************************************************************/
> void
659,660c559,560
< struct ifnet *ifp = adapter->ifp;
< device_t dev = adapter->dev;
---
> struct ifnet *ifp = adapter->ifp;
> device_t dev = adapter->dev;
662c562
< int error = 0;
---
> int error = 0;
667,668c567,568
< ixgbe_stop_adapter(hw);
< callout_stop(&adapter->timer);
---
> hw->mac.ops.stop_adapter(hw);
> callout_stop(&adapter->timer);
670,671c570,571
< /* reprogram the RAR[0] in case user changed it. */
< ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
---
> /* reprogram the RAR[0] in case user changed it. */
> hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
675,677c575,576
< IXGBE_ETH_LENGTH_OF_ADDRESS);
< ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1);
< hw->addr_ctrl.rar_used_count = 1;
---
> IXGBE_ETH_LENGTH_OF_ADDRESS);
> hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, 1);
687,688c586,587
< ixgbe_reset_hw(hw);
< error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11);
---
> hw->mac.ops.reset_hw(hw);
> error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_12);
690c589,590
< device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error);
---
> device_printf(dev, "MBX API 1.2 negotiation failed! Error %d\n",
> error);
698,700c598,600
< ** Determine the correct mbuf pool
< ** for doing jumbo/headersplit
< */
---
> * Determine the correct mbuf pool
> * for doing jumbo/headersplit
> */
726c626
<
---
>
730c630
< /* Set up MSI/X routing */
---
> /* Set up MSI-X routing */
736,737c636,637
< /* Set moderation on the Link interrupt */
< IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR);
---
> /* Set moderation on the Link interrupt */
> IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR);
743c643,644
< ixv_config_link(adapter);
---
> hw->mac.ops.check_link(hw, &adapter->link_speed, &adapter->link_up,
> FALSE);
756c657
< }
---
> } /* ixv_init_locked */
758,769d658
< static void
< ixv_init(void *arg)
< {
< struct adapter *adapter = arg;
<
< IXGBE_CORE_LOCK(adapter);
< ixv_init_locked(adapter);
< IXGBE_CORE_UNLOCK(adapter);
< return;
< }
<
<
771,774c660,661
< **
< ** MSIX Interrupt Handlers and Tasklets
< **
< */
---
> * MSI-X Interrupt Handlers and Tasklets
> */
780,781c667,668
< u32 queue = 1 << vector;
< u32 mask;
---
> u32 queue = 1 << vector;
> u32 mask;
785c672
< }
---
> } /* ixv_enable_queue */
791,792c678,679
< u64 queue = (u64)(1 << vector);
< u32 mask;
---
> u64 queue = (u64)(1 << vector);
> u32 mask;
796c683
< }
---
> } /* ixv_disable_queue */
803c690
< }
---
> } /* ixv_rearm_queues */
806,842c693,695
< static void
< ixv_handle_que(void *context, int pending)
< {
< struct ix_queue *que = context;
< struct adapter *adapter = que->adapter;
< struct tx_ring *txr = que->txr;
< struct ifnet *ifp = adapter->ifp;
< bool more;
<
< if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
< more = ixgbe_rxeof(que);
< IXGBE_TX_LOCK(txr);
< ixgbe_txeof(txr);
< #if __FreeBSD_version >= 800000
< if (!drbr_empty(ifp, txr->br))
< ixgbe_mq_start_locked(ifp, txr);
< #else
< if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
< ixgbe_start_locked(txr, ifp);
< #endif
< IXGBE_TX_UNLOCK(txr);
< if (more) {
< taskqueue_enqueue(que->tq, &que->que_task);
< return;
< }
< }
<
< /* Reenable this interrupt */
< ixv_enable_queue(adapter, que->msix);
< return;
< }
<
< /*********************************************************************
< *
< * MSI Queue Interrupt Service routine
< *
< **********************************************************************/
---
> /************************************************************************
> * ixv_msix_que - MSI Queue Interrupt Service routine
> ************************************************************************/
846c699
< struct ix_queue *que = arg;
---
> struct ix_queue *que = arg;
849,852c702,705
< struct tx_ring *txr = que->txr;
< struct rx_ring *rxr = que->rxr;
< bool more;
< u32 newitr = 0;
---
> struct tx_ring *txr = que->txr;
> struct rx_ring *rxr = que->rxr;
> bool more;
> u32 newitr = 0;
862,872c715,720
< ** Make certain that if the stack
< ** has anything queued the task gets
< ** scheduled to handle it.
< */
< #ifdef IXGBE_LEGACY_TX
< if (!IFQ_DRV_IS_EMPTY(&adapter->ifp->if_snd))
< ixgbe_start_locked(txr, ifp);
< #else
< if (!drbr_empty(adapter->ifp, txr->br))
< ixgbe_mq_start_locked(ifp, txr);
< #endif
---
> * Make certain that if the stack
> * has anything queued the task gets
> * scheduled to handle it.
> */
> if (!ixv_ring_empty(adapter->ifp, txr->br))
> ixv_start_locked(ifp, txr);
880,887c728,734
< ** Do Adaptive Interrupt Moderation:
< ** - Write out last calculated setting
< ** - Calculate based on average size over
< ** the last interval.
< */
< if (que->eitr_setting)
< IXGBE_WRITE_REG(&adapter->hw,
< IXGBE_VTEITR(que->msix),
---
> * Do Adaptive Interrupt Moderation:
> * - Write out last calculated setting
> * - Calculate based on average size over
> * the last interval.
> */
> if (que->eitr_setting)
> IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEITR(que->msix),
889,890d735
<
< que->eitr_setting = 0;
892,895c737,742
< /* Idle, do nothing */
< if ((txr->bytes == 0) && (rxr->bytes == 0))
< goto no_calc;
<
---
> que->eitr_setting = 0;
>
> /* Idle, do nothing */
> if ((txr->bytes == 0) && (rxr->bytes == 0))
> goto no_calc;
>
897c744
< newitr = txr->bytes/txr->packets;
---
> newitr = txr->bytes/txr->packets;
899,900c746
< newitr = max(newitr,
< (rxr->bytes / rxr->packets));
---
> newitr = max(newitr, (rxr->bytes / rxr->packets));
913,915d758
<
< /* save for next interrupt */
< que->eitr_setting = newitr;
917,921c760,761
< /* Reset state */
< txr->bytes = 0;
< txr->packets = 0;
< rxr->bytes = 0;
< rxr->packets = 0;
---
> /* save for next interrupt */
> que->eitr_setting = newitr;
922a763,768
> /* Reset state */
> txr->bytes = 0;
> txr->packets = 0;
> rxr->bytes = 0;
> rxr->packets = 0;
>
926c772
< else /* Reenable this interrupt */
---
> else /* Re-enable this interrupt */
927a774
>
929c776
< }
---
> } /* ixv_msix_que */
930a778,780
> /************************************************************************
> * ixv_msix_mbx
> ************************************************************************/
934c784
< struct adapter *adapter = arg;
---
> struct adapter *adapter = arg;
936c786
< u32 reg;
---
> u32 reg;
949a800
>
951c802
< }
---
> } /* ixv_msix_mbx */
953c804,805
< /*********************************************************************
---
> /************************************************************************
> * ixv_media_status - Media Ioctl callback
955,960c807,809
< * Media Ioctl callback
< *
< * This routine is called whenever the user queries the status of
< * the interface using ifconfig.
< *
< **********************************************************************/
---
> * Called whenever the user queries the status of
> * the interface using ifconfig.
> ************************************************************************/
962c811
< ixv_media_status(struct ifnet * ifp, struct ifmediareq * ifmr)
---
> ixv_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
985c834
< ifmr->ifm_active |= IFM_FDX;
---
> ifmr->ifm_active |= IFM_10G_T | IFM_FDX;
986a836,841
> case IXGBE_LINK_SPEED_100_FULL:
> ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
> break;
> case IXGBE_LINK_SPEED_10_FULL:
> ifmr->ifm_active |= IFM_10_T | IFM_FDX;
> break;
992c847
< }
---
> } /* ixv_media_status */
994c849,850
< /*********************************************************************
---
> /************************************************************************
> * ixv_media_change - Media Ioctl callback
996,1001c852,854
< * Media Ioctl callback
< *
< * This routine is called when the user changes speed/duplex using
< * media/mediopt option with ifconfig.
< *
< **********************************************************************/
---
> * Called when the user changes speed/duplex using
> * media/mediopt option with ifconfig.
> ************************************************************************/
1003c856
< ixv_media_change(struct ifnet * ifp)
---
> ixv_media_change(struct ifnet *ifp)
1013,1017c866,870
< switch (IFM_SUBTYPE(ifm->ifm_media)) {
< case IFM_AUTO:
< break;
< default:
< device_printf(adapter->dev, "Only auto media type\n");
---
> switch (IFM_SUBTYPE(ifm->ifm_media)) {
> case IFM_AUTO:
> break;
> default:
> device_printf(adapter->dev, "Only auto media type\n");
1019c872
< }
---
> }
1022c875
< }
---
> } /* ixv_media_change */
1025,1026c878,879
< /*********************************************************************
< * Multicast Update
---
> /************************************************************************
> * ixv_set_multi - Multicast Update
1028,1032c881,882
< * This routine is called whenever multicast address list is updated.
< *
< **********************************************************************/
< #define IXGBE_RAR_ENTRIES 16
<
---
> * Called whenever multicast address list is updated.
> ************************************************************************/
1036,1040c886,890
< u8 mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
< u8 *update_ptr;
< struct ifmultiaddr *ifma;
< int mcnt = 0;
< struct ifnet *ifp = adapter->ifp;
---
> u8 mta[MAX_NUM_MULTICAST_ADDRESSES * IXGBE_ETH_LENGTH_OF_ADDRESS];
> u8 *update_ptr;
> struct ifmultiaddr *ifma;
> struct ifnet *ifp = adapter->ifp;
> int mcnt = 0;
1052c902
< bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr),
---
> bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1065,1066c915,916
< ixgbe_update_mc_addr_list(&adapter->hw,
< update_ptr, mcnt, ixv_mc_array_itr, TRUE);
---
> adapter->hw.mac.ops.update_mc_addr_list(&adapter->hw, update_ptr, mcnt,
> ixv_mc_array_itr, TRUE);
1069c919
< }
---
> } /* ixv_set_multi */
1071,1075c921,927
< /*
< * This is an iterator function now needed by the multicast
< * shared code. It simply feeds the shared code routine the
< * addresses in the array of ixv_set_multi() one by one.
< */
---
> /************************************************************************
> * ixv_mc_array_itr
> *
> * An iterator function needed by the multicast shared code.
> * It feeds the shared code routine the addresses in the
> * array of ixv_set_multi() one by one.
> ************************************************************************/
1084a937
>
1086c939
< }
---
> } /* ixv_mc_array_itr */
1088,1089c941,942
< /*********************************************************************
< * Timer routine
---
> /************************************************************************
> * ixv_local_timer - Timer routine
1091,1095c944,946
< * This routine checks for link status,updates statistics,
< * and runs the watchdog check.
< *
< **********************************************************************/
<
---
> * Checks for link status, updates statistics,
> * and runs the watchdog check.
> ************************************************************************/
1099,1103c950,954
< struct adapter *adapter = arg;
< device_t dev = adapter->dev;
< struct ix_queue *que = adapter->queues;
< u64 queues = 0;
< int hung = 0;
---
> struct adapter *adapter = arg;
> device_t dev = adapter->dev;
> struct ix_queue *que = adapter->queues;
> u64 queues = 0;
> int hung = 0;
1107c958
< ixv_update_link_status(adapter);
---
> ixv_check_link(adapter);
1113,1116c964,967
< ** Check the TX queues status
< ** - mark hung queues so we don't schedule on them
< ** - watchdog only if all queues show hung
< */
---
> * Check the TX queues status
> * - mark hung queues so we don't schedule on them
> * - watchdog only if all queues show hung
> */
1122,1125c973,976
< ** Each time txeof runs without cleaning, but there
< ** are uncleaned descriptors it increments busy. If
< ** we get to the MAX we declare it hung.
< */
---
> * Each time txeof runs without cleaning, but there
> * are uncleaned descriptors it increments busy. If
> * we get to the MAX we declare it hung.
> */
1134c985
< adapter->active_queues |= ((u64)1 << que->me);
---
> adapter->active_queues |= ((u64)1 << que->me);
1137,1138c988,989
< device_printf(dev,"Warning queue %d "
< "appears to be hung!\n", i);
---
> device_printf(dev,
> "Warning queue %d appears to be hung!\n", i);
1152a1004
>
1155a1008
>
1160c1013
< }
---
> } /* ixv_local_timer */
1162,1166c1015,1021
< /*
< ** Note: this routine updates the OS on the link state
< ** the real check of the hardware only happens with
< ** a link interrupt.
< */
---
> /************************************************************************
> * ixv_update_link_status - Update OS on link state
> *
> * Note: Only updates the OS on the cached link state.
> * The real check of the hardware only happens with
> * a link interrupt.
> ************************************************************************/
1170,1171c1025,1026
< struct ifnet *ifp = adapter->ifp;
< device_t dev = adapter->dev;
---
> struct ifnet *ifp = adapter->ifp;
> device_t dev = adapter->dev;
1173c1028
< if (adapter->link_up){
---
> if (adapter->link_up) {
1177c1032
< ((adapter->link_speed == 128)? 10:1),
---
> ((adapter->link_speed == 128) ? 10 : 1),
1192c1047
< }
---
> } /* ixv_update_link_status */
1195c1050,1051
< /*********************************************************************
---
> /************************************************************************
> * ixv_stop - Stop the hardware
1197,1201c1053,1055
< * This routine disables all traffic on the adapter by issuing a
< * global reset on the MAC and deallocates TX/RX buffers.
< *
< **********************************************************************/
<
---
> * Disables all traffic on the adapter by issuing a
> * global reset on the MAC and deallocates TX/RX buffers.
> ************************************************************************/
1205,1206c1059,1060
< struct ifnet *ifp;
< struct adapter *adapter = arg;
---
> struct ifnet *ifp;
> struct adapter *adapter = arg;
1207a1062
>
1218c1073
< ixgbe_reset_hw(hw);
---
> hw->mac.ops.reset_hw(hw);
1220c1075
< ixgbe_stop_adapter(hw);
---
> hw->mac.ops.stop_adapter(hw);
1224c1079
< ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
---
> hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
1227c1082
< }
---
> } /* ixv_stop */
1230,1269c1085,1087
< /*********************************************************************
< *
< * Determine hardware revision.
< *
< **********************************************************************/
< static void
< ixv_identify_hardware(struct adapter *adapter)
< {
< device_t dev = adapter->dev;
< struct ixgbe_hw *hw = &adapter->hw;
<
< /*
< ** Make sure BUSMASTER is set, on a VM under
< ** KVM it may not be and will break things.
< */
< pci_enable_busmaster(dev);
<
< /* Save off the information about this board */
< hw->vendor_id = pci_get_vendor(dev);
< hw->device_id = pci_get_device(dev);
< hw->revision_id = pci_read_config(dev, PCIR_REVID, 1);
< hw->subsystem_vendor_id =
< pci_read_config(dev, PCIR_SUBVEND_0, 2);
< hw->subsystem_device_id =
< pci_read_config(dev, PCIR_SUBDEV_0, 2);
<
< /* We need this to determine device-specific things */
< ixgbe_set_mac_type(hw);
<
< /* Set the right number of segments */
< adapter->num_segs = IXGBE_82599_SCATTER;
<
< return;
< }
<
< /*********************************************************************
< *
< * Setup MSIX Interrupt resources and handlers
< *
< **********************************************************************/
---
> /************************************************************************
> * ixv_allocate_pci_resources
> ************************************************************************/
1271c1089
< ixv_allocate_msix(struct adapter *adapter)
---
> ixv_allocate_pci_resources(struct adapter *adapter)
1273,1368d1090
< device_t dev = adapter->dev;
< struct ix_queue *que = adapter->queues;
< struct tx_ring *txr = adapter->tx_rings;
< int error, rid, vector = 0;
<
< for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
< rid = vector + 1;
< que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
< RF_SHAREABLE | RF_ACTIVE);
< if (que->res == NULL) {
< device_printf(dev,"Unable to allocate"
< " bus resource: que interrupt [%d]\n", vector);
< return (ENXIO);
< }
< /* Set the handler function */
< error = bus_setup_intr(dev, que->res,
< INTR_TYPE_NET | INTR_MPSAFE, NULL,
< ixv_msix_que, que, &que->tag);
< if (error) {
< que->res = NULL;
< device_printf(dev, "Failed to register QUE handler");
< return (error);
< }
< #if __FreeBSD_version >= 800504
< bus_describe_intr(dev, que->res, que->tag, "que %d", i);
< #endif
< que->msix = vector;
< adapter->active_queues |= (u64)(1 << que->msix);
< /*
< ** Bind the msix vector, and thus the
< ** ring to the corresponding cpu.
< */
< if (adapter->num_queues > 1)
< bus_bind_intr(dev, que->res, i);
< TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
< TASK_INIT(&que->que_task, 0, ixv_handle_que, que);
< que->tq = taskqueue_create_fast("ixv_que", M_NOWAIT,
< taskqueue_thread_enqueue, &que->tq);
< taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que",
< device_get_nameunit(adapter->dev));
< }
<
< /* and Mailbox */
< rid = vector + 1;
< adapter->res = bus_alloc_resource_any(dev,
< SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
< if (!adapter->res) {
< device_printf(dev,"Unable to allocate"
< " bus resource: MBX interrupt [%d]\n", rid);
< return (ENXIO);
< }
< /* Set the mbx handler function */
< error = bus_setup_intr(dev, adapter->res,
< INTR_TYPE_NET | INTR_MPSAFE, NULL,
< ixv_msix_mbx, adapter, &adapter->tag);
< if (error) {
< adapter->res = NULL;
< device_printf(dev, "Failed to register LINK handler");
< return (error);
< }
< #if __FreeBSD_version >= 800504
< bus_describe_intr(dev, adapter->res, adapter->tag, "mbx");
< #endif
< adapter->vector = vector;
< /* Tasklets for Mailbox */
< TASK_INIT(&adapter->link_task, 0, ixv_handle_mbx, adapter);
< adapter->tq = taskqueue_create_fast("ixv_mbx", M_NOWAIT,
< taskqueue_thread_enqueue, &adapter->tq);
< taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s mbxq",
< device_get_nameunit(adapter->dev));
< /*
< ** Due to a broken design QEMU will fail to properly
< ** enable the guest for MSIX unless the vectors in
< ** the table are all set up, so we must rewrite the
< ** ENABLE in the MSIX control register again at this
< ** point to cause it to successfully initialize us.
< */
< if (adapter->hw.mac.type == ixgbe_mac_82599_vf) {
< int msix_ctrl;
< pci_find_cap(dev, PCIY_MSIX, &rid);
< rid += PCIR_MSIX_CTRL;
< msix_ctrl = pci_read_config(dev, rid, 2);
< msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE;
< pci_write_config(dev, rid, msix_ctrl, 2);
< }
<
< return (0);
< }
<
< /*
< * Setup MSIX resources, note that the VF
< * device MUST use MSIX, there is no fallback.
< */
< static int
< ixv_setup_msix(struct adapter *adapter)
< {
1370c1092
< int rid, want, msgs;
---
> int rid;
1372,1419d1093
<
< /* Must have at least 2 MSIX vectors */
< msgs = pci_msix_count(dev);
< if (msgs < 2)
< goto out;
< rid = PCIR_BAR(3);
< adapter->msix_mem = bus_alloc_resource_any(dev,
< SYS_RES_MEMORY, &rid, RF_ACTIVE);
< if (adapter->msix_mem == NULL) {
< device_printf(adapter->dev,
< "Unable to map MSIX table \n");
< goto out;
< }
<
< /*
< ** Want vectors for the queues,
< ** plus an additional for mailbox.
< */
< want = adapter->num_queues + 1;
< if (want > msgs) {
< want = msgs;
< adapter->num_queues = msgs - 1;
< } else
< msgs = want;
< if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
< device_printf(adapter->dev,
< "Using MSIX interrupts with %d vectors\n", want);
< return (want);
< }
< /* Release in case alloc was insufficient */
< pci_release_msi(dev);
< out:
< if (adapter->msix_mem != NULL) {
< bus_release_resource(dev, SYS_RES_MEMORY,
< rid, adapter->msix_mem);
< adapter->msix_mem = NULL;
< }
< device_printf(adapter->dev,"MSIX config error\n");
< return (ENXIO);
< }
<
<
< static int
< ixv_allocate_pci_resources(struct adapter *adapter)
< {
< int rid;
< device_t dev = adapter->dev;
<
1421,1422c1095,1096
< adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
< &rid, RF_ACTIVE);
---
> adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
> RF_ACTIVE);
1429,1430c1103
< adapter->osdep.mem_bus_space_tag =
< rman_get_bustag(adapter->pci_mem);
---
> adapter->osdep.mem_bus_space_tag = rman_get_bustag(adapter->pci_mem);
1432c1105
< rman_get_bushandle(adapter->pci_mem);
---
> rman_get_bushandle(adapter->pci_mem);
1437d1109
< adapter->hw.back = adapter;
1439,1449c1111,1112
< /*
< ** Now setup MSI/X, should
< ** return us the number of
< ** configured vectors.
< */
< adapter->msix = ixv_setup_msix(adapter);
< if (adapter->msix == ENXIO)
< return (ENXIO);
< else
< return (0);
< }
---
> return (0);
> } /* ixv_allocate_pci_resources */
1450a1114,1116
> /************************************************************************
> * ixv_free_pci_resources
> ************************************************************************/
1454,1456c1120,1122
< struct ix_queue *que = adapter->queues;
< device_t dev = adapter->dev;
< int rid, memrid;
---
> struct ix_queue *que = adapter->queues;
> device_t dev = adapter->dev;
> int rid, memrid;
1461,1467c1127,1133
< ** There is a slight possibility of a failure mode
< ** in attach that will result in entering this function
< ** before interrupt resources have been initialized, and
< ** in that case we do not want to execute the loops below
< ** We can detect this reliably by the state of the adapter
< ** res pointer.
< */
---
> * There is a slight possibility of a failure mode
> * in attach that will result in entering this function
> * before interrupt resources have been initialized, and
> * in that case we do not want to execute the loops below
> * We can detect this reliably by the state of the adapter
> * res pointer.
> */
1472,1473c1138,1139
< ** Release all msix queue resources:
< */
---
> * Release all msix queue resources:
> */
1485,1489c1151,1152
< /* Clean the Legacy or Link interrupt last */
< if (adapter->vector) /* we are doing MSIX */
< rid = adapter->vector + 1;
< else
< (adapter->msix != 0) ? (rid = 1):(rid = 0);
---
> /* Clean the Mailbox interrupt last */
> rid = adapter->vector + 1;
1499,1500c1162
< if (adapter->msix)
< pci_release_msi(dev);
---
> pci_release_msi(dev);
1503,1504c1165,1166
< bus_release_resource(dev, SYS_RES_MEMORY,
< memrid, adapter->msix_mem);
---
> bus_release_resource(dev, SYS_RES_MEMORY, memrid,
> adapter->msix_mem);
1507,1508c1169,1170
< bus_release_resource(dev, SYS_RES_MEMORY,
< PCIR_BAR(0), adapter->pci_mem);
---
> bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
> adapter->pci_mem);
1511c1173
< }
---
> } /* ixv_free_pci_resources */
1513c1175,1176
< /*********************************************************************
---
> /************************************************************************
> * ixv_setup_interface
1515,1517c1178,1179
< * Setup networking device structure and register an interface.
< *
< **********************************************************************/
---
> * Setup networking device structure and register an interface.
> ************************************************************************/
1521c1183
< struct ifnet *ifp;
---
> struct ifnet *ifp;
1534,1540c1196,1211
< #if __FreeBSD_version >= 800000
< ifp->if_transmit = ixgbe_mq_start;
< ifp->if_qflush = ixgbe_qflush;
< #else
< ifp->if_start = ixgbe_start;
< #endif
< ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2;
---
> if_setgetcounterfn(ifp, ixv_get_counter);
> /* TSO parameters */
> ifp->if_hw_tsomax = 65518;
> ifp->if_hw_tsomaxsegcount = IXGBE_82599_SCATTER;
> ifp->if_hw_tsomaxsegsize = 2048;
> if (adapter->feat_en & IXGBE_FEATURE_LEGACY_TX) {
> ifp->if_start = ixgbe_legacy_start;
> ixv_start_locked = ixgbe_legacy_start_locked;
> ixv_ring_empty = ixgbe_legacy_ring_empty;
> } else {
> ifp->if_transmit = ixgbe_mq_start;
> ifp->if_qflush = ixgbe_qflush;
> ixv_start_locked = ixgbe_mq_start_locked;
> ixv_ring_empty = drbr_empty;
> }
> IFQ_SET_MAXLEN(&ifp->if_snd, adapter->num_tx_desc - 2);
1544,1545c1215
< adapter->max_frame_size =
< ifp->if_mtu + IXGBE_MTU_HDR_VLAN;
---
> adapter->max_frame_size = ifp->if_mtu + IXGBE_MTU_HDR;
1552,1557c1222,1233
< ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM;
< ifp->if_capabilities |= IFCAP_JUMBO_MTU;
< ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING
< | IFCAP_VLAN_HWTSO
< | IFCAP_VLAN_MTU;
< ifp->if_capabilities |= IFCAP_LRO;
---
> /* Set capability flags */
> ifp->if_capabilities |= IFCAP_HWCSUM
> | IFCAP_HWCSUM_IPV6
> | IFCAP_TSO
> | IFCAP_LRO
> | IFCAP_VLAN_HWTAGGING
> | IFCAP_VLAN_HWTSO
> | IFCAP_VLAN_HWCSUM
> | IFCAP_JUMBO_MTU
> | IFCAP_VLAN_MTU;
>
> /* Enable the above capabilities by default */
1565c1241
< ixv_media_status);
---
> ixv_media_status);
1570,1576c1246
< }
<
< static void
< ixv_config_link(struct adapter *adapter)
< {
< struct ixgbe_hw *hw = &adapter->hw;
< u32 autoneg;
---
> } /* ixv_setup_interface */
1578,1581d1247
< if (hw->mac.ops.check_link)
< hw->mac.ops.check_link(hw, &autoneg,
< &adapter->link_up, FALSE);
< }
1583,1588c1249,1251
<
< /*********************************************************************
< *
< * Enable transmit unit.
< *
< **********************************************************************/
---
> /************************************************************************
> * ixv_initialize_transmit_units - Enable transmit unit.
> ************************************************************************/
1592,1593c1255,1256
< struct tx_ring *txr = adapter->tx_rings;
< struct ixgbe_hw *hw = &adapter->hw;
---
> struct tx_ring *txr = adapter->tx_rings;
> struct ixgbe_hw *hw = &adapter->hw;
1597,1598c1260,1261
< u64 tdba = txr->txdma.dma_paddr;
< u32 txctrl, txdctl;
---
> u64 tdba = txr->txdma.dma_paddr;
> u32 txctrl, txdctl;
1606,1607c1269,1270
< IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(i), 0);
< IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(i), 0);
---
> IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDH(i), 0);
> IXGBE_WRITE_REG(&adapter->hw, IXGBE_VFTDT(i), 0);
1614c1277
< (tdba & 0x00000000ffffffffULL));
---
> (tdba & 0x00000000ffffffffULL));
1617,1618c1280
< adapter->num_tx_desc *
< sizeof(struct ixgbe_legacy_tx_desc));
---
> adapter->num_tx_desc * sizeof(struct ixgbe_legacy_tx_desc));
1630c1292
< }
---
> } /* ixv_initialize_transmit_units */
1633,1638c1295,1305
< /*********************************************************************
< *
< * Setup receive registers and features.
< *
< **********************************************************************/
< #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
---
> /************************************************************************
> * ixv_initialize_rss_mapping
> ************************************************************************/
> static void
> ixv_initialize_rss_mapping(struct adapter *adapter)
> {
> struct ixgbe_hw *hw = &adapter->hw;
> u32 reta = 0, mrqc, rss_key[10];
> int queue_id;
> int i, j;
> u32 rss_hash_config;
1639a1307,1393
> if (adapter->feat_en & IXGBE_FEATURE_RSS) {
> /* Fetch the configured RSS key */
> rss_getkey((uint8_t *)&rss_key);
> } else {
> /* set up random bits */
> arc4rand(&rss_key, sizeof(rss_key), 0);
> }
>
> /* Now fill out hash function seeds */
> for (i = 0; i < 10; i++)
> IXGBE_WRITE_REG(hw, IXGBE_VFRSSRK(i), rss_key[i]);
>
> /* Set up the redirection table */
> for (i = 0, j = 0; i < 64; i++, j++) {
> if (j == adapter->num_queues)
> j = 0;
>
> if (adapter->feat_en & IXGBE_FEATURE_RSS) {
> /*
> * Fetch the RSS bucket id for the given indirection
> * entry. Cap it at the number of configured buckets
> * (which is num_queues.)
> */
> queue_id = rss_get_indirection_to_bucket(i);
> queue_id = queue_id % adapter->num_queues;
> } else
> queue_id = j;
>
> /*
> * The low 8 bits are for hash value (n+0);
> * The next 8 bits are for hash value (n+1), etc.
> */
> reta >>= 8;
> reta |= ((uint32_t)queue_id) << 24;
> if ((i & 3) == 3) {
> IXGBE_WRITE_REG(hw, IXGBE_VFRETA(i >> 2), reta);
> reta = 0;
> }
> }
>
> /* Perform hash on these packet types */
> if (adapter->feat_en & IXGBE_FEATURE_RSS)
> rss_hash_config = rss_gethashconfig();
> else {
> /*
> * Disable UDP - IP fragments aren't currently being handled
> * and so we end up with a mix of 2-tuple and 4-tuple
> * traffic.
> */
> rss_hash_config = RSS_HASHTYPE_RSS_IPV4
> | RSS_HASHTYPE_RSS_TCP_IPV4
> | RSS_HASHTYPE_RSS_IPV6
> | RSS_HASHTYPE_RSS_TCP_IPV6;
> }
>
> mrqc = IXGBE_MRQC_RSSEN;
> if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
> mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4;
> if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
> mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP;
> if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6)
> mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6;
> if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6)
> mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
> if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX)
> device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_IPV6_EX defined, but not supported\n",
> __func__);
> if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6_EX)
> device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_TCP_IPV6_EX defined, but not supported\n",
> __func__);
> if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
> mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP;
> if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4_EX)
> device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV4_EX defined, but not supported\n",
> __func__);
> if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6)
> mrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
> if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6_EX)
> device_printf(adapter->dev, "%s: RSS_HASHTYPE_RSS_UDP_IPV6_EX defined, but not supported\n",
> __func__);
> IXGBE_WRITE_REG(hw, IXGBE_VFMRQC, mrqc);
> } /* ixv_initialize_rss_mapping */
>
>
> /************************************************************************
> * ixv_initialize_receive_units - Setup receive registers and features.
> ************************************************************************/
1643,1646c1397,1400
< struct rx_ring *rxr = adapter->rx_rings;
< struct ixgbe_hw *hw = &adapter->hw;
< struct ifnet *ifp = adapter->ifp;
< u32 bufsz, rxcsum, psrtype;
---
> struct rx_ring *rxr = adapter->rx_rings;
> struct ixgbe_hw *hw = &adapter->hw;
> struct ifnet *ifp = adapter->ifp;
> u32 bufsz, rxcsum, psrtype;
1653,1655c1407,1411
< psrtype = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR |
< IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR |
< IXGBE_PSRTYPE_L2HDR;
---
> psrtype = IXGBE_PSRTYPE_TCPHDR
> | IXGBE_PSRTYPE_UDPHDR
> | IXGBE_PSRTYPE_IPV4HDR
> | IXGBE_PSRTYPE_IPV6HDR
> | IXGBE_PSRTYPE_L2HDR;
1656a1413,1415
> if (adapter->num_queues > 1)
> psrtype |= 1 << 29;
>
1660c1419,1421
< ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size);
---
> if (ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size) != 0) {
> device_printf(adapter->dev, "There is a problem with the PF setup. It is likely the receive unit for this VF will not function correctly.\n");
> }
1681,1682c1442
< IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(i),
< (rdba >> 32));
---
> IXGBE_WRITE_REG(hw, IXGBE_VFRDBAH(i), (rdba >> 32));
1708,1709c1468
< else
< msec_delay(1);
---
> msec_delay(1);
1714d1472
< #ifdef DEV_NETMAP
1731c1489,1491
< if (ifp->if_capenable & IFCAP_NETMAP) {
---
> #ifdef DEV_NETMAP
> if ((adapter->feat_en & IXGBE_FEATURE_NETMAP) &&
> (ifp->if_capenable & IFCAP_NETMAP)) {
1744a1505,1511
> ixv_initialize_rss_mapping(adapter);
>
> if (adapter->num_queues > 1) {
> /* RSS and RX IPP Checksum are mutually exclusive */
> rxcsum |= IXGBE_RXCSUM_PCSD;
> }
>
1754c1521
< }
---
> } /* ixv_initialize_receive_units */
1755a1523,1525
> /************************************************************************
> * ixv_setup_vlan_support
> ************************************************************************/
1760,1761c1530
< u32 ctrl, vid, vfta, retry;
< struct rx_ring *rxr;
---
> u32 ctrl, vid, vfta, retry;
1764,1768c1533,1537
< ** We get here thru init_locked, meaning
< ** a soft reset, this has already cleared
< ** the VFTA and other state, so if there
< ** have been no vlan's registered do nothing.
< */
---
> * We get here thru init_locked, meaning
> * a soft reset, this has already cleared
> * the VFTA and other state, so if there
> * have been no vlan's registered do nothing.
> */
1781,1782c1550
< rxr = &adapter->rx_rings[i];
< rxr->vtag_strip = TRUE;
---
> adapter->rx_rings[i].vtag_strip = TRUE;
1786,1788c1554,1556
< ** A soft reset zero's out the VFTA, so
< ** we need to repopulate it now.
< */
---
> * A soft reset zero's out the VFTA, so
> * we need to repopulate it now.
> */
1794,1797c1562,1565
< ** Reconstruct the vlan id's
< ** based on the bits set in each
< ** of the array ints.
< */
---
> * Reconstruct the vlan id's
> * based on the bits set in each
> * of the array ints.
> */
1804c1572
< while (ixgbe_set_vfta(hw, vid, 0, TRUE)) {
---
> while (hw->mac.ops.set_vfta(hw, vid, 0, TRUE, FALSE)) {
1810c1578
< }
---
> } /* ixv_setup_vlan_support */
1812,1818c1580,1587
< /*
< ** This routine is run via an vlan config EVENT,
< ** it enables us to use the HW Filter table since
< ** we can get the vlan id. This just creates the
< ** entry in the soft version of the VFTA, init will
< ** repopulate the real table.
< */
---
> /************************************************************************
> * ixv_register_vlan
> *
> * Run via a vlan config EVENT, it enables us to use the
> * HW Filter table since we can get the vlan id. This just
> * creates the entry in the soft version of the VFTA, init
> * will repopulate the real table.
> ************************************************************************/
1822,1823c1591,1592
< struct adapter *adapter = ifp->if_softc;
< u16 index, bit;
---
> struct adapter *adapter = ifp->if_softc;
> u16 index, bit;
1839c1608
< }
---
> } /* ixv_register_vlan */
1841,1845c1610,1615
< /*
< ** This routine is run via an vlan
< ** unconfig EVENT, remove our entry
< ** in the soft vfta.
< */
---
> /************************************************************************
> * ixv_unregister_vlan
> *
> * Run via a vlan unconfig EVENT, remove our entry
> * in the soft vfta.
> ************************************************************************/
1849,1850c1619,1620
< struct adapter *adapter = ifp->if_softc;
< u16 index, bit;
---
> struct adapter *adapter = ifp->if_softc;
> u16 index, bit;
1855c1625
< if ((vtag == 0) || (vtag > 4095)) /* Invalid */
---
> if ((vtag == 0) || (vtag > 4095)) /* Invalid */
1866c1636
< }
---
> } /* ixv_unregister_vlan */
1867a1638,1640
> /************************************************************************
> * ixv_enable_intr
> ************************************************************************/
1873c1646
< u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
---
> u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
1882c1655
< for (int i = 0; i < adapter->num_queues; i++, que++)
---
> for (int i = 0; i < adapter->num_queues; i++, que++)
1888c1661
< }
---
> } /* ixv_enable_intr */
1889a1663,1665
> /************************************************************************
> * ixv_disable_intr
> ************************************************************************/
1895a1672
>
1897c1674
< }
---
> } /* ixv_disable_intr */
1899,1904c1676,1683
< /*
< ** Setup the correct IVAR register for a particular MSIX interrupt
< ** - entry is the register array entry
< ** - vector is the MSIX vector for this queue
< ** - type is RX/TX/MISC
< */
---
> /************************************************************************
> * ixv_set_ivar
> *
> * Setup the correct IVAR register for a particular MSI-X interrupt
> * - entry is the register array entry
> * - vector is the MSI-X vector for this queue
> * - type is RX/TX/MISC
> ************************************************************************/
1909c1688
< u32 ivar, index;
---
> u32 ivar, index;
1918c1697
< } else { /* RX/TX IVARS */
---
> } else { /* RX/TX IVARS */
1925c1704
< }
---
> } /* ixv_set_ivar */
1926a1706,1708
> /************************************************************************
> * ixv_configure_ivars
> ************************************************************************/
1930c1712
< struct ix_queue *que = adapter->queues;
---
> struct ix_queue *que = adapter->queues;
1932c1714
< for (int i = 0; i < adapter->num_queues; i++, que++) {
---
> for (int i = 0; i < adapter->num_queues; i++, que++) {
1934c1716
< ixv_set_ivar(adapter, i, que->msix, 0);
---
> ixv_set_ivar(adapter, i, que->msix, 0);
1938,1939c1720,1721
< IXGBE_WRITE_REG(&adapter->hw,
< IXGBE_VTEITR(que->msix), IXV_EITR_DEFAULT);
---
> IXGBE_WRITE_REG(&adapter->hw, IXGBE_VTEITR(que->msix),
> IXGBE_EITR_DEFAULT);
1943,1944c1725,1726
< ixv_set_ivar(adapter, 1, adapter->vector, -1);
< }
---
> ixv_set_ivar(adapter, 1, adapter->vector, -1);
> } /* ixv_configure_ivars */
1947,1952c1729,1733
< /*
< ** Tasklet handler for MSIX MBX interrupts
< ** - do outside interrupt since it might sleep
< */
< static void
< ixv_handle_mbx(void *context, int pending)
---
> /************************************************************************
> * ixv_get_counter
> ************************************************************************/
> static uint64_t
> ixv_get_counter(struct ifnet *ifp, ift_counter cnt)
1954c1735
< struct adapter *adapter = context;
---
> struct adapter *adapter;
1956,1959c1737
< ixgbe_check_link(&adapter->hw,
< &adapter->link_speed, &adapter->link_up, 0);
< ixv_update_link_status(adapter);
< }
---
> adapter = if_getsoftc(ifp);
1961,1966c1739,1762
< /*
< ** The VF stats registers never have a truly virgin
< ** starting point, so this routine tries to make an
< ** artificial one, marking ground zero on attach as
< ** it were.
< */
---
> switch (cnt) {
> case IFCOUNTER_IPACKETS:
> return (adapter->ipackets);
> case IFCOUNTER_OPACKETS:
> return (adapter->opackets);
> case IFCOUNTER_IBYTES:
> return (adapter->ibytes);
> case IFCOUNTER_OBYTES:
> return (adapter->obytes);
> case IFCOUNTER_IMCASTS:
> return (adapter->imcasts);
> default:
> return (if_get_counter_default(ifp, cnt));
> }
> } /* ixv_get_counter */
>
> /************************************************************************
> * ixv_save_stats
> *
> * The VF stats registers never have a truly virgin
> * starting point, so this routine tries to make an
> * artificial one, marking ground zero on attach as
> * it were.
> ************************************************************************/
1982,1983c1778,1782
< }
<
---
> } /* ixv_save_stats */
>
> /************************************************************************
> * ixv_init_stats
> ************************************************************************/
1988c1787
<
---
>
2006c1805
< }
---
> } /* ixv_init_stats */
2008,2015c1807,1814
< #define UPDATE_STAT_32(reg, last, count) \
< { \
< u32 current = IXGBE_READ_REG(hw, reg); \
< if (current < last) \
< count += 0x100000000LL; \
< last = current; \
< count &= 0xFFFFFFFF00000000LL; \
< count |= current; \
---
> #define UPDATE_STAT_32(reg, last, count) \
> { \
> u32 current = IXGBE_READ_REG(hw, reg); \
> if (current < last) \
> count += 0x100000000LL; \
> last = current; \
> count &= 0xFFFFFFFF00000000LL; \
> count |= current; \
2018,2027c1817,1826
< #define UPDATE_STAT_36(lsb, msb, last, count) \
< { \
< u64 cur_lsb = IXGBE_READ_REG(hw, lsb); \
< u64 cur_msb = IXGBE_READ_REG(hw, msb); \
< u64 current = ((cur_msb << 32) | cur_lsb); \
< if (current < last) \
< count += 0x1000000000LL; \
< last = current; \
< count &= 0xFFFFFFF000000000LL; \
< count |= current; \
---
> #define UPDATE_STAT_36(lsb, msb, last, count) \
> { \
> u64 cur_lsb = IXGBE_READ_REG(hw, lsb); \
> u64 cur_msb = IXGBE_READ_REG(hw, msb); \
> u64 current = ((cur_msb << 32) | cur_lsb); \
> if (current < last) \
> count += 0x1000000000LL; \
> last = current; \
> count &= 0xFFFFFFF000000000LL; \
> count |= current; \
2030,2032c1829,1831
< /*
< ** ixv_update_stats - Update the board statistics counters.
< */
---
> /************************************************************************
> * ixv_update_stats - Update the board statistics counters.
> ************************************************************************/
2036c1835,1836
< struct ixgbe_hw *hw = &adapter->hw;
---
> struct ixgbe_hw *hw = &adapter->hw;
> struct ixgbevf_hw_stats *stats = &adapter->stats.vf;
2048d1847
< }
2050,2052c1849,1859
< /*
< * Add statistic sysctls for the VF.
< */
---
> /* Fill out the OS statistics structure */
> IXGBE_SET_IPACKETS(adapter, stats->vfgprc);
> IXGBE_SET_OPACKETS(adapter, stats->vfgptc);
> IXGBE_SET_IBYTES(adapter, stats->vfgorc);
> IXGBE_SET_OBYTES(adapter, stats->vfgotc);
> IXGBE_SET_IMCASTS(adapter, stats->vfmprc);
> } /* ixv_update_stats */
>
> /************************************************************************
> * ixv_add_stats_sysctls - Add statistic sysctls for the VF.
> ************************************************************************/
2056,2063c1863,1868
< device_t dev = adapter->dev;
< struct ix_queue *que = &adapter->queues[0];
< struct tx_ring *txr = que->txr;
< struct rx_ring *rxr = que->rxr;
<
< struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
< struct sysctl_oid *tree = device_get_sysctl_tree(dev);
< struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
---
> device_t dev = adapter->dev;
> struct tx_ring *txr = adapter->tx_rings;
> struct rx_ring *rxr = adapter->rx_rings;
> struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
> struct sysctl_oid *tree = device_get_sysctl_tree(dev);
> struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
2064a1870,1871
> struct sysctl_oid *stat_node, *queue_node;
> struct sysctl_oid_list *stat_list, *queue_list;
2066,2067c1873,1874
< struct sysctl_oid *stat_node, *queue_node;
< struct sysctl_oid_list *stat_list, *queue_list;
---
> #define QUEUE_NAME_LEN 32
> char namebuf[QUEUE_NAME_LEN];
2071,2072c1878
< CTLFLAG_RD, &adapter->dropped_pkts,
< "Driver dropped packets");
---
> CTLFLAG_RD, &adapter->dropped_pkts, "Driver dropped packets");
2074,2075c1880
< CTLFLAG_RD, &adapter->mbuf_defrag_failed,
< "m_defrag() failed");
---
> CTLFLAG_RD, &adapter->mbuf_defrag_failed, "m_defrag() failed");
2077,2078c1882,1884
< CTLFLAG_RD, &adapter->watchdog_events,
< "Watchdog timeouts");
---
> CTLFLAG_RD, &adapter->watchdog_events, "Watchdog timeouts");
> SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq",
> CTLFLAG_RD, &adapter->link_irq, "Link MSI-X IRQ Handled");
2079a1886,1920
> for (int i = 0; i < adapter->num_queues; i++, txr++) {
> snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i);
> queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
> CTLFLAG_RD, NULL, "Queue Name");
> queue_list = SYSCTL_CHILDREN(queue_node);
>
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs",
> CTLFLAG_RD, &(adapter->queues[i].irqs), "IRQs on queue");
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "no_tx_dma_setup",
> CTLFLAG_RD, &(txr->no_tx_dma_setup),
> "Driver Tx DMA failure in Tx");
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc",
> CTLFLAG_RD, &(txr->no_desc_avail),
> "Not-enough-descriptors count: TX");
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets",
> CTLFLAG_RD, &(txr->total_packets), "TX Packets");
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "br_drops",
> CTLFLAG_RD, &(txr->br->br_drops),
> "Packets dropped in buf_ring");
> }
>
> for (int i = 0; i < adapter->num_queues; i++, rxr++) {
> snprintf(namebuf, QUEUE_NAME_LEN, "queue%d", i);
> queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
> CTLFLAG_RD, NULL, "Queue Name");
> queue_list = SYSCTL_CHILDREN(queue_node);
>
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets",
> CTLFLAG_RD, &(rxr->rx_packets), "RX packets");
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes",
> CTLFLAG_RD, &(rxr->rx_bytes), "RX bytes");
> SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_discarded",
> CTLFLAG_RD, &(rxr->rx_discarded), "Discarded RX packets");
> }
>
2081,2082c1922
< CTLFLAG_RD, NULL,
< "VF Statistics (read from HW registers)");
---
> CTLFLAG_RD, NULL, "VF Statistics (read from HW registers)");
2086,2087c1926
< CTLFLAG_RD, &stats->vfgprc,
< "Good Packets Received");
---
> CTLFLAG_RD, &stats->vfgprc, "Good Packets Received");
2089,2090c1928
< CTLFLAG_RD, &stats->vfgorc,
< "Good Octets Received");
---
> CTLFLAG_RD, &stats->vfgorc, "Good Octets Received");
2092,2093c1930
< CTLFLAG_RD, &stats->vfmprc,
< "Multicast Packets Received");
---
> CTLFLAG_RD, &stats->vfmprc, "Multicast Packets Received");
2095,2096c1932
< CTLFLAG_RD, &stats->vfgptc,
< "Good Packets Transmitted");
---
> CTLFLAG_RD, &stats->vfgptc, "Good Packets Transmitted");
2098,2099c1934,1935
< CTLFLAG_RD, &stats->vfgotc,
< "Good Octets Transmitted");
---
> CTLFLAG_RD, &stats->vfgotc, "Good Octets Transmitted");
> } /* ixv_add_stats_sysctls */
2101,2130c1937,1939
< queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "que",
< CTLFLAG_RD, NULL,
< "Queue Statistics (collected by SW)");
< queue_list = SYSCTL_CHILDREN(queue_node);
<
< SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "irqs",
< CTLFLAG_RD, &(que->irqs),
< "IRQs on queue");
< SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_irqs",
< CTLFLAG_RD, &(rxr->rx_irq),
< "RX irqs on queue");
< SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_packets",
< CTLFLAG_RD, &(rxr->rx_packets),
< "RX packets");
< SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_bytes",
< CTLFLAG_RD, &(rxr->rx_bytes),
< "RX bytes");
< SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "rx_discarded",
< CTLFLAG_RD, &(rxr->rx_discarded),
< "Discarded RX packets");
<
< SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_packets",
< CTLFLAG_RD, &(txr->total_packets),
< "TX Packets");
<
< SYSCTL_ADD_UQUAD(ctx, queue_list, OID_AUTO, "tx_no_desc",
< CTLFLAG_RD, &(txr->no_desc_avail),
< "# of times not enough descriptors were available during TX");
< }
<
---
> /************************************************************************
> * ixv_set_sysctl_value
> ************************************************************************/
2139c1948
< }
---
> } /* ixv_set_sysctl_value */
2141c1950,1951
< /**********************************************************************
---
> /************************************************************************
> * ixv_print_debug_info
2143,2147c1953,1956
< * This routine is called only when em_display_debug_stats is enabled.
< * This routine provides a way to take a look at important statistics
< * maintained by the driver and hardware.
< *
< **********************************************************************/
---
> * Called only when em_display_debug_stats is enabled.
> * Provides a way to take a look at important statistics
> * maintained by the driver and hardware.
> ************************************************************************/
2151,2156c1960,1965
< device_t dev = adapter->dev;
< struct ixgbe_hw *hw = &adapter->hw;
< struct ix_queue *que = adapter->queues;
< struct rx_ring *rxr;
< struct tx_ring *txr;
< struct lro_ctrl *lro;
---
> device_t dev = adapter->dev;
> struct ixgbe_hw *hw = &adapter->hw;
> struct ix_queue *que = adapter->queues;
> struct rx_ring *rxr;
> struct tx_ring *txr;
> struct lro_ctrl *lro;
2158,2159c1967,1968
< device_printf(dev,"Error Byte Count = %u \n",
< IXGBE_READ_REG(hw, IXGBE_ERRBC));
---
> device_printf(dev, "Error Byte Count = %u \n",
> IXGBE_READ_REG(hw, IXGBE_ERRBC));
2161,2179c1970,1988
< for (int i = 0; i < adapter->num_queues; i++, que++) {
< txr = que->txr;
< rxr = que->rxr;
< lro = &rxr->lro;
< device_printf(dev,"QUE(%d) IRQs Handled: %lu\n",
< que->msix, (long)que->irqs);
< device_printf(dev,"RX(%d) Packets Received: %lld\n",
< rxr->me, (long long)rxr->rx_packets);
< device_printf(dev,"RX(%d) Bytes Received: %lu\n",
< rxr->me, (long)rxr->rx_bytes);
< device_printf(dev,"RX(%d) LRO Queued= %lld\n",
< rxr->me, (long long)lro->lro_queued);
< device_printf(dev,"RX(%d) LRO Flushed= %lld\n",
< rxr->me, (long long)lro->lro_flushed);
< device_printf(dev,"TX(%d) Packets Sent: %lu\n",
< txr->me, (long)txr->total_packets);
< device_printf(dev,"TX(%d) NO Desc Avail: %lu\n",
< txr->me, (long)txr->no_desc_avail);
< }
---
> for (int i = 0; i < adapter->num_queues; i++, que++) {
> txr = que->txr;
> rxr = que->rxr;
> lro = &rxr->lro;
> device_printf(dev, "QUE(%d) IRQs Handled: %lu\n",
> que->msix, (long)que->irqs);
> device_printf(dev, "RX(%d) Packets Received: %lld\n",
> rxr->me, (long long)rxr->rx_packets);
> device_printf(dev, "RX(%d) Bytes Received: %lu\n",
> rxr->me, (long)rxr->rx_bytes);
> device_printf(dev, "RX(%d) LRO Queued= %lld\n",
> rxr->me, (long long)lro->lro_queued);
> device_printf(dev, "RX(%d) LRO Flushed= %lld\n",
> rxr->me, (long long)lro->lro_flushed);
> device_printf(dev, "TX(%d) Packets Sent: %lu\n",
> txr->me, (long)txr->total_packets);
> device_printf(dev, "TX(%d) NO Desc Avail: %lu\n",
> txr->me, (long)txr->no_desc_avail);
> }
2181,2184c1990,1991
< device_printf(dev,"MBX IRQ Handled: %lu\n",
< (long)adapter->link_irq);
< return;
< }
---
> device_printf(dev, "MBX IRQ Handled: %lu\n", (long)adapter->link_irq);
> } /* ixv_print_debug_info */
2185a1993,1995
> /************************************************************************
> * ixv_sysctl_debug
> ************************************************************************/
2189d1998
< int error, result;
2190a2000
> int error, result;
2199c2009
< adapter = (struct adapter *) arg1;
---
> adapter = (struct adapter *)arg1;
2201a2012
>
2203c2014
< }
---
> } /* ixv_sysctl_debug */
2204a2016,2416
> /************************************************************************
> * ixv_init_device_features
> ************************************************************************/
> static void
> ixv_init_device_features(struct adapter *adapter)
> {
> adapter->feat_cap = IXGBE_FEATURE_NETMAP
> | IXGBE_FEATURE_VF
> | IXGBE_FEATURE_RSS
> | IXGBE_FEATURE_LEGACY_TX;
>
> /* A tad short on feature flags for VFs, atm. */
> switch (adapter->hw.mac.type) {
> case ixgbe_mac_82599_vf:
> break;
> case ixgbe_mac_X540_vf:
> break;
> case ixgbe_mac_X550_vf:
> case ixgbe_mac_X550EM_x_vf:
> case ixgbe_mac_X550EM_a_vf:
> adapter->feat_cap |= IXGBE_FEATURE_NEEDS_CTXD;
> break;
> default:
> break;
> }
>
> /* Enabled by default... */
> /* Is a virtual function (VF) */
> if (adapter->feat_cap & IXGBE_FEATURE_VF)
> adapter->feat_en |= IXGBE_FEATURE_VF;
> /* Netmap */
> if (adapter->feat_cap & IXGBE_FEATURE_NETMAP)
> adapter->feat_en |= IXGBE_FEATURE_NETMAP;
> /* Receive-Side Scaling (RSS) */
> if (adapter->feat_cap & IXGBE_FEATURE_RSS)
> adapter->feat_en |= IXGBE_FEATURE_RSS;
> /* Needs advanced context descriptor regardless of offloads req'd */
> if (adapter->feat_cap & IXGBE_FEATURE_NEEDS_CTXD)
> adapter->feat_en |= IXGBE_FEATURE_NEEDS_CTXD;
>
> /* Enabled via sysctl... */
> /* Legacy (single queue) transmit */
> if ((adapter->feat_cap & IXGBE_FEATURE_LEGACY_TX) &&
> ixv_enable_legacy_tx)
> adapter->feat_en |= IXGBE_FEATURE_LEGACY_TX;
> } /* ixv_init_device_features */
>
> /************************************************************************
> * ixv_shutdown - Shutdown entry point
> ************************************************************************/
> static int
> ixv_shutdown(device_t dev)
> {
> struct adapter *adapter = device_get_softc(dev);
> IXGBE_CORE_LOCK(adapter);
> ixv_stop(adapter);
> IXGBE_CORE_UNLOCK(adapter);
>
> return (0);
> } /* ixv_shutdown */
>
>
> /************************************************************************
> * ixv_ioctl - Ioctl entry point
> *
> * Called when the user wants to configure the interface.
> *
> * return 0 on success, positive on failure
> ************************************************************************/
> static int
> ixv_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
> {
> struct adapter *adapter = ifp->if_softc;
> struct ifreq *ifr = (struct ifreq *)data;
> #if defined(INET) || defined(INET6)
> struct ifaddr *ifa = (struct ifaddr *)data;
> bool avoid_reset = FALSE;
> #endif
> int error = 0;
>
> switch (command) {
>
> case SIOCSIFADDR:
> #ifdef INET
> if (ifa->ifa_addr->sa_family == AF_INET)
> avoid_reset = TRUE;
> #endif
> #ifdef INET6
> if (ifa->ifa_addr->sa_family == AF_INET6)
> avoid_reset = TRUE;
> #endif
> #if defined(INET) || defined(INET6)
> /*
> * Calling init results in link renegotiation,
> * so we avoid doing it when possible.
> */
> if (avoid_reset) {
> ifp->if_flags |= IFF_UP;
> if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
> ixv_init(adapter);
> if (!(ifp->if_flags & IFF_NOARP))
> arp_ifinit(ifp, ifa);
> } else
> error = ether_ioctl(ifp, command, data);
> break;
> #endif
> case SIOCSIFMTU:
> IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)");
> if (ifr->ifr_mtu > IXGBE_MAX_MTU) {
> error = EINVAL;
> } else {
> IXGBE_CORE_LOCK(adapter);
> ifp->if_mtu = ifr->ifr_mtu;
> adapter->max_frame_size = ifp->if_mtu + IXGBE_MTU_HDR;
> if (ifp->if_drv_flags & IFF_DRV_RUNNING)
> ixv_init_locked(adapter);
> IXGBE_CORE_UNLOCK(adapter);
> }
> break;
> case SIOCSIFFLAGS:
> IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)");
> IXGBE_CORE_LOCK(adapter);
> if (ifp->if_flags & IFF_UP) {
> if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
> ixv_init_locked(adapter);
> } else
> if (ifp->if_drv_flags & IFF_DRV_RUNNING)
> ixv_stop(adapter);
> adapter->if_flags = ifp->if_flags;
> IXGBE_CORE_UNLOCK(adapter);
> break;
> case SIOCADDMULTI:
> case SIOCDELMULTI:
> IOCTL_DEBUGOUT("ioctl: SIOC(ADD|DEL)MULTI");
> if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
> IXGBE_CORE_LOCK(adapter);
> ixv_disable_intr(adapter);
> ixv_set_multi(adapter);
> ixv_enable_intr(adapter);
> IXGBE_CORE_UNLOCK(adapter);
> }
> break;
> case SIOCSIFMEDIA:
> case SIOCGIFMEDIA:
> IOCTL_DEBUGOUT("ioctl: SIOCxIFMEDIA (Get/Set Interface Media)");
> error = ifmedia_ioctl(ifp, ifr, &adapter->media, command);
> break;
> case SIOCSIFCAP:
> {
> int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
> IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)");
> if (mask & IFCAP_HWCSUM)
> ifp->if_capenable ^= IFCAP_HWCSUM;
> if (mask & IFCAP_TSO4)
> ifp->if_capenable ^= IFCAP_TSO4;
> if (mask & IFCAP_LRO)
> ifp->if_capenable ^= IFCAP_LRO;
> if (mask & IFCAP_VLAN_HWTAGGING)
> ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
> if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
> IXGBE_CORE_LOCK(adapter);
> ixv_init_locked(adapter);
> IXGBE_CORE_UNLOCK(adapter);
> }
> VLAN_CAPABILITIES(ifp);
> break;
> }
>
> default:
> IOCTL_DEBUGOUT1("ioctl: UNKNOWN (0x%X)\n", (int)command);
> error = ether_ioctl(ifp, command, data);
> break;
> }
>
> return (error);
> } /* ixv_ioctl */
>
> /************************************************************************
> * ixv_init
> ************************************************************************/
> static void
> ixv_init(void *arg)
> {
> struct adapter *adapter = arg;
>
> IXGBE_CORE_LOCK(adapter);
> ixv_init_locked(adapter);
> IXGBE_CORE_UNLOCK(adapter);
>
> return;
> } /* ixv_init */
>
>
> /************************************************************************
> * ixv_handle_que
> ************************************************************************/
> static void
> ixv_handle_que(void *context, int pending)
> {
> struct ix_queue *que = context;
> struct adapter *adapter = que->adapter;
> struct tx_ring *txr = que->txr;
> struct ifnet *ifp = adapter->ifp;
> bool more;
>
> if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
> more = ixgbe_rxeof(que);
> IXGBE_TX_LOCK(txr);
> ixgbe_txeof(txr);
> if (!ixv_ring_empty(ifp, txr->br))
> ixv_start_locked(ifp, txr);
> IXGBE_TX_UNLOCK(txr);
> if (more) {
> taskqueue_enqueue(que->tq, &que->que_task);
> return;
> }
> }
>
> /* Re-enable this interrupt */
> ixv_enable_queue(adapter, que->msix);
>
> return;
> } /* ixv_handle_que */
>
> /************************************************************************
> * ixv_allocate_msix - Setup MSI-X Interrupt resources and handlers
> ************************************************************************/
> static int
> ixv_allocate_msix(struct adapter *adapter)
> {
> device_t dev = adapter->dev;
> struct ix_queue *que = adapter->queues;
> struct tx_ring *txr = adapter->tx_rings;
> int error, msix_ctrl, rid, vector = 0;
>
> for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
> rid = vector + 1;
> que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
> RF_SHAREABLE | RF_ACTIVE);
> if (que->res == NULL) {
> device_printf(dev, "Unable to allocate bus resource: que interrupt [%d]\n",
> vector);
> return (ENXIO);
> }
> /* Set the handler function */
> error = bus_setup_intr(dev, que->res,
> INTR_TYPE_NET | INTR_MPSAFE, NULL,
> ixv_msix_que, que, &que->tag);
> if (error) {
> que->res = NULL;
> device_printf(dev, "Failed to register QUE handler");
> return (error);
> }
> #if __FreeBSD_version >= 800504
> bus_describe_intr(dev, que->res, que->tag, "que %d", i);
> #endif
> que->msix = vector;
> adapter->active_queues |= (u64)(1 << que->msix);
> /*
> * Bind the MSI-X vector, and thus the
> * ring to the corresponding CPU.
> */
> if (adapter->num_queues > 1)
> bus_bind_intr(dev, que->res, i);
> TASK_INIT(&txr->txq_task, 0, ixgbe_deferred_mq_start, txr);
> TASK_INIT(&que->que_task, 0, ixv_handle_que, que);
> que->tq = taskqueue_create_fast("ixv_que", M_NOWAIT,
> taskqueue_thread_enqueue, &que->tq);
> taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que",
> device_get_nameunit(adapter->dev));
> }
>
> /* and Mailbox */
> rid = vector + 1;
> adapter->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
> RF_SHAREABLE | RF_ACTIVE);
> if (!adapter->res) {
> device_printf(dev,
> "Unable to allocate bus resource: MBX interrupt [%d]\n",
> rid);
> return (ENXIO);
> }
> /* Set the mbx handler function */
> error = bus_setup_intr(dev, adapter->res, INTR_TYPE_NET | INTR_MPSAFE,
> NULL, ixv_msix_mbx, adapter, &adapter->tag);
> if (error) {
> adapter->res = NULL;
> device_printf(dev, "Failed to register LINK handler");
> return (error);
> }
> #if __FreeBSD_version >= 800504
> bus_describe_intr(dev, adapter->res, adapter->tag, "mbx");
> #endif
> adapter->vector = vector;
> /* Tasklets for Mailbox */
> TASK_INIT(&adapter->link_task, 0, ixv_handle_link, adapter);
> adapter->tq = taskqueue_create_fast("ixv_mbx", M_NOWAIT,
> taskqueue_thread_enqueue, &adapter->tq);
> taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s mbxq",
> device_get_nameunit(adapter->dev));
> /*
> * Due to a broken design QEMU will fail to properly
> * enable the guest for MSI-X unless the vectors in
> * the table are all set up, so we must rewrite the
> * ENABLE in the MSI-X control register again at this
> * point to cause it to successfully initialize us.
> */
> if (adapter->hw.mac.type == ixgbe_mac_82599_vf) {
> pci_find_cap(dev, PCIY_MSIX, &rid);
> rid += PCIR_MSIX_CTRL;
> msix_ctrl = pci_read_config(dev, rid, 2);
> msix_ctrl |= PCIM_MSIXCTRL_MSIX_ENABLE;
> pci_write_config(dev, rid, msix_ctrl, 2);
> }
>
> return (0);
> } /* ixv_allocate_msix */
>
> /************************************************************************
> * ixv_configure_interrupts - Setup MSI-X resources
> *
> * Note: The VF device MUST use MSI-X, there is no fallback.
> ************************************************************************/
> static int
> ixv_configure_interrupts(struct adapter *adapter)
> {
> device_t dev = adapter->dev;
> int rid, want, msgs;
>
> /* Must have at least 2 MSI-X vectors */
> msgs = pci_msix_count(dev);
> if (msgs < 2)
> goto out;
> rid = PCIR_BAR(3);
> adapter->msix_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
> RF_ACTIVE);
> if (adapter->msix_mem == NULL) {
> device_printf(adapter->dev, "Unable to map MSI-X table \n");
> goto out;
> }
>
> /*
> * Want vectors for the queues,
> * plus an additional for mailbox.
> */
> want = adapter->num_queues + 1;
> if (want > msgs) {
> want = msgs;
> adapter->num_queues = msgs - 1;
> } else
> msgs = want;
> if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
> device_printf(adapter->dev,
> "Using MSI-X interrupts with %d vectors\n", want);
> /* reflect correct sysctl value */
> ixv_num_queues = adapter->num_queues;
>
> return (0);
> }
> /* Release in case alloc was insufficient */
> pci_release_msi(dev);
> out:
> if (adapter->msix_mem != NULL) {
> bus_release_resource(dev, SYS_RES_MEMORY, rid,
> adapter->msix_mem);
> adapter->msix_mem = NULL;
> }
> device_printf(adapter->dev, "MSI-X config error\n");
>
> return (ENXIO);
> } /* ixv_configure_interrupts */
>
>
> /************************************************************************
> * ixv_handle_link - Tasklet handler for MSI-X MBX interrupts
> *
> * Done outside of interrupt context since the driver might sleep
> ************************************************************************/
> static void
> ixv_handle_link(void *context, int pending)
> {
> struct adapter *adapter = context;
>
> adapter->hw.mac.ops.check_link(&adapter->hw, &adapter->link_speed,
> &adapter->link_up, FALSE);
> ixv_update_link_status(adapter);
> } /* ixv_handle_link */
>
> /************************************************************************
> * ixv_check_link - Used in the local timer to poll for link changes
> ************************************************************************/
> static void
> ixv_check_link(struct adapter *adapter)
> {
> adapter->hw.mac.get_link_status = TRUE;
>
> adapter->hw.mac.ops.check_link(&adapter->hw, &adapter->link_speed,
> &adapter->link_up, FALSE);
> ixv_update_link_status(adapter);
> } /* ixv_check_link */
>