Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 15552
b: refs/heads/master
c: 4433f42
h: refs/heads/master
v: v3
  • Loading branch information
Stephen Hemminger authored and David S. Miller committed Jan 3, 2006
1 parent e7d900b commit 912484f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4505a3ef720845b5db3ddb440de13cd4800fd508
refs/heads/master: 4433f420e57afae0ab308b1e2b979f09c86bc115
49 changes: 38 additions & 11 deletions trunk/net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@
* ethtool, use ethtool_ops. Also, since driver might sleep need to
* not be holding any locks.
*/
static int br_initial_port_cost(struct net_device *dev)
static int port_cost(struct net_device *dev)
{

struct ethtool_cmd ecmd = { ETHTOOL_GSET };
struct ifreq ifr;
mm_segment_t old_fs;
Expand All @@ -58,10 +57,6 @@ static int br_initial_port_cost(struct net_device *dev)
return 2;
case SPEED_10:
return 100;
default:
pr_info("bridge: can't decode speed from %s: %d\n",
dev->name, ecmd.speed);
return 100;
}
}

Expand All @@ -75,6 +70,35 @@ static int br_initial_port_cost(struct net_device *dev)
return 100; /* assume old 10Mbps */
}


/*
* Check for port carrier transistions.
* Called from work queue to allow for calling functions that
* might sleep (such as speed check), and to debounce.
*/
static void port_carrier_check(void *arg)
{
struct net_bridge_port *p = arg;

rtnl_lock();
if (netif_carrier_ok(p->dev)) {
u32 cost = port_cost(p->dev);

spin_lock_bh(&p->br->lock);
if (p->state == BR_STATE_DISABLED) {
p->path_cost = cost;
br_stp_enable_port(p);
}
spin_unlock_bh(&p->br->lock);
} else {
spin_lock_bh(&p->br->lock);
if (p->state != BR_STATE_DISABLED)
br_stp_disable_port(p);
spin_unlock_bh(&p->br->lock);
}
rtnl_unlock();
}

static void destroy_nbp(struct net_bridge_port *p)
{
struct net_device *dev = p->dev;
Expand Down Expand Up @@ -102,6 +126,9 @@ static void del_nbp(struct net_bridge_port *p)
dev->br_port = NULL;
dev_set_promiscuity(dev, -1);

cancel_delayed_work(&p->carrier_check);
flush_scheduled_work();

spin_lock_bh(&br->lock);
br_stp_disable_port(p);
spin_unlock_bh(&br->lock);
Expand Down Expand Up @@ -195,10 +222,9 @@ static int find_portno(struct net_bridge *br)
return (index >= BR_MAX_PORTS) ? -EXFULL : index;
}

/* called with RTNL */
/* called with RTNL but without bridge lock */
static struct net_bridge_port *new_nbp(struct net_bridge *br,
struct net_device *dev,
unsigned long cost)
struct net_device *dev)
{
int index;
struct net_bridge_port *p;
Expand All @@ -215,12 +241,13 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
p->br = br;
dev_hold(dev);
p->dev = dev;
p->path_cost = cost;
p->path_cost = port_cost(dev);
p->priority = 0x8000 >> BR_PORT_BITS;
dev->br_port = p;
p->port_no = index;
br_init_port(p);
p->state = BR_STATE_DISABLED;
INIT_WORK(&p->carrier_check, port_carrier_check, p);
kobject_init(&p->kobj);

return p;
Expand Down Expand Up @@ -351,7 +378,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
if (dev->br_port != NULL)
return -EBUSY;

if (IS_ERR(p = new_nbp(br, dev, br_initial_port_cost(dev))))
if (IS_ERR(p = new_nbp(br, dev)))
return PTR_ERR(p);

if ((err = br_fdb_insert(br, p, dev->dev_addr)))
Expand Down
14 changes: 3 additions & 11 deletions trunk/net/bridge/br_notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,9 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
br_stp_recalculate_bridge_id(br);
break;

case NETDEV_CHANGE: /* device is up but carrier changed */
if (!(br->dev->flags & IFF_UP))
break;

if (netif_carrier_ok(dev)) {
if (p->state == BR_STATE_DISABLED)
br_stp_enable_port(p);
} else {
if (p->state != BR_STATE_DISABLED)
br_stp_disable_port(p);
}
case NETDEV_CHANGE:
if (br->dev->flags & IFF_UP)
schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
break;

case NETDEV_FEAT_CHANGE:
Expand Down
3 changes: 3 additions & 0 deletions trunk/net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
#define BR_PORT_BITS 10
#define BR_MAX_PORTS (1<<BR_PORT_BITS)

#define BR_PORT_DEBOUNCE (HZ/10)

typedef struct bridge_id bridge_id;
typedef struct mac_addr mac_addr;
typedef __u16 port_id;
Expand Down Expand Up @@ -78,6 +80,7 @@ struct net_bridge_port
struct timer_list hold_timer;
struct timer_list message_age_timer;
struct kobject kobj;
struct work_struct carrier_check;
struct rcu_head rcu;
};

Expand Down

0 comments on commit 912484f

Please sign in to comment.