sh_eth.c revision 264be2f5a973cc85be3e31d6bf6234b55a256627
1128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov/*  SuperH Ethernet device driver
286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
3f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
4b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov *  Copyright (C) 2008-2014 Renesas Solutions Corp.
5b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov *  Copyright (C) 2013-2014 Cogent Embedded, Inc.
6702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks *  Copyright (C) 2014 Codethink Limited
786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  This program is free software; you can redistribute it and/or modify it
986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  under the terms and conditions of the GNU General Public License,
1086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  version 2, as published by the Free Software Foundation.
1186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
1286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  This program is distributed in the hope it will be useful, but WITHOUT
1386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  more details.
1686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
1786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  The full GNU General Public License is included in this distribution in
1886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  the file called "COPYING".
1986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */
2086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
210654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/module.h>
220654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/kernel.h>
230654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/spinlock.h>
246a27cdeddf48858089e3672f844615cbf0877ebfNobuhiro Iwamatsu#include <linux/interrupt.h>
2586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/dma-mapping.h>
2686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/etherdevice.h>
2786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/delay.h>
2886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/platform_device.h>
2986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/mdio-bitbang.h>
3086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/netdevice.h>
31b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of.h>
32b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of_device.h>
33b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of_irq.h>
34b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of_net.h>
3586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/phy.h>
3686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/cache.h>
3786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/io.h>
38bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm#include <linux/pm_runtime.h>
395a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
40dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#include <linux/ethtool.h>
41fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda#include <linux/if_vlan.h>
42f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu#include <linux/clk.h>
43d4fa0e35fdbd54acf791fa3793d6d17f7795f7aeYoshihiro Shimoda#include <linux/sh_eth.h>
44702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks#include <linux/of_mdio.h>
4586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
4686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include "sh_eth.h"
4786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
48dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#define SH_ETH_DEF_MSG_ENABLE \
49dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		(NETIF_MSG_LINK	| \
50dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		NETIF_MSG_TIMER	| \
51dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		NETIF_MSG_RX_ERR| \
52dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		NETIF_MSG_TX_ERR)
53dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
54c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
55c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDSR]		= 0x0000,
56c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDMR]		= 0x0400,
57c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDTRR]		= 0x0408,
58c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDRRR]		= 0x0410,
59c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESR]		= 0x0428,
60c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESIPR]	= 0x0430,
61c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDLAR]		= 0x0010,
62c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFAR]		= 0x0014,
63c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFXR]		= 0x0018,
64c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFFR]		= 0x001c,
65c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDLAR]		= 0x0030,
66c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFAR]		= 0x0034,
67c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFXR]		= 0x0038,
68c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFFR]		= 0x003c,
69c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TRSCER]	= 0x0438,
70c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMFCR]		= 0x0440,
71c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TFTR]		= 0x0448,
72c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FDR]		= 0x0450,
73c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMCR]		= 0x0458,
74c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RPADIR]	= 0x0460,
75c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FCFTR]		= 0x0468,
76c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CSMR]		= 0x04E4,
77c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
78c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECMR]		= 0x0500,
79c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSR]		= 0x0510,
80c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSIPR]	= 0x0518,
81c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIR]		= 0x0520,
82c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PSR]		= 0x0528,
83c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIPR]		= 0x052c,
84c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFLR]		= 0x0508,
85c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[APR]		= 0x0554,
86c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MPR]		= 0x0558,
87c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PFTCR]		= 0x055c,
88c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PFRCR]		= 0x0560,
89c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSER]	= 0x0564,
90c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[GECMR]		= 0x05b0,
91c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[BCULR]		= 0x05b4,
92c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAHR]		= 0x05c0,
93c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MALR]		= 0x05c8,
94c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TROCR]		= 0x0700,
95c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CDCR]		= 0x0708,
96c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[LCCR]		= 0x0710,
97c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEFCR]		= 0x0740,
98c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FRECR]		= 0x0748,
99c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSFRCR]	= 0x0750,
100c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TLFRCR]	= 0x0758,
101c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCR]		= 0x0760,
102c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CERCR]		= 0x0768,
103c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEECR]		= 0x0770,
104c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAFCR]		= 0x0778,
105c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMII_MII]	= 0x0790,
106c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
107c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ARSTR]		= 0x0000,
108c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_CTRST]	= 0x0004,
109c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN0]	= 0x0010,
110c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN1]	= 0x0014,
111c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FCM]	= 0x0018,
112c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL0]	= 0x0020,
113c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL1]	= 0x0024,
114c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL0]	= 0x0028,
115c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL1]	= 0x002c,
116c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL0]	= 0x0030,
117c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL1]	= 0x0034,
118c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSLC]	= 0x0038,
119c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAG0]	= 0x0040,
120c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAG1]	= 0x0044,
121c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSR]	= 0x0050,
122c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWINMK]	= 0x0054,
123c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT0]	= 0x0048,
124c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT1]	= 0x004c,
125c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_VTAG0]	= 0x0058,
126c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_VTAG1]	= 0x005c,
127c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADSBSY]	= 0x0060,
128c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_TEN]	= 0x0064,
129c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST1]	= 0x0070,
130c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST2]	= 0x0074,
131c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST3]	= 0x0078,
132c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST4]	= 0x007c,
133c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRH0]	= 0x0100,
134c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL0]	= 0x0104,
135c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRH31]	= 0x01f8,
136c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL31]	= 0x01fc,
137c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
138c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR0]	= 0x0080,
139c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR0]	= 0x0084,
140c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR0]	= 0x0088,
141c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR0]	= 0x008c,
142c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR0]	= 0x0090,
143c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR0]	= 0x0094,
144c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR1]	= 0x00a0,
145c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR1]	= 0x00a0,
146c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR1]	= 0x00a8,
147c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR1]	= 0x00ac,
148c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR1]	= 0x00b0,
149c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR1]	= 0x00b4,
150c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov};
151c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
152db893473d313a4ad9455e89d1bd5e136a57f411eSimon Hormanstatic const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
153db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[EDSR]		= 0x0000,
154db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[EDMR]		= 0x0400,
155db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[EDTRR]		= 0x0408,
156db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[EDRRR]		= 0x0410,
157db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[EESR]		= 0x0428,
158db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[EESIPR]	= 0x0430,
159db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TDLAR]		= 0x0010,
160db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TDFAR]		= 0x0014,
161db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TDFXR]		= 0x0018,
162db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TDFFR]		= 0x001c,
163db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RDLAR]		= 0x0030,
164db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RDFAR]		= 0x0034,
165db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RDFXR]		= 0x0038,
166db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RDFFR]		= 0x003c,
167db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TRSCER]	= 0x0438,
168db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RMFCR]		= 0x0440,
169db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TFTR]		= 0x0448,
170db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[FDR]		= 0x0450,
171db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RMCR]		= 0x0458,
172db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RPADIR]	= 0x0460,
173db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[FCFTR]		= 0x0468,
174db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[CSMR]		= 0x04E4,
175db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
176db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[ECMR]		= 0x0500,
177db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RFLR]		= 0x0508,
178db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[ECSR]		= 0x0510,
179db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[ECSIPR]	= 0x0518,
180db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[PIR]		= 0x0520,
181db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[APR]		= 0x0554,
182db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[MPR]		= 0x0558,
183db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[PFTCR]		= 0x055c,
184db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[PFRCR]		= 0x0560,
185db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TPAUSER]	= 0x0564,
186db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[MAHR]		= 0x05c0,
187db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[MALR]		= 0x05c8,
188db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[CEFCR]		= 0x0740,
189db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[FRECR]		= 0x0748,
190db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSFRCR]	= 0x0750,
191db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TLFRCR]	= 0x0758,
192db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RFCR]		= 0x0760,
193db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[MAFCR]		= 0x0778,
194db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
195db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[ARSTR]		= 0x0000,
196db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_CTRST]	= 0x0004,
197db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_VTAG0]	= 0x0058,
198db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_ADSBSY]	= 0x0060,
199db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_TEN]	= 0x0064,
200db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_ADRH0]	= 0x0100,
201db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_ADRL0]	= 0x0104,
202db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_ADRH31]	= 0x01f8,
203db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TSU_ADRL31]	= 0x01fc,
204db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
205db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TXNLCR0]	= 0x0080,
206db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[TXALCR0]	= 0x0084,
207db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RXNLCR0]	= 0x0088,
208db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	[RXALCR0]	= 0x008C,
209db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman};
210db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
211a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyovstatic const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
212a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[ECMR]		= 0x0300,
213a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFLR]		= 0x0308,
214a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[ECSR]		= 0x0310,
215a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[ECSIPR]	= 0x0318,
216a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[PIR]		= 0x0320,
217a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[PSR]		= 0x0328,
218a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RDMLR]		= 0x0340,
219a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[IPGR]		= 0x0350,
220a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[APR]		= 0x0354,
221a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MPR]		= 0x0358,
222a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFCF]		= 0x0360,
223a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TPAUSER]	= 0x0364,
224a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TPAUSECR]	= 0x0368,
225a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MAHR]		= 0x03c0,
226a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MALR]		= 0x03c8,
227a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TROCR]		= 0x03d0,
228a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[CDCR]		= 0x03d4,
229a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[LCCR]		= 0x03d8,
230a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[CNDCR]		= 0x03dc,
231a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[CEFCR]		= 0x03e4,
232a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[FRECR]		= 0x03e8,
233a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TSFRCR]	= 0x03ec,
234a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TLFRCR]	= 0x03f0,
235a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFCR]		= 0x03f4,
236a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MAFCR]		= 0x03f8,
237a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
238a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EDMR]		= 0x0200,
239a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EDTRR]		= 0x0208,
240a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EDRRR]		= 0x0210,
241a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TDLAR]		= 0x0218,
242a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RDLAR]		= 0x0220,
243a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EESR]		= 0x0228,
244a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EESIPR]	= 0x0230,
245a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TRSCER]	= 0x0238,
246a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RMFCR]		= 0x0240,
247a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TFTR]		= 0x0248,
248a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[FDR]		= 0x0250,
249a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RMCR]		= 0x0258,
250a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TFUCR]		= 0x0264,
251a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFOCR]		= 0x0268,
25255754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman	[RMIIMODE]      = 0x026c,
253a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[FCFTR]		= 0x0270,
254a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TRIMD]		= 0x027c,
255a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov};
256a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
257c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
258c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECMR]		= 0x0100,
259c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFLR]		= 0x0108,
260c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSR]		= 0x0110,
261c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSIPR]	= 0x0118,
262c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIR]		= 0x0120,
263c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PSR]		= 0x0128,
264c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDMLR]		= 0x0140,
265c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[IPGR]		= 0x0150,
266c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[APR]		= 0x0154,
267c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MPR]		= 0x0158,
268c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSER]	= 0x0164,
269c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCF]		= 0x0160,
270c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSECR]	= 0x0168,
271c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[BCFRR]		= 0x016c,
272c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAHR]		= 0x01c0,
273c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MALR]		= 0x01c8,
274c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TROCR]		= 0x01d0,
275c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CDCR]		= 0x01d4,
276c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[LCCR]		= 0x01d8,
277c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CNDCR]		= 0x01dc,
278c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEFCR]		= 0x01e4,
279c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FRECR]		= 0x01e8,
280c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSFRCR]	= 0x01ec,
281c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TLFRCR]	= 0x01f0,
282c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCR]		= 0x01f4,
283c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAFCR]		= 0x01f8,
284c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RTRATE]	= 0x01fc,
285c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
286c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDMR]		= 0x0000,
287c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDTRR]		= 0x0008,
288c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDRRR]		= 0x0010,
289c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDLAR]		= 0x0018,
290c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDLAR]		= 0x0020,
291c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESR]		= 0x0028,
292c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESIPR]	= 0x0030,
293c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TRSCER]	= 0x0038,
294c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMFCR]		= 0x0040,
295c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TFTR]		= 0x0048,
296c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FDR]		= 0x0050,
297c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMCR]		= 0x0058,
298c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TFUCR]		= 0x0064,
299c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFOCR]		= 0x0068,
300c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FCFTR]		= 0x0070,
301c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RPADIR]	= 0x0078,
302c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TRIMD]		= 0x007c,
303c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RBWAR]		= 0x00c8,
304c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFAR]		= 0x00cc,
305c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TBRAR]		= 0x00d4,
306c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFAR]		= 0x00d8,
307c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov};
308c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
309c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
310c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECMR]		= 0x0160,
311c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSR]		= 0x0164,
312c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSIPR]	= 0x0168,
313c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIR]		= 0x016c,
314c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAHR]		= 0x0170,
315c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MALR]		= 0x0174,
316c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFLR]		= 0x0178,
317c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PSR]		= 0x017c,
318c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TROCR]		= 0x0180,
319c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CDCR]		= 0x0184,
320c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[LCCR]		= 0x0188,
321c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CNDCR]		= 0x018c,
322c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEFCR]		= 0x0194,
323c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FRECR]		= 0x0198,
324c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSFRCR]	= 0x019c,
325c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TLFRCR]	= 0x01a0,
326c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCR]		= 0x01a4,
327c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAFCR]		= 0x01a8,
328c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[IPGR]		= 0x01b4,
329c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[APR]		= 0x01b8,
330c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MPR]		= 0x01bc,
331c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSER]	= 0x01c4,
332c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[BCFR]		= 0x01cc,
333c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
334c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ARSTR]		= 0x0000,
335c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_CTRST]	= 0x0004,
336c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN0]	= 0x0010,
337c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN1]	= 0x0014,
338c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FCM]	= 0x0018,
339c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL0]	= 0x0020,
340c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL1]	= 0x0024,
341c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL0]	= 0x0028,
342c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL1]	= 0x002c,
343c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL0]	= 0x0030,
344c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL1]	= 0x0034,
345c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSLC]	= 0x0038,
346c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAGM0]	= 0x0040,
347c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAGM1]	= 0x0044,
348c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT0]	= 0x0048,
349c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT1]	= 0x004c,
350c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSR]	= 0x0050,
351c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWINMK]	= 0x0054,
352c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADSBSY]	= 0x0060,
353c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_TEN]	= 0x0064,
354c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST1]	= 0x0070,
355c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST2]	= 0x0074,
356c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST3]	= 0x0078,
357c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST4]	= 0x007c,
358c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
359c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR0]	= 0x0080,
360c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR0]	= 0x0084,
361c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR0]	= 0x0088,
362c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR0]	= 0x008c,
363c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR0]	= 0x0090,
364c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR0]	= 0x0094,
365c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR1]	= 0x00a0,
366c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR1]	= 0x00a0,
367c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR1]	= 0x00a8,
368c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR1]	= 0x00ac,
369c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR1]	= 0x00b0,
370c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR1]	= 0x00b4,
371c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
372c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRH0]	= 0x0100,
373c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL0]	= 0x0104,
374c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL31]	= 0x01fc,
375c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov};
376c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
377504c8ca55c70fb6cab0b97381e70ad0e143f539eSimon Hormanstatic bool sh_eth_is_gether(struct sh_eth_private *mdp)
378dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu{
379504c8ca55c70fb6cab0b97381e70ad0e143f539eSimon Horman	return mdp->reg_offset == sh_eth_offset_gigabit;
380dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu}
381dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
382db893473d313a4ad9455e89d1bd5e136a57f411eSimon Hormanstatic bool sh_eth_is_rz_fast_ether(struct sh_eth_private *mdp)
383db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman{
384db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	return mdp->reg_offset == sh_eth_offset_fast_rz;
385db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman}
386db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
3878e994402ad5e6ae3d391c0935f9f1dc2eeb92a5eSergei Shtylyovstatic void sh_eth_select_mii(struct net_device *ndev)
3885e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu{
3895e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	u32 value = 0x0;
3905e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
3915e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
3925e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	switch (mdp->phy_interface) {
3935e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	case PHY_INTERFACE_MODE_GMII:
3945e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x2;
3955e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
3965e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	case PHY_INTERFACE_MODE_MII:
3975e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x1;
3985e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
3995e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	case PHY_INTERFACE_MODE_RMII:
4005e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x0;
4015e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
4025e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	default:
4035e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		pr_warn("PHY interface mode was not setup. Set to MII.\n");
4045e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x1;
4055e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
4065e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	}
4075e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
4085e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, value, RMII_MII);
4095e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu}
4105e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
4118e994402ad5e6ae3d391c0935f9f1dc2eeb92a5eSergei Shtylyovstatic void sh_eth_set_duplex(struct net_device *ndev)
41265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda{
41365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
41465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
41565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	if (mdp->duplex) /* Full */
4164a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
41765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	else		/* Half */
4184a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
41965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda}
42065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
42104b0ed2ad49834fe47d3c4171ad189c688a222b9Nobuhiro Iwamatsu/* There is CPU dependent code */
422589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyovstatic void sh_eth_set_rate_r8a777x(struct net_device *ndev)
42365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda{
42465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
425d0418bb7123f44b23d69ac349eec7daf9103472fPhil Edworthy
426a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	switch (mdp->speed) {
427a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	case 10: /* 10BASE */
428a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_ELB, ECMR);
429a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
430a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	case 100:/* 100BASE */
431a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_ELB, ECMR);
432a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
433a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	default:
434a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
435a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	}
436a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov}
437a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
438674853b222168f2066db028cad89ab52cbcdeee5Sergei Shtylyov/* R8A7778/9 */
439589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyovstatic struct sh_eth_cpu_data r8a777x_data = {
440a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.set_duplex	= sh_eth_set_duplex,
441589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyov	.set_rate	= sh_eth_set_rate_r8a777x,
442a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
443a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_FAST_RCAR,
444a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
445a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
446a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
447a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.eesipr_value	= 0x01ff009f,
448a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
449a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
450ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
451ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
452ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_ECI,
453a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
454a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.apr		= 1,
455a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.mpr		= 1,
456a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.tpauser	= 1,
457a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.hw_swap	= 1,
458a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov};
459a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
46094a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyov/* R8A7790/1 */
46194a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyovstatic struct sh_eth_cpu_data r8a779x_data = {
462e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.set_duplex	= sh_eth_set_duplex,
463e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.set_rate	= sh_eth_set_rate_r8a777x,
464e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman
465a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_FAST_RCAR,
466a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
467e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
468e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
469e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.eesipr_value	= 0x01ff009f,
470e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman
471e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
472ba361cb3d4c977e2b94b5d97905f66b4d48964deLaurent Pinchart	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
473ba361cb3d4c977e2b94b5d97905f66b4d48964deLaurent Pinchart			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
474ba361cb3d4c977e2b94b5d97905f66b4d48964deLaurent Pinchart			  EESR_ECI,
475e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman
476e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.apr		= 1,
477e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.mpr		= 1,
478e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.tpauser	= 1,
479e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.hw_swap	= 1,
480e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman	.rmiimode	= 1,
481fd9af07c3404ac9ecbd0d859563360f51ce1ffdeKouei Abe	.shift_rd0	= 1,
482e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman};
483e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman
4849c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyovstatic void sh_eth_set_rate_sh7724(struct net_device *ndev)
485a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov{
486a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	struct sh_eth_private *mdp = netdev_priv(ndev);
48765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
48865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	switch (mdp->speed) {
48965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	case 10: /* 10BASE */
490a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
49165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda		break;
49265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	case 100:/* 100BASE */
493a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
49465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda		break;
49565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	default:
49665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda		break;
49765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	}
49865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda}
49965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
50065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda/* SH7724 */
5019c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyovstatic struct sh_eth_cpu_data sh7724_data = {
50265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.set_duplex	= sh_eth_set_duplex,
5039c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyov	.set_rate	= sh_eth_set_rate_sh7724,
50465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
505a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_FAST_SH4,
506a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
50765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
50865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
509a80c3de714bc4855747faf5f00e8203fb800e6bbSergei Shtylyov	.eesipr_value	= 0x01ff009f,
51065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
51165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
512ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
513ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
514ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_ECI,
51565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
51665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.apr		= 1,
51765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.mpr		= 1,
51865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.tpauser	= 1,
51965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.hw_swap	= 1,
520503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm	.rpadir		= 1,
521503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm	.rpadir_value	= 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
52265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda};
5235cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
52424549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyovstatic void sh_eth_set_rate_sh7757(struct net_device *ndev)
525f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda{
526f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
527f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
528f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	switch (mdp->speed) {
529f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	case 10: /* 10BASE */
5304a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0, RTRATE);
531f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda		break;
532f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	case 100:/* 100BASE */
5334a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 1, RTRATE);
534f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda		break;
535f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	default:
536f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda		break;
537f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	}
538f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda}
539f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
540f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda/* SH7757 */
54124549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyovstatic struct sh_eth_cpu_data sh7757_data = {
54224549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov	.set_duplex	= sh_eth_set_duplex,
54324549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov	.set_rate	= sh_eth_set_rate_sh7757,
544f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
545a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_FAST_SH4,
546a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
547f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
548305a3388b5b3121aff6b10054136b40ca91ab35bSergei Shtylyov	.rmcr_value	= RMCR_RNC,
549f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
550f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
551ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
552ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
553ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_ECI,
554f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
5555b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu	.irq_flags	= IRQF_SHARED,
556f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.apr		= 1,
557f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.mpr		= 1,
558f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.tpauser	= 1,
559f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.hw_swap	= 1,
560f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.no_ade		= 1,
5612e98e7974de208de0dab9e9969bd47576d07ff10Yoshihiro Shimoda	.rpadir		= 1,
5622e98e7974de208de0dab9e9969bd47576d07ff10Yoshihiro Shimoda	.rpadir_value   = 2 << 16,
563f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda};
56465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
565e403d295817cf9f8be3110eb7ee1a03981287495David S. Miller#define SH_GIGA_ETH_BASE	0xfee00000UL
5668fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define GIGA_MALR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
5678fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define GIGA_MAHR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
5688fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic void sh_eth_chip_reset_giga(struct net_device *ndev)
5698fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{
5708fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	int i;
5718fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	unsigned long mahr[2], malr[2];
5728fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5738fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	/* save MAHR and MALR */
5748fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	for (i = 0; i < 2; i++) {
575ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		malr[i] = ioread32((void *)GIGA_MALR(i));
576ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		mahr[i] = ioread32((void *)GIGA_MAHR(i));
5778fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	}
5788fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5798fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	/* reset device */
580ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	iowrite32(ARSTR_ARSTR, (void *)(SH_GIGA_ETH_BASE + 0x1800));
5818fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	mdelay(1);
5828fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5838fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	/* restore MAHR and MALR */
5848fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	for (i = 0; i < 2; i++) {
585ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		iowrite32(malr[i], (void *)GIGA_MALR(i));
586ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		iowrite32(mahr[i], (void *)GIGA_MAHR(i));
5878fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	}
5888fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}
5898fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5908fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic void sh_eth_set_rate_giga(struct net_device *ndev)
5918fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{
5928fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
5938fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5948fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	switch (mdp->speed) {
5958fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	case 10: /* 10BASE */
5968fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x00000000, GECMR);
5978fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
5988fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	case 100:/* 100BASE */
5998fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x00000010, GECMR);
6008fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
6018fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	case 1000: /* 1000BASE */
6028fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x00000020, GECMR);
6038fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
6048fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	default:
6058fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
6068fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	}
6078fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}
6088fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
6098fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda/* SH7757(GETHERC) */
61024549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyovstatic struct sh_eth_cpu_data sh7757_data_giga = {
6118fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.chip_reset	= sh_eth_chip_reset_giga,
61204b0ed2ad49834fe47d3c4171ad189c688a222b9Nobuhiro Iwamatsu	.set_duplex	= sh_eth_set_duplex,
6138fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.set_rate	= sh_eth_set_rate_giga,
6148fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
615a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_GIGABIT,
616a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
6178fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.ecsr_value	= ECSR_ICD | ECSR_MPD,
6188fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
6198fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
6208fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
6218fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.tx_check	= EESR_TC1 | EESR_FTC,
622ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
623ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
624ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_TDE | EESR_ECI,
6258fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.fdr_value	= 0x0000072f,
626305a3388b5b3121aff6b10054136b40ca91ab35bSergei Shtylyov	.rmcr_value	= RMCR_RNC,
6278fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
6285b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu	.irq_flags	= IRQF_SHARED,
6298fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.apr		= 1,
6308fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.mpr		= 1,
6318fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.tpauser	= 1,
6328fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.bculr		= 1,
6338fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.hw_swap	= 1,
6348fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.rpadir		= 1,
6358fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.rpadir_value   = 2 << 16,
6368fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.no_trimd	= 1,
6378fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.no_ade		= 1,
6383acbc9715a5ac8a2534a69eb3488b63b7c9fb1e2Yoshihiro Shimoda	.tsu		= 1,
6398fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda};
6408fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
641380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_chip_reset(struct net_device *ndev)
642380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
6434986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
6444986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda
645380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	/* reset device */
6464986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
647380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	mdelay(1);
648380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
649380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
650f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyovstatic void sh_eth_set_rate_gether(struct net_device *ndev)
651380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
652380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
653380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
654380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	switch (mdp->speed) {
655380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	case 10: /* 10BASE */
6564a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, GECMR_10, GECMR);
657380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
658380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	case 100:/* 100BASE */
6594a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, GECMR_100, GECMR);
660380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
661380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	case 1000: /* 1000BASE */
6624a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, GECMR_1000, GECMR);
663380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
664380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	default:
665380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
666380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	}
667380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
668380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
669f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov/* SH7734 */
670f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyovstatic struct sh_eth_cpu_data sh7734_data = {
671380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.chip_reset	= sh_eth_chip_reset,
672380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.set_duplex	= sh_eth_set_duplex,
673f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.set_rate	= sh_eth_set_rate_gether,
674f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov
675a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_GIGABIT,
676a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
677f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.ecsr_value	= ECSR_ICD | ECSR_MPD,
678f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
679f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
680f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov
681f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.tx_check	= EESR_TC1 | EESR_FTC,
682ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
683ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
684ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_TDE | EESR_ECI,
685f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov
686f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.apr		= 1,
687f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.mpr		= 1,
688f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.tpauser	= 1,
689f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.bculr		= 1,
690f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.hw_swap	= 1,
691f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.no_trimd	= 1,
692f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.no_ade		= 1,
693f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.tsu		= 1,
694f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.hw_crc		= 1,
695f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.select_mii	= 1,
696f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov};
697f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov
698f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov/* SH7763 */
699f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyovstatic struct sh_eth_cpu_data sh7763_data = {
700f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.chip_reset	= sh_eth_chip_reset,
701f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.set_duplex	= sh_eth_set_duplex,
702f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	.set_rate	= sh_eth_set_rate_gether,
703380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
704a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_GIGABIT,
705a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
706380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.ecsr_value	= ECSR_ICD | ECSR_MPD,
707380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
708380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
709380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
710380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.tx_check	= EESR_TC1 | EESR_FTC,
711128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
712128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
713380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			  EESR_ECI,
714380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
715380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.apr		= 1,
716380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.mpr		= 1,
717380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.tpauser	= 1,
718380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.bculr		= 1,
719380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.hw_swap	= 1,
720380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.no_trimd	= 1,
721380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.no_ade		= 1,
7224986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	.tsu		= 1,
7235b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu	.irq_flags	= IRQF_SHARED,
724380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda};
725380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
726e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyovstatic void sh_eth_chip_reset_r8a7740(struct net_device *ndev)
72773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda{
72873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
72973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
73073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	/* reset device */
73173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
73273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	mdelay(1);
73373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
7345e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_select_mii(ndev);
73573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda}
73673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
73773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda/* R8A7740 */
738e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyovstatic struct sh_eth_cpu_data r8a7740_data = {
739e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyov	.chip_reset	= sh_eth_chip_reset_r8a7740,
74073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.set_duplex	= sh_eth_set_duplex,
741e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyov	.set_rate	= sh_eth_set_rate_gether,
74273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
743a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_GIGABIT,
744a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
74573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.ecsr_value	= ECSR_ICD | ECSR_MPD,
74673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
74773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
74873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
74973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.tx_check	= EESR_TC1 | EESR_FTC,
750ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
751ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
752ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov			  EESR_TDE | EESR_ECI,
753cc23528db0300d5c8c0b98670a577bf1dc3e0e82Simon Horman	.fdr_value	= 0x0000070f,
754305a3388b5b3121aff6b10054136b40ca91ab35bSergei Shtylyov	.rmcr_value	= RMCR_RNC,
75573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
75673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.apr		= 1,
75773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.mpr		= 1,
75873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.tpauser	= 1,
75973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.bculr		= 1,
76073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.hw_swap	= 1,
761cc23528db0300d5c8c0b98670a577bf1dc3e0e82Simon Horman	.rpadir		= 1,
762cc23528db0300d5c8c0b98670a577bf1dc3e0e82Simon Horman	.rpadir_value   = 2 << 16,
76373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.no_trimd	= 1,
76473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.no_ade		= 1,
76573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.tsu		= 1,
7665e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	.select_mii	= 1,
767ac8025a643a0e0beb81f3f37ca693364c6b77858Sergei Shtylyov	.shift_rd0	= 1,
76873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda};
76973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
770db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman/* R7S72100 */
771db893473d313a4ad9455e89d1bd5e136a57f411eSimon Hormanstatic struct sh_eth_cpu_data r7s72100_data = {
772db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.chip_reset	= sh_eth_chip_reset,
773db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.set_duplex	= sh_eth_set_duplex,
774db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
775db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.register_type	= SH_ETH_REG_FAST_RZ,
776db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
777db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.ecsr_value	= ECSR_ICD,
778db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.ecsipr_value	= ECSIPR_ICDIP,
779db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.eesipr_value	= 0xff7f009f,
780db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
781db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.tx_check	= EESR_TC1 | EESR_FTC,
782db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
783db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman			  EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE |
784db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman			  EESR_TDE | EESR_ECI,
785db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.fdr_value	= 0x0000070f,
786db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.rmcr_value	= RMCR_RNC,
787db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
788db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.no_psr		= 1,
789db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.apr		= 1,
790db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.mpr		= 1,
791db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.tpauser	= 1,
792db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.hw_swap	= 1,
793db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.rpadir		= 1,
794db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.rpadir_value   = 2 << 16,
795db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.no_trimd	= 1,
796db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.no_ade		= 1,
797db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.hw_crc		= 1,
798db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.tsu		= 1,
799db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	.shift_rd0	= 1,
800db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman};
801db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
802c18a79abe31f555ec3b363b5b8c1d003230053b6Sergei Shtylyovstatic struct sh_eth_cpu_data sh7619_data = {
803a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_FAST_SH3_SH2,
804a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
805380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
806380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
807380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.apr		= 1,
808380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.mpr		= 1,
809380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.tpauser	= 1,
810380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.hw_swap	= 1,
811380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda};
8127bbe150d8c57c59689c8c50fd7b9915f4a7e10daSergei Shtylyov
8137bbe150d8c57c59689c8c50fd7b9915f4a7e10daSergei Shtylyovstatic struct sh_eth_cpu_data sh771x_data = {
814a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	.register_type	= SH_ETH_REG_FAST_SH3_SH2,
815a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov
816380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
8174986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	.tsu		= 1,
818380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda};
819380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
820380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
821380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
822380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->ecsr_value)
823380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->ecsr_value = DEFAULT_ECSR_INIT;
824380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
825380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->ecsipr_value)
826380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->ecsipr_value = DEFAULT_ECSIPR_INIT;
827380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
828380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->fcftr_value)
829128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		cd->fcftr_value = DEFAULT_FIFO_F_D_RFF |
830380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				  DEFAULT_FIFO_F_D_RFD;
831380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
832380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->fdr_value)
833380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->fdr_value = DEFAULT_FDR_INIT;
834380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
835380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->rmcr_value)
836380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->rmcr_value = DEFAULT_RMCR_VALUE;
837380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
838380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->tx_check)
839380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->tx_check = DEFAULT_TX_CHECK;
840380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
841380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->eesr_err_check)
842380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK;
843380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
844380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
8455cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_check_reset(struct net_device *ndev)
8465cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu{
8475cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	int ret = 0;
8485cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	int cnt = 100;
8495cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
8505cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	while (cnt > 0) {
8515cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		if (!(sh_eth_read(ndev, EDMR) & 0x3))
8525cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu			break;
8535cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		mdelay(1);
8545cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		cnt--;
8555cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	}
8569f8c4265bda4a6e9aa97041d5cfd91386f460b65Sergei Shtylyov	if (cnt <= 0) {
8579f8c4265bda4a6e9aa97041d5cfd91386f460b65Sergei Shtylyov		pr_err("Device reset failed\n");
8585cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		ret = -ETIMEDOUT;
8595cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	}
8605cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	return ret;
861380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
862dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
863dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsustatic int sh_eth_reset(struct net_device *ndev)
864dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu{
865dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
866dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu	int ret = 0;
867dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
868db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) {
869dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, EDSR_ENALL, EDSR);
870dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
871dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu			     EDMR);
872dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
873dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		ret = sh_eth_check_reset(ndev);
874dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		if (ret)
875dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu			goto out;
876dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
877dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		/* Table Init */
878dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, TDLAR);
879dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, TDFAR);
880dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, TDFXR);
881dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, TDFFR);
882dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, RDLAR);
883dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, RDFAR);
884dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, RDFXR);
885dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, RDFFR);
886dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
887dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		/* Reset HW CRC register */
888dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		if (mdp->cd->hw_crc)
889dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu			sh_eth_write(ndev, 0x0, CSMR);
890dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
891dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		/* Select MII mode */
892dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		if (mdp->cd->select_mii)
893dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu			sh_eth_select_mii(ndev);
894dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu	} else {
895dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
896dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu			     EDMR);
897dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		mdelay(3);
898dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
899dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu			     EDMR);
900dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu	}
901dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu
902dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsuout:
903dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu	return ret;
904dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu}
905380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
90673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
907380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_receive_align(struct sk_buff *skb)
908380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
909380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	int reserve;
910380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
911380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	reserve = SH4_SKB_RX_ALIGN - ((u32)skb->data & (SH4_SKB_RX_ALIGN - 1));
912380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (reserve)
913380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		skb_reserve(skb, reserve);
914380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
915380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#else
916380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_receive_align(struct sk_buff *skb)
917380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
918380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	skb_reserve(skb, SH2_SH3_SKB_RX_ALIGN);
919380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
920380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#endif
921380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
922380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
92371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato/* CPU <-> EDMAC endian convert */
92471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Satostatic inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
92571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato{
92671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	switch (mdp->edmac_endian) {
92771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_LITTLE_ENDIAN:
92871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return cpu_to_le32(x);
92971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_BIG_ENDIAN:
93071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return cpu_to_be32(x);
93171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	}
93271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	return x;
93371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato}
93471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato
93571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Satostatic inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
93671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato{
93771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	switch (mdp->edmac_endian) {
93871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_LITTLE_ENDIAN:
93971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return le32_to_cpu(x);
94071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_BIG_ENDIAN:
94171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return be32_to_cpu(x);
94271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	}
94371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	return x;
94471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato}
94571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato
946128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov/* Program the hardware MAC address from dev->dev_addr. */
94786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void update_mac_address(struct net_device *ndev)
94886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
9494a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev,
950128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		     (ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
951128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		     (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR);
9524a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev,
953128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		     (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR);
95486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
95586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
956128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov/* Get MAC address from SuperH MAC address register
95786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
95886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * SuperH's Ethernet device doesn't have 'ROM' to MAC address.
95986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g).
96086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * When you want use this device, you must set MAC address in bootloader.
96186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
96286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */
963748031f9fd2c06b28817d80761a5de97190cfd03Magnus Dammstatic void read_mac_address(struct net_device *ndev, unsigned char *mac)
96486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
965748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
966d458cdf712e0c671e8e819abb16ecd6e44f9daecJoe Perches		memcpy(ndev->dev_addr, mac, ETH_ALEN);
967748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	} else {
9684a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24);
9694a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF;
9704a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[2] = (sh_eth_read(ndev, MAHR) >> 8) & 0xFF;
9714a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[3] = (sh_eth_read(ndev, MAHR) & 0xFF);
9724a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[4] = (sh_eth_read(ndev, MALR) >> 8) & 0xFF;
9734a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[5] = (sh_eth_read(ndev, MALR) & 0xFF);
974748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	}
97586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
97686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
977c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimodastatic unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
978c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda{
979db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp))
980c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		return EDTRR_TRNS_GETHER;
981c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	else
982c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		return EDTRR_TRNS_ETHER;
983c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda}
984c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda
98586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustruct bb_info {
986ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	void (*set_gate)(void *addr);
98786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct mdiobb_ctrl ctrl;
988ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	void *addr;
98986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mmd_msk;/* MMD */
99086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mdo_msk;
99186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mdi_msk;
99286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mdc_msk;
99386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu};
99486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
99586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit set */
996ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic void bb_set(void *addr, u32 msk)
99786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
998ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	iowrite32(ioread32(addr) | msk, addr);
99986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
100086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
100186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit clear */
1002ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic void bb_clr(void *addr, u32 msk)
100386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
1004ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	iowrite32((ioread32(addr) & ~msk), addr);
100586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
100686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
100786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit read */
1008ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic int bb_read(void *addr, u32 msk)
100986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
1010ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	return (ioread32(addr) & msk) != 0;
101186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
101286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
101386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Data I/O pin control */
101486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
101586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
101686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
1017b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
1018b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1019b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1020b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
102186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (bit)
102286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_set(bitbang->addr, bitbang->mmd_msk);
102386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
102486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_clr(bitbang->addr, bitbang->mmd_msk);
102586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
102686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
102786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Set bit data*/
102886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
102986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
103086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
103186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1032b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1033b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1034b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
103586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (bit)
103686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_set(bitbang->addr, bitbang->mdo_msk);
103786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
103886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_clr(bitbang->addr, bitbang->mdo_msk);
103986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
104086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
104186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Get bit data*/
104286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_get_mdio(struct mdiobb_ctrl *ctrl)
104386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
104486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
1045b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
1046b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1047b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1048b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
104986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return bb_read(bitbang->addr, bitbang->mdi_msk);
105086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
105186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
105286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDC pin control */
105386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
105486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
105586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
105686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1057b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1058b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1059b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
106086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (bit)
106186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_set(bitbang->addr, bitbang->mdc_msk);
106286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
106386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_clr(bitbang->addr, bitbang->mdc_msk);
106486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
106586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
106686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* mdio bus control struct */
106786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct mdiobb_ops bb_ops = {
106886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.owner = THIS_MODULE,
106986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.set_mdc = sh_mdc_ctrl,
107086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.set_mdio_dir = sh_mmd_ctrl,
107186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.set_mdio_data = sh_set_mdio,
107286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.get_mdio_data = sh_get_mdio,
107386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu};
107486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
107586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* free skb and descriptor buffer */
107686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_ring_free(struct net_device *ndev)
107786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
107886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
107986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int i;
108086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
108186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free Rx skb ringbuffer */
108286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (mdp->rx_skbuff) {
1083525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		for (i = 0; i < mdp->num_rx_ring; i++) {
108486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (mdp->rx_skbuff[i])
108586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				dev_kfree_skb(mdp->rx_skbuff[i]);
108686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
108786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
108886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	kfree(mdp->rx_skbuff);
108991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->rx_skbuff = NULL;
109086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
109186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free Tx skb ringbuffer */
109286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (mdp->tx_skbuff) {
1093525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		for (i = 0; i < mdp->num_tx_ring; i++) {
109486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (mdp->tx_skbuff[i])
109586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				dev_kfree_skb(mdp->tx_skbuff[i]);
109686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
109786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
109886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	kfree(mdp->tx_skbuff);
109991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->tx_skbuff = NULL;
110086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
110186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
110286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* format skb and descriptor buffer */
110386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_ring_format(struct net_device *ndev)
110486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
110586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
110686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int i;
110786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sk_buff *skb;
110886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_rxdesc *rxdesc = NULL;
110986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_txdesc *txdesc = NULL;
1110525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring;
1111525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring;
111286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1113128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	mdp->cur_rx = 0;
1114128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	mdp->cur_tx = 0;
1115128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	mdp->dirty_rx = 0;
1116128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	mdp->dirty_tx = 0;
111786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
111886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	memset(mdp->rx_ring, 0, rx_ringsize);
111986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
112086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* build Rx ring buffer */
1121525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_rx_ring; i++) {
112286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* skb */
112386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->rx_skbuff[i] = NULL;
1124dae2e9f430c46c29e3f771110094bd3da3625aa4Pradeep A. Dalvi		skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
112586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->rx_skbuff[i] = skb;
112686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (skb == NULL)
112786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			break;
1128bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz,
1129128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			       DMA_FROM_DEVICE);
1130380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		sh_eth_set_receive_align(skb);
1131380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
113286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* RX descriptor */
113386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc = &mdp->rx_ring[i];
11340029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda		rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
113571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
113686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
113786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* The size of the buffer is 16 byte boundary. */
11380029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
1139b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		/* Rx descriptor address set */
1140b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		if (i == 0) {
11414a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda			sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
1142db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman			if (sh_eth_is_gether(mdp) ||
1143db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman			    sh_eth_is_rz_fast_ether(mdp))
1144c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda				sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
1145b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		}
114686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
114786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1148525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);
114986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
115086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Mark the last entry as wrapping the ring. */
115171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
115286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
115386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	memset(mdp->tx_ring, 0, tx_ringsize);
115486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
115586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* build Tx ring buffer */
1156525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_tx_ring; i++) {
115786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->tx_skbuff[i] = NULL;
115886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc = &mdp->tx_ring[i];
115971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status = cpu_to_edmac(mdp, TD_TFP);
116086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc->buffer_length = 0;
1161b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		if (i == 0) {
116271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato			/* Tx descriptor address set */
11634a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
1164db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman			if (sh_eth_is_gether(mdp) ||
1165db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman			    sh_eth_is_rz_fast_ether(mdp))
1166c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda				sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
1167b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		}
116886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
116986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
117071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
117186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
117286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
117386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Get skb and descriptor buffer */
117486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_ring_init(struct net_device *ndev)
117586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
117686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
117786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int rx_ringsize, tx_ringsize, ret = 0;
117886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1179128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	/* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
118086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 * card needs room to do 8 byte alignment, +2 so we can reserve
118186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 * the first 2 bytes, and +16 gets room for the status word from the
118286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 * card.
118386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 */
118486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ :
118586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			  (((ndev->mtu + 26 + 7) & ~7) + 2 + 16));
1186503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm	if (mdp->cd->rpadir)
1187503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm		mdp->rx_buf_sz += NET_IP_ALIGN;
118886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
118986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Allocate RX and TX skb rings */
1190b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches	mdp->rx_skbuff = kmalloc_array(mdp->num_rx_ring,
1191b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches				       sizeof(*mdp->rx_skbuff), GFP_KERNEL);
119286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->rx_skbuff) {
119386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
119486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return ret;
119586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
119686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1197b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches	mdp->tx_skbuff = kmalloc_array(mdp->num_tx_ring,
1198b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches				       sizeof(*mdp->tx_skbuff), GFP_KERNEL);
119986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->tx_skbuff) {
120086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
120186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto skb_ring_free;
120286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
120386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
120486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Allocate all Rx descriptors. */
1205525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
120686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
1207d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches					  GFP_KERNEL);
120886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->rx_ring) {
120986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
121086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto desc_ring_free;
121186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
121286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
121386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->dirty_rx = 0;
121486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
121586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Allocate all Tx descriptors. */
1216525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
121786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
1218d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches					  GFP_KERNEL);
121986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->tx_ring) {
122086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
122186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto desc_ring_free;
122286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
122386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
122486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
122586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsudesc_ring_free:
122686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* free DMA buffer */
122786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma);
122886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
122986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuskb_ring_free:
123086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free Rx and Tx skb ring buffer */
123186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	sh_eth_ring_free(ndev);
123291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->tx_ring = NULL;
123391c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->rx_ring = NULL;
123486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
123586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
123686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
123786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
123891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimodastatic void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
123991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda{
124091c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	int ringsize;
124191c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda
124291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	if (mdp->rx_ring) {
1243525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
124491c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		dma_free_coherent(NULL, ringsize, mdp->rx_ring,
124591c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda				  mdp->rx_desc_dma);
124691c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		mdp->rx_ring = NULL;
124791c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	}
124891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda
124991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	if (mdp->tx_ring) {
1250525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
125191c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		dma_free_coherent(NULL, ringsize, mdp->tx_ring,
125291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda				  mdp->tx_desc_dma);
125391c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		mdp->tx_ring = NULL;
125491c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	}
125591c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda}
125691c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda
1257525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic int sh_eth_dev_init(struct net_device *ndev, bool start)
125886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
125986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret = 0;
126086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
126186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 val;
126286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
126386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Soft Reset */
12645cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	ret = sh_eth_reset(ndev);
12655cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	if (ret)
12665cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		goto out;
126786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
126855754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman	if (mdp->cd->rmiimode)
126955754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman		sh_eth_write(ndev, 0x1, RMIIMODE);
127055754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman
1271b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Descriptor format */
1272b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	sh_eth_ring_format(ndev);
1273380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->rpadir)
12744a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);
127586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
127686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* all sh_eth int mask */
12774a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, EESIPR);
127886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
127910b9194f959608368ed89df1937f17cfe6bd6d84Yoshihiro Shimoda#if defined(__LITTLE_ENDIAN)
1280380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->hw_swap)
12814a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, EDMR_EL, EDMR);
1282380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	else
1283b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu#endif
12844a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0, EDMR);
128586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1286b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* FIFO size set */
12874a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
12884a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, TFTR);
128986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1290b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Frame recv control */
12914a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);
129286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
12932ecbb783c3bf5a63f555c39deef308dcc1902b7fYoshihiro Shimoda	sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER);
129486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1295380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->bculr)
12964a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0x800, BCULR);	/* Burst sycle set */
1297b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
12984a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR);
129986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1300380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!mdp->cd->no_trimd)
13014a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0, TRIMD);
130286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1303b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Recv frame limit set register */
1304fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda	sh_eth_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN,
1305fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda		     RFLR);
130686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
13074a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
1308525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (start)
1309525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
131086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
131186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PAUSE Prohibition */
13124a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
131386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
131486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
13154a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, val, ECMR);
1316b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
1317380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->set_rate)
1318380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		mdp->cd->set_rate(ndev);
1319380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1320b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* E-MAC Status Register clear */
13214a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
1322b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
1323b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* E-MAC Interrupt Enable register */
1324525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (start)
1325525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
132686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
132786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Set MAC address */
132886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	update_mac_address(ndev);
132986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
133086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* mask reset */
1331380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->apr)
13324a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, APR_AP, APR);
1333380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->mpr)
13344a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, MPR_MP, MPR);
1335380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->tpauser)
13364a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
1337b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
1338525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (start) {
1339525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Setting the Rx mode will start the Rx process. */
1340525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, EDRRR_R, EDRRR);
134186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1342525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		netif_start_queue(ndev);
1343525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
134486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
13455cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsuout:
134686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
134786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
134886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
134986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* free Tx skb function */
135086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_txfree(struct net_device *ndev)
135186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
135286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
135386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_txdesc *txdesc;
1354128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	int free_num = 0;
135586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int entry = 0;
135686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
135786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
1358525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		entry = mdp->dirty_tx % mdp->num_tx_ring;
135986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc = &mdp->tx_ring[entry];
136071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
136186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			break;
136286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Free the original skb. */
136386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->tx_skbuff[entry]) {
136431fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda			dma_unmap_single(&ndev->dev, txdesc->addr,
136531fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda					 txdesc->buffer_length, DMA_TO_DEVICE);
136686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
136786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->tx_skbuff[entry] = NULL;
1368128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			free_num++;
136986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
137071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status = cpu_to_edmac(mdp, TD_TFP);
1371525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		if (entry >= mdp->num_tx_ring - 1)
137271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato			txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
137386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1374bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_packets++;
1375bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_bytes += txdesc->buffer_length;
137686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1377128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	return free_num;
137886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
137986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
138086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Packet receive function */
13813719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovstatic int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
138286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
138386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
138486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_rxdesc *rxdesc;
138586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1386525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int entry = mdp->cur_rx % mdp->num_rx_ring;
1387525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx;
138886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sk_buff *skb;
13893719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	int exceeded = 0;
139086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u16 pkt_len = 0;
1391380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	u32 desc_status;
139286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
139386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	rxdesc = &mdp->rx_ring[entry];
139471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
139571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		desc_status = edmac_to_cpu(mdp, rxdesc->status);
139686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		pkt_len = rxdesc->frame_length;
139786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
139886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (--boguscnt < 0)
139986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			break;
140086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
14013719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		if (*quota <= 0) {
14023719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			exceeded = 1;
14033719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			break;
14043719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		}
14053719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		(*quota)--;
14063719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
140786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (!(desc_status & RDFEND))
1408bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_length_errors++;
140986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1410128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		/* In case of almost all GETHER/ETHERs, the Receive Frame State
1411dd019897358b815f7828dab90b51d51df4d3658dYoshihiro Shimoda		 * (RFS) bits in the Receive Descriptor 0 are from bit 9 to
1412db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		 * bit 0. However, in case of the R8A7740, R8A779x, and
1413db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		 * R7S72100 the RFS bits are from bit 25 to bit 16. So, the
1414db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		 * driver needs right shifting by 16.
1415dd019897358b815f7828dab90b51d51df4d3658dYoshihiro Shimoda		 */
1416ac8025a643a0e0beb81f3f37ca693364c6b77858Sergei Shtylyov		if (mdp->cd->shift_rd0)
1417ac8025a643a0e0beb81f3f37ca693364c6b77858Sergei Shtylyov			desc_status >>= 16;
1418dd019897358b815f7828dab90b51d51df4d3658dYoshihiro Shimoda
141986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
142086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
1421bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_errors++;
142286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS1)
1423bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_crc_errors++;
142486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS2)
1425bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_frame_errors++;
142686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS3)
1427bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_length_errors++;
142886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS4)
1429bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_length_errors++;
143086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS6)
1431bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_missed_errors++;
143286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS10)
1433bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_over_errors++;
143486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		} else {
1435380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			if (!mdp->cd->hw_swap)
1436380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				sh_eth_soft_swap(
1437380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda					phys_to_virt(ALIGN(rxdesc->addr, 4)),
1438380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda					pkt_len + 2);
143986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			skb = mdp->rx_skbuff[entry];
144086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->rx_skbuff[entry] = NULL;
1441503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm			if (mdp->cd->rpadir)
1442503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm				skb_reserve(skb, NET_IP_ALIGN);
14437db8e0c14c9cb4adb667b4c558d8ffec8d5b40f2Kouei Abe			dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr,
14447db8e0c14c9cb4adb667b4c558d8ffec8d5b40f2Kouei Abe						mdp->rx_buf_sz,
14457db8e0c14c9cb4adb667b4c558d8ffec8d5b40f2Kouei Abe						DMA_FROM_DEVICE);
144686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			skb_put(skb, pkt_len);
144786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			skb->protocol = eth_type_trans(skb, ndev);
1448a8e9fd0f7462f5cada5189513d12fe6c9cce2105Sergei Shtylyov			netif_receive_skb(skb);
1449bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_packets++;
1450bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_bytes += pkt_len;
145186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
145271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
1453525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		entry = (++mdp->cur_rx) % mdp->num_rx_ring;
1454862df49750e7ca9369c04d8d8105b3cc5d976e0dYoshihiro Shimoda		rxdesc = &mdp->rx_ring[entry];
145586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
145686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
145786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Refill the Rx ring buffers. */
145886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
1459525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		entry = mdp->dirty_rx % mdp->num_rx_ring;
146086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc = &mdp->rx_ring[entry];
1461b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		/* The size of the buffer is 16 byte boundary. */
14620029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
1463b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
146486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->rx_skbuff[entry] == NULL) {
1465dae2e9f430c46c29e3f771110094bd3da3625aa4Pradeep A. Dalvi			skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
146686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->rx_skbuff[entry] = skb;
146786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (skb == NULL)
146886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				break;	/* Better luck next round. */
1469bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz,
1470128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov				       DMA_FROM_DEVICE);
1471380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			sh_eth_set_receive_align(skb);
1472380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1473bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet			skb_checksum_none_assert(skb);
14740029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda			rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
147586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
1476525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		if (entry >= mdp->num_rx_ring - 1)
147786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			rxdesc->status |=
147871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato				cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
147986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		else
148086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			rxdesc->status |=
148171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato				cpu_to_edmac(mdp, RD_RACT | RD_RFP);
148286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
148386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
148486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Restart Rx engine if stopped. */
148586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* If we don't need to check status, don't. -KDU */
148679fba9f51755c704c0a7d7b7f0df10874dc0a744Yoshihiro Shimoda	if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
1487a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda		/* fix the values for the next receiving if RDE is set */
1488128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		if (intr_status & EESR_RDE) {
1489128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			u32 count = (sh_eth_read(ndev, RDFAR) -
1490128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov				     sh_eth_read(ndev, RDLAR)) >> 4;
1491128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov
1492128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			mdp->cur_rx = count;
1493128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			mdp->dirty_rx = count;
1494128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		}
14954a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, EDRRR_R, EDRRR);
149679fba9f51755c704c0a7d7b7f0df10874dc0a744Yoshihiro Shimoda	}
149786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
14983719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	return exceeded;
149986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
150086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
15014a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_rcv_snd_disable(struct net_device *ndev)
1502dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1503dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* disable tx and rx */
15044a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
15054a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		~(ECMR_RE | ECMR_TE), ECMR);
1506dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1507dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
15084a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_rcv_snd_enable(struct net_device *ndev)
1509dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1510dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* enable tx and rx */
15114a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) |
15124a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		(ECMR_RE | ECMR_TE), ECMR);
1513dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1514dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
151586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* error control function */
151686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_error(struct net_device *ndev, int intr_status)
151786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
151886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
151986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 felic_stat;
1520380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	u32 link_stat;
1521380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	u32 mask;
152286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
152386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_ECI) {
15244a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		felic_stat = sh_eth_read(ndev, ECSR);
15254a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, felic_stat, ECSR);	/* clear int */
152686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (felic_stat & ECSR_ICD)
1527bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.tx_carrier_errors++;
152886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (felic_stat & ECSR_LCHNG) {
152986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			/* Link Changed */
15304923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda			if (mdp->cd->no_psr || mdp->no_ether_link) {
15311e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov				goto ignore_link;
1532380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			} else {
15334a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				link_stat = (sh_eth_read(ndev, PSR));
15344923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda				if (mdp->ether_link_active_low)
15354923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda					link_stat = ~link_stat;
1536380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			}
1537128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			if (!(link_stat & PHY_ST_LINK)) {
15384a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_rcv_snd_disable(ndev);
1539128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			} else {
154086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				/* Link Up */
15414a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
1542128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov						   ~DMAC_M_ECI, EESIPR);
1543128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov				/* clear int */
15444a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_write(ndev, sh_eth_read(ndev, ECSR),
1545128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov					     ECSR);
15464a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) |
1547128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov						   DMAC_M_ECI, EESIPR);
154886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				/* enable tx and rx */
15494a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_rcv_snd_enable(ndev);
155086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			}
155186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
155286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
155386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
15541e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyovignore_link:
155586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_TWB) {
15564eb313a7a939a983c525648227b5fe0a9d41679fSergei Shtylyov		/* Unused write back interrupt */
15574eb313a7a939a983c525648227b5fe0a9d41679fSergei Shtylyov		if (intr_status & EESR_TABT) {	/* Transmit Abort int */
1558bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.tx_aborted_errors++;
1559dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			if (netif_msg_tx_err(mdp))
1560dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu				dev_err(&ndev->dev, "Transmit Abort\n");
15614eb313a7a939a983c525648227b5fe0a9d41679fSergei Shtylyov		}
156286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
156386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
156486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_RABT) {
156586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Receive Abort int */
156686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (intr_status & EESR_RFRMER) {
156786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			/* Receive Frame Overflow int */
1568bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_frame_errors++;
1569dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			if (netif_msg_rx_err(mdp))
1570dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu				dev_err(&ndev->dev, "Receive Abort\n");
157186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
157286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1573380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1574dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (intr_status & EESR_TDE) {
1575dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		/* Transmit Descriptor Empty int */
1576bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_fifo_errors++;
1577dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_tx_err(mdp))
1578dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Transmit Descriptor Empty\n");
1579dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1580dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1581dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (intr_status & EESR_TFE) {
1582dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		/* FIFO under flow */
1583bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_fifo_errors++;
1584dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_tx_err(mdp))
1585dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Transmit FIFO Under flow\n");
158686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
158786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
158886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_RDE) {
158986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Receive Descriptor Empty int */
1590bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.rx_over_errors++;
159186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1592dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_rx_err(mdp))
1593dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Receive Descriptor Empty\n");
159486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1595dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
159686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_RFE) {
159786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Receive FIFO Overflow int */
1598bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.rx_fifo_errors++;
1599dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_rx_err(mdp))
1600dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Receive FIFO Overflow\n");
1601dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1602dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1603dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) {
1604dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		/* Address Error */
1605bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_fifo_errors++;
1606dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_tx_err(mdp))
1607dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Address Error\n");
160886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1609380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1610380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
1611380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->no_ade)
1612380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		mask &= ~EESR_ADE;
1613380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (intr_status & mask) {
161486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Tx error */
16154a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		u32 edtrr = sh_eth_read(ndev, EDTRR);
1616090d560fc4723f61b561c8fceb810d4645b49b4cSergei Shtylyov
161786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* dmesg */
1618090d560fc4723f61b561c8fceb810d4645b49b4cSergei Shtylyov		dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
1619090d560fc4723f61b561c8fceb810d4645b49b4cSergei Shtylyov			intr_status, mdp->cur_tx, mdp->dirty_tx,
1620090d560fc4723f61b561c8fceb810d4645b49b4cSergei Shtylyov			(u32)ndev->state, edtrr);
162186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* dirty buffer free */
162286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		sh_eth_txfree(ndev);
162386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
162486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* SH7712 BUG */
1625c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
162686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			/* tx dma start */
1627c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda			sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
162886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
162986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* wakeup */
163086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		netif_wake_queue(ndev);
163186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
163286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
163386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
163486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic irqreturn_t sh_eth_interrupt(int irq, void *netdev)
163586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
163686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct net_device *ndev = netdev;
163786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1638380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	struct sh_eth_cpu_data *cd = mdp->cd;
16390e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu	irqreturn_t ret = IRQ_NONE;
16403719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	unsigned long intr_status, intr_enable;
164186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
164286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_lock(&mdp->lock);
164386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16443893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	/* Get interrupt status */
16454a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	intr_status = sh_eth_read(ndev, EESR);
16463893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	/* Mask it with the interrupt mask, forcing ECI interrupt to be always
16473893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 * enabled since it's the one that  comes thru regardless of the mask,
16483893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 * and we need to fully handle it in sh_eth_error() in order to quench
16493893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 * it as it doesn't get cleared by just writing 1 to the ECI bit...
16503893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 */
16513719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	intr_enable = sh_eth_read(ndev, EESIPR);
16523719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	intr_status &= intr_enable | DMAC_M_ECI;
16533719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check))
16540e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu		ret = IRQ_HANDLED;
16553719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	else
16560e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu		goto other_irq;
165786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16583719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	if (intr_status & EESR_RX_CHECK) {
16593719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		if (napi_schedule_prep(&mdp->napi)) {
16603719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			/* Mask Rx interrupts */
16613719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			sh_eth_write(ndev, intr_enable & ~EESR_RX_CHECK,
16623719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov				     EESIPR);
16633719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			__napi_schedule(&mdp->napi);
16643719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		} else {
16653719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			dev_warn(&ndev->dev,
16663719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov				 "ignoring interrupt, status 0x%08lx, mask 0x%08lx.\n",
16673719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov				 intr_status, intr_enable);
16683719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		}
16693719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	}
167086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1671b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Tx Check */
1672380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (intr_status & cd->tx_check) {
16733719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		/* Clear Tx interrupts */
16743719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		sh_eth_write(ndev, intr_status & cd->tx_check, EESR);
16753719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
167686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		sh_eth_txfree(ndev);
167786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		netif_wake_queue(ndev);
167886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
167986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16803719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	if (intr_status & cd->eesr_err_check) {
16813719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		/* Clear error interrupts */
16823719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		sh_eth_write(ndev, intr_status & cd->eesr_err_check, EESR);
16833719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
168486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		sh_eth_error(ndev, intr_status);
16853719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	}
168686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16870e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsuother_irq:
168886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_unlock(&mdp->lock);
168986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16900e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu	return ret;
169186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
169286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16933719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovstatic int sh_eth_poll(struct napi_struct *napi, int budget)
16943719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov{
16953719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	struct sh_eth_private *mdp = container_of(napi, struct sh_eth_private,
16963719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov						  napi);
16973719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	struct net_device *ndev = napi->dev;
16983719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	int quota = budget;
16993719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	unsigned long intr_status;
17003719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
17013719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	for (;;) {
17023719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		intr_status = sh_eth_read(ndev, EESR);
17033719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		if (!(intr_status & EESR_RX_CHECK))
17043719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			break;
17053719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		/* Clear Rx interrupts */
17063719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		sh_eth_write(ndev, intr_status & EESR_RX_CHECK, EESR);
17073719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
17083719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		if (sh_eth_rx(ndev, intr_status, &quota))
17093719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov			goto out;
17103719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	}
17113719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
17123719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	napi_complete(napi);
17133719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
17143719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	/* Reenable Rx interrupts */
17153719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
17163719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovout:
17173719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	return budget - quota;
17183719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov}
17193719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
172086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY state control function */
172186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_adjust_link(struct net_device *ndev)
172286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
172386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
172486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct phy_device *phydev = mdp->phydev;
172586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int new_state = 0;
172686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
17273340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov	if (phydev->link) {
172886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (phydev->duplex != mdp->duplex) {
172986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			new_state = 1;
173086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->duplex = phydev->duplex;
1731380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			if (mdp->cd->set_duplex)
1732380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				mdp->cd->set_duplex(ndev);
173386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
173486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
173586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (phydev->speed != mdp->speed) {
173686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			new_state = 1;
173786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->speed = phydev->speed;
1738380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			if (mdp->cd->set_rate)
1739380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				mdp->cd->set_rate(ndev);
174086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
17413340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov		if (!mdp->link) {
174291a5615203355bb34e0b9e68e94f27f24719a74cYoshihiro Shimoda			sh_eth_write(ndev,
1743128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov				     sh_eth_read(ndev, ECMR) & ~ECMR_TXF,
1744128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov				     ECMR);
174586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			new_state = 1;
174686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->link = phydev->link;
17471e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov			if (mdp->cd->no_psr || mdp->no_ether_link)
17481e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov				sh_eth_rcv_snd_enable(ndev);
174986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
175086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	} else if (mdp->link) {
175186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		new_state = 1;
17523340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov		mdp->link = 0;
175386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->speed = 0;
175486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->duplex = -1;
17551e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov		if (mdp->cd->no_psr || mdp->no_ether_link)
17561e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov			sh_eth_rcv_snd_disable(ndev);
175786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
175886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1759dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (new_state && netif_msg_link(mdp))
176086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		phy_print_status(phydev);
176186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
176286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
176386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY init function */
176486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_phy_init(struct net_device *ndev)
176586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
1766702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	struct device_node *np = ndev->dev.parent->of_node;
176786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
176886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct phy_device *phydev = NULL;
176986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
17703340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov	mdp->link = 0;
177186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->speed = 0;
177286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->duplex = -1;
177386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
177486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Try connect to PHY */
1775702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	if (np) {
1776702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		struct device_node *pn;
1777702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks
1778702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		pn = of_parse_phandle(np, "phy-handle", 0);
1779702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		phydev = of_phy_connect(ndev, pn,
1780702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks					sh_eth_adjust_link, 0,
1781702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks					mdp->phy_interface);
1782702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks
1783702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		if (!phydev)
1784702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks			phydev = ERR_PTR(-ENOENT);
1785702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	} else {
1786702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		char phy_id[MII_BUS_ID_SIZE + 3];
1787702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks
1788702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
1789702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks			 mdp->mii_bus->id, mdp->phy_id);
1790702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks
1791702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
1792702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks				     mdp->phy_interface);
1793702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	}
1794702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks
179586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (IS_ERR(phydev)) {
1796702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		dev_err(&ndev->dev, "failed to connect PHY\n");
179786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return PTR_ERR(phydev);
179886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1799380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
180018be099badcfc4a12f058addc55c4270d5a8bec8Sergei Shtylyov	dev_info(&ndev->dev, "attached PHY %d (IRQ %d) to driver %s\n",
180118be099badcfc4a12f058addc55c4270d5a8bec8Sergei Shtylyov		 phydev->addr, phydev->irq, phydev->drv->name);
180286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
180386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->phydev = phydev;
180486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
180586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
180686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
180786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
180886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY control start function */
180986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_phy_start(struct net_device *ndev)
181086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
181186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
181286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret;
181386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
181486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = sh_eth_phy_init(ndev);
181586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
181686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return ret;
181786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
181886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	phy_start(mdp->phydev);
181986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
182086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
182186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
182286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1823dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_get_settings(struct net_device *ndev,
1824128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			       struct ethtool_cmd *ecmd)
1825dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1826dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1827dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	unsigned long flags;
1828dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int ret;
1829dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1830dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
1831dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	ret = phy_ethtool_gset(mdp->phydev, ecmd);
1832dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
1833dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1834dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return ret;
1835dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1836dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1837dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_set_settings(struct net_device *ndev,
1838128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			       struct ethtool_cmd *ecmd)
1839dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1840dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1841dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	unsigned long flags;
1842dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int ret;
1843dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1844dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
1845dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1846dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* disable tx and rx */
18474a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_rcv_snd_disable(ndev);
1848dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1849dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	ret = phy_ethtool_sset(mdp->phydev, ecmd);
1850dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (ret)
1851dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		goto error_exit;
1852dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1853dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (ecmd->duplex == DUPLEX_FULL)
1854dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		mdp->duplex = 1;
1855dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	else
1856dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		mdp->duplex = 0;
1857dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1858dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (mdp->cd->set_duplex)
1859dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		mdp->cd->set_duplex(ndev);
1860dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1861dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsuerror_exit:
1862dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	mdelay(1);
1863dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1864dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* enable tx and rx */
18654a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_rcv_snd_enable(ndev);
1866dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1867dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
1868dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1869dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return ret;
1870dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1871dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1872dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_nway_reset(struct net_device *ndev)
1873dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1874dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1875dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	unsigned long flags;
1876dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int ret;
1877dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1878dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
1879dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	ret = phy_start_aneg(mdp->phydev);
1880dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
1881dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1882dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return ret;
1883dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1884dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1885dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic u32 sh_eth_get_msglevel(struct net_device *ndev)
1886dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1887dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1888dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return mdp->msg_enable;
1889dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1890dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1891dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_set_msglevel(struct net_device *ndev, u32 value)
1892dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1893dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1894dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	mdp->msg_enable = value;
1895dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1896dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1897dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic const char sh_eth_gstrings_stats[][ETH_GSTRING_LEN] = {
1898dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	"rx_current", "tx_current",
1899dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	"rx_dirty", "tx_dirty",
1900dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu};
1901dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#define SH_ETH_STATS_LEN  ARRAY_SIZE(sh_eth_gstrings_stats)
1902dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1903dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_get_sset_count(struct net_device *netdev, int sset)
1904dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1905dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	switch (sset) {
1906dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	case ETH_SS_STATS:
1907dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		return SH_ETH_STATS_LEN;
1908dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	default:
1909dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		return -EOPNOTSUPP;
1910dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1911dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1912dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1913dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_get_ethtool_stats(struct net_device *ndev,
1914128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov				     struct ethtool_stats *stats, u64 *data)
1915dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1916dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1917dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int i = 0;
1918dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1919dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* device-specific stats */
1920dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->cur_rx;
1921dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->cur_tx;
1922dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->dirty_rx;
1923dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->dirty_tx;
1924dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1925dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1926dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
1927dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1928dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	switch (stringset) {
1929dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	case ETH_SS_STATS:
1930dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		memcpy(data, *sh_eth_gstrings_stats,
1931128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		       sizeof(sh_eth_gstrings_stats));
1932dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		break;
1933dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1934dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1935dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1936525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic void sh_eth_get_ringparam(struct net_device *ndev,
1937525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda				 struct ethtool_ringparam *ring)
1938525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda{
1939525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
1940525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1941525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->rx_max_pending = RX_RING_MAX;
1942525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->tx_max_pending = TX_RING_MAX;
1943525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->rx_pending = mdp->num_rx_ring;
1944525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->tx_pending = mdp->num_tx_ring;
1945525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda}
1946525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1947525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic int sh_eth_set_ringparam(struct net_device *ndev,
1948525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda				struct ethtool_ringparam *ring)
1949525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda{
1950525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
1951525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int ret;
1952525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1953525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ring->tx_pending > TX_RING_MAX ||
1954525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	    ring->rx_pending > RX_RING_MAX ||
1955525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	    ring->tx_pending < TX_RING_MIN ||
1956525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	    ring->rx_pending < RX_RING_MIN)
1957525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return -EINVAL;
1958525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ring->rx_mini_pending || ring->rx_jumbo_pending)
1959525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return -EINVAL;
1960525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1961525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (netif_running(ndev)) {
1962525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		netif_tx_disable(ndev);
1963525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Disable interrupts by clearing the interrupt mask. */
1964525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, 0x0000, EESIPR);
1965525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Stop the chip's Tx and Rx processes. */
1966525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, 0, EDTRR);
1967525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, 0, EDRRR);
1968525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		synchronize_irq(ndev->irq);
1969525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1970525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1971525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	/* Free all the skbuffs in the Rx queue. */
1972525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	sh_eth_ring_free(ndev);
1973525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	/* Free DMA buffer */
1974525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	sh_eth_free_dma_buffer(mdp);
1975525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1976525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	/* Set new parameters */
1977525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_rx_ring = ring->rx_pending;
1978525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_tx_ring = ring->tx_pending;
1979525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1980525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ret = sh_eth_ring_init(ndev);
1981525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ret < 0) {
1982525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		dev_err(&ndev->dev, "%s: sh_eth_ring_init failed.\n", __func__);
1983525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return ret;
1984525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1985525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ret = sh_eth_dev_init(ndev, false);
1986525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ret < 0) {
1987525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		dev_err(&ndev->dev, "%s: sh_eth_dev_init failed.\n", __func__);
1988525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return ret;
1989525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1990525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1991525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (netif_running(ndev)) {
1992525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
1993525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Setting the Rx mode will start the Rx process. */
1994525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, EDRRR_R, EDRRR);
1995525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		netif_wake_queue(ndev);
1996525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1997525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1998525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	return 0;
1999525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda}
2000525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
20019b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemmingerstatic const struct ethtool_ops sh_eth_ethtool_ops = {
2002dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_settings	= sh_eth_get_settings,
2003dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.set_settings	= sh_eth_set_settings,
20049b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemminger	.nway_reset	= sh_eth_nway_reset,
2005dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_msglevel	= sh_eth_get_msglevel,
2006dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.set_msglevel	= sh_eth_set_msglevel,
20079b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemminger	.get_link	= ethtool_op_get_link,
2008dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_strings	= sh_eth_get_strings,
2009dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_ethtool_stats  = sh_eth_get_ethtool_stats,
2010dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_sset_count     = sh_eth_get_sset_count,
2011525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	.get_ringparam	= sh_eth_get_ringparam,
2012525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	.set_ringparam	= sh_eth_set_ringparam,
2013dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu};
2014dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
201586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* network device open function */
201686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_open(struct net_device *ndev)
201786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
201886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret = 0;
201986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
202086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2021bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_get_sync(&mdp->pdev->dev);
2022bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2023d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov	napi_enable(&mdp->napi);
2024d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov
2025a0607fd3a25ba1848a63a0d925e36d914735ab47Joe Perches	ret = request_irq(ndev->irq, sh_eth_interrupt,
20265b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu			  mdp->cd->irq_flags, ndev->name, ndev);
202786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret) {
2028380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		dev_err(&ndev->dev, "Can not assign IRQ number\n");
2029d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov		goto out_napi_off;
203086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
203186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
203286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Descriptor set */
203386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = sh_eth_ring_init(ndev);
203486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
203586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_irq;
203686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
203786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* device init */
2038525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ret = sh_eth_dev_init(ndev, true);
203986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
204086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_irq;
204186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
204286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PHY control start*/
204386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = sh_eth_phy_start(ndev);
204486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
204586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_irq;
204686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
204786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
204886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
204986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_free_irq:
205086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_irq(ndev->irq, ndev);
2051d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyovout_napi_off:
2052d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov	napi_disable(&mdp->napi);
2053bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_put_sync(&mdp->pdev->dev);
205486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
205586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
205686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
205786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Timeout function */
205886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_tx_timeout(struct net_device *ndev)
205986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
206086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
206186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_rxdesc *rxdesc;
206286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int i;
206386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
206486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	netif_stop_queue(ndev);
206586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2066128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	if (netif_msg_timer(mdp)) {
2067128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x, resetting...\n",
2068128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov			ndev->name, (int)sh_eth_read(ndev, EESR));
2069128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	}
207086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
207186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* tx_errors count up */
2072bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.tx_errors++;
207386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
207486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free all the skbuffs in the Rx queue. */
2075525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_rx_ring; i++) {
207686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc = &mdp->rx_ring[i];
207786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc->status = 0;
207886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc->addr = 0xBADF00D0;
207986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->rx_skbuff[i])
208086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			dev_kfree_skb(mdp->rx_skbuff[i]);
208186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->rx_skbuff[i] = NULL;
208286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
2083525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_tx_ring; i++) {
208486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->tx_skbuff[i])
208586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			dev_kfree_skb(mdp->tx_skbuff[i]);
208686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->tx_skbuff[i] = NULL;
208786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
208886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
208986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* device init */
2090525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	sh_eth_dev_init(ndev, true);
209186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
209286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
209386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Packet transmit function */
209486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
209586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
209686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
209786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_txdesc *txdesc;
209886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 entry;
2099fb5e2f9b9410a4362897d12dc1ed4f7cec1b0d45Nobuhiro Iwamatsu	unsigned long flags;
210086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
210186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
2102525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
210386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (!sh_eth_txfree(ndev)) {
2104dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			if (netif_msg_tx_queued(mdp))
2105dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu				dev_warn(&ndev->dev, "TxFD exhausted.\n");
210686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			netif_stop_queue(ndev);
210786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			spin_unlock_irqrestore(&mdp->lock, flags);
21085b548140225c6bbbbd560551dd1048b2c0ce58bePatrick McHardy			return NETDEV_TX_BUSY;
210986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
211086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
211186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
211286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2113525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	entry = mdp->cur_tx % mdp->num_tx_ring;
211486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->tx_skbuff[entry] = skb;
211586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	txdesc = &mdp->tx_ring[entry];
211686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* soft swap. */
2117380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!mdp->cd->hw_swap)
2118380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
2119380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				 skb->len + 2);
212031fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda	txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len,
212131fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda				      DMA_TO_DEVICE);
2122730c8c69bc8d4640336885e20e719b0842d0fcb2Sergei Shtylyov	if (skb->len < ETH_ZLEN)
2123730c8c69bc8d4640336885e20e719b0842d0fcb2Sergei Shtylyov		txdesc->buffer_length = ETH_ZLEN;
212486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
212586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc->buffer_length = skb->len;
212686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2127525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (entry >= mdp->num_tx_ring - 1)
212871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
212986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
213071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
213186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
213286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->cur_tx++;
213386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2134c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
2135c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
2136b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
21376ed106549d17474ca17a16057f4c0ed4eba5a7caPatrick McHardy	return NETDEV_TX_OK;
213886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
213986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
214086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* device close function */
214186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_close(struct net_device *ndev)
214286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
214386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
214486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
214586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	netif_stop_queue(ndev);
214686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
214786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Disable interrupts by clearing the interrupt mask. */
21484a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0x0000, EESIPR);
214986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
215086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Stop the chip's Tx and Rx processes. */
21514a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, EDTRR);
21524a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, EDRRR);
215386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
215486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PHY Disconnect */
215586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (mdp->phydev) {
215686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		phy_stop(mdp->phydev);
215786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		phy_disconnect(mdp->phydev);
215886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
215986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
216086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_irq(ndev->irq, ndev);
216186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2162d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov	napi_disable(&mdp->napi);
2163d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov
216486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free all the skbuffs in the Rx queue. */
216586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	sh_eth_ring_free(ndev);
216686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
216786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* free DMA buffer */
216891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	sh_eth_free_dma_buffer(mdp);
216986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2170bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_put_sync(&mdp->pdev->dev);
2171bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
217286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
217386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
217486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
217586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
217686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
217786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
217886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2179db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	if (sh_eth_is_rz_fast_ether(mdp))
2180db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		return &ndev->stats;
2181db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
2182bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_get_sync(&mdp->pdev->dev);
2183bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2184bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR);
21854a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, TROCR);	/* (write clear) */
2186bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.collisions += sh_eth_read(ndev, CDCR);
21874a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, CDCR);	/* (write clear) */
2188bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
21894a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, LCCR);	/* (write clear) */
2190c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (sh_eth_is_gether(mdp)) {
2191bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
2192c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, 0, CERCR);	/* (write clear) */
2193bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
2194c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, 0, CEECR);	/* (write clear) */
2195c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	} else {
2196bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
2197c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, 0, CNDCR);	/* (write clear) */
2198c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	}
2199bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_put_sync(&mdp->pdev->dev);
2200bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2201bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	return &ndev->stats;
220286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
220386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2204bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet/* ioctl to device function */
2205128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyovstatic int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
220686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
220786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
220886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct phy_device *phydev = mdp->phydev;
220986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
221086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!netif_running(ndev))
221186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return -EINVAL;
221286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
221386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!phydev)
221486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return -ENODEV;
221586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
221628b041139e344ecd0f144d6205b004ae354cfa1eRichard Cochran	return phy_mii_ioctl(phydev, rq, cmd);
221786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
221886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
22196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda/* For TSU_POSTn. Please refer to the manual about this (strange) bitfields */
22206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void *sh_eth_tsu_get_post_reg_offset(struct sh_eth_private *mdp,
22216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					    int entry)
22226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return sh_eth_tsu_get_offset(mdp, TSU_POST1) + (entry / 8 * 4);
22246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic u32 sh_eth_tsu_get_post_mask(int entry)
22276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0x0f << (28 - ((entry % 8) * 4));
22296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic u32 sh_eth_tsu_get_post_bit(struct sh_eth_private *mdp, int entry)
22326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return (0x08 >> (mdp->port << 1)) << (28 - ((entry % 8) * 4));
22346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_enable_cam_entry_post(struct net_device *ndev,
22376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					     int entry)
22386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
22406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 tmp;
22416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset;
22426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry);
22446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	tmp = ioread32(reg_offset);
22456743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(tmp | sh_eth_tsu_get_post_bit(mdp, entry), reg_offset);
22466743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22476743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic bool sh_eth_tsu_disable_cam_entry_post(struct net_device *ndev,
22496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					      int entry)
22506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22516743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
22526743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 post_mask, ref_mask, tmp;
22536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset;
22546743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry);
22566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	post_mask = sh_eth_tsu_get_post_mask(entry);
22576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	ref_mask = sh_eth_tsu_get_post_bit(mdp, entry) & ~post_mask;
22586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	tmp = ioread32(reg_offset);
22606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(tmp & ~post_mask, reg_offset);
22616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	/* If other port enables, the function returns "true" */
22636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return tmp & ref_mask;
22646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_busy(struct net_device *ndev)
22676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int timeout = SH_ETH_TSU_TIMEOUT_MS * 100;
22696743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
22706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	while ((sh_eth_tsu_read(mdp, TSU_ADSBSY) & TSU_ADSBSY_0)) {
22726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		udelay(10);
22736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		timeout--;
22746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (timeout <= 0) {
22756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			dev_err(&ndev->dev, "%s: timeout\n", __func__);
22766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return -ETIMEDOUT;
22776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		}
22786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
22796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
22816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_write_entry(struct net_device *ndev, void *reg,
22846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				  const u8 *addr)
22856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 val;
22876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3];
22896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(val, reg);
22906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (sh_eth_tsu_busy(ndev) < 0)
22916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return -EBUSY;
22926743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = addr[4] << 8 | addr[5];
22946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(val, reg + 4);
22956743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (sh_eth_tsu_busy(ndev) < 0)
22966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return -EBUSY;
22976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
22996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23016743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_read_entry(void *reg, u8 *addr)
23026743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23036743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 val;
23046743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23056743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = ioread32(reg);
23066743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[0] = (val >> 24) & 0xff;
23076743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[1] = (val >> 16) & 0xff;
23086743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[2] = (val >> 8) & 0xff;
23096743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[3] = val & 0xff;
23106743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = ioread32(reg + 4);
23116743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[4] = (val >> 8) & 0xff;
23126743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[5] = val & 0xff;
23136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23156743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_find_entry(struct net_device *ndev, const u8 *addr)
23176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
23206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i;
23216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 c_addr[ETH_ALEN];
23226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) {
23246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_read_entry(reg_offset, c_addr);
2325c4bde29cb0f3a520e3dd666e523f9a576a47a47adingtianhong		if (ether_addr_equal(addr, c_addr))
23266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return i;
23276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
23286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return -ENOENT;
23306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_find_empty(struct net_device *ndev)
23336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 blank[ETH_ALEN];
23356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int entry;
23366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	memset(blank, 0, sizeof(blank));
23386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	entry = sh_eth_tsu_find_entry(ndev, blank);
23396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return (entry < 0) ? -ENOMEM : entry;
23406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_disable_cam_entry_table(struct net_device *ndev,
23436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					      int entry)
23446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23456743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23466743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
23476743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int ret;
23486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 blank[ETH_ALEN];
23496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) &
23516743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			 ~(1 << (31 - entry)), TSU_TEN);
23526743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	memset(blank, 0, sizeof(blank));
23546743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	ret = sh_eth_tsu_write_entry(ndev, reg_offset + entry * 8, blank);
23556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (ret < 0)
23566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return ret;
23576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
23586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_add_entry(struct net_device *ndev, const u8 *addr)
23616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
23646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i, ret;
23656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (!mdp->cd->tsu)
23676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return 0;
23686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23696743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	i = sh_eth_tsu_find_entry(ndev, addr);
23706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (i < 0) {
23716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* No entry found, create one */
23726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		i = sh_eth_tsu_find_empty(ndev);
23736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (i < 0)
23746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return -ENOMEM;
23756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ret = sh_eth_tsu_write_entry(ndev, reg_offset + i * 8, addr);
23766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (ret < 0)
23776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return ret;
23786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Enable the entry */
23806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) |
23816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				 (1 << (31 - i)), TSU_TEN);
23826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
23836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	/* Entry found or created, enable POST */
23856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	sh_eth_tsu_enable_cam_entry_post(ndev, i);
23866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
23886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_del_entry(struct net_device *ndev, const u8 *addr)
23916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23926743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i, ret;
23946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23956743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (!mdp->cd->tsu)
23966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return 0;
23976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	i = sh_eth_tsu_find_entry(ndev, addr);
23996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (i) {
24006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Entry found */
24016743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (sh_eth_tsu_disable_cam_entry_post(ndev, i))
24026743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			goto done;
24036743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24046743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Disable the entry if both ports was disabled */
24056743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ret = sh_eth_tsu_disable_cam_entry_table(ndev, i);
24066743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (ret < 0)
24076743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return ret;
24086743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
24096743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodadone:
24106743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
24116743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
24126743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_purge_all(struct net_device *ndev)
24146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
24156743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
24166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i, ret;
24176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
24196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return 0;
24206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) {
24226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (sh_eth_tsu_disable_cam_entry_post(ndev, i))
24236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			continue;
24246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Disable the entry if both ports was disabled */
24266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ret = sh_eth_tsu_disable_cam_entry_table(ndev, i);
24276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (ret < 0)
24286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return ret;
24296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
24306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
24326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
24336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_purge_mcast(struct net_device *ndev)
24356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
24366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
24376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 addr[ETH_ALEN];
24386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
24396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i;
24406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
24426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return;
24436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) {
24456743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_read_entry(reg_offset, addr);
24466743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (is_multicast_ether_addr(addr))
24476743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			sh_eth_tsu_del_entry(ndev, addr);
24486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
24496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
24506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
245186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Multicast reception directions set */
245286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_set_multicast_list(struct net_device *ndev)
245386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
24546743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
24556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 ecmr_bits;
24566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int mcast_all = 0;
24576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	unsigned long flags;
24586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	spin_lock_irqsave(&mdp->lock, flags);
2460128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	/* Initial condition is MCT = 1, PRM = 0.
24616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	 * Depending on ndev->flags, set PRM or clear MCT
24626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	 */
24636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT;
24646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (!(ndev->flags & IFF_MULTICAST)) {
24666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_purge_mcast(ndev);
24676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		mcast_all = 1;
24686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
24696743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (ndev->flags & IFF_ALLMULTI) {
24706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_purge_mcast(ndev);
24716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ecmr_bits &= ~ECMR_MCT;
24726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		mcast_all = 1;
24736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
24746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
247586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ndev->flags & IFF_PROMISC) {
24766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_purge_all(ndev);
24776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ecmr_bits = (ecmr_bits & ~ECMR_MCT) | ECMR_PRM;
24786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	} else if (mdp->cd->tsu) {
24796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		struct netdev_hw_addr *ha;
24806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		netdev_for_each_mc_addr(ha, ndev) {
24816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			if (mcast_all && is_multicast_ether_addr(ha->addr))
24826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				continue;
24836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			if (sh_eth_tsu_add_entry(ndev, ha->addr) < 0) {
24856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				if (!mcast_all) {
24866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					sh_eth_tsu_purge_mcast(ndev);
24876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					ecmr_bits &= ~ECMR_MCT;
24886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					mcast_all = 1;
24896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				}
24906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			}
24916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		}
249286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	} else {
249386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Normal, unicast/broadcast-only mode. */
24946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT;
249586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
24966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	/* update the ethernet mode */
24986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	sh_eth_write(ndev, ecmr_bits, ECMR);
24996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
25006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	spin_unlock_irqrestore(&mdp->lock, flags);
250186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
250271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
250371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimodastatic int sh_eth_get_vtag_index(struct sh_eth_private *mdp)
250471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{
250571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (!mdp->port)
250671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return TSU_VTAG0;
250771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	else
250871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return TSU_VTAG1;
250971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda}
251071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
251180d5c3689b886308247da295a228a54df49a44f6Patrick McHardystatic int sh_eth_vlan_rx_add_vid(struct net_device *ndev,
251280d5c3689b886308247da295a228a54df49a44f6Patrick McHardy				  __be16 proto, u16 vid)
251371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{
251471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
251571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	int vtag_reg_index = sh_eth_get_vtag_index(mdp);
251671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
251771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
251871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return -EPERM;
251971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
252071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	/* No filtering if vid = 0 */
252171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (!vid)
252271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return 0;
252371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
252471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	mdp->vlan_num_ids++;
252571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
2526128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	/* The controller has one VLAN tag HW filter. So, if the filter is
252771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	 * already enabled, the driver disables it and the filte
252871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	 */
252971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (mdp->vlan_num_ids > 1) {
253071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		/* disable VLAN filter */
253171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, vtag_reg_index);
253271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return 0;
253371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	}
253471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
253571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	sh_eth_tsu_write(mdp, TSU_VTAG_ENABLE | (vid & TSU_VTAG_VID_MASK),
253671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda			 vtag_reg_index);
253771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
253871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	return 0;
253971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda}
254071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
254180d5c3689b886308247da295a228a54df49a44f6Patrick McHardystatic int sh_eth_vlan_rx_kill_vid(struct net_device *ndev,
254280d5c3689b886308247da295a228a54df49a44f6Patrick McHardy				   __be16 proto, u16 vid)
254371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{
254471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
254571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	int vtag_reg_index = sh_eth_get_vtag_index(mdp);
254671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
254771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
254871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return -EPERM;
254971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
255071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	/* No filtering if vid = 0 */
255171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (!vid)
255271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return 0;
255371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
255471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	mdp->vlan_num_ids--;
255571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, vtag_reg_index);
255671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
255771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	return 0;
255871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda}
255986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
256086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* SuperH's TSU register init function */
25614a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_tsu_init(struct sh_eth_private *mdp)
256286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
2563db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	if (sh_eth_is_rz_fast_ether(mdp)) {
2564db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */
2565db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		return;
2566db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	}
2567db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman
25684a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWEN0);	/* Disable forward(0->1) */
25694a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWEN1);	/* Disable forward(1->0) */
25704a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FCM);	/* forward fifo 3k-3k */
25714a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL0);
25724a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL1);
25734a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_PRISL0);
25744a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_PRISL1);
25754a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
25764a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
25774a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
2578c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (sh_eth_is_gether(mdp)) {
2579c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAG0);	/* Disable QTAG(0->1) */
2580c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAG1);	/* Disable QTAG(1->0) */
2581c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	} else {
2582c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);	/* Disable QTAG(0->1) */
2583c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);	/* Disable QTAG(1->0) */
2584c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	}
25854a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWSR);	/* all interrupt status clear */
25864a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWINMK);	/* Disable all interrupt */
25874a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_TEN);	/* Disable all CAM entry */
25884a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST1);	/* Disable CAM entry [ 0- 7] */
25894a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST2);	/* Disable CAM entry [ 8-15] */
25904a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST3);	/* Disable CAM entry [16-23] */
25914a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST4);	/* Disable CAM entry [24-31] */
259286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
259386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
259486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDIO bus release function */
259586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_mdio_release(struct net_device *ndev)
259686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
259786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
259886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
259986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* unregister mdio bus */
260086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdiobus_unregister(bus);
260186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
260286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* remove mdio bus info from net_device */
260386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	dev_set_drvdata(&ndev->dev, NULL);
260486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
260586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* free bitbang info */
260686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_mdio_bitbang(bus);
260786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
260886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
260986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
261086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
261186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDIO bus init function */
2612b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimodastatic int sh_mdio_init(struct net_device *ndev, int id,
2613b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda			struct sh_eth_plat_data *pd)
261486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
261586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret, i;
261686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang;
261786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
261886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
261986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* create bit control struct for PHY */
2620d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	bitbang = devm_kzalloc(&ndev->dev, sizeof(struct bb_info),
2621d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov			       GFP_KERNEL);
262286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!bitbang) {
262386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
262486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out;
262586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
262686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
262786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* bitbang init */
2628ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	bitbang->addr = mdp->addr + mdp->reg_offset[PIR];
2629b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	bitbang->set_gate = pd->set_mdio_gate;
2630dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mdi_msk = PIR_MDI;
2631dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mdo_msk = PIR_MDO;
2632dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mmd_msk = PIR_MMD;
2633dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mdc_msk = PIR_MDC;
263486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	bitbang->ctrl.ops = &bb_ops;
263586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2636c2e07b3a9ced33dd92597201be3931be8ea57ed6Stefan Weil	/* MII controller setting */
263786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
263886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->mii_bus) {
263986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
2640d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		goto out;
264186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
264286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
264386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Hook up MII support for ethtool */
264486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->mii_bus->name = "sh_mii";
264518ee49ddb0d242ed1d0e273038d5e4f6de7379d3Lennert Buytenhek	mdp->mii_bus->parent = &ndev->dev;
26465278fb547076ad6768d16c8b4df45c086470c163Florian Fainelli	snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
2647128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		 mdp->pdev->name, id);
264886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
264986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PHY IRQ */
2650d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	mdp->mii_bus->irq = devm_kzalloc(&ndev->dev,
2651d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov					 sizeof(int) * PHY_MAX_ADDR,
2652d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov					 GFP_KERNEL);
265386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->mii_bus->irq) {
265486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
265586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_bus;
265686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
265786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
26588f6352f2b5aecd4b0af5ef31361af1146f9528d6YOSHIFUJI Hideaki / 吉藤英明	/* register mdio bus */
2659702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	if (ndev->dev.parent->of_node) {
2660702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		ret = of_mdiobus_register(mdp->mii_bus,
2661702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks					  ndev->dev.parent->of_node);
2662702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	} else {
2663702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		for (i = 0; i < PHY_MAX_ADDR; i++)
2664702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks			mdp->mii_bus->irq[i] = PHY_POLL;
2665702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		if (pd->phy_irq > 0)
2666702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks			mdp->mii_bus->irq[pd->phy] = pd->phy_irq;
2667702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks
2668702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		ret = mdiobus_register(mdp->mii_bus);
2669702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	}
2670702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks
267186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
2672d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		goto out_free_bus;
267386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
267486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	dev_set_drvdata(&ndev->dev, mdp->mii_bus);
267586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
267686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
267786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
267886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_free_bus:
2679298cf9beb9679522de995e249eccbd82f7c51999Lennert Buytenhek	free_mdio_bitbang(mdp->mii_bus);
268086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
268186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout:
268286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
268386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
268486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
26854a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic const u16 *sh_eth_get_register_offset(int register_type)
26864a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda{
26874a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	const u16 *reg_offset = NULL;
26884a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda
26894a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	switch (register_type) {
26904a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	case SH_ETH_REG_GIGABIT:
26914a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		reg_offset = sh_eth_offset_gigabit;
26924a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
2693db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	case SH_ETH_REG_FAST_RZ:
2694db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		reg_offset = sh_eth_offset_fast_rz;
2695db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman		break;
2696a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	case SH_ETH_REG_FAST_RCAR:
2697a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		reg_offset = sh_eth_offset_fast_rcar;
2698a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
26994a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	case SH_ETH_REG_FAST_SH4:
27004a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		reg_offset = sh_eth_offset_fast_sh4;
27014a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
27024a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	case SH_ETH_REG_FAST_SH3_SH2:
27034a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		reg_offset = sh_eth_offset_fast_sh3_sh2;
27044a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
27054a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	default:
27064a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
27074a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	}
27084a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda
27094a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	return reg_offset;
27104a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda}
27114a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda
27128f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyovstatic const struct net_device_ops sh_eth_netdev_ops = {
2713ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_open		= sh_eth_open,
2714ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_stop		= sh_eth_close,
2715ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_start_xmit		= sh_eth_start_xmit,
2716ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_get_stats		= sh_eth_get_stats,
2717ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_tx_timeout		= sh_eth_tx_timeout,
2718ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_do_ioctl		= sh_eth_do_ioctl,
2719ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_validate_addr	= eth_validate_addr,
2720ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_set_mac_address	= eth_mac_addr,
2721ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_change_mtu		= eth_change_mtu,
2722ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov};
2723ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov
27248f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyovstatic const struct net_device_ops sh_eth_netdev_ops_tsu = {
27258f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_open		= sh_eth_open,
27268f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_stop		= sh_eth_close,
27278f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_start_xmit		= sh_eth_start_xmit,
27288f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_get_stats		= sh_eth_get_stats,
27298f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_set_rx_mode	= sh_eth_set_multicast_list,
27308f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_vlan_rx_add_vid	= sh_eth_vlan_rx_add_vid,
27318f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_vlan_rx_kill_vid	= sh_eth_vlan_rx_kill_vid,
27328f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_tx_timeout		= sh_eth_tx_timeout,
27338f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_do_ioctl		= sh_eth_do_ioctl,
27348f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_validate_addr	= eth_validate_addr,
27358f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_set_mac_address	= eth_mac_addr,
27368f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	.ndo_change_mtu		= eth_change_mtu,
27378f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov};
27388f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov
2739b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#ifdef CONFIG_OF
2740b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyovstatic struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev)
2741b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov{
2742b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	struct device_node *np = dev->of_node;
2743b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	struct sh_eth_plat_data *pdata;
2744b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	const char *mac_addr;
2745b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
2746b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
2747b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	if (!pdata)
2748b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		return NULL;
2749b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
2750b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	pdata->phy_interface = of_get_phy_mode(np);
2751b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
2752b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	mac_addr = of_get_mac_address(np);
2753b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	if (mac_addr)
2754b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		memcpy(pdata->mac_addr, mac_addr, ETH_ALEN);
2755b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
2756b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	pdata->no_ether_link =
2757b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		of_property_read_bool(np, "renesas,no-ether-link");
2758b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	pdata->ether_link_active_low =
2759b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		of_property_read_bool(np, "renesas,ether-link-active-low");
2760b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
2761b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	return pdata;
2762b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov}
2763b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
2764b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyovstatic const struct of_device_id sh_eth_match_table[] = {
2765b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	{ .compatible = "renesas,gether-r8a7740", .data = &r8a7740_data },
2766b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	{ .compatible = "renesas,ether-r8a7778", .data = &r8a777x_data },
2767b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	{ .compatible = "renesas,ether-r8a7779", .data = &r8a777x_data },
2768b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	{ .compatible = "renesas,ether-r8a7790", .data = &r8a779x_data },
2769b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	{ .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data },
2770b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	{ .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data },
2771b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	{ }
2772b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov};
2773b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei ShtylyovMODULE_DEVICE_TABLE(of, sh_eth_match_table);
2774b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#else
2775b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyovstatic inline struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev)
2776b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov{
2777b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	return NULL;
2778b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov}
2779b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#endif
2780b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
278186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_drv_probe(struct platform_device *pdev)
278286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
27839c38657cfcb739b7dc4ce9065a85b4f0c195bef8Kuninori Morimoto	int ret, devno = 0;
278486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct resource *res;
278586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct net_device *ndev = NULL;
2786ec0d75518cb06261f1823fa2713fe52b9b26455eKuninori Morimoto	struct sh_eth_private *mdp = NULL;
27870b76b86235296efeabe49f79a3e70336cff9664eJingoo Han	struct sh_eth_plat_data *pd = dev_get_platdata(&pdev->dev);
2788afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov	const struct platform_device_id *id = platform_get_device_id(pdev);
278986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
279086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* get base addr */
279186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
279286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (unlikely(res == NULL)) {
279386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		dev_err(&pdev->dev, "invalid resource\n");
279486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -EINVAL;
279586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out;
279686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
279786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
279886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev = alloc_etherdev(sizeof(struct sh_eth_private));
279986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!ndev) {
280086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
280186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out;
280286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
280386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
280486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* The sh Ether-specific entries in the device structure. */
280586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev->base_addr = res->start;
280686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	devno = pdev->id;
280786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (devno < 0)
280886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		devno = 0;
280986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
281086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev->dma = -1;
2811cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin	ret = platform_get_irq(pdev, 0);
2812cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin	if (ret < 0) {
281386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENODEV;
281486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_release;
281586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
2816cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin	ndev->irq = ret;
281786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
281886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	SET_NETDEV_DEV(ndev, &pdev->dev);
281986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
282086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp = netdev_priv(ndev);
2821525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_tx_ring = TX_RING_SIZE;
2822525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_rx_ring = RX_RING_SIZE;
2823d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	mdp->addr = devm_ioremap_resource(&pdev->dev, res);
2824d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	if (IS_ERR(mdp->addr)) {
2825d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		ret = PTR_ERR(mdp->addr);
2826ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		goto out_release;
2827ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	}
2828ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda
282986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_lock_init(&mdp->lock);
2830bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	mdp->pdev = pdev;
2831bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_enable(&pdev->dev);
2832bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_resume(&pdev->dev);
283386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2834b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	if (pdev->dev.of_node)
2835b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		pd = sh_eth_parse_dt(&pdev->dev);
28363b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov	if (!pd) {
28373b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov		dev_err(&pdev->dev, "no platform data\n");
28383b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov		ret = -EINVAL;
28393b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov		goto out_release;
28403b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov	}
28413b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov
284286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* get PHY ID */
284371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	mdp->phy_id = pd->phy;
2844e47c90523484518aac30498150e427d824ace705Yoshihiro Shimoda	mdp->phy_interface = pd->phy_interface;
284571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	/* EDMAC endian */
284671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	mdp->edmac_endian = pd->edmac_endian;
28474923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda	mdp->no_ether_link = pd->no_ether_link;
28484923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda	mdp->ether_link_active_low = pd->ether_link_active_low;
284986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2850380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	/* set cpu data */
2851b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	if (id) {
2852b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		mdp->cd = (struct sh_eth_cpu_data *)id->driver_data;
2853b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	} else	{
2854b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		const struct of_device_id *match;
2855b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov
2856b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		match = of_match_device(of_match_ptr(sh_eth_match_table),
2857b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov					&pdev->dev);
2858b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		mdp->cd = (struct sh_eth_cpu_data *)match->data;
2859b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov	}
2860a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov	mdp->reg_offset = sh_eth_get_register_offset(mdp->cd->register_type);
2861264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov	if (!mdp->reg_offset) {
2862264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov		dev_err(&pdev->dev, "Unknown register type (%d)\n",
2863264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov			mdp->cd->register_type);
2864264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov		ret = -EINVAL;
2865264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov		goto out_release;
2866264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov	}
2867380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	sh_eth_set_default_cpu_data(mdp->cd);
2868380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
286986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* set function */
28708f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	if (mdp->cd->tsu)
28718f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov		ndev->netdev_ops = &sh_eth_netdev_ops_tsu;
28728f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov	else
28738f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov		ndev->netdev_ops = &sh_eth_netdev_ops;
2874dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
287586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev->watchdog_timeo = TX_TIMEOUT;
287686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2877dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* debug message level */
2878dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
287986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
288086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* read and set MAC address */
2881748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	read_mac_address(ndev, pd->mac_addr);
2882ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov	if (!is_valid_ether_addr(ndev->dev_addr)) {
2883ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov		dev_warn(&pdev->dev,
2884ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov			 "no valid MAC address supplied, using a random one.\n");
2885ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov		eth_hw_addr_random(ndev);
2886ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov	}
288786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
28886ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda	/* ioremap the TSU registers */
28896ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda	if (mdp->cd->tsu) {
28906ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda		struct resource *rtsu;
28916ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda		rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
2892d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		mdp->tsu_addr = devm_ioremap_resource(&pdev->dev, rtsu);
2893d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		if (IS_ERR(mdp->tsu_addr)) {
2894d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov			ret = PTR_ERR(mdp->tsu_addr);
2895fc0c0900408e05758a0df17c1924ca837fafca5eSergei Shtylyov			goto out_release;
2896fc0c0900408e05758a0df17c1924ca837fafca5eSergei Shtylyov		}
28976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		mdp->port = devno % 2;
2898f646968f8f7c624587de729115d802372b9063ddPatrick McHardy		ndev->features = NETIF_F_HW_VLAN_CTAG_FILTER;
28996ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda	}
29006ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda
2901150647fb2c313d7c5184fca3fa0829a4a7d6f7bcYoshihiro Shimoda	/* initialize first or needed device */
2902150647fb2c313d7c5184fca3fa0829a4a7d6f7bcYoshihiro Shimoda	if (!devno || pd->needs_init) {
2903380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		if (mdp->cd->chip_reset)
2904380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			mdp->cd->chip_reset(ndev);
290586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
29064986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda		if (mdp->cd->tsu) {
29074986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda			/* TSU init (Init only)*/
29084986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda			sh_eth_tsu_init(mdp);
29094986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda		}
291086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
291186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
29123719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	netif_napi_add(ndev, &mdp->napi, sh_eth_poll, 64);
29133719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
291486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* network device register */
291586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = register_netdev(ndev);
291686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
29173719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov		goto out_napi_del;
291886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
291986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* mdio bus init */
2920b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	ret = sh_mdio_init(ndev, pdev->id, pd);
2921702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	if (ret) {
2922702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks		dev_err(&ndev->dev, "failed to initialise MDIO\n");
292386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_unregister;
2924702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks	}
292586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
292625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	/* print device information */
29276cd9b49d7328c4656bfc17fcb47fb814955d40d2H Hartley Sweeten	pr_info("Base address at 0x%x, %pM, IRQ %d.\n",
2928128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov		(u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
292986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
293086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	platform_set_drvdata(pdev, ndev);
293186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
293286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
293386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
293486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_unregister:
293586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	unregister_netdev(ndev);
293686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
29373719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovout_napi_del:
29383719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	netif_napi_del(&mdp->napi);
29393719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov
294086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_release:
294186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* net_dev free */
294286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ndev)
294386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		free_netdev(ndev);
294486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
294586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout:
294686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
294786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
294886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
294986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_drv_remove(struct platform_device *pdev)
295086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
295186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct net_device *ndev = platform_get_drvdata(pdev);
29523719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	struct sh_eth_private *mdp = netdev_priv(ndev);
295386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
295486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	sh_mdio_release(ndev);
295586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	unregister_netdev(ndev);
29563719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov	netif_napi_del(&mdp->napi);
2957bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_disable(&pdev->dev);
295886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_netdev(ndev);
295986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
296086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
296186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
296286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2963540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#ifdef CONFIG_PM
2964bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Dammstatic int sh_eth_runtime_nop(struct device *dev)
2965bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm{
2966128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov	/* Runtime PM callback shared between ->runtime_suspend()
2967bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * and ->runtime_resume(). Simply returns success.
2968bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 *
2969bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * This driver re-initializes all registers after
2970bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * pm_runtime_get_sync() anyway so there is no need
2971bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * to save and restore registers here.
2972bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 */
2973bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	return 0;
2974bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm}
2975bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2976540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsustatic const struct dev_pm_ops sh_eth_dev_pm_ops = {
2977bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	.runtime_suspend = sh_eth_runtime_nop,
2978bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	.runtime_resume = sh_eth_runtime_nop,
2979bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm};
2980540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#define SH_ETH_PM_OPS (&sh_eth_dev_pm_ops)
2981540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#else
2982540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#define SH_ETH_PM_OPS NULL
2983540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#endif
2984bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2985afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyovstatic struct platform_device_id sh_eth_id_table[] = {
2986c18a79abe31f555ec3b363b5b8c1d003230053b6Sergei Shtylyov	{ "sh7619-ether", (kernel_ulong_t)&sh7619_data },
29877bbe150d8c57c59689c8c50fd7b9915f4a7e10daSergei Shtylyov	{ "sh771x-ether", (kernel_ulong_t)&sh771x_data },
29889c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyov	{ "sh7724-ether", (kernel_ulong_t)&sh7724_data },
2989f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	{ "sh7734-gether", (kernel_ulong_t)&sh7734_data },
299024549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov	{ "sh7757-ether", (kernel_ulong_t)&sh7757_data },
299124549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov	{ "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga },
2992f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov	{ "sh7763-gether", (kernel_ulong_t)&sh7763_data },
2993db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman	{ "r7s72100-ether", (kernel_ulong_t)&r7s72100_data },
2994e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyov	{ "r8a7740-gether", (kernel_ulong_t)&r8a7740_data },
2995589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyov	{ "r8a777x-ether", (kernel_ulong_t)&r8a777x_data },
299694a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyov	{ "r8a7790-ether", (kernel_ulong_t)&r8a779x_data },
299794a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyov	{ "r8a7791-ether", (kernel_ulong_t)&r8a779x_data },
2998afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov	{ }
2999afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov};
3000afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei ShtylyovMODULE_DEVICE_TABLE(platform, sh_eth_id_table);
3001afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov
300286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct platform_driver sh_eth_driver = {
300386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.probe = sh_eth_drv_probe,
300486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.remove = sh_eth_drv_remove,
3005afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov	.id_table = sh_eth_id_table,
300686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.driver = {
300786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		   .name = CARDNAME,
3008540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu		   .pm = SH_ETH_PM_OPS,
3009b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov		   .of_match_table = of_match_ptr(sh_eth_match_table),
301086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	},
301186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu};
301286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
3013db62f684deeb291ab2533b99843d5df9a36b1f19Axel Linmodule_platform_driver(sh_eth_driver);
301486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
301586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_AUTHOR("Nobuhiro Iwamatsu, Yoshihiro Shimoda");
301686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_DESCRIPTION("Renesas SuperH Ethernet driver");
301786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_LICENSE("GPL v2");
3018