drivers: ethernet: eth_nxp_imx_netc: support handling pseudo MAC

This is to support handling pseudo MAC during initialization, but not
to support DSA master port. Current driver supports DSA with limitation
that only switch function is available without management via DSA master
port. DSA master port support is TODO work.

Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
This commit is contained in:
Yangbo Lu 2024-11-26 16:50:55 +08:00 committed by Benjamin Cabé
commit 3aafce99b3
4 changed files with 29 additions and 3 deletions

View file

@ -7,6 +7,7 @@ menuconfig ETH_NXP_IMX_NETC
depends on DT_HAS_NXP_IMX_NETC_PSI_ENABLED depends on DT_HAS_NXP_IMX_NETC_PSI_ENABLED
select MDIO select MDIO
select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT
select ETH_DSA_SUPPORT
help help
Enable Ethernet and Network Controller (NETC) driver for NXP IMX SoCs. Enable Ethernet and Network Controller (NETC) driver for NXP IMX SoCs.

View file

@ -225,6 +225,7 @@ int netc_eth_init_common(const struct device *dev)
int netc_eth_tx(const struct device *dev, struct net_pkt *pkt) 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; struct netc_eth_data *data = dev->data;
netc_buffer_struct_t buff = {.buffer = data->tx_buff, .length = sizeof(data->tx_buff)}; netc_buffer_struct_t buff = {.buffer = data->tx_buff, .length = sizeof(data->tx_buff)};
netc_frame_struct_t frame = {.buffArray = &buff, .length = 1}; netc_frame_struct_t frame = {.buffArray = &buff, .length = 1};
@ -234,6 +235,11 @@ int netc_eth_tx(const struct device *dev, struct net_pkt *pkt)
__ASSERT(pkt, "Packet pointer is NULL"); __ASSERT(pkt, "Packet pointer is NULL");
/* TODO: support DSA master */
if (cfg->pseudo_mac) {
return -ENOSYS;
}
k_mutex_lock(&data->tx_mutex, K_FOREVER); k_mutex_lock(&data->tx_mutex, K_FOREVER);
/* Copy packet to tx buffer */ /* Copy packet to tx buffer */
@ -275,9 +281,10 @@ error:
enum ethernet_hw_caps netc_eth_get_capabilities(const struct device *dev) enum ethernet_hw_caps netc_eth_get_capabilities(const struct device *dev)
{ {
ARG_UNUSED(dev); const struct netc_eth_config *cfg = dev->config;
uint32_t caps;
return (ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T | ETHERNET_LINK_1000BASE_T | caps = (ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T | ETHERNET_LINK_1000BASE_T |
ETHERNET_HW_RX_CHKSUM_OFFLOAD | ETHERNET_HW_FILTERING ETHERNET_HW_RX_CHKSUM_OFFLOAD | ETHERNET_HW_FILTERING
#if defined(CONFIG_NET_VLAN) #if defined(CONFIG_NET_VLAN)
| ETHERNET_HW_VLAN | ETHERNET_HW_VLAN
@ -286,6 +293,12 @@ enum ethernet_hw_caps netc_eth_get_capabilities(const struct device *dev)
| ETHERNET_PROMISC_MODE | ETHERNET_PROMISC_MODE
#endif #endif
); );
if (cfg->pseudo_mac) {
caps |= ETHERNET_DSA_MASTER_PORT;
}
return caps;
} }
int netc_eth_set_config(const struct device *dev, enum ethernet_config_type type, int netc_eth_set_config(const struct device *dev, enum ethernet_config_type type,

View file

@ -77,6 +77,7 @@ struct netc_eth_config {
uint16_t si_idx; uint16_t si_idx;
const struct device *phy_dev; const struct device *phy_dev;
netc_hw_mii_mode_t phy_mode; netc_hw_mii_mode_t phy_mode;
volatile bool pseudo_mac;
void (*generate_mac)(uint8_t *mac_addr); void (*generate_mac)(uint8_t *mac_addr);
void (*bdr_init)(netc_bdr_config_t *bdr_config, netc_rx_bdr_config_t *rx_bdr_config, void (*bdr_init)(netc_bdr_config_t *bdr_config, netc_rx_bdr_config_t *rx_bdr_config,
netc_tx_bdr_config_t *tx_bdr_config); netc_tx_bdr_config_t *tx_bdr_config);

View file

@ -80,6 +80,10 @@ static void netc_eth_iface_init(struct net_if *iface)
ethernet_init(iface); ethernet_init(iface);
if (cfg->pseudo_mac) {
return;
}
/* /*
* PSI controls the PHY. If PHY is configured either as fixed * PSI controls the PHY. If PHY is configured either as fixed
* link or autoneg, the callback is executed at least once * link or autoneg, the callback is executed at least once
@ -100,11 +104,16 @@ static int netc_eth_init(const struct device *dev)
const struct netc_eth_config *cfg = dev->config; const struct netc_eth_config *cfg = dev->config;
int err; int err;
if (cfg->pseudo_mac) {
goto init_common;
}
err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT);
if (err) { if (err) {
return err; return err;
} }
init_common:
return netc_eth_init_common(dev); return netc_eth_init_common(dev);
} }
@ -182,8 +191,10 @@ static const struct ethernet_api netc_eth_api = {.iface_api.init = netc_eth_ifac
static const struct netc_eth_config netc_eth##n##_config = { \ static const struct netc_eth_config netc_eth##n##_config = { \
.generate_mac = netc_eth##n##_generate_mac, \ .generate_mac = netc_eth##n##_generate_mac, \
.bdr_init = netc_eth##n##_bdr_init, \ .bdr_init = netc_eth##n##_bdr_init, \
.phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle)), \ .phy_dev = (COND_CODE_1(DT_INST_NODE_HAS_PROP(n, phy_handle), \
(DEVICE_DT_GET(DT_INST_PHANDLE(n, phy_handle))), NULL)), \
.phy_mode = NETC_PHY_MODE(DT_DRV_INST(n)), \ .phy_mode = NETC_PHY_MODE(DT_DRV_INST(n)), \
.pseudo_mac = DT_ENUM_HAS_VALUE(DT_DRV_INST(n), phy_connection_type, internal), \
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
.si_idx = (DT_INST_PROP(n, mac_index) << 8) | DT_INST_PROP(n, si_index), \ .si_idx = (DT_INST_PROP(n, mac_index) << 8) | DT_INST_PROP(n, si_index), \
.tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \ .tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \