Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
0002 /* Copyright 2017-2019 NXP */
0003 
0004 #include <linux/net_tstamp.h>
0005 #include <linux/module.h>
0006 #include "enetc.h"
0007 
0008 static const u32 enetc_si_regs[] = {
0009     ENETC_SIMR, ENETC_SIPMAR0, ENETC_SIPMAR1, ENETC_SICBDRMR,
0010     ENETC_SICBDRSR, ENETC_SICBDRBAR0, ENETC_SICBDRBAR1, ENETC_SICBDRPIR,
0011     ENETC_SICBDRCIR, ENETC_SICBDRLENR, ENETC_SICAPR0, ENETC_SICAPR1,
0012     ENETC_SIUEFDCR
0013 };
0014 
0015 static const u32 enetc_txbdr_regs[] = {
0016     ENETC_TBMR, ENETC_TBSR, ENETC_TBBAR0, ENETC_TBBAR1,
0017     ENETC_TBPIR, ENETC_TBCIR, ENETC_TBLENR, ENETC_TBIER, ENETC_TBICR0,
0018     ENETC_TBICR1
0019 };
0020 
0021 static const u32 enetc_rxbdr_regs[] = {
0022     ENETC_RBMR, ENETC_RBSR, ENETC_RBBSR, ENETC_RBCIR, ENETC_RBBAR0,
0023     ENETC_RBBAR1, ENETC_RBPIR, ENETC_RBLENR, ENETC_RBIER, ENETC_RBICR0,
0024     ENETC_RBICR1
0025 };
0026 
0027 static const u32 enetc_port_regs[] = {
0028     ENETC_PMR, ENETC_PSR, ENETC_PSIPMR, ENETC_PSIPMAR0(0),
0029     ENETC_PSIPMAR1(0), ENETC_PTXMBAR, ENETC_PCAPR0, ENETC_PCAPR1,
0030     ENETC_PSICFGR0(0), ENETC_PRFSCAPR, ENETC_PTCMSDUR(0),
0031     ENETC_PM0_CMD_CFG, ENETC_PM0_MAXFRM, ENETC_PM0_IF_MODE
0032 };
0033 
0034 static int enetc_get_reglen(struct net_device *ndev)
0035 {
0036     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0037     struct enetc_hw *hw = &priv->si->hw;
0038     int len;
0039 
0040     len = ARRAY_SIZE(enetc_si_regs);
0041     len += ARRAY_SIZE(enetc_txbdr_regs) * priv->num_tx_rings;
0042     len += ARRAY_SIZE(enetc_rxbdr_regs) * priv->num_rx_rings;
0043 
0044     if (hw->port)
0045         len += ARRAY_SIZE(enetc_port_regs);
0046 
0047     len *= sizeof(u32) * 2; /* store 2 entries per reg: addr and value */
0048 
0049     return len;
0050 }
0051 
0052 static void enetc_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
0053                void *regbuf)
0054 {
0055     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0056     struct enetc_hw *hw = &priv->si->hw;
0057     u32 *buf = (u32 *)regbuf;
0058     int i, j;
0059     u32 addr;
0060 
0061     for (i = 0; i < ARRAY_SIZE(enetc_si_regs); i++) {
0062         *buf++ = enetc_si_regs[i];
0063         *buf++ = enetc_rd(hw, enetc_si_regs[i]);
0064     }
0065 
0066     for (i = 0; i < priv->num_tx_rings; i++) {
0067         for (j = 0; j < ARRAY_SIZE(enetc_txbdr_regs); j++) {
0068             addr = ENETC_BDR(TX, i, enetc_txbdr_regs[j]);
0069 
0070             *buf++ = addr;
0071             *buf++ = enetc_rd(hw, addr);
0072         }
0073     }
0074 
0075     for (i = 0; i < priv->num_rx_rings; i++) {
0076         for (j = 0; j < ARRAY_SIZE(enetc_rxbdr_regs); j++) {
0077             addr = ENETC_BDR(RX, i, enetc_rxbdr_regs[j]);
0078 
0079             *buf++ = addr;
0080             *buf++ = enetc_rd(hw, addr);
0081         }
0082     }
0083 
0084     if (!hw->port)
0085         return;
0086 
0087     for (i = 0; i < ARRAY_SIZE(enetc_port_regs); i++) {
0088         addr = ENETC_PORT_BASE + enetc_port_regs[i];
0089         *buf++ = addr;
0090         *buf++ = enetc_rd(hw, addr);
0091     }
0092 }
0093 
0094 static const struct {
0095     int reg;
0096     char name[ETH_GSTRING_LEN];
0097 } enetc_si_counters[] =  {
0098     { ENETC_SIROCT, "SI rx octets" },
0099     { ENETC_SIRFRM, "SI rx frames" },
0100     { ENETC_SIRUCA, "SI rx u-cast frames" },
0101     { ENETC_SIRMCA, "SI rx m-cast frames" },
0102     { ENETC_SITOCT, "SI tx octets" },
0103     { ENETC_SITFRM, "SI tx frames" },
0104     { ENETC_SITUCA, "SI tx u-cast frames" },
0105     { ENETC_SITMCA, "SI tx m-cast frames" },
0106     { ENETC_RBDCR(0), "Rx ring  0 discarded frames" },
0107     { ENETC_RBDCR(1), "Rx ring  1 discarded frames" },
0108     { ENETC_RBDCR(2), "Rx ring  2 discarded frames" },
0109     { ENETC_RBDCR(3), "Rx ring  3 discarded frames" },
0110     { ENETC_RBDCR(4), "Rx ring  4 discarded frames" },
0111     { ENETC_RBDCR(5), "Rx ring  5 discarded frames" },
0112     { ENETC_RBDCR(6), "Rx ring  6 discarded frames" },
0113     { ENETC_RBDCR(7), "Rx ring  7 discarded frames" },
0114     { ENETC_RBDCR(8), "Rx ring  8 discarded frames" },
0115     { ENETC_RBDCR(9), "Rx ring  9 discarded frames" },
0116     { ENETC_RBDCR(10), "Rx ring 10 discarded frames" },
0117     { ENETC_RBDCR(11), "Rx ring 11 discarded frames" },
0118     { ENETC_RBDCR(12), "Rx ring 12 discarded frames" },
0119     { ENETC_RBDCR(13), "Rx ring 13 discarded frames" },
0120     { ENETC_RBDCR(14), "Rx ring 14 discarded frames" },
0121     { ENETC_RBDCR(15), "Rx ring 15 discarded frames" },
0122 };
0123 
0124 static const struct {
0125     int reg;
0126     char name[ETH_GSTRING_LEN];
0127 } enetc_port_counters[] = {
0128     { ENETC_PM0_REOCT,  "MAC rx ethernet octets" },
0129     { ENETC_PM0_RALN,   "MAC rx alignment errors" },
0130     { ENETC_PM0_RXPF,   "MAC rx valid pause frames" },
0131     { ENETC_PM0_RFRM,   "MAC rx valid frames" },
0132     { ENETC_PM0_RFCS,   "MAC rx fcs errors" },
0133     { ENETC_PM0_RVLAN,  "MAC rx VLAN frames" },
0134     { ENETC_PM0_RERR,   "MAC rx frame errors" },
0135     { ENETC_PM0_RUCA,   "MAC rx unicast frames" },
0136     { ENETC_PM0_RMCA,   "MAC rx multicast frames" },
0137     { ENETC_PM0_RBCA,   "MAC rx broadcast frames" },
0138     { ENETC_PM0_RDRP,   "MAC rx dropped packets" },
0139     { ENETC_PM0_RPKT,   "MAC rx packets" },
0140     { ENETC_PM0_RUND,   "MAC rx undersized packets" },
0141     { ENETC_PM0_R64,    "MAC rx 64 byte packets" },
0142     { ENETC_PM0_R127,   "MAC rx 65-127 byte packets" },
0143     { ENETC_PM0_R255,   "MAC rx 128-255 byte packets" },
0144     { ENETC_PM0_R511,   "MAC rx 256-511 byte packets" },
0145     { ENETC_PM0_R1023,  "MAC rx 512-1023 byte packets" },
0146     { ENETC_PM0_R1522,  "MAC rx 1024-1522 byte packets" },
0147     { ENETC_PM0_R1523X, "MAC rx 1523 to max-octet packets" },
0148     { ENETC_PM0_ROVR,   "MAC rx oversized packets" },
0149     { ENETC_PM0_RJBR,   "MAC rx jabber packets" },
0150     { ENETC_PM0_RFRG,   "MAC rx fragment packets" },
0151     { ENETC_PM0_RCNP,   "MAC rx control packets" },
0152     { ENETC_PM0_RDRNTP, "MAC rx fifo drop" },
0153     { ENETC_PM0_TEOCT,  "MAC tx ethernet octets" },
0154     { ENETC_PM0_TOCT,   "MAC tx octets" },
0155     { ENETC_PM0_TCRSE,  "MAC tx carrier sense errors" },
0156     { ENETC_PM0_TXPF,   "MAC tx valid pause frames" },
0157     { ENETC_PM0_TFRM,   "MAC tx frames" },
0158     { ENETC_PM0_TFCS,   "MAC tx fcs errors" },
0159     { ENETC_PM0_TVLAN,  "MAC tx VLAN frames" },
0160     { ENETC_PM0_TERR,   "MAC tx frame errors" },
0161     { ENETC_PM0_TUCA,   "MAC tx unicast frames" },
0162     { ENETC_PM0_TMCA,   "MAC tx multicast frames" },
0163     { ENETC_PM0_TBCA,   "MAC tx broadcast frames" },
0164     { ENETC_PM0_TPKT,   "MAC tx packets" },
0165     { ENETC_PM0_TUND,   "MAC tx undersized packets" },
0166     { ENETC_PM0_T64,    "MAC tx 64 byte packets" },
0167     { ENETC_PM0_T127,   "MAC tx 65-127 byte packets" },
0168     { ENETC_PM0_T255,   "MAC tx 128-255 byte packets" },
0169     { ENETC_PM0_T511,   "MAC tx 256-511 byte packets" },
0170     { ENETC_PM0_T1023,  "MAC tx 512-1023 byte packets" },
0171     { ENETC_PM0_T1522,  "MAC tx 1024-1522 byte packets" },
0172     { ENETC_PM0_T1523X, "MAC tx 1523 to max-octet packets" },
0173     { ENETC_PM0_TCNP,   "MAC tx control packets" },
0174     { ENETC_PM0_TDFR,   "MAC tx deferred packets" },
0175     { ENETC_PM0_TMCOL,  "MAC tx multiple collisions" },
0176     { ENETC_PM0_TSCOL,  "MAC tx single collisions" },
0177     { ENETC_PM0_TLCOL,  "MAC tx late collisions" },
0178     { ENETC_PM0_TECOL,  "MAC tx excessive collisions" },
0179     { ENETC_UFDMF,      "SI MAC nomatch u-cast discards" },
0180     { ENETC_MFDMF,      "SI MAC nomatch m-cast discards" },
0181     { ENETC_PBFDSIR,    "SI MAC nomatch b-cast discards" },
0182     { ENETC_PUFDVFR,    "SI VLAN nomatch u-cast discards" },
0183     { ENETC_PMFDVFR,    "SI VLAN nomatch m-cast discards" },
0184     { ENETC_PBFDVFR,    "SI VLAN nomatch b-cast discards" },
0185     { ENETC_PFDMSAPR,   "SI pruning discarded frames" },
0186     { ENETC_PICDR(0),   "ICM DR0 discarded frames" },
0187     { ENETC_PICDR(1),   "ICM DR1 discarded frames" },
0188     { ENETC_PICDR(2),   "ICM DR2 discarded frames" },
0189     { ENETC_PICDR(3),   "ICM DR3 discarded frames" },
0190 };
0191 
0192 static const char rx_ring_stats[][ETH_GSTRING_LEN] = {
0193     "Rx ring %2d frames",
0194     "Rx ring %2d alloc errors",
0195     "Rx ring %2d XDP drops",
0196     "Rx ring %2d recycles",
0197     "Rx ring %2d recycle failures",
0198     "Rx ring %2d redirects",
0199     "Rx ring %2d redirect failures",
0200     "Rx ring %2d redirect S/G",
0201 };
0202 
0203 static const char tx_ring_stats[][ETH_GSTRING_LEN] = {
0204     "Tx ring %2d frames",
0205     "Tx ring %2d XDP frames",
0206     "Tx ring %2d XDP drops",
0207     "Tx window drop %2d frames",
0208 };
0209 
0210 static int enetc_get_sset_count(struct net_device *ndev, int sset)
0211 {
0212     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0213     int len;
0214 
0215     if (sset != ETH_SS_STATS)
0216         return -EOPNOTSUPP;
0217 
0218     len = ARRAY_SIZE(enetc_si_counters) +
0219           ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings +
0220           ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings;
0221 
0222     if (!enetc_si_is_pf(priv->si))
0223         return len;
0224 
0225     len += ARRAY_SIZE(enetc_port_counters);
0226 
0227     return len;
0228 }
0229 
0230 static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
0231 {
0232     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0233     u8 *p = data;
0234     int i, j;
0235 
0236     switch (stringset) {
0237     case ETH_SS_STATS:
0238         for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++) {
0239             strlcpy(p, enetc_si_counters[i].name, ETH_GSTRING_LEN);
0240             p += ETH_GSTRING_LEN;
0241         }
0242         for (i = 0; i < priv->num_tx_rings; i++) {
0243             for (j = 0; j < ARRAY_SIZE(tx_ring_stats); j++) {
0244                 snprintf(p, ETH_GSTRING_LEN, tx_ring_stats[j],
0245                      i);
0246                 p += ETH_GSTRING_LEN;
0247             }
0248         }
0249         for (i = 0; i < priv->num_rx_rings; i++) {
0250             for (j = 0; j < ARRAY_SIZE(rx_ring_stats); j++) {
0251                 snprintf(p, ETH_GSTRING_LEN, rx_ring_stats[j],
0252                      i);
0253                 p += ETH_GSTRING_LEN;
0254             }
0255         }
0256 
0257         if (!enetc_si_is_pf(priv->si))
0258             break;
0259 
0260         for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++) {
0261             strlcpy(p, enetc_port_counters[i].name,
0262                 ETH_GSTRING_LEN);
0263             p += ETH_GSTRING_LEN;
0264         }
0265         break;
0266     }
0267 }
0268 
0269 static void enetc_get_ethtool_stats(struct net_device *ndev,
0270                     struct ethtool_stats *stats, u64 *data)
0271 {
0272     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0273     struct enetc_hw *hw = &priv->si->hw;
0274     int i, o = 0;
0275 
0276     for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++)
0277         data[o++] = enetc_rd64(hw, enetc_si_counters[i].reg);
0278 
0279     for (i = 0; i < priv->num_tx_rings; i++) {
0280         data[o++] = priv->tx_ring[i]->stats.packets;
0281         data[o++] = priv->tx_ring[i]->stats.xdp_tx;
0282         data[o++] = priv->tx_ring[i]->stats.xdp_tx_drops;
0283         data[o++] = priv->tx_ring[i]->stats.win_drop;
0284     }
0285 
0286     for (i = 0; i < priv->num_rx_rings; i++) {
0287         data[o++] = priv->rx_ring[i]->stats.packets;
0288         data[o++] = priv->rx_ring[i]->stats.rx_alloc_errs;
0289         data[o++] = priv->rx_ring[i]->stats.xdp_drops;
0290         data[o++] = priv->rx_ring[i]->stats.recycles;
0291         data[o++] = priv->rx_ring[i]->stats.recycle_failures;
0292         data[o++] = priv->rx_ring[i]->stats.xdp_redirect;
0293         data[o++] = priv->rx_ring[i]->stats.xdp_redirect_failures;
0294         data[o++] = priv->rx_ring[i]->stats.xdp_redirect_sg;
0295     }
0296 
0297     if (!enetc_si_is_pf(priv->si))
0298         return;
0299 
0300     for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++)
0301         data[o++] = enetc_port_rd(hw, enetc_port_counters[i].reg);
0302 }
0303 
0304 #define ENETC_RSSHASH_L3 (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO | RXH_IP_SRC | \
0305               RXH_IP_DST)
0306 #define ENETC_RSSHASH_L4 (ENETC_RSSHASH_L3 | RXH_L4_B_0_1 | RXH_L4_B_2_3)
0307 static int enetc_get_rsshash(struct ethtool_rxnfc *rxnfc)
0308 {
0309     static const u32 rsshash[] = {
0310             [TCP_V4_FLOW]    = ENETC_RSSHASH_L4,
0311             [UDP_V4_FLOW]    = ENETC_RSSHASH_L4,
0312             [SCTP_V4_FLOW]   = ENETC_RSSHASH_L4,
0313             [AH_ESP_V4_FLOW] = ENETC_RSSHASH_L3,
0314             [IPV4_FLOW]      = ENETC_RSSHASH_L3,
0315             [TCP_V6_FLOW]    = ENETC_RSSHASH_L4,
0316             [UDP_V6_FLOW]    = ENETC_RSSHASH_L4,
0317             [SCTP_V6_FLOW]   = ENETC_RSSHASH_L4,
0318             [AH_ESP_V6_FLOW] = ENETC_RSSHASH_L3,
0319             [IPV6_FLOW]      = ENETC_RSSHASH_L3,
0320             [ETHER_FLOW]     = 0,
0321     };
0322 
0323     if (rxnfc->flow_type >= ARRAY_SIZE(rsshash))
0324         return -EINVAL;
0325 
0326     rxnfc->data = rsshash[rxnfc->flow_type];
0327 
0328     return 0;
0329 }
0330 
0331 /* current HW spec does byte reversal on everything including MAC addresses */
0332 static void ether_addr_copy_swap(u8 *dst, const u8 *src)
0333 {
0334     int i;
0335 
0336     for (i = 0; i < ETH_ALEN; i++)
0337         dst[i] = src[ETH_ALEN - i - 1];
0338 }
0339 
0340 static int enetc_set_cls_entry(struct enetc_si *si,
0341                    struct ethtool_rx_flow_spec *fs, bool en)
0342 {
0343     struct ethtool_tcpip4_spec *l4ip4_h, *l4ip4_m;
0344     struct ethtool_usrip4_spec *l3ip4_h, *l3ip4_m;
0345     struct ethhdr *eth_h, *eth_m;
0346     struct enetc_cmd_rfse rfse = { {0} };
0347 
0348     if (!en)
0349         goto done;
0350 
0351     switch (fs->flow_type & 0xff) {
0352     case TCP_V4_FLOW:
0353         l4ip4_h = &fs->h_u.tcp_ip4_spec;
0354         l4ip4_m = &fs->m_u.tcp_ip4_spec;
0355         goto l4ip4;
0356     case UDP_V4_FLOW:
0357         l4ip4_h = &fs->h_u.udp_ip4_spec;
0358         l4ip4_m = &fs->m_u.udp_ip4_spec;
0359         goto l4ip4;
0360     case SCTP_V4_FLOW:
0361         l4ip4_h = &fs->h_u.sctp_ip4_spec;
0362         l4ip4_m = &fs->m_u.sctp_ip4_spec;
0363 l4ip4:
0364         rfse.sip_h[0] = l4ip4_h->ip4src;
0365         rfse.sip_m[0] = l4ip4_m->ip4src;
0366         rfse.dip_h[0] = l4ip4_h->ip4dst;
0367         rfse.dip_m[0] = l4ip4_m->ip4dst;
0368         rfse.sport_h = ntohs(l4ip4_h->psrc);
0369         rfse.sport_m = ntohs(l4ip4_m->psrc);
0370         rfse.dport_h = ntohs(l4ip4_h->pdst);
0371         rfse.dport_m = ntohs(l4ip4_m->pdst);
0372         if (l4ip4_m->tos)
0373             netdev_warn(si->ndev, "ToS field is not supported and was ignored\n");
0374         rfse.ethtype_h = ETH_P_IP; /* IPv4 */
0375         rfse.ethtype_m = 0xffff;
0376         break;
0377     case IP_USER_FLOW:
0378         l3ip4_h = &fs->h_u.usr_ip4_spec;
0379         l3ip4_m = &fs->m_u.usr_ip4_spec;
0380 
0381         rfse.sip_h[0] = l3ip4_h->ip4src;
0382         rfse.sip_m[0] = l3ip4_m->ip4src;
0383         rfse.dip_h[0] = l3ip4_h->ip4dst;
0384         rfse.dip_m[0] = l3ip4_m->ip4dst;
0385         if (l3ip4_m->tos)
0386             netdev_warn(si->ndev, "ToS field is not supported and was ignored\n");
0387         rfse.ethtype_h = ETH_P_IP; /* IPv4 */
0388         rfse.ethtype_m = 0xffff;
0389         break;
0390     case ETHER_FLOW:
0391         eth_h = &fs->h_u.ether_spec;
0392         eth_m = &fs->m_u.ether_spec;
0393 
0394         ether_addr_copy_swap(rfse.smac_h, eth_h->h_source);
0395         ether_addr_copy_swap(rfse.smac_m, eth_m->h_source);
0396         ether_addr_copy_swap(rfse.dmac_h, eth_h->h_dest);
0397         ether_addr_copy_swap(rfse.dmac_m, eth_m->h_dest);
0398         rfse.ethtype_h = ntohs(eth_h->h_proto);
0399         rfse.ethtype_m = ntohs(eth_m->h_proto);
0400         break;
0401     default:
0402         return -EOPNOTSUPP;
0403     }
0404 
0405     rfse.mode |= ENETC_RFSE_EN;
0406     if (fs->ring_cookie != RX_CLS_FLOW_DISC) {
0407         rfse.mode |= ENETC_RFSE_MODE_BD;
0408         rfse.result = fs->ring_cookie;
0409     }
0410 done:
0411     return enetc_set_fs_entry(si, &rfse, fs->location);
0412 }
0413 
0414 static int enetc_get_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc,
0415                u32 *rule_locs)
0416 {
0417     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0418     int i, j;
0419 
0420     switch (rxnfc->cmd) {
0421     case ETHTOOL_GRXRINGS:
0422         rxnfc->data = priv->num_rx_rings;
0423         break;
0424     case ETHTOOL_GRXFH:
0425         /* get RSS hash config */
0426         return enetc_get_rsshash(rxnfc);
0427     case ETHTOOL_GRXCLSRLCNT:
0428         /* total number of entries */
0429         rxnfc->data = priv->si->num_fs_entries;
0430         /* number of entries in use */
0431         rxnfc->rule_cnt = 0;
0432         for (i = 0; i < priv->si->num_fs_entries; i++)
0433             if (priv->cls_rules[i].used)
0434                 rxnfc->rule_cnt++;
0435         break;
0436     case ETHTOOL_GRXCLSRULE:
0437         if (rxnfc->fs.location >= priv->si->num_fs_entries)
0438             return -EINVAL;
0439 
0440         /* get entry x */
0441         rxnfc->fs = priv->cls_rules[rxnfc->fs.location].fs;
0442         break;
0443     case ETHTOOL_GRXCLSRLALL:
0444         /* total number of entries */
0445         rxnfc->data = priv->si->num_fs_entries;
0446         /* array of indexes of used entries */
0447         j = 0;
0448         for (i = 0; i < priv->si->num_fs_entries; i++) {
0449             if (!priv->cls_rules[i].used)
0450                 continue;
0451             if (j == rxnfc->rule_cnt)
0452                 return -EMSGSIZE;
0453             rule_locs[j++] = i;
0454         }
0455         /* number of entries in use */
0456         rxnfc->rule_cnt = j;
0457         break;
0458     default:
0459         return -EOPNOTSUPP;
0460     }
0461 
0462     return 0;
0463 }
0464 
0465 static int enetc_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc)
0466 {
0467     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0468     int err;
0469 
0470     switch (rxnfc->cmd) {
0471     case ETHTOOL_SRXCLSRLINS:
0472         if (rxnfc->fs.location >= priv->si->num_fs_entries)
0473             return -EINVAL;
0474 
0475         if (rxnfc->fs.ring_cookie >= priv->num_rx_rings &&
0476             rxnfc->fs.ring_cookie != RX_CLS_FLOW_DISC)
0477             return -EINVAL;
0478 
0479         err = enetc_set_cls_entry(priv->si, &rxnfc->fs, true);
0480         if (err)
0481             return err;
0482         priv->cls_rules[rxnfc->fs.location].fs = rxnfc->fs;
0483         priv->cls_rules[rxnfc->fs.location].used = 1;
0484         break;
0485     case ETHTOOL_SRXCLSRLDEL:
0486         if (rxnfc->fs.location >= priv->si->num_fs_entries)
0487             return -EINVAL;
0488 
0489         err = enetc_set_cls_entry(priv->si, &rxnfc->fs, false);
0490         if (err)
0491             return err;
0492         priv->cls_rules[rxnfc->fs.location].used = 0;
0493         break;
0494     default:
0495         return -EOPNOTSUPP;
0496     }
0497 
0498     return 0;
0499 }
0500 
0501 static u32 enetc_get_rxfh_key_size(struct net_device *ndev)
0502 {
0503     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0504 
0505     /* return the size of the RX flow hash key.  PF only */
0506     return (priv->si->hw.port) ? ENETC_RSSHASH_KEY_SIZE : 0;
0507 }
0508 
0509 static u32 enetc_get_rxfh_indir_size(struct net_device *ndev)
0510 {
0511     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0512 
0513     /* return the size of the RX flow hash indirection table */
0514     return priv->si->num_rss;
0515 }
0516 
0517 static int enetc_get_rxfh(struct net_device *ndev, u32 *indir, u8 *key,
0518               u8 *hfunc)
0519 {
0520     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0521     struct enetc_hw *hw = &priv->si->hw;
0522     int err = 0, i;
0523 
0524     /* return hash function */
0525     if (hfunc)
0526         *hfunc = ETH_RSS_HASH_TOP;
0527 
0528     /* return hash key */
0529     if (key && hw->port)
0530         for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
0531             ((u32 *)key)[i] = enetc_port_rd(hw, ENETC_PRSSK(i));
0532 
0533     /* return RSS table */
0534     if (indir)
0535         err = enetc_get_rss_table(priv->si, indir, priv->si->num_rss);
0536 
0537     return err;
0538 }
0539 
0540 void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes)
0541 {
0542     int i;
0543 
0544     for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
0545         enetc_port_wr(hw, ENETC_PRSSK(i), ((u32 *)bytes)[i]);
0546 }
0547 
0548 static int enetc_set_rxfh(struct net_device *ndev, const u32 *indir,
0549               const u8 *key, const u8 hfunc)
0550 {
0551     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0552     struct enetc_hw *hw = &priv->si->hw;
0553     int err = 0;
0554 
0555     /* set hash key, if PF */
0556     if (key && hw->port)
0557         enetc_set_rss_key(hw, key);
0558 
0559     /* set RSS table */
0560     if (indir)
0561         err = enetc_set_rss_table(priv->si, indir, priv->si->num_rss);
0562 
0563     return err;
0564 }
0565 
0566 static void enetc_get_ringparam(struct net_device *ndev,
0567                 struct ethtool_ringparam *ring,
0568                 struct kernel_ethtool_ringparam *kernel_ring,
0569                 struct netlink_ext_ack *extack)
0570 {
0571     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0572 
0573     ring->rx_pending = priv->rx_bd_count;
0574     ring->tx_pending = priv->tx_bd_count;
0575 
0576     /* do some h/w sanity checks for BDR length */
0577     if (netif_running(ndev)) {
0578         struct enetc_hw *hw = &priv->si->hw;
0579         u32 val = enetc_rxbdr_rd(hw, 0, ENETC_RBLENR);
0580 
0581         if (val != priv->rx_bd_count)
0582             netif_err(priv, hw, ndev, "RxBDR[RBLENR] = %d!\n", val);
0583 
0584         val = enetc_txbdr_rd(hw, 0, ENETC_TBLENR);
0585 
0586         if (val != priv->tx_bd_count)
0587             netif_err(priv, hw, ndev, "TxBDR[TBLENR] = %d!\n", val);
0588     }
0589 }
0590 
0591 static int enetc_get_coalesce(struct net_device *ndev,
0592                   struct ethtool_coalesce *ic,
0593                   struct kernel_ethtool_coalesce *kernel_coal,
0594                   struct netlink_ext_ack *extack)
0595 {
0596     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0597     struct enetc_int_vector *v = priv->int_vector[0];
0598 
0599     ic->tx_coalesce_usecs = enetc_cycles_to_usecs(priv->tx_ictt);
0600     ic->rx_coalesce_usecs = enetc_cycles_to_usecs(v->rx_ictt);
0601 
0602     ic->tx_max_coalesced_frames = ENETC_TXIC_PKTTHR;
0603     ic->rx_max_coalesced_frames = ENETC_RXIC_PKTTHR;
0604 
0605     ic->use_adaptive_rx_coalesce = priv->ic_mode & ENETC_IC_RX_ADAPTIVE;
0606 
0607     return 0;
0608 }
0609 
0610 static int enetc_set_coalesce(struct net_device *ndev,
0611                   struct ethtool_coalesce *ic,
0612                   struct kernel_ethtool_coalesce *kernel_coal,
0613                   struct netlink_ext_ack *extack)
0614 {
0615     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0616     u32 rx_ictt, tx_ictt;
0617     int i, ic_mode;
0618     bool changed;
0619 
0620     tx_ictt = enetc_usecs_to_cycles(ic->tx_coalesce_usecs);
0621     rx_ictt = enetc_usecs_to_cycles(ic->rx_coalesce_usecs);
0622 
0623     if (ic->rx_max_coalesced_frames != ENETC_RXIC_PKTTHR)
0624         return -EOPNOTSUPP;
0625 
0626     if (ic->tx_max_coalesced_frames != ENETC_TXIC_PKTTHR)
0627         return -EOPNOTSUPP;
0628 
0629     ic_mode = ENETC_IC_NONE;
0630     if (ic->use_adaptive_rx_coalesce) {
0631         ic_mode |= ENETC_IC_RX_ADAPTIVE;
0632         rx_ictt = 0x1;
0633     } else {
0634         ic_mode |= rx_ictt ? ENETC_IC_RX_MANUAL : 0;
0635     }
0636 
0637     ic_mode |= tx_ictt ? ENETC_IC_TX_MANUAL : 0;
0638 
0639     /* commit the settings */
0640     changed = (ic_mode != priv->ic_mode) || (priv->tx_ictt != tx_ictt);
0641 
0642     priv->ic_mode = ic_mode;
0643     priv->tx_ictt = tx_ictt;
0644 
0645     for (i = 0; i < priv->bdr_int_num; i++) {
0646         struct enetc_int_vector *v = priv->int_vector[i];
0647 
0648         v->rx_ictt = rx_ictt;
0649         v->rx_dim_en = !!(ic_mode & ENETC_IC_RX_ADAPTIVE);
0650     }
0651 
0652     if (netif_running(ndev) && changed) {
0653         /* reconfigure the operation mode of h/w interrupts,
0654          * traffic needs to be paused in the process
0655          */
0656         enetc_stop(ndev);
0657         enetc_start(ndev);
0658     }
0659 
0660     return 0;
0661 }
0662 
0663 static int enetc_get_ts_info(struct net_device *ndev,
0664                  struct ethtool_ts_info *info)
0665 {
0666     int *phc_idx;
0667 
0668     phc_idx = symbol_get(enetc_phc_index);
0669     if (phc_idx) {
0670         info->phc_index = *phc_idx;
0671         symbol_put(enetc_phc_index);
0672     } else {
0673         info->phc_index = -1;
0674     }
0675 
0676 #ifdef CONFIG_FSL_ENETC_PTP_CLOCK
0677     info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
0678                 SOF_TIMESTAMPING_RX_HARDWARE |
0679                 SOF_TIMESTAMPING_RAW_HARDWARE |
0680                 SOF_TIMESTAMPING_TX_SOFTWARE |
0681                 SOF_TIMESTAMPING_RX_SOFTWARE |
0682                 SOF_TIMESTAMPING_SOFTWARE;
0683 
0684     info->tx_types = (1 << HWTSTAMP_TX_OFF) |
0685              (1 << HWTSTAMP_TX_ON) |
0686              (1 << HWTSTAMP_TX_ONESTEP_SYNC);
0687     info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
0688                (1 << HWTSTAMP_FILTER_ALL);
0689 #else
0690     info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
0691                 SOF_TIMESTAMPING_TX_SOFTWARE |
0692                 SOF_TIMESTAMPING_SOFTWARE;
0693 #endif
0694     return 0;
0695 }
0696 
0697 static void enetc_get_wol(struct net_device *dev,
0698               struct ethtool_wolinfo *wol)
0699 {
0700     wol->supported = 0;
0701     wol->wolopts = 0;
0702 
0703     if (dev->phydev)
0704         phy_ethtool_get_wol(dev->phydev, wol);
0705 }
0706 
0707 static int enetc_set_wol(struct net_device *dev,
0708              struct ethtool_wolinfo *wol)
0709 {
0710     int ret;
0711 
0712     if (!dev->phydev)
0713         return -EOPNOTSUPP;
0714 
0715     ret = phy_ethtool_set_wol(dev->phydev, wol);
0716     if (!ret)
0717         device_set_wakeup_enable(&dev->dev, wol->wolopts);
0718 
0719     return ret;
0720 }
0721 
0722 static void enetc_get_pauseparam(struct net_device *dev,
0723                  struct ethtool_pauseparam *pause)
0724 {
0725     struct enetc_ndev_priv *priv = netdev_priv(dev);
0726 
0727     phylink_ethtool_get_pauseparam(priv->phylink, pause);
0728 }
0729 
0730 static int enetc_set_pauseparam(struct net_device *dev,
0731                 struct ethtool_pauseparam *pause)
0732 {
0733     struct enetc_ndev_priv *priv = netdev_priv(dev);
0734 
0735     return phylink_ethtool_set_pauseparam(priv->phylink, pause);
0736 }
0737 
0738 static int enetc_get_link_ksettings(struct net_device *dev,
0739                     struct ethtool_link_ksettings *cmd)
0740 {
0741     struct enetc_ndev_priv *priv = netdev_priv(dev);
0742 
0743     if (!priv->phylink)
0744         return -EOPNOTSUPP;
0745 
0746     return phylink_ethtool_ksettings_get(priv->phylink, cmd);
0747 }
0748 
0749 static int enetc_set_link_ksettings(struct net_device *dev,
0750                     const struct ethtool_link_ksettings *cmd)
0751 {
0752     struct enetc_ndev_priv *priv = netdev_priv(dev);
0753 
0754     if (!priv->phylink)
0755         return -EOPNOTSUPP;
0756 
0757     return phylink_ethtool_ksettings_set(priv->phylink, cmd);
0758 }
0759 
0760 static const struct ethtool_ops enetc_pf_ethtool_ops = {
0761     .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
0762                      ETHTOOL_COALESCE_MAX_FRAMES |
0763                      ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
0764     .get_regs_len = enetc_get_reglen,
0765     .get_regs = enetc_get_regs,
0766     .get_sset_count = enetc_get_sset_count,
0767     .get_strings = enetc_get_strings,
0768     .get_ethtool_stats = enetc_get_ethtool_stats,
0769     .get_rxnfc = enetc_get_rxnfc,
0770     .set_rxnfc = enetc_set_rxnfc,
0771     .get_rxfh_key_size = enetc_get_rxfh_key_size,
0772     .get_rxfh_indir_size = enetc_get_rxfh_indir_size,
0773     .get_rxfh = enetc_get_rxfh,
0774     .set_rxfh = enetc_set_rxfh,
0775     .get_ringparam = enetc_get_ringparam,
0776     .get_coalesce = enetc_get_coalesce,
0777     .set_coalesce = enetc_set_coalesce,
0778     .get_link_ksettings = enetc_get_link_ksettings,
0779     .set_link_ksettings = enetc_set_link_ksettings,
0780     .get_link = ethtool_op_get_link,
0781     .get_ts_info = enetc_get_ts_info,
0782     .get_wol = enetc_get_wol,
0783     .set_wol = enetc_set_wol,
0784     .get_pauseparam = enetc_get_pauseparam,
0785     .set_pauseparam = enetc_set_pauseparam,
0786 };
0787 
0788 static const struct ethtool_ops enetc_vf_ethtool_ops = {
0789     .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
0790                      ETHTOOL_COALESCE_MAX_FRAMES |
0791                      ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
0792     .get_regs_len = enetc_get_reglen,
0793     .get_regs = enetc_get_regs,
0794     .get_sset_count = enetc_get_sset_count,
0795     .get_strings = enetc_get_strings,
0796     .get_ethtool_stats = enetc_get_ethtool_stats,
0797     .get_rxnfc = enetc_get_rxnfc,
0798     .set_rxnfc = enetc_set_rxnfc,
0799     .get_rxfh_indir_size = enetc_get_rxfh_indir_size,
0800     .get_rxfh = enetc_get_rxfh,
0801     .set_rxfh = enetc_set_rxfh,
0802     .get_ringparam = enetc_get_ringparam,
0803     .get_coalesce = enetc_get_coalesce,
0804     .set_coalesce = enetc_set_coalesce,
0805     .get_link = ethtool_op_get_link,
0806     .get_ts_info = enetc_get_ts_info,
0807 };
0808 
0809 void enetc_set_ethtool_ops(struct net_device *ndev)
0810 {
0811     struct enetc_ndev_priv *priv = netdev_priv(ndev);
0812 
0813     if (enetc_si_is_pf(priv->si))
0814         ndev->ethtool_ops = &enetc_pf_ethtool_ops;
0815     else
0816         ndev->ethtool_ops = &enetc_vf_ethtool_ops;
0817 }