Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.39-rc4 909 lines 24 kB view raw
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 *) &regs->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_restore(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 device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC); 639 640 spin_lock_irqsave(&priv->bflock, flags); 641 priv->wol_en = !!device_may_wakeup(&dev->dev); 642 spin_unlock_irqrestore(&priv->bflock, flags); 643 644 return 0; 645} 646#endif 647 648static int gfar_ethflow_to_class(int flow_type, u64 *class) 649{ 650 switch (flow_type) { 651 case TCP_V4_FLOW: 652 *class = CLASS_CODE_TCP_IPV4; 653 break; 654 case UDP_V4_FLOW: 655 *class = CLASS_CODE_UDP_IPV4; 656 break; 657 case AH_V4_FLOW: 658 case ESP_V4_FLOW: 659 *class = CLASS_CODE_AH_ESP_IPV4; 660 break; 661 case SCTP_V4_FLOW: 662 *class = CLASS_CODE_SCTP_IPV4; 663 break; 664 case TCP_V6_FLOW: 665 *class = CLASS_CODE_TCP_IPV6; 666 break; 667 case UDP_V6_FLOW: 668 *class = CLASS_CODE_UDP_IPV6; 669 break; 670 case AH_V6_FLOW: 671 case ESP_V6_FLOW: 672 *class = CLASS_CODE_AH_ESP_IPV6; 673 break; 674 case SCTP_V6_FLOW: 675 *class = CLASS_CODE_SCTP_IPV6; 676 break; 677 default: 678 return 0; 679 } 680 681 return 1; 682} 683 684static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) 685{ 686 u32 fcr = 0x0, fpr = FPR_FILER_MASK; 687 688 if (ethflow & RXH_L2DA) { 689 fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH | 690 RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; 691 ftp_rqfpr[priv->cur_filer_idx] = fpr; 692 ftp_rqfcr[priv->cur_filer_idx] = fcr; 693 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 694 priv->cur_filer_idx = priv->cur_filer_idx - 1; 695 696 fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH | 697 RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; 698 ftp_rqfpr[priv->cur_filer_idx] = fpr; 699 ftp_rqfcr[priv->cur_filer_idx] = fcr; 700 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 701 priv->cur_filer_idx = priv->cur_filer_idx - 1; 702 } 703 704 if (ethflow & RXH_VLAN) { 705 fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH | 706 RQFCR_AND | RQFCR_HASHTBL_0; 707 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 708 ftp_rqfpr[priv->cur_filer_idx] = fpr; 709 ftp_rqfcr[priv->cur_filer_idx] = fcr; 710 priv->cur_filer_idx = priv->cur_filer_idx - 1; 711 } 712 713 if (ethflow & RXH_IP_SRC) { 714 fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | 715 RQFCR_AND | RQFCR_HASHTBL_0; 716 ftp_rqfpr[priv->cur_filer_idx] = fpr; 717 ftp_rqfcr[priv->cur_filer_idx] = fcr; 718 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 719 priv->cur_filer_idx = priv->cur_filer_idx - 1; 720 } 721 722 if (ethflow & (RXH_IP_DST)) { 723 fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | 724 RQFCR_AND | RQFCR_HASHTBL_0; 725 ftp_rqfpr[priv->cur_filer_idx] = fpr; 726 ftp_rqfcr[priv->cur_filer_idx] = fcr; 727 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 728 priv->cur_filer_idx = priv->cur_filer_idx - 1; 729 } 730 731 if (ethflow & RXH_L3_PROTO) { 732 fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH | 733 RQFCR_AND | RQFCR_HASHTBL_0; 734 ftp_rqfpr[priv->cur_filer_idx] = fpr; 735 ftp_rqfcr[priv->cur_filer_idx] = fcr; 736 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 737 priv->cur_filer_idx = priv->cur_filer_idx - 1; 738 } 739 740 if (ethflow & RXH_L4_B_0_1) { 741 fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | 742 RQFCR_AND | RQFCR_HASHTBL_0; 743 ftp_rqfpr[priv->cur_filer_idx] = fpr; 744 ftp_rqfcr[priv->cur_filer_idx] = fcr; 745 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 746 priv->cur_filer_idx = priv->cur_filer_idx - 1; 747 } 748 749 if (ethflow & RXH_L4_B_2_3) { 750 fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | 751 RQFCR_AND | RQFCR_HASHTBL_0; 752 ftp_rqfpr[priv->cur_filer_idx] = fpr; 753 ftp_rqfcr[priv->cur_filer_idx] = fcr; 754 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 755 priv->cur_filer_idx = priv->cur_filer_idx - 1; 756 } 757} 758 759static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class) 760{ 761 unsigned int last_rule_idx = priv->cur_filer_idx; 762 unsigned int cmp_rqfpr; 763 unsigned int local_rqfpr[MAX_FILER_IDX + 1]; 764 unsigned int local_rqfcr[MAX_FILER_IDX + 1]; 765 int i = 0x0, k = 0x0; 766 int j = MAX_FILER_IDX, l = 0x0; 767 768 switch (class) { 769 case TCP_V4_FLOW: 770 cmp_rqfpr = RQFPR_IPV4 |RQFPR_TCP; 771 break; 772 case UDP_V4_FLOW: 773 cmp_rqfpr = RQFPR_IPV4 |RQFPR_UDP; 774 break; 775 case TCP_V6_FLOW: 776 cmp_rqfpr = RQFPR_IPV6 |RQFPR_TCP; 777 break; 778 case UDP_V6_FLOW: 779 cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP; 780 break; 781 case IPV4_FLOW: 782 cmp_rqfpr = RQFPR_IPV4; 783 case IPV6_FLOW: 784 cmp_rqfpr = RQFPR_IPV6; 785 break; 786 default: 787 printk(KERN_ERR "Right now this class is not supported\n"); 788 return 0; 789 } 790 791 for (i = 0; i < MAX_FILER_IDX + 1; i++) { 792 local_rqfpr[j] = ftp_rqfpr[i]; 793 local_rqfcr[j] = ftp_rqfcr[i]; 794 j--; 795 if ((ftp_rqfcr[i] == (RQFCR_PID_PARSE | 796 RQFCR_CLE |RQFCR_AND)) && 797 (ftp_rqfpr[i] == cmp_rqfpr)) 798 break; 799 } 800 801 if (i == MAX_FILER_IDX + 1) { 802 printk(KERN_ERR "No parse rule found, "); 803 printk(KERN_ERR "can't create hash rules\n"); 804 return 0; 805 } 806 807 /* If a match was found, then it begins the starting of a cluster rule 808 * if it was already programmed, we need to overwrite these rules 809 */ 810 for (l = i+1; l < MAX_FILER_IDX; l++) { 811 if ((ftp_rqfcr[l] & RQFCR_CLE) && 812 !(ftp_rqfcr[l] & RQFCR_AND)) { 813 ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT | 814 RQFCR_HASHTBL_0 | RQFCR_PID_MASK; 815 ftp_rqfpr[l] = FPR_FILER_MASK; 816 gfar_write_filer(priv, l, ftp_rqfcr[l], ftp_rqfpr[l]); 817 break; 818 } 819 820 if (!(ftp_rqfcr[l] & RQFCR_CLE) && (ftp_rqfcr[l] & RQFCR_AND)) 821 continue; 822 else { 823 local_rqfpr[j] = ftp_rqfpr[l]; 824 local_rqfcr[j] = ftp_rqfcr[l]; 825 j--; 826 } 827 } 828 829 priv->cur_filer_idx = l - 1; 830 last_rule_idx = l; 831 832 /* hash rules */ 833 ethflow_to_filer_rules(priv, ethflow); 834 835 /* Write back the popped out rules again */ 836 for (k = j+1; k < MAX_FILER_IDX; k++) { 837 ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k]; 838 ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k]; 839 gfar_write_filer(priv, priv->cur_filer_idx, 840 local_rqfcr[k], local_rqfpr[k]); 841 if (!priv->cur_filer_idx) 842 break; 843 priv->cur_filer_idx = priv->cur_filer_idx - 1; 844 } 845 846 return 1; 847} 848 849static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd) 850{ 851 u64 class; 852 853 if (!gfar_ethflow_to_class(cmd->flow_type, &class)) 854 return -EINVAL; 855 856 if (class < CLASS_CODE_USER_PROG1 || 857 class > CLASS_CODE_SCTP_IPV6) 858 return -EINVAL; 859 860 /* write the filer rules here */ 861 if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type)) 862 return -1; 863 864 return 0; 865} 866 867static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) 868{ 869 struct gfar_private *priv = netdev_priv(dev); 870 int ret = 0; 871 872 switch(cmd->cmd) { 873 case ETHTOOL_SRXFH: 874 ret = gfar_set_hash_opts(priv, cmd); 875 break; 876 default: 877 ret = -EINVAL; 878 } 879 880 return ret; 881} 882 883const struct ethtool_ops gfar_ethtool_ops = { 884 .get_settings = gfar_gsettings, 885 .set_settings = gfar_ssettings, 886 .get_drvinfo = gfar_gdrvinfo, 887 .get_regs_len = gfar_reglen, 888 .get_regs = gfar_get_regs, 889 .get_link = ethtool_op_get_link, 890 .get_coalesce = gfar_gcoalesce, 891 .set_coalesce = gfar_scoalesce, 892 .get_ringparam = gfar_gringparam, 893 .set_ringparam = gfar_sringparam, 894 .get_strings = gfar_gstrings, 895 .get_sset_count = gfar_sset_count, 896 .get_ethtool_stats = gfar_fill_stats, 897 .get_rx_csum = gfar_get_rx_csum, 898 .get_tx_csum = gfar_get_tx_csum, 899 .set_rx_csum = gfar_set_rx_csum, 900 .set_tx_csum = gfar_set_tx_csum, 901 .set_sg = ethtool_op_set_sg, 902 .get_msglevel = gfar_get_msglevel, 903 .set_msglevel = gfar_set_msglevel, 904#ifdef CONFIG_PM 905 .get_wol = gfar_get_wol, 906 .set_wol = gfar_set_wol, 907#endif 908 .set_rxnfc = gfar_set_nfc, 909};