/*
* SuperH Ethernet device driver
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/mdio-bitbang.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/cache.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/clk.h>
#include <linux/sh_eth.h>
#include "sh_eth.h"
#define SH_ETH_DEF_MSG_ENABLE \
(NETIF_MSG_LINK | \
NETIF_MSG_TIMER | \
NETIF_MSG_RX_ERR| \
NETIF_MSG_TX_ERR)
static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
[EDSR] = 0x0000,
[EDMR] = 0x0400,
[EDTRR] = 0x0408,
[EDRRR] = 0x0410,
[EESR] = 0x0428,
[EESIPR] = 0x0430,
[TDLAR] = 0x0010,
[TDFAR] = 0x0014,
[TDFXR] = 0x0018,
[TDFFR] = 0x001c,
[RDLAR] = 0x0030,
[RDFAR] = 0x0034,
[RDFXR] = 0x0038,
[RDFFR] = 0x003c,
[TRSCER] = 0x0438,
[RMFCR] = 0x0440,
[TFTR] = 0x0448,
[FDR] = 0x0450,
[RMCR] = 0x0458,
[RPADIR] = 0x0460,
[FCFTR] = 0x0468,
[CSMR] = 0x04E4,
[ECMR] = 0x0500,
[ECSR] = 0x0510,
[ECSIPR] = 0x0518,
[PIR] = 0x0520,
[PSR] = 0x0528,
[PIPR] = 0x052c,
[RFLR] = 0x0508,
[APR] = 0x0554,
[MPR] = 0x0558,
[PFTCR] = 0x055c,
[PFRCR] = 0x0560,
[TPAUSER] = 0x0564,
[GECMR] = 0x05b0,
[BCULR] = 0x05b4,
[MAHR] = 0x05c0,
[MALR] = 0x05c8,
[TROCR] = 0x0700,
[CDCR] = 0x0708,
[LCCR] = 0x0710,
[CEFCR] = 0x0740,
[FRECR] = 0x0748,
[TSFRCR] = 0x0750,
[TLFRCR] = 0x0758,
[RFCR] = 0x0760,
[CERCR] = 0x0768,
[CEECR] = 0x0770,
[MAFCR] = 0x0778,
[RMII_MII] = 0x0790,
[ARSTR] = 0x0000,
[TSU_CTRST] = 0x0004,
[TSU_FWEN0] = 0x0010,
[TSU_FWEN1] = 0x0014,
[TSU_FCM] = 0x0018,
[TSU_BSYSL0] = 0x0020,
[TSU_BSYSL1] = 0x0024,
[TSU_PRISL0] = 0x0028,
[TSU_PRISL1] = 0x002c,
[TSU_FWSL0] = 0x0030,
[TSU_FWSL1] = 0x0034,
[TSU_FWSLC] = 0x0038,
[TSU_QTAG0] = 0x0040,
[TSU_QTAG1] = 0x0044,
[TSU_FWSR] = 0x0050,
[TSU_FWINMK] = 0x0054,
[TSU_ADQT0] = 0x0048,
[TSU_ADQT1] = 0x004c,
[TSU_VTAG0] = 0x0058,
[TSU_VTAG1] = 0x005c,
[TSU_ADSBSY] = 0x0060,
[TSU_TEN] = 0x0064,
[TSU_POST1] = 0x0070,
[TSU_POST2] = 0x0074,
[TSU_POST3] = 0x0078,
[TSU_POST4] = 0x007c,
[TSU_ADRH0] = 0x0100,
[TSU_ADRL0] = 0x0104,
[TSU_ADRH31] = 0x01f8,
[TSU_ADRL31] = 0x01fc,
[TXNLCR0] = 0x0080,
[TXALCR0] = 0x0084,
[RXNLCR0] = 0x0088,
[RXALCR0] = 0x008c,
[FWNLCR0] = 0x0090,
[FWALCR0] = 0x0094,
[TXNLCR1] = 0x00a0,
[TXALCR1] = 0x00a0,
[RXNLCR1] = 0x00a8,
[RXALCR1] = 0x00ac,
[FWNLCR1] = 0x00b0,
[FWALCR1] = 0x00b4,
};
static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
[ECMR] = 0x0300,
[RFLR] = 0x0308,
[ECSR] = 0x0310,
[ECSIPR] = 0x0318,
[PIR] = 0x0320,
[PSR] = 0x0328,
[RDMLR] = 0x0340,
[IPGR] = 0x0350,
[APR] = 0x0354,
[MPR] = 0x0358,
[RFCF] = 0x0360,
[TPAUSER] = 0x0364,
[TPAUSECR] = 0x0368,
[MAHR] = 0x03c0,
[MALR] = 0x03c8,
[TROCR] = 0x03d0,
[CDCR] = 0x03d4,
[LCCR] = 0x03d8,
[CNDCR] = 0x03dc,
[CEFCR] = 0x03e4,
[FRECR] = 0x03e8,
[TSFRCR] = 0x03ec,
[TLFRCR] = 0x03f0,
[RFCR] = 0x03f4,
[MAFCR] = 0x03f8,
[EDMR] = 0x0200,
[EDTRR] = 0x0208,
[EDRRR] = 0x0210,
[TDLAR] = 0x0218,
[RDLAR] = 0x0220,
[EESR] = 0x0228,
[EESIPR] = 0x0230,
[TRSCER] = 0x0238,
[RMFCR] = 0x0240,
[TFTR] = 0x0248,
[FDR] = 0x0250,
[RMCR] = 0x0258,
[TFUCR] = 0x0264,
[RFOCR] = 0x0268,
[RMIIMODE] = 0x026c,
[FCFTR] = 0x0270,
[TRIMD] = 0x027c,
};
static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
[ECMR] = 0x0100,
[RFLR] = 0x0108,
[ECSR] = 0x0110,
[ECSIPR] = 0x0118,
[PIR] = 0x0120,
[PSR] = 0x0128,
[RDMLR] = 0x0140,
[IPGR] = 0x0150,
[APR] = 0x0154,
[MPR] = 0x0158,
[TPAUSER] = 0x0164,
[RFCF] = 0x0160,
[TPAUSECR] = 0x0168,
[BCFRR] = 0x016c,
[MAHR] = 0x01c0,
[MALR] = 0x01c8,
[TROCR] = 0x01d0,
[CDCR] = 0x01d4,
[LCCR] = 0x01d8,
[CNDCR] = 0x01dc,
[CEFCR] = 0x01e4,
[FRECR] = 0x01e8,
[TSFRCR] = 0x01ec,
[TLFRCR] = 0x01f0,
[RFCR] = 0x01f4,
[MAFCR] = 0x01f8,
[RTRATE] = 0x01fc,
[EDMR] = 0x0000,
[EDTRR] = 0x0008,
[EDRRR] = 0x0010,
[TDLAR] = 0x0018,
[RDLAR] = 0x0020,
[EESR] = 0x0028,
[EESIPR] = 0x0030,
[TRSCER] = 0x0038,
[RMFCR] = 0x0040,
[TFTR] = 0x0048,
[FDR] = 0x0050,
[RMCR] = 0x0058,
[TFUCR] = 0x0064,
[RFOCR] = 0x0068,
[FCFTR] = 0x0070,
[RPADIR] = 0x0078,
[TRIMD] = 0x007c,
[RBWAR] = 0x00c8,
[RDFAR] = 0x00cc,
[TBRAR] = 0x00d4,
[TDFAR] = 0x00d8,
};
static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
[ECMR] = 0x0160,
[ECSR] = 0x0164,
[ECSIPR] = 0x0168,
[PIR] = 0x016c,
[MAHR] = 0x0170,
[MALR] = 0x0174,
[RFLR] = 0x0178,
[PSR] = 0x017c,
[TROCR] = 0x0180,
[CDCR] = 0x0184,
[LCCR] = 0x0188,
[CNDCR] = 0x018c,
[CEFCR] = 0x0194,
[FRECR] = 0x0198,
[TSFRCR] = 0x019c,
[TLFRCR] = 0x01a0,
[RFCR] = 0x01a4,
[MAFCR] = 0x01a8,
[IPGR] = 0x01b4,
[APR] = 0x01b8,
[MPR] = 0x01bc,
[TPAUSER] = 0x01c4,
[BCFR] = 0x01cc,
[ARSTR] = 0x0000,
[TSU_CTRST] = 0x0004,
[TSU_FWEN0] = 0x0010,
[TSU_FWEN1] = 0x0014,
[TSU_FCM] = 0x0018,
[TSU_BSYSL0] = 0x0020,
[TSU_BSYSL1] = 0x0024,
[TSU_PRISL0] = 0x0028,
[TSU_PRISL1] = 0x002c,
[TSU_FWSL0] = 0x0030,
[TSU_FWSL1] = 0x0034,
[TSU_FWSLC] = 0x0038,
[TSU_QTAGM0] = 0x0040,
[TSU_QTAGM1] = 0x0044,
[TSU_ADQT0] = 0x0048,
[TSU_ADQT1] = 0x004c,
[TSU_FWSR] = 0x0050,
[TSU_FWINMK] = 0x0054,
[TSU_ADSBSY] = 0x0060,
[TSU_TEN] = 0x0064,
[TSU_POST1] = 0x0070,
[TSU_POST2] = 0x0074,
[TSU_POST3] = 0x0078,
[TSU_POST4] = 0x007c,
[TXNLCR0] = 0x0080,
[TXALCR0] = 0x0084,
[RXNLCR0] = 0x0088,
[RXALCR0] = 0x008c,
[FWNLCR0] = 0x0090,
[FWALCR0] = 0x0094,
[TXNLCR1] = 0x00a0,
[TXALCR1] = 0x00a0,
[RXNLCR1] = 0x00a8,
[RXALCR1] = 0x00ac,
[FWNLCR1] = 0x00b0,
[FWALCR1] = 0x00b4,
[TSU_ADRH0] = 0x0100,
[TSU_ADRL0] = 0x0104,
[TSU_ADRL31] = 0x01fc,
};
static int sh_eth_is_gether(struct sh_eth_private *mdp)
{
if (mdp->reg_offset == sh_eth_offset_gigabit)
return 1;
else
return 0;
}
static void sh_eth_select_mii(struct net_device *ndev)
{
u32 value = 0x0;
struct sh_eth_private *mdp = netdev_priv(ndev);
switch (mdp->phy_interface) {
case PHY_INTERFACE_MODE_GMII:
value = 0x2;
break;
case PHY_INTERFACE_MODE_MII:
value = 0x1;
break;
case PHY_INTERFACE_MODE_RMII:
value = 0x0;
break;
default:
pr_warn("PHY interface mode was not setup. Set to MII.\n");
value = 0x1;
break;
}
sh_eth_write(ndev, value, RMII_MII);
}
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
if (mdp->duplex) /* Full */
sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
else /* Half */
sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
}
/* There is CPU dependent code */
static void sh_eth_set_rate_r8a777x(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
switch (mdp->speed) {
case 10: /* 10BASE */
sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_ELB, ECMR);
break;
case 100:/* 100BASE */
sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_ELB, ECMR);
break;
default:
break;
}
}
/* R8A7778/9 */
static struct sh_eth_cpu_data r8a777x_data = {
.set_duplex = sh_eth_set_duplex,
.set_rate = sh_eth_set_rate_r8a777x,
.register_type = SH_ETH_REG_FAST_RCAR,
.ecsr_value = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
.ecsipr_value = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
.eesipr_value = 0x01ff009f,
.tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
.eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE |
EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE |
EESR_ECI,
.apr = 1,
.mpr = 1,
.tpauser = 1,
.hw_swap = 1,
};
/* R8A7790 */
static struct sh_eth_cpu_data r8a7790_data = {
.set_duplex = sh_eth_set_duplex,
.set_ra
sh_eth.rar_V2
版权申诉
168 浏览量
2022-09-21
19:07:26
上传
评论
收藏 18KB RAR 举报
我虽横行却不霸道
- 粉丝: 75
- 资源: 1万+
最新资源
- MATLAB大数据仿真案例-蚁群算法(ACO)用于求解旅行商(TSP)问题.rar
- MySQL基础知识-个人笔记.rar
- Project8.ipynb
- Python实现BWO-LSTM白鲸算法优化长短期记忆神经网络时间序列预测(完整源码和数据)
- C语言实现文件读写操作的几种常用方法-C 语言.rar
- RK 3568 Android11 版本的梯形校正补丁
- 基于pyqt yolov5 dlib的驾驶员行为监控系统源码+模型.zip
- python代码案例详解-旅行商问题的多种求解算法.rar
- 单相电力电子负载仿真,PWM整流+单相并网逆变
- C语言功能模块(配置文件读取 、debug日志记录等).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈