Skip to content

Commit

Permalink
qed: Add supported link and advertise link to display in ethtool.
Browse files Browse the repository at this point in the history
	Added transceiver type, speed capability and board types
	in HSI, are utilizing to display the accurate link
	information in ethtool.

Signed-off-by: Rahul Verma <Rahul.Verma@cavium.com>
Signed-off-by: Ariel Elior <ariel.elior@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Rahul Verma authored and David S. Miller committed Oct 16, 2018
1 parent e292b63 commit c56a8be
Show file tree
Hide file tree
Showing 5 changed files with 426 additions and 58 deletions.
199 changes: 148 additions & 51 deletions drivers/net/ethernet/qlogic/qed/qed_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "qed_iscsi.h"

#include "qed_mcp.h"
#include "qed_reg_addr.h"
#include "qed_hw.h"
#include "qed_selftest.h"
#include "qed_debug.h"
Expand Down Expand Up @@ -1330,8 +1331,7 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
link_params->speed.autoneg = params->autoneg;
if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) {
link_params->speed.advertised_speeds = 0;
if ((params->adv_speeds & QED_LM_1000baseT_Half_BIT) ||
(params->adv_speeds & QED_LM_1000baseT_Full_BIT))
if (params->adv_speeds & QED_LM_1000baseT_Full_BIT)
link_params->speed.advertised_speeds |=
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
if (params->adv_speeds & QED_LM_10000baseKR_Full_BIT)
Expand Down Expand Up @@ -1462,13 +1462,149 @@ static int qed_get_link_data(struct qed_hwfn *hwfn,
return 0;
}

static void qed_fill_link_capability(struct qed_hwfn *hwfn,
struct qed_ptt *ptt, u32 capability,
u32 *if_capability)
{
u32 media_type, tcvr_state, tcvr_type;
u32 speed_mask, board_cfg;

if (qed_mcp_get_media_type(hwfn, ptt, &media_type))
media_type = MEDIA_UNSPECIFIED;

if (qed_mcp_get_transceiver_data(hwfn, ptt, &tcvr_state, &tcvr_type))
tcvr_type = ETH_TRANSCEIVER_STATE_UNPLUGGED;

if (qed_mcp_trans_speed_mask(hwfn, ptt, &speed_mask))
speed_mask = 0xFFFFFFFF;

if (qed_mcp_get_board_config(hwfn, ptt, &board_cfg))
board_cfg = NVM_CFG1_PORT_PORT_TYPE_UNDEFINED;

DP_VERBOSE(hwfn->cdev, NETIF_MSG_DRV,
"Media_type = 0x%x tcvr_state = 0x%x tcvr_type = 0x%x speed_mask = 0x%x board_cfg = 0x%x\n",
media_type, tcvr_state, tcvr_type, speed_mask, board_cfg);

switch (media_type) {
case MEDIA_DA_TWINAX:
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
*if_capability |= QED_LM_20000baseKR2_Full_BIT;
/* For DAC media multiple speed capabilities are supported*/
capability = capability & speed_mask;
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
*if_capability |= QED_LM_1000baseKX_Full_BIT;
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
*if_capability |= QED_LM_10000baseCR_Full_BIT;
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
*if_capability |= QED_LM_40000baseCR4_Full_BIT;
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
*if_capability |= QED_LM_25000baseCR_Full_BIT;
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
*if_capability |= QED_LM_50000baseCR2_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
*if_capability |= QED_LM_100000baseCR4_Full_BIT;
break;
case MEDIA_BASE_T:
if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_EXT_PHY) {
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) {
*if_capability |= QED_LM_1000baseT_Full_BIT;
}
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) {
*if_capability |= QED_LM_10000baseT_Full_BIT;
}
}
if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) {
if (tcvr_type == ETH_TRANSCEIVER_TYPE_1000BASET)
*if_capability |= QED_LM_1000baseT_Full_BIT;
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_BASET)
*if_capability |= QED_LM_10000baseT_Full_BIT;
}
break;
case MEDIA_SFP_1G_FIBER:
case MEDIA_SFPP_10G_FIBER:
case MEDIA_XFP_FIBER:
case MEDIA_MODULE_FIBER:
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) {
if ((tcvr_type == ETH_TRANSCEIVER_TYPE_1G_LX) ||
(tcvr_type == ETH_TRANSCEIVER_TYPE_1G_SX))
*if_capability |= QED_LM_1000baseKX_Full_BIT;
}
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) {
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_SR)
*if_capability |= QED_LM_10000baseSR_Full_BIT;
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LR)
*if_capability |= QED_LM_10000baseLR_Full_BIT;
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LRM)
*if_capability |= QED_LM_10000baseLRM_Full_BIT;
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_ER)
*if_capability |= QED_LM_10000baseR_FEC_BIT;
}
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
*if_capability |= QED_LM_20000baseKR2_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) {
if (tcvr_type == ETH_TRANSCEIVER_TYPE_25G_SR)
*if_capability |= QED_LM_25000baseSR_Full_BIT;
}
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) {
if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_LR4)
*if_capability |= QED_LM_40000baseLR4_Full_BIT;
if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_SR4)
*if_capability |= QED_LM_40000baseSR4_Full_BIT;
}
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
*if_capability |= QED_LM_50000baseKR2_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) {
if (tcvr_type == ETH_TRANSCEIVER_TYPE_100G_SR4)
*if_capability |= QED_LM_100000baseSR4_Full_BIT;
}

break;
case MEDIA_KR:
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
*if_capability |= QED_LM_20000baseKR2_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
*if_capability |= QED_LM_1000baseKX_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
*if_capability |= QED_LM_10000baseKR_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
*if_capability |= QED_LM_25000baseKR_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
*if_capability |= QED_LM_40000baseKR4_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
*if_capability |= QED_LM_50000baseKR2_Full_BIT;
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
*if_capability |= QED_LM_100000baseKR4_Full_BIT;
break;
case MEDIA_UNSPECIFIED:
case MEDIA_NOT_PRESENT:
DP_VERBOSE(hwfn->cdev, QED_MSG_DEBUG,
"Unknown media and transceiver type;\n");
break;
}
}

static void qed_fill_link(struct qed_hwfn *hwfn,
struct qed_ptt *ptt,
struct qed_link_output *if_link)
{
struct qed_mcp_link_capabilities link_caps;
struct qed_mcp_link_params params;
struct qed_mcp_link_state link;
struct qed_mcp_link_capabilities link_caps;
u32 media_type;

memset(if_link, 0, sizeof(*if_link));
Expand Down Expand Up @@ -1499,51 +1635,13 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
if_link->advertised_caps |= QED_LM_Autoneg_BIT;
else
if_link->advertised_caps &= ~QED_LM_Autoneg_BIT;
if (params.speed.advertised_speeds &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
if_link->advertised_caps |= QED_LM_1000baseT_Half_BIT |
QED_LM_1000baseT_Full_BIT;
if (params.speed.advertised_speeds &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
if_link->advertised_caps |= QED_LM_10000baseKR_Full_BIT;
if (params.speed.advertised_speeds &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
if_link->advertised_caps |= QED_LM_20000baseKR2_Full_BIT;
if (params.speed.advertised_speeds &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
if_link->advertised_caps |= QED_LM_25000baseKR_Full_BIT;
if (params.speed.advertised_speeds &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
if_link->advertised_caps |= QED_LM_40000baseLR4_Full_BIT;
if (params.speed.advertised_speeds &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
if_link->advertised_caps |= QED_LM_50000baseKR2_Full_BIT;
if (params.speed.advertised_speeds &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
if_link->advertised_caps |= QED_LM_100000baseKR4_Full_BIT;

if (link_caps.speed_capabilities &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
if_link->supported_caps |= QED_LM_1000baseT_Half_BIT |
QED_LM_1000baseT_Full_BIT;
if (link_caps.speed_capabilities &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
if_link->supported_caps |= QED_LM_10000baseKR_Full_BIT;
if (link_caps.speed_capabilities &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
if_link->supported_caps |= QED_LM_20000baseKR2_Full_BIT;
if (link_caps.speed_capabilities &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
if_link->supported_caps |= QED_LM_25000baseKR_Full_BIT;
if (link_caps.speed_capabilities &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
if_link->supported_caps |= QED_LM_40000baseLR4_Full_BIT;
if (link_caps.speed_capabilities &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
if_link->supported_caps |= QED_LM_50000baseKR2_Full_BIT;
if (link_caps.speed_capabilities &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
if_link->supported_caps |= QED_LM_100000baseKR4_Full_BIT;

/* Fill link advertised capability*/
qed_fill_link_capability(hwfn, ptt, params.speed.advertised_speeds,
&if_link->advertised_caps);
/* Fill link supported capability*/
qed_fill_link_capability(hwfn, ptt, link_caps.speed_capabilities,
&if_link->supported_caps);

if (link.link_up)
if_link->speed = link.speed;
Expand All @@ -1563,9 +1661,8 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE;

/* Link partner capabilities */
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_1G_HD)
if_link->lp_caps |= QED_LM_1000baseT_Half_BIT;
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_1G_FD)
if (link.partner_adv_speed &
QED_LINK_PARTNER_SPEED_1G_FD)
if_link->lp_caps |= QED_LM_1000baseT_Full_BIT;
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_10G)
if_link->lp_caps |= QED_LM_10000baseKR_Full_BIT;
Expand Down
Loading

0 comments on commit c56a8be

Please sign in to comment.