Changeset View
Changeset View
Standalone View
Standalone View
stable/10/sys/dev/ixgbe/if_ixv.c
Show All 37 Lines | |||||
#include "opt_inet6.h" | #include "opt_inet6.h" | ||||
#endif | #endif | ||||
#include "ixgbe.h" | #include "ixgbe.h" | ||||
/********************************************************************* | /********************************************************************* | ||||
* Driver version | * Driver version | ||||
*********************************************************************/ | *********************************************************************/ | ||||
char ixv_driver_version[] = "1.4.0"; | char ixv_driver_version[] = "1.4.6-k"; | ||||
/********************************************************************* | /********************************************************************* | ||||
* PCI Device ID Table | * PCI Device ID Table | ||||
* | * | ||||
* Used by probe to select devices to load on | * Used by probe to select devices to load on | ||||
* Last field stores an index into ixv_strings | * Last field stores an index into ixv_strings | ||||
* Last entry must be all 0s | * Last entry must be all 0s | ||||
* | * | ||||
▲ Show 20 Lines • Show All 232 Lines • ▼ Show 20 Lines | ixv_attach(device_t dev) | ||||
struct adapter *adapter; | struct adapter *adapter; | ||||
struct ixgbe_hw *hw; | struct ixgbe_hw *hw; | ||||
int error = 0; | int error = 0; | ||||
INIT_DEBUGOUT("ixv_attach: begin"); | INIT_DEBUGOUT("ixv_attach: begin"); | ||||
/* Allocate, clear, and link in our adapter structure */ | /* Allocate, clear, and link in our adapter structure */ | ||||
adapter = device_get_softc(dev); | adapter = device_get_softc(dev); | ||||
adapter->dev = adapter->osdep.dev = dev; | adapter->dev = dev; | ||||
hw = &adapter->hw; | hw = &adapter->hw; | ||||
#ifdef DEV_NETMAP | |||||
adapter->init_locked = ixv_init_locked; | |||||
adapter->stop_locked = ixv_stop; | |||||
#endif | |||||
/* Core Lock Init*/ | /* Core Lock Init*/ | ||||
IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); | IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); | ||||
/* SYSCTL APIs */ | /* SYSCTL APIs */ | ||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), | ||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | ||||
OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW, | OID_AUTO, "debug", CTLTYPE_INT | CTLFLAG_RW, | ||||
adapter, 0, ixv_sysctl_debug, "I", "Debug Info"); | adapter, 0, ixv_sysctl_debug, "I", "Debug Info"); | ||||
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), | SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), | ||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | ||||
OID_AUTO, "enable_aim", CTLFLAG_RW, | OID_AUTO, "enable_aim", CTLFLAG_RW, | ||||
&ixv_enable_aim, 1, "Interrupt Moderation"); | &ixv_enable_aim, 1, "Interrupt Moderation"); | ||||
/* Set up the timer callout */ | /* Set up the timer callout */ | ||||
callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); | callout_init_mtx(&adapter->timer, &adapter->core_mtx, 0); | ||||
/* Determine hardware revision */ | /* Determine hardware revision */ | ||||
ixv_identify_hardware(adapter); | ixv_identify_hardware(adapter); | ||||
/* Do base PCI setup - map BAR0 */ | /* Do base PCI setup - map BAR0 */ | ||||
if (ixv_allocate_pci_resources(adapter)) { | if (ixv_allocate_pci_resources(adapter)) { | ||||
device_printf(dev, "Allocation of PCI resources failed\n"); | device_printf(dev, "ixv_allocate_pci_resources() failed!\n"); | ||||
error = ENXIO; | error = ENXIO; | ||||
goto err_out; | goto err_out; | ||||
} | } | ||||
/* Sysctls for limiting the amount of work done in the taskqueues */ | /* Sysctls for limiting the amount of work done in the taskqueues */ | ||||
ixv_set_sysctl_value(adapter, "rx_processing_limit", | ixv_set_sysctl_value(adapter, "rx_processing_limit", | ||||
"max number of rx packets to process", | "max number of rx packets to process", | ||||
&adapter->rx_process_limit, ixv_rx_process_limit); | &adapter->rx_process_limit, ixv_rx_process_limit); | ||||
Show All 23 Lines | if (((ixv_rxd * sizeof(union ixgbe_adv_rx_desc)) % DBA_ALIGN) != 0 || | ||||
ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD) { | ixv_rxd < MIN_RXD || ixv_rxd > MAX_RXD) { | ||||
device_printf(dev, "RXD config issue, using default!\n"); | device_printf(dev, "RXD config issue, using default!\n"); | ||||
adapter->num_rx_desc = DEFAULT_RXD; | adapter->num_rx_desc = DEFAULT_RXD; | ||||
} else | } else | ||||
adapter->num_rx_desc = ixv_rxd; | adapter->num_rx_desc = ixv_rxd; | ||||
/* Allocate our TX/RX Queues */ | /* Allocate our TX/RX Queues */ | ||||
if (ixgbe_allocate_queues(adapter)) { | if (ixgbe_allocate_queues(adapter)) { | ||||
device_printf(dev, "ixgbe_allocate_queues() failed!\n"); | |||||
error = ENOMEM; | error = ENOMEM; | ||||
goto err_out; | goto err_out; | ||||
} | } | ||||
/* | /* | ||||
** Initialize the shared code: its | ** Initialize the shared code: its | ||||
** at this point the mac type is set. | ** at this point the mac type is set. | ||||
*/ | */ | ||||
error = ixgbe_init_shared_code(hw); | error = ixgbe_init_shared_code(hw); | ||||
if (error) { | if (error) { | ||||
device_printf(dev,"Shared Code Initialization Failure\n"); | device_printf(dev, "ixgbe_init_shared_code() failed!\n"); | ||||
error = EIO; | error = EIO; | ||||
goto err_late; | goto err_late; | ||||
} | } | ||||
/* Setup the mailbox */ | /* Setup the mailbox */ | ||||
ixgbe_init_mbx_params_vf(hw); | ixgbe_init_mbx_params_vf(hw); | ||||
ixgbe_reset_hw(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); | |||||
if (error) { | |||||
error = EIO; | |||||
goto err_late; | |||||
} | |||||
/* Get the Mailbox API version */ | /* Negotiate mailbox API version */ | ||||
device_printf(dev,"MBX API %d negotiation: %d\n", | error = ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11); | ||||
ixgbe_mbox_api_11, | if (error) { | ||||
ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11)); | device_printf(dev, "MBX API 1.1 negotiation failed! Error %d\n", error); | ||||
error = EIO; | |||||
goto err_late; | |||||
} | |||||
error = ixgbe_init_hw(hw); | error = ixgbe_init_hw(hw); | ||||
if (error) { | if (error) { | ||||
device_printf(dev,"Hardware Initialization Failure\n"); | device_printf(dev, "ixgbe_init_hw() failed!\n"); | ||||
error = EIO; | error = EIO; | ||||
goto err_late; | goto err_late; | ||||
} | } | ||||
error = ixv_allocate_msix(adapter); | error = ixv_allocate_msix(adapter); | ||||
if (error) | if (error) { | ||||
device_printf(dev, "ixv_allocate_msix() failed!\n"); | |||||
goto err_late; | goto err_late; | ||||
} | |||||
/* If no mac address was assigned, make a random one */ | /* If no mac address was assigned, make a random one */ | ||||
if (!ixv_check_ether_addr(hw->mac.addr)) { | if (!ixv_check_ether_addr(hw->mac.addr)) { | ||||
u8 addr[ETHER_ADDR_LEN]; | u8 addr[ETHER_ADDR_LEN]; | ||||
arc4rand(&addr, sizeof(addr), 0); | arc4rand(&addr, sizeof(addr), 0); | ||||
addr[0] &= 0xFE; | addr[0] &= 0xFE; | ||||
addr[0] |= 0x02; | addr[0] |= 0x02; | ||||
bcopy(addr, hw->mac.addr, sizeof(addr)); | bcopy(addr, hw->mac.addr, sizeof(addr)); | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct adapter *adapter = device_get_softc(dev); | struct adapter *adapter = device_get_softc(dev); | ||||
struct ix_queue *que = adapter->queues; | struct ix_queue *que = adapter->queues; | ||||
INIT_DEBUGOUT("ixv_detach: begin"); | INIT_DEBUGOUT("ixv_detach: begin"); | ||||
/* Make sure VLANS are not using driver */ | /* Make sure VLANS are not using driver */ | ||||
if (adapter->ifp->if_vlantrunk != NULL) { | if (adapter->ifp->if_vlantrunk != NULL) { | ||||
device_printf(dev,"Vlan in use, detach first\n"); | device_printf(dev, "Vlan in use, detach first\n"); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
IXGBE_CORE_LOCK(adapter); | IXGBE_CORE_LOCK(adapter); | ||||
ixv_stop(adapter); | ixv_stop(adapter); | ||||
IXGBE_CORE_UNLOCK(adapter); | IXGBE_CORE_UNLOCK(adapter); | ||||
for (int i = 0; i < adapter->num_queues; i++, que++) { | for (int i = 0; i < adapter->num_queues; i++, que++) { | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | if (avoid_reset) { | ||||
if (!(ifp->if_flags & IFF_NOARP)) | if (!(ifp->if_flags & IFF_NOARP)) | ||||
arp_ifinit(ifp, ifa); | arp_ifinit(ifp, ifa); | ||||
} else | } else | ||||
error = ether_ioctl(ifp, command, data); | error = ether_ioctl(ifp, command, data); | ||||
break; | break; | ||||
#endif | #endif | ||||
case SIOCSIFMTU: | case SIOCSIFMTU: | ||||
IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); | IOCTL_DEBUGOUT("ioctl: SIOCSIFMTU (Set Interface MTU)"); | ||||
if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - ETHER_HDR_LEN) { | if (ifr->ifr_mtu > IXGBE_MAX_FRAME_SIZE - IXGBE_MTU_HDR) { | ||||
error = EINVAL; | error = EINVAL; | ||||
} else { | } else { | ||||
IXGBE_CORE_LOCK(adapter); | IXGBE_CORE_LOCK(adapter); | ||||
ifp->if_mtu = ifr->ifr_mtu; | ifp->if_mtu = ifr->ifr_mtu; | ||||
adapter->max_frame_size = | adapter->max_frame_size = | ||||
ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; | ifp->if_mtu + IXGBE_MTU_HDR; | ||||
ixv_init_locked(adapter); | ixv_init_locked(adapter); | ||||
IXGBE_CORE_UNLOCK(adapter); | IXGBE_CORE_UNLOCK(adapter); | ||||
} | } | ||||
break; | break; | ||||
case SIOCSIFFLAGS: | case SIOCSIFFLAGS: | ||||
IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)"); | IOCTL_DEBUGOUT("ioctl: SIOCSIFFLAGS (Set Interface Flags)"); | ||||
IXGBE_CORE_LOCK(adapter); | IXGBE_CORE_LOCK(adapter); | ||||
if (ifp->if_flags & IFF_UP) { | if (ifp->if_flags & IFF_UP) { | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
#define IXGBE_MHADD_MFS_SHIFT 16 | #define IXGBE_MHADD_MFS_SHIFT 16 | ||||
static void | static void | ||||
ixv_init_locked(struct adapter *adapter) | ixv_init_locked(struct adapter *adapter) | ||||
{ | { | ||||
struct ifnet *ifp = adapter->ifp; | struct ifnet *ifp = adapter->ifp; | ||||
device_t dev = adapter->dev; | device_t dev = adapter->dev; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
u32 mhadd, gpie; | int error = 0; | ||||
INIT_DEBUGOUT("ixv_init: begin"); | INIT_DEBUGOUT("ixv_init_locked: begin"); | ||||
mtx_assert(&adapter->core_mtx, MA_OWNED); | mtx_assert(&adapter->core_mtx, MA_OWNED); | ||||
hw->adapter_stopped = FALSE; | hw->adapter_stopped = FALSE; | ||||
ixgbe_stop_adapter(hw); | ixgbe_stop_adapter(hw); | ||||
callout_stop(&adapter->timer); | callout_stop(&adapter->timer); | ||||
/* reprogram the RAR[0] in case user changed it. */ | /* reprogram the RAR[0] in case user changed it. */ | ||||
ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); | ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); | ||||
/* Get the latest mac address, User can use a LAA */ | /* Get the latest mac address, User can use a LAA */ | ||||
bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr, | bcopy(IF_LLADDR(adapter->ifp), hw->mac.addr, | ||||
IXGBE_ETH_LENGTH_OF_ADDRESS); | IXGBE_ETH_LENGTH_OF_ADDRESS); | ||||
ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1); | ixgbe_set_rar(hw, 0, hw->mac.addr, 0, 1); | ||||
hw->addr_ctrl.rar_used_count = 1; | hw->addr_ctrl.rar_used_count = 1; | ||||
/* Prepare transmit descriptors and buffers */ | /* Prepare transmit descriptors and buffers */ | ||||
if (ixgbe_setup_transmit_structures(adapter)) { | if (ixgbe_setup_transmit_structures(adapter)) { | ||||
device_printf(dev,"Could not setup transmit structures\n"); | device_printf(dev, "Could not setup transmit structures\n"); | ||||
ixv_stop(adapter); | ixv_stop(adapter); | ||||
return; | return; | ||||
} | } | ||||
/* Reset VF and renegotiate mailbox API version */ | |||||
ixgbe_reset_hw(hw); | ixgbe_reset_hw(hw); | ||||
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); | |||||
ixv_initialize_transmit_units(adapter); | ixv_initialize_transmit_units(adapter); | ||||
/* Setup Multicast table */ | /* Setup Multicast table */ | ||||
ixv_set_multi(adapter); | ixv_set_multi(adapter); | ||||
/* | /* | ||||
** Determine the correct mbuf pool | ** Determine the correct mbuf pool | ||||
** for doing jumbo/headersplit | ** for doing jumbo/headersplit | ||||
*/ | */ | ||||
if (ifp->if_mtu > ETHERMTU) | if (ifp->if_mtu > ETHERMTU) | ||||
adapter->rx_mbuf_sz = MJUMPAGESIZE; | adapter->rx_mbuf_sz = MJUMPAGESIZE; | ||||
else | else | ||||
adapter->rx_mbuf_sz = MCLBYTES; | adapter->rx_mbuf_sz = MCLBYTES; | ||||
/* Prepare receive descriptors and buffers */ | /* Prepare receive descriptors and buffers */ | ||||
if (ixgbe_setup_receive_structures(adapter)) { | if (ixgbe_setup_receive_structures(adapter)) { | ||||
device_printf(dev,"Could not setup receive structures\n"); | device_printf(dev, "Could not setup receive structures\n"); | ||||
ixv_stop(adapter); | ixv_stop(adapter); | ||||
return; | return; | ||||
} | } | ||||
/* Configure RX settings */ | /* Configure RX settings */ | ||||
ixv_initialize_receive_units(adapter); | ixv_initialize_receive_units(adapter); | ||||
/* Enable Enhanced MSIX mode */ | |||||
gpie = IXGBE_READ_REG(&adapter->hw, IXGBE_GPIE); | |||||
gpie |= IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME; | |||||
gpie |= IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD; | |||||
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); | |||||
/* Set the various hardware offload abilities */ | /* Set the various hardware offload abilities */ | ||||
ifp->if_hwassist = 0; | ifp->if_hwassist = 0; | ||||
if (ifp->if_capenable & IFCAP_TSO4) | if (ifp->if_capenable & IFCAP_TSO4) | ||||
ifp->if_hwassist |= CSUM_TSO; | ifp->if_hwassist |= CSUM_TSO; | ||||
if (ifp->if_capenable & IFCAP_TXCSUM) { | if (ifp->if_capenable & IFCAP_TXCSUM) { | ||||
ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); | ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); | ||||
#if __FreeBSD_version >= 800000 | #if __FreeBSD_version >= 800000 | ||||
ifp->if_hwassist |= CSUM_SCTP; | ifp->if_hwassist |= CSUM_SCTP; | ||||
#endif | #endif | ||||
} | } | ||||
/* Set MTU size */ | |||||
if (ifp->if_mtu > ETHERMTU) { | |||||
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); | |||||
mhadd &= ~IXGBE_MHADD_MFS_MASK; | |||||
mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT; | |||||
IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); | |||||
} | |||||
/* Set up VLAN offload and filter */ | /* Set up VLAN offload and filter */ | ||||
ixv_setup_vlan_support(adapter); | ixv_setup_vlan_support(adapter); | ||||
callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); | |||||
/* Set up MSI/X routing */ | /* Set up MSI/X routing */ | ||||
ixv_configure_ivars(adapter); | ixv_configure_ivars(adapter); | ||||
/* Set up auto-mask */ | /* Set up auto-mask */ | ||||
IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, IXGBE_EICS_RTX_QUEUE); | IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, IXGBE_EICS_RTX_QUEUE); | ||||
/* Set moderation on the Link interrupt */ | /* Set moderation on the Link interrupt */ | ||||
IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR); | IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR); | ||||
/* Stats init */ | /* Stats init */ | ||||
ixv_init_stats(adapter); | ixv_init_stats(adapter); | ||||
/* Config/Enable Link */ | /* Config/Enable Link */ | ||||
ixv_config_link(adapter); | ixv_config_link(adapter); | ||||
/* Start watchdog */ | |||||
callout_reset(&adapter->timer, hz, ixv_local_timer, adapter); | |||||
/* And now turn on interrupts */ | /* And now turn on interrupts */ | ||||
ixv_enable_intr(adapter); | ixv_enable_intr(adapter); | ||||
/* Now inform the stack we're ready */ | /* Now inform the stack we're ready */ | ||||
ifp->if_drv_flags |= IFF_DRV_RUNNING; | ifp->if_drv_flags |= IFF_DRV_RUNNING; | ||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 661 Lines • ▼ Show 20 Lines | ixv_allocate_pci_resources(struct adapter *adapter) | ||||
int rid; | int rid; | ||||
device_t dev = adapter->dev; | device_t dev = adapter->dev; | ||||
rid = PCIR_BAR(0); | rid = PCIR_BAR(0); | ||||
adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, | adapter->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, | ||||
&rid, RF_ACTIVE); | &rid, RF_ACTIVE); | ||||
if (!(adapter->pci_mem)) { | if (!(adapter->pci_mem)) { | ||||
device_printf(dev,"Unable to allocate bus resource: memory\n"); | device_printf(dev, "Unable to allocate bus resource: memory\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
adapter->osdep.mem_bus_space_tag = | adapter->osdep.mem_bus_space_tag = | ||||
rman_get_bustag(adapter->pci_mem); | rman_get_bustag(adapter->pci_mem); | ||||
adapter->osdep.mem_bus_space_handle = | adapter->osdep.mem_bus_space_handle = | ||||
rman_get_bushandle(adapter->pci_mem); | rman_get_bushandle(adapter->pci_mem); | ||||
adapter->hw.hw_addr = (u8 *) &adapter->osdep.mem_bus_space_handle; | adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle; | ||||
/* Pick up the tuneable queues */ | /* Pick up the tuneable queues */ | ||||
adapter->num_queues = ixv_num_queues; | adapter->num_queues = ixv_num_queues; | ||||
adapter->hw.back = adapter; | |||||
adapter->hw.back = &adapter->osdep; | |||||
/* | /* | ||||
** Now setup MSI/X, should | ** Now setup MSI/X, should | ||||
** return us the number of | ** return us the number of | ||||
** configured vectors. | ** configured vectors. | ||||
*/ | */ | ||||
adapter->msix = ixv_setup_msix(adapter); | adapter->msix = ixv_setup_msix(adapter); | ||||
if (adapter->msix == ENXIO) | if (adapter->msix == ENXIO) | ||||
return (ENXIO); | return (ENXIO); | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
ifp->if_start = ixgbe_start; | ifp->if_start = ixgbe_start; | ||||
#endif | #endif | ||||
ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2; | ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2; | ||||
ether_ifattach(ifp, adapter->hw.mac.addr); | ether_ifattach(ifp, adapter->hw.mac.addr); | ||||
adapter->max_frame_size = | adapter->max_frame_size = | ||||
ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; | ifp->if_mtu + IXGBE_MTU_HDR_VLAN; | ||||
/* | /* | ||||
* Tell the upper layer(s) we support long frames. | * Tell the upper layer(s) we support long frames. | ||||
*/ | */ | ||||
ifp->if_hdrlen = sizeof(struct ether_vlan_header); | ifp->if_hdrlen = sizeof(struct ether_vlan_header); | ||||
ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM; | ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO4 | IFCAP_VLAN_HWCSUM; | ||||
ifp->if_capabilities |= IFCAP_JUMBO_MTU; | ifp->if_capabilities |= IFCAP_JUMBO_MTU; | ||||
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | ||||
| IFCAP_VLAN_HWTSO | | IFCAP_VLAN_HWTSO | ||||
| IFCAP_VLAN_MTU; | | IFCAP_VLAN_MTU; | ||||
ifp->if_capabilities |= IFCAP_LRO; | ifp->if_capabilities |= IFCAP_LRO; | ||||
ifp->if_capenable = ifp->if_capabilities; | ifp->if_capenable = ifp->if_capabilities; | ||||
/* | /* | ||||
* Specify the media types supported by this adapter and register | * Specify the media types supported by this adapter and register | ||||
* callbacks to update media and link information | * callbacks to update media and link information | ||||
*/ | */ | ||||
ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change, | ifmedia_init(&adapter->media, IFM_IMASK, ixv_media_change, | ||||
ixv_media_status); | ixv_media_status); | ||||
ifmedia_add(&adapter->media, IFM_ETHER | IFM_FDX, 0, NULL); | |||||
ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); | ifmedia_add(&adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL); | ||||
ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); | ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); | ||||
return; | return; | ||||
} | } | ||||
static void | static void | ||||
ixv_config_link(struct adapter *adapter) | ixv_config_link(struct adapter *adapter) | ||||
{ | { | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
u32 autoneg, err = 0; | u32 autoneg; | ||||
if (hw->mac.ops.check_link) | if (hw->mac.ops.check_link) | ||||
err = hw->mac.ops.check_link(hw, &autoneg, | hw->mac.ops.check_link(hw, &autoneg, | ||||
&adapter->link_up, FALSE); | &adapter->link_up, FALSE); | ||||
if (err) | |||||
goto out; | |||||
if (hw->mac.ops.setup_link) | |||||
err = hw->mac.ops.setup_link(hw, | |||||
autoneg, adapter->link_up); | |||||
out: | |||||
return; | |||||
} | } | ||||
/********************************************************************* | /********************************************************************* | ||||
* | * | ||||
* Enable transmit unit. | * Enable transmit unit. | ||||
* | * | ||||
**********************************************************************/ | **********************************************************************/ | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
ixv_initialize_receive_units(struct adapter *adapter) | ixv_initialize_receive_units(struct adapter *adapter) | ||||
{ | { | ||||
struct rx_ring *rxr = adapter->rx_rings; | struct rx_ring *rxr = adapter->rx_rings; | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
struct ifnet *ifp = adapter->ifp; | struct ifnet *ifp = adapter->ifp; | ||||
u32 bufsz, rxcsum, psrtype; | u32 bufsz, rxcsum, psrtype; | ||||
int max_frame; | |||||
if (ifp->if_mtu > ETHERMTU) | if (ifp->if_mtu > ETHERMTU) | ||||
bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; | bufsz = 4096 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; | ||||
else | else | ||||
bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; | bufsz = 2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; | ||||
psrtype = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR | | psrtype = IXGBE_PSRTYPE_TCPHDR | IXGBE_PSRTYPE_UDPHDR | | ||||
IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR | | IXGBE_PSRTYPE_IPV4HDR | IXGBE_PSRTYPE_IPV6HDR | | ||||
IXGBE_PSRTYPE_L2HDR; | IXGBE_PSRTYPE_L2HDR; | ||||
IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); | IXGBE_WRITE_REG(hw, IXGBE_VFPSRTYPE, psrtype); | ||||
/* Tell PF our expected packet-size */ | /* Tell PF our max_frame size */ | ||||
max_frame = ifp->if_mtu + IXGBE_MTU_HDR; | ixgbevf_rlpml_set_vf(hw, adapter->max_frame_size); | ||||
ixgbevf_rlpml_set_vf(hw, max_frame); | |||||
for (int i = 0; i < adapter->num_queues; i++, rxr++) { | for (int i = 0; i < adapter->num_queues; i++, rxr++) { | ||||
u64 rdba = rxr->rxdma.dma_paddr; | u64 rdba = rxr->rxdma.dma_paddr; | ||||
u32 reg, rxdctl; | u32 reg, rxdctl; | ||||
/* Disable the queue */ | /* Disable the queue */ | ||||
rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); | rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); | ||||
rxdctl &= ~(IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME); | rxdctl &= ~IXGBE_RXDCTL_ENABLE; | ||||
IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); | IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); | ||||
for (int j = 0; j < 10; j++) { | for (int j = 0; j < 10; j++) { | ||||
if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & | if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & | ||||
IXGBE_RXDCTL_ENABLE) | IXGBE_RXDCTL_ENABLE) | ||||
msec_delay(1); | msec_delay(1); | ||||
else | else | ||||
break; | break; | ||||
} | } | ||||
Show All 13 Lines | for (int i = 0; i < adapter->num_queues; i++, rxr++) { | ||||
/* Set up the SRRCTL register */ | /* Set up the SRRCTL register */ | ||||
reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); | reg = IXGBE_READ_REG(hw, IXGBE_VFSRRCTL(i)); | ||||
reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; | reg &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; | ||||
reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; | reg &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; | ||||
reg |= bufsz; | reg |= bufsz; | ||||
reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; | reg |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; | ||||
IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), reg); | IXGBE_WRITE_REG(hw, IXGBE_VFSRRCTL(i), reg); | ||||
/* Setup the HW Rx Head and Tail Descriptor Pointers */ | /* Capture Rx Tail register */ | ||||
IXGBE_WRITE_REG(hw, IXGBE_VFRDH(rxr->me), 0); | |||||
IXGBE_WRITE_REG(hw, IXGBE_VFRDT(rxr->me), | |||||
adapter->num_rx_desc - 1); | |||||
/* Set Rx Tail register */ | |||||
rxr->tail = IXGBE_VFRDT(rxr->me); | rxr->tail = IXGBE_VFRDT(rxr->me); | ||||
/* Do the queue enabling last */ | /* Do the queue enabling last */ | ||||
rxdctl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); | rxdctl |= IXGBE_RXDCTL_ENABLE | IXGBE_RXDCTL_VME; | ||||
rxdctl |= IXGBE_RXDCTL_ENABLE; | |||||
IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); | IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), rxdctl); | ||||
for (int k = 0; k < 10; k++) { | for (int k = 0; k < 10; k++) { | ||||
if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & | if (IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)) & | ||||
IXGBE_RXDCTL_ENABLE) | IXGBE_RXDCTL_ENABLE) | ||||
break; | break; | ||||
else | else | ||||
msec_delay(1); | msec_delay(1); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | #endif /* DEV_NETMAP */ | ||||
return; | return; | ||||
} | } | ||||
static void | static void | ||||
ixv_setup_vlan_support(struct adapter *adapter) | ixv_setup_vlan_support(struct adapter *adapter) | ||||
{ | { | ||||
struct ixgbe_hw *hw = &adapter->hw; | struct ixgbe_hw *hw = &adapter->hw; | ||||
u32 ctrl, vid, vfta, retry; | u32 ctrl, vid, vfta, retry; | ||||
struct rx_ring *rxr; | |||||
/* | /* | ||||
** We get here thru init_locked, meaning | ** We get here thru init_locked, meaning | ||||
** a soft reset, this has already cleared | ** a soft reset, this has already cleared | ||||
** the VFTA and other state, so if there | ** the VFTA and other state, so if there | ||||
** have been no vlan's registered do nothing. | ** have been no vlan's registered do nothing. | ||||
*/ | */ | ||||
if (adapter->num_vlans == 0) | if (adapter->num_vlans == 0) | ||||
return; | return; | ||||
/* Enable the queues */ | /* Enable the queues */ | ||||
for (int i = 0; i < adapter->num_queues; i++) { | for (int i = 0; i < adapter->num_queues; i++) { | ||||
ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); | ctrl = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(i)); | ||||
ctrl |= IXGBE_RXDCTL_VME; | ctrl |= IXGBE_RXDCTL_VME; | ||||
IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl); | IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(i), ctrl); | ||||
/* | |||||
* Let Rx path know that it needs to store VLAN tag | |||||
* as part of extra mbuf info. | |||||
*/ | |||||
rxr = &adapter->rx_rings[i]; | |||||
rxr->vtag_strip = TRUE; | |||||
} | } | ||||
/* | /* | ||||
** A soft reset zero's out the VFTA, so | ** A soft reset zero's out the VFTA, so | ||||
** we need to repopulate it now. | ** we need to repopulate it now. | ||||
*/ | */ | ||||
for (int i = 0; i < IXGBE_VFTA_SIZE; i++) { | for (int i = 0; i < IXGBE_VFTA_SIZE; i++) { | ||||
if (ixv_shadow_vfta[i] == 0) | if (ixv_shadow_vfta[i] == 0) | ||||
continue; | continue; | ||||
vfta = ixv_shadow_vfta[i]; | vfta = ixv_shadow_vfta[i]; | ||||
/* | /* | ||||
** Reconstruct the vlan id's | ** Reconstruct the vlan id's | ||||
** based on the bits set in each | ** based on the bits set in each | ||||
** of the array ints. | ** of the array ints. | ||||
*/ | */ | ||||
for ( int j = 0; j < 32; j++) { | for (int j = 0; j < 32; j++) { | ||||
retry = 0; | retry = 0; | ||||
if ((vfta & (1 << j)) == 0) | if ((vfta & (1 << j)) == 0) | ||||
continue; | continue; | ||||
vid = (i * 32) + j; | vid = (i * 32) + j; | ||||
/* Call the shared code mailbox routine */ | /* Call the shared code mailbox routine */ | ||||
while (ixgbe_set_vfta(hw, vid, 0, TRUE)) { | while (ixgbe_set_vfta(hw, vid, 0, TRUE)) { | ||||
if (++retry > 5) | if (++retry > 5) | ||||
break; | break; | ||||
Show All 10 Lines | |||||
** repopulate the real table. | ** repopulate the real table. | ||||
*/ | */ | ||||
static void | static void | ||||
ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) | ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) | ||||
{ | { | ||||
struct adapter *adapter = ifp->if_softc; | struct adapter *adapter = ifp->if_softc; | ||||
u16 index, bit; | u16 index, bit; | ||||
if (ifp->if_softc != arg) /* Not our event */ | if (ifp->if_softc != arg) /* Not our event */ | ||||
return; | return; | ||||
if ((vtag == 0) || (vtag > 4095)) /* Invalid */ | if ((vtag == 0) || (vtag > 4095)) /* Invalid */ | ||||
return; | return; | ||||
IXGBE_CORE_LOCK(adapter); | IXGBE_CORE_LOCK(adapter); | ||||
index = (vtag >> 5) & 0x7F; | index = (vtag >> 5) & 0x7F; | ||||
bit = vtag & 0x1F; | bit = vtag & 0x1F; | ||||
ixv_shadow_vfta[index] |= (1 << bit); | ixv_shadow_vfta[index] |= (1 << bit); | ||||
++adapter->num_vlans; | ++adapter->num_vlans; | ||||
/* Re-init to load the changes */ | /* Re-init to load the changes */ | ||||
▲ Show 20 Lines • Show All 370 Lines • Show Last 20 Lines |