aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/spider_net.c
diff options
context:
space:
mode:
authorJens Osterkamp <osterkam@de.ibm.com>2005-09-06 22:30:54 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-06 22:35:29 -0400
commit543cec517dbc07c7c801ccacd02141d99f09f756 (patch)
tree58e45dbbf38c5a72fb851ea756c3a1799a9fa466 /drivers/net/spider_net.c
parentaaec0fab5f8809fe1509fdc204e769bb35ebe41a (diff)
[PATCH] net: update the spider_net driver
- Prevent PCI posting problems by using synchronous register access in critical places - Check return value from firmware device tree functions - fix device cleanup Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Cc: Jeff Garzik <jgarzik@pobox.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/spider_net.c')
-rw-r--r--drivers/net/spider_net.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index 692a0437fef7..6784e6e13685 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -109,6 +109,23 @@ spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value)
109} 109}
110 110
111/** 111/**
112 * spider_net_write_reg_sync - writes to an SMMIO register of a card
113 * @card: device structure
114 * @reg: register to write to
115 * @value: value to write into the specified SMMIO register
116 *
117 * Unlike spider_net_write_reg, this will also make sure the
118 * data arrives on the card by reading the reg again.
119 */
120static void
121spider_net_write_reg_sync(struct spider_net_card *card, u32 reg, u32 value)
122{
123 value = cpu_to_le32(value);
124 writel(value, card->regs + reg);
125 (void)readl(card->regs + reg);
126}
127
128/**
112 * spider_net_rx_irq_off - switch off rx irq on this spider card 129 * spider_net_rx_irq_off - switch off rx irq on this spider card
113 * @card: device structure 130 * @card: device structure
114 * 131 *
@@ -123,7 +140,7 @@ spider_net_rx_irq_off(struct spider_net_card *card)
123 spin_lock_irqsave(&card->intmask_lock, flags); 140 spin_lock_irqsave(&card->intmask_lock, flags);
124 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); 141 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
125 regvalue &= ~SPIDER_NET_RXINT; 142 regvalue &= ~SPIDER_NET_RXINT;
126 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); 143 spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
127 spin_unlock_irqrestore(&card->intmask_lock, flags); 144 spin_unlock_irqrestore(&card->intmask_lock, flags);
128} 145}
129 146
@@ -196,7 +213,7 @@ spider_net_rx_irq_on(struct spider_net_card *card)
196 spin_lock_irqsave(&card->intmask_lock, flags); 213 spin_lock_irqsave(&card->intmask_lock, flags);
197 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); 214 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
198 regvalue |= SPIDER_NET_RXINT; 215 regvalue |= SPIDER_NET_RXINT;
199 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); 216 spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
200 spin_unlock_irqrestore(&card->intmask_lock, flags); 217 spin_unlock_irqrestore(&card->intmask_lock, flags);
201} 218}
202 219
@@ -215,7 +232,7 @@ spider_net_tx_irq_off(struct spider_net_card *card)
215 spin_lock_irqsave(&card->intmask_lock, flags); 232 spin_lock_irqsave(&card->intmask_lock, flags);
216 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); 233 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
217 regvalue &= ~SPIDER_NET_TXINT; 234 regvalue &= ~SPIDER_NET_TXINT;
218 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); 235 spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
219 spin_unlock_irqrestore(&card->intmask_lock, flags); 236 spin_unlock_irqrestore(&card->intmask_lock, flags);
220} 237}
221 238
@@ -234,7 +251,7 @@ spider_net_tx_irq_on(struct spider_net_card *card)
234 spin_lock_irqsave(&card->intmask_lock, flags); 251 spin_lock_irqsave(&card->intmask_lock, flags);
235 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); 252 regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
236 regvalue |= SPIDER_NET_TXINT; 253 regvalue |= SPIDER_NET_TXINT;
237 spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); 254 spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
238 spin_unlock_irqrestore(&card->intmask_lock, flags); 255 spin_unlock_irqrestore(&card->intmask_lock, flags);
239} 256}
240 257
@@ -813,6 +830,9 @@ spider_net_stop(struct net_device *netdev)
813 spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); 830 spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
814 spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); 831 spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
815 832
833 /* free_irq(netdev->irq, netdev);*/
834 free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
835
816 spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, 836 spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
817 SPIDER_NET_DMA_TX_FEND_VALUE); 837 SPIDER_NET_DMA_TX_FEND_VALUE);
818 838
@@ -822,10 +842,6 @@ spider_net_stop(struct net_device *netdev)
822 /* release chains */ 842 /* release chains */
823 spider_net_release_tx_chain(card, 1); 843 spider_net_release_tx_chain(card, 1);
824 844
825 /* switch off card */
826 spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
827 SPIDER_NET_CKRCTRL_STOP_VALUE);
828
829 spider_net_free_chain(card, &card->tx_chain); 845 spider_net_free_chain(card, &card->tx_chain);
830 spider_net_free_chain(card, &card->rx_chain); 846 spider_net_free_chain(card, &card->rx_chain);
831 847
@@ -1745,6 +1761,10 @@ spider_net_open(struct net_device *netdev)
1745 1761
1746 spider_net_enable_card(card); 1762 spider_net_enable_card(card);
1747 1763
1764 netif_start_queue(netdev);
1765 netif_carrier_on(netdev);
1766 netif_poll_enable(netdev);
1767
1748 return 0; 1768 return 0;
1749 1769
1750register_int_failed: 1770register_int_failed:
@@ -2045,7 +2065,12 @@ spider_net_setup_netdev(struct spider_net_card *card)
2045 netdev->irq = card->pdev->irq; 2065 netdev->irq = card->pdev->irq;
2046 2066
2047 dn = pci_device_to_OF_node(card->pdev); 2067 dn = pci_device_to_OF_node(card->pdev);
2068 if (!dn)
2069 return -EIO;
2070
2048 mac = (u8 *)get_property(dn, "local-mac-address", NULL); 2071 mac = (u8 *)get_property(dn, "local-mac-address", NULL);
2072 if (!mac)
2073 return -EIO;
2049 memcpy(addr.sa_data, mac, ETH_ALEN); 2074 memcpy(addr.sa_data, mac, ETH_ALEN);
2050 2075
2051 result = spider_net_set_mac(netdev, &addr); 2076 result = spider_net_set_mac(netdev, &addr);
@@ -2243,10 +2268,15 @@ spider_net_remove(struct pci_dev *pdev)
2243 atomic_read(&card->tx_timeout_task_counter) == 0); 2268 atomic_read(&card->tx_timeout_task_counter) == 0);
2244 2269
2245 unregister_netdev(netdev); 2270 unregister_netdev(netdev);
2271
2272 /* switch off card */
2273 spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
2274 SPIDER_NET_CKRCTRL_STOP_VALUE);
2275 spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
2276 SPIDER_NET_CKRCTRL_RUN_VALUE);
2277
2246 spider_net_undo_pci_setup(card); 2278 spider_net_undo_pci_setup(card);
2247 free_netdev(netdev); 2279 free_netdev(netdev);
2248
2249 free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
2250} 2280}
2251 2281
2252static struct pci_driver spider_net_driver = { 2282static struct pci_driver spider_net_driver = {