int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], unsigned char multicast_spec, u8 protocol_version) { struct hsr_priv *hsr; struct hsr_port *port; int res; hsr = netdev_priv(hsr_dev); INIT_LIST_HEAD(&hsr->ports); INIT_LIST_HEAD(&hsr->node_db); INIT_LIST_HEAD(&hsr->self_node_db); ether_addr_copy(hsr_dev->dev_addr, slave[0]->dev_addr); /* Make sure we recognize frames from ourselves in hsr_rcv() */ res = hsr_create_self_node(&hsr->self_node_db, hsr_dev->dev_addr, slave[1]->dev_addr); if (res < 0) return res; spin_lock_init(&hsr->seqnr_lock); /* Overflow soon to find bugs easier: */ hsr->sequence_nr = HSR_SEQNR_START; hsr->sup_sequence_nr = HSR_SUP_SEQNR_START; init_timer(&hsr->announce_timer); 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; hsr->protVersion = protocol_version; /* FIXME: should I modify the value of these? * * - hsr_dev->flags - i.e. * IFF_MASTER/SLAVE? * - hsr_dev->priv_flags - i.e. * IFF_EBRIDGE? * IFF_TX_SKB_SHARING? * IFF_HSR_MASTER/SLAVE? */ /* Make sure the 1st call to netif_carrier_on() gets through */ netif_carrier_off(hsr_dev); res = hsr_add_port(hsr, hsr_dev, HSR_PT_MASTER); if (res) return res; res = register_netdevice(hsr_dev); if (res) goto fail; res = hsr_add_port(hsr, slave[0], HSR_PT_SLAVE_A); if (res) goto fail; res = hsr_add_port(hsr, slave[1], HSR_PT_SLAVE_B); if (res) goto fail; hsr->prune_timer.expires = jiffies + msecs_to_jiffies(PRUNE_PERIOD); add_timer(&hsr->prune_timer); return 0; fail: hsr_for_each_port(hsr, port) hsr_del_port(port); return res; }
int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2], unsigned char multicast_spec) { struct hsr_priv *hsr_priv; int i; int res; hsr_priv = netdev_priv(hsr_dev); hsr_priv->dev = hsr_dev; INIT_LIST_HEAD(&hsr_priv->node_db); INIT_LIST_HEAD(&hsr_priv->self_node_db); for (i = 0; i < HSR_MAX_SLAVE; i++) hsr_priv->slave[i] = slave[i]; spin_lock_init(&hsr_priv->seqnr_lock); /* Overflow soon to find bugs easier: */ hsr_priv->sequence_nr = USHRT_MAX - 1024; init_timer(&hsr_priv->announce_timer); hsr_priv->announce_timer.function = hsr_announce; hsr_priv->announce_timer.data = (unsigned long) hsr_priv; ether_addr_copy(hsr_priv->sup_multicast_addr, def_multicast_addr); hsr_priv->sup_multicast_addr[ETH_ALEN - 1] = multicast_spec; /* FIXME: should I modify the value of these? * * - hsr_dev->flags - i.e. * IFF_MASTER/SLAVE? * - hsr_dev->priv_flags - i.e. * IFF_EBRIDGE? * IFF_TX_SKB_SHARING? * IFF_HSR_MASTER/SLAVE? */ for (i = 0; i < HSR_MAX_SLAVE; i++) { res = check_slave_ok(slave[i]); if (res) return res; } hsr_dev->features = slave[0]->features & slave[1]->features; /* Prevent recursive tx locking */ hsr_dev->features |= NETIF_F_LLTX; /* VLAN on top of HSR needs testing and probably some work on * hsr_header_create() etc. */ hsr_dev->features |= NETIF_F_VLAN_CHALLENGED; /* Set hsr_dev's MAC address to that of mac_slave1 */ ether_addr_copy(hsr_dev->dev_addr, hsr_priv->slave[0]->dev_addr); /* Set required header length */ for (i = 0; i < HSR_MAX_SLAVE; i++) { if (slave[i]->hard_header_len + HSR_TAGLEN > hsr_dev->hard_header_len) hsr_dev->hard_header_len = slave[i]->hard_header_len + HSR_TAGLEN; } /* MTU */ for (i = 0; i < HSR_MAX_SLAVE; i++) if (slave[i]->mtu - HSR_TAGLEN < hsr_dev->mtu) hsr_dev->mtu = slave[i]->mtu - HSR_TAGLEN; /* Make sure the 1st call to netif_carrier_on() gets through */ netif_carrier_off(hsr_dev); /* Promiscuity */ for (i = 0; i < HSR_MAX_SLAVE; i++) { res = dev_set_promiscuity(slave[i], 1); if (res) { netdev_info(hsr_dev, "Cannot set slave promiscuity (%s, %d)\n", slave[i]->name, res); goto fail; } } /* Make sure we recognize frames from ourselves in hsr_rcv() */ res = hsr_create_self_node(&hsr_priv->self_node_db, hsr_dev->dev_addr, hsr_priv->slave[1]->dev_addr); if (res < 0) goto fail; res = register_netdevice(hsr_dev); if (res) goto fail; register_hsr_master(hsr_priv); return 0; fail: restore_slaves(hsr_dev); return res; }