aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorArthur Kepner <akepner@sgi.com>2005-08-23 01:34:53 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-23 01:34:53 -0400
commit8531c5ffbca65f6df868637c26e6df6f88bff738 (patch)
tree2f4fc2f57c83b4d67e06273df4964dc1d724daa5 /drivers/net/bonding
parentefcce839360fb3a7b6dedeacaec80f68b0f2d052 (diff)
[PATCH] bonding: inherit zero-copy flags of slaves
This change allows a bonding device to inherit the "zero-copy" features of its slave devices. It was inspired by a couple of previous postings on this topic: http://marc.theaimsgroup.com/?l=bonding-devel&m=111924607327794&w=2 http://marc.theaimsgroup.com/?l=bonding-devel&m=111925242706297&w=2 and it's largely a combination of the patches that appear in those emails. Signed-off-by: Arthur Kepner <akepner@sgi.com>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c58
-rw-r--r--drivers/net/bonding/bonding.h3
2 files changed, 60 insertions, 1 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 2c930da90a85..94c9f68dd16b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1604,6 +1604,44 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
1604 return 0; 1604 return 0;
1605} 1605}
1606 1606
1607#define BOND_INTERSECT_FEATURES \
1608 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
1609
1610/*
1611 * Compute the features available to the bonding device by
1612 * intersection of all of the slave devices' BOND_INTERSECT_FEATURES.
1613 * Call this after attaching or detaching a slave to update the
1614 * bond's features.
1615 */
1616static int bond_compute_features(struct bonding *bond)
1617{
1618 int i;
1619 struct slave *slave;
1620 struct net_device *bond_dev = bond->dev;
1621 int features = bond->bond_features;
1622
1623 bond_for_each_slave(bond, slave, i) {
1624 struct net_device * slave_dev = slave->dev;
1625 if (i == 0) {
1626 features |= BOND_INTERSECT_FEATURES;
1627 }
1628 features &=
1629 ~(~slave_dev->features & BOND_INTERSECT_FEATURES);
1630 }
1631
1632 /* turn off NETIF_F_SG if we need a csum and h/w can't do it */
1633 if ((features & NETIF_F_SG) &&
1634 !(features & (NETIF_F_IP_CSUM |
1635 NETIF_F_NO_CSUM |
1636 NETIF_F_HW_CSUM))) {
1637 features &= ~NETIF_F_SG;
1638 }
1639
1640 bond_dev->features = features;
1641
1642 return 0;
1643}
1644
1607/* enslave device <slave> to bond device <master> */ 1645/* enslave device <slave> to bond device <master> */
1608static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) 1646static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1609{ 1647{
@@ -1811,6 +1849,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de
1811 new_slave->delay = 0; 1849 new_slave->delay = 0;
1812 new_slave->link_failure_count = 0; 1850 new_slave->link_failure_count = 0;
1813 1851
1852 bond_compute_features(bond);
1853
1814 if (bond->params.miimon && !bond->params.use_carrier) { 1854 if (bond->params.miimon && !bond->params.use_carrier) {
1815 link_reporting = bond_check_dev_link(bond, slave_dev, 1); 1855 link_reporting = bond_check_dev_link(bond, slave_dev, 1);
1816 1856
@@ -2015,7 +2055,7 @@ err_free:
2015 2055
2016err_undo_flags: 2056err_undo_flags:
2017 bond_dev->features = old_features; 2057 bond_dev->features = old_features;
2018 2058
2019 return res; 2059 return res;
2020} 2060}
2021 2061
@@ -2100,6 +2140,8 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de
2100 /* release the slave from its bond */ 2140 /* release the slave from its bond */
2101 bond_detach_slave(bond, slave); 2141 bond_detach_slave(bond, slave);
2102 2142
2143 bond_compute_features(bond);
2144
2103 if (bond->primary_slave == slave) { 2145 if (bond->primary_slave == slave) {
2104 bond->primary_slave = NULL; 2146 bond->primary_slave = NULL;
2105 } 2147 }
@@ -2243,6 +2285,8 @@ static int bond_release_all(struct net_device *bond_dev)
2243 bond_alb_deinit_slave(bond, slave); 2285 bond_alb_deinit_slave(bond, slave);
2244 } 2286 }
2245 2287
2288 bond_compute_features(bond);
2289
2246 /* now that the slave is detached, unlock and perform 2290 /* now that the slave is detached, unlock and perform
2247 * all the undo steps that should not be called from 2291 * all the undo steps that should not be called from
2248 * within a lock. 2292 * within a lock.
@@ -3588,6 +3632,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
3588static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) 3632static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
3589{ 3633{
3590 struct net_device *bond_dev = slave_dev->master; 3634 struct net_device *bond_dev = slave_dev->master;
3635 struct bonding *bond = bond_dev->priv;
3591 3636
3592 switch (event) { 3637 switch (event) {
3593 case NETDEV_UNREGISTER: 3638 case NETDEV_UNREGISTER:
@@ -3626,6 +3671,9 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
3626 * TODO: handle changing the primary's name 3671 * TODO: handle changing the primary's name
3627 */ 3672 */
3628 break; 3673 break;
3674 case NETDEV_FEAT_CHANGE:
3675 bond_compute_features(bond);
3676 break;
3629 default: 3677 default:
3630 break; 3678 break;
3631 } 3679 }
@@ -4526,6 +4574,11 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode)
4526 } 4574 }
4527} 4575}
4528 4576
4577static struct ethtool_ops bond_ethtool_ops = {
4578 .get_tx_csum = ethtool_op_get_tx_csum,
4579 .get_sg = ethtool_op_get_sg,
4580};
4581
4529/* 4582/*
4530 * Does not allocate but creates a /proc entry. 4583 * Does not allocate but creates a /proc entry.
4531 * Allowed to fail. 4584 * Allowed to fail.
@@ -4555,6 +4608,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
4555 bond_dev->stop = bond_close; 4608 bond_dev->stop = bond_close;
4556 bond_dev->get_stats = bond_get_stats; 4609 bond_dev->get_stats = bond_get_stats;
4557 bond_dev->do_ioctl = bond_do_ioctl; 4610 bond_dev->do_ioctl = bond_do_ioctl;
4611 bond_dev->ethtool_ops = &bond_ethtool_ops;
4558 bond_dev->set_multicast_list = bond_set_multicast_list; 4612 bond_dev->set_multicast_list = bond_set_multicast_list;
4559 bond_dev->change_mtu = bond_change_mtu; 4613 bond_dev->change_mtu = bond_change_mtu;
4560 bond_dev->set_mac_address = bond_set_mac_address; 4614 bond_dev->set_mac_address = bond_set_mac_address;
@@ -4591,6 +4645,8 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
4591 NETIF_F_HW_VLAN_RX | 4645 NETIF_F_HW_VLAN_RX |
4592 NETIF_F_HW_VLAN_FILTER); 4646 NETIF_F_HW_VLAN_FILTER);
4593 4647
4648 bond->bond_features = bond_dev->features;
4649
4594#ifdef CONFIG_PROC_FS 4650#ifdef CONFIG_PROC_FS
4595 bond_create_proc_entry(bond); 4651 bond_create_proc_entry(bond);
4596#endif 4652#endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index d27f377b3eeb..388196980862 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -211,6 +211,9 @@ struct bonding {
211 struct bond_params params; 211 struct bond_params params;
212 struct list_head vlan_list; 212 struct list_head vlan_list;
213 struct vlan_group *vlgrp; 213 struct vlan_group *vlgrp;
214 /* the features the bonding device supports, independently
215 * of any slaves */
216 int bond_features;
214}; 217};
215 218
216/** 219/**