net/hinic: add device initialization
[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_mbuf.h>
9 #include <rte_malloc.h>
10 #include <rte_memcpy.h>
11 #include <rte_mempool.h>
12 #include <rte_errno.h>
13
14 #include "base/hinic_compat.h"
15 #include "base/hinic_pmd_hwdev.h"
16 #include "base/hinic_pmd_hwif.h"
17 #include "base/hinic_pmd_wq.h"
18 #include "base/hinic_pmd_cfg.h"
19 #include "base/hinic_pmd_mgmt.h"
20 #include "base/hinic_pmd_cmdq.h"
21 #include "base/hinic_pmd_niccfg.h"
22 #include "base/hinic_pmd_nicio.h"
23 #include "hinic_pmd_ethdev.h"
24 #include "hinic_pmd_tx.h"
25 #include "hinic_pmd_rx.h"
26
27 /* Vendor ID used by Huawei devices */
28 #define HINIC_HUAWEI_VENDOR_ID          0x19E5
29
30 /* Hinic devices */
31 #define HINIC_DEV_ID_PRD                0x1822
32 #define HINIC_DEV_ID_MEZZ_25GE          0x0210
33 #define HINIC_DEV_ID_MEZZ_40GE          0x020D
34 #define HINIC_DEV_ID_MEZZ_100GE         0x0205
35
36 #define HINIC_SERVICE_MODE_NIC          2
37
38 #define HINIC_INTR_CB_UNREG_MAX_RETRIES         10
39
40 #define DEFAULT_BASE_COS                4
41 #define NR_MAX_COS                      8
42
43 #define HINIC_MIN_RX_BUF_SIZE           1024
44 #define HINIC_MAX_MAC_ADDRS             1
45
46 /** Driver-specific log messages type. */
47 int hinic_logtype;
48
49 static const struct rte_eth_desc_lim hinic_rx_desc_lim = {
50         .nb_max = HINIC_MAX_QUEUE_DEPTH,
51         .nb_min = HINIC_MIN_QUEUE_DEPTH,
52         .nb_align = HINIC_RXD_ALIGN,
53 };
54
55 static const struct rte_eth_desc_lim hinic_tx_desc_lim = {
56         .nb_max = HINIC_MAX_QUEUE_DEPTH,
57         .nb_min = HINIC_MIN_QUEUE_DEPTH,
58         .nb_align = HINIC_TXD_ALIGN,
59 };
60
61 /**
62  * Interrupt handler triggered by NIC  for handling
63  * specific event.
64  *
65  * @param: The address of parameter (struct rte_eth_dev *) regsitered before.
66  **/
67 static void hinic_dev_interrupt_handler(void *param)
68 {
69         struct rte_eth_dev *dev = param;
70         struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
71
72         if (!hinic_test_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status)) {
73                 PMD_DRV_LOG(WARNING, "Device's interrupt is disabled, ignore interrupt event, dev_name: %s, port_id: %d",
74                             nic_dev->proc_dev_name, dev->data->port_id);
75                 return;
76         }
77
78         /* aeq0 msg handler */
79         hinic_dev_handle_aeq_event(nic_dev->hwdev, param);
80 }
81
82 /**
83  * Ethernet device configuration.
84  *
85  * Prepare the driver for a given number of TX and RX queues, mtu size
86  * and configure RSS.
87  *
88  * @param dev
89  *   Pointer to Ethernet device structure.
90  *
91  * @return
92  *   0 on success, negative error value otherwise.
93  */
94 static int hinic_dev_configure(struct rte_eth_dev *dev)
95 {
96         struct hinic_nic_dev *nic_dev;
97         struct hinic_nic_io *nic_io;
98         int err;
99
100         nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
101         nic_io = nic_dev->hwdev->nic_io;
102
103         nic_dev->num_sq =  dev->data->nb_tx_queues;
104         nic_dev->num_rq = dev->data->nb_rx_queues;
105
106         nic_io->num_sqs =  dev->data->nb_tx_queues;
107         nic_io->num_rqs = dev->data->nb_rx_queues;
108
109         /* queue pair is max_num(sq, rq) */
110         nic_dev->num_qps = (nic_dev->num_sq > nic_dev->num_rq) ?
111                         nic_dev->num_sq : nic_dev->num_rq;
112         nic_io->num_qps = nic_dev->num_qps;
113
114         if (nic_dev->num_qps > nic_io->max_qps) {
115                 PMD_DRV_LOG(ERR,
116                         "Queue number out of range, get queue_num:%d, max_queue_num:%d",
117                         nic_dev->num_qps, nic_io->max_qps);
118                 return -EINVAL;
119         }
120
121         /* mtu size is 256~9600 */
122         if (dev->data->dev_conf.rxmode.max_rx_pkt_len < HINIC_MIN_FRAME_SIZE ||
123             dev->data->dev_conf.rxmode.max_rx_pkt_len >
124             HINIC_MAX_JUMBO_FRAME_SIZE) {
125                 PMD_DRV_LOG(ERR,
126                         "Max rx pkt len out of range, get max_rx_pkt_len:%d, "
127                         "expect between %d and %d",
128                         dev->data->dev_conf.rxmode.max_rx_pkt_len,
129                         HINIC_MIN_FRAME_SIZE, HINIC_MAX_JUMBO_FRAME_SIZE);
130                 return -EINVAL;
131         }
132
133         nic_dev->mtu_size =
134                 HINIC_PKTLEN_TO_MTU(dev->data->dev_conf.rxmode.max_rx_pkt_len);
135
136         /* rss template */
137         err = hinic_config_mq_mode(dev, TRUE);
138         if (err) {
139                 PMD_DRV_LOG(ERR, "Config multi-queue failed");
140                 return err;
141         }
142
143         return HINIC_OK;
144 }
145
146 /**
147  * Get link speed from NIC.
148  *
149  * @param dev
150  *   Pointer to Ethernet device structure.
151  * @param speed_capa
152  *   Pointer to link speed structure.
153  */
154 static void hinic_get_speed_capa(struct rte_eth_dev *dev, uint32_t *speed_capa)
155 {
156         struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
157         u32 supported_link, advertised_link;
158         int err;
159
160 #define HINIC_LINK_MODE_SUPPORT_1G      (1U << HINIC_GE_BASE_KX)
161
162 #define HINIC_LINK_MODE_SUPPORT_10G     (1U << HINIC_10GE_BASE_KR)
163
164 #define HINIC_LINK_MODE_SUPPORT_25G     ((1U << HINIC_25GE_BASE_KR_S) | \
165                                         (1U << HINIC_25GE_BASE_CR_S) | \
166                                         (1U << HINIC_25GE_BASE_KR) | \
167                                         (1U << HINIC_25GE_BASE_CR))
168
169 #define HINIC_LINK_MODE_SUPPORT_40G     ((1U << HINIC_40GE_BASE_KR4) | \
170                                         (1U << HINIC_40GE_BASE_CR4))
171
172 #define HINIC_LINK_MODE_SUPPORT_100G    ((1U << HINIC_100GE_BASE_KR4) | \
173                                         (1U << HINIC_100GE_BASE_CR4))
174
175         err = hinic_get_link_mode(nic_dev->hwdev,
176                                   &supported_link, &advertised_link);
177         if (err || supported_link == HINIC_SUPPORTED_UNKNOWN ||
178             advertised_link == HINIC_SUPPORTED_UNKNOWN) {
179                 PMD_DRV_LOG(WARNING, "Get speed capability info failed, device: %s, port_id: %u",
180                           nic_dev->proc_dev_name, dev->data->port_id);
181         } else {
182                 *speed_capa = 0;
183                 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_1G))
184                         *speed_capa |= ETH_LINK_SPEED_1G;
185                 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_10G))
186                         *speed_capa |= ETH_LINK_SPEED_10G;
187                 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_25G))
188                         *speed_capa |= ETH_LINK_SPEED_25G;
189                 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_40G))
190                         *speed_capa |= ETH_LINK_SPEED_40G;
191                 if (!!(supported_link & HINIC_LINK_MODE_SUPPORT_100G))
192                         *speed_capa |= ETH_LINK_SPEED_100G;
193         }
194 }
195
196 /**
197  * DPDK callback to get information about the device.
198  *
199  * @param dev
200  *   Pointer to Ethernet device structure.
201  * @param info
202  *   Pointer to Info structure output buffer.
203  */
204 static void
205 hinic_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
206 {
207         struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
208
209         info->max_rx_queues  = nic_dev->nic_cap.max_rqs;
210         info->max_tx_queues  = nic_dev->nic_cap.max_sqs;
211         info->min_rx_bufsize = HINIC_MIN_RX_BUF_SIZE;
212         info->max_rx_pktlen  = HINIC_MAX_JUMBO_FRAME_SIZE;
213         info->max_mac_addrs  = HINIC_MAX_MAC_ADDRS;
214
215         hinic_get_speed_capa(dev, &info->speed_capa);
216         info->rx_queue_offload_capa = 0;
217         info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP |
218                                 DEV_RX_OFFLOAD_IPV4_CKSUM |
219                                 DEV_RX_OFFLOAD_UDP_CKSUM |
220                                 DEV_RX_OFFLOAD_TCP_CKSUM;
221
222         info->tx_queue_offload_capa = 0;
223         info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT |
224                                 DEV_TX_OFFLOAD_IPV4_CKSUM |
225                                 DEV_TX_OFFLOAD_UDP_CKSUM |
226                                 DEV_TX_OFFLOAD_TCP_CKSUM |
227                                 DEV_TX_OFFLOAD_SCTP_CKSUM |
228                                 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
229                                 DEV_TX_OFFLOAD_TCP_TSO |
230                                 DEV_TX_OFFLOAD_MULTI_SEGS;
231
232         info->hash_key_size = HINIC_RSS_KEY_SIZE;
233         info->reta_size = HINIC_RSS_INDIR_SIZE;
234         info->flow_type_rss_offloads = HINIC_RSS_OFFLOAD_ALL;
235         info->rx_desc_lim = hinic_rx_desc_lim;
236         info->tx_desc_lim = hinic_tx_desc_lim;
237 }
238
239 static void hinic_free_all_rq(struct hinic_nic_dev *nic_dev)
240 {
241         u16 q_id;
242
243         for (q_id = 0; q_id < nic_dev->num_rq; q_id++)
244                 hinic_destroy_rq(nic_dev->hwdev, q_id);
245 }
246
247 static void hinic_free_all_sq(struct hinic_nic_dev *nic_dev)
248 {
249         u16 q_id;
250
251         for (q_id = 0; q_id < nic_dev->num_sq; q_id++)
252                 hinic_destroy_sq(nic_dev->hwdev, q_id);
253 }
254
255 static void hinic_disable_interrupt(struct rte_eth_dev *dev)
256 {
257         struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
258         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
259         int ret, retries = 0;
260
261         hinic_clear_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
262
263         /* disable msix interrupt in hardware */
264         hinic_set_msix_state(nic_dev->hwdev, 0, HINIC_MSIX_DISABLE);
265
266         /* disable rte interrupt */
267         ret = rte_intr_disable(&pci_dev->intr_handle);
268         if (ret)
269                 PMD_DRV_LOG(ERR, "Disable intr failed: %d", ret);
270
271         do {
272                 ret =
273                 rte_intr_callback_unregister(&pci_dev->intr_handle,
274                                              hinic_dev_interrupt_handler, dev);
275                 if (ret >= 0) {
276                         break;
277                 } else if (ret == -EAGAIN) {
278                         rte_delay_ms(100);
279                         retries++;
280                 } else {
281                         PMD_DRV_LOG(ERR, "intr callback unregister failed: %d",
282                                     ret);
283                         break;
284                 }
285         } while (retries < HINIC_INTR_CB_UNREG_MAX_RETRIES);
286
287         if (retries == HINIC_INTR_CB_UNREG_MAX_RETRIES)
288                 PMD_DRV_LOG(ERR, "Unregister intr callback failed after %d retries",
289                             retries);
290 }
291
292 /**
293  * Init mac_vlan table in NIC.
294  *
295  * @param dev
296  *   Pointer to Ethernet device structure.
297  *
298  * @return
299  *   0 on success and stats is filled,
300  *   negative error value otherwise.
301  */
302 static int hinic_init_mac_addr(struct rte_eth_dev *eth_dev)
303 {
304         struct hinic_nic_dev *nic_dev =
305                                 HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
306         uint8_t addr_bytes[RTE_ETHER_ADDR_LEN];
307         u16 func_id = 0;
308         int rc = 0;
309
310         rc = hinic_get_default_mac(nic_dev->hwdev, addr_bytes);
311         if (rc)
312                 return rc;
313
314         memmove(eth_dev->data->mac_addrs->addr_bytes,
315                 addr_bytes, RTE_ETHER_ADDR_LEN);
316
317         func_id = hinic_global_func_id(nic_dev->hwdev);
318         rc = hinic_set_mac(nic_dev->hwdev, eth_dev->data->mac_addrs->addr_bytes,
319                            0, func_id);
320         if (rc && rc != HINIC_PF_SET_VF_ALREADY)
321                 return rc;
322
323         return 0;
324 }
325
326 /**
327  * Deinit mac_vlan table in NIC.
328  *
329  * @param dev
330  *   Pointer to Ethernet device structure.
331  *
332  * @return
333  *   0 on success and stats is filled,
334  *   negative error value otherwise.
335  */
336 static void hinic_deinit_mac_addr(struct rte_eth_dev *eth_dev)
337 {
338         struct hinic_nic_dev *nic_dev =
339                                 HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
340         int rc;
341         u16 func_id = 0;
342
343         if (rte_is_zero_ether_addr(eth_dev->data->mac_addrs))
344                 return;
345
346         func_id = hinic_global_func_id(nic_dev->hwdev);
347         rc = hinic_del_mac(nic_dev->hwdev,
348                            eth_dev->data->mac_addrs->addr_bytes,
349                            0, func_id);
350         if (rc && rc != HINIC_PF_SET_VF_ALREADY)
351                 PMD_DRV_LOG(ERR, "Delete mac table failed, dev_name: %s",
352                             eth_dev->data->name);
353 }
354
355 static int hinic_set_default_pause_feature(struct hinic_nic_dev *nic_dev)
356 {
357         struct nic_pause_config pause_config = {0};
358
359         pause_config.auto_neg = 0;
360         pause_config.rx_pause = HINIC_DEFAUT_PAUSE_CONFIG;
361         pause_config.tx_pause = HINIC_DEFAUT_PAUSE_CONFIG;
362
363         return hinic_set_pause_config(nic_dev->hwdev, pause_config);
364 }
365
366 static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev)
367 {
368         u8 up_tc[HINIC_DCB_UP_MAX] = {0};
369         u8 up_pgid[HINIC_DCB_UP_MAX] = {0};
370         u8 up_bw[HINIC_DCB_UP_MAX] = {0};
371         u8 pg_bw[HINIC_DCB_UP_MAX] = {0};
372         u8 up_strict[HINIC_DCB_UP_MAX] = {0};
373         int i = 0;
374
375         pg_bw[0] = 100;
376         for (i = 0; i < HINIC_DCB_UP_MAX; i++)
377                 up_bw[i] = 100;
378
379         return hinic_dcb_set_ets(nic_dev->hwdev, up_tc, pg_bw,
380                                         up_pgid, up_bw, up_strict);
381 }
382
383 static void hinic_init_default_cos(struct hinic_nic_dev *nic_dev)
384 {
385         nic_dev->default_cos =
386                         (hinic_global_func_id(nic_dev->hwdev) +
387                          DEFAULT_BASE_COS) % NR_MAX_COS;
388 }
389
390 static int hinic_set_default_hw_feature(struct hinic_nic_dev *nic_dev)
391 {
392         int err;
393
394         hinic_init_default_cos(nic_dev);
395
396         /* Restore DCB configure to default status */
397         err = hinic_set_default_dcb_feature(nic_dev);
398         if (err)
399                 return err;
400
401         /* disable LRO */
402         err = hinic_set_rx_lro(nic_dev->hwdev, 0, 0, (u8)0);
403         if (err)
404                 return err;
405
406         /* Set pause enable, and up will disable pfc. */
407         err = hinic_set_default_pause_feature(nic_dev);
408         if (err)
409                 return err;
410
411         err = hinic_reset_port_link_cfg(nic_dev->hwdev);
412         if (err)
413                 return err;
414
415         err = hinic_set_link_status_follow(nic_dev->hwdev,
416                                            HINIC_LINK_FOLLOW_PORT);
417         if (err == HINIC_MGMT_CMD_UNSUPPORTED)
418                 PMD_DRV_LOG(WARNING, "Don't support to set link status follow phy port status");
419         else if (err)
420                 return err;
421
422         return hinic_set_anti_attack(nic_dev->hwdev, true);
423 }
424
425 static int32_t hinic_card_workmode_check(struct hinic_nic_dev *nic_dev)
426 {
427         struct hinic_board_info info = { 0 };
428         int rc;
429
430         rc = hinic_get_board_info(nic_dev->hwdev, &info);
431         if (rc)
432                 return rc;
433
434         return (info.service_mode == HINIC_SERVICE_MODE_NIC ? HINIC_OK :
435                                                 HINIC_ERROR);
436 }
437
438 static int hinic_copy_mempool_init(struct hinic_nic_dev *nic_dev)
439 {
440         nic_dev->cpy_mpool = rte_mempool_lookup(nic_dev->proc_dev_name);
441         if (nic_dev->cpy_mpool == NULL) {
442                 nic_dev->cpy_mpool =
443                 rte_pktmbuf_pool_create(nic_dev->proc_dev_name,
444                                         HINIC_COPY_MEMPOOL_DEPTH,
445                                         RTE_CACHE_LINE_SIZE, 0,
446                                         HINIC_COPY_MBUF_SIZE,
447                                         rte_socket_id());
448                 if (!nic_dev->cpy_mpool) {
449                         PMD_DRV_LOG(ERR, "Create copy mempool failed, errno: %d, dev_name: %s",
450                                     rte_errno, nic_dev->proc_dev_name);
451                         return -ENOMEM;
452                 }
453         }
454
455         return 0;
456 }
457
458 static void hinic_copy_mempool_uninit(struct hinic_nic_dev *nic_dev)
459 {
460         if (nic_dev->cpy_mpool != NULL)
461                 rte_mempool_free(nic_dev->cpy_mpool);
462 }
463
464 static int hinic_init_sw_rxtxqs(struct hinic_nic_dev *nic_dev)
465 {
466         u32 txq_size;
467         u32 rxq_size;
468
469         /* allocate software txq array */
470         txq_size = nic_dev->nic_cap.max_sqs * sizeof(*nic_dev->txqs);
471         nic_dev->txqs = kzalloc_aligned(txq_size, GFP_KERNEL);
472         if (!nic_dev->txqs) {
473                 PMD_DRV_LOG(ERR, "Allocate txqs failed");
474                 return -ENOMEM;
475         }
476
477         /* allocate software rxq array */
478         rxq_size = nic_dev->nic_cap.max_rqs * sizeof(*nic_dev->rxqs);
479         nic_dev->rxqs = kzalloc_aligned(rxq_size, GFP_KERNEL);
480         if (!nic_dev->rxqs) {
481                 /* free txqs */
482                 kfree(nic_dev->txqs);
483                 nic_dev->txqs = NULL;
484
485                 PMD_DRV_LOG(ERR, "Allocate rxqs failed");
486                 return -ENOMEM;
487         }
488
489         return HINIC_OK;
490 }
491
492 static void hinic_deinit_sw_rxtxqs(struct hinic_nic_dev *nic_dev)
493 {
494         kfree(nic_dev->txqs);
495         nic_dev->txqs = NULL;
496
497         kfree(nic_dev->rxqs);
498         nic_dev->rxqs = NULL;
499 }
500
501 static int hinic_nic_dev_create(struct rte_eth_dev *eth_dev)
502 {
503         struct hinic_nic_dev *nic_dev =
504                                 HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
505         int rc;
506
507         nic_dev->hwdev = rte_zmalloc("hinic_hwdev", sizeof(*nic_dev->hwdev),
508                                      RTE_CACHE_LINE_SIZE);
509         if (!nic_dev->hwdev) {
510                 PMD_DRV_LOG(ERR, "Allocate hinic hwdev memory failed, dev_name: %s",
511                             eth_dev->data->name);
512                 return -ENOMEM;
513         }
514         nic_dev->hwdev->pcidev_hdl = RTE_ETH_DEV_TO_PCI(eth_dev);
515
516         /* init osdep*/
517         rc = hinic_osdep_init(nic_dev->hwdev);
518         if (rc) {
519                 PMD_DRV_LOG(ERR, "Initialize os_dep failed, dev_name: %s",
520                             eth_dev->data->name);
521                 goto init_osdep_fail;
522         }
523
524         /* init_hwif */
525         rc = hinic_hwif_res_init(nic_dev->hwdev);
526         if (rc) {
527                 PMD_DRV_LOG(ERR, "Initialize hwif failed, dev_name: %s",
528                             eth_dev->data->name);
529                 goto init_hwif_fail;
530         }
531
532         /* init_cfg_mgmt */
533         rc = init_cfg_mgmt(nic_dev->hwdev);
534         if (rc) {
535                 PMD_DRV_LOG(ERR, "Initialize cfg_mgmt failed, dev_name: %s",
536                             eth_dev->data->name);
537                 goto init_cfgmgnt_fail;
538         }
539
540         /* init_aeqs */
541         rc = hinic_comm_aeqs_init(nic_dev->hwdev);
542         if (rc) {
543                 PMD_DRV_LOG(ERR, "Initialize aeqs failed, dev_name: %s",
544                             eth_dev->data->name);
545                 goto init_aeqs_fail;
546         }
547
548         /* init_pf_to_mgnt */
549         rc = hinic_comm_pf_to_mgmt_init(nic_dev->hwdev);
550         if (rc) {
551                 PMD_DRV_LOG(ERR, "Initialize pf_to_mgmt failed, dev_name: %s",
552                             eth_dev->data->name);
553                 goto init_pf_to_mgmt_fail;
554         }
555
556         rc = hinic_card_workmode_check(nic_dev);
557         if (rc) {
558                 PMD_DRV_LOG(ERR, "Check card workmode failed, dev_name: %s",
559                             eth_dev->data->name);
560                 goto workmode_check_fail;
561         }
562
563         /* do l2nic reset to make chip clear */
564         rc = hinic_l2nic_reset(nic_dev->hwdev);
565         if (rc) {
566                 PMD_DRV_LOG(ERR, "Do l2nic reset failed, dev_name: %s",
567                             eth_dev->data->name);
568                 goto l2nic_reset_fail;
569         }
570
571         /* init dma and aeq msix attribute table */
572         (void)hinic_init_attr_table(nic_dev->hwdev);
573
574         /* init_cmdqs */
575         rc = hinic_comm_cmdqs_init(nic_dev->hwdev);
576         if (rc) {
577                 PMD_DRV_LOG(ERR, "Initialize cmdq failed, dev_name: %s",
578                             eth_dev->data->name);
579                 goto init_cmdq_fail;
580         }
581
582         /* set hardware state active */
583         rc = hinic_activate_hwdev_state(nic_dev->hwdev);
584         if (rc) {
585                 PMD_DRV_LOG(ERR, "Initialize resources state failed, dev_name: %s",
586                             eth_dev->data->name);
587                 goto init_resources_state_fail;
588         }
589
590         /* init_capability */
591         rc = hinic_init_capability(nic_dev->hwdev);
592         if (rc) {
593                 PMD_DRV_LOG(ERR, "Initialize capability failed, dev_name: %s",
594                             eth_dev->data->name);
595                 goto init_cap_fail;
596         }
597
598         /* get nic capability */
599         if (!hinic_support_nic(nic_dev->hwdev, &nic_dev->nic_cap))
600                 goto nic_check_fail;
601
602         /* init root cla and function table */
603         rc = hinic_init_nicio(nic_dev->hwdev);
604         if (rc) {
605                 PMD_DRV_LOG(ERR, "Initialize nic_io failed, dev_name: %s",
606                             eth_dev->data->name);
607                 goto init_nicio_fail;
608         }
609
610         /* init_software_txrxq */
611         rc = hinic_init_sw_rxtxqs(nic_dev);
612         if (rc) {
613                 PMD_DRV_LOG(ERR, "Initialize sw_rxtxqs failed, dev_name: %s",
614                             eth_dev->data->name);
615                 goto init_sw_rxtxqs_fail;
616         }
617
618         rc = hinic_copy_mempool_init(nic_dev);
619         if (rc) {
620                 PMD_DRV_LOG(ERR, "Create copy mempool failed, dev_name: %s",
621                          eth_dev->data->name);
622                 goto init_mpool_fail;
623         }
624
625         /* set hardware feature to default status */
626         rc = hinic_set_default_hw_feature(nic_dev);
627         if (rc) {
628                 PMD_DRV_LOG(ERR, "Initialize hardware default features failed, dev_name: %s",
629                             eth_dev->data->name);
630                 goto set_default_hw_feature_fail;
631         }
632
633         return 0;
634
635 set_default_hw_feature_fail:
636         hinic_copy_mempool_uninit(nic_dev);
637
638 init_mpool_fail:
639         hinic_deinit_sw_rxtxqs(nic_dev);
640
641 init_sw_rxtxqs_fail:
642         hinic_deinit_nicio(nic_dev->hwdev);
643
644 nic_check_fail:
645 init_nicio_fail:
646 init_cap_fail:
647         hinic_deactivate_hwdev_state(nic_dev->hwdev);
648
649 init_resources_state_fail:
650         hinic_comm_cmdqs_free(nic_dev->hwdev);
651
652 init_cmdq_fail:
653 l2nic_reset_fail:
654 workmode_check_fail:
655         hinic_comm_pf_to_mgmt_free(nic_dev->hwdev);
656
657 init_pf_to_mgmt_fail:
658         hinic_comm_aeqs_free(nic_dev->hwdev);
659
660 init_aeqs_fail:
661         free_cfg_mgmt(nic_dev->hwdev);
662
663 init_cfgmgnt_fail:
664         hinic_hwif_res_free(nic_dev->hwdev);
665
666 init_hwif_fail:
667         hinic_osdep_deinit(nic_dev->hwdev);
668
669 init_osdep_fail:
670         rte_free(nic_dev->hwdev);
671         nic_dev->hwdev = NULL;
672
673         return rc;
674 }
675
676 static void hinic_nic_dev_destroy(struct rte_eth_dev *eth_dev)
677 {
678         struct hinic_nic_dev *nic_dev =
679                         HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
680
681         (void)hinic_set_link_status_follow(nic_dev->hwdev,
682                                            HINIC_LINK_FOLLOW_DEFAULT);
683         hinic_copy_mempool_uninit(nic_dev);
684         hinic_deinit_sw_rxtxqs(nic_dev);
685         hinic_deinit_nicio(nic_dev->hwdev);
686         hinic_deactivate_hwdev_state(nic_dev->hwdev);
687         hinic_comm_cmdqs_free(nic_dev->hwdev);
688         hinic_comm_pf_to_mgmt_free(nic_dev->hwdev);
689         hinic_comm_aeqs_free(nic_dev->hwdev);
690         free_cfg_mgmt(nic_dev->hwdev);
691         hinic_hwif_res_free(nic_dev->hwdev);
692         hinic_osdep_deinit(nic_dev->hwdev);
693         rte_free(nic_dev->hwdev);
694         nic_dev->hwdev = NULL;
695 }
696
697 static int hinic_func_init(struct rte_eth_dev *eth_dev)
698 {
699         struct rte_pci_device *pci_dev;
700         struct rte_ether_addr *eth_addr;
701         struct hinic_nic_dev *nic_dev;
702         int rc;
703
704         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
705
706         /* EAL is SECONDARY and eth_dev is already created */
707         if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
708                 rc = rte_intr_callback_register(&pci_dev->intr_handle,
709                                                 hinic_dev_interrupt_handler,
710                                                 (void *)eth_dev);
711                 if (rc)
712                         PMD_DRV_LOG(ERR, "Initialize %s failed in secondary process",
713                                     eth_dev->data->name);
714
715                 return rc;
716         }
717
718         nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
719         memset(nic_dev, 0, sizeof(*nic_dev));
720
721         snprintf(nic_dev->proc_dev_name,
722                  sizeof(nic_dev->proc_dev_name),
723                  "hinic-%.4x:%.2x:%.2x.%x",
724                  pci_dev->addr.domain, pci_dev->addr.bus,
725                  pci_dev->addr.devid, pci_dev->addr.function);
726
727         /* alloc mac_addrs */
728         eth_addr = rte_zmalloc("hinic_mac", sizeof(*eth_addr), 0);
729         if (!eth_addr) {
730                 PMD_DRV_LOG(ERR, "Allocate ethernet addresses' memory failed, dev_name: %s",
731                             eth_dev->data->name);
732                 rc = -ENOMEM;
733                 goto eth_addr_fail;
734         }
735         eth_dev->data->mac_addrs = eth_addr;
736
737         /*
738          * Pass the information to the rte_eth_dev_close() that it should also
739          * release the private port resources.
740          */
741         eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
742
743         /* create hardware nic_device */
744         rc = hinic_nic_dev_create(eth_dev);
745         if (rc) {
746                 PMD_DRV_LOG(ERR, "Create nic device failed, dev_name: %s",
747                             eth_dev->data->name);
748                 goto create_nic_dev_fail;
749         }
750
751         rc = hinic_init_mac_addr(eth_dev);
752         if (rc) {
753                 PMD_DRV_LOG(ERR, "Initialize mac table failed, dev_name: %s",
754                             eth_dev->data->name);
755                 goto init_mac_fail;
756         }
757
758         /* register callback func to eal lib */
759         rc = rte_intr_callback_register(&pci_dev->intr_handle,
760                                         hinic_dev_interrupt_handler,
761                                         (void *)eth_dev);
762         if (rc) {
763                 PMD_DRV_LOG(ERR, "Register rte interrupt callback failed, dev_name: %s",
764                             eth_dev->data->name);
765                 goto reg_intr_cb_fail;
766         }
767
768         /* enable uio/vfio intr/eventfd mapping */
769         rc = rte_intr_enable(&pci_dev->intr_handle);
770         if (rc) {
771                 PMD_DRV_LOG(ERR, "Enable rte interrupt failed, dev_name: %s",
772                             eth_dev->data->name);
773                 goto enable_intr_fail;
774         }
775         hinic_set_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status);
776
777         hinic_set_bit(HINIC_DEV_INIT, &nic_dev->dev_status);
778         PMD_DRV_LOG(INFO, "Initialize %s in primary successfully",
779                     eth_dev->data->name);
780
781         return 0;
782
783 enable_intr_fail:
784         (void)rte_intr_callback_unregister(&pci_dev->intr_handle,
785                                            hinic_dev_interrupt_handler,
786                                            (void *)eth_dev);
787
788 reg_intr_cb_fail:
789         hinic_deinit_mac_addr(eth_dev);
790
791 init_mac_fail:
792         hinic_nic_dev_destroy(eth_dev);
793
794 create_nic_dev_fail:
795         rte_free(eth_addr);
796         eth_dev->data->mac_addrs = NULL;
797
798 eth_addr_fail:
799         PMD_DRV_LOG(ERR, "Initialize %s in primary failed",
800                     eth_dev->data->name);
801         return rc;
802 }
803
804 /**
805  * DPDK callback to close the device.
806  *
807  * @param dev
808  *   Pointer to Ethernet device structure.
809  */
810 static void hinic_dev_close(struct rte_eth_dev *dev)
811 {
812         struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
813
814         if (hinic_test_and_set_bit(HINIC_DEV_CLOSE, &nic_dev->dev_status)) {
815                 PMD_DRV_LOG(WARNING, "Device %s already closed",
816                             dev->data->name);
817                 return;
818         }
819
820         /* rx_cqe, rx_info */
821         hinic_free_all_rx_resources(dev);
822
823         /* tx_info */
824         hinic_free_all_tx_resources(dev);
825
826         /* free wq, pi_dma_addr */
827         hinic_free_all_rq(nic_dev);
828
829         /* free wq, db_addr */
830         hinic_free_all_sq(nic_dev);
831
832         /* deinit mac vlan tbl */
833         hinic_deinit_mac_addr(dev);
834
835         /* disable hardware and uio interrupt */
836         hinic_disable_interrupt(dev);
837
838         /* deinit nic hardware device */
839         hinic_nic_dev_destroy(dev);
840 }
841
842 static const struct eth_dev_ops hinic_pmd_ops = {
843         .dev_configure                 = hinic_dev_configure,
844         .dev_infos_get                 = hinic_dev_infos_get,
845         .dev_close                     = hinic_dev_close,
846 };
847
848 static int hinic_dev_init(struct rte_eth_dev *eth_dev)
849 {
850         struct rte_pci_device *pci_dev;
851
852         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
853
854         PMD_DRV_LOG(INFO, "Initializing pf hinic-%.4x:%.2x:%.2x.%x in %s process",
855                     pci_dev->addr.domain, pci_dev->addr.bus,
856                     pci_dev->addr.devid, pci_dev->addr.function,
857                     (rte_eal_process_type() == RTE_PROC_PRIMARY) ?
858                     "primary" : "secondary");
859
860         /* rte_eth_dev ops, rx_burst and tx_burst */
861         eth_dev->dev_ops = &hinic_pmd_ops;
862
863         return hinic_func_init(eth_dev);
864 }
865
866 static int hinic_dev_uninit(struct rte_eth_dev *dev)
867 {
868         struct hinic_nic_dev *nic_dev;
869
870         nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
871         hinic_clear_bit(HINIC_DEV_INIT, &nic_dev->dev_status);
872
873         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
874                 return 0;
875
876         hinic_dev_close(dev);
877
878         dev->dev_ops = NULL;
879
880         rte_free(dev->data->mac_addrs);
881         dev->data->mac_addrs = NULL;
882
883         return HINIC_OK;
884 }
885
886 static struct rte_pci_id pci_id_hinic_map[] = {
887         { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_PRD) },
888         { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_25GE) },
889         { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_40GE) },
890         { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_100GE) },
891         {.vendor_id = 0},
892 };
893
894 static int hinic_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
895                            struct rte_pci_device *pci_dev)
896 {
897         return rte_eth_dev_pci_generic_probe(pci_dev,
898                 sizeof(struct hinic_nic_dev), hinic_dev_init);
899 }
900
901 static int hinic_pci_remove(struct rte_pci_device *pci_dev)
902 {
903         return rte_eth_dev_pci_generic_remove(pci_dev, hinic_dev_uninit);
904 }
905
906 static struct rte_pci_driver rte_hinic_pmd = {
907         .id_table = pci_id_hinic_map,
908         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
909         .probe = hinic_pci_probe,
910         .remove = hinic_pci_remove,
911 };
912
913 RTE_PMD_REGISTER_PCI(net_hinic, rte_hinic_pmd);
914 RTE_PMD_REGISTER_PCI_TABLE(net_hinic, pci_id_hinic_map);
915
916 RTE_INIT(hinic_init_log)
917 {
918         hinic_logtype = rte_log_register("pmd.net.hinic");
919         if (hinic_logtype >= 0)
920                 rte_log_set_level(hinic_logtype, RTE_LOG_INFO);
921 }