diff options
author | Dhananjay Phadke <dhananjay.phadke@qlogic.com> | 2010-04-01 15:01:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-03 17:19:13 -0400 |
commit | 897e8c7c450dac2912b677c6e6bf8b04aa5bdf72 (patch) | |
tree | 9bd6fa9ef5c643e08c17847871703f8b0deafead /drivers/net/qlcnic | |
parent | 0bc92b5b4987ab55f2b75ef42251476b2e049e3d (diff) |
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>
Diffstat (limited to 'drivers/net/qlcnic')
-rw-r--r-- | drivers/net/qlcnic/qlcnic.h | 5 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hdr.h | 3 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hw.c | 25 | ||||
-rw-r--r-- | drivers/net/qlcnic/qlcnic_main.c | 35 |
4 files changed, 56 insertions, 12 deletions
diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 0da94b208db1..8a3446df4e90 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h | |||
@@ -994,6 +994,11 @@ u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off); | |||
994 | int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data); | 994 | int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data); |
995 | int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *, u64 off, u64 data); | 995 | int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *, u64 off, u64 data); |
996 | int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *, u64 off, u64 *data); | 996 | int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *, u64 off, u64 *data); |
997 | void qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *, u64, u64 *); | ||
998 | void qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *, u64, u64); | ||
999 | |||
1000 | #define ADDR_IN_RANGE(addr, low, high) \ | ||
1001 | (((addr) < (high)) && ((addr) >= (low))) | ||
997 | 1002 | ||
998 | #define QLCRD32(adapter, off) \ | 1003 | #define QLCRD32(adapter, off) \ |
999 | (qlcnic_hw_read_wx_2M(adapter, off)) | 1004 | (qlcnic_hw_read_wx_2M(adapter, off)) |
diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 0469f84360a4..25465a9a7dd0 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h | |||
@@ -435,9 +435,10 @@ enum { | |||
435 | #define QLCNIC_PCI_MS_2M (0x80000) | 435 | #define QLCNIC_PCI_MS_2M (0x80000) |
436 | #define QLCNIC_PCI_OCM0_2M (0x000c0000UL) | 436 | #define QLCNIC_PCI_OCM0_2M (0x000c0000UL) |
437 | #define QLCNIC_PCI_CRBSPACE (0x06000000UL) | 437 | #define QLCNIC_PCI_CRBSPACE (0x06000000UL) |
438 | #define QLCNIC_PCI_CAMQM (0x04800000UL) | ||
439 | #define QLCNIC_PCI_CAMQM_END (0x04800800UL) | ||
438 | #define QLCNIC_PCI_2MB_SIZE (0x00200000UL) | 440 | #define QLCNIC_PCI_2MB_SIZE (0x00200000UL) |
439 | #define QLCNIC_PCI_CAMQM_2M_BASE (0x000ff800UL) | 441 | #define QLCNIC_PCI_CAMQM_2M_BASE (0x000ff800UL) |
440 | #define QLCNIC_PCI_CAMQM_2M_END (0x04800800UL) | ||
441 | 442 | ||
442 | #define QLCNIC_CRB_CAM QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_CAM) | 443 | #define QLCNIC_CRB_CAM QLCNIC_PCI_CRB_WINDOW(QLCNIC_HW_PX_MAP_CRB_CAM) |
443 | 444 | ||
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index da00e162b6d3..b977874f28ce 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c | |||
@@ -53,9 +53,6 @@ static inline void writeq(u64 val, void __iomem *addr) | |||
53 | } | 53 | } |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | #define ADDR_IN_RANGE(addr, low, high) \ | ||
57 | (((addr) < (high)) && ((addr) >= (low))) | ||
58 | |||
59 | #define PCI_OFFSET_FIRST_RANGE(adapter, off) \ | 56 | #define PCI_OFFSET_FIRST_RANGE(adapter, off) \ |
60 | ((adapter)->ahw.pci_base0 + (off)) | 57 | ((adapter)->ahw.pci_base0 + (off)) |
61 | 58 | ||
@@ -936,6 +933,28 @@ unlock: | |||
936 | return ret; | 933 | return ret; |
937 | } | 934 | } |
938 | 935 | ||
936 | void | ||
937 | qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data) | ||
938 | { | ||
939 | void __iomem *addr = adapter->ahw.pci_base0 + | ||
940 | QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); | ||
941 | |||
942 | mutex_lock(&adapter->ahw.mem_lock); | ||
943 | *data = readq(addr); | ||
944 | mutex_unlock(&adapter->ahw.mem_lock); | ||
945 | } | ||
946 | |||
947 | void | ||
948 | qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data) | ||
949 | { | ||
950 | void __iomem *addr = adapter->ahw.pci_base0 + | ||
951 | QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); | ||
952 | |||
953 | mutex_lock(&adapter->ahw.mem_lock); | ||
954 | writeq(data, addr); | ||
955 | mutex_unlock(&adapter->ahw.mem_lock); | ||
956 | } | ||
957 | |||
939 | #define MAX_CTL_CHECK 1000 | 958 | #define MAX_CTL_CHECK 1000 |
940 | 959 | ||
941 | int | 960 | int |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index fc721564e69e..a2346229312e 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -2386,14 +2386,21 @@ static int | |||
2386 | qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, | 2386 | qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter, |
2387 | loff_t offset, size_t size) | 2387 | loff_t offset, size_t size) |
2388 | { | 2388 | { |
2389 | size_t crb_size = 4; | ||
2390 | |||
2389 | if (!(adapter->flags & QLCNIC_DIAG_ENABLED)) | 2391 | if (!(adapter->flags & QLCNIC_DIAG_ENABLED)) |
2390 | return -EIO; | 2392 | return -EIO; |
2391 | 2393 | ||
2392 | if ((size != 4) || (offset & 0x3)) | 2394 | if (offset < QLCNIC_PCI_CRBSPACE) { |
2393 | return -EINVAL; | 2395 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, |
2396 | QLCNIC_PCI_CAMQM_END)) | ||
2397 | crb_size = 8; | ||
2398 | else | ||
2399 | return -EINVAL; | ||
2400 | } | ||
2394 | 2401 | ||
2395 | if (offset < QLCNIC_PCI_CRBSPACE) | 2402 | if ((size != crb_size) || (offset & (crb_size-1))) |
2396 | return -EINVAL; | 2403 | return -EINVAL; |
2397 | 2404 | ||
2398 | return 0; | 2405 | return 0; |
2399 | } | 2406 | } |
@@ -2405,14 +2412,20 @@ qlcnic_sysfs_read_crb(struct kobject *kobj, struct bin_attribute *attr, | |||
2405 | struct device *dev = container_of(kobj, struct device, kobj); | 2412 | struct device *dev = container_of(kobj, struct device, kobj); |
2406 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 2413 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
2407 | u32 data; | 2414 | u32 data; |
2415 | u64 qmdata; | ||
2408 | int ret; | 2416 | int ret; |
2409 | 2417 | ||
2410 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | 2418 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); |
2411 | if (ret != 0) | 2419 | if (ret != 0) |
2412 | return ret; | 2420 | return ret; |
2413 | 2421 | ||
2414 | data = QLCRD32(adapter, offset); | 2422 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { |
2415 | memcpy(buf, &data, size); | 2423 | qlcnic_pci_camqm_read_2M(adapter, offset, &qmdata); |
2424 | memcpy(buf, &qmdata, size); | ||
2425 | } else { | ||
2426 | data = QLCRD32(adapter, offset); | ||
2427 | memcpy(buf, &data, size); | ||
2428 | } | ||
2416 | return size; | 2429 | return size; |
2417 | } | 2430 | } |
2418 | 2431 | ||
@@ -2423,14 +2436,20 @@ qlcnic_sysfs_write_crb(struct kobject *kobj, struct bin_attribute *attr, | |||
2423 | struct device *dev = container_of(kobj, struct device, kobj); | 2436 | struct device *dev = container_of(kobj, struct device, kobj); |
2424 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); | 2437 | struct qlcnic_adapter *adapter = dev_get_drvdata(dev); |
2425 | u32 data; | 2438 | u32 data; |
2439 | u64 qmdata; | ||
2426 | int ret; | 2440 | int ret; |
2427 | 2441 | ||
2428 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); | 2442 | ret = qlcnic_sysfs_validate_crb(adapter, offset, size); |
2429 | if (ret != 0) | 2443 | if (ret != 0) |
2430 | return ret; | 2444 | return ret; |
2431 | 2445 | ||
2432 | memcpy(&data, buf, size); | 2446 | if (ADDR_IN_RANGE(offset, QLCNIC_PCI_CAMQM, QLCNIC_PCI_CAMQM_END)) { |
2433 | QLCWR32(adapter, offset, data); | 2447 | memcpy(&qmdata, buf, size); |
2448 | qlcnic_pci_camqm_write_2M(adapter, offset, qmdata); | ||
2449 | } else { | ||
2450 | memcpy(&data, buf, size); | ||
2451 | QLCWR32(adapter, offset, data); | ||
2452 | } | ||
2434 | return size; | 2453 | return size; |
2435 | } | 2454 | } |
2436 | 2455 | ||