Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15087c2b authored by Sony Chacko's avatar Sony Chacko Committed by David S. Miller
Browse files

qlcnic: modify PCI and register access routines



Refactor 82xx driver to support new adapter
Update PCI and hardware access routines

Signed-off-by: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarSony Chacko <sony.chacko@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 79788450
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
+24 −16
Original line number Diff line number Diff line
@@ -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 */
+161 −116
Original line number Diff line number Diff line
@@ -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,8 +924,7 @@ 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,
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;
	}
+35 −28
Original line number Diff line number Diff line
@@ -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;