aboutsummaryrefslogtreecommitdiffstats
path: root/net/hsr/hsr_forward.c
diff options
context:
space:
mode:
authorGeorge McCollister <george.mccollister@gmail.com>2021-02-09 19:02:10 -0600
committerDavid S. Miller <davem@davemloft.net>2021-02-11 13:24:44 -0800
commit78be9217c4014cebac4d549cc2db1f2886d5a8fb (patch)
tree968ff404a23219e4345511bcdf2e9c19a9244a11 /net/hsr/hsr_forward.c
parentnet: dsa: xrs700x: use of_match_ptr() on xrs700x_mdio_dt_ids (diff)
downloadlinux-dev-78be9217c4014cebac4d549cc2db1f2886d5a8fb.tar.xz
linux-dev-78be9217c4014cebac4d549cc2db1f2886d5a8fb.zip
net: hsr: generate supervision frame without HSR/PRP tag
For a switch to offload insertion of HSR/PRP tags, frames must not be sent to the CPU facing switch port with a tag. Generate supervision frames (eth type ETH_P_PRP) without HSR v1 (ETH_P_HSR)/PRP tag and rely on create_tagged_frame which inserts it later. This will allow skipping the tag insertion for all outgoing frames in the future which is required for HSR v1/PRP tag insertions to be offloaded. HSR v0 supervision frames always contain tag information so insertion of the tag can't be offloaded. IEC 62439-3 Ed.2.0 (HSR v1) specifically notes that this was changed since v0 to allow offloading. Signed-off-by: George McCollister <george.mccollister@gmail.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Tested-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/hsr/hsr_forward.c')
-rw-r--r--net/hsr/hsr_forward.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
index cadfccd7876e..d32cd87d5c5b 100644
--- a/net/hsr/hsr_forward.c
+++ b/net/hsr/hsr_forward.c
@@ -186,6 +186,7 @@ static struct sk_buff *prp_fill_rct(struct sk_buff *skb,
set_prp_LSDU_size(trailer, lsdu_size);
trailer->sequence_nr = htons(frame->sequence_nr);
trailer->PRP_suffix = htons(ETH_P_PRP);
+ skb->protocol = eth_hdr(skb)->h_proto;
return skb;
}
@@ -226,6 +227,7 @@ static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;
hsr_ethhdr->ethhdr.h_proto = htons(proto_version ?
ETH_P_HSR : ETH_P_PRP);
+ skb->protocol = hsr_ethhdr->ethhdr.h_proto;
return skb;
}
@@ -454,7 +456,11 @@ static void handle_std_frame(struct sk_buff *skb,
void hsr_fill_frame_info(__be16 proto, struct sk_buff *skb,
struct hsr_frame_info *frame)
{
- if (proto == htons(ETH_P_PRP) ||
+ struct hsr_port *port = frame->port_rcv;
+ struct hsr_priv *hsr = port->hsr;
+
+ /* HSRv0 supervisory frames double as a tag so treat them as tagged. */
+ if ((!hsr->prot_version && proto == htons(ETH_P_PRP)) ||
proto == htons(ETH_P_HSR)) {
/* HSR tagged frame :- Data or Supervision */
frame->skb_std = NULL;