diff options
author | Simon Horman <horms+renesas@verge.net.au> | 2014-01-16 19:22:28 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-17 21:13:58 -0500 |
commit | db893473d313a4ad9455e89d1bd5e136a57f411e (patch) | |
tree | c69719f42e92187dcf3bfad1d28d6fdfa30ba35d /drivers | |
parent | 504c8ca55c70fb6cab0b97381e70ad0e143f539e (diff) |
sh_eth: Add support for r7s72100
The r7s72100 SoC includes a fast ethernet controller.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Acked-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.c | 124 | ||||
-rw-r--r-- | drivers/net/ethernet/renesas/sh_eth.h | 3 |
2 files changed, 119 insertions, 8 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index fe2c8bb4d2f1..040cb94e8219 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -143,6 +143,65 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { | |||
143 | [FWALCR1] = 0x00b4, | 143 | [FWALCR1] = 0x00b4, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { | ||
147 | [EDSR] = 0x0000, | ||
148 | [EDMR] = 0x0400, | ||
149 | [EDTRR] = 0x0408, | ||
150 | [EDRRR] = 0x0410, | ||
151 | [EESR] = 0x0428, | ||
152 | [EESIPR] = 0x0430, | ||
153 | [TDLAR] = 0x0010, | ||
154 | [TDFAR] = 0x0014, | ||
155 | [TDFXR] = 0x0018, | ||
156 | [TDFFR] = 0x001c, | ||
157 | [RDLAR] = 0x0030, | ||
158 | [RDFAR] = 0x0034, | ||
159 | [RDFXR] = 0x0038, | ||
160 | [RDFFR] = 0x003c, | ||
161 | [TRSCER] = 0x0438, | ||
162 | [RMFCR] = 0x0440, | ||
163 | [TFTR] = 0x0448, | ||
164 | [FDR] = 0x0450, | ||
165 | [RMCR] = 0x0458, | ||
166 | [RPADIR] = 0x0460, | ||
167 | [FCFTR] = 0x0468, | ||
168 | [CSMR] = 0x04E4, | ||
169 | |||
170 | [ECMR] = 0x0500, | ||
171 | [RFLR] = 0x0508, | ||
172 | [ECSR] = 0x0510, | ||
173 | [ECSIPR] = 0x0518, | ||
174 | [PIR] = 0x0520, | ||
175 | [APR] = 0x0554, | ||
176 | [MPR] = 0x0558, | ||
177 | [PFTCR] = 0x055c, | ||
178 | [PFRCR] = 0x0560, | ||
179 | [TPAUSER] = 0x0564, | ||
180 | [MAHR] = 0x05c0, | ||
181 | [MALR] = 0x05c8, | ||
182 | [CEFCR] = 0x0740, | ||
183 | [FRECR] = 0x0748, | ||
184 | [TSFRCR] = 0x0750, | ||
185 | [TLFRCR] = 0x0758, | ||
186 | [RFCR] = 0x0760, | ||
187 | [MAFCR] = 0x0778, | ||
188 | |||
189 | [ARSTR] = 0x0000, | ||
190 | [TSU_CTRST] = 0x0004, | ||
191 | [TSU_VTAG0] = 0x0058, | ||
192 | [TSU_ADSBSY] = 0x0060, | ||
193 | [TSU_TEN] = 0x0064, | ||
194 | [TSU_ADRH0] = 0x0100, | ||
195 | [TSU_ADRL0] = 0x0104, | ||
196 | [TSU_ADRH31] = 0x01f8, | ||
197 | [TSU_ADRL31] = 0x01fc, | ||
198 | |||
199 | [TXNLCR0] = 0x0080, | ||
200 | [TXALCR0] = 0x0084, | ||
201 | [RXNLCR0] = 0x0088, | ||
202 | [RXALCR0] = 0x008C, | ||
203 | }; | ||
204 | |||
146 | static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { | 205 | static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { |
147 | [ECMR] = 0x0300, | 206 | [ECMR] = 0x0300, |
148 | [RFLR] = 0x0308, | 207 | [RFLR] = 0x0308, |
@@ -314,6 +373,11 @@ static bool sh_eth_is_gether(struct sh_eth_private *mdp) | |||
314 | return mdp->reg_offset == sh_eth_offset_gigabit; | 373 | return mdp->reg_offset == sh_eth_offset_gigabit; |
315 | } | 374 | } |
316 | 375 | ||
376 | static bool sh_eth_is_rz_fast_ether(struct sh_eth_private *mdp) | ||
377 | { | ||
378 | return mdp->reg_offset == sh_eth_offset_fast_rz; | ||
379 | } | ||
380 | |||
317 | static void sh_eth_select_mii(struct net_device *ndev) | 381 | static void sh_eth_select_mii(struct net_device *ndev) |
318 | { | 382 | { |
319 | u32 value = 0x0; | 383 | u32 value = 0x0; |
@@ -697,6 +761,38 @@ static struct sh_eth_cpu_data r8a7740_data = { | |||
697 | .shift_rd0 = 1, | 761 | .shift_rd0 = 1, |
698 | }; | 762 | }; |
699 | 763 | ||
764 | /* R7S72100 */ | ||
765 | static struct sh_eth_cpu_data r7s72100_data = { | ||
766 | .chip_reset = sh_eth_chip_reset, | ||
767 | .set_duplex = sh_eth_set_duplex, | ||
768 | |||
769 | .register_type = SH_ETH_REG_FAST_RZ, | ||
770 | |||
771 | .ecsr_value = ECSR_ICD, | ||
772 | .ecsipr_value = ECSIPR_ICDIP, | ||
773 | .eesipr_value = 0xff7f009f, | ||
774 | |||
775 | .tx_check = EESR_TC1 | EESR_FTC, | ||
776 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | | ||
777 | EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | | ||
778 | EESR_TDE | EESR_ECI, | ||
779 | .fdr_value = 0x0000070f, | ||
780 | .rmcr_value = RMCR_RNC, | ||
781 | |||
782 | .no_psr = 1, | ||
783 | .apr = 1, | ||
784 | .mpr = 1, | ||
785 | .tpauser = 1, | ||
786 | .hw_swap = 1, | ||
787 | .rpadir = 1, | ||
788 | .rpadir_value = 2 << 16, | ||
789 | .no_trimd = 1, | ||
790 | .no_ade = 1, | ||
791 | .hw_crc = 1, | ||
792 | .tsu = 1, | ||
793 | .shift_rd0 = 1, | ||
794 | }; | ||
795 | |||
700 | static struct sh_eth_cpu_data sh7619_data = { | 796 | static struct sh_eth_cpu_data sh7619_data = { |
701 | .register_type = SH_ETH_REG_FAST_SH3_SH2, | 797 | .register_type = SH_ETH_REG_FAST_SH3_SH2, |
702 | 798 | ||
@@ -763,7 +859,7 @@ static int sh_eth_reset(struct net_device *ndev) | |||
763 | struct sh_eth_private *mdp = netdev_priv(ndev); | 859 | struct sh_eth_private *mdp = netdev_priv(ndev); |
764 | int ret = 0; | 860 | int ret = 0; |
765 | 861 | ||
766 | if (sh_eth_is_gether(mdp)) { | 862 | if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) { |
767 | sh_eth_write(ndev, EDSR_ENALL, EDSR); | 863 | sh_eth_write(ndev, EDSR_ENALL, EDSR); |
768 | sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, | 864 | sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, |
769 | EDMR); | 865 | EDMR); |
@@ -874,7 +970,7 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac) | |||
874 | 970 | ||
875 | static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp) | 971 | static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp) |
876 | { | 972 | { |
877 | if (sh_eth_is_gether(mdp)) | 973 | if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) |
878 | return EDTRR_TRNS_GETHER; | 974 | return EDTRR_TRNS_GETHER; |
879 | else | 975 | else |
880 | return EDTRR_TRNS_ETHER; | 976 | return EDTRR_TRNS_ETHER; |
@@ -1037,7 +1133,8 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
1037 | /* Rx descriptor address set */ | 1133 | /* Rx descriptor address set */ |
1038 | if (i == 0) { | 1134 | if (i == 0) { |
1039 | sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR); | 1135 | sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR); |
1040 | if (sh_eth_is_gether(mdp)) | 1136 | if (sh_eth_is_gether(mdp) || |
1137 | sh_eth_is_rz_fast_ether(mdp)) | ||
1041 | sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR); | 1138 | sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR); |
1042 | } | 1139 | } |
1043 | } | 1140 | } |
@@ -1058,7 +1155,8 @@ static void sh_eth_ring_format(struct net_device *ndev) | |||
1058 | if (i == 0) { | 1155 | if (i == 0) { |
1059 | /* Tx descriptor address set */ | 1156 | /* Tx descriptor address set */ |
1060 | sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR); | 1157 | sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR); |
1061 | if (sh_eth_is_gether(mdp)) | 1158 | if (sh_eth_is_gether(mdp) || |
1159 | sh_eth_is_rz_fast_ether(mdp)) | ||
1062 | sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR); | 1160 | sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR); |
1063 | } | 1161 | } |
1064 | } | 1162 | } |
@@ -1305,9 +1403,9 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) | |||
1305 | 1403 | ||
1306 | /* In case of almost all GETHER/ETHERs, the Receive Frame State | 1404 | /* In case of almost all GETHER/ETHERs, the Receive Frame State |
1307 | * (RFS) bits in the Receive Descriptor 0 are from bit 9 to | 1405 | * (RFS) bits in the Receive Descriptor 0 are from bit 9 to |
1308 | * bit 0. However, in case of the R8A7740's GETHER, the RFS | 1406 | * bit 0. However, in case of the R8A7740, R8A779x, and |
1309 | * bits are from bit 25 to bit 16. So, the driver needs right | 1407 | * R7S72100 the RFS bits are from bit 25 to bit 16. So, the |
1310 | * shifting by 16. | 1408 | * driver needs right shifting by 16. |
1311 | */ | 1409 | */ |
1312 | if (mdp->cd->shift_rd0) | 1410 | if (mdp->cd->shift_rd0) |
1313 | desc_status >>= 16; | 1411 | desc_status >>= 16; |
@@ -2057,6 +2155,9 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) | |||
2057 | { | 2155 | { |
2058 | struct sh_eth_private *mdp = netdev_priv(ndev); | 2156 | struct sh_eth_private *mdp = netdev_priv(ndev); |
2059 | 2157 | ||
2158 | if (sh_eth_is_rz_fast_ether(mdp)) | ||
2159 | return &ndev->stats; | ||
2160 | |||
2060 | pm_runtime_get_sync(&mdp->pdev->dev); | 2161 | pm_runtime_get_sync(&mdp->pdev->dev); |
2061 | 2162 | ||
2062 | ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); | 2163 | ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); |
@@ -2438,6 +2539,11 @@ static int sh_eth_vlan_rx_kill_vid(struct net_device *ndev, | |||
2438 | /* SuperH's TSU register init function */ | 2539 | /* SuperH's TSU register init function */ |
2439 | static void sh_eth_tsu_init(struct sh_eth_private *mdp) | 2540 | static void sh_eth_tsu_init(struct sh_eth_private *mdp) |
2440 | { | 2541 | { |
2542 | if (sh_eth_is_rz_fast_ether(mdp)) { | ||
2543 | sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ | ||
2544 | return; | ||
2545 | } | ||
2546 | |||
2441 | sh_eth_tsu_write(mdp, 0, TSU_FWEN0); /* Disable forward(0->1) */ | 2547 | sh_eth_tsu_write(mdp, 0, TSU_FWEN0); /* Disable forward(0->1) */ |
2442 | sh_eth_tsu_write(mdp, 0, TSU_FWEN1); /* Disable forward(1->0) */ | 2548 | sh_eth_tsu_write(mdp, 0, TSU_FWEN1); /* Disable forward(1->0) */ |
2443 | sh_eth_tsu_write(mdp, 0, TSU_FCM); /* forward fifo 3k-3k */ | 2549 | sh_eth_tsu_write(mdp, 0, TSU_FCM); /* forward fifo 3k-3k */ |
@@ -2557,6 +2663,9 @@ static const u16 *sh_eth_get_register_offset(int register_type) | |||
2557 | case SH_ETH_REG_GIGABIT: | 2663 | case SH_ETH_REG_GIGABIT: |
2558 | reg_offset = sh_eth_offset_gigabit; | 2664 | reg_offset = sh_eth_offset_gigabit; |
2559 | break; | 2665 | break; |
2666 | case SH_ETH_REG_FAST_RZ: | ||
2667 | reg_offset = sh_eth_offset_fast_rz; | ||
2668 | break; | ||
2560 | case SH_ETH_REG_FAST_RCAR: | 2669 | case SH_ETH_REG_FAST_RCAR: |
2561 | reg_offset = sh_eth_offset_fast_rcar; | 2670 | reg_offset = sh_eth_offset_fast_rcar; |
2562 | break; | 2671 | break; |
@@ -2795,6 +2904,7 @@ static struct platform_device_id sh_eth_id_table[] = { | |||
2795 | { "sh7757-ether", (kernel_ulong_t)&sh7757_data }, | 2904 | { "sh7757-ether", (kernel_ulong_t)&sh7757_data }, |
2796 | { "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga }, | 2905 | { "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga }, |
2797 | { "sh7763-gether", (kernel_ulong_t)&sh7763_data }, | 2906 | { "sh7763-gether", (kernel_ulong_t)&sh7763_data }, |
2907 | { "r7s72100-ether", (kernel_ulong_t)&r7s72100_data }, | ||
2798 | { "r8a7740-gether", (kernel_ulong_t)&r8a7740_data }, | 2908 | { "r8a7740-gether", (kernel_ulong_t)&r8a7740_data }, |
2799 | { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data }, | 2909 | { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data }, |
2800 | { "r8a7790-ether", (kernel_ulong_t)&r8a779x_data }, | 2910 | { "r8a7790-ether", (kernel_ulong_t)&r8a779x_data }, |
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index 0fe35b72a1d0..6075915b88ec 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h | |||
@@ -155,6 +155,7 @@ enum { | |||
155 | 155 | ||
156 | enum { | 156 | enum { |
157 | SH_ETH_REG_GIGABIT, | 157 | SH_ETH_REG_GIGABIT, |
158 | SH_ETH_REG_FAST_RZ, | ||
158 | SH_ETH_REG_FAST_RCAR, | 159 | SH_ETH_REG_FAST_RCAR, |
159 | SH_ETH_REG_FAST_SH4, | 160 | SH_ETH_REG_FAST_SH4, |
160 | SH_ETH_REG_FAST_SH3_SH2 | 161 | SH_ETH_REG_FAST_SH3_SH2 |
@@ -169,7 +170,7 @@ enum { | |||
169 | 170 | ||
170 | /* Register's bits | 171 | /* Register's bits |
171 | */ | 172 | */ |
172 | /* EDSR : sh7734, sh7757, sh7763, and r8a7740 only */ | 173 | /* EDSR : sh7734, sh7757, sh7763, r8a7740, and r7s72100 only */ |
173 | enum EDSR_BIT { | 174 | enum EDSR_BIT { |
174 | EDSR_ENT = 0x01, EDSR_ENR = 0x02, | 175 | EDSR_ENT = 0x01, EDSR_ENR = 0x02, |
175 | }; | 176 | }; |