1128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov/* SuperH Ethernet device driver 286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * 3f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu * Copyright (C) 2006-2012 Nobuhiro Iwamatsu 4b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov * Copyright (C) 2008-2014 Renesas Solutions Corp. 5b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov * Copyright (C) 2013-2014 Cogent Embedded, Inc. 6702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks * Copyright (C) 2014 Codethink Limited 786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * 886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * This program is free software; you can redistribute it and/or modify it 986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * under the terms and conditions of the GNU General Public License, 1086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * version 2, as published by the Free Software Foundation. 1186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * 1286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * This program is distributed in the hope it will be useful, but WITHOUT 1386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 1586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * more details. 1686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * 1786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * The full GNU General Public License is included in this distribution in 1886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * the file called "COPYING". 1986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */ 2086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 210654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/module.h> 220654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/kernel.h> 230654011d900670884197d9a06ad17b378dfde831Yoshihiro Shimoda#include <linux/spinlock.h> 246a27cdeddf48858089e3672f844615cbf0877ebfNobuhiro Iwamatsu#include <linux/interrupt.h> 2586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/dma-mapping.h> 2686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/etherdevice.h> 2786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/delay.h> 2886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/platform_device.h> 2986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/mdio-bitbang.h> 3086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/netdevice.h> 31b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of.h> 32b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of_device.h> 33b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of_irq.h> 34b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#include <linux/of_net.h> 3586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/phy.h> 3686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/cache.h> 3786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include <linux/io.h> 38bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm#include <linux/pm_runtime.h> 395a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 40dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#include <linux/ethtool.h> 41fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda#include <linux/if_vlan.h> 42f0e81fecd4f83de7854262c8a6b3af19dfa99bf9Nobuhiro Iwamatsu#include <linux/clk.h> 43d4fa0e35fdbd54acf791fa3793d6d17f7795f7aeYoshihiro Shimoda#include <linux/sh_eth.h> 44702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks#include <linux/of_mdio.h> 4586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 4686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu#include "sh_eth.h" 4786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 48dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#define SH_ETH_DEF_MSG_ENABLE \ 49dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu (NETIF_MSG_LINK | \ 50dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu NETIF_MSG_TIMER | \ 51dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu NETIF_MSG_RX_ERR| \ 52dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu NETIF_MSG_TX_ERR) 53dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 54c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { 55c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EDSR] = 0x0000, 56c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EDMR] = 0x0400, 57c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EDTRR] = 0x0408, 58c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EDRRR] = 0x0410, 59c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EESR] = 0x0428, 60c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EESIPR] = 0x0430, 61c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TDLAR] = 0x0010, 62c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TDFAR] = 0x0014, 63c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TDFXR] = 0x0018, 64c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TDFFR] = 0x001c, 65c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RDLAR] = 0x0030, 66c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RDFAR] = 0x0034, 67c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RDFXR] = 0x0038, 68c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RDFFR] = 0x003c, 69c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TRSCER] = 0x0438, 70c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RMFCR] = 0x0440, 71c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TFTR] = 0x0448, 72c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FDR] = 0x0450, 73c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RMCR] = 0x0458, 74c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RPADIR] = 0x0460, 75c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FCFTR] = 0x0468, 76c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CSMR] = 0x04E4, 77c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 78c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECMR] = 0x0500, 79c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECSR] = 0x0510, 80c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECSIPR] = 0x0518, 81c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PIR] = 0x0520, 82c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PSR] = 0x0528, 83c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PIPR] = 0x052c, 84c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFLR] = 0x0508, 85c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [APR] = 0x0554, 86c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MPR] = 0x0558, 87c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PFTCR] = 0x055c, 88c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PFRCR] = 0x0560, 89c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TPAUSER] = 0x0564, 90c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [GECMR] = 0x05b0, 91c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [BCULR] = 0x05b4, 92c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MAHR] = 0x05c0, 93c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MALR] = 0x05c8, 94c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TROCR] = 0x0700, 95c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CDCR] = 0x0708, 96c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [LCCR] = 0x0710, 97c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CEFCR] = 0x0740, 98c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FRECR] = 0x0748, 99c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSFRCR] = 0x0750, 100c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TLFRCR] = 0x0758, 101c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFCR] = 0x0760, 102c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CERCR] = 0x0768, 103c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CEECR] = 0x0770, 104c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MAFCR] = 0x0778, 105c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RMII_MII] = 0x0790, 106c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 107c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ARSTR] = 0x0000, 108c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_CTRST] = 0x0004, 109c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWEN0] = 0x0010, 110c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWEN1] = 0x0014, 111c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FCM] = 0x0018, 112c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_BSYSL0] = 0x0020, 113c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_BSYSL1] = 0x0024, 114c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_PRISL0] = 0x0028, 115c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_PRISL1] = 0x002c, 116c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSL0] = 0x0030, 117c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSL1] = 0x0034, 118c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSLC] = 0x0038, 119c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_QTAG0] = 0x0040, 120c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_QTAG1] = 0x0044, 121c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSR] = 0x0050, 122c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWINMK] = 0x0054, 123c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADQT0] = 0x0048, 124c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADQT1] = 0x004c, 125c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_VTAG0] = 0x0058, 126c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_VTAG1] = 0x005c, 127c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADSBSY] = 0x0060, 128c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_TEN] = 0x0064, 129c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST1] = 0x0070, 130c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST2] = 0x0074, 131c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST3] = 0x0078, 132c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST4] = 0x007c, 133c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADRH0] = 0x0100, 134c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADRL0] = 0x0104, 135c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADRH31] = 0x01f8, 136c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADRL31] = 0x01fc, 137c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 138c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXNLCR0] = 0x0080, 139c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXALCR0] = 0x0084, 140c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXNLCR0] = 0x0088, 141c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXALCR0] = 0x008c, 142c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWNLCR0] = 0x0090, 143c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWALCR0] = 0x0094, 144c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXNLCR1] = 0x00a0, 145c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXALCR1] = 0x00a0, 146c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXNLCR1] = 0x00a8, 147c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXALCR1] = 0x00ac, 148c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWNLCR1] = 0x00b0, 149c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWALCR1] = 0x00b4, 150c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov}; 151c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 152db893473d313a4ad9455e89d1bd5e136a57f411eSimon Hormanstatic const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { 153db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [EDSR] = 0x0000, 154db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [EDMR] = 0x0400, 155db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [EDTRR] = 0x0408, 156db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [EDRRR] = 0x0410, 157db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [EESR] = 0x0428, 158db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [EESIPR] = 0x0430, 159db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TDLAR] = 0x0010, 160db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TDFAR] = 0x0014, 161db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TDFXR] = 0x0018, 162db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TDFFR] = 0x001c, 163db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RDLAR] = 0x0030, 164db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RDFAR] = 0x0034, 165db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RDFXR] = 0x0038, 166db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RDFFR] = 0x003c, 167db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TRSCER] = 0x0438, 168db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RMFCR] = 0x0440, 169db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TFTR] = 0x0448, 170db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [FDR] = 0x0450, 171db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RMCR] = 0x0458, 172db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RPADIR] = 0x0460, 173db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [FCFTR] = 0x0468, 174db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [CSMR] = 0x04E4, 175db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 176db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [ECMR] = 0x0500, 177db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RFLR] = 0x0508, 178db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [ECSR] = 0x0510, 179db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [ECSIPR] = 0x0518, 180db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [PIR] = 0x0520, 181db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [APR] = 0x0554, 182db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [MPR] = 0x0558, 183db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [PFTCR] = 0x055c, 184db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [PFRCR] = 0x0560, 185db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TPAUSER] = 0x0564, 186db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [MAHR] = 0x05c0, 187db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [MALR] = 0x05c8, 188db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [CEFCR] = 0x0740, 189db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [FRECR] = 0x0748, 190db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSFRCR] = 0x0750, 191db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TLFRCR] = 0x0758, 192db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RFCR] = 0x0760, 193db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [MAFCR] = 0x0778, 194db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 195db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [ARSTR] = 0x0000, 196db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_CTRST] = 0x0004, 197db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_VTAG0] = 0x0058, 198db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_ADSBSY] = 0x0060, 199db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_TEN] = 0x0064, 200db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_ADRH0] = 0x0100, 201db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_ADRL0] = 0x0104, 202db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_ADRH31] = 0x01f8, 203db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TSU_ADRL31] = 0x01fc, 204db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 205db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TXNLCR0] = 0x0080, 206db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [TXALCR0] = 0x0084, 207db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RXNLCR0] = 0x0088, 208db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman [RXALCR0] = 0x008C, 209db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman}; 210db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 211a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyovstatic const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { 212a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [ECMR] = 0x0300, 213a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RFLR] = 0x0308, 214a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [ECSR] = 0x0310, 215a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [ECSIPR] = 0x0318, 216a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [PIR] = 0x0320, 217a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [PSR] = 0x0328, 218a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RDMLR] = 0x0340, 219a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [IPGR] = 0x0350, 220a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [APR] = 0x0354, 221a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [MPR] = 0x0358, 222a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RFCF] = 0x0360, 223a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TPAUSER] = 0x0364, 224a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TPAUSECR] = 0x0368, 225a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [MAHR] = 0x03c0, 226a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [MALR] = 0x03c8, 227a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TROCR] = 0x03d0, 228a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [CDCR] = 0x03d4, 229a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [LCCR] = 0x03d8, 230a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [CNDCR] = 0x03dc, 231a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [CEFCR] = 0x03e4, 232a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [FRECR] = 0x03e8, 233a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TSFRCR] = 0x03ec, 234a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TLFRCR] = 0x03f0, 235a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RFCR] = 0x03f4, 236a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [MAFCR] = 0x03f8, 237a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov 238a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [EDMR] = 0x0200, 239a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [EDTRR] = 0x0208, 240a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [EDRRR] = 0x0210, 241a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TDLAR] = 0x0218, 242a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RDLAR] = 0x0220, 243a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [EESR] = 0x0228, 244a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [EESIPR] = 0x0230, 245a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TRSCER] = 0x0238, 246a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RMFCR] = 0x0240, 247a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TFTR] = 0x0248, 248a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [FDR] = 0x0250, 249a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RMCR] = 0x0258, 250a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TFUCR] = 0x0264, 251a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [RFOCR] = 0x0268, 25255754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman [RMIIMODE] = 0x026c, 253a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [FCFTR] = 0x0270, 254a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov [TRIMD] = 0x027c, 255a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov}; 256a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov 257c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { 258c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECMR] = 0x0100, 259c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFLR] = 0x0108, 260c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECSR] = 0x0110, 261c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECSIPR] = 0x0118, 262c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PIR] = 0x0120, 263c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PSR] = 0x0128, 264c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RDMLR] = 0x0140, 265c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [IPGR] = 0x0150, 266c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [APR] = 0x0154, 267c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MPR] = 0x0158, 268c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TPAUSER] = 0x0164, 269c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFCF] = 0x0160, 270c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TPAUSECR] = 0x0168, 271c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [BCFRR] = 0x016c, 272c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MAHR] = 0x01c0, 273c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MALR] = 0x01c8, 274c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TROCR] = 0x01d0, 275c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CDCR] = 0x01d4, 276c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [LCCR] = 0x01d8, 277c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CNDCR] = 0x01dc, 278c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CEFCR] = 0x01e4, 279c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FRECR] = 0x01e8, 280c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSFRCR] = 0x01ec, 281c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TLFRCR] = 0x01f0, 282c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFCR] = 0x01f4, 283c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MAFCR] = 0x01f8, 284c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RTRATE] = 0x01fc, 285c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 286c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EDMR] = 0x0000, 287c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EDTRR] = 0x0008, 288c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EDRRR] = 0x0010, 289c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TDLAR] = 0x0018, 290c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RDLAR] = 0x0020, 291c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EESR] = 0x0028, 292c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [EESIPR] = 0x0030, 293c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TRSCER] = 0x0038, 294c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RMFCR] = 0x0040, 295c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TFTR] = 0x0048, 296c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FDR] = 0x0050, 297c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RMCR] = 0x0058, 298c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TFUCR] = 0x0064, 299c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFOCR] = 0x0068, 300c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FCFTR] = 0x0070, 301c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RPADIR] = 0x0078, 302c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TRIMD] = 0x007c, 303c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RBWAR] = 0x00c8, 304c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RDFAR] = 0x00cc, 305c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TBRAR] = 0x00d4, 306c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TDFAR] = 0x00d8, 307c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov}; 308c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 309c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyovstatic const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { 310d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [EDMR] = 0x0000, 311d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [EDTRR] = 0x0004, 312d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [EDRRR] = 0x0008, 313d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [TDLAR] = 0x000c, 314d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [RDLAR] = 0x0010, 315d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [EESR] = 0x0014, 316d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [EESIPR] = 0x0018, 317d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [TRSCER] = 0x001c, 318d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [RMFCR] = 0x0020, 319d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [TFTR] = 0x0024, 320d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [FDR] = 0x0028, 321d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [RMCR] = 0x002c, 322d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [EDOCR] = 0x0030, 323d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [FCFTR] = 0x0034, 324d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [RPADIR] = 0x0038, 325d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [TRIMD] = 0x003c, 326d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [RBWAR] = 0x0040, 327d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [RDFAR] = 0x0044, 328d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [TBRAR] = 0x004c, 329d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov [TDFAR] = 0x0050, 330d8b0426af5b67973585712c9af36b86f6ea97815Sergei Shtylyov 331c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECMR] = 0x0160, 332c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECSR] = 0x0164, 333c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ECSIPR] = 0x0168, 334c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PIR] = 0x016c, 335c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MAHR] = 0x0170, 336c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MALR] = 0x0174, 337c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFLR] = 0x0178, 338c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [PSR] = 0x017c, 339c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TROCR] = 0x0180, 340c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CDCR] = 0x0184, 341c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [LCCR] = 0x0188, 342c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CNDCR] = 0x018c, 343c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [CEFCR] = 0x0194, 344c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FRECR] = 0x0198, 345c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSFRCR] = 0x019c, 346c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TLFRCR] = 0x01a0, 347c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RFCR] = 0x01a4, 348c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MAFCR] = 0x01a8, 349c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [IPGR] = 0x01b4, 350c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [APR] = 0x01b8, 351c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [MPR] = 0x01bc, 352c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TPAUSER] = 0x01c4, 353c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [BCFR] = 0x01cc, 354c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 355c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [ARSTR] = 0x0000, 356c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_CTRST] = 0x0004, 357c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWEN0] = 0x0010, 358c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWEN1] = 0x0014, 359c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FCM] = 0x0018, 360c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_BSYSL0] = 0x0020, 361c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_BSYSL1] = 0x0024, 362c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_PRISL0] = 0x0028, 363c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_PRISL1] = 0x002c, 364c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSL0] = 0x0030, 365c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSL1] = 0x0034, 366c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSLC] = 0x0038, 367c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_QTAGM0] = 0x0040, 368c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_QTAGM1] = 0x0044, 369c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADQT0] = 0x0048, 370c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADQT1] = 0x004c, 371c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWSR] = 0x0050, 372c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_FWINMK] = 0x0054, 373c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADSBSY] = 0x0060, 374c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_TEN] = 0x0064, 375c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST1] = 0x0070, 376c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST2] = 0x0074, 377c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST3] = 0x0078, 378c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_POST4] = 0x007c, 379c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 380c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXNLCR0] = 0x0080, 381c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXALCR0] = 0x0084, 382c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXNLCR0] = 0x0088, 383c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXALCR0] = 0x008c, 384c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWNLCR0] = 0x0090, 385c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWALCR0] = 0x0094, 386c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXNLCR1] = 0x00a0, 387c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TXALCR1] = 0x00a0, 388c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXNLCR1] = 0x00a8, 389c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [RXALCR1] = 0x00ac, 390c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWNLCR1] = 0x00b0, 391c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [FWALCR1] = 0x00b4, 392c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 393c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADRH0] = 0x0100, 394c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADRL0] = 0x0104, 395c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov [TSU_ADRL31] = 0x01fc, 396c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov}; 397c0013f6f8bbcb7605d591431444780d636dbe223Sergei Shtylyov 398504c8ca55c70fb6cab0b97381e70ad0e143f539eSimon Hormanstatic bool sh_eth_is_gether(struct sh_eth_private *mdp) 399dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu{ 400504c8ca55c70fb6cab0b97381e70ad0e143f539eSimon Horman return mdp->reg_offset == sh_eth_offset_gigabit; 401dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu} 402dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 403db893473d313a4ad9455e89d1bd5e136a57f411eSimon Hormanstatic bool sh_eth_is_rz_fast_ether(struct sh_eth_private *mdp) 404db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman{ 405db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman return mdp->reg_offset == sh_eth_offset_fast_rz; 406db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman} 407db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 4088e994402ad5e6ae3d391c0935f9f1dc2eeb92a5eSergei Shtylyovstatic void sh_eth_select_mii(struct net_device *ndev) 4095e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu{ 4105e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu u32 value = 0x0; 4115e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 4125e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu 4135e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu switch (mdp->phy_interface) { 4145e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu case PHY_INTERFACE_MODE_GMII: 4155e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu value = 0x2; 4165e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu break; 4175e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu case PHY_INTERFACE_MODE_MII: 4185e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu value = 0x1; 4195e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu break; 4205e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu case PHY_INTERFACE_MODE_RMII: 4215e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu value = 0x0; 4225e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu break; 4235e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu default: 424f75f14ec2f7b552dc87b4b57b2a19e487378f774Sergei Shtylyov netdev_warn(ndev, 425f75f14ec2f7b552dc87b4b57b2a19e487378f774Sergei Shtylyov "PHY interface mode was not setup. Set to MII.\n"); 4265e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu value = 0x1; 4275e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu break; 4285e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu } 4295e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu 4305e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu sh_eth_write(ndev, value, RMII_MII); 4315e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu} 4325e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu 4338e994402ad5e6ae3d391c0935f9f1dc2eeb92a5eSergei Shtylyovstatic void sh_eth_set_duplex(struct net_device *ndev) 43465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda{ 43565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 43665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 43765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda if (mdp->duplex) /* Full */ 4384a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR); 43965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda else /* Half */ 4404a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR); 44165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda} 44265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 44304b0ed2ad49834fe47d3c4171ad189c688a222b9Nobuhiro Iwamatsu/* There is CPU dependent code */ 444589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyovstatic void sh_eth_set_rate_r8a777x(struct net_device *ndev) 44565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda{ 44665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 447d0418bb7123f44b23d69ac349eec7daf9103472fPhil Edworthy 448a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov switch (mdp->speed) { 449a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov case 10: /* 10BASE */ 450a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_ELB, ECMR); 451a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov break; 452a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov case 100:/* 100BASE */ 453a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_ELB, ECMR); 454a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov break; 455a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov default: 456a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov break; 457a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov } 458a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov} 459a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov 460674853b222168f2066db028cad89ab52cbcdeee5Sergei Shtylyov/* R8A7778/9 */ 461589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyovstatic struct sh_eth_cpu_data r8a777x_data = { 462a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .set_duplex = sh_eth_set_duplex, 463589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyov .set_rate = sh_eth_set_rate_r8a777x, 464a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov 465a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_FAST_RCAR, 466a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 467a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD, 468a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP, 469a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .eesipr_value = 0x01ff009f, 470a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov 471a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, 472ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | 473ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | 474ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_ECI, 475a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov 476a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .apr = 1, 477a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .mpr = 1, 478a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .tpauser = 1, 479a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov .hw_swap = 1, 480a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov}; 481a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov 48294a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyov/* R8A7790/1 */ 48394a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyovstatic struct sh_eth_cpu_data r8a779x_data = { 484e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .set_duplex = sh_eth_set_duplex, 485e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .set_rate = sh_eth_set_rate_r8a777x, 486e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman 487a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_FAST_RCAR, 488a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 489e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD, 490e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP, 491e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .eesipr_value = 0x01ff009f, 492e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman 493e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, 494ba361cb3d4c977e2b94b5d97905f66b4d48964deLaurent Pinchart .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | 495ba361cb3d4c977e2b94b5d97905f66b4d48964deLaurent Pinchart EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | 496ba361cb3d4c977e2b94b5d97905f66b4d48964deLaurent Pinchart EESR_ECI, 497e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman 498e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .apr = 1, 499e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .mpr = 1, 500e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .tpauser = 1, 501e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .hw_swap = 1, 502e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman .rmiimode = 1, 503fd9af07c3404ac9ecbd0d859563360f51ce1ffdeKouei Abe .shift_rd0 = 1, 504e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman}; 505e18dbf7efcb7a727e5db773597ddfd6981a530e6Simon Horman 5069c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyovstatic void sh_eth_set_rate_sh7724(struct net_device *ndev) 507a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov{ 508a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov struct sh_eth_private *mdp = netdev_priv(ndev); 50965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 51065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda switch (mdp->speed) { 51165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda case 10: /* 10BASE */ 512a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR); 51365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda break; 51465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda case 100:/* 100BASE */ 515a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR); 51665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda break; 51765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda default: 51865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda break; 51965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda } 52065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda} 52165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 52265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda/* SH7724 */ 5239c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyovstatic struct sh_eth_cpu_data sh7724_data = { 52465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .set_duplex = sh_eth_set_duplex, 5259c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyov .set_rate = sh_eth_set_rate_sh7724, 52665ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 527a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_FAST_SH4, 528a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 52965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD, 53065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP, 531a80c3de714bc4855747faf5f00e8203fb800e6bbSergei Shtylyov .eesipr_value = 0x01ff009f, 53265ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 53365ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, 534ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | 535ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | 536ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_ECI, 53765ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 53865ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .apr = 1, 53965ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .mpr = 1, 54065ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .tpauser = 1, 54165ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda .hw_swap = 1, 542503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm .rpadir = 1, 543503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm .rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */ 54465ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda}; 5455cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu 54624549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyovstatic void sh_eth_set_rate_sh7757(struct net_device *ndev) 547f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda{ 548f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 549f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda 550f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda switch (mdp->speed) { 551f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda case 10: /* 10BASE */ 5524a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0, RTRATE); 553f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda break; 554f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda case 100:/* 100BASE */ 5554a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 1, RTRATE); 556f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda break; 557f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda default: 558f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda break; 559f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda } 560f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda} 561f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda 562f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda/* SH7757 */ 56324549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyovstatic struct sh_eth_cpu_data sh7757_data = { 56424549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov .set_duplex = sh_eth_set_duplex, 56524549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov .set_rate = sh_eth_set_rate_sh7757, 566f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda 567a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_FAST_SH4, 568a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 569f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, 570f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda 571f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, 572ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | 573ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | 574ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_ECI, 575f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda 5765b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu .irq_flags = IRQF_SHARED, 577f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda .apr = 1, 578f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda .mpr = 1, 579f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda .tpauser = 1, 580f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda .hw_swap = 1, 581f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda .no_ade = 1, 5822e98e7974de208de0dab9e9969bd47576d07ff10Yoshihiro Shimoda .rpadir = 1, 5832e98e7974de208de0dab9e9969bd47576d07ff10Yoshihiro Shimoda .rpadir_value = 2 << 16, 584f29a3d040727a80c3307a2bea057206be049c305Yoshihiro Shimoda}; 58565ac8851490ec97a96759af729132c96f925a795Yoshihiro Shimoda 586e403d295817cf9f8be3110eb7ee1a03981287495David S. Miller#define SH_GIGA_ETH_BASE 0xfee00000UL 5878fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define GIGA_MALR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8) 5888fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda#define GIGA_MAHR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0) 5898fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic void sh_eth_chip_reset_giga(struct net_device *ndev) 5908fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{ 5918fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda int i; 5928fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda unsigned long mahr[2], malr[2]; 5938fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 5948fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda /* save MAHR and MALR */ 5958fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda for (i = 0; i < 2; i++) { 596ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda malr[i] = ioread32((void *)GIGA_MALR(i)); 597ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda mahr[i] = ioread32((void *)GIGA_MAHR(i)); 5988fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda } 5998fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 6008fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda /* reset device */ 601ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda iowrite32(ARSTR_ARSTR, (void *)(SH_GIGA_ETH_BASE + 0x1800)); 6028fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda mdelay(1); 6038fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 6048fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda /* restore MAHR and MALR */ 6058fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda for (i = 0; i < 2; i++) { 606ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda iowrite32(malr[i], (void *)GIGA_MALR(i)); 607ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda iowrite32(mahr[i], (void *)GIGA_MAHR(i)); 6088fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda } 6098fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda} 6108fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 6118fcd496151b4354569283056076339239b86fabeYoshihiro Shimodastatic void sh_eth_set_rate_giga(struct net_device *ndev) 6128fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda{ 6138fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 6148fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 6158fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda switch (mdp->speed) { 6168fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda case 10: /* 10BASE */ 6178fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda sh_eth_write(ndev, 0x00000000, GECMR); 6188fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda break; 6198fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda case 100:/* 100BASE */ 6208fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda sh_eth_write(ndev, 0x00000010, GECMR); 6218fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda break; 6228fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda case 1000: /* 1000BASE */ 6238fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda sh_eth_write(ndev, 0x00000020, GECMR); 6248fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda break; 6258fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda default: 6268fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda break; 6278fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda } 6288fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda} 6298fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 6308fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda/* SH7757(GETHERC) */ 63124549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyovstatic struct sh_eth_cpu_data sh7757_data_giga = { 6328fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .chip_reset = sh_eth_chip_reset_giga, 63304b0ed2ad49834fe47d3c4171ad189c688a222b9Nobuhiro Iwamatsu .set_duplex = sh_eth_set_duplex, 6348fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .set_rate = sh_eth_set_rate_giga, 6358fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 636a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_GIGABIT, 637a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 6388fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .ecsr_value = ECSR_ICD | ECSR_MPD, 6398fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, 6408fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, 6418fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 6428fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .tx_check = EESR_TC1 | EESR_FTC, 643ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | 644ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | 645ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_TDE | EESR_ECI, 6468fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .fdr_value = 0x0000072f, 6478fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 6485b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu .irq_flags = IRQF_SHARED, 6498fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .apr = 1, 6508fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .mpr = 1, 6518fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .tpauser = 1, 6528fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .bculr = 1, 6538fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .hw_swap = 1, 6548fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .rpadir = 1, 6558fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .rpadir_value = 2 << 16, 6568fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .no_trimd = 1, 6578fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda .no_ade = 1, 6583acbc9715a5ac8a2534a69eb3488b63b7c9fb1e2Yoshihiro Shimoda .tsu = 1, 6598fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda}; 6608fcd496151b4354569283056076339239b86fabeYoshihiro Shimoda 661380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_chip_reset(struct net_device *ndev) 662380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{ 6634986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 6644986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda 665380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda /* reset device */ 6664986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR); 667380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda mdelay(1); 668380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda} 669380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 670f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyovstatic void sh_eth_set_rate_gether(struct net_device *ndev) 671380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{ 672380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 673380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 674380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda switch (mdp->speed) { 675380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda case 10: /* 10BASE */ 6764a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, GECMR_10, GECMR); 677380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda break; 678380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda case 100:/* 100BASE */ 6794a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, GECMR_100, GECMR); 680380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda break; 681380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda case 1000: /* 1000BASE */ 6824a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, GECMR_1000, GECMR); 683380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda break; 684380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda default: 685380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda break; 686380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda } 687380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda} 688380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 689f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov/* SH7734 */ 690f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyovstatic struct sh_eth_cpu_data sh7734_data = { 691380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .chip_reset = sh_eth_chip_reset, 692380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .set_duplex = sh_eth_set_duplex, 693f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .set_rate = sh_eth_set_rate_gether, 694f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov 695a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_GIGABIT, 696a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 697f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .ecsr_value = ECSR_ICD | ECSR_MPD, 698f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, 699f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, 700f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov 701f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .tx_check = EESR_TC1 | EESR_FTC, 702ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | 703ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | 704ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_TDE | EESR_ECI, 705f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov 706f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .apr = 1, 707f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .mpr = 1, 708f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .tpauser = 1, 709f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .bculr = 1, 710f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .hw_swap = 1, 711f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .no_trimd = 1, 712f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .no_ade = 1, 713f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .tsu = 1, 714f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .hw_crc = 1, 715f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .select_mii = 1, 716f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov}; 717f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov 718f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov/* SH7763 */ 719f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyovstatic struct sh_eth_cpu_data sh7763_data = { 720f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .chip_reset = sh_eth_chip_reset, 721f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .set_duplex = sh_eth_set_duplex, 722f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov .set_rate = sh_eth_set_rate_gether, 723380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 724a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_GIGABIT, 725a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 726380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .ecsr_value = ECSR_ICD | ECSR_MPD, 727380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, 728380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, 729380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 730380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .tx_check = EESR_TC1 | EESR_FTC, 731128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | 732128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | 733380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda EESR_ECI, 734380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 735380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .apr = 1, 736380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .mpr = 1, 737380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .tpauser = 1, 738380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .bculr = 1, 739380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .hw_swap = 1, 740380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .no_trimd = 1, 741380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .no_ade = 1, 7424986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda .tsu = 1, 7435b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu .irq_flags = IRQF_SHARED, 744380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}; 745380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 746e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyovstatic void sh_eth_chip_reset_r8a7740(struct net_device *ndev) 74773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda{ 74873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 74973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda 75073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda /* reset device */ 75173a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR); 75273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda mdelay(1); 75373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda 7545e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu sh_eth_select_mii(ndev); 75573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda} 75673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda 75773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda/* R8A7740 */ 758e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyovstatic struct sh_eth_cpu_data r8a7740_data = { 759e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyov .chip_reset = sh_eth_chip_reset_r8a7740, 76073a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .set_duplex = sh_eth_set_duplex, 761e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyov .set_rate = sh_eth_set_rate_gether, 76273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda 763a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_GIGABIT, 764a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 76573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .ecsr_value = ECSR_ICD | ECSR_MPD, 76673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP, 76773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, 76873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda 76973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .tx_check = EESR_TC1 | EESR_FTC, 770ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | 771ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | 772ca8c35852138ee0585eaffe6b9f10a5261ea7771Sergei Shtylyov EESR_TDE | EESR_ECI, 773cc23528db0300d5c8c0b98670a577bf1dc3e0e82Simon Horman .fdr_value = 0x0000070f, 77473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda 77573a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .apr = 1, 77673a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .mpr = 1, 77773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .tpauser = 1, 77873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .bculr = 1, 77973a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .hw_swap = 1, 780cc23528db0300d5c8c0b98670a577bf1dc3e0e82Simon Horman .rpadir = 1, 781cc23528db0300d5c8c0b98670a577bf1dc3e0e82Simon Horman .rpadir_value = 2 << 16, 78273a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .no_trimd = 1, 78373a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .no_ade = 1, 78473a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda .tsu = 1, 7855e7a76be0e48217aff6b6f34bdcce4725db999e2Nobuhiro Iwamatsu .select_mii = 1, 786ac8025a643a0e0beb81f3f37ca693364c6b77858Sergei Shtylyov .shift_rd0 = 1, 78773a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda}; 78873a0d907301ece200d32b4e8ba2da2ca296b507fYoshihiro Shimoda 789db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman/* R7S72100 */ 790db893473d313a4ad9455e89d1bd5e136a57f411eSimon Hormanstatic struct sh_eth_cpu_data r7s72100_data = { 791db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .chip_reset = sh_eth_chip_reset, 792db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .set_duplex = sh_eth_set_duplex, 793db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 794db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .register_type = SH_ETH_REG_FAST_RZ, 795db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 796db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .ecsr_value = ECSR_ICD, 797db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .ecsipr_value = ECSIPR_ICDIP, 798db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .eesipr_value = 0xff7f009f, 799db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 800db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .tx_check = EESR_TC1 | EESR_FTC, 801db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | 802db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | 803db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman EESR_TDE | EESR_ECI, 804db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .fdr_value = 0x0000070f, 805db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 806db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .no_psr = 1, 807db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .apr = 1, 808db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .mpr = 1, 809db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .tpauser = 1, 810db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .hw_swap = 1, 811db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .rpadir = 1, 812db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .rpadir_value = 2 << 16, 813db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .no_trimd = 1, 814db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .no_ade = 1, 815db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .hw_crc = 1, 816db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .tsu = 1, 817db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman .shift_rd0 = 1, 818db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman}; 819db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 820c18a79abe31f555ec3b363b5b8c1d003230053b6Sergei Shtylyovstatic struct sh_eth_cpu_data sh7619_data = { 821a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_FAST_SH3_SH2, 822a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 823380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, 824380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 825380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .apr = 1, 826380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .mpr = 1, 827380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .tpauser = 1, 828380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .hw_swap = 1, 829380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}; 8307bbe150d8c57c59689c8c50fd7b9915f4a7e10daSergei Shtylyov 8317bbe150d8c57c59689c8c50fd7b9915f4a7e10daSergei Shtylyovstatic struct sh_eth_cpu_data sh771x_data = { 832a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov .register_type = SH_ETH_REG_FAST_SH3_SH2, 833a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov 834380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, 8354986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda .tsu = 1, 836380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda}; 837380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 838380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd) 839380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{ 840380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!cd->ecsr_value) 841380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda cd->ecsr_value = DEFAULT_ECSR_INIT; 842380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 843380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!cd->ecsipr_value) 844380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda cd->ecsipr_value = DEFAULT_ECSIPR_INIT; 845380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 846380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!cd->fcftr_value) 847128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov cd->fcftr_value = DEFAULT_FIFO_F_D_RFF | 848380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda DEFAULT_FIFO_F_D_RFD; 849380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 850380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!cd->fdr_value) 851380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda cd->fdr_value = DEFAULT_FDR_INIT; 852380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 853380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!cd->tx_check) 854380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda cd->tx_check = DEFAULT_TX_CHECK; 855380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 856380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!cd->eesr_err_check) 857380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK; 858380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda} 859380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 8605cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsustatic int sh_eth_check_reset(struct net_device *ndev) 8615cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu{ 8625cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu int ret = 0; 8635cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu int cnt = 100; 8645cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu 8655cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu while (cnt > 0) { 8665cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu if (!(sh_eth_read(ndev, EDMR) & 0x3)) 8675cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu break; 8685cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu mdelay(1); 8695cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu cnt--; 8705cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu } 8719f8c4265bda4a6e9aa97041d5cfd91386f460b65Sergei Shtylyov if (cnt <= 0) { 872f75f14ec2f7b552dc87b4b57b2a19e487378f774Sergei Shtylyov netdev_err(ndev, "Device reset failed\n"); 8735cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu ret = -ETIMEDOUT; 8745cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu } 8755cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu return ret; 876380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda} 877dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 878dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsustatic int sh_eth_reset(struct net_device *ndev) 879dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu{ 880dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 881dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu int ret = 0; 882dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 883db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) { 884dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, EDSR_ENALL, EDSR); 885dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, 886dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu EDMR); 887dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 888dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu ret = sh_eth_check_reset(ndev); 889dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu if (ret) 890f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart return ret; 891dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 892dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu /* Table Init */ 893dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, TDLAR); 894dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, TDFAR); 895dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, TDFXR); 896dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, TDFFR); 897dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, RDLAR); 898dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, RDFAR); 899dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, RDFXR); 900dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, RDFFR); 901dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 902dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu /* Reset HW CRC register */ 903dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu if (mdp->cd->hw_crc) 904dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, 0x0, CSMR); 905dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 906dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu /* Select MII mode */ 907dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu if (mdp->cd->select_mii) 908dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_select_mii(ndev); 909dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu } else { 910dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, 911dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu EDMR); 912dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu mdelay(3); 913dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, 914dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu EDMR); 915dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu } 916dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu 917dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu return ret; 918dabdde9ea77d4a77094726c82468a3bd767fb29bNobuhiro Iwamatsu} 919380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 920380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimodastatic void sh_eth_set_receive_align(struct sk_buff *skb) 921380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda{ 9224d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura uintptr_t reserve = (uintptr_t)skb->data & (SH_ETH_RX_ALIGN - 1); 923380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 924380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (reserve) 9254d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura skb_reserve(skb, SH_ETH_RX_ALIGN - reserve); 926380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda} 927380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 928380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 92971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato/* CPU <-> EDMAC endian convert */ 93071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Satostatic inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x) 93171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato{ 93271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato switch (mdp->edmac_endian) { 93371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato case EDMAC_LITTLE_ENDIAN: 93471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato return cpu_to_le32(x); 93571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato case EDMAC_BIG_ENDIAN: 93671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato return cpu_to_be32(x); 93771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato } 93871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato return x; 93971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato} 94071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato 94171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Satostatic inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x) 94271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato{ 94371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato switch (mdp->edmac_endian) { 94471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato case EDMAC_LITTLE_ENDIAN: 94571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato return le32_to_cpu(x); 94671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato case EDMAC_BIG_ENDIAN: 94771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato return be32_to_cpu(x); 94871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato } 94971557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato return x; 95071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato} 95171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato 952128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov/* Program the hardware MAC address from dev->dev_addr. */ 95386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void update_mac_address(struct net_device *ndev) 95486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 9554a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 956128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov (ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | 957128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR); 9584a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 959128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR); 96086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 96186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 962128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov/* Get MAC address from SuperH MAC address register 96386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * 96486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * SuperH's Ethernet device doesn't have 'ROM' to MAC address. 96586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g). 96686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * When you want use this device, you must set MAC address in bootloader. 96786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * 96886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */ 969748031f9fd2c06b28817d80761a5de97190cfd03Magnus Dammstatic void read_mac_address(struct net_device *ndev, unsigned char *mac) 97086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 971748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) { 972d458cdf712e0c671e8e819abb16ecd6e44f9daecJoe Perches memcpy(ndev->dev_addr, mac, ETH_ALEN); 973748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm } else { 9744a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24); 9754a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF; 9764a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda ndev->dev_addr[2] = (sh_eth_read(ndev, MAHR) >> 8) & 0xFF; 9774a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda ndev->dev_addr[3] = (sh_eth_read(ndev, MAHR) & 0xFF); 9784a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda ndev->dev_addr[4] = (sh_eth_read(ndev, MALR) >> 8) & 0xFF; 9794a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda ndev->dev_addr[5] = (sh_eth_read(ndev, MALR) & 0xFF); 980748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm } 98186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 98286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 983c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimodastatic unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp) 984c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda{ 985db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) 986c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda return EDTRR_TRNS_GETHER; 987c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda else 988c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda return EDTRR_TRNS_ETHER; 989c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda} 990c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda 99186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustruct bb_info { 992ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda void (*set_gate)(void *addr); 99386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct mdiobb_ctrl ctrl; 994ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda void *addr; 99586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u32 mmd_msk;/* MMD */ 99686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u32 mdo_msk; 99786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u32 mdi_msk; 99886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u32 mdc_msk; 99986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}; 100086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 100186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit set */ 1002ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic void bb_set(void *addr, u32 msk) 100386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 1004ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda iowrite32(ioread32(addr) | msk, addr); 100586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 100686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 100786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit clear */ 1008ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic void bb_clr(void *addr, u32 msk) 100986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 1010ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda iowrite32((ioread32(addr) & ~msk), addr); 101186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 101286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 101386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY bit read */ 1014ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimodastatic int bb_read(void *addr, u32 msk) 101586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 1016ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda return (ioread32(addr) & msk) != 0; 101786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 101886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 101986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Data I/O pin control */ 102086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit) 102186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 102286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); 1023b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda 1024b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda if (bitbang->set_gate) 1025b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda bitbang->set_gate(bitbang->addr); 1026b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda 102786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (bit) 102886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu bb_set(bitbang->addr, bitbang->mmd_msk); 102986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu else 103086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu bb_clr(bitbang->addr, bitbang->mmd_msk); 103186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 103286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 103386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Set bit data*/ 103486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit) 103586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 103686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); 103786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1038b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda if (bitbang->set_gate) 1039b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda bitbang->set_gate(bitbang->addr); 1040b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda 104186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (bit) 104286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu bb_set(bitbang->addr, bitbang->mdo_msk); 104386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu else 104486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu bb_clr(bitbang->addr, bitbang->mdo_msk); 104586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 104686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 104786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Get bit data*/ 104886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_get_mdio(struct mdiobb_ctrl *ctrl) 104986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 105086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); 1051b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda 1052b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda if (bitbang->set_gate) 1053b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda bitbang->set_gate(bitbang->addr); 1054b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda 105586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return bb_read(bitbang->addr, bitbang->mdi_msk); 105686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 105786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 105886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDC pin control */ 105986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit) 106086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 106186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); 106286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1063b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda if (bitbang->set_gate) 1064b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda bitbang->set_gate(bitbang->addr); 1065b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda 106686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (bit) 106786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu bb_set(bitbang->addr, bitbang->mdc_msk); 106886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu else 106986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu bb_clr(bitbang->addr, bitbang->mdc_msk); 107086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 107186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 107286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* mdio bus control struct */ 107386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct mdiobb_ops bb_ops = { 107486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .owner = THIS_MODULE, 107586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .set_mdc = sh_mdc_ctrl, 107686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .set_mdio_dir = sh_mmd_ctrl, 107786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .set_mdio_data = sh_set_mdio, 107886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .get_mdio_data = sh_get_mdio, 107986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}; 108086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 108186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* free skb and descriptor buffer */ 108286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_ring_free(struct net_device *ndev) 108386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 108486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 108586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int i; 108686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 108786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Free Rx skb ringbuffer */ 108886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (mdp->rx_skbuff) { 1089179d80aff82bf8dff9db30589fe5a2297c454d35Sergei Shtylyov for (i = 0; i < mdp->num_rx_ring; i++) 1090179d80aff82bf8dff9db30589fe5a2297c454d35Sergei Shtylyov dev_kfree_skb(mdp->rx_skbuff[i]); 109186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 109286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu kfree(mdp->rx_skbuff); 109391c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->rx_skbuff = NULL; 109486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 109586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Free Tx skb ringbuffer */ 109686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (mdp->tx_skbuff) { 1097179d80aff82bf8dff9db30589fe5a2297c454d35Sergei Shtylyov for (i = 0; i < mdp->num_tx_ring; i++) 1098179d80aff82bf8dff9db30589fe5a2297c454d35Sergei Shtylyov dev_kfree_skb(mdp->tx_skbuff[i]); 109986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 110086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu kfree(mdp->tx_skbuff); 110191c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->tx_skbuff = NULL; 110286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 110386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 110486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* format skb and descriptor buffer */ 110586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_ring_format(struct net_device *ndev) 110686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 110786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 110886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int i; 110986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sk_buff *skb; 111086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_rxdesc *rxdesc = NULL; 111186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_txdesc *txdesc = NULL; 1112525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda int rx_ringsize = sizeof(*rxdesc) * mdp->num_rx_ring; 1113525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda int tx_ringsize = sizeof(*txdesc) * mdp->num_tx_ring; 11144d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; 111586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1116128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov mdp->cur_rx = 0; 1117128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov mdp->cur_tx = 0; 1118128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov mdp->dirty_rx = 0; 1119128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov mdp->dirty_tx = 0; 112086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 112186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu memset(mdp->rx_ring, 0, rx_ringsize); 112286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 112386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* build Rx ring buffer */ 1124525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda for (i = 0; i < mdp->num_rx_ring; i++) { 112586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* skb */ 112686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->rx_skbuff[i] = NULL; 11274d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura skb = netdev_alloc_skb(ndev, skbuff_size); 112886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->rx_skbuff[i] = skb; 112986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (skb == NULL) 113086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu break; 1131380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda sh_eth_set_receive_align(skb); 1132380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 113386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* RX descriptor */ 113486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc = &mdp->rx_ring[i]; 11354d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura /* The size of the buffer is a multiple of 16 bytes. */ 11364d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); 11374d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura dma_map_single(&ndev->dev, skb->data, rxdesc->buffer_length, 11384d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura DMA_FROM_DEVICE); 11390029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); 114071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP); 114186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1142b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* Rx descriptor address set */ 1143b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu if (i == 0) { 11444a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR); 1145db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman if (sh_eth_is_gether(mdp) || 1146db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman sh_eth_is_rz_fast_ether(mdp)) 1147c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR); 1148b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu } 114986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 115086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1151525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda mdp->dirty_rx = (u32) (i - mdp->num_rx_ring); 115286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 115386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Mark the last entry as wrapping the ring. */ 115471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL); 115586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 115686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu memset(mdp->tx_ring, 0, tx_ringsize); 115786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 115886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* build Tx ring buffer */ 1159525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda for (i = 0; i < mdp->num_tx_ring; i++) { 116086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->tx_skbuff[i] = NULL; 116186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu txdesc = &mdp->tx_ring[i]; 116271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato txdesc->status = cpu_to_edmac(mdp, TD_TFP); 116386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu txdesc->buffer_length = 0; 1164b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu if (i == 0) { 116571557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato /* Tx descriptor address set */ 11664a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR); 1167db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman if (sh_eth_is_gether(mdp) || 1168db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman sh_eth_is_rz_fast_ether(mdp)) 1169c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR); 1170b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu } 117186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 117286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 117371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato txdesc->status |= cpu_to_edmac(mdp, TD_TDLE); 117486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 117586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 117686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Get skb and descriptor buffer */ 117786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_ring_init(struct net_device *ndev) 117886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 117986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 118086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int rx_ringsize, tx_ringsize, ret = 0; 118186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1182128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov /* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the 118386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * card needs room to do 8 byte alignment, +2 so we can reserve 118486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * the first 2 bytes, and +16 gets room for the status word from the 118586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu * card. 118686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu */ 118786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ : 118886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu (((ndev->mtu + 26 + 7) & ~7) + 2 + 16)); 1189503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm if (mdp->cd->rpadir) 1190503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm mdp->rx_buf_sz += NET_IP_ALIGN; 119186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 119286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Allocate RX and TX skb rings */ 1193b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches mdp->rx_skbuff = kmalloc_array(mdp->num_rx_ring, 1194b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches sizeof(*mdp->rx_skbuff), GFP_KERNEL); 119586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!mdp->rx_skbuff) { 119686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = -ENOMEM; 119786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 119886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 119986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1200b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches mdp->tx_skbuff = kmalloc_array(mdp->num_tx_ring, 1201b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches sizeof(*mdp->tx_skbuff), GFP_KERNEL); 120286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!mdp->tx_skbuff) { 120386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = -ENOMEM; 120486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto skb_ring_free; 120586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 120686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 120786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Allocate all Rx descriptors. */ 1208525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; 120986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, 1210d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches GFP_KERNEL); 121186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!mdp->rx_ring) { 121286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = -ENOMEM; 121386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto desc_ring_free; 121486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 121586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 121686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->dirty_rx = 0; 121786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 121886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Allocate all Tx descriptors. */ 1219525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; 122086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, 1221d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches GFP_KERNEL); 122286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!mdp->tx_ring) { 122386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = -ENOMEM; 122486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto desc_ring_free; 122586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 122686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 122786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 122886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsudesc_ring_free: 122986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* free DMA buffer */ 123086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma); 123186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 123286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuskb_ring_free: 123386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Free Rx and Tx skb ring buffer */ 123486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu sh_eth_ring_free(ndev); 123591c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->tx_ring = NULL; 123691c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->rx_ring = NULL; 123786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 123886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 123986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 124086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 124191c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimodastatic void sh_eth_free_dma_buffer(struct sh_eth_private *mdp) 124291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda{ 124391c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda int ringsize; 124491c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda 124591c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda if (mdp->rx_ring) { 1246525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; 124791c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda dma_free_coherent(NULL, ringsize, mdp->rx_ring, 124891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->rx_desc_dma); 124991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->rx_ring = NULL; 125091c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda } 125191c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda 125291c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda if (mdp->tx_ring) { 1253525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring; 125491c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda dma_free_coherent(NULL, ringsize, mdp->tx_ring, 125591c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->tx_desc_dma); 125691c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda mdp->tx_ring = NULL; 125791c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda } 125891c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda} 125991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda 1260525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic int sh_eth_dev_init(struct net_device *ndev, bool start) 126186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 126286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int ret = 0; 126386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 126486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u32 val; 126586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 126686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Soft Reset */ 12675cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu ret = sh_eth_reset(ndev); 12685cee1d37c9f565f1aa515408863dbb13db67dab9Nobuhiro Iwamatsu if (ret) 1269f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart return ret; 127086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 127155754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman if (mdp->cd->rmiimode) 127255754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman sh_eth_write(ndev, 0x1, RMIIMODE); 127355754f19d7ee4fa3633f55a4a084af8590c35efaSimon Horman 1274b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* Descriptor format */ 1275b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu sh_eth_ring_format(ndev); 1276380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->rpadir) 12774a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR); 127886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 127986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* all sh_eth int mask */ 12804a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0, EESIPR); 128186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 128210b9194f959608368ed89df1937f17cfe6bd6d84Yoshihiro Shimoda#if defined(__LITTLE_ENDIAN) 1283380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->hw_swap) 12844a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, EDMR_EL, EDMR); 1285380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda else 1286b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu#endif 12874a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0, EDMR); 128886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1289b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* FIFO size set */ 12904a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, mdp->cd->fdr_value, FDR); 12914a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0, TFTR); 129286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1293530aa2d0d9d55ab2775d47621ddf4b5b15bc1110Ben Dooks /* Frame recv control (enable multiple-packets per rx irq) */ 1294530aa2d0d9d55ab2775d47621ddf4b5b15bc1110Ben Dooks sh_eth_write(ndev, RMCR_RNC, RMCR); 129586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 12962ecbb783c3bf5a63f555c39deef308dcc1902b7fYoshihiro Shimoda sh_eth_write(ndev, DESC_I_RINT8 | DESC_I_RINT5 | DESC_I_TINT2, TRSCER); 129786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1298380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->bculr) 12994a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */ 1300b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu 13014a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR); 130286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1303380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!mdp->cd->no_trimd) 13044a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0, TRIMD); 130586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1306b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* Recv frame limit set register */ 1307fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda sh_eth_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, 1308fdb37a7f84a58ccad24abffd54ad46d23b763e13Yoshihiro Shimoda RFLR); 130986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 13104a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR); 1311525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (start) 1312525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); 131386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 131486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* PAUSE Prohibition */ 13154a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda val = (sh_eth_read(ndev, ECMR) & ECMR_DM) | 131686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; 131786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 13184a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, val, ECMR); 1319b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu 1320380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->set_rate) 1321380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda mdp->cd->set_rate(ndev); 1322380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 1323b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* E-MAC Status Register clear */ 13244a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR); 1325b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu 1326b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* E-MAC Interrupt Enable register */ 1327525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (start) 1328525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR); 132986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 133086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Set MAC address */ 133186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu update_mac_address(ndev); 133286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 133386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* mask reset */ 1334380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->apr) 13354a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, APR_AP, APR); 1336380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->mpr) 13374a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, MPR_MP, MPR); 1338380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->tpauser) 13394a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER); 1340b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu 1341525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (start) { 1342525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda /* Setting the Rx mode will start the Rx process. */ 1343525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, EDRRR_R, EDRRR); 134486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1345525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda netif_start_queue(ndev); 1346525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda } 134786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 134886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 134986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 135086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 135186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* free Tx skb function */ 135286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_txfree(struct net_device *ndev) 135386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 135486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 135586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_txdesc *txdesc; 1356128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov int free_num = 0; 135786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int entry = 0; 135886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 135986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) { 1360525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda entry = mdp->dirty_tx % mdp->num_tx_ring; 136186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu txdesc = &mdp->tx_ring[entry]; 136271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato if (txdesc->status & cpu_to_edmac(mdp, TD_TACT)) 136386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu break; 136486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Free the original skb. */ 136586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (mdp->tx_skbuff[entry]) { 136631fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda dma_unmap_single(&ndev->dev, txdesc->addr, 136731fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda txdesc->buffer_length, DMA_TO_DEVICE); 136886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu dev_kfree_skb_irq(mdp->tx_skbuff[entry]); 136986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->tx_skbuff[entry] = NULL; 1370128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov free_num++; 137186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 137271557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato txdesc->status = cpu_to_edmac(mdp, TD_TFP); 1373525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (entry >= mdp->num_tx_ring - 1) 137471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato txdesc->status |= cpu_to_edmac(mdp, TD_TDLE); 137586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1376bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_packets++; 1377bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_bytes += txdesc->buffer_length; 137886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 1379128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov return free_num; 138086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 138186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 138286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Packet receive function */ 13833719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovstatic int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) 138486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 138586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 138686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_rxdesc *rxdesc; 138786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1388525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda int entry = mdp->cur_rx % mdp->num_rx_ring; 1389525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda int boguscnt = (mdp->dirty_rx + mdp->num_rx_ring) - mdp->cur_rx; 139086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sk_buff *skb; 139186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u16 pkt_len = 0; 1392380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda u32 desc_status; 13934d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura int skbuff_size = mdp->rx_buf_sz + SH_ETH_RX_ALIGN - 1; 139486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 139586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc = &mdp->rx_ring[entry]; 139671557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) { 139771557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato desc_status = edmac_to_cpu(mdp, rxdesc->status); 139886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu pkt_len = rxdesc->frame_length; 139986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 140086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (--boguscnt < 0) 140186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu break; 140286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 14034f809cea611f1f00a0b7a42751cb12d997a4c11cYoshihiro Shimoda if (*quota <= 0) 14043719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov break; 14054f809cea611f1f00a0b7a42751cb12d997a4c11cYoshihiro Shimoda 14063719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov (*quota)--; 14073719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 140886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!(desc_status & RDFEND)) 1409bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_length_errors++; 141086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1411128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov /* In case of almost all GETHER/ETHERs, the Receive Frame State 1412dd019897358b815f7828dab90b51d51df4d3658dYoshihiro Shimoda * (RFS) bits in the Receive Descriptor 0 are from bit 9 to 1413db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman * bit 0. However, in case of the R8A7740, R8A779x, and 1414db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman * R7S72100 the RFS bits are from bit 25 to bit 16. So, the 1415db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman * driver needs right shifting by 16. 1416dd019897358b815f7828dab90b51d51df4d3658dYoshihiro Shimoda */ 1417ac8025a643a0e0beb81f3f37ca693364c6b77858Sergei Shtylyov if (mdp->cd->shift_rd0) 1418ac8025a643a0e0beb81f3f37ca693364c6b77858Sergei Shtylyov desc_status >>= 16; 1419dd019897358b815f7828dab90b51d51df4d3658dYoshihiro Shimoda 142086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 | 142186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu RD_RFS5 | RD_RFS6 | RD_RFS10)) { 1422bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_errors++; 142386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (desc_status & RD_RFS1) 1424bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_crc_errors++; 142586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (desc_status & RD_RFS2) 1426bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_frame_errors++; 142786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (desc_status & RD_RFS3) 1428bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_length_errors++; 142986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (desc_status & RD_RFS4) 1430bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_length_errors++; 143186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (desc_status & RD_RFS6) 1432bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_missed_errors++; 143386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (desc_status & RD_RFS10) 1434bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_over_errors++; 143586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } else { 1436380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!mdp->cd->hw_swap) 1437380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda sh_eth_soft_swap( 1438380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda phys_to_virt(ALIGN(rxdesc->addr, 4)), 1439380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda pkt_len + 2); 144086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu skb = mdp->rx_skbuff[entry]; 144186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->rx_skbuff[entry] = NULL; 1442503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm if (mdp->cd->rpadir) 1443503914cf4a4b5dbe3f844e0a92f412ae99fde70eMagnus Damm skb_reserve(skb, NET_IP_ALIGN); 14447db8e0c14c9cb4adb667b4c558d8ffec8d5b40f2Kouei Abe dma_sync_single_for_cpu(&ndev->dev, rxdesc->addr, 14454d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura ALIGN(mdp->rx_buf_sz, 16), 14467db8e0c14c9cb4adb667b4c558d8ffec8d5b40f2Kouei Abe DMA_FROM_DEVICE); 144786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu skb_put(skb, pkt_len); 144886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu skb->protocol = eth_type_trans(skb, ndev); 1449a8e9fd0f7462f5cada5189513d12fe6c9cce2105Sergei Shtylyov netif_receive_skb(skb); 1450bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_packets++; 1451bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_bytes += pkt_len; 145286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 1453525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda entry = (++mdp->cur_rx) % mdp->num_rx_ring; 1454862df49750e7ca9369c04d8d8105b3cc5d976e0dYoshihiro Shimoda rxdesc = &mdp->rx_ring[entry]; 145586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 145686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 145786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Refill the Rx ring buffers. */ 145886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) { 1459525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda entry = mdp->dirty_rx % mdp->num_rx_ring; 146086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc = &mdp->rx_ring[entry]; 1461b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* The size of the buffer is 16 byte boundary. */ 14620029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16); 1463b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu 146486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (mdp->rx_skbuff[entry] == NULL) { 14654d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura skb = netdev_alloc_skb(ndev, skbuff_size); 146686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->rx_skbuff[entry] = skb; 146786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (skb == NULL) 146886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu break; /* Better luck next round. */ 1469380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda sh_eth_set_receive_align(skb); 14704d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura dma_map_single(&ndev->dev, skb->data, 14714d6a949c62f123569fb355b6ec7f314b76f93735Mitsuhiro Kimura rxdesc->buffer_length, DMA_FROM_DEVICE); 1472380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 1473bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet skb_checksum_none_assert(skb); 14740029d64af5d72049e2170e4609fa83bd1f3f07cdYoshihiro Shimoda rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); 147586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 1476525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (entry >= mdp->num_rx_ring - 1) 147786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc->status |= 147871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL); 147986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu else 148086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc->status |= 148171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato cpu_to_edmac(mdp, RD_RACT | RD_RFP); 148286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 148386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 148486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Restart Rx engine if stopped. */ 148586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* If we don't need to check status, don't. -KDU */ 148679fba9f51755c704c0a7d7b7f0df10874dc0a744Yoshihiro Shimoda if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { 1487a18e08bdcf845efb7344cea146e683df746bbfb4Yoshihiro Shimoda /* fix the values for the next receiving if RDE is set */ 1488128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov if (intr_status & EESR_RDE) { 1489128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov u32 count = (sh_eth_read(ndev, RDFAR) - 1490128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov sh_eth_read(ndev, RDLAR)) >> 4; 1491128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov 1492128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov mdp->cur_rx = count; 1493128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov mdp->dirty_rx = count; 1494128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov } 14954a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, EDRRR_R, EDRRR); 149679fba9f51755c704c0a7d7b7f0df10874dc0a744Yoshihiro Shimoda } 149786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 14984f809cea611f1f00a0b7a42751cb12d997a4c11cYoshihiro Shimoda return *quota <= 0; 149986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 150086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 15014a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_rcv_snd_disable(struct net_device *ndev) 1502dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1503dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* disable tx and rx */ 15044a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & 15054a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda ~(ECMR_RE | ECMR_TE), ECMR); 1506dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1507dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 15084a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_rcv_snd_enable(struct net_device *ndev) 1509dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1510dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* enable tx and rx */ 15114a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | 15124a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda (ECMR_RE | ECMR_TE), ECMR); 1513dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1514dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 151586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* error control function */ 151686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_error(struct net_device *ndev, int intr_status) 151786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 151886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 151986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u32 felic_stat; 1520380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda u32 link_stat; 1521380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda u32 mask; 152286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 152386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (intr_status & EESR_ECI) { 15244a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda felic_stat = sh_eth_read(ndev, ECSR); 15254a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, felic_stat, ECSR); /* clear int */ 152686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (felic_stat & ECSR_ICD) 1527bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_carrier_errors++; 152886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (felic_stat & ECSR_LCHNG) { 152986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Link Changed */ 15304923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda if (mdp->cd->no_psr || mdp->no_ether_link) { 15311e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov goto ignore_link; 1532380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda } else { 15334a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda link_stat = (sh_eth_read(ndev, PSR)); 15344923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda if (mdp->ether_link_active_low) 15354923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda link_stat = ~link_stat; 1536380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda } 1537128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov if (!(link_stat & PHY_ST_LINK)) { 15384a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_rcv_snd_disable(ndev); 1539128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov } else { 154086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Link Up */ 15414a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) & 1542128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov ~DMAC_M_ECI, EESIPR); 1543128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov /* clear int */ 15444a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, ECSR), 1545128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov ECSR); 15464a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) | 1547128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov DMAC_M_ECI, EESIPR); 154886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* enable tx and rx */ 15494a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_rcv_snd_enable(ndev); 155086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 155186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 155286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 155386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 15541e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyovignore_link: 155586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (intr_status & EESR_TWB) { 15564eb313a7a939a983c525648227b5fe0a9d41679fSergei Shtylyov /* Unused write back interrupt */ 15574eb313a7a939a983c525648227b5fe0a9d41679fSergei Shtylyov if (intr_status & EESR_TABT) { /* Transmit Abort int */ 1558bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_aborted_errors++; 15598d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, tx_err, ndev, "Transmit Abort\n"); 15604eb313a7a939a983c525648227b5fe0a9d41679fSergei Shtylyov } 156186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 156286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 156386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (intr_status & EESR_RABT) { 156486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Receive Abort int */ 156586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (intr_status & EESR_RFRMER) { 156686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Receive Frame Overflow int */ 1567bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_frame_errors++; 15688d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, rx_err, ndev, "Receive Abort\n"); 156986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 157086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 1571380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 1572dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu if (intr_status & EESR_TDE) { 1573dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* Transmit Descriptor Empty int */ 1574bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_fifo_errors++; 15758d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, tx_err, ndev, "Transmit Descriptor Empty\n"); 1576dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu } 1577dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1578dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu if (intr_status & EESR_TFE) { 1579dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* FIFO under flow */ 1580bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_fifo_errors++; 15818d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, tx_err, ndev, "Transmit FIFO Under flow\n"); 158286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 158386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 158486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (intr_status & EESR_RDE) { 158586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Receive Descriptor Empty int */ 1586bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_over_errors++; 15878d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, rx_err, ndev, "Receive Descriptor Empty\n"); 158886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 1589dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 159086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (intr_status & EESR_RFE) { 159186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Receive FIFO Overflow int */ 1592bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.rx_fifo_errors++; 15938d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, rx_err, ndev, "Receive FIFO Overflow\n"); 1594dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu } 1595dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1596dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu if (!mdp->cd->no_ade && (intr_status & EESR_ADE)) { 1597dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* Address Error */ 1598bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_fifo_errors++; 15998d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, tx_err, ndev, "Address Error\n"); 160086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 1601380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 1602380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE; 1603380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->no_ade) 1604380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda mask &= ~EESR_ADE; 1605380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (intr_status & mask) { 160686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Tx error */ 16074a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda u32 edtrr = sh_eth_read(ndev, EDTRR); 1608090d560fc4723f61b561c8fceb810d4645b49b4cSergei Shtylyov 160986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* dmesg */ 1610da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_err(ndev, "TX error. status=%8.8x cur_tx=%8.8x dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n", 1611da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov intr_status, mdp->cur_tx, mdp->dirty_tx, 1612da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov (u32)ndev->state, edtrr); 161386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* dirty buffer free */ 161486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu sh_eth_txfree(ndev); 161586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 161686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* SH7712 BUG */ 1617c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) { 161886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* tx dma start */ 1619c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR); 162086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 162186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* wakeup */ 162286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu netif_wake_queue(ndev); 162386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 162486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 162586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 162686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic irqreturn_t sh_eth_interrupt(int irq, void *netdev) 162786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 162886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct net_device *ndev = netdev; 162986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 1630380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda struct sh_eth_cpu_data *cd = mdp->cd; 16310e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu irqreturn_t ret = IRQ_NONE; 16323719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov unsigned long intr_status, intr_enable; 163386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 163486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu spin_lock(&mdp->lock); 163586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 16363893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov /* Get interrupt status */ 16374a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda intr_status = sh_eth_read(ndev, EESR); 16383893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov /* Mask it with the interrupt mask, forcing ECI interrupt to be always 16393893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov * enabled since it's the one that comes thru regardless of the mask, 16403893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov * and we need to fully handle it in sh_eth_error() in order to quench 16413893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov * it as it doesn't get cleared by just writing 1 to the ECI bit... 16423893b27345ac0ff13c1b9ec20ad50966b810997eSergei Shtylyov */ 16433719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov intr_enable = sh_eth_read(ndev, EESIPR); 16443719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov intr_status &= intr_enable | DMAC_M_ECI; 16453719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov if (intr_status & (EESR_RX_CHECK | cd->tx_check | cd->eesr_err_check)) 16460e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu ret = IRQ_HANDLED; 16473719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov else 16480e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu goto other_irq; 164986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 16503719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov if (intr_status & EESR_RX_CHECK) { 16513719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov if (napi_schedule_prep(&mdp->napi)) { 16523719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov /* Mask Rx interrupts */ 16533719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov sh_eth_write(ndev, intr_enable & ~EESR_RX_CHECK, 16543719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov EESIPR); 16553719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov __napi_schedule(&mdp->napi); 16563719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov } else { 1657da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_warn(ndev, 1658da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov "ignoring interrupt, status 0x%08lx, mask 0x%08lx.\n", 1659da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov intr_status, intr_enable); 16603719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov } 16613719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov } 166286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1663b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu /* Tx Check */ 1664380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (intr_status & cd->tx_check) { 16653719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov /* Clear Tx interrupts */ 16663719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov sh_eth_write(ndev, intr_status & cd->tx_check, EESR); 16673719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 166886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu sh_eth_txfree(ndev); 166986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu netif_wake_queue(ndev); 167086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 167186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 16723719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov if (intr_status & cd->eesr_err_check) { 16733719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov /* Clear error interrupts */ 16743719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov sh_eth_write(ndev, intr_status & cd->eesr_err_check, EESR); 16753719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 167686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu sh_eth_error(ndev, intr_status); 16773719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov } 167886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 16790e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsuother_irq: 168086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu spin_unlock(&mdp->lock); 168186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 16820e0fde3c8d65524b8dfd834332d6e4a92711a66aNobuhiro Iwamatsu return ret; 168386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 168486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 16853719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovstatic int sh_eth_poll(struct napi_struct *napi, int budget) 16863719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov{ 16873719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov struct sh_eth_private *mdp = container_of(napi, struct sh_eth_private, 16883719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov napi); 16893719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov struct net_device *ndev = napi->dev; 16903719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov int quota = budget; 16913719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov unsigned long intr_status; 16923719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 16933719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov for (;;) { 16943719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov intr_status = sh_eth_read(ndev, EESR); 16953719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov if (!(intr_status & EESR_RX_CHECK)) 16963719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov break; 16973719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov /* Clear Rx interrupts */ 16983719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov sh_eth_write(ndev, intr_status & EESR_RX_CHECK, EESR); 16993719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 17003719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov if (sh_eth_rx(ndev, intr_status, "a)) 17013719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov goto out; 17023719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov } 17033719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 17043719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov napi_complete(napi); 17053719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 17063719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov /* Reenable Rx interrupts */ 17073719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); 17083719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovout: 17093719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov return budget - quota; 17103719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov} 17113719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 171286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY state control function */ 171386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_adjust_link(struct net_device *ndev) 171486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 171586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 171686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct phy_device *phydev = mdp->phydev; 171786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int new_state = 0; 171886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 17193340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov if (phydev->link) { 172086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (phydev->duplex != mdp->duplex) { 172186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu new_state = 1; 172286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->duplex = phydev->duplex; 1723380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->set_duplex) 1724380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda mdp->cd->set_duplex(ndev); 172586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 172686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 172786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (phydev->speed != mdp->speed) { 172886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu new_state = 1; 172986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->speed = phydev->speed; 1730380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->set_rate) 1731380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda mdp->cd->set_rate(ndev); 173286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 17333340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov if (!mdp->link) { 173491a5615203355bb34e0b9e68e94f27f24719a74cYoshihiro Shimoda sh_eth_write(ndev, 1735128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov sh_eth_read(ndev, ECMR) & ~ECMR_TXF, 1736128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov ECMR); 173786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu new_state = 1; 173886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->link = phydev->link; 17391e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov if (mdp->cd->no_psr || mdp->no_ether_link) 17401e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov sh_eth_rcv_snd_enable(ndev); 174186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 174286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } else if (mdp->link) { 174386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu new_state = 1; 17443340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov mdp->link = 0; 174586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->speed = 0; 174686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->duplex = -1; 17471e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov if (mdp->cd->no_psr || mdp->no_ether_link) 17481e1b812bbe1069fc8e2e372dca7d5f541c7a8cebSergei Shtylyov sh_eth_rcv_snd_disable(ndev); 174986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 175086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1751dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu if (new_state && netif_msg_link(mdp)) 175286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu phy_print_status(phydev); 175386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 175486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 175586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY init function */ 175686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_phy_init(struct net_device *ndev) 175786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 1758702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks struct device_node *np = ndev->dev.parent->of_node; 175986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 176086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct phy_device *phydev = NULL; 176186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 17623340d2aae3433ad9147f6bf0adc452b324e31591Sergei Shtylyov mdp->link = 0; 176386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->speed = 0; 176486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->duplex = -1; 176586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 176686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Try connect to PHY */ 1767702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks if (np) { 1768702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks struct device_node *pn; 1769702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks 1770702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks pn = of_parse_phandle(np, "phy-handle", 0); 1771702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks phydev = of_phy_connect(ndev, pn, 1772702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks sh_eth_adjust_link, 0, 1773702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks mdp->phy_interface); 1774702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks 1775702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks if (!phydev) 1776702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks phydev = ERR_PTR(-ENOENT); 1777702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks } else { 1778702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks char phy_id[MII_BUS_ID_SIZE + 3]; 1779702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks 1780702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, 1781702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks mdp->mii_bus->id, mdp->phy_id); 1782702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks 1783702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link, 1784702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks mdp->phy_interface); 1785702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks } 1786702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks 178786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (IS_ERR(phydev)) { 1788da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_err(ndev, "failed to connect PHY\n"); 178986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return PTR_ERR(phydev); 179086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 1791380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 1792da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_info(ndev, "attached PHY %d (IRQ %d) to driver %s\n", 1793da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov phydev->addr, phydev->irq, phydev->drv->name); 179486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 179586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->phydev = phydev; 179686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 179786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return 0; 179886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 179986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 180086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* PHY control start function */ 180186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_phy_start(struct net_device *ndev) 180286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 180386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 180486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int ret; 180586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 180686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = sh_eth_phy_init(ndev); 180786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ret) 180886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 180986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 181086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu phy_start(mdp->phydev); 181186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 181286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return 0; 181386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 181486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 1815dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_get_settings(struct net_device *ndev, 1816128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov struct ethtool_cmd *ecmd) 1817dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1818dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 1819dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu unsigned long flags; 1820dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu int ret; 1821dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1822dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu spin_lock_irqsave(&mdp->lock, flags); 1823dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu ret = phy_ethtool_gset(mdp->phydev, ecmd); 1824dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu spin_unlock_irqrestore(&mdp->lock, flags); 1825dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1826dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu return ret; 1827dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1828dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1829dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_set_settings(struct net_device *ndev, 1830128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov struct ethtool_cmd *ecmd) 1831dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1832dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 1833dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu unsigned long flags; 1834dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu int ret; 1835dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1836dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu spin_lock_irqsave(&mdp->lock, flags); 1837dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1838dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* disable tx and rx */ 18394a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_rcv_snd_disable(ndev); 1840dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1841dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu ret = phy_ethtool_sset(mdp->phydev, ecmd); 1842dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu if (ret) 1843dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu goto error_exit; 1844dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1845dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu if (ecmd->duplex == DUPLEX_FULL) 1846dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu mdp->duplex = 1; 1847dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu else 1848dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu mdp->duplex = 0; 1849dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1850dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu if (mdp->cd->set_duplex) 1851dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu mdp->cd->set_duplex(ndev); 1852dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1853dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsuerror_exit: 1854dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu mdelay(1); 1855dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1856dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* enable tx and rx */ 18574a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_rcv_snd_enable(ndev); 1858dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1859dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu spin_unlock_irqrestore(&mdp->lock, flags); 1860dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1861dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu return ret; 1862dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1863dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1864dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_nway_reset(struct net_device *ndev) 1865dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1866dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 1867dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu unsigned long flags; 1868dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu int ret; 1869dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1870dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu spin_lock_irqsave(&mdp->lock, flags); 1871dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu ret = phy_start_aneg(mdp->phydev); 1872dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu spin_unlock_irqrestore(&mdp->lock, flags); 1873dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1874dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu return ret; 1875dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1876dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1877dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic u32 sh_eth_get_msglevel(struct net_device *ndev) 1878dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1879dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 1880dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu return mdp->msg_enable; 1881dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1882dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1883dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_set_msglevel(struct net_device *ndev, u32 value) 1884dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1885dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 1886dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu mdp->msg_enable = value; 1887dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1888dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1889dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic const char sh_eth_gstrings_stats[][ETH_GSTRING_LEN] = { 1890dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu "rx_current", "tx_current", 1891dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu "rx_dirty", "tx_dirty", 1892dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}; 1893dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu#define SH_ETH_STATS_LEN ARRAY_SIZE(sh_eth_gstrings_stats) 1894dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1895dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic int sh_eth_get_sset_count(struct net_device *netdev, int sset) 1896dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1897dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu switch (sset) { 1898dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu case ETH_SS_STATS: 1899dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu return SH_ETH_STATS_LEN; 1900dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu default: 1901dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu return -EOPNOTSUPP; 1902dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu } 1903dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1904dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1905dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_get_ethtool_stats(struct net_device *ndev, 1906128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov struct ethtool_stats *stats, u64 *data) 1907dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1908dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 1909dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu int i = 0; 1910dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1911dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* device-specific stats */ 1912dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu data[i++] = mdp->cur_rx; 1913dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu data[i++] = mdp->cur_tx; 1914dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu data[i++] = mdp->dirty_rx; 1915dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu data[i++] = mdp->dirty_tx; 1916dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1917dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1918dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsustatic void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data) 1919dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu{ 1920dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu switch (stringset) { 1921dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu case ETH_SS_STATS: 1922dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu memcpy(data, *sh_eth_gstrings_stats, 1923128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov sizeof(sh_eth_gstrings_stats)); 1924dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu break; 1925dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu } 1926dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu} 1927dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 1928525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic void sh_eth_get_ringparam(struct net_device *ndev, 1929525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda struct ethtool_ringparam *ring) 1930525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda{ 1931525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 1932525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1933525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ring->rx_max_pending = RX_RING_MAX; 1934525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ring->tx_max_pending = TX_RING_MAX; 1935525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ring->rx_pending = mdp->num_rx_ring; 1936525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ring->tx_pending = mdp->num_tx_ring; 1937525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda} 1938525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1939525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimodastatic int sh_eth_set_ringparam(struct net_device *ndev, 1940525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda struct ethtool_ringparam *ring) 1941525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda{ 1942525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 1943525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda int ret; 1944525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1945525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (ring->tx_pending > TX_RING_MAX || 1946525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ring->rx_pending > RX_RING_MAX || 1947525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ring->tx_pending < TX_RING_MIN || 1948525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ring->rx_pending < RX_RING_MIN) 1949525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda return -EINVAL; 1950525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (ring->rx_mini_pending || ring->rx_jumbo_pending) 1951525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda return -EINVAL; 1952525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1953525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (netif_running(ndev)) { 1954525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda netif_tx_disable(ndev); 1955525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda /* Disable interrupts by clearing the interrupt mask. */ 1956525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, 0x0000, EESIPR); 1957525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda /* Stop the chip's Tx and Rx processes. */ 1958525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, 0, EDTRR); 1959525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, 0, EDRRR); 1960525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda synchronize_irq(ndev->irq); 1961525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda } 1962525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1963525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda /* Free all the skbuffs in the Rx queue. */ 1964525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_ring_free(ndev); 1965525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda /* Free DMA buffer */ 1966525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_free_dma_buffer(mdp); 1967525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1968525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda /* Set new parameters */ 1969525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda mdp->num_rx_ring = ring->rx_pending; 1970525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda mdp->num_tx_ring = ring->tx_pending; 1971525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1972525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ret = sh_eth_ring_init(ndev); 1973525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (ret < 0) { 1974da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_err(ndev, "%s: sh_eth_ring_init failed.\n", __func__); 1975525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda return ret; 1976525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda } 1977525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ret = sh_eth_dev_init(ndev, false); 1978525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (ret < 0) { 1979da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_err(ndev, "%s: sh_eth_dev_init failed.\n", __func__); 1980525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda return ret; 1981525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda } 1982525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1983525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (netif_running(ndev)) { 1984525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR); 1985525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda /* Setting the Rx mode will start the Rx process. */ 1986525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_write(ndev, EDRRR_R, EDRRR); 1987525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda netif_wake_queue(ndev); 1988525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda } 1989525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 1990525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda return 0; 1991525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda} 1992525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda 19939b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemmingerstatic const struct ethtool_ops sh_eth_ethtool_ops = { 1994dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu .get_settings = sh_eth_get_settings, 1995dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu .set_settings = sh_eth_set_settings, 19969b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemminger .nway_reset = sh_eth_nway_reset, 1997dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu .get_msglevel = sh_eth_get_msglevel, 1998dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu .set_msglevel = sh_eth_set_msglevel, 19999b07be4b2a78166bc54c8eedf18da8a8aafacfabstephen hemminger .get_link = ethtool_op_get_link, 2000dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu .get_strings = sh_eth_get_strings, 2001dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu .get_ethtool_stats = sh_eth_get_ethtool_stats, 2002dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu .get_sset_count = sh_eth_get_sset_count, 2003525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda .get_ringparam = sh_eth_get_ringparam, 2004525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda .set_ringparam = sh_eth_set_ringparam, 2005dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu}; 2006dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu 200786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* network device open function */ 200886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_open(struct net_device *ndev) 200986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 201086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int ret = 0; 201186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 201286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2013bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm pm_runtime_get_sync(&mdp->pdev->dev); 2014bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm 2015d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov napi_enable(&mdp->napi); 2016d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov 2017a0607fd3a25ba1848a63a0d925e36d914735ab47Joe Perches ret = request_irq(ndev->irq, sh_eth_interrupt, 20185b3dfd13ae8bdebea67c02612fe282baff850bb0Nobuhiro Iwamatsu mdp->cd->irq_flags, ndev->name, ndev); 201986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ret) { 2020da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_err(ndev, "Can not assign IRQ number\n"); 2021d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov goto out_napi_off; 202286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 202386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 202486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Descriptor set */ 202586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = sh_eth_ring_init(ndev); 202686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ret) 202786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto out_free_irq; 202886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 202986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* device init */ 2030525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda ret = sh_eth_dev_init(ndev, true); 203186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ret) 203286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto out_free_irq; 203386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 203486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* PHY control start*/ 203586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = sh_eth_phy_start(ndev); 203686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ret) 203786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto out_free_irq; 203886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 20397fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura mdp->is_opened = 1; 20407fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura 204186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 204286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 204386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_free_irq: 204486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu free_irq(ndev->irq, ndev); 2045d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyovout_napi_off: 2046d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov napi_disable(&mdp->napi); 2047bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm pm_runtime_put_sync(&mdp->pdev->dev); 204886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 204986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 205086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 205186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Timeout function */ 205286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_tx_timeout(struct net_device *ndev) 205386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 205486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 205586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_rxdesc *rxdesc; 205686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int i; 205786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 205886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu netif_stop_queue(ndev); 205986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 20608d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_err(mdp, timer, ndev, 20618d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov "transmit timed out, status %8.8x, resetting...\n", 20628d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov (int)sh_eth_read(ndev, EESR)); 206386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 206486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* tx_errors count up */ 2065bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet ndev->stats.tx_errors++; 206686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 206786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Free all the skbuffs in the Rx queue. */ 2068525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda for (i = 0; i < mdp->num_rx_ring; i++) { 206986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc = &mdp->rx_ring[i]; 207086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc->status = 0; 207186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu rxdesc->addr = 0xBADF00D0; 2072179d80aff82bf8dff9db30589fe5a2297c454d35Sergei Shtylyov dev_kfree_skb(mdp->rx_skbuff[i]); 207386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->rx_skbuff[i] = NULL; 207486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 2075525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda for (i = 0; i < mdp->num_tx_ring; i++) { 2076179d80aff82bf8dff9db30589fe5a2297c454d35Sergei Shtylyov dev_kfree_skb(mdp->tx_skbuff[i]); 207786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->tx_skbuff[i] = NULL; 207886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 207986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 208086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* device init */ 2081525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda sh_eth_dev_init(ndev, true); 208286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 208386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 208486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Packet transmit function */ 208586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) 208686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 208786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 208886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_txdesc *txdesc; 208986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu u32 entry; 2090fb5e2f9b9410a4362897d12dc1ed4f7cec1b0d45Nobuhiro Iwamatsu unsigned long flags; 209186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 209286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu spin_lock_irqsave(&mdp->lock, flags); 2093525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) { 209486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!sh_eth_txfree(ndev)) { 20958d5009f6a9d9f4ef62a39bf68b53379b2b766c1cSergei Shtylyov netif_warn(mdp, tx_queued, ndev, "TxFD exhausted.\n"); 209686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu netif_stop_queue(ndev); 209786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu spin_unlock_irqrestore(&mdp->lock, flags); 20985b548140225c6bbbbd560551dd1048b2c0ce58bePatrick McHardy return NETDEV_TX_BUSY; 209986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 210086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 210186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu spin_unlock_irqrestore(&mdp->lock, flags); 210286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2103525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda entry = mdp->cur_tx % mdp->num_tx_ring; 210486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->tx_skbuff[entry] = skb; 210586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu txdesc = &mdp->tx_ring[entry]; 210686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* soft swap. */ 2107380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (!mdp->cd->hw_swap) 2108380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)), 2109380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda skb->len + 2); 211031fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda txdesc->addr = dma_map_single(&ndev->dev, skb->data, skb->len, 211131fcb99d9958bdf04e84224e202f69e6cdac893bYoshihiro Shimoda DMA_TO_DEVICE); 2112730c8c69bc8d4640336885e20e719b0842d0fcb2Sergei Shtylyov if (skb->len < ETH_ZLEN) 2113730c8c69bc8d4640336885e20e719b0842d0fcb2Sergei Shtylyov txdesc->buffer_length = ETH_ZLEN; 211486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu else 211586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu txdesc->buffer_length = skb->len; 211686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2117525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda if (entry >= mdp->num_tx_ring - 1) 211871557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE); 211986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu else 212071557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato txdesc->status |= cpu_to_edmac(mdp, TD_TACT); 212186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 212286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->cur_tx++; 212386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2124c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp))) 2125c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR); 2126b0ca2a21f769ae255bd6821cbc5af8af797f1da7Nobuhiro Iwamatsu 21276ed106549d17474ca17a16057f4c0ed4eba5a7caPatrick McHardy return NETDEV_TX_OK; 212886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 212986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 21307fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimurastatic struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) 21317fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura{ 21327fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura struct sh_eth_private *mdp = netdev_priv(ndev); 21337fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura 21347fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura if (sh_eth_is_rz_fast_ether(mdp)) 21357fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura return &ndev->stats; 21367fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura 21377fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura if (!mdp->is_opened) 21387fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura return &ndev->stats; 21397fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura 21407fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura ndev->stats.tx_dropped += sh_eth_read(ndev, TROCR); 21417fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura sh_eth_write(ndev, 0, TROCR); /* (write clear) */ 21427fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura ndev->stats.collisions += sh_eth_read(ndev, CDCR); 21437fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura sh_eth_write(ndev, 0, CDCR); /* (write clear) */ 21447fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura ndev->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR); 21457fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura sh_eth_write(ndev, 0, LCCR); /* (write clear) */ 21467fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura 21477fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura if (sh_eth_is_gether(mdp)) { 21487fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR); 21497fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura sh_eth_write(ndev, 0, CERCR); /* (write clear) */ 21507fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR); 21517fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura sh_eth_write(ndev, 0, CEECR); /* (write clear) */ 21527fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura } else { 21537fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura ndev->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR); 21547fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura sh_eth_write(ndev, 0, CNDCR); /* (write clear) */ 21557fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura } 21567fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura 21577fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura return &ndev->stats; 21587fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura} 21597fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura 216086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* device close function */ 216186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_close(struct net_device *ndev) 216286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 216386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 216486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 216586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu netif_stop_queue(ndev); 216686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 216786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Disable interrupts by clearing the interrupt mask. */ 21684a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0x0000, EESIPR); 216986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 217086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Stop the chip's Tx and Rx processes. */ 21714a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0, EDTRR); 21724a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_write(ndev, 0, EDRRR); 217386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 21747fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura sh_eth_get_stats(ndev); 217586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* PHY Disconnect */ 217686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (mdp->phydev) { 217786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu phy_stop(mdp->phydev); 217886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu phy_disconnect(mdp->phydev); 217986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 218086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 218186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu free_irq(ndev->irq, ndev); 218286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2183d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov napi_disable(&mdp->napi); 2184d2779e99468fd83ef1493c34f3803fec9aad8345Sergei Shtylyov 218586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Free all the skbuffs in the Rx queue. */ 218686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu sh_eth_ring_free(ndev); 218786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 218886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* free DMA buffer */ 218991c77550000a7d888aaf9f9ac13e3e3485d18560Yoshihiro Shimoda sh_eth_free_dma_buffer(mdp); 219086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2191bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm pm_runtime_put_sync(&mdp->pdev->dev); 2192bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm 21937fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura mdp->is_opened = 0; 2194bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm 21957fa2955ff70ce4532f144d26b8a087095f9c9ffcMitsuhiro Kimura return 0; 219686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 219786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2198bb7d92e3e3049e22b5807ac559a72b38fad5f499Eric Dumazet/* ioctl to device function */ 2199128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyovstatic int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) 220086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 220186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct sh_eth_private *mdp = netdev_priv(ndev); 220286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct phy_device *phydev = mdp->phydev; 220386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 220486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!netif_running(ndev)) 220586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return -EINVAL; 220686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 220786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!phydev) 220886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return -ENODEV; 220986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 221028b041139e344ecd0f144d6205b004ae354cfa1eRichard Cochran return phy_mii_ioctl(phydev, rq, cmd); 221186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 221286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 22136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda/* For TSU_POSTn. Please refer to the manual about this (strange) bitfields */ 22146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void *sh_eth_tsu_get_post_reg_offset(struct sh_eth_private *mdp, 22156743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int entry) 22166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return sh_eth_tsu_get_offset(mdp, TSU_POST1) + (entry / 8 * 4); 22186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 22196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic u32 sh_eth_tsu_get_post_mask(int entry) 22216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0x0f << (28 - ((entry % 8) * 4)); 22236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 22246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic u32 sh_eth_tsu_get_post_bit(struct sh_eth_private *mdp, int entry) 22266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return (0x08 >> (mdp->port << 1)) << (28 - ((entry % 8) * 4)); 22286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 22296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_enable_cam_entry_post(struct net_device *ndev, 22316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int entry) 22326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 22346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u32 tmp; 22356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda void *reg_offset; 22366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry); 22386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda tmp = ioread32(reg_offset); 22396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda iowrite32(tmp | sh_eth_tsu_get_post_bit(mdp, entry), reg_offset); 22406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 22416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic bool sh_eth_tsu_disable_cam_entry_post(struct net_device *ndev, 22436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int entry) 22446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22456743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 22466743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u32 post_mask, ref_mask, tmp; 22476743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda void *reg_offset; 22486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda reg_offset = sh_eth_tsu_get_post_reg_offset(mdp, entry); 22506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda post_mask = sh_eth_tsu_get_post_mask(entry); 22516743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ref_mask = sh_eth_tsu_get_post_bit(mdp, entry) & ~post_mask; 22526743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda tmp = ioread32(reg_offset); 22546743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda iowrite32(tmp & ~post_mask, reg_offset); 22556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* If other port enables, the function returns "true" */ 22576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return tmp & ref_mask; 22586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 22596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_busy(struct net_device *ndev) 22616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int timeout = SH_ETH_TSU_TIMEOUT_MS * 100; 22636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 22646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda while ((sh_eth_tsu_read(mdp, TSU_ADSBSY) & TSU_ADSBSY_0)) { 22666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda udelay(10); 22676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda timeout--; 22686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (timeout <= 0) { 2269da2468555643efbde3fb026cd46e5245800cc872Sergei Shtylyov netdev_err(ndev, "%s: timeout\n", __func__); 22706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return -ETIMEDOUT; 22716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 22726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 22736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 22756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 22766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_write_entry(struct net_device *ndev, void *reg, 22786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda const u8 *addr) 22796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u32 val; 22816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda val = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3]; 22836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda iowrite32(val, reg); 22846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (sh_eth_tsu_busy(ndev) < 0) 22856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return -EBUSY; 22866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda val = addr[4] << 8 | addr[5]; 22886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda iowrite32(val, reg + 4); 22896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (sh_eth_tsu_busy(ndev) < 0) 22906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return -EBUSY; 22916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22926743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 22936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 22946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22956743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_read_entry(void *reg, u8 *addr) 22966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 22976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u32 val; 22986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 22996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda val = ioread32(reg); 23006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda addr[0] = (val >> 24) & 0xff; 23016743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda addr[1] = (val >> 16) & 0xff; 23026743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda addr[2] = (val >> 8) & 0xff; 23036743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda addr[3] = val & 0xff; 23046743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda val = ioread32(reg + 4); 23056743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda addr[4] = (val >> 8) & 0xff; 23066743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda addr[5] = val & 0xff; 23076743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 23086743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23096743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23106743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_find_entry(struct net_device *ndev, const u8 *addr) 23116743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 23126743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 23136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); 23146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int i; 23156743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u8 c_addr[ETH_ALEN]; 23166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { 23186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_read_entry(reg_offset, c_addr); 2319c4bde29cb0f3a520e3dd666e523f9a576a47a47adingtianhong if (ether_addr_equal(addr, c_addr)) 23206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return i; 23216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 23226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return -ENOENT; 23246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 23256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_find_empty(struct net_device *ndev) 23276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 23286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u8 blank[ETH_ALEN]; 23296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int entry; 23306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda memset(blank, 0, sizeof(blank)); 23326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda entry = sh_eth_tsu_find_entry(ndev, blank); 23336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return (entry < 0) ? -ENOMEM : entry; 23346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 23356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_disable_cam_entry_table(struct net_device *ndev, 23376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int entry) 23386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 23396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 23406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); 23416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int ret; 23426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u8 blank[ETH_ALEN]; 23436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) & 23456743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ~(1 << (31 - entry)), TSU_TEN); 23466743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23476743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda memset(blank, 0, sizeof(blank)); 23486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ret = sh_eth_tsu_write_entry(ndev, reg_offset + entry * 8, blank); 23496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (ret < 0) 23506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return ret; 23516743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 23526743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 23536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23546743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_add_entry(struct net_device *ndev, const u8 *addr) 23556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 23566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 23576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); 23586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int i, ret; 23596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (!mdp->cd->tsu) 23616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 23626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda i = sh_eth_tsu_find_entry(ndev, addr); 23646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (i < 0) { 23656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* No entry found, create one */ 23666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda i = sh_eth_tsu_find_empty(ndev); 23676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (i < 0) 23686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return -ENOMEM; 23696743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ret = sh_eth_tsu_write_entry(ndev, reg_offset + i * 8, addr); 23706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (ret < 0) 23716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return ret; 23726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* Enable the entry */ 23746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_write(mdp, sh_eth_tsu_read(mdp, TSU_TEN) | 23756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda (1 << (31 - i)), TSU_TEN); 23766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 23776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* Entry found or created, enable POST */ 23796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_enable_cam_entry_post(ndev, i); 23806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 23826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 23836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_del_entry(struct net_device *ndev, const u8 *addr) 23856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 23866743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 23876743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int i, ret; 23886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23896743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (!mdp->cd->tsu) 23906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 23916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23926743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda i = sh_eth_tsu_find_entry(ndev, addr); 23936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (i) { 23946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* Entry found */ 23956743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (sh_eth_tsu_disable_cam_entry_post(ndev, i)) 23966743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda goto done; 23976743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 23986743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* Disable the entry if both ports was disabled */ 23996743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ret = sh_eth_tsu_disable_cam_entry_table(ndev, i); 24006743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (ret < 0) 24016743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return ret; 24026743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 24036743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodadone: 24046743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 24056743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 24066743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24076743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic int sh_eth_tsu_purge_all(struct net_device *ndev) 24086743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 24096743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 24106743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int i, ret; 24116743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24126743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (unlikely(!mdp->cd->tsu)) 24136743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 24146743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24156743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++) { 24166743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (sh_eth_tsu_disable_cam_entry_post(ndev, i)) 24176743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda continue; 24186743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24196743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* Disable the entry if both ports was disabled */ 24206743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ret = sh_eth_tsu_disable_cam_entry_table(ndev, i); 24216743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (ret < 0) 24226743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return ret; 24236743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 24246743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24256743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return 0; 24266743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 24276743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24286743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimodastatic void sh_eth_tsu_purge_mcast(struct net_device *ndev) 24296743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda{ 24306743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 24316743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u8 addr[ETH_ALEN]; 24326743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda void *reg_offset = sh_eth_tsu_get_offset(mdp, TSU_ADRH0); 24336743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int i; 24346743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24356743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (unlikely(!mdp->cd->tsu)) 24366743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda return; 24376743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24386743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES; i++, reg_offset += 8) { 24396743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_read_entry(reg_offset, addr); 24406743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (is_multicast_ether_addr(addr)) 24416743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_del_entry(ndev, addr); 24426743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 24436743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda} 24446743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 244586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* Multicast reception directions set */ 244686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic void sh_eth_set_multicast_list(struct net_device *ndev) 244786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 24486743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 24496743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda u32 ecmr_bits; 24506743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda int mcast_all = 0; 24516743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda unsigned long flags; 24526743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24536743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda spin_lock_irqsave(&mdp->lock, flags); 2454128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov /* Initial condition is MCT = 1, PRM = 0. 24556743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda * Depending on ndev->flags, set PRM or clear MCT 24566743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda */ 24576743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ecmr_bits = (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) | ECMR_MCT; 24586743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24596743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (!(ndev->flags & IFF_MULTICAST)) { 24606743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_purge_mcast(ndev); 24616743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda mcast_all = 1; 24626743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 24636743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (ndev->flags & IFF_ALLMULTI) { 24646743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_purge_mcast(ndev); 24656743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ecmr_bits &= ~ECMR_MCT; 24666743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda mcast_all = 1; 24676743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 24686743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 246986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ndev->flags & IFF_PROMISC) { 24706743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_purge_all(ndev); 24716743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ecmr_bits = (ecmr_bits & ~ECMR_MCT) | ECMR_PRM; 24726743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } else if (mdp->cd->tsu) { 24736743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda struct netdev_hw_addr *ha; 24746743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda netdev_for_each_mc_addr(ha, ndev) { 24756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (mcast_all && is_multicast_ether_addr(ha->addr)) 24766743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda continue; 24776743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24786743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (sh_eth_tsu_add_entry(ndev, ha->addr) < 0) { 24796743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda if (!mcast_all) { 24806743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_tsu_purge_mcast(ndev); 24816743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ecmr_bits &= ~ECMR_MCT; 24826743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda mcast_all = 1; 24836743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 24846743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 24856743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda } 248686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } else { 248786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Normal, unicast/broadcast-only mode. */ 24886743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda ecmr_bits = (ecmr_bits & ~ECMR_PRM) | ECMR_MCT; 248986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 24906743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24916743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda /* update the ethernet mode */ 24926743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda sh_eth_write(ndev, ecmr_bits, ECMR); 24936743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda 24946743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda spin_unlock_irqrestore(&mdp->lock, flags); 249586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 249671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 249771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimodastatic int sh_eth_get_vtag_index(struct sh_eth_private *mdp) 249871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{ 249971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda if (!mdp->port) 250071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return TSU_VTAG0; 250171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda else 250271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return TSU_VTAG1; 250371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda} 250471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 250580d5c3689b886308247da295a228a54df49a44f6Patrick McHardystatic int sh_eth_vlan_rx_add_vid(struct net_device *ndev, 250680d5c3689b886308247da295a228a54df49a44f6Patrick McHardy __be16 proto, u16 vid) 250771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{ 250871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 250971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda int vtag_reg_index = sh_eth_get_vtag_index(mdp); 251071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 251171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda if (unlikely(!mdp->cd->tsu)) 251271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return -EPERM; 251371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 251471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda /* No filtering if vid = 0 */ 251571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda if (!vid) 251671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return 0; 251771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 251871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda mdp->vlan_num_ids++; 251971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 2520128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov /* The controller has one VLAN tag HW filter. So, if the filter is 252171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda * already enabled, the driver disables it and the filte 252271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda */ 252371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda if (mdp->vlan_num_ids > 1) { 252471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda /* disable VLAN filter */ 252571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda sh_eth_tsu_write(mdp, 0, vtag_reg_index); 252671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return 0; 252771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda } 252871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 252971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda sh_eth_tsu_write(mdp, TSU_VTAG_ENABLE | (vid & TSU_VTAG_VID_MASK), 253071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda vtag_reg_index); 253171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 253271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return 0; 253371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda} 253471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 253580d5c3689b886308247da295a228a54df49a44f6Patrick McHardystatic int sh_eth_vlan_rx_kill_vid(struct net_device *ndev, 253680d5c3689b886308247da295a228a54df49a44f6Patrick McHardy __be16 proto, u16 vid) 253771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda{ 253871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda struct sh_eth_private *mdp = netdev_priv(ndev); 253971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda int vtag_reg_index = sh_eth_get_vtag_index(mdp); 254071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 254171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda if (unlikely(!mdp->cd->tsu)) 254271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return -EPERM; 254371cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 254471cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda /* No filtering if vid = 0 */ 254571cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda if (!vid) 254671cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return 0; 254771cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 254871cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda mdp->vlan_num_ids--; 254971cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda sh_eth_tsu_write(mdp, 0, vtag_reg_index); 255071cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda 255171cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda return 0; 255271cc7c37af71b497698f7f8a68e46a458071fcefYoshihiro Shimoda} 255386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 255486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* SuperH's TSU register init function */ 25554a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic void sh_eth_tsu_init(struct sh_eth_private *mdp) 255686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 2557db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman if (sh_eth_is_rz_fast_ether(mdp)) { 2558db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ 2559db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman return; 2560db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman } 2561db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman 25624a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_FWEN0); /* Disable forward(0->1) */ 25634a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_FWEN1); /* Disable forward(1->0) */ 25644a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_FCM); /* forward fifo 3k-3k */ 25654a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL0); 25664a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL1); 25674a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_PRISL0); 25684a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_PRISL1); 25694a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_FWSL0); 25704a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_FWSL1); 25714a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC); 2572c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda if (sh_eth_is_gether(mdp)) { 2573c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */ 2574c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */ 2575c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda } else { 2576c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */ 2577c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */ 2578c5ed53687b39c195b4730de8c0355c1b78054ba6Yoshihiro Shimoda } 25794a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_FWSR); /* all interrupt status clear */ 25804a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_FWINMK); /* Disable all interrupt */ 25814a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */ 25824a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_POST1); /* Disable CAM entry [ 0- 7] */ 25834a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_POST2); /* Disable CAM entry [ 8-15] */ 25844a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_POST3); /* Disable CAM entry [16-23] */ 25854a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda sh_eth_tsu_write(mdp, 0, TSU_POST4); /* Disable CAM entry [24-31] */ 258686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 258786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 258886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDIO bus release function */ 2589bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchartstatic int sh_mdio_release(struct sh_eth_private *mdp) 259086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 259186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* unregister mdio bus */ 2592bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchart mdiobus_unregister(mdp->mii_bus); 259386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 259486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* free bitbang info */ 2595bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchart free_mdio_bitbang(mdp->mii_bus); 259686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 259786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return 0; 259886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 259986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 260086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu/* MDIO bus init function */ 2601bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchartstatic int sh_mdio_init(struct sh_eth_private *mdp, 2602b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda struct sh_eth_plat_data *pd) 260386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 260486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu int ret, i; 260586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct bb_info *bitbang; 2606bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchart struct platform_device *pdev = mdp->pdev; 2607aa8d422510969b705656e49fc0166d862aca9246Laurent Pinchart struct device *dev = &mdp->pdev->dev; 260886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 260986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* create bit control struct for PHY */ 2610aa8d422510969b705656e49fc0166d862aca9246Laurent Pinchart bitbang = devm_kzalloc(dev, sizeof(struct bb_info), GFP_KERNEL); 2611f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart if (!bitbang) 2612f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart return -ENOMEM; 261386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 261486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* bitbang init */ 2615ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda bitbang->addr = mdp->addr + mdp->reg_offset[PIR]; 2616b3017e6a03d261778ad9450b5510460c4d462203Yoshihiro Shimoda bitbang->set_gate = pd->set_mdio_gate; 2617dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov bitbang->mdi_msk = PIR_MDI; 2618dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov bitbang->mdo_msk = PIR_MDO; 2619dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov bitbang->mmd_msk = PIR_MMD; 2620dfed5e7fb4ec946694cad7400d75c44f3bb7f645Sergei Shtylyov bitbang->mdc_msk = PIR_MDC; 262186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu bitbang->ctrl.ops = &bb_ops; 262286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2623c2e07b3a9ced33dd92597201be3931be8ea57ed6Stefan Weil /* MII controller setting */ 262486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl); 2625f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart if (!mdp->mii_bus) 2626f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart return -ENOMEM; 262786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 262886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* Hook up MII support for ethtool */ 262986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp->mii_bus->name = "sh_mii"; 2630a5bd60608936fbb84471a80592401ce29a68de71Laurent Pinchart mdp->mii_bus->parent = dev; 26315278fb547076ad6768d16c8b4df45c086470c163Florian Fainelli snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", 2632bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchart pdev->name, pdev->id); 263386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 263486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* PHY IRQ */ 263586b5d251d5ac4dda51a022b34cb29b4ce65a8cd5Sergei Shtylyov mdp->mii_bus->irq = devm_kmalloc_array(dev, PHY_MAX_ADDR, sizeof(int), 263686b5d251d5ac4dda51a022b34cb29b4ce65a8cd5Sergei Shtylyov GFP_KERNEL); 263786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (!mdp->mii_bus->irq) { 263886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = -ENOMEM; 263986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto out_free_bus; 264086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 264186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2642bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchart /* register MDIO bus */ 2643bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchart if (dev->of_node) { 2644bd920ff553ba17f19372501a14e432d9d92b102bLaurent Pinchart ret = of_mdiobus_register(mdp->mii_bus, dev->of_node); 2645702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks } else { 2646702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks for (i = 0; i < PHY_MAX_ADDR; i++) 2647702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks mdp->mii_bus->irq[i] = PHY_POLL; 2648702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks if (pd->phy_irq > 0) 2649702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks mdp->mii_bus->irq[pd->phy] = pd->phy_irq; 2650702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks 2651702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks ret = mdiobus_register(mdp->mii_bus); 2652702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks } 2653702eca02b7c8574b42359512ebccfa777a71f66eBen Dooks 265486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ret) 2655d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov goto out_free_bus; 265686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 265786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return 0; 265886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 265986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_free_bus: 2660298cf9beb9679522de995e249eccbd82f7c51999Lennert Buytenhek free_mdio_bitbang(mdp->mii_bus); 266186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 266286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 266386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 26644a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimodastatic const u16 *sh_eth_get_register_offset(int register_type) 26654a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda{ 26664a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda const u16 *reg_offset = NULL; 26674a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda 26684a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda switch (register_type) { 26694a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda case SH_ETH_REG_GIGABIT: 26704a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda reg_offset = sh_eth_offset_gigabit; 26714a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda break; 2672db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman case SH_ETH_REG_FAST_RZ: 2673db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman reg_offset = sh_eth_offset_fast_rz; 2674db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman break; 2675a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov case SH_ETH_REG_FAST_RCAR: 2676a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov reg_offset = sh_eth_offset_fast_rcar; 2677a3f109bd793dfe5c611220ca5ab6c72f1aed479eSergei Shtylyov break; 26784a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda case SH_ETH_REG_FAST_SH4: 26794a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda reg_offset = sh_eth_offset_fast_sh4; 26804a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda break; 26814a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda case SH_ETH_REG_FAST_SH3_SH2: 26824a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda reg_offset = sh_eth_offset_fast_sh3_sh2; 26834a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda break; 26844a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda default: 26854a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda break; 26864a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda } 26874a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda 26884a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda return reg_offset; 26894a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda} 26904a55530f38e4eeee3afb06093e81309138fe8360Yoshihiro Shimoda 26918f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyovstatic const struct net_device_ops sh_eth_netdev_ops = { 2692ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_open = sh_eth_open, 2693ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_stop = sh_eth_close, 2694ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_start_xmit = sh_eth_start_xmit, 2695ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_get_stats = sh_eth_get_stats, 2696ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_tx_timeout = sh_eth_tx_timeout, 2697ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_do_ioctl = sh_eth_do_ioctl, 2698ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_validate_addr = eth_validate_addr, 2699ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_set_mac_address = eth_mac_addr, 2700ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov .ndo_change_mtu = eth_change_mtu, 2701ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov}; 2702ebf84eaa927be41a440fd4c8f81e1844922bc0b2Alexander Beregalov 27038f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyovstatic const struct net_device_ops sh_eth_netdev_ops_tsu = { 27048f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_open = sh_eth_open, 27058f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_stop = sh_eth_close, 27068f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_start_xmit = sh_eth_start_xmit, 27078f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_get_stats = sh_eth_get_stats, 27088f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_set_rx_mode = sh_eth_set_multicast_list, 27098f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_vlan_rx_add_vid = sh_eth_vlan_rx_add_vid, 27108f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_vlan_rx_kill_vid = sh_eth_vlan_rx_kill_vid, 27118f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_tx_timeout = sh_eth_tx_timeout, 27128f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_do_ioctl = sh_eth_do_ioctl, 27138f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_validate_addr = eth_validate_addr, 27148f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_set_mac_address = eth_mac_addr, 27158f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov .ndo_change_mtu = eth_change_mtu, 27168f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov}; 27178f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov 2718b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#ifdef CONFIG_OF 2719b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyovstatic struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev) 2720b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov{ 2721b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov struct device_node *np = dev->of_node; 2722b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov struct sh_eth_plat_data *pdata; 2723b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov const char *mac_addr; 2724b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 2725b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 2726b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov if (!pdata) 2727b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov return NULL; 2728b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 2729b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov pdata->phy_interface = of_get_phy_mode(np); 2730b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 2731b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov mac_addr = of_get_mac_address(np); 2732b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov if (mac_addr) 2733b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov memcpy(pdata->mac_addr, mac_addr, ETH_ALEN); 2734b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 2735b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov pdata->no_ether_link = 2736b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov of_property_read_bool(np, "renesas,no-ether-link"); 2737b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov pdata->ether_link_active_low = 2738b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov of_property_read_bool(np, "renesas,ether-link-active-low"); 2739b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 2740b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov return pdata; 2741b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov} 2742b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 2743b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyovstatic const struct of_device_id sh_eth_match_table[] = { 2744b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov { .compatible = "renesas,gether-r8a7740", .data = &r8a7740_data }, 2745b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov { .compatible = "renesas,ether-r8a7778", .data = &r8a777x_data }, 2746b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov { .compatible = "renesas,ether-r8a7779", .data = &r8a777x_data }, 2747b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov { .compatible = "renesas,ether-r8a7790", .data = &r8a779x_data }, 2748b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov { .compatible = "renesas,ether-r8a7791", .data = &r8a779x_data }, 27490f76b9d83b2b010b63a094024b3cfd82e20af28dHisashi Nakamura { .compatible = "renesas,ether-r8a7794", .data = &r8a779x_data }, 2750b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov { .compatible = "renesas,ether-r7s72100", .data = &r7s72100_data }, 2751b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov { } 2752b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov}; 2753b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei ShtylyovMODULE_DEVICE_TABLE(of, sh_eth_match_table); 2754b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#else 2755b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyovstatic inline struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev) 2756b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov{ 2757b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov return NULL; 2758b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov} 2759b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov#endif 2760b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 276186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_drv_probe(struct platform_device *pdev) 276286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 27639c38657cfcb739b7dc4ce9065a85b4f0c195bef8Kuninori Morimoto int ret, devno = 0; 276486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct resource *res; 276586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct net_device *ndev = NULL; 2766ec0d75518cb06261f1823fa2713fe52b9b26455eKuninori Morimoto struct sh_eth_private *mdp = NULL; 27670b76b86235296efeabe49f79a3e70336cff9664eJingoo Han struct sh_eth_plat_data *pd = dev_get_platdata(&pdev->dev); 2768afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov const struct platform_device_id *id = platform_get_device_id(pdev); 276986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 277086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* get base addr */ 277186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 277286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (unlikely(res == NULL)) { 277386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu dev_err(&pdev->dev, "invalid resource\n"); 2774f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart return -EINVAL; 277586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 277686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 277786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ndev = alloc_etherdev(sizeof(struct sh_eth_private)); 2778f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart if (!ndev) 2779f738a13d8365b0f824f3f20450b413f55374f175Laurent Pinchart return -ENOMEM; 278086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2781b5893a08812602de164fa5ac6494f84df8d09a4fBen Dooks pm_runtime_enable(&pdev->dev); 2782b5893a08812602de164fa5ac6494f84df8d09a4fBen Dooks pm_runtime_get_sync(&pdev->dev); 2783b5893a08812602de164fa5ac6494f84df8d09a4fBen Dooks 278486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* The sh Ether-specific entries in the device structure. */ 278586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ndev->base_addr = res->start; 278686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu devno = pdev->id; 278786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (devno < 0) 278886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu devno = 0; 278986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 279086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ndev->dma = -1; 2791cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin ret = platform_get_irq(pdev, 0); 2792cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin if (ret < 0) { 279386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = -ENODEV; 279486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu goto out_release; 279586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 2796cc3c080d9f4484021e7b14f99de94a8c85a668d5roel kluin ndev->irq = ret; 279786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 279886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu SET_NETDEV_DEV(ndev, &pdev->dev); 279986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 280086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu mdp = netdev_priv(ndev); 2801525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda mdp->num_tx_ring = TX_RING_SIZE; 2802525b8075edda9c2ab4b81e210505bd7487ea6e56Yoshihiro Shimoda mdp->num_rx_ring = RX_RING_SIZE; 2803d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov mdp->addr = devm_ioremap_resource(&pdev->dev, res); 2804d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov if (IS_ERR(mdp->addr)) { 2805d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov ret = PTR_ERR(mdp->addr); 2806ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda goto out_release; 2807ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda } 2808ae70644df780c0e87f1705fda932e7cb1bdb2074Yoshihiro Shimoda 280986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu spin_lock_init(&mdp->lock); 2810bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm mdp->pdev = pdev; 281186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2812b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov if (pdev->dev.of_node) 2813b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov pd = sh_eth_parse_dt(&pdev->dev); 28143b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov if (!pd) { 28153b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov dev_err(&pdev->dev, "no platform data\n"); 28163b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov ret = -EINVAL; 28173b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov goto out_release; 28183b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov } 28193b4c5cbf42bda976ab70354e7786a0808265d9d5Sergei Shtylyov 282086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* get PHY ID */ 282171557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato mdp->phy_id = pd->phy; 2822e47c90523484518aac30498150e427d824ace705Yoshihiro Shimoda mdp->phy_interface = pd->phy_interface; 282371557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato /* EDMAC endian */ 282471557a37adb5df17631c493b3b7d912938c720b2Yoshinori Sato mdp->edmac_endian = pd->edmac_endian; 28254923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda mdp->no_ether_link = pd->no_ether_link; 28264923576b8ac5bfd36ab2beb176aeb747aaab7e41Yoshihiro Shimoda mdp->ether_link_active_low = pd->ether_link_active_low; 282786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2828380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda /* set cpu data */ 2829b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov if (id) { 2830b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov mdp->cd = (struct sh_eth_cpu_data *)id->driver_data; 2831b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov } else { 2832b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov const struct of_device_id *match; 2833b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov 2834b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov match = of_match_device(of_match_ptr(sh_eth_match_table), 2835b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov &pdev->dev); 2836b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov mdp->cd = (struct sh_eth_cpu_data *)match->data; 2837b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov } 2838a3153d8c41132d6fda080a4b3e53b7ee25d3c125Sergei Shtylyov mdp->reg_offset = sh_eth_get_register_offset(mdp->cd->register_type); 2839264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov if (!mdp->reg_offset) { 2840264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov dev_err(&pdev->dev, "Unknown register type (%d)\n", 2841264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov mdp->cd->register_type); 2842264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov ret = -EINVAL; 2843264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov goto out_release; 2844264be2f5a973cc85be3e31d6bf6234b55a256627Sergei Shtylyov } 2845380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda sh_eth_set_default_cpu_data(mdp->cd); 2846380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda 284786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* set function */ 28488f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov if (mdp->cd->tsu) 28498f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov ndev->netdev_ops = &sh_eth_netdev_ops_tsu; 28508f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov else 28518f728d7934c77f63e89abcc96b46a7a98416d5c1Sergei Shtylyov ndev->netdev_ops = &sh_eth_netdev_ops; 28527ad24ea4bf620a32631d7b3069c3e30c078b0c3eWilfried Klaebe ndev->ethtool_ops = &sh_eth_ethtool_ops; 285386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ndev->watchdog_timeo = TX_TIMEOUT; 285486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2855dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu /* debug message level */ 2856dc19e4e5e02fb6b46cccb08b2735e38b997a6ddfNobuhiro Iwamatsu mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE; 285786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 285886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* read and set MAC address */ 2859748031f9fd2c06b28817d80761a5de97190cfd03Magnus Damm read_mac_address(ndev, pd->mac_addr); 2860ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov if (!is_valid_ether_addr(ndev->dev_addr)) { 2861ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov dev_warn(&pdev->dev, 2862ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov "no valid MAC address supplied, using a random one.\n"); 2863ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov eth_hw_addr_random(ndev); 2864ff6e722870ddca2808b5d46159e58904f8ededf1Sergei Shtylyov } 286586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 28666ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda /* ioremap the TSU registers */ 28676ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda if (mdp->cd->tsu) { 28686ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda struct resource *rtsu; 28696ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1); 2870d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov mdp->tsu_addr = devm_ioremap_resource(&pdev->dev, rtsu); 2871d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov if (IS_ERR(mdp->tsu_addr)) { 2872d5e07e69218fd9aa21d6c8c5ccc629d92bdb9b0fSergei Shtylyov ret = PTR_ERR(mdp->tsu_addr); 2873fc0c0900408e05758a0df17c1924ca837fafca5eSergei Shtylyov goto out_release; 2874fc0c0900408e05758a0df17c1924ca837fafca5eSergei Shtylyov } 28756743fe6df43b4dc5950f605edfeee086d0a80f06Yoshihiro Shimoda mdp->port = devno % 2; 2876f646968f8f7c624587de729115d802372b9063ddPatrick McHardy ndev->features = NETIF_F_HW_VLAN_CTAG_FILTER; 28776ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda } 28786ba88021c36516c26c11eff8c6d7d9a045faecd3Yoshihiro Shimoda 2879150647fb2c313d7c5184fca3fa0829a4a7d6f7bcYoshihiro Shimoda /* initialize first or needed device */ 2880150647fb2c313d7c5184fca3fa0829a4a7d6f7bcYoshihiro Shimoda if (!devno || pd->needs_init) { 2881380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda if (mdp->cd->chip_reset) 2882380af9e390ec81e74a2fd7fad948a8b12eeec7daYoshihiro Shimoda mdp->cd->chip_reset(ndev); 288386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 28844986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda if (mdp->cd->tsu) { 28854986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda /* TSU init (Init only)*/ 28864986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda sh_eth_tsu_init(mdp); 28874986b996882d82c68ab54b822d7cfdd7dd35f19aYoshihiro Shimoda } 288886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu } 288986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2890daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart /* MDIO bus init */ 2891daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart ret = sh_mdio_init(mdp, pd); 2892daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart if (ret) { 2893daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart dev_err(&ndev->dev, "failed to initialise MDIO\n"); 2894daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart goto out_release; 2895daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart } 2896daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart 28973719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov netif_napi_add(ndev, &mdp->napi, sh_eth_poll, 64); 28983719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 289986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* network device register */ 290086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu ret = register_netdev(ndev); 290186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ret) 29023719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov goto out_napi_del; 290386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 290425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* print device information */ 2905f75f14ec2f7b552dc87b4b57b2a19e487378f774Sergei Shtylyov netdev_info(ndev, "Base address at 0x%x, %pM, IRQ %d.\n", 2906f75f14ec2f7b552dc87b4b57b2a19e487378f774Sergei Shtylyov (u32)ndev->base_addr, ndev->dev_addr, ndev->irq); 290786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2908b5893a08812602de164fa5ac6494f84df8d09a4fBen Dooks pm_runtime_put(&pdev->dev); 290986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu platform_set_drvdata(pdev, ndev); 291086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 291186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 291286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 29133719109d61ca96746c733538ec776d02a6952640Sergei Shtylyovout_napi_del: 29143719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov netif_napi_del(&mdp->napi); 2915daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart sh_mdio_release(mdp); 29163719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov 291786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsuout_release: 291886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu /* net_dev free */ 291986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu if (ndev) 292086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu free_netdev(ndev); 292186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2922b5893a08812602de164fa5ac6494f84df8d09a4fBen Dooks pm_runtime_put(&pdev->dev); 2923b5893a08812602de164fa5ac6494f84df8d09a4fBen Dooks pm_runtime_disable(&pdev->dev); 292486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return ret; 292586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 292686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 292786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic int sh_eth_drv_remove(struct platform_device *pdev) 292886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu{ 292986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu struct net_device *ndev = platform_get_drvdata(pdev); 29303719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov struct sh_eth_private *mdp = netdev_priv(ndev); 293186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 293286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu unregister_netdev(ndev); 29333719109d61ca96746c733538ec776d02a6952640Sergei Shtylyov netif_napi_del(&mdp->napi); 2934daacf03f0bbfefee3df107c3f7659d22e22538a7Laurent Pinchart sh_mdio_release(mdp); 2935bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm pm_runtime_disable(&pdev->dev); 293686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu free_netdev(ndev); 293786a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 293886a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu return 0; 293986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu} 294086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2941540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#ifdef CONFIG_PM 2942bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Dammstatic int sh_eth_runtime_nop(struct device *dev) 2943bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm{ 2944128296fc3fa2f607050cc2c5d6dc90237f3cedb3Sergei Shtylyov /* Runtime PM callback shared between ->runtime_suspend() 2945bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm * and ->runtime_resume(). Simply returns success. 2946bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm * 2947bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm * This driver re-initializes all registers after 2948bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm * pm_runtime_get_sync() anyway so there is no need 2949bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm * to save and restore registers here. 2950bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm */ 2951bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm return 0; 2952bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm} 2953bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm 2954540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsustatic const struct dev_pm_ops sh_eth_dev_pm_ops = { 2955bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm .runtime_suspend = sh_eth_runtime_nop, 2956bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm .runtime_resume = sh_eth_runtime_nop, 2957bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm}; 2958540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#define SH_ETH_PM_OPS (&sh_eth_dev_pm_ops) 2959540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#else 2960540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#define SH_ETH_PM_OPS NULL 2961540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu#endif 2962bcd5149ded6b2edbf3732fa1483600a716b1cba6Magnus Damm 2963afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyovstatic struct platform_device_id sh_eth_id_table[] = { 2964c18a79abe31f555ec3b363b5b8c1d003230053b6Sergei Shtylyov { "sh7619-ether", (kernel_ulong_t)&sh7619_data }, 29657bbe150d8c57c59689c8c50fd7b9915f4a7e10daSergei Shtylyov { "sh771x-ether", (kernel_ulong_t)&sh771x_data }, 29669c3beaabb951d672b1534c7f56f84054b088f879Sergei Shtylyov { "sh7724-ether", (kernel_ulong_t)&sh7724_data }, 2967f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov { "sh7734-gether", (kernel_ulong_t)&sh7734_data }, 296824549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov { "sh7757-ether", (kernel_ulong_t)&sh7757_data }, 296924549e2a0f33628b5160eac16c6aebf1cfaf22f1Sergei Shtylyov { "sh7757-gether", (kernel_ulong_t)&sh7757_data_giga }, 2970f5d12767c8fd77e29d3d6771de59fd9ac3e540bbSergei Shtylyov { "sh7763-gether", (kernel_ulong_t)&sh7763_data }, 2971db893473d313a4ad9455e89d1bd5e136a57f411eSimon Horman { "r7s72100-ether", (kernel_ulong_t)&r7s72100_data }, 2972e5c9b4cd665106d9b5397114ea81a53059410b6aSergei Shtylyov { "r8a7740-gether", (kernel_ulong_t)&r8a7740_data }, 2973589ebdef7e3107401bf96a9c660753d397329ee9Sergei Shtylyov { "r8a777x-ether", (kernel_ulong_t)&r8a777x_data }, 297494a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyov { "r8a7790-ether", (kernel_ulong_t)&r8a779x_data }, 297594a12b15e4c575e0aa0ba5e24a4f213163a823d0Sergei Shtylyov { "r8a7791-ether", (kernel_ulong_t)&r8a779x_data }, 29760f76b9d83b2b010b63a094024b3cfd82e20af28dHisashi Nakamura { "r8a7794-ether", (kernel_ulong_t)&r8a779x_data }, 2977afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov { } 2978afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov}; 2979afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei ShtylyovMODULE_DEVICE_TABLE(platform, sh_eth_id_table); 2980afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov 298186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsustatic struct platform_driver sh_eth_driver = { 298286a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .probe = sh_eth_drv_probe, 298386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .remove = sh_eth_drv_remove, 2984afe391ad4b05f8f00ca955e165f3b37b480506b7Sergei Shtylyov .id_table = sh_eth_id_table, 298586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .driver = { 298686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu .name = CARDNAME, 2987540ad1b888ad9564520c1c8c48ad675f76ffce62Nobuhiro Iwamatsu .pm = SH_ETH_PM_OPS, 2988b356e978e92fccd17a3e4620a4821bdbfb706c1aSergei Shtylyov .of_match_table = of_match_ptr(sh_eth_match_table), 298986a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu }, 299086a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu}; 299186a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 2992db62f684deeb291ab2533b99843d5df9a36b1f19Axel Linmodule_platform_driver(sh_eth_driver); 299386a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro Iwamatsu 299486a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_AUTHOR("Nobuhiro Iwamatsu, Yoshihiro Shimoda"); 299586a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_DESCRIPTION("Renesas SuperH Ethernet driver"); 299686a74ff21a7ac4bc06b18076ddb0347712b46cfdNobuhiro IwamatsuMODULE_LICENSE("GPL v2"); 2997