aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sunhme.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sunhme.c')
-rw-r--r--drivers/net/sunhme.c443
1 files changed, 220 insertions, 223 deletions
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bd5d2668a36..f05eea53623 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>
@@ -13,7 +13,6 @@
13 * argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50 13 * argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <linux/types.h> 18#include <linux/types.h>
@@ -40,15 +39,13 @@
40#include <asm/dma.h> 39#include <asm/dma.h>
41#include <asm/byteorder.h> 40#include <asm/byteorder.h>
42 41
43#ifdef __sparc__ 42#ifdef CONFIG_SPARC
44#include <asm/idprom.h> 43#include <asm/idprom.h>
45#include <asm/sbus.h> 44#include <asm/sbus.h>
46#include <asm/openprom.h> 45#include <asm/openprom.h>
47#include <asm/oplib.h> 46#include <asm/oplib.h>
47#include <asm/prom.h>
48#include <asm/auxio.h> 48#include <asm/auxio.h>
49#ifndef __sparc_v9__
50#include <asm/io-unit.h>
51#endif
52#endif 49#endif
53#include <asm/uaccess.h> 50#include <asm/uaccess.h>
54 51
@@ -57,7 +54,7 @@
57 54
58#ifdef CONFIG_PCI 55#ifdef CONFIG_PCI
59#include <linux/pci.h> 56#include <linux/pci.h>
60#ifdef __sparc__ 57#ifdef CONFIG_SPARC
61#include <asm/pbm.h> 58#include <asm/pbm.h>
62#endif 59#endif
63#endif 60#endif
@@ -65,9 +62,9 @@
65#include "sunhme.h" 62#include "sunhme.h"
66 63
67#define DRV_NAME "sunhme" 64#define DRV_NAME "sunhme"
68#define DRV_VERSION "2.02" 65#define DRV_VERSION "3.00"
69#define DRV_RELDATE "8/24/03" 66#define DRV_RELDATE "June 23, 2006"
70#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" 67#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"
71 68
72static char version[] = 69static char version[] =
73 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; 70 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
@@ -83,8 +80,6 @@ static int macaddr[6];
83module_param_array(macaddr, int, NULL, 0); 80module_param_array(macaddr, int, NULL, 0);
84MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); 81MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
85 82
86static struct happy_meal *root_happy_dev;
87
88#ifdef CONFIG_SBUS 83#ifdef CONFIG_SBUS
89static struct quattro *qfe_sbus_list; 84static struct quattro *qfe_sbus_list;
90#endif 85#endif
@@ -181,26 +176,6 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp)
181#define DEFAULT_IPG2 4 /* For all modes */ 176#define DEFAULT_IPG2 4 /* For all modes */
182#define DEFAULT_JAMSIZE 4 /* Toe jam */ 177#define DEFAULT_JAMSIZE 4 /* Toe jam */
183 178
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
190static 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
200MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
201
202#endif
203
204/* NOTE: In the descriptor writes one _must_ write the address 179/* NOTE: In the descriptor writes one _must_ write the address
205 * member _first_. The card must not be allowed to see 180 * member _first_. The card must not be allowed to see
206 * the updated descriptor flags until the address is 181 * the updated descriptor flags until the address is
@@ -530,7 +505,7 @@ static void happy_meal_tcvr_write(struct happy_meal *hp,
530 unsigned short value) 505 unsigned short value)
531{ 506{
532 int tries = TCVR_WRITE_TRIES; 507 int tries = TCVR_WRITE_TRIES;
533 508
534 ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value)); 509 ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value));
535 510
536 /* Welcome to Sun Microsystems, can I take your order please? */ 511 /* Welcome to Sun Microsystems, can I take your order please? */
@@ -1232,7 +1207,7 @@ static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tr
1232 * flags, thus: 1207 * flags, thus:
1233 * 1208 *
1234 * skb->csum = rxd->rx_flags & 0xffff; 1209 * skb->csum = rxd->rx_flags & 0xffff;
1235 * skb->ip_summed = CHECKSUM_HW; 1210 * skb->ip_summed = CHECKSUM_COMPLETE;
1236 * 1211 *
1237 * before sending off the skb to the protocols, and we are good as gold. 1212 * before sending off the skb to the protocols, and we are good as gold.
1238 */ 1213 */
@@ -1610,7 +1585,7 @@ static int happy_meal_init(struct happy_meal *hp)
1610 HMD(("happy_meal_init: old[%08x] bursts<", 1585 HMD(("happy_meal_init: old[%08x] bursts<",
1611 hme_read32(hp, gregs + GREG_CFG))); 1586 hme_read32(hp, gregs + GREG_CFG)));
1612 1587
1613#ifndef __sparc__ 1588#ifndef CONFIG_SPARC
1614 /* It is always PCI and can handle 64byte bursts. */ 1589 /* It is always PCI and can handle 64byte bursts. */
1615 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); 1590 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64);
1616#else 1591#else
@@ -1647,7 +1622,7 @@ static int happy_meal_init(struct happy_meal *hp)
1647 HMD(("XXX>")); 1622 HMD(("XXX>"));
1648 hme_write32(hp, gregs + GREG_CFG, 0); 1623 hme_write32(hp, gregs + GREG_CFG, 0);
1649 } 1624 }
1650#endif /* __sparc__ */ 1625#endif /* CONFIG_SPARC */
1651 1626
1652 /* Turn off interrupts we do not want to hear. */ 1627 /* Turn off interrupts we do not want to hear. */
1653 HMD((", enable global interrupts, ")); 1628 HMD((", enable global interrupts, "));
@@ -1803,7 +1778,7 @@ static void happy_meal_set_initial_advertisement(struct happy_meal *hp)
1803static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status) 1778static int happy_meal_is_not_so_happy(struct happy_meal *hp, u32 status)
1804{ 1779{
1805 int reset = 0; 1780 int reset = 0;
1806 1781
1807 /* Only print messages for non-counter related interrupts. */ 1782 /* Only print messages for non-counter related interrupts. */
1808 if (status & (GREG_STAT_STSTERR | GREG_STAT_TFIFO_UND | 1783 if (status & (GREG_STAT_STSTERR | GREG_STAT_TFIFO_UND |
1809 GREG_STAT_MAXPKTERR | GREG_STAT_RXERR | 1784 GREG_STAT_MAXPKTERR | GREG_STAT_RXERR |
@@ -2099,7 +2074,7 @@ static void happy_meal_rx(struct happy_meal *hp, struct net_device *dev)
2099 2074
2100 /* This card is _fucking_ hot... */ 2075 /* This card is _fucking_ hot... */
2101 skb->csum = ntohs(csum ^ 0xffff); 2076 skb->csum = ntohs(csum ^ 0xffff);
2102 skb->ip_summed = CHECKSUM_HW; 2077 skb->ip_summed = CHECKSUM_COMPLETE;
2103 2078
2104 RXD(("len=%d csum=%4x]", len, csum)); 2079 RXD(("len=%d csum=%4x]", len, csum));
2105 skb->protocol = eth_type_trans(skb, dev); 2080 skb->protocol = eth_type_trans(skb, dev);
@@ -2219,7 +2194,7 @@ static int happy_meal_open(struct net_device *dev)
2219 */ 2194 */
2220 if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) { 2195 if ((hp->happy_flags & (HFLAG_QUATTRO|HFLAG_PCI)) != HFLAG_QUATTRO) {
2221 if (request_irq(dev->irq, &happy_meal_interrupt, 2196 if (request_irq(dev->irq, &happy_meal_interrupt,
2222 SA_SHIRQ, dev->name, (void *)dev)) { 2197 IRQF_SHARED, dev->name, (void *)dev)) {
2223 HMD(("EAGAIN\n")); 2198 HMD(("EAGAIN\n"));
2224 printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n", 2199 printk(KERN_ERR "happy_meal(SBUS): Can't order irq %d to go.\n",
2225 dev->irq); 2200 dev->irq);
@@ -2293,7 +2268,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
2293 u32 tx_flags; 2268 u32 tx_flags;
2294 2269
2295 tx_flags = TXFLAG_OWN; 2270 tx_flags = TXFLAG_OWN;
2296 if (skb->ip_summed == CHECKSUM_HW) { 2271 if (skb->ip_summed == CHECKSUM_PARTIAL) {
2297 u32 csum_start_off, csum_stuff_off; 2272 u32 csum_start_off, csum_stuff_off;
2298 2273
2299 csum_start_off = (u32) (skb->h.raw - skb->data); 2274 csum_start_off = (u32) (skb->h.raw - skb->data);
@@ -2537,7 +2512,7 @@ static u32 hme_get_link(struct net_device *dev)
2537 return (hp->sw_bmsr & BMSR_LSTATUS); 2512 return (hp->sw_bmsr & BMSR_LSTATUS);
2538} 2513}
2539 2514
2540static struct ethtool_ops hme_ethtool_ops = { 2515static const struct ethtool_ops hme_ethtool_ops = {
2541 .get_settings = hme_get_settings, 2516 .get_settings = hme_get_settings,
2542 .set_settings = hme_set_settings, 2517 .set_settings = hme_set_settings,
2543 .get_drvinfo = hme_get_drvinfo, 2518 .get_drvinfo = hme_get_drvinfo,
@@ -2547,7 +2522,7 @@ static struct ethtool_ops hme_ethtool_ops = {
2547static int hme_version_printed; 2522static int hme_version_printed;
2548 2523
2549#ifdef CONFIG_SBUS 2524#ifdef CONFIG_SBUS
2550void __init quattro_get_ranges(struct quattro *qp) 2525void __devinit quattro_get_ranges(struct quattro *qp)
2551{ 2526{
2552 struct sbus_dev *sdev = qp->quattro_dev; 2527 struct sbus_dev *sdev = qp->quattro_dev;
2553 int err; 2528 int err;
@@ -2563,7 +2538,7 @@ void __init quattro_get_ranges(struct quattro *qp)
2563 qp->nranges = (err / sizeof(struct linux_prom_ranges)); 2538 qp->nranges = (err / sizeof(struct linux_prom_ranges));
2564} 2539}
2565 2540
2566static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp) 2541static void __devinit quattro_apply_ranges(struct quattro *qp, struct happy_meal *hp)
2567{ 2542{
2568 struct sbus_dev *sdev = hp->happy_dev; 2543 struct sbus_dev *sdev = hp->happy_dev;
2569 int rng; 2544 int rng;
@@ -2590,16 +2565,12 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h
2590 * 2565 *
2591 * Return NULL on failure. 2566 * Return NULL on failure.
2592 */ 2567 */
2593static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) 2568static struct quattro * __devinit quattro_sbus_find(struct sbus_dev *goal_sdev)
2594{ 2569{
2595 struct sbus_bus *sbus;
2596 struct sbus_dev *sdev; 2570 struct sbus_dev *sdev;
2597 struct quattro *qp; 2571 struct quattro *qp;
2598 int i; 2572 int i;
2599 2573
2600 if (qfe_sbus_list == NULL)
2601 goto found;
2602
2603 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { 2574 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2604 for (i = 0, sdev = qp->quattro_dev; 2575 for (i = 0, sdev = qp->quattro_dev;
2605 (sdev != NULL) && (i < 4); 2576 (sdev != NULL) && (i < 4);
@@ -2608,17 +2579,7 @@ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev)
2608 return qp; 2579 return qp;
2609 } 2580 }
2610 } 2581 }
2611 for_each_sbus(sbus) {
2612 for_each_sbusdev(sdev, sbus) {
2613 if (sdev == goal_sdev)
2614 goto found;
2615 }
2616 }
2617 2582
2618 /* Cannot find quattro parent, fail. */
2619 return NULL;
2620
2621found:
2622 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); 2583 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL);
2623 if (qp != NULL) { 2584 if (qp != NULL) {
2624 int i; 2585 int i;
@@ -2647,7 +2608,7 @@ static void __init quattro_sbus_register_irqs(void)
2647 2608
2648 err = request_irq(sdev->irqs[0], 2609 err = request_irq(sdev->irqs[0],
2649 quattro_sbus_interrupt, 2610 quattro_sbus_interrupt,
2650 SA_SHIRQ, "Quattro", 2611 IRQF_SHARED, "Quattro",
2651 qp); 2612 qp);
2652 if (err != 0) { 2613 if (err != 0) {
2653 printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err); 2614 printk(KERN_ERR "Quattro: Fatal IRQ registery error %d.\n", err);
@@ -2655,6 +2616,17 @@ static void __init quattro_sbus_register_irqs(void)
2655 } 2616 }
2656 } 2617 }
2657} 2618}
2619
2620static void quattro_sbus_free_irqs(void)
2621{
2622 struct quattro *qp;
2623
2624 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2625 struct sbus_dev *sdev = qp->quattro_dev;
2626
2627 free_irq(sdev->irqs[0], qp);
2628 }
2629}
2658#endif /* CONFIG_SBUS */ 2630#endif /* CONFIG_SBUS */
2659 2631
2660#ifdef CONFIG_PCI 2632#ifdef CONFIG_PCI
@@ -2689,8 +2661,9 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
2689#endif /* CONFIG_PCI */ 2661#endif /* CONFIG_PCI */
2690 2662
2691#ifdef CONFIG_SBUS 2663#ifdef CONFIG_SBUS
2692static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) 2664static int __devinit happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
2693{ 2665{
2666 struct device_node *dp = sdev->ofdev.node;
2694 struct quattro *qp = NULL; 2667 struct quattro *qp = NULL;
2695 struct happy_meal *hp; 2668 struct happy_meal *hp;
2696 struct net_device *dev; 2669 struct net_device *dev;
@@ -2713,6 +2686,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2713 if (!dev) 2686 if (!dev)
2714 goto err_out; 2687 goto err_out;
2715 SET_MODULE_OWNER(dev); 2688 SET_MODULE_OWNER(dev);
2689 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
2716 2690
2717 if (hme_version_printed++ == 0) 2691 if (hme_version_printed++ == 0)
2718 printk(KERN_INFO "%s", version); 2692 printk(KERN_INFO "%s", version);
@@ -2728,13 +2702,16 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2728 for (i = 0; i < 6; i++) 2702 for (i = 0; i < 6; i++)
2729 dev->dev_addr[i] = macaddr[i]; 2703 dev->dev_addr[i] = macaddr[i];
2730 macaddr[5]++; 2704 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 { 2705 } else {
2737 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 2706 unsigned char *addr;
2707 int len;
2708
2709 addr = of_get_property(dp, "local-mac-address", &len);
2710
2711 if (qfe_slot != -1 && addr && len == 6)
2712 memcpy(dev->dev_addr, addr, 6);
2713 else
2714 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2738 } 2715 }
2739 2716
2740 hp = dev->priv; 2717 hp = dev->priv;
@@ -2745,9 +2722,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2745 2722
2746 err = -ENODEV; 2723 err = -ENODEV;
2747 if (sdev->num_registers != 5) { 2724 if (sdev->num_registers != 5) {
2748 printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", 2725 printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n",
2749 sdev->num_registers); 2726 sdev->num_registers);
2750 printk(KERN_ERR "happymeal: Would you like that for here or to go?\n");
2751 goto err_out_free_netdev; 2727 goto err_out_free_netdev;
2752 } 2728 }
2753 2729
@@ -2761,39 +2737,39 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2761 hp->gregs = sbus_ioremap(&sdev->resource[0], 0, 2737 hp->gregs = sbus_ioremap(&sdev->resource[0], 0,
2762 GREG_REG_SIZE, "HME Global Regs"); 2738 GREG_REG_SIZE, "HME Global Regs");
2763 if (!hp->gregs) { 2739 if (!hp->gregs) {
2764 printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); 2740 printk(KERN_ERR "happymeal: Cannot map global registers.\n");
2765 goto err_out_free_netdev; 2741 goto err_out_free_netdev;
2766 } 2742 }
2767 2743
2768 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, 2744 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
2769 ETX_REG_SIZE, "HME TX Regs"); 2745 ETX_REG_SIZE, "HME TX Regs");
2770 if (!hp->etxregs) { 2746 if (!hp->etxregs) {
2771 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); 2747 printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n");
2772 goto err_out_iounmap; 2748 goto err_out_iounmap;
2773 } 2749 }
2774 2750
2775 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, 2751 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
2776 ERX_REG_SIZE, "HME RX Regs"); 2752 ERX_REG_SIZE, "HME RX Regs");
2777 if (!hp->erxregs) { 2753 if (!hp->erxregs) {
2778 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); 2754 printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n");
2779 goto err_out_iounmap; 2755 goto err_out_iounmap;
2780 } 2756 }
2781 2757
2782 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, 2758 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
2783 BMAC_REG_SIZE, "HME BIGMAC Regs"); 2759 BMAC_REG_SIZE, "HME BIGMAC Regs");
2784 if (!hp->bigmacregs) { 2760 if (!hp->bigmacregs) {
2785 printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); 2761 printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n");
2786 goto err_out_iounmap; 2762 goto err_out_iounmap;
2787 } 2763 }
2788 2764
2789 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, 2765 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
2790 TCVR_REG_SIZE, "HME Tranceiver Regs"); 2766 TCVR_REG_SIZE, "HME Tranceiver Regs");
2791 if (!hp->tcvregs) { 2767 if (!hp->tcvregs) {
2792 printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); 2768 printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n");
2793 goto err_out_iounmap; 2769 goto err_out_iounmap;
2794 } 2770 }
2795 2771
2796 hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); 2772 hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
2797 if (hp->hm_revision == 0xff) 2773 if (hp->hm_revision == 0xff)
2798 hp->hm_revision = 0xa0; 2774 hp->hm_revision = 0xa0;
2799 2775
@@ -2807,8 +2783,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2807 hp->happy_flags |= HFLAG_QUATTRO; 2783 hp->happy_flags |= HFLAG_QUATTRO;
2808 2784
2809 /* Get the supported DVMA burst sizes from our Happy SBUS. */ 2785 /* Get the supported DVMA burst sizes from our Happy SBUS. */
2810 hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, 2786 hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node,
2811 "burst-sizes", 0x00); 2787 "burst-sizes", 0x00);
2812 2788
2813 hp->happy_block = sbus_alloc_consistent(hp->happy_dev, 2789 hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
2814 PAGE_SIZE, 2790 PAGE_SIZE,
@@ -2871,6 +2847,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2871 goto err_out_free_consistent; 2847 goto err_out_free_consistent;
2872 } 2848 }
2873 2849
2850 dev_set_drvdata(&sdev->ofdev.dev, hp);
2851
2874 if (qfe_slot != -1) 2852 if (qfe_slot != -1)
2875 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", 2853 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
2876 dev->name, qfe_slot); 2854 dev->name, qfe_slot);
@@ -2883,12 +2861,6 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2883 dev->dev_addr[i], i == 5 ? ' ' : ':'); 2861 dev->dev_addr[i], i == 5 ? ' ' : ':');
2884 printk("\n"); 2862 printk("\n");
2885 2863
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; 2864 return 0;
2893 2865
2894err_out_free_consistent: 2866err_out_free_consistent:
@@ -2918,7 +2890,7 @@ err_out:
2918#endif 2890#endif
2919 2891
2920#ifdef CONFIG_PCI 2892#ifdef CONFIG_PCI
2921#ifndef __sparc__ 2893#ifndef CONFIG_SPARC
2922static int is_quattro_p(struct pci_dev *pdev) 2894static int is_quattro_p(struct pci_dev *pdev)
2923{ 2895{
2924 struct pci_dev *busdev = pdev->bus->self; 2896 struct pci_dev *busdev = pdev->bus->self;
@@ -3006,14 +2978,14 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
3006 get_random_bytes(&dev_addr[3], 3); 2978 get_random_bytes(&dev_addr[3], 3);
3007 return; 2979 return;
3008} 2980}
3009#endif /* !(__sparc__) */ 2981#endif /* !(CONFIG_SPARC) */
3010 2982
3011static int __init happy_meal_pci_init(struct pci_dev *pdev) 2983static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
2984 const struct pci_device_id *ent)
3012{ 2985{
3013 struct quattro *qp = NULL; 2986 struct quattro *qp = NULL;
3014#ifdef __sparc__ 2987#ifdef CONFIG_SPARC
3015 struct pcidev_cookie *pcp; 2988 struct pcidev_cookie *pcp;
3016 int node;
3017#endif 2989#endif
3018 struct happy_meal *hp; 2990 struct happy_meal *hp;
3019 struct net_device *dev; 2991 struct net_device *dev;
@@ -3024,15 +2996,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3024 int err; 2996 int err;
3025 2997
3026 /* Now make sure pci_dev cookie is there. */ 2998 /* Now make sure pci_dev cookie is there. */
3027#ifdef __sparc__ 2999#ifdef CONFIG_SPARC
3028 pcp = pdev->sysdata; 3000 pcp = pdev->sysdata;
3029 if (pcp == NULL || pcp->prom_node == -1) { 3001 if (pcp == NULL) {
3030 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); 3002 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n");
3031 return -ENODEV; 3003 return -ENODEV;
3032 } 3004 }
3033 node = pcp->prom_node; 3005
3034 3006 strcpy(prom_name, pcp->prom_node->name);
3035 prom_getstring(node, "name", prom_name, sizeof(prom_name));
3036#else 3007#else
3037 if (is_quattro_p(pdev)) 3008 if (is_quattro_p(pdev))
3038 strcpy(prom_name, "SUNW,qfe"); 3009 strcpy(prom_name, "SUNW,qfe");
@@ -3075,7 +3046,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3075 hp->qfe_parent = qp; 3046 hp->qfe_parent = qp;
3076 hp->qfe_ent = qfe_slot; 3047 hp->qfe_ent = qfe_slot;
3077 qp->happy_meals[qfe_slot] = dev; 3048 qp->happy_meals[qfe_slot] = dev;
3078 } 3049 }
3079 3050
3080 hpreg_res = pci_resource_start(pdev, 0); 3051 hpreg_res = pci_resource_start(pdev, 0);
3081 err = -ENODEV; 3052 err = -ENODEV;
@@ -3103,11 +3074,15 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3103 dev->dev_addr[i] = macaddr[i]; 3074 dev->dev_addr[i] = macaddr[i];
3104 macaddr[5]++; 3075 macaddr[5]++;
3105 } else { 3076 } else {
3106#ifdef __sparc__ 3077#ifdef CONFIG_SPARC
3078 unsigned char *addr;
3079 int len;
3080
3107 if (qfe_slot != -1 && 3081 if (qfe_slot != -1 &&
3108 prom_getproplen(node, "local-mac-address") == 6) { 3082 (addr = of_get_property(pcp->prom_node,
3109 prom_getproperty(node, "local-mac-address", 3083 "local-mac-address", &len)) != NULL
3110 dev->dev_addr, 6); 3084 && len == 6) {
3085 memcpy(dev->dev_addr, addr, 6);
3111 } else { 3086 } else {
3112 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 3087 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
3113 } 3088 }
@@ -3115,7 +3090,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3115 get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]); 3090 get_hme_mac_nonsparc(pdev, &dev->dev_addr[0]);
3116#endif 3091#endif
3117 } 3092 }
3118 3093
3119 /* Layout registers. */ 3094 /* Layout registers. */
3120 hp->gregs = (hpreg_base + 0x0000UL); 3095 hp->gregs = (hpreg_base + 0x0000UL);
3121 hp->etxregs = (hpreg_base + 0x2000UL); 3096 hp->etxregs = (hpreg_base + 0x2000UL);
@@ -3123,8 +3098,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3123 hp->bigmacregs = (hpreg_base + 0x6000UL); 3098 hp->bigmacregs = (hpreg_base + 0x6000UL);
3124 hp->tcvregs = (hpreg_base + 0x7000UL); 3099 hp->tcvregs = (hpreg_base + 0x7000UL);
3125 3100
3126#ifdef __sparc__ 3101#ifdef CONFIG_SPARC
3127 hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); 3102 hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff);
3128 if (hp->hm_revision == 0xff) { 3103 if (hp->hm_revision == 0xff) {
3129 unsigned char prev; 3104 unsigned char prev;
3130 3105
@@ -3148,7 +3123,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3148 /* And of course, indicate this is PCI. */ 3123 /* And of course, indicate this is PCI. */
3149 hp->happy_flags |= HFLAG_PCI; 3124 hp->happy_flags |= HFLAG_PCI;
3150 3125
3151#ifdef __sparc__ 3126#ifdef CONFIG_SPARC
3152 /* Assume PCI happy meals can handle all burst sizes. */ 3127 /* Assume PCI happy meals can handle all burst sizes. */
3153 hp->happy_bursts = DMA_BURSTBITS; 3128 hp->happy_bursts = DMA_BURSTBITS;
3154#endif 3129#endif
@@ -3211,6 +3186,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3211 goto err_out_iounmap; 3186 goto err_out_iounmap;
3212 } 3187 }
3213 3188
3189 dev_set_drvdata(&pdev->dev, hp);
3190
3214 if (!qfe_slot) { 3191 if (!qfe_slot) {
3215 struct pci_dev *qpdev = qp->quattro_dev; 3192 struct pci_dev *qpdev = qp->quattro_dev;
3216 3193
@@ -3224,7 +3201,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3224 qpdev->device == PCI_DEVICE_ID_DEC_21153) 3201 qpdev->device == PCI_DEVICE_ID_DEC_21153)
3225 printk("DEC 21153 PCI Bridge\n"); 3202 printk("DEC 21153 PCI Bridge\n");
3226 else 3203 else
3227 printk("unknown bridge %04x.%04x\n", 3204 printk("unknown bridge %04x.%04x\n",
3228 qpdev->vendor, qpdev->device); 3205 qpdev->vendor, qpdev->device);
3229 } 3206 }
3230 3207
@@ -3240,12 +3217,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3240 3217
3241 printk("\n"); 3218 printk("\n");
3242 3219
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; 3220 return 0;
3250 3221
3251err_out_iounmap: 3222err_out_iounmap:
@@ -3263,136 +3234,141 @@ err_out_clear_quattro:
3263err_out: 3234err_out:
3264 return err; 3235 return err;
3265} 3236}
3266#endif
3267 3237
3268#ifdef CONFIG_SBUS 3238static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
3269static int __init happy_meal_sbus_probe(void)
3270{ 3239{
3271 struct sbus_bus *sbus; 3240 struct happy_meal *hp = dev_get_drvdata(&pdev->dev);
3272 struct sbus_dev *sdev; 3241 struct net_device *net_dev = hp->dev;
3273 int cards = 0; 3242
3274 char model[128]; 3243 unregister_netdev(net_dev);
3275 3244
3276 for_each_sbus(sbus) { 3245 pci_free_consistent(hp->happy_dev,
3277 for_each_sbusdev(sdev, sbus) { 3246 PAGE_SIZE,
3278 char *name = sdev->prom_name; 3247 hp->happy_block,
3279 3248 hp->hblock_dvma);
3280 if (!strcmp(name, "SUNW,hme")) { 3249 iounmap(hp->gregs);
3281 cards++; 3250 pci_release_regions(hp->happy_dev);
3282 prom_getstring(sdev->prom_node, "model", 3251
3283 model, sizeof(model)); 3252 free_netdev(net_dev);
3284 if (!strcmp(model, "SUNW,sbus-qfe")) 3253
3285 happy_meal_sbus_init(sdev, 1); 3254 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} 3255}
3299#endif
3300 3256
3301#ifdef CONFIG_PCI 3257static struct pci_device_id happymeal_pci_ids[] = {
3302static int __init happy_meal_pci_probe(void) 3258 { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) },
3259 { } /* Terminating entry */
3260};
3261
3262MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
3263
3264static struct pci_driver hme_pci_driver = {
3265 .name = "hme",
3266 .id_table = happymeal_pci_ids,
3267 .probe = happy_meal_pci_probe,
3268 .remove = __devexit_p(happy_meal_pci_remove),
3269};
3270
3271static int __init happy_meal_pci_init(void)
3272{
3273 return pci_register_driver(&hme_pci_driver);
3274}
3275
3276static void happy_meal_pci_exit(void)
3303{ 3277{
3304 struct pci_dev *pdev = NULL; 3278 pci_unregister_driver(&hme_pci_driver);
3305 int cards = 0;
3306 3279
3307 while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, 3280 while (qfe_pci_list) {
3308 PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { 3281 struct quattro *qfe = qfe_pci_list;
3309 if (pci_enable_device(pdev)) 3282 struct quattro *next = qfe->next;
3310 continue; 3283
3311 pci_set_master(pdev); 3284 kfree(qfe);
3312 cards++; 3285
3313 happy_meal_pci_init(pdev); 3286 qfe_pci_list = next;
3314 } 3287 }
3315 return cards;
3316} 3288}
3289
3317#endif 3290#endif
3318 3291
3319static int __init happy_meal_probe(void) 3292#ifdef CONFIG_SBUS
3293static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match)
3320{ 3294{
3321 static int called = 0; 3295 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
3322 int cards; 3296 struct device_node *dp = dev->node;
3297 char *model = of_get_property(dp, "model", NULL);
3298 int is_qfe = (match->data != NULL);
3323 3299
3324 root_happy_dev = NULL; 3300 if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe"))
3301 is_qfe = 1;
3325 3302
3326 if (called) 3303 return happy_meal_sbus_probe_one(sdev, is_qfe);
3327 return -ENODEV; 3304}
3328 called++; 3305
3306static int __devexit hme_sbus_remove(struct of_device *dev)
3307{
3308 struct happy_meal *hp = dev_get_drvdata(&dev->dev);
3309 struct net_device *net_dev = hp->dev;
3310
3311 unregister_netdevice(net_dev);
3312
3313 /* XXX qfe parent interrupt... */
3314
3315 sbus_iounmap(hp->gregs, GREG_REG_SIZE);
3316 sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
3317 sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
3318 sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
3319 sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
3320 sbus_free_consistent(hp->happy_dev,
3321 PAGE_SIZE,
3322 hp->happy_block,
3323 hp->hblock_dvma);
3324
3325 free_netdev(net_dev);
3326
3327 dev_set_drvdata(&dev->dev, NULL);
3329 3328
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; 3329 return 0;
3340} 3330}
3341 3331
3332static struct of_device_id hme_sbus_match[] = {
3333 {
3334 .name = "SUNW,hme",
3335 },
3336 {
3337 .name = "SUNW,qfe",
3338 .data = (void *) 1,
3339 },
3340 {
3341 .name = "qfe",
3342 .data = (void *) 1,
3343 },
3344 {},
3345};
3342 3346
3343static void __exit happy_meal_cleanup_module(void) 3347MODULE_DEVICE_TABLE(of, hme_sbus_match);
3344{
3345#ifdef CONFIG_SBUS
3346 struct quattro *last_seen_qfe = NULL;
3347#endif
3348 3348
3349 while (root_happy_dev) { 3349static struct of_platform_driver hme_sbus_driver = {
3350 struct happy_meal *hp = root_happy_dev; 3350 .name = "hme",
3351 struct happy_meal *next = root_happy_dev->next_module; 3351 .match_table = hme_sbus_match,
3352 struct net_device *dev = hp->dev; 3352 .probe = hme_sbus_probe,
3353 .remove = __devexit_p(hme_sbus_remove),
3354};
3353 3355
3354 /* Unregister netdev before unmapping registers as this 3356static int __init happy_meal_sbus_init(void)
3355 * call can end up trying to access those registers. 3357{
3356 */ 3358 int err;
3357 unregister_netdev(dev);
3358 3359
3359#ifdef CONFIG_SBUS 3360 err = of_register_driver(&hme_sbus_driver, &sbus_bus_type);
3360 if (!(hp->happy_flags & HFLAG_PCI)) { 3361 if (!err)
3361 if (hp->happy_flags & HFLAG_QUATTRO) { 3362 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 3363
3368 sbus_iounmap(hp->gregs, GREG_REG_SIZE); 3364 return err;
3369 sbus_iounmap(hp->etxregs, ETX_REG_SIZE); 3365}
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 3366
3391 root_happy_dev = next; 3367static void happy_meal_sbus_exit(void)
3392 } 3368{
3369 of_unregister_driver(&hme_sbus_driver);
3370 quattro_sbus_free_irqs();
3393 3371
3394 /* Now cleanup the quattro lists. */
3395#ifdef CONFIG_SBUS
3396 while (qfe_sbus_list) { 3372 while (qfe_sbus_list) {
3397 struct quattro *qfe = qfe_sbus_list; 3373 struct quattro *qfe = qfe_sbus_list;
3398 struct quattro *next = qfe->next; 3374 struct quattro *next = qfe->next;
@@ -3401,18 +3377,39 @@ static void __exit happy_meal_cleanup_module(void)
3401 3377
3402 qfe_sbus_list = next; 3378 qfe_sbus_list = next;
3403 } 3379 }
3380}
3404#endif 3381#endif
3405#ifdef CONFIG_PCI
3406 while (qfe_pci_list) {
3407 struct quattro *qfe = qfe_pci_list;
3408 struct quattro *next = qfe->next;
3409 3382
3410 kfree(qfe); 3383static int __init happy_meal_probe(void)
3384{
3385 int err = 0;
3411 3386
3412 qfe_pci_list = next; 3387#ifdef CONFIG_SBUS
3388 err = happy_meal_sbus_init();
3389#endif
3390#ifdef CONFIG_PCI
3391 if (!err) {
3392 err = happy_meal_pci_init();
3393#ifdef CONFIG_SBUS
3394 if (err)
3395 happy_meal_sbus_exit();
3396#endif
3413 } 3397 }
3414#endif 3398#endif
3399
3400 return err;
3401}
3402
3403
3404static void __exit happy_meal_exit(void)
3405{
3406#ifdef CONFIG_SBUS
3407 happy_meal_sbus_exit();
3408#endif
3409#ifdef CONFIG_PCI
3410 happy_meal_pci_exit();
3411#endif
3415} 3412}
3416 3413
3417module_init(happy_meal_probe); 3414module_init(happy_meal_probe);
3418module_exit(happy_meal_cleanup_module); 3415module_exit(happy_meal_exit);