aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sh_eth.c
diff options
context:
space:
mode:
authorYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>2011-03-07 16:59:49 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-14 17:10:15 -0400
commit8fcd496151b4354569283056076339239b86fabe (patch)
tree54ebf3e52e9cc3c2a79361f534ace0b22c680b6c /drivers/net/sh_eth.c
parente47c90523484518aac30498150e427d824ace705 (diff)
net: sh_eth: add support for SH7757's GETHER
The SH7757 have GETHER and ETHER both. This patch supports them. Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sh_eth.c')
-rw-r--r--drivers/net/sh_eth.c136
1 files changed, 135 insertions, 1 deletions
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 5d28ce68f357..dcf9f87d021f 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -94,7 +94,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
94 .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */ 94 .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
95}; 95};
96#elif defined(CONFIG_CPU_SUBTYPE_SH7757) 96#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
97#define SH_ETH_RESET_DEFAULT 1 97#define SH_ETH_HAS_BOTH_MODULES 1
98#define SH_ETH_HAS_TSU 1
98static void sh_eth_set_duplex(struct net_device *ndev) 99static void sh_eth_set_duplex(struct net_device *ndev)
99{ 100{
100 struct sh_eth_private *mdp = netdev_priv(ndev); 101 struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -141,6 +142,135 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
141 .no_ade = 1, 142 .no_ade = 1,
142}; 143};
143 144
145#define SH_GIGA_ETH_BASE 0xfee00000
146#define GIGA_MALR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
147#define GIGA_MAHR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
148static void sh_eth_chip_reset_giga(struct net_device *ndev)
149{
150 int i;
151 unsigned long mahr[2], malr[2];
152
153 /* save MAHR and MALR */
154 for (i = 0; i < 2; i++) {
155 malr[i] = readl(GIGA_MALR(i));
156 mahr[i] = readl(GIGA_MAHR(i));
157 }
158
159 /* reset device */
160 writel(ARSTR_ARSTR, SH_GIGA_ETH_BASE + 0x1800);
161 mdelay(1);
162
163 /* restore MAHR and MALR */
164 for (i = 0; i < 2; i++) {
165 writel(malr[i], GIGA_MALR(i));
166 writel(mahr[i], GIGA_MAHR(i));
167 }
168}
169
170static int sh_eth_is_gether(struct sh_eth_private *mdp);
171static void sh_eth_reset(struct net_device *ndev)
172{
173 struct sh_eth_private *mdp = netdev_priv(ndev);
174 int cnt = 100;
175
176 if (sh_eth_is_gether(mdp)) {
177 sh_eth_write(ndev, 0x03, EDSR);
178 sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
179 EDMR);
180 while (cnt > 0) {
181 if (!(sh_eth_read(ndev, EDMR) & 0x3))
182 break;
183 mdelay(1);
184 cnt--;
185 }
186 if (cnt < 0)
187 printk(KERN_ERR "Device reset fail\n");
188
189 /* Table Init */
190 sh_eth_write(ndev, 0x0, TDLAR);
191 sh_eth_write(ndev, 0x0, TDFAR);
192 sh_eth_write(ndev, 0x0, TDFXR);
193 sh_eth_write(ndev, 0x0, TDFFR);
194 sh_eth_write(ndev, 0x0, RDLAR);
195 sh_eth_write(ndev, 0x0, RDFAR);
196 sh_eth_write(ndev, 0x0, RDFXR);
197 sh_eth_write(ndev, 0x0, RDFFR);
198 } else {
199 sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
200 EDMR);
201 mdelay(3);
202 sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
203 EDMR);
204 }
205}
206
207static void sh_eth_set_duplex_giga(struct net_device *ndev)
208{
209 struct sh_eth_private *mdp = netdev_priv(ndev);
210
211 if (mdp->duplex) /* Full */
212 sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
213 else /* Half */
214 sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
215}
216
217static void sh_eth_set_rate_giga(struct net_device *ndev)
218{
219 struct sh_eth_private *mdp = netdev_priv(ndev);
220
221 switch (mdp->speed) {
222 case 10: /* 10BASE */
223 sh_eth_write(ndev, 0x00000000, GECMR);
224 break;
225 case 100:/* 100BASE */
226 sh_eth_write(ndev, 0x00000010, GECMR);
227 break;
228 case 1000: /* 1000BASE */
229 sh_eth_write(ndev, 0x00000020, GECMR);
230 break;
231 default:
232 break;
233 }
234}
235
236/* SH7757(GETHERC) */
237static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
238 .chip_reset = sh_eth_chip_reset_giga,
239 .set_duplex = sh_eth_set_duplex_giga,
240 .set_rate = sh_eth_set_rate_giga,
241
242 .ecsr_value = ECSR_ICD | ECSR_MPD,
243 .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
244 .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
245
246 .tx_check = EESR_TC1 | EESR_FTC,
247 .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
248 EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
249 EESR_ECI,
250 .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
251 EESR_TFE,
252 .fdr_value = 0x0000072f,
253 .rmcr_value = 0x00000001,
254
255 .apr = 1,
256 .mpr = 1,
257 .tpauser = 1,
258 .bculr = 1,
259 .hw_swap = 1,
260 .rpadir = 1,
261 .rpadir_value = 2 << 16,
262 .no_trimd = 1,
263 .no_ade = 1,
264};
265
266static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
267{
268 if (sh_eth_is_gether(mdp))
269 return &sh_eth_my_cpu_data_giga;
270 else
271 return &sh_eth_my_cpu_data;
272}
273
144#elif defined(CONFIG_CPU_SUBTYPE_SH7763) 274#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
145#define SH_ETH_HAS_TSU 1 275#define SH_ETH_HAS_TSU 1
146static void sh_eth_chip_reset(struct net_device *ndev) 276static void sh_eth_chip_reset(struct net_device *ndev)
@@ -1677,7 +1807,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1677 mdp->reg_offset = sh_eth_get_register_offset(pd->register_type); 1807 mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);
1678 1808
1679 /* set cpu data */ 1809 /* set cpu data */
1810#if defined(SH_ETH_HAS_BOTH_MODULES)
1811 mdp->cd = sh_eth_get_cpu_data(mdp);
1812#else
1680 mdp->cd = &sh_eth_my_cpu_data; 1813 mdp->cd = &sh_eth_my_cpu_data;
1814#endif
1681 sh_eth_set_default_cpu_data(mdp->cd); 1815 sh_eth_set_default_cpu_data(mdp->cd);
1682 1816
1683 /* set function */ 1817 /* set function */