New upstream version 17.11.4
[deb_dpdk.git] / drivers / net / bnx2x / bnx2x_ethdev.c
1 /*
2  * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
3  *
4  * Copyright (c) 2015 QLogic Corporation.
5  * All rights reserved.
6  * www.qlogic.com
7  *
8  * See LICENSE.bnx2x_pmd for copyright and licensing details.
9  */
10
11 #include "bnx2x.h"
12 #include "bnx2x_rxtx.h"
13
14 #include <rte_dev.h>
15 #include <rte_ethdev_pci.h>
16 #include <rte_alarm.h>
17 #include <rte_atomic.h>
18
19 /*
20  * The set of PCI devices this driver supports
21  */
22 #define BROADCOM_PCI_VENDOR_ID 0x14E4
23 static const struct rte_pci_id pci_id_bnx2x_map[] = {
24         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57800) },
25         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57711) },
26         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57810) },
27         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57811) },
28         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57840_OBS) },
29         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57840_4_10) },
30         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57840_2_20) },
31 #ifdef RTE_LIBRTE_BNX2X_MF_SUPPORT
32         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57810_MF) },
33         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57811_MF) },
34         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57840_MF) },
35 #endif
36         { .vendor_id = 0, }
37 };
38
39 static const struct rte_pci_id pci_id_bnx2xvf_map[] = {
40         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57800_VF) },
41         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57810_VF) },
42         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57811_VF) },
43         { RTE_PCI_DEVICE(BROADCOM_PCI_VENDOR_ID, CHIP_NUM_57840_VF) },
44         { .vendor_id = 0, }
45 };
46
47 struct rte_bnx2x_xstats_name_off {
48         char name[RTE_ETH_XSTATS_NAME_SIZE];
49         uint32_t offset_hi;
50         uint32_t offset_lo;
51 };
52
53 static const struct rte_bnx2x_xstats_name_off bnx2x_xstats_strings[] = {
54         {"rx_buffer_drops",
55                 offsetof(struct bnx2x_eth_stats, brb_drop_hi),
56                 offsetof(struct bnx2x_eth_stats, brb_drop_lo)},
57         {"rx_buffer_truncates",
58                 offsetof(struct bnx2x_eth_stats, brb_truncate_hi),
59                 offsetof(struct bnx2x_eth_stats, brb_truncate_lo)},
60         {"rx_buffer_truncate_discard",
61                 offsetof(struct bnx2x_eth_stats, brb_truncate_discard),
62                 offsetof(struct bnx2x_eth_stats, brb_truncate_discard)},
63         {"mac_filter_discard",
64                 offsetof(struct bnx2x_eth_stats, mac_filter_discard),
65                 offsetof(struct bnx2x_eth_stats, mac_filter_discard)},
66         {"no_match_vlan_tag_discard",
67                 offsetof(struct bnx2x_eth_stats, mf_tag_discard),
68                 offsetof(struct bnx2x_eth_stats, mf_tag_discard)},
69         {"tx_pause",
70                 offsetof(struct bnx2x_eth_stats, pause_frames_sent_hi),
71                 offsetof(struct bnx2x_eth_stats, pause_frames_sent_lo)},
72         {"rx_pause",
73                 offsetof(struct bnx2x_eth_stats, pause_frames_received_hi),
74                 offsetof(struct bnx2x_eth_stats, pause_frames_received_lo)},
75         {"tx_priority_flow_control",
76                 offsetof(struct bnx2x_eth_stats, pfc_frames_sent_hi),
77                 offsetof(struct bnx2x_eth_stats, pfc_frames_sent_lo)},
78         {"rx_priority_flow_control",
79                 offsetof(struct bnx2x_eth_stats, pfc_frames_received_hi),
80                 offsetof(struct bnx2x_eth_stats, pfc_frames_received_lo)}
81 };
82
83 /**
84  * Atomically reads the link status information from global
85  * structure rte_eth_dev.
86  *
87  * @param dev
88  *   - Pointer to the structure rte_eth_dev to read from.
89  *   - Pointer to the buffer to be saved with the link status.
90  *
91  * @return
92  *   - On success, zero.
93  *   - On failure, negative value.
94  */
95 static inline int
96 bnx2x_dev_atomic_read_link_status(struct rte_eth_dev *dev,
97                                   struct rte_eth_link *link)
98 {
99         struct rte_eth_link *dst = link;
100         struct rte_eth_link *src = &dev->data->dev_link;
101
102         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
103                                         *(uint64_t *)src) == 0)
104                 return -1;
105
106         return 0;
107 }
108
109 /**
110  * Atomically writes the link status information into global
111  * structure rte_eth_dev.
112  *
113  * @param dev
114  *   - Pointer to the structure rte_eth_dev to read from.
115  *   - Pointer to the buffer to be saved with the link status.
116  *
117  * @return
118  *   - On success, zero.
119  *   - On failure, negative value.
120  */
121 static inline int
122 bnx2x_dev_atomic_write_link_status(struct rte_eth_dev *dev,
123                                    struct rte_eth_link *link)
124 {
125         struct rte_eth_link *dst = &dev->data->dev_link;
126         struct rte_eth_link *src = link;
127
128         if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
129                                         *(uint64_t *)src) == 0)
130                 return -1;
131
132         return 0;
133 }
134
135 static int
136 bnx2x_link_update(struct rte_eth_dev *dev)
137 {
138         struct bnx2x_softc *sc = dev->data->dev_private;
139         struct rte_eth_link orig;
140         struct rte_eth_link link;
141
142         PMD_INIT_FUNC_TRACE();
143
144         bnx2x_link_status_update(sc);
145         memset(&orig, 0, sizeof(orig));
146         memset(&link, 0, sizeof(link));
147         bnx2x_dev_atomic_read_link_status(dev, &orig);
148         mb();
149         link.link_speed = sc->link_vars.line_speed;
150         switch (sc->link_vars.duplex) {
151                 case DUPLEX_FULL:
152                         link.link_duplex = ETH_LINK_FULL_DUPLEX;
153                         break;
154                 case DUPLEX_HALF:
155                         link.link_duplex = ETH_LINK_HALF_DUPLEX;
156                         break;
157         }
158         link.link_autoneg = !(dev->data->dev_conf.link_speeds &
159                         ETH_LINK_SPEED_FIXED);
160         link.link_status = sc->link_vars.link_up;
161         bnx2x_dev_atomic_write_link_status(dev, &link);
162
163         return (link.link_status == orig.link_status) ? -1 : 0;
164 }
165
166 static void
167 bnx2x_interrupt_action(struct rte_eth_dev *dev)
168 {
169         struct bnx2x_softc *sc = dev->data->dev_private;
170         uint32_t link_status;
171
172         bnx2x_intr_legacy(sc, 0);
173
174         if (sc->periodic_flags & PERIODIC_GO)
175                 bnx2x_periodic_callout(sc);
176         link_status = REG_RD(sc, sc->link_params.shmem_base +
177                         offsetof(struct shmem_region,
178                                 port_mb[sc->link_params.port].link_status));
179         if ((link_status & LINK_STATUS_LINK_UP) != dev->data->dev_link.link_status)
180                 bnx2x_link_update(dev);
181 }
182
183 static void
184 bnx2x_interrupt_handler(void *param)
185 {
186         struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
187         struct bnx2x_softc *sc = dev->data->dev_private;
188
189         PMD_DEBUG_PERIODIC_LOG(INFO, "Interrupt handled");
190
191         bnx2x_interrupt_action(dev);
192         rte_intr_enable(&sc->pci_dev->intr_handle);
193 }
194
195 static void bnx2x_periodic_start(void *param)
196 {
197         struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
198         struct bnx2x_softc *sc = dev->data->dev_private;
199         int ret = 0;
200
201         atomic_store_rel_long(&sc->periodic_flags, PERIODIC_GO);
202         bnx2x_interrupt_action(dev);
203         if (IS_PF(sc)) {
204                 ret = rte_eal_alarm_set(BNX2X_SP_TIMER_PERIOD,
205                                         bnx2x_periodic_start, (void *)dev);
206                 if (ret) {
207                         PMD_DRV_LOG(ERR, "Unable to start periodic"
208                                          " timer rc %d", ret);
209                         assert(false && "Unable to start periodic timer");
210                 }
211         }
212 }
213
214 void bnx2x_periodic_stop(void *param)
215 {
216         struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
217         struct bnx2x_softc *sc = dev->data->dev_private;
218
219         atomic_store_rel_long(&sc->periodic_flags, PERIODIC_STOP);
220
221         rte_eal_alarm_cancel(bnx2x_periodic_start, (void *)dev);
222 }
223
224 /*
225  * Devops - helper functions can be called from user application
226  */
227
228 static int
229 bnx2x_dev_link_update(struct rte_eth_dev *dev,
230                       __rte_unused int wait_to_complete)
231 {
232         PMD_INIT_FUNC_TRACE();
233
234         return bnx2x_link_update(dev);
235 }
236
237 static int
238 bnx2xvf_dev_link_update(struct rte_eth_dev *dev,
239                         __rte_unused int wait_to_complete)
240 {
241         struct bnx2x_softc *sc = dev->data->dev_private;
242         int ret = 0;
243
244         ret = bnx2x_link_update(dev);
245
246         bnx2x_check_bull(sc);
247         if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
248                 PMD_DRV_LOG(ERR, "PF indicated channel is down."
249                                 "VF device is no longer operational");
250                 dev->data->dev_link.link_status = ETH_LINK_DOWN;
251         }
252
253         return ret;
254 }
255
256 static int
257 bnx2x_dev_configure(struct rte_eth_dev *dev)
258 {
259         struct bnx2x_softc *sc = dev->data->dev_private;
260         int mp_ncpus = sysconf(_SC_NPROCESSORS_CONF);
261
262         PMD_INIT_FUNC_TRACE();
263
264         if (dev->data->dev_conf.rxmode.jumbo_frame)
265                 sc->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len;
266
267         if (dev->data->nb_tx_queues > dev->data->nb_rx_queues) {
268                 PMD_DRV_LOG(ERR, "The number of TX queues is greater than number of RX queues");
269                 return -EINVAL;
270         }
271
272         sc->num_queues = MAX(dev->data->nb_rx_queues, dev->data->nb_tx_queues);
273         if (sc->num_queues > mp_ncpus) {
274                 PMD_DRV_LOG(ERR, "The number of queues is more than number of CPUs");
275                 return -EINVAL;
276         }
277
278         PMD_DRV_LOG(DEBUG, "num_queues=%d, mtu=%d",
279                        sc->num_queues, sc->mtu);
280
281         /* allocate ilt */
282         if (bnx2x_alloc_ilt_mem(sc) != 0) {
283                 PMD_DRV_LOG(ERR, "bnx2x_alloc_ilt_mem was failed");
284                 return -ENXIO;
285         }
286
287         /* allocate the host hardware/software hsi structures */
288         if (bnx2x_alloc_hsi_mem(sc) != 0) {
289                 PMD_DRV_LOG(ERR, "bnx2x_alloc_hsi_mem was failed");
290                 bnx2x_free_ilt_mem(sc);
291                 return -ENXIO;
292         }
293
294         return 0;
295 }
296
297 static int
298 bnx2x_dev_start(struct rte_eth_dev *dev)
299 {
300         struct bnx2x_softc *sc = dev->data->dev_private;
301         int ret = 0;
302
303         PMD_INIT_FUNC_TRACE();
304
305         /* start the periodic callout */
306         if (sc->periodic_flags & PERIODIC_STOP)
307                 bnx2x_periodic_start(dev);
308
309         ret = bnx2x_init(sc);
310         if (ret) {
311                 PMD_DRV_LOG(DEBUG, "bnx2x_init failed (%d)", ret);
312                 return -1;
313         }
314
315         if (IS_PF(sc)) {
316                 rte_intr_callback_register(&sc->pci_dev->intr_handle,
317                                 bnx2x_interrupt_handler, (void *)dev);
318
319                 if (rte_intr_enable(&sc->pci_dev->intr_handle))
320                         PMD_DRV_LOG(ERR, "rte_intr_enable failed");
321         }
322
323         ret = bnx2x_dev_rx_init(dev);
324         if (ret != 0) {
325                 PMD_DRV_LOG(DEBUG, "bnx2x_dev_rx_init returned error code");
326                 return -3;
327         }
328
329         /* Print important adapter info for the user. */
330         bnx2x_print_adapter_info(sc);
331
332         return ret;
333 }
334
335 static void
336 bnx2x_dev_stop(struct rte_eth_dev *dev)
337 {
338         struct bnx2x_softc *sc = dev->data->dev_private;
339         int ret = 0;
340
341         PMD_INIT_FUNC_TRACE();
342
343         if (IS_PF(sc)) {
344                 rte_intr_disable(&sc->pci_dev->intr_handle);
345                 rte_intr_callback_unregister(&sc->pci_dev->intr_handle,
346                                 bnx2x_interrupt_handler, (void *)dev);
347         }
348
349         /* stop the periodic callout */
350         bnx2x_periodic_stop(dev);
351
352         ret = bnx2x_nic_unload(sc, UNLOAD_NORMAL, FALSE);
353         if (ret) {
354                 PMD_DRV_LOG(DEBUG, "bnx2x_nic_unload failed (%d)", ret);
355                 return;
356         }
357
358         /* Update device link status */
359         if (IS_PF(sc))
360                 bnx2x_dev_link_update(dev, 0);
361         else
362                 bnx2xvf_dev_link_update(dev, 0);
363
364         return;
365 }
366
367 static void
368 bnx2x_dev_close(struct rte_eth_dev *dev)
369 {
370         struct bnx2x_softc *sc = dev->data->dev_private;
371
372         PMD_INIT_FUNC_TRACE();
373
374         if (IS_VF(sc))
375                 bnx2x_vf_close(sc);
376
377         bnx2x_dev_clear_queues(dev);
378         memset(&(dev->data->dev_link), 0 , sizeof(struct rte_eth_link));
379
380         /* free the host hardware/software hsi structures */
381         bnx2x_free_hsi_mem(sc);
382
383         /* free ilt */
384         bnx2x_free_ilt_mem(sc);
385 }
386
387 static void
388 bnx2x_promisc_enable(struct rte_eth_dev *dev)
389 {
390         struct bnx2x_softc *sc = dev->data->dev_private;
391
392         PMD_INIT_FUNC_TRACE();
393         sc->rx_mode = BNX2X_RX_MODE_PROMISC;
394         if (rte_eth_allmulticast_get(dev->data->port_id) == 1)
395                 sc->rx_mode = BNX2X_RX_MODE_ALLMULTI_PROMISC;
396         bnx2x_set_rx_mode(sc);
397 }
398
399 static void
400 bnx2x_promisc_disable(struct rte_eth_dev *dev)
401 {
402         struct bnx2x_softc *sc = dev->data->dev_private;
403
404         PMD_INIT_FUNC_TRACE();
405         sc->rx_mode = BNX2X_RX_MODE_NORMAL;
406         if (rte_eth_allmulticast_get(dev->data->port_id) == 1)
407                 sc->rx_mode = BNX2X_RX_MODE_ALLMULTI;
408         bnx2x_set_rx_mode(sc);
409 }
410
411 static void
412 bnx2x_dev_allmulticast_enable(struct rte_eth_dev *dev)
413 {
414         struct bnx2x_softc *sc = dev->data->dev_private;
415
416         PMD_INIT_FUNC_TRACE();
417         sc->rx_mode = BNX2X_RX_MODE_ALLMULTI;
418         if (rte_eth_promiscuous_get(dev->data->port_id) == 1)
419                 sc->rx_mode = BNX2X_RX_MODE_ALLMULTI_PROMISC;
420         bnx2x_set_rx_mode(sc);
421 }
422
423 static void
424 bnx2x_dev_allmulticast_disable(struct rte_eth_dev *dev)
425 {
426         struct bnx2x_softc *sc = dev->data->dev_private;
427
428         PMD_INIT_FUNC_TRACE();
429         sc->rx_mode = BNX2X_RX_MODE_NORMAL;
430         if (rte_eth_promiscuous_get(dev->data->port_id) == 1)
431                 sc->rx_mode = BNX2X_RX_MODE_PROMISC;
432         bnx2x_set_rx_mode(sc);
433 }
434
435 static int
436 bnx2x_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
437 {
438         struct bnx2x_softc *sc = dev->data->dev_private;
439         uint32_t brb_truncate_discard;
440         uint64_t brb_drops;
441         uint64_t brb_truncates;
442
443         PMD_INIT_FUNC_TRACE();
444
445         bnx2x_stats_handle(sc, STATS_EVENT_UPDATE);
446
447         memset(stats, 0, sizeof (struct rte_eth_stats));
448
449         stats->ipackets =
450                 HILO_U64(sc->eth_stats.total_unicast_packets_received_hi,
451                                 sc->eth_stats.total_unicast_packets_received_lo) +
452                 HILO_U64(sc->eth_stats.total_multicast_packets_received_hi,
453                                 sc->eth_stats.total_multicast_packets_received_lo) +
454                 HILO_U64(sc->eth_stats.total_broadcast_packets_received_hi,
455                                 sc->eth_stats.total_broadcast_packets_received_lo);
456
457         stats->opackets =
458                 HILO_U64(sc->eth_stats.total_unicast_packets_transmitted_hi,
459                                 sc->eth_stats.total_unicast_packets_transmitted_lo) +
460                 HILO_U64(sc->eth_stats.total_multicast_packets_transmitted_hi,
461                                 sc->eth_stats.total_multicast_packets_transmitted_lo) +
462                 HILO_U64(sc->eth_stats.total_broadcast_packets_transmitted_hi,
463                                 sc->eth_stats.total_broadcast_packets_transmitted_lo);
464
465         stats->ibytes =
466                 HILO_U64(sc->eth_stats.total_bytes_received_hi,
467                                 sc->eth_stats.total_bytes_received_lo);
468
469         stats->obytes =
470                 HILO_U64(sc->eth_stats.total_bytes_transmitted_hi,
471                                 sc->eth_stats.total_bytes_transmitted_lo);
472
473         stats->ierrors =
474                 HILO_U64(sc->eth_stats.error_bytes_received_hi,
475                                 sc->eth_stats.error_bytes_received_lo);
476
477         stats->oerrors = 0;
478
479         stats->rx_nombuf =
480                 HILO_U64(sc->eth_stats.no_buff_discard_hi,
481                                 sc->eth_stats.no_buff_discard_lo);
482
483         brb_drops =
484                 HILO_U64(sc->eth_stats.brb_drop_hi,
485                          sc->eth_stats.brb_drop_lo);
486
487         brb_truncates =
488                 HILO_U64(sc->eth_stats.brb_truncate_hi,
489                          sc->eth_stats.brb_truncate_lo);
490
491         brb_truncate_discard = sc->eth_stats.brb_truncate_discard;
492
493         stats->imissed = brb_drops + brb_truncates +
494                          brb_truncate_discard + stats->rx_nombuf;
495
496         return 0;
497 }
498
499 static int
500 bnx2x_get_xstats_names(__rte_unused struct rte_eth_dev *dev,
501                        struct rte_eth_xstat_name *xstats_names,
502                        __rte_unused unsigned limit)
503 {
504         unsigned int i, stat_cnt = RTE_DIM(bnx2x_xstats_strings);
505
506         if (xstats_names != NULL)
507                 for (i = 0; i < stat_cnt; i++)
508                         snprintf(xstats_names[i].name,
509                                 sizeof(xstats_names[i].name),
510                                 "%s",
511                                 bnx2x_xstats_strings[i].name);
512
513         return stat_cnt;
514 }
515
516 static int
517 bnx2x_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
518                      unsigned int n)
519 {
520         struct bnx2x_softc *sc = dev->data->dev_private;
521         unsigned int num = RTE_DIM(bnx2x_xstats_strings);
522
523         if (n < num)
524                 return num;
525
526         bnx2x_stats_handle(sc, STATS_EVENT_UPDATE);
527
528         for (num = 0; num < n; num++) {
529                 if (bnx2x_xstats_strings[num].offset_hi !=
530                     bnx2x_xstats_strings[num].offset_lo)
531                         xstats[num].value = HILO_U64(
532                                           *(uint32_t *)((char *)&sc->eth_stats +
533                                           bnx2x_xstats_strings[num].offset_hi),
534                                           *(uint32_t *)((char *)&sc->eth_stats +
535                                           bnx2x_xstats_strings[num].offset_lo));
536                 else
537                         xstats[num].value =
538                                           *(uint64_t *)((char *)&sc->eth_stats +
539                                           bnx2x_xstats_strings[num].offset_lo);
540                 xstats[num].id = num;
541         }
542
543         return num;
544 }
545
546 static void
547 bnx2x_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
548 {
549         struct bnx2x_softc *sc = dev->data->dev_private;
550         dev_info->pci_dev = RTE_ETH_DEV_TO_PCI(dev);
551         dev_info->max_rx_queues  = sc->max_rx_queues;
552         dev_info->max_tx_queues  = sc->max_tx_queues;
553         dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
554         dev_info->max_rx_pktlen  = BNX2X_MAX_RX_PKT_LEN;
555         dev_info->max_mac_addrs  = BNX2X_MAX_MAC_ADDRS;
556         dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
557 }
558
559 static int
560 bnx2x_mac_addr_add(struct rte_eth_dev *dev, struct ether_addr *mac_addr,
561                 uint32_t index, uint32_t pool)
562 {
563         struct bnx2x_softc *sc = dev->data->dev_private;
564
565         if (sc->mac_ops.mac_addr_add) {
566                 sc->mac_ops.mac_addr_add(dev, mac_addr, index, pool);
567                 return 0;
568         }
569         return -ENOTSUP;
570 }
571
572 static void
573 bnx2x_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
574 {
575         struct bnx2x_softc *sc = dev->data->dev_private;
576
577         if (sc->mac_ops.mac_addr_remove)
578                 sc->mac_ops.mac_addr_remove(dev, index);
579 }
580
581 static const struct eth_dev_ops bnx2x_eth_dev_ops = {
582         .dev_configure                = bnx2x_dev_configure,
583         .dev_start                    = bnx2x_dev_start,
584         .dev_stop                     = bnx2x_dev_stop,
585         .dev_close                    = bnx2x_dev_close,
586         .promiscuous_enable           = bnx2x_promisc_enable,
587         .promiscuous_disable          = bnx2x_promisc_disable,
588         .allmulticast_enable          = bnx2x_dev_allmulticast_enable,
589         .allmulticast_disable         = bnx2x_dev_allmulticast_disable,
590         .link_update                  = bnx2x_dev_link_update,
591         .stats_get                    = bnx2x_dev_stats_get,
592         .xstats_get                   = bnx2x_dev_xstats_get,
593         .xstats_get_names             = bnx2x_get_xstats_names,
594         .dev_infos_get                = bnx2x_dev_infos_get,
595         .rx_queue_setup               = bnx2x_dev_rx_queue_setup,
596         .rx_queue_release             = bnx2x_dev_rx_queue_release,
597         .tx_queue_setup               = bnx2x_dev_tx_queue_setup,
598         .tx_queue_release             = bnx2x_dev_tx_queue_release,
599         .mac_addr_add                 = bnx2x_mac_addr_add,
600         .mac_addr_remove              = bnx2x_mac_addr_remove,
601 };
602
603 /*
604  * dev_ops for virtual function
605  */
606 static const struct eth_dev_ops bnx2xvf_eth_dev_ops = {
607         .dev_configure                = bnx2x_dev_configure,
608         .dev_start                    = bnx2x_dev_start,
609         .dev_stop                     = bnx2x_dev_stop,
610         .dev_close                    = bnx2x_dev_close,
611         .promiscuous_enable           = bnx2x_promisc_enable,
612         .promiscuous_disable          = bnx2x_promisc_disable,
613         .allmulticast_enable          = bnx2x_dev_allmulticast_enable,
614         .allmulticast_disable         = bnx2x_dev_allmulticast_disable,
615         .link_update                  = bnx2xvf_dev_link_update,
616         .stats_get                    = bnx2x_dev_stats_get,
617         .xstats_get                   = bnx2x_dev_xstats_get,
618         .xstats_get_names             = bnx2x_get_xstats_names,
619         .dev_infos_get                = bnx2x_dev_infos_get,
620         .rx_queue_setup               = bnx2x_dev_rx_queue_setup,
621         .rx_queue_release             = bnx2x_dev_rx_queue_release,
622         .tx_queue_setup               = bnx2x_dev_tx_queue_setup,
623         .tx_queue_release             = bnx2x_dev_tx_queue_release,
624         .mac_addr_add                 = bnx2x_mac_addr_add,
625         .mac_addr_remove              = bnx2x_mac_addr_remove,
626 };
627
628
629 static int
630 bnx2x_common_dev_init(struct rte_eth_dev *eth_dev, int is_vf)
631 {
632         int ret = 0;
633         struct rte_pci_device *pci_dev;
634         struct bnx2x_softc *sc;
635
636         PMD_INIT_FUNC_TRACE();
637
638         eth_dev->dev_ops = is_vf ? &bnx2xvf_eth_dev_ops : &bnx2x_eth_dev_ops;
639         pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
640
641         rte_eth_copy_pci_info(eth_dev, pci_dev);
642
643         sc = eth_dev->data->dev_private;
644         sc->pcie_bus    = pci_dev->addr.bus;
645         sc->pcie_device = pci_dev->addr.devid;
646
647         if (is_vf)
648                 sc->flags = BNX2X_IS_VF_FLAG;
649
650         sc->devinfo.vendor_id    = pci_dev->id.vendor_id;
651         sc->devinfo.device_id    = pci_dev->id.device_id;
652         sc->devinfo.subvendor_id = pci_dev->id.subsystem_vendor_id;
653         sc->devinfo.subdevice_id = pci_dev->id.subsystem_device_id;
654
655         sc->pcie_func = pci_dev->addr.function;
656         sc->bar[BAR0].base_addr = (void *)pci_dev->mem_resource[0].addr;
657         if (is_vf)
658                 sc->bar[BAR1].base_addr = (void *)
659                         ((uintptr_t)pci_dev->mem_resource[0].addr + PXP_VF_ADDR_DB_START);
660         else
661                 sc->bar[BAR1].base_addr = pci_dev->mem_resource[2].addr;
662
663         assert(sc->bar[BAR0].base_addr);
664         assert(sc->bar[BAR1].base_addr);
665
666         bnx2x_load_firmware(sc);
667         assert(sc->firmware);
668
669         if (eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
670                 sc->udp_rss = 1;
671
672         sc->rx_budget = BNX2X_RX_BUDGET;
673         sc->hc_rx_ticks = BNX2X_RX_TICKS;
674         sc->hc_tx_ticks = BNX2X_TX_TICKS;
675
676         sc->interrupt_mode = INTR_MODE_SINGLE_MSIX;
677         sc->rx_mode = BNX2X_RX_MODE_NORMAL;
678
679         sc->pci_dev = pci_dev;
680         ret = bnx2x_attach(sc);
681         if (ret) {
682                 PMD_DRV_LOG(ERR, "bnx2x_attach failed (%d)", ret);
683                 return ret;
684         }
685
686         /* schedule periodic poll for slowpath link events */
687         if (IS_PF(sc)) {
688                 ret = rte_eal_alarm_set(BNX2X_SP_TIMER_PERIOD,
689                                         bnx2x_periodic_start, (void *)eth_dev);
690                 if (ret) {
691                         PMD_DRV_LOG(ERR, "Unable to start periodic"
692                                           " timer rc %d", ret);
693                         return -EINVAL;
694                 }
695         }
696
697         eth_dev->data->mac_addrs = (struct ether_addr *)sc->link_params.mac_addr;
698
699         PMD_DRV_LOG(INFO, "pcie_bus=%d, pcie_device=%d",
700                         sc->pcie_bus, sc->pcie_device);
701         PMD_DRV_LOG(INFO, "bar0.addr=%p, bar1.addr=%p",
702                         sc->bar[BAR0].base_addr, sc->bar[BAR1].base_addr);
703         PMD_DRV_LOG(INFO, "port=%d, path=%d, vnic=%d, func=%d",
704                         PORT_ID(sc), PATH_ID(sc), VNIC_ID(sc), FUNC_ID(sc));
705         PMD_DRV_LOG(INFO, "portID=%d vendorID=0x%x deviceID=0x%x",
706                         eth_dev->data->port_id, pci_dev->id.vendor_id, pci_dev->id.device_id);
707
708         if (IS_VF(sc)) {
709                 rte_spinlock_init(&sc->vf2pf_lock);
710
711                 ret = bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_mbx_msg),
712                                       &sc->vf2pf_mbox_mapping, "vf2pf_mbox",
713                                       RTE_CACHE_LINE_SIZE);
714                 if (ret)
715                         goto out;
716
717                 sc->vf2pf_mbox = (struct bnx2x_vf_mbx_msg *)
718                                          sc->vf2pf_mbox_mapping.vaddr;
719
720                 ret = bnx2x_dma_alloc(sc, sizeof(struct bnx2x_vf_bulletin),
721                                       &sc->pf2vf_bulletin_mapping, "vf2pf_bull",
722                                       RTE_CACHE_LINE_SIZE);
723                 if (ret)
724                         goto out;
725
726                 sc->pf2vf_bulletin = (struct bnx2x_vf_bulletin *)
727                                              sc->pf2vf_bulletin_mapping.vaddr;
728
729                 ret = bnx2x_vf_get_resources(sc, sc->max_tx_queues,
730                                              sc->max_rx_queues);
731                 if (ret)
732                         goto out;
733         }
734
735         return 0;
736
737 out:
738         bnx2x_periodic_stop(eth_dev);
739         return ret;
740 }
741
742 static int
743 eth_bnx2x_dev_init(struct rte_eth_dev *eth_dev)
744 {
745         PMD_INIT_FUNC_TRACE();
746         return bnx2x_common_dev_init(eth_dev, 0);
747 }
748
749 static int
750 eth_bnx2xvf_dev_init(struct rte_eth_dev *eth_dev)
751 {
752         PMD_INIT_FUNC_TRACE();
753         return bnx2x_common_dev_init(eth_dev, 1);
754 }
755
756 static struct rte_pci_driver rte_bnx2x_pmd;
757 static struct rte_pci_driver rte_bnx2xvf_pmd;
758
759 static int eth_bnx2x_pci_probe(struct rte_pci_driver *pci_drv,
760         struct rte_pci_device *pci_dev)
761 {
762         struct rte_eth_dev *eth_dev;
763         int ret;
764
765         eth_dev = rte_eth_dev_pci_allocate(pci_dev, sizeof(struct bnx2x_softc));
766         if (!eth_dev)
767                 return -ENOMEM;
768
769         if (pci_drv == &rte_bnx2x_pmd)
770                 ret = eth_bnx2x_dev_init(eth_dev);
771         else if (pci_drv == &rte_bnx2xvf_pmd)
772                 ret = eth_bnx2xvf_dev_init(eth_dev);
773         else
774                 ret = -EINVAL;
775
776         if (ret)
777                 rte_eth_dev_pci_release(eth_dev);
778
779         return ret;
780 }
781
782 static int eth_bnx2x_pci_remove(struct rte_pci_device *pci_dev)
783 {
784         return rte_eth_dev_pci_generic_remove(pci_dev, NULL);
785 }
786
787 static struct rte_pci_driver rte_bnx2x_pmd = {
788         .id_table = pci_id_bnx2x_map,
789         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
790         .probe = eth_bnx2x_pci_probe,
791         .remove = eth_bnx2x_pci_remove,
792 };
793
794 /*
795  * virtual function driver struct
796  */
797 static struct rte_pci_driver rte_bnx2xvf_pmd = {
798         .id_table = pci_id_bnx2xvf_map,
799         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
800         .probe = eth_bnx2x_pci_probe,
801         .remove = eth_bnx2x_pci_remove,
802 };
803
804 RTE_PMD_REGISTER_PCI(net_bnx2x, rte_bnx2x_pmd);
805 RTE_PMD_REGISTER_PCI_TABLE(net_bnx2x, pci_id_bnx2x_map);
806 RTE_PMD_REGISTER_KMOD_DEP(net_bnx2x, "* igb_uio | uio_pci_generic | vfio-pci");
807 RTE_PMD_REGISTER_PCI(net_bnx2xvf, rte_bnx2xvf_pmd);
808 RTE_PMD_REGISTER_PCI_TABLE(net_bnx2xvf, pci_id_bnx2xvf_map);
809 RTE_PMD_REGISTER_KMOD_DEP(net_bnx2xvf, "* igb_uio | vfio-pci");