Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70f9cf89 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller
Browse files

netxen: add sysfs entries for diag tools



Add sysfs entries to enable register and memory access
for diagnostic tools.

Signed-off-by: default avatarNarender Kumar <narender.kumar@qlogic.com>
Signed-off-by: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f03b0ebd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1089,6 +1089,7 @@ typedef struct {
#define NETXEN_NIC_MSIX_ENABLED		0x04
#define NETXEN_NIC_LRO_ENABLED		0x08
#define NETXEN_NIC_BRIDGE_ENABLED       0X10
#define NETXEN_NIC_DIAG_ENABLED		0x20
#define NETXEN_IS_MSI_FAMILY(adapter) \
	((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))

+187 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ static void netxen_nic_poll_controller(struct net_device *netdev);

static void netxen_create_sysfs_entries(struct netxen_adapter *adapter);
static void netxen_remove_sysfs_entries(struct netxen_adapter *adapter);
static void netxen_create_diag_entries(struct netxen_adapter *adapter);
static void netxen_remove_diag_entries(struct netxen_adapter *adapter);

static int nx_decr_dev_ref_cnt(struct netxen_adapter *adapter);
static int netxen_can_start_firmware(struct netxen_adapter *adapter);
@@ -1307,6 +1309,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
		break;
	}

	netxen_create_diag_entries(adapter);

	return 0;

err_out_disable_msi:
@@ -1359,6 +1363,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)

	netxen_teardown_intr(adapter);

	netxen_remove_diag_entries(adapter);

	netxen_cleanup_pci_map(adapter);

	netxen_release_firmware(adapter);
@@ -2331,6 +2337,160 @@ static struct device_attribute dev_attr_bridged_mode = {
       .store = netxen_store_bridged_mode,
};

static ssize_t
netxen_store_diag_mode(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t len)
{
	struct netxen_adapter *adapter = dev_get_drvdata(dev);
	unsigned long new;

	if (strict_strtoul(buf, 2, &new))
		return -EINVAL;

	if (!!new != !!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
		adapter->flags ^= NETXEN_NIC_DIAG_ENABLED;

	return len;
}

static ssize_t
netxen_show_diag_mode(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct netxen_adapter *adapter = dev_get_drvdata(dev);

	return sprintf(buf, "%d\n",
			!!(adapter->flags & NETXEN_NIC_DIAG_ENABLED));
}

static struct device_attribute dev_attr_diag_mode = {
	.attr = {.name = "diag_mode", .mode = (S_IRUGO | S_IWUSR)},
	.show = netxen_show_diag_mode,
	.store = netxen_store_diag_mode,
};

static int
netxen_sysfs_validate_crb(struct netxen_adapter *adapter,
		loff_t offset, size_t size)
{
	if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
		return -EIO;

	if ((size != 4) || (offset & 0x3))
		return  -EINVAL;

	if (offset < NETXEN_PCI_CRBSPACE)
		return -EINVAL;

	return 0;
}

static ssize_t
netxen_sysfs_read_crb(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;
	int ret;

	ret = netxen_sysfs_validate_crb(adapter, offset, size);
	if (ret != 0)
		return ret;

	data = NXRD32(adapter, offset);
	memcpy(buf, &data, size);
	return size;
}

static ssize_t
netxen_sysfs_write_crb(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;
	int ret;

	ret = netxen_sysfs_validate_crb(adapter, offset, size);
	if (ret != 0)
		return ret;

	memcpy(&data, buf, size);
	NXWR32(adapter, offset, data);
	return size;
}

static int
netxen_sysfs_validate_mem(struct netxen_adapter *adapter,
		loff_t offset, size_t size)
{
	if (!(adapter->flags & NETXEN_NIC_DIAG_ENABLED))
		return -EIO;

	if ((size != 8) || (offset & 0x7))
		return  -EIO;

	return 0;
}

static ssize_t
netxen_sysfs_read_mem(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);
	u64 data;
	int ret;

	ret = netxen_sysfs_validate_mem(adapter, offset, size);
	if (ret != 0)
		return ret;

	if (adapter->pci_mem_read(adapter, offset, &data))
		return -EIO;

	memcpy(buf, &data, size);

	return size;
}

ssize_t netxen_sysfs_write_mem(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);
	u64 data;
	int ret;

	ret = netxen_sysfs_validate_mem(adapter, offset, size);
	if (ret != 0)
		return ret;

	memcpy(&data, buf, size);

	if (adapter->pci_mem_write(adapter, offset, data))
		return -EIO;

	return size;
}


static struct bin_attribute bin_attr_crb = {
	.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
	.size = 0,
	.read = netxen_sysfs_read_crb,
	.write = netxen_sysfs_write_crb,
};

static struct bin_attribute bin_attr_mem = {
	.attr = {.name = "mem", .mode = (S_IRUGO | S_IWUSR)},
	.size = 0,
	.read = netxen_sysfs_read_mem,
	.write = netxen_sysfs_write_mem,
};

static void
netxen_create_sysfs_entries(struct netxen_adapter *adapter)
{
@@ -2356,6 +2516,33 @@ netxen_remove_sysfs_entries(struct netxen_adapter *adapter)
		device_remove_file(dev, &dev_attr_bridged_mode);
}

static void
netxen_create_diag_entries(struct netxen_adapter *adapter)
{
	struct pci_dev *pdev = adapter->pdev;
	struct device *dev;

	dev = &pdev->dev;
	if (device_create_file(dev, &dev_attr_diag_mode))
		dev_info(dev, "failed to create diag_mode sysfs entry\n");
	if (device_create_bin_file(dev, &bin_attr_crb))
		dev_info(dev, "failed to create crb sysfs entry\n");
	if (device_create_bin_file(dev, &bin_attr_mem))
		dev_info(dev, "failed to create mem sysfs entry\n");
}


static void
netxen_remove_diag_entries(struct netxen_adapter *adapter)
{
	struct pci_dev *pdev = adapter->pdev;
	struct device *dev = &pdev->dev;

	device_remove_file(dev, &dev_attr_diag_mode);
	device_remove_bin_file(dev, &bin_attr_crb);
	device_remove_bin_file(dev, &bin_attr_mem);
}

#ifdef CONFIG_INET

#define is_netxen_netdev(dev) (dev->netdev_ops == &netxen_netdev_ops)