diff options
author | Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> | 2013-03-28 07:51:31 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-29 15:31:30 -0400 |
commit | a3f109bd793dfe5c611220ca5ab6c72f1aed479e (patch) | |
tree | e1e343f8dda30b5e64c92941dd62a529186f8e7c | |
parent | c0013f6f8bbcb7605d591431444780d636dbe223 (diff) |
sh_eth: add R-Car support for real
Commit d0418bb7123f44b23d69ac349eec7daf9103472f (net: sh_eth: Add eth support
for R8A7779 device) was a failed attempt to add support for one of members of
the R-Car SoC family. That's for three reasons: it treated R8A7779 the same
as SH7724 except including quite dirty hack adding ECMR_ELB bit to the mask
in sh_eth_set_rate() while not removing ECMR_RTM bit (despite it's reserved in
R-Car Ether), and it didn't add a new register offset array despite the closest
SH_ETH_REG_FAST_SH4 mapping differs by 0x200 to the offsets all the R-Car Ether
registers have, and also some of the registers in this old mapping don't exist
on R-Car Ether (due to this, SH7724's 'sh_eth_my_cpu_data' structure is not
adequeate for R-Car too). Fix all these shortcomings, restoring the SH7724
related section to its pristine state...
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 107 | ||||
-rw-r--r-- | include/linux/sh_eth.h | 1 |
2 files changed, 100 insertions, 8 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 13abe917cbdf..da604059b148 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * SuperH Ethernet device driver | 2 | * SuperH Ethernet device driver |
3 | * | 3 | * |
4 | * Copyright (C) 2006-2012 Nobuhiro Iwamatsu | 4 | * Copyright (C) 2006-2012 Nobuhiro Iwamatsu |
5 | * Copyright (C) 2008-2012 Renesas Solutions Corp. | 5 | * Copyright (C) 2008-2013 Renesas Solutions Corp. |
6 | * Copyright (C) 2013 Cogent Embedded, Inc. | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms and conditions of the GNU General Public License, | 9 | * under the terms and conditions of the GNU General Public License, |
@@ -147,6 +148,51 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { | |||
147 | [FWALCR1] = 0x00b4, | 148 | [FWALCR1] = 0x00b4, |
148 | }; | 149 | }; |
149 | 150 | ||
151 | static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { | ||
152 | [ECMR] = 0x0300, | ||
153 | [RFLR] = 0x0308, | ||
154 | [ECSR] = 0x0310, | ||
155 | [ECSIPR] = 0x0318, | ||
156 | [PIR] = 0x0320, | ||
157 | [PSR] = 0x0328, | ||
158 | [RDMLR] = 0x0340, | ||
159 | [IPGR] = 0x0350, | ||
160 | [APR] = 0x0354, | ||
161 | [MPR] = 0x0358, | ||
162 | [RFCF] = 0x0360, | ||
163 | [TPAUSER] = 0x0364, | ||
164 | [TPAUSECR] = 0x0368, | ||
165 | [MAHR] = 0x03c0, | ||
166 | [MALR] = 0x03c8, | ||
167 | [TROCR] = 0x03d0, | ||
168 | [CDCR] = 0x03d4, | ||
169 | [LCCR] = 0x03d8, | ||
170 | [CNDCR] = 0x03dc, | ||
171 | [CEFCR] = 0x03e4, | ||
172 | [FRECR] = 0x03e8, | ||
173 | [TSFRCR] = 0x03ec, | ||
174 | [TLFRCR] = 0x03f0, | ||
175 | [RFCR] = 0x03f4, | ||
176 | [MAFCR] = 0x03f8, | ||
177 | |||
178 | [EDMR] = 0x0200, | ||
179 | [EDTRR] = 0x0208, | ||
180 | [EDRRR] = 0x0210, | ||
181 | [TDLAR] = 0x0218, | ||
182 | [RDLAR] = 0x0220, | ||
183 | [EESR] = 0x0228, | ||
184 | [EESIPR] = 0x0230, | ||
185 | [TRSCER] = 0x0238, | ||
186 | [RMFCR] = 0x0240, | ||
187 | [TFTR] = 0x0248, | ||
188 | [FDR] = 0x0250, | ||
189 | [RMCR] = 0x0258, | ||
190 | [TFUCR] = 0x0264, | ||
191 | [RFOCR] = 0x0268, | ||
192 | [FCFTR] = 0x0270, | ||
193 | [TRIMD] = 0x027c, | ||
194 | }; | ||
195 | |||
150 | static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { | 196 | static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { |
151 | [ECMR] = 0x0100, | 197 | [ECMR] = 0x0100, |
152 | [RFLR] = 0x0108, | 198 | [RFLR] = 0x0108, |
@@ -296,7 +342,7 @@ static void sh_eth_select_mii(struct net_device *ndev) | |||
296 | #endif | 342 | #endif |
297 | 343 | ||
298 | /* There is CPU dependent code */ | 344 | /* There is CPU dependent code */ |
299 | #if defined(CONFIG_CPU_SUBTYPE_SH7724) || defined(CONFIG_ARCH_R8A7779) | 345 | #if defined(CONFIG_ARCH_R8A7779) |
300 | #define SH_ETH_RESET_DEFAULT 1 | 346 | #define SH_ETH_RESET_DEFAULT 1 |
301 | static void sh_eth_set_duplex(struct net_device *ndev) | 347 | static void sh_eth_set_duplex(struct net_device *ndev) |
302 | { | 348 | { |
@@ -311,18 +357,60 @@ static void sh_eth_set_duplex(struct net_device *ndev) | |||
311 | static void sh_eth_set_rate(struct net_device *ndev) | 357 | static void sh_eth_set_rate(struct net_device *ndev) |
312 | { | 358 | { |
313 | struct sh_eth_private *mdp = netdev_priv(ndev); | 359 | struct sh_eth_private *mdp = netdev_priv(ndev); |
314 | unsigned int bits = ECMR_RTM; | ||
315 | 360 | ||
316 | #if defined(CONFIG_ARCH_R8A7779) | 361 | switch (mdp->speed) { |
317 | bits |= ECMR_ELB; | 362 | case 10: /* 10BASE */ |
318 | #endif | 363 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_ELB, ECMR); |
364 | break; | ||
365 | case 100:/* 100BASE */ | ||
366 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_ELB, ECMR); | ||
367 | break; | ||
368 | default: | ||
369 | break; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* R8A7779 */ | ||
374 | static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | ||
375 | .set_duplex = sh_eth_set_duplex, | ||
376 | .set_rate = sh_eth_set_rate, | ||
377 | |||
378 | .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD, | ||
379 | .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP, | ||
380 | .eesipr_value = 0x01ff009f, | ||
381 | |||
382 | .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, | ||
383 | .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE | | ||
384 | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI, | ||
385 | .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE, | ||
386 | |||
387 | .apr = 1, | ||
388 | .mpr = 1, | ||
389 | .tpauser = 1, | ||
390 | .hw_swap = 1, | ||
391 | }; | ||
392 | #elif defined(CONFIG_CPU_SUBTYPE_SH7724) | ||
393 | #define SH_ETH_RESET_DEFAULT 1 | ||
394 | static void sh_eth_set_duplex(struct net_device *ndev) | ||
395 | { | ||
396 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
397 | |||
398 | if (mdp->duplex) /* Full */ | ||
399 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR); | ||
400 | else /* Half */ | ||
401 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR); | ||
402 | } | ||
403 | |||
404 | static void sh_eth_set_rate(struct net_device *ndev) | ||
405 | { | ||
406 | struct sh_eth_private *mdp = netdev_priv(ndev); | ||
319 | 407 | ||
320 | switch (mdp->speed) { | 408 | switch (mdp->speed) { |
321 | case 10: /* 10BASE */ | 409 | case 10: /* 10BASE */ |
322 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~bits, ECMR); | 410 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR); |
323 | break; | 411 | break; |
324 | case 100:/* 100BASE */ | 412 | case 100:/* 100BASE */ |
325 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | bits, ECMR); | 413 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR); |
326 | break; | 414 | break; |
327 | default: | 415 | default: |
328 | break; | 416 | break; |
@@ -2521,6 +2609,9 @@ static const u16 *sh_eth_get_register_offset(int register_type) | |||
2521 | case SH_ETH_REG_GIGABIT: | 2609 | case SH_ETH_REG_GIGABIT: |
2522 | reg_offset = sh_eth_offset_gigabit; | 2610 | reg_offset = sh_eth_offset_gigabit; |
2523 | break; | 2611 | break; |
2612 | case SH_ETH_REG_FAST_RCAR: | ||
2613 | reg_offset = sh_eth_offset_fast_rcar; | ||
2614 | break; | ||
2524 | case SH_ETH_REG_FAST_SH4: | 2615 | case SH_ETH_REG_FAST_SH4: |
2525 | reg_offset = sh_eth_offset_fast_sh4; | 2616 | reg_offset = sh_eth_offset_fast_sh4; |
2526 | break; | 2617 | break; |
diff --git a/include/linux/sh_eth.h b/include/linux/sh_eth.h index b17d765ded84..fc305713fc6d 100644 --- a/include/linux/sh_eth.h +++ b/include/linux/sh_eth.h | |||
@@ -6,6 +6,7 @@ | |||
6 | enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN}; | 6 | enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN}; |
7 | enum { | 7 | enum { |
8 | SH_ETH_REG_GIGABIT, | 8 | SH_ETH_REG_GIGABIT, |
9 | SH_ETH_REG_FAST_RCAR, | ||
9 | SH_ETH_REG_FAST_SH4, | 10 | SH_ETH_REG_FAST_SH4, |
10 | SH_ETH_REG_FAST_SH3_SH2 | 11 | SH_ETH_REG_FAST_SH3_SH2 |
11 | }; | 12 | }; |