bc2d8868ed9d1b8b7e448a6c2dfbdf5b49e7d085
[dpdk.git] / drivers / net / enic / enic_vf_representor.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2008-2019 Cisco Systems, Inc.  All rights reserved.
3  */
4
5 #include <stdint.h>
6 #include <stdio.h>
7
8 #include <rte_bus_pci.h>
9 #include <rte_common.h>
10 #include <rte_dev.h>
11 #include <rte_ethdev_driver.h>
12 #include <rte_ethdev_pci.h>
13 #include <rte_flow_driver.h>
14 #include <rte_kvargs.h>
15 #include <rte_pci.h>
16 #include <rte_string_fns.h>
17
18 #include "enic_compat.h"
19 #include "enic.h"
20 #include "vnic_dev.h"
21 #include "vnic_enet.h"
22 #include "vnic_intr.h"
23 #include "vnic_cq.h"
24 #include "vnic_wq.h"
25 #include "vnic_rq.h"
26
27 static uint16_t enic_vf_recv_pkts(void *rx_queue __rte_unused,
28                                   struct rte_mbuf **rx_pkts __rte_unused,
29                                   uint16_t nb_pkts __rte_unused)
30 {
31         return 0;
32 }
33
34 static uint16_t enic_vf_xmit_pkts(void *tx_queue __rte_unused,
35                                   struct rte_mbuf **tx_pkts __rte_unused,
36                                   uint16_t nb_pkts __rte_unused)
37 {
38         return 0;
39 }
40
41 static int enic_vf_dev_tx_queue_setup(struct rte_eth_dev *eth_dev __rte_unused,
42         uint16_t queue_idx __rte_unused,
43         uint16_t nb_desc __rte_unused,
44         unsigned int socket_id __rte_unused,
45         const struct rte_eth_txconf *tx_conf __rte_unused)
46 {
47         ENICPMD_FUNC_TRACE();
48         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
49                 return -E_RTE_SECONDARY;
50         return 0;
51 }
52
53 static void enic_vf_dev_tx_queue_release(void *txq __rte_unused)
54 {
55         ENICPMD_FUNC_TRACE();
56         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
57                 return;
58 }
59
60 static int enic_vf_dev_rx_queue_setup(struct rte_eth_dev *eth_dev __rte_unused,
61         uint16_t queue_idx __rte_unused,
62         uint16_t nb_desc __rte_unused,
63         unsigned int socket_id __rte_unused,
64         const struct rte_eth_rxconf *rx_conf __rte_unused,
65         struct rte_mempool *mp __rte_unused)
66 {
67         ENICPMD_FUNC_TRACE();
68         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
69                 return -E_RTE_SECONDARY;
70         return 0;
71 }
72
73 static void enic_vf_dev_rx_queue_release(void *rxq __rte_unused)
74 {
75         ENICPMD_FUNC_TRACE();
76         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
77                 return;
78 }
79
80 static int enic_vf_dev_configure(struct rte_eth_dev *eth_dev __rte_unused)
81 {
82         ENICPMD_FUNC_TRACE();
83         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
84                 return -E_RTE_SECONDARY;
85         return 0;
86 }
87
88 static int enic_vf_dev_start(struct rte_eth_dev *eth_dev)
89 {
90         struct enic_vf_representor *vf;
91         int ret;
92
93         ENICPMD_FUNC_TRACE();
94         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
95                 return -E_RTE_SECONDARY;
96
97         vf = eth_dev->data->dev_private;
98         /* Remove all packet filters so no ingress packets go to VF.
99          * When PF enables switchdev, it will ensure packet filters
100          * are removed.  So, this is not technically needed.
101          */
102         ENICPMD_LOG(DEBUG, "Clear packet filters");
103         ret = vnic_dev_packet_filter(vf->enic.vdev, 0, 0, 0, 0, 0);
104         if (ret) {
105                 ENICPMD_LOG(ERR, "Cannot clear packet filters");
106                 return ret;
107         }
108         return 0;
109 }
110
111 static void enic_vf_dev_stop(struct rte_eth_dev *eth_dev __rte_unused)
112 {
113         ENICPMD_FUNC_TRACE();
114         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
115                 return;
116 }
117
118 /*
119  * "close" is no-op for now and solely exists so that rte_eth_dev_close()
120  * can finish its own cleanup without errors.
121  */
122 static void enic_vf_dev_close(struct rte_eth_dev *eth_dev __rte_unused)
123 {
124         ENICPMD_FUNC_TRACE();
125         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
126                 return;
127 }
128
129 static int enic_vf_link_update(struct rte_eth_dev *eth_dev,
130         int wait_to_complete __rte_unused)
131 {
132         struct enic_vf_representor *vf;
133         struct rte_eth_link link;
134         struct enic *pf;
135
136         ENICPMD_FUNC_TRACE();
137         vf = eth_dev->data->dev_private;
138         pf = vf->pf;
139         /*
140          * Link status and speed are same as PF. Update PF status and then
141          * copy it to VF.
142          */
143         enic_link_update(pf->rte_dev);
144         rte_eth_linkstatus_get(pf->rte_dev, &link);
145         rte_eth_linkstatus_set(eth_dev, &link);
146         return 0;
147 }
148
149 static int enic_vf_stats_get(struct rte_eth_dev *eth_dev,
150         struct rte_eth_stats *stats)
151 {
152         struct enic_vf_representor *vf;
153         struct vnic_stats *vs;
154         int err;
155
156         ENICPMD_FUNC_TRACE();
157         vf = eth_dev->data->dev_private;
158         /* Get VF stats via PF */
159         err = vnic_dev_stats_dump(vf->enic.vdev, &vs);
160         if (err) {
161                 ENICPMD_LOG(ERR, "error in getting stats\n");
162                 return err;
163         }
164         stats->ipackets = vs->rx.rx_frames_ok;
165         stats->opackets = vs->tx.tx_frames_ok;
166         stats->ibytes = vs->rx.rx_bytes_ok;
167         stats->obytes = vs->tx.tx_bytes_ok;
168         stats->ierrors = vs->rx.rx_errors + vs->rx.rx_drop;
169         stats->oerrors = vs->tx.tx_errors;
170         stats->imissed = vs->rx.rx_no_bufs;
171         return 0;
172 }
173
174 static int enic_vf_stats_reset(struct rte_eth_dev *eth_dev)
175 {
176         struct enic_vf_representor *vf;
177         int err;
178
179         ENICPMD_FUNC_TRACE();
180         vf = eth_dev->data->dev_private;
181         /* Ask PF to clear VF stats */
182         err = vnic_dev_stats_clear(vf->enic.vdev);
183         if (err)
184                 ENICPMD_LOG(ERR, "error in clearing stats\n");
185         return err;
186 }
187
188 static int enic_vf_dev_infos_get(struct rte_eth_dev *eth_dev,
189         struct rte_eth_dev_info *device_info)
190 {
191         struct enic_vf_representor *vf;
192         struct enic *pf;
193
194         ENICPMD_FUNC_TRACE();
195         vf = eth_dev->data->dev_private;
196         pf = vf->pf;
197         device_info->max_rx_queues = eth_dev->data->nb_rx_queues;
198         device_info->max_tx_queues = eth_dev->data->nb_tx_queues;
199         device_info->min_rx_bufsize = ENIC_MIN_MTU;
200         /* Max packet size is same as PF */
201         device_info->max_rx_pktlen = enic_mtu_to_max_rx_pktlen(pf->max_mtu);
202         device_info->max_mac_addrs = ENIC_UNICAST_PERFECT_FILTERS;
203         /* No offload capa, RSS, etc. until Tx/Rx handlers are added */
204         device_info->rx_offload_capa = 0;
205         device_info->tx_offload_capa = 0;
206         device_info->switch_info.name = pf->rte_dev->device->name;
207         device_info->switch_info.domain_id = vf->switch_domain_id;
208         device_info->switch_info.port_id = vf->vf_id;
209         return 0;
210 }
211
212 static void set_vf_packet_filter(struct enic_vf_representor *vf)
213 {
214         /* switchdev: packet filters are ignored */
215         if (vf->enic.switchdev_mode)
216                 return;
217         /* Ask PF to apply filters on VF */
218         vnic_dev_packet_filter(vf->enic.vdev, 1 /* unicast */, 1 /* mcast */,
219                 1 /* bcast */, vf->promisc, vf->allmulti);
220 }
221
222 static int enic_vf_promiscuous_enable(struct rte_eth_dev *eth_dev)
223 {
224         struct enic_vf_representor *vf;
225
226         ENICPMD_FUNC_TRACE();
227         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
228                 return -E_RTE_SECONDARY;
229         vf = eth_dev->data->dev_private;
230         vf->promisc = 1;
231         set_vf_packet_filter(vf);
232         return 0;
233 }
234
235 static int enic_vf_promiscuous_disable(struct rte_eth_dev *eth_dev)
236 {
237         struct enic_vf_representor *vf;
238
239         ENICPMD_FUNC_TRACE();
240         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
241                 return -E_RTE_SECONDARY;
242         vf = eth_dev->data->dev_private;
243         vf->promisc = 0;
244         set_vf_packet_filter(vf);
245         return 0;
246 }
247
248 static int enic_vf_allmulticast_enable(struct rte_eth_dev *eth_dev)
249 {
250         struct enic_vf_representor *vf;
251
252         ENICPMD_FUNC_TRACE();
253         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
254                 return -E_RTE_SECONDARY;
255         vf = eth_dev->data->dev_private;
256         vf->allmulti = 1;
257         set_vf_packet_filter(vf);
258         return 0;
259 }
260
261 static int enic_vf_allmulticast_disable(struct rte_eth_dev *eth_dev)
262 {
263         struct enic_vf_representor *vf;
264
265         ENICPMD_FUNC_TRACE();
266         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
267                 return -E_RTE_SECONDARY;
268         vf = eth_dev->data->dev_private;
269         vf->allmulti = 0;
270         set_vf_packet_filter(vf);
271         return 0;
272 }
273
274 /*
275  * A minimal set of handlers.
276  * The representor can get/set a small set of VF settings via "proxy" devcmd.
277  * With proxy devcmd, the PF driver basically tells the VIC firmware to
278  * "perform this devcmd on that VF".
279  */
280 static const struct eth_dev_ops enic_vf_representor_dev_ops = {
281         .allmulticast_enable  = enic_vf_allmulticast_enable,
282         .allmulticast_disable = enic_vf_allmulticast_disable,
283         .dev_configure        = enic_vf_dev_configure,
284         .dev_infos_get        = enic_vf_dev_infos_get,
285         .dev_start            = enic_vf_dev_start,
286         .dev_stop             = enic_vf_dev_stop,
287         .dev_close            = enic_vf_dev_close,
288         .link_update          = enic_vf_link_update,
289         .promiscuous_enable   = enic_vf_promiscuous_enable,
290         .promiscuous_disable  = enic_vf_promiscuous_disable,
291         .stats_get            = enic_vf_stats_get,
292         .stats_reset          = enic_vf_stats_reset,
293         .rx_queue_setup       = enic_vf_dev_rx_queue_setup,
294         .rx_queue_release     = enic_vf_dev_rx_queue_release,
295         .tx_queue_setup       = enic_vf_dev_tx_queue_setup,
296         .tx_queue_release     = enic_vf_dev_tx_queue_release,
297 };
298
299 static int get_vf_config(struct enic_vf_representor *vf)
300 {
301         struct vnic_enet_config *c;
302         struct enic *pf;
303         int switch_mtu;
304         int err;
305
306         c = &vf->config;
307         pf = vf->pf;
308         /* VF MAC */
309         err = vnic_dev_get_mac_addr(vf->enic.vdev, vf->mac_addr.addr_bytes);
310         if (err) {
311                 ENICPMD_LOG(ERR, "error in getting MAC address\n");
312                 return err;
313         }
314         rte_ether_addr_copy(&vf->mac_addr, vf->eth_dev->data->mac_addrs);
315
316         /* VF MTU per its vNIC setting */
317         err = vnic_dev_spec(vf->enic.vdev,
318                             offsetof(struct vnic_enet_config, mtu),
319                             sizeof(c->mtu), &c->mtu);
320         if (err) {
321                 ENICPMD_LOG(ERR, "error in getting MTU\n");
322                 return err;
323         }
324         /*
325          * Blade switch (fabric interconnect) port's MTU. Assume the kernel
326          * enic driver runs on VF. That driver automatically adjusts its MTU
327          * according to the switch MTU.
328          */
329         switch_mtu = vnic_dev_mtu(pf->vdev);
330         vf->eth_dev->data->mtu = c->mtu;
331         if (switch_mtu > c->mtu)
332                 vf->eth_dev->data->mtu = RTE_MIN(ENIC_MAX_MTU, switch_mtu);
333         return 0;
334 }
335
336 int enic_vf_representor_init(struct rte_eth_dev *eth_dev, void *init_params)
337 {
338         struct enic_vf_representor *vf, *params;
339         struct rte_pci_device *pdev;
340         struct enic *pf, *vf_enic;
341         struct rte_pci_addr *addr;
342         int ret;
343
344         ENICPMD_FUNC_TRACE();
345         params = init_params;
346         vf = eth_dev->data->dev_private;
347         vf->switch_domain_id = params->switch_domain_id;
348         vf->vf_id = params->vf_id;
349         vf->eth_dev = eth_dev;
350         vf->pf = params->pf;
351         vf->allmulti = 1;
352         vf->promisc = 0;
353         pf = vf->pf;
354         vf->enic.switchdev_mode = pf->switchdev_mode;
355         /* Only switchdev is supported now */
356         RTE_ASSERT(vf->enic.switchdev_mode);
357
358         /* Check for non-existent VFs */
359         pdev = RTE_ETH_DEV_TO_PCI(pf->rte_dev);
360         if (vf->vf_id >= pdev->max_vfs) {
361                 ENICPMD_LOG(ERR, "VF ID is invalid. vf_id %u max_vfs %u",
362                             vf->vf_id, pdev->max_vfs);
363                 return -ENODEV;
364         }
365
366         eth_dev->device->driver = pf->rte_dev->device->driver;
367         eth_dev->dev_ops = &enic_vf_representor_dev_ops;
368         eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR
369                 | RTE_ETH_DEV_CLOSE_REMOVE;
370         eth_dev->data->representor_id = vf->vf_id;
371         eth_dev->data->mac_addrs = rte_zmalloc("enic_mac_addr_vf",
372                 sizeof(struct rte_ether_addr) *
373                 ENIC_UNICAST_PERFECT_FILTERS, 0);
374         if (eth_dev->data->mac_addrs == NULL)
375                 return -ENOMEM;
376         /* Use 1 RX queue and 1 TX queue for representor path */
377         eth_dev->data->nb_rx_queues = 1;
378         eth_dev->data->nb_tx_queues = 1;
379         eth_dev->rx_pkt_burst = &enic_vf_recv_pkts;
380         eth_dev->tx_pkt_burst = &enic_vf_xmit_pkts;
381         /* Initial link state copied from PF */
382         eth_dev->data->dev_link = pf->rte_dev->data->dev_link;
383         /* Representor vdev to perform devcmd */
384         vf->enic.vdev = vnic_vf_rep_register(&vf->enic, pf->vdev, vf->vf_id);
385         if (vf->enic.vdev == NULL)
386                 return -ENOMEM;
387         ret = vnic_dev_alloc_stats_mem(vf->enic.vdev);
388         if (ret)
389                 return ret;
390         /* Get/copy VF vNIC MAC, MTU, etc. into eth_dev */
391         ret = get_vf_config(vf);
392         if (ret)
393                 return ret;
394
395         /*
396          * Calculate VF BDF. The firmware ensures that PF BDF is always
397          * bus:dev.0, and VF BDFs are dev.1, dev.2, and so on.
398          */
399         vf->bdf = pdev->addr;
400         vf->bdf.function += vf->vf_id + 1;
401
402         /* Copy a few fields used by enic_fm_flow */
403         vf_enic = &vf->enic;
404         vf_enic->switch_domain_id = vf->switch_domain_id;
405         vf_enic->flow_filter_mode = pf->flow_filter_mode;
406         vf_enic->rte_dev = eth_dev;
407         vf_enic->dev_data = eth_dev->data;
408         LIST_INIT(&vf_enic->flows);
409         LIST_INIT(&vf_enic->memzone_list);
410         rte_spinlock_init(&vf_enic->memzone_list_lock);
411         addr = &vf->bdf;
412         snprintf(vf_enic->bdf_name, ENICPMD_BDF_LENGTH, "%04x:%02x:%02x.%x",
413                  addr->domain, addr->bus, addr->devid, addr->function);
414         return 0;
415 }
416
417 int enic_vf_representor_uninit(struct rte_eth_dev *eth_dev)
418 {
419         struct enic_vf_representor *vf;
420
421         ENICPMD_FUNC_TRACE();
422         vf = eth_dev->data->dev_private;
423         vnic_dev_unregister(vf->enic.vdev);
424         return 0;
425 }