Skip to content

Commit 540e3f3

Browse files
net:eth:ethtool support of cable detection and error case handling
1 parent a35e409 commit 540e3f3

File tree

1 file changed

+102
-31
lines changed

1 file changed

+102
-31
lines changed

drivers/net/ethernet/altera/intel_fpga_hssi_etile_ethtool.c

Lines changed: 102 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
// SPDX-License-Identifier: GPL-2.0
1+
// SPDX-License-Identifier: GPL
22
/* Ethtool support for Intel FPGA E-tile Ethernet MAC driver
3-
* Copyright (C) 2019-2022 Intel Corporation. All rights reserved
3+
* Copyright (C) 2022,2023 Intel Corporation. All rights reserved
44
*
55
* Contributors:
6-
* Roman Bulgakov
7-
* Yu Ying Choo
8-
* Dalon Westergreen
9-
* Joyce Ooi
10-
*
11-
* Original driver contributed by GlobalLogic.
6+
* Preetam Narayan
127
*/
138

149
#include <linux/ethtool.h>
@@ -1067,8 +1062,8 @@ static void etile_get_regs(struct net_device *dev,
10671062
}
10681063

10691064
static void etile_get_pauseparam(struct net_device *dev,
1070-
struct ethtool_pauseparam *pauseparam)
1071-
{
1065+
struct ethtool_pauseparam *pauseparam) {
1066+
10721067
struct intel_fpga_etile_eth_private *priv = netdev_priv(dev);
10731068

10741069
pauseparam->rx_pause = 0;
@@ -1082,8 +1077,8 @@ static void etile_get_pauseparam(struct net_device *dev,
10821077
}
10831078

10841079
static int etile_set_pauseparam(struct net_device *dev,
1085-
struct ethtool_pauseparam *pauseparam)
1086-
{
1080+
struct ethtool_pauseparam *pauseparam) {
1081+
10871082
struct intel_fpga_etile_eth_private *priv = netdev_priv(dev);
10881083
struct platform_device *pdev = priv->pdev_hssi;
10891084
u32 chan = priv->chan;
@@ -1100,28 +1095,35 @@ static int etile_set_pauseparam(struct net_device *dev,
11001095

11011096
if (pauseparam->rx_pause) {
11021097
new_pause |= FLOW_RX;
1103-
hssi_set_bit(pdev, HSSI_ETH_RECONFIG, chan,
1104-
eth_pause_and_priority_csroffs(rx_flow_control_feature_cfg),
1105-
ETH_RX_EN_STD_FLOW_CTRL);
1106-
} else {
1107-
hssi_clear_bit(pdev, HSSI_ETH_RECONFIG, chan,
1108-
eth_pause_and_priority_csroffs(rx_flow_control_feature_cfg),
1109-
ETH_RX_EN_STD_FLOW_CTRL);
1098+
hssi_set_bit_atomic(pdev,
1099+
HSSI_ETH_RECONFIG, chan,
1100+
eth_pause_and_priority_csroffs(rx_flow_control_feature_cfg),
1101+
ETH_RX_EN_STD_FLOW_CTRL);
1102+
}
1103+
else {
1104+
hssi_clear_bit_atomic(pdev,
1105+
HSSI_ETH_RECONFIG, chan,
1106+
eth_pause_and_priority_csroffs(rx_flow_control_feature_cfg),
1107+
ETH_RX_EN_STD_FLOW_CTRL);
11101108
}
11111109

11121110
if (pauseparam->tx_pause) {
11131111
new_pause |= FLOW_TX;
1114-
hssi_set_bit(pdev, HSSI_ETH_RECONFIG, chan,
1115-
eth_pause_and_priority_csroffs(tx_flow_control_feature_cfg),
1116-
ETH_TX_EN_STD_FLOW_CTRL);
1117-
} else {
1118-
hssi_clear_bit(pdev, HSSI_ETH_RECONFIG, chan,
1119-
eth_pause_and_priority_csroffs(tx_flow_control_feature_cfg),
1120-
ETH_TX_EN_STD_FLOW_CTRL);
1112+
hssi_set_bit_atomic(pdev,
1113+
HSSI_ETH_RECONFIG, chan,
1114+
eth_pause_and_priority_csroffs(tx_flow_control_feature_cfg),
1115+
ETH_TX_EN_STD_FLOW_CTRL);
1116+
}
1117+
else {
1118+
hssi_clear_bit_atomic(pdev,
1119+
HSSI_ETH_RECONFIG, chan,
1120+
eth_pause_and_priority_csroffs(tx_flow_control_feature_cfg),
1121+
ETH_TX_EN_STD_FLOW_CTRL);
11211122
}
11221123

1123-
hssi_csrwr32(pdev, HSSI_ETH_RECONFIG, chan,
1124-
eth_pause_and_priority_csroffs(pause_quanta_0), priv->pause);
1124+
hssi_csrwr32_atomic(pdev, HSSI_ETH_RECONFIG, chan,
1125+
eth_pause_and_priority_csroffs(pause_quanta_0), priv->pause);
1126+
11251127
priv->flow_ctrl = new_pause;
11261128
out:
11271129
spin_unlock(&priv->mac_cfg_lock);
@@ -1132,14 +1134,13 @@ static int etile_get_ts_info(struct net_device *dev,
11321134
struct ethtool_ts_info *info)
11331135
{
11341136

1135-
#if 0
11361137
struct intel_fpga_etile_eth_private *priv = netdev_priv(dev);
11371138

11381139
if (priv->ptp_priv.ptp_clock)
11391140
info->phc_index = ptp_clock_index(priv->ptp_priv.ptp_clock);
11401141
else
1141-
#endif
11421142
info->phc_index = -1;
1143+
11431144
info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
11441145
SOF_TIMESTAMPING_RX_HARDWARE |
11451146
SOF_TIMESTAMPING_RAW_HARDWARE;
@@ -1184,13 +1185,82 @@ static int etile_get_link_ksettings(struct net_device *dev,
11841185
struct ethtool_link_ksettings *cmd)
11851186
{
11861187
struct intel_fpga_etile_eth_private *priv = netdev_priv(dev);
1188+
int ret;
11871189

11881190
if (!priv)
11891191
return -ENODEV;
11901192

1191-
return phylink_ethtool_ksettings_get(priv->phylink, cmd);
1193+
if (!netif_running(dev))
1194+
{
1195+
cmd->base.speed = 0;
1196+
cmd->base.duplex = DUPLEX_UNKNOWN;
1197+
}
1198+
1199+
ret = phylink_ethtool_ksettings_get(priv->phylink, cmd);
1200+
return ret;
1201+
}
1202+
1203+
static int etile_get_link_ext_state(struct net_device *net_dev,
1204+
struct ethtool_link_ext_state_info *link_ext_state_info)
1205+
{
1206+
struct intel_fpga_etile_eth_private *priv = netdev_priv(net_dev);
1207+
1208+
if (netif_carrier_ok(net_dev))
1209+
return -ENODATA;
1210+
1211+
if (priv->cable_unplugged)
1212+
link_ext_state_info->link_ext_state =
1213+
ETHTOOL_LINK_EXT_STATE_NO_CABLE;
1214+
1215+
return 0;
11921216
}
11931217

1218+
#ifdef TO_BE_IMPLEMENTED
1219+
static int etile_map_reset_flags(struct net_device *net_dev, u32 *flags) {
1220+
1221+
struct intel_fpga_etile_eth_private *priv = netdev_priv(net_dev);
1222+
struct platform_device *pdev = priv->pdev_hssi;
1223+
1224+
u32 ethflag = *flags;
1225+
1226+
if (!priv)
1227+
return -ENODEV;
1228+
1229+
while(ethflag != 0) {
1230+
1231+
switch(ethflag & 1) {
1232+
1233+
case ETH_RESET_PHY:
1234+
pma_digital_reset(priv, true, true);
1235+
pma_analog_reset(priv);
1236+
ethflag &= ~ETH_RESET_PHY;
1237+
break;
1238+
1239+
case ETH_RESET_ALL:
1240+
hssi_cold_rst(pdev);
1241+
priv->dmaops->reset_dma(&priv->dma_priv);
1242+
ethflag &= ~ETH_RESET_ALL;
1243+
break;
1244+
1245+
case ETH_RESET_DMA:
1246+
priv->dmaops->reset_dma(&priv->dma_priv);
1247+
ethflag &= ~ETH_RESET_DMA;
1248+
break;
1249+
1250+
case ETH_RESET_FILTER:
1251+
priv->dma_priv.hwts_tx_en = 0;
1252+
priv->dma_priv.hwts_rx_en = 0;
1253+
break;
1254+
1255+
default:
1256+
break;
1257+
}
1258+
1259+
ethflag >>= 1;
1260+
}
1261+
}
1262+
#endif
1263+
11941264
static const struct ethtool_ops xtile_ethtool_ops = {
11951265
.get_drvinfo = etile_get_drvinfo,
11961266
.get_regs_len = etile_reglen,
@@ -1206,6 +1276,7 @@ static const struct ethtool_ops xtile_ethtool_ops = {
12061276
.get_ts_info = etile_get_ts_info,
12071277
.get_link_ksettings = etile_get_link_ksettings,
12081278
.set_link_ksettings = etile_set_link_ksettings,
1279+
.get_link_ext_state = etile_get_link_ext_state,
12091280
};
12101281

12111282
void intel_fpga_xtile_set_ethtool_ops(struct net_device *netdev)

0 commit comments

Comments
 (0)