提交 faa6fcbb 编写于 作者: D Dmitry Kravkov 提交者: David S. Miller

bnx2x: (NPAR mode) Fix FW initialization

Fix FW initialization according to max BW stored in percents
 for NPAR mode. Protect HW from being configured to speed 0.
Signed-off-by: NDmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: NEilon Greenstein <eilong@broadcom.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 e3fa3aff
...@@ -703,19 +703,20 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp) ...@@ -703,19 +703,20 @@ u16 bnx2x_get_mf_speed(struct bnx2x *bp)
{ {
u16 line_speed = bp->link_vars.line_speed; u16 line_speed = bp->link_vars.line_speed;
if (IS_MF(bp)) { if (IS_MF(bp)) {
u16 maxCfg = (bp->mf_config[BP_VN(bp)] & u16 maxCfg = bnx2x_extract_max_cfg(bp,
FUNC_MF_CFG_MAX_BW_MASK) >> bp->mf_config[BP_VN(bp)]);
FUNC_MF_CFG_MAX_BW_SHIFT;
/* Calculate the current MAX line speed limit for the DCC /* Calculate the current MAX line speed limit for the MF
* capable devices * devices
*/ */
if (IS_MF_SD(bp)) { if (IS_MF_SI(bp))
line_speed = (line_speed * maxCfg) / 100;
else { /* SD mode */
u16 vn_max_rate = maxCfg * 100; u16 vn_max_rate = maxCfg * 100;
if (vn_max_rate < line_speed) if (vn_max_rate < line_speed)
line_speed = vn_max_rate; line_speed = vn_max_rate;
} else /* IS_MF_SI(bp)) */ }
line_speed = (line_speed * maxCfg) / 100;
} }
return line_speed; return line_speed;
......
...@@ -1044,4 +1044,24 @@ static inline void storm_memset_cmng(struct bnx2x *bp, ...@@ -1044,4 +1044,24 @@ static inline void storm_memset_cmng(struct bnx2x *bp,
void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_acquire_phy_lock(struct bnx2x *bp);
void bnx2x_release_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp);
/**
* Extracts MAX BW part from MF configuration.
*
* @param bp
* @param mf_cfg
*
* @return u16
*/
static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg)
{
u16 max_cfg = (mf_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT;
if (!max_cfg) {
BNX2X_ERR("Illegal configuration detected for Max BW - "
"using 100 instead\n");
max_cfg = 100;
}
return max_cfg;
}
#endif /* BNX2X_CMN_H */ #endif /* BNX2X_CMN_H */
...@@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -238,7 +238,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
speed |= (cmd->speed_hi << 16); speed |= (cmd->speed_hi << 16);
if (IS_MF_SI(bp)) { if (IS_MF_SI(bp)) {
u32 param = 0; u32 param = 0, part;
u32 line_speed = bp->link_vars.line_speed; u32 line_speed = bp->link_vars.line_speed;
/* use 10G if no link detected */ /* use 10G if no link detected */
...@@ -251,9 +251,11 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -251,9 +251,11 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
REQ_BC_VER_4_SET_MF_BW); REQ_BC_VER_4_SET_MF_BW);
return -EINVAL; return -EINVAL;
} }
if (line_speed < speed) { part = (speed * 100) / line_speed;
BNX2X_DEV_INFO("New speed should be less or equal " if (line_speed < speed || !part) {
"to actual line speed\n"); BNX2X_DEV_INFO("Speed setting should be in a range "
"from 1%% to 100%% "
"of actual line speed\n");
return -EINVAL; return -EINVAL;
} }
/* load old values */ /* load old values */
...@@ -263,8 +265,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ...@@ -263,8 +265,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
param &= FUNC_MF_CFG_MIN_BW_MASK; param &= FUNC_MF_CFG_MIN_BW_MASK;
/* set new MAX value */ /* set new MAX value */
param |= (((speed * 100) / line_speed) param |= (part << FUNC_MF_CFG_MAX_BW_SHIFT)
<< FUNC_MF_CFG_MAX_BW_SHIFT)
& FUNC_MF_CFG_MAX_BW_MASK; & FUNC_MF_CFG_MAX_BW_MASK;
bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param); bnx2x_fw_command(bp, DRV_MSG_CODE_SET_MF_BW, param);
......
...@@ -1974,13 +1974,22 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) ...@@ -1974,13 +1974,22 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn)
vn_max_rate = 0; vn_max_rate = 0;
} else { } else {
u32 maxCfg = bnx2x_extract_max_cfg(bp, vn_cfg);
vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >>
FUNC_MF_CFG_MIN_BW_SHIFT) * 100; FUNC_MF_CFG_MIN_BW_SHIFT) * 100;
/* If min rate is zero - set it to 1 */ /* If fairness is enabled (not all min rates are zeroes) and
if current min rate is zero - set it to 1.
This is a requirement of the algorithm. */
if (bp->vn_weight_sum && (vn_min_rate == 0)) if (bp->vn_weight_sum && (vn_min_rate == 0))
vn_min_rate = DEF_MIN_RATE; vn_min_rate = DEF_MIN_RATE;
vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >>
FUNC_MF_CFG_MAX_BW_SHIFT) * 100; if (IS_MF_SI(bp))
/* maxCfg in percents of linkspeed */
vn_max_rate = (bp->link_vars.line_speed * maxCfg) / 100;
else
/* maxCfg is absolute in 100Mb units */
vn_max_rate = maxCfg * 100;
} }
DP(NETIF_MSG_IFUP, DP(NETIF_MSG_IFUP,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册