Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jkirsher/next-queue

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2015-09-15

This series contains updates to ixgbe and fm10k.

Don fixes a ixgbe issue by adding checks for systems that do not have
SFP's to avoid incorrectly acting on interrupts that are falsely
interpreted as SFP events.

Alex Williamson adds a fix for ixgbe to disable SR-IOV prior to
unregistering the netdev to avoid issues with guest OS's which do not
support hot-unplug or their hot-unplug is broken.

Alex Duyck update the lowest limit for adaptive interrupt interrupt
moderation to about 12K interrupts per second for ixgbe.  This change
increases the performance for ixgbe.  Also fixed up fm10k to remove
the optimization that assumed that all fragments would be limited to
page size, since that assumption is incorrect as the TCP allocator can
provide up to a 32K page fragment.  Updated fm10k to add the MAC
address to the list of values recorded on driver load.  Fixes fm10k
so that we only trigger the data path reset if the fabric is ready to
handle traffic to avoid triggering the reset unless the switch API is
ready for us.

Jacob updates the fm10k driver to disable the service task during
suspend and re-enable it after we resume. If we don't do this, the
device could be UP when you suspend and come back from resume as
DOWN.  Also update fm10k to prevent the removal of default VID rules,
 and correctly remove the stack layers information of the VLAN, but then
return to forwarding that VID as untagged frames.  If we deleted the VID
rules here, we would begin dropping traffic due to VLAN membership
violations.  Fixed fm10k to use pcie_get_minimum_link(), which is useful
in cases where we connect to a slot at Gen3, but the slot is behind a bus
which is only connected at Gen2.  Updated fm10k to update the netdev
permanent address during reinit instead of up to enable users to
immediately see the new MAC address on the VF even if the device is not
up.  Adds the creation of VLAN interfaces on a device, even while the
device is down for fm10k.  Fixed an issue where we request the incorrect
MAC/VLAN combinations, and prevents us from accidentally reporting some
frames as VLAN tagged.  Provided a couple of trivial fixes for fm10k
to fix code style and typos in code comments.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Sep 17, 2015
2 parents c4047f5 + 9adbac5 commit a2f23e0
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 135 deletions.
5 changes: 3 additions & 2 deletions drivers/net/ethernet/intel/fm10k/fm10k_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ static void *fm10k_dbg_desc_seq_start(struct seq_file *s, loff_t *pos)
}

static void *fm10k_dbg_desc_seq_next(struct seq_file *s,
void __always_unused *v, loff_t *pos)
void __always_unused *v,
loff_t *pos)
{
struct fm10k_ring *ring = s->private;

return (++(*pos) < ring->count) ? pos : NULL;
}

static void fm10k_dbg_desc_seq_stop(struct seq_file __always_unused *s,
__always_unused void *v)
void __always_unused *v)
{
/* Do nothing. */
}
Expand Down
3 changes: 0 additions & 3 deletions drivers/net/ethernet/intel/fm10k/fm10k_iov.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,6 @@ int fm10k_iov_resume(struct pci_dev *pdev)
hw->iov.ops.set_lport(hw, vf_info, i,
FM10K_VF_FLAG_MULTI_CAPABLE);

/* assign our default vid to the VF following reset */
vf_info->sw_vid = hw->mac.default_vid;

/* mailbox is disconnected so we don't send a message */
hw->iov.ops.assign_default_mac_vlan(hw, vf_info);

Expand Down
12 changes: 5 additions & 7 deletions drivers/net/ethernet/intel/fm10k/fm10k_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,11 @@ static unsigned int fm10k_process_skb_fields(struct fm10k_ring *rx_ring,
if (rx_desc->w.vlan) {
u16 vid = le16_to_cpu(rx_desc->w.vlan);

if (vid != rx_ring->vid)
if ((vid & VLAN_VID_MASK) != rx_ring->vid)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
else if (vid & VLAN_PRIO_MASK)
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
vid & VLAN_PRIO_MASK);
}

fm10k_type_trans(rx_ring, rx_desc, skb);
Expand Down Expand Up @@ -1079,22 +1082,17 @@ netdev_tx_t fm10k_xmit_frame_ring(struct sk_buff *skb,
struct fm10k_tx_buffer *first;
int tso;
u32 tx_flags = 0;
#if PAGE_SIZE > FM10K_MAX_DATA_PER_TXD
unsigned short f;
#endif
u16 count = TXD_USE_COUNT(skb_headlen(skb));

/* need: 1 descriptor per page * PAGE_SIZE/FM10K_MAX_DATA_PER_TXD,
* + 1 desc for skb_headlen/FM10K_MAX_DATA_PER_TXD,
* + 2 desc gap to keep tail from touching head
* otherwise try next time
*/
#if PAGE_SIZE > FM10K_MAX_DATA_PER_TXD
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
#else
count += skb_shinfo(skb)->nr_frags;
#endif

if (fm10k_maybe_stop_tx(tx_ring, count + 3)) {
tx_ring->tx_stats.tx_busy++;
return NETDEV_TX_BUSY;
Expand Down
39 changes: 21 additions & 18 deletions drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set)
struct fm10k_intfc *interface = netdev_priv(netdev);
struct fm10k_hw *hw = &interface->hw;
s32 err;
int i;

/* updates do not apply to VLAN 0 */
if (!vid)
Expand All @@ -775,8 +776,25 @@ static int fm10k_update_vid(struct net_device *netdev, u16 vid, bool set)
if (!set)
clear_bit(vid, interface->active_vlans);

/* if default VLAN is already present do nothing */
if (vid == hw->mac.default_vid)
/* disable the default VID on ring if we have an active VLAN */
for (i = 0; i < interface->num_rx_queues; i++) {
struct fm10k_ring *rx_ring = interface->rx_ring[i];
u16 rx_vid = rx_ring->vid & (VLAN_N_VID - 1);

if (test_bit(rx_vid, interface->active_vlans))
rx_ring->vid |= FM10K_VLAN_CLEAR;
else
rx_ring->vid &= ~FM10K_VLAN_CLEAR;
}

/* Do not remove default VID related entries from VLAN and MAC tables */
if (!set && vid == hw->mac.default_vid)
return 0;

/* Do not throw an error if the interface is down. We will sync once
* we come up
*/
if (test_bit(__FM10K_DOWN, &interface->state))
return 0;

fm10k_mbx_lock(interface);
Expand Down Expand Up @@ -996,21 +1014,6 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface)
int xcast_mode;
u16 vid, glort;

/* restore our address if perm_addr is set */
if (hw->mac.type == fm10k_mac_vf) {
if (is_valid_ether_addr(hw->mac.perm_addr)) {
ether_addr_copy(hw->mac.addr, hw->mac.perm_addr);
ether_addr_copy(netdev->perm_addr, hw->mac.perm_addr);
ether_addr_copy(netdev->dev_addr, hw->mac.perm_addr);
netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
}

if (hw->mac.vlan_override)
netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
else
netdev->features |= NETIF_F_HW_VLAN_CTAG_RX;
}

/* record glort for this interface */
glort = interface->glort;

Expand Down Expand Up @@ -1045,7 +1048,7 @@ void fm10k_restore_rx_state(struct fm10k_intfc *interface)
vid, true, 0);
}

/* update xcast mode before syncronizing addresses */
/* update xcast mode before synchronizing addresses */
hw->mac.ops.update_xcast_mode(hw, glort, xcast_mode);

/* synchronize all of the addresses */
Expand Down
176 changes: 145 additions & 31 deletions drivers/net/ethernet/intel/fm10k/fm10k_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ static void fm10k_reinit(struct fm10k_intfc *interface)
/* reassociate interrupts */
fm10k_mbx_request_irq(interface);

/* update hardware address for VFs if perm_addr has changed */
if (hw->mac.type == fm10k_mac_vf) {
if (is_valid_ether_addr(hw->mac.perm_addr)) {
ether_addr_copy(hw->mac.addr, hw->mac.perm_addr);
ether_addr_copy(netdev->perm_addr, hw->mac.perm_addr);
ether_addr_copy(netdev->dev_addr, hw->mac.perm_addr);
netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
}

if (hw->mac.vlan_override)
netdev->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
else
netdev->features |= NETIF_F_HW_VLAN_CTAG_RX;
}

/* reset clock */
fm10k_ts_reset(interface);

Expand Down Expand Up @@ -663,6 +678,10 @@ static void fm10k_configure_rx_ring(struct fm10k_intfc *interface,
/* assign default VLAN to queue */
ring->vid = hw->mac.default_vid;

/* if we have an active VLAN, disable default VID */
if (test_bit(hw->mac.default_vid, interface->active_vlans))
ring->vid |= FM10K_VLAN_CLEAR;

/* Map interrupt */
if (ring->q_vector) {
rxint = ring->q_vector->v_idx + NON_Q_VECTORS(hw);
Expand Down Expand Up @@ -861,10 +880,12 @@ void fm10k_netpoll(struct net_device *netdev)

#endif
#define FM10K_ERR_MSG(type) case (type): error = #type; break
static void fm10k_print_fault(struct fm10k_intfc *interface, int type,
static void fm10k_handle_fault(struct fm10k_intfc *interface, int type,
struct fm10k_fault *fault)
{
struct pci_dev *pdev = interface->pdev;
struct fm10k_hw *hw = &interface->hw;
struct fm10k_iov_data *iov_data = interface->iov_data;
char *error;

switch (type) {
Expand Down Expand Up @@ -918,6 +939,30 @@ static void fm10k_print_fault(struct fm10k_intfc *interface, int type,
"%s Address: 0x%llx SpecInfo: 0x%x Func: %02x.%0x\n",
error, fault->address, fault->specinfo,
PCI_SLOT(fault->func), PCI_FUNC(fault->func));

/* For VF faults, clear out the respective LPORT, reset the queue
* resources, and then reconnect to the mailbox. This allows the
* VF in question to resume behavior. For transient faults that are
* the result of non-malicious behavior this will log the fault and
* allow the VF to resume functionality. Obviously for malicious VFs
* they will be able to attempt malicious behavior again. In this
* case, the system administrator will need to step in and manually
* remove or disable the VF in question.
*/
if (fault->func && iov_data) {
int vf = fault->func - 1;
struct fm10k_vf_info *vf_info = &iov_data->vf_info[vf];

hw->iov.ops.reset_lport(hw, vf_info);
hw->iov.ops.reset_resources(hw, vf_info);

/* reset_lport disables the VF, so re-enable it */
hw->iov.ops.set_lport(hw, vf_info, vf,
FM10K_VF_FLAG_MULTI_CAPABLE);

/* reset_resources will disconnect from the mbx */
vf_info->mbx.ops.connect(hw, &vf_info->mbx);
}
}

static void fm10k_report_fault(struct fm10k_intfc *interface, u32 eicr)
Expand All @@ -941,7 +986,7 @@ static void fm10k_report_fault(struct fm10k_intfc *interface, u32 eicr)
continue;
}

fm10k_print_fault(interface, type, &fault);
fm10k_handle_fault(interface, type, &fault);
}
}

Expand Down Expand Up @@ -1705,22 +1750,86 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,

static void fm10k_slot_warn(struct fm10k_intfc *interface)
{
struct device *dev = &interface->pdev->dev;
enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN;
enum pci_bus_speed speed = PCI_SPEED_UNKNOWN;
struct fm10k_hw *hw = &interface->hw;
int max_gts = 0, expected_gts = 0;

if (hw->mac.ops.is_slot_appropriate(hw))
if (pcie_get_minimum_link(interface->pdev, &speed, &width) ||
speed == PCI_SPEED_UNKNOWN || width == PCIE_LNK_WIDTH_UNKNOWN) {
dev_warn(&interface->pdev->dev,
"Unable to determine PCI Express bandwidth.\n");
return;
}

switch (speed) {
case PCIE_SPEED_2_5GT:
/* 8b/10b encoding reduces max throughput by 20% */
max_gts = 2 * width;
break;
case PCIE_SPEED_5_0GT:
/* 8b/10b encoding reduces max throughput by 20% */
max_gts = 4 * width;
break;
case PCIE_SPEED_8_0GT:
/* 128b/130b encoding has less than 2% impact on throughput */
max_gts = 8 * width;
break;
default:
dev_warn(&interface->pdev->dev,
"Unable to determine PCI Express bandwidth.\n");
return;
}

dev_info(&interface->pdev->dev,
"PCI Express bandwidth of %dGT/s available\n",
max_gts);
dev_info(&interface->pdev->dev,
"(Speed:%s, Width: x%d, Encoding Loss:%s, Payload:%s)\n",
(speed == PCIE_SPEED_8_0GT ? "8.0GT/s" :
speed == PCIE_SPEED_5_0GT ? "5.0GT/s" :
speed == PCIE_SPEED_2_5GT ? "2.5GT/s" :
"Unknown"),
hw->bus.width,
(speed == PCIE_SPEED_2_5GT ? "20%" :
speed == PCIE_SPEED_5_0GT ? "20%" :
speed == PCIE_SPEED_8_0GT ? "<2%" :
"Unknown"),
(hw->bus.payload == fm10k_bus_payload_128 ? "128B" :
hw->bus.payload == fm10k_bus_payload_256 ? "256B" :
hw->bus.payload == fm10k_bus_payload_512 ? "512B" :
"Unknown"));

dev_warn(dev,
"For optimal performance, a %s %s slot is recommended.\n",
(hw->bus_caps.width == fm10k_bus_width_pcie_x1 ? "x1" :
hw->bus_caps.width == fm10k_bus_width_pcie_x4 ? "x4" :
"x8"),
(hw->bus_caps.speed == fm10k_bus_speed_2500 ? "2.5GT/s" :
hw->bus_caps.speed == fm10k_bus_speed_5000 ? "5.0GT/s" :
"8.0GT/s"));
dev_warn(dev,
"A slot with more lanes and/or higher speed is suggested.\n");
switch (hw->bus_caps.speed) {
case fm10k_bus_speed_2500:
/* 8b/10b encoding reduces max throughput by 20% */
expected_gts = 2 * hw->bus_caps.width;
break;
case fm10k_bus_speed_5000:
/* 8b/10b encoding reduces max throughput by 20% */
expected_gts = 4 * hw->bus_caps.width;
break;
case fm10k_bus_speed_8000:
/* 128b/130b encoding has less than 2% impact on throughput */
expected_gts = 8 * hw->bus_caps.width;
break;
default:
dev_warn(&interface->pdev->dev,
"Unable to determine expected PCI Express bandwidth.\n");
return;
}

if (max_gts < expected_gts) {
dev_warn(&interface->pdev->dev,
"This device requires %dGT/s of bandwidth for optimal performance.\n",
expected_gts);
dev_warn(&interface->pdev->dev,
"A %sslot with x%d lanes is suggested.\n",
(hw->bus_caps.speed == fm10k_bus_speed_2500 ? "2.5GT/s " :
hw->bus_caps.speed == fm10k_bus_speed_5000 ? "5.0GT/s " :
hw->bus_caps.speed == fm10k_bus_speed_8000 ? "8.0GT/s " : ""),
hw->bus_caps.width);
}
}

/**
Expand All @@ -1739,7 +1848,6 @@ static int fm10k_probe(struct pci_dev *pdev,
{
struct net_device *netdev;
struct fm10k_intfc *interface;
struct fm10k_hw *hw;
int err;

err = pci_enable_device_mem(pdev);
Expand Down Expand Up @@ -1783,7 +1891,6 @@ static int fm10k_probe(struct pci_dev *pdev,

interface->netdev = netdev;
interface->pdev = pdev;
hw = &interface->hw;

interface->uc_addr = ioremap(pci_resource_start(pdev, 0),
FM10K_UC_ADDR_SIZE);
Expand Down Expand Up @@ -1825,24 +1932,12 @@ static int fm10k_probe(struct pci_dev *pdev,
/* Register PTP interface */
fm10k_ptp_register(interface);

/* print bus type/speed/width info */
dev_info(&pdev->dev, "(PCI Express:%s Width: %s Payload: %s)\n",
(hw->bus.speed == fm10k_bus_speed_8000 ? "8.0GT/s" :
hw->bus.speed == fm10k_bus_speed_5000 ? "5.0GT/s" :
hw->bus.speed == fm10k_bus_speed_2500 ? "2.5GT/s" :
"Unknown"),
(hw->bus.width == fm10k_bus_width_pcie_x8 ? "x8" :
hw->bus.width == fm10k_bus_width_pcie_x4 ? "x4" :
hw->bus.width == fm10k_bus_width_pcie_x1 ? "x1" :
"Unknown"),
(hw->bus.payload == fm10k_bus_payload_128 ? "128B" :
hw->bus.payload == fm10k_bus_payload_256 ? "256B" :
hw->bus.payload == fm10k_bus_payload_512 ? "512B" :
"Unknown"));

/* print warning for non-optimal configurations */
fm10k_slot_warn(interface);

/* report MAC address for logging */
dev_info(&pdev->dev, "%pM\n", netdev->dev_addr);

/* enable SR-IOV after registering netdev to enforce PF/VF ordering */
fm10k_iov_configure(pdev, 0);

Expand Down Expand Up @@ -1983,6 +2078,16 @@ static int fm10k_resume(struct pci_dev *pdev)
if (err)
return err;

/* assume host is not ready, to prevent race with watchdog in case we
* actually don't have connection to the switch
*/
interface->host_ready = false;
fm10k_watchdog_host_not_ready(interface);

/* clear the service task disable bit to allow service task to start */
clear_bit(__FM10K_SERVICE_DISABLE, &interface->state);
fm10k_service_event_schedule(interface);

/* restore SR-IOV interface */
fm10k_iov_resume(pdev);

Expand Down Expand Up @@ -2010,6 +2115,15 @@ static int fm10k_suspend(struct pci_dev *pdev,

fm10k_iov_suspend(pdev);

/* the watchdog tasks may read registers, which will appear like a
* surprise-remove event once the PCI device is disabled. This will
* cause us to close the netdevice, so we don't retain the open/closed
* state post-resume. Prevent this by disabling the service task while
* suspended, until we actually resume.
*/
set_bit(__FM10K_SERVICE_DISABLE, &interface->state);
cancel_work_sync(&interface->service_task);

rtnl_lock();

if (netif_running(netdev))
Expand Down
Loading

0 comments on commit a2f23e0

Please sign in to comment.