Commit f2e0899f authored by Dmitry Kravkov's avatar Dmitry Kravkov Committed by David S. Miller

bnx2x: Add 57712 support

57712 HW supported with same set of features as for 57710/57711
Signed-off-by: default avatarDmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8fe23fbd
......@@ -180,10 +180,16 @@ void bnx2x_panic_dump(struct bnx2x *bp);
#define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val)
#define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \
offsetof(struct mf_cfg, field))
#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \
offsetof(struct mf2_cfg, field))
#define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field))
#define MF_CFG_WR(bp, field, val) REG_WR(bp,\
MF_CFG_ADDR(bp, field), (val))
#define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field))
#define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \
(SHMEM2_RD((bp), size) > \
offsetof(struct shmem2_region, field)))
#define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg)
#define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val)
......@@ -296,6 +302,8 @@ union db_prod {
union host_hc_status_block {
/* pointer to fp status block e1x */
struct host_hc_status_block_e1x *e1x_sb;
/* pointer to fp status block e2 */
struct host_hc_status_block_e2 *e2_sb;
};
struct bnx2x_fastpath {
......@@ -564,12 +572,19 @@ struct bnx2x_common {
#define CHIP_NUM_57710 0x164e
#define CHIP_NUM_57711 0x164f
#define CHIP_NUM_57711E 0x1650
#define CHIP_NUM_57712 0x1662
#define CHIP_NUM_57712E 0x1663
#define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710)
#define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711)
#define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E)
#define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712)
#define CHIP_IS_57712E(bp) (CHIP_NUM(bp) == CHIP_NUM_57712E)
#define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \
CHIP_IS_57711E(bp))
#define IS_E1H_OFFSET CHIP_IS_E1H(bp)
#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \
CHIP_IS_57712E(bp))
#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp)))
#define IS_E1H_OFFSET (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp))
#define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000)
#define CHIP_REV_Ax 0x00000000
......@@ -596,6 +611,7 @@ struct bnx2x_common {
u32 shmem_base;
u32 shmem2_base;
u32 mf_cfg_base;
u32 mf2_cfg_base;
u32 hw_config;
......@@ -603,10 +619,25 @@ struct bnx2x_common {
u8 int_block;
#define INT_BLOCK_HC 0
#define INT_BLOCK_IGU 1
#define INT_BLOCK_MODE_NORMAL 0
#define INT_BLOCK_MODE_BW_COMP 2
#define CHIP_INT_MODE_IS_NBC(bp) \
(CHIP_IS_E2(bp) && \
!((bp)->common.int_block & INT_BLOCK_MODE_BW_COMP))
#define CHIP_INT_MODE_IS_BC(bp) (!CHIP_INT_MODE_IS_NBC(bp))
u8 chip_port_mode;
#define CHIP_4_PORT_MODE 0x0
#define CHIP_2_PORT_MODE 0x1
#define CHIP_PORT_MODE_NONE 0x2
#define CHIP_MODE(bp) (bp->common.chip_port_mode)
#define CHIP_MODE_IS_4_PORT(bp) (CHIP_MODE(bp) == CHIP_4_PORT_MODE)
};
/* IGU MSIX STATISTICS on 57712: 64 for VFs; 4 for PFs; 4 for Attentions */
#define BNX2X_IGU_STAS_MSG_VF_CNT 64
#define BNX2X_IGU_STAS_MSG_PF_CNT 4
/* end of common */
......@@ -670,7 +701,7 @@ enum {
*/
#define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */
#define MAX_CONTEXT FP_SB_MAX_E1x
#define FP_SB_MAX_E2 16 /* fast-path interrupt contexts E2 */
/*
* cid_cnt paramter below refers to the value returned by
......@@ -754,7 +785,7 @@ struct bnx2x_slowpath {
#define MAX_DYNAMIC_ATTN_GRPS 8
struct attn_route {
u32 sig[4];
u32 sig[5];
};
struct iro {
......@@ -896,13 +927,20 @@ struct bnx2x {
#define HW_VLAN_RX_FLAG 0x800
#define MF_FUNC_DIS 0x1000
int func;
int pf_num; /* absolute PF number */
int pfid; /* per-path PF number */
int base_fw_ndsb;
#define BP_PORT(bp) (bp->func % PORT_MAX)
#define BP_FUNC(bp) (bp->func)
#define BP_E1HVN(bp) (bp->func >> 1)
#define BP_PATH(bp) (!CHIP_IS_E2(bp) ? \
0 : (bp->pf_num & 1))
#define BP_PORT(bp) (bp->pfid & 1)
#define BP_FUNC(bp) (bp->pfid)
#define BP_ABS_FUNC(bp) (bp->pf_num)
#define BP_E1HVN(bp) (bp->pfid >> 1)
#define BP_VN(bp) (CHIP_MODE_IS_4_PORT(bp) ? \
0 : BP_E1HVN(bp))
#define BP_L_ID(bp) (BP_E1HVN(bp) << 2)
#define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\
BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1))
#ifdef BCM_CNIC
#define BCM_CNIC_CID_START 16
......@@ -932,7 +970,8 @@ struct bnx2x {
struct cmng_struct_per_port cmng;
u32 vn_weight_sum;
u32 mf_config;
u32 mf_config[E1HVN_MAX];
u32 mf2_config[E2_FUNC_MAX];
u16 mf_ov;
u8 mf_mode;
#define IS_MF(bp) (bp->mf_mode != 0)
......@@ -1127,11 +1166,11 @@ struct bnx2x {
#define RSS_IPV6_CAP 0x0004
#define RSS_IPV6_TCP_CAP 0x0008
#define BNX2X_MAX_QUEUES(bp) (IS_MF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \
: MAX_CONTEXT)
#define BNX2X_NUM_QUEUES(bp) (bp->num_queues)
#define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1)
#define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE)
#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1)
#define RSS_IPV4_CAP_MASK \
TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY
......@@ -1342,14 +1381,40 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
/* DMAE command defines */
#define DMAE_CMD_SRC_PCI 0
#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC
#define DMAE_TIMEOUT -1
#define DMAE_PCI_ERROR -2 /* E2 and onward */
#define DMAE_NOT_RDY -3
#define DMAE_PCI_ERR_FLAG 0x80000000
#define DMAE_SRC_PCI 0
#define DMAE_SRC_GRC 1
#define DMAE_DST_NONE 0
#define DMAE_DST_PCI 1
#define DMAE_DST_GRC 2
#define DMAE_COMP_PCI 0
#define DMAE_COMP_GRC 1
/* E2 and onward - PCI error handling in the completion */
#define DMAE_COMP_REGULAR 0
#define DMAE_COM_SET_ERR 1
#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_SRC_PCI (DMAE_SRC_PCI << \
DMAE_COMMAND_SRC_SHIFT)
#define DMAE_CMD_SRC_GRC (DMAE_SRC_GRC << \
DMAE_COMMAND_SRC_SHIFT)
#define DMAE_CMD_C_DST_PCI 0
#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT)
#define DMAE_CMD_DST_PCI (DMAE_DST_PCI << \
DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_DST_GRC (DMAE_DST_GRC << \
DMAE_COMMAND_DST_SHIFT)
#define DMAE_CMD_C_DST_PCI (DMAE_COMP_PCI << \
DMAE_COMMAND_C_DST_SHIFT)
#define DMAE_CMD_C_DST_GRC (DMAE_COMP_GRC << \
DMAE_COMMAND_C_DST_SHIFT)
#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE
......@@ -1365,10 +1430,20 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET
#define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT
#define DMAE_SRC_PF 0
#define DMAE_SRC_VF 1
#define DMAE_DST_PF 0
#define DMAE_DST_VF 1
#define DMAE_C_SRC 0
#define DMAE_C_DST 1
#define DMAE_LEN32_RD_MAX 0x80
#define DMAE_LEN32_WR_MAX(bp) (CHIP_IS_E1(bp) ? 0x400 : 0x2000)
#define DMAE_COMP_VAL 0xe0d0d0ae
#define DMAE_COMP_VAL 0x60d0d0ae /* E2 and on - upper bit
indicates eror */
#define MAX_DMAE_C_PER_PORT 8
#define INIT_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \
......@@ -1534,6 +1609,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define GET_FLAG(value, mask) \
(((value) &= (mask)) >> (mask##_SHIFT))
#define GET_FIELD(value, fname) \
(((value) & (fname##_MASK)) >> (fname##_SHIFT))
#define CAM_IS_INVALID(x) \
(GET_FLAG(x.flags, \
MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \
......@@ -1553,6 +1631,9 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0
#endif
#ifndef ETH_MAX_RX_CLIENTS_E2
#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H
#endif
#define BNX2X_VPD_LEN 128
#define VENDOR_ID_LEN 4
......@@ -1570,13 +1651,18 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
#define BNX2X_EXTERN extern
#endif
BNX2X_EXTERN int load_count[3]; /* 0-common, 1-port0, 2-port1 */
BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */
/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */
extern void bnx2x_set_ethtool_ops(struct net_device *netdev);
void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx);
u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type);
u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode);
u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type,
bool with_comp, u8 comp_type);
#define WAIT_RAMROD_POLL 0x01
#define WAIT_RAMROD_COMMON 0x02
......
This diff is collapsed.
......@@ -366,10 +366,77 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp,
fp->index, bd_prod, rx_comp_prod, rx_sge_prod);
}
static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id,
u8 segment, u16 index, u8 op,
u8 update, u32 igu_addr)
{
struct igu_regular cmd_data = {0};
cmd_data.sb_id_and_flags =
((index << IGU_REGULAR_SB_INDEX_SHIFT) |
(segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) |
(update << IGU_REGULAR_BUPDATE_SHIFT) |
(op << IGU_REGULAR_ENABLE_INT_SHIFT));
DP(NETIF_MSG_HW, "write 0x%08x to IGU addr 0x%x\n",
cmd_data.sb_id_and_flags, igu_addr);
REG_WR(bp, igu_addr, cmd_data.sb_id_and_flags);
/* Make sure that ACK is written */
mmiowb();
barrier();
}
static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
u8 storm, u16 index, u8 op, u8 update)
static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp,
u8 idu_sb_id, bool is_Pf)
{
u32 data, ctl, cnt = 100;
u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA;
u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL;
u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4;
u32 sb_bit = 1 << (idu_sb_id%32);
u32 func_encode = BP_FUNC(bp) |
((is_Pf == true ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT);
u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id;
/* Not supported in BC mode */
if (CHIP_INT_MODE_IS_BC(bp))
return;
data = (IGU_USE_REGISTER_cstorm_type_0_sb_cleanup
<< IGU_REGULAR_CLEANUP_TYPE_SHIFT) |
IGU_REGULAR_CLEANUP_SET |
IGU_REGULAR_BCLEANUP;
ctl = addr_encode << IGU_CTRL_REG_ADDRESS_SHIFT |
func_encode << IGU_CTRL_REG_FID_SHIFT |
IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT;
DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
data, igu_addr_data);
REG_WR(bp, igu_addr_data, data);
mmiowb();
barrier();
DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
ctl, igu_addr_ctl);
REG_WR(bp, igu_addr_ctl, ctl);
mmiowb();
barrier();
/* wait for clean up to finish */
while (!(REG_RD(bp, igu_addr_ack) & sb_bit) && --cnt)
msleep(20);
if (!(REG_RD(bp, igu_addr_ack) & sb_bit)) {
DP(NETIF_MSG_HW, "Unable to finish IGU cleanup: "
"idu_sb_id %d offset %d bit %d (cnt %d)\n",
idu_sb_id, idu_sb_id/32, idu_sb_id%32, cnt);
}
}
static inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id,
u8 storm, u16 index, u8 op, u8 update)
{
u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
COMMAND_REG_INT_ACK);
......@@ -390,7 +457,37 @@ static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id,
mmiowb();
barrier();
}
static inline u16 bnx2x_ack_int(struct bnx2x *bp)
static inline void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment,
u16 index, u8 op, u8 update)
{
u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8;
bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update,
igu_addr);
}
static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm,
u16 index, u8 op, u8 update)
{
if (bp->common.int_block == INT_BLOCK_HC)
bnx2x_hc_ack_sb(bp, igu_sb_id, storm, index, op, update);
else {
u8 segment;
if (CHIP_INT_MODE_IS_BC(bp))
segment = storm;
else if (igu_sb_id != bp->igu_dsb_id)
segment = IGU_SEG_ACCESS_DEF;
else if (storm == ATTENTION_ID)
segment = IGU_SEG_ACCESS_ATTN;
else
segment = IGU_SEG_ACCESS_DEF;
bnx2x_igu_ack_sb(bp, igu_sb_id, segment, index, op, update);
}
}
static inline u16 bnx2x_hc_ack_int(struct bnx2x *bp)
{
u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 +
COMMAND_REG_SIMD_MASK);
......@@ -399,13 +496,34 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp)
DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n",
result, hc_addr);
barrier();
return result;
}
static inline u16 bnx2x_igu_ack_int(struct bnx2x *bp)
{
u32 igu_addr = (BAR_IGU_INTMEM + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8);
u32 result = REG_RD(bp, igu_addr);
DP(NETIF_MSG_HW, "read 0x%08x from IGU addr 0x%x\n",
result, igu_addr);
barrier();
return result;
}
static inline u16 bnx2x_ack_int(struct bnx2x *bp)
{
barrier();
if (bp->common.int_block == INT_BLOCK_HC)
return bnx2x_hc_ack_int(bp);
else
return bnx2x_igu_ack_int(bp);
}
/*
* fast path service functions
*/
static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp)
{
/* Tell compiler that consumer and producer can change */
......@@ -456,6 +574,17 @@ static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
rx_cons_sb++;
return (fp->rx_comp_cons != rx_cons_sb);
}
/**
* disables tx from stack point of view
*
* @param bp
*/
static inline void bnx2x_tx_disable(struct bnx2x *bp)
{
netif_tx_disable(bp->dev);
netif_carrier_off(bp->dev);
}
static inline void bnx2x_free_rx_sge(struct bnx2x *bp,
struct bnx2x_fastpath *fp, u16 index)
{
......
......@@ -31,14 +31,24 @@ struct dump_sign {
#define RI_E1 0x1
#define RI_E1H 0x2
#define RI_E2 0x4
#define RI_ONLINE 0x100
#define RI_PATH0_DUMP 0x200
#define RI_PATH1_DUMP 0x400
#define RI_E1_OFFLINE (RI_E1)
#define RI_E1_ONLINE (RI_E1 | RI_ONLINE)
#define RI_E1H_OFFLINE (RI_E1H)
#define RI_E1H_ONLINE (RI_E1H | RI_ONLINE)
#define RI_ALL_OFFLINE (RI_E1 | RI_E1H)
#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_ONLINE)
#define RI_E2_OFFLINE (RI_E2)
#define RI_E2_ONLINE (RI_E2 | RI_ONLINE)
#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H)
#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE)
#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H)
#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE)
#define RI_E1E2_OFFLINE (RI_E2 | RI_E1)
#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE)
#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2)
#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE)
#define MAX_TIMER_PENDING 200
#define TIMER_SCAN_DONT_CARE 0xFF
......@@ -513,6 +523,12 @@ static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = {
{ 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE }
};
#define WREGS_COUNT_E2 1
static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 };
static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = {
{ 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE }
};
static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 };
......@@ -531,4 +547,17 @@ static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] =
{ 0x1640d0, 0x1640d4 };
#define PAGE_MODE_VALUES_E2 2
#define PAGE_READ_REGS_E2 1
#define PAGE_WRITE_REGS_E2 1
static const u32 page_vals_e2[PAGE_MODE_VALUES_E2] = { 0, 128 };
static const u32 page_write_regs_e2[PAGE_WRITE_REGS_E2] = { 328476 };
static const struct reg_addr page_read_regs_e2[PAGE_READ_REGS_E2] = {
{ 0x58000, 4608, RI_E2_ONLINE } };
#endif /* BNX2X_DUMP_H */
......@@ -41,19 +41,19 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
(bp->link_vars.link_up)) {
cmd->speed = bp->link_vars.line_speed;
cmd->duplex = bp->link_vars.duplex;
if (IS_MF(bp)) {
u16 vn_max_rate;
vn_max_rate =
((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
if (vn_max_rate < cmd->speed)
cmd->speed = vn_max_rate;
}
} else {
cmd->speed = bp->link_params.req_line_speed[cfg_idx];
cmd->duplex = bp->link_params.req_duplex[cfg_idx];
}
if (IS_MF(bp)) {
u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] &
FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) *
100;
if (vn_max_rate < cmd->speed)
cmd->speed = vn_max_rate;
}
if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
cmd->port = PORT_TP;
......@@ -298,6 +298,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
#define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE)
static int bnx2x_get_regs_len(struct net_device *dev)
{
......@@ -315,7 +316,7 @@ static int bnx2x_get_regs_len(struct net_device *dev)
regdump_len += wreg_addrs_e1[i].size *
(1 + wreg_addrs_e1[i].read_regs_count);
} else { /* E1H */
} else if (CHIP_IS_E1H(bp)) {
for (i = 0; i < REGS_COUNT; i++)
if (IS_E1H_ONLINE(reg_addrs[i].info))
regdump_len += reg_addrs[i].size;
......@@ -324,6 +325,15 @@ static int bnx2x_get_regs_len(struct net_device *dev)
if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
regdump_len += wreg_addrs_e1h[i].size *
(1 + wreg_addrs_e1h[i].read_regs_count);
} else if (CHIP_IS_E2(bp)) {
for (i = 0; i < REGS_COUNT; i++)
if (IS_E2_ONLINE(reg_addrs[i].info))
regdump_len += reg_addrs[i].size;
for (i = 0; i < WREGS_COUNT_E2; i++)
if (IS_E2_ONLINE(wreg_addrs_e2[i].info))
regdump_len += wreg_addrs_e2[i].size *
(1 + wreg_addrs_e2[i].read_regs_count);
}
regdump_len *= 4;
regdump_len += sizeof(struct dump_hdr);
......@@ -331,6 +341,23 @@ static int bnx2x_get_regs_len(struct net_device *dev)
return regdump_len;
}
static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p)
{
u32 i, j, k, n;
for (i = 0; i < PAGE_MODE_VALUES_E2; i++) {
for (j = 0; j < PAGE_WRITE_REGS_E2; j++) {
REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]);
for (k = 0; k < PAGE_READ_REGS_E2; k++)
if (IS_E2_ONLINE(page_read_regs_e2[k].info))
for (n = 0; n <
page_read_regs_e2[k].size; n++)
*p++ = REG_RD(bp,
page_read_regs_e2[k].addr + n*4);
}
}
}
static void bnx2x_get_regs(struct net_device *dev,
struct ethtool_regs *regs, void *_p)
{
......@@ -350,7 +377,14 @@ static void bnx2x_get_regs(struct net_device *dev,
dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE;
if (CHIP_IS_E1(bp))
dump_hdr.info = RI_E1_ONLINE;
else if (CHIP_IS_E1H(bp))
dump_hdr.info = RI_E1H_ONLINE;
else if (CHIP_IS_E2(bp))
dump_hdr.info = RI_E2_ONLINE |
(BP_PATH(bp) ? RI_PATH1_DUMP : RI_PATH0_DUMP);
memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
p += dump_hdr.hdr_size + 1;
......@@ -362,16 +396,25 @@ static void bnx2x_get_regs(struct net_device *dev,
*p++ = REG_RD(bp,
reg_addrs[i].addr + j*4);
} else { /* E1H */
} else if (CHIP_IS_E1H(bp)) {
for (i = 0; i < REGS_COUNT; i++)
if (IS_E1H_ONLINE(reg_addrs[i].info))
for (j = 0; j < reg_addrs[i].size; j++)
*p++ = REG_RD(bp,
reg_addrs[i].addr + j*4);
} else if (CHIP_IS_E2(bp)) {
for (i = 0; i < REGS_COUNT; i++)
if (IS_E2_ONLINE(reg_addrs[i].info))
for (j = 0; j < reg_addrs[i].size; j++)
*p++ = REG_RD(bp,
reg_addrs[i].addr + j*4);
bnx2x_read_pages_regs_e2(bp, p);
}
}
#define PHY_FW_VER_LEN 10
#define PHY_FW_VER_LEN 20
static void bnx2x_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
......@@ -474,7 +517,7 @@ static u32 bnx2x_get_link(struct net_device *dev)
{
struct bnx2x *bp = netdev_priv(dev);
if (bp->flags & MF_FUNC_DIS)
if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN))
return 0;
return bp->link_vars.link_up;
......@@ -1235,6 +1278,9 @@ static int bnx2x_test_registers(struct bnx2x *bp)
for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
u32 offset, mask, save_val, val;
if (CHIP_IS_E2(bp) &&
reg_tbl[i].offset0 == HC_REG_AGG_INT_0)
continue;
offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
mask = reg_tbl[i].mask;
......@@ -1286,20 +1332,33 @@ static int bnx2x_test_memory(struct bnx2x *bp)
u32 offset;
u32 e1_mask;
u32 e1h_mask;
u32 e2_mask;
} prty_tbl[] = {
{ "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 },
{ "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 },
{ "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 },
{ "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 },
{ "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 },
{ "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 },
{ NULL, 0xffffffff, 0, 0 }
{ "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0, 0 },
{ "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2, 0 },
{ "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0, 0 },
{ "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0, 0 },
{ "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0, 0 },
{ "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0, 0 },
{ NULL, 0xffffffff, 0, 0, 0 }
};
if (!netif_running