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 6bac04603a88..6e5a68ecde09 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; |
@@ -1058,53 +997,59 @@ static const struct net_device_ops au1000_netdev_ops = { | |||
1058 | .ndo_change_mtu = eth_change_mtu, | 997 | .ndo_change_mtu = eth_change_mtu, |
1059 | }; | 998 | }; |
1060 | 999 | ||
1061 | static struct net_device * au1000_probe(int port_num) | 1000 | static int __devinit au1000_probe(struct platform_device *pdev) |
1062 | { | 1001 | { |
1063 | static unsigned version_printed = 0; | 1002 | static unsigned version_printed = 0; |
1064 | struct au1000_private *aup = NULL; | 1003 | struct au1000_private *aup = NULL; |
1004 | struct au1000_eth_platform_data *pd; | ||
1065 | struct net_device *dev = NULL; | 1005 | struct net_device *dev = NULL; |
1066 | db_dest_t *pDB, *pDBfree; | 1006 | db_dest_t *pDB, *pDBfree; |
1007 | int irq, i, err = 0; | ||
1008 | struct resource *base, *macen; | ||
1067 | char ethaddr[6]; | 1009 | char ethaddr[6]; |
1068 | int irq, i, err; | ||
1069 | u32 base, macen; | ||
1070 | 1010 | ||
1071 | if (port_num >= NUM_ETH_INTERFACES) | 1011 | base = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1072 | return NULL; | 1012 | if (!base) { |
1013 | printk(KERN_ERR DRV_NAME ": failed to retrieve base register\n"); | ||
1014 | err = -ENODEV; | ||
1015 | goto out; | ||
1016 | } | ||
1073 | 1017 | ||
1074 | base = CPHYSADDR(iflist[port_num].base_addr ); | 1018 | macen = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1075 | macen = CPHYSADDR(iflist[port_num].macen_addr); | 1019 | if (!macen) { |
1076 | irq = iflist[port_num].irq; | 1020 | printk(KERN_ERR DRV_NAME ": failed to retrieve MAC Enable register\n"); |
1021 | err = -ENODEV; | ||
1022 | goto out; | ||
1023 | } | ||
1077 | 1024 | ||
1078 | if (!request_mem_region( base, MAC_IOSIZE, "Au1x00 ENET") || | 1025 | irq = platform_get_irq(pdev, 0); |
1079 | !request_mem_region(macen, 4, "Au1x00 ENET")) | 1026 | if (irq < 0) { |
1080 | return NULL; | 1027 | printk(KERN_ERR DRV_NAME ": failed to retrieve IRQ\n"); |
1028 | err = -ENODEV; | ||
1029 | goto out; | ||
1030 | } | ||
1081 | 1031 | ||
1082 | if (version_printed++ == 0) | 1032 | if (!request_mem_region(base->start, resource_size(base), pdev->name)) { |
1083 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); | 1033 | printk(KERN_ERR DRV_NAME ": failed to request memory region for base registers\n"); |
1034 | err = -ENXIO; | ||
1035 | goto out; | ||
1036 | } | ||
1037 | |||
1038 | if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) { | ||
1039 | printk(KERN_ERR DRV_NAME ": failed to request memory region for MAC enable register\n"); | ||
1040 | err = -ENXIO; | ||
1041 | goto err_request; | ||
1042 | } | ||
1084 | 1043 | ||
1085 | dev = alloc_etherdev(sizeof(struct au1000_private)); | 1044 | dev = alloc_etherdev(sizeof(struct au1000_private)); |
1086 | if (!dev) { | 1045 | if (!dev) { |
1087 | printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); | 1046 | printk(KERN_ERR "%s: alloc_etherdev failed\n", DRV_NAME); |
1088 | return NULL; | 1047 | err = -ENOMEM; |
1048 | goto err_alloc; | ||
1089 | } | 1049 | } |
1090 | 1050 | ||
1091 | dev->base_addr = base; | 1051 | SET_NETDEV_DEV(dev, &pdev->dev); |
1092 | dev->irq = irq; | 1052 | platform_set_drvdata(pdev, dev); |
1093 | dev->netdev_ops = &au1000_netdev_ops; | ||
1094 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1095 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1096 | |||
1097 | err = register_netdev(dev); | ||
1098 | if (err != 0) { | ||
1099 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", | ||
1100 | DRV_NAME, err); | ||
1101 | free_netdev(dev); | ||
1102 | return NULL; | ||
1103 | } | ||
1104 | |||
1105 | printk("%s: Au1xx0 Ethernet found at 0x%x, irq %d\n", | ||
1106 | dev->name, base, irq); | ||
1107 | |||
1108 | aup = netdev_priv(dev); | 1053 | aup = netdev_priv(dev); |
1109 | 1054 | ||
1110 | spin_lock_init(&aup->lock); | 1055 | spin_lock_init(&aup->lock); |
@@ -1115,21 +1060,29 @@ static struct net_device * au1000_probe(int port_num) | |||
1115 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | 1060 | (NUM_TX_BUFFS + NUM_RX_BUFFS), |
1116 | &aup->dma_addr, 0); | 1061 | &aup->dma_addr, 0); |
1117 | if (!aup->vaddr) { | 1062 | if (!aup->vaddr) { |
1118 | free_netdev(dev); | 1063 | printk(KERN_ERR DRV_NAME ": failed to allocate data buffers\n"); |
1119 | release_mem_region( base, MAC_IOSIZE); | 1064 | err = -ENOMEM; |
1120 | release_mem_region(macen, 4); | 1065 | goto err_vaddr; |
1121 | return NULL; | ||
1122 | } | 1066 | } |
1123 | 1067 | ||
1124 | /* aup->mac is the base address of the MAC's registers */ | 1068 | /* aup->mac is the base address of the MAC's registers */ |
1125 | aup->mac = (volatile mac_reg_t *)iflist[port_num].base_addr; | 1069 | aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base)); |
1070 | if (!aup->mac) { | ||
1071 | printk(KERN_ERR DRV_NAME ": failed to ioremap MAC registers\n"); | ||
1072 | err = -ENXIO; | ||
1073 | goto err_remap1; | ||
1074 | } | ||
1126 | 1075 | ||
1127 | /* Setup some variables for quick register address access */ | 1076 | /* Setup some variables for quick register address access */ |
1128 | aup->enable = (volatile u32 *)iflist[port_num].macen_addr; | 1077 | aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen)); |
1129 | aup->mac_id = port_num; | 1078 | if (!aup->enable) { |
1130 | au_macs[port_num] = aup; | 1079 | printk(KERN_ERR DRV_NAME ": failed to ioremap MAC enable register\n"); |
1080 | err = -ENXIO; | ||
1081 | goto err_remap2; | ||
1082 | } | ||
1083 | aup->mac_id = pdev->id; | ||
1131 | 1084 | ||
1132 | if (port_num == 0) { | 1085 | if (pdev->id == 0) { |
1133 | if (prom_get_ethernet_addr(ethaddr) == 0) | 1086 | if (prom_get_ethernet_addr(ethaddr) == 0) |
1134 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); | 1087 | memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr)); |
1135 | else { | 1088 | else { |
@@ -1139,7 +1092,7 @@ static struct net_device * au1000_probe(int port_num) | |||
1139 | } | 1092 | } |
1140 | 1093 | ||
1141 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); | 1094 | setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); |
1142 | } else if (port_num == 1) | 1095 | } else if (pdev->id == 1) |
1143 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); | 1096 | setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); |
1144 | 1097 | ||
1145 | /* | 1098 | /* |
@@ -1147,14 +1100,37 @@ static struct net_device * au1000_probe(int port_num) | |||
1147 | * to match those that are printed on their stickers | 1100 | * to match those that are printed on their stickers |
1148 | */ | 1101 | */ |
1149 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); | 1102 | memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr)); |
1150 | dev->dev_addr[5] += port_num; | 1103 | dev->dev_addr[5] += pdev->id; |
1151 | 1104 | ||
1152 | *aup->enable = 0; | 1105 | *aup->enable = 0; |
1153 | aup->mac_enabled = 0; | 1106 | aup->mac_enabled = 0; |
1154 | 1107 | ||
1108 | pd = pdev->dev.platform_data; | ||
1109 | if (!pd) { | ||
1110 | printk(KERN_INFO DRV_NAME ": no platform_data passed, PHY search on MAC0\n"); | ||
1111 | aup->phy1_search_mac0 = 1; | ||
1112 | } else { | ||
1113 | aup->phy_static_config = pd->phy_static_config; | ||
1114 | aup->phy_search_highest_addr = pd->phy_search_highest_addr; | ||
1115 | aup->phy1_search_mac0 = pd->phy1_search_mac0; | ||
1116 | aup->phy_addr = pd->phy_addr; | ||
1117 | aup->phy_busid = pd->phy_busid; | ||
1118 | aup->phy_irq = pd->phy_irq; | ||
1119 | } | ||
1120 | |||
1121 | if (aup->phy_busid && aup->phy_busid > 0) { | ||
1122 | printk(KERN_ERR DRV_NAME ": MAC0-associated PHY attached 2nd MACs MII" | ||
1123 | "bus not supported yet\n"); | ||
1124 | err = -ENODEV; | ||
1125 | goto err_mdiobus_alloc; | ||
1126 | } | ||
1127 | |||
1155 | aup->mii_bus = mdiobus_alloc(); | 1128 | aup->mii_bus = mdiobus_alloc(); |
1156 | if (aup->mii_bus == NULL) | 1129 | if (aup->mii_bus == NULL) { |
1157 | goto err_out; | 1130 | printk(KERN_ERR DRV_NAME ": failed to allocate mdiobus structure\n"); |
1131 | err = -ENOMEM; | ||
1132 | goto err_mdiobus_alloc; | ||
1133 | } | ||
1158 | 1134 | ||
1159 | aup->mii_bus->priv = dev; | 1135 | aup->mii_bus->priv = dev; |
1160 | aup->mii_bus->read = au1000_mdiobus_read; | 1136 | aup->mii_bus->read = au1000_mdiobus_read; |
@@ -1168,23 +1144,19 @@ static struct net_device * au1000_probe(int port_num) | |||
1168 | 1144 | ||
1169 | for(i = 0; i < PHY_MAX_ADDR; ++i) | 1145 | for(i = 0; i < PHY_MAX_ADDR; ++i) |
1170 | aup->mii_bus->irq[i] = PHY_POLL; | 1146 | aup->mii_bus->irq[i] = PHY_POLL; |
1171 | |||
1172 | /* if known, set corresponding PHY IRQs */ | 1147 | /* if known, set corresponding PHY IRQs */ |
1173 | #if defined(AU1XXX_PHY_STATIC_CONFIG) | 1148 | if (aup->phy_static_config) |
1174 | # if defined(AU1XXX_PHY0_IRQ) | 1149 | if (aup->phy_irq && aup->phy_busid == aup->mac_id) |
1175 | if (AU1XXX_PHY0_BUSID == aup->mac_id) | 1150 | aup->mii_bus->irq[aup->phy_addr] = aup->phy_irq; |
1176 | aup->mii_bus->irq[AU1XXX_PHY0_ADDR] = AU1XXX_PHY0_IRQ; | 1151 | |
1177 | # endif | 1152 | err = mdiobus_register(aup->mii_bus); |
1178 | # if defined(AU1XXX_PHY1_IRQ) | 1153 | if (err) { |
1179 | if (AU1XXX_PHY1_BUSID == aup->mac_id) | 1154 | printk(KERN_ERR DRV_NAME " failed to register MDIO bus\n"); |
1180 | aup->mii_bus->irq[AU1XXX_PHY1_ADDR] = AU1XXX_PHY1_IRQ; | 1155 | goto err_mdiobus_reg; |
1181 | # endif | 1156 | } |
1182 | #endif | ||
1183 | mdiobus_register(aup->mii_bus); | ||
1184 | 1157 | ||
1185 | if (mii_probe(dev) != 0) { | 1158 | if (mii_probe(dev) != 0) |
1186 | goto err_out; | 1159 | goto err_out; |
1187 | } | ||
1188 | 1160 | ||
1189 | pDBfree = NULL; | 1161 | pDBfree = NULL; |
1190 | /* setup the data buffer descriptors and attach a buffer to each one */ | 1162 | /* setup the data buffer descriptors and attach a buffer to each one */ |
@@ -1216,19 +1188,35 @@ static struct net_device * au1000_probe(int port_num) | |||
1216 | aup->tx_db_inuse[i] = pDB; | 1188 | aup->tx_db_inuse[i] = pDB; |
1217 | } | 1189 | } |
1218 | 1190 | ||
1191 | dev->base_addr = base->start; | ||
1192 | dev->irq = irq; | ||
1193 | dev->netdev_ops = &au1000_netdev_ops; | ||
1194 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1195 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1196 | |||
1219 | /* | 1197 | /* |
1220 | * The boot code uses the ethernet controller, so reset it to start | 1198 | * The boot code uses the ethernet controller, so reset it to start |
1221 | * fresh. au1000_init() expects that the device is in reset state. | 1199 | * fresh. au1000_init() expects that the device is in reset state. |
1222 | */ | 1200 | */ |
1223 | reset_mac(dev); | 1201 | reset_mac(dev); |
1224 | 1202 | ||
1225 | return dev; | 1203 | err = register_netdev(dev); |
1204 | if (err) { | ||
1205 | printk(KERN_ERR DRV_NAME "%s: Cannot register net device, aborting.\n", | ||
1206 | dev->name); | ||
1207 | goto err_out; | ||
1208 | } | ||
1209 | |||
1210 | printk("%s: Au1xx0 Ethernet found at 0x%lx, irq %d\n", | ||
1211 | dev->name, (unsigned long)base->start, irq); | ||
1212 | if (version_printed++ == 0) | ||
1213 | printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); | ||
1214 | |||
1215 | return 0; | ||
1226 | 1216 | ||
1227 | err_out: | 1217 | err_out: |
1228 | if (aup->mii_bus != NULL) { | 1218 | if (aup->mii_bus != NULL) |
1229 | mdiobus_unregister(aup->mii_bus); | 1219 | mdiobus_unregister(aup->mii_bus); |
1230 | mdiobus_free(aup->mii_bus); | ||
1231 | } | ||
1232 | 1220 | ||
1233 | /* here we should have a valid dev plus aup-> register addresses | 1221 | /* here we should have a valid dev plus aup-> register addresses |
1234 | * so we can reset the mac properly.*/ | 1222 | * so we can reset the mac properly.*/ |
@@ -1242,67 +1230,84 @@ err_out: | |||
1242 | if (aup->tx_db_inuse[i]) | 1230 | if (aup->tx_db_inuse[i]) |
1243 | ReleaseDB(aup, aup->tx_db_inuse[i]); | 1231 | ReleaseDB(aup, aup->tx_db_inuse[i]); |
1244 | } | 1232 | } |
1233 | err_mdiobus_reg: | ||
1234 | mdiobus_free(aup->mii_bus); | ||
1235 | err_mdiobus_alloc: | ||
1236 | iounmap(aup->enable); | ||
1237 | err_remap2: | ||
1238 | iounmap(aup->mac); | ||
1239 | err_remap1: | ||
1245 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), | 1240 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), |
1246 | (void *)aup->vaddr, aup->dma_addr); | 1241 | (void *)aup->vaddr, aup->dma_addr); |
1247 | unregister_netdev(dev); | 1242 | err_vaddr: |
1248 | free_netdev(dev); | 1243 | free_netdev(dev); |
1249 | release_mem_region( base, MAC_IOSIZE); | 1244 | err_alloc: |
1250 | release_mem_region(macen, 4); | 1245 | release_mem_region(macen->start, resource_size(macen)); |
1251 | return NULL; | 1246 | err_request: |
1247 | release_mem_region(base->start, resource_size(base)); | ||
1248 | out: | ||
1249 | return err; | ||
1252 | } | 1250 | } |
1253 | 1251 | ||
1254 | /* | 1252 | static int __devexit au1000_remove(struct platform_device *pdev) |
1255 | * Setup the base address and interrupt of the Au1xxx ethernet macs | ||
1256 | * based on cpu type and whether the interface is enabled in sys_pinfunc | ||
1257 | * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0. | ||
1258 | */ | ||
1259 | static int __init au1000_init_module(void) | ||
1260 | { | 1253 | { |
1261 | int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4); | 1254 | struct net_device *dev = platform_get_drvdata(pdev); |
1262 | struct net_device *dev; | 1255 | struct au1000_private *aup = netdev_priv(dev); |
1263 | int i, found_one = 0; | 1256 | int i; |
1257 | struct resource *base, *macen; | ||
1264 | 1258 | ||
1265 | num_ifs = NUM_ETH_INTERFACES - ni; | 1259 | platform_set_drvdata(pdev, NULL); |
1260 | |||
1261 | unregister_netdev(dev); | ||
1262 | mdiobus_unregister(aup->mii_bus); | ||
1263 | mdiobus_free(aup->mii_bus); | ||
1264 | |||
1265 | for (i = 0; i < NUM_RX_DMA; i++) | ||
1266 | if (aup->rx_db_inuse[i]) | ||
1267 | ReleaseDB(aup, aup->rx_db_inuse[i]); | ||
1268 | |||
1269 | for (i = 0; i < NUM_TX_DMA; i++) | ||
1270 | if (aup->tx_db_inuse[i]) | ||
1271 | ReleaseDB(aup, aup->tx_db_inuse[i]); | ||
1272 | |||
1273 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * | ||
1274 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1275 | (void *)aup->vaddr, aup->dma_addr); | ||
1276 | |||
1277 | iounmap(aup->mac); | ||
1278 | iounmap(aup->enable); | ||
1279 | |||
1280 | base = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1281 | release_mem_region(base->start, resource_size(base)); | ||
1282 | |||
1283 | macen = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
1284 | release_mem_region(macen->start, resource_size(macen)); | ||
1285 | |||
1286 | free_netdev(dev); | ||
1266 | 1287 | ||
1267 | for(i = 0; i < num_ifs; i++) { | ||
1268 | dev = au1000_probe(i); | ||
1269 | iflist[i].dev = dev; | ||
1270 | if (dev) | ||
1271 | found_one++; | ||
1272 | } | ||
1273 | if (!found_one) | ||
1274 | return -ENODEV; | ||
1275 | return 0; | 1288 | return 0; |
1276 | } | 1289 | } |
1277 | 1290 | ||
1278 | static void __exit au1000_cleanup_module(void) | 1291 | static struct platform_driver au1000_eth_driver = { |
1292 | .probe = au1000_probe, | ||
1293 | .remove = __devexit_p(au1000_remove), | ||
1294 | .driver = { | ||
1295 | .name = "au1000-eth", | ||
1296 | .owner = THIS_MODULE, | ||
1297 | }, | ||
1298 | }; | ||
1299 | MODULE_ALIAS("platform:au1000-eth"); | ||
1300 | |||
1301 | |||
1302 | static int __init au1000_init_module(void) | ||
1303 | { | ||
1304 | return platform_driver_register(&au1000_eth_driver); | ||
1305 | } | ||
1306 | |||
1307 | static void __exit au1000_exit_module(void) | ||
1279 | { | 1308 | { |
1280 | int i, j; | 1309 | platform_driver_unregister(&au1000_eth_driver); |
1281 | struct net_device *dev; | ||
1282 | struct au1000_private *aup; | ||
1283 | |||
1284 | for (i = 0; i < num_ifs; i++) { | ||
1285 | dev = iflist[i].dev; | ||
1286 | if (dev) { | ||
1287 | aup = netdev_priv(dev); | ||
1288 | unregister_netdev(dev); | ||
1289 | mdiobus_unregister(aup->mii_bus); | ||
1290 | mdiobus_free(aup->mii_bus); | ||
1291 | for (j = 0; j < NUM_RX_DMA; j++) | ||
1292 | if (aup->rx_db_inuse[j]) | ||
1293 | ReleaseDB(aup, aup->rx_db_inuse[j]); | ||
1294 | for (j = 0; j < NUM_TX_DMA; j++) | ||
1295 | if (aup->tx_db_inuse[j]) | ||
1296 | ReleaseDB(aup, aup->tx_db_inuse[j]); | ||
1297 | dma_free_noncoherent(NULL, MAX_BUF_SIZE * | ||
1298 | (NUM_TX_BUFFS + NUM_RX_BUFFS), | ||
1299 | (void *)aup->vaddr, aup->dma_addr); | ||
1300 | release_mem_region(dev->base_addr, MAC_IOSIZE); | ||
1301 | release_mem_region(CPHYSADDR(iflist[i].macen_addr), 4); | ||
1302 | free_netdev(dev); | ||
1303 | } | ||
1304 | } | ||
1305 | } | 1310 | } |
1306 | 1311 | ||
1307 | module_init(au1000_init_module); | 1312 | module_init(au1000_init_module); |
1308 | module_exit(au1000_cleanup_module); | 1313 | module_exit(au1000_exit_module); |