0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/kernel.h>
0015 #include <linux/errno.h>
0016 #include <linux/stddef.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/netdevice.h>
0019 #include <linux/etherdevice.h>
0020 #include <linux/skbuff.h>
0021 #include <linux/spinlock.h>
0022 #include <linux/mm.h>
0023 #include <linux/delay.h>
0024 #include <linux/dma-mapping.h>
0025 #include <linux/ethtool.h>
0026 #include <linux/mii.h>
0027 #include <linux/phy.h>
0028
0029 #include <asm/io.h>
0030 #include <asm/irq.h>
0031 #include <linux/uaccess.h>
0032 #include <asm/types.h>
0033
0034 #include "ucc_geth.h"
0035
0036 static const char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
0037 "tx-64-frames",
0038 "tx-65-127-frames",
0039 "tx-128-255-frames",
0040 "rx-64-frames",
0041 "rx-65-127-frames",
0042 "rx-128-255-frames",
0043 "tx-bytes-ok",
0044 "tx-pause-frames",
0045 "tx-multicast-frames",
0046 "tx-broadcast-frames",
0047 "rx-frames",
0048 "rx-bytes-ok",
0049 "rx-bytes-all",
0050 "rx-multicast-frames",
0051 "rx-broadcast-frames",
0052 "stats-counter-carry",
0053 "stats-counter-mask",
0054 "rx-dropped-frames",
0055 };
0056
0057 static const char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
0058 "tx-single-collision",
0059 "tx-multiple-collision",
0060 "tx-late-collision",
0061 "tx-aborted-frames",
0062 "tx-lost-frames",
0063 "tx-carrier-sense-errors",
0064 "tx-frames-ok",
0065 "tx-excessive-differ-frames",
0066 "tx-256-511-frames",
0067 "tx-512-1023-frames",
0068 "tx-1024-1518-frames",
0069 "tx-jumbo-frames",
0070 };
0071
0072 static const char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
0073 "rx-crc-errors",
0074 "rx-alignment-errors",
0075 "rx-in-range-length-errors",
0076 "rx-out-of-range-length-errors",
0077 "rx-too-long-frames",
0078 "rx-runt",
0079 "rx-very-long-event",
0080 "rx-symbol-errors",
0081 "rx-busy-drop-frames",
0082 "reserved",
0083 "reserved",
0084 "rx-mismatch-drop-frames",
0085 "rx-small-than-64",
0086 "rx-256-511-frames",
0087 "rx-512-1023-frames",
0088 "rx-1024-1518-frames",
0089 "rx-jumbo-frames",
0090 "rx-mac-error-loss",
0091 "rx-pause-frames",
0092 "reserved",
0093 "rx-vlan-removed",
0094 "rx-vlan-replaced",
0095 "rx-vlan-inserted",
0096 "rx-ip-checksum-errors",
0097 };
0098
0099 #define UEC_HW_STATS_LEN ARRAY_SIZE(hw_stat_gstrings)
0100 #define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings)
0101 #define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings)
0102
0103 static int
0104 uec_get_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd)
0105 {
0106 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0107 struct phy_device *phydev = ugeth->phydev;
0108
0109 if (!phydev)
0110 return -ENODEV;
0111
0112 phy_ethtool_ksettings_get(phydev, cmd);
0113
0114 return 0;
0115 }
0116
0117 static int
0118 uec_set_ksettings(struct net_device *netdev,
0119 const struct ethtool_link_ksettings *cmd)
0120 {
0121 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0122 struct phy_device *phydev = ugeth->phydev;
0123
0124 if (!phydev)
0125 return -ENODEV;
0126
0127 return phy_ethtool_ksettings_set(phydev, cmd);
0128 }
0129
0130 static void
0131 uec_get_pauseparam(struct net_device *netdev,
0132 struct ethtool_pauseparam *pause)
0133 {
0134 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0135
0136 pause->autoneg = ugeth->phydev->autoneg;
0137
0138 if (ugeth->ug_info->receiveFlowControl)
0139 pause->rx_pause = 1;
0140 if (ugeth->ug_info->transmitFlowControl)
0141 pause->tx_pause = 1;
0142 }
0143
0144 static int
0145 uec_set_pauseparam(struct net_device *netdev,
0146 struct ethtool_pauseparam *pause)
0147 {
0148 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0149 int ret = 0;
0150
0151 ugeth->ug_info->receiveFlowControl = pause->rx_pause;
0152 ugeth->ug_info->transmitFlowControl = pause->tx_pause;
0153
0154 if (ugeth->phydev->autoneg) {
0155 if (netif_running(netdev)) {
0156
0157 netdev_info(netdev, "Please re-open the interface\n");
0158 }
0159 } else {
0160 struct ucc_geth_info *ug_info = ugeth->ug_info;
0161
0162 ret = init_flow_control_params(ug_info->aufc,
0163 ug_info->receiveFlowControl,
0164 ug_info->transmitFlowControl,
0165 ug_info->pausePeriod,
0166 ug_info->extensionField,
0167 &ugeth->uccf->uf_regs->upsmr,
0168 &ugeth->ug_regs->uempr,
0169 &ugeth->ug_regs->maccfg1);
0170 }
0171
0172 return ret;
0173 }
0174
0175 static uint32_t
0176 uec_get_msglevel(struct net_device *netdev)
0177 {
0178 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0179 return ugeth->msg_enable;
0180 }
0181
0182 static void
0183 uec_set_msglevel(struct net_device *netdev, uint32_t data)
0184 {
0185 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0186 ugeth->msg_enable = data;
0187 }
0188
0189 static int
0190 uec_get_regs_len(struct net_device *netdev)
0191 {
0192 return sizeof(struct ucc_geth);
0193 }
0194
0195 static void
0196 uec_get_regs(struct net_device *netdev,
0197 struct ethtool_regs *regs, void *p)
0198 {
0199 int i;
0200 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0201 u32 __iomem *ug_regs = (u32 __iomem *)ugeth->ug_regs;
0202 u32 *buff = p;
0203
0204 for (i = 0; i < sizeof(struct ucc_geth) / sizeof(u32); i++)
0205 buff[i] = in_be32(&ug_regs[i]);
0206 }
0207
0208 static void
0209 uec_get_ringparam(struct net_device *netdev,
0210 struct ethtool_ringparam *ring,
0211 struct kernel_ethtool_ringparam *kernel_ring,
0212 struct netlink_ext_ack *extack)
0213 {
0214 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0215 struct ucc_geth_info *ug_info = ugeth->ug_info;
0216 int queue = 0;
0217
0218 ring->rx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
0219 ring->rx_mini_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
0220 ring->rx_jumbo_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
0221 ring->tx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
0222
0223 ring->rx_pending = ug_info->bdRingLenRx[queue];
0224 ring->rx_mini_pending = ug_info->bdRingLenRx[queue];
0225 ring->rx_jumbo_pending = ug_info->bdRingLenRx[queue];
0226 ring->tx_pending = ug_info->bdRingLenTx[queue];
0227 }
0228
0229 static int
0230 uec_set_ringparam(struct net_device *netdev,
0231 struct ethtool_ringparam *ring,
0232 struct kernel_ethtool_ringparam *kernel_ring,
0233 struct netlink_ext_ack *extack)
0234 {
0235 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0236 struct ucc_geth_info *ug_info = ugeth->ug_info;
0237 int queue = 0, ret = 0;
0238
0239 if (ring->rx_pending < UCC_GETH_RX_BD_RING_SIZE_MIN) {
0240 netdev_info(netdev, "RxBD ring size must be no smaller than %d\n",
0241 UCC_GETH_RX_BD_RING_SIZE_MIN);
0242 return -EINVAL;
0243 }
0244 if (ring->rx_pending % UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT) {
0245 netdev_info(netdev, "RxBD ring size must be multiple of %d\n",
0246 UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT);
0247 return -EINVAL;
0248 }
0249 if (ring->tx_pending < UCC_GETH_TX_BD_RING_SIZE_MIN) {
0250 netdev_info(netdev, "TxBD ring size must be no smaller than %d\n",
0251 UCC_GETH_TX_BD_RING_SIZE_MIN);
0252 return -EINVAL;
0253 }
0254
0255 if (netif_running(netdev))
0256 return -EBUSY;
0257
0258 ug_info->bdRingLenRx[queue] = ring->rx_pending;
0259 ug_info->bdRingLenTx[queue] = ring->tx_pending;
0260
0261 return ret;
0262 }
0263
0264 static int uec_get_sset_count(struct net_device *netdev, int sset)
0265 {
0266 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0267 u32 stats_mode = ugeth->ug_info->statisticsMode;
0268 int len = 0;
0269
0270 switch (sset) {
0271 case ETH_SS_STATS:
0272 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE)
0273 len += UEC_HW_STATS_LEN;
0274 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX)
0275 len += UEC_TX_FW_STATS_LEN;
0276 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
0277 len += UEC_RX_FW_STATS_LEN;
0278
0279 return len;
0280
0281 default:
0282 return -EOPNOTSUPP;
0283 }
0284 }
0285
0286 static void uec_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
0287 {
0288 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0289 u32 stats_mode = ugeth->ug_info->statisticsMode;
0290
0291 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
0292 memcpy(buf, hw_stat_gstrings, UEC_HW_STATS_LEN *
0293 ETH_GSTRING_LEN);
0294 buf += UEC_HW_STATS_LEN * ETH_GSTRING_LEN;
0295 }
0296 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
0297 memcpy(buf, tx_fw_stat_gstrings, UEC_TX_FW_STATS_LEN *
0298 ETH_GSTRING_LEN);
0299 buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN;
0300 }
0301 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
0302 memcpy(buf, rx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN *
0303 ETH_GSTRING_LEN);
0304 }
0305
0306 static void uec_get_ethtool_stats(struct net_device *netdev,
0307 struct ethtool_stats *stats, uint64_t *data)
0308 {
0309 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0310 u32 stats_mode = ugeth->ug_info->statisticsMode;
0311 u32 __iomem *base;
0312 int i, j = 0;
0313
0314 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
0315 if (ugeth->ug_regs)
0316 base = (u32 __iomem *)&ugeth->ug_regs->tx64;
0317 else
0318 base = NULL;
0319
0320 for (i = 0; i < UEC_HW_STATS_LEN; i++)
0321 data[j++] = base ? in_be32(&base[i]) : 0;
0322 }
0323 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
0324 base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram;
0325 for (i = 0; i < UEC_TX_FW_STATS_LEN; i++)
0326 data[j++] = base ? in_be32(&base[i]) : 0;
0327 }
0328 if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
0329 base = (u32 __iomem *)ugeth->p_rx_fw_statistics_pram;
0330 for (i = 0; i < UEC_RX_FW_STATS_LEN; i++)
0331 data[j++] = base ? in_be32(&base[i]) : 0;
0332 }
0333 }
0334
0335
0336 static void
0337 uec_get_drvinfo(struct net_device *netdev,
0338 struct ethtool_drvinfo *drvinfo)
0339 {
0340 strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
0341 strlcpy(drvinfo->bus_info, "QUICC ENGINE", sizeof(drvinfo->bus_info));
0342 }
0343
0344 #ifdef CONFIG_PM
0345
0346 static void uec_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
0347 {
0348 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0349 struct phy_device *phydev = ugeth->phydev;
0350
0351 if (phydev && phydev->irq)
0352 wol->supported |= WAKE_PHY;
0353 if (qe_alive_during_sleep())
0354 wol->supported |= WAKE_MAGIC;
0355
0356 wol->wolopts = ugeth->wol_en;
0357 }
0358
0359 static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
0360 {
0361 struct ucc_geth_private *ugeth = netdev_priv(netdev);
0362 struct phy_device *phydev = ugeth->phydev;
0363
0364 if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
0365 return -EINVAL;
0366 else if (wol->wolopts & WAKE_PHY && (!phydev || !phydev->irq))
0367 return -EINVAL;
0368 else if (wol->wolopts & WAKE_MAGIC && !qe_alive_during_sleep())
0369 return -EINVAL;
0370
0371 ugeth->wol_en = wol->wolopts;
0372 device_set_wakeup_enable(&netdev->dev, ugeth->wol_en);
0373
0374 return 0;
0375 }
0376
0377 #else
0378 #define uec_get_wol NULL
0379 #define uec_set_wol NULL
0380 #endif
0381
0382 static const struct ethtool_ops uec_ethtool_ops = {
0383 .get_drvinfo = uec_get_drvinfo,
0384 .get_regs_len = uec_get_regs_len,
0385 .get_regs = uec_get_regs,
0386 .get_msglevel = uec_get_msglevel,
0387 .set_msglevel = uec_set_msglevel,
0388 .nway_reset = phy_ethtool_nway_reset,
0389 .get_link = ethtool_op_get_link,
0390 .get_ringparam = uec_get_ringparam,
0391 .set_ringparam = uec_set_ringparam,
0392 .get_pauseparam = uec_get_pauseparam,
0393 .set_pauseparam = uec_set_pauseparam,
0394 .get_sset_count = uec_get_sset_count,
0395 .get_strings = uec_get_strings,
0396 .get_ethtool_stats = uec_get_ethtool_stats,
0397 .get_wol = uec_get_wol,
0398 .set_wol = uec_set_wol,
0399 .get_ts_info = ethtool_op_get_ts_info,
0400 .get_link_ksettings = uec_get_ksettings,
0401 .set_link_ksettings = uec_set_ksettings,
0402 };
0403
0404 void uec_set_ethtool_ops(struct net_device *netdev)
0405 {
0406 netdev->ethtool_ops = &uec_ethtool_ops;
0407 }