Ejemplo n.º 1
0
/*
 * Stop device: disable rx and tx functions to allow for reconfiguring.
 */
static void
vmxnet3_dev_stop(struct rte_eth_dev *dev)
{
	struct rte_eth_link link;
	struct vmxnet3_hw *hw = dev->data->dev_private;

	PMD_INIT_FUNC_TRACE();

	if (hw->adapter_stopped == 1) {
		PMD_INIT_LOG(DEBUG, "Device already closed.");
		return;
	}

	/* disable interrupts */
	vmxnet3_disable_intr(hw);

	/* quiesce the device first */
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAL, 0);
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAH, 0);

	/* reset the device */
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
	PMD_INIT_LOG(DEBUG, "Device reset.");
	hw->adapter_stopped = 0;

	vmxnet3_dev_clear_queues(dev);

	/* Clear recorded link status */
	memset(&link, 0, sizeof(link));
	vmxnet3_dev_atomic_write_link_status(dev, &link);
}
Ejemplo n.º 2
0
/*
 * Configure device link speed and setup link.
 * Must be called after eth_vmxnet3_dev_init. Other wise it might fail
 * It returns 0 on success.
 */
static int
vmxnet3_dev_start(struct rte_eth_dev *dev)
{
	int status, ret;
	struct vmxnet3_hw *hw = dev->data->dev_private;

	PMD_INIT_FUNC_TRACE();

	ret = vmxnet3_setup_driver_shared(dev);
	if (ret != VMXNET3_SUCCESS)
		return ret;

	/* Exchange shared data with device */
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAL,
			       VMXNET3_GET_ADDR_LO(hw->sharedPA));
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_DSAH,
			       VMXNET3_GET_ADDR_HI(hw->sharedPA));

	/* Activate device by register write */
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_ACTIVATE_DEV);
	status = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);

	if (status != 0) {
		PMD_INIT_LOG(ERR, "Device activation: UNSUCCESSFUL");
		return -1;
	}

	/* Disable interrupts */
	vmxnet3_disable_intr(hw);

	/*
	 * Load RX queues with blank mbufs and update next2fill index for device
	 * Update RxMode of the device
	 */
	ret = vmxnet3_dev_rxtx_init(dev);
	if (ret != VMXNET3_SUCCESS) {
		PMD_INIT_LOG(ERR, "Device receive init: UNSUCCESSFUL");
		return ret;
	}

	/* Setting proper Rx Mode and issue Rx Mode Update command */
	vmxnet3_dev_set_rxmode(hw, VMXNET3_RXM_UCAST | VMXNET3_RXM_BCAST, 1);

	/*
	 * Don't need to handle events for now
	 */
#if PROCESS_SYS_EVENTS == 1
	events = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_ECR);
	PMD_INIT_LOG(DEBUG, "Reading events: 0x%X", events);
	vmxnet3_process_events(hw);
#endif
	return status;
}
Ejemplo n.º 3
0
static void
vmxnet3_get_ethtool_stats(struct net_device *netdev,
                          struct ethtool_stats *stats, u64  *buf)
{
    struct vmxnet3_adapter *adapter = netdev_priv(netdev);
    u8 *base;
    int i;

    VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);

    /* this does assume each counter is 64-bit wide */

    base = (u8 *)&adapter->tqd_start->stats;
    for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
        *buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset);

    base = (u8 *)&adapter->tx_queue.stats;
    for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
        *buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset);

    base = (u8 *)&adapter->rqd_start->stats;
    for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
        *buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset);

    base = (u8 *)&adapter->rx_queue.stats;
    for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
        *buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset);

    base = (u8 *)adapter;
    for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
        *buf++ = *(u64 *)(base + vmxnet3_global_stats[i].offset);
}
Ejemplo n.º 4
0
static void
vmxnet3_write_mac(struct vmxnet3_hw *hw, const uint8_t *addr)
{
	uint32_t val;

	PMD_INIT_LOG(DEBUG,
		     "Writing MAC Address : %02x:%02x:%02x:%02x:%02x:%02x",
		     addr[0], addr[1], addr[2],
		     addr[3], addr[4], addr[5]);

	val = *(const uint32_t *)addr;
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_MACL, val);

	val = (addr[5] << 8) | addr[4];
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_MACH, val);
}
static int
vmxnet3_set_rss_indir(struct net_device *netdev,
		      const struct ethtool_rxfh_indir *p)
{
	unsigned int i;
	unsigned long flags;
	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
	struct UPT1_RSSConf *rssConf = adapter->rss_conf;

	if (p->size != rssConf->indTableSize)
		return -EINVAL;
	for (i = 0; i < rssConf->indTableSize; i++) {
		/*
		 * Return with error code if any of the queue indices
		 * is out of range
		 */
		if (p->ring_index[i] < 0 ||
		    p->ring_index[i] >= adapter->num_rx_queues)
			return -EINVAL;
	}

	for (i = 0; i < rssConf->indTableSize; i++)
		rssConf->indTable[i] = p->ring_index[i];

	spin_lock_irqsave(&adapter->cmd_lock, flags);
	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
			       VMXNET3_CMD_UPDATE_RSSIDT);
	spin_unlock_irqrestore(&adapter->cmd_lock, flags);

	return 0;

}
static int
vmxnet3_set_flags(struct net_device *netdev, u32 data)
{
	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
	u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
	u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
	unsigned long flags;

	if (data & ~ETH_FLAG_LRO)
		return -EOPNOTSUPP;

	if (lro_requested ^ lro_present) {
		/* toggle the LRO feature*/
		netdev->features ^= NETIF_F_LRO;

		/* update harware LRO capability accordingly */
		if (lro_requested)
			adapter->shared->devRead.misc.uptFeatures |=
							UPT1_F_LRO;
		else
			adapter->shared->devRead.misc.uptFeatures &=
							~UPT1_F_LRO;
		spin_lock_irqsave(&adapter->cmd_lock, flags);
		VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
				       VMXNET3_CMD_UPDATE_FEATURE);
		spin_unlock_irqrestore(&adapter->cmd_lock, flags);
	}
	return 0;
}
Ejemplo n.º 7
0
struct net_device_stats *
vmxnet3_get_stats(struct net_device *netdev)
{
	struct vmxnet3_adapter *adapter;
	struct vmxnet3_tq_driver_stats *drvTxStats;
	struct vmxnet3_rq_driver_stats *drvRxStats;
	struct UPT1_TxStats *devTxStats;
	struct UPT1_RxStats *devRxStats;
	struct net_device_stats *net_stats = &netdev->stats;
	unsigned long flags;
	int i;

	adapter = netdev_priv(netdev);

	/* Collect the dev stats into the shared area */
	spin_lock_irqsave(&adapter->cmd_lock, flags);
	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
	spin_unlock_irqrestore(&adapter->cmd_lock, flags);

	memset(net_stats, 0, sizeof(*net_stats));
	for (i = 0; i < adapter->num_tx_queues; i++) {
		devTxStats = &adapter->tqd_start[i].stats;
		drvTxStats = &adapter->tx_queue[i].stats;
		net_stats->tx_packets += devTxStats->ucastPktsTxOK +
					devTxStats->mcastPktsTxOK +
					devTxStats->bcastPktsTxOK;
		net_stats->tx_bytes += devTxStats->ucastBytesTxOK +
				      devTxStats->mcastBytesTxOK +
				      devTxStats->bcastBytesTxOK;
		net_stats->tx_errors += devTxStats->pktsTxError;
		net_stats->tx_dropped += drvTxStats->drop_total;
	}

	for (i = 0; i < adapter->num_rx_queues; i++) {
		devRxStats = &adapter->rqd_start[i].stats;
		drvRxStats = &adapter->rx_queue[i].stats;
		net_stats->rx_packets += devRxStats->ucastPktsRxOK +
					devRxStats->mcastPktsRxOK +
					devRxStats->bcastPktsRxOK;

		net_stats->rx_bytes += devRxStats->ucastBytesRxOK +
				      devRxStats->mcastBytesRxOK +
				      devRxStats->bcastBytesRxOK;

		net_stats->rx_errors += devRxStats->pktsRxError;
		net_stats->rx_dropped += drvRxStats->drop_total;
		net_stats->multicast +=  devRxStats->mcastPktsRxOK;
	}
	return net_stats;
}
Ejemplo n.º 8
0
struct net_device_stats *
vmxnet3_get_stats(struct net_device *netdev)
{
    struct vmxnet3_adapter *adapter;
    struct vmxnet3_tq_driver_stats *drvTxStats;
    struct vmxnet3_rq_driver_stats *drvRxStats;
    struct UPT1_TxStats *devTxStats;
    struct UPT1_RxStats *devRxStats;
    struct net_device_stats *net_stats = &netdev->stats;

    adapter = netdev_priv(netdev);

    /* Collect the dev stats into the shared area */
    VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);

    /* Assuming that we have a single queue device */
    devTxStats = &adapter->tqd_start->stats;
    devRxStats = &adapter->rqd_start->stats;

    /* Get access to the driver stats per queue */
    drvTxStats = &adapter->tx_queue.stats;
    drvRxStats = &adapter->rx_queue.stats;

    memset(net_stats, 0, sizeof(*net_stats));

    net_stats->rx_packets = devRxStats->ucastPktsRxOK +
                            devRxStats->mcastPktsRxOK +
                            devRxStats->bcastPktsRxOK;

    net_stats->tx_packets = devTxStats->ucastPktsTxOK +
                            devTxStats->mcastPktsTxOK +
                            devTxStats->bcastPktsTxOK;

    net_stats->rx_bytes = devRxStats->ucastBytesRxOK +
                          devRxStats->mcastBytesRxOK +
                          devRxStats->bcastBytesRxOK;

    net_stats->tx_bytes = devTxStats->ucastBytesTxOK +
                          devTxStats->mcastBytesTxOK +
                          devTxStats->bcastBytesTxOK;

    net_stats->rx_errors = devRxStats->pktsRxError;
    net_stats->tx_errors = devTxStats->pktsTxError;
    net_stats->rx_dropped = drvRxStats->drop_total;
    net_stats->tx_dropped = drvTxStats->drop_total;
    net_stats->multicast =  devRxStats->mcastPktsRxOK;

    return net_stats;
}
Ejemplo n.º 9
0
static void
vmxnet3_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
	unsigned int i;
	struct vmxnet3_hw *hw = dev->data->dev_private;

	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);

	RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_TX_QUEUES);
	for (i = 0; i < hw->num_tx_queues; i++) {
		struct UPT1_TxStats *txStats = &hw->tqd_start[i].stats;

		stats->q_opackets[i] = txStats->ucastPktsTxOK +
			txStats->mcastPktsTxOK +
			txStats->bcastPktsTxOK;
		stats->q_obytes[i] = txStats->ucastBytesTxOK +
			txStats->mcastBytesTxOK +
			txStats->bcastBytesTxOK;

		stats->opackets += stats->q_opackets[i];
		stats->obytes += stats->q_obytes[i];
		stats->oerrors += txStats->pktsTxError +
			txStats->pktsTxDiscard;
	}

	RTE_BUILD_BUG_ON(RTE_ETHDEV_QUEUE_STAT_CNTRS < VMXNET3_MAX_RX_QUEUES);
	for (i = 0; i < hw->num_rx_queues; i++) {
		struct UPT1_RxStats *rxStats = &hw->rqd_start[i].stats;

		stats->q_ipackets[i] = rxStats->ucastPktsRxOK +
			rxStats->mcastPktsRxOK +
			rxStats->bcastPktsRxOK;

		stats->q_ibytes[i] = rxStats->ucastBytesRxOK +
			rxStats->mcastBytesRxOK +
			rxStats->bcastBytesRxOK;

		stats->ipackets += stats->q_ipackets[i];
		stats->ibytes += stats->q_ibytes[i];

		stats->q_errors[i] = rxStats->pktsRxError;
		stats->ierrors += rxStats->pktsRxError;
		stats->rx_nombuf += rxStats->pktsRxOutOfBuf;
	}
}
Ejemplo n.º 10
0
static void
vmxnet3_get_ethtool_stats(struct net_device *netdev,
			  struct ethtool_stats *stats, u64  *buf)
{
	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
	unsigned long flags;
	u8 *base;
	int i;
	int j = 0;

	spin_lock_irqsave(&adapter->cmd_lock, flags);
	VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
	spin_unlock_irqrestore(&adapter->cmd_lock, flags);

	/* this does assume each counter is 64-bit wide */
	for (j = 0; j < adapter->num_tx_queues; j++) {
		base = (u8 *)&adapter->tqd_start[j].stats;
		*buf++ = (u64)j;
		for (i = 1; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
			*buf++ = *(u64 *)(base +
					  vmxnet3_tq_dev_stats[i].offset);

		base = (u8 *)&adapter->tx_queue[j].stats;
		for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
			*buf++ = *(u64 *)(base +
					  vmxnet3_tq_driver_stats[i].offset);
	}

	for (j = 0; j < adapter->num_tx_queues; j++) {
		base = (u8 *)&adapter->rqd_start[j].stats;
		*buf++ = (u64) j;
		for (i = 1; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
			*buf++ = *(u64 *)(base +
					  vmxnet3_rq_dev_stats[i].offset);

		base = (u8 *)&adapter->rx_queue[j].stats;
		for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
			*buf++ = *(u64 *)(base +
					  vmxnet3_rq_driver_stats[i].offset);
	}

	base = (u8 *)adapter;
	for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
		*buf++ = *(u64 *)(base + vmxnet3_global_stats[i].offset);
}
Ejemplo n.º 11
0
static int
vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
{
    struct vmxnet3_adapter *adapter = netdev_priv(netdev);

    if (adapter->rxcsum != val) {
        adapter->rxcsum = val;
        if (netif_running(netdev)) {
            if (val)
                adapter->shared->devRead.misc.uptFeatures |=
                    UPT1_F_RXCSUM;
            else
                adapter->shared->devRead.misc.uptFeatures &=
                    ~UPT1_F_RXCSUM;

            VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                                   VMXNET3_CMD_UPDATE_FEATURE);
        }
    }
    return 0;
}
Ejemplo n.º 12
0
static int
vmxnet3_set_flags(struct net_device *netdev, u32 data) {
	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
	u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
	u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
 
	if (lro_requested ^ lro_present) {
		/* toggle the LRO feature*/
		netdev->features ^= NETIF_F_LRO;
 
		/* update harware LRO capability accordingly */
		if (lro_requested)
			adapter->shared->devRead.misc.uptFeatures |=
						cpu_to_le64(UPT1_F_LRO);
		else
			adapter->shared->devRead.misc.uptFeatures &=
						cpu_to_le64(~UPT1_F_LRO);
		VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
				       VMXNET3_CMD_UPDATE_FEATURE);
	}
	return 0;
}
Ejemplo n.º 13
0
static int
vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
{
	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
	unsigned long flags;

	if (adapter->rxcsum != val) {
		adapter->rxcsum = val;
		if (netif_running(netdev)) {
			if (val)
				adapter->shared->devRead.misc.uptFeatures |=
				UPT1_F_RXCSUM;
			else
				adapter->shared->devRead.misc.uptFeatures &=
				~UPT1_F_RXCSUM;

			spin_lock_irqsave(&adapter->cmd_lock, flags);
			VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
					       VMXNET3_CMD_UPDATE_FEATURE);
			spin_unlock_irqrestore(&adapter->cmd_lock, flags);
		}
	}
	return 0;
}
Ejemplo n.º 14
0
/*
 * It returns 0 on success.
 */
static int
eth_vmxnet3_dev_init(struct rte_eth_dev *eth_dev)
{
	struct rte_pci_device *pci_dev;
	struct vmxnet3_hw *hw = eth_dev->data->dev_private;
	uint32_t mac_hi, mac_lo, ver;

	PMD_INIT_FUNC_TRACE();

	eth_dev->dev_ops = &vmxnet3_eth_dev_ops;
	eth_dev->rx_pkt_burst = &vmxnet3_recv_pkts;
	eth_dev->tx_pkt_burst = &vmxnet3_xmit_pkts;
	pci_dev = eth_dev->pci_dev;

	/*
	 * for secondary processes, we don't initialize any further as primary
	 * has already done this work.
	 */
	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
		return 0;

	rte_eth_copy_pci_info(eth_dev, pci_dev);

	/* Vendor and Device ID need to be set before init of shared code */
	hw->device_id = pci_dev->id.device_id;
	hw->vendor_id = pci_dev->id.vendor_id;
	hw->hw_addr0 = (void *)pci_dev->mem_resource[0].addr;
	hw->hw_addr1 = (void *)pci_dev->mem_resource[1].addr;

	hw->num_rx_queues = 1;
	hw->num_tx_queues = 1;
	hw->bufs_per_pkt = 1;

	/* Check h/w version compatibility with driver. */
	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_VRRS);
	PMD_INIT_LOG(DEBUG, "Hardware version : %d", ver);
	if (ver & 0x1)
		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_VRRS, 1);
	else {
		PMD_INIT_LOG(ERR, "Incompatible h/w version, should be 0x1");
		return -EIO;
	}

	/* Check UPT version compatibility with driver. */
	ver = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_UVRS);
	PMD_INIT_LOG(DEBUG, "UPT hardware version : %d", ver);
	if (ver & 0x1)
		VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_UVRS, 1);
	else {
		PMD_INIT_LOG(ERR, "Incompatible UPT version.");
		return -EIO;
	}

	/* Getting MAC Address */
	mac_lo = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_MACL);
	mac_hi = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_MACH);
	memcpy(hw->perm_addr  , &mac_lo, 4);
	memcpy(hw->perm_addr+4, &mac_hi, 2);

	/* Allocate memory for storing MAC addresses */
	eth_dev->data->mac_addrs = rte_zmalloc("vmxnet3", ETHER_ADDR_LEN *
					       VMXNET3_MAX_MAC_ADDRS, 0);
	if (eth_dev->data->mac_addrs == NULL) {
		PMD_INIT_LOG(ERR,
			     "Failed to allocate %d bytes needed to store MAC addresses",
			     ETHER_ADDR_LEN * VMXNET3_MAX_MAC_ADDRS);
		return -ENOMEM;
	}
	/* Copy the permanent MAC address */
	ether_addr_copy((struct ether_addr *) hw->perm_addr,
			&eth_dev->data->mac_addrs[0]);

	PMD_INIT_LOG(DEBUG, "MAC Address : %02x:%02x:%02x:%02x:%02x:%02x",
		     hw->perm_addr[0], hw->perm_addr[1], hw->perm_addr[2],
		     hw->perm_addr[3], hw->perm_addr[4], hw->perm_addr[5]);

	/* Put device in Quiesce Mode */
	VMXNET3_WRITE_BAR1_REG(hw, VMXNET3_REG_CMD, VMXNET3_CMD_QUIESCE_DEV);

	/* allow untagged pkts */
	VMXNET3_SET_VFTABLE_ENTRY(hw->shadow_vfta, 0);

	return 0;
}