diff options
Diffstat (limited to 'drivers/net/au1000_eth.c')
-rw-r--r-- | drivers/net/au1000_eth.c | 441 |
1 files changed, 223 insertions, 218 deletions
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index a66b06aa1f0b..4da191b87b0d 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/delay.h> | 55 | #include <linux/delay.h> |
56 | #include <linux/crc32.h> | 56 | #include <linux/crc32.h> |
57 | #include <linux/phy.h> | 57 | #include <linux/phy.h> |
58 | #include <linux/platform_device.h> | ||
58 | 59 | ||
59 | #include <asm/cpu.h> | 60 | #include <asm/cpu.h> |
60 | #include <asm/mipsregs.h> | 61 | #include <asm/mipsregs.h> |
@@ -63,6 +64,7 @@ | |||
63 | #include <asm/processor.h> | 64 | #include <asm/processor.h> |
64 | 65 | ||
65 | #include <au1000.h> | 66 | #include <au1000.h> |
67 | #include <au1xxx_eth.h> | ||
66 | #include <prom.h> | 68 | #include <prom.h> |
67 | 69 | ||
68 | #include "au1000_eth.h" | 70 | #include "au1000_eth.h" |
@@ -112,15 +114,15 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES]; | |||
112 | * | 114 | * |
113 | * PHY detection algorithm | 115 | * PHY detection algorithm |
114 | * | 116 | * |
115 | * If AU1XXX_PHY_STATIC_CONFIG is undefined, the PHY setup is | 117 | * If phy_static_config is undefined, the PHY setup is |
116 | * autodetected: | 118 | * autodetected: |
117 | * | 119 | * |
118 | * mii_probe() first searches the current MAC's MII bus for a PHY, | 120 | * mii_probe() first searches the current MAC's MII bus for a PHY, |
119 | * selecting the first (or last, if AU1XXX_PHY_SEARCH_HIGHEST_ADDR is | 121 | * selecting the first (or last, if phy_search_highest_addr is |
120 | * defined) PHY address not already claimed by another netdev. | 122 | * defined) PHY address not already claimed by another netdev. |
121 | * | 123 | * |
122 | * If nothing was found that way when searching for the 2nd ethernet | 124 | * If nothing was found that way when searching for the 2nd ethernet |
123 | * controller's PHY and AU1XXX_PHY1_SEARCH_ON_MAC0 is defined, then | 125 | * controller's PHY and phy1_search_mac0 is defined, then |
124 | * the first MII bus is searched as well for an unclaimed PHY; this is | 126 | * the first MII bus is searched as well for an unclaimed PHY; this is |
125 | * needed in case of a dual-PHY accessible only through the MAC0's MII | 127 | * needed in case of a dual-PHY accessible only through the MAC0's MII |
126 | * bus. | 128 | * bus. |
@@ -129,9 +131,7 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES]; | |||
129 | * controller is not registered to the network subsystem. | 131 | * controller is not registered to the network subsystem. |
130 | */ | 132 | */ |
131 | 133 | ||
132 | /* autodetection defaults */ | 134 | /* autodetection defaults: phy1_search_mac0 */ |
133 | #undef AU1XXX_PHY_SEARCH_HIGHEST_ADDR | ||
134 | #define AU1XXX_PHY1_SEARCH_ON_MAC0 | ||
135 | 135 | ||
136 | /* static PHY setup | 136 | /* static PHY setup |
137 | * | 137 | * |
@@ -148,29 +148,6 @@ struct au1000_private *au_macs[NUM_ETH_INTERFACES]; | |||
148 | * specific irq-map | 148 | * specific irq-map |
149 | */ | 149 | */ |
150 | 150 | ||
151 | #if defined(CONFIG_MIPS_BOSPORUS) | ||
152 | /* | ||
153 | * Micrel/Kendin 5 port switch attached to MAC0, | ||
154 | * MAC0 is associated with PHY address 5 (== WAN port) | ||
155 | * MAC1 is not associated with any PHY, since it's connected directly | ||
156 | * to the switch. | ||
157 | * no interrupts are used | ||
158 | */ | ||
159 | # define AU1XXX_PHY_STATIC_CONFIG | ||
160 | |||
161 | # define AU1XXX_PHY0_ADDR 5 | ||
162 | # define AU1XXX_PHY0_BUSID 0 | ||
163 | # undef AU1XXX_PHY0_IRQ | ||
164 | |||
165 | # undef AU1XXX_PHY1_ADDR | ||
166 | # undef AU1XXX_PHY1_BUSID | ||
167 | # undef AU1XXX_PHY1_IRQ | ||
168 | #endif | ||
169 | |||
170 | #if defined(AU1XXX_PHY0_BUSID) && (AU1XXX_PHY0_BUSID > 0) | ||
171 | # error MAC0-associated PHY attached 2nd MACs MII bus not supported yet | ||
172 | #endif | ||
173 | |||
174 | static void enable_mac(struct net_device *dev, int force_reset) | 151 | static void enable_mac(struct net_device *dev, int force_reset) |
175 | { | 152 | { |
176 | unsigned long flags; | 153 | unsigned long flags; |
@@ -390,67 +367,55 @@ static int mii_probe (struct net_device *dev) | |||
390 | struct au1000_private *const aup = netdev_priv(dev); | 367 | struct au1000_private *const aup = netdev_priv(dev); |
391 | struct phy_device *phydev = NULL; | 368 | struct phy_device *phydev = NULL; |
392 | 369 | ||
393 | #if defined(AU1XXX_PHY_STATIC_CONFIG) | 370 | if (aup->phy_static_config) { |
394 | BUG_ON(aup->mac_id < 0 || aup->mac_id > 1); | 371 | BUG_ON(aup->mac_id < 0 || aup->mac_id > 1); |
395 | 372 | ||
396 | if(aup->mac_id == 0) { /* get PHY0 */ | 373 | if (aup->phy_addr) |
397 | # if defined(AU1XXX_PHY0_ADDR) | 374 | phydev = aup->mii_bus->phy_map[aup->phy_addr]; |
398 | phydev = au_macs[AU1XXX_PHY0_BUSID]->mii_bus->phy_map[AU1XXX_PHY0_ADDR]; | 375 | else |
399 | # else | 376 | printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", |
400 | printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", | 377 | dev->name); |
401 | dev->name); | ||
402 | return 0; | ||
403 | # endif /* defined(AU1XXX_PHY0_ADDR) */ | ||
404 | } else if (aup->mac_id == 1) { /* get PHY1 */ | ||
405 | # if defined(AU1XXX_PHY1_ADDR) | ||
406 | phydev = au_macs[AU1XXX_PHY1_BUSID]->mii_bus->phy_map[AU1XXX_PHY1_ADDR]; | ||
407 | # else | ||
408 | printk (KERN_INFO DRV_NAME ":%s: using PHY-less setup\n", | ||
409 | dev->name); | ||
410 | return 0; | 378 | return 0; |
411 | # endif /* defined(AU1XXX_PHY1_ADDR) */ | 379 | } else { |
412 | } | 380 | int phy_addr; |
413 | 381 | ||
414 | #else /* defined(AU1XXX_PHY_STATIC_CONFIG) */ | 382 | /* find the first (lowest address) PHY on the current MAC's MII bus */ |
415 | int phy_addr; | 383 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) |
416 | 384 | if (aup->mii_bus->phy_map[phy_addr]) { | |
417 | /* find the first (lowest address) PHY on the current MAC's MII bus */ | 385 | phydev = aup->mii_bus->phy_map[phy_addr]; |
418 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) | 386 | if (!aup->phy_search_highest_addr) |
419 | if (aup->mii_bus->phy_map[phy_addr]) { | 387 | break; /* break out with first one found */ |
420 | phydev = aup->mii_bus->phy_map[phy_addr]; | 388 | } |
421 | # if !defined(AU1XXX_PHY_SEARCH_HIGHEST_ADDR) | ||
422 | break; /* break out with first one found */ | ||
423 | # endif | ||
424 | } | ||
425 | 389 | ||
426 | # if defined(AU1XXX_PHY1_SEARCH_ON_MAC0) | 390 | if (aup->phy1_search_mac0) { |
427 | /* try harder to find a PHY */ | 391 | /* try harder to find a PHY */ |
428 | if (!phydev && (aup->mac_id == 1)) { | 392 | if (!phydev && (aup->mac_id == 1)) { |
429 | /* no PHY found, maybe we have a dual PHY? */ | 393 | /* no PHY found, maybe we have a dual PHY? */ |
430 | printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, " | 394 | printk (KERN_INFO DRV_NAME ": no PHY found on MAC1, " |
431 | "let's see if it's attached to MAC0...\n"); | 395 | "let's see if it's attached to MAC0...\n"); |
432 | 396 | ||
433 | BUG_ON(!au_macs[0]); | 397 | /* find the first (lowest address) non-attached PHY on |
398 | * the MAC0 MII bus */ | ||
399 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { | ||
400 | struct phy_device *const tmp_phydev = | ||
401 | aup->mii_bus->phy_map[phy_addr]; | ||
434 | 402 | ||
435 | /* find the first (lowest address) non-attached PHY on | 403 | if (aup->mac_id == 1) |
436 | * the MAC0 MII bus */ | 404 | break; |
437 | for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { | ||
438 | struct phy_device *const tmp_phydev = | ||
439 | au_macs[0]->mii_bus->phy_map[phy_addr]; | ||
440 | 405 | ||
441 | if (!tmp_phydev) | 406 | if (!tmp_phydev) |
442 | continue; /* no PHY here... */ | 407 | continue; /* no PHY here... */ |
443 | 408 | ||
444 | if (tmp_phydev->attached_dev) | 409 | if (tmp_phydev->attached_dev) |
445 | continue; /* already claimed by MAC0 */ | 410 | continue; /* already claimed by MAC0 */ |
446 | 411 | ||
447 | phydev = tmp_phydev; | 412 | phydev = tmp_phydev; |
448 | break; /* found it */ | 413 | break; /* found it */ |
414 | } | ||
415 | } | ||
449 | } | 416 | } |
450 | } | 417 | } |
451 | # endif /* defined(AU1XXX_PHY1_SEARCH_OTHER_BUS) */ | ||
452 | 418 | ||
453 | #endif /* defined(AU1XXX_PHY_STATIC_CONFIG) */ | ||
454 | if (!phydev) { | 419 | if (!phydev) { |
455 | printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name); | 420 | printk (KERN_ERR DRV_NAME ":%s: no PHY found\n", dev->name); |
456 | return -1; | 421 | return -1; |
@@ -578,31 +543,6 @@ setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) | |||
578 | } | 543 | } |
579 | } | 544 | } |
580 | 545 | ||
581 | static struct { | ||
582 | u32 base_addr; | ||
583 | u32 macen_addr; | ||
584 | int irq; | ||
585 | struct net_device *dev; | ||
586 | } iflist[2] = { | ||
587 | #ifdef CONFIG_SOC_AU1000 | ||
588 | {AU1000_ETH0_BASE, AU1000_MAC0_ENABLE, AU1000_MAC0_DMA_INT}, | ||
589 | {AU1000_ETH1_BASE, AU1000_MAC1_ENABLE, AU1000_MAC1_DMA_INT} | ||
590 | #endif | ||
591 | #ifdef CONFIG_SOC_AU1100 | ||
592 | {AU1100_ETH0_BASE, AU1100_MAC0_ENABLE, AU1100_MAC0_DMA_INT} | ||
593 | #endif | ||
594 | #ifdef CONFIG_SOC_AU1500 | ||
595 | {AU1500_ETH0_BASE, AU1500_MAC0_ENABLE, AU1500_MAC0_DMA_INT}, | ||
596 | {AU1500_ETH1_BASE, AU1500_MAC1_ENABLE, AU1500_MAC1_DMA_INT} | ||
597 | #endif | ||
598 | #ifdef CONFIG_SOC_AU1550 | ||
599 | {AU1550_ETH0_BASE, AU1550_MAC0_ENABLE, AU1550_MAC0_DMA_INT}, | ||
600 | {AU1550_ETH1_BASE, AU1550_MAC1_ENABLE, AU1550_MAC1_DMA_INT} | ||
601 | #endif | ||
602 | }; | ||
603 | |||
604 | static int num_ifs; | ||
605 | |||
606 | /* | 546 | /* |
607 | * ethtool operations | 547 | * ethtool operations |
608 | */ | 548 | */ |
@@ -711,7 +651,6 @@ static int au1000_init(struct net_device *dev) | |||
711 | 651 | ||
712 | static inline void update_rx_stats(struct net_device *dev, u32 status) | 652 | static inline void update_rx_stats(struct net_device *dev, u32 status) |
713 | { | 653 | { |
714 | struct au1000_private *aup = netdev_priv(dev); | ||
715 | struct net_device_stats *ps = &dev->stats; | 654 | struct net_device_stats *ps = &dev->stats; |
716 | 655 | ||
717 | ps->rx_packets++; | 656 | ps->rx_packets++; |
@@ -969,7 +908,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) | |||
969 | } | 908 | } |
970 | 909 | ||
971 | pDB = aup->tx_db_inuse[aup->tx_head]; | 910 | pDB = aup->tx_db_inuse[aup->tx_head]; |
972 | skb_copy_from_linear_data(skb, pDB->vaddr, skb->len); | 911 | skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len); |
973 | if (skb->len < ETH_ZLEN) { | 912 | if (skb->len < ETH_ZLEN) { |
974 | for (i=skb->len; i<ETH_ZLEN; i++) { | 913 | for (i=skb->len; i<ETH_ZLEN; i++) { |
975 | ((char *)pDB->vaddr)[i] = 0; | 914 | ((char *)pDB->vaddr)[i] = 0; |
@@ -1055,53 +994,59 @@ static const struct net_device_ops au1000_netdev_ops = { | |||
1055 | .ndo_change_mtu = eth_change_mtu, | 994 | .ndo_change_mtu = eth_change_mtu, |
1056 | }; | 995 | }; |
1057 | 996 | ||
1058 | static struct net_device * au1000_probe(int port_num) | 997 | static int __devinit au1000_probe(struct platform_device *pdev) |
1059 | { | 998 | { |
1060 | static unsigned version_printed = 0; | 999 | static unsigned version_printed = 0; |
1061 | struct au1000_private *aup = NULL; | 1000 | struct au1000_private *aup = NULL; |
1001 | struct au1000_eth_platform_data *pd; | ||
1062 | struct net_device *dev = NULL; | 1002 | struct net_device *dev = NULL; |
1063 | db_dest_t *pDB, *pDBfree; | 1003 | db_dest_t *pDB, *pDBfree; |
1004 | int irq, i, err = 0; | ||
1005 | struct resource *base, *macen; | ||
1064 | char ethaddr[6]; | 1006 | char ethaddr[6]; |
1065 | int irq, i, err; | ||
1066 | u32 base, macen; | ||
1067 | 1007 | ||
1068 | if (port_num >= NUM_ETH_INTERFACES) | 1008 | base = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1069 | return NULL; | 1009 | if (!base) { |
1010 | printk(KERN_ERR DRV_NAME ": failed to retrieve base register\n"); | ||
1011 | err = -ENODEV; | ||
1012 | goto out; | ||
1013 | } | ||
1070 | 1014 | ||
1071 | base = CPHYSADDR(iflist[port_num].base_addr ); | 1015 | macen = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1072 | macen = CPHYSADDR(iflist[port_num].macen_addr); | 1016 | if (!macen) { |
1073 | irq = iflist[port_num].irq; | 1017 | printk(KERN_ERR DRV_NAME ": failed to retrieve MAC Enable register\n"); |
1018 | err = -ENODEV; | ||
1019 | goto out; | ||
1020 | } | ||
1074 | 1021 | ||
1075 | if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") || | 1022 | irq = platform_get_irq(pdev, 0); |
1076 | !request_mem_region(macen, 4, "Au1x00 ENET")) | 1023 | if (irq < 0) { |
1077 | return NULL; | 1024 | printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n"); |
1025 | err = -ENODEV; | ||
1026 | goto out; | ||
1027 | } | ||
1078 | 1028 | ||
1079 | if (version_printed++ == 0) | 1029 | if (!request_mem_region(base->start, resource_size(base), pdev->name)) { |
1080 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); | 1030 | printk(KERN_ERR DRV_NAME ": failed to request memory region for base registers\n"); |
1031 | err = -ENXIO; | ||
1032 | goto out; | ||
1033 | } | ||
1034 | |||
1035 | if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) { | ||
1036 | printk(KERN_ERR DRV_NAME ": failed to request memory region for MAC enable register\n"); | ||
1037 | err = -ENXIO; | ||
1038 | goto err_request; | ||
1039 | } | ||
1081 | 1040 | ||
1082 | dev = alloc_etherdev(sizeof(struct au1000_private)); | 1041 | dev = alloc_etherdev(sizeof(struct au1000_private)); |
1083 | if (!dev) { | 1042 | if (!dev) { |
1084 | printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); | 1043 | printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); |
1085 | return NULL; | 1044 | err = -ENOMEM; |
1045 | goto err_alloc; | ||
1086 | } | 1046 | } |
1087 | 1047 | ||
1088 | dev->base_addr = base; | 1048 | SET_NETDEV_DEV(dev, &pdev->dev); |
1089 | dev->irq = irq; | 1049 | platform_set_drvdata(pdev, dev); |
1090 | dev->netdev_ops = &au1000_netdev_ops; | ||
1091 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1092 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1093 | |||
1094 | err = register_netdev(dev); | ||
1095 | if (err != 0) { | ||
1096 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", | ||
1097 | DRV_NAME, err); | ||
1098 | free_netdev(dev); | ||
1099 | return NULL; | ||
1100 | } | ||
1101 | |||
1102 | printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n", | ||
1103 | dev->name, base, irq); | ||
1104 | |||
1105 | aup = netdev_priv(dev); | 1050 | aup = netdev_priv(dev); |
1106 | 1051 | ||
1107 | spin_lock_init(&aup->lock); | 1052 | spin_lock_init(&aup->lock); |
@@ -1112,21 +1057,29 @@ static struct net_device * au1000_probe(int port_num) | |||
1112 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | 1057 | (NUM_TX_BUFFS + NUM_RX_BUFFS), |
1113 | &aup->dma_addr, 0); | 1058 | &aup->dma_addr, 0); |
1114 | if (!aup->vaddr) { | 1059 | if (!aup->vaddr) { |
1115 | free_netdev(dev); | 1060 | printk(KERN_ERR DRV_NAME ": failed to allocate data buffers\n"); |
1116 | release_mem_region( base, MAC_IOSIZE); | 1061 | err = -ENOMEM; |
1117 | release_mem_region(macen, 4); | 1062 | goto err_vaddr; |
1118 | return NULL; | ||
1119 | } | 1063 | } |
1120 | 1064 | ||
1121 | /* aup->mac is the base address of the MAC's registers */ | 1065 | /* aup->mac is the base address of the MAC's registers */ |
1122 | aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr; | 1066 | aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base)); |
1067 | if (!aup->mac) { | ||
1068 | printk(KERN_ERR DRV_NAME ": failed to ioremap MAC registers\n"); | ||
1069 | err = -ENXIO; | ||
1070 | goto err_remap1; | ||
1071 | } | ||
1123 | 1072 | ||
1124 | /* Setup some variables for quick register address access */ | 1073 | /* Setup some variables for quick register address access */ |
1125 | aup->enable = (volatile u32 *)iflist[port_num].macen_addr; | 1074 | aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen)); |
1126 | aup->mac_id = port_num; | 1075 | if (!aup->enable) { |
1127 | au_macs[port_num] = aup; | 1076 | printk(KERN_ERR DRV_NAME ": failed to ioremap MAC enable register\n"); |
1077 | err = -ENXIO; | ||
1078 | goto err_remap2; | ||
1079 | } | ||
1080 | aup->mac_id = pdev->id; | ||
1128 | 1081 | ||
1129 | if (port_num == 0) { | 1082 | if (pdev->id == 0) { |
1130 | if (prom_get_ethernet_addr(ethaddr) == 0) | 1083 | if (prom_get_ethernet_addr(ethaddr) == 0) |
1131 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); | 1084 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); |
1132 | else { | 1085 | else { |
@@ -1136,7 +1089,7 @@ static struct net_device * au1000_probe(int port_num) | |||
1136 | } | 1089 | } |
1137 | 1090 | ||
1138 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); | 1091 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); |
1139 | } else if (port_num == 1) | 1092 | } else if (pdev->id == 1) |
1140 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); | 1093 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); |
1141 | 1094 | ||
1142 | /* | 1095 | /* |
@@ -1144,14 +1097,37 @@ static struct net_device * au1000_probe(int port_num) | |||
1144 | * to match those that are printed on their stickers | 1097 | * to match those that are printed on their stickers |
1145 | */ | 1098 | */ |
1146 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | 1099 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); |
1147 | dev->dev_addr[5] += port_num; | 1100 | dev->dev_addr[5] += pdev->id; |
1148 | 1101 | ||
1149 | *aup->enable = 0; | 1102 | *aup->enable = 0; |
1150 | aup->mac_enabled = 0; | 1103 | aup->mac_enabled = 0; |
1151 | 1104 | ||
1105 | pd = pdev->dev.platform_data; | ||
1106 | if (!pd) { | ||
1107 | printk(KERN_INFO DRV_NAME ": no platform_data passed, PHY search on MAC0\n"); | ||
1108 | aup->phy1_search_mac0 = 1; | ||
1109 | } else { | ||
1110 | aup->phy_static_config = pd->phy_static_config; | ||
1111 | aup->phy_search_highest_addr = pd->phy_search_highest_addr; | ||
1112 | aup->phy1_search_mac0 = pd->phy1_search_mac0; | ||
1113 | aup->phy_addr = pd->phy_addr; | ||
1114 | aup->phy_busid = pd->phy_busid; | ||
1115 | aup->phy_irq = pd->phy_irq; | ||
1116 | } | ||
1117 | |||
1118 | if (aup->phy_busid && aup->phy_busid > 0) { | ||
1119 | printk(KERN_ERR DRV_NAME ": MAC0-associated PHY attached 2nd MACs MII" | ||
1120 | "bus not supported yet\n"); | ||
1121 | err = -ENODEV; | ||
1122 | goto err_mdiobus_alloc; | ||
1123 | } | ||
1124 | |||
1152 | aup->mii_bus = mdiobus_alloc(); | 1125 | aup->mii_bus = mdiobus_alloc(); |
1153 | if (aup->mii_bus == NULL) | 1126 | if (aup->mii_bus == NULL) { |
1154 | goto err_out; | 1127 | printk(KERN_ERR DRV_NAME ": failed to allocate mdiobus structure\n"); |
1128 | err = -ENOMEM; | ||
1129 | goto err_mdiobus_alloc; | ||
1130 | } | ||
1155 | 1131 | ||
1156 | aup->mii_bus->priv = dev; | 1132 | aup->mii_bus->priv = dev; |
1157 | aup->mii_bus->read = au1000_mdiobus_read; | 1133 | aup->mii_bus->read = au1000_mdiobus_read; |
@@ -1165,23 +1141,19 @@ static struct net_device * au1000_probe(int port_num) | |||
1165 | 1141 | ||
1166 | for(i = 0; i < PHY_MAX_ADDR; ++i) | 1142 | for(i = 0; i < PHY_MAX_ADDR; ++i) |
1167 | aup->mii_bus->irq[i] = PHY_POLL; | 1143 | aup->mii_bus->irq[i] = PHY_POLL; |
1168 | |||
1169 | /* if known, set corresponding PHY IRQs */ | 1144 | /* if known, set corresponding PHY IRQs */ |
1170 | #if defined(AU1XXX_PHY_STATIC_CONFIG) | 1145 | if (aup->phy_static_config) |
1171 | # if defined(AU1XXX_PHY0_IRQ) | 1146 | if (aup->phy_irq && aup->phy_busid == aup->mac_id) |
1172 | if (AU1XXX_PHY0_BUSID == aup->mac_id) | 1147 | aup->mii_bus->irq[aup->phy_addr] = aup->phy_irq; |
1173 | aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ; | 1148 | |
1174 | # endif | 1149 | err = mdiobus_register(aup->mii_bus); |
1175 | # if defined(AU1XXX_PHY1_IRQ) | 1150 | if (err) { |
1176 | if (AU1XXX_PHY1_BUSID == aup->mac_id) | 1151 | printk(KERN_ERR DRV_NAME " failed to register MDIO bus\n"); |
1177 | aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ; | 1152 | goto err_mdiobus_reg; |
1178 | # endif | 1153 | } |
1179 | #endif | ||
1180 | mdiobus_register(aup->mii_bus); | ||
1181 | 1154 | ||
1182 | if (mii_probe(dev) != 0) { | 1155 | if (mii_probe(dev) != 0) |
1183 | goto err_out; | 1156 | goto err_out; |
1184 | } | ||
1185 | 1157 | ||
1186 | pDBfree = NULL; | 1158 | pDBfree = NULL; |
1187 | /* setup the data buffer descriptors and attach a buffer to each one */ | 1159 | /* setup the data buffer descriptors and attach a buffer to each one */ |
@@ -1213,19 +1185,35 @@ static struct net_device * au1000_probe(int port_num) | |||
1213 | aup->tx_db_inuse[i] = pDB; | 1185 | aup->tx_db_inuse[i] = pDB; |
1214 | } | 1186 | } |
1215 | 1187 | ||
1188 | dev->base_addr = base->start; | ||
1189 | dev->irq = irq; | ||
1190 | dev->netdev_ops = &au1000_netdev_ops; | ||
1191 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1192 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1193 | |||
1216 | /* | 1194 | /* |
1217 | * The boot code uses the ethernet controller, so reset it to start | 1195 | * The boot code uses the ethernet controller, so reset it to start |
1218 | * fresh. au1000_init() expects that the device is in reset state. | 1196 | * fresh. au1000_init() expects that the device is in reset state. |
1219 | */ | 1197 | */ |
1220 | reset_mac(dev); | 1198 | reset_mac(dev); |
1221 | 1199 | ||
1222 | return dev; | 1200 | err = register_netdev(dev); |
1201 | if (err) { | ||
1202 | printk(KERN_ERR DRV_NAME "%s: Cannot register net device, aborting.\n", | ||
1203 | dev->name); | ||
1204 | goto err_out; | ||
1205 | } | ||
1206 | |||
1207 | printk("%s: Au1xx0 Ethernet found at 0x%lx, irq %d\n", | ||
1208 | dev->name, (unsigned long)base->start, irq); | ||
1209 | if (version_printed++ == 0) | ||
1210 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); | ||
1211 | |||
1212 | return 0; | ||
1223 | 1213 | ||
1224 | err_out: | 1214 | err_out: |
1225 | if (aup->mii_bus != NULL) { | 1215 | if (aup->mii_bus != NULL) |
1226 | mdiobus_unregister(aup->mii_bus); | 1216 | mdiobus_unregister(aup->mii_bus); |
1227 | mdiobus_free(aup->mii_bus); | ||
1228 | } | ||
1229 | 1217 | ||
1230 | /* here we should have a valid dev plus aup-> register addresses | 1218 | /* here we should have a valid dev plus aup-> register addresses |
1231 | * so we can reset the mac properly.*/ | 1219 | * so we can reset the mac properly.*/ |
@@ -1239,67 +1227,84 @@ err_out: | |||
1239 | if (aup->tx_db_inuse[i]) | 1227 | if (aup->tx_db_inuse[i]) |
1240 | ReleaseDB(aup, aup->tx_db_inuse[i]); | 1228 | ReleaseDB(aup, aup->tx_db_inuse[i]); |
1241 | } | 1229 | } |
1230 | err_mdiobus_reg: | ||
1231 | mdiobus_free(aup->mii_bus); | ||
1232 | err_mdiobus_alloc: | ||
1233 | iounmap(aup->enable); | ||
1234 | err_remap2: | ||
1235 | iounmap(aup->mac); | ||
1236 | err_remap1: | ||
1242 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), | 1237 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), |
1243 | (void *)aup->vaddr, aup->dma_addr); | 1238 | (void *)aup->vaddr, aup->dma_addr); |
1244 | unregister_netdev(dev); | 1239 | err_vaddr: |
1245 | free_netdev(dev); | 1240 | free_netdev(dev); |
1246 | release_mem_region( base, MAC_IOSIZE); | 1241 | err_alloc: |
1247 | release_mem_region(macen, 4); | 1242 | release_mem_region(macen->start, resource_size(macen)); |
1248 | return NULL; | 1243 | err_request: |
1244 | release_mem_region(base->start, resource_size(base)); | ||
1245 | out: | ||
1246 | return err; | ||
1249 | } | 1247 | } |
1250 | 1248 | ||
1251 | /* | 1249 | static int __devexit au1000_remove(struct platform_device *pdev) |
1252 | * Setup the base address and interrupt of the Au1xxx ethernet macs | ||
1253 | * based on cpu type and whether the interface is enabled in sys_pinfunc | ||
1254 | * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0. | ||
1255 | */ | ||
1256 | static int __init au1000_init_module(void) | ||
1257 | { | 1250 | { |
1258 | int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4); | 1251 | struct net_device *dev = platform_get_drvdata(pdev); |
1259 | struct net_device *dev; | 1252 | struct au1000_private *aup = netdev_priv(dev); |
1260 | int i, found_one = 0; | 1253 | int i; |
1254 | struct resource *base, *macen; | ||
1261 | 1255 | ||
1262 | num_ifs = NUM_ETH_INTERFACES - ni; | 1256 | platform_set_drvdata(pdev, NULL); |
1257 | |||
1258 | unregister_netdev(dev); | ||
1259 | mdiobus_unregister(aup->mii_bus); | ||
1260 | mdiobus_free(aup->mii_bus); | ||
1261 | |||
1262 | for (i = 0; i < NUM_RX_DMA; i++) | ||
1263 | if (aup->rx_db_inuse[i]) | ||
1264 | ReleaseDB(aup, aup->rx_db_inuse[i]); | ||
1265 | |||
1266 | for (i = 0; i < NUM_TX_DMA; i++) | ||
1267 | if (aup->tx_db_inuse[i]) | ||
1268 | ReleaseDB(aup, aup->tx_db_inuse[i]); | ||
1269 | |||
1270 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * | ||
1271 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1272 | (void *)aup->vaddr, aup->dma_addr); | ||
1273 | |||
1274 | iounmap(aup->mac); | ||
1275 | iounmap(aup->enable); | ||
1276 | |||
1277 | base = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1278 | release_mem_region(base->start, resource_size(base)); | ||
1279 | |||
1280 | macen = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
1281 | release_mem_region(macen->start, resource_size(macen)); | ||
1282 | |||
1283 | free_netdev(dev); | ||
1263 | 1284 | ||
1264 | for(i = 0; i < num_ifs; i++) { | ||
1265 | dev = au1000_probe(i); | ||
1266 | iflist[i].dev = dev; | ||
1267 | if (dev) | ||
1268 | found_one++; | ||
1269 | } | ||
1270 | if (!found_one) | ||
1271 | return -ENODEV; | ||
1272 | return 0; | 1285 | return 0; |
1273 | } | 1286 | } |
1274 | 1287 | ||
1275 | static void __exit au1000_cleanup_module(void) | 1288 | static struct platform_driver au1000_eth_driver = { |
1289 | .probe = au1000_probe, | ||
1290 | .remove = __devexit_p(au1000_remove), | ||
1291 | .driver = { | ||
1292 | .name = "au1000-eth", | ||
1293 | .owner = THIS_MODULE, | ||
1294 | }, | ||
1295 | }; | ||
1296 | MODULE_ALIAS("platform:au1000-eth"); | ||
1297 | |||
1298 | |||
1299 | static int __init au1000_init_module(void) | ||
1300 | { | ||
1301 | return platform_driver_register(&au1000_eth_driver); | ||
1302 | } | ||
1303 | |||
1304 | static void __exit au1000_exit_module(void) | ||
1276 | { | 1305 | { |
1277 | int i, j; | 1306 | platform_driver_unregister(&au1000_eth_driver); |
1278 | struct net_device *dev; | ||
1279 | struct au1000_private *aup; | ||
1280 | |||
1281 | for (i = 0; i < num_ifs; i++) { | ||
1282 | dev = iflist[i].dev; | ||
1283 | if (dev) { | ||
1284 | aup = netdev_priv(dev); | ||
1285 | unregister_netdev(dev); | ||
1286 | mdiobus_unregister(aup->mii_bus); | ||
1287 | mdiobus_free(aup->mii_bus); | ||
1288 | for (j = 0; j < NUM_RX_DMA; j++) | ||
1289 | if (aup->rx_db_inuse[j]) | ||
1290 | ReleaseDB(aup, aup->rx_db_inuse[j]); | ||
1291 | for (j = 0; j < NUM_TX_DMA; j++) | ||
1292 | if (aup->tx_db_inuse[j]) | ||
1293 | ReleaseDB(aup, aup->tx_db_inuse[j]); | ||
1294 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * | ||
1295 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1296 | (void *)aup->vaddr, aup->dma_addr); | ||
1297 | release_mem_region(dev->base_addr, MAC_IOSIZE); | ||
1298 | release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4); | ||
1299 | free_netdev(dev); | ||
1300 | } | ||
1301 | } | ||
1302 | } | 1307 | } |
1303 | 1308 | ||
1304 | module_init(au1000_init_module); | 1309 | module_init(au1000_init_module); |
1305 | module_exit(au1000_cleanup_module); | 1310 | module_exit(au1000_exit_module); |