Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VLAN overhaul #70345

Merged
merged 33 commits into from Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4454669
net: ethernet: VLAN overhaul and refactoring
jukkar Mar 17, 2024
7d7b78e
tests: net: vlan: Update because of VLAN changes
jukkar Mar 19, 2024
90490b5
net: if: Remove VLAN count checks
jukkar Mar 17, 2024
f912cdf
net: if: Enhance debug prints when adding IP address to iface
jukkar Mar 18, 2024
707e651
net: if: Start IPv6 DAD when interface comes up
jukkar Mar 18, 2024
1f22d2b
net: if: Add debug print when interface is taken up
jukkar Mar 18, 2024
27458c7
net: if: Join all unjoined solicited node multicast groups
jukkar Mar 18, 2024
c59654e
net: if: We can only rejoin mcast groups for native IP stack
jukkar Mar 19, 2024
2511d7c
net: virtual: Force LAA bit for link address
jukkar Mar 18, 2024
4e0f882
net: virtual: Do not try to send data if interface is down
jukkar Mar 27, 2024
5c657e2
net: shell: Refactor VLAN configuration prints
jukkar Mar 17, 2024
c1c230b
net: shell: Print VLAN name instead of interface type
jukkar Mar 18, 2024
361c4fd
net: shell: Print multicast join status for iface cmd
jukkar Mar 18, 2024
b97a4e8
net: ethernet: Enhance debug prints by printing ifindex
jukkar Mar 18, 2024
f99ea81
net: arp: Enhance debug prints by printing interface index
jukkar Mar 19, 2024
2a4b2c7
drivers: eth: native_sim: Remove VLAN handling
jukkar Mar 18, 2024
1dda3c1
drivers: ethernet: stm32: Remove VLAN code as it is no longer needed
jukkar Mar 19, 2024
6945507
drivers: ethernet: sam_gmac: Remove VLAN code as it is no longer needed
jukkar Mar 19, 2024
4db459b
drivers: ethernet: enc28j60: Remove VLAN code as it is no longer needed
jukkar Mar 19, 2024
d90a64b
drivers: ethernet: mcux: Remove VLAN code as it is no longer needed
jukkar Mar 19, 2024
17d26e1
drivers: ethernet: nxp_s32_gmac: Remove VLAN code as it is no longer …
jukkar Mar 19, 2024
b231947
drivers: ethernet: nxp_enet: Remove VLAN code as it is no longer needed
jukkar Mar 19, 2024
607fd2e
drivers: ethernet: xmc4xxx: Remove VLAN code as it is no longer needed
jukkar Mar 19, 2024
ab4228a
drivers: ethernet: e1000: Remove VLAN code as it is no longer needed
jukkar Mar 19, 2024
1d2eb7a
drivers: ethernet: nxp_s32_netc: Remove VLAN code as it is no longer …
jukkar Mar 19, 2024
d890b9a
samples: net: echo_server: Rework the VLAN support
jukkar Mar 17, 2024
66d0c68
samples: net: vlan: Use proper VLAN interface
jukkar Mar 26, 2024
16f2249
samples: net: echo-client: Fix the VLAN support
jukkar Mar 26, 2024
d82fced
samples: net: txtime: Fix the VLAN support
jukkar Mar 26, 2024
165d14a
samples: net: mdns_responder: Fix the VLAN support
jukkar Mar 26, 2024
97bc3a0
samples: net: lldp: Fix the VLAN support
jukkar Mar 27, 2024
050676c
net: gptp: Remove VLAN support
jukkar Mar 26, 2024
d756604
doc: migration-guide-3.7: Add Virtual LAN (VLAN) information
jukkar Mar 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/releases/migration-guide-3.7.rst
Expand Up @@ -194,6 +194,12 @@ Networking
used to read the inner IPv4/IPv6 packets in an IP tunnel. This incoming tunnel read is now
implemented in `recv` callback. (:github:`70549`)

* Virtual LAN (VLAN) implementation is changed to use the Virtual network interfaces.
There are no API changes, but the type of a VLAN network interface is changed from `ETHERNET`
to `VIRTUAL`. This could require changes to the code that sets the VLAN tags to a network
interface. For example in the `net_eth_is_vlan_enabled()` API, the 2nd interface parameter
must point to the main Ethernet interface, and not to the VLAN interface. (:github:`70345`)

* Modified the ``wifi connect`` command to use key-value format for the arguments. In the
previous implementation, we were identifying an option using its position in the argument string.
This made it difficult to deal with optional arguments or extending the support
Expand Down
46 changes: 3 additions & 43 deletions drivers/ethernet/eth_e1000.c
Expand Up @@ -68,22 +68,9 @@ static const char *e1000_reg_to_string(enum e1000_reg_t r)
return NULL;
}

static struct net_if *get_iface(struct e1000_dev *ctx, uint16_t vlan_tag)
static struct net_if *get_iface(struct e1000_dev *ctx)
{
#if defined(CONFIG_NET_VLAN)
struct net_if *iface;

iface = net_eth_get_vlan_iface(ctx->iface, vlan_tag);
if (!iface) {
return ctx->iface;
}

return iface;
#else
ARG_UNUSED(vlan_tag);

return ctx->iface;
#endif
}

static enum ethernet_hw_caps e1000_caps(const struct device *dev)
Expand Down Expand Up @@ -187,7 +174,6 @@ static void e1000_isr(const struct device *ddev)
{
struct e1000_dev *dev = ddev->data;
uint32_t icr = ior32(dev, ICR); /* Cleared upon read */
uint16_t vlan_tag = NET_VLAN_TAG_UNSPEC;

icr &= ~(ICR_TXDW | ICR_TXQE);

Expand All @@ -197,31 +183,9 @@ static void e1000_isr(const struct device *ddev)
icr &= ~ICR_RXO;

if (pkt) {
#if defined(CONFIG_NET_VLAN)
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);

if (ntohs(hdr->type) == NET_ETH_PTYPE_VLAN) {
struct net_eth_vlan_hdr *hdr_vlan =
(struct net_eth_vlan_hdr *)
NET_ETH_HDR(pkt);

net_pkt_set_vlan_tci(
pkt, ntohs(hdr_vlan->vlan.tci));
vlan_tag = net_pkt_vlan_tag(pkt);

#if CONFIG_NET_TC_RX_COUNT > 1
enum net_priority prio;

prio = net_vlan2priority(
net_pkt_vlan_priority(pkt));
net_pkt_set_priority(pkt, prio);
#endif
}
#endif /* CONFIG_NET_VLAN */

net_recv_data(get_iface(dev, vlan_tag), pkt);
net_recv_data(get_iface(dev), pkt);
} else {
eth_stats_update_errors_rx(get_iface(dev, vlan_tag));
eth_stats_update_errors_rx(get_iface(dev));
}
}

Expand Down Expand Up @@ -291,10 +255,6 @@ static void e1000_iface_init(struct net_if *iface)
struct e1000_dev *dev = net_if_get_device(iface)->data;
const struct e1000_config *config = net_if_get_device(iface)->config;

/* For VLAN, this value is only used to get the correct L2 driver.
* The iface pointer in device context should contain the main
* interface if the VLANs are enabled.
*/
if (dev->iface == NULL) {
dev->iface = iface;

Expand Down
55 changes: 7 additions & 48 deletions drivers/ethernet/eth_enc28j60.c
Expand Up @@ -457,23 +457,9 @@ static void eth_enc28j60_init_phy(const struct device *dev)
}
}

static struct net_if *get_iface(struct eth_enc28j60_runtime *ctx,
uint16_t vlan_tag)
static struct net_if *get_iface(struct eth_enc28j60_runtime *ctx)
{
#if defined(CONFIG_NET_VLAN)
struct net_if *iface;

iface = net_eth_get_vlan_iface(ctx->iface, vlan_tag);
if (!iface) {
return ctx->iface;
}

return iface;
#else
ARG_UNUSED(vlan_tag);

return ctx->iface;
#endif
}

static int eth_enc28j60_tx(const struct device *dev, struct net_pkt *pkt)
Expand Down Expand Up @@ -549,8 +535,7 @@ static int eth_enc28j60_tx(const struct device *dev, struct net_pkt *pkt)
return 0;
}

static void enc28j60_read_packet(const struct device *dev, uint16_t *vlan_tag,
uint16_t frm_len)
static void enc28j60_read_packet(const struct device *dev, uint16_t frm_len)
{
const struct eth_enc28j60_config *config = dev->config;
struct eth_enc28j60_runtime *context = dev->data;
Expand All @@ -560,11 +545,11 @@ static void enc28j60_read_packet(const struct device *dev, uint16_t *vlan_tag,
uint8_t dummy[4];

/* Get the frame from the buffer */
pkt = net_pkt_rx_alloc_with_buffer(get_iface(context, *vlan_tag), frm_len,
pkt = net_pkt_rx_alloc_with_buffer(get_iface(context), frm_len,
AF_UNSPEC, 0, K_MSEC(config->timeout));
if (!pkt) {
LOG_ERR("%s: Could not allocate rx buffer", dev->name);
eth_stats_update_errors_rx(get_iface(context, *vlan_tag));
eth_stats_update_errors_rx(get_iface(context));
return;
}

Expand Down Expand Up @@ -606,28 +591,7 @@ static void enc28j60_read_packet(const struct device *dev, uint16_t *vlan_tag,
eth_enc28j60_read_mem(dev, dummy, 1);
}

#if defined(CONFIG_NET_VLAN)
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);

if (ntohs(hdr->type) == NET_ETH_PTYPE_VLAN) {
struct net_eth_vlan_hdr *hdr_vlan =
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);

net_pkt_set_vlan_tci(pkt, ntohs(hdr_vlan->vlan.tci));
*vlan_tag = net_pkt_vlan_tag(pkt);

#if CONFIG_NET_TC_RX_COUNT > 1
enum net_priority prio;

prio = net_vlan2priority(net_pkt_vlan_priority(pkt));
net_pkt_set_priority(pkt, prio);
#endif
} else {
net_pkt_set_iface(pkt, context->iface);
}
#else /* CONFIG_NET_VLAN */
net_pkt_set_iface(pkt, context->iface);
#endif /* CONFIG_NET_VLAN */

/* Feed buffer frame to IP stack */
LOG_DBG("%s: Received packet of length %u", dev->name, lengthfr);
Expand All @@ -636,7 +600,7 @@ static void enc28j60_read_packet(const struct device *dev, uint16_t *vlan_tag,
}
}

static int eth_enc28j60_rx(const struct device *dev, uint16_t *vlan_tag)
static int eth_enc28j60_rx(const struct device *dev)
{
struct eth_enc28j60_runtime *context = dev->data;
uint8_t counter;
Expand Down Expand Up @@ -688,7 +652,7 @@ static int eth_enc28j60_rx(const struct device *dev, uint16_t *vlan_tag)
*/
frm_len = sys_get_le16(info) - 4;

enc28j60_read_packet(dev, vlan_tag, frm_len);
enc28j60_read_packet(dev, frm_len);

/* Free buffer memory and decrement rx counter */
eth_enc28j60_set_bank(dev, ENC28J60_REG_ERXRDPTL);
Expand Down Expand Up @@ -716,15 +680,14 @@ static void eth_enc28j60_rx_thread(void *p1, void *p2, void *p3)

const struct device *dev = p1;
struct eth_enc28j60_runtime *context = dev->data;
uint16_t vlan_tag = NET_VLAN_TAG_UNSPEC;
uint8_t int_stat;

while (true) {
k_sem_take(&context->int_sem, K_FOREVER);

eth_enc28j60_read_reg(dev, ENC28J60_REG_EIR, &int_stat);
if (int_stat & ENC28J60_BIT_EIR_PKTIF) {
eth_enc28j60_rx(dev, &vlan_tag);
eth_enc28j60_rx(dev);
/* Clear rx interruption flag */
eth_enc28j60_clear_eth_reg(dev, ENC28J60_REG_EIR,
ENC28J60_BIT_EIR_PKTIF
Expand Down Expand Up @@ -769,10 +732,6 @@ static void eth_enc28j60_iface_init(struct net_if *iface)
sizeof(context->mac_address),
NET_LINK_ETHERNET);

/* For VLAN, this value is only used to get the correct L2 driver.
* The iface pointer in context should contain the main interface
* if the VLANs are enabled.
*/
if (context->iface == NULL) {
context->iface = iface;
}
Expand Down
86 changes: 12 additions & 74 deletions drivers/ethernet/eth_mcux.c
Expand Up @@ -161,10 +161,6 @@ static const char *eth_name(ENET_Type *base)
struct eth_context {
ENET_Type *base;
void (*config_func)(void);
/* If VLAN is enabled, there can be multiple VLAN interfaces related to
* this physical device. In that case, this pointer value is not really
* used for anything.
*/
struct net_if *iface;
#if defined(CONFIG_NET_POWER_MANAGEMENT)
clock_ip_name_t clock;
Expand Down Expand Up @@ -336,22 +332,9 @@ static void eth_mcux_decode_duplex_and_speed(uint32_t status,
}
#endif /* ETH_MCUX_FIXED_LINK */

static inline struct net_if *get_iface(struct eth_context *ctx, uint16_t vlan_tag)
static inline struct net_if *get_iface(struct eth_context *ctx)
{
#if defined(CONFIG_NET_VLAN)
struct net_if *iface;

iface = net_eth_get_vlan_iface(ctx->iface, vlan_tag);
if (!iface) {
return ctx->iface;
}

return iface;
#else
ARG_UNUSED(vlan_tag);

return ctx->iface;
#endif
}

static void eth_mcux_phy_enter_reset(struct eth_context *context)
Expand Down Expand Up @@ -672,31 +655,12 @@ static bool eth_get_ptp_data(struct net_if *iface, struct net_pkt *pkt)
{
int eth_hlen;

#if defined(CONFIG_NET_VLAN)
struct net_eth_vlan_hdr *hdr_vlan;
struct ethernet_context *eth_ctx;
bool vlan_enabled = false;

eth_ctx = net_if_l2_data(iface);
if (net_eth_is_vlan_enabled(eth_ctx, iface)) {
hdr_vlan = (struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
vlan_enabled = true;

if (ntohs(hdr_vlan->type) != NET_ETH_PTYPE_PTP) {
return false;
}

eth_hlen = sizeof(struct net_eth_vlan_hdr);
} else
#endif
{
if (ntohs(NET_ETH_HDR(pkt)->type) != NET_ETH_PTYPE_PTP) {
return false;
}

eth_hlen = sizeof(struct net_eth_hdr);
if (ntohs(NET_ETH_HDR(pkt)->type) != NET_ETH_PTYPE_PTP) {
return false;
}

eth_hlen = sizeof(struct net_eth_hdr);

net_pkt_set_priority(pkt, NET_PRIORITY_CA);

return true;
Expand Down Expand Up @@ -762,7 +726,6 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt)

static int eth_rx(struct eth_context *context)
{
uint16_t vlan_tag = NET_VLAN_TAG_UNSPEC;
uint32_t frame_length = 0U;
struct net_if *iface;
struct net_pkt *pkt;
Expand Down Expand Up @@ -823,36 +786,12 @@ static int eth_rx(struct eth_context *context)

k_mutex_unlock(&context->rx_frame_buf_mutex);

#if defined(CONFIG_NET_VLAN)
{
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);

if (ntohs(hdr->type) == NET_ETH_PTYPE_VLAN) {
struct net_eth_vlan_hdr *hdr_vlan =
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);

net_pkt_set_vlan_tci(pkt, ntohs(hdr_vlan->vlan.tci));
vlan_tag = net_pkt_vlan_tag(pkt);

#if CONFIG_NET_TC_RX_COUNT > 1
{
enum net_priority prio;

prio = net_vlan2priority(
net_pkt_vlan_priority(pkt));
net_pkt_set_priority(pkt, prio);
}
#endif
}
}
#endif /* CONFIG_NET_VLAN */

/*
* Use MAC timestamp
*/
#if defined(CONFIG_PTP_CLOCK_MCUX)
k_mutex_lock(&context->ptp_mutex, K_FOREVER);
if (eth_get_ptp_data(get_iface(context, vlan_tag), pkt)) {
if (eth_get_ptp_data(get_iface(context), pkt)) {
ENET_Ptp1588GetTimer(context->base, &context->enet_handle,
&ptpTimeData);
/* If latest timestamp reloads after getting from Rx BD,
Expand All @@ -873,7 +812,7 @@ static int eth_rx(struct eth_context *context)
k_mutex_unlock(&context->ptp_mutex);
#endif /* CONFIG_PTP_CLOCK_MCUX */

iface = get_iface(context, vlan_tag);
iface = get_iface(context);
#if defined(CONFIG_NET_DSA)
iface = dsa_net_recv(iface, &pkt);
#endif
Expand All @@ -892,7 +831,7 @@ static int eth_rx(struct eth_context *context)
0, RING_ID, NULL);
__ASSERT_NO_MSG(status == kStatus_Success);
error:
eth_stats_update_errors_rx(get_iface(context, vlan_tag));
eth_stats_update_errors_rx(get_iface(context));
return -EIO;
}

Expand Down Expand Up @@ -1174,10 +1113,6 @@ static void eth_iface_init(struct net_if *iface)
sizeof(context->mac_addr),
NET_LINK_ETHERNET);

/* For VLAN, this value is only used to get the correct L2 driver.
* The iface pointer in context should contain the main interface
* if the VLANs are enabled.
*/
if (context->iface == NULL) {
context->iface = iface;
}
Expand All @@ -1195,8 +1130,11 @@ static enum ethernet_hw_caps eth_mcux_get_capabilities(const struct device *dev)
{
ARG_UNUSED(dev);

return ETHERNET_HW_VLAN | ETHERNET_LINK_10BASE_T |
return ETHERNET_LINK_10BASE_T |
ETHERNET_HW_FILTERING |
#if defined(CONFIG_NET_VLAN)
ETHERNET_HW_VLAN |
#endif
#if defined(CONFIG_PTP_CLOCK_MCUX)
ETHERNET_PTP |
#endif
Expand Down