Skip to content

Commit

Permalink
qlcnic: handle queue manager access
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dhananjay Phadke authored and David S. Miller committed Apr 3, 2010
1 parent 0bc92b5 commit 897e8c7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 12 deletions.
5 changes: 5 additions & 0 deletions drivers/net/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/qlcnic/qlcnic_hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
25 changes: 22 additions & 3 deletions drivers/net/qlcnic/qlcnic_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down Expand Up @@ -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
Expand Down
35 changes: 27 additions & 8 deletions drivers/net/qlcnic/qlcnic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down

0 comments on commit 897e8c7

Please sign in to comment.