Commit 031554ea authored by David S. Miller's avatar David S. Miller
parents 9c5e0c0b b876a744
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
obj-$(CONFIG_IXGBE) += ixgbe.o obj-$(CONFIG_IXGBE) += ixgbe.o
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\ ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \ ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o ixgbe_ptp.o
...@@ -40,4 +40,5 @@ ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \ ...@@ -40,4 +40,5 @@ ixgbe-$(CONFIG_IXGBE_DCB) += ixgbe_dcb.o ixgbe_dcb_82598.o \
ixgbe_dcb_82599.o ixgbe_dcb_nl.o ixgbe_dcb_82599.o ixgbe_dcb_nl.o
ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o ixgbe-$(CONFIG_IXGBE_HWMON) += ixgbe_sysfs.o
ixgbe-$(CONFIG_DEBUG_FS) += ixgbe_debugfs.o
ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/aer.h> #include <linux/aer.h>
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/jiffies.h>
#include <linux/clocksource.h> #include <linux/clocksource.h>
#include <linux/net_tstamp.h> #include <linux/net_tstamp.h>
...@@ -231,6 +232,7 @@ struct ixgbe_ring { ...@@ -231,6 +232,7 @@ struct ixgbe_ring {
struct ixgbe_tx_buffer *tx_buffer_info; struct ixgbe_tx_buffer *tx_buffer_info;
struct ixgbe_rx_buffer *rx_buffer_info; struct ixgbe_rx_buffer *rx_buffer_info;
}; };
unsigned long last_rx_timestamp;
unsigned long state; unsigned long state;
u8 __iomem *tail; u8 __iomem *tail;
dma_addr_t dma; /* phys. address of descriptor ring */ dma_addr_t dma; /* phys. address of descriptor ring */
...@@ -580,11 +582,14 @@ struct ixgbe_adapter { ...@@ -580,11 +582,14 @@ struct ixgbe_adapter {
struct ptp_clock *ptp_clock; struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps; struct ptp_clock_info ptp_caps;
struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb;
unsigned long ptp_tx_start;
unsigned long last_overflow_check; unsigned long last_overflow_check;
unsigned long last_rx_ptp_check;
spinlock_t tmreg_lock; spinlock_t tmreg_lock;
struct cyclecounter cc; struct cyclecounter cc;
struct timecounter tc; struct timecounter tc;
int rx_hwtstamp_filter;
u32 base_incval; u32 base_incval;
/* SR-IOV */ /* SR-IOV */
...@@ -749,15 +754,32 @@ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring) ...@@ -749,15 +754,32 @@ static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring)
extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter); extern void ixgbe_ptp_init(struct ixgbe_adapter *adapter);
extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); extern void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); extern void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
extern void ixgbe_ptp_tx_hwtstamp(struct ixgbe_q_vector *q_vector, extern void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
extern void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
struct sk_buff *skb); struct sk_buff *skb);
extern void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
union ixgbe_adv_rx_desc *rx_desc, union ixgbe_adv_rx_desc *rx_desc,
struct sk_buff *skb); struct sk_buff *skb)
{
if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
return;
__ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb);
/*
* Update the last_rx_timestamp timer in order to enable watchdog check
* for error case of latched timestamp on a dropped packet.
*/
rx_ring->last_rx_timestamp = jiffies;
}
extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, extern int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
struct ifreq *ifr, int cmd); struct ifreq *ifr, int cmd);
extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); extern void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
extern void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); extern void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); extern void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr);
#ifdef CONFIG_PCI_IOV
void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter);
#endif
#endif /* _IXGBE_H_ */ #endif /* _IXGBE_H_ */
...@@ -24,9 +24,6 @@ ...@@ -24,9 +24,6 @@
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*******************************************************************************/ *******************************************************************************/
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -277,5 +274,3 @@ void ixgbe_dbg_exit(void) ...@@ -277,5 +274,3 @@ void ixgbe_dbg_exit(void)
{ {
debugfs_remove_recursive(ixgbe_dbg_root); debugfs_remove_recursive(ixgbe_dbg_root);
} }
#endif /* CONFIG_DEBUG_FS */
...@@ -1837,19 +1837,11 @@ static void ixgbe_diag_test(struct net_device *netdev, ...@@ -1837,19 +1837,11 @@ static void ixgbe_diag_test(struct net_device *netdev,
struct ethtool_test *eth_test, u64 *data) struct ethtool_test *eth_test, u64 *data)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
bool if_running = netif_running(netdev); bool if_running = netif_running(netdev);
set_bit(__IXGBE_TESTING, &adapter->state); set_bit(__IXGBE_TESTING, &adapter->state);
if (eth_test->flags == ETH_TEST_FL_OFFLINE) { if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
/* Offline tests */
e_info(hw, "offline testing starting\n");
/* Link test performed before hardware reset so autoneg doesn't
* interfere with test result */
if (ixgbe_link_test(adapter, &data[4]))
eth_test->flags |= ETH_TEST_FL_FAILED;
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
int i; int i;
for (i = 0; i < adapter->num_vfs; i++) { for (i = 0; i < adapter->num_vfs; i++) {
...@@ -1870,12 +1862,24 @@ static void ixgbe_diag_test(struct net_device *netdev, ...@@ -1870,12 +1862,24 @@ static void ixgbe_diag_test(struct net_device *netdev,
} }
} }
/* Offline tests */
e_info(hw, "offline testing starting\n");
if (if_running) if (if_running)
/* indicate we're in test mode */ /* indicate we're in test mode */
dev_close(netdev); dev_close(netdev);
else
ixgbe_reset(adapter);
/* bringing adapter down disables SFP+ optics */
if (hw->mac.ops.enable_tx_laser)
hw->mac.ops.enable_tx_laser(hw);
/* Link test performed before hardware reset so autoneg doesn't
* interfere with test result
*/
if (ixgbe_link_test(adapter, &data[4]))
eth_test->flags |= ETH_TEST_FL_FAILED;
ixgbe_reset(adapter);
e_info(hw, "register testing starting\n"); e_info(hw, "register testing starting\n");
if (ixgbe_reg_test(adapter, &data[0])) if (ixgbe_reg_test(adapter, &data[0]))
eth_test->flags |= ETH_TEST_FL_FAILED; eth_test->flags |= ETH_TEST_FL_FAILED;
...@@ -1908,16 +1912,22 @@ static void ixgbe_diag_test(struct net_device *netdev, ...@@ -1908,16 +1912,22 @@ static void ixgbe_diag_test(struct net_device *netdev,
skip_loopback: skip_loopback:
ixgbe_reset(adapter); ixgbe_reset(adapter);
/* clear testing bit and return adapter to previous state */
clear_bit(__IXGBE_TESTING, &adapter->state); clear_bit(__IXGBE_TESTING, &adapter->state);
if (if_running) if (if_running)
dev_open(netdev); dev_open(netdev);
} else { } else {
e_info(hw, "online testing starting\n"); e_info(hw, "online testing starting\n");
/* if adapter is down, SFP+ optics will be disabled */
if (!if_running && hw->mac.ops.enable_tx_laser)
hw->mac.ops.enable_tx_laser(hw);
/* Online tests */ /* Online tests */
if (ixgbe_link_test(adapter, &data[4])) if (ixgbe_link_test(adapter, &data[4]))
eth_test->flags |= ETH_TEST_FL_FAILED; eth_test->flags |= ETH_TEST_FL_FAILED;
/* Online tests aren't run; pass by default */ /* Offline tests aren't run; pass by default */
data[0] = 0; data[0] = 0;
data[1] = 0; data[1] = 0;
data[2] = 0; data[2] = 0;
...@@ -1925,6 +1935,10 @@ static void ixgbe_diag_test(struct net_device *netdev, ...@@ -1925,6 +1935,10 @@ static void ixgbe_diag_test(struct net_device *netdev,
clear_bit(__IXGBE_TESTING, &adapter->state); clear_bit(__IXGBE_TESTING, &adapter->state);
} }
/* if adapter was down, ensure SFP+ optics are disabled again */
if (!if_running && hw->mac.ops.disable_tx_laser)
hw->mac.ops.disable_tx_laser(hw);
skip_ol_tests: skip_ol_tests:
msleep_interruptible(4 * 1000); msleep_interruptible(4 * 1000);
} }
...@@ -2695,6 +2709,14 @@ static int ixgbe_get_ts_info(struct net_device *dev, ...@@ -2695,6 +2709,14 @@ static int ixgbe_get_ts_info(struct net_device *dev,
(1 << HWTSTAMP_FILTER_NONE) | (1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) | (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
(1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) | (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
(1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
(1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
(1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT); (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
break; break;
default: default:
......
...@@ -803,6 +803,7 @@ static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter) ...@@ -803,6 +803,7 @@ static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter)
/* Do the reset outside of interrupt context */ /* Do the reset outside of interrupt context */
if (!test_bit(__IXGBE_DOWN, &adapter->state)) { if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
e_warn(drv, "initiating reset due to tx timeout\n");
ixgbe_service_event_schedule(adapter); ixgbe_service_event_schedule(adapter);
} }
} }
...@@ -850,9 +851,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, ...@@ -850,9 +851,6 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
total_bytes += tx_buffer->bytecount; total_bytes += tx_buffer->bytecount;
total_packets += tx_buffer->gso_segs; total_packets += tx_buffer->gso_segs;
if (unlikely(tx_buffer->tx_flags & IXGBE_TX_FLAGS_TSTAMP))
ixgbe_ptp_tx_hwtstamp(q_vector, tx_buffer->skb);
/* free the skb */ /* free the skb */
dev_kfree_skb_any(tx_buffer->skb); dev_kfree_skb_any(tx_buffer->skb);
...@@ -1441,7 +1439,7 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, ...@@ -1441,7 +1439,7 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
ixgbe_rx_checksum(rx_ring, rx_desc, skb); ixgbe_rx_checksum(rx_ring, rx_desc, skb);
ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, rx_desc, skb); ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
if ((dev->features & NETIF_F_HW_VLAN_RX) && if ((dev->features & NETIF_F_HW_VLAN_RX) &&
ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
...@@ -5534,6 +5532,8 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter) ...@@ -5534,6 +5532,8 @@ static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
break; break;
} }
adapter->last_rx_ptp_check = jiffies;
if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED)
ixgbe_ptp_start_cyclecounter(adapter); ixgbe_ptp_start_cyclecounter(adapter);
...@@ -5614,6 +5614,7 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter) ...@@ -5614,6 +5614,7 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
* to get done, so reset controller to flush Tx. * to get done, so reset controller to flush Tx.
* (Do the reset outside of interrupt context). * (Do the reset outside of interrupt context).
*/ */
e_warn(drv, "initiating reset to clear Tx work after link loss\n");
adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED; adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
} }
} }
...@@ -5878,7 +5879,6 @@ static void ixgbe_service_task(struct work_struct *work) ...@@ -5878,7 +5879,6 @@ static void ixgbe_service_task(struct work_struct *work)
struct ixgbe_adapter *adapter = container_of(work, struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter, struct ixgbe_adapter,
service_task); service_task);
ixgbe_reset_subtask(adapter); ixgbe_reset_subtask(adapter);
ixgbe_sfp_detection_subtask(adapter); ixgbe_sfp_detection_subtask(adapter);
ixgbe_sfp_link_config_subtask(adapter); ixgbe_sfp_link_config_subtask(adapter);
...@@ -5886,7 +5886,11 @@ static void ixgbe_service_task(struct work_struct *work) ...@@ -5886,7 +5886,11 @@ static void ixgbe_service_task(struct work_struct *work)
ixgbe_watchdog_subtask(adapter); ixgbe_watchdog_subtask(adapter);
ixgbe_fdir_reinit_subtask(adapter); ixgbe_fdir_reinit_subtask(adapter);
ixgbe_check_hang_subtask(adapter); ixgbe_check_hang_subtask(adapter);
if (adapter->flags2 & IXGBE_FLAG2_PTP_ENABLED) {
ixgbe_ptp_overflow_check(adapter); ixgbe_ptp_overflow_check(adapter);
ixgbe_ptp_rx_hang(adapter);
}
ixgbe_service_event_complete(adapter); ixgbe_service_event_complete(adapter);
} }
...@@ -6432,6 +6436,11 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, ...@@ -6432,6 +6436,11 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
tx_flags |= IXGBE_TX_FLAGS_TSTAMP; tx_flags |= IXGBE_TX_FLAGS_TSTAMP;
/* schedule check for Tx timestamp */
adapter->ptp_tx_skb = skb_get(skb);
adapter->ptp_tx_start = jiffies;
schedule_work(&adapter->ptp_tx_work);
} }
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
...@@ -6827,6 +6836,26 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) ...@@ -6827,6 +6836,26 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
} }
#endif /* CONFIG_IXGBE_DCB */ #endif /* CONFIG_IXGBE_DCB */
#ifdef CONFIG_PCI_IOV
void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
rtnl_lock();
#ifdef CONFIG_IXGBE_DCB
ixgbe_setup_tc(netdev, netdev_get_num_tc(netdev));
#else
if (netif_running(netdev))
ixgbe_close(netdev);
ixgbe_clear_interrupt_scheme(adapter);
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
ixgbe_open(netdev);
#endif
rtnl_unlock();
}
#endif
void ixgbe_do_reset(struct net_device *netdev) void ixgbe_do_reset(struct net_device *netdev)
{ {
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
...@@ -7353,7 +7382,15 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -7353,7 +7382,15 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} }
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
ixgbe_enable_sriov(adapter, ii); /* SR-IOV not supported on the 82598 */
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
goto skip_sriov;
/* Mailbox */
ixgbe_init_mbx_params_pf(hw);
memcpy(&hw->mbx.ops, ii->mbx_ops, sizeof(hw->mbx.ops));
ixgbe_enable_sriov(adapter);
pci_sriov_set_totalvfs(pdev, 63);
skip_sriov:
#endif #endif
netdev->features = NETIF_F_SG | netdev->features = NETIF_F_SG |
...@@ -7609,8 +7646,14 @@ static void ixgbe_remove(struct pci_dev *pdev) ...@@ -7609,8 +7646,14 @@ static void ixgbe_remove(struct pci_dev *pdev)
if (netdev->reg_state == NETREG_REGISTERED) if (netdev->reg_state == NETREG_REGISTERED)
unregister_netdev(netdev); unregister_netdev(netdev);
#ifdef CONFIG_PCI_IOV
/*
* Only disable SR-IOV on unload if the user specified the now
* deprecated max_vfs module parameter.
*/
if (max_vfs)
ixgbe_disable_sriov(adapter); ixgbe_disable_sriov(adapter);
#endif
ixgbe_clear_interrupt_scheme(adapter); ixgbe_clear_interrupt_scheme(adapter);
ixgbe_release_hw_control(adapter); ixgbe_release_hw_control(adapter);
...@@ -7824,6 +7867,7 @@ static struct pci_driver ixgbe_driver = { ...@@ -7824,6 +7867,7 @@ static struct pci_driver ixgbe_driver = {
.resume = ixgbe_resume, .resume = ixgbe_resume,
#endif #endif
.shutdown = ixgbe_shutdown, .shutdown = ixgbe_shutdown,
.sriov_configure = ixgbe_pci_sriov_configure,
.err_handler = &ixgbe_err_handler .err_handler = &ixgbe_err_handler
}; };
......
...@@ -44,50 +44,11 @@ ...@@ -44,50 +44,11 @@
#include "ixgbe_sriov.h" #include "ixgbe_sriov.h"
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
const struct ixgbe_info *ii)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int num_vf_macvlans, i; int num_vf_macvlans, i;
struct vf_macvlans *mv_list; struct vf_macvlans *mv_list;
int pre_existing_vfs = 0;
pre_existing_vfs = pci_num_vf(adapter->pdev);
if (!pre_existing_vfs && !adapter->num_vfs)
return;
/* If there are pre-existing VFs then we have to force
* use of that many because they were not deleted the last
* time someone removed the PF driver. That would have
* been because they were allocated to guest VMs and can't
* be removed. Go ahead and just re-enable the old amount.
* If the user wants to change the number of VFs they can
* use ethtool while making sure no VFs are allocated to
* guest VMs... i.e. the right way.
*/
if (pre_existing_vfs) {
adapter->num_vfs = pre_existing_vfs;
dev_warn(&adapter->pdev->dev, "Virtual Functions already "
"enabled for this device - Please reload all "
"VF drivers to avoid spoofed packet errors\n");
} else {
int err;
/*
* The 82599 supports up to 64 VFs per physical function
* but this implementation limits allocation to 63 so that
* basic networking resources are still available to the
* physical function. If the user requests greater thn
* 63 VFs then it is an error - reset to default of zero.
*/
adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, 63);
err = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
if (err) {
e_err(probe, "Failed to enable PCI sriov: %d\n", err);
adapter->num_vfs = 0;
return;
}
}
adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED; adapter->flags |= IXGBE_FLAG_SRIOV_ENABLED;
e_info(probe, "SR-IOV enabled with %d VFs\n", adapter->num_vfs); e_info(probe, "SR-IOV enabled with %d VFs\n", adapter->num_vfs);
...@@ -128,12 +89,6 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, ...@@ -128,12 +89,6 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
kcalloc(adapter->num_vfs, kcalloc(adapter->num_vfs,
sizeof(struct vf_data_storage), GFP_KERNEL); sizeof(struct vf_data_storage), GFP_KERNEL);
if (adapter->vfinfo) { if (adapter->vfinfo) {
/* Now that we're sure SR-IOV is enabled
* and memory allocated set up the mailbox parameters
*/
ixgbe_init_mbx_params_pf(hw);
memcpy(&hw->mbx.ops, ii->mbx_ops, sizeof(hw->mbx.ops));
/* limit trafffic classes based on VFs enabled */ /* limit trafffic classes based on VFs enabled */
if ((adapter->hw.mac.type == ixgbe_mac_82599EB) && if ((adapter->hw.mac.type == ixgbe_mac_82599EB) &&
(adapter->num_vfs < 16)) { (adapter->num_vfs < 16)) {
...@@ -157,10 +112,62 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, ...@@ -157,10 +112,62 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
/* enable spoof checking for all VFs */ /* enable spoof checking for all VFs */
for (i = 0; i < adapter->num_vfs; i++) for (i = 0; i < adapter->num_vfs; i++)
adapter->vfinfo[i].spoofchk_enabled = true; adapter->vfinfo[i].spoofchk_enabled = true;
return 0;
}
return -ENOMEM;
}
/* Note this function is called when the user wants to enable SR-IOV
* VFs using the now deprecated module parameter
*/
void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
{
int pre_existing_vfs = 0;
pre_existing_vfs = pci_num_vf(adapter->pdev);
if (!pre_existing_vfs && !adapter->num_vfs)
return;
if (!pre_existing_vfs)
dev_warn(&adapter->pdev->dev,
"Enabling SR-IOV VFs using the module parameter is deprecated - please use the pci sysfs interface.\n");
/* If there are pre-existing VFs then we have to force
* use of that many - over ride any module parameter value.
* This may result from the user unloading the PF driver
* while VFs were assigned to guest VMs or because the VFs
* have been created via the new PCI SR-IOV sysfs interface.
*/
if (pre_existing_vfs) {
adapter->num_vfs = pre_existing_vfs;
dev_warn(&adapter->pdev->dev,
"Virtual Functions already enabled for this device - Please reload all VF drivers to avoid spoofed packet errors\n");
} else {
int err;
/*
* The 82599 supports up to 64 VFs per physical function
* but this implementation limits allocation to 63 so that
* basic networking resources are still available to the
* physical function. If the user requests greater thn
* 63 VFs then it is an error - reset to default of zero.
*/
adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, 63);
err = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
if (err) {
e_err(probe, "Failed to enable PCI sriov: %d\n", err);
adapter->num_vfs = 0;
return; return;
} }
}
/* Oh oh */ if (!__ixgbe_enable_sriov(adapter))
return;
/* If we have gotten to this point then there is no memory available
* to manage the VF devices - print message and bail.
*/
e_err(probe, "Unable to allocate memory for VF Data Storage - " e_err(probe, "Unable to allocate memory for VF Data Storage - "
"SRIOV disabled\n"); "SRIOV disabled\n");
ixgbe_disable_sriov(adapter); ixgbe_disable_sriov(adapter);
...@@ -200,11 +207,12 @@ static bool ixgbe_vfs_are_assigned(struct ixgbe_adapter *adapter) ...@@ -200,11 +207,12 @@ static bool ixgbe_vfs_are_assigned(struct ixgbe_adapter *adapter)
} }
#endif /* #ifdef CONFIG_PCI_IOV */ #endif /* #ifdef CONFIG_PCI_IOV */
void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 gpie; u32 gpie;
u32 vmdctl; u32 vmdctl;
int rss;
/* set num VFs to 0 to prevent access to vfinfo */ /* set num VFs to 0 to prevent access to vfinfo */
adapter->num_vfs = 0; adapter->num_vfs = 0;
...@@ -219,7 +227,7 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) ...@@ -219,7 +227,7 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
/* if SR-IOV is already disabled then there is nothing to do */ /* if SR-IOV is already disabled then there is nothing to do */
if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
return; return 0;
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
/* /*
...@@ -229,7 +237,7 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) ...@@ -229,7 +237,7 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
*/ */
if (ixgbe_vfs_are_assigned(adapter)) { if (ixgbe_vfs_are_assigned(adapter)) {
e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n"); e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n");
return; return -EPERM;
} }
/* disable iov and allow time for transactions to clear */ /* disable iov and allow time for transactions to clear */
pci_disable_sriov(adapter->pdev); pci_disable_sriov(adapter->pdev);
...@@ -252,10 +260,94 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) ...@@ -252,10 +260,94 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED; adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED;
adapter->ring_feature[RING_F_VMDQ].offset = 0; adapter->ring_feature[RING_F_VMDQ].offset = 0;
rss = min_t(int, IXGBE_MAX_RSS_INDICES, num_online_cpus());
adapter->ring_feature[RING_F_RSS].limit = rss;
/* take a breather then clean up driver data */ /* take a breather then clean up driver data */
msleep(100); msleep(100);
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
return 0;
}
static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
{
#ifdef CONFIG_PCI_IOV
struct ixgbe_adapter *adapter = pci_get_drvdata(dev);
int err = 0;
int i;
int pre_existing_vfs = pci_num_vf(dev);
if (pre_existing_vfs && pre_existing_vfs != num_vfs)
err = ixgbe_disable_sriov(adapter);
else if (pre_existing_vfs && pre_existing_vfs == num_vfs)
goto out;
if (err)
goto err_out;
/* While the SR-IOV capability structure reports total VFs to be
* 64 we limit the actual number that can be allocated to 63 so
* that some transmit/receive resources can be reserved to the
* PF. The PCI bus driver already checks for other values out of
* range.
*/
if (num_vfs > 63) {
err = -EPERM;
goto err_out;
}
adapter->num_vfs = num_vfs;
err = __ixgbe_enable_sriov(adapter);
if (err)
goto err_out;
for (i = 0; i < adapter->num_vfs; i++)
ixgbe_vf_configuration(dev, (i | 0x10000000));
err = pci_enable_sriov(dev, num_vfs);
if (err) {
e_dev_warn("Failed to enable PCI sriov: %d\n", err);
goto err_out;
}
ixgbe_sriov_reinit(adapter);
out:
return num_vfs;
err_out:
return err;
#endif
return 0;
}
static int ixgbe_pci_sriov_disable(struct pci_dev *dev)
{
struct ixgbe_adapter *adapter = pci_get_drvdata(dev);
int err;
u32 current_flags = adapter->flags;
err = ixgbe_disable_sriov(adapter);
/* Only reinit if no error and state changed */
if (!err && current_flags != adapter->flags) {
/* ixgbe_disable_sriov() doesn't clear VMDQ flag */
adapter->flags &= ~IXGBE_FLAG_VMDQ_ENABLED;
#ifdef CONFIG_PCI_IOV
ixgbe_sriov_reinit(adapter);
#endif
}
return err;
}
int ixgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
{
if (num_vfs == 0)
return ixgbe_pci_sriov_disable(dev);
else
return ixgbe_pci_sriov_enable(dev, num_vfs);
} }
static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
......
...@@ -41,11 +41,11 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); ...@@ -41,11 +41,11 @@ int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);
int ixgbe_ndo_get_vf_config(struct net_device *netdev, int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi); int vf, struct ifla_vf_info *ivi);
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
void ixgbe_disable_sriov(struct ixgbe_adapter *adapter); int ixgbe_disable_sriov(struct ixgbe_adapter *adapter);
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, void ixgbe_enable_sriov(struct ixgbe_adapter *adapter);
const struct ixgbe_info *ii);
#endif #endif
int ixgbe_pci_sriov_configure(struct pci_dev *dev, int num_vfs);
static inline void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, static inline void ixgbe_set_vmvir(struct ixgbe_adapter *adapter,
u16 vid, u16 qos, u32 vf) u16 vid, u16 qos, u32 vf)
......
...@@ -2245,10 +2245,23 @@ static void ixgbevf_watchdog_task(struct work_struct *work) ...@@ -2245,10 +2245,23 @@ static void ixgbevf_watchdog_task(struct work_struct *work)
if (link_up) { if (link_up) {
if (!netif_carrier_ok(netdev)) { if (!netif_carrier_ok(netdev)) {
char *link_speed_string;
switch (link_speed) {
case IXGBE_LINK_SPEED_10GB_FULL:
link_speed_string = "10 Gbps";
break;
case IXGBE_LINK_SPEED_1GB_FULL:
link_speed_string = "1 Gbps";
break;
case IXGBE_LINK_SPEED_100_FULL:
link_speed_string = "100 Mbps";
break;
default:
link_speed_string = "unknown speed";
break;
}
dev_info(&adapter->pdev->dev, dev_info(&adapter->pdev->dev,
"NIC Link is Up, %u Gbps\n", "NIC Link is Up, %s\n", link_speed_string);
(link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
10 : 1);
netif_carrier_on(netdev); netif_carrier_on(netdev);
netif_tx_wake_all_queues(netdev); netif_tx_wake_all_queues(netdev);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment