Commit 127a425e authored by Ariel Elior's avatar Ariel Elior Committed by David S. Miller

bnx2x: Removing indirect register access

In virtualized environments indirect access to the device may not be supported
(depending on the Hypervisor type). Indirect device access was used since in
some harware contexts (i.e. certain chipset and BIOS) every access the driver
makes across the pci is followed by a BIOS initiated Zero Length Read to the
same address. When accessing widebus registers this zero length read corrupts
the serialization of the read/write sequence resulting with errors. To avoid
this problem widebus registers are always accessed via the DMAE or the indirect
interface. However, the 57712x and 578xx devices intercept the zero length read
and so using the indirect interface with these devices is not necessary. Since
PDA is only supported for 57712x and 578xx the indirect access to device was
restricted to 57710 and 57711x.
Signed-off-by: default avatarAriel Elior <ariele@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8d7b0278
...@@ -69,12 +69,12 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len, ...@@ -69,12 +69,12 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len,
{ {
if (bp->dmae_ready) if (bp->dmae_ready)
bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
else if (wb)
/* /* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
* Wide bus registers with no dmae need to be written else if (wb && CHIP_IS_E1(bp))
* using indirect write.
*/
bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
else else
bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len); bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
} }
...@@ -99,8 +99,14 @@ static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) ...@@ -99,8 +99,14 @@ static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
{ {
if (bp->dmae_ready) if (bp->dmae_ready)
bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
else
/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
else if (CHIP_IS_E1(bp))
bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
else
bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
} }
static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr,
...@@ -177,8 +183,14 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, ...@@ -177,8 +183,14 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr,
{ {
if (bp->dmae_ready) if (bp->dmae_ready)
VIRT_WR_DMAE_LEN(bp, data, addr, len, 0); VIRT_WR_DMAE_LEN(bp, data, addr, len, 0);
else
/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
else if (CHIP_IS_E1(bp))
bnx2x_init_ind_wr(bp, addr, data, len); bnx2x_init_ind_wr(bp, addr, data, len);
/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
else
bnx2x_init_str_wr(bp, addr, data, len);
} }
static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo,
...@@ -840,25 +852,15 @@ static void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count, ...@@ -840,25 +852,15 @@ static void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count,
} }
} }
static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count) static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count,
u32 base_reg, u32 reg)
{ {
int i; int i;
u32 wb_data[2]; u32 wb_data[2] = {0, 0};
wb_data[0] = wb_data[1] = 0;
for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) { for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) {
REG_WR(bp, QM_REG_BASEADDR + i*4, REG_WR(bp, base_reg + i*4,
qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, bnx2x_init_wr_wb(bp, reg + i*8, wb_data, 2);
wb_data, 2);
if (CHIP_IS_E1H(bp)) {
REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4,
qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8,
wb_data, 2);
}
} }
} }
...@@ -873,7 +875,12 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, ...@@ -873,7 +875,12 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
case INITOP_INIT: case INITOP_INIT:
/* set in the init-value array */ /* set in the init-value array */
case INITOP_SET: case INITOP_SET:
bnx2x_qm_set_ptr_table(bp, qm_cid_count); bnx2x_qm_set_ptr_table(bp, qm_cid_count,
QM_REG_BASEADDR, QM_REG_PTRTBL);
if (CHIP_IS_E1H(bp))
bnx2x_qm_set_ptr_table(bp, qm_cid_count,
QM_REG_BASEADDR_EXT_A,
QM_REG_PTRTBL_EXT_A);
break; break;
case INITOP_CLEAR: case INITOP_CLEAR:
break; break;
......
...@@ -498,9 +498,13 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, ...@@ -498,9 +498,13 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
if (!bp->dmae_ready) { if (!bp->dmae_ready) {
u32 *data = bnx2x_sp(bp, wb_data[0]); u32 *data = bnx2x_sp(bp, wb_data[0]);
DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" DP(BNX2X_MSG_OFF,
" using indirect\n", dst_addr, len32); "DMAE is not ready (dst_addr %08x len32 %d) using indirect\n",
bnx2x_init_ind_wr(bp, dst_addr, data, len32); dst_addr, len32);
if (CHIP_IS_E1(bp))
bnx2x_init_ind_wr(bp, dst_addr, data, len32);
else
bnx2x_init_str_wr(bp, dst_addr, data, len32);
return; return;
} }
...@@ -528,10 +532,16 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) ...@@ -528,10 +532,16 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
u32 *data = bnx2x_sp(bp, wb_data[0]); u32 *data = bnx2x_sp(bp, wb_data[0]);
int i; int i;
DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x len32 %d)" if (CHIP_IS_E1(bp)) {
" using indirect\n", src_addr, len32); DP(BNX2X_MSG_OFF,
for (i = 0; i < len32; i++) "DMAE is not ready (src_addr %08x len32 %d) using indirect\n",
data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4); src_addr, len32);
for (i = 0; i < len32; i++)
data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4);
} else
for (i = 0; i < len32; i++)
data[i] = REG_RD(bp, src_addr + i*4);
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment