aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkira Takeuchi <takeuchi.akr@jp.panasonic.com>2010-10-27 12:28:58 -0400
committerDavid Howells <dhowells@redhat.com>2010-10-27 12:28:58 -0400
commit62747cd27ee241ffa32d501e45980cdc441d4a09 (patch)
tree6ad1e1d530c5761dc39e1fb21fca56a2751c63e7
parent6044cf1d9426dfd5cdc1e7b9cf8eaed6418e1ff6 (diff)
MN10300: ASB2364: Add support for SMSC911X and SMC911X
Add support for SMSC911X and SMC911X for the ASB2364 unit. Signed-off-by: Akira Takeuchi <takeuchi.akr@jp.panasonic.com> Signed-off-by: Kiyoshi Owada <owada.kiyoshi@jp.panasonic.com> Signed-off-by: David Howells <dhowells@redhat.com> cc: steve.glendinning@smsc.com cc: netdev@vger.kernel.org
-rw-r--r--arch/mn10300/Kconfig1
-rw-r--r--arch/mn10300/include/asm/smsc911x.h1
-rw-r--r--arch/mn10300/unit-asb2364/Makefile2
-rw-r--r--arch/mn10300/unit-asb2364/include/unit/smsc911x.h171
-rw-r--r--arch/mn10300/unit-asb2364/smsc911x.c58
-rw-r--r--drivers/net/Kconfig12
-rw-r--r--drivers/net/smsc911x.c3
-rw-r--r--drivers/net/smsc911x.h11
8 files changed, 256 insertions, 3 deletions
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 42ca55a47377..129ca492e917 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -117,6 +117,7 @@ config MN10300_UNIT_ASB2305
117 117
118config MN10300_UNIT_ASB2364 118config MN10300_UNIT_ASB2364
119 bool "ASB2364" 119 bool "ASB2364"
120 select SMSC911X_ARCH_HOOKS if SMSC911X
120 121
121endchoice 122endchoice
122 123
diff --git a/arch/mn10300/include/asm/smsc911x.h b/arch/mn10300/include/asm/smsc911x.h
new file mode 100644
index 000000000000..2fcd1080322b
--- /dev/null
+++ b/arch/mn10300/include/asm/smsc911x.h
@@ -0,0 +1 @@
#include <unit/smsc911x.h>
diff --git a/arch/mn10300/unit-asb2364/Makefile b/arch/mn10300/unit-asb2364/Makefile
index e9d9b90ef6da..b3263ecfc4ff 100644
--- a/arch/mn10300/unit-asb2364/Makefile
+++ b/arch/mn10300/unit-asb2364/Makefile
@@ -8,3 +8,5 @@
8# Note 2! The CFLAGS definitions are now in the main makefile... 8# Note 2! The CFLAGS definitions are now in the main makefile...
9 9
10obj-y := unit-init.o leds.o irq-fpga.o 10obj-y := unit-init.o leds.o irq-fpga.o
11
12obj-$(CONFIG_SMSC911X) += smsc911x.o
diff --git a/arch/mn10300/unit-asb2364/include/unit/smsc911x.h b/arch/mn10300/unit-asb2364/include/unit/smsc911x.h
new file mode 100644
index 000000000000..4c1ede535fa9
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/include/unit/smsc911x.h
@@ -0,0 +1,171 @@
1/* Support for the SMSC911x NIC
2 *
3 * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
4 * All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#ifndef _ASM_UNIT_SMSC911X_H
12#define _ASM_UNIT_SMSC911X_H
13
14#include <linux/netdevice.h>
15#include <proc/irq.h>
16#include <unit/fpga-regs.h>
17
18#define MN10300_USE_EXT_EEPROM
19
20
21#define SMSC911X_BASE 0xA8000000UL
22#define SMSC911X_BASE_END 0xA8000100UL
23#define SMSC911X_IRQ FPGA_LAN_IRQ
24
25/*
26 * Allow the FPGA to be initialised by the SMSC911x driver
27 */
28#undef SMSC_INITIALIZE
29#define SMSC_INITIALIZE() \
30do { \
31 /* release reset */ \
32 ASB2364_FPGA_REG_RESET_LAN = 0x0001; \
33 SyncExBus(); \
34} while (0)
35
36#ifdef MN10300_USE_EXT_EEPROM
37#include <linux/delay.h>
38#include <unit/clock.h>
39
40#define EEPROM_ADDRESS 0xA0
41#define MAC_OFFSET 0x0008
42#define USE_IIC_CH 0 /* 0 or 1 */
43#define IIC_OFFSET (0x80000 * USE_IIC_CH)
44#define IIC_DTRM __SYSREG(0xd8400000 + IIC_OFFSET, u32)
45#define IIC_DREC __SYSREG(0xd8400004 + IIC_OFFSET, u32)
46#define IIC_MYADD __SYSREG(0xd8400008 + IIC_OFFSET, u32)
47#define IIC_CLK __SYSREG(0xd840000c + IIC_OFFSET, u32)
48#define IIC_BRST __SYSREG(0xd8400010 + IIC_OFFSET, u32)
49#define IIC_HOLD __SYSREG(0xd8400014 + IIC_OFFSET, u32)
50#define IIC_BSTS __SYSREG(0xd8400018 + IIC_OFFSET, u32)
51#define IIC_ICR __SYSREG(0xd4000080 + 4 * USE_IIC_CH, u16)
52
53#define IIC_CLK_PLS ((unsigned short)(MN10300_IOCLK / 100000 - 1))
54#define IIC_CLK_LOW ((unsigned short)(IIC_CLK_PLS / 2))
55
56#define SYS_IIC_DTRM_Bit_STA ((unsigned short)0x0400)
57#define SYS_IIC_DTRM_Bit_STO ((unsigned short)0x0200)
58#define SYS_IIC_DTRM_Bit_ACK ((unsigned short)0x0100)
59#define SYS_IIC_DTRM_Bit_DATA ((unsigned short)0x00FF)
60
61static inline void POLL_INT_REQ(volatile u16 *icr)
62{
63 unsigned long flags;
64 u16 tmp;
65
66 while (!(*icr & GxICR_REQUEST))
67 ;
68 flags = arch_local_cli_save();
69 tmp = *icr;
70 *icr = (tmp & GxICR_LEVEL) | GxICR_DETECT;
71 tmp = *icr;
72 arch_local_irq_restore(flags);
73}
74
75/*
76 * Implement the SMSC911x hook for MAC address retrieval
77 */
78#undef smsc_get_mac
79static inline int smsc_get_mac(struct net_device *dev)
80{
81 unsigned char *mac_buf = dev->dev_addr;
82 int i;
83 unsigned short value;
84 unsigned int data;
85 int mac_length = 6;
86 int check;
87 u16 orig_gicr, tmp;
88 unsigned long flags;
89
90 /* save original GnICR and clear GnICR.IE */
91 flags = arch_local_cli_save();
92 orig_gicr = IIC_ICR;
93 IIC_ICR = orig_gicr & GxICR_LEVEL;
94 tmp = IIC_ICR;
95 arch_local_irq_restore(flags);
96
97 IIC_MYADD = 0x00000008;
98 IIC_CLK = (IIC_CLK_LOW << 16) + (IIC_CLK_PLS);
99 /* bus hung recovery */
100
101 while (1) {
102 check = 0;
103 for (i = 0; i < 3; i++) {
104 if ((IIC_BSTS & 0x00000003) == 0x00000003)
105 check++;
106 udelay(3);
107 }
108
109 if (check == 3) {
110 IIC_BRST = 0x00000003;
111 break;
112 } else {
113 for (i = 0; i < 3; i++) {
114 IIC_BRST = 0x00000002;
115 udelay(8);
116 IIC_BRST = 0x00000003;
117 udelay(8);
118 }
119 }
120 }
121
122 IIC_BRST = 0x00000002;
123 IIC_BRST = 0x00000003;
124
125 value = SYS_IIC_DTRM_Bit_STA | SYS_IIC_DTRM_Bit_ACK;
126 value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
127 (unsigned short)0x0000);
128 IIC_DTRM = value;
129 POLL_INT_REQ(&IIC_ICR);
130
131 /** send offset of MAC address in EEPROM **/
132 IIC_DTRM = (unsigned char)((MAC_OFFSET & 0xFF00) >> 8);
133 POLL_INT_REQ(&IIC_ICR);
134
135 IIC_DTRM = (unsigned char)(MAC_OFFSET & 0x00FF);
136 POLL_INT_REQ(&IIC_ICR);
137
138 udelay(1000);
139
140 value = SYS_IIC_DTRM_Bit_STA;
141 value |= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
142 (unsigned short)0x0001);
143 IIC_DTRM = value;
144 POLL_INT_REQ(&IIC_ICR);
145
146 IIC_DTRM = 0x00000000;
147 while (mac_length > 0) {
148 POLL_INT_REQ(&IIC_ICR);
149
150 data = IIC_DREC;
151 mac_length--;
152 if (mac_length == 0)
153 value = 0x00000300; /* stop IIC bus */
154 else if (mac_length == 1)
155 value = 0x00000100; /* no ack */
156 else
157 value = 0x00000000; /* ack */
158 IIC_DTRM = value;
159 *mac_buf++ = (unsigned char)(data & 0xff);
160 }
161
162 /* restore GnICR.LV and GnICR.IE */
163 flags = arch_local_cli_save();
164 IIC_ICR = (orig_gicr & (GxICR_LEVEL | GxICR_ENABLE));
165 tmp = IIC_ICR;
166 arch_local_irq_restore(flags);
167
168 return 0;
169}
170#endif /* MN10300_USE_EXT_EEPROM */
171#endif /* _ASM_UNIT_SMSC911X_H */
diff --git a/arch/mn10300/unit-asb2364/smsc911x.c b/arch/mn10300/unit-asb2364/smsc911x.c
new file mode 100644
index 000000000000..544a73e94c81
--- /dev/null
+++ b/arch/mn10300/unit-asb2364/smsc911x.c
@@ -0,0 +1,58 @@
1/* Specification for the SMSC911x NIC
2 *
3 * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
4 * All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/ioport.h>
17#include <linux/smsc911x.h>
18#include <unit/smsc911x.h>
19
20static struct smsc911x_platform_config smsc911x_config = {
21 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
22 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
23 .flags = SMSC911X_USE_32BIT,
24};
25
26static struct resource smsc911x_resources[] = {
27 [0] = {
28 .start = SMSC911X_BASE,
29 .end = SMSC911X_BASE_END,
30 .flags = IORESOURCE_MEM,
31 },
32 [1] = {
33 .start = SMSC911X_IRQ,
34 .end = SMSC911X_IRQ,
35 .flags = IORESOURCE_IRQ,
36 },
37};
38
39static struct platform_device smsc911x_device = {
40 .name = "smsc911x",
41 .id = 0,
42 .num_resources = ARRAY_SIZE(smsc911x_resources),
43 .resource = smsc911x_resources,
44 .dev = {
45 .platform_data = &smsc911x_config,
46 }
47};
48
49/*
50 * add platform devices
51 */
52static int __init unit_device_init(void)
53{
54 platform_device_register(&smsc911x_device);
55 return 0;
56}
57
58device_initcall(unit_device_init);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 86fe67fd49ba..9334539ebf75 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1041,7 +1041,7 @@ config SMC911X
1041 tristate "SMSC LAN911[5678] support" 1041 tristate "SMSC LAN911[5678] support"
1042 select CRC32 1042 select CRC32
1043 select MII 1043 select MII
1044 depends on ARM || SUPERH 1044 depends on ARM || SUPERH || MN10300
1045 help 1045 help
1046 This is a driver for SMSC's LAN911x series of Ethernet chipsets 1046 This is a driver for SMSC's LAN911x series of Ethernet chipsets
1047 including the new LAN9115, LAN9116, LAN9117, and LAN9118. 1047 including the new LAN9115, LAN9116, LAN9117, and LAN9118.
@@ -1055,7 +1055,7 @@ config SMC911X
1055 1055
1056config SMSC911X 1056config SMSC911X
1057 tristate "SMSC LAN911x/LAN921x families embedded ethernet support" 1057 tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
1058 depends on ARM || SUPERH || BLACKFIN || MIPS 1058 depends on ARM || SUPERH || BLACKFIN || MIPS || MN10300
1059 select CRC32 1059 select CRC32
1060 select MII 1060 select MII
1061 select PHYLIB 1061 select PHYLIB
@@ -1067,6 +1067,14 @@ config SMSC911X
1067 <file:Documentation/networking/net-modules.txt>. The module 1067 <file:Documentation/networking/net-modules.txt>. The module
1068 will be called smsc911x. 1068 will be called smsc911x.
1069 1069
1070config SMSC911X_ARCH_HOOKS
1071 def_bool n
1072 depends on SMSC911X
1073 help
1074 If the arch enables this, it allows the arch to implement various
1075 hooks for more comprehensive interrupt control and also to override
1076 the source of the MAC address.
1077
1070config NET_VENDOR_RACAL 1078config NET_VENDOR_RACAL
1071 bool "Racal-Interlan (Micom) NI cards" 1079 bool "Racal-Interlan (Micom) NI cards"
1072 depends on ISA 1080 depends on ISA
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index a8e5856ce882..64bfdae5956f 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -2075,7 +2075,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
2075 } else { 2075 } else {
2076 /* Try reading mac address from device. if EEPROM is present 2076 /* Try reading mac address from device. if EEPROM is present
2077 * it will already have been set */ 2077 * it will already have been set */
2078 smsc911x_read_mac_address(dev); 2078 smsc_get_mac(dev);
2079 2079
2080 if (is_valid_ether_addr(dev->dev_addr)) { 2080 if (is_valid_ether_addr(dev->dev_addr)) {
2081 /* eeprom values are valid so use them */ 2081 /* eeprom values are valid so use them */
@@ -2176,6 +2176,7 @@ static struct platform_driver smsc911x_driver = {
2176/* Entry point for loading the module */ 2176/* Entry point for loading the module */
2177static int __init smsc911x_init_module(void) 2177static int __init smsc911x_init_module(void)
2178{ 2178{
2179 SMSC_INITIALIZE();
2179 return platform_driver_register(&smsc911x_driver); 2180 return platform_driver_register(&smsc911x_driver);
2180} 2181}
2181 2182
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h
index 016360c65ce2..52f38e12a879 100644
--- a/drivers/net/smsc911x.h
+++ b/drivers/net/smsc911x.h
@@ -394,4 +394,15 @@
394#define LPA_PAUSE_ALL (LPA_PAUSE_CAP | \ 394#define LPA_PAUSE_ALL (LPA_PAUSE_CAP | \
395 LPA_PAUSE_ASYM) 395 LPA_PAUSE_ASYM)
396 396
397/*
398 * Provide hooks to let the arch add to the initialisation procedure
399 * and to override the source of the MAC address.
400 */
401#define SMSC_INITIALIZE() do {} while (0)
402#define smsc_get_mac(dev) smsc911x_read_mac_address((dev))
403
404#ifdef CONFIG_SMSC911X_ARCH_HOOKS
405#include <asm/smsc911x.h>
406#endif
407
397#endif /* __SMSC911X_H__ */ 408#endif /* __SMSC911X_H__ */