drivers: copy PCI device info to ethdev data
[dpdk.git] / drivers / net / bnx2x / bnx2x_ethdev.c
1 /*
2  * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
3  *
4  * All rights reserved.
5  */
6
7 #include "bnx2x.h"
8 #include "bnx2x_rxtx.h"
9
10 #include <rte_dev.h>
11
12 /*
13  * The set of PCI devices this driver supports
14  */
15 static struct rte_pci_id pci_id_bnx2x_map[] = {
16 #define RTE_PCI_DEV_ID_DECL_BNX2X(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
17 #include "rte_pci_dev_ids.h"
18         { .vendor_id = 0, }
19 };
20
21 static struct rte_pci_id pci_id_bnx2xvf_map[] = {
22 #define RTE_PCI_DEV_ID_DECL_BNX2XVF(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
23 #include "rte_pci_dev_ids.h"
24         { .vendor_id = 0, }
25 };
26
27 static void
28 bnx2x_link_update(struct rte_eth_dev *dev)
29 {
30         struct bnx2x_softc *sc = dev->data->dev_private;
31
32         PMD_INIT_FUNC_TRACE();
33         bnx2x_link_status_update(sc);
34         mb();
35         dev->data->dev_link.link_speed = sc->link_vars.line_speed;
36         switch (sc->link_vars.duplex) {
37                 case DUPLEX_FULL:
38                         dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
39                         break;
40                 case DUPLEX_HALF:
41                         dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
42                         break;
43                 default:
44                         dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
45         }
46         dev->data->dev_link.link_status = sc->link_vars.link_up;
47 }
48
49 static void
50 bnx2x_interrupt_action(struct rte_eth_dev *dev)
51 {
52         struct bnx2x_softc *sc = dev->data->dev_private;
53         uint32_t link_status;
54
55         PMD_DRV_LOG(INFO, "Interrupt handled");
56
57         if (bnx2x_intr_legacy(sc, 0))
58                 DELAY_MS(250);
59         if (sc->periodic_flags & PERIODIC_GO)
60                 bnx2x_periodic_callout(sc);
61         link_status = REG_RD(sc, sc->link_params.shmem_base +
62                         offsetof(struct shmem_region,
63                                 port_mb[sc->link_params.port].link_status));
64         if ((link_status & LINK_STATUS_LINK_UP) != dev->data->dev_link.link_status)
65                 bnx2x_link_update(dev);
66 }
67
68 static __rte_unused void
69 bnx2x_interrupt_handler(__rte_unused struct rte_intr_handle *handle, void *param)
70 {
71         struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
72
73         bnx2x_interrupt_action(dev);
74         rte_intr_enable(&(dev->pci_dev->intr_handle));
75 }
76
77 /*
78  * Devops - helper functions can be called from user application
79  */
80
81 static int
82 bnx2x_dev_configure(struct rte_eth_dev *dev)
83 {
84         struct bnx2x_softc *sc = dev->data->dev_private;
85         int mp_ncpus = sysconf(_SC_NPROCESSORS_CONF);
86         int ret;
87
88         PMD_INIT_FUNC_TRACE();
89
90         if (dev->data->dev_conf.rxmode.jumbo_frame)
91                 sc->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len;
92
93         if (dev->data->nb_tx_queues > dev->data->nb_rx_queues) {
94                 PMD_DRV_LOG(ERR, "The number of TX queues is greater than number of RX queues");
95                 return -EINVAL;
96         }
97
98         sc->num_queues = MAX(dev->data->nb_rx_queues, dev->data->nb_tx_queues);
99         if (sc->num_queues > mp_ncpus) {
100                 PMD_DRV_LOG(ERR, "The number of queues is more than number of CPUs");
101                 return -EINVAL;
102         }
103
104         PMD_DRV_LOG(DEBUG, "num_queues=%d, mtu=%d",
105                        sc->num_queues, sc->mtu);
106
107         /* allocate ilt */
108         if (bnx2x_alloc_ilt_mem(sc) != 0) {
109                 PMD_DRV_LOG(ERR, "bnx2x_alloc_ilt_mem was failed");
110                 return -ENXIO;
111         }
112
113         /* allocate the host hardware/software hsi structures */
114         if (bnx2x_alloc_hsi_mem(sc) != 0) {
115                 PMD_DRV_LOG(ERR, "bnx2x_alloc_hsi_mem was failed");
116                 bnx2x_free_ilt_mem(sc);
117                 return -ENXIO;
118         }
119
120         if (IS_VF(sc)) {
121                 if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_mbx_msg),
122                                   &sc->vf2pf_mbox_mapping, "vf2pf_mbox",
123                                   RTE_CACHE_LINE_SIZE) != 0)
124                         return -ENOMEM;
125
126                 sc->vf2pf_mbox = (struct bnx2x_vf_mbx_msg *)sc->vf2pf_mbox_mapping.vaddr;
127                 if (bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_bulletin),
128                                   &sc->pf2vf_bulletin_mapping, "vf2pf_bull",
129                                   RTE_CACHE_LINE_SIZE) != 0)
130                         return -ENOMEM;
131
132                 sc->pf2vf_bulletin = (struct bnx2x_vf_bulletin *)sc->pf2vf_bulletin_mapping.vaddr;
133
134                 ret = bnx2x_vf_get_resources(sc, sc->num_queues, sc->num_queues);
135                 if (ret)
136                         return ret;
137         }
138
139         return 0;
140 }
141
142 static int
143 bnx2x_dev_start(struct rte_eth_dev *dev)
144 {
145         struct bnx2x_softc *sc = dev->data->dev_private;
146         int ret = 0;
147
148         PMD_INIT_FUNC_TRACE();
149
150         ret = bnx2x_init(sc);
151         if (ret) {
152                 PMD_DRV_LOG(DEBUG, "bnx2x_init failed (%d)", ret);
153                 return -1;
154         }
155
156         if (IS_PF(sc)) {
157                 rte_intr_callback_register(&(dev->pci_dev->intr_handle),
158                                 bnx2x_interrupt_handler, (void *)dev);
159
160                 if(rte_intr_enable(&(dev->pci_dev->intr_handle)))
161                         PMD_DRV_LOG(ERR, "rte_intr_enable failed");
162         }
163
164         ret = bnx2x_dev_rx_init(dev);
165         if (ret != 0) {
166                 PMD_DRV_LOG(DEBUG, "bnx2x_dev_rx_init returned error code");
167                 return -3;
168         }
169
170         /* Print important adapter info for the user. */
171         bnx2x_print_adapter_info(sc);
172
173         DELAY_MS(2500);
174
175         return ret;
176 }
177
178 static void
179 bnx2x_dev_stop(struct rte_eth_dev *dev)
180 {
181         struct bnx2x_softc *sc = dev->data->dev_private;
182         int ret = 0;
183
184         PMD_INIT_FUNC_TRACE();
185
186         if (IS_PF(sc)) {
187                 rte_intr_disable(&(dev->pci_dev->intr_handle));
188                 rte_intr_callback_unregister(&(dev->pci_dev->intr_handle),
189                                 bnx2x_interrupt_handler, (void *)dev);
190         }
191
192         ret = bnx2x_nic_unload(sc, UNLOAD_NORMAL, FALSE);
193         if (ret) {
194                 PMD_DRV_LOG(DEBUG, "bnx2x_nic_unload failed (%d)", ret);
195                 return;
196         }
197
198         return;
199 }
200
201 static void
202 bnx2x_dev_close(struct rte_eth_dev *dev)
203 {
204         struct bnx2x_softc *sc = dev->data->dev_private;
205
206         PMD_INIT_FUNC_TRACE();
207
208         if (IS_VF(sc))
209                 bnx2x_vf_close(sc);
210
211         bnx2x_dev_clear_queues(dev);
212         memset(&(dev->data->dev_link), 0 , sizeof(struct rte_eth_link));
213
214         /* free the host hardware/software hsi structures */
215         bnx2x_free_hsi_mem(sc);
216
217         /* free ilt */
218         bnx2x_free_ilt_mem(sc);
219 }
220
221 static void
222 bnx2x_promisc_enable(struct rte_eth_dev *dev)
223 {
224         struct bnx2x_softc *sc = dev->data->dev_private;
225
226         PMD_INIT_FUNC_TRACE();
227         sc->rx_mode = BNX2X_RX_MODE_PROMISC;
228         bnx2x_set_rx_mode(sc);
229 }
230
231 static void
232 bnx2x_promisc_disable(struct rte_eth_dev *dev)
233 {
234         struct bnx2x_softc *sc = dev->data->dev_private;
235
236         PMD_INIT_FUNC_TRACE();
237         sc->rx_mode = BNX2X_RX_MODE_NORMAL;
238         bnx2x_set_rx_mode(sc);
239 }
240
241 static void
242 bnx2x_dev_allmulticast_enable(struct rte_eth_dev *dev)
243 {
244         struct bnx2x_softc *sc = dev->data->dev_private;
245
246         PMD_INIT_FUNC_TRACE();
247         sc->rx_mode = BNX2X_RX_MODE_ALLMULTI;
248         bnx2x_set_rx_mode(sc);
249 }
250
251 static void
252 bnx2x_dev_allmulticast_disable(struct rte_eth_dev *dev)
253 {
254         struct bnx2x_softc *sc = dev->data->dev_private;
255
256         PMD_INIT_FUNC_TRACE();
257         sc->rx_mode = BNX2X_RX_MODE_NORMAL;
258         bnx2x_set_rx_mode(sc);
259 }
260
261 static int
262 bnx2x_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
263 {
264         PMD_INIT_FUNC_TRACE();
265
266         int old_link_status = dev->data->dev_link.link_status;
267
268         bnx2x_link_update(dev);
269
270         return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
271 }
272
273 static int
274 bnx2xvf_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
275 {
276         int old_link_status = dev->data->dev_link.link_status;
277         struct bnx2x_softc *sc = dev->data->dev_private;
278
279         bnx2x_link_update(dev);
280
281         bnx2x_check_bull(sc);
282         if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
283                 PMD_DRV_LOG(ERR, "PF indicated channel is down."
284                                 "VF device is no longer operational");
285                 dev->data->dev_link.link_status = 0;
286         }
287
288         return old_link_status == dev->data->dev_link.link_status ? -1 : 0;
289 }
290
291 static void
292 bnx2x_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
293 {
294         struct bnx2x_softc *sc = dev->data->dev_private;
295
296         PMD_INIT_FUNC_TRACE();
297
298         bnx2x_stats_handle(sc, STATS_EVENT_UPDATE);
299
300         memset(stats, 0, sizeof (struct rte_eth_stats));
301
302         stats->ipackets =
303                 HILO_U64(sc->eth_stats.total_unicast_packets_received_hi,
304                                 sc->eth_stats.total_unicast_packets_received_lo) +
305                 HILO_U64(sc->eth_stats.total_multicast_packets_received_hi,
306                                 sc->eth_stats.total_multicast_packets_received_lo) +
307                 HILO_U64(sc->eth_stats.total_broadcast_packets_received_hi,
308                                 sc->eth_stats.total_broadcast_packets_received_lo);
309
310         stats->opackets =
311                 HILO_U64(sc->eth_stats.total_unicast_packets_transmitted_hi,
312                                 sc->eth_stats.total_unicast_packets_transmitted_lo) +
313                 HILO_U64(sc->eth_stats.total_multicast_packets_transmitted_hi,
314                                 sc->eth_stats.total_multicast_packets_transmitted_lo) +
315                 HILO_U64(sc->eth_stats.total_broadcast_packets_transmitted_hi,
316                                 sc->eth_stats.total_broadcast_packets_transmitted_lo);
317
318         stats->ibytes =
319                 HILO_U64(sc->eth_stats.total_bytes_received_hi,
320                                 sc->eth_stats.total_bytes_received_lo);
321
322         stats->obytes =
323                 HILO_U64(sc->eth_stats.total_bytes_transmitted_hi,
324                                 sc->eth_stats.total_bytes_transmitted_lo);
325
326         stats->ierrors =
327                 HILO_U64(sc->eth_stats.error_bytes_received_hi,
328                                 sc->eth_stats.error_bytes_received_lo);
329
330         stats->oerrors = 0;
331
332         stats->rx_nombuf =
333                 HILO_U64(sc->eth_stats.no_buff_discard_hi,
334                                 sc->eth_stats.no_buff_discard_lo);
335 }
336
337 static void
338 bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_info *dev_info)
339 {
340         struct bnx2x_softc *sc = dev->data->dev_private;
341         dev_info->max_rx_queues  = sc->max_rx_queues;
342         dev_info->max_tx_queues  = sc->max_tx_queues;
343         dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
344         dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
345         dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
346 }
347
348 static void
349 bnx2x_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
350                 uint32_t index, uint32_t pool)
351 {
352         struct bnx2x_softc *sc = dev->data->dev_private;
353
354         if (sc->mac_ops.mac_addr_add)
355                 sc->mac_ops.mac_addr_add(dev, mac_addr, index, pool);
356 }
357
358 static void
359 bnx2x_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
360 {
361         struct bnx2x_softc *sc = dev->data->dev_private;
362
363         if (sc->mac_ops.mac_addr_remove)
364                 sc->mac_ops.mac_addr_remove(dev, index);
365 }
366
367 static struct eth_dev_ops bnx2x_eth_dev_ops = {
368         .dev_configure                = bnx2x_dev_configure,
369         .dev_start                    = bnx2x_dev_start,
370         .dev_stop                     = bnx2x_dev_stop,
371         .dev_close                    = bnx2x_dev_close,
372         .promiscuous_enable           = bnx2x_promisc_enable,
373         .promiscuous_disable          = bnx2x_promisc_disable,
374         .allmulticast_enable          = bnx2x_dev_allmulticast_enable,
375         .allmulticast_disable         = bnx2x_dev_allmulticast_disable,
376         .link_update                  = bnx2x_dev_link_update,
377         .stats_get                    = bnx2x_dev_stats_get,
378         .dev_infos_get                = bnx2x_dev_infos_get,
379         .rx_queue_setup               = bnx2x_dev_rx_queue_setup,
380         .rx_queue_release             = bnx2x_dev_rx_queue_release,
381         .tx_queue_setup               = bnx2x_dev_tx_queue_setup,
382         .tx_queue_release             = bnx2x_dev_tx_queue_release,
383         .mac_addr_add                 = bnx2x_mac_addr_add,
384         .mac_addr_remove              = bnx2x_mac_addr_remove,
385 };
386
387 /*
388  * dev_ops for virtual function
389  */
390 static struct eth_dev_ops bnx2xvf_eth_dev_ops = {
391         .dev_configure                = bnx2x_dev_configure,
392         .dev_start                    = bnx2x_dev_start,
393         .dev_stop                     = bnx2x_dev_stop,
394         .dev_close                    = bnx2x_dev_close,
395         .promiscuous_enable           = bnx2x_promisc_enable,
396         .promiscuous_disable          = bnx2x_promisc_disable,
397         .allmulticast_enable          = bnx2x_dev_allmulticast_enable,
398         .allmulticast_disable         = bnx2x_dev_allmulticast_disable,
399         .link_update                  = bnx2xvf_dev_link_update,
400         .stats_get                    = bnx2x_dev_stats_get,
401         .dev_infos_get                = bnx2x_dev_infos_get,
402         .rx_queue_setup               = bnx2x_dev_rx_queue_setup,
403         .rx_queue_release             = bnx2x_dev_rx_queue_release,
404         .tx_queue_setup               = bnx2x_dev_tx_queue_setup,
405         .tx_queue_release             = bnx2x_dev_tx_queue_release,
406         .mac_addr_add                 = bnx2x_mac_addr_add,
407         .mac_addr_remove              = bnx2x_mac_addr_remove,
408 };
409
410
411 static int
412 bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
413 {
414         int ret = 0;
415         struct rte_pci_device *pci_dev;
416         struct bnx2x_softc *sc;
417
418         PMD_INIT_FUNC_TRACE();
419
420         eth_dev->dev_ops = is_vf ? &bnx2xvf_eth_dev_ops : &bnx2x_eth_dev_ops;
421         pci_dev = eth_dev->pci_dev;
422
423         rte_eth_copy_pci_info(eth_dev, pci_dev);
424
425         sc = eth_dev->data->dev_private;
426         sc->pcie_bus    = pci_dev->addr.bus;
427         sc->pcie_device = pci_dev->addr.devid;
428
429         if (is_vf)
430                 sc->flags = BNX2X_IS_VF_FLAG;
431
432         sc->devinfo.vendor_id    = pci_dev->id.vendor_id;
433         sc->devinfo.device_id    = pci_dev->id.device_id;
434         sc->devinfo.subvendor_id = pci_dev->id.subsystem_vendor_id;
435         sc->devinfo.subdevice_id = pci_dev->id.subsystem_device_id;
436
437         sc->pcie_func = pci_dev->addr.function;
438         sc->bar[BAR0].base_addr = (void *)pci_dev->mem_resource[0].addr;
439         if (is_vf)
440                 sc->bar[BAR1].base_addr = (void *)
441                         ((uint64_t)pci_dev->mem_resource[0].addr + PXP_VF_ADDR_DB_START);
442         else
443                 sc->bar[BAR1].base_addr = pci_dev->mem_resource[2].addr;
444
445         assert(sc->bar[BAR0].base_addr);
446         assert(sc->bar[BAR1].base_addr);
447
448         bnx2x_load_firmware(sc);
449         assert(sc->firmware);
450
451         if (eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
452                 sc->udp_rss = 1;
453
454         sc->rx_budget = BNX2X_RX_BUDGET;
455         sc->hc_rx_ticks = BNX2X_RX_TICKS;
456         sc->hc_tx_ticks = BNX2X_TX_TICKS;
457
458         sc->interrupt_mode = INTR_MODE_SINGLE_MSIX;
459         sc->rx_mode = BNX2X_RX_MODE_NORMAL;
460
461         sc->pci_dev = pci_dev;
462         ret = bnx2x_attach(sc);
463         if (ret) {
464                 PMD_DRV_LOG(ERR, "bnx2x_attach failed (%d)", ret);
465         }
466
467         eth_dev->data->mac_addrs = (struct ether_addr *)sc->link_params.mac_addr;
468
469         PMD_DRV_LOG(INFO, "pcie_bus=%d, pcie_device=%d",
470                         sc->pcie_bus, sc->pcie_device);
471         PMD_DRV_LOG(INFO, "bar0.addr=%p, bar1.addr=%p",
472                         sc->bar[BAR0].base_addr, sc->bar[BAR1].base_addr);
473         PMD_DRV_LOG(INFO, "port=%d, path=%d, vnic=%d, func=%d",
474                         PORT_ID(sc), PATH_ID(sc), VNIC_ID(sc), FUNC_ID(sc));
475         PMD_DRV_LOG(INFO, "portID=%d vendorID=0x%x deviceID=0x%x",
476                         eth_dev->data->port_id, pci_dev->id.vendor_id, pci_dev->id.device_id);
477
478         return ret;
479 }
480
481 static int
482 eth_bnx2x_dev_init(struct rte_eth_dev *eth_dev)
483 {
484         PMD_INIT_FUNC_TRACE();
485         return bnx2x_common_dev_init(eth_dev, 0);
486 }
487
488 static int
489 eth_bnx2xvf_dev_init(struct rte_eth_dev *eth_dev)
490 {
491         PMD_INIT_FUNC_TRACE();
492         return bnx2x_common_dev_init(eth_dev, 1);
493 }
494
495 static struct eth_driver rte_bnx2x_pmd = {
496         .pci_drv = {
497                 .name = "rte_bnx2x_pmd",
498                 .id_table = pci_id_bnx2x_map,
499                 .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
500         },
501         .eth_dev_init = eth_bnx2x_dev_init,
502         .dev_private_size = sizeof(struct bnx2x_softc),
503 };
504
505 /*
506  * virtual function driver struct
507  */
508 static struct eth_driver rte_bnx2xvf_pmd = {
509         .pci_drv = {
510                 .name = "rte_bnx2xvf_pmd",
511                 .id_table = pci_id_bnx2xvf_map,
512                 .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
513         },
514         .eth_dev_init = eth_bnx2xvf_dev_init,
515         .dev_private_size = sizeof(struct bnx2x_softc),
516 };
517
518 static int rte_bnx2x_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
519 {
520         PMD_INIT_FUNC_TRACE();
521         rte_eth_driver_register(&rte_bnx2x_pmd);
522
523         return 0;
524 }
525
526 static int rte_bnx2xvf_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
527 {
528         PMD_INIT_FUNC_TRACE();
529         rte_eth_driver_register(&rte_bnx2xvf_pmd);
530
531         return 0;
532 }
533
534 static struct rte_driver rte_bnx2x_driver = {
535         .type = PMD_PDEV,
536         .init = rte_bnx2x_pmd_init,
537 };
538
539 static struct rte_driver rte_bnx2xvf_driver = {
540         .type = PMD_PDEV,
541         .init = rte_bnx2xvf_pmd_init,
542 };
543
544 PMD_REGISTER_DRIVER(rte_bnx2x_driver);
545 PMD_REGISTER_DRIVER(rte_bnx2xvf_driver);