sh_eth.c revision 80d5c3689b886308247da295a228a54df49a44f6
186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/*
286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  SuperH Ethernet device driver
386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
4f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu *  Copyright (C) 2006-2012 Nobuhiro Iwamatsu
5a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov *  Copyright (C) 2008-2013 Renesas Solutions Corp.
6a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov *  Copyright (C) 2013 Cogent Embedded, Inc.
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 *  You should have received a copy of the GNU General Public License along with
1786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  this program; if not, write to the Free Software Foundation, Inc.,
1886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
2086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  The full GNU General Public License is included in this distribution in
2186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *  the file called "COPYING".
2286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */
2386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/init.h>
250654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/module.h>
260654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/kernel.h>
270654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/spinlock.h>
286a27cdeddf48858089e3672f844615cbf0877ebfNobuhiro Iwamatsu#include <linux/interrupt.h>
2986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/dma-mapping.h>
3086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/etherdevice.h>
3186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/delay.h>
3286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/platform_device.h>
3386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/mdio-bitbang.h>
3486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/netdevice.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>
4486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
4586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include "sh_eth.h"
4686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
47dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#define SH_ETH_DEF_MSG_ENABLE \
48dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		(NETIF_MSG_LINK	| \
49dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		NETIF_MSG_TIMER	| \
50dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		NETIF_MSG_RX_ERR| \
51dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		NETIF_MSG_TX_ERR)
52dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
53c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
54c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDSR]		= 0x0000,
55c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDMR]		= 0x0400,
56c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDTRR]		= 0x0408,
57c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDRRR]		= 0x0410,
58c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESR]		= 0x0428,
59c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESIPR]	= 0x0430,
60c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDLAR]		= 0x0010,
61c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFAR]		= 0x0014,
62c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFXR]		= 0x0018,
63c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFFR]		= 0x001c,
64c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDLAR]		= 0x0030,
65c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFAR]		= 0x0034,
66c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFXR]		= 0x0038,
67c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFFR]		= 0x003c,
68c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TRSCER]	= 0x0438,
69c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMFCR]		= 0x0440,
70c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TFTR]		= 0x0448,
71c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FDR]		= 0x0450,
72c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMCR]		= 0x0458,
73c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RPADIR]	= 0x0460,
74c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FCFTR]		= 0x0468,
75c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CSMR]		= 0x04E4,
76c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
77c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECMR]		= 0x0500,
78c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSR]		= 0x0510,
79c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSIPR]	= 0x0518,
80c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIR]		= 0x0520,
81c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PSR]		= 0x0528,
82c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIPR]		= 0x052c,
83c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFLR]		= 0x0508,
84c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[APR]		= 0x0554,
85c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MPR]		= 0x0558,
86c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PFTCR]		= 0x055c,
87c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PFRCR]		= 0x0560,
88c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSER]	= 0x0564,
89c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[GECMR]		= 0x05b0,
90c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[BCULR]		= 0x05b4,
91c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAHR]		= 0x05c0,
92c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MALR]		= 0x05c8,
93c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TROCR]		= 0x0700,
94c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CDCR]		= 0x0708,
95c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[LCCR]		= 0x0710,
96c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEFCR]		= 0x0740,
97c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FRECR]		= 0x0748,
98c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSFRCR]	= 0x0750,
99c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TLFRCR]	= 0x0758,
100c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCR]		= 0x0760,
101c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CERCR]		= 0x0768,
102c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEECR]		= 0x0770,
103c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAFCR]		= 0x0778,
104c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMII_MII]	= 0x0790,
105c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
106c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ARSTR]		= 0x0000,
107c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_CTRST]	= 0x0004,
108c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN0]	= 0x0010,
109c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN1]	= 0x0014,
110c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FCM]	= 0x0018,
111c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL0]	= 0x0020,
112c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL1]	= 0x0024,
113c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL0]	= 0x0028,
114c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL1]	= 0x002c,
115c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL0]	= 0x0030,
116c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL1]	= 0x0034,
117c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSLC]	= 0x0038,
118c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAG0]	= 0x0040,
119c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAG1]	= 0x0044,
120c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSR]	= 0x0050,
121c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWINMK]	= 0x0054,
122c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT0]	= 0x0048,
123c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT1]	= 0x004c,
124c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_VTAG0]	= 0x0058,
125c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_VTAG1]	= 0x005c,
126c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADSBSY]	= 0x0060,
127c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_TEN]	= 0x0064,
128c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST1]	= 0x0070,
129c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST2]	= 0x0074,
130c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST3]	= 0x0078,
131c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST4]	= 0x007c,
132c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRH0]	= 0x0100,
133c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL0]	= 0x0104,
134c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRH31]	= 0x01f8,
135c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL31]	= 0x01fc,
136c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
137c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR0]	= 0x0080,
138c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR0]	= 0x0084,
139c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR0]	= 0x0088,
140c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR0]	= 0x008c,
141c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR0]	= 0x0090,
142c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR0]	= 0x0094,
143c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR1]	= 0x00a0,
144c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR1]	= 0x00a0,
145c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR1]	= 0x00a8,
146c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR1]	= 0x00ac,
147c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR1]	= 0x00b0,
148c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR1]	= 0x00b4,
149c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov};
150c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
151a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyovstatic const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
152a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[ECMR]		= 0x0300,
153a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFLR]		= 0x0308,
154a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[ECSR]		= 0x0310,
155a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[ECSIPR]	= 0x0318,
156a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[PIR]		= 0x0320,
157a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[PSR]		= 0x0328,
158a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RDMLR]		= 0x0340,
159a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[IPGR]		= 0x0350,
160a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[APR]		= 0x0354,
161a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MPR]		= 0x0358,
162a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFCF]		= 0x0360,
163a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TPAUSER]	= 0x0364,
164a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TPAUSECR]	= 0x0368,
165a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MAHR]		= 0x03c0,
166a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MALR]		= 0x03c8,
167a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TROCR]		= 0x03d0,
168a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[CDCR]		= 0x03d4,
169a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[LCCR]		= 0x03d8,
170a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[CNDCR]		= 0x03dc,
171a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[CEFCR]		= 0x03e4,
172a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[FRECR]		= 0x03e8,
173a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TSFRCR]	= 0x03ec,
174a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TLFRCR]	= 0x03f0,
175a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFCR]		= 0x03f4,
176a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[MAFCR]		= 0x03f8,
177a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
178a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EDMR]		= 0x0200,
179a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EDTRR]		= 0x0208,
180a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EDRRR]		= 0x0210,
181a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TDLAR]		= 0x0218,
182a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RDLAR]		= 0x0220,
183a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EESR]		= 0x0228,
184a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[EESIPR]	= 0x0230,
185a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TRSCER]	= 0x0238,
186a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RMFCR]		= 0x0240,
187a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TFTR]		= 0x0248,
188a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[FDR]		= 0x0250,
189a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RMCR]		= 0x0258,
190a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TFUCR]		= 0x0264,
191a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[RFOCR]		= 0x0268,
192a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[FCFTR]		= 0x0270,
193a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	[TRIMD]		= 0x027c,
194a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov};
195a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
196c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
197c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECMR]		= 0x0100,
198c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFLR]		= 0x0108,
199c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSR]		= 0x0110,
200c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSIPR]	= 0x0118,
201c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIR]		= 0x0120,
202c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PSR]		= 0x0128,
203c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDMLR]		= 0x0140,
204c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[IPGR]		= 0x0150,
205c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[APR]		= 0x0154,
206c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MPR]		= 0x0158,
207c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSER]	= 0x0164,
208c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCF]		= 0x0160,
209c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSECR]	= 0x0168,
210c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[BCFRR]		= 0x016c,
211c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAHR]		= 0x01c0,
212c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MALR]		= 0x01c8,
213c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TROCR]		= 0x01d0,
214c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CDCR]		= 0x01d4,
215c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[LCCR]		= 0x01d8,
216c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CNDCR]		= 0x01dc,
217c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEFCR]		= 0x01e4,
218c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FRECR]		= 0x01e8,
219c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSFRCR]	= 0x01ec,
220c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TLFRCR]	= 0x01f0,
221c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCR]		= 0x01f4,
222c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAFCR]		= 0x01f8,
223c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RTRATE]	= 0x01fc,
224c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
225c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDMR]		= 0x0000,
226c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDTRR]		= 0x0008,
227c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EDRRR]		= 0x0010,
228c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDLAR]		= 0x0018,
229c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDLAR]		= 0x0020,
230c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESR]		= 0x0028,
231c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[EESIPR]	= 0x0030,
232c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TRSCER]	= 0x0038,
233c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMFCR]		= 0x0040,
234c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TFTR]		= 0x0048,
235c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FDR]		= 0x0050,
236c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RMCR]		= 0x0058,
237c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TFUCR]		= 0x0064,
238c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFOCR]		= 0x0068,
239c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FCFTR]		= 0x0070,
240c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RPADIR]	= 0x0078,
241c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TRIMD]		= 0x007c,
242c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RBWAR]		= 0x00c8,
243c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RDFAR]		= 0x00cc,
244c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TBRAR]		= 0x00d4,
245c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TDFAR]		= 0x00d8,
246c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov};
247c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
248c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
249c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECMR]		= 0x0160,
250c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSR]		= 0x0164,
251c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ECSIPR]	= 0x0168,
252c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PIR]		= 0x016c,
253c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAHR]		= 0x0170,
254c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MALR]		= 0x0174,
255c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFLR]		= 0x0178,
256c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[PSR]		= 0x017c,
257c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TROCR]		= 0x0180,
258c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CDCR]		= 0x0184,
259c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[LCCR]		= 0x0188,
260c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CNDCR]		= 0x018c,
261c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[CEFCR]		= 0x0194,
262c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FRECR]		= 0x0198,
263c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSFRCR]	= 0x019c,
264c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TLFRCR]	= 0x01a0,
265c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RFCR]		= 0x01a4,
266c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MAFCR]		= 0x01a8,
267c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[IPGR]		= 0x01b4,
268c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[APR]		= 0x01b8,
269c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[MPR]		= 0x01bc,
270c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TPAUSER]	= 0x01c4,
271c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[BCFR]		= 0x01cc,
272c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
273c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[ARSTR]		= 0x0000,
274c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_CTRST]	= 0x0004,
275c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN0]	= 0x0010,
276c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWEN1]	= 0x0014,
277c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FCM]	= 0x0018,
278c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL0]	= 0x0020,
279c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_BSYSL1]	= 0x0024,
280c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL0]	= 0x0028,
281c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_PRISL1]	= 0x002c,
282c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL0]	= 0x0030,
283c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSL1]	= 0x0034,
284c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSLC]	= 0x0038,
285c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAGM0]	= 0x0040,
286c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_QTAGM1]	= 0x0044,
287c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT0]	= 0x0048,
288c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADQT1]	= 0x004c,
289c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWSR]	= 0x0050,
290c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_FWINMK]	= 0x0054,
291c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADSBSY]	= 0x0060,
292c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_TEN]	= 0x0064,
293c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST1]	= 0x0070,
294c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST2]	= 0x0074,
295c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST3]	= 0x0078,
296c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_POST4]	= 0x007c,
297c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
298c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR0]	= 0x0080,
299c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR0]	= 0x0084,
300c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR0]	= 0x0088,
301c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR0]	= 0x008c,
302c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR0]	= 0x0090,
303c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR0]	= 0x0094,
304c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXNLCR1]	= 0x00a0,
305c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TXALCR1]	= 0x00a0,
306c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXNLCR1]	= 0x00a8,
307c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[RXALCR1]	= 0x00ac,
308c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWNLCR1]	= 0x00b0,
309c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[FWALCR1]	= 0x00b4,
310c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
311c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRH0]	= 0x0100,
312c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL0]	= 0x0104,
313c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov	[TSU_ADRL31]	= 0x01fc,
314c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov};
315c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov
3165e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu#if defined(CONFIG_CPU_SUBTYPE_SH7734) || \
3175e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	defined(CONFIG_CPU_SUBTYPE_SH7763) || \
3185e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	defined(CONFIG_ARCH_R8A7740)
3195e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsustatic void sh_eth_select_mii(struct net_device *ndev)
3205e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu{
3215e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	u32 value = 0x0;
3225e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
3235e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
3245e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	switch (mdp->phy_interface) {
3255e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	case PHY_INTERFACE_MODE_GMII:
3265e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x2;
3275e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
3285e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	case PHY_INTERFACE_MODE_MII:
3295e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x1;
3305e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
3315e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	case PHY_INTERFACE_MODE_RMII:
3325e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x0;
3335e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
3345e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	default:
3355e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		pr_warn("PHY interface mode was not setup. Set to MII.\n");
3365e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		value = 0x1;
3375e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		break;
3385e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	}
3395e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
3405e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, value, RMII_MII);
3415e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu}
3425e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu#endif
3435e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
344380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda/* There is CPU dependent code */
345a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov#if defined(CONFIG_ARCH_R8A7779)
34665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda#define SH_ETH_RESET_DEFAULT	1
34765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimodastatic void sh_eth_set_duplex(struct net_device *ndev)
34865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda{
34965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
35065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
35165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	if (mdp->duplex) /* Full */
3524a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
35365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	else		/* Half */
3544a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
35565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda}
35665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
35765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimodastatic void sh_eth_set_rate(struct net_device *ndev)
35865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda{
35965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
360d0418bb7123f44b23d69ac349eec7daf9103472fPhil Edworthy
361a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	switch (mdp->speed) {
362a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	case 10: /* 10BASE */
363a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_ELB, ECMR);
364a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
365a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	case 100:/* 100BASE */
366a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_ELB, ECMR);
367a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
368a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	default:
369a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
370a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	}
371a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov}
372a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
373a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov/* R8A7779 */
374a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyovstatic struct sh_eth_cpu_data sh_eth_my_cpu_data = {
375a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.set_duplex	= sh_eth_set_duplex,
376a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.set_rate	= sh_eth_set_rate,
377a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
378a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
379a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
380a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.eesipr_value	= 0x01ff009f,
381a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
382a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
383a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
384a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov			  EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
385a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.tx_error_check	= EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
386a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
387a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.apr		= 1,
388a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.mpr		= 1,
389a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.tpauser	= 1,
390a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	.hw_swap	= 1,
391a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov};
392a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
393a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov#define SH_ETH_RESET_DEFAULT	1
394a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyovstatic void sh_eth_set_duplex(struct net_device *ndev)
395a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov{
396a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	struct sh_eth_private *mdp = netdev_priv(ndev);
397a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
398a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	if (mdp->duplex) /* Full */
399a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
400a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	else		/* Half */
401a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
402a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov}
403a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov
404a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyovstatic void sh_eth_set_rate(struct net_device *ndev)
405a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov{
406a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	struct sh_eth_private *mdp = netdev_priv(ndev);
40765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
40865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	switch (mdp->speed) {
40965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	case 10: /* 10BASE */
410a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
41165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda		break;
41265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	case 100:/* 100BASE */
413a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
41465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda		break;
41565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	default:
41665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda		break;
41765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	}
41865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda}
41965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
42065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda/* SH7724 */
42165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimodastatic struct sh_eth_cpu_data sh_eth_my_cpu_data = {
42265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.set_duplex	= sh_eth_set_duplex,
42365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.set_rate	= sh_eth_set_rate,
42465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
42565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
42665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
42765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f,
42865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
42965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
43065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
43165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda			  EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
43265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.tx_error_check	= EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
43365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
43465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.apr		= 1,
43565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.mpr		= 1,
43665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.tpauser	= 1,
43765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda	.hw_swap	= 1,
438503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm	.rpadir		= 1,
439503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm	.rpadir_value	= 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
44065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda};
441f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
4428fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define SH_ETH_HAS_BOTH_MODULES	1
4438fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define SH_ETH_HAS_TSU	1
4445cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_check_reset(struct net_device *ndev);
4455cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
446f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimodastatic void sh_eth_set_duplex(struct net_device *ndev)
447f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda{
448f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
449f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
450f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	if (mdp->duplex) /* Full */
4514a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
452f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	else		/* Half */
4534a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
454f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda}
455f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
456f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimodastatic void sh_eth_set_rate(struct net_device *ndev)
457f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda{
458f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
459f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
460f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	switch (mdp->speed) {
461f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	case 10: /* 10BASE */
4624a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0, RTRATE);
463f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda		break;
464f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	case 100:/* 100BASE */
4654a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 1, RTRATE);
466f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda		break;
467f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	default:
468f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda		break;
469f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	}
470f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda}
471f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
472f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda/* SH7757 */
473f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimodastatic struct sh_eth_cpu_data sh_eth_my_cpu_data = {
474f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.set_duplex		= sh_eth_set_duplex,
475f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.set_rate		= sh_eth_set_rate,
476f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
477f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
478f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.rmcr_value	= 0x00000001,
479f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
480f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.tx_check	= EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
481f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.eesr_err_check	= EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
482f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda			  EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
483f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.tx_error_check	= EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
484f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda
485f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.apr		= 1,
486f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.mpr		= 1,
487f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.tpauser	= 1,
488f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.hw_swap	= 1,
489f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda	.no_ade		= 1,
4902e98e7974de208de0dab9e9969bd47576d07ff10Yoshihiro Shimoda	.rpadir		= 1,
4912e98e7974de208de0dab9e9969bd47576d07ff10Yoshihiro Shimoda	.rpadir_value   = 2 << 16,
492f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda};
49365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda
4948fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define SH_GIGA_ETH_BASE	0xfee00000
4958fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define GIGA_MALR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
4968fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define GIGA_MAHR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
4978fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic void sh_eth_chip_reset_giga(struct net_device *ndev)
4988fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{
4998fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	int i;
5008fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	unsigned long mahr[2], malr[2];
5018fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5028fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	/* save MAHR and MALR */
5038fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	for (i = 0; i < 2; i++) {
504ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		malr[i] = ioread32((void *)GIGA_MALR(i));
505ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		mahr[i] = ioread32((void *)GIGA_MAHR(i));
5068fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	}
5078fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5088fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	/* reset device */
509ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	iowrite32(ARSTR_ARSTR, (void *)(SH_GIGA_ETH_BASE + 0x1800));
5108fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	mdelay(1);
5118fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5128fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	/* restore MAHR and MALR */
5138fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	for (i = 0; i < 2; i++) {
514ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		iowrite32(malr[i], (void *)GIGA_MALR(i));
515ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		iowrite32(mahr[i], (void *)GIGA_MAHR(i));
5168fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	}
5178fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}
5188fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5198fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic int sh_eth_is_gether(struct sh_eth_private *mdp);
5205cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_reset(struct net_device *ndev)
5218fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{
5228fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
5235cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	int ret = 0;
5248fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5258fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	if (sh_eth_is_gether(mdp)) {
5268fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x03, EDSR);
5278fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
5288fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda				EDMR);
5295cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
5305cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		ret = sh_eth_check_reset(ndev);
5315cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		if (ret)
5325cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu			goto out;
5338fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5348fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		/* Table Init */
5358fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, TDLAR);
5368fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, TDFAR);
5378fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, TDFXR);
5388fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, TDFFR);
5398fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, RDLAR);
5408fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, RDFAR);
5418fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, RDFXR);
5428fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x0, RDFFR);
5438fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	} else {
5448fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
5458fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda				EDMR);
5468fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		mdelay(3);
5478fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
5488fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda				EDMR);
5498fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	}
5505cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
5515cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsuout:
5525cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	return ret;
5538fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}
5548fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5558fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic void sh_eth_set_duplex_giga(struct net_device *ndev)
5568fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{
5578fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
5588fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5598fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	if (mdp->duplex) /* Full */
5608fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
5618fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	else		/* Half */
5628fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
5638fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}
5648fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5658fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic void sh_eth_set_rate_giga(struct net_device *ndev)
5668fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{
5678fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
5688fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5698fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	switch (mdp->speed) {
5708fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	case 10: /* 10BASE */
5718fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x00000000, GECMR);
5728fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
5738fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	case 100:/* 100BASE */
5748fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x00000010, GECMR);
5758fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
5768fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	case 1000: /* 1000BASE */
5778fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		sh_eth_write(ndev, 0x00000020, GECMR);
5788fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
5798fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	default:
5808fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		break;
5818fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	}
5828fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}
5838fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5848fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda/* SH7757(GETHERC) */
5858fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
5868fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.chip_reset	= sh_eth_chip_reset_giga,
5878fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.set_duplex	= sh_eth_set_duplex_giga,
5888fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.set_rate	= sh_eth_set_rate_giga,
5898fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5908fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.ecsr_value	= ECSR_ICD | ECSR_MPD,
5918fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
5928fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
5938fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
5948fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.tx_check	= EESR_TC1 | EESR_FTC,
5958fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
5968fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
5978fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda			  EESR_ECI,
5988fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.tx_error_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
5998fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda			  EESR_TFE,
6008fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.fdr_value	= 0x0000072f,
6018fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.rmcr_value	= 0x00000001,
6028fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
6038fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.apr		= 1,
6048fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.mpr		= 1,
6058fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.tpauser	= 1,
6068fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.bculr		= 1,
6078fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.hw_swap	= 1,
6088fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.rpadir		= 1,
6098fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.rpadir_value   = 2 << 16,
6108fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.no_trimd	= 1,
6118fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	.no_ade		= 1,
6123acbc9715a5ac8a2534a69eb3488b63b7c9fb1e2Yoshihiro Shimoda	.tsu		= 1,
6138fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda};
6148fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
6158fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
6168fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{
6178fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	if (sh_eth_is_gether(mdp))
6188fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		return &sh_eth_my_cpu_data_giga;
6198fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	else
6208fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda		return &sh_eth_my_cpu_data;
6218fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}
6228fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda
623f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu#elif defined(CONFIG_CPU_SUBTYPE_SH7734) || defined(CONFIG_CPU_SUBTYPE_SH7763)
624380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#define SH_ETH_HAS_TSU	1
6255cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_check_reset(struct net_device *ndev);
626f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsustatic void sh_eth_reset_hw_crc(struct net_device *ndev);
6275e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
628380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_chip_reset(struct net_device *ndev)
629380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
6304986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
6314986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda
632380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	/* reset device */
6334986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
634380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	mdelay(1);
635380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
636380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
637380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_duplex(struct net_device *ndev)
638380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
639380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
640380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
641380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->duplex) /* Full */
6424a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
643380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	else		/* Half */
6444a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
645380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
646380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
647380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_rate(struct net_device *ndev)
648380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
649380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
650380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
651380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	switch (mdp->speed) {
652380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	case 10: /* 10BASE */
6534a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, GECMR_10, GECMR);
654380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
655380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	case 100:/* 100BASE */
6564a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, GECMR_100, GECMR);
657380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
658380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	case 1000: /* 1000BASE */
6594a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, GECMR_1000, GECMR);
660380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
661380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	default:
662380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		break;
663380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	}
664380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
665380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
666380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda/* sh7763 */
667380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic struct sh_eth_cpu_data sh_eth_my_cpu_data = {
668380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.chip_reset	= sh_eth_chip_reset,
669380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.set_duplex	= sh_eth_set_duplex,
670380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.set_rate	= sh_eth_set_rate,
671380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
672380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.ecsr_value	= ECSR_ICD | ECSR_MPD,
673380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
674380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
675380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
676380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.tx_check	= EESR_TC1 | EESR_FTC,
677380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
678380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
679380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			  EESR_ECI,
680380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.tx_error_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
681380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			  EESR_TFE,
682380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
683380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.apr		= 1,
684380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.mpr		= 1,
685380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.tpauser	= 1,
686380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.bculr		= 1,
687380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.hw_swap	= 1,
688380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.no_trimd	= 1,
689380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.no_ade		= 1,
6904986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	.tsu		= 1,
691f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu#if defined(CONFIG_CPU_SUBTYPE_SH7734)
692f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu	.hw_crc     = 1,
6935e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	.select_mii = 1,
694f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu#endif
695380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda};
696380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
6975cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_reset(struct net_device *ndev)
6985e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu{
6995cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	int ret = 0;
7005e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
7015e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, EDSR_ENALL, EDSR);
7025e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
7035cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
7045cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	ret = sh_eth_check_reset(ndev);
7055cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	if (ret)
7065cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		goto out;
7075e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
7085e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	/* Table Init */
7095e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, TDLAR);
7105e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, TDFAR);
7115e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, TDFXR);
7125e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, TDFFR);
7135e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, RDLAR);
7145e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, RDFAR);
7155e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, RDFXR);
7165e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_write(ndev, 0x0, RDFFR);
7175e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
7185e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	/* Reset HW CRC register */
7195e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_reset_hw_crc(ndev);
7205e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
7215e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	/* Select MII mode */
7225e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	if (sh_eth_my_cpu_data.select_mii)
7235e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu		sh_eth_select_mii(ndev);
7245cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsuout:
7255cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	return ret;
7265e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu}
7275e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu
728f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsustatic void sh_eth_reset_hw_crc(struct net_device *ndev)
729f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu{
730f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu	if (sh_eth_my_cpu_data.hw_crc)
731f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu		sh_eth_write(ndev, 0x0, CSMR);
732f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu}
733f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu
73473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda#elif defined(CONFIG_ARCH_R8A7740)
73573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda#define SH_ETH_HAS_TSU	1
7365cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_check_reset(struct net_device *ndev);
7375cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
73873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimodastatic void sh_eth_chip_reset(struct net_device *ndev)
73973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda{
74073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
74173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
74273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	/* reset device */
74373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
74473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	mdelay(1);
74573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
7465e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	sh_eth_select_mii(ndev);
74773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda}
74873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
7495cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_reset(struct net_device *ndev)
75073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda{
7515cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	int ret = 0;
75273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
75373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, EDSR_ENALL, EDSR);
75473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
7555cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
7565cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	ret = sh_eth_check_reset(ndev);
7575cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	if (ret)
7585cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		goto out;
75973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
76073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	/* Table Init */
76173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, TDLAR);
76273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, TDFAR);
76373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, TDFXR);
76473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, TDFFR);
76573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, RDLAR);
76673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, RDFAR);
76773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, RDFXR);
76873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	sh_eth_write(ndev, 0x0, RDFFR);
7695cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
7705cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsuout:
7715cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	return ret;
77273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda}
77373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
77473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimodastatic void sh_eth_set_duplex(struct net_device *ndev)
77573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda{
77673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
77773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
77873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	if (mdp->duplex) /* Full */
77973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
78073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	else		/* Half */
78173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
78273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda}
78373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
78473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimodastatic void sh_eth_set_rate(struct net_device *ndev)
78573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda{
78673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
78773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
78873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	switch (mdp->speed) {
78973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	case 10: /* 10BASE */
79073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		sh_eth_write(ndev, GECMR_10, GECMR);
79173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		break;
79273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	case 100:/* 100BASE */
79373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		sh_eth_write(ndev, GECMR_100, GECMR);
79473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		break;
79573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	case 1000: /* 1000BASE */
79673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		sh_eth_write(ndev, GECMR_1000, GECMR);
79773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		break;
79873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	default:
79973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		break;
80073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	}
80173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda}
80273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
80373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda/* R8A7740 */
80473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimodastatic struct sh_eth_cpu_data sh_eth_my_cpu_data = {
80573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.chip_reset	= sh_eth_chip_reset,
80673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.set_duplex	= sh_eth_set_duplex,
80773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.set_rate	= sh_eth_set_rate,
80873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
80973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.ecsr_value	= ECSR_ICD | ECSR_MPD,
81073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
81173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
81273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
81373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.tx_check	= EESR_TC1 | EESR_FTC,
81473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
81573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
81673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda			  EESR_ECI,
81773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.tx_error_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
81873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda			  EESR_TFE,
81973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
82073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.apr		= 1,
82173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.mpr		= 1,
82273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.tpauser	= 1,
82373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.bculr		= 1,
82473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.hw_swap	= 1,
82573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.no_trimd	= 1,
82673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.no_ade		= 1,
82773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda	.tsu		= 1,
8285e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu	.select_mii	= 1,
82973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda};
83073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
831380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
832380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#define SH_ETH_RESET_DEFAULT	1
833380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic struct sh_eth_cpu_data sh_eth_my_cpu_data = {
834380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
835380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
836380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.apr		= 1,
837380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.mpr		= 1,
838380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.tpauser	= 1,
839380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.hw_swap	= 1,
840380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda};
841380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
842380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#define SH_ETH_RESET_DEFAULT	1
843380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#define SH_ETH_HAS_TSU	1
844380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic struct sh_eth_cpu_data sh_eth_my_cpu_data = {
845380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
8464986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda	.tsu		= 1,
847380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda};
848380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#endif
849380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
850380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
851380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
852380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->ecsr_value)
853380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->ecsr_value = DEFAULT_ECSR_INIT;
854380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
855380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->ecsipr_value)
856380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->ecsipr_value = DEFAULT_ECSIPR_INIT;
857380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
858380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->fcftr_value)
859380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->fcftr_value = DEFAULT_FIFO_F_D_RFF | \
860380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				  DEFAULT_FIFO_F_D_RFD;
861380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
862380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->fdr_value)
863380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->fdr_value = DEFAULT_FDR_INIT;
864380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
865380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->rmcr_value)
866380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->rmcr_value = DEFAULT_RMCR_VALUE;
867380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
868380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->tx_check)
869380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->tx_check = DEFAULT_TX_CHECK;
870380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
871380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->eesr_err_check)
872380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK;
873380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
874380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!cd->tx_error_check)
875380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		cd->tx_error_check = DEFAULT_TX_ERROR_CHECK;
876380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
877380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
878380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#if defined(SH_ETH_RESET_DEFAULT)
879380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda/* Chip Reset */
8805cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int  sh_eth_reset(struct net_device *ndev)
881380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
882c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR);
883380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	mdelay(3);
884c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR);
8855cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
8865cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	return 0;
8875cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu}
8885cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu#else
8895cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_check_reset(struct net_device *ndev)
8905cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu{
8915cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	int ret = 0;
8925cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	int cnt = 100;
8935cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu
8945cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	while (cnt > 0) {
8955cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		if (!(sh_eth_read(ndev, EDMR) & 0x3))
8965cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu			break;
8975cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		mdelay(1);
8985cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		cnt--;
8995cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	}
9005cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	if (cnt < 0) {
90114c3326a111b948cabc35d523a43a1e6663f6091Nobuhiro Iwamatsu		pr_err("Device reset fail\n");
9025cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		ret = -ETIMEDOUT;
9035cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	}
9045cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	return ret;
905380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
906380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#endif
907380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
90873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
909380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_receive_align(struct sk_buff *skb)
910380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
911380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	int reserve;
912380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
913380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	reserve = SH4_SKB_RX_ALIGN - ((u32)skb->data & (SH4_SKB_RX_ALIGN - 1));
914380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (reserve)
915380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		skb_reserve(skb, reserve);
916380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
917380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#else
918380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_receive_align(struct sk_buff *skb)
919380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{
920380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	skb_reserve(skb, SH2_SH3_SKB_RX_ALIGN);
921380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}
922380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#endif
923380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
924380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
92571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato/* CPU <-> EDMAC endian convert */
92671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Satostatic inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
92771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato{
92871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	switch (mdp->edmac_endian) {
92971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_LITTLE_ENDIAN:
93071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return cpu_to_le32(x);
93171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_BIG_ENDIAN:
93271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return cpu_to_be32(x);
93371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	}
93471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	return x;
93571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato}
93671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato
93771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Satostatic inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
93871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato{
93971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	switch (mdp->edmac_endian) {
94071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_LITTLE_ENDIAN:
94171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return le32_to_cpu(x);
94271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	case EDMAC_BIG_ENDIAN:
94371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		return be32_to_cpu(x);
94471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	}
94571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	return x;
94671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato}
94771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato
94886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/*
94986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * Program the hardware MAC address from dev->dev_addr.
95086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */
95186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void update_mac_address(struct net_device *ndev)
95286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
9534a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev,
9544a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		(ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
9554a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		(ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR);
9564a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev,
9574a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		(ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR);
95886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
95986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
96086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/*
96186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * Get MAC address from SuperH MAC address register
96286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
96386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * SuperH's Ethernet device doesn't have 'ROM' to MAC address.
96486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g).
96586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * When you want use this device, you must set MAC address in bootloader.
96686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu *
96786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */
968748031f9fd2c06b28817d80761a5de97190cfd03Magnus Dammstatic void read_mac_address(struct net_device *ndev, unsigned char *mac)
96986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
970748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
971748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm		memcpy(ndev->dev_addr, mac, 6);
972748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	} else {
9734a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24);
9744a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF;
9754a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[2] = (sh_eth_read(ndev, MAHR) >> 8) & 0xFF;
9764a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[3] = (sh_eth_read(ndev, MAHR) & 0xFF);
9774a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[4] = (sh_eth_read(ndev, MALR) >> 8) & 0xFF;
9784a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		ndev->dev_addr[5] = (sh_eth_read(ndev, MALR) & 0xFF);
979748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	}
98086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
98186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
982c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimodastatic int sh_eth_is_gether(struct sh_eth_private *mdp)
983c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda{
984c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (mdp->reg_offset == sh_eth_offset_gigabit)
985c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		return 1;
986c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	else
987c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		return 0;
988c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda}
989c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda
990c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimodastatic unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
991c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda{
992c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (sh_eth_is_gether(mdp))
993c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		return EDTRR_TRNS_GETHER;
994c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	else
995c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		return EDTRR_TRNS_ETHER;
996c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda}
997c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda
99886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustruct bb_info {
999ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	void (*set_gate)(void *addr);
100086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct mdiobb_ctrl ctrl;
1001ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	void *addr;
100286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mmd_msk;/* MMD */
100386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mdo_msk;
100486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mdi_msk;
100586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 mdc_msk;
100686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu};
100786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
100886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit set */
1009ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic void bb_set(void *addr, u32 msk)
101086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
1011ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	iowrite32(ioread32(addr) | msk, addr);
101286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
101386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
101486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit clear */
1015ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic void bb_clr(void *addr, u32 msk)
101686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
1017ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	iowrite32((ioread32(addr) & ~msk), addr);
101886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
101986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
102086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit read */
1021ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic int bb_read(void *addr, u32 msk)
102286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
1023ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	return (ioread32(addr) & msk) != 0;
102486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
102586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
102686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Data I/O pin control */
102786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
102886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
102986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
1030b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
1031b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1032b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1033b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
103486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (bit)
103586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_set(bitbang->addr, bitbang->mmd_msk);
103686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
103786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_clr(bitbang->addr, bitbang->mmd_msk);
103886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
103986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
104086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Set bit data*/
104186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
104286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
104386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
104486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1045b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1046b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1047b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
104886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (bit)
104986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_set(bitbang->addr, bitbang->mdo_msk);
105086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
105186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_clr(bitbang->addr, bitbang->mdo_msk);
105286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
105386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
105486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Get bit data*/
105586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_get_mdio(struct mdiobb_ctrl *ctrl)
105686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
105786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
1058b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
1059b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1060b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1061b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
106286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return bb_read(bitbang->addr, bitbang->mdi_msk);
106386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
106486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
106586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDC pin control */
106686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
106786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
106886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
106986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1070b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	if (bitbang->set_gate)
1071b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda		bitbang->set_gate(bitbang->addr);
1072b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda
107386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (bit)
107486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_set(bitbang->addr, bitbang->mdc_msk);
107586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
107686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		bb_clr(bitbang->addr, bitbang->mdc_msk);
107786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
107886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
107986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* mdio bus control struct */
108086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct mdiobb_ops bb_ops = {
108186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.owner = THIS_MODULE,
108286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.set_mdc = sh_mdc_ctrl,
108386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.set_mdio_dir = sh_mmd_ctrl,
108486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.set_mdio_data = sh_set_mdio,
108586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.get_mdio_data = sh_get_mdio,
108686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu};
108786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
108886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* free skb and descriptor buffer */
108986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_ring_free(struct net_device *ndev)
109086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
109186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
109286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int i;
109386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
109486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free Rx skb ringbuffer */
109586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (mdp->rx_skbuff) {
1096525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		for (i = 0; i < mdp->num_rx_ring; i++) {
109786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (mdp->rx_skbuff[i])
109886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				dev_kfree_skb(mdp->rx_skbuff[i]);
109986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
110086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
110186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	kfree(mdp->rx_skbuff);
110291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->rx_skbuff = NULL;
110386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
110486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free Tx skb ringbuffer */
110586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (mdp->tx_skbuff) {
1106525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		for (i = 0; i < mdp->num_tx_ring; i++) {
110786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (mdp->tx_skbuff[i])
110886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				dev_kfree_skb(mdp->tx_skbuff[i]);
110986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
111086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
111186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	kfree(mdp->tx_skbuff);
111291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->tx_skbuff = NULL;
111386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
111486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
111586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* format skb and descriptor buffer */
111686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_ring_format(struct net_device *ndev)
111786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
111886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
111986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int i;
112086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sk_buff *skb;
112186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_rxdesc *rxdesc = NULL;
112286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_txdesc *txdesc = NULL;
1123525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring;
1124525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring;
112586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
112686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->cur_rx = mdp->cur_tx = 0;
112786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->dirty_rx = mdp->dirty_tx = 0;
112886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
112986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	memset(mdp->rx_ring, 0, rx_ringsize);
113086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
113186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* build Rx ring buffer */
1132525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_rx_ring; i++) {
113386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* skb */
113486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->rx_skbuff[i] = NULL;
1135dae2e9f430c46c29e3f771110094bd3da3625aa4Pradeep A. Dalvi		skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
113686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->rx_skbuff[i] = skb;
113786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (skb == NULL)
113886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			break;
1139bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz,
1140e88aae7bb1dc50457489d1d7c81dcf4db23ccf94Yoshihiro Shimoda				DMA_FROM_DEVICE);
1141380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		sh_eth_set_receive_align(skb);
1142380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
114386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* RX descriptor */
114486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc = &mdp->rx_ring[i];
11450029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda		rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
114671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
114786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
114886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* The size of the buffer is 16 byte boundary. */
11490029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
1150b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		/* Rx descriptor address set */
1151b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		if (i == 0) {
11524a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda			sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
1153c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda			if (sh_eth_is_gether(mdp))
1154c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda				sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
1155b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		}
115686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
115786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1158525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->dirty_rx = (u32) (i - mdp->num_rx_ring);
115986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
116086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Mark the last entry as wrapping the ring. */
116171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
116286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
116386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	memset(mdp->tx_ring, 0, tx_ringsize);
116486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
116586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* build Tx ring buffer */
1166525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_tx_ring; i++) {
116786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->tx_skbuff[i] = NULL;
116886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc = &mdp->tx_ring[i];
116971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status = cpu_to_edmac(mdp, TD_TFP);
117086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc->buffer_length = 0;
1171b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		if (i == 0) {
117271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato			/* Tx descriptor address set */
11734a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
1174c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda			if (sh_eth_is_gether(mdp))
1175c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda				sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
1176b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		}
117786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
117886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
117971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
118086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
118186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
118286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Get skb and descriptor buffer */
118386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_ring_init(struct net_device *ndev)
118486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
118586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
118686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int rx_ringsize, tx_ringsize, ret = 0;
118786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
118886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/*
118986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 * +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
119086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 * card needs room to do 8 byte alignment, +2 so we can reserve
119186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 * the first 2 bytes, and +16 gets room for the status word from the
119286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 * card.
119386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	 */
119486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ :
119586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			  (((ndev->mtu + 26 + 7) & ~7) + 2 + 16));
1196503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm	if (mdp->cd->rpadir)
1197503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm		mdp->rx_buf_sz += NET_IP_ALIGN;
119886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
119986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Allocate RX and TX skb rings */
1200b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches	mdp->rx_skbuff = kmalloc_array(mdp->num_rx_ring,
1201b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches				       sizeof(*mdp->rx_skbuff), GFP_KERNEL);
120286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->rx_skbuff) {
120386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
120486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return ret;
120586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
120686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1207b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches	mdp->tx_skbuff = kmalloc_array(mdp->num_tx_ring,
1208b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches				       sizeof(*mdp->tx_skbuff), GFP_KERNEL);
120986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->tx_skbuff) {
121086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
121186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto skb_ring_free;
121286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
121386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
121486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Allocate all Rx descriptors. */
1215525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
121686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
1217d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches					  GFP_KERNEL);
121886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->rx_ring) {
121986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
122086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto desc_ring_free;
122186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
122286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
122386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->dirty_rx = 0;
122486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
122586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Allocate all Tx descriptors. */
1226525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
122786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
1228d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches					  GFP_KERNEL);
122986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->tx_ring) {
123086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
123186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto desc_ring_free;
123286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
123386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
123486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
123586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsudesc_ring_free:
123686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* free DMA buffer */
123786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma);
123886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
123986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuskb_ring_free:
124086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free Rx and Tx skb ring buffer */
124186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	sh_eth_ring_free(ndev);
124291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->tx_ring = NULL;
124391c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	mdp->rx_ring = NULL;
124486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
124586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
124686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
124786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
124891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimodastatic void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
124991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda{
125091c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	int ringsize;
125191c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda
125291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	if (mdp->rx_ring) {
1253525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
125491c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		dma_free_coherent(NULL, ringsize, mdp->rx_ring,
125591c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda				  mdp->rx_desc_dma);
125691c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		mdp->rx_ring = NULL;
125791c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	}
125891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda
125991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	if (mdp->tx_ring) {
1260525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
126191c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		dma_free_coherent(NULL, ringsize, mdp->tx_ring,
126291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda				  mdp->tx_desc_dma);
126391c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda		mdp->tx_ring = NULL;
126491c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	}
126591c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda}
126691c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda
1267525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic int sh_eth_dev_init(struct net_device *ndev, bool start)
126886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
126986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret = 0;
127086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
127186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 val;
127286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
127386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Soft Reset */
12745cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	ret = sh_eth_reset(ndev);
12755cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu	if (ret)
12765cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu		goto out;
127786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1278b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Descriptor format */
1279b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	sh_eth_ring_format(ndev);
1280380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->rpadir)
12814a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);
128286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
128386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* all sh_eth int mask */
12844a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, EESIPR);
128586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
128610b9194f959608368ed89df1937f17cfe6bd6d84Yoshihiro Shimoda#if defined(__LITTLE_ENDIAN)
1287380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->hw_swap)
12884a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, EDMR_EL, EDMR);
1289380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	else
1290b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu#endif
12914a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0, EDMR);
129286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1293b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* FIFO size set */
12944a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
12954a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, TFTR);
129686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1297b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Frame recv control */
12984a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);
129986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
13002ecbb783c3bf5a63f555c39deef308dcc1902b7fYoshihiro Shimoda	sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER);
130186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1302380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->bculr)
13034a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0x800, BCULR);	/* Burst sycle set */
1304b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
13054a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR);
130686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1307380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!mdp->cd->no_trimd)
13084a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, 0, TRIMD);
130986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1310b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Recv frame limit set register */
1311fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda	sh_eth_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN,
1312fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda		     RFLR);
131386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
13144a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
1315525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (start)
1316525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
131786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
131886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PAUSE Prohibition */
13194a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
132086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
132186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
13224a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, val, ECMR);
1323b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
1324380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->set_rate)
1325380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		mdp->cd->set_rate(ndev);
1326380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1327b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* E-MAC Status Register clear */
13284a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
1329b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
1330b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* E-MAC Interrupt Enable register */
1331525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (start)
1332525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
133386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
133486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Set MAC address */
133586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	update_mac_address(ndev);
133686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
133786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* mask reset */
1338380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->apr)
13394a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, APR_AP, APR);
1340380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->mpr)
13414a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, MPR_MP, MPR);
1342380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->tpauser)
13434a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
1344b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
1345525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (start) {
1346525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Setting the Rx mode will start the Rx process. */
1347525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, EDRRR_R, EDRRR);
134886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1349525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		netif_start_queue(ndev);
1350525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
135186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
13525cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsuout:
135386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
135486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
135586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
135686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* free Tx skb function */
135786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_txfree(struct net_device *ndev)
135886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
135986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
136086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_txdesc *txdesc;
136186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int freeNum = 0;
136286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int entry = 0;
136386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
136486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
1365525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		entry = mdp->dirty_tx % mdp->num_tx_ring;
136686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc = &mdp->tx_ring[entry];
136771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
136886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			break;
136986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Free the original skb. */
137086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->tx_skbuff[entry]) {
137131fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda			dma_unmap_single(&ndev->dev, txdesc->addr,
137231fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda					 txdesc->buffer_length, DMA_TO_DEVICE);
137386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
137486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->tx_skbuff[entry] = NULL;
137586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			freeNum++;
137686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
137771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status = cpu_to_edmac(mdp, TD_TFP);
1378525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		if (entry >= mdp->num_tx_ring - 1)
137971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato			txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
138086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1381bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_packets++;
1382bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_bytes += txdesc->buffer_length;
138386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
138486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return freeNum;
138586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
138686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
138786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Packet receive function */
1388a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimodastatic int sh_eth_rx(struct net_device *ndev, u32 intr_status)
138986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
139086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
139186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_rxdesc *rxdesc;
139286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1393525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int entry = mdp->cur_rx % mdp->num_rx_ring;
1394525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx;
139586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sk_buff *skb;
139686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u16 pkt_len = 0;
1397380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	u32 desc_status;
139886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
139986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	rxdesc = &mdp->rx_ring[entry];
140071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
140171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		desc_status = edmac_to_cpu(mdp, rxdesc->status);
140286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		pkt_len = rxdesc->frame_length;
140386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
140473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda#if defined(CONFIG_ARCH_R8A7740)
140573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda		desc_status >>= 16;
140673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda#endif
140773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda
140886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (--boguscnt < 0)
140986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			break;
141086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
141186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (!(desc_status & RDFEND))
1412bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_length_errors++;
141386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
141486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
141586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				   RD_RFS5 | RD_RFS6 | RD_RFS10)) {
1416bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_errors++;
141786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS1)
1418bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_crc_errors++;
141986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS2)
1420bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_frame_errors++;
142186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS3)
1422bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_length_errors++;
142386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS4)
1424bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_length_errors++;
142586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS6)
1426bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_missed_errors++;
142786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (desc_status & RD_RFS10)
1428bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet				ndev->stats.rx_over_errors++;
142986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		} else {
1430380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			if (!mdp->cd->hw_swap)
1431380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				sh_eth_soft_swap(
1432380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda					phys_to_virt(ALIGN(rxdesc->addr, 4)),
1433380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda					pkt_len + 2);
143486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			skb = mdp->rx_skbuff[entry];
143586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->rx_skbuff[entry] = NULL;
1436503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm			if (mdp->cd->rpadir)
1437503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm				skb_reserve(skb, NET_IP_ALIGN);
143886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			skb_put(skb, pkt_len);
143986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			skb->protocol = eth_type_trans(skb, ndev);
144086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			netif_rx(skb);
1441bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_packets++;
1442bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_bytes += pkt_len;
144386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
144471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
1445525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		entry = (++mdp->cur_rx) % mdp->num_rx_ring;
1446862df49750e7ca9369c04d8d8105b3cc5d976e0dYoshihiro Shimoda		rxdesc = &mdp->rx_ring[entry];
144786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
144886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
144986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Refill the Rx ring buffers. */
145086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
1451525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		entry = mdp->dirty_rx % mdp->num_rx_ring;
145286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc = &mdp->rx_ring[entry];
1453b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu		/* The size of the buffer is 16 byte boundary. */
14540029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
1455b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
145686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->rx_skbuff[entry] == NULL) {
1457dae2e9f430c46c29e3f771110094bd3da3625aa4Pradeep A. Dalvi			skb = netdev_alloc_skb(ndev, mdp->rx_buf_sz);
145886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->rx_skbuff[entry] = skb;
145986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			if (skb == NULL)
146086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				break;	/* Better luck next round. */
1461bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			dma_map_single(&ndev->dev, skb->data, mdp->rx_buf_sz,
1462e88aae7bb1dc50457489d1d7c81dcf4db23ccf94Yoshihiro Shimoda					DMA_FROM_DEVICE);
1463380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			sh_eth_set_receive_align(skb);
1464380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1465bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet			skb_checksum_none_assert(skb);
14660029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda			rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
146786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
1468525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		if (entry >= mdp->num_rx_ring - 1)
146986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			rxdesc->status |=
147071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato				cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
147186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		else
147286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			rxdesc->status |=
147371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato				cpu_to_edmac(mdp, RD_RACT | RD_RFP);
147486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
147586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
147686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Restart Rx engine if stopped. */
147786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* If we don't need to check status, don't. -KDU */
147879fba9f51755c704c0a7d7b7f0df10874dc0a744Yoshihiro Shimoda	if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
1479a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda		/* fix the values for the next receiving if RDE is set */
1480a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda		if (intr_status & EESR_RDE)
1481a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda			mdp->cur_rx = mdp->dirty_rx =
1482a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda				(sh_eth_read(ndev, RDFAR) -
1483a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda				 sh_eth_read(ndev, RDLAR)) >> 4;
14844a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, EDRRR_R, EDRRR);
148579fba9f51755c704c0a7d7b7f0df10874dc0a744Yoshihiro Shimoda	}
148686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
148786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
148886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
148986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
14904a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_rcv_snd_disable(struct net_device *ndev)
1491dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1492dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* disable tx and rx */
14934a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
14944a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		~(ECMR_RE | ECMR_TE), ECMR);
1495dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1496dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
14974a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_rcv_snd_enable(struct net_device *ndev)
1498dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1499dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* enable tx and rx */
15004a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) |
15014a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		(ECMR_RE | ECMR_TE), ECMR);
1502dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1503dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
150486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* error control function */
150586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_error(struct net_device *ndev, int intr_status)
150686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
150786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
150886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 felic_stat;
1509380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	u32 link_stat;
1510380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	u32 mask;
151186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
151286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_ECI) {
15134a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		felic_stat = sh_eth_read(ndev, ECSR);
15144a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, felic_stat, ECSR);	/* clear int */
151586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (felic_stat & ECSR_ICD)
1516bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.tx_carrier_errors++;
151786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (felic_stat & ECSR_LCHNG) {
151886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			/* Link Changed */
15194923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda			if (mdp->cd->no_psr || mdp->no_ether_link) {
15201e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov				goto ignore_link;
1521380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			} else {
15224a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				link_stat = (sh_eth_read(ndev, PSR));
15234923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda				if (mdp->ether_link_active_low)
15244923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda					link_stat = ~link_stat;
1525380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			}
1526dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			if (!(link_stat & PHY_ST_LINK))
15274a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_rcv_snd_disable(ndev);
1528dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			else {
152986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				/* Link Up */
15304a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
15314a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda					  ~DMAC_M_ECI, EESIPR);
153286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				/*clear int */
15334a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_write(ndev, sh_eth_read(ndev, ECSR),
15344a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda					  ECSR);
15354a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) |
15364a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda					  DMAC_M_ECI, EESIPR);
153786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				/* enable tx and rx */
15384a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda				sh_eth_rcv_snd_enable(ndev);
153986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			}
154086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
154186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
154286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
15431e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyovignore_link:
154486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_TWB) {
154586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Write buck end. unused write back interrupt */
154686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (intr_status & EESR_TABT)	/* Transmit Abort int */
1547bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.tx_aborted_errors++;
1548dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			if (netif_msg_tx_err(mdp))
1549dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu				dev_err(&ndev->dev, "Transmit Abort\n");
155086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
155186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
155286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_RABT) {
155386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Receive Abort int */
155486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (intr_status & EESR_RFRMER) {
155586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			/* Receive Frame Overflow int */
1556bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet			ndev->stats.rx_frame_errors++;
1557dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			if (netif_msg_rx_err(mdp))
1558dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu				dev_err(&ndev->dev, "Receive Abort\n");
155986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
156086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1561380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1562dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (intr_status & EESR_TDE) {
1563dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		/* Transmit Descriptor Empty int */
1564bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_fifo_errors++;
1565dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_tx_err(mdp))
1566dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Transmit Descriptor Empty\n");
1567dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1568dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1569dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (intr_status & EESR_TFE) {
1570dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		/* FIFO under flow */
1571bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_fifo_errors++;
1572dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_tx_err(mdp))
1573dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Transmit FIFO Under flow\n");
157486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
157586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
157686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_RDE) {
157786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Receive Descriptor Empty int */
1578bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.rx_over_errors++;
157986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1580dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_rx_err(mdp))
1581dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Receive Descriptor Empty\n");
158286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1583dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
158486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (intr_status & EESR_RFE) {
158586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Receive FIFO Overflow int */
1586bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.rx_fifo_errors++;
1587dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_rx_err(mdp))
1588dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Receive FIFO Overflow\n");
1589dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1590dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1591dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) {
1592dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		/* Address Error */
1593bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_fifo_errors++;
1594dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		if (netif_msg_tx_err(mdp))
1595dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			dev_err(&ndev->dev, "Address Error\n");
159686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1597380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
1598380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
1599380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (mdp->cd->no_ade)
1600380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		mask &= ~EESR_ADE;
1601380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (intr_status & mask) {
160286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Tx error */
16034a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		u32 edtrr = sh_eth_read(ndev, EDTRR);
160486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* dmesg */
1605380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
1606380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				intr_status, mdp->cur_tx);
1607380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		dev_err(&ndev->dev, "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
160886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				mdp->dirty_tx, (u32) ndev->state, edtrr);
160986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* dirty buffer free */
161086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		sh_eth_txfree(ndev);
161186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
161286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* SH7712 BUG */
1613c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
161486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			/* tx dma start */
1615c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda			sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
161686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
161786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* wakeup */
161886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		netif_wake_queue(ndev);
161986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
162086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
162186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
162286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic irqreturn_t sh_eth_interrupt(int irq, void *netdev)
162386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
162486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct net_device *ndev = netdev;
162586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1626380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	struct sh_eth_cpu_data *cd = mdp->cd;
16270e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu	irqreturn_t ret = IRQ_NONE;
16283893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	unsigned long intr_status;
162986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
163086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_lock(&mdp->lock);
163186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16323893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	/* Get interrupt status */
16334a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	intr_status = sh_eth_read(ndev, EESR);
16343893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	/* Mask it with the interrupt mask, forcing ECI interrupt to be always
16353893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 * enabled since it's the one that  comes thru regardless of the mask,
16363893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 * and we need to fully handle it in sh_eth_error() in order to quench
16373893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 * it as it doesn't get cleared by just writing 1 to the ECI bit...
16383893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	 */
16393893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov	intr_status &= sh_eth_read(ndev, EESIPR) | DMAC_M_ECI;
164086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Clear interrupt */
16410e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu	if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
16420e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu			EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
1643380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			cd->tx_check | cd->eesr_err_check)) {
16444a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		sh_eth_write(ndev, intr_status, EESR);
16450e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu		ret = IRQ_HANDLED;
16460e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu	} else
16470e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu		goto other_irq;
164886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1649b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	if (intr_status & (EESR_FRC | /* Frame recv*/
1650b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu			EESR_RMAF | /* Multi cast address recv*/
1651b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu			EESR_RRF  | /* Bit frame recv */
1652b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu			EESR_RTLF | /* Long frame recv*/
1653b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu			EESR_RTSF | /* short frame recv */
1654b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu			EESR_PRE  | /* PHY-LSI recv error */
1655b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu			EESR_CERF)){ /* recv frame CRC error */
1656a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda		sh_eth_rx(ndev, intr_status);
1657b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	}
165886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1659b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu	/* Tx Check */
1660380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (intr_status & cd->tx_check) {
166186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		sh_eth_txfree(ndev);
166286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		netif_wake_queue(ndev);
166386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
166486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1665380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (intr_status & cd->eesr_err_check)
166686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		sh_eth_error(ndev, intr_status);
166786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16680e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsuother_irq:
166986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_unlock(&mdp->lock);
167086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16710e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu	return ret;
167286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
167386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
167486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY state control function */
167586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_adjust_link(struct net_device *ndev)
167686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
167786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
167886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct phy_device *phydev = mdp->phydev;
167986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int new_state = 0;
168086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
16813340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov	if (phydev->link) {
168286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (phydev->duplex != mdp->duplex) {
168386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			new_state = 1;
168486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->duplex = phydev->duplex;
1685380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			if (mdp->cd->set_duplex)
1686380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				mdp->cd->set_duplex(ndev);
168786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
168886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
168986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (phydev->speed != mdp->speed) {
169086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			new_state = 1;
169186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->speed = phydev->speed;
1692380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			if (mdp->cd->set_rate)
1693380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				mdp->cd->set_rate(ndev);
169486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
16953340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov		if (!mdp->link) {
169691a5615203355bb34e0b9e68e94f27f24719a74cYoshihiro Shimoda			sh_eth_write(ndev,
169791a5615203355bb34e0b9e68e94f27f24719a74cYoshihiro Shimoda				(sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR);
169886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			new_state = 1;
169986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			mdp->link = phydev->link;
17001e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov			if (mdp->cd->no_psr || mdp->no_ether_link)
17011e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov				sh_eth_rcv_snd_enable(ndev);
170286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
170386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	} else if (mdp->link) {
170486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		new_state = 1;
17053340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov		mdp->link = 0;
170686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->speed = 0;
170786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->duplex = -1;
17081e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov		if (mdp->cd->no_psr || mdp->no_ether_link)
17091e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov			sh_eth_rcv_snd_disable(ndev);
171086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
171186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1712dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (new_state && netif_msg_link(mdp))
171386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		phy_print_status(phydev);
171486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
171586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
171686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY init function */
171786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_phy_init(struct net_device *ndev)
171886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
171986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
17200a372eb91f9d507701a901c2f62ed31ca67fd66cDavid S. Miller	char phy_id[MII_BUS_ID_SIZE + 3];
172186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct phy_device *phydev = NULL;
172286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1723fb28ad35906af2f042c94e2f9c0f898ef9acfa37Kay Sievers	snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
172486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->mii_bus->id , mdp->phy_id);
172586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
17263340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov	mdp->link = 0;
172786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->speed = 0;
172886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->duplex = -1;
172986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
173086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Try connect to PHY */
1731c061b18df0f1fe3f50fe451dbbdc9ede3c19701aJoe Perches	phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
1732f9a8f83b04e0c362a2fc660dbad980d24af209fcFlorian Fainelli			     mdp->phy_interface);
173386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (IS_ERR(phydev)) {
173486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		dev_err(&ndev->dev, "phy_connect failed\n");
173586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return PTR_ERR(phydev);
173686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
1737380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
173886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	dev_info(&ndev->dev, "attached phy %i to driver %s\n",
1739380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		phydev->addr, phydev->drv->name);
174086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
174186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->phydev = phydev;
174286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
174386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
174486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
174586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
174686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY control start function */
174786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_phy_start(struct net_device *ndev)
174886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
174986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
175086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret;
175186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
175286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = sh_eth_phy_init(ndev);
175386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
175486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return ret;
175586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
175686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* reset phy - this also wakes it from PDOWN */
175786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	phy_write(mdp->phydev, MII_BMCR, BMCR_RESET);
175886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	phy_start(mdp->phydev);
175986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
176086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
176186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
176286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1763dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_get_settings(struct net_device *ndev,
1764dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			struct ethtool_cmd *ecmd)
1765dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1766dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1767dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	unsigned long flags;
1768dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int ret;
1769dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1770dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
1771dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	ret = phy_ethtool_gset(mdp->phydev, ecmd);
1772dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
1773dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1774dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return ret;
1775dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1776dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1777dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_set_settings(struct net_device *ndev,
1778dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		struct ethtool_cmd *ecmd)
1779dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1780dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1781dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	unsigned long flags;
1782dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int ret;
1783dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1784dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
1785dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1786dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* disable tx and rx */
17874a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_rcv_snd_disable(ndev);
1788dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1789dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	ret = phy_ethtool_sset(mdp->phydev, ecmd);
1790dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (ret)
1791dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		goto error_exit;
1792dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1793dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (ecmd->duplex == DUPLEX_FULL)
1794dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		mdp->duplex = 1;
1795dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	else
1796dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		mdp->duplex = 0;
1797dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1798dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (mdp->cd->set_duplex)
1799dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		mdp->cd->set_duplex(ndev);
1800dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1801dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsuerror_exit:
1802dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	mdelay(1);
1803dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1804dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* enable tx and rx */
18054a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_rcv_snd_enable(ndev);
1806dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1807dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
1808dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1809dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return ret;
1810dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1811dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1812dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_nway_reset(struct net_device *ndev)
1813dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1814dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1815dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	unsigned long flags;
1816dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int ret;
1817dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1818dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
1819dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	ret = phy_start_aneg(mdp->phydev);
1820dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
1821dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1822dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return ret;
1823dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1824dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1825dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic u32 sh_eth_get_msglevel(struct net_device *ndev)
1826dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1827dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1828dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	return mdp->msg_enable;
1829dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1830dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1831dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_set_msglevel(struct net_device *ndev, u32 value)
1832dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1833dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1834dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	mdp->msg_enable = value;
1835dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1836dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1837dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic const char sh_eth_gstrings_stats[][ETH_GSTRING_LEN] = {
1838dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	"rx_current", "tx_current",
1839dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	"rx_dirty", "tx_dirty",
1840dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu};
1841dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#define SH_ETH_STATS_LEN  ARRAY_SIZE(sh_eth_gstrings_stats)
1842dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1843dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_get_sset_count(struct net_device *netdev, int sset)
1844dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1845dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	switch (sset) {
1846dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	case ETH_SS_STATS:
1847dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		return SH_ETH_STATS_LEN;
1848dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	default:
1849dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		return -EOPNOTSUPP;
1850dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1851dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1852dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1853dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_get_ethtool_stats(struct net_device *ndev,
1854dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			struct ethtool_stats *stats, u64 *data)
1855dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1856dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
1857dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	int i = 0;
1858dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1859dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* device-specific stats */
1860dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->cur_rx;
1861dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->cur_tx;
1862dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->dirty_rx;
1863dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	data[i++] = mdp->dirty_tx;
1864dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1865dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1866dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
1867dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{
1868dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	switch (stringset) {
1869dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	case ETH_SS_STATS:
1870dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		memcpy(data, *sh_eth_gstrings_stats,
1871dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu					sizeof(sh_eth_gstrings_stats));
1872dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		break;
1873dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	}
1874dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}
1875dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
1876525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic void sh_eth_get_ringparam(struct net_device *ndev,
1877525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda				 struct ethtool_ringparam *ring)
1878525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda{
1879525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
1880525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1881525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->rx_max_pending = RX_RING_MAX;
1882525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->tx_max_pending = TX_RING_MAX;
1883525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->rx_pending = mdp->num_rx_ring;
1884525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ring->tx_pending = mdp->num_tx_ring;
1885525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda}
1886525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1887525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic int sh_eth_set_ringparam(struct net_device *ndev,
1888525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda				struct ethtool_ringparam *ring)
1889525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda{
1890525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
1891525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	int ret;
1892525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1893525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ring->tx_pending > TX_RING_MAX ||
1894525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	    ring->rx_pending > RX_RING_MAX ||
1895525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	    ring->tx_pending < TX_RING_MIN ||
1896525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	    ring->rx_pending < RX_RING_MIN)
1897525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return -EINVAL;
1898525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ring->rx_mini_pending || ring->rx_jumbo_pending)
1899525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return -EINVAL;
1900525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1901525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (netif_running(ndev)) {
1902525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		netif_tx_disable(ndev);
1903525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Disable interrupts by clearing the interrupt mask. */
1904525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, 0x0000, EESIPR);
1905525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Stop the chip's Tx and Rx processes. */
1906525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, 0, EDTRR);
1907525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, 0, EDRRR);
1908525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		synchronize_irq(ndev->irq);
1909525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1910525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1911525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	/* Free all the skbuffs in the Rx queue. */
1912525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	sh_eth_ring_free(ndev);
1913525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	/* Free DMA buffer */
1914525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	sh_eth_free_dma_buffer(mdp);
1915525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1916525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	/* Set new parameters */
1917525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_rx_ring = ring->rx_pending;
1918525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_tx_ring = ring->tx_pending;
1919525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1920525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ret = sh_eth_ring_init(ndev);
1921525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ret < 0) {
1922525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		dev_err(&ndev->dev, "%s: sh_eth_ring_init failed.\n", __func__);
1923525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return ret;
1924525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1925525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ret = sh_eth_dev_init(ndev, false);
1926525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (ret < 0) {
1927525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		dev_err(&ndev->dev, "%s: sh_eth_dev_init failed.\n", __func__);
1928525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		return ret;
1929525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1930525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1931525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (netif_running(ndev)) {
1932525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
1933525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		/* Setting the Rx mode will start the Rx process. */
1934525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		sh_eth_write(ndev, EDRRR_R, EDRRR);
1935525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda		netif_wake_queue(ndev);
1936525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	}
1937525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
1938525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	return 0;
1939525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda}
1940525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda
19419b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemmingerstatic const struct ethtool_ops sh_eth_ethtool_ops = {
1942dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_settings	= sh_eth_get_settings,
1943dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.set_settings	= sh_eth_set_settings,
19449b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemminger	.nway_reset	= sh_eth_nway_reset,
1945dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_msglevel	= sh_eth_get_msglevel,
1946dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.set_msglevel	= sh_eth_set_msglevel,
19479b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemminger	.get_link	= ethtool_op_get_link,
1948dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_strings	= sh_eth_get_strings,
1949dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_ethtool_stats  = sh_eth_get_ethtool_stats,
1950dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	.get_sset_count     = sh_eth_get_sset_count,
1951525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	.get_ringparam	= sh_eth_get_ringparam,
1952525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	.set_ringparam	= sh_eth_set_ringparam,
1953dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu};
1954dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu
195586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* network device open function */
195686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_open(struct net_device *ndev)
195786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
195886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret = 0;
195986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
196086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
1961bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_get_sync(&mdp->pdev->dev);
1962bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
1963a0607fd3a25ba1848a63a0d925e36d914735ab47Joe Perches	ret = request_irq(ndev->irq, sh_eth_interrupt,
1964f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda#if defined(CONFIG_CPU_SUBTYPE_SH7763) || \
1965dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	defined(CONFIG_CPU_SUBTYPE_SH7764) || \
1966dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	defined(CONFIG_CPU_SUBTYPE_SH7757)
19670e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu				IRQF_SHARED,
19680e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu#else
19690e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu				0,
19700e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu#endif
19710e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu				ndev->name, ndev);
197286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret) {
1973380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		dev_err(&ndev->dev, "Can not assign IRQ number\n");
197486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return ret;
197586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
197686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
197786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Descriptor set */
197886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = sh_eth_ring_init(ndev);
197986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
198086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_irq;
198186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
198286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* device init */
1983525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	ret = sh_eth_dev_init(ndev, true);
198486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
198586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_irq;
198686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
198786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PHY control start*/
198886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = sh_eth_phy_start(ndev);
198986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
199086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_irq;
199186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
199286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
199386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
199486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_free_irq:
199586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_irq(ndev->irq, ndev);
1996bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_put_sync(&mdp->pdev->dev);
199786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
199886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
199986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
200086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Timeout function */
200186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_tx_timeout(struct net_device *ndev)
200286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
200386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
200486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_rxdesc *rxdesc;
200586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int i;
200686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
200786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	netif_stop_queue(ndev);
200886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2009dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	if (netif_msg_timer(mdp))
2010dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu		dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x,"
20114a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	       " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR));
201286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
201386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* tx_errors count up */
2014bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.tx_errors++;
201586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
201686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free all the skbuffs in the Rx queue. */
2017525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_rx_ring; i++) {
201886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc = &mdp->rx_ring[i];
201986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc->status = 0;
202086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		rxdesc->addr = 0xBADF00D0;
202186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->rx_skbuff[i])
202286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			dev_kfree_skb(mdp->rx_skbuff[i]);
202386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->rx_skbuff[i] = NULL;
202486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
2025525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	for (i = 0; i < mdp->num_tx_ring; i++) {
202686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (mdp->tx_skbuff[i])
202786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			dev_kfree_skb(mdp->tx_skbuff[i]);
202886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->tx_skbuff[i] = NULL;
202986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
203086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
203186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* device init */
2032525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	sh_eth_dev_init(ndev, true);
203386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
203486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
203586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Packet transmit function */
203686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
203786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
203886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
203986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_txdesc *txdesc;
204086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	u32 entry;
2041fb5e2f9b9410a4362897d12dc1ed4f7cec1b0d45Nobuhiro Iwamatsu	unsigned long flags;
204286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
204386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_lock_irqsave(&mdp->lock, flags);
2044525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
204586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		if (!sh_eth_txfree(ndev)) {
2046dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu			if (netif_msg_tx_queued(mdp))
2047dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu				dev_warn(&ndev->dev, "TxFD exhausted.\n");
204886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			netif_stop_queue(ndev);
204986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu			spin_unlock_irqrestore(&mdp->lock, flags);
20505b548140225c6bbbbd560551dd1048b2c0ce58bePatrick McHardy			return NETDEV_TX_BUSY;
205186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		}
205286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
205386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_unlock_irqrestore(&mdp->lock, flags);
205486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2055525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	entry = mdp->cur_tx % mdp->num_tx_ring;
205686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->tx_skbuff[entry] = skb;
205786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	txdesc = &mdp->tx_ring[entry];
205886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* soft swap. */
2059380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	if (!mdp->cd->hw_swap)
2060380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
2061380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda				 skb->len + 2);
206231fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda	txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len,
206331fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda				      DMA_TO_DEVICE);
206486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (skb->len < ETHERSMALL)
206586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc->buffer_length = ETHERSMALL;
206686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
206786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		txdesc->buffer_length = skb->len;
206886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2069525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	if (entry >= mdp->num_tx_ring - 1)
207071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
207186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	else
207271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato		txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
207386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
207486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->cur_tx++;
207586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2076c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
2077c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
2078b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu
20796ed106549d17474ca17a16057f4c0ed4eba5a7caPatrick McHardy	return NETDEV_TX_OK;
208086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
208186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
208286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* device close function */
208386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_close(struct net_device *ndev)
208486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
208586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
208686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
208786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	netif_stop_queue(ndev);
208886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
208986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Disable interrupts by clearing the interrupt mask. */
20904a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0x0000, EESIPR);
209186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
209286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Stop the chip's Tx and Rx processes. */
20934a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, EDTRR);
20944a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, EDRRR);
209586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
209686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PHY Disconnect */
209786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (mdp->phydev) {
209886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		phy_stop(mdp->phydev);
209986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		phy_disconnect(mdp->phydev);
210086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
210186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
210286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_irq(ndev->irq, ndev);
210386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
210486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Free all the skbuffs in the Rx queue. */
210586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	sh_eth_ring_free(ndev);
210686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
210786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* free DMA buffer */
210891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda	sh_eth_free_dma_buffer(mdp);
210986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2110bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_put_sync(&mdp->pdev->dev);
2111bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
211286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
211386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
211486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
211586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
211686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
211786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
211886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2119bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_get_sync(&mdp->pdev->dev);
2120bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2121bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR);
21224a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, TROCR);	/* (write clear) */
2123bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.collisions += sh_eth_read(ndev, CDCR);
21244a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, CDCR);	/* (write clear) */
2125bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
21264a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_write(ndev, 0, LCCR);	/* (write clear) */
2127c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (sh_eth_is_gether(mdp)) {
2128bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
2129c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, 0, CERCR);	/* (write clear) */
2130bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
2131c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, 0, CEECR);	/* (write clear) */
2132c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	} else {
2133bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet		ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
2134c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_write(ndev, 0, CNDCR);	/* (write clear) */
2135c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	}
2136bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_put_sync(&mdp->pdev->dev);
2137bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2138bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet	return &ndev->stats;
213986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
214086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2141bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet/* ioctl to device function */
214286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
214386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu				int cmd)
214486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
214586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
214686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct phy_device *phydev = mdp->phydev;
214786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
214886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!netif_running(ndev))
214986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return -EINVAL;
215086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
215186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!phydev)
215286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		return -ENODEV;
215386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
215428b041139e344ecd0f144d6205b004ae354cfa1eRichard Cochran	return phy_mii_ioctl(phydev, rq, cmd);
215586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
215686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2157380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#if defined(SH_ETH_HAS_TSU)
21586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda/* For TSU_POSTn. Please refer to the manual about this (strange) bitfields */
21596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void *sh_eth_tsu_get_post_reg_offset(struct sh_eth_private *mdp,
21606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					    int entry)
21616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
21626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return sh_eth_tsu_get_offset(mdp, TSU_POST1) + (entry / 8 * 4);
21636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
21646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
21656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic u32 sh_eth_tsu_get_post_mask(int entry)
21666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
21676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0x0f << (28 - ((entry % 8) * 4));
21686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
21696743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
21706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic u32 sh_eth_tsu_get_post_bit(struct sh_eth_private *mdp, int entry)
21716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
21726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return (0x08 >> (mdp->port << 1)) << (28 - ((entry % 8) * 4));
21736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
21746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
21756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_enable_cam_entry_post(struct net_device *ndev,
21766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					     int entry)
21776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
21786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
21796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 tmp;
21806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset;
21816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
21826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry);
21836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	tmp = ioread32(reg_offset);
21846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(tmp | sh_eth_tsu_get_post_bit(mdp, entry), reg_offset);
21856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
21866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
21876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic bool sh_eth_tsu_disable_cam_entry_post(struct net_device *ndev,
21886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					      int entry)
21896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
21906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
21916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 post_mask, ref_mask, tmp;
21926743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset;
21936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
21946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry);
21956743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	post_mask = sh_eth_tsu_get_post_mask(entry);
21966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	ref_mask = sh_eth_tsu_get_post_bit(mdp, entry) & ~post_mask;
21976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
21986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	tmp = ioread32(reg_offset);
21996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(tmp & ~post_mask, reg_offset);
22006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22016743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	/* If other port enables, the function returns "true" */
22026743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return tmp & ref_mask;
22036743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22046743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22056743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_busy(struct net_device *ndev)
22066743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22076743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int timeout = SH_ETH_TSU_TIMEOUT_MS * 100;
22086743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
22096743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22106743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	while ((sh_eth_tsu_read(mdp, TSU_ADSBSY) & TSU_ADSBSY_0)) {
22116743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		udelay(10);
22126743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		timeout--;
22136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (timeout <= 0) {
22146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			dev_err(&ndev->dev, "%s: timeout\n", __func__);
22156743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return -ETIMEDOUT;
22166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		}
22176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
22186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
22206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_write_entry(struct net_device *ndev, void *reg,
22236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				  const u8 *addr)
22246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 val;
22266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3];
22286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(val, reg);
22296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (sh_eth_tsu_busy(ndev) < 0)
22306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return -EBUSY;
22316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = addr[4] << 8 | addr[5];
22336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	iowrite32(val, reg + 4);
22346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (sh_eth_tsu_busy(ndev) < 0)
22356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return -EBUSY;
22366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
22386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_read_entry(void *reg, u8 *addr)
22416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 val;
22436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = ioread32(reg);
22456743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[0] = (val >> 24) & 0xff;
22466743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[1] = (val >> 16) & 0xff;
22476743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[2] = (val >> 8) & 0xff;
22486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[3] = val & 0xff;
22496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	val = ioread32(reg + 4);
22506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[4] = (val >> 8) & 0xff;
22516743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	addr[5] = val & 0xff;
22526743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22546743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_find_entry(struct net_device *ndev, const u8 *addr)
22566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
22586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
22596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i;
22606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 c_addr[ETH_ALEN];
22616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) {
22636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_read_entry(reg_offset, c_addr);
22646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (memcmp(addr, c_addr, ETH_ALEN) == 0)
22656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return i;
22666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
22676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return -ENOENT;
22696743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_find_empty(struct net_device *ndev)
22726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 blank[ETH_ALEN];
22746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int entry;
22756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	memset(blank, 0, sizeof(blank));
22776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	entry = sh_eth_tsu_find_entry(ndev, blank);
22786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return (entry < 0) ? -ENOMEM : entry;
22796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_disable_cam_entry_table(struct net_device *ndev,
22826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					      int entry)
22836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
22846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
22856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
22866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int ret;
22876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 blank[ETH_ALEN];
22886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) &
22906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			 ~(1 << (31 - entry)), TSU_TEN);
22916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22926743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	memset(blank, 0, sizeof(blank));
22936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	ret = sh_eth_tsu_write_entry(ndev, reg_offset + entry * 8, blank);
22946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (ret < 0)
22956743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return ret;
22966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
22976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
22986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
22996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_add_entry(struct net_device *ndev, const u8 *addr)
23006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23016743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23026743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
23036743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i, ret;
23046743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23056743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (!mdp->cd->tsu)
23066743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return 0;
23076743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23086743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	i = sh_eth_tsu_find_entry(ndev, addr);
23096743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (i < 0) {
23106743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* No entry found, create one */
23116743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		i = sh_eth_tsu_find_empty(ndev);
23126743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (i < 0)
23136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return -ENOMEM;
23146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ret = sh_eth_tsu_write_entry(ndev, reg_offset + i * 8, addr);
23156743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (ret < 0)
23166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return ret;
23176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Enable the entry */
23196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) |
23206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				 (1 << (31 - i)), TSU_TEN);
23216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
23226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	/* Entry found or created, enable POST */
23246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	sh_eth_tsu_enable_cam_entry_post(ndev, i);
23256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
23276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_del_entry(struct net_device *ndev, const u8 *addr)
23306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i, ret;
23336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (!mdp->cd->tsu)
23356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return 0;
23366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	i = sh_eth_tsu_find_entry(ndev, addr);
23386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (i) {
23396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Entry found */
23406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (sh_eth_tsu_disable_cam_entry_post(ndev, i))
23416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			goto done;
23426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Disable the entry if both ports was disabled */
23446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ret = sh_eth_tsu_disable_cam_entry_table(ndev, i);
23456743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (ret < 0)
23466743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return ret;
23476743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
23486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodadone:
23496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
23506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23516743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23526743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_purge_all(struct net_device *ndev)
23536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23546743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i, ret;
23566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
23586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return 0;
23596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) {
23616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (sh_eth_tsu_disable_cam_entry_post(ndev, i))
23626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			continue;
23636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		/* Disable the entry if both ports was disabled */
23656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ret = sh_eth_tsu_disable_cam_entry_table(ndev, i);
23666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (ret < 0)
23676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			return ret;
23686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
23696743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	return 0;
23716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_purge_mcast(struct net_device *ndev)
23746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{
23756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u8 addr[ETH_ALEN];
23776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0);
23786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int i;
23796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
23816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		return;
23826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) {
23846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_read_entry(reg_offset, addr);
23856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		if (is_multicast_ether_addr(addr))
23866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			sh_eth_tsu_del_entry(ndev, addr);
23876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
23886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda}
23896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
239086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Multicast reception directions set */
239186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_set_multicast_list(struct net_device *ndev)
239286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
23936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
23946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	u32 ecmr_bits;
23956743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	int mcast_all = 0;
23966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	unsigned long flags;
23976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
23986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	spin_lock_irqsave(&mdp->lock, flags);
23996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	/*
24006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	 * Initial condition is MCT = 1, PRM = 0.
24016743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	 * Depending on ndev->flags, set PRM or clear MCT
24026743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	 */
24036743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT;
24046743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24056743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (!(ndev->flags & IFF_MULTICAST)) {
24066743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_purge_mcast(ndev);
24076743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		mcast_all = 1;
24086743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
24096743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	if (ndev->flags & IFF_ALLMULTI) {
24106743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_purge_mcast(ndev);
24116743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ecmr_bits &= ~ECMR_MCT;
24126743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		mcast_all = 1;
24136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	}
24146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
241586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ndev->flags & IFF_PROMISC) {
24166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		sh_eth_tsu_purge_all(ndev);
24176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ecmr_bits = (ecmr_bits & ~ECMR_MCT) | ECMR_PRM;
24186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	} else if (mdp->cd->tsu) {
24196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		struct netdev_hw_addr *ha;
24206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		netdev_for_each_mc_addr(ha, ndev) {
24216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			if (mcast_all && is_multicast_ether_addr(ha->addr))
24226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				continue;
24236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			if (sh_eth_tsu_add_entry(ndev, ha->addr) < 0) {
24256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				if (!mcast_all) {
24266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					sh_eth_tsu_purge_mcast(ndev);
24276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					ecmr_bits &= ~ECMR_MCT;
24286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda					mcast_all = 1;
24296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda				}
24306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda			}
24316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		}
243286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	} else {
243386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		/* Normal, unicast/broadcast-only mode. */
24346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT;
243586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
24366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	/* update the ethernet mode */
24386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	sh_eth_write(ndev, ecmr_bits, ECMR);
24396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda
24406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda	spin_unlock_irqrestore(&mdp->lock, flags);
244186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
244271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
244371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimodastatic int sh_eth_get_vtag_index(struct sh_eth_private *mdp)
244471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{
244571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (!mdp->port)
244671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return TSU_VTAG0;
244771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	else
244871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return TSU_VTAG1;
244971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda}
245071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
245180d5c3689b886308247da295a228a54df49a44f6Patrick McHardystatic int sh_eth_vlan_rx_add_vid(struct net_device *ndev,
245280d5c3689b886308247da295a228a54df49a44f6Patrick McHardy				  __be16 proto, u16 vid)
245371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{
245471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
245571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	int vtag_reg_index = sh_eth_get_vtag_index(mdp);
245671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
245771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
245871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return -EPERM;
245971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
246071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	/* No filtering if vid = 0 */
246171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (!vid)
246271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return 0;
246371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
246471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	mdp->vlan_num_ids++;
246571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
246671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	/*
246771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	 * The controller has one VLAN tag HW filter. So, if the filter is
246871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	 * already enabled, the driver disables it and the filte
246971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	 */
247071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (mdp->vlan_num_ids > 1) {
247171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		/* disable VLAN filter */
247271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, vtag_reg_index);
247371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return 0;
247471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	}
247571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
247671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	sh_eth_tsu_write(mdp, TSU_VTAG_ENABLE | (vid & TSU_VTAG_VID_MASK),
247771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda			 vtag_reg_index);
247871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
247971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	return 0;
248071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda}
248171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
248280d5c3689b886308247da295a228a54df49a44f6Patrick McHardystatic int sh_eth_vlan_rx_kill_vid(struct net_device *ndev,
248380d5c3689b886308247da295a228a54df49a44f6Patrick McHardy				   __be16 proto, u16 vid)
248471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{
248571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	struct sh_eth_private *mdp = netdev_priv(ndev);
248671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	int vtag_reg_index = sh_eth_get_vtag_index(mdp);
248771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
248871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (unlikely(!mdp->cd->tsu))
248971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return -EPERM;
249071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
249171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	/* No filtering if vid = 0 */
249271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	if (!vid)
249371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda		return 0;
249471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
249571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	mdp->vlan_num_ids--;
249671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, vtag_reg_index);
249771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda
249871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	return 0;
249971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda}
25004986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda#endif /* SH_ETH_HAS_TSU */
250186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
250286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* SuperH's TSU register init function */
25034a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_tsu_init(struct sh_eth_private *mdp)
250486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
25054a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWEN0);	/* Disable forward(0->1) */
25064a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWEN1);	/* Disable forward(1->0) */
25074a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FCM);	/* forward fifo 3k-3k */
25084a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL0);
25094a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL1);
25104a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_PRISL0);
25114a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_PRISL1);
25124a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
25134a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
25144a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
2515c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	if (sh_eth_is_gether(mdp)) {
2516c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAG0);	/* Disable QTAG(0->1) */
2517c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAG1);	/* Disable QTAG(1->0) */
2518c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	} else {
2519c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);	/* Disable QTAG(0->1) */
2520c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda		sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);	/* Disable QTAG(1->0) */
2521c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda	}
25224a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWSR);	/* all interrupt status clear */
25234a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_FWINMK);	/* Disable all interrupt */
25244a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_TEN);	/* Disable all CAM entry */
25254a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST1);	/* Disable CAM entry [ 0- 7] */
25264a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST2);	/* Disable CAM entry [ 8-15] */
25274a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST3);	/* Disable CAM entry [16-23] */
25284a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	sh_eth_tsu_write(mdp, 0, TSU_POST4);	/* Disable CAM entry [24-31] */
252986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
253086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
253186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDIO bus release function */
253286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_mdio_release(struct net_device *ndev)
253386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
253486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
253586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
253686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* unregister mdio bus */
253786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdiobus_unregister(bus);
253886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
253986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* remove mdio bus info from net_device */
254086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	dev_set_drvdata(&ndev->dev, NULL);
254186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
254286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* free bitbang info */
254386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_mdio_bitbang(bus);
254486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
254586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
254686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
254786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
254886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDIO bus init function */
2549b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimodastatic int sh_mdio_init(struct net_device *ndev, int id,
2550b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda			struct sh_eth_plat_data *pd)
255186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
255286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	int ret, i;
255386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct bb_info *bitbang;
255486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct sh_eth_private *mdp = netdev_priv(ndev);
255586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
255686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* create bit control struct for PHY */
2557d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	bitbang = devm_kzalloc(&ndev->dev, sizeof(struct bb_info),
2558d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov			       GFP_KERNEL);
255986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!bitbang) {
256086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
256186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out;
256286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
256386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
256486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* bitbang init */
2565ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	bitbang->addr = mdp->addr + mdp->reg_offset[PIR];
2566b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	bitbang->set_gate = pd->set_mdio_gate;
2567dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mdi_msk = PIR_MDI;
2568dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mdo_msk = PIR_MDO;
2569dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mmd_msk = PIR_MMD;
2570dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov	bitbang->mdc_msk = PIR_MDC;
257186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	bitbang->ctrl.ops = &bb_ops;
257286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2573c2e07b3a9ced33dd92597201be3931be8ea57ed6Stefan Weil	/* MII controller setting */
257486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
257586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->mii_bus) {
257686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
2577d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		goto out;
257886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
257986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
258086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Hook up MII support for ethtool */
258186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp->mii_bus->name = "sh_mii";
258218ee49ddb0d242ed1d0e273038d5e4f6de7379d3Lennert Buytenhek	mdp->mii_bus->parent = &ndev->dev;
25835278fb547076ad6768d16c8b4df45c086470c163Florian Fainelli	snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
258434aa6f1400810890636ba0b170effbfa71eacec7Nobuhiro Iwamatsu		mdp->pdev->name, id);
258586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
258686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* PHY IRQ */
2587d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	mdp->mii_bus->irq = devm_kzalloc(&ndev->dev,
2588d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov					 sizeof(int) * PHY_MAX_ADDR,
2589d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov					 GFP_KERNEL);
259086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!mdp->mii_bus->irq) {
259186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
259286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_free_bus;
259386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
259486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
259586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	for (i = 0; i < PHY_MAX_ADDR; i++)
259686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		mdp->mii_bus->irq[i] = PHY_POLL;
259786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
25988f6352f2b5aecd4b0af5ef31361af1146f9528d6YOSHIFUJI Hideaki / 吉藤英明	/* register mdio bus */
259986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = mdiobus_register(mdp->mii_bus);
260086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
2601d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		goto out_free_bus;
260286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
260386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	dev_set_drvdata(&ndev->dev, mdp->mii_bus);
260486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
260586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
260686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
260786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_free_bus:
2608298cf9beb9679522de995e249eccbd82f7c51999Lennert Buytenhek	free_mdio_bitbang(mdp->mii_bus);
260986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
261086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout:
261186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
261286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
261386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
26144a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic const u16 *sh_eth_get_register_offset(int register_type)
26154a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda{
26164a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	const u16 *reg_offset = NULL;
26174a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda
26184a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	switch (register_type) {
26194a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	case SH_ETH_REG_GIGABIT:
26204a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		reg_offset = sh_eth_offset_gigabit;
26214a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
2622a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov	case SH_ETH_REG_FAST_RCAR:
2623a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		reg_offset = sh_eth_offset_fast_rcar;
2624a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov		break;
26254a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	case SH_ETH_REG_FAST_SH4:
26264a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		reg_offset = sh_eth_offset_fast_sh4;
26274a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
26284a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	case SH_ETH_REG_FAST_SH3_SH2:
26294a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		reg_offset = sh_eth_offset_fast_sh3_sh2;
26304a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
26314a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	default:
263214c3326a111b948cabc35d523a43a1e6663f6091Nobuhiro Iwamatsu		pr_err("Unknown register type (%d)\n", register_type);
26334a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda		break;
26344a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	}
26354a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda
26364a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	return reg_offset;
26374a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda}
26384a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda
2639ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalovstatic const struct net_device_ops sh_eth_netdev_ops = {
2640ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_open		= sh_eth_open,
2641ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_stop		= sh_eth_close,
2642ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_start_xmit		= sh_eth_start_xmit,
2643ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_get_stats		= sh_eth_get_stats,
2644380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#if defined(SH_ETH_HAS_TSU)
2645afc4b13df143122f99a0eb10bfefb216c2806de0Jiri Pirko	.ndo_set_rx_mode	= sh_eth_set_multicast_list,
264671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	.ndo_vlan_rx_add_vid	= sh_eth_vlan_rx_add_vid,
264771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda	.ndo_vlan_rx_kill_vid	= sh_eth_vlan_rx_kill_vid,
2648380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda#endif
2649ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_tx_timeout		= sh_eth_tx_timeout,
2650ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_do_ioctl		= sh_eth_do_ioctl,
2651ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_validate_addr	= eth_validate_addr,
2652ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_set_mac_address	= eth_mac_addr,
2653ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	.ndo_change_mtu		= eth_change_mtu,
2654ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov};
2655ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov
265686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_drv_probe(struct platform_device *pdev)
265786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
26589c38657cfcb739b7dc4ce9065a85b4f0c195bef8Kuninori Morimoto	int ret, devno = 0;
265986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct resource *res;
266086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct net_device *ndev = NULL;
2661ec0d75518cb06261f1823fa2713fe52b9b26455eKuninori Morimoto	struct sh_eth_private *mdp = NULL;
2662564044b0928d46a87774c246ae80cb3cead9264dSergei Shtylyov	struct sh_eth_plat_data *pd = pdev->dev.platform_data;
266386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
266486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* get base addr */
266586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
266686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (unlikely(res == NULL)) {
266786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		dev_err(&pdev->dev, "invalid resource\n");
266886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -EINVAL;
266986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out;
267086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
267186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
267286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev = alloc_etherdev(sizeof(struct sh_eth_private));
267386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (!ndev) {
267486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENOMEM;
267586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out;
267686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
267786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
267886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* The sh Ether-specific entries in the device structure. */
267986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev->base_addr = res->start;
268086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	devno = pdev->id;
268186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (devno < 0)
268286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		devno = 0;
268386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
268486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev->dma = -1;
2685cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin	ret = platform_get_irq(pdev, 0);
2686cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin	if (ret < 0) {
268786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		ret = -ENODEV;
268886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_release;
268986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
2690cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin	ndev->irq = ret;
269186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
269286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	SET_NETDEV_DEV(ndev, &pdev->dev);
269386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
269486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* Fill in the fields of the device structure with ethernet values. */
269586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ether_setup(ndev);
269686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
269786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	mdp = netdev_priv(ndev);
2698525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_tx_ring = TX_RING_SIZE;
2699525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda	mdp->num_rx_ring = RX_RING_SIZE;
2700d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	mdp->addr = devm_ioremap_resource(&pdev->dev, res);
2701d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov	if (IS_ERR(mdp->addr)) {
2702d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		ret = PTR_ERR(mdp->addr);
2703ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda		goto out_release;
2704ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda	}
2705ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda
270686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	spin_lock_init(&mdp->lock);
2707bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	mdp->pdev = pdev;
2708bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_enable(&pdev->dev);
2709bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_resume(&pdev->dev);
271086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
271186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* get PHY ID */
271271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	mdp->phy_id = pd->phy;
2713e47c90523484518aac30498150e427d824ace705Yoshihiro Shimoda	mdp->phy_interface = pd->phy_interface;
271471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	/* EDMAC endian */
271571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato	mdp->edmac_endian = pd->edmac_endian;
27164923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda	mdp->no_ether_link = pd->no_ether_link;
27174923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda	mdp->ether_link_active_low = pd->ether_link_active_low;
27184a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda	mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);
271986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2720380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	/* set cpu data */
27218fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#if defined(SH_ETH_HAS_BOTH_MODULES)
27228fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda	mdp->cd = sh_eth_get_cpu_data(mdp);
27238fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#else
2724380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	mdp->cd = &sh_eth_my_cpu_data;
27258fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#endif
2726380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda	sh_eth_set_default_cpu_data(mdp->cd);
2727380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda
272886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* set function */
2729ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov	ndev->netdev_ops = &sh_eth_netdev_ops;
2730dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
273186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ndev->watchdog_timeo = TX_TIMEOUT;
273286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2733dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	/* debug message level */
2734dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu	mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
273586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
273686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* read and set MAC address */
2737748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm	read_mac_address(ndev, pd->mac_addr);
273886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
27396ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda	/* ioremap the TSU registers */
27406ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda	if (mdp->cd->tsu) {
27416ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda		struct resource *rtsu;
27426ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda		rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
27436ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda		if (!rtsu) {
27446ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda			dev_err(&pdev->dev, "Not found TSU resource\n");
2745043c4789726e6abb5be6115cb054af4926481952Peter Senna Tschudin			ret = -ENODEV;
27466ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda			goto out_release;
27476ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda		}
2748d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		mdp->tsu_addr = devm_ioremap_resource(&pdev->dev, rtsu);
2749d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov		if (IS_ERR(mdp->tsu_addr)) {
2750d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov			ret = PTR_ERR(mdp->tsu_addr);
2751fc0c0900408e05758a0df17c1924ca837fafca5eSergei Shtylyov			goto out_release;
2752fc0c0900408e05758a0df17c1924ca837fafca5eSergei Shtylyov		}
27536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda		mdp->port = devno % 2;
2754f646968f8f7c624587de729115d802372b9063ddPatrick McHardy		ndev->features = NETIF_F_HW_VLAN_CTAG_FILTER;
27556ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda	}
27566ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda
2757150647fb2c313d7c5184fca3fa0829a4a7d6f7bcYoshihiro Shimoda	/* initialize first or needed device */
2758150647fb2c313d7c5184fca3fa0829a4a7d6f7bcYoshihiro Shimoda	if (!devno || pd->needs_init) {
2759380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda		if (mdp->cd->chip_reset)
2760380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda			mdp->cd->chip_reset(ndev);
276186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
27624986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda		if (mdp->cd->tsu) {
27634986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda			/* TSU init (Init only)*/
27644986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda			sh_eth_tsu_init(mdp);
27654986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda		}
276686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	}
276786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
276886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* network device register */
276986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	ret = register_netdev(ndev);
277086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
277186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_release;
277286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
277386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* mdio bus init */
2774b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda	ret = sh_mdio_init(ndev, pdev->id, pd);
277586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ret)
277686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		goto out_unregister;
277786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
277825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	/* print device information */
27796cd9b49d7328c4656bfc17fcb47fb814955d40d2H Hartley Sweeten	pr_info("Base address at 0x%x, %pM, IRQ %d.\n",
27806cd9b49d7328c4656bfc17fcb47fb814955d40d2H Hartley Sweeten	       (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);
278186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
278286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	platform_set_drvdata(pdev, ndev);
278386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
278486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
278586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
278686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_unregister:
278786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	unregister_netdev(ndev);
278886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
278986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_release:
279086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	/* net_dev free */
279186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	if (ndev)
279286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		free_netdev(ndev);
279386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
279486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout:
279586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return ret;
279686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
279786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
279886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_drv_remove(struct platform_device *pdev)
279986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{
280086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	struct net_device *ndev = platform_get_drvdata(pdev);
280186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
280286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	sh_mdio_release(ndev);
280386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	unregister_netdev(ndev);
2804bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	pm_runtime_disable(&pdev->dev);
280586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	free_netdev(ndev);
280686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	platform_set_drvdata(pdev, NULL);
280786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
280886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	return 0;
280986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}
281086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2811bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Dammstatic int sh_eth_runtime_nop(struct device *dev)
2812bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm{
2813bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	/*
2814bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * Runtime PM callback shared between ->runtime_suspend()
2815bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * and ->runtime_resume(). Simply returns success.
2816bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 *
2817bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * This driver re-initializes all registers after
2818bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * pm_runtime_get_sync() anyway so there is no need
2819bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 * to save and restore registers here.
2820bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	 */
2821bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	return 0;
2822bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm}
2823bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
2824bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Dammstatic struct dev_pm_ops sh_eth_dev_pm_ops = {
2825bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	.runtime_suspend = sh_eth_runtime_nop,
2826bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm	.runtime_resume = sh_eth_runtime_nop,
2827bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm};
2828bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm
282986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct platform_driver sh_eth_driver = {
283086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.probe = sh_eth_drv_probe,
283186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.remove = sh_eth_drv_remove,
283286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	.driver = {
283386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu		   .name = CARDNAME,
2834bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm		   .pm = &sh_eth_dev_pm_ops,
283586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu	},
283686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu};
283786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
2838db62f684deeb291ab2533b99843d5df9a36b1f19Axel Linmodule_platform_driver(sh_eth_driver);
283986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu
284086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_AUTHOR("Nobuhiro Iwamatsu, Yoshihiro Shimoda");
284186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_DESCRIPTION("Renesas SuperH Ethernet driver");
284286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_LICENSE("GPL v2");
2843