X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgbe%2Fcxgbevf_ethdev.c;h=60e96aa4e4a2700862fe00567715e965dc401629;hb=c3318f529c28e8320ac43f86f214f93e2190445d;hp=7d5b8c07f244bc83ac7064a360d3a32e55116b21;hpb=011ebc236ddcee6c2d82771333faaf5bbb289143;p=dpdk.git diff --git a/drivers/net/cxgbe/cxgbevf_ethdev.c b/drivers/net/cxgbe/cxgbevf_ethdev.c index 7d5b8c07f2..60e96aa4e4 100644 --- a/drivers/net/cxgbe/cxgbevf_ethdev.c +++ b/drivers/net/cxgbe/cxgbevf_ethdev.c @@ -28,7 +28,50 @@ /* *... and the PCI ID Table itself ... */ -#include "t4_pci_id_tbl.h" +#include "base/t4_pci_id_tbl.h" + +/* + * Get port statistics. + */ +static int cxgbevf_dev_stats_get(struct rte_eth_dev *eth_dev, + struct rte_eth_stats *eth_stats) +{ + struct port_info *pi = eth_dev->data->dev_private; + struct adapter *adapter = pi->adapter; + struct sge *s = &adapter->sge; + struct port_stats ps; + unsigned int i; + + cxgbevf_stats_get(pi, &ps); + + /* RX Stats */ + eth_stats->ierrors = ps.rx_len_err; + + /* TX Stats */ + eth_stats->opackets = ps.tx_bcast_frames + ps.tx_mcast_frames + + ps.tx_ucast_frames; + eth_stats->obytes = ps.tx_octets; + eth_stats->oerrors = ps.tx_drop; + + for (i = 0; i < pi->n_rx_qsets; i++) { + struct sge_eth_rxq *rxq = + &s->ethrxq[pi->first_qset + i]; + + eth_stats->q_ipackets[i] = rxq->stats.pkts; + eth_stats->q_ibytes[i] = rxq->stats.rx_bytes; + eth_stats->ipackets += eth_stats->q_ipackets[i]; + eth_stats->ibytes += eth_stats->q_ibytes[i]; + } + + for (i = 0; i < pi->n_tx_qsets; i++) { + struct sge_eth_txq *txq = + &s->ethtxq[pi->first_qset + i]; + + eth_stats->q_opackets[i] = txq->stats.pkts; + eth_stats->q_obytes[i] = txq->stats.tx_bytes; + } + return 0; +} static const struct eth_dev_ops cxgbevf_eth_dev_ops = { .dev_start = cxgbe_dev_start, @@ -42,6 +85,8 @@ static const struct eth_dev_ops cxgbevf_eth_dev_ops = { .dev_infos_get = cxgbe_dev_info_get, .dev_supported_ptypes_get = cxgbe_dev_supported_ptypes_get, .link_update = cxgbe_dev_link_update, + .dev_set_link_up = cxgbe_dev_set_link_up, + .dev_set_link_down = cxgbe_dev_set_link_down, .mtu_set = cxgbe_dev_mtu_set, .tx_queue_setup = cxgbe_dev_tx_queue_setup, .tx_queue_start = cxgbe_dev_tx_queue_start, @@ -51,6 +96,8 @@ static const struct eth_dev_ops cxgbevf_eth_dev_ops = { .rx_queue_start = cxgbe_dev_rx_queue_start, .rx_queue_stop = cxgbe_dev_rx_queue_stop, .rx_queue_release = cxgbe_dev_rx_queue_release, + .stats_get = cxgbevf_dev_stats_get, + .mac_addr_set = cxgbe_mac_addr_set, }; /* @@ -59,12 +106,84 @@ static const struct eth_dev_ops cxgbevf_eth_dev_ops = { */ static int eth_cxgbevf_dev_init(struct rte_eth_dev *eth_dev) { + struct port_info *pi = eth_dev->data->dev_private; + struct rte_pci_device *pci_dev; + char name[RTE_ETH_NAME_MAX_LEN]; + struct adapter *adapter = NULL; + int err = 0; + CXGBE_FUNC_TRACE(); eth_dev->dev_ops = &cxgbevf_eth_dev_ops; + eth_dev->rx_pkt_burst = &cxgbe_recv_pkts; + eth_dev->tx_pkt_burst = &cxgbe_xmit_pkts; + pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + + /* for secondary processes, we attach to ethdevs allocated by primary + * and do minimal initialization. + */ + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + int i; + + for (i = 1; i < MAX_NPORTS; i++) { + struct rte_eth_dev *rest_eth_dev; + char namei[RTE_ETH_NAME_MAX_LEN]; + + snprintf(namei, sizeof(namei), "%s_%d", + pci_dev->device.name, i); + rest_eth_dev = rte_eth_dev_attach_secondary(namei); + if (rest_eth_dev) { + rest_eth_dev->device = &pci_dev->device; + rest_eth_dev->dev_ops = + eth_dev->dev_ops; + rest_eth_dev->rx_pkt_burst = + eth_dev->rx_pkt_burst; + rest_eth_dev->tx_pkt_burst = + eth_dev->tx_pkt_burst; + rte_eth_dev_probing_finish(rest_eth_dev); + } + } + return 0; + } + + snprintf(name, sizeof(name), "cxgbevfadapter%d", + eth_dev->data->port_id); + adapter = rte_zmalloc(name, sizeof(*adapter), 0); + if (!adapter) + return -1; + + adapter->use_unpacked_mode = 1; + adapter->regs = (void *)pci_dev->mem_resource[0].addr; + if (!adapter->regs) { + dev_err(adapter, "%s: cannot map device registers\n", __func__); + err = -ENOMEM; + goto out_free_adapter; + } + adapter->pdev = pci_dev; + adapter->eth_dev = eth_dev; + pi->adapter = adapter; + err = cxgbevf_probe(adapter); + if (err) { + dev_err(adapter, "%s: cxgbevf probe failed with err %d\n", + __func__, err); + goto out_free_adapter; + } + + return 0; + +out_free_adapter: + rte_free(adapter); + return err; +} + +static int eth_cxgbevf_dev_uninit(struct rte_eth_dev *eth_dev) +{ + struct port_info *pi = eth_dev->data->dev_private; + struct adapter *adap = pi->adapter; - /* XXX: Do probe */ - return -EIO; + /* Free up other ports and all resources */ + cxgbe_close(adap); + return 0; } static int eth_cxgbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, @@ -76,7 +195,7 @@ static int eth_cxgbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, static int eth_cxgbevf_pci_remove(struct rte_pci_device *pci_dev) { - return rte_eth_dev_pci_generic_remove(pci_dev, NULL); + return rte_eth_dev_pci_generic_remove(pci_dev, eth_cxgbevf_dev_uninit); } static struct rte_pci_driver rte_cxgbevf_pmd = {