|
From: Pete P. <pp...@us...> - 2001-08-28 07:23:57
|
Update of /cvsroot/linux-mips/linux/drivers/net
In directory usw-pr-cvs1:/tmp/cvs-serv14591/drivers/net
Modified Files:
au1000_eth.c
Log Message:
Added preliminary power management supuport:
* turn off the clocks to the uarts when not used
* turn off the clocks to the ethernets when not used
* adhoc /proc interface for putting the cpu to sleep and
dynamically scaling the cpu frequency.
* fixed a pci compile problem
Index: au1000_eth.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/drivers/net/au1000_eth.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** au1000_eth.c 2001/08/25 02:19:28 1.3
--- au1000_eth.c 2001/08/28 07:23:54 1.4
***************
*** 65,68 ****
--- 65,69 ----
static void dma_free(void *, size_t);
static void hard_stop(struct net_device *);
+ static void enable_rx_tx(struct net_device *dev);
static int __init au1000_probe1(struct net_device *, long, int, int);
static int au1000_init(struct net_device *);
***************
*** 79,89 ****
static inline void update_rx_stats(struct net_device *, u32);
static void au1000_timer(unsigned long);
- static void cleanup_buffers(struct net_device *);
static int au1000_ioctl(struct net_device *, struct ifreq *, int);
static int mdio_read(struct net_device *, int, int);
static void mdio_write(struct net_device *, int, int, u16);
- static inline void sync(void);
extern void ack_rise_edge_irq(unsigned int);
static int next_dev;
--- 80,93 ----
static inline void update_rx_stats(struct net_device *, u32);
static void au1000_timer(unsigned long);
static int au1000_ioctl(struct net_device *, struct ifreq *, int);
static int mdio_read(struct net_device *, int, int);
static void mdio_write(struct net_device *, int, int, u16);
+ // 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);
static int next_dev;
***************
*** 120,127 ****
"au1000eth.c:0.1 pp...@mv...\n";
! // FIX! Need real Ethernet addresses
! static unsigned char au1000_mac_addr[2][6] __devinitdata = {
! {0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00},
! {0x00, 0x50, 0xc2, 0x0c, 0x40, 0x00}
};
--- 124,133 ----
"au1000eth.c:0.1 pp...@mv...\n";
! /* These addresses are only used if yamon doesn't tell us what
! * the mac address is, and the mac address is not passed on the
! * command line.
! */
! static unsigned char au1000_mac_addr[6] __devinitdata = {
! 0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00
};
***************
*** 133,141 ****
#define dma32_to_cpu be32_to_cpu
- /* CPU pipeline flush */
- static inline void sync(void)
- {
- asm volatile ("sync");
- }
/* FIXME
--- 139,142 ----
***************
*** 169,172 ****
--- 170,174 ----
data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
mdio_write(dev, phy_addr, MII_CONTROL, data);
+
#ifdef AU1000_ETH_DEBUG
dump_mii(dev, phy_addr);
***************
*** 231,234 ****
--- 233,237 ----
*link = 0;
*speed = 0;
+ dev->if_port = IF_PORT_UNKNOWN;
}
return 0;
***************
*** 455,458 ****
--- 458,472 ----
+ static void enable_rx_tx(struct net_device *dev)
+ {
+ struct au1000_private *aup = (struct au1000_private *) dev->priv;
+
+ if (au1000_debug > 4)
+ printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);
+
+ aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
+ au_sync_delay(10);
+ }
+
static void hard_stop(struct net_device *dev)
{
***************
*** 463,468 ****
aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
! sync();
! mdelay(10);
}
--- 477,481 ----
aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
! au_sync_delay(10);
}
***************
*** 480,509 ****
hard_stop(dev);
*aup->enable |= MAC_DMA_RESET;
! sync();
! mdelay(10);
aup->tx_full = 0;
spin_unlock_irqrestore(&aup->lock, flags);
}
- static void cleanup_buffers(struct net_device *dev)
- {
- int i;
- struct au1000_private *aup = (struct au1000_private *) dev->priv;
-
- for (i=0; i<NUM_RX_DMA; i++) {
- if (aup->rx_db_inuse[i]) {
- ReleaseDB(aup, aup->rx_db_inuse[i]);
- aup->rx_db_inuse[i] = 0;
- }
- }
-
- for (i=0; i<NUM_TX_DMA; i++) {
- if (aup->tx_db_inuse[i]) {
- ReleaseDB(aup, aup->tx_db_inuse[i]);
- aup->tx_db_inuse[i] = 0;
- }
- }
- }
-
/*
--- 493,503 ----
hard_stop(dev);
*aup->enable |= MAC_DMA_RESET;
! au_sync_delay(2);
! *aup->enable &= ~(MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE);
! au_sync_delay(2);
aup->tx_full = 0;
spin_unlock_irqrestore(&aup->lock, flags);
}
/*
***************
*** 518,527 ****
for (i=0; i<NUM_RX_DMA; i++) {
! aup->rx_dma_ring[i] = (volatile rx_dma_t *) ioremap_nocache((unsigned long)
! (rx_base + sizeof(rx_dma_t)*i), sizeof(rx_dma_t));
}
for (i=0; i<NUM_TX_DMA; i++) {
! aup->tx_dma_ring[i] = (volatile tx_dma_t *)ioremap_nocache((unsigned long)
! (tx_base + sizeof(tx_dma_t)*i), sizeof(tx_dma_t));
}
}
--- 512,519 ----
for (i=0; i<NUM_RX_DMA; i++) {
! aup->rx_dma_ring[i] = (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
}
for (i=0; i<NUM_TX_DMA; i++) {
! aup->tx_dma_ring[i] = (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
}
}
***************
*** 563,567 ****
int i, retval = 0;
db_dest_t *pDB, *pDBfree;
! u16 link, speed;
if ((ioaddr != AU1000_ETH0_BASE) && (ioaddr != AU1000_ETH1_BASE)) {
--- 555,560 ----
int i, retval = 0;
db_dest_t *pDB, *pDBfree;
! char *pmac, *argptr;
! char ethaddr[6];
if ((ioaddr != AU1000_ETH0_BASE) && (ioaddr != AU1000_ETH1_BASE)) {
***************
*** 609,624 ****
/* aup->mac is the base address of the MAC's registers */
! aup->mac = (volatile mac_reg_t *)ioremap_nocache((unsigned long)ioaddr, sizeof(*aup->mac));
/* Setup some variables for quick register address access */
if (ioaddr == AU1000_ETH0_BASE) {
! aup->enable = (volatile u32 *)
! ioremap_nocache((unsigned long)MAC0_ENABLE, sizeof(*aup->enable));
! memcpy(dev->dev_addr, au1000_mac_addr[0], sizeof(dev->dev_addr));
setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
}
else if (ioaddr == AU1000_ETH1_BASE) {
! aup->enable = (volatile u32 *)
! ioremap_nocache((unsigned long)MAC1_ENABLE, sizeof(*aup->enable));
! memcpy(dev->dev_addr, au1000_mac_addr[1], sizeof(dev->dev_addr));
setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
}
--- 602,631 ----
/* aup->mac is the base address of the MAC's registers */
! aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
/* Setup some variables for quick register address access */
if (ioaddr == AU1000_ETH0_BASE) {
! if (!get_ethernet_addr(ethaddr)) { /* check env variables first */
! memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
! }
! 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 {
! str2eaddr(ethaddr, pmac + strlen("ethaddr="));
! memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
! }
! }
! aup->enable = (volatile u32 *) ((unsigned long)MAC0_ENABLE);
! memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
}
else if (ioaddr == AU1000_ETH1_BASE) {
! aup->enable = (volatile u32 *) ((unsigned long)MAC1_ENABLE);
! memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
! dev->dev_addr[4] += 0x10;
setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
}
***************
*** 633,651 ****
* will hang */
*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
! MAC_EN_CLOCK_ENABLE | MAC_EN_TOSS;
! sync();
! mdelay(2);
if (mii_probe(dev) != 0) {
goto free_region;
}
- aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
- if (!link) {
- printk(KERN_INFO "%s: link down resetting...\n", dev->name);
- aup->phy_ops->phy_reset(dev, aup->phy_addr);
- aup->phy_ops->phy_init(dev, aup->phy_addr);
- }
- else {
- printk(KERN_INFO "%s: link up (%s)\n", dev->name, phy_link[speed]);
- }
pDBfree = NULL;
--- 640,648 ----
* will hang */
*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
! MAC_EN_CLOCK_ENABLE;
! au_sync_delay(2);
if (mii_probe(dev) != 0) {
goto free_region;
}
pDBfree = NULL;
***************
*** 697,701 ****
*/
reset_mac(dev);
-
return 0;
--- 694,697 ----
***************
*** 729,734 ****
int i;
u32 value, control;
! if (au1000_debug > 4) printk("%s: au1000_init", dev->name);
spin_lock_irqsave(&aup->lock, flags);
--- 725,731 ----
int i;
u32 value, control;
+ u16 link, speed;
! if (au1000_debug > 4) printk("%s: au1000_init\n", dev->name);
spin_lock_irqsave(&aup->lock, flags);
***************
*** 736,743 ****
/* bring the device out of reset */
value = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
! MAC_EN_CLOCK_ENABLE | MAC_EN_TOSS;
*aup->enable = value;
! sync();
! mdelay(200);
aup->mac->control = 0;
--- 733,739 ----
/* bring the device out of reset */
value = MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
! MAC_EN_CLOCK_ENABLE;
*aup->enable = value;
! au_sync_delay(200);
aup->mac->control = 0;
***************
*** 753,763 ****
aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
}
! sync();
control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
control |= MAC_BIG_ENDIAN;
#endif
aup->mac->control = control;
spin_unlock_irqrestore(&aup->lock, flags);
--- 749,764 ----
aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
}
+ au_sync();
! aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
control |= MAC_BIG_ENDIAN;
#endif
+ if (link && (dev->if_port == IF_PORT_100BASEFX)) {
+ control |= MAC_FULL_DUPLEX;
+ }
aup->mac->control = control;
+ au_sync();
spin_unlock_irqrestore(&aup->lock, flags);
***************
*** 769,773 ****
struct net_device *dev = (struct net_device *)data;
struct au1000_private *aup = (struct au1000_private *) dev->priv;
! u16 mii_data, link, speed;
if (!dev) {
--- 770,775 ----
struct net_device *dev = (struct net_device *)data;
struct au1000_private *aup = (struct au1000_private *) dev->priv;
! unsigned char if_port;
! u16 link, speed;
if (!dev) {
***************
*** 776,783 ****
return;
}
- if (!(dev->flags & IFF_UP)) {
- goto set_timer;
- }
if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
if (link) {
--- 778,783 ----
return;
}
+ if_port = dev->if_port;
if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
if (link) {
***************
*** 785,789 ****
netif_carrier_on(dev);
dev->flags |= IFF_RUNNING;
! printk(KERN_DEBUG "%s: link up\n", dev->name);
}
}
--- 785,789 ----
netif_carrier_on(dev);
dev->flags |= IFF_RUNNING;
! printk(KERN_INFO "%s: link up\n", dev->name);
}
}
***************
*** 793,802 ****
dev->flags &= ~IFF_RUNNING;
dev->if_port = 0;
! printk(KERN_DEBUG "%s: link down\n", dev->name);
}
}
}
! set_timer:
aup->timer.expires = RUN_AT((1*HZ));
aup->timer.data = (unsigned long)dev;
--- 793,815 ----
dev->flags &= ~IFF_RUNNING;
dev->if_port = 0;
! printk(KERN_INFO "%s: link down\n", dev->name);
}
}
}
! if (link && (dev->if_port != if_port) && (dev->if_port != IF_PORT_UNKNOWN)) {
! hard_stop(dev);
! if (dev->if_port == IF_PORT_100BASEFX) {
! printk(KERN_INFO "%s: going to full duplex\n", dev->name);
! aup->mac->control |= MAC_FULL_DUPLEX;
! au_sync_delay(1);
! }
! else {
! aup->mac->control &= ~MAC_FULL_DUPLEX;
! au_sync_delay(1);
! }
! enable_rx_tx(dev);
! }
!
aup->timer.expires = RUN_AT((1*HZ));
aup->timer.data = (unsigned long)dev;
***************
*** 875,882 ****
if (status & TX_FRAME_ABORTED) {
! ps->tx_errors++;
! ps->tx_aborted_errors++;
! if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
! ps->tx_carrier_errors++;
}
}
--- 888,905 ----
if (status & TX_FRAME_ABORTED) {
! if (dev->if_port == IF_PORT_100BASEFX) {
! if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
! /* any other tx errors are only valid
! * in half duplex mode */
! ps->tx_errors++;
! ps->tx_aborted_errors++;
! }
! }
! else {
! ps->tx_errors++;
! ps->tx_aborted_errors++;
! if (status & (TX_NO_CARRIER | TX_LOSS_CARRIER))
! ps->tx_carrier_errors++;
! }
}
}
***************
*** 899,903 ****
ptxd->buff_stat &= ~TX_T_DONE;
ptxd->len = 0;
! sync();
aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
--- 922,926 ----
ptxd->buff_stat &= ~TX_T_DONE;
ptxd->len = 0;
! au_sync();
aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1);
***************
*** 962,966 ****
ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
! sync();
dev_kfree_skb(skb);
aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
--- 985,989 ----
ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
! au_sync();
dev_kfree_skb(skb);
aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
***************
*** 1061,1065 ****
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
! sync();
/* next descriptor */
--- 1084,1088 ----
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
! au_sync();
/* next descriptor */
***************
*** 1083,1088 ****
return;
}
- au1000_rx(dev);
au1000_tx_ack(dev);
}
--- 1106,1111 ----
return;
}
au1000_tx_ack(dev);
+ au1000_rx(dev);
}
***************
*** 1119,1125 ****
struct au1000_private *aup = (struct au1000_private *) dev->priv;
- /* fixme */
if (au1000_debug > 4)
! printk("%s: set_multicast: flags=%x\n", dev->name, dev->flags);
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
--- 1142,1147 ----
struct au1000_private *aup = (struct au1000_private *) dev->priv;
if (au1000_debug > 4)
! printk("%s: set_rx_mode: flags=%x\n", dev->name, dev->flags);
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
***************
*** 1143,1146 ****
--- 1165,1169 ----
aup->mac->multi_hash_high = mc_filter[1];
aup->mac->multi_hash_low = mc_filter[0];
+ aup->mac->control &= ~MAC_PROMISCUOUS;
aup->mac->control |= MAC_HASH_MODE;
}
***************
*** 1181,1185 ****
switch(map->port){
case IF_PORT_UNKNOWN: /* use auto here */
! printk("auto\\n");
dev->if_port = map->port;
/* Link Down: the timer will bring it up */
--- 1204,1208 ----
switch(map->port){
case IF_PORT_UNKNOWN: /* use auto here */
! printk(KERN_INFO "%s: config phy for aneg\n", dev->name);
dev->if_port = map->port;
/* Link Down: the timer will bring it up */
***************
*** 1197,1201 ****
case IF_PORT_10BASET: /* 10BaseT */
! printk("10baseT\n");
dev->if_port = map->port;
--- 1220,1224 ----
case IF_PORT_10BASET: /* 10BaseT */
! printk(KERN_INFO "%s: config phy for 10BaseT\n", dev->name);
dev->if_port = map->port;
***************
*** 1205,1209 ****
/* set Speed to 10Mbps, Half Duplex */
control = mdio_read(dev, aup->phy_addr, MII_CONTROL);
- printk("read control %x\n", control);
control &= ~(MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_FDX);
--- 1228,1231 ----
***************
*** 1214,1218 ****
case IF_PORT_100BASET: /* 100BaseT */
case IF_PORT_100BASETX: /* 100BaseTx */
! printk("100 base T/TX\n");
dev->if_port = map->port;
--- 1236,1240 ----
case IF_PORT_100BASET: /* 100BaseT */
case IF_PORT_100BASETX: /* 100BaseTx */
! printk(KERN_INFO "%s: config phy for 100BaseTX\n", dev->name);
dev->if_port = map->port;
***************
*** 1230,1234 ****
case IF_PORT_100BASEFX: /* 100BaseFx */
! printk("100 Base FX\n");
dev->if_port = map->port;
--- 1252,1256 ----
case IF_PORT_100BASEFX: /* 100BaseFx */
! printk(KERN_INFO "%s: config phy for 100BaseFX\n", dev->name);
dev->if_port = map->port;
***************
*** 1246,1255 ****
case IF_PORT_AUI: /* AUI */
/* These Modes are not supported (are they?)*/
! printk(KERN_INFO "Not supported");
return -EOPNOTSUPP;
break;
default:
! printk("Invalid");
return -EINVAL;
}
--- 1268,1277 ----
case IF_PORT_AUI: /* AUI */
/* These Modes are not supported (are they?)*/
! printk(KERN_ERR "%s: 10Base2/AUI not supported", dev->name);
return -EOPNOTSUPP;
break;
default:
! printk(KERN_ERR "%s: Invalid media selected", dev->name);
return -EINVAL;
}
|