summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorClaudiu Manoil <claudiu.manoil@freescale.com>2014-03-18 14:21:47 (GMT)
committerMadalin-Cristian Bucur <madalin.bucur@freescale.com>2014-03-24 15:53:35 (GMT)
commitc6ffe7138605a35fc37156184de906f82eca1353 (patch)
tree40a5ce5446dcdd5a37b07e7b95944173b8749f4a /drivers/net/ethernet
parent924d40725a825d8c1a74b87b46bb93e653e10b18 (diff)
downloadlinux-fsl-qoriq-c6ffe7138605a35fc37156184de906f82eca1353.tar.xz
gianfar: Fix P1010 config regression (SQ polling)
The P1010 device tree restricts the number of supported interrupt groups to 1, although the eth controller can support 2 interrupt groups and the driver assumes the Multi-Group mode ("fsl,etsec2" model). So, in this case the assumption that the Multi-Group mode (MQ_MG_MODE) devices always support 2 interrupt groups is false. To fix this, a check for the actual number of interrupt groups enabled in the board's device tree has been added in gfar_probe for the "fsl,etsec2" devices. Without this fix, P1010 based boards claim support for 2 Tx queues to the net stack but only one is actually allocated, leading to NULL access in xmit. This issue was introduced by enabling Single-Queue polling for the P1010 devices. Change-Id: I74e2d143557a7e2cebce8928ac42160e79957f0c Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/9876 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Rajan Gupta <rajan.gupta@freescale.com> Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index bf35061..307b70c 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -767,9 +767,19 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
num_tx_qs = 1;
num_rx_qs = 1;
} else { /* MQ_MG_MODE */
+ /* get the actual number of supported groups */
+ unsigned int num_grps = of_get_available_child_count(np);
+
+ if (num_grps == 0 || num_grps > MAXGROUPS) {
+ dev_err(&ofdev->dev, "Invalid # of int groups(%d)\n",
+ num_grps);
+ pr_err("Cannot do alloc_etherdev, aborting\n");
+ return -EINVAL;
+ }
+
if (poll_mode == GFAR_SQ_POLLING) {
- num_tx_qs = 2; /* one txq per int group */
- num_rx_qs = 2; /* one rxq per int group */
+ num_tx_qs = num_grps; /* one txq per int group */
+ num_rx_qs = num_grps; /* one rxq per int group */
} else { /* GFAR_MQ_POLLING */
num_tx_qs = tx_queues ? *tx_queues : 1;
num_rx_qs = rx_queues ? *rx_queues : 1;