diff options
Diffstat (limited to 'drivers/net/ns83820.c')
-rw-r--r-- | drivers/net/ns83820.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 70429108c40d..0e76859c90a2 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c | |||
@@ -803,7 +803,7 @@ static int ns83820_setup_rx(struct net_device *ndev) | |||
803 | 803 | ||
804 | writel(dev->IMR_cache, dev->base + IMR); | 804 | writel(dev->IMR_cache, dev->base + IMR); |
805 | writel(1, dev->base + IER); | 805 | writel(1, dev->base + IER); |
806 | spin_unlock_irq(&dev->misc_lock); | 806 | spin_unlock(&dev->misc_lock); |
807 | 807 | ||
808 | kick_rx(ndev); | 808 | kick_rx(ndev); |
809 | 809 | ||
@@ -1012,8 +1012,6 @@ static void do_tx_done(struct net_device *ndev) | |||
1012 | struct ns83820 *dev = PRIV(ndev); | 1012 | struct ns83820 *dev = PRIV(ndev); |
1013 | u32 cmdsts, tx_done_idx, *desc; | 1013 | u32 cmdsts, tx_done_idx, *desc; |
1014 | 1014 | ||
1015 | spin_lock_irq(&dev->tx_lock); | ||
1016 | |||
1017 | dprintk("do_tx_done(%p)\n", ndev); | 1015 | dprintk("do_tx_done(%p)\n", ndev); |
1018 | tx_done_idx = dev->tx_done_idx; | 1016 | tx_done_idx = dev->tx_done_idx; |
1019 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); | 1017 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); |
@@ -1069,7 +1067,6 @@ static void do_tx_done(struct net_device *ndev) | |||
1069 | netif_start_queue(ndev); | 1067 | netif_start_queue(ndev); |
1070 | netif_wake_queue(ndev); | 1068 | netif_wake_queue(ndev); |
1071 | } | 1069 | } |
1072 | spin_unlock_irq(&dev->tx_lock); | ||
1073 | } | 1070 | } |
1074 | 1071 | ||
1075 | static void ns83820_cleanup_tx(struct ns83820 *dev) | 1072 | static void ns83820_cleanup_tx(struct ns83820 *dev) |
@@ -1281,11 +1278,13 @@ static struct ethtool_ops ops = { | |||
1281 | .get_link = ns83820_get_link | 1278 | .get_link = ns83820_get_link |
1282 | }; | 1279 | }; |
1283 | 1280 | ||
1281 | /* this function is called in irq context from the ISR */ | ||
1284 | static void ns83820_mib_isr(struct ns83820 *dev) | 1282 | static void ns83820_mib_isr(struct ns83820 *dev) |
1285 | { | 1283 | { |
1286 | spin_lock(&dev->misc_lock); | 1284 | unsigned long flags; |
1285 | spin_lock_irqsave(&dev->misc_lock, flags); | ||
1287 | ns83820_update_stats(dev); | 1286 | ns83820_update_stats(dev); |
1288 | spin_unlock(&dev->misc_lock); | 1287 | spin_unlock_irqrestore(&dev->misc_lock, flags); |
1289 | } | 1288 | } |
1290 | 1289 | ||
1291 | static void ns83820_do_isr(struct net_device *ndev, u32 isr); | 1290 | static void ns83820_do_isr(struct net_device *ndev, u32 isr); |
@@ -1307,6 +1306,8 @@ static irqreturn_t ns83820_irq(int foo, void *data, struct pt_regs *regs) | |||
1307 | static void ns83820_do_isr(struct net_device *ndev, u32 isr) | 1306 | static void ns83820_do_isr(struct net_device *ndev, u32 isr) |
1308 | { | 1307 | { |
1309 | struct ns83820 *dev = PRIV(ndev); | 1308 | struct ns83820 *dev = PRIV(ndev); |
1309 | unsigned long flags; | ||
1310 | |||
1310 | #ifdef DEBUG | 1311 | #ifdef DEBUG |
1311 | if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC)) | 1312 | if (isr & ~(ISR_PHY | ISR_RXDESC | ISR_RXEARLY | ISR_RXOK | ISR_RXERR | ISR_TXIDLE | ISR_TXOK | ISR_TXDESC)) |
1312 | Dprintk("odd isr? 0x%08x\n", isr); | 1313 | Dprintk("odd isr? 0x%08x\n", isr); |
@@ -1321,10 +1322,10 @@ static void ns83820_do_isr(struct net_device *ndev, u32 isr) | |||
1321 | if ((ISR_RXDESC | ISR_RXOK) & isr) { | 1322 | if ((ISR_RXDESC | ISR_RXOK) & isr) { |
1322 | prefetch(dev->rx_info.next_rx_desc); | 1323 | prefetch(dev->rx_info.next_rx_desc); |
1323 | 1324 | ||
1324 | spin_lock_irq(&dev->misc_lock); | 1325 | spin_lock_irqsave(&dev->misc_lock, flags); |
1325 | dev->IMR_cache &= ~(ISR_RXDESC | ISR_RXOK); | 1326 | dev->IMR_cache &= ~(ISR_RXDESC | ISR_RXOK); |
1326 | writel(dev->IMR_cache, dev->base + IMR); | 1327 | writel(dev->IMR_cache, dev->base + IMR); |
1327 | spin_unlock_irq(&dev->misc_lock); | 1328 | spin_unlock_irqrestore(&dev->misc_lock, flags); |
1328 | 1329 | ||
1329 | tasklet_schedule(&dev->rx_tasklet); | 1330 | tasklet_schedule(&dev->rx_tasklet); |
1330 | //rx_irq(ndev); | 1331 | //rx_irq(ndev); |
@@ -1370,16 +1371,18 @@ static void ns83820_do_isr(struct net_device *ndev, u32 isr) | |||
1370 | * work has accumulated | 1371 | * work has accumulated |
1371 | */ | 1372 | */ |
1372 | if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) { | 1373 | if ((ISR_TXDESC | ISR_TXIDLE | ISR_TXOK | ISR_TXERR) & isr) { |
1374 | spin_lock_irqsave(&dev->tx_lock, flags); | ||
1373 | do_tx_done(ndev); | 1375 | do_tx_done(ndev); |
1376 | spin_unlock_irqrestore(&dev->tx_lock, flags); | ||
1374 | 1377 | ||
1375 | /* Disable TxOk if there are no outstanding tx packets. | 1378 | /* Disable TxOk if there are no outstanding tx packets. |
1376 | */ | 1379 | */ |
1377 | if ((dev->tx_done_idx == dev->tx_free_idx) && | 1380 | if ((dev->tx_done_idx == dev->tx_free_idx) && |
1378 | (dev->IMR_cache & ISR_TXOK)) { | 1381 | (dev->IMR_cache & ISR_TXOK)) { |
1379 | spin_lock_irq(&dev->misc_lock); | 1382 | spin_lock_irqsave(&dev->misc_lock, flags); |
1380 | dev->IMR_cache &= ~ISR_TXOK; | 1383 | dev->IMR_cache &= ~ISR_TXOK; |
1381 | writel(dev->IMR_cache, dev->base + IMR); | 1384 | writel(dev->IMR_cache, dev->base + IMR); |
1382 | spin_unlock_irq(&dev->misc_lock); | 1385 | spin_unlock_irqrestore(&dev->misc_lock, flags); |
1383 | } | 1386 | } |
1384 | } | 1387 | } |
1385 | 1388 | ||
@@ -1390,10 +1393,10 @@ static void ns83820_do_isr(struct net_device *ndev, u32 isr) | |||
1390 | * nature are expected, we must enable TxOk. | 1393 | * nature are expected, we must enable TxOk. |
1391 | */ | 1394 | */ |
1392 | if ((ISR_TXIDLE & isr) && (dev->tx_done_idx != dev->tx_free_idx)) { | 1395 | if ((ISR_TXIDLE & isr) && (dev->tx_done_idx != dev->tx_free_idx)) { |
1393 | spin_lock_irq(&dev->misc_lock); | 1396 | spin_lock_irqsave(&dev->misc_lock, flags); |
1394 | dev->IMR_cache |= ISR_TXOK; | 1397 | dev->IMR_cache |= ISR_TXOK; |
1395 | writel(dev->IMR_cache, dev->base + IMR); | 1398 | writel(dev->IMR_cache, dev->base + IMR); |
1396 | spin_unlock_irq(&dev->misc_lock); | 1399 | spin_unlock_irqrestore(&dev->misc_lock, flags); |
1397 | } | 1400 | } |
1398 | 1401 | ||
1399 | /* MIB interrupt: one of the statistics counters is about to overflow */ | 1402 | /* MIB interrupt: one of the statistics counters is about to overflow */ |
@@ -1455,7 +1458,7 @@ static void ns83820_tx_timeout(struct net_device *ndev) | |||
1455 | u32 tx_done_idx, *desc; | 1458 | u32 tx_done_idx, *desc; |
1456 | unsigned long flags; | 1459 | unsigned long flags; |
1457 | 1460 | ||
1458 | local_irq_save(flags); | 1461 | spin_lock_irqsave(&dev->tx_lock, flags); |
1459 | 1462 | ||
1460 | tx_done_idx = dev->tx_done_idx; | 1463 | tx_done_idx = dev->tx_done_idx; |
1461 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); | 1464 | desc = dev->tx_descs + (tx_done_idx * DESC_SIZE); |
@@ -1482,7 +1485,7 @@ static void ns83820_tx_timeout(struct net_device *ndev) | |||
1482 | ndev->name, | 1485 | ndev->name, |
1483 | tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS])); | 1486 | tx_done_idx, dev->tx_free_idx, le32_to_cpu(desc[DESC_CMDSTS])); |
1484 | 1487 | ||
1485 | local_irq_restore(flags); | 1488 | spin_unlock_irqrestore(&dev->tx_lock, flags); |
1486 | } | 1489 | } |
1487 | 1490 | ||
1488 | static void ns83820_tx_watch(unsigned long data) | 1491 | static void ns83820_tx_watch(unsigned long data) |
@@ -1832,7 +1835,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ | |||
1832 | } else if (!pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { | 1835 | } else if (!pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { |
1833 | using_dac = 0; | 1836 | using_dac = 0; |
1834 | } else { | 1837 | } else { |
1835 | printk(KERN_WARNING "ns83820.c: pci_set_dma_mask failed!\n"); | 1838 | dev_warn(&pci_dev->dev, "pci_set_dma_mask failed!\n"); |
1836 | return -ENODEV; | 1839 | return -ENODEV; |
1837 | } | 1840 | } |
1838 | 1841 | ||
@@ -1855,7 +1858,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ | |||
1855 | 1858 | ||
1856 | err = pci_enable_device(pci_dev); | 1859 | err = pci_enable_device(pci_dev); |
1857 | if (err) { | 1860 | if (err) { |
1858 | printk(KERN_INFO "ns83820: pci_enable_dev failed: %d\n", err); | 1861 | dev_info(&pci_dev->dev, "pci_enable_dev failed: %d\n", err); |
1859 | goto out_free; | 1862 | goto out_free; |
1860 | } | 1863 | } |
1861 | 1864 | ||
@@ -1884,8 +1887,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ | |||
1884 | err = request_irq(pci_dev->irq, ns83820_irq, IRQF_SHARED, | 1887 | err = request_irq(pci_dev->irq, ns83820_irq, IRQF_SHARED, |
1885 | DRV_NAME, ndev); | 1888 | DRV_NAME, ndev); |
1886 | if (err) { | 1889 | if (err) { |
1887 | printk(KERN_INFO "ns83820: unable to register irq %d\n", | 1890 | dev_info(&pci_dev->dev, "unable to register irq %d, err %d\n", |
1888 | pci_dev->irq); | 1891 | pci_dev->irq, err); |
1889 | goto out_disable; | 1892 | goto out_disable; |
1890 | } | 1893 | } |
1891 | 1894 | ||
@@ -1899,7 +1902,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ | |||
1899 | rtnl_lock(); | 1902 | rtnl_lock(); |
1900 | err = dev_alloc_name(ndev, ndev->name); | 1903 | err = dev_alloc_name(ndev, ndev->name); |
1901 | if (err < 0) { | 1904 | if (err < 0) { |
1902 | printk(KERN_INFO "ns83820: unable to get netdev name: %d\n", err); | 1905 | dev_info(&pci_dev->dev, "unable to get netdev name: %d\n", err); |
1903 | goto out_free_irq; | 1906 | goto out_free_irq; |
1904 | } | 1907 | } |
1905 | 1908 | ||