Linux MIPS Architecture development
 help / color / mirror / Atom feed
* [RFC] Au1x00 Ethernet driver
@ 2003-06-06 18:01 Joe George
  2003-06-09 17:20 ` Pete Popov
  2003-06-14  0:36 ` Pete Popov
  0 siblings, 2 replies; 3+ messages in thread
From: Joe George @ 2003-06-06 18:01 UTC (permalink / raw)
  To: ppopov; +Cc: linux-mips, ralf


The Au1x00 SOCs allow the highest number ethernet interface
to be disabled and some of the signals to be used as GPIOs.

The patch below detects if the interface is enabled and
ignores it if it is disabled.  It is part of what I need.

Our boards do not contain the phy for either ethernet
channel and may be used with 0, 1, or 2 ethernet interfaces.
The phys are on separate boards.

If I do not install a phy on an interface I get an oops, so
it doesn't look like everything that was setup in anticipation
of finding the phy gets taken back down correctly.


<4>eth0: Au1xxx ethernet found at 0xb0500000, irq 28
<3>eth0: No MII transceivers found!
<3>eth0: au1000_probe1 failed.  Returns 0
<4>eth0: Au1xxx ethernet found at 0xb0510000, irq 29
<6>eth0: Broadcom BCM5221 10/100 BaseT PHY at phy address 0
<6>eth0: Using Broadcom BCM5221 10/100 BaseT PHY as default
.
.
.
<1>Unable to handle kernel paging request at virtual address 00000002, epc == 8024e140, ra == 8024ea34
<4>Oops in fault.c::do_page_fault, line 206:
.
.
.

I would like to use the same kernel for all cases and use phy
detection to configure the interfaces.  So I'm really asking if
phy detection is acceptable for inclusion in the kernel?  If so,
I'll try to come up with acceptable patches.

More generally, I'm wondering whether using autodetection for
configuration is desirable as there are a number of other areas
where I'd like to see it used.

Joe


--- linux-mips-cvs24/drivers/net/au1000_eth.c	Mon Jun  2 21:35:28 2003
+++ tst_mips24/drivers/net/au1000_eth.c	Wed Jun  4 17:51:46 2003
@@ -54,6 +54,7 @@
 #include <asm/io.h>
 
 #include <asm/au1000.h>
+#include <asm/cpu.h>
 #include "au1000_eth.h"
 
 #ifdef AU1000_ETH_DEBUG
@@ -109,27 +110,6 @@ extern char * __init prom_getcmdline(voi
  */
 
 
-/*
- * Base address and interupt of the Au1xxx ethernet macs
- */
-static struct au1if {
-	unsigned int port;
-	int irq;
-} au1x00_iflist[] = {
-#if defined(CONFIG_SOC_AU1000)
-		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
-		{AU1000_ETH1_BASE, AU1000_ETH1_IRQ}
-#elif defined(CONFIG_SOC_AU1500)
-		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
-		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
-#elif defined(CONFIG_SOC_AU1100)
-		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
-#else
-#error "Unsupported Au1x00 CPU"
-#endif
-	};
-#define NUM_INTERFACES (sizeof(au1x00_iflist) / sizeof(struct au1if))
-
 static char version[] __devinitdata =
     "au1000eth.c:1.1 ppopov@mvista.com\n";
 
@@ -1003,17 +983,40 @@ setup_hw_rings(struct au1000_private *au
 	}
 }
 
+/*
+ * Setup the base address and interupt of the Au1xxx ethernet macs
+ * based on cpu type and whether the interface is enabled in sys_pinfunc
+ * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
+ */
 static int __init au1000_init_module(void)
 {
-	int i;
-	int base_addr, irq;
-
-	for (i=0; i<NUM_INTERFACES; i++) {
-		base_addr = au1x00_iflist[i].port;
-		irq = au1x00_iflist[i].irq;
-		if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
+	struct cpuinfo_mips *c = &current_cpu_data;
+	int base_addr[2], irq[2], num_ifs, i;
+	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
+
+	irq[0] = AU1000_ETH0_IRQ;
+	irq[1] = AU1000_ETH1_IRQ;
+	switch (c->cputype) {
+	case CPU_AU1000:
+		num_ifs = 2 - ni;
+		base_addr[0] = AU1000_ETH0_BASE;
+		base_addr[1] = AU1000_ETH1_BASE;
+		break;
+	case CPU_AU1100:
+		num_ifs = 1 - ni;
+		base_addr[0] = AU1000_ETH0_BASE;
+		break;
+	case CPU_AU1500:
+		num_ifs = 2 - ni;
+		base_addr[0] = AU1500_ETH0_BASE;
+		base_addr[1] = AU1500_ETH1_BASE;
+		break;
+	default:
+		num_ifs = 0;
+	}
+	for(i = 0; i < num_ifs; i++) {
+		if (au1000_probe1(NULL, base_addr[i], irq[i], i) != 0)
 			return -ENODEV;
-		}
 	}
 	return 0;
 }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC] Au1x00 Ethernet driver
  2003-06-06 18:01 [RFC] Au1x00 Ethernet driver Joe George
@ 2003-06-09 17:20 ` Pete Popov
  2003-06-14  0:36 ` Pete Popov
  1 sibling, 0 replies; 3+ messages in thread
From: Pete Popov @ 2003-06-09 17:20 UTC (permalink / raw)
  To: joeg; +Cc: Linux MIPS mailing list

Joe,


> The patch below detects if the interface is enabled and
> ignores it if it is disabled.  It is part of what I need.

Seems reasonable, thanks. I'll test it later and apply it.

> I would like to use the same kernel for all cases and use phy
> detection to configure the interfaces.  So I'm really asking if
> phy detection is acceptable for inclusion in the kernel?  If so,
> I'll try to come up with acceptable patches.
> 
> More generally, I'm wondering whether using autodetection for
> configuration is desirable as there are a number of other areas
> where I'd like to see it used.

The autodetection is nice, I think, as long as there's not too many
exception cases in how you do the detection.  I recently added support
for a BCM dual phy and that code really didn't fit well in the current
scheme of things. If we start running into more and more of these cases,
we'll have to revisit the autodectection strategy.

It would also be nice to completely separate the phy layer from the MAC
so other drivers can use the same phy support routines.

Pete

> Joe
> 
> 
> --- linux-mips-cvs24/drivers/net/au1000_eth.c	Mon Jun  2 21:35:28 2003
> +++ tst_mips24/drivers/net/au1000_eth.c	Wed Jun  4 17:51:46 2003
> @@ -54,6 +54,7 @@
>  #include <asm/io.h>
>  
>  #include <asm/au1000.h>
> +#include <asm/cpu.h>
>  #include "au1000_eth.h"
>  
>  #ifdef AU1000_ETH_DEBUG
> @@ -109,27 +110,6 @@ extern char * __init prom_getcmdline(voi
>   */
>  
> 
> -/*
> - * Base address and interupt of the Au1xxx ethernet macs
> - */
> -static struct au1if {
> -	unsigned int port;
> -	int irq;
> -} au1x00_iflist[] = {
> -#if defined(CONFIG_SOC_AU1000)
> -		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
> -		{AU1000_ETH1_BASE, AU1000_ETH1_IRQ}
> -#elif defined(CONFIG_SOC_AU1500)
> -		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
> -		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
> -#elif defined(CONFIG_SOC_AU1100)
> -		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
> -#else
> -#error "Unsupported Au1x00 CPU"
> -#endif
> -	};
> -#define NUM_INTERFACES (sizeof(au1x00_iflist) / sizeof(struct au1if))
> -
>  static char version[] __devinitdata =
>      "au1000eth.c:1.1 ppopov@mvista.com\n";
>  
> @@ -1003,17 +983,40 @@ setup_hw_rings(struct au1000_private *au
>  	}
>  }
>  
> +/*
> + * Setup the base address and interupt of the Au1xxx ethernet macs
> + * based on cpu type and whether the interface is enabled in sys_pinfunc
> + * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
> + */
>  static int __init au1000_init_module(void)
>  {
> -	int i;
> -	int base_addr, irq;
> -
> -	for (i=0; i<NUM_INTERFACES; i++) {
> -		base_addr = au1x00_iflist[i].port;
> -		irq = au1x00_iflist[i].irq;
> -		if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
> +	struct cpuinfo_mips *c = &current_cpu_data;
> +	int base_addr[2], irq[2], num_ifs, i;
> +	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
> +
> +	irq[0] = AU1000_ETH0_IRQ;
> +	irq[1] = AU1000_ETH1_IRQ;
> +	switch (c->cputype) {
> +	case CPU_AU1000:
> +		num_ifs = 2 - ni;
> +		base_addr[0] = AU1000_ETH0_BASE;
> +		base_addr[1] = AU1000_ETH1_BASE;
> +		break;
> +	case CPU_AU1100:
> +		num_ifs = 1 - ni;
> +		base_addr[0] = AU1000_ETH0_BASE;
> +		break;
> +	case CPU_AU1500:
> +		num_ifs = 2 - ni;
> +		base_addr[0] = AU1500_ETH0_BASE;
> +		base_addr[1] = AU1500_ETH1_BASE;
> +		break;
> +	default:
> +		num_ifs = 0;
> +	}
> +	for(i = 0; i < num_ifs; i++) {
> +		if (au1000_probe1(NULL, base_addr[i], irq[i], i) != 0)
>  			return -ENODEV;
> -		}
>  	}
>  	return 0;
>  }
> 
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC] Au1x00 Ethernet driver
  2003-06-06 18:01 [RFC] Au1x00 Ethernet driver Joe George
  2003-06-09 17:20 ` Pete Popov
@ 2003-06-14  0:36 ` Pete Popov
  1 sibling, 0 replies; 3+ messages in thread
From: Pete Popov @ 2003-06-14  0:36 UTC (permalink / raw)
  To: joeg; +Cc: Linux MIPS mailing list

Joe,

OK, I ran a quick test and applied it. I should probably put in a config
option to allow you to disable the highest ethernet port and use the
gpios instead.

Pete

On Fri, 2003-06-06 at 11:01, Joe George wrote:
> The Au1x00 SOCs allow the highest number ethernet interface
> to be disabled and some of the signals to be used as GPIOs.
> 
> The patch below detects if the interface is enabled and
> ignores it if it is disabled.  It is part of what I need.
> 
> Our boards do not contain the phy for either ethernet
> channel and may be used with 0, 1, or 2 ethernet interfaces.
> The phys are on separate boards.
> 
> If I do not install a phy on an interface I get an oops, so
> it doesn't look like everything that was setup in anticipation
> of finding the phy gets taken back down correctly.
> 
> 
> <4>eth0: Au1xxx ethernet found at 0xb0500000, irq 28
> <3>eth0: No MII transceivers found!
> <3>eth0: au1000_probe1 failed.  Returns 0
> <4>eth0: Au1xxx ethernet found at 0xb0510000, irq 29
> <6>eth0: Broadcom BCM5221 10/100 BaseT PHY at phy address 0
> <6>eth0: Using Broadcom BCM5221 10/100 BaseT PHY as default
> .
> .
> .
> <1>Unable to handle kernel paging request at virtual address 00000002, epc == 8024e140, ra == 8024ea34
> <4>Oops in fault.c::do_page_fault, line 206:
> .
> .
> .
> 
> I would like to use the same kernel for all cases and use phy
> detection to configure the interfaces.  So I'm really asking if
> phy detection is acceptable for inclusion in the kernel?  If so,
> I'll try to come up with acceptable patches.
> 
> More generally, I'm wondering whether using autodetection for
> configuration is desirable as there are a number of other areas
> where I'd like to see it used.
> 
> Joe
> 
> 
> --- linux-mips-cvs24/drivers/net/au1000_eth.c	Mon Jun  2 21:35:28 2003
> +++ tst_mips24/drivers/net/au1000_eth.c	Wed Jun  4 17:51:46 2003
> @@ -54,6 +54,7 @@
>  #include <asm/io.h>
>  
>  #include <asm/au1000.h>
> +#include <asm/cpu.h>
>  #include "au1000_eth.h"
>  
>  #ifdef AU1000_ETH_DEBUG
> @@ -109,27 +110,6 @@ extern char * __init prom_getcmdline(voi
>   */
>  
> 
> -/*
> - * Base address and interupt of the Au1xxx ethernet macs
> - */
> -static struct au1if {
> -	unsigned int port;
> -	int irq;
> -} au1x00_iflist[] = {
> -#if defined(CONFIG_SOC_AU1000)
> -		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
> -		{AU1000_ETH1_BASE, AU1000_ETH1_IRQ}
> -#elif defined(CONFIG_SOC_AU1500)
> -		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
> -		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
> -#elif defined(CONFIG_SOC_AU1100)
> -		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
> -#else
> -#error "Unsupported Au1x00 CPU"
> -#endif
> -	};
> -#define NUM_INTERFACES (sizeof(au1x00_iflist) / sizeof(struct au1if))
> -
>  static char version[] __devinitdata =
>      "au1000eth.c:1.1 ppopov@mvista.com\n";
>  
> @@ -1003,17 +983,40 @@ setup_hw_rings(struct au1000_private *au
>  	}
>  }
>  
> +/*
> + * Setup the base address and interupt of the Au1xxx ethernet macs
> + * based on cpu type and whether the interface is enabled in sys_pinfunc
> + * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
> + */
>  static int __init au1000_init_module(void)
>  {
> -	int i;
> -	int base_addr, irq;
> -
> -	for (i=0; i<NUM_INTERFACES; i++) {
> -		base_addr = au1x00_iflist[i].port;
> -		irq = au1x00_iflist[i].irq;
> -		if (au1000_probe1(NULL, base_addr, irq, i) != 0) {
> +	struct cpuinfo_mips *c = &current_cpu_data;
> +	int base_addr[2], irq[2], num_ifs, i;
> +	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
> +
> +	irq[0] = AU1000_ETH0_IRQ;
> +	irq[1] = AU1000_ETH1_IRQ;
> +	switch (c->cputype) {
> +	case CPU_AU1000:
> +		num_ifs = 2 - ni;
> +		base_addr[0] = AU1000_ETH0_BASE;
> +		base_addr[1] = AU1000_ETH1_BASE;
> +		break;
> +	case CPU_AU1100:
> +		num_ifs = 1 - ni;
> +		base_addr[0] = AU1000_ETH0_BASE;
> +		break;
> +	case CPU_AU1500:
> +		num_ifs = 2 - ni;
> +		base_addr[0] = AU1500_ETH0_BASE;
> +		base_addr[1] = AU1500_ETH1_BASE;
> +		break;
> +	default:
> +		num_ifs = 0;
> +	}
> +	for(i = 0; i < num_ifs; i++) {
> +		if (au1000_probe1(NULL, base_addr[i], irq[i], i) != 0)
>  			return -ENODEV;
> -		}
>  	}
>  	return 0;
>  }
> 
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2003-06-14  0:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-06-06 18:01 [RFC] Au1x00 Ethernet driver Joe George
2003-06-09 17:20 ` Pete Popov
2003-06-14  0:36 ` Pete Popov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox