lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1231949353-29630-7-git-send-email-s.hauer@pengutronix.de>
Date:	Wed, 14 Jan 2009 17:09:13 +0100
From:	Sascha Hauer <s.hauer@...gutronix.de>
To:	netdev@...r.kernel.org
Cc:	Sebastian Siewior <bigeasy@...utronix.de>,
	Greg Ungerer <gerg@...inux.org>,
	Sascha Hauer <s.hauer@...gutronix.de>
Subject: [PATCH] fec: Add mx2 support (WIP)

Signed-off-by: Sascha Hauer <s.hauer@...gutronix.de>
---
 drivers/net/Kconfig |    2 +-
 drivers/net/fec.c   |  121 +++++++++++++++++++++++++++++++++++++++++++++++++--
 drivers/net/fec.h   |   11 ++++-
 3 files changed, 127 insertions(+), 7 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9fe8cb7..5333e65 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1829,7 +1829,7 @@ config 68360_ENET
 
 config FEC
 	bool "FEC ethernet controller (of ColdFire CPUs)"
-	depends on M523x || M527x || M5272 || M528x || M520x
+	depends on M523x || M527x || M5272 || M528x || M520x || ARCH_MX2
 	help
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire processors.
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 81c8e11..a3e5b63 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -38,10 +38,14 @@
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/clk.h>
 
 #include <asm/cacheflush.h>
+
+#ifndef CONFIG_ARCH_MX2
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
+#endif
 
 #include "fec.h"
 
@@ -51,6 +55,13 @@
 #define	FEC_MAX_PORTS	1
 #endif
 
+#ifdef CONFIG_ARCH_MX2
+#include <mach/hardware.h>
+#define FEC_ALIGNMENT	0xf
+#else
+#define FEC_ALIGNMENT	0x3
+#endif
+
 #if defined(CONFIG_M5272)
 #define HAVE_mii_link_interrupt
 #endif
@@ -70,6 +81,8 @@ static unsigned int fec_hw[] = {
 	(MCF_MBAR+0x30000),
 #elif defined(CONFIG_M532x)
 	(MCF_MBAR+0xfc030000),
+#elif defined(CONFIG_ARCH_MX2)
+	(unsigned int)IO_ADDRESS(FEC_BASE_ADDR),
 #endif
 };
 
@@ -156,7 +169,7 @@ typedef struct {
  * account when setting it.
  */
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MX2)
 #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
 #else
 #define	OPT_FRAME_SIZE	0
@@ -337,7 +350,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	 *	4-byte boundaries. Use bounce buffers to copy data
 	 *	and get it aligned. Ugh.
 	 */
-	if (bdp->cbd_bufaddr & 0x3) {
+	if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
 		unsigned int index;
 		index = bdp - fep->tx_bd_base;
 		memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len);
@@ -354,8 +367,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.
 	 */
-	flush_dcache_range((unsigned long)skb->data,
-			   (unsigned long)skb->data + skb->len);
+	dma_sync_single(NULL, bdp->cbd_bufaddr,
+			bdp->cbd_datlen, 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.
@@ -628,6 +641,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
 	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);
+
 	/* This does 16 byte alignment, exactly what we need.
 	 * The packet length includes FCS, but we don't want to
 	 * include that when passing upstream as it messes up
@@ -1109,7 +1125,14 @@ static phy_info_t const phy_info_am79c874 = {
 /* register definitions for the 8721 */
 
 #define MII_KS8721BL_RXERCR	21
+#ifdef CONFIG_ARCH_MX2
+ /* FIXME: is this a bug or board specific?
+  * 27 was found somewhere in the Freescale code
+  */
+#define MII_KS8721BL_ICSR	27
+#else
 #define MII_KS8721BL_ICSR	22
+#endif
 #define	MII_KS8721BL_PHYCR	31
 
 static phy_cmd_t const phy_cmd_ks8721bl_config[] = {
@@ -1698,6 +1721,95 @@ static void __inline__ fec_phy_ack_intr(void)
 {
 }
 
+#elif defined(CONFIG_ARCH_MX2)
+
+/*
+ * do some initializtion based architecture of this chip
+ */
+static void inline fec_arch_init(void)
+{
+	struct clk *clk;
+	clk = clk_get(NULL, "fec_clk");
+	clk_enable(clk);
+	clk_put(clk);
+	return;
+}
+
+/*
+ * Code specific to Freescale i.MXC
+ */
+static void inline fec_request_intrs(struct net_device *dev)
+{
+	/* Setup interrupt handlers. */
+	if (request_irq(MXC_INT_FEC, fec_enet_interrupt, 0, "fec", dev) != 0)
+		panic("FEC: Could not allocate FEC IRQ(%d)!\n", MXC_INT_FEC);
+}
+
+static void inline fec_set_mii(struct net_device *dev,
+				   struct fec_enet_private *fep)
+{
+	u32 rate;
+	struct clk *clk;
+	volatile fec_t *fecp;
+	fecp = fep->hwp;
+	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+	fecp->fec_x_cntrl = 0x00;
+
+	/*
+	 * Set MII speed to 2.5 MHz
+	 */
+	clk = clk_get(NULL, "fec_clk");
+	rate = clk_get_rate(clk);
+	clk_put(clk);
+
+	fep->phy_speed = ((((rate / 2 + 4999999) / 2500000) / 2) & 0x3F) << 1;
+	fecp->fec_mii_speed = fep->phy_speed;
+	fec_restart(dev, 0);
+}
+
+static void inline fec_get_mac(struct net_device *dev)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+	volatile fec_t *fecp;
+	unsigned char *iap, tmpaddr[ETH_ALEN];
+	int i;
+	unsigned long l;
+	unsigned char mac_preinitialized = 0;
+	fecp = fep->hwp;
+
+	/* check if mac address was already initialized by firmware */
+	l = fecp->fec_addr_low;
+	tmpaddr[0] = (unsigned char)((l & 0xFF000000) >> 24);
+	tmpaddr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
+	tmpaddr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
+	tmpaddr[3] = (unsigned char)((l & 0x000000FF) >> 0);
+	l = fecp->fec_addr_high;
+	tmpaddr[4] = (unsigned char)((l & 0xFF000000) >> 24);
+	tmpaddr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
+
+	for (i = 0; i < ETH_ALEN; i++)
+		mac_preinitialized |= tmpaddr[i];
+
+	if (mac_preinitialized) {
+		iap = &tmpaddr[0];
+		memcpy(dev->dev_addr, iap, ETH_ALEN);
+	}
+}
+
+static void inline fec_disable_phy_intr(void)
+{
+}
+
+static void inline fec_phy_ack_intr(void)
+{
+}
+
+static void inline fec_localhw_setup(void)
+{
+}
+
+/* ------------------------------------------------------------------------- */
+
 #endif
 
 /* ------------------------------------------------------------------------- */
@@ -2404,6 +2516,7 @@ static int __init fec_enet_module_init(void)
 	int i, err;
 
 	printk("FEC ENET Version 0.2\n");
+	fec_arch_init();
 
 	for (i = 0; (i < FEC_MAX_PORTS); i++) {
 		dev = alloc_etherdev(sizeof(struct fec_enet_private));
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 292719d..ca36ea0 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,7 @@
 /****************************************************************************/
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
-    defined(CONFIG_M520x) || defined(CONFIG_M532x)
+    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MX2)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
@@ -103,12 +103,19 @@ typedef struct fec {
 /*
  *	Define the buffer descriptor structure.
  */
+#ifdef CONFIG_ARCH_MXC
+typedef struct bufdesc {
+	unsigned short cbd_datlen;	/* Data length */
+	unsigned short cbd_sc;	/* Control and status info */
+	unsigned long cbd_bufaddr;	/* Buffer address */
+} cbd_t;
+#else
 typedef struct bufdesc {
 	unsigned short	cbd_sc;			/* Control and status info */
 	unsigned short	cbd_datlen;		/* Data length */
 	unsigned long	cbd_bufaddr;		/* Buffer address */
 } cbd_t;
-
+#endif
 
 /*
  *	The following definitions courtesy of commproc.h, which where
-- 
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ