diff options
Diffstat (limited to 'drivers/net/cpmac.c')
-rw-r--r-- | drivers/net/cpmac.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 61f9da2b4943..60777fd90b33 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | 29 | ||
30 | #include <linux/netdevice.h> | 30 | #include <linux/netdevice.h> |
31 | #include <linux/if_vlan.h> | ||
31 | #include <linux/etherdevice.h> | 32 | #include <linux/etherdevice.h> |
32 | #include <linux/ethtool.h> | 33 | #include <linux/ethtool.h> |
33 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
@@ -36,6 +37,7 @@ | |||
36 | #include <linux/phy_fixed.h> | 37 | #include <linux/phy_fixed.h> |
37 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
38 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
40 | #include <linux/clk.h> | ||
39 | #include <asm/gpio.h> | 41 | #include <asm/gpio.h> |
40 | #include <asm/atomic.h> | 42 | #include <asm/atomic.h> |
41 | 43 | ||
@@ -54,9 +56,9 @@ module_param(dumb_switch, int, 0444); | |||
54 | MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); | 56 | MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable"); |
55 | MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); | 57 | MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); |
56 | 58 | ||
57 | #define CPMAC_VERSION "0.5.1" | 59 | #define CPMAC_VERSION "0.5.2" |
58 | /* frame size + 802.1q tag */ | 60 | /* frame size + 802.1q tag + FCS size */ |
59 | #define CPMAC_SKB_SIZE (ETH_FRAME_LEN + 4) | 61 | #define CPMAC_SKB_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) |
60 | #define CPMAC_QUEUES 8 | 62 | #define CPMAC_QUEUES 8 |
61 | 63 | ||
62 | /* Ethernet registers */ | 64 | /* Ethernet registers */ |
@@ -294,9 +296,16 @@ static int cpmac_mdio_write(struct mii_bus *bus, int phy_id, | |||
294 | 296 | ||
295 | static int cpmac_mdio_reset(struct mii_bus *bus) | 297 | static int cpmac_mdio_reset(struct mii_bus *bus) |
296 | { | 298 | { |
299 | struct clk *cpmac_clk; | ||
300 | |||
301 | cpmac_clk = clk_get(&bus->dev, "cpmac"); | ||
302 | if (IS_ERR(cpmac_clk)) { | ||
303 | printk(KERN_ERR "unable to get cpmac clock\n"); | ||
304 | return -1; | ||
305 | } | ||
297 | ar7_device_reset(AR7_RESET_BIT_MDIO); | 306 | ar7_device_reset(AR7_RESET_BIT_MDIO); |
298 | cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE | | 307 | cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE | |
299 | MDIOC_CLKDIV(ar7_cpmac_freq() / 2200000 - 1)); | 308 | MDIOC_CLKDIV(clk_get_rate(cpmac_clk) / 2200000 - 1)); |
300 | return 0; | 309 | return 0; |
301 | } | 310 | } |
302 | 311 | ||
@@ -320,7 +329,6 @@ static int cpmac_config(struct net_device *dev, struct ifmap *map) | |||
320 | static void cpmac_set_multicast_list(struct net_device *dev) | 329 | static void cpmac_set_multicast_list(struct net_device *dev) |
321 | { | 330 | { |
322 | struct dev_mc_list *iter; | 331 | struct dev_mc_list *iter; |
323 | int i; | ||
324 | u8 tmp; | 332 | u8 tmp; |
325 | u32 mbp, bit, hash[2] = { 0, }; | 333 | u32 mbp, bit, hash[2] = { 0, }; |
326 | struct cpmac_priv *priv = netdev_priv(dev); | 334 | struct cpmac_priv *priv = netdev_priv(dev); |
@@ -340,8 +348,7 @@ static void cpmac_set_multicast_list(struct net_device *dev) | |||
340 | * cpmac uses some strange mac address hashing | 348 | * cpmac uses some strange mac address hashing |
341 | * (not crc32) | 349 | * (not crc32) |
342 | */ | 350 | */ |
343 | for (i = 0, iter = dev->mc_list; i < dev->mc_count; | 351 | netdev_for_each_mc_addr(iter, dev) { |
344 | i++, iter = iter->next) { | ||
345 | bit = 0; | 352 | bit = 0; |
346 | tmp = iter->dmi_addr[0]; | 353 | tmp = iter->dmi_addr[0]; |
347 | bit ^= (tmp >> 2) ^ (tmp << 4); | 354 | bit ^= (tmp >> 2) ^ (tmp << 4); |
@@ -380,9 +387,8 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv, | |||
380 | return NULL; | 387 | return NULL; |
381 | } | 388 | } |
382 | 389 | ||
383 | skb = netdev_alloc_skb(priv->dev, CPMAC_SKB_SIZE); | 390 | skb = netdev_alloc_skb_ip_align(priv->dev, CPMAC_SKB_SIZE); |
384 | if (likely(skb)) { | 391 | if (likely(skb)) { |
385 | skb_reserve(skb, 2); | ||
386 | skb_put(desc->skb, desc->datalen); | 392 | skb_put(desc->skb, desc->datalen); |
387 | desc->skb->protocol = eth_type_trans(desc->skb, priv->dev); | 393 | desc->skb->protocol = eth_type_trans(desc->skb, priv->dev); |
388 | desc->skb->ip_summed = CHECKSUM_NONE; | 394 | desc->skb->ip_summed = CHECKSUM_NONE; |
@@ -991,12 +997,11 @@ static int cpmac_open(struct net_device *dev) | |||
991 | 997 | ||
992 | priv->rx_head = &priv->desc_ring[CPMAC_QUEUES]; | 998 | priv->rx_head = &priv->desc_ring[CPMAC_QUEUES]; |
993 | for (i = 0, desc = priv->rx_head; i < priv->ring_size; i++, desc++) { | 999 | for (i = 0, desc = priv->rx_head; i < priv->ring_size; i++, desc++) { |
994 | skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE); | 1000 | skb = netdev_alloc_skb_ip_align(dev, CPMAC_SKB_SIZE); |
995 | if (unlikely(!skb)) { | 1001 | if (unlikely(!skb)) { |
996 | res = -ENOMEM; | 1002 | res = -ENOMEM; |
997 | goto fail_desc; | 1003 | goto fail_desc; |
998 | } | 1004 | } |
999 | skb_reserve(skb, 2); | ||
1000 | desc->skb = skb; | 1005 | desc->skb = skb; |
1001 | desc->data_mapping = dma_map_single(&dev->dev, skb->data, | 1006 | desc->data_mapping = dma_map_single(&dev->dev, skb->data, |
1002 | CPMAC_SKB_SIZE, | 1007 | CPMAC_SKB_SIZE, |
@@ -1132,8 +1137,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1132 | } | 1137 | } |
1133 | 1138 | ||
1134 | if (phy_id == PHY_MAX_ADDR) { | 1139 | if (phy_id == PHY_MAX_ADDR) { |
1135 | dev_err(&pdev->dev, "no PHY present\n"); | 1140 | dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n"); |
1136 | return -ENODEV; | 1141 | strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ |
1142 | phy_id = pdev->id; | ||
1137 | } | 1143 | } |
1138 | 1144 | ||
1139 | dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); | 1145 | dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); |
@@ -1165,7 +1171,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) | |||
1165 | priv->dev = dev; | 1171 | priv->dev = dev; |
1166 | priv->ring_size = 64; | 1172 | priv->ring_size = 64; |
1167 | priv->msg_enable = netif_msg_init(debug_level, 0xff); | 1173 | priv->msg_enable = netif_msg_init(debug_level, 0xff); |
1168 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr)); | 1174 | memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr)); |
1169 | 1175 | ||
1170 | snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); | 1176 | snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); |
1171 | 1177 | ||
@@ -1286,8 +1292,8 @@ void __devexit cpmac_exit(void) | |||
1286 | { | 1292 | { |
1287 | platform_driver_unregister(&cpmac_driver); | 1293 | platform_driver_unregister(&cpmac_driver); |
1288 | mdiobus_unregister(cpmac_mii); | 1294 | mdiobus_unregister(cpmac_mii); |
1289 | mdiobus_free(cpmac_mii); | ||
1290 | iounmap(cpmac_mii->priv); | 1295 | iounmap(cpmac_mii->priv); |
1296 | mdiobus_free(cpmac_mii); | ||
1291 | } | 1297 | } |
1292 | 1298 | ||
1293 | module_init(cpmac_init); | 1299 | module_init(cpmac_init); |