Ejemplo n.º 1
0
static int ibmveth_set_features(struct net_device *dev,
	netdev_features_t features)
{
	struct ibmveth_adapter *adapter = netdev_priv(dev);
	int rx_csum = !!(features & NETIF_F_RXCSUM);
	int large_send = !!(features & (NETIF_F_TSO | NETIF_F_TSO6));
	int rc1 = 0, rc2 = 0;

	if (rx_csum != adapter->rx_csum) {
		rc1 = ibmveth_set_csum_offload(dev, rx_csum);
		if (rc1 && !adapter->rx_csum)
			dev->features =
				features & ~(NETIF_F_CSUM_MASK |
					     NETIF_F_RXCSUM);
	}

	if (large_send != adapter->large_send) {
		rc2 = ibmveth_set_tso(dev, large_send);
		if (rc2 && !adapter->large_send)
			dev->features =
				features & ~(NETIF_F_TSO | NETIF_F_TSO6);
	}

	return rc1 ? rc1 : rc2;
}
Ejemplo n.º 2
0
static int ibmveth_set_rx_csum(struct net_device *dev, u32 data)
{
	struct ibmveth_adapter *adapter = netdev_priv(dev);

	if ((data && adapter->rx_csum) || (!data && !adapter->rx_csum))
		return 0;

	return ibmveth_set_csum_offload(dev, data, ibmveth_set_rx_csum_flags);
}
Ejemplo n.º 3
0
static int ibmveth_set_features(struct net_device *dev, u32 features)
{
	struct ibmveth_adapter *adapter = netdev_priv(dev);
	int rx_csum = !!(features & NETIF_F_RXCSUM);
	int rc;

	if (rx_csum == adapter->rx_csum)
		return 0;

	rc = ibmveth_set_csum_offload(dev, rx_csum);
	if (rc && !adapter->rx_csum)
		dev->features = features & ~(NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);

	return rc;
}
Ejemplo n.º 4
0
static int ibmveth_set_tx_csum(struct net_device *dev, u32 data)
{
	struct ibmveth_adapter *adapter = netdev_priv(dev);
	int rc = 0;

	if (data && (dev->features & NETIF_F_IP_CSUM))
		return 0;
	if (!data && !(dev->features & NETIF_F_IP_CSUM))
		return 0;

	if (data && !adapter->rx_csum)
		rc = ibmveth_set_csum_offload(dev, data, ibmveth_set_tx_csum_flags);
	else
		ibmveth_set_tx_csum_flags(dev, data);

	return rc;
}
Ejemplo n.º 5
0
static int __devinit ibmveth_probe(struct vio_dev *dev,
				   const struct vio_device_id *id)
{
	int rc, i;
	struct net_device *netdev;
	struct ibmveth_adapter *adapter;
	unsigned char *mac_addr_p;
	unsigned int *mcastFilterSize_p;

	dev_dbg(&dev->dev, "entering ibmveth_probe for UA 0x%x\n",
		dev->unit_address);

	mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR,
							NULL);
	if (!mac_addr_p) {
		dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n");
		return -EINVAL;
	}

	mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev,
						VETH_MCAST_FILTER_SIZE, NULL);
	if (!mcastFilterSize_p) {
		dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE "
			"attribute\n");
		return -EINVAL;
	}

	netdev = alloc_etherdev(sizeof(struct ibmveth_adapter));

	if (!netdev)
		return -ENOMEM;

	adapter = netdev_priv(netdev);
	dev_set_drvdata(&dev->dev, netdev);

	adapter->vdev = dev;
	adapter->netdev = netdev;
	adapter->mcastFilterSize = *mcastFilterSize_p;
	adapter->pool_config = 0;

	netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);

	/*
	 * Some older boxes running PHYP non-natively have an OF that returns
	 * a 8-byte local-mac-address field (and the first 2 bytes have to be
	 * ignored) while newer boxes' OF return a 6-byte field. Note that
	 * IEEE 1275 specifies that local-mac-address must be a 6-byte field.
	 * The RPA doc specifies that the first byte must be 10b, so we'll
	 * just look for it to solve this 8 vs. 6 byte field issue
	 */
	if ((*mac_addr_p & 0x3) != 0x02)
		mac_addr_p += 2;

	adapter->mac_addr = 0;
	memcpy(&adapter->mac_addr, mac_addr_p, 6);

	netdev->irq = dev->irq;
	netdev->netdev_ops = &ibmveth_netdev_ops;
	netdev->ethtool_ops = &netdev_ethtool_ops;
	SET_NETDEV_DEV(netdev, &dev->dev);
	netdev->features |= NETIF_F_SG;

	memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);

	for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) {
		struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
		int error;

		ibmveth_init_buffer_pool(&adapter->rx_buff_pool[i], i,
					 pool_count[i], pool_size[i],
					 pool_active[i]);
		error = kobject_init_and_add(kobj, &ktype_veth_pool,
					     &dev->dev.kobj, "pool%d", i);
		if (!error)
			kobject_uevent(kobj, KOBJ_ADD);
	}

	netdev_dbg(netdev, "adapter @ 0x%p\n", adapter);

	adapter->buffer_list_dma = DMA_ERROR_CODE;
	adapter->filter_list_dma = DMA_ERROR_CODE;
	adapter->rx_queue.queue_dma = DMA_ERROR_CODE;

	netdev_dbg(netdev, "registering netdev...\n");

	ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags);

	rc = register_netdev(netdev);

	if (rc) {
		netdev_dbg(netdev, "failed to register netdev rc=%d\n", rc);
		free_netdev(netdev);
		return rc;
	}

	netdev_dbg(netdev, "registered\n");

	return 0;
}