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