]> git.hungrycats.org Git - linux/commitdiff
gianfar: Change default HW Tx queue scheduling mode
authorClaudiu Manoil <claudiu.manoil@freescale.com>
Sun, 23 Sep 2012 22:39:08 +0000 (22:39 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 13 Oct 2013 22:42:47 +0000 (15:42 -0700)
commit b98b8babd6e3370fadb7c6eaacb00eb2f6344a6c upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar.h

index 0819a7403847ebf93164f4073b0850b3d86a0eb3..d5de9a474aeabd0ca6f2955ce5f47ae5fb1f13a3 100644 (file)
@@ -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);
 
@@ -1153,6 +1159,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);
index 4c9f8d487dbbf4825e10fc2e3ee25199662e7517..348b6dd08f537e57ee492cf163b156cee09d8a74 100644 (file)
@@ -301,8 +301,16 @@ extern const char gfar_driver_version[];
 #define TCTRL_TFCPAUSE         0x00000008
 #define TCTRL_TXSCHED_MASK     0x00000006
 #define TCTRL_TXSCHED_INIT     0x00000000
+/* priority scheduling */
 #define TCTRL_TXSCHED_PRIO     0x00000002
+/* weighted round-robin scheduling (WRRS) */
 #define TCTRL_TXSCHED_WRRS     0x00000004
+/* default WRRS weight and policy setting,
+ * tailored to the tr03wt and tr47wt registers:
+ * equal weight for all Tx Qs, measured in 64byte units
+ */
+#define DEFAULT_WRRS_WEIGHT    0x18181818
+
 #define TCTRL_INIT_CSUM                (TCTRL_TUCSEN | TCTRL_IPCSEN)
 
 #define IEVENT_INIT_CLEAR      0xffffffff
@@ -1098,7 +1106,8 @@ struct gfar_private {
                extended_hash:1,
                bd_stash_en:1,
                rx_filer_enable:1,
-               wol_en:1; /* Wake-on-LAN enabled */
+               wol_en:1, /* Wake-on-LAN enabled */
+               prio_sched_en:1; /* Enable priorty based Tx scheduling in Hw */
        unsigned short padding;
 
        /* PHY stuff */