diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2006-02-08 18:23:26 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-03 21:23:02 -0500 |
commit | f90fdc3cce3d8c8ed09615dc68cb789655078803 (patch) | |
tree | 116371105890850b3c302eb6728b02675914efb7 | |
parent | c96a34ec3bad5ba37ee4da4a188ad534b2fa4321 (diff) |
[PATCH] sb1250-mac: Add support for the BCM1480
This adds support for the 4th port and other new features of the
BCM1480 SOC.
Signed-Off-By: Andy Isaacson <adi@broadcom.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/sb1250-mac.c | 109 |
1 files changed, 70 insertions, 39 deletions
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index aa4ca1821759..f2be9f83f091 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001,2002,2003 Broadcom Corporation | 2 | * Copyright (C) 2001,2002,2003,2004 Broadcom Corporation |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
@@ -43,6 +43,7 @@ | |||
43 | #define SBMAC_ETH0_HWADDR "40:00:00:00:01:00" | 43 | #define SBMAC_ETH0_HWADDR "40:00:00:00:01:00" |
44 | #define SBMAC_ETH1_HWADDR "40:00:00:00:01:01" | 44 | #define SBMAC_ETH1_HWADDR "40:00:00:00:01:01" |
45 | #define SBMAC_ETH2_HWADDR "40:00:00:00:01:02" | 45 | #define SBMAC_ETH2_HWADDR "40:00:00:00:01:02" |
46 | #define SBMAC_ETH3_HWADDR "40:00:00:00:01:03" | ||
46 | #endif | 47 | #endif |
47 | 48 | ||
48 | 49 | ||
@@ -57,7 +58,7 @@ static char version1[] __devinitdata = | |||
57 | 58 | ||
58 | #define CONFIG_SBMAC_COALESCE | 59 | #define CONFIG_SBMAC_COALESCE |
59 | 60 | ||
60 | #define MAX_UNITS 3 /* More are supported, limit only on options */ | 61 | #define MAX_UNITS 4 /* More are supported, limit only on options */ |
61 | 62 | ||
62 | /* Time in jiffies before concluding the transmitter is hung. */ | 63 | /* Time in jiffies before concluding the transmitter is hung. */ |
63 | #define TX_TIMEOUT (2*HZ) | 64 | #define TX_TIMEOUT (2*HZ) |
@@ -85,11 +86,11 @@ MODULE_PARM_DESC(noisy_mii, "MII status messages"); | |||
85 | The media type is usually passed in 'options[]'. | 86 | The media type is usually passed in 'options[]'. |
86 | */ | 87 | */ |
87 | #ifdef MODULE | 88 | #ifdef MODULE |
88 | static int options[MAX_UNITS] = {-1, -1, -1}; | 89 | static int options[MAX_UNITS] = {-1, -1, -1, -1}; |
89 | module_param_array(options, int, NULL, S_IRUGO); | 90 | module_param_array(options, int, NULL, S_IRUGO); |
90 | MODULE_PARM_DESC(options, "1-" __MODULE_STRING(MAX_UNITS)); | 91 | MODULE_PARM_DESC(options, "1-" __MODULE_STRING(MAX_UNITS)); |
91 | 92 | ||
92 | static int full_duplex[MAX_UNITS] = {-1, -1, -1}; | 93 | static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1}; |
93 | module_param_array(full_duplex, int, NULL, S_IRUGO); | 94 | module_param_array(full_duplex, int, NULL, S_IRUGO); |
94 | MODULE_PARM_DESC(full_duplex, "1-" __MODULE_STRING(MAX_UNITS)); | 95 | MODULE_PARM_DESC(full_duplex, "1-" __MODULE_STRING(MAX_UNITS)); |
95 | #endif | 96 | #endif |
@@ -105,13 +106,26 @@ MODULE_PARM_DESC(int_timeout, "Timeout value"); | |||
105 | #endif | 106 | #endif |
106 | 107 | ||
107 | #include <asm/sibyte/sb1250.h> | 108 | #include <asm/sibyte/sb1250.h> |
108 | #include <asm/sibyte/sb1250_defs.h> | 109 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) |
110 | #include <asm/sibyte/bcm1480_regs.h> | ||
111 | #include <asm/sibyte/bcm1480_int.h> | ||
112 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) | ||
109 | #include <asm/sibyte/sb1250_regs.h> | 113 | #include <asm/sibyte/sb1250_regs.h> |
110 | #include <asm/sibyte/sb1250_mac.h> | ||
111 | #include <asm/sibyte/sb1250_dma.h> | ||
112 | #include <asm/sibyte/sb1250_int.h> | 114 | #include <asm/sibyte/sb1250_int.h> |
115 | #else | ||
116 | #error invalid SiByte MAC configuation | ||
117 | #endif | ||
113 | #include <asm/sibyte/sb1250_scd.h> | 118 | #include <asm/sibyte/sb1250_scd.h> |
119 | #include <asm/sibyte/sb1250_mac.h> | ||
120 | #include <asm/sibyte/sb1250_dma.h> | ||
114 | 121 | ||
122 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | ||
123 | #define UNIT_INT(n) (K_BCM1480_INT_MAC_0 + ((n) * 2)) | ||
124 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) | ||
125 | #define UNIT_INT(n) (K_INT_MAC_0 + (n)) | ||
126 | #else | ||
127 | #error invalid SiByte MAC configuation | ||
128 | #endif | ||
115 | 129 | ||
116 | /********************************************************************** | 130 | /********************************************************************** |
117 | * Simple types | 131 | * Simple types |
@@ -1476,10 +1490,10 @@ static void sbmac_channel_start(struct sbmac_softc *s) | |||
1476 | * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above | 1490 | * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above |
1477 | * Use a larger RD_THRSH for gigabit | 1491 | * Use a larger RD_THRSH for gigabit |
1478 | */ | 1492 | */ |
1479 | if (periph_rev >= 2) | 1493 | if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) |
1480 | th_value = 64; | ||
1481 | else | ||
1482 | th_value = 28; | 1494 | th_value = 28; |
1495 | else | ||
1496 | th_value = 64; | ||
1483 | 1497 | ||
1484 | fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ | 1498 | fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ |
1485 | ((s->sbm_speed == sbmac_speed_1000) | 1499 | ((s->sbm_speed == sbmac_speed_1000) |
@@ -1589,13 +1603,17 @@ static void sbmac_channel_start(struct sbmac_softc *s) | |||
1589 | * Turn on the rest of the bits in the enable register | 1603 | * Turn on the rest of the bits in the enable register |
1590 | */ | 1604 | */ |
1591 | 1605 | ||
1606 | #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) | ||
1607 | __raw_writeq(M_MAC_RXDMA_EN0 | | ||
1608 | M_MAC_TXDMA_EN0, s->sbm_macenable); | ||
1609 | #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) | ||
1592 | __raw_writeq(M_MAC_RXDMA_EN0 | | 1610 | __raw_writeq(M_MAC_RXDMA_EN0 | |
1593 | M_MAC_TXDMA_EN0 | | 1611 | M_MAC_TXDMA_EN0 | |
1594 | M_MAC_RX_ENABLE | | 1612 | M_MAC_RX_ENABLE | |
1595 | M_MAC_TX_ENABLE, s->sbm_macenable); | 1613 | M_MAC_TX_ENABLE, s->sbm_macenable); |
1596 | 1614 | #else | |
1597 | 1615 | #error invalid SiByte MAC configuation | |
1598 | 1616 | #endif | |
1599 | 1617 | ||
1600 | #ifdef CONFIG_SBMAC_COALESCE | 1618 | #ifdef CONFIG_SBMAC_COALESCE |
1601 | /* | 1619 | /* |
@@ -1786,11 +1804,12 @@ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc) | |||
1786 | reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); | 1804 | reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); |
1787 | __raw_writeq(reg, sc->sbm_rxfilter); | 1805 | __raw_writeq(reg, sc->sbm_rxfilter); |
1788 | 1806 | ||
1789 | /* read system identification to determine revision */ | 1807 | /* BCM1250 pass1 didn't have hardware checksum. Everything |
1790 | if (periph_rev >= 2) { | 1808 | later does. */ |
1791 | sc->rx_hw_checksum = ENABLE; | 1809 | if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) { |
1792 | } else { | ||
1793 | sc->rx_hw_checksum = DISABLE; | 1810 | sc->rx_hw_checksum = DISABLE; |
1811 | } else { | ||
1812 | sc->rx_hw_checksum = ENABLE; | ||
1794 | } | 1813 | } |
1795 | } | 1814 | } |
1796 | 1815 | ||
@@ -2220,7 +2239,7 @@ static void sbmac_setmulti(struct sbmac_softc *sc) | |||
2220 | 2239 | ||
2221 | 2240 | ||
2222 | 2241 | ||
2223 | #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) | 2242 | #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) |
2224 | /********************************************************************** | 2243 | /********************************************************************** |
2225 | * SBMAC_PARSE_XDIGIT(str) | 2244 | * SBMAC_PARSE_XDIGIT(str) |
2226 | * | 2245 | * |
@@ -2792,7 +2811,7 @@ static int sbmac_close(struct net_device *dev) | |||
2792 | 2811 | ||
2793 | 2812 | ||
2794 | 2813 | ||
2795 | #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) | 2814 | #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR) |
2796 | static void | 2815 | static void |
2797 | sbmac_setup_hwaddr(int chan,char *addr) | 2816 | sbmac_setup_hwaddr(int chan,char *addr) |
2798 | { | 2817 | { |
@@ -2818,25 +2837,7 @@ sbmac_init_module(void) | |||
2818 | unsigned long port; | 2837 | unsigned long port; |
2819 | int chip_max_units; | 2838 | int chip_max_units; |
2820 | 2839 | ||
2821 | /* | 2840 | /* Set the number of available units based on the SOC type. */ |
2822 | * For bringup when not using the firmware, we can pre-fill | ||
2823 | * the MAC addresses using the environment variables | ||
2824 | * specified in this file (or maybe from the config file?) | ||
2825 | */ | ||
2826 | #ifdef SBMAC_ETH0_HWADDR | ||
2827 | sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR); | ||
2828 | #endif | ||
2829 | #ifdef SBMAC_ETH1_HWADDR | ||
2830 | sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR); | ||
2831 | #endif | ||
2832 | #ifdef SBMAC_ETH2_HWADDR | ||
2833 | sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR); | ||
2834 | #endif | ||
2835 | |||
2836 | /* | ||
2837 | * Walk through the Ethernet controllers and find | ||
2838 | * those who have their MAC addresses set. | ||
2839 | */ | ||
2840 | switch (soc_type) { | 2841 | switch (soc_type) { |
2841 | case K_SYS_SOC_TYPE_BCM1250: | 2842 | case K_SYS_SOC_TYPE_BCM1250: |
2842 | case K_SYS_SOC_TYPE_BCM1250_ALT: | 2843 | case K_SYS_SOC_TYPE_BCM1250_ALT: |
@@ -2848,6 +2849,10 @@ sbmac_init_module(void) | |||
2848 | case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ | 2849 | case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */ |
2849 | chip_max_units = 2; | 2850 | chip_max_units = 2; |
2850 | break; | 2851 | break; |
2852 | case K_SYS_SOC_TYPE_BCM1x55: | ||
2853 | case K_SYS_SOC_TYPE_BCM1x80: | ||
2854 | chip_max_units = 4; | ||
2855 | break; | ||
2851 | default: | 2856 | default: |
2852 | chip_max_units = 0; | 2857 | chip_max_units = 0; |
2853 | break; | 2858 | break; |
@@ -2855,6 +2860,32 @@ sbmac_init_module(void) | |||
2855 | if (chip_max_units > MAX_UNITS) | 2860 | if (chip_max_units > MAX_UNITS) |
2856 | chip_max_units = MAX_UNITS; | 2861 | chip_max_units = MAX_UNITS; |
2857 | 2862 | ||
2863 | /* | ||
2864 | * For bringup when not using the firmware, we can pre-fill | ||
2865 | * the MAC addresses using the environment variables | ||
2866 | * specified in this file (or maybe from the config file?) | ||
2867 | */ | ||
2868 | #ifdef SBMAC_ETH0_HWADDR | ||
2869 | if (chip_max_units > 0) | ||
2870 | sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR); | ||
2871 | #endif | ||
2872 | #ifdef SBMAC_ETH1_HWADDR | ||
2873 | if (chip_max_units > 1) | ||
2874 | sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR); | ||
2875 | #endif | ||
2876 | #ifdef SBMAC_ETH2_HWADDR | ||
2877 | if (chip_max_units > 2) | ||
2878 | sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR); | ||
2879 | #endif | ||
2880 | #ifdef SBMAC_ETH3_HWADDR | ||
2881 | if (chip_max_units > 3) | ||
2882 | sbmac_setup_hwaddr(3,SBMAC_ETH3_HWADDR); | ||
2883 | #endif | ||
2884 | |||
2885 | /* | ||
2886 | * Walk through the Ethernet controllers and find | ||
2887 | * those who have their MAC addresses set. | ||
2888 | */ | ||
2858 | for (idx = 0; idx < chip_max_units; idx++) { | 2889 | for (idx = 0; idx < chip_max_units; idx++) { |
2859 | 2890 | ||
2860 | /* | 2891 | /* |
@@ -2886,7 +2917,7 @@ sbmac_init_module(void) | |||
2886 | 2917 | ||
2887 | printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); | 2918 | printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port); |
2888 | 2919 | ||
2889 | dev->irq = K_INT_MAC_0 + idx; | 2920 | dev->irq = UNIT_INT(idx); |
2890 | dev->base_addr = port; | 2921 | dev->base_addr = port; |
2891 | dev->mem_end = 0; | 2922 | dev->mem_end = 0; |
2892 | if (sbmac_init(dev, idx)) { | 2923 | if (sbmac_init(dev, idx)) { |