]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/sis190.c
sis190: remove needless MII reset
[linux-2.6-omap-h63xx.git] / drivers / net / sis190.c
index ec2ad9f0efa25bcbc46509149920bdd8a6a4ec5a..20f48296efcb28f2f83356e1925b6de53e4e44e9 100644 (file)
 #define PHY_ID_ANY             0x1f
 #define MII_REG_ANY            0x1f
 
-#ifdef CONFIG_SIS190_NAPI
-#define NAPI_SUFFIX    "-NAPI"
-#else
-#define NAPI_SUFFIX    ""
-#endif
-
-#define DRV_VERSION            "1.2" NAPI_SUFFIX
+#define DRV_VERSION            "1.2"
 #define DRV_NAME               "sis190"
 #define SIS190_DRIVER_NAME     DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
 #define PFX DRV_NAME ": "
 
-#ifdef CONFIG_SIS190_NAPI
-#define sis190_rx_skb                  netif_receive_skb
-#define sis190_rx_quota(count, quota)  min(count, quota)
-#else
 #define sis190_rx_skb                  netif_rx
 #define sis190_rx_quota(count, quota)  count
-#endif
 
 #define MAC_ADDR_LEN           6
 
@@ -281,7 +270,6 @@ struct sis190_private {
        void __iomem *mmio_addr;
        struct pci_dev *pci_dev;
        struct net_device *dev;
-       struct net_device_stats stats;
        spinlock_t lock;
        u32 rx_buf_sz;
        u32 cur_rx;
@@ -338,7 +326,7 @@ static const struct {
        { "SiS 191 PCI Gigabit Ethernet adapter" },
 };
 
-static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
+static struct pci_device_id sis190_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
        { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
        { 0, },
@@ -384,7 +372,7 @@ static void __mdio_cmd(void __iomem *ioaddr, u32 ctl)
                msleep(1);
        }
 
-       if (i > 999)
+       if (i > 99)
                printk(KERN_ERR PFX "PHY command failed !\n");
 }
 
@@ -486,36 +474,29 @@ static inline void sis190_map_to_asic(struct RxDesc *desc, dma_addr_t mapping,
 static inline void sis190_make_unusable_by_asic(struct RxDesc *desc)
 {
        desc->PSize = 0x0;
-       desc->addr = 0xdeadbeef;
+       desc->addr = cpu_to_le32(0xdeadbeef);
        desc->size &= cpu_to_le32(RingEnd);
        wmb();
        desc->status = 0x0;
 }
 
-static int sis190_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
-                              struct RxDesc *desc, u32 rx_buf_sz)
+static struct sk_buff *sis190_alloc_rx_skb(struct sis190_private *tp,
+                                          struct RxDesc *desc)
 {
+       u32 rx_buf_sz = tp->rx_buf_sz;
        struct sk_buff *skb;
-       dma_addr_t mapping;
-       int ret = 0;
 
-       skb = dev_alloc_skb(rx_buf_sz);
-       if (!skb)
-               goto err_out;
-
-       *sk_buff = skb;
+       skb = netdev_alloc_skb(tp->dev, rx_buf_sz);
+       if (likely(skb)) {
+               dma_addr_t mapping;
 
-       mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
-                                PCI_DMA_FROMDEVICE);
-
-       sis190_map_to_asic(desc, mapping, rx_buf_sz);
-out:
-       return ret;
+               mapping = pci_map_single(tp->pci_dev, skb->data, tp->rx_buf_sz,
+                                        PCI_DMA_FROMDEVICE);
+               sis190_map_to_asic(desc, mapping, rx_buf_sz);
+       } else
+               sis190_make_unusable_by_asic(desc);
 
-err_out:
-       ret = -ENOMEM;
-       sis190_make_unusable_by_asic(desc);
-       goto out;
+       return skb;
 }
 
 static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev,
@@ -524,37 +505,41 @@ static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev,
        u32 cur;
 
        for (cur = start; cur < end; cur++) {
-               int ret, i = cur % NUM_RX_DESC;
+               unsigned int i = cur % NUM_RX_DESC;
 
                if (tp->Rx_skbuff[i])
                        continue;
 
-               ret = sis190_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
-                                         tp->RxDescRing + i, tp->rx_buf_sz);
-               if (ret < 0)
+               tp->Rx_skbuff[i] = sis190_alloc_rx_skb(tp, tp->RxDescRing + i);
+
+               if (!tp->Rx_skbuff[i])
                        break;
        }
        return cur - start;
 }
 
-static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
-                                    struct RxDesc *desc, int rx_buf_sz)
+static bool sis190_try_rx_copy(struct sis190_private *tp,
+                              struct sk_buff **sk_buff, int pkt_size,
+                              dma_addr_t addr)
 {
-       int ret = -1;
+       struct sk_buff *skb;
+       bool done = false;
 
-       if (pkt_size < rx_copybreak) {
-               struct sk_buff *skb;
+       if (pkt_size >= rx_copybreak)
+               goto out;
 
-               skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
-               if (skb) {
-                       skb_reserve(skb, NET_IP_ALIGN);
-                       skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
-                       *sk_buff = skb;
-                       sis190_give_to_asic(desc, rx_buf_sz);
-                       ret = 0;
-               }
-       }
-       return ret;
+       skb = netdev_alloc_skb(tp->dev, pkt_size + 2);
+       if (!skb)
+               goto out;
+
+       pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size,
+                                      PCI_DMA_FROMDEVICE);
+       skb_reserve(skb, 2);
+       skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
+       *sk_buff = skb;
+       done = true;
+out:
+       return done;
 }
 
 static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats)
@@ -580,7 +565,7 @@ static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats)
 static int sis190_rx_interrupt(struct net_device *dev,
                               struct sis190_private *tp, void __iomem *ioaddr)
 {
-       struct net_device_stats *stats = &tp->stats;
+       struct net_device_stats *stats = &dev->stats;
        u32 rx_left, cur_rx = tp->cur_rx;
        u32 delta, count;
 
@@ -592,7 +577,7 @@ static int sis190_rx_interrupt(struct net_device *dev,
                struct RxDesc *desc = tp->RxDescRing + entry;
                u32 status;
 
-               if (desc->status & OWNbit)
+               if (le32_to_cpu(desc->status) & OWNbit)
                        break;
 
                status = le32_to_cpu(desc->PSize);
@@ -604,9 +589,9 @@ static int sis190_rx_interrupt(struct net_device *dev,
                        sis190_give_to_asic(desc, tp->rx_buf_sz);
                else {
                        struct sk_buff *skb = tp->Rx_skbuff[entry];
+                       dma_addr_t addr = le32_to_cpu(desc->addr);
                        int pkt_size = (status & RxSizeMask) - 4;
-                       void (*pci_action)(struct pci_dev *, dma_addr_t,
-                               size_t, int) = pci_dma_sync_single_for_device;
+                       struct pci_dev *pdev = tp->pci_dev;
 
                        if (unlikely(pkt_size > tp->rx_buf_sz)) {
                                net_intr(tp, KERN_INFO
@@ -618,20 +603,18 @@ static int sis190_rx_interrupt(struct net_device *dev,
                                continue;
                        }
 
-                       pci_dma_sync_single_for_cpu(tp->pci_dev,
-                               le32_to_cpu(desc->addr), tp->rx_buf_sz,
-                               PCI_DMA_FROMDEVICE);
 
-                       if (sis190_try_rx_copy(&skb, pkt_size, desc,
-                                              tp->rx_buf_sz)) {
-                               pci_action = pci_unmap_single;
+                       if (sis190_try_rx_copy(tp, &skb, pkt_size, addr)) {
+                               pci_dma_sync_single_for_device(pdev, addr,
+                                       tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+                               sis190_give_to_asic(desc, tp->rx_buf_sz);
+                       } else {
+                               pci_unmap_single(pdev, addr, tp->rx_buf_sz,
+                                                PCI_DMA_FROMDEVICE);
                                tp->Rx_skbuff[entry] = NULL;
                                sis190_make_unusable_by_asic(desc);
                        }
 
-                       pci_action(tp->pci_dev, le32_to_cpu(desc->addr),
-                                  tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
-
                        skb_put(skb, pkt_size);
                        skb->protocol = eth_type_trans(skb, dev);
 
@@ -694,8 +677,8 @@ static void sis190_tx_interrupt(struct net_device *dev,
 
                skb = tp->Tx_skbuff[entry];
 
-               tp->stats.tx_packets++;
-               tp->stats.tx_bytes += skb->len;
+               dev->stats.tx_packets++;
+               dev->stats.tx_bytes += skb->len;
 
                sis190_unmap_tx_skb(tp->pci_dev, skb, txd);
                tp->Tx_skbuff[entry] = NULL;
@@ -859,10 +842,8 @@ static void sis190_soft_reset(void __iomem *ioaddr)
 {
        SIS_W32(IntrControl, 0x8000);
        SIS_PCI_COMMIT();
-       msleep(1);
        SIS_W32(IntrControl, 0x0);
        sis190_asic_down(ioaddr);
-       msleep(1);
 }
 
 static void sis190_hw_start(struct net_device *dev)
@@ -918,10 +899,9 @@ static void sis190_phy_task(struct work_struct *work)
                mod_timer(&tp->timer, jiffies + HZ/10);
        } else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
                     BMSR_ANEGCOMPLETE)) {
-               net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
-                        dev->name);
                netif_carrier_off(dev);
-               mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
+               net_link(tp, KERN_WARNING "%s: auto-negotiating...\n",
+                        dev->name);
                mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
        } else {
                /* Rejoice ! */
@@ -1053,8 +1033,6 @@ static int sis190_open(struct net_device *dev)
        if (rc < 0)
                goto err_free_rx_1;
 
-       INIT_WORK(&tp->phy_task, sis190_phy_task);
-
        sis190_request_timer(dev);
 
        rc = request_irq(dev->irq, sis190_interrupt, IRQF_SHARED, dev->name, dev);
@@ -1091,7 +1069,7 @@ static void sis190_tx_clear(struct sis190_private *tp)
                tp->Tx_skbuff[i] = NULL;
                dev_kfree_skb(skb);
 
-               tp->stats.tx_dropped++;
+               tp->dev->stats.tx_dropped++;
        }
        tp->cur_tx = tp->dirty_tx = 0;
 }
@@ -1115,10 +1093,8 @@ static void sis190_down(struct net_device *dev)
 
                synchronize_irq(dev->irq);
 
-               if (!poll_locked) {
-                       netif_poll_disable(dev);
+               if (!poll_locked)
                        poll_locked++;
-               }
 
                synchronize_sched();
 
@@ -1137,8 +1113,6 @@ static int sis190_close(struct net_device *dev)
 
        free_irq(dev->irq, dev);
 
-       netif_poll_enable(dev);
-
        pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma);
        pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma);
 
@@ -1158,7 +1132,7 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (unlikely(skb->len < ETH_ZLEN)) {
                if (skb_padto(skb, ETH_ZLEN)) {
-                       tp->stats.tx_dropped++;
+                       dev->stats.tx_dropped++;
                        goto out;
                }
                len = ETH_ZLEN;
@@ -1211,13 +1185,6 @@ out:
        return NETDEV_TX_OK;
 }
 
-static struct net_device_stats *sis190_get_stats(struct net_device *dev)
-{
-       struct sis190_private *tp = netdev_priv(dev);
-
-       return &tp->stats;
-}
-
 static void sis190_free_phy(struct list_head *first_phy)
 {
        struct sis190_phy *cur, *next;
@@ -1404,7 +1371,7 @@ out:
        return rc;
 }
 
-static void __devexit sis190_mii_remove(struct net_device *dev)
+static void sis190_mii_remove(struct net_device *dev)
 {
        struct sis190_private *tp = netdev_priv(dev);
 
@@ -1436,7 +1403,6 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)
                goto err_out_0;
        }
 
-       SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        tp = netdev_priv(dev);
@@ -1562,9 +1528,9 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
 
        /* Get MAC address from EEPROM */
        for (i = 0; i < MAC_ADDR_LEN / 2; i++) {
-               __le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
+               u16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i);
 
-               ((u16 *)dev->dev_addr)[i] = le16_to_cpu(w);
+               ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(w);
        }
 
        sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
@@ -1573,26 +1539,32 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
 }
 
 /**
- *     sis190_get_mac_addr_from_apc - Get MAC address for SiS965 model
+ *     sis190_get_mac_addr_from_apc - Get MAC address for SiS96x model
  *     @pdev: PCI device
  *     @dev:  network device to get address for
  *
- *     SiS965 model, use APC CMOS RAM to store MAC address.
+ *     SiS96x model, use APC CMOS RAM to store MAC address.
  *     APC CMOS RAM is accessed through ISA bridge.
  *     MAC address is read into @net_dev->dev_addr.
  */
 static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
                                                  struct net_device *dev)
 {
+       static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 };
        struct sis190_private *tp = netdev_priv(dev);
        struct pci_dev *isa_bridge;
        u8 reg, tmp8;
-       int i;
+       unsigned int i;
 
        net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n",
                  pci_name(pdev));
 
-       isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
+       for (i = 0; i < ARRAY_SIZE(ids); i++) {
+               isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, ids[i], NULL);
+               if (isa_bridge)
+                       break;
+       }
+
        if (!isa_bridge) {
                net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
                          pci_name(pdev));
@@ -1652,15 +1624,21 @@ static inline void sis190_init_rxfilter(struct net_device *dev)
        SIS_PCI_COMMIT();
 }
 
-static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
+static int __devinit sis190_get_mac_addr(struct pci_dev *pdev, 
+                                        struct net_device *dev)
 {
-       u8 from;
+       int rc;
+
+       rc = sis190_get_mac_addr_from_eeprom(pdev, dev);
+       if (rc < 0) {
+               u8 reg;
 
-       pci_read_config_byte(pdev, 0x73, &from);
+               pci_read_config_byte(pdev, 0x73, &reg);
 
-       return (from & 0x00000001) ?
-               sis190_get_mac_addr_from_apc(pdev, dev) :
-               sis190_get_mac_addr_from_eeprom(pdev, dev);
+               if (reg & 0x00000001)
+                       rc = sis190_get_mac_addr_from_apc(pdev, dev);
+       }
+       return rc;
 }
 
 static void sis190_set_speed_auto(struct net_device *dev)
@@ -1780,6 +1758,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
        struct net_device *dev;
        void __iomem *ioaddr;
        int rc;
+       DECLARE_MAC_BUF(mac);
 
        if (!printed_version) {
                net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n");
@@ -1808,7 +1787,6 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
        dev->open = sis190_open;
        dev->stop = sis190_close;
        dev->do_ioctl = sis190_ioctl;
-       dev->get_stats = sis190_get_stats;
        dev->tx_timeout = sis190_tx_timeout;
        dev->watchdog_timeo = SIS190_TX_TIMEOUT;
        dev->hard_start_xmit = sis190_start_xmit;
@@ -1831,12 +1809,9 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
                goto err_remove_mii;
 
        net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), "
-              "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
-              pci_name(pdev), sis_chip_info[ent->driver_data].name,
-              ioaddr, dev->irq,
-              dev->dev_addr[0], dev->dev_addr[1],
-              dev->dev_addr[2], dev->dev_addr[3],
-              dev->dev_addr[4], dev->dev_addr[5]);
+                 "%s\n",
+                 pci_name(pdev), sis_chip_info[ent->driver_data].name,
+                 ioaddr, dev->irq, print_mac(mac, dev->dev_addr));
 
        net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
                  (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");