net: ethernet: l2: Add support for VLAN tag strip
If ethernet controller has VLAN tag strip flag enabled (ETHERNET_HW_VLAN_TAG_STRIP), L2 etherent will not read tag from the Rx etherent header. Instead it will fetch VLAN tag from net packet metadata. Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
This commit is contained in:
parent
08d24e428e
commit
49cb24a5eb
1 changed files with 29 additions and 13 deletions
|
@ -68,7 +68,7 @@ void net_eth_ipv6_mcast_to_mac_addr(const struct in6_addr *ipv6_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NET_VLAN
|
#ifdef CONFIG_NET_VLAN
|
||||||
#define print_vlan_ll_addrs(pkt, type, tci, len, src, dst) \
|
#define print_vlan_ll_addrs(pkt, type, tci, len, src, dst, tagstrip) \
|
||||||
if (CONFIG_NET_L2_ETHERNET_LOG_LEVEL >= LOG_LEVEL_DBG) { \
|
if (CONFIG_NET_L2_ETHERNET_LOG_LEVEL >= LOG_LEVEL_DBG) { \
|
||||||
char out[sizeof("xx:xx:xx:xx:xx:xx")]; \
|
char out[sizeof("xx:xx:xx:xx:xx:xx")]; \
|
||||||
\
|
\
|
||||||
|
@ -76,12 +76,13 @@ void net_eth_ipv6_mcast_to_mac_addr(const struct in6_addr *ipv6_addr,
|
||||||
net_sprint_ll_addr((src)->addr, \
|
net_sprint_ll_addr((src)->addr, \
|
||||||
sizeof(struct net_eth_addr))); \
|
sizeof(struct net_eth_addr))); \
|
||||||
\
|
\
|
||||||
NET_DBG("iface %p src %s dst %s type 0x%x tag %d pri %d " \
|
NET_DBG("iface %p src %s dst %s type 0x%x " \
|
||||||
"len %zu", \
|
"tag %d %spri %d len %zu", \
|
||||||
net_pkt_iface(pkt), log_strdup(out), \
|
net_pkt_iface(pkt), log_strdup(out), \
|
||||||
log_strdup(net_sprint_ll_addr((dst)->addr, \
|
log_strdup(net_sprint_ll_addr((dst)->addr, \
|
||||||
sizeof(struct net_eth_addr))), \
|
sizeof(struct net_eth_addr))), \
|
||||||
type, net_eth_vlan_get_vid(tci), \
|
type, net_eth_vlan_get_vid(tci), \
|
||||||
|
tagstrip ? "(stripped) " : "", \
|
||||||
net_eth_vlan_get_pcp(tci), (size_t)len); \
|
net_eth_vlan_get_pcp(tci), (size_t)len); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -136,6 +137,14 @@ static void ethernet_update_rx_stats(struct net_if *iface,
|
||||||
#endif /* CONFIG_NET_STATISTICS_ETHERNET */
|
#endif /* CONFIG_NET_STATISTICS_ETHERNET */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool eth_is_vlan_tag_stripped(struct net_if *iface)
|
||||||
|
{
|
||||||
|
struct device *dev = net_if_get_device(iface);
|
||||||
|
const struct ethernet_api *api = dev->driver_api;
|
||||||
|
|
||||||
|
return (api->get_capabilities(dev) & ETHERNET_HW_VLAN_TAG_STRIP);
|
||||||
|
}
|
||||||
|
|
||||||
static enum net_verdict ethernet_recv(struct net_if *iface,
|
static enum net_verdict ethernet_recv(struct net_if *iface,
|
||||||
struct net_pkt *pkt)
|
struct net_pkt *pkt)
|
||||||
{
|
{
|
||||||
|
@ -147,7 +156,8 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
|
||||||
sa_family_t family;
|
sa_family_t family;
|
||||||
|
|
||||||
if (net_eth_is_vlan_enabled(ctx, iface) &&
|
if (net_eth_is_vlan_enabled(ctx, iface) &&
|
||||||
type == NET_ETH_PTYPE_VLAN) {
|
type == NET_ETH_PTYPE_VLAN &&
|
||||||
|
!eth_is_vlan_tag_stripped(iface)) {
|
||||||
struct net_eth_vlan_hdr *hdr_vlan =
|
struct net_eth_vlan_hdr *hdr_vlan =
|
||||||
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
|
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
|
||||||
|
|
||||||
|
@ -196,13 +206,19 @@ static enum net_verdict ethernet_recv(struct net_if *iface,
|
||||||
lladdr->type = NET_LINK_ETHERNET;
|
lladdr->type = NET_LINK_ETHERNET;
|
||||||
|
|
||||||
if (net_eth_is_vlan_enabled(ctx, iface)) {
|
if (net_eth_is_vlan_enabled(ctx, iface)) {
|
||||||
struct net_eth_vlan_hdr *hdr_vlan __unused =
|
if (type == NET_ETH_PTYPE_VLAN ||
|
||||||
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
|
(eth_is_vlan_tag_stripped(iface) &&
|
||||||
|
net_pkt_vlan_tci(pkt))) {
|
||||||
print_vlan_ll_addrs(pkt, type, ntohs(hdr_vlan->vlan.tci),
|
print_vlan_ll_addrs(pkt, type, net_pkt_vlan_tci(pkt),
|
||||||
net_pkt_get_len(pkt),
|
net_pkt_get_len(pkt),
|
||||||
net_pkt_lladdr_src(pkt),
|
net_pkt_lladdr_src(pkt),
|
||||||
net_pkt_lladdr_dst(pkt));
|
net_pkt_lladdr_dst(pkt),
|
||||||
|
eth_is_vlan_tag_stripped(iface));
|
||||||
|
} else {
|
||||||
|
print_ll_addrs(pkt, type, net_pkt_get_len(pkt),
|
||||||
|
net_pkt_lladdr_src(pkt),
|
||||||
|
net_pkt_lladdr_dst(pkt));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
print_ll_addrs(pkt, type, net_pkt_get_len(pkt),
|
print_ll_addrs(pkt, type, net_pkt_get_len(pkt),
|
||||||
net_pkt_lladdr_src(pkt),
|
net_pkt_lladdr_src(pkt),
|
||||||
|
@ -452,7 +468,7 @@ static struct net_buf *ethernet_fill_header(struct ethernet_context *ctx,
|
||||||
print_vlan_ll_addrs(pkt, ntohs(hdr_vlan->type),
|
print_vlan_ll_addrs(pkt, ntohs(hdr_vlan->type),
|
||||||
net_pkt_vlan_tci(pkt),
|
net_pkt_vlan_tci(pkt),
|
||||||
hdr_frag->len,
|
hdr_frag->len,
|
||||||
&hdr_vlan->src, &hdr_vlan->dst);
|
&hdr_vlan->src, &hdr_vlan->dst, false);
|
||||||
} else {
|
} else {
|
||||||
hdr = (struct net_eth_hdr *)(hdr_frag->data);
|
hdr = (struct net_eth_hdr *)(hdr_frag->data);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue