}
}
-void hsr_set_operstate(struct net_device *hsr_dev, struct net_device *slave1,
- struct net_device *slave2)
+static void hsr_set_operstate(struct net_device *hsr_dev, bool has_carrier)
{
if (!is_admin_up(hsr_dev)) {
__hsr_set_operstate(hsr_dev, IF_OPER_DOWN);
return;
}
- if (is_slave_up(slave1) || is_slave_up(slave2))
+ if (has_carrier)
__hsr_set_operstate(hsr_dev, IF_OPER_UP);
else
__hsr_set_operstate(hsr_dev, IF_OPER_LOWERLAYERDOWN);
}
-void hsr_set_carrier(struct net_device *hsr_dev, struct net_device *slave1,
- struct net_device *slave2)
+static bool hsr_check_carrier(struct hsr_priv *hsr)
{
- if (is_slave_up(slave1) || is_slave_up(slave2))
- netif_carrier_on(hsr_dev);
+ bool has_carrier;
+
+ has_carrier = (is_slave_up(hsr->slave[0]) || is_slave_up(hsr->slave[1]));
+
+ if (has_carrier)
+ netif_carrier_on(hsr->dev);
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;
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)
{
hsr = netdev_priv(hsr_dev);
- del_timer(&hsr->announce_timer);
+ del_timer_sync(&hsr->prune_timer);
+ del_timer_sync(&hsr->announce_timer);
unregister_hsr_master(hsr); /* calls list_del_rcu on hsr */
restore_slaves(hsr_dev);
call_rcu(&hsr->rcu_head, reclaim_hsr_dev); /* reclaim hsr */
hsr->announce_timer.function = hsr_announce;
hsr->announce_timer.data = (unsigned long) hsr;
+ init_timer(&hsr->prune_timer);
+ hsr->prune_timer.function = hsr_prune_nodes;
+ hsr->prune_timer.data = (unsigned long) hsr;
+
ether_addr_copy(hsr->sup_multicast_addr, def_multicast_addr);
hsr->sup_multicast_addr[ETH_ALEN - 1] = multicast_spec;
if (res)
goto fail;
+ hsr->prune_timer.expires = jiffies + msecs_to_jiffies(PRUNE_PERIOD);
+ add_timer(&hsr->prune_timer);
+
register_hsr_master(hsr);
return 0;