1540914bcSEd Czeck /* SPDX-License-Identifier: BSD-3-Clause 2540914bcSEd Czeck * Copyright (c) 2015-2018 Atomic Rules LLC 31131cbf0SEd Czeck */ 41131cbf0SEd Czeck 51131cbf0SEd Czeck #include <unistd.h> 61131cbf0SEd Czeck #include <sys/stat.h> 71131cbf0SEd Czeck #include <dlfcn.h> 81131cbf0SEd Czeck 91f37cb2bSDavid Marchand #include <bus_pci_driver.h> 10df96fd0dSBruce Richardson #include <ethdev_pci.h> 111131cbf0SEd Czeck #include <rte_kvargs.h> 121131cbf0SEd Czeck 131131cbf0SEd Czeck #include "ark_global.h" 141131cbf0SEd Czeck #include "ark_logs.h" 15727b3fe2SEd Czeck #include "ark_ethdev_tx.h" 16727b3fe2SEd Czeck #include "ark_ethdev_rx.h" 17727b3fe2SEd Czeck #include "ark_mpu.h" 18727b3fe2SEd Czeck #include "ark_ddm.h" 19727b3fe2SEd Czeck #include "ark_udm.h" 20727b3fe2SEd Czeck #include "ark_rqp.h" 21727b3fe2SEd Czeck #include "ark_pktdir.h" 22727b3fe2SEd Czeck #include "ark_pktgen.h" 23727b3fe2SEd Czeck #include "ark_pktchkr.h" 241131cbf0SEd Czeck 251131cbf0SEd Czeck /* Internal prototypes */ 261131cbf0SEd Czeck static int eth_ark_check_args(struct ark_adapter *ark, const char *params); 271131cbf0SEd Czeck static int eth_ark_dev_init(struct rte_eth_dev *dev); 28727b3fe2SEd Czeck static int ark_config_device(struct rte_eth_dev *dev); 291131cbf0SEd Czeck static int eth_ark_dev_uninit(struct rte_eth_dev *eth_dev); 301131cbf0SEd Czeck static int eth_ark_dev_configure(struct rte_eth_dev *dev); 31727b3fe2SEd Czeck static int eth_ark_dev_start(struct rte_eth_dev *dev); 3262024eb8SIvan Ilchenko static int eth_ark_dev_stop(struct rte_eth_dev *dev); 33b142387bSThomas Monjalon static int eth_ark_dev_close(struct rte_eth_dev *dev); 34bdad90d1SIvan Ilchenko static int eth_ark_dev_info_get(struct rte_eth_dev *dev, 351131cbf0SEd Czeck struct rte_eth_dev_info *dev_info); 36727b3fe2SEd Czeck static int eth_ark_dev_link_update(struct rte_eth_dev *dev, 37727b3fe2SEd Czeck int wait_to_complete); 38727b3fe2SEd Czeck static int eth_ark_dev_set_link_up(struct rte_eth_dev *dev); 39727b3fe2SEd Czeck static int eth_ark_dev_set_link_down(struct rte_eth_dev *dev); 40d5b0924bSMatan Azrad static int eth_ark_dev_stats_get(struct rte_eth_dev *dev, 41727b3fe2SEd Czeck struct rte_eth_stats *stats); 429970a9adSIgor Romanov static int eth_ark_dev_stats_reset(struct rte_eth_dev *dev); 43caccf8b3SOlivier Matz static int eth_ark_set_default_mac_addr(struct rte_eth_dev *dev, 446d13ea8eSOlivier Matz struct rte_ether_addr *mac_addr); 456d01e580SWei Dai static int eth_ark_macaddr_add(struct rte_eth_dev *dev, 466d13ea8eSOlivier Matz struct rte_ether_addr *mac_addr, 47727b3fe2SEd Czeck uint32_t index, 48727b3fe2SEd Czeck uint32_t pool); 49727b3fe2SEd Czeck static void eth_ark_macaddr_remove(struct rte_eth_dev *dev, 50727b3fe2SEd Czeck uint32_t index); 519ae74488SJohn Miller static int eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t size); 521131cbf0SEd Czeck 531131cbf0SEd Czeck /* 541131cbf0SEd Czeck * The packet generator is a functional block used to generate packet 551131cbf0SEd Czeck * patterns for testing. It is not intended for nominal use. 561131cbf0SEd Czeck */ 571131cbf0SEd Czeck #define ARK_PKTGEN_ARG "Pkt_gen" 581131cbf0SEd Czeck 591131cbf0SEd Czeck /* 601131cbf0SEd Czeck * The packet checker is a functional block used to verify packet 611131cbf0SEd Czeck * patterns for testing. It is not intended for nominal use. 621131cbf0SEd Czeck */ 631131cbf0SEd Czeck #define ARK_PKTCHKR_ARG "Pkt_chkr" 641131cbf0SEd Czeck 651131cbf0SEd Czeck /* 661131cbf0SEd Czeck * The packet director is used to select the internal ingress and 671131cbf0SEd Czeck * egress packets paths during testing. It is not intended for 681131cbf0SEd Czeck * nominal use. 691131cbf0SEd Czeck */ 701131cbf0SEd Czeck #define ARK_PKTDIR_ARG "Pkt_dir" 711131cbf0SEd Czeck 721131cbf0SEd Czeck /* Devinfo configurations */ 731131cbf0SEd Czeck #define ARK_RX_MAX_QUEUE (4096 * 4) 741131cbf0SEd Czeck #define ARK_RX_MIN_QUEUE (512) 751131cbf0SEd Czeck #define ARK_RX_MAX_PKT_LEN ((16 * 1024) - 128) 761131cbf0SEd Czeck #define ARK_RX_MIN_BUFSIZE (1024) 771131cbf0SEd Czeck 781131cbf0SEd Czeck #define ARK_TX_MAX_QUEUE (4096 * 4) 791131cbf0SEd Czeck #define ARK_TX_MIN_QUEUE (256) 801131cbf0SEd Czeck 811131cbf0SEd Czeck static const char * const valid_arguments[] = { 821131cbf0SEd Czeck ARK_PKTGEN_ARG, 831131cbf0SEd Czeck ARK_PKTCHKR_ARG, 841131cbf0SEd Czeck ARK_PKTDIR_ARG, 851131cbf0SEd Czeck NULL 861131cbf0SEd Czeck }; 871131cbf0SEd Czeck 88c5314a53SJohn Miller #define AR_VENDOR_ID 0x1d6c 891131cbf0SEd Czeck static const struct rte_pci_id pci_id_ark_map[] = { 90c5314a53SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x100d)}, 91c5314a53SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x100e)}, 92c5314a53SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x100f)}, 93c5314a53SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1010)}, 94c5314a53SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1017)}, 95c5314a53SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1018)}, 96c5314a53SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1019)}, 97b5c58298SEd Czeck {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101a)}, 98b5c58298SEd Czeck {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101b)}, 99b5c58298SEd Czeck {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101c)}, 10051ec6c74SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101e)}, 10151ec6c74SJohn Miller {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x101f)}, 102cdfaa85eSShepard Siegel {RTE_PCI_DEVICE(AR_VENDOR_ID, 0x1022)}, 1031131cbf0SEd Czeck {.vendor_id = 0, /* sentinel */ }, 1041131cbf0SEd Czeck }; 1051131cbf0SEd Czeck 106c5314a53SJohn Miller /* 107c5314a53SJohn Miller * This structure is used to statically define the capabilities 108c5314a53SJohn Miller * of supported devices. 109c5314a53SJohn Miller * Capabilities: 110c5314a53SJohn Miller * rqpacing - 111c5314a53SJohn Miller * Some HW variants require that PCIe read-requests be correctly throttled. 112c5314a53SJohn Miller * This is called "rqpacing" and has to do with credit and flow control 113c5314a53SJohn Miller * on certain Arkville implementations. 114c5314a53SJohn Miller */ 115c5314a53SJohn Miller struct ark_caps { 116c5314a53SJohn Miller bool rqpacing; 1176799275eSEd Czeck bool isvf; 118c5314a53SJohn Miller }; 119c5314a53SJohn Miller struct ark_dev_caps { 120c5314a53SJohn Miller uint32_t device_id; 121c5314a53SJohn Miller struct ark_caps caps; 122c5314a53SJohn Miller }; 1236799275eSEd Czeck #define SET_DEV_CAPS(id, rqp, vf) \ 1246799275eSEd Czeck {id, {.rqpacing = rqp, .isvf = vf} } 125c5314a53SJohn Miller 126c5314a53SJohn Miller static const struct ark_dev_caps 127c5314a53SJohn Miller ark_device_caps[] = { 1286799275eSEd Czeck SET_DEV_CAPS(0x100d, true, false), 1296799275eSEd Czeck SET_DEV_CAPS(0x100e, true, false), 1306799275eSEd Czeck SET_DEV_CAPS(0x100f, true, false), 1316799275eSEd Czeck SET_DEV_CAPS(0x1010, false, false), 1326799275eSEd Czeck SET_DEV_CAPS(0x1017, true, false), 1336799275eSEd Czeck SET_DEV_CAPS(0x1018, true, false), 1346799275eSEd Czeck SET_DEV_CAPS(0x1019, true, false), 1356799275eSEd Czeck SET_DEV_CAPS(0x101a, true, false), 1366799275eSEd Czeck SET_DEV_CAPS(0x101b, true, false), 1376799275eSEd Czeck SET_DEV_CAPS(0x101c, true, true), 1386799275eSEd Czeck SET_DEV_CAPS(0x101e, false, false), 1396799275eSEd Czeck SET_DEV_CAPS(0x101f, false, false), 140c5314a53SJohn Miller {.device_id = 0,} 141c5314a53SJohn Miller }; 142c5314a53SJohn Miller 1431131cbf0SEd Czeck static int 1441131cbf0SEd Czeck eth_ark_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 1451131cbf0SEd Czeck struct rte_pci_device *pci_dev) 1461131cbf0SEd Czeck { 1471131cbf0SEd Czeck struct rte_eth_dev *eth_dev; 1481131cbf0SEd Czeck int ret; 1491131cbf0SEd Czeck 1501131cbf0SEd Czeck eth_dev = rte_eth_dev_pci_allocate(pci_dev, sizeof(struct ark_adapter)); 1511131cbf0SEd Czeck 1521131cbf0SEd Czeck if (eth_dev == NULL) 1531131cbf0SEd Czeck return -ENOMEM; 1541131cbf0SEd Czeck 1551131cbf0SEd Czeck ret = eth_ark_dev_init(eth_dev); 1561131cbf0SEd Czeck if (ret) 1572c65898bSThomas Monjalon rte_eth_dev_release_port(eth_dev); 1581131cbf0SEd Czeck 1591131cbf0SEd Czeck return ret; 1601131cbf0SEd Czeck } 1611131cbf0SEd Czeck 1621131cbf0SEd Czeck static int 1631131cbf0SEd Czeck eth_ark_pci_remove(struct rte_pci_device *pci_dev) 1641131cbf0SEd Czeck { 1651131cbf0SEd Czeck return rte_eth_dev_pci_generic_remove(pci_dev, eth_ark_dev_uninit); 1661131cbf0SEd Czeck } 1671131cbf0SEd Czeck 1681131cbf0SEd Czeck static struct rte_pci_driver rte_ark_pmd = { 1691131cbf0SEd Czeck .id_table = pci_id_ark_map, 1701131cbf0SEd Czeck .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC, 1711131cbf0SEd Czeck .probe = eth_ark_pci_probe, 1721131cbf0SEd Czeck .remove = eth_ark_pci_remove, 1731131cbf0SEd Czeck }; 1741131cbf0SEd Czeck 1751131cbf0SEd Czeck static const struct eth_dev_ops ark_eth_dev_ops = { 1761131cbf0SEd Czeck .dev_configure = eth_ark_dev_configure, 177727b3fe2SEd Czeck .dev_start = eth_ark_dev_start, 178727b3fe2SEd Czeck .dev_stop = eth_ark_dev_stop, 179727b3fe2SEd Czeck .dev_close = eth_ark_dev_close, 180727b3fe2SEd Czeck 1811131cbf0SEd Czeck .dev_infos_get = eth_ark_dev_info_get, 182727b3fe2SEd Czeck 183727b3fe2SEd Czeck .rx_queue_setup = eth_ark_dev_rx_queue_setup, 184727b3fe2SEd Czeck .tx_queue_setup = eth_ark_tx_queue_setup, 185727b3fe2SEd Czeck 186727b3fe2SEd Czeck .link_update = eth_ark_dev_link_update, 187727b3fe2SEd Czeck .dev_set_link_up = eth_ark_dev_set_link_up, 188727b3fe2SEd Czeck .dev_set_link_down = eth_ark_dev_set_link_down, 189727b3fe2SEd Czeck 190727b3fe2SEd Czeck .rx_queue_start = eth_ark_rx_start_queue, 191727b3fe2SEd Czeck .rx_queue_stop = eth_ark_rx_stop_queue, 192727b3fe2SEd Czeck 193727b3fe2SEd Czeck .tx_queue_start = eth_ark_tx_queue_start, 194727b3fe2SEd Czeck .tx_queue_stop = eth_ark_tx_queue_stop, 195727b3fe2SEd Czeck 196727b3fe2SEd Czeck .stats_get = eth_ark_dev_stats_get, 197727b3fe2SEd Czeck .stats_reset = eth_ark_dev_stats_reset, 198727b3fe2SEd Czeck 199727b3fe2SEd Czeck .mac_addr_add = eth_ark_macaddr_add, 200727b3fe2SEd Czeck .mac_addr_remove = eth_ark_macaddr_remove, 201727b3fe2SEd Czeck .mac_addr_set = eth_ark_set_default_mac_addr, 2029ae74488SJohn Miller 2039ae74488SJohn Miller .mtu_set = eth_ark_set_mtu, 2041131cbf0SEd Czeck }; 2051131cbf0SEd Czeck 2061131cbf0SEd Czeck static int 207727b3fe2SEd Czeck check_for_ext(struct ark_adapter *ark) 208727b3fe2SEd Czeck { 209727b3fe2SEd Czeck int found = 0; 210727b3fe2SEd Czeck 211727b3fe2SEd Czeck /* Get the env */ 212727b3fe2SEd Czeck const char *dllpath = getenv("ARK_EXT_PATH"); 213727b3fe2SEd Czeck 214727b3fe2SEd Czeck if (dllpath == NULL) { 2151502d443SEd Czeck ARK_PMD_LOG(DEBUG, "EXT NO dll path specified\n"); 216727b3fe2SEd Czeck return 0; 217727b3fe2SEd Czeck } 2181502d443SEd Czeck ARK_PMD_LOG(NOTICE, "EXT found dll path at %s\n", dllpath); 219727b3fe2SEd Czeck 220727b3fe2SEd Czeck /* Open and load the .so */ 221727b3fe2SEd Czeck ark->d_handle = dlopen(dllpath, RTLD_LOCAL | RTLD_LAZY); 222727b3fe2SEd Czeck if (ark->d_handle == NULL) { 2231502d443SEd Czeck ARK_PMD_LOG(ERR, "Could not load user extension %s\n", 224727b3fe2SEd Czeck dllpath); 225727b3fe2SEd Czeck return -1; 226727b3fe2SEd Czeck } 2271502d443SEd Czeck ARK_PMD_LOG(DEBUG, "SUCCESS: loaded user extension %s\n", 228727b3fe2SEd Czeck dllpath); 229727b3fe2SEd Czeck 230727b3fe2SEd Czeck /* Get the entry points */ 231727b3fe2SEd Czeck ark->user_ext.dev_init = 232727b3fe2SEd Czeck (void *(*)(struct rte_eth_dev *, void *, int)) 233f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_init"); 2341502d443SEd Czeck ARK_PMD_LOG(DEBUG, "device ext init pointer = %p\n", 235727b3fe2SEd Czeck ark->user_ext.dev_init); 236727b3fe2SEd Czeck ark->user_ext.dev_get_port_count = 237727b3fe2SEd Czeck (int (*)(struct rte_eth_dev *, void *)) 238f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_get_port_count"); 239727b3fe2SEd Czeck ark->user_ext.dev_uninit = 240727b3fe2SEd Czeck (void (*)(struct rte_eth_dev *, void *)) 241f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_uninit"); 242727b3fe2SEd Czeck ark->user_ext.dev_configure = 243727b3fe2SEd Czeck (int (*)(struct rte_eth_dev *, void *)) 244f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_configure"); 245727b3fe2SEd Czeck ark->user_ext.dev_start = 246727b3fe2SEd Czeck (int (*)(struct rte_eth_dev *, void *)) 247f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_start"); 248727b3fe2SEd Czeck ark->user_ext.dev_stop = 249727b3fe2SEd Czeck (void (*)(struct rte_eth_dev *, void *)) 250f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_stop"); 251727b3fe2SEd Czeck ark->user_ext.dev_close = 252727b3fe2SEd Czeck (void (*)(struct rte_eth_dev *, void *)) 253f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_close"); 254727b3fe2SEd Czeck ark->user_ext.link_update = 255727b3fe2SEd Czeck (int (*)(struct rte_eth_dev *, int, void *)) 256f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_link_update"); 257727b3fe2SEd Czeck ark->user_ext.dev_set_link_up = 258727b3fe2SEd Czeck (int (*)(struct rte_eth_dev *, void *)) 259f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_up"); 260727b3fe2SEd Czeck ark->user_ext.dev_set_link_down = 261727b3fe2SEd Czeck (int (*)(struct rte_eth_dev *, void *)) 262f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_down"); 263727b3fe2SEd Czeck ark->user_ext.stats_get = 264d5b0924bSMatan Azrad (int (*)(struct rte_eth_dev *, struct rte_eth_stats *, 265727b3fe2SEd Czeck void *)) 266f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_stats_get"); 267727b3fe2SEd Czeck ark->user_ext.stats_reset = 268727b3fe2SEd Czeck (void (*)(struct rte_eth_dev *, void *)) 269f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_stats_reset"); 270727b3fe2SEd Czeck ark->user_ext.mac_addr_add = 2716d13ea8eSOlivier Matz (void (*)(struct rte_eth_dev *, struct rte_ether_addr *, 2726d13ea8eSOlivier Matz uint32_t, uint32_t, void *)) 273f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_add"); 274727b3fe2SEd Czeck ark->user_ext.mac_addr_remove = 275727b3fe2SEd Czeck (void (*)(struct rte_eth_dev *, uint32_t, void *)) 276f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_remove"); 277727b3fe2SEd Czeck ark->user_ext.mac_addr_set = 2786d13ea8eSOlivier Matz (void (*)(struct rte_eth_dev *, struct rte_ether_addr *, 279727b3fe2SEd Czeck void *)) 280f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_set"); 2819ae74488SJohn Miller ark->user_ext.set_mtu = 2829ae74488SJohn Miller (int (*)(struct rte_eth_dev *, uint16_t, 2839ae74488SJohn Miller void *)) 284f2764c36SEd Czeck dlsym(ark->d_handle, "rte_pmd_ark_set_mtu"); 2856c7f491eSEd Czeck ark->user_ext.rx_user_meta_hook = 2866c7f491eSEd Czeck (rx_user_meta_hook_fn)dlsym(ark->d_handle, 2876c7f491eSEd Czeck "rte_pmd_ark_rx_user_meta_hook"); 2886c7f491eSEd Czeck ark->user_ext.tx_user_meta_hook = 2896c7f491eSEd Czeck (tx_user_meta_hook_fn)dlsym(ark->d_handle, 2906c7f491eSEd Czeck "rte_pmd_ark_tx_user_meta_hook"); 291727b3fe2SEd Czeck 292727b3fe2SEd Czeck return found; 293727b3fe2SEd Czeck } 294727b3fe2SEd Czeck 295727b3fe2SEd Czeck static int 2961131cbf0SEd Czeck eth_ark_dev_init(struct rte_eth_dev *dev) 2971131cbf0SEd Czeck { 2980bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 2991131cbf0SEd Czeck struct rte_pci_device *pci_dev; 300727b3fe2SEd Czeck int ret; 301727b3fe2SEd Czeck int port_count = 1; 302727b3fe2SEd Czeck int p; 303*bf73ee28SEd Czeck uint16_t num_queues; 304c5314a53SJohn Miller bool rqpacing = false; 3051131cbf0SEd Czeck 3061131cbf0SEd Czeck ark->eth_dev = dev; 3071131cbf0SEd Czeck 3081502d443SEd Czeck ARK_PMD_LOG(DEBUG, "\n"); 3091131cbf0SEd Czeck 310727b3fe2SEd Czeck /* Check to see if there is an extension that we need to load */ 311727b3fe2SEd Czeck ret = check_for_ext(ark); 312727b3fe2SEd Czeck if (ret) 313727b3fe2SEd Czeck return ret; 3141abc7209SEd Czeck 315c0802544SFerruh Yigit pci_dev = RTE_ETH_DEV_TO_PCI(dev); 3161131cbf0SEd Czeck rte_eth_copy_pci_info(dev, pci_dev); 317f30e69b4SFerruh Yigit dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 3181131cbf0SEd Czeck 319c5314a53SJohn Miller p = 0; 320c5314a53SJohn Miller while (ark_device_caps[p].device_id != 0) { 321c5314a53SJohn Miller if (pci_dev->id.device_id == ark_device_caps[p].device_id) { 322c5314a53SJohn Miller rqpacing = ark_device_caps[p].caps.rqpacing; 3236799275eSEd Czeck ark->isvf = ark_device_caps[p].caps.isvf; 324c5314a53SJohn Miller break; 325c5314a53SJohn Miller } 326c5314a53SJohn Miller p++; 327c5314a53SJohn Miller } 328c5314a53SJohn Miller 329727b3fe2SEd Czeck /* Use dummy function until setup */ 330a41f593fSFerruh Yigit dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; 331a41f593fSFerruh Yigit dev->tx_pkt_burst = rte_eth_pkt_burst_dummy; 332727b3fe2SEd Czeck 3331131cbf0SEd Czeck ark->bar0 = (uint8_t *)pci_dev->mem_resource[0].addr; 3341131cbf0SEd Czeck ark->a_bar = (uint8_t *)pci_dev->mem_resource[2].addr; 3351131cbf0SEd Czeck 336727b3fe2SEd Czeck ark->sysctrl.v = (void *)&ark->bar0[ARK_SYSCTRL_BASE]; 337727b3fe2SEd Czeck ark->mpurx.v = (void *)&ark->bar0[ARK_MPU_RX_BASE]; 338727b3fe2SEd Czeck ark->udm.v = (void *)&ark->bar0[ARK_UDM_BASE]; 339727b3fe2SEd Czeck ark->mputx.v = (void *)&ark->bar0[ARK_MPU_TX_BASE]; 340727b3fe2SEd Czeck ark->ddm.v = (void *)&ark->bar0[ARK_DDM_BASE]; 341727b3fe2SEd Czeck ark->cmac.v = (void *)&ark->bar0[ARK_CMAC_BASE]; 342727b3fe2SEd Czeck ark->external.v = (void *)&ark->bar0[ARK_EXTERNAL_BASE]; 343727b3fe2SEd Czeck ark->pktdir.v = (void *)&ark->bar0[ARK_PKTDIR_BASE]; 344727b3fe2SEd Czeck ark->pktgen.v = (void *)&ark->bar0[ARK_PKTGEN_BASE]; 345727b3fe2SEd Czeck ark->pktchkr.v = (void *)&ark->bar0[ARK_PKTCHKR_BASE]; 346727b3fe2SEd Czeck 347c5314a53SJohn Miller if (rqpacing) { 348727b3fe2SEd Czeck ark->rqpacing = 349727b3fe2SEd Czeck (struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE); 350c5314a53SJohn Miller } else { 351c5314a53SJohn Miller ark->rqpacing = NULL; 352c5314a53SJohn Miller } 353727b3fe2SEd Czeck ark->started = 0; 3543b4f34f6SEd Czeck ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL; 355727b3fe2SEd Czeck 3561502d443SEd Czeck ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x HW Commit_ID: %08x\n", 357727b3fe2SEd Czeck ark->sysctrl.t32[4], 358727b3fe2SEd Czeck rte_be_to_cpu_32(ark->sysctrl.t32[0x20 / 4])); 3591502d443SEd Czeck ARK_PMD_LOG(NOTICE, "Arkville HW Commit_ID: %08x\n", 360727b3fe2SEd Czeck rte_be_to_cpu_32(ark->sysctrl.t32[0x20 / 4])); 361727b3fe2SEd Czeck 362727b3fe2SEd Czeck /* If HW sanity test fails, return an error */ 363727b3fe2SEd Czeck if (ark->sysctrl.t32[4] != 0xcafef00d) { 3641502d443SEd Czeck ARK_PMD_LOG(ERR, 365727b3fe2SEd Czeck "HW Sanity test has failed, expected constant" 366727b3fe2SEd Czeck " 0x%x, read 0x%x (%s)\n", 367727b3fe2SEd Czeck 0xcafef00d, 368727b3fe2SEd Czeck ark->sysctrl.t32[4], __func__); 369727b3fe2SEd Czeck return -1; 370727b3fe2SEd Czeck } 3719ff8fe95SEd Czeck if (ark->sysctrl.t32[3] != 0) { 372c5314a53SJohn Miller if (ark->rqpacing) { 3739ff8fe95SEd Czeck if (ark_rqp_lasped(ark->rqpacing)) { 3741502d443SEd Czeck ARK_PMD_LOG(ERR, "Arkville Evaluation System - " 3759ff8fe95SEd Czeck "Timer has Expired\n"); 3769ff8fe95SEd Czeck return -1; 3779ff8fe95SEd Czeck } 3781502d443SEd Czeck ARK_PMD_LOG(WARNING, "Arkville Evaluation System - " 3799ff8fe95SEd Czeck "Timer is Running\n"); 3809ff8fe95SEd Czeck } 381c5314a53SJohn Miller } 382727b3fe2SEd Czeck 3831502d443SEd Czeck ARK_PMD_LOG(DEBUG, 384727b3fe2SEd Czeck "HW Sanity test has PASSED, expected constant" 385727b3fe2SEd Czeck " 0x%x, read 0x%x (%s)\n", 386727b3fe2SEd Czeck 0xcafef00d, ark->sysctrl.t32[4], __func__); 387727b3fe2SEd Czeck 388727b3fe2SEd Czeck /* We are a single function multi-port device. */ 389727b3fe2SEd Czeck ret = ark_config_device(dev); 390589876bfSEd Czeck if (ret) 391589876bfSEd Czeck return -1; 392589876bfSEd Czeck 3931131cbf0SEd Czeck dev->dev_ops = &ark_eth_dev_ops; 394cbfc6111SFerruh Yigit dev->rx_queue_count = eth_ark_dev_rx_queue_count; 3951131cbf0SEd Czeck 39635b2d13fSOlivier Matz dev->data->mac_addrs = rte_zmalloc("ark", RTE_ETHER_ADDR_LEN, 0); 397727b3fe2SEd Czeck if (!dev->data->mac_addrs) { 3981502d443SEd Czeck ARK_PMD_LOG(ERR, 399727b3fe2SEd Czeck "Failed to allocated memory for storing mac address" 400727b3fe2SEd Czeck ); 401727b3fe2SEd Czeck } 402727b3fe2SEd Czeck 403727b3fe2SEd Czeck if (ark->user_ext.dev_init) { 404428046b4SJohn Miller ark->user_data[dev->data->port_id] = 405428046b4SJohn Miller ark->user_ext.dev_init(dev, ark->a_bar, 0); 406428046b4SJohn Miller if (!ark->user_data[dev->data->port_id]) { 4071502d443SEd Czeck ARK_PMD_LOG(WARNING, 408727b3fe2SEd Czeck "Failed to initialize PMD extension!" 409727b3fe2SEd Czeck " continuing without it\n"); 410727b3fe2SEd Czeck memset(&ark->user_ext, 0, sizeof(struct ark_user_ext)); 411727b3fe2SEd Czeck dlclose(ark->d_handle); 412727b3fe2SEd Czeck } 413727b3fe2SEd Czeck } 414727b3fe2SEd Czeck 4151131cbf0SEd Czeck if (pci_dev->device.devargs) 4161131cbf0SEd Czeck ret = eth_ark_check_args(ark, pci_dev->device.devargs->args); 4171131cbf0SEd Czeck else 4181502d443SEd Czeck ARK_PMD_LOG(INFO, "No Device args found\n"); 4191131cbf0SEd Czeck 420727b3fe2SEd Czeck if (ret) 421727b3fe2SEd Czeck goto error; 422727b3fe2SEd Czeck /* 423727b3fe2SEd Czeck * We will create additional devices based on the number of requested 424727b3fe2SEd Czeck * ports 425727b3fe2SEd Czeck */ 426727b3fe2SEd Czeck if (ark->user_ext.dev_get_port_count) 427727b3fe2SEd Czeck port_count = 428428046b4SJohn Miller ark->user_ext.dev_get_port_count(dev, 429428046b4SJohn Miller ark->user_data[dev->data->port_id]); 430727b3fe2SEd Czeck ark->num_ports = port_count; 431*bf73ee28SEd Czeck num_queues = ark_api_num_queues_per_port(ark->mpurx.v, port_count); 432727b3fe2SEd Czeck 433727b3fe2SEd Czeck for (p = 0; p < port_count; p++) { 434727b3fe2SEd Czeck struct rte_eth_dev *eth_dev; 435727b3fe2SEd Czeck char name[RTE_ETH_NAME_MAX_LEN]; 436727b3fe2SEd Czeck 437727b3fe2SEd Czeck snprintf(name, sizeof(name), "arketh%d", 438727b3fe2SEd Czeck dev->data->port_id + p); 439727b3fe2SEd Czeck 440727b3fe2SEd Czeck if (p == 0) { 441727b3fe2SEd Czeck /* First port is already allocated by DPDK */ 442727b3fe2SEd Czeck eth_dev = ark->eth_dev; 4435bfe551dSEd Czeck rte_eth_dev_probing_finish(eth_dev); 444727b3fe2SEd Czeck continue; 445727b3fe2SEd Czeck } 446727b3fe2SEd Czeck 447727b3fe2SEd Czeck /* reserve an ethdev entry */ 448727b3fe2SEd Czeck eth_dev = rte_eth_dev_allocate(name); 449727b3fe2SEd Czeck if (!eth_dev) { 4501502d443SEd Czeck ARK_PMD_LOG(ERR, 451727b3fe2SEd Czeck "Could not allocate eth_dev for port %d\n", 452727b3fe2SEd Czeck p); 453727b3fe2SEd Czeck goto error; 454727b3fe2SEd Czeck } 455727b3fe2SEd Czeck 456727b3fe2SEd Czeck eth_dev->device = &pci_dev->device; 457*bf73ee28SEd Czeck /* Device requires new dev_private data */ 458*bf73ee28SEd Czeck eth_dev->data->dev_private = 459*bf73ee28SEd Czeck rte_zmalloc_socket(name, 460*bf73ee28SEd Czeck sizeof(struct ark_adapter), 461*bf73ee28SEd Czeck RTE_CACHE_LINE_SIZE, 462*bf73ee28SEd Czeck rte_socket_id()); 463*bf73ee28SEd Czeck 464*bf73ee28SEd Czeck memcpy(eth_dev->data->dev_private, ark, 465*bf73ee28SEd Czeck sizeof(struct ark_adapter)); 466*bf73ee28SEd Czeck ark = eth_dev->data->dev_private; 467*bf73ee28SEd Czeck ark->qbase = p * num_queues; 468*bf73ee28SEd Czeck 469727b3fe2SEd Czeck eth_dev->dev_ops = ark->eth_dev->dev_ops; 470727b3fe2SEd Czeck eth_dev->tx_pkt_burst = ark->eth_dev->tx_pkt_burst; 471727b3fe2SEd Czeck eth_dev->rx_pkt_burst = ark->eth_dev->rx_pkt_burst; 472727b3fe2SEd Czeck 473727b3fe2SEd Czeck rte_eth_copy_pci_info(eth_dev, pci_dev); 474f30e69b4SFerruh Yigit eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 475727b3fe2SEd Czeck 47635b2d13fSOlivier Matz eth_dev->data->mac_addrs = rte_zmalloc(name, 47735b2d13fSOlivier Matz RTE_ETHER_ADDR_LEN, 0); 478727b3fe2SEd Czeck if (!eth_dev->data->mac_addrs) { 4791502d443SEd Czeck ARK_PMD_LOG(ERR, 480727b3fe2SEd Czeck "Memory allocation for MAC failed!" 481727b3fe2SEd Czeck " Exiting.\n"); 482727b3fe2SEd Czeck goto error; 483727b3fe2SEd Czeck } 484727b3fe2SEd Czeck 485428046b4SJohn Miller if (ark->user_ext.dev_init) { 486428046b4SJohn Miller ark->user_data[eth_dev->data->port_id] = 487727b3fe2SEd Czeck ark->user_ext.dev_init(dev, ark->a_bar, p); 488727b3fe2SEd Czeck } 489fbe90cddSThomas Monjalon 490fbe90cddSThomas Monjalon rte_eth_dev_probing_finish(eth_dev); 491428046b4SJohn Miller } 492727b3fe2SEd Czeck 4931131cbf0SEd Czeck return ret; 494727b3fe2SEd Czeck 495727b3fe2SEd Czeck error: 496727b3fe2SEd Czeck rte_free(dev->data->mac_addrs); 497e7f2fa88SDavid Marchand dev->data->mac_addrs = NULL; 498727b3fe2SEd Czeck return -1; 499727b3fe2SEd Czeck } 500727b3fe2SEd Czeck 501727b3fe2SEd Czeck /* 502727b3fe2SEd Czeck *Initial device configuration when device is opened 503727b3fe2SEd Czeck * setup the DDM, and UDM 504727b3fe2SEd Czeck * Called once per PCIE device 505727b3fe2SEd Czeck */ 506727b3fe2SEd Czeck static int 507727b3fe2SEd Czeck ark_config_device(struct rte_eth_dev *dev) 508727b3fe2SEd Czeck { 5090bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 510727b3fe2SEd Czeck uint16_t num_q, i; 511727b3fe2SEd Czeck struct ark_mpu_t *mpu; 512727b3fe2SEd Czeck 513727b3fe2SEd Czeck /* 514727b3fe2SEd Czeck * Make sure that the packet director, generator and checker are in a 515727b3fe2SEd Czeck * known state 516727b3fe2SEd Czeck */ 5176799275eSEd Czeck if (!ark->isvf) { 518727b3fe2SEd Czeck ark->start_pg = 0; 519c7ff3d78SJohn Miller ark->pg_running = 0; 520727b3fe2SEd Czeck ark->pg = ark_pktgen_init(ark->pktgen.v, 0, 1); 52153a9ba13SYong Wang if (ark->pg == NULL) 52253a9ba13SYong Wang return -1; 523727b3fe2SEd Czeck ark_pktgen_reset(ark->pg); 524727b3fe2SEd Czeck ark->pc = ark_pktchkr_init(ark->pktchkr.v, 0, 1); 52553a9ba13SYong Wang if (ark->pc == NULL) 52653a9ba13SYong Wang return -1; 527727b3fe2SEd Czeck ark_pktchkr_stop(ark->pc); 528727b3fe2SEd Czeck ark->pd = ark_pktdir_init(ark->pktdir.v); 52953a9ba13SYong Wang if (ark->pd == NULL) 53053a9ba13SYong Wang return -1; 5316799275eSEd Czeck } 532727b3fe2SEd Czeck /* Verify HW */ 533727b3fe2SEd Czeck if (ark_udm_verify(ark->udm.v)) 534727b3fe2SEd Czeck return -1; 535727b3fe2SEd Czeck if (ark_ddm_verify(ark->ddm.v)) 536727b3fe2SEd Czeck return -1; 537727b3fe2SEd Czeck 538727b3fe2SEd Czeck /* MPU reset */ 539727b3fe2SEd Czeck mpu = ark->mpurx.v; 540727b3fe2SEd Czeck num_q = ark_api_num_queues(mpu); 541727b3fe2SEd Czeck ark->rx_queues = num_q; 542727b3fe2SEd Czeck for (i = 0; i < num_q; i++) { 543727b3fe2SEd Czeck mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET); 544727b3fe2SEd Czeck } 545727b3fe2SEd Czeck 546727b3fe2SEd Czeck mpu = ark->mputx.v; 547727b3fe2SEd Czeck num_q = ark_api_num_queues(mpu); 548727b3fe2SEd Czeck ark->tx_queues = num_q; 549727b3fe2SEd Czeck for (i = 0; i < num_q; i++) { 550727b3fe2SEd Czeck mpu = RTE_PTR_ADD(mpu, ARK_MPU_QOFFSET); 551727b3fe2SEd Czeck } 552727b3fe2SEd Czeck 5536799275eSEd Czeck if (!ark->isvf && ark->rqpacing) 554727b3fe2SEd Czeck ark_rqp_stats_reset(ark->rqpacing); 555727b3fe2SEd Czeck 556727b3fe2SEd Czeck return 0; 5571131cbf0SEd Czeck } 5581131cbf0SEd Czeck 5591131cbf0SEd Czeck static int 5601131cbf0SEd Czeck eth_ark_dev_uninit(struct rte_eth_dev *dev) 5611131cbf0SEd Czeck { 5620bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 563727b3fe2SEd Czeck 5641131cbf0SEd Czeck if (rte_eal_process_type() != RTE_PROC_PRIMARY) 5651131cbf0SEd Czeck return 0; 5661131cbf0SEd Czeck 567727b3fe2SEd Czeck if (ark->user_ext.dev_uninit) 568428046b4SJohn Miller ark->user_ext.dev_uninit(dev, 569428046b4SJohn Miller ark->user_data[dev->data->port_id]); 570727b3fe2SEd Czeck 5716799275eSEd Czeck if (!ark->isvf) { 572727b3fe2SEd Czeck ark_pktgen_uninit(ark->pg); 573727b3fe2SEd Czeck ark_pktchkr_uninit(ark->pc); 5746799275eSEd Czeck } 575727b3fe2SEd Czeck 5761131cbf0SEd Czeck return 0; 5771131cbf0SEd Czeck } 5781131cbf0SEd Czeck 5791131cbf0SEd Czeck static int 580727b3fe2SEd Czeck eth_ark_dev_configure(struct rte_eth_dev *dev) 5811131cbf0SEd Czeck { 5820bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 583727b3fe2SEd Czeck 584727b3fe2SEd Czeck eth_ark_dev_set_link_up(dev); 585727b3fe2SEd Czeck if (ark->user_ext.dev_configure) 586428046b4SJohn Miller return ark->user_ext.dev_configure(dev, 587428046b4SJohn Miller ark->user_data[dev->data->port_id]); 5881131cbf0SEd Czeck return 0; 5891131cbf0SEd Czeck } 5901131cbf0SEd Czeck 591727b3fe2SEd Czeck static int 592727b3fe2SEd Czeck eth_ark_dev_start(struct rte_eth_dev *dev) 593727b3fe2SEd Czeck { 5940bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 595727b3fe2SEd Czeck int i; 596727b3fe2SEd Czeck 597727b3fe2SEd Czeck /* RX Side */ 598727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_rx_queues; i++) 599727b3fe2SEd Czeck eth_ark_rx_start_queue(dev, i); 600727b3fe2SEd Czeck 601727b3fe2SEd Czeck /* TX Side */ 602727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_tx_queues; i++) 603727b3fe2SEd Czeck eth_ark_tx_queue_start(dev, i); 604727b3fe2SEd Czeck 605727b3fe2SEd Czeck ark->started = 1; 606727b3fe2SEd Czeck /* set xmit and receive function */ 607727b3fe2SEd Czeck dev->rx_pkt_burst = ð_ark_recv_pkts; 608727b3fe2SEd Czeck dev->tx_pkt_burst = ð_ark_xmit_pkts; 609727b3fe2SEd Czeck 6106799275eSEd Czeck if (!ark->isvf && ark->start_pg) 611727b3fe2SEd Czeck ark_pktchkr_run(ark->pc); 612727b3fe2SEd Czeck 6136799275eSEd Czeck if (!ark->isvf && ark->start_pg && !ark->pg_running) { 614a7ba40b2SThomas Monjalon rte_thread_t thread; 615727b3fe2SEd Czeck 61662774b78SThomas Monjalon /* Delay packet generator start allow the hardware to be ready 617727b3fe2SEd Czeck * This is only used for sanity checking with internal generator 618727b3fe2SEd Czeck */ 619a7ba40b2SThomas Monjalon char tname[RTE_THREAD_INTERNAL_NAME_SIZE]; 620a7ba40b2SThomas Monjalon snprintf(tname, sizeof(tname), "ark-pg%d", dev->data->port_id); 621c7ff3d78SJohn Miller 622a7ba40b2SThomas Monjalon if (rte_thread_create_internal_control(&thread, tname, 6234b42104cSEd Czeck ark_pktgen_delay_start, ark->pg)) { 6241502d443SEd Czeck ARK_PMD_LOG(ERR, "Could not create pktgen " 625d1434c04SJohn Miller "starter thread\n"); 626d1434c04SJohn Miller return -1; 627d1434c04SJohn Miller } 628c7ff3d78SJohn Miller ark->pg_running = 1; 629727b3fe2SEd Czeck } 630727b3fe2SEd Czeck 631727b3fe2SEd Czeck if (ark->user_ext.dev_start) 632428046b4SJohn Miller ark->user_ext.dev_start(dev, 633428046b4SJohn Miller ark->user_data[dev->data->port_id]); 634727b3fe2SEd Czeck 635727b3fe2SEd Czeck return 0; 636727b3fe2SEd Czeck } 637727b3fe2SEd Czeck 63862024eb8SIvan Ilchenko static int 639727b3fe2SEd Czeck eth_ark_dev_stop(struct rte_eth_dev *dev) 640727b3fe2SEd Czeck { 641727b3fe2SEd Czeck uint16_t i; 642727b3fe2SEd Czeck int status; 6430bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 644727b3fe2SEd Czeck 645727b3fe2SEd Czeck if (ark->started == 0) 64662024eb8SIvan Ilchenko return 0; 647727b3fe2SEd Czeck ark->started = 0; 648b8f5d2aeSThomas Monjalon dev->data->dev_started = 0; 649727b3fe2SEd Czeck 650727b3fe2SEd Czeck /* Stop the extension first */ 651727b3fe2SEd Czeck if (ark->user_ext.dev_stop) 652428046b4SJohn Miller ark->user_ext.dev_stop(dev, 653428046b4SJohn Miller ark->user_data[dev->data->port_id]); 654727b3fe2SEd Czeck 655727b3fe2SEd Czeck /* Stop the packet generator */ 6566799275eSEd Czeck if (!ark->isvf && ark->start_pg && ark->pg_running) { 657727b3fe2SEd Czeck ark_pktgen_pause(ark->pg); 658c7ff3d78SJohn Miller ark->pg_running = 0; 659c7ff3d78SJohn Miller } 660727b3fe2SEd Czeck 661a41f593fSFerruh Yigit dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; 662a41f593fSFerruh Yigit dev->tx_pkt_burst = rte_eth_pkt_burst_dummy; 663727b3fe2SEd Czeck 664f0d33f78SEd Czeck /* Stop RX Side */ 665f0d33f78SEd Czeck for (i = 0; i < dev->data->nb_rx_queues; i++) 666f0d33f78SEd Czeck eth_ark_rx_stop_queue(dev, i); 667f0d33f78SEd Czeck 668727b3fe2SEd Czeck /* STOP TX Side */ 669727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_tx_queues; i++) { 670727b3fe2SEd Czeck status = eth_ark_tx_queue_stop(dev, i); 671727b3fe2SEd Czeck if (status != 0) { 672f8244c63SZhiyong Yang uint16_t port = dev->data->port_id; 6731502d443SEd Czeck ARK_PMD_LOG(ERR, 674727b3fe2SEd Czeck "tx_queue stop anomaly" 675727b3fe2SEd Czeck " port %u, queue %u\n", 676727b3fe2SEd Czeck port, i); 677727b3fe2SEd Czeck } 678727b3fe2SEd Czeck } 679727b3fe2SEd Czeck 680727b3fe2SEd Czeck ark_udm_dump_stats(ark->udm.v, "Post stop"); 681727b3fe2SEd Czeck 68222862a02SJohn Miller for (i = 0; i < dev->data->nb_rx_queues; i++) 683727b3fe2SEd Czeck eth_ark_rx_dump_queue(dev, i, __func__); 684727b3fe2SEd Czeck 685727b3fe2SEd Czeck /* Stop the packet checker if it is running */ 6866799275eSEd Czeck if (!ark->isvf && ark->start_pg) { 687727b3fe2SEd Czeck ark_pktchkr_dump_stats(ark->pc); 688727b3fe2SEd Czeck ark_pktchkr_stop(ark->pc); 689727b3fe2SEd Czeck } 69062024eb8SIvan Ilchenko 69162024eb8SIvan Ilchenko return 0; 692727b3fe2SEd Czeck } 693727b3fe2SEd Czeck 694b142387bSThomas Monjalon static int 695727b3fe2SEd Czeck eth_ark_dev_close(struct rte_eth_dev *dev) 696727b3fe2SEd Czeck { 6970bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 698727b3fe2SEd Czeck uint16_t i; 699727b3fe2SEd Czeck 70030410493SThomas Monjalon if (rte_eal_process_type() != RTE_PROC_PRIMARY) 70130410493SThomas Monjalon return 0; 70230410493SThomas Monjalon 703727b3fe2SEd Czeck if (ark->user_ext.dev_close) 704428046b4SJohn Miller ark->user_ext.dev_close(dev, 705428046b4SJohn Miller ark->user_data[dev->data->port_id]); 706727b3fe2SEd Czeck 707727b3fe2SEd Czeck eth_ark_dev_stop(dev); 708727b3fe2SEd Czeck 709727b3fe2SEd Czeck /* 710f0d33f78SEd Czeck * This should only be called once for the device during shutdown 711727b3fe2SEd Czeck */ 712c5314a53SJohn Miller if (ark->rqpacing) 713727b3fe2SEd Czeck ark_rqp_dump(ark->rqpacing); 714727b3fe2SEd Czeck 7156799275eSEd Czeck /* return to power-on state */ 7166799275eSEd Czeck if (ark->pd) 7176799275eSEd Czeck ark_pktdir_setup(ark->pd, ARK_PKT_DIR_INIT_VAL); 7186799275eSEd Czeck 719727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_tx_queues; i++) { 720727b3fe2SEd Czeck eth_ark_tx_queue_release(dev->data->tx_queues[i]); 721727b3fe2SEd Czeck dev->data->tx_queues[i] = 0; 722727b3fe2SEd Czeck } 723727b3fe2SEd Czeck 724727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_rx_queues; i++) { 725727b3fe2SEd Czeck eth_ark_dev_rx_queue_release(dev->data->rx_queues[i]); 726727b3fe2SEd Czeck dev->data->rx_queues[i] = 0; 727727b3fe2SEd Czeck } 728c5ddc9b9SEd Czeck 729b142387bSThomas Monjalon return 0; 730727b3fe2SEd Czeck } 731727b3fe2SEd Czeck 732bdad90d1SIvan Ilchenko static int 7331131cbf0SEd Czeck eth_ark_dev_info_get(struct rte_eth_dev *dev, 7341131cbf0SEd Czeck struct rte_eth_dev_info *dev_info) 7351131cbf0SEd Czeck { 7360bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 737727b3fe2SEd Czeck struct ark_mpu_t *tx_mpu = RTE_PTR_ADD(ark->bar0, ARK_MPU_TX_BASE); 738727b3fe2SEd Czeck struct ark_mpu_t *rx_mpu = RTE_PTR_ADD(ark->bar0, ARK_MPU_RX_BASE); 739727b3fe2SEd Czeck uint16_t ports = ark->num_ports; 740727b3fe2SEd Czeck 7411131cbf0SEd Czeck dev_info->max_rx_pktlen = ARK_RX_MAX_PKT_LEN; 7421131cbf0SEd Czeck dev_info->min_rx_bufsize = ARK_RX_MIN_BUFSIZE; 7431131cbf0SEd Czeck 744727b3fe2SEd Czeck dev_info->max_rx_queues = ark_api_num_queues_per_port(rx_mpu, ports); 745727b3fe2SEd Czeck dev_info->max_tx_queues = ark_api_num_queues_per_port(tx_mpu, ports); 746727b3fe2SEd Czeck 7471131cbf0SEd Czeck dev_info->rx_desc_lim = (struct rte_eth_desc_lim) { 7481131cbf0SEd Czeck .nb_max = ARK_RX_MAX_QUEUE, 7491131cbf0SEd Czeck .nb_min = ARK_RX_MIN_QUEUE, 7501131cbf0SEd Czeck .nb_align = ARK_RX_MIN_QUEUE}; /* power of 2 */ 7511131cbf0SEd Czeck 7521131cbf0SEd Czeck dev_info->tx_desc_lim = (struct rte_eth_desc_lim) { 7531131cbf0SEd Czeck .nb_max = ARK_TX_MAX_QUEUE, 7541131cbf0SEd Czeck .nb_min = ARK_TX_MIN_QUEUE, 7551131cbf0SEd Czeck .nb_align = ARK_TX_MIN_QUEUE}; /* power of 2 */ 7561131cbf0SEd Czeck 7571131cbf0SEd Czeck /* ARK PMD supports all line rates, how do we indicate that here ?? */ 758295968d1SFerruh Yigit dev_info->speed_capa = (RTE_ETH_LINK_SPEED_1G | 759295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_10G | 760295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_25G | 761295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_40G | 762295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_50G | 763295968d1SFerruh Yigit RTE_ETH_LINK_SPEED_100G); 764bdad90d1SIvan Ilchenko 765295968d1SFerruh Yigit dev_info->rx_offload_capa = RTE_ETH_RX_OFFLOAD_TIMESTAMP; 766a926951aSThomas Monjalon 767bdad90d1SIvan Ilchenko return 0; 7681131cbf0SEd Czeck } 7691131cbf0SEd Czeck 770727b3fe2SEd Czeck static int 771727b3fe2SEd Czeck eth_ark_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete) 772727b3fe2SEd Czeck { 7731502d443SEd Czeck ARK_PMD_LOG(DEBUG, "link status = %d\n", 774727b3fe2SEd Czeck dev->data->dev_link.link_status); 7750bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 776727b3fe2SEd Czeck 777727b3fe2SEd Czeck if (ark->user_ext.link_update) { 778727b3fe2SEd Czeck return ark->user_ext.link_update 779727b3fe2SEd Czeck (dev, wait_to_complete, 780428046b4SJohn Miller ark->user_data[dev->data->port_id]); 781727b3fe2SEd Czeck } 782727b3fe2SEd Czeck return 0; 783727b3fe2SEd Czeck } 784727b3fe2SEd Czeck 785727b3fe2SEd Czeck static int 786727b3fe2SEd Czeck eth_ark_dev_set_link_up(struct rte_eth_dev *dev) 787727b3fe2SEd Czeck { 788727b3fe2SEd Czeck dev->data->dev_link.link_status = 1; 7890bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 790727b3fe2SEd Czeck 791727b3fe2SEd Czeck if (ark->user_ext.dev_set_link_up) 792428046b4SJohn Miller return ark->user_ext.dev_set_link_up(dev, 793428046b4SJohn Miller ark->user_data[dev->data->port_id]); 794727b3fe2SEd Czeck return 0; 795727b3fe2SEd Czeck } 796727b3fe2SEd Czeck 797727b3fe2SEd Czeck static int 798727b3fe2SEd Czeck eth_ark_dev_set_link_down(struct rte_eth_dev *dev) 799727b3fe2SEd Czeck { 800727b3fe2SEd Czeck dev->data->dev_link.link_status = 0; 8010bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 802727b3fe2SEd Czeck 803727b3fe2SEd Czeck if (ark->user_ext.dev_set_link_down) 804428046b4SJohn Miller return ark->user_ext.dev_set_link_down(dev, 805428046b4SJohn Miller ark->user_data[dev->data->port_id]); 806727b3fe2SEd Czeck return 0; 807727b3fe2SEd Czeck } 808727b3fe2SEd Czeck 809d5b0924bSMatan Azrad static int 810727b3fe2SEd Czeck eth_ark_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 811727b3fe2SEd Czeck { 812727b3fe2SEd Czeck uint16_t i; 8130bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 814727b3fe2SEd Czeck 815727b3fe2SEd Czeck stats->ipackets = 0; 816727b3fe2SEd Czeck stats->ibytes = 0; 817727b3fe2SEd Czeck stats->opackets = 0; 818727b3fe2SEd Czeck stats->obytes = 0; 819727b3fe2SEd Czeck stats->imissed = 0; 820727b3fe2SEd Czeck stats->oerrors = 0; 821727b3fe2SEd Czeck 822727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_tx_queues; i++) 823727b3fe2SEd Czeck eth_tx_queue_stats_get(dev->data->tx_queues[i], stats); 824727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_rx_queues; i++) 825727b3fe2SEd Czeck eth_rx_queue_stats_get(dev->data->rx_queues[i], stats); 826727b3fe2SEd Czeck if (ark->user_ext.stats_get) 827d5b0924bSMatan Azrad return ark->user_ext.stats_get(dev, stats, 828428046b4SJohn Miller ark->user_data[dev->data->port_id]); 829d5b0924bSMatan Azrad return 0; 830727b3fe2SEd Czeck } 831727b3fe2SEd Czeck 8329970a9adSIgor Romanov static int 833727b3fe2SEd Czeck eth_ark_dev_stats_reset(struct rte_eth_dev *dev) 834727b3fe2SEd Czeck { 835727b3fe2SEd Czeck uint16_t i; 8360bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 837727b3fe2SEd Czeck 838727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_tx_queues; i++) 839f588d3a5SJohn Miller eth_tx_queue_stats_reset(dev->data->tx_queues[i]); 840727b3fe2SEd Czeck for (i = 0; i < dev->data->nb_rx_queues; i++) 841727b3fe2SEd Czeck eth_rx_queue_stats_reset(dev->data->rx_queues[i]); 842727b3fe2SEd Czeck if (ark->user_ext.stats_reset) 843428046b4SJohn Miller ark->user_ext.stats_reset(dev, 844428046b4SJohn Miller ark->user_data[dev->data->port_id]); 8459970a9adSIgor Romanov 8469970a9adSIgor Romanov return 0; 847727b3fe2SEd Czeck } 848727b3fe2SEd Czeck 8496d01e580SWei Dai static int 850727b3fe2SEd Czeck eth_ark_macaddr_add(struct rte_eth_dev *dev, 8516d13ea8eSOlivier Matz struct rte_ether_addr *mac_addr, 852727b3fe2SEd Czeck uint32_t index, 853727b3fe2SEd Czeck uint32_t pool) 854727b3fe2SEd Czeck { 8550bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 856727b3fe2SEd Czeck 8576d01e580SWei Dai if (ark->user_ext.mac_addr_add) { 858727b3fe2SEd Czeck ark->user_ext.mac_addr_add(dev, 859727b3fe2SEd Czeck mac_addr, 860727b3fe2SEd Czeck index, 861727b3fe2SEd Czeck pool, 862428046b4SJohn Miller ark->user_data[dev->data->port_id]); 8636d01e580SWei Dai return 0; 8646d01e580SWei Dai } 8656d01e580SWei Dai return -ENOTSUP; 866727b3fe2SEd Czeck } 867727b3fe2SEd Czeck 868727b3fe2SEd Czeck static void 869727b3fe2SEd Czeck eth_ark_macaddr_remove(struct rte_eth_dev *dev, uint32_t index) 870727b3fe2SEd Czeck { 8710bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 872727b3fe2SEd Czeck 873727b3fe2SEd Czeck if (ark->user_ext.mac_addr_remove) 874428046b4SJohn Miller ark->user_ext.mac_addr_remove(dev, index, 875428046b4SJohn Miller ark->user_data[dev->data->port_id]); 876727b3fe2SEd Czeck } 877727b3fe2SEd Czeck 878caccf8b3SOlivier Matz static int 879727b3fe2SEd Czeck eth_ark_set_default_mac_addr(struct rte_eth_dev *dev, 8806d13ea8eSOlivier Matz struct rte_ether_addr *mac_addr) 881727b3fe2SEd Czeck { 8820bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 883727b3fe2SEd Czeck 884caccf8b3SOlivier Matz if (ark->user_ext.mac_addr_set) { 885428046b4SJohn Miller ark->user_ext.mac_addr_set(dev, mac_addr, 886428046b4SJohn Miller ark->user_data[dev->data->port_id]); 887caccf8b3SOlivier Matz return 0; 888caccf8b3SOlivier Matz } 889caccf8b3SOlivier Matz return -ENOTSUP; 890727b3fe2SEd Czeck } 891727b3fe2SEd Czeck 8929ae74488SJohn Miller static int 8939ae74488SJohn Miller eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t size) 8949ae74488SJohn Miller { 8950bf8b0f1SStephen Hemminger struct ark_adapter *ark = dev->data->dev_private; 8969ae74488SJohn Miller 8979ae74488SJohn Miller if (ark->user_ext.set_mtu) 8989ae74488SJohn Miller return ark->user_ext.set_mtu(dev, size, 8999ae74488SJohn Miller ark->user_data[dev->data->port_id]); 9009ae74488SJohn Miller 9019ae74488SJohn Miller return -ENOTSUP; 9029ae74488SJohn Miller } 9039ae74488SJohn Miller 9041131cbf0SEd Czeck static inline int 9051131cbf0SEd Czeck process_pktdir_arg(const char *key, const char *value, 9061131cbf0SEd Czeck void *extra_args) 9071131cbf0SEd Czeck { 9081502d443SEd Czeck ARK_PMD_LOG(DEBUG, "key = %s, value = %s\n", 9091131cbf0SEd Czeck key, value); 9101131cbf0SEd Czeck struct ark_adapter *ark = 9111131cbf0SEd Czeck (struct ark_adapter *)extra_args; 9121131cbf0SEd Czeck 9131131cbf0SEd Czeck ark->pkt_dir_v = strtol(value, NULL, 16); 9141502d443SEd Czeck ARK_PMD_LOG(DEBUG, "pkt_dir_v = 0x%x\n", ark->pkt_dir_v); 9151131cbf0SEd Czeck return 0; 9161131cbf0SEd Czeck } 9171131cbf0SEd Czeck 9181131cbf0SEd Czeck static inline int 9191131cbf0SEd Czeck process_file_args(const char *key, const char *value, void *extra_args) 9201131cbf0SEd Czeck { 9211502d443SEd Czeck ARK_PMD_LOG(DEBUG, "key = %s, value = %s\n", 9221131cbf0SEd Czeck key, value); 9231131cbf0SEd Czeck char *args = (char *)extra_args; 9241131cbf0SEd Czeck 9251131cbf0SEd Czeck /* Open the configuration file */ 9261131cbf0SEd Czeck FILE *file = fopen(value, "r"); 9271131cbf0SEd Czeck char line[ARK_MAX_ARG_LEN]; 9281131cbf0SEd Czeck int size = 0; 9291131cbf0SEd Czeck int first = 1; 9301131cbf0SEd Czeck 9312f3b88fbSJohn Miller if (file == NULL) { 9321502d443SEd Czeck ARK_PMD_LOG(ERR, "Unable to open " 9332f3b88fbSJohn Miller "config file %s\n", value); 9342f3b88fbSJohn Miller return -1; 9352f3b88fbSJohn Miller } 9362f3b88fbSJohn Miller 9371131cbf0SEd Czeck while (fgets(line, sizeof(line), file)) { 9381131cbf0SEd Czeck size += strlen(line); 9391131cbf0SEd Czeck if (size >= ARK_MAX_ARG_LEN) { 9401502d443SEd Czeck ARK_PMD_LOG(ERR, "Unable to parse file %s args, " 9411131cbf0SEd Czeck "parameter list is too long\n", value); 9421131cbf0SEd Czeck fclose(file); 9431131cbf0SEd Czeck return -1; 9441131cbf0SEd Czeck } 9451131cbf0SEd Czeck if (first) { 9461131cbf0SEd Czeck strncpy(args, line, ARK_MAX_ARG_LEN); 9471131cbf0SEd Czeck first = 0; 9481131cbf0SEd Czeck } else { 9491131cbf0SEd Czeck strncat(args, line, ARK_MAX_ARG_LEN); 9501131cbf0SEd Czeck } 9511131cbf0SEd Czeck } 9521502d443SEd Czeck ARK_PMD_LOG(DEBUG, "file = %s\n", args); 9531131cbf0SEd Czeck fclose(file); 9541131cbf0SEd Czeck return 0; 9551131cbf0SEd Czeck } 9561131cbf0SEd Czeck 9571131cbf0SEd Czeck static int 9581131cbf0SEd Czeck eth_ark_check_args(struct ark_adapter *ark, const char *params) 9591131cbf0SEd Czeck { 9601131cbf0SEd Czeck struct rte_kvargs *kvlist; 9611131cbf0SEd Czeck unsigned int k_idx; 9621131cbf0SEd Czeck struct rte_kvargs_pair *pair = NULL; 9630f31eb0cSFerruh Yigit int ret = -1; 9641131cbf0SEd Czeck 9651131cbf0SEd Czeck kvlist = rte_kvargs_parse(params, valid_arguments); 9661131cbf0SEd Czeck if (kvlist == NULL) 9671131cbf0SEd Czeck return 0; 9681131cbf0SEd Czeck 9691131cbf0SEd Czeck ark->pkt_gen_args[0] = 0; 9701131cbf0SEd Czeck ark->pkt_chkr_args[0] = 0; 9711131cbf0SEd Czeck 9721131cbf0SEd Czeck for (k_idx = 0; k_idx < kvlist->count; k_idx++) { 9731131cbf0SEd Czeck pair = &kvlist->pairs[k_idx]; 9741502d443SEd Czeck ARK_PMD_LOG(DEBUG, "**** Arg passed to PMD = %s:%s\n", 9751131cbf0SEd Czeck pair->key, 9761131cbf0SEd Czeck pair->value); 9771131cbf0SEd Czeck } 9781131cbf0SEd Czeck 9791131cbf0SEd Czeck if (rte_kvargs_process(kvlist, 9801131cbf0SEd Czeck ARK_PKTDIR_ARG, 9811131cbf0SEd Czeck &process_pktdir_arg, 9821131cbf0SEd Czeck ark) != 0) { 9831502d443SEd Czeck ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTDIR_ARG); 9840f31eb0cSFerruh Yigit goto free_kvlist; 9851131cbf0SEd Czeck } 9861131cbf0SEd Czeck 9871131cbf0SEd Czeck if (rte_kvargs_process(kvlist, 9881131cbf0SEd Czeck ARK_PKTGEN_ARG, 9891131cbf0SEd Czeck &process_file_args, 9901131cbf0SEd Czeck ark->pkt_gen_args) != 0) { 9911502d443SEd Czeck ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTGEN_ARG); 9920f31eb0cSFerruh Yigit goto free_kvlist; 9931131cbf0SEd Czeck } 9941131cbf0SEd Czeck 9951131cbf0SEd Czeck if (rte_kvargs_process(kvlist, 9961131cbf0SEd Czeck ARK_PKTCHKR_ARG, 9971131cbf0SEd Czeck &process_file_args, 9981131cbf0SEd Czeck ark->pkt_chkr_args) != 0) { 9991502d443SEd Czeck ARK_PMD_LOG(ERR, "Unable to parse arg %s\n", ARK_PKTCHKR_ARG); 10000f31eb0cSFerruh Yigit goto free_kvlist; 10011131cbf0SEd Czeck } 10021131cbf0SEd Czeck 10036799275eSEd Czeck if (ark->isvf) { 10046799275eSEd Czeck ret = 0; 10056799275eSEd Czeck goto free_kvlist; 10066799275eSEd Czeck } 10071502d443SEd Czeck ARK_PMD_LOG(INFO, "packet director set to 0x%x\n", ark->pkt_dir_v); 1008727b3fe2SEd Czeck /* Setup the packet director */ 1009727b3fe2SEd Czeck ark_pktdir_setup(ark->pd, ark->pkt_dir_v); 1010727b3fe2SEd Czeck 1011727b3fe2SEd Czeck /* Setup the packet generator */ 1012727b3fe2SEd Czeck if (ark->pkt_gen_args[0]) { 10131502d443SEd Czeck ARK_PMD_LOG(DEBUG, "Setting up the packet generator\n"); 1014727b3fe2SEd Czeck ark_pktgen_parse(ark->pkt_gen_args); 1015727b3fe2SEd Czeck ark_pktgen_reset(ark->pg); 1016727b3fe2SEd Czeck ark_pktgen_setup(ark->pg); 1017727b3fe2SEd Czeck ark->start_pg = 1; 1018727b3fe2SEd Czeck } 1019727b3fe2SEd Czeck 1020727b3fe2SEd Czeck /* Setup the packet checker */ 1021727b3fe2SEd Czeck if (ark->pkt_chkr_args[0]) { 1022727b3fe2SEd Czeck ark_pktchkr_parse(ark->pkt_chkr_args); 1023727b3fe2SEd Czeck ark_pktchkr_setup(ark->pc); 1024727b3fe2SEd Czeck } 10251131cbf0SEd Czeck 10260f31eb0cSFerruh Yigit ret = 0; 10270f31eb0cSFerruh Yigit 10280f31eb0cSFerruh Yigit free_kvlist: 10290f31eb0cSFerruh Yigit rte_kvargs_free(kvlist); 10300f31eb0cSFerruh Yigit 10310f31eb0cSFerruh Yigit return ret; 10321131cbf0SEd Czeck } 10331131cbf0SEd Czeck 10341131cbf0SEd Czeck RTE_PMD_REGISTER_PCI(net_ark, rte_ark_pmd); 10351131cbf0SEd Czeck RTE_PMD_REGISTER_KMOD_DEP(net_ark, "* igb_uio | uio_pci_generic "); 10361131cbf0SEd Czeck RTE_PMD_REGISTER_PCI_TABLE(net_ark, pci_id_ark_map); 10371131cbf0SEd Czeck RTE_PMD_REGISTER_PARAM_STRING(net_ark, 10381131cbf0SEd Czeck ARK_PKTGEN_ARG "=<filename> " 10391131cbf0SEd Czeck ARK_PKTCHKR_ARG "=<filename> " 10401131cbf0SEd Czeck ARK_PKTDIR_ARG "=<bitmap>"); 1041eeded204SDavid Marchand RTE_LOG_REGISTER_DEFAULT(ark_logtype, NOTICE); 1042