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
  18};
  19
  20static const u32 enetc_rxbdr_regs[] = {
  21        ENETC_RBMR, ENETC_RBSR, ENETC_RBBSR, ENETC_RBCIR, ENETC_RBBAR0,
  22        ENETC_RBBAR1, ENETC_RBPIR, ENETC_RBLENR, ENETC_RBICIR0, ENETC_RBIER
  23};
  24
  25static const u32 enetc_port_regs[] = {
  26        ENETC_PMR, ENETC_PSR, ENETC_PSIPMR, ENETC_PSIPMAR0(0),
  27        ENETC_PSIPMAR1(0), ENETC_PTXMBAR, ENETC_PCAPR0, ENETC_PCAPR1,
  28        ENETC_PSICFGR0(0), ENETC_PRFSCAPR, ENETC_PTCMSDUR(0),
  29        ENETC_PM0_CMD_CFG, ENETC_PM0_MAXFRM, ENETC_PM0_IF_MODE
  30};
  31
  32static int enetc_get_reglen(struct net_device *ndev)
  33{
  34        struct enetc_ndev_priv *priv = netdev_priv(ndev);
  35        struct enetc_hw *hw = &priv->si->hw;
  36        int len;
  37
  38        len = ARRAY_SIZE(enetc_si_regs);
  39        len += ARRAY_SIZE(enetc_txbdr_regs) * priv->num_tx_rings;
  40        len += ARRAY_SIZE(enetc_rxbdr_regs) * priv->num_rx_rings;
  41
  42        if (hw->port)
  43                len += ARRAY_SIZE(enetc_port_regs);
  44
  45        len *= sizeof(u32) * 2; /* store 2 entries per reg: addr and value */
  46
  47        return len;
  48}
  49
  50static void enetc_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
  51                           void *regbuf)
  52{
  53        struct enetc_ndev_priv *priv = netdev_priv(ndev);
  54        struct enetc_hw *hw = &priv->si->hw;
  55        u32 *buf = (u32 *)regbuf;
  56        int i, j;
  57        u32 addr;
  58
  59        for (i = 0; i < ARRAY_SIZE(enetc_si_regs); i++) {
  60                *buf++ = enetc_si_regs[i];
  61                *buf++ = enetc_rd(hw, enetc_si_regs[i]);
  62        }
  63
  64        for (i = 0; i < priv->num_tx_rings; i++) {
  65                for (j = 0; j < ARRAY_SIZE(enetc_txbdr_regs); j++) {
  66                        addr = ENETC_BDR(TX, i, enetc_txbdr_regs[j]);
  67
  68                        *buf++ = addr;
  69                        *buf++ = enetc_rd(hw, addr);
  70                }
  71        }
  72
  73        for (i = 0; i < priv->num_rx_rings; i++) {
  74                for (j = 0; j < ARRAY_SIZE(enetc_rxbdr_regs); j++) {
  75                        addr = ENETC_BDR(RX, i, enetc_rxbdr_regs[j]);
  76
  77                        *buf++ = addr;
  78                        *buf++ = enetc_rd(hw, addr);
  79                }
  80        }
  81
  82        if (!hw->port)
  83                return;
  84
  85        for (i = 0; i < ARRAY_SIZE(enetc_port_regs); i++) {
  86                addr = ENETC_PORT_BASE + enetc_port_regs[i];
  87                *buf++ = addr;
  88                *buf++ = enetc_rd(hw, addr);
  89        }
  90}
  91
  92static const struct {
  93        int reg;
  94        char name[ETH_GSTRING_LEN];
  95} enetc_si_counters[] =  {
  96        { ENETC_SIROCT, "SI rx octets" },
  97        { ENETC_SIRFRM, "SI rx frames" },
  98        { ENETC_SIRUCA, "SI rx u-cast frames" },
  99        { ENETC_SIRMCA, "SI rx m-cast frames" },
 100        { ENETC_SITOCT, "SI tx octets" },
 101        { ENETC_SITFRM, "SI tx frames" },
 102        { ENETC_SITUCA, "SI tx u-cast frames" },
 103        { ENETC_SITMCA, "SI tx m-cast frames" },
 104        { ENETC_RBDCR(0), "Rx ring  0 discarded frames" },
 105        { ENETC_RBDCR(1), "Rx ring  1 discarded frames" },
 106        { ENETC_RBDCR(2), "Rx ring  2 discarded frames" },
 107        { ENETC_RBDCR(3), "Rx ring  3 discarded frames" },
 108        { ENETC_RBDCR(4), "Rx ring  4 discarded frames" },
 109        { ENETC_RBDCR(5), "Rx ring  5 discarded frames" },
 110        { ENETC_RBDCR(6), "Rx ring  6 discarded frames" },
 111        { ENETC_RBDCR(7), "Rx ring  7 discarded frames" },
 112        { ENETC_RBDCR(8), "Rx ring  8 discarded frames" },
 113        { ENETC_RBDCR(9), "Rx ring  9 discarded frames" },
 114        { ENETC_RBDCR(10), "Rx ring 10 discarded frames" },
 115        { ENETC_RBDCR(11), "Rx ring 11 discarded frames" },
 116        { ENETC_RBDCR(12), "Rx ring 12 discarded frames" },
 117        { ENETC_RBDCR(13), "Rx ring 13 discarded frames" },
 118        { ENETC_RBDCR(14), "Rx ring 14 discarded frames" },
 119        { ENETC_RBDCR(15), "Rx ring 15 discarded frames" },
 120};
 121
 122static const struct {
 123        int reg;
 124        char name[ETH_GSTRING_LEN];
 125} enetc_port_counters[] = {
 126        { ENETC_PM0_REOCT,  "MAC rx ethernet octets" },
 127        { ENETC_PM0_RALN,   "MAC rx alignment errors" },
 128        { ENETC_PM0_RXPF,   "MAC rx valid pause frames" },
 129        { ENETC_PM0_RFRM,   "MAC rx valid frames" },
 130        { ENETC_PM0_RFCS,   "MAC rx fcs errors" },
 131        { ENETC_PM0_RVLAN,  "MAC rx VLAN frames" },
 132        { ENETC_PM0_RERR,   "MAC rx frame errors" },
 133        { ENETC_PM0_RUCA,   "MAC rx unicast frames" },
 134        { ENETC_PM0_RMCA,   "MAC rx multicast frames" },
 135        { ENETC_PM0_RBCA,   "MAC rx broadcast frames" },
 136        { ENETC_PM0_RDRP,   "MAC rx dropped packets" },
 137        { ENETC_PM0_RPKT,   "MAC rx packets" },
 138        { ENETC_PM0_RUND,   "MAC rx undersized packets" },
 139        { ENETC_PM0_R64,    "MAC rx 64 byte packets" },
 140        { ENETC_PM0_R127,   "MAC rx 65-127 byte packets" },
 141        { ENETC_PM0_R255,   "MAC rx 128-255 byte packets" },
 142        { ENETC_PM0_R511,   "MAC rx 256-511 byte packets" },
 143        { ENETC_PM0_R1023,  "MAC rx 512-1023 byte packets" },
 144        { ENETC_PM0_R1518,  "MAC rx 1024-1518 byte packets" },
 145        { ENETC_PM0_R1519X, "MAC rx 1519 to max-octet packets" },
 146        { ENETC_PM0_ROVR,   "MAC rx oversized packets" },
 147        { ENETC_PM0_RJBR,   "MAC rx jabber packets" },
 148        { ENETC_PM0_RFRG,   "MAC rx fragment packets" },
 149        { ENETC_PM0_RCNP,   "MAC rx control packets" },
 150        { ENETC_PM0_RDRNTP, "MAC rx fifo drop" },
 151        { ENETC_PM0_TEOCT,  "MAC tx ethernet octets" },
 152        { ENETC_PM0_TOCT,   "MAC tx octets" },
 153        { ENETC_PM0_TCRSE,  "MAC tx carrier sense errors" },
 154        { ENETC_PM0_TXPF,   "MAC tx valid pause frames" },
 155        { ENETC_PM0_TFRM,   "MAC tx frames" },
 156        { ENETC_PM0_TFCS,   "MAC tx fcs errors" },
 157        { ENETC_PM0_TVLAN,  "MAC tx VLAN frames" },
 158        { ENETC_PM0_TERR,   "MAC tx frames" },
 159        { ENETC_PM0_TUCA,   "MAC tx unicast frames" },
 160        { ENETC_PM0_TMCA,   "MAC tx multicast frames" },
 161        { ENETC_PM0_TBCA,   "MAC tx broadcast frames" },
 162        { ENETC_PM0_TPKT,   "MAC tx packets" },
 163        { ENETC_PM0_TUND,   "MAC tx undersized packets" },
 164        { ENETC_PM0_T127,   "MAC tx 65-127 byte packets" },
 165        { ENETC_PM0_T1023,  "MAC tx 512-1023 byte packets" },
 166        { ENETC_PM0_T1518,  "MAC tx 1024-1518 byte packets" },
 167        { ENETC_PM0_TCNP,   "MAC tx control packets" },
 168        { ENETC_PM0_TDFR,   "MAC tx deferred packets" },
 169        { ENETC_PM0_TMCOL,  "MAC tx multiple collisions" },
 170        { ENETC_PM0_TSCOL,  "MAC tx single collisions" },
 171        { ENETC_PM0_TLCOL,  "MAC tx late collisions" },
 172        { ENETC_PM0_TECOL,  "MAC tx excessive collisions" },
 173        { ENETC_UFDMF,      "SI MAC nomatch u-cast discards" },
 174        { ENETC_MFDMF,      "SI MAC nomatch m-cast discards" },
 175        { ENETC_PBFDSIR,    "SI MAC nomatch b-cast discards" },
 176        { ENETC_PUFDVFR,    "SI VLAN nomatch u-cast discards" },
 177        { ENETC_PMFDVFR,    "SI VLAN nomatch m-cast discards" },
 178        { ENETC_PBFDVFR,    "SI VLAN nomatch b-cast discards" },
 179        { ENETC_PFDMSAPR,   "SI pruning discarded frames" },
 180        { ENETC_PICDR(0),   "ICM DR0 discarded frames" },
 181        { ENETC_PICDR(1),   "ICM DR1 discarded frames" },
 182        { ENETC_PICDR(2),   "ICM DR2 discarded frames" },
 183        { ENETC_PICDR(3),   "ICM DR3 discarded frames" },
 184};
 185
 186static const char rx_ring_stats[][ETH_GSTRING_LEN] = {
 187        "Rx ring %2d frames",
 188        "Rx ring %2d alloc errors",
 189};
 190
 191static const char tx_ring_stats[][ETH_GSTRING_LEN] = {
 192        "Tx ring %2d frames",
 193};
 194
 195static int enetc_get_sset_count(struct net_device *ndev, int sset)
 196{
 197        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 198
 199        if (sset == ETH_SS_STATS)
 200                return ARRAY_SIZE(enetc_si_counters) +
 201                        ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings +
 202                        ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings +
 203                        (enetc_si_is_pf(priv->si) ?
 204                        ARRAY_SIZE(enetc_port_counters) : 0);
 205
 206        return -EOPNOTSUPP;
 207}
 208
 209static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
 210{
 211        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 212        u8 *p = data;
 213        int i, j;
 214
 215        switch (stringset) {
 216        case ETH_SS_STATS:
 217                for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++) {
 218                        strlcpy(p, enetc_si_counters[i].name, ETH_GSTRING_LEN);
 219                        p += ETH_GSTRING_LEN;
 220                }
 221                for (i = 0; i < priv->num_tx_rings; i++) {
 222                        for (j = 0; j < ARRAY_SIZE(tx_ring_stats); j++) {
 223                                snprintf(p, ETH_GSTRING_LEN, tx_ring_stats[j],
 224                                         i);
 225                                p += ETH_GSTRING_LEN;
 226                        }
 227                }
 228                for (i = 0; i < priv->num_rx_rings; i++) {
 229                        for (j = 0; j < ARRAY_SIZE(rx_ring_stats); j++) {
 230                                snprintf(p, ETH_GSTRING_LEN, rx_ring_stats[j],
 231                                         i);
 232                                p += ETH_GSTRING_LEN;
 233                        }
 234                }
 235
 236                if (!enetc_si_is_pf(priv->si))
 237                        break;
 238
 239                for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++) {
 240                        strlcpy(p, enetc_port_counters[i].name,
 241                                ETH_GSTRING_LEN);
 242                        p += ETH_GSTRING_LEN;
 243                }
 244                break;
 245        }
 246}
 247
 248static void enetc_get_ethtool_stats(struct net_device *ndev,
 249                                    struct ethtool_stats *stats, u64 *data)
 250{
 251        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 252        struct enetc_hw *hw = &priv->si->hw;
 253        int i, o = 0;
 254
 255        for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++)
 256                data[o++] = enetc_rd64(hw, enetc_si_counters[i].reg);
 257
 258        for (i = 0; i < priv->num_tx_rings; i++)
 259                data[o++] = priv->tx_ring[i]->stats.packets;
 260
 261        for (i = 0; i < priv->num_rx_rings; i++) {
 262                data[o++] = priv->rx_ring[i]->stats.packets;
 263                data[o++] = priv->rx_ring[i]->stats.rx_alloc_errs;
 264        }
 265
 266        if (!enetc_si_is_pf(priv->si))
 267                return;
 268
 269        for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
 270                data[o++] = enetc_port_rd(hw, enetc_port_counters[i].reg);
 271}
 272
 273#define ENETC_RSSHASH_L3 (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO | RXH_IP_SRC | \
 274                          RXH_IP_DST)
 275#define ENETC_RSSHASH_L4 (ENETC_RSSHASH_L3 | RXH_L4_B_0_1 | RXH_L4_B_2_3)
 276static int enetc_get_rsshash(struct ethtool_rxnfc *rxnfc)
 277{
 278        static const u32 rsshash[] = {
 279                        [TCP_V4_FLOW]    = ENETC_RSSHASH_L4,
 280                        [UDP_V4_FLOW]    = ENETC_RSSHASH_L4,
 281                        [SCTP_V4_FLOW]   = ENETC_RSSHASH_L4,
 282                        [AH_ESP_V4_FLOW] = ENETC_RSSHASH_L3,
 283                        [IPV4_FLOW]      = ENETC_RSSHASH_L3,
 284                        [TCP_V6_FLOW]    = ENETC_RSSHASH_L4,
 285                        [UDP_V6_FLOW]    = ENETC_RSSHASH_L4,
 286                        [SCTP_V6_FLOW]   = ENETC_RSSHASH_L4,
 287                        [AH_ESP_V6_FLOW] = ENETC_RSSHASH_L3,
 288                        [IPV6_FLOW]      = ENETC_RSSHASH_L3,
 289                        [ETHER_FLOW]     = 0,
 290        };
 291
 292        if (rxnfc->flow_type >= ARRAY_SIZE(rsshash))
 293                return -EINVAL;
 294
 295        rxnfc->data = rsshash[rxnfc->flow_type];
 296
 297        return 0;
 298}
 299
 300/* current HW spec does byte reversal on everything including MAC addresses */
 301static void ether_addr_copy_swap(u8 *dst, const u8 *src)
 302{
 303        int i;
 304
 305        for (i = 0; i < ETH_ALEN; i++)
 306                dst[i] = src[ETH_ALEN - i - 1];
 307}
 308
 309static int enetc_set_cls_entry(struct enetc_si *si,
 310                               struct ethtool_rx_flow_spec *fs, bool en)
 311{
 312        struct ethtool_tcpip4_spec *l4ip4_h, *l4ip4_m;
 313        struct ethtool_usrip4_spec *l3ip4_h, *l3ip4_m;
 314        struct ethhdr *eth_h, *eth_m;
 315        struct enetc_cmd_rfse rfse = { {0} };
 316
 317        if (!en)
 318                goto done;
 319
 320        switch (fs->flow_type & 0xff) {
 321        case TCP_V4_FLOW:
 322                l4ip4_h = &fs->h_u.tcp_ip4_spec;
 323                l4ip4_m = &fs->m_u.tcp_ip4_spec;
 324                goto l4ip4;
 325        case UDP_V4_FLOW:
 326                l4ip4_h = &fs->h_u.udp_ip4_spec;
 327                l4ip4_m = &fs->m_u.udp_ip4_spec;
 328                goto l4ip4;
 329        case SCTP_V4_FLOW:
 330                l4ip4_h = &fs->h_u.sctp_ip4_spec;
 331                l4ip4_m = &fs->m_u.sctp_ip4_spec;
 332l4ip4:
 333                rfse.sip_h[0] = l4ip4_h->ip4src;
 334                rfse.sip_m[0] = l4ip4_m->ip4src;
 335                rfse.dip_h[0] = l4ip4_h->ip4dst;
 336                rfse.dip_m[0] = l4ip4_m->ip4dst;
 337                rfse.sport_h = ntohs(l4ip4_h->psrc);
 338                rfse.sport_m = ntohs(l4ip4_m->psrc);
 339                rfse.dport_h = ntohs(l4ip4_h->pdst);
 340                rfse.dport_m = ntohs(l4ip4_m->pdst);
 341                if (l4ip4_m->tos)
 342                        netdev_warn(si->ndev, "ToS field is not supported and was ignored\n");
 343                rfse.ethtype_h = ETH_P_IP; /* IPv4 */
 344                rfse.ethtype_m = 0xffff;
 345                break;
 346        case IP_USER_FLOW:
 347                l3ip4_h = &fs->h_u.usr_ip4_spec;
 348                l3ip4_m = &fs->m_u.usr_ip4_spec;
 349
 350                rfse.sip_h[0] = l3ip4_h->ip4src;
 351                rfse.sip_m[0] = l3ip4_m->ip4src;
 352                rfse.dip_h[0] = l3ip4_h->ip4dst;
 353                rfse.dip_m[0] = l3ip4_m->ip4dst;
 354                if (l3ip4_m->tos)
 355                        netdev_warn(si->ndev, "ToS field is not supported and was ignored\n");
 356                rfse.ethtype_h = ETH_P_IP; /* IPv4 */
 357                rfse.ethtype_m = 0xffff;
 358                break;
 359        case ETHER_FLOW:
 360                eth_h = &fs->h_u.ether_spec;
 361                eth_m = &fs->m_u.ether_spec;
 362
 363                ether_addr_copy_swap(rfse.smac_h, eth_h->h_source);
 364                ether_addr_copy_swap(rfse.smac_m, eth_m->h_source);
 365                ether_addr_copy_swap(rfse.dmac_h, eth_h->h_dest);
 366                ether_addr_copy_swap(rfse.dmac_m, eth_m->h_dest);
 367                rfse.ethtype_h = ntohs(eth_h->h_proto);
 368                rfse.ethtype_m = ntohs(eth_m->h_proto);
 369                break;
 370        default:
 371                return -EOPNOTSUPP;
 372        }
 373
 374        rfse.mode |= ENETC_RFSE_EN;
 375        if (fs->ring_cookie != RX_CLS_FLOW_DISC) {
 376                rfse.mode |= ENETC_RFSE_MODE_BD;
 377                rfse.result = fs->ring_cookie;
 378        }
 379done:
 380        return enetc_set_fs_entry(si, &rfse, fs->location);
 381}
 382
 383static int enetc_get_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc,
 384                           u32 *rule_locs)
 385{
 386        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 387        int i, j;
 388
 389        switch (rxnfc->cmd) {
 390        case ETHTOOL_GRXRINGS:
 391                rxnfc->data = priv->num_rx_rings;
 392                break;
 393        case ETHTOOL_GRXFH:
 394                /* get RSS hash config */
 395                return enetc_get_rsshash(rxnfc);
 396        case ETHTOOL_GRXCLSRLCNT:
 397                /* total number of entries */
 398                rxnfc->data = priv->si->num_fs_entries;
 399                /* number of entries in use */
 400                rxnfc->rule_cnt = 0;
 401                for (i = 0; i < priv->si->num_fs_entries; i++)
 402                        if (priv->cls_rules[i].used)
 403                                rxnfc->rule_cnt++;
 404                break;
 405        case ETHTOOL_GRXCLSRULE:
 406                if (rxnfc->fs.location >= priv->si->num_fs_entries)
 407                        return -EINVAL;
 408
 409                /* get entry x */
 410                rxnfc->fs = priv->cls_rules[rxnfc->fs.location].fs;
 411                break;
 412        case ETHTOOL_GRXCLSRLALL:
 413                /* total number of entries */
 414                rxnfc->data = priv->si->num_fs_entries;
 415                /* array of indexes of used entries */
 416                j = 0;
 417                for (i = 0; i < priv->si->num_fs_entries; i++) {
 418                        if (!priv->cls_rules[i].used)
 419                                continue;
 420                        if (j == rxnfc->rule_cnt)
 421                                return -EMSGSIZE;
 422                        rule_locs[j++] = i;
 423                }
 424                /* number of entries in use */
 425                rxnfc->rule_cnt = j;
 426                break;
 427        default:
 428                return -EOPNOTSUPP;
 429        }
 430
 431        return 0;
 432}
 433
 434static int enetc_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc)
 435{
 436        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 437        int err;
 438
 439        switch (rxnfc->cmd) {
 440        case ETHTOOL_SRXCLSRLINS:
 441                if (rxnfc->fs.location >= priv->si->num_fs_entries)
 442                        return -EINVAL;
 443
 444                if (rxnfc->fs.ring_cookie >= priv->num_rx_rings &&
 445                    rxnfc->fs.ring_cookie != RX_CLS_FLOW_DISC)
 446                        return -EINVAL;
 447
 448                err = enetc_set_cls_entry(priv->si, &rxnfc->fs, true);
 449                if (err)
 450                        return err;
 451                priv->cls_rules[rxnfc->fs.location].fs = rxnfc->fs;
 452                priv->cls_rules[rxnfc->fs.location].used = 1;
 453                break;
 454        case ETHTOOL_SRXCLSRLDEL:
 455                if (rxnfc->fs.location >= priv->si->num_fs_entries)
 456                        return -EINVAL;
 457
 458                err = enetc_set_cls_entry(priv->si, &rxnfc->fs, false);
 459                if (err)
 460                        return err;
 461                priv->cls_rules[rxnfc->fs.location].used = 0;
 462                break;
 463        default:
 464                return -EOPNOTSUPP;
 465        }
 466
 467        return 0;
 468}
 469
 470static u32 enetc_get_rxfh_key_size(struct net_device *ndev)
 471{
 472        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 473
 474        /* return the size of the RX flow hash key.  PF only */
 475        return (priv->si->hw.port) ? ENETC_RSSHASH_KEY_SIZE : 0;
 476}
 477
 478static u32 enetc_get_rxfh_indir_size(struct net_device *ndev)
 479{
 480        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 481
 482        /* return the size of the RX flow hash indirection table */
 483        return priv->si->num_rss;
 484}
 485
 486static int enetc_get_rxfh(struct net_device *ndev, u32 *indir, u8 *key,
 487                          u8 *hfunc)
 488{
 489        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 490        struct enetc_hw *hw = &priv->si->hw;
 491        int err = 0, i;
 492
 493        /* return hash function */
 494        if (hfunc)
 495                *hfunc = ETH_RSS_HASH_TOP;
 496
 497        /* return hash key */
 498        if (key && hw->port)
 499                for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
 500                        ((u32 *)key)[i] = enetc_port_rd(hw, ENETC_PRSSK(i));
 501
 502        /* return RSS table */
 503        if (indir)
 504                err = enetc_get_rss_table(priv->si, indir, priv->si->num_rss);
 505
 506        return err;
 507}
 508
 509void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes)
 510{
 511        int i;
 512
 513        for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
 514                enetc_port_wr(hw, ENETC_PRSSK(i), ((u32 *)bytes)[i]);
 515}
 516
 517static int enetc_set_rxfh(struct net_device *ndev, const u32 *indir,
 518                          const u8 *key, const u8 hfunc)
 519{
 520        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 521        struct enetc_hw *hw = &priv->si->hw;
 522        int err = 0;
 523
 524        /* set hash key, if PF */
 525        if (key && hw->port)
 526                enetc_set_rss_key(hw, key);
 527
 528        /* set RSS table */
 529        if (indir)
 530                err = enetc_set_rss_table(priv->si, indir, priv->si->num_rss);
 531
 532        return err;
 533}
 534
 535static void enetc_get_ringparam(struct net_device *ndev,
 536                                struct ethtool_ringparam *ring)
 537{
 538        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 539
 540        ring->rx_pending = priv->rx_bd_count;
 541        ring->tx_pending = priv->tx_bd_count;
 542
 543        /* do some h/w sanity checks for BDR length */
 544        if (netif_running(ndev)) {
 545                struct enetc_hw *hw = &priv->si->hw;
 546                u32 val = enetc_rxbdr_rd(hw, 0, ENETC_RBLENR);
 547
 548                if (val != priv->rx_bd_count)
 549                        netif_err(priv, hw, ndev, "RxBDR[RBLENR] = %d!\n", val);
 550
 551                val = enetc_txbdr_rd(hw, 0, ENETC_TBLENR);
 552
 553                if (val != priv->tx_bd_count)
 554                        netif_err(priv, hw, ndev, "TxBDR[TBLENR] = %d!\n", val);
 555        }
 556}
 557
 558static int enetc_get_ts_info(struct net_device *ndev,
 559                             struct ethtool_ts_info *info)
 560{
 561        int *phc_idx;
 562
 563        phc_idx = symbol_get(enetc_phc_index);
 564        if (phc_idx) {
 565                info->phc_index = *phc_idx;
 566                symbol_put(enetc_phc_index);
 567        } else {
 568                info->phc_index = -1;
 569        }
 570
 571#ifdef CONFIG_FSL_ENETC_HW_TIMESTAMPING
 572        info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
 573                                SOF_TIMESTAMPING_RX_HARDWARE |
 574                                SOF_TIMESTAMPING_RAW_HARDWARE;
 575
 576        info->tx_types = (1 << HWTSTAMP_TX_OFF) |
 577                         (1 << HWTSTAMP_TX_ON);
 578        info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
 579                           (1 << HWTSTAMP_FILTER_ALL);
 580#else
 581        info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
 582                                SOF_TIMESTAMPING_SOFTWARE;
 583#endif
 584        return 0;
 585}
 586
 587static const struct ethtool_ops enetc_pf_ethtool_ops = {
 588        .get_regs_len = enetc_get_reglen,
 589        .get_regs = enetc_get_regs,
 590        .get_sset_count = enetc_get_sset_count,
 591        .get_strings = enetc_get_strings,
 592        .get_ethtool_stats = enetc_get_ethtool_stats,
 593        .get_rxnfc = enetc_get_rxnfc,
 594        .set_rxnfc = enetc_set_rxnfc,
 595        .get_rxfh_key_size = enetc_get_rxfh_key_size,
 596        .get_rxfh_indir_size = enetc_get_rxfh_indir_size,
 597        .get_rxfh = enetc_get_rxfh,
 598        .set_rxfh = enetc_set_rxfh,
 599        .get_ringparam = enetc_get_ringparam,
 600        .get_link_ksettings = phy_ethtool_get_link_ksettings,
 601        .set_link_ksettings = phy_ethtool_set_link_ksettings,
 602        .get_link = ethtool_op_get_link,
 603        .get_ts_info = enetc_get_ts_info,
 604};
 605
 606static const struct ethtool_ops enetc_vf_ethtool_ops = {
 607        .get_regs_len = enetc_get_reglen,
 608        .get_regs = enetc_get_regs,
 609        .get_sset_count = enetc_get_sset_count,
 610        .get_strings = enetc_get_strings,
 611        .get_ethtool_stats = enetc_get_ethtool_stats,
 612        .get_rxnfc = enetc_get_rxnfc,
 613        .set_rxnfc = enetc_set_rxnfc,
 614        .get_rxfh_indir_size = enetc_get_rxfh_indir_size,
 615        .get_rxfh = enetc_get_rxfh,
 616        .set_rxfh = enetc_set_rxfh,
 617        .get_ringparam = enetc_get_ringparam,
 618        .get_link = ethtool_op_get_link,
 619        .get_ts_info = enetc_get_ts_info,
 620};
 621
 622void enetc_set_ethtool_ops(struct net_device *ndev)
 623{
 624        struct enetc_ndev_priv *priv = netdev_priv(ndev);
 625
 626        if (enetc_si_is_pf(priv->si))
 627                ndev->ethtool_ops = &enetc_pf_ethtool_ops;
 628        else
 629                ndev->ethtool_ops = &enetc_vf_ethtool_ops;
 630}
 631