diff options
author | David S. Miller <davem@davemloft.net> | 2014-03-10 13:17:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-10 13:17:44 -0400 |
commit | 19433646fec836f6804fd5409f8a89a5869d1c7d (patch) | |
tree | 4c68117fd4bda6b8ac7e51eca82e5c59a24c1116 | |
parent | be14cc98e9fd5416cc8f86799913fd3c52dc720e (diff) | |
parent | 71ff9e3df7e1c5d3293af6b595309124e8c97412 (diff) |
Merge branch 'gianfar-next'
Claudiu Manoil says:
====================
gianfar: Tx timeout issue
There's an older Tx timeout issue showing up on etsec2 devices
with 2 CPUs. I pinned this issue down to processing overhead
incurred by supporting multiple Tx/Rx rings, as explained in
the 2nd patch below. But before this, there's also a concurency
issue leading to Rx/Tx spurrious interrupts, addressed by the
'Tx NAPI' patch below.
The Tx timeout can be triggered with multiple Tx flows,
'iperf -c -N 8' commands, on a 2 CPUs etsec2 based (P1020) board.
Before the patches:
"""
root@p1020rdb-pc:~# iperf -c 172.16.1.3 -n 1000M -P 8 &
[...]
root@p1020rdb-pc:~# NETDEV WATCHDOG: eth1 (fsl-gianfar): transmit queue 1 timed out
WARNING: at net/sched/sch_generic.c:279
Modules linked in:
CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.13.0-rc3-03386-g89ea59c #23
task: ed84ef40 ti: ed868000 task.ti: ed868000
NIP: c04627a8 LR: c04627a8 CTR: c02fb270
REGS: ed869d00 TRAP: 0700 Not tainted (3.13.0-rc3-03386-g89ea59c)
MSR: 00029000 <CE,EE,ME> CR: 44000022 XER: 20000000
[...]
root@p1020rdb-pc:~# [ ID] Interval Transfer Bandwidth
[ 5] 0.0-19.3 sec 1000 MBytes 434 Mbits/sec
[ 8] 0.0-39.7 sec 1000 MBytes 211 Mbits/sec
[ 9] 0.0-40.1 sec 1000 MBytes 209 Mbits/sec
[ 3] 0.0-40.2 sec 1000 MBytes 209 Mbits/sec
[ 10] 0.0-59.0 sec 1000 MBytes 142 Mbits/sec
[ 7] 0.0-74.6 sec 1000 MBytes 112 Mbits/sec
[ 6] 0.0-74.7 sec 1000 MBytes 112 Mbits/sec
[ 4] 0.0-74.7 sec 1000 MBytes 112 Mbits/sec
[SUM] 0.0-74.7 sec 7.81 GBytes 898 Mbits/sec
root@p1020rdb-pc:~# ifconfig eth1
eth1 Link encap:Ethernet HWaddr 00:04:9f:00:13:01
inet addr:172.16.1.1 Bcast:172.16.255.255 Mask:255.255.0.0
inet6 addr: fe80::204:9fff:fe00:1301/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:708722 errors:0 dropped:0 overruns:0 frame:0
TX packets:8717849 errors:6 dropped:0 overruns:1470 carrier:0
collisions:0 txqueuelen:1000
RX bytes:58118018 (55.4 MiB) TX bytes:274069482 (261.3 MiB)
Base address:0xa000
"""
After applying the patches:
"""
root@p1020rdb-pc:~# iperf -c 172.16.1.3 -n 1000M -P 8 &
[...]
root@p1020rdb-pc:~# [ ID] Interval Transfer Bandwidth
[ 9] 0.0-70.5 sec 1000 MBytes 119 Mbits/sec
[ 5] 0.0-70.5 sec 1000 MBytes 119 Mbits/sec
[ 6] 0.0-70.7 sec 1000 MBytes 119 Mbits/sec
[ 4] 0.0-71.0 sec 1000 MBytes 118 Mbits/sec
[ 8] 0.0-71.1 sec 1000 MBytes 118 Mbits/sec
[ 3] 0.0-71.2 sec 1000 MBytes 118 Mbits/sec
[ 10] 0.0-71.3 sec 1000 MBytes 118 Mbits/sec
[ 7] 0.0-71.3 sec 1000 MBytes 118 Mbits/sec
[SUM] 0.0-71.3 sec 7.81 GBytes 942 Mbits/sec
root@p1020rdb-pc:~# ifconfig eth1
eth1 Link encap:Ethernet HWaddr 00:04:9f:00:13:01
inet addr:172.16.1.1 Bcast:172.16.255.255 Mask:255.255.0.0
inet6 addr: fe80::204:9fff:fe00:1301/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:728446 errors:0 dropped:0 overruns:0 frame:0
TX packets:8690057 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:59732650 (56.9 MiB) TX bytes:271554306 (258.9 MiB)
Base address:0xa000
"""
v2: PATCH 2:
Replaced CPP check with run-time condition to
limit the number of queues. Updated comments.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.c | 274 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/gianfar.h | 52 |
2 files changed, 232 insertions, 94 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index c5b9320f7629..28effbecdab6 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -128,8 +128,10 @@ static void free_skb_resources(struct gfar_private *priv); | |||
128 | static void gfar_set_multi(struct net_device *dev); | 128 | static void gfar_set_multi(struct net_device *dev); |
129 | static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); | 129 | static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); |
130 | static void gfar_configure_serdes(struct net_device *dev); | 130 | static void gfar_configure_serdes(struct net_device *dev); |
131 | static int gfar_poll(struct napi_struct *napi, int budget); | 131 | static int gfar_poll_rx(struct napi_struct *napi, int budget); |
132 | static int gfar_poll_sq(struct napi_struct *napi, int budget); | 132 | static int gfar_poll_tx(struct napi_struct *napi, int budget); |
133 | static int gfar_poll_rx_sq(struct napi_struct *napi, int budget); | ||
134 | static int gfar_poll_tx_sq(struct napi_struct *napi, int budget); | ||
133 | #ifdef CONFIG_NET_POLL_CONTROLLER | 135 | #ifdef CONFIG_NET_POLL_CONTROLLER |
134 | static void gfar_netpoll(struct net_device *dev); | 136 | static void gfar_netpoll(struct net_device *dev); |
135 | #endif | 137 | #endif |
@@ -361,7 +363,10 @@ static void gfar_mac_rx_config(struct gfar_private *priv) | |||
361 | if (priv->rx_filer_enable) { | 363 | if (priv->rx_filer_enable) { |
362 | rctrl |= RCTRL_FILREN; | 364 | rctrl |= RCTRL_FILREN; |
363 | /* Program the RIR0 reg with the required distribution */ | 365 | /* Program the RIR0 reg with the required distribution */ |
364 | gfar_write(®s->rir0, DEFAULT_RIR0); | 366 | if (priv->poll_mode == GFAR_SQ_POLLING) |
367 | gfar_write(®s->rir0, DEFAULT_2RXQ_RIR0); | ||
368 | else /* GFAR_MQ_POLLING */ | ||
369 | gfar_write(®s->rir0, DEFAULT_8RXQ_RIR0); | ||
365 | } | 370 | } |
366 | 371 | ||
367 | /* Restore PROMISC mode */ | 372 | /* Restore PROMISC mode */ |
@@ -614,23 +619,26 @@ static void disable_napi(struct gfar_private *priv) | |||
614 | { | 619 | { |
615 | int i; | 620 | int i; |
616 | 621 | ||
617 | for (i = 0; i < priv->num_grps; i++) | 622 | for (i = 0; i < priv->num_grps; i++) { |
618 | napi_disable(&priv->gfargrp[i].napi); | 623 | napi_disable(&priv->gfargrp[i].napi_rx); |
624 | napi_disable(&priv->gfargrp[i].napi_tx); | ||
625 | } | ||
619 | } | 626 | } |
620 | 627 | ||
621 | static void enable_napi(struct gfar_private *priv) | 628 | static void enable_napi(struct gfar_private *priv) |
622 | { | 629 | { |
623 | int i; | 630 | int i; |
624 | 631 | ||
625 | for (i = 0; i < priv->num_grps; i++) | 632 | for (i = 0; i < priv->num_grps; i++) { |
626 | napi_enable(&priv->gfargrp[i].napi); | 633 | napi_enable(&priv->gfargrp[i].napi_rx); |
634 | napi_enable(&priv->gfargrp[i].napi_tx); | ||
635 | } | ||
627 | } | 636 | } |
628 | 637 | ||
629 | static int gfar_parse_group(struct device_node *np, | 638 | static int gfar_parse_group(struct device_node *np, |
630 | struct gfar_private *priv, const char *model) | 639 | struct gfar_private *priv, const char *model) |
631 | { | 640 | { |
632 | struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps]; | 641 | struct gfar_priv_grp *grp = &priv->gfargrp[priv->num_grps]; |
633 | u32 *queue_mask; | ||
634 | int i; | 642 | int i; |
635 | 643 | ||
636 | for (i = 0; i < GFAR_NUM_IRQS; i++) { | 644 | for (i = 0; i < GFAR_NUM_IRQS; i++) { |
@@ -659,12 +667,20 @@ static int gfar_parse_group(struct device_node *np, | |||
659 | grp->priv = priv; | 667 | grp->priv = priv; |
660 | spin_lock_init(&grp->grplock); | 668 | spin_lock_init(&grp->grplock); |
661 | if (priv->mode == MQ_MG_MODE) { | 669 | if (priv->mode == MQ_MG_MODE) { |
662 | queue_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL); | 670 | u32 *rxq_mask, *txq_mask; |
663 | grp->rx_bit_map = queue_mask ? | 671 | rxq_mask = (u32 *)of_get_property(np, "fsl,rx-bit-map", NULL); |
664 | *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); | 672 | txq_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL); |
665 | queue_mask = (u32 *)of_get_property(np, "fsl,tx-bit-map", NULL); | 673 | |
666 | grp->tx_bit_map = queue_mask ? | 674 | if (priv->poll_mode == GFAR_SQ_POLLING) { |
667 | *queue_mask : (DEFAULT_MAPPING >> priv->num_grps); | 675 | /* One Q per interrupt group: Q0 to G0, Q1 to G1 */ |
676 | grp->rx_bit_map = (DEFAULT_MAPPING >> priv->num_grps); | ||
677 | grp->tx_bit_map = (DEFAULT_MAPPING >> priv->num_grps); | ||
678 | } else { /* GFAR_MQ_POLLING */ | ||
679 | grp->rx_bit_map = rxq_mask ? | ||
680 | *rxq_mask : (DEFAULT_MAPPING >> priv->num_grps); | ||
681 | grp->tx_bit_map = txq_mask ? | ||
682 | *txq_mask : (DEFAULT_MAPPING >> priv->num_grps); | ||
683 | } | ||
668 | } else { | 684 | } else { |
669 | grp->rx_bit_map = 0xFF; | 685 | grp->rx_bit_map = 0xFF; |
670 | grp->tx_bit_map = 0xFF; | 686 | grp->tx_bit_map = 0xFF; |
@@ -680,6 +696,8 @@ static int gfar_parse_group(struct device_node *np, | |||
680 | * also assign queues to groups | 696 | * also assign queues to groups |
681 | */ | 697 | */ |
682 | for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) { | 698 | for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) { |
699 | if (!grp->rx_queue) | ||
700 | grp->rx_queue = priv->rx_queue[i]; | ||
683 | grp->num_rx_queues++; | 701 | grp->num_rx_queues++; |
684 | grp->rstat |= (RSTAT_CLEAR_RHALT >> i); | 702 | grp->rstat |= (RSTAT_CLEAR_RHALT >> i); |
685 | priv->rqueue |= ((RQUEUE_EN0 | RQUEUE_EX0) >> i); | 703 | priv->rqueue |= ((RQUEUE_EN0 | RQUEUE_EX0) >> i); |
@@ -687,6 +705,8 @@ static int gfar_parse_group(struct device_node *np, | |||
687 | } | 705 | } |
688 | 706 | ||
689 | for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) { | 707 | for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) { |
708 | if (!grp->tx_queue) | ||
709 | grp->tx_queue = priv->tx_queue[i]; | ||
690 | grp->num_tx_queues++; | 710 | grp->num_tx_queues++; |
691 | grp->tstat |= (TSTAT_CLEAR_THALT >> i); | 711 | grp->tstat |= (TSTAT_CLEAR_THALT >> i); |
692 | priv->tqueue |= (TQUEUE_EN0 >> i); | 712 | priv->tqueue |= (TQUEUE_EN0 >> i); |
@@ -717,9 +737,22 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
717 | if (!np || !of_device_is_available(np)) | 737 | if (!np || !of_device_is_available(np)) |
718 | return -ENODEV; | 738 | return -ENODEV; |
719 | 739 | ||
720 | /* parse the num of tx and rx queues */ | 740 | /* parse the num of HW tx and rx queues */ |
721 | tx_queues = (u32 *)of_get_property(np, "fsl,num_tx_queues", NULL); | 741 | tx_queues = (u32 *)of_get_property(np, "fsl,num_tx_queues", NULL); |
722 | num_tx_qs = tx_queues ? *tx_queues : 1; | 742 | rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL); |
743 | |||
744 | if (priv->mode == SQ_SG_MODE) { | ||
745 | num_tx_qs = 1; | ||
746 | num_rx_qs = 1; | ||
747 | } else { /* MQ_MG_MODE */ | ||
748 | if (priv->poll_mode == GFAR_SQ_POLLING) { | ||
749 | num_tx_qs = 2; /* one q per int group */ | ||
750 | num_rx_qs = 2; /* one q per int group */ | ||
751 | } else { /* GFAR_MQ_POLLING */ | ||
752 | num_tx_qs = tx_queues ? *tx_queues : 1; | ||
753 | num_rx_qs = rx_queues ? *rx_queues : 1; | ||
754 | } | ||
755 | } | ||
723 | 756 | ||
724 | if (num_tx_qs > MAX_TX_QS) { | 757 | if (num_tx_qs > MAX_TX_QS) { |
725 | pr_err("num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n", | 758 | pr_err("num_tx_qs(=%d) greater than MAX_TX_QS(=%d)\n", |
@@ -728,9 +761,6 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
728 | return -EINVAL; | 761 | return -EINVAL; |
729 | } | 762 | } |
730 | 763 | ||
731 | rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL); | ||
732 | num_rx_qs = rx_queues ? *rx_queues : 1; | ||
733 | |||
734 | if (num_rx_qs > MAX_RX_QS) { | 764 | if (num_rx_qs > MAX_RX_QS) { |
735 | pr_err("num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n", | 765 | pr_err("num_rx_qs(=%d) greater than MAX_RX_QS(=%d)\n", |
736 | num_rx_qs, MAX_RX_QS); | 766 | num_rx_qs, MAX_RX_QS); |
@@ -771,6 +801,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
771 | /* Parse and initialize group specific information */ | 801 | /* Parse and initialize group specific information */ |
772 | if (of_device_is_compatible(np, "fsl,etsec2")) { | 802 | if (of_device_is_compatible(np, "fsl,etsec2")) { |
773 | priv->mode = MQ_MG_MODE; | 803 | priv->mode = MQ_MG_MODE; |
804 | priv->poll_mode = GFAR_SQ_POLLING; | ||
774 | for_each_child_of_node(np, child) { | 805 | for_each_child_of_node(np, child) { |
775 | err = gfar_parse_group(child, priv, model); | 806 | err = gfar_parse_group(child, priv, model); |
776 | if (err) | 807 | if (err) |
@@ -778,6 +809,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) | |||
778 | } | 809 | } |
779 | } else { | 810 | } else { |
780 | priv->mode = SQ_SG_MODE; | 811 | priv->mode = SQ_SG_MODE; |
812 | priv->poll_mode = GFAR_SQ_POLLING; | ||
781 | err = gfar_parse_group(np, priv, model); | 813 | err = gfar_parse_group(np, priv, model); |
782 | if (err) | 814 | if (err) |
783 | goto err_grp_init; | 815 | goto err_grp_init; |
@@ -1257,13 +1289,19 @@ static int gfar_probe(struct platform_device *ofdev) | |||
1257 | dev->ethtool_ops = &gfar_ethtool_ops; | 1289 | dev->ethtool_ops = &gfar_ethtool_ops; |
1258 | 1290 | ||
1259 | /* Register for napi ...We are registering NAPI for each grp */ | 1291 | /* Register for napi ...We are registering NAPI for each grp */ |
1260 | if (priv->mode == SQ_SG_MODE) | 1292 | for (i = 0; i < priv->num_grps; i++) { |
1261 | netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq, | 1293 | if (priv->poll_mode == GFAR_SQ_POLLING) { |
1262 | GFAR_DEV_WEIGHT); | 1294 | netif_napi_add(dev, &priv->gfargrp[i].napi_rx, |
1263 | else | 1295 | gfar_poll_rx_sq, GFAR_DEV_WEIGHT); |
1264 | for (i = 0; i < priv->num_grps; i++) | 1296 | netif_napi_add(dev, &priv->gfargrp[i].napi_tx, |
1265 | netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, | 1297 | gfar_poll_tx_sq, 2); |
1266 | GFAR_DEV_WEIGHT); | 1298 | } else { |
1299 | netif_napi_add(dev, &priv->gfargrp[i].napi_rx, | ||
1300 | gfar_poll_rx, GFAR_DEV_WEIGHT); | ||
1301 | netif_napi_add(dev, &priv->gfargrp[i].napi_tx, | ||
1302 | gfar_poll_tx, 2); | ||
1303 | } | ||
1304 | } | ||
1267 | 1305 | ||
1268 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { | 1306 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) { |
1269 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | | 1307 | dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | |
@@ -2538,31 +2576,6 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2538 | netdev_tx_completed_queue(txq, howmany, bytes_sent); | 2576 | netdev_tx_completed_queue(txq, howmany, bytes_sent); |
2539 | } | 2577 | } |
2540 | 2578 | ||
2541 | static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp) | ||
2542 | { | ||
2543 | unsigned long flags; | ||
2544 | |||
2545 | spin_lock_irqsave(&gfargrp->grplock, flags); | ||
2546 | if (napi_schedule_prep(&gfargrp->napi)) { | ||
2547 | gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED); | ||
2548 | __napi_schedule(&gfargrp->napi); | ||
2549 | } else { | ||
2550 | /* Clear IEVENT, so interrupts aren't called again | ||
2551 | * because of the packets that have already arrived. | ||
2552 | */ | ||
2553 | gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK); | ||
2554 | } | ||
2555 | spin_unlock_irqrestore(&gfargrp->grplock, flags); | ||
2556 | |||
2557 | } | ||
2558 | |||
2559 | /* Interrupt Handler for Transmit complete */ | ||
2560 | static irqreturn_t gfar_transmit(int irq, void *grp_id) | ||
2561 | { | ||
2562 | gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id); | ||
2563 | return IRQ_HANDLED; | ||
2564 | } | ||
2565 | |||
2566 | static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, | 2579 | static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp, |
2567 | struct sk_buff *skb) | 2580 | struct sk_buff *skb) |
2568 | { | 2581 | { |
@@ -2633,7 +2646,48 @@ static inline void count_errors(unsigned short status, struct net_device *dev) | |||
2633 | 2646 | ||
2634 | irqreturn_t gfar_receive(int irq, void *grp_id) | 2647 | irqreturn_t gfar_receive(int irq, void *grp_id) |
2635 | { | 2648 | { |
2636 | gfar_schedule_cleanup((struct gfar_priv_grp *)grp_id); | 2649 | struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id; |
2650 | unsigned long flags; | ||
2651 | u32 imask; | ||
2652 | |||
2653 | if (likely(napi_schedule_prep(&grp->napi_rx))) { | ||
2654 | spin_lock_irqsave(&grp->grplock, flags); | ||
2655 | imask = gfar_read(&grp->regs->imask); | ||
2656 | imask &= IMASK_RX_DISABLED; | ||
2657 | gfar_write(&grp->regs->imask, imask); | ||
2658 | spin_unlock_irqrestore(&grp->grplock, flags); | ||
2659 | __napi_schedule(&grp->napi_rx); | ||
2660 | } else { | ||
2661 | /* Clear IEVENT, so interrupts aren't called again | ||
2662 | * because of the packets that have already arrived. | ||
2663 | */ | ||
2664 | gfar_write(&grp->regs->ievent, IEVENT_RX_MASK); | ||
2665 | } | ||
2666 | |||
2667 | return IRQ_HANDLED; | ||
2668 | } | ||
2669 | |||
2670 | /* Interrupt Handler for Transmit complete */ | ||
2671 | static irqreturn_t gfar_transmit(int irq, void *grp_id) | ||
2672 | { | ||
2673 | struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id; | ||
2674 | unsigned long flags; | ||
2675 | u32 imask; | ||
2676 | |||
2677 | if (likely(napi_schedule_prep(&grp->napi_tx))) { | ||
2678 | spin_lock_irqsave(&grp->grplock, flags); | ||
2679 | imask = gfar_read(&grp->regs->imask); | ||
2680 | imask &= IMASK_TX_DISABLED; | ||
2681 | gfar_write(&grp->regs->imask, imask); | ||
2682 | spin_unlock_irqrestore(&grp->grplock, flags); | ||
2683 | __napi_schedule(&grp->napi_tx); | ||
2684 | } else { | ||
2685 | /* Clear IEVENT, so interrupts aren't called again | ||
2686 | * because of the packets that have already arrived. | ||
2687 | */ | ||
2688 | gfar_write(&grp->regs->ievent, IEVENT_TX_MASK); | ||
2689 | } | ||
2690 | |||
2637 | return IRQ_HANDLED; | 2691 | return IRQ_HANDLED; |
2638 | } | 2692 | } |
2639 | 2693 | ||
@@ -2757,7 +2811,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2757 | rx_queue->stats.rx_bytes += pkt_len; | 2811 | rx_queue->stats.rx_bytes += pkt_len; |
2758 | skb_record_rx_queue(skb, rx_queue->qindex); | 2812 | skb_record_rx_queue(skb, rx_queue->qindex); |
2759 | gfar_process_frame(dev, skb, amount_pull, | 2813 | gfar_process_frame(dev, skb, amount_pull, |
2760 | &rx_queue->grp->napi); | 2814 | &rx_queue->grp->napi_rx); |
2761 | 2815 | ||
2762 | } else { | 2816 | } else { |
2763 | netif_warn(priv, rx_err, dev, "Missing skb!\n"); | 2817 | netif_warn(priv, rx_err, dev, "Missing skb!\n"); |
@@ -2786,55 +2840,81 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2786 | return howmany; | 2840 | return howmany; |
2787 | } | 2841 | } |
2788 | 2842 | ||
2789 | static int gfar_poll_sq(struct napi_struct *napi, int budget) | 2843 | static int gfar_poll_rx_sq(struct napi_struct *napi, int budget) |
2790 | { | 2844 | { |
2791 | struct gfar_priv_grp *gfargrp = | 2845 | struct gfar_priv_grp *gfargrp = |
2792 | container_of(napi, struct gfar_priv_grp, napi); | 2846 | container_of(napi, struct gfar_priv_grp, napi_rx); |
2793 | struct gfar __iomem *regs = gfargrp->regs; | 2847 | struct gfar __iomem *regs = gfargrp->regs; |
2794 | struct gfar_priv_tx_q *tx_queue = gfargrp->priv->tx_queue[0]; | 2848 | struct gfar_priv_rx_q *rx_queue = gfargrp->rx_queue; |
2795 | struct gfar_priv_rx_q *rx_queue = gfargrp->priv->rx_queue[0]; | ||
2796 | int work_done = 0; | 2849 | int work_done = 0; |
2797 | 2850 | ||
2798 | /* Clear IEVENT, so interrupts aren't called again | 2851 | /* Clear IEVENT, so interrupts aren't called again |
2799 | * because of the packets that have already arrived | 2852 | * because of the packets that have already arrived |
2800 | */ | 2853 | */ |
2801 | gfar_write(®s->ievent, IEVENT_RTX_MASK); | 2854 | gfar_write(®s->ievent, IEVENT_RX_MASK); |
2802 | |||
2803 | /* run Tx cleanup to completion */ | ||
2804 | if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) | ||
2805 | gfar_clean_tx_ring(tx_queue); | ||
2806 | 2855 | ||
2807 | work_done = gfar_clean_rx_ring(rx_queue, budget); | 2856 | work_done = gfar_clean_rx_ring(rx_queue, budget); |
2808 | 2857 | ||
2809 | if (work_done < budget) { | 2858 | if (work_done < budget) { |
2859 | u32 imask; | ||
2810 | napi_complete(napi); | 2860 | napi_complete(napi); |
2811 | /* Clear the halt bit in RSTAT */ | 2861 | /* Clear the halt bit in RSTAT */ |
2812 | gfar_write(®s->rstat, gfargrp->rstat); | 2862 | gfar_write(®s->rstat, gfargrp->rstat); |
2813 | 2863 | ||
2814 | gfar_write(®s->imask, IMASK_DEFAULT); | 2864 | spin_lock_irq(&gfargrp->grplock); |
2865 | imask = gfar_read(®s->imask); | ||
2866 | imask |= IMASK_RX_DEFAULT; | ||
2867 | gfar_write(®s->imask, imask); | ||
2868 | spin_unlock_irq(&gfargrp->grplock); | ||
2815 | } | 2869 | } |
2816 | 2870 | ||
2817 | return work_done; | 2871 | return work_done; |
2818 | } | 2872 | } |
2819 | 2873 | ||
2820 | static int gfar_poll(struct napi_struct *napi, int budget) | 2874 | static int gfar_poll_tx_sq(struct napi_struct *napi, int budget) |
2875 | { | ||
2876 | struct gfar_priv_grp *gfargrp = | ||
2877 | container_of(napi, struct gfar_priv_grp, napi_tx); | ||
2878 | struct gfar __iomem *regs = gfargrp->regs; | ||
2879 | struct gfar_priv_tx_q *tx_queue = gfargrp->tx_queue; | ||
2880 | u32 imask; | ||
2881 | |||
2882 | /* Clear IEVENT, so interrupts aren't called again | ||
2883 | * because of the packets that have already arrived | ||
2884 | */ | ||
2885 | gfar_write(®s->ievent, IEVENT_TX_MASK); | ||
2886 | |||
2887 | /* run Tx cleanup to completion */ | ||
2888 | if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) | ||
2889 | gfar_clean_tx_ring(tx_queue); | ||
2890 | |||
2891 | napi_complete(napi); | ||
2892 | |||
2893 | spin_lock_irq(&gfargrp->grplock); | ||
2894 | imask = gfar_read(®s->imask); | ||
2895 | imask |= IMASK_TX_DEFAULT; | ||
2896 | gfar_write(®s->imask, imask); | ||
2897 | spin_unlock_irq(&gfargrp->grplock); | ||
2898 | |||
2899 | return 0; | ||
2900 | } | ||
2901 | |||
2902 | static int gfar_poll_rx(struct napi_struct *napi, int budget) | ||
2821 | { | 2903 | { |
2822 | struct gfar_priv_grp *gfargrp = | 2904 | struct gfar_priv_grp *gfargrp = |
2823 | container_of(napi, struct gfar_priv_grp, napi); | 2905 | container_of(napi, struct gfar_priv_grp, napi_rx); |
2824 | struct gfar_private *priv = gfargrp->priv; | 2906 | struct gfar_private *priv = gfargrp->priv; |
2825 | struct gfar __iomem *regs = gfargrp->regs; | 2907 | struct gfar __iomem *regs = gfargrp->regs; |
2826 | struct gfar_priv_tx_q *tx_queue = NULL; | ||
2827 | struct gfar_priv_rx_q *rx_queue = NULL; | 2908 | struct gfar_priv_rx_q *rx_queue = NULL; |
2828 | int work_done = 0, work_done_per_q = 0; | 2909 | int work_done = 0, work_done_per_q = 0; |
2829 | int i, budget_per_q = 0; | 2910 | int i, budget_per_q = 0; |
2830 | int has_tx_work = 0; | ||
2831 | unsigned long rstat_rxf; | 2911 | unsigned long rstat_rxf; |
2832 | int num_act_queues; | 2912 | int num_act_queues; |
2833 | 2913 | ||
2834 | /* Clear IEVENT, so interrupts aren't called again | 2914 | /* Clear IEVENT, so interrupts aren't called again |
2835 | * because of the packets that have already arrived | 2915 | * because of the packets that have already arrived |
2836 | */ | 2916 | */ |
2837 | gfar_write(®s->ievent, IEVENT_RTX_MASK); | 2917 | gfar_write(®s->ievent, IEVENT_RX_MASK); |
2838 | 2918 | ||
2839 | rstat_rxf = gfar_read(®s->rstat) & RSTAT_RXF_MASK; | 2919 | rstat_rxf = gfar_read(®s->rstat) & RSTAT_RXF_MASK; |
2840 | 2920 | ||
@@ -2842,15 +2922,6 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2842 | if (num_act_queues) | 2922 | if (num_act_queues) |
2843 | budget_per_q = budget/num_act_queues; | 2923 | budget_per_q = budget/num_act_queues; |
2844 | 2924 | ||
2845 | for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { | ||
2846 | tx_queue = priv->tx_queue[i]; | ||
2847 | /* run Tx cleanup to completion */ | ||
2848 | if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) { | ||
2849 | gfar_clean_tx_ring(tx_queue); | ||
2850 | has_tx_work = 1; | ||
2851 | } | ||
2852 | } | ||
2853 | |||
2854 | for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { | 2925 | for_each_set_bit(i, &gfargrp->rx_bit_map, priv->num_rx_queues) { |
2855 | /* skip queue if not active */ | 2926 | /* skip queue if not active */ |
2856 | if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i))) | 2927 | if (!(rstat_rxf & (RSTAT_CLEAR_RXF0 >> i))) |
@@ -2873,19 +2944,62 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
2873 | } | 2944 | } |
2874 | } | 2945 | } |
2875 | 2946 | ||
2876 | if (!num_act_queues && !has_tx_work) { | 2947 | if (!num_act_queues) { |
2877 | 2948 | u32 imask; | |
2878 | napi_complete(napi); | 2949 | napi_complete(napi); |
2879 | 2950 | ||
2880 | /* Clear the halt bit in RSTAT */ | 2951 | /* Clear the halt bit in RSTAT */ |
2881 | gfar_write(®s->rstat, gfargrp->rstat); | 2952 | gfar_write(®s->rstat, gfargrp->rstat); |
2882 | 2953 | ||
2883 | gfar_write(®s->imask, IMASK_DEFAULT); | 2954 | spin_lock_irq(&gfargrp->grplock); |
2955 | imask = gfar_read(®s->imask); | ||
2956 | imask |= IMASK_RX_DEFAULT; | ||
2957 | gfar_write(®s->imask, imask); | ||
2958 | spin_unlock_irq(&gfargrp->grplock); | ||
2884 | } | 2959 | } |
2885 | 2960 | ||
2886 | return work_done; | 2961 | return work_done; |
2887 | } | 2962 | } |
2888 | 2963 | ||
2964 | static int gfar_poll_tx(struct napi_struct *napi, int budget) | ||
2965 | { | ||
2966 | struct gfar_priv_grp *gfargrp = | ||
2967 | container_of(napi, struct gfar_priv_grp, napi_tx); | ||
2968 | struct gfar_private *priv = gfargrp->priv; | ||
2969 | struct gfar __iomem *regs = gfargrp->regs; | ||
2970 | struct gfar_priv_tx_q *tx_queue = NULL; | ||
2971 | int has_tx_work = 0; | ||
2972 | int i; | ||
2973 | |||
2974 | /* Clear IEVENT, so interrupts aren't called again | ||
2975 | * because of the packets that have already arrived | ||
2976 | */ | ||
2977 | gfar_write(®s->ievent, IEVENT_TX_MASK); | ||
2978 | |||
2979 | for_each_set_bit(i, &gfargrp->tx_bit_map, priv->num_tx_queues) { | ||
2980 | tx_queue = priv->tx_queue[i]; | ||
2981 | /* run Tx cleanup to completion */ | ||
2982 | if (tx_queue->tx_skbuff[tx_queue->skb_dirtytx]) { | ||
2983 | gfar_clean_tx_ring(tx_queue); | ||
2984 | has_tx_work = 1; | ||
2985 | } | ||
2986 | } | ||
2987 | |||
2988 | if (!has_tx_work) { | ||
2989 | u32 imask; | ||
2990 | napi_complete(napi); | ||
2991 | |||
2992 | spin_lock_irq(&gfargrp->grplock); | ||
2993 | imask = gfar_read(®s->imask); | ||
2994 | imask |= IMASK_TX_DEFAULT; | ||
2995 | gfar_write(®s->imask, imask); | ||
2996 | spin_unlock_irq(&gfargrp->grplock); | ||
2997 | } | ||
2998 | |||
2999 | return 0; | ||
3000 | } | ||
3001 | |||
3002 | |||
2889 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3003 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2890 | /* Polling 'interrupt' - used by things like netconsole to send skbs | 3004 | /* Polling 'interrupt' - used by things like netconsole to send skbs |
2891 | * without having to re-enable interrupts. It's not called while | 3005 | * without having to re-enable interrupts. It's not called while |
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 1e16216d4150..84632c569f2c 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h | |||
@@ -377,8 +377,11 @@ extern const char gfar_driver_version[]; | |||
377 | IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \ | 377 | IMASK_RXFEN0 | IMASK_BSY | IMASK_EBERR | IMASK_BABR | \ |
378 | IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \ | 378 | IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \ |
379 | | IMASK_PERR) | 379 | | IMASK_PERR) |
380 | #define IMASK_RTX_DISABLED ((~(IMASK_RXFEN0 | IMASK_TXFEN | IMASK_BSY)) \ | 380 | #define IMASK_RX_DEFAULT (IMASK_RXFEN0 | IMASK_BSY) |
381 | & IMASK_DEFAULT) | 381 | #define IMASK_TX_DEFAULT (IMASK_TXFEN | IMASK_TXBEN) |
382 | |||
383 | #define IMASK_RX_DISABLED ((~(IMASK_RX_DEFAULT)) & IMASK_DEFAULT) | ||
384 | #define IMASK_TX_DISABLED ((~(IMASK_TX_DEFAULT)) & IMASK_DEFAULT) | ||
382 | 385 | ||
383 | /* Fifo management */ | 386 | /* Fifo management */ |
384 | #define FIFO_TX_THR_MASK 0x01ff | 387 | #define FIFO_TX_THR_MASK 0x01ff |
@@ -409,7 +412,9 @@ extern const char gfar_driver_version[]; | |||
409 | 412 | ||
410 | /* This default RIR value directly corresponds | 413 | /* This default RIR value directly corresponds |
411 | * to the 3-bit hash value generated */ | 414 | * to the 3-bit hash value generated */ |
412 | #define DEFAULT_RIR0 0x05397700 | 415 | #define DEFAULT_8RXQ_RIR0 0x05397700 |
416 | /* Map even hash values to Q0, and odd ones to Q1 */ | ||
417 | #define DEFAULT_2RXQ_RIR0 0x04104100 | ||
413 | 418 | ||
414 | /* RQFCR register bits */ | 419 | /* RQFCR register bits */ |
415 | #define RQFCR_GPI 0x80000000 | 420 | #define RQFCR_GPI 0x80000000 |
@@ -904,6 +909,22 @@ enum { | |||
904 | MQ_MG_MODE | 909 | MQ_MG_MODE |
905 | }; | 910 | }; |
906 | 911 | ||
912 | /* GFAR_SQ_POLLING: Single Queue NAPI polling mode | ||
913 | * The driver supports a single pair of RX/Tx queues | ||
914 | * per interrupt group (Rx/Tx int line). MQ_MG mode | ||
915 | * devices have 2 interrupt groups, so the device will | ||
916 | * have a total of 2 Tx and 2 Rx queues in this case. | ||
917 | * GFAR_MQ_POLLING: Multi Queue NAPI polling mode | ||
918 | * The driver supports all the 8 Rx and Tx HW queues | ||
919 | * each queue mapped by the Device Tree to one of | ||
920 | * the 2 interrupt groups. This mode implies significant | ||
921 | * processing overhead (CPU and controller level). | ||
922 | */ | ||
923 | enum gfar_poll_mode { | ||
924 | GFAR_SQ_POLLING = 0, | ||
925 | GFAR_MQ_POLLING | ||
926 | }; | ||
927 | |||
907 | /* | 928 | /* |
908 | * Per TX queue stats | 929 | * Per TX queue stats |
909 | */ | 930 | */ |
@@ -1013,17 +1034,20 @@ struct gfar_irqinfo { | |||
1013 | */ | 1034 | */ |
1014 | 1035 | ||
1015 | struct gfar_priv_grp { | 1036 | struct gfar_priv_grp { |
1016 | spinlock_t grplock __attribute__ ((aligned (SMP_CACHE_BYTES))); | 1037 | spinlock_t grplock __aligned(SMP_CACHE_BYTES); |
1017 | struct napi_struct napi; | 1038 | struct napi_struct napi_rx; |
1018 | struct gfar_private *priv; | 1039 | struct napi_struct napi_tx; |
1019 | struct gfar __iomem *regs; | 1040 | struct gfar __iomem *regs; |
1020 | unsigned int rstat; | 1041 | struct gfar_priv_tx_q *tx_queue; |
1021 | unsigned long num_rx_queues; | 1042 | struct gfar_priv_rx_q *rx_queue; |
1022 | unsigned long rx_bit_map; | ||
1023 | /* cacheline 3 */ | ||
1024 | unsigned int tstat; | 1043 | unsigned int tstat; |
1044 | unsigned int rstat; | ||
1045 | |||
1046 | struct gfar_private *priv; | ||
1025 | unsigned long num_tx_queues; | 1047 | unsigned long num_tx_queues; |
1026 | unsigned long tx_bit_map; | 1048 | unsigned long tx_bit_map; |
1049 | unsigned long num_rx_queues; | ||
1050 | unsigned long rx_bit_map; | ||
1027 | 1051 | ||
1028 | struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS]; | 1052 | struct gfar_irqinfo *irqinfo[GFAR_NUM_IRQS]; |
1029 | }; | 1053 | }; |
@@ -1053,8 +1077,6 @@ enum gfar_dev_state { | |||
1053 | * the buffer descriptor determines the actual condition. | 1077 | * the buffer descriptor determines the actual condition. |
1054 | */ | 1078 | */ |
1055 | struct gfar_private { | 1079 | struct gfar_private { |
1056 | unsigned int num_rx_queues; | ||
1057 | |||
1058 | struct device *dev; | 1080 | struct device *dev; |
1059 | struct net_device *ndev; | 1081 | struct net_device *ndev; |
1060 | enum gfar_errata errata; | 1082 | enum gfar_errata errata; |
@@ -1062,6 +1084,7 @@ struct gfar_private { | |||
1062 | 1084 | ||
1063 | u16 uses_rxfcb; | 1085 | u16 uses_rxfcb; |
1064 | u16 padding; | 1086 | u16 padding; |
1087 | u32 device_flags; | ||
1065 | 1088 | ||
1066 | /* HW time stamping enabled flag */ | 1089 | /* HW time stamping enabled flag */ |
1067 | int hwts_rx_en; | 1090 | int hwts_rx_en; |
@@ -1072,10 +1095,11 @@ struct gfar_private { | |||
1072 | struct gfar_priv_grp gfargrp[MAXGROUPS]; | 1095 | struct gfar_priv_grp gfargrp[MAXGROUPS]; |
1073 | 1096 | ||
1074 | unsigned long state; | 1097 | unsigned long state; |
1075 | u32 device_flags; | ||
1076 | 1098 | ||
1077 | unsigned int mode; | 1099 | unsigned short mode; |
1100 | unsigned short poll_mode; | ||
1078 | unsigned int num_tx_queues; | 1101 | unsigned int num_tx_queues; |
1102 | unsigned int num_rx_queues; | ||
1079 | unsigned int num_grps; | 1103 | unsigned int num_grps; |
1080 | 1104 | ||
1081 | /* Network Statistics */ | 1105 | /* Network Statistics */ |