diff options
author | David S. Miller <davem@davemloft.net> | 2010-07-27 21:01:35 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-27 21:01:35 -0700 |
commit | bb7e95c8fd859922c6cf3ebbb3a8546007df1748 (patch) | |
tree | 58b54c6306ba168b76f25cc6dc9a2d1d2eb830a7 /drivers | |
parent | b8bc0421ab7f83712a0a8ef7eb05fa73ec53c027 (diff) | |
parent | 5447080cfa3c77154498dfbf225367ac85b4c2b5 (diff) | |
download | blackbird-op-linux-bb7e95c8fd859922c6cf3ebbb3a8546007df1748.tar.gz blackbird-op-linux-bb7e95c8fd859922c6cf3ebbb3a8546007df1748.zip |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/bnx2x_main.c
Merge bnx2x bug fixes in by hand... :-/
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bnx2x/bnx2x.h | 4 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_main.c | 1 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_stats.c | 37 | ||||
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 2 | ||||
-rw-r--r-- | drivers/net/igb/igb_main.c | 9 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 9 | ||||
-rw-r--r-- | drivers/net/macvlan.c | 10 | ||||
-rw-r--r-- | drivers/net/macvtap.c | 18 | ||||
-rw-r--r-- | drivers/net/s2io.h | 2 | ||||
-rw-r--r-- | drivers/net/tun.c | 14 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/i2400m-usb.h | 1 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/usb.c | 2 |
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) }, |