Re: [PATCH v7 1/2] net: mhi: Enable Ethernet interface support
vivek pernamitta <[email protected]> Wed, 11 Feb 2026 15:49:11 +0530
| Newsgroups | dev.linux.lists.mhi,org.kernel.vger.linux-arm-msm,org.kernel.vger.linux-kernel,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
On 2/5/2026 7:38 PM, Loic Poulain wrote: > Hi Vivek, > > On Thu, Feb 5, 2026 at 11:35 AM Vivek Pernamitta > <[email protected]> wrote: >> >> From: Vivek Pernamitta <[email protected]> >> >> Add support to configure a new client as Ethernet type over MHI by >> setting "mhi_device_info.ethernet_if = true". Create a new Ethernet >> interface named eth%d. This complements existing NET driver support. >> >> Introduce IP_SW1, ETH0, and ETH1 network interfaces required for >> M-plane, NETCONF, and S-plane components. >> >> M-plane: >> Implement DU M-Plane software for non-real-time O-RAN management >> between O-DU and O-RU using NETCONF/YANG and O-RAN WG4 M-Plane YANG >> models. Provide capability exchange, configuration management, >> performance monitoring, and fault management per O-RAN.WG4.TS.MP.0- >> R004-v18.00. >> >> NETCONF: >> Use NETCONF protocol for configuration operations such as fetching, >> modifying, and deleting network device configurations. >> >> S-plane: >> Support frequency and time synchronization between O-DUs and O-RUs >> using Synchronous Ethernet and IEEE 1588. Assume PTP transport over >> L2 Ethernet (ITU-T G.8275.1) for full timing support; allow PTP over >> UDP/IP (ITU-T G.8275.2) with reduced reliability. as per ORAN spec >> O-RAN.WG4.CUS.0-R003-v12.00. >> >> Signed-off-by: Vivek Pernamitta <[email protected]> >> --- >> drivers/net/mhi_net.c | 75 ++++++++++++++++++++++++++++++++++++++++++--------- >> 1 file changed, 62 insertions(+), 13 deletions(-) >> >> diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c >> index ae169929a9d8e449b5a427993abf68e8d032fae2..fbec10c1ba9faf1ccf049b808e9d391800320989 100644 >> --- a/drivers/net/mhi_net.c >> +++ b/drivers/net/mhi_net.c >> @@ -4,6 +4,7 @@ >> * Copyright (C) 2020 Linaro Ltd <[email protected]> >> */ >> >> +#include <linux/etherdevice.h> >> #include <linux/if_arp.h> >> #include <linux/mhi.h> >> #include <linux/mod_devicetable.h> >> @@ -38,10 +39,12 @@ struct mhi_net_dev { >> u32 rx_queue_sz; >> int msg_enable; >> unsigned int mru; >> + bool ethernet_if; >> }; >> >> struct mhi_device_info { >> const char *netname; >> + bool ethernet_if; >> }; >> >> static int mhi_ndo_open(struct net_device *ndev) >> @@ -119,11 +122,29 @@ static void mhi_ndo_get_stats64(struct net_device *ndev, >> } while (u64_stats_fetch_retry(&mhi_netdev->stats.tx_syncp, start)); >> } >> >> +static int mhi_mac_address(struct net_device *dev, void *p) >> +{ >> + if (dev->type == ARPHRD_ETHER) >> + return eth_mac_addr(dev, p); >> + >> + return 0; >> +} >> + >> +static int mhi_validate_address(struct net_device *dev) >> +{ >> + if (dev->type == ARPHRD_ETHER) >> + return eth_validate_addr(dev); >> + >> + return 0; >> +} >> + >> static const struct net_device_ops mhi_netdev_ops = { >> .ndo_open = mhi_ndo_open, >> .ndo_stop = mhi_ndo_stop, >> .ndo_start_xmit = mhi_ndo_xmit, >> .ndo_get_stats64 = mhi_ndo_get_stats64, >> + .ndo_set_mac_address = mhi_mac_address, >> + .ndo_validate_addr = mhi_validate_address, >> }; >> >> static void mhi_net_setup(struct net_device *ndev) >> @@ -140,6 +161,13 @@ static void mhi_net_setup(struct net_device *ndev) >> ndev->tx_queue_len = 1000; >> } >> >> +static void mhi_ethernet_setup(struct net_device *ndev) >> +{ >> + ndev->netdev_ops = &mhi_netdev_ops; >> + ether_setup(ndev); >> + ndev->max_mtu = ETH_MAX_MTU; >> +} >> + >> static struct sk_buff *mhi_net_skb_agg(struct mhi_net_dev *mhi_netdev, >> struct sk_buff *skb) >> { >> @@ -209,16 +237,22 @@ static void mhi_net_dl_callback(struct mhi_device *mhi_dev, >> mhi_netdev->skbagg_head = NULL; >> } >> >> - switch (skb->data[0] & 0xf0) { >> - case 0x40: >> - skb->protocol = htons(ETH_P_IP); >> - break; >> - case 0x60: >> - skb->protocol = htons(ETH_P_IPV6); >> - break; >> - default: >> - skb->protocol = htons(ETH_P_MAP); >> - break; >> + if (mhi_netdev->ethernet_if) { >> + skb_copy_to_linear_data(skb, skb->data, >> + mhi_res->bytes_xferd); > > What is the purpose of the above? > > > Will remove this line skb_copy_to_linear_data, as it does memcpy again in same skb->data >> + skb->protocol = eth_type_trans(skb, mhi_netdev->ndev); >> + } else { >> + switch (skb->data[0] & 0xf0) { >> + case 0x40: >> + skb->protocol = htons(ETH_P_IP); >> + break; >> + case 0x60: >> + skb->protocol = htons(ETH_P_IPV6); >> + break; >> + default: >> + skb->protocol = htons(ETH_P_MAP); >> + break; >> + } >> } >> >> u64_stats_update_begin(&mhi_netdev->stats.rx_syncp); >> @@ -301,11 +335,14 @@ static void mhi_net_rx_refill_work(struct work_struct *work) >> schedule_delayed_work(&mhi_netdev->rx_refill, HZ / 2); >> } >> >> -static int mhi_net_newlink(struct mhi_device *mhi_dev, struct net_device *ndev) >> +static int mhi_net_newlink(struct mhi_device *mhi_dev, struct net_device *ndev, bool eth_dev) >> { >> struct mhi_net_dev *mhi_netdev; >> int err; >> >> + if (eth_dev) >> + eth_hw_addr_random(ndev); >> + >> mhi_netdev = netdev_priv(ndev); >> >> dev_set_drvdata(&mhi_dev->dev, mhi_netdev); >> @@ -313,6 +350,7 @@ static int mhi_net_newlink(struct mhi_device *mhi_dev, struct net_device *ndev) >> mhi_netdev->mdev = mhi_dev; >> mhi_netdev->skbagg_head = NULL; >> mhi_netdev->mru = mhi_dev->mhi_cntrl->mru; >> + mhi_netdev->ethernet_if = eth_dev; >> >> INIT_DELAYED_WORK(&mhi_netdev->rx_refill, mhi_net_rx_refill_work); >> u64_stats_init(&mhi_netdev->stats.rx_syncp); >> @@ -356,13 +394,14 @@ static int mhi_net_probe(struct mhi_device *mhi_dev, >> int err; >> >> ndev = alloc_netdev(sizeof(struct mhi_net_dev), info->netname, >> - NET_NAME_PREDICTABLE, mhi_net_setup); >> + NET_NAME_ENUM, info->ethernet_if ? >> + mhi_ethernet_setup : mhi_net_setup); >> if (!ndev) >> return -ENOMEM; >> >> SET_NETDEV_DEV(ndev, &mhi_dev->dev); >> >> - err = mhi_net_newlink(mhi_dev, ndev); >> + err = mhi_net_newlink(mhi_dev, ndev, info->ethernet_if); >> if (err) { >> free_netdev(ndev); >> return err; >> @@ -380,10 +419,17 @@ static void mhi_net_remove(struct mhi_device *mhi_dev) >> >> static const struct mhi_device_info mhi_hwip0 = { >> .netname = "mhi_hwip%d", >> + .ethernet_if = false, >> }; >> >> static const struct mhi_device_info mhi_swip0 = { >> .netname = "mhi_swip%d", >> + .ethernet_if = false, >> +}; >> + >> +static const struct mhi_device_info mhi_eth0 = { >> + .netname = "eth%d", >> + .ethernet_if = true, >> }; >> >> static const struct mhi_device_id mhi_net_id_table[] = { >> @@ -391,6 +437,9 @@ static const struct mhi_device_id mhi_net_id_table[] = { >> { .chan = "IP_HW0", .driver_data = (kernel_ulong_t)&mhi_hwip0 }, >> /* Software data PATH (to modem CPU) */ >> { .chan = "IP_SW0", .driver_data = (kernel_ulong_t)&mhi_swip0 }, >> + { .chan = "IP_SW1", .driver_data = (kernel_ulong_t)&mhi_swip0 }, >> + { .chan = "IP_ETH0", .driver_data = (kernel_ulong_t)&mhi_eth0 }, >> + { .chan = "IP_ETH1", .driver_data = (kernel_ulong_t)&mhi_eth0 }, >> {} >> }; >> MODULE_DEVICE_TABLE(mhi, mhi_net_id_table); >> >> -- >> 2.34.1 >> >>