1011ebc23SKumar Sanghvi /* SPDX-License-Identifier: BSD-3-Clause
2011ebc23SKumar Sanghvi * Copyright(c) 2018 Chelsio Communications.
3011ebc23SKumar Sanghvi * All rights reserved.
4011ebc23SKumar Sanghvi */
5011ebc23SKumar Sanghvi
6df96fd0dSBruce Richardson #include <ethdev_driver.h>
7df96fd0dSBruce Richardson #include <ethdev_pci.h>
8011ebc23SKumar Sanghvi
9011ebc23SKumar Sanghvi #include "cxgbe.h"
10011ebc23SKumar Sanghvi #include "cxgbe_pfvf.h"
11011ebc23SKumar Sanghvi
12011ebc23SKumar Sanghvi /*
13011ebc23SKumar Sanghvi * Macros needed to support the PCI Device ID Table ...
14011ebc23SKumar Sanghvi */
15011ebc23SKumar Sanghvi #define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \
16011ebc23SKumar Sanghvi static const struct rte_pci_id cxgb4vf_pci_tbl[] = {
17011ebc23SKumar Sanghvi #define CH_PCI_DEVICE_ID_FUNCTION 0x8
18011ebc23SKumar Sanghvi
19011ebc23SKumar Sanghvi #define PCI_VENDOR_ID_CHELSIO 0x1425
20011ebc23SKumar Sanghvi
21011ebc23SKumar Sanghvi #define CH_PCI_ID_TABLE_ENTRY(devid) \
22011ebc23SKumar Sanghvi { RTE_PCI_DEVICE(PCI_VENDOR_ID_CHELSIO, (devid)) }
23011ebc23SKumar Sanghvi
24011ebc23SKumar Sanghvi #define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \
25011ebc23SKumar Sanghvi { .vendor_id = 0, } \
26011ebc23SKumar Sanghvi }
27011ebc23SKumar Sanghvi
28011ebc23SKumar Sanghvi /*
29011ebc23SKumar Sanghvi *... and the PCI ID Table itself ...
30011ebc23SKumar Sanghvi */
3189c8bd95SRahul Lakkireddy #include "base/t4_pci_id_tbl.h"
32011ebc23SKumar Sanghvi
33a0a344a8SKumar Sanghvi /*
34a0a344a8SKumar Sanghvi * Get port statistics.
35a0a344a8SKumar Sanghvi */
cxgbevf_dev_stats_get(struct rte_eth_dev * eth_dev,struct rte_eth_stats * eth_stats)36a0a344a8SKumar Sanghvi static int cxgbevf_dev_stats_get(struct rte_eth_dev *eth_dev,
37a0a344a8SKumar Sanghvi struct rte_eth_stats *eth_stats)
38a0a344a8SKumar Sanghvi {
3963a97e58SStephen Hemminger struct port_info *pi = eth_dev->data->dev_private;
40a0a344a8SKumar Sanghvi struct adapter *adapter = pi->adapter;
41a0a344a8SKumar Sanghvi struct sge *s = &adapter->sge;
42a0a344a8SKumar Sanghvi struct port_stats ps;
43a0a344a8SKumar Sanghvi unsigned int i;
44a0a344a8SKumar Sanghvi
45a0a344a8SKumar Sanghvi cxgbevf_stats_get(pi, &ps);
46a0a344a8SKumar Sanghvi
47a0a344a8SKumar Sanghvi /* RX Stats */
48a0a344a8SKumar Sanghvi eth_stats->ierrors = ps.rx_len_err;
49a0a344a8SKumar Sanghvi
50a0a344a8SKumar Sanghvi /* TX Stats */
51a0a344a8SKumar Sanghvi eth_stats->opackets = ps.tx_bcast_frames + ps.tx_mcast_frames +
52a0a344a8SKumar Sanghvi ps.tx_ucast_frames;
53d67692baSRahul Lakkireddy eth_stats->obytes = ps.tx_octets;
54a0a344a8SKumar Sanghvi eth_stats->oerrors = ps.tx_drop;
55a0a344a8SKumar Sanghvi
56a0a344a8SKumar Sanghvi for (i = 0; i < pi->n_rx_qsets; i++) {
575ec659a7SNikhil Vasoya struct sge_eth_rxq *rxq = &s->ethrxq[pi->first_rxqset + i];
58a0a344a8SKumar Sanghvi
595ec659a7SNikhil Vasoya eth_stats->ipackets += rxq->stats.pkts;
605ec659a7SNikhil Vasoya eth_stats->ibytes += rxq->stats.rx_bytes;
61a0a344a8SKumar Sanghvi }
62a0a344a8SKumar Sanghvi
63a0a344a8SKumar Sanghvi return 0;
64a0a344a8SKumar Sanghvi }
65a0a344a8SKumar Sanghvi
66011ebc23SKumar Sanghvi static const struct eth_dev_ops cxgbevf_eth_dev_ops = {
67011ebc23SKumar Sanghvi .dev_start = cxgbe_dev_start,
68011ebc23SKumar Sanghvi .dev_stop = cxgbe_dev_stop,
69011ebc23SKumar Sanghvi .dev_close = cxgbe_dev_close,
70011ebc23SKumar Sanghvi .promiscuous_enable = cxgbe_dev_promiscuous_enable,
71011ebc23SKumar Sanghvi .promiscuous_disable = cxgbe_dev_promiscuous_disable,
72011ebc23SKumar Sanghvi .allmulticast_enable = cxgbe_dev_allmulticast_enable,
73011ebc23SKumar Sanghvi .allmulticast_disable = cxgbe_dev_allmulticast_disable,
74011ebc23SKumar Sanghvi .dev_configure = cxgbe_dev_configure,
75011ebc23SKumar Sanghvi .dev_infos_get = cxgbe_dev_info_get,
76011ebc23SKumar Sanghvi .dev_supported_ptypes_get = cxgbe_dev_supported_ptypes_get,
77011ebc23SKumar Sanghvi .link_update = cxgbe_dev_link_update,
78265af08eSRahul Lakkireddy .dev_set_link_up = cxgbe_dev_set_link_up,
79265af08eSRahul Lakkireddy .dev_set_link_down = cxgbe_dev_set_link_down,
80011ebc23SKumar Sanghvi .mtu_set = cxgbe_dev_mtu_set,
81011ebc23SKumar Sanghvi .tx_queue_setup = cxgbe_dev_tx_queue_setup,
82011ebc23SKumar Sanghvi .tx_queue_start = cxgbe_dev_tx_queue_start,
83011ebc23SKumar Sanghvi .tx_queue_stop = cxgbe_dev_tx_queue_stop,
84011ebc23SKumar Sanghvi .tx_queue_release = cxgbe_dev_tx_queue_release,
85011ebc23SKumar Sanghvi .rx_queue_setup = cxgbe_dev_rx_queue_setup,
86011ebc23SKumar Sanghvi .rx_queue_start = cxgbe_dev_rx_queue_start,
87011ebc23SKumar Sanghvi .rx_queue_stop = cxgbe_dev_rx_queue_stop,
88011ebc23SKumar Sanghvi .rx_queue_release = cxgbe_dev_rx_queue_release,
89a0a344a8SKumar Sanghvi .stats_get = cxgbevf_dev_stats_get,
905ec659a7SNikhil Vasoya .xstats_get = cxgbe_dev_xstats_get,
915ec659a7SNikhil Vasoya .xstats_get_by_id = cxgbe_dev_xstats_get_by_id,
925ec659a7SNikhil Vasoya .xstats_get_names = cxgbe_dev_xstats_get_names,
935ec659a7SNikhil Vasoya .xstats_get_names_by_id = cxgbe_dev_xstats_get_names_by_id,
940c4a5dfcSKumar Sanghvi .mac_addr_set = cxgbe_mac_addr_set,
95*1cd22be2SNikhil Vasoya .fw_version_get = cxgbe_fw_version_get,
96011ebc23SKumar Sanghvi };
97011ebc23SKumar Sanghvi
98011ebc23SKumar Sanghvi /*
99011ebc23SKumar Sanghvi * Initialize driver
100011ebc23SKumar Sanghvi * It returns 0 on success.
101011ebc23SKumar Sanghvi */
eth_cxgbevf_dev_init(struct rte_eth_dev * eth_dev)102011ebc23SKumar Sanghvi static int eth_cxgbevf_dev_init(struct rte_eth_dev *eth_dev)
103011ebc23SKumar Sanghvi {
10463a97e58SStephen Hemminger struct port_info *pi = eth_dev->data->dev_private;
1055e80364aSKumar Sanghvi struct rte_pci_device *pci_dev;
1065e80364aSKumar Sanghvi char name[RTE_ETH_NAME_MAX_LEN];
1075e80364aSKumar Sanghvi struct adapter *adapter = NULL;
1085e80364aSKumar Sanghvi int err = 0;
1095e80364aSKumar Sanghvi
110011ebc23SKumar Sanghvi CXGBE_FUNC_TRACE();
111011ebc23SKumar Sanghvi
112011ebc23SKumar Sanghvi eth_dev->dev_ops = &cxgbevf_eth_dev_ops;
113880ead4eSKumar Sanghvi eth_dev->rx_pkt_burst = &cxgbe_recv_pkts;
114880ead4eSKumar Sanghvi eth_dev->tx_pkt_burst = &cxgbe_xmit_pkts;
1155e80364aSKumar Sanghvi pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
116011ebc23SKumar Sanghvi
1175e80364aSKumar Sanghvi /* for secondary processes, we attach to ethdevs allocated by primary
1185e80364aSKumar Sanghvi * and do minimal initialization.
1195e80364aSKumar Sanghvi */
1205e80364aSKumar Sanghvi if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1215e80364aSKumar Sanghvi int i;
1225e80364aSKumar Sanghvi
1235e80364aSKumar Sanghvi for (i = 1; i < MAX_NPORTS; i++) {
1245e80364aSKumar Sanghvi struct rte_eth_dev *rest_eth_dev;
1255e80364aSKumar Sanghvi char namei[RTE_ETH_NAME_MAX_LEN];
1265e80364aSKumar Sanghvi
1275e80364aSKumar Sanghvi snprintf(namei, sizeof(namei), "%s_%d",
1285e80364aSKumar Sanghvi pci_dev->device.name, i);
1295e80364aSKumar Sanghvi rest_eth_dev = rte_eth_dev_attach_secondary(namei);
1305e80364aSKumar Sanghvi if (rest_eth_dev) {
1315e80364aSKumar Sanghvi rest_eth_dev->device = &pci_dev->device;
1325e80364aSKumar Sanghvi rest_eth_dev->dev_ops =
1335e80364aSKumar Sanghvi eth_dev->dev_ops;
1345e80364aSKumar Sanghvi rest_eth_dev->rx_pkt_burst =
1355e80364aSKumar Sanghvi eth_dev->rx_pkt_burst;
1365e80364aSKumar Sanghvi rest_eth_dev->tx_pkt_burst =
1375e80364aSKumar Sanghvi eth_dev->tx_pkt_burst;
138fbe90cddSThomas Monjalon rte_eth_dev_probing_finish(rest_eth_dev);
1395e80364aSKumar Sanghvi }
1405e80364aSKumar Sanghvi }
1415e80364aSKumar Sanghvi return 0;
1425e80364aSKumar Sanghvi }
1435e80364aSKumar Sanghvi
1445e80364aSKumar Sanghvi snprintf(name, sizeof(name), "cxgbevfadapter%d",
1455e80364aSKumar Sanghvi eth_dev->data->port_id);
1465e80364aSKumar Sanghvi adapter = rte_zmalloc(name, sizeof(*adapter), 0);
1475e80364aSKumar Sanghvi if (!adapter)
1485e80364aSKumar Sanghvi return -1;
1495e80364aSKumar Sanghvi
1505e80364aSKumar Sanghvi adapter->use_unpacked_mode = 1;
1515e80364aSKumar Sanghvi adapter->regs = (void *)pci_dev->mem_resource[0].addr;
1525e80364aSKumar Sanghvi if (!adapter->regs) {
1535e80364aSKumar Sanghvi dev_err(adapter, "%s: cannot map device registers\n", __func__);
1545e80364aSKumar Sanghvi err = -ENOMEM;
1555e80364aSKumar Sanghvi goto out_free_adapter;
1565e80364aSKumar Sanghvi }
1575e80364aSKumar Sanghvi adapter->pdev = pci_dev;
1585e80364aSKumar Sanghvi adapter->eth_dev = eth_dev;
1595e80364aSKumar Sanghvi pi->adapter = adapter;
160dd7c9f12SRahul Lakkireddy
161dd7c9f12SRahul Lakkireddy cxgbe_process_devargs(adapter);
162dd7c9f12SRahul Lakkireddy
1635e80364aSKumar Sanghvi err = cxgbevf_probe(adapter);
1645e80364aSKumar Sanghvi if (err) {
1655e80364aSKumar Sanghvi dev_err(adapter, "%s: cxgbevf probe failed with err %d\n",
1665e80364aSKumar Sanghvi __func__, err);
1675e80364aSKumar Sanghvi goto out_free_adapter;
1685e80364aSKumar Sanghvi }
1695e80364aSKumar Sanghvi
1705e80364aSKumar Sanghvi return 0;
1715e80364aSKumar Sanghvi
1725e80364aSKumar Sanghvi out_free_adapter:
1735e80364aSKumar Sanghvi rte_free(adapter);
1745e80364aSKumar Sanghvi return err;
175011ebc23SKumar Sanghvi }
176011ebc23SKumar Sanghvi
eth_cxgbevf_dev_uninit(struct rte_eth_dev * eth_dev)177854f4bf0SRahul Lakkireddy static int eth_cxgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
178854f4bf0SRahul Lakkireddy {
17911df4a68SRahul Lakkireddy struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
18011df4a68SRahul Lakkireddy uint16_t port_id;
1818a5a0aadSThomas Monjalon int err = 0;
182854f4bf0SRahul Lakkireddy
183854f4bf0SRahul Lakkireddy /* Free up other ports and all resources */
18411df4a68SRahul Lakkireddy RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device)
1858a5a0aadSThomas Monjalon err |= rte_eth_dev_close(port_id);
18611df4a68SRahul Lakkireddy
1878a5a0aadSThomas Monjalon return err == 0 ? 0 : -EIO;
188854f4bf0SRahul Lakkireddy }
189854f4bf0SRahul Lakkireddy
eth_cxgbevf_pci_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)190011ebc23SKumar Sanghvi static int eth_cxgbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
191011ebc23SKumar Sanghvi struct rte_pci_device *pci_dev)
192011ebc23SKumar Sanghvi {
193011ebc23SKumar Sanghvi return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct port_info),
194011ebc23SKumar Sanghvi eth_cxgbevf_dev_init);
195011ebc23SKumar Sanghvi }
196011ebc23SKumar Sanghvi
eth_cxgbevf_pci_remove(struct rte_pci_device * pci_dev)197011ebc23SKumar Sanghvi static int eth_cxgbevf_pci_remove(struct rte_pci_device *pci_dev)
198011ebc23SKumar Sanghvi {
199854f4bf0SRahul Lakkireddy return rte_eth_dev_pci_generic_remove(pci_dev, eth_cxgbevf_dev_uninit);
200011ebc23SKumar Sanghvi }
201011ebc23SKumar Sanghvi
202011ebc23SKumar Sanghvi static struct rte_pci_driver rte_cxgbevf_pmd = {
203011ebc23SKumar Sanghvi .id_table = cxgb4vf_pci_tbl,
204011ebc23SKumar Sanghvi .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
205011ebc23SKumar Sanghvi .probe = eth_cxgbevf_pci_probe,
206011ebc23SKumar Sanghvi .remove = eth_cxgbevf_pci_remove,
207011ebc23SKumar Sanghvi };
208011ebc23SKumar Sanghvi
209011ebc23SKumar Sanghvi RTE_PMD_REGISTER_PCI(net_cxgbevf, rte_cxgbevf_pmd);
210011ebc23SKumar Sanghvi RTE_PMD_REGISTER_PCI_TABLE(net_cxgbevf, cxgb4vf_pci_tbl);
211011ebc23SKumar Sanghvi RTE_PMD_REGISTER_KMOD_DEP(net_cxgbevf, "* igb_uio | vfio-pci");
212dd7c9f12SRahul Lakkireddy RTE_PMD_REGISTER_PARAM_STRING(net_cxgbevf,
213dd7c9f12SRahul Lakkireddy CXGBE_DEVARG_CMN_KEEP_OVLAN "=<0|1> "
214fa033437SRahul Lakkireddy CXGBE_DEVARG_CMN_TX_MODE_LATENCY "=<0|1> "
215dd7c9f12SRahul Lakkireddy CXGBE_DEVARG_VF_FORCE_LINK_UP "=<0|1> ");
216