net/txgbe: add PF module init and uninit for SRIOV
[dpdk.git] / drivers / net / txgbe / txgbe_pf.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2020
3  */
4
5 #include <stdio.h>
6 #include <errno.h>
7 #include <stdint.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <stdarg.h>
11 #include <inttypes.h>
12
13 #include <rte_interrupts.h>
14 #include <rte_log.h>
15 #include <rte_debug.h>
16 #include <rte_eal.h>
17 #include <rte_ether.h>
18 #include <rte_ethdev_driver.h>
19 #include <rte_memcpy.h>
20 #include <rte_malloc.h>
21 #include <rte_random.h>
22 #include <rte_bus_pci.h>
23
24 #include "base/txgbe.h"
25 #include "txgbe_ethdev.h"
26
27 static inline uint16_t
28 dev_num_vf(struct rte_eth_dev *eth_dev)
29 {
30         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
31
32         return pci_dev->max_vfs;
33 }
34
35 static inline
36 int txgbe_vf_perm_addr_gen(struct rte_eth_dev *dev, uint16_t vf_num)
37 {
38         unsigned char vf_mac_addr[RTE_ETHER_ADDR_LEN];
39         struct txgbe_vf_info *vfinfo = *TXGBE_DEV_VFDATA(dev);
40         uint16_t vfn;
41
42         for (vfn = 0; vfn < vf_num; vfn++) {
43                 rte_eth_random_addr(vf_mac_addr);
44                 /* keep the random address as default */
45                 memcpy(vfinfo[vfn].vf_mac_addresses, vf_mac_addr,
46                            RTE_ETHER_ADDR_LEN);
47         }
48
49         return 0;
50 }
51
52 static inline int
53 txgbe_mb_intr_setup(struct rte_eth_dev *dev)
54 {
55         struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
56
57         intr->mask_misc |= TXGBE_ICRMISC_VFMBX;
58
59         return 0;
60 }
61
62 void txgbe_pf_host_init(struct rte_eth_dev *eth_dev)
63 {
64         struct txgbe_vf_info **vfinfo = TXGBE_DEV_VFDATA(eth_dev);
65         struct txgbe_mirror_info *mirror_info = TXGBE_DEV_MR_INFO(eth_dev);
66         struct txgbe_uta_info *uta_info = TXGBE_DEV_UTA_INFO(eth_dev);
67         struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
68         uint16_t vf_num;
69         uint8_t nb_queue;
70
71         PMD_INIT_FUNC_TRACE();
72
73         RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
74         vf_num = dev_num_vf(eth_dev);
75         if (vf_num == 0)
76                 return;
77
78         *vfinfo = rte_zmalloc("vf_info",
79                         sizeof(struct txgbe_vf_info) * vf_num, 0);
80         if (*vfinfo == NULL)
81                 rte_panic("Cannot allocate memory for private VF data\n");
82
83         rte_eth_switch_domain_alloc(&(*vfinfo)->switch_domain_id);
84
85         memset(mirror_info, 0, sizeof(struct txgbe_mirror_info));
86         memset(uta_info, 0, sizeof(struct txgbe_uta_info));
87         hw->mac.mc_filter_type = 0;
88
89         if (vf_num >= ETH_32_POOLS) {
90                 nb_queue = 2;
91                 RTE_ETH_DEV_SRIOV(eth_dev).active = ETH_64_POOLS;
92         } else if (vf_num >= ETH_16_POOLS) {
93                 nb_queue = 4;
94                 RTE_ETH_DEV_SRIOV(eth_dev).active = ETH_32_POOLS;
95         } else {
96                 nb_queue = 8;
97                 RTE_ETH_DEV_SRIOV(eth_dev).active = ETH_16_POOLS;
98         }
99
100         RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = nb_queue;
101         RTE_ETH_DEV_SRIOV(eth_dev).def_vmdq_idx = vf_num;
102         RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx =
103                         (uint16_t)(vf_num * nb_queue);
104
105         txgbe_vf_perm_addr_gen(eth_dev, vf_num);
106
107         /* init_mailbox_params */
108         hw->mbx.init_params(hw);
109
110         /* set mb interrupt mask */
111         txgbe_mb_intr_setup(eth_dev);
112 }
113
114 void txgbe_pf_host_uninit(struct rte_eth_dev *eth_dev)
115 {
116         struct txgbe_vf_info **vfinfo;
117         uint16_t vf_num;
118         int ret;
119
120         PMD_INIT_FUNC_TRACE();
121
122         RTE_ETH_DEV_SRIOV(eth_dev).active = 0;
123         RTE_ETH_DEV_SRIOV(eth_dev).nb_q_per_pool = 0;
124         RTE_ETH_DEV_SRIOV(eth_dev).def_vmdq_idx = 0;
125         RTE_ETH_DEV_SRIOV(eth_dev).def_pool_q_idx = 0;
126
127         vf_num = dev_num_vf(eth_dev);
128         if (vf_num == 0)
129                 return;
130
131         vfinfo = TXGBE_DEV_VFDATA(eth_dev);
132         if (*vfinfo == NULL)
133                 return;
134
135         ret = rte_eth_switch_domain_free((*vfinfo)->switch_domain_id);
136         if (ret)
137                 PMD_INIT_LOG(WARNING, "failed to free switch domain: %d", ret);
138
139         rte_free(*vfinfo);
140         *vfinfo = NULL;
141 }
142