aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar_ethtool.c
diff options
context:
space:
mode:
authorSandeep Gopalpet <Sandeep.Kumar@freescale.com>2009-11-02 02:03:00 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-03 02:40:55 -0500
commita12f801d4b349bc57622584e70e45a4ccbef53b6 (patch)
tree1b081795127d9e47aa5bac516fededa736dfc394 /drivers/net/gianfar_ethtool.c
parent123b43e9716115302a0095e14f2c545811712715 (diff)
gianfar: Add per queue structure support
This patch introduces per tx and per rx queue structures. Earlier the members of these structures were inside the gfar_private structure. Moving forward if we want to support multiple queues, we need to refactor the gfar_private structure so that introduction of multiple queues is easier. Signed-off-by: Sandeep Gopalpet <Sandeep.Kumar@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/gianfar_ethtool.c')
-rw-r--r--drivers/net/gianfar_ethtool.c100
1 files changed, 65 insertions, 35 deletions
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 6c144b525b47..6d0d1714c2f2 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -7,8 +7,9 @@
7 * 7 *
8 * Author: Andy Fleming 8 * Author: Andy Fleming
9 * Maintainer: Kumar Gala 9 * Maintainer: Kumar Gala
10 * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
10 * 11 *
11 * Copyright (c) 2003,2004 Freescale Semiconductor, Inc. 12 * Copyright 2003-2006, 2008-2009 Freescale Semiconductor, Inc.
12 * 13 *
13 * This software may be used and distributed according to 14 * This software may be used and distributed according to
14 * the terms of the GNU Public License, Version 2, incorporated herein 15 * the terms of the GNU Public License, Version 2, incorporated herein
@@ -41,7 +42,7 @@
41#include "gianfar.h" 42#include "gianfar.h"
42 43
43extern void gfar_start(struct net_device *dev); 44extern void gfar_start(struct net_device *dev);
44extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); 45extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
45 46
46#define GFAR_MAX_COAL_USECS 0xffff 47#define GFAR_MAX_COAL_USECS 0xffff
47#define GFAR_MAX_COAL_FRAMES 0xff 48#define GFAR_MAX_COAL_FRAMES 0xff
@@ -197,12 +198,16 @@ static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
197{ 198{
198 struct gfar_private *priv = netdev_priv(dev); 199 struct gfar_private *priv = netdev_priv(dev);
199 struct phy_device *phydev = priv->phydev; 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;
200 203
201 if (NULL == phydev) 204 if (NULL == phydev)
202 return -ENODEV; 205 return -ENODEV;
206 tx_queue = priv->tx_queue;
207 rx_queue = priv->rx_queue;
203 208
204 cmd->maxtxpkt = get_icft_value(priv->txic); 209 cmd->maxtxpkt = get_icft_value(tx_queue->txic);
205 cmd->maxrxpkt = get_icft_value(priv->rxic); 210 cmd->maxrxpkt = get_icft_value(rx_queue->rxic);
206 211
207 return phy_ethtool_gset(phydev, cmd); 212 return phy_ethtool_gset(phydev, cmd);
208} 213}
@@ -279,6 +284,8 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
279static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) 284static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
280{ 285{
281 struct gfar_private *priv = netdev_priv(dev); 286 struct gfar_private *priv = netdev_priv(dev);
287 struct gfar_priv_rx_q *rx_queue = NULL;
288 struct gfar_priv_tx_q *tx_queue = NULL;
282 unsigned long rxtime; 289 unsigned long rxtime;
283 unsigned long rxcount; 290 unsigned long rxcount;
284 unsigned long txtime; 291 unsigned long txtime;
@@ -290,10 +297,13 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
290 if (NULL == priv->phydev) 297 if (NULL == priv->phydev)
291 return -ENODEV; 298 return -ENODEV;
292 299
293 rxtime = get_ictt_value(priv->rxic); 300 rx_queue = priv->rx_queue;
294 rxcount = get_icft_value(priv->rxic); 301 tx_queue = priv->tx_queue;
295 txtime = get_ictt_value(priv->txic); 302
296 txcount = get_icft_value(priv->txic); 303 rxtime = get_ictt_value(rx_queue->rxic);
304 rxcount = get_icft_value(rx_queue->rxic);
305 txtime = get_ictt_value(tx_queue->txic);
306 txcount = get_icft_value(tx_queue->txic);
297 cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime); 307 cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime);
298 cvals->rx_max_coalesced_frames = rxcount; 308 cvals->rx_max_coalesced_frames = rxcount;
299 309
@@ -339,16 +349,21 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
339static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) 349static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
340{ 350{
341 struct gfar_private *priv = netdev_priv(dev); 351 struct gfar_private *priv = netdev_priv(dev);
352 struct gfar_priv_tx_q *tx_queue = NULL;
353 struct gfar_priv_rx_q *rx_queue = NULL;
342 354
343 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) 355 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
344 return -EOPNOTSUPP; 356 return -EOPNOTSUPP;
345 357
358 tx_queue = priv->tx_queue;
359 rx_queue = priv->rx_queue;
360
346 /* Set up rx coalescing */ 361 /* Set up rx coalescing */
347 if ((cvals->rx_coalesce_usecs == 0) || 362 if ((cvals->rx_coalesce_usecs == 0) ||
348 (cvals->rx_max_coalesced_frames == 0)) 363 (cvals->rx_max_coalesced_frames == 0))
349 priv->rxcoalescing = 0; 364 rx_queue->rxcoalescing = 0;
350 else 365 else
351 priv->rxcoalescing = 1; 366 rx_queue->rxcoalescing = 1;
352 367
353 if (NULL == priv->phydev) 368 if (NULL == priv->phydev)
354 return -ENODEV; 369 return -ENODEV;
@@ -366,15 +381,15 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
366 return -EINVAL; 381 return -EINVAL;
367 } 382 }
368 383
369 priv->rxic = mk_ic_value(cvals->rx_max_coalesced_frames, 384 rx_queue->rxic = mk_ic_value(cvals->rx_max_coalesced_frames,
370 gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs)); 385 gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs));
371 386
372 /* Set up tx coalescing */ 387 /* Set up tx coalescing */
373 if ((cvals->tx_coalesce_usecs == 0) || 388 if ((cvals->tx_coalesce_usecs == 0) ||
374 (cvals->tx_max_coalesced_frames == 0)) 389 (cvals->tx_max_coalesced_frames == 0))
375 priv->txcoalescing = 0; 390 tx_queue->txcoalescing = 0;
376 else 391 else
377 priv->txcoalescing = 1; 392 tx_queue->txcoalescing = 1;
378 393
379 /* Check the bounds of the values */ 394 /* Check the bounds of the values */
380 if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) { 395 if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
@@ -389,16 +404,16 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
389 return -EINVAL; 404 return -EINVAL;
390 } 405 }
391 406
392 priv->txic = mk_ic_value(cvals->tx_max_coalesced_frames, 407 tx_queue->txic = mk_ic_value(cvals->tx_max_coalesced_frames,
393 gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs)); 408 gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
394 409
395 gfar_write(&priv->regs->rxic, 0); 410 gfar_write(&priv->regs->rxic, 0);
396 if (priv->rxcoalescing) 411 if (rx_queue->rxcoalescing)
397 gfar_write(&priv->regs->rxic, priv->rxic); 412 gfar_write(&priv->regs->rxic, rx_queue->rxic);
398 413
399 gfar_write(&priv->regs->txic, 0); 414 gfar_write(&priv->regs->txic, 0);
400 if (priv->txcoalescing) 415 if (tx_queue->txcoalescing)
401 gfar_write(&priv->regs->txic, priv->txic); 416 gfar_write(&priv->regs->txic, tx_queue->txic);
402 417
403 return 0; 418 return 0;
404} 419}
@@ -409,6 +424,11 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
409static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) 424static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
410{ 425{
411 struct gfar_private *priv = netdev_priv(dev); 426 struct gfar_private *priv = netdev_priv(dev);
427 struct gfar_priv_tx_q *tx_queue = NULL;
428 struct gfar_priv_rx_q *rx_queue = NULL;
429
430 tx_queue = priv->tx_queue;
431 rx_queue = priv->rx_queue;
412 432
413 rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE; 433 rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE;
414 rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE; 434 rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE;
@@ -418,10 +438,10 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv
418 /* Values changeable by the user. The valid values are 438 /* Values changeable by the user. The valid values are
419 * in the range 1 to the "*_max_pending" counterpart above. 439 * in the range 1 to the "*_max_pending" counterpart above.
420 */ 440 */
421 rvals->rx_pending = priv->rx_ring_size; 441 rvals->rx_pending = rx_queue->rx_ring_size;
422 rvals->rx_mini_pending = priv->rx_ring_size; 442 rvals->rx_mini_pending = rx_queue->rx_ring_size;
423 rvals->rx_jumbo_pending = priv->rx_ring_size; 443 rvals->rx_jumbo_pending = rx_queue->rx_ring_size;
424 rvals->tx_pending = priv->tx_ring_size; 444 rvals->tx_pending = tx_queue->tx_ring_size;
425} 445}
426 446
427/* Change the current ring parameters, stopping the controller if 447/* Change the current ring parameters, stopping the controller if
@@ -431,6 +451,8 @@ static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rv
431static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) 451static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
432{ 452{
433 struct gfar_private *priv = netdev_priv(dev); 453 struct gfar_private *priv = netdev_priv(dev);
454 struct gfar_priv_tx_q *tx_queue = NULL;
455 struct gfar_priv_rx_q *rx_queue = NULL;
434 int err = 0; 456 int err = 0;
435 457
436 if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE) 458 if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE)
@@ -451,29 +473,32 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
451 return -EINVAL; 473 return -EINVAL;
452 } 474 }
453 475
476 tx_queue = priv->tx_queue;
477 rx_queue = priv->rx_queue;
478
454 if (dev->flags & IFF_UP) { 479 if (dev->flags & IFF_UP) {
455 unsigned long flags; 480 unsigned long flags;
456 481
457 /* Halt TX and RX, and process the frames which 482 /* Halt TX and RX, and process the frames which
458 * have already been received */ 483 * have already been received */
459 spin_lock_irqsave(&priv->txlock, flags); 484 spin_lock_irqsave(&tx_queue->txlock, flags);
460 spin_lock(&priv->rxlock); 485 spin_lock(&rx_queue->rxlock);
461 486
462 gfar_halt(dev); 487 gfar_halt(dev);
463 488
464 spin_unlock(&priv->rxlock); 489 spin_unlock(&rx_queue->rxlock);
465 spin_unlock_irqrestore(&priv->txlock, flags); 490 spin_unlock_irqrestore(&tx_queue->txlock, flags);
466 491
467 gfar_clean_rx_ring(dev, priv->rx_ring_size); 492 gfar_clean_rx_ring(rx_queue, rx_queue->rx_ring_size);
468 493
469 /* Now we take down the rings to rebuild them */ 494 /* Now we take down the rings to rebuild them */
470 stop_gfar(dev); 495 stop_gfar(dev);
471 } 496 }
472 497
473 /* Change the size */ 498 /* Change the size */
474 priv->rx_ring_size = rvals->rx_pending; 499 rx_queue->rx_ring_size = rvals->rx_pending;
475 priv->tx_ring_size = rvals->tx_pending; 500 tx_queue->tx_ring_size = rvals->tx_pending;
476 priv->num_txbdfree = priv->tx_ring_size; 501 tx_queue->num_txbdfree = tx_queue->tx_ring_size;
477 502
478 /* Rebuild the rings with the new size */ 503 /* Rebuild the rings with the new size */
479 if (dev->flags & IFF_UP) { 504 if (dev->flags & IFF_UP) {
@@ -486,24 +511,29 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva
486static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) 511static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
487{ 512{
488 struct gfar_private *priv = netdev_priv(dev); 513 struct gfar_private *priv = netdev_priv(dev);
514 struct gfar_priv_rx_q *rx_queue = NULL;
515 struct gfar_priv_tx_q *tx_queue = NULL;
489 unsigned long flags; 516 unsigned long flags;
490 int err = 0; 517 int err = 0;
491 518
492 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) 519 if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
493 return -EOPNOTSUPP; 520 return -EOPNOTSUPP;
494 521
522 tx_queue = priv->tx_queue;
523 rx_queue = priv->rx_queue;
524
495 if (dev->flags & IFF_UP) { 525 if (dev->flags & IFF_UP) {
496 /* Halt TX and RX, and process the frames which 526 /* Halt TX and RX, and process the frames which
497 * have already been received */ 527 * have already been received */
498 spin_lock_irqsave(&priv->txlock, flags); 528 spin_lock_irqsave(&tx_queue->txlock, flags);
499 spin_lock(&priv->rxlock); 529 spin_lock(&rx_queue->rxlock);
500 530
501 gfar_halt(dev); 531 gfar_halt(dev);
502 532
503 spin_unlock(&priv->rxlock); 533 spin_unlock(&rx_queue->rxlock);
504 spin_unlock_irqrestore(&priv->txlock, flags); 534 spin_unlock_irqrestore(&tx_queue->txlock, flags);
505 535
506 gfar_clean_rx_ring(dev, priv->rx_ring_size); 536 gfar_clean_rx_ring(rx_queue, rx_queue->rx_ring_size);
507 537
508 /* Now we take down the rings to rebuild them */ 538 /* Now we take down the rings to rebuild them */
509 stop_gfar(dev); 539 stop_gfar(dev);