* [PATCH v7 0/2] net: mhi: Add support to enable ethernet interface
@ 2026-02-05 10:34 Vivek Pernamitta
2026-02-05 10:34 ` [PATCH v7 1/2] net: mhi: Enable Ethernet interface support Vivek Pernamitta
2026-02-05 10:34 ` [PATCH v7 2/2] bus: mhi: host: pci: Enable IP_SW1, IP_ETH0 and IP_ETH1 channels for QDU100 Vivek Pernamitta
0 siblings, 2 replies; 7+ messages in thread
From: Vivek Pernamitta @ 2026-02-05 10:34 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Manivannan Sadhasivam
Cc: netdev, linux-kernel, mhi, linux-arm-msm, Vivek Pernamitta,
Vivek Pernamitta
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.
YANG model based interface aligned with O-RAN WG4 M-Plane
specifications over TCP between the OAM application on the
host and the DU M-Plane software running on the X100 platform.
Netconf:
Use NETCONF protocol for configuration operations such as
fetching, modifying, and deleting network device
configurations.
This interface is used for IETF Netconf communication,
enabling a Netconf server on the ORU to interact with a
Netconf client running on the host.
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.
To support accurate phase and time synchronization between
the host (L2) and device (L1-High), the system must exchange
PTP messages as raw Layer-2 Ethernet frames, because the
ITU-T G.8275.1 profile operates strictly over Ethernet
multicast and not over IP networks. This means the device’s
PTP stack can only send and receive PTP Announce, Sync,
Follow-Up, and Delay messages in native Ethernet format, not
as IPv4/IPv6 packets. However, the host and device communicate
only through MHI/PCIe, which provides no native Ethernet
interface. Therefore, the system must implement a virtual
Ethernet interface over MHI on both sides. This virtual
Layer-2 link enables true Ethernet-frame transport, ensuring
the device’s PTP implementation remains fully compliant with
the G.8275.1 Ethernet-based timing model.
The actual link between the device (QDU100) and the host is
PCIe/MHI. The device has the Ethernet interface and is exposed
as the MHI channel to the host. So this patch creates the
Ethernet interface on the host based on the 'IP_ETH' channel
so that the host can use this interface for exchanging the
NETCONF packets.
The patch primarily addresses host-to-DU(QDU100) communication.
However, the NETCONF/M-Plane packets originating from the host
will eventually be transmitted from the DU to the RU over the
fronthaul, which uses Ethernet. For additional details on this
architecture and data flow, refer to the O-RAN Management
Plane Specification:
O-RAN.WG4.MP.0-v07.00
O-RAN Alliance Working Group 4 – Management Plane
Specification
Chapter 4: O-RU to O-DU Interface Management
Signed-off-by: Vivek Pernamitta <vpernami@qti.qualcomm.com>
---
patchset link for V6 : https://lore.kernel.org/all/20251209-vdev_next-20251208_eth_v6-v6-0-80898204f5d8@quicinc.com/
patchset link for V1 (first post) : https://lore.kernel.org/all/20250724-b4-eth_us-v1-0-4dff04a9a128@quicinc.com/
changes to v7:
- Updated to NET_NAME_ENUM while allocating netdev as per Andrew
- Updated more information as per comments from Jakub and Mani
changes to v6:
- Removed interm variable useage as per comments from Simon and Dmirty.
- Squashed gerrits 1 and 2 in single gerrit.
- Added more description for M-plane, Netconf and S-plane.
changes to v5:
- change in email ID from "quic_vpernami@quicinc.com" to "vivek.pernamitta@oss.qualcomm.com"
- Renamed to patch v5 as per comments from Manivannan
- Restored to original name as per comments from Jakub
- Renamed the ethernet interfce to eth%d as per Jakub
---
---
Vivek Pernamitta (2):
net: mhi: Enable Ethernet interface support
bus: mhi: host: pci: Enable IP_SW1, IP_ETH0 and IP_ETH1 channels for QDU100
drivers/bus/mhi/host/pci_generic.c | 8 ++++
drivers/net/mhi_net.c | 75 +++++++++++++++++++++++++++++++-------
2 files changed, 70 insertions(+), 13 deletions(-)
---
base-commit: 0f8a890c4524d6e4013ff225e70de2aed7e6d726
change-id: 20260205-eth_vdev_next-20260204_eth-807136ad5cd0
Best regards,
--
Vivek Pernamitta <vpernami@qti.qualcomm.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v7 1/2] net: mhi: Enable Ethernet interface support 2026-02-05 10:34 [PATCH v7 0/2] net: mhi: Add support to enable ethernet interface Vivek Pernamitta @ 2026-02-05 10:34 ` Vivek Pernamitta 2026-02-05 14:08 ` Loic Poulain 2026-02-10 10:43 ` Paolo Abeni 2026-02-05 10:34 ` [PATCH v7 2/2] bus: mhi: host: pci: Enable IP_SW1, IP_ETH0 and IP_ETH1 channels for QDU100 Vivek Pernamitta 1 sibling, 2 replies; 7+ messages in thread From: Vivek Pernamitta @ 2026-02-05 10:34 UTC (permalink / raw) To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Manivannan Sadhasivam Cc: netdev, linux-kernel, mhi, linux-arm-msm, Vivek Pernamitta, Vivek Pernamitta From: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com> 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 <vivek.pernamitta@oss.qualcomm.com> --- 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 <loic.poulain@linaro.org> */ +#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); + 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 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v7 1/2] net: mhi: Enable Ethernet interface support 2026-02-05 10:34 ` [PATCH v7 1/2] net: mhi: Enable Ethernet interface support Vivek Pernamitta @ 2026-02-05 14:08 ` Loic Poulain 2026-02-11 10:19 ` vivek pernamitta 2026-02-10 10:43 ` Paolo Abeni 1 sibling, 1 reply; 7+ messages in thread From: Loic Poulain @ 2026-02-05 14:08 UTC (permalink / raw) To: Vivek Pernamitta Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Manivannan Sadhasivam, netdev, linux-kernel, mhi, linux-arm-msm, Vivek Pernamitta Hi Vivek, On Thu, Feb 5, 2026 at 11:35 AM Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com> wrote: > > From: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com> > > 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 <vivek.pernamitta@oss.qualcomm.com> > --- > 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 <loic.poulain@linaro.org> > */ > > +#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? > + 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 > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 1/2] net: mhi: Enable Ethernet interface support 2026-02-05 14:08 ` Loic Poulain @ 2026-02-11 10:19 ` vivek pernamitta 0 siblings, 0 replies; 7+ messages in thread From: vivek pernamitta @ 2026-02-11 10:19 UTC (permalink / raw) To: Loic Poulain Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Manivannan Sadhasivam, netdev, linux-kernel, mhi, linux-arm-msm, Vivek Pernamitta On 2/5/2026 7:38 PM, Loic Poulain wrote: > Hi Vivek, > > On Thu, Feb 5, 2026 at 11:35 AM Vivek Pernamitta > <vivek.pernamitta@oss.qualcomm.com> wrote: >> >> From: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com> >> >> 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 <vivek.pernamitta@oss.qualcomm.com> >> --- >> 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 <loic.poulain@linaro.org> >> */ >> >> +#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 >> >> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 1/2] net: mhi: Enable Ethernet interface support 2026-02-05 10:34 ` [PATCH v7 1/2] net: mhi: Enable Ethernet interface support Vivek Pernamitta 2026-02-05 14:08 ` Loic Poulain @ 2026-02-10 10:43 ` Paolo Abeni 2026-02-11 10:24 ` vivek pernamitta 1 sibling, 1 reply; 7+ messages in thread From: Paolo Abeni @ 2026-02-10 10:43 UTC (permalink / raw) To: Vivek Pernamitta, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Manivannan Sadhasivam Cc: netdev, linux-kernel, mhi, linux-arm-msm, Vivek Pernamitta On 2/5/26 11:34 AM, Vivek Pernamitta wrote: > @@ -4,6 +4,7 @@ > * Copyright (C) 2020 Linaro Ltd <loic.poulain@linaro.org> > */ > > +#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; This is not needed, instead you could check !!dev->header_ops /P ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v7 1/2] net: mhi: Enable Ethernet interface support 2026-02-10 10:43 ` Paolo Abeni @ 2026-02-11 10:24 ` vivek pernamitta 0 siblings, 0 replies; 7+ messages in thread From: vivek pernamitta @ 2026-02-11 10:24 UTC (permalink / raw) To: Paolo Abeni, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Manivannan Sadhasivam Cc: netdev, linux-kernel, mhi, linux-arm-msm, Vivek Pernamitta On 2/10/2026 4:13 PM, Paolo Abeni wrote: > On 2/5/26 11:34 AM, Vivek Pernamitta wrote: >> @@ -4,6 +4,7 @@ >> * Copyright (C) 2020 Linaro Ltd <loic.poulain@linaro.org> >> */ >> >> +#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; > > This is not needed, instead you could check !!dev->header_ops > > /P > As this driver supports only Ethernet and IP net interface types. Will remove the ethernet_if member from the mhi_net_dev structure and use net_device->header_ops for interface-type checks ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v7 2/2] bus: mhi: host: pci: Enable IP_SW1, IP_ETH0 and IP_ETH1 channels for QDU100 2026-02-05 10:34 [PATCH v7 0/2] net: mhi: Add support to enable ethernet interface Vivek Pernamitta 2026-02-05 10:34 ` [PATCH v7 1/2] net: mhi: Enable Ethernet interface support Vivek Pernamitta @ 2026-02-05 10:34 ` Vivek Pernamitta 1 sibling, 0 replies; 7+ messages in thread From: Vivek Pernamitta @ 2026-02-05 10:34 UTC (permalink / raw) To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Manivannan Sadhasivam Cc: netdev, linux-kernel, mhi, linux-arm-msm, Vivek Pernamitta, Vivek Pernamitta From: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com> Enable IP_SW1, IP_ETH0 and IP_ETH1 channels for M-plane, NETCONF and S-plane interface for QDU100. Signed-off-by: Vivek Pernamitta <vivek.pernamitta@oss.qualcomm.com> --- drivers/bus/mhi/host/pci_generic.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index 0884a384b77fc3f56fa62a12351933132ffc9293..6affef34ffc449eb48cd254bf3d8d69a49aeafdb 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -253,6 +253,13 @@ static const struct mhi_channel_config mhi_qcom_qdu100_channels[] = { MHI_CHANNEL_CONFIG_DL(41, "MHI_PHC", 32, 4), MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 256, 5), MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 256, 5), + MHI_CHANNEL_CONFIG_UL(48, "IP_SW1", 256, 6), + MHI_CHANNEL_CONFIG_DL(49, "IP_SW1", 256, 6), + MHI_CHANNEL_CONFIG_UL(50, "IP_ETH0", 256, 7), + MHI_CHANNEL_CONFIG_DL(51, "IP_ETH0", 256, 7), + MHI_CHANNEL_CONFIG_UL(52, "IP_ETH1", 256, 8), + MHI_CHANNEL_CONFIG_DL(53, "IP_ETH1", 256, 8), + }; static struct mhi_event_config mhi_qcom_qdu100_events[] = { @@ -268,6 +275,7 @@ static struct mhi_event_config mhi_qcom_qdu100_events[] = { MHI_EVENT_CONFIG_SW_DATA(5, 512), MHI_EVENT_CONFIG_SW_DATA(6, 512), MHI_EVENT_CONFIG_SW_DATA(7, 512), + MHI_EVENT_CONFIG_SW_DATA(8, 512), }; static const struct mhi_controller_config mhi_qcom_qdu100_config = { -- 2.34.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-02-11 10:25 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-05 10:34 [PATCH v7 0/2] net: mhi: Add support to enable ethernet interface Vivek Pernamitta 2026-02-05 10:34 ` [PATCH v7 1/2] net: mhi: Enable Ethernet interface support Vivek Pernamitta 2026-02-05 14:08 ` Loic Poulain 2026-02-11 10:19 ` vivek pernamitta 2026-02-10 10:43 ` Paolo Abeni 2026-02-11 10:24 ` vivek pernamitta 2026-02-05 10:34 ` [PATCH v7 2/2] bus: mhi: host: pci: Enable IP_SW1, IP_ETH0 and IP_ETH1 channels for QDU100 Vivek Pernamitta
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox