0001
0002
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;
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
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;
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;
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
0426 return enetc_get_rsshash(rxnfc);
0427 case ETHTOOL_GRXCLSRLCNT:
0428
0429 rxnfc->data = priv->si->num_fs_entries;
0430
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
0441 rxnfc->fs = priv->cls_rules[rxnfc->fs.location].fs;
0442 break;
0443 case ETHTOOL_GRXCLSRLALL:
0444
0445 rxnfc->data = priv->si->num_fs_entries;
0446
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
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
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
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
0525 if (hfunc)
0526 *hfunc = ETH_RSS_HASH_TOP;
0527
0528
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
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
0556 if (key && hw->port)
0557 enetc_set_rss_key(hw, key);
0558
0559
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
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
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
0654
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 }