summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bnx2x/bnx2x.h4
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c1
-rw-r--r--drivers/net/bnx2x/bnx2x_stats.c37
-rw-r--r--drivers/net/bonding/bond_alb.c2
-rw-r--r--drivers/net/igb/igb_main.c9
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c9
-rw-r--r--drivers/net/macvlan.c10
-rw-r--r--drivers/net/macvtap.c18
-rw-r--r--drivers/net/s2io.h2
-rw-r--r--drivers/net/tun.c14
-rw-r--r--drivers/net/wimax/i2400m/i2400m-usb.h1
-rw-r--r--drivers/net/wimax/i2400m/usb.c2
12 files changed, 88 insertions, 21 deletions
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 817b0887f8cd..53af9c93e75c 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -863,6 +863,10 @@ struct bnx2x {
/* used to synchronize stats collecting */
int stats_state;
+
+ /* used for synchronization of concurrent threads statistics handling */
+ spinlock_t stats_lock;
+
/* used by dmae command loader */
struct dmae_command stats_dmae;
int executer_idx;
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 75568f111754..b4ec2b02a465 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -6714,6 +6714,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp)
mutex_init(&bp->port.phy_mutex);
mutex_init(&bp->fw_mb_mutex);
+ spin_lock_init(&bp->stats_lock);
#ifdef BCM_CNIC
mutex_init(&bp->cnic_mutex);
#endif
diff --git a/drivers/net/bnx2x/bnx2x_stats.c b/drivers/net/bnx2x/bnx2x_stats.c
index 3f5127720423..c74724461020 100644
--- a/drivers/net/bnx2x/bnx2x_stats.c
+++ b/drivers/net/bnx2x/bnx2x_stats.c
@@ -156,6 +156,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
struct eth_query_ramrod_data ramrod_data = {0};
int i, rc;
+ spin_lock_bh(&bp->stats_lock);
+
ramrod_data.drv_counter = bp->stats_counter++;
ramrod_data.collect_port = bp->port.pmf ? 1 : 0;
for_each_queue(bp, i)
@@ -169,6 +171,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp)
bp->spq_left++;
bp->stats_pending = 1;
}
+
+ spin_unlock_bh(&bp->stats_lock);
}
}
@@ -734,6 +738,14 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
struct host_func_stats *fstats = bnx2x_sp(bp, func_stats);
struct bnx2x_eth_stats *estats = &bp->eth_stats;
int i;
+ u16 cur_stats_counter;
+
+ /* Make sure we use the value of the counter
+ * used for sending the last stats ramrod.
+ */
+ spin_lock_bh(&bp->stats_lock);
+ cur_stats_counter = bp->stats_counter - 1;
+ spin_unlock_bh(&bp->stats_lock);
memcpy(&(fstats->total_bytes_received_hi),
&(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi),
@@ -761,25 +773,22 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp)
u32 diff;
/* are storm stats valid? */
- if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) !=
- bp->stats_counter) {
+ if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) {
DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm"
" xstorm counter (0x%x) != stats_counter (0x%x)\n",
- i, xclient->stats_counter, bp->stats_counter);
+ i, xclient->stats_counter, cur_stats_counter + 1);
return -1;
}
- if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) !=
- bp->stats_counter) {
+ if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) {
DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm"
" tstorm counter (0x%x) != stats_counter (0x%x)\n",
- i, tclient->stats_counter, bp->stats_counter);
+ i, tclient->stats_counter, cur_stats_counter + 1);
return -2;
}
- if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) !=
- bp->stats_counter) {
+ if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) {
DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm"
" ustorm counter (0x%x) != stats_counter (0x%x)\n",
- i, uclient->stats_counter, bp->stats_counter);
+ i, uclient->stats_counter, cur_stats_counter + 1);
return -4;
}
@@ -1216,16 +1225,18 @@ static const struct {
void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
{
- enum bnx2x_stats_state state = bp->stats_state;
+ enum bnx2x_stats_state state;
if (unlikely(bp->panic))
return;
- bnx2x_stats_stm[state][event].action(bp);
+ /* Protect a state change flow */
+ spin_lock_bh(&bp->stats_lock);
+ state = bp->stats_state;
bp->stats_state = bnx2x_stats_stm[state][event].next_state;
+ spin_unlock_bh(&bp->stats_lock);
- /* Make sure the state has been "changed" */
- smp_wmb();
+ bnx2x_stats_stm[state][event].action(bp);
if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index e3b35d0b4284..c746b331771d 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -815,7 +815,7 @@ static int rlb_initialize(struct bonding *bond)
/*initialize packet type*/
pk_type->type = cpu_to_be16(ETH_P_ARP);
- pk_type->dev = NULL;
+ pk_type->dev = bond->dev;
pk_type->func = rlb_arp_recv;
/* register to receive ARPs */
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 94656179441d..667b527b0312 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1722,6 +1722,15 @@ static int __devinit igb_probe(struct pci_dev *pdev,
u16 eeprom_apme_mask = IGB_EEPROM_APME;
u32 part_num;
+ /* Catch broken hardware that put the wrong VF device ID in
+ * the PCIe SR-IOV capability.
+ */
+ if (pdev->is_virtfn) {
+ WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n",
+ pci_name(pdev), pdev->vendor, pdev->device);
+ return -EINVAL;
+ }
+
err = pci_enable_device_mem(pdev);
if (err)
return err;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index e92acbf5a307..7d6a415bcf88 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6539,6 +6539,15 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
#endif
u32 part_num, eec;
+ /* Catch broken hardware that put the wrong VF device ID in
+ * the PCIe SR-IOV capability.
+ */
+ if (pdev->is_virtfn) {
+ WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n",
+ pci_name(pdev), pdev->vendor, pdev->device);
+ return -EINVAL;
+ }
+
err = pci_enable_device_mem(pdev);
if (err)
return err;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 1b28aaec0a5a..6e9da96a87b2 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -515,7 +515,7 @@ static const struct net_device_ops macvlan_netdev_ops = {
.ndo_validate_addr = eth_validate_addr,
};
-static void macvlan_setup(struct net_device *dev)
+void macvlan_common_setup(struct net_device *dev)
{
ether_setup(dev);
@@ -524,6 +524,12 @@ static void macvlan_setup(struct net_device *dev)
dev->destructor = free_netdev;
dev->header_ops = &macvlan_hard_header_ops,
dev->ethtool_ops = &macvlan_ethtool_ops;
+}
+EXPORT_SYMBOL_GPL(macvlan_common_setup);
+
+static void macvlan_setup(struct net_device *dev)
+{
+ macvlan_common_setup(dev);
dev->tx_queue_len = 0;
}
@@ -735,7 +741,6 @@ int macvlan_link_register(struct rtnl_link_ops *ops)
/* common fields */
ops->priv_size = sizeof(struct macvlan_dev);
ops->get_tx_queues = macvlan_get_tx_queues;
- ops->setup = macvlan_setup;
ops->validate = macvlan_validate;
ops->maxtype = IFLA_MACVLAN_MAX;
ops->policy = macvlan_policy;
@@ -749,6 +754,7 @@ EXPORT_SYMBOL_GPL(macvlan_link_register);
static struct rtnl_link_ops macvlan_link_ops = {
.kind = "macvlan",
+ .setup = macvlan_setup,
.newlink = macvlan_newlink,
.dellink = macvlan_dellink,
};
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 2b4d59b58b2c..3b1c54a9c6ef 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -180,11 +180,18 @@ static int macvtap_forward(struct net_device *dev, struct sk_buff *skb)
{
struct macvtap_queue *q = macvtap_get_queue(dev, skb);
if (!q)
- return -ENOLINK;
+ goto drop;
+
+ if (skb_queue_len(&q->sk.sk_receive_queue) >= dev->tx_queue_len)
+ goto drop;
skb_queue_tail(&q->sk.sk_receive_queue, skb);
wake_up_interruptible_poll(sk_sleep(&q->sk), POLLIN | POLLRDNORM | POLLRDBAND);
- return 0;
+ return NET_RX_SUCCESS;
+
+drop:
+ kfree_skb(skb);
+ return NET_RX_DROP;
}
/*
@@ -235,8 +242,15 @@ static void macvtap_dellink(struct net_device *dev,
macvlan_dellink(dev, head);
}
+static void macvtap_setup(struct net_device *dev)
+{
+ macvlan_common_setup(dev);
+ dev->tx_queue_len = TUN_READQ_SIZE;
+}
+
static struct rtnl_link_ops macvtap_link_ops __read_mostly = {
.kind = "macvtap",
+ .setup = macvtap_setup,
.newlink = macvtap_newlink,
.dellink = macvtap_dellink,
};
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 3645fb3673db..0af033533905 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -65,7 +65,7 @@ static int debug_level = ERR_DBG;
/* DEBUG message print. */
#define DBG_PRINT(dbg_level, fmt, args...) do { \
- if (dbg_level >= debug_level) \
+ if (dbg_level <= debug_level) \
pr_info(fmt, ##args); \
} while (0)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 6ad6fe706312..63042596f0cf 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -736,8 +736,18 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
else if (sinfo->gso_type & SKB_GSO_UDP)
gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
- else
- BUG();
+ else {
+ printk(KERN_ERR "tun: unexpected GSO type: "
+ "0x%x, gso_size %d, hdr_len %d\n",
+ sinfo->gso_type, gso.gso_size,
+ gso.hdr_len);
+ print_hex_dump(KERN_ERR, "tun: ",
+ DUMP_PREFIX_NONE,
+ 16, 1, skb->head,
+ min((int)gso.hdr_len, 64), true);
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
if (sinfo->gso_type & SKB_GSO_TCP_ECN)
gso.gso_type |= VIRTIO_NET_HDR_GSO_ECN;
} else
diff --git a/drivers/net/wimax/i2400m/i2400m-usb.h b/drivers/net/wimax/i2400m/i2400m-usb.h
index 2d7c96d7e865..eb80243e22df 100644
--- a/drivers/net/wimax/i2400m/i2400m-usb.h
+++ b/drivers/net/wimax/i2400m/i2400m-usb.h
@@ -152,6 +152,7 @@ enum {
/* Device IDs */
USB_DEVICE_ID_I6050 = 0x0186,
USB_DEVICE_ID_I6050_2 = 0x0188,
+ USB_DEVICE_ID_I6250 = 0x0187,
};
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index 0d5081d77dc0..d3365ac85dde 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -491,6 +491,7 @@ int i2400mu_probe(struct usb_interface *iface,
switch (id->idProduct) {
case USB_DEVICE_ID_I6050:
case USB_DEVICE_ID_I6050_2:
+ case USB_DEVICE_ID_I6250:
i2400mu->i6050 = 1;
break;
default:
@@ -739,6 +740,7 @@ static
struct usb_device_id i2400mu_id_table[] = {
{ USB_DEVICE(0x8086, USB_DEVICE_ID_I6050) },
{ USB_DEVICE(0x8086, USB_DEVICE_ID_I6050_2) },
+ { USB_DEVICE(0x8086, USB_DEVICE_ID_I6250) },
{ USB_DEVICE(0x8086, 0x0181) },
{ USB_DEVICE(0x8086, 0x1403) },
{ USB_DEVICE(0x8086, 0x1405) },