diff --git a/boards/nxp/imx943_evk/doc/index.rst b/boards/nxp/imx943_evk/doc/index.rst index a3d6122e2ad76..92bd31f614ea0 100644 --- a/boards/nxp/imx943_evk/doc/index.rst +++ b/boards/nxp/imx943_evk/doc/index.rst @@ -65,10 +65,12 @@ CPU's UART1 for Cortex-A55, and UART8 for Cortex-M33. Ethernet -------- -NETC driver supports to manage the Physical Station Interface (PSI). +NETC driver supports to manage the Physical Station Interface (PSI), and TSN switch. The ENET0, ENETC1, ENETC2 ports could be enabled for M33 by west build option ``-DEXTRA_DTC_OVERLAY_FILE=enetc.overlay``. +The two switch ports could be verified via :zephyr:code-sample:`dsa`. + Programming and Debugging (A55) ******************************* diff --git a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts index 4ed9ab8e91b85..77d369709e5fc 100644 --- a/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts +++ b/boards/nxp/imx943_evk/imx943_evk_mimx94398_m33.dts @@ -28,15 +28,15 @@ pinctrl-names = "default"; status = "disabled"; - phy0: phy@f { + phy0: phy@2 { compatible = "ethernet-phy"; - reg = <0xf>; + reg = <0x2>; status = "disabled"; }; - phy1: phy@10 { + phy1: phy@3 { compatible = "ethernet-phy"; - reg = <0x10>; + reg = <0x3>; status = "disabled"; }; @@ -89,3 +89,27 @@ pinctrl-0 = <&lpuart8_default>; pinctrl-names = "default"; }; + +&switch_port0 { + zephyr,random-mac-address; + pinctrl-0 = <ð0_default>; + pinctrl-names = "default"; + phy-handle = <&phy0>; + phy-connection-type = "mii"; + status = "disabled"; +}; + +&switch_port1 { + zephyr,random-mac-address; + pinctrl-0 = <ð1_default>; + pinctrl-names = "default"; + phy-handle = <&phy1>; + phy-connection-type = "mii"; + status = "disabled"; +}; + +/* Internal port */ +&switch_port3 { + zephyr,random-mac-address; + status = "disabled"; +}; diff --git a/drivers/ethernet/dsa/CMakeLists.txt b/drivers/ethernet/dsa/CMakeLists.txt index 1ade5f741d90b..bfaa7ceebd1fb 100644 --- a/drivers/ethernet/dsa/CMakeLists.txt +++ b/drivers/ethernet/dsa/CMakeLists.txt @@ -1,3 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_DSA_KSZ8XXX dsa_ksz8xxx.c) +zephyr_library_sources_ifdef(CONFIG_DSA_NXP_IMX_NETC dsa_nxp_imx_netc.c) diff --git a/drivers/ethernet/dsa/Kconfig b/drivers/ethernet/dsa/Kconfig index b7773e7476b79..5094622caff1c 100644 --- a/drivers/ethernet/dsa/Kconfig +++ b/drivers/ethernet/dsa/Kconfig @@ -1,7 +1,8 @@ -# Distributed Switch Architecture [DSA] configuration options +# Distributed Switch Architecture [DSA] device configuration options # Copyright (c) 2020 DENX Software Engineering GmbH # Lukasz Majewski +# Copyright 2025 NXP # SPDX-License-Identifier: Apache-2.0 config ETH_DSA_SUPPORT_DEPRECATED @@ -10,25 +11,13 @@ config ETH_DSA_SUPPORT_DEPRECATED Set by an ethernet driver that supports DSA. This is obsolete, and only used for legacy dsa device. -menuconfig NET_DSA - bool "Distributed Switch Architecture support" +menuconfig DSA_DRIVERS + bool "Distributed Switch Architecture device drivers" + default y if NET_DSA help Enable Distributed Switch Architecture support. -if NET_DSA - -config NET_DSA_DEPRECATED - bool "Distributed Switch Architecture support for legacy device" - select DEPRECATED - depends on ETH_DSA_SUPPORT_DEPRECATED - help - This is obsolete, and only used for legacy dsa device. - -config DSA_PORT_MAX_COUNT - int "DSA port max count" - default 8 - help - Set DSA port max count. +if DSA_DRIVERS config DSA_KSZ8XXX bool @@ -66,14 +55,6 @@ config DSA_KSZ_TAIL_TAGGING help Add support for tail tagging on DSA device. -config DSA_TAG_SIZE - int "DSA tag size in bytes" - default 1 if DSA_KSZ8794 || DSA_KSZ8863 || DSA_KSZ8463 - default 0 - depends on DSA_KSZ_TAIL_TAGGING - help - Set the DSA tag length in bytes. - config DSA_KSZ_PORT_ISOLATING bool "Support for ports isolating" depends on DSA_KSZ8794 || DSA_KSZ8863 || DSA_KSZ8463 @@ -86,10 +67,11 @@ config DSA_SPI help Use SPI bus to communicate with PHY -module = NET_DSA -module-dep = NET_LOG -module-str = Log level for DSA -module-help = Enables core DSA code to output debug messages. -source "subsys/net/Kconfig.template.log_config.net" +config DSA_NXP_IMX_NETC + bool "Support for NXP i.MX NETC" + default y + depends on DT_HAS_NXP_NETC_SWITCH_ENABLED + help + Add support for NXP i.MX NETC DSA device driver. -endif # NET_DSA +endif # DSA_DRIVERS diff --git a/drivers/ethernet/nxp_imx_netc/dsa_nxp_imx_netc.c b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c similarity index 97% rename from drivers/ethernet/nxp_imx_netc/dsa_nxp_imx_netc.c rename to drivers/ethernet/dsa/dsa_nxp_imx_netc.c index 9208a5133479d..55a67a89ccc17 100644 --- a/drivers/ethernet/nxp_imx_netc/dsa_nxp_imx_netc.c +++ b/drivers/ethernet/dsa/dsa_nxp_imx_netc.c @@ -9,9 +9,9 @@ LOG_MODULE_REGISTER(dsa_netc, CONFIG_ETHERNET_LOG_LEVEL); #include #include +#include #include "../eth.h" -#include "nxp_imx_netc.h" #include "fsl_netc_switch.h" #define DT_DRV_COMPAT nxp_netc_switch @@ -128,6 +128,7 @@ static struct dsa_api dsa_netc_api = { .port_idx = DT_REG_ADDR(port), \ .phy_dev = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(port, phy_handle)), \ .phy_mode = DT_PROP_OR(port, phy_connection_type, ""), \ + .tag_proto = DSA_TAG_PROTO_BY_DT(port), \ .ethernet_connection = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(port, ethernet)), \ .prv_config = &dsa_netc_##n##_##port##_config, \ }; \ diff --git a/drivers/ethernet/nxp_imx_netc/CMakeLists.txt b/drivers/ethernet/nxp_imx_netc/CMakeLists.txt index 91fbf4d4f1eef..ac625baa99c76 100644 --- a/drivers/ethernet/nxp_imx_netc/CMakeLists.txt +++ b/drivers/ethernet/nxp_imx_netc/CMakeLists.txt @@ -5,5 +5,3 @@ if(CONFIG_ETH_NXP_IMX_NETC) zephyr_library_sources(eth_nxp_imx_netc.c) zephyr_library_sources(eth_nxp_imx_netc_psi.c) endif() - -zephyr_library_sources_ifdef(CONFIG_DSA_NXP_IMX_NETC dsa_nxp_imx_netc.c) diff --git a/drivers/ethernet/nxp_imx_netc/Kconfig b/drivers/ethernet/nxp_imx_netc/Kconfig index 5c6af4f5c0cb6..aa7b4dd48dc36 100644 --- a/drivers/ethernet/nxp_imx_netc/Kconfig +++ b/drivers/ethernet/nxp_imx_netc/Kconfig @@ -85,14 +85,3 @@ config ETH_NXP_IMX_RX_RING_BUF_SIZE store one complete Ethernet frame, and be a multiple of 8. endif # ETH_NXP_IMX_NETC - -if NET_DSA - -config DSA_NXP_IMX_NETC - bool "Support for NXP i.MX NETC" - default y - depends on DT_HAS_NXP_NETC_SWITCH_ENABLED - help - Add support for NXP i.MX NETC DSA device driver. - -endif diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c index 32762582dce7d..04988b986149f 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c @@ -294,7 +294,6 @@ int netc_eth_init_common(const struct device *dev) int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) { - const struct netc_eth_config *cfg = dev->config; struct netc_eth_data *data = dev->data; netc_buffer_struct_t buff = {.buffer = data->tx_buff, .length = sizeof(data->tx_buff)}; netc_frame_struct_t frame = {.buffArray = &buff, .length = 1}; @@ -303,6 +302,7 @@ int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) size_t pkt_len = net_pkt_get_len(pkt); #if defined(NETC_HAS_NO_SWITCH_TAG_SUPPORT) struct ethernet_context *eth_ctx = net_if_l2_data(data->iface); + const struct netc_eth_config *cfg = dev->config; #endif status_t result; int ret; @@ -314,18 +314,16 @@ int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) iface_dst = data->iface; - if (cfg->pseudo_mac) { #if defined(NETC_HAS_NO_SWITCH_TAG_SUPPORT) + if (cfg->pseudo_mac) { /* DSA conduit port not used */ if (eth_ctx->dsa_port != DSA_CONDUIT_PORT) { return -ENOSYS; } /* DSA driver redirects the iface */ iface_dst = pkt->iface; -#else - return -ENOSYS; -#endif } +#endif k_mutex_lock(&data->tx_mutex, K_FOREVER); diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h index 157f7e61bae47..406583e664587 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h @@ -7,7 +7,7 @@ #ifndef ZEPHYR_DRIVERS_ETHERNET_ETH_NXP_IMX_NETC_PRIV_H_ #define ZEPHYR_DRIVERS_ETHERNET_ETH_NXP_IMX_NETC_PRIV_H_ -#include "nxp_imx_netc.h" +#include #include "fsl_netc_endpoint.h" #include "fsl_msgintr.h" diff --git a/dts/arm/nxp/nxp_imx943_m33.dtsi b/dts/arm/nxp/nxp_imx943_m33.dtsi index 787fbcfd29744..432210ecf5144 100644 --- a/dts/arm/nxp/nxp_imx943_m33.dtsi +++ b/dts/arm/nxp/nxp_imx943_m33.dtsi @@ -303,6 +303,16 @@ status = "disabled"; }; + /* Internal port */ + enetc_psi3: ethernet@4cd40000 { + compatible = "nxp,imx-netc-psi"; + reg = <0x4cd40000 0x10000>; + mac-index = <3>; + si-index = <3>; + phy-connection-type = "internal"; + status = "disabled"; + }; + netc_ptp_clock0: ptp_clock@4cd80000 { compatible = "nxp,netc-ptp-clock"; reg = <0x4cd80000 0x10000>; @@ -323,6 +333,38 @@ clocks = <&scmi_clk IMX943_CLK_ENET>; status = "disabled"; }; + + netc_switch: switch { + compatible = "nxp,netc-switch"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + + switch_port0: switch_port@0 { + reg = <0>; + status = "disabled"; + }; + + switch_port1: switch_port@1 { + reg = <1>; + status = "disabled"; + }; + + /* Parallel interface is muxed with enetc_psi0. */ + switch_port2: switch_port@2 { + reg = <2>; + status = "disabled"; + }; + + /* Internal port */ + switch_port3: switch_port@3 { + reg = <3>; + ethernet = <&enetc_psi3>; + phy-connection-type = "internal"; + tag-protocol = "netc"; + status = "disabled"; + }; + }; }; }; }; diff --git a/dts/bindings/dsa/dsa.yaml b/dts/bindings/dsa/dsa.yaml index eca0b1d6d2c55..b7fa5d4a8b87a 100644 --- a/dts/bindings/dsa/dsa.yaml +++ b/dts/bindings/dsa/dsa.yaml @@ -4,7 +4,7 @@ description: DSA Device child-binding: - description: Properties of slave port + description: Properties of port include: - name: pinctrl-device.yaml @@ -25,3 +25,10 @@ child-binding: description: A phandle to a valid Ethernet device node. This host device is what the switch port is connected to. + tag-protocol: + type: string + description: + Tag protocol the switch using. Or the switch supports no tag way + if it's not specified on CPU port. + enum: + - "netc" diff --git a/drivers/ethernet/nxp_imx_netc/nxp_imx_netc.h b/include/zephyr/drivers/ethernet/nxp_imx_netc.h similarity index 100% rename from drivers/ethernet/nxp_imx_netc/nxp_imx_netc.h rename to include/zephyr/drivers/ethernet/nxp_imx_netc.h diff --git a/include/zephyr/net/dsa_core.h b/include/zephyr/net/dsa_core.h index f22d4d0aa07e1..6a00b21d8371c 100644 --- a/include/zephyr/net/dsa_core.h +++ b/include/zephyr/net/dsa_core.h @@ -75,6 +75,12 @@ extern "C" { }; \ DT_INST_FOREACH_CHILD_STATUS_OKAY_VARGS(n, fn, n); +#define DSA_TAG_PROTO_NONE 0 +#define DSA_TAG_PROTO_NETC 1 + +#define DSA_TAG_PROTO_BY_DT(node_id) \ + (DT_ENUM_HAS_VALUE(node_id, tag_protocol, netc) ? DSA_TAG_PROTO_NETC : DSA_TAG_PROTO_NONE) + /** DSA switch context data */ struct dsa_switch_context { /** Pointers to all DSA user network interfaces */ @@ -137,6 +143,8 @@ struct dsa_port_config { const struct device *phy_dev; /** PHY mode */ const char *phy_mode; + /** Tag protocol */ + const int tag_proto; /** Ethernet device connected to the port */ const struct device *ethernet_connection; /** Instance specific config */ diff --git a/samples/net/dsa/boards/imx943_evk_mimx94398_m33_ddr.conf b/samples/net/dsa/boards/imx943_evk_mimx94398_m33_ddr.conf new file mode 100644 index 0000000000000..544b9163d4115 --- /dev/null +++ b/samples/net/dsa/boards/imx943_evk_mimx94398_m33_ddr.conf @@ -0,0 +1 @@ +CONFIG_NET_SAMPLE_DSA_LLDP=n diff --git a/samples/net/dsa/boards/imx943_evk_mimx94398_m33_ddr.overlay b/samples/net/dsa/boards/imx943_evk_mimx94398_m33_ddr.overlay new file mode 100644 index 0000000000000..a146ae971c2a0 --- /dev/null +++ b/samples/net/dsa/boards/imx943_evk_mimx94398_m33_ddr.overlay @@ -0,0 +1,39 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&emdio { + status = "okay"; + + phy0: phy@2 { + status = "okay"; + }; + + phy1: phy@3 { + status = "okay"; + }; +}; + +/* Internal port */ +&enetc_psi3 { + status = "okay"; +}; + +&netc_switch { + status = "okay"; + + switch_port0: switch_port@0 { + status = "okay"; + }; + + switch_port1: switch_port@1 { + status = "okay"; + }; + + /* Internal port */ + switch_port3: switch_port@3 { + status = "okay"; + }; +}; diff --git a/samples/net/dsa/sample.yaml b/samples/net/dsa/sample.yaml index 3016a7e5f6f16..dc89f0d97e873 100644 --- a/samples/net/dsa/sample.yaml +++ b/samples/net/dsa/sample.yaml @@ -13,4 +13,5 @@ tests: - ip_k66f - mimxrt1180_evk/mimxrt1189/cm33 - mimxrt1180_evk/mimxrt1189/cm7 + - imx943_evk/mimx94398/m33/ddr depends_on: eth diff --git a/subsys/net/l2/ethernet/Kconfig b/subsys/net/l2/ethernet/Kconfig index 00b4ebba3d64e..0c21e6f3c7a8e 100644 --- a/subsys/net/l2/ethernet/Kconfig +++ b/subsys/net/l2/ethernet/Kconfig @@ -114,6 +114,7 @@ module-help = Enables core ARP code to output debug messages. source "subsys/net/Kconfig.template.log_config.net" endif # NET_ARP +source "subsys/net/l2/ethernet/dsa/Kconfig" source "subsys/net/l2/ethernet/gptp/Kconfig" source "subsys/net/l2/ethernet/lldp/Kconfig" diff --git a/subsys/net/l2/ethernet/dsa/CMakeLists.txt b/subsys/net/l2/ethernet/dsa/CMakeLists.txt index 7c5d26ebb2ec6..d1fe3d015a10c 100644 --- a/subsys/net/l2/ethernet/dsa/CMakeLists.txt +++ b/subsys/net/l2/ethernet/dsa/CMakeLists.txt @@ -8,4 +8,5 @@ zephyr_library_sources(dsa_core.c) zephyr_library_sources(dsa_port.c) zephyr_library_sources(dsa_user.c) zephyr_library_sources(dsa_tag.c) +zephyr_library_sources_ifdef(CONFIG_DSA_TAG_PROTOCOL_NETC dsa_tag_netc.c) endif() diff --git a/subsys/net/l2/ethernet/dsa/Kconfig b/subsys/net/l2/ethernet/dsa/Kconfig new file mode 100644 index 0000000000000..5c56a99f179c7 --- /dev/null +++ b/subsys/net/l2/ethernet/dsa/Kconfig @@ -0,0 +1,52 @@ +# Distributed Switch Architecture [DSA] configuration options + +# Copyright (c) 2020 DENX Software Engineering GmbH +# Lukasz Majewski +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +menuconfig NET_DSA + bool "Distributed Switch Architecture support" + help + Enable Distributed Switch Architecture support. + +if NET_DSA + +config NET_DSA_DEPRECATED + bool "Distributed Switch Architecture support for legacy device" + select DEPRECATED + depends on ETH_DSA_SUPPORT_DEPRECATED + help + This is obsolete, and only used for legacy dsa device. + +config DSA_PORT_MAX_COUNT + int "DSA port max count" + default 8 + help + Set DSA port max count. + +config DSA_TAG_SIZE + int "DSA tag size in bytes" + # These platforms are still using legacy DSA core driver + default 1 if DSA_KSZ8794 || DSA_KSZ8863 || DSA_KSZ8463 + default 0 + help + Set the DSA tag length in bytes. + +config DSA_TAG_PROTOCOL_NETC + bool "Tag protocol - NETC" + default y if $(dt_node_str_prop_equals,$(dt_nodelabel_path,switch_port0),tag-protocol,netc) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,switch_port1),tag-protocol,netc) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,switch_port2),tag-protocol,netc) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,switch_port3),tag-protocol,netc) \ + || $(dt_node_str_prop_equals,$(dt_nodelabel_path,switch_port4),tag-protocol,netc) + help + NXP NETC tag protocol. + +module = NET_DSA +module-dep = NET_LOG +module-str = Log level for DSA +module-help = Enables core DSA code to output debug messages. +source "subsys/net/Kconfig.template.log_config.net" + +endif # NET_DSA diff --git a/subsys/net/l2/ethernet/dsa/dsa_port.c b/subsys/net/l2/ethernet/dsa/dsa_port.c index 33f9b156e0508..b8ccb2a2921cf 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_port.c +++ b/subsys/net/l2/ethernet/dsa/dsa_port.c @@ -10,6 +10,7 @@ LOG_MODULE_REGISTER(net_dsa_port, CONFIG_NET_DSA_LOG_LEVEL); #include #include #include +#include "dsa_tag.h" #if defined(CONFIG_NET_INTERFACE_NAME_LEN) #define INTERFACE_NAME_LEN CONFIG_NET_INTERFACE_NAME_LEN @@ -28,19 +29,18 @@ int dsa_port_initialize(const struct device *dev) dsa_switch_ctx->init_ports++; - /* Find conduit port */ + /* Find the connection of conduit port and cpu port */ if (dsa_switch_ctx->iface_conduit == NULL && cfg->ethernet_connection != NULL) { dsa_switch_ctx->iface_conduit = net_if_lookup_by_dev(cfg->ethernet_connection); if (dsa_switch_ctx->iface_conduit == NULL) { LOG_ERR("DSA: Conduit iface NOT found!"); } + /* Set up tag protocol on the cpu port */ eth_ctx->dsa_port = DSA_CPU_PORT; + dsa_tag_setup(dev); - /* - * Provide pointer to DSA switch context to conduit's eth interface - * struct ethernet_context - */ + /* Provide DSA information to the conduit port */ eth_ctx_conduit = net_if_l2_data(dsa_switch_ctx->iface_conduit); eth_ctx_conduit->dsa_switch_ctx = dsa_switch_ctx; eth_ctx_conduit->dsa_port = DSA_CONDUIT_PORT; diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.c b/subsys/net/l2/ethernet/dsa/dsa_tag.c index b63d901d2bb1a..bdce548e1b7aa 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.c +++ b/subsys/net/l2/ethernet/dsa/dsa_tag.c @@ -6,6 +6,7 @@ #include #include +#include "dsa_tag.h" struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt) { @@ -36,3 +37,20 @@ struct net_pkt *dsa_tag_xmit(struct net_if *iface, struct net_pkt *pkt) return dsa_switch_ctx->dapi->xmit(iface, pkt); } + +void dsa_tag_setup(const struct device *dev_cpu) +{ + const struct dsa_port_config *cfg = dev_cpu->config; + struct dsa_switch_context *dsa_switch_ctx = dev_cpu->data; + + switch (cfg->tag_proto) { + case DSA_TAG_PROTO_NETC: + dsa_switch_ctx->dapi->recv = dsa_tag_netc_recv; + dsa_switch_ctx->dapi->xmit = dsa_tag_netc_xmit; + break; + default: + dsa_switch_ctx->dapi->recv = NULL; + dsa_switch_ctx->dapi->xmit = NULL; + break; + } +} diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag.h b/subsys/net/l2/ethernet/dsa/dsa_tag.h index 3728fa991e64d..36a9b7989c7ec 100644 --- a/subsys/net/l2/ethernet/dsa/dsa_tag.h +++ b/subsys/net/l2/ethernet/dsa/dsa_tag.h @@ -6,7 +6,10 @@ #ifndef ZEPHYR_SUBSYS_DSA_TAG_PRIV_H_ #define ZEPHYR_SUBSYS_DSA_TAG_PRIV_H_ +#include "dsa_tag_netc.h" + struct net_if *dsa_tag_recv(struct net_if *iface, struct net_pkt *pkt); struct net_pkt *dsa_tag_xmit(struct net_if *iface, struct net_pkt *pkt); +void dsa_tag_setup(const struct device *dev_cpu); #endif diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c new file mode 100644 index 0000000000000..813754c046c25 --- /dev/null +++ b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.c @@ -0,0 +1,96 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_dsa_tag_netc, CONFIG_NET_DSA_LOG_LEVEL); + +#include +#include +#include "dsa_tag_netc.h" +#include "fsl_netc_tag.h" + +/* tag is inserted after DMAC/SMAC fields */ +struct dsa_tag_netc_to_host_header { + uint8_t dmac[NET_ETH_ADDR_LEN]; + uint8_t smac[NET_ETH_ADDR_LEN]; + netc_swt_tag_host_t tag; +}; + +struct dsa_tag_netc_to_port_header { + uint8_t dmac[NET_ETH_ADDR_LEN]; + uint8_t smac[NET_ETH_ADDR_LEN]; + netc_swt_tag_port_no_ts_t tag; +}; + +struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) +{ + struct ethernet_context *eth_ctx = net_if_l2_data(iface); + uint16_t header_len = sizeof(struct dsa_tag_netc_to_host_header); + struct dsa_tag_netc_to_host_header *header; + struct net_if *iface_dst = iface; + uint8_t *ptr; + + if (pkt->frags->len < header_len) { + LOG_ERR("tag len error"); + return iface_dst; + } + + /* redirect to user port */ + header = (struct dsa_tag_netc_to_host_header *)pkt->frags->data; + iface_dst = eth_ctx->dsa_switch_ctx->iface_user[header->tag.comTag.port]; + + /* drop tag */ + ptr = net_buf_pull(pkt->frags, sizeof(netc_swt_tag_host_t)); + for (int i = 0; i < (NET_ETH_ADDR_LEN * 2); i++) { + ptr[i] = *(uint8_t *)((uintptr_t)header + i); + } + + return iface_dst; +} + +struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) +{ + const struct device *dev = net_if_get_device(iface); + struct dsa_port_config *cfg = (struct dsa_port_config *)dev->config; + struct dsa_tag_netc_to_port_header *header; + struct net_buf *buf; + + size_t buf_len = pkt->frags->len + sizeof(netc_swt_tag_port_no_ts_t); + + /* allocate new net_buf */ + buf = net_buf_alloc_len(net_buf_pool_get(pkt->buffer->pool_id), buf_len, K_NO_WAIT); + if (!buf) { + LOG_ERR("cannot allocate new data buffer"); + return NULL; + } + + /* init buf */ + buf->len = buf_len; + memset(buf->data, 0, buf->len); + + /* fill header */ + header = (struct dsa_tag_netc_to_port_header *)buf->data; + memcpy(header, pkt->frags->data, (NET_ETH_ADDR_LEN * 2)); + header->tag.comTag.tpid = NETC_SWITCH_DEFAULT_ETHER_TYPE; + header->tag.comTag.subType = kNETC_TagToPortNoTs; + header->tag.comTag.type = kNETC_TagToPort; + header->tag.comTag.swtId = 1, + header->tag.comTag.port = cfg->port_idx; + + /* copy the rest data */ + memcpy((void *)((uintptr_t)buf->data + sizeof(*header)), + (void *)((uintptr_t)pkt->frags->data + (2 * NET_ETH_ADDR_LEN)), + pkt->frags->len - (2 * NET_ETH_ADDR_LEN)); + + /* insert the new frag */ + net_buf_frag_insert(pkt->frags, buf); + + /* drop the old frag */ + pkt->frags = buf; + net_pkt_cursor_init(pkt); + + return pkt; +} diff --git a/subsys/net/l2/ethernet/dsa/dsa_tag_netc.h b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.h new file mode 100644 index 0000000000000..6a8c480a69517 --- /dev/null +++ b/subsys/net/l2/ethernet/dsa/dsa_tag_netc.h @@ -0,0 +1,24 @@ +/* + * Copyright 2025 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ +#define ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ + +#ifdef CONFIG_DSA_TAG_PROTOCOL_NETC +struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt); +struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt); +#else +static inline struct net_if *dsa_tag_netc_recv(struct net_if *iface, struct net_pkt *pkt) +{ + return iface; +} + +static inline struct net_pkt *dsa_tag_netc_xmit(struct net_if *iface, struct net_pkt *pkt) +{ + return pkt; +} +#endif /* CONFIG_DSA_TAG_PROTOCOL_NETC */ + +#endif /* ZEPHYR_SUBSYS_DSA_TAG_NETC_H_ */ diff --git a/west.yml b/west.yml index 116f4d478050e..84139a249b0b4 100644 --- a/west.yml +++ b/west.yml @@ -210,7 +210,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 7a52cbb7cb56db3a276cbd617db3ea7cc3435d12 + revision: pull/575/head path: modules/hal/nxp groups: - hal