net/hinic: add build and doc files
[dpdk.git] / drivers / net / hinic / hinic_pmd_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Huawei Technologies Co., Ltd
3  */
4
5 #include <rte_pci.h>
6 #include <rte_bus_pci.h>
7 #include <rte_ethdev_pci.h>
8 #include <rte_malloc.h>
9 #include <rte_memcpy.h>
10
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"
15
16 /* Vendor ID used by Huawei devices */
17 #define HINIC_HUAWEI_VENDOR_ID          0x19E5
18
19 /* Hinic devices */
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
24
25 #define HINIC_MIN_RX_BUF_SIZE           1024
26 #define HINIC_MAX_MAC_ADDRS             1
27
28 /** Driver-specific log messages type. */
29 int hinic_logtype;
30
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,
35 };
36
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,
41 };
42
43 /**
44  * Get link speed from NIC.
45  *
46  * @param dev
47  *   Pointer to Ethernet device structure.
48  * @param speed_capa
49  *   Pointer to link speed structure.
50  */
51 static void hinic_get_speed_capa(struct rte_eth_dev *dev, uint32_t *speed_capa)
52 {
53         struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
54         u32 supported_link, advertised_link;
55         int err;
56
57 #define HINIC_LINK_MODE_SUPPORT_1G      (1U << HINIC_GE_BASE_KX)
58
59 #define HINIC_LINK_MODE_SUPPORT_10G     (1U << HINIC_10GE_BASE_KR)
60
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))
65
66 #define HINIC_LINK_MODE_SUPPORT_40G     ((1U << HINIC_40GE_BASE_KR4) | \
67                                         (1U << HINIC_40GE_BASE_CR4))
68
69 #define HINIC_LINK_MODE_SUPPORT_100G    ((1U << HINIC_100GE_BASE_KR4) | \
70                                         (1U << HINIC_100GE_BASE_CR4))
71
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);
78         } else {
79                 *speed_capa = 0;
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;
90         }
91 }
92
93 /**
94  * DPDK callback to get information about the device.
95  *
96  * @param dev
97  *   Pointer to Ethernet device structure.
98  * @param info
99  *   Pointer to Info structure output buffer.
100  */
101 static void
102 hinic_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
103 {
104         struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
105
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;
111
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;
118
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;
128
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;
133 }
134
135 static int hinic_func_init(__rte_unused struct rte_eth_dev *eth_dev)
136 {
137         return 0;
138 }
139
140 /**
141  * DPDK callback to close the device.
142  *
143  * @param dev
144  *   Pointer to Ethernet device structure.
145  */
146 static void hinic_dev_close(__rte_unused struct rte_eth_dev *dev)
147 {
148 }
149
150 static const struct eth_dev_ops hinic_pmd_ops = {
151         .dev_infos_get                 = hinic_dev_infos_get,
152 };
153
154 static int hinic_dev_init(struct rte_eth_dev *eth_dev)
155 {
156         struct rte_pci_device *pci_dev;
157
158         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
159
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");
165
166         /* rte_eth_dev ops, rx_burst and tx_burst */
167         eth_dev->dev_ops = &hinic_pmd_ops;
168
169         return hinic_func_init(eth_dev);
170 }
171
172 static int hinic_dev_uninit(struct rte_eth_dev *dev)
173 {
174         struct hinic_nic_dev *nic_dev;
175
176         nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
177         hinic_clear_bit(HINIC_DEV_INIT, &nic_dev->dev_status);
178
179         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
180                 return 0;
181
182         hinic_dev_close(dev);
183
184         dev->dev_ops = NULL;
185         dev->rx_pkt_burst = NULL;
186         dev->tx_pkt_burst = NULL;
187
188         rte_free(dev->data->mac_addrs);
189         dev->data->mac_addrs = NULL;
190
191         return HINIC_OK;
192 }
193
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) },
199         {.vendor_id = 0},
200 };
201
202 static int hinic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
203                            struct rte_pci_device *pci_dev)
204 {
205         return rte_eth_dev_pci_generic_probe(pci_dev,
206                 sizeof(struct hinic_nic_dev), hinic_dev_init);
207 }
208
209 static int hinic_pci_remove(struct rte_pci_device *pci_dev)
210 {
211         return rte_eth_dev_pci_generic_remove(pci_dev, hinic_dev_uninit);
212 }
213
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,
219 };
220
221 RTE_PMD_REGISTER_PCI(net_hinic, rte_hinic_pmd);
222 RTE_PMD_REGISTER_PCI_TABLE(net_hinic, pci_id_hinic_map);
223
224 RTE_INIT(hinic_init_log)
225 {
226         hinic_logtype = rte_log_register("pmd.net.hinic");
227         if (hinic_logtype >= 0)
228                 rte_log_set_level(hinic_logtype, RTE_LOG_INFO);
229 }