mirror of https://gitee.com/openkylin/linux.git
bnxt_en: Implement ethtool set_fec_param() method.
This feature allows the user to set the different FEC modes on the NIC port. Any new setting will take effect immediately after a link toggle. Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2046e3c356
commit
ccd6a9dcab
|
@ -8890,7 +8890,7 @@ static bool bnxt_support_dropped(u16 advertising, u16 supported)
|
|||
return ((supported | diff) != supported);
|
||||
}
|
||||
|
||||
static int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
|
||||
int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
|
||||
{
|
||||
int rc = 0;
|
||||
struct bnxt_link_info *link_info = &bp->link_info;
|
||||
|
|
|
@ -1259,6 +1259,49 @@ struct bnxt_link_info {
|
|||
struct hwrm_port_phy_qcfg_output phy_qcfg_resp;
|
||||
};
|
||||
|
||||
#define BNXT_FEC_RS544_ON \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_ENABLE | \
|
||||
PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_IEEE_ENABLE)
|
||||
|
||||
#define BNXT_FEC_RS544_OFF \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_DISABLE | \
|
||||
PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_IEEE_DISABLE)
|
||||
|
||||
#define BNXT_FEC_RS272_ON \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_1XN_ENABLE | \
|
||||
PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_IEEE_ENABLE)
|
||||
|
||||
#define BNXT_FEC_RS272_OFF \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_1XN_DISABLE | \
|
||||
PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_IEEE_DISABLE)
|
||||
|
||||
#define BNXT_PAM4_SUPPORTED(link_info) \
|
||||
((link_info)->support_pam4_speeds)
|
||||
|
||||
#define BNXT_FEC_RS_ON(link_info) \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE | \
|
||||
PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE | \
|
||||
(BNXT_PAM4_SUPPORTED(link_info) ? \
|
||||
(BNXT_FEC_RS544_ON | BNXT_FEC_RS272_OFF) : 0))
|
||||
|
||||
#define BNXT_FEC_LLRS_ON \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE | \
|
||||
PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE | \
|
||||
BNXT_FEC_RS272_ON | BNXT_FEC_RS544_OFF)
|
||||
|
||||
#define BNXT_FEC_RS_OFF(link_info) \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_DISABLE | \
|
||||
(BNXT_PAM4_SUPPORTED(link_info) ? \
|
||||
(BNXT_FEC_RS544_OFF | BNXT_FEC_RS272_OFF) : 0))
|
||||
|
||||
#define BNXT_FEC_BASE_R_ON(link_info) \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_ENABLE | \
|
||||
BNXT_FEC_RS_OFF(link_info))
|
||||
|
||||
#define BNXT_FEC_ALL_OFF(link_info) \
|
||||
(PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE | \
|
||||
BNXT_FEC_RS_OFF(link_info))
|
||||
|
||||
#define BNXT_MAX_QUEUE 8
|
||||
|
||||
struct bnxt_queue_info {
|
||||
|
@ -2125,6 +2168,7 @@ int bnxt_get_avail_msix(struct bnxt *bp, int num);
|
|||
int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
|
||||
void bnxt_tx_disable(struct bnxt *bp);
|
||||
void bnxt_tx_enable(struct bnxt *bp);
|
||||
int bnxt_update_link(struct bnxt *bp, bool chng_link_state);
|
||||
int bnxt_hwrm_set_pause(struct bnxt *);
|
||||
int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool);
|
||||
int bnxt_hwrm_alloc_wol_fltr(struct bnxt *bp);
|
||||
|
|
|
@ -1924,6 +1924,67 @@ static int bnxt_get_fecparam(struct net_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u32 bnxt_ethtool_forced_fec_to_fw(struct bnxt_link_info *link_info,
|
||||
u32 fec)
|
||||
{
|
||||
u32 fw_fec = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE;
|
||||
|
||||
if (fec & ETHTOOL_FEC_BASER)
|
||||
fw_fec |= BNXT_FEC_BASE_R_ON(link_info);
|
||||
else if (fec & ETHTOOL_FEC_RS)
|
||||
fw_fec |= BNXT_FEC_RS_ON(link_info);
|
||||
else if (fec & ETHTOOL_FEC_LLRS)
|
||||
fw_fec |= BNXT_FEC_LLRS_ON;
|
||||
return fw_fec;
|
||||
}
|
||||
|
||||
static int bnxt_set_fecparam(struct net_device *dev,
|
||||
struct ethtool_fecparam *fecparam)
|
||||
{
|
||||
struct hwrm_port_phy_cfg_input req = {0};
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
struct bnxt_link_info *link_info;
|
||||
u32 new_cfg, fec = fecparam->fec;
|
||||
u16 fec_cfg;
|
||||
int rc;
|
||||
|
||||
link_info = &bp->link_info;
|
||||
fec_cfg = link_info->fec_cfg;
|
||||
if (fec_cfg & BNXT_FEC_NONE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (fec & ETHTOOL_FEC_OFF) {
|
||||
new_cfg = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE |
|
||||
BNXT_FEC_ALL_OFF(link_info);
|
||||
goto apply_fec;
|
||||
}
|
||||
if (((fec & ETHTOOL_FEC_AUTO) && !(fec_cfg & BNXT_FEC_AUTONEG_CAP)) ||
|
||||
((fec & ETHTOOL_FEC_RS) && !(fec_cfg & BNXT_FEC_ENC_RS_CAP)) ||
|
||||
((fec & ETHTOOL_FEC_LLRS) && !(fec_cfg & BNXT_FEC_ENC_LLRS_CAP)) ||
|
||||
((fec & ETHTOOL_FEC_BASER) && !(fec_cfg & BNXT_FEC_ENC_BASE_R_CAP)))
|
||||
return -EINVAL;
|
||||
|
||||
if (fec & ETHTOOL_FEC_AUTO) {
|
||||
if (!link_info->autoneg)
|
||||
return -EINVAL;
|
||||
new_cfg = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_ENABLE;
|
||||
} else {
|
||||
new_cfg = bnxt_ethtool_forced_fec_to_fw(link_info, fec);
|
||||
}
|
||||
|
||||
apply_fec:
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_CFG, -1, -1);
|
||||
req.flags = cpu_to_le32(new_cfg | PORT_PHY_CFG_REQ_FLAGS_RESET_PHY);
|
||||
rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
||||
/* update current settings */
|
||||
if (!rc) {
|
||||
mutex_lock(&bp->link_lock);
|
||||
bnxt_update_link(bp, false);
|
||||
mutex_unlock(&bp->link_lock);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void bnxt_get_pauseparam(struct net_device *dev,
|
||||
struct ethtool_pauseparam *epause)
|
||||
{
|
||||
|
@ -3830,6 +3891,7 @@ const struct ethtool_ops bnxt_ethtool_ops = {
|
|||
.get_link_ksettings = bnxt_get_link_ksettings,
|
||||
.set_link_ksettings = bnxt_set_link_ksettings,
|
||||
.get_fecparam = bnxt_get_fecparam,
|
||||
.set_fecparam = bnxt_set_fecparam,
|
||||
.get_pause_stats = bnxt_get_pause_stats,
|
||||
.get_pauseparam = bnxt_get_pauseparam,
|
||||
.set_pauseparam = bnxt_set_pauseparam,
|
||||
|
|
Loading…
Reference in New Issue