diff options
| -rw-r--r-- | drivers/net/spider_net.c | 50 |
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 | */ | ||
| 120 | static void | ||
| 121 | spider_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 | ||
| 1750 | register_int_failed: | 1770 | register_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 | ||
| 2252 | static struct pci_driver spider_net_driver = { | 2282 | static struct pci_driver spider_net_driver = { |
