diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/myri_sbus.c | 116 | ||||
-rw-r--r-- | drivers/net/myri_sbus.h | 1 | ||||
-rw-r--r-- | drivers/net/sunbmac.c | 127 | ||||
-rw-r--r-- | drivers/net/sunbmac.h | 1 | ||||
-rw-r--r-- | drivers/net/sungem.c | 19 | ||||
-rw-r--r-- | drivers/net/sunhme.c | 417 | ||||
-rw-r--r-- | drivers/net/sunhme.h | 1 | ||||
-rw-r--r-- | drivers/net/sunlance.c | 173 | ||||
-rw-r--r-- | drivers/net/sunqe.c | 468 | ||||
-rw-r--r-- | drivers/net/tg3.c | 10 | ||||
-rw-r--r-- | drivers/net/tulip/tulip_core.c | 12 |
11 files changed, 673 insertions, 672 deletions
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 6c86dca62e2a..d9f616fea3d9 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* myri_sbus.h: MyriCOM MyriNET SBUS card driver. | 1 | /* myri_sbus.c: MyriCOM MyriNET SBUS card driver. |
2 | * | 2 | * |
3 | * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) | 3 | * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | static char version[] = | 6 | static char version[] = |
7 | "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n"; | 7 | "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n"; |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
@@ -81,10 +81,6 @@ static char version[] = | |||
81 | #define DHDR(x) | 81 | #define DHDR(x) |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | #ifdef MODULE | ||
85 | static struct myri_eth *root_myri_dev; | ||
86 | #endif | ||
87 | |||
88 | static void myri_reset_off(void __iomem *lp, void __iomem *cregs) | 84 | static void myri_reset_off(void __iomem *lp, void __iomem *cregs) |
89 | { | 85 | { |
90 | /* Clear IRQ mask. */ | 86 | /* Clear IRQ mask. */ |
@@ -896,8 +892,9 @@ static void dump_eeprom(struct myri_eth *mp) | |||
896 | } | 892 | } |
897 | #endif | 893 | #endif |
898 | 894 | ||
899 | static int __init myri_ether_init(struct sbus_dev *sdev, int num) | 895 | static int __init myri_ether_init(struct sbus_dev *sdev) |
900 | { | 896 | { |
897 | static int num; | ||
901 | static unsigned version_printed; | 898 | static unsigned version_printed; |
902 | struct net_device *dev; | 899 | struct net_device *dev; |
903 | struct myri_eth *mp; | 900 | struct myri_eth *mp; |
@@ -913,6 +910,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num) | |||
913 | if (version_printed++ == 0) | 910 | if (version_printed++ == 0) |
914 | printk(version); | 911 | printk(version); |
915 | 912 | ||
913 | SET_MODULE_OWNER(dev); | ||
914 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
915 | |||
916 | mp = (struct myri_eth *) dev->priv; | 916 | mp = (struct myri_eth *) dev->priv; |
917 | spin_lock_init(&mp->irq_lock); | 917 | spin_lock_init(&mp->irq_lock); |
918 | mp->myri_sdev = sdev; | 918 | mp->myri_sdev = sdev; |
@@ -1092,10 +1092,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num) | |||
1092 | goto err_free_irq; | 1092 | goto err_free_irq; |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | #ifdef MODULE | 1095 | dev_set_drvdata(&sdev->ofdev.dev, mp); |
1096 | mp->next_module = root_myri_dev; | 1096 | |
1097 | root_myri_dev = mp; | 1097 | num++; |
1098 | #endif | ||
1099 | 1098 | ||
1100 | printk("%s: MyriCOM MyriNET Ethernet ", dev->name); | 1099 | printk("%s: MyriCOM MyriNET Ethernet ", dev->name); |
1101 | 1100 | ||
@@ -1114,61 +1113,68 @@ err: | |||
1114 | return -ENODEV; | 1113 | return -ENODEV; |
1115 | } | 1114 | } |
1116 | 1115 | ||
1117 | static int __init myri_sbus_match(struct sbus_dev *sdev) | ||
1118 | { | ||
1119 | char *name = sdev->prom_name; | ||
1120 | 1116 | ||
1121 | if (!strcmp(name, "MYRICOM,mlanai") || | 1117 | static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match) |
1122 | !strcmp(name, "myri")) | 1118 | { |
1123 | return 1; | 1119 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
1124 | 1120 | ||
1125 | return 0; | 1121 | return myri_ether_init(sdev); |
1126 | } | 1122 | } |
1127 | 1123 | ||
1128 | static int __init myri_sbus_probe(void) | 1124 | static int __devexit myri_sbus_remove(struct of_device *dev) |
1129 | { | 1125 | { |
1130 | struct sbus_bus *bus; | 1126 | struct myri_eth *mp = dev_get_drvdata(&dev->dev); |
1131 | struct sbus_dev *sdev = NULL; | 1127 | struct net_device *net_dev = mp->dev; |
1132 | static int called; | ||
1133 | int cards = 0, v; | ||
1134 | 1128 | ||
1135 | #ifdef MODULE | 1129 | unregister_netdevice(net_dev); |
1136 | root_myri_dev = NULL; | ||
1137 | #endif | ||
1138 | 1130 | ||
1139 | if (called) | 1131 | free_irq(net_dev->irq, net_dev); |
1140 | return -ENODEV; | 1132 | |
1141 | called++; | 1133 | if (mp->eeprom.cpuvers < CPUVERS_4_0) { |
1142 | 1134 | sbus_iounmap(mp->regs, mp->reg_size); | |
1143 | for_each_sbus(bus) { | 1135 | } else { |
1144 | for_each_sbusdev(sdev, bus) { | 1136 | sbus_iounmap(mp->cregs, PAGE_SIZE); |
1145 | if (myri_sbus_match(sdev)) { | 1137 | sbus_iounmap(mp->lregs, (256 * 1024)); |
1146 | cards++; | 1138 | sbus_iounmap(mp->lanai, (512 * 1024)); |
1147 | DET(("Found myricom myrinet as %s\n", sdev->prom_name)); | ||
1148 | if ((v = myri_ether_init(sdev, (cards - 1)))) | ||
1149 | return v; | ||
1150 | } | ||
1151 | } | ||
1152 | } | 1139 | } |
1153 | if (!cards) | 1140 | |
1154 | return -ENODEV; | 1141 | free_netdev(net_dev); |
1142 | |||
1143 | dev_set_drvdata(&dev->dev, NULL); | ||
1144 | |||
1155 | return 0; | 1145 | return 0; |
1156 | } | 1146 | } |
1157 | 1147 | ||
1158 | static void __exit myri_sbus_cleanup(void) | 1148 | static struct of_device_id myri_sbus_match[] = { |
1149 | { | ||
1150 | .name = "MYRICOM,mlanai", | ||
1151 | }, | ||
1152 | { | ||
1153 | .name = "myri", | ||
1154 | }, | ||
1155 | {}, | ||
1156 | }; | ||
1157 | |||
1158 | MODULE_DEVICE_TABLE(of, myri_sbus_match); | ||
1159 | |||
1160 | static struct of_platform_driver myri_sbus_driver = { | ||
1161 | .name = "myri", | ||
1162 | .match_table = myri_sbus_match, | ||
1163 | .probe = myri_sbus_probe, | ||
1164 | .remove = __devexit_p(myri_sbus_remove), | ||
1165 | }; | ||
1166 | |||
1167 | static int __init myri_sbus_init(void) | ||
1168 | { | ||
1169 | return of_register_driver(&myri_sbus_driver, &sbus_bus_type); | ||
1170 | } | ||
1171 | |||
1172 | static void __exit myri_sbus_exit(void) | ||
1159 | { | 1173 | { |
1160 | #ifdef MODULE | 1174 | of_unregister_driver(&myri_sbus_driver); |
1161 | while (root_myri_dev) { | ||
1162 | struct myri_eth *next = root_myri_dev->next_module; | ||
1163 | |||
1164 | unregister_netdev(root_myri_dev->dev); | ||
1165 | /* this will also free the co-allocated 'root_myri_dev' */ | ||
1166 | free_netdev(root_myri_dev->dev); | ||
1167 | root_myri_dev = next; | ||
1168 | } | ||
1169 | #endif /* MODULE */ | ||
1170 | } | 1175 | } |
1171 | 1176 | ||
1172 | module_init(myri_sbus_probe); | 1177 | module_init(myri_sbus_init); |
1173 | module_exit(myri_sbus_cleanup); | 1178 | module_exit(myri_sbus_exit); |
1179 | |||
1174 | MODULE_LICENSE("GPL"); | 1180 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h index 47722f708a41..2f69ef7cdccb 100644 --- a/drivers/net/myri_sbus.h +++ b/drivers/net/myri_sbus.h | |||
@@ -290,7 +290,6 @@ struct myri_eth { | |||
290 | unsigned int reg_size; /* Size of register space. */ | 290 | unsigned int reg_size; /* Size of register space. */ |
291 | unsigned int shmem_base; /* Offset to shared ram. */ | 291 | unsigned int shmem_base; /* Offset to shared ram. */ |
292 | struct sbus_dev *myri_sdev; /* Our SBUS device struct. */ | 292 | struct sbus_dev *myri_sdev; /* Our SBUS device struct. */ |
293 | struct myri_eth *next_module; /* Next in adapter chain. */ | ||
294 | }; | 293 | }; |
295 | 294 | ||
296 | /* We use this to acquire receive skb's that we can DMA directly into. */ | 295 | /* We use this to acquire receive skb's that we can DMA directly into. */ |
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index cfaf47c63c58..7127f0f36f0e 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c | |||
@@ -72,8 +72,6 @@ MODULE_LICENSE("GPL"); | |||
72 | #define DIRQ(x) | 72 | #define DIRQ(x) |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | static struct bigmac *root_bigmac_dev; | ||
76 | |||
77 | #define DEFAULT_JAMSIZE 4 /* Toe jam */ | 75 | #define DEFAULT_JAMSIZE 4 /* Toe jam */ |
78 | 76 | ||
79 | #define QEC_RESET_TRIES 200 | 77 | #define QEC_RESET_TRIES 200 |
@@ -491,7 +489,7 @@ static void bigmac_tcvr_init(struct bigmac *bp) | |||
491 | } | 489 | } |
492 | } | 490 | } |
493 | 491 | ||
494 | static int bigmac_init(struct bigmac *, int); | 492 | static int bigmac_init_hw(struct bigmac *, int); |
495 | 493 | ||
496 | static int try_next_permutation(struct bigmac *bp, void __iomem *tregs) | 494 | static int try_next_permutation(struct bigmac *bp, void __iomem *tregs) |
497 | { | 495 | { |
@@ -551,7 +549,7 @@ static void bigmac_timer(unsigned long data) | |||
551 | if (ret == -1) { | 549 | if (ret == -1) { |
552 | printk(KERN_ERR "%s: Link down, cable problem?\n", | 550 | printk(KERN_ERR "%s: Link down, cable problem?\n", |
553 | bp->dev->name); | 551 | bp->dev->name); |
554 | ret = bigmac_init(bp, 0); | 552 | ret = bigmac_init_hw(bp, 0); |
555 | if (ret) { | 553 | if (ret) { |
556 | printk(KERN_ERR "%s: Error, cannot re-init the " | 554 | printk(KERN_ERR "%s: Error, cannot re-init the " |
557 | "BigMAC.\n", bp->dev->name); | 555 | "BigMAC.\n", bp->dev->name); |
@@ -621,7 +619,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp) | |||
621 | add_timer(&bp->bigmac_timer); | 619 | add_timer(&bp->bigmac_timer); |
622 | } | 620 | } |
623 | 621 | ||
624 | static int bigmac_init(struct bigmac *bp, int from_irq) | 622 | static int bigmac_init_hw(struct bigmac *bp, int from_irq) |
625 | { | 623 | { |
626 | void __iomem *gregs = bp->gregs; | 624 | void __iomem *gregs = bp->gregs; |
627 | void __iomem *cregs = bp->creg; | 625 | void __iomem *cregs = bp->creg; |
@@ -752,7 +750,7 @@ static void bigmac_is_medium_rare(struct bigmac *bp, u32 qec_status, u32 bmac_st | |||
752 | } | 750 | } |
753 | 751 | ||
754 | printk(" RESET\n"); | 752 | printk(" RESET\n"); |
755 | bigmac_init(bp, 1); | 753 | bigmac_init_hw(bp, 1); |
756 | } | 754 | } |
757 | 755 | ||
758 | /* BigMAC transmit complete service routines. */ | 756 | /* BigMAC transmit complete service routines. */ |
@@ -926,7 +924,7 @@ static int bigmac_open(struct net_device *dev) | |||
926 | return ret; | 924 | return ret; |
927 | } | 925 | } |
928 | init_timer(&bp->bigmac_timer); | 926 | init_timer(&bp->bigmac_timer); |
929 | ret = bigmac_init(bp, 0); | 927 | ret = bigmac_init_hw(bp, 0); |
930 | if (ret) | 928 | if (ret) |
931 | free_irq(dev->irq, bp); | 929 | free_irq(dev->irq, bp); |
932 | return ret; | 930 | return ret; |
@@ -950,7 +948,7 @@ static void bigmac_tx_timeout(struct net_device *dev) | |||
950 | { | 948 | { |
951 | struct bigmac *bp = (struct bigmac *) dev->priv; | 949 | struct bigmac *bp = (struct bigmac *) dev->priv; |
952 | 950 | ||
953 | bigmac_init(bp, 0); | 951 | bigmac_init_hw(bp, 0); |
954 | netif_wake_queue(dev); | 952 | netif_wake_queue(dev); |
955 | } | 953 | } |
956 | 954 | ||
@@ -1104,6 +1102,8 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) | |||
1104 | bp->qec_sdev = qec_sdev; | 1102 | bp->qec_sdev = qec_sdev; |
1105 | bp->bigmac_sdev = qec_sdev->child; | 1103 | bp->bigmac_sdev = qec_sdev->child; |
1106 | 1104 | ||
1105 | SET_NETDEV_DEV(dev, &bp->bigmac_sdev->ofdev.dev); | ||
1106 | |||
1107 | spin_lock_init(&bp->lock); | 1107 | spin_lock_init(&bp->lock); |
1108 | 1108 | ||
1109 | /* Verify the registers we expect, are actually there. */ | 1109 | /* Verify the registers we expect, are actually there. */ |
@@ -1226,11 +1226,7 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev) | |||
1226 | goto fail_and_cleanup; | 1226 | goto fail_and_cleanup; |
1227 | } | 1227 | } |
1228 | 1228 | ||
1229 | /* Put us into the list of instances attached for later driver | 1229 | dev_set_drvdata(&bp->bigmac_sdev->ofdev.dev, bp); |
1230 | * exit. | ||
1231 | */ | ||
1232 | bp->next_module = root_bigmac_dev; | ||
1233 | root_bigmac_dev = bp; | ||
1234 | 1230 | ||
1235 | printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name); | 1231 | printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name); |
1236 | for (i = 0; i < 6; i++) | 1232 | for (i = 0; i < 6; i++) |
@@ -1266,69 +1262,68 @@ fail_and_cleanup: | |||
1266 | /* QEC can be the parent of either QuadEthernet or | 1262 | /* QEC can be the parent of either QuadEthernet or |
1267 | * a BigMAC. We want the latter. | 1263 | * a BigMAC. We want the latter. |
1268 | */ | 1264 | */ |
1269 | static int __init bigmac_match(struct sbus_dev *sdev) | 1265 | static int __devinit bigmac_sbus_probe(struct of_device *dev, const struct of_device_id *match) |
1270 | { | 1266 | { |
1271 | struct sbus_dev *child = sdev->child; | 1267 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
1268 | struct device_node *dp = dev->node; | ||
1272 | 1269 | ||
1273 | if (strcmp(sdev->prom_name, "qec") != 0) | 1270 | if (!strcmp(dp->name, "be")) |
1274 | return 0; | 1271 | sdev = sdev->parent; |
1275 | 1272 | ||
1276 | if (child == NULL) | 1273 | return bigmac_ether_init(sdev); |
1277 | return 0; | ||
1278 | |||
1279 | if (strcmp(child->prom_name, "be") != 0) | ||
1280 | return 0; | ||
1281 | |||
1282 | return 1; | ||
1283 | } | 1274 | } |
1284 | 1275 | ||
1285 | static int __init bigmac_probe(void) | 1276 | static int __devexit bigmac_sbus_remove(struct of_device *dev) |
1286 | { | 1277 | { |
1287 | struct sbus_bus *sbus; | 1278 | struct bigmac *bp = dev_get_drvdata(&dev->dev); |
1288 | struct sbus_dev *sdev = NULL; | 1279 | struct net_device *net_dev = bp->dev; |
1289 | static int called; | 1280 | |
1290 | int cards = 0, v; | 1281 | unregister_netdevice(net_dev); |
1291 | 1282 | ||
1292 | root_bigmac_dev = NULL; | 1283 | sbus_iounmap(bp->gregs, GLOB_REG_SIZE); |
1293 | 1284 | sbus_iounmap(bp->creg, CREG_REG_SIZE); | |
1294 | if (called) | 1285 | sbus_iounmap(bp->bregs, BMAC_REG_SIZE); |
1295 | return -ENODEV; | 1286 | sbus_iounmap(bp->tregs, TCVR_REG_SIZE); |
1296 | called++; | 1287 | sbus_free_consistent(bp->bigmac_sdev, |
1297 | 1288 | PAGE_SIZE, | |
1298 | for_each_sbus(sbus) { | 1289 | bp->bmac_block, |
1299 | for_each_sbusdev(sdev, sbus) { | 1290 | bp->bblock_dvma); |
1300 | if (bigmac_match(sdev)) { | 1291 | |
1301 | cards++; | 1292 | free_netdev(net_dev); |
1302 | if ((v = bigmac_ether_init(sdev))) | 1293 | |
1303 | return v; | 1294 | dev_set_drvdata(&dev->dev, NULL); |
1304 | } | 1295 | |
1305 | } | ||
1306 | } | ||
1307 | if (!cards) | ||
1308 | return -ENODEV; | ||
1309 | return 0; | 1296 | return 0; |
1310 | } | 1297 | } |
1311 | 1298 | ||
1312 | static void __exit bigmac_cleanup(void) | 1299 | static struct of_device_id bigmac_sbus_match[] = { |
1313 | { | 1300 | { |
1314 | while (root_bigmac_dev) { | 1301 | .name = "qec", |
1315 | struct bigmac *bp = root_bigmac_dev; | 1302 | }, |
1316 | struct bigmac *bp_nxt = root_bigmac_dev->next_module; | 1303 | { |
1304 | .name = "be", | ||
1305 | }, | ||
1306 | {}, | ||
1307 | }; | ||
1317 | 1308 | ||
1318 | sbus_iounmap(bp->gregs, GLOB_REG_SIZE); | 1309 | MODULE_DEVICE_TABLE(of, bigmac_sbus_match); |
1319 | sbus_iounmap(bp->creg, CREG_REG_SIZE); | ||
1320 | sbus_iounmap(bp->bregs, BMAC_REG_SIZE); | ||
1321 | sbus_iounmap(bp->tregs, TCVR_REG_SIZE); | ||
1322 | sbus_free_consistent(bp->bigmac_sdev, | ||
1323 | PAGE_SIZE, | ||
1324 | bp->bmac_block, | ||
1325 | bp->bblock_dvma); | ||
1326 | 1310 | ||
1327 | unregister_netdev(bp->dev); | 1311 | static struct of_platform_driver bigmac_sbus_driver = { |
1328 | free_netdev(bp->dev); | 1312 | .name = "sunbmac", |
1329 | root_bigmac_dev = bp_nxt; | 1313 | .match_table = bigmac_sbus_match, |
1330 | } | 1314 | .probe = bigmac_sbus_probe, |
1315 | .remove = __devexit_p(bigmac_sbus_remove), | ||
1316 | }; | ||
1317 | |||
1318 | static int __init bigmac_init(void) | ||
1319 | { | ||
1320 | return of_register_driver(&bigmac_sbus_driver, &sbus_bus_type); | ||
1321 | } | ||
1322 | |||
1323 | static void __exit bigmac_exit(void) | ||
1324 | { | ||
1325 | of_unregister_driver(&bigmac_sbus_driver); | ||
1331 | } | 1326 | } |
1332 | 1327 | ||
1333 | module_init(bigmac_probe); | 1328 | module_init(bigmac_init); |
1334 | module_exit(bigmac_cleanup); | 1329 | module_exit(bigmac_exit); |
diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h index b0dbc5187143..b563d3c2993e 100644 --- a/drivers/net/sunbmac.h +++ b/drivers/net/sunbmac.h | |||
@@ -332,7 +332,6 @@ struct bigmac { | |||
332 | struct sbus_dev *qec_sdev; | 332 | struct sbus_dev *qec_sdev; |
333 | struct sbus_dev *bigmac_sdev; | 333 | struct sbus_dev *bigmac_sdev; |
334 | struct net_device *dev; | 334 | struct net_device *dev; |
335 | struct bigmac *next_module; | ||
336 | }; | 335 | }; |
337 | 336 | ||
338 | /* We use this to acquire receive skb's that we can DMA directly into. */ | 337 | /* We use this to acquire receive skb's that we can DMA directly into. */ |
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 38cd30cb7c75..5248670d29f7 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -2880,17 +2880,20 @@ static int __devinit gem_get_device_address(struct gem *gp) | |||
2880 | #if defined(__sparc__) | 2880 | #if defined(__sparc__) |
2881 | struct pci_dev *pdev = gp->pdev; | 2881 | struct pci_dev *pdev = gp->pdev; |
2882 | struct pcidev_cookie *pcp = pdev->sysdata; | 2882 | struct pcidev_cookie *pcp = pdev->sysdata; |
2883 | int node = -1; | 2883 | int use_idprom = 1; |
2884 | 2884 | ||
2885 | if (pcp != NULL) { | 2885 | if (pcp != NULL) { |
2886 | node = pcp->prom_node; | 2886 | unsigned char *addr; |
2887 | if (prom_getproplen(node, "local-mac-address") == 6) | 2887 | int len; |
2888 | prom_getproperty(node, "local-mac-address", | 2888 | |
2889 | dev->dev_addr, 6); | 2889 | addr = of_get_property(pcp->prom_node, "local-mac-address", |
2890 | else | 2890 | &len); |
2891 | node = -1; | 2891 | if (addr && len == 6) { |
2892 | use_idprom = 0; | ||
2893 | memcpy(dev->dev_addr, addr, 6); | ||
2894 | } | ||
2892 | } | 2895 | } |
2893 | if (node == -1) | 2896 | if (use_idprom) |
2894 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); | 2897 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); |
2895 | #elif defined(CONFIG_PPC_PMAC) | 2898 | #elif defined(CONFIG_PPC_PMAC) |
2896 | unsigned char *addr; | 2899 | unsigned char *addr; |
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index bd5d2668a362..c33ead3470db 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* $Id: sunhme.c,v 1.124 2002/01/15 06:25:51 davem Exp $ | 1 | /* sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, |
2 | * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching, | ||
3 | * auto carrier detecting ethernet driver. Also known as the | 2 | * auto carrier detecting ethernet driver. Also known as the |
4 | * "Happy Meal Ethernet" found on SunSwift SBUS cards. | 3 | * "Happy Meal Ethernet" found on SunSwift SBUS cards. |
5 | * | 4 | * |
6 | * Copyright (C) 1996, 1998, 1999, 2002, 2003 David S. Miller (davem@redhat.com) | 5 | * Copyright (C) 1996, 1998, 1999, 2002, 2003, |
6 | 2006 David S. Miller (davem@davemloft.net) | ||
7 | * | 7 | * |
8 | * Changes : | 8 | * Changes : |
9 | * 2000/11/11 Willy Tarreau <willy AT meta-x.org> | 9 | * 2000/11/11 Willy Tarreau <willy AT meta-x.org> |
@@ -40,15 +40,13 @@ | |||
40 | #include <asm/dma.h> | 40 | #include <asm/dma.h> |
41 | #include <asm/byteorder.h> | 41 | #include <asm/byteorder.h> |
42 | 42 | ||
43 | #ifdef __sparc__ | 43 | #ifdef CONFIG_SPARC |
44 | #include <asm/idprom.h> | 44 | #include <asm/idprom.h> |
45 | #include <asm/sbus.h> | 45 | #include <asm/sbus.h> |
46 | #include <asm/openprom.h> | 46 | #include <asm/openprom.h> |
47 | #include <asm/oplib.h> | 47 | #include <asm/oplib.h> |
48 | #include <asm/prom.h> | ||
48 | #include <asm/auxio.h> | 49 | #include <asm/auxio.h> |
49 | #ifndef __sparc_v9__ | ||
50 | #include <asm/io-unit.h> | ||
51 | #endif | ||
52 | #endif | 50 | #endif |
53 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
54 | 52 | ||
@@ -57,7 +55,7 @@ | |||
57 | 55 | ||
58 | #ifdef CONFIG_PCI | 56 | #ifdef CONFIG_PCI |
59 | #include <linux/pci.h> | 57 | #include <linux/pci.h> |
60 | #ifdef __sparc__ | 58 | #ifdef CONFIG_SPARC |
61 | #include <asm/pbm.h> | 59 | #include <asm/pbm.h> |
62 | #endif | 60 | #endif |
63 | #endif | 61 | #endif |
@@ -65,9 +63,9 @@ | |||
65 | #include "sunhme.h" | 63 | #include "sunhme.h" |
66 | 64 | ||
67 | #define DRV_NAME "sunhme" | 65 | #define DRV_NAME "sunhme" |
68 | #define DRV_VERSION "2.02" | 66 | #define DRV_VERSION "3.00" |
69 | #define DRV_RELDATE "8/24/03" | 67 | #define DRV_RELDATE "June 23, 2006" |
70 | #define DRV_AUTHOR "David S. Miller (davem@redhat.com)" | 68 | #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" |
71 | 69 | ||
72 | static char version[] = | 70 | static char version[] = |
73 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; | 71 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; |
@@ -83,8 +81,6 @@ static int macaddr[6]; | |||
83 | module_param_array(macaddr, int, NULL, 0); | 81 | module_param_array(macaddr, int, NULL, 0); |
84 | MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); | 82 | MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); |
85 | 83 | ||
86 | static struct happy_meal *root_happy_dev; | ||
87 | |||
88 | #ifdef CONFIG_SBUS | 84 | #ifdef CONFIG_SBUS |
89 | static struct quattro *qfe_sbus_list; | 85 | static struct quattro *qfe_sbus_list; |
90 | #endif | 86 | #endif |
@@ -181,26 +177,6 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp) | |||
181 | #define DEFAULT_IPG2 4 /* For all modes */ | 177 | #define DEFAULT_IPG2 4 /* For all modes */ |
182 | #define DEFAULT_JAMSIZE 4 /* Toe jam */ | 178 | #define DEFAULT_JAMSIZE 4 /* Toe jam */ |
183 | 179 | ||
184 | #if defined(CONFIG_PCI) && defined(MODULE) | ||
185 | /* This happy_pci_ids is declared __initdata because it is only used | ||
186 | as an advisory to depmod. If this is ported to the new PCI interface | ||
187 | where it could be referenced at any time due to hot plugging, | ||
188 | the __initdata reference should be removed. */ | ||
189 | |||
190 | static struct pci_device_id happymeal_pci_ids[] = { | ||
191 | { | ||
192 | .vendor = PCI_VENDOR_ID_SUN, | ||
193 | .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, | ||
194 | .subvendor = PCI_ANY_ID, | ||
195 | .subdevice = PCI_ANY_ID, | ||
196 | }, | ||
197 | { } /* Terminating entry */ | ||
198 | }; | ||
199 | |||
200 | MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); | ||
201 | |||
202 | #endif | ||
203 | |||
204 | /* NOTE: In the descriptor writes one _must_ write the address | 180 | /* NOTE: In the descriptor writes one _must_ write the address |
205 | * member _first_. The card must not be allowed to see | 181 | * member _first_. The card must not be allowed to see |
206 | * the updated descriptor flags until the address is | 182 | * the updated descriptor flags until the address is |
@@ -1610,7 +1586,7 @@ static int happy_meal_init(struct happy_meal *hp) | |||
1610 | HMD(("happy_meal_init: old[%08x] bursts<", | 1586 | HMD(("happy_meal_init: old[%08x] bursts<", |
1611 | hme_read32(hp, gregs + GREG_CFG))); | 1587 | hme_read32(hp, gregs + GREG_CFG))); |
1612 | 1588 | ||
1613 | #ifndef __sparc__ | 1589 | #ifndef CONFIG_SPARC |
1614 | /* It is always PCI and can handle 64byte bursts. */ | 1590 | /* It is always PCI and can handle 64byte bursts. */ |
1615 | hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); | 1591 | hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); |
1616 | #else | 1592 | #else |
@@ -1647,7 +1623,7 @@ static int happy_meal_init(struct happy_meal *hp) | |||
1647 | HMD(("XXX>")); | 1623 | HMD(("XXX>")); |
1648 | hme_write32(hp, gregs + GREG_CFG, 0); | 1624 | hme_write32(hp, gregs + GREG_CFG, 0); |
1649 | } | 1625 | } |
1650 | #endif /* __sparc__ */ | 1626 | #endif /* CONFIG_SPARC */ |
1651 | 1627 | ||
1652 | /* Turn off interrupts we do not want to hear. */ | 1628 | /* Turn off interrupts we do not want to hear. */ |
1653 | HMD((", enable global interrupts, ")); | 1629 | HMD((", enable global interrupts, ")); |
@@ -2592,14 +2568,10 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h | |||
2592 | */ | 2568 | */ |
2593 | static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) | 2569 | static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) |
2594 | { | 2570 | { |
2595 | struct sbus_bus *sbus; | ||
2596 | struct sbus_dev *sdev; | 2571 | struct sbus_dev *sdev; |
2597 | struct quattro *qp; | 2572 | struct quattro *qp; |
2598 | int i; | 2573 | int i; |
2599 | 2574 | ||
2600 | if (qfe_sbus_list == NULL) | ||
2601 | goto found; | ||
2602 | |||
2603 | for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { | 2575 | for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { |
2604 | for (i = 0, sdev = qp->quattro_dev; | 2576 | for (i = 0, sdev = qp->quattro_dev; |
2605 | (sdev != NULL) && (i < 4); | 2577 | (sdev != NULL) && (i < 4); |
@@ -2608,17 +2580,7 @@ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) | |||
2608 | return qp; | 2580 | return qp; |
2609 | } | 2581 | } |
2610 | } | 2582 | } |
2611 | for_each_sbus(sbus) { | ||
2612 | for_each_sbusdev(sdev, sbus) { | ||
2613 | if (sdev == goal_sdev) | ||
2614 | goto found; | ||
2615 | } | ||
2616 | } | ||
2617 | |||
2618 | /* Cannot find quattro parent, fail. */ | ||
2619 | return NULL; | ||
2620 | 2583 | ||
2621 | found: | ||
2622 | qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); | 2584 | qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); |
2623 | if (qp != NULL) { | 2585 | if (qp != NULL) { |
2624 | int i; | 2586 | int i; |
@@ -2655,6 +2617,17 @@ static void __init quattro_sbus_register_irqs(void) | |||
2655 | } | 2617 | } |
2656 | } | 2618 | } |
2657 | } | 2619 | } |
2620 | |||
2621 | static void __devexit quattro_sbus_free_irqs(void) | ||
2622 | { | ||
2623 | struct quattro *qp; | ||
2624 | |||
2625 | for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { | ||
2626 | struct sbus_dev *sdev = qp->quattro_dev; | ||
2627 | |||
2628 | free_irq(sdev->irqs[0], qp); | ||
2629 | } | ||
2630 | } | ||
2658 | #endif /* CONFIG_SBUS */ | 2631 | #endif /* CONFIG_SBUS */ |
2659 | 2632 | ||
2660 | #ifdef CONFIG_PCI | 2633 | #ifdef CONFIG_PCI |
@@ -2689,8 +2662,9 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev) | |||
2689 | #endif /* CONFIG_PCI */ | 2662 | #endif /* CONFIG_PCI */ |
2690 | 2663 | ||
2691 | #ifdef CONFIG_SBUS | 2664 | #ifdef CONFIG_SBUS |
2692 | static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | 2665 | static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe) |
2693 | { | 2666 | { |
2667 | struct device_node *dp = sdev->ofdev.node; | ||
2694 | struct quattro *qp = NULL; | 2668 | struct quattro *qp = NULL; |
2695 | struct happy_meal *hp; | 2669 | struct happy_meal *hp; |
2696 | struct net_device *dev; | 2670 | struct net_device *dev; |
@@ -2713,6 +2687,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2713 | if (!dev) | 2687 | if (!dev) |
2714 | goto err_out; | 2688 | goto err_out; |
2715 | SET_MODULE_OWNER(dev); | 2689 | SET_MODULE_OWNER(dev); |
2690 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
2716 | 2691 | ||
2717 | if (hme_version_printed++ == 0) | 2692 | if (hme_version_printed++ == 0) |
2718 | printk(KERN_INFO "%s", version); | 2693 | printk(KERN_INFO "%s", version); |
@@ -2728,13 +2703,16 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2728 | for (i = 0; i < 6; i++) | 2703 | for (i = 0; i < 6; i++) |
2729 | dev->dev_addr[i] = macaddr[i]; | 2704 | dev->dev_addr[i] = macaddr[i]; |
2730 | macaddr[5]++; | 2705 | macaddr[5]++; |
2731 | } else if (qfe_slot != -1 && | ||
2732 | prom_getproplen(sdev->prom_node, | ||
2733 | "local-mac-address") == 6) { | ||
2734 | prom_getproperty(sdev->prom_node, "local-mac-address", | ||
2735 | dev->dev_addr, 6); | ||
2736 | } else { | 2706 | } else { |
2737 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); | 2707 | unsigned char *addr; |
2708 | int len; | ||
2709 | |||
2710 | addr = of_get_property(dp, "local-mac-address", &len); | ||
2711 | |||
2712 | if (qfe_slot != -1 && addr && len == 6) | ||
2713 | memcpy(dev->dev_addr, addr, 6); | ||
2714 | else | ||
2715 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); | ||
2738 | } | 2716 | } |
2739 | 2717 | ||
2740 | hp = dev->priv; | 2718 | hp = dev->priv; |
@@ -2745,9 +2723,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2745 | 2723 | ||
2746 | err = -ENODEV; | 2724 | err = -ENODEV; |
2747 | if (sdev->num_registers != 5) { | 2725 | if (sdev->num_registers != 5) { |
2748 | printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", | 2726 | printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n", |
2749 | sdev->num_registers); | 2727 | sdev->num_registers); |
2750 | printk(KERN_ERR "happymeal: Would you like that for here or to go?\n"); | ||
2751 | goto err_out_free_netdev; | 2728 | goto err_out_free_netdev; |
2752 | } | 2729 | } |
2753 | 2730 | ||
@@ -2761,39 +2738,39 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2761 | hp->gregs = sbus_ioremap(&sdev->resource[0], 0, | 2738 | hp->gregs = sbus_ioremap(&sdev->resource[0], 0, |
2762 | GREG_REG_SIZE, "HME Global Regs"); | 2739 | GREG_REG_SIZE, "HME Global Regs"); |
2763 | if (!hp->gregs) { | 2740 | if (!hp->gregs) { |
2764 | printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); | 2741 | printk(KERN_ERR "happymeal: Cannot map global registers.\n"); |
2765 | goto err_out_free_netdev; | 2742 | goto err_out_free_netdev; |
2766 | } | 2743 | } |
2767 | 2744 | ||
2768 | hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, | 2745 | hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, |
2769 | ETX_REG_SIZE, "HME TX Regs"); | 2746 | ETX_REG_SIZE, "HME TX Regs"); |
2770 | if (!hp->etxregs) { | 2747 | if (!hp->etxregs) { |
2771 | printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); | 2748 | printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n"); |
2772 | goto err_out_iounmap; | 2749 | goto err_out_iounmap; |
2773 | } | 2750 | } |
2774 | 2751 | ||
2775 | hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, | 2752 | hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, |
2776 | ERX_REG_SIZE, "HME RX Regs"); | 2753 | ERX_REG_SIZE, "HME RX Regs"); |
2777 | if (!hp->erxregs) { | 2754 | if (!hp->erxregs) { |
2778 | printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); | 2755 | printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n"); |
2779 | goto err_out_iounmap; | 2756 | goto err_out_iounmap; |
2780 | } | 2757 | } |
2781 | 2758 | ||
2782 | hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, | 2759 | hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, |
2783 | BMAC_REG_SIZE, "HME BIGMAC Regs"); | 2760 | BMAC_REG_SIZE, "HME BIGMAC Regs"); |
2784 | if (!hp->bigmacregs) { | 2761 | if (!hp->bigmacregs) { |
2785 | printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); | 2762 | printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n"); |
2786 | goto err_out_iounmap; | 2763 | goto err_out_iounmap; |
2787 | } | 2764 | } |
2788 | 2765 | ||
2789 | hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, | 2766 | hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, |
2790 | TCVR_REG_SIZE, "HME Tranceiver Regs"); | 2767 | TCVR_REG_SIZE, "HME Tranceiver Regs"); |
2791 | if (!hp->tcvregs) { | 2768 | if (!hp->tcvregs) { |
2792 | printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); | 2769 | printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n"); |
2793 | goto err_out_iounmap; | 2770 | goto err_out_iounmap; |
2794 | } | 2771 | } |
2795 | 2772 | ||
2796 | hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); | 2773 | hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff); |
2797 | if (hp->hm_revision == 0xff) | 2774 | if (hp->hm_revision == 0xff) |
2798 | hp->hm_revision = 0xa0; | 2775 | hp->hm_revision = 0xa0; |
2799 | 2776 | ||
@@ -2807,8 +2784,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2807 | hp->happy_flags |= HFLAG_QUATTRO; | 2784 | hp->happy_flags |= HFLAG_QUATTRO; |
2808 | 2785 | ||
2809 | /* Get the supported DVMA burst sizes from our Happy SBUS. */ | 2786 | /* Get the supported DVMA burst sizes from our Happy SBUS. */ |
2810 | hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, | 2787 | hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node, |
2811 | "burst-sizes", 0x00); | 2788 | "burst-sizes", 0x00); |
2812 | 2789 | ||
2813 | hp->happy_block = sbus_alloc_consistent(hp->happy_dev, | 2790 | hp->happy_block = sbus_alloc_consistent(hp->happy_dev, |
2814 | PAGE_SIZE, | 2791 | PAGE_SIZE, |
@@ -2871,6 +2848,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2871 | goto err_out_free_consistent; | 2848 | goto err_out_free_consistent; |
2872 | } | 2849 | } |
2873 | 2850 | ||
2851 | dev_set_drvdata(&sdev->ofdev.dev, hp); | ||
2852 | |||
2874 | if (qfe_slot != -1) | 2853 | if (qfe_slot != -1) |
2875 | printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", | 2854 | printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", |
2876 | dev->name, qfe_slot); | 2855 | dev->name, qfe_slot); |
@@ -2883,12 +2862,6 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) | |||
2883 | dev->dev_addr[i], i == 5 ? ' ' : ':'); | 2862 | dev->dev_addr[i], i == 5 ? ' ' : ':'); |
2884 | printk("\n"); | 2863 | printk("\n"); |
2885 | 2864 | ||
2886 | /* We are home free at this point, link us in to the happy | ||
2887 | * device list. | ||
2888 | */ | ||
2889 | hp->next_module = root_happy_dev; | ||
2890 | root_happy_dev = hp; | ||
2891 | |||
2892 | return 0; | 2865 | return 0; |
2893 | 2866 | ||
2894 | err_out_free_consistent: | 2867 | err_out_free_consistent: |
@@ -2918,7 +2891,7 @@ err_out: | |||
2918 | #endif | 2891 | #endif |
2919 | 2892 | ||
2920 | #ifdef CONFIG_PCI | 2893 | #ifdef CONFIG_PCI |
2921 | #ifndef __sparc__ | 2894 | #ifndef CONFIG_SPARC |
2922 | static int is_quattro_p(struct pci_dev *pdev) | 2895 | static int is_quattro_p(struct pci_dev *pdev) |
2923 | { | 2896 | { |
2924 | struct pci_dev *busdev = pdev->bus->self; | 2897 | struct pci_dev *busdev = pdev->bus->self; |
@@ -3006,14 +2979,14 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr) | |||
3006 | get_random_bytes(&dev_addr[3], 3); | 2979 | get_random_bytes(&dev_addr[3], 3); |
3007 | return; | 2980 | return; |
3008 | } | 2981 | } |
3009 | #endif /* !(__sparc__) */ | 2982 | #endif /* !(CONFIG_SPARC) */ |
3010 | 2983 | ||
3011 | static int __init happy_meal_pci_init(struct pci_dev *pdev) | 2984 | static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, |
2985 | const struct pci_device_id *ent) | ||
3012 | { | 2986 | { |
3013 | struct quattro *qp = NULL; | 2987 | struct quattro *qp = NULL; |
3014 | #ifdef __sparc__ | 2988 | #ifdef CONFIG_SPARC |
3015 | struct pcidev_cookie *pcp; | 2989 | struct pcidev_cookie *pcp; |
3016 | int node; | ||
3017 | #endif | 2990 | #endif |
3018 | struct happy_meal *hp; | 2991 | struct happy_meal *hp; |
3019 | struct net_device *dev; | 2992 | struct net_device *dev; |
@@ -3024,15 +2997,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3024 | int err; | 2997 | int err; |
3025 | 2998 | ||
3026 | /* Now make sure pci_dev cookie is there. */ | 2999 | /* Now make sure pci_dev cookie is there. */ |
3027 | #ifdef __sparc__ | 3000 | #ifdef CONFIG_SPARC |
3028 | pcp = pdev->sysdata; | 3001 | pcp = pdev->sysdata; |
3029 | if (pcp == NULL || pcp->prom_node == -1) { | 3002 | if (pcp == NULL) { |
3030 | printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); | 3003 | printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); |
3031 | return -ENODEV; | 3004 | return -ENODEV; |
3032 | } | 3005 | } |
3033 | node = pcp->prom_node; | ||
3034 | 3006 | ||
3035 | prom_getstring(node, "name", prom_name, sizeof(prom_name)); | 3007 | strcpy(prom_name, pcp->prom_node->name); |
3036 | #else | 3008 | #else |
3037 | if (is_quattro_p(pdev)) | 3009 | if (is_quattro_p(pdev)) |
3038 | strcpy(prom_name, "SUNW,qfe"); | 3010 | strcpy(prom_name, "SUNW,qfe"); |
@@ -3103,11 +3075,15 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3103 | dev->dev_addr[i] = macaddr[i]; | 3075 | dev->dev_addr[i] = macaddr[i]; |
3104 | macaddr[5]++; | 3076 | macaddr[5]++; |
3105 | } else { | 3077 | } else { |
3106 | #ifdef __sparc__ | 3078 | #ifdef CONFIG_SPARC |
3079 | unsigned char *addr; | ||
3080 | int len; | ||
3081 | |||
3107 | if (qfe_slot != -1 && | 3082 | if (qfe_slot != -1 && |
3108 | prom_getproplen(node, "local-mac-address") == 6) { | 3083 | (addr = of_get_property(pcp->prom_node, |
3109 | prom_getproperty(node, "local-mac-address", | 3084 | "local-mac-address", &len)) != NULL |
3110 | dev->dev_addr, 6); | 3085 | && len == 6) { |
3086 | memcpy(dev->dev_addr, addr, 6); | ||
3111 | } else { | 3087 | } else { |
3112 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); | 3088 | memcpy(dev->dev_addr, idprom->id_ethaddr, 6); |
3113 | } | 3089 | } |
@@ -3123,8 +3099,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3123 | hp->bigmacregs = (hpreg_base + 0x6000UL); | 3099 | hp->bigmacregs = (hpreg_base + 0x6000UL); |
3124 | hp->tcvregs = (hpreg_base + 0x7000UL); | 3100 | hp->tcvregs = (hpreg_base + 0x7000UL); |
3125 | 3101 | ||
3126 | #ifdef __sparc__ | 3102 | #ifdef CONFIG_SPARC |
3127 | hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); | 3103 | hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff); |
3128 | if (hp->hm_revision == 0xff) { | 3104 | if (hp->hm_revision == 0xff) { |
3129 | unsigned char prev; | 3105 | unsigned char prev; |
3130 | 3106 | ||
@@ -3148,7 +3124,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3148 | /* And of course, indicate this is PCI. */ | 3124 | /* And of course, indicate this is PCI. */ |
3149 | hp->happy_flags |= HFLAG_PCI; | 3125 | hp->happy_flags |= HFLAG_PCI; |
3150 | 3126 | ||
3151 | #ifdef __sparc__ | 3127 | #ifdef CONFIG_SPARC |
3152 | /* Assume PCI happy meals can handle all burst sizes. */ | 3128 | /* Assume PCI happy meals can handle all burst sizes. */ |
3153 | hp->happy_bursts = DMA_BURSTBITS; | 3129 | hp->happy_bursts = DMA_BURSTBITS; |
3154 | #endif | 3130 | #endif |
@@ -3211,6 +3187,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3211 | goto err_out_iounmap; | 3187 | goto err_out_iounmap; |
3212 | } | 3188 | } |
3213 | 3189 | ||
3190 | dev_set_drvdata(&pdev->dev, hp); | ||
3191 | |||
3214 | if (!qfe_slot) { | 3192 | if (!qfe_slot) { |
3215 | struct pci_dev *qpdev = qp->quattro_dev; | 3193 | struct pci_dev *qpdev = qp->quattro_dev; |
3216 | 3194 | ||
@@ -3240,12 +3218,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) | |||
3240 | 3218 | ||
3241 | printk("\n"); | 3219 | printk("\n"); |
3242 | 3220 | ||
3243 | /* We are home free at this point, link us in to the happy | ||
3244 | * device list. | ||
3245 | */ | ||
3246 | hp->next_module = root_happy_dev; | ||
3247 | root_happy_dev = hp; | ||
3248 | |||
3249 | return 0; | 3221 | return 0; |
3250 | 3222 | ||
3251 | err_out_iounmap: | 3223 | err_out_iounmap: |
@@ -3263,136 +3235,146 @@ err_out_clear_quattro: | |||
3263 | err_out: | 3235 | err_out: |
3264 | return err; | 3236 | return err; |
3265 | } | 3237 | } |
3266 | #endif | ||
3267 | 3238 | ||
3268 | #ifdef CONFIG_SBUS | 3239 | static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) |
3269 | static int __init happy_meal_sbus_probe(void) | ||
3270 | { | 3240 | { |
3271 | struct sbus_bus *sbus; | 3241 | struct happy_meal *hp = dev_get_drvdata(&pdev->dev); |
3272 | struct sbus_dev *sdev; | 3242 | struct net_device *net_dev = hp->dev; |
3273 | int cards = 0; | 3243 | |
3274 | char model[128]; | 3244 | unregister_netdev(net_dev); |
3275 | 3245 | ||
3276 | for_each_sbus(sbus) { | 3246 | pci_free_consistent(hp->happy_dev, |
3277 | for_each_sbusdev(sdev, sbus) { | 3247 | PAGE_SIZE, |
3278 | char *name = sdev->prom_name; | 3248 | hp->happy_block, |
3279 | 3249 | hp->hblock_dvma); | |
3280 | if (!strcmp(name, "SUNW,hme")) { | 3250 | iounmap(hp->gregs); |
3281 | cards++; | 3251 | pci_release_regions(hp->happy_dev); |
3282 | prom_getstring(sdev->prom_node, "model", | 3252 | |
3283 | model, sizeof(model)); | 3253 | free_netdev(net_dev); |
3284 | if (!strcmp(model, "SUNW,sbus-qfe")) | 3254 | |
3285 | happy_meal_sbus_init(sdev, 1); | 3255 | dev_set_drvdata(&pdev->dev, NULL); |
3286 | else | ||
3287 | happy_meal_sbus_init(sdev, 0); | ||
3288 | } else if (!strcmp(name, "qfe") || | ||
3289 | !strcmp(name, "SUNW,qfe")) { | ||
3290 | cards++; | ||
3291 | happy_meal_sbus_init(sdev, 1); | ||
3292 | } | ||
3293 | } | ||
3294 | } | ||
3295 | if (cards != 0) | ||
3296 | quattro_sbus_register_irqs(); | ||
3297 | return cards; | ||
3298 | } | 3256 | } |
3299 | #endif | ||
3300 | 3257 | ||
3301 | #ifdef CONFIG_PCI | 3258 | static struct pci_device_id happymeal_pci_ids[] = { |
3302 | static int __init happy_meal_pci_probe(void) | 3259 | { |
3260 | .vendor = PCI_VENDOR_ID_SUN, | ||
3261 | .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, | ||
3262 | .subvendor = PCI_ANY_ID, | ||
3263 | .subdevice = PCI_ANY_ID, | ||
3264 | }, | ||
3265 | { } /* Terminating entry */ | ||
3266 | }; | ||
3267 | |||
3268 | MODULE_DEVICE_TABLE(pci, happymeal_pci_ids); | ||
3269 | |||
3270 | static struct pci_driver hme_pci_driver = { | ||
3271 | .name = "hme", | ||
3272 | .id_table = happymeal_pci_ids, | ||
3273 | .probe = happy_meal_pci_probe, | ||
3274 | .remove = __devexit_p(happy_meal_pci_remove), | ||
3275 | }; | ||
3276 | |||
3277 | static int __init happy_meal_pci_init(void) | ||
3303 | { | 3278 | { |
3304 | struct pci_dev *pdev = NULL; | 3279 | return pci_module_init(&hme_pci_driver); |
3305 | int cards = 0; | 3280 | } |
3306 | 3281 | ||
3307 | while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, | 3282 | static void happy_meal_pci_exit(void) |
3308 | PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { | 3283 | { |
3309 | if (pci_enable_device(pdev)) | 3284 | pci_unregister_driver(&hme_pci_driver); |
3310 | continue; | 3285 | |
3311 | pci_set_master(pdev); | 3286 | while (qfe_pci_list) { |
3312 | cards++; | 3287 | struct quattro *qfe = qfe_pci_list; |
3313 | happy_meal_pci_init(pdev); | 3288 | struct quattro *next = qfe->next; |
3289 | |||
3290 | kfree(qfe); | ||
3291 | |||
3292 | qfe_pci_list = next; | ||
3314 | } | 3293 | } |
3315 | return cards; | ||
3316 | } | 3294 | } |
3295 | |||
3317 | #endif | 3296 | #endif |
3318 | 3297 | ||
3319 | static int __init happy_meal_probe(void) | 3298 | #ifdef CONFIG_SBUS |
3299 | static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match) | ||
3320 | { | 3300 | { |
3321 | static int called = 0; | 3301 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
3322 | int cards; | 3302 | struct device_node *dp = dev->node; |
3303 | char *model = of_get_property(dp, "model", NULL); | ||
3304 | int is_qfe = (match->data != NULL); | ||
3323 | 3305 | ||
3324 | root_happy_dev = NULL; | 3306 | if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) |
3307 | is_qfe = 1; | ||
3325 | 3308 | ||
3326 | if (called) | 3309 | return happy_meal_sbus_probe_one(sdev, is_qfe); |
3327 | return -ENODEV; | 3310 | } |
3328 | called++; | 3311 | |
3312 | static int __devexit hme_sbus_remove(struct of_device *dev) | ||
3313 | { | ||
3314 | struct happy_meal *hp = dev_get_drvdata(&dev->dev); | ||
3315 | struct net_device *net_dev = hp->dev; | ||
3316 | |||
3317 | unregister_netdevice(net_dev); | ||
3318 | |||
3319 | /* XXX qfe parent interrupt... */ | ||
3320 | |||
3321 | sbus_iounmap(hp->gregs, GREG_REG_SIZE); | ||
3322 | sbus_iounmap(hp->etxregs, ETX_REG_SIZE); | ||
3323 | sbus_iounmap(hp->erxregs, ERX_REG_SIZE); | ||
3324 | sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); | ||
3325 | sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); | ||
3326 | sbus_free_consistent(hp->happy_dev, | ||
3327 | PAGE_SIZE, | ||
3328 | hp->happy_block, | ||
3329 | hp->hblock_dvma); | ||
3330 | |||
3331 | free_netdev(net_dev); | ||
3332 | |||
3333 | dev_set_drvdata(&dev->dev, NULL); | ||
3329 | 3334 | ||
3330 | cards = 0; | ||
3331 | #ifdef CONFIG_SBUS | ||
3332 | cards += happy_meal_sbus_probe(); | ||
3333 | #endif | ||
3334 | #ifdef CONFIG_PCI | ||
3335 | cards += happy_meal_pci_probe(); | ||
3336 | #endif | ||
3337 | if (!cards) | ||
3338 | return -ENODEV; | ||
3339 | return 0; | 3335 | return 0; |
3340 | } | 3336 | } |
3341 | 3337 | ||
3338 | static struct of_device_id hme_sbus_match[] = { | ||
3339 | { | ||
3340 | .name = "SUNW,hme", | ||
3341 | }, | ||
3342 | { | ||
3343 | .name = "SUNW,qfe", | ||
3344 | .data = (void *) 1, | ||
3345 | }, | ||
3346 | { | ||
3347 | .name = "qfe", | ||
3348 | .data = (void *) 1, | ||
3349 | }, | ||
3350 | {}, | ||
3351 | }; | ||
3342 | 3352 | ||
3343 | static void __exit happy_meal_cleanup_module(void) | 3353 | MODULE_DEVICE_TABLE(of, hme_sbus_match); |
3344 | { | ||
3345 | #ifdef CONFIG_SBUS | ||
3346 | struct quattro *last_seen_qfe = NULL; | ||
3347 | #endif | ||
3348 | 3354 | ||
3349 | while (root_happy_dev) { | 3355 | static struct of_platform_driver hme_sbus_driver = { |
3350 | struct happy_meal *hp = root_happy_dev; | 3356 | .name = "hme", |
3351 | struct happy_meal *next = root_happy_dev->next_module; | 3357 | .match_table = hme_sbus_match, |
3352 | struct net_device *dev = hp->dev; | 3358 | .probe = hme_sbus_probe, |
3359 | .remove = __devexit_p(hme_sbus_remove), | ||
3360 | }; | ||
3353 | 3361 | ||
3354 | /* Unregister netdev before unmapping registers as this | 3362 | static int __init happy_meal_sbus_init(void) |
3355 | * call can end up trying to access those registers. | 3363 | { |
3356 | */ | 3364 | int err; |
3357 | unregister_netdev(dev); | ||
3358 | 3365 | ||
3359 | #ifdef CONFIG_SBUS | 3366 | err = of_register_driver(&hme_sbus_driver, &sbus_bus_type); |
3360 | if (!(hp->happy_flags & HFLAG_PCI)) { | 3367 | if (!err) |
3361 | if (hp->happy_flags & HFLAG_QUATTRO) { | 3368 | quattro_sbus_register_irqs(); |
3362 | if (hp->qfe_parent != last_seen_qfe) { | ||
3363 | free_irq(dev->irq, hp->qfe_parent); | ||
3364 | last_seen_qfe = hp->qfe_parent; | ||
3365 | } | ||
3366 | } | ||
3367 | 3369 | ||
3368 | sbus_iounmap(hp->gregs, GREG_REG_SIZE); | 3370 | return err; |
3369 | sbus_iounmap(hp->etxregs, ETX_REG_SIZE); | 3371 | } |
3370 | sbus_iounmap(hp->erxregs, ERX_REG_SIZE); | ||
3371 | sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE); | ||
3372 | sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE); | ||
3373 | sbus_free_consistent(hp->happy_dev, | ||
3374 | PAGE_SIZE, | ||
3375 | hp->happy_block, | ||
3376 | hp->hblock_dvma); | ||
3377 | } | ||
3378 | #endif | ||
3379 | #ifdef CONFIG_PCI | ||
3380 | if ((hp->happy_flags & HFLAG_PCI)) { | ||
3381 | pci_free_consistent(hp->happy_dev, | ||
3382 | PAGE_SIZE, | ||
3383 | hp->happy_block, | ||
3384 | hp->hblock_dvma); | ||
3385 | iounmap(hp->gregs); | ||
3386 | pci_release_regions(hp->happy_dev); | ||
3387 | } | ||
3388 | #endif | ||
3389 | free_netdev(dev); | ||
3390 | 3372 | ||
3391 | root_happy_dev = next; | 3373 | static void happy_meal_sbus_exit(void) |
3392 | } | 3374 | { |
3375 | of_unregister_driver(&hme_sbus_driver); | ||
3376 | quattro_sbus_free_irqs(); | ||
3393 | 3377 | ||
3394 | /* Now cleanup the quattro lists. */ | ||
3395 | #ifdef CONFIG_SBUS | ||
3396 | while (qfe_sbus_list) { | 3378 | while (qfe_sbus_list) { |
3397 | struct quattro *qfe = qfe_sbus_list; | 3379 | struct quattro *qfe = qfe_sbus_list; |
3398 | struct quattro *next = qfe->next; | 3380 | struct quattro *next = qfe->next; |
@@ -3401,18 +3383,39 @@ static void __exit happy_meal_cleanup_module(void) | |||
3401 | 3383 | ||
3402 | qfe_sbus_list = next; | 3384 | qfe_sbus_list = next; |
3403 | } | 3385 | } |
3386 | } | ||
3404 | #endif | 3387 | #endif |
3405 | #ifdef CONFIG_PCI | ||
3406 | while (qfe_pci_list) { | ||
3407 | struct quattro *qfe = qfe_pci_list; | ||
3408 | struct quattro *next = qfe->next; | ||
3409 | 3388 | ||
3410 | kfree(qfe); | 3389 | static int __init happy_meal_probe(void) |
3390 | { | ||
3391 | int err = 0; | ||
3411 | 3392 | ||
3412 | qfe_pci_list = next; | 3393 | #ifdef CONFIG_SBUS |
3394 | err = happy_meal_sbus_init(); | ||
3395 | #endif | ||
3396 | #ifdef CONFIG_PCI | ||
3397 | if (!err) { | ||
3398 | err = happy_meal_pci_init(); | ||
3399 | #ifdef CONFIG_SBUS | ||
3400 | if (err) | ||
3401 | happy_meal_sbus_exit(); | ||
3402 | #endif | ||
3413 | } | 3403 | } |
3414 | #endif | 3404 | #endif |
3405 | |||
3406 | return err; | ||
3407 | } | ||
3408 | |||
3409 | |||
3410 | static void __exit happy_meal_exit(void) | ||
3411 | { | ||
3412 | #ifdef CONFIG_SBUS | ||
3413 | happy_meal_sbus_exit(); | ||
3414 | #endif | ||
3415 | #ifdef CONFIG_PCI | ||
3416 | happy_meal_pci_exit(); | ||
3417 | #endif | ||
3415 | } | 3418 | } |
3416 | 3419 | ||
3417 | module_init(happy_meal_probe); | 3420 | module_init(happy_meal_probe); |
3418 | module_exit(happy_meal_cleanup_module); | 3421 | module_exit(happy_meal_exit); |
diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h index 34e9f953cea4..9b7ccaeeee89 100644 --- a/drivers/net/sunhme.h +++ b/drivers/net/sunhme.h | |||
@@ -461,7 +461,6 @@ struct happy_meal { | |||
461 | struct net_device *dev; /* Backpointer */ | 461 | struct net_device *dev; /* Backpointer */ |
462 | struct quattro *qfe_parent; /* For Quattro cards */ | 462 | struct quattro *qfe_parent; /* For Quattro cards */ |
463 | int qfe_ent; /* Which instance on quattro */ | 463 | int qfe_ent; /* Which instance on quattro */ |
464 | struct happy_meal *next_module; | ||
465 | }; | 464 | }; |
466 | 465 | ||
467 | /* Here are the happy flags. */ | 466 | /* Here are the happy flags. */ |
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 6381243d8d00..2c239ab63a80 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c | |||
@@ -266,7 +266,6 @@ struct lance_private { | |||
266 | char *name; | 266 | char *name; |
267 | dma_addr_t init_block_dvma; | 267 | dma_addr_t init_block_dvma; |
268 | struct net_device *dev; /* Backpointer */ | 268 | struct net_device *dev; /* Backpointer */ |
269 | struct lance_private *next_module; | ||
270 | struct sbus_dev *sdev; | 269 | struct sbus_dev *sdev; |
271 | struct timer_list multicast_timer; | 270 | struct timer_list multicast_timer; |
272 | }; | 271 | }; |
@@ -298,8 +297,6 @@ int sparc_lance_debug = 2; | |||
298 | 297 | ||
299 | #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) | 298 | #define LANCE_ADDR(x) ((long)(x) & ~0xff000000) |
300 | 299 | ||
301 | static struct lance_private *root_lance_dev; | ||
302 | |||
303 | /* Load the CSR registers */ | 300 | /* Load the CSR registers */ |
304 | static void load_csrs(struct lance_private *lp) | 301 | static void load_csrs(struct lance_private *lp) |
305 | { | 302 | { |
@@ -1327,9 +1324,9 @@ static struct ethtool_ops sparc_lance_ethtool_ops = { | |||
1327 | .get_link = sparc_lance_get_link, | 1324 | .get_link = sparc_lance_get_link, |
1328 | }; | 1325 | }; |
1329 | 1326 | ||
1330 | static int __init sparc_lance_init(struct sbus_dev *sdev, | 1327 | static int __init sparc_lance_probe_one(struct sbus_dev *sdev, |
1331 | struct sbus_dma *ledma, | 1328 | struct sbus_dma *ledma, |
1332 | struct sbus_dev *lebuffer) | 1329 | struct sbus_dev *lebuffer) |
1333 | { | 1330 | { |
1334 | static unsigned version_printed; | 1331 | static unsigned version_printed; |
1335 | struct net_device *dev; | 1332 | struct net_device *dev; |
@@ -1473,6 +1470,7 @@ no_link_test: | |||
1473 | 1470 | ||
1474 | lp->dev = dev; | 1471 | lp->dev = dev; |
1475 | SET_MODULE_OWNER(dev); | 1472 | SET_MODULE_OWNER(dev); |
1473 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
1476 | dev->open = &lance_open; | 1474 | dev->open = &lance_open; |
1477 | dev->stop = &lance_close; | 1475 | dev->stop = &lance_close; |
1478 | dev->hard_start_xmit = &lance_start_xmit; | 1476 | dev->hard_start_xmit = &lance_start_xmit; |
@@ -1500,8 +1498,7 @@ no_link_test: | |||
1500 | goto fail; | 1498 | goto fail; |
1501 | } | 1499 | } |
1502 | 1500 | ||
1503 | lp->next_module = root_lance_dev; | 1501 | dev_set_drvdata(&sdev->ofdev.dev, lp); |
1504 | root_lance_dev = lp; | ||
1505 | 1502 | ||
1506 | printk(KERN_INFO "%s: LANCE ", dev->name); | 1503 | printk(KERN_INFO "%s: LANCE ", dev->name); |
1507 | 1504 | ||
@@ -1536,88 +1533,112 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev) | |||
1536 | #include <asm/machines.h> | 1533 | #include <asm/machines.h> |
1537 | 1534 | ||
1538 | /* Find all the lance cards on the system and initialize them */ | 1535 | /* Find all the lance cards on the system and initialize them */ |
1539 | static int __init sparc_lance_probe(void) | 1536 | static struct sbus_dev sun4_sdev; |
1537 | static int __init sparc_lance_init(void) | ||
1540 | { | 1538 | { |
1541 | static struct sbus_dev sdev; | ||
1542 | static int called; | ||
1543 | |||
1544 | root_lance_dev = NULL; | ||
1545 | |||
1546 | if (called) | ||
1547 | return -ENODEV; | ||
1548 | called++; | ||
1549 | |||
1550 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || | 1539 | if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || |
1551 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { | 1540 | (idprom->id_machtype == (SM_SUN4|SM_4_470))) { |
1552 | memset(&sdev, 0, sizeof(sdev)); | 1541 | memset(&sun4_sdev, 0, sizeof(sdev)); |
1553 | sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; | 1542 | sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; |
1554 | sdev.irqs[0] = 6; | 1543 | sun4_sdev.irqs[0] = 6; |
1555 | return sparc_lance_init(&sdev, NULL, NULL); | 1544 | return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); |
1556 | } | 1545 | } |
1557 | return -ENODEV; | 1546 | return -ENODEV; |
1558 | } | 1547 | } |
1559 | 1548 | ||
1560 | #else /* !CONFIG_SUN4 */ | 1549 | static int __exit sunlance_sun4_remove(void) |
1561 | |||
1562 | /* Find all the lance cards on the system and initialize them */ | ||
1563 | static int __init sparc_lance_probe(void) | ||
1564 | { | 1550 | { |
1565 | struct sbus_bus *bus; | 1551 | struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); |
1566 | struct sbus_dev *sdev = NULL; | 1552 | struct net_device *net_dev = lp->dev; |
1567 | struct sbus_dma *ledma = NULL; | 1553 | |
1568 | static int called; | 1554 | unregister_netdevice(net_dev); |
1569 | int cards = 0, v; | 1555 | |
1570 | 1556 | lance_free_hwresources(root_lance_dev); | |
1571 | root_lance_dev = NULL; | 1557 | |
1572 | 1558 | free_netdev(net_dev); | |
1573 | if (called) | 1559 | |
1574 | return -ENODEV; | 1560 | dev_set_drvdata(&sun4_sdev->dev, NULL); |
1575 | called++; | 1561 | |
1576 | |||
1577 | for_each_sbus (bus) { | ||
1578 | for_each_sbusdev (sdev, bus) { | ||
1579 | if (strcmp(sdev->prom_name, "le") == 0) { | ||
1580 | cards++; | ||
1581 | if ((v = sparc_lance_init(sdev, NULL, NULL))) | ||
1582 | return v; | ||
1583 | continue; | ||
1584 | } | ||
1585 | if (strcmp(sdev->prom_name, "ledma") == 0) { | ||
1586 | cards++; | ||
1587 | ledma = find_ledma(sdev); | ||
1588 | if ((v = sparc_lance_init(sdev->child, | ||
1589 | ledma, NULL))) | ||
1590 | return v; | ||
1591 | continue; | ||
1592 | } | ||
1593 | if (strcmp(sdev->prom_name, "lebuffer") == 0){ | ||
1594 | cards++; | ||
1595 | if ((v = sparc_lance_init(sdev->child, | ||
1596 | NULL, sdev))) | ||
1597 | return v; | ||
1598 | continue; | ||
1599 | } | ||
1600 | } /* for each sbusdev */ | ||
1601 | } /* for each sbus */ | ||
1602 | if (!cards) | ||
1603 | return -ENODEV; | ||
1604 | return 0; | 1562 | return 0; |
1605 | } | 1563 | } |
1606 | #endif /* !CONFIG_SUN4 */ | ||
1607 | 1564 | ||
1608 | static void __exit sparc_lance_cleanup(void) | 1565 | #else /* !CONFIG_SUN4 */ |
1566 | |||
1567 | static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match) | ||
1609 | { | 1568 | { |
1610 | struct lance_private *lp; | 1569 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
1570 | struct device_node *dp = dev->node; | ||
1571 | int err; | ||
1572 | |||
1573 | if (!strcmp(dp->name, "le")) { | ||
1574 | err = sparc_lance_probe_one(sdev, NULL, NULL); | ||
1575 | } else if (!strcmp(dp->name, "ledma")) { | ||
1576 | struct sbus_dma *ledma = find_ledma(sdev); | ||
1611 | 1577 | ||
1612 | while (root_lance_dev) { | 1578 | err = sparc_lance_probe_one(sdev->child, ledma, NULL); |
1613 | lp = root_lance_dev->next_module; | 1579 | } else { |
1580 | BUG_ON(strcmp(dp->name, "lebuffer")); | ||
1614 | 1581 | ||
1615 | unregister_netdev(root_lance_dev->dev); | 1582 | err = sparc_lance_probe_one(sdev->child, NULL, sdev); |
1616 | lance_free_hwresources(root_lance_dev); | ||
1617 | free_netdev(root_lance_dev->dev); | ||
1618 | root_lance_dev = lp; | ||
1619 | } | 1583 | } |
1584 | |||
1585 | return err; | ||
1586 | } | ||
1587 | |||
1588 | static int __devexit sunlance_sbus_remove(struct of_device *dev) | ||
1589 | { | ||
1590 | struct lance_private *lp = dev_get_drvdata(&dev->dev); | ||
1591 | struct net_device *net_dev = lp->dev; | ||
1592 | |||
1593 | unregister_netdevice(net_dev); | ||
1594 | |||
1595 | lance_free_hwresources(lp); | ||
1596 | |||
1597 | free_netdev(net_dev); | ||
1598 | |||
1599 | dev_set_drvdata(&dev->dev, NULL); | ||
1600 | |||
1601 | return 0; | ||
1602 | } | ||
1603 | |||
1604 | static struct of_device_id sunlance_sbus_match[] = { | ||
1605 | { | ||
1606 | .name = "le", | ||
1607 | }, | ||
1608 | { | ||
1609 | .name = "ledma", | ||
1610 | }, | ||
1611 | { | ||
1612 | .name = "lebuffer", | ||
1613 | }, | ||
1614 | {}, | ||
1615 | }; | ||
1616 | |||
1617 | MODULE_DEVICE_TABLE(of, sunlance_sbus_match); | ||
1618 | |||
1619 | static struct of_platform_driver sunlance_sbus_driver = { | ||
1620 | .name = "sunlance", | ||
1621 | .match_table = sunlance_sbus_match, | ||
1622 | .probe = sunlance_sbus_probe, | ||
1623 | .remove = __devexit_p(sunlance_sbus_remove), | ||
1624 | }; | ||
1625 | |||
1626 | |||
1627 | /* Find all the lance cards on the system and initialize them */ | ||
1628 | static int __init sparc_lance_init(void) | ||
1629 | { | ||
1630 | return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type); | ||
1631 | } | ||
1632 | #endif /* !CONFIG_SUN4 */ | ||
1633 | |||
1634 | static void __exit sparc_lance_exit(void) | ||
1635 | { | ||
1636 | #ifdef CONFIG_SUN4 | ||
1637 | sunlance_sun4_remove(); | ||
1638 | #else | ||
1639 | of_unregister_driver(&sunlance_sbus_driver); | ||
1640 | #endif | ||
1620 | } | 1641 | } |
1621 | 1642 | ||
1622 | module_init(sparc_lance_probe); | 1643 | module_init(sparc_lance_init); |
1623 | module_exit(sparc_lance_cleanup); | 1644 | module_exit(sparc_lance_exit); |
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 1f2323be60d4..9da6d5b87173 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c | |||
@@ -1,10 +1,9 @@ | |||
1 | /* $Id: sunqe.c,v 1.55 2002/01/15 06:48:55 davem Exp $ | 1 | /* sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. |
2 | * sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver. | ||
3 | * Once again I am out to prove that every ethernet | 2 | * Once again I am out to prove that every ethernet |
4 | * controller out there can be most efficiently programmed | 3 | * controller out there can be most efficiently programmed |
5 | * if you make it look like a LANCE. | 4 | * if you make it look like a LANCE. |
6 | * | 5 | * |
7 | * Copyright (C) 1996, 1999, 2003 David S. Miller (davem@redhat.com) | 6 | * Copyright (C) 1996, 1999, 2003, 2006 David S. Miller (davem@davemloft.net) |
8 | */ | 7 | */ |
9 | 8 | ||
10 | #include <linux/module.h> | 9 | #include <linux/module.h> |
@@ -41,9 +40,9 @@ | |||
41 | #include "sunqe.h" | 40 | #include "sunqe.h" |
42 | 41 | ||
43 | #define DRV_NAME "sunqe" | 42 | #define DRV_NAME "sunqe" |
44 | #define DRV_VERSION "3.0" | 43 | #define DRV_VERSION "4.0" |
45 | #define DRV_RELDATE "8/24/03" | 44 | #define DRV_RELDATE "June 23, 2006" |
46 | #define DRV_AUTHOR "David S. Miller (davem@redhat.com)" | 45 | #define DRV_AUTHOR "David S. Miller (davem@davemloft.net)" |
47 | 46 | ||
48 | static char version[] = | 47 | static char version[] = |
49 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; | 48 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; |
@@ -755,298 +754,269 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev) | |||
755 | qecp->gregs + GLOB_RSIZE); | 754 | qecp->gregs + GLOB_RSIZE); |
756 | } | 755 | } |
757 | 756 | ||
758 | /* Four QE's per QEC card. */ | 757 | static u8 __init qec_get_burst(struct device_node *dp) |
759 | static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) | ||
760 | { | 758 | { |
761 | static unsigned version_printed; | ||
762 | struct net_device *qe_devs[4]; | ||
763 | struct sunqe *qeps[4]; | ||
764 | struct sbus_dev *qesdevs[4]; | ||
765 | struct sbus_dev *child; | ||
766 | struct sunqec *qecp = NULL; | ||
767 | u8 bsizes, bsizes_more; | 759 | u8 bsizes, bsizes_more; |
768 | int i, j, res = -ENOMEM; | ||
769 | 760 | ||
770 | for (i = 0; i < 4; i++) { | 761 | /* Find and set the burst sizes for the QEC, since it |
771 | qe_devs[i] = alloc_etherdev(sizeof(struct sunqe)); | 762 | * does the actual dma for all 4 channels. |
772 | if (!qe_devs[i]) | 763 | */ |
773 | goto out; | 764 | bsizes = of_getintprop_default(dp, "burst-sizes", 0xff); |
774 | } | 765 | bsizes &= 0xff; |
766 | bsizes_more = of_getintprop_default(dp->parent, "burst-sizes", 0xff); | ||
775 | 767 | ||
776 | if (version_printed++ == 0) | 768 | if (bsizes_more != 0xff) |
777 | printk(KERN_INFO "%s", version); | 769 | bsizes &= bsizes_more; |
770 | if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 || | ||
771 | (bsizes & DMA_BURST32)==0) | ||
772 | bsizes = (DMA_BURST32 - 1); | ||
778 | 773 | ||
779 | for (i = 0; i < 4; i++) { | 774 | return bsizes; |
780 | qeps[i] = (struct sunqe *) qe_devs[i]->priv; | 775 | } |
781 | for (j = 0; j < 6; j++) | ||
782 | qe_devs[i]->dev_addr[j] = idprom->id_ethaddr[j]; | ||
783 | qeps[i]->channel = i; | ||
784 | spin_lock_init(&qeps[i]->lock); | ||
785 | } | ||
786 | 776 | ||
787 | qecp = kmalloc(sizeof(struct sunqec), GFP_KERNEL); | 777 | static struct sunqec * __init get_qec(struct sbus_dev *child_sdev) |
788 | if (qecp == NULL) | 778 | { |
789 | goto out1; | 779 | struct sbus_dev *qec_sdev = child_sdev->parent; |
790 | qecp->qec_sdev = sdev; | 780 | struct sunqec *qecp; |
791 | 781 | ||
792 | for (i = 0; i < 4; i++) { | 782 | for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) { |
793 | qecp->qes[i] = qeps[i]; | 783 | if (qecp->qec_sdev == qec_sdev) |
794 | qeps[i]->dev = qe_devs[i]; | 784 | break; |
795 | qeps[i]->parent = qecp; | ||
796 | } | 785 | } |
786 | if (!qecp) { | ||
787 | qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); | ||
788 | if (qecp) { | ||
789 | u32 ctrl; | ||
790 | |||
791 | qecp->qec_sdev = qec_sdev; | ||
792 | qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0, | ||
793 | GLOB_REG_SIZE, | ||
794 | "QEC Global Registers"); | ||
795 | if (!qecp->gregs) | ||
796 | goto fail; | ||
797 | |||
798 | /* Make sure the QEC is in MACE mode. */ | ||
799 | ctrl = sbus_readl(qecp->gregs + GLOB_CTRL); | ||
800 | ctrl &= 0xf0000000; | ||
801 | if (ctrl != GLOB_CTRL_MMODE) { | ||
802 | printk(KERN_ERR "qec: Not in MACE mode!\n"); | ||
803 | goto fail; | ||
804 | } | ||
797 | 805 | ||
798 | res = -ENODEV; | 806 | if (qec_global_reset(qecp->gregs)) |
807 | goto fail; | ||
799 | 808 | ||
800 | for (i = 0, child = sdev->child; i < 4; i++, child = child->next) { | 809 | qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node); |
801 | /* Link in channel */ | ||
802 | j = prom_getintdefault(child->prom_node, "channel#", -1); | ||
803 | if (j == -1) | ||
804 | goto out2; | ||
805 | qesdevs[j] = child; | ||
806 | } | ||
807 | 810 | ||
808 | for (i = 0; i < 4; i++) | 811 | qec_init_once(qecp, qec_sdev); |
809 | qeps[i]->qe_sdev = qesdevs[i]; | ||
810 | 812 | ||
811 | /* Now map in the registers, QEC globals first. */ | 813 | if (request_irq(qec_sdev->irqs[0], &qec_interrupt, |
812 | qecp->gregs = sbus_ioremap(&sdev->resource[0], 0, | 814 | SA_SHIRQ, "qec", (void *) qecp)) { |
813 | GLOB_REG_SIZE, "QEC Global Registers"); | 815 | printk(KERN_ERR "qec: Can't register irq.\n"); |
814 | if (!qecp->gregs) { | 816 | goto fail; |
815 | printk(KERN_ERR "QuadEther: Cannot map QEC global registers.\n"); | 817 | } |
816 | goto out2; | ||
817 | } | ||
818 | 818 | ||
819 | /* Make sure the QEC is in MACE mode. */ | 819 | qecp->next_module = root_qec_dev; |
820 | if ((sbus_readl(qecp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_MMODE) { | 820 | root_qec_dev = qecp; |
821 | printk(KERN_ERR "QuadEther: AIEEE, QEC is not in MACE mode!\n"); | 821 | } |
822 | goto out3; | ||
823 | } | 822 | } |
824 | 823 | ||
825 | /* Reset the QEC. */ | 824 | return qecp; |
826 | if (qec_global_reset(qecp->gregs)) | ||
827 | goto out3; | ||
828 | 825 | ||
829 | /* Find and set the burst sizes for the QEC, since it does | 826 | fail: |
830 | * the actual dma for all 4 channels. | 827 | if (qecp->gregs) |
831 | */ | 828 | sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); |
832 | bsizes = prom_getintdefault(sdev->prom_node, "burst-sizes", 0xff); | 829 | kfree(qecp); |
833 | bsizes &= 0xff; | 830 | return NULL; |
834 | bsizes_more = prom_getintdefault(sdev->bus->prom_node, "burst-sizes", 0xff); | 831 | } |
835 | 832 | ||
836 | if (bsizes_more != 0xff) | 833 | static int __init qec_ether_init(struct sbus_dev *sdev) |
837 | bsizes &= bsizes_more; | 834 | { |
838 | if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 || | 835 | static unsigned version_printed; |
839 | (bsizes & DMA_BURST32)==0) | 836 | struct net_device *dev; |
840 | bsizes = (DMA_BURST32 - 1); | 837 | struct sunqe *qe; |
838 | struct sunqec *qecp; | ||
839 | int i, res; | ||
841 | 840 | ||
842 | qecp->qec_bursts = bsizes; | 841 | if (version_printed++ == 0) |
842 | printk(KERN_INFO "%s", version); | ||
843 | 843 | ||
844 | /* Perform one time QEC initialization, we never touch the QEC | 844 | dev = alloc_etherdev(sizeof(struct sunqe)); |
845 | * globals again after this. | 845 | if (!dev) |
846 | */ | 846 | return -ENOMEM; |
847 | qec_init_once(qecp, sdev); | ||
848 | |||
849 | for (i = 0; i < 4; i++) { | ||
850 | struct sunqe *qe = qeps[i]; | ||
851 | /* Map in QEC per-channel control registers. */ | ||
852 | qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, | ||
853 | CREG_REG_SIZE, "QEC Channel Registers"); | ||
854 | if (!qe->qcregs) { | ||
855 | printk(KERN_ERR "QuadEther: Cannot map QE %d's channel registers.\n", i); | ||
856 | goto out4; | ||
857 | } | ||
858 | 847 | ||
859 | /* Map in per-channel AMD MACE registers. */ | 848 | qe = netdev_priv(dev); |
860 | qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, | ||
861 | MREGS_REG_SIZE, "QE MACE Registers"); | ||
862 | if (!qe->mregs) { | ||
863 | printk(KERN_ERR "QuadEther: Cannot map QE %d's MACE registers.\n", i); | ||
864 | goto out4; | ||
865 | } | ||
866 | 849 | ||
867 | qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, | 850 | i = of_getintprop_default(sdev->ofdev.node, "channel#", -1); |
868 | PAGE_SIZE, | 851 | if (i == -1) { |
869 | &qe->qblock_dvma); | 852 | struct sbus_dev *td = sdev->parent->child; |
870 | qe->buffers = sbus_alloc_consistent(qe->qe_sdev, | 853 | i = 0; |
871 | sizeof(struct sunqe_buffers), | 854 | while (td != sdev) { |
872 | &qe->buffers_dvma); | 855 | td = td->next; |
873 | if (qe->qe_block == NULL || qe->qblock_dvma == 0 || | 856 | i++; |
874 | qe->buffers == NULL || qe->buffers_dvma == 0) { | ||
875 | goto out4; | ||
876 | } | 857 | } |
877 | |||
878 | /* Stop this QE. */ | ||
879 | qe_stop(qe); | ||
880 | } | 858 | } |
859 | qe->channel = i; | ||
860 | spin_lock_init(&qe->lock); | ||
861 | |||
862 | res = -ENODEV; | ||
863 | qecp = get_qec(sdev); | ||
864 | if (!qecp) | ||
865 | goto fail; | ||
881 | 866 | ||
882 | for (i = 0; i < 4; i++) { | 867 | qecp->qes[qe->channel] = qe; |
883 | SET_MODULE_OWNER(qe_devs[i]); | 868 | qe->dev = dev; |
884 | qe_devs[i]->open = qe_open; | 869 | qe->parent = qecp; |
885 | qe_devs[i]->stop = qe_close; | 870 | qe->qe_sdev = sdev; |
886 | qe_devs[i]->hard_start_xmit = qe_start_xmit; | ||
887 | qe_devs[i]->get_stats = qe_get_stats; | ||
888 | qe_devs[i]->set_multicast_list = qe_set_multicast; | ||
889 | qe_devs[i]->tx_timeout = qe_tx_timeout; | ||
890 | qe_devs[i]->watchdog_timeo = 5*HZ; | ||
891 | qe_devs[i]->irq = sdev->irqs[0]; | ||
892 | qe_devs[i]->dma = 0; | ||
893 | qe_devs[i]->ethtool_ops = &qe_ethtool_ops; | ||
894 | } | ||
895 | 871 | ||
896 | /* QEC receives interrupts from each QE, then it sends the actual | 872 | res = -ENOMEM; |
897 | * IRQ to the cpu itself. Since QEC is the single point of | 873 | qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0, |
898 | * interrupt for all QE channels we register the IRQ handler | 874 | CREG_REG_SIZE, "QEC Channel Registers"); |
899 | * for it now. | 875 | if (!qe->qcregs) { |
900 | */ | 876 | printk(KERN_ERR "qe: Cannot map channel registers.\n"); |
901 | if (request_irq(sdev->irqs[0], &qec_interrupt, | 877 | goto fail; |
902 | SA_SHIRQ, "QuadEther", (void *) qecp)) { | ||
903 | printk(KERN_ERR "QuadEther: Can't register QEC master irq handler.\n"); | ||
904 | res = -EAGAIN; | ||
905 | goto out4; | ||
906 | } | 878 | } |
907 | 879 | ||
908 | for (i = 0; i < 4; i++) { | 880 | qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0, |
909 | if (register_netdev(qe_devs[i]) != 0) | 881 | MREGS_REG_SIZE, "QE MACE Registers"); |
910 | goto out5; | 882 | if (!qe->mregs) { |
883 | printk(KERN_ERR "qe: Cannot map MACE registers.\n"); | ||
884 | goto fail; | ||
911 | } | 885 | } |
912 | 886 | ||
913 | /* Report the QE channels. */ | 887 | qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, |
914 | for (i = 0; i < 4; i++) { | 888 | PAGE_SIZE, |
915 | printk(KERN_INFO "%s: QuadEthernet channel[%d] ", qe_devs[i]->name, i); | 889 | &qe->qblock_dvma); |
916 | for (j = 0; j < 6; j++) | 890 | qe->buffers = sbus_alloc_consistent(qe->qe_sdev, |
917 | printk ("%2.2x%c", | 891 | sizeof(struct sunqe_buffers), |
918 | qe_devs[i]->dev_addr[j], | 892 | &qe->buffers_dvma); |
919 | j == 5 ? ' ': ':'); | 893 | if (qe->qe_block == NULL || qe->qblock_dvma == 0 || |
920 | printk("\n"); | 894 | qe->buffers == NULL || qe->buffers_dvma == 0) |
921 | } | 895 | goto fail; |
896 | |||
897 | /* Stop this QE. */ | ||
898 | qe_stop(qe); | ||
899 | |||
900 | SET_MODULE_OWNER(dev); | ||
901 | SET_NETDEV_DEV(dev, &sdev->ofdev.dev); | ||
902 | |||
903 | dev->open = qe_open; | ||
904 | dev->stop = qe_close; | ||
905 | dev->hard_start_xmit = qe_start_xmit; | ||
906 | dev->get_stats = qe_get_stats; | ||
907 | dev->set_multicast_list = qe_set_multicast; | ||
908 | dev->tx_timeout = qe_tx_timeout; | ||
909 | dev->watchdog_timeo = 5*HZ; | ||
910 | dev->irq = sdev->irqs[0]; | ||
911 | dev->dma = 0; | ||
912 | dev->ethtool_ops = &qe_ethtool_ops; | ||
913 | |||
914 | res = register_netdev(dev); | ||
915 | if (res) | ||
916 | goto fail; | ||
917 | |||
918 | dev_set_drvdata(&sdev->ofdev.dev, qe); | ||
919 | |||
920 | printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel); | ||
921 | for (i = 0; i < 6; i++) | ||
922 | printk ("%2.2x%c", | ||
923 | dev->dev_addr[i], | ||
924 | i == 5 ? ' ': ':'); | ||
925 | printk("\n"); | ||
922 | 926 | ||
923 | /* We are home free at this point, link the qe's into | ||
924 | * the master list for later driver exit. | ||
925 | */ | ||
926 | qecp->next_module = root_qec_dev; | ||
927 | root_qec_dev = qecp; | ||
928 | 927 | ||
929 | return 0; | 928 | return 0; |
930 | 929 | ||
931 | out5: | 930 | fail: |
932 | while (i--) | 931 | if (qe->qcregs) |
933 | unregister_netdev(qe_devs[i]); | 932 | sbus_iounmap(qe->qcregs, CREG_REG_SIZE); |
934 | free_irq(sdev->irqs[0], (void *)qecp); | 933 | if (qe->mregs) |
935 | out4: | 934 | sbus_iounmap(qe->mregs, MREGS_REG_SIZE); |
936 | for (i = 0; i < 4; i++) { | 935 | if (qe->qe_block) |
937 | struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv; | 936 | sbus_free_consistent(qe->qe_sdev, |
938 | 937 | PAGE_SIZE, | |
939 | if (qe->qcregs) | 938 | qe->qe_block, |
940 | sbus_iounmap(qe->qcregs, CREG_REG_SIZE); | 939 | qe->qblock_dvma); |
941 | if (qe->mregs) | 940 | if (qe->buffers) |
942 | sbus_iounmap(qe->mregs, MREGS_REG_SIZE); | 941 | sbus_free_consistent(qe->qe_sdev, |
943 | if (qe->qe_block) | 942 | sizeof(struct sunqe_buffers), |
944 | sbus_free_consistent(qe->qe_sdev, | 943 | qe->buffers, |
945 | PAGE_SIZE, | 944 | qe->buffers_dvma); |
946 | qe->qe_block, | 945 | |
947 | qe->qblock_dvma); | 946 | free_netdev(dev); |
948 | if (qe->buffers) | 947 | |
949 | sbus_free_consistent(qe->qe_sdev, | ||
950 | sizeof(struct sunqe_buffers), | ||
951 | qe->buffers, | ||
952 | qe->buffers_dvma); | ||
953 | } | ||
954 | out3: | ||
955 | sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); | ||
956 | out2: | ||
957 | kfree(qecp); | ||
958 | out1: | ||
959 | i = 4; | ||
960 | out: | ||
961 | while (i--) | ||
962 | free_netdev(qe_devs[i]); | ||
963 | return res; | 948 | return res; |
964 | } | 949 | } |
965 | 950 | ||
966 | static int __init qec_match(struct sbus_dev *sdev) | 951 | static int __devinit qec_sbus_probe(struct of_device *dev, const struct of_device_id *match) |
967 | { | 952 | { |
968 | struct sbus_dev *sibling; | 953 | struct sbus_dev *sdev = to_sbus_device(&dev->dev); |
969 | int i; | ||
970 | |||
971 | if (strcmp(sdev->prom_name, "qec") != 0) | ||
972 | return 0; | ||
973 | 954 | ||
974 | /* QEC can be parent of either QuadEthernet or BigMAC | 955 | return qec_ether_init(sdev); |
975 | * children. Do not confuse this with qfe/SUNW,qfe | ||
976 | * which is a quad-happymeal card and handled by | ||
977 | * a different driver. | ||
978 | */ | ||
979 | sibling = sdev->child; | ||
980 | for (i = 0; i < 4; i++) { | ||
981 | if (sibling == NULL) | ||
982 | return 0; | ||
983 | if (strcmp(sibling->prom_name, "qe") != 0) | ||
984 | return 0; | ||
985 | sibling = sibling->next; | ||
986 | } | ||
987 | return 1; | ||
988 | } | 956 | } |
989 | 957 | ||
990 | static int __init qec_probe(void) | 958 | static int __devexit qec_sbus_remove(struct of_device *dev) |
991 | { | 959 | { |
992 | struct net_device *dev = NULL; | 960 | struct sunqe *qp = dev_get_drvdata(&dev->dev); |
993 | struct sbus_bus *bus; | 961 | struct net_device *net_dev = qp->dev; |
994 | struct sbus_dev *sdev = NULL; | 962 | |
995 | static int called; | 963 | unregister_netdevice(net_dev); |
996 | int cards = 0, v; | 964 | |
997 | 965 | sbus_iounmap(qp->qcregs, CREG_REG_SIZE); | |
998 | root_qec_dev = NULL; | 966 | sbus_iounmap(qp->mregs, MREGS_REG_SIZE); |
999 | 967 | sbus_free_consistent(qp->qe_sdev, | |
1000 | if (called) | 968 | PAGE_SIZE, |
1001 | return -ENODEV; | 969 | qp->qe_block, |
1002 | called++; | 970 | qp->qblock_dvma); |
1003 | 971 | sbus_free_consistent(qp->qe_sdev, | |
1004 | for_each_sbus(bus) { | 972 | sizeof(struct sunqe_buffers), |
1005 | for_each_sbusdev(sdev, bus) { | 973 | qp->buffers, |
1006 | if (cards) | 974 | qp->buffers_dvma); |
1007 | dev = NULL; | 975 | |
1008 | 976 | free_netdev(net_dev); | |
1009 | if (qec_match(sdev)) { | 977 | |
1010 | cards++; | 978 | dev_set_drvdata(&dev->dev, NULL); |
1011 | if ((v = qec_ether_init(dev, sdev))) | 979 | |
1012 | return v; | ||
1013 | } | ||
1014 | } | ||
1015 | } | ||
1016 | if (!cards) | ||
1017 | return -ENODEV; | ||
1018 | return 0; | 980 | return 0; |
1019 | } | 981 | } |
1020 | 982 | ||
1021 | static void __exit qec_cleanup(void) | 983 | static struct of_device_id qec_sbus_match[] = { |
984 | { | ||
985 | .name = "qe", | ||
986 | }, | ||
987 | {}, | ||
988 | }; | ||
989 | |||
990 | MODULE_DEVICE_TABLE(of, qec_sbus_match); | ||
991 | |||
992 | static struct of_platform_driver qec_sbus_driver = { | ||
993 | .name = "qec", | ||
994 | .match_table = qec_sbus_match, | ||
995 | .probe = qec_sbus_probe, | ||
996 | .remove = __devexit_p(qec_sbus_remove), | ||
997 | }; | ||
998 | |||
999 | static int __init qec_init(void) | ||
1000 | { | ||
1001 | return of_register_driver(&qec_sbus_driver, &sbus_bus_type); | ||
1002 | } | ||
1003 | |||
1004 | static void __exit qec_exit(void) | ||
1022 | { | 1005 | { |
1023 | struct sunqec *next_qec; | 1006 | of_unregister_driver(&qec_sbus_driver); |
1024 | int i; | ||
1025 | 1007 | ||
1026 | while (root_qec_dev) { | 1008 | while (root_qec_dev) { |
1027 | next_qec = root_qec_dev->next_module; | 1009 | struct sunqec *next = root_qec_dev->next_module; |
1028 | 1010 | ||
1029 | /* Release all four QE channels, then the QEC itself. */ | 1011 | free_irq(root_qec_dev->qec_sdev->irqs[0], |
1030 | for (i = 0; i < 4; i++) { | 1012 | (void *) root_qec_dev); |
1031 | unregister_netdev(root_qec_dev->qes[i]->dev); | ||
1032 | sbus_iounmap(root_qec_dev->qes[i]->qcregs, CREG_REG_SIZE); | ||
1033 | sbus_iounmap(root_qec_dev->qes[i]->mregs, MREGS_REG_SIZE); | ||
1034 | sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, | ||
1035 | PAGE_SIZE, | ||
1036 | root_qec_dev->qes[i]->qe_block, | ||
1037 | root_qec_dev->qes[i]->qblock_dvma); | ||
1038 | sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev, | ||
1039 | sizeof(struct sunqe_buffers), | ||
1040 | root_qec_dev->qes[i]->buffers, | ||
1041 | root_qec_dev->qes[i]->buffers_dvma); | ||
1042 | free_netdev(root_qec_dev->qes[i]->dev); | ||
1043 | } | ||
1044 | free_irq(root_qec_dev->qec_sdev->irqs[0], (void *)root_qec_dev); | ||
1045 | sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE); | 1013 | sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE); |
1014 | |||
1046 | kfree(root_qec_dev); | 1015 | kfree(root_qec_dev); |
1047 | root_qec_dev = next_qec; | 1016 | |
1017 | root_qec_dev = next; | ||
1048 | } | 1018 | } |
1049 | } | 1019 | } |
1050 | 1020 | ||
1051 | module_init(qec_probe); | 1021 | module_init(qec_init); |
1052 | module_exit(qec_cleanup); | 1022 | module_exit(qec_exit); |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e3e380f90f86..35f931638750 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -10549,11 +10549,13 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp) | |||
10549 | struct pcidev_cookie *pcp = pdev->sysdata; | 10549 | struct pcidev_cookie *pcp = pdev->sysdata; |
10550 | 10550 | ||
10551 | if (pcp != NULL) { | 10551 | if (pcp != NULL) { |
10552 | int node = pcp->prom_node; | 10552 | unsigned char *addr; |
10553 | int len; | ||
10553 | 10554 | ||
10554 | if (prom_getproplen(node, "local-mac-address") == 6) { | 10555 | addr = of_get_property(pcp->prom_node, "local-mac-address", |
10555 | prom_getproperty(node, "local-mac-address", | 10556 | &len); |
10556 | dev->dev_addr, 6); | 10557 | if (addr && len == 6) { |
10558 | memcpy(dev->dev_addr, addr, 6); | ||
10557 | memcpy(dev->perm_addr, dev->dev_addr, 6); | 10559 | memcpy(dev->perm_addr, dev->dev_addr, 6); |
10558 | return 0; | 10560 | return 0; |
10559 | } | 10561 | } |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index cabdf894e21e..e0de66739a42 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -1550,10 +1550,14 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1550 | dev->dev_addr[i] = last_phys_addr[i]; | 1550 | dev->dev_addr[i] = last_phys_addr[i]; |
1551 | dev->dev_addr[i] = last_phys_addr[i] + 1; | 1551 | dev->dev_addr[i] = last_phys_addr[i] + 1; |
1552 | #if defined(__sparc__) | 1552 | #if defined(__sparc__) |
1553 | if ((pcp != NULL) && prom_getproplen(pcp->prom_node, | 1553 | if (pcp) { |
1554 | "local-mac-address") == 6) { | 1554 | unsigned char *addr; |
1555 | prom_getproperty(pcp->prom_node, "local-mac-address", | 1555 | int len; |
1556 | dev->dev_addr, 6); | 1556 | |
1557 | addr = of_get_property(pcp->prom_node, | ||
1558 | "local-mac-address", &len); | ||
1559 | if (addr && len == 6) | ||
1560 | memcpy(dev->dev_addr, addr, 6); | ||
1557 | } | 1561 | } |
1558 | #endif | 1562 | #endif |
1559 | #if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */ | 1563 | #if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */ |