/* */
/* 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 */
#include <asm/iommu.h>
#include <asm/vio.h>
#include <asm/uaccess.h>
-#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include "ibmveth.h"
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 <larson1@us.ibm.com>");
+MODULE_AUTHOR("Santiago Leon <santil@us.ibm.com>");
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)
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;
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);
adapter->replenish_add_buff_failure++;
break;
} else {
- pool->free_map[free_index] = 0xffff;
buffers_added++;
adapter->replenish_add_buff_success++;
}
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 */
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;
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)
{
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++;
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;
}
adapter = netdev->priv;
memset(adapter, 0, sizeof(adapter));
- dev->driver_data = netdev;
+ dev->dev.driver_data = netdev;
adapter->vdev = dev;
adapter->netdev = netdev;
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);
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);
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);