* [PATCH net-next 0/2] dsa: implement HW bonding
@ 2015-02-20 10:51 Jonas Johansson
2015-02-20 10:51 ` [PATCH net-next 1/2] dsa: bonding: " Jonas Johansson
` (2 more replies)
0 siblings, 3 replies; 22+ messages in thread
From: Jonas Johansson @ 2015-02-20 10:51 UTC (permalink / raw)
To: netdev; +Cc: Jonas Johansson
From: Jonas Johansson <jonas.johansson@westermo.se>
This patchset will implement hardware bonding support for the DSA driver and
the Marvell 88E6095 device.
Jonas Johansson (2):
dsa: bonding: implement HW bonding
mv88e6131: bonding: implement single device trunking
drivers/net/dsa/mv88e6131.c | 254 ++++++++++++++++++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx.h | 14 +++
drivers/net/team/team.c | 4 +
include/linux/netdevice.h | 8 ++
include/net/dsa.h | 8 ++
net/dsa/dsa.c | 60 +++++++++++
net/dsa/dsa_priv.h | 6 ++
net/dsa/slave.c | 23 ++++
8 files changed, 377 insertions(+)
--
2.1.0
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 10:51 [PATCH net-next 0/2] dsa: implement HW bonding Jonas Johansson @ 2015-02-20 10:51 ` Jonas Johansson 2015-02-20 15:12 ` Andrew Lunn ` (2 more replies) 2015-02-20 10:51 ` [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking Jonas Johansson 2015-02-21 16:40 ` [PATCH net-next 0/2] dsa: implement HW bonding Jiri Pirko 2 siblings, 3 replies; 22+ messages in thread From: Jonas Johansson @ 2015-02-20 10:51 UTC (permalink / raw) To: netdev; +Cc: Jonas Johansson From: Jonas Johansson <jonas.johansson@westermo.se> This patch will implement hooks for hardware bonding support for the DSA driver. When the team driver adds a DSA slave port the port will be assigned a bond group id and the DSA slave driver can setup the hardware. When team changes the port state (enabled/disabled) the DSA slave driver is able to use the attach/detach callback which will allow the hardware to change the hardware settings to reflect the state. Added DSA hooks: bond_add_group: To add a port to a bond group bond_del_group: To remove a port from a bond group bond_attach: To mark the port in a bond group as attached/active bond_detach: To unmark the port in a bond group as detach/inactive Added new network device hooks: ndo_bond_attach: To attach a device to a bond group. ndo_bond_detach: To detach a device from a bond group. Team: Added callback to ndo_bond_attach when port is enabled. Added callback to ndo_bond_detach when port is disabled. Added DSA notifier: Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> --- drivers/net/team/team.c | 4 ++++ include/linux/netdevice.h | 8 +++++++ include/net/dsa.h | 8 +++++++ net/dsa/dsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ net/dsa/dsa_priv.h | 6 +++++ net/dsa/slave.c | 23 ++++++++++++++++++ 6 files changed, 109 insertions(+) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 0e62274..f7b2afb 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -934,6 +934,8 @@ static void team_port_enable(struct team *team, team->ops.port_enabled(team, port); team_notify_peers(team); team_mcast_rejoin(team); + if (port->dev->netdev_ops->ndo_bond_attach) + port->dev->netdev_ops->ndo_bond_attach(port->dev); } static void __reconstruct_port_hlist(struct team *team, int rm_index) @@ -965,6 +967,8 @@ static void team_port_disable(struct team *team, team_adjust_ops(team); team_notify_peers(team); team_mcast_rejoin(team); + if (port->dev->netdev_ops->ndo_bond_detach) + port->dev->netdev_ops->ndo_bond_detach(port->dev); } #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \ diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5897b4e..8ebaefa 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -939,6 +939,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, * int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev); * Called to release previously enslaved netdev. * + * int (*ndo_bond_attach)(struct net_device *dev); + * Called to attach the device to a bond group. + * + * int (*ndo_bond_detach)(struct net_device *dev); + * Called to detach the device from a bond group. + * * Feature/offload setting functions. * netdev_features_t (*ndo_fix_features)(struct net_device *dev, * netdev_features_t features); @@ -1131,6 +1137,8 @@ struct net_device_ops { struct net_device *slave_dev); int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev); + int (*ndo_bond_attach)(struct net_device *dev); + int (*ndo_bond_detach)(struct net_device *dev); netdev_features_t (*ndo_fix_features)(struct net_device *dev, netdev_features_t features); int (*ndo_set_features)(struct net_device *dev, diff --git a/include/net/dsa.h b/include/net/dsa.h index ed3c34b..64b5963 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -254,6 +254,14 @@ struct dsa_switch_driver { int (*get_eee)(struct dsa_switch *ds, int port, struct ethtool_eee *e); + /* + * Bonding + */ + int (*bond_add_group)(struct dsa_switch *ds, int port, int gid); + int (*bond_del_group)(struct dsa_switch *ds, int port, int gid); + int (*bond_attach)(struct dsa_switch *ds, int port); + int (*bond_detach)(struct dsa_switch *ds, int port); + #ifdef CONFIG_NET_DSA_HWMON /* Hardware monitoring */ int (*get_temp)(struct dsa_switch *ds, int *temp); diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 2173402..3d2c599 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/module.h> #include <net/dsa.h> +#include <net/rtnetlink.h> #include <linux/of.h> #include <linux/of_mdio.h> #include <linux/of_platform.h> @@ -442,6 +443,62 @@ static void dsa_link_poll_timer(unsigned long _dst) schedule_work(&dst->link_poll_work); } +/* net device notifier event handler ****************************************/ +static int dsa_master_changed(struct net_device *dev) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + struct net_device *master = netdev_master_upper_dev_get(dev); + int err = 0; + + /* Add port to bond group */ + if (master && master->rtnl_link_ops && + !strcmp(master->rtnl_link_ops->kind, "team")) { + + p->bond_gid = master->ifindex; + + if (!ds->drv->bond_add_group) + return -EOPNOTSUPP; + return ds->drv->bond_add_group(ds, p->port, p->bond_gid); + } + + /* Remove port from bond group */ + if (!master && p->bond_gid) { + if (!ds->drv->bond_del_group) + return -EOPNOTSUPP; + err = ds->drv->bond_del_group(ds, p->port, p->bond_gid); + p->bond_gid = 0; + return err; + } + + return 0; +} + +static int dsa_event(struct notifier_block *nb, unsigned long event, void *data) + +{ + struct net_device *dev; + int err = 0; + + switch (event) { + case NETDEV_CHANGEUPPER: + dev = netdev_notifier_info_to_dev(data); + if (!dsa_slave_check(dev)) + return NOTIFY_DONE; + err = dsa_master_changed(dev); + if (err) + netdev_warn(dev, + "failed to reflect master change (err %d)\n", + err); + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block dsa_nb __read_mostly = { + .notifier_call = dsa_event, +}; /* platform driver init and cleanup *****************************************/ static int dev_is_class(struct device *dev, void *class) @@ -778,6 +835,9 @@ static int dsa_probe(struct platform_device *pdev) add_timer(&dst->link_poll_timer); } + /* Setup notifier */ + register_netdevice_notifier(&dsa_nb); + return 0; out: diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index dc9756d..6a1456a 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -45,6 +45,11 @@ struct dsa_slave_priv { int old_link; int old_pause; int old_duplex; + + /* + * Bond group id, or 0 if port is not bonded. + */ + int bond_gid; }; /* dsa.c */ @@ -58,6 +63,7 @@ struct net_device *dsa_slave_create(struct dsa_switch *ds, int port, char *name); int dsa_slave_suspend(struct net_device *slave_dev); int dsa_slave_resume(struct net_device *slave_dev); +bool dsa_slave_check(struct net_device *dev); /* tag_dsa.c */ extern const struct dsa_device_ops dsa_netdev_ops; diff --git a/net/dsa/slave.c b/net/dsa/slave.c index f23dead..88c84bf 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -441,6 +441,22 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e) return ret; } +static int dsa_slave_bond_attach(struct net_device *dev) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + + return ds->drv->bond_attach(ds, p->port); +} + +static int dsa_slave_bond_detach(struct net_device *dev) +{ + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->parent; + + return ds->drv->bond_detach(ds, p->port); +} + static const struct ethtool_ops dsa_slave_ethtool_ops = { .get_settings = dsa_slave_get_settings, .set_settings = dsa_slave_set_settings, @@ -470,6 +486,8 @@ static const struct net_device_ops dsa_slave_netdev_ops = { .ndo_set_rx_mode = dsa_slave_set_rx_mode, .ndo_set_mac_address = dsa_slave_set_mac_address, .ndo_do_ioctl = dsa_slave_ioctl, + .ndo_bond_attach = dsa_slave_bond_attach, + .ndo_bond_detach = dsa_slave_bond_detach, }; static void dsa_slave_adjust_link(struct net_device *dev) @@ -574,6 +592,11 @@ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, return 0; } +bool dsa_slave_check(struct net_device *ndev) +{ + return ndev->netdev_ops == &dsa_slave_netdev_ops; +} + int dsa_slave_suspend(struct net_device *slave_dev) { struct dsa_slave_priv *p = netdev_priv(slave_dev); -- 2.1.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 10:51 ` [PATCH net-next 1/2] dsa: bonding: " Jonas Johansson @ 2015-02-20 15:12 ` Andrew Lunn 2015-02-20 16:19 ` Jonas Johansson 2015-02-20 16:41 ` Florian Fainelli 2015-02-21 21:12 ` Scott Feldman 2 siblings, 1 reply; 22+ messages in thread From: Andrew Lunn @ 2015-02-20 15:12 UTC (permalink / raw) To: Jonas Johansson; +Cc: netdev, Jonas Johansson On Fri, Feb 20, 2015 at 11:51:12AM +0100, Jonas Johansson wrote: > From: Jonas Johansson <jonas.johansson@westermo.se> > > This patch will implement hooks for hardware bonding support for the DSA > driver. When the team driver adds a DSA slave port the port will be assigned > a bond group id and the DSA slave driver can setup the hardware. When team > changes the port state (enabled/disabled) the DSA slave driver is able to > use the attach/detach callback which will allow the hardware to change the > hardware settings to reflect the state. > > Added DSA hooks: > bond_add_group: To add a port to a bond group > bond_del_group: To remove a port from a bond group > bond_attach: To mark the port in a bond group as attached/active > bond_detach: To unmark the port in a bond group as detach/inactive > > Added new network device hooks: > ndo_bond_attach: To attach a device to a bond group. > ndo_bond_detach: To detach a device from a bond group. > > Team: > Added callback to ndo_bond_attach when port is enabled. > Added callback to ndo_bond_detach when port is disabled. > > Added DSA notifier: > Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. > > Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> > --- > drivers/net/team/team.c | 4 ++++ > include/linux/netdevice.h | 8 +++++++ > include/net/dsa.h | 8 +++++++ > net/dsa/dsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ > net/dsa/dsa_priv.h | 6 +++++ > net/dsa/slave.c | 23 ++++++++++++++++++ > 6 files changed, 109 insertions(+) > > diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c > index 0e62274..f7b2afb 100644 > --- a/drivers/net/team/team.c > +++ b/drivers/net/team/team.c > @@ -934,6 +934,8 @@ static void team_port_enable(struct team *team, > team->ops.port_enabled(team, port); > team_notify_peers(team); > team_mcast_rejoin(team); > + if (port->dev->netdev_ops->ndo_bond_attach) > + port->dev->netdev_ops->ndo_bond_attach(port->dev); > } > > static void __reconstruct_port_hlist(struct team *team, int rm_index) > @@ -965,6 +967,8 @@ static void team_port_disable(struct team *team, > team_adjust_ops(team); > team_notify_peers(team); > team_mcast_rejoin(team); > + if (port->dev->netdev_ops->ndo_bond_detach) > + port->dev->netdev_ops->ndo_bond_detach(port->dev); > } > > #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \ > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index 5897b4e..8ebaefa 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -939,6 +939,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, > * int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev); > * Called to release previously enslaved netdev. > * > + * int (*ndo_bond_attach)(struct net_device *dev); > + * Called to attach the device to a bond group. > + * > + * int (*ndo_bond_detach)(struct net_device *dev); > + * Called to detach the device from a bond group. > + * > * Feature/offload setting functions. > * netdev_features_t (*ndo_fix_features)(struct net_device *dev, > * netdev_features_t features); > @@ -1131,6 +1137,8 @@ struct net_device_ops { > struct net_device *slave_dev); > int (*ndo_del_slave)(struct net_device *dev, > struct net_device *slave_dev); > + int (*ndo_bond_attach)(struct net_device *dev); > + int (*ndo_bond_detach)(struct net_device *dev); > netdev_features_t (*ndo_fix_features)(struct net_device *dev, > netdev_features_t features); > int (*ndo_set_features)(struct net_device *dev, > diff --git a/include/net/dsa.h b/include/net/dsa.h > index ed3c34b..64b5963 100644 > --- a/include/net/dsa.h > +++ b/include/net/dsa.h > @@ -254,6 +254,14 @@ struct dsa_switch_driver { > int (*get_eee)(struct dsa_switch *ds, int port, > struct ethtool_eee *e); > > + /* > + * Bonding > + */ > + int (*bond_add_group)(struct dsa_switch *ds, int port, int gid); > + int (*bond_del_group)(struct dsa_switch *ds, int port, int gid); > + int (*bond_attach)(struct dsa_switch *ds, int port); > + int (*bond_detach)(struct dsa_switch *ds, int port); > + > #ifdef CONFIG_NET_DSA_HWMON > /* Hardware monitoring */ > int (*get_temp)(struct dsa_switch *ds, int *temp); > diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c > index 2173402..3d2c599 100644 > --- a/net/dsa/dsa.c > +++ b/net/dsa/dsa.c > @@ -17,6 +17,7 @@ > #include <linux/slab.h> > #include <linux/module.h> > #include <net/dsa.h> > +#include <net/rtnetlink.h> > #include <linux/of.h> > #include <linux/of_mdio.h> > #include <linux/of_platform.h> > @@ -442,6 +443,62 @@ static void dsa_link_poll_timer(unsigned long _dst) > schedule_work(&dst->link_poll_work); > } > > +/* net device notifier event handler ****************************************/ > +static int dsa_master_changed(struct net_device *dev) > +{ > + struct dsa_slave_priv *p = netdev_priv(dev); > + struct dsa_switch *ds = p->parent; > + struct net_device *master = netdev_master_upper_dev_get(dev); > + int err = 0; > + > + /* Add port to bond group */ > + if (master && master->rtnl_link_ops && > + !strcmp(master->rtnl_link_ops->kind, "team")) { > + > + p->bond_gid = master->ifindex; > + > + if (!ds->drv->bond_add_group) > + return -EOPNOTSUPP; > + return ds->drv->bond_add_group(ds, p->port, p->bond_gid); > + } Hi Jonas Maybe it is here and i cannot see it, but where do you check the slave devices in the group are in the same physical switch. Remember that DSA allows nearly arbitrary trees of switches. Andrew ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 15:12 ` Andrew Lunn @ 2015-02-20 16:19 ` Jonas Johansson 0 siblings, 0 replies; 22+ messages in thread From: Jonas Johansson @ 2015-02-20 16:19 UTC (permalink / raw) To: Andrew Lunn; +Cc: Jonas Johansson, netdev, Jonas Johansson On Fri, 20 Feb 2015, Andrew Lunn wrote: > On Fri, Feb 20, 2015 at 11:51:12AM +0100, Jonas Johansson wrote: >> From: Jonas Johansson <jonas.johansson@westermo.se> >> >> This patch will implement hooks for hardware bonding support for the DSA >> driver. When the team driver adds a DSA slave port the port will be assigned >> a bond group id and the DSA slave driver can setup the hardware. When team >> changes the port state (enabled/disabled) the DSA slave driver is able to >> use the attach/detach callback which will allow the hardware to change the >> hardware settings to reflect the state. >> >> Added DSA hooks: >> bond_add_group: To add a port to a bond group >> bond_del_group: To remove a port from a bond group >> bond_attach: To mark the port in a bond group as attached/active >> bond_detach: To unmark the port in a bond group as detach/inactive >> >> Added new network device hooks: >> ndo_bond_attach: To attach a device to a bond group. >> ndo_bond_detach: To detach a device from a bond group. >> >> Team: >> Added callback to ndo_bond_attach when port is enabled. >> Added callback to ndo_bond_detach when port is disabled. >> >> Added DSA notifier: >> Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. >> >> Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> >> --- >> drivers/net/team/team.c | 4 ++++ >> include/linux/netdevice.h | 8 +++++++ >> include/net/dsa.h | 8 +++++++ >> net/dsa/dsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ >> net/dsa/dsa_priv.h | 6 +++++ >> net/dsa/slave.c | 23 ++++++++++++++++++ >> 6 files changed, 109 insertions(+) >> >> diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c >> index 0e62274..f7b2afb 100644 >> --- a/drivers/net/team/team.c >> +++ b/drivers/net/team/team.c >> @@ -934,6 +934,8 @@ static void team_port_enable(struct team *team, >> team->ops.port_enabled(team, port); >> team_notify_peers(team); >> team_mcast_rejoin(team); >> + if (port->dev->netdev_ops->ndo_bond_attach) >> + port->dev->netdev_ops->ndo_bond_attach(port->dev); >> } >> >> static void __reconstruct_port_hlist(struct team *team, int rm_index) >> @@ -965,6 +967,8 @@ static void team_port_disable(struct team *team, >> team_adjust_ops(team); >> team_notify_peers(team); >> team_mcast_rejoin(team); >> + if (port->dev->netdev_ops->ndo_bond_detach) >> + port->dev->netdev_ops->ndo_bond_detach(port->dev); >> } >> >> #define TEAM_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \ >> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h >> index 5897b4e..8ebaefa 100644 >> --- a/include/linux/netdevice.h >> +++ b/include/linux/netdevice.h >> @@ -939,6 +939,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev, >> * int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev); >> * Called to release previously enslaved netdev. >> * >> + * int (*ndo_bond_attach)(struct net_device *dev); >> + * Called to attach the device to a bond group. >> + * >> + * int (*ndo_bond_detach)(struct net_device *dev); >> + * Called to detach the device from a bond group. >> + * >> * Feature/offload setting functions. >> * netdev_features_t (*ndo_fix_features)(struct net_device *dev, >> * netdev_features_t features); >> @@ -1131,6 +1137,8 @@ struct net_device_ops { >> struct net_device *slave_dev); >> int (*ndo_del_slave)(struct net_device *dev, >> struct net_device *slave_dev); >> + int (*ndo_bond_attach)(struct net_device *dev); >> + int (*ndo_bond_detach)(struct net_device *dev); >> netdev_features_t (*ndo_fix_features)(struct net_device *dev, >> netdev_features_t features); >> int (*ndo_set_features)(struct net_device *dev, >> diff --git a/include/net/dsa.h b/include/net/dsa.h >> index ed3c34b..64b5963 100644 >> --- a/include/net/dsa.h >> +++ b/include/net/dsa.h >> @@ -254,6 +254,14 @@ struct dsa_switch_driver { >> int (*get_eee)(struct dsa_switch *ds, int port, >> struct ethtool_eee *e); >> >> + /* >> + * Bonding >> + */ >> + int (*bond_add_group)(struct dsa_switch *ds, int port, int gid); >> + int (*bond_del_group)(struct dsa_switch *ds, int port, int gid); >> + int (*bond_attach)(struct dsa_switch *ds, int port); >> + int (*bond_detach)(struct dsa_switch *ds, int port); >> + >> #ifdef CONFIG_NET_DSA_HWMON >> /* Hardware monitoring */ >> int (*get_temp)(struct dsa_switch *ds, int *temp); >> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c >> index 2173402..3d2c599 100644 >> --- a/net/dsa/dsa.c >> +++ b/net/dsa/dsa.c >> @@ -17,6 +17,7 @@ >> #include <linux/slab.h> >> #include <linux/module.h> >> #include <net/dsa.h> >> +#include <net/rtnetlink.h> >> #include <linux/of.h> >> #include <linux/of_mdio.h> >> #include <linux/of_platform.h> >> @@ -442,6 +443,62 @@ static void dsa_link_poll_timer(unsigned long _dst) >> schedule_work(&dst->link_poll_work); >> } >> >> +/* net device notifier event handler ****************************************/ >> +static int dsa_master_changed(struct net_device *dev) >> +{ >> + struct dsa_slave_priv *p = netdev_priv(dev); >> + struct dsa_switch *ds = p->parent; >> + struct net_device *master = netdev_master_upper_dev_get(dev); >> + int err = 0; >> + >> + /* Add port to bond group */ >> + if (master && master->rtnl_link_ops && >> + !strcmp(master->rtnl_link_ops->kind, "team")) { >> + >> + p->bond_gid = master->ifindex; >> + >> + if (!ds->drv->bond_add_group) >> + return -EOPNOTSUPP; >> + return ds->drv->bond_add_group(ds, p->port, p->bond_gid); >> + } > > Hi Jonas > > Maybe it is here and i cannot see it, but where do you check the slave > devices in the group are in the same physical switch. Remember that > DSA allows nearly arbitrary trees of switches. > > Andrew > Thanks for the review. You are correct, there is no check if the slave devices are in the same physical switch. I know that some devices (e.g. 88E6095) can handle cross-chip trunking, but as this implementation was targeting single-chip trunking you are correct that a check needs to be implemented to prevent the slaves to spread over several devices. I'll look into it. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 10:51 ` [PATCH net-next 1/2] dsa: bonding: " Jonas Johansson 2015-02-20 15:12 ` Andrew Lunn @ 2015-02-20 16:41 ` Florian Fainelli 2015-02-20 17:56 ` roopa 2015-02-20 19:28 ` Jonas Johansson 2015-02-21 21:12 ` Scott Feldman 2 siblings, 2 replies; 22+ messages in thread From: Florian Fainelli @ 2015-02-20 16:41 UTC (permalink / raw) To: Jonas Johansson, netdev; +Cc: Jonas Johansson, Jiri Pirko, Scott Feldman On 20/02/15 02:51, Jonas Johansson wrote: > From: Jonas Johansson <jonas.johansson@westermo.se> > > This patch will implement hooks for hardware bonding support for the DSA > driver. When the team driver adds a DSA slave port the port will be assigned > a bond group id and the DSA slave driver can setup the hardware. When team > changes the port state (enabled/disabled) the DSA slave driver is able to > use the attach/detach callback which will allow the hardware to change the > hardware settings to reflect the state. > > Added DSA hooks: > bond_add_group: To add a port to a bond group > bond_del_group: To remove a port from a bond group > bond_attach: To mark the port in a bond group as attached/active > bond_detach: To unmark the port in a bond group as detach/inactive > > Added new network device hooks: > ndo_bond_attach: To attach a device to a bond group. > ndo_bond_detach: To detach a device from a bond group. > > Team: > Added callback to ndo_bond_attach when port is enabled. > Added callback to ndo_bond_detach when port is disabled. > > Added DSA notifier: > Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. > > Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> > --- > drivers/net/team/team.c | 4 ++++ > include/linux/netdevice.h | 8 +++++++ > include/net/dsa.h | 8 +++++++ > net/dsa/dsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ > net/dsa/dsa_priv.h | 6 +++++ > net/dsa/slave.c | 23 ++++++++++++++++++ > 6 files changed, 109 insertions(+) > > diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c > index 0e62274..f7b2afb 100644 > --- a/drivers/net/team/team.c > +++ b/drivers/net/team/team.c > @@ -934,6 +934,8 @@ static void team_port_enable(struct team *team, > team->ops.port_enabled(team, port); > team_notify_peers(team); > team_mcast_rejoin(team); > + if (port->dev->netdev_ops->ndo_bond_attach) > + port->dev->netdev_ops->ndo_bond_attach(port->dev); > } > > static void __reconstruct_port_hlist(struct team *team, int rm_index) > @@ -965,6 +967,8 @@ static void team_port_disable(struct team *team, > team_adjust_ops(team); > team_notify_peers(team); > team_mcast_rejoin(team); > + if (port->dev->netdev_ops->ndo_bond_detach) > + port->dev->netdev_ops->ndo_bond_detach(port->dev); > } Do we really need new ndos here? Cannot we learn this via NETDEV_CHANGEUPPER? > [snip] > > /* platform driver init and cleanup *****************************************/ > static int dev_is_class(struct device *dev, void *class) > @@ -778,6 +835,9 @@ static int dsa_probe(struct platform_device *pdev) > add_timer(&dst->link_poll_timer); > } > > + /* Setup notifier */ > + register_netdevice_notifier(&dsa_nb); I do not think we need to register the netdevice_notifier for every DSA platform_device we might instantiate, a single one, global, whenever the DSA driver gets inserted should be enough. Also, I would prefer if we moved this to net/dsa/slave.c where the other netdevice_ops are layered, very much like this patch: [1]: http://patchwork.ozlabs.org/patch/440696/ > + > return 0; > > out: > diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h > index dc9756d..6a1456a 100644 > --- a/net/dsa/dsa_priv.h > +++ b/net/dsa/dsa_priv.h > @@ -45,6 +45,11 @@ struct dsa_slave_priv { > int old_link; > int old_pause; > int old_duplex; > + > + /* > + * Bond group id, or 0 if port is not bonded. > + */ > + int bond_gid; > }; > > /* dsa.c */ > @@ -58,6 +63,7 @@ struct net_device *dsa_slave_create(struct dsa_switch *ds, > int port, char *name); > int dsa_slave_suspend(struct net_device *slave_dev); > int dsa_slave_resume(struct net_device *slave_dev); > +bool dsa_slave_check(struct net_device *dev); > > /* tag_dsa.c */ > extern const struct dsa_device_ops dsa_netdev_ops; > diff --git a/net/dsa/slave.c b/net/dsa/slave.c > index f23dead..88c84bf 100644 > --- a/net/dsa/slave.c > +++ b/net/dsa/slave.c > @@ -441,6 +441,22 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e) > return ret; > } > > +static int dsa_slave_bond_attach(struct net_device *dev) > +{ > + struct dsa_slave_priv *p = netdev_priv(dev); > + struct dsa_switch *ds = p->parent; > + > + return ds->drv->bond_attach(ds, p->port); You need to test for the callback implementation in the driver, since it is optional and likely not to be implemented immediately. -- Florian ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 16:41 ` Florian Fainelli @ 2015-02-20 17:56 ` roopa 2015-02-20 19:28 ` Jonas Johansson 1 sibling, 0 replies; 22+ messages in thread From: roopa @ 2015-02-20 17:56 UTC (permalink / raw) To: Florian Fainelli Cc: Jonas Johansson, netdev, Jonas Johansson, Jiri Pirko, Scott Feldman On 2/20/15, 8:41 AM, Florian Fainelli wrote: > On 20/02/15 02:51, Jonas Johansson wrote: >> From: Jonas Johansson <jonas.johansson@westermo.se> >> >> This patch will implement hooks for hardware bonding support for the DSA >> driver. When the team driver adds a DSA slave port the port will be assigned >> a bond group id and the DSA slave driver can setup the hardware. When team >> changes the port state (enabled/disabled) the DSA slave driver is able to >> use the attach/detach callback which will allow the hardware to change the >> hardware settings to reflect the state. >> >> Added DSA hooks: >> bond_add_group: To add a port to a bond group >> bond_del_group: To remove a port from a bond group >> bond_attach: To mark the port in a bond group as attached/active >> bond_detach: To unmark the port in a bond group as detach/inactive >> >> Added new network device hooks: >> ndo_bond_attach: To attach a device to a bond group. >> ndo_bond_detach: To detach a device from a bond group. >> >> Team: >> Added callback to ndo_bond_attach when port is enabled. >> Added callback to ndo_bond_detach when port is disabled. >> >> Added DSA notifier: >> Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. >> >> Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> >> --- >> drivers/net/team/team.c | 4 ++++ >> include/linux/netdevice.h | 8 +++++++ >> include/net/dsa.h | 8 +++++++ >> net/dsa/dsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ >> net/dsa/dsa_priv.h | 6 +++++ >> net/dsa/slave.c | 23 ++++++++++++++++++ >> 6 files changed, 109 insertions(+) >> >> diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c >> index 0e62274..f7b2afb 100644 >> --- a/drivers/net/team/team.c >> +++ b/drivers/net/team/team.c >> @@ -934,6 +934,8 @@ static void team_port_enable(struct team *team, >> team->ops.port_enabled(team, port); >> team_notify_peers(team); >> team_mcast_rejoin(team); >> + if (port->dev->netdev_ops->ndo_bond_attach) >> + port->dev->netdev_ops->ndo_bond_attach(port->dev); >> } >> >> static void __reconstruct_port_hlist(struct team *team, int rm_index) >> @@ -965,6 +967,8 @@ static void team_port_disable(struct team *team, >> team_adjust_ops(team); >> team_notify_peers(team); >> team_mcast_rejoin(team); >> + if (port->dev->netdev_ops->ndo_bond_detach) >> + port->dev->netdev_ops->ndo_bond_detach(port->dev); >> } > Do we really need new ndos here? Cannot we learn this via > NETDEV_CHANGEUPPER? +1, I was just typing a similar response. We need this for switchdevices too and notifiers can be used here. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 16:41 ` Florian Fainelli 2015-02-20 17:56 ` roopa @ 2015-02-20 19:28 ` Jonas Johansson 2015-02-21 16:57 ` Jiri Pirko 1 sibling, 1 reply; 22+ messages in thread From: Jonas Johansson @ 2015-02-20 19:28 UTC (permalink / raw) To: Florian Fainelli Cc: Jonas Johansson, netdev, Jonas Johansson, Jiri Pirko, Scott Feldman On Fri, 20 Feb 2015, Florian Fainelli wrote: > On 20/02/15 02:51, Jonas Johansson wrote: >> From: Jonas Johansson <jonas.johansson@westermo.se> >> >> This patch will implement hooks for hardware bonding support for the DSA >> driver. When the team driver adds a DSA slave port the port will be assigned >> a bond group id and the DSA slave driver can setup the hardware. When team >> changes the port state (enabled/disabled) the DSA slave driver is able to >> use the attach/detach callback which will allow the hardware to change the >> hardware settings to reflect the state. >> >> Added DSA hooks: >> bond_add_group: To add a port to a bond group >> bond_del_group: To remove a port from a bond group >> bond_attach: To mark the port in a bond group as attached/active >> bond_detach: To unmark the port in a bond group as detach/inactive >> >> Added new network device hooks: >> ndo_bond_attach: To attach a device to a bond group. >> ndo_bond_detach: To detach a device from a bond group. >> >> Team: >> Added callback to ndo_bond_attach when port is enabled. >> Added callback to ndo_bond_detach when port is disabled. >> >> Added DSA notifier: >> Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. >> >> Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> >> --- >> drivers/net/team/team.c | 4 ++++ >> include/linux/netdevice.h | 8 +++++++ >> include/net/dsa.h | 8 +++++++ >> net/dsa/dsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ >> net/dsa/dsa_priv.h | 6 +++++ >> net/dsa/slave.c | 23 ++++++++++++++++++ >> 6 files changed, 109 insertions(+) >> >> diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c >> index 0e62274..f7b2afb 100644 >> --- a/drivers/net/team/team.c >> +++ b/drivers/net/team/team.c >> @@ -934,6 +934,8 @@ static void team_port_enable(struct team *team, >> team->ops.port_enabled(team, port); >> team_notify_peers(team); >> team_mcast_rejoin(team); >> + if (port->dev->netdev_ops->ndo_bond_attach) >> + port->dev->netdev_ops->ndo_bond_attach(port->dev); >> } >> >> static void __reconstruct_port_hlist(struct team *team, int rm_index) >> @@ -965,6 +967,8 @@ static void team_port_disable(struct team *team, >> team_adjust_ops(team); >> team_notify_peers(team); >> team_mcast_rejoin(team); >> + if (port->dev->netdev_ops->ndo_bond_detach) >> + port->dev->netdev_ops->ndo_bond_detach(port->dev); >> } > > Do we really need new ndos here? Cannot we learn this via > NETDEV_CHANGEUPPER? > If team e.g. uses LACP as runner, a number of ports can be configured as a bond group, but only the ports of the same physical type will be enabled and used for bonding. team_port_enable() and team_port_disable() are the functions to set the ports which should be included for bonding. > > [snip] > >> >> /* platform driver init and cleanup *****************************************/ >> static int dev_is_class(struct device *dev, void *class) >> @@ -778,6 +835,9 @@ static int dsa_probe(struct platform_device *pdev) >> add_timer(&dst->link_poll_timer); >> } >> >> + /* Setup notifier */ >> + register_netdevice_notifier(&dsa_nb); > > I do not think we need to register the netdevice_notifier for every DSA > platform_device we might instantiate, a single one, global, whenever the > DSA driver gets inserted should be enough. > > Also, I would prefer if we moved this to net/dsa/slave.c where the other > netdevice_ops are layered, very much like this patch: > > [1]: http://patchwork.ozlabs.org/patch/440696/ > I agree. >> + >> return 0; >> >> out: >> diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h >> index dc9756d..6a1456a 100644 >> --- a/net/dsa/dsa_priv.h >> +++ b/net/dsa/dsa_priv.h >> @@ -45,6 +45,11 @@ struct dsa_slave_priv { >> int old_link; >> int old_pause; >> int old_duplex; >> + >> + /* >> + * Bond group id, or 0 if port is not bonded. >> + */ >> + int bond_gid; >> }; >> >> /* dsa.c */ >> @@ -58,6 +63,7 @@ struct net_device *dsa_slave_create(struct dsa_switch *ds, >> int port, char *name); >> int dsa_slave_suspend(struct net_device *slave_dev); >> int dsa_slave_resume(struct net_device *slave_dev); >> +bool dsa_slave_check(struct net_device *dev); >> >> /* tag_dsa.c */ >> extern const struct dsa_device_ops dsa_netdev_ops; >> diff --git a/net/dsa/slave.c b/net/dsa/slave.c >> index f23dead..88c84bf 100644 >> --- a/net/dsa/slave.c >> +++ b/net/dsa/slave.c >> @@ -441,6 +441,22 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e) >> return ret; >> } >> >> +static int dsa_slave_bond_attach(struct net_device *dev) >> +{ >> + struct dsa_slave_priv *p = netdev_priv(dev); >> + struct dsa_switch *ds = p->parent; >> + >> + return ds->drv->bond_attach(ds, p->port); > > You need to test for the callback implementation in the driver, since it > is optional and likely not to be implemented immediately. > -- > Florian > Thanks, I missed that. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 19:28 ` Jonas Johansson @ 2015-02-21 16:57 ` Jiri Pirko 2015-02-21 20:43 ` Andrew Lunn 0 siblings, 1 reply; 22+ messages in thread From: Jiri Pirko @ 2015-02-21 16:57 UTC (permalink / raw) To: Jonas Johansson; +Cc: Florian Fainelli, netdev, Jonas Johansson, Scott Feldman Fri, Feb 20, 2015 at 08:28:48PM CET, jonasj76@gmail.com wrote: > > >On Fri, 20 Feb 2015, Florian Fainelli wrote: > >>On 20/02/15 02:51, Jonas Johansson wrote: >>>From: Jonas Johansson <jonas.johansson@westermo.se> >>> >>>This patch will implement hooks for hardware bonding support for the DSA >>>driver. When the team driver adds a DSA slave port the port will be assigned >>>a bond group id and the DSA slave driver can setup the hardware. When team >>>changes the port state (enabled/disabled) the DSA slave driver is able to >>>use the attach/detach callback which will allow the hardware to change the >>>hardware settings to reflect the state. >>> >>>Added DSA hooks: >>> bond_add_group: To add a port to a bond group >>> bond_del_group: To remove a port from a bond group >>> bond_attach: To mark the port in a bond group as attached/active >>> bond_detach: To unmark the port in a bond group as detach/inactive >>> >>>Added new network device hooks: >>> ndo_bond_attach: To attach a device to a bond group. >>> ndo_bond_detach: To detach a device from a bond group. >>> >>>Team: >>> Added callback to ndo_bond_attach when port is enabled. >>> Added callback to ndo_bond_detach when port is disabled. >>> >>>Added DSA notifier: >>> Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. >>> >>>Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> >>>--- >>> drivers/net/team/team.c | 4 ++++ >>> include/linux/netdevice.h | 8 +++++++ >>> include/net/dsa.h | 8 +++++++ >>> net/dsa/dsa.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ >>> net/dsa/dsa_priv.h | 6 +++++ >>> net/dsa/slave.c | 23 ++++++++++++++++++ >>> 6 files changed, 109 insertions(+) >>> >>>diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c >>>index 0e62274..f7b2afb 100644 >>>--- a/drivers/net/team/team.c >>>+++ b/drivers/net/team/team.c >>>@@ -934,6 +934,8 @@ static void team_port_enable(struct team *team, >>> team->ops.port_enabled(team, port); >>> team_notify_peers(team); >>> team_mcast_rejoin(team); >>>+ if (port->dev->netdev_ops->ndo_bond_attach) >>>+ port->dev->netdev_ops->ndo_bond_attach(port->dev); >>> } >>> >>> static void __reconstruct_port_hlist(struct team *team, int rm_index) >>>@@ -965,6 +967,8 @@ static void team_port_disable(struct team *team, >>> team_adjust_ops(team); >>> team_notify_peers(team); >>> team_mcast_rejoin(team); >>>+ if (port->dev->netdev_ops->ndo_bond_detach) >>>+ port->dev->netdev_ops->ndo_bond_detach(port->dev); >>> } >> >>Do we really need new ndos here? Cannot we learn this via >>NETDEV_CHANGEUPPER? >> >If team e.g. uses LACP as runner, a number of ports can be configured as a >bond group, but only the ports of the same physical type will be enabled and >used for bonding. team_port_enable() and team_port_disable() are the >functions to set the ports which should be included for bonding. Hmm, I'm not sure I understand correctly what the marvel hw is capable of. Would you care to explain it a bit ? (or maybe I should read the datasheet) If we want to offload bond functionality (tx, rx), we need to be careful about the features, mainly mode/runner tx function which should not be different in hw to what we have in kernel. That might be pretty hard for example in case of loadbalance team mode, where bpf is used to get tx port. Also, switchdev ndos and notifier propagation needs to be implemented in team/bond. But maybe I'm getting your usecase wrong. Please help me to understand it. Thanks. > >> >>[snip] >> >>> >>> /* platform driver init and cleanup *****************************************/ >>> static int dev_is_class(struct device *dev, void *class) >>>@@ -778,6 +835,9 @@ static int dsa_probe(struct platform_device *pdev) >>> add_timer(&dst->link_poll_timer); >>> } >>> >>>+ /* Setup notifier */ >>>+ register_netdevice_notifier(&dsa_nb); >> >>I do not think we need to register the netdevice_notifier for every DSA >>platform_device we might instantiate, a single one, global, whenever the >>DSA driver gets inserted should be enough. >> >>Also, I would prefer if we moved this to net/dsa/slave.c where the other >>netdevice_ops are layered, very much like this patch: >> >>[1]: http://patchwork.ozlabs.org/patch/440696/ >> >I agree. > >>>+ >>> return 0; >>> >>> out: >>>diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h >>>index dc9756d..6a1456a 100644 >>>--- a/net/dsa/dsa_priv.h >>>+++ b/net/dsa/dsa_priv.h >>>@@ -45,6 +45,11 @@ struct dsa_slave_priv { >>> int old_link; >>> int old_pause; >>> int old_duplex; >>>+ >>>+ /* >>>+ * Bond group id, or 0 if port is not bonded. >>>+ */ >>>+ int bond_gid; >>> }; >>> >>> /* dsa.c */ >>>@@ -58,6 +63,7 @@ struct net_device *dsa_slave_create(struct dsa_switch *ds, >>> int port, char *name); >>> int dsa_slave_suspend(struct net_device *slave_dev); >>> int dsa_slave_resume(struct net_device *slave_dev); >>>+bool dsa_slave_check(struct net_device *dev); >>> >>> /* tag_dsa.c */ >>> extern const struct dsa_device_ops dsa_netdev_ops; >>>diff --git a/net/dsa/slave.c b/net/dsa/slave.c >>>index f23dead..88c84bf 100644 >>>--- a/net/dsa/slave.c >>>+++ b/net/dsa/slave.c >>>@@ -441,6 +441,22 @@ static int dsa_slave_get_eee(struct net_device *dev, struct ethtool_eee *e) >>> return ret; >>> } >>> >>>+static int dsa_slave_bond_attach(struct net_device *dev) >>>+{ >>>+ struct dsa_slave_priv *p = netdev_priv(dev); >>>+ struct dsa_switch *ds = p->parent; >>>+ >>>+ return ds->drv->bond_attach(ds, p->port); >> >>You need to test for the callback implementation in the driver, since it >>is optional and likely not to be implemented immediately. >>-- >>Florian >> >Thanks, I missed that. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-21 16:57 ` Jiri Pirko @ 2015-02-21 20:43 ` Andrew Lunn 0 siblings, 0 replies; 22+ messages in thread From: Andrew Lunn @ 2015-02-21 20:43 UTC (permalink / raw) To: Jiri Pirko Cc: Jonas Johansson, Florian Fainelli, netdev, Jonas Johansson, Scott Feldman > Hmm, I'm not sure I understand correctly what the marvel hw is capable of. > Would you care to explain it a bit ? (or maybe I should read the > datasheet) The mv88e6060 data sheet is publicly available. It is a rather old chip, but i guess trunking has not changed too much since then. All the newer chips require an NDA to get the datahseet. What i've done before is get the switch to combine two ports into a trunk. It will then load balance packets over the two ports. If one of the ports fails, i.e. link down, it will then concentrate all the traffic over the one remaining port. i.e some basic form of redundancy/failover. Not covered by this patchset, but what would be interesting, is getting trunking working towards the host. Many of the recent wireless APs have two ethernet interfaces connected to the switch. The current DSA architecture only allows one of them to be used for traffic to/from the host from/to the switch. Andrew ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-20 10:51 ` [PATCH net-next 1/2] dsa: bonding: " Jonas Johansson 2015-02-20 15:12 ` Andrew Lunn 2015-02-20 16:41 ` Florian Fainelli @ 2015-02-21 21:12 ` Scott Feldman 2015-02-23 15:52 ` Jonas Johansson 2 siblings, 1 reply; 22+ messages in thread From: Scott Feldman @ 2015-02-21 21:12 UTC (permalink / raw) To: Jonas Johansson Cc: Netdev, Jonas Johansson, Roopa Prabhu, Florian Fainelli, Andy Gospodarek, Jiří Pírko On Fri, Feb 20, 2015 at 2:51 AM, Jonas Johansson <jonasj76@gmail.com> wrote: > From: Jonas Johansson <jonas.johansson@westermo.se> > > This patch will implement hooks for hardware bonding support for the DSA > driver. When the team driver adds a DSA slave port the port will be assigned > a bond group id and the DSA slave driver can setup the hardware. When team > changes the port state (enabled/disabled) the DSA slave driver is able to > use the attach/detach callback which will allow the hardware to change the > hardware settings to reflect the state. > > Added DSA hooks: > bond_add_group: To add a port to a bond group > bond_del_group: To remove a port from a bond group > bond_attach: To mark the port in a bond group as attached/active > bond_detach: To unmark the port in a bond group as detach/inactive > > Added new network device hooks: > ndo_bond_attach: To attach a device to a bond group. > ndo_bond_detach: To detach a device from a bond group. > > Team: > Added callback to ndo_bond_attach when port is enabled. > Added callback to ndo_bond_detach when port is disabled. > > Added DSA notifier: > Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. Hi Jonas, Cc:'ing Andy as he mentioned at netdev01 he was looking into something similar for switchdev. My comments are along the lines of the others: Can we up-level this not for just DSA but for switchdev in general? I think the requirements are: 1) It should work for team or bonding. 2) Port driver needs to know a) bond membership, and b) port (active, inactive) status, at least for 802.3ad. 3) Try to avoid adding new ndo ops if possible, and rather use what's there. It took me a bit to figure out your new ndo ops in this patch. Going by the name ndo_bond_attach/dettach, I thought these were for port membership, but you're using them for port status change. So the name was confusing. Since you already have port membership covered with netdevice event NETDEV_CHANGEUPPER, can we also adapt port status change into netdevice event NETDEV_BONDING_INFO? (See netdev_bonding_info_change()). -scott ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 1/2] dsa: bonding: implement HW bonding 2015-02-21 21:12 ` Scott Feldman @ 2015-02-23 15:52 ` Jonas Johansson 0 siblings, 0 replies; 22+ messages in thread From: Jonas Johansson @ 2015-02-23 15:52 UTC (permalink / raw) To: Scott Feldman Cc: Jonas Johansson, Netdev, Jonas Johansson, Roopa Prabhu, Florian Fainelli, Andy Gospodarek, Jiří Pírko On Sat, 21 Feb 2015, Scott Feldman wrote: > On Fri, Feb 20, 2015 at 2:51 AM, Jonas Johansson <jonasj76@gmail.com> wrote: >> From: Jonas Johansson <jonas.johansson@westermo.se> >> >> This patch will implement hooks for hardware bonding support for the DSA >> driver. When the team driver adds a DSA slave port the port will be assigned >> a bond group id and the DSA slave driver can setup the hardware. When team >> changes the port state (enabled/disabled) the DSA slave driver is able to >> use the attach/detach callback which will allow the hardware to change the >> hardware settings to reflect the state. >> >> Added DSA hooks: >> bond_add_group: To add a port to a bond group >> bond_del_group: To remove a port from a bond group >> bond_attach: To mark the port in a bond group as attached/active >> bond_detach: To unmark the port in a bond group as detach/inactive >> >> Added new network device hooks: >> ndo_bond_attach: To attach a device to a bond group. >> ndo_bond_detach: To detach a device from a bond group. >> >> Team: >> Added callback to ndo_bond_attach when port is enabled. >> Added callback to ndo_bond_detach when port is disabled. >> >> Added DSA notifier: >> Listening on NETDEV_CHANGEUPPER to add or deleta a port to/from a bond group. > > Hi Jonas, > > Cc:'ing Andy as he mentioned at netdev01 he was looking into something > similar for switchdev. > > My comments are along the lines of the others: > > Can we up-level this not for just DSA but for switchdev in general? I > think the requirements are: > > 1) It should work for team or bonding. > > 2) Port driver needs to know a) bond membership, and b) port (active, > inactive) status, at least for 802.3ad. > > 3) Try to avoid adding new ndo ops if possible, and rather use what's there. > > It took me a bit to figure out your new ndo ops in this patch. Going > by the name ndo_bond_attach/dettach, I thought these were for port > membership, but you're using them for port status change. So the name > was confusing. Since you already have port membership covered with > netdevice event NETDEV_CHANGEUPPER, can we also adapt port status > change into netdevice event NETDEV_BONDING_INFO? (See > netdev_bonding_info_change()). > > -scott > I think aiming for switchdev is a good ides. I will look into this and if NETDEV_BONDING_INFO can be used instead if adding the new ndo fops. I'm on vacation atm, so I will start look into it the next week. Thanks for all the good input. - Jonas ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-02-20 10:51 [PATCH net-next 0/2] dsa: implement HW bonding Jonas Johansson 2015-02-20 10:51 ` [PATCH net-next 1/2] dsa: bonding: " Jonas Johansson @ 2015-02-20 10:51 ` Jonas Johansson 2015-02-20 15:26 ` Andrew Lunn 2015-02-21 16:40 ` [PATCH net-next 0/2] dsa: implement HW bonding Jiri Pirko 2 siblings, 1 reply; 22+ messages in thread From: Jonas Johansson @ 2015-02-20 10:51 UTC (permalink / raw) To: netdev; +Cc: Jonas Johansson From: Jonas Johansson <jonas.johansson@westermo.se> This patch will use the DSA hardware bonding support hooks to setup trunking for the Marvell 88E6095 device. The implementation only handles trunking in a single device. Hooks: .bond_add_group: Add port to a bond group .bond_del_group: Remove port from a bond group .bond_attach: Attach/activate port in bond group .bond_detach: Detach/inactivate port in bond group Procedure to add/remome port from bond group: Setup trunk learning (Port Association Vector) Setup loop prevention (VLAN Table) Setup load balancing (Trunk Mask Load Balance Table) Procedure to attach/detach port: Change load balancing (Trunk Mask Load Balance Table) Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> --- drivers/net/dsa/mv88e6131.c | 254 ++++++++++++++++++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx.h | 14 +++ 2 files changed, 268 insertions(+) diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index 2540ef0..3ba7a0c 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c @@ -382,6 +382,256 @@ mv88e6131_get_ethtool_stats(struct dsa_switch *ds, mv88e6131_hw_stats, port, data); } +/* Trunking */ +static int mv88e6131_bond_set_trunk_learning(struct dsa_switch *ds, + int *ports, size_t num) +{ + u16 port_vec = 0; + int ret; + int i; + + num = num < MAX_PORTS ? num : MAX_PORTS; + + for (i = 0; i < num; i++) + port_vec |= 1 << ports[i]; + + for (i = 0; i < num; i++) { + ret = mv88e6xxx_reg_read(ds, REG_PORT(ports[i]), REG_PORT_PAV); + if (ret < 0) + continue; + ret = (ret & 0xf800) | (port_vec & 0x7ff); + mv88e6xxx_reg_write(ds, REG_PORT(ports[i]), REG_PORT_PAV, ret); + } + + return 0; +} + +static int mv88e6131_bond_set_loop_prevention(struct dsa_switch *ds, + int *ports, size_t num) +{ + u16 port_vec = 0; + int ret; + int i; + + num = num < MAX_PORTS ? num : MAX_PORTS; + + for (i = 0; i < num; i++) + port_vec |= 1 << ports[i]; + + for (i = 0; i < num; i++) { + ret = mv88e6xxx_reg_read(ds, REG_PORT(ports[i]), REG_PORT_VLAN_MAP); + if (ret < 0) + continue; + ret &= ~port_vec & 0x7ff; + mv88e6xxx_reg_write(ds, REG_PORT(ports[i]), REG_PORT_VLAN_MAP, ret); + } + + return 0; +} + +static int mv88e6131_wait_trunk_mask(struct dsa_switch *ds) +{ + const int max_retries = 10; + int retries = 0; + int ret; + + /* Wait for update Trunk Mask data */ + while (1) { + ret = REG_READ(REG_GLOBAL2, REG_TRUNK_MASK); + if (!(ret & 0x8000)) + return ret; + if (retries > max_retries) { + pr_warn("mv88e6131: Timeout waiting for " + "Trunk Mask Table Register Update\n"); + return -EBUSY; + } + retries++; + usleep_range(20, 50); + }; + + return -EPERM; +} + +static int mv88e6131_get_trunk_mask(struct dsa_switch *ds, int trunk_nr, u16 *mask) +{ + int ret; + + if (trunk_nr > 0x7) + return -EINVAL; + + ret = mv88e6131_wait_trunk_mask(ds); + if (ret < 0) + return ret; + + /* Set MaskNum */ + ret = (ret & 0x0fff) | (trunk_nr << 12); + REG_WRITE(REG_GLOBAL2, REG_TRUNK_MASK, ret); + + /* Get TrunkMask */ + ret = REG_READ(REG_GLOBAL2, REG_TRUNK_MASK); + *mask = ret & 0x7FF; + + return 0; +} + +static int mv88e6131_set_trunk_mask(struct dsa_switch *ds, int trunk_nr, u16 mask) +{ + int ret; + + if (trunk_nr > 0x7) + return -EINVAL; + + ret = mv88e6131_wait_trunk_mask(ds); + if (ret < 0) + return ret; + + /* Write TrunkMask */ + ret = 0x8000 | (ret & 0x7800) | (trunk_nr << 12) | (mask & 0x7ff); + REG_WRITE(REG_GLOBAL2, REG_TRUNK_MASK, ret); + + return 0; +} + +static int mv88e6131_bond_set_load_balancing(struct dsa_switch *ds, + int *ports, bool *attached, size_t num) +{ + u16 mask; + u16 member_mask = 0; + int att_ports[MAX_PORTS]; + int att_num = 0; + int ret; + int i; + + num = num < MAX_PORTS ? num : MAX_PORTS; + + for (i = 0; i < num; i++) { + member_mask |= 1 << ports[i]; + if (attached[i]) + att_ports[att_num++] = ports[i]; + } + + for (i = 0; i < 8; i++) { + ret = mv88e6131_get_trunk_mask(ds, i, &mask); + if (ret < 0) + continue; + mask &= ~member_mask; + if (att_num) + mask |= 1 << att_ports[i % att_num]; + mv88e6131_set_trunk_mask(ds, i, mask); + } + + return 0; +} + +static int mv88e6131_bond_get_ports(struct dsa_switch *ds, int gid, int *ports, bool *attached, size_t sz) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int num = 0; + int p; + + for (p = 0; (p < MAX_PORTS) && (num < sz) ; p++) { + if (ps->bond_port[p].gid == gid) { + ports[num] = p; + attached[num] = ps->bond_port[p].attached; + num++; + } + } + + return num; +} + +static int mv88e6131_bond_setup(struct dsa_switch *ds, int gid) +{ + int ports[MAX_PORTS]; + bool attached[MAX_PORTS]; + int num; + int err = 0; + + num = mv88e6131_bond_get_ports(ds, gid, ports, attached, MAX_PORTS); + + err = mv88e6131_bond_set_trunk_learning(ds, ports, num); + if (err) + return err; + err = mv88e6131_bond_set_loop_prevention(ds, ports, num); + if (err) + return err; + err = mv88e6131_bond_set_load_balancing(ds, ports, attached, num); + if (err) + return err; + + return 0; + +} + +static int mv88e6131_bond_add_group(struct dsa_switch *ds, int port, int gid) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + + ps->bond_port[port].gid = gid; + ps->bond_port[port].attached = false; + + return mv88e6131_bond_setup(ds, gid); +} + +static int mv88e6131_bond_del_group(struct dsa_switch *ds, int port, int gid) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + bool btmp; + int ret; + + ps->bond_port[port].gid = 0; + ps->bond_port[port].attached = false; + mv88e6131_bond_setup(ds, gid); + + /* Reset trunk learning */ + ret = mv88e6xxx_reg_read(ds, REG_PORT(port), REG_PORT_PAV); + if (ret >= 0) { + ret = (ret & 0xf800) | ((1 << port) & 0x7ff); + mv88e6xxx_reg_write(ds, REG_PORT(port), REG_PORT_PAV, ret); + } + /* Reset loop prevention */ + ret = mv88e6xxx_reg_read(ds, REG_PORT(port), REG_PORT_VLAN_MAP); + if (ret >= 0) { + ret = (ret & 0xf800) | ((1 << dsa_upstream_port(ds)) & 0x7ff); + mv88e6xxx_reg_write(ds, REG_PORT(port), REG_PORT_VLAN_MAP, ret); + } + /* Reset load balancing */ + btmp = true; + mv88e6131_bond_set_load_balancing(ds, &port, &btmp, 1); + + return 0; +} + +static int mv88e6131_bond_attach(struct dsa_switch *ds, int port) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ports[MAX_PORTS]; + bool attached[MAX_PORTS]; + int gid = ps->bond_port[port].gid; + int num; + + ps->bond_port[port].attached = true; + num = mv88e6131_bond_get_ports(ds, gid, ports, attached, MAX_PORTS); + + return mv88e6131_bond_set_load_balancing(ds, ports, attached, num); +} + +static int mv88e6131_bond_detach(struct dsa_switch *ds, int port) +{ + struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); + int ports[MAX_PORTS]; + bool attached[MAX_PORTS]; + int gid = ps->bond_port[port].gid; + int num; + + ps->bond_port[port].attached = false; + num = mv88e6131_bond_get_ports(ds, gid, ports, attached, MAX_PORTS); + + return mv88e6131_bond_set_load_balancing(ds, ports, attached, num); +} + + + static int mv88e6131_get_sset_count(struct dsa_switch *ds) { return ARRAY_SIZE(mv88e6131_hw_stats); @@ -399,6 +649,10 @@ struct dsa_switch_driver mv88e6131_switch_driver = { .get_strings = mv88e6131_get_strings, .get_ethtool_stats = mv88e6131_get_ethtool_stats, .get_sset_count = mv88e6131_get_sset_count, + .bond_add_group = mv88e6131_bond_add_group, + .bond_del_group = mv88e6131_bond_del_group, + .bond_attach = mv88e6131_bond_attach, + .bond_detach = mv88e6131_bond_detach, }; MODULE_ALIAS("platform:mv88e6085"); diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 7294227..383b224 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h @@ -11,9 +11,19 @@ #ifndef __MV88E6XXX_H #define __MV88E6XXX_H +#define MAX_PORTS 11 + #define REG_PORT(p) (0x10 + (p)) +#define REG_PORT_VLAN_MAP 0x6 +#define REG_PORT_PAV 0xb #define REG_GLOBAL 0x1b #define REG_GLOBAL2 0x1c +#define REG_TRUNK_MASK 0x7 + +struct mv88e6xxx_bond_port { + int gid; + bool attached; +}; struct mv88e6xxx_priv_state { /* When using multi-chip addressing, this mutex protects @@ -49,6 +59,10 @@ struct mv88e6xxx_priv_state { struct mutex eeprom_mutex; int id; /* switch product id */ + + /* Contains bonding info for each port + */ + struct mv88e6xxx_bond_port bond_port[MAX_PORTS]; }; struct mv88e6xxx_hw_stat { -- 2.1.0 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-02-20 10:51 ` [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking Jonas Johansson @ 2015-02-20 15:26 ` Andrew Lunn 2015-02-20 15:56 ` Jonas Johansson 2015-03-06 17:06 ` Florian Fainelli 0 siblings, 2 replies; 22+ messages in thread From: Andrew Lunn @ 2015-02-20 15:26 UTC (permalink / raw) To: Jonas Johansson; +Cc: netdev, Jonas Johansson On Fri, Feb 20, 2015 at 11:51:13AM +0100, Jonas Johansson wrote: > From: Jonas Johansson <jonas.johansson@westermo.se> > > This patch will use the DSA hardware bonding support hooks to setup trunking > for the Marvell 88E6095 device. The implementation only handles trunking in > a single device. > > Hooks: > .bond_add_group: Add port to a bond group > .bond_del_group: Remove port from a bond group > .bond_attach: Attach/activate port in bond group > .bond_detach: Detach/inactivate port in bond group > > Procedure to add/remome port from bond group: > Setup trunk learning (Port Association Vector) > Setup loop prevention (VLAN Table) > Setup load balancing (Trunk Mask Load Balance Table) > > Procedure to attach/detach port: > Change load balancing (Trunk Mask Load Balance Table) > > Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> > --- > drivers/net/dsa/mv88e6131.c | 254 ++++++++++++++++++++++++++++++++++++++++++++ > drivers/net/dsa/mv88e6xxx.h | 14 +++ > 2 files changed, 268 insertions(+) > > diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c > index 2540ef0..3ba7a0c 100644 > --- a/drivers/net/dsa/mv88e6131.c > +++ b/drivers/net/dsa/mv88e6131.c > @@ -382,6 +382,256 @@ mv88e6131_get_ethtool_stats(struct dsa_switch *ds, > mv88e6131_hw_stats, port, data); > } > > +/* Trunking */ > +static int mv88e6131_bond_set_trunk_learning(struct dsa_switch *ds, > + int *ports, size_t num) > +{ > + u16 port_vec = 0; > + int ret; > + int i; > + > + num = num < MAX_PORTS ? num : MAX_PORTS; > + > + for (i = 0; i < num; i++) > + port_vec |= 1 << ports[i]; > + > + for (i = 0; i < num; i++) { > + ret = mv88e6xxx_reg_read(ds, REG_PORT(ports[i]), REG_PORT_PAV); > + if (ret < 0) > + continue; > + ret = (ret & 0xf800) | (port_vec & 0x7ff); > + mv88e6xxx_reg_write(ds, REG_PORT(ports[i]), REG_PORT_PAV, ret); > + } > + > + return 0; > +} The mv886060 seems to have the PAV register. So i guess most of the Marvell switches support this. Is there anything specific to the 6131 here? Could this be moved into mv88x6xxx so other switch drivers can use it? > + > +static int mv88e6131_bond_set_loop_prevention(struct dsa_switch *ds, > + int *ports, size_t num) > +{ > + u16 port_vec = 0; > + int ret; > + int i; > + > + num = num < MAX_PORTS ? num : MAX_PORTS; > + > + for (i = 0; i < num; i++) > + port_vec |= 1 << ports[i]; > + > + for (i = 0; i < num; i++) { > + ret = mv88e6xxx_reg_read(ds, REG_PORT(ports[i]), REG_PORT_VLAN_MAP); > + if (ret < 0) > + continue; > + ret &= ~port_vec & 0x7ff; > + mv88e6xxx_reg_write(ds, REG_PORT(ports[i]), REG_PORT_VLAN_MAP, ret); > + } > + > + return 0; > +} Same question again, anything specific to the 6131 here? > +static int mv88e6131_wait_trunk_mask(struct dsa_switch *ds) > +{ > + const int max_retries = 10; > + int retries = 0; > + int ret; > + > + /* Wait for update Trunk Mask data */ > + while (1) { > + ret = REG_READ(REG_GLOBAL2, REG_TRUNK_MASK); > + if (!(ret & 0x8000)) > + return ret; > + if (retries > max_retries) { > + pr_warn("mv88e6131: Timeout waiting for " > + "Trunk Mask Table Register Update\n"); > + return -EBUSY; > + } > + retries++; > + usleep_range(20, 50); > + }; This looks a lot like the wait functions what Guenter Roeck added to 6352 and i just moved to mv88e6xxx.c. Please use the generic infrastructure in the shared code. Please could you look at all your functions and see what is specific to the 6131 and what is generic. Place the generic code into mv88e6xxx please so we can all use it. Thanks Andrew ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-02-20 15:26 ` Andrew Lunn @ 2015-02-20 15:56 ` Jonas Johansson 2015-03-06 17:06 ` Florian Fainelli 1 sibling, 0 replies; 22+ messages in thread From: Jonas Johansson @ 2015-02-20 15:56 UTC (permalink / raw) To: Andrew Lunn; +Cc: Jonas Johansson, netdev, Jonas Johansson On Fri, 20 Feb 2015, Andrew Lunn wrote: > On Fri, Feb 20, 2015 at 11:51:13AM +0100, Jonas Johansson wrote: >> From: Jonas Johansson <jonas.johansson@westermo.se> >> >> This patch will use the DSA hardware bonding support hooks to setup trunking >> for the Marvell 88E6095 device. The implementation only handles trunking in >> a single device. >> >> Hooks: >> .bond_add_group: Add port to a bond group >> .bond_del_group: Remove port from a bond group >> .bond_attach: Attach/activate port in bond group >> .bond_detach: Detach/inactivate port in bond group >> >> Procedure to add/remome port from bond group: >> Setup trunk learning (Port Association Vector) >> Setup loop prevention (VLAN Table) >> Setup load balancing (Trunk Mask Load Balance Table) >> >> Procedure to attach/detach port: >> Change load balancing (Trunk Mask Load Balance Table) >> >> Signed-off-by: Jonas Johansson <jonas.johansson@westermo.se> >> --- >> drivers/net/dsa/mv88e6131.c | 254 ++++++++++++++++++++++++++++++++++++++++++++ >> drivers/net/dsa/mv88e6xxx.h | 14 +++ >> 2 files changed, 268 insertions(+) >> >> diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c >> index 2540ef0..3ba7a0c 100644 >> --- a/drivers/net/dsa/mv88e6131.c >> +++ b/drivers/net/dsa/mv88e6131.c >> @@ -382,6 +382,256 @@ mv88e6131_get_ethtool_stats(struct dsa_switch *ds, >> mv88e6131_hw_stats, port, data); >> } >> >> +/* Trunking */ >> +static int mv88e6131_bond_set_trunk_learning(struct dsa_switch *ds, >> + int *ports, size_t num) >> +{ >> + u16 port_vec = 0; >> + int ret; >> + int i; >> + >> + num = num < MAX_PORTS ? num : MAX_PORTS; >> + >> + for (i = 0; i < num; i++) >> + port_vec |= 1 << ports[i]; >> + >> + for (i = 0; i < num; i++) { >> + ret = mv88e6xxx_reg_read(ds, REG_PORT(ports[i]), REG_PORT_PAV); >> + if (ret < 0) >> + continue; >> + ret = (ret & 0xf800) | (port_vec & 0x7ff); >> + mv88e6xxx_reg_write(ds, REG_PORT(ports[i]), REG_PORT_PAV, ret); >> + } >> + >> + return 0; >> +} > > The mv886060 seems to have the PAV register. So i guess most of the > Marvell switches support this. Is there anything specific to the 6131 > here? Could this be moved into mv88x6xxx so other switch drivers can > use it? > I guess you are correct, i'll look into it. >> + >> +static int mv88e6131_bond_set_loop_prevention(struct dsa_switch *ds, >> + int *ports, size_t num) >> +{ >> + u16 port_vec = 0; >> + int ret; >> + int i; >> + >> + num = num < MAX_PORTS ? num : MAX_PORTS; >> + >> + for (i = 0; i < num; i++) >> + port_vec |= 1 << ports[i]; >> + >> + for (i = 0; i < num; i++) { >> + ret = mv88e6xxx_reg_read(ds, REG_PORT(ports[i]), REG_PORT_VLAN_MAP); >> + if (ret < 0) >> + continue; >> + ret &= ~port_vec & 0x7ff; >> + mv88e6xxx_reg_write(ds, REG_PORT(ports[i]), REG_PORT_VLAN_MAP, ret); >> + } >> + >> + return 0; >> +} > > Same question again, anything specific to the 6131 here? > I'll check. >> +static int mv88e6131_wait_trunk_mask(struct dsa_switch *ds) >> +{ >> + const int max_retries = 10; >> + int retries = 0; >> + int ret; >> + >> + /* Wait for update Trunk Mask data */ >> + while (1) { >> + ret = REG_READ(REG_GLOBAL2, REG_TRUNK_MASK); >> + if (!(ret & 0x8000)) >> + return ret; >> + if (retries > max_retries) { >> + pr_warn("mv88e6131: Timeout waiting for " >> + "Trunk Mask Table Register Update\n"); >> + return -EBUSY; >> + } >> + retries++; >> + usleep_range(20, 50); >> + }; > > This looks a lot like the wait functions what Guenter Roeck added to > 6352 and i just moved to mv88e6xxx.c. Please use the generic > infrastructure in the shared code. > Seems like the function is doing exactly what I'm looking for. > Please could you look at all your functions and see what is specific > to the 6131 and what is generic. Place the generic code into mv88e6xxx > please so we can all use it. > > Thanks > Andrew > Thanks for your review, I'll check if the functions is specific to the 6131 or if it the code could be moved to mv88e6xxx.c. On vacation a.t.m, back in a week. ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-02-20 15:26 ` Andrew Lunn 2015-02-20 15:56 ` Jonas Johansson @ 2015-03-06 17:06 ` Florian Fainelli 2015-03-06 19:23 ` Andrew Lunn 1 sibling, 1 reply; 22+ messages in thread From: Florian Fainelli @ 2015-03-06 17:06 UTC (permalink / raw) To: Andrew Lunn, Jonas Johansson Cc: netdev, Jonas Johansson, Jiri Pirko, Scott Feldman On 20/02/15 07:26, Andrew Lunn wrote: > On Fri, Feb 20, 2015 at 11:51:13AM +0100, Jonas Johansson wrote: > > Please could you look at all your functions and see what is specific > to the 6131 and what is generic. Place the generic code into mv88e6xxx > please so we can all use it. Out of curiosity, how many bonding/trunking groups are supported on the switches models currently in tree? Let's say there is a limitation: like no more than 2 different bonding groups on a given physical switch, where would we put this limitation, down to the switch driver? -- Florian ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-03-06 17:06 ` Florian Fainelli @ 2015-03-06 19:23 ` Andrew Lunn 2015-03-06 20:47 ` Florian Fainelli 0 siblings, 1 reply; 22+ messages in thread From: Andrew Lunn @ 2015-03-06 19:23 UTC (permalink / raw) To: Florian Fainelli Cc: Jonas Johansson, netdev, Jonas Johansson, Jiri Pirko, Scott Feldman On Fri, Mar 06, 2015 at 09:06:50AM -0800, Florian Fainelli wrote: > On 20/02/15 07:26, Andrew Lunn wrote: > > On Fri, Feb 20, 2015 at 11:51:13AM +0100, Jonas Johansson wrote: > > > > Please could you look at all your functions and see what is specific > > to the 6131 and what is generic. Place the generic code into mv88e6xxx > > please so we can all use it. > > Out of curiosity, how many bonding/trunking groups are supported on the > switches models currently in tree? > > Let's say there is a limitation: like no more than 2 different bonding > groups on a given physical switch, where would we put this limitation, > down to the switch driver? Hi Florian It is limited, but it seems to be quite a high limit. I don't have exact numbers for the devices currently in tree, but i've used an 10 port switch which had a limit something like 8 trunk groups, and a maximum of 8 ports per trunk. I suspect we would put the resource tracking in the shared mv88e6xxx code, and configure it with the limitations from the specific chip driver. However, does SF2 have similar trunking capabilities, and limits? Does it make sense to have this at a higher level so it can be used by all drivers? Andrew ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-03-06 19:23 ` Andrew Lunn @ 2015-03-06 20:47 ` Florian Fainelli 2015-03-06 21:47 ` Andrew Lunn 0 siblings, 1 reply; 22+ messages in thread From: Florian Fainelli @ 2015-03-06 20:47 UTC (permalink / raw) To: Andrew Lunn Cc: Jonas Johansson, netdev, Jonas Johansson, Jiri Pirko, Scott Feldman On 06/03/15 11:23, Andrew Lunn wrote: > On Fri, Mar 06, 2015 at 09:06:50AM -0800, Florian Fainelli wrote: >> On 20/02/15 07:26, Andrew Lunn wrote: >>> On Fri, Feb 20, 2015 at 11:51:13AM +0100, Jonas Johansson wrote: >>> >>> Please could you look at all your functions and see what is specific >>> to the 6131 and what is generic. Place the generic code into mv88e6xxx >>> please so we can all use it. >> >> Out of curiosity, how many bonding/trunking groups are supported on the >> switches models currently in tree? >> >> Let's say there is a limitation: like no more than 2 different bonding >> groups on a given physical switch, where would we put this limitation, >> down to the switch driver? > > Hi Florian > > It is limited, but it seems to be quite a high limit. I don't have > exact numbers for the devices currently in tree, but i've used an 10 > port switch which had a limit something like 8 trunk groups, and a > maximum of 8 ports per trunk. > > I suspect we would put the resource tracking in the shared mv88e6xxx > code, and configure it with the limitations from the specific chip > driver. > > However, does SF2 have similar trunking capabilities, and limits? Does > it make sense to have this at a higher level so it can be used by all > drivers? Most Broadcom switches, either SF2 or roboswitch (b53) have a limit of 2 trunking groups, without limitations on the number of ports included in any of these two groups. The larger question is once we start advertising capabilities, where does that stop, right? It would probably be simpler for now to e.g: allow 2 trunking groups to be configured, and when trying to configure a 3rd one, return -ENOSPC and act upon that to either take the software slow path (which is probably not possible) or just return a hard error condition. -- Florian ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-03-06 20:47 ` Florian Fainelli @ 2015-03-06 21:47 ` Andrew Lunn 2015-03-06 22:43 ` Scott Feldman 0 siblings, 1 reply; 22+ messages in thread From: Andrew Lunn @ 2015-03-06 21:47 UTC (permalink / raw) To: Florian Fainelli Cc: Jonas Johansson, netdev, Jonas Johansson, Jiri Pirko, Scott Feldman Hi Florian > Most Broadcom switches, either SF2 or roboswitch (b53) have a limit of 2 > trunking groups, without limitations on the number of ports included in > any of these two groups. O.K, so maybe we want the basic resource management in the DSA layer, not the switch drivers. > The larger question is once we start advertising capabilities, where > does that stop, right? It would probably be simpler for now to e.g: > allow 2 trunking groups to be configured, and when trying to configure a > 3rd one, return -ENOSPC and act upon that to either take the software > slow path (which is probably not possible) or just return a hard error > condition. This is more than a DSA question. It applies to all the hardware acceleration being discussed at the moment. As you hinted to above, i suppose we have two different situations: 1) We can fall back to a software slow path. 2) There is no software fallback, we have to error out, and it would be nice to have a well defined error code for out of hardware resources. We also should think about how we tell user space we have fallen back to a slow path. I'm sure users want to know why it works, but works much slower. Andrew ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-03-06 21:47 ` Andrew Lunn @ 2015-03-06 22:43 ` Scott Feldman 2015-03-07 14:38 ` Jiri Pirko 0 siblings, 1 reply; 22+ messages in thread From: Scott Feldman @ 2015-03-06 22:43 UTC (permalink / raw) To: Andrew Lunn Cc: Florian Fainelli, Jonas Johansson, Netdev, Jonas Johansson, Jiri Pirko On Fri, Mar 6, 2015 at 1:47 PM, Andrew Lunn <andrew@lunn.ch> wrote: > Hi Florian > >> Most Broadcom switches, either SF2 or roboswitch (b53) have a limit of 2 >> trunking groups, without limitations on the number of ports included in >> any of these two groups. > > O.K, so maybe we want the basic resource management in the DSA layer, > not the switch drivers. > >> The larger question is once we start advertising capabilities, where >> does that stop, right? It would probably be simpler for now to e.g: >> allow 2 trunking groups to be configured, and when trying to configure a >> 3rd one, return -ENOSPC and act upon that to either take the software >> slow path (which is probably not possible) or just return a hard error >> condition. > > This is more than a DSA question. It applies to all the hardware > acceleration being discussed at the moment. As you hinted to above, i > suppose we have two different situations: > > 1) We can fall back to a software slow path. > > 2) There is no software fallback, we have to error out, and it would > be nice to have a well defined error code for out of hardware > resources. > > We also should think about how we tell user space we have fallen back > to a slow path. I'm sure users want to know why it works, but works > much slower. For the general hardware acceleration of bonds, my thoughts for switchdev are: (Assume 802.3ad LAG setup for discussion sake, other bonding modes are similar). 1. The driver has access to port membership notification via netevent, so driver knows which ports are in which bonds. This notification is passive; there is no way to signal to user that when port was put in a bond if it was programmed into a device LAG group or not. It's totally up to the driver and device resources to make that decision. 2. The driver can know port active status via netevent as well. If device has the port in a LAG group, then reflect the active status down to device port. Again, a passive notification. 3. CPU-originating egress traffic would be LAGed by bonding (or team) driver. (This is true regardless if the device LAG group was setup or not). 4a. If device LAG group setup, forwarded traffic would be LAG egressed by device (fast path). 4b. If no device LAG group, ingress traffic is sent to CPU (slow path) for bonding (or team) to LAG egress. So software fall-back (4b) is the default case if driver/device can't setup LAG group for forwarding. So the question is: how does user know which bonds are accelerated? So far, we've used the label "external" to mark L2 bridge FDB which are offloaded to the device and "external" to mark L3 routes offloaded to the device. Do we mark bonds as "external" if the LAG path is offloaded to the device? -scott ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-03-06 22:43 ` Scott Feldman @ 2015-03-07 14:38 ` Jiri Pirko 2015-03-07 17:31 ` John Fastabend 0 siblings, 1 reply; 22+ messages in thread From: Jiri Pirko @ 2015-03-07 14:38 UTC (permalink / raw) To: Scott Feldman Cc: Andrew Lunn, Florian Fainelli, Jonas Johansson, Netdev, Jonas Johansson Fri, Mar 06, 2015 at 11:43:55PM CET, sfeldma@gmail.com wrote: >On Fri, Mar 6, 2015 at 1:47 PM, Andrew Lunn <andrew@lunn.ch> wrote: >> Hi Florian >> >>> Most Broadcom switches, either SF2 or roboswitch (b53) have a limit of 2 >>> trunking groups, without limitations on the number of ports included in >>> any of these two groups. >> >> O.K, so maybe we want the basic resource management in the DSA layer, >> not the switch drivers. >> >>> The larger question is once we start advertising capabilities, where >>> does that stop, right? It would probably be simpler for now to e.g: >>> allow 2 trunking groups to be configured, and when trying to configure a >>> 3rd one, return -ENOSPC and act upon that to either take the software >>> slow path (which is probably not possible) or just return a hard error >>> condition. >> >> This is more than a DSA question. It applies to all the hardware >> acceleration being discussed at the moment. As you hinted to above, i >> suppose we have two different situations: >> >> 1) We can fall back to a software slow path. >> >> 2) There is no software fallback, we have to error out, and it would >> be nice to have a well defined error code for out of hardware >> resources. >> >> We also should think about how we tell user space we have fallen back >> to a slow path. I'm sure users want to know why it works, but works >> much slower. > >For the general hardware acceleration of bonds, my thoughts for switchdev are: > >(Assume 802.3ad LAG setup for discussion sake, other bonding modes are similar). > >1. The driver has access to port membership notification via netevent, >so driver knows which ports are in which bonds. This notification is >passive; there is no way to signal to user that when port was put in a >bond if it was programmed into a device LAG group or not. It's >totally up to the driver and device resources to make that decision. Exactly. The fact if another group can be added or not should be decided and handled by driver. The driver then notifies higher layers using switchdev notifier event. > >2. The driver can know port active status via netevent as well. If >device has the port in a LAG group, then reflect the active status >down to device port. Again, a passive notification. > >3. CPU-originating egress traffic would be LAGed by bonding (or team) >driver. (This is true regardless if the device LAG group was setup or >not). > >4a. If device LAG group setup, forwarded traffic would be LAG egressed >by device (fast path). > >4b. If no device LAG group, ingress traffic is sent to CPU (slow path) >for bonding (or team) to LAG egress. > >So software fall-back (4b) is the default case if driver/device can't >setup LAG group for forwarding. > >So the question is: how does user know which bonds are accelerated? >So far, we've used the label "external" to mark L2 bridge FDB which >are offloaded to the device and "external" to mark L3 routes offloaded >to the device. Do we mark bonds as "external" if the LAG path is >offloaded to the device? I believe that this is the way to go. Introduce this flag for bond and team to signal user if LAG is offloaded or not. > >-scott ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking 2015-03-07 14:38 ` Jiri Pirko @ 2015-03-07 17:31 ` John Fastabend 0 siblings, 0 replies; 22+ messages in thread From: John Fastabend @ 2015-03-07 17:31 UTC (permalink / raw) To: Jiri Pirko Cc: Scott Feldman, Andrew Lunn, Florian Fainelli, Jonas Johansson, Netdev, Jonas Johansson On 03/07/2015 06:38 AM, Jiri Pirko wrote: > Fri, Mar 06, 2015 at 11:43:55PM CET, sfeldma@gmail.com wrote: >> On Fri, Mar 6, 2015 at 1:47 PM, Andrew Lunn <andrew@lunn.ch> wrote: >>> Hi Florian >>> >>>> Most Broadcom switches, either SF2 or roboswitch (b53) have a limit of 2 >>>> trunking groups, without limitations on the number of ports included in >>>> any of these two groups. >>> >>> O.K, so maybe we want the basic resource management in the DSA layer, >>> not the switch drivers. >>> >>>> The larger question is once we start advertising capabilities, where >>>> does that stop, right? It would probably be simpler for now to e.g: >>>> allow 2 trunking groups to be configured, and when trying to configure a >>>> 3rd one, return -ENOSPC and act upon that to either take the software >>>> slow path (which is probably not possible) or just return a hard error >>>> condition. >>> >>> This is more than a DSA question. It applies to all the hardware >>> acceleration being discussed at the moment. As you hinted to above, i >>> suppose we have two different situations: >>> >>> 1) We can fall back to a software slow path. >>> >>> 2) There is no software fallback, we have to error out, and it would >>> be nice to have a well defined error code for out of hardware >>> resources. >>> I have a (3) case where we don't ever want to fall back to slow path even if it is possible and (4) we don't ever want to offload the operation even when it is possible. Having to program the device then unwind it from user space seems a bit error prone and ugly. At some point I think we will have to handle these cases its probably fine to get the transparent offload working as a start though. Specifically, talking about LAG I'm not sure of the use case for (4) but in general it is useful. >>> We also should think about how we tell user space we have fallen back >>> to a slow path. I'm sure users want to know why it works, but works >>> much slower. >> >> For the general hardware acceleration of bonds, my thoughts for switchdev are: >> >> (Assume 802.3ad LAG setup for discussion sake, other bonding modes are similar). >> >> 1. The driver has access to port membership notification via netevent, >> so driver knows which ports are in which bonds. This notification is >> passive; there is no way to signal to user that when port was put in a >> bond if it was programmed into a device LAG group or not. It's >> totally up to the driver and device resources to make that decision. > > Exactly. The fact if another group can be added or not should be decided > and handled by driver. The driver then notifies higher layers using > switchdev notifier event. hmm same point I need to be able to know ahead of time if it is going to succeed or fail. I think we can extend this in two ways one add an explicit flag to say 'add this to hardware or fail' or 'never offload this' although for LAG setup this might be challenging because the notification is passive as noted. The other way to do this is to sufficient exposure of the hardware model and resources so software can predict a priori that the LAG setup will be accelerated. I think we need both... My only point here is eventually management of the system is challenging if its entirely a driver decision at least in many cases where we have intelligent agents managing the network. But sure get the simple case working as a start. > >> >> 2. The driver can know port active status via netevent as well. If >> device has the port in a LAG group, then reflect the active status >> down to device port. Again, a passive notification. >> >> 3. CPU-originating egress traffic would be LAGed by bonding (or team) >> driver. (This is true regardless if the device LAG group was setup or >> not). >> >> 4a. If device LAG group setup, forwarded traffic would be LAG egressed >> by device (fast path). >> >> 4b. If no device LAG group, ingress traffic is sent to CPU (slow path) >> for bonding (or team) to LAG egress. >> >> So software fall-back (4b) is the default case if driver/device can't >> setup LAG group for forwarding. >> >> So the question is: how does user know which bonds are accelerated? >> So far, we've used the label "external" to mark L2 bridge FDB which >> are offloaded to the device and "external" to mark L3 routes offloaded >> to the device. Do we mark bonds as "external" if the LAG path is >> offloaded to the device? > > I believe that this is the way to go. Introduce this flag for bond and > team to signal user if LAG is offloaded or not. > > >> >> -scott > -- > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- John Fastabend Intel Corporation ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH net-next 0/2] dsa: implement HW bonding 2015-02-20 10:51 [PATCH net-next 0/2] dsa: implement HW bonding Jonas Johansson 2015-02-20 10:51 ` [PATCH net-next 1/2] dsa: bonding: " Jonas Johansson 2015-02-20 10:51 ` [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking Jonas Johansson @ 2015-02-21 16:40 ` Jiri Pirko 2 siblings, 0 replies; 22+ messages in thread From: Jiri Pirko @ 2015-02-21 16:40 UTC (permalink / raw) To: Jonas Johansson; +Cc: netdev, Jonas Johansson Fri, Feb 20, 2015 at 11:51:11AM CET, jonasj76@gmail.com wrote: >From: Jonas Johansson <jonas.johansson@westermo.se> > >This patchset will implement hardware bonding support for the DSA driver and >the Marvell 88E6095 device. > >Jonas Johansson (2): > dsa: bonding: implement HW bonding > mv88e6131: bonding: implement single device trunking > You should use scripts/get_maintainer.pl script and cc all relevant people... > drivers/net/dsa/mv88e6131.c | 254 ++++++++++++++++++++++++++++++++++++++++++++ > drivers/net/dsa/mv88e6xxx.h | 14 +++ > drivers/net/team/team.c | 4 + > include/linux/netdevice.h | 8 ++ > include/net/dsa.h | 8 ++ > net/dsa/dsa.c | 60 +++++++++++ > net/dsa/dsa_priv.h | 6 ++ > net/dsa/slave.c | 23 ++++ > 8 files changed, 377 insertions(+) > >-- >2.1.0 > >-- >To unsubscribe from this list: send the line "unsubscribe netdev" in >the body of a message to majordomo@vger.kernel.org >More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2015-03-07 17:32 UTC | newest] Thread overview: 22+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-02-20 10:51 [PATCH net-next 0/2] dsa: implement HW bonding Jonas Johansson 2015-02-20 10:51 ` [PATCH net-next 1/2] dsa: bonding: " Jonas Johansson 2015-02-20 15:12 ` Andrew Lunn 2015-02-20 16:19 ` Jonas Johansson 2015-02-20 16:41 ` Florian Fainelli 2015-02-20 17:56 ` roopa 2015-02-20 19:28 ` Jonas Johansson 2015-02-21 16:57 ` Jiri Pirko 2015-02-21 20:43 ` Andrew Lunn 2015-02-21 21:12 ` Scott Feldman 2015-02-23 15:52 ` Jonas Johansson 2015-02-20 10:51 ` [PATCH net-next 2/2] mv88e6131: bonding: implement single device trunking Jonas Johansson 2015-02-20 15:26 ` Andrew Lunn 2015-02-20 15:56 ` Jonas Johansson 2015-03-06 17:06 ` Florian Fainelli 2015-03-06 19:23 ` Andrew Lunn 2015-03-06 20:47 ` Florian Fainelli 2015-03-06 21:47 ` Andrew Lunn 2015-03-06 22:43 ` Scott Feldman 2015-03-07 14:38 ` Jiri Pirko 2015-03-07 17:31 ` John Fastabend 2015-02-21 16:40 ` [PATCH net-next 0/2] dsa: implement HW bonding Jiri Pirko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).