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

Commit 897e8c7c authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller
Browse files

qlcnic: handle queue manager access



Check the access by tools for hardware queue engine and handle it
separately than other block registers, otherwise incorrect data
is returned.

Signed-off-by: default avatarDhananjay Phadke <dhananjay.phadke@qlogic.com>
Signed-off-by: default avatarAmit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0bc92b5b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -994,6 +994,11 @@ u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off);
int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data);
int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *, u64 off, u64 data);
int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *, u64 off, u64 *data);
void qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *, u64, u64 *);
void qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *, u64, u64);

#define ADDR_IN_RANGE(addr, low, high)	\
	(((addr) < (high)) && ((addr) >= (low)))

#define QLCRD32(adapter, off) \
	(qlcnic_hw_read_wx_2M(adapter, off))
+2 −1
Original line number Diff line number Diff line
@@ -435,9 +435,10 @@ enum {
#define QLCNIC_PCI_MS_2M	(0x80000)
#define QLCNIC_PCI_OCM0_2M	(0x000c0000UL)
#define QLCNIC_PCI_CRBSPACE	(0x06000000UL)
#define QLCNIC_PCI_CAMQM	(0x04800000UL)
#define QLCNIC_PCI_CAMQM_END	(0x04800800UL)
#define QLCNIC_PCI_2MB_SIZE	(0x00200000UL)
#define QLCNIC_PCI_CAMQM_2M_BASE	(0x000ff800UL)
#define QLCNIC_PCI_CAMQM_2M_END 	(0x04800800UL)

#define QLCNIC_CRB_CAM	QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_CAM)

+22 −3
Original line number Diff line number Diff line
@@ -53,9 +53,6 @@ static inline void writeq(u64 val, void __iomem *addr)
}
#endif

#define ADDR_IN_RANGE(addr, low, high)	\
	(((addr) < (high)) && ((addr) >= (low)))

#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
	((adapter)->ahw.pci_base0 + (off))

@@ -936,6 +933,28 @@ unlock:
	return ret;
}

void
qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data)
{
	void __iomem *addr = adapter->ahw.pci_base0 +
		QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);

	mutex_lock(&adapter->ahw.mem_lock);
	*data = readq(addr);
	mutex_unlock(&adapter->ahw.mem_lock);
}

void
qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data)
{
	void __iomem *addr = adapter->ahw.pci_base0 +
		QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);

	mutex_lock(&adapter->ahw.mem_lock);
	writeq(data, addr);
	mutex_unlock(&adapter->ahw.mem_lock);
}

#define MAX_CTL_CHECK   1000

int
+27 −8
Original line number Diff line number Diff line
@@ -2386,13 +2386,20 @@ static int
qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
		loff_t offset, size_t size)
{
	size_t crb_size = 4;

	if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
		return -EIO;

	if ((size != 4) || (offset & 0x3))
	if (offset < QLCNIC_PCI_CRBSPACE) {
		if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM,
					QLCNIC_PCI_CAMQM_END))
			crb_size = 8;
		else
			return -EINVAL;
	}

	if (offset < QLCNIC_PCI_CRBSPACE)
	if ((size != crb_size) || (offset & (crb_size-1)))
		return  -EINVAL;

	return 0;
@@ -2405,14 +2412,20 @@ qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr,
	struct device *dev = container_of(kobj, struct device, kobj);
	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
	u32 data;
	u64 qmdata;
	int ret;

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

	if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
		qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata);
		memcpy(buf, &qmdata, size);
	} else {
		data = QLCRD32(adapter, offset);
		memcpy(buf, &data, size);
	}
	return size;
}

@@ -2423,14 +2436,20 @@ qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr,
	struct device *dev = container_of(kobj, struct device, kobj);
	struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
	u32 data;
	u64 qmdata;
	int ret;

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

	if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) {
		memcpy(&qmdata, buf, size);
		qlcnic_pci_camqm_write_2M(adapter, offset, qmdata);
	} else {
		memcpy(&data, buf, size);
		QLCWR32(adapter, offset, data);
	}
	return size;
}