// SPDX-License-Identifier: GPL-2.0 /* Copyright 2011-2014 Autronica Fire and Security AS * * Author(s): * 2011-2014 Arvid Brodin, arvid.brodin@alten.se * This file contains device methods for creating, using and destroying * virtual HSR or PRP devices.
*/
master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); /* netif_stacked_transfer_operstate() cannot be used here since * it doesn't set IF_OPER_LOWERLAYERDOWN (?)
*/
has_carrier = hsr_check_carrier(master);
hsr_set_operstate(master, has_carrier);
hsr_check_announce(master->dev);
}
int hsr_get_max_mtu(struct hsr_priv *hsr)
{ unsignedint mtu_max; struct hsr_port *port;
staticint hsr_dev_change_mtu(struct net_device *dev, int new_mtu)
{ struct hsr_priv *hsr;
hsr = netdev_priv(dev);
if (new_mtu > hsr_get_max_mtu(hsr)) {
netdev_info(dev, "A HSR master's MTU cannot be greater than the smallest MTU of its slaves minus the HSR Tag length (%d octets).\n",
HSR_HLEN); return -EINVAL;
}
hsr_for_each_port_rtnl(hsr, port) { if (port->type == HSR_PT_MASTER) continue; switch (port->type) { case HSR_PT_SLAVE_A:
designation = "Slave A"; break; case HSR_PT_SLAVE_B:
designation = "Slave B"; break; case HSR_PT_INTERLINK:
designation = "Interlink"; break; default:
designation = "Unknown";
} if (!is_slave_up(port->dev))
netdev_warn(dev, "%s (%s) is not up; please bring it up to get a fully working HSR network\n",
designation, port->dev->name);
}
if (!designation)
netdev_warn(dev, "No slave devices configured\n");
/* Mask out all features that, if supported by one device, should be * enabled for all devices (see NETIF_F_ONE_FOR_ALL). * * Anything that's off in mask will not be enabled - so only things * that were in features originally, and also is in NETIF_F_ONE_FOR_ALL, * may become enabled.
*/
features &= ~NETIF_F_ONE_FOR_ALL;
hsr_for_each_port_rtnl(hsr, port)
features = netdev_increment_features(features,
port->dev->features,
mask);
staticstruct sk_buff *hsr_init_skb(struct hsr_port *master, int extra)
{ struct hsr_priv *hsr = master->hsr; struct sk_buff *skb; int hlen, tlen; int len;
hlen = LL_RESERVED_SPACE(master->dev);
tlen = master->dev->needed_tailroom;
len = sizeof(struct hsr_sup_tag) + sizeof(struct hsr_sup_payload); /* skb size is same for PRP/HSR frames, only difference * being, for PRP it is a trailer and for HSR it is a * header. * RedBox might use @extra more bytes.
*/
skb = dev_alloc_skb(len + extra + hlen + tlen);
/* From HSRv1 on we have separate supervision sequence numbers. */
spin_lock_bh(&hsr->seqnr_lock); if (hsr->prot_version > 0) {
hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
hsr->sup_sequence_nr++;
} else {
hsr_stag->sequence_nr = htons(hsr->sequence_nr);
hsr->sequence_nr++;
}
hsr_stag->tlv.HSR_TLV_type = type; /* HSRv0 has 6 unused bytes after the MAC */
hsr_stag->tlv.HSR_TLV_length = hsr->prot_version ? sizeof(struct hsr_sup_payload) : 12;
/* Payload: MacAddressA / SAN MAC from ProxyNodeTable */
hsr_sp = skb_put(skb, sizeof(struct hsr_sup_payload));
ether_addr_copy(hsr_sp->macaddress_A, addr);
/* From HSRv1 on we have separate supervision sequence numbers. */
spin_lock_bh(&hsr->seqnr_lock);
hsr_stag->sequence_nr = htons(hsr->sup_sequence_nr);
hsr->sup_sequence_nr++;
hsr_stag->tlv.HSR_TLV_type = PRP_TLV_LIFE_CHECK_DD;
hsr_stag->tlv.HSR_TLV_length = sizeof(struct hsr_sup_payload);
rcu_read_lock(); /* RedBOX sends supervisory frames to HSR network with MAC addresses * of SAN nodes stored in ProxyNodeTable.
*/
interlink = hsr_port_get_hsr(hsr, HSR_PT_INTERLINK); if (!interlink) goto done;
ret = vlan_vid_add(port->dev, proto, vid); switch (port->type) { case HSR_PT_SLAVE_A: if (ret) { /* clean up Slave-B */
netdev_err(dev, "add vid failed for Slave-A\n"); if (is_slave_b_added)
vlan_vid_del(port->dev, proto, vid); return ret;
}
is_slave_a_added = true; break;
case HSR_PT_SLAVE_B: if (ret) { /* clean up Slave-A */
netdev_err(dev, "add vid failed for Slave-B\n"); if (is_slave_a_added)
vlan_vid_del(port->dev, proto, vid); return ret;
}
/* initialize protocol specific functions */ if (protocol_version == PRP_V1) { /* For PRP, lan_id has most significant 3 bits holding * the net_id of PRP_LAN_ID
*/
hsr->net_id = PRP_LAN_ID << 1;
hsr->proto_ops = &prp_ops;
} else {
hsr->proto_ops = &hsr_ops;
}
/* Make sure we recognize frames from ourselves in hsr_rcv() */
res = hsr_create_self_node(hsr, hsr_dev->dev_addr,
slave[1]->dev_addr); if (res < 0) return res;
if (unregister)
unregister_netdevice(hsr_dev); return res;
}
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.12Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.