Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Browse files Browse the repository at this point in the history
Pull networking fixes from David Miller:

 1) We've discovered a common error in several networking drivers, they
    put VLAN offload features into ->vlan_features, which would suggest
    that they support offloading 2 or more levels of VLAN encapsulation.
    Not only do these devices not do that, but we don't have the
    infrastructure yet to handle that at all.

    Fixes from Vlad Yasevich.

 2) Fix tcpdump crash with bridging and vlans, also from Vlad.

 3) Some MAINTAINERS updates for random32 and bonding.

 4) Fix late reseeds of prandom generator, from Sasha Levin.

 5) Bridge doesn't handle stacked vlans properly, fix from Toshiaki
    Makita.

 6) Fix deadlock in openvswitch, from Flavio Leitner.

 7) get_timewait4_sock() doesn't report delay times correctly, fix from
    Eric Dumazet.

 8) Duplicate address detection and addrconf verification need to run in
    contexts where RTNL can be obtained.  Move them to run from a
    workqueue.  From Hannes Frederic Sowa.

 9) Fix route refcount leaking in ip tunnels, from Pravin B Shelar.

10) Don't return -EINTR from non-blocking recvmsg() on AF_UNIX sockets,
    from Eric Dumazet.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (28 commits)
  vlan: Warn the user if lowerdev has bad vlan features.
  veth: Turn off vlan rx acceleration in vlan_features
  ifb: Remove vlan acceleration from vlan_features
  qlge: Do not propaged vlan tag offloads to vlans
  bridge: Fix crash with vlan filtering and tcpdump
  net: Account for all vlan headers in skb_mac_gso_segment
  MAINTAINERS: bonding: change email address
  MAINTAINERS: bonding: change email address
  ipv6: move DAD and addrconf_verify processing to workqueue
  tcp: fix get_timewait4_sock() delay computation on 64bit
  openvswitch: fix a possible deadlock and lockdep warning
  bridge: Fix handling stacked vlan tags
  bridge: Fix inabillity to retrieve vlan tags when tx offload is disabled
  vhost: validate vhost_get_vq_desc return value
  vhost: fix total length when packets are too short
  random32: avoid attempt to late reseed if in the middle of seeding
  random32: assign to network folks in MAINTAINERS
  net/mlx4_core: pass pci_device_id.driver_data to __mlx4_init_one during reset
  core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors
  vlan: Set hard_header_len according to available acceleration
  ...
  • Loading branch information
Linus Torvalds committed Mar 28, 2014
2 parents bc53267 + 5f2feca commit 49d8137
Show file tree
Hide file tree
Showing 32 changed files with 363 additions and 195 deletions.
5 changes: 3 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1832,8 +1832,8 @@ F: net/bluetooth/
F: include/net/bluetooth/

BONDING DRIVER
M: Jay Vosburgh <fubar@us.ibm.com>
M: Veaceslav Falico <vfalico@redhat.com>
M: Jay Vosburgh <j.vosburgh@gmail.com>
M: Veaceslav Falico <vfalico@gmail.com>
M: Andy Gospodarek <andy@greyhouse.net>
L: netdev@vger.kernel.org
W: http://sourceforge.net/projects/bonding/
Expand Down Expand Up @@ -6006,6 +6006,7 @@ F: include/uapi/linux/net.h
F: include/uapi/linux/netdevice.h
F: tools/net/
F: tools/testing/selftests/net/
F: lib/random32.c

NETWORKING [IPv4/IPv6]
M: "David S. Miller" <davem@davemloft.net>
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -17649,8 +17649,6 @@ static int tg3_init_one(struct pci_dev *pdev,

tg3_init_bufmgr_config(tp);

features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX;

/* 5700 B0 chips do not support checksumming correctly due
* to hardware bugs.
*/
Expand Down Expand Up @@ -17682,7 +17680,8 @@ static int tg3_init_one(struct pci_dev *pdev,
features |= NETIF_F_TSO_ECN;
}

dev->features |= features;
dev->features |= features | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX;
dev->vlan_features |= features;

/*
Expand Down
60 changes: 20 additions & 40 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_mdio.h>
Expand Down Expand Up @@ -88,8 +89,9 @@
#define MVNETA_TX_IN_PRGRS BIT(1)
#define MVNETA_TX_FIFO_EMPTY BIT(8)
#define MVNETA_RX_MIN_FRAME_SIZE 0x247c
#define MVNETA_SGMII_SERDES_CFG 0x24A0
#define MVNETA_SERDES_CFG 0x24A0
#define MVNETA_SGMII_SERDES_PROTO 0x0cc7
#define MVNETA_RGMII_SERDES_PROTO 0x0667
#define MVNETA_TYPE_PRIO 0x24bc
#define MVNETA_FORCE_UNI BIT(21)
#define MVNETA_TXQ_CMD_1 0x24e4
Expand Down Expand Up @@ -161,7 +163,7 @@
#define MVNETA_GMAC_MAX_RX_SIZE_MASK 0x7ffc
#define MVNETA_GMAC0_PORT_ENABLE BIT(0)
#define MVNETA_GMAC_CTRL_2 0x2c08
#define MVNETA_GMAC2_PSC_ENABLE BIT(3)
#define MVNETA_GMAC2_PCS_ENABLE BIT(3)
#define MVNETA_GMAC2_PORT_RGMII BIT(4)
#define MVNETA_GMAC2_PORT_RESET BIT(6)
#define MVNETA_GMAC_STATUS 0x2c10
Expand Down Expand Up @@ -710,35 +712,6 @@ static void mvneta_rxq_bm_disable(struct mvneta_port *pp,
mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
}



/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */
static void mvneta_gmac_rgmii_set(struct mvneta_port *pp, int enable)
{
u32 val;

val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);

if (enable)
val |= MVNETA_GMAC2_PORT_RGMII;
else
val &= ~MVNETA_GMAC2_PORT_RGMII;

mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
}

/* Config SGMII port */
static void mvneta_port_sgmii_config(struct mvneta_port *pp)
{
u32 val;

val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
val |= MVNETA_GMAC2_PSC_ENABLE;
mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);

mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
}

/* Start the Ethernet port RX and TX activity */
static void mvneta_port_up(struct mvneta_port *pp)
{
Expand Down Expand Up @@ -2756,12 +2729,15 @@ static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);

if (phy_mode == PHY_INTERFACE_MODE_SGMII)
mvneta_port_sgmii_config(pp);
mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO);
else
mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_RGMII_SERDES_PROTO);

val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);

mvneta_gmac_rgmii_set(pp, 1);
val |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII;

/* Cancel Port Reset */
val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
val &= ~MVNETA_GMAC2_PORT_RESET;
mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);

Expand All @@ -2774,6 +2750,7 @@ static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
static int mvneta_probe(struct platform_device *pdev)
{
const struct mbus_dram_target_info *dram_target_info;
struct resource *res;
struct device_node *dn = pdev->dev.of_node;
struct device_node *phy_node;
u32 phy_addr;
Expand Down Expand Up @@ -2838,17 +2815,23 @@ static int mvneta_probe(struct platform_device *pdev)

clk_prepare_enable(pp->clk);

pp->base = of_iomap(dn, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
err = -ENODEV;
goto err_clk;
}

pp->base = devm_ioremap_resource(&pdev->dev, res);
if (pp->base == NULL) {
err = -ENOMEM;
err = PTR_ERR(pp->base);
goto err_clk;
}

/* Alloc per-cpu stats */
pp->stats = alloc_percpu(struct mvneta_pcpu_stats);
if (!pp->stats) {
err = -ENOMEM;
goto err_unmap;
goto err_clk;
}

for_each_possible_cpu(cpu) {
Expand Down Expand Up @@ -2913,8 +2896,6 @@ static int mvneta_probe(struct platform_device *pdev)
mvneta_deinit(pp);
err_free_stats:
free_percpu(pp->stats);
err_unmap:
iounmap(pp->base);
err_clk:
clk_disable_unprepare(pp->clk);
err_free_irq:
Expand All @@ -2934,7 +2915,6 @@ static int mvneta_remove(struct platform_device *pdev)
mvneta_deinit(pp);
clk_disable_unprepare(pp->clk);
free_percpu(pp->stats);
iounmap(pp->base);
irq_dispose_mapping(dev->irq);
free_netdev(dev);

Expand Down
6 changes: 5 additions & 1 deletion drivers/net/ethernet/mellanox/mlx4/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2681,7 +2681,11 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,

static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
{
int ret = __mlx4_init_one(pdev, 0);
const struct pci_device_id *id;
int ret;

id = pci_match_id(mlx4_pci_table, pdev);
ret = __mlx4_init_one(pdev, id->driver_data);

return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
}
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/ethernet/qlogic/qlge/qlge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4765,7 +4765,9 @@ static int qlge_probe(struct pci_dev *pdev,
ndev->features = ndev->hw_features;
ndev->vlan_features = ndev->hw_features;
/* vlan gets same features (except vlan filter) */
ndev->vlan_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
ndev->vlan_features &= ~(NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX);

if (test_bit(QL_DMA64, &qdev->flags))
ndev->features |= NETIF_F_HIGHDMA;
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ifb.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ static void ifb_setup(struct net_device *dev)
dev->tx_queue_len = TX_Q_LIMIT;

dev->features |= IFB_FEATURES;
dev->vlan_features |= IFB_FEATURES;
dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX);

dev->flags |= IFF_NOARP;
dev->flags &= ~IFF_MULTICAST;
Expand Down
33 changes: 19 additions & 14 deletions drivers/net/usb/usbnet.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,14 +752,12 @@ EXPORT_SYMBOL_GPL(usbnet_unlink_rx_urbs);
// precondition: never called in_interrupt
static void usbnet_terminate_urbs(struct usbnet *dev)
{
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
DECLARE_WAITQUEUE(wait, current);
int temp;

/* ensure there are no more active urbs */
add_wait_queue(&unlink_wakeup, &wait);
add_wait_queue(&dev->wait, &wait);
set_current_state(TASK_UNINTERRUPTIBLE);
dev->wait = &unlink_wakeup;
temp = unlink_urbs(dev, &dev->txq) +
unlink_urbs(dev, &dev->rxq);

Expand All @@ -773,15 +771,14 @@ static void usbnet_terminate_urbs(struct usbnet *dev)
"waited for %d urb completions\n", temp);
}
set_current_state(TASK_RUNNING);
dev->wait = NULL;
remove_wait_queue(&unlink_wakeup, &wait);
remove_wait_queue(&dev->wait, &wait);
}

int usbnet_stop (struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
struct driver_info *info = dev->driver_info;
int retval;
int retval, pm;

clear_bit(EVENT_DEV_OPEN, &dev->flags);
netif_stop_queue (net);
Expand All @@ -791,6 +788,8 @@ int usbnet_stop (struct net_device *net)
net->stats.rx_packets, net->stats.tx_packets,
net->stats.rx_errors, net->stats.tx_errors);

/* to not race resume */
pm = usb_autopm_get_interface(dev->intf);
/* allow minidriver to stop correctly (wireless devices to turn off
* radio etc) */
if (info->stop) {
Expand All @@ -817,6 +816,9 @@ int usbnet_stop (struct net_device *net)
dev->flags = 0;
del_timer_sync (&dev->delay);
tasklet_kill (&dev->bh);
if (!pm)
usb_autopm_put_interface(dev->intf);

if (info->manage_power &&
!test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags))
info->manage_power(dev, 0);
Expand Down Expand Up @@ -1437,11 +1439,12 @@ static void usbnet_bh (unsigned long param)
/* restart RX again after disabling due to high error rate */
clear_bit(EVENT_RX_KILL, &dev->flags);

// waiting for all pending urbs to complete?
if (dev->wait) {
if ((dev->txq.qlen + dev->rxq.qlen + dev->done.qlen) == 0) {
wake_up (dev->wait);
}
/* waiting for all pending urbs to complete?
* only then can we forgo submitting anew
*/
if (waitqueue_active(&dev->wait)) {
if (dev->txq.qlen + dev->rxq.qlen + dev->done.qlen == 0)
wake_up_all(&dev->wait);

// or are we maybe short a few urbs?
} else if (netif_running (dev->net) &&
Expand Down Expand Up @@ -1580,6 +1583,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
dev->driver_name = name;
dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
| NETIF_MSG_PROBE | NETIF_MSG_LINK);
init_waitqueue_head(&dev->wait);
skb_queue_head_init (&dev->rxq);
skb_queue_head_init (&dev->txq);
skb_queue_head_init (&dev->done);
Expand Down Expand Up @@ -1791,9 +1795,10 @@ int usbnet_resume (struct usb_interface *intf)
spin_unlock_irq(&dev->txq.lock);

if (test_bit(EVENT_DEV_OPEN, &dev->flags)) {
/* handle remote wakeup ASAP */
if (!dev->wait &&
netif_device_present(dev->net) &&
/* handle remote wakeup ASAP
* we cannot race against stop
*/
if (netif_device_present(dev->net) &&
!timer_pending(&dev->delay) &&
!test_bit(EVENT_RX_HALT, &dev->flags))
rx_alloc_submit(dev, GFP_NOIO);
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/veth.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,10 @@ static void veth_setup(struct net_device *dev)
dev->features |= NETIF_F_LLTX;
dev->features |= VETH_FEATURES;
dev->vlan_features = dev->features &
~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX);
~(NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_STAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_STAG_RX);
dev->destructor = veth_dev_free;

dev->hw_features = VETH_FEATURES;
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,7 @@ static bool try_fill_recv(struct receive_queue *rq, gfp_t gfp)
if (err)
break;
} while (rq->vq->num_free);
if (unlikely(!virtqueue_kick(rq->vq)))
return false;
virtqueue_kick(rq->vq);
return !oom;
}

Expand Down Expand Up @@ -877,7 +876,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
err = xmit_skb(sq, skb);

/* This should not happen! */
if (unlikely(err) || unlikely(!virtqueue_kick(sq->vq))) {
if (unlikely(err)) {
dev->stats.tx_fifo_errors++;
if (net_ratelimit())
dev_warn(&dev->dev,
Expand All @@ -886,6 +885,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
kfree_skb(skb);
return NETDEV_TX_OK;
}
virtqueue_kick(sq->vq);

/* Don't wait up for transmitted skbs to be freed. */
skb_orphan(skb);
Expand Down
20 changes: 19 additions & 1 deletion drivers/vhost/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,9 +505,13 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
r = -ENOBUFS;
goto err;
}
d = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg,
r = vhost_get_vq_desc(vq->dev, vq, vq->iov + seg,
ARRAY_SIZE(vq->iov) - seg, &out,
&in, log, log_num);
if (unlikely(r < 0))
goto err;

d = r;
if (d == vq->num) {
r = 0;
goto err;
Expand All @@ -532,6 +536,12 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
*iovcount = seg;
if (unlikely(log))
*log_num = nlogs;

/* Detect overrun */
if (unlikely(datalen > 0)) {
r = UIO_MAXIOV + 1;
goto err;
}
return headcount;
err:
vhost_discard_vq_desc(vq, headcount);
Expand Down Expand Up @@ -587,6 +597,14 @@ static void handle_rx(struct vhost_net *net)
/* On error, stop handling until the next kick. */
if (unlikely(headcount < 0))
break;
/* On overrun, truncate and discard */
if (unlikely(headcount > UIO_MAXIOV)) {
msg.msg_iovlen = 1;
err = sock->ops->recvmsg(NULL, sock, &msg,
1, MSG_DONTWAIT | MSG_TRUNC);
pr_debug("Discarded rx packet: len %zd\n", sock_len);
continue;
}
/* OK, now we need to know about added descriptors. */
if (!headcount) {
if (unlikely(vhost_enable_notify(&net->dev, vq))) {
Expand Down
7 changes: 7 additions & 0 deletions include/linux/netdev_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,11 @@ enum {
/* changeable features with no special hardware requirements */
#define NETIF_F_SOFT_FEATURES (NETIF_F_GSO | NETIF_F_GRO)

#define NETIF_F_VLAN_FEATURES (NETIF_F_HW_VLAN_CTAG_FILTER | \
NETIF_F_HW_VLAN_CTAG_RX | \
NETIF_F_HW_VLAN_CTAG_TX | \
NETIF_F_HW_VLAN_STAG_FILTER | \
NETIF_F_HW_VLAN_STAG_RX | \
NETIF_F_HW_VLAN_STAG_TX)

#endif /* _LINUX_NETDEV_FEATURES_H */
Loading

0 comments on commit 49d8137

Please sign in to comment.