Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

This commit is contained in:
David S. Miller 2009-05-03 14:07:43 -07:00
commit d252a5e7b7
11 changed files with 79 additions and 54 deletions

View file

@ -2211,33 +2211,24 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
{ {
struct bonding *bond = netdev_priv(bond_dev); struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave; struct slave *slave;
int i, found = 0; int i, res = -ENODEV;
if (info->slave_id < 0) {
return -ENODEV;
}
read_lock(&bond->lock); read_lock(&bond->lock);
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave, i) {
if (i == (int)info->slave_id) { if (i == (int)info->slave_id) {
found = 1; res = 0;
strcpy(info->slave_name, slave->dev->name);
info->link = slave->link;
info->state = slave->state;
info->link_failure_count = slave->link_failure_count;
break; break;
} }
} }
read_unlock(&bond->lock); read_unlock(&bond->lock);
if (found) { return res;
strcpy(info->slave_name, slave->dev->name);
info->link = slave->link;
info->state = slave->state;
info->link_failure_count = slave->link_failure_count;
} else {
return -ENODEV;
}
return 0;
} }
/*-------------------------------- Monitoring -------------------------------*/ /*-------------------------------- Monitoring -------------------------------*/
@ -5173,16 +5164,15 @@ int bond_create(char *name, struct bond_params *params)
up_write(&bonding_rwsem); up_write(&bonding_rwsem);
rtnl_unlock(); /* allows sysfs registration of net device */ rtnl_unlock(); /* allows sysfs registration of net device */
res = bond_create_sysfs_entry(netdev_priv(bond_dev)); res = bond_create_sysfs_entry(netdev_priv(bond_dev));
if (res < 0) { if (res < 0)
rtnl_lock(); goto out_unreg;
down_write(&bonding_rwsem);
bond_deinit(bond_dev);
unregister_netdevice(bond_dev);
goto out_rtnl;
}
return 0; return 0;
out_unreg:
rtnl_lock();
down_write(&bonding_rwsem);
unregister_netdevice(bond_dev);
out_bond: out_bond:
bond_deinit(bond_dev); bond_deinit(bond_dev);
out_netdev: out_netdev:

View file

@ -3784,7 +3784,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
adapter->params.info = ai; adapter->params.info = ai;
adapter->params.nports = ai->nports0 + ai->nports1; adapter->params.nports = ai->nports0 + ai->nports1;
adapter->params.chan_map = !!ai->nports0 | (!!ai->nports1 << 1); adapter->params.chan_map = (!!ai->nports0) | (!!ai->nports1 << 1);
adapter->params.rev = t3_read_reg(adapter, A_PL_REV); adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
/* /*
* We used to only run the "adapter check task" once a second if * We used to only run the "adapter check task" once a second if

View file

@ -664,7 +664,7 @@ static int netconsole_netdev_event(struct notifier_block *this,
struct netconsole_target *nt; struct netconsole_target *nt;
struct net_device *dev = ptr; struct net_device *dev = ptr;
if (!(event == NETDEV_CHANGENAME)) if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER))
goto done; goto done;
spin_lock_irqsave(&target_list_lock, flags); spin_lock_irqsave(&target_list_lock, flags);
@ -675,6 +675,15 @@ static int netconsole_netdev_event(struct notifier_block *this,
case NETDEV_CHANGENAME: case NETDEV_CHANGENAME:
strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);
break; break;
case NETDEV_UNREGISTER:
if (!nt->enabled)
break;
netpoll_cleanup(&nt->np);
nt->enabled = 0;
printk(KERN_INFO "netconsole: network logging stopped"
", interface %s unregistered\n",
dev->name);
break;
} }
} }
netconsole_target_put(nt); netconsole_target_put(nt);

View file

@ -941,6 +941,16 @@ static int smsc95xx_reset(struct usbnet *dev)
if (netif_msg_ifup(dev)) if (netif_msg_ifup(dev))
devdbg(dev, "ID_REV = 0x%08x", read_buf); devdbg(dev, "ID_REV = 0x%08x", read_buf);
/* Configure GPIO pins as LED outputs */
write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
LED_GPIO_CFG_FDX_LED;
ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
if (ret < 0) {
devwarn(dev, "Failed to write LED_GPIO_CFG register, ret=%d",
ret);
return ret;
}
/* Init Tx */ /* Init Tx */
write_buf = 0; write_buf = 0;
ret = smsc95xx_write_reg(dev, FLOW, write_buf); ret = smsc95xx_write_reg(dev, FLOW, write_buf);
@ -1231,6 +1241,11 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0424, 0x9500), USB_DEVICE(0x0424, 0x9500),
.driver_info = (unsigned long) &smsc95xx_info, .driver_info = (unsigned long) &smsc95xx_info,
}, },
{
/* SMSC9512/9514 USB Hub & Ethernet Device */
USB_DEVICE(0x0424, 0xec00),
.driver_info = (unsigned long) &smsc95xx_info,
},
{ }, /* END */ { }, /* END */
}; };
MODULE_DEVICE_TABLE(usb, products); MODULE_DEVICE_TABLE(usb, products);

View file

@ -99,6 +99,9 @@
#define PM_CTL_WUPS_MULTI_ (0x00000003) #define PM_CTL_WUPS_MULTI_ (0x00000003)
#define LED_GPIO_CFG (0x24) #define LED_GPIO_CFG (0x24)
#define LED_GPIO_CFG_SPD_LED (0x01000000)
#define LED_GPIO_CFG_LNK_LED (0x00100000)
#define LED_GPIO_CFG_FDX_LED (0x00010000)
#define GPIO_CFG (0x28) #define GPIO_CFG (0x28)

View file

@ -616,10 +616,11 @@ static int virtnet_open(struct net_device *dev)
static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
struct scatterlist *data, int out, int in) struct scatterlist *data, int out, int in)
{ {
struct scatterlist sg[VIRTNET_SEND_COMMAND_SG_MAX + 2]; struct scatterlist *s, sg[VIRTNET_SEND_COMMAND_SG_MAX + 2];
struct virtio_net_ctrl_hdr ctrl; struct virtio_net_ctrl_hdr ctrl;
virtio_net_ctrl_ack status = ~0; virtio_net_ctrl_ack status = ~0;
unsigned int tmp; unsigned int tmp;
int i;
/* Caller should know better */ /* Caller should know better */
BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) || BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ||
@ -634,7 +635,8 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
sg_init_table(sg, out + in); sg_init_table(sg, out + in);
sg_set_buf(&sg[0], &ctrl, sizeof(ctrl)); sg_set_buf(&sg[0], &ctrl, sizeof(ctrl));
memcpy(&sg[1], data, sizeof(struct scatterlist) * (out + in - 2)); for_each_sg(data, s, out + in - 2, i)
sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
sg_set_buf(&sg[out + in - 1], &status, sizeof(status)); sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi)); BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi));
@ -688,7 +690,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
promisc = ((dev->flags & IFF_PROMISC) != 0); promisc = ((dev->flags & IFF_PROMISC) != 0);
allmulti = ((dev->flags & IFF_ALLMULTI) != 0); allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
sg_set_buf(sg, &promisc, sizeof(promisc)); sg_init_one(sg, &promisc, sizeof(promisc));
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
VIRTIO_NET_CTRL_RX_PROMISC, VIRTIO_NET_CTRL_RX_PROMISC,
@ -696,7 +698,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
promisc ? "en" : "dis"); promisc ? "en" : "dis");
sg_set_buf(sg, &allmulti, sizeof(allmulti)); sg_init_one(sg, &allmulti, sizeof(allmulti));
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
VIRTIO_NET_CTRL_RX_ALLMULTI, VIRTIO_NET_CTRL_RX_ALLMULTI,
@ -712,6 +714,8 @@ static void virtnet_set_rx_mode(struct net_device *dev)
return; return;
} }
sg_init_table(sg, 2);
/* Store the unicast list and count in the front of the buffer */ /* Store the unicast list and count in the front of the buffer */
mac_data->entries = dev->uc_count; mac_data->entries = dev->uc_count;
addr = dev->uc_list; addr = dev->uc_list;
@ -740,24 +744,24 @@ static void virtnet_set_rx_mode(struct net_device *dev)
kfree(buf); kfree(buf);
} }
static void virnet_vlan_rx_add_vid(struct net_device *dev, u16 vid) static void virtnet_vlan_rx_add_vid(struct net_device *dev, u16 vid)
{ {
struct virtnet_info *vi = netdev_priv(dev); struct virtnet_info *vi = netdev_priv(dev);
struct scatterlist sg; struct scatterlist sg;
sg_set_buf(&sg, &vid, sizeof(vid)); sg_init_one(&sg, &vid, sizeof(vid));
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0)) VIRTIO_NET_CTRL_VLAN_ADD, &sg, 1, 0))
dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid); dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid);
} }
static void virnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
{ {
struct virtnet_info *vi = netdev_priv(dev); struct virtnet_info *vi = netdev_priv(dev);
struct scatterlist sg; struct scatterlist sg;
sg_set_buf(&sg, &vid, sizeof(vid)); sg_init_one(&sg, &vid, sizeof(vid));
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN,
VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0)) VIRTIO_NET_CTRL_VLAN_DEL, &sg, 1, 0))
@ -790,8 +794,8 @@ static const struct net_device_ops virtnet_netdev = {
.ndo_set_mac_address = virtnet_set_mac_address, .ndo_set_mac_address = virtnet_set_mac_address,
.ndo_set_rx_mode = virtnet_set_rx_mode, .ndo_set_rx_mode = virtnet_set_rx_mode,
.ndo_change_mtu = virtnet_change_mtu, .ndo_change_mtu = virtnet_change_mtu,
.ndo_vlan_rx_add_vid = virnet_vlan_rx_add_vid, .ndo_vlan_rx_add_vid = virtnet_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = virnet_vlan_rx_kill_vid, .ndo_vlan_rx_kill_vid = virtnet_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = virtnet_netpoll, .ndo_poll_controller = virtnet_netpoll,
#endif #endif

View file

@ -472,7 +472,7 @@ static inline void xt_info_rdlock_bh(void)
local_bh_disable(); local_bh_disable();
lock = &__get_cpu_var(xt_info_locks); lock = &__get_cpu_var(xt_info_locks);
if (!lock->readers++) if (likely(!lock->readers++))
spin_lock(&lock->lock); spin_lock(&lock->lock);
} }
@ -480,7 +480,7 @@ static inline void xt_info_rdunlock_bh(void)
{ {
struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks); struct xt_info_lock *lock = &__get_cpu_var(xt_info_locks);
if (!--lock->readers) if (likely(!--lock->readers))
spin_unlock(&lock->lock); spin_unlock(&lock->lock);
local_bh_enable(); local_bh_enable();
} }

View file

@ -4,6 +4,7 @@
* compatible drivers/servers. */ * compatible drivers/servers. */
#include <linux/types.h> #include <linux/types.h>
#include <linux/virtio_config.h> #include <linux/virtio_config.h>
#include <linux/if_ether.h>
/* The ID for virtio_net */ /* The ID for virtio_net */
#define VIRTIO_ID_NET 1 #define VIRTIO_ID_NET 1

View file

@ -1735,11 +1735,12 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
{ {
u32 hash; u32 hash;
if (skb_rx_queue_recorded(skb)) { if (skb_rx_queue_recorded(skb))
hash = skb_get_rx_queue(skb); return skb_get_rx_queue(skb) % dev->real_num_tx_queues;
} else if (skb->sk && skb->sk->sk_hash) {
if (skb->sk && skb->sk->sk_hash)
hash = skb->sk->sk_hash; hash = skb->sk->sk_hash;
} else else
hash = skb->protocol; hash = skb->protocol;
hash = jhash_1word(hash, skb_tx_hashrnd); hash = jhash_1word(hash, skb_tx_hashrnd);

View file

@ -1365,9 +1365,8 @@ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i)
static inline struct page *linear_to_page(struct page *page, unsigned int *len, static inline struct page *linear_to_page(struct page *page, unsigned int *len,
unsigned int *offset, unsigned int *offset,
struct sk_buff *skb) struct sk_buff *skb, struct sock *sk)
{ {
struct sock *sk = skb->sk;
struct page *p = sk->sk_sndmsg_page; struct page *p = sk->sk_sndmsg_page;
unsigned int off; unsigned int off;
@ -1405,13 +1404,14 @@ new_page:
*/ */
static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page, static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page,
unsigned int *len, unsigned int offset, unsigned int *len, unsigned int offset,
struct sk_buff *skb, int linear) struct sk_buff *skb, int linear,
struct sock *sk)
{ {
if (unlikely(spd->nr_pages == PIPE_BUFFERS)) if (unlikely(spd->nr_pages == PIPE_BUFFERS))
return 1; return 1;
if (linear) { if (linear) {
page = linear_to_page(page, len, &offset, skb); page = linear_to_page(page, len, &offset, skb, sk);
if (!page) if (!page)
return 1; return 1;
} else } else
@ -1442,7 +1442,8 @@ static inline void __segment_seek(struct page **page, unsigned int *poff,
static inline int __splice_segment(struct page *page, unsigned int poff, static inline int __splice_segment(struct page *page, unsigned int poff,
unsigned int plen, unsigned int *off, unsigned int plen, unsigned int *off,
unsigned int *len, struct sk_buff *skb, unsigned int *len, struct sk_buff *skb,
struct splice_pipe_desc *spd, int linear) struct splice_pipe_desc *spd, int linear,
struct sock *sk)
{ {
if (!*len) if (!*len)
return 1; return 1;
@ -1465,7 +1466,7 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
/* the linear region may spread across several pages */ /* the linear region may spread across several pages */
flen = min_t(unsigned int, flen, PAGE_SIZE - poff); flen = min_t(unsigned int, flen, PAGE_SIZE - poff);
if (spd_fill_page(spd, page, &flen, poff, skb, linear)) if (spd_fill_page(spd, page, &flen, poff, skb, linear, sk))
return 1; return 1;
__segment_seek(&page, &poff, &plen, flen); __segment_seek(&page, &poff, &plen, flen);
@ -1481,8 +1482,8 @@ static inline int __splice_segment(struct page *page, unsigned int poff,
* pipe is full or if we already spliced the requested length. * pipe is full or if we already spliced the requested length.
*/ */
static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
unsigned int *len, unsigned int *len, struct splice_pipe_desc *spd,
struct splice_pipe_desc *spd) struct sock *sk)
{ {
int seg; int seg;
@ -1492,7 +1493,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
if (__splice_segment(virt_to_page(skb->data), if (__splice_segment(virt_to_page(skb->data),
(unsigned long) skb->data & (PAGE_SIZE - 1), (unsigned long) skb->data & (PAGE_SIZE - 1),
skb_headlen(skb), skb_headlen(skb),
offset, len, skb, spd, 1)) offset, len, skb, spd, 1, sk))
return 1; return 1;
/* /*
@ -1502,7 +1503,7 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset,
const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; const skb_frag_t *f = &skb_shinfo(skb)->frags[seg];
if (__splice_segment(f->page, f->page_offset, f->size, if (__splice_segment(f->page, f->page_offset, f->size,
offset, len, skb, spd, 0)) offset, len, skb, spd, 0, sk))
return 1; return 1;
} }
@ -1528,12 +1529,13 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
.ops = &sock_pipe_buf_ops, .ops = &sock_pipe_buf_ops,
.spd_release = sock_spd_release, .spd_release = sock_spd_release,
}; };
struct sock *sk = skb->sk;
/* /*
* __skb_splice_bits() only fails if the output has no room left, * __skb_splice_bits() only fails if the output has no room left,
* so no point in going over the frag_list for the error case. * so no point in going over the frag_list for the error case.
*/ */
if (__skb_splice_bits(skb, &offset, &tlen, &spd)) if (__skb_splice_bits(skb, &offset, &tlen, &spd, sk))
goto done; goto done;
else if (!tlen) else if (!tlen)
goto done; goto done;
@ -1545,14 +1547,13 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
struct sk_buff *list = skb_shinfo(skb)->frag_list; struct sk_buff *list = skb_shinfo(skb)->frag_list;
for (; list && tlen; list = list->next) { for (; list && tlen; list = list->next) {
if (__skb_splice_bits(list, &offset, &tlen, &spd)) if (__skb_splice_bits(list, &offset, &tlen, &spd, sk))
break; break;
} }
} }
done: done:
if (spd.nr_pages) { if (spd.nr_pages) {
struct sock *sk = skb->sk;
int ret; int ret;
/* /*

View file

@ -837,6 +837,7 @@ config NETFILTER_XT_MATCH_SOCKET
depends on NETFILTER_TPROXY depends on NETFILTER_TPROXY
depends on NETFILTER_XTABLES depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
depends on !NF_CONNTRACK || NF_CONNTRACK
select NF_DEFRAG_IPV4 select NF_DEFRAG_IPV4
help help
This option adds a `socket' match, which can be used to match This option adds a `socket' match, which can be used to match