X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2F8139cp.c;h=6f93a765e56479ec9f0b598faf517468d3cd6ca0;hb=6b31a515e3401685cdab2eeb6692f1a0f53f72ca;hp=8f5d77923c7d0180d213c5ca23d59b6c1715c070;hpb=3598b57be449a2ee9178e5c511bdb1a8aaccba20;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 8f5d779..6f93a76 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -48,7 +48,7 @@ */ #define DRV_NAME "8139cp" -#define DRV_VERSION "1.2" +#define DRV_VERSION "1.3" #define DRV_RELDATE "Mar 22, 2004" @@ -314,11 +314,6 @@ struct cp_desc { u64 addr; }; -struct ring_info { - struct sk_buff *skb; - u32 len; -}; - struct cp_dma_stats { u64 tx_ok; u64 rx_ok; @@ -352,23 +347,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; }; @@ -406,10 +401,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); @@ -541,7 +534,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]; @@ -571,7 +564,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); @@ -581,7 +574,7 @@ rx_status_loop: } skb_reserve(new_skb, RX_OFFSET); - new_skb->dev = cp->dev; + new_skb->dev = dev; pci_unmap_single(cp->pdev, mapping, buflen, PCI_DMA_FROMDEVICE); @@ -596,7 +589,7 @@ rx_status_loop: mapping = pci_map_single(cp->pdev, new_skb->data, buflen, PCI_DMA_FROMDEVICE); - cp->rx_skb[rx_tail].skb = new_skb; + cp->rx_skb[rx_tail] = new_skb; cp_rx_skb(cp, skb, desc); rx++; @@ -624,13 +617,15 @@ rx_next: * this round of polling */ if (rx_work) { + unsigned long flags; + if (cpr16(IntrStatus) & cp_rx_intr_mask) goto rx_status_loop; - local_irq_disable(); + local_irq_save(flags); cpw16_f(IntrMask, cp_intr_mask); __netif_rx_complete(dev); - local_irq_enable(); + local_irq_restore(flags); return 0; /* done */ } @@ -638,8 +633,7 @@ rx_next: return 1; /* not done */ } -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; @@ -703,7 +697,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 @@ -723,11 +717,12 @@ static void cp_tx (struct cp_private *cp) 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, le64_to_cpu(txd->addr), - cp->tx_skb[tx_tail].len, PCI_DMA_TODEVICE); + le32_to_cpu(txd->opts1) & 0xffff, + PCI_DMA_TODEVICE); if (status & LastFrag) { if (status & (TxError | TxFIFOUnder)) { @@ -754,7 +749,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); } @@ -770,17 +765,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; @@ -811,7 +807,7 @@ 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) { + else if (skb->ip_summed == CHECKSUM_PARTIAL) { const struct iphdr *ip = skb->nh.iph; if (ip->protocol == IPPROTO_TCP) flags |= IPCS | TCPCS; @@ -824,8 +820,7 @@ 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].len = len; + cp->tx_skb[entry] = skb; entry = NEXT_TX(entry); } else { struct cp_desc *txd; @@ -841,8 +836,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev) first_len = skb_headlen(skb); first_mapping = pci_map_single(cp->pdev, skb->data, first_len, PCI_DMA_TODEVICE); - cp->tx_skb[entry].skb = skb; - 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++) { @@ -863,7 +857,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) @@ -883,8 +877,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].len = len; + cp->tx_skb[entry] = skb; entry = NEXT_TX(entry); } @@ -893,7 +886,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 | @@ -916,7 +909,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; @@ -937,8 +930,6 @@ static void __cp_set_rx_mode (struct net_device *dev) /* Note: do not reorder, GCC is clever about common statements. */ if (dev->flags & IFF_PROMISC) { /* Unconditionally log net taps. */ - printk (KERN_NOTICE "%s: Promiscuous mode enabled.\n", - dev->name); rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys; @@ -1097,7 +1088,7 @@ static int cp_refill_rx (struct cp_private *cp) mapping = pci_map_single(cp->pdev, skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); - cp->rx_skb[i].skb = skb; + cp->rx_skb[i] = skb; cp->rx_ring[i].opts2 = 0; cp->rx_ring[i].addr = cpu_to_le64(mapping); @@ -1152,21 +1143,22 @@ static void cp_clean_rings (struct cp_private *cp) unsigned i; for (i = 0; i < CP_RX_RING_SIZE; i++) { - if (cp->rx_skb[i].skb) { + if (cp->rx_skb[i]) { desc = cp->rx_ring + i; pci_unmap_single(cp->pdev, 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; + if (cp->tx_skb[i]) { + struct sk_buff *skb = cp->tx_skb[i]; desc = cp->tx_ring + i; pci_unmap_single(cp->pdev, le64_to_cpu(desc->addr), - cp->tx_skb[i].len, PCI_DMA_TODEVICE); + 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++; @@ -1176,8 +1168,8 @@ 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) @@ -1556,7 +1548,7 @@ static void cp_get_ethtool_stats (struct net_device *dev, pci_free_consistent(cp->pdev, 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, @@ -2009,7 +2001,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) @@ -2024,14 +2015,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); @@ -2097,7 +2086,7 @@ static int __init cp_init (void) #ifdef MODULE printk("%s", version); #endif - return pci_module_init (&cp_driver); + return pci_register_driver(&cp_driver); } static void __exit cp_exit (void)