Power management for au1000_eth.c
Subsystems (3)
Hello,
I'm trying to add power management support to au1000_eth.c driver.
In order to to it I 've added these two functions:
static int au1000_eth_suspend(struct device *dev, pm_message_t state, u32 level)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct au1000_private *aup = (struct au1000_private *) ndev->priv; if (!ndev)
return 0;
switch (level) {
case SUSPEND_DISABLE :
if (netif_running(ndev))
netif_device_detach(ndev);break;
case SUSPEND_SAVE_STATE : /* bring the device out of reset, otherwise accessing to mii * will hang */ *aup->enable = MAC_EN_CLOCK_ENABLE; au_sync_delay(2); *aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE; au_sync_delay(2); if (aup->phy_ops->phy_suspend) aup->phy_ops->phy_suspend(ndev, aup->phy_addr, level); del_timer_sync(&aup->timer); /* FIXME: REMOVED??? */ reset_mac(ndev); netif_stop_queue(ndev); free_irq(ndev->irq, dev);
break;
case SUSPEND_POWER_DOWN :
break;
}
return 0;
}
static int au1000_eth_resume(struct device *dev, u32 level)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct au1000_private *aup = (struct au1000_private *) ndev->priv;
u32 flags;
int ret; if (!ndev)
return 0;
switch (level) {
case RESUME_RESTORE_STATE :
/* bring the device out of reset, otherwise accessing to mii
* will hang */
*aup->enable = MAC_EN_CLOCK_ENABLE;
au_sync_delay(2);
*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 |
MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
au_sync_delay(2);
if (aup->phy_ops->phy_resume)
aup->phy_ops->phy_resume(ndev, aup->phy_addr, level);
aup->phy_ops->phy_init(ndev, aup->phy_addr); /* au1000_init() expects that the device is in reset state.
*/
reset_mac(ndev); /* au1000_init() expects the device in reset */ au1000_init(ndev);
ret = request_irq(ndev->irq, &au1000_interrupt, 0, ndev->name, ndev);
if (ret) {
printk(KERN_ERR "%s: unable to get IRQ %d\n",
ndev->name, ndev->irq);
return ret; //FIXME
}
init_timer(&aup->timer); /* used in ioctl() */
aup->timer.expires = RUN_AT((3*HZ));
aup->timer.data = (unsigned long) ndev;
aup->timer.function = &au1000_timer; /* timer handler */
add_timer(&aup->timer);break;
case RESUME_ENABLE : if (netif_running(ndev)) netif_device_attach(ndev); break; } return 0; }
The problem is that after wakeup the system hangs or returns lots of errors like:
Reserved instruction in kernel code in arch/mips/kernel/traps.c::do_ri, line 706[#169]:
Note that if I compile the driver as a module and removing it before sleeping and reinstalling it after wake up the system (and the ethernet) works correctly...
Suggestions? :)
Thanks in advance,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127
Quoted 3 lines · Rodolfo Giometti
Hello,
I'm trying to add power management support to
au1000_eth.cdriver.
Solved! :)
Here a patch to implement power management functions for au1000_eth.
Note that this patch needs my previous one who implements new power management's sysfs interface.
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127
PATCH 1/1 Oops! - Re: Power management for au1000_eth.c
Quoted 11 lines · Rodolfo Giometti
Quoted 3 lines · Rodolfo Giometti
Hello,
I'm trying to add power management support to
au1000_eth.cdriver.Solved! :)
Here a patch to implement power management functions for
au1000_eth.Note that this patch needs my previous one who implements new power management's sysfs interface.
The forgotten attachment. :)
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127
mips/au1000/common/au1xxx_irqmap.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/au1xxx_irqmap.c +2 -2
@@ -118,7 +118,7 @@ { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
@@ -152,7 +152,7 @@ { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},/*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/ { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
mips/au1000/common/platform.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/platform.c +79 -0
91 lines not on this page · raw message
drivers/net/Kconfig +2 -2
@@ -440,12 +440,12 @@ Say Y here to support the Ethernet subsystem on your GT96100 card. config MIPS_AU1X00_ENET - bool "MIPS AU1000 Ethernet support" + tristate "MIPS AU1000 Ethernet support" depends on NET_ETHERNET && SOC_AU1X00 select CRC32 help If you have an Alchemy Semi AU1X00 based system - say Y. Otherwise, say N. + say Y or M. Otherwise, say N. config SGI_IOC3_ETH bool "SGI IOC3 Ethernet"
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +306 -185
641 lines not on this page · raw message
net/au1000_eth.h renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.h +2 -0
@@ -152,6 +152,8 @@int (*phy_init) (struct net_device *,int );int (*phy_reset) (struct net_device *,int );int (*phy_status) (struct net_device *,int ,u16 *,u16 *); +int (*phy_suspend) (struct net_device *,int ,int ); +int (*phy_resume) (struct net_device *,int ,int ); };/*
Sergei Shtylyov
NAKRe: [PATCH] Oops! - Re: Power management for au1000_eth.c
Hello.
Quoted 5 lines · Rodolfo Giometti
Quoted 5 lines
Quoted 1 line
I'm trying to add power management support to
au1000_eth.cdriver.Solved! :)
Here a patch to implement power management functions for
au1000_eth.
Actually, the network driver patches should be sent to Jeff Garzik and
Andrew Morton.
Quoted 4 lines
Quoted 2 lines
Note that this patch needs my previous one who implements new power management's sysfs interface.
The forgotten attachment. :)
Funny, I've also been cooking a patch to straighten Alchemy Ethernet
probing code a bit...
Quoted 14 lines
------------------------------------------------------------------------
mips/au1000/common/au1xxx_irqmap.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/au1xxx_irqmap.c +1
-1@@ -118,7 +118,7 @@ { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
mips/au1000/common/au1xxx_irqmap.c line 158
Quoted 8 lines
mips/au1000/common/au1xxx_irqmap.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/au1xxx_irqmap.c +1
-1@@ -152,7 +152,7 @@ { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0},/*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/ { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
Don't think these changes are necessary.
Quoted 5 lines
mips/au1000/common/platform.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/platform.c +0
-0@@ -16,6 +16,78 @@#include <asm/mach-au1x00/au1xxx.h>
mips/au1000/common/platform.c line 27
Quoted 10 lines
mips/au1000/common/platform.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/platform.c +9
-0+#if defined(CONFIG_MIPS_AU1X00_ENET ) || defined(CONFIG_MIPS_AU1X00_ENET_MODULE ) +/* Ethernet controllers */ +static struct resource au1xxx_eth0_resources[] = { + [0 ] = { + .name ="eth-base" , + .start =ETH0_BASE , + .end =ETH0_BASE +0x0ffff , + .flags =IORESOURCE_MEM , + },
NAK, ETH0_BASE not defined anywhere, and that address differs between SOCs.
Note that this must be a *physical* address, not KSEG1-base.
mips/au1000/common/platform.c line 33
Quoted 6 lines
mips/au1000/common/platform.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/platform.c +6
-0+ [1] = { + .name = "eth-mac", + .start = MAC0_ENABLE, + .end = MAC0_ENABLE + 0x0ffff, + .flags = IORESOURCE_MEM, + },
NAK, because:
1) MAC0_ENABLE not defined anywhere, and that address differs between SOCs;
2) MAC enable register occupies 4 bytes, not 65536.
[...]
Quoted 5 lines
mips/au1000/common/platform.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/platform.c +5
-0+#if defined(CONFIG_SOC_AU1000) || \ + defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550) +static struct resource au1xxx_eth1_resources[] = { + [0] = { + .name = "eth-base",
mips/au1000/common/platform.c line 68
Quoted 10 lines
mips/au1000/common/platform.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/platform.c +10
-0+ .start = ETH1_BASE, + .end = ETH1_BASE + 0x0ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "eth-mac", + .start = MAC1_ENABLE, + .end = MAC1_ENABLE + 0x0ffff, + .flags = IORESOURCE_MEM, + },
Same here.
Quoted 2 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +0
-0
[...]
net/au1000_eth.c line 74
Quoted 7 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-2@@ -67,8 +71,8 @@static int au1000_debug =3 ;#endif -#define DRV_NAME "au1000eth" -#define DRV_VERSION "1.5" +#define DRV_NAME "au1xxx-eth"
au1000_eth, according to the driver name.
net/au1000_eth.c line 75
Quoted 1 line
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-0+#define DRV_VERSION "1.6"
Heh, nobody keeps track of the versions. :-)
Quoted 8 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +2
-2@@ -1435,40 +1391,14 @@ .get_link = au1000_get_link }; -static struct net_device * -au1000_probe (u32 ioaddr,int irq,int port_num) +static int +au1000_lowlevel_probe (struct net_device *ndev,u32 ioaddr,u32 macen_addr,int port_num)
[...]
Quoted 5 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +0
-1@@ -1477,15 +1407,16 @@ &aup->dma_addr, 0);if (!aup->vaddr) { -free_netdev (dev);
net/au1000_eth.c line 1417
Quoted 10 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +4
-2-release_mem_region (CPHYSADDR (ioaddr),MAC_IOSIZE ); -return NULL ; +printk (KERN_ERR "%s: cannot dma_alloc_noncoherent\n" , + ndev->name); + ret = -ENOMEM ; + goto out; }/* aup->mac is the base address of the MAC's registers */ aup->mac = (volatile mac_reg_t *)((unsigned long )ioaddr);
NAK, ioaddr should be physical address.
net/au1000_eth.c line 1419
Quoted 3 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-1/* Setup some variables for quick register address access */ -if (ioaddr == iflist[0 ].base_addr) +if (port_num ==0 )
Yep, I disliked this code too. :-)
Quoted 13 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-1{/* check env variables first */ if (!get_ethernet_addr (ethaddr)) {@@ -1495,7 +1426,7 @@ argptr =prom_getcmdline ();if ((pmac =strstr (argptr,"ethaddr=" )) ==NULL ) {printk (KERN_INFO "%s: No mac address found\n" , - dev->name); + ndev->name);/* use the hard coded mac addresses */ }else {str2eaddr (ethaddr, pmac +strlen ("ethaddr=" ));
net/au1000_eth.c line 1438
Quoted 6 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-2@@ -1504,26 +1435,26 @@ } } aup->enable = (volatile u32 *) - ((unsigned long )iflist[0 ].macen_addr); -memcpy (dev->dev_addr, au1000_mac_addr,sizeof (au1000_mac_addr)); + ((unsigned long ) macen_addr);
NAK, macen_addr should have been a physical address at that point too
(if the plarform definitions were correct :-). Also, this could have been done outside of "if".
net/au1000_eth.c line 1439
Quoted 1 line
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-0+memcpy (ndev->dev_addr, au1000_mac_addr,sizeof (au1000_mac_addr));
That too.
Quoted 5 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +0
-0setup_hw_rings (aup,MAC0_RX_DMA_ADDR ,MAC0_TX_DMA_ADDR ); aup->mac_id =0 ; au_macs[0 ] = aup; }else
net/au1000_eth.c line 1450
Quoted 10 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +4
-4-if (ioaddr == iflist[1 ].base_addr) +if (port_num ==1 ) { aup->enable = (volatile u32 *) - ((unsigned long )iflist[1 ].macen_addr); -memcpy (dev->dev_addr, au1000_mac_addr,sizeof (au1000_mac_addr)); - dev->dev_addr[4 ] +=0x10 ; + ((unsigned long ) macen_addr); +memcpy (ndev->dev_addr, au1000_mac_addr,sizeof (au1000_mac_addr)); + ndev->dev_addr[4 ] +=0x10 ;
Actually, the DBAu15x0 boards have their Ethernet addresess differ by 1 in
the last byte, not by 0x10 in the next to last one. This code assigns to the port an address different to what's printed on a port's sticker. This should be fixed I guess...
net/au1000_eth.c line 1458
Quoted 9 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-1setup_hw_rings (aup,MAC1_RX_DMA_ADDR ,MAC1_TX_DMA_ADDR ); aup->mac_id =1 ; au_macs[1 ] = aup; }else { -printk (KERN_ERR "%s: bad ioaddr\n" , dev->name); +printk (KERN_ERR "%s: bad ioaddr\n" , ndev->name); }
Doubt we need this "else" at all...
Quoted 31 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +25
-2@@ -2255,5 +2162,232 @@return 0 ; } -module_init (au1000_init_module); -module_exit (au1000_cleanup_module); +/* +* 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 au1000_drv_probe (struct device *dev) +{ +struct platform_device *pdev =to_platform_device (dev); +struct net_device *ndev; +struct au1000_private *aup; +struct resource *res; +static unsigned version_printed =0 ; +u32 base_addr, macen_addr; +int irq, ret; + + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"eth-base" ); +if (!res) { + ret = -ENODEV ; + goto out; + } + base_addr = res->start; + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"eth-mac" ); +if (!res) { + ret = -ENODEV ; + goto out;
net/au1000_eth.c line 2199
Quoted 10 lines
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +10
-0+ } + macen_addr = res->start; + res =platform_get_resource_byname (pdev,IORESOURCE_IRQ ,"eth-irq" ); +if (!res) { + ret = -ENODEV ; + goto out; + } + irq = res->start; + +if (!request_mem_region (CPHYSADDR (base_addr),MAC_IOSIZE ,"Au1x00 ENET" )) {
NAK, base_addr should adready be a physical address. Also, why norequest_mem_region()
for the MAC enable register?
net/au1000_eth.c line 2216
Quoted 1 line
net/au1000_eth.c renamed from home/develop/embedded/mipsel/linux/linux-mips.git/drivers/net/au1000_eth.c +1
-0+ ret =au1000_lowlevel_probe (ndev, base_addr, macen_addr, pdev->id);
Remember, The passed addresses are physical at that point.
[...]
WBR, Sergei
Re: [PATCH] Oops! - Re: Power management for au1000_eth.c
Quoted 3 lines · Sergei Shtylyov
Actually, the network driver patches should be sent to Jeff Garzik and
Andrew Morton.
Ok. Sorry. Hope they can get the patch from this list.
Quoted 2 lines
Funny, I've also been cooking a patch to straighten Alchemy Ethernet
probing code a bit...
:)
Quoted 15 lines
Quoted 15 lines
------------------------------------------------------------------------
---
/home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/au1xxx_irqmap.c2006-03-31 16:57:26.000000000 +0200
+++arch/mips/au1000/common/au1xxx_irqmap.c2006-04-03
17:50:49.000000000 +0200(quoted diff) +1
-1@@ -118,7 +118,7 @@ { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
Quoted 11 lines
Review line 158
Quoted 9 lines
(quoted diff) +1
-1@@ -152,7 +152,7 @@ { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, - { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, + { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0}, /*{ AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0},*/ { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0}, { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },Don't think these changes are necessary.
These are necessary to group togheter CPUs that have the same parameters.
Quoted 8 lines
Quoted 8 lines
---
/home/develop/embedded/mipsel/linux/linux-mips.git/arch/mips/au1000/common/platform.c2006-04-03 18:22:05.000000000 +0200
+++arch/mips/au1000/common/platform.c2006-04-05
23:08:55.000000000 +0200(quoted diff) +0
-0@@ -16,6 +16,78 @@ #include <asm/mach-au1x00/au1xxx.h>
Quoted 14 lines
Review line 28
Quoted 10 lines
(quoted diff) +9
-0+#if defined(CONFIG_MIPS_AU1X00_ENET) || defined(CONFIG_MIPS_AU1X00_ENET_MODULE) +/* Ethernet controllers */ +static struct resource au1xxx_eth0_resources[] = { + [0] = { + .name = "eth-base", + .start = ETH0_BASE, + .end = ETH0_BASE + 0x0ffff, + .flags = IORESOURCE_MEM, + },NAK,
ETH0_BASEnot defined anywhere, and that address differs between SOCs.
Note that this must be a *physical* address, not KSEG1-base.
You are right! I forgot to add the attached file... I'm very sorry but I must work on an older Linux version which still use CVS. I can't switch to GIT right now and I have to build my patches by hands.
In the attached file you can see that I grouped togheter CPUs that have the same configuration parameters.
Quoted 5 lines
Review line 30
Quoted 3 lines
(quoted diff) +1
-1/* Setup some variables for quick register address access */ - if (ioaddr == iflist[0].base_addr) + if (port_num == 0)Yep, I disliked this code too. :-)
I just use the "id" filed instaed of using the base address. It seems to me more readable...
Quoted 18 lines
Quoted 18 lines
{ /* check env variables first */ if (!get_ethernet_addr(ethaddr)) {(quoted diff) +1
-0@@ -1495,7 +1426,7 @@ argptr = prom_getcmdline(); if ((pmac = strstr(argptr, "ethaddr=")) == NULL) { printk(KERN_INFO "%s: No mac address found\n", - dev->name); + ndev->name); /* use the hard coded mac addresses */ } else {str2eaddr(ethaddr, pmac + strlen("ethaddr="));(quoted diff) +0
-1@@ -1504,26 +1435,26 @@ } } aup->enable = (volatile u32 *) - ((unsigned long)iflist[0].macen_addr);
Quoted 8 lines
Review line 1439
Quoted 3 lines
(quoted diff) +1
-1- memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); + ((unsigned long) macen_addr);NAK,
macen_addrshould have been a physical address at that point too
(if the plarform definitions were correct :-). Also, this could have been done
outside of "if".
I just keeped the original structure...
Quoted 14 lines
Quoted 14 lines
(quoted diff) +2
-4setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); aup->mac_id = 0; au_macs[0] = aup; } else - if (ioaddr == iflist[1].base_addr) + if (port_num == 1) { aup->enable = (volatile u32 *) - ((unsigned long)iflist[1].macen_addr); - memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); - dev->dev_addr[4] += 0x10; + ((unsigned long) macen_addr);
Quoted 8 lines
Review line 1452
Quoted 3 lines
(quoted diff) +2
-0+ memcpy(ndev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); + ndev->dev_addr[4] += 0x10;Actually, the DBAu15x0 boards have their Ethernet addresess differ by 1 in the last byte, not by
0x10in the next to last one. This code assigns to
the port an address different to what's printed on a port's sticker. This should be fixed I guess...
Yes. However this comes from the previous driver version and I'm working on an Au1100 based board. :)
Quoted 38 lines
Quoted 38 lines
(quoted diff) +32
-2@@ -2255,5 +2162,232 @@ return 0; } -module_init(au1000_init_module); -module_exit(au1000_cleanup_module); +/* + * 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 au1000_drv_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct net_device *ndev; + struct au1000_private *aup; + struct resource *res; + static unsigned version_printed = 0; + u32 base_addr, macen_addr; + int irq, ret; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eth-base"); + if (!res) { + ret = -ENODEV; + goto out; + } + base_addr = res->start; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eth-mac"); + if (!res) { + ret = -ENODEV; + goto out; + } + macen_addr = res->start; + res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "eth-irq"); + if (!res) { + ret = -ENODEV; + goto out; + }
Quoted 8 lines
Quoted 4 lines
(quoted diff) +3
-0+ irq = res->start; + + if (!request_mem_region(CPHYSADDR(base_addr), MAC_IOSIZE, "Au1x00ENET")) {
NAK,
base_addrshould adready be a physical address. Also, why norequest_mem_region()
for the MAC enable register?
Yes. I forgot to add it.
Thanks for your suggestions! But I'd like to know if I have to change something and resubmit the patch or these suggestions can be resolved during the merging of the code...
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127
asm-mips/mach-au1x00/au1000.h renamed from home/develop/embedded/mipsel/linux/linux-mips.git/include/asm-mips/mach-au1x00/au1000.h +18 -21
@@ -606,11 +690,10 @@#define USB_OHCI_BASE 0x10100000 // phys addr for ioremap#define USB_HOST_CONFIG 0xB017fffc -#define AU1000_ETH0_BASE 0xB0500000 -#define AU1000_ETH1_BASE 0xB0510000 -#define AU1000_MAC0_ENABLE 0xB0520000 -#define AU1000_MAC1_ENABLE 0xB0520004 -#define NUM_ETH_INTERFACES 2 +#define ETH0_BASE 0xB0500000 +#define ETH1_BASE 0xB0510000 +#define MAC0_ENABLE 0xB0520000 +#define MAC1_ENABLE 0xB0520004#endif /* CONFIG_SOC_AU1000 */ /* Au1500 */
@@ -635,8 +718,8 @@#define AU1000_USB_DEV_SUS_INT 25#define AU1000_USB_HOST_INT 26#define AU1000_ACSYNC_INT 27 -#define AU1500_MAC0_DMA_INT 28 -#define AU1500_MAC1_DMA_INT 29 +#define AU1000_MAC0_DMA_INT 28 +#define AU1000_MAC1_DMA_INT 29#define AU1000_AC97C_INT 31#define AU1000_GPIO_0 32#define AU1000_GPIO_1 33
@@ -683,11 +766,10 @@#define USB_OHCI_BASE 0x10100000 // phys addr for ioremap#define USB_HOST_CONFIG 0xB017fffc -#define AU1500_ETH0_BASE 0xB1500000 -#define AU1500_ETH1_BASE 0xB1510000 -#define AU1500_MAC0_ENABLE 0xB1520000 -#define AU1500_MAC1_ENABLE 0xB1520004 -#define NUM_ETH_INTERFACES 2 +#define ETH0_BASE 0xB1500000 +#define ETH1_BASE 0xB1510000 +#define MAC0_ENABLE 0xB1520000 +#define MAC1_ENABLE 0xB1520004#endif /* CONFIG_SOC_AU1500 */ /* Au1100 */
@@ -713,8 +795,8 @@#define AU1000_USB_DEV_SUS_INT 25#define AU1000_USB_HOST_INT 26#define AU1000_ACSYNC_INT 27 -#define AU1100_MAC0_DMA_INT 28 -#define AU1100_GPIO_208_215 29 +#define AU1000_MAC0_DMA_INT 28 +#define AU1100_GPIO_208_215 29#define AU1100_LCD_INT 30#define AU1000_AC97C_INT 31#define AU1000_GPIO_0 32
@@ -757,8 +839,8 @@#define USB_OHCI_BASE 0x10100000 // phys addr for ioremap#define USB_HOST_CONFIG 0xB017fffc -#define AU1100_ETH0_BASE 0xB0500000 -#define AU1100_MAC0_ENABLE 0xB0520000 +#define ETH0_BASE 0xB0500000 +#define MAC0_ENABLE 0xB0520000#define NUM_ETH_INTERFACES 1#endif /* CONFIG_SOC_AU1100 */
@@ -841,11 +923,10 @@#define USB_OHCI_LEN 0x00060000#define USB_HOST_CONFIG 0xB4027ffc -#define AU1550_ETH0_BASE 0xB0500000 -#define AU1550_ETH1_BASE 0xB0510000 -#define AU1550_MAC0_ENABLE 0xB0520000 -#define AU1550_MAC1_ENABLE 0xB0520004 -#define NUM_ETH_INTERFACES 2 +#define ETH0_BASE 0xB0500000 +#define ETH1_BASE 0xB0510000 +#define MAC0_ENABLE 0xB0520000 +#define MAC1_ENABLE 0xB0520004#endif /* CONFIG_SOC_AU1550 */ #ifdef CONFIG_SOC_AU1200
Re: Oops! - Re: Power management for au1000_eth.c
In reply to Sergei ShtylyovQuoted 4 lines · Sergei Shtylyov
Hello.
Rodolfo Giometti wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 5 lines
Quoted 1 line
I'm trying to add power management support to
au1000_eth.cdriver.Solved! :)
Here a patch to implement power management functions for
au1000_eth.Actually, the network driver patches should be sent to Jeff Garzik and
Andrew Morton.
And the description is wrong - this isn't exactly just power management, there are lots of changes here. You should separate them out into multiple patches.
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Note that this patch needs my previous one who implements new power management's sysfs interface.
Thats OK, as long as this patch can be applied on its own, without requiring the previous patch. It is one thing to write a new PM interface for the whole system, but the driver suspend and resume functions should never be system specific. That makes life easier for future developers.
Quoted 2 lines
Funny, I've also been cooking a patch to straighten Alchemy Ethernet
probing code a bit...
I think we can all get along here. The PM stuff looks decent to me, and Sergei had some good comments about the rest of the patch. I don't see any reason why the two of you can't get together and bang out a few patches to fix all of our ills.
Jordan
--
Jordan Crouse
Senior Linux Engineer
AMD - Personal Connectivity Solutions Group
<www.amd.com/embeddedprocessors>
PATCH 1/1 au1000_eth.c probe code straightened up
In reply to Rodolfo Giometti Straighten up the AMD Au1xx0 Ethernet probing code, make it print out (and
store in the 'net_device' structure) the physical address of the controller, not the KSEG1-based virtual. Make the driver also claim/release the 4-byte MAC enable registers and assign to the Ethernet ports two consecutive MAC addresses to match those that are printed on their stickers.
drivers/net/au1000_eth.c +87 -119
@@ -2,7 +2,7 @@* * Alchemy Au1x00 ethernet driver * -* Copyright 2001,2002,2003 MontaVista Software Inc. +* Copyright 2001-2003, 2006 MontaVista Software Inc. * Copyright 2002 TimeSys Corp. * Added ethtool/mii-tool support, * Copyright 2004 Matt Porter <[email protected]>
@@ -67,7 +67,7 @@ static int au1000_debug = 5;static int au1000_debug =3 ;#endif -#define DRV_NAME "au1000eth" +#define DRV_NAME "au1000_eth"#define DRV_VERSION "1.5"#define DRV_AUTHOR "Pete Popov <[email protected]>"#define DRV_DESC "Au1xxx on-chip Ethernet driver"
@@ -79,7 +79,7 @@ MODULE_LICENSE("GPL");// prototypes static void hard_stop (struct net_device *);static void enable_rx_tx (struct net_device *dev); -static struct net_device *au1000_probe (u32 ioaddr,int irq,int port_num); +static struct net_device *au1000_probe (int port_num);static int au1000_init (struct net_device *);static int au1000_open (struct net_device *);static int au1000_close (struct net_device *);
@@ -1159,12 +1159,27 @@ setup_hw_rings(struct au1000_private *au }static struct { -int port;u32 base_addr;u32 macen_addr;int irq;struct net_device *dev; -} iflist[2 ]; +} iflist[2 ] = { +#ifdef CONFIG_SOC_AU1000 + {AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT}, + {AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT} +#endif +#ifdef CONFIG_SOC_AU1100 + {AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT} +#endif +#ifdef CONFIG_SOC_AU1500 + {AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT}, + {AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT} +#endif +#ifdef CONFIG_SOC_AU1550 + {AU1550_ETH0_BASE ,AU1550_MAC0_ENABLE ,AU1550_MAC0_DMA_INT }, + {AU1550_ETH1_BASE ,AU1550_MAC1_ENABLE ,AU1550_MAC1_DMA_INT } +#endif +};static int num_ifs;
@@ -1175,58 +1190,14 @@ static int num_ifs;*/ static int __init au1000_init_module (void ) { -struct cpuinfo_mips *c = ¤t_cpu_data;int ni = (int )((au_readl (SYS_PINFUNC ) & (u32)(SYS_PF_NI2 )) >>4 );struct net_device *dev;int i, found_one =0 ; -switch (c->cputype) { -#ifdef CONFIG_SOC_AU1000 -case CPU_AU1000 : - num_ifs =2 - ni; - iflist[0 ].base_addr =AU1000_ETH0_BASE ; - iflist[1 ].base_addr =AU1000_ETH1_BASE ; - iflist[0 ].macen_addr =AU1000_MAC0_ENABLE ; - iflist[1 ].macen_addr =AU1000_MAC1_ENABLE ; - iflist[0 ].irq =AU1000_MAC0_DMA_INT ; - iflist[1 ].irq =AU1000_MAC1_DMA_INT ; -break ; -#endif -#ifdef CONFIG_SOC_AU1100 -case CPU_AU1100 : - num_ifs =1 - ni; - iflist[0 ].base_addr =AU1100_ETH0_BASE ; - iflist[0 ].macen_addr =AU1100_MAC0_ENABLE ; - iflist[0 ].irq =AU1100_MAC0_DMA_INT ; -break ; -#endif -#ifdef CONFIG_SOC_AU1500 -case CPU_AU1500 : - num_ifs =2 - ni; - iflist[0 ].base_addr =AU1500_ETH0_BASE ; - iflist[1 ].base_addr =AU1500_ETH1_BASE ; - iflist[0 ].macen_addr =AU1500_MAC0_ENABLE ; - iflist[1 ].macen_addr =AU1500_MAC1_ENABLE ; - iflist[0 ].irq =AU1500_MAC0_DMA_INT ; - iflist[1 ].irq =AU1500_MAC1_DMA_INT ; -break ; -#endif -#ifdef CONFIG_SOC_AU1550 -case CPU_AU1550 : - num_ifs =2 - ni; - iflist[0 ].base_addr =AU1550_ETH0_BASE ; - iflist[1 ].base_addr =AU1550_ETH1_BASE ; - iflist[0 ].macen_addr =AU1550_MAC0_ENABLE ; - iflist[1 ].macen_addr =AU1550_MAC1_ENABLE ; - iflist[0 ].irq =AU1550_MAC0_DMA_INT ; - iflist[1 ].irq =AU1550_MAC1_DMA_INT ; -break ; -#endif -default : - num_ifs =0 ; - } + num_ifs =NUM_ETH_INTERFACES - ni; +for (i =0 ; i < num_ifs; i++) { - dev =au1000_probe (iflist[i].base_addr, iflist[i].irq, i); + dev =au1000_probe (i); iflist[i].dev = dev;if (dev) found_one++;
@@ -1435,8 +1406,7 @@ static struct ethtool_ops au1000_ethtool .get_link = au1000_get_link }; -static struct net_device * -au1000_probe (u32 ioaddr,int irq,int port_num) +static struct net_device *au1000_probe (int port_num) {static unsigned version_printed =0 ;struct au1000_private *aup =NULL ;
@@ -1444,94 +1414,95 @@ au1000_probe(u32 ioaddr, int irq, int podb_dest_t *pDB, *pDBfree;char *pmac, *argptr;char ethaddr[6 ]; -int i, err; +int irq, i, err; +u32 base, macen; + +if (port_num >=NUM_ETH_INTERFACES ) +return NULL ; -if (!request_mem_region (CPHYSADDR (ioaddr),MAC_IOSIZE ,"Au1x00 ENET" )) + base =CPHYSADDR (iflist[port_num].base_addr ); + macen =CPHYSADDR (iflist[port_num].macen_addr); + irq = iflist[port_num].irq; + +if (!request_mem_region ( base,MAC_IOSIZE ,"Au1x00 ENET" ) || + !request_mem_region (macen,4 ,"Au1x00 ENET" ))return NULL ; -if (version_printed++ ==0 ) +if (version_printed++ ==0 )printk ("%s version %s %s\n" ,DRV_NAME ,DRV_VERSION ,DRV_AUTHOR ); dev =alloc_etherdev (sizeof (struct au1000_private ));if (!dev) { -printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n" ); +printk (KERN_ERR "%s: alloc_etherdev failed\n" ,DRV_NAME );return NULL ; } -if ((err =register_netdev (dev))) { -printk (KERN_ERR "Au1x_eth Cannot register net device err %d\n" , - err); +if ((err =register_netdev (dev)) !=0 ) { +printk (KERN_ERR "%s: Cannot register net device, error %d\n" , +DRV_NAME , err);free_netdev (dev);return NULL ; } -printk ("%s: Au1x Ethernet found at 0x%x, irq %d\n" , - dev->name, ioaddr, irq); +printk ("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n" , + dev->name, base, irq); aup = dev->priv;/* Allocate the data buffers */ /* Snooping works fine with eth on all au1xxx */ - aup->vaddr = (u32 )dma_alloc_noncoherent (NULL , -MAX_BUF_SIZE * (NUM_TX_BUFFS +NUM_RX_BUFFS ), - &aup->dma_addr, -0 ); + aup->vaddr = (u32 )dma_alloc_noncoherent (NULL ,MAX_BUF_SIZE * + (NUM_TX_BUFFS +NUM_RX_BUFFS ), + &aup->dma_addr,0 );if (!aup->vaddr) {free_netdev (dev); -release_mem_region (CPHYSADDR (ioaddr),MAC_IOSIZE ); +release_mem_region ( base,MAC_IOSIZE ); +release_mem_region (macen,4 );return NULL ; }/* aup->mac is the base address of the MAC's registers */ - aup->mac = (volatile mac_reg_t *)((unsigned long )ioaddr); + aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr; +/* Setup some variables for quick register address access */ -if (ioaddr == iflist[0 ].base_addr) - { -/* check env variables first */ -if (!get_ethernet_addr (ethaddr)) { + aup->enable = (volatile u32 *)iflist[port_num].macen_addr; + aup->mac_id = port_num; + au_macs[port_num] = aup; + +if (port_num ==0 ) { +/* Check the environment variables first */ +if (get_ethernet_addr (ethaddr) ==0 )memcpy (au1000_mac_addr, ethaddr,sizeof (au1000_mac_addr)); - }else { +else {/* Check command line */ argptr =prom_getcmdline (); -if ((pmac =strstr (argptr,"ethaddr=" )) ==NULL ) { -printk (KERN_INFO "%s: No mac address found\n" , - dev->name); -/* use the hard coded mac addresses */ - }else { +if ((pmac =strstr (argptr,"ethaddr=" )) ==NULL ) +printk (KERN_INFO "%s: No MAC address found\n" , + dev->name); +/* Use the hard coded MAC addresses */ +else {str2eaddr (ethaddr, pmac +strlen ("ethaddr=" ));memcpy (au1000_mac_addr, ethaddr, -sizeof (au1000_mac_addr)); +sizeof (au1000_mac_addr)); } } - aup->enable = (volatile u32 *) - ((unsigned long )iflist[0 ].macen_addr); -memcpy (dev->dev_addr, au1000_mac_addr,sizeof (au1000_mac_addr)); +setup_hw_rings (aup,MAC0_RX_DMA_ADDR ,MAC0_TX_DMA_ADDR ); - aup->mac_id =0 ; - au_macs[0 ] = aup; - } -else -if (ioaddr == iflist[1 ].base_addr) - { - aup->enable = (volatile u32 *) - ((unsigned long )iflist[1 ].macen_addr); -memcpy (dev->dev_addr, au1000_mac_addr,sizeof (au1000_mac_addr)); - dev->dev_addr[4 ] +=0x10 ; + }else if (port_num ==1 )setup_hw_rings (aup,MAC1_RX_DMA_ADDR ,MAC1_TX_DMA_ADDR ); - aup->mac_id =1 ; - au_macs[1 ] = aup; - } -else - { -printk (KERN_ERR "%s: bad ioaddr\n" , dev->name); - } -/* bring the device out of reset, otherwise probing the mii -* will hang */ +/* +* Assign to the Ethernet ports two consecutive MAC addresses +* to match those that are printed on their stickers +*/ +memcpy (dev->dev_addr, au1000_mac_addr,sizeof (au1000_mac_addr)); + dev->dev_addr[5 ] += port_num; + +/* Bring the device out of reset, otherwise probing the MII will hang */ *aup->enable =MAC_EN_CLOCK_ENABLE ;au_sync_delay (2 ); - *aup->enable =MAC_EN_RESET0 |MAC_EN_RESET1 | -MAC_EN_RESET2 |MAC_EN_CLOCK_ENABLE ; + *aup->enable =MAC_EN_RESET0 |MAC_EN_RESET1 |MAC_EN_RESET2 | +MAC_EN_CLOCK_ENABLE ;au_sync_delay (2 ); aup->mii =kmalloc (sizeof (struct mii_phy ),GFP_KERNEL );
@@ -1580,7 +1551,7 @@ au1000_probe(u32 ioaddr, int irq, int po }spin_lock_init (&aup->lock); - dev->base_addr = ioaddr; + dev->base_addr = base; dev->irq = irq; dev->open = au1000_open; dev->hard_start_xmit = au1000_tx;
@@ -1614,13 +1585,12 @@ err_out:if (aup->tx_db_inuse[i])ReleaseDB (aup, aup->tx_db_inuse[i]); } -dma_free_noncoherent (NULL , -MAX_BUF_SIZE * (NUM_TX_BUFFS +NUM_RX_BUFFS ), - (void *)aup->vaddr, - aup->dma_addr); +dma_free_noncoherent (NULL ,MAX_BUF_SIZE * (NUM_TX_BUFFS +NUM_RX_BUFFS ), + (void *)aup->vaddr, aup->dma_addr);unregister_netdev (dev);free_netdev (dev); -release_mem_region (CPHYSADDR (ioaddr),MAC_IOSIZE ); +release_mem_region ( base,MAC_IOSIZE ); +release_mem_region (macen,4 );return NULL ; }
@@ -1805,20 +1775,18 @@ static void __exit au1000_cleanup_module aup = (struct au1000_private *) dev->priv;unregister_netdev (dev);kfree (aup->mii); -for (j =0 ; j <NUM_RX_DMA ; j++) { +for (j =0 ; j <NUM_RX_DMA ; j++)if (aup->rx_db_inuse[j])ReleaseDB (aup, aup->rx_db_inuse[j]); - } -for (j =0 ; j <NUM_TX_DMA ; j++) { +for (j =0 ; j <NUM_TX_DMA ; j++)if (aup->tx_db_inuse[j])ReleaseDB (aup, aup->tx_db_inuse[j]); - } -dma_free_noncoherent (NULL , -MAX_BUF_SIZE * (NUM_TX_BUFFS +NUM_RX_BUFFS ), - (void *)aup->vaddr, - aup->dma_addr); +dma_free_noncoherent (NULL ,MAX_BUF_SIZE * + (NUM_TX_BUFFS +NUM_RX_BUFFS ), + (void *)aup->vaddr, aup->dma_addr); +release_mem_region (dev->base_addr,MAC_IOSIZE ); +release_mem_region (CPHYSADDR (iflist[i].macen_addr),4 );free_netdev (dev); -release_mem_region (CPHYSADDR (iflist[i].base_addr),MAC_IOSIZE ); } } }
Re: [PATCH] au1000_eth.c Power Management, driver registration and module support
Hello,
here:
http://ftp.enneenne.com/pub/misc/au1100-patches/linux/patch-au1000_eth-pm-and-registration
the new version of my patch for au1000_eth.c who should implement:
* Module support.
- bool "MIPS AU1000 Ethernet support"
+ tristate "MIPS AU1000 Ethernet support"
* Driver registration.
+static int __init au1000_eth_init(void)
+{
+ return driver_register(&au1000_driver);
+}
+
+static void __exit au1000_eth_cleanup(void)
+{
+ driver_unregister(&au1000_driver);
+} * Power Management.
+#ifdef CONFIG_PM
+ .suspend = au1000_drv_suspend,
+ .resume = au1000_drv_resume,
+#endif
Also, as suggested by Sergei it:
* uses physical addresses and not KSEG1-based virtual anymore and claims/releases the 4-byte MAC enable registers:
wwpc:~# cat /proc/iomem 10500000-1050ffff : eth-base 10520000-10520003 : eth-mac
* assigns to the Ethernet ports two consecutive MAC addresses:
- dev->dev_addr[4] += 0x10; + ((unsigned long) macen_addr); + memcpy(ndev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); + ndev->dev_addr[5] += 0x01;
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127
Re: [PATCH] au1000_eth.c Power Management, driver registration and module support
Hello,
yesterday I did a little mess with GIT... now the patch is complete. Sorry. :)
I forgot also to say that it has been done against «linux-2.6.16-stable» branch.
Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127
Re: [PATCH] au1000_eth.c Power Management, driver registration and module support
In reply to Rodolfo GiomettiHello.
Quoted 15 lines · Rodolfo Giometti
here:
http://ftp.enneenne.com/pub/misc/au1100-patches/linux/patch-au1000_eth-pm-and-registrationthe new version of my patch for
au1000_eth.cwho should implement:Also, as suggested by Sergei it:
* uses physical addresses and not KSEG1-based virtual anymore and claims/releases the 4-byte MAC enable registers:
wwpc:~# cat /proc/iomem 10500000-1050ffff : eth-base 10520000-10520003 : eth-mac
Quoted 8 lines
* assigns to the Ethernet ports two consecutive MAC addresses:
- dev->dev_addr[4] += 0x10; + ((unsigned long) macen_addr); + memcpy(ndev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); + ndev->dev_addr[5] += 0x01;Ciao,
Now that this is merged, Rodolfo's patch should probably preempt mine...
but it looks like something was lost during the transition: I failed to see
where SYS_PINFUNC register is actually read (the comment mentioning this was retained :-) to check whether Ethernet port 1 is enabled (its pins are shared w/GPIO)...
Quoted 1 line
Rodolfo
WBR, Sergei
Re: [PATCH] au1000_eth.c Power Management, driver registration and module support
Quoted 6 lines · Sergei Shtylyov
Now that this is merged, Rodolfo's patch should probably preempt mine...
but it looks like something was lost during the transition: I failed to see whereSYS_PINFUNCregister is actually read (the comment mentioning this was retained :-) to check whether Ethernet port 1 is enabled (its pins are shared w/GPIO)...
You are right! Maybe something like this may fix the problem:
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 341fdc4..8a6427e 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -2149,6 +2149,9 @@ static int au1000_drv_probe(struct devic
void *base_addr, *macen_addr;
int irq, ret; + if (pdev->id == 1 && (au_readl(SYS_PINFUNC) & SYS_PF_NI2) != 0)
+ return -ENODEV;
+
/* Get the resource info */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eth-base");
if (!res) {Ciao,
Rodolfo
Signature · 4 lines
GNU/Linux Solutions e-mail: [email protected] Linux Device Driver [email protected] Embedded Systems [email protected] UNIX programming phone: +39 349 2432127