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

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
......@@ -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))
......
......@@ -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)
......
......@@ -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 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off,
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
......
......@@ -2386,14 +2386,21 @@ 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))
return -EINVAL;
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)
return -EINVAL;
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;
data = QLCRD32(adapter, offset);
memcpy(buf, &data, size);
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;
memcpy(&data, buf, size);
QLCWR32(adapter, offset, data);
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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment