xref: /dpdk/drivers/net/cxgbe/cxgbevf_ethdev.c (revision dd7c9f12762e69eb4fdce16c1b01547a67a8ab2c)
1011ebc23SKumar Sanghvi /* SPDX-License-Identifier: BSD-3-Clause
2011ebc23SKumar Sanghvi  * Copyright(c) 2018 Chelsio Communications.
3011ebc23SKumar Sanghvi  * All rights reserved.
4011ebc23SKumar Sanghvi  */
5011ebc23SKumar Sanghvi 
6011ebc23SKumar Sanghvi #include <rte_ethdev_driver.h>
7011ebc23SKumar Sanghvi #include <rte_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  */
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++) {
57a0a344a8SKumar Sanghvi 		struct sge_eth_rxq *rxq =
58a0a344a8SKumar Sanghvi 			&s->ethrxq[pi->first_qset + i];
59a0a344a8SKumar Sanghvi 
60a0a344a8SKumar Sanghvi 		eth_stats->q_ipackets[i] = rxq->stats.pkts;
61a0a344a8SKumar Sanghvi 		eth_stats->q_ibytes[i] = rxq->stats.rx_bytes;
62a0a344a8SKumar Sanghvi 		eth_stats->ipackets += eth_stats->q_ipackets[i];
63a0a344a8SKumar Sanghvi 		eth_stats->ibytes += eth_stats->q_ibytes[i];
64a0a344a8SKumar Sanghvi 	}
65a0a344a8SKumar Sanghvi 
66a0a344a8SKumar Sanghvi 	for (i = 0; i < pi->n_tx_qsets; i++) {
67a0a344a8SKumar Sanghvi 		struct sge_eth_txq *txq =
68a0a344a8SKumar Sanghvi 			&s->ethtxq[pi->first_qset + i];
69a0a344a8SKumar Sanghvi 
70a0a344a8SKumar Sanghvi 		eth_stats->q_opackets[i] = txq->stats.pkts;
71a0a344a8SKumar Sanghvi 		eth_stats->q_obytes[i] = txq->stats.tx_bytes;
72a0a344a8SKumar Sanghvi 	}
73a0a344a8SKumar Sanghvi 	return 0;
74a0a344a8SKumar Sanghvi }
75a0a344a8SKumar Sanghvi 
76011ebc23SKumar Sanghvi static const struct eth_dev_ops cxgbevf_eth_dev_ops = {
77011ebc23SKumar Sanghvi 	.dev_start              = cxgbe_dev_start,
78011ebc23SKumar Sanghvi 	.dev_stop               = cxgbe_dev_stop,
79011ebc23SKumar Sanghvi 	.dev_close              = cxgbe_dev_close,
80011ebc23SKumar Sanghvi 	.promiscuous_enable     = cxgbe_dev_promiscuous_enable,
81011ebc23SKumar Sanghvi 	.promiscuous_disable    = cxgbe_dev_promiscuous_disable,
82011ebc23SKumar Sanghvi 	.allmulticast_enable    = cxgbe_dev_allmulticast_enable,
83011ebc23SKumar Sanghvi 	.allmulticast_disable   = cxgbe_dev_allmulticast_disable,
84011ebc23SKumar Sanghvi 	.dev_configure          = cxgbe_dev_configure,
85011ebc23SKumar Sanghvi 	.dev_infos_get          = cxgbe_dev_info_get,
86011ebc23SKumar Sanghvi 	.dev_supported_ptypes_get = cxgbe_dev_supported_ptypes_get,
87011ebc23SKumar Sanghvi 	.link_update            = cxgbe_dev_link_update,
88265af08eSRahul Lakkireddy 	.dev_set_link_up        = cxgbe_dev_set_link_up,
89265af08eSRahul Lakkireddy 	.dev_set_link_down      = cxgbe_dev_set_link_down,
90011ebc23SKumar Sanghvi 	.mtu_set                = cxgbe_dev_mtu_set,
91011ebc23SKumar Sanghvi 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
92011ebc23SKumar Sanghvi 	.tx_queue_start         = cxgbe_dev_tx_queue_start,
93011ebc23SKumar Sanghvi 	.tx_queue_stop          = cxgbe_dev_tx_queue_stop,
94011ebc23SKumar Sanghvi 	.tx_queue_release       = cxgbe_dev_tx_queue_release,
95011ebc23SKumar Sanghvi 	.rx_queue_setup         = cxgbe_dev_rx_queue_setup,
96011ebc23SKumar Sanghvi 	.rx_queue_start         = cxgbe_dev_rx_queue_start,
97011ebc23SKumar Sanghvi 	.rx_queue_stop          = cxgbe_dev_rx_queue_stop,
98011ebc23SKumar Sanghvi 	.rx_queue_release       = cxgbe_dev_rx_queue_release,
99a0a344a8SKumar Sanghvi 	.stats_get		= cxgbevf_dev_stats_get,
1000c4a5dfcSKumar Sanghvi 	.mac_addr_set		= cxgbe_mac_addr_set,
101011ebc23SKumar Sanghvi };
102011ebc23SKumar Sanghvi 
103011ebc23SKumar Sanghvi /*
104011ebc23SKumar Sanghvi  * Initialize driver
105011ebc23SKumar Sanghvi  * It returns 0 on success.
106011ebc23SKumar Sanghvi  */
107011ebc23SKumar Sanghvi static int eth_cxgbevf_dev_init(struct rte_eth_dev *eth_dev)
108011ebc23SKumar Sanghvi {
10963a97e58SStephen Hemminger 	struct port_info *pi = eth_dev->data->dev_private;
1105e80364aSKumar Sanghvi 	struct rte_pci_device *pci_dev;
1115e80364aSKumar Sanghvi 	char name[RTE_ETH_NAME_MAX_LEN];
1125e80364aSKumar Sanghvi 	struct adapter *adapter = NULL;
1135e80364aSKumar Sanghvi 	int err = 0;
1145e80364aSKumar Sanghvi 
115011ebc23SKumar Sanghvi 	CXGBE_FUNC_TRACE();
116011ebc23SKumar Sanghvi 
117011ebc23SKumar Sanghvi 	eth_dev->dev_ops = &cxgbevf_eth_dev_ops;
118880ead4eSKumar Sanghvi 	eth_dev->rx_pkt_burst = &cxgbe_recv_pkts;
119880ead4eSKumar Sanghvi 	eth_dev->tx_pkt_burst = &cxgbe_xmit_pkts;
1205e80364aSKumar Sanghvi 	pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
121011ebc23SKumar Sanghvi 
1225e80364aSKumar Sanghvi 	/* for secondary processes, we attach to ethdevs allocated by primary
1235e80364aSKumar Sanghvi 	 * and do minimal initialization.
1245e80364aSKumar Sanghvi 	 */
1255e80364aSKumar Sanghvi 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
1265e80364aSKumar Sanghvi 		int i;
1275e80364aSKumar Sanghvi 
1285e80364aSKumar Sanghvi 		for (i = 1; i < MAX_NPORTS; i++) {
1295e80364aSKumar Sanghvi 			struct rte_eth_dev *rest_eth_dev;
1305e80364aSKumar Sanghvi 			char namei[RTE_ETH_NAME_MAX_LEN];
1315e80364aSKumar Sanghvi 
1325e80364aSKumar Sanghvi 			snprintf(namei, sizeof(namei), "%s_%d",
1335e80364aSKumar Sanghvi 				 pci_dev->device.name, i);
1345e80364aSKumar Sanghvi 			rest_eth_dev = rte_eth_dev_attach_secondary(namei);
1355e80364aSKumar Sanghvi 			if (rest_eth_dev) {
1365e80364aSKumar Sanghvi 				rest_eth_dev->device = &pci_dev->device;
1375e80364aSKumar Sanghvi 				rest_eth_dev->dev_ops =
1385e80364aSKumar Sanghvi 					eth_dev->dev_ops;
1395e80364aSKumar Sanghvi 				rest_eth_dev->rx_pkt_burst =
1405e80364aSKumar Sanghvi 					eth_dev->rx_pkt_burst;
1415e80364aSKumar Sanghvi 				rest_eth_dev->tx_pkt_burst =
1425e80364aSKumar Sanghvi 					eth_dev->tx_pkt_burst;
143fbe90cddSThomas Monjalon 				rte_eth_dev_probing_finish(rest_eth_dev);
1445e80364aSKumar Sanghvi 			}
1455e80364aSKumar Sanghvi 		}
1465e80364aSKumar Sanghvi 		return 0;
1475e80364aSKumar Sanghvi 	}
1485e80364aSKumar Sanghvi 
1495e80364aSKumar Sanghvi 	snprintf(name, sizeof(name), "cxgbevfadapter%d",
1505e80364aSKumar Sanghvi 		 eth_dev->data->port_id);
1515e80364aSKumar Sanghvi 	adapter = rte_zmalloc(name, sizeof(*adapter), 0);
1525e80364aSKumar Sanghvi 	if (!adapter)
1535e80364aSKumar Sanghvi 		return -1;
1545e80364aSKumar Sanghvi 
1555e80364aSKumar Sanghvi 	adapter->use_unpacked_mode = 1;
1565e80364aSKumar Sanghvi 	adapter->regs = (void *)pci_dev->mem_resource[0].addr;
1575e80364aSKumar Sanghvi 	if (!adapter->regs) {
1585e80364aSKumar Sanghvi 		dev_err(adapter, "%s: cannot map device registers\n", __func__);
1595e80364aSKumar Sanghvi 		err = -ENOMEM;
1605e80364aSKumar Sanghvi 		goto out_free_adapter;
1615e80364aSKumar Sanghvi 	}
1625e80364aSKumar Sanghvi 	adapter->pdev = pci_dev;
1635e80364aSKumar Sanghvi 	adapter->eth_dev = eth_dev;
1645e80364aSKumar Sanghvi 	pi->adapter = adapter;
165*dd7c9f12SRahul Lakkireddy 
166*dd7c9f12SRahul Lakkireddy 	cxgbe_process_devargs(adapter);
167*dd7c9f12SRahul Lakkireddy 
1685e80364aSKumar Sanghvi 	err = cxgbevf_probe(adapter);
1695e80364aSKumar Sanghvi 	if (err) {
1705e80364aSKumar Sanghvi 		dev_err(adapter, "%s: cxgbevf probe failed with err %d\n",
1715e80364aSKumar Sanghvi 			__func__, err);
1725e80364aSKumar Sanghvi 		goto out_free_adapter;
1735e80364aSKumar Sanghvi 	}
1745e80364aSKumar Sanghvi 
1755e80364aSKumar Sanghvi 	return 0;
1765e80364aSKumar Sanghvi 
1775e80364aSKumar Sanghvi out_free_adapter:
1785e80364aSKumar Sanghvi 	rte_free(adapter);
1795e80364aSKumar Sanghvi 	return err;
180011ebc23SKumar Sanghvi }
181011ebc23SKumar Sanghvi 
182854f4bf0SRahul Lakkireddy static int eth_cxgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
183854f4bf0SRahul Lakkireddy {
18463a97e58SStephen Hemminger 	struct port_info *pi = eth_dev->data->dev_private;
185854f4bf0SRahul Lakkireddy 	struct adapter *adap = pi->adapter;
186854f4bf0SRahul Lakkireddy 
187854f4bf0SRahul Lakkireddy 	/* Free up other ports and all resources */
188854f4bf0SRahul Lakkireddy 	cxgbe_close(adap);
189854f4bf0SRahul Lakkireddy 	return 0;
190854f4bf0SRahul Lakkireddy }
191854f4bf0SRahul Lakkireddy 
192011ebc23SKumar Sanghvi static int eth_cxgbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
193011ebc23SKumar Sanghvi 				 struct rte_pci_device *pci_dev)
194011ebc23SKumar Sanghvi {
195011ebc23SKumar Sanghvi 	return rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct port_info),
196011ebc23SKumar Sanghvi 					     eth_cxgbevf_dev_init);
197011ebc23SKumar Sanghvi }
198011ebc23SKumar Sanghvi 
199011ebc23SKumar Sanghvi static int eth_cxgbevf_pci_remove(struct rte_pci_device *pci_dev)
200011ebc23SKumar Sanghvi {
201854f4bf0SRahul Lakkireddy 	return rte_eth_dev_pci_generic_remove(pci_dev, eth_cxgbevf_dev_uninit);
202011ebc23SKumar Sanghvi }
203011ebc23SKumar Sanghvi 
204011ebc23SKumar Sanghvi static struct rte_pci_driver rte_cxgbevf_pmd = {
205011ebc23SKumar Sanghvi 	.id_table = cxgb4vf_pci_tbl,
206011ebc23SKumar Sanghvi 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
207011ebc23SKumar Sanghvi 	.probe = eth_cxgbevf_pci_probe,
208011ebc23SKumar Sanghvi 	.remove = eth_cxgbevf_pci_remove,
209011ebc23SKumar Sanghvi };
210011ebc23SKumar Sanghvi 
211011ebc23SKumar Sanghvi RTE_PMD_REGISTER_PCI(net_cxgbevf, rte_cxgbevf_pmd);
212011ebc23SKumar Sanghvi RTE_PMD_REGISTER_PCI_TABLE(net_cxgbevf, cxgb4vf_pci_tbl);
213011ebc23SKumar Sanghvi RTE_PMD_REGISTER_KMOD_DEP(net_cxgbevf, "* igb_uio | vfio-pci");
214*dd7c9f12SRahul Lakkireddy RTE_PMD_REGISTER_PARAM_STRING(net_cxgbevf,
215*dd7c9f12SRahul Lakkireddy 			      CXGBE_DEVARG_CMN_KEEP_OVLAN "=<0|1> "
216*dd7c9f12SRahul Lakkireddy 			      CXGBE_DEVARG_VF_FORCE_LINK_UP "=<0|1> ");
217