diff options
Diffstat (limited to 'drivers/net/sb1250-mac.c')
-rw-r--r-- | drivers/net/sb1250-mac.c | 275 |
1 files changed, 5 insertions, 270 deletions
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 04efc0c1bda9..1f3acc3a5dfd 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 | ||
@@ -2086,8 +2068,6 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev) | |||
2086 | return NETDEV_TX_BUSY; | 2068 | return NETDEV_TX_BUSY; |
2087 | } | 2069 | } |
2088 | 2070 | ||
2089 | dev->trans_start = jiffies; | ||
2090 | |||
2091 | spin_unlock_irqrestore(&sc->sbm_lock, flags); | 2071 | spin_unlock_irqrestore(&sc->sbm_lock, flags); |
2092 | 2072 | ||
2093 | return NETDEV_TX_OK; | 2073 | return NETDEV_TX_OK; |
@@ -2112,7 +2092,7 @@ static void sbmac_setmulti(struct sbmac_softc *sc) | |||
2112 | uint64_t reg; | 2092 | uint64_t reg; |
2113 | void __iomem *port; | 2093 | void __iomem *port; |
2114 | int idx; | 2094 | int idx; |
2115 | struct dev_mc_list *mclist; | 2095 | struct netdev_hw_addr *ha; |
2116 | struct net_device *dev = sc->sbm_dev; | 2096 | struct net_device *dev = sc->sbm_dev; |
2117 | 2097 | ||
2118 | /* | 2098 | /* |
@@ -2161,10 +2141,10 @@ static void sbmac_setmulti(struct sbmac_softc *sc) | |||
2161 | * XXX if the table overflows */ | 2141 | * XXX if the table overflows */ |
2162 | 2142 | ||
2163 | idx = 1; /* skip station address */ | 2143 | idx = 1; /* skip station address */ |
2164 | netdev_for_each_mc_addr(mclist, dev) { | 2144 | netdev_for_each_mc_addr(ha, dev) { |
2165 | if (idx == MAC_ADDR_COUNT) | 2145 | if (idx == MAC_ADDR_COUNT) |
2166 | break; | 2146 | break; |
2167 | reg = sbmac_addr2reg(mclist->dmi_addr); | 2147 | reg = sbmac_addr2reg(ha->addr); |
2168 | port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); | 2148 | port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); |
2169 | __raw_writeq(reg, port); | 2149 | __raw_writeq(reg, port); |
2170 | idx++; | 2150 | idx++; |
@@ -2182,85 +2162,6 @@ static void sbmac_setmulti(struct sbmac_softc *sc) | |||
2182 | } | 2162 | } |
2183 | } | 2163 | } |
2184 | 2164 | ||
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) | 2165 | static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) |
2265 | { | 2166 | { |
2266 | if (new_mtu > ENET_PACKET_SIZE) | 2167 | if (new_mtu > ENET_PACKET_SIZE) |
@@ -2585,7 +2486,7 @@ static void sbmac_tx_timeout (struct net_device *dev) | |||
2585 | spin_lock_irqsave(&sc->sbm_lock, flags); | 2486 | spin_lock_irqsave(&sc->sbm_lock, flags); |
2586 | 2487 | ||
2587 | 2488 | ||
2588 | dev->trans_start = jiffies; | 2489 | dev->trans_start = jiffies; /* prevent tx timeout */ |
2589 | dev->stats.tx_errors++; | 2490 | dev->stats.tx_errors++; |
2590 | 2491 | ||
2591 | spin_unlock_irqrestore(&sc->sbm_lock, flags); | 2492 | spin_unlock_irqrestore(&sc->sbm_lock, flags); |
@@ -2662,7 +2563,6 @@ static int sbmac_close(struct net_device *dev) | |||
2662 | static int sbmac_poll(struct napi_struct *napi, int budget) | 2563 | static int sbmac_poll(struct napi_struct *napi, int budget) |
2663 | { | 2564 | { |
2664 | struct sbmac_softc *sc = container_of(napi, struct sbmac_softc, napi); | 2565 | struct sbmac_softc *sc = container_of(napi, struct sbmac_softc, napi); |
2665 | struct net_device *dev = sc->sbm_dev; | ||
2666 | int work_done; | 2566 | int work_done; |
2667 | 2567 | ||
2668 | work_done = sbdma_rx_process(sc, &(sc->sbm_rxdma), budget, 1); | 2568 | work_done = sbdma_rx_process(sc, &(sc->sbm_rxdma), budget, 1); |
@@ -2766,162 +2666,6 @@ static int __exit sbmac_remove(struct platform_device *pldev) | |||
2766 | return 0; | 2666 | return 0; |
2767 | } | 2667 | } |
2768 | 2668 | ||
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 = { | 2669 | static struct platform_driver sbmac_driver = { |
2926 | .probe = sbmac_probe, | 2670 | .probe = sbmac_probe, |
2927 | .remove = __exit_p(sbmac_remove), | 2671 | .remove = __exit_p(sbmac_remove), |
@@ -2932,20 +2676,11 @@ static struct platform_driver sbmac_driver = { | |||
2932 | 2676 | ||
2933 | static int __init sbmac_init_module(void) | 2677 | static int __init sbmac_init_module(void) |
2934 | { | 2678 | { |
2935 | int err; | 2679 | 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 | } | 2680 | } |
2945 | 2681 | ||
2946 | static void __exit sbmac_cleanup_module(void) | 2682 | static void __exit sbmac_cleanup_module(void) |
2947 | { | 2683 | { |
2948 | sbmac_platform_cleanup(); | ||
2949 | platform_driver_unregister(&sbmac_driver); | 2684 | platform_driver_unregister(&sbmac_driver); |
2950 | } | 2685 | } |
2951 | 2686 | ||