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_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_write_2M(struct qlcnic_adapter *, u64 off, u64 data);
|
||||||
int qlcnic_pci_mem_read_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) \
|
#define QLCRD32(adapter, off) \
|
||||||
(qlcnic_hw_read_wx_2M(adapter, off))
|
(qlcnic_hw_read_wx_2M(adapter, off))
|
||||||
|
@ -435,9 +435,10 @@ enum {
|
|||||||
#define QLCNIC_PCI_MS_2M (0x80000)
|
#define QLCNIC_PCI_MS_2M (0x80000)
|
||||||
#define QLCNIC_PCI_OCM0_2M (0x000c0000UL)
|
#define QLCNIC_PCI_OCM0_2M (0x000c0000UL)
|
||||||
#define QLCNIC_PCI_CRBSPACE (0x06000000UL)
|
#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_2MB_SIZE (0x00200000UL)
|
||||||
#define QLCNIC_PCI_CAMQM_2M_BASE (0x000ff800UL)
|
#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)
|
#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
|
#endif
|
||||||
|
|
||||||
#define ADDR_IN_RANGE(addr, low, high) \
|
|
||||||
(((addr) < (high)) && ((addr) >= (low)))
|
|
||||||
|
|
||||||
#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
|
#define PCI_OFFSET_FIRST_RANGE(adapter, off) \
|
||||||
((adapter)->ahw.pci_base0 + (off))
|
((adapter)->ahw.pci_base0 + (off))
|
||||||
|
|
||||||
@ -936,6 +933,28 @@ unlock:
|
|||||||
return ret;
|
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
|
#define MAX_CTL_CHECK 1000
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -2386,13 +2386,20 @@ static int
|
|||||||
qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
|
qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
|
||||||
loff_t offset, size_t size)
|
loff_t offset, size_t size)
|
||||||
{
|
{
|
||||||
|
size_t crb_size = 4;
|
||||||
|
|
||||||
if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
|
if (!(adapter->flags & QLCNIC_DIAG_ENABLED))
|
||||||
return -EIO;
|
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;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (offset < QLCNIC_PCI_CRBSPACE)
|
if ((size != crb_size) || (offset & (crb_size-1)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
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 device *dev = container_of(kobj, struct device, kobj);
|
||||||
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
|
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
|
||||||
u32 data;
|
u32 data;
|
||||||
|
u64 qmdata;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
|
ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
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);
|
data = QLCRD32(adapter, offset);
|
||||||
memcpy(buf, &data, size);
|
memcpy(buf, &data, size);
|
||||||
|
}
|
||||||
return 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 device *dev = container_of(kobj, struct device, kobj);
|
||||||
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
|
struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
|
||||||
u32 data;
|
u32 data;
|
||||||
|
u64 qmdata;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
|
ret = qlcnic_sysfs_validate_crb(adapter, offset, size);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
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);
|
memcpy(&data, buf, size);
|
||||||
QLCWR32(adapter, offset, data);
|
QLCWR32(adapter, offset, data);
|
||||||
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user