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 v2.6.18-rc1 590 lines 16 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 * 11 * Copyright (c) 2003,2004 Freescale Semiconductor, Inc. 12 * 13 * This software may be used and distributed according to 14 * the terms of the GNU Public License, Version 2, incorporated herein 15 * by reference. 16 */ 17 18#include <linux/kernel.h> 19#include <linux/sched.h> 20#include <linux/string.h> 21#include <linux/errno.h> 22#include <linux/slab.h> 23#include <linux/interrupt.h> 24#include <linux/init.h> 25#include <linux/delay.h> 26#include <linux/netdevice.h> 27#include <linux/etherdevice.h> 28#include <linux/skbuff.h> 29#include <linux/spinlock.h> 30#include <linux/mm.h> 31 32#include <asm/io.h> 33#include <asm/irq.h> 34#include <asm/uaccess.h> 35#include <linux/module.h> 36#include <linux/crc32.h> 37#include <asm/types.h> 38#include <asm/uaccess.h> 39#include <linux/ethtool.h> 40#include <linux/mii.h> 41#include <linux/phy.h> 42 43#include "gianfar.h" 44 45#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) 46 47extern void gfar_start(struct net_device *dev); 48extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); 49 50#define GFAR_MAX_COAL_USECS 0xffff 51#define GFAR_MAX_COAL_FRAMES 0xff 52static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, 53 u64 * buf); 54static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf); 55static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); 56static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals); 57static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals); 58static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals); 59static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); 60 61static char stat_gstrings[][ETH_GSTRING_LEN] = { 62 "rx-dropped-by-kernel", 63 "rx-large-frame-errors", 64 "rx-short-frame-errors", 65 "rx-non-octet-errors", 66 "rx-crc-errors", 67 "rx-overrun-errors", 68 "rx-busy-errors", 69 "rx-babbling-errors", 70 "rx-truncated-frames", 71 "ethernet-bus-error", 72 "tx-babbling-errors", 73 "tx-underrun-errors", 74 "rx-skb-missing-errors", 75 "tx-timeout-errors", 76 "tx-rx-64-frames", 77 "tx-rx-65-127-frames", 78 "tx-rx-128-255-frames", 79 "tx-rx-256-511-frames", 80 "tx-rx-512-1023-frames", 81 "tx-rx-1024-1518-frames", 82 "tx-rx-1519-1522-good-vlan", 83 "rx-bytes", 84 "rx-packets", 85 "rx-fcs-errors", 86 "receive-multicast-packet", 87 "receive-broadcast-packet", 88 "rx-control-frame-packets", 89 "rx-pause-frame-packets", 90 "rx-unknown-op-code", 91 "rx-alignment-error", 92 "rx-frame-length-error", 93 "rx-code-error", 94 "rx-carrier-sense-error", 95 "rx-undersize-packets", 96 "rx-oversize-packets", 97 "rx-fragmented-frames", 98 "rx-jabber-frames", 99 "rx-dropped-frames", 100 "tx-byte-counter", 101 "tx-packets", 102 "tx-multicast-packets", 103 "tx-broadcast-packets", 104 "tx-pause-control-frames", 105 "tx-deferral-packets", 106 "tx-excessive-deferral-packets", 107 "tx-single-collision-packets", 108 "tx-multiple-collision-packets", 109 "tx-late-collision-packets", 110 "tx-excessive-collision-packets", 111 "tx-total-collision", 112 "reserved", 113 "tx-dropped-frames", 114 "tx-jabber-frames", 115 "tx-fcs-errors", 116 "tx-control-frames", 117 "tx-oversize-frames", 118 "tx-undersize-frames", 119 "tx-fragmented-frames", 120}; 121 122/* Fill in a buffer with the strings which correspond to the 123 * stats */ 124static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) 125{ 126 struct gfar_private *priv = netdev_priv(dev); 127 128 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) 129 memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN); 130 else 131 memcpy(buf, stat_gstrings, 132 GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN); 133} 134 135/* Fill in an array of 64-bit statistics from various sources. 136 * This array will be appended to the end of the ethtool_stats 137 * structure, and returned to user space 138 */ 139static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf) 140{ 141 int i; 142 struct gfar_private *priv = netdev_priv(dev); 143 u64 *extra = (u64 *) & priv->extra_stats; 144 145 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { 146 u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon; 147 struct gfar_stats *stats = (struct gfar_stats *) buf; 148 149 for (i = 0; i < GFAR_RMON_LEN; i++) 150 stats->rmon[i] = (u64) gfar_read(&rmon[i]); 151 152 for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) 153 stats->extra[i] = extra[i]; 154 } else 155 for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) 156 buf[i] = extra[i]; 157} 158 159/* Returns the number of stats (and their corresponding strings) */ 160static int gfar_stats_count(struct net_device *dev) 161{ 162 struct gfar_private *priv = netdev_priv(dev); 163 164 if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) 165 return GFAR_STATS_LEN; 166 else 167 return GFAR_EXTRA_STATS_LEN; 168} 169 170/* Fills in the drvinfo structure with some basic info */ 171static void gfar_gdrvinfo(struct net_device *dev, struct 172 ethtool_drvinfo *drvinfo) 173{ 174 strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); 175 strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN); 176 strncpy(drvinfo->fw_version, "N/A", GFAR_INFOSTR_LEN); 177 strncpy(drvinfo->bus_info, "N/A", GFAR_INFOSTR_LEN); 178 drvinfo->n_stats = GFAR_STATS_LEN; 179 drvinfo->testinfo_len = 0; 180 drvinfo->regdump_len = 0; 181 drvinfo->eedump_len = 0; 182} 183 184 185static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd) 186{ 187 struct gfar_private *priv = netdev_priv(dev); 188 struct phy_device *phydev = priv->phydev; 189 190 if (NULL == phydev) 191 return -ENODEV; 192 193 return phy_ethtool_sset(phydev, cmd); 194} 195 196 197/* Return the current settings in the ethtool_cmd structure */ 198static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) 199{ 200 struct gfar_private *priv = netdev_priv(dev); 201 struct phy_device *phydev = priv->phydev; 202 203 if (NULL == phydev) 204 return -ENODEV; 205 206 cmd->maxtxpkt = priv->txcount; 207 cmd->maxrxpkt = priv->rxcount; 208 209 return phy_ethtool_gset(phydev, cmd); 210} 211 212/* Return the length of the register structure */ 213static int gfar_reglen(struct net_device *dev) 214{ 215 return sizeof (struct gfar); 216} 217 218/* Return a dump of the GFAR register space */ 219static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) 220{ 221 int i; 222 struct gfar_private *priv = netdev_priv(dev); 223 u32 __iomem *theregs = (u32 __iomem *) priv->regs; 224 u32 *buf = (u32 *) regbuf; 225 226 for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++) 227 buf[i] = gfar_read(&theregs[i]); 228} 229 230/* Convert microseconds to ethernet clock ticks, which changes 231 * depending on what speed the controller is running at */ 232static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs) 233{ 234 unsigned int count; 235 236 /* The timer is different, depending on the interface speed */ 237 switch (priv->phydev->speed) { 238 case SPEED_1000: 239 count = GFAR_GBIT_TIME; 240 break; 241 case SPEED_100: 242 count = GFAR_100_TIME; 243 break; 244 case SPEED_10: 245 default: 246 count = GFAR_10_TIME; 247 break; 248 } 249 250 /* Make sure we return a number greater than 0 251 * if usecs > 0 */ 252 return ((usecs * 1000 + count - 1) / count); 253} 254 255/* Convert ethernet clock ticks to microseconds */ 256static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int ticks) 257{ 258 unsigned int count; 259 260 /* The timer is different, depending on the interface speed */ 261 switch (priv->phydev->speed) { 262 case SPEED_1000: 263 count = GFAR_GBIT_TIME; 264 break; 265 case SPEED_100: 266 count = GFAR_100_TIME; 267 break; 268 case SPEED_10: 269 default: 270 count = GFAR_10_TIME; 271 break; 272 } 273 274 /* Make sure we return a number greater than 0 */ 275 /* if ticks is > 0 */ 276 return ((ticks * count) / 1000); 277} 278 279/* Get the coalescing parameters, and put them in the cvals 280 * structure. */ 281static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) 282{ 283 struct gfar_private *priv = netdev_priv(dev); 284 285 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) 286 return -EOPNOTSUPP; 287 288 if (NULL == priv->phydev) 289 return -ENODEV; 290 291 cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime); 292 cvals->rx_max_coalesced_frames = priv->rxcount; 293 294 cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, priv->txtime); 295 cvals->tx_max_coalesced_frames = priv->txcount; 296 297 cvals->use_adaptive_rx_coalesce = 0; 298 cvals->use_adaptive_tx_coalesce = 0; 299 300 cvals->pkt_rate_low = 0; 301 cvals->rx_coalesce_usecs_low = 0; 302 cvals->rx_max_coalesced_frames_low = 0; 303 cvals->tx_coalesce_usecs_low = 0; 304 cvals->tx_max_coalesced_frames_low = 0; 305 306 /* When the packet rate is below pkt_rate_high but above 307 * pkt_rate_low (both measured in packets per second) the 308 * normal {rx,tx}_* coalescing parameters are used. 309 */ 310 311 /* When the packet rate is (measured in packets per second) 312 * is above pkt_rate_high, the {rx,tx}_*_high parameters are 313 * used. 314 */ 315 cvals->pkt_rate_high = 0; 316 cvals->rx_coalesce_usecs_high = 0; 317 cvals->rx_max_coalesced_frames_high = 0; 318 cvals->tx_coalesce_usecs_high = 0; 319 cvals->tx_max_coalesced_frames_high = 0; 320 321 /* How often to do adaptive coalescing packet rate sampling, 322 * measured in seconds. Must not be zero. 323 */ 324 cvals->rate_sample_interval = 0; 325 326 return 0; 327} 328 329/* Change the coalescing values. 330 * Both cvals->*_usecs and cvals->*_frames have to be > 0 331 * in order for coalescing to be active 332 */ 333static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) 334{ 335 struct gfar_private *priv = netdev_priv(dev); 336 337 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) 338 return -EOPNOTSUPP; 339 340 /* Set up rx coalescing */ 341 if ((cvals->rx_coalesce_usecs == 0) || 342 (cvals->rx_max_coalesced_frames == 0)) 343 priv->rxcoalescing = 0; 344 else 345 priv->rxcoalescing = 1; 346 347 if (NULL == priv->phydev) 348 return -ENODEV; 349 350 /* Check the bounds of the values */ 351 if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) { 352 pr_info("Coalescing is limited to %d microseconds\n", 353 GFAR_MAX_COAL_USECS); 354 return -EINVAL; 355 } 356 357 if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) { 358 pr_info("Coalescing is limited to %d frames\n", 359 GFAR_MAX_COAL_FRAMES); 360 return -EINVAL; 361 } 362 363 priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs); 364 priv->rxcount = cvals->rx_max_coalesced_frames; 365 366 /* Set up tx coalescing */ 367 if ((cvals->tx_coalesce_usecs == 0) || 368 (cvals->tx_max_coalesced_frames == 0)) 369 priv->txcoalescing = 0; 370 else 371 priv->txcoalescing = 1; 372 373 /* Check the bounds of the values */ 374 if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) { 375 pr_info("Coalescing is limited to %d microseconds\n", 376 GFAR_MAX_COAL_USECS); 377 return -EINVAL; 378 } 379 380 if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) { 381 pr_info("Coalescing is limited to %d frames\n", 382 GFAR_MAX_COAL_FRAMES); 383 return -EINVAL; 384 } 385 386 priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs); 387 priv->txcount = cvals->tx_max_coalesced_frames; 388 389 if (priv->rxcoalescing) 390 gfar_write(&priv->regs->rxic, 391 mk_ic_value(priv->rxcount, priv->rxtime)); 392 else 393 gfar_write(&priv->regs->rxic, 0); 394 395 if (priv->txcoalescing) 396 gfar_write(&priv->regs->txic, 397 mk_ic_value(priv->txcount, priv->txtime)); 398 else 399 gfar_write(&priv->regs->txic, 0); 400 401 return 0; 402} 403 404/* Fills in rvals with the current ring parameters. Currently, 405 * rx, rx_mini, and rx_jumbo rings are the same size, as mini and 406 * jumbo are ignored by the driver */ 407static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) 408{ 409 struct gfar_private *priv = netdev_priv(dev); 410 411 rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE; 412 rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE; 413 rvals->rx_jumbo_max_pending = GFAR_RX_MAX_RING_SIZE; 414 rvals->tx_max_pending = GFAR_TX_MAX_RING_SIZE; 415 416 /* Values changeable by the user. The valid values are 417 * in the range 1 to the "*_max_pending" counterpart above. 418 */ 419 rvals->rx_pending = priv->rx_ring_size; 420 rvals->rx_mini_pending = priv->rx_ring_size; 421 rvals->rx_jumbo_pending = priv->rx_ring_size; 422 rvals->tx_pending = priv->tx_ring_size; 423} 424 425/* Change the current ring parameters, stopping the controller if 426 * necessary so that we don't mess things up while we're in 427 * motion. We wait for the ring to be clean before reallocating 428 * the rings. */ 429static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) 430{ 431 struct gfar_private *priv = netdev_priv(dev); 432 int err = 0; 433 434 if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE) 435 return -EINVAL; 436 437 if (!is_power_of_2(rvals->rx_pending)) { 438 printk("%s: Ring sizes must be a power of 2\n", 439 dev->name); 440 return -EINVAL; 441 } 442 443 if (rvals->tx_pending > GFAR_TX_MAX_RING_SIZE) 444 return -EINVAL; 445 446 if (!is_power_of_2(rvals->tx_pending)) { 447 printk("%s: Ring sizes must be a power of 2\n", 448 dev->name); 449 return -EINVAL; 450 } 451 452 if (dev->flags & IFF_UP) { 453 unsigned long flags; 454 455 /* Halt TX and RX, and process the frames which 456 * have already been received */ 457 spin_lock_irqsave(&priv->txlock, flags); 458 spin_lock(&priv->rxlock); 459 460 gfar_halt(dev); 461 gfar_clean_rx_ring(dev, priv->rx_ring_size); 462 463 spin_unlock(&priv->rxlock); 464 spin_unlock_irqrestore(&priv->txlock, flags); 465 466 /* Now we take down the rings to rebuild them */ 467 stop_gfar(dev); 468 } 469 470 /* Change the size */ 471 priv->rx_ring_size = rvals->rx_pending; 472 priv->tx_ring_size = rvals->tx_pending; 473 474 /* Rebuild the rings with the new size */ 475 if (dev->flags & IFF_UP) 476 err = startup_gfar(dev); 477 478 return err; 479} 480 481static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) 482{ 483 struct gfar_private *priv = netdev_priv(dev); 484 int err = 0; 485 486 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 487 return -EOPNOTSUPP; 488 489 if (dev->flags & IFF_UP) { 490 unsigned long flags; 491 492 /* Halt TX and RX, and process the frames which 493 * have already been received */ 494 spin_lock_irqsave(&priv->txlock, flags); 495 spin_lock(&priv->rxlock); 496 497 gfar_halt(dev); 498 gfar_clean_rx_ring(dev, priv->rx_ring_size); 499 500 spin_unlock(&priv->rxlock); 501 spin_unlock_irqrestore(&priv->txlock, flags); 502 503 /* Now we take down the rings to rebuild them */ 504 stop_gfar(dev); 505 } 506 507 priv->rx_csum_enable = data; 508 509 if (dev->flags & IFF_UP) 510 err = startup_gfar(dev); 511 512 return err; 513} 514 515static uint32_t gfar_get_rx_csum(struct net_device *dev) 516{ 517 struct gfar_private *priv = netdev_priv(dev); 518 519 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 520 return 0; 521 522 return priv->rx_csum_enable; 523} 524 525static int gfar_set_tx_csum(struct net_device *dev, uint32_t data) 526{ 527 unsigned long flags; 528 struct gfar_private *priv = netdev_priv(dev); 529 530 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 531 return -EOPNOTSUPP; 532 533 spin_lock_irqsave(&priv->txlock, flags); 534 gfar_halt(dev); 535 536 if (data) 537 dev->features |= NETIF_F_IP_CSUM; 538 else 539 dev->features &= ~NETIF_F_IP_CSUM; 540 541 gfar_start(dev); 542 spin_unlock_irqrestore(&priv->txlock, flags); 543 544 return 0; 545} 546 547static uint32_t gfar_get_tx_csum(struct net_device *dev) 548{ 549 struct gfar_private *priv = netdev_priv(dev); 550 551 if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 552 return 0; 553 554 return (dev->features & NETIF_F_IP_CSUM) != 0; 555} 556 557static uint32_t gfar_get_msglevel(struct net_device *dev) 558{ 559 struct gfar_private *priv = netdev_priv(dev); 560 return priv->msg_enable; 561} 562 563static void gfar_set_msglevel(struct net_device *dev, uint32_t data) 564{ 565 struct gfar_private *priv = netdev_priv(dev); 566 priv->msg_enable = data; 567} 568 569 570struct ethtool_ops gfar_ethtool_ops = { 571 .get_settings = gfar_gsettings, 572 .set_settings = gfar_ssettings, 573 .get_drvinfo = gfar_gdrvinfo, 574 .get_regs_len = gfar_reglen, 575 .get_regs = gfar_get_regs, 576 .get_link = ethtool_op_get_link, 577 .get_coalesce = gfar_gcoalesce, 578 .set_coalesce = gfar_scoalesce, 579 .get_ringparam = gfar_gringparam, 580 .set_ringparam = gfar_sringparam, 581 .get_strings = gfar_gstrings, 582 .get_stats_count = gfar_stats_count, 583 .get_ethtool_stats = gfar_fill_stats, 584 .get_rx_csum = gfar_get_rx_csum, 585 .get_tx_csum = gfar_get_tx_csum, 586 .set_rx_csum = gfar_set_rx_csum, 587 .set_tx_csum = gfar_set_tx_csum, 588 .get_msglevel = gfar_get_msglevel, 589 .set_msglevel = gfar_set_msglevel, 590};