1/* 2 * drivers/net/gianfar_ethtool.c 3 * 4 * Gianfar Ethernet Driver 5 * Ethtool support for Gianfar Enet 6 * Based on e1000 ethtool support 7 * 8 * Author: Andy Fleming 9 * Maintainer: Kumar Gala 10 * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com> 11 * 12 * Copyright 2003-2006, 2008-2009 Freescale Semiconductor, Inc. 13 * 14 * This software may be used and distributed according to 15 * the terms of the GNU Public License, Version 2, incorporated herein 16 * by reference. 17 */ 18 19#include <linux/kernel.h> 20#include <linux/string.h> 21#include <linux/errno.h> 22#include <linux/interrupt.h> 23#include <linux/init.h> 24#include <linux/delay.h> 25#include <linux/netdevice.h> 26#include <linux/etherdevice.h> 27#include <linux/skbuff.h> 28#include <linux/spinlock.h> 29#include <linux/mm.h> 30 31#include <asm/io.h> 32#include <asm/irq.h> 33#include <asm/uaccess.h> 34#include <linux/module.h> 35#include <linux/crc32.h> 36#include <asm/types.h> 37#include <linux/ethtool.h> 38#include <linux/mii.h> 39#include <linux/phy.h> 40 41#include "gianfar.h" 42 43extern void gfar_start(struct net_device *dev); 44extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit); 45 46#define GFAR_MAX_COAL_USECS 0xffff 47#define GFAR_MAX_COAL_FRAMES 0xff 48static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, 49 u64 * buf); 50static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf); 51static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); 52static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); 53static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals); 54static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals); 55static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); 56 57static char stat_gstrings[][ETH_GSTRING_LEN] = { 58 "rx-dropped-by-kernel", 59 "rx-large-frame-errors", 60 "rx-short-frame-errors", 61 "rx-non-octet-errors", 62 "rx-crc-errors", 63 "rx-overrun-errors", 64 "rx-busy-errors", 65 "rx-babbling-errors", 66 "rx-truncated-frames", 67 "ethernet-bus-error", 68 "tx-babbling-errors", 69 "tx-underrun-errors", 70 "rx-skb-missing-errors", 71 "tx-timeout-errors", 72 "tx-rx-64-frames", 73 "tx-rx-65-127-frames", 74 "tx-rx-128-255-frames", 75 "tx-rx-256-511-frames", 76 "tx-rx-512-1023-frames", 77 "tx-rx-1024-1518-frames", 78 "tx-rx-1519-1522-good-vlan", 79 "rx-bytes", 80 "rx-packets", 81 "rx-fcs-errors", 82 "receive-multicast-packet", 83 "receive-broadcast-packet", 84 "rx-control-frame-packets", 85 "rx-pause-frame-packets", 86 "rx-unknown-op-code", 87 "rx-alignment-error", 88 "rx-frame-length-error", 89 "rx-code-error", 90 "rx-carrier-sense-error", 91 "rx-undersize-packets", 92 "rx-oversize-packets", 93 "rx-fragmented-frames", 94 "rx-jabber-frames", 95 "rx-dropped-frames", 96 "tx-byte-counter", 97 "tx-packets", 98 "tx-multicast-packets", 99 "tx-broadcast-packets", 100 "tx-pause-control-frames", 101 "tx-deferral-packets", 102 "tx-excessive-deferral-packets", 103 "tx-single-collision-packets", 104 "tx-multiple-collision-packets", 105 "tx-late-collision-packets", 106 "tx-excessive-collision-packets", 107 "tx-total-collision", 108 "reserved", 109 "tx-dropped-frames", 110 "tx-jabber-frames", 111 "tx-fcs-errors", 112 "tx-control-frames", 113 "tx-oversize-frames", 114 "tx-undersize-frames", 115 "tx-fragmented-frames", 116}; 117 118/* Fill in a buffer with the strings which correspond to the 119 * stats */ 120static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) 121{ 122 struct gfar_private *priv = netdev_priv(dev); 123 124 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) 125 memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN); 126 else 127 memcpy(buf, stat_gstrings, 128 GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN); 129} 130 131/* Fill in an array of 64-bit statistics from various sources. 132 * This array will be appended to the end of the ethtool_stats 133 * structure, and returned to user space 134 */ 135static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf) 136{ 137 int i; 138 struct gfar_private *priv = netdev_priv(dev); 139 struct gfar __iomem *regs = priv->gfargrp[0].regs; 140 u64 *extra = (u64 *) & priv->extra_stats; 141 142 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { 143 u32 __iomem *rmon = (u32 __iomem *) ®s->rmon; 144 struct gfar_stats *stats = (struct gfar_stats *) buf; 145 146 for (i = 0; i < GFAR_RMON_LEN; i++) 147 stats->rmon[i] = (u64) gfar_read(&rmon[i]); 148 149 for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) 150 stats->extra[i] = extra[i]; 151 } else 152 for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) 153 buf[i] = extra[i]; 154} 155 156static int gfar_sset_count(struct net_device *dev, int sset) 157{ 158 struct gfar_private *priv = netdev_priv(dev); 159 160 switch (sset) { 161 case ETH_SS_STATS: 162 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON) 163 return GFAR_STATS_LEN; 164 else 165 return GFAR_EXTRA_STATS_LEN; 166 default: 167 return -EOPNOTSUPP; 168 } 169} 170 171/* Fills in the drvinfo structure with some basic info */ 172static void gfar_gdrvinfo(struct net_device *dev, struct 173 ethtool_drvinfo *drvinfo) 174{ 175 strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); 176 strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN); 177 strncpy(drvinfo->fw_version, "N/A", GFAR_INFOSTR_LEN); 178 strncpy(drvinfo->bus_info, "N/A", GFAR_INFOSTR_LEN); 179 drvinfo->regdump_len = 0; 180 drvinfo->eedump_len = 0; 181} 182 183 184static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd) 185{ 186 struct gfar_private *priv = netdev_priv(dev); 187 struct phy_device *phydev = priv->phydev; 188 189 if (NULL == phydev) 190 return -ENODEV; 191 192 return phy_ethtool_sset(phydev, cmd); 193} 194 195 196/* Return the current settings in the ethtool_cmd structure */ 197static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) 198{ 199 struct gfar_private *priv = netdev_priv(dev); 200 struct phy_device *phydev = priv->phydev; 201 struct gfar_priv_rx_q *rx_queue = NULL; 202 struct gfar_priv_tx_q *tx_queue = NULL; 203 204 if (NULL == phydev) 205 return -ENODEV; 206 tx_queue = priv->tx_queue[0]; 207 rx_queue = priv->rx_queue[0]; 208 209 /* etsec-1.7 and older versions have only one txic 210 * and rxic regs although they support multiple queues */ 211 cmd->maxtxpkt = get_icft_value(tx_queue->txic); 212 cmd->maxrxpkt = get_icft_value(rx_queue->rxic); 213 214 return phy_ethtool_gset(phydev, cmd); 215} 216 217/* Return the length of the register structure */ 218static int gfar_reglen(struct net_device *dev) 219{ 220 return sizeof (struct gfar); 221} 222 223/* Return a dump of the GFAR register space */ 224static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) 225{ 226 int i; 227 struct gfar_private *priv = netdev_priv(dev); 228 u32 __iomem *theregs = (u32 __iomem *) priv->gfargrp[0].regs; 229 u32 *buf = (u32 *) regbuf; 230 231 for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++) 232 buf[i] = gfar_read(&theregs[i]); 233} 234 235/* Convert microseconds to ethernet clock ticks, which changes 236 * depending on what speed the controller is running at */ 237static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs) 238{ 239 unsigned int count; 240 241 /* The timer is different, depending on the interface speed */ 242 switch (priv->phydev->speed) { 243 case SPEED_1000: 244 count = GFAR_GBIT_TIME; 245 break; 246 case SPEED_100: 247 count = GFAR_100_TIME; 248 break; 249 case SPEED_10: 250 default: 251 count = GFAR_10_TIME; 252 break; 253 } 254 255 /* Make sure we return a number greater than 0 256 * if usecs > 0 */ 257 return ((usecs * 1000 + count - 1) / count); 258} 259 260/* Convert ethernet clock ticks to microseconds */ 261static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int ticks) 262{ 263 unsigned int count; 264 265 /* The timer is different, depending on the interface speed */ 266 switch (priv->phydev->speed) { 267 case SPEED_1000: 268 count = GFAR_GBIT_TIME; 269 break; 270 case SPEED_100: 271 count = GFAR_100_TIME; 272 break; 273 case SPEED_10: 274 default: 275 count = GFAR_10_TIME; 276 break; 277 } 278 279 /* Make sure we return a number greater than 0 */ 280 /* if ticks is > 0 */ 281 return ((ticks * count) / 1000); 282} 283 284/* Get the coalescing parameters, and put them in the cvals 285 * structure. */ 286static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) 287{ 288 struct gfar_private *priv = netdev_priv(dev); 289 struct gfar_priv_rx_q *rx_queue = NULL; 290 struct gfar_priv_tx_q *tx_queue = NULL; 291 unsigned long rxtime; 292 unsigned long rxcount; 293 unsigned long txtime; 294 unsigned long txcount; 295 296 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) 297 return -EOPNOTSUPP; 298 299 if (NULL == priv->phydev) 300 return -ENODEV; 301 302 rx_queue = priv->rx_queue[0]; 303 tx_queue = priv->tx_queue[0]; 304 305 rxtime = get_ictt_value(rx_queue->rxic); 306 rxcount = get_icft_value(rx_queue->rxic); 307 txtime = get_ictt_value(tx_queue->txic); 308 txcount = get_icft_value(tx_queue->txic); 309 cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime); 310 cvals->rx_max_coalesced_frames = rxcount; 311 312 cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, txtime); 313 cvals->tx_max_coalesced_frames = txcount; 314 315 cvals->use_adaptive_rx_coalesce = 0; 316 cvals->use_adaptive_tx_coalesce = 0; 317 318 cvals->pkt_rate_low = 0; 319 cvals->rx_coalesce_usecs_low = 0; 320 cvals->rx_max_coalesced_frames_low = 0; 321 cvals->tx_coalesce_usecs_low = 0; 322 cvals->tx_max_coalesced_frames_low = 0; 323 324 /* When the packet rate is below pkt_rate_high but above 325 * pkt_rate_low (both measured in packets per second) the 326 * normal {rx,tx}_* coalescing parameters are used. 327 */ 328 329 /* When the packet rate is (measured in packets per second) 330 * is above pkt_rate_high, the {rx,tx}_*_high parameters are 331 * used. 332 */ 333 cvals->pkt_rate_high = 0; 334 cvals->rx_coalesce_usecs_high = 0; 335 cvals->rx_max_coalesced_frames_high = 0; 336 cvals->tx_coalesce_usecs_high = 0; 337 cvals->tx_max_coalesced_frames_high = 0; 338 339 /* How often to do adaptive coalescing packet rate sampling, 340 * measured in seconds. Must not be zero. 341 */ 342 cvals->rate_sample_interval = 0; 343 344 return 0; 345} 346 347/* Change the coalescing values. 348 * Both cvals->*_usecs and cvals->*_frames have to be > 0 349 * in order for coalescing to be active 350 */ 351static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) 352{ 353 struct gfar_private *priv = netdev_priv(dev); 354 int i = 0; 355 356 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) 357 return -EOPNOTSUPP; 358 359 /* Set up rx coalescing */ 360 /* As of now, we will enable/disable coalescing for all 361 * queues together in case of eTSEC2, this will be modified 362 * along with the ethtool interface */ 363 if ((cvals->rx_coalesce_usecs == 0) || 364 (cvals->rx_max_coalesced_frames == 0)) { 365 for (i = 0; i < priv->num_rx_queues; i++) 366 priv->rx_queue[i]->rxcoalescing = 0; 367 } else { 368 for (i = 0; i < priv->num_rx_queues; i++) 369 priv->rx_queue[i]->rxcoalescing = 1; 370 } 371 372 if (NULL == priv->phydev) 373 return -ENODEV; 374 375 /* Check the bounds of the values */ 376 if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) { 377 pr_info("Coalescing is limited to %d microseconds\n", 378 GFAR_MAX_COAL_USECS); 379 return -EINVAL; 380 } 381 382 if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) { 383 pr_info("Coalescing is limited to %d frames\n", 384 GFAR_MAX_COAL_FRAMES); 385 return -EINVAL; 386 } 387 388 for (i = 0; i < priv->num_rx_queues; i++) { 389 priv->rx_queue[i]->rxic = mk_ic_value( 390 cvals->rx_max_coalesced_frames, 391 gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs)); 392 } 393 394 /* Set up tx coalescing */ 395 if ((cvals->tx_coalesce_usecs == 0) || 396 (cvals->tx_max_coalesced_frames == 0)) { 397 for (i = 0; i < priv->num_tx_queues; i++) 398 priv->tx_queue[i]->txcoalescing = 0; 399 } else { 400 for (i = 0; i < priv->num_tx_queues; i++) 401 priv->tx_queue[i]->txcoalescing = 1; 402 } 403 404 /* Check the bounds of the values */ 405 if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) { 406 pr_info("Coalescing is limited to %d microseconds\n", 407 GFAR_MAX_COAL_USECS); 408 return -EINVAL; 409 } 410 411 if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) { 412 pr_info("Coalescing is limited to %d frames\n", 413 GFAR_MAX_COAL_FRAMES); 414 return -EINVAL; 415 } 416 417 for (i = 0; i < priv->num_tx_queues; i++) { 418 priv->tx_queue[i]->txic = mk_ic_value( 419 cvals->tx_max_coalesced_frames, 420 gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs)); 421 } 422 423 gfar_configure_coalescing(priv, 0xFF, 0xFF); 424 425 return 0; 426} 427 428/* Fills in rvals with the current ring parameters. Currently, 429 * rx, rx_mini, and rx_jumbo rings are the same size, as mini and 430 * jumbo are ignored by the driver */ 431static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) 432{ 433 struct gfar_private *priv = netdev_priv(dev); 434 struct gfar_priv_tx_q *tx_queue = NULL; 435 struct gfar_priv_rx_q *rx_queue = NULL; 436 437 tx_queue = priv->tx_queue[0]; 438 rx_queue = priv->rx_queue[0]; 439 440 rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE; 441 rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE; 442 rvals->rx_jumbo_max_pending = GFAR_RX_MAX_RING_SIZE; 443 rvals->tx_max_pending = GFAR_TX_MAX_RING_SIZE; 444 445 /* Values changeable by the user. The valid values are 446 * in the range 1 to the "*_max_pending" counterpart above. 447 */ 448 rvals->rx_pending = rx_queue->rx_ring_size; 449 rvals->rx_mini_pending = rx_queue->rx_ring_size; 450 rvals->rx_jumbo_pending = rx_queue->rx_ring_size; 451 rvals->tx_pending = tx_queue->tx_ring_size; 452} 453 454/* Change the current ring parameters, stopping the controller if 455 * necessary so that we don't mess things up while we're in 456 * motion. We wait for the ring to be clean before reallocating 457 * the rings. */ 458static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) 459{ 460 struct gfar_private *priv = netdev_priv(dev); 461 int err = 0, i = 0; 462 463 if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE) 464 return -EINVAL; 465 466 if (!is_power_of_2(rvals->rx_pending)) { 467 printk("%s: Ring sizes must be a power of 2\n", 468 dev->name); 469 return -EINVAL; 470 } 471 472 if (rvals->tx_pending > GFAR_TX_MAX_RING_SIZE) 473 return -EINVAL; 474 475 if (!is_power_of_2(rvals->tx_pending)) { 476 printk("%s: Ring sizes must be a power of 2\n", 477 dev->name); 478 return -EINVAL; 479 } 480 481 482 if (dev->flags & IFF_UP) { 483 unsigned long flags; 484 485 /* Halt TX and RX, and process the frames which 486 * have already been received */ 487 local_irq_save(flags); 488 lock_tx_qs(priv); 489 lock_rx_qs(priv); 490 491 gfar_halt(dev); 492 493 unlock_rx_qs(priv); 494 unlock_tx_qs(priv); 495 local_irq_restore(flags); 496 497 for (i = 0; i < priv->num_rx_queues; i++) 498 gfar_clean_rx_ring(priv->rx_queue[i], 499 priv->rx_queue[i]->rx_ring_size); 500 501 /* Now we take down the rings to rebuild them */ 502 stop_gfar(dev); 503 } 504 505 /* Change the size */ 506 for (i = 0; i < priv->num_rx_queues; i++) { 507 priv->rx_queue[i]->rx_ring_size = rvals->rx_pending; 508 priv->tx_queue[i]->tx_ring_size = rvals->tx_pending; 509 priv->tx_queue[i]->num_txbdfree = priv->tx_queue[i]->tx_ring_size; 510 } 511 512 /* Rebuild the rings with the new size */ 513 if (dev->flags & IFF_UP) { 514 err = startup_gfar(dev); 515 netif_tx_wake_all_queues(dev); 516 } 517 return err; 518} 519 520static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) 521{ 522 struct gfar_private *priv = netdev_priv(dev); 523 unsigned long flags; 524 int err = 0, i = 0; 525 526 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 527 return -EOPNOTSUPP; 528 529 530 if (dev->flags & IFF_UP) { 531 /* Halt TX and RX, and process the frames which 532 * have already been received */ 533 local_irq_save(flags); 534 lock_tx_qs(priv); 535 lock_rx_qs(priv); 536 537 gfar_halt(dev); 538 539 unlock_tx_qs(priv); 540 unlock_rx_qs(priv); 541 local_irq_save(flags); 542 543 for (i = 0; i < priv->num_rx_queues; i++) 544 gfar_clean_rx_ring(priv->rx_queue[i], 545 priv->rx_queue[i]->rx_ring_size); 546 547 /* Now we take down the rings to rebuild them */ 548 stop_gfar(dev); 549 } 550 551 spin_lock_irqsave(&priv->bflock, flags); 552 priv->rx_csum_enable = data; 553 spin_unlock_irqrestore(&priv->bflock, flags); 554 555 if (dev->flags & IFF_UP) { 556 err = startup_gfar(dev); 557 netif_tx_wake_all_queues(dev); 558 } 559 return err; 560} 561 562static uint32_t gfar_get_rx_csum(struct net_device *dev) 563{ 564 struct gfar_private *priv = netdev_priv(dev); 565 566 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 567 return 0; 568 569 return priv->rx_csum_enable; 570} 571 572static int gfar_set_tx_csum(struct net_device *dev, uint32_t data) 573{ 574 struct gfar_private *priv = netdev_priv(dev); 575 576 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 577 return -EOPNOTSUPP; 578 579 netif_tx_lock_bh(dev); 580 581 if (data) 582 dev->features |= NETIF_F_IP_CSUM; 583 else 584 dev->features &= ~NETIF_F_IP_CSUM; 585 586 netif_tx_unlock_bh(dev); 587 588 return 0; 589} 590 591static uint32_t gfar_get_tx_csum(struct net_device *dev) 592{ 593 struct gfar_private *priv = netdev_priv(dev); 594 595 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 596 return 0; 597 598 return (dev->features & NETIF_F_IP_CSUM) != 0; 599} 600 601static uint32_t gfar_get_msglevel(struct net_device *dev) 602{ 603 struct gfar_private *priv = netdev_priv(dev); 604 return priv->msg_enable; 605} 606 607static void gfar_set_msglevel(struct net_device *dev, uint32_t data) 608{ 609 struct gfar_private *priv = netdev_priv(dev); 610 priv->msg_enable = data; 611} 612 613#ifdef CONFIG_PM 614static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 615{ 616 struct gfar_private *priv = netdev_priv(dev); 617 618 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) { 619 wol->supported = WAKE_MAGIC; 620 wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0; 621 } else { 622 wol->supported = wol->wolopts = 0; 623 } 624} 625 626static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 627{ 628 struct gfar_private *priv = netdev_priv(dev); 629 unsigned long flags; 630 631 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && 632 wol->wolopts != 0) 633 return -EINVAL; 634 635 if (wol->wolopts & ~WAKE_MAGIC) 636 return -EINVAL; 637 638 spin_lock_irqsave(&priv->bflock, flags); 639 priv->wol_en = wol->wolopts & WAKE_MAGIC ? 1 : 0; 640 device_set_wakeup_enable(&dev->dev, priv->wol_en); 641 spin_unlock_irqrestore(&priv->bflock, flags); 642 643 return 0; 644} 645#endif 646 647static int gfar_ethflow_to_class(int flow_type, u64 *class) 648{ 649 switch (flow_type) { 650 case TCP_V4_FLOW: 651 *class = CLASS_CODE_TCP_IPV4; 652 break; 653 case UDP_V4_FLOW: 654 *class = CLASS_CODE_UDP_IPV4; 655 break; 656 case AH_V4_FLOW: 657 case ESP_V4_FLOW: 658 *class = CLASS_CODE_AH_ESP_IPV4; 659 break; 660 case SCTP_V4_FLOW: 661 *class = CLASS_CODE_SCTP_IPV4; 662 break; 663 case TCP_V6_FLOW: 664 *class = CLASS_CODE_TCP_IPV6; 665 break; 666 case UDP_V6_FLOW: 667 *class = CLASS_CODE_UDP_IPV6; 668 break; 669 case AH_V6_FLOW: 670 case ESP_V6_FLOW: 671 *class = CLASS_CODE_AH_ESP_IPV6; 672 break; 673 case SCTP_V6_FLOW: 674 *class = CLASS_CODE_SCTP_IPV6; 675 break; 676 default: 677 return 0; 678 } 679 680 return 1; 681} 682 683static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) 684{ 685 u32 fcr = 0x0, fpr = FPR_FILER_MASK; 686 687 if (ethflow & RXH_L2DA) { 688 fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH | 689 RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; 690 ftp_rqfpr[priv->cur_filer_idx] = fpr; 691 ftp_rqfcr[priv->cur_filer_idx] = fcr; 692 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 693 priv->cur_filer_idx = priv->cur_filer_idx - 1; 694 695 fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH | 696 RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; 697 ftp_rqfpr[priv->cur_filer_idx] = fpr; 698 ftp_rqfcr[priv->cur_filer_idx] = fcr; 699 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 700 priv->cur_filer_idx = priv->cur_filer_idx - 1; 701 } 702 703 if (ethflow & RXH_VLAN) { 704 fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH | 705 RQFCR_AND | RQFCR_HASHTBL_0; 706 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 707 ftp_rqfpr[priv->cur_filer_idx] = fpr; 708 ftp_rqfcr[priv->cur_filer_idx] = fcr; 709 priv->cur_filer_idx = priv->cur_filer_idx - 1; 710 } 711 712 if (ethflow & RXH_IP_SRC) { 713 fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | 714 RQFCR_AND | RQFCR_HASHTBL_0; 715 ftp_rqfpr[priv->cur_filer_idx] = fpr; 716 ftp_rqfcr[priv->cur_filer_idx] = fcr; 717 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 718 priv->cur_filer_idx = priv->cur_filer_idx - 1; 719 } 720 721 if (ethflow & (RXH_IP_DST)) { 722 fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | 723 RQFCR_AND | RQFCR_HASHTBL_0; 724 ftp_rqfpr[priv->cur_filer_idx] = fpr; 725 ftp_rqfcr[priv->cur_filer_idx] = fcr; 726 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 727 priv->cur_filer_idx = priv->cur_filer_idx - 1; 728 } 729 730 if (ethflow & RXH_L3_PROTO) { 731 fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH | 732 RQFCR_AND | RQFCR_HASHTBL_0; 733 ftp_rqfpr[priv->cur_filer_idx] = fpr; 734 ftp_rqfcr[priv->cur_filer_idx] = fcr; 735 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 736 priv->cur_filer_idx = priv->cur_filer_idx - 1; 737 } 738 739 if (ethflow & RXH_L4_B_0_1) { 740 fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | 741 RQFCR_AND | RQFCR_HASHTBL_0; 742 ftp_rqfpr[priv->cur_filer_idx] = fpr; 743 ftp_rqfcr[priv->cur_filer_idx] = fcr; 744 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 745 priv->cur_filer_idx = priv->cur_filer_idx - 1; 746 } 747 748 if (ethflow & RXH_L4_B_2_3) { 749 fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | 750 RQFCR_AND | RQFCR_HASHTBL_0; 751 ftp_rqfpr[priv->cur_filer_idx] = fpr; 752 ftp_rqfcr[priv->cur_filer_idx] = fcr; 753 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 754 priv->cur_filer_idx = priv->cur_filer_idx - 1; 755 } 756} 757 758static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class) 759{ 760 unsigned int last_rule_idx = priv->cur_filer_idx; 761 unsigned int cmp_rqfpr; 762 unsigned int local_rqfpr[MAX_FILER_IDX + 1]; 763 unsigned int local_rqfcr[MAX_FILER_IDX + 1]; 764 int i = 0x0, k = 0x0; 765 int j = MAX_FILER_IDX, l = 0x0; 766 767 switch (class) { 768 case TCP_V4_FLOW: 769 cmp_rqfpr = RQFPR_IPV4 |RQFPR_TCP; 770 break; 771 case UDP_V4_FLOW: 772 cmp_rqfpr = RQFPR_IPV4 |RQFPR_UDP; 773 break; 774 case TCP_V6_FLOW: 775 cmp_rqfpr = RQFPR_IPV6 |RQFPR_TCP; 776 break; 777 case UDP_V6_FLOW: 778 cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP; 779 break; 780 case IPV4_FLOW: 781 cmp_rqfpr = RQFPR_IPV4; 782 case IPV6_FLOW: 783 cmp_rqfpr = RQFPR_IPV6; 784 break; 785 default: 786 printk(KERN_ERR "Right now this class is not supported\n"); 787 return 0; 788 } 789 790 for (i = 0; i < MAX_FILER_IDX + 1; i++) { 791 local_rqfpr[j] = ftp_rqfpr[i]; 792 local_rqfcr[j] = ftp_rqfcr[i]; 793 j--; 794 if ((ftp_rqfcr[i] == (RQFCR_PID_PARSE | 795 RQFCR_CLE |RQFCR_AND)) && 796 (ftp_rqfpr[i] == cmp_rqfpr)) 797 break; 798 } 799 800 if (i == MAX_FILER_IDX + 1) { 801 printk(KERN_ERR "No parse rule found, "); 802 printk(KERN_ERR "can't create hash rules\n"); 803 return 0; 804 } 805 806 /* If a match was found, then it begins the starting of a cluster rule 807 * if it was already programmed, we need to overwrite these rules 808 */ 809 for (l = i+1; l < MAX_FILER_IDX; l++) { 810 if ((ftp_rqfcr[l] & RQFCR_CLE) && 811 !(ftp_rqfcr[l] & RQFCR_AND)) { 812 ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT | 813 RQFCR_HASHTBL_0 | RQFCR_PID_MASK; 814 ftp_rqfpr[l] = FPR_FILER_MASK; 815 gfar_write_filer(priv, l, ftp_rqfcr[l], ftp_rqfpr[l]); 816 break; 817 } 818 819 if (!(ftp_rqfcr[l] & RQFCR_CLE) && (ftp_rqfcr[l] & RQFCR_AND)) 820 continue; 821 else { 822 local_rqfpr[j] = ftp_rqfpr[l]; 823 local_rqfcr[j] = ftp_rqfcr[l]; 824 j--; 825 } 826 } 827 828 priv->cur_filer_idx = l - 1; 829 last_rule_idx = l; 830 831 /* hash rules */ 832 ethflow_to_filer_rules(priv, ethflow); 833 834 /* Write back the popped out rules again */ 835 for (k = j+1; k < MAX_FILER_IDX; k++) { 836 ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k]; 837 ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k]; 838 gfar_write_filer(priv, priv->cur_filer_idx, 839 local_rqfcr[k], local_rqfpr[k]); 840 if (!priv->cur_filer_idx) 841 break; 842 priv->cur_filer_idx = priv->cur_filer_idx - 1; 843 } 844 845 return 1; 846} 847 848static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd) 849{ 850 u64 class; 851 852 if (!gfar_ethflow_to_class(cmd->flow_type, &class)) 853 return -EINVAL; 854 855 if (class < CLASS_CODE_USER_PROG1 || 856 class > CLASS_CODE_SCTP_IPV6) 857 return -EINVAL; 858 859 /* write the filer rules here */ 860 if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type)) 861 return -1; 862 863 return 0; 864} 865 866static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) 867{ 868 struct gfar_private *priv = netdev_priv(dev); 869 int ret = 0; 870 871 switch(cmd->cmd) { 872 case ETHTOOL_SRXFH: 873 ret = gfar_set_hash_opts(priv, cmd); 874 break; 875 default: 876 ret = -EINVAL; 877 } 878 879 return ret; 880} 881 882const struct ethtool_ops gfar_ethtool_ops = { 883 .get_settings = gfar_gsettings, 884 .set_settings = gfar_ssettings, 885 .get_drvinfo = gfar_gdrvinfo, 886 .get_regs_len = gfar_reglen, 887 .get_regs = gfar_get_regs, 888 .get_link = ethtool_op_get_link, 889 .get_coalesce = gfar_gcoalesce, 890 .set_coalesce = gfar_scoalesce, 891 .get_ringparam = gfar_gringparam, 892 .set_ringparam = gfar_sringparam, 893 .get_strings = gfar_gstrings, 894 .get_sset_count = gfar_sset_count, 895 .get_ethtool_stats = gfar_fill_stats, 896 .get_rx_csum = gfar_get_rx_csum, 897 .get_tx_csum = gfar_get_tx_csum, 898 .set_rx_csum = gfar_set_rx_csum, 899 .set_tx_csum = gfar_set_tx_csum, 900 .set_sg = ethtool_op_set_sg, 901 .get_msglevel = gfar_get_msglevel, 902 .set_msglevel = gfar_set_msglevel, 903#ifdef CONFIG_PM 904 .get_wol = gfar_get_wol, 905 .set_wol = gfar_set_wol, 906#endif 907 .set_rxnfc = gfar_set_nfc, 908}; 909