use broken-out patches for the coldfire to make it easier to follow differences against the bsp
SVN-Revision: 16547
This commit is contained in:
392
target/linux/coldfire/patches/010-m5445x_fec.patch
Normal file
392
target/linux/coldfire/patches/010-m5445x_fec.patch
Normal file
@@ -0,0 +1,392 @@
|
||||
From c562ab80fe383e6fa49dbe38257421cf37f0e4b3 Mon Sep 17 00:00:00 2001
|
||||
From: Kurt Mahan <kmahan@freescale.com>
|
||||
Date: Wed, 31 Oct 2007 17:07:25 -0600
|
||||
Subject: [PATCH] MCF5445x FEC support.
|
||||
|
||||
LTIBName: m5445x-fec
|
||||
Signed-off-by: Kurt Mahan <kmahan@freescale.com>
|
||||
---
|
||||
drivers/net/Kconfig | 8 ++-
|
||||
drivers/net/fec.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
drivers/net/fec.h | 2 +-
|
||||
3 files changed, 198 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/drivers/net/Kconfig
|
||||
+++ b/drivers/net/Kconfig
|
||||
@@ -1973,7 +1973,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 || M54455
|
||||
help
|
||||
Say Y here if you want to use the built-in 10/100 Fast ethernet
|
||||
controller on some Motorola ColdFire processors.
|
||||
@@ -1985,6 +1985,12 @@ config FEC2
|
||||
Say Y here if you want to use the second built-in 10/100 Fast
|
||||
ethernet controller on some Motorola ColdFire processors.
|
||||
|
||||
+config FEC_SHARED_PHY
|
||||
+ bool "Shared PHY interface(on some ColdFire designs)"
|
||||
+ depends on FEC2
|
||||
+ help
|
||||
+ Say Y here if both PHYs are controlled via a single channel.
|
||||
+
|
||||
config FEC_MPC52xx
|
||||
tristate "MPC52xx FEC driver"
|
||||
depends on PPC_MERGE && PPC_MPC52xx && PPC_BESTCOMM_FEC
|
||||
--- a/drivers/net/fec.c
|
||||
+++ b/drivers/net/fec.c
|
||||
@@ -51,7 +51,9 @@
|
||||
|
||||
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
|
||||
defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
|
||||
- defined(CONFIG_M520x) || defined(CONFIG_M532x)
|
||||
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
|
||||
+ defined(CONFIG_M54455)
|
||||
+
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include "fec.h"
|
||||
@@ -82,6 +84,11 @@ static unsigned int fec_hw[] = {
|
||||
(MCF_MBAR+0x30000),
|
||||
#elif defined(CONFIG_M532x)
|
||||
(MCF_MBAR+0xfc030000),
|
||||
+#elif defined(CONFIG_M54455)
|
||||
+ (MCF_MBAR+0xfc030000),
|
||||
+#if defined(CONFIG_FEC2)
|
||||
+ (MCF_MBAR+0xfc034000),
|
||||
+#endif
|
||||
#else
|
||||
&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
|
||||
#endif
|
||||
@@ -172,7 +179,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_M54455)
|
||||
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
|
||||
#else
|
||||
#define OPT_FRAME_SIZE 0
|
||||
@@ -213,6 +220,7 @@ struct fec_enet_private {
|
||||
uint phy_speed;
|
||||
phy_info_t const *phy;
|
||||
struct work_struct phy_task;
|
||||
+ volatile fec_t *phy_hwp;
|
||||
|
||||
uint sequence_done;
|
||||
uint mii_phy_task_queued;
|
||||
@@ -349,7 +357,8 @@ fec_enet_start_xmit(struct sk_buff *skb,
|
||||
if (bdp->cbd_bufaddr & 0x3) {
|
||||
unsigned int index;
|
||||
index = bdp - fep->tx_bd_base;
|
||||
- memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen);
|
||||
+ memcpy(fep->tx_bounce[index],
|
||||
+ (void *)skb->data, bdp->cbd_datlen);
|
||||
bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
|
||||
}
|
||||
|
||||
@@ -702,7 +711,7 @@ fec_enet_mii(struct net_device *dev)
|
||||
uint mii_reg;
|
||||
|
||||
fep = netdev_priv(dev);
|
||||
- ep = fep->hwp;
|
||||
+ ep = fep->phy_hwp;
|
||||
mii_reg = ep->fec_mii_data;
|
||||
|
||||
spin_lock(&fep->lock);
|
||||
@@ -753,7 +762,7 @@ mii_queue(struct net_device *dev, int re
|
||||
mii_tail = mip;
|
||||
} else {
|
||||
mii_head = mii_tail = mip;
|
||||
- fep->hwp->fec_mii_data = regval;
|
||||
+ fep->phy_hwp->fec_mii_data = regval;
|
||||
}
|
||||
} else {
|
||||
retval = 1;
|
||||
@@ -1151,8 +1160,7 @@ static phy_info_t const phy_info_ks8721b
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
-/* register definitions for the DP83848 */
|
||||
-
|
||||
+/* register definitions for the DP83848 and DP83849 */
|
||||
#define MII_DP8384X_PHYSTST 16 /* PHY Status Register */
|
||||
|
||||
static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
|
||||
@@ -1186,27 +1194,50 @@ static void mii_parse_dp8384x_sr2(uint m
|
||||
*s |= PHY_STAT_FAULT;
|
||||
}
|
||||
|
||||
+static phy_cmd_t const phy_cmd_dp8384x_ack_int[] = {
|
||||
+ { mk_mii_end, }
|
||||
+ };
|
||||
+
|
||||
+static phy_cmd_t const phy_cmd_dp8384x_shutdown[] = {
|
||||
+ { mk_mii_end, }
|
||||
+ };
|
||||
+
|
||||
static phy_info_t phy_info_dp83848= {
|
||||
- 0x020005c9,
|
||||
- "DP83848",
|
||||
+ .id = 0x020005c9,
|
||||
+ .name = "DP83848",
|
||||
|
||||
- (const phy_cmd_t []) { /* config */
|
||||
+ .config = (const phy_cmd_t []) { /* config */
|
||||
{ mk_mii_read(MII_REG_CR), mii_parse_cr },
|
||||
{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
|
||||
{ mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
|
||||
{ mk_mii_end, }
|
||||
},
|
||||
- (const phy_cmd_t []) { /* startup - enable interrupts */
|
||||
+ .startup = (const phy_cmd_t []) { /* startup - enable interrupts */
|
||||
{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
|
||||
{ mk_mii_read(MII_REG_SR), mii_parse_sr },
|
||||
{ mk_mii_end, }
|
||||
},
|
||||
- (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
|
||||
+ .ack_int = phy_cmd_dp8384x_ack_int,
|
||||
+ .shutdown = phy_cmd_dp8384x_shutdown,
|
||||
+};
|
||||
+
|
||||
+static phy_info_t phy_info_dp83849 = {
|
||||
+ .id = 0x020005ca,
|
||||
+ .name = "DP83849",
|
||||
+
|
||||
+ .config = (const phy_cmd_t []) { /* config */
|
||||
+ { mk_mii_read(MII_REG_CR), mii_parse_cr },
|
||||
+ { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
|
||||
+ { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
|
||||
{ mk_mii_end, }
|
||||
},
|
||||
- (const phy_cmd_t []) { /* shutdown */
|
||||
+ .startup = (const phy_cmd_t []) { /* startup - enable interrupts */
|
||||
+ { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
|
||||
+ { mk_mii_read(MII_REG_SR), mii_parse_sr },
|
||||
{ mk_mii_end, }
|
||||
},
|
||||
+ .ack_int = phy_cmd_dp8384x_ack_int,
|
||||
+ .shutdown = phy_cmd_dp8384x_shutdown,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -1218,6 +1249,7 @@ static phy_info_t const * const phy_info
|
||||
&phy_info_am79c874,
|
||||
&phy_info_ks8721bl,
|
||||
&phy_info_dp83848,
|
||||
+ &phy_info_dp83849,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -1799,6 +1831,138 @@ static void __inline__ fec_uncache(unsig
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
+#elif defined(CONFIG_M54455)
|
||||
+/*
|
||||
+ * Code specific for M54455
|
||||
+ */
|
||||
+
|
||||
+static void __inline__ fec_request_intrs(struct net_device *dev)
|
||||
+{
|
||||
+ struct fec_enet_private *fep;
|
||||
+ int b;
|
||||
+ static const struct idesc {
|
||||
+ char *name;
|
||||
+ unsigned short irq;
|
||||
+ } *idp, id[] = {
|
||||
+ { "fec(TXF)", 36 },
|
||||
+ { "fec(TXB)", 37 },
|
||||
+ { "fec(TXFIFO)", 38 },
|
||||
+ { "fec(TXCR)", 39 },
|
||||
+ { "fec(RXF)", 40 },
|
||||
+ { "fec(RXB)", 41 },
|
||||
+ { "fec(MII)", 42 },
|
||||
+ { "fec(LC)", 43 },
|
||||
+ { "fec(HBERR)", 44 },
|
||||
+ { "fec(GRA)", 45 },
|
||||
+ { "fec(EBERR)", 46 },
|
||||
+ { "fec(BABT)", 47 },
|
||||
+ { "fec(BABR)", 48 },
|
||||
+ { NULL },
|
||||
+ };
|
||||
+
|
||||
+ fep = netdev_priv(dev);
|
||||
+ b = (fep->index) ? 77 : 64;
|
||||
+
|
||||
+ /* Setup interrupt handlers. */
|
||||
+ for (idp = id; idp->name; idp++) {
|
||||
+ if (request_irq(b+idp->irq, fec_enet_interrupt, 0,
|
||||
+ idp->name, dev) != 0)
|
||||
+ printk(KERN_ERR "FEC: Could not alloc %s IRQ(%d)!\n",
|
||||
+ idp->name, b+idp->irq);
|
||||
+ }
|
||||
+
|
||||
+ if (fep->index) {
|
||||
+ /* Configure RMII */
|
||||
+ MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
|
||||
+ MCF_GPIO_PAR_FEC_FEC1_MASK) |
|
||||
+ MCF_GPIO_PAR_FEC_FEC1_RMII_GPIO;
|
||||
+ } else {
|
||||
+ /* Configure RMII */
|
||||
+ MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
|
||||
+ MCF_GPIO_PAR_FEC_FEC0_MASK) |
|
||||
+ MCF_GPIO_PAR_FEC_FEC0_RMII_GPIO;
|
||||
+ }
|
||||
+
|
||||
+ /* Set up gpio outputs for MII lines on FEC0 */
|
||||
+ MCF_GPIO_PAR_FECI2C |= (0 |
|
||||
+ MCF_GPIO_PAR_FECI2C_MDIO0_MDIO0 |
|
||||
+ MCF_GPIO_PAR_FECI2C_MDC0_MDC0);
|
||||
+}
|
||||
+
|
||||
+static void __inline__ fec_set_mii(struct net_device *dev,
|
||||
+ struct fec_enet_private *fep)
|
||||
+{
|
||||
+ 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
|
||||
+ */
|
||||
+ fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
|
||||
+ 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];
|
||||
+
|
||||
+ fecp = fep->hwp;
|
||||
+
|
||||
+ if (FEC_FLASHMAC) {
|
||||
+ /*
|
||||
+ * Get MAC address from FLASH.
|
||||
+ * If it is all 1's or 0's, use the default.
|
||||
+ */
|
||||
+ iap = FEC_FLASHMAC;
|
||||
+ if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
|
||||
+ (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
|
||||
+ iap = fec_mac_default;
|
||||
+ if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
|
||||
+ (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
|
||||
+ iap = fec_mac_default;
|
||||
+ } else {
|
||||
+ *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
|
||||
+ *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
|
||||
+ iap = &tmpaddr[0];
|
||||
+ }
|
||||
+
|
||||
+ memcpy(dev->dev_addr, iap, ETH_ALEN);
|
||||
+
|
||||
+ /* Adjust MAC if using default MAC address */
|
||||
+ if (iap == fec_mac_default)
|
||||
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] +
|
||||
+ fep->index;
|
||||
+}
|
||||
+
|
||||
+static void __inline__ fec_enable_phy_intr(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void __inline__ fec_disable_phy_intr(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void __inline__ fec_phy_ack_intr(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void __inline__ fec_localhw_setup(void)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static void __inline__ fec_uncache(unsigned long addr)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+/* ------------------------------------------------------------------------- */
|
||||
+
|
||||
|
||||
#else
|
||||
|
||||
@@ -2305,7 +2469,7 @@ fec_set_mac_address(struct net_device *d
|
||||
|
||||
}
|
||||
|
||||
-/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
|
||||
+/* Initialize the FEC Ethernet.
|
||||
*/
|
||||
/*
|
||||
* XXX: We need to clean up on failure exits here.
|
||||
@@ -2326,7 +2490,7 @@ int __init fec_enet_init(struct net_devi
|
||||
|
||||
/* Allocate memory for buffer descriptors.
|
||||
*/
|
||||
- mem_addr = __get_free_page(GFP_KERNEL);
|
||||
+ mem_addr = __get_free_page(GFP_DMA);
|
||||
if (mem_addr == 0) {
|
||||
printk("FEC: allocate descriptor memory failed?\n");
|
||||
return -ENOMEM;
|
||||
@@ -2339,6 +2503,11 @@ int __init fec_enet_init(struct net_devi
|
||||
fep->index = index;
|
||||
fep->hwp = fecp;
|
||||
fep->netdev = dev;
|
||||
+#ifdef CONFIG_FEC_SHARED_PHY
|
||||
+ fep->phy_hwp = (volatile fec_t *) fec_hw[index & ~1];
|
||||
+#else
|
||||
+ fep->phy_hwp = fecp;
|
||||
+#endif
|
||||
|
||||
/* Whack a reset. We should wait for this.
|
||||
*/
|
||||
@@ -2375,7 +2544,7 @@ int __init fec_enet_init(struct net_devi
|
||||
|
||||
/* Allocate a page.
|
||||
*/
|
||||
- mem_addr = __get_free_page(GFP_KERNEL);
|
||||
+ mem_addr = __get_free_page(GFP_DMA);
|
||||
/* XXX: missing check for allocation failure */
|
||||
|
||||
fec_uncache(mem_addr);
|
||||
@@ -2400,7 +2569,7 @@ int __init fec_enet_init(struct net_devi
|
||||
bdp = fep->tx_bd_base;
|
||||
for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
|
||||
if (j >= FEC_ENET_TX_FRPPG) {
|
||||
- mem_addr = __get_free_page(GFP_KERNEL);
|
||||
+ mem_addr = __get_free_page(GFP_DMA);
|
||||
j = 1;
|
||||
} else {
|
||||
mem_addr += FEC_ENET_TX_FRSIZE;
|
||||
@@ -2462,7 +2631,11 @@ int __init fec_enet_init(struct net_devi
|
||||
* remainder of the interface.
|
||||
*/
|
||||
fep->phy_id_done = 0;
|
||||
+#ifndef CONFIG_FEC_SHARED_PHY
|
||||
fep->phy_addr = 0;
|
||||
+#else
|
||||
+ fep->phy_addr = fep->index;
|
||||
+#endif
|
||||
mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
|
||||
|
||||
index++;
|
||||
--- 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_M54455)
|
||||
/*
|
||||
* Just figures, Motorola would have to change the offsets for
|
||||
* registers in the same peripheral device on different models
|
||||
Reference in New Issue
Block a user