Commit d9601be1 authored by David S. Miller's avatar David S. Miller

Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
100GbE Intel Wired LAN Driver Updates 2017-10-02

This series contains updates to fm10k only.

Jake provides all but one of the changes in this series.  Most are small
fixes, starting with ensuring prompt transmission of messages queued up
after each VF message is received and handled.  Fix a possible race
condition between the watchdog task and the processing of mailbox
messages by just checking whether the mailbox is still open.  Fix a
couple of GCC v7 warnings, including misspelled "fall through" comments
and warnings about possible truncation of calls to snprintf().  Cleaned
up a convoluted bitshift and read for the PFVFLRE register.  Fixed a
potential divide by zero when finding the proper r_idx.

Markus Elfring fixes an issue which was found using Coccinelle, where
we should have been using seq_putc() instead of seq_puts().
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c4b3630a 04914390
/* Intel(R) Ethernet Switch Host Interface Driver /* Intel(R) Ethernet Switch Host Interface Driver
* Copyright(c) 2013 - 2016 Intel Corporation. * Copyright(c) 2013 - 2017 Intel Corporation.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -517,8 +517,8 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready) ...@@ -517,8 +517,8 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready)
goto out; goto out;
} }
/* verify Mailbox is still valid */ /* verify Mailbox is still open */
if (!mbx->ops.tx_ready(mbx, FM10K_VFMBX_MSG_MTU)) if (mbx->state != FM10K_STATE_OPEN)
goto out; goto out;
/* interface cannot receive traffic without logical ports */ /* interface cannot receive traffic without logical ports */
......
...@@ -52,9 +52,9 @@ static void fm10k_dbg_desc_seq_stop(struct seq_file __always_unused *s, ...@@ -52,9 +52,9 @@ static void fm10k_dbg_desc_seq_stop(struct seq_file __always_unused *s,
static void fm10k_dbg_desc_break(struct seq_file *s, int i) static void fm10k_dbg_desc_break(struct seq_file *s, int i)
{ {
while (i--) while (i--)
seq_puts(s, "-"); seq_putc(s, '-');
seq_puts(s, "\n"); seq_putc(s, '\n');
} }
static int fm10k_dbg_tx_desc_seq_show(struct seq_file *s, void *v) static int fm10k_dbg_tx_desc_seq_show(struct seq_file *s, void *v)
......
/* Intel(R) Ethernet Switch Host Interface Driver /* Intel(R) Ethernet Switch Host Interface Driver
* Copyright(c) 2013 - 2016 Intel Corporation. * Copyright(c) 2013 - 2017 Intel Corporation.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -66,11 +66,8 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface) ...@@ -66,11 +66,8 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface)
goto read_unlock; goto read_unlock;
/* read VFLRE to determine if any VFs have been reset */ /* read VFLRE to determine if any VFs have been reset */
do { vflre = fm10k_read_reg(hw, FM10K_PFVFLRE(1));
vflre = fm10k_read_reg(hw, FM10K_PFVFLRE(0));
vflre <<= 32; vflre <<= 32;
vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(1));
vflre = (vflre << 32) | (vflre >> 32);
vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(0)); vflre |= fm10k_read_reg(hw, FM10K_PFVFLRE(0));
i = iov_data->num_vfs; i = iov_data->num_vfs;
...@@ -84,7 +81,6 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface) ...@@ -84,7 +81,6 @@ s32 fm10k_iov_event(struct fm10k_intfc *interface)
hw->iov.ops.reset_resources(hw, vf_info); hw->iov.ops.reset_resources(hw, vf_info);
vf_info->mbx.ops.connect(hw, &vf_info->mbx); vf_info->mbx.ops.connect(hw, &vf_info->mbx);
} }
} while (i != iov_data->num_vfs);
read_unlock: read_unlock:
rcu_read_unlock(); rcu_read_unlock();
...@@ -126,6 +122,9 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface) ...@@ -126,6 +122,9 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface)
struct fm10k_mbx_info *mbx = &vf_info->mbx; struct fm10k_mbx_info *mbx = &vf_info->mbx;
u16 glort = vf_info->glort; u16 glort = vf_info->glort;
/* process the SM mailbox first to drain outgoing messages */
hw->mbx.ops.process(hw, &hw->mbx);
/* verify port mapping is valid, if not reset port */ /* verify port mapping is valid, if not reset port */
if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort)) if (vf_info->vf_flags && !fm10k_glort_valid_pf(hw, glort))
hw->iov.ops.reset_lport(hw, vf_info); hw->iov.ops.reset_lport(hw, vf_info);
...@@ -140,6 +139,10 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface) ...@@ -140,6 +139,10 @@ s32 fm10k_iov_mbx(struct fm10k_intfc *interface)
if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) { if (!hw->mbx.ops.tx_ready(&hw->mbx, FM10K_VFMBX_MSG_MTU)) {
/* keep track of how many times this occurs */ /* keep track of how many times this occurs */
interface->hw_sm_mbx_full++; interface->hw_sm_mbx_full++;
/* make sure we try again momentarily */
fm10k_service_event_schedule(interface);
break; break;
} }
......
...@@ -876,6 +876,7 @@ static void fm10k_tx_csum(struct fm10k_ring *tx_ring, ...@@ -876,6 +876,7 @@ static void fm10k_tx_csum(struct fm10k_ring *tx_ring,
case IPPROTO_GRE: case IPPROTO_GRE:
if (skb->encapsulation) if (skb->encapsulation)
break; break;
/* fall through */
default: default:
if (unlikely(net_ratelimit())) { if (unlikely(net_ratelimit())) {
dev_warn(tx_ring->dev, dev_warn(tx_ring->dev,
......
/* Intel(R) Ethernet Switch Host Interface Driver /* Intel(R) Ethernet Switch Host Interface Driver
* Copyright(c) 2013 - 2016 Intel Corporation. * Copyright(c) 2013 - 2017 Intel Corporation.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -1586,7 +1586,7 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx, ...@@ -1586,7 +1586,7 @@ s32 fm10k_pfvf_mbx_init(struct fm10k_hw *hw, struct fm10k_mbx_info *mbx,
mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0); mbx->mbmem_reg = FM10K_MBMEM_VF(id, 0);
break; break;
} }
/* fallthough */ /* fall through */
default: default:
return FM10K_MBX_ERR_NO_MBX; return FM10K_MBX_ERR_NO_MBX;
} }
......
...@@ -643,9 +643,13 @@ int fm10k_close(struct net_device *netdev) ...@@ -643,9 +643,13 @@ int fm10k_close(struct net_device *netdev)
static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev) static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
{ {
struct fm10k_intfc *interface = netdev_priv(dev); struct fm10k_intfc *interface = netdev_priv(dev);
int num_tx_queues = READ_ONCE(interface->num_tx_queues);
unsigned int r_idx = skb->queue_mapping; unsigned int r_idx = skb->queue_mapping;
int err; int err;
if (!num_tx_queues)
return NETDEV_TX_BUSY;
if ((skb->protocol == htons(ETH_P_8021Q)) && if ((skb->protocol == htons(ETH_P_8021Q)) &&
!skb_vlan_tag_present(skb)) { !skb_vlan_tag_present(skb)) {
/* FM10K only supports hardware tagging, any tags in frame /* FM10K only supports hardware tagging, any tags in frame
...@@ -698,8 +702,8 @@ static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev) ...@@ -698,8 +702,8 @@ static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
__skb_put(skb, pad_len); __skb_put(skb, pad_len);
} }
if (r_idx >= interface->num_tx_queues) if (r_idx >= num_tx_queues)
r_idx %= interface->num_tx_queues; r_idx %= num_tx_queues;
err = fm10k_xmit_frame_ring(skb, interface->tx_ring[r_idx]); err = fm10k_xmit_frame_ring(skb, interface->tx_ring[r_idx]);
......
...@@ -118,6 +118,27 @@ static void fm10k_service_event_complete(struct fm10k_intfc *interface) ...@@ -118,6 +118,27 @@ static void fm10k_service_event_complete(struct fm10k_intfc *interface)
fm10k_service_event_schedule(interface); fm10k_service_event_schedule(interface);
} }
static void fm10k_stop_service_event(struct fm10k_intfc *interface)
{
set_bit(__FM10K_SERVICE_DISABLE, interface->state);
cancel_work_sync(&interface->service_task);
/* It's possible that cancel_work_sync stopped the service task from
* running before it could actually start. In this case the
* __FM10K_SERVICE_SCHED bit will never be cleared. Since we know that
* the service task cannot be running at this point, we need to clear
* the scheduled bit, as otherwise the service task may never be
* restarted.
*/
clear_bit(__FM10K_SERVICE_SCHED, interface->state);
}
static void fm10k_start_service_event(struct fm10k_intfc *interface)
{
clear_bit(__FM10K_SERVICE_DISABLE, interface->state);
fm10k_service_event_schedule(interface);
}
/** /**
* fm10k_service_timer - Timer Call-back * fm10k_service_timer - Timer Call-back
* @data: pointer to interface cast into an unsigned long * @data: pointer to interface cast into an unsigned long
...@@ -132,35 +153,6 @@ static void fm10k_service_timer(unsigned long data) ...@@ -132,35 +153,6 @@ static void fm10k_service_timer(unsigned long data)
fm10k_service_event_schedule(interface); fm10k_service_event_schedule(interface);
} }
static void fm10k_detach_subtask(struct fm10k_intfc *interface)
{
struct net_device *netdev = interface->netdev;
u32 __iomem *hw_addr;
u32 value;
/* do nothing if device is still present or hw_addr is set */
if (netif_device_present(netdev) || interface->hw.hw_addr)
return;
/* check the real address space to see if we've recovered */
hw_addr = READ_ONCE(interface->uc_addr);
value = readl(hw_addr);
if (~value) {
interface->hw.hw_addr = interface->uc_addr;
netif_device_attach(netdev);
set_bit(FM10K_FLAG_RESET_REQUESTED, interface->flags);
netdev_warn(netdev, "PCIe link restored, device now attached\n");
return;
}
rtnl_lock();
if (netif_running(netdev))
dev_close(netdev);
rtnl_unlock();
}
static void fm10k_prepare_for_reset(struct fm10k_intfc *interface) static void fm10k_prepare_for_reset(struct fm10k_intfc *interface)
{ {
struct net_device *netdev = interface->netdev; struct net_device *netdev = interface->netdev;
...@@ -270,6 +262,35 @@ static int fm10k_handle_reset(struct fm10k_intfc *interface) ...@@ -270,6 +262,35 @@ static int fm10k_handle_reset(struct fm10k_intfc *interface)
return err; return err;
} }
static void fm10k_detach_subtask(struct fm10k_intfc *interface)
{
struct net_device *netdev = interface->netdev;
u32 __iomem *hw_addr;
u32 value;
/* do nothing if device is still present or hw_addr is set */
if (netif_device_present(netdev) || interface->hw.hw_addr)
return;
/* check the real address space to see if we've recovered */
hw_addr = READ_ONCE(interface->uc_addr);
value = readl(hw_addr);
if (~value) {
interface->hw.hw_addr = interface->uc_addr;
netif_device_attach(netdev);
set_bit(FM10K_FLAG_RESET_REQUESTED, interface->flags);
netdev_warn(netdev, "PCIe link restored, device now attached\n");
return;
}
rtnl_lock();
if (netif_running(netdev))
dev_close(netdev);
rtnl_unlock();
}
static void fm10k_reinit(struct fm10k_intfc *interface) static void fm10k_reinit(struct fm10k_intfc *interface)
{ {
int err; int err;
...@@ -1544,7 +1565,7 @@ int fm10k_qv_request_irq(struct fm10k_intfc *interface) ...@@ -1544,7 +1565,7 @@ int fm10k_qv_request_irq(struct fm10k_intfc *interface)
struct net_device *dev = interface->netdev; struct net_device *dev = interface->netdev;
struct fm10k_hw *hw = &interface->hw; struct fm10k_hw *hw = &interface->hw;
struct msix_entry *entry; struct msix_entry *entry;
int ri = 0, ti = 0; unsigned int ri = 0, ti = 0;
int vector, err; int vector, err;
entry = &interface->msix_entries[NON_Q_VECTORS(hw)]; entry = &interface->msix_entries[NON_Q_VECTORS(hw)];
...@@ -1554,15 +1575,15 @@ int fm10k_qv_request_irq(struct fm10k_intfc *interface) ...@@ -1554,15 +1575,15 @@ int fm10k_qv_request_irq(struct fm10k_intfc *interface)
/* name the vector */ /* name the vector */
if (q_vector->tx.count && q_vector->rx.count) { if (q_vector->tx.count && q_vector->rx.count) {
snprintf(q_vector->name, sizeof(q_vector->name) - 1, snprintf(q_vector->name, sizeof(q_vector->name),
"%s-TxRx-%d", dev->name, ri++); "%s-TxRx-%u", dev->name, ri++);
ti++; ti++;
} else if (q_vector->rx.count) { } else if (q_vector->rx.count) {
snprintf(q_vector->name, sizeof(q_vector->name) - 1, snprintf(q_vector->name, sizeof(q_vector->name),
"%s-rx-%d", dev->name, ri++); "%s-rx-%u", dev->name, ri++);
} else if (q_vector->tx.count) { } else if (q_vector->tx.count) {
snprintf(q_vector->name, sizeof(q_vector->name) - 1, snprintf(q_vector->name, sizeof(q_vector->name),
"%s-tx-%d", dev->name, ti++); "%s-tx-%u", dev->name, ti++);
} else { } else {
/* skip this unused q_vector */ /* skip this unused q_vector */
continue; continue;
...@@ -1800,9 +1821,6 @@ static int fm10k_sw_init(struct fm10k_intfc *interface, ...@@ -1800,9 +1821,6 @@ static int fm10k_sw_init(struct fm10k_intfc *interface,
netdev->vlan_features |= NETIF_F_HIGHDMA; netdev->vlan_features |= NETIF_F_HIGHDMA;
} }
/* delay any future reset requests */
interface->last_reset = jiffies + (10 * HZ);
/* reset and initialize the hardware so it is in a known state */ /* reset and initialize the hardware so it is in a known state */
err = hw->mac.ops.reset_hw(hw); err = hw->mac.ops.reset_hw(hw);
if (err) { if (err) {
...@@ -2079,8 +2097,9 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2079,8 +2097,9 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* enable SR-IOV after registering netdev to enforce PF/VF ordering */ /* enable SR-IOV after registering netdev to enforce PF/VF ordering */
fm10k_iov_configure(pdev, 0); fm10k_iov_configure(pdev, 0);
/* clear the service task disable bit to allow service task to start */ /* clear the service task disable bit and kick off service task */
clear_bit(__FM10K_SERVICE_DISABLE, interface->state); clear_bit(__FM10K_SERVICE_DISABLE, interface->state);
fm10k_service_event_schedule(interface);
return 0; return 0;
...@@ -2118,8 +2137,7 @@ static void fm10k_remove(struct pci_dev *pdev) ...@@ -2118,8 +2137,7 @@ static void fm10k_remove(struct pci_dev *pdev)
del_timer_sync(&interface->service_timer); del_timer_sync(&interface->service_timer);
set_bit(__FM10K_SERVICE_DISABLE, interface->state); fm10k_stop_service_event(interface);
cancel_work_sync(&interface->service_task);
/* free netdev, this may bounce the interrupts due to setup_tc */ /* free netdev, this may bounce the interrupts due to setup_tc */
if (netdev->reg_state == NETREG_REGISTERED) if (netdev->reg_state == NETREG_REGISTERED)
...@@ -2157,8 +2175,7 @@ static void fm10k_prepare_suspend(struct fm10k_intfc *interface) ...@@ -2157,8 +2175,7 @@ static void fm10k_prepare_suspend(struct fm10k_intfc *interface)
* stopped. We stop the watchdog task until after we resume software * stopped. We stop the watchdog task until after we resume software
* activity. * activity.
*/ */
set_bit(__FM10K_SERVICE_DISABLE, interface->state); fm10k_stop_service_event(interface);
cancel_work_sync(&interface->service_task);
fm10k_prepare_for_reset(interface); fm10k_prepare_for_reset(interface);
} }
...@@ -2185,9 +2202,8 @@ static int fm10k_handle_resume(struct fm10k_intfc *interface) ...@@ -2185,9 +2202,8 @@ static int fm10k_handle_resume(struct fm10k_intfc *interface)
interface->link_down_event = jiffies + (HZ); interface->link_down_event = jiffies + (HZ);
set_bit(__FM10K_LINK_DOWN, interface->state); set_bit(__FM10K_LINK_DOWN, interface->state);
/* clear the service task disable bit to allow service task to start */ /* restart the service task */
clear_bit(__FM10K_SERVICE_DISABLE, interface->state); fm10k_start_service_event(interface);
fm10k_service_event_schedule(interface);
return err; return err;
} }
......
/* Intel(R) Ethernet Switch Host Interface Driver /* Intel(R) Ethernet Switch Host Interface Driver
* Copyright(c) 2013 - 2016 Intel Corporation. * Copyright(c) 2013 - 2017 Intel Corporation.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -1334,19 +1334,19 @@ static u8 fm10k_iov_supported_xcast_mode_pf(struct fm10k_vf_info *vf_info, ...@@ -1334,19 +1334,19 @@ static u8 fm10k_iov_supported_xcast_mode_pf(struct fm10k_vf_info *vf_info,
case FM10K_XCAST_MODE_PROMISC: case FM10K_XCAST_MODE_PROMISC:
if (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE) if (vf_flags & FM10K_VF_FLAG_PROMISC_CAPABLE)
return FM10K_XCAST_MODE_PROMISC; return FM10K_XCAST_MODE_PROMISC;
/* fallthough */ /* fall through */
case FM10K_XCAST_MODE_ALLMULTI: case FM10K_XCAST_MODE_ALLMULTI:
if (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE) if (vf_flags & FM10K_VF_FLAG_ALLMULTI_CAPABLE)
return FM10K_XCAST_MODE_ALLMULTI; return FM10K_XCAST_MODE_ALLMULTI;
/* fallthough */ /* fall through */
case FM10K_XCAST_MODE_MULTI: case FM10K_XCAST_MODE_MULTI:
if (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE) if (vf_flags & FM10K_VF_FLAG_MULTI_CAPABLE)
return FM10K_XCAST_MODE_MULTI; return FM10K_XCAST_MODE_MULTI;
/* fallthough */ /* fall through */
case FM10K_XCAST_MODE_NONE: case FM10K_XCAST_MODE_NONE:
if (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE) if (vf_flags & FM10K_VF_FLAG_NONE_CAPABLE)
return FM10K_XCAST_MODE_NONE; return FM10K_XCAST_MODE_NONE;
/* fallthough */ /* fall through */
default: default:
break; break;
} }
......
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