From: 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. Allocate MHI netdevs using NET_NAME_ENUM to reflect kernel-enumerated naming. This updates the reported name_assign_type for MHI net interfaces created by this driver, aligning naming semantics across existing and new devices. No functional or interface naming changes are introduced 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 --- drivers/net/mhi_net.c | 67 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c index ae169929a9d8e449b5a427993abf68e8d032fae2..aa65b267d5c06c76482eaede097c500edc1cdf7f 100644 --- a/drivers/net/mhi_net.c +++ b/drivers/net/mhi_net.c @@ -4,6 +4,7 @@ * Copyright (C) 2020 Linaro Ltd */ +#include #include #include #include @@ -42,6 +43,7 @@ struct mhi_net_dev { struct mhi_device_info { const char *netname; + bool ethernet_if; }; static int mhi_ndo_open(struct net_device *ndev) @@ -119,11 +121,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 +160,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 +236,20 @@ 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->ndev->header_ops) { + 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); @@ -306,6 +337,9 @@ static int mhi_net_newlink(struct mhi_device *mhi_dev, struct net_device *ndev) struct mhi_net_dev *mhi_netdev; int err; + if (!!ndev->header_ops) + eth_hw_addr_random(ndev); + mhi_netdev = netdev_priv(ndev); dev_set_drvdata(&mhi_dev->dev, mhi_netdev); @@ -356,7 +390,8 @@ 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; @@ -380,10 +415,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 +433,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