Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/hfi1: Remove opa_vnic

OPA Vnic has been abandoned and left to rot. Time to excise.

Signed-off-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
Link: https://patch.msgid.link/177308912950.1280237.15051663328388849915.stgit@awdrv-04.cornelisnetworks.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Dennis Dalessandro and committed by
Leon Romanovsky
1b50f420 2afa8b9f

+20 -4976
-15
Documentation/driver-api/infiniband.rst
··· 92 92 .. kernel-doc:: drivers/infiniband/ulp/iser/iser_verbs.c 93 93 :internal: 94 94 95 - Omni-Path (OPA) Virtual NIC support 96 - ----------------------------------- 97 - 98 - .. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_internal.h 99 - :internal: 100 - 101 - .. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h 102 - :internal: 103 - 104 - .. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c 105 - :internal: 106 - 107 - .. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c 108 - :internal: 109 - 110 95 InfiniBand SCSI RDMA protocol target support 111 96 -------------------------------------------- 112 97
-1
Documentation/infiniband/index.rst
··· 9 9 10 10 core_locking 11 11 ipoib 12 - opa_vnic 13 12 sysfs 14 13 tag_matching 15 14 ucaps
-159
Documentation/infiniband/opa_vnic.rst
··· 1 - ================================================================= 2 - Intel Omni-Path (OPA) Virtual Network Interface Controller (VNIC) 3 - ================================================================= 4 - 5 - Intel Omni-Path (OPA) Virtual Network Interface Controller (VNIC) feature 6 - supports Ethernet functionality over Omni-Path fabric by encapsulating 7 - the Ethernet packets between HFI nodes. 8 - 9 - Architecture 10 - ============= 11 - The patterns of exchanges of Omni-Path encapsulated Ethernet packets 12 - involves one or more virtual Ethernet switches overlaid on the Omni-Path 13 - fabric topology. A subset of HFI nodes on the Omni-Path fabric are 14 - permitted to exchange encapsulated Ethernet packets across a particular 15 - virtual Ethernet switch. The virtual Ethernet switches are logical 16 - abstractions achieved by configuring the HFI nodes on the fabric for 17 - header generation and processing. In the simplest configuration all HFI 18 - nodes across the fabric exchange encapsulated Ethernet packets over a 19 - single virtual Ethernet switch. A virtual Ethernet switch, is effectively 20 - an independent Ethernet network. The configuration is performed by an 21 - Ethernet Manager (EM) which is part of the trusted Fabric Manager (FM) 22 - application. HFI nodes can have multiple VNICs each connected to a 23 - different virtual Ethernet switch. The below diagram presents a case 24 - of two virtual Ethernet switches with two HFI nodes:: 25 - 26 - +-------------------+ 27 - | Subnet/ | 28 - | Ethernet | 29 - | Manager | 30 - +-------------------+ 31 - / / 32 - / / 33 - / / 34 - / / 35 - +-----------------------------+ +------------------------------+ 36 - | Virtual Ethernet Switch | | Virtual Ethernet Switch | 37 - | +---------+ +---------+ | | +---------+ +---------+ | 38 - | | VPORT | | VPORT | | | | VPORT | | VPORT | | 39 - +--+---------+----+---------+-+ +-+---------+----+---------+---+ 40 - | \ / | 41 - | \ / | 42 - | \/ | 43 - | / \ | 44 - | / \ | 45 - +-----------+------------+ +-----------+------------+ 46 - | VNIC | VNIC | | VNIC | VNIC | 47 - +-----------+------------+ +-----------+------------+ 48 - | HFI | | HFI | 49 - +------------------------+ +------------------------+ 50 - 51 - 52 - The Omni-Path encapsulated Ethernet packet format is as described below. 53 - 54 - ==================== ================================ 55 - Bits Field 56 - ==================== ================================ 57 - Quad Word 0: 58 - 0-19 SLID (lower 20 bits) 59 - 20-30 Length (in Quad Words) 60 - 31 BECN bit 61 - 32-51 DLID (lower 20 bits) 62 - 52-56 SC (Service Class) 63 - 57-59 RC (Routing Control) 64 - 60 FECN bit 65 - 61-62 L2 (=10, 16B format) 66 - 63 LT (=1, Link Transfer Head Flit) 67 - 68 - Quad Word 1: 69 - 0-7 L4 type (=0x78 ETHERNET) 70 - 8-11 SLID[23:20] 71 - 12-15 DLID[23:20] 72 - 16-31 PKEY 73 - 32-47 Entropy 74 - 48-63 Reserved 75 - 76 - Quad Word 2: 77 - 0-15 Reserved 78 - 16-31 L4 header 79 - 32-63 Ethernet Packet 80 - 81 - Quad Words 3 to N-1: 82 - 0-63 Ethernet packet (pad extended) 83 - 84 - Quad Word N (last): 85 - 0-23 Ethernet packet (pad extended) 86 - 24-55 ICRC 87 - 56-61 Tail 88 - 62-63 LT (=01, Link Transfer Tail Flit) 89 - ==================== ================================ 90 - 91 - Ethernet packet is padded on the transmit side to ensure that the VNIC OPA 92 - packet is quad word aligned. The 'Tail' field contains the number of bytes 93 - padded. On the receive side the 'Tail' field is read and the padding is 94 - removed (along with ICRC, Tail and OPA header) before passing packet up 95 - the network stack. 96 - 97 - The L4 header field contains the virtual Ethernet switch id the VNIC port 98 - belongs to. On the receive side, this field is used to de-multiplex the 99 - received VNIC packets to different VNIC ports. 100 - 101 - Driver Design 102 - ============== 103 - Intel OPA VNIC software design is presented in the below diagram. 104 - OPA VNIC functionality has a HW dependent component and a HW 105 - independent component. 106 - 107 - The support has been added for IB device to allocate and free the RDMA 108 - netdev devices. The RDMA netdev supports interfacing with the network 109 - stack thus creating standard network interfaces. OPA_VNIC is an RDMA 110 - netdev device type. 111 - 112 - The HW dependent VNIC functionality is part of the HFI1 driver. It 113 - implements the verbs to allocate and free the OPA_VNIC RDMA netdev. 114 - It involves HW resource allocation/management for VNIC functionality. 115 - It interfaces with the network stack and implements the required 116 - net_device_ops functions. It expects Omni-Path encapsulated Ethernet 117 - packets in the transmit path and provides HW access to them. It strips 118 - the Omni-Path header from the received packets before passing them up 119 - the network stack. It also implements the RDMA netdev control operations. 120 - 121 - The OPA VNIC module implements the HW independent VNIC functionality. 122 - It consists of two parts. The VNIC Ethernet Management Agent (VEMA) 123 - registers itself with IB core as an IB client and interfaces with the 124 - IB MAD stack. It exchanges the management information with the Ethernet 125 - Manager (EM) and the VNIC netdev. The VNIC netdev part allocates and frees 126 - the OPA_VNIC RDMA netdev devices. It overrides the net_device_ops functions 127 - set by HW dependent VNIC driver where required to accommodate any control 128 - operation. It also handles the encapsulation of Ethernet packets with an 129 - Omni-Path header in the transmit path. For each VNIC interface, the 130 - information required for encapsulation is configured by the EM via VEMA MAD 131 - interface. It also passes any control information to the HW dependent driver 132 - by invoking the RDMA netdev control operations:: 133 - 134 - +-------------------+ +----------------------+ 135 - | | | Linux | 136 - | IB MAD | | Network | 137 - | | | Stack | 138 - +-------------------+ +----------------------+ 139 - | | | 140 - | | | 141 - +----------------------------+ | 142 - | | | 143 - | OPA VNIC Module | | 144 - | (OPA VNIC RDMA Netdev | | 145 - | & EMA functions) | | 146 - | | | 147 - +----------------------------+ | 148 - | | 149 - | | 150 - +------------------+ | 151 - | IB core | | 152 - +------------------+ | 153 - | | 154 - | | 155 - +--------------------------------------------+ 156 - | | 157 - | HFI1 Driver with VNIC support | 158 - | | 159 - +--------------------------------------------+
-1
Documentation/translations/zh_CN/infiniband/index.rst
··· 24 24 25 25 core_locking 26 26 ipoib 27 - opa_vnic 28 27 sysfs 29 28 tag_matching 30 29 user_mad
-156
Documentation/translations/zh_CN/infiniband/opa_vnic.rst
··· 1 - .. include:: ../disclaimer-zh_CN.rst 2 - 3 - :Original: Documentation/infiniband/opa_vnic.rst 4 - 5 - :翻译: 6 - 7 - 司延腾 Yanteng Si <siyanteng@loongson.cn> 8 - 9 - :校译: 10 - 11 - 王普宇 Puyu Wang <realpuyuwang@gmail.com> 12 - 时奎亮 Alex Shi <alexs@kernel.org> 13 - 14 - .. _cn_infiniband_opa_vnic: 15 - 16 - ============================================= 17 - 英特尔全路径(OPA)虚拟网络接口控制器(VNIC) 18 - ============================================= 19 - 20 - 英特尔全路径(OPA)虚拟网络接口控制器(VNIC)功能通过封装HFI节点之间的以 21 - 太网数据包,支持Omni-Path结构上的以太网功能。 22 - 23 - 体系结构 24 - ======== 25 - 26 - Omni-Path封装的以太网数据包的交换模式涉及Omni-Path结构拓扑上覆盖的一个或 27 - 多个虚拟以太网交换机。Omni-Path结构上的HFI节点的一个子集被允许在特定的虚 28 - 拟以太网交换机上交换封装的以太网数据包。虚拟以太网交换机是通过配置结构上的 29 - HFI节点实现的逻辑抽象,用于生成和处理报头。在最简单的配置中,整个结构的所有 30 - HFI节点通过一个虚拟以太网交换机交换封装的以太网数据包。一个虚拟以太网交换机, 31 - 实际上是一个独立的以太网网络。该配置由以太网管理器(EM)执行,它是可信的结 32 - 构管理器(FM)应用程序的一部分。HFI节点可以有多个VNIC,每个连接到不同的虚 33 - 拟以太网交换机。下图介绍了两个虚拟以太网交换机与两个HFI节点的情况:: 34 - 35 - +-------------------+ 36 - | 子网/ | 37 - | 以太网 | 38 - | 管理 | 39 - +-------------------+ 40 - / / 41 - / / 42 - / / 43 - / / 44 - +-----------------------------+ +------------------------------+ 45 - | 虚拟以太网切换 | | 虚拟以太网切换 | 46 - | +---------+ +---------+ | | +---------+ +---------+ | 47 - | | VPORT | | VPORT | | | | VPORT | | VPORT | | 48 - +--+---------+----+---------+-+ +-+---------+----+---------+---+ 49 - | \ / | 50 - | \ / | 51 - | \/ | 52 - | / \ | 53 - | / \ | 54 - +-----------+------------+ +-----------+------------+ 55 - | VNIC | VNIC | | VNIC | VNIC | 56 - +-----------+------------+ +-----------+------------+ 57 - | HFI | | HFI | 58 - +------------------------+ +------------------------+ 59 - 60 - 61 - Omni-Path封装的以太网数据包格式如下所述。 62 - 63 - ==================== ================================ 64 - 位 域 65 - ==================== ================================ 66 - Quad Word 0: 67 - 0-19 SLID (低20位) 68 - 20-30 长度 (以四字为单位) 69 - 31 BECN 位 70 - 32-51 DLID (低20位) 71 - 52-56 SC (服务级别) 72 - 57-59 RC (路由控制) 73 - 60 FECN 位 74 - 61-62 L2 (=10, 16B 格式) 75 - 63 LT (=1, 链路传输头 Flit) 76 - 77 - Quad Word 1: 78 - 0-7 L4 type (=0x78 ETHERNET) 79 - 8-11 SLID[23:20] 80 - 12-15 DLID[23:20] 81 - 16-31 PKEY 82 - 32-47 熵 83 - 48-63 保留 84 - 85 - Quad Word 2: 86 - 0-15 保留 87 - 16-31 L4 头 88 - 32-63 以太网数据包 89 - 90 - Quad Words 3 to N-1: 91 - 0-63 以太网数据包 (pad拓展) 92 - 93 - Quad Word N (last): 94 - 0-23 以太网数据包 (pad拓展) 95 - 24-55 ICRC 96 - 56-61 尾 97 - 62-63 LT (=01, 链路传输尾 Flit) 98 - ==================== ================================ 99 - 100 - 以太网数据包在传输端被填充,以确保VNIC OPA数据包是四字对齐的。“尾”字段 101 - 包含填充的字节数。在接收端,“尾”字段被读取,在将数据包向上传递到网络堆 102 - 栈之前,填充物被移除(与ICRC、尾和OPA头一起)。 103 - 104 - L4头字段包含VNIC端口所属的虚拟以太网交换机ID。在接收端,该字段用于将收 105 - 到的VNIC数据包去多路复用到不同的VNIC端口。 106 - 107 - 驱动设计 108 - ======== 109 - 110 - 英特尔OPA VNIC的软件设计如下图所示。OPA VNIC功能有一个依赖于硬件的部分 111 - 和一个独立于硬件的部分。 112 - 113 - 对IB设备分配和释放RDMA netdev设备的支持已经被加入。RDMA netdev支持与 114 - 网络堆栈的对接,从而创建标准的网络接口。OPA_VNIC是一个RDMA netdev设备 115 - 类型。 116 - 117 - 依赖于HW的VNIC功能是HFI1驱动的一部分。它实现了分配和释放OPA_VNIC RDMA 118 - netdev的动作。它涉及VNIC功能的HW资源分配/管理。它与网络堆栈接口并实现所 119 - 需的net_device_ops功能。它在传输路径中期待Omni-Path封装的以太网数据包, 120 - 并提供对它们的HW访问。在将数据包向上传递到网络堆栈之前,它把Omni-Path头 121 - 从接收的数据包中剥离。它还实现了RDMA netdev控制操作。 122 - 123 - OPA VNIC模块实现了独立于硬件的VNIC功能。它由两部分组成。VNIC以太网管理 124 - 代理(VEMA)作为一个IB客户端向IB核心注册,并与IB MAD栈接口。它与以太网 125 - 管理器(EM)和VNIC netdev交换管理信息。VNIC netdev部分分配和释放OPA_VNIC 126 - RDMA netdev设备。它在需要时覆盖由依赖HW的VNIC驱动设置的net_device_ops函数, 127 - 以适应任何控制操作。它还处理以太网数据包的封装,在传输路径中使用Omni-Path头。 128 - 对于每个VNIC接口,封装所需的信息是由EM通过VEMA MAD接口配置的。它还通过调用 129 - RDMA netdev控制操作将任何控制信息传递给依赖于HW的驱动程序:: 130 - 131 - +-------------------+ +----------------------+ 132 - | | | Linux | 133 - | IB MAD | | 网络 | 134 - | | | 栈 | 135 - +-------------------+ +----------------------+ 136 - | | | 137 - | | | 138 - +----------------------------+ | 139 - | | | 140 - | OPA VNIC 模块 | | 141 - | (OPA VNIC RDMA Netdev | | 142 - | & EMA 函数) | | 143 - | | | 144 - +----------------------------+ | 145 - | | 146 - | | 147 - +------------------+ | 148 - | IB 核心 | | 149 - +------------------+ | 150 - | | 151 - | | 152 - +--------------------------------------------+ 153 - | | 154 - | HFI1 驱动和 VNIC 支持 | 155 - | | 156 - +--------------------------------------------+
-6
MAINTAINERS
··· 19764 19764 S: Maintained 19765 19765 F: drivers/rtc/rtc-optee.c 19766 19766 19767 - OPA-VNIC DRIVER 19768 - M: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> 19769 - L: linux-rdma@vger.kernel.org 19770 - S: Supported 19771 - F: drivers/infiniband/ulp/opa_vnic 19772 - 19773 19767 OPEN ALLIANCE 10BASE-T1S MACPHY SERIAL INTERFACE FRAMEWORK 19774 19768 M: Parthiban Veerasooran <parthiban.veerasooran@microchip.com> 19775 19769 L: netdev@vger.kernel.org
-2
drivers/infiniband/Kconfig
··· 112 112 source "drivers/infiniband/ulp/isert/Kconfig" 113 113 source "drivers/infiniband/ulp/rtrs/Kconfig" 114 114 115 - source "drivers/infiniband/ulp/opa_vnic/Kconfig" 116 - 117 115 endif # INFINIBAND
+1 -3
drivers/infiniband/hw/hfi1/Makefile
··· 49 49 user_pages.o \ 50 50 user_sdma.o \ 51 51 verbs.o \ 52 - verbs_txreq.o \ 53 - vnic_main.o \ 54 - vnic_sdma.o 52 + verbs_txreq.o 55 53 56 54 ifdef CONFIG_DEBUG_FS 57 55 hfi1-y += debugfs.o
+1 -1
drivers/infiniband/hw/hfi1/aspm.c
··· 179 179 } 180 180 181 181 /* 182 - * Disable interrupt processing for verbs contexts when PSM or VNIC contexts 182 + * Disable interrupt processing for verbs contexts when PSM contexts 183 183 * are open. 184 184 */ 185 185 void aspm_disable_all(struct hfi1_devdata *dd)
+7 -47
drivers/infiniband/hw/hfi1/chip.c
··· 85 85 /* 86 86 * RSM instance allocation 87 87 * 0 - User Fecn Handling 88 - * 1 - Vnic 88 + * 1 - Deprecated 89 89 * 2 - AIP 90 90 * 3 - Verbs 91 91 */ 92 92 #define RSM_INS_FECN 0 93 - #define RSM_INS_VNIC 1 93 + #define RSM_INS_DEPRECATED 1 94 94 #define RSM_INS_AIP 2 95 95 #define RSM_INS_VERBS 3 96 96 ··· 151 151 #define DETH_AIP_SQPN_OFFSET(off) ((DETH_AIP_SQPN_QW << QW_SHIFT) | (off)) 152 152 #define DETH_AIP_SQPN_SELECT_OFFSET \ 153 153 DETH_AIP_SQPN_OFFSET(DETH_AIP_SQPN_BIT_OFFSET) 154 - 155 - /* RSM fields for Vnic */ 156 - /* L2_TYPE: QW 0, OFFSET 61 - for match */ 157 - #define L2_TYPE_QW 0ull 158 - #define L2_TYPE_BIT_OFFSET 61ull 159 - #define L2_TYPE_OFFSET(off) ((L2_TYPE_QW << QW_SHIFT) | (off)) 160 - #define L2_TYPE_MATCH_OFFSET L2_TYPE_OFFSET(L2_TYPE_BIT_OFFSET) 161 - #define L2_TYPE_MASK 3ull 162 - #define L2_16B_VALUE 2ull 163 154 164 155 /* L4_TYPE QW 1, OFFSET 0 - for match */ 165 156 #define L4_TYPE_QW 1ull ··· 6835 6844 for (i = 0; i < dd->num_rcv_contexts; i++) { 6836 6845 rcd = hfi1_rcd_get_by_index(dd, i); 6837 6846 6838 - /* Ensure all non-user contexts(including vnic) are enabled */ 6847 + /* Ensure all non-user contexts are enabled */ 6839 6848 if (!rcd || 6840 - (i >= dd->first_dyn_alloc_ctxt && !rcd->is_vnic)) { 6849 + (i >= dd->first_dyn_alloc_ctxt)) { 6841 6850 hfi1_rcd_put(rcd); 6842 6851 continue; 6843 6852 } ··· 8458 8467 return work_done; 8459 8468 } 8460 8469 8461 - /* Receive packet napi handler for netdevs VNIC and AIP */ 8470 + /* Receive packet napi handler for netdevs AIP */ 8462 8471 irqreturn_t receive_context_interrupt_napi(int irq, void *data) 8463 8472 { 8464 8473 struct hfi1_ctxtdata *rcd = data; ··· 14497 14506 int ctxt_count = hfi1_netdev_ctxt_count(dd); 14498 14507 14499 14508 /* We already have contexts mapped in RMT */ 14500 - if (has_rsm_rule(dd, RSM_INS_VNIC) || has_rsm_rule(dd, RSM_INS_AIP)) { 14509 + if (has_rsm_rule(dd, RSM_INS_AIP)) { 14501 14510 dd_dev_info(dd, "Contexts are already mapped in RMT\n"); 14502 14511 return true; 14503 14512 } ··· 14576 14585 14577 14586 hfi1_enable_rsm_rule(dd, RSM_INS_AIP, &rrd); 14578 14587 } 14579 - } 14580 - 14581 - /* Initialize RSM for VNIC */ 14582 - void hfi1_init_vnic_rsm(struct hfi1_devdata *dd) 14583 - { 14584 - int rmt_start = hfi1_netdev_get_free_rmt_idx(dd); 14585 - struct rsm_rule_data rrd = { 14586 - /* Add rule for vnic */ 14587 - .offset = rmt_start, 14588 - .pkt_type = 4, 14589 - /* Match 16B packets */ 14590 - .field1_off = L2_TYPE_MATCH_OFFSET, 14591 - .mask1 = L2_TYPE_MASK, 14592 - .value1 = L2_16B_VALUE, 14593 - /* Match ETH L4 packets */ 14594 - .field2_off = L4_TYPE_MATCH_OFFSET, 14595 - .mask2 = L4_16B_TYPE_MASK, 14596 - .value2 = L4_16B_ETH_VALUE, 14597 - /* Calc context from veswid and entropy */ 14598 - .index1_off = L4_16B_HDR_VESWID_OFFSET, 14599 - .index1_width = ilog2(NUM_NETDEV_MAP_ENTRIES), 14600 - .index2_off = L2_16B_ENTROPY_OFFSET, 14601 - .index2_width = ilog2(NUM_NETDEV_MAP_ENTRIES) 14602 - }; 14603 - 14604 - hfi1_enable_rsm_rule(dd, RSM_INS_VNIC, &rrd); 14605 - } 14606 - 14607 - void hfi1_deinit_vnic_rsm(struct hfi1_devdata *dd) 14608 - { 14609 - clear_rsm_rule(dd, RSM_INS_VNIC); 14610 14588 } 14611 14589 14612 14590 void hfi1_deinit_aip_rsm(struct hfi1_devdata *dd) ··· 15155 15195 (dd->revision >> CCE_REVISION_SW_SHIFT) 15156 15196 & CCE_REVISION_SW_MASK); 15157 15197 15158 - /* alloc VNIC/AIP rx data */ 15198 + /* alloc AIP rx data */ 15159 15199 ret = hfi1_alloc_rx(dd); 15160 15200 if (ret) 15161 15201 goto bail_cleanup;
-2
drivers/infiniband/hw/hfi1/chip.h
··· 1392 1392 u16 pkey); 1393 1393 int hfi1_clear_ctxt_pkey(struct hfi1_devdata *dd, struct hfi1_ctxtdata *ctxt); 1394 1394 void hfi1_read_link_quality(struct hfi1_devdata *dd, u8 *link_quality); 1395 - void hfi1_init_vnic_rsm(struct hfi1_devdata *dd); 1396 - void hfi1_deinit_vnic_rsm(struct hfi1_devdata *dd); 1397 1395 1398 1396 irqreturn_t general_interrupt(int irq, void *data); 1399 1397 irqreturn_t sdma_interrupt(int irq, void *data);
+6 -7
drivers/infiniband/hw/hfi1/driver.c
··· 20 20 #include "qp.h" 21 21 #include "sdma.h" 22 22 #include "debugfs.h" 23 - #include "vnic.h" 24 23 #include "fault.h" 25 24 26 25 #include "ipoib.h" ··· 908 909 u16 i; 909 910 910 911 /* 911 - * For dynamically allocated kernel contexts (like vnic) switch 912 + * For dynamically allocated kernel contexts switch 912 913 * interrupt handler only for that context. Otherwise, switch 913 914 * interrupt handler for all statically allocated kernel contexts. 914 915 */ 915 - if (rcd->ctxt >= dd->first_dyn_alloc_ctxt && !rcd->is_vnic) { 916 + if (rcd->ctxt >= dd->first_dyn_alloc_ctxt) { 916 917 hfi1_rcd_get(rcd); 917 918 hfi1_set_fast(rcd); 918 919 hfi1_rcd_put(rcd); ··· 921 922 922 923 for (i = HFI1_CTRL_CTXT + 1; i < dd->num_rcv_contexts; i++) { 923 924 rcd = hfi1_rcd_get_by_index(dd, i); 924 - if (rcd && (i < dd->first_dyn_alloc_ctxt || rcd->is_vnic)) 925 + if (rcd && (i < dd->first_dyn_alloc_ctxt)) 925 926 hfi1_set_fast(rcd); 926 927 hfi1_rcd_put(rcd); 927 928 } ··· 937 938 rcd = hfi1_rcd_get_by_index(dd, i); 938 939 if (!rcd) 939 940 continue; 940 - if (i < dd->first_dyn_alloc_ctxt || rcd->is_vnic) 941 + if (i < dd->first_dyn_alloc_ctxt) 941 942 rcd->do_interrupt = rcd->slow_handler; 942 943 943 944 hfi1_rcd_put(rcd); ··· 1399 1400 goto bail; 1400 1401 } 1401 1402 1402 - /* If there are any user/vnic contexts, we cannot reset */ 1403 + /* If there are any user contexts, we cannot reset */ 1403 1404 mutex_lock(&hfi1_mutex); 1404 1405 if (dd->rcd) 1405 1406 if (hfi1_stats.sps_ctxts) { ··· 1898 1899 [RHF_RCV_TYPE_EAGER] = process_receive_invalid, 1899 1900 [RHF_RCV_TYPE_IB] = hfi1_ipoib_ib_rcv, 1900 1901 [RHF_RCV_TYPE_ERROR] = process_receive_error, 1901 - [RHF_RCV_TYPE_BYPASS] = hfi1_vnic_bypass_rcv, 1902 + [RHF_RCV_TYPE_BYPASS] = process_receive_invalid, 1902 1903 [RHF_RCV_TYPE_INVALID5] = process_receive_invalid, 1903 1904 [RHF_RCV_TYPE_INVALID6] = process_receive_invalid, 1904 1905 [RHF_RCV_TYPE_INVALID7] = process_receive_invalid,
-20
drivers/infiniband/hw/hfi1/hfi.h
··· 212 212 u8 rhf_offset; 213 213 /* dynamic receive available interrupt timeout */ 214 214 u8 rcvavail_timeout; 215 - /* Indicates that this is vnic context */ 216 - bool is_vnic; 217 - /* vnic queue index this context is mapped to */ 218 - u8 vnic_q_idx; 219 215 /* Is ASPM interrupt supported for this context */ 220 216 bool aspm_intr_supported; 221 217 /* ASPM state (enabled/disabled) for this context */ ··· 398 402 #define OPA_16B_L4_FM 0x08 399 403 #define OPA_16B_L4_IB_LOCAL 0x09 400 404 #define OPA_16B_L4_IB_GLOBAL 0x0A 401 - #define OPA_16B_L4_ETHR OPA_VNIC_L4_ETHR 402 405 403 406 /* 404 407 * OPA 16B Management ··· 992 997 #define NUM_MAP_ENTRIES 256 993 998 #define NUM_MAP_REGS 32 994 999 995 - /* Virtual NIC information */ 996 - struct hfi1_vnic_data { 997 - struct kmem_cache *txreq_cache; 998 - u8 num_vports; 999 - }; 1000 - 1001 - struct hfi1_vnic_vport_info; 1002 - 1003 1000 /* device data struct now contains only "general per-device" info. 1004 1001 * fields related to a physical IB port are in a hfi1_pportdata struct. 1005 1002 */ ··· 1285 1298 send_routine process_dma_send; 1286 1299 void (*pio_inline_send)(struct hfi1_devdata *dd, struct pio_buf *pbuf, 1287 1300 u64 pbc, const void *from, size_t count); 1288 - int (*process_vnic_dma_send)(struct hfi1_devdata *dd, u8 q_idx, 1289 - struct hfi1_vnic_vport_info *vinfo, 1290 - struct sk_buff *skb, u64 pbc, u8 plen); 1291 1301 /* hfi1_pportdata, points to array of (physical) port-specific 1292 1302 * data structs, indexed by pidx (0..n-1) 1293 1303 */ ··· 1298 1314 u16 flags; 1299 1315 /* Number of physical ports available */ 1300 1316 u8 num_pports; 1301 - /* Lowest context number which can be used by user processes or VNIC */ 1302 1317 u8 first_dyn_alloc_ctxt; 1303 1318 /* adding a new field here would make it part of this cacheline */ 1304 1319 ··· 1336 1353 bool aspm_enabled; /* ASPM state: enabled/disabled */ 1337 1354 struct rhashtable *sdma_rht; 1338 1355 1339 - /* vnic data */ 1340 - struct hfi1_vnic_data vnic; 1341 1356 /* Lock to protect IRQ SRC register access */ 1342 1357 spinlock_t irq_src_lock; 1343 - int vnic_num_vports; 1344 1358 struct hfi1_netdev_rx *netdev_rx; 1345 1359 struct hfi1_affinity_node *affinity_entry; 1346 1360
+1 -3
drivers/infiniband/hw/hfi1/init.c
··· 26 26 #include "verbs.h" 27 27 #include "aspm.h" 28 28 #include "affinity.h" 29 - #include "vnic.h" 30 29 #include "exp_rcv.h" 31 30 #include "netdev.h" 32 31 ··· 348 349 * We do this here because we have to take into account all 349 350 * the RcvArray entries that previous context would have 350 351 * taken and we have to account for any extra groups assigned 351 - * to the static (kernel) or dynamic (vnic/user) contexts. 352 + * to the static (kernel) or dynamic (user) contexts. 352 353 */ 353 354 if (ctxt < dd->first_dyn_alloc_ctxt) { 354 355 if (ctxt < kctxt_ngroups) { ··· 850 851 dd->process_pio_send = hfi1_verbs_send_pio; 851 852 dd->process_dma_send = hfi1_verbs_send_dma; 852 853 dd->pio_inline_send = pio_copy; 853 - dd->process_vnic_dma_send = hfi1_vnic_send_dma; 854 854 855 855 if (is_ax(dd)) { 856 856 atomic_set(&dd->drop_packet, DROP_PACKET_ON);
-1
drivers/infiniband/hw/hfi1/mad.c
··· 12 12 #include "mad.h" 13 13 #include "trace.h" 14 14 #include "qp.h" 15 - #include "vnic.h" 16 15 17 16 /* the reset value from the FM is supposed to be 0xffff, handle both */ 18 17 #define OPA_LINK_WIDTH_RESET_OLD 0x0fff
+1 -3
drivers/infiniband/hw/hfi1/msix.c
··· 24 24 * one for the general, "slow path" interrupt 25 25 * one per used SDMA engine 26 26 * one per kernel receive context 27 - * one for each VNIC context 28 27 * ...any new IRQs should be added here. 29 28 */ 30 29 total = 1 + dd->num_sdma + dd->n_krcv_queues + dd->num_netdev_contexts; ··· 126 127 irq_handler_t thread, 127 128 const char *name) 128 129 { 129 - int nr = msix_request_irq(rcd->dd, rcd, handler, thread, 130 - rcd->is_vnic ? IRQ_NETDEVCTXT : IRQ_RCVCTXT, 130 + int nr = msix_request_irq(rcd->dd, rcd, handler, thread, IRQ_RCVCTXT, 131 131 name); 132 132 if (nr < 0) 133 133 return nr;
+2 -6
drivers/infiniband/hw/hfi1/netdev.h
··· 14 14 15 15 /** 16 16 * struct hfi1_netdev_rxq - Receive Queue for HFI 17 - * Both IPoIB and VNIC netdevices will be working on the rx abstraction. 17 + * IPoIB netdevices will be working on the rx abstraction. 18 18 * @napi: napi object 19 19 * @rx: ptr to netdev_rx 20 20 * @rcd: ptr to receive context data ··· 25 25 struct hfi1_ctxtdata *rcd; 26 26 }; 27 27 28 - /* 29 - * Number of netdev contexts used. Ensure it is less than or equal to 30 - * max queues supported by VNIC (HFI1_VNIC_MAX_QUEUE). 31 - */ 32 28 #define HFI1_MAX_NETDEV_CTXTS 8 33 29 34 30 /* Number of NETDEV RSM entries */ ··· 38 42 * @num_rx_q: number of receive queues 39 43 * @rmt_index: first free index in RMT Array 40 44 * @msix_start: first free MSI-X interrupt vector. 41 - * @dev_tbl: netdev table for unique identifier VNIC and IPoIb VLANs. 45 + * @dev_tbl: netdev table for unique identifier IPoIb VLANs. 42 46 * @enabled: atomic counter of netdevs enabling receive queues. 43 47 * When 0 NAPI will be disabled. 44 48 * @netdevs: atomic counter of netdevs using dummy netdev.
+1 -2
drivers/infiniband/hw/hfi1/netdev_rx.c
··· 78 78 uctxt->fast_handler = handle_receive_interrupt_napi_fp; 79 79 uctxt->slow_handler = handle_receive_interrupt_napi_sp; 80 80 hfi1_set_seq_cnt(uctxt, 1); 81 - uctxt->is_vnic = true; 82 81 83 82 hfi1_stats.sps_ctxts++; 84 83 ··· 426 427 427 428 /** 428 429 * hfi1_netdev_add_data - Registers data with unique identifier 429 - * to be requested later this is needed for VNIC and IPoIB VLANs 430 + * to be requested later this is needed for IPoIB VLANs 430 431 * implementations. 431 432 * This call is protected by mutex idr_lock. 432 433 *
-2
drivers/infiniband/hw/hfi1/verbs.c
··· 21 21 #include "qp.h" 22 22 #include "verbs_txreq.h" 23 23 #include "debugfs.h" 24 - #include "vnic.h" 25 24 #include "fault.h" 26 25 #include "affinity.h" 27 26 #include "ipoib.h" ··· 1728 1729 1729 1730 .alloc_hw_device_stats = hfi1_alloc_hw_device_stats, 1730 1731 .alloc_hw_port_stats = hfi_alloc_hw_port_stats, 1731 - .alloc_rdma_netdev = hfi1_vnic_alloc_rn, 1732 1732 .device_group = &ib_hfi1_attr_group, 1733 1733 .get_dev_fw_str = hfi1_get_dev_fw_str, 1734 1734 .get_hw_stats = get_hw_stats,
-126
drivers/infiniband/hw/hfi1/vnic.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 - /* 3 - * Copyright(c) 2017 - 2020 Intel Corporation. 4 - */ 5 - 6 - #ifndef _HFI1_VNIC_H 7 - #define _HFI1_VNIC_H 8 - #include <rdma/opa_vnic.h> 9 - #include "hfi.h" 10 - #include "sdma.h" 11 - 12 - #define HFI1_VNIC_MAX_TXQ 16 13 - #define HFI1_VNIC_MAX_PAD 12 14 - 15 - /* L4 header definitions */ 16 - #define HFI1_VNIC_L4_HDR_OFFSET OPA_VNIC_L2_HDR_LEN 17 - 18 - #define HFI1_VNIC_GET_L4_HDR(data) \ 19 - (*((u16 *)((u8 *)(data) + HFI1_VNIC_L4_HDR_OFFSET))) 20 - 21 - #define HFI1_VNIC_GET_VESWID(data) \ 22 - (HFI1_VNIC_GET_L4_HDR(data) & 0xFFF) 23 - 24 - /* Service class */ 25 - #define HFI1_VNIC_SC_OFFSET_LOW 6 26 - #define HFI1_VNIC_SC_OFFSET_HI 7 27 - #define HFI1_VNIC_SC_SHIFT 4 28 - 29 - #define HFI1_VNIC_MAX_QUEUE 16 30 - #define HFI1_NUM_VNIC_CTXT 8 31 - 32 - /** 33 - * struct hfi1_vnic_sdma - VNIC per Tx ring SDMA information 34 - * @dd - device data pointer 35 - * @sde - sdma engine 36 - * @vinfo - vnic info pointer 37 - * @wait - iowait structure 38 - * @stx - sdma tx request 39 - * @state - vnic Tx ring SDMA state 40 - * @q_idx - vnic Tx queue index 41 - */ 42 - struct hfi1_vnic_sdma { 43 - struct hfi1_devdata *dd; 44 - struct sdma_engine *sde; 45 - struct hfi1_vnic_vport_info *vinfo; 46 - struct iowait wait; 47 - struct sdma_txreq stx; 48 - unsigned int state; 49 - u8 q_idx; 50 - bool pkts_sent; 51 - }; 52 - 53 - /** 54 - * struct hfi1_vnic_rx_queue - HFI1 VNIC receive queue 55 - * @idx: queue index 56 - * @vinfo: pointer to vport information 57 - * @netdev: network device 58 - * @napi: netdev napi structure 59 - * @skbq: queue of received socket buffers 60 - */ 61 - struct hfi1_vnic_rx_queue { 62 - u8 idx; 63 - struct hfi1_vnic_vport_info *vinfo; 64 - struct net_device *netdev; 65 - struct napi_struct napi; 66 - }; 67 - 68 - /** 69 - * struct hfi1_vnic_vport_info - HFI1 VNIC virtual port information 70 - * @dd: device data pointer 71 - * @netdev: net device pointer 72 - * @flags: state flags 73 - * @lock: vport lock 74 - * @num_tx_q: number of transmit queues 75 - * @num_rx_q: number of receive queues 76 - * @vesw_id: virtual switch id 77 - * @rxq: Array of receive queues 78 - * @stats: per queue stats 79 - * @sdma: VNIC SDMA structure per TXQ 80 - */ 81 - struct hfi1_vnic_vport_info { 82 - struct hfi1_devdata *dd; 83 - struct net_device *netdev; 84 - unsigned long flags; 85 - 86 - /* Lock used around state updates */ 87 - struct mutex lock; 88 - 89 - u8 num_tx_q; 90 - u8 num_rx_q; 91 - u16 vesw_id; 92 - struct hfi1_vnic_rx_queue rxq[HFI1_NUM_VNIC_CTXT]; 93 - 94 - struct opa_vnic_stats stats[HFI1_VNIC_MAX_QUEUE]; 95 - struct hfi1_vnic_sdma sdma[HFI1_VNIC_MAX_TXQ]; 96 - }; 97 - 98 - #define v_dbg(format, arg...) \ 99 - netdev_dbg(vinfo->netdev, format, ## arg) 100 - #define v_err(format, arg...) \ 101 - netdev_err(vinfo->netdev, format, ## arg) 102 - #define v_info(format, arg...) \ 103 - netdev_info(vinfo->netdev, format, ## arg) 104 - 105 - /* vnic hfi1 internal functions */ 106 - void hfi1_vnic_setup(struct hfi1_devdata *dd); 107 - int hfi1_vnic_txreq_init(struct hfi1_devdata *dd); 108 - void hfi1_vnic_txreq_deinit(struct hfi1_devdata *dd); 109 - 110 - void hfi1_vnic_bypass_rcv(struct hfi1_packet *packet); 111 - void hfi1_vnic_sdma_init(struct hfi1_vnic_vport_info *vinfo); 112 - bool hfi1_vnic_sdma_write_avail(struct hfi1_vnic_vport_info *vinfo, 113 - u8 q_idx); 114 - 115 - /* vnic rdma netdev operations */ 116 - struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, 117 - u32 port_num, 118 - enum rdma_netdev_t type, 119 - const char *name, 120 - unsigned char name_assign_type, 121 - void (*setup)(struct net_device *)); 122 - int hfi1_vnic_send_dma(struct hfi1_devdata *dd, u8 q_idx, 123 - struct hfi1_vnic_vport_info *vinfo, 124 - struct sk_buff *skb, u64 pbc, u8 plen); 125 - 126 - #endif /* _HFI1_VNIC_H */
-615
drivers/infiniband/hw/hfi1/vnic_main.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 - /* 3 - * Copyright(c) 2017 - 2020 Intel Corporation. 4 - */ 5 - 6 - /* 7 - * This file contains HFI1 support for VNIC functionality 8 - */ 9 - 10 - #include <linux/io.h> 11 - #include <linux/if_vlan.h> 12 - 13 - #include "vnic.h" 14 - #include "netdev.h" 15 - 16 - #define HFI_TX_TIMEOUT_MS 1000 17 - 18 - #define HFI1_VNIC_RCV_Q_SIZE 1024 19 - 20 - #define HFI1_VNIC_UP 0 21 - 22 - static DEFINE_SPINLOCK(vport_cntr_lock); 23 - 24 - #define SUM_GRP_COUNTERS(stats, qstats, x_grp) do { \ 25 - u64 *src64, *dst64; \ 26 - for (src64 = &qstats->x_grp.unicast, \ 27 - dst64 = &stats->x_grp.unicast; \ 28 - dst64 <= &stats->x_grp.s_1519_max;) { \ 29 - *dst64++ += *src64++; \ 30 - } \ 31 - } while (0) 32 - 33 - #define VNIC_MASK (0xFF) 34 - #define VNIC_ID(val) ((1ull << 24) | ((val) & VNIC_MASK)) 35 - 36 - /* hfi1_vnic_update_stats - update statistics */ 37 - static void hfi1_vnic_update_stats(struct hfi1_vnic_vport_info *vinfo, 38 - struct opa_vnic_stats *stats) 39 - { 40 - struct net_device *netdev = vinfo->netdev; 41 - u8 i; 42 - 43 - /* add tx counters on different queues */ 44 - for (i = 0; i < vinfo->num_tx_q; i++) { 45 - struct opa_vnic_stats *qstats = &vinfo->stats[i]; 46 - struct rtnl_link_stats64 *qnstats = &vinfo->stats[i].netstats; 47 - 48 - stats->netstats.tx_fifo_errors += qnstats->tx_fifo_errors; 49 - stats->netstats.tx_carrier_errors += qnstats->tx_carrier_errors; 50 - stats->tx_drop_state += qstats->tx_drop_state; 51 - stats->tx_dlid_zero += qstats->tx_dlid_zero; 52 - 53 - SUM_GRP_COUNTERS(stats, qstats, tx_grp); 54 - stats->netstats.tx_packets += qnstats->tx_packets; 55 - stats->netstats.tx_bytes += qnstats->tx_bytes; 56 - } 57 - 58 - /* add rx counters on different queues */ 59 - for (i = 0; i < vinfo->num_rx_q; i++) { 60 - struct opa_vnic_stats *qstats = &vinfo->stats[i]; 61 - struct rtnl_link_stats64 *qnstats = &vinfo->stats[i].netstats; 62 - 63 - stats->netstats.rx_fifo_errors += qnstats->rx_fifo_errors; 64 - stats->netstats.rx_nohandler += qnstats->rx_nohandler; 65 - stats->rx_drop_state += qstats->rx_drop_state; 66 - stats->rx_oversize += qstats->rx_oversize; 67 - stats->rx_runt += qstats->rx_runt; 68 - 69 - SUM_GRP_COUNTERS(stats, qstats, rx_grp); 70 - stats->netstats.rx_packets += qnstats->rx_packets; 71 - stats->netstats.rx_bytes += qnstats->rx_bytes; 72 - } 73 - 74 - stats->netstats.tx_errors = stats->netstats.tx_fifo_errors + 75 - stats->netstats.tx_carrier_errors + 76 - stats->tx_drop_state + stats->tx_dlid_zero; 77 - stats->netstats.tx_dropped = stats->netstats.tx_errors; 78 - 79 - stats->netstats.rx_errors = stats->netstats.rx_fifo_errors + 80 - stats->netstats.rx_nohandler + 81 - stats->rx_drop_state + stats->rx_oversize + 82 - stats->rx_runt; 83 - stats->netstats.rx_dropped = stats->netstats.rx_errors; 84 - 85 - netdev->stats.tx_packets = stats->netstats.tx_packets; 86 - netdev->stats.tx_bytes = stats->netstats.tx_bytes; 87 - netdev->stats.tx_fifo_errors = stats->netstats.tx_fifo_errors; 88 - netdev->stats.tx_carrier_errors = stats->netstats.tx_carrier_errors; 89 - netdev->stats.tx_errors = stats->netstats.tx_errors; 90 - netdev->stats.tx_dropped = stats->netstats.tx_dropped; 91 - 92 - netdev->stats.rx_packets = stats->netstats.rx_packets; 93 - netdev->stats.rx_bytes = stats->netstats.rx_bytes; 94 - netdev->stats.rx_fifo_errors = stats->netstats.rx_fifo_errors; 95 - netdev->stats.multicast = stats->rx_grp.mcastbcast; 96 - netdev->stats.rx_length_errors = stats->rx_oversize + stats->rx_runt; 97 - netdev->stats.rx_errors = stats->netstats.rx_errors; 98 - netdev->stats.rx_dropped = stats->netstats.rx_dropped; 99 - } 100 - 101 - /* update_len_counters - update pkt's len histogram counters */ 102 - static inline void update_len_counters(struct opa_vnic_grp_stats *grp, 103 - int len) 104 - { 105 - /* account for 4 byte FCS */ 106 - if (len >= 1515) 107 - grp->s_1519_max++; 108 - else if (len >= 1020) 109 - grp->s_1024_1518++; 110 - else if (len >= 508) 111 - grp->s_512_1023++; 112 - else if (len >= 252) 113 - grp->s_256_511++; 114 - else if (len >= 124) 115 - grp->s_128_255++; 116 - else if (len >= 61) 117 - grp->s_65_127++; 118 - else 119 - grp->s_64++; 120 - } 121 - 122 - /* hfi1_vnic_update_tx_counters - update transmit counters */ 123 - static void hfi1_vnic_update_tx_counters(struct hfi1_vnic_vport_info *vinfo, 124 - u8 q_idx, struct sk_buff *skb, int err) 125 - { 126 - struct ethhdr *mac_hdr = (struct ethhdr *)skb_mac_header(skb); 127 - struct opa_vnic_stats *stats = &vinfo->stats[q_idx]; 128 - struct opa_vnic_grp_stats *tx_grp = &stats->tx_grp; 129 - u16 vlan_tci; 130 - 131 - stats->netstats.tx_packets++; 132 - stats->netstats.tx_bytes += skb->len + ETH_FCS_LEN; 133 - 134 - update_len_counters(tx_grp, skb->len); 135 - 136 - /* rest of the counts are for good packets only */ 137 - if (unlikely(err)) 138 - return; 139 - 140 - if (is_multicast_ether_addr(mac_hdr->h_dest)) 141 - tx_grp->mcastbcast++; 142 - else 143 - tx_grp->unicast++; 144 - 145 - if (!__vlan_get_tag(skb, &vlan_tci)) 146 - tx_grp->vlan++; 147 - else 148 - tx_grp->untagged++; 149 - } 150 - 151 - /* hfi1_vnic_update_rx_counters - update receive counters */ 152 - static void hfi1_vnic_update_rx_counters(struct hfi1_vnic_vport_info *vinfo, 153 - u8 q_idx, struct sk_buff *skb, int err) 154 - { 155 - struct ethhdr *mac_hdr = (struct ethhdr *)skb->data; 156 - struct opa_vnic_stats *stats = &vinfo->stats[q_idx]; 157 - struct opa_vnic_grp_stats *rx_grp = &stats->rx_grp; 158 - u16 vlan_tci; 159 - 160 - stats->netstats.rx_packets++; 161 - stats->netstats.rx_bytes += skb->len + ETH_FCS_LEN; 162 - 163 - update_len_counters(rx_grp, skb->len); 164 - 165 - /* rest of the counts are for good packets only */ 166 - if (unlikely(err)) 167 - return; 168 - 169 - if (is_multicast_ether_addr(mac_hdr->h_dest)) 170 - rx_grp->mcastbcast++; 171 - else 172 - rx_grp->unicast++; 173 - 174 - if (!__vlan_get_tag(skb, &vlan_tci)) 175 - rx_grp->vlan++; 176 - else 177 - rx_grp->untagged++; 178 - } 179 - 180 - /* This function is overloaded for opa_vnic specific implementation */ 181 - static void hfi1_vnic_get_stats64(struct net_device *netdev, 182 - struct rtnl_link_stats64 *stats) 183 - { 184 - struct opa_vnic_stats *vstats = (struct opa_vnic_stats *)stats; 185 - struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); 186 - 187 - hfi1_vnic_update_stats(vinfo, vstats); 188 - } 189 - 190 - static u64 create_bypass_pbc(u32 vl, u32 dw_len) 191 - { 192 - u64 pbc; 193 - 194 - pbc = ((u64)PBC_IHCRC_NONE << PBC_INSERT_HCRC_SHIFT) 195 - | PBC_INSERT_BYPASS_ICRC | PBC_CREDIT_RETURN 196 - | PBC_PACKET_BYPASS 197 - | ((vl & PBC_VL_MASK) << PBC_VL_SHIFT) 198 - | (dw_len & PBC_LENGTH_DWS_MASK) << PBC_LENGTH_DWS_SHIFT; 199 - 200 - return pbc; 201 - } 202 - 203 - /* hfi1_vnic_maybe_stop_tx - stop tx queue if required */ 204 - static void hfi1_vnic_maybe_stop_tx(struct hfi1_vnic_vport_info *vinfo, 205 - u8 q_idx) 206 - { 207 - netif_stop_subqueue(vinfo->netdev, q_idx); 208 - if (!hfi1_vnic_sdma_write_avail(vinfo, q_idx)) 209 - return; 210 - 211 - netif_start_subqueue(vinfo->netdev, q_idx); 212 - } 213 - 214 - static netdev_tx_t hfi1_netdev_start_xmit(struct sk_buff *skb, 215 - struct net_device *netdev) 216 - { 217 - struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); 218 - u8 pad_len, q_idx = skb->queue_mapping; 219 - struct hfi1_devdata *dd = vinfo->dd; 220 - struct opa_vnic_skb_mdata *mdata; 221 - u32 pkt_len, total_len; 222 - int err = -EINVAL; 223 - u64 pbc; 224 - 225 - v_dbg("xmit: queue %d skb len %d\n", q_idx, skb->len); 226 - if (unlikely(!netif_oper_up(netdev))) { 227 - vinfo->stats[q_idx].tx_drop_state++; 228 - goto tx_finish; 229 - } 230 - 231 - /* take out meta data */ 232 - mdata = (struct opa_vnic_skb_mdata *)skb->data; 233 - skb_pull(skb, sizeof(*mdata)); 234 - if (unlikely(mdata->flags & OPA_VNIC_SKB_MDATA_ENCAP_ERR)) { 235 - vinfo->stats[q_idx].tx_dlid_zero++; 236 - goto tx_finish; 237 - } 238 - 239 - /* add tail padding (for 8 bytes size alignment) and icrc */ 240 - pad_len = -(skb->len + OPA_VNIC_ICRC_TAIL_LEN) & 0x7; 241 - pad_len += OPA_VNIC_ICRC_TAIL_LEN; 242 - 243 - /* 244 - * pkt_len is how much data we have to write, includes header and data. 245 - * total_len is length of the packet in Dwords plus the PBC should not 246 - * include the CRC. 247 - */ 248 - pkt_len = (skb->len + pad_len) >> 2; 249 - total_len = pkt_len + 2; /* PBC + packet */ 250 - 251 - pbc = create_bypass_pbc(mdata->vl, total_len); 252 - 253 - skb_get(skb); 254 - v_dbg("pbc 0x%016llX len %d pad_len %d\n", pbc, skb->len, pad_len); 255 - err = dd->process_vnic_dma_send(dd, q_idx, vinfo, skb, pbc, pad_len); 256 - if (unlikely(err)) { 257 - if (err == -ENOMEM) 258 - vinfo->stats[q_idx].netstats.tx_fifo_errors++; 259 - else if (err != -EBUSY) 260 - vinfo->stats[q_idx].netstats.tx_carrier_errors++; 261 - } 262 - /* remove the header before updating tx counters */ 263 - skb_pull(skb, OPA_VNIC_HDR_LEN); 264 - 265 - if (unlikely(err == -EBUSY)) { 266 - hfi1_vnic_maybe_stop_tx(vinfo, q_idx); 267 - dev_kfree_skb_any(skb); 268 - return NETDEV_TX_BUSY; 269 - } 270 - 271 - tx_finish: 272 - /* update tx counters */ 273 - hfi1_vnic_update_tx_counters(vinfo, q_idx, skb, err); 274 - dev_kfree_skb_any(skb); 275 - return NETDEV_TX_OK; 276 - } 277 - 278 - static u16 hfi1_vnic_select_queue(struct net_device *netdev, 279 - struct sk_buff *skb, 280 - struct net_device *sb_dev) 281 - { 282 - struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); 283 - struct opa_vnic_skb_mdata *mdata; 284 - struct sdma_engine *sde; 285 - 286 - mdata = (struct opa_vnic_skb_mdata *)skb->data; 287 - sde = sdma_select_engine_vl(vinfo->dd, mdata->entropy, mdata->vl); 288 - return sde->this_idx; 289 - } 290 - 291 - /* hfi1_vnic_decap_skb - strip OPA header from the skb (ethernet) packet */ 292 - static inline int hfi1_vnic_decap_skb(struct hfi1_vnic_rx_queue *rxq, 293 - struct sk_buff *skb) 294 - { 295 - struct hfi1_vnic_vport_info *vinfo = rxq->vinfo; 296 - int max_len = vinfo->netdev->mtu + VLAN_ETH_HLEN; 297 - int rc = -EFAULT; 298 - 299 - skb_pull(skb, OPA_VNIC_HDR_LEN); 300 - 301 - /* Validate Packet length */ 302 - if (unlikely(skb->len > max_len)) 303 - vinfo->stats[rxq->idx].rx_oversize++; 304 - else if (unlikely(skb->len < ETH_ZLEN)) 305 - vinfo->stats[rxq->idx].rx_runt++; 306 - else 307 - rc = 0; 308 - return rc; 309 - } 310 - 311 - static struct hfi1_vnic_vport_info *get_vnic_port(struct hfi1_devdata *dd, 312 - int vesw_id) 313 - { 314 - int vnic_id = VNIC_ID(vesw_id); 315 - 316 - return hfi1_netdev_get_data(dd, vnic_id); 317 - } 318 - 319 - static struct hfi1_vnic_vport_info *get_first_vnic_port(struct hfi1_devdata *dd) 320 - { 321 - struct hfi1_vnic_vport_info *vinfo; 322 - int next_id = VNIC_ID(0); 323 - 324 - vinfo = hfi1_netdev_get_first_data(dd, &next_id); 325 - 326 - if (next_id > VNIC_ID(VNIC_MASK)) 327 - return NULL; 328 - 329 - return vinfo; 330 - } 331 - 332 - void hfi1_vnic_bypass_rcv(struct hfi1_packet *packet) 333 - { 334 - struct hfi1_devdata *dd = packet->rcd->dd; 335 - struct hfi1_vnic_vport_info *vinfo = NULL; 336 - struct hfi1_vnic_rx_queue *rxq; 337 - struct sk_buff *skb; 338 - int l4_type, vesw_id = -1, rc; 339 - u8 q_idx; 340 - unsigned char *pad_info; 341 - 342 - l4_type = hfi1_16B_get_l4(packet->ebuf); 343 - if (likely(l4_type == OPA_16B_L4_ETHR)) { 344 - vesw_id = HFI1_VNIC_GET_VESWID(packet->ebuf); 345 - vinfo = get_vnic_port(dd, vesw_id); 346 - 347 - /* 348 - * In case of invalid vesw id, count the error on 349 - * the first available vport. 350 - */ 351 - if (unlikely(!vinfo)) { 352 - struct hfi1_vnic_vport_info *vinfo_tmp; 353 - 354 - vinfo_tmp = get_first_vnic_port(dd); 355 - if (vinfo_tmp) { 356 - spin_lock(&vport_cntr_lock); 357 - vinfo_tmp->stats[0].netstats.rx_nohandler++; 358 - spin_unlock(&vport_cntr_lock); 359 - } 360 - } 361 - } 362 - 363 - if (unlikely(!vinfo)) { 364 - dd_dev_warn(dd, "vnic rcv err: l4 %d vesw id %d ctx %d\n", 365 - l4_type, vesw_id, packet->rcd->ctxt); 366 - return; 367 - } 368 - 369 - q_idx = packet->rcd->vnic_q_idx; 370 - rxq = &vinfo->rxq[q_idx]; 371 - if (unlikely(!netif_oper_up(vinfo->netdev))) { 372 - vinfo->stats[q_idx].rx_drop_state++; 373 - return; 374 - } 375 - 376 - skb = netdev_alloc_skb(vinfo->netdev, packet->tlen); 377 - if (unlikely(!skb)) { 378 - vinfo->stats[q_idx].netstats.rx_fifo_errors++; 379 - return; 380 - } 381 - 382 - memcpy(skb->data, packet->ebuf, packet->tlen); 383 - skb_put(skb, packet->tlen); 384 - 385 - pad_info = skb->data + skb->len - 1; 386 - skb_trim(skb, (skb->len - OPA_VNIC_ICRC_TAIL_LEN - 387 - ((*pad_info) & 0x7))); 388 - 389 - rc = hfi1_vnic_decap_skb(rxq, skb); 390 - 391 - /* update rx counters */ 392 - hfi1_vnic_update_rx_counters(vinfo, rxq->idx, skb, rc); 393 - if (unlikely(rc)) { 394 - dev_kfree_skb_any(skb); 395 - return; 396 - } 397 - 398 - skb_checksum_none_assert(skb); 399 - skb->protocol = eth_type_trans(skb, rxq->netdev); 400 - 401 - napi_gro_receive(&rxq->napi, skb); 402 - } 403 - 404 - static int hfi1_vnic_up(struct hfi1_vnic_vport_info *vinfo) 405 - { 406 - struct hfi1_devdata *dd = vinfo->dd; 407 - struct net_device *netdev = vinfo->netdev; 408 - int rc; 409 - 410 - /* ensure virtual eth switch id is valid */ 411 - if (!vinfo->vesw_id) 412 - return -EINVAL; 413 - 414 - rc = hfi1_netdev_add_data(dd, VNIC_ID(vinfo->vesw_id), vinfo); 415 - if (rc < 0) 416 - return rc; 417 - 418 - rc = hfi1_netdev_rx_init(dd); 419 - if (rc) 420 - goto err_remove; 421 - 422 - netif_carrier_on(netdev); 423 - netif_tx_start_all_queues(netdev); 424 - set_bit(HFI1_VNIC_UP, &vinfo->flags); 425 - 426 - return 0; 427 - 428 - err_remove: 429 - hfi1_netdev_remove_data(dd, VNIC_ID(vinfo->vesw_id)); 430 - return rc; 431 - } 432 - 433 - static void hfi1_vnic_down(struct hfi1_vnic_vport_info *vinfo) 434 - { 435 - struct hfi1_devdata *dd = vinfo->dd; 436 - 437 - clear_bit(HFI1_VNIC_UP, &vinfo->flags); 438 - netif_carrier_off(vinfo->netdev); 439 - netif_tx_disable(vinfo->netdev); 440 - hfi1_netdev_remove_data(dd, VNIC_ID(vinfo->vesw_id)); 441 - 442 - hfi1_netdev_rx_destroy(dd); 443 - } 444 - 445 - static int hfi1_netdev_open(struct net_device *netdev) 446 - { 447 - struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); 448 - int rc; 449 - 450 - mutex_lock(&vinfo->lock); 451 - rc = hfi1_vnic_up(vinfo); 452 - mutex_unlock(&vinfo->lock); 453 - return rc; 454 - } 455 - 456 - static int hfi1_netdev_close(struct net_device *netdev) 457 - { 458 - struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); 459 - 460 - mutex_lock(&vinfo->lock); 461 - if (test_bit(HFI1_VNIC_UP, &vinfo->flags)) 462 - hfi1_vnic_down(vinfo); 463 - mutex_unlock(&vinfo->lock); 464 - return 0; 465 - } 466 - 467 - static int hfi1_vnic_init(struct hfi1_vnic_vport_info *vinfo) 468 - { 469 - struct hfi1_devdata *dd = vinfo->dd; 470 - int rc = 0; 471 - 472 - mutex_lock(&hfi1_mutex); 473 - if (!dd->vnic_num_vports) { 474 - rc = hfi1_vnic_txreq_init(dd); 475 - if (rc) 476 - goto txreq_fail; 477 - } 478 - 479 - rc = hfi1_netdev_rx_init(dd); 480 - if (rc) { 481 - dd_dev_err(dd, "Unable to initialize netdev contexts\n"); 482 - goto alloc_fail; 483 - } 484 - 485 - hfi1_init_vnic_rsm(dd); 486 - 487 - dd->vnic_num_vports++; 488 - hfi1_vnic_sdma_init(vinfo); 489 - 490 - alloc_fail: 491 - if (!dd->vnic_num_vports) 492 - hfi1_vnic_txreq_deinit(dd); 493 - txreq_fail: 494 - mutex_unlock(&hfi1_mutex); 495 - return rc; 496 - } 497 - 498 - static void hfi1_vnic_deinit(struct hfi1_vnic_vport_info *vinfo) 499 - { 500 - struct hfi1_devdata *dd = vinfo->dd; 501 - 502 - mutex_lock(&hfi1_mutex); 503 - if (--dd->vnic_num_vports == 0) { 504 - hfi1_deinit_vnic_rsm(dd); 505 - hfi1_vnic_txreq_deinit(dd); 506 - } 507 - mutex_unlock(&hfi1_mutex); 508 - hfi1_netdev_rx_destroy(dd); 509 - } 510 - 511 - static void hfi1_vnic_set_vesw_id(struct net_device *netdev, int id) 512 - { 513 - struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); 514 - bool reopen = false; 515 - 516 - /* 517 - * If vesw_id is being changed, and if the vnic port is up, 518 - * reset the vnic port to ensure new vesw_id gets picked up 519 - */ 520 - if (id != vinfo->vesw_id) { 521 - mutex_lock(&vinfo->lock); 522 - if (test_bit(HFI1_VNIC_UP, &vinfo->flags)) { 523 - hfi1_vnic_down(vinfo); 524 - reopen = true; 525 - } 526 - 527 - vinfo->vesw_id = id; 528 - if (reopen) 529 - hfi1_vnic_up(vinfo); 530 - 531 - mutex_unlock(&vinfo->lock); 532 - } 533 - } 534 - 535 - /* netdev ops */ 536 - static const struct net_device_ops hfi1_netdev_ops = { 537 - .ndo_open = hfi1_netdev_open, 538 - .ndo_stop = hfi1_netdev_close, 539 - .ndo_start_xmit = hfi1_netdev_start_xmit, 540 - .ndo_select_queue = hfi1_vnic_select_queue, 541 - .ndo_get_stats64 = hfi1_vnic_get_stats64, 542 - }; 543 - 544 - static void hfi1_vnic_free_rn(struct net_device *netdev) 545 - { 546 - struct hfi1_vnic_vport_info *vinfo = opa_vnic_dev_priv(netdev); 547 - 548 - hfi1_vnic_deinit(vinfo); 549 - mutex_destroy(&vinfo->lock); 550 - free_netdev(netdev); 551 - } 552 - 553 - struct net_device *hfi1_vnic_alloc_rn(struct ib_device *device, 554 - u32 port_num, 555 - enum rdma_netdev_t type, 556 - const char *name, 557 - unsigned char name_assign_type, 558 - void (*setup)(struct net_device *)) 559 - { 560 - struct hfi1_devdata *dd = dd_from_ibdev(device); 561 - struct hfi1_vnic_vport_info *vinfo; 562 - struct net_device *netdev; 563 - struct rdma_netdev *rn; 564 - int i, size, rc; 565 - 566 - if (!dd->num_netdev_contexts) 567 - return ERR_PTR(-ENOMEM); 568 - 569 - if (!port_num || (port_num > dd->num_pports)) 570 - return ERR_PTR(-EINVAL); 571 - 572 - if (type != RDMA_NETDEV_OPA_VNIC) 573 - return ERR_PTR(-EOPNOTSUPP); 574 - 575 - size = sizeof(struct opa_vnic_rdma_netdev) + sizeof(*vinfo); 576 - netdev = alloc_netdev_mqs(size, name, name_assign_type, setup, 577 - chip_sdma_engines(dd), 578 - dd->num_netdev_contexts); 579 - if (!netdev) 580 - return ERR_PTR(-ENOMEM); 581 - 582 - rn = netdev_priv(netdev); 583 - vinfo = opa_vnic_dev_priv(netdev); 584 - vinfo->dd = dd; 585 - vinfo->num_tx_q = chip_sdma_engines(dd); 586 - vinfo->num_rx_q = dd->num_netdev_contexts; 587 - vinfo->netdev = netdev; 588 - rn->free_rdma_netdev = hfi1_vnic_free_rn; 589 - rn->set_id = hfi1_vnic_set_vesw_id; 590 - 591 - netdev->features = NETIF_F_HIGHDMA | NETIF_F_SG; 592 - netdev->hw_features = netdev->features; 593 - netdev->vlan_features = netdev->features; 594 - netdev->watchdog_timeo = msecs_to_jiffies(HFI_TX_TIMEOUT_MS); 595 - netdev->netdev_ops = &hfi1_netdev_ops; 596 - mutex_init(&vinfo->lock); 597 - 598 - for (i = 0; i < vinfo->num_rx_q; i++) { 599 - struct hfi1_vnic_rx_queue *rxq = &vinfo->rxq[i]; 600 - 601 - rxq->idx = i; 602 - rxq->vinfo = vinfo; 603 - rxq->netdev = netdev; 604 - } 605 - 606 - rc = hfi1_vnic_init(vinfo); 607 - if (rc) 608 - goto init_fail; 609 - 610 - return netdev; 611 - init_fail: 612 - mutex_destroy(&vinfo->lock); 613 - free_netdev(netdev); 614 - return ERR_PTR(rc); 615 - }
-282
drivers/infiniband/hw/hfi1/vnic_sdma.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 - /* 3 - * Copyright(c) 2017 - 2018 Intel Corporation. 4 - */ 5 - 6 - /* 7 - * This file contains HFI1 support for VNIC SDMA functionality 8 - */ 9 - 10 - #include "sdma.h" 11 - #include "vnic.h" 12 - 13 - #define HFI1_VNIC_SDMA_Q_ACTIVE BIT(0) 14 - #define HFI1_VNIC_SDMA_Q_DEFERRED BIT(1) 15 - 16 - #define HFI1_VNIC_TXREQ_NAME_LEN 32 17 - #define HFI1_VNIC_SDMA_DESC_WTRMRK 64 18 - 19 - /* 20 - * struct vnic_txreq - VNIC transmit descriptor 21 - * @txreq: sdma transmit request 22 - * @sdma: vnic sdma pointer 23 - * @skb: skb to send 24 - * @pad: pad buffer 25 - * @plen: pad length 26 - * @pbc_val: pbc value 27 - */ 28 - struct vnic_txreq { 29 - struct sdma_txreq txreq; 30 - struct hfi1_vnic_sdma *sdma; 31 - 32 - struct sk_buff *skb; 33 - unsigned char pad[HFI1_VNIC_MAX_PAD]; 34 - u16 plen; 35 - __le64 pbc_val; 36 - }; 37 - 38 - static void vnic_sdma_complete(struct sdma_txreq *txreq, 39 - int status) 40 - { 41 - struct vnic_txreq *tx = container_of(txreq, struct vnic_txreq, txreq); 42 - struct hfi1_vnic_sdma *vnic_sdma = tx->sdma; 43 - 44 - sdma_txclean(vnic_sdma->dd, txreq); 45 - dev_kfree_skb_any(tx->skb); 46 - kmem_cache_free(vnic_sdma->dd->vnic.txreq_cache, tx); 47 - } 48 - 49 - static noinline int build_vnic_ulp_payload(struct sdma_engine *sde, 50 - struct vnic_txreq *tx) 51 - { 52 - int i, ret = 0; 53 - 54 - ret = sdma_txadd_kvaddr( 55 - sde->dd, 56 - &tx->txreq, 57 - tx->skb->data, 58 - skb_headlen(tx->skb)); 59 - if (unlikely(ret)) 60 - goto bail_txadd; 61 - 62 - for (i = 0; i < skb_shinfo(tx->skb)->nr_frags; i++) { 63 - skb_frag_t *frag = &skb_shinfo(tx->skb)->frags[i]; 64 - 65 - /* combine physically continuous fragments later? */ 66 - ret = sdma_txadd_page(sde->dd, 67 - &tx->txreq, 68 - skb_frag_page(frag), 69 - skb_frag_off(frag), 70 - skb_frag_size(frag), 71 - NULL, NULL, NULL); 72 - if (unlikely(ret)) 73 - goto bail_txadd; 74 - } 75 - 76 - if (tx->plen) 77 - ret = sdma_txadd_kvaddr(sde->dd, &tx->txreq, 78 - tx->pad + HFI1_VNIC_MAX_PAD - tx->plen, 79 - tx->plen); 80 - 81 - bail_txadd: 82 - return ret; 83 - } 84 - 85 - static int build_vnic_tx_desc(struct sdma_engine *sde, 86 - struct vnic_txreq *tx, 87 - u64 pbc) 88 - { 89 - int ret = 0; 90 - u16 hdrbytes = 2 << 2; /* PBC */ 91 - 92 - ret = sdma_txinit_ahg( 93 - &tx->txreq, 94 - 0, 95 - hdrbytes + tx->skb->len + tx->plen, 96 - 0, 97 - 0, 98 - NULL, 99 - 0, 100 - vnic_sdma_complete); 101 - if (unlikely(ret)) 102 - goto bail_txadd; 103 - 104 - /* add pbc */ 105 - tx->pbc_val = cpu_to_le64(pbc); 106 - ret = sdma_txadd_kvaddr( 107 - sde->dd, 108 - &tx->txreq, 109 - &tx->pbc_val, 110 - hdrbytes); 111 - if (unlikely(ret)) 112 - goto bail_txadd; 113 - 114 - /* add the ulp payload */ 115 - ret = build_vnic_ulp_payload(sde, tx); 116 - bail_txadd: 117 - return ret; 118 - } 119 - 120 - /* setup the last plen bypes of pad */ 121 - static inline void hfi1_vnic_update_pad(unsigned char *pad, u8 plen) 122 - { 123 - pad[HFI1_VNIC_MAX_PAD - 1] = plen - OPA_VNIC_ICRC_TAIL_LEN; 124 - } 125 - 126 - int hfi1_vnic_send_dma(struct hfi1_devdata *dd, u8 q_idx, 127 - struct hfi1_vnic_vport_info *vinfo, 128 - struct sk_buff *skb, u64 pbc, u8 plen) 129 - { 130 - struct hfi1_vnic_sdma *vnic_sdma = &vinfo->sdma[q_idx]; 131 - struct sdma_engine *sde = vnic_sdma->sde; 132 - struct vnic_txreq *tx; 133 - int ret = -ECOMM; 134 - 135 - if (unlikely(READ_ONCE(vnic_sdma->state) != HFI1_VNIC_SDMA_Q_ACTIVE)) 136 - goto tx_err; 137 - 138 - if (unlikely(!sde || !sdma_running(sde))) 139 - goto tx_err; 140 - 141 - tx = kmem_cache_alloc(dd->vnic.txreq_cache, GFP_ATOMIC); 142 - if (unlikely(!tx)) { 143 - ret = -ENOMEM; 144 - goto tx_err; 145 - } 146 - 147 - tx->sdma = vnic_sdma; 148 - tx->skb = skb; 149 - hfi1_vnic_update_pad(tx->pad, plen); 150 - tx->plen = plen; 151 - ret = build_vnic_tx_desc(sde, tx, pbc); 152 - if (unlikely(ret)) 153 - goto free_desc; 154 - 155 - ret = sdma_send_txreq(sde, iowait_get_ib_work(&vnic_sdma->wait), 156 - &tx->txreq, vnic_sdma->pkts_sent); 157 - /* When -ECOMM, sdma callback will be called with ABORT status */ 158 - if (unlikely(ret && unlikely(ret != -ECOMM))) 159 - goto free_desc; 160 - 161 - if (!ret) { 162 - vnic_sdma->pkts_sent = true; 163 - iowait_starve_clear(vnic_sdma->pkts_sent, &vnic_sdma->wait); 164 - } 165 - return ret; 166 - 167 - free_desc: 168 - sdma_txclean(dd, &tx->txreq); 169 - kmem_cache_free(dd->vnic.txreq_cache, tx); 170 - tx_err: 171 - if (ret != -EBUSY) 172 - dev_kfree_skb_any(skb); 173 - else 174 - vnic_sdma->pkts_sent = false; 175 - return ret; 176 - } 177 - 178 - /* 179 - * hfi1_vnic_sdma_sleep - vnic sdma sleep function 180 - * 181 - * This function gets called from sdma_send_txreq() when there are not enough 182 - * sdma descriptors available to send the packet. It adds Tx queue's wait 183 - * structure to sdma engine's dmawait list to be woken up when descriptors 184 - * become available. 185 - */ 186 - static int hfi1_vnic_sdma_sleep(struct sdma_engine *sde, 187 - struct iowait_work *wait, 188 - struct sdma_txreq *txreq, 189 - uint seq, 190 - bool pkts_sent) 191 - { 192 - struct hfi1_vnic_sdma *vnic_sdma = 193 - container_of(wait->iow, struct hfi1_vnic_sdma, wait); 194 - 195 - write_seqlock(&sde->waitlock); 196 - if (sdma_progress(sde, seq, txreq)) { 197 - write_sequnlock(&sde->waitlock); 198 - return -EAGAIN; 199 - } 200 - 201 - vnic_sdma->state = HFI1_VNIC_SDMA_Q_DEFERRED; 202 - if (list_empty(&vnic_sdma->wait.list)) { 203 - iowait_get_priority(wait->iow); 204 - iowait_queue(pkts_sent, wait->iow, &sde->dmawait); 205 - } 206 - write_sequnlock(&sde->waitlock); 207 - return -EBUSY; 208 - } 209 - 210 - /* 211 - * hfi1_vnic_sdma_wakeup - vnic sdma wakeup function 212 - * 213 - * This function gets called when SDMA descriptors becomes available and Tx 214 - * queue's wait structure was previously added to sdma engine's dmawait list. 215 - * It notifies the upper driver about Tx queue wakeup. 216 - */ 217 - static void hfi1_vnic_sdma_wakeup(struct iowait *wait, int reason) 218 - { 219 - struct hfi1_vnic_sdma *vnic_sdma = 220 - container_of(wait, struct hfi1_vnic_sdma, wait); 221 - struct hfi1_vnic_vport_info *vinfo = vnic_sdma->vinfo; 222 - 223 - vnic_sdma->state = HFI1_VNIC_SDMA_Q_ACTIVE; 224 - if (__netif_subqueue_stopped(vinfo->netdev, vnic_sdma->q_idx)) 225 - netif_wake_subqueue(vinfo->netdev, vnic_sdma->q_idx); 226 - }; 227 - 228 - inline bool hfi1_vnic_sdma_write_avail(struct hfi1_vnic_vport_info *vinfo, 229 - u8 q_idx) 230 - { 231 - struct hfi1_vnic_sdma *vnic_sdma = &vinfo->sdma[q_idx]; 232 - 233 - return (READ_ONCE(vnic_sdma->state) == HFI1_VNIC_SDMA_Q_ACTIVE); 234 - } 235 - 236 - void hfi1_vnic_sdma_init(struct hfi1_vnic_vport_info *vinfo) 237 - { 238 - int i; 239 - 240 - for (i = 0; i < vinfo->num_tx_q; i++) { 241 - struct hfi1_vnic_sdma *vnic_sdma = &vinfo->sdma[i]; 242 - 243 - iowait_init(&vnic_sdma->wait, 0, NULL, NULL, 244 - hfi1_vnic_sdma_sleep, 245 - hfi1_vnic_sdma_wakeup, NULL, NULL); 246 - vnic_sdma->sde = &vinfo->dd->per_sdma[i]; 247 - vnic_sdma->dd = vinfo->dd; 248 - vnic_sdma->vinfo = vinfo; 249 - vnic_sdma->q_idx = i; 250 - vnic_sdma->state = HFI1_VNIC_SDMA_Q_ACTIVE; 251 - 252 - /* Add a free descriptor watermark for wakeups */ 253 - if (vnic_sdma->sde->descq_cnt > HFI1_VNIC_SDMA_DESC_WTRMRK) { 254 - struct iowait_work *work; 255 - 256 - INIT_LIST_HEAD(&vnic_sdma->stx.list); 257 - vnic_sdma->stx.num_desc = HFI1_VNIC_SDMA_DESC_WTRMRK; 258 - work = iowait_get_ib_work(&vnic_sdma->wait); 259 - list_add_tail(&vnic_sdma->stx.list, &work->tx_head); 260 - } 261 - } 262 - } 263 - 264 - int hfi1_vnic_txreq_init(struct hfi1_devdata *dd) 265 - { 266 - char buf[HFI1_VNIC_TXREQ_NAME_LEN]; 267 - 268 - snprintf(buf, sizeof(buf), "hfi1_%u_vnic_txreq_cache", dd->unit); 269 - dd->vnic.txreq_cache = kmem_cache_create(buf, 270 - sizeof(struct vnic_txreq), 271 - 0, SLAB_HWCACHE_ALIGN, 272 - NULL); 273 - if (!dd->vnic.txreq_cache) 274 - return -ENOMEM; 275 - return 0; 276 - } 277 - 278 - void hfi1_vnic_txreq_deinit(struct hfi1_devdata *dd) 279 - { 280 - kmem_cache_destroy(dd->vnic.txreq_cache); 281 - dd->vnic.txreq_cache = NULL; 282 - }
-1
drivers/infiniband/ulp/Makefile
··· 4 4 obj-$(CONFIG_INFINIBAND_SRPT) += srpt/ 5 5 obj-$(CONFIG_INFINIBAND_ISER) += iser/ 6 6 obj-$(CONFIG_INFINIBAND_ISERT) += isert/ 7 - obj-$(CONFIG_INFINIBAND_OPA_VNIC) += opa_vnic/ 8 7 obj-$(CONFIG_INFINIBAND_RTRS) += rtrs/
-9
drivers/infiniband/ulp/opa_vnic/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - config INFINIBAND_OPA_VNIC 3 - tristate "Cornelis OPX VNIC support" 4 - depends on X86_64 && INFINIBAND 5 - help 6 - This is Omni-Path Express (OPX) Virtual Network Interface Controller (VNIC) 7 - driver for Ethernet over Omni-Path feature. It implements the HW 8 - independent VNIC functionality. It interfaces with Linux stack for 9 - data path and IB MAD for the control path.
-9
drivers/infiniband/ulp/opa_vnic/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - # Makefile - Cornelis Omni-Path Express Virtual Network Controller driver 3 - # Copyright(c) 2017, Intel Corporation. 4 - # Copyright(c) 2021, Cornelis Networks. 5 - # 6 - obj-$(CONFIG_INFINIBAND_OPA_VNIC) += opa_vnic.o 7 - 8 - opa_vnic-y := opa_vnic_netdev.o opa_vnic_encap.o opa_vnic_ethtool.o \ 9 - opa_vnic_vema.o opa_vnic_vema_iface.o
-513
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c
··· 1 - /* 2 - * Copyright(c) 2017 Intel Corporation. 3 - * 4 - * This file is provided under a dual BSD/GPLv2 license. When using or 5 - * redistributing this file, you may do so under either license. 6 - * 7 - * GPL LICENSE SUMMARY 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of version 2 of the GNU General Public License as 11 - * published by the Free Software Foundation. 12 - * 13 - * This program is distributed in the hope that it will be useful, but 14 - * WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 - * General Public License for more details. 17 - * 18 - * BSD LICENSE 19 - * 20 - * Redistribution and use in source and binary forms, with or without 21 - * modification, are permitted provided that the following conditions 22 - * are met: 23 - * 24 - * - Redistributions of source code must retain the above copyright 25 - * notice, this list of conditions and the following disclaimer. 26 - * - Redistributions in binary form must reproduce the above copyright 27 - * notice, this list of conditions and the following disclaimer in 28 - * the documentation and/or other materials provided with the 29 - * distribution. 30 - * - Neither the name of Intel Corporation nor the names of its 31 - * contributors may be used to endorse or promote products derived 32 - * from this software without specific prior written permission. 33 - * 34 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 35 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 36 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 37 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 38 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 39 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 40 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 41 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 42 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 43 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 44 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 - * 46 - */ 47 - 48 - /* 49 - * This file contains OPA VNIC encapsulation/decapsulation function. 50 - */ 51 - 52 - #include <linux/if_ether.h> 53 - #include <linux/if_vlan.h> 54 - 55 - #include "opa_vnic_internal.h" 56 - 57 - /* OPA 16B Header fields */ 58 - #define OPA_16B_LID_MASK 0xFFFFFull 59 - #define OPA_16B_SLID_HIGH_SHFT 8 60 - #define OPA_16B_SLID_MASK 0xF00ull 61 - #define OPA_16B_DLID_MASK 0xF000ull 62 - #define OPA_16B_DLID_HIGH_SHFT 12 63 - #define OPA_16B_LEN_SHFT 20 64 - #define OPA_16B_SC_SHFT 20 65 - #define OPA_16B_RC_SHFT 25 66 - #define OPA_16B_PKEY_SHFT 16 67 - 68 - #define OPA_VNIC_L4_HDR_SHFT 16 69 - 70 - /* L2+L4 hdr len is 20 bytes (5 quad words) */ 71 - #define OPA_VNIC_HDR_QW_LEN 5 72 - 73 - static inline void opa_vnic_make_header(u8 *hdr, u32 slid, u32 dlid, u16 len, 74 - u16 pkey, u16 entropy, u8 sc, u8 rc, 75 - u8 l4_type, u16 l4_hdr) 76 - { 77 - /* h[1]: LT=1, 16B L2=10 */ 78 - u32 h[OPA_VNIC_HDR_QW_LEN] = {0, 0xc0000000, 0, 0, 0}; 79 - 80 - h[2] = l4_type; 81 - h[3] = entropy; 82 - h[4] = l4_hdr << OPA_VNIC_L4_HDR_SHFT; 83 - 84 - /* Extract and set 4 upper bits and 20 lower bits of the lids */ 85 - h[0] |= (slid & OPA_16B_LID_MASK); 86 - h[2] |= ((slid >> (20 - OPA_16B_SLID_HIGH_SHFT)) & OPA_16B_SLID_MASK); 87 - 88 - h[1] |= (dlid & OPA_16B_LID_MASK); 89 - h[2] |= ((dlid >> (20 - OPA_16B_DLID_HIGH_SHFT)) & OPA_16B_DLID_MASK); 90 - 91 - h[0] |= (len << OPA_16B_LEN_SHFT); 92 - h[1] |= (rc << OPA_16B_RC_SHFT); 93 - h[1] |= (sc << OPA_16B_SC_SHFT); 94 - h[2] |= ((u32)pkey << OPA_16B_PKEY_SHFT); 95 - 96 - memcpy(hdr, h, OPA_VNIC_HDR_LEN); 97 - } 98 - 99 - /* 100 - * Using a simple hash table for mac table implementation with the last octet 101 - * of mac address as a key. 102 - */ 103 - static void opa_vnic_free_mac_tbl(struct hlist_head *mactbl) 104 - { 105 - struct opa_vnic_mac_tbl_node *node; 106 - struct hlist_node *tmp; 107 - int bkt; 108 - 109 - if (!mactbl) 110 - return; 111 - 112 - vnic_hash_for_each_safe(mactbl, bkt, tmp, node, hlist) { 113 - hash_del(&node->hlist); 114 - kfree(node); 115 - } 116 - kfree(mactbl); 117 - } 118 - 119 - static struct hlist_head *opa_vnic_alloc_mac_tbl(void) 120 - { 121 - u32 size = sizeof(struct hlist_head) * OPA_VNIC_MAC_TBL_SIZE; 122 - struct hlist_head *mactbl; 123 - 124 - mactbl = kzalloc(size, GFP_KERNEL); 125 - if (!mactbl) 126 - return ERR_PTR(-ENOMEM); 127 - 128 - vnic_hash_init(mactbl); 129 - return mactbl; 130 - } 131 - 132 - /* opa_vnic_release_mac_tbl - empty and free the mac table */ 133 - void opa_vnic_release_mac_tbl(struct opa_vnic_adapter *adapter) 134 - { 135 - struct hlist_head *mactbl; 136 - 137 - mutex_lock(&adapter->mactbl_lock); 138 - mactbl = rcu_access_pointer(adapter->mactbl); 139 - rcu_assign_pointer(adapter->mactbl, NULL); 140 - synchronize_rcu(); 141 - opa_vnic_free_mac_tbl(mactbl); 142 - adapter->info.vport.mac_tbl_digest = 0; 143 - mutex_unlock(&adapter->mactbl_lock); 144 - } 145 - 146 - /* 147 - * opa_vnic_query_mac_tbl - query the mac table for a section 148 - * 149 - * This function implements query of specific function of the mac table. 150 - * The function also expects the requested range to be valid. 151 - */ 152 - void opa_vnic_query_mac_tbl(struct opa_vnic_adapter *adapter, 153 - struct opa_veswport_mactable *tbl) 154 - { 155 - struct opa_vnic_mac_tbl_node *node; 156 - struct hlist_head *mactbl; 157 - int bkt; 158 - u16 loffset, lnum_entries; 159 - 160 - rcu_read_lock(); 161 - mactbl = rcu_dereference(adapter->mactbl); 162 - if (!mactbl) 163 - goto get_mac_done; 164 - 165 - loffset = be16_to_cpu(tbl->offset); 166 - lnum_entries = be16_to_cpu(tbl->num_entries); 167 - 168 - vnic_hash_for_each(mactbl, bkt, node, hlist) { 169 - struct __opa_vnic_mactable_entry *nentry = &node->entry; 170 - struct opa_veswport_mactable_entry *entry; 171 - 172 - if ((node->index < loffset) || 173 - (node->index >= (loffset + lnum_entries))) 174 - continue; 175 - 176 - /* populate entry in the tbl corresponding to the index */ 177 - entry = &tbl->tbl_entries[node->index - loffset]; 178 - memcpy(entry->mac_addr, nentry->mac_addr, 179 - ARRAY_SIZE(entry->mac_addr)); 180 - memcpy(entry->mac_addr_mask, nentry->mac_addr_mask, 181 - ARRAY_SIZE(entry->mac_addr_mask)); 182 - entry->dlid_sd = cpu_to_be32(nentry->dlid_sd); 183 - } 184 - tbl->mac_tbl_digest = cpu_to_be32(adapter->info.vport.mac_tbl_digest); 185 - get_mac_done: 186 - rcu_read_unlock(); 187 - } 188 - 189 - /* 190 - * opa_vnic_update_mac_tbl - update mac table section 191 - * 192 - * This function updates the specified section of the mac table. 193 - * The procedure includes following steps. 194 - * - Allocate a new mac (hash) table. 195 - * - Add the specified entries to the new table. 196 - * (except the ones that are requested to be deleted). 197 - * - Add all the other entries from the old mac table. 198 - * - If there is a failure, free the new table and return. 199 - * - Switch to the new table. 200 - * - Free the old table and return. 201 - * 202 - * The function also expects the requested range to be valid. 203 - */ 204 - int opa_vnic_update_mac_tbl(struct opa_vnic_adapter *adapter, 205 - struct opa_veswport_mactable *tbl) 206 - { 207 - struct opa_vnic_mac_tbl_node *node, *new_node; 208 - struct hlist_head *new_mactbl, *old_mactbl; 209 - int i, bkt, rc = 0; 210 - u8 key; 211 - u16 loffset, lnum_entries; 212 - 213 - mutex_lock(&adapter->mactbl_lock); 214 - /* allocate new mac table */ 215 - new_mactbl = opa_vnic_alloc_mac_tbl(); 216 - if (IS_ERR(new_mactbl)) { 217 - mutex_unlock(&adapter->mactbl_lock); 218 - return PTR_ERR(new_mactbl); 219 - } 220 - 221 - loffset = be16_to_cpu(tbl->offset); 222 - lnum_entries = be16_to_cpu(tbl->num_entries); 223 - 224 - /* add updated entries to the new mac table */ 225 - for (i = 0; i < lnum_entries; i++) { 226 - struct __opa_vnic_mactable_entry *nentry; 227 - struct opa_veswport_mactable_entry *entry = 228 - &tbl->tbl_entries[i]; 229 - u8 *mac_addr = entry->mac_addr; 230 - u8 empty_mac[ETH_ALEN] = { 0 }; 231 - 232 - v_dbg("new mac entry %4d: %02x:%02x:%02x:%02x:%02x:%02x %x\n", 233 - loffset + i, mac_addr[0], mac_addr[1], mac_addr[2], 234 - mac_addr[3], mac_addr[4], mac_addr[5], 235 - entry->dlid_sd); 236 - 237 - /* if the entry is being removed, do not add it */ 238 - if (!memcmp(mac_addr, empty_mac, ARRAY_SIZE(empty_mac))) 239 - continue; 240 - 241 - node = kzalloc_obj(*node); 242 - if (!node) { 243 - rc = -ENOMEM; 244 - goto updt_done; 245 - } 246 - 247 - node->index = loffset + i; 248 - nentry = &node->entry; 249 - memcpy(nentry->mac_addr, entry->mac_addr, 250 - ARRAY_SIZE(nentry->mac_addr)); 251 - memcpy(nentry->mac_addr_mask, entry->mac_addr_mask, 252 - ARRAY_SIZE(nentry->mac_addr_mask)); 253 - nentry->dlid_sd = be32_to_cpu(entry->dlid_sd); 254 - key = node->entry.mac_addr[OPA_VNIC_MAC_HASH_IDX]; 255 - vnic_hash_add(new_mactbl, &node->hlist, key); 256 - } 257 - 258 - /* add other entries from current mac table to new mac table */ 259 - old_mactbl = rcu_access_pointer(adapter->mactbl); 260 - if (!old_mactbl) 261 - goto switch_tbl; 262 - 263 - vnic_hash_for_each(old_mactbl, bkt, node, hlist) { 264 - if ((node->index >= loffset) && 265 - (node->index < (loffset + lnum_entries))) 266 - continue; 267 - 268 - new_node = kzalloc_obj(*new_node); 269 - if (!new_node) { 270 - rc = -ENOMEM; 271 - goto updt_done; 272 - } 273 - 274 - new_node->index = node->index; 275 - memcpy(&new_node->entry, &node->entry, sizeof(node->entry)); 276 - key = new_node->entry.mac_addr[OPA_VNIC_MAC_HASH_IDX]; 277 - vnic_hash_add(new_mactbl, &new_node->hlist, key); 278 - } 279 - 280 - switch_tbl: 281 - /* switch to new table */ 282 - rcu_assign_pointer(adapter->mactbl, new_mactbl); 283 - synchronize_rcu(); 284 - 285 - adapter->info.vport.mac_tbl_digest = be32_to_cpu(tbl->mac_tbl_digest); 286 - updt_done: 287 - /* upon failure, free the new table; otherwise, free the old table */ 288 - if (rc) 289 - opa_vnic_free_mac_tbl(new_mactbl); 290 - else 291 - opa_vnic_free_mac_tbl(old_mactbl); 292 - 293 - mutex_unlock(&adapter->mactbl_lock); 294 - return rc; 295 - } 296 - 297 - /* opa_vnic_chk_mac_tbl - check mac table for dlid */ 298 - static uint32_t opa_vnic_chk_mac_tbl(struct opa_vnic_adapter *adapter, 299 - struct ethhdr *mac_hdr) 300 - { 301 - struct opa_vnic_mac_tbl_node *node; 302 - struct hlist_head *mactbl; 303 - u32 dlid = 0; 304 - u8 key; 305 - 306 - rcu_read_lock(); 307 - mactbl = rcu_dereference(adapter->mactbl); 308 - if (unlikely(!mactbl)) 309 - goto chk_done; 310 - 311 - key = mac_hdr->h_dest[OPA_VNIC_MAC_HASH_IDX]; 312 - vnic_hash_for_each_possible(mactbl, node, hlist, key) { 313 - struct __opa_vnic_mactable_entry *entry = &node->entry; 314 - 315 - /* if related to source mac, skip */ 316 - if (unlikely(OPA_VNIC_DLID_SD_IS_SRC_MAC(entry->dlid_sd))) 317 - continue; 318 - 319 - if (!memcmp(node->entry.mac_addr, mac_hdr->h_dest, 320 - ARRAY_SIZE(node->entry.mac_addr))) { 321 - /* mac address found */ 322 - dlid = OPA_VNIC_DLID_SD_GET_DLID(node->entry.dlid_sd); 323 - break; 324 - } 325 - } 326 - 327 - chk_done: 328 - rcu_read_unlock(); 329 - return dlid; 330 - } 331 - 332 - /* opa_vnic_get_dlid - find and return the DLID */ 333 - static uint32_t opa_vnic_get_dlid(struct opa_vnic_adapter *adapter, 334 - struct sk_buff *skb, u8 def_port) 335 - { 336 - struct __opa_veswport_info *info = &adapter->info; 337 - struct ethhdr *mac_hdr = (struct ethhdr *)skb_mac_header(skb); 338 - u32 dlid; 339 - 340 - dlid = opa_vnic_chk_mac_tbl(adapter, mac_hdr); 341 - if (dlid) 342 - return dlid; 343 - 344 - if (is_multicast_ether_addr(mac_hdr->h_dest)) { 345 - dlid = info->vesw.u_mcast_dlid; 346 - } else { 347 - if (is_local_ether_addr(mac_hdr->h_dest)) { 348 - dlid = ((uint32_t)mac_hdr->h_dest[5] << 16) | 349 - ((uint32_t)mac_hdr->h_dest[4] << 8) | 350 - mac_hdr->h_dest[3]; 351 - if (unlikely(!dlid)) 352 - v_warn("Null dlid in MAC address\n"); 353 - } else if (def_port != OPA_VNIC_INVALID_PORT) { 354 - if (def_port < OPA_VESW_MAX_NUM_DEF_PORT) 355 - dlid = info->vesw.u_ucast_dlid[def_port]; 356 - } 357 - } 358 - 359 - return dlid; 360 - } 361 - 362 - /* opa_vnic_get_sc - return the service class */ 363 - static u8 opa_vnic_get_sc(struct __opa_veswport_info *info, 364 - struct sk_buff *skb) 365 - { 366 - struct ethhdr *mac_hdr = (struct ethhdr *)skb_mac_header(skb); 367 - u16 vlan_tci; 368 - u8 sc; 369 - 370 - if (!__vlan_get_tag(skb, &vlan_tci)) { 371 - u8 pcp = OPA_VNIC_VLAN_PCP(vlan_tci); 372 - 373 - if (is_multicast_ether_addr(mac_hdr->h_dest)) 374 - sc = info->vport.pcp_to_sc_mc[pcp]; 375 - else 376 - sc = info->vport.pcp_to_sc_uc[pcp]; 377 - } else { 378 - if (is_multicast_ether_addr(mac_hdr->h_dest)) 379 - sc = info->vport.non_vlan_sc_mc; 380 - else 381 - sc = info->vport.non_vlan_sc_uc; 382 - } 383 - 384 - return sc; 385 - } 386 - 387 - u8 opa_vnic_get_vl(struct opa_vnic_adapter *adapter, struct sk_buff *skb) 388 - { 389 - struct ethhdr *mac_hdr = (struct ethhdr *)skb_mac_header(skb); 390 - struct __opa_veswport_info *info = &adapter->info; 391 - u8 vl; 392 - 393 - if (skb_vlan_tag_present(skb)) { 394 - u8 pcp = skb_vlan_tag_get(skb) >> VLAN_PRIO_SHIFT; 395 - 396 - if (is_multicast_ether_addr(mac_hdr->h_dest)) 397 - vl = info->vport.pcp_to_vl_mc[pcp]; 398 - else 399 - vl = info->vport.pcp_to_vl_uc[pcp]; 400 - } else { 401 - if (is_multicast_ether_addr(mac_hdr->h_dest)) 402 - vl = info->vport.non_vlan_vl_mc; 403 - else 404 - vl = info->vport.non_vlan_vl_uc; 405 - } 406 - 407 - return vl; 408 - } 409 - 410 - /* opa_vnic_get_rc - return the routing control */ 411 - static u8 opa_vnic_get_rc(struct __opa_veswport_info *info, 412 - struct sk_buff *skb) 413 - { 414 - u8 proto, rout_ctrl; 415 - 416 - switch (vlan_get_protocol(skb)) { 417 - case htons(ETH_P_IPV6): 418 - proto = ipv6_hdr(skb)->nexthdr; 419 - if (proto == IPPROTO_TCP) 420 - rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, 421 - IPV6_TCP); 422 - else if (proto == IPPROTO_UDP) 423 - rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, 424 - IPV6_UDP); 425 - else 426 - rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, IPV6); 427 - break; 428 - case htons(ETH_P_IP): 429 - proto = ip_hdr(skb)->protocol; 430 - if (proto == IPPROTO_TCP) 431 - rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, 432 - IPV4_TCP); 433 - else if (proto == IPPROTO_UDP) 434 - rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, 435 - IPV4_UDP); 436 - else 437 - rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, IPV4); 438 - break; 439 - default: 440 - rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, DEFAULT); 441 - } 442 - 443 - return rout_ctrl; 444 - } 445 - 446 - /* opa_vnic_calc_entropy - calculate the packet entropy */ 447 - u8 opa_vnic_calc_entropy(struct sk_buff *skb) 448 - { 449 - u32 hash = skb_get_hash(skb); 450 - 451 - /* store XOR of all bytes in lower 8 bits */ 452 - hash ^= hash >> 8; 453 - hash ^= hash >> 16; 454 - 455 - /* return lower 8 bits as entropy */ 456 - return (u8)(hash & 0xFF); 457 - } 458 - 459 - /* opa_vnic_get_def_port - get default port based on entropy */ 460 - static inline u8 opa_vnic_get_def_port(struct opa_vnic_adapter *adapter, 461 - u8 entropy) 462 - { 463 - u8 flow_id; 464 - 465 - /* Add the upper and lower 4-bits of entropy to get the flow id */ 466 - flow_id = ((entropy & 0xf) + (entropy >> 4)); 467 - return adapter->flow_tbl[flow_id & (OPA_VNIC_FLOW_TBL_SIZE - 1)]; 468 - } 469 - 470 - /* Calculate packet length including OPA header, crc and padding */ 471 - static inline int opa_vnic_wire_length(struct sk_buff *skb) 472 - { 473 - u32 pad_len; 474 - 475 - /* padding for 8 bytes size alignment */ 476 - pad_len = -(skb->len + OPA_VNIC_ICRC_TAIL_LEN) & 0x7; 477 - pad_len += OPA_VNIC_ICRC_TAIL_LEN; 478 - 479 - return (skb->len + pad_len) >> 3; 480 - } 481 - 482 - /* opa_vnic_encap_skb - encapsulate skb packet with OPA header and meta data */ 483 - void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb) 484 - { 485 - struct __opa_veswport_info *info = &adapter->info; 486 - struct opa_vnic_skb_mdata *mdata; 487 - u8 def_port, sc, rc, entropy, *hdr; 488 - u16 len, l4_hdr; 489 - u32 dlid; 490 - 491 - hdr = skb_push(skb, OPA_VNIC_HDR_LEN); 492 - 493 - entropy = opa_vnic_calc_entropy(skb); 494 - def_port = opa_vnic_get_def_port(adapter, entropy); 495 - len = opa_vnic_wire_length(skb); 496 - dlid = opa_vnic_get_dlid(adapter, skb, def_port); 497 - sc = opa_vnic_get_sc(info, skb); 498 - rc = opa_vnic_get_rc(info, skb); 499 - l4_hdr = info->vesw.vesw_id; 500 - 501 - mdata = skb_push(skb, sizeof(*mdata)); 502 - mdata->vl = opa_vnic_get_vl(adapter, skb); 503 - mdata->entropy = entropy; 504 - mdata->flags = 0; 505 - if (unlikely(!dlid)) { 506 - mdata->flags = OPA_VNIC_SKB_MDATA_ENCAP_ERR; 507 - return; 508 - } 509 - 510 - opa_vnic_make_header(hdr, info->vport.encap_slid, dlid, len, 511 - info->vesw.pkey, entropy, sc, rc, 512 - OPA_VNIC_L4_ETHR, l4_hdr); 513 - }
-524
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h
··· 1 - #ifndef _OPA_VNIC_ENCAP_H 2 - #define _OPA_VNIC_ENCAP_H 3 - /* 4 - * Copyright(c) 2017 Intel Corporation. 5 - * 6 - * This file is provided under a dual BSD/GPLv2 license. When using or 7 - * redistributing this file, you may do so under either license. 8 - * 9 - * GPL LICENSE SUMMARY 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of version 2 of the GNU General Public License as 13 - * published by the Free Software Foundation. 14 - * 15 - * This program is distributed in the hope that it will be useful, but 16 - * WITHOUT ANY WARRANTY; without even the implied warranty of 17 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 - * General Public License for more details. 19 - * 20 - * BSD LICENSE 21 - * 22 - * Redistribution and use in source and binary forms, with or without 23 - * modification, are permitted provided that the following conditions 24 - * are met: 25 - * 26 - * - Redistributions of source code must retain the above copyright 27 - * notice, this list of conditions and the following disclaimer. 28 - * - Redistributions in binary form must reproduce the above copyright 29 - * notice, this list of conditions and the following disclaimer in 30 - * the documentation and/or other materials provided with the 31 - * distribution. 32 - * - Neither the name of Intel Corporation nor the names of its 33 - * contributors may be used to endorse or promote products derived 34 - * from this software without specific prior written permission. 35 - * 36 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 37 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 38 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 39 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 40 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 43 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 44 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 45 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 46 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 47 - * 48 - */ 49 - 50 - /* 51 - * This file contains all OPA VNIC declaration required for encapsulation 52 - * and decapsulation of Ethernet packets 53 - */ 54 - 55 - #include <linux/types.h> 56 - #include <rdma/ib_mad.h> 57 - 58 - /* EMA class version */ 59 - #define OPA_EMA_CLASS_VERSION 0x80 60 - 61 - /* 62 - * Define the Intel vendor management class for OPA 63 - * ETHERNET MANAGEMENT 64 - */ 65 - #define OPA_MGMT_CLASS_INTEL_EMA 0x34 66 - 67 - /* EM attribute IDs */ 68 - #define OPA_EM_ATTR_CLASS_PORT_INFO 0x0001 69 - #define OPA_EM_ATTR_VESWPORT_INFO 0x0011 70 - #define OPA_EM_ATTR_VESWPORT_MAC_ENTRIES 0x0012 71 - #define OPA_EM_ATTR_IFACE_UCAST_MACS 0x0013 72 - #define OPA_EM_ATTR_IFACE_MCAST_MACS 0x0014 73 - #define OPA_EM_ATTR_DELETE_VESW 0x0015 74 - #define OPA_EM_ATTR_VESWPORT_SUMMARY_COUNTERS 0x0020 75 - #define OPA_EM_ATTR_VESWPORT_ERROR_COUNTERS 0x0022 76 - 77 - /* VNIC configured and operational state values */ 78 - #define OPA_VNIC_STATE_DROP_ALL 0x1 79 - #define OPA_VNIC_STATE_FORWARDING 0x3 80 - 81 - #define OPA_VESW_MAX_NUM_DEF_PORT 16 82 - #define OPA_VNIC_MAX_NUM_PCP 8 83 - 84 - #define OPA_VNIC_EMA_DATA (OPA_MGMT_MAD_SIZE - IB_MGMT_VENDOR_HDR) 85 - 86 - /* Defines for vendor specific notice(trap) attributes */ 87 - #define OPA_INTEL_EMA_NOTICE_TYPE_INFO 0x04 88 - 89 - /* INTEL OUI */ 90 - #define INTEL_OUI_1 0x00 91 - #define INTEL_OUI_2 0x06 92 - #define INTEL_OUI_3 0x6a 93 - 94 - /* Trap opcodes sent from VNIC */ 95 - #define OPA_VESWPORT_TRAP_IFACE_UCAST_MAC_CHANGE 0x1 96 - #define OPA_VESWPORT_TRAP_IFACE_MCAST_MAC_CHANGE 0x2 97 - #define OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE 0x3 98 - 99 - #define OPA_VNIC_DLID_SD_IS_SRC_MAC(dlid_sd) (!!((dlid_sd) & 0x20)) 100 - #define OPA_VNIC_DLID_SD_GET_DLID(dlid_sd) ((dlid_sd) >> 8) 101 - 102 - /* VNIC Ethernet link status */ 103 - #define OPA_VNIC_ETH_LINK_UP 1 104 - #define OPA_VNIC_ETH_LINK_DOWN 2 105 - 106 - /* routing control */ 107 - #define OPA_VNIC_ENCAP_RC_DEFAULT 0 108 - #define OPA_VNIC_ENCAP_RC_IPV4 4 109 - #define OPA_VNIC_ENCAP_RC_IPV4_UDP 8 110 - #define OPA_VNIC_ENCAP_RC_IPV4_TCP 12 111 - #define OPA_VNIC_ENCAP_RC_IPV6 16 112 - #define OPA_VNIC_ENCAP_RC_IPV6_TCP 20 113 - #define OPA_VNIC_ENCAP_RC_IPV6_UDP 24 114 - 115 - #define OPA_VNIC_ENCAP_RC_EXT(w, b) (((w) >> OPA_VNIC_ENCAP_RC_ ## b) & 0x7) 116 - 117 - /** 118 - * struct opa_vesw_info - OPA vnic switch information 119 - * @fabric_id: 10-bit fabric id 120 - * @vesw_id: 12-bit virtual ethernet switch id 121 - * @rsvd0: reserved bytes 122 - * @def_port_mask: bitmask of default ports 123 - * @rsvd1: reserved bytes 124 - * @pkey: partition key 125 - * @rsvd2: reserved bytes 126 - * @u_mcast_dlid: unknown multicast dlid 127 - * @u_ucast_dlid: array of unknown unicast dlids 128 - * @rsvd3: reserved bytes 129 - * @rc: routing control 130 - * @eth_mtu: Ethernet MTU 131 - * @rsvd4: reserved bytes 132 - */ 133 - struct opa_vesw_info { 134 - __be16 fabric_id; 135 - __be16 vesw_id; 136 - 137 - u8 rsvd0[6]; 138 - __be16 def_port_mask; 139 - 140 - u8 rsvd1[2]; 141 - __be16 pkey; 142 - 143 - u8 rsvd2[4]; 144 - __be32 u_mcast_dlid; 145 - __be32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT]; 146 - 147 - __be32 rc; 148 - 149 - u8 rsvd3[56]; 150 - __be16 eth_mtu; 151 - u8 rsvd4[2]; 152 - } __packed; 153 - 154 - /** 155 - * struct opa_per_veswport_info - OPA vnic per port information 156 - * @port_num: port number 157 - * @eth_link_status: current ethernet link state 158 - * @rsvd0: reserved bytes 159 - * @base_mac_addr: base mac address 160 - * @config_state: configured port state 161 - * @oper_state: operational port state 162 - * @max_mac_tbl_ent: max number of mac table entries 163 - * @max_smac_ent: max smac entries in mac table 164 - * @mac_tbl_digest: mac table digest 165 - * @rsvd1: reserved bytes 166 - * @encap_slid: base slid for the port 167 - * @pcp_to_sc_uc: sc by pcp index for unicast ethernet packets 168 - * @pcp_to_vl_uc: vl by pcp index for unicast ethernet packets 169 - * @pcp_to_sc_mc: sc by pcp index for multicast ethernet packets 170 - * @pcp_to_vl_mc: vl by pcp index for multicast ethernet packets 171 - * @non_vlan_sc_uc: sc for non-vlan unicast ethernet packets 172 - * @non_vlan_vl_uc: vl for non-vlan unicast ethernet packets 173 - * @non_vlan_sc_mc: sc for non-vlan multicast ethernet packets 174 - * @non_vlan_vl_mc: vl for non-vlan multicast ethernet packets 175 - * @rsvd2: reserved bytes 176 - * @uc_macs_gen_count: generation count for unicast macs list 177 - * @mc_macs_gen_count: generation count for multicast macs list 178 - * @rsvd3: reserved bytes 179 - */ 180 - struct opa_per_veswport_info { 181 - __be32 port_num; 182 - 183 - u8 eth_link_status; 184 - u8 rsvd0[3]; 185 - 186 - u8 base_mac_addr[ETH_ALEN]; 187 - u8 config_state; 188 - u8 oper_state; 189 - 190 - __be16 max_mac_tbl_ent; 191 - __be16 max_smac_ent; 192 - __be32 mac_tbl_digest; 193 - u8 rsvd1[4]; 194 - 195 - __be32 encap_slid; 196 - 197 - u8 pcp_to_sc_uc[OPA_VNIC_MAX_NUM_PCP]; 198 - u8 pcp_to_vl_uc[OPA_VNIC_MAX_NUM_PCP]; 199 - u8 pcp_to_sc_mc[OPA_VNIC_MAX_NUM_PCP]; 200 - u8 pcp_to_vl_mc[OPA_VNIC_MAX_NUM_PCP]; 201 - 202 - u8 non_vlan_sc_uc; 203 - u8 non_vlan_vl_uc; 204 - u8 non_vlan_sc_mc; 205 - u8 non_vlan_vl_mc; 206 - 207 - u8 rsvd2[48]; 208 - 209 - __be16 uc_macs_gen_count; 210 - __be16 mc_macs_gen_count; 211 - 212 - u8 rsvd3[8]; 213 - } __packed; 214 - 215 - /** 216 - * struct opa_veswport_info - OPA vnic port information 217 - * @vesw: OPA vnic switch information 218 - * @vport: OPA vnic per port information 219 - * 220 - * On host, each of the virtual ethernet ports belongs 221 - * to a different virtual ethernet switches. 222 - */ 223 - struct opa_veswport_info { 224 - struct opa_vesw_info vesw; 225 - struct opa_per_veswport_info vport; 226 - }; 227 - 228 - /** 229 - * struct opa_veswport_mactable_entry - single entry in the forwarding table 230 - * @mac_addr: MAC address 231 - * @mac_addr_mask: MAC address bit mask 232 - * @dlid_sd: Matching DLID and side data 233 - * 234 - * On the host each virtual ethernet port will have 235 - * a forwarding table. These tables are used to 236 - * map a MAC to a LID and other data. For more 237 - * details see struct opa_veswport_mactable_entries. 238 - * This is the structure of a single mactable entry 239 - */ 240 - struct opa_veswport_mactable_entry { 241 - u8 mac_addr[ETH_ALEN]; 242 - u8 mac_addr_mask[ETH_ALEN]; 243 - __be32 dlid_sd; 244 - } __packed; 245 - 246 - /** 247 - * struct opa_veswport_mactable - Forwarding table array 248 - * @offset: mac table starting offset 249 - * @num_entries: Number of entries to get or set 250 - * @mac_tbl_digest: mac table digest 251 - * @tbl_entries: Array of table entries 252 - * 253 - * The EM sends down this structure in a MAD indicating 254 - * the starting offset in the forwarding table that this 255 - * entry is to be loaded into and the number of entries 256 - * that that this MAD instance contains 257 - * The mac_tbl_digest has been added to this MAD structure. It will be set by 258 - * the EM and it will be used by the EM to check if there are any 259 - * discrepancies with this value and the value 260 - * maintained by the EM in the case of VNIC port being deleted or unloaded 261 - * A new instantiation of a VNIC will always have a value of zero. 262 - * This value is stored as part of the vnic adapter structure and will be 263 - * accessed by the GET and SET routines for both the mactable entries and the 264 - * veswport info. 265 - */ 266 - struct opa_veswport_mactable { 267 - __be16 offset; 268 - __be16 num_entries; 269 - __be32 mac_tbl_digest; 270 - struct opa_veswport_mactable_entry tbl_entries[]; 271 - } __packed; 272 - 273 - /** 274 - * struct opa_veswport_summary_counters - summary counters 275 - * @vp_instance: vport instance on the OPA port 276 - * @vesw_id: virtual ethernet switch id 277 - * @veswport_num: virtual ethernet switch port number 278 - * @tx_errors: transmit errors 279 - * @rx_errors: receive errors 280 - * @tx_packets: transmit packets 281 - * @rx_packets: receive packets 282 - * @tx_bytes: transmit bytes 283 - * @rx_bytes: receive bytes 284 - * @tx_unicast: unicast packets transmitted 285 - * @tx_mcastbcast: multicast/broadcast packets transmitted 286 - * @tx_untagged: non-vlan packets transmitted 287 - * @tx_vlan: vlan packets transmitted 288 - * @tx_64_size: transmit packet length is 64 bytes 289 - * @tx_65_127: transmit packet length is >=65 and < 127 bytes 290 - * @tx_128_255: transmit packet length is >=128 and < 255 bytes 291 - * @tx_256_511: transmit packet length is >=256 and < 511 bytes 292 - * @tx_512_1023: transmit packet length is >=512 and < 1023 bytes 293 - * @tx_1024_1518: transmit packet length is >=1024 and < 1518 bytes 294 - * @tx_1519_max: transmit packet length >= 1519 bytes 295 - * @rx_unicast: unicast packets received 296 - * @rx_mcastbcast: multicast/broadcast packets received 297 - * @rx_untagged: non-vlan packets received 298 - * @rx_vlan: vlan packets received 299 - * @rx_64_size: received packet length is 64 bytes 300 - * @rx_65_127: received packet length is >=65 and < 127 bytes 301 - * @rx_128_255: received packet length is >=128 and < 255 bytes 302 - * @rx_256_511: received packet length is >=256 and < 511 bytes 303 - * @rx_512_1023: received packet length is >=512 and < 1023 bytes 304 - * @rx_1024_1518: received packet length is >=1024 and < 1518 bytes 305 - * @rx_1519_max: received packet length >= 1519 bytes 306 - * @reserved: reserved bytes 307 - * 308 - * All the above are counters of corresponding conditions. 309 - */ 310 - struct opa_veswport_summary_counters { 311 - __be16 vp_instance; 312 - __be16 vesw_id; 313 - __be32 veswport_num; 314 - 315 - __be64 tx_errors; 316 - __be64 rx_errors; 317 - __be64 tx_packets; 318 - __be64 rx_packets; 319 - __be64 tx_bytes; 320 - __be64 rx_bytes; 321 - 322 - __be64 tx_unicast; 323 - __be64 tx_mcastbcast; 324 - 325 - __be64 tx_untagged; 326 - __be64 tx_vlan; 327 - 328 - __be64 tx_64_size; 329 - __be64 tx_65_127; 330 - __be64 tx_128_255; 331 - __be64 tx_256_511; 332 - __be64 tx_512_1023; 333 - __be64 tx_1024_1518; 334 - __be64 tx_1519_max; 335 - 336 - __be64 rx_unicast; 337 - __be64 rx_mcastbcast; 338 - 339 - __be64 rx_untagged; 340 - __be64 rx_vlan; 341 - 342 - __be64 rx_64_size; 343 - __be64 rx_65_127; 344 - __be64 rx_128_255; 345 - __be64 rx_256_511; 346 - __be64 rx_512_1023; 347 - __be64 rx_1024_1518; 348 - __be64 rx_1519_max; 349 - 350 - __be64 reserved[16]; 351 - } __packed; 352 - 353 - /** 354 - * struct opa_veswport_error_counters - error counters 355 - * @vp_instance: vport instance on the OPA port 356 - * @vesw_id: virtual ethernet switch id 357 - * @veswport_num: virtual ethernet switch port number 358 - * @tx_errors: transmit errors 359 - * @rx_errors: receive errors 360 - * @rsvd0: reserved bytes 361 - * @tx_smac_filt: smac filter errors 362 - * @rsvd1: reserved bytes 363 - * @rsvd2: reserved bytes 364 - * @rsvd3: reserved bytes 365 - * @tx_dlid_zero: transmit packets with invalid dlid 366 - * @rsvd4: reserved bytes 367 - * @tx_logic: other transmit errors 368 - * @rsvd5: reserved bytes 369 - * @tx_drop_state: packet tansmission in non-forward port state 370 - * @rx_bad_veswid: received packet with invalid vesw id 371 - * @rsvd6: reserved bytes 372 - * @rx_runt: received ethernet packet with length < 64 bytes 373 - * @rx_oversize: received ethernet packet with length > MTU size 374 - * @rsvd7: reserved bytes 375 - * @rx_eth_down: received packets when interface is down 376 - * @rx_drop_state: received packets in non-forwarding port state 377 - * @rx_logic: other receive errors 378 - * @rsvd8: reserved bytes 379 - * @rsvd9: reserved bytes 380 - * 381 - * All the above are counters of corresponding error conditions. 382 - */ 383 - struct opa_veswport_error_counters { 384 - __be16 vp_instance; 385 - __be16 vesw_id; 386 - __be32 veswport_num; 387 - 388 - __be64 tx_errors; 389 - __be64 rx_errors; 390 - 391 - __be64 rsvd0; 392 - __be64 tx_smac_filt; 393 - __be64 rsvd1; 394 - __be64 rsvd2; 395 - __be64 rsvd3; 396 - __be64 tx_dlid_zero; 397 - __be64 rsvd4; 398 - __be64 tx_logic; 399 - __be64 rsvd5; 400 - __be64 tx_drop_state; 401 - 402 - __be64 rx_bad_veswid; 403 - __be64 rsvd6; 404 - __be64 rx_runt; 405 - __be64 rx_oversize; 406 - __be64 rsvd7; 407 - __be64 rx_eth_down; 408 - __be64 rx_drop_state; 409 - __be64 rx_logic; 410 - __be64 rsvd8; 411 - 412 - __be64 rsvd9[16]; 413 - } __packed; 414 - 415 - /** 416 - * struct opa_veswport_trap - Trap message sent to EM by VNIC 417 - * @fabric_id: 10 bit fabric id 418 - * @veswid: 12 bit virtual ethernet switch id 419 - * @veswportnum: logical port number on the Virtual switch 420 - * @opaportnum: physical port num (redundant on host) 421 - * @veswportindex: switch port index on opa port 0 based 422 - * @opcode: operation 423 - * @reserved: 32 bit for alignment 424 - * 425 - * The VNIC will send trap messages to the Ethernet manager to 426 - * inform it about changes to the VNIC config, behaviour etc. 427 - * This is the format of the trap payload. 428 - */ 429 - struct opa_veswport_trap { 430 - __be16 fabric_id; 431 - __be16 veswid; 432 - __be32 veswportnum; 433 - __be16 opaportnum; 434 - u8 veswportindex; 435 - u8 opcode; 436 - __be32 reserved; 437 - } __packed; 438 - 439 - /** 440 - * struct opa_vnic_iface_mac_entry - single entry in the mac list 441 - * @mac_addr: MAC address 442 - */ 443 - struct opa_vnic_iface_mac_entry { 444 - u8 mac_addr[ETH_ALEN]; 445 - }; 446 - 447 - /** 448 - * struct opa_veswport_iface_macs - Msg to set globally administered MAC 449 - * @start_idx: position of first entry (0 based) 450 - * @num_macs_in_msg: number of MACs in this message 451 - * @tot_macs_in_lst: The total number of MACs the agent has 452 - * @gen_count: gen_count to indicate change 453 - * @entry: The mac list entry 454 - * 455 - * Same attribute IDS and attribute modifiers as in locally administered 456 - * addresses used to set globally administered addresses 457 - */ 458 - struct opa_veswport_iface_macs { 459 - __be16 start_idx; 460 - __be16 num_macs_in_msg; 461 - __be16 tot_macs_in_lst; 462 - __be16 gen_count; 463 - struct opa_vnic_iface_mac_entry entry[]; 464 - } __packed; 465 - 466 - /** 467 - * struct opa_vnic_vema_mad - Generic VEMA MAD 468 - * @mad_hdr: Generic MAD header 469 - * @rmpp_hdr: RMPP header for vendor specific MADs 470 - * @reserved: reserved bytes 471 - * @oui: Unique org identifier 472 - * @data: MAD data 473 - */ 474 - struct opa_vnic_vema_mad { 475 - struct ib_mad_hdr mad_hdr; 476 - struct ib_rmpp_hdr rmpp_hdr; 477 - u8 reserved; 478 - u8 oui[3]; 479 - u8 data[OPA_VNIC_EMA_DATA]; 480 - }; 481 - 482 - /** 483 - * struct opa_vnic_notice_attr - Generic Notice MAD 484 - * @gen_type: Generic/Specific bit and type of notice 485 - * @oui_1: Vendor ID byte 1 486 - * @oui_2: Vendor ID byte 2 487 - * @oui_3: Vendor ID byte 3 488 - * @trap_num: Trap number 489 - * @toggle_count: Notice toggle bit and count value 490 - * @issuer_lid: Trap issuer's lid 491 - * @reserved: reserved bytes 492 - * @issuer_gid: Issuer GID (only if Report method) 493 - * @raw_data: Trap message body 494 - */ 495 - struct opa_vnic_notice_attr { 496 - u8 gen_type; 497 - u8 oui_1; 498 - u8 oui_2; 499 - u8 oui_3; 500 - __be16 trap_num; 501 - __be16 toggle_count; 502 - __be32 issuer_lid; 503 - __be32 reserved; 504 - u8 issuer_gid[16]; 505 - u8 raw_data[64]; 506 - } __packed; 507 - 508 - /** 509 - * struct opa_vnic_vema_mad_trap - Generic VEMA MAD Trap 510 - * @mad_hdr: Generic MAD header 511 - * @rmpp_hdr: RMPP header for vendor specific MADs 512 - * @reserved: reserved bytes 513 - * @oui: Unique org identifier 514 - * @notice: Notice structure 515 - */ 516 - struct opa_vnic_vema_mad_trap { 517 - struct ib_mad_hdr mad_hdr; 518 - struct ib_rmpp_hdr rmpp_hdr; 519 - u8 reserved; 520 - u8 oui[3]; 521 - struct opa_vnic_notice_attr notice; 522 - }; 523 - 524 - #endif /* _OPA_VNIC_ENCAP_H */
-183
drivers/infiniband/ulp/opa_vnic/opa_vnic_ethtool.c
··· 1 - /* 2 - * Copyright(c) 2017 Intel Corporation. 3 - * 4 - * This file is provided under a dual BSD/GPLv2 license. When using or 5 - * redistributing this file, you may do so under either license. 6 - * 7 - * GPL LICENSE SUMMARY 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of version 2 of the GNU General Public License as 11 - * published by the Free Software Foundation. 12 - * 13 - * This program is distributed in the hope that it will be useful, but 14 - * WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 - * General Public License for more details. 17 - * 18 - * BSD LICENSE 19 - * 20 - * Redistribution and use in source and binary forms, with or without 21 - * modification, are permitted provided that the following conditions 22 - * are met: 23 - * 24 - * - Redistributions of source code must retain the above copyright 25 - * notice, this list of conditions and the following disclaimer. 26 - * - Redistributions in binary form must reproduce the above copyright 27 - * notice, this list of conditions and the following disclaimer in 28 - * the documentation and/or other materials provided with the 29 - * distribution. 30 - * - Neither the name of Intel Corporation nor the names of its 31 - * contributors may be used to endorse or promote products derived 32 - * from this software without specific prior written permission. 33 - * 34 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 35 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 36 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 37 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 38 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 39 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 40 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 41 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 42 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 43 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 44 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 - * 46 - */ 47 - 48 - /* 49 - * This file contains OPA VNIC ethtool functions 50 - */ 51 - 52 - #include <linux/ethtool.h> 53 - 54 - #include "opa_vnic_internal.h" 55 - 56 - enum {NETDEV_STATS, VNIC_STATS}; 57 - 58 - struct vnic_stats { 59 - char stat_string[ETH_GSTRING_LEN]; 60 - struct { 61 - int sizeof_stat; 62 - int stat_offset; 63 - }; 64 - }; 65 - 66 - #define VNIC_STAT(m) { sizeof_field(struct opa_vnic_stats, m), \ 67 - offsetof(struct opa_vnic_stats, m) } 68 - 69 - static struct vnic_stats vnic_gstrings_stats[] = { 70 - /* NETDEV stats */ 71 - {"rx_packets", VNIC_STAT(netstats.rx_packets)}, 72 - {"tx_packets", VNIC_STAT(netstats.tx_packets)}, 73 - {"rx_bytes", VNIC_STAT(netstats.rx_bytes)}, 74 - {"tx_bytes", VNIC_STAT(netstats.tx_bytes)}, 75 - {"rx_errors", VNIC_STAT(netstats.rx_errors)}, 76 - {"tx_errors", VNIC_STAT(netstats.tx_errors)}, 77 - {"rx_dropped", VNIC_STAT(netstats.rx_dropped)}, 78 - {"tx_dropped", VNIC_STAT(netstats.tx_dropped)}, 79 - 80 - /* SUMMARY counters */ 81 - {"tx_unicast", VNIC_STAT(tx_grp.unicast)}, 82 - {"tx_mcastbcast", VNIC_STAT(tx_grp.mcastbcast)}, 83 - {"tx_untagged", VNIC_STAT(tx_grp.untagged)}, 84 - {"tx_vlan", VNIC_STAT(tx_grp.vlan)}, 85 - 86 - {"tx_64_size", VNIC_STAT(tx_grp.s_64)}, 87 - {"tx_65_127", VNIC_STAT(tx_grp.s_65_127)}, 88 - {"tx_128_255", VNIC_STAT(tx_grp.s_128_255)}, 89 - {"tx_256_511", VNIC_STAT(tx_grp.s_256_511)}, 90 - {"tx_512_1023", VNIC_STAT(tx_grp.s_512_1023)}, 91 - {"tx_1024_1518", VNIC_STAT(tx_grp.s_1024_1518)}, 92 - {"tx_1519_max", VNIC_STAT(tx_grp.s_1519_max)}, 93 - 94 - {"rx_unicast", VNIC_STAT(rx_grp.unicast)}, 95 - {"rx_mcastbcast", VNIC_STAT(rx_grp.mcastbcast)}, 96 - {"rx_untagged", VNIC_STAT(rx_grp.untagged)}, 97 - {"rx_vlan", VNIC_STAT(rx_grp.vlan)}, 98 - 99 - {"rx_64_size", VNIC_STAT(rx_grp.s_64)}, 100 - {"rx_65_127", VNIC_STAT(rx_grp.s_65_127)}, 101 - {"rx_128_255", VNIC_STAT(rx_grp.s_128_255)}, 102 - {"rx_256_511", VNIC_STAT(rx_grp.s_256_511)}, 103 - {"rx_512_1023", VNIC_STAT(rx_grp.s_512_1023)}, 104 - {"rx_1024_1518", VNIC_STAT(rx_grp.s_1024_1518)}, 105 - {"rx_1519_max", VNIC_STAT(rx_grp.s_1519_max)}, 106 - 107 - /* ERROR counters */ 108 - {"rx_fifo_errors", VNIC_STAT(netstats.rx_fifo_errors)}, 109 - {"rx_length_errors", VNIC_STAT(netstats.rx_length_errors)}, 110 - 111 - {"tx_fifo_errors", VNIC_STAT(netstats.tx_fifo_errors)}, 112 - {"tx_carrier_errors", VNIC_STAT(netstats.tx_carrier_errors)}, 113 - 114 - {"tx_dlid_zero", VNIC_STAT(tx_dlid_zero)}, 115 - {"tx_drop_state", VNIC_STAT(tx_drop_state)}, 116 - {"rx_drop_state", VNIC_STAT(rx_drop_state)}, 117 - {"rx_oversize", VNIC_STAT(rx_oversize)}, 118 - {"rx_runt", VNIC_STAT(rx_runt)}, 119 - }; 120 - 121 - #define VNIC_STATS_LEN ARRAY_SIZE(vnic_gstrings_stats) 122 - 123 - /* vnic_get_drvinfo - get driver info */ 124 - static void vnic_get_drvinfo(struct net_device *netdev, 125 - struct ethtool_drvinfo *drvinfo) 126 - { 127 - strscpy(drvinfo->driver, opa_vnic_driver_name, sizeof(drvinfo->driver)); 128 - strscpy(drvinfo->bus_info, dev_name(netdev->dev.parent), 129 - sizeof(drvinfo->bus_info)); 130 - } 131 - 132 - /* vnic_get_sset_count - get string set count */ 133 - static int vnic_get_sset_count(struct net_device *netdev, int sset) 134 - { 135 - return (sset == ETH_SS_STATS) ? VNIC_STATS_LEN : -EOPNOTSUPP; 136 - } 137 - 138 - /* vnic_get_ethtool_stats - get statistics */ 139 - static void vnic_get_ethtool_stats(struct net_device *netdev, 140 - struct ethtool_stats *stats, u64 *data) 141 - { 142 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 143 - struct opa_vnic_stats vstats; 144 - int i; 145 - 146 - memset(&vstats, 0, sizeof(vstats)); 147 - spin_lock(&adapter->stats_lock); 148 - adapter->rn_ops->ndo_get_stats64(netdev, &vstats.netstats); 149 - spin_unlock(&adapter->stats_lock); 150 - for (i = 0; i < VNIC_STATS_LEN; i++) { 151 - char *p = (char *)&vstats + vnic_gstrings_stats[i].stat_offset; 152 - 153 - data[i] = (vnic_gstrings_stats[i].sizeof_stat == 154 - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 155 - } 156 - } 157 - 158 - /* vnic_get_strings - get strings */ 159 - static void vnic_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 160 - { 161 - int i; 162 - 163 - if (stringset != ETH_SS_STATS) 164 - return; 165 - 166 - for (i = 0; i < VNIC_STATS_LEN; i++) 167 - ethtool_puts(&data, vnic_gstrings_stats[i].stat_string); 168 - } 169 - 170 - /* ethtool ops */ 171 - static const struct ethtool_ops opa_vnic_ethtool_ops = { 172 - .get_drvinfo = vnic_get_drvinfo, 173 - .get_link = ethtool_op_get_link, 174 - .get_strings = vnic_get_strings, 175 - .get_sset_count = vnic_get_sset_count, 176 - .get_ethtool_stats = vnic_get_ethtool_stats, 177 - }; 178 - 179 - /* opa_vnic_set_ethtool_ops - set ethtool ops */ 180 - void opa_vnic_set_ethtool_ops(struct net_device *netdev) 181 - { 182 - netdev->ethtool_ops = &opa_vnic_ethtool_ops; 183 - }
-329
drivers/infiniband/ulp/opa_vnic/opa_vnic_internal.h
··· 1 - #ifndef _OPA_VNIC_INTERNAL_H 2 - #define _OPA_VNIC_INTERNAL_H 3 - /* 4 - * Copyright(c) 2017 Intel Corporation. 5 - * 6 - * This file is provided under a dual BSD/GPLv2 license. When using or 7 - * redistributing this file, you may do so under either license. 8 - * 9 - * GPL LICENSE SUMMARY 10 - * 11 - * This program is free software; you can redistribute it and/or modify 12 - * it under the terms of version 2 of the GNU General Public License as 13 - * published by the Free Software Foundation. 14 - * 15 - * This program is distributed in the hope that it will be useful, but 16 - * WITHOUT ANY WARRANTY; without even the implied warranty of 17 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 - * General Public License for more details. 19 - * 20 - * BSD LICENSE 21 - * 22 - * Redistribution and use in source and binary forms, with or without 23 - * modification, are permitted provided that the following conditions 24 - * are met: 25 - * 26 - * - Redistributions of source code must retain the above copyright 27 - * notice, this list of conditions and the following disclaimer. 28 - * - Redistributions in binary form must reproduce the above copyright 29 - * notice, this list of conditions and the following disclaimer in 30 - * the documentation and/or other materials provided with the 31 - * distribution. 32 - * - Neither the name of Intel Corporation nor the names of its 33 - * contributors may be used to endorse or promote products derived 34 - * from this software without specific prior written permission. 35 - * 36 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 37 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 38 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 39 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 40 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 42 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 43 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 44 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 45 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 46 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 47 - * 48 - */ 49 - 50 - /* 51 - * This file contains OPA VNIC driver internal declarations 52 - */ 53 - 54 - #include <linux/bitops.h> 55 - #include <linux/etherdevice.h> 56 - #include <linux/hashtable.h> 57 - #include <linux/sizes.h> 58 - #include <rdma/opa_vnic.h> 59 - 60 - #include "opa_vnic_encap.h" 61 - 62 - #define OPA_VNIC_VLAN_PCP(vlan_tci) \ 63 - (((vlan_tci) & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT) 64 - 65 - /* Flow to default port redirection table size */ 66 - #define OPA_VNIC_FLOW_TBL_SIZE 32 67 - 68 - /* Invalid port number */ 69 - #define OPA_VNIC_INVALID_PORT 0xff 70 - 71 - struct opa_vnic_adapter; 72 - 73 - /* 74 - * struct __opa_vesw_info - OPA vnic virtual switch info 75 - * 76 - * Same as opa_vesw_info without bitwise attribute. 77 - */ 78 - struct __opa_vesw_info { 79 - u16 fabric_id; 80 - u16 vesw_id; 81 - 82 - u8 rsvd0[6]; 83 - u16 def_port_mask; 84 - 85 - u8 rsvd1[2]; 86 - u16 pkey; 87 - 88 - u8 rsvd2[4]; 89 - u32 u_mcast_dlid; 90 - u32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT]; 91 - 92 - u32 rc; 93 - 94 - u8 rsvd3[56]; 95 - u16 eth_mtu; 96 - u8 rsvd4[2]; 97 - } __packed; 98 - 99 - /* 100 - * struct __opa_per_veswport_info - OPA vnic per port info 101 - * 102 - * Same as opa_per_veswport_info without bitwise attribute. 103 - */ 104 - struct __opa_per_veswport_info { 105 - u32 port_num; 106 - 107 - u8 eth_link_status; 108 - u8 rsvd0[3]; 109 - 110 - u8 base_mac_addr[ETH_ALEN]; 111 - u8 config_state; 112 - u8 oper_state; 113 - 114 - u16 max_mac_tbl_ent; 115 - u16 max_smac_ent; 116 - u32 mac_tbl_digest; 117 - u8 rsvd1[4]; 118 - 119 - u32 encap_slid; 120 - 121 - u8 pcp_to_sc_uc[OPA_VNIC_MAX_NUM_PCP]; 122 - u8 pcp_to_vl_uc[OPA_VNIC_MAX_NUM_PCP]; 123 - u8 pcp_to_sc_mc[OPA_VNIC_MAX_NUM_PCP]; 124 - u8 pcp_to_vl_mc[OPA_VNIC_MAX_NUM_PCP]; 125 - 126 - u8 non_vlan_sc_uc; 127 - u8 non_vlan_vl_uc; 128 - u8 non_vlan_sc_mc; 129 - u8 non_vlan_vl_mc; 130 - 131 - u8 rsvd2[48]; 132 - 133 - u16 uc_macs_gen_count; 134 - u16 mc_macs_gen_count; 135 - 136 - u8 rsvd3[8]; 137 - } __packed; 138 - 139 - /* 140 - * struct __opa_veswport_info - OPA vnic port info 141 - * 142 - * Same as opa_veswport_info without bitwise attribute. 143 - */ 144 - struct __opa_veswport_info { 145 - struct __opa_vesw_info vesw; 146 - struct __opa_per_veswport_info vport; 147 - }; 148 - 149 - /* 150 - * struct __opa_veswport_trap - OPA vnic trap info 151 - * 152 - * Same as opa_veswport_trap without bitwise attribute. 153 - */ 154 - struct __opa_veswport_trap { 155 - u16 fabric_id; 156 - u16 veswid; 157 - u32 veswportnum; 158 - u16 opaportnum; 159 - u8 veswportindex; 160 - u8 opcode; 161 - u32 reserved; 162 - } __packed; 163 - 164 - /** 165 - * struct opa_vnic_ctrl_port - OPA virtual NIC control port 166 - * @ibdev: pointer to ib device 167 - * @ops: opa vnic control operations 168 - * @num_ports: number of opa ports 169 - */ 170 - struct opa_vnic_ctrl_port { 171 - struct ib_device *ibdev; 172 - struct opa_vnic_ctrl_ops *ops; 173 - u8 num_ports; 174 - }; 175 - 176 - /** 177 - * struct opa_vnic_adapter - OPA VNIC netdev private data structure 178 - * @netdev: pointer to associated netdev 179 - * @ibdev: ib device 180 - * @cport: pointer to opa vnic control port 181 - * @rn_ops: rdma netdev's net_device_ops 182 - * @port_num: OPA port number 183 - * @vport_num: vesw port number 184 - * @lock: adapter lock 185 - * @info: virtual ethernet switch port information 186 - * @vema_mac_addr: mac address configured by vema 187 - * @umac_hash: unicast maclist hash 188 - * @mmac_hash: multicast maclist hash 189 - * @mactbl: hash table of MAC entries 190 - * @mactbl_lock: mac table lock 191 - * @stats_lock: statistics lock 192 - * @flow_tbl: flow to default port redirection table 193 - * @trap_timeout: trap timeout 194 - * @trap_count: no. of traps allowed within timeout period 195 - */ 196 - struct opa_vnic_adapter { 197 - struct net_device *netdev; 198 - struct ib_device *ibdev; 199 - struct opa_vnic_ctrl_port *cport; 200 - const struct net_device_ops *rn_ops; 201 - 202 - u8 port_num; 203 - u8 vport_num; 204 - 205 - /* Lock used around concurrent updates to netdev */ 206 - struct mutex lock; 207 - 208 - struct __opa_veswport_info info; 209 - u8 vema_mac_addr[ETH_ALEN]; 210 - u32 umac_hash; 211 - u32 mmac_hash; 212 - struct hlist_head __rcu *mactbl; 213 - 214 - /* Lock used to protect updates to mac table */ 215 - struct mutex mactbl_lock; 216 - 217 - /* Lock used to protect access to vnic counters */ 218 - spinlock_t stats_lock; 219 - 220 - u8 flow_tbl[OPA_VNIC_FLOW_TBL_SIZE]; 221 - 222 - unsigned long trap_timeout; 223 - u8 trap_count; 224 - }; 225 - 226 - /* Same as opa_veswport_mactable_entry, but without bitwise attribute */ 227 - struct __opa_vnic_mactable_entry { 228 - u8 mac_addr[ETH_ALEN]; 229 - u8 mac_addr_mask[ETH_ALEN]; 230 - u32 dlid_sd; 231 - } __packed; 232 - 233 - /** 234 - * struct opa_vnic_mac_tbl_node - OPA VNIC mac table node 235 - * @hlist: hash list handle 236 - * @index: index of entry in the mac table 237 - * @entry: entry in the table 238 - */ 239 - struct opa_vnic_mac_tbl_node { 240 - struct hlist_node hlist; 241 - u16 index; 242 - struct __opa_vnic_mactable_entry entry; 243 - }; 244 - 245 - #define v_dbg(format, arg...) \ 246 - netdev_dbg(adapter->netdev, format, ## arg) 247 - #define v_err(format, arg...) \ 248 - netdev_err(adapter->netdev, format, ## arg) 249 - #define v_info(format, arg...) \ 250 - netdev_info(adapter->netdev, format, ## arg) 251 - #define v_warn(format, arg...) \ 252 - netdev_warn(adapter->netdev, format, ## arg) 253 - 254 - #define c_err(format, arg...) \ 255 - dev_err(&cport->ibdev->dev, format, ## arg) 256 - #define c_info(format, arg...) \ 257 - dev_info(&cport->ibdev->dev, format, ## arg) 258 - #define c_dbg(format, arg...) \ 259 - dev_dbg(&cport->ibdev->dev, format, ## arg) 260 - 261 - /* The maximum allowed entries in the mac table */ 262 - #define OPA_VNIC_MAC_TBL_MAX_ENTRIES 2048 263 - /* Limit of smac entries in mac table */ 264 - #define OPA_VNIC_MAX_SMAC_LIMIT 256 265 - 266 - /* The last octet of the MAC address is used as the key to the hash table */ 267 - #define OPA_VNIC_MAC_HASH_IDX 5 268 - 269 - /* The VNIC MAC hash table is of size 2^8 */ 270 - #define OPA_VNIC_MAC_TBL_HASH_BITS 8 271 - #define OPA_VNIC_MAC_TBL_SIZE BIT(OPA_VNIC_MAC_TBL_HASH_BITS) 272 - 273 - /* VNIC HASH MACROS */ 274 - #define vnic_hash_init(hashtable) __hash_init(hashtable, OPA_VNIC_MAC_TBL_SIZE) 275 - 276 - #define vnic_hash_add(hashtable, node, key) \ 277 - hlist_add_head(node, \ 278 - &hashtable[hash_min(key, ilog2(OPA_VNIC_MAC_TBL_SIZE))]) 279 - 280 - #define vnic_hash_for_each_safe(name, bkt, tmp, obj, member) \ 281 - for ((bkt) = 0, obj = NULL; \ 282 - !obj && (bkt) < OPA_VNIC_MAC_TBL_SIZE; (bkt)++) \ 283 - hlist_for_each_entry_safe(obj, tmp, &name[bkt], member) 284 - 285 - #define vnic_hash_for_each_possible(name, obj, member, key) \ 286 - hlist_for_each_entry(obj, \ 287 - &name[hash_min(key, ilog2(OPA_VNIC_MAC_TBL_SIZE))], member) 288 - 289 - #define vnic_hash_for_each(name, bkt, obj, member) \ 290 - for ((bkt) = 0, obj = NULL; \ 291 - !obj && (bkt) < OPA_VNIC_MAC_TBL_SIZE; (bkt)++) \ 292 - hlist_for_each_entry(obj, &name[bkt], member) 293 - 294 - extern char opa_vnic_driver_name[]; 295 - 296 - struct opa_vnic_adapter *opa_vnic_add_netdev(struct ib_device *ibdev, 297 - u8 port_num, u8 vport_num); 298 - void opa_vnic_rem_netdev(struct opa_vnic_adapter *adapter); 299 - void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb); 300 - u8 opa_vnic_get_vl(struct opa_vnic_adapter *adapter, struct sk_buff *skb); 301 - u8 opa_vnic_calc_entropy(struct sk_buff *skb); 302 - void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter); 303 - void opa_vnic_release_mac_tbl(struct opa_vnic_adapter *adapter); 304 - void opa_vnic_query_mac_tbl(struct opa_vnic_adapter *adapter, 305 - struct opa_veswport_mactable *tbl); 306 - int opa_vnic_update_mac_tbl(struct opa_vnic_adapter *adapter, 307 - struct opa_veswport_mactable *tbl); 308 - void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter, 309 - struct opa_veswport_iface_macs *macs); 310 - void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter, 311 - struct opa_veswport_iface_macs *macs); 312 - void opa_vnic_get_summary_counters(struct opa_vnic_adapter *adapter, 313 - struct opa_veswport_summary_counters *cntrs); 314 - void opa_vnic_get_error_counters(struct opa_vnic_adapter *adapter, 315 - struct opa_veswport_error_counters *cntrs); 316 - void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter, 317 - struct opa_vesw_info *info); 318 - void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter, 319 - struct opa_vesw_info *info); 320 - void opa_vnic_get_per_veswport_info(struct opa_vnic_adapter *adapter, 321 - struct opa_per_veswport_info *info); 322 - void opa_vnic_set_per_veswport_info(struct opa_vnic_adapter *adapter, 323 - struct opa_per_veswport_info *info); 324 - void opa_vnic_vema_report_event(struct opa_vnic_adapter *adapter, u8 event); 325 - void opa_vnic_set_ethtool_ops(struct net_device *netdev); 326 - void opa_vnic_vema_send_trap(struct opa_vnic_adapter *adapter, 327 - struct __opa_veswport_trap *data, u32 lid); 328 - 329 - #endif /* _OPA_VNIC_INTERNAL_H */
-400
drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c
··· 1 - /* 2 - * Copyright(c) 2017 Intel Corporation. 3 - * 4 - * This file is provided under a dual BSD/GPLv2 license. When using or 5 - * redistributing this file, you may do so under either license. 6 - * 7 - * GPL LICENSE SUMMARY 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of version 2 of the GNU General Public License as 11 - * published by the Free Software Foundation. 12 - * 13 - * This program is distributed in the hope that it will be useful, but 14 - * WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 - * General Public License for more details. 17 - * 18 - * BSD LICENSE 19 - * 20 - * Redistribution and use in source and binary forms, with or without 21 - * modification, are permitted provided that the following conditions 22 - * are met: 23 - * 24 - * - Redistributions of source code must retain the above copyright 25 - * notice, this list of conditions and the following disclaimer. 26 - * - Redistributions in binary form must reproduce the above copyright 27 - * notice, this list of conditions and the following disclaimer in 28 - * the documentation and/or other materials provided with the 29 - * distribution. 30 - * - Neither the name of Intel Corporation nor the names of its 31 - * contributors may be used to endorse or promote products derived 32 - * from this software without specific prior written permission. 33 - * 34 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 35 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 36 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 37 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 38 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 39 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 40 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 41 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 42 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 43 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 44 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 - * 46 - */ 47 - 48 - /* 49 - * This file contains OPA Virtual Network Interface Controller (VNIC) driver 50 - * netdev functionality. 51 - */ 52 - 53 - #include <linux/if_vlan.h> 54 - #include <linux/crc32.h> 55 - 56 - #include "opa_vnic_internal.h" 57 - 58 - #define OPA_TX_TIMEOUT_MS 1000 59 - 60 - #define OPA_VNIC_SKB_HEADROOM \ 61 - ALIGN((OPA_VNIC_HDR_LEN + OPA_VNIC_SKB_MDATA_LEN), 8) 62 - 63 - /* This function is overloaded for opa_vnic specific implementation */ 64 - static void opa_vnic_get_stats64(struct net_device *netdev, 65 - struct rtnl_link_stats64 *stats) 66 - { 67 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 68 - struct opa_vnic_stats vstats; 69 - 70 - memset(&vstats, 0, sizeof(vstats)); 71 - spin_lock(&adapter->stats_lock); 72 - adapter->rn_ops->ndo_get_stats64(netdev, &vstats.netstats); 73 - spin_unlock(&adapter->stats_lock); 74 - memcpy(stats, &vstats.netstats, sizeof(*stats)); 75 - } 76 - 77 - /* opa_netdev_start_xmit - transmit function */ 78 - static netdev_tx_t opa_netdev_start_xmit(struct sk_buff *skb, 79 - struct net_device *netdev) 80 - { 81 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 82 - 83 - v_dbg("xmit: queue %d skb len %d\n", skb->queue_mapping, skb->len); 84 - /* pad to ensure mininum ethernet packet length */ 85 - if (unlikely(skb->len < ETH_ZLEN)) { 86 - if (skb_padto(skb, ETH_ZLEN)) 87 - return NETDEV_TX_OK; 88 - 89 - skb_put(skb, ETH_ZLEN - skb->len); 90 - } 91 - 92 - opa_vnic_encap_skb(adapter, skb); 93 - return adapter->rn_ops->ndo_start_xmit(skb, netdev); 94 - } 95 - 96 - static u16 opa_vnic_select_queue(struct net_device *netdev, struct sk_buff *skb, 97 - struct net_device *sb_dev) 98 - { 99 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 100 - struct opa_vnic_skb_mdata *mdata; 101 - int rc; 102 - 103 - /* pass entropy and vl as metadata in skb */ 104 - mdata = skb_push(skb, sizeof(*mdata)); 105 - mdata->entropy = opa_vnic_calc_entropy(skb); 106 - mdata->vl = opa_vnic_get_vl(adapter, skb); 107 - rc = adapter->rn_ops->ndo_select_queue(netdev, skb, sb_dev); 108 - skb_pull(skb, sizeof(*mdata)); 109 - return rc; 110 - } 111 - 112 - static void opa_vnic_update_state(struct opa_vnic_adapter *adapter, bool up) 113 - { 114 - struct __opa_veswport_info *info = &adapter->info; 115 - 116 - mutex_lock(&adapter->lock); 117 - /* Operational state can only be DROP_ALL or FORWARDING */ 118 - if ((info->vport.config_state == OPA_VNIC_STATE_FORWARDING) && up) { 119 - info->vport.oper_state = OPA_VNIC_STATE_FORWARDING; 120 - info->vport.eth_link_status = OPA_VNIC_ETH_LINK_UP; 121 - } else { 122 - info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL; 123 - info->vport.eth_link_status = OPA_VNIC_ETH_LINK_DOWN; 124 - } 125 - 126 - if (info->vport.config_state == OPA_VNIC_STATE_FORWARDING) 127 - netif_dormant_off(adapter->netdev); 128 - else 129 - netif_dormant_on(adapter->netdev); 130 - mutex_unlock(&adapter->lock); 131 - } 132 - 133 - /* opa_vnic_process_vema_config - process vema configuration updates */ 134 - void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter) 135 - { 136 - struct __opa_veswport_info *info = &adapter->info; 137 - struct rdma_netdev *rn = netdev_priv(adapter->netdev); 138 - u8 port_num[OPA_VESW_MAX_NUM_DEF_PORT] = { 0 }; 139 - struct net_device *netdev = adapter->netdev; 140 - u8 i, port_count = 0; 141 - u16 port_mask; 142 - 143 - /* If the base_mac_addr is changed, update the interface mac address */ 144 - if (memcmp(info->vport.base_mac_addr, adapter->vema_mac_addr, 145 - ARRAY_SIZE(info->vport.base_mac_addr))) { 146 - struct sockaddr saddr; 147 - 148 - memcpy(saddr.sa_data, info->vport.base_mac_addr, 149 - ARRAY_SIZE(info->vport.base_mac_addr)); 150 - mutex_lock(&adapter->lock); 151 - eth_commit_mac_addr_change(netdev, &saddr); 152 - memcpy(adapter->vema_mac_addr, 153 - info->vport.base_mac_addr, ETH_ALEN); 154 - mutex_unlock(&adapter->lock); 155 - } 156 - 157 - rn->set_id(netdev, info->vesw.vesw_id); 158 - 159 - /* Handle MTU limit change */ 160 - rtnl_lock(); 161 - netdev->max_mtu = max_t(unsigned int, info->vesw.eth_mtu, 162 - netdev->min_mtu); 163 - if (netdev->mtu > netdev->max_mtu) 164 - dev_set_mtu(netdev, netdev->max_mtu); 165 - rtnl_unlock(); 166 - 167 - /* Update flow to default port redirection table */ 168 - port_mask = info->vesw.def_port_mask; 169 - for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++) { 170 - if (port_mask & 1) 171 - port_num[port_count++] = i; 172 - port_mask >>= 1; 173 - } 174 - 175 - /* 176 - * Build the flow table. Flow table is required when destination LID 177 - * is not available. Up to OPA_VNIC_FLOW_TBL_SIZE flows supported. 178 - * Each flow need a default port number to get its dlid from the 179 - * u_ucast_dlid array. 180 - */ 181 - for (i = 0; i < OPA_VNIC_FLOW_TBL_SIZE; i++) 182 - adapter->flow_tbl[i] = port_count ? port_num[i % port_count] : 183 - OPA_VNIC_INVALID_PORT; 184 - 185 - /* update state */ 186 - opa_vnic_update_state(adapter, !!(netdev->flags & IFF_UP)); 187 - } 188 - 189 - /* 190 - * Set the power on default values in adapter's vema interface structure. 191 - */ 192 - static inline void opa_vnic_set_pod_values(struct opa_vnic_adapter *adapter) 193 - { 194 - adapter->info.vport.max_mac_tbl_ent = OPA_VNIC_MAC_TBL_MAX_ENTRIES; 195 - adapter->info.vport.max_smac_ent = OPA_VNIC_MAX_SMAC_LIMIT; 196 - adapter->info.vport.config_state = OPA_VNIC_STATE_DROP_ALL; 197 - adapter->info.vport.eth_link_status = OPA_VNIC_ETH_LINK_DOWN; 198 - adapter->info.vesw.eth_mtu = ETH_DATA_LEN; 199 - } 200 - 201 - /* opa_vnic_set_mac_addr - change mac address */ 202 - static int opa_vnic_set_mac_addr(struct net_device *netdev, void *addr) 203 - { 204 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 205 - struct sockaddr *sa = addr; 206 - int rc; 207 - 208 - if (!memcmp(netdev->dev_addr, sa->sa_data, ETH_ALEN)) 209 - return 0; 210 - 211 - mutex_lock(&adapter->lock); 212 - rc = eth_mac_addr(netdev, addr); 213 - mutex_unlock(&adapter->lock); 214 - if (rc) 215 - return rc; 216 - 217 - adapter->info.vport.uc_macs_gen_count++; 218 - opa_vnic_vema_report_event(adapter, 219 - OPA_VESWPORT_TRAP_IFACE_UCAST_MAC_CHANGE); 220 - return 0; 221 - } 222 - 223 - /* 224 - * opa_vnic_mac_send_event - post event on possible mac list exchange 225 - * Send trap when digest from uc/mc mac list differs from previous run. 226 - * Digest is evaluated similar to how cksum does. 227 - */ 228 - static void opa_vnic_mac_send_event(struct net_device *netdev, u8 event) 229 - { 230 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 231 - struct netdev_hw_addr *ha; 232 - struct netdev_hw_addr_list *hw_list; 233 - u32 *ref_crc; 234 - u32 l, crc = 0; 235 - 236 - switch (event) { 237 - case OPA_VESWPORT_TRAP_IFACE_UCAST_MAC_CHANGE: 238 - hw_list = &netdev->uc; 239 - adapter->info.vport.uc_macs_gen_count++; 240 - ref_crc = &adapter->umac_hash; 241 - break; 242 - case OPA_VESWPORT_TRAP_IFACE_MCAST_MAC_CHANGE: 243 - hw_list = &netdev->mc; 244 - adapter->info.vport.mc_macs_gen_count++; 245 - ref_crc = &adapter->mmac_hash; 246 - break; 247 - default: 248 - return; 249 - } 250 - netdev_hw_addr_list_for_each(ha, hw_list) { 251 - crc = crc32_le(crc, ha->addr, ETH_ALEN); 252 - } 253 - l = netdev_hw_addr_list_count(hw_list) * ETH_ALEN; 254 - crc = ~crc32_le(crc, (void *)&l, sizeof(l)); 255 - 256 - if (crc != *ref_crc) { 257 - *ref_crc = crc; 258 - opa_vnic_vema_report_event(adapter, event); 259 - } 260 - } 261 - 262 - /* opa_vnic_set_rx_mode - handle uc/mc mac list change */ 263 - static void opa_vnic_set_rx_mode(struct net_device *netdev) 264 - { 265 - opa_vnic_mac_send_event(netdev, 266 - OPA_VESWPORT_TRAP_IFACE_UCAST_MAC_CHANGE); 267 - 268 - opa_vnic_mac_send_event(netdev, 269 - OPA_VESWPORT_TRAP_IFACE_MCAST_MAC_CHANGE); 270 - } 271 - 272 - /* opa_netdev_open - activate network interface */ 273 - static int opa_netdev_open(struct net_device *netdev) 274 - { 275 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 276 - int rc; 277 - 278 - rc = adapter->rn_ops->ndo_open(adapter->netdev); 279 - if (rc) { 280 - v_dbg("open failed %d\n", rc); 281 - return rc; 282 - } 283 - 284 - /* Update status and send trap */ 285 - opa_vnic_update_state(adapter, true); 286 - opa_vnic_vema_report_event(adapter, 287 - OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE); 288 - return 0; 289 - } 290 - 291 - /* opa_netdev_close - disable network interface */ 292 - static int opa_netdev_close(struct net_device *netdev) 293 - { 294 - struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev); 295 - int rc; 296 - 297 - rc = adapter->rn_ops->ndo_stop(adapter->netdev); 298 - if (rc) { 299 - v_dbg("close failed %d\n", rc); 300 - return rc; 301 - } 302 - 303 - /* Update status and send trap */ 304 - opa_vnic_update_state(adapter, false); 305 - opa_vnic_vema_report_event(adapter, 306 - OPA_VESWPORT_TRAP_ETH_LINK_STATUS_CHANGE); 307 - return 0; 308 - } 309 - 310 - /* netdev ops */ 311 - static const struct net_device_ops opa_netdev_ops = { 312 - .ndo_open = opa_netdev_open, 313 - .ndo_stop = opa_netdev_close, 314 - .ndo_start_xmit = opa_netdev_start_xmit, 315 - .ndo_get_stats64 = opa_vnic_get_stats64, 316 - .ndo_set_rx_mode = opa_vnic_set_rx_mode, 317 - .ndo_select_queue = opa_vnic_select_queue, 318 - .ndo_set_mac_address = opa_vnic_set_mac_addr, 319 - }; 320 - 321 - /* opa_vnic_add_netdev - create vnic netdev interface */ 322 - struct opa_vnic_adapter *opa_vnic_add_netdev(struct ib_device *ibdev, 323 - u8 port_num, u8 vport_num) 324 - { 325 - struct opa_vnic_adapter *adapter; 326 - struct net_device *netdev; 327 - struct rdma_netdev *rn; 328 - int rc; 329 - 330 - netdev = ibdev->ops.alloc_rdma_netdev(ibdev, port_num, 331 - RDMA_NETDEV_OPA_VNIC, 332 - "veth%d", NET_NAME_UNKNOWN, 333 - ether_setup); 334 - if (!netdev) 335 - return ERR_PTR(-ENOMEM); 336 - else if (IS_ERR(netdev)) 337 - return ERR_CAST(netdev); 338 - 339 - rn = netdev_priv(netdev); 340 - adapter = kzalloc_obj(*adapter); 341 - if (!adapter) { 342 - rc = -ENOMEM; 343 - goto adapter_err; 344 - } 345 - 346 - rn->clnt_priv = adapter; 347 - rn->hca = ibdev; 348 - rn->port_num = port_num; 349 - adapter->netdev = netdev; 350 - adapter->ibdev = ibdev; 351 - adapter->port_num = port_num; 352 - adapter->vport_num = vport_num; 353 - adapter->rn_ops = netdev->netdev_ops; 354 - 355 - netdev->netdev_ops = &opa_netdev_ops; 356 - netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE; 357 - netdev->hard_header_len += OPA_VNIC_SKB_HEADROOM; 358 - mutex_init(&adapter->lock); 359 - mutex_init(&adapter->mactbl_lock); 360 - spin_lock_init(&adapter->stats_lock); 361 - 362 - SET_NETDEV_DEV(netdev, ibdev->dev.parent); 363 - 364 - opa_vnic_set_ethtool_ops(netdev); 365 - 366 - opa_vnic_set_pod_values(adapter); 367 - 368 - rc = register_netdev(netdev); 369 - if (rc) 370 - goto netdev_err; 371 - 372 - netif_carrier_off(netdev); 373 - netif_dormant_on(netdev); 374 - v_info("initialized\n"); 375 - 376 - return adapter; 377 - netdev_err: 378 - mutex_destroy(&adapter->lock); 379 - mutex_destroy(&adapter->mactbl_lock); 380 - kfree(adapter); 381 - adapter_err: 382 - rn->free_rdma_netdev(netdev); 383 - 384 - return ERR_PTR(rc); 385 - } 386 - 387 - /* opa_vnic_rem_netdev - remove vnic netdev interface */ 388 - void opa_vnic_rem_netdev(struct opa_vnic_adapter *adapter) 389 - { 390 - struct net_device *netdev = adapter->netdev; 391 - struct rdma_netdev *rn = netdev_priv(netdev); 392 - 393 - v_info("removing\n"); 394 - unregister_netdev(netdev); 395 - opa_vnic_release_mac_tbl(adapter); 396 - mutex_destroy(&adapter->lock); 397 - mutex_destroy(&adapter->mactbl_lock); 398 - kfree(adapter); 399 - rn->free_rdma_netdev(netdev); 400 - }
-1056
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
··· 1 - /* 2 - * Copyright(c) 2017 Intel Corporation. 3 - * Copyright(c) 2021 Cornelis Networks. 4 - * 5 - * This file is provided under a dual BSD/GPLv2 license. When using or 6 - * redistributing this file, you may do so under either license. 7 - * 8 - * GPL LICENSE SUMMARY 9 - * 10 - * This program is free software; you can redistribute it and/or modify 11 - * it under the terms of version 2 of the GNU General Public License as 12 - * published by the Free Software Foundation. 13 - * 14 - * This program is distributed in the hope that it will be useful, but 15 - * WITHOUT ANY WARRANTY; without even the implied warranty of 16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 - * General Public License for more details. 18 - * 19 - * BSD LICENSE 20 - * 21 - * Redistribution and use in source and binary forms, with or without 22 - * modification, are permitted provided that the following conditions 23 - * are met: 24 - * 25 - * - Redistributions of source code must retain the above copyright 26 - * notice, this list of conditions and the following disclaimer. 27 - * - Redistributions in binary form must reproduce the above copyright 28 - * notice, this list of conditions and the following disclaimer in 29 - * the documentation and/or other materials provided with the 30 - * distribution. 31 - * - Neither the name of Intel Corporation nor the names of its 32 - * contributors may be used to endorse or promote products derived 33 - * from this software without specific prior written permission. 34 - * 35 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 - * 47 - */ 48 - 49 - /* 50 - * This file contains OPX Virtual Network Interface Controller (VNIC) 51 - * Ethernet Management Agent (EMA) driver 52 - */ 53 - 54 - #include <linux/module.h> 55 - #include <linux/xarray.h> 56 - #include <rdma/ib_addr.h> 57 - #include <rdma/ib_verbs.h> 58 - #include <rdma/opa_smi.h> 59 - #include <rdma/opa_port_info.h> 60 - 61 - #include "opa_vnic_internal.h" 62 - 63 - char opa_vnic_driver_name[] = "opa_vnic"; 64 - 65 - /* 66 - * The trap service level is kept in bits 3 to 7 in the trap_sl_rsvd 67 - * field in the class port info MAD. 68 - */ 69 - #define GET_TRAP_SL_FROM_CLASS_PORT_INFO(x) (((x) >> 3) & 0x1f) 70 - 71 - /* Cap trap bursts to a reasonable limit good for normal cases */ 72 - #define OPA_VNIC_TRAP_BURST_LIMIT 4 73 - 74 - /* 75 - * VNIC trap limit timeout. 76 - * Inverse of cap2_mask response time out (1.0737 secs) = 0.9 77 - * secs approx IB spec 13.4.6.2.1 PortInfoSubnetTimeout and 78 - * 13.4.9 Traps. 79 - */ 80 - #define OPA_VNIC_TRAP_TIMEOUT ((4096 * (1UL << 18)) / 1000) 81 - 82 - #define OPA_VNIC_UNSUP_ATTR \ 83 - cpu_to_be16(IB_MGMT_MAD_STATUS_UNSUPPORTED_METHOD_ATTRIB) 84 - 85 - #define OPA_VNIC_INVAL_ATTR \ 86 - cpu_to_be16(IB_MGMT_MAD_STATUS_INVALID_ATTRIB_VALUE) 87 - 88 - #define OPA_VNIC_CLASS_CAP_TRAP 0x1 89 - 90 - /* Maximum number of VNIC ports supported */ 91 - #define OPA_VNIC_MAX_NUM_VPORT 255 92 - 93 - /** 94 - * struct opa_vnic_vema_port -- VNIC VEMA port details 95 - * @cport: pointer to port 96 - * @mad_agent: pointer to mad agent for port 97 - * @class_port_info: Class port info information. 98 - * @tid: Transaction id 99 - * @port_num: OPA port number 100 - * @vports: vnic ports 101 - * @event_handler: ib event handler 102 - * @lock: adapter interface lock 103 - */ 104 - struct opa_vnic_vema_port { 105 - struct opa_vnic_ctrl_port *cport; 106 - struct ib_mad_agent *mad_agent; 107 - struct opa_class_port_info class_port_info; 108 - u64 tid; 109 - u8 port_num; 110 - struct xarray vports; 111 - struct ib_event_handler event_handler; 112 - 113 - /* Lock to query/update network adapter */ 114 - struct mutex lock; 115 - }; 116 - 117 - static int opa_vnic_vema_add_one(struct ib_device *device); 118 - static void opa_vnic_vema_rem_one(struct ib_device *device, 119 - void *client_data); 120 - 121 - static struct ib_client opa_vnic_client = { 122 - .name = opa_vnic_driver_name, 123 - .add = opa_vnic_vema_add_one, 124 - .remove = opa_vnic_vema_rem_one, 125 - }; 126 - 127 - /** 128 - * vema_get_vport_num -- Get the vnic from the mad 129 - * @recvd_mad: Received mad 130 - * 131 - * Return: returns value of the vnic port number 132 - */ 133 - static inline u8 vema_get_vport_num(struct opa_vnic_vema_mad *recvd_mad) 134 - { 135 - return be32_to_cpu(recvd_mad->mad_hdr.attr_mod) & 0xff; 136 - } 137 - 138 - /** 139 - * vema_get_vport_adapter -- Get vnic port adapter from recvd mad 140 - * @recvd_mad: received mad 141 - * @port: ptr to port struct on which MAD was recvd 142 - * 143 - * Return: vnic adapter 144 - */ 145 - static inline struct opa_vnic_adapter * 146 - vema_get_vport_adapter(struct opa_vnic_vema_mad *recvd_mad, 147 - struct opa_vnic_vema_port *port) 148 - { 149 - u8 vport_num = vema_get_vport_num(recvd_mad); 150 - 151 - return xa_load(&port->vports, vport_num); 152 - } 153 - 154 - /** 155 - * vema_mac_tbl_req_ok -- Check if mac request has correct values 156 - * @mac_tbl: mac table 157 - * 158 - * This function checks for the validity of the offset and number of 159 - * entries required. 160 - * 161 - * Return: true if offset and num_entries are valid 162 - */ 163 - static inline bool vema_mac_tbl_req_ok(struct opa_veswport_mactable *mac_tbl) 164 - { 165 - u16 offset, num_entries; 166 - u16 req_entries = ((OPA_VNIC_EMA_DATA - sizeof(*mac_tbl)) / 167 - sizeof(mac_tbl->tbl_entries[0])); 168 - 169 - offset = be16_to_cpu(mac_tbl->offset); 170 - num_entries = be16_to_cpu(mac_tbl->num_entries); 171 - 172 - return ((num_entries <= req_entries) && 173 - (offset + num_entries <= OPA_VNIC_MAC_TBL_MAX_ENTRIES)); 174 - } 175 - 176 - /* 177 - * Return the power on default values in the port info structure 178 - * in big endian format as required by MAD. 179 - */ 180 - static inline void vema_get_pod_values(struct opa_veswport_info *port_info) 181 - { 182 - memset(port_info, 0, sizeof(*port_info)); 183 - port_info->vport.max_mac_tbl_ent = 184 - cpu_to_be16(OPA_VNIC_MAC_TBL_MAX_ENTRIES); 185 - port_info->vport.max_smac_ent = 186 - cpu_to_be16(OPA_VNIC_MAX_SMAC_LIMIT); 187 - port_info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL; 188 - port_info->vport.config_state = OPA_VNIC_STATE_DROP_ALL; 189 - port_info->vesw.eth_mtu = cpu_to_be16(ETH_DATA_LEN); 190 - } 191 - 192 - /** 193 - * vema_add_vport -- Add a new vnic port 194 - * @port: ptr to opa_vnic_vema_port struct 195 - * @vport_num: vnic port number (to be added) 196 - * 197 - * Return a pointer to the vnic adapter structure 198 - */ 199 - static struct opa_vnic_adapter *vema_add_vport(struct opa_vnic_vema_port *port, 200 - u8 vport_num) 201 - { 202 - struct opa_vnic_ctrl_port *cport = port->cport; 203 - struct opa_vnic_adapter *adapter; 204 - 205 - adapter = opa_vnic_add_netdev(cport->ibdev, port->port_num, vport_num); 206 - if (!IS_ERR(adapter)) { 207 - int rc; 208 - 209 - adapter->cport = cport; 210 - rc = xa_insert(&port->vports, vport_num, adapter, GFP_KERNEL); 211 - if (rc < 0) { 212 - opa_vnic_rem_netdev(adapter); 213 - adapter = ERR_PTR(rc); 214 - } 215 - } 216 - 217 - return adapter; 218 - } 219 - 220 - /** 221 - * vema_get_class_port_info -- Get class info for port 222 - * @port: Port on whic MAD was received 223 - * @recvd_mad: pointer to the received mad 224 - * @rsp_mad: pointer to respose mad 225 - * 226 - * This function copies the latest class port info value set for the 227 - * port and stores it for generating traps 228 - */ 229 - static void vema_get_class_port_info(struct opa_vnic_vema_port *port, 230 - struct opa_vnic_vema_mad *recvd_mad, 231 - struct opa_vnic_vema_mad *rsp_mad) 232 - { 233 - struct opa_class_port_info *port_info; 234 - 235 - port_info = (struct opa_class_port_info *)rsp_mad->data; 236 - memcpy(port_info, &port->class_port_info, sizeof(*port_info)); 237 - port_info->base_version = OPA_MGMT_BASE_VERSION; 238 - port_info->class_version = OPA_EMA_CLASS_VERSION; 239 - 240 - /* 241 - * Set capability mask bit indicating agent generates traps, 242 - * and set the maximum number of VNIC ports supported. 243 - */ 244 - port_info->cap_mask = cpu_to_be16((OPA_VNIC_CLASS_CAP_TRAP | 245 - (OPA_VNIC_MAX_NUM_VPORT << 8))); 246 - 247 - /* 248 - * Since a get routine is always sent by the EM first we 249 - * set the expected response time to 250 - * 4.096 usec * 2^18 == 1.0737 sec here. 251 - */ 252 - port_info->cap_mask2_resp_time = cpu_to_be32(18); 253 - } 254 - 255 - /** 256 - * vema_set_class_port_info -- Get class info for port 257 - * @port: Port on whic MAD was received 258 - * @recvd_mad: pointer to the received mad 259 - * @rsp_mad: pointer to respose mad 260 - * 261 - * This function updates the port class info for the specific vnic 262 - * and sets up the response mad data 263 - */ 264 - static void vema_set_class_port_info(struct opa_vnic_vema_port *port, 265 - struct opa_vnic_vema_mad *recvd_mad, 266 - struct opa_vnic_vema_mad *rsp_mad) 267 - { 268 - memcpy(&port->class_port_info, recvd_mad->data, 269 - sizeof(port->class_port_info)); 270 - 271 - vema_get_class_port_info(port, recvd_mad, rsp_mad); 272 - } 273 - 274 - /** 275 - * vema_get_veswport_info -- Get veswport info 276 - * @port: source port on which MAD was received 277 - * @recvd_mad: pointer to the received mad 278 - * @rsp_mad: pointer to respose mad 279 - */ 280 - static void vema_get_veswport_info(struct opa_vnic_vema_port *port, 281 - struct opa_vnic_vema_mad *recvd_mad, 282 - struct opa_vnic_vema_mad *rsp_mad) 283 - { 284 - struct opa_veswport_info *port_info = 285 - (struct opa_veswport_info *)rsp_mad->data; 286 - struct opa_vnic_adapter *adapter; 287 - 288 - adapter = vema_get_vport_adapter(recvd_mad, port); 289 - if (adapter) { 290 - memset(port_info, 0, sizeof(*port_info)); 291 - opa_vnic_get_vesw_info(adapter, &port_info->vesw); 292 - opa_vnic_get_per_veswport_info(adapter, 293 - &port_info->vport); 294 - } else { 295 - vema_get_pod_values(port_info); 296 - } 297 - } 298 - 299 - /** 300 - * vema_set_veswport_info -- Set veswport info 301 - * @port: source port on which MAD was received 302 - * @recvd_mad: pointer to the received mad 303 - * @rsp_mad: pointer to respose mad 304 - * 305 - * This function gets the port class infor for vnic 306 - */ 307 - static void vema_set_veswport_info(struct opa_vnic_vema_port *port, 308 - struct opa_vnic_vema_mad *recvd_mad, 309 - struct opa_vnic_vema_mad *rsp_mad) 310 - { 311 - struct opa_vnic_ctrl_port *cport = port->cport; 312 - struct opa_veswport_info *port_info; 313 - struct opa_vnic_adapter *adapter; 314 - u8 vport_num; 315 - 316 - vport_num = vema_get_vport_num(recvd_mad); 317 - 318 - adapter = vema_get_vport_adapter(recvd_mad, port); 319 - if (!adapter) { 320 - adapter = vema_add_vport(port, vport_num); 321 - if (IS_ERR(adapter)) { 322 - c_err("failed to add vport %d: %ld\n", 323 - vport_num, PTR_ERR(adapter)); 324 - goto err_exit; 325 - } 326 - } 327 - 328 - port_info = (struct opa_veswport_info *)recvd_mad->data; 329 - opa_vnic_set_vesw_info(adapter, &port_info->vesw); 330 - opa_vnic_set_per_veswport_info(adapter, &port_info->vport); 331 - 332 - /* Process the new config settings */ 333 - opa_vnic_process_vema_config(adapter); 334 - 335 - vema_get_veswport_info(port, recvd_mad, rsp_mad); 336 - return; 337 - 338 - err_exit: 339 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 340 - } 341 - 342 - /** 343 - * vema_get_mac_entries -- Get MAC entries in VNIC MAC table 344 - * @port: source port on which MAD was received 345 - * @recvd_mad: pointer to the received mad 346 - * @rsp_mad: pointer to respose mad 347 - * 348 - * This function gets the MAC entries that are programmed into 349 - * the VNIC MAC forwarding table. It checks for the validity of 350 - * the index into the MAC table and the number of entries that 351 - * are to be retrieved. 352 - */ 353 - static void vema_get_mac_entries(struct opa_vnic_vema_port *port, 354 - struct opa_vnic_vema_mad *recvd_mad, 355 - struct opa_vnic_vema_mad *rsp_mad) 356 - { 357 - struct opa_veswport_mactable *mac_tbl_in, *mac_tbl_out; 358 - struct opa_vnic_adapter *adapter; 359 - 360 - adapter = vema_get_vport_adapter(recvd_mad, port); 361 - if (!adapter) { 362 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 363 - return; 364 - } 365 - 366 - mac_tbl_in = (struct opa_veswport_mactable *)recvd_mad->data; 367 - mac_tbl_out = (struct opa_veswport_mactable *)rsp_mad->data; 368 - 369 - if (vema_mac_tbl_req_ok(mac_tbl_in)) { 370 - mac_tbl_out->offset = mac_tbl_in->offset; 371 - mac_tbl_out->num_entries = mac_tbl_in->num_entries; 372 - opa_vnic_query_mac_tbl(adapter, mac_tbl_out); 373 - } else { 374 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 375 - } 376 - } 377 - 378 - /** 379 - * vema_set_mac_entries -- Set MAC entries in VNIC MAC table 380 - * @port: source port on which MAD was received 381 - * @recvd_mad: pointer to the received mad 382 - * @rsp_mad: pointer to respose mad 383 - * 384 - * This function sets the MAC entries in the VNIC forwarding table 385 - * It checks for the validity of the index and the number of forwarding 386 - * table entries to be programmed. 387 - */ 388 - static void vema_set_mac_entries(struct opa_vnic_vema_port *port, 389 - struct opa_vnic_vema_mad *recvd_mad, 390 - struct opa_vnic_vema_mad *rsp_mad) 391 - { 392 - struct opa_veswport_mactable *mac_tbl; 393 - struct opa_vnic_adapter *adapter; 394 - 395 - adapter = vema_get_vport_adapter(recvd_mad, port); 396 - if (!adapter) { 397 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 398 - return; 399 - } 400 - 401 - mac_tbl = (struct opa_veswport_mactable *)recvd_mad->data; 402 - if (vema_mac_tbl_req_ok(mac_tbl)) { 403 - if (opa_vnic_update_mac_tbl(adapter, mac_tbl)) 404 - rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR; 405 - } else { 406 - rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR; 407 - } 408 - vema_get_mac_entries(port, recvd_mad, rsp_mad); 409 - } 410 - 411 - /** 412 - * vema_set_delete_vesw -- Reset VESW info to POD values 413 - * @port: source port on which MAD was received 414 - * @recvd_mad: pointer to the received mad 415 - * @rsp_mad: pointer to respose mad 416 - * 417 - * This function clears all the fields of veswport info for the requested vesw 418 - * and sets them back to the power-on default values. It does not delete the 419 - * vesw. 420 - */ 421 - static void vema_set_delete_vesw(struct opa_vnic_vema_port *port, 422 - struct opa_vnic_vema_mad *recvd_mad, 423 - struct opa_vnic_vema_mad *rsp_mad) 424 - { 425 - struct opa_veswport_info *port_info = 426 - (struct opa_veswport_info *)rsp_mad->data; 427 - struct opa_vnic_adapter *adapter; 428 - 429 - adapter = vema_get_vport_adapter(recvd_mad, port); 430 - if (!adapter) { 431 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 432 - return; 433 - } 434 - 435 - vema_get_pod_values(port_info); 436 - opa_vnic_set_vesw_info(adapter, &port_info->vesw); 437 - opa_vnic_set_per_veswport_info(adapter, &port_info->vport); 438 - 439 - /* Process the new config settings */ 440 - opa_vnic_process_vema_config(adapter); 441 - 442 - opa_vnic_release_mac_tbl(adapter); 443 - 444 - vema_get_veswport_info(port, recvd_mad, rsp_mad); 445 - } 446 - 447 - /** 448 - * vema_get_mac_list -- Get the unicast/multicast macs. 449 - * @port: source port on which MAD was received 450 - * @recvd_mad: Received mad contains fields to set vnic parameters 451 - * @rsp_mad: Response mad to be built 452 - * @attr_id: Attribute ID indicating multicast or unicast mac list 453 - */ 454 - static void vema_get_mac_list(struct opa_vnic_vema_port *port, 455 - struct opa_vnic_vema_mad *recvd_mad, 456 - struct opa_vnic_vema_mad *rsp_mad, 457 - u16 attr_id) 458 - { 459 - struct opa_veswport_iface_macs *macs_in, *macs_out; 460 - int max_entries = (OPA_VNIC_EMA_DATA - sizeof(*macs_out)) / ETH_ALEN; 461 - struct opa_vnic_adapter *adapter; 462 - 463 - adapter = vema_get_vport_adapter(recvd_mad, port); 464 - if (!adapter) { 465 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 466 - return; 467 - } 468 - 469 - macs_in = (struct opa_veswport_iface_macs *)recvd_mad->data; 470 - macs_out = (struct opa_veswport_iface_macs *)rsp_mad->data; 471 - 472 - macs_out->start_idx = macs_in->start_idx; 473 - if (macs_in->num_macs_in_msg) 474 - macs_out->num_macs_in_msg = macs_in->num_macs_in_msg; 475 - else 476 - macs_out->num_macs_in_msg = cpu_to_be16(max_entries); 477 - 478 - if (attr_id == OPA_EM_ATTR_IFACE_MCAST_MACS) 479 - opa_vnic_query_mcast_macs(adapter, macs_out); 480 - else 481 - opa_vnic_query_ucast_macs(adapter, macs_out); 482 - } 483 - 484 - /** 485 - * vema_get_summary_counters -- Gets summary counters. 486 - * @port: source port on which MAD was received 487 - * @recvd_mad: Received mad contains fields to set vnic parameters 488 - * @rsp_mad: Response mad to be built 489 - */ 490 - static void vema_get_summary_counters(struct opa_vnic_vema_port *port, 491 - struct opa_vnic_vema_mad *recvd_mad, 492 - struct opa_vnic_vema_mad *rsp_mad) 493 - { 494 - struct opa_veswport_summary_counters *cntrs; 495 - struct opa_vnic_adapter *adapter; 496 - 497 - adapter = vema_get_vport_adapter(recvd_mad, port); 498 - if (adapter) { 499 - cntrs = (struct opa_veswport_summary_counters *)rsp_mad->data; 500 - opa_vnic_get_summary_counters(adapter, cntrs); 501 - } else { 502 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 503 - } 504 - } 505 - 506 - /** 507 - * vema_get_error_counters -- Gets summary counters. 508 - * @port: source port on which MAD was received 509 - * @recvd_mad: Received mad contains fields to set vnic parameters 510 - * @rsp_mad: Response mad to be built 511 - */ 512 - static void vema_get_error_counters(struct opa_vnic_vema_port *port, 513 - struct opa_vnic_vema_mad *recvd_mad, 514 - struct opa_vnic_vema_mad *rsp_mad) 515 - { 516 - struct opa_veswport_error_counters *cntrs; 517 - struct opa_vnic_adapter *adapter; 518 - 519 - adapter = vema_get_vport_adapter(recvd_mad, port); 520 - if (adapter) { 521 - cntrs = (struct opa_veswport_error_counters *)rsp_mad->data; 522 - opa_vnic_get_error_counters(adapter, cntrs); 523 - } else { 524 - rsp_mad->mad_hdr.status = OPA_VNIC_INVAL_ATTR; 525 - } 526 - } 527 - 528 - /** 529 - * vema_get -- Process received get MAD 530 - * @port: source port on which MAD was received 531 - * @recvd_mad: Received mad 532 - * @rsp_mad: Response mad to be built 533 - */ 534 - static void vema_get(struct opa_vnic_vema_port *port, 535 - struct opa_vnic_vema_mad *recvd_mad, 536 - struct opa_vnic_vema_mad *rsp_mad) 537 - { 538 - u16 attr_id = be16_to_cpu(recvd_mad->mad_hdr.attr_id); 539 - 540 - switch (attr_id) { 541 - case OPA_EM_ATTR_CLASS_PORT_INFO: 542 - vema_get_class_port_info(port, recvd_mad, rsp_mad); 543 - break; 544 - case OPA_EM_ATTR_VESWPORT_INFO: 545 - vema_get_veswport_info(port, recvd_mad, rsp_mad); 546 - break; 547 - case OPA_EM_ATTR_VESWPORT_MAC_ENTRIES: 548 - vema_get_mac_entries(port, recvd_mad, rsp_mad); 549 - break; 550 - case OPA_EM_ATTR_IFACE_UCAST_MACS: 551 - case OPA_EM_ATTR_IFACE_MCAST_MACS: 552 - vema_get_mac_list(port, recvd_mad, rsp_mad, attr_id); 553 - break; 554 - case OPA_EM_ATTR_VESWPORT_SUMMARY_COUNTERS: 555 - vema_get_summary_counters(port, recvd_mad, rsp_mad); 556 - break; 557 - case OPA_EM_ATTR_VESWPORT_ERROR_COUNTERS: 558 - vema_get_error_counters(port, recvd_mad, rsp_mad); 559 - break; 560 - default: 561 - rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR; 562 - break; 563 - } 564 - } 565 - 566 - /** 567 - * vema_set -- Process received set MAD 568 - * @port: source port on which MAD was received 569 - * @recvd_mad: Received mad contains fields to set vnic parameters 570 - * @rsp_mad: Response mad to be built 571 - */ 572 - static void vema_set(struct opa_vnic_vema_port *port, 573 - struct opa_vnic_vema_mad *recvd_mad, 574 - struct opa_vnic_vema_mad *rsp_mad) 575 - { 576 - u16 attr_id = be16_to_cpu(recvd_mad->mad_hdr.attr_id); 577 - 578 - switch (attr_id) { 579 - case OPA_EM_ATTR_CLASS_PORT_INFO: 580 - vema_set_class_port_info(port, recvd_mad, rsp_mad); 581 - break; 582 - case OPA_EM_ATTR_VESWPORT_INFO: 583 - vema_set_veswport_info(port, recvd_mad, rsp_mad); 584 - break; 585 - case OPA_EM_ATTR_VESWPORT_MAC_ENTRIES: 586 - vema_set_mac_entries(port, recvd_mad, rsp_mad); 587 - break; 588 - case OPA_EM_ATTR_DELETE_VESW: 589 - vema_set_delete_vesw(port, recvd_mad, rsp_mad); 590 - break; 591 - default: 592 - rsp_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR; 593 - break; 594 - } 595 - } 596 - 597 - /** 598 - * vema_send -- Send handler for VEMA MAD agent 599 - * @mad_agent: pointer to the mad agent 600 - * @mad_wc: pointer to mad send work completion information 601 - * 602 - * Free all the data structures associated with the sent MAD 603 - */ 604 - static void vema_send(struct ib_mad_agent *mad_agent, 605 - struct ib_mad_send_wc *mad_wc) 606 - { 607 - rdma_destroy_ah(mad_wc->send_buf->ah, RDMA_DESTROY_AH_SLEEPABLE); 608 - ib_free_send_mad(mad_wc->send_buf); 609 - } 610 - 611 - /** 612 - * vema_recv -- Recv handler for VEMA MAD agent 613 - * @mad_agent: pointer to the mad agent 614 - * @send_buf: Send buffer if found, else NULL 615 - * @mad_wc: pointer to mad send work completion information 616 - * 617 - * Handle only set and get methods and respond to other methods 618 - * as unsupported. Allocate response buffer and address handle 619 - * for the response MAD. 620 - */ 621 - static void vema_recv(struct ib_mad_agent *mad_agent, 622 - struct ib_mad_send_buf *send_buf, 623 - struct ib_mad_recv_wc *mad_wc) 624 - { 625 - struct opa_vnic_vema_port *port; 626 - struct ib_ah *ah; 627 - struct ib_mad_send_buf *rsp; 628 - struct opa_vnic_vema_mad *vema_mad; 629 - 630 - if (!mad_wc || !mad_wc->recv_buf.mad) 631 - return; 632 - 633 - port = mad_agent->context; 634 - ah = ib_create_ah_from_wc(mad_agent->qp->pd, mad_wc->wc, 635 - mad_wc->recv_buf.grh, mad_agent->port_num); 636 - if (IS_ERR(ah)) 637 - goto free_recv_mad; 638 - 639 - rsp = ib_create_send_mad(mad_agent, mad_wc->wc->src_qp, 640 - mad_wc->wc->pkey_index, 0, 641 - IB_MGMT_VENDOR_HDR, OPA_VNIC_EMA_DATA, 642 - GFP_KERNEL, OPA_MGMT_BASE_VERSION); 643 - if (IS_ERR(rsp)) 644 - goto err_rsp; 645 - 646 - rsp->ah = ah; 647 - vema_mad = rsp->mad; 648 - memcpy(vema_mad, mad_wc->recv_buf.mad, IB_MGMT_VENDOR_HDR); 649 - vema_mad->mad_hdr.method = IB_MGMT_METHOD_GET_RESP; 650 - vema_mad->mad_hdr.status = 0; 651 - 652 - /* Lock ensures network adapter is not removed */ 653 - mutex_lock(&port->lock); 654 - 655 - switch (mad_wc->recv_buf.mad->mad_hdr.method) { 656 - case IB_MGMT_METHOD_GET: 657 - vema_get(port, (struct opa_vnic_vema_mad *)mad_wc->recv_buf.mad, 658 - vema_mad); 659 - break; 660 - case IB_MGMT_METHOD_SET: 661 - vema_set(port, (struct opa_vnic_vema_mad *)mad_wc->recv_buf.mad, 662 - vema_mad); 663 - break; 664 - default: 665 - vema_mad->mad_hdr.status = OPA_VNIC_UNSUP_ATTR; 666 - break; 667 - } 668 - mutex_unlock(&port->lock); 669 - 670 - if (!ib_post_send_mad(rsp, NULL)) { 671 - /* 672 - * with post send successful ah and send mad 673 - * will be destroyed in send handler 674 - */ 675 - goto free_recv_mad; 676 - } 677 - 678 - ib_free_send_mad(rsp); 679 - 680 - err_rsp: 681 - rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE); 682 - free_recv_mad: 683 - ib_free_recv_mad(mad_wc); 684 - } 685 - 686 - /** 687 - * vema_get_port -- Gets the opa_vnic_vema_port 688 - * @cport: pointer to control dev 689 - * @port_num: Port number 690 - * 691 - * This function loops through the ports and returns 692 - * the opa_vnic_vema port structure that is associated 693 - * with the OPA port number 694 - * 695 - * Return: ptr to requested opa_vnic_vema_port strucure 696 - * if success, NULL if not 697 - */ 698 - static struct opa_vnic_vema_port * 699 - vema_get_port(struct opa_vnic_ctrl_port *cport, u8 port_num) 700 - { 701 - struct opa_vnic_vema_port *port = (void *)cport + sizeof(*cport); 702 - 703 - if (port_num > cport->num_ports) 704 - return NULL; 705 - 706 - return port + (port_num - 1); 707 - } 708 - 709 - /** 710 - * opa_vnic_vema_send_trap -- This function sends a trap to the EM 711 - * @adapter: pointer to vnic adapter 712 - * @data: pointer to trap data filled by calling function 713 - * @lid: issuers lid (encap_slid from vesw_port_info) 714 - * 715 - * This function is called from the VNIC driver to send a trap if there 716 - * is somethng the EM should be notified about. These events currently 717 - * are 718 - * 1) UNICAST INTERFACE MACADDRESS changes 719 - * 2) MULTICAST INTERFACE MACADDRESS changes 720 - * 3) ETHERNET LINK STATUS changes 721 - * While allocating the send mad the remote site qpn used is 1 722 - * as this is the well known QP. 723 - * 724 - */ 725 - void opa_vnic_vema_send_trap(struct opa_vnic_adapter *adapter, 726 - struct __opa_veswport_trap *data, u32 lid) 727 - { 728 - struct opa_vnic_ctrl_port *cport = adapter->cport; 729 - struct ib_mad_send_buf *send_buf; 730 - struct opa_vnic_vema_port *port; 731 - struct ib_device *ibp; 732 - struct opa_vnic_vema_mad_trap *trap_mad; 733 - struct opa_class_port_info *class; 734 - struct rdma_ah_attr ah_attr; 735 - struct ib_ah *ah; 736 - struct opa_veswport_trap *trap; 737 - u32 trap_lid; 738 - u16 pkey_idx; 739 - 740 - if (!cport) 741 - goto err_exit; 742 - ibp = cport->ibdev; 743 - port = vema_get_port(cport, data->opaportnum); 744 - if (!port || !port->mad_agent) 745 - goto err_exit; 746 - 747 - if (time_before(jiffies, adapter->trap_timeout)) { 748 - if (adapter->trap_count == OPA_VNIC_TRAP_BURST_LIMIT) { 749 - v_warn("Trap rate exceeded\n"); 750 - goto err_exit; 751 - } else { 752 - adapter->trap_count++; 753 - } 754 - } else { 755 - adapter->trap_count = 0; 756 - } 757 - 758 - class = &port->class_port_info; 759 - /* Set up address handle */ 760 - memset(&ah_attr, 0, sizeof(ah_attr)); 761 - ah_attr.type = rdma_ah_find_type(ibp, port->port_num); 762 - rdma_ah_set_sl(&ah_attr, 763 - GET_TRAP_SL_FROM_CLASS_PORT_INFO(class->trap_sl_rsvd)); 764 - rdma_ah_set_port_num(&ah_attr, port->port_num); 765 - trap_lid = be32_to_cpu(class->trap_lid); 766 - /* 767 - * check for trap lid validity, must not be zero 768 - * The trap sink could change after we fashion the MAD but since traps 769 - * are not guaranteed we won't use a lock as anyway the change will take 770 - * place even with locking. 771 - */ 772 - if (!trap_lid) { 773 - c_err("%s: Invalid dlid\n", __func__); 774 - goto err_exit; 775 - } 776 - 777 - rdma_ah_set_dlid(&ah_attr, trap_lid); 778 - ah = rdma_create_ah(port->mad_agent->qp->pd, &ah_attr, 0); 779 - if (IS_ERR(ah)) { 780 - c_err("%s:Couldn't create new AH = %p\n", __func__, ah); 781 - c_err("%s:dlid = %d, sl = %d, port = %d\n", __func__, 782 - rdma_ah_get_dlid(&ah_attr), rdma_ah_get_sl(&ah_attr), 783 - rdma_ah_get_port_num(&ah_attr)); 784 - goto err_exit; 785 - } 786 - 787 - if (ib_find_pkey(ibp, data->opaportnum, IB_DEFAULT_PKEY_FULL, 788 - &pkey_idx) < 0) { 789 - c_err("%s:full key not found, defaulting to partial\n", 790 - __func__); 791 - if (ib_find_pkey(ibp, data->opaportnum, IB_DEFAULT_PKEY_PARTIAL, 792 - &pkey_idx) < 0) 793 - pkey_idx = 1; 794 - } 795 - 796 - send_buf = ib_create_send_mad(port->mad_agent, 1, pkey_idx, 0, 797 - IB_MGMT_VENDOR_HDR, IB_MGMT_MAD_DATA, 798 - GFP_ATOMIC, OPA_MGMT_BASE_VERSION); 799 - if (IS_ERR(send_buf)) { 800 - c_err("%s:Couldn't allocate send buf\n", __func__); 801 - goto err_sndbuf; 802 - } 803 - 804 - send_buf->ah = ah; 805 - 806 - /* Set up common MAD hdr */ 807 - trap_mad = send_buf->mad; 808 - trap_mad->mad_hdr.base_version = OPA_MGMT_BASE_VERSION; 809 - trap_mad->mad_hdr.mgmt_class = OPA_MGMT_CLASS_INTEL_EMA; 810 - trap_mad->mad_hdr.class_version = OPA_EMA_CLASS_VERSION; 811 - trap_mad->mad_hdr.method = IB_MGMT_METHOD_TRAP; 812 - port->tid++; 813 - trap_mad->mad_hdr.tid = cpu_to_be64(port->tid); 814 - trap_mad->mad_hdr.attr_id = IB_SMP_ATTR_NOTICE; 815 - 816 - /* Set up vendor OUI */ 817 - trap_mad->oui[0] = INTEL_OUI_1; 818 - trap_mad->oui[1] = INTEL_OUI_2; 819 - trap_mad->oui[2] = INTEL_OUI_3; 820 - 821 - /* Setup notice attribute portion */ 822 - trap_mad->notice.gen_type = OPA_INTEL_EMA_NOTICE_TYPE_INFO << 1; 823 - trap_mad->notice.oui_1 = INTEL_OUI_1; 824 - trap_mad->notice.oui_2 = INTEL_OUI_2; 825 - trap_mad->notice.oui_3 = INTEL_OUI_3; 826 - trap_mad->notice.issuer_lid = cpu_to_be32(lid); 827 - 828 - /* copy the actual trap data */ 829 - trap = (struct opa_veswport_trap *)trap_mad->notice.raw_data; 830 - trap->fabric_id = cpu_to_be16(data->fabric_id); 831 - trap->veswid = cpu_to_be16(data->veswid); 832 - trap->veswportnum = cpu_to_be32(data->veswportnum); 833 - trap->opaportnum = cpu_to_be16(data->opaportnum); 834 - trap->veswportindex = data->veswportindex; 835 - trap->opcode = data->opcode; 836 - 837 - /* If successful send set up rate limit timeout else bail */ 838 - if (ib_post_send_mad(send_buf, NULL)) { 839 - ib_free_send_mad(send_buf); 840 - } else { 841 - if (adapter->trap_count) 842 - return; 843 - adapter->trap_timeout = jiffies + 844 - usecs_to_jiffies(OPA_VNIC_TRAP_TIMEOUT); 845 - return; 846 - } 847 - 848 - err_sndbuf: 849 - rdma_destroy_ah(ah, 0); 850 - err_exit: 851 - v_err("Aborting trap\n"); 852 - } 853 - 854 - static void opa_vnic_event(struct ib_event_handler *handler, 855 - struct ib_event *record) 856 - { 857 - struct opa_vnic_vema_port *port = 858 - container_of(handler, struct opa_vnic_vema_port, event_handler); 859 - struct opa_vnic_ctrl_port *cport = port->cport; 860 - struct opa_vnic_adapter *adapter; 861 - unsigned long index; 862 - 863 - if (record->element.port_num != port->port_num) 864 - return; 865 - 866 - c_dbg("OPA_VNIC received event %d on device %s port %d\n", 867 - record->event, dev_name(&record->device->dev), 868 - record->element.port_num); 869 - 870 - if (record->event != IB_EVENT_PORT_ERR && 871 - record->event != IB_EVENT_PORT_ACTIVE) 872 - return; 873 - 874 - xa_for_each(&port->vports, index, adapter) { 875 - if (record->event == IB_EVENT_PORT_ACTIVE) 876 - netif_carrier_on(adapter->netdev); 877 - else 878 - netif_carrier_off(adapter->netdev); 879 - } 880 - } 881 - 882 - /** 883 - * vema_unregister -- Unregisters agent 884 - * @cport: pointer to control port 885 - * 886 - * This deletes the registration by VEMA for MADs 887 - */ 888 - static void vema_unregister(struct opa_vnic_ctrl_port *cport) 889 - { 890 - struct opa_vnic_adapter *adapter; 891 - unsigned long index; 892 - int i; 893 - 894 - for (i = 1; i <= cport->num_ports; i++) { 895 - struct opa_vnic_vema_port *port = vema_get_port(cport, i); 896 - 897 - if (!port->mad_agent) 898 - continue; 899 - 900 - /* Lock ensures no MAD is being processed */ 901 - mutex_lock(&port->lock); 902 - xa_for_each(&port->vports, index, adapter) 903 - opa_vnic_rem_netdev(adapter); 904 - mutex_unlock(&port->lock); 905 - 906 - ib_unregister_mad_agent(port->mad_agent); 907 - port->mad_agent = NULL; 908 - mutex_destroy(&port->lock); 909 - xa_destroy(&port->vports); 910 - ib_unregister_event_handler(&port->event_handler); 911 - } 912 - } 913 - 914 - /** 915 - * vema_register -- Registers agent 916 - * @cport: pointer to control port 917 - * 918 - * This function registers the handlers for the VEMA MADs 919 - * 920 - * Return: returns 0 on success. non zero otherwise 921 - */ 922 - static int vema_register(struct opa_vnic_ctrl_port *cport) 923 - { 924 - struct ib_mad_reg_req reg_req = { 925 - .mgmt_class = OPA_MGMT_CLASS_INTEL_EMA, 926 - .mgmt_class_version = OPA_MGMT_BASE_VERSION, 927 - .oui = { INTEL_OUI_1, INTEL_OUI_2, INTEL_OUI_3 } 928 - }; 929 - int i; 930 - 931 - set_bit(IB_MGMT_METHOD_GET, reg_req.method_mask); 932 - set_bit(IB_MGMT_METHOD_SET, reg_req.method_mask); 933 - 934 - /* register ib event handler and mad agent for each port on dev */ 935 - for (i = 1; i <= cport->num_ports; i++) { 936 - struct opa_vnic_vema_port *port = vema_get_port(cport, i); 937 - int ret; 938 - 939 - port->cport = cport; 940 - port->port_num = i; 941 - 942 - INIT_IB_EVENT_HANDLER(&port->event_handler, 943 - cport->ibdev, opa_vnic_event); 944 - ib_register_event_handler(&port->event_handler); 945 - 946 - xa_init(&port->vports); 947 - mutex_init(&port->lock); 948 - port->mad_agent = ib_register_mad_agent(cport->ibdev, i, 949 - IB_QPT_GSI, &reg_req, 950 - IB_MGMT_RMPP_VERSION, 951 - vema_send, vema_recv, 952 - port, 0); 953 - if (IS_ERR(port->mad_agent)) { 954 - ret = PTR_ERR(port->mad_agent); 955 - port->mad_agent = NULL; 956 - mutex_destroy(&port->lock); 957 - vema_unregister(cport); 958 - return ret; 959 - } 960 - } 961 - 962 - return 0; 963 - } 964 - 965 - /** 966 - * opa_vnic_ctrl_config_dev -- This function sends a trap to the EM 967 - * by way of ib_modify_port to indicate support for ethernet on the 968 - * fabric. 969 - * @cport: pointer to control port 970 - * @en: enable or disable ethernet on fabric support 971 - */ 972 - static void opa_vnic_ctrl_config_dev(struct opa_vnic_ctrl_port *cport, bool en) 973 - { 974 - struct ib_port_modify pm = { 0 }; 975 - int i; 976 - 977 - if (en) 978 - pm.set_port_cap_mask = OPA_CAP_MASK3_IsEthOnFabricSupported; 979 - else 980 - pm.clr_port_cap_mask = OPA_CAP_MASK3_IsEthOnFabricSupported; 981 - 982 - for (i = 1; i <= cport->num_ports; i++) 983 - ib_modify_port(cport->ibdev, i, IB_PORT_OPA_MASK_CHG, &pm); 984 - } 985 - 986 - /** 987 - * opa_vnic_vema_add_one -- Handle new ib device 988 - * @device: ib device pointer 989 - * 990 - * Allocate the vnic control port and initialize it. 991 - */ 992 - static int opa_vnic_vema_add_one(struct ib_device *device) 993 - { 994 - struct opa_vnic_ctrl_port *cport; 995 - int rc, size = sizeof(*cport); 996 - 997 - if (!rdma_cap_opa_vnic(device)) 998 - return -EOPNOTSUPP; 999 - 1000 - size += device->phys_port_cnt * sizeof(struct opa_vnic_vema_port); 1001 - cport = kzalloc(size, GFP_KERNEL); 1002 - if (!cport) 1003 - return -ENOMEM; 1004 - 1005 - cport->num_ports = device->phys_port_cnt; 1006 - cport->ibdev = device; 1007 - 1008 - /* Initialize opa vnic management agent (vema) */ 1009 - rc = vema_register(cport); 1010 - if (!rc) 1011 - c_info("VNIC client initialized\n"); 1012 - 1013 - ib_set_client_data(device, &opa_vnic_client, cport); 1014 - opa_vnic_ctrl_config_dev(cport, true); 1015 - return 0; 1016 - } 1017 - 1018 - /** 1019 - * opa_vnic_vema_rem_one -- Handle ib device removal 1020 - * @device: ib device pointer 1021 - * @client_data: ib client data 1022 - * 1023 - * Uninitialize and free the vnic control port. 1024 - */ 1025 - static void opa_vnic_vema_rem_one(struct ib_device *device, 1026 - void *client_data) 1027 - { 1028 - struct opa_vnic_ctrl_port *cport = client_data; 1029 - 1030 - c_info("removing VNIC client\n"); 1031 - opa_vnic_ctrl_config_dev(cport, false); 1032 - vema_unregister(cport); 1033 - kfree(cport); 1034 - } 1035 - 1036 - static int __init opa_vnic_init(void) 1037 - { 1038 - int rc; 1039 - 1040 - rc = ib_register_client(&opa_vnic_client); 1041 - if (rc) 1042 - pr_err("VNIC driver register failed %d\n", rc); 1043 - 1044 - return rc; 1045 - } 1046 - module_init(opa_vnic_init); 1047 - 1048 - static void opa_vnic_deinit(void) 1049 - { 1050 - ib_unregister_client(&opa_vnic_client); 1051 - } 1052 - module_exit(opa_vnic_deinit); 1053 - 1054 - MODULE_LICENSE("Dual BSD/GPL"); 1055 - MODULE_AUTHOR("Cornelis Networks"); 1056 - MODULE_DESCRIPTION("Cornelis OPX Virtual Network driver");
-390
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c
··· 1 - /* 2 - * Copyright(c) 2017 Intel Corporation. 3 - * 4 - * This file is provided under a dual BSD/GPLv2 license. When using or 5 - * redistributing this file, you may do so under either license. 6 - * 7 - * GPL LICENSE SUMMARY 8 - * 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of version 2 of the GNU General Public License as 11 - * published by the Free Software Foundation. 12 - * 13 - * This program is distributed in the hope that it will be useful, but 14 - * WITHOUT ANY WARRANTY; without even the implied warranty of 15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 - * General Public License for more details. 17 - * 18 - * BSD LICENSE 19 - * 20 - * Redistribution and use in source and binary forms, with or without 21 - * modification, are permitted provided that the following conditions 22 - * are met: 23 - * 24 - * - Redistributions of source code must retain the above copyright 25 - * notice, this list of conditions and the following disclaimer. 26 - * - Redistributions in binary form must reproduce the above copyright 27 - * notice, this list of conditions and the following disclaimer in 28 - * the documentation and/or other materials provided with the 29 - * distribution. 30 - * - Neither the name of Intel Corporation nor the names of its 31 - * contributors may be used to endorse or promote products derived 32 - * from this software without specific prior written permission. 33 - * 34 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 35 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 36 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 37 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 38 - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 39 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 40 - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 41 - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 42 - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 43 - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 44 - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 45 - * 46 - */ 47 - 48 - /* 49 - * This file contains OPA VNIC EMA Interface functions. 50 - */ 51 - 52 - #include "opa_vnic_internal.h" 53 - 54 - /** 55 - * opa_vnic_vema_report_event - sent trap to report the specified event 56 - * @adapter: vnic port adapter 57 - * @event: event to be reported 58 - * 59 - * This function calls vema api to sent a trap for the given event. 60 - */ 61 - void opa_vnic_vema_report_event(struct opa_vnic_adapter *adapter, u8 event) 62 - { 63 - struct __opa_veswport_info *info = &adapter->info; 64 - struct __opa_veswport_trap trap_data; 65 - 66 - trap_data.fabric_id = info->vesw.fabric_id; 67 - trap_data.veswid = info->vesw.vesw_id; 68 - trap_data.veswportnum = info->vport.port_num; 69 - trap_data.opaportnum = adapter->port_num; 70 - trap_data.veswportindex = adapter->vport_num; 71 - trap_data.opcode = event; 72 - 73 - opa_vnic_vema_send_trap(adapter, &trap_data, info->vport.encap_slid); 74 - } 75 - 76 - /** 77 - * opa_vnic_get_summary_counters - get summary counters 78 - * @adapter: vnic port adapter 79 - * @cntrs: pointer to destination summary counters structure 80 - * 81 - * This function populates the summary counters that is maintained by the 82 - * given adapter to destination address provided. 83 - */ 84 - void opa_vnic_get_summary_counters(struct opa_vnic_adapter *adapter, 85 - struct opa_veswport_summary_counters *cntrs) 86 - { 87 - struct opa_vnic_stats vstats; 88 - __be64 *dst; 89 - u64 *src; 90 - 91 - memset(&vstats, 0, sizeof(vstats)); 92 - spin_lock(&adapter->stats_lock); 93 - adapter->rn_ops->ndo_get_stats64(adapter->netdev, &vstats.netstats); 94 - spin_unlock(&adapter->stats_lock); 95 - 96 - cntrs->vp_instance = cpu_to_be16(adapter->vport_num); 97 - cntrs->vesw_id = cpu_to_be16(adapter->info.vesw.vesw_id); 98 - cntrs->veswport_num = cpu_to_be32(adapter->port_num); 99 - 100 - cntrs->tx_errors = cpu_to_be64(vstats.netstats.tx_errors); 101 - cntrs->rx_errors = cpu_to_be64(vstats.netstats.rx_errors); 102 - cntrs->tx_packets = cpu_to_be64(vstats.netstats.tx_packets); 103 - cntrs->rx_packets = cpu_to_be64(vstats.netstats.rx_packets); 104 - cntrs->tx_bytes = cpu_to_be64(vstats.netstats.tx_bytes); 105 - cntrs->rx_bytes = cpu_to_be64(vstats.netstats.rx_bytes); 106 - 107 - /* 108 - * This loop depends on layout of 109 - * opa_veswport_summary_counters opa_vnic_stats structures. 110 - */ 111 - for (dst = &cntrs->tx_unicast, src = &vstats.tx_grp.unicast; 112 - dst < &cntrs->reserved[0]; dst++, src++) { 113 - *dst = cpu_to_be64(*src); 114 - } 115 - } 116 - 117 - /** 118 - * opa_vnic_get_error_counters - get error counters 119 - * @adapter: vnic port adapter 120 - * @cntrs: pointer to destination error counters structure 121 - * 122 - * This function populates the error counters that is maintained by the 123 - * given adapter to destination address provided. 124 - */ 125 - void opa_vnic_get_error_counters(struct opa_vnic_adapter *adapter, 126 - struct opa_veswport_error_counters *cntrs) 127 - { 128 - struct opa_vnic_stats vstats; 129 - 130 - memset(&vstats, 0, sizeof(vstats)); 131 - spin_lock(&adapter->stats_lock); 132 - adapter->rn_ops->ndo_get_stats64(adapter->netdev, &vstats.netstats); 133 - spin_unlock(&adapter->stats_lock); 134 - 135 - cntrs->vp_instance = cpu_to_be16(adapter->vport_num); 136 - cntrs->vesw_id = cpu_to_be16(adapter->info.vesw.vesw_id); 137 - cntrs->veswport_num = cpu_to_be32(adapter->port_num); 138 - 139 - cntrs->tx_errors = cpu_to_be64(vstats.netstats.tx_errors); 140 - cntrs->rx_errors = cpu_to_be64(vstats.netstats.rx_errors); 141 - cntrs->tx_dlid_zero = cpu_to_be64(vstats.tx_dlid_zero); 142 - cntrs->tx_drop_state = cpu_to_be64(vstats.tx_drop_state); 143 - cntrs->tx_logic = cpu_to_be64(vstats.netstats.tx_fifo_errors + 144 - vstats.netstats.tx_carrier_errors); 145 - 146 - cntrs->rx_bad_veswid = cpu_to_be64(vstats.netstats.rx_nohandler); 147 - cntrs->rx_runt = cpu_to_be64(vstats.rx_runt); 148 - cntrs->rx_oversize = cpu_to_be64(vstats.rx_oversize); 149 - cntrs->rx_drop_state = cpu_to_be64(vstats.rx_drop_state); 150 - cntrs->rx_logic = cpu_to_be64(vstats.netstats.rx_fifo_errors); 151 - } 152 - 153 - /** 154 - * opa_vnic_get_vesw_info -- Get the vesw information 155 - * @adapter: vnic port adapter 156 - * @info: pointer to destination vesw info structure 157 - * 158 - * This function copies the vesw info that is maintained by the 159 - * given adapter to destination address provided. 160 - */ 161 - void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter, 162 - struct opa_vesw_info *info) 163 - { 164 - struct __opa_vesw_info *src = &adapter->info.vesw; 165 - int i; 166 - 167 - info->fabric_id = cpu_to_be16(src->fabric_id); 168 - info->vesw_id = cpu_to_be16(src->vesw_id); 169 - memcpy(info->rsvd0, src->rsvd0, ARRAY_SIZE(src->rsvd0)); 170 - info->def_port_mask = cpu_to_be16(src->def_port_mask); 171 - memcpy(info->rsvd1, src->rsvd1, ARRAY_SIZE(src->rsvd1)); 172 - info->pkey = cpu_to_be16(src->pkey); 173 - 174 - memcpy(info->rsvd2, src->rsvd2, ARRAY_SIZE(src->rsvd2)); 175 - info->u_mcast_dlid = cpu_to_be32(src->u_mcast_dlid); 176 - for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++) 177 - info->u_ucast_dlid[i] = cpu_to_be32(src->u_ucast_dlid[i]); 178 - 179 - info->rc = cpu_to_be32(src->rc); 180 - 181 - memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3)); 182 - info->eth_mtu = cpu_to_be16(src->eth_mtu); 183 - memcpy(info->rsvd4, src->rsvd4, ARRAY_SIZE(src->rsvd4)); 184 - } 185 - 186 - /** 187 - * opa_vnic_set_vesw_info -- Set the vesw information 188 - * @adapter: vnic port adapter 189 - * @info: pointer to vesw info structure 190 - * 191 - * This function updates the vesw info that is maintained by the 192 - * given adapter with vesw info provided. Reserved fields are stored 193 - * and returned back to EM as is. 194 - */ 195 - void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter, 196 - struct opa_vesw_info *info) 197 - { 198 - struct __opa_vesw_info *dst = &adapter->info.vesw; 199 - int i; 200 - 201 - dst->fabric_id = be16_to_cpu(info->fabric_id); 202 - dst->vesw_id = be16_to_cpu(info->vesw_id); 203 - memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0)); 204 - dst->def_port_mask = be16_to_cpu(info->def_port_mask); 205 - memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1)); 206 - dst->pkey = be16_to_cpu(info->pkey); 207 - 208 - memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2)); 209 - dst->u_mcast_dlid = be32_to_cpu(info->u_mcast_dlid); 210 - for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++) 211 - dst->u_ucast_dlid[i] = be32_to_cpu(info->u_ucast_dlid[i]); 212 - 213 - dst->rc = be32_to_cpu(info->rc); 214 - 215 - memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3)); 216 - dst->eth_mtu = be16_to_cpu(info->eth_mtu); 217 - memcpy(dst->rsvd4, info->rsvd4, ARRAY_SIZE(info->rsvd4)); 218 - } 219 - 220 - /** 221 - * opa_vnic_get_per_veswport_info -- Get the vesw per port information 222 - * @adapter: vnic port adapter 223 - * @info: pointer to destination vport info structure 224 - * 225 - * This function copies the vesw per port info that is maintained by the 226 - * given adapter to destination address provided. 227 - * Note that the read only fields are not copied. 228 - */ 229 - void opa_vnic_get_per_veswport_info(struct opa_vnic_adapter *adapter, 230 - struct opa_per_veswport_info *info) 231 - { 232 - struct __opa_per_veswport_info *src = &adapter->info.vport; 233 - 234 - info->port_num = cpu_to_be32(src->port_num); 235 - info->eth_link_status = src->eth_link_status; 236 - memcpy(info->rsvd0, src->rsvd0, ARRAY_SIZE(src->rsvd0)); 237 - 238 - memcpy(info->base_mac_addr, src->base_mac_addr, 239 - ARRAY_SIZE(info->base_mac_addr)); 240 - info->config_state = src->config_state; 241 - info->oper_state = src->oper_state; 242 - info->max_mac_tbl_ent = cpu_to_be16(src->max_mac_tbl_ent); 243 - info->max_smac_ent = cpu_to_be16(src->max_smac_ent); 244 - info->mac_tbl_digest = cpu_to_be32(src->mac_tbl_digest); 245 - memcpy(info->rsvd1, src->rsvd1, ARRAY_SIZE(src->rsvd1)); 246 - 247 - info->encap_slid = cpu_to_be32(src->encap_slid); 248 - memcpy(info->pcp_to_sc_uc, src->pcp_to_sc_uc, 249 - ARRAY_SIZE(info->pcp_to_sc_uc)); 250 - memcpy(info->pcp_to_vl_uc, src->pcp_to_vl_uc, 251 - ARRAY_SIZE(info->pcp_to_vl_uc)); 252 - memcpy(info->pcp_to_sc_mc, src->pcp_to_sc_mc, 253 - ARRAY_SIZE(info->pcp_to_sc_mc)); 254 - memcpy(info->pcp_to_vl_mc, src->pcp_to_vl_mc, 255 - ARRAY_SIZE(info->pcp_to_vl_mc)); 256 - info->non_vlan_sc_uc = src->non_vlan_sc_uc; 257 - info->non_vlan_vl_uc = src->non_vlan_vl_uc; 258 - info->non_vlan_sc_mc = src->non_vlan_sc_mc; 259 - info->non_vlan_vl_mc = src->non_vlan_vl_mc; 260 - memcpy(info->rsvd2, src->rsvd2, ARRAY_SIZE(src->rsvd2)); 261 - 262 - info->uc_macs_gen_count = cpu_to_be16(src->uc_macs_gen_count); 263 - info->mc_macs_gen_count = cpu_to_be16(src->mc_macs_gen_count); 264 - memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3)); 265 - } 266 - 267 - /** 268 - * opa_vnic_set_per_veswport_info -- Set vesw per port information 269 - * @adapter: vnic port adapter 270 - * @info: pointer to vport info structure 271 - * 272 - * This function updates the vesw per port info that is maintained by the 273 - * given adapter with vesw per port info provided. Reserved fields are 274 - * stored and returned back to EM as is. 275 - */ 276 - void opa_vnic_set_per_veswport_info(struct opa_vnic_adapter *adapter, 277 - struct opa_per_veswport_info *info) 278 - { 279 - struct __opa_per_veswport_info *dst = &adapter->info.vport; 280 - 281 - dst->port_num = be32_to_cpu(info->port_num); 282 - memcpy(dst->rsvd0, info->rsvd0, ARRAY_SIZE(info->rsvd0)); 283 - 284 - memcpy(dst->base_mac_addr, info->base_mac_addr, 285 - ARRAY_SIZE(dst->base_mac_addr)); 286 - dst->config_state = info->config_state; 287 - memcpy(dst->rsvd1, info->rsvd1, ARRAY_SIZE(info->rsvd1)); 288 - 289 - dst->encap_slid = be32_to_cpu(info->encap_slid); 290 - memcpy(dst->pcp_to_sc_uc, info->pcp_to_sc_uc, 291 - ARRAY_SIZE(dst->pcp_to_sc_uc)); 292 - memcpy(dst->pcp_to_vl_uc, info->pcp_to_vl_uc, 293 - ARRAY_SIZE(dst->pcp_to_vl_uc)); 294 - memcpy(dst->pcp_to_sc_mc, info->pcp_to_sc_mc, 295 - ARRAY_SIZE(dst->pcp_to_sc_mc)); 296 - memcpy(dst->pcp_to_vl_mc, info->pcp_to_vl_mc, 297 - ARRAY_SIZE(dst->pcp_to_vl_mc)); 298 - dst->non_vlan_sc_uc = info->non_vlan_sc_uc; 299 - dst->non_vlan_vl_uc = info->non_vlan_vl_uc; 300 - dst->non_vlan_sc_mc = info->non_vlan_sc_mc; 301 - dst->non_vlan_vl_mc = info->non_vlan_vl_mc; 302 - memcpy(dst->rsvd2, info->rsvd2, ARRAY_SIZE(info->rsvd2)); 303 - memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3)); 304 - } 305 - 306 - /** 307 - * opa_vnic_query_mcast_macs - query multicast mac list 308 - * @adapter: vnic port adapter 309 - * @macs: pointer mac list 310 - * 311 - * This function populates the provided mac list with the configured 312 - * multicast addresses in the adapter. 313 - */ 314 - void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter, 315 - struct opa_veswport_iface_macs *macs) 316 - { 317 - u16 start_idx, num_macs, idx = 0, count = 0; 318 - struct netdev_hw_addr *ha; 319 - 320 - start_idx = be16_to_cpu(macs->start_idx); 321 - num_macs = be16_to_cpu(macs->num_macs_in_msg); 322 - netdev_for_each_mc_addr(ha, adapter->netdev) { 323 - struct opa_vnic_iface_mac_entry *entry = &macs->entry[count]; 324 - 325 - if (start_idx > idx++) 326 - continue; 327 - else if (num_macs == count) 328 - break; 329 - memcpy(entry, ha->addr, sizeof(*entry)); 330 - count++; 331 - } 332 - 333 - macs->tot_macs_in_lst = cpu_to_be16(netdev_mc_count(adapter->netdev)); 334 - macs->num_macs_in_msg = cpu_to_be16(count); 335 - macs->gen_count = cpu_to_be16(adapter->info.vport.mc_macs_gen_count); 336 - } 337 - 338 - /** 339 - * opa_vnic_query_ucast_macs - query unicast mac list 340 - * @adapter: vnic port adapter 341 - * @macs: pointer mac list 342 - * 343 - * This function populates the provided mac list with the configured 344 - * unicast addresses in the adapter. 345 - */ 346 - void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter, 347 - struct opa_veswport_iface_macs *macs) 348 - { 349 - u16 start_idx, tot_macs, num_macs, idx = 0, count = 0, em_macs = 0; 350 - struct netdev_hw_addr *ha; 351 - 352 - start_idx = be16_to_cpu(macs->start_idx); 353 - num_macs = be16_to_cpu(macs->num_macs_in_msg); 354 - /* loop through dev_addrs list first */ 355 - for_each_dev_addr(adapter->netdev, ha) { 356 - struct opa_vnic_iface_mac_entry *entry = &macs->entry[count]; 357 - 358 - /* Do not include EM specified MAC address */ 359 - if (!memcmp(adapter->info.vport.base_mac_addr, ha->addr, 360 - ARRAY_SIZE(adapter->info.vport.base_mac_addr))) { 361 - em_macs++; 362 - continue; 363 - } 364 - 365 - if (start_idx > idx++) 366 - continue; 367 - else if (num_macs == count) 368 - break; 369 - memcpy(entry, ha->addr, sizeof(*entry)); 370 - count++; 371 - } 372 - 373 - /* loop through uc list */ 374 - netdev_for_each_uc_addr(ha, adapter->netdev) { 375 - struct opa_vnic_iface_mac_entry *entry = &macs->entry[count]; 376 - 377 - if (start_idx > idx++) 378 - continue; 379 - else if (num_macs == count) 380 - break; 381 - memcpy(entry, ha->addr, sizeof(*entry)); 382 - count++; 383 - } 384 - 385 - tot_macs = netdev_hw_addr_list_count(&adapter->netdev->dev_addrs) + 386 - netdev_uc_count(adapter->netdev) - em_macs; 387 - macs->tot_macs_in_lst = cpu_to_be16(tot_macs); 388 - macs->num_macs_in_msg = cpu_to_be16(count); 389 - macs->gen_count = cpu_to_be16(adapter->info.vport.uc_macs_gen_count); 390 - }
-6
include/rdma/ib_verbs.h
··· 2361 2361 2362 2362 /* rdma netdev type - specifies protocol type */ 2363 2363 enum rdma_netdev_t { 2364 - RDMA_NETDEV_OPA_VNIC, 2365 2364 RDMA_NETDEV_IPOIB, 2366 2365 }; 2367 2366 ··· 2374 2375 u32 port_num; 2375 2376 int mtu; 2376 2377 2377 - /* 2378 - * cleanup function must be specified. 2379 - * FIXME: This is only used for OPA_VNIC and that usage should be 2380 - * removed too. 2381 - */ 2382 2378 void (*free_rdma_netdev)(struct net_device *netdev); 2383 2379 2384 2380 /* control functions */
-96
include/rdma/opa_vnic.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ 2 - /* 3 - * Copyright(c) 2017 - 2020 Intel Corporation. 4 - */ 5 - 6 - #ifndef _OPA_VNIC_H 7 - #define _OPA_VNIC_H 8 - 9 - /* 10 - * This file contains Intel Omni-Path (OPA) Virtual Network Interface 11 - * Controller (VNIC) specific declarations. 12 - */ 13 - 14 - #include <rdma/ib_verbs.h> 15 - 16 - /* 16 header bytes + 2 reserved bytes */ 17 - #define OPA_VNIC_L2_HDR_LEN (16 + 2) 18 - 19 - #define OPA_VNIC_L4_HDR_LEN 2 20 - 21 - #define OPA_VNIC_HDR_LEN (OPA_VNIC_L2_HDR_LEN + \ 22 - OPA_VNIC_L4_HDR_LEN) 23 - 24 - #define OPA_VNIC_L4_ETHR 0x78 25 - 26 - #define OPA_VNIC_ICRC_LEN 4 27 - #define OPA_VNIC_TAIL_LEN 1 28 - #define OPA_VNIC_ICRC_TAIL_LEN (OPA_VNIC_ICRC_LEN + OPA_VNIC_TAIL_LEN) 29 - 30 - #define OPA_VNIC_SKB_MDATA_LEN 4 31 - #define OPA_VNIC_SKB_MDATA_ENCAP_ERR 0x1 32 - 33 - /* opa vnic rdma netdev's private data structure */ 34 - struct opa_vnic_rdma_netdev { 35 - struct rdma_netdev rn; /* keep this first */ 36 - /* followed by device private data */ 37 - char *dev_priv[]; 38 - }; 39 - 40 - static inline void *opa_vnic_priv(const struct net_device *dev) 41 - { 42 - struct rdma_netdev *rn = netdev_priv(dev); 43 - 44 - return rn->clnt_priv; 45 - } 46 - 47 - static inline void *opa_vnic_dev_priv(const struct net_device *dev) 48 - { 49 - struct opa_vnic_rdma_netdev *oparn = netdev_priv(dev); 50 - 51 - return oparn->dev_priv; 52 - } 53 - 54 - /* opa_vnic skb meta data structure */ 55 - struct opa_vnic_skb_mdata { 56 - u8 vl; 57 - u8 entropy; 58 - u8 flags; 59 - u8 rsvd; 60 - } __packed; 61 - 62 - /* OPA VNIC group statistics */ 63 - struct opa_vnic_grp_stats { 64 - u64 unicast; 65 - u64 mcastbcast; 66 - u64 untagged; 67 - u64 vlan; 68 - u64 s_64; 69 - u64 s_65_127; 70 - u64 s_128_255; 71 - u64 s_256_511; 72 - u64 s_512_1023; 73 - u64 s_1024_1518; 74 - u64 s_1519_max; 75 - }; 76 - 77 - struct opa_vnic_stats { 78 - /* standard netdev statistics */ 79 - struct rtnl_link_stats64 netstats; 80 - 81 - /* OPA VNIC statistics */ 82 - struct opa_vnic_grp_stats tx_grp; 83 - struct opa_vnic_grp_stats rx_grp; 84 - u64 tx_dlid_zero; 85 - u64 tx_drop_state; 86 - u64 rx_drop_state; 87 - u64 rx_runt; 88 - u64 rx_oversize; 89 - }; 90 - 91 - static inline bool rdma_cap_opa_vnic(struct ib_device *device) 92 - { 93 - return !!(device->attrs.kernel_cap_flags & IBK_RDMA_NETDEV_OPA); 94 - } 95 - 96 - #endif /* _OPA_VNIC_H */