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; } |