diff options
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r-- | drivers/net/gianfar.c | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 9831b3f408aa..bd42502b85cf 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -93,7 +93,7 @@ | |||
93 | #include <linux/of.h> | 93 | #include <linux/of.h> |
94 | 94 | ||
95 | #include "gianfar.h" | 95 | #include "gianfar.h" |
96 | #include "gianfar_mii.h" | 96 | #include "fsl_pq_mdio.h" |
97 | 97 | ||
98 | #define TX_TIMEOUT (1*HZ) | 98 | #define TX_TIMEOUT (1*HZ) |
99 | #undef BRIEF_GFAR_ERRORS | 99 | #undef BRIEF_GFAR_ERRORS |
@@ -141,8 +141,6 @@ void gfar_start(struct net_device *dev); | |||
141 | static void gfar_clear_exact_match(struct net_device *dev); | 141 | static void gfar_clear_exact_match(struct net_device *dev); |
142 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); | 142 | static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr); |
143 | 143 | ||
144 | extern const struct ethtool_ops gfar_ethtool_ops; | ||
145 | |||
146 | MODULE_AUTHOR("Freescale Semiconductor, Inc"); | 144 | MODULE_AUTHOR("Freescale Semiconductor, Inc"); |
147 | MODULE_DESCRIPTION("Gianfar Ethernet Driver"); | 145 | MODULE_DESCRIPTION("Gianfar Ethernet Driver"); |
148 | MODULE_LICENSE("GPL"); | 146 | MODULE_LICENSE("GPL"); |
@@ -166,6 +164,9 @@ static int gfar_of_init(struct net_device *dev) | |||
166 | struct gfar_private *priv = netdev_priv(dev); | 164 | struct gfar_private *priv = netdev_priv(dev); |
167 | struct device_node *np = priv->node; | 165 | struct device_node *np = priv->node; |
168 | char bus_name[MII_BUS_ID_SIZE]; | 166 | char bus_name[MII_BUS_ID_SIZE]; |
167 | const u32 *stash; | ||
168 | const u32 *stash_len; | ||
169 | const u32 *stash_idx; | ||
169 | 170 | ||
170 | if (!np || !of_device_is_available(np)) | 171 | if (!np || !of_device_is_available(np)) |
171 | return -ENODEV; | 172 | return -ENODEV; |
@@ -195,6 +196,26 @@ static int gfar_of_init(struct net_device *dev) | |||
195 | } | 196 | } |
196 | } | 197 | } |
197 | 198 | ||
199 | stash = of_get_property(np, "bd-stash", NULL); | ||
200 | |||
201 | if(stash) { | ||
202 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_BD_STASHING; | ||
203 | priv->bd_stash_en = 1; | ||
204 | } | ||
205 | |||
206 | stash_len = of_get_property(np, "rx-stash-len", NULL); | ||
207 | |||
208 | if (stash_len) | ||
209 | priv->rx_stash_size = *stash_len; | ||
210 | |||
211 | stash_idx = of_get_property(np, "rx-stash-idx", NULL); | ||
212 | |||
213 | if (stash_idx) | ||
214 | priv->rx_stash_index = *stash_idx; | ||
215 | |||
216 | if (stash_len || stash_idx) | ||
217 | priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING; | ||
218 | |||
198 | mac_addr = of_get_mac_address(np); | 219 | mac_addr = of_get_mac_address(np); |
199 | if (mac_addr) | 220 | if (mac_addr) |
200 | memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN); | 221 | memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN); |
@@ -255,7 +276,7 @@ static int gfar_of_init(struct net_device *dev) | |||
255 | of_node_put(phy); | 276 | of_node_put(phy); |
256 | of_node_put(mdio); | 277 | of_node_put(mdio); |
257 | 278 | ||
258 | gfar_mdio_bus_name(bus_name, mdio); | 279 | fsl_pq_mdio_bus_name(bus_name, mdio); |
259 | snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x", | 280 | snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x", |
260 | bus_name, *id); | 281 | bus_name, *id); |
261 | } | 282 | } |
@@ -425,7 +446,7 @@ static int gfar_probe(struct of_device *ofdev, | |||
425 | priv->hash_width = 8; | 446 | priv->hash_width = 8; |
426 | 447 | ||
427 | priv->hash_regs[0] = &priv->regs->gaddr0; | 448 | priv->hash_regs[0] = &priv->regs->gaddr0; |
428 | priv->hash_regs[1] = &priv->regs->gaddr1; | 449 | priv->hash_regs[1] = &priv->regs->gaddr1; |
429 | priv->hash_regs[2] = &priv->regs->gaddr2; | 450 | priv->hash_regs[2] = &priv->regs->gaddr2; |
430 | priv->hash_regs[3] = &priv->regs->gaddr3; | 451 | priv->hash_regs[3] = &priv->regs->gaddr3; |
431 | priv->hash_regs[4] = &priv->regs->gaddr4; | 452 | priv->hash_regs[4] = &priv->regs->gaddr4; |
@@ -466,6 +487,9 @@ static int gfar_probe(struct of_device *ofdev, | |||
466 | goto register_fail; | 487 | goto register_fail; |
467 | } | 488 | } |
468 | 489 | ||
490 | device_init_wakeup(&dev->dev, | ||
491 | priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); | ||
492 | |||
469 | /* fill out IRQ number and name fields */ | 493 | /* fill out IRQ number and name fields */ |
470 | len_devname = strlen(dev->name); | 494 | len_devname = strlen(dev->name); |
471 | strncpy(&priv->int_name_tx[0], dev->name, len_devname); | 495 | strncpy(&priv->int_name_tx[0], dev->name, len_devname); |
@@ -838,7 +862,7 @@ void stop_gfar(struct net_device *dev) | |||
838 | free_irq(priv->interruptTransmit, dev); | 862 | free_irq(priv->interruptTransmit, dev); |
839 | free_irq(priv->interruptReceive, dev); | 863 | free_irq(priv->interruptReceive, dev); |
840 | } else { | 864 | } else { |
841 | free_irq(priv->interruptTransmit, dev); | 865 | free_irq(priv->interruptTransmit, dev); |
842 | } | 866 | } |
843 | 867 | ||
844 | free_skb_resources(priv); | 868 | free_skb_resources(priv); |
@@ -1183,6 +1207,8 @@ static int gfar_enet_open(struct net_device *dev) | |||
1183 | 1207 | ||
1184 | napi_enable(&priv->napi); | 1208 | napi_enable(&priv->napi); |
1185 | 1209 | ||
1210 | skb_queue_head_init(&priv->rx_recycle); | ||
1211 | |||
1186 | /* Initialize a bunch of registers */ | 1212 | /* Initialize a bunch of registers */ |
1187 | init_registers(dev); | 1213 | init_registers(dev); |
1188 | 1214 | ||
@@ -1203,6 +1229,8 @@ static int gfar_enet_open(struct net_device *dev) | |||
1203 | 1229 | ||
1204 | netif_start_queue(dev); | 1230 | netif_start_queue(dev); |
1205 | 1231 | ||
1232 | device_set_wakeup_enable(&dev->dev, priv->wol_en); | ||
1233 | |||
1206 | return err; | 1234 | return err; |
1207 | } | 1235 | } |
1208 | 1236 | ||
@@ -1399,6 +1427,7 @@ static int gfar_close(struct net_device *dev) | |||
1399 | 1427 | ||
1400 | napi_disable(&priv->napi); | 1428 | napi_disable(&priv->napi); |
1401 | 1429 | ||
1430 | skb_queue_purge(&priv->rx_recycle); | ||
1402 | cancel_work_sync(&priv->reset_task); | 1431 | cancel_work_sync(&priv->reset_task); |
1403 | stop_gfar(dev); | 1432 | stop_gfar(dev); |
1404 | 1433 | ||
@@ -1595,7 +1624,17 @@ static int gfar_clean_tx_ring(struct net_device *dev) | |||
1595 | bdp = next_txbd(bdp, base, tx_ring_size); | 1624 | bdp = next_txbd(bdp, base, tx_ring_size); |
1596 | } | 1625 | } |
1597 | 1626 | ||
1598 | dev_kfree_skb_any(skb); | 1627 | /* |
1628 | * If there's room in the queue (limit it to rx_buffer_size) | ||
1629 | * we add this skb back into the pool, if it's the right size | ||
1630 | */ | ||
1631 | if (skb_queue_len(&priv->rx_recycle) < priv->rx_ring_size && | ||
1632 | skb_recycle_check(skb, priv->rx_buffer_size + | ||
1633 | RXBUF_ALIGNMENT)) | ||
1634 | __skb_queue_head(&priv->rx_recycle, skb); | ||
1635 | else | ||
1636 | dev_kfree_skb_any(skb); | ||
1637 | |||
1599 | priv->tx_skbuff[skb_dirtytx] = NULL; | 1638 | priv->tx_skbuff[skb_dirtytx] = NULL; |
1600 | 1639 | ||
1601 | skb_dirtytx = (skb_dirtytx + 1) & | 1640 | skb_dirtytx = (skb_dirtytx + 1) & |
@@ -1626,9 +1665,9 @@ static void gfar_schedule_cleanup(struct net_device *dev) | |||
1626 | spin_lock_irqsave(&priv->txlock, flags); | 1665 | spin_lock_irqsave(&priv->txlock, flags); |
1627 | spin_lock(&priv->rxlock); | 1666 | spin_lock(&priv->rxlock); |
1628 | 1667 | ||
1629 | if (netif_rx_schedule_prep(&priv->napi)) { | 1668 | if (napi_schedule_prep(&priv->napi)) { |
1630 | gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED); | 1669 | gfar_write(&priv->regs->imask, IMASK_RTX_DISABLED); |
1631 | __netif_rx_schedule(&priv->napi); | 1670 | __napi_schedule(&priv->napi); |
1632 | } else { | 1671 | } else { |
1633 | /* | 1672 | /* |
1634 | * Clear IEVENT, so interrupts aren't called again | 1673 | * Clear IEVENT, so interrupts aren't called again |
@@ -1674,8 +1713,10 @@ struct sk_buff * gfar_new_skb(struct net_device *dev) | |||
1674 | struct gfar_private *priv = netdev_priv(dev); | 1713 | struct gfar_private *priv = netdev_priv(dev); |
1675 | struct sk_buff *skb = NULL; | 1714 | struct sk_buff *skb = NULL; |
1676 | 1715 | ||
1677 | /* We have to allocate the skb, so keep trying till we succeed */ | 1716 | skb = __skb_dequeue(&priv->rx_recycle); |
1678 | skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT); | 1717 | if (!skb) |
1718 | skb = netdev_alloc_skb(dev, | ||
1719 | priv->rx_buffer_size + RXBUF_ALIGNMENT); | ||
1679 | 1720 | ||
1680 | if (!skb) | 1721 | if (!skb) |
1681 | return NULL; | 1722 | return NULL; |
@@ -1823,7 +1864,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) | |||
1823 | if (unlikely(!newskb)) | 1864 | if (unlikely(!newskb)) |
1824 | newskb = skb; | 1865 | newskb = skb; |
1825 | else if (skb) | 1866 | else if (skb) |
1826 | dev_kfree_skb_any(skb); | 1867 | __skb_queue_head(&priv->rx_recycle, skb); |
1827 | } else { | 1868 | } else { |
1828 | /* Increment the number of packets */ | 1869 | /* Increment the number of packets */ |
1829 | dev->stats.rx_packets++; | 1870 | dev->stats.rx_packets++; |
@@ -1835,6 +1876,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) | |||
1835 | skb_put(skb, pkt_len); | 1876 | skb_put(skb, pkt_len); |
1836 | dev->stats.rx_bytes += pkt_len; | 1877 | dev->stats.rx_bytes += pkt_len; |
1837 | 1878 | ||
1879 | if (in_irq() || irqs_disabled()) | ||
1880 | printk("Interrupt problem!\n"); | ||
1838 | gfar_process_frame(dev, skb, amount_pull); | 1881 | gfar_process_frame(dev, skb, amount_pull); |
1839 | 1882 | ||
1840 | } else { | 1883 | } else { |
@@ -1891,7 +1934,7 @@ static int gfar_poll(struct napi_struct *napi, int budget) | |||
1891 | return budget; | 1934 | return budget; |
1892 | 1935 | ||
1893 | if (rx_cleaned < budget) { | 1936 | if (rx_cleaned < budget) { |
1894 | netif_rx_complete(napi); | 1937 | napi_complete(napi); |
1895 | 1938 | ||
1896 | /* Clear the halt bit in RSTAT */ | 1939 | /* Clear the halt bit in RSTAT */ |
1897 | gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT); | 1940 | gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT); |
@@ -2308,23 +2351,12 @@ static struct of_platform_driver gfar_driver = { | |||
2308 | 2351 | ||
2309 | static int __init gfar_init(void) | 2352 | static int __init gfar_init(void) |
2310 | { | 2353 | { |
2311 | int err = gfar_mdio_init(); | 2354 | return of_register_platform_driver(&gfar_driver); |
2312 | |||
2313 | if (err) | ||
2314 | return err; | ||
2315 | |||
2316 | err = of_register_platform_driver(&gfar_driver); | ||
2317 | |||
2318 | if (err) | ||
2319 | gfar_mdio_exit(); | ||
2320 | |||
2321 | return err; | ||
2322 | } | 2355 | } |
2323 | 2356 | ||
2324 | static void __exit gfar_exit(void) | 2357 | static void __exit gfar_exit(void) |
2325 | { | 2358 | { |
2326 | of_unregister_platform_driver(&gfar_driver); | 2359 | of_unregister_platform_driver(&gfar_driver); |
2327 | gfar_mdio_exit(); | ||
2328 | } | 2360 | } |
2329 | 2361 | ||
2330 | module_init(gfar_init); | 2362 | module_init(gfar_init); |