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: Dhananjay Phadke <dhananjay.phadke@qlogic.com> Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
0bc92b5b49
commit
897e8c7c45
|
@ -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 @@ 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue