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

Merge branch 'qed-Align-PTT-and-add-various-link-modes'

Rahul Verma says:

====================
Align PTT and add various link modes.

This series aligns the ptt propagation as local ptt or global ptt.
Adds new transceiver modes, speed capabilities and board config,
which is utilized to display the enhanced link modes, media types
and speed. Enhances the link with detailed information.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0ba4ad32 1c90eabc
......@@ -915,7 +915,7 @@ u16 qed_get_cm_pq_idx_llt_mtc(struct qed_hwfn *p_hwfn, u8 tc);
/* Prototypes */
int qed_fill_dev_info(struct qed_dev *cdev,
struct qed_dev_info *dev_info);
void qed_link_update(struct qed_hwfn *hwfn);
void qed_link_update(struct qed_hwfn *hwfn, struct qed_ptt *ptt);
u32 qed_unzip_data(struct qed_hwfn *p_hwfn,
u32 input_len, u8 *input_buf,
u32 max_size, u8 *unzip_buf);
......
......@@ -12207,11 +12207,56 @@ struct public_port {
u32 transceiver_data;
#define ETH_TRANSCEIVER_STATE_MASK 0x000000FF
#define ETH_TRANSCEIVER_STATE_SHIFT 0x00000000
#define ETH_TRANSCEIVER_STATE_OFFSET 0x00000000
#define ETH_TRANSCEIVER_STATE_UNPLUGGED 0x00000000
#define ETH_TRANSCEIVER_STATE_PRESENT 0x00000001
#define ETH_TRANSCEIVER_STATE_VALID 0x00000003
#define ETH_TRANSCEIVER_STATE_UPDATING 0x00000008
#define ETH_TRANSCEIVER_TYPE_MASK 0x0000FF00
#define ETH_TRANSCEIVER_TYPE_OFFSET 0x8
#define ETH_TRANSCEIVER_TYPE_NONE 0x00
#define ETH_TRANSCEIVER_TYPE_UNKNOWN 0xFF
#define ETH_TRANSCEIVER_TYPE_1G_PCC 0x01
#define ETH_TRANSCEIVER_TYPE_1G_ACC 0x02
#define ETH_TRANSCEIVER_TYPE_1G_LX 0x03
#define ETH_TRANSCEIVER_TYPE_1G_SX 0x04
#define ETH_TRANSCEIVER_TYPE_10G_SR 0x05
#define ETH_TRANSCEIVER_TYPE_10G_LR 0x06
#define ETH_TRANSCEIVER_TYPE_10G_LRM 0x07
#define ETH_TRANSCEIVER_TYPE_10G_ER 0x08
#define ETH_TRANSCEIVER_TYPE_10G_PCC 0x09
#define ETH_TRANSCEIVER_TYPE_10G_ACC 0x0a
#define ETH_TRANSCEIVER_TYPE_XLPPI 0x0b
#define ETH_TRANSCEIVER_TYPE_40G_LR4 0x0c
#define ETH_TRANSCEIVER_TYPE_40G_SR4 0x0d
#define ETH_TRANSCEIVER_TYPE_40G_CR4 0x0e
#define ETH_TRANSCEIVER_TYPE_100G_AOC 0x0f
#define ETH_TRANSCEIVER_TYPE_100G_SR4 0x10
#define ETH_TRANSCEIVER_TYPE_100G_LR4 0x11
#define ETH_TRANSCEIVER_TYPE_100G_ER4 0x12
#define ETH_TRANSCEIVER_TYPE_100G_ACC 0x13
#define ETH_TRANSCEIVER_TYPE_100G_CR4 0x14
#define ETH_TRANSCEIVER_TYPE_4x10G_SR 0x15
#define ETH_TRANSCEIVER_TYPE_25G_CA_N 0x16
#define ETH_TRANSCEIVER_TYPE_25G_ACC_S 0x17
#define ETH_TRANSCEIVER_TYPE_25G_CA_S 0x18
#define ETH_TRANSCEIVER_TYPE_25G_ACC_M 0x19
#define ETH_TRANSCEIVER_TYPE_25G_CA_L 0x1a
#define ETH_TRANSCEIVER_TYPE_25G_ACC_L 0x1b
#define ETH_TRANSCEIVER_TYPE_25G_SR 0x1c
#define ETH_TRANSCEIVER_TYPE_25G_LR 0x1d
#define ETH_TRANSCEIVER_TYPE_25G_AOC 0x1e
#define ETH_TRANSCEIVER_TYPE_4x10G 0x1f
#define ETH_TRANSCEIVER_TYPE_4x25G_CR 0x20
#define ETH_TRANSCEIVER_TYPE_1000BASET 0x21
#define ETH_TRANSCEIVER_TYPE_10G_BASET 0x22
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR 0x30
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR 0x31
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR 0x32
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR 0x33
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR 0x34
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR 0x35
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36
u32 wol_info;
u32 wol_pkt_len;
u32 wol_pkt_details;
......@@ -13199,6 +13244,13 @@ struct nvm_cfg1_port {
u32 transceiver_00;
u32 device_ids;
u32 board_cfg;
#define NVM_CFG1_PORT_PORT_TYPE_MASK 0x000000FF
#define NVM_CFG1_PORT_PORT_TYPE_OFFSET 0
#define NVM_CFG1_PORT_PORT_TYPE_UNDEFINED 0x0
#define NVM_CFG1_PORT_PORT_TYPE_MODULE 0x1
#define NVM_CFG1_PORT_PORT_TYPE_BACKPLANE 0x2
#define NVM_CFG1_PORT_PORT_TYPE_EXT_PHY 0x3
#define NVM_CFG1_PORT_PORT_TYPE_MODULE_SLAVE 0x4
u32 mnm_10g_cap;
u32 mnm_10g_ctrl;
u32 mnm_10g_misc;
......
This diff is collapsed.
......@@ -1447,7 +1447,7 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE)
qed_mcp_read_eee_config(p_hwfn, p_ptt, p_link);
qed_link_update(p_hwfn);
qed_link_update(p_hwfn, p_ptt);
out:
spin_unlock_bh(&p_hwfn->mcp_info->link_lock);
}
......@@ -1867,12 +1867,12 @@ int qed_mcp_get_mbi_ver(struct qed_hwfn *p_hwfn,
return 0;
}
int qed_mcp_get_media_type(struct qed_dev *cdev, u32 *p_media_type)
int qed_mcp_get_media_type(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u32 *p_media_type)
{
struct qed_hwfn *p_hwfn = &cdev->hwfns[0];
struct qed_ptt *p_ptt;
*p_media_type = MEDIA_UNSPECIFIED;
if (IS_VF(cdev))
if (IS_VF(p_hwfn->cdev))
return -EINVAL;
if (!qed_mcp_is_init(p_hwfn)) {
......@@ -1880,16 +1880,195 @@ int qed_mcp_get_media_type(struct qed_dev *cdev, u32 *p_media_type)
return -EBUSY;
}
*p_media_type = MEDIA_UNSPECIFIED;
if (!p_ptt) {
*p_media_type = MEDIA_UNSPECIFIED;
return -EINVAL;
}
p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt)
*p_media_type = qed_rd(p_hwfn, p_ptt,
p_hwfn->mcp_info->port_addr +
offsetof(struct public_port,
media_type));
return 0;
}
int qed_mcp_get_transceiver_data(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 *p_transceiver_state,
u32 *p_transceiver_type)
{
u32 transceiver_info;
if (IS_VF(p_hwfn->cdev))
return -EINVAL;
if (!qed_mcp_is_init(p_hwfn)) {
DP_NOTICE(p_hwfn, "MFW is not initialized!\n");
return -EBUSY;
}
*p_media_type = qed_rd(p_hwfn, p_ptt, p_hwfn->mcp_info->port_addr +
offsetof(struct public_port, media_type));
*p_transceiver_type = ETH_TRANSCEIVER_TYPE_NONE;
*p_transceiver_state = ETH_TRANSCEIVER_STATE_UPDATING;
qed_ptt_release(p_hwfn, p_ptt);
transceiver_info = qed_rd(p_hwfn, p_ptt,
p_hwfn->mcp_info->port_addr +
offsetof(struct public_port,
transceiver_data));
*p_transceiver_state = (transceiver_info &
ETH_TRANSCEIVER_STATE_MASK) >>
ETH_TRANSCEIVER_STATE_OFFSET;
if (*p_transceiver_state == ETH_TRANSCEIVER_STATE_PRESENT)
*p_transceiver_type = (transceiver_info &
ETH_TRANSCEIVER_TYPE_MASK) >>
ETH_TRANSCEIVER_TYPE_OFFSET;
else
*p_transceiver_type = ETH_TRANSCEIVER_TYPE_UNKNOWN;
return 0;
}
static bool qed_is_transceiver_ready(u32 transceiver_state,
u32 transceiver_type)
{
if ((transceiver_state & ETH_TRANSCEIVER_STATE_PRESENT) &&
((transceiver_state & ETH_TRANSCEIVER_STATE_UPDATING) == 0x0) &&
(transceiver_type != ETH_TRANSCEIVER_TYPE_NONE))
return true;
return false;
}
int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u32 *p_speed_mask)
{
u32 transceiver_type, transceiver_state;
qed_mcp_get_transceiver_data(p_hwfn, p_ptt, &transceiver_state,
&transceiver_type);
if (qed_is_transceiver_ready(transceiver_state, transceiver_type) ==
false)
return -EINVAL;
switch (transceiver_type) {
case ETH_TRANSCEIVER_TYPE_1G_LX:
case ETH_TRANSCEIVER_TYPE_1G_SX:
case ETH_TRANSCEIVER_TYPE_1G_PCC:
case ETH_TRANSCEIVER_TYPE_1G_ACC:
case ETH_TRANSCEIVER_TYPE_1000BASET:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
case ETH_TRANSCEIVER_TYPE_10G_SR:
case ETH_TRANSCEIVER_TYPE_10G_LR:
case ETH_TRANSCEIVER_TYPE_10G_LRM:
case ETH_TRANSCEIVER_TYPE_10G_ER:
case ETH_TRANSCEIVER_TYPE_10G_PCC:
case ETH_TRANSCEIVER_TYPE_10G_ACC:
case ETH_TRANSCEIVER_TYPE_4x10G:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
break;
case ETH_TRANSCEIVER_TYPE_40G_LR4:
case ETH_TRANSCEIVER_TYPE_40G_SR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
break;
case ETH_TRANSCEIVER_TYPE_100G_AOC:
case ETH_TRANSCEIVER_TYPE_100G_SR4:
case ETH_TRANSCEIVER_TYPE_100G_LR4:
case ETH_TRANSCEIVER_TYPE_100G_ER4:
case ETH_TRANSCEIVER_TYPE_100G_ACC:
*p_speed_mask =
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
break;
case ETH_TRANSCEIVER_TYPE_25G_SR:
case ETH_TRANSCEIVER_TYPE_25G_LR:
case ETH_TRANSCEIVER_TYPE_25G_AOC:
case ETH_TRANSCEIVER_TYPE_25G_ACC_S:
case ETH_TRANSCEIVER_TYPE_25G_ACC_M:
case ETH_TRANSCEIVER_TYPE_25G_ACC_L:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
break;
case ETH_TRANSCEIVER_TYPE_25G_CA_N:
case ETH_TRANSCEIVER_TYPE_25G_CA_S:
case ETH_TRANSCEIVER_TYPE_25G_CA_L:
case ETH_TRANSCEIVER_TYPE_4x25G_CR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
case ETH_TRANSCEIVER_TYPE_40G_CR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
case ETH_TRANSCEIVER_TYPE_100G_CR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
*p_speed_mask =
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC:
*p_speed_mask =
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
break;
case ETH_TRANSCEIVER_TYPE_XLPPI:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
break;
case ETH_TRANSCEIVER_TYPE_10G_BASET:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
default:
DP_INFO(p_hwfn, "Unknown transcevier type 0x%x\n",
transceiver_type);
*p_speed_mask = 0xff;
break;
}
return 0;
}
int qed_mcp_get_board_config(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u32 *p_board_config)
{
u32 nvm_cfg_addr, nvm_cfg1_offset, port_cfg_addr;
if (IS_VF(p_hwfn->cdev))
return -EINVAL;
if (!qed_mcp_is_init(p_hwfn)) {
DP_NOTICE(p_hwfn, "MFW is not initialized!\n");
return -EBUSY;
}
if (!p_ptt) {
*p_board_config = NVM_CFG1_PORT_PORT_TYPE_UNDEFINED;
return -EINVAL;
}
nvm_cfg_addr = qed_rd(p_hwfn, p_ptt, MISC_REG_GEN_PURP_CR0);
nvm_cfg1_offset = qed_rd(p_hwfn, p_ptt, nvm_cfg_addr + 4);
port_cfg_addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
offsetof(struct nvm_cfg1, port[MFW_PORT(p_hwfn)]);
*p_board_config = qed_rd(p_hwfn, p_ptt,
port_cfg_addr +
offsetof(struct nvm_cfg1_port,
board_cfg));
return 0;
}
......
......@@ -322,14 +322,61 @@ int qed_mcp_get_mbi_ver(struct qed_hwfn *p_hwfn,
* @brief Get media type value of the port.
*
* @param cdev - qed dev pointer
* @param p_ptt
* @param mfw_ver - media type value
*
* @return int -
* 0 - Operation was successul.
* -EBUSY - Operation failed
*/
int qed_mcp_get_media_type(struct qed_dev *cdev,
u32 *media_type);
int qed_mcp_get_media_type(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u32 *media_type);
/**
* @brief Get transceiver data of the port.
*
* @param cdev - qed dev pointer
* @param p_ptt
* @param p_transceiver_state - transceiver state.
* @param p_transceiver_type - media type value
*
* @return int -
* 0 - Operation was successful.
* -EBUSY - Operation failed
*/
int qed_mcp_get_transceiver_data(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt,
u32 *p_transceiver_state,
u32 *p_tranceiver_type);
/**
* @brief Get transceiver supported speed mask.
*
* @param cdev - qed dev pointer
* @param p_ptt
* @param p_speed_mask - Bit mask of all supported speeds.
*
* @return int -
* 0 - Operation was successful.
* -EBUSY - Operation failed
*/
int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u32 *p_speed_mask);
/**
* @brief Get board configuration.
*
* @param cdev - qed dev pointer
* @param p_ptt
* @param p_board_config - Board config.
*
* @return int -
* 0 - Operation was successful.
* -EBUSY - Operation failed
*/
int qed_mcp_get_board_config(struct qed_hwfn *p_hwfn,
struct qed_ptt *p_ptt, u32 *p_board_config);
/**
* @brief General function for sending commands to the MCP
......
......@@ -1688,7 +1688,7 @@ static void qed_handle_bulletin_change(struct qed_hwfn *hwfn)
ops->ports_update(cookie, vxlan_port, geneve_port);
/* Always update link configuration according to bulletin */
qed_link_update(hwfn);
qed_link_update(hwfn, NULL);
}
void qed_iov_vf_task(struct work_struct *work)
......
......@@ -413,19 +413,42 @@ struct qede_link_mode_mapping {
};
static const struct qede_link_mode_mapping qed_lm_map[] = {
{QED_LM_FIBRE_BIT, ETHTOOL_LINK_MODE_FIBRE_BIT},
{QED_LM_Autoneg_BIT, ETHTOOL_LINK_MODE_Autoneg_BIT},
{QED_LM_Asym_Pause_BIT, ETHTOOL_LINK_MODE_Asym_Pause_BIT},
{QED_LM_Pause_BIT, ETHTOOL_LINK_MODE_Pause_BIT},
{QED_LM_1000baseT_Half_BIT, ETHTOOL_LINK_MODE_1000baseT_Half_BIT},
{QED_LM_1000baseT_Full_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
{QED_LM_10000baseT_Full_BIT, ETHTOOL_LINK_MODE_10000baseT_Full_BIT},
{QED_LM_2500baseX_Full_BIT, ETHTOOL_LINK_MODE_2500baseX_Full_BIT},
{QED_LM_Backplane_BIT, ETHTOOL_LINK_MODE_Backplane_BIT},
{QED_LM_1000baseKX_Full_BIT, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT},
{QED_LM_10000baseKX4_Full_BIT, ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT},
{QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT},
{QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT},
{QED_LM_10000baseR_FEC_BIT, ETHTOOL_LINK_MODE_10000baseR_FEC_BIT},
{QED_LM_20000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT},
{QED_LM_25000baseKR_Full_BIT, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT},
{QED_LM_40000baseKR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT},
{QED_LM_40000baseCR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT},
{QED_LM_40000baseSR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT},
{QED_LM_40000baseLR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT},
{QED_LM_25000baseCR_Full_BIT, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT},
{QED_LM_25000baseKR_Full_BIT, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT},
{QED_LM_25000baseSR_Full_BIT, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT},
{QED_LM_50000baseCR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT},
{QED_LM_50000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT},
{QED_LM_100000baseKR4_Full_BIT,
ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT},
ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT},
{QED_LM_100000baseSR4_Full_BIT,
ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT},
{QED_LM_100000baseCR4_Full_BIT,
ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT},
{QED_LM_100000baseLR4_ER4_Full_BIT,
ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT},
{QED_LM_50000baseSR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT},
{QED_LM_1000baseX_Full_BIT, ETHTOOL_LINK_MODE_1000baseX_Full_BIT},
{QED_LM_10000baseCR_Full_BIT, ETHTOOL_LINK_MODE_10000baseCR_Full_BIT},
{QED_LM_10000baseSR_Full_BIT, ETHTOOL_LINK_MODE_10000baseSR_Full_BIT},
{QED_LM_10000baseLR_Full_BIT, ETHTOOL_LINK_MODE_10000baseLR_Full_BIT},
{QED_LM_10000baseLRM_Full_BIT, ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT},
};
#define QEDE_DRV_TO_ETHTOOL_CAPS(caps, lk_ksettings, name) \
......@@ -495,6 +518,7 @@ static int qede_set_link_ksettings(struct net_device *dev,
struct qede_dev *edev = netdev_priv(dev);
struct qed_link_output current_link;
struct qed_link_params params;
u32 sup_caps;
if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
DP_INFO(edev, "Link settings are not allowed to be changed\n");
......@@ -521,60 +545,85 @@ static int qede_set_link_ksettings(struct net_device *dev,
params.forced_speed = base->speed;
switch (base->speed) {
case SPEED_1000:
if (!(current_link.supported_caps &
QED_LM_1000baseT_Full_BIT)) {
sup_caps = QED_LM_1000baseT_Full_BIT |
QED_LM_1000baseKX_Full_BIT |
QED_LM_1000baseX_Full_BIT;
if (!(current_link.supported_caps & sup_caps)) {
DP_INFO(edev, "1G speed not supported\n");
return -EINVAL;
}
params.adv_speeds = QED_LM_1000baseT_Full_BIT;
params.adv_speeds = current_link.supported_caps &
sup_caps;
break;
case SPEED_10000:
if (!(current_link.supported_caps &
QED_LM_10000baseKR_Full_BIT)) {
sup_caps = QED_LM_10000baseT_Full_BIT |
QED_LM_10000baseKR_Full_BIT |
QED_LM_10000baseKX4_Full_BIT |
QED_LM_10000baseR_FEC_BIT |
QED_LM_10000baseCR_Full_BIT |
QED_LM_10000baseSR_Full_BIT |
QED_LM_10000baseLR_Full_BIT |
QED_LM_10000baseLRM_Full_BIT;
if (!(current_link.supported_caps & sup_caps)) {
DP_INFO(edev, "10G speed not supported\n");
return -EINVAL;
}
params.adv_speeds = QED_LM_10000baseKR_Full_BIT;
params.adv_speeds = current_link.supported_caps &
sup_caps;
break;
case SPEED_20000:
if (!(current_link.supported_caps &
QED_LM_20000baseKR2_Full_BIT)) {
QED_LM_20000baseKR2_Full_BIT)) {
DP_INFO(edev, "20G speed not supported\n");
return -EINVAL;
}
params.adv_speeds = QED_LM_20000baseKR2_Full_BIT;
break;
case SPEED_25000:
if (!(current_link.supported_caps &
QED_LM_25000baseKR_Full_BIT)) {
sup_caps = QED_LM_25000baseKR_Full_BIT |
QED_LM_25000baseCR_Full_BIT |
QED_LM_25000baseSR_Full_BIT;
if (!(current_link.supported_caps & sup_caps)) {
DP_INFO(edev, "25G speed not supported\n");
return -EINVAL;
}
params.adv_speeds = QED_LM_25000baseKR_Full_BIT;
params.adv_speeds = current_link.supported_caps &
sup_caps;
break;
case SPEED_40000:
if (!(current_link.supported_caps &
QED_LM_40000baseLR4_Full_BIT)) {
sup_caps = QED_LM_40000baseLR4_Full_BIT |
QED_LM_40000baseKR4_Full_BIT |
QED_LM_40000baseCR4_Full_BIT |
QED_LM_40000baseSR4_Full_BIT;
if (!(current_link.supported_caps & sup_caps)) {
DP_INFO(edev, "40G speed not supported\n");
return -EINVAL;
}
params.adv_speeds = QED_LM_40000baseLR4_Full_BIT;
params.adv_speeds = current_link.supported_caps &
sup_caps;
break;
case SPEED_50000:
if (!(current_link.supported_caps &
QED_LM_50000baseKR2_Full_BIT)) {
sup_caps = QED_LM_50000baseKR2_Full_BIT |
QED_LM_50000baseCR2_Full_BIT |
QED_LM_50000baseSR2_Full_BIT;
if (!(current_link.supported_caps & sup_caps)) {
DP_INFO(edev, "50G speed not supported\n");
return -EINVAL;
}
params.adv_speeds = QED_LM_50000baseKR2_Full_BIT;
params.adv_speeds = current_link.supported_caps &
sup_caps;
break;
case SPEED_100000:
if (!(current_link.supported_caps &
QED_LM_100000baseKR4_Full_BIT)) {
sup_caps = QED_LM_100000baseKR4_Full_BIT |
QED_LM_100000baseSR4_Full_BIT |
QED_LM_100000baseCR4_Full_BIT |
QED_LM_100000baseLR4_ER4_Full_BIT;
if (!(current_link.supported_caps & sup_caps)) {
DP_INFO(edev, "100G speed not supported\n");
return -EINVAL;
}
params.adv_speeds = QED_LM_100000baseKR4_Full_BIT;
params.adv_speeds = current_link.supported_caps &
sup_caps;
break;
default:
DP_INFO(edev, "Unsupported speed %u\n", base->speed);
......
......@@ -667,15 +667,35 @@ enum qed_link_mode_bits {
QED_LM_Autoneg_BIT = BIT(1),
QED_LM_Asym_Pause_BIT = BIT(2),
QED_LM_Pause_BIT = BIT(3),
QED_LM_1000baseT_Half_BIT = BIT(4),
QED_LM_1000baseT_Full_BIT = BIT(5),
QED_LM_1000baseT_Full_BIT = BIT(4),
QED_LM_10000baseT_Full_BIT = BIT(5),
QED_LM_10000baseKR_Full_BIT = BIT(6),
QED_LM_20000baseKR2_Full_BIT = BIT(7),
QED_LM_25000baseKR_Full_BIT = BIT(8),
QED_LM_40000baseLR4_Full_BIT = BIT(9),
QED_LM_50000baseKR2_Full_BIT = BIT(10),
QED_LM_100000baseKR4_Full_BIT = BIT(11),
QED_LM_COUNT = 11
QED_LM_2500baseX_Full_BIT = BIT(12),
QED_LM_Backplane_BIT = BIT(13),
QED_LM_1000baseKX_Full_BIT = BIT(14),
QED_LM_10000baseKX4_Full_BIT = BIT(15),
QED_LM_10000baseR_FEC_BIT = BIT(16),
QED_LM_40000baseKR4_Full_BIT = BIT(17),
QED_LM_40000baseCR4_Full_BIT = BIT(18),
QED_LM_40000baseSR4_Full_BIT = BIT(19),
QED_LM_25000baseCR_Full_BIT = BIT(20),
QED_LM_25000baseSR_Full_BIT = BIT(21),
QED_LM_50000baseCR2_Full_BIT = BIT(22),
QED_LM_100000baseSR4_Full_BIT = BIT(23),
QED_LM_100000baseCR4_Full_BIT = BIT(24),
QED_LM_100000baseLR4_ER4_Full_BIT = BIT(25),
QED_LM_50000baseSR2_Full_BIT = BIT(26),
QED_LM_1000baseX_Full_BIT = BIT(27),
QED_LM_10000baseCR_Full_BIT = BIT(28),
QED_LM_10000baseSR_Full_BIT = BIT(29),
QED_LM_10000baseLR_Full_BIT = BIT(30),
QED_LM_10000baseLRM_Full_BIT = BIT(31),
QED_LM_COUNT = 32
};
struct qed_link_params {
......
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