static void hsr_fill_tag(struct hsr_ethhdr *hsr_ethhdr, struct hsr_priv *hsr_priv) { unsigned long irqflags; /* IEC 62439-1:2010, p 48, says the 4-bit "path" field can take values * between 0001-1001 ("ring identifier", for regular HSR frames), * or 1111 ("HSR management", supervision frames). Unfortunately, the * spec writers forgot to explain what a "ring identifier" is, or * how it is used. So we just set this to 0001 for regular frames, * and 1111 for supervision frames. */ set_hsr_tag_path(&hsr_ethhdr->hsr_tag, 0x1); /* IEC 62439-1:2010, p 12: "The link service data unit in an Ethernet * frame is the content of the frame located between the Length/Type * field and the Frame Check Sequence." * * IEC 62439-3, p 48, specifies the "original LPDU" to include the * original "LT" field (what "LT" means is not explained anywhere as * far as I can see - perhaps "Length/Type"?). So LSDU_size might * equal original length + 2. * Also, the fact that this field is not used anywhere (might be used * by a RedBox connecting HSR and PRP nets?) means I cannot test its * correctness. Instead of guessing, I set this to 0 here, to make any * problems immediately apparent. Anyone using this driver with PRP/HSR * RedBoxes might need to fix this... */ set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, 0); spin_lock_irqsave(&hsr_priv->seqnr_lock, irqflags); hsr_ethhdr->hsr_tag.sequence_nr = htons(hsr_priv->sequence_nr); hsr_priv->sequence_nr++; spin_unlock_irqrestore(&hsr_priv->seqnr_lock, irqflags); hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto; hsr_ethhdr->ethhdr.h_proto = htons(ETH_P_PRP); }
static void send_hsr_supervision_frame(struct hsr_port *master, u8 type, u8 hsrVer) { struct sk_buff *skb; int hlen, tlen; struct hsr_tag *hsr_tag; struct hsr_sup_tag *hsr_stag; struct hsr_sup_payload *hsr_sp; unsigned long irqflags; hlen = LL_RESERVED_SPACE(master->dev); tlen = master->dev->needed_tailroom; skb = dev_alloc_skb( sizeof(struct hsr_tag) + sizeof(struct hsr_sup_tag) + sizeof(struct hsr_sup_payload) + hlen + tlen); if (skb == NULL) return; skb_reserve(skb, hlen); skb->dev = master->dev; skb->protocol = htons(hsrVer ? ETH_P_HSR : ETH_P_PRP); skb->priority = TC_PRIO_CONTROL; if (dev_hard_header(skb, skb->dev, (hsrVer ? ETH_P_HSR : ETH_P_PRP), master->hsr->sup_multicast_addr, skb->dev->dev_addr, skb->len) <= 0) goto out; skb_reset_mac_header(skb); if (hsrVer > 0) { hsr_tag = (typeof(hsr_tag)) skb_put(skb, sizeof(struct hsr_tag)); hsr_tag->encap_proto = htons(ETH_P_PRP); set_hsr_tag_LSDU_size(hsr_tag, HSR_V1_SUP_LSDUSIZE); } hsr_stag = (typeof(hsr_stag)) skb_put(skb, sizeof(struct hsr_sup_tag)); set_hsr_stag_path(hsr_stag, (hsrVer ? 0x0 : 0xf)); set_hsr_stag_HSR_Ver(hsr_stag, hsrVer); /* From HSRv1 on we have separate supervision sequence numbers. */ spin_lock_irqsave(&master->hsr->seqnr_lock, irqflags); if (hsrVer > 0) { hsr_stag->sequence_nr = htons(master->hsr->sup_sequence_nr); hsr_tag->sequence_nr = htons(master->hsr->sequence_nr); master->hsr->sup_sequence_nr++; master->hsr->sequence_nr++; } else { hsr_stag->sequence_nr = htons(master->hsr->sequence_nr); master->hsr->sequence_nr++; } spin_unlock_irqrestore(&master->hsr->seqnr_lock, irqflags); hsr_stag->HSR_TLV_Type = type; /* TODO: Why 12 in HSRv0? */ hsr_stag->HSR_TLV_Length = hsrVer ? sizeof(struct hsr_sup_payload) : 12; /* Payload: MacAddressA */ hsr_sp = (typeof(hsr_sp)) skb_put(skb, sizeof(struct hsr_sup_payload)); ether_addr_copy(hsr_sp->MacAddressA, master->dev->dev_addr); skb_put_padto(skb, ETH_ZLEN + HSR_HLEN); hsr_forward_skb(skb, master); return; out: WARN_ONCE(1, "HSR: Could not send supervision frame\n"); kfree_skb(skb); }