linux/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
   2/* Copyright 2017-2019 NXP */
   3
   4#include <linux/net_tstamp.h>
   5#include <linux/module.h>
   6#include "enetc.h"
   7
   8static const u32 enetc_si_regs[] = {
   9        ENETC_SIMR, ENETC_SIPMAR0, ENETC_SIPMAR1, ENETC_SICBDRMR,
  10        ENETC_SICBDRSR, ENETC_SICBDRBAR0, ENETC_SICBDRBAR1, ENETC_SICBDRPIR,
  11        ENETC_SICBDRCIR, ENETC_SICBDRLENR, ENETC_SICAPR0, ENETC_SICAPR1,
  12        ENETC_SIUEFDCR
  13};
  14
  15static const u32 enetc_txbdr_regs[] = {
  16        ENETC_TBMR, ENETC_TBSR, ENETC_TBBAR0, ENETC_TBBAR1,
  17        ENETC_TBPIR, ENETC_TBCIR, ENETC_TBLENR, ENETC_TBIER, ENETC_TBICR0,
  18        ENETC_TBICR1
  19};
  20
  21static const u32 enetc_rxbdr_regs[] = {
  22        ENETC_RBMR, ENETC_RBSR, ENETC_RBBSR, ENETC_RBCIR, ENETC_RBBAR0,
  23        ENETC_RBBAR1, ENETC_RBPIR, ENETC_RBLENR, ENETC_RBIER, ENETC_RBICR0,
  24        ENETC_RBICR1
  25};
  26
  27static const u32 enetc_port_regs[] = {
  28        ENETC_PMR, ENETC_PSR, ENETC_PSIPMR, ENETC_PSIPMAR0(0),
  29        ENETC_PSIPMAR1(0), ENETC_PTXMBAR, ENETC_PCAPR0, ENETC_PCAPR1,
  30        ENETC_PSICFGR0(0), ENETC_PRFSCAPR, ENETC_PTCMSDUR(0),
  31        ENETC_PM0_CMD_CFG, ENETC_PM0_MAXFRM, ENETC_PM0_IF_MODE
  32};
  33
  34static int enetc_get_reglen(struct net_device *ndev)
  35{
  36        struct enetc_ndev_priv *priv = netdev_priv(ndev);
  37        struct enetc_hw *hw = &priv->si->hw;
  38        int len;
  39
  40        len = ARRAY_SIZE(enetc_si_regs);
  41        len += ARRAY_SIZE(enetc_txbdr_regs) * priv->num_tx_rings;
  42        len += ARRAY_SIZE(enetc_rxbdr_regs) * priv->num_rx_rings;
  43
  44        if (hw->port)
  45                len += ARRAY_SIZE(enetc_port_regs);
  46
  47        len *= sizeof(u32) * 2; /* store 2 entries per reg: addr and value */
  48
  49        return len;
  50}
  51
  52static void enetc_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
  53                           void *regbuf)
  54{
  55        struct enetc_ndev_priv *priv = netdev_priv(ndev);
  56        struct enetc_hw *hw = &priv->si->hw;
  57        u32 *buf = (u32 *)regbuf;
  58        int i, j;
  59        u32 addr;
  60
  61        for (i = 0; i < ARRAY_SIZE(enetc_si_regs); i++) {
  62                *buf++ = enetc_si_regs[i];
  63                *buf++ = enetc_rd(hw, enetc_si_regs[i]);
  64        }
  65
  66        for (i = 0; i < priv->num_tx_rings; i++) {
  67                for (j = 0; j < ARRAY_SIZE(enetc_txbdr_regs); j++) {
  68                        addr = ENETC_BDR(TX, i, enetc_txbdr_regs[j]);
  69
  70                        *buf++ = addr;
  71                        *buf++ = enetc_rd(hw, addr);
  72                }
  73        }
  74
  75        for (i = 0; i < priv->num_rx_rings; i++) {
  76                for (j = 0; j < ARRAY_SIZE(enetc_rxbdr_regs); j++) {
  77                        addr = ENETC_BDR(RX, i, enetc_rxbdr_regs[j]);
  78
  79                        *buf++ = addr;
  80                        *buf++ = enetc_rd(hw, addr);
  81                }
  82        }
  83
  84        if (!hw->port)
  85                return;
  86
  87        for (i = 0; i < ARRAY_SIZE(enetc_port_regs); i++) {
  88                addr = ENETC_PORT_BASE + enetc_port_regs[i];
  89                *buf++ = addr;
  90                *buf++ = enetc_rd(hw, addr);
  91        }
  92}
  93
  94static const struct {
  95        int reg;
  96        char name[ETH_GSTRING_LEN];
  97} enetc_si_counters[] =  {
  98        { ENETC_SIROCT, "SI rx octets" },
  99        { ENETC_SIRFRM, "SI rx frames" },
 100        { ENETC_SIRUCA, "SI rx u-cast frames" },
 101        { ENETC_SIRMCA, "SI rx m-cast frames" },
 102        { ENETC_SITOCT, "SI tx octets" },
 103        { ENETC_SITFRM, "SI tx frames" },
 104        { ENETC_SITUCA, "SI tx u-cast frames" },
 105        { ENETC_SITMCA, "SI tx m-cast frames" },
 106        { ENETC_RBDCR(0), "Rx ring  0 discarded frames" },
 107        { ENETC_RBDCR(1), "Rx ring  1 discarded frames" },
 108        { ENETC_RBDCR(2), "Rx ring  2 discarded frames" },
 109        { ENETC_RBDCR(3), "Rx ring  3 discarded frames" },
 110        { ENETC_RBDCR(4), "Rx ring  4 discarded frames" },
 111        { ENETC_RBDCR(5), "Rx ring  5 discarded frames" },
 112        { ENETC_RBDCR(6), "Rx ring  6 discarded frames" },
 113        { ENETC_RBDCR(7), "Rx ring  7 discarded frames" },
 114        { ENETC_RBDCR(8), "Rx ring  8 discarded frames" },
 115        { ENETC_RBDCR(9), "Rx ring  9 discarded frames" },
 116        { ENETC_RBDCR(10), "Rx ring 10 discarded frames" },
 117        { ENETC_RBDCR(11), "Rx ring 11 discarded frames" },
 118        { ENETC_RBDCR(12), "Rx ring 12 discarded frames" },
 119        { ENETC_RBDCR(13), "Rx ring 13 discarded frames" },
 120        { ENETC_RBDCR(14), "Rx ring 14 discarded frames" },
 121        { ENETC_RBDCR(15), "Rx ring 15 discarded frames" },
 122};
 123
 124static const struct {
 125        int reg;
 126        char name[ETH_GSTRING_LEN];
 127} enetc_port_counters[] = {
 128        { ENETC_PM0_REOCT,  "MAC rx ethernet octets" },
 129        { ENETC_PM0_RALN,   "MAC rx alignment errors" },
 130        { ENETC_PM0_RXPF,   "MAC rx valid pause frames" },
 131        { ENETC_PM0_RFRM,   "MAC rx valid frames" },
 132        { ENETC_PM0_RFCS,   "MAC rx fcs errors" },
 133        { ENETC_PM0_RVLAN,  "MAC rx VLAN frames" },
 134        { ENETC_PM0_RERR,   "MAC rx frame errors" },
 135        { ENETC_PM0_RUCA,   "MAC rx unicast frames" },
 136        { ENETC_PM0_RMCA,   "MAC rx multicast frames" },
 137        { ENETC_PM0_RBCA,   "MAC rx broadcast frames" },
 138        { ENETC_PM0_RDRP,   "MAC rx dropped packets" },
 139        { ENETC_PM0_RPKT,   "MAC rx packets" },
 140        { ENETC_PM0_RUND,   "MAC rx undersized packets" },
 141        { ENETC_PM0_R64,    "MAC rx 64 byte packets" },
 142        { ENETC_PM0_R127,   "MAC rx 65-127 byte packets" },
 143        { ENETC_PM0_R255,   "MAC rx 128-255 byte packets" },
 144        { ENETC_PM0_R511,   "MAC rx 256-511 byte packets" },
 145        { ENETC_PM0_R1023,  "MAC rx 512-1023 byte packets" },
 146        { ENETC_PM0_R1522,  "MAC rx 1024-1522 byte packets" },
 147        { ENETC_PM0_R1523X, "MAC rx 1523 to max-octet packets" },
 148        { ENETC_PM0_ROVR,   "MAC rx oversized packets" },
 149        { ENETC_PM0_RJBR,   "MAC rx jabber packets" },
 150        { ENETC_PM0_RFRG,   "MAC rx fragment packets" },
 151        { ENETC_PM0_RCNP,   "MAC rx control packets" },
 152        { ENETC_PM0_RDRNTP, "MAC rx fifo drop" },
 153        { ENETC_PM0_TEOCT,  "MAC tx ethernet octets" },
 154        { ENETC_PM0_TOCT,   "MAC tx octets" },
 155        { ENETC_PM0_TCRSE,  "MAC tx carrier sense errors" },
 156        { ENETC_PM0_TXPF,   "MAC tx valid pause frames" },
 157        { ENETC_PM0_TFRM,   "MAC tx frames" },
 158        { ENETC_PM0_TFCS,   "MAC tx fcs errors" },
 159        { ENETC_PM0_TVLAN,  "MAC tx VLAN frames" },
 160        { ENETC_PM0_TERR,   "MAC tx frame errors" },
 161        { ENETC_PM0_TUCA,   "MAC tx unicast frames" },
 162        { ENETC_PM0_TMCA,   "MAC tx multicast frames" },
 163        { ENETC_PM0_TBCA,   "MAC tx broadcast frames" },
 164        { ENETC_PM0_TPKT,   "MAC tx packets" },
 165        { ENETC_PM0_TUND,   "MAC tx undersized packets" },
 166        { ENETC_PM0_T64,    "MAC tx 64 byte packets" },
 167        { ENETC_PM0_T127,   "MAC tx 65-127 byte packets" },
 168        { ENETC_PM0_T255,   "MAC tx 128-255 byte packets" },
 169        { ENETC_PM0_T511,   "MAC tx 256-511 byte packets" },
 170        { ENETC_PM0_T1023,  "MAC tx 512-1023 byte packets" },
 171        { ENETC_PM0_T1522,  "MAC tx 1024-1522 byte packets" },
 172        { ENETC_PM0_T1523X, "MAC tx 1523 to max-octet packets" },
 173        { ENETC_PM0_TCNP,   "MAC tx control packets" },
 174        { ENETC_PM0_TDFR,   "MAC tx deferred packets" },
 175        { ENETC_PM0_TMCOL,  "MAC tx multiple collisions" },
 176        { ENETC_PM0_TSCOL,  "MAC tx single collisions" },
 177        { ENETC_PM0_TLCOL,  "MAC tx late collisions" },
 178        { ENETC_PM0_TECOL,  "MAC tx excessive collisions" },
 179        { ENETC_UFDMF,      "SI MAC nomatch u-cast discards" },
 180        { ENETC_MFDMF,      "SI MAC nomatch m-cast discards" },
 181        { ENETC_PBFDSIR,    "SI MAC nomatch b-cast discards" },
 182        { ENETC_PUFDVFR,    "SI VLAN nomatch u-cast discards" },
 183        { ENETC_PMFDVFR,    "SI VLAN nomatch m-cast discards" },
 184        { ENETC_PBFDVFR,    "SI VLAN nomatch b-cast discards" },
 185        { ENETC_PFDMSAPR,   "SI pruning discarded frames" },
 186        { ENETC_PICDR(0),   "ICM DR0 discarded frames" },
 187        { ENETC_PICDR(1),   "ICM DR1 discarded frames" },
 188        { ENETC_PICDR(2),   "ICM DR2 discarded frames" },
 189        { ENETC_PICDR(3),   "ICM DR3 discarded frames" },
 190};
 191
 192static const char rx_ring_stats[][ETH_GSTRING_LEN] = {
 193        "Rx ring %2d frames",
 194        "Rx ring %2d alloc errors",
 195        "Rx ring %2d XDP drops",
 196        "Rx ring %2d recycles",
 197        "Rx ring %2d recycle failures",
 198        "Rx ring %2d redirects",
 199        "Rx ring %2d redirect failures",
 200        "Rx ring %2d redirect S/G",
 201};
 202
 203static const char tx_ring_stats[][ETH_GSTRING_LEN] = {
 204        "Tx ring %2d frames",
 205        "Tx ring %2d XDP frames",
 206        "Tx ring %2d XDP drops",
 207};
 208
 209static int enetc_get_sset_count(struct net_device *ndev, int sset)
 210{
 211        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 212        int len;
 213
 214        if (sset != ETH_SS_STATS)
 215                return -EOPNOTSUPP;
 216
 217        len = ARRAY_SIZE(enetc_si_counters) +
 218              ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings +
 219              ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings;
 220
 221        if (!enetc_si_is_pf(priv->si))
 222                return len;
 223
 224        len += ARRAY_SIZE(enetc_port_counters);
 225
 226        return len;
 227}
 228
 229static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
 230{
 231        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 232        u8 *p = data;
 233        int i, j;
 234
 235        switch (stringset) {
 236        case ETH_SS_STATS:
 237                for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++) {
 238                        strlcpy(p, enetc_si_counters[i].name, ETH_GSTRING_LEN);
 239                        p += ETH_GSTRING_LEN;
 240                }
 241                for (i = 0; i < priv->num_tx_rings; i++) {
 242                        for (j = 0; j < ARRAY_SIZE(tx_ring_stats); j++) {
 243                                snprintf(p, ETH_GSTRING_LEN, tx_ring_stats[j],
 244                                         i);
 245                                p += ETH_GSTRING_LEN;
 246                        }
 247                }
 248                for (i = 0; i < priv->num_rx_rings; i++) {
 249                        for (j = 0; j < ARRAY_SIZE(rx_ring_stats); j++) {
 250                                snprintf(p, ETH_GSTRING_LEN, rx_ring_stats[j],
 251                                         i);
 252                                p += ETH_GSTRING_LEN;
 253                        }
 254                }
 255
 256                if (!enetc_si_is_pf(priv->si))
 257                        break;
 258
 259                for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++) {
 260                        strlcpy(p, enetc_port_counters[i].name,
 261                                ETH_GSTRING_LEN);
 262                        p += ETH_GSTRING_LEN;
 263                }
 264                break;
 265        }
 266}
 267
 268static void enetc_get_ethtool_stats(struct net_device *ndev,
 269                                    struct ethtool_stats *stats, u64 *data)
 270{
 271        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 272        struct enetc_hw *hw = &priv->si->hw;
 273        int i, o = 0;
 274
 275        for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++)
 276                data[o++] = enetc_rd64(hw, enetc_si_counters[i].reg);
 277
 278        for (i = 0; i < priv->num_tx_rings; i++) {
 279                data[o++] = priv->tx_ring[i]->stats.packets;
 280                data[o++] = priv->tx_ring[i]->stats.xdp_tx;
 281                data[o++] = priv->tx_ring[i]->stats.xdp_tx_drops;
 282        }
 283
 284        for (i = 0; i < priv->num_rx_rings; i++) {
 285                data[o++] = priv->rx_ring[i]->stats.packets;
 286                data[o++] = priv->rx_ring[i]->stats.rx_alloc_errs;
 287                data[o++] = priv->rx_ring[i]->stats.xdp_drops;
 288                data[o++] = priv->rx_ring[i]->stats.recycles;
 289                data[o++] = priv->rx_ring[i]->stats.recycle_failures;
 290                data[o++] = priv->rx_ring[i]->stats.xdp_redirect;
 291                data[o++] = priv->rx_ring[i]->stats.xdp_redirect_failures;
 292                data[o++] = priv->rx_ring[i]->stats.xdp_redirect_sg;
 293        }
 294
 295        if (!enetc_si_is_pf(priv->si))
 296                return;
 297
 298        for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
 299                data[o++] = enetc_port_rd(hw, enetc_port_counters[i].reg);
 300}
 301
 302#define ENETC_RSSHASH_L3 (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO | RXH_IP_SRC | \
 303                          RXH_IP_DST)
 304#define ENETC_RSSHASH_L4 (ENETC_RSSHASH_L3 | RXH_L4_B_0_1 | RXH_L4_B_2_3)
 305static int enetc_get_rsshash(struct ethtool_rxnfc *rxnfc)
 306{
 307        static const u32 rsshash[] = {
 308                        [TCP_V4_FLOW]    = ENETC_RSSHASH_L4,
 309                        [UDP_V4_FLOW]    = ENETC_RSSHASH_L4,
 310                        [SCTP_V4_FLOW]   = ENETC_RSSHASH_L4,
 311                        [AH_ESP_V4_FLOW] = ENETC_RSSHASH_L3,
 312                        [IPV4_FLOW]      = ENETC_RSSHASH_L3,
 313                        [TCP_V6_FLOW]    = ENETC_RSSHASH_L4,
 314                        [UDP_V6_FLOW]    = ENETC_RSSHASH_L4,
 315                        [SCTP_V6_FLOW]   = ENETC_RSSHASH_L4,
 316                        [AH_ESP_V6_FLOW] = ENETC_RSSHASH_L3,
 317                        [IPV6_FLOW]      = ENETC_RSSHASH_L3,
 318                        [ETHER_FLOW]     = 0,
 319        };
 320
 321        if (rxnfc->flow_type >= ARRAY_SIZE(rsshash))
 322                return -EINVAL;
 323
 324        rxnfc->data = rsshash[rxnfc->flow_type];
 325
 326        return 0;
 327}
 328
 329/* current HW spec does byte reversal on everything including MAC addresses */
 330static void ether_addr_copy_swap(u8 *dst, const u8 *src)
 331{
 332        int i;
 333
 334        for (i = 0; i < ETH_ALEN; i++)
 335                dst[i] = src[ETH_ALEN - i - 1];
 336}
 337
 338static int enetc_set_cls_entry(struct enetc_si *si,
 339                               struct ethtool_rx_flow_spec *fs, bool en)
 340{
 341        struct ethtool_tcpip4_spec *l4ip4_h, *l4ip4_m;
 342        struct ethtool_usrip4_spec *l3ip4_h, *l3ip4_m;
 343        struct ethhdr *eth_h, *eth_m;
 344        struct enetc_cmd_rfse rfse = { {0} };
 345
 346        if (!en)
 347                goto done;
 348
 349        switch (fs->flow_type & 0xff) {
 350        case TCP_V4_FLOW:
 351                l4ip4_h = &fs->h_u.tcp_ip4_spec;
 352                l4ip4_m = &fs->m_u.tcp_ip4_spec;
 353                goto l4ip4;
 354        case UDP_V4_FLOW:
 355                l4ip4_h = &fs->h_u.udp_ip4_spec;
 356                l4ip4_m = &fs->m_u.udp_ip4_spec;
 357                goto l4ip4;
 358        case SCTP_V4_FLOW:
 359                l4ip4_h = &fs->h_u.sctp_ip4_spec;
 360                l4ip4_m = &fs->m_u.sctp_ip4_spec;
 361l4ip4:
 362                rfse.sip_h[0] = l4ip4_h->ip4src;
 363                rfse.sip_m[0] = l4ip4_m->ip4src;
 364                rfse.dip_h[0] = l4ip4_h->ip4dst;
 365                rfse.dip_m[0] = l4ip4_m->ip4dst;
 366                rfse.sport_h = ntohs(l4ip4_h->psrc);
 367                rfse.sport_m = ntohs(l4ip4_m->psrc);
 368                rfse.dport_h = ntohs(l4ip4_h->pdst);
 369                rfse.dport_m = ntohs(l4ip4_m->pdst);
 370                if (l4ip4_m->tos)
 371                        netdev_warn(si->ndev, "ToS field is not supported and was ignored\n");
 372                rfse.ethtype_h = ETH_P_IP; /* IPv4 */
 373                rfse.ethtype_m = 0xffff;
 374                break;
 375        case IP_USER_FLOW:
 376                l3ip4_h = &fs->h_u.usr_ip4_spec;
 377                l3ip4_m = &fs->m_u.usr_ip4_spec;
 378
 379                rfse.sip_h[0] = l3ip4_h->ip4src;
 380                rfse.sip_m[0] = l3ip4_m->ip4src;
 381                rfse.dip_h[0] = l3ip4_h->ip4dst;
 382                rfse.dip_m[0] = l3ip4_m->ip4dst;
 383                if (l3ip4_m->tos)
 384                        netdev_warn(si->ndev, "ToS field is not supported and was ignored\n");
 385                rfse.ethtype_h = ETH_P_IP; /* IPv4 */
 386                rfse.ethtype_m = 0xffff;
 387                break;
 388        case ETHER_FLOW:
 389                eth_h = &fs->h_u.ether_spec;
 390                eth_m = &fs->m_u.ether_spec;
 391
 392                ether_addr_copy_swap(rfse.smac_h, eth_h->h_source);
 393                ether_addr_copy_swap(rfse.smac_m, eth_m->h_source);
 394                ether_addr_copy_swap(rfse.dmac_h, eth_h->h_dest);
 395                ether_addr_copy_swap(rfse.dmac_m, eth_m->h_dest);
 396                rfse.ethtype_h = ntohs(eth_h->h_proto);
 397                rfse.ethtype_m = ntohs(eth_m->h_proto);
 398                break;
 399        default:
 400                return -EOPNOTSUPP;
 401        }
 402
 403        rfse.mode |= ENETC_RFSE_EN;
 404        if (fs->ring_cookie != RX_CLS_FLOW_DISC) {
 405                rfse.mode |= ENETC_RFSE_MODE_BD;
 406                rfse.result = fs->ring_cookie;
 407        }
 408done:
 409        return enetc_set_fs_entry(si, &rfse, fs->location);
 410}
 411
 412static int enetc_get_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc,
 413                           u32 *rule_locs)
 414{
 415        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 416        int i, j;
 417
 418        switch (rxnfc->cmd) {
 419        case ETHTOOL_GRXRINGS:
 420                rxnfc->data = priv->num_rx_rings;
 421                break;
 422        case ETHTOOL_GRXFH:
 423                /* get RSS hash config */
 424                return enetc_get_rsshash(rxnfc);
 425        case ETHTOOL_GRXCLSRLCNT:
 426                /* total number of entries */
 427                rxnfc->data = priv->si->num_fs_entries;
 428                /* number of entries in use */
 429                rxnfc->rule_cnt = 0;
 430                for (i = 0; i < priv->si->num_fs_entries; i++)
 431                        if (priv->cls_rules[i].used)
 432                                rxnfc->rule_cnt++;
 433                break;
 434        case ETHTOOL_GRXCLSRULE:
 435                if (rxnfc->fs.location >= priv->si->num_fs_entries)
 436                        return -EINVAL;
 437
 438                /* get entry x */
 439                rxnfc->fs = priv->cls_rules[rxnfc->fs.location].fs;
 440                break;
 441        case ETHTOOL_GRXCLSRLALL:
 442                /* total number of entries */
 443                rxnfc->data = priv->si->num_fs_entries;
 444                /* array of indexes of used entries */
 445                j = 0;
 446                for (i = 0; i < priv->si->num_fs_entries; i++) {
 447                        if (!priv->cls_rules[i].used)
 448                                continue;
 449                        if (j == rxnfc->rule_cnt)
 450                                return -EMSGSIZE;
 451                        rule_locs[j++] = i;
 452                }
 453                /* number of entries in use */
 454                rxnfc->rule_cnt = j;
 455                break;
 456        default:
 457                return -EOPNOTSUPP;
 458        }
 459
 460        return 0;
 461}
 462
 463static int enetc_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc)
 464{
 465        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 466        int err;
 467
 468        switch (rxnfc->cmd) {
 469        case ETHTOOL_SRXCLSRLINS:
 470                if (rxnfc->fs.location >= priv->si->num_fs_entries)
 471                        return -EINVAL;
 472
 473                if (rxnfc->fs.ring_cookie >= priv->num_rx_rings &&
 474                    rxnfc->fs.ring_cookie != RX_CLS_FLOW_DISC)
 475                        return -EINVAL;
 476
 477                err = enetc_set_cls_entry(priv->si, &rxnfc->fs, true);
 478                if (err)
 479                        return err;
 480                priv->cls_rules[rxnfc->fs.location].fs = rxnfc->fs;
 481                priv->cls_rules[rxnfc->fs.location].used = 1;
 482                break;
 483        case ETHTOOL_SRXCLSRLDEL:
 484                if (rxnfc->fs.location >= priv->si->num_fs_entries)
 485                        return -EINVAL;
 486
 487                err = enetc_set_cls_entry(priv->si, &rxnfc->fs, false);
 488                if (err)
 489                        return err;
 490                priv->cls_rules[rxnfc->fs.location].used = 0;
 491                break;
 492        default:
 493                return -EOPNOTSUPP;
 494        }
 495
 496        return 0;
 497}
 498
 499static u32 enetc_get_rxfh_key_size(struct net_device *ndev)
 500{
 501        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 502
 503        /* return the size of the RX flow hash key.  PF only */
 504        return (priv->si->hw.port) ? ENETC_RSSHASH_KEY_SIZE : 0;
 505}
 506
 507static u32 enetc_get_rxfh_indir_size(struct net_device *ndev)
 508{
 509        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 510
 511        /* return the size of the RX flow hash indirection table */
 512        return priv->si->num_rss;
 513}
 514
 515static int enetc_get_rxfh(struct net_device *ndev, u32 *indir, u8 *key,
 516                          u8 *hfunc)
 517{
 518        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 519        struct enetc_hw *hw = &priv->si->hw;
 520        int err = 0, i;
 521
 522        /* return hash function */
 523        if (hfunc)
 524                *hfunc = ETH_RSS_HASH_TOP;
 525
 526        /* return hash key */
 527        if (key && hw->port)
 528                for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
 529                        ((u32 *)key)[i] = enetc_port_rd(hw, ENETC_PRSSK(i));
 530
 531        /* return RSS table */
 532        if (indir)
 533                err = enetc_get_rss_table(priv->si, indir, priv->si->num_rss);
 534
 535        return err;
 536}
 537
 538void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes)
 539{
 540        int i;
 541
 542        for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
 543                enetc_port_wr(hw, ENETC_PRSSK(i), ((u32 *)bytes)[i]);
 544}
 545
 546static int enetc_set_rxfh(struct net_device *ndev, const u32 *indir,
 547                          const u8 *key, const u8 hfunc)
 548{
 549        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 550        struct enetc_hw *hw = &priv->si->hw;
 551        int err = 0;
 552
 553        /* set hash key, if PF */
 554        if (key && hw->port)
 555                enetc_set_rss_key(hw, key);
 556
 557        /* set RSS table */
 558        if (indir)
 559                err = enetc_set_rss_table(priv->si, indir, priv->si->num_rss);
 560
 561        return err;
 562}
 563
 564static void enetc_get_ringparam(struct net_device *ndev,
 565                                struct ethtool_ringparam *ring)
 566{
 567        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 568
 569        ring->rx_pending = priv->rx_bd_count;
 570        ring->tx_pending = priv->tx_bd_count;
 571
 572        /* do some h/w sanity checks for BDR length */
 573        if (netif_running(ndev)) {
 574                struct enetc_hw *hw = &priv->si->hw;
 575                u32 val = enetc_rxbdr_rd(hw, 0, ENETC_RBLENR);
 576
 577                if (val != priv->rx_bd_count)
 578                        netif_err(priv, hw, ndev, "RxBDR[RBLENR] = %d!\n", val);
 579
 580                val = enetc_txbdr_rd(hw, 0, ENETC_TBLENR);
 581
 582                if (val != priv->tx_bd_count)
 583                        netif_err(priv, hw, ndev, "TxBDR[TBLENR] = %d!\n", val);
 584        }
 585}
 586
 587static int enetc_get_coalesce(struct net_device *ndev,
 588                              struct ethtool_coalesce *ic,
 589                              struct kernel_ethtool_coalesce *kernel_coal,
 590                              struct netlink_ext_ack *extack)
 591{
 592        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 593        struct enetc_int_vector *v = priv->int_vector[0];
 594
 595        ic->tx_coalesce_usecs = enetc_cycles_to_usecs(priv->tx_ictt);
 596        ic->rx_coalesce_usecs = enetc_cycles_to_usecs(v->rx_ictt);
 597
 598        ic->tx_max_coalesced_frames = ENETC_TXIC_PKTTHR;
 599        ic->rx_max_coalesced_frames = ENETC_RXIC_PKTTHR;
 600
 601        ic->use_adaptive_rx_coalesce = priv->ic_mode & ENETC_IC_RX_ADAPTIVE;
 602
 603        return 0;
 604}
 605
 606static int enetc_set_coalesce(struct net_device *ndev,
 607                              struct ethtool_coalesce *ic,
 608                              struct kernel_ethtool_coalesce *kernel_coal,
 609                              struct netlink_ext_ack *extack)
 610{
 611        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 612        u32 rx_ictt, tx_ictt;
 613        int i, ic_mode;
 614        bool changed;
 615
 616        tx_ictt = enetc_usecs_to_cycles(ic->tx_coalesce_usecs);
 617        rx_ictt = enetc_usecs_to_cycles(ic->rx_coalesce_usecs);
 618
 619        if (ic->rx_max_coalesced_frames != ENETC_RXIC_PKTTHR)
 620                return -EOPNOTSUPP;
 621
 622        if (ic->tx_max_coalesced_frames != ENETC_TXIC_PKTTHR)
 623                return -EOPNOTSUPP;
 624
 625        ic_mode = ENETC_IC_NONE;
 626        if (ic->use_adaptive_rx_coalesce) {
 627                ic_mode |= ENETC_IC_RX_ADAPTIVE;
 628                rx_ictt = 0x1;
 629        } else {
 630                ic_mode |= rx_ictt ? ENETC_IC_RX_MANUAL : 0;
 631        }
 632
 633        ic_mode |= tx_ictt ? ENETC_IC_TX_MANUAL : 0;
 634
 635        /* commit the settings */
 636        changed = (ic_mode != priv->ic_mode) || (priv->tx_ictt != tx_ictt);
 637
 638        priv->ic_mode = ic_mode;
 639        priv->tx_ictt = tx_ictt;
 640
 641        for (i = 0; i < priv->bdr_int_num; i++) {
 642                struct enetc_int_vector *v = priv->int_vector[i];
 643
 644                v->rx_ictt = rx_ictt;
 645                v->rx_dim_en = !!(ic_mode & ENETC_IC_RX_ADAPTIVE);
 646        }
 647
 648        if (netif_running(ndev) && changed) {
 649                /* reconfigure the operation mode of h/w interrupts,
 650                 * traffic needs to be paused in the process
 651                 */
 652                enetc_stop(ndev);
 653                enetc_start(ndev);
 654        }
 655
 656        return 0;
 657}
 658
 659static int enetc_get_ts_info(struct net_device *ndev,
 660                             struct ethtool_ts_info *info)
 661{
 662        int *phc_idx;
 663
 664        phc_idx = symbol_get(enetc_phc_index);
 665        if (phc_idx) {
 666                info->phc_index = *phc_idx;
 667                symbol_put(enetc_phc_index);
 668        } else {
 669                info->phc_index = -1;
 670        }
 671
 672#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
 673        info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
 674                                SOF_TIMESTAMPING_RX_HARDWARE |
 675                                SOF_TIMESTAMPING_RAW_HARDWARE;
 676
 677        info->tx_types = (1 << HWTSTAMP_TX_OFF) |
 678                         (1 << HWTSTAMP_TX_ON) |
 679                         (1 << HWTSTAMP_TX_ONESTEP_SYNC);
 680        info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
 681                           (1 << HWTSTAMP_FILTER_ALL);
 682#else
 683        info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
 684                                SOF_TIMESTAMPING_TX_SOFTWARE |
 685                                SOF_TIMESTAMPING_SOFTWARE;
 686#endif
 687        return 0;
 688}
 689
 690static void enetc_get_wol(struct net_device *dev,
 691                          struct ethtool_wolinfo *wol)
 692{
 693        wol->supported = 0;
 694        wol->wolopts = 0;
 695
 696        if (dev->phydev)
 697                phy_ethtool_get_wol(dev->phydev, wol);
 698}
 699
 700static int enetc_set_wol(struct net_device *dev,
 701                         struct ethtool_wolinfo *wol)
 702{
 703        int ret;
 704
 705        if (!dev->phydev)
 706                return -EOPNOTSUPP;
 707
 708        ret = phy_ethtool_set_wol(dev->phydev, wol);
 709        if (!ret)
 710                device_set_wakeup_enable(&dev->dev, wol->wolopts);
 711
 712        return ret;
 713}
 714
 715static void enetc_get_pauseparam(struct net_device *dev,
 716                                 struct ethtool_pauseparam *pause)
 717{
 718        struct enetc_ndev_priv *priv = netdev_priv(dev);
 719
 720        phylink_ethtool_get_pauseparam(priv->phylink, pause);
 721}
 722
 723static int enetc_set_pauseparam(struct net_device *dev,
 724                                struct ethtool_pauseparam *pause)
 725{
 726        struct enetc_ndev_priv *priv = netdev_priv(dev);
 727
 728        return phylink_ethtool_set_pauseparam(priv->phylink, pause);
 729}
 730
 731static int enetc_get_link_ksettings(struct net_device *dev,
 732                                    struct ethtool_link_ksettings *cmd)
 733{
 734        struct enetc_ndev_priv *priv = netdev_priv(dev);
 735
 736        if (!priv->phylink)
 737                return -EOPNOTSUPP;
 738
 739        return phylink_ethtool_ksettings_get(priv->phylink, cmd);
 740}
 741
 742static int enetc_set_link_ksettings(struct net_device *dev,
 743                                    const struct ethtool_link_ksettings *cmd)
 744{
 745        struct enetc_ndev_priv *priv = netdev_priv(dev);
 746
 747        if (!priv->phylink)
 748                return -EOPNOTSUPP;
 749
 750        return phylink_ethtool_ksettings_set(priv->phylink, cmd);
 751}
 752
 753static const struct ethtool_ops enetc_pf_ethtool_ops = {
 754        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 755                                     ETHTOOL_COALESCE_MAX_FRAMES |
 756                                     ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
 757        .get_regs_len = enetc_get_reglen,
 758        .get_regs = enetc_get_regs,
 759        .get_sset_count = enetc_get_sset_count,
 760        .get_strings = enetc_get_strings,
 761        .get_ethtool_stats = enetc_get_ethtool_stats,
 762        .get_rxnfc = enetc_get_rxnfc,
 763        .set_rxnfc = enetc_set_rxnfc,
 764        .get_rxfh_key_size = enetc_get_rxfh_key_size,
 765        .get_rxfh_indir_size = enetc_get_rxfh_indir_size,
 766        .get_rxfh = enetc_get_rxfh,
 767        .set_rxfh = enetc_set_rxfh,
 768        .get_ringparam = enetc_get_ringparam,
 769        .get_coalesce = enetc_get_coalesce,
 770        .set_coalesce = enetc_set_coalesce,
 771        .get_link_ksettings = enetc_get_link_ksettings,
 772        .set_link_ksettings = enetc_set_link_ksettings,
 773        .get_link = ethtool_op_get_link,
 774        .get_ts_info = enetc_get_ts_info,
 775        .get_wol = enetc_get_wol,
 776        .set_wol = enetc_set_wol,
 777        .get_pauseparam = enetc_get_pauseparam,
 778        .set_pauseparam = enetc_set_pauseparam,
 779};
 780
 781static const struct ethtool_ops enetc_vf_ethtool_ops = {
 782        .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
 783                                     ETHTOOL_COALESCE_MAX_FRAMES |
 784                                     ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
 785        .get_regs_len = enetc_get_reglen,
 786        .get_regs = enetc_get_regs,
 787        .get_sset_count = enetc_get_sset_count,
 788        .get_strings = enetc_get_strings,
 789        .get_ethtool_stats = enetc_get_ethtool_stats,
 790        .get_rxnfc = enetc_get_rxnfc,
 791        .set_rxnfc = enetc_set_rxnfc,
 792        .get_rxfh_indir_size = enetc_get_rxfh_indir_size,
 793        .get_rxfh = enetc_get_rxfh,
 794        .set_rxfh = enetc_set_rxfh,
 795        .get_ringparam = enetc_get_ringparam,
 796        .get_coalesce = enetc_get_coalesce,
 797        .set_coalesce = enetc_set_coalesce,
 798        .get_link = ethtool_op_get_link,
 799        .get_ts_info = enetc_get_ts_info,
 800};
 801
 802void enetc_set_ethtool_ops(struct net_device *ndev)
 803{
 804        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 805
 806        if (enetc_si_is_pf(priv->si))
 807                ndev->ethtool_ops = &enetc_pf_ethtool_ops;
 808        else
 809                ndev->ethtool_ops = &enetc_vf_ethtool_ops;
 810}
 811