Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.0-rc4 813 lines 23 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, 2011 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 520int gfar_set_features(struct net_device *dev, u32 features) 521{ 522 struct gfar_private *priv = netdev_priv(dev); 523 unsigned long flags; 524 int err = 0, i = 0; 525 u32 changed = dev->features ^ features; 526 527 if (!(changed & NETIF_F_RXCSUM)) 528 return 0; 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 dev->features = features; 551 552 err = startup_gfar(dev); 553 netif_tx_wake_all_queues(dev); 554 } 555 return err; 556} 557 558static uint32_t gfar_get_msglevel(struct net_device *dev) 559{ 560 struct gfar_private *priv = netdev_priv(dev); 561 return priv->msg_enable; 562} 563 564static void gfar_set_msglevel(struct net_device *dev, uint32_t data) 565{ 566 struct gfar_private *priv = netdev_priv(dev); 567 priv->msg_enable = data; 568} 569 570#ifdef CONFIG_PM 571static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 572{ 573 struct gfar_private *priv = netdev_priv(dev); 574 575 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) { 576 wol->supported = WAKE_MAGIC; 577 wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0; 578 } else { 579 wol->supported = wol->wolopts = 0; 580 } 581} 582 583static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 584{ 585 struct gfar_private *priv = netdev_priv(dev); 586 unsigned long flags; 587 588 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) && 589 wol->wolopts != 0) 590 return -EINVAL; 591 592 if (wol->wolopts & ~WAKE_MAGIC) 593 return -EINVAL; 594 595 device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC); 596 597 spin_lock_irqsave(&priv->bflock, flags); 598 priv->wol_en = !!device_may_wakeup(&dev->dev); 599 spin_unlock_irqrestore(&priv->bflock, flags); 600 601 return 0; 602} 603#endif 604 605static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow) 606{ 607 u32 fcr = 0x0, fpr = FPR_FILER_MASK; 608 609 if (ethflow & RXH_L2DA) { 610 fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH | 611 RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; 612 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 613 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 614 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 615 priv->cur_filer_idx = priv->cur_filer_idx - 1; 616 617 fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH | 618 RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0; 619 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 620 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 621 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 622 priv->cur_filer_idx = priv->cur_filer_idx - 1; 623 } 624 625 if (ethflow & RXH_VLAN) { 626 fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH | 627 RQFCR_AND | RQFCR_HASHTBL_0; 628 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 629 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 630 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 631 priv->cur_filer_idx = priv->cur_filer_idx - 1; 632 } 633 634 if (ethflow & RXH_IP_SRC) { 635 fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | 636 RQFCR_AND | RQFCR_HASHTBL_0; 637 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 638 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 639 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 640 priv->cur_filer_idx = priv->cur_filer_idx - 1; 641 } 642 643 if (ethflow & (RXH_IP_DST)) { 644 fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH | 645 RQFCR_AND | RQFCR_HASHTBL_0; 646 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 647 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 648 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 649 priv->cur_filer_idx = priv->cur_filer_idx - 1; 650 } 651 652 if (ethflow & RXH_L3_PROTO) { 653 fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH | 654 RQFCR_AND | RQFCR_HASHTBL_0; 655 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 656 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 657 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 658 priv->cur_filer_idx = priv->cur_filer_idx - 1; 659 } 660 661 if (ethflow & RXH_L4_B_0_1) { 662 fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | 663 RQFCR_AND | RQFCR_HASHTBL_0; 664 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 665 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 666 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 667 priv->cur_filer_idx = priv->cur_filer_idx - 1; 668 } 669 670 if (ethflow & RXH_L4_B_2_3) { 671 fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH | 672 RQFCR_AND | RQFCR_HASHTBL_0; 673 priv->ftp_rqfpr[priv->cur_filer_idx] = fpr; 674 priv->ftp_rqfcr[priv->cur_filer_idx] = fcr; 675 gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr); 676 priv->cur_filer_idx = priv->cur_filer_idx - 1; 677 } 678} 679 680static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class) 681{ 682 unsigned int last_rule_idx = priv->cur_filer_idx; 683 unsigned int cmp_rqfpr; 684 unsigned int local_rqfpr[MAX_FILER_IDX + 1]; 685 unsigned int local_rqfcr[MAX_FILER_IDX + 1]; 686 int i = 0x0, k = 0x0; 687 int j = MAX_FILER_IDX, l = 0x0; 688 689 switch (class) { 690 case TCP_V4_FLOW: 691 cmp_rqfpr = RQFPR_IPV4 |RQFPR_TCP; 692 break; 693 case UDP_V4_FLOW: 694 cmp_rqfpr = RQFPR_IPV4 |RQFPR_UDP; 695 break; 696 case TCP_V6_FLOW: 697 cmp_rqfpr = RQFPR_IPV6 |RQFPR_TCP; 698 break; 699 case UDP_V6_FLOW: 700 cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP; 701 break; 702 default: 703 printk(KERN_ERR "Right now this class is not supported\n"); 704 return 0; 705 } 706 707 for (i = 0; i < MAX_FILER_IDX + 1; i++) { 708 local_rqfpr[j] = priv->ftp_rqfpr[i]; 709 local_rqfcr[j] = priv->ftp_rqfcr[i]; 710 j--; 711 if ((priv->ftp_rqfcr[i] == (RQFCR_PID_PARSE | 712 RQFCR_CLE |RQFCR_AND)) && 713 (priv->ftp_rqfpr[i] == cmp_rqfpr)) 714 break; 715 } 716 717 if (i == MAX_FILER_IDX + 1) { 718 printk(KERN_ERR "No parse rule found, "); 719 printk(KERN_ERR "can't create hash rules\n"); 720 return 0; 721 } 722 723 /* If a match was found, then it begins the starting of a cluster rule 724 * if it was already programmed, we need to overwrite these rules 725 */ 726 for (l = i+1; l < MAX_FILER_IDX; l++) { 727 if ((priv->ftp_rqfcr[l] & RQFCR_CLE) && 728 !(priv->ftp_rqfcr[l] & RQFCR_AND)) { 729 priv->ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT | 730 RQFCR_HASHTBL_0 | RQFCR_PID_MASK; 731 priv->ftp_rqfpr[l] = FPR_FILER_MASK; 732 gfar_write_filer(priv, l, priv->ftp_rqfcr[l], 733 priv->ftp_rqfpr[l]); 734 break; 735 } 736 737 if (!(priv->ftp_rqfcr[l] & RQFCR_CLE) && 738 (priv->ftp_rqfcr[l] & RQFCR_AND)) 739 continue; 740 else { 741 local_rqfpr[j] = priv->ftp_rqfpr[l]; 742 local_rqfcr[j] = priv->ftp_rqfcr[l]; 743 j--; 744 } 745 } 746 747 priv->cur_filer_idx = l - 1; 748 last_rule_idx = l; 749 750 /* hash rules */ 751 ethflow_to_filer_rules(priv, ethflow); 752 753 /* Write back the popped out rules again */ 754 for (k = j+1; k < MAX_FILER_IDX; k++) { 755 priv->ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k]; 756 priv->ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k]; 757 gfar_write_filer(priv, priv->cur_filer_idx, 758 local_rqfcr[k], local_rqfpr[k]); 759 if (!priv->cur_filer_idx) 760 break; 761 priv->cur_filer_idx = priv->cur_filer_idx - 1; 762 } 763 764 return 1; 765} 766 767static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd) 768{ 769 /* write the filer rules here */ 770 if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type)) 771 return -EINVAL; 772 773 return 0; 774} 775 776static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd) 777{ 778 struct gfar_private *priv = netdev_priv(dev); 779 int ret = 0; 780 781 switch(cmd->cmd) { 782 case ETHTOOL_SRXFH: 783 ret = gfar_set_hash_opts(priv, cmd); 784 break; 785 default: 786 ret = -EINVAL; 787 } 788 789 return ret; 790} 791 792const struct ethtool_ops gfar_ethtool_ops = { 793 .get_settings = gfar_gsettings, 794 .set_settings = gfar_ssettings, 795 .get_drvinfo = gfar_gdrvinfo, 796 .get_regs_len = gfar_reglen, 797 .get_regs = gfar_get_regs, 798 .get_link = ethtool_op_get_link, 799 .get_coalesce = gfar_gcoalesce, 800 .set_coalesce = gfar_scoalesce, 801 .get_ringparam = gfar_gringparam, 802 .set_ringparam = gfar_sringparam, 803 .get_strings = gfar_gstrings, 804 .get_sset_count = gfar_sset_count, 805 .get_ethtool_stats = gfar_fill_stats, 806 .get_msglevel = gfar_get_msglevel, 807 .set_msglevel = gfar_set_msglevel, 808#ifdef CONFIG_PM 809 .get_wol = gfar_get_wol, 810 .set_wol = gfar_set_wol, 811#endif 812 .set_rxnfc = gfar_set_nfc, 813};