net: dsa: move bridging routines

Move the DSA port code which bridges a port in port.c, where it belongs.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vivien Didelot 2017-05-19 17:00:45 -04:00 committed by David S. Miller
parent a40c175b4a
commit cfbed329be
3 changed files with 60 additions and 57 deletions

View File

@ -64,6 +64,8 @@ void dsa_legacy_unregister(void);
int dsa_port_set_state(struct dsa_port *dp, u8 state, int dsa_port_set_state(struct dsa_port *dp, u8 state,
struct switchdev_trans *trans); struct switchdev_trans *trans);
void dsa_port_set_state_now(struct dsa_port *dp, u8 state); void dsa_port_set_state_now(struct dsa_port *dp, u8 state);
int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br);
void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br);
/* slave.c */ /* slave.c */
extern const struct dsa_device_ops notag_netdev_ops; extern const struct dsa_device_ops notag_netdev_ops;

View File

@ -11,9 +11,20 @@
*/ */
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
#include <linux/notifier.h>
#include "dsa_priv.h" #include "dsa_priv.h"
static int dsa_port_notify(struct dsa_port *dp, unsigned long e, void *v)
{
struct raw_notifier_head *nh = &dp->ds->dst->nh;
int err;
err = raw_notifier_call_chain(nh, e, v);
return notifier_to_errno(err);
}
int dsa_port_set_state(struct dsa_port *dp, u8 state, int dsa_port_set_state(struct dsa_port *dp, u8 state,
struct switchdev_trans *trans) struct switchdev_trans *trans)
{ {
@ -53,3 +64,50 @@ void dsa_port_set_state_now(struct dsa_port *dp, u8 state)
if (err) if (err)
pr_err("DSA: failed to set STP state %u (%d)\n", state, err); pr_err("DSA: failed to set STP state %u (%d)\n", state, err);
} }
int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br)
{
struct dsa_notifier_bridge_info info = {
.sw_index = dp->ds->index,
.port = dp->index,
.br = br,
};
int err;
/* Here the port is already bridged. Reflect the current configuration
* so that drivers can program their chips accordingly.
*/
dp->bridge_dev = br;
err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_JOIN, &info);
/* The bridging is rolled back on error */
if (err)
dp->bridge_dev = NULL;
return err;
}
void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
{
struct dsa_notifier_bridge_info info = {
.sw_index = dp->ds->index,
.port = dp->index,
.br = br,
};
int err;
/* Here the port is already unbridged. Reflect the current configuration
* so that drivers can program their chips accordingly.
*/
dp->bridge_dev = NULL;
err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_LEAVE, &info);
if (err)
pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
* so allow it to be in BR_STATE_FORWARDING to be kept functional
*/
dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
}

View File

@ -27,16 +27,6 @@
static bool dsa_slave_dev_check(struct net_device *dev); static bool dsa_slave_dev_check(struct net_device *dev);
static int dsa_port_notify(struct dsa_port *dp, unsigned long e, void *v)
{
struct raw_notifier_head *nh = &dp->ds->dst->nh;
int err;
err = raw_notifier_call_chain(nh, e, v);
return notifier_to_errno(err);
}
/* slave mii_bus handling ***************************************************/ /* slave mii_bus handling ***************************************************/
static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg) static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
{ {
@ -514,53 +504,6 @@ static int dsa_slave_port_obj_dump(struct net_device *dev,
return err; return err;
} }
static int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br)
{
struct dsa_notifier_bridge_info info = {
.sw_index = dp->ds->index,
.port = dp->index,
.br = br,
};
int err;
/* Here the port is already bridged. Reflect the current configuration
* so that drivers can program their chips accordingly.
*/
dp->bridge_dev = br;
err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_JOIN, &info);
/* The bridging is rolled back on error */
if (err)
dp->bridge_dev = NULL;
return err;
}
static void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
{
struct dsa_notifier_bridge_info info = {
.sw_index = dp->ds->index,
.port = dp->index,
.br = br,
};
int err;
/* Here the port is already unbridged. Reflect the current configuration
* so that drivers can program their chips accordingly.
*/
dp->bridge_dev = NULL;
err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_LEAVE, &info);
if (err)
pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
* so allow it to be in BR_STATE_FORWARDING to be kept functional
*/
dsa_port_set_state_now(dp, BR_STATE_FORWARDING);
}
static int dsa_slave_port_attr_get(struct net_device *dev, static int dsa_slave_port_attr_get(struct net_device *dev,
struct switchdev_attr *attr) struct switchdev_attr *attr)
{ {