diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index b665b420a4f2..6ce6ce1df6d2 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -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, |