net/hsr: Operstate handling cleanup.

Signed-off-by: Arvid Brodin <arvid.brodin@alten.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Arvid Brodin 2014-07-04 23:36:40 +02:00 committed by David S. Miller
parent abff716276
commit e9aae56ea4
3 changed files with 30 additions and 22 deletions

View File

@ -46,31 +46,36 @@ static void __hsr_set_operstate(struct net_device *dev, int transition)
} }
} }
void hsr_set_operstate(struct net_device *hsr_dev, struct net_device *slave1, static void hsr_set_operstate(struct net_device *hsr_dev, bool has_carrier)
struct net_device *slave2)
{ {
if (!is_admin_up(hsr_dev)) { if (!is_admin_up(hsr_dev)) {
__hsr_set_operstate(hsr_dev, IF_OPER_DOWN); __hsr_set_operstate(hsr_dev, IF_OPER_DOWN);
return; return;
} }
if (is_slave_up(slave1) || is_slave_up(slave2)) if (has_carrier)
__hsr_set_operstate(hsr_dev, IF_OPER_UP); __hsr_set_operstate(hsr_dev, IF_OPER_UP);
else else
__hsr_set_operstate(hsr_dev, IF_OPER_LOWERLAYERDOWN); __hsr_set_operstate(hsr_dev, IF_OPER_LOWERLAYERDOWN);
} }
void hsr_set_carrier(struct net_device *hsr_dev, struct net_device *slave1, static bool hsr_check_carrier(struct hsr_priv *hsr)
struct net_device *slave2)
{ {
if (is_slave_up(slave1) || is_slave_up(slave2)) bool has_carrier;
netif_carrier_on(hsr_dev);
has_carrier = (is_slave_up(hsr->slave[0]) || is_slave_up(hsr->slave[1]));
if (has_carrier)
netif_carrier_on(hsr->dev);
else else
netif_carrier_off(hsr_dev); netif_carrier_off(hsr->dev);
return has_carrier;
} }
void hsr_check_announce(struct net_device *hsr_dev, int old_operstate) static void hsr_check_announce(struct net_device *hsr_dev,
unsigned char old_operstate)
{ {
struct hsr_priv *hsr; struct hsr_priv *hsr;
@ -89,6 +94,20 @@ void hsr_check_announce(struct net_device *hsr_dev, int old_operstate)
del_timer(&hsr->announce_timer); del_timer(&hsr->announce_timer);
} }
void hsr_check_carrier_and_operstate(struct hsr_priv *hsr)
{
unsigned char old_operstate;
bool has_carrier;
/* netif_stacked_transfer_operstate() cannot be used here since
* it doesn't set IF_OPER_LOWERLAYERDOWN (?)
*/
old_operstate = hsr->dev->operstate;
has_carrier = hsr_check_carrier(hsr);
hsr_set_operstate(hsr->dev, has_carrier);
hsr_check_announce(hsr->dev, old_operstate);
}
int hsr_get_max_mtu(struct hsr_priv *hsr) int hsr_get_max_mtu(struct hsr_priv *hsr)
{ {

View File

@ -18,11 +18,7 @@
void hsr_dev_setup(struct net_device *dev); void hsr_dev_setup(struct net_device *dev);
int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
unsigned char multicast_spec); unsigned char multicast_spec);
void hsr_set_operstate(struct net_device *hsr_dev, struct net_device *slave1, void hsr_check_carrier_and_operstate(struct hsr_priv *hsr);
struct net_device *slave2);
void hsr_set_carrier(struct net_device *hsr_dev, struct net_device *slave1,
struct net_device *slave2);
void hsr_check_announce(struct net_device *hsr_dev, int old_operstate);
bool is_hsr_master(struct net_device *dev); bool is_hsr_master(struct net_device *dev);
int hsr_get_max_mtu(struct hsr_priv *hsr); int hsr_get_max_mtu(struct hsr_priv *hsr);

View File

@ -91,7 +91,6 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
{ {
struct net_device *slave, *other_slave; struct net_device *slave, *other_slave;
struct hsr_priv *hsr; struct hsr_priv *hsr;
int old_operstate;
int mtu_max; int mtu_max;
int res; int res;
struct net_device *dev; struct net_device *dev;
@ -115,13 +114,7 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
case NETDEV_UP: /* Administrative state DOWN */ case NETDEV_UP: /* Administrative state DOWN */
case NETDEV_DOWN: /* Administrative state UP */ case NETDEV_DOWN: /* Administrative state UP */
case NETDEV_CHANGE: /* Link (carrier) state changes */ case NETDEV_CHANGE: /* Link (carrier) state changes */
old_operstate = hsr->dev->operstate; hsr_check_carrier_and_operstate(hsr);
hsr_set_carrier(hsr->dev, slave, other_slave);
/* netif_stacked_transfer_operstate() cannot be used here since
* it doesn't set IF_OPER_LOWERLAYERDOWN (?)
*/
hsr_set_operstate(hsr->dev, slave, other_slave);
hsr_check_announce(hsr->dev, old_operstate);
break; break;
case NETDEV_CHANGEADDR: case NETDEV_CHANGEADDR: