[PATCH 03/12] fec: do not typedef struct types

Previous thread: none

Next thread: Acai Berry , Flush out toxins, reduce Cho by Bingham on Tuesday, April 14, 2009 - 11:49 am. (1 message)
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Hi,

These patches aim to modernize the FEC ethernet driver.
Greg, can you please confirm that the ifdef in patch 01/12 is indeed unused?

Sascha

The following changes since commit 0882e8dd3aad33eca41696d463bb896e6c8817eb:
  Linus Torvalds (1):
        Linux 2.6.30-rc2

are available in the git repository at:

  git://git.pengutronix.de/git/sha/linux-2.6.git fec

Sascha Hauer (12):
      fec: remove unused ifdef
      fec: switch to writel/readl
      fec: do not typedef struct types
      fec: remove unnecessary cast
      fec: Codingstyle cleanups
      fec: refactor set_multicast_list() to make it more readable
      fec: refactor init function
      fec: align receive packets
      fec: remove debugging printks
      fec: switch to net_device_ops
      FEC Buffer rework
      fec: call fec_restart() in fec_open()

 drivers/net/fec.c |  897 ++++++++++++++++++++++-------------------------------
 drivers/net/fec.h |  112 ++-----
 2 files changed, 402 insertions(+), 607 deletions(-)
--

From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.h |   44 --------------------------------------------
 1 files changed, 0 insertions(+), 44 deletions(-)

diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 76c64c9..c2f97f3 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -13,8 +13,6 @@
 #define	FEC_H
 /****************************************************************************/
 
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
@@ -58,48 +56,6 @@ typedef struct fec {
 	unsigned long	fec_r_buff_size;	/* Maximum receive buff size */
 } fec_t;
 
-#else
-
-/*
- *	Define device register set address map.
- */
-typedef struct fec {
-	unsigned long	fec_ecntrl;		/* Ethernet control reg */
-	unsigned long	fec_ievent;		/* Interrupt even reg */
-	unsigned long	fec_imask;		/* Interrupt mask reg */
-	unsigned long	fec_ivec;		/* Interrupt vec status reg */
-	unsigned long	fec_r_des_active;	/* Receive descriptor reg */
-	unsigned long	fec_x_des_active;	/* Transmit descriptor reg */
-	unsigned long	fec_reserved1[10];
-	unsigned long	fec_mii_data;		/* MII manage frame reg */
-	unsigned long	fec_mii_speed;		/* MII speed control reg */
-	unsigned long	fec_reserved2[17];
-	unsigned long	fec_r_bound;		/* FIFO receive bound reg */
-	unsigned long	fec_r_fstart;		/* FIFO receive start reg */
-	unsigned long	fec_reserved3[4];
-	unsigned long	fec_x_wmrk;		/* FIFO transmit water mark */
-	unsigned long	fec_reserved4;
-	unsigned long	fec_x_fstart;		/* FIFO transmit start reg */
-	unsigned long	fec_reserved5[21];
-	unsigned long	fec_r_cntrl;		/* Receive control reg */
-	unsigned long	fec_max_frm_len;	/* Maximum frame length reg */
-	unsigned long	fec_reserved6[14];
-	unsigned long	fec_x_cntrl;		/* Transmit ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |  279 ++++++++++++++++++++++-------------------------------
 drivers/net/fec.h |   60 +++++-------
 2 files changed, 138 insertions(+), 201 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 682e7f0..3fa3fe4 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -165,7 +165,7 @@ typedef struct {
  */
 struct fec_enet_private {
 	/* Hardware registers of the FEC device */
-	volatile fec_t	*hwp;
+	void __iomem *hwp;
 
 	struct net_device *netdev;
 
@@ -288,15 +288,11 @@ static int	mii_queue(struct net_device *dev, int request,
 static int
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct fec_enet_private *fep;
-	volatile fec_t	*fecp;
+	struct fec_enet_private *fep = netdev_priv(dev);
 	volatile cbd_t	*bdp;
 	unsigned short	status;
 	unsigned long flags;
 
-	fep = netdev_priv(dev);
-	fecp = (volatile fec_t*)dev->base_addr;
-
 	if (!fep->link) {
 		/* Link is down or autonegotiation is in progress. */
 		return 1;
@@ -363,7 +359,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 
 	/* Trigger transmission start */
-	fecp->fec_x_des_active = 0;
+	writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
 	/* If this was the last BD in the ring, start at the beginning again.
 	*/
@@ -436,29 +432,25 @@ static irqreturn_t
 fec_enet_interrupt(int irq, void * dev_id)
 {
 	struct	net_device *dev = dev_id;
-	volatile fec_t	*fecp;
+	struct fec_enet_private *fep = netdev_priv(dev);
 	uint	int_events;
 	irqreturn_t ret = IRQ_NONE;
 
-	fecp = (volatile fec_t*)dev->base_addr;
-
-	/* Get the interrupt events that caused us to be here.
-	*/
+	/* Get the interrupt events that caused us to be here. */
 	do {
-		int_events = fecp->fec_ievent;
-		fecp->fec_ievent = int_events;
+		int_events = readl(fep->hwp + FEC_IEVENT);
+		writel(int_events, fep->hwp + FEC_IEVENT);
 
-		/* Handle receive event in its own ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |   37 ++++++++++++++++++++-----------------
 drivers/net/fec.h |    8 ++++----
 2 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 3fa3fe4..fea8e27 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -180,10 +180,14 @@ struct fec_enet_private {
 	/* CPM dual port RAM relative addresses.
 	*/
 	dma_addr_t	bd_dma;
-	cbd_t	*rx_bd_base;		/* Address of Rx and Tx buffers. */
-	cbd_t	*tx_bd_base;
-	cbd_t	*cur_rx, *cur_tx;		/* The next free ring entry */
-	cbd_t	*dirty_tx;	/* The ring entries to be free()ed. */
+	/* Address of Rx and Tx buffers. */
+	struct bufdesc	*rx_bd_base;
+	struct bufdesc	*tx_bd_base;
+	/* The next free ring entry */
+	struct bufdesc	*cur_rx, *cur_tx; 
+	/* The ring entries to be free()ed. */
+	struct bufdesc	*dirty_tx;
+
 	uint	tx_full;
 	/* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
 	spinlock_t hw_lock;
@@ -289,7 +293,7 @@ static int
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
-	volatile cbd_t	*bdp;
+	struct bufdesc *bdp;
 	unsigned short	status;
 	unsigned long flags;
 
@@ -374,7 +378,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(dev);
 	}
 
-	fep->cur_tx = (cbd_t *)bdp;
+	fep->cur_tx = bdp;
 
 	spin_unlock_irqrestore(&fep->hw_lock, flags);
 
@@ -391,7 +395,7 @@ fec_timeout(struct net_device *dev)
 #ifndef final_version
 	{
 	int	i;
-	cbd_t	*bdp;
+	struct bufdesc *bdp;
 
 	printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
 	       (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
@@ -471,7 +475,7 @@ static void
 fec_enet_tx(struct net_device *dev)
 {
 	struct	fec_enet_private *fep;
-	volatile cbd_t	*bdp;
+	struct bufdesc *bdp;
 	unsigned short status;
 	struct	sk_buff	*skb;
 
@@ -534,7 +538,7 @@ fec_enet_tx(struct ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |   14 +++++---------
 1 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index fea8e27..3a43d96 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1661,11 +1661,10 @@ int __init fec_enet_init(struct net_device *dev, int index)
 	struct bufdesc *bdp, *cbd_base;
 	int 		i, j;
 
-	/* Allocate memory for buffer descriptors.
-	*/
-	mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
-			&fep->bd_dma, GFP_KERNEL);
-	if (mem_addr == 0) {
+	/* Allocate memory for buffer descriptors. */
+	cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
+			GFP_KERNEL);
+	if (!cbd_base) {
 		printk("FEC: allocate descriptor memory failed?\n");
 		return -ENOMEM;
 	}
@@ -1699,10 +1698,7 @@ int __init fec_enet_init(struct net_device *dev, int index)
 	}
 #endif
 
-	cbd_base = (struct bufdesc *)mem_addr;
-
-	/* Set receive and transmit descriptor base.
-	*/
+	/* Set receive and transmit descriptor base. */
 	fep->rx_bd_base = cbd_base;
 	fep->tx_bd_base = cbd_base + RX_RING_SIZE;
 
-- 
1.6.2.1

--

From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |  354 +++++++++++++++++++++--------------------------------
 1 files changed, 139 insertions(+), 215 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 3a43d96..ab8e66b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -86,8 +86,7 @@ static unsigned char	fec_mac_default[] = {
 #endif
 #endif /* CONFIG_M5272 */
 
-/* Forward declarations of some structures to support different PHYs
-*/
+/* Forward declarations of some structures to support different PHYs */
 
 typedef struct {
 	uint mii_data;
@@ -123,8 +122,7 @@ typedef struct {
 #error "FEC: descriptor ring size constants too large"
 #endif
 
-/* Interrupt events/masks.
-*/
+/* Interrupt events/masks. */
 #define FEC_ENET_HBERR	((uint)0x80000000)	/* Heartbeat error */
 #define FEC_ENET_BABR	((uint)0x40000000)	/* Babbling receiver */
 #define FEC_ENET_BABT	((uint)0x20000000)	/* Babbling transmitter */
@@ -177,15 +175,14 @@ struct fec_enet_private {
 	ushort	skb_cur;
 	ushort	skb_dirty;
 
-	/* CPM dual port RAM relative addresses.
-	*/
+	/* CPM dual port RAM relative addresses */
 	dma_addr_t	bd_dma;
-	/* Address of Rx and Tx buffers. */
+	/* Address of Rx and Tx buffers */
 	struct bufdesc	*rx_bd_base;
 	struct bufdesc	*tx_bd_base;
 	/* The next free ring entry */
 	struct bufdesc	*cur_rx, *cur_tx; 
-	/* The ring entries to be free()ed. */
+	/* The ring entries to be free()ed */
 	struct bufdesc	*dirty_tx;
 
 	uint	tx_full;
@@ -245,19 +242,16 @@ static mii_list_t	*mii_tail;
 static int	mii_queue(struct net_device *dev, int request,
 				void (*func)(uint, struct net_device *));
 
-/* Make MII read/write commands for the FEC.
-*/
+/* Make MII read/write commands for the FEC */
 #define mk_mii_read(REG)	(0x60020000 | ((REG & 0x1f) << 18))
 #define mk_mii_write(REG, VAL)	(0x50020000 | ((REG & 0x1f) << 18) | \
 						(VAL & 0xffff))
 #define mk_mii_end	0
 
-/* Transmitter timeout.
-*/
-#define ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |   99 +++++++++++++++++++++++++++-------------------------
 1 files changed, 51 insertions(+), 48 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index ab8e66b..b72df48 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1518,57 +1518,60 @@ static void set_multicast_list(struct net_device *dev)
 		tmp = readl(fep->hwp + FEC_R_CNTRL);
 		tmp |= 0x8;
 		writel(tmp, fep->hwp + FEC_R_CNTRL);
-	} else {
-		tmp = readl(fep->hwp + FEC_R_CNTRL);
-		tmp &= ~0x8;
-		writel(tmp, fep->hwp + FEC_R_CNTRL);
+		return;
+	}
 
-		if (dev->flags & IFF_ALLMULTI) {
-			/* Catch all multicast addresses, so set the
-			 * filter to all 1's
-			 */
-			writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
-			writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
-		} else {
-			/* Clear filter and add the addresses in hash register
-			 */
-			writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
-			writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
-
-			dmi = dev->mc_list;
-
-			for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
-				/* Only support group multicast for now */
-				if (!(dmi->dmi_addr[0] & 1))
-					continue;
-
-				/* calculate crc32 value of mac address */
-				crc = 0xffffffff;
-
-				for (i = 0; i < dmi->dmi_addrlen; i++) {
-					data = dmi->dmi_addr[i];
-					for (bit = 0; bit < 8; bit++, data >>= 1) {
-						crc = (crc >> 1) ^
-						(((crc ^ data) & 1) ? CRC32_POLY : 0);
-					}
-				}
-
-				/* only upper 6 bits (HASH_BITS) are used
-				 * which point to specific bit in he hash registers
-				 */
-				hash = (crc >> (32 - HASH_BITS)) & 0x3f;
-
-				if (hash > 31) {
-					tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
-					tmp |= 1 << (hash - 32);
-					writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
-				} else {
-					tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
-					tmp |= 1 << hash;
-					writel(tmp, fep->hwp + ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

fec_enet_init() does the hardware initialisation and then calls
fec_restart() which does the same initialisation again, so we
can safely remove the initialisation from fec_enet_init().

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |   39 ++++-----------------------------------
 1 files changed, 4 insertions(+), 35 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index b72df48..a3037ab 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1616,10 +1616,6 @@ int __init fec_enet_init(struct net_device *dev, int index)
 	fep->hwp = (void __iomem *)dev->base_addr;
 	fep->netdev = dev;
 
-	/* Whack a reset.  We should wait for this. */
-	writel(1, fep->hwp + FEC_ECNTRL);
-	udelay(10);
-
 	/* Set the Ethernet address */
 #ifdef CONFIG_M5272
 	fec_get_mac(dev);
@@ -1641,11 +1637,6 @@ int __init fec_enet_init(struct net_device *dev, int index)
 	fep->rx_bd_base = cbd_base;
 	fep->tx_bd_base = cbd_base + RX_RING_SIZE;
 
-	fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
-	fep->cur_rx = fep->rx_bd_base;
-
-	fep->skb_cur = fep->skb_dirty = 0;
-
 	/* Initialize the receive buffer descriptors. */
 	bdp = fep->rx_bd_base;
 	for (i=0; i<FEC_ENET_RX_PAGES; i++) {
@@ -1689,25 +1680,9 @@ int __init fec_enet_init(struct net_device *dev, int index)
 	bdp--;
 	bdp->cbd_sc |= BD_SC_WRAP;
 
-	/* Set receive and transmit descriptor base */
-	writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
-	writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
-			fep->hwp + FEC_X_DES_START);
-
 #ifdef HAVE_mii_link_interrupt
 	fec_request_mii_intr(dev);
 #endif
-
-	writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
-	writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
-	writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
-	writel(2, fep->hwp + FEC_ECNTRL);
-	writel(0, fep->hwp + FEC_R_DES_ACTIVE);
-#ifndef CONFIG_M5272
-	writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
-	writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
-#endif
-
 	/* The FEC ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Otherwise we get a lot of alignment errors

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index a3037ab..be3226c 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -598,13 +598,14 @@ fec_enet_rx(struct net_device *dev)
 		 * include that when passing upstream as it messes up
 		 * bridging applications.
 		 */
-		skb = dev_alloc_skb(pkt_len - 4);
+		skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN);
 
-		if (skb == NULL) {
+		if (unlikely(!skb)) {
 			printk("%s: Memory squeeze, dropping packet.\n",
 					dev->name);
 			dev->stats.rx_dropped++;
 		} else {
+			skb_reserve(skb, NET_IP_ALIGN);
 			skb_put(skb, pkt_len - 4);	/* Make room */
 			skb_copy_to_linear_data(skb, data, pkt_len - 4);
 			skb->protocol = eth_type_trans(skb, dev);
-- 
1.6.2.1

--

From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

These printks in fec_timeout do not give useful information in
a production kernel.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |   33 ---------------------------------
 1 files changed, 0 insertions(+), 33 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index be3226c..d96aba9 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -377,41 +377,8 @@ fec_timeout(struct net_device *dev)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 
-	printk("%s: transmit timed out.\n", dev->name);
 	dev->stats.tx_errors++;
-#ifndef final_version
-	{
-	int	i;
-	struct bufdesc *bdp;
-
-	printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
-	       (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
-	       (unsigned long)fep->dirty_tx,
-	       (unsigned long)fep->cur_rx);
-
-	bdp = fep->tx_bd_base;
-	printk(" tx: %u buffers\n",  TX_RING_SIZE);
-	for (i = 0 ; i < TX_RING_SIZE; i++) {
-		printk("  %08x: %04x %04x %08x\n",
-		       (uint) bdp,
-		       bdp->cbd_sc,
-		       bdp->cbd_datlen,
-		       (int) bdp->cbd_bufaddr);
-		bdp++;
-	}
 
-	bdp = fep->rx_bd_base;
-	printk(" rx: %lu buffers\n",  (unsigned long) RX_RING_SIZE);
-	for (i = 0 ; i < RX_RING_SIZE; i++) {
-		printk("  %08x: %04x %04x %08x\n",
-		       (uint) bdp,
-		       bdp->cbd_sc,
-		       bdp->cbd_datlen,
-		       (int) bdp->cbd_bufaddr);
-		bdp++;
-	}
-	}
-#endif
 	fec_restart(dev, fep->full_duplex);
 	netif_wake_queue(dev);
 }
-- 
1.6.2.1

--

From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |   36 ++++++++++++++++++++----------------
 1 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index d96aba9..f4afbe9 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -210,17 +210,13 @@ struct fec_enet_private {
 	int	full_duplex;
 };
 
-static int fec_enet_open(struct net_device *dev);
-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void fec_enet_mii(struct net_device *dev);
 static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
 static void fec_enet_tx(struct net_device *dev);
 static void fec_enet_rx(struct net_device *dev);
 static int fec_enet_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
 static void fec_restart(struct net_device *dev, int duplex);
 static void fec_stop(struct net_device *dev);
-static void fec_set_mac_address(struct net_device *dev);
 
 
 /* MII processing.  We keep this as simple as possible.  Requests are
@@ -1411,7 +1407,6 @@ fec_enet_open(struct net_device *dev)
 	/* I should reset the ring buffers here, but I don't yet know
 	 * a simple way to do that.
 	 */
-	fec_set_mac_address(dev);
 
 	fep->sequence_done = 0;
 	fep->link = 0;
@@ -1544,19 +1539,35 @@ static void set_multicast_list(struct net_device *dev)
 }
 
 /* Set a MAC change in hardware. */
-static void
-fec_set_mac_address(struct net_device *dev)
+static int
+fec_set_mac_address(struct net_device *dev, void *p)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-	/* Set station address. */
 	writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
 		(dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
 		fep->hwp + FEC_ADDR_LOW);
 	writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

Allocate buffers in fec_open and free them again in fec_close. This makes
it possible to use this driver as a module.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |  139 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 88 insertions(+), 51 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index f4afbe9..0e1d268 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -172,6 +172,7 @@ struct fec_enet_private {
 	/* The saved address of a sent-in-place packet/buffer, for skfree(). */
 	unsigned char *tx_bounce[TX_RING_SIZE];
 	struct	sk_buff* tx_skbuff[TX_RING_SIZE];
+	struct	sk_buff* rx_skbuff[RX_RING_SIZE];
 	ushort	skb_cur;
 	ushort	skb_dirty;
 
@@ -335,8 +336,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Push the data cache so the CPM does not get stale memory
 	 * data.
 	 */
-	dma_sync_single(NULL, bdp->cbd_bufaddr,
-			bdp->cbd_datlen, DMA_TO_DEVICE);
+	bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+			FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
 
 	/* Send it on its way.  Tell FEC it's ready, interrupt when done,
 	 * it's the last BD of the frame, and to put the CRC on the end.
@@ -429,7 +430,11 @@ fec_enet_tx(struct net_device *dev)
 	bdp = fep->dirty_tx;
 
 	while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
-		if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+		if (bdp == fep->cur_tx && fep->tx_full == 0)
+			break;
+
+		dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+		bdp->cbd_bufaddr = 0;
 
 		skb = fep->tx_skbuff[fep->skb_dirty];
 		/* Check for errors. */
@@ -553,8 +558,8 @@ fec_enet_rx(struct net_device *dev)
 		dev->stats.rx_bytes += pkt_len;
 		data = (__u8*)__va(bdp->cbd_bufaddr);
 
-		dma_sync_single(NULL, (unsigned long)__pa(data),
-			pkt_len - 4, DMA_FROM_DEVICE);
+	        dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
+        			DMA_FROM_DEVICE);
 
 		/* This does 16 byte ...
From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 4:32 am

We called fec_stop() in fec_enet_close(), thus we have to call
fec_restart() in fec_enet_open().

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |   18 ++++++++----------
 1 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 0e1d268..28db691 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1490,6 +1490,8 @@ fec_enet_open(struct net_device *dev)
 	fep->sequence_done = 0;
 	fep->link = 0;
 
+	fec_restart(dev, 1);
+
 	if (fep->phy) {
 		mii_do_cmd(dev, fep->phy->ack_int);
 		mii_do_cmd(dev, fep->phy->config);
@@ -1506,18 +1508,14 @@ fec_enet_open(struct net_device *dev)
 			schedule();
 
 		mii_do_cmd(dev, fep->phy->startup);
-
-		/* Set the initial link state to true. A lot of hardware
-		 * based on this device does not implement a PHY interrupt,
-		 * so we are never notified of link change.
-		 */
-		fep->link = 1;
-	} else {
-		fep->link = 1; /* lets just try it and see */
-		/* no phy,  go full duplex,  it's most likely a hub chip */
-		fec_restart(dev, 1);
 	}
 
+	/* Set the initial link state to true. A lot of hardware
+	 * based on this device does not implement a PHY interrupt,
+	 * so we are never notified of link change.
+	 */
+	fep->link = 1;
+
 	netif_start_queue(dev);
 	fep->opened = 1;
 	return 0;
-- 
1.6.2.1

--

From: David Miller
Date: Thursday, April 16, 2009 - 2:38 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:38 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: Greg Ungerer
Date: Friday, April 17, 2009 - 3:07 am

Hi Sascha,


This is the only one that doesn't work for ColdFire. There is no
dma_map_single() or dma_unmap_single() currently. I will fix that,
so I am fine with this anyways.

With all the other patches applied it still basically works on ColdFire
(at least on initial testing on a 5208). I have seen a few spurious
interrupts though with these changes applied, that didn't happen
before. I will investigate further when get a few minutes.

Regards


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
825 Stanley St,                             FAX:         +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia         WEB: http://www.SnapGear.com
--

From: Sascha Hauer
Date: Friday, April 17, 2009 - 3:12 am

Ok, thanks for testing

Regards,
  Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:37 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:37 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:37 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:37 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:37 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:36 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:36 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: David Miller
Date: Thursday, April 16, 2009 - 2:36 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 6:11 am

Since the second register set is used for M5272 we cannot remove it.
Here is an updated version.

Sascha


From 4330c85a8902007a6fb726333a85b9e981579992 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Wed, 15 Apr 2009 09:51:34 +0200
Subject: [PATCH 01/11] fec: switch to writel/readl

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/net/fec.c |  279 ++++++++++++++++++++++-------------------------------
 drivers/net/fec.h |  119 +++++++++--------------
 2 files changed, 161 insertions(+), 237 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 682e7f0..3fa3fe4 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -165,7 +165,7 @@ typedef struct {
  */
 struct fec_enet_private {
 	/* Hardware registers of the FEC device */
-	volatile fec_t	*hwp;
+	void __iomem *hwp;
 
 	struct net_device *netdev;
 
@@ -288,15 +288,11 @@ static int	mii_queue(struct net_device *dev, int request,
 static int
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct fec_enet_private *fep;
-	volatile fec_t	*fecp;
+	struct fec_enet_private *fep = netdev_priv(dev);
 	volatile cbd_t	*bdp;
 	unsigned short	status;
 	unsigned long flags;
 
-	fep = netdev_priv(dev);
-	fecp = (volatile fec_t*)dev->base_addr;
-
 	if (!fep->link) {
 		/* Link is down or autonegotiation is in progress. */
 		return 1;
@@ -363,7 +359,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 
 	/* Trigger transmission start */
-	fecp->fec_x_des_active = 0;
+	writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
 	/* If this was the last BD in the ring, start at the beginning again.
 	*/
@@ -436,29 +432,25 @@ static irqreturn_t
 fec_enet_interrupt(int irq, void * dev_id)
 {
 	struct	net_device *dev = dev_id;
-	volatile fec_t	*fecp;
+	struct fec_enet_private *fep = netdev_priv(dev);
 	uint	int_events;
 	irqreturn_t ret = IRQ_NONE;
 
-	fecp = (volatile fec_t*)dev->base_addr;
-
-	/* ...
From: David Miller
Date: Thursday, April 16, 2009 - 2:36 am

From: Sascha Hauer <s.hauer@pengutronix.de>

Applied.
--

From: Greg Ungerer
Date: Wednesday, April 15, 2009 - 5:12 am

Hi Sascha,


It is used for the CONFIG_M5272 case. The offsets to some registers
are slightly different for the version of the FEC hardware in that
SoC CPU.

Regards


-- 
------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg@snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
825 Stanley St,                             FAX:         +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia         WEB: http://www.SnapGear.com
--

From: Sascha Hauer
Date: Wednesday, April 15, 2009 - 5:55 am

Ok, then I'll skip the first patch and update the second one
accordingly.

Regards

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
--

Previous thread: none

Next thread: Acai Berry , Flush out toxins, reduce Cho by Bingham on Tuesday, April 14, 2009 - 11:49 am. (1 message)