Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvar...
[pandora-kernel.git] / drivers / net / netxen / netxen_nic_main.c
index b665b42..6ce6ce1 100644 (file)
@@ -2537,51 +2537,81 @@ static int
 netxen_sysfs_validate_crb(struct netxen_adapter *adapter,
                loff_t offset, size_t size)
 {
+       size_t crb_size = 4;
+
        if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
                return -EIO;
 
-       if ((size != 4) || (offset & 0x3))
-               return  -EINVAL;
+       if (offset < NETXEN_PCI_CRBSPACE) {
+               if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+                       return -EINVAL;
 
-       if (offset < NETXEN_PCI_CRBSPACE)
-               return -EINVAL;
+               if (ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
+                                               NETXEN_PCI_CAMQM_2M_END))
+                       crb_size = 8;
+               else
+                       return -EINVAL;
+       }
+
+       if ((size != crb_size) || (offset & (crb_size-1)))
+               return  -EINVAL;
 
        return 0;
 }
 
 static ssize_t
-netxen_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr,
+netxen_sysfs_read_crb(struct file *filp, struct kobject *kobj,
+               struct bin_attribute *attr,
                char *buf, loff_t offset, size_t size)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
        struct netxen_adapter *adapter = dev_get_drvdata(dev);
        u32 data;
+       u64 qmdata;
        int ret;
 
        ret = netxen_sysfs_validate_crb(adapter, offset, size);
        if (ret != 0)
                return ret;
 
-       data = NXRD32(adapter, offset);
-       memcpy(buf, &data, size);
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id) &&
+               ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
+                                       NETXEN_PCI_CAMQM_2M_END)) {
+               netxen_pci_camqm_read_2M(adapter, offset, &qmdata);
+               memcpy(buf, &qmdata, size);
+       } else {
+               data = NXRD32(adapter, offset);
+               memcpy(buf, &data, size);
+       }
+
        return size;
 }
 
 static ssize_t
-netxen_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr,
+netxen_sysfs_write_crb(struct file *filp, struct kobject *kobj,
+               struct bin_attribute *attr,
                char *buf, loff_t offset, size_t size)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
        struct netxen_adapter *adapter = dev_get_drvdata(dev);
        u32 data;
+       u64 qmdata;
        int ret;
 
        ret = netxen_sysfs_validate_crb(adapter, offset, size);
        if (ret != 0)
                return ret;
 
-       memcpy(&data, buf, size);
-       NXWR32(adapter, offset, data);
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id) &&
+               ADDR_IN_RANGE(offset, NETXEN_PCI_CAMQM,
+                                       NETXEN_PCI_CAMQM_2M_END)) {
+               memcpy(&qmdata, buf, size);
+               netxen_pci_camqm_write_2M(adapter, offset, qmdata);
+       } else {
+               memcpy(&data, buf, size);
+               NXWR32(adapter, offset, data);
+       }
+
        return size;
 }
 
@@ -2599,7 +2629,8 @@ netxen_sysfs_validate_mem(struct netxen_adapter *adapter,
 }
 
 static ssize_t
-netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr,
+netxen_sysfs_read_mem(struct file *filp, struct kobject *kobj,
+               struct bin_attribute *attr,
                char *buf, loff_t offset, size_t size)
 {
        struct device *dev = container_of(kobj, struct device, kobj);
@@ -2619,7 +2650,7 @@ netxen_sysfs_read_mem(struct kobject *kobj, struct bin_attribute *attr,
        return size;
 }
 
-static ssize_t netxen_sysfs_write_mem(struct kobject *kobj,
+static ssize_t netxen_sysfs_write_mem(struct file *filp, struct kobject *kobj,
                struct bin_attribute *attr, char *buf,
                loff_t offset, size_t size)
 {
@@ -2753,7 +2784,6 @@ netxen_config_indev_addr(struct net_device *dev, unsigned long event)
        } endfor_ifa(indev);
 
        in_dev_put(indev);
-       return;
 }
 
 static int netxen_netdev_event(struct notifier_block *this,