diff options
author | Sony Chacko <sony.chacko@qlogic.com> | 2012-12-04 03:33:54 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-12-04 18:00:12 (GMT) |
commit | 15087c2b313b57feffcd92695c984a25e0e4eb90 (patch) | |
tree | 32bfadf86deec054d1ee304a0ca7cfb8312041fe | |
parent | 797884509d1f7dffa4fd1028a1f62a19705a518b (diff) | |
download | linux-fsl-qoriq-15087c2b313b57feffcd92695c984a25e0e4eb90.tar.xz |
qlcnic: modify PCI and register access routines
Refactor 82xx driver to support new adapter
Update PCI and hardware access routines
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Sony Chacko <sony.chacko@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h | 40 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 277 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 63 |
4 files changed, 222 insertions, 162 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 352a1e4..528d88c 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -1279,7 +1279,7 @@ struct qlcnic_cmd_args { int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter); int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config); -u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off); +int 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); @@ -1345,7 +1345,7 @@ int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr, int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter); void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter); -void __iomem *qlcnic_get_ioaddr(struct qlcnic_adapter *, u32); +void __iomem *qlcnic_get_ioaddr(struct qlcnic_hardware_context *, u32); int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter); void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h index bd5030e..49cc1ac 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h @@ -816,55 +816,63 @@ enum { #define LSD(x) ((uint32_t)((uint64_t)(x))) #define MSD(x) ((uint32_t)((((uint64_t)(x)) >> 16) >> 16)) +#define QLCNIC_MS_CTRL 0x41000090 +#define QLCNIC_MS_ADDR_LO 0x41000094 +#define QLCNIC_MS_ADDR_HI 0x41000098 +#define QLCNIC_MS_WRTDATA_LO 0x410000A0 +#define QLCNIC_MS_WRTDATA_HI 0x410000A4 +#define QLCNIC_MS_WRTDATA_ULO 0x410000B0 +#define QLCNIC_MS_WRTDATA_UHI 0x410000B4 +#define QLCNIC_MS_RDDATA_LO 0x410000A8 +#define QLCNIC_MS_RDDATA_HI 0x410000AC +#define QLCNIC_MS_RDDATA_ULO 0x410000B8 +#define QLCNIC_MS_RDDATA_UHI 0x410000BC + +#define QLCNIC_TA_WRITE_ENABLE (TA_CTL_ENABLE | TA_CTL_WRITE) +#define QLCNIC_TA_WRITE_START (TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE) +#define QLCNIC_TA_START_ENABLE (TA_CTL_START | TA_CTL_ENABLE) + #define QLCNIC_LEGACY_INTR_CONFIG \ { \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F0, \ .tgt_status_reg = ISR_INT_TARGET_STATUS, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(0) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK, }, \ \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F1, \ .tgt_status_reg = ISR_INT_TARGET_STATUS_F1, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK_F1, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(1) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK_F1, }, \ \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F2, \ .tgt_status_reg = ISR_INT_TARGET_STATUS_F2, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK_F2, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(2) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK_F2, }, \ \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F3, \ .tgt_status_reg = ISR_INT_TARGET_STATUS_F3, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK_F3, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(3) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK_F3, }, \ \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F4, \ .tgt_status_reg = ISR_INT_TARGET_STATUS_F4, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK_F4, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(4) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK_F4, }, \ \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F5, \ .tgt_status_reg = ISR_INT_TARGET_STATUS_F5, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK_F5, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(5) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK_F5, }, \ \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F6, \ .tgt_status_reg = ISR_INT_TARGET_STATUS_F6, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK_F6, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(6) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK_F6, }, \ \ { \ .int_vec_bit = PCIX_INT_VECTOR_BIT_F7, \ .tgt_status_reg = ISR_INT_TARGET_STATUS_F7, \ - .tgt_mask_reg = ISR_INT_TARGET_MASK_F7, \ - .pci_int_reg = ISR_MSI_INT_TRIGGER(7) }, \ + .tgt_mask_reg = ISR_INT_TARGET_MASK_F7, }, \ } /* NIU REGS */ diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index 382c6ac..fc48e00 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -6,6 +6,7 @@ */ #include "qlcnic.h" +#include "qlcnic_hdr.h" #include <linux/slab.h> #include <net/ip.h> @@ -22,6 +23,15 @@ #define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) #define CRB_INDIRECT_2M (0x1e0000UL) +struct qlcnic_ms_reg_ctrl { + u32 ocm_window; + u32 control; + u32 hi; + u32 low; + u32 rd[4]; + u32 wd[4]; + u64 off; +}; #ifndef readq static inline u64 readq(void __iomem *addr) @@ -266,10 +276,44 @@ static const unsigned crb_hub_agt[64] = { 0, }; +static const u32 msi_tgt_status[8] = { + ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1, + ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3, + ISR_INT_TARGET_STATUS_F4, ISR_INT_TARGET_STATUS_F5, + ISR_INT_TARGET_STATUS_F6, ISR_INT_TARGET_STATUS_F7 +}; + /* PCI Windowing for DDR regions. */ #define QLCNIC_PCIE_SEM_TIMEOUT 10000 +static void qlcnic_read_window_reg(u32 addr, void __iomem *bar0, u32 *data) +{ + u32 dest; + void __iomem *val; + + dest = addr & 0xFFFF0000; + val = bar0 + QLCNIC_FW_DUMP_REG1; + writel(dest, val); + readl(val); + val = bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr); + *data = readl(val); +} + +static void qlcnic_write_window_reg(u32 addr, void __iomem *bar0, u32 data) +{ + u32 dest; + void __iomem *val; + + dest = addr & 0xFFFF0000; + val = bar0 + QLCNIC_FW_DUMP_REG1; + writel(dest, val); + readl(val); + val = bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr); + writel(data, val); + readl(val); +} + int qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) { @@ -300,6 +344,23 @@ qlcnic_pcie_sem_unlock(struct qlcnic_adapter *adapter, int sem) QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_UNLOCK(sem))); } +static int qlcnic_ind_rd(struct qlcnic_adapter *adapter, u32 addr) +{ + u32 data; + + if (qlcnic_82xx_check(adapter)) + qlcnic_read_window_reg(addr, adapter->ahw->pci_base0, &data); + else + return -EIO; + return data; +} + +static void qlcnic_ind_wr(struct qlcnic_adapter *adapter, u32 addr, u32 data) +{ + if (qlcnic_82xx_check(adapter)) + qlcnic_write_window_reg(addr, adapter->ahw->pci_base0, data); +} + static int qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, struct cmd_desc_type0 *cmd_desc_arr, int nr_desc) @@ -863,9 +924,8 @@ int qlcnic_set_features(struct net_device *netdev, netdev_features_t features) * 0 if no window access is needed. 'off' is set to 2M addr * In: 'off' is offset from base in 128M pci map */ -static int -qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter, - ulong off, void __iomem **addr) +static int qlcnic_pci_get_crb_addr_2M(struct qlcnic_hardware_context *ahw, + ulong off, void __iomem **addr) { const struct crb_128M_2M_sub_block_map *m; @@ -880,7 +940,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter, m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)]; if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) { - *addr = adapter->ahw->pci_base0 + m->start_2M + + *addr = ahw->pci_base0 + m->start_2M + (off - m->start_128M); return 0; } @@ -888,7 +948,7 @@ qlcnic_pci_get_crb_addr_2M(struct qlcnic_adapter *adapter, /* * Not in direct map, use crb window */ - *addr = adapter->ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16)); + *addr = ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16)); return 1; } @@ -929,7 +989,7 @@ qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data) int rv; void __iomem *addr = NULL; - rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr); + rv = qlcnic_pci_get_crb_addr_2M(adapter->ahw, off, &addr); if (rv == 0) { writel(data, addr); @@ -954,15 +1014,14 @@ qlcnic_hw_write_wx_2M(struct qlcnic_adapter *adapter, ulong off, u32 data) return -EIO; } -u32 -qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) +int qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) { unsigned long flags; int rv; u32 data = -1; void __iomem *addr = NULL; - rv = qlcnic_pci_get_crb_addr_2M(adapter, off, &addr); + rv = qlcnic_pci_get_crb_addr_2M(adapter->ahw, off, &addr); if (rv == 0) return readl(addr); @@ -985,46 +1044,28 @@ qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off) } -void __iomem * -qlcnic_get_ioaddr(struct qlcnic_adapter *adapter, u32 offset) +void __iomem *qlcnic_get_ioaddr(struct qlcnic_hardware_context *ahw, + u32 offset) { void __iomem *addr = NULL; - WARN_ON(qlcnic_pci_get_crb_addr_2M(adapter, offset, &addr)); + WARN_ON(qlcnic_pci_get_crb_addr_2M(ahw, offset, &addr)); return addr; } - -static int -qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter, - u64 addr, u32 *start) -{ - u32 window; - - window = OCM_WIN_P3P(addr); - - writel(window, adapter->ahw->ocm_win_crb); - /* read back to flush */ - readl(adapter->ahw->ocm_win_crb); - - *start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr); - return 0; -} - -static int -qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, - u64 *data, int op) +static int qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, + u32 window, u64 off, u64 *data, int op) { void __iomem *addr; - int ret; u32 start; mutex_lock(&adapter->ahw->mem_lock); - ret = qlcnic_pci_set_window_2M(adapter, off, &start); - if (ret != 0) - goto unlock; + writel(window, adapter->ahw->ocm_win_crb); + /* read back to flush */ + readl(adapter->ahw->ocm_win_crb); + start = QLCNIC_PCI_OCM0_2M + off; addr = adapter->ahw->pci_base0 + start; @@ -1033,10 +1074,12 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, else /* write */ writeq(*data, addr); -unlock: - mutex_unlock(&adapter->ahw->mem_lock); + /* Set window to 0 */ + writel(0, adapter->ahw->ocm_win_crb); + readl(adapter->ahw->ocm_win_crb); - return ret; + mutex_unlock(&adapter->ahw->mem_lock); + return 0; } void @@ -1061,52 +1104,74 @@ qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data) mutex_unlock(&adapter->ahw->mem_lock); } -int -qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, - u64 off, u64 data) + + +/* Set MS memory control data for different adapters */ +static void qlcnic_set_ms_controls(struct qlcnic_adapter *adapter, u64 off, + struct qlcnic_ms_reg_ctrl *ms) +{ + ms->control = QLCNIC_MS_CTRL; + ms->low = QLCNIC_MS_ADDR_LO; + ms->hi = QLCNIC_MS_ADDR_HI; + if (off & 0xf) { + ms->wd[0] = QLCNIC_MS_WRTDATA_LO; + ms->rd[0] = QLCNIC_MS_RDDATA_LO; + ms->wd[1] = QLCNIC_MS_WRTDATA_HI; + ms->rd[1] = QLCNIC_MS_RDDATA_HI; + ms->wd[2] = QLCNIC_MS_WRTDATA_ULO; + ms->wd[3] = QLCNIC_MS_WRTDATA_UHI; + ms->rd[2] = QLCNIC_MS_RDDATA_ULO; + ms->rd[3] = QLCNIC_MS_RDDATA_UHI; + } else { + ms->wd[0] = QLCNIC_MS_WRTDATA_ULO; + ms->rd[0] = QLCNIC_MS_RDDATA_ULO; + ms->wd[1] = QLCNIC_MS_WRTDATA_UHI; + ms->rd[1] = QLCNIC_MS_RDDATA_UHI; + ms->wd[2] = QLCNIC_MS_WRTDATA_LO; + ms->wd[3] = QLCNIC_MS_WRTDATA_HI; + ms->rd[2] = QLCNIC_MS_RDDATA_LO; + ms->rd[3] = QLCNIC_MS_RDDATA_HI; + } + + ms->ocm_window = OCM_WIN_P3P(off); + ms->off = GET_MEM_OFFS_2M(off); +} + +int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data) { - int i, j, ret; + int j, ret = 0; u32 temp, off8; - void __iomem *mem_crb; + struct qlcnic_ms_reg_ctrl ms; /* Only 64-bit aligned access */ if (off & 7) return -EIO; - /* P3 onward, test agent base for MIU and SIU is same */ - if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, - QLCNIC_ADDR_QDR_NET_MAX)) { - mem_crb = qlcnic_get_ioaddr(adapter, - QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); - goto correct; - } + memset(&ms, 0, sizeof(struct qlcnic_ms_reg_ctrl)); + if (!(ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, + QLCNIC_ADDR_QDR_NET_MAX) || + ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, + QLCNIC_ADDR_DDR_NET_MAX))) + return -EIO; - if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) { - mem_crb = qlcnic_get_ioaddr(adapter, - QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE); - goto correct; - } + qlcnic_set_ms_controls(adapter, off, &ms); if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX)) - return qlcnic_pci_mem_access_direct(adapter, off, &data, 1); - - return -EIO; + return qlcnic_pci_mem_access_direct(adapter, ms.ocm_window, + ms.off, &data, 1); -correct: off8 = off & ~0xf; mutex_lock(&adapter->ahw->mem_lock); - writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); - writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); + qlcnic_ind_wr(adapter, ms.low, off8); + qlcnic_ind_wr(adapter, ms.hi, 0); - i = 0; - writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); - writel((TA_CTL_START | TA_CTL_ENABLE), - (mem_crb + TEST_AGT_CTRL)); + qlcnic_ind_wr(adapter, ms.control, TA_CTL_ENABLE); + qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_START_ENABLE); for (j = 0; j < MAX_CTL_CHECK; j++) { - temp = readl(mem_crb + TEST_AGT_CTRL); + temp = qlcnic_ind_rd(adapter, ms.control); if ((temp & TA_CTL_BUSY) == 0) break; } @@ -1116,24 +1181,18 @@ correct: goto done; } - i = (off & 0xf) ? 0 : 2; - writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)), - mem_crb + MIU_TEST_AGT_WRDATA(i)); - writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)), - mem_crb + MIU_TEST_AGT_WRDATA(i+1)); - i = (off & 0xf) ? 2 : 0; - - writel(data & 0xffffffff, - mem_crb + MIU_TEST_AGT_WRDATA(i)); - writel((data >> 32) & 0xffffffff, - mem_crb + MIU_TEST_AGT_WRDATA(i+1)); + /* This is the modify part of read-modify-write */ + qlcnic_ind_wr(adapter, ms.wd[0], qlcnic_ind_rd(adapter, ms.rd[0])); + qlcnic_ind_wr(adapter, ms.wd[1], qlcnic_ind_rd(adapter, ms.rd[1])); + /* This is the write part of read-modify-write */ + qlcnic_ind_wr(adapter, ms.wd[2], data & 0xffffffff); + qlcnic_ind_wr(adapter, ms.wd[3], (data >> 32) & 0xffffffff); - writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL)); - writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE), - (mem_crb + TEST_AGT_CTRL)); + qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_WRITE_ENABLE); + qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_WRITE_START); for (j = 0; j < MAX_CTL_CHECK; j++) { - temp = readl(mem_crb + TEST_AGT_CTRL); + temp = qlcnic_ind_rd(adapter, ms.control); if ((temp & TA_CTL_BUSY) == 0) break; } @@ -1152,52 +1211,41 @@ done: return ret; } -int -qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, - u64 off, u64 *data) +int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data) { int j, ret; u32 temp, off8; u64 val; - void __iomem *mem_crb; + struct qlcnic_ms_reg_ctrl ms; /* Only 64-bit aligned access */ if (off & 7) return -EIO; + if (!(ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, + QLCNIC_ADDR_QDR_NET_MAX) || + ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, + QLCNIC_ADDR_DDR_NET_MAX))) + return -EIO; - /* P3 onward, test agent base for MIU and SIU is same */ - if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, - QLCNIC_ADDR_QDR_NET_MAX)) { - mem_crb = qlcnic_get_ioaddr(adapter, - QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); - goto correct; - } - - if (ADDR_IN_RANGE(off, QLCNIC_ADDR_DDR_NET, QLCNIC_ADDR_DDR_NET_MAX)) { - mem_crb = qlcnic_get_ioaddr(adapter, - QLCNIC_CRB_DDR_NET+MIU_TEST_AGT_BASE); - goto correct; - } + memset(&ms, 0, sizeof(struct qlcnic_ms_reg_ctrl)); + qlcnic_set_ms_controls(adapter, off, &ms); - if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX)) { - return qlcnic_pci_mem_access_direct(adapter, - off, data, 0); - } + if (ADDR_IN_RANGE(off, QLCNIC_ADDR_OCM0, QLCNIC_ADDR_OCM0_MAX)) + return qlcnic_pci_mem_access_direct(adapter, ms.ocm_window, + ms.off, data, 0); - return -EIO; + mutex_lock(&adapter->ahw->mem_lock); -correct: off8 = off & ~0xf; - mutex_lock(&adapter->ahw->mem_lock); + qlcnic_ind_wr(adapter, ms.low, off8); + qlcnic_ind_wr(adapter, ms.hi, 0); - writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO)); - writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); - writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); - writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL)); + qlcnic_ind_wr(adapter, ms.control, TA_CTL_ENABLE); + qlcnic_ind_wr(adapter, ms.control, QLCNIC_TA_START_ENABLE); for (j = 0; j < MAX_CTL_CHECK; j++) { - temp = readl(mem_crb + TEST_AGT_CTRL); + temp = qlcnic_ind_rd(adapter, ms.control); if ((temp & TA_CTL_BUSY) == 0) break; } @@ -1208,13 +1256,10 @@ correct: "failed to read through agent\n"); ret = -EIO; } else { - off8 = MIU_TEST_AGT_RDDATA_LO; - if (off & 0xf) - off8 = MIU_TEST_AGT_RDDATA_UPPER_LO; - temp = readl(mem_crb + off8 + 4); + temp = qlcnic_ind_rd(adapter, ms.rd[3]); val = (u64)temp << 32; - val |= readl(mem_crb + off8); + val |= qlcnic_ind_rd(adapter, ms.rd[2]); *data = val; ret = 0; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index c03c760..747e16b 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -283,32 +283,31 @@ static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) return err; } - static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) { + u32 offset, mask_reg; const struct qlcnic_legacy_intr_set *legacy_intrp; + struct qlcnic_hardware_context *ahw = adapter->ahw; struct pci_dev *pdev = adapter->pdev; if (use_msi && !pci_enable_msi(pdev)) { adapter->flags |= QLCNIC_MSI_ENABLED; - adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter, - msi_tgt_status[adapter->ahw->pci_func]); + offset = msi_tgt_status[adapter->ahw->pci_func]; + adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter->ahw, + offset); dev_info(&pdev->dev, "using msi interrupts\n"); adapter->msix_entries[0].vector = pdev->irq; return; } legacy_intrp = &legacy_intr[adapter->ahw->pci_func]; - adapter->ahw->int_vec_bit = legacy_intrp->int_vec_bit; - adapter->tgt_status_reg = qlcnic_get_ioaddr(adapter, - legacy_intrp->tgt_status_reg); - adapter->tgt_mask_reg = qlcnic_get_ioaddr(adapter, - legacy_intrp->tgt_mask_reg); - adapter->isr_int_vec = qlcnic_get_ioaddr(adapter, ISR_INT_VECTOR); - - adapter->crb_int_state_reg = qlcnic_get_ioaddr(adapter, - ISR_INT_STATE_REG); + offset = legacy_intrp->tgt_status_reg; + adapter->tgt_status_reg = qlcnic_get_ioaddr(ahw, offset); + mask_reg = legacy_intrp->tgt_mask_reg; + adapter->tgt_mask_reg = qlcnic_get_ioaddr(ahw, mask_reg); + adapter->isr_int_vec = qlcnic_get_ioaddr(ahw, ISR_INT_VECTOR); + adapter->crb_int_state_reg = qlcnic_get_ioaddr(ahw, ISR_INT_STATE_REG); dev_info(&pdev->dev, "using legacy interrupts\n"); adapter->msix_entries[0].vector = pdev->irq; } @@ -480,20 +479,32 @@ qlcnic_check_vf(struct qlcnic_adapter *adapter) adapter->nic_ops = &qlcnic_ops; } -static int -qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) +#define QLCNIC_82XX_BAR0_LENGTH 0x00200000UL +static void qlcnic_get_bar_length(u32 dev_id, ulong *bar) +{ + switch (dev_id) { + case PCI_DEVICE_ID_QLOGIC_QLE824X: + *bar = QLCNIC_82XX_BAR0_LENGTH; + break; + default: + *bar = 0; + } +} + +static int qlcnic_setup_pci_map(struct pci_dev *pdev, + struct qlcnic_hardware_context *ahw) { + u32 offset; void __iomem *mem_ptr0 = NULL; resource_size_t mem_base; - unsigned long mem_len, pci_len0 = 0; - - struct pci_dev *pdev = adapter->pdev; + unsigned long mem_len, pci_len0 = 0, bar0_len; /* remap phys address */ mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ mem_len = pci_resource_len(pdev, 0); - if (mem_len == QLCNIC_PCI_2MB_SIZE) { + qlcnic_get_bar_length(pdev->device, &bar0_len); + if (mem_len >= bar0_len) { mem_ptr0 = pci_ioremap_bar(pdev, 0); if (mem_ptr0 == NULL) { @@ -506,15 +517,10 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) } dev_info(&pdev->dev, "%dMB memory map\n", (int)(mem_len>>20)); - - adapter->ahw->pci_base0 = mem_ptr0; - adapter->ahw->pci_len0 = pci_len0; - - qlcnic_check_vf(adapter); - - adapter->ahw->ocm_win_crb = qlcnic_get_ioaddr(adapter, - QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG( - adapter->ahw->pci_func))); + ahw->pci_base0 = mem_ptr0; + ahw->pci_len0 = pci_len0; + offset = QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(ahw->pci_func)); + qlcnic_get_ioaddr(ahw, offset); return 0; } @@ -1510,9 +1516,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) spin_lock_init(&adapter->tx_clean_lock); INIT_LIST_HEAD(&adapter->mac_list); - err = qlcnic_setup_pci_map(adapter); + err = qlcnic_setup_pci_map(pdev, adapter->ahw); if (err) goto err_out_free_hw; + qlcnic_check_vf(adapter); /* This will be reset for mezz cards */ adapter->portnum = adapter->ahw->pci_func; |