net: hsr: Add VLAN support

Add support for creating VLAN interfaces over HSR/PRP interface.

Signed-off-by: WingMan Kwok <w-kwok2@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://patch.msgid.link/20241106091710.3308519-2-danishanwar@ti.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
WingMan Kwok 2024-11-06 14:47:07 +05:30 committed by Jakub Kicinski
parent 23462e036e
commit d977d7eb09
2 changed files with 14 additions and 10 deletions

View File

@ -572,11 +572,6 @@ void hsr_dev_setup(struct net_device *dev)
NETIF_F_HW_VLAN_CTAG_TX; NETIF_F_HW_VLAN_CTAG_TX;
dev->features = dev->hw_features; dev->features = dev->hw_features;
/* VLAN on top of HSR needs testing and probably some work on
* hsr_header_create() etc.
*/
dev->features |= NETIF_F_VLAN_CHALLENGED;
} }
/* Return true if dev is a HSR master; return false otherwise. /* Return true if dev is a HSR master; return false otherwise.

View File

@ -280,6 +280,7 @@ static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
struct hsr_port *port, u8 proto_version) struct hsr_port *port, u8 proto_version)
{ {
struct hsr_ethhdr *hsr_ethhdr; struct hsr_ethhdr *hsr_ethhdr;
unsigned char *pc;
int lsdu_size; int lsdu_size;
/* pad to minimum packet size which is 60 + 6 (HSR tag) */ /* pad to minimum packet size which is 60 + 6 (HSR tag) */
@ -290,7 +291,18 @@ static struct sk_buff *hsr_fill_tag(struct sk_buff *skb,
if (frame->is_vlan) if (frame->is_vlan)
lsdu_size -= 4; lsdu_size -= 4;
hsr_ethhdr = (struct hsr_ethhdr *)skb_mac_header(skb); pc = skb_mac_header(skb);
if (frame->is_vlan)
/* This 4-byte shift (size of a vlan tag) does not
* mean that the ethhdr starts there. But rather it
* provides the proper environment for accessing
* the fields, such as hsr_tag etc., just like
* when the vlan tag is not there. This is because
* the hsr tag is after the vlan tag.
*/
hsr_ethhdr = (struct hsr_ethhdr *)(pc + VLAN_HLEN);
else
hsr_ethhdr = (struct hsr_ethhdr *)pc;
hsr_set_path_id(hsr_ethhdr, port); hsr_set_path_id(hsr_ethhdr, port);
set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size); set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, lsdu_size);
@ -368,7 +380,7 @@ struct sk_buff *prp_create_tagged_frame(struct hsr_frame_info *frame,
return skb_clone(frame->skb_std, GFP_ATOMIC); return skb_clone(frame->skb_std, GFP_ATOMIC);
} }
skb = skb_copy_expand(frame->skb_std, 0, skb = skb_copy_expand(frame->skb_std, skb_headroom(frame->skb_std),
skb_tailroom(frame->skb_std) + HSR_HLEN, skb_tailroom(frame->skb_std) + HSR_HLEN,
GFP_ATOMIC); GFP_ATOMIC);
return prp_fill_rct(skb, frame, port); return prp_fill_rct(skb, frame, port);
@ -690,9 +702,6 @@ static int fill_frame_info(struct hsr_frame_info *frame,
if (frame->is_vlan) { if (frame->is_vlan) {
vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr; vlan_hdr = (struct hsr_vlan_ethhdr *)ethhdr;
proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto;
/* FIXME: */
netdev_warn_once(skb->dev, "VLAN not yet supported");
return -EINVAL;
} }
frame->is_from_san = false; frame->is_from_san = false;