diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 98bf88a2e7f7bf615c5bb5b81003d0220a5f15ba..e4664e325ad70ba17ae46d4ac88d50eb50a94d58 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -8314,3 +8314,9 @@ CONFIG_ARCH_USE_MEMTEST=y # end of Kernel hacking CONFIG_KWORKER_NUMA_AFFINITY=y + +# +# unified bus +# +CONFIG_UB_UBL=m +# end of unified bus diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig index 4050098c07757c8d479f13d67deb38276c36b1a0..677cff9308a43f2ace8582782c1cab194dc402c3 100644 --- a/arch/x86/configs/openeuler_defconfig +++ b/arch/x86/configs/openeuler_defconfig @@ -9504,3 +9504,9 @@ CONFIG_ARCH_USE_MEMTEST=y # end of Kernel hacking CONFIG_KWORKER_NUMA_AFFINITY=y + +# +# unified bus +# +CONFIG_UB_UBL=n +# end of unified bus diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3531558c7b518ca5a8c391f02ac45a859af0f41e..ff4e041a69e0319ff313c8698edb4380e2a19f47 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -500,6 +500,8 @@ source "drivers/net/fddi/Kconfig" source "drivers/net/hippi/Kconfig" +source "drivers/net/ub/Kconfig" + source "drivers/net/ipa/Kconfig" config NET_SB1000 diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e15939e77122b922004ad98739cd9b943c053708..e089d6f441974532d9cf5f39e274b0208017664d 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -75,6 +75,7 @@ obj-$(CONFIG_WLAN) += wireless/ obj-$(CONFIG_IEEE802154) += ieee802154/ obj-$(CONFIG_WWAN) += wwan/ obj-$(CONFIG_MCTP) += mctp/ +obj-$(CONFIG_UB_UBL) += ub/ obj-$(CONFIG_VMXNET3) += vmxnet3/ obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o diff --git a/drivers/net/ub/Kconfig b/drivers/net/ub/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..ff611fba52c195e3bfdfcde799996d399a644dec --- /dev/null +++ b/drivers/net/ub/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# UBL configuration +# + +config UB_UBL + default n + tristate "UB link support" + help + This enables UB link support which is + used to replace tradtional ethernet layer. + Say 'Y' or 'm' if your device works + in UB mode. \ No newline at end of file diff --git a/drivers/net/ub/Makefile b/drivers/net/ub/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..98c1cc30bc131b517c3eaf215c38b62d7ade06f0 --- /dev/null +++ b/drivers/net/ub/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Makefile for the HISILICON network device drivers. +# + +#### compile ubl +obj-$(CONFIG_UB_UBL) += dev/ \ No newline at end of file diff --git a/drivers/net/ub/dev/Makefile b/drivers/net/ub/dev/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f7130b0da68ee04ad1d4173f42864fa1cce8b374 --- /dev/null +++ b/drivers/net/ub/dev/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Makefile for the HISILICON network device drivers. +# + +#### compile ubl +obj-$(CONFIG_UB_UBL) += ubl.o \ No newline at end of file diff --git a/drivers/net/ub/dev/ubl.c b/drivers/net/ub/dev/ubl.c new file mode 100644 index 0000000000000000000000000000000000000000..b3637476b1fbd154c47a238f1dbffcc1cab938fc --- /dev/null +++ b/drivers/net/ub/dev/ubl.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (c) 2025 HiSilicon Technologies Co., Ltd. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * UBL An implementation of the UB protocol suite for the LINUX + * operating system. + * + * UB link device handling. + * + * Version: @(#)ubl.c 1.0.1 25/09/24 + * + */ + +#include +#include +#include + +static __be16 ubl_type_to_proto(u8 type) +{ + __be16 proto; + + switch (type) { + case UB_IPV4_CFG_TYPE: + proto = htons(ETH_P_IP); + break; + case UB_IPV6_CFG_TYPE: + proto = htons(ETH_P_IPV6); + break; + case UB_NOIP_CFG_TYPE: + default: + proto = htons(ETH_P_UB); + break; + } + + return proto; +} + +/** + * ubl_add_sw_ctype - add software packet type for skb->data + * @skb: buffer to alter + * @ctype: indicates the packet type + * + * The packet type cannot be known by parsing packets from user, + * which leads to restrictions on the use of socket. + * Add sw_ctype field to indicate the packet type. And sw_ctype + * exists only during software prcessing. + * +----------+----+-----+-----------+ + * | sw_ctype | CC | NPI | L3 Packet | + * +----------+----+-----+-----------+ + */ +static int ubl_add_sw_ctype(struct sk_buff *skb, u8 ctype) +{ + u8 *pkt_cfg; + + if (skb_cow_head(skb, sizeof(u8))) + return -ENOMEM; + + pkt_cfg = (u8 *)skb_push(skb, sizeof(u8)); + *pkt_cfg = ctype; + + return 0; +} + +/** + * ubl_create_header - create the ubl header + * @skb: buffer to alter + * @dev: source device + * @type: ubl type field + * @daddr: not used in ubl + * @saddr: not used in ubl + * @len: packet length (<= skb->len) + * + */ +static int ubl_create_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned int len) +{ + struct ublhdr *ubl; + + if (type == ETH_P_IP || type == ETH_P_IPV6) { + ubl = (struct ublhdr *)skb_push(skb, UBL_HLEN); + memset(ubl, 0, sizeof(struct ublhdr)); + ubl->h_npi = htonl(UB_DEFAULT_NPI); + ubl->cfg = (type == ETH_P_IP) ? UB_IPV4_CFG_TYPE : UB_IPV6_CFG_TYPE; + return UBL_HLEN; + } else if (type == ETH_P_UB) { + return 0; + } + + return -UBL_HLEN; +} + +/** + * ubl_header_parse_protocol - parse packets protocol before sending it to + * driver. + * @skb: buffer to alter + * + * parse packets based on packet data if skb->protocol is ETH_P_ALL or 0. + */ +static __be16 ubl_header_parse_protocol(const struct sk_buff *skb) +{ + return ubl_type_to_proto(skb->data[0]); +} + +static const struct header_ops ubl_header_ops ____cacheline_aligned = { + .create = ubl_create_header, + .parse_protocol = ubl_header_parse_protocol, +}; + +/** + * ubl_setup - setup ub link network device + * @dev: network device + * + * Fill in the fields of the device structure with ubl-generic values. + */ +void ubl_setup(struct net_device *dev) +{ + dev->header_ops = &ubl_header_ops; + dev->type = ARPHRD_UB; + dev->hard_header_len = UBL_HLEN; + dev->min_header_len = UBL_HLEN; + dev->mtu = UB_DATA_LEN; + dev->min_mtu = UB_MIN_MTU; + dev->max_mtu = UB_DATA_LEN; + dev->addr_len = UBL_ALEN; + dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; + dev->flags = (IFF_NOARP | IFF_POINTOPOINT); + dev->priv_flags |= IFF_TX_SKB_SHARING; +} +EXPORT_SYMBOL(ubl_setup); + +/** + * alloc_ubldev_mqs - Allocates and sets up a ub-link device + * @sizeof_priv: Size of additional driver-private structure to be allocated + * for this ubl device + * @txqs: The number of TX queues this device has. + * @rxqs: The number of RX queues this device has. + * + * Fill in the fields of the device structure with ubl-generic + * values. Basically done everything except registering the device. + * + * Constructs a new net device, completing with a private data area of + * size (sizeof_priv). A 32-byte (not bit) alignment is enforced for + * this private data area. + */ + +struct net_device *alloc_ubldev_mqs(int sizeof_priv, unsigned int txqs, + unsigned int rxqs) +{ + return alloc_netdev_mqs(sizeof_priv, "ubl%d", NET_NAME_UNKNOWN, + ubl_setup, txqs, rxqs); +} +EXPORT_SYMBOL(alloc_ubldev_mqs); + +/** + * ubl_type_trans - obtains skb->protocol and adds sw_ptype to the packet + * @skb: buffer to alter + * @dev: source device + * @type: packet type + * + * Obtains the packet type and translates it to skb->protocol and adds sw_ptype + * to the packet data. + */ +__be16 ubl_type_trans(struct sk_buff *skb, struct net_device *dev, u8 type) +{ + skb->dev = dev; + if (ubl_add_sw_ctype(skb, type)) + net_warn_ratelimited("add sw ctype failed\n"); + + skb_reset_mac_header(skb); + if (type == UB_IPV4_CFG_TYPE || type == UB_IPV6_CFG_TYPE) + skb_pull_inline(skb, UBL_HLEN); + else if (type != UB_NOIP_CFG_TYPE) + net_warn_ratelimited("An unknown packet is received by %s, type is %u\n", + dev->name, type); + + return ubl_type_to_proto(type); +} +EXPORT_SYMBOL(ubl_type_trans); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("UB link level"); +MODULE_VERSION(UBL_MOD_VERSION); diff --git a/include/net/ub/ubl.h b/include/net/ub/ubl.h new file mode 100644 index 0000000000000000000000000000000000000000..63582e147ab774cc646b8c6edca4826d6a43de04 --- /dev/null +++ b/include/net/ub/ubl.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2023-2023 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ + +#ifndef _NET_UB_UBL_H_ +#define _NET_UB_UBL_H_ + +#include +#include +#include +#include + +#define UBL_MOD_VERSION "1.0.0" + +#define UBL_HARD_HLEN 4 +#define UBL_HLEN 7 +#define UBL_ALEN 16 + +#define UBL_LCRC_LEN 2 +#define UBL_BCRC_LEN 4 +#define UBL_LINK_LEN 2 + +#define UB_DEFAULT_NPI 1 + +#define UB_MAX_BLOCK_NUM 16 +#define UB_FLIT_NUM_OF_BLOCK 32 +#define UB_BYTE_OF_FLIT 20 +#define UB_BYTE_OF_BLK (UB_BYTE_OF_FLIT * UB_FLIT_NUM_OF_BLOCK) + +#define UB_BLOCK_CRC_LEN (UBL_BCRC_LEN + UBL_LCRC_LEN) +#define UB_MAX_MTU_PER_BLK (UB_BYTE_OF_BLK - UBL_LINK_LEN - UB_BLOCK_CRC_LEN) +#define UB_DATA_LEN 1500 +#define UB_MAX_MTU ((UB_MAX_BLOCK_NUM * UB_MAX_MTU_PER_BLK) - \ + UBL_HLEN - UBL_HARD_HLEN + UBL_LINK_LEN) +#define UB_MIN_MTU 68 + +#define UB_IPV4_CFG_TYPE 3 +#define UB_IPV6_CFG_TYPE 4 +#define UB_NOIP_CFG_TYPE 5 +#define UB_UNKNOWN_CFG_TYPE 255 + +/** + * struct ublhdr - ub link header + * @cfg: network type configuration + * @resv: reserved bit-field + * @h_cc: congestion control + * @h_npi: network partition identifier + */ +struct ublhdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 cfg : 4; + u8 resv : 4; +#else + u8 resv : 4; + u8 cfg : 4; +#endif + __be16 h_cc; + __be32 h_npi; +} __packed; + +/** + * ubl_rmv_sw_ctype - delete software packet type for skb->data + * @skb: buffer to alter + * + * Before the packet is sent to the hardware, remove sw_ctype field + * and restore the original packet. + */ +static inline void *ubl_rmv_sw_ctype(struct sk_buff *skb) +{ + return pskb_pull(skb, sizeof(u8)); +} + +void ubl_setup(struct net_device *dev); +__be16 ubl_type_trans(struct sk_buff *skb, struct net_device *dev, u8 type); +struct net_device *alloc_ubldev_mqs(int sizeof_priv, unsigned int txqs, + unsigned int rxqs); +#define alloc_ubldev_mq(sizeof_priv, count) \ + alloc_ubldev_mqs((sizeof_priv), (count), (count)) + +#endif diff --git a/include/uapi/linux/if_arp.h b/include/uapi/linux/if_arp.h index 4783af9fe5200225044b221cd4499359900669cd..ed514ed01268df24fe960ce7b9fb81493e624a25 100644 --- a/include/uapi/linux/if_arp.h +++ b/include/uapi/linux/if_arp.h @@ -43,6 +43,8 @@ #define ARPHRD_EUI64 27 /* EUI-64 */ #define ARPHRD_INFINIBAND 32 /* InfiniBand */ +#define ARPHRD_UB 38 /* Unified bus */ + /* Dummy types for non ARP hardware */ #define ARPHRD_SLIP 256 #define ARPHRD_CSLIP 257 diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 69e0457eb2000dfda7b96fd4b1daff93f7970f9f..065ca4e2d3c4b25c122e2b5e1c4962ed524a72a9 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h @@ -159,6 +159,7 @@ #define ETH_P_MCTP 0x00FA /* Management component transport * protocol packets */ +#define ETH_P_UB 0x0100 /* Network control packet of Unified Bus */ /* * This is an Ethernet frame header.