diff options
Diffstat (limited to 'drivers/net/sb1250-mac.c')
-rw-r--r-- | drivers/net/sb1250-mac.c | 331 |
1 files changed, 34 insertions, 297 deletions
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 332031747a23..fec3c29b2ea8 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -48,23 +48,6 @@ | |||
48 | #include <asm/io.h> | 48 | #include <asm/io.h> |
49 | #include <asm/processor.h> /* Processor type for cache alignment. */ | 49 | #include <asm/processor.h> /* Processor type for cache alignment. */ |
50 | 50 | ||
51 | /* This is only here until the firmware is ready. In that case, | ||
52 | the firmware leaves the ethernet address in the register for us. */ | ||
53 | #ifdef CONFIG_SIBYTE_STANDALONE | ||
54 | #define SBMAC_ETH0_HWADDR "40:00:00:00:01:00" | ||
55 | #define SBMAC_ETH1_HWADDR "40:00:00:00:01:01" | ||
56 | #define SBMAC_ETH2_HWADDR "40:00:00:00:01:02" | ||
57 | #define SBMAC_ETH3_HWADDR "40:00:00:00:01:03" | ||
58 | #endif | ||
59 | |||
60 | |||
61 | /* These identify the driver base version and may not be removed. */ | ||
62 | #if 0 | ||
63 | static char version1[] __initdata = | ||
64 | "sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg\n"; | ||
65 | #endif | ||
66 | |||
67 | |||
68 | /* Operational parameters that usually are not changed. */ | 51 | /* Operational parameters that usually are not changed. */ |
69 | 52 | ||
70 | #define CONFIG_SBMAC_COALESCE | 53 | #define CONFIG_SBMAC_COALESCE |
@@ -349,7 +332,6 @@ static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx, | |||
349 | ********************************************************************* */ | 332 | ********************************************************************* */ |
350 | 333 | ||
351 | static char sbmac_string[] = "sb1250-mac"; | 334 | static char sbmac_string[] = "sb1250-mac"; |
352 | static char sbmac_pretty[] = "SB1250 MAC"; | ||
353 | 335 | ||
354 | static char sbmac_mdio_string[] = "sb1250-mac-mdio"; | 336 | static char sbmac_mdio_string[] = "sb1250-mac-mdio"; |
355 | 337 | ||
@@ -2182,85 +2164,6 @@ static void sbmac_setmulti(struct sbmac_softc *sc) | |||
2182 | } | 2164 | } |
2183 | } | 2165 | } |
2184 | 2166 | ||
2185 | #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) | ||
2186 | /********************************************************************** | ||
2187 | * SBMAC_PARSE_XDIGIT(str) | ||
2188 | * | ||
2189 | * Parse a hex digit, returning its value | ||
2190 | * | ||
2191 | * Input parameters: | ||
2192 | * str - character | ||
2193 | * | ||
2194 | * Return value: | ||
2195 | * hex value, or -1 if invalid | ||
2196 | ********************************************************************* */ | ||
2197 | |||
2198 | static int sbmac_parse_xdigit(char str) | ||
2199 | { | ||
2200 | int digit; | ||
2201 | |||
2202 | if ((str >= '0') && (str <= '9')) | ||
2203 | digit = str - '0'; | ||
2204 | else if ((str >= 'a') && (str <= 'f')) | ||
2205 | digit = str - 'a' + 10; | ||
2206 | else if ((str >= 'A') && (str <= 'F')) | ||
2207 | digit = str - 'A' + 10; | ||
2208 | else | ||
2209 | return -1; | ||
2210 | |||
2211 | return digit; | ||
2212 | } | ||
2213 | |||
2214 | /********************************************************************** | ||
2215 | * SBMAC_PARSE_HWADDR(str,hwaddr) | ||
2216 | * | ||
2217 | * Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte | ||
2218 | * Ethernet address. | ||
2219 | * | ||
2220 | * Input parameters: | ||
2221 | * str - string | ||
2222 | * hwaddr - pointer to hardware address | ||
2223 | * | ||
2224 | * Return value: | ||
2225 | * 0 if ok, else -1 | ||
2226 | ********************************************************************* */ | ||
2227 | |||
2228 | static int sbmac_parse_hwaddr(char *str, unsigned char *hwaddr) | ||
2229 | { | ||
2230 | int digit1,digit2; | ||
2231 | int idx = 6; | ||
2232 | |||
2233 | while (*str && (idx > 0)) { | ||
2234 | digit1 = sbmac_parse_xdigit(*str); | ||
2235 | if (digit1 < 0) | ||
2236 | return -1; | ||
2237 | str++; | ||
2238 | if (!*str) | ||
2239 | return -1; | ||
2240 | |||
2241 | if ((*str == ':') || (*str == '-')) { | ||
2242 | digit2 = digit1; | ||
2243 | digit1 = 0; | ||
2244 | } | ||
2245 | else { | ||
2246 | digit2 = sbmac_parse_xdigit(*str); | ||
2247 | if (digit2 < 0) | ||
2248 | return -1; | ||
2249 | str++; | ||
2250 | } | ||
2251 | |||
2252 | *hwaddr++ = (digit1 << 4) | digit2; | ||
2253 | idx--; | ||
2254 | |||
2255 | if (*str == '-') | ||
2256 | str++; | ||
2257 | if (*str == ':') | ||
2258 | str++; | ||
2259 | } | ||
2260 | return 0; | ||
2261 | } | ||
2262 | #endif | ||
2263 | |||
2264 | static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) | 2167 | static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) |
2265 | { | 2168 | { |
2266 | if (new_mtu > ENET_PACKET_SIZE) | 2169 | if (new_mtu > ENET_PACKET_SIZE) |
@@ -2353,17 +2256,36 @@ static int sbmac_init(struct platform_device *pldev, long long base) | |||
2353 | 2256 | ||
2354 | sc->mii_bus = mdiobus_alloc(); | 2257 | sc->mii_bus = mdiobus_alloc(); |
2355 | if (sc->mii_bus == NULL) { | 2258 | if (sc->mii_bus == NULL) { |
2356 | sbmac_uninitctx(sc); | 2259 | err = -ENOMEM; |
2357 | return -ENOMEM; | 2260 | goto uninit_ctx; |
2261 | } | ||
2262 | |||
2263 | sc->mii_bus->name = sbmac_mdio_string; | ||
2264 | snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx); | ||
2265 | sc->mii_bus->priv = sc; | ||
2266 | sc->mii_bus->read = sbmac_mii_read; | ||
2267 | sc->mii_bus->write = sbmac_mii_write; | ||
2268 | sc->mii_bus->irq = sc->phy_irq; | ||
2269 | for (i = 0; i < PHY_MAX_ADDR; ++i) | ||
2270 | sc->mii_bus->irq[i] = SBMAC_PHY_INT; | ||
2271 | |||
2272 | sc->mii_bus->parent = &pldev->dev; | ||
2273 | /* | ||
2274 | * Probe PHY address | ||
2275 | */ | ||
2276 | err = mdiobus_register(sc->mii_bus); | ||
2277 | if (err) { | ||
2278 | printk(KERN_ERR "%s: unable to register MDIO bus\n", | ||
2279 | dev->name); | ||
2280 | goto free_mdio; | ||
2358 | } | 2281 | } |
2282 | dev_set_drvdata(&pldev->dev, sc->mii_bus); | ||
2359 | 2283 | ||
2360 | err = register_netdev(dev); | 2284 | err = register_netdev(dev); |
2361 | if (err) { | 2285 | if (err) { |
2362 | printk(KERN_ERR "%s.%d: unable to register netdev\n", | 2286 | printk(KERN_ERR "%s.%d: unable to register netdev\n", |
2363 | sbmac_string, idx); | 2287 | sbmac_string, idx); |
2364 | mdiobus_free(sc->mii_bus); | 2288 | goto unreg_mdio; |
2365 | sbmac_uninitctx(sc); | ||
2366 | return err; | ||
2367 | } | 2289 | } |
2368 | 2290 | ||
2369 | pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name); | 2291 | pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name); |
@@ -2379,19 +2301,15 @@ static int sbmac_init(struct platform_device *pldev, long long base) | |||
2379 | pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n", | 2301 | pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n", |
2380 | dev->name, base, eaddr); | 2302 | dev->name, base, eaddr); |
2381 | 2303 | ||
2382 | sc->mii_bus->name = sbmac_mdio_string; | ||
2383 | snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx); | ||
2384 | sc->mii_bus->priv = sc; | ||
2385 | sc->mii_bus->read = sbmac_mii_read; | ||
2386 | sc->mii_bus->write = sbmac_mii_write; | ||
2387 | sc->mii_bus->irq = sc->phy_irq; | ||
2388 | for (i = 0; i < PHY_MAX_ADDR; ++i) | ||
2389 | sc->mii_bus->irq[i] = SBMAC_PHY_INT; | ||
2390 | |||
2391 | sc->mii_bus->parent = &pldev->dev; | ||
2392 | dev_set_drvdata(&pldev->dev, sc->mii_bus); | ||
2393 | |||
2394 | return 0; | 2304 | return 0; |
2305 | unreg_mdio: | ||
2306 | mdiobus_unregister(sc->mii_bus); | ||
2307 | dev_set_drvdata(&pldev->dev, NULL); | ||
2308 | free_mdio: | ||
2309 | mdiobus_free(sc->mii_bus); | ||
2310 | uninit_ctx: | ||
2311 | sbmac_uninitctx(sc); | ||
2312 | return err; | ||
2395 | } | 2313 | } |
2396 | 2314 | ||
2397 | 2315 | ||
@@ -2417,16 +2335,6 @@ static int sbmac_open(struct net_device *dev) | |||
2417 | goto out_err; | 2335 | goto out_err; |
2418 | } | 2336 | } |
2419 | 2337 | ||
2420 | /* | ||
2421 | * Probe PHY address | ||
2422 | */ | ||
2423 | err = mdiobus_register(sc->mii_bus); | ||
2424 | if (err) { | ||
2425 | printk(KERN_ERR "%s: unable to register MDIO bus\n", | ||
2426 | dev->name); | ||
2427 | goto out_unirq; | ||
2428 | } | ||
2429 | |||
2430 | sc->sbm_speed = sbmac_speed_none; | 2338 | sc->sbm_speed = sbmac_speed_none; |
2431 | sc->sbm_duplex = sbmac_duplex_none; | 2339 | sc->sbm_duplex = sbmac_duplex_none; |
2432 | sc->sbm_fc = sbmac_fc_none; | 2340 | sc->sbm_fc = sbmac_fc_none; |
@@ -2457,11 +2365,7 @@ static int sbmac_open(struct net_device *dev) | |||
2457 | return 0; | 2365 | return 0; |
2458 | 2366 | ||
2459 | out_unregister: | 2367 | out_unregister: |
2460 | mdiobus_unregister(sc->mii_bus); | ||
2461 | |||
2462 | out_unirq: | ||
2463 | free_irq(dev->irq, dev); | 2368 | free_irq(dev->irq, dev); |
2464 | |||
2465 | out_err: | 2369 | out_err: |
2466 | return err; | 2370 | return err; |
2467 | } | 2371 | } |
@@ -2650,9 +2554,6 @@ static int sbmac_close(struct net_device *dev) | |||
2650 | 2554 | ||
2651 | phy_disconnect(sc->phy_dev); | 2555 | phy_disconnect(sc->phy_dev); |
2652 | sc->phy_dev = NULL; | 2556 | sc->phy_dev = NULL; |
2653 | |||
2654 | mdiobus_unregister(sc->mii_bus); | ||
2655 | |||
2656 | free_irq(dev->irq, dev); | 2557 | free_irq(dev->irq, dev); |
2657 | 2558 | ||
2658 | sbdma_emptyring(&(sc->sbm_txdma)); | 2559 | sbdma_emptyring(&(sc->sbm_txdma)); |
@@ -2759,6 +2660,7 @@ static int __exit sbmac_remove(struct platform_device *pldev) | |||
2759 | 2660 | ||
2760 | unregister_netdev(dev); | 2661 | unregister_netdev(dev); |
2761 | sbmac_uninitctx(sc); | 2662 | sbmac_uninitctx(sc); |
2663 | mdiobus_unregister(sc->mii_bus); | ||
2762 | mdiobus_free(sc->mii_bus); | 2664 | mdiobus_free(sc->mii_bus); |
2763 | iounmap(sc->sbm_base); | 2665 | iounmap(sc->sbm_base); |
2764 | free_netdev(dev); | 2666 | free_netdev(dev); |
@@ -2766,162 +2668,6 @@ static int __exit sbmac_remove(struct platform_device *pldev) | |||
2766 | return 0; | 2668 | return 0; |
2767 | } | 2669 | } |
2768 | 2670 | ||
2769 | |||
2770 | static struct platform_device **sbmac_pldev; | ||
2771 | static int sbmac_max_units; | ||
2772 | |||
2773 | #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) | ||
2774 | static void __init sbmac_setup_hwaddr(int idx, char *addr) | ||
2775 | { | ||
2776 | void __iomem *sbm_base; | ||
2777 | unsigned long start, end; | ||
2778 | uint8_t eaddr[6]; | ||
2779 | uint64_t val; | ||
2780 | |||
2781 | if (idx >= sbmac_max_units) | ||
2782 | return; | ||
2783 | |||
2784 | start = A_MAC_CHANNEL_BASE(idx); | ||
2785 | end = A_MAC_CHANNEL_BASE(idx + 1) - 1; | ||
2786 | |||
2787 | sbm_base = ioremap_nocache(start, end - start + 1); | ||
2788 | if (!sbm_base) { | ||
2789 | printk(KERN_ERR "%s: unable to map device registers\n", | ||
2790 | sbmac_string); | ||
2791 | return; | ||
2792 | } | ||
2793 | |||
2794 | sbmac_parse_hwaddr(addr, eaddr); | ||
2795 | val = sbmac_addr2reg(eaddr); | ||
2796 | __raw_writeq(val, sbm_base + R_MAC_ETHERNET_ADDR); | ||
2797 | val = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR); | ||
2798 | |||
2799 | iounmap(sbm_base); | ||
2800 | } | ||
2801 | #endif | ||
2802 | |||
2803 | static int __init sbmac_platform_probe_one(int idx) | ||
2804 | { | ||
2805 | struct platform_device *pldev; | ||
2806 | struct { | ||
2807 | struct resource r; | ||
2808 | char name[strlen(sbmac_pretty) + 4]; | ||
2809 | } *res; | ||
2810 | int err; | ||
2811 | |||
2812 | res = kzalloc(sizeof(*res), GFP_KERNEL); | ||
2813 | if (!res) { | ||
2814 | printk(KERN_ERR "%s.%d: unable to allocate memory\n", | ||
2815 | sbmac_string, idx); | ||
2816 | err = -ENOMEM; | ||
2817 | goto out_err; | ||
2818 | } | ||
2819 | |||
2820 | /* | ||
2821 | * This is the base address of the MAC. | ||
2822 | */ | ||
2823 | snprintf(res->name, sizeof(res->name), "%s %d", sbmac_pretty, idx); | ||
2824 | res->r.name = res->name; | ||
2825 | res->r.flags = IORESOURCE_MEM; | ||
2826 | res->r.start = A_MAC_CHANNEL_BASE(idx); | ||
2827 | res->r.end = A_MAC_CHANNEL_BASE(idx + 1) - 1; | ||
2828 | |||
2829 | pldev = platform_device_register_simple(sbmac_string, idx, &res->r, 1); | ||
2830 | if (IS_ERR(pldev)) { | ||
2831 | printk(KERN_ERR "%s.%d: unable to register platform device\n", | ||
2832 | sbmac_string, idx); | ||
2833 | err = PTR_ERR(pldev); | ||
2834 | goto out_kfree; | ||
2835 | } | ||
2836 | |||
2837 | if (!pldev->dev.driver) { | ||
2838 | err = 0; /* No hardware at this address. */ | ||
2839 | goto out_unregister; | ||
2840 | } | ||
2841 | |||
2842 | sbmac_pldev[idx] = pldev; | ||
2843 | return 0; | ||
2844 | |||
2845 | out_unregister: | ||
2846 | platform_device_unregister(pldev); | ||
2847 | |||
2848 | out_kfree: | ||
2849 | kfree(res); | ||
2850 | |||
2851 | out_err: | ||
2852 | return err; | ||
2853 | } | ||
2854 | |||
2855 | static void __init sbmac_platform_probe(void) | ||
2856 | { | ||
2857 | int i; | ||
2858 | |||
2859 | /* Set the number of available units based on the SOC type. */ | ||
2860 | switch (soc_type) { | ||
2861 | case K_SYS_SOC_TYPE_BCM1250: | ||
2862 | case K_SYS_SOC_TYPE_BCM1250_ALT: | ||
2863 | sbmac_max_units = 3; | ||
2864 | break; | ||
2865 | case K_SYS_SOC_TYPE_BCM1120: | ||
2866 | case K_SYS_SOC_TYPE_BCM1125: | ||
2867 | case K_SYS_SOC_TYPE_BCM1125H: | ||
2868 | case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ | ||
2869 | sbmac_max_units = 2; | ||
2870 | break; | ||
2871 | case K_SYS_SOC_TYPE_BCM1x55: | ||
2872 | case K_SYS_SOC_TYPE_BCM1x80: | ||
2873 | sbmac_max_units = 4; | ||
2874 | break; | ||
2875 | default: | ||
2876 | return; /* none */ | ||
2877 | } | ||
2878 | |||
2879 | /* | ||
2880 | * For bringup when not using the firmware, we can pre-fill | ||
2881 | * the MAC addresses using the environment variables | ||
2882 | * specified in this file (or maybe from the config file?) | ||
2883 | */ | ||
2884 | #ifdef SBMAC_ETH0_HWADDR | ||
2885 | sbmac_setup_hwaddr(0, SBMAC_ETH0_HWADDR); | ||
2886 | #endif | ||
2887 | #ifdef SBMAC_ETH1_HWADDR | ||
2888 | sbmac_setup_hwaddr(1, SBMAC_ETH1_HWADDR); | ||
2889 | #endif | ||
2890 | #ifdef SBMAC_ETH2_HWADDR | ||
2891 | sbmac_setup_hwaddr(2, SBMAC_ETH2_HWADDR); | ||
2892 | #endif | ||
2893 | #ifdef SBMAC_ETH3_HWADDR | ||
2894 | sbmac_setup_hwaddr(3, SBMAC_ETH3_HWADDR); | ||
2895 | #endif | ||
2896 | |||
2897 | sbmac_pldev = kcalloc(sbmac_max_units, sizeof(*sbmac_pldev), | ||
2898 | GFP_KERNEL); | ||
2899 | if (!sbmac_pldev) { | ||
2900 | printk(KERN_ERR "%s: unable to allocate memory\n", | ||
2901 | sbmac_string); | ||
2902 | return; | ||
2903 | } | ||
2904 | |||
2905 | /* | ||
2906 | * Walk through the Ethernet controllers and find | ||
2907 | * those who have their MAC addresses set. | ||
2908 | */ | ||
2909 | for (i = 0; i < sbmac_max_units; i++) | ||
2910 | if (sbmac_platform_probe_one(i)) | ||
2911 | break; | ||
2912 | } | ||
2913 | |||
2914 | |||
2915 | static void __exit sbmac_platform_cleanup(void) | ||
2916 | { | ||
2917 | int i; | ||
2918 | |||
2919 | for (i = 0; i < sbmac_max_units; i++) | ||
2920 | platform_device_unregister(sbmac_pldev[i]); | ||
2921 | kfree(sbmac_pldev); | ||
2922 | } | ||
2923 | |||
2924 | |||
2925 | static struct platform_driver sbmac_driver = { | 2671 | static struct platform_driver sbmac_driver = { |
2926 | .probe = sbmac_probe, | 2672 | .probe = sbmac_probe, |
2927 | .remove = __exit_p(sbmac_remove), | 2673 | .remove = __exit_p(sbmac_remove), |
@@ -2932,20 +2678,11 @@ static struct platform_driver sbmac_driver = { | |||
2932 | 2678 | ||
2933 | static int __init sbmac_init_module(void) | 2679 | static int __init sbmac_init_module(void) |
2934 | { | 2680 | { |
2935 | int err; | 2681 | return platform_driver_register(&sbmac_driver); |
2936 | |||
2937 | err = platform_driver_register(&sbmac_driver); | ||
2938 | if (err) | ||
2939 | return err; | ||
2940 | |||
2941 | sbmac_platform_probe(); | ||
2942 | |||
2943 | return err; | ||
2944 | } | 2682 | } |
2945 | 2683 | ||
2946 | static void __exit sbmac_cleanup_module(void) | 2684 | static void __exit sbmac_cleanup_module(void) |
2947 | { | 2685 | { |
2948 | sbmac_platform_cleanup(); | ||
2949 | platform_driver_unregister(&sbmac_driver); | 2686 | platform_driver_unregister(&sbmac_driver); |
2950 | } | 2687 | } |
2951 | 2688 | ||