Commit bc48878c authored by David S. Miller's avatar David S. Miller

Merge branch 'bnx2x-next'

Yuval Mintz says:

====================
bnx2x: link and protection changes

This patch series contains 2 small additions to link configuration,
as well as a safeguard against loading the device on a hardware at
a failed state.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 19a12049 0f587f1b
...@@ -521,6 +521,17 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ ...@@ -521,6 +521,17 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
*/ */
#define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000 #define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000
#define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16 #define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16
/* Set non-default values for TXFIR in SFP mode. */
#define PORT_HW_CFG_TX_DRV_IFIR_MASK 0x00F00000
#define PORT_HW_CFG_TX_DRV_IFIR_SHIFT 20
/* Set non-default values for IPREDRIVER in SFP mode. */
#define PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK 0x0F000000
#define PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT 24
/* Set non-default values for POST2 in SFP mode. */
#define PORT_HW_CFG_TX_DRV_POST2_MASK 0xF0000000
#define PORT_HW_CFG_TX_DRV_POST2_SHIFT 28
u32 reserved0[5]; /* 0x17c */ u32 reserved0[5]; /* 0x17c */
...@@ -2247,8 +2258,8 @@ struct shmem2_region { ...@@ -2247,8 +2258,8 @@ struct shmem2_region {
#define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000 #define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000
u32 reserved5[2]; u32 reserved5[2];
u32 reserved6[PORT_MAX]; u32 link_change_count[PORT_MAX]; /* Offset 0x160-0x164 */
#define LINK_CHANGE_COUNT_MASK 0xff /* Offset 0x168 */
/* driver version for each personality */ /* driver version for each personality */
struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */ struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */
......
...@@ -195,6 +195,10 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy, ...@@ -195,6 +195,10 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
#define MAX_PACKET_SIZE (9700) #define MAX_PACKET_SIZE (9700)
#define MAX_KR_LINK_RETRY 4 #define MAX_KR_LINK_RETRY 4
#define DEFAULT_TX_DRV_BRDCT 2
#define DEFAULT_TX_DRV_IFIR 0
#define DEFAULT_TX_DRV_POST2 3
#define DEFAULT_TX_DRV_IPRE_DRIVER 6
/**********************************************************/ /**********************************************************/
/* INTERFACE */ /* INTERFACE */
...@@ -3595,10 +3599,11 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, ...@@ -3595,10 +3599,11 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
* init configuration, and set/clear SGMII flag. Internal * init configuration, and set/clear SGMII flag. Internal
* phy init is done purely in phy_init stage. * phy init is done purely in phy_init stage.
*/ */
#define WC_TX_DRIVER(post2, idriver, ipre) \ #define WC_TX_DRIVER(post2, idriver, ipre, ifir) \
((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \ ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \
(idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \ (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \
(ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)) (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \
(ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET))
#define WC_TX_FIR(post, main, pre) \ #define WC_TX_FIR(post, main, pre) \
((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \ ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \
...@@ -3765,12 +3770,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, ...@@ -3765,12 +3770,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
lane = bnx2x_get_warpcore_lane(phy, params); lane = bnx2x_get_warpcore_lane(phy, params);
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
WC_TX_DRIVER(0x02, 0x06, 0x09)); WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
/* Configure the next lane if dual mode */ /* Configure the next lane if dual mode */
if (phy->flags & FLAGS_WC_DUAL_MODE) if (phy->flags & FLAGS_WC_DUAL_MODE)
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1),
WC_TX_DRIVER(0x02, 0x06, 0x09)); WC_TX_DRIVER(0x02, 0x06, 0x09, 0));
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
0x03f0); 0x03f0);
...@@ -3933,6 +3938,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, ...@@ -3933,6 +3938,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u16 misc1_val, tap_val, tx_driver_val, lane, val; u16 misc1_val, tap_val, tx_driver_val, lane, val;
u32 cfg_tap_val, tx_drv_brdct, tx_equal; u32 cfg_tap_val, tx_drv_brdct, tx_equal;
u32 ifir_val, ipost2_val, ipre_driver_val;
/* Hold rxSeqStart */ /* Hold rxSeqStart */
bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
...@@ -3978,7 +3984,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, ...@@ -3978,7 +3984,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
if (is_xfi) { if (is_xfi) {
misc1_val |= 0x5; misc1_val |= 0x5;
tap_val = WC_TX_FIR(0x08, 0x37, 0x00); tap_val = WC_TX_FIR(0x08, 0x37, 0x00);
tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03); tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0);
} else { } else {
cfg_tap_val = REG_RD(bp, params->shmem_base + cfg_tap_val = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region, dev_info. offsetof(struct shmem_region, dev_info.
...@@ -3987,10 +3993,6 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, ...@@ -3987,10 +3993,6 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK; tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK;
tx_drv_brdct = (cfg_tap_val &
PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
misc1_val |= 0x9; misc1_val |= 0x9;
/* TAP values are controlled by nvram, if value there isn't 0 */ /* TAP values are controlled by nvram, if value there isn't 0 */
...@@ -3999,11 +4001,36 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, ...@@ -3999,11 +4001,36 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
else else
tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02); tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02);
if (tx_drv_brdct) ifir_val = DEFAULT_TX_DRV_IFIR;
tx_driver_val = WC_TX_DRIVER(0x03, (u16)tx_drv_brdct, ipost2_val = DEFAULT_TX_DRV_POST2;
0x06); ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER;
else tx_drv_brdct = DEFAULT_TX_DRV_BRDCT;
tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06);
/* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all
* configuration.
*/
if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK |
PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK |
PORT_HW_CFG_TX_DRV_POST2_MASK)) {
ifir_val = (cfg_tap_val &
PORT_HW_CFG_TX_DRV_IFIR_MASK) >>
PORT_HW_CFG_TX_DRV_IFIR_SHIFT;
ipre_driver_val = (cfg_tap_val &
PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK)
>> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT;
ipost2_val = (cfg_tap_val &
PORT_HW_CFG_TX_DRV_POST2_MASK) >>
PORT_HW_CFG_TX_DRV_POST2_SHIFT;
}
if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) {
tx_drv_brdct = (cfg_tap_val &
PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >>
PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT;
}
tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct,
ipre_driver_val, ifir_val);
} }
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
...@@ -4144,7 +4171,7 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, ...@@ -4144,7 +4171,7 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
MDIO_WC_REG_TX_FIR_TAP_ENABLE)); MDIO_WC_REG_TX_FIR_TAP_ENABLE));
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
WC_TX_DRIVER(0x02, 0x02, 0x02)); WC_TX_DRIVER(0x02, 0x02, 0x02, 0));
} }
static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
...@@ -6731,6 +6758,25 @@ static int bnx2x_update_link_up(struct link_params *params, ...@@ -6731,6 +6758,25 @@ static int bnx2x_update_link_up(struct link_params *params,
msleep(20); msleep(20);
return rc; return rc;
} }
static void bnx2x_chng_link_count(struct link_params *params, bool clear)
{
struct bnx2x *bp = params->bp;
u32 addr, val;
/* Verify the link_change_count is supported by the MFW */
if (!(SHMEM2_HAS(bp, link_change_count)))
return;
addr = params->shmem2_base +
offsetof(struct shmem2_region, link_change_count[params->port]);
if (clear)
val = 0;
else
val = REG_RD(bp, addr) + 1;
REG_WR(bp, addr, val);
}
/* The bnx2x_link_update function should be called upon link /* The bnx2x_link_update function should be called upon link
* interrupt. * interrupt.
* Link is considered up as follows: * Link is considered up as follows:
...@@ -6749,6 +6795,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) ...@@ -6749,6 +6795,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
struct link_vars phy_vars[MAX_PHYS]; struct link_vars phy_vars[MAX_PHYS];
u8 port = params->port; u8 port = params->port;
u8 link_10g_plus, phy_index; u8 link_10g_plus, phy_index;
u32 prev_link_status = vars->link_status;
u8 ext_phy_link_up = 0, cur_link_up; u8 ext_phy_link_up = 0, cur_link_up;
int rc = 0; int rc = 0;
u8 is_mi_int = 0; u8 is_mi_int = 0;
...@@ -6988,6 +7035,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) ...@@ -6988,6 +7035,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
else else
rc = bnx2x_update_link_down(params, vars); rc = bnx2x_update_link_down(params, vars);
if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP)
bnx2x_chng_link_count(params, false);
/* Update MCP link status was changed */ /* Update MCP link status was changed */
if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX) if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX)
bnx2x_fw_command(bp, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0); bnx2x_fw_command(bp, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0);
...@@ -12631,6 +12681,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) ...@@ -12631,6 +12681,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
params->link_flags = PHY_INITIALIZED; params->link_flags = PHY_INITIALIZED;
/* Driver opens NIG-BRB filters */ /* Driver opens NIG-BRB filters */
bnx2x_set_rx_filter(params, 1); bnx2x_set_rx_filter(params, 1);
bnx2x_chng_link_count(params, true);
/* Check if link flap can be avoided */ /* Check if link flap can be avoided */
lfa_status = bnx2x_check_lfa(params); lfa_status = bnx2x_check_lfa(params);
...@@ -12705,6 +12756,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, ...@@ -12705,6 +12756,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
/* Disable attentions */ /* Disable attentions */
vars->link_status = 0; vars->link_status = 0;
bnx2x_chng_link_count(params, true);
bnx2x_update_mng(params, vars->link_status); bnx2x_update_mng(params, vars->link_status);
vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK |
SHMEM_EEE_ACTIVE_BIT); SHMEM_EEE_ACTIVE_BIT);
......
...@@ -11650,6 +11650,13 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp) ...@@ -11650,6 +11650,13 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
u32 val = 0, val2 = 0; u32 val = 0, val2 = 0;
int rc = 0; int rc = 0;
/* Validate that chip access is feasible */
if (REG_RD(bp, MISC_REG_CHIP_NUM) == 0xffffffff) {
dev_err(&bp->pdev->dev,
"Chip read returns all Fs. Preventing probe from continuing\n");
return -EINVAL;
}
bnx2x_get_common_hwinfo(bp); bnx2x_get_common_hwinfo(bp);
/* /*
......
...@@ -7341,6 +7341,8 @@ Theotherbitsarereservedandshouldbezero*/ ...@@ -7341,6 +7341,8 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081 #define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081
#define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091 #define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091
#define MDIO_WC_REG_TX0_TX_DRIVER 0x8067 #define MDIO_WC_REG_TX0_TX_DRIVER 0x8067
#define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET 0x01
#define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_MASK 0x000e
#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04
#define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0 #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0
#define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08 #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08
......
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