X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fibmveth.c;h=be0729dfb5a9747e7d3c2f1882aa2253a3bbacc2;hb=87fc8d1bb10cd459024a742c6a10961fefcef18f;hp=c3836f6de58c91f5330ca004e68238ab7bb278bc;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index c3836f6de..be0729dfb 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -2,8 +2,8 @@ /* */ /* IBM eServer i/pSeries Virtual Ethernet Device Driver */ /* Copyright (C) 2003 IBM Corp. */ -/* Dave Larson (larson1@us.ibm.com) */ -/* Santiago Leon (santil@us.ibm.com) */ +/* Originally written by Dave Larson (larson1@us.ibm.com) */ +/* Maintained by Santiago Leon (santil@us.ibm.com) */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -55,7 +55,6 @@ #include #include #include -#include #include #include "ibmveth.h" @@ -105,11 +104,12 @@ static struct proc_dir_entry *ibmveth_proc_dir; static const char ibmveth_driver_name[] = "ibmveth"; static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver"; -static const char ibmveth_driver_version[] = "1.0"; +#define ibmveth_driver_version "1.02" -MODULE_AUTHOR("Dave Larson "); +MODULE_AUTHOR("Santiago Leon "); MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); MODULE_LICENSE("GPL"); +MODULE_VERSION(ibmveth_driver_version); /* simple methods of getting data from the current rxq entry */ static inline int ibmveth_rxq_pending_buffer(struct ibmveth_adapter *adapter) @@ -214,11 +214,12 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc free_index = pool->consumer_index++ % pool->size; index = pool->free_map[free_index]; - ibmveth_assert(index != 0xffff); + ibmveth_assert(index != IBM_VETH_INVALID_MAP); ibmveth_assert(pool->skbuff[index] == NULL); dma_addr = vio_map_single(adapter->vdev, skb->data, pool->buff_size, DMA_FROM_DEVICE); + pool->free_map[free_index] = IBM_VETH_INVALID_MAP; pool->dma_addr[index] = dma_addr; pool->skbuff[index] = skb; @@ -233,6 +234,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); if(lpar_rc != H_Success) { + pool->free_map[free_index] = IBM_VETH_INVALID_MAP; pool->skbuff[index] = NULL; pool->consumer_index--; vio_unmap_single(adapter->vdev, pool->dma_addr[index], pool->buff_size, DMA_FROM_DEVICE); @@ -240,7 +242,6 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc adapter->replenish_add_buff_failure++; break; } else { - pool->free_map[free_index] = 0xffff; buffers_added++; adapter->replenish_add_buff_success++; } @@ -270,7 +271,6 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); atomic_inc(&adapter->not_replenishing); - ibmveth_assert(atomic_read(&adapter->not_replenishing) == 1); } /* kick the replenish tasklet if we need replenishing and it isn't already running */ @@ -529,7 +529,7 @@ static int ibmveth_open(struct net_device *netdev) ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc); do { rc = h_free_logical_lan(adapter->vdev->unit_address); - } while H_isLongBusy(rc); + } while (H_isLongBusy(rc) || (rc == H_Busy)); ibmveth_cleanup(adapter); return rc; @@ -561,7 +561,7 @@ static int ibmveth_close(struct net_device *netdev) do { lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); - } while H_isLongBusy(lpar_rc); + } while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy)); if(lpar_rc != H_Success) { @@ -733,6 +733,8 @@ static int ibmveth_poll(struct net_device *netdev, int *budget) if(ibmveth_rxq_pending_buffer(adapter)) { struct sk_buff *skb; + rmb(); + if(!ibmveth_rxq_buffer_valid(adapter)) { wmb(); /* suggested by larson1 */ adapter->rx_invalid_buffer++; @@ -874,22 +876,25 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ struct net_device *netdev; struct ibmveth_adapter *adapter; - unsigned int *mac_addr_p; + unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n", dev->unit_address); - mac_addr_p = (unsigned int *) vio_get_attribute(dev, VETH_MAC_ADDR, 0); + mac_addr_p = (unsigned char *) vio_get_attribute(dev, VETH_MAC_ADDR, 0); if(!mac_addr_p) { - ibmveth_error_printk("Can't find VETH_MAC_ADDR attribute\n"); + printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find VETH_MAC_ADDR " + "attribute\n", __FILE__, __LINE__); return 0; } mcastFilterSize_p= (unsigned int *) vio_get_attribute(dev, VETH_MCAST_FILTER_SIZE, 0); if(!mcastFilterSize_p) { - ibmveth_error_printk("Can't find VETH_MCAST_FILTER_SIZE attribute\n"); + printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find " + "VETH_MCAST_FILTER_SIZE attribute\n", + __FILE__, __LINE__); return 0; } @@ -902,7 +907,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ adapter = netdev->priv; memset(adapter, 0, sizeof(adapter)); - dev->driver_data = netdev; + dev->dev.driver_data = netdev; adapter->vdev = dev; adapter->netdev = netdev; @@ -916,8 +921,8 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ 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 */ - while (*((char*)mac_addr_p) != (char)(0x02)) - ((char*)mac_addr_p)++; + if ((*mac_addr_p & 0x3) != 0x02) + mac_addr_p += 2; adapter->mac_addr = 0; memcpy(&adapter->mac_addr, mac_addr_p, 6); @@ -935,6 +940,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev->do_ioctl = ibmveth_ioctl; netdev->ethtool_ops = &netdev_ethtool_ops; netdev->change_mtu = ibmveth_change_mtu; + SET_NETDEV_DEV(netdev, &dev->dev); memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); @@ -971,7 +977,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ static int __devexit ibmveth_remove(struct vio_dev *dev) { - struct net_device *netdev = dev->driver_data; + struct net_device *netdev = dev->dev.driver_data; struct ibmveth_adapter *adapter = netdev->priv; unregister_netdev(netdev);