Stephen Hemminger <[EMAIL PROTECTED]> :
[...]
> Then stop at #6. 

#1..#6 applied to branch 'for-jeff' at
git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6.git

Shortlog
--------

Francois Romieu:
      de2104x: prevent interrupt before the interrupt handler is registered
      de2104x: fix the TX watchdog

Stephen Hemminger:
      sky2: remove support for old untested hardware
      sky2: warn on newer untested chips
      sky2: remove wake-on-lan until fixed
      sky2: not really random enough for entropy pool
      sky2: force Tx interrupt when ring near full
      sky2: don't choke on oversize frames

Patch
-----

diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 72c1630..34afa0d 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -61,10 +61,6 @@
  * a receive requires one (or two if using 64 bit dma).
  */
 
-#define is_ec_a1(hw) \
-       unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \
-                (hw)->chip_rev == CHIP_REV_YU_EC_A1)
-
 #define RX_LE_SIZE             512
 #define RX_LE_BYTES            (RX_LE_SIZE*sizeof(struct sky2_rx_le))
 #define RX_MAX_PENDING         (RX_LE_SIZE/2 - 2)
@@ -74,7 +70,7 @@
 #define TX_RING_SIZE           512
 #define TX_DEF_PENDING         (TX_RING_SIZE - 1)
 #define TX_MIN_PENDING         64
-#define MAX_SKB_TX_LE          (4 + 2*MAX_SKB_FRAGS)
+#define MAX_SKB_TX_LE          (4 + 
(sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS)
 
 #define STATUS_RING_SIZE       2048    /* 2 ports * (TX + 2*RX) */
 #define STATUS_LE_BYTES                (STATUS_RING_SIZE*sizeof(struct 
sky2_status_le))
@@ -622,8 +618,8 @@ static void sky2_mac_init(struct sky2_hw
 
        /* Configure Rx MAC FIFO */
        sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
-       sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T),
-                    GMF_RX_CTRL_DEF);
+       sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
+                    GMF_OPER_ON | GMF_RX_F_FL_ON);
 
        /* Flush Rx MAC FIFO on any flow control or error */
        sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
@@ -725,37 +721,11 @@ static inline struct sky2_tx_le *get_tx_
        return le;
 }
 
-/*
- * This is a workaround code taken from SysKonnect sk98lin driver
- * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
- */
-static void sky2_put_idx(struct sky2_hw *hw, unsigned q,
-                               u16 idx, u16 *last, u16 size)
+/* Update chip's next pointer */
+static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
 {
        wmb();
-       if (is_ec_a1(hw) && idx < *last) {
-               u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
-
-               if (hwget == 0) {
-                       /* Start prefetching again */
-                       sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0);
-                       goto setnew;
-               }
-
-               if (hwget == size - 1) {
-                       /* set watermark to one list element */
-                       sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8);
-
-                       /* set put index to first list element */
-                       sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0);
-               } else          /* have hardware go to end of list */
-                       sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX),
-                                    size - 1);
-       } else {
-setnew:
-               sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
-       }
-       *last = idx;
+       sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
        mmiowb();
 }
 
@@ -995,9 +965,12 @@ static int sky2_rx_start(struct sky2_por
                sky2_rx_add(sky2, re->mapaddr);
        }
 
+       /* Truncate oversize frames */
+       sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 
8);
+       sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON);
+
        /* Tell chip about available buffers */
-       sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
-       sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
+       sky2_put_idx(hw, rxq, sky2->rx_put);
        return 0;
 nomem:
        sky2_rx_clean(sky2);
@@ -1145,6 +1118,7 @@ static int sky2_xmit_frame(struct sk_buf
        struct sky2_tx_le *le = NULL;
        struct tx_ring_info *re;
        unsigned i, len;
+       int avail;
        dma_addr_t mapping;
        u32 addr64;
        u16 mss;
@@ -1287,11 +1261,14 @@ static int sky2_xmit_frame(struct sk_buf
        re->idx = sky2->tx_prod;
        le->ctrl |= EOP;
 
-       sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
-                    &sky2->tx_last_put, TX_RING_SIZE);
+       avail = tx_avail(sky2);
+       if (avail < TX_MIN_PENDING) {
+               le->ctrl |= FRC_STAT;
+               if (avail <= MAX_SKB_TX_LE)
+                       netif_stop_queue(dev);
+       }
 
-       if (tx_avail(sky2) <= MAX_SKB_TX_LE)
-               netif_stop_queue(dev);
+       sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
 
 out_unlock:
        spin_unlock(&sky2->tx_lock);
@@ -1707,10 +1684,12 @@ static void sky2_tx_timeout(struct net_d
 
 
 #define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
-/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan 
*/
+/* Want receive buffer size to be multiple of 64 bits
+ * and incl room for vlan and truncation
+ */
 static inline unsigned sky2_buf_size(int mtu)
 {
-       return roundup(mtu + ETH_HLEN + 4, 8);
+       return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
 }
 
 static int sky2_change_mtu(struct net_device *dev, int new_mtu)
@@ -1793,7 +1772,7 @@ static struct sk_buff *sky2_receive(stru
        if (!(status & GMR_FS_RX_OK))
                goto resubmit;
 
-       if ((status >> 16) != length || length > sky2->rx_bufsize)
+       if (length > sky2->netdev->mtu + ETH_HLEN)
                goto oversize;
 
        if (length < copybreak) {
@@ -1832,8 +1811,7 @@ resubmit:
        sky2_rx_add(sky2, re->mapaddr);
 
        /* Tell receiver about new buffers. */
-       sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put,
-                    &sky2->rx_last_put, RX_LE_SIZE);
+       sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put);
 
        return skb;
 
@@ -2227,6 +2205,23 @@ static int sky2_reset(struct sky2_hw *hw
                return -EOPNOTSUPP;
        }
 
+       hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
+
+       /* This rev is really old, and requires untested workarounds */
+       if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == 
CHIP_REV_YU_EC_A1) {
+               printk(KERN_ERR PFX "%s: unsupported revision Yukon-%s (0x%x) 
rev %d\n",
+                      pci_name(hw->pdev), yukon2_name[hw->chip_id - 
CHIP_ID_YUKON_XL],
+                      hw->chip_id, hw->chip_rev);
+               return -EOPNOTSUPP;
+       }
+
+       /* This chip is new and not tested yet */
+       if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+               pr_info(PFX "%s: is a version of Yukon 2 chipset that has not 
been tested yet.\n",
+                       pci_name(hw->pdev));
+               pr_info("Please report success/failure to maintainer <[EMAIL 
PROTECTED]>\n");
+       }
+
        /* disable ASF */
        if (hw->chip_id <= CHIP_ID_YUKON_EC) {
                sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
@@ -2260,7 +2255,6 @@ static int sky2_reset(struct sky2_hw *hw
                if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
                        ++hw->ports;
        }
-       hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
 
        sky2_set_power_state(hw, PCI_D0);
 
@@ -2327,29 +2321,17 @@ static int sky2_reset(struct sky2_hw *hw
        sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
 
        /* These status setup values are copied from SysKonnect's driver */
-       if (is_ec_a1(hw)) {
-               /* WA for dev. #4.3 */
-               sky2_write16(hw, STAT_TX_IDX_TH, 0xfff);        /* Tx Threshold 
*/
-
-               /* set Status-FIFO watermark */
-               sky2_write8(hw, STAT_FIFO_WM, 0x21);    /* WA for dev. #4.18 */
-
-               /* set Status-FIFO ISR watermark */
-               sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07);        /* WA for dev. 
#4.18 */
-               sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000));
-       } else {
-               sky2_write16(hw, STAT_TX_IDX_TH, 10);
-               sky2_write8(hw, STAT_FIFO_WM, 16);
+       sky2_write16(hw, STAT_TX_IDX_TH, 10);
+       sky2_write8(hw, STAT_FIFO_WM, 16);
 
-               /* set Status-FIFO ISR watermark */
-               if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
-                       sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
-               else
-                       sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
+       /* set Status-FIFO ISR watermark */
+       if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
+               sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
+       else
+               sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
 
-               sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
-               sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7));
-       }
+       sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
+       sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7));
 
        /* enable status unit */
        sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
@@ -2795,38 +2777,6 @@ static int sky2_set_pauseparam(struct ne
        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)
 {
@@ -3014,10 +2964,6 @@ static struct ethtool_ops sky2_ethtool_o
        .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,
@@ -3080,7 +3026,7 @@ static __devinit struct net_device *sky2
        INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2);
        init_MUTEX(&sky2->phy_sema);
        sky2->tx_pending = TX_DEF_PENDING;
-       sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING;
+       sky2->rx_pending = RX_DEF_PENDING;
        sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
 
        hw->dev[port] = dev;
@@ -3243,8 +3189,7 @@ static int __devinit sky2_probe(struct p
                }
        }
 
-       err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
-                         DRV_NAME, hw);
+       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);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index dce955c..2a23f3a 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;
@@ -1865,7 +1863,6 @@ struct sky2_port {
        u8                   rx_pause;
        u8                   tx_pause;
        u8                   rx_csum;
-       u8                   wol;
 
        struct net_device_stats net_stats;
 
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index d7fb3ff..2d0cfbc 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1362,7 +1362,6 @@ static int de_open (struct net_device *d
 {
        struct de_private *de = dev->priv;
        int rc;
-       unsigned long flags;
 
        if (netif_msg_ifup(de))
                printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
@@ -1376,18 +1375,20 @@ static int de_open (struct net_device *d
                return rc;
        }
 
-       rc = de_init_hw(de);
-       if (rc) {
-               printk(KERN_ERR "%s: h/w init failure, err=%d\n",
-                      dev->name, rc);
-               goto err_out_free;
-       }
+       dw32(IntrMask, 0);
 
        rc = request_irq(dev->irq, de_interrupt, SA_SHIRQ, dev->name, dev);
        if (rc) {
                printk(KERN_ERR "%s: IRQ %d request failure, err=%d\n",
                       dev->name, dev->irq, rc);
-               goto err_out_hw;
+               goto err_out_free;
+       }
+
+       rc = de_init_hw(de);
+       if (rc) {
+               printk(KERN_ERR "%s: h/w init failure, err=%d\n",
+                      dev->name, rc);
+               goto err_out_free_irq;
        }
 
        netif_start_queue(dev);
@@ -1395,11 +1396,8 @@ static int de_open (struct net_device *d
 
        return 0;
 
-err_out_hw:
-       spin_lock_irqsave(&de->lock, flags);
-       de_stop_hw(de);
-       spin_unlock_irqrestore(&de->lock, flags);
-
+err_out_free_irq:
+       free_irq(dev->irq, dev);
 err_out_free:
        de_free_rings(de);
        return rc;
@@ -1455,6 +1453,8 @@ static void de_tx_timeout (struct net_de
        synchronize_irq(dev->irq);
        de_clean_rings(de);
 
+       de_init_rings(de);
+
        de_init_hw(de);
        
        netif_wake_queue(dev);
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to