THOL2 = 0x20000000,
THOL1 = 0x10000000,
THOL0 = 0x00000000,
+
+ WND = 0x00080000,
+ TABRT = 0x00040000,
+ FIFO = 0x00020000,
+ LINK = 0x00010000,
+ ColCountMask = 0x0000ffff,
/* RxDesc.status */
IPON = 0x20000000,
TCPON = 0x10000000,
unsigned int type;
u32 feature;
} mii_chip_table[] = {
+ { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 },
{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
{ "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 },
{ "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
sis190_rx_skb(skb);
- dev->last_rx = jiffies;
stats->rx_packets++;
stats->rx_bytes += pkt_size;
if ((status & BCAST) == MCAST)
memset(desc, 0x00, sizeof(*desc));
}
+static inline int sis190_tx_pkt_err(u32 status, struct net_device_stats *stats)
+{
+#define TxErrMask (WND | TABRT | FIFO | LINK)
+
+ if (!unlikely(status & TxErrMask))
+ return 0;
+
+ if (status & WND)
+ stats->tx_window_errors++;
+ if (status & TABRT)
+ stats->tx_aborted_errors++;
+ if (status & FIFO)
+ stats->tx_fifo_errors++;
+ if (status & LINK)
+ stats->tx_carrier_errors++;
+
+ stats->tx_errors++;
+
+ return -1;
+}
+
static void sis190_tx_interrupt(struct net_device *dev,
struct sis190_private *tp, void __iomem *ioaddr)
{
+ struct net_device_stats *stats = &dev->stats;
u32 pending, dirty_tx = tp->dirty_tx;
/*
* It would not be needed if queueing was allowed to be enabled
for (; pending; pending--, dirty_tx++) {
unsigned int entry = dirty_tx % NUM_TX_DESC;
struct TxDesc *txd = tp->TxDescRing + entry;
+ u32 status = le32_to_cpu(txd->status);
struct sk_buff *skb;
- if (le32_to_cpu(txd->status) & OWNbit)
+ if (status & OWNbit)
break;
skb = tp->Tx_skbuff[entry];
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += skb->len;
+ if (likely(sis190_tx_pkt_err(status, stats) == 0)) {
+ stats->tx_packets++;
+ stats->tx_bytes += skb->len;
+ stats->collisions += ((status & ColCountMask) - 1);
+ }
sis190_unmap_tx_skb(tp->pci_dev, skb, txd);
tp->Tx_skbuff[entry] = NULL;
SIS_PCI_COMMIT();
}
-static int __devinit sis190_get_mac_addr(struct pci_dev *pdev,
+static int __devinit sis190_get_mac_addr(struct pci_dev *pdev,
struct net_device *dev)
{
int rc;
generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL);
}
+static const struct net_device_ops sis190_netdev_ops = {
+ .ndo_open = sis190_open,
+ .ndo_stop = sis190_close,
+ .ndo_do_ioctl = sis190_ioctl,
+ .ndo_start_xmit = sis190_start_xmit,
+ .ndo_tx_timeout = sis190_tx_timeout,
+ .ndo_set_multicast_list = sis190_set_rx_mode,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = sis190_netpoll,
+#endif
+};
+
static int __devinit sis190_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
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");
INIT_WORK(&tp->phy_task, sis190_phy_task);
- dev->open = sis190_open;
- dev->stop = sis190_close;
- dev->do_ioctl = sis190_ioctl;
- dev->tx_timeout = sis190_tx_timeout;
- dev->watchdog_timeo = SIS190_TX_TIMEOUT;
- dev->hard_start_xmit = sis190_start_xmit;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- dev->poll_controller = sis190_netpoll;
-#endif
- dev->set_multicast_list = sis190_set_rx_mode;
+ dev->netdev_ops = &sis190_netdev_ops;
+
SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) 0xdead;
+ dev->watchdog_timeo = SIS190_TX_TIMEOUT;
spin_lock_init(&tp->lock);
if (rc < 0)
goto err_remove_mii;
- net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), "
- "%s\n",
+ net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), %pM\n",
pci_name(pdev), sis_chip_info[ent->driver_data].name,
- ioaddr, dev->irq, print_mac(mac, dev->dev_addr));
+ ioaddr, dev->irq, dev->dev_addr);
net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
(tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");