Merge tag '8139cp-20060912-00' of git://electric-eye.fr.zoreil.com/home/romieu/linux-2.6 into tmp
This commit is contained in:
commit
cb930205c9
1 changed files with 50 additions and 62 deletions
|
@ -314,12 +314,6 @@ struct cp_desc {
|
||||||
u64 addr;
|
u64 addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ring_info {
|
|
||||||
struct sk_buff *skb;
|
|
||||||
dma_addr_t mapping;
|
|
||||||
u32 len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cp_dma_stats {
|
struct cp_dma_stats {
|
||||||
u64 tx_ok;
|
u64 tx_ok;
|
||||||
u64 rx_ok;
|
u64 rx_ok;
|
||||||
|
@ -353,23 +347,23 @@ struct cp_private {
|
||||||
struct net_device_stats net_stats;
|
struct net_device_stats net_stats;
|
||||||
struct cp_extra_stats cp_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 cp_desc *rx_ring;
|
||||||
struct ring_info rx_skb[CP_RX_RING_SIZE];
|
struct sk_buff *rx_skb[CP_RX_RING_SIZE];
|
||||||
unsigned rx_buf_sz;
|
|
||||||
|
|
||||||
unsigned tx_head ____cacheline_aligned;
|
unsigned tx_head ____cacheline_aligned;
|
||||||
unsigned tx_tail;
|
unsigned tx_tail;
|
||||||
|
|
||||||
struct cp_desc *tx_ring;
|
struct cp_desc *tx_ring;
|
||||||
struct ring_info tx_skb[CP_TX_RING_SIZE];
|
struct sk_buff *tx_skb[CP_TX_RING_SIZE];
|
||||||
dma_addr_t ring_dma;
|
|
||||||
|
unsigned rx_buf_sz;
|
||||||
|
unsigned wol_enabled : 1; /* Is Wake-on-LAN enabled? */
|
||||||
|
|
||||||
#if CP_VLAN_TAG_USED
|
#if CP_VLAN_TAG_USED
|
||||||
struct vlan_group *vlgrp;
|
struct vlan_group *vlgrp;
|
||||||
#endif
|
#endif
|
||||||
|
dma_addr_t ring_dma;
|
||||||
unsigned int wol_enabled : 1; /* Is Wake-on-LAN enabled? */
|
|
||||||
|
|
||||||
struct mii_if_info mii_if;
|
struct mii_if_info mii_if;
|
||||||
};
|
};
|
||||||
|
@ -407,10 +401,8 @@ static int cp_set_eeprom(struct net_device *dev,
|
||||||
struct ethtool_eeprom *eeprom, u8 *data);
|
struct ethtool_eeprom *eeprom, u8 *data);
|
||||||
|
|
||||||
static struct pci_device_id cp_pci_tbl[] = {
|
static struct pci_device_id cp_pci_tbl[] = {
|
||||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
|
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139), },
|
||||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
|
{ PCI_DEVICE(PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322), },
|
||||||
{ PCI_VENDOR_ID_TTTECH, PCI_DEVICE_ID_TTTECH_MC322,
|
|
||||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
|
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
|
MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
|
||||||
|
@ -542,7 +534,7 @@ static int cp_rx_poll (struct net_device *dev, int *budget)
|
||||||
struct cp_desc *desc;
|
struct cp_desc *desc;
|
||||||
unsigned buflen;
|
unsigned buflen;
|
||||||
|
|
||||||
skb = cp->rx_skb[rx_tail].skb;
|
skb = cp->rx_skb[rx_tail];
|
||||||
BUG_ON(!skb);
|
BUG_ON(!skb);
|
||||||
|
|
||||||
desc = &cp->rx_ring[rx_tail];
|
desc = &cp->rx_ring[rx_tail];
|
||||||
|
@ -551,7 +543,7 @@ static int cp_rx_poll (struct net_device *dev, int *budget)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
len = (status & 0x1fff) - 4;
|
len = (status & 0x1fff) - 4;
|
||||||
mapping = cp->rx_skb[rx_tail].mapping;
|
mapping = le64_to_cpu(desc->addr);
|
||||||
|
|
||||||
if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) {
|
if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) {
|
||||||
/* we don't support incoming fragmented frames.
|
/* we don't support incoming fragmented frames.
|
||||||
|
@ -572,7 +564,7 @@ static int cp_rx_poll (struct net_device *dev, int *budget)
|
||||||
|
|
||||||
if (netif_msg_rx_status(cp))
|
if (netif_msg_rx_status(cp))
|
||||||
printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n",
|
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;
|
buflen = cp->rx_buf_sz + RX_OFFSET;
|
||||||
new_skb = dev_alloc_skb (buflen);
|
new_skb = dev_alloc_skb (buflen);
|
||||||
|
@ -582,7 +574,7 @@ static int cp_rx_poll (struct net_device *dev, int *budget)
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_reserve(new_skb, RX_OFFSET);
|
skb_reserve(new_skb, RX_OFFSET);
|
||||||
new_skb->dev = cp->dev;
|
new_skb->dev = dev;
|
||||||
|
|
||||||
pci_unmap_single(cp->pdev, mapping,
|
pci_unmap_single(cp->pdev, mapping,
|
||||||
buflen, PCI_DMA_FROMDEVICE);
|
buflen, PCI_DMA_FROMDEVICE);
|
||||||
|
@ -595,11 +587,9 @@ static int cp_rx_poll (struct net_device *dev, int *budget)
|
||||||
|
|
||||||
skb_put(skb, len);
|
skb_put(skb, len);
|
||||||
|
|
||||||
mapping =
|
mapping = pci_map_single(cp->pdev, new_skb->data, buflen,
|
||||||
cp->rx_skb[rx_tail].mapping =
|
PCI_DMA_FROMDEVICE);
|
||||||
pci_map_single(cp->pdev, new_skb->data,
|
cp->rx_skb[rx_tail] = new_skb;
|
||||||
buflen, PCI_DMA_FROMDEVICE);
|
|
||||||
cp->rx_skb[rx_tail].skb = new_skb;
|
|
||||||
|
|
||||||
cp_rx_skb(cp, skb, desc);
|
cp_rx_skb(cp, skb, desc);
|
||||||
rx++;
|
rx++;
|
||||||
|
@ -717,19 +707,21 @@ static void cp_tx (struct cp_private *cp)
|
||||||
unsigned tx_tail = cp->tx_tail;
|
unsigned tx_tail = cp->tx_tail;
|
||||||
|
|
||||||
while (tx_tail != tx_head) {
|
while (tx_tail != tx_head) {
|
||||||
|
struct cp_desc *txd = cp->tx_ring + tx_tail;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
u32 status;
|
u32 status;
|
||||||
|
|
||||||
rmb();
|
rmb();
|
||||||
status = le32_to_cpu(cp->tx_ring[tx_tail].opts1);
|
status = le32_to_cpu(txd->opts1);
|
||||||
if (status & DescOwn)
|
if (status & DescOwn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
skb = cp->tx_skb[tx_tail].skb;
|
skb = cp->tx_skb[tx_tail];
|
||||||
BUG_ON(!skb);
|
BUG_ON(!skb);
|
||||||
|
|
||||||
pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping,
|
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 & LastFrag) {
|
||||||
if (status & (TxError | TxFIFOUnder)) {
|
if (status & (TxError | TxFIFOUnder)) {
|
||||||
|
@ -756,7 +748,7 @@ static void cp_tx (struct cp_private *cp)
|
||||||
dev_kfree_skb_irq(skb);
|
dev_kfree_skb_irq(skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
cp->tx_skb[tx_tail].skb = NULL;
|
cp->tx_skb[tx_tail] = NULL;
|
||||||
|
|
||||||
tx_tail = NEXT_TX(tx_tail);
|
tx_tail = NEXT_TX(tx_tail);
|
||||||
}
|
}
|
||||||
|
@ -826,9 +818,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
txd->opts1 = cpu_to_le32(flags);
|
txd->opts1 = cpu_to_le32(flags);
|
||||||
wmb();
|
wmb();
|
||||||
|
|
||||||
cp->tx_skb[entry].skb = skb;
|
cp->tx_skb[entry] = skb;
|
||||||
cp->tx_skb[entry].mapping = mapping;
|
|
||||||
cp->tx_skb[entry].len = len;
|
|
||||||
entry = NEXT_TX(entry);
|
entry = NEXT_TX(entry);
|
||||||
} else {
|
} else {
|
||||||
struct cp_desc *txd;
|
struct cp_desc *txd;
|
||||||
|
@ -844,9 +834,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
first_len = skb_headlen(skb);
|
first_len = skb_headlen(skb);
|
||||||
first_mapping = pci_map_single(cp->pdev, skb->data,
|
first_mapping = pci_map_single(cp->pdev, skb->data,
|
||||||
first_len, PCI_DMA_TODEVICE);
|
first_len, PCI_DMA_TODEVICE);
|
||||||
cp->tx_skb[entry].skb = skb;
|
cp->tx_skb[entry] = skb;
|
||||||
cp->tx_skb[entry].mapping = first_mapping;
|
|
||||||
cp->tx_skb[entry].len = first_len;
|
|
||||||
entry = NEXT_TX(entry);
|
entry = NEXT_TX(entry);
|
||||||
|
|
||||||
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
|
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
|
||||||
|
@ -887,9 +875,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
|
||||||
txd->opts1 = cpu_to_le32(ctrl);
|
txd->opts1 = cpu_to_le32(ctrl);
|
||||||
wmb();
|
wmb();
|
||||||
|
|
||||||
cp->tx_skb[entry].skb = skb;
|
cp->tx_skb[entry] = skb;
|
||||||
cp->tx_skb[entry].mapping = mapping;
|
|
||||||
cp->tx_skb[entry].len = len;
|
|
||||||
entry = NEXT_TX(entry);
|
entry = NEXT_TX(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,6 +1075,7 @@ static int cp_refill_rx (struct cp_private *cp)
|
||||||
|
|
||||||
for (i = 0; i < CP_RX_RING_SIZE; i++) {
|
for (i = 0; i < CP_RX_RING_SIZE; i++) {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
dma_addr_t mapping;
|
||||||
|
|
||||||
skb = dev_alloc_skb(cp->rx_buf_sz + RX_OFFSET);
|
skb = dev_alloc_skb(cp->rx_buf_sz + RX_OFFSET);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
|
@ -1097,12 +1084,12 @@ static int cp_refill_rx (struct cp_private *cp)
|
||||||
skb->dev = cp->dev;
|
skb->dev = cp->dev;
|
||||||
skb_reserve(skb, RX_OFFSET);
|
skb_reserve(skb, RX_OFFSET);
|
||||||
|
|
||||||
cp->rx_skb[i].mapping = pci_map_single(cp->pdev,
|
mapping = pci_map_single(cp->pdev, skb->data, cp->rx_buf_sz,
|
||||||
skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
PCI_DMA_FROMDEVICE);
|
||||||
cp->rx_skb[i].skb = skb;
|
cp->rx_skb[i] = skb;
|
||||||
|
|
||||||
cp->rx_ring[i].opts2 = 0;
|
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))
|
if (i == (CP_RX_RING_SIZE - 1))
|
||||||
cp->rx_ring[i].opts1 =
|
cp->rx_ring[i].opts1 =
|
||||||
cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
|
cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
|
||||||
|
@ -1150,23 +1137,27 @@ static int cp_alloc_rings (struct cp_private *cp)
|
||||||
|
|
||||||
static void cp_clean_rings (struct cp_private *cp)
|
static void cp_clean_rings (struct cp_private *cp)
|
||||||
{
|
{
|
||||||
|
struct cp_desc *desc;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
for (i = 0; i < CP_RX_RING_SIZE; i++) {
|
for (i = 0; i < CP_RX_RING_SIZE; i++) {
|
||||||
if (cp->rx_skb[i].skb) {
|
if (cp->rx_skb[i]) {
|
||||||
pci_unmap_single(cp->pdev, cp->rx_skb[i].mapping,
|
desc = cp->rx_ring + i;
|
||||||
|
pci_unmap_single(cp->pdev, le64_to_cpu(desc->addr),
|
||||||
cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
|
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++) {
|
for (i = 0; i < CP_TX_RING_SIZE; i++) {
|
||||||
if (cp->tx_skb[i].skb) {
|
if (cp->tx_skb[i]) {
|
||||||
struct sk_buff *skb = cp->tx_skb[i].skb;
|
struct sk_buff *skb = cp->tx_skb[i];
|
||||||
|
|
||||||
pci_unmap_single(cp->pdev, cp->tx_skb[i].mapping,
|
desc = cp->tx_ring + i;
|
||||||
cp->tx_skb[i].len, PCI_DMA_TODEVICE);
|
pci_unmap_single(cp->pdev, le64_to_cpu(desc->addr),
|
||||||
if (le32_to_cpu(cp->tx_ring[i].opts1) & LastFrag)
|
le32_to_cpu(desc->opts1) & 0xffff,
|
||||||
|
PCI_DMA_TODEVICE);
|
||||||
|
if (le32_to_cpu(desc->opts1) & LastFrag)
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
cp->net_stats.tx_dropped++;
|
cp->net_stats.tx_dropped++;
|
||||||
}
|
}
|
||||||
|
@ -1175,8 +1166,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->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->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->rx_skb, 0, sizeof(struct sk_buff *) * CP_RX_RING_SIZE);
|
||||||
memset(&cp->tx_skb, 0, sizeof(struct ring_info) * CP_TX_RING_SIZE);
|
memset(cp->tx_skb, 0, sizeof(struct sk_buff *) * CP_TX_RING_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cp_free_rings (struct cp_private *cp)
|
static void cp_free_rings (struct cp_private *cp)
|
||||||
|
@ -2008,7 +1999,6 @@ static void cp_remove_one (struct pci_dev *pdev)
|
||||||
struct net_device *dev = pci_get_drvdata(pdev);
|
struct net_device *dev = pci_get_drvdata(pdev);
|
||||||
struct cp_private *cp = netdev_priv(dev);
|
struct cp_private *cp = netdev_priv(dev);
|
||||||
|
|
||||||
BUG_ON(!dev);
|
|
||||||
unregister_netdev(dev);
|
unregister_netdev(dev);
|
||||||
iounmap(cp->regs);
|
iounmap(cp->regs);
|
||||||
if (cp->wol_enabled)
|
if (cp->wol_enabled)
|
||||||
|
@ -2023,14 +2013,12 @@ static void cp_remove_one (struct pci_dev *pdev)
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
static int cp_suspend (struct pci_dev *pdev, pm_message_t state)
|
static int cp_suspend (struct pci_dev *pdev, pm_message_t state)
|
||||||
{
|
{
|
||||||
struct net_device *dev;
|
struct net_device *dev = pci_get_drvdata(pdev);
|
||||||
struct cp_private *cp;
|
struct cp_private *cp = netdev_priv(dev);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
dev = pci_get_drvdata (pdev);
|
if (!netif_running(dev))
|
||||||
cp = netdev_priv(dev);
|
return 0;
|
||||||
|
|
||||||
if (!dev || !netif_running (dev)) return 0;
|
|
||||||
|
|
||||||
netif_device_detach (dev);
|
netif_device_detach (dev);
|
||||||
netif_stop_queue (dev);
|
netif_stop_queue (dev);
|
||||||
|
|
Loading…
Reference in a new issue