Commit 9228b7c1 authored by Alexander Lobakin's avatar Alexander Lobakin Committed by David S. Miller

qed: add support for multi-rate transceivers

Set the corresponding advertised and supported link modes according
to the detected transceiver type and device capabilities.
Signed-off-by: default avatarAlexander Lobakin <alobakin@marvell.com>
Signed-off-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d47839f3
...@@ -12027,6 +12027,10 @@ struct public_port { ...@@ -12027,6 +12027,10 @@ struct public_port {
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR 0x34 #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_LR 0x35
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36 #define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR 0x37
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR 0x38
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR 0x39
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR 0x3a
u32 wol_info; u32 wol_info;
u32 wol_pkt_len; u32 wol_pkt_len;
......
...@@ -1696,21 +1696,40 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn, ...@@ -1696,21 +1696,40 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
phylink_set(if_caps, 20000baseKR2_Full); phylink_set(if_caps, 20000baseKR2_Full);
/* For DAC media multiple speed capabilities are supported*/ /* For DAC media multiple speed capabilities are supported */
capability = capability & speed_mask; capability |= speed_mask;
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
phylink_set(if_caps, 1000baseKX_Full); phylink_set(if_caps, 1000baseKX_Full);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
phylink_set(if_caps, 10000baseCR_Full); phylink_set(if_caps, 10000baseCR_Full);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
phylink_set(if_caps, 40000baseCR4_Full); switch (tcvr_type) {
case ETH_TRANSCEIVER_TYPE_40G_CR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
phylink_set(if_caps, 40000baseCR4_Full);
break;
default:
break;
}
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
phylink_set(if_caps, 25000baseCR_Full); phylink_set(if_caps, 25000baseCR_Full);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
phylink_set(if_caps, 50000baseCR2_Full); phylink_set(if_caps, 50000baseCR2_Full);
if (capability & if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
phylink_set(if_caps, 100000baseCR4_Full); switch (tcvr_type) {
case ETH_TRANSCEIVER_TYPE_100G_CR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
phylink_set(if_caps, 100000baseCR4_Full);
break;
default:
break;
}
break; break;
case MEDIA_BASE_T: case MEDIA_BASE_T:
...@@ -1728,10 +1747,16 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn, ...@@ -1728,10 +1747,16 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) { if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) {
phylink_set(if_caps, FIBRE); phylink_set(if_caps, FIBRE);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_1000BASET) switch (tcvr_type) {
case ETH_TRANSCEIVER_TYPE_1000BASET:
phylink_set(if_caps, 1000baseT_Full); phylink_set(if_caps, 1000baseT_Full);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_BASET) break;
case ETH_TRANSCEIVER_TYPE_10G_BASET:
phylink_set(if_caps, 10000baseT_Full); phylink_set(if_caps, 10000baseT_Full);
break;
default:
break;
}
} }
break; break;
...@@ -1740,47 +1765,89 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn, ...@@ -1740,47 +1765,89 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
case MEDIA_XFP_FIBER: case MEDIA_XFP_FIBER:
case MEDIA_MODULE_FIBER: case MEDIA_MODULE_FIBER:
phylink_set(if_caps, FIBRE); phylink_set(if_caps, FIBRE);
capability |= speed_mask;
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) { if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
if ((tcvr_type == ETH_TRANSCEIVER_TYPE_1G_LX) || switch (tcvr_type) {
(tcvr_type == ETH_TRANSCEIVER_TYPE_1G_SX)) case ETH_TRANSCEIVER_TYPE_1G_LX:
case ETH_TRANSCEIVER_TYPE_1G_SX:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
phylink_set(if_caps, 1000baseKX_Full); phylink_set(if_caps, 1000baseKX_Full);
} break;
default:
break;
}
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) { if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_SR) switch (tcvr_type) {
case ETH_TRANSCEIVER_TYPE_10G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
phylink_set(if_caps, 10000baseSR_Full); phylink_set(if_caps, 10000baseSR_Full);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LR) break;
case ETH_TRANSCEIVER_TYPE_10G_LR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
phylink_set(if_caps, 10000baseLR_Full); phylink_set(if_caps, 10000baseLR_Full);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LRM) break;
case ETH_TRANSCEIVER_TYPE_10G_LRM:
phylink_set(if_caps, 10000baseLRM_Full); phylink_set(if_caps, 10000baseLRM_Full);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_ER) break;
case ETH_TRANSCEIVER_TYPE_10G_ER:
phylink_set(if_caps, 10000baseR_FEC); phylink_set(if_caps, 10000baseR_FEC);
} break;
default:
break;
}
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
phylink_set(if_caps, 20000baseKR2_Full); phylink_set(if_caps, 20000baseKR2_Full);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) { if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
if (tcvr_type == ETH_TRANSCEIVER_TYPE_25G_SR) switch (tcvr_type) {
case ETH_TRANSCEIVER_TYPE_25G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
phylink_set(if_caps, 25000baseSR_Full); phylink_set(if_caps, 25000baseSR_Full);
} break;
default:
break;
}
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) { if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_LR4) switch (tcvr_type) {
case ETH_TRANSCEIVER_TYPE_40G_LR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
phylink_set(if_caps, 40000baseLR4_Full); phylink_set(if_caps, 40000baseLR4_Full);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_SR4) break;
case ETH_TRANSCEIVER_TYPE_40G_SR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
phylink_set(if_caps, 40000baseSR4_Full); phylink_set(if_caps, 40000baseSR4_Full);
} break;
default:
break;
}
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
phylink_set(if_caps, 50000baseKR2_Full); phylink_set(if_caps, 50000baseKR2_Full);
if (capability & if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) { NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
if (tcvr_type == ETH_TRANSCEIVER_TYPE_100G_SR4) switch (tcvr_type) {
case ETH_TRANSCEIVER_TYPE_100G_SR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
phylink_set(if_caps, 100000baseSR4_Full); phylink_set(if_caps, 100000baseSR4_Full);
} break;
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
phylink_set(if_caps, 100000baseLR4_ER4_Full);
break;
default:
break;
}
break; break;
case MEDIA_KR: case MEDIA_KR:
...@@ -1805,6 +1872,7 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn, ...@@ -1805,6 +1872,7 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
break; break;
case MEDIA_UNSPECIFIED: case MEDIA_UNSPECIFIED:
case MEDIA_NOT_PRESENT: case MEDIA_NOT_PRESENT:
default:
DP_VERBOSE(hwfn->cdev, QED_MSG_DEBUG, DP_VERBOSE(hwfn->cdev, QED_MSG_DEBUG,
"Unknown media and transceiver type;\n"); "Unknown media and transceiver type;\n");
break; break;
......
...@@ -2193,6 +2193,11 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn, ...@@ -2193,6 +2193,11 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G | NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G; NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break; break;
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
break;
case ETH_TRANSCEIVER_TYPE_40G_CR4: case ETH_TRANSCEIVER_TYPE_40G_CR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR: case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G | *p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G |
...@@ -2223,8 +2228,10 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn, ...@@ -2223,8 +2228,10 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G; *p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
break; break;
case ETH_TRANSCEIVER_TYPE_10G_BASET: case ETH_TRANSCEIVER_TYPE_10G_BASET:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G | *p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G; NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break; break;
default: default:
DP_INFO(p_hwfn, "Unknown transceiver type 0x%x\n", DP_INFO(p_hwfn, "Unknown transceiver type 0x%x\n",
......
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