Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81206ebc authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'gianfar'



Claudiu Manoil says:

====================
gianfar: Device configuration fixes

This patchset represents the first part of an effort
to solve some old device configuration issues in gianfar,
especially run-time reset and re-configuration problems.
I'm referring to "on-the-fly" configuration of registers
against HW specification, concurrency issues during device
reset / re-configuration operations, and implementing HW
advisories for these operations.

There's also a good deal of code cleanup and refactoring,
and some other (minor) fixes as well.

v2: Remove sysfs stubs w/o replacing them with module
    params (patch 2).
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c85fde83 7cca336a
Loading
Loading
Loading
Loading
+0 −30
Original line number Diff line number Diff line
The Gianfar Ethernet Driver
Sysfs File description

Author: Andy Fleming <afleming@freescale.com>
Updated: 2005-07-28

SYSFS

Several of the features of the gianfar driver are controlled
through sysfs files.  These are:

bd_stash:
To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
bd_stash, echo 'off' or '0' to disable

rx_stash_len:
To stash the first n bytes of the packet in L2, echo the number
of bytes to buf_stash_len.  echo 0 to disable.

WARNING: You could really screw these up if you set them too low or high!
fifo_threshold:
To change the number of bytes the controller needs in the
fifo before it starts transmission, echo the number of bytes to 
fifo_thresh.  Range should be 0-511.

fifo_starve:
When the FIFO has less than this many bytes during a transmit, it
enters starve mode, and increases the priority of TX memory
transactions.  To change, echo the number of bytes to
fifo_starve.  Range should be 0-511.

fifo_starve_off:
Once in starve mode, the FIFO remains there until it has this
many bytes.  To change, echo the number of bytes to
fifo_starve_off.  Range should be 0-511.

CHECKSUM OFFLOADING

+1 −2
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@ obj-$(CONFIG_FSL_XGMAC_MDIO) += xgmac_mdio.o
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
gianfar_driver-objs := gianfar.o \
		gianfar_ethtool.o \
		gianfar_sysfs.o
		gianfar_ethtool.o
obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
+236 −264
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
 * Maintainer: Kumar Gala
 * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
 *
 * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
 * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
 * Copyright 2007 MontaVista Software, Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
@@ -138,9 +138,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
			       int amount_pull, struct napi_struct *napi);
void gfar_halt(struct net_device *dev);
static void gfar_halt_nodisable(struct net_device *dev);
void gfar_start(struct net_device *dev);
static void gfar_halt_nodisable(struct gfar_private *priv);
static void gfar_clear_exact_match(struct net_device *dev);
static void gfar_set_mac_for_addr(struct net_device *dev, int num,
				  const u8 *addr);
@@ -338,7 +336,6 @@ static void gfar_init_mac(struct net_device *ndev)
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u32 rctrl = 0;
	u32 tctrl = 0;
	u32 attrs = 0;

	/* write the tx/rx base registers */
	gfar_init_tx_rx_base(priv);
@@ -376,13 +373,6 @@ static void gfar_init_mac(struct net_device *ndev)
		rctrl |= RCTRL_PADDING(priv->padding);
	}

	/* Insert receive time stamps into padding alignment bytes */
	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) {
		rctrl &= ~RCTRL_PAL_MASK;
		rctrl |= RCTRL_PADDING(8);
		priv->padding = 8;
	}

	/* Enable HW time stamping if requested from user space */
	if (priv->hwts_rx_en) {
		rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE;
@@ -409,29 +399,6 @@ static void gfar_init_mac(struct net_device *ndev)
	}

	gfar_write(&regs->tctrl, tctrl);

	/* Set the extraction length and index */
	attrs = ATTRELI_EL(priv->rx_stash_size) |
		ATTRELI_EI(priv->rx_stash_index);

	gfar_write(&regs->attreli, attrs);

	/* Start with defaults, and add stashing or locking
	 * depending on the approprate variables
	 */
	attrs = ATTR_INIT_SETTINGS;

	if (priv->bd_stash_en)
		attrs |= ATTR_BDSTASH;

	if (priv->rx_stash_size != 0)
		attrs |= ATTR_BUFSTASH;

	gfar_write(&regs->attr, attrs);

	gfar_write(&regs->fifo_tx_thr, priv->fifo_threshold);
	gfar_write(&regs->fifo_tx_starve, priv->fifo_starve);
	gfar_write(&regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
}

static struct net_device_stats *gfar_get_stats(struct net_device *dev)
@@ -479,6 +446,29 @@ static const struct net_device_ops gfar_netdev_ops = {
#endif
};

static void gfar_ints_disable(struct gfar_private *priv)
{
	int i;
	for (i = 0; i < priv->num_grps; i++) {
		struct gfar __iomem *regs = priv->gfargrp[i].regs;
		/* Clear IEVENT */
		gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);

		/* Initialize IMASK */
		gfar_write(&regs->imask, IMASK_INIT_CLEAR);
	}
}

static void gfar_ints_enable(struct gfar_private *priv)
{
	int i;
	for (i = 0; i < priv->num_grps; i++) {
		struct gfar __iomem *regs = priv->gfargrp[i].regs;
		/* Unmask the interrupts we look for */
		gfar_write(&regs->imask, IMASK_DEFAULT);
	}
}

void lock_rx_qs(struct gfar_private *priv)
{
	int i;
@@ -511,7 +501,43 @@ void unlock_tx_qs(struct gfar_private *priv)
		spin_unlock(&priv->tx_queue[i]->txlock);
}

static void free_tx_pointers(struct gfar_private *priv)
static int gfar_alloc_tx_queues(struct gfar_private *priv)
{
	int i;

	for (i = 0; i < priv->num_tx_queues; i++) {
		priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
					    GFP_KERNEL);
		if (!priv->tx_queue[i])
			return -ENOMEM;

		priv->tx_queue[i]->tx_skbuff = NULL;
		priv->tx_queue[i]->qindex = i;
		priv->tx_queue[i]->dev = priv->ndev;
		spin_lock_init(&(priv->tx_queue[i]->txlock));
	}
	return 0;
}

static int gfar_alloc_rx_queues(struct gfar_private *priv)
{
	int i;

	for (i = 0; i < priv->num_rx_queues; i++) {
		priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
					    GFP_KERNEL);
		if (!priv->rx_queue[i])
			return -ENOMEM;

		priv->rx_queue[i]->rx_skbuff = NULL;
		priv->rx_queue[i]->qindex = i;
		priv->rx_queue[i]->dev = priv->ndev;
		spin_lock_init(&(priv->rx_queue[i]->rxlock));
	}
	return 0;
}

static void gfar_free_tx_queues(struct gfar_private *priv)
{
	int i;

@@ -519,7 +545,7 @@ static void free_tx_pointers(struct gfar_private *priv)
		kfree(priv->tx_queue[i]);
}

static void free_rx_pointers(struct gfar_private *priv)
static void gfar_free_rx_queues(struct gfar_private *priv)
{
	int i;

@@ -608,6 +634,30 @@ static int gfar_parse_group(struct device_node *np,
		grp->rx_bit_map = 0xFF;
		grp->tx_bit_map = 0xFF;
	}

	/* bit_map's MSB is q0 (from q0 to q7) but, for_each_set_bit parses
	 * right to left, so we need to revert the 8 bits to get the q index
	 */
	grp->rx_bit_map = bitrev8(grp->rx_bit_map);
	grp->tx_bit_map = bitrev8(grp->tx_bit_map);

	/* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
	 * also assign queues to groups
	 */
	for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
		grp->num_rx_queues++;
		grp->rstat |= (RSTAT_CLEAR_RHALT >> i);
		priv->rqueue |= ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
		priv->rx_queue[i]->grp = grp;
	}

	for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
		grp->num_tx_queues++;
		grp->tstat |= (TSTAT_CLEAR_THALT >> i);
		priv->tqueue |= (TQUEUE_EN0 >> i);
		priv->tx_queue[i]->grp = grp;
	}

	priv->num_grps++;

	return 0;
@@ -664,7 +714,14 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
	priv->num_tx_queues = num_tx_qs;
	netif_set_real_num_rx_queues(dev, num_rx_qs);
	priv->num_rx_queues = num_rx_qs;
	priv->num_grps = 0x0;

	err = gfar_alloc_tx_queues(priv);
	if (err)
		goto tx_alloc_failed;

	err = gfar_alloc_rx_queues(priv);
	if (err)
		goto rx_alloc_failed;

	/* Init Rx queue filer rule set linked list */
	INIT_LIST_HEAD(&priv->rx_list.list);
@@ -691,38 +748,6 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
			goto err_grp_init;
	}

	for (i = 0; i < priv->num_tx_queues; i++)
		priv->tx_queue[i] = NULL;
	for (i = 0; i < priv->num_rx_queues; i++)
		priv->rx_queue[i] = NULL;

	for (i = 0; i < priv->num_tx_queues; i++) {
		priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q),
					    GFP_KERNEL);
		if (!priv->tx_queue[i]) {
			err = -ENOMEM;
			goto tx_alloc_failed;
		}
		priv->tx_queue[i]->tx_skbuff = NULL;
		priv->tx_queue[i]->qindex = i;
		priv->tx_queue[i]->dev = dev;
		spin_lock_init(&(priv->tx_queue[i]->txlock));
	}

	for (i = 0; i < priv->num_rx_queues; i++) {
		priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q),
					    GFP_KERNEL);
		if (!priv->rx_queue[i]) {
			err = -ENOMEM;
			goto rx_alloc_failed;
		}
		priv->rx_queue[i]->rx_skbuff = NULL;
		priv->rx_queue[i]->qindex = i;
		priv->rx_queue[i]->dev = dev;
		spin_lock_init(&(priv->rx_queue[i]->rxlock));
	}


	stash = of_get_property(np, "bd-stash", NULL);

	if (stash) {
@@ -749,17 +774,16 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
		memcpy(dev->dev_addr, mac_addr, ETH_ALEN);

	if (model && !strcasecmp(model, "TSEC"))
		priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
		priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
				     FSL_GIANFAR_DEV_HAS_COALESCE |
				     FSL_GIANFAR_DEV_HAS_RMON |
				     FSL_GIANFAR_DEV_HAS_MULTI_INTR;

	if (model && !strcasecmp(model, "eTSEC"))
		priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT |
		priv->device_flags |= FSL_GIANFAR_DEV_HAS_GIGABIT |
				     FSL_GIANFAR_DEV_HAS_COALESCE |
				     FSL_GIANFAR_DEV_HAS_RMON |
				     FSL_GIANFAR_DEV_HAS_MULTI_INTR |
				     FSL_GIANFAR_DEV_HAS_PADDING |
				     FSL_GIANFAR_DEV_HAS_CSUM |
				     FSL_GIANFAR_DEV_HAS_VLAN |
				     FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
@@ -784,12 +808,12 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)

	return 0;

rx_alloc_failed:
	free_rx_pointers(priv);
tx_alloc_failed:
	free_tx_pointers(priv);
err_grp_init:
	unmap_group_regs(priv);
rx_alloc_failed:
	gfar_free_rx_queues(priv);
tx_alloc_failed:
	gfar_free_tx_queues(priv);
	free_gfar_dev(priv);
	return err;
}
@@ -875,19 +899,6 @@ static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
	return phy_mii_ioctl(priv->phydev, rq, cmd);
}

static unsigned int reverse_bitmap(unsigned int bit_map, unsigned int max_qs)
{
	unsigned int new_bit_map = 0x0;
	int mask = 0x1 << (max_qs - 1), i;

	for (i = 0; i < max_qs; i++) {
		if (bit_map & mask)
			new_bit_map = new_bit_map + (1 << i);
		mask = mask >> 0x1;
	}
	return new_bit_map;
}

static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
				   u32 class)
{
@@ -1005,43 +1016,10 @@ static void gfar_detect_errata(struct gfar_private *priv)
			 priv->errata);
}

/* Set up the ethernet device structure, private data,
 * and anything else we need before we start
 */
static int gfar_probe(struct platform_device *ofdev)
static void gfar_hw_init(struct gfar_private *priv)
{
	u32 tempval;
	struct net_device *dev = NULL;
	struct gfar_private *priv = NULL;
	struct gfar __iomem *regs = NULL;
	int err = 0, i, grp_idx = 0;
	u32 rstat = 0, tstat = 0, rqueue = 0, tqueue = 0;
	u32 isrg = 0;
	u32 __iomem *baddr;

	err = gfar_of_init(ofdev, &dev);

	if (err)
		return err;

	priv = netdev_priv(dev);
	priv->ndev = dev;
	priv->ofdev = ofdev;
	priv->dev = &ofdev->dev;
	SET_NETDEV_DEV(dev, &ofdev->dev);

	spin_lock_init(&priv->bflock);
	INIT_WORK(&priv->reset_task, gfar_reset_task);

	platform_set_drvdata(ofdev, priv);
	regs = priv->gfargrp[0].regs;

	gfar_detect_errata(priv);

	/* Stop the DMA engine now, in case it was running before
	 * (The firmware could have used it, and left it running).
	 */
	gfar_halt(dev);
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u32 tempval, attrs;

	/* Reset MAC layer */
	gfar_write(&regs->maccfg1, MACCFG1_SOFT_RESET);
@@ -1049,15 +1027,10 @@ static int gfar_probe(struct platform_device *ofdev)
	/* We need to delay at least 3 TX clocks */
	udelay(2);

	tempval = 0;
	if (!priv->pause_aneg_en && priv->tx_pause_en)
		tempval |= MACCFG1_TX_FLOW;
	if (!priv->pause_aneg_en && priv->rx_pause_en)
		tempval |= MACCFG1_RX_FLOW;
	/* the soft reset bit is not self-resetting, so we need to
	 * clear it before resuming normal operation
	 */
	gfar_write(&regs->maccfg1, tempval);
	gfar_write(&regs->maccfg1, 0);

	/* Initialize MACCFG2. */
	tempval = MACCFG2_INIT_SETTINGS;
@@ -1068,37 +1041,39 @@ static int gfar_probe(struct platform_device *ofdev)
	/* Initialize ECNTRL */
	gfar_write(&regs->ecntrl, ECNTRL_INIT_SETTINGS);

	/* Set the dev->base_addr to the gfar reg region */
	dev->base_addr = (unsigned long) regs;
	/* Set the extraction length and index */
	attrs = ATTRELI_EL(priv->rx_stash_size) |
		ATTRELI_EI(priv->rx_stash_index);

	/* Fill in the dev structure */
	dev->watchdog_timeo = TX_TIMEOUT;
	dev->mtu = 1500;
	dev->netdev_ops = &gfar_netdev_ops;
	dev->ethtool_ops = &gfar_ethtool_ops;
	gfar_write(&regs->attreli, attrs);

	/* Register for napi ...We are registering NAPI for each grp */
	if (priv->mode == SQ_SG_MODE)
		netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq,
			       GFAR_DEV_WEIGHT);
	else
		for (i = 0; i < priv->num_grps; i++)
			netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
				       GFAR_DEV_WEIGHT);
	/* Start with defaults, and add stashing
	 * depending on driver parameters
	 */
	attrs = ATTR_INIT_SETTINGS;

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
		dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
				   NETIF_F_RXCSUM;
		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
				 NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
	}
	if (priv->bd_stash_en)
		attrs |= ATTR_BDSTASH;

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
		dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
				    NETIF_F_HW_VLAN_CTAG_RX;
		dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
	if (priv->rx_stash_size != 0)
		attrs |= ATTR_BUFSTASH;

	gfar_write(&regs->attr, attrs);

	/* FIFO configs */
	gfar_write(&regs->fifo_tx_thr, DEFAULT_FIFO_TX_THR);
	gfar_write(&regs->fifo_tx_starve, DEFAULT_FIFO_TX_STARVE);
	gfar_write(&regs->fifo_tx_starve_shutoff, DEFAULT_FIFO_TX_STARVE_OFF);

	/* Program the interrupt steering regs, only for MG devices */
	if (priv->num_grps > 1)
		gfar_write_isrg(priv);
}

static void __init gfar_init_addr_hash_table(struct gfar_private *priv)
{
	struct gfar __iomem *regs = priv->gfargrp[0].regs;

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
		priv->extended_hash = 1;
		priv->hash_width = 9;
@@ -1133,68 +1108,82 @@ static int gfar_probe(struct platform_device *ofdev)
		priv->hash_regs[6] = &regs->gaddr6;
		priv->hash_regs[7] = &regs->gaddr7;
	}
}

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_PADDING)
		priv->padding = DEFAULT_PADDING;
	else
		priv->padding = 0;
/* Set up the ethernet device structure, private data,
 * and anything else we need before we start
 */
static int gfar_probe(struct platform_device *ofdev)
{
	struct net_device *dev = NULL;
	struct gfar_private *priv = NULL;
	int err = 0, i;

	if (dev->features & NETIF_F_IP_CSUM ||
	    priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
		dev->needed_headroom = GMAC_FCB_LEN;
	err = gfar_of_init(ofdev, &dev);

	/* Program the isrg regs only if number of grps > 1 */
	if (priv->num_grps > 1) {
		baddr = &regs->isrg0;
		for (i = 0; i < priv->num_grps; i++) {
			isrg |= (priv->gfargrp[i].rx_bit_map << ISRG_SHIFT_RX);
			isrg |= (priv->gfargrp[i].tx_bit_map << ISRG_SHIFT_TX);
			gfar_write(baddr, isrg);
			baddr++;
			isrg = 0x0;
		}
	}
	if (err)
		return err;

	/* Need to reverse the bit maps as  bit_map's MSB is q0
	 * but, for_each_set_bit parses from right to left, which
	 * basically reverses the queue numbers
	 */
	for (i = 0; i< priv->num_grps; i++) {
		priv->gfargrp[i].tx_bit_map =
			reverse_bitmap(priv->gfargrp[i].tx_bit_map, MAX_TX_QS);
		priv->gfargrp[i].rx_bit_map =
			reverse_bitmap(priv->gfargrp[i].rx_bit_map, MAX_RX_QS);
	}
	priv = netdev_priv(dev);
	priv->ndev = dev;
	priv->ofdev = ofdev;
	priv->dev = &ofdev->dev;
	SET_NETDEV_DEV(dev, &ofdev->dev);

	/* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
	 * also assign queues to groups
	spin_lock_init(&priv->bflock);
	INIT_WORK(&priv->reset_task, gfar_reset_task);

	platform_set_drvdata(ofdev, priv);

	gfar_detect_errata(priv);

	/* Stop the DMA engine now, in case it was running before
	 * (The firmware could have used it, and left it running).
	 */
	for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
		priv->gfargrp[grp_idx].num_rx_queues = 0x0;
	gfar_halt(priv);

		for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
				 priv->num_rx_queues) {
			priv->gfargrp[grp_idx].num_rx_queues++;
			priv->rx_queue[i]->grp = &priv->gfargrp[grp_idx];
			rstat = rstat | (RSTAT_CLEAR_RHALT >> i);
			rqueue = rqueue | ((RQUEUE_EN0 | RQUEUE_EX0) >> i);
		}
		priv->gfargrp[grp_idx].num_tx_queues = 0x0;
	gfar_hw_init(priv);

		for_each_set_bit(i, &priv->gfargrp[grp_idx].tx_bit_map,
				 priv->num_tx_queues) {
			priv->gfargrp[grp_idx].num_tx_queues++;
			priv->tx_queue[i]->grp = &priv->gfargrp[grp_idx];
			tstat = tstat | (TSTAT_CLEAR_THALT >> i);
			tqueue = tqueue | (TQUEUE_EN0 >> i);
	/* Set the dev->base_addr to the gfar reg region */
	dev->base_addr = (unsigned long) priv->gfargrp[0].regs;

	/* Fill in the dev structure */
	dev->watchdog_timeo = TX_TIMEOUT;
	dev->mtu = 1500;
	dev->netdev_ops = &gfar_netdev_ops;
	dev->ethtool_ops = &gfar_ethtool_ops;

	/* Register for napi ...We are registering NAPI for each grp */
	if (priv->mode == SQ_SG_MODE)
		netif_napi_add(dev, &priv->gfargrp[0].napi, gfar_poll_sq,
			       GFAR_DEV_WEIGHT);
	else
		for (i = 0; i < priv->num_grps; i++)
			netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll,
				       GFAR_DEV_WEIGHT);

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
		dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
				   NETIF_F_RXCSUM;
		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
				 NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
	}
		priv->gfargrp[grp_idx].rstat = rstat;
		priv->gfargrp[grp_idx].tstat = tstat;
		rstat = tstat =0;

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
		dev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
				    NETIF_F_HW_VLAN_CTAG_RX;
		dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
	}

	gfar_write(&regs->rqueue, rqueue);
	gfar_write(&regs->tqueue, tqueue);
	gfar_init_addr_hash_table(priv);

	/* Insert receive time stamps into padding alignment bytes */
	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
		priv->padding = 8;

	if (dev->features & NETIF_F_IP_CSUM ||
	    priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
		dev->needed_headroom = GMAC_FCB_LEN;

	priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;

@@ -1251,9 +1240,6 @@ static int gfar_probe(struct platform_device *ofdev)
	/* Initialize the filer table */
	gfar_init_filer_table(priv);

	/* Create all the sysfs files */
	gfar_init_sysfs(dev);

	/* Print out the device info */
	netdev_info(dev, "mac: %pM\n", dev->dev_addr);

@@ -1272,8 +1258,8 @@ static int gfar_probe(struct platform_device *ofdev)

register_fail:
	unmap_group_regs(priv);
	free_tx_pointers(priv);
	free_rx_pointers(priv);
	gfar_free_rx_queues(priv);
	gfar_free_tx_queues(priv);
	if (priv->phy_node)
		of_node_put(priv->phy_node);
	if (priv->tbi_node)
@@ -1293,6 +1279,8 @@ static int gfar_remove(struct platform_device *ofdev)

	unregister_netdev(priv->ndev);
	unmap_group_regs(priv);
	gfar_free_rx_queues(priv);
	gfar_free_tx_queues(priv);
	free_gfar_dev(priv);

	return 0;
@@ -1320,7 +1308,7 @@ static int gfar_suspend(struct device *dev)
		lock_tx_qs(priv);
		lock_rx_qs(priv);

		gfar_halt_nodisable(ndev);
		gfar_halt_nodisable(priv);

		/* Disable Tx, and Rx if wake-on-LAN is disabled. */
		tempval = gfar_read(&regs->maccfg1);
@@ -1384,7 +1372,7 @@ static int gfar_resume(struct device *dev)
	tempval &= ~MACCFG2_MPEN;
	gfar_write(&regs->maccfg2, tempval);

	gfar_start(ndev);
	gfar_start(priv);

	unlock_rx_qs(priv);
	unlock_tx_qs(priv);
@@ -1416,7 +1404,7 @@ static int gfar_restore(struct device *dev)
	init_registers(ndev);
	gfar_set_mac_address(ndev);
	gfar_init_mac(ndev);
	gfar_start(ndev);
	gfar_start(priv);

	priv->oldlink = 0;
	priv->oldspeed = 0;
@@ -1577,19 +1565,10 @@ static void gfar_configure_serdes(struct net_device *dev)
static void init_registers(struct net_device *dev)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar __iomem *regs = NULL;
	int i;

	for (i = 0; i < priv->num_grps; i++) {
		regs = priv->gfargrp[i].regs;
		/* Clear IEVENT */
		gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
	struct gfar __iomem *regs = priv->gfargrp[0].regs;

		/* Initialize IMASK */
		gfar_write(&regs->imask, IMASK_INIT_CLEAR);
	}
	gfar_ints_disable(priv);

	regs = priv->gfargrp[0].regs;
	/* Init hash registers to zero */
	gfar_write(&regs->igaddr0, 0);
	gfar_write(&regs->igaddr1, 0);
@@ -1648,23 +1627,13 @@ static int __gfar_is_rx_idle(struct gfar_private *priv)
}

/* Halt the receive and transmit queues */
static void gfar_halt_nodisable(struct net_device *dev)
static void gfar_halt_nodisable(struct gfar_private *priv)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar __iomem *regs = NULL;
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u32 tempval;
	int i;

	for (i = 0; i < priv->num_grps; i++) {
		regs = priv->gfargrp[i].regs;
		/* Mask all interrupts */
		gfar_write(&regs->imask, IMASK_INIT_CLEAR);

		/* Clear all interrupts */
		gfar_write(&regs->ievent, IEVENT_INIT_CLEAR);
	}
	gfar_ints_disable(priv);

	regs = priv->gfargrp[0].regs;
	/* Stop the DMA, and wait for it to stop */
	tempval = gfar_read(&regs->dmactrl);
	if ((tempval & (DMACTRL_GRS | DMACTRL_GTS)) !=
@@ -1685,15 +1654,20 @@ static void gfar_halt_nodisable(struct net_device *dev)
}

/* Halt the receive and transmit queues */
void gfar_halt(struct net_device *dev)
void gfar_halt(struct gfar_private *priv)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u32 tempval;

	gfar_halt_nodisable(dev);
	/* Dissable the Rx/Tx hw queues */
	gfar_write(&regs->rqueue, 0);
	gfar_write(&regs->tqueue, 0);

	/* Disable Rx and Tx */
	mdelay(10);

	gfar_halt_nodisable(priv);

	/* Disable Rx/Tx DMA */
	tempval = gfar_read(&regs->maccfg1);
	tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
	gfar_write(&regs->maccfg1, tempval);
@@ -1720,7 +1694,7 @@ void stop_gfar(struct net_device *dev)
	lock_tx_qs(priv);
	lock_rx_qs(priv);

	gfar_halt(dev);
	gfar_halt(priv);

	unlock_rx_qs(priv);
	unlock_tx_qs(priv);
@@ -1825,17 +1799,15 @@ static void free_skb_resources(struct gfar_private *priv)
			  priv->tx_queue[0]->tx_bd_dma_base);
}

void gfar_start(struct net_device *dev)
void gfar_start(struct gfar_private *priv)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u32 tempval;
	int i = 0;

	/* Enable Rx and Tx in MACCFG1 */
	tempval = gfar_read(&regs->maccfg1);
	tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
	gfar_write(&regs->maccfg1, tempval);
	/* Enable Rx/Tx hw queues */
	gfar_write(&regs->rqueue, priv->rqueue);
	gfar_write(&regs->tqueue, priv->tqueue);

	/* Initialize DMACTRL to have WWR and WOP */
	tempval = gfar_read(&regs->dmactrl);
@@ -1852,11 +1824,16 @@ void gfar_start(struct net_device *dev)
		/* Clear THLT/RHLT, so that the DMA starts polling now */
		gfar_write(&regs->tstat, priv->gfargrp[i].tstat);
		gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
		/* Unmask the interrupts we look for */
		gfar_write(&regs->imask, IMASK_DEFAULT);
	}

	dev->trans_start = jiffies; /* prevent tx timeout */
	/* Enable Rx/Tx DMA */
	tempval = gfar_read(&regs->maccfg1);
	tempval |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
	gfar_write(&regs->maccfg1, tempval);

	gfar_ints_enable(priv);

	priv->ndev->trans_start = jiffies; /* prevent tx timeout */
}

static void gfar_configure_coalescing(struct gfar_private *priv,
@@ -1960,15 +1937,10 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
int startup_gfar(struct net_device *ndev)
{
	struct gfar_private *priv = netdev_priv(ndev);
	struct gfar __iomem *regs = NULL;
	int err, i, j;

	for (i = 0; i < priv->num_grps; i++) {
		regs= priv->gfargrp[i].regs;
		gfar_write(&regs->imask, IMASK_INIT_CLEAR);
	}
	gfar_ints_disable(priv);

	regs= priv->gfargrp[0].regs;
	err = gfar_alloc_skb_resources(ndev);
	if (err)
		return err;
@@ -1985,7 +1957,7 @@ int startup_gfar(struct net_device *ndev)
	}

	/* Start the controller */
	gfar_start(ndev);
	gfar_start(priv);

	phy_start(priv->phydev);

+33 −11
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
 * Maintainer: Kumar Gala
 * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
 *
 * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
 * Copyright 2002-2009, 2011-2013 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
@@ -880,7 +880,6 @@ struct gfar {
#define FSL_GIANFAR_DEV_HAS_CSUM		0x00000010
#define FSL_GIANFAR_DEV_HAS_VLAN		0x00000020
#define FSL_GIANFAR_DEV_HAS_EXTENDED_HASH	0x00000040
#define FSL_GIANFAR_DEV_HAS_PADDING		0x00000080
#define FSL_GIANFAR_DEV_HAS_MAGIC_PACKET	0x00000100
#define FSL_GIANFAR_DEV_HAS_BD_STASHING		0x00000200
#define FSL_GIANFAR_DEV_HAS_BUF_STASHING	0x00000400
@@ -892,8 +891,8 @@ struct gfar {
#define DEFAULT_MAPPING 	0xFF
#endif

#define ISRG_SHIFT_TX	0x10
#define ISRG_SHIFT_RX	0x18
#define ISRG_RR0	0x80000000
#define ISRG_TR0	0x00800000

/* The same driver can operate in two modes */
/* SQ_SG_MODE: Single Queue Single Group Mode
@@ -1113,6 +1112,9 @@ struct gfar_private {
	unsigned int total_tx_ring_size;
	unsigned int total_rx_ring_size;

	u32 rqueue;
	u32 tqueue;

	/* RX per device parameters */
	unsigned int rx_stash_size;
	unsigned int rx_stash_index;
@@ -1127,11 +1129,6 @@ struct gfar_private {
	u32 __iomem *hash_regs[16];
	int hash_width;

	/* global parameters */
	unsigned int fifo_threshold;
	unsigned int fifo_starve;
	unsigned int fifo_starve_off;

	/*Filer table*/
	unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
	unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
@@ -1176,6 +1173,31 @@ static inline void gfar_read_filer(struct gfar_private *priv,
	*fpr = gfar_read(&regs->rqfpr);
}

static inline void gfar_write_isrg(struct gfar_private *priv)
{
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u32 __iomem *baddr = &regs->isrg0;
	u32 isrg = 0;
	int grp_idx, i;

	for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
		struct gfar_priv_grp *grp = &priv->gfargrp[grp_idx];

		for_each_set_bit(i, &grp->rx_bit_map, priv->num_rx_queues) {
			isrg |= (ISRG_RR0 >> i);
		}

		for_each_set_bit(i, &grp->tx_bit_map, priv->num_tx_queues) {
			isrg |= (ISRG_TR0 >> i);
		}

		gfar_write(baddr, isrg);

		baddr++;
		isrg = 0;
	}
}

void lock_rx_qs(struct gfar_private *priv);
void lock_tx_qs(struct gfar_private *priv);
void unlock_rx_qs(struct gfar_private *priv);
@@ -1183,11 +1205,11 @@ void unlock_tx_qs(struct gfar_private *priv);
irqreturn_t gfar_receive(int irq, void *dev_id);
int startup_gfar(struct net_device *dev);
void stop_gfar(struct net_device *dev);
void gfar_halt(struct net_device *dev);
void gfar_halt(struct gfar_private *priv);
void gfar_start(struct gfar_private *priv);
void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, int enable,
		   u32 regnum, u32 read);
void gfar_configure_coalescing_all(struct gfar_private *priv);
void gfar_init_sysfs(struct net_device *dev);
int gfar_set_features(struct net_device *dev, netdev_features_t features);
void gfar_check_rx_parser_mode(struct gfar_private *priv);
void gfar_vlan_mode(struct net_device *dev, netdev_features_t features);
Loading