From 290d4de5b71f60bb5853a7ef9f0e8c817cd26892 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 15:48:15 -0800 Subject: [PATCH] sky2: remove support for untested Yukon EC/rev 0 The Yukon EC/rev0 (A1) chipset requires a bunch of workarounds. I copied these from sk98lin. But since they never got tested and add more cruft to the code; any attempt at using driver as is on this version will probably fail. It looks like this was a early engineering sample chip revision, if it ever shows up on a real system. Produce an error message. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/sky2.h') diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index dce955c76f3..e2bf1d37ed0 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1840,7 +1840,6 @@ struct sky2_port { u16 tx_prod; /* next le to use */ u32 tx_addr64; u16 tx_pending; - u16 tx_last_put; u16 tx_last_mss; struct ring_info *rx_ring ____cacheline_aligned_in_smp; @@ -1849,7 +1848,6 @@ struct sky2_port { u16 rx_next; /* next re to check */ u16 rx_put; /* next le index to use */ u16 rx_pending; - u16 rx_last_put; u16 rx_bufsize; #ifdef SKY2_VLAN_TAG_USED u16 rx_tag; -- cgit v1.2.3-70-g09d2 From c4b1580e8ad1aab13e0d8b97c7af3eebab8791ae Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 15:48:16 -0800 Subject: [PATCH] sky2: drop broken wake on lan support Remove wake on lan support for now. It doesn't work right, and I don't have a machine with working suspend/resume to test or fix it. It will be re-enabled later. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 36 ------------------------------------ drivers/net/sky2.h | 1 - 2 files changed, 37 deletions(-) (limited to 'drivers/net/sky2.h') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3086e52032a..3a6c796eb70 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2777,38 +2777,6 @@ static int sky2_set_pauseparam(struct net_device *dev, return err; } -#ifdef CONFIG_PM -static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct sky2_port *sky2 = netdev_priv(dev); - - wol->supported = WAKE_MAGIC; - wol->wolopts = sky2->wol ? WAKE_MAGIC : 0; -} - -static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) -{ - struct sky2_port *sky2 = netdev_priv(dev); - struct sky2_hw *hw = sky2->hw; - - if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) - return -EOPNOTSUPP; - - sky2->wol = wol->wolopts == WAKE_MAGIC; - - if (sky2->wol) { - memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN); - - sky2_write16(hw, WOL_CTRL_STAT, - WOL_CTL_ENA_PME_ON_MAGIC_PKT | - WOL_CTL_ENA_MAGIC_PKT_UNIT); - } else - sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT); - - return 0; -} -#endif - static int sky2_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ecmd) { @@ -2996,10 +2964,6 @@ static struct ethtool_ops sky2_ethtool_ops = { .set_ringparam = sky2_set_ringparam, .get_pauseparam = sky2_get_pauseparam, .set_pauseparam = sky2_set_pauseparam, -#ifdef CONFIG_PM - .get_wol = sky2_get_wol, - .set_wol = sky2_set_wol, -#endif .phys_id = sky2_phys_id, .get_stats_count = sky2_get_stats_count, .get_ethtool_stats = sky2_get_ethtool_stats, diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index e2bf1d37ed0..2a23f3ad6d9 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1863,7 +1863,6 @@ struct sky2_port { u8 rx_pause; u8 tx_pause; u8 rx_csum; - u8 wol; struct net_device_stats net_stats; -- cgit v1.2.3-70-g09d2 From e07b1aa8b3ebedd3c7e0e1b4b524f1b2d62707cf Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 15:48:17 -0800 Subject: [PATCH] sky2: rework of NAPI and IRQ management Redo the interupt handling of sky2 driver based on the IRQ mangement documentation. All interrupts are handled by the device0 NAPI poll routine. Don't need to adjust interrupt mask in IRQ context, done only when changing device under RTNL. Therefore don't need hwlock anymore. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 276 +++++++++++++++++++++-------------------------------- drivers/net/sky2.h | 15 +-- 2 files changed, 111 insertions(+), 180 deletions(-) (limited to 'drivers/net/sky2.h') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3a6c796eb70..41dbe588de3 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -500,9 +500,9 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* Force a renegotiation */ static void sky2_phy_reinit(struct sky2_port *sky2) { - down(&sky2->phy_sema); + spin_lock_bh(&sky2->phy_lock); sky2_phy_init(sky2->hw, sky2->port); - up(&sky2->phy_sema); + spin_unlock_bh(&sky2->phy_lock); } static void sky2_mac_init(struct sky2_hw *hw, unsigned port) @@ -567,9 +567,9 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); - down(&sky2->phy_sema); + spin_lock_bh(&sky2->phy_lock); sky2_phy_init(hw, port); - up(&sky2->phy_sema); + spin_unlock_bh(&sky2->phy_lock); /* MIB clear */ reg = gma_read16(hw, port, GM_PHY_ADDR); @@ -856,9 +856,9 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: { u16 val = 0; - down(&sky2->phy_sema); + spin_lock_bh(&sky2->phy_lock); err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val); - up(&sky2->phy_sema); + spin_unlock_bh(&sky2->phy_lock); data->val_out = val; break; @@ -868,10 +868,10 @@ static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!capable(CAP_NET_ADMIN)) return -EPERM; - down(&sky2->phy_sema); + spin_lock_bh(&sky2->phy_lock); err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f, data->val_in); - up(&sky2->phy_sema); + spin_unlock_bh(&sky2->phy_lock); break; } return err; @@ -983,7 +983,7 @@ static int sky2_up(struct net_device *dev) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; - u32 ramsize, rxspace; + u32 ramsize, rxspace, imask; int err = -ENOMEM; if (netif_msg_ifup(sky2)) @@ -1048,10 +1048,10 @@ static int sky2_up(struct net_device *dev) goto err_out; /* Enable interrupts from phy/mac for port */ - spin_lock_irq(&hw->hw_lock); - hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; - sky2_write32(hw, B0_IMSK, hw->intr_mask); - spin_unlock_irq(&hw->hw_lock); + imask = sky2_read32(hw, B0_IMSK); + imask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; + sky2_write32(hw, B0_IMSK, imask); + return 0; err_out: @@ -1343,6 +1343,7 @@ static int sky2_down(struct net_device *dev) struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; u16 ctrl; + u32 imask; /* Never really got started! */ if (!sky2->tx_le) @@ -1354,14 +1355,6 @@ static int sky2_down(struct net_device *dev) /* Stop more packets from being queued */ netif_stop_queue(dev); - /* Disable port IRQ */ - spin_lock_irq(&hw->hw_lock); - hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); - sky2_write32(hw, B0_IMSK, hw->intr_mask); - spin_unlock_irq(&hw->hw_lock); - - flush_scheduled_work(); - sky2_phy_reset(hw, port); /* Stop transmitter */ @@ -1405,6 +1398,11 @@ static int sky2_down(struct net_device *dev) sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); + /* Disable port IRQ */ + imask = sky2_read32(hw, B0_IMSK); + imask &= ~(sky2->port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; + sky2_write32(hw, B0_IMSK, imask); + /* turn off LED's */ sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); @@ -1599,20 +1597,19 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) return 0; } -/* - * Interrupt from PHY are handled outside of interrupt context - * because accessing phy registers requires spin wait which might - * cause excess interrupt latency. - */ -static void sky2_phy_task(void *arg) +/* Interrupt from PHY */ +static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) { - struct sky2_port *sky2 = arg; - struct sky2_hw *hw = sky2->hw; + struct net_device *dev = hw->dev[port]; + struct sky2_port *sky2 = netdev_priv(dev); u16 istatus, phystat; - down(&sky2->phy_sema); - istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT); - phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT); + spin_lock(&sky2->phy_lock); + istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); + phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); + + if (!netif_running(dev)) + goto out; if (netif_msg_intr(sky2)) printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", @@ -1638,12 +1635,7 @@ static void sky2_phy_task(void *arg) sky2_link_down(sky2); } out: - up(&sky2->phy_sema); - - spin_lock_irq(&hw->hw_lock); - hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2; - sky2_write32(hw, B0_IMSK, hw->intr_mask); - spin_unlock_irq(&hw->hw_lock); + spin_unlock(&sky2->phy_lock); } @@ -1655,20 +1647,6 @@ static void sky2_tx_timeout(struct net_device *dev) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; unsigned txq = txqaddr[sky2->port]; - u16 ridx; - - /* Maybe we just missed an status interrupt */ - spin_lock(&sky2->tx_lock); - ridx = sky2_read16(hw, - sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX); - sky2_tx_complete(sky2, ridx); - spin_unlock(&sky2->tx_lock); - - if (!netif_queue_stopped(dev)) { - if (net_ratelimit()) - pr_info(PFX "transmit interrupt missed? recovered\n"); - return; - } if (netif_msg_timer(sky2)) printk(KERN_ERR PFX "%s: tx timeout\n", dev->name); @@ -1698,6 +1676,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) struct sky2_hw *hw = sky2->hw; int err; u16 ctl, mode; + u32 imask; if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) return -EINVAL; @@ -1710,12 +1689,15 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) return 0; } + imask = sky2_read32(hw, B0_IMSK); sky2_write32(hw, B0_IMSK, 0); dev->trans_start = jiffies; /* prevent tx timeout */ netif_stop_queue(dev); netif_poll_disable(hw->dev[0]); + synchronize_irq(hw->pdev->irq); + ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); sky2_rx_stop(sky2); @@ -1734,7 +1716,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); err = sky2_rx_start(sky2); - sky2_write32(hw, B0_IMSK, hw->intr_mask); + sky2_write32(hw, B0_IMSK, imask); if (err) dev_close(dev); @@ -1838,76 +1820,51 @@ error: goto resubmit; } -/* - * Check for transmit complete - */ -#define TX_NO_STATUS 0xffff - -static void sky2_tx_check(struct sky2_hw *hw, int port, u16 last) +/* Transmit complete */ +static inline void sky2_tx_done(struct net_device *dev, u16 last) { - if (last != TX_NO_STATUS) { - struct net_device *dev = hw->dev[port]; - if (dev && netif_running(dev)) { - struct sky2_port *sky2 = netdev_priv(dev); + struct sky2_port *sky2 = netdev_priv(dev); - spin_lock(&sky2->tx_lock); - sky2_tx_complete(sky2, last); - spin_unlock(&sky2->tx_lock); - } + if (netif_running(dev)) { + spin_lock(&sky2->tx_lock); + sky2_tx_complete(sky2, last); + spin_unlock(&sky2->tx_lock); } } -/* - * Both ports share the same status interrupt, therefore there is only - * one poll routine. - */ -static int sky2_poll(struct net_device *dev0, int *budget) +/* Process status response ring */ +static int sky2_status_intr(struct sky2_hw *hw, int to_do) { - struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; - unsigned int to_do = min(dev0->quota, *budget); - unsigned int work_done = 0; - u16 hwidx; - u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; - - sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); - - /* - * Kick the STAT_LEV_TIMER_CTRL timer. - * This fixes my hangs on Yukon-EC (0xb6) rev 1. - * The if clause is there to start the timer only if it has been - * configured correctly and not been disabled via ethtool. - */ - if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) { - sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP); - sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START); - } + int work_done = 0; - hwidx = sky2_read16(hw, STAT_PUT_IDX); - BUG_ON(hwidx >= STATUS_RING_SIZE); rmb(); - while (hwidx != hw->st_idx) { + for(;;) { struct sky2_status_le *le = hw->st_le + hw->st_idx; struct net_device *dev; struct sky2_port *sky2; struct sk_buff *skb; u32 status; u16 length; + u8 link, opcode; + + opcode = le->opcode; + if (!opcode) + break; + opcode &= ~HW_OWNER; - le = hw->st_le + hw->st_idx; hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE; - prefetch(hw->st_le + hw->st_idx); + le->opcode = 0; - BUG_ON(le->link >= 2); - dev = hw->dev[le->link]; - if (dev == NULL || !netif_running(dev)) - continue; + link = le->link; + BUG_ON(link >= 2); + dev = hw->dev[link]; sky2 = netdev_priv(dev); - status = le32_to_cpu(le->status); - length = le16_to_cpu(le->length); + length = le->length; + status = le->status; - switch (le->opcode & ~HW_OWNER) { + switch (opcode) { case OP_RXSTAT: skb = sky2_receive(sky2, length, status); if (!skb) @@ -1947,42 +1904,23 @@ static int sky2_poll(struct net_device *dev0, int *budget) case OP_TXINDEXLE: /* TX index reports status for both ports */ - tx_done[0] = status & 0xffff; - tx_done[1] = ((status >> 24) & 0xff) - | (u16)(length & 0xf) << 8; + sky2_tx_done(hw->dev[0], status & 0xffff); + if (hw->dev[1]) + sky2_tx_done(hw->dev[1], + ((status >> 24) & 0xff) + | (u16)(length & 0xf) << 8); break; default: if (net_ratelimit()) printk(KERN_WARNING PFX - "unknown status opcode 0x%x\n", le->opcode); + "unknown status opcode 0x%x\n", opcode); break; } } exit_loop: - sky2_tx_check(hw, 0, tx_done[0]); - sky2_tx_check(hw, 1, tx_done[1]); - - if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); - } - - if (likely(work_done < to_do)) { - spin_lock_irq(&hw->hw_lock); - __netif_rx_complete(dev0); - - hw->intr_mask |= Y2_IS_STAT_BMU; - sky2_write32(hw, B0_IMSK, hw->intr_mask); - spin_unlock_irq(&hw->hw_lock); - - return 0; - } else { - *budget -= work_done; - dev0->quota -= work_done; - return 1; - } + return work_done; } static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status) @@ -2101,42 +2039,17 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) } } -static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) -{ - struct net_device *dev = hw->dev[port]; - struct sky2_port *sky2 = netdev_priv(dev); - - hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); - sky2_write32(hw, B0_IMSK, hw->intr_mask); - - schedule_work(&sky2->phy_task); -} -static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) +static int sky2_poll(struct net_device *dev0, int *budget) { - struct sky2_hw *hw = dev_id; - struct net_device *dev0 = hw->dev[0]; - u32 status; - - status = sky2_read32(hw, B0_Y2_SP_ISRC2); - if (status == 0 || status == ~0) - return IRQ_NONE; + struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; + int work_limit = min(dev0->quota, *budget); + int work_done = 0; + u32 status = sky2_read32(hw, B0_ISRC); - spin_lock(&hw->hw_lock); if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); - /* Do NAPI for Rx and Tx status */ - if (status & Y2_IS_STAT_BMU) { - hw->intr_mask &= ~Y2_IS_STAT_BMU; - sky2_write32(hw, B0_IMSK, hw->intr_mask); - - if (likely(__netif_rx_schedule_prep(dev0))) { - prefetch(&hw->st_le[hw->st_idx]); - __netif_rx_schedule(dev0); - } - } - if (status & Y2_IS_IRQ_PHY1) sky2_phy_intr(hw, 0); @@ -2149,9 +2062,38 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) if (status & Y2_IS_IRQ_MAC2) sky2_mac_intr(hw, 1); + if (status & Y2_IS_STAT_BMU) { + work_done = sky2_status_intr(hw, work_limit); + *budget -= work_done; + dev0->quota -= work_done; + + if (work_done >= work_limit) + return 1; + + sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); + } + + netif_rx_complete(dev0); + + /* Ack interrupt and re-enable */ sky2_write32(hw, B0_Y2_SP_ICR, 2); + return 0; +} + +static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct sky2_hw *hw = dev_id; + struct net_device *dev0 = hw->dev[0]; + u32 status; + + /* Reading this mask interrupts as side effect */ + status = sky2_read32(hw, B0_Y2_SP_ISRC2); + if (status == 0 || status == ~0) + return IRQ_NONE; - spin_unlock(&hw->hw_lock); + prefetch(&hw->st_le[hw->st_idx]); + if (likely(__netif_rx_schedule_prep(dev0))) + __netif_rx_schedule(dev0); return IRQ_HANDLED; } @@ -2320,7 +2262,6 @@ static int sky2_reset(struct sky2_hw *hw) /* Set the list last index */ sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); - /* These status setup values are copied from SysKonnect's driver */ sky2_write16(hw, STAT_TX_IDX_TH, 10); sky2_write8(hw, STAT_FIFO_WM, 16); @@ -2714,7 +2655,7 @@ static int sky2_phys_id(struct net_device *dev, u32 data) ms = data * 1000; /* save initial values */ - down(&sky2->phy_sema); + spin_lock_bh(&sky2->phy_lock); if (hw->chip_id == CHIP_ID_YUKON_XL) { u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); @@ -2730,9 +2671,9 @@ static int sky2_phys_id(struct net_device *dev, u32 data) sky2_led(hw, port, onoff); onoff = !onoff; - up(&sky2->phy_sema); + spin_unlock_bh(&sky2->phy_lock); interrupted = msleep_interruptible(250); - down(&sky2->phy_sema); + spin_lock_bh(&sky2->phy_lock); ms -= 250; } @@ -2747,7 +2688,7 @@ static int sky2_phys_id(struct net_device *dev, u32 data) gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); } - up(&sky2->phy_sema); + spin_unlock_bh(&sky2->phy_lock); return 0; } @@ -3023,8 +2964,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, */ sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); - INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2); - init_MUTEX(&sky2->phy_sema); + spin_lock_init(&sky2->phy_lock); sky2->tx_pending = TX_DEF_PENDING; sky2->rx_pending = RX_DEF_PENDING; sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); @@ -3136,7 +3076,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_free_hw; } hw->pm_cap = pm_cap; - spin_lock_init(&hw->hw_lock); #ifdef __BIG_ENDIAN /* byte swap descriptors in hardware */ @@ -3196,8 +3135,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_unregister; } - hw->intr_mask = Y2_IS_BASE; - sky2_write32(hw, B0_IMSK, hw->intr_mask); + sky2_write32(hw, B0_IMSK, Y2_IS_BASE); pci_set_drvdata(pdev, hw); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 2a23f3ad6d9..db362b69b0b 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -278,13 +278,9 @@ enum { Y2_IS_CHK_TXS1 = 1<<1, /* Descriptor error TXS 1 */ Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */ - Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU | - Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY | - Y2_IS_IRQ_SW | Y2_IS_TIMINT, - Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 | - Y2_IS_CHK_RX1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXS1, - Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 | - Y2_IS_CHK_RX2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_TXS2, + Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU, + Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1, + Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2, }; /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ @@ -1832,6 +1828,7 @@ struct sky2_port { struct net_device *netdev; unsigned port; u32 msg_enable; + spinlock_t phy_lock; spinlock_t tx_lock ____cacheline_aligned_in_smp; struct tx_ring_info *tx_ring; @@ -1866,16 +1863,12 @@ struct sky2_port { struct net_device_stats net_stats; - struct work_struct phy_task; - struct semaphore phy_sema; }; struct sky2_hw { void __iomem *regs; struct pci_dev *pdev; struct net_device *dev[2]; - spinlock_t hw_lock; - u32 intr_mask; int pm_cap; u8 chip_id; -- cgit v1.2.3-70-g09d2 From fb2690a9bfa330aff3de29cbdde526591ac90dce Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 15:48:19 -0800 Subject: [PATCH] sky2: add MSI support Add MSI support to sky2 driver. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++--- drivers/net/sky2.h | 2 ++ 2 files changed, 79 insertions(+), 4 deletions(-) (limited to 'drivers/net/sky2.h') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7e3353f55c3..2e29972b8d0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -92,6 +92,10 @@ static int copybreak __read_mostly = 256; module_param(copybreak, int, 0); MODULE_PARM_DESC(copybreak, "Receive copy threshold"); +static int disable_msi = 0; +module_param(disable_msi, int, 0); +MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); + static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, @@ -2045,7 +2049,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; int work_limit = min(dev0->quota, *budget); int work_done = 0; - u32 status = sky2_read32(hw, B0_ISRC); + u32 status = sky2_read32(hw, B0_Y2_SP_EISR); if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); @@ -2075,8 +2079,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) netif_rx_complete(dev0); - /* Ack interrupt and re-enable */ - sky2_write32(hw, B0_Y2_SP_ICR, 2); + status = sky2_read32(hw, B0_Y2_SP_LISR); return 0; } @@ -3001,6 +3004,66 @@ static void __devinit sky2_show_addr(struct net_device *dev) dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); } +/* Handle software interrupt used during MSI test */ +static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id, + struct pt_regs *regs) +{ + struct sky2_hw *hw = dev_id; + u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2); + + if (status == 0) + return IRQ_NONE; + + if (status & Y2_IS_IRQ_SW) { + hw->msi_detected = 1; + wake_up(&hw->msi_wait); + sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); + } + sky2_write32(hw, B0_Y2_SP_ICR, 2); + + return IRQ_HANDLED; +} + +/* Test interrupt path by forcing a a software IRQ */ +static int __devinit sky2_test_msi(struct sky2_hw *hw) +{ + struct pci_dev *pdev = hw->pdev; + int err; + + sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); + + err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw); + if (err) { + printk(KERN_ERR PFX "%s: cannot assign irq %d\n", + pci_name(pdev), pdev->irq); + return err; + } + + init_waitqueue_head (&hw->msi_wait); + + sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); + wmb(); + + wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); + + if (!hw->msi_detected) { + /* MSI test failed, go back to INTx mode */ + printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " + "switching to INTx mode. Please report this failure to " + "the PCI maintainer and include system chipset information.\n", + pci_name(pdev)); + + err = -EOPNOTSUPP; + sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); + } + + sky2_write32(hw, B0_IMSK, 0); + + free_irq(pdev->irq, hw); + + return err; +} + static int __devinit sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -3121,7 +3184,15 @@ static int __devinit sky2_probe(struct pci_dev *pdev, } } - err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); + if (!disable_msi && pci_enable_msi(pdev) == 0) { + err = sky2_test_msi(hw); + if (err == -EOPNOTSUPP) + pci_disable_msi(pdev); + else if (err) + goto err_out_unregister; + } + + err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); if (err) { printk(KERN_ERR PFX "%s: cannot assign irq %d\n", pci_name(pdev), pdev->irq); @@ -3135,6 +3206,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, return 0; err_out_unregister: + pci_disable_msi(pdev); if (dev1) { unregister_netdev(dev1); free_netdev(dev1); @@ -3177,6 +3249,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev) sky2_read8(hw, B0_CTST); free_irq(pdev->irq, hw); + pci_disable_msi(pdev); pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index db362b69b0b..50e9f7d38bf 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1879,6 +1879,8 @@ struct sky2_hw { struct sky2_status_le *st_le; u32 st_idx; dma_addr_t st_dma; + int msi_detected; + wait_queue_head_t msi_wait; }; /* Register accessor for memory mapped device */ -- cgit v1.2.3-70-g09d2 From d257924e85a81561a956f1791fa5a226e3a32ce1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 20 Mar 2006 15:48:22 -0800 Subject: [PATCH] sky2: handle all error irqs The hardware has additional error trap interrupt bits. I have never seen them trigger, but if they do, it looks like this might be useful. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 55 ++++++++++++++++++++++++++++++++++++++++++++---------- drivers/net/sky2.h | 6 ++++-- 2 files changed, 49 insertions(+), 12 deletions(-) (limited to 'drivers/net/sky2.h') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index ab36a7460a2..380bb59f351 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2066,6 +2066,27 @@ static void sky2_mac_intr(struct sky2_hw *hw, unsigned port) } } +/* This should never happen it is a fatal situation */ +static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, + const char *rxtx, u32 mask) +{ + struct net_device *dev = hw->dev[port]; + struct sky2_port *sky2 = netdev_priv(dev); + u32 imask; + + printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n", + dev ? dev->name : "", rxtx); + + imask = sky2_read32(hw, B0_IMSK); + imask &= ~mask; + sky2_write32(hw, B0_IMSK, imask); + + if (dev) { + spin_lock(&sky2->phy_lock); + sky2_link_down(sky2); + spin_unlock(&sky2->phy_lock); + } +} static int sky2_poll(struct net_device *dev0, int *budget) { @@ -2074,20 +2095,34 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); - if (status & Y2_IS_HW_ERR) - sky2_hw_intr(hw); + if (unlikely(status & ~Y2_IS_STAT_BMU)) { + if (status & Y2_IS_HW_ERR) + sky2_hw_intr(hw); + + if (status & Y2_IS_IRQ_PHY1) + sky2_phy_intr(hw, 0); - if (status & Y2_IS_IRQ_PHY1) - sky2_phy_intr(hw, 0); + if (status & Y2_IS_IRQ_PHY2) + sky2_phy_intr(hw, 1); - if (status & Y2_IS_IRQ_PHY2) - sky2_phy_intr(hw, 1); + if (status & Y2_IS_IRQ_MAC1) + sky2_mac_intr(hw, 0); - if (status & Y2_IS_IRQ_MAC1) - sky2_mac_intr(hw, 0); + if (status & Y2_IS_IRQ_MAC2) + sky2_mac_intr(hw, 1); - if (status & Y2_IS_IRQ_MAC2) - sky2_mac_intr(hw, 1); + if (status & Y2_IS_CHK_RX1) + sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); + + if (status & Y2_IS_CHK_RX2) + sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); + + if (status & Y2_IS_CHK_TXA1) + sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); + + if (status & Y2_IS_CHK_TXA2) + sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); + } if (status & Y2_IS_STAT_BMU) { work_done = sky2_status_intr(hw, work_limit); diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 50e9f7d38bf..d63cd5a1b71 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -279,8 +279,10 @@ enum { Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */ Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU, - Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1, - Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2, + Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 + | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1, + Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 + | Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2, }; /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ -- cgit v1.2.3-70-g09d2 From eadfa7ddca98b0430b8b666e0344ab1d559389c8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 22 Mar 2006 10:38:45 -0800 Subject: [PATCH] sky2: more ethtool stats Expose all the available hardware statistics via ethtool. And cleanup some of the statistics definitions. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 27 +++++++++++++++++---- drivers/net/sky2.h | 71 +++++++++++++++++++++++++++--------------------------- 2 files changed, 57 insertions(+), 41 deletions(-) (limited to 'drivers/net/sky2.h') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f08fe6c884b..36db93811ac 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2478,17 +2478,34 @@ static const struct sky2_stat { { "rx_unicast", GM_RXF_UC_OK }, { "tx_mac_pause", GM_TXF_MPAUSE }, { "rx_mac_pause", GM_RXF_MPAUSE }, - { "collisions", GM_TXF_SNG_COL }, + { "collisions", GM_TXF_COL }, { "late_collision",GM_TXF_LAT_COL }, { "aborted", GM_TXF_ABO_COL }, + { "single_collisions", GM_TXF_SNG_COL }, { "multi_collisions", GM_TXF_MUL_COL }, - { "fifo_underrun", GM_TXE_FIFO_UR }, - { "fifo_overflow", GM_RXE_FIFO_OV }, - { "rx_toolong", GM_RXF_LNG_ERR }, - { "rx_jabber", GM_RXF_JAB_PKT }, + + { "rx_short", GM_RXE_SHT }, { "rx_runt", GM_RXE_FRAG }, + { "rx_64_byte_packets", GM_RXF_64B }, + { "rx_65_to_127_byte_packets", GM_RXF_127B }, + { "rx_128_to_255_byte_packets", GM_RXF_255B }, + { "rx_256_to_511_byte_packets", GM_RXF_511B }, + { "rx_512_to_1023_byte_packets", GM_RXF_1023B }, + { "rx_1024_to_1518_byte_packets", GM_RXF_1518B }, + { "rx_1518_to_max_byte_packets", GM_RXF_MAX_SZ }, { "rx_too_long", GM_RXF_LNG_ERR }, + { "rx_fifo_overflow", GM_RXE_FIFO_OV }, + { "rx_jabber", GM_RXF_JAB_PKT }, { "rx_fcs_error", GM_RXF_FCS_ERR }, + + { "tx_64_byte_packets", GM_TXF_64B }, + { "tx_65_to_127_byte_packets", GM_TXF_127B }, + { "tx_128_to_255_byte_packets", GM_TXF_255B }, + { "tx_256_to_511_byte_packets", GM_TXF_511B }, + { "tx_512_to_1023_byte_packets", GM_TXF_1023B }, + { "tx_1024_to_1518_byte_packets", GM_TXF_1518B }, + { "tx_1519_to_max_byte_packets", GM_TXF_MAX_SZ }, + { "tx_fifo_underrun", GM_TXE_FIFO_UR }, }; static u32 sky2_get_rx_csum(struct net_device *dev) diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index d63cd5a1b71..2838f661b39 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -1373,23 +1373,23 @@ enum { GM_SMI_CTRL = 0x0080, /* 16 bit r/w SMI Control Register */ GM_SMI_DATA = 0x0084, /* 16 bit r/w SMI Data Register */ GM_PHY_ADDR = 0x0088, /* 16 bit r/w GPHY Address Register */ +/* MIB Counters */ + GM_MIB_CNT_BASE = 0x0100, /* Base Address of MIB Counters */ + GM_MIB_CNT_SIZE = 256, }; -/* MIB Counters */ -#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */ -#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */ /* * MIB Counters base address definitions (low word) - * use offset 4 for access to high word (32 bit r/o) */ enum { - GM_RXF_UC_OK = GM_MIB_CNT_BASE + 0, /* Unicast Frames Received OK */ + GM_RXF_UC_OK = GM_MIB_CNT_BASE + 0, /* Unicast Frames Received OK */ GM_RXF_BC_OK = GM_MIB_CNT_BASE + 8, /* Broadcast Frames Received OK */ GM_RXF_MPAUSE = GM_MIB_CNT_BASE + 16, /* Pause MAC Ctrl Frames Received */ GM_RXF_MC_OK = GM_MIB_CNT_BASE + 24, /* Multicast Frames Received OK */ GM_RXF_FCS_ERR = GM_MIB_CNT_BASE + 32, /* Rx Frame Check Seq. Error */ - /* GM_MIB_CNT_BASE + 40: reserved */ + GM_RXO_OK_LO = GM_MIB_CNT_BASE + 48, /* Octets Received OK Low */ GM_RXO_OK_HI = GM_MIB_CNT_BASE + 56, /* Octets Received OK High */ GM_RXO_ERR_LO = GM_MIB_CNT_BASE + 64, /* Octets Received Invalid Low */ @@ -1397,37 +1397,36 @@ enum { GM_RXF_SHT = GM_MIB_CNT_BASE + 80, /* Frames <64 Byte Received OK */ GM_RXE_FRAG = GM_MIB_CNT_BASE + 88, /* Frames <64 Byte Received with FCS Err */ GM_RXF_64B = GM_MIB_CNT_BASE + 96, /* 64 Byte Rx Frame */ - GM_RXF_127B = GM_MIB_CNT_BASE + 104, /* 65-127 Byte Rx Frame */ - GM_RXF_255B = GM_MIB_CNT_BASE + 112, /* 128-255 Byte Rx Frame */ - GM_RXF_511B = GM_MIB_CNT_BASE + 120, /* 256-511 Byte Rx Frame */ - GM_RXF_1023B = GM_MIB_CNT_BASE + 128, /* 512-1023 Byte Rx Frame */ - GM_RXF_1518B = GM_MIB_CNT_BASE + 136, /* 1024-1518 Byte Rx Frame */ - GM_RXF_MAX_SZ = GM_MIB_CNT_BASE + 144, /* 1519-MaxSize Byte Rx Frame */ - GM_RXF_LNG_ERR = GM_MIB_CNT_BASE + 152, /* Rx Frame too Long Error */ - GM_RXF_JAB_PKT = GM_MIB_CNT_BASE + 160, /* Rx Jabber Packet Frame */ - /* GM_MIB_CNT_BASE + 168: reserved */ - GM_RXE_FIFO_OV = GM_MIB_CNT_BASE + 176, /* Rx FIFO overflow Event */ - /* GM_MIB_CNT_BASE + 184: reserved */ - GM_TXF_UC_OK = GM_MIB_CNT_BASE + 192, /* Unicast Frames Xmitted OK */ - GM_TXF_BC_OK = GM_MIB_CNT_BASE + 200, /* Broadcast Frames Xmitted OK */ - GM_TXF_MPAUSE = GM_MIB_CNT_BASE + 208, /* Pause MAC Ctrl Frames Xmitted */ - GM_TXF_MC_OK = GM_MIB_CNT_BASE + 216, /* Multicast Frames Xmitted OK */ - GM_TXO_OK_LO = GM_MIB_CNT_BASE + 224, /* Octets Transmitted OK Low */ - GM_TXO_OK_HI = GM_MIB_CNT_BASE + 232, /* Octets Transmitted OK High */ - GM_TXF_64B = GM_MIB_CNT_BASE + 240, /* 64 Byte Tx Frame */ - GM_TXF_127B = GM_MIB_CNT_BASE + 248, /* 65-127 Byte Tx Frame */ - GM_TXF_255B = GM_MIB_CNT_BASE + 256, /* 128-255 Byte Tx Frame */ - GM_TXF_511B = GM_MIB_CNT_BASE + 264, /* 256-511 Byte Tx Frame */ - GM_TXF_1023B = GM_MIB_CNT_BASE + 272, /* 512-1023 Byte Tx Frame */ - GM_TXF_1518B = GM_MIB_CNT_BASE + 280, /* 1024-1518 Byte Tx Frame */ - GM_TXF_MAX_SZ = GM_MIB_CNT_BASE + 288, /* 1519-MaxSize Byte Tx Frame */ - - GM_TXF_COL = GM_MIB_CNT_BASE + 304, /* Tx Collision */ - GM_TXF_LAT_COL = GM_MIB_CNT_BASE + 312, /* Tx Late Collision */ - GM_TXF_ABO_COL = GM_MIB_CNT_BASE + 320, /* Tx aborted due to Exces. Col. */ - GM_TXF_MUL_COL = GM_MIB_CNT_BASE + 328, /* Tx Multiple Collision */ - GM_TXF_SNG_COL = GM_MIB_CNT_BASE + 336, /* Tx Single Collision */ - GM_TXE_FIFO_UR = GM_MIB_CNT_BASE + 344, /* Tx FIFO Underrun Event */ + GM_RXF_127B = GM_MIB_CNT_BASE + 104,/* 65-127 Byte Rx Frame */ + GM_RXF_255B = GM_MIB_CNT_BASE + 112,/* 128-255 Byte Rx Frame */ + GM_RXF_511B = GM_MIB_CNT_BASE + 120,/* 256-511 Byte Rx Frame */ + GM_RXF_1023B = GM_MIB_CNT_BASE + 128,/* 512-1023 Byte Rx Frame */ + GM_RXF_1518B = GM_MIB_CNT_BASE + 136,/* 1024-1518 Byte Rx Frame */ + GM_RXF_MAX_SZ = GM_MIB_CNT_BASE + 144,/* 1519-MaxSize Byte Rx Frame */ + GM_RXF_LNG_ERR = GM_MIB_CNT_BASE + 152,/* Rx Frame too Long Error */ + GM_RXF_JAB_PKT = GM_MIB_CNT_BASE + 160,/* Rx Jabber Packet Frame */ + + GM_RXE_FIFO_OV = GM_MIB_CNT_BASE + 176,/* Rx FIFO overflow Event */ + GM_TXF_UC_OK = GM_MIB_CNT_BASE + 192,/* Unicast Frames Xmitted OK */ + GM_TXF_BC_OK = GM_MIB_CNT_BASE + 200,/* Broadcast Frames Xmitted OK */ + GM_TXF_MPAUSE = GM_MIB_CNT_BASE + 208,/* Pause MAC Ctrl Frames Xmitted */ + GM_TXF_MC_OK = GM_MIB_CNT_BASE + 216,/* Multicast Frames Xmitted OK */ + GM_TXO_OK_LO = GM_MIB_CNT_BASE + 224,/* Octets Transmitted OK Low */ + GM_TXO_OK_HI = GM_MIB_CNT_BASE + 232,/* Octets Transmitted OK High */ + GM_TXF_64B = GM_MIB_CNT_BASE + 240,/* 64 Byte Tx Frame */ + GM_TXF_127B = GM_MIB_CNT_BASE + 248,/* 65-127 Byte Tx Frame */ + GM_TXF_255B = GM_MIB_CNT_BASE + 256,/* 128-255 Byte Tx Frame */ + GM_TXF_511B = GM_MIB_CNT_BASE + 264,/* 256-511 Byte Tx Frame */ + GM_TXF_1023B = GM_MIB_CNT_BASE + 272,/* 512-1023 Byte Tx Frame */ + GM_TXF_1518B = GM_MIB_CNT_BASE + 280,/* 1024-1518 Byte Tx Frame */ + GM_TXF_MAX_SZ = GM_MIB_CNT_BASE + 288,/* 1519-MaxSize Byte Tx Frame */ + + GM_TXF_COL = GM_MIB_CNT_BASE + 304,/* Tx Collision */ + GM_TXF_LAT_COL = GM_MIB_CNT_BASE + 312,/* Tx Late Collision */ + GM_TXF_ABO_COL = GM_MIB_CNT_BASE + 320,/* Tx aborted due to Exces. Col. */ + GM_TXF_MUL_COL = GM_MIB_CNT_BASE + 328,/* Tx Multiple Collision */ + GM_TXF_SNG_COL = GM_MIB_CNT_BASE + 336,/* Tx Single Collision */ + GM_TXE_FIFO_UR = GM_MIB_CNT_BASE + 344,/* Tx FIFO Underrun Event */ }; /* GMAC Bit Definitions */ -- cgit v1.2.3-70-g09d2