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 8 static 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 15 static 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 20 static 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 25 static 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 32 static 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 50 static 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 92 static 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 122 static 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 186 static const char rx_ring_stats[][ETH_GSTRING_LEN] = { 187 "Rx ring %2d frames", 188 "Rx ring %2d alloc errors", 189 }; 190 191 static const char tx_ring_stats[][ETH_GSTRING_LEN] = { 192 "Tx ring %2d frames", 193 }; 194 195 static int enetc_get_sset_count(struct net_device *ndev, int sset) 196 { 197 struct enetc_ndev_priv *priv = netdev_priv(ndev); 198 int len; 199 200 if (sset != ETH_SS_STATS) 201 return -EOPNOTSUPP; 202 203 len = ARRAY_SIZE(enetc_si_counters) + 204 ARRAY_SIZE(tx_ring_stats) * priv->num_tx_rings + 205 ARRAY_SIZE(rx_ring_stats) * priv->num_rx_rings; 206 207 if (!enetc_si_is_pf(priv->si)) 208 return len; 209 210 len += ARRAY_SIZE(enetc_port_counters); 211 212 return len; 213 } 214 215 static void enetc_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 216 { 217 struct enetc_ndev_priv *priv = netdev_priv(ndev); 218 u8 *p = data; 219 int i, j; 220 221 switch (stringset) { 222 case ETH_SS_STATS: 223 for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++) { 224 strlcpy(p, enetc_si_counters[i].name, ETH_GSTRING_LEN); 225 p += ETH_GSTRING_LEN; 226 } 227 for (i = 0; i < priv->num_tx_rings; i++) { 228 for (j = 0; j < ARRAY_SIZE(tx_ring_stats); j++) { 229 snprintf(p, ETH_GSTRING_LEN, tx_ring_stats[j], 230 i); 231 p += ETH_GSTRING_LEN; 232 } 233 } 234 for (i = 0; i < priv->num_rx_rings; i++) { 235 for (j = 0; j < ARRAY_SIZE(rx_ring_stats); j++) { 236 snprintf(p, ETH_GSTRING_LEN, rx_ring_stats[j], 237 i); 238 p += ETH_GSTRING_LEN; 239 } 240 } 241 242 if (!enetc_si_is_pf(priv->si)) 243 break; 244 245 for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++) { 246 strlcpy(p, enetc_port_counters[i].name, 247 ETH_GSTRING_LEN); 248 p += ETH_GSTRING_LEN; 249 } 250 break; 251 } 252 } 253 254 static void enetc_get_ethtool_stats(struct net_device *ndev, 255 struct ethtool_stats *stats, u64 *data) 256 { 257 struct enetc_ndev_priv *priv = netdev_priv(ndev); 258 struct enetc_hw *hw = &priv->si->hw; 259 int i, o = 0; 260 261 for (i = 0; i < ARRAY_SIZE(enetc_si_counters); i++) 262 data[o++] = enetc_rd64(hw, enetc_si_counters[i].reg); 263 264 for (i = 0; i < priv->num_tx_rings; i++) 265 data[o++] = priv->tx_ring[i]->stats.packets; 266 267 for (i = 0; i < priv->num_rx_rings; i++) { 268 data[o++] = priv->rx_ring[i]->stats.packets; 269 data[o++] = priv->rx_ring[i]->stats.rx_alloc_errs; 270 } 271 272 if (!enetc_si_is_pf(priv->si)) 273 return; 274 275 for (i = 0; i < ARRAY_SIZE(enetc_port_counters); i++) 276 data[o++] = enetc_port_rd(hw, enetc_port_counters[i].reg); 277 } 278 279 #define ENETC_RSSHASH_L3 (RXH_L2DA | RXH_VLAN | RXH_L3_PROTO | RXH_IP_SRC | \ 280 RXH_IP_DST) 281 #define ENETC_RSSHASH_L4 (ENETC_RSSHASH_L3 | RXH_L4_B_0_1 | RXH_L4_B_2_3) 282 static int enetc_get_rsshash(struct ethtool_rxnfc *rxnfc) 283 { 284 static const u32 rsshash[] = { 285 [TCP_V4_FLOW] = ENETC_RSSHASH_L4, 286 [UDP_V4_FLOW] = ENETC_RSSHASH_L4, 287 [SCTP_V4_FLOW] = ENETC_RSSHASH_L4, 288 [AH_ESP_V4_FLOW] = ENETC_RSSHASH_L3, 289 [IPV4_FLOW] = ENETC_RSSHASH_L3, 290 [TCP_V6_FLOW] = ENETC_RSSHASH_L4, 291 [UDP_V6_FLOW] = ENETC_RSSHASH_L4, 292 [SCTP_V6_FLOW] = ENETC_RSSHASH_L4, 293 [AH_ESP_V6_FLOW] = ENETC_RSSHASH_L3, 294 [IPV6_FLOW] = ENETC_RSSHASH_L3, 295 [ETHER_FLOW] = 0, 296 }; 297 298 if (rxnfc->flow_type >= ARRAY_SIZE(rsshash)) 299 return -EINVAL; 300 301 rxnfc->data = rsshash[rxnfc->flow_type]; 302 303 return 0; 304 } 305 306 /* current HW spec does byte reversal on everything including MAC addresses */ 307 static void ether_addr_copy_swap(u8 *dst, const u8 *src) 308 { 309 int i; 310 311 for (i = 0; i < ETH_ALEN; i++) 312 dst[i] = src[ETH_ALEN - i - 1]; 313 } 314 315 static int enetc_set_cls_entry(struct enetc_si *si, 316 struct ethtool_rx_flow_spec *fs, bool en) 317 { 318 struct ethtool_tcpip4_spec *l4ip4_h, *l4ip4_m; 319 struct ethtool_usrip4_spec *l3ip4_h, *l3ip4_m; 320 struct ethhdr *eth_h, *eth_m; 321 struct enetc_cmd_rfse rfse = { {0} }; 322 323 if (!en) 324 goto done; 325 326 switch (fs->flow_type & 0xff) { 327 case TCP_V4_FLOW: 328 l4ip4_h = &fs->h_u.tcp_ip4_spec; 329 l4ip4_m = &fs->m_u.tcp_ip4_spec; 330 goto l4ip4; 331 case UDP_V4_FLOW: 332 l4ip4_h = &fs->h_u.udp_ip4_spec; 333 l4ip4_m = &fs->m_u.udp_ip4_spec; 334 goto l4ip4; 335 case SCTP_V4_FLOW: 336 l4ip4_h = &fs->h_u.sctp_ip4_spec; 337 l4ip4_m = &fs->m_u.sctp_ip4_spec; 338 l4ip4: 339 rfse.sip_h[0] = l4ip4_h->ip4src; 340 rfse.sip_m[0] = l4ip4_m->ip4src; 341 rfse.dip_h[0] = l4ip4_h->ip4dst; 342 rfse.dip_m[0] = l4ip4_m->ip4dst; 343 rfse.sport_h = ntohs(l4ip4_h->psrc); 344 rfse.sport_m = ntohs(l4ip4_m->psrc); 345 rfse.dport_h = ntohs(l4ip4_h->pdst); 346 rfse.dport_m = ntohs(l4ip4_m->pdst); 347 if (l4ip4_m->tos) 348 netdev_warn(si->ndev, "ToS field is not supported and was ignored\n"); 349 rfse.ethtype_h = ETH_P_IP; /* IPv4 */ 350 rfse.ethtype_m = 0xffff; 351 break; 352 case IP_USER_FLOW: 353 l3ip4_h = &fs->h_u.usr_ip4_spec; 354 l3ip4_m = &fs->m_u.usr_ip4_spec; 355 356 rfse.sip_h[0] = l3ip4_h->ip4src; 357 rfse.sip_m[0] = l3ip4_m->ip4src; 358 rfse.dip_h[0] = l3ip4_h->ip4dst; 359 rfse.dip_m[0] = l3ip4_m->ip4dst; 360 if (l3ip4_m->tos) 361 netdev_warn(si->ndev, "ToS field is not supported and was ignored\n"); 362 rfse.ethtype_h = ETH_P_IP; /* IPv4 */ 363 rfse.ethtype_m = 0xffff; 364 break; 365 case ETHER_FLOW: 366 eth_h = &fs->h_u.ether_spec; 367 eth_m = &fs->m_u.ether_spec; 368 369 ether_addr_copy_swap(rfse.smac_h, eth_h->h_source); 370 ether_addr_copy_swap(rfse.smac_m, eth_m->h_source); 371 ether_addr_copy_swap(rfse.dmac_h, eth_h->h_dest); 372 ether_addr_copy_swap(rfse.dmac_m, eth_m->h_dest); 373 rfse.ethtype_h = ntohs(eth_h->h_proto); 374 rfse.ethtype_m = ntohs(eth_m->h_proto); 375 break; 376 default: 377 return -EOPNOTSUPP; 378 } 379 380 rfse.mode |= ENETC_RFSE_EN; 381 if (fs->ring_cookie != RX_CLS_FLOW_DISC) { 382 rfse.mode |= ENETC_RFSE_MODE_BD; 383 rfse.result = fs->ring_cookie; 384 } 385 done: 386 return enetc_set_fs_entry(si, &rfse, fs->location); 387 } 388 389 static int enetc_get_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc, 390 u32 *rule_locs) 391 { 392 struct enetc_ndev_priv *priv = netdev_priv(ndev); 393 int i, j; 394 395 switch (rxnfc->cmd) { 396 case ETHTOOL_GRXRINGS: 397 rxnfc->data = priv->num_rx_rings; 398 break; 399 case ETHTOOL_GRXFH: 400 /* get RSS hash config */ 401 return enetc_get_rsshash(rxnfc); 402 case ETHTOOL_GRXCLSRLCNT: 403 /* total number of entries */ 404 rxnfc->data = priv->si->num_fs_entries; 405 /* number of entries in use */ 406 rxnfc->rule_cnt = 0; 407 for (i = 0; i < priv->si->num_fs_entries; i++) 408 if (priv->cls_rules[i].used) 409 rxnfc->rule_cnt++; 410 break; 411 case ETHTOOL_GRXCLSRULE: 412 if (rxnfc->fs.location >= priv->si->num_fs_entries) 413 return -EINVAL; 414 415 /* get entry x */ 416 rxnfc->fs = priv->cls_rules[rxnfc->fs.location].fs; 417 break; 418 case ETHTOOL_GRXCLSRLALL: 419 /* total number of entries */ 420 rxnfc->data = priv->si->num_fs_entries; 421 /* array of indexes of used entries */ 422 j = 0; 423 for (i = 0; i < priv->si->num_fs_entries; i++) { 424 if (!priv->cls_rules[i].used) 425 continue; 426 if (j == rxnfc->rule_cnt) 427 return -EMSGSIZE; 428 rule_locs[j++] = i; 429 } 430 /* number of entries in use */ 431 rxnfc->rule_cnt = j; 432 break; 433 default: 434 return -EOPNOTSUPP; 435 } 436 437 return 0; 438 } 439 440 static int enetc_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *rxnfc) 441 { 442 struct enetc_ndev_priv *priv = netdev_priv(ndev); 443 int err; 444 445 switch (rxnfc->cmd) { 446 case ETHTOOL_SRXCLSRLINS: 447 if (rxnfc->fs.location >= priv->si->num_fs_entries) 448 return -EINVAL; 449 450 if (rxnfc->fs.ring_cookie >= priv->num_rx_rings && 451 rxnfc->fs.ring_cookie != RX_CLS_FLOW_DISC) 452 return -EINVAL; 453 454 err = enetc_set_cls_entry(priv->si, &rxnfc->fs, true); 455 if (err) 456 return err; 457 priv->cls_rules[rxnfc->fs.location].fs = rxnfc->fs; 458 priv->cls_rules[rxnfc->fs.location].used = 1; 459 break; 460 case ETHTOOL_SRXCLSRLDEL: 461 if (rxnfc->fs.location >= priv->si->num_fs_entries) 462 return -EINVAL; 463 464 err = enetc_set_cls_entry(priv->si, &rxnfc->fs, false); 465 if (err) 466 return err; 467 priv->cls_rules[rxnfc->fs.location].used = 0; 468 break; 469 default: 470 return -EOPNOTSUPP; 471 } 472 473 return 0; 474 } 475 476 static u32 enetc_get_rxfh_key_size(struct net_device *ndev) 477 { 478 struct enetc_ndev_priv *priv = netdev_priv(ndev); 479 480 /* return the size of the RX flow hash key. PF only */ 481 return (priv->si->hw.port) ? ENETC_RSSHASH_KEY_SIZE : 0; 482 } 483 484 static u32 enetc_get_rxfh_indir_size(struct net_device *ndev) 485 { 486 struct enetc_ndev_priv *priv = netdev_priv(ndev); 487 488 /* return the size of the RX flow hash indirection table */ 489 return priv->si->num_rss; 490 } 491 492 static int enetc_get_rxfh(struct net_device *ndev, u32 *indir, u8 *key, 493 u8 *hfunc) 494 { 495 struct enetc_ndev_priv *priv = netdev_priv(ndev); 496 struct enetc_hw *hw = &priv->si->hw; 497 int err = 0, i; 498 499 /* return hash function */ 500 if (hfunc) 501 *hfunc = ETH_RSS_HASH_TOP; 502 503 /* return hash key */ 504 if (key && hw->port) 505 for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++) 506 ((u32 *)key)[i] = enetc_port_rd(hw, ENETC_PRSSK(i)); 507 508 /* return RSS table */ 509 if (indir) 510 err = enetc_get_rss_table(priv->si, indir, priv->si->num_rss); 511 512 return err; 513 } 514 515 void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes) 516 { 517 int i; 518 519 for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++) 520 enetc_port_wr(hw, ENETC_PRSSK(i), ((u32 *)bytes)[i]); 521 } 522 523 static int enetc_set_rxfh(struct net_device *ndev, const u32 *indir, 524 const u8 *key, const u8 hfunc) 525 { 526 struct enetc_ndev_priv *priv = netdev_priv(ndev); 527 struct enetc_hw *hw = &priv->si->hw; 528 int err = 0; 529 530 /* set hash key, if PF */ 531 if (key && hw->port) 532 enetc_set_rss_key(hw, key); 533 534 /* set RSS table */ 535 if (indir) 536 err = enetc_set_rss_table(priv->si, indir, priv->si->num_rss); 537 538 return err; 539 } 540 541 static void enetc_get_ringparam(struct net_device *ndev, 542 struct ethtool_ringparam *ring) 543 { 544 struct enetc_ndev_priv *priv = netdev_priv(ndev); 545 546 ring->rx_pending = priv->rx_bd_count; 547 ring->tx_pending = priv->tx_bd_count; 548 549 /* do some h/w sanity checks for BDR length */ 550 if (netif_running(ndev)) { 551 struct enetc_hw *hw = &priv->si->hw; 552 u32 val = enetc_rxbdr_rd(hw, 0, ENETC_RBLENR); 553 554 if (val != priv->rx_bd_count) 555 netif_err(priv, hw, ndev, "RxBDR[RBLENR] = %d!\n", val); 556 557 val = enetc_txbdr_rd(hw, 0, ENETC_TBLENR); 558 559 if (val != priv->tx_bd_count) 560 netif_err(priv, hw, ndev, "TxBDR[TBLENR] = %d!\n", val); 561 } 562 } 563 564 static int enetc_get_ts_info(struct net_device *ndev, 565 struct ethtool_ts_info *info) 566 { 567 int *phc_idx; 568 569 phc_idx = symbol_get(enetc_phc_index); 570 if (phc_idx) { 571 info->phc_index = *phc_idx; 572 symbol_put(enetc_phc_index); 573 } else { 574 info->phc_index = -1; 575 } 576 577 #ifdef CONFIG_FSL_ENETC_PTP_CLOCK 578 info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | 579 SOF_TIMESTAMPING_RX_HARDWARE | 580 SOF_TIMESTAMPING_RAW_HARDWARE; 581 582 info->tx_types = (1 << HWTSTAMP_TX_OFF) | 583 (1 << HWTSTAMP_TX_ON); 584 info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | 585 (1 << HWTSTAMP_FILTER_ALL); 586 #else 587 info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE | 588 SOF_TIMESTAMPING_TX_SOFTWARE | 589 SOF_TIMESTAMPING_SOFTWARE; 590 #endif 591 return 0; 592 } 593 594 static void enetc_get_wol(struct net_device *dev, 595 struct ethtool_wolinfo *wol) 596 { 597 wol->supported = 0; 598 wol->wolopts = 0; 599 600 if (dev->phydev) 601 phy_ethtool_get_wol(dev->phydev, wol); 602 } 603 604 static int enetc_set_wol(struct net_device *dev, 605 struct ethtool_wolinfo *wol) 606 { 607 int ret; 608 609 if (!dev->phydev) 610 return -EOPNOTSUPP; 611 612 ret = phy_ethtool_set_wol(dev->phydev, wol); 613 if (!ret) 614 device_set_wakeup_enable(&dev->dev, wol->wolopts); 615 616 return ret; 617 } 618 619 static const struct ethtool_ops enetc_pf_ethtool_ops = { 620 .get_regs_len = enetc_get_reglen, 621 .get_regs = enetc_get_regs, 622 .get_sset_count = enetc_get_sset_count, 623 .get_strings = enetc_get_strings, 624 .get_ethtool_stats = enetc_get_ethtool_stats, 625 .get_rxnfc = enetc_get_rxnfc, 626 .set_rxnfc = enetc_set_rxnfc, 627 .get_rxfh_key_size = enetc_get_rxfh_key_size, 628 .get_rxfh_indir_size = enetc_get_rxfh_indir_size, 629 .get_rxfh = enetc_get_rxfh, 630 .set_rxfh = enetc_set_rxfh, 631 .get_ringparam = enetc_get_ringparam, 632 .get_link_ksettings = phy_ethtool_get_link_ksettings, 633 .set_link_ksettings = phy_ethtool_set_link_ksettings, 634 .get_link = ethtool_op_get_link, 635 .get_ts_info = enetc_get_ts_info, 636 .get_wol = enetc_get_wol, 637 .set_wol = enetc_set_wol, 638 }; 639 640 static const struct ethtool_ops enetc_vf_ethtool_ops = { 641 .get_regs_len = enetc_get_reglen, 642 .get_regs = enetc_get_regs, 643 .get_sset_count = enetc_get_sset_count, 644 .get_strings = enetc_get_strings, 645 .get_ethtool_stats = enetc_get_ethtool_stats, 646 .get_rxnfc = enetc_get_rxnfc, 647 .set_rxnfc = enetc_set_rxnfc, 648 .get_rxfh_indir_size = enetc_get_rxfh_indir_size, 649 .get_rxfh = enetc_get_rxfh, 650 .set_rxfh = enetc_set_rxfh, 651 .get_ringparam = enetc_get_ringparam, 652 .get_link = ethtool_op_get_link, 653 .get_ts_info = enetc_get_ts_info, 654 }; 655 656 void enetc_set_ethtool_ops(struct net_device *ndev) 657 { 658 struct enetc_ndev_priv *priv = netdev_priv(ndev); 659 660 if (enetc_si_is_pf(priv->si)) 661 ndev->ethtool_ops = &enetc_pf_ethtool_ops; 662 else 663 ndev->ethtool_ops = &enetc_vf_ethtool_ops; 664 } 665