#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
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;
{ "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, },
msleep(1);
}
- if (i > 999)
+ if (i > 99)
printk(KERN_ERR PFX "PHY command failed !\n");
}
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;
-
- mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ skb = netdev_alloc_skb(tp->dev, rx_buf_sz);
+ if (likely(skb)) {
+ dma_addr_t mapping;
- 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,
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)
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;
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);
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
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);
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;
{
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)
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 ! */
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);
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;
}
synchronize_irq(dev->irq);
- if (!poll_locked) {
- netif_poll_disable(dev);
+ if (!poll_locked)
poll_locked++;
- }
synchronize_sched();
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);
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;
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;
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);
goto err_out_0;
}
- SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
tp = netdev_priv(dev);
/* 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));
}
/**
- * 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);
- if (!isa_bridge)
- isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0966, 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",
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, ®);
- 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)
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");
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;
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");