summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/freescale/gianfar.c
diff options
context:
space:
mode:
authorClaudiu Manoil <claudiu.manoil@freescale.com>2012-09-24 02:39:08 +0400
committerDavid S. Miller <davem@davemloft.net>2012-09-25 00:25:16 +0400
commitb98b8babd6e3370fadb7c6eaacb00eb2f6344a6c (patch)
tree84490a56fe0cbeffd6082d54d9bf3172efd1668a /drivers/net/ethernet/freescale/gianfar.c
parent0cf833aefaa85bbfce3ff70485e5534e09254773 (diff)
downloadlinux-b98b8babd6e3370fadb7c6eaacb00eb2f6344a6c.tar.xz
gianfar: Change default HW Tx queue scheduling mode
This is primarily to address transmission timeout occurrences, when multiple H/W Tx queues are being used concurrently. Because in the priority scheduling mode the controller does not service the Tx queues equally (but in ascending index order), Tx timeouts are being triggered rightaway for a basic test with multiple simultaneous connections like: iperf -c <server_ip> -n 100M -P 8 resulting in kernel trace: NETDEV WATCHDOG: eth1 (fsl-gianfar): transmit queue <X> timed out ------------[ cut here ]------------ WARNING: at net/sched/sch_generic.c:255 ... and controller reset during intense traffic, and possibly further complications. This patch changes the default H/W Tx scheduling setting (TXSCHED) for multi-queue devices, from priority scheduling mode to a weighted round robin mode with equal weights for all H/W Tx queues, and addresses the issue above. Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/freescale/gianfar.c')
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 4d5b58ce1298..a1b52ec3b930 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -394,7 +394,13 @@ static void gfar_init_mac(struct net_device *ndev)
if (ndev->features & NETIF_F_IP_CSUM)
tctrl |= TCTRL_INIT_CSUM;
- tctrl |= TCTRL_TXSCHED_PRIO;
+ if (priv->prio_sched_en)
+ tctrl |= TCTRL_TXSCHED_PRIO;
+ else {
+ tctrl |= TCTRL_TXSCHED_WRRS;
+ gfar_write(&regs->tr03wt, DEFAULT_WRRS_WEIGHT);
+ gfar_write(&regs->tr47wt, DEFAULT_WRRS_WEIGHT);
+ }
gfar_write(&regs->tctrl, tctrl);
@@ -1160,6 +1166,9 @@ static int gfar_probe(struct platform_device *ofdev)
priv->rx_filer_enable = 1;
/* Enable most messages by default */
priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+ /* use pritority h/w tx queue scheduling for single queue devices */
+ if (priv->num_tx_queues == 1)
+ priv->prio_sched_en = 1;
/* Carrier starts down, phylib will bring it up */
netif_carrier_off(dev);