From: Vivek Pernamitta Rename the MHI network interface to include the device name, improving clarity when multiple MHI controllers are connected. Currently, MHI NET device interfaces are created as mhi_swip/ mhi_hwip for each channel, making it difficult to distinguish between channels when multiple EP/MHI controllers are connected. Rename the MHI interface to include the device name, for example: - Channel IP_SW0 for the 1st MHI controller will be named mhi0_IP_SW0. - Channel IP_SW0 for the 2nd MHI controller will be named mhi1_IP_SW0. - Channel IP_HW0 for the 1st MHI controller will be named mhi0_IP_HW0. Signed-off-by: Vivek Pernamitta --- drivers/net/mhi_net.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c index ae169929a9d8e449b5a427993abf68e8d032fae2..08ab67f9a769ec64e1007853e47743003a197ec4 100644 --- a/drivers/net/mhi_net.c +++ b/drivers/net/mhi_net.c @@ -351,11 +351,20 @@ static void mhi_net_dellink(struct mhi_device *mhi_dev, struct net_device *ndev) static int mhi_net_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { - const struct mhi_device_info *info = (struct mhi_device_info *)id->driver_data; + const struct mhi_device_info *info; + struct device *dev = &mhi_dev->dev; + char netname[IFNAMSIZ] = {0}; struct net_device *ndev; int err; - ndev = alloc_netdev(sizeof(struct mhi_net_dev), info->netname, + info = (struct mhi_device_info *)id->driver_data; + + if (snprintf(netname, sizeof(netname), "%s", dev_name(dev)) >= IFNAMSIZ) { + dev_err(dev, "Invalid interface name: '%s'\n", netname); + return -EINVAL; + } + + ndev = alloc_netdev(sizeof(struct mhi_net_dev), netname, NET_NAME_PREDICTABLE, mhi_net_setup); if (!ndev) return -ENOMEM; -- 2.34.1 From: Vivek Pernamitta Currently, we only have support for the NET driver. This update allows a new client to be configured as an Ethernet type over MHI by setting "mhi_device_info.ethernet_if = true". A new interface for Ethernet will be created with _. Signed-off-by: Vivek Pernamitta --- drivers/net/mhi_net.c | 84 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 13 deletions(-) diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c index 08ab67f9a769ec64e1007853e47743003a197ec4..ba65abcee32a253fc1eb9d75f1693734f4d53ee3 100644 --- a/drivers/net/mhi_net.c +++ b/drivers/net/mhi_net.c @@ -11,6 +11,7 @@ #include #include #include +#include #define MHI_NET_MIN_MTU ETH_MIN_MTU #define MHI_NET_MAX_MTU 0xffff @@ -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,37 @@ 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) +{ + int ret; + + if (dev->type == ARPHRD_ETHER) { + ret = eth_mac_addr(dev, p); + return ret; + } + + return 0; +} + +static int mhi_validate_address(struct net_device *dev) +{ + int ret; + + if (dev->type == ARPHRD_ETHER) { + ret = eth_validate_addr(dev); + return ret; + } + + 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 +169,14 @@ 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->min_mtu = ETH_MIN_MTU; + 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 +246,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 +344,17 @@ 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); + if (!is_valid_ether_addr(ndev->dev_addr)) + return -EADDRNOTAVAIL; + } + mhi_netdev = netdev_priv(ndev); dev_set_drvdata(&mhi_dev->dev, mhi_netdev); @@ -313,6 +362,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); @@ -365,13 +415,14 @@ static int mhi_net_probe(struct mhi_device *mhi_dev, } ndev = alloc_netdev(sizeof(struct mhi_net_dev), netname, - NET_NAME_PREDICTABLE, mhi_net_setup); + NET_NAME_PREDICTABLE, 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; @@ -389,10 +440,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 = "mhi_eth%d", + .ethernet_if = true, }; static const struct mhi_device_id mhi_net_id_table[] = { -- 2.34.1 From: Vivek Pernamitta Add IP_SW1, ETH0 and ETH1 network interfaces are required for M-plane, Nefconf and S-plane component. Signed-off-by: Vivek Pernamitta --- drivers/net/mhi_net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/mhi_net.c b/drivers/net/mhi_net.c index ba65abcee32a253fc1eb9d75f1693734f4d53ee3..ea3f27cbfafe54ef20f66ec0f046ce979c876217 100644 --- a/drivers/net/mhi_net.c +++ b/drivers/net/mhi_net.c @@ -458,6 +458,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 From: Vivek Pernamitta Enable IP_SW1, IP_ETH0 and IP_ETH1 channels for M-plane, NETCONF and S-plane interface for QDU100. Signed-off-by: Vivek Pernamitta --- 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 4edb5bb476baf02af02aed00be0d6bacf9e92634..1527e0b5ac24bee5d99a36ef6ab47ed619e77db9 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -263,6 +263,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[] = { @@ -278,6 +285,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