From: Jan Damborsky <jan.damborsky@devcom.cz>
To: Markus Westergren <markus.westergren@biologigrand.ac>
Cc: linuxppc-embedded@ozlabs.org
Subject: Re: Support for Adder875 in Linux 2.4
Date: Wed, 16 Feb 2005 11:48:12 +0100 [thread overview]
Message-ID: <421324EC.5000104@devcom.cz> (raw)
In-Reply-To: <Pine.LNX.4.50.0502142045070.28518-100000@220a.licentiaten.umea.hsb.se>
[-- Attachment #1: Type: text/plain, Size: 411 bytes --]
Markus Westergren wrote:
>I got my board working with both ethernet ports today. I'm interested in your
>patch so that I can see if we made the same ugly hack and if I have overlocked
>something :)
>
>/Markus
>
>
The patch is here. I am sorry it has not been done against current denk
source tree,
I used the one from 19th January. But I hope it might satisfy for
understanding the way
the hack is done.
[-- Attachment #2: fec.diff --]
[-- Type: text/plain, Size: 8434 bytes --]
diff -purN linuxppc_2_4_devel-org/arch/ppc/8xx_io/fec.c linuxppc_2_4_devel-new/arch/ppc/8xx_io/fec.c
--- linuxppc_2_4_devel-org/arch/ppc/8xx_io/fec.c 2004-08-02 17:34:43.000000000 +0200
+++ linuxppc_2_4_devel-new/arch/ppc/8xx_io/fec.c 2005-02-15 21:36:09.000000000 +0100
@@ -181,6 +181,7 @@ typedef struct {
* the buffer descriptor determines the actual condition.
*/
struct fec_enet_private {
+ int irq_num;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff* tx_skbuff[TX_RING_SIZE];
ushort skb_cur;
@@ -232,6 +233,10 @@ struct fec_enet_private {
#endif
};
+/* Initialize the FEC Ethernet on 860T and 2nd FEC on Duet.
+ */
+static int __init fec_enet_low_init(int ch);
+
static int fec_enet_open(struct net_device *dev);
static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
#ifdef CONFIG_USE_MDIO
@@ -250,7 +255,6 @@ static struct net_device_stats *fec_enet
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 ushort my_enet_addr[3];
#ifdef CONFIG_USE_MDIO
static int fec_enet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -2018,7 +2022,7 @@ static void set_multicast_list(struct ne
volatile fec_t *ep;
fep = (struct fec_enet_private *)dev->priv;
- ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
+ ep = (volatile fec_t *)dev->base_addr;
if (dev->flags&IFF_PROMISC) {
@@ -2128,14 +2132,31 @@ static void set_multicast_list(struct ne
}
}
-/* Initialize the FEC Ethernet on 860T.
- */
int __init fec_enet_init(void)
{
+#ifdef CONFIG_FEC2_ENET
+ int ret;
+
+ if ((ret = fec_enet_low_init(0)) < 0)
+ return(ret);
+
+ return(fec_enet_low_init(1));
+#else
+ return(fec_enet_low_init(0));
+#endif
+} /* end of fec_enet_init() */
+
+/* Initialize the FEC Ethernet on 860T and 2nd FEC on Duet.
+ */
+static int __init
+fec_enet_low_init(
+ int ch)
+{
struct net_device *dev;
struct fec_enet_private *fep;
int i, j, k;
- unsigned char *eap, *iap, *ba;
+
+ unsigned char *iap, *ba;
dma_addr_t mem_addr;
volatile cbd_t *bdp;
cbd_t *cbd_base;
@@ -2162,7 +2183,10 @@ int __init fec_enet_init(void)
*/
dev = init_etherdev(0, 0);
+ if (ch == 0)
fecp = &(immap->im_cpm.cp_fec);
+ else
+ fecp = &(immap->im_cpm.cp_fec2);
/* Whack a reset. We should wait for this.
*/
@@ -2179,7 +2203,7 @@ int __init fec_enet_init(void)
/* Set the Ethernet address. If using multiple Enets on the 8xx,
* this needs some work to get unique addresses.
*/
- eap = (unsigned char *)my_enet_addr;
+
iap = bd->bi_enetaddr;
#ifdef CONFIG_SCC_ENET
@@ -2201,12 +2225,15 @@ int __init fec_enet_init(void)
tmpaddr[3] |= 0x80;
# endif
iap = tmpaddr;
-#endif
+#endif /* CONFIG_SCC_ENET */
for (i=0; i<6; i++) {
- dev->dev_addr[i] = *eap++ = *iap++;
+ dev->dev_addr[i] = *iap++;
}
+ if (ch == 1)
+ dev->dev_addr[3] ^= 0x01;
+
/* Allocate memory for buffer descriptors.
*/
if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
@@ -2258,8 +2285,15 @@ int __init fec_enet_init(void)
fep->ph_priv = NULL;
#endif
/* Install our interrupt handler. */
+ if (ch == 0) {
+ fep->irq_num = FEC_INTERRUPT;
if (request_irq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
panic("Could not allocate FEC IRQ!");
+ } else {
+ fep->irq_num = FEC2_INTERRUPT;
+ if (request_irq(FEC2_INTERRUPT, fec_enet_interrupt, 0, "fec2", dev) != 0)
+ panic("Could not allocate FEC2 IRQ!");
+ }
dev->base_addr = (unsigned long)fecp;
dev->priv = fep;
@@ -2316,6 +2350,33 @@ int __init fec_enet_init(void)
mii_free = mii_cmds;
#endif /* CONFIG_USE_MDIO */
+/* MPC87x/88x have got 2 FECs and different pinout */
+#if defined(CONFIG_TS3_DUET)
+ if (ch == 0) {
+ immap->im_ioport.iop_papar |= 0xf830;
+ immap->im_ioport.iop_padir |= 0x0830;
+ immap->im_ioport.iop_padir &= ~0xf000;
+
+ immap->im_cpm.cp_pbpar |= 0x00001001;
+ immap->im_cpm.cp_pbdir &= ~0x00001001;
+
+ immap->im_ioport.iop_pcpar |= 0x000c;
+ immap->im_ioport.iop_pcdir &= ~0x000c;
+
+ immap->im_cpm.cp_pepar |= 0x00000003;
+ immap->im_cpm.cp_pedir |= 0x00000003;
+ immap->im_cpm.cp_peso &= ~0x00000003;
+
+ immap->im_cpm.cp_cptr &= ~0x00000100;
+ } else {
+ immap->im_cpm.cp_pepar |= 0x0003fffc;
+ immap->im_cpm.cp_pedir |= 0x0003fffc;
+ immap->im_cpm.cp_peso &= ~0x000087fc;
+ immap->im_cpm.cp_peso |= 0x00037800;
+
+ immap->im_cpm.cp_cptr &= ~0x00000080;
+ } /*endif*/
+#else
#ifndef CONFIG_ICU862
/* Configure all of port D for MII.
*/
@@ -2355,6 +2416,7 @@ int __init fec_enet_init(void)
immap->im_ioport.iop_pddir = 0x1c58; /* Pre rev. D */
else
immap->im_ioport.iop_pddir = 0x1fff; /* Rev. D and later */
+#endif /* CONFIG_TS3_DUET */
#ifdef CONFIG_USE_MDIO
/* Set MII speed to 2.5 MHz
@@ -2373,7 +2435,10 @@ int __init fec_enet_init(void)
", MII irq %d"
#endif
", addr ",
- dev->name, FEC_INTERRUPT
+
+ dev->name,
+ fep->irq_num
+
#ifdef PHY_INTERRUPT
, PHY_INTERRUPT
#endif
@@ -2411,12 +2476,9 @@ fec_restart(struct net_device *dev, int
struct fec_enet_private *fep;
int i;
volatile cbd_t *bdp;
- volatile immap_t *immap;
volatile fec_t *fecp;
- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */
-
- fecp = &(immap->im_cpm.cp_fec);
+ fecp = (volatile fec_t *)dev->base_addr;
fep = dev->priv;
@@ -2439,8 +2501,9 @@ fec_restart(struct net_device *dev, int
/* Set station address.
*/
- fecp->fec_addr_low = (my_enet_addr[0] << 16) | my_enet_addr[1];
- fecp->fec_addr_high = my_enet_addr[2];
+ fecp->fec_addr_low = (dev->dev_addr[0] << 24) | (dev->dev_addr[1] << 16)
+ | (dev->dev_addr[2] << 8) | (dev->dev_addr[3] << 0);
+ fecp->fec_addr_high = (dev->dev_addr[4] << 8) | dev->dev_addr[5];
/* Reset all multicast.
*/
@@ -2531,7 +2594,7 @@ fec_restart(struct net_device *dev, int
*/
fecp->fec_ievent = 0xffc0;
- fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+ fecp->fec_ivec = (fep->irq_num/2) << 29;
/* Enable interrupts we wish to service.
*/
@@ -2552,21 +2615,17 @@ fec_restart(struct net_device *dev, int
static void
fec_stop(struct net_device *dev)
{
- volatile immap_t *immap;
volatile fec_t *fecp;
struct fec_enet_private *fep;
int i;
- immap = (immap_t *)IMAP_ADDR; /* pointer to internal registers */
-
- fecp = &(immap->im_cpm.cp_fec);
+ fecp = (volatile fec_t *)dev->base_addr;
if ((fecp->fec_ecntrl & FEC_ECNTRL_ETHER_EN) == 0)
return; /* already down */
fep = dev->priv;
-
fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */
for (i = 0;
@@ -2584,7 +2643,8 @@ fec_stop(struct net_device *dev)
/* Enable MII command finished interrupt
*/
- fecp->fec_ivec = (FEC_INTERRUPT/2) << 29;
+ fecp->fec_ivec = (fep->irq_num/2) << 29;
+
fecp->fec_imask = FEC_ENET_MII;
#ifdef CONFIG_USE_MDIO
diff -purN linuxppc_2_4_devel-org/include/asm-ppc/8xx_immap.h linuxppc_2_4_devel-new/include/asm-ppc/8xx_immap.h
--- linuxppc_2_4_devel-org/include/asm-ppc/8xx_immap.h 2004-08-02 17:40:47.000000000 +0200
+++ linuxppc_2_4_devel-new/include/asm-ppc/8xx_immap.h 2005-02-15 21:09:22.000000000 +0100
@@ -9,6 +9,7 @@
* a combination that I found difficult to separate into logical
* functional files.....but anyone else is welcome to try. -- Dan
*/
+
#ifdef __KERNEL__
#ifndef __IMMAP_8XX__
#define __IMMAP_8XX__
@@ -426,8 +427,21 @@ typedef struct comm_proc {
uint cp_pbpar;
char res12[2];
ushort cp_pbodr;
- uint cp_pbdat;
- char res13[0x18];
+ uint cp_pbdat;
+
+ /*
+ * Port E - MPC87x/88x only.
+ */
+ uint cp_pedir;
+ uint cp_pepar;
+ uint cp_peso;
+ uint cp_peodr;
+ uint cp_pedat;
+
+ /* Communications Processor Timing Register -
+ Contains RMII Timing for the FECs on MPC87x/88x only.
+ */
+ uint cp_cptr;
/* Serial Interface and Time Slot Assignment.
*/
@@ -454,7 +468,12 @@ typedef struct comm_proc {
union fec_lcd fl_un;
#define cp_fec fl_un.fl_un_fec
#define lcd_cmap fl_un.fl_un_cmap
- char res18[0x1000];
+
+ char res18[0xE00];
+
+ /* The DUET family has a second FEC here */
+ fec_t cp_fec2;
+#define cp_fec1 cp_fec /* consistency macro */
/* Dual Ported RAM follows.
* There are many different formats for this memory area
next prev parent reply other threads:[~2005-02-16 10:48 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-13 12:28 Support for Adder875 in Linux 2.4 Markus Westergren
2005-02-14 6:45 ` Yuli Barcohen
2005-02-14 19:44 ` Markus Westergren
2005-02-15 9:35 ` (no subject) Yuli Barcohen
2005-02-14 12:37 ` Support for Adder875 in Linux 2.4 Jan Damborsky
2005-02-14 19:47 ` Markus Westergren
2005-02-16 10:48 ` Jan Damborsky [this message]
2005-02-16 21:32 ` Markus Westergren
2005-02-17 15:58 ` Jan Damborsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=421324EC.5000104@devcom.cz \
--to=jan.damborsky@devcom.cz \
--cc=linuxppc-embedded@ozlabs.org \
--cc=markus.westergren@biologigrand.ac \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).