summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorClaudiu Manoil <claudiu.manoil@freescale.com>2014-03-11 16:01:24 (GMT)
committerMadalin-Cristian Bucur <madalin.bucur@freescale.com>2014-03-12 15:53:31 (GMT)
commit5249cbcb5ef7b8a812d6963b7459d3dd46fdb712 (patch)
tree4e296351a85c3f1373f31cf5834b07fecf4629ae /drivers
parentf98117a17f0104ab5a12eb3c2a41bfd345b6284e (diff)
downloadlinux-fsl-qoriq-5249cbcb5ef7b8a812d6963b7459d3dd46fdb712.tar.xz
gianfar: Fix multi-queue support checks @probe()
priv is not instantiated at gfar_of_init() time, when parsing the DT for info on supported HW queues. Before the netdev can be allocated, the number of supported queues must be known. Because the number of supported queues depends on device type, move the compatibility checks before netdev allocation. Local vars are used to hold the operation mode info before netdev allocation. This fixes the null accesses for priv->.., in gfar_of_init. Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net> Change-Id: I7b3c4c65196bb443d7e1eccf01ef0a2b5cf6f193 Reviewed-on: http://git.am.freescale.net:8181/9706 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/freescale/gianfar.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index f74ec69..c27195d 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -741,21 +741,30 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
const u32 *stash_idx;
unsigned int num_tx_qs, num_rx_qs;
u32 *tx_queues, *rx_queues;
+ unsigned short mode, poll_mode;
if (!np || !of_device_is_available(np))
return -ENODEV;
+ if (of_device_is_compatible(np, "fsl,etsec2")) {
+ mode = MQ_MG_MODE;
+ poll_mode = GFAR_SQ_POLLING;
+ } else {
+ mode = SQ_SG_MODE;
+ poll_mode = GFAR_SQ_POLLING;
+ }
+
/* parse the num of HW tx and rx queues */
tx_queues = (u32 *)of_get_property(np, "fsl,num_tx_queues", NULL);
rx_queues = (u32 *)of_get_property(np, "fsl,num_rx_queues", NULL);
- if (priv->mode == SQ_SG_MODE) {
+ if (mode == SQ_SG_MODE) {
num_tx_qs = 1;
num_rx_qs = 1;
} else { /* MQ_MG_MODE */
- if (priv->poll_mode == GFAR_SQ_POLLING) {
- num_tx_qs = 2; /* one q per int group */
- num_rx_qs = 2; /* one q per int group */
+ if (poll_mode == GFAR_SQ_POLLING) {
+ num_tx_qs = 2; /* one txq per int group */
+ num_rx_qs = 2; /* 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;
@@ -784,6 +793,9 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
priv = netdev_priv(dev);
priv->ndev = dev;
+ priv->mode = mode;
+ priv->poll_mode = poll_mode;
+
priv->num_tx_queues = num_tx_qs;
netif_set_real_num_rx_queues(dev, num_rx_qs);
priv->num_rx_queues = num_rx_qs;
@@ -807,17 +819,13 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
priv->gfargrp[i].regs = NULL;
/* Parse and initialize group specific information */
- if (of_device_is_compatible(np, "fsl,etsec2")) {
- priv->mode = MQ_MG_MODE;
- priv->poll_mode = GFAR_SQ_POLLING;
+ if (priv->mode == MQ_MG_MODE) {
for_each_child_of_node(np, child) {
err = gfar_parse_group(child, priv, model);
if (err)
goto err_grp_init;
}
- } else {
- priv->mode = SQ_SG_MODE;
- priv->poll_mode = GFAR_SQ_POLLING;
+ } else { /* SQ_SG_MODE */
err = gfar_parse_group(np, priv, model);
if (err)
goto err_grp_init;