au1000_eth fixes/improvemetns for 2.6.x
PATCH 1/1 au1000_eth fixes/improvemetns for 2.6.x
the following patch
*) removes 'inline' for 'extern' declarations
*) fixes some nasty buffer overflow due to
sizeof (dev->dev_addr) > sizeof(au1000_mac_addr)' at least in 2.6.x
*) removes some unused symbols
*) generates random "local assigned" mac addresses instead of using the hardcoded one
*) prints out the finally selected mac address on initialization
*) marks a few structs 'const'
*) doesn't segfault when no MII is detected...
regards,
Signature · 2 lines
Herbert Valerio Riedel <[email protected]> Research Group for Industrial Software @ Vienna University of Technology
Index: au1000_eth.c
===================================================================
RCS file: /home/cvs/linux/drivers/net/au1000_eth.c,v retrieving revision 1.39
au1000_eth.c +36 -39
@@ -95,11 +95,9 @@static void dump_mii (struct net_device *dev,int phy_id);// externs -extern void ack_rise_edge_irq (unsigned int );extern int get_ethernet_addr (char *ethernet_addr); -extern inline void str2eaddr (unsigned char *ea,unsigned char *str); -extern inline unsigned char str2hexnum (unsigned char c); -extern char *__init prom_getcmdline (void ); +extern void str2eaddr (unsigned char *ea,unsigned char *str); +extern char *__init prom_getcmdline (void );/* * Theory of operation
@@ -120,7 +118,7 @@* the mac address is, and the mac address is not passed on the * command line. */ -static unsigned char au1000_mac_addr[6 ]__devinitdata = { +static unsigned char au1000_mac_addr[ETH_ALEN ]__devinitdata = {0x00 ,0x50 ,0xc2 ,0x0c ,0x30 ,0x00 };
@@ -131,7 +129,7 @@#define cpu_to_dma32 cpu_to_be32#define dma32_to_cpu be32_to_cpu -struct au1000_private *au_macs[NUM_ETH_INTERFACES ]; +static struct au1000_private *au_macs[NUM_ETH_INTERFACES ];/* FIXME * All of the PHY code really should be detached from the MAC
@@ -149,13 +147,6 @@ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ SUPPORTED_Autoneg -static char *phy_link[] = -{"unknown" , -"10Base2" ,"10BaseT" , -"AUI" , -"100BaseT" ,"100BaseTX" ,"100BaseFX" -}; -int bcm_5201_init (struct net_device *dev,int phy_addr) {s16 data;
@@ -723,61 +714,61 @@ }#endif -struct phy_ops bcm_5201_ops = { +const struct phy_ops bcm_5201_ops = { bcm_5201_init, bcm_5201_reset, bcm_5201_status, }; -struct phy_ops am79c874_ops = { +const struct phy_ops am79c874_ops = { am79c874_init, am79c874_reset, am79c874_status, }; -struct phy_ops am79c901_ops = { +const struct phy_ops am79c901_ops = { am79c901_init, am79c901_reset, am79c901_status, }; -struct phy_ops lsi_80227_ops = { +const struct phy_ops lsi_80227_ops = { lsi_80227_init, lsi_80227_reset, lsi_80227_status, }; -struct phy_ops lxt971a_ops = { +const struct phy_ops lxt971a_ops = { lxt971a_init, lxt971a_reset, lxt971a_status, }; -struct phy_ops ks8995m_ops = { +const struct phy_ops ks8995m_ops = { ks8995m_init, ks8995m_reset, ks8995m_status, }; -struct phy_ops smsc_83C185_ops = { +const struct phy_ops smsc_83C185_ops = { smsc_83C185_init, smsc_83C185_reset, smsc_83C185_status, };#ifdef CONFIG_MIPS_BOSPORUS -struct phy_ops stub_ops = { +const struct phy_ops stub_ops = { stub_init, stub_reset, stub_status, };#endif -static struct mii_chip_info { +const static struct mii_chip_info {const char * name;u16 phy_id0;u16 phy_id1; -struct phy_ops *phy_ops; +const struct phy_ops *phy_ops;int dual_phy; } mii_chip_table[] = { {"Broadcom BCM5201 10/100 BaseT PHY" ,0x0040 ,0x6212 , &bcm_5201_ops,0 },
@@ -983,6 +974,10 @@ } } } + +/* PHY not found */ +printk (KERN_ERR "%s: Au1x No MII transceivers found!\n" , dev->name); +return -1 ; found: #ifdef CONFIG_MIPS_BOSPORUS
@@ -1448,7 +1443,6 @@struct net_device *dev =NULL ;db_dest_t *pDB, *pDBfree;char *pmac, *argptr; -char ethaddr[6 ];int i, err;if (!request_mem_region (CPHYSADDR (ioaddr),MAC_IOSIZE ,"Au1x00 ENET" ))
@@ -1470,8 +1464,7 @@return NULL ; } -printk ("%s: Au1x Ethernet found at 0x%x, irq %d\n" , - dev->name, ioaddr, irq); +printk ("%s: Au1x Ethernet found at 0x%x, irq %d\n" , dev->name, ioaddr, irq); aup = dev->priv;
@@ -1492,25 +1485,25 @@/* Setup some variables for quick register address access */ if (ioaddr == iflist[0 ].base_addr) { +char ethaddr[ETH_ALEN ]; +/* check env variables first */ if (!get_ethernet_addr (ethaddr)) { -memcpy (au1000_mac_addr, ethaddr,sizeof (dev->dev_addr)); +memcpy (au1000_mac_addr, ethaddr,ETH_ALEN ); }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 */ +printk (KERN_INFO "%s: No mac address found, generating random local assigned address\n" , + dev->name); +random_ether_addr (au1000_mac_addr); }else {str2eaddr (ethaddr, pmac +strlen ("ethaddr=" )); -memcpy (au1000_mac_addr, ethaddr, -sizeof (dev->dev_addr)); +memcpy (au1000_mac_addr, ethaddr,ETH_ALEN ); } } - aup->enable = (volatile u32 *) - ((unsigned long )iflist[0 ].macen_addr); -memcpy (dev->dev_addr, au1000_mac_addr,sizeof (dev->dev_addr)); + aup->enable = (volatile u32 *)((unsigned long )iflist[0 ].macen_addr); +memcpy (dev->dev_addr, au1000_mac_addr,ETH_ALEN );setup_hw_rings (aup,MAC0_RX_DMA_ADDR ,MAC0_TX_DMA_ADDR ); aup->mac_id =0 ; au_macs[0 ] = aup;
@@ -1518,10 +1511,9 @@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 (dev->dev_addr)); - dev->dev_addr[4 ] +=0x10 ; + aup->enable = (volatile u32 *)((unsigned long )iflist[1 ].macen_addr); +memcpy (dev->dev_addr, au1000_mac_addr,ETH_ALEN ); + dev->dev_addr[5 ] +=0x01 ;setup_hw_rings (aup,MAC1_RX_DMA_ADDR ,MAC1_TX_DMA_ADDR ); aup->mac_id =1 ; au_macs[1 ] = aup;
@@ -1531,6 +1523,11 @@printk (KERN_ERR "%s: bad ioaddr\n" , dev->name); } +printk (KERN_INFO "%s: Using mac address " , dev->name); +for (i =0 ; i <5 ; i++) +printk ("%2.2x:" , dev->dev_addr[i]); +printk ("%2.2x\n" , dev->dev_addr[i]); +/* bring the device out of reset, otherwise probing the mii * will hang */ *aup->enable =MAC_EN_CLOCK_ENABLE ;
Index: au1000_eth.h
===================================================================
RCS file: /home/cvs/linux/drivers/net/au1000_eth.h,v retrieving revision 1.10
au1000_eth.h +2 -3
@@ -142,7 +142,7 @@ typedef struct mii_phy { struct mii_phy * next; - struct mii_chip_info * chip_info; + const struct mii_chip_info * chip_info; u16 status; u32 *mii_control_reg; u32 *mii_data_reg;
@@ -200,7 +200,6 @@struct au1000_private { -db_dest_t *pDBfree;db_dest_t db[NUM_RX_BUFFS +NUM_TX_BUFFS ];volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA ];
@@ -214,7 +213,7 @@int mac_id;mii_phy_t *mii; -struct phy_ops *phy_ops; +const struct phy_ops *phy_ops;/* These variables are just for quick access to certain regs addresses. */ volatile mac_reg_t *mac;/* mac registers */