X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2F8139cp.c;h=a453eda834d52e3584755367169ada0ff22e4bc6;hb=3e18826c73735eee5fca92584137824d9a387008;hp=4cdb6b2efb9a1043a8c2251987dfc7ca2015a68d;hpb=4e83b7fad8d3fd55828baa4510885c7362e66a26;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 4cdb6b2..a453eda 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -26,7 +26,6 @@ TODO: * Test Tx checksumming thoroughly - * Implement dev->tx_timeout Low priority TODO: * Complete reset on PciErr @@ -79,7 +78,7 @@ #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) #define CP_VLAN_TAG_USED 1 #define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \ - do { (tx_desc)->opts2 = (vlan_tag_value); } while (0) + do { (tx_desc)->opts2 = cpu_to_le32(vlan_tag_value); } while (0) #else #define CP_VLAN_TAG_USED 0 #define CP_VLAN_TX_TAG(tx_desc,vlan_tag_value) \ @@ -107,11 +106,6 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered mu #define PFX DRV_NAME ": " -#ifndef TRUE -#define FALSE 0 -#define TRUE (!FALSE) -#endif - #define CP_DEF_MSG_ENABLE (NETIF_MSG_DRV | \ NETIF_MSG_PROBE | \ NETIF_MSG_LINK) @@ -309,31 +303,25 @@ static const unsigned int cp_rx_config = (RX_DMA_BURST << RxCfgDMAShift); struct cp_desc { - u32 opts1; - u32 opts2; - u64 addr; -}; - -struct ring_info { - struct sk_buff *skb; - dma_addr_t mapping; - u32 len; + __le32 opts1; + __le32 opts2; + __le64 addr; }; struct cp_dma_stats { - u64 tx_ok; - u64 rx_ok; - u64 tx_err; - u32 rx_err; - u16 rx_fifo; - u16 frame_align; - u32 tx_ok_1col; - u32 tx_ok_mcol; - u64 rx_ok_phys; - u64 rx_ok_bcast; - u32 rx_ok_mcast; - u16 tx_abort; - u16 tx_underrun; + __le64 tx_ok; + __le64 rx_ok; + __le64 tx_err; + __le32 rx_err; + __le16 rx_fifo; + __le16 frame_align; + __le32 tx_ok_1col; + __le32 tx_ok_mcol; + __le64 rx_ok_phys; + __le64 rx_ok_bcast; + __le32 rx_ok_mcast; + __le16 tx_abort; + __le16 tx_underrun; } __attribute__((packed)); struct cp_extra_stats { @@ -346,6 +334,8 @@ struct cp_private { spinlock_t lock; u32 msg_enable; + struct napi_struct napi; + struct pci_dev *pdev; u32 rx_config; u16 cpcmd; @@ -353,23 +343,23 @@ struct cp_private { struct net_device_stats net_stats; struct cp_extra_stats cp_stats; - unsigned rx_tail ____cacheline_aligned; + unsigned rx_head ____cacheline_aligned; + unsigned rx_tail; struct cp_desc *rx_ring; - struct ring_info rx_skb[CP_RX_RING_SIZE]; - unsigned rx_buf_sz; + struct sk_buff *rx_skb[CP_RX_RING_SIZE]; unsigned tx_head ____cacheline_aligned; unsigned tx_tail; - struct cp_desc *tx_ring; - struct ring_info tx_skb[CP_TX_RING_SIZE]; - dma_addr_t ring_dma; + struct sk_buff *tx_skb[CP_TX_RING_SIZE]; + + unsigned rx_buf_sz; + unsigned wol_enabled : 1; /* Is Wake-on-LAN enabled? */ #if CP_VLAN_TAG_USED struct vlan_group *vlgrp; #endif - - unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */ + dma_addr_t ring_dma; struct mii_if_info mii_if; }; @@ -407,10 +397,8 @@ static int cp_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *data); static struct pci_device_id cp_pci_tbl[] = { - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, - { PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139), }, + { PCI_DEVICE(PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322), }, { }, }; MODULE_DEVICE_TABLE(pci, cp_pci_tbl); @@ -443,21 +431,12 @@ static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) spin_lock_irqsave(&cp->lock, flags); cp->vlgrp = grp; - cp->cpcmd |= RxVlanOn; - cpw16(CpCmd, cp->cpcmd); - spin_unlock_irqrestore(&cp->lock, flags); -} - -static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) -{ - struct cp_private *cp = netdev_priv(dev); - unsigned long flags; + if (grp) + cp->cpcmd |= RxVlanOn; + else + cp->cpcmd &= ~RxVlanOn; - spin_lock_irqsave(&cp->lock, flags); - cp->cpcmd &= ~RxVlanOn; cpw16(CpCmd, cp->cpcmd); - if (cp->vlgrp) - cp->vlgrp->vlan_devices[vid] = NULL; spin_unlock_irqrestore(&cp->lock, flags); } #endif /* CP_VLAN_TAG_USED */ @@ -483,9 +462,9 @@ static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb, cp->dev->last_rx = jiffies; #if CP_VLAN_TAG_USED - if (cp->vlgrp && (desc->opts2 & RxVlanTagged)) { + if (cp->vlgrp && (desc->opts2 & cpu_to_le32(RxVlanTagged))) { vlan_hwaccel_receive_skb(skb, cp->vlgrp, - be16_to_cpu(desc->opts2 & 0xffff)); + swab16(le32_to_cpu(desc->opts2) & 0xffff)); } else #endif netif_receive_skb(skb); @@ -524,12 +503,12 @@ static inline unsigned int cp_rx_csum_ok (u32 status) return 0; } -static int cp_rx_poll (struct net_device *dev, int *budget) +static int cp_rx_poll(struct napi_struct *napi, int budget) { - struct cp_private *cp = netdev_priv(dev); - unsigned rx_tail = cp->rx_tail; - unsigned rx_work = dev->quota; - unsigned rx; + struct cp_private *cp = container_of(napi, struct cp_private, napi); + struct net_device *dev = cp->dev; + unsigned int rx_tail = cp->rx_tail; + int rx; rx_status_loop: rx = 0; @@ -542,7 +521,7 @@ rx_status_loop: struct cp_desc *desc; unsigned buflen; - skb = cp->rx_skb[rx_tail].skb; + skb = cp->rx_skb[rx_tail]; BUG_ON(!skb); desc = &cp->rx_ring[rx_tail]; @@ -551,7 +530,7 @@ rx_status_loop: break; len = (status & 0x1fff) - 4; - mapping = cp->rx_skb[rx_tail].mapping; + mapping = le64_to_cpu(desc->addr); if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) { /* we don't support incoming fragmented frames. @@ -572,7 +551,7 @@ rx_status_loop: if (netif_msg_rx_status(cp)) printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n", - cp->dev->name, rx_tail, status, len); + dev->name, rx_tail, status, len); buflen = cp->rx_buf_sz + RX_OFFSET; new_skb = dev_alloc_skb (buflen); @@ -582,9 +561,8 @@ rx_status_loop: } skb_reserve(new_skb, RX_OFFSET); - new_skb->dev = cp->dev; - pci_unmap_single(cp->pdev, mapping, + dma_unmap_single(&cp->pdev->dev, mapping, buflen, PCI_DMA_FROMDEVICE); /* Handle checksum offloading for incoming packets. */ @@ -595,11 +573,9 @@ rx_status_loop: skb_put(skb, len); - mapping = - cp->rx_skb[rx_tail].mapping = - pci_map_single(cp->pdev, new_skb->data, - buflen, PCI_DMA_FROMDEVICE); - cp->rx_skb[rx_tail].skb = new_skb; + mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen, + PCI_DMA_FROMDEVICE); + cp->rx_skb[rx_tail] = new_skb; cp_rx_skb(cp, skb, desc); rx++; @@ -614,35 +590,31 @@ rx_next: desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz); rx_tail = NEXT_RX(rx_tail); - if (!rx_work--) + if (rx >= budget) break; } cp->rx_tail = rx_tail; - dev->quota -= rx; - *budget -= rx; - /* if we did not reach work limit, then we're done with * this round of polling */ - if (rx_work) { + if (rx < budget) { + unsigned long flags; + if (cpr16(IntrStatus) & cp_rx_intr_mask) goto rx_status_loop; - local_irq_disable(); + spin_lock_irqsave(&cp->lock, flags); cpw16_f(IntrMask, cp_intr_mask); - __netif_rx_complete(dev); - local_irq_enable(); - - return 0; /* done */ + __netif_rx_complete(dev, napi); + spin_unlock_irqrestore(&cp->lock, flags); } - return 1; /* not done */ + return rx; } -static irqreturn_t -cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t cp_interrupt (int irq, void *dev_instance) { struct net_device *dev = dev_instance; struct cp_private *cp; @@ -672,15 +644,15 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) } if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) - if (netif_rx_schedule_prep(dev)) { + if (netif_rx_schedule_prep(dev, &cp->napi)) { cpw16_f(IntrMask, cp_norx_intr_mask); - __netif_rx_schedule(dev); + __netif_rx_schedule(dev, &cp->napi); } if (status & (TxOK | TxErr | TxEmpty | SWInt)) cp_tx(cp); if (status & LinkChg) - mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); + mii_check_media(&cp->mii_if, netif_msg_link(cp), false); spin_unlock(&cp->lock); @@ -706,7 +678,7 @@ cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs) static void cp_poll_controller(struct net_device *dev) { disable_irq(dev->irq); - cp_interrupt(dev->irq, dev, NULL); + cp_interrupt(dev->irq, dev); enable_irq(dev->irq); } #endif @@ -717,19 +689,21 @@ static void cp_tx (struct cp_private *cp) unsigned tx_tail = cp->tx_tail; while (tx_tail != tx_head) { + struct cp_desc *txd = cp->tx_ring + tx_tail; struct sk_buff *skb; u32 status; rmb(); - status = le32_to_cpu(cp->tx_ring[tx_tail].opts1); + status = le32_to_cpu(txd->opts1); if (status & DescOwn) break; - skb = cp->tx_skb[tx_tail].skb; + skb = cp->tx_skb[tx_tail]; BUG_ON(!skb); - pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping, - cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE); + dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr), + le32_to_cpu(txd->opts1) & 0xffff, + PCI_DMA_TODEVICE); if (status & LastFrag) { if (status & (TxError | TxFIFOUnder)) { @@ -756,7 +730,7 @@ static void cp_tx (struct cp_private *cp) dev_kfree_skb_irq(skb); } - cp->tx_skb[tx_tail].skb = NULL; + cp->tx_skb[tx_tail] = NULL; tx_tail = NEXT_TX(tx_tail); } @@ -772,17 +746,18 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) struct cp_private *cp = netdev_priv(dev); unsigned entry; u32 eor, flags; + unsigned long intr_flags; #if CP_VLAN_TAG_USED u32 vlan_tag = 0; #endif int mss = 0; - spin_lock_irq(&cp->lock); + spin_lock_irqsave(&cp->lock, intr_flags); /* This is a hard error, log it. */ if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) { netif_stop_queue(dev); - spin_unlock_irq(&cp->lock); + spin_unlock_irqrestore(&cp->lock, intr_flags); printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", dev->name); return 1; @@ -790,7 +765,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) #if CP_VLAN_TAG_USED if (cp->vlgrp && vlan_tx_tag_present(skb)) - vlan_tag = TxVlanTag | cpu_to_be16(vlan_tx_tag_get(skb)); + vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb)); #endif entry = cp->tx_head; @@ -804,7 +779,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) dma_addr_t mapping; len = skb->len; - mapping = pci_map_single(cp->pdev, skb->data, len, PCI_DMA_TODEVICE); + mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE); CP_VLAN_TX_TAG(txd, vlan_tag); txd->addr = cpu_to_le64(mapping); wmb(); @@ -813,8 +788,8 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) if (mss) flags |= LargeSend | ((mss & MSSMask) << MSSShift); - else if (skb->ip_summed == CHECKSUM_HW) { - const struct iphdr *ip = skb->nh.iph; + else if (skb->ip_summed == CHECKSUM_PARTIAL) { + const struct iphdr *ip = ip_hdr(skb); if (ip->protocol == IPPROTO_TCP) flags |= IPCS | TCPCS; else if (ip->protocol == IPPROTO_UDP) @@ -826,27 +801,23 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) txd->opts1 = cpu_to_le32(flags); wmb(); - cp->tx_skb[entry].skb = skb; - cp->tx_skb[entry].mapping = mapping; - cp->tx_skb[entry].len = len; + cp->tx_skb[entry] = skb; entry = NEXT_TX(entry); } else { struct cp_desc *txd; u32 first_len, first_eor; dma_addr_t first_mapping; int frag, first_entry = entry; - const struct iphdr *ip = skb->nh.iph; + const struct iphdr *ip = ip_hdr(skb); /* We must give this initial chunk to the device last. * Otherwise we could race with the device. */ first_eor = eor; first_len = skb_headlen(skb); - first_mapping = pci_map_single(cp->pdev, skb->data, + first_mapping = dma_map_single(&cp->pdev->dev, skb->data, first_len, PCI_DMA_TODEVICE); - cp->tx_skb[entry].skb = skb; - cp->tx_skb[entry].mapping = first_mapping; - cp->tx_skb[entry].len = first_len; + cp->tx_skb[entry] = skb; entry = NEXT_TX(entry); for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { @@ -856,7 +827,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) dma_addr_t mapping; len = this_frag->size; - mapping = pci_map_single(cp->pdev, + mapping = dma_map_single(&cp->pdev->dev, ((void *) page_address(this_frag->page) + this_frag->page_offset), len, PCI_DMA_TODEVICE); @@ -867,7 +838,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) if (mss) ctrl |= LargeSend | ((mss & MSSMask) << MSSShift); - else if (skb->ip_summed == CHECKSUM_HW) { + else if (skb->ip_summed == CHECKSUM_PARTIAL) { if (ip->protocol == IPPROTO_TCP) ctrl |= IPCS | TCPCS; else if (ip->protocol == IPPROTO_UDP) @@ -887,9 +858,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) txd->opts1 = cpu_to_le32(ctrl); wmb(); - cp->tx_skb[entry].skb = skb; - cp->tx_skb[entry].mapping = mapping; - cp->tx_skb[entry].len = len; + cp->tx_skb[entry] = skb; entry = NEXT_TX(entry); } @@ -898,7 +867,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) txd->addr = cpu_to_le64(first_mapping); wmb(); - if (skb->ip_summed == CHECKSUM_HW) { + if (skb->ip_summed == CHECKSUM_PARTIAL) { if (ip->protocol == IPPROTO_TCP) txd->opts1 = cpu_to_le32(first_eor | first_len | FirstFrag | DescOwn | @@ -921,7 +890,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1)) netif_stop_queue(dev); - spin_unlock_irq(&cp->lock); + spin_unlock_irqrestore(&cp->lock, intr_flags); cpw8(TxPoll, NormalTxPoll); dev->trans_start = jiffies; @@ -1049,8 +1018,8 @@ static void cp_init_hw (struct cp_private *cp) cpw8_f (Cfg9346, Cfg9346_Unlock); /* Restore our idea of the MAC address. */ - cpw32_f (MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0))); - cpw32_f (MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4))); + cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); + cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); cp_start_hw(cp); cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ @@ -1089,20 +1058,20 @@ static int cp_refill_rx (struct cp_private *cp) for (i = 0; i < CP_RX_RING_SIZE; i++) { struct sk_buff *skb; + dma_addr_t mapping; skb = dev_alloc_skb(cp->rx_buf_sz + RX_OFFSET); if (!skb) goto err_out; - skb->dev = cp->dev; skb_reserve(skb, RX_OFFSET); - cp->rx_skb[i].mapping = pci_map_single(cp->pdev, - skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); - cp->rx_skb[i].skb = skb; + mapping = dma_map_single(&cp->pdev->dev, skb->data, + cp->rx_buf_sz, PCI_DMA_FROMDEVICE); + cp->rx_skb[i] = skb; cp->rx_ring[i].opts2 = 0; - cp->rx_ring[i].addr = cpu_to_le64(cp->rx_skb[i].mapping); + cp->rx_ring[i].addr = cpu_to_le64(mapping); if (i == (CP_RX_RING_SIZE - 1)) cp->rx_ring[i].opts1 = cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz); @@ -1138,7 +1107,8 @@ static int cp_alloc_rings (struct cp_private *cp) { void *mem; - mem = pci_alloc_consistent(cp->pdev, CP_RING_BYTES, &cp->ring_dma); + mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES, + &cp->ring_dma, GFP_KERNEL); if (!mem) return -ENOMEM; @@ -1150,23 +1120,27 @@ static int cp_alloc_rings (struct cp_private *cp) static void cp_clean_rings (struct cp_private *cp) { + struct cp_desc *desc; unsigned i; for (i = 0; i < CP_RX_RING_SIZE; i++) { - if (cp->rx_skb[i].skb) { - pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping, + if (cp->rx_skb[i]) { + desc = cp->rx_ring + i; + dma_unmap_single(&cp->pdev->dev,le64_to_cpu(desc->addr), cp->rx_buf_sz, PCI_DMA_FROMDEVICE); - dev_kfree_skb(cp->rx_skb[i].skb); + dev_kfree_skb(cp->rx_skb[i]); } } for (i = 0; i < CP_TX_RING_SIZE; i++) { - if (cp->tx_skb[i].skb) { - struct sk_buff *skb = cp->tx_skb[i].skb; - - pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping, - cp->tx_skb[i].len, PCI_DMA_TODEVICE); - if (le32_to_cpu(cp->tx_ring[i].opts1) & LastFrag) + if (cp->tx_skb[i]) { + struct sk_buff *skb = cp->tx_skb[i]; + + desc = cp->tx_ring + i; + dma_unmap_single(&cp->pdev->dev,le64_to_cpu(desc->addr), + le32_to_cpu(desc->opts1) & 0xffff, + PCI_DMA_TODEVICE); + if (le32_to_cpu(desc->opts1) & LastFrag) dev_kfree_skb(skb); cp->net_stats.tx_dropped++; } @@ -1175,14 +1149,15 @@ static void cp_clean_rings (struct cp_private *cp) memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE); memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE); - memset(&cp->rx_skb, 0, sizeof(struct ring_info) * CP_RX_RING_SIZE); - memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE); + memset(cp->rx_skb, 0, sizeof(struct sk_buff *) * CP_RX_RING_SIZE); + memset(cp->tx_skb, 0, sizeof(struct sk_buff *) * CP_TX_RING_SIZE); } static void cp_free_rings (struct cp_private *cp) { cp_clean_rings(cp); - pci_free_consistent(cp->pdev, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); + dma_free_coherent(&cp->pdev->dev, CP_RING_BYTES, cp->rx_ring, + cp->ring_dma); cp->rx_ring = NULL; cp->tx_ring = NULL; } @@ -1199,6 +1174,8 @@ static int cp_open (struct net_device *dev) if (rc) return rc; + napi_enable(&cp->napi); + cp_init_hw(cp); rc = request_irq(dev->irq, cp_interrupt, IRQF_SHARED, dev->name, dev); @@ -1206,12 +1183,13 @@ static int cp_open (struct net_device *dev) goto err_out_hw; netif_carrier_off(dev); - mii_check_media(&cp->mii_if, netif_msg_link(cp), TRUE); + mii_check_media(&cp->mii_if, netif_msg_link(cp), true); netif_start_queue(dev); return 0; err_out_hw: + napi_disable(&cp->napi); cp_stop_hw(cp); cp_free_rings(cp); return rc; @@ -1222,6 +1200,8 @@ static int cp_close (struct net_device *dev) struct cp_private *cp = netdev_priv(dev); unsigned long flags; + napi_disable(&cp->napi); + if (netif_msg_ifdown(cp)) printk(KERN_DEBUG "%s: disabling interface\n", dev->name); @@ -1241,6 +1221,30 @@ static int cp_close (struct net_device *dev) return 0; } +static void cp_tx_timeout(struct net_device *dev) +{ + struct cp_private *cp = netdev_priv(dev); + unsigned long flags; + int rc; + + printk(KERN_WARNING "%s: Transmit timeout, status %2x %4x %4x %4x\n", + dev->name, cpr8(Cmd), cpr16(CpCmd), + cpr16(IntrStatus), cpr16(IntrMask)); + + spin_lock_irqsave(&cp->lock, flags); + + cp_stop_hw(cp); + cp_clean_rings(cp); + rc = cp_init_rings(cp); + cp_start_hw(cp); + + netif_wake_queue(dev); + + spin_unlock_irqrestore(&cp->lock, flags); + + return; +} + #ifdef BROKEN static int cp_change_mtu(struct net_device *dev, int new_mtu) { @@ -1379,9 +1383,14 @@ static int cp_get_regs_len(struct net_device *dev) return CP_REGS_SIZE; } -static int cp_get_stats_count (struct net_device *dev) +static int cp_get_sset_count (struct net_device *dev, int sset) { - return CP_NUM_STATS; + switch (sset) { + case ETH_SS_STATS: + return CP_NUM_STATS; + default: + return -EOPNOTSUPP; + } } static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) @@ -1517,7 +1526,8 @@ static void cp_get_ethtool_stats (struct net_device *dev, dma_addr_t dma; int i; - nic_stats = pci_alloc_consistent(cp->pdev, sizeof(*nic_stats), &dma); + nic_stats = dma_alloc_coherent(&cp->pdev->dev, sizeof(*nic_stats), + &dma, GFP_KERNEL); if (!nic_stats) return; @@ -1552,13 +1562,13 @@ static void cp_get_ethtool_stats (struct net_device *dev, tmp_stats[i++] = cp->cp_stats.rx_frags; BUG_ON(i != CP_NUM_STATS); - pci_free_consistent(cp->pdev, sizeof(*nic_stats), nic_stats, dma); + dma_free_coherent(&cp->pdev->dev, sizeof(*nic_stats), nic_stats, dma); } -static struct ethtool_ops cp_ethtool_ops = { +static const struct ethtool_ops cp_ethtool_ops = { .get_drvinfo = cp_get_drvinfo, .get_regs_len = cp_get_regs_len, - .get_stats_count = cp_get_stats_count, + .get_sset_count = cp_get_sset_count, .get_settings = cp_get_settings, .set_settings = cp_set_settings, .nway_reset = cp_nway_reset, @@ -1567,18 +1577,14 @@ static struct ethtool_ops cp_ethtool_ops = { .set_msglevel = cp_set_msglevel, .get_rx_csum = cp_get_rx_csum, .set_rx_csum = cp_set_rx_csum, - .get_tx_csum = ethtool_op_get_tx_csum, .set_tx_csum = ethtool_op_set_tx_csum, /* local! */ - .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, - .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, .get_regs = cp_get_regs, .get_wol = cp_get_wol, .set_wol = cp_set_wol, .get_strings = cp_get_strings, .get_ethtool_stats = cp_get_ethtool_stats, - .get_perm_addr = ethtool_op_get_perm_addr, .get_eeprom_len = cp_get_eeprom_len, .get_eeprom = cp_get_eeprom, .set_eeprom = cp_set_eeprom, @@ -1822,7 +1828,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) void __iomem *regs; resource_size_t pciaddr; unsigned int addr_len, i, pci_using_dac; - u8 pci_rev; + DECLARE_MAC_BUF(mac); #ifndef MODULE static int version_printed; @@ -1830,13 +1836,11 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) printk("%s", version); #endif - pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); - if (pdev->vendor == PCI_VENDOR_ID_REALTEK && - pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pci_rev < 0x20) { + pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) { dev_err(&pdev->dev, "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip\n", - pdev->vendor, pdev->device, pci_rev); + pdev->vendor, pdev->device, pdev->revision); dev_err(&pdev->dev, "Try the \"8139too\" driver instead.\n"); return -ENODEV; } @@ -1844,7 +1848,6 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev = alloc_etherdev(sizeof(struct cp_private)); if (!dev) return -ENOMEM; - SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); cp = netdev_priv(dev); @@ -1927,8 +1930,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) /* read MAC address from EEPROM */ addr_len = read_eeprom (regs, 0, 8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) - ((u16 *) (dev->dev_addr))[i] = - le16_to_cpu (read_eeprom (regs, i + 7, addr_len)); + ((__le16 *) (dev->dev_addr))[i] = + cpu_to_le16(read_eeprom (regs, i + 7, addr_len)); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); dev->open = cp_open; @@ -1937,24 +1940,20 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) dev->hard_start_xmit = cp_start_xmit; dev->get_stats = cp_get_stats; dev->do_ioctl = cp_ioctl; - dev->poll = cp_rx_poll; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = cp_poll_controller; #endif - dev->weight = 16; /* arbitrary? from NAPI_HOWTO.txt. */ + netif_napi_add(dev, &cp->napi, cp_rx_poll, 16); #ifdef BROKEN dev->change_mtu = cp_change_mtu; #endif dev->ethtool_ops = &cp_ethtool_ops; -#if 0 dev->tx_timeout = cp_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; -#endif #if CP_VLAN_TAG_USED dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; dev->vlan_rx_register = cp_vlan_rx_register; - dev->vlan_rx_kill_vid = cp_vlan_rx_kill_vid; #endif if (pci_using_dac) @@ -1971,13 +1970,10 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_iomap; printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, " - "%02x:%02x:%02x:%02x:%02x:%02x, " - "IRQ %d\n", + "%s, IRQ %d\n", dev->name, dev->base_addr, - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], + print_mac(mac, dev->dev_addr), dev->irq); pci_set_drvdata(pdev, dev); @@ -2008,7 +2004,6 @@ static void cp_remove_one (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); struct cp_private *cp = netdev_priv(dev); - BUG_ON(!dev); unregister_netdev(dev); iounmap(cp->regs); if (cp->wol_enabled) @@ -2023,14 +2018,12 @@ static void cp_remove_one (struct pci_dev *pdev) #ifdef CONFIG_PM static int cp_suspend (struct pci_dev *pdev, pm_message_t state) { - struct net_device *dev; - struct cp_private *cp; + struct net_device *dev = pci_get_drvdata(pdev); + struct cp_private *cp = netdev_priv(dev); unsigned long flags; - dev = pci_get_drvdata (pdev); - cp = netdev_priv(dev); - - if (!dev || !netif_running (dev)) return 0; + if (!netif_running(dev)) + return 0; netif_device_detach (dev); netif_stop_queue (dev); @@ -2072,7 +2065,7 @@ static int cp_resume (struct pci_dev *pdev) spin_lock_irqsave (&cp->lock, flags); - mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); + mii_check_media(&cp->mii_if, netif_msg_link(cp), false); spin_unlock_irqrestore (&cp->lock, flags);