1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2017 Huawei Technologies Co., Ltd
6 #include <rte_bus_pci.h>
7 #include <rte_ethdev_pci.h>
8 #include <rte_malloc.h>
9 #include <rte_memcpy.h>
11 #include "base/hinic_compat.h"
12 #include "base/hinic_pmd_hwdev.h"
13 #include "base/hinic_pmd_niccfg.h"
14 #include "hinic_pmd_ethdev.h"
16 /* Vendor ID used by Huawei devices */
17 #define HINIC_HUAWEI_VENDOR_ID 0x19E5
20 #define HINIC_DEV_ID_PRD 0x1822
21 #define HINIC_DEV_ID_MEZZ_25GE 0x0210
22 #define HINIC_DEV_ID_MEZZ_40GE 0x020D
23 #define HINIC_DEV_ID_MEZZ_100GE 0x0205
25 #define HINIC_MIN_RX_BUF_SIZE 1024
26 #define HINIC_MAX_MAC_ADDRS 1
28 /** Driver-specific log messages type. */
31 static const struct rte_eth_desc_lim hinic_rx_desc_lim = {
32 .nb_max = HINIC_MAX_QUEUE_DEPTH,
33 .nb_min = HINIC_MIN_QUEUE_DEPTH,
34 .nb_align = HINIC_RXD_ALIGN,
37 static const struct rte_eth_desc_lim hinic_tx_desc_lim = {
38 .nb_max = HINIC_MAX_QUEUE_DEPTH,
39 .nb_min = HINIC_MIN_QUEUE_DEPTH,
40 .nb_align = HINIC_TXD_ALIGN,
44 * Get link speed from NIC.
47 * Pointer to Ethernet device structure.
49 * Pointer to link speed structure.
51 static void hinic_get_speed_capa(struct rte_eth_dev *dev, uint32_t *speed_capa)
53 struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
54 u32 supported_link, advertised_link;
57 #define HINIC_LINK_MODE_SUPPORT_1G (1U << HINIC_GE_BASE_KX)
59 #define HINIC_LINK_MODE_SUPPORT_10G (1U << HINIC_10GE_BASE_KR)
61 #define HINIC_LINK_MODE_SUPPORT_25G ((1U << HINIC_25GE_BASE_KR_S) | \
62 (1U << HINIC_25GE_BASE_CR_S) | \
63 (1U << HINIC_25GE_BASE_KR) | \
64 (1U << HINIC_25GE_BASE_CR))
66 #define HINIC_LINK_MODE_SUPPORT_40G ((1U << HINIC_40GE_BASE_KR4) | \
67 (1U << HINIC_40GE_BASE_CR4))
69 #define HINIC_LINK_MODE_SUPPORT_100G ((1U << HINIC_100GE_BASE_KR4) | \
70 (1U << HINIC_100GE_BASE_CR4))
72 err = hinic_get_link_mode(nic_dev->hwdev,
73 &supported_link, &advertised_link);
74 if (err || supported_link == HINIC_SUPPORTED_UNKNOWN ||
75 advertised_link == HINIC_SUPPORTED_UNKNOWN) {
76 PMD_DRV_LOG(WARNING, "Get speed capability info failed, device: %s, port_id: %u",
77 nic_dev->proc_dev_name, dev->data->port_id);
80 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_1G))
81 *speed_capa |= ETH_LINK_SPEED_1G;
82 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_10G))
83 *speed_capa |= ETH_LINK_SPEED_10G;
84 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_25G))
85 *speed_capa |= ETH_LINK_SPEED_25G;
86 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_40G))
87 *speed_capa |= ETH_LINK_SPEED_40G;
88 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_100G))
89 *speed_capa |= ETH_LINK_SPEED_100G;
94 * DPDK callback to get information about the device.
97 * Pointer to Ethernet device structure.
99 * Pointer to Info structure output buffer.
102 hinic_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
104 struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
106 info->max_rx_queues = nic_dev->nic_cap.max_rqs;
107 info->max_tx_queues = nic_dev->nic_cap.max_sqs;
108 info->min_rx_bufsize = HINIC_MIN_RX_BUF_SIZE;
109 info->max_rx_pktlen = HINIC_MAX_JUMBO_FRAME_SIZE;
110 info->max_mac_addrs = HINIC_MAX_MAC_ADDRS;
112 hinic_get_speed_capa(dev, &info->speed_capa);
113 info->rx_queue_offload_capa = 0;
114 info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP |
115 DEV_RX_OFFLOAD_IPV4_CKSUM |
116 DEV_RX_OFFLOAD_UDP_CKSUM |
117 DEV_RX_OFFLOAD_TCP_CKSUM;
119 info->tx_queue_offload_capa = 0;
120 info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
121 DEV_TX_OFFLOAD_IPV4_CKSUM |
122 DEV_TX_OFFLOAD_UDP_CKSUM |
123 DEV_TX_OFFLOAD_TCP_CKSUM |
124 DEV_TX_OFFLOAD_SCTP_CKSUM |
125 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
126 DEV_TX_OFFLOAD_TCP_TSO |
127 DEV_TX_OFFLOAD_MULTI_SEGS;
129 info->hash_key_size = HINIC_RSS_KEY_SIZE;
130 info->reta_size = HINIC_RSS_INDIR_SIZE;
131 info->rx_desc_lim = hinic_rx_desc_lim;
132 info->tx_desc_lim = hinic_tx_desc_lim;
135 static int hinic_func_init(__rte_unused struct rte_eth_dev *eth_dev)
141 * DPDK callback to close the device.
144 * Pointer to Ethernet device structure.
146 static void hinic_dev_close(__rte_unused struct rte_eth_dev *dev)
150 static const struct eth_dev_ops hinic_pmd_ops = {
151 .dev_infos_get = hinic_dev_infos_get,
154 static int hinic_dev_init(struct rte_eth_dev *eth_dev)
156 struct rte_pci_device *pci_dev;
158 pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
160 PMD_DRV_LOG(INFO, "Initializing pf hinic-%.4x:%.2x:%.2x.%x in %s process",
161 pci_dev->addr.domain, pci_dev->addr.bus,
162 pci_dev->addr.devid, pci_dev->addr.function,
163 (rte_eal_process_type() == RTE_PROC_PRIMARY) ?
164 "primary" : "secondary");
166 /* rte_eth_dev ops, rx_burst and tx_burst */
167 eth_dev->dev_ops = &hinic_pmd_ops;
169 return hinic_func_init(eth_dev);
172 static int hinic_dev_uninit(struct rte_eth_dev *dev)
174 struct hinic_nic_dev *nic_dev;
176 nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
177 hinic_clear_bit(HINIC_DEV_INIT, &nic_dev->dev_status);
179 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
182 hinic_dev_close(dev);
185 dev->rx_pkt_burst = NULL;
186 dev->tx_pkt_burst = NULL;
188 rte_free(dev->data->mac_addrs);
189 dev->data->mac_addrs = NULL;
194 static struct rte_pci_id pci_id_hinic_map[] = {
195 { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_PRD) },
196 { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_25GE) },
197 { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_40GE) },
198 { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_100GE) },
202 static int hinic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
203 struct rte_pci_device *pci_dev)
205 return rte_eth_dev_pci_generic_probe(pci_dev,
206 sizeof(struct hinic_nic_dev), hinic_dev_init);
209 static int hinic_pci_remove(struct rte_pci_device *pci_dev)
211 return rte_eth_dev_pci_generic_remove(pci_dev, hinic_dev_uninit);
214 static struct rte_pci_driver rte_hinic_pmd = {
215 .id_table = pci_id_hinic_map,
216 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
217 .probe = hinic_pci_probe,
218 .remove = hinic_pci_remove,
221 RTE_PMD_REGISTER_PCI(net_hinic, rte_hinic_pmd);
222 RTE_PMD_REGISTER_PCI_TABLE(net_hinic, pci_id_hinic_map);
224 RTE_INIT(hinic_init_log)
226 hinic_logtype = rte_log_register("pmd.net.hinic");
227 if (hinic_logtype >= 0)
228 rte_log_set_level(hinic_logtype, RTE_LOG_INFO);