| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * drivers/net/ethernet/freescale/gianfar_ethtool.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 10 | 11 | * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> |
|---|
| 11 | 12 | * |
|---|
| 12 | 13 | * Copyright 2003-2006, 2008-2009, 2011 Freescale Semiconductor, Inc. |
|---|
| 13 | | - * |
|---|
| 14 | | - * This software may be used and distributed according to |
|---|
| 15 | | - * the terms of the GNU Public License, Version 2, incorporated herein |
|---|
| 16 | | - * by reference. |
|---|
| 17 | 14 | */ |
|---|
| 18 | 15 | |
|---|
| 19 | 16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 48 | 45 | |
|---|
| 49 | 46 | #define GFAR_MAX_COAL_USECS 0xffff |
|---|
| 50 | 47 | #define GFAR_MAX_COAL_FRAMES 0xff |
|---|
| 51 | | -static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, |
|---|
| 52 | | - u64 *buf); |
|---|
| 53 | | -static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf); |
|---|
| 54 | | -static int gfar_gcoalesce(struct net_device *dev, |
|---|
| 55 | | - struct ethtool_coalesce *cvals); |
|---|
| 56 | | -static int gfar_scoalesce(struct net_device *dev, |
|---|
| 57 | | - struct ethtool_coalesce *cvals); |
|---|
| 58 | | -static void gfar_gringparam(struct net_device *dev, |
|---|
| 59 | | - struct ethtool_ringparam *rvals); |
|---|
| 60 | | -static int gfar_sringparam(struct net_device *dev, |
|---|
| 61 | | - struct ethtool_ringparam *rvals); |
|---|
| 62 | | -static void gfar_gdrvinfo(struct net_device *dev, |
|---|
| 63 | | - struct ethtool_drvinfo *drvinfo); |
|---|
| 64 | 48 | |
|---|
| 65 | 49 | static const char stat_gstrings[][ETH_GSTRING_LEN] = { |
|---|
| 66 | 50 | /* extra stats */ |
|---|
| .. | .. |
|---|
| 180 | 164 | struct ethtool_drvinfo *drvinfo) |
|---|
| 181 | 165 | { |
|---|
| 182 | 166 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
|---|
| 183 | | - strlcpy(drvinfo->version, gfar_driver_version, |
|---|
| 184 | | - sizeof(drvinfo->version)); |
|---|
| 185 | | - strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version)); |
|---|
| 186 | | - strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info)); |
|---|
| 187 | 167 | } |
|---|
| 188 | 168 | |
|---|
| 189 | 169 | /* Return the length of the register structure */ |
|---|
| .. | .. |
|---|
| 230 | 210 | |
|---|
| 231 | 211 | /* Make sure we return a number greater than 0 |
|---|
| 232 | 212 | * if usecs > 0 */ |
|---|
| 233 | | - return (usecs * 1000 + count - 1) / count; |
|---|
| 213 | + return DIV_ROUND_UP(usecs * 1000, count); |
|---|
| 234 | 214 | } |
|---|
| 235 | 215 | |
|---|
| 236 | 216 | /* Convert ethernet clock ticks to microseconds */ |
|---|
| .. | .. |
|---|
| 291 | 271 | |
|---|
| 292 | 272 | cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, txtime); |
|---|
| 293 | 273 | cvals->tx_max_coalesced_frames = txcount; |
|---|
| 294 | | - |
|---|
| 295 | | - cvals->use_adaptive_rx_coalesce = 0; |
|---|
| 296 | | - cvals->use_adaptive_tx_coalesce = 0; |
|---|
| 297 | | - |
|---|
| 298 | | - cvals->pkt_rate_low = 0; |
|---|
| 299 | | - cvals->rx_coalesce_usecs_low = 0; |
|---|
| 300 | | - cvals->rx_max_coalesced_frames_low = 0; |
|---|
| 301 | | - cvals->tx_coalesce_usecs_low = 0; |
|---|
| 302 | | - cvals->tx_max_coalesced_frames_low = 0; |
|---|
| 303 | | - |
|---|
| 304 | | - /* When the packet rate is below pkt_rate_high but above |
|---|
| 305 | | - * pkt_rate_low (both measured in packets per second) the |
|---|
| 306 | | - * normal {rx,tx}_* coalescing parameters are used. |
|---|
| 307 | | - */ |
|---|
| 308 | | - |
|---|
| 309 | | - /* When the packet rate is (measured in packets per second) |
|---|
| 310 | | - * is above pkt_rate_high, the {rx,tx}_*_high parameters are |
|---|
| 311 | | - * used. |
|---|
| 312 | | - */ |
|---|
| 313 | | - cvals->pkt_rate_high = 0; |
|---|
| 314 | | - cvals->rx_coalesce_usecs_high = 0; |
|---|
| 315 | | - cvals->rx_max_coalesced_frames_high = 0; |
|---|
| 316 | | - cvals->tx_coalesce_usecs_high = 0; |
|---|
| 317 | | - cvals->tx_max_coalesced_frames_high = 0; |
|---|
| 318 | | - |
|---|
| 319 | | - /* How often to do adaptive coalescing packet rate sampling, |
|---|
| 320 | | - * measured in seconds. Must not be zero. |
|---|
| 321 | | - */ |
|---|
| 322 | | - cvals->rate_sample_interval = 0; |
|---|
| 323 | 274 | |
|---|
| 324 | 275 | return 0; |
|---|
| 325 | 276 | } |
|---|
| .. | .. |
|---|
| 503 | 454 | struct gfar_private *priv = netdev_priv(dev); |
|---|
| 504 | 455 | struct phy_device *phydev = dev->phydev; |
|---|
| 505 | 456 | struct gfar __iomem *regs = priv->gfargrp[0].regs; |
|---|
| 506 | | - u32 oldadv, newadv; |
|---|
| 507 | 457 | |
|---|
| 508 | 458 | if (!phydev) |
|---|
| 509 | 459 | return -ENODEV; |
|---|
| 510 | 460 | |
|---|
| 511 | | - if (!(phydev->supported & SUPPORTED_Pause) || |
|---|
| 512 | | - (!(phydev->supported & SUPPORTED_Asym_Pause) && |
|---|
| 513 | | - (epause->rx_pause != epause->tx_pause))) |
|---|
| 461 | + if (!phy_validate_pause(phydev, epause)) |
|---|
| 514 | 462 | return -EINVAL; |
|---|
| 515 | 463 | |
|---|
| 516 | 464 | priv->rx_pause_en = priv->tx_pause_en = 0; |
|---|
| 465 | + phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause); |
|---|
| 517 | 466 | if (epause->rx_pause) { |
|---|
| 518 | 467 | priv->rx_pause_en = 1; |
|---|
| 519 | 468 | |
|---|
| 520 | 469 | if (epause->tx_pause) { |
|---|
| 521 | 470 | priv->tx_pause_en = 1; |
|---|
| 522 | | - /* FLOW_CTRL_RX & TX */ |
|---|
| 523 | | - newadv = ADVERTISED_Pause; |
|---|
| 524 | | - } else /* FLOW_CTLR_RX */ |
|---|
| 525 | | - newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause; |
|---|
| 471 | + } |
|---|
| 526 | 472 | } else if (epause->tx_pause) { |
|---|
| 527 | 473 | priv->tx_pause_en = 1; |
|---|
| 528 | | - /* FLOW_CTLR_TX */ |
|---|
| 529 | | - newadv = ADVERTISED_Asym_Pause; |
|---|
| 530 | | - } else |
|---|
| 531 | | - newadv = 0; |
|---|
| 474 | + } |
|---|
| 532 | 475 | |
|---|
| 533 | 476 | if (epause->autoneg) |
|---|
| 534 | 477 | priv->pause_aneg_en = 1; |
|---|
| 535 | 478 | else |
|---|
| 536 | 479 | priv->pause_aneg_en = 0; |
|---|
| 537 | 480 | |
|---|
| 538 | | - oldadv = phydev->advertising & |
|---|
| 539 | | - (ADVERTISED_Pause | ADVERTISED_Asym_Pause); |
|---|
| 540 | | - if (oldadv != newadv) { |
|---|
| 541 | | - phydev->advertising &= |
|---|
| 542 | | - ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); |
|---|
| 543 | | - phydev->advertising |= newadv; |
|---|
| 544 | | - if (phydev->autoneg) |
|---|
| 545 | | - /* inform link partner of our |
|---|
| 546 | | - * new flow ctrl settings |
|---|
| 547 | | - */ |
|---|
| 548 | | - return phy_start_aneg(phydev); |
|---|
| 481 | + if (!epause->autoneg) { |
|---|
| 482 | + u32 tempval = gfar_read(®s->maccfg1); |
|---|
| 549 | 483 | |
|---|
| 550 | | - if (!epause->autoneg) { |
|---|
| 551 | | - u32 tempval; |
|---|
| 552 | | - tempval = gfar_read(®s->maccfg1); |
|---|
| 553 | | - tempval &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); |
|---|
| 484 | + tempval &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); |
|---|
| 554 | 485 | |
|---|
| 555 | | - priv->tx_actual_en = 0; |
|---|
| 556 | | - if (priv->tx_pause_en) { |
|---|
| 557 | | - priv->tx_actual_en = 1; |
|---|
| 558 | | - tempval |= MACCFG1_TX_FLOW; |
|---|
| 559 | | - } |
|---|
| 560 | | - |
|---|
| 561 | | - if (priv->rx_pause_en) |
|---|
| 562 | | - tempval |= MACCFG1_RX_FLOW; |
|---|
| 563 | | - gfar_write(®s->maccfg1, tempval); |
|---|
| 486 | + priv->tx_actual_en = 0; |
|---|
| 487 | + if (priv->tx_pause_en) { |
|---|
| 488 | + priv->tx_actual_en = 1; |
|---|
| 489 | + tempval |= MACCFG1_TX_FLOW; |
|---|
| 564 | 490 | } |
|---|
| 491 | + |
|---|
| 492 | + if (priv->rx_pause_en) |
|---|
| 493 | + tempval |= MACCFG1_RX_FLOW; |
|---|
| 494 | + gfar_write(®s->maccfg1, tempval); |
|---|
| 565 | 495 | } |
|---|
| 566 | 496 | |
|---|
| 567 | 497 | return 0; |
|---|
| .. | .. |
|---|
| 1155 | 1085 | prio = vlan_tci_prio(rule); |
|---|
| 1156 | 1086 | prio_mask = vlan_tci_priom(rule); |
|---|
| 1157 | 1087 | |
|---|
| 1158 | | - if (cfi == VLAN_TAG_PRESENT && cfi_mask == VLAN_TAG_PRESENT) { |
|---|
| 1159 | | - vlan |= RQFPR_CFI; |
|---|
| 1160 | | - vlan_mask |= RQFPR_CFI; |
|---|
| 1161 | | - } else if (cfi != VLAN_TAG_PRESENT && |
|---|
| 1162 | | - cfi_mask == VLAN_TAG_PRESENT) { |
|---|
| 1088 | + if (cfi_mask) { |
|---|
| 1089 | + if (cfi) |
|---|
| 1090 | + vlan |= RQFPR_CFI; |
|---|
| 1163 | 1091 | vlan_mask |= RQFPR_CFI; |
|---|
| 1164 | 1092 | } |
|---|
| 1165 | 1093 | } |
|---|
| .. | .. |
|---|
| 1515 | 1443 | struct gfar_private *priv = netdev_priv(dev); |
|---|
| 1516 | 1444 | struct platform_device *ptp_dev; |
|---|
| 1517 | 1445 | struct device_node *ptp_node; |
|---|
| 1518 | | - struct qoriq_ptp *ptp = NULL; |
|---|
| 1446 | + struct ptp_qoriq *ptp = NULL; |
|---|
| 1519 | 1447 | |
|---|
| 1520 | 1448 | info->phc_index = -1; |
|---|
| 1521 | 1449 | |
|---|
| .. | .. |
|---|
| 1528 | 1456 | ptp_node = of_find_compatible_node(NULL, NULL, "fsl,etsec-ptp"); |
|---|
| 1529 | 1457 | if (ptp_node) { |
|---|
| 1530 | 1458 | ptp_dev = of_find_device_by_node(ptp_node); |
|---|
| 1459 | + of_node_put(ptp_node); |
|---|
| 1531 | 1460 | if (ptp_dev) |
|---|
| 1532 | 1461 | ptp = platform_get_drvdata(ptp_dev); |
|---|
| 1533 | 1462 | } |
|---|
| .. | .. |
|---|
| 1546 | 1475 | } |
|---|
| 1547 | 1476 | |
|---|
| 1548 | 1477 | const struct ethtool_ops gfar_ethtool_ops = { |
|---|
| 1478 | + .supported_coalesce_params = ETHTOOL_COALESCE_USECS | |
|---|
| 1479 | + ETHTOOL_COALESCE_MAX_FRAMES, |
|---|
| 1549 | 1480 | .get_drvinfo = gfar_gdrvinfo, |
|---|
| 1550 | 1481 | .get_regs_len = gfar_reglen, |
|---|
| 1551 | 1482 | .get_regs = gfar_get_regs, |
|---|