diff --git a/[refs] b/[refs] index d090cddf2b44..b872e16f2095 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 359b8800d3a46557844969c485e1a14baf119b06 +refs/heads/master: 747af1e154545566d04f647f86fc3ae512439fab diff --git a/trunk/arch/ppc/platforms/hdpu.c b/trunk/arch/ppc/platforms/hdpu.c index f945416960e9..50039a204c24 100644 --- a/trunk/arch/ppc/platforms/hdpu.c +++ b/trunk/arch/ppc/platforms/hdpu.c @@ -319,10 +319,11 @@ static void __init hdpu_fixup_eth_pdata(struct platform_device *pd) struct mv643xx_eth_platform_data *eth_pd; eth_pd = pd->dev.platform_data; + eth_pd->port_serial_control = + mv64x60_read(&bh, MV643XX_ETH_PORT_SERIAL_CONTROL_REG(pd->id) & ~1); + eth_pd->force_phy_addr = 1; eth_pd->phy_addr = pd->id; - eth_pd->speed = SPEED_100; - eth_pd->duplex = DUPLEX_FULL; eth_pd->tx_queue_size = 400; eth_pd->rx_queue_size = 800; } diff --git a/trunk/arch/ppc/syslib/mv64x60.c b/trunk/arch/ppc/syslib/mv64x60.c index 1f01b7e2376b..94ea346b7b4b 100644 --- a/trunk/arch/ppc/syslib/mv64x60.c +++ b/trunk/arch/ppc/syslib/mv64x60.c @@ -313,7 +313,7 @@ static struct platform_device mpsc1_device = { }; #endif -#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) +#ifdef CONFIG_MV643XX_ETH static struct resource mv64x60_eth_shared_resources[] = { [0] = { .name = "ethernet shared base", @@ -456,7 +456,7 @@ static struct platform_device *mv64x60_pd_devs[] __initdata = { &mpsc0_device, &mpsc1_device, #endif -#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) +#ifdef CONFIG_MV643XX_ETH &mv64x60_eth_shared_device, #endif #ifdef CONFIG_MV643XX_ETH_0 diff --git a/trunk/drivers/net/3c523.c b/trunk/drivers/net/3c523.c index b40885d41680..9e1fe2e0478c 100644 --- a/trunk/drivers/net/3c523.c +++ b/trunk/drivers/net/3c523.c @@ -105,7 +105,6 @@ #include #include #include -#include #include #include @@ -659,7 +658,7 @@ static int init586(struct net_device *dev) s = jiffies; /* warning: only active with interrupts on !! */ while (!(cfg_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) + if (jiffies - s > 30*HZ/100) break; } @@ -685,7 +684,7 @@ static int init586(struct net_device *dev) s = jiffies; while (!(ias_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) + if (jiffies - s > 30*HZ/100) break; } @@ -710,7 +709,7 @@ static int init586(struct net_device *dev) s = jiffies; while (!(tdr_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) { + if (jiffies - s > 30*HZ/100) { printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__); result = 1; break; @@ -799,7 +798,7 @@ static int init586(struct net_device *dev) elmc_id_attn586(); s = jiffies; while (!(mc_cmd->cmd_status & STAT_COMPL)) { - if (time_after(jiffies, s + 30*HZ/100)) + if (jiffies - s > 30*HZ/100) break; } if (!(mc_cmd->cmd_status & STAT_COMPL)) { diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index 3dde1df33487..7488ee7f7caf 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -258,7 +258,6 @@ static int vortex_debug = 1; #include #include #include -#include #include /* For NR_IRQS only. */ #include #include @@ -2718,7 +2717,7 @@ boomerang_rx(struct net_device *dev) skb = dev_alloc_skb(PKT_BUF_SZ); if (skb == NULL) { static unsigned long last_jif; - if (time_after(jiffies, last_jif + 10 * HZ)) { + if ((jiffies - last_jif) > 10 * HZ) { printk(KERN_WARNING "%s: memory shortage\n", dev->name); last_jif = jiffies; } diff --git a/trunk/drivers/net/acenic.c b/trunk/drivers/net/acenic.c index b508812e97ac..b8953de5664a 100644 --- a/trunk/drivers/net/acenic.c +++ b/trunk/drivers/net/acenic.c @@ -1002,8 +1002,6 @@ static int __devinit ace_init(struct net_device *dev) mac1 = 0; for(i = 0; i < 4; i++) { - int tmp; - mac1 = mac1 << 8; tmp = read_eeprom_byte(dev, 0x8c+i); if (tmp < 0) { @@ -1014,8 +1012,6 @@ static int __devinit ace_init(struct net_device *dev) } mac2 = 0; for(i = 4; i < 8; i++) { - int tmp; - mac2 = mac2 << 8; tmp = read_eeprom_byte(dev, 0x8c+i); if (tmp < 0) { diff --git a/trunk/drivers/net/apne.c b/trunk/drivers/net/apne.c index b9820b86cdcc..a94216b87184 100644 --- a/trunk/drivers/net/apne.c +++ b/trunk/drivers/net/apne.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -217,7 +216,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(" not found (no reset ack).\n"); return -ENODEV; } @@ -383,7 +382,7 @@ apne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk("%s: ne_reset_8390() did not complete.\n", dev->name); break; } @@ -531,7 +530,7 @@ apne_block_output(struct net_device *dev, int count, dma_start = jiffies; while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk("%s: timeout waiting for Tx RDC.\n", dev->name); apne_reset_8390(dev); NS8390_init(dev,1); diff --git a/trunk/drivers/net/arcnet/arc-rawmode.c b/trunk/drivers/net/arcnet/arc-rawmode.c index e7555d4e6ff1..e1ea29b0cd14 100644 --- a/trunk/drivers/net/arcnet/arc-rawmode.c +++ b/trunk/drivers/net/arcnet/arc-rawmode.c @@ -42,7 +42,7 @@ static int build_header(struct sk_buff *skb, struct net_device *dev, static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); -static struct ArcProto rawmode_proto = +struct ArcProto rawmode_proto = { .suffix = 'r', .mtu = XMTU, diff --git a/trunk/drivers/net/arcnet/arcnet.c b/trunk/drivers/net/arcnet/arcnet.c index 64e2caf3083d..12ef52c193a3 100644 --- a/trunk/drivers/net/arcnet/arcnet.c +++ b/trunk/drivers/net/arcnet/arcnet.c @@ -52,7 +52,6 @@ #include #include #include -#include /* "do nothing" functions for protocol drivers */ static void null_rx(struct net_device *dev, int bufnum, @@ -62,7 +61,6 @@ static int null_build_header(struct sk_buff *skb, struct net_device *dev, static int null_prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); -static void arcnet_rx(struct net_device *dev, int bufnum); /* * one ArcProto per possible proto ID. None of the elements of @@ -73,7 +71,7 @@ static void arcnet_rx(struct net_device *dev, int bufnum); struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto, *arc_raw_proto; -static struct ArcProto arc_proto_null = +struct ArcProto arc_proto_null = { .suffix = '?', .mtu = XMTU, @@ -92,6 +90,7 @@ EXPORT_SYMBOL(arc_proto_map); EXPORT_SYMBOL(arc_proto_default); EXPORT_SYMBOL(arc_bcast_proto); EXPORT_SYMBOL(arc_raw_proto); +EXPORT_SYMBOL(arc_proto_null); EXPORT_SYMBOL(arcnet_unregister_proto); EXPORT_SYMBOL(arcnet_debug); EXPORT_SYMBOL(alloc_arcdev); @@ -119,7 +118,7 @@ static int __init arcnet_init(void) arcnet_debug = debug; - printk("arcnet loaded.\n"); + printk(VERSION); #ifdef ALPHA_WARNING BUGLVL(D_EXTRA) { @@ -179,8 +178,8 @@ EXPORT_SYMBOL(arcnet_dump_skb); * Dump the contents of an ARCnet buffer */ #if (ARCNET_DEBUG_MAX & (D_RX | D_TX)) -static void arcnet_dump_packet(struct net_device *dev, int bufnum, - char *desc, int take_arcnet_lock) +void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc, + int take_arcnet_lock) { struct arcnet_local *lp = dev->priv; int i, length; @@ -209,10 +208,7 @@ static void arcnet_dump_packet(struct net_device *dev, int bufnum, } -#else - -#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) do { } while (0) - +EXPORT_SYMBOL(arcnet_dump_packet); #endif @@ -737,7 +733,7 @@ static void arcnet_timeout(struct net_device *dev) spin_unlock_irqrestore(&lp->lock, flags); - if (time_after(jiffies, lp->last_timeout + 10*HZ)) { + if (jiffies - lp->last_timeout > 10*HZ) { BUGMSG(D_EXTRA, "tx timed out%s (status=%Xh, intmask=%Xh, dest=%02Xh)\n", msg, status, lp->intmask, lp->lasttrans_dest); lp->last_timeout = jiffies; @@ -1000,7 +996,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) * This is a generic packet receiver that calls arcnet??_rx depending on the * protocol ID found. */ -static void arcnet_rx(struct net_device *dev, int bufnum) +void arcnet_rx(struct net_device *dev, int bufnum) { struct arcnet_local *lp = dev->priv; struct archdr pkt; diff --git a/trunk/drivers/net/arcnet/rfc1051.c b/trunk/drivers/net/arcnet/rfc1051.c index 6d6c69f036ef..6d7913704fb5 100644 --- a/trunk/drivers/net/arcnet/rfc1051.c +++ b/trunk/drivers/net/arcnet/rfc1051.c @@ -43,7 +43,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); -static struct ArcProto rfc1051_proto = +struct ArcProto rfc1051_proto = { .suffix = 's', .mtu = XMTU - RFC1051_HDR_SIZE, diff --git a/trunk/drivers/net/arcnet/rfc1201.c b/trunk/drivers/net/arcnet/rfc1201.c index bee34226abfa..6b6ae4bf3d39 100644 --- a/trunk/drivers/net/arcnet/rfc1201.c +++ b/trunk/drivers/net/arcnet/rfc1201.c @@ -43,7 +43,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, int bufnum); static int continue_tx(struct net_device *dev, int bufnum); -static struct ArcProto rfc1201_proto = +struct ArcProto rfc1201_proto = { .suffix = 'a', .mtu = 1500, /* could be more, but some receivers can't handle it... */ diff --git a/trunk/drivers/net/arm/etherh.c b/trunk/drivers/net/arm/etherh.c index d52deb8d2075..6a93b666eb72 100644 --- a/trunk/drivers/net/arm/etherh.c +++ b/trunk/drivers/net/arm/etherh.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include @@ -356,7 +355,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf dma_start = jiffies; while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_ERR "%s: timeout waiting for TX RDC\n", dev->name); etherh_reset (dev); diff --git a/trunk/drivers/net/b44.c b/trunk/drivers/net/b44.c index c3267e4e1bb0..df9d6e80c4f2 100644 --- a/trunk/drivers/net/b44.c +++ b/trunk/drivers/net/b44.c @@ -1399,6 +1399,7 @@ static int b44_open(struct net_device *dev) b44_init_rings(bp); b44_init_hw(bp); + netif_carrier_off(dev); b44_check_phy(bp); err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev); @@ -1463,7 +1464,7 @@ static int b44_close(struct net_device *dev) #endif b44_halt(bp); b44_free_rings(bp); - netif_carrier_off(dev); + netif_carrier_off(bp->dev); spin_unlock_irq(&bp->lock); @@ -1999,8 +2000,6 @@ static int __devinit b44_init_one(struct pci_dev *pdev, dev->irq = pdev->irq; SET_ETHTOOL_OPS(dev, &b44_ethtool_ops); - netif_carrier_off(dev); - err = b44_get_invariants(bp); if (err) { printk(KERN_ERR PFX "Problem fetching invariants of chip, " diff --git a/trunk/drivers/net/bonding/bond_main.c b/trunk/drivers/net/bonding/bond_main.c index 4ff006c37626..2582d98ef5c3 100644 --- a/trunk/drivers/net/bonding/bond_main.c +++ b/trunk/drivers/net/bonding/bond_main.c @@ -576,7 +576,7 @@ static int bond_update_speed_duplex(struct slave *slave) slave->duplex = DUPLEX_FULL; if (slave_dev->ethtool_ops) { - int res; + u32 res; if (!slave_dev->ethtool_ops->get_settings) { return -1; diff --git a/trunk/drivers/net/eth16i.c b/trunk/drivers/net/eth16i.c index b67545be2caa..f32a6b3acb2a 100644 --- a/trunk/drivers/net/eth16i.c +++ b/trunk/drivers/net/eth16i.c @@ -161,7 +161,6 @@ static char *version = #include #include #include -#include #include #include @@ -755,7 +754,7 @@ static void eth16i_set_port(int ioaddr, int porttype) static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) { - unsigned long starttime; + int starttime; outb(0xff, ioaddr + TX_STATUS_REG); @@ -766,7 +765,7 @@ static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) outb(TX_START | 1, ioaddr + TRANSMIT_START_REG); while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) { - if( time_after(jiffies, starttime + TX_TIMEOUT)) { + if( (jiffies - starttime) > TX_TIMEOUT) { return -1; } } @@ -776,18 +775,18 @@ static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l) static int eth16i_receive_probe_packet(int ioaddr) { - unsigned long starttime; + int starttime; starttime = jiffies; while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) { - if( time_after(jiffies, starttime + TX_TIMEOUT)) { + if( (jiffies - starttime) > TX_TIMEOUT) { if(eth16i_debug > 1) printk(KERN_DEBUG "Timeout occurred waiting transmit packet received\n"); starttime = jiffies; while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) { - if( time_after(jiffies, starttime + TX_TIMEOUT)) { + if( (jiffies - starttime) > TX_TIMEOUT) { if(eth16i_debug > 1) printk(KERN_DEBUG "Timeout occurred waiting receive packet\n"); return -1; diff --git a/trunk/drivers/net/hamradio/baycom_epp.c b/trunk/drivers/net/hamradio/baycom_epp.c index 9220de9f4fe7..e4188d082f01 100644 --- a/trunk/drivers/net/hamradio/baycom_epp.c +++ b/trunk/drivers/net/hamradio/baycom_epp.c @@ -905,7 +905,7 @@ static int epp_open(struct net_device *dev) /* autoprobe baud rate */ tstart = jiffies; i = 0; - while (time_before(jiffies, tstart + HZ/3)) { + while ((signed)(jiffies-tstart-HZ/3) < 0) { if (pp->ops->epp_read_addr(pp, &stat, 1, 0) != 1) goto epptimeout; if ((stat & (EPP_NRAEF|EPP_NRHF)) == EPP_NRHF) { diff --git a/trunk/drivers/net/hp100.c b/trunk/drivers/net/hp100.c index a37b82ebca37..55c7ed608391 100644 --- a/trunk/drivers/net/hp100.c +++ b/trunk/drivers/net/hp100.c @@ -115,7 +115,6 @@ #include #include #include -#include #include @@ -1500,7 +1499,7 @@ static int hp100_start_xmit_bm(struct sk_buff *skb, struct net_device *dev) printk("hp100: %s: start_xmit_bm: No TX PDL available.\n", dev->name); #endif /* not waited long enough since last tx? */ - if (time_before(jiffies, dev->trans_start + HZ)) + if (jiffies - dev->trans_start < HZ) return -EAGAIN; if (hp100_check_lan(dev)) @@ -1653,7 +1652,7 @@ static int hp100_start_xmit(struct sk_buff *skb, struct net_device *dev) printk("hp100: %s: start_xmit: tx free mem = 0x%x\n", dev->name, i); #endif /* not waited long enough since last failed tx try? */ - if (time_before(jiffies, dev->trans_start + HZ)) { + if (jiffies - dev->trans_start < HZ) { #ifdef HP100_DEBUG printk("hp100: %s: trans_start timing problem\n", dev->name); diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index df572018595e..40ae36b20c9d 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -79,15 +79,10 @@ #define PHY_WAIT_MICRO_SECONDS 10 /* Static function declarations */ +static int eth_port_link_is_up(unsigned int eth_port_num); static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *MacAddr); static void eth_port_set_multicast_list(struct net_device *); -static void mv643xx_eth_port_enable_tx(unsigned int port_num, - unsigned int channels); -static void mv643xx_eth_port_enable_rx(unsigned int port_num, - unsigned int channels); -static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num); -static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num); static int mv643xx_eth_open(struct net_device *); static int mv643xx_eth_stop(struct net_device *); static int mv643xx_eth_change_mtu(struct net_device *, int); @@ -96,12 +91,8 @@ static void eth_port_init_mac_tables(unsigned int eth_port_num); #ifdef MV643XX_NAPI static int mv643xx_poll(struct net_device *dev, int *budget); #endif -static int ethernet_phy_get(unsigned int eth_port_num); static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); static int ethernet_phy_detect(unsigned int eth_port_num); -static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location); -static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val); -static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static struct ethtool_ops mv643xx_ethtool_ops; static char mv643xx_driver_name[] = "mv643xx_eth"; @@ -178,11 +169,11 @@ static void mv643xx_eth_rx_task(void *data) if (test_and_set_bit(0, &mp->rx_task_busy)) panic("%s: Error in test_set_bit / clear_bit", dev->name); - while (mp->rx_desc_count < (mp->rx_ring_size - 5)) { + while (mp->rx_ring_skbs < (mp->rx_ring_size - 5)) { skb = dev_alloc_skb(RX_SKB_SIZE + DMA_ALIGN); if (!skb) break; - mp->rx_desc_count++; + mp->rx_ring_skbs++; unaligned = (u32)skb->data & (DMA_ALIGN - 1); if (unaligned) skb_reserve(skb, DMA_ALIGN - unaligned); @@ -203,7 +194,7 @@ static void mv643xx_eth_rx_task(void *data) * If RX ring is empty of SKB, set a timer to try allocating * again in a later time . */ - if ((mp->rx_desc_count == 0) && (mp->rx_timer_flag == 0)) { + if ((mp->rx_ring_skbs == 0) && (mp->rx_timer_flag == 0)) { printk(KERN_INFO "%s: Rx ring is empty\n", dev->name); /* After 100mSec */ mp->timeout.expires = jiffies + (HZ / 10); @@ -252,7 +243,8 @@ static void mv643xx_eth_update_mac_address(struct net_device *dev) unsigned int port_num = mp->port_num; eth_port_init_mac_tables(port_num); - eth_port_uc_addr_set(port_num, dev->dev_addr); + memcpy(mp->port_mac_addr, dev->dev_addr, 6); + eth_port_uc_addr_set(port_num, mp->port_mac_addr); } /* @@ -266,14 +258,13 @@ static void mv643xx_eth_update_mac_address(struct net_device *dev) static void mv643xx_eth_set_rx_mode(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); - u32 config_reg; - config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num)); if (dev->flags & IFF_PROMISC) - config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; + mp->port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; else - config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; - mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), config_reg); + mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; + + mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config); eth_port_set_multicast_list(dev); } @@ -329,7 +320,7 @@ static void mv643xx_eth_tx_timeout_task(struct net_device *dev) netif_device_detach(dev); eth_port_reset(mp->port_num); - eth_port_start(dev); + eth_port_start(mp); netif_device_attach(dev); } @@ -404,7 +395,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev) #else while (eth_port_receive(mp, &pkt_info) == ETH_OK) { #endif - mp->rx_desc_count--; + mp->rx_ring_skbs--; received_packets++; /* Update statistics. Note byte count includes 4 byte CRC count */ @@ -453,62 +444,11 @@ static int mv643xx_eth_receive_queue(struct net_device *dev) netif_rx(skb); #endif } - dev->last_rx = jiffies; } return received_packets; } -/* Set the mv643xx port configuration register for the speed/duplex mode. */ -static void mv643xx_eth_update_pscr(struct net_device *dev, - struct ethtool_cmd *ecmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - int port_num = mp->port_num; - u32 o_pscr, n_pscr; - unsigned int channels; - - o_pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); - n_pscr = o_pscr; - - /* clear speed, duplex and rx buffer size fields */ - n_pscr &= ~(MV643XX_ETH_SET_MII_SPEED_TO_100 | - MV643XX_ETH_SET_GMII_SPEED_TO_1000 | - MV643XX_ETH_SET_FULL_DUPLEX_MODE | - MV643XX_ETH_MAX_RX_PACKET_MASK); - - if (ecmd->duplex == DUPLEX_FULL) - n_pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE; - - if (ecmd->speed == SPEED_1000) - n_pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000 | - MV643XX_ETH_MAX_RX_PACKET_9700BYTE; - else { - if (ecmd->speed == SPEED_100) - n_pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100; - n_pscr |= MV643XX_ETH_MAX_RX_PACKET_1522BYTE; - } - - if (n_pscr != o_pscr) { - if ((o_pscr & MV643XX_ETH_SERIAL_PORT_ENABLE) == 0) - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - n_pscr); - else { - channels = mv643xx_eth_port_disable_tx(port_num); - - o_pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE; - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - o_pscr); - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - n_pscr); - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), - n_pscr); - if (channels) - mv643xx_eth_port_enable_tx(port_num, channels); - } - } -} - /* * mv643xx_eth_int_handler * @@ -521,7 +461,7 @@ static void mv643xx_eth_update_pscr(struct net_device *dev, */ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, - struct pt_regs *regs) + struct pt_regs *regs) { struct net_device *dev = (struct net_device *)dev_id; struct mv643xx_private *mp = netdev_priv(dev); @@ -554,7 +494,7 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, /* UDP change : We may need this */ if ((eth_int_cause_ext & 0x0000ffff) && (mv643xx_eth_free_tx_queue(dev, eth_int_cause_ext) == 0) && - (mp->tx_ring_size > mp->tx_desc_count + MAX_DESCS_PER_SKB)) + (mp->tx_ring_size > mp->tx_ring_skbs + MAX_DESCS_PER_SKB)) netif_wake_queue(dev); #ifdef MV643XX_NAPI } else { @@ -591,23 +531,15 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, } /* PHY status changed */ if (eth_int_cause_ext & (BIT16 | BIT20)) { - struct ethtool_cmd cmd; - - if (mii_link_ok(&mp->mii)) { - mii_ethtool_gset(&mp->mii, &cmd); - mv643xx_eth_update_pscr(dev, &cmd); - if (!netif_carrier_ok(dev)) { - netif_carrier_on(dev); - if (mp->tx_ring_size > mp->tx_desc_count + - MAX_DESCS_PER_SKB) { - netif_wake_queue(dev); - /* Start TX queue */ - mv643xx_eth_port_enable_tx(port_num, mp->port_tx_queue_command); - } - } - } else if (netif_carrier_ok(dev)) { - netif_stop_queue(dev); + if (eth_port_link_is_up(port_num)) { + netif_carrier_on(dev); + netif_wake_queue(dev); + /* Start TX queue */ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG + (port_num), 1); + } else { netif_carrier_off(dev); + netif_stop_queue(dev); } } @@ -736,8 +668,8 @@ static void ether_init_rx_desc_ring(struct mv643xx_private *mp) mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc); - /* Enable queue 0 for this port */ - mp->port_rx_queue_command = 1; + /* Add the queue to the list of RX queues of this port */ + mp->port_rx_queue_command |= 1; } /* @@ -783,36 +715,8 @@ static void ether_init_tx_desc_ring(struct mv643xx_private *mp) mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc); - /* Enable queue 0 for this port */ - mp->port_tx_queue_command = 1; -} - -static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - int err; - - spin_lock_irq(&mp->lock); - err = mii_ethtool_sset(&mp->mii, cmd); - spin_unlock_irq(&mp->lock); - - return err; -} - -static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - int err; - - spin_lock_irq(&mp->lock); - err = mii_ethtool_gset(&mp->mii, cmd); - spin_unlock_irq(&mp->lock); - - /* The PHY may support 1000baseT_Half, but the mv643xx does not */ - cmd->supported &= ~SUPPORTED_1000baseT_Half; - cmd->advertising &= ~ADVERTISED_1000baseT_Half; - - return err; + /* Add the queue to the list of Tx queues of this port */ + mp->port_tx_queue_command |= 1; } /* @@ -843,6 +747,12 @@ static int mv643xx_eth_open(struct net_device *dev) return -EAGAIN; } + /* Stop RX Queues */ + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); + + /* Set the MAC Address */ + memcpy(mp->port_mac_addr, dev->dev_addr, 6); + eth_port_init(mp); INIT_WORK(&mp->rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev); @@ -871,7 +781,7 @@ static int mv643xx_eth_open(struct net_device *dev) } /* Allocate TX ring */ - mp->tx_desc_count = 0; + mp->tx_ring_skbs = 0; size = mp->tx_ring_size * sizeof(struct eth_tx_desc); mp->tx_desc_area_size = size; @@ -896,7 +806,7 @@ static int mv643xx_eth_open(struct net_device *dev) ether_init_tx_desc_ring(mp); /* Allocate RX ring */ - mp->rx_desc_count = 0; + mp->rx_ring_skbs = 0; size = mp->rx_ring_size * sizeof(struct eth_rx_desc); mp->rx_desc_area_size = size; @@ -928,11 +838,7 @@ static int mv643xx_eth_open(struct net_device *dev) mv643xx_eth_rx_task(dev); /* Fill RX ring with skb's */ - /* Clear any pending ethernet port interrupts */ - mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); - mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); - - eth_port_start(dev); + eth_port_start(mp); /* Interrupt Coalescing */ @@ -944,13 +850,16 @@ static int mv643xx_eth_open(struct net_device *dev) mp->tx_int_coal = eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL); + /* Clear any pending ethernet port interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); + /* Unmask phy and link status changes interrupts */ mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), INT_UNMASK_ALL_EXT); /* Unmask RX buffer and TX end interrupt */ mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL); - return 0; out_free_tx_skb: @@ -971,20 +880,20 @@ static void mv643xx_eth_free_tx_rings(struct net_device *dev) struct sk_buff *skb; /* Stop Tx Queues */ - mv643xx_eth_port_disable_tx(port_num); + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0x0000ff00); /* Free outstanding skb's on TX rings */ - for (curr = 0; mp->tx_desc_count && curr < mp->tx_ring_size; curr++) { + for (curr = 0; mp->tx_ring_skbs && curr < mp->tx_ring_size; curr++) { skb = mp->tx_skb[curr]; if (skb) { - mp->tx_desc_count -= skb_shinfo(skb)->nr_frags; + mp->tx_ring_skbs -= skb_shinfo(skb)->nr_frags; dev_kfree_skb(skb); - mp->tx_desc_count--; + mp->tx_ring_skbs--; } } - if (mp->tx_desc_count) + if (mp->tx_ring_skbs) printk("%s: Error on Tx descriptor free - could not free %d" - " descriptors\n", dev->name, mp->tx_desc_count); + " descriptors\n", dev->name, mp->tx_ring_skbs); /* Free TX ring */ if (mp->tx_sram_size) @@ -1001,21 +910,21 @@ static void mv643xx_eth_free_rx_rings(struct net_device *dev) int curr; /* Stop RX Queues */ - mv643xx_eth_port_disable_rx(port_num); + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); /* Free preallocated skb's on RX rings */ - for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) { + for (curr = 0; mp->rx_ring_skbs && curr < mp->rx_ring_size; curr++) { if (mp->rx_skb[curr]) { dev_kfree_skb(mp->rx_skb[curr]); - mp->rx_desc_count--; + mp->rx_ring_skbs--; } } - if (mp->rx_desc_count) + if (mp->rx_ring_skbs) printk(KERN_ERR "%s: Error in freeing Rx Ring. %d skb's still" " stuck in RX Ring - ignoring them\n", dev->name, - mp->rx_desc_count); + mp->rx_ring_skbs); /* Free RX ring */ if (mp->rx_sram_size) iounmap(mp->p_rx_desc_area); @@ -1085,8 +994,7 @@ static void mv643xx_tx(struct net_device *dev) } if (netif_queue_stopped(dev) && - mp->tx_ring_size > - mp->tx_desc_count + MAX_DESCS_PER_SKB) + mp->tx_ring_size > mp->tx_ring_skbs + MAX_DESCS_PER_SKB) netif_wake_queue(dev); } @@ -1139,15 +1047,16 @@ static int mv643xx_poll(struct net_device *dev, int *budget) static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) { - unsigned int frag; - skb_frag_t *fragp; + unsigned int frag; + skb_frag_t *fragp; - for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - fragp = &skb_shinfo(skb)->frags[frag]; - if (fragp->size <= 8 && fragp->page_offset & 0x7) - return 1; - } - return 0; + for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { + fragp = &skb_shinfo(skb)->frags[frag]; + if (fragp->size <= 8 && fragp->page_offset & 0x7) + return 1; + + } + return 0; } @@ -1178,7 +1087,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) } /* This is a hard error, log it. */ - if ((mp->tx_ring_size - mp->tx_desc_count) <= + if ((mp->tx_ring_size - mp->tx_ring_skbs) <= (skb_shinfo(skb)->nr_frags + 1)) { netif_stop_queue(dev); printk(KERN_ERR @@ -1355,7 +1264,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Check if TX queue can handle another skb. If not, then * signal higher layers to stop requesting TX */ - if (mp->tx_ring_size <= (mp->tx_desc_count + MAX_DESCS_PER_SKB)) + if (mp->tx_ring_size <= (mp->tx_ring_skbs + MAX_DESCS_PER_SKB)) /* * Stop getting skb's from upper layers. * Getting skb's from upper layers will be enabled again after @@ -1405,35 +1314,6 @@ static void mv643xx_netpoll(struct net_device *netdev) } #endif -static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address, - int speed, int duplex, - struct ethtool_cmd *cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - memset(cmd, 0, sizeof(*cmd)); - - cmd->port = PORT_MII; - cmd->transceiver = XCVR_INTERNAL; - cmd->phy_address = phy_address; - - if (speed == 0) { - cmd->autoneg = AUTONEG_ENABLE; - /* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */ - cmd->speed = SPEED_100; - cmd->advertising = ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full; - if (mp->mii.supports_gmii) - cmd->advertising |= ADVERTISED_1000baseT_Full; - } else { - cmd->autoneg = AUTONEG_DISABLE; - cmd->speed = speed; - cmd->duplex = duplex; - } -} - /*/ * mv643xx_eth_probe * @@ -1454,9 +1334,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) u8 *p; struct resource *res; int err; - struct ethtool_cmd cmd; - int duplex = DUPLEX_HALF; - int speed = 0; /* default to auto-negotiation */ dev = alloc_etherdev(sizeof(struct mv643xx_private)); if (!dev) @@ -1494,7 +1371,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev->tx_queue_len = mp->tx_ring_size; dev->base_addr = 0; dev->change_mtu = mv643xx_eth_change_mtu; - dev->do_ioctl = mv643xx_eth_do_ioctl; SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops); #ifdef MV643XX_CHECKSUM_OFFLOAD_TX @@ -1515,17 +1391,33 @@ static int mv643xx_eth_probe(struct platform_device *pdev) /* set default config values */ eth_port_uc_addr_get(dev, dev->dev_addr); + mp->port_config = MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE; + mp->port_config_extend = MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE; + mp->port_sdma_config = MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE; + mp->port_serial_control = MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE; mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE; mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE; pd = pdev->dev.platform_data; if (pd) { - if (pd->mac_addr) + if (pd->mac_addr != NULL) memcpy(dev->dev_addr, pd->mac_addr, 6); if (pd->phy_addr || pd->force_phy_addr) ethernet_phy_set(port_num, pd->phy_addr); + if (pd->port_config || pd->force_port_config) + mp->port_config = pd->port_config; + + if (pd->port_config_extend || pd->force_port_config_extend) + mp->port_config_extend = pd->port_config_extend; + + if (pd->port_sdma_config || pd->force_port_sdma_config) + mp->port_sdma_config = pd->port_sdma_config; + + if (pd->port_serial_control || pd->force_port_serial_control) + mp->port_serial_control = pd->port_serial_control; + if (pd->rx_queue_size) mp->rx_ring_size = pd->rx_queue_size; @@ -1541,33 +1433,16 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->rx_sram_size = pd->rx_sram_size; mp->rx_sram_addr = pd->rx_sram_addr; } - - duplex = pd->duplex; - speed = pd->speed; } - /* Hook up MII support for ethtool */ - mp->mii.dev = dev; - mp->mii.mdio_read = mv643xx_mdio_read; - mp->mii.mdio_write = mv643xx_mdio_write; - mp->mii.phy_id = ethernet_phy_get(port_num); - mp->mii.phy_id_mask = 0x3f; - mp->mii.reg_num_mask = 0x1f; - err = ethernet_phy_detect(port_num); if (err) { pr_debug("MV643xx ethernet port %d: " "No PHY detected at addr %d\n", port_num, ethernet_phy_get(port_num)); - goto out; + return err; } - ethernet_phy_reset(port_num); - mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii); - mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd); - mv643xx_eth_update_pscr(dev, &cmd); - mv643xx_set_settings(dev, &cmd); - err = register_netdev(dev); if (err) goto out; @@ -1831,6 +1706,7 @@ MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); * Prior to calling the initialization routine eth_port_init() the user * must set the following fields under mv643xx_private struct: * port_num User Ethernet port number. + * port_mac_addr[6] User defined port MAC address. * port_config User port configuration value. * port_config_extend User port config extend value. * port_sdma_config User port SDMA config value. @@ -1847,12 +1723,20 @@ MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); * return_info Tx/Rx user resource return information. */ +/* defines */ +/* SDMA command macros */ +#define ETH_ENABLE_TX_QUEUE(eth_port) \ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), 1) + +/* locals */ + /* PHY routines */ static int ethernet_phy_get(unsigned int eth_port_num); static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); /* Ethernet Port routines */ -static void eth_port_set_filter_table_entry(int table, unsigned char entry); +static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble, + int option); /* * eth_port_init - Initialize the Ethernet port driver @@ -1880,12 +1764,17 @@ static void eth_port_set_filter_table_entry(int table, unsigned char entry); */ static void eth_port_init(struct mv643xx_private *mp) { + mp->port_rx_queue_command = 0; + mp->port_tx_queue_command = 0; + mp->rx_resource_err = 0; mp->tx_resource_err = 0; eth_port_reset(mp->port_num); eth_port_init_mac_tables(mp->port_num); + + ethernet_phy_reset(mp->port_num); } /* @@ -1907,7 +1796,7 @@ static void eth_port_init(struct mv643xx_private *mp) * and ether_init_rx_desc_ring for Rx queues). * * INPUT: - * dev - a pointer to the required interface + * struct mv643xx_private *mp Ethernet port control struct * * OUTPUT: * Ethernet port is ready to receive and transmit. @@ -1915,13 +1804,10 @@ static void eth_port_init(struct mv643xx_private *mp) * RETURN: * None. */ -static void eth_port_start(struct net_device *dev) +static void eth_port_start(struct mv643xx_private *mp) { - struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; int tx_curr_desc, rx_curr_desc; - u32 pscr; - struct ethtool_cmd ethtool_cmd; /* Assignment of Tx CTRP of given queue */ tx_curr_desc = mp->tx_curr_desc_q; @@ -1934,45 +1820,37 @@ static void eth_port_start(struct net_device *dev) (u32)((struct eth_rx_desc *)mp->rx_desc_dma + rx_curr_desc)); /* Add the assigned Ethernet address to the port's address table */ - eth_port_uc_addr_set(port_num, dev->dev_addr); + eth_port_uc_addr_set(port_num, mp->port_mac_addr); /* Assign port configuration and command. */ - mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), - MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE); + mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp->port_config); mv_write(MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port_num), - MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE); - - pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); + mp->port_config_extend); - pscr &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE | MV643XX_ETH_FORCE_LINK_PASS); - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); - pscr |= MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL | - MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII | - MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX | - MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL | - MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED; - - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); + /* Increase the Rx side buffer size if supporting GigE */ + if (mp->port_serial_control & MV643XX_ETH_SET_GMII_SPEED_TO_1000) + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), + (mp->port_serial_control & 0xfff1ffff) | (0x5 << 17)); + else + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), + mp->port_serial_control); - pscr |= MV643XX_ETH_SERIAL_PORT_ENABLE; - mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr); + mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), + mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)) | + MV643XX_ETH_SERIAL_PORT_ENABLE); /* Assign port SDMA configuration */ mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num), - MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE); + mp->port_sdma_config); /* Enable port Rx. */ - mv643xx_eth_port_enable_rx(port_num, mp->port_rx_queue_command); + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), + mp->port_rx_queue_command); /* Disable port bandwidth limits by clearing MTU register */ mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0); - - /* save phy settings across reset */ - mv643xx_get_settings(dev, ðtool_cmd); - ethernet_phy_reset(mp->port_num); - mv643xx_set_settings(dev, ðtool_cmd); } /* @@ -1986,9 +1864,8 @@ static void eth_port_start(struct net_device *dev) * char * p_addr Address to be set * * OUTPUT: - * Set MAC address low and high registers. also calls - * eth_port_set_filter_table_entry() to set the unicast - * table with the proper information. + * Set MAC address low and high registers. also calls eth_port_uc_addr() + * To set the unicast table with the proper information. * * RETURN: * N/A. @@ -1999,7 +1876,6 @@ static void eth_port_uc_addr_set(unsigned int eth_port_num, { unsigned int mac_h; unsigned int mac_l; - int table; mac_l = (p_addr[4] << 8) | (p_addr[5]); mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | @@ -2009,8 +1885,9 @@ static void eth_port_uc_addr_set(unsigned int eth_port_num, mv_write(MV643XX_ETH_MAC_ADDR_HIGH(eth_port_num), mac_h); /* Accept frames of this address */ - table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(eth_port_num); - eth_port_set_filter_table_entry(table, p_addr[5] & 0x0f); + eth_port_uc_addr(eth_port_num, p_addr[5], ACCEPT_MAC_ADDR); + + return; } /* @@ -2048,6 +1925,72 @@ static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *p_addr) p_addr[5] = mac_l & 0xff; } +/* + * eth_port_uc_addr - This function Set the port unicast address table + * + * DESCRIPTION: + * This function locates the proper entry in the Unicast table for the + * specified MAC nibble and sets its properties according to function + * parameters. + * + * INPUT: + * unsigned int eth_port_num Port number. + * unsigned char uc_nibble Unicast MAC Address last nibble. + * int option 0 = Add, 1 = remove address. + * + * OUTPUT: + * This function add/removes MAC addresses from the port unicast address + * table. + * + * RETURN: + * true is output succeeded. + * false if option parameter is invalid. + * + */ +static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble, + int option) +{ + unsigned int unicast_reg; + unsigned int tbl_offset; + unsigned int reg_offset; + + /* Locate the Unicast table entry */ + uc_nibble = (0xf & uc_nibble); + tbl_offset = (uc_nibble / 4) * 4; /* Register offset from unicast table base */ + reg_offset = uc_nibble % 4; /* Entry offset within the above register */ + + switch (option) { + case REJECT_MAC_ADDR: + /* Clear accepts frame bit at given unicast DA table entry */ + unicast_reg = mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset)); + + unicast_reg &= (0x0E << (8 * reg_offset)); + + mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset), unicast_reg); + break; + + case ACCEPT_MAC_ADDR: + /* Set accepts frame bit at unicast DA filter table entry */ + unicast_reg = + mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset)); + + unicast_reg |= (0x01 << (8 * reg_offset)); + + mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + tbl_offset), unicast_reg); + + break; + + default: + return 0; + } + + return 1; +} + /* * The entries in each table are indexed by a hash of a packet's MAC * address. One bit in each entry determines whether the packet is @@ -2194,26 +2137,26 @@ static void eth_port_set_multicast_list(struct net_device *dev) */ if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) { for (table_index = 0; table_index <= 0xFC; table_index += 4) { - /* Set all entries in DA filter special multicast - * table (Ex_dFSMT) - * Set for ETH_Q0 for now - * Bits - * 0 Accept=1, Drop=0 - * 3-1 Queue ETH_Q0=0 - * 7-4 Reserved = 0; - */ - mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); - - /* Set all entries in DA filter other multicast - * table (Ex_dFOMT) - * Set for ETH_Q0 for now - * Bits - * 0 Accept=1, Drop=0 - * 3-1 Queue ETH_Q0=0 - * 7-4 Reserved = 0; - */ - mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); - } + /* Set all entries in DA filter special multicast + * table (Ex_dFSMT) + * Set for ETH_Q0 for now + * Bits + * 0 Accept=1, Drop=0 + * 3-1 Queue ETH_Q0=0 + * 7-4 Reserved = 0; + */ + mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); + + /* Set all entries in DA filter other multicast + * table (Ex_dFOMT) + * Set for ETH_Q0 for now + * Bits + * 0 Accept=1, Drop=0 + * 3-1 Queue ETH_Q0=0 + * 7-4 Reserved = 0; + */ + mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); + } return; } @@ -2260,8 +2203,8 @@ static void eth_port_init_mac_tables(unsigned int eth_port_num) /* Clear DA filter unicast table (Ex_dFUT) */ for (table_index = 0; table_index <= 0xC; table_index += 4) - mv_write(MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE - (eth_port_num) + table_index, 0); + mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE + (eth_port_num) + table_index), 0); for (table_index = 0; table_index <= 0xFC; table_index += 4) { /* Clear DA filter special multicast table (Ex_dFSMT) */ @@ -2444,73 +2387,6 @@ static void ethernet_phy_reset(unsigned int eth_port_num) eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data); phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */ eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data); - - /* wait for PHY to come out of reset */ - do { - udelay(1); - eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data); - } while (phy_reg_data & 0x8000); -} - -static void mv643xx_eth_port_enable_tx(unsigned int port_num, - unsigned int channels) -{ - mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), channels); -} - -static void mv643xx_eth_port_enable_rx(unsigned int port_num, - unsigned int channels) -{ - mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), channels); -} - -static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num) -{ - u32 channels; - - /* Stop Tx port activity. Check port Tx activity. */ - channels = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) - & 0xFF; - if (channels) { - /* Issue stop command for active channels only */ - mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), - (channels << 8)); - - /* Wait for all Tx activity to terminate. */ - /* Check port cause register that all Tx queues are stopped */ - while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) - & 0xFF) - udelay(PHY_WAIT_MICRO_SECONDS); - - /* Wait for Tx FIFO to empty */ - while (mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)) & - ETH_PORT_TX_FIFO_EMPTY) - udelay(PHY_WAIT_MICRO_SECONDS); - } - - return channels; -} - -static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num) -{ - u32 channels; - - /* Stop Rx port activity. Check port Rx activity. */ - channels = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num) - & 0xFF); - if (channels) { - /* Issue stop command for active channels only */ - mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), - (channels << 8)); - - /* Wait for all Rx activity to terminate. */ - /* Check port cause register that all Rx queues are stopped */ - while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)) - & 0xFF) - udelay(PHY_WAIT_MICRO_SECONDS); - } - - return channels; } /* @@ -2535,21 +2411,70 @@ static void eth_port_reset(unsigned int port_num) { unsigned int reg_data; - mv643xx_eth_port_disable_tx(port_num); - mv643xx_eth_port_disable_rx(port_num); + /* Stop Tx port activity. Check port Tx activity. */ + reg_data = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), + (reg_data << 8)); + + /* Wait for all Tx activity to terminate. */ + /* Check port cause register that all Tx queues are stopped */ + while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num)) + & 0xFF) + udelay(10); + } + + /* Stop Rx port activity. Check port Rx activity. */ + reg_data = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)); + + if (reg_data & 0xFF) { + /* Issue stop command for active channels only */ + mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), + (reg_data << 8)); + + /* Wait for all Rx activity to terminate. */ + /* Check port cause register that all Rx queues are stopped */ + while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num)) + & 0xFF) + udelay(10); + } /* Clear all MIB counters */ eth_clear_mib_counters(port_num); /* Reset the Enable bit in the Configuration Register */ reg_data = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); - reg_data &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE | - MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL | - MV643XX_ETH_FORCE_LINK_PASS); + reg_data &= ~MV643XX_ETH_SERIAL_PORT_ENABLE; mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data); } +static int eth_port_autoneg_supported(unsigned int eth_port_num) +{ + unsigned int phy_reg_data0; + + eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data0); + + return phy_reg_data0 & 0x1000; +} + +static int eth_port_link_is_up(unsigned int eth_port_num) +{ + unsigned int phy_reg_data1; + + eth_port_read_smi_reg(eth_port_num, 1, &phy_reg_data1); + + if (eth_port_autoneg_supported(eth_port_num)) { + if (phy_reg_data1 & 0x20) /* auto-neg complete */ + return 1; + } else if (phy_reg_data1 & 0x4) /* link up */ + return 1; + + return 0; +} + /* * eth_port_read_smi_reg - Read PHY registers * @@ -2654,24 +2579,6 @@ static void eth_port_write_smi_reg(unsigned int eth_port_num, spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags); } -/* - * Wrappers for MII support library. - */ -static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location) -{ - int val; - struct mv643xx_private *mp = netdev_priv(dev); - - eth_port_read_smi_reg(mp->port_num, location, &val); - return val; -} - -static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val) -{ - struct mv643xx_private *mp = netdev_priv(dev); - eth_port_write_smi_reg(mp->port_num, location, val); -} - /* * eth_port_send - Send an Ethernet packet * @@ -2710,6 +2617,7 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, struct eth_tx_desc *current_descriptor; struct eth_tx_desc *first_descriptor; u32 command; + unsigned long flags; /* Do not process Tx ring in case of Tx ring resource error */ if (mp->tx_resource_err) @@ -2726,8 +2634,10 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, return ETH_ERROR; } - mp->tx_desc_count++; - BUG_ON(mp->tx_desc_count > mp->tx_ring_size); + spin_lock_irqsave(&mp->lock, flags); + + mp->tx_ring_skbs++; + BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); /* Get the Tx Desc ring indexes */ tx_desc_curr = mp->tx_curr_desc_q; @@ -2761,7 +2671,7 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, first_descriptor->cmd_sts = mp->tx_first_command; wmb(); - mv643xx_eth_port_enable_tx(mp->port_num, mp->port_tx_queue_command); + ETH_ENABLE_TX_QUEUE(mp->port_num); /* * Finish Tx packet. Update first desc in case of Tx resource @@ -2775,11 +2685,15 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, mp->tx_resource_err = 1; mp->tx_curr_desc_q = tx_first_desc; + spin_unlock_irqrestore(&mp->lock, flags); + return ETH_QUEUE_LAST_RESOURCE; } mp->tx_curr_desc_q = tx_next_desc; + spin_unlock_irqrestore(&mp->lock, flags); + return ETH_OK; } #else @@ -2790,13 +2704,16 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, int tx_desc_used; struct eth_tx_desc *current_descriptor; unsigned int command_status; + unsigned long flags; /* Do not process Tx ring in case of Tx ring resource error */ if (mp->tx_resource_err) return ETH_QUEUE_FULL; - mp->tx_desc_count++; - BUG_ON(mp->tx_desc_count > mp->tx_ring_size); + spin_lock_irqsave(&mp->lock, flags); + + mp->tx_ring_skbs++; + BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); /* Get the Tx Desc ring indexes */ tx_desc_curr = mp->tx_curr_desc_q; @@ -2814,7 +2731,7 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT; wmb(); - mv643xx_eth_port_enable_tx(mp->port_num, mp->port_tx_queue_command); + ETH_ENABLE_TX_QUEUE(mp->port_num); /* Finish Tx packet. Update first desc in case of Tx resource error */ tx_desc_curr = (tx_desc_curr + 1) % mp->tx_ring_size; @@ -2825,9 +2742,12 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, /* Check for ring index overlap in the Tx desc ring */ if (tx_desc_curr == tx_desc_used) { mp->tx_resource_err = 1; + + spin_unlock_irqrestore(&mp->lock, flags); return ETH_QUEUE_LAST_RESOURCE; } + spin_unlock_irqrestore(&mp->lock, flags); return ETH_OK; } #endif @@ -2910,8 +2830,8 @@ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp, /* Any Tx return cancels the Tx resource error status */ mp->tx_resource_err = 0; - BUG_ON(mp->tx_desc_count == 0); - mp->tx_desc_count--; + BUG_ON(mp->tx_ring_skbs == 0); + mp->tx_ring_skbs--; out: spin_unlock_irqrestore(&mp->lock, flags); @@ -2978,10 +2898,8 @@ static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, p_pkt_info->return_info = mp->rx_skb[rx_curr_desc]; p_pkt_info->l4i_chk = p_rx_desc->buf_size; - /* - * Clean the return info field to indicate that the - * packet has been moved to the upper layers - */ + /* Clean the return info field to indicate that the packet has been */ + /* moved to the upper layers */ mp->rx_skb[rx_curr_desc] = NULL; /* Update current index in data structure */ @@ -3062,7 +2980,7 @@ struct mv643xx_stats { }; #define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \ - offsetof(struct mv643xx_private, m) + offsetof(struct mv643xx_private, m) static const struct mv643xx_stats mv643xx_gstrings_stats[] = { { "rx_packets", MV643XX_STAT(stats.rx_packets) }, @@ -3108,8 +3026,114 @@ static const struct mv643xx_stats mv643xx_gstrings_stats[] = { #define MV643XX_STATS_LEN \ sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats) -static void mv643xx_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) +static int +mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + struct mv643xx_private *mp = netdev->priv; + int port_num = mp->port_num; + int autoneg = eth_port_autoneg_supported(port_num); + int mode_10_bit; + int auto_duplex; + int half_duplex = 0; + int full_duplex = 0; + int auto_speed; + int speed_10 = 0; + int speed_100 = 0; + int speed_1000 = 0; + + u32 pcs = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)); + u32 psr = mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)); + + mode_10_bit = psr & MV643XX_ETH_PORT_STATUS_MODE_10_BIT; + + if (mode_10_bit) { + ecmd->supported = SUPPORTED_10baseT_Half; + } else { + ecmd->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + (autoneg ? SUPPORTED_Autoneg : 0) | + SUPPORTED_TP); + + auto_duplex = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX); + auto_speed = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII); + + ecmd->advertising = ADVERTISED_TP; + + if (autoneg) { + ecmd->advertising |= ADVERTISED_Autoneg; + + if (auto_duplex) { + half_duplex = 1; + full_duplex = 1; + } else { + if (pcs & MV643XX_ETH_SET_FULL_DUPLEX_MODE) + full_duplex = 1; + else + half_duplex = 1; + } + + if (auto_speed) { + speed_10 = 1; + speed_100 = 1; + speed_1000 = 1; + } else { + if (pcs & MV643XX_ETH_SET_GMII_SPEED_TO_1000) + speed_1000 = 1; + else if (pcs & MV643XX_ETH_SET_MII_SPEED_TO_100) + speed_100 = 1; + else + speed_10 = 1; + } + + if (speed_10 & half_duplex) + ecmd->advertising |= ADVERTISED_10baseT_Half; + if (speed_10 & full_duplex) + ecmd->advertising |= ADVERTISED_10baseT_Full; + if (speed_100 & half_duplex) + ecmd->advertising |= ADVERTISED_100baseT_Half; + if (speed_100 & full_duplex) + ecmd->advertising |= ADVERTISED_100baseT_Full; + if (speed_1000) + ecmd->advertising |= ADVERTISED_1000baseT_Full; + } + } + + ecmd->port = PORT_TP; + ecmd->phy_address = ethernet_phy_get(port_num); + + ecmd->transceiver = XCVR_EXTERNAL; + + if (netif_carrier_ok(netdev)) { + if (mode_10_bit) + ecmd->speed = SPEED_10; + else { + if (psr & MV643XX_ETH_PORT_STATUS_GMII_1000) + ecmd->speed = SPEED_1000; + else if (psr & MV643XX_ETH_PORT_STATUS_MII_100) + ecmd->speed = SPEED_100; + else + ecmd->speed = SPEED_10; + } + + if (psr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX) + ecmd->duplex = DUPLEX_FULL; + else + ecmd->duplex = DUPLEX_HALF; + } else { + ecmd->speed = -1; + ecmd->duplex = -1; + } + + ecmd->autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE; + return 0; +} + +static void +mv643xx_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) { strncpy(drvinfo->driver, mv643xx_driver_name, 32); strncpy(drvinfo->version, mv643xx_driver_version, 32); @@ -3118,77 +3142,53 @@ static void mv643xx_get_drvinfo(struct net_device *netdev, drvinfo->n_stats = MV643XX_STATS_LEN; } -static int mv643xx_get_stats_count(struct net_device *netdev) +static int +mv643xx_get_stats_count(struct net_device *netdev) { return MV643XX_STATS_LEN; } -static void mv643xx_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, uint64_t *data) +static void +mv643xx_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, uint64_t *data) { struct mv643xx_private *mp = netdev->priv; int i; eth_update_mib_counters(mp); - for (i = 0; i < MV643XX_STATS_LEN; i++) { + for(i = 0; i < MV643XX_STATS_LEN; i++) { char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset; - data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == + data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p; } } -static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, - uint8_t *data) +static void +mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) { int i; switch(stringset) { case ETH_SS_STATS: for (i=0; i < MV643XX_STATS_LEN; i++) { - memcpy(data + i * ETH_GSTRING_LEN, - mv643xx_gstrings_stats[i].stat_string, - ETH_GSTRING_LEN); + memcpy(data + i * ETH_GSTRING_LEN, + mv643xx_gstrings_stats[i].stat_string, + ETH_GSTRING_LEN); } break; } } -static u32 mv643xx_eth_get_link(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - return mii_link_ok(&mp->mii); -} - -static int mv643xx_eth_nway_restart(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - return mii_nway_restart(&mp->mii); -} - -static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL); -} - static struct ethtool_ops mv643xx_ethtool_ops = { .get_settings = mv643xx_get_settings, - .set_settings = mv643xx_set_settings, .get_drvinfo = mv643xx_get_drvinfo, - .get_link = mv643xx_eth_get_link, + .get_link = ethtool_op_get_link, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_strings = mv643xx_get_strings, .get_stats_count = mv643xx_get_stats_count, .get_ethtool_stats = mv643xx_get_ethtool_stats, - .get_strings = mv643xx_get_strings, - .get_stats_count = mv643xx_get_stats_count, - .get_ethtool_stats = mv643xx_get_ethtool_stats, - .nway_reset = mv643xx_eth_nway_restart, }; /************* End ethtool support *************************/ diff --git a/trunk/drivers/net/mv643xx_eth.h b/trunk/drivers/net/mv643xx_eth.h index a553054e8da7..f769f9b626ea 100644 --- a/trunk/drivers/net/mv643xx_eth.h +++ b/trunk/drivers/net/mv643xx_eth.h @@ -5,7 +5,6 @@ #include #include #include -#include #include @@ -90,6 +89,10 @@ * */ +/* MAC accepet/reject macros */ +#define ACCEPT_MAC_ADDR 0 +#define REJECT_MAC_ADDR 1 + /* Buffer offset from buffer pointer */ #define RX_BUF_OFFSET 0x2 @@ -321,6 +324,11 @@ struct mv643xx_mib_counters { struct mv643xx_private { int port_num; /* User Ethernet port number */ + u8 port_mac_addr[6]; /* User defined port MAC address.*/ + u32 port_config; /* User port configuration value*/ + u32 port_config_extend; /* User port config extend value*/ + u32 port_sdma_config; /* User port SDMA config value */ + u32 port_serial_control; /* User port serial control value */ u32 port_tx_queue_command; /* Port active Tx queues summary*/ u32 port_rx_queue_command; /* Port active Rx queues summary*/ @@ -368,12 +376,12 @@ struct mv643xx_private { spinlock_t lock; /* Size of Tx Ring per queue */ unsigned int tx_ring_size; - /* Number of tx descriptors in use */ - unsigned int tx_desc_count; + /* Ammont of SKBs outstanding on Tx queue */ + unsigned int tx_ring_skbs; /* Size of Rx Ring per queue */ unsigned int rx_ring_size; - /* Number of rx descriptors in use */ - unsigned int rx_desc_count; + /* Ammount of SKBs allocated to Rx Ring per queue */ + unsigned int rx_ring_skbs; /* * rx_task used to fill RX ring out of bottom half context @@ -390,7 +398,6 @@ struct mv643xx_private { u32 rx_int_coal; u32 tx_int_coal; - struct mii_if_info mii; }; /* ethernet.h API list */ @@ -398,7 +405,7 @@ struct mv643xx_private { /* Port operation control routines */ static void eth_port_init(struct mv643xx_private *mp); static void eth_port_reset(unsigned int eth_port_num); -static void eth_port_start(struct net_device *dev); +static void eth_port_start(struct mv643xx_private *mp); /* Port MAC address routines */ static void eth_port_uc_addr_set(unsigned int eth_port_num, diff --git a/trunk/drivers/net/ne-h8300.c b/trunk/drivers/net/ne-h8300.c index aaebd28a1920..8f40368cf2e9 100644 --- a/trunk/drivers/net/ne-h8300.c +++ b/trunk/drivers/net/ne-h8300.c @@ -27,7 +27,6 @@ static const char version1[] = #include #include #include -#include #include #include @@ -366,7 +365,7 @@ static void ne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); break; } @@ -581,7 +580,7 @@ static void ne_block_output(struct net_device *dev, int count, #endif while ((inb_p(NE_BASE + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); ne_reset_8390(dev); NS8390_init(dev,1); diff --git a/trunk/drivers/net/ne.c b/trunk/drivers/net/ne.c index 08b218c5bfbc..94f782d51f0f 100644 --- a/trunk/drivers/net/ne.c +++ b/trunk/drivers/net/ne.c @@ -50,7 +50,6 @@ static const char version2[] = #include #include #include -#include #include #include @@ -342,7 +341,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { if (bad_card) { printk(" (warning: no reset ack)"); break; @@ -581,7 +580,7 @@ static void ne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); break; } @@ -788,7 +787,7 @@ static void ne_block_output(struct net_device *dev, int count, #endif while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); ne_reset_8390(dev); NS8390_init(dev,1); diff --git a/trunk/drivers/net/ne2.c b/trunk/drivers/net/ne2.c index 2aa7b77f84f8..e6df375a1d4b 100644 --- a/trunk/drivers/net/ne2.c +++ b/trunk/drivers/net/ne2.c @@ -75,7 +75,6 @@ static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon #include #include -#include #include #include @@ -396,7 +395,7 @@ static int __init ne2_probe1(struct net_device *dev, int slot) outb(inb(base_addr + NE_RESET), base_addr + NE_RESET); while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(" not found (no reset ack).\n"); retval = -ENODEV; goto out; @@ -549,7 +548,7 @@ static void ne_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk("%s: ne_reset_8390() did not complete.\n", dev->name); break; @@ -750,7 +749,7 @@ static void ne_block_output(struct net_device *dev, int count, #endif while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk("%s: timeout waiting for Tx RDC.\n", dev->name); ne_reset_8390(dev); NS8390_init(dev,1); diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c index 253cf018dfba..b0c3b6ab6263 100644 --- a/trunk/drivers/net/ns83820.c +++ b/trunk/drivers/net/ns83820.c @@ -116,7 +116,6 @@ #include #include #include -#include #include #include @@ -1608,7 +1607,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab { struct ns83820 *dev = PRIV(ndev); int timed_out = 0; - unsigned long start; + long start; u32 status; int loops = 0; @@ -1626,7 +1625,7 @@ static void ns83820_run_bist(struct net_device *ndev, const char *name, u32 enab break; if (status & fail) break; - if (time_after_eq(jiffies, start + HZ)) { + if ((jiffies - start) >= HZ) { timed_out = 1; break; } diff --git a/trunk/drivers/net/oaknet.c b/trunk/drivers/net/oaknet.c index d0f686d6eaaa..62167a29debe 100644 --- a/trunk/drivers/net/oaknet.c +++ b/trunk/drivers/net/oaknet.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -607,7 +606,7 @@ oaknet_block_output(struct net_device *dev, int count, #endif while ((ei_ibp(base + EN0_ISR) & ENISR_RDC) == 0) { - if (time_after(jiffies, start + OAKNET_WAIT)) { + if (jiffies - start > OAKNET_WAIT) { printk("%s: timeout waiting for Tx RDC.\n", dev->name); oaknet_reset_8390(dev); NS8390_init(dev, TRUE); diff --git a/trunk/drivers/net/pcmcia/3c589_cs.c b/trunk/drivers/net/pcmcia/3c589_cs.c index c4abc9365f8e..1c3c9c666f74 100644 --- a/trunk/drivers/net/pcmcia/3c589_cs.c +++ b/trunk/drivers/net/pcmcia/3c589_cs.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -797,7 +796,7 @@ static void media_check(unsigned long arg) media = inw(ioaddr+WN4_MEDIA) & 0xc810; /* Ignore collisions unless we've had no irq's recently */ - if (time_before(jiffies, lp->last_irq + HZ)) { + if (jiffies - lp->last_irq < HZ) { media &= ~0x0010; } else { /* Try harder to detect carrier errors */ diff --git a/trunk/drivers/net/ppp_async.c b/trunk/drivers/net/ppp_async.c index 23659fd7c3a6..aa6540b39466 100644 --- a/trunk/drivers/net/ppp_async.c +++ b/trunk/drivers/net/ppp_async.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -571,7 +570,7 @@ ppp_async_encode(struct asyncppp *ap) * character if necessary. */ if (islcp || flag_time == 0 - || time_after_eq(jiffies, ap->last_xmit + flag_time)) + || jiffies - ap->last_xmit >= flag_time) *buf++ = PPP_FLAG; ap->last_xmit = jiffies; fcs = PPP_INITFCS; diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index da0d8a85acce..89c46787676c 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -72,8 +72,8 @@ static char s2io_driver_name[] = "Neterion"; static char s2io_driver_version[] = DRV_VERSION; -static int rxd_size[4] = {32,48,48,64}; -static int rxd_count[4] = {127,85,85,63}; +int rxd_size[4] = {32,48,48,64}; +int rxd_count[4] = {127,85,85,63}; static inline int RXD_IS_UP2DT(RxD_t *rxdp) { @@ -2127,7 +2127,7 @@ static void stop_nic(struct s2io_nic *nic) } } -static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) +int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) { struct net_device *dev = nic->dev; struct sk_buff *frag_list; @@ -2852,7 +2852,7 @@ static int wait_for_cmd_complete(nic_t * sp) * void. */ -static void s2io_reset(nic_t * sp) +void s2io_reset(nic_t * sp) { XENA_dev_config_t __iomem *bar0 = sp->bar0; u64 val64; @@ -2940,7 +2940,7 @@ static void s2io_reset(nic_t * sp) * SUCCESS on success and FAILURE on failure. */ -static int s2io_set_swapper(nic_t * sp) +int s2io_set_swapper(nic_t * sp) { struct net_device *dev = sp->dev; XENA_dev_config_t __iomem *bar0 = sp->bar0; @@ -3089,7 +3089,7 @@ static int wait_for_msix_trans(nic_t *nic, int i) return ret; } -static void restore_xmsi_data(nic_t *nic) +void restore_xmsi_data(nic_t *nic) { XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 val64; @@ -3180,7 +3180,7 @@ int s2io_enable_msi(nic_t *nic) return 0; } -static int s2io_enable_msi_x(nic_t *nic) +int s2io_enable_msi_x(nic_t *nic) { XENA_dev_config_t __iomem *bar0 = nic->bar0; u64 tx_mat, rx_mat; @@ -3586,7 +3586,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = (u64) pci_map_page (sp->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); + txdp->Control_1 |= TXD_BUFFER0_SIZE(frag->size); if (skb_shinfo(skb)->ufo_size) txdp->Control_1 |= TXD_UFO_EN; } @@ -4128,7 +4128,7 @@ static void s2io_set_multicast(struct net_device *dev) * as defined in errno.h file on failure. */ -static int s2io_set_mac_addr(struct net_device *dev, u8 * addr) +int s2io_set_mac_addr(struct net_device *dev, u8 * addr) { nic_t *sp = dev->priv; XENA_dev_config_t __iomem *bar0 = sp->bar0; @@ -5713,7 +5713,7 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) * void. */ -static void s2io_link(nic_t * sp, int link) +void s2io_link(nic_t * sp, int link) { struct net_device *dev = (struct net_device *) sp->dev; @@ -5738,7 +5738,7 @@ static void s2io_link(nic_t * sp, int link) * returns the revision ID of the device. */ -static int get_xena_rev_id(struct pci_dev *pdev) +int get_xena_rev_id(struct pci_dev *pdev) { u8 id = 0; int ret; @@ -6343,7 +6343,7 @@ int __init s2io_starter(void) * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. */ -static void s2io_closer(void) +void s2io_closer(void) { pci_unregister_driver(&s2io_driver); DBG_PRINT(INIT_DBG, "cleanup done\n"); diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 68ae33651947..852a6a899d07 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -64,7 +64,7 @@ typedef enum xena_max_outstanding_splits { #define INTR_DBG 4 /* Global variable that defines the present debug level of the driver. */ -static int debug_level = ERR_DBG; +int debug_level = ERR_DBG; /* Default level. */ /* DEBUG message print. */ #define DBG_PRINT(dbg_level, args...) if(!(debug_level #include #include -#include #include #include @@ -700,7 +699,7 @@ static void hardware_send_packet(struct net_device * dev, char *buf, int length) int ioaddr = dev->base_addr; int status = inw(SEEQ_STATUS); int transmit_ptr = 0; - unsigned long tmp; + int tmp; if (net_debug>4) { printk("%s: send 0x%04x\n",dev->name,length); @@ -725,7 +724,7 @@ static void hardware_send_packet(struct net_device * dev, char *buf, int length) /* drain FIFO */ tmp = jiffies; - while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ)) + while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && (jiffies - tmp < HZ)) mb(); /* doit ! */ diff --git a/trunk/drivers/net/shaper.c b/trunk/drivers/net/shaper.c index 88e212043a43..221354eea21f 100644 --- a/trunk/drivers/net/shaper.c +++ b/trunk/drivers/net/shaper.c @@ -83,7 +83,6 @@ #include #include #include -#include #include #include @@ -169,7 +168,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) /* * Queue over time. Spill packet. */ - if(time_after(SHAPERCB(skb)->shapeclock,jiffies + SHAPER_LATENCY)) { + if(SHAPERCB(skb)->shapeclock-jiffies > SHAPER_LATENCY) { dev_kfree_skb(skb); shaper->stats.tx_dropped++; } else diff --git a/trunk/drivers/net/sk98lin/h/skaddr.h b/trunk/drivers/net/sk98lin/h/skaddr.h index 423ad063d09b..3a2ea4a4b539 100644 --- a/trunk/drivers/net/sk98lin/h/skaddr.h +++ b/trunk/drivers/net/sk98lin/h/skaddr.h @@ -236,6 +236,18 @@ extern int SkAddrMcClear( SK_U32 PortNumber, int Flags); +extern int SkAddrXmacMcClear( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int Flags); + +extern int SkAddrGmacMcClear( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int Flags); + extern int SkAddrMcAdd( SK_AC *pAC, SK_IOC IoC, @@ -243,11 +255,35 @@ extern int SkAddrMcAdd( SK_MAC_ADDR *pMc, int Flags); +extern int SkAddrXmacMcAdd( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + SK_MAC_ADDR *pMc, + int Flags); + +extern int SkAddrGmacMcAdd( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + SK_MAC_ADDR *pMc, + int Flags); + extern int SkAddrMcUpdate( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); +extern int SkAddrXmacMcUpdate( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber); + +extern int SkAddrGmacMcUpdate( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber); + extern int SkAddrOverride( SK_AC *pAC, SK_IOC IoC, @@ -261,6 +297,18 @@ extern int SkAddrPromiscuousChange( SK_U32 PortNumber, int NewPromMode); +extern int SkAddrXmacPromiscuousChange( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int NewPromMode); + +extern int SkAddrGmacPromiscuousChange( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 PortNumber, + int NewPromMode); + #ifndef SK_SLIM extern int SkAddrSwap( SK_AC *pAC, diff --git a/trunk/drivers/net/sk98lin/h/skcsum.h b/trunk/drivers/net/sk98lin/h/skcsum.h index 6e256bd9a28c..2b94adb93331 100644 --- a/trunk/drivers/net/sk98lin/h/skcsum.h +++ b/trunk/drivers/net/sk98lin/h/skcsum.h @@ -203,6 +203,12 @@ extern SKCS_STATUS SkCsGetReceiveInfo( unsigned Checksum2, int NetNumber); +extern void SkCsGetSendInfo( + SK_AC *pAc, + void *pIpHeader, + SKCS_PACKET_INFO *pPacketInfo, + int NetNumber); + extern void SkCsSetReceiveFlags( SK_AC *pAc, unsigned ReceiveFlags, diff --git a/trunk/drivers/net/sk98lin/h/skgeinit.h b/trunk/drivers/net/sk98lin/h/skgeinit.h index 143e635ec24d..184f47c5a60f 100644 --- a/trunk/drivers/net/sk98lin/h/skgeinit.h +++ b/trunk/drivers/net/sk98lin/h/skgeinit.h @@ -464,6 +464,12 @@ typedef struct s_GeInit { /* * public functions in skgeinit.c */ +extern void SkGePollRxD( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL PollRxD); + extern void SkGePollTxD( SK_AC *pAC, SK_IOC IoC, @@ -516,6 +522,10 @@ extern void SkGeXmitLED( int Led, int Mode); +extern void SkGeInitRamIface( + SK_AC *pAC, + SK_IOC IoC); + extern int SkGeInitAssignRamToQueues( SK_AC *pAC, int ActivePort, @@ -539,6 +549,11 @@ extern void SkMacHardRst( SK_IOC IoC, int Port); +extern void SkMacClearRst( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkXmInitMac( SK_AC *pAC, SK_IOC IoC, @@ -565,6 +580,11 @@ extern void SkMacFlushTxFifo( SK_IOC IoC, int Port); +extern void SkMacFlushRxFifo( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkMacIrq( SK_AC *pAC, SK_IOC IoC, @@ -581,6 +601,12 @@ extern void SkMacAutoNegLipaPhy( int Port, SK_U16 IStatus); +extern void SkMacSetRxTxEn( + SK_AC *pAC, + SK_IOC IoC, + int Port, + int Para); + extern int SkMacRxTxEnable( SK_AC *pAC, SK_IOC IoC, @@ -633,6 +659,16 @@ extern void SkXmClrExactAddr( int StartNum, int StopNum); +extern void SkXmInitDupMd( + SK_AC *pAC, + SK_IOC IoC, + int Port); + +extern void SkXmInitPauseMd( + SK_AC *pAC, + SK_IOC IoC, + int Port); + extern void SkXmAutoNegLipaXmac( SK_AC *pAC, SK_IOC IoC, @@ -693,6 +729,17 @@ extern int SkGmCableDiagStatus( int Port, SK_BOOL StartTest); +extern int SkGmEnterLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_U8 Mode); + +extern int SkGmLeaveLowPowerMode( + SK_AC *pAC, + SK_IOC IoC, + int Port); + #ifdef SK_DIAG extern void SkGePhyRead( SK_AC *pAC, @@ -735,6 +782,7 @@ extern void SkXmSendCont( /* * public functions in skgeinit.c */ +extern void SkGePollRxD(); extern void SkGePollTxD(); extern void SkGeYellowLED(); extern int SkGeCfgSync(); @@ -744,6 +792,7 @@ extern int SkGeInit(); extern void SkGeDeInit(); extern int SkGeInitPort(); extern void SkGeXmitLED(); +extern void SkGeInitRamIface(); extern int SkGeInitAssignRamToQueues(); /* @@ -752,15 +801,18 @@ extern int SkGeInitAssignRamToQueues(); extern void SkMacRxTxDisable(); extern void SkMacSoftRst(); extern void SkMacHardRst(); +extern void SkMacClearRst(); extern void SkMacInitPhy(); extern int SkMacRxTxEnable(); extern void SkMacPromiscMode(); extern void SkMacHashing(); extern void SkMacIrqDisable(); extern void SkMacFlushTxFifo(); +extern void SkMacFlushRxFifo(); extern void SkMacIrq(); extern int SkMacAutoNegDone(); extern void SkMacAutoNegLipaPhy(); +extern void SkMacSetRxTxEn(); extern void SkXmInitMac(); extern void SkXmPhyRead(); extern void SkXmPhyWrite(); @@ -768,6 +820,8 @@ extern void SkGmInitMac(); extern void SkGmPhyRead(); extern void SkGmPhyWrite(); extern void SkXmClrExactAddr(); +extern void SkXmInitDupMd(); +extern void SkXmInitPauseMd(); extern void SkXmAutoNegLipaXmac(); extern int SkXmUpdateStats(); extern int SkGmUpdateStats(); @@ -778,6 +832,8 @@ extern int SkGmResetCounter(); extern int SkXmOverflowStatus(); extern int SkGmOverflowStatus(); extern int SkGmCableDiagStatus(); +extern int SkGmEnterLowPowerMode(); +extern int SkGmLeaveLowPowerMode(); #ifdef SK_DIAG extern void SkGePhyRead(); diff --git a/trunk/drivers/net/sk98lin/h/skgepnmi.h b/trunk/drivers/net/sk98lin/h/skgepnmi.h index 1ed214ccb253..3b2773e6f822 100644 --- a/trunk/drivers/net/sk98lin/h/skgepnmi.h +++ b/trunk/drivers/net/sk98lin/h/skgepnmi.h @@ -946,6 +946,10 @@ typedef struct s_PnmiData { * Function prototypes */ extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, + unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex); +extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, + void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, diff --git a/trunk/drivers/net/sk98lin/h/skgesirq.h b/trunk/drivers/net/sk98lin/h/skgesirq.h index 3eec6274e413..b486bd9b6628 100644 --- a/trunk/drivers/net/sk98lin/h/skgesirq.h +++ b/trunk/drivers/net/sk98lin/h/skgesirq.h @@ -105,6 +105,7 @@ extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); +extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port); extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port); #endif /* _INC_SKGESIRQ_H_ */ diff --git a/trunk/drivers/net/sk98lin/h/ski2c.h b/trunk/drivers/net/sk98lin/h/ski2c.h index 6a63f4a15de6..598bb42ccc3d 100644 --- a/trunk/drivers/net/sk98lin/h/ski2c.h +++ b/trunk/drivers/net/sk98lin/h/ski2c.h @@ -162,6 +162,9 @@ typedef struct s_I2c { } SK_I2C; extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, + int Reg, int Burst); +extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); #ifdef SK_DIAG extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, int Burst); diff --git a/trunk/drivers/net/sk98lin/h/skvpd.h b/trunk/drivers/net/sk98lin/h/skvpd.h index fdd9e48e8040..daa9a8d154fc 100644 --- a/trunk/drivers/net/sk98lin/h/skvpd.h +++ b/trunk/drivers/net/sk98lin/h/skvpd.h @@ -183,6 +183,14 @@ extern SK_U32 VpdReadDWord( int addr); #endif /* SKDIAG */ +extern int VpdSetupPara( + SK_AC *pAC, + const char *key, + const char *buf, + int len, + int type, + int op); + extern SK_VPD_STATUS *VpdStat( SK_AC *pAC, SK_IOC IoC); @@ -219,6 +227,11 @@ extern int VpdUpdate( SK_AC *pAC, SK_IOC IoC); +extern void VpdErrLog( + SK_AC *pAC, + SK_IOC IoC, + char *msg); + #ifdef SKDIAG extern int VpdReadBlock( SK_AC *pAC, @@ -236,6 +249,7 @@ extern int VpdWriteBlock( #endif /* SKDIAG */ #else /* SK_KR_PROTO */ extern SK_U32 VpdReadDWord(); +extern int VpdSetupPara(); extern SK_VPD_STATUS *VpdStat(); extern int VpdKeys(); extern int VpdRead(); @@ -243,6 +257,7 @@ extern SK_BOOL VpdMayWrite(); extern int VpdWrite(); extern int VpdDelete(); extern int VpdUpdate(); +extern void VpdErrLog(); #endif /* SK_KR_PROTO */ #endif /* __INC_SKVPD_H_ */ diff --git a/trunk/drivers/net/sk98lin/skaddr.c b/trunk/drivers/net/sk98lin/skaddr.c index 6e6c56aa6d6f..a7e25edc7fc4 100644 --- a/trunk/drivers/net/sk98lin/skaddr.c +++ b/trunk/drivers/net/sk98lin/skaddr.c @@ -87,21 +87,6 @@ static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; static int Next0[SK_MAX_MACS] = {0}; #endif /* DEBUG */ -static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - SK_MAC_ADDR *pMc, int Flags); -static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int Flags); -static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); -static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, - SK_U32 PortNumber, int NewPromMode); -static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - SK_MAC_ADDR *pMc, int Flags); -static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, - int Flags); -static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); -static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, - SK_U32 PortNumber, int NewPromMode); - /* functions ******************************************************************/ /****************************************************************************** @@ -387,7 +372,7 @@ int Flags) /* permanent/non-perm, sw-only */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrXmacMcClear( +int SkAddrXmacMcClear( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Index of affected port */ @@ -444,7 +429,7 @@ int Flags) /* permanent/non-perm, sw-only */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrGmacMcClear( +int SkAddrGmacMcClear( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Index of affected port */ @@ -534,7 +519,7 @@ int Flags) /* permanent/non-perm, sw-only */ * Returns: * Hash value of multicast address. */ -static SK_U32 SkXmacMcHash( +SK_U32 SkXmacMcHash( unsigned char *pMc) /* Multicast address */ { SK_U32 Idx; @@ -572,7 +557,7 @@ unsigned char *pMc) /* Multicast address */ * Returns: * Hash value of multicast address. */ -static SK_U32 SkGmacMcHash( +SK_U32 SkGmacMcHash( unsigned char *pMc) /* Multicast address */ { SK_U32 Data; @@ -687,7 +672,7 @@ int Flags) /* permanent/non-permanent */ * SK_MC_ILLEGAL_ADDRESS * SK_MC_RLMT_OVERFLOW */ -static int SkAddrXmacMcAdd( +int SkAddrXmacMcAdd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Port Number */ @@ -793,7 +778,7 @@ int Flags) /* permanent/non-permanent */ * SK_MC_FILTERING_INEXACT * SK_MC_ILLEGAL_ADDRESS */ -static int SkAddrGmacMcAdd( +int SkAddrGmacMcAdd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Port Number */ @@ -952,7 +937,7 @@ SK_U32 PortNumber) /* Port Number */ * SK_MC_FILTERING_INEXACT * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrXmacMcUpdate( +int SkAddrXmacMcUpdate( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ @@ -1097,7 +1082,7 @@ SK_U32 PortNumber) /* Port Number */ * SK_MC_FILTERING_INEXACT * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrGmacMcUpdate( +int SkAddrGmacMcUpdate( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ @@ -1483,7 +1468,7 @@ int NewPromMode) /* new promiscuous mode */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrXmacPromiscuousChange( +int SkAddrXmacPromiscuousChange( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* port whose promiscuous mode changes */ @@ -1600,7 +1585,7 @@ int NewPromMode) /* new promiscuous mode */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -static int SkAddrGmacPromiscuousChange( +int SkAddrGmacPromiscuousChange( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* port whose promiscuous mode changes */ diff --git a/trunk/drivers/net/sk98lin/skgeinit.c b/trunk/drivers/net/sk98lin/skgeinit.c index 67f1d6a5c15d..6cb49dd02251 100644 --- a/trunk/drivers/net/sk98lin/skgeinit.c +++ b/trunk/drivers/net/sk98lin/skgeinit.c @@ -57,6 +57,34 @@ static struct s_Config OemConfig = { #endif }; +/****************************************************************************** + * + * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring + * + * Description: + * Enable or disable the descriptor polling of the receive descriptor + * ring (RxD) for port 'Port'. + * The new configuration is *not* saved over any SkGeStopPort() and + * SkGeInitPort() calls. + * + * Returns: + * nothing + */ +void SkGePollRxD( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ +{ + SK_GEPORT *pPrt; + + pPrt = &pAC->GIni.GP[Port]; + + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ? + CSR_ENA_POL : CSR_DIS_POL); +} /* SkGePollRxD */ + + /****************************************************************************** * * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings @@ -924,7 +952,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkGeInitRamIface( +void SkGeInitRamIface( SK_AC *pAC, /* adapter context */ SK_IOC IoC) /* IO context */ { @@ -1381,6 +1409,83 @@ SK_IOC IoC) /* IO context */ } /* SkGeInit0*/ +#ifdef SK_PCI_RESET + +/****************************************************************************** + * + * SkGePciReset() - Reset PCI interface + * + * Description: + * o Read PCI configuration. + * o Change power state to 3. + * o Change power state to 0. + * o Restore PCI configuration. + * + * Returns: + * 0: Success. + * 1: Power state could not be changed to 3. + */ +static int SkGePciReset( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC) /* IO context */ +{ + int i; + SK_U16 PmCtlSts; + SK_U32 Bp1; + SK_U32 Bp2; + SK_U16 PciCmd; + SK_U8 Cls; + SK_U8 Lat; + SK_U8 ConfigSpace[PCI_CFG_SIZE]; + + /* + * Note: Switching to D3 state is like a software reset. + * Switching from D3 to D0 is a hardware reset. + * We have to save and restore the configuration space. + */ + for (i = 0; i < PCI_CFG_SIZE; i++) { + SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]); + } + + /* We know the RAM Interface Arbiter is enabled. */ + SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3); + SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); + + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) { + return(1); + } + + /* Return to D0 state. */ + SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0); + + /* Check for D0 state. */ + SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); + + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { + return(1); + } + + /* Check PCI Config Registers. */ + SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd); + SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls); + SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1); + SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2); + SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); + + if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 || + (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) { + return(1); + } + + /* Restore PCI Config Space. */ + for (i = 0; i < PCI_CFG_SIZE; i++) { + SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]); + } + + return(0); +} /* SkGePciReset */ + +#endif /* SK_PCI_RESET */ /****************************************************************************** * @@ -1419,6 +1524,10 @@ SK_IOC IoC) /* IO context */ /* save CLK_RUN bits (YUKON-Lite) */ SK_IN16(IoC, B0_CTST, &CtrlStat); +#ifdef SK_PCI_RESET + (void)SkGePciReset(pAC, IoC); +#endif /* SK_PCI_RESET */ + /* do the SW-reset */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); @@ -1882,6 +1991,11 @@ SK_IOC IoC) /* IO context */ int i; SK_U16 Word; +#ifdef SK_PHY_LP_MODE + SK_U8 Byte; + SK_U16 PmCtlSts; +#endif /* SK_PHY_LP_MODE */ + #if (!defined(SK_SLIM) && !defined(VCPU)) /* ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC); @@ -1896,6 +2010,38 @@ SK_IOC IoC) /* IO context */ } } +#ifdef SK_PHY_LP_MODE + /* + * for power saving purposes within mobile environments + * we set the PHY to coma mode and switch to D3 power state. + */ + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + + /* for all ports switch PHY to coma mode */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); + } + + if (pAC->GIni.GIVauxAvail) { + /* switch power to VAUX */ + Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF; + + SK_OUT8(IoC, B0_POWER_CTRL, Byte); + } + + /* switch to D3 state */ + SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts); + + PmCtlSts |= PCI_PM_STATE_D3; + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts); + } +#endif /* SK_PHY_LP_MODE */ + /* Reset all bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not diff --git a/trunk/drivers/net/sk98lin/skgemib.c b/trunk/drivers/net/sk98lin/skgemib.c index 0a6f67a7a395..2991bc85cf2c 100644 --- a/trunk/drivers/net/sk98lin/skgemib.c +++ b/trunk/drivers/net/sk98lin/skgemib.c @@ -871,6 +871,13 @@ PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = { sizeof(SK_PNMI_CONF), SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), SK_PNMI_RO, MacPrivateConf, 0}, +#ifdef SK_PHY_LP_MODE + {OID_SKGE_PHY_LP_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), + SK_PNMI_RW, MacPrivateConf, 0}, +#endif {OID_SKGE_LINK_CAP, SK_PNMI_MAC_ENTRIES, sizeof(SK_PNMI_CONF), diff --git a/trunk/drivers/net/sk98lin/skgepnmi.c b/trunk/drivers/net/sk98lin/skgepnmi.c index b36dd9ac6b29..a386172107e8 100644 --- a/trunk/drivers/net/sk98lin/skgepnmi.c +++ b/trunk/drivers/net/sk98lin/skgepnmi.c @@ -56,6 +56,10 @@ static const char SysKonnectFileId[] = * Public Function prototypes */ int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); +int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, @@ -583,7 +587,7 @@ int Level) /* Initialization level */ * exist (e.g. port instance 3 on a two port * adapter. */ -static int SkPnmiGetVar( +int SkPnmiGetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ @@ -625,7 +629,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ * exist (e.g. port instance 3 on a two port * adapter. */ -static int SkPnmiPreSetVar( +int SkPnmiPreSetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ @@ -5058,6 +5062,9 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ case OID_SKGE_SPEED_CAP: case OID_SKGE_SPEED_MODE: case OID_SKGE_SPEED_STATUS: +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: +#endif if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); @@ -5133,6 +5140,28 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ Offset += sizeof(SK_U32); break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + continue; + } + else { + /* Get value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + } + else { /* DualNetMode */ + + Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + *pBufPtr = Val8; + } + Offset += sizeof(SK_U8); + break; +#endif + case OID_SKGE_LINK_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { @@ -5449,6 +5478,16 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ } break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (*pLen < Limit - LogPortIndex) { + + *pLen = Limit - LogPortIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +#endif + case OID_SKGE_MTU: if (*pLen < sizeof(SK_U32)) { @@ -5806,6 +5845,116 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ Offset += sizeof(SK_U32); break; +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + /* The preset ends here */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ + if (LogPortIndex == 0) { + Offset = 0; + continue; + } + else { + /* Set value for physical ports */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + switch (*(pBuf + Offset)) { + case 0: + /* If LowPowerMode is active, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + case 1: + case 2: + case 3: + case 4: + /* If no LowPowerMode is active, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + } + else { /* DualNetMode */ + + switch (*(pBuf + Offset)) { + case 0: + /* If we are in a LowPowerMode, we can leave it. */ + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + case 1: + case 2: + case 3: + case 4: + /* If we are not already in LowPowerMode, we can enter it. */ + if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { + + if ((*(pBuf + Offset)) < 3) { + + SkDrvDeInitAdapter(pAC); + } + else { + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + Offset += sizeof(SK_U8); + break; +#endif + default: SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, ("MacPrivateConf: Unknown OID should be handled before set")); diff --git a/trunk/drivers/net/sk98lin/skgesirq.c b/trunk/drivers/net/sk98lin/skgesirq.c index ab66d80a4455..87520f0057d7 100644 --- a/trunk/drivers/net/sk98lin/skgesirq.c +++ b/trunk/drivers/net/sk98lin/skgesirq.c @@ -265,7 +265,7 @@ int Port) /* Port Index (MAC_1 + n) */ * * Returns: N/A */ -static void SkHWLinkUp( +void SkHWLinkUp( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -612,6 +612,14 @@ SK_U32 Istatus) /* Interrupt status word */ * we ignore those */ pPrt->HalfDupTimerActive = SK_TRUE; +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0), + pAC->Rlmt.Port[0].Net->NetNumber); + + pPrt->LastOctets = Octets; +#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 0); @@ -645,6 +653,14 @@ SK_U32 Istatus) /* Interrupt status word */ pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && !pPrt->HalfDupTimerActive) { pPrt->HalfDupTimerActive = SK_TRUE; +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1), + pAC->Rlmt.Port[1].Net->NetNumber); + + pPrt->LastOctets = Octets; +#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 1); @@ -2069,6 +2085,12 @@ SK_EVPARA Para) /* Event specific Parameter */ pPrt->HalfDupTimerActive = SK_FALSE; if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { +#ifdef XXX + Len = sizeof(SK_U64); + SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, + &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), + pAC->Rlmt.Port[Port].Net->NetNumber); +#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, Port); diff --git a/trunk/drivers/net/sk98lin/ski2c.c b/trunk/drivers/net/sk98lin/ski2c.c index 79bf57cb5326..075a0464e56b 100644 --- a/trunk/drivers/net/sk98lin/ski2c.c +++ b/trunk/drivers/net/sk98lin/ski2c.c @@ -396,7 +396,7 @@ int Rw) /* Read / Write Flag */ * 1: error, transfer does not complete, I2C transfer * killed, wait loop terminated. */ -static int SkI2cWait( +int SkI2cWait( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ @@ -481,7 +481,7 @@ SK_IOC IoC) /* I/O Context */ * returns 0: success * 1: error */ -static int SkI2cWrite( +int SkI2cWrite( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 I2cData, /* I2C Data to write */ @@ -538,7 +538,7 @@ int I2cBurst) /* I2C Burst Flag */ * 1 if the read is completed * 0 if the read must be continued (I2C Bus still allocated) */ -static int SkI2cReadSensor( +int SkI2cReadSensor( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_SENSOR *pSen) /* Sensor to be read */ diff --git a/trunk/drivers/net/sk98lin/sklm80.c b/trunk/drivers/net/sk98lin/sklm80.c index a204f5bb55d4..68292d18175b 100644 --- a/trunk/drivers/net/sk98lin/sklm80.c +++ b/trunk/drivers/net/sk98lin/sklm80.c @@ -34,7 +34,79 @@ static const char SysKonnectFileId[] = #include "h/lm80.h" #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ +#ifdef SK_DIAG +#define BREAK_OR_WAIT(pAC,IoC,Event) SkI2cWait(pAC,IoC,Event) +#else /* nSK_DIAG */ #define BREAK_OR_WAIT(pAC,IoC,Event) break +#endif /* nSK_DIAG */ + +#ifdef SK_DIAG +/* + * read the register 'Reg' from the device 'Dev' + * + * return read error -1 + * success the read value + */ +int SkLm80RcvReg( +SK_IOC IoC, /* Adapter Context */ +int Dev, /* I2C device address */ +int Reg) /* register to read */ +{ + int Val = 0; + int TempExt; + + /* Signal device number */ + if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) { + return(-1); + } + + if (SkI2cSndByte(IoC, Reg)) { + return(-1); + } + + /* repeat start */ + if (SkI2cSndDev(IoC, Dev, I2C_READ)) { + return(-1); + } + + switch (Reg) { + case LM80_TEMP_IN: + Val = (int)SkI2cRcvByte(IoC, 1); + + /* First: correct the value: it might be negative */ + if ((Val & 0x80) != 0) { + /* Value is negative */ + Val = Val - 256; + } + Val = Val * SK_LM80_TEMP_LSB; + SkI2cStop(IoC); + + TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL); + + if (Val > 0) { + Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); + } + else { + Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); + } + return(Val); + break; + case LM80_VT0_IN: + case LM80_VT1_IN: + case LM80_VT2_IN: + case LM80_VT3_IN: + Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB; + break; + + default: + Val = (int)SkI2cRcvByte(IoC, 1); + break; + } + + SkI2cStop(IoC); + return(Val); +} +#endif /* SK_DIAG */ /* * read a sensors value (LM80 specific) diff --git a/trunk/drivers/net/sk98lin/skrlmt.c b/trunk/drivers/net/sk98lin/skrlmt.c index be8d1ccddf6d..9ea11ab2296a 100644 --- a/trunk/drivers/net/sk98lin/skrlmt.c +++ b/trunk/drivers/net/sk98lin/skrlmt.c @@ -282,6 +282,7 @@ typedef struct s_SpTreeRlmtPacket { SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}}; SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}; +SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; /* local variables ************************************************************/ diff --git a/trunk/drivers/net/sk98lin/skvpd.c b/trunk/drivers/net/sk98lin/skvpd.c index 17786056c66a..eb3c8988ced1 100644 --- a/trunk/drivers/net/sk98lin/skvpd.c +++ b/trunk/drivers/net/sk98lin/skvpd.c @@ -132,6 +132,65 @@ int addr) /* VPD address */ #endif /* SKDIAG */ +#if 0 + +/* + Write the dword 'data' at address 'addr' into the VPD EEPROM, and + verify that the data is written. + + Needed Time: + +. MIN MAX +. ------------------------------------------------------------------- +. write 1.8 ms 3.6 ms +. internal write cyles 0.7 ms 7.0 ms +. ------------------------------------------------------------------- +. over all program time 2.5 ms 10.6 ms +. read 1.3 ms 2.6 ms +. ------------------------------------------------------------------- +. over all 3.8 ms 13.2 ms +. + + + Returns 0: success + 1: error, I2C transfer does not terminate + 2: error, data verify error + + */ +static int VpdWriteDWord( +SK_AC *pAC, /* pAC pointer */ +SK_IOC IoC, /* IO Context */ +int addr, /* VPD address */ +SK_U32 data) /* VPD data to write */ +{ + /* start VPD write */ + /* Don't swap here, it's a data stream of bytes */ + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + ("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data)); + VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data); + /* But do it here */ + addr |= VPD_WRITE; + + VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)); + + /* this may take up to 10,6 ms */ + if (VpdWait(pAC, IoC, VPD_WRITE)) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("Write Timed Out\n")); + return(1); + }; + + /* verify data */ + if (VpdReadDWord(pAC, IoC, addr) != data) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + ("Data Verify Error\n")); + return(2); + } + return(0); +} /* VpdWriteDWord */ + +#endif /* 0 */ + /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from * or to the I2C EEPROM. @@ -669,7 +728,7 @@ char *etp) /* end pointer input position */ * 6: fatal VPD error * */ -static int VpdSetupPara( +int VpdSetupPara( SK_AC *pAC, /* common data base */ const char *key, /* keyword to insert */ const char *buf, /* buffer with the keyword value */ @@ -1089,3 +1148,50 @@ SK_IOC IoC) /* IO Context */ return(0); } + + +/* + * Read the contents of the VPD EEPROM and copy it to the VPD buffer + * if not already done. If the keyword "VF" is not present it will be + * created and the error log message will be stored to this keyword. + * If "VF" is not present the error log message will be stored to the + * keyword "VL". "VL" will created or overwritten if "VF" is present. + * The VPD read/write area is saved to the VPD EEPROM. + * + * returns nothing, errors will be ignored. + */ +void VpdErrLog( +SK_AC *pAC, /* common data base */ +SK_IOC IoC, /* IO Context */ +char *msg) /* error log message */ +{ + SK_VPD_PARA *v, vf; /* VF */ + int len; + + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, + ("VPD error log msg %s\n", msg)); + if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { + if (VpdInit(pAC, IoC) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, + ("VPD init error\n")); + return; + } + } + + len = strlen(msg); + if (len > VPD_MAX_LEN) { + /* cut it */ + len = VPD_MAX_LEN; + } + if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n")); + (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY); + } + else { + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n")); + (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY); + } + + (void)VpdUpdate(pAC, IoC); +} + diff --git a/trunk/drivers/net/sk98lin/skxmac2.c b/trunk/drivers/net/sk98lin/skxmac2.c index b4e75022a657..42d2d963150a 100644 --- a/trunk/drivers/net/sk98lin/skxmac2.c +++ b/trunk/drivers/net/sk98lin/skxmac2.c @@ -41,13 +41,13 @@ static const char SysKonnectFileId[] = #endif #ifdef GENESIS -static BCOM_HACK BcomRegA1Hack[] = { +BCOM_HACK BcomRegA1Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 }, { 0, 0 } }; -static BCOM_HACK BcomRegC0Hack[] = { +BCOM_HACK BcomRegC0Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, { 0, 0 } @@ -790,7 +790,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkMacFlushRxFifo( +void SkMacFlushRxFifo( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1231,6 +1231,38 @@ int Port) /* Port Index (MAC_1 + n) */ } /* SkMacHardRst */ +/****************************************************************************** + * + * SkMacClearRst() - Clear the MAC reset + * + * Description: calls a clear MAC reset routine dep. on board type + * + * Returns: + * nothing + */ +void SkMacClearRst( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + SkXmClearRst(pAC, IoC, Port); + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmClearRst(pAC, IoC, Port); + } +#endif /* YUKON */ + +} /* SkMacClearRst */ + + #ifdef GENESIS /****************************************************************************** * @@ -1681,7 +1713,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkXmInitDupMd( +void SkXmInitDupMd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1729,7 +1761,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkXmInitPauseMd( +void SkXmInitPauseMd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -2044,7 +2076,283 @@ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ } /* SkXmInitPhyBcom */ #endif /* GENESIS */ + #ifdef YUKON +#ifndef SK_SLIM +/****************************************************************************** + * + * SkGmEnterLowPowerMode() + * + * Description: + * This function sets the Marvell Alaska PHY to the low power mode + * given by parameter mode. + * The following low power modes are available: + * + * - Coma Mode (Deep Sleep): + * Power consumption: ~15 - 30 mW + * The PHY cannot wake up on its own. + * + * - IEEE 22.2.4.1.5 compatible power down mode + * Power consumption: ~240 mW + * The PHY cannot wake up on its own. + * + * - energy detect mode + * Power consumption: ~160 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * + * - energy detect plus mode + * Power consumption: ~150 mW + * The PHY can wake up on its own by detecting activity + * on the CAT 5 cable. + * Connected devices can be woken up by sending normal link + * pulses every one second. + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmEnterLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (e.g. MAC_1) */ +SK_U8 Mode) /* low power mode */ +{ + SK_U16 Word; + SK_U32 DWord; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = Mode; + + switch (Mode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + /* setup General Purpose Control Register */ + GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS | + GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); + + /* apply COMA mode workaround */ + SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f); + SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3); + + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Set PHY to Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - disable MAC 125 MHz clock + * - allow MAC power down + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + Word &= ~PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode on */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - disable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word |= PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* activate energy detect mode 1 */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + + /* energy detect mode */ + if (Mode == PHY_PM_ENERGY_DETECT) { + Word |= PHY_M_PC_EN_DET; + } + /* energy detect plus mode */ + else { + Word |= PHY_M_PC_EN_DET_PLUS; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmEnterLowPowerMode */ + +/****************************************************************************** + * + * SkGmLeaveLowPowerMode() + * + * Description: + * Leave the current low power mode and switch to normal mode + * + * Note: + * + * Returns: + * 0: ok + * 1: error + */ +int SkGmLeaveLowPowerMode( +SK_AC *pAC, /* adapter context */ +SK_IOC IoC, /* IO context */ +int Port) /* Port Index (e.g. MAC_1) */ +{ + SK_U32 DWord; + SK_U16 Word; + SK_U8 LastMode; + int Ret = 0; + + if (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; + + switch (LastMode) { + /* coma mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + /* Release PHY from Coma Mode */ + SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + SK_IN32(IoC, B2_GP_IO, &DWord); + + /* set to output */ + DWord |= (GP_DIR_9 | GP_IO_9); + + /* set PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + + /* clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + /* + * - enable MAC 125 MHz clock + * - set MAC power up + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + Word |= PHY_M_PC_MAC_POW_UP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * register changes must be followed by a software + * reset to take effect + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + /* switch IEEE compatible power down mode off */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word &= ~PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* + * - enable MAC 125 MHz clock + */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* disable energy detect mode */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_EN_DET_MSK; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* + * reinitialize the PHY to force a software reset + * which is necessary after the register settings + * for the energy detect modes. + * Furthermore reinitialisation prevents that the + * PHY is running out of a stable state. + */ + SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; + Ret = 1; + break; + } + } + /* low power modes are not supported by this chip */ + else { + Ret = 1; + } + + return(Ret); + +} /* SkGmLeaveLowPowerMode */ +#endif /* !SK_SLIM */ + + /****************************************************************************** * * SkGmInitPhyMarv() - Initialize the Marvell Phy registers @@ -3112,6 +3420,145 @@ int Port) /* Port Index (MAC_1 + n) */ } /* SkMacAutoNegDone */ +#ifdef GENESIS +/****************************************************************************** + * + * SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC + * + * Description: + * sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg. + * enables Rx/Tx + * + * Returns: N/A + */ +static void SkXmSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */ +{ + SK_U16 Word; + + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + + switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { + case SK_MAC_LOOPB_ON: + Word |= XM_MMU_MAC_LB; + break; + case SK_MAC_LOOPB_OFF: + Word &= ~XM_MMU_MAC_LB; + break; + } + + switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) { + case SK_PHY_LOOPB_ON: + Word |= XM_MMU_GMII_LOOP; + break; + case SK_PHY_LOOPB_OFF: + Word &= ~XM_MMU_GMII_LOOP; + break; + } + + switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { + case SK_PHY_FULLD_ON: + Word |= XM_MMU_GMII_FD; + break; + case SK_PHY_FULLD_OFF: + Word &= ~XM_MMU_GMII_FD; + break; + } + + XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX); + + /* dummy read to ensure writing */ + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); + +} /* SkXmSetRxTxEn */ +#endif /* GENESIS */ + + +#ifdef YUKON +/****************************************************************************** + * + * SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC + * + * Description: + * sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg. + * enables Rx/Tx + * + * Returns: N/A + */ +static void SkGmSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) /* Parameter to set: MAC LoopBack, Duplex Mode */ +{ + SK_U16 Ctrl; + + GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); + + switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { + case SK_MAC_LOOPB_ON: + Ctrl |= GM_GPCR_LOOP_ENA; + break; + case SK_MAC_LOOPB_OFF: + Ctrl &= ~GM_GPCR_LOOP_ENA; + break; + } + + switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { + case SK_PHY_FULLD_ON: + Ctrl |= GM_GPCR_DUP_FULL; + break; + case SK_PHY_FULLD_OFF: + Ctrl &= ~GM_GPCR_DUP_FULL; + break; + } + + GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA | + GM_GPCR_TX_ENA)); + + /* dummy read to ensure writing */ + GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); + +} /* SkGmSetRxTxEn */ +#endif /* YUKON */ + + +#ifndef SK_SLIM +/****************************************************************************** + * + * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters + * + * Description: calls the Special Set Rx/Tx Enable routines dep. on board type + * + * Returns: N/A + */ +void SkMacSetRxTxEn( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* IO context */ +int Port, /* Port Index (MAC_1 + n) */ +int Para) +{ +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + + SkXmSetRxTxEn(pAC, IoC, Port, Para); + } +#endif /* GENESIS */ + +#ifdef YUKON + if (pAC->GIni.GIYukon) { + + SkGmSetRxTxEn(pAC, IoC, Port, Para); + } +#endif /* YUKON */ + +} /* SkMacSetRxTxEn */ +#endif /* !SK_SLIM */ + + /****************************************************************************** * * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up @@ -3529,7 +3976,7 @@ SK_U16 PhyStat) /* PHY Status word to analyse */ * Returns: * nothing */ -static void SkXmIrq( +void SkXmIrq( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -3665,7 +4112,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -static void SkGmIrq( +void SkGmIrq( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ diff --git a/trunk/drivers/net/starfire.c b/trunk/drivers/net/starfire.c index ed5458c45446..d167deda9a53 100644 --- a/trunk/drivers/net/starfire.c +++ b/trunk/drivers/net/starfire.c @@ -2084,38 +2084,6 @@ static int netdev_close(struct net_device *dev) return 0; } -#ifdef CONFIG_PM -static int starfire_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (netif_running(dev)) { - netif_device_detach(dev); - netdev_close(dev); - } - - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev,state)); - - return 0; -} - -static int starfire_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - if (netif_running(dev)) { - netdev_open(dev); - netif_device_attach(dev); - } - - return 0; -} -#endif /* CONFIG_PM */ - static void __devexit starfire_remove_one (struct pci_dev *pdev) { @@ -2147,10 +2115,6 @@ static struct pci_driver starfire_driver = { .name = DRV_NAME, .probe = starfire_init_one, .remove = __devexit_p(starfire_remove_one), -#ifdef CONFIG_PM - .suspend = starfire_suspend, - .resume = starfire_resume, -#endif /* CONFIG_PM */ .id_table = starfire_pci_tbl, }; diff --git a/trunk/drivers/net/tokenring/lanstreamer.c b/trunk/drivers/net/tokenring/lanstreamer.c index c58a4c31d0dd..97712c3c4e07 100644 --- a/trunk/drivers/net/tokenring/lanstreamer.c +++ b/trunk/drivers/net/tokenring/lanstreamer.c @@ -122,7 +122,6 @@ #include #include #include -#include #include @@ -513,7 +512,7 @@ static int streamer_reset(struct net_device *dev) while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) { msleep_interruptible(100); - if (time_after(jiffies, t + 40 * HZ)) { + if (jiffies - t > 40 * HZ) { printk(KERN_ERR "IBM PCI tokenring card not responding\n"); release_region(dev->base_addr, STREAMER_IO_SPACE); diff --git a/trunk/drivers/net/tokenring/olympic.c b/trunk/drivers/net/tokenring/olympic.c index 23032a7bc0a9..05477d24fd49 100644 --- a/trunk/drivers/net/tokenring/olympic.c +++ b/trunk/drivers/net/tokenring/olympic.c @@ -100,7 +100,6 @@ #include #include #include -#include #include @@ -308,7 +307,7 @@ static int __devinit olympic_init(struct net_device *dev) t=jiffies; while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) { schedule(); - if(time_after(jiffies, t + 40*HZ)) { + if(jiffies-t > 40*HZ) { printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); return -ENODEV; } @@ -360,7 +359,7 @@ static int __devinit olympic_init(struct net_device *dev) t=jiffies; while (!readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE) { schedule() ; - if(time_after(jiffies, t + 2*HZ)) { + if(jiffies-t > 2*HZ) { printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ; return -ENODEV; } @@ -374,7 +373,7 @@ static int __devinit olympic_init(struct net_device *dev) t=jiffies; while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) { schedule(); - if(time_after(jiffies, t + 15*HZ)) { + if(jiffies-t > 15*HZ) { printk(KERN_ERR "IBM PCI tokenring card not responding.\n"); return -ENODEV; } @@ -520,7 +519,7 @@ static int olympic_open(struct net_device *dev) olympic_priv->srb_queued=0; break; } - if (time_after(jiffies, t + 10*HZ)) { + if ((jiffies-t) > 10*HZ) { printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ; olympic_priv->srb_queued=0; break ; diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index d6c3d52d2e86..d7fb3ffe06ac 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -402,7 +402,8 @@ static void de_rx (struct de_private *de) unsigned copying_skb, buflen; skb = de->rx_skb[rx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); rmb(); status = le32_to_cpu(de->rx_ring[rx_tail].opts1); if (status & DescOwn) @@ -544,7 +545,8 @@ static void de_tx (struct de_private *de) break; skb = de->tx_skb[tx_tail].skb; - BUG_ON(!skb); + if (!skb) + BUG(); if (unlikely(skb == DE_DUMMY_SKB)) goto next; @@ -787,7 +789,8 @@ static void __de_set_rx_mode (struct net_device *dev) de->tx_head = NEXT_TX(entry); - BUG_ON(TX_BUFFS_AVAIL(de) < 0); + if (TX_BUFFS_AVAIL(de) < 0) + BUG(); if (TX_BUFFS_AVAIL(de) == 0) netif_stop_queue(dev); @@ -913,7 +916,8 @@ static void de_set_media (struct de_private *de) unsigned media = de->media_type; u32 macmode = dr32(MacMode); - BUG_ON(de_is_running(de)); + if (de_is_running(de)) + BUG(); if (de->de21040) dw32(CSR11, FULL_DUPLEX_MAGIC); @@ -1149,7 +1153,8 @@ static void de_media_interrupt (struct de_private *de, u32 status) return; } - BUG_ON(!(status & LinkFail)); + if (!(status & LinkFail)) + BUG(); if (netif_carrier_ok(de->dev)) { de_link_down(de); @@ -2087,7 +2092,8 @@ static void __exit de_remove_one (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct de_private *de = dev->priv; - BUG_ON(!dev); + if (!dev) + BUG(); unregister_netdev(dev); kfree(de->ee_data); iounmap(de->regs); diff --git a/trunk/drivers/net/tulip/pnic.c b/trunk/drivers/net/tulip/pnic.c index ca7e53246adb..d9980bde7508 100644 --- a/trunk/drivers/net/tulip/pnic.c +++ b/trunk/drivers/net/tulip/pnic.c @@ -16,7 +16,6 @@ #include #include -#include #include "tulip.h" @@ -69,7 +68,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5) */ if (tulip_media_cap[dev->if_port] & MediaIsMII) return; - if (! tp->nwayset || time_after(jiffies, dev->trans_start + 1*HZ)) { + if (! tp->nwayset || jiffies - dev->trans_start > 1*HZ) { tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff); iowrite32(tp->csr6, ioaddr + CSR6); iowrite32(0x30, ioaddr + CSR12); diff --git a/trunk/drivers/net/tulip/winbond-840.c b/trunk/drivers/net/tulip/winbond-840.c index ba05dedf29d3..5b1af3986abf 100644 --- a/trunk/drivers/net/tulip/winbond-840.c +++ b/trunk/drivers/net/tulip/winbond-840.c @@ -1645,7 +1645,7 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state) /* no more hardware accesses behind this line. */ - BUG_ON(np->csr6); + if (np->csr6) BUG(); if (ioread32(ioaddr + IntrEnable)) BUG(); /* pci_power_off(pdev, -1); */ diff --git a/trunk/drivers/net/tulip/xircom_cb.c b/trunk/drivers/net/tulip/xircom_cb.c index c5c738a51ee3..60d1e05ab732 100644 --- a/trunk/drivers/net/tulip/xircom_cb.c +++ b/trunk/drivers/net/tulip/xircom_cb.c @@ -598,8 +598,10 @@ static void setup_descriptors(struct xircom_private *card) enter("setup_descriptors"); - BUG_ON(card->rx_buffer == NULL); - BUG_ON(card->tx_buffer == NULL); + if (card->rx_buffer == NULL) + BUG(); + if (card->tx_buffer == NULL) + BUG(); /* Receive descriptors */ memset(card->rx_buffer, 0, 128); /* clear the descriptors */ diff --git a/trunk/drivers/net/wireless/strip.c b/trunk/drivers/net/wireless/strip.c index 18a44580b53b..18baacfc5a2c 100644 --- a/trunk/drivers/net/wireless/strip.c +++ b/trunk/drivers/net/wireless/strip.c @@ -112,7 +112,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; #include #include #include -#include + /************************************************************************/ /* Useful structures and definitions */ @@ -1569,7 +1569,7 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev) del_timer(&strip_info->idle_timer); - if (time_after(jiffies, strip_info->pps_timer + HZ)) { + if (jiffies - strip_info->pps_timer > HZ) { unsigned long t = jiffies - strip_info->pps_timer; unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t; unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t; diff --git a/trunk/drivers/net/zorro8390.c b/trunk/drivers/net/zorro8390.c index 761021603597..8ab6e12153ba 100644 --- a/trunk/drivers/net/zorro8390.c +++ b/trunk/drivers/net/zorro8390.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -152,7 +151,7 @@ static int __devinit zorro8390_init(struct net_device *dev, z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(KERN_WARNING " not found (no reset ack).\n"); return -ENODEV; } @@ -274,7 +273,7 @@ static void zorro8390_reset_8390(struct net_device *dev) /* This check _should_not_ be necessary, omit eventually. */ while ((z_readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) - if (time_after(jiffies, reset_start_time + 2*HZ/100)) { + if (jiffies - reset_start_time > 2*HZ/100) { printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); break; @@ -401,7 +400,7 @@ static void zorro8390_block_output(struct net_device *dev, int count, dma_start = jiffies; while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) - if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ + if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ printk(KERN_ERR "%s: timeout waiting for Tx RDC.\n", dev->name); zorro8390_reset_8390(dev); diff --git a/trunk/include/linux/arcdevice.h b/trunk/include/linux/arcdevice.h index 231ba090ae34..7198f129e135 100644 --- a/trunk/include/linux/arcdevice.h +++ b/trunk/include/linux/arcdevice.h @@ -206,6 +206,7 @@ struct ArcProto { extern struct ArcProto *arc_proto_map[256], *arc_proto_default, *arc_bcast_proto, *arc_raw_proto; +extern struct ArcProto arc_proto_null; /* @@ -333,9 +334,17 @@ void arcnet_dump_skb(struct net_device *dev, struct sk_buff *skb, char *desc); #define arcnet_dump_skb(dev,skb,desc) ; #endif +#if (ARCNET_DEBUG_MAX & D_RX) || (ARCNET_DEBUG_MAX & D_TX) +void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc, + int take_arcnet_lock); +#else +#define arcnet_dump_packet(dev, bufnum, desc,take_arcnet_lock) ; +#endif + void arcnet_unregister_proto(struct ArcProto *proto); irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs); struct net_device *alloc_arcdev(char *name); +void arcnet_rx(struct net_device *dev, int bufnum); #endif /* __KERNEL__ */ #endif /* _LINUX_ARCDEVICE_H */ diff --git a/trunk/include/linux/mv643xx.h b/trunk/include/linux/mv643xx.h index 955d3069d727..0b08cd692201 100644 --- a/trunk/include/linux/mv643xx.h +++ b/trunk/include/linux/mv643xx.h @@ -1214,7 +1214,6 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_FORCE_BP_MODE_NO_JAM 0 #define MV643XX_ETH_FORCE_BP_MODE_JAM_TX (1<<7) #define MV643XX_ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR (1<<8) -#define MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED (1<<9) #define MV643XX_ETH_FORCE_LINK_FAIL 0 #define MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL (1<<10) #define MV643XX_ETH_RETRANSMIT_16_ATTEMPTS 0 @@ -1244,8 +1243,6 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_SET_MII_SPEED_TO_10 0 #define MV643XX_ETH_SET_MII_SPEED_TO_100 (1<<24) -#define MV643XX_ETH_MAX_RX_PACKET_MASK (0x7<<17) - #define MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE \ MV643XX_ETH_DO_NOT_FORCE_LINK_PASS | \ MV643XX_ETH_ENABLE_AUTO_NEG_FOR_DUPLX | \ @@ -1288,15 +1285,23 @@ struct mv64xxx_i2c_pdata { #define MV643XX_ETH_NAME "mv643xx_eth" struct mv643xx_eth_platform_data { + /* + * Non-values for mac_addr, phy_addr, port_config, etc. + * override the default value. Setting the corresponding + * force_* field, causes the default value to be overridden + * even when zero. + */ + unsigned int force_phy_addr:1; + unsigned int force_port_config:1; + unsigned int force_port_config_extend:1; + unsigned int force_port_sdma_config:1; + unsigned int force_port_serial_control:1; + int phy_addr; char *mac_addr; /* pointer to mac address */ - u16 force_phy_addr; /* force override if phy_addr == 0 */ - u16 phy_addr; - - /* If speed is 0, then speed and duplex are autonegotiated. */ - int speed; /* 0, SPEED_10, SPEED_100, SPEED_1000 */ - int duplex; /* DUPLEX_HALF or DUPLEX_FULL */ - - /* non-zero values of the following fields override defaults */ + u32 port_config; + u32 port_config_extend; + u32 port_sdma_config; + u32 port_serial_control; u32 tx_queue_size; u32 rx_queue_size; u32 tx_sram_addr;