aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/marvell/skge.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/marvell/skge.c')
-rw-r--r--drivers/net/ethernet/marvell/skge.c118
1 files changed, 62 insertions, 56 deletions
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index edb9bda55d5..e912b6887d4 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -931,17 +931,17 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base)
}
/* Allocate and setup a new buffer for receiving */
-static int skge_rx_setup(struct pci_dev *pdev,
- struct skge_element *e,
+static int skge_rx_setup(struct skge_port *skge, struct skge_element *e,
struct sk_buff *skb, unsigned int bufsize)
{
struct skge_rx_desc *rd = e->desc;
dma_addr_t map;
- map = pci_map_single(pdev, skb->data, bufsize,
+ map = pci_map_single(skge->hw->pdev, skb->data, bufsize,
PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, map))
- goto mapping_error;
+
+ if (pci_dma_mapping_error(skge->hw->pdev, map))
+ return -1;
rd->dma_lo = lower_32_bits(map);
rd->dma_hi = upper_32_bits(map);
@@ -957,12 +957,6 @@ static int skge_rx_setup(struct pci_dev *pdev,
dma_unmap_addr_set(e, mapaddr, map);
dma_unmap_len_set(e, maplen, bufsize);
return 0;
-
-mapping_error:
- if (net_ratelimit())
- dev_warn(&pdev->dev, "%s: rx mapping error\n",
- skb->dev->name);
- return -EIO;
}
/* Resume receiving using existing skb,
@@ -1024,11 +1018,10 @@ static int skge_rx_fill(struct net_device *dev)
return -ENOMEM;
skb_reserve(skb, NET_IP_ALIGN);
- if (skge_rx_setup(skge->hw->pdev, e, skb, skge->rx_buf_size)) {
- kfree_skb(skb);
- return -ENOMEM;
+ if (skge_rx_setup(skge, e, skb, skge->rx_buf_size) < 0) {
+ dev_kfree_skb(skb);
+ return -EIO;
}
-
} while ((e = e->next) != ring->start);
ring->to_clean = ring->start;
@@ -2558,7 +2551,7 @@ static int skge_up(struct net_device *dev)
BUG_ON(skge->dma & 7);
- if ((u64)skge->dma >> 32 != ((u64) skge->dma + skge->mem_size) >> 32) {
+ if (upper_32_bits(skge->dma) != upper_32_bits(skge->dma + skge->mem_size)) {
dev_err(&hw->pdev->dev, "pci_alloc_consistent region crosses 4G boundary\n");
err = -EINVAL;
goto free_pci_mem;
@@ -2836,25 +2829,23 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
return NETDEV_TX_OK;
mapping_unwind:
- /* unroll any pages that were already mapped. */
- if (e != skge->tx_ring.to_use) {
- struct skge_element *u;
-
- for (u = skge->tx_ring.to_use->next; u != e; u = u->next)
- pci_unmap_page(hw->pdev, dma_unmap_addr(u, mapaddr),
- dma_unmap_len(u, maplen),
- PCI_DMA_TODEVICE);
- e = skge->tx_ring.to_use;
- }
- /* undo the mapping for the skb header */
- pci_unmap_single(hw->pdev, dma_unmap_addr(e, mapaddr),
+ e = skge->tx_ring.to_use;
+ pci_unmap_single(hw->pdev,
+ dma_unmap_addr(e, mapaddr),
dma_unmap_len(e, maplen),
PCI_DMA_TODEVICE);
+ while (i-- > 0) {
+ e = e->next;
+ pci_unmap_page(hw->pdev,
+ dma_unmap_addr(e, mapaddr),
+ dma_unmap_len(e, maplen),
+ PCI_DMA_TODEVICE);
+ }
+
mapping_error:
- /* mapping error causes error message and packet to be discarded. */
if (net_ratelimit())
dev_warn(&hw->pdev->dev, "%s: tx mapping error\n", dev->name);
- dev_kfree_skb(skb);
+ dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}
@@ -3086,30 +3077,36 @@ static struct sk_buff *skge_rx_get(struct net_device *dev,
pci_dma_sync_single_for_cpu(skge->hw->pdev,
dma_unmap_addr(e, mapaddr),
- len, PCI_DMA_FROMDEVICE);
+ dma_unmap_len(e, maplen),
+ PCI_DMA_FROMDEVICE);
skb_copy_from_linear_data(e->skb, skb->data, len);
pci_dma_sync_single_for_device(skge->hw->pdev,
dma_unmap_addr(e, mapaddr),
- len, PCI_DMA_FROMDEVICE);
+ dma_unmap_len(e, maplen),
+ PCI_DMA_FROMDEVICE);
skge_rx_reuse(e, skge->rx_buf_size);
} else {
+ struct skge_element ee;
struct sk_buff *nskb;
nskb = netdev_alloc_skb_ip_align(dev, skge->rx_buf_size);
if (!nskb)
goto resubmit;
- if (unlikely(skge_rx_setup(skge->hw->pdev, e, nskb, skge->rx_buf_size))) {
+ ee = *e;
+
+ skb = ee.skb;
+ prefetch(skb->data);
+
+ if (skge_rx_setup(skge, e, nskb, skge->rx_buf_size) < 0) {
dev_kfree_skb(nskb);
goto resubmit;
}
pci_unmap_single(skge->hw->pdev,
- dma_unmap_addr(e, mapaddr),
- dma_unmap_len(e, maplen),
+ dma_unmap_addr(&ee, mapaddr),
+ dma_unmap_len(&ee, maplen),
PCI_DMA_FROMDEVICE);
- skb = e->skb;
- prefetch(skb->data);
}
skb_put(skb, len);
@@ -3175,7 +3172,7 @@ static void skge_tx_done(struct net_device *dev)
pkts_compl++;
bytes_compl += e->skb->len;
- dev_kfree_skb(e->skb);
+ dev_consume_skb_any(e->skb);
}
}
netdev_completed_queue(dev, pkts_compl, bytes_compl);
@@ -3234,7 +3231,7 @@ static int skge_poll(struct napi_struct *napi, int to_do)
if (work_done < to_do) {
unsigned long flags;
- napi_gro_flush(napi);
+ napi_gro_flush(napi, false);
spin_lock_irqsave(&hw->hw_lock, flags);
__napi_complete(napi);
hw->intr_mask |= napimask[skge->port];
@@ -3751,7 +3748,7 @@ static const struct file_operations skge_debug_fops = {
static int skge_device_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
- struct net_device *dev = ptr;
+ struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct skge_port *skge;
struct dentry *d;
@@ -3852,10 +3849,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
struct skge_port *skge;
struct net_device *dev = alloc_etherdev(sizeof(*skge));
- if (!dev) {
- dev_err(&hw->pdev->dev, "etherdev alloc failed\n");
+ if (!dev)
return NULL;
- }
SET_NETDEV_DEV(dev, &hw->pdev->dev);
dev->netdev_ops = &skge_netdev_ops;
@@ -3902,12 +3897,11 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
/* read the mac address */
memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
return dev;
}
-static void __devinit skge_show_addr(struct net_device *dev)
+static void skge_show_addr(struct net_device *dev)
{
const struct skge_port *skge = netdev_priv(dev);
@@ -3916,8 +3910,7 @@ static void __devinit skge_show_addr(struct net_device *dev)
static int only_32bit_dma;
-static int __devinit skge_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int skge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *dev, *dev1;
struct skge_hw *hw;
@@ -3965,10 +3958,9 @@ static int __devinit skge_probe(struct pci_dev *pdev,
/* space for skge@pci:0000:04:00.0 */
hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
+ strlen(pci_name(pdev)) + 1, GFP_KERNEL);
- if (!hw) {
- dev_err(&pdev->dev, "cannot allocate hardware struct\n");
+ if (!hw)
goto err_out_free_regions;
- }
+
sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
hw->pdev = pdev;
@@ -3992,8 +3984,10 @@ static int __devinit skge_probe(struct pci_dev *pdev,
skge_board_name(hw), hw->chip_rev);
dev = skge_devinit(hw, 0, using_dac);
- if (!dev)
+ if (!dev) {
+ err = -ENOMEM;
goto err_out_led_off;
+ }
/* Some motherboards are broken and has zero in ROM. */
if (!is_valid_ether_addr(dev->dev_addr))
@@ -4052,12 +4046,11 @@ err_out_free_regions:
pci_release_regions(pdev);
err_out_disable_pdev:
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
err_out:
return err;
}
-static void __devexit skge_remove(struct pci_dev *pdev)
+static void skge_remove(struct pci_dev *pdev)
{
struct skge_hw *hw = pci_get_drvdata(pdev);
struct net_device *dev0, *dev1;
@@ -4071,7 +4064,7 @@ static void __devexit skge_remove(struct pci_dev *pdev)
dev0 = hw->dev[0];
unregister_netdev(dev0);
- tasklet_disable(&hw->phy_task);
+ tasklet_kill(&hw->phy_task);
spin_lock_irq(&hw->hw_lock);
hw->intr_mask = 0;
@@ -4096,7 +4089,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
iounmap(hw->regs);
kfree(hw);
- pci_set_drvdata(pdev, NULL);
}
#ifdef CONFIG_PM_SLEEP
@@ -4187,7 +4179,7 @@ static struct pci_driver skge_driver = {
.name = DRV_NAME,
.id_table = skge_id_table,
.probe = skge_probe,
- .remove = __devexit_p(skge_remove),
+ .remove = skge_remove,
.shutdown = skge_shutdown,
.driver.pm = SKGE_PM_OPS,
};
@@ -4200,6 +4192,20 @@ static struct dmi_system_id skge_32bit_dma_boards[] = {
DMI_MATCH(DMI_BOARD_NAME, "nForce"),
},
},
+ {
+ .ident = "ASUS P5NSLI",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "P5NSLI")
+ },
+ },
+ {
+ .ident = "FUJITSU SIEMENS A8NE-FM",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "A8NE-FM")
+ },
+ },
{}
};