提交 88314868 编写于 作者: B bigmagic

add ls2k gmac driver

上级 1556ba8e
......@@ -6,7 +6,7 @@
#
# RT-Thread Kernel
#
CONFIG_RT_NAME_MAX=8
CONFIG_RT_NAME_MAX=30
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=8
......@@ -14,12 +14,12 @@ CONFIG_RT_ALIGN_SIZE=8
CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=100
CONFIG_RT_TICK_PER_SECOND=1000
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=2048
CONFIG_IDLE_THREAD_STACK_SIZE=16384
# CONFIG_RT_USING_TIMER_SOFT is not set
CONFIG_RT_DEBUG=y
# CONFIG_RT_DEBUG_COLOR is not set
......@@ -65,6 +65,7 @@ CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=256
CONFIG_RT_CONSOLE_DEVICE_NAME="uart"
CONFIG_RT_VER_NUM=0x40003
CONFIG_ARCH_CPU_64BIT=y
# CONFIG_RT_USING_CPU_FFS is not set
CONFIG_ARCH_MIPS64=y
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
......@@ -74,7 +75,7 @@ CONFIG_ARCH_MIPS64=y
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
CONFIG_RT_MAIN_THREAD_STACK_SIZE=16384
CONFIG_RT_MAIN_THREAD_PRIORITY=10
#
......@@ -93,7 +94,7 @@ CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_USING_DESCRIPTION=y
# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=4096
CONFIG_FINSH_THREAD_STACK_SIZE=16384
CONFIG_FINSH_CMD_SIZE=80
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_USING_MSH=y
......@@ -106,23 +107,42 @@ CONFIG_FINSH_ARG_MAX=10
#
CONFIG_RT_USING_DFS=y
CONFIG_DFS_USING_WORKDIR=y
CONFIG_DFS_FILESYSTEMS_MAX=2
CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
CONFIG_DFS_FILESYSTEMS_MAX=10
CONFIG_DFS_FILESYSTEM_TYPES_MAX=10
CONFIG_DFS_FD_MAX=16
# CONFIG_RT_USING_DFS_MNTTABLE is not set
# CONFIG_RT_USING_DFS_ELMFAT is not set
CONFIG_RT_USING_DFS_ELMFAT=y
#
# elm-chan's FatFs, Generic FAT Filesystem Module
#
CONFIG_RT_DFS_ELM_CODE_PAGE=936
CONFIG_RT_DFS_ELM_WORD_ACCESS=y
# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
CONFIG_RT_DFS_ELM_USE_LFN_3=y
CONFIG_RT_DFS_ELM_USE_LFN=3
CONFIG_RT_DFS_ELM_MAX_LFN=255
CONFIG_RT_DFS_ELM_DRIVES=9
CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
# CONFIG_RT_DFS_ELM_USE_ERASE is not set
CONFIG_RT_DFS_ELM_REENTRANT=y
CONFIG_RT_USING_DFS_DEVFS=y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_UFFS is not set
# CONFIG_RT_USING_DFS_JFFS2 is not set
# CONFIG_RT_USING_DFS_NFS is not set
#
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ=512
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=16384
CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=5
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_SERIAL_USING_DMA=y
CONFIG_RT_SERIAL_RB_BUFSZ=64
......@@ -132,6 +152,7 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_I2C is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC is not set
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
......@@ -172,22 +193,91 @@ CONFIG_RT_USING_POSIX=y
#
# Socket abstraction layer
#
# CONFIG_RT_USING_SAL is not set
CONFIG_RT_USING_SAL=y
#
# protocol stack implement
#
CONFIG_SAL_USING_LWIP=y
# CONFIG_SAL_USING_POSIX is not set
CONFIG_SAL_SOCKETS_NUM=16
#
# Network interface device
#
# CONFIG_RT_USING_NETDEV is not set
CONFIG_RT_USING_NETDEV=y
CONFIG_NETDEV_USING_IFCONFIG=y
CONFIG_NETDEV_USING_PING=y
CONFIG_NETDEV_USING_NETSTAT=y
CONFIG_NETDEV_USING_AUTO_DEFAULT=y
# CONFIG_NETDEV_USING_IPV6 is not set
CONFIG_NETDEV_IPV4=1
CONFIG_NETDEV_IPV6=0
# CONFIG_NETDEV_IPV6_SCOPES is not set
#
# light weight TCP/IP stack
#
# CONFIG_RT_USING_LWIP is not set
CONFIG_RT_USING_LWIP=y
# CONFIG_RT_USING_LWIP141 is not set
CONFIG_RT_USING_LWIP202=y
# CONFIG_RT_USING_LWIP212 is not set
# CONFIG_RT_USING_LWIP_IPV6 is not set
CONFIG_RT_LWIP_MEM_ALIGNMENT=8
CONFIG_RT_LWIP_IGMP=y
CONFIG_RT_LWIP_ICMP=y
CONFIG_RT_LWIP_SNMP=y
CONFIG_RT_LWIP_DNS=y
CONFIG_RT_LWIP_DHCP=y
CONFIG_IP_SOF_BROADCAST=1
CONFIG_IP_SOF_BROADCAST_RECV=1
#
# Static IPv4 Address
#
CONFIG_RT_LWIP_IPADDR="192.168.1.30"
CONFIG_RT_LWIP_GWADDR="192.168.1.1"
CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
CONFIG_RT_LWIP_UDP=y
CONFIG_RT_LWIP_TCP=y
CONFIG_RT_LWIP_RAW=y
# CONFIG_RT_LWIP_PPP is not set
CONFIG_RT_MEMP_NUM_NETCONN=8
CONFIG_RT_LWIP_PBUF_NUM=16
CONFIG_RT_LWIP_RAW_PCB_NUM=4
CONFIG_RT_LWIP_UDP_PCB_NUM=4
CONFIG_RT_LWIP_TCP_PCB_NUM=4
CONFIG_RT_LWIP_TCP_SEG_NUM=40
CONFIG_RT_LWIP_TCP_SND_BUF=8196
CONFIG_RT_LWIP_TCP_WND=8196
CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=5
CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=32
CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=16384
# CONFIG_LWIP_NO_RX_THREAD is not set
# CONFIG_LWIP_NO_TX_THREAD is not set
CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=5
CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=16384
CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=32
CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
CONFIG_LWIP_NETIF_LINK_CALLBACK=1
CONFIG_SO_REUSE=1
CONFIG_LWIP_SO_RCVTIMEO=1
CONFIG_LWIP_SO_SNDTIMEO=1
CONFIG_LWIP_SO_RCVBUF=1
CONFIG_LWIP_SO_LINGER=0
# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
CONFIG_LWIP_NETIF_LOOPBACK=0
CONFIG_RT_LWIP_STATS=y
# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
CONFIG_RT_LWIP_USING_PING=y
# CONFIG_RT_LWIP_DEBUG is not set
#
# AT commands
#
# CONFIG_RT_USING_AT is not set
# CONFIG_LWIP_USING_DHCPD is not set
#
# VBUS(Virtual Software BUS)
......@@ -213,7 +303,9 @@ CONFIG_RT_USING_POSIX=y
#
# IoT - internet of things
#
# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_UMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_WEBNET is not set
# CONFIG_PKG_USING_MONGOOSE is not set
......@@ -259,7 +351,7 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
# CONFIG_PKG_USING_JIOT-C-SDK is not set
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
......@@ -281,6 +373,8 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_CAPNP is not set
# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
# CONFIG_PKG_USING_AGILE_TELNET is not set
# CONFIG_PKG_USING_NMEALIB is not set
# CONFIG_PKG_USING_AGILE_JSMN is not set
#
# security packages
......@@ -289,6 +383,7 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_libsodium is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
# CONFIG_PKG_USING_YD_CRYPTO is not set
#
# language packages
......@@ -323,7 +418,9 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
# CONFIG_PKG_USING_BS8116A is not set
# CONFIG_PKG_USING_GPS_RMC is not set
# CONFIG_PKG_USING_URLENCODE is not set
# CONFIG_PKG_USING_UMCN is not set
#
# system packages
......@@ -331,9 +428,15 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_GUIENGINE is not set
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_LWEXT4 is not set
CONFIG_PKG_USING_LWEXT4=y
CONFIG_PKG_LWEXT4_PATH="/packages/system/lwext4"
CONFIG_RT_USING_DFS_LWEXT4=y
CONFIG_PKG_USING_LWEXT4_LATEST_VERSION=y
# CONFIG_PKG_USING_LWEXT4_V100 is not set
CONFIG_PKG_LWEXT4_VER="latest"
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_FAL is not set
# CONFIG_PKG_USING_FLASHDB is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
......@@ -346,6 +449,10 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_SYSWATCH is not set
# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
# CONFIG_PKG_USING_PLCCORE is not set
# CONFIG_PKG_USING_RAMDISK is not set
# CONFIG_PKG_USING_MININI is not set
# CONFIG_PKG_USING_QBOOT is not set
# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
#
# peripheral libraries and drivers
......@@ -383,6 +490,7 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
# CONFIG_PKG_USING_WS2812B is not set
# CONFIG_PKG_USING_EMBARC_BSP is not set
# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
# CONFIG_PKG_USING_MULTI_RTIMER is not set
......@@ -390,6 +498,13 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_BEEP is not set
# CONFIG_PKG_USING_EASYBLINK is not set
# CONFIG_PKG_USING_PMS_SERIES is not set
# CONFIG_PKG_USING_CAN_YMODEM is not set
# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
# CONFIG_PKG_USING_QLED is not set
# CONFIG_PKG_USING_PAJ7620 is not set
# CONFIG_PKG_USING_AGILE_CONSOLE is not set
# CONFIG_PKG_USING_LD3320 is not set
# CONFIG_PKG_USING_WK2124 is not set
#
# miscellaneous packages
......@@ -426,36 +541,5 @@ CONFIG_RT_USING_POSIX=y
# CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_UKAL is not set
#
# Privated Packages of RealThread
#
# CONFIG_PKG_USING_CODEC is not set
# CONFIG_PKG_USING_PLAYER is not set
# CONFIG_PKG_USING_MPLAYER is not set
# CONFIG_PKG_USING_PERSIMMON_SRC is not set
# CONFIG_PKG_USING_JS_PERSIMMON is not set
# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
#
# Network Utilities
#
# CONFIG_PKG_USING_WICED is not set
# CONFIG_PKG_USING_CLOUDSDK is not set
# CONFIG_PKG_USING_POWER_MANAGER is not set
# CONFIG_PKG_USING_RT_OTA is not set
# CONFIG_PKG_USING_RDBD_SRC is not set
# CONFIG_PKG_USING_RTINSIGHT is not set
# CONFIG_PKG_USING_SMARTCONFIG is not set
# CONFIG_PKG_USING_RTX is not set
# CONFIG_RT_USING_TESTCASE is not set
# CONFIG_PKG_USING_NGHTTP2 is not set
# CONFIG_PKG_USING_AVS is not set
# CONFIG_PKG_USING_ALI_LINKKIT is not set
# CONFIG_PKG_USING_STS is not set
# CONFIG_PKG_USING_DLMS is not set
# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
# CONFIG_PKG_USING_ZBAR is not set
# CONFIG_PKG_USING_MCF is not set
# CONFIG_PKG_USING_URPC is not set
# CONFIG_PKG_USING_CRCLIB is not set
CONFIG_SOC_LS2K1000=y
import os
import sys
import rtconfig
import pdb
from rtconfig import RTT_ROOT
......@@ -9,7 +10,8 @@ from building import *
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
rtconfig.AFLAGS += ' -I' + str(Dir('#')) + ' -I ' + RTT_ROOT + '/libcpu/mips/common/'
#rtconfig.AFLAGS += ' -I' + str(Dir('#')) + ' -I ' + RTT_ROOT + '/libcpu/mips/common/'
rtconfig.AFLAGS += ' -I' + str('.') + ' -I ' + RTT_ROOT + '/libcpu/mips/common/'
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
......
......@@ -7,4 +7,14 @@ CPPPATH = [cwd]
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
group = group + objs
Return('group')
......@@ -16,7 +16,7 @@
extern unsigned char __bss_end;
#define CPU_HZ (1000 * 1000 * 1000) //QEMU 200*1000*1000
#define RT_HW_HEAP_BEGIN KSEG1BASE//(void*)&__bss_end
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024)
void rt_hw_board_init(void);
......
from building import *
cwd = GetCurrentDir()
src = Glob('*.c')
CPPPATH = [cwd]
if GetDepend('RT_USING_LWIP') == False:
SrcRemove(src, 'mii.c')
SrcRemove(src, 'synopGMAC.c')
SrcRemove(src, 'synopGMAC_Dev.c')
SrcRemove(src, 'synopGMAC_plat.c')
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
*/
#include "mii.h"
static inline unsigned int mii_nway_result (unsigned int negotiated)
{
unsigned int ret;
if (negotiated & LPA_100FULL)
ret = LPA_100FULL;
else if (negotiated & LPA_100BASE4)
ret = LPA_100BASE4;
else if (negotiated & LPA_100HALF)
ret = LPA_100HALF;
else if (negotiated & LPA_10FULL)
ret = LPA_10FULL;
else
ret = LPA_10HALF;
return ret;
}
static int mii_check_gmii_support(struct mii_if_info *mii)
{
int reg;
reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
if (reg & BMSR_ESTATEN) {
reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
return 1;
}
return 0;
}
static int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
{
struct synopGMACNetworkAdapter * dev = mii->dev;
u32 advert, bmcr, lpa, nego;
u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
ecmd->supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
if (mii->supports_gmii)
ecmd->supported |= SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full;
/* only supports twisted-pair */
ecmd->port = PORT_MII;
/* only supports internal transceiver */
ecmd->transceiver = XCVR_INTERNAL;
/* this isn't fully supported at higher layers */
ecmd->phy_address = mii->phy_id;
ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
if (mii->supports_gmii)
advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
if (advert & ADVERTISE_10HALF)
ecmd->advertising |= ADVERTISED_10baseT_Half;
if (advert & ADVERTISE_10FULL)
ecmd->advertising |= ADVERTISED_10baseT_Full;
if (advert & ADVERTISE_100HALF)
ecmd->advertising |= ADVERTISED_100baseT_Half;
if (advert & ADVERTISE_100FULL)
ecmd->advertising |= ADVERTISED_100baseT_Full;
if (advert2 & ADVERTISE_1000HALF)
ecmd->advertising |= ADVERTISED_1000baseT_Half;
if (advert2 & ADVERTISE_1000FULL)
ecmd->advertising |= ADVERTISED_1000baseT_Full;
bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
if (mii->supports_gmii) {
bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
}
if (bmcr & BMCR_ANENABLE) {
ecmd->advertising |= ADVERTISED_Autoneg;
ecmd->autoneg = AUTONEG_ENABLE;
nego = mii_nway_result(advert & lpa);
if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) &
(lpa2 >> 2))
ecmd->speed = SPEED_1000;
else if (nego == LPA_100FULL || nego == LPA_100HALF)
ecmd->speed = SPEED_100;
else
ecmd->speed = SPEED_10;
if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL ||
nego == LPA_10FULL) {
ecmd->duplex = DUPLEX_FULL;
mii->full_duplex = 1;
} else {
ecmd->duplex = DUPLEX_HALF;
mii->full_duplex = 0;
}
} else {
ecmd->autoneg = AUTONEG_DISABLE;
ecmd->speed = ((bmcr & BMCR_SPEED1000 &&
(bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 :
(bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10);
ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
}
/* ignore maxtxpkt, maxrxpkt for now */
return 0;
}
static int mii_link_ok (struct mii_if_info *mii)
{
/* first, a dummy read, needed to latch some MII phys */
mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS)
return 1;
return 0;
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
*/
#ifndef __MII_H__
#define __MII_H__
/* Generic MII registers. */
#include "synopGMAC_types.h"
#define MII_BMCR 0x00 /* Basic mode control register */
#define MII_BMSR 0x01 /* Basic mode status register */
#define MII_PHYSID1 0x02 /* PHYS ID 1 */
#define MII_PHYSID2 0x03 /* PHYS ID 2 */
#define MII_ADVERTISE 0x04 /* Advertisement control reg */
#define MII_LPA 0x05 /* Link partner ability reg */
#define MII_EXPANSION 0x06 /* Expansion register */
#define MII_CTRL1000 0x09 /* 1000BASE-T control */
#define MII_STAT1000 0x0a /* 1000BASE-T status */
#define MII_ESTATUS 0x0f /* Extended Status */
#define MII_DCOUNTER 0x12 /* Disconnect counter */
#define MII_FCSCOUNTER 0x13 /* False carrier counter */
#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
#define MII_RERRCOUNTER 0x15 /* Receive error counter */
#define MII_SREVISION 0x16 /* Silicon revision */
#define MII_RESV1 0x17 /* Reserved... */
#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
#define MII_PHYADDR 0x19 /* PHY address */
#define MII_RESV2 0x1a /* Reserved... */
#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
#define MII_NCONFIG 0x1c /* Network interface config */
/* Basic mode control register. */
#define BMCR_RESV 0x003f /* Unused... */
#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */
#define BMCR_CTST 0x0080 /* Collision test */
#define BMCR_FULLDPLX 0x0100 /* Full duplex */
#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
#define BMCR_RESET 0x8000 /* Reset the DP83840 */
/* Basic mode status register. */
#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
#define BMSR_JCD 0x0002 /* Jabber detected */
#define BMSR_LSTATUS 0x0004 /* Link status */
#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
#define BMSR_RFAULT 0x0010 /* Remote fault detected */
#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
#define BMSR_RESV 0x00c0 /* Unused... */
#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */
#define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */
#define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */
#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
/* Advertisement control register. */
#define ADVERTISE_SLCT 0x001f /* Selector bits */
#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
#define ADVERTISE_1000XFULL 0x0020 /* Try for 1000BASE-X full-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
#define ADVERTISE_1000XHALF 0x0040 /* Try for 1000BASE-X half-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
#define ADVERTISE_1000XPAUSE 0x0080 /* Try for 1000BASE-X pause */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
#define ADVERTISE_1000XPSE_ASYM 0x0100 /* Try for 1000BASE-X asym pause */
#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */
#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymetric pause */
#define ADVERTISE_RESV 0x1000 /* Unused... */
#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
ADVERTISE_CSMA)
#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
ADVERTISE_100HALF | ADVERTISE_100FULL)
/* Indicates what features are advertised by the interface. */
#define ADVERTISED_10baseT_Half (1 << 0)
#define ADVERTISED_10baseT_Full (1 << 1)
#define ADVERTISED_100baseT_Half (1 << 2)
#define ADVERTISED_100baseT_Full (1 << 3)
#define ADVERTISED_1000baseT_Half (1 << 4)
#define ADVERTISED_1000baseT_Full (1 << 5)
#define ADVERTISED_Autoneg (1 << 6)
#define ADVERTISED_TP (1 << 7)
#define ADVERTISED_AUI (1 << 8)
#define ADVERTISED_MII (1 << 9)
#define ADVERTISED_FIBRE (1 << 10)
#define ADVERTISED_BNC (1 << 11)
#define ADVERTISED_10000baseT_Full (1 << 12)
#define ADVERTISED_Pause (1 << 13)
#define ADVERTISED_Asym_Pause (1 << 14)
/* Link partner ability register. */
#define LPA_SLCT 0x001f /* Same as advertise selector */
#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
#define LPA_1000XFULL 0x0020 /* Can do 1000BASE-X full-duplex */
#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
#define LPA_1000XHALF 0x0040 /* Can do 1000BASE-X half-duplex */
#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
#define LPA_1000XPAUSE 0x0080 /* Can do 1000BASE-X pause */
#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
#define LPA_1000XPAUSE_ASYM 0x0100 /* Can do 1000BASE-X pause asym*/
#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
#define LPA_PAUSE_CAP 0x0400 /* Can pause */
#define LPA_PAUSE_ASYM 0x0800 /* Can pause asymetrically */
#define LPA_RESV 0x1000 /* Unused... */
#define LPA_RFAULT 0x2000 /* Link partner faulted */
#define LPA_LPACK 0x4000 /* Link partner acked us */
#define LPA_NPAGE 0x8000 /* Next page bit */
#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
/* Expansion register for auto-negotiation. */
#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
#define EXPANSION_RESV 0xffe0 /* Unused... */
#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */
#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */
/* N-way test register. */
#define NWAYTEST_RESV1 0x00ff /* Unused... */
#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
#define NWAYTEST_RESV2 0xfe00 /* Unused... */
/* 1000BASE-T Control register */
#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
/* 1000BASE-T Status register */
#define LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
#define LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
#define LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
#define SUPPORTED_10baseT_Half (1 << 0)
#define SUPPORTED_10baseT_Full (1 << 1)
#define SUPPORTED_100baseT_Half (1 << 2)
#define SUPPORTED_100baseT_Full (1 << 3)
#define SUPPORTED_1000baseT_Half (1 << 4)
#define SUPPORTED_1000baseT_Full (1 << 5)
#define SUPPORTED_Autoneg (1 << 6)
#define SUPPORTED_TP (1 << 7)
#define SUPPORTED_AUI (1 << 8)
#define SUPPORTED_MII (1 << 9)
#define SUPPORTED_FIBRE (1 << 10)
#define SUPPORTED_BNC (1 << 11)
#define SUPPORTED_10000baseT_Full (1 << 12)
#define SUPPORTED_Pause (1 << 13)
#define SUPPORTED_Asym_Pause (1 << 14)
/* Which connector port. */
#define PORT_TP 0x00
#define PORT_AUI 0x01
#define PORT_MII 0x02
#define PORT_FIBRE 0x03
#define PORT_BNC 0x04
/* Which transceiver to use. */
#define XCVR_INTERNAL 0x00
#define XCVR_EXTERNAL 0x01
#define XCVR_DUMMY1 0x02
#define XCVR_DUMMY2 0x03
#define XCVR_DUMMY3 0x04
#define AUTONEG_DISABLE 0x00
#define AUTONEG_ENABLE 0x01
#define SPEED_10 10
#define SPEED_100 100
#define SPEED_1000 1000
#define SPEED_2500 2500
#define SPEED_10000 10000
#define DUPLEX_HALF 0x00
#define DUPLEX_FULL 0x01
struct ethtool_cmd {
u32 cmd;
u32 supported; /* Features this interface supports */
u32 advertising; /* Features this interface advertises */
u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */
u8 duplex; /* Duplex, half or full */
u8 port; /* Which connector port */
u8 phy_address;
u8 transceiver; /* Which transceiver to use */
u8 autoneg; /* Enable or disable autonegotiation */
u32 maxtxpkt; /* Tx pkts before generating tx int */
u32 maxrxpkt; /* Rx pkts before generating rx int */
u32 reserved[4];
};
struct mii_if_info {
int phy_id;
int advertising;
int phy_id_mask;
int reg_num_mask;
unsigned int full_duplex : 1; /* is full duplex? */
unsigned int force_media : 1; /* is autoneg. disabled? */
unsigned int supports_gmii : 1; /* are GMII registers supported? */
struct synopGMACNetworkAdapter *dev;
int (*mdio_read) (struct synopGMACNetworkAdapter *dev, int phy_id, int location);
void (*mdio_write) (struct synopGMACNetworkAdapter *dev, int phy_id, int location, int val);
};
#endif
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
* 2020-08-10 lizhirui porting to ls2k
*/
#include <rtthread.h>
#include <rtdef.h>
//#include <lwip/pbuf.h>
#include "synopGMAC.h"
#include "mii.c"
#include "synopGMAC_debug.h"
#define RMII
#define Gmac_base (0x9000000000000000 | 0x40040000)
#define Buffer_Size 2048
#define MAX_ADDR_LEN 6
#define NAMESIZE 16
#define LS1B_GMAC0_IRQ 34
#define BUS_SIZE_ALIGN(x) ((x+15)&~15)
#define DEFAULT_MAC_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7}
u64 regbase = 0x9000000000000000 | 0x40040000;
static u32 GMAC_Power_down;
extern void *plat_alloc_consistent_dmaable_memory(synopGMACdevice *pcidev, u32 size, u32 *addr) ;
extern s32 synopGMAC_check_phy_init(synopGMACPciNetworkAdapter *adapter) ;
extern int init_phy(synopGMACdevice *gmacdev);
dma_addr_t plat_dma_map_single(void *hwdev, void *ptr, u32 size);
void eth_rx_irq(int irqno, void *param);
static char Rx_Buffer[Buffer_Size];
static char Tx_Buffer[Buffer_Size];
struct rt_eth_dev
{
struct eth_device parent;
rt_uint8_t dev_addr[MAX_ADDR_LEN];
char *name;
int iobase;
int state;
int index;
struct rt_timer link_timer;
struct rt_timer rx_poll_timer;
void *priv;
};
static struct rt_eth_dev eth_dev;
static struct rt_semaphore sem_ack, sem_lock;
/**
* This sets up the transmit Descriptor queue in ring or chain mode.
* This function is tightly coupled to the platform and operating system
* Device is interested only after the descriptors are setup. Therefore this function
* is not included in the device driver API. This function should be treated as an
* example code to design the descriptor structures for ring mode or chain mode.
* This function depends on the pcidev structure for allocation consistent dma-able memory in case
* of linux.
* This limitation is due to the fact that linux uses pci structure to allocate a dmable memory
* - Allocates the memory for the descriptors.
* - Initialize the Busy and Next descriptors indices to 0(Indicating first descriptor).
* - Initialize the Busy and Next descriptors to first descriptor address.
* - Initialize the last descriptor with the endof ring in case of ring mode.
* - Initialize the descriptors in chain mode.
* @param[in] pointer to synopGMACdevice.
* @param[in] pointer to pci_device structure.
* @param[in] number of descriptor expected in tx descriptor queue.
* @param[in] whether descriptors to be created in RING mode or CHAIN mode.
* \return 0 upon success. Error code upon failure.
* \note This function fails if allocation fails for required number of descriptors in Ring mode,
* but in chain mode
* function returns -ESYNOPGMACNOMEM in the process of descriptor chain creation. once returned from
* this function
* user should for gmacdev->TxDescCount to see how many descriptors are there in the chain. Should
* continue further
* only if the number of descriptors in the chain meets the requirements
*/
s32 synopGMAC_setup_tx_desc_queue(synopGMACdevice *gmacdev, u32 no_of_desc, u32 desc_mode)
{
s32 i;
DmaDesc *bf1;
DmaDesc *first_desc = NULL;
dma_addr_t dma_addr;
gmacdev->TxDescCount = 0;
first_desc = (DmaDesc *)plat_alloc_consistent_dmaable_memory(gmacdev, sizeof(DmaDesc) * (no_of_desc), &dma_addr);
if (first_desc == NULL)
{
rt_kprintf("Error in Tx Descriptors memory allocation\n");
return -ESYNOPGMACNOMEM;
}
DEBUG_MES("tx_first_desc_addr = %p\n", first_desc);
DEBUG_MES("dmaadr = %p\n", dma_addr);
gmacdev->TxDescCount = no_of_desc;
gmacdev->TxDesc = first_desc;
gmacdev->TxDescDma = dma_addr;
for (i = 0; i < gmacdev->TxDescCount; i++)
{
synopGMAC_tx_desc_init_ring(gmacdev->TxDesc + i, i == gmacdev->TxDescCount - 1);
#if SYNOP_TOP_DEBUG
rt_kprintf("\n%02d %08x \n", i, (unsigned int)(gmacdev->TxDesc + i));
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i))->status);
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i)->length));
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i)->buffer1));
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i)->buffer2));
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i)->data1));
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i)->data2));
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i)->dummy1));
rt_kprintf("%08x ", (unsigned int)((gmacdev->TxDesc + i)->dummy2));
#endif
}
gmacdev->TxNext = 0;
gmacdev->TxBusy = 0;
gmacdev->TxNextDesc = gmacdev->TxDesc;
gmacdev->TxBusyDesc = gmacdev->TxDesc;
gmacdev->BusyTxDesc = 0;
return -ESYNOPGMACNOERR;
}
/**
* This sets up the receive Descriptor queue in ring or chain mode.
* This function is tightly coupled to the platform and operating system
* Device is interested only after the descriptors are setup. Therefore this function
* is not included in the device driver API. This function should be treated as an
* example code to design the descriptor structures in ring mode or chain mode.
* This function depends on the pcidev structure for allocation of consistent dma-able memory in
* case of linux.
* This limitation is due to the fact that linux uses pci structure to allocate a dmable memory
* - Allocates the memory for the descriptors.
* - Initialize the Busy and Next descriptors indices to 0(Indicating first descriptor).
* - Initialize the Busy and Next descriptors to first descriptor address.
* - Initialize the last descriptor with the endof ring in case of ring mode.
* - Initialize the descriptors in chain mode.
* @param[in] pointer to synopGMACdevice.
* @param[in] pointer to pci_device structure.
* @param[in] number of descriptor expected in rx descriptor queue.
* @param[in] whether descriptors to be created in RING mode or CHAIN mode.
* \return 0 upon success. Error code upon failure.
* \note This function fails if allocation fails for required number of descriptors in Ring mode,
* but in chain mode
* function returns -ESYNOPGMACNOMEM in the process of descriptor chain creation. once returned from
* this function
* user should for gmacdev->RxDescCount to see how many descriptors are there in the chain. Should
* continue further
* only if the number of descriptors in the chain meets the requirements
*/
s32 synopGMAC_setup_rx_desc_queue(synopGMACdevice *gmacdev, u32 no_of_desc, u32 desc_mode)
{
s32 i;
DmaDesc *bf1;
DmaDesc *first_desc = NULL;
dma_addr_t dma_addr;
gmacdev->RxDescCount = 0;
first_desc = (DmaDesc *)plat_alloc_consistent_dmaable_memory(gmacdev, sizeof(DmaDesc) * no_of_desc, &dma_addr);
if (first_desc == NULL)
{
rt_kprintf("Error in Rx Descriptor Memory allocation in Ring mode\n");
return -ESYNOPGMACNOMEM;
}
DEBUG_MES("rx_first_desc_addr = %p\n", first_desc);
DEBUG_MES("dmaadr = %p\n", dma_addr);
gmacdev->RxDescCount = no_of_desc;
gmacdev->RxDesc = (DmaDesc *)first_desc;
gmacdev->RxDescDma = dma_addr;
for (i = 0; i < gmacdev->RxDescCount; i++)
{
synopGMAC_rx_desc_init_ring(gmacdev->RxDesc + i, i == gmacdev->RxDescCount - 1);
}
gmacdev->RxNext = 0;
gmacdev->RxBusy = 0;
gmacdev->RxNextDesc = gmacdev->RxDesc;
gmacdev->RxBusyDesc = gmacdev->RxDesc;
gmacdev->BusyRxDesc = 0;
return -ESYNOPGMACNOERR;
}
void synopGMAC_linux_cable_unplug_function(void *adaptr)
{
s32 data;
synopGMACPciNetworkAdapter *adapter = (synopGMACPciNetworkAdapter *)adaptr;
synopGMACdevice *gmacdev = adapter->synopGMACdev;
struct ethtool_cmd cmd;
//rt_kprintf("%s\n",__FUNCTION__);
if (!mii_link_ok(&adapter->mii))
{
if (gmacdev->LinkState)
rt_kprintf("\r\nNo Link\r\n");
gmacdev->DuplexMode = 0;
gmacdev->Speed = 0;
gmacdev->LoopBackMode = 0;
gmacdev->LinkState = 0;
}
else
{
data = synopGMAC_check_phy_init(adapter);
if (gmacdev->LinkState != data)
{
gmacdev->LinkState = data;
synopGMAC_mac_init(gmacdev);
rt_kprintf("Link is up in %s mode\n", (gmacdev->DuplexMode == FULLDUPLEX) ? "FULL DUPLEX" : "HALF DUPLEX");
if (gmacdev->Speed == SPEED1000)
rt_kprintf("Link is with 1000M Speed \r\n");
if (gmacdev->Speed == SPEED100)
rt_kprintf("Link is with 100M Speed \n");
if (gmacdev->Speed == SPEED10)
rt_kprintf("Link is with 10M Speed \n");
}
}
}
s32 synopGMAC_check_phy_init(synopGMACPciNetworkAdapter *adapter)
{
struct ethtool_cmd cmd;
synopGMACdevice *gmacdev = adapter->synopGMACdev;
if (!mii_link_ok(&adapter->mii))
{
gmacdev->DuplexMode = FULLDUPLEX;
gmacdev->Speed = SPEED100;
return 0;
}
else
{
mii_ethtool_gset(&adapter->mii, &cmd);
gmacdev->DuplexMode = (cmd.duplex == DUPLEX_FULL) ? FULLDUPLEX : HALFDUPLEX ;
if (cmd.speed == SPEED_1000)
gmacdev->Speed = SPEED1000;
else if (cmd.speed == SPEED_100)
gmacdev->Speed = SPEED100;
else
gmacdev->Speed = SPEED10;
}
return gmacdev->Speed | (gmacdev->DuplexMode << 4);
}
static int Mac_change_check(u8 *macaddr0, u8 *macaddr1)
{
int i;
for (i = 0; i < 6; i++)
{
if (macaddr0[i] != macaddr1[i])
return 1;
}
return 0;
}
static rt_err_t eth_init(rt_device_t device)
{
struct eth_device *eth_device = (struct eth_device *)device;
RT_ASSERT(eth_device != RT_NULL);
s32 ijk;
s32 status = 0;
u64 dma_addr;
u32 Mac_changed = 0;
struct pbuf *pbuf;
u8 macaddr[6] = DEFAULT_MAC_ADDRESS;
struct rt_eth_dev *dev = &eth_dev;
struct synopGMACNetworkAdapter *adapter = dev->priv;
synopGMACdevice *gmacdev = (synopGMACdevice *)adapter->synopGMACdev;
synopGMAC_reset(gmacdev);
synopGMAC_attach(gmacdev, (regbase + MACBASE), (regbase + DMABASE), DEFAULT_PHY_BASE, macaddr);
synopGMAC_read_version(gmacdev);
synopGMAC_set_mdc_clk_div(gmacdev, GmiiCsrClk3);
gmacdev->ClockDivMdc = synopGMAC_get_mdc_clk_div(gmacdev);
init_phy(adapter->synopGMACdev);
DEBUG_MES("tx desc_queue\n");
synopGMAC_setup_tx_desc_queue(gmacdev, TRANSMIT_DESC_SIZE, RINGMODE);
synopGMAC_init_tx_desc_base(gmacdev);
DEBUG_MES("rx desc_queue\n");
synopGMAC_setup_rx_desc_queue(gmacdev, RECEIVE_DESC_SIZE, RINGMODE);
synopGMAC_init_rx_desc_base(gmacdev);
DEBUG_MES("DmaRxBaseAddr = %08x\n", synopGMACReadReg(gmacdev->DmaBase, DmaRxBaseAddr));
// u32 dmaRx_Base_addr = synopGMACReadReg(gmacdev->DmaBase,DmaRxBaseAddr);
// rt_kprintf("first_desc_addr = 0x%x\n", dmaRx_Base_addr);
#ifdef ENH_DESC_8W
synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength32 | DmaDescriptorSkip2 | DmaDescriptor8Words);
#else
synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip1);
//synopGMAC_dma_bus_mode_init(gmacdev, DmaBurstLength4 | DmaDescriptorSkip2);
#endif
synopGMAC_dma_control_init(gmacdev, DmaStoreAndForward | DmaTxSecondFrame | DmaRxThreshCtrl128);
status = synopGMAC_check_phy_init(adapter);
synopGMAC_mac_init(gmacdev);
synopGMAC_pause_control(gmacdev);
#ifdef IPC_OFFLOAD
synopGMAC_enable_rx_chksum_offload(gmacdev);
synopGMAC_rx_tcpip_chksum_drop_enable(gmacdev);
#endif
u64 skb;
do
{
skb = (u64)plat_alloc_memory(RX_BUF_SIZE); //should skb aligned here?
if (skb == RT_NULL)
{
rt_kprintf("ERROR in skb buffer allocation\n");
break;
}
dma_addr = plat_dma_map_single(gmacdev, (void *)skb, RX_BUF_SIZE); //获取 skb 的 dma 地址
status = synopGMAC_set_rx_qptr(gmacdev, dma_addr, RX_BUF_SIZE, (u64)skb, 0, 0, 0);
if (status < 0)
{
rt_kprintf("status < 0!!\n");
plat_free_memory((void *)skb);
}
}
while (status >= 0 && (status < (RECEIVE_DESC_SIZE - 1)));
synopGMAC_clear_interrupt(gmacdev);
synopGMAC_disable_mmc_tx_interrupt(gmacdev, 0xFFFFFFFF);
synopGMAC_disable_mmc_rx_interrupt(gmacdev, 0xFFFFFFFF);
synopGMAC_disable_mmc_ipc_rx_interrupt(gmacdev, 0xFFFFFFFF);
// synopGMAC_disable_interrupt_all(gmacdev);
synopGMAC_enable_interrupt(gmacdev, DmaIntEnable);
synopGMAC_enable_dma_rx(gmacdev);
synopGMAC_enable_dma_tx(gmacdev);
plat_delay(DEFAULT_LOOP_VARIABLE);
synopGMAC_check_phy_init(adapter);
synopGMAC_mac_init(gmacdev);
rt_timer_init(&dev->link_timer, "link_timer",
synopGMAC_linux_cable_unplug_function,
(void *)adapter,
RT_TICK_PER_SECOND,
RT_TIMER_FLAG_PERIODIC);
rt_timer_start(&dev->link_timer);
#ifdef RT_USING_GMAC_INT_MODE
/* installl isr */
DEBUG_MES("%s\n", __FUNCTION__);
rt_hw_interrupt_install(LS1C_MAC_IRQ, eth_rx_irq, RT_NULL, "e0_isr");
rt_hw_interrupt_umask(LS1C_MAC_IRQ);
#else
rt_timer_init(&dev->rx_poll_timer, "rx_poll_timer",
eth_rx_irq,
(void *)adapter,
1,
RT_TIMER_FLAG_PERIODIC);
rt_timer_start(&dev->rx_poll_timer);
#endif /*RT_USING_GMAC_INT_MODE*/
return RT_EOK;
}
static rt_err_t eth_open(rt_device_t dev, rt_uint16_t oflag)
{
rt_kprintf("eth_open!!\n");
return RT_EOK;
}
static rt_err_t eth_close(rt_device_t dev)
{
return RT_EOK;
}
static rt_size_t eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
static rt_size_t eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
static rt_err_t eth_control(rt_device_t dev, int cmd, void *args)
{
switch (cmd)
{
case NIOCTL_GADDR:
if (args) rt_memcpy(args, eth_dev.dev_addr, 6);
else return -RT_ERROR;
break;
default :
break;
}
return RT_EOK;
}
rt_err_t rt_eth_tx(rt_device_t device, struct pbuf *p)
{
/* lock eth device */
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
DEBUG_MES("in %s\n", __FUNCTION__);
s32 status;
u64 pbuf;
u64 dma_addr;
u32 offload_needed = 0;
u32 index;
DmaDesc *dpr;
struct rt_eth_dev *dev = (struct rt_eth_dev *) device;
struct synopGMACNetworkAdapter *adapter;
synopGMACdevice *gmacdev;
adapter = (struct synopGMACNetworkAdapter *) dev->priv;
if (adapter == NULL)
return -1;
gmacdev = (synopGMACdevice *) adapter->synopGMACdev;
if (gmacdev == NULL)
return -1;
if (!synopGMAC_is_desc_owned_by_dma(gmacdev->TxNextDesc))
{
pbuf = (u64)plat_alloc_memory(p->tot_len);
//pbuf = (u32)pbuf_alloc(PBUF_LINK, p->len, PBUF_RAM);
if (pbuf == 0)
{
rt_kprintf("===error in alloc bf1\n");
return -1;
}
DEBUG_MES("p->len = %d\n", p->len);
pbuf_copy_partial(p, (void *)pbuf, p->tot_len, 0);
dma_addr = plat_dma_map_single(gmacdev, (void *)pbuf, p->tot_len);
status = synopGMAC_set_tx_qptr(gmacdev, dma_addr, p->tot_len, pbuf, 0, 0, 0, offload_needed, &index, dpr);
if (status < 0)
{
rt_kprintf("%s No More Free Tx Descriptors\n", __FUNCTION__);
plat_free_memory((void *)pbuf);
return -16;
}
}
synopGMAC_resume_dma_tx(gmacdev);
s32 desc_index;
u64 data1, data2;
u32 dma_addr1, dma_addr2;
u32 length1, length2;
#ifdef ENH_DESC_8W
u32 ext_status;
u16 time_stamp_higher;
u32 time_stamp_high;
u32 time_stamp_low;
#endif
do
{
#ifdef ENH_DESC_8W
desc_index = synopGMAC_get_tx_qptr(gmacdev, &status, &dma_addr1, &length1, &data1, &dma_addr2, &length2, &data2, &ext_status, &time_stamp_high, &time_stamp_low);
synopGMAC_TS_read_timestamp_higher_val(gmacdev, &time_stamp_higher);
#else
desc_index = synopGMAC_get_tx_qptr(gmacdev, &status, &dma_addr1, &length1, &data1, &dma_addr2, &length2, &data2);
#endif
if (desc_index >= 0 && data1 != 0)
{
#ifdef IPC_OFFLOAD
if (synopGMAC_is_tx_ipv4header_checksum_error(gmacdev, status))
{
rt_kprintf("Harware Failed to Insert IPV4 Header Checksum\n");
}
if (synopGMAC_is_tx_payload_checksum_error(gmacdev, status))
{
rt_kprintf("Harware Failed to Insert Payload Checksum\n");
}
#endif
plat_free_memory((void *)(data1)); //sw: data1 = buffer1
if (synopGMAC_is_desc_valid(status))
{
adapter->synopGMACNetStats.tx_bytes += length1;
adapter->synopGMACNetStats.tx_packets++;
}
else
{
adapter->synopGMACNetStats.tx_errors++;
adapter->synopGMACNetStats.tx_aborted_errors += synopGMAC_is_tx_aborted(status);
adapter->synopGMACNetStats.tx_carrier_errors += synopGMAC_is_tx_carrier_error(status);
}
}
adapter->synopGMACNetStats.collisions += synopGMAC_get_tx_collision_count(status);
}
while (desc_index >= 0);
/* unlock eth device */
rt_sem_release(&sem_lock);
// rt_kprintf("output %d bytes\n", p->len);
u32 test_data;
test_data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus);
//rt_kprintf("dma_status = 0x%08x\n",test_data);
return RT_EOK;
}
struct pbuf *rt_eth_rx(rt_device_t device)
{
DEBUG_MES("%s : \n", __FUNCTION__);
struct rt_eth_dev *dev = &eth_dev;
struct synopGMACNetworkAdapter *adapter;
synopGMACdevice *gmacdev;
// struct PmonInet * pinetdev;
s32 desc_index;
int i;
char *ptr;
u32 bf1;
u64 data1;
u64 data2;
u32 len;
u32 status;
u32 dma_addr1;
u32 dma_addr2;
struct pbuf *pbuf = RT_NULL;
rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
adapter = (struct synopGMACNetworkAdapter *) dev->priv;
if (adapter == NULL)
{
rt_kprintf("%S : Unknown Device !!\n", __FUNCTION__);
return NULL;
}
gmacdev = (synopGMACdevice *) adapter->synopGMACdev;
if (gmacdev == NULL)
{
rt_kprintf("%s : GMAC device structure is missing\n", __FUNCTION__);
return NULL;
}
/*Handle the Receive Descriptors*/
desc_index = synopGMAC_get_rx_qptr(gmacdev, &status, &dma_addr1, NULL, &data1, &dma_addr2, NULL, &data2);
if(((u32)desc_index >= RECEIVE_DESC_SIZE) && (desc_index != -1))
{
rt_kprintf("host receive descriptor address pointer = 0x%08x\n",synopGMACReadReg(gmacdev->DmaBase,DmaRxCurrDesc));
rt_kprintf("host receive buffer = 0x%08x\n",synopGMACReadReg(gmacdev->DmaBase,DmaRxCurrAddr));
rt_kprintf("desc_index error!!!!,tick = %d\n",rt_tick_get());
while(1);
}
if (desc_index >= 0 && data1 != 0)
{
DEBUG_MES("Received Data at Rx Descriptor %d for skb 0x%08x whose status is %08x\n", desc_index, dma_addr1, status);
if (synopGMAC_is_rx_desc_valid(status) || SYNOP_PHY_LOOPBACK)
{
dma_addr1 = plat_dma_map_single(gmacdev, (void *)data1, RX_BUF_SIZE);
len = synopGMAC_get_rx_desc_frame_length(status)-4; //Not interested in Ethernet CRC bytes
pbuf = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
if (pbuf == 0) rt_kprintf("===error in pbuf_alloc\n");
rt_memcpy(pbuf->payload, (char *)data1, len);
DEBUG_MES("==get pkg len: %d\n", len);
}
else
{
rt_kprintf("s: %08x\n", status);
adapter->synopGMACNetStats.rx_errors++;
adapter->synopGMACNetStats.collisions += synopGMAC_is_rx_frame_collision(status);
adapter->synopGMACNetStats.rx_crc_errors += synopGMAC_is_rx_crc(status);
adapter->synopGMACNetStats.rx_frame_errors += synopGMAC_is_frame_dribbling_errors(status);
adapter->synopGMACNetStats.rx_length_errors += synopGMAC_is_rx_frame_length_errors(status);
}
desc_index = synopGMAC_set_rx_qptr(gmacdev, dma_addr1, RX_BUF_SIZE, (u64)data1, 0, 0, 0);
if (desc_index < 0)
{
#if SYNOP_RX_DEBUG
rt_kprintf("Cannot set Rx Descriptor for data1 %08x\n", (u32)data1);
#endif
plat_free_memory((void *)data1);
}
}
rt_sem_release(&sem_lock);
DEBUG_MES("%s : before return \n", __FUNCTION__);
return pbuf;
}
static int rtl88e1111_config_init(synopGMACdevice *gmacdev)
{
int retval, err;
u16 data;
DEBUG_MES("in %s\n", __FUNCTION__);
synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x14, &data);
data = data | 0x82;
err = synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x14, data);
synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x00, &data);
data = data | 0x8000;
err = synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x00, data);
#if SYNOP_PHY_LOOPBACK
synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x14, &data);
data = data | 0x70;
data = data & 0xffdf;
err = synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x14, data);
data = 0x8000;
err = synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x00, data);
data = 0x5140;
err = synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x00, data);
#endif
if (err < 0)
return err;
return 0;
}
int init_phy(synopGMACdevice *gmacdev)
{
u16 data;
synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 2, &data);
/*set 88e1111 clock phase delay*/
if (data == 0x141)
rtl88e1111_config_init(gmacdev);
#if defined (RMII)
else if (data == 0x8201)
{
//RTL8201
data = 0x400; // set RMII mode
synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x19, data);
synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x19, &data);
TR("phy reg25 is %0x \n", data);
data = 0x3100; //set 100M speed
synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x0, data);
}
else if (data == 0x0180 || data == 0x0181)
{
//DM9161
synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x10, &data);
data |= (1 << 8); //set RMII mode
synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x10, data); //set RMII mode
synopGMAC_read_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x10, &data);
TR("phy reg16 is 0x%0x \n", data);
// synopGMAC_read_phy_reg(gmacdev->MacBase,gmacdev->PhyBase,0x0,&data);
// data &= ~(1<<10);
data = 0x3100; //set auto-
//data = 0x0100; //set 10M speed
synopGMAC_write_phy_reg(gmacdev->MacBase, gmacdev->PhyBase, 0x0, data);
}
#endif
return 0;
}
u32 synopGMAC_wakeup_filter_config3[] =
{
0x00000000,
0x000000FF,
0x00000000,
0x00000000,
0x00000100,
0x00003200,
0x7eED0000,
0x00000000
};
static void synopGMAC_linux_powerdown_mac(synopGMACdevice *gmacdev)
{
rt_kprintf("Put the GMAC to power down mode..\n");
GMAC_Power_down = 1;
synopGMAC_disable_dma_tx(gmacdev);
plat_delay(10000);
synopGMAC_tx_disable(gmacdev);
synopGMAC_rx_disable(gmacdev);
plat_delay(10000);
synopGMAC_disable_dma_rx(gmacdev);
synopGMAC_magic_packet_enable(gmacdev);
synopGMAC_write_wakeup_frame_register(gmacdev, synopGMAC_wakeup_filter_config3);
synopGMAC_wakeup_frame_enable(gmacdev);
synopGMAC_rx_enable(gmacdev);
synopGMAC_pmt_int_enable(gmacdev);
synopGMAC_power_down_enable(gmacdev);
return;
}
static void synopGMAC_linux_powerup_mac(synopGMACdevice *gmacdev)
{
GMAC_Power_down = 0;
if (synopGMAC_is_magic_packet_received(gmacdev))
rt_kprintf("GMAC wokeup due to Magic Pkt Received\n");
if (synopGMAC_is_wakeup_frame_received(gmacdev))
rt_kprintf("GMAC wokeup due to Wakeup Frame Received\n");
synopGMAC_pmt_int_disable(gmacdev);
synopGMAC_rx_enable(gmacdev);
synopGMAC_enable_dma_rx(gmacdev);
synopGMAC_tx_enable(gmacdev);
synopGMAC_enable_dma_tx(gmacdev);
return;
}
static int mdio_read(synopGMACPciNetworkAdapter *adapter, int addr, int reg)
{
synopGMACdevice *gmacdev;
u16 data;
gmacdev = adapter->synopGMACdev;
synopGMAC_read_phy_reg(gmacdev->MacBase, addr, reg, &data);
return data;
}
static void mdio_write(synopGMACPciNetworkAdapter *adapter, int addr, int reg, int data)
{
synopGMACdevice *gmacdev;
gmacdev = adapter->synopGMACdev;
synopGMAC_write_phy_reg(gmacdev->MacBase, addr, reg, data);
}
void eth_rx_irq(int irqno, void *param)
{
struct rt_eth_dev *dev = &eth_dev;
struct synopGMACNetworkAdapter *adapter = dev->priv;
//DEBUG_MES("in irq!!\n");
#ifdef RT_USING_GMAC_INT_MODE
int i ;
for (i = 0; i < 7200; i++)
;
#endif /*RT_USING_GMAC_INT_MODE*/
synopGMACdevice *gmacdev = (synopGMACdevice *)adapter->synopGMACdev;
u32 interrupt, dma_status_reg;
s32 status;
u32 dma_addr;
//rt_kprintf("irq i = %d\n", i++);
dma_status_reg = synopGMACReadReg(gmacdev->DmaBase, DmaStatus);
if (dma_status_reg == 0)
{
rt_kprintf("dma_status ==0 \n");
return;
}
//rt_kprintf("dma_status_reg is 0x%x\n", dma_status_reg);
u32 gmacstatus;
synopGMAC_disable_interrupt_all(gmacdev);
gmacstatus = synopGMACReadReg(gmacdev->MacBase, GmacStatus);
if (dma_status_reg & GmacPmtIntr)
{
rt_kprintf("%s:: Interrupt due to PMT module\n", __FUNCTION__);
//synopGMAC_linux_powerup_mac(gmacdev);
}
if (dma_status_reg & GmacMmcIntr)
{
rt_kprintf("%s:: Interrupt due to MMC module\n", __FUNCTION__);
DEBUG_MES("%s:: synopGMAC_rx_int_status = %08x\n", __FUNCTION__, synopGMAC_read_mmc_rx_int_status(gmacdev));
DEBUG_MES("%s:: synopGMAC_tx_int_status = %08x\n", __FUNCTION__, synopGMAC_read_mmc_tx_int_status(gmacdev));
}
if (dma_status_reg & GmacLineIntfIntr)
{
rt_kprintf("%s:: Interrupt due to GMAC LINE module\n", __FUNCTION__);
}
interrupt = synopGMAC_get_interrupt_type(gmacdev);
//rt_kprintf("%s:Interrupts to be handled: 0x%08x\n",__FUNCTION__,interrupt);
if (interrupt & synopGMACDmaError)
{
u8 mac_addr0[6];
rt_kprintf("%s::Fatal Bus Error Inetrrupt Seen\n", __FUNCTION__);
memcpy(mac_addr0, dev->dev_addr, 6);
synopGMAC_disable_dma_tx(gmacdev);
synopGMAC_disable_dma_rx(gmacdev);
synopGMAC_take_desc_ownership_tx(gmacdev);
synopGMAC_take_desc_ownership_rx(gmacdev);
synopGMAC_init_tx_rx_desc_queue(gmacdev);
synopGMAC_reset(gmacdev);
synopGMAC_set_mac_addr(gmacdev, GmacAddr0High, GmacAddr0Low, mac_addr0);
synopGMAC_dma_bus_mode_init(gmacdev, DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip1);
synopGMAC_dma_control_init(gmacdev, DmaStoreAndForward);
synopGMAC_init_rx_desc_base(gmacdev);
synopGMAC_init_tx_desc_base(gmacdev);
synopGMAC_mac_init(gmacdev);
synopGMAC_enable_dma_rx(gmacdev);
synopGMAC_enable_dma_tx(gmacdev);
}
if (interrupt & synopGMACDmaRxNormal)
{
//DEBUG_MES("%s:: Rx Normal \n", __FUNCTION__);
//synop_handle_received_data(netdev);
eth_device_ready(&eth_dev.parent);
}
if (interrupt & synopGMACDmaRxAbnormal)
{
//rt_kprintf("%s::Abnormal Rx Interrupt Seen\n",__FUNCTION__);
if (GMAC_Power_down == 0)
{
adapter->synopGMACNetStats.rx_over_errors++;
synopGMACWriteReg(gmacdev->DmaBase, DmaStatus, 0x80);
synopGMAC_resume_dma_rx(gmacdev);
}
}
if (interrupt & synopGMACDmaRxStopped)
{
rt_kprintf("%s::Receiver stopped seeing Rx interrupts\n", __FUNCTION__); //Receiver gone in to stopped state
}
if (interrupt & synopGMACDmaTxNormal)
{
DEBUG_MES("%s::Finished Normal Transmission \n", __FUNCTION__);
// synop_handle_transmit_over(netdev);
}
if (interrupt & synopGMACDmaTxAbnormal)
{
rt_kprintf("%s::Abnormal Tx Interrupt Seen\n", __FUNCTION__);
}
if (interrupt & synopGMACDmaTxStopped)
{
TR("%s::Transmitter stopped sending the packets\n", __FUNCTION__);
if (GMAC_Power_down == 0) // If Mac is not in powerdown
{
synopGMAC_disable_dma_tx(gmacdev);
synopGMAC_take_desc_ownership_tx(gmacdev);
synopGMAC_enable_dma_tx(gmacdev);
// netif_wake_queue(netdev);
TR("%s::Transmission Resumed\n", __FUNCTION__);
}
}
/* Enable the interrrupt before returning from ISR*/
synopGMAC_enable_interrupt(gmacdev, DmaIntEnable);
return;
}
int rt_hw_eth_init(void)
{
u64 base_addr = Gmac_base;
struct synopGMACNetworkAdapter *synopGMACadapter;
static u8 mac_addr0[6] = DEFAULT_MAC_ADDRESS;
int index;
//rt_kprintf("rt_hw_eth_init 1\n");
rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
memset(&eth_dev, 0, sizeof(eth_dev));
synopGMACadapter = (struct synopGMACNetworkAdapter *)plat_alloc_memory(sizeof(struct synopGMACNetworkAdapter));
if (!synopGMACadapter)
{
rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
}
memset((char *)synopGMACadapter, 0, sizeof(struct synopGMACNetworkAdapter));
synopGMACadapter->synopGMACdev = NULL;
synopGMACadapter->synopGMACdev = (synopGMACdevice *) plat_alloc_memory(sizeof(synopGMACdevice));
if (!synopGMACadapter->synopGMACdev)
{
rt_kprintf("Error in Memory Allocataion, Founction : %s \n", __FUNCTION__);
}
memset((char *)synopGMACadapter->synopGMACdev, 0, sizeof(synopGMACdevice));
/*
* Attach the device to MAC struct This will configure all the required base addresses
* such as Mac base, configuration base, phy base address(out of 32 possible phys)
* */
synopGMAC_attach(synopGMACadapter->synopGMACdev, (regbase + MACBASE), regbase + DMABASE, DEFAULT_PHY_BASE, mac_addr0);
init_phy(synopGMACadapter->synopGMACdev);
synopGMAC_reset(synopGMACadapter->synopGMACdev);
/* MII setup */
synopGMACadapter->mii.phy_id_mask = 0x1F;
synopGMACadapter->mii.reg_num_mask = 0x1F;
synopGMACadapter->mii.dev = synopGMACadapter;
synopGMACadapter->mii.mdio_read = mdio_read;
synopGMACadapter->mii.mdio_write = mdio_write;
synopGMACadapter->mii.phy_id = synopGMACadapter->synopGMACdev->PhyBase;
synopGMACadapter->mii.supports_gmii = mii_check_gmii_support(&synopGMACadapter->mii);
eth_dev.iobase = base_addr;
eth_dev.name = "e0";
eth_dev.priv = synopGMACadapter;
eth_dev.dev_addr[0] = mac_addr0[0];
eth_dev.dev_addr[1] = mac_addr0[1];
eth_dev.dev_addr[2] = mac_addr0[2];
eth_dev.dev_addr[3] = mac_addr0[3];
eth_dev.dev_addr[4] = mac_addr0[4];
eth_dev.dev_addr[5] = mac_addr0[5];
eth_dev.parent.parent.type = RT_Device_Class_NetIf;
eth_dev.parent.parent.init = eth_init;
eth_dev.parent.parent.open = eth_open;
eth_dev.parent.parent.close = eth_close;
eth_dev.parent.parent.read = eth_read;
eth_dev.parent.parent.write = eth_write;
eth_dev.parent.parent.control = eth_control;
eth_dev.parent.parent.user_data = RT_NULL;
eth_dev.parent.eth_tx = rt_eth_tx;
eth_dev.parent.eth_rx = rt_eth_rx;
eth_device_init(&(eth_dev.parent), "e0");
eth_device_linkchange(&eth_dev.parent, RT_TRUE); //linkup the e0 for lwip to check
//rt_kprintf("rt_hw_eth_init 2\n");
return 0;
}
INIT_COMPONENT_EXPORT(rt_hw_eth_init);
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
*/
#ifndef __SYNOPGMAC__H
#define __SYNOPGMAC__H
#include "synopGMAC_network_interface.h"
#include "synopGMAC_Host.h"
#include "synopGMAC_Dev.h"
#include "synopGMAC_plat.h"
#include "mii.h"
#include "synopGMAC_types.h"
int rt_hw_eth_init(void);
#endif /*__SYNOPGMAC__H*/
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
* 2020-08-10 lizhirui porting to ls2k
*/
#include "synopGMAC_Dev.h"
#include <rthw.h>
#include <rtthread.h>
#define UNUSED 1
/**
* Function to set the MDC clock for mdio transactiona
*
* @param[in] pointer to device structure.
* @param[in] clk divider value.
* \return Reuturns 0 on success else return the error value.
*/
s32 synopGMAC_set_mdc_clk_div(synopGMACdevice *gmacdev,u32 clk_div_val)
{
u32 orig_data;
orig_data = synopGMACReadReg(gmacdev -> MacBase,GmacGmiiAddr);//set the mdc clock to the user defined value
orig_data &= (~GmiiCsrClkMask);
orig_data |= clk_div_val;
synopGMACWriteReg(gmacdev -> MacBase,GmacGmiiAddr,orig_data);
return 0;
}
/**
* Returns the current MDC divider value programmed in the ip.
*
* @param[in] pointer to device structure.
* @param[in] clk divider value.
* \return Returns the MDC divider value read.
*/
u32 synopGMAC_get_mdc_clk_div(synopGMACdevice *gmacdev)
{
u32 data;
data = synopGMACReadReg(gmacdev->MacBase,GmacGmiiAddr);
data &= GmiiCsrClkMask;
return data;
}
/**
* Function to read the Phy register. The access to phy register
* is a slow process as the data is moved accross MDI/MDO interface
* @param[in] pointer to Register Base (It is the mac base in our case) .
* @param[in] PhyBase register is the index of one of supported 32 PHY devices.
* @param[in] Register offset is the index of one of the 32 phy register.
* @param[out] u16 data read from the respective phy register (only valid iff return value is 0).
* \return Returns 0 on success else return the error status.
*/
s32 synopGMAC_read_phy_reg(u64 RegBase,u32 PhyBase, u32 RegOffset, u16 * data )
{
u64 addr;
u32 loop_variable;
addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask)
| GmiiCsrClk3; //sw: add GmiiCsrClk
addr = addr | GmiiBusy ; //Gmii busy bit
synopGMACWriteReg(RegBase,GmacGmiiAddr,addr);
//write the address from where the data to be read in GmiiGmiiAddr register of synopGMAC ip
for(loop_variable = 0;loop_variable < DEFAULT_LOOP_VARIABLE;loop_variable++)
{
//Wait till the busy bit gets cleared within a certain amount of time
if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy))
{
break;
}
plat_delay(DEFAULT_DELAY_VARIABLE);
}
if(loop_variable < DEFAULT_LOOP_VARIABLE)
{
*data = (u16)(synopGMACReadReg(RegBase,GmacGmiiData) & 0xFFFF);
}
else
{
TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n");
return -ESYNOPGMACPHYERR;
}
//sw
#if SYNOP_REG_DEBUG
printf("read phy reg: offset = 0x%x\tdata = 0x%x\n",RegOffset,*data);
#endif
return -ESYNOPGMACNOERR;
}
/**
* Function to write to the Phy register. The access to phy register
* is a slow process as the data is moved accross MDI/MDO interface
* @param[in] pointer to Register Base (It is the mac base in our case) .
* @param[in] PhyBase register is the index of one of supported 32 PHY devices.
* @param[in] Register offset is the index of one of the 32 phy register.
* @param[in] data to be written to the respective phy register.
* \return Returns 0 on success else return the error status.
*/
s32 synopGMAC_write_phy_reg(u64 RegBase, u32 PhyBase, u32 RegOffset, u16 data)
{
u32 addr;
u32 loop_variable;
synopGMACWriteReg(RegBase,GmacGmiiData,data); // write the data in to GmacGmiiData register of synopGMAC ip
addr = ((PhyBase << GmiiDevShift) & GmiiDevMask) | ((RegOffset << GmiiRegShift) & GmiiRegMask) | GmiiWrite | GmiiCsrClk3; //sw: add GmiiCsrclk
addr = addr | GmiiBusy ; //set Gmii clk to 20-35 Mhz and Gmii busy bit
synopGMACWriteReg(RegBase,GmacGmiiAddr,addr);
for(loop_variable = 0;loop_variable < DEFAULT_LOOP_VARIABLE;loop_variable++)
{
if (!(synopGMACReadReg(RegBase,GmacGmiiAddr) & GmiiBusy))
{
break;
}
plat_delay(DEFAULT_DELAY_VARIABLE);
}
if(loop_variable < DEFAULT_LOOP_VARIABLE)
{
return -ESYNOPGMACNOERR;
}
else
{
TR("Error::: PHY not responding Busy bit didnot get cleared !!!!!!\n");
return -ESYNOPGMACPHYERR;
}
#if SYNOP_REG_DEBUG
printf("write phy reg: offset = 0x%x\tdata = 0x%x",RegOffset,data);
#endif
}
/**
* Function to configure the phy in loopback mode.
*
* @param[in] pointer to synopGMACdevice.
* @param[in] enable or disable the loopback.
* \return 0 on success else return the error status.
* \note Don't get confused with mac loop-back synopGMAC_loopback_on(synopGMACdevice *)
* and synopGMAC_loopback_off(synopGMACdevice *) functions.
*/
#if UNUSED
s32 synopGMAC_phy_loopback(synopGMACdevice *gmacdev,bool loopback)
{
s32 status = -ESYNOPGMACNOERR;
u16 temp;
status = synopGMAC_read_phy_reg(gmacdev -> MacBase, gmacdev -> PhyBase,PHY_CONTROL_REG,&temp);
if(loopback)
{
temp |= 0x4000;
}
else
{
temp = temp;
}
status = synopGMAC_write_phy_reg(gmacdev -> MacBase,gmacdev -> PhyBase,PHY_CONTROL_REG,temp);
return status;
}
#endif
/**
* Function to read the GMAC IP Version and populates the same in device data structure.
* @param[in] pointer to synopGMACdevice.
* \return Always return 0.
*/
s32 synopGMAC_read_version(synopGMACdevice *gmacdev)
{
u32 data = 0;
data = synopGMACReadReg(gmacdev -> MacBase,GmacVersion);
gmacdev -> Version = data;
return 0;
}
/**
* Function to reset the GMAC core.
* This reests the DMA and GMAC core. After reset all the registers holds their respective reset value
* @param[in] pointer to synopGMACdevice.
* \return 0 on success else return the error status.
*/
s32 synopGMAC_reset(synopGMACdevice *gmacdev)
{
u32 data = 0;
synopGMACWriteReg(gmacdev -> DmaBase,DmaBusMode,DmaResetOn);
plat_delay(DEFAULT_LOOP_VARIABLE);
data = synopGMACReadReg(gmacdev -> DmaBase,DmaBusMode);
TR("DATA after Reset = %08x\n",data);
return 0;
}
/**
* Function to program DMA bus mode register.
*
* The Bus Mode register is programmed with the value given. The bits to be set are
* bit wise or'ed and sent as the second argument to this function.
* @param[in] pointer to synopGMACdevice.
* @param[in] the data to be programmed.
* \return 0 on success else return the error status.
*/
s32 synopGMAC_dma_bus_mode_init(synopGMACdevice *gmacdev,u32 init_value)
{
synopGMACWriteReg(gmacdev -> DmaBase,DmaBusMode,init_value);
return 0;
}
/**
* Function to program DMA Control register(Operation Mode Register 0x18).
*
* The Dma Control register is programmed with the value given. The bits to be set are
* bit wise or'ed and sent as the second argument to this function.
* @param[in] pointer to synopGMACdevice.
* @param[in] the data to be programmed.
* \return 0 on success else return the error status.
*/
s32 synopGMAC_dma_control_init(synopGMACdevice *gmacdev,u32 init_value)
{
synopGMACWriteReg(gmacdev -> DmaBase,DmaControl,init_value);
return 0;
}
/*Gmac configuration functions*/
/**
* Enable the watchdog timer on the receiver.
* When enabled, Gmac enables Watchdog timer, and GMAC allows no more than
* 2048 bytes of data (10,240 if Jumbo frame enabled).
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_wd_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacWatchdog);
return;
}
/**
* Disable the watchdog timer on the receiver.
* When disabled, Gmac disabled watchdog timer, and can receive frames up to
* 16,384 bytes.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_wd_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacWatchdog);
return;
}
/**
* Enables the Jabber frame support.
* When enabled, GMAC disabled the jabber timer, and can transfer 16,384 byte frames.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_jab_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacJabber);
return;
}
/**
* Disables the Jabber frame support.
* When disabled, GMAC enables jabber timer. It cuts of transmitter if application
* sends more than 2048 bytes of data (10240 if Jumbo frame enabled).
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_jab_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacJabber);
return;
}
#endif
/**
* Enables Frame bursting (Only in Half Duplex Mode).
* When enabled, GMAC allows frame bursting in GMII Half Duplex mode.
* Reserved in 10/100 and Full-Duplex configurations.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_frame_burst_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacFrameBurst);
return;
}
/**
* Disables Frame bursting.
* When Disabled, frame bursting is not supported.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_frame_burst_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacFrameBurst);
return;
}
#endif
/**
* Enable Jumbo frame support.
* When Enabled GMAC supports jumbo frames of 9018/9022(VLAN tagged).
* Giant frame error is not reported in receive frame status.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_jumbo_frame_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacJumboFrame);
return;
}
#endif
/**
* Disable Jumbo frame support.
* When Disabled GMAC does not supports jumbo frames.
* Giant frame error is reported in receive frame status.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_jumbo_frame_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacJumboFrame);
return;
}
/**
* Disable Carrier sense.
* When Disabled GMAC ignores CRS signal during frame transmission
* in half duplex mode.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_disable_crs(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacDisableCrs);
return;
}
#endif
/**
* Selects the GMII port.
* When called GMII (1000Mbps) port is selected (programmable only in 10/100/1000 Mbps configuration).
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_select_gmii(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacMiiGmii);
return;
}
/**
* Selects the MII port.
* When called MII (10/100Mbps) port is selected (programmable only in 10/100/1000 Mbps configuration).
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_select_mii(synopGMACdevice * gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacMiiGmii);
return;
}
/**
* Enables Receive Own bit (Only in Half Duplex Mode).
* When enaled GMAC receives all the packets given by phy while transmitting.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_rx_own_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacRxOwn);
return;
}
/**
* Disables Receive Own bit (Only in Half Duplex Mode).
* When enaled GMAC disables the reception of frames when gmii_txen_o is asserted.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_rx_own_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacRxOwn);
return;
}
#endif
/**
* Sets the GMAC in loopback mode.
* When on GMAC operates in loop-back mode at GMII/MII.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
* \note (G)MII Receive clock is required for loopback to work properly, as transmit clock is
* not looped back internally.
*/
void synopGMAC_loopback_on(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacLoopback);
return;
}
/**
* Sets the GMAC in Normal mode.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_loopback_off(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacLoopback);
return;
}
/**
* Sets the GMAC core in Full-Duplex mode.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_set_full_duplex(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacDuplex);
return;
}
/**
* Sets the GMAC core in Half-Duplex mode.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_set_half_duplex(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacDuplex);
return;
}
/**
* GMAC tries retransmission (Only in Half Duplex mode).
* If collision occurs on the GMII/MII, GMAC attempt retries based on the
* back off limit configured.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
* \note This function is tightly coupled with synopGMAC_back_off_limit(synopGMACdev *, u32).
*/
void synopGMAC_retry_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacRetry);
return;
}
/**
* GMAC tries only one transmission (Only in Half Duplex mode).
* If collision occurs on the GMII/MII, GMAC will ignore the current frami
* transmission and report a frame abort with excessive collision in tranmit frame status.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_retry_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacRetry);
return;
}
#endif
/**
* GMAC strips the Pad/FCS field of incoming frames.
* This is true only if the length field value is less than or equal to
* 1500 bytes. All received frames with length field greater than or equal to
* 1501 bytes are passed to the application without stripping the Pad/FCS field.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_pad_crc_strip_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacPadCrcStrip);
return;
}
#endif
/**
* GMAC doesnot strips the Pad/FCS field of incoming frames.
* GMAC will pass all the incoming frames to Host unmodified.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_pad_crc_strip_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacPadCrcStrip);
u32 status = synopGMACReadReg(gmacdev -> MacBase,GmacConfig);
DEBUG_MES("strips status : %u\n", status & GmacPadCrcStrip);
return;
}
/**
* GMAC programmed with the back off limit value.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
* \note This function is tightly coupled with synopGMAC_retry_enable(synopGMACdevice * gmacdev)
*/
void synopGMAC_back_off_limit(synopGMACdevice *gmacdev,u32 value)
{
u32 data;
data = synopGMACReadReg(gmacdev -> MacBase,GmacConfig);
data &= (~GmacBackoffLimit);
data |= value;
synopGMACWriteReg(gmacdev -> MacBase,GmacConfig,data);
return;
}
/**
* Enables the Deferral check in GMAC (Only in Half Duplex mode)
* GMAC issues a Frame Abort Status, along with the excessive deferral error bit set in the
* transmit frame status when transmit state machine is deferred for more than
* - 24,288 bit times in 10/100Mbps mode
* - 155,680 bit times in 1000Mbps mode or Jumbo frame mode in 10/100Mbps operation.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
* \note Deferral begins when transmitter is ready to transmit, but is prevented because of
* an active CRS (carrier sense)
*/
#if UNUSED
void synopGMAC_deferral_check_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacDeferralCheck);
return;
}
#endif
/**
* Disables the Deferral check in GMAC (Only in Half Duplex mode).
* GMAC defers until the CRS signal goes inactive.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_deferral_check_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacDeferralCheck);
return;
}
/**
* Enable the reception of frames on GMII/MII.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_rx_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacRx);
return;
}
/**
* Disable the reception of frames on GMII/MII.
* GMAC receive state machine is disabled after completion of reception of current frame.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_rx_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacRx);
return;
}
#endif
/**
* Enable the transmission of frames on GMII/MII.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_tx_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacTx);
return;
}
/**
* Disable the transmission of frames on GMII/MII.
* GMAC transmit state machine is disabled after completion of transmission of current frame.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_tx_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacConfig,GmacTx);
return;
}
#endif
/*Receive frame filter configuration functions*/
/**
* Disables reception of all the frames to application.
* GMAC passes only those received frames to application which
* pass SA/DA address filtering.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_frame_filter_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacFilter);
return;
}
/**
* Enables reception of all the frames to application.
* GMAC passes all the frames received to application irrespective of whether they
* pass SA/DA address filtering or not.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_frame_filter_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacFilter);
return;
}
/**
* Populates the Hash High register with the data supplied.
* This function is called when the Hash filtering is to be enabled.
* @param[in] pointer to synopGMACdevice.
* @param[in] data to be written to hash table high register.
* \return void.
*/
#if UNUSED
void synopGMAC_write_hash_table_high(synopGMACdevice *gmacdev,u32 data)
{
synopGMACWriteReg(gmacdev -> MacBase,GmacHashHigh,data);
return;
}
#endif
/**
* Populates the Hash Low register with the data supplied.
* This function is called when the Hash filtering is to be enabled.
* @param[in] pointer to synopGMACdevice.
* @param[in] data to be written to hash table low register.
* \return void.
*/
#if UNUSED
void synopGMAC_write_hash_table_low(synopGMACdevice *gmacdev,u32 data)
{
synopGMACWriteReg(gmacdev -> MacBase,GmacHashLow,data);
return;
}
#endif
/**
* Enables Hash or Perfect filter (only if Hash filter is enabled in H/W).
* Only frames matching either perfect filtering or Hash Filtering as per HMC and HUC
* configuration are sent to application.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_hash_perfect_filter_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacHashPerfectFilter);
return;
}
#endif
/**
* Enables only Hash(only if Hash filter is enabled in H/W).
* Only frames matching Hash Filtering as per HMC and HUC
* configuration are sent to application.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_Hash_filter_only_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacHashPerfectFilter);
return;
}
#endif
/**
* Enables Source address filtering.
* When enabled source address filtering is performed. Only frames matching SA filtering are passed to application with
* SAMatch bit of RxStatus is set. GMAC drops failed frames.
* @param[in] pointer to synopGMACdevice.
* \return void.
* \note This function is overriden by synopGMAC_frame_filter_disable(synopGMACdevice *)
*/
#if UNUSED
void synopGMAC_src_addr_filter_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacSrcAddrFilter);
return;
}
#endif
/**
* Disables Source address filtering.
* When disabled GMAC forwards the received frames with updated SAMatch bit in RxStatus.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_src_addr_filter_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacSrcAddrFilter);
return;
}
/**
* Enables Inverse Destination address filtering.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_dst_addr_filter_inverse(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacDestAddrFilterInv);
return;
}
#endif
/**
* Enables the normal Destination address filtering.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_dst_addr_filter_normal(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacDestAddrFilterInv);
return;
}
/**
* Enables forwarding of control frames.
* When set forwards all the control frames (incl. unicast and multicast PAUSE frames).
* @param[in] pointer to synopGMACdevice.
* \return void.
* \note Depends on RFE of FlowControlRegister[2]
*/
void synopGMAC_set_pass_control(synopGMACdevice *gmacdev,u32 passcontrol)
{
u32 data;
data = synopGMACReadReg(gmacdev -> MacBase,GmacFrameFilter);
data &= (~GmacPassControl);
data |= passcontrol;
synopGMACWriteReg(gmacdev -> MacBase,GmacFrameFilter,data);
return;
}
/**
* Enables Broadcast frames.
* When enabled Address filtering module passes all incoming broadcast frames.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_broadcast_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacBroadcast);
return;
}
/**
* Disable Broadcast frames.
* When disabled Address filtering module filters all incoming broadcast frames.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_broadcast_disable(synopGMACdevice * gmacdev)
{
synopGMACSetBits(gmacdev->MacBase, GmacFrameFilter, GmacBroadcast);
return;
}
#endif
/**
* Enables Multicast frames.
* When enabled all multicast frames are passed.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_multicast_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacMulticastFilter);
return;
}
#endif
/**
* Disable Multicast frames.
* When disabled multicast frame filtering depends on HMC bit.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_multicast_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacMulticastFilter);
return;
}
/**
* Enables multicast hash filtering.
* When enabled GMAC performs teh destination address filtering according to the hash table.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_multicast_hash_filter_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacMcastHashFilter);
return;
}
#endif
/**
* Disables multicast hash filtering.
* When disabled GMAC performs perfect destination address filtering for multicast frames, it compares
* DA field with the value programmed in DA register.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_multicast_hash_filter_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacMcastHashFilter);
return;
}
/**
* Enables promiscous mode.
* When enabled Address filter modules pass all incoming frames regardless of their Destination
* and source addresses.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_promisc_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacPromiscuousMode);
return;
}
#endif
/**
* Clears promiscous mode.
* When called the GMAC falls back to normal operation from promiscous mode.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_promisc_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacPromiscuousMode);
return;
}
/**
* Enables unicast hash filtering.
* When enabled GMAC performs the destination address filtering of unicast frames according to the hash table.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_unicast_hash_filter_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFrameFilter,GmacUcastHashFilter);
return;
}
#endif
/**
* Disables multicast hash filtering.
* When disabled GMAC performs perfect destination address filtering for unicast frames, it compares
* DA field with the value programmed in DA register.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_unicast_hash_filter_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFrameFilter,GmacUcastHashFilter);
return;
}
/*Flow control configuration functions*/
/**
* Enables detection of pause frames with stations unicast address.
* When enabled GMAC detects the pause frames with stations unicast address in addition to the
* detection of pause frames with unique multicast address.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_unicast_pause_frame_detect_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFlowControl,GmacUnicastPauseFrame);
return;
}
#endif
/**
* Disables detection of pause frames with stations unicast address.
* When disabled GMAC only detects with the unique multicast address (802.3x).
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_unicast_pause_frame_detect_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFlowControl,GmacUnicastPauseFrame);
return;
}
/**
* Rx flow control enable.
* When Enabled GMAC will decode the rx pause frame and disable the tx for a specified time.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_rx_flow_control_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFlowControl,GmacRxFlowControl);
return;
}
/**
* Rx flow control disable.
* When disabled GMAC will not decode pause frame.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_rx_flow_control_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFlowControl,GmacRxFlowControl);
return;
}
/**
* Tx flow control enable.
* When Enabled
* - In full duplex GMAC enables flow control operation to transmit pause frames.
* - In Half duplex GMAC enables the back pressure operation
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_tx_flow_control_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFlowControl,GmacTxFlowControl);
return;
}
/**
* Tx flow control disable.
* When Disabled
* - In full duplex GMAC will not transmit any pause frames.
* - In Half duplex GMAC disables the back pressure feature.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_tx_flow_control_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev -> MacBase,GmacFlowControl,GmacTxFlowControl);
return;
}
/**
* Initiate Flowcontrol operation.
* When Set
* - In full duplex GMAC initiates pause control frame.
* - In Half duplex GMAC initiates back pressure function.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_tx_activate_flow_control(synopGMACdevice *gmacdev)
{
//In case of full duplex check for this bit to b'0. if it is read as b'1 indicates that
//control frame transmission is in progress.
if(gmacdev -> Speed == FULLDUPLEX)
{
if(!synopGMACCheckBits(gmacdev -> MacBase,GmacFlowControl,GmacFlowControlBackPressure))
{
synopGMACSetBits(gmacdev -> MacBase,GmacFlowControl,GmacFlowControlBackPressure);
}
}
else//if half duplex mode
{
synopGMACSetBits(gmacdev -> MacBase,GmacFlowControl,GmacFlowControlBackPressure);
}
return;
}
#endif
/**
* stops Flowcontrol operation.
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
#if UNUSED
void synopGMAC_tx_deactivate_flow_control(synopGMACdevice *gmacdev)
{
//In full duplex this bit is automatically cleared after transmitting a pause control frame.
if(gmacdev->Speed == HALFDUPLEX)
{
synopGMACSetBits(gmacdev -> MacBase,GmacFlowControl,GmacFlowControlBackPressure);
}
return;
}
#endif
/**
* This enables the pause frame generation after programming the appropriate registers.
* presently activation is set at 3k and deactivation set at 4k. These may have to tweaked
* if found any issues
* @param[in] pointer to synopGMACdevice.
* \return void.
*/
void synopGMAC_pause_control(synopGMACdevice *gmacdev)
{
u32 omr_reg;
u32 mac_flow_control_reg;
omr_reg = synopGMACReadReg(gmacdev -> DmaBase,DmaControl);
omr_reg |= DmaRxFlowCtrlAct4K | DmaRxFlowCtrlDeact5K | DmaEnHwFlowCtrl;
synopGMACWriteReg(gmacdev -> DmaBase,DmaControl,omr_reg);
mac_flow_control_reg = synopGMACReadReg(gmacdev -> MacBase,GmacFlowControl);
mac_flow_control_reg |= GmacRxFlowControl | GmacTxFlowControl | 0xFFFF0000;
synopGMACWriteReg(gmacdev -> MacBase,GmacFlowControl,mac_flow_control_reg);
return;
}
/**
* Example mac initialization sequence.
* This function calls the initialization routines to initialize the GMAC register.
* One can change the functions invoked here to have different configuration as per the requirement
* @param[in] pointer to synopGMACdevice.
* \return Returns 0 on success.
*/
s32 synopGMAC_mac_init(synopGMACdevice *gmacdev)
{
u32 PHYreg;
if(gmacdev->DuplexMode == FULLDUPLEX)
{
TR("\n===phy FULLDUPLEX MODE\n"); //sw: debug
synopGMAC_wd_enable(gmacdev);
synopGMAC_jab_enable(gmacdev);
synopGMAC_frame_burst_enable(gmacdev);
synopGMAC_jumbo_frame_disable(gmacdev);
synopGMAC_rx_own_enable(gmacdev);
#if SYNOP_LOOPBACK_MODE
synopGMAC_loopback_on(gmacdev);
#else
synopGMAC_loopback_off(gmacdev);
#endif
synopGMAC_set_full_duplex(gmacdev); //1
synopGMAC_retry_enable(gmacdev);
synopGMAC_pad_crc_strip_disable(gmacdev);
synopGMAC_back_off_limit(gmacdev,GmacBackoffLimit0);
synopGMAC_deferral_check_disable(gmacdev);
synopGMAC_tx_enable(gmacdev); //according to Tang Dan's commitment
synopGMAC_rx_enable(gmacdev);
synopGMACSetBits(gmacdev -> DmaBase,DmaControl,DmaStoreAndForward);//3
synopGMACSetBits(gmacdev -> DmaBase,DmaControl,DmaFwdErrorFrames);
if(gmacdev -> Speed == SPEED1000)
{
synopGMAC_select_gmii(gmacdev);
}
else
{
synopGMAC_select_mii(gmacdev);
if(gmacdev -> Speed == SPEED100)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacFESpeed100);
}
else
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacFESpeed10);
}
}
/*Frame Filter Configuration*/
//synopGMAC_frame_filter_enable(gmacdev); //2
synopGMAC_frame_filter_disable(gmacdev); //2
synopGMAC_set_pass_control(gmacdev,GmacPassControl0);
synopGMAC_broadcast_enable(gmacdev);
synopGMAC_src_addr_filter_disable(gmacdev);
synopGMAC_multicast_disable(gmacdev);
synopGMAC_dst_addr_filter_normal(gmacdev); //scl
//synopGMAC_dst_addr_filter_inverse(gmacdev);
synopGMAC_multicast_hash_filter_disable(gmacdev);
synopGMAC_promisc_disable(gmacdev);
synopGMAC_unicast_hash_filter_disable(gmacdev);
/*Flow Control Configuration*/
synopGMAC_unicast_pause_frame_detect_disable(gmacdev);
synopGMAC_rx_flow_control_enable(gmacdev);
synopGMAC_tx_flow_control_enable(gmacdev);
}
else//for Half Duplex configuration
{
TR("\n===phy HALFDUPLEX MODE\n"); //sw: debug
synopGMAC_wd_enable(gmacdev );
synopGMAC_jab_enable(gmacdev);
synopGMAC_frame_burst_enable(gmacdev);
synopGMAC_jumbo_frame_disable(gmacdev);
synopGMAC_rx_own_enable(gmacdev);
#if SYNOP_LOOPBACK_MODE
synopGMAC_loopback_on(gmacdev);
#else
synopGMAC_loopback_off(gmacdev);
#endif
synopGMAC_set_half_duplex(gmacdev);
synopGMAC_retry_enable(gmacdev);
synopGMAC_pad_crc_strip_disable(gmacdev);
synopGMAC_back_off_limit(gmacdev,GmacBackoffLimit0);
synopGMAC_deferral_check_disable(gmacdev);
//sw: set efe & tsf
synopGMACSetBits(gmacdev -> DmaBase,DmaControl,DmaStoreAndForward);
synopGMACSetBits(gmacdev -> DmaBase,DmaControl,DmaFwdErrorFrames);
//sw: put it in the end
synopGMAC_tx_enable(gmacdev);
synopGMAC_rx_enable(gmacdev);
if(gmacdev -> Speed == SPEED1000)
synopGMAC_select_gmii(gmacdev);
else{
synopGMAC_select_mii(gmacdev);
if(gmacdev -> Speed == SPEED100)
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacFESpeed100);
}
else
{
synopGMACSetBits(gmacdev -> MacBase,GmacConfig,GmacFESpeed10);
}
}
// synopGMACSetBits(gmacdev->MacBase, GmacConfig, GmacDisableCrs);
// synopGMAC_select_gmii(gmacdev);
/*Frame Filter Configuration*/
synopGMAC_frame_filter_enable(gmacdev);
// synopGMAC_frame_filter_disable(gmacdev);
synopGMAC_set_pass_control(gmacdev,GmacPassControl0);
synopGMAC_broadcast_enable(gmacdev);
synopGMAC_src_addr_filter_disable(gmacdev);
synopGMAC_multicast_disable(gmacdev);
synopGMAC_dst_addr_filter_normal(gmacdev);
synopGMAC_multicast_hash_filter_disable(gmacdev);
synopGMAC_promisc_disable(gmacdev);
// synopGMAC_promisc_enable(gmacdev);
synopGMAC_unicast_hash_filter_disable(gmacdev);
//sw: loopback mode
// synopGMAC_loopback_on(gmacdev);
/*Flow Control Configuration*/
synopGMAC_unicast_pause_frame_detect_disable(gmacdev);
synopGMAC_rx_flow_control_disable(gmacdev);
synopGMAC_tx_flow_control_disable(gmacdev);
/*To set PHY register to enable CRS on Transmit*/
}
return 0;
}
/**
* Sets the Mac address in to GMAC register.
* This function sets the MAC address to the MAC register in question.
* @param[in] pointer to synopGMACdevice to populate mac dma and phy addresses.
* @param[in] Register offset for Mac address high
* @param[in] Register offset for Mac address low
* @param[in] buffer containing mac address to be programmed.
* \return 0 upon success. Error code upon failure.
*/
s32 synopGMAC_set_mac_addr(synopGMACdevice *gmacdev,u32 MacHigh,u32 MacLow,u8 *MacAddr)
{
u32 data;
data = (MacAddr[5] << 8) | MacAddr[4];
synopGMACWriteReg(gmacdev -> MacBase,MacHigh,data);
data = (MacAddr[3] << 24) | (MacAddr[2] << 16) | (MacAddr[1] << 8) | MacAddr[0];
synopGMACWriteReg(gmacdev -> MacBase,MacLow,data);
return 0;
}
/**
* Get the Mac address in to the address specified.
* The mac register contents are read and written to buffer passed.
* @param[in] pointer to synopGMACdevice to populate mac dma and phy addresses.
* @param[in] Register offset for Mac address high
* @param[in] Register offset for Mac address low
* @param[out] buffer containing the device mac address.
* \return 0 upon success. Error code upon failure.
*/
s32 synopGMAC_get_mac_addr(synopGMACdevice *gmacdev,u32 MacHigh,u32 MacLow,u8 *MacAddr)
{
u32 data;
data = synopGMACReadReg(gmacdev -> MacBase,MacHigh);
MacAddr[5] = (data >> 8) & 0xff;
MacAddr[4] = (data) & 0xff;
data = synopGMACReadReg(gmacdev -> MacBase,MacLow);
MacAddr[3] = (data >> 24) & 0xff;
MacAddr[2] = (data >> 16) & 0xff;
MacAddr[1] = (data >> 8 ) & 0xff;
MacAddr[0] = (data ) & 0xff;
// rt_kprintf("MacAddr = 0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t0x%x\n",MacAddr[0],MacAddr[1],MacAddr[2],MacAddr[3],MacAddr[4],MacAddr[5]);
return 0;
}
/**
* Attaches the synopGMAC device structure to the hardware.
* Device structure is populated with MAC/DMA and PHY base addresses.
* @param[in] pointer to synopGMACdevice to populate mac dma and phy addresses.
* @param[in] GMAC IP mac base address.
* @param[in] GMAC IP dma base address.
* @param[in] GMAC IP phy base address.
* \return 0 upon success. Error code upon failure.
* \note This is important function. No kernel api provided by Synopsys
*/
s32 synopGMAC_attach(synopGMACdevice *gmacdev,u64 macBase,u64 dmaBase,u64 phyBase,u8 *mac_addr)
{
/*Make sure the Device data strucure is cleared before we proceed further*/
rt_memset((void *)gmacdev,0,sizeof(synopGMACdevice));
/*Populate the mac and dma base addresses*/
gmacdev -> MacBase = macBase;
gmacdev -> DmaBase = dmaBase;
gmacdev -> PhyBase = phyBase;
// rt_kprintf("gmacdev->DmaBase = 0x%x\n", gmacdev->DmaBase);
// rt_kprintf("dmaBase = 0x%x\n", dmaBase);
{
int i,j;
u16 data;
for (i = phyBase,j = 0;j < 32;i = (i + 1) & 0x1f,j++)
{
synopGMAC_read_phy_reg(gmacdev -> MacBase,i,2,&data);
if(data != 0 && data != 0xffff)
{
break;
}
synopGMAC_read_phy_reg(gmacdev -> MacBase,i,3,&data);
if(data != 0 && data != 0xffff)
{
break;
}
}
if(j == 32)
{
rt_kprintf("phy_detect: can't find PHY!\n");
}
gmacdev -> PhyBase = i;
}
// synopGMAC_get_mac_addr(gmacdev, GmacAddr0High, GmacAddr0Low, mac_addr);
/* Program/flash in the station/IP's Mac address */
synopGMAC_set_mac_addr(gmacdev,GmacAddr0High,GmacAddr0Low,mac_addr);
return 0;
}
/**
* Initialize the rx descriptors for ring or chain mode operation.
* - Status field is initialized to 0.
* - EndOfRing set for the last descriptor.
* - buffer1 and buffer2 set to 0 for ring mode of operation. (note)
* - data1 and data2 set to 0. (note)
* @param[in] pointer to DmaDesc structure.
* @param[in] whether end of ring
* \return void.
* \note Initialization of the buffer1, buffer2, data1,data2 and status are not done here. This only initializes whether one wants to use this descriptor
* in chain mode or ring mode. For chain mode of operation the buffer2 and data2 are programmed before calling this function.
*/
void synopGMAC_rx_desc_init_ring(DmaDesc *desc,bool last_ring_desc)
{
desc -> length = last_ring_desc ? RxDescEndOfRing : 0;
desc -> status = 0;
desc -> buffer1 = 0;
desc -> buffer2 = 0;
desc -> data1 = 0;
desc -> data2 = 0;
//desc -> dummy1 = 0;
//desc -> dummy2 = 0;
return;
}
void synopGMAC_rx_desc_recycle(DmaDesc *desc,bool last_ring_desc)
{
desc -> status = DescOwnByDma;
desc -> length = last_ring_desc ? RxDescEndOfRing : 0;
//desc->buffer1 = 0;
//desc->buffer2 = 0;
//desc->data1 = 0;
//desc->data2 = 0;
//desc -> dummy1 = 0;
//desc -> dummy2 = 0;
return;
}
/**
* Initialize the tx descriptors for ring or chain mode operation.
* - Status field is initialized to 0.
* - EndOfRing set for the last descriptor.
* - buffer1 and buffer2 set to 0 for ring mode of operation. (note)
* - data1 and data2 set to 0. (note)
* @param[in] pointer to DmaDesc structure.
* @param[in] whether end of ring
* \return void.
* \note Initialization of the buffer1, buffer2, data1,data2 and status are not done here. This only initializes whether one wants to use this descriptor
* in chain mode or ring mode. For chain mode of operation the buffer2 and data2 are programmed before calling this function.
*/
void synopGMAC_tx_desc_init_ring(DmaDesc *desc, bool last_ring_desc)
{
#ifdef ENH_DESC
desc -> status = last_ring_desc ? TxDescEndOfRing : 0;
desc -> length = 0;
#else
desc -> length = last_ring_desc ? TxDescEndOfRing : 0;
desc -> status = 0;
#endif
//sw
desc -> buffer1 = 0;
desc -> buffer2 = 0;
desc -> data1 = 0;
desc -> data2 = 0;
//desc -> dummy1 = 0;
//desc -> dummy2 = 0;
return;
}
/**
* Initialize the rx descriptors for chain mode of operation.
* - Status field is initialized to 0.
* - EndOfRing set for the last descriptor.
* - buffer1 and buffer2 set to 0.
* - data1 and data2 set to 0.
* @param[in] pointer to DmaDesc structure.
* @param[in] whether end of ring
* \return void.
*/
void synopGMAC_rx_desc_init_chain(DmaDesc * desc)
{
desc -> status = 0;
desc -> length = RxDescChain;
desc -> buffer1 = 0;
desc -> data1 = 0;
return;
}
/**
* Initialize the rx descriptors for chain mode of operation.
* - Status field is initialized to 0.
* - EndOfRing set for the last descriptor.
* - buffer1 and buffer2 set to 0.
* - data1 and data2 set to 0.
* @param[in] pointer to DmaDesc structure.
* @param[in] whether end of ring
* \return void.
*/
void synopGMAC_tx_desc_init_chain(DmaDesc * desc)
{
#ifdef ENH_DESC
desc -> status = TxDescChain;
desc -> length = 0;
#else
desc -> length = TxDescChain;
#endif
desc -> buffer1 = 0;
desc -> data1 = 0;
return;
}
s32 synopGMAC_init_tx_rx_desc_queue(synopGMACdevice *gmacdev)
{
s32 i;
for(i = 0;i < gmacdev -> TxDescCount;i++)
{
synopGMAC_tx_desc_init_ring(gmacdev -> TxDesc + i, i == gmacdev -> TxDescCount - 1);
}
TR("At line %d\n",__LINE__);
for(i = 0; i < gmacdev -> RxDescCount; i++)
{
synopGMAC_rx_desc_init_ring(gmacdev -> RxDesc + i, i == gmacdev -> RxDescCount - 1);
}
gmacdev -> TxNext = 0;
gmacdev -> TxBusy = 0;
gmacdev -> RxNext = 0;
gmacdev -> RxBusy = 0;
return -ESYNOPGMACNOERR;
}
/**
* Programs the DmaRxBaseAddress with the Rx descriptor base address.
* Rx Descriptor's base address is available in the gmacdev structure. This function progrms the
* Dma Rx Base address with the starting address of the descriptor ring or chain.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_init_rx_desc_base(synopGMACdevice *gmacdev)
{
DEBUG_MES("gmacdev->RxDescDma = %08x\n",gmacdev -> RxDescDma);
synopGMACWriteReg(gmacdev -> DmaBase,DmaRxBaseAddr,(u32)gmacdev -> RxDescDma);
return;
}
/**
* Programs the DmaTxBaseAddress with the Tx descriptor base address.
* Tx Descriptor's base address is available in the gmacdev structure. This function progrms the
* Dma Tx Base address with the starting address of the descriptor ring or chain.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_init_tx_desc_base(synopGMACdevice *gmacdev)
{
synopGMACWriteReg(gmacdev -> DmaBase,DmaTxBaseAddr,(u32)gmacdev -> TxDescDma);
return;
}
/**
* Makes the Dma as owner for this descriptor.
* This function sets the own bit of status field of the DMA descriptor,
* indicating the DMA is the owner for this descriptor.
* @param[in] pointer to DmaDesc structure.
* \return returns void.
*/
void synopGMAC_set_owner_dma(DmaDesc *desc)
{
desc -> status |= DescOwnByDma;
}
/**
* set tx descriptor to indicate SOF.
* This Descriptor contains the start of ethernet frame.
* @param[in] pointer to DmaDesc structure.
* \return returns void.
*/
void synopGMAC_set_desc_sof(DmaDesc *desc)
{
#ifdef ENH_DESC
desc -> status |= DescTxFirst;//ENH_DESC
#else
desc -> length |= DescTxFirst;
#endif
}
/**
* set tx descriptor to indicate EOF.
* This descriptor contains the End of ethernet frame.
* @param[in] pointer to DmaDesc structure.
* \return returns void.
*/
void synopGMAC_set_desc_eof(DmaDesc *desc)
{
#ifdef ENH_DESC
desc -> status |= DescTxLast;//ENH_DESC
#else
desc -> length |= DescTxLast;
#endif
}
/**
* checks whether this descriptor contains start of frame.
* This function is to check whether the descriptor's data buffer
* contains a fresh ethernet frame?
* @param[in] pointer to DmaDesc structure.
* \return returns true if SOF in current descriptor, else returns fail.
*/
bool synopGMAC_is_sof_in_rx_desc(DmaDesc *desc)
{
return ((desc -> status & DescRxFirst) == DescRxFirst);
}
/**
* checks whether this descriptor contains end of frame.
* This function is to check whether the descriptor's data buffer
* contains end of ethernet frame?
* @param[in] pointer to DmaDesc structure.
* \return returns true if SOF in current descriptor, else returns fail.
*/
bool synopGMAC_is_eof_in_rx_desc(DmaDesc *desc)
{
return ((desc -> status & DescRxLast) == DescRxLast);
}
/**
* checks whether destination address filter failed in the rx frame.
* @param[in] pointer to DmaDesc structure.
* \return returns true if Failed, false if not.
*/
bool synopGMAC_is_da_filter_failed(DmaDesc *desc)
{
return ((desc -> status & DescDAFilterFail) == DescDAFilterFail);
}
/**
* checks whether source address filter failed in the rx frame.
* @param[in] pointer to DmaDesc structure.
* \return returns true if Failed, false if not.
*/
bool synopGMAC_is_sa_filter_failed(DmaDesc *desc)
{
return ((desc -> status & DescSAFilterFail) == DescSAFilterFail);
}
/**
* Checks whether the descriptor is owned by DMA.
* If descriptor is owned by DMA then the OWN bit is set to 1. This API is same for both ring and chain mode.
* @param[in] pointer to DmaDesc structure.
* \return returns true if Dma owns descriptor and false if not.
*/
bool synopGMAC_is_desc_owned_by_dma(DmaDesc *desc)
{
return ((desc -> status & DescOwnByDma) == DescOwnByDma);
}
/**
* returns the byte length of received frame including CRC.
* This returns the no of bytes received in the received ethernet frame including CRC(FCS).
* @param[in] pointer to DmaDesc structure.
* \return returns the length of received frame lengths in bytes.
*/
u32 synopGMAC_get_rx_desc_frame_length(u32 status)
{
return ((status & DescFrameLengthMask) >> DescFrameLengthShift);
}
/**
* Checks whether the descriptor is valid
* if no errors such as CRC/Receive Error/Watchdog Timeout/Late collision/Giant Frame/Overflow/Descriptor
* error the descritpor is said to be a valid descriptor.
* @param[in] pointer to DmaDesc structure.
* \return True if desc valid. false if error.
*/
bool synopGMAC_is_desc_valid(u32 status)
{
return ((status & DescError) == 0);
}
/**
* Checks whether the descriptor is empty.
* If the buffer1 and buffer2 lengths are zero in ring mode descriptor is empty.
* In chain mode buffer2 length is 0 but buffer2 itself contains the next descriptor address.
* @param[in] pointer to DmaDesc structure.
* \return returns true if descriptor is empty, false if not empty.
*/
bool synopGMAC_is_desc_empty(DmaDesc *desc)
{
//if both the buffer1 length and buffer2 length are zero desc is empty
return(((desc -> length & DescSize1Mask) == 0) && ((desc -> length & DescSize2Mask) == 0));
}
/**
* Checks whether the rx descriptor is valid.
* if rx descripor is not in error and complete frame is available in the same descriptor
* @param[in] pointer to DmaDesc structure.
* \return returns true if no error and first and last desc bits are set, otherwise it returns false.
*/
bool synopGMAC_is_rx_desc_valid(u32 status)
{
return ((status & DescError) == 0) && ((status & DescRxFirst) == DescRxFirst) && ((status & DescRxLast) == DescRxLast);
}
/**
* Checks whether the tx is aborted due to collisions.
* @param[in] pointer to DmaDesc structure.
* \return returns true if collisions, else returns false.
*/
bool synopGMAC_is_tx_aborted(u32 status)
{
return (((status & DescTxLateCollision) == DescTxLateCollision) | ((status & DescTxExcCollisions) == DescTxExcCollisions));
}
/**
* Checks whether the tx carrier error.
* @param[in] pointer to DmaDesc structure.
* \return returns true if carrier error occured, else returns falser.
*/
bool synopGMAC_is_tx_carrier_error(u32 status)
{
return (((status & DescTxLostCarrier) == DescTxLostCarrier) | ((status & DescTxNoCarrier) == DescTxNoCarrier));
}
/**
* Gives the transmission collision count.
* returns the transmission collision count indicating number of collisions occured before the frame was transmitted.
* Make sure to check excessive collision didnot happen to ensure the count is valid.
* @param[in] pointer to DmaDesc structure.
* \return returns the count value of collision.
*/
u32 synopGMAC_get_tx_collision_count(u32 status)
{
return ((status & DescTxCollMask) >> DescTxCollShift);
}
u32 synopGMAC_is_exc_tx_collisions(u32 status)
{
return ((status & DescTxExcCollisions) == DescTxExcCollisions);
}
/**
* Check for damaged frame due to overflow or collision.
* Retruns true if rx frame was damaged due to buffer overflow in MTL or late collision in half duplex mode.
* @param[in] pointer to DmaDesc structure.
* \return returns true if error else returns false.
*/
bool synopGMAC_is_rx_frame_damaged(u32 status)
{
//bool synopGMAC_dma_rx_collisions(u32 status)
return (((status & DescRxDamaged) == DescRxDamaged) | ((status & DescRxCollision) == DescRxCollision));
}
/**
* Check for damaged frame due to collision.
* Retruns true if rx frame was damaged due to late collision in half duplex mode.
* @param[in] pointer to DmaDesc structure.
* \return returns true if error else returns false.
*/
bool synopGMAC_is_rx_frame_collision(u32 status)
{
//bool synopGMAC_dma_rx_collisions(u32 status)
return ((status & DescRxCollision) == DescRxCollision);
}
/**
* Check for receive CRC error.
* Retruns true if rx frame CRC error occured.
* @param[in] pointer to DmaDesc structure.
* \return returns true if error else returns false.
*/
bool synopGMAC_is_rx_crc(u32 status)
{
//u32 synopGMAC_dma_rx_crc(u32 status)
return ((status & DescRxCrc) == DescRxCrc);
}
/**
* Indicates rx frame has non integer multiple of bytes. (odd nibbles).
* Retruns true if dribbling error in rx frame.
* @param[in] pointer to DmaDesc structure.
* \return returns true if error else returns false.
*/
bool synopGMAC_is_frame_dribbling_errors(u32 status)
{
//u32 synopGMAC_dma_rx_frame_errors(u32 status)
return ((status & DescRxDribbling) == DescRxDribbling);
}
/**
* Indicates error in rx frame length.
* Retruns true if received frame length doesnot match with the length field
* @param[in] pointer to DmaDesc structure.
* \return returns true if error else returns false.
*/
bool synopGMAC_is_rx_frame_length_errors(u32 status)
{
//u32 synopGMAC_dma_rx_length_errors(u32 status)
return((status & DescRxLengthError) == DescRxLengthError);
}
/**
* Checks whether this rx descriptor is last rx descriptor.
* This returns true if it is last descriptor either in ring mode or in chain mode.
* @param[in] pointer to devic structure.
* @param[in] pointer to DmaDesc structure.
* \return returns true if it is last descriptor, false if not.
* \note This function should not be called before initializing the descriptor using synopGMAC_desc_init().
*/
bool synopGMAC_is_last_rx_desc(synopGMACdevice *gmacdev,DmaDesc *desc)
{
//bool synopGMAC_is_last_desc(DmaDesc *desc)
return (((desc -> length & RxDescEndOfRing) == RxDescEndOfRing) || ((u64)gmacdev -> RxDesc == desc -> data2));
}
/**
* Checks whether this tx descriptor is last tx descriptor.
* This returns true if it is last descriptor either in ring mode or in chain mode.
* @param[in] pointer to devic structure.
* @param[in] pointer to DmaDesc structure.
* \return returns true if it is last descriptor, false if not.
* \note This function should not be called before initializing the descriptor using synopGMAC_desc_init().
*/
bool synopGMAC_is_last_tx_desc(synopGMACdevice *gmacdev,DmaDesc *desc)
{
//bool synopGMAC_is_last_desc(DmaDesc *desc)
#ifdef ENH_DESC
return (((desc->status & TxDescEndOfRing) == TxDescEndOfRing) || ((u64)gmacdev -> TxDesc == desc -> data2));
#else
return (((desc->length & TxDescEndOfRing) == TxDescEndOfRing) || ((u64)gmacdev -> TxDesc == desc -> data2));
#endif
}
/**
* Checks whether this rx descriptor is in chain mode.
* This returns true if it is this descriptor is in chain mode.
* @param[in] pointer to DmaDesc structure.
* \return returns true if chain mode is set, false if not.
*/
bool synopGMAC_is_rx_desc_chained(DmaDesc *desc)
{
return((desc -> length & RxDescChain) == RxDescChain);
}
/**
* Checks whether this tx descriptor is in chain mode.
* This returns true if it is this descriptor is in chain mode.
* @param[in] pointer to DmaDesc structure.
* \return returns true if chain mode is set, false if not.
*/
bool synopGMAC_is_tx_desc_chained(DmaDesc *desc)
{
#ifdef ENH_DESC
return((desc -> status & TxDescChain) == TxDescChain);
#else
return((desc -> length & TxDescChain) == TxDescChain);
#endif
}
/**
* Driver Api to get the descriptor field information.
* This returns the status, dma-able address of buffer1, the length of buffer1, virtual address of buffer1
* dma-able address of buffer2, length of buffer2, virtural adddress of buffer2.
* @param[in] pointer to DmaDesc structure.
* @param[out] pointer to status field fo descriptor.
* @param[out] dma-able address of buffer1.
* @param[out] length of buffer1.
* @param[out] virtual address of buffer1.
* @param[out] dma-able address of buffer2.
* @param[out] length of buffer2.
* @param[out] virtual address of buffer2.
* \return returns void.
*/
void synopGMAC_get_desc_data(DmaDesc *desc,u32 *Status,u32 *Buffer1,u32 *Length1,u64 *Data1,u32 *Buffer2,u32 *Length2,u64 *Data2)
{
if(Status != 0)
{
*Status = desc -> status;
}
if(Buffer1 != 0)
{
*Buffer1 = desc -> buffer1;
}
if(Length1 != 0)
{
*Length1 = (desc -> length & DescSize1Mask) >> DescSize1Shift;
}
if(Data1 != 0)
{
*Data1 = desc -> data1;
}
if(Buffer2 != 0)
{
*Buffer2 = desc -> buffer2;
}
if(Length2 != 0)
{
*Length2 = (desc -> length & DescSize2Mask) >> DescSize2Shift;
}
if(Data2 != 0)
{
*Data2 = desc -> data2;
}
return;
}
#ifdef ENH_DESC_8W
/**
* This function is defined two times. Once when the code is compiled for ENHANCED DESCRIPTOR SUPPORT and Once for Normal descriptor
* Get the index and address of Tx desc.
* This api is same for both ring mode and chain mode.
* This function tracks the tx descriptor the DMA just closed after the transmission of data from this descriptor is
* over. This returns the descriptor fields to the caller.
* @param[in] pointer to synopGMACdevice.
* @param[out] status field of the descriptor.
* @param[out] Dma-able buffer1 pointer.
* @param[out] length of buffer1 (Max is 2048).
* @param[out] virtual pointer for buffer1.
* @param[out] Dma-able buffer2 pointer.
* @param[out] length of buffer2 (Max is 2048).
* @param[out] virtual pointer for buffer2.
* @param[out] u32 data indicating whether the descriptor is in ring mode or chain mode.
* \return returns present tx descriptor index on success. Negative value if error.
*/
s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2,
u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_Low)
{
u32 txover = gmacdev->TxBusy;
DmaDesc * txdesc = gmacdev->TxBusyDesc;
if(synopGMAC_is_desc_owned_by_dma(txdesc))
return -1;
if(synopGMAC_is_desc_empty(txdesc))
return -1;
(gmacdev->BusyTxDesc)--; //busy tx descriptor is reduced by one as it will be handed over to Processor now
if(Status != 0)
*Status = txdesc->status;
if(Ext_Status != 0)
*Ext_Status = txdesc->extstatus;
if(Time_Stamp_High != 0)
*Time_Stamp_High = txdesc->timestamphigh;
if(Time_Stamp_Low != 0)
*Time_Stamp_High = txdesc->timestamplow;
if(Buffer1 != 0)
*Buffer1 = txdesc->buffer1;
if(Length1 != 0)
*Length1 = (txdesc->length & DescSize1Mask) >> DescSize1Shift;
if(Data1 != 0)
*Data1 = txdesc->data1;
if(Buffer2 != 0)
*Buffer2 = txdesc->buffer2;
if(Length2 != 0)
*Length2 = (txdesc->length & DescSize2Mask) >> DescSize2Shift;
if(Data1 != 0)
*Data2 = txdesc->data2;
gmacdev->TxBusy = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txover + 1;
if(synopGMAC_is_tx_desc_chained(txdesc)){
gmacdev->TxBusyDesc = (DmaDesc *)txdesc->data2;
synopGMAC_tx_desc_init_chain(txdesc);
}
else{
gmacdev->TxBusyDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1);
synopGMAC_tx_desc_init_ring(txdesc, synopGMAC_is_last_tx_desc(gmacdev,txdesc));
}
TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",txover,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2);
return txover;
}
#else
/**
* Get the index and address of Tx desc.
* This api is same for both ring mode and chain mode.
* This function tracks the tx descriptor the DMA just closed after the transmission of data from this descriptor is
* over. This returns the descriptor fields to the caller.
* @param[in] pointer to synopGMACdevice.
* @param[out] status field of the descriptor.
* @param[out] Dma-able buffer1 pointer.
* @param[out] length of buffer1 (Max is 2048).
* @param[out] virtual pointer for buffer1.
* @param[out] Dma-able buffer2 pointer.
* @param[out] length of buffer2 (Max is 2048).
* @param[out] virtual pointer for buffer2.
* @param[out] u32 data indicating whether the descriptor is in ring mode or chain mode.
* \return returns present tx descriptor index on success. Negative value if error.
*/
s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2 )
{
u32 txover = gmacdev->TxBusy;
DmaDesc * txdesc = gmacdev->TxBusyDesc;
int i;
//sw: dbg
//pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_R);
//pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_W);
#if SYNOP_TX_DEBUG
printf("Cache sync before get a used tx dma desc!\n");
printf("\n==%02d %08x %08x %08x %08x %08x %08x %08x\n",txover,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2);
#endif
if(synopGMAC_is_desc_owned_by_dma(txdesc))
{
return -1;
}
// gmacdev->TxBusy = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txover + 1;
// gmacdev->TxBusyDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1);
if(synopGMAC_is_desc_empty(txdesc))
{
return -1;
}
(gmacdev->BusyTxDesc)--; //busy tx descriptor is reduced by one as it will be handed over to Processor now
if(Status != 0)
*Status = txdesc->status;
if(Buffer1 != 0)
*Buffer1 = txdesc->buffer1;
if(Length1 != 0)
*Length1 = (txdesc->length & DescSize1Mask) >> DescSize1Shift;
if(Data1 != 0)
*Data1 = txdesc->data1;
if(Buffer2 != 0)
*Buffer2 = txdesc->buffer2;
if(Length2 != 0)
*Length2 = (txdesc->length & DescSize2Mask) >> DescSize2Shift;
if(Data1 != 0)
*Data2 = txdesc->data2;
gmacdev->TxBusy = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txover + 1;
if(synopGMAC_is_tx_desc_chained(txdesc))
{
gmacdev->TxBusyDesc = (DmaDesc *)txdesc->data2;
synopGMAC_tx_desc_init_chain(txdesc);
}
else
{
gmacdev->TxBusyDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1);
synopGMAC_tx_desc_init_ring(txdesc, synopGMAC_is_last_tx_desc(gmacdev,txdesc));
}
//printf("%02d %08x %08x %08x %08x %08x %08x %08x\n",txover,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2);
//pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_W);
#if SYNOP_TX_DEBUG
printf("Cache sync after re-init a tx dma desc!\n");
#endif
return txover;
}
#endif
/**
* Populate the tx desc structure with the buffer address.
* Once the driver has a packet ready to be transmitted, this function is called with the
* valid dma-able buffer addresses and their lengths. This function populates the descriptor
* and make the DMA the owner for the descriptor. This function also controls whether Checksum
* offloading to be done in hardware or not.
* This api is same for both ring mode and chain mode.
* @param[in] pointer to synopGMACdevice.
* @param[in] Dma-able buffer1 pointer.
* @param[in] length of buffer1 (Max is 2048).
* @param[in] virtual pointer for buffer1.
* @param[in] Dma-able buffer2 pointer.
* @param[in] length of buffer2 (Max is 2048).
* @param[in] virtual pointer for buffer2.
* @param[in] u32 data indicating whether the descriptor is in ring mode or chain mode.
* @param[in] u32 indicating whether the checksum offloading in HW/SW.
* \return returns present tx descriptor index on success. Negative value if error.
*/
u32 len;
s32 synopGMAC_set_tx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u64 Data1, u32 Buffer2, u32 Length2, u64 Data2,u32 offload_needed,u32 * index, DmaDesc * Dpr)
{
u32 txnext = gmacdev->TxNext;
DmaDesc * txdesc = gmacdev->TxNextDesc;
*index = txnext;
Dpr = txdesc;
if(!synopGMAC_is_desc_empty(txdesc))
{
TR("set tx qptr: desc empty!\n");
return -1;
}
(gmacdev->BusyTxDesc)++; //busy tx descriptor is reduced by one as it will be handed over to Processor now
if(synopGMAC_is_tx_desc_chained(txdesc)){
txdesc->length |= ((Length1 <<DescSize1Shift) & DescSize1Mask);
#ifdef ENH_DESC
txdesc->status |= (DescTxFirst | DescTxLast | DescTxIntEnable); //ENH_DESC
#else
txdesc->length |= (DescTxFirst | DescTxLast | DescTxIntEnable); //Its always assumed that complete data will fit in to one descriptor
#endif
txdesc->buffer1 = Buffer1;
txdesc->data1 = Data1;
if(offload_needed){
/*
Make sure that the OS you are running supports the IP and TCP checkusm offloaidng,
before calling any of the functions given below.
*/
synopGMAC_tx_checksum_offload_ipv4hdr(gmacdev, txdesc);
synopGMAC_tx_checksum_offload_tcponly(gmacdev, txdesc);
// synopGMAC_tx_checksum_offload_tcp_pseudo(gmacdev, txdesc);
}
#ifdef ENH_DESC
txdesc->status |= DescOwnByDma;//ENH_DESC
#else
txdesc->status = DescOwnByDma;
#endif
gmacdev->TxNext = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txnext + 1;
gmacdev->TxNextDesc = (DmaDesc *)txdesc->data2;
}
else{
// printf("synopGMAC_set_tx_qptr:in ring mode\n");
txdesc->length |= (((Length1 <<DescSize1Shift) & DescSize1Mask) | ((Length2 <<DescSize2Shift) & DescSize2Mask));
#ifdef ENH_DESC
txdesc->status |= (DescTxFirst | DescTxLast | DescTxIntEnable); //ENH_DESC
#else
txdesc->length |= (DescTxFirst | DescTxLast | DescTxIntEnable); //Its always assumed that complete data will fit in to one descriptor
#endif
txdesc->buffer1 = Buffer1;
txdesc->data1 = Data1;
txdesc->buffer2 = Buffer2;
txdesc->data2 = Data2;
if(offload_needed){
/*
Make sure that the OS you are running supports the IP and TCP checkusm offloaidng,
before calling any of the functions given below.
*/
//sw: i am not sure about the checksum.so i omit it in the outside
synopGMAC_tx_checksum_offload_ipv4hdr(gmacdev, txdesc);
synopGMAC_tx_checksum_offload_tcponly(gmacdev, txdesc);
// synopGMAC_tx_checksum_offload_tcp_pseudo(gmacdev, txdesc);
}
#ifdef ENH_DESC
txdesc->status |= DescOwnByDma;//ENH_DESC
#else
// printf("synopGMAC_set_tx_qptr:give the tx descroptor to dma\n");
txdesc->status = DescOwnByDma;
#endif
gmacdev->TxNext = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? 0 : txnext + 1;
gmacdev->TxNextDesc = synopGMAC_is_last_tx_desc(gmacdev,txdesc) ? gmacdev->TxDesc : (txdesc + 1);
}
#if SYNOP_TX_DEBUG
printf("%02d %08x %08x %08x %08x %08x %08x %08x\n",txnext,(u32)txdesc,txdesc->status,txdesc->length,txdesc->buffer1,txdesc->buffer2,txdesc->data1,txdesc->data2);
#endif
//pci_sync_cache(0, (vm_offset_t)txdesc, 64, SYNC_W);
#if SYNOP_TX_DEBUG
printf("Cache sync to set a tx desc!\n");
#endif
//pci_sync_cache(0, (vm_offset_t)(txdesc->data1), 32, SYNC_W);
#if SYNOP_TX_DEBUG
//printf("Cache sync for data in the buf of the tx desc!\n");
#endif
return txnext;
}
#ifdef ENH_DESC_8W
/**
* Prepares the descriptor to receive packets.
* The descriptor is allocated with the valid buffer addresses (sk_buff address) and the length fields
* and handed over to DMA by setting the ownership. After successful return from this function the
* descriptor is added to the receive descriptor pool/queue.
* This api is same for both ring mode and chain mode.
* @param[in] pointer to synopGMACdevice.
* @param[in] Dma-able buffer1 pointer.
* @param[in] length of buffer1 (Max is 2048).
* @param[in] Dma-able buffer2 pointer.
* @param[in] length of buffer2 (Max is 2048).
* @param[in] u32 data indicating whether the descriptor is in ring mode or chain mode.
* \return returns present rx descriptor index on success. Negative value if error.
*/
// dma_addr RX_BUF_SIZE skb
s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u64 Data1, u32 Buffer2, u32 Length2, u64 Data2)
{
u32 rxnext = gmacdev->RxNext;
DmaDesc * rxdesc = gmacdev->RxNextDesc;
if(!synopGMAC_is_desc_empty(rxdesc))
return -1;
if(synopGMAC_is_rx_desc_chained(rxdesc)){
rxdesc->length |= ((Length1 <<DescSize1Shift) & DescSize1Mask);
rxdesc->buffer1 = Buffer1;
rxdesc->data1 = Data1;
rxdesc->extstatus = 0;
rxdesc->reserved1 = 0;
rxdesc->timestamplow = 0;
rxdesc->timestamphigh = 0;
if((rxnext % MODULO_INTERRUPT) !=0)
rxdesc->length |= RxDisIntCompl;
rxdesc->status = DescOwnByDma;
gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
gmacdev->RxNextDesc = (DmaDesc *)rxdesc->data2;
}
else{
rxdesc->length |= (((Length1 <<DescSize1Shift) & DescSize1Mask) | ((Length2 << DescSize2Shift) & DescSize2Mask));
rxdesc->buffer1 = Buffer1;
rxdesc->data1 = Data1;
rxdesc->extstatus = 0;
rxdesc->reserved1 = 0;
rxdesc->timestamplow = 0;
rxdesc->timestamphigh = 0;
rxdesc->buffer2 = Buffer2;
rxdesc->data2 = Data2;
if((rxnext % MODULO_INTERRUPT) !=0)
rxdesc->length |= RxDisIntCompl;
rxdesc->status = DescOwnByDma;
gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
gmacdev->RxNextDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1);
}
#if SYNOP_RX_DEBUG
TR("%02d %08x %08x %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2,rxdesc->dummy1,rxdesc->dummy2);
#endif
(gmacdev->BusyRxDesc)++; //One descriptor will be given to Hardware. So busy count incremented by one
//pci_sync_cache(0, (vm_offset_t)rxdesc,64, SYNC_W);
return rxnext;
}
#else
/**
* Prepares the descriptor to receive packets.
* The descriptor is allocated with the valid buffer addresses (sk_buff address) and the length fields
* and handed over to DMA by setting the ownership. After successful return from this function the
* descriptor is added to the receive descriptor pool/queue.
* This api is same for both ring mode and chain mode.
* @param[in] pointer to synopGMACdevice.
* @param[in] Dma-able buffer1 pointer.
* @param[in] length of buffer1 (Max is 2048).
* @param[in] Dma-able buffer2 pointer.
* @param[in] length of buffer2 (Max is 2048).
* @param[in] u32 data indicating whether the descriptor is in ring mode or chain mode.
* \return returns present rx descriptor index on success. Negative value if error.
*/
s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u64 Data1, u32 Buffer2, u32 Length2, u64 Data2)
{
u32 rxnext = gmacdev->RxNext;
DmaDesc * rxdesc = gmacdev->RxNextDesc;
if(!synopGMAC_is_desc_empty(rxdesc))
return -1;
if(synopGMAC_is_rx_desc_chained(rxdesc)){
rxdesc->length |= ((Length1 <<DescSize1Shift) & DescSize1Mask);
rxdesc->buffer1 = Buffer1;
rxdesc->data1 = Data1;
if((rxnext % MODULO_INTERRUPT) !=0)
rxdesc->length |= RxDisIntCompl;
rxdesc->status = DescOwnByDma;
gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
gmacdev->RxNextDesc = (DmaDesc *)rxdesc->data2;
}
else{
rxdesc->length |= (((Length1 <<DescSize1Shift) & DescSize1Mask) | ((Length2 << DescSize2Shift) & DescSize2Mask));
rxdesc->buffer1 = Buffer1;
rxdesc->data1 = Data1;
rxdesc->buffer2 = Buffer2;
rxdesc->data2 = Data2;
if((rxnext % MODULO_INTERRUPT) !=0)
rxdesc->length |= RxDisIntCompl;
rxdesc->status = DescOwnByDma;
gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
gmacdev->RxNextDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1);
}
#if SYNOP_RX_DEBUG
TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2);
#endif
(gmacdev->BusyRxDesc)++; //One descriptor will be given to Hardware. So busy count incremented by one
return rxnext;
}
s32 synopGMAC_set_rx_qptr_init(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u64 Data1, u32 Buffer2, u32 Length2, u64 Data2)
{
u32 rxnext = gmacdev->RxNext;
DmaDesc * rxdesc = gmacdev->RxNextDesc;
/* sw
if(synopGMAC_is_desc_owned_by_dma(rxdesc))
return -1;
*/
if(!synopGMAC_is_desc_empty(rxdesc))
return -1;
if(synopGMAC_is_rx_desc_chained(rxdesc)){
rxdesc->length |= ((Length1 <<DescSize1Shift) & DescSize1Mask);
rxdesc->buffer1 = Buffer1;
rxdesc->data1 = Data1;
if((rxnext % MODULO_INTERRUPT) !=0)
rxdesc->length |= RxDisIntCompl;
rxdesc->status = DescOwnByDma;
rxdesc->status = 0;
gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
gmacdev->RxNextDesc = (DmaDesc *)rxdesc->data2;
}
else{
rxdesc->length |= (((Length1 <<DescSize1Shift) & DescSize1Mask) | ((Length2 << DescSize2Shift) & DescSize2Mask));
rxdesc->buffer1 = Buffer1;
rxdesc->data1 = Data1;
rxdesc->buffer2 = Buffer2;
rxdesc->data2 = Data2;
if((rxnext % MODULO_INTERRUPT) !=0)
rxdesc->length |= RxDisIntCompl;
rxdesc->status = DescOwnByDma;
rxdesc->status = 0;
gmacdev->RxNext = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
gmacdev->RxNextDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1);
}
TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2);
(gmacdev->BusyRxDesc)++; //One descriptor will be given to Hardware. So busy count incremented by one
return rxnext;
}
#endif
#ifdef ENH_DESC_8W
/**
* This function is defined two times. Once when the code is compiled for ENHANCED DESCRIPTOR SUPPORT and Once for Normal descriptor
* Get back the descriptor from DMA after data has been received.
* When the DMA indicates that the data is received (interrupt is generated), this function should be
* called to get the descriptor and hence the data buffers received. With successful return from this
* function caller gets the descriptor fields for processing. check the parameters to understand the
* fields returned.`
* @param[in] pointer to synopGMACdevice.
* @param[out] pointer to hold the status of DMA.
* @param[out] Dma-able buffer1 pointer.
* @param[out] pointer to hold length of buffer1 (Max is 2048).
* @param[out] virtual pointer for buffer1.
* @param[out] Dma-able buffer2 pointer.
* @param[out] pointer to hold length of buffer2 (Max is 2048).
* @param[out] virtual pointer for buffer2.
* \return returns present rx descriptor index on success. Negative value if error.
*/
s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2,
u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_Low)
{
u32 rxnext = gmacdev->RxBusy; // index of descriptor the DMA just completed. May be useful when data
//is spread over multiple buffers/descriptors
DmaDesc * rxdesc = gmacdev->RxBusyDesc;
if(synopGMAC_is_desc_owned_by_dma(rxdesc))
return -1;
if(synopGMAC_is_desc_empty(rxdesc))
return -1;
if(Status != 0)
*Status = rxdesc->status;// send the status of this descriptor
if(Ext_Status != 0)
*Ext_Status = rxdesc->extstatus;
if(Time_Stamp_High != 0)
*Time_Stamp_High = rxdesc->timestamphigh;
if(Time_Stamp_Low != 0)
*Time_Stamp_Low = rxdesc->timestamplow;
if(Length1 != 0)
*Length1 = (rxdesc->length & DescSize1Mask) >> DescSize1Shift;
if(Buffer1 != 0)
*Buffer1 = rxdesc->buffer1;
if(Data1 != 0)
*Data1 = rxdesc->data1;
if(Length2 != 0)
*Length2 = (rxdesc->length & DescSize2Mask) >> DescSize2Shift;
if(Buffer2 != 0)
*Buffer2 = rxdesc->buffer2;
if(Data1 != 0)
*Data2 = rxdesc->data2;
gmacdev->RxBusy = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
if(synopGMAC_is_rx_desc_chained(rxdesc)){
gmacdev->RxBusyDesc = (DmaDesc *)rxdesc->data2;
synopGMAC_rx_desc_init_chain(rxdesc);
//synopGMAC_desc_init_chain(rxdesc, synopGMAC_is_last_rx_desc(gmacdev,rxdesc),0,0);
}
else{
gmacdev->RxBusyDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1);
synopGMAC_rx_desc_init_ring(rxdesc, synopGMAC_is_last_rx_desc(gmacdev,rxdesc));
}
TR("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2);
(gmacdev->BusyRxDesc)--; //busy tx descriptor is reduced by one as it will be handed over to Processor now
return(rxnext);
}
#else
/**
* Get back the descriptor from DMA after data has been received.
* When the DMA indicates that the data is received (interrupt is generated), this function should be
* called to get the descriptor and hence the data buffers received. With successful return from this
* function caller gets the descriptor fields for processing. check the parameters to understand the
* fields returned.`
* @param[in] pointer to synopGMACdevice.
* @param[out] pointer to hold the status of DMA.
* @param[out] Dma-able buffer1 pointer.
* @param[out] pointer to hold length of buffer1 (Max is 2048).
* @param[out] virtual pointer for buffer1.
* @param[out] Dma-able buffer2 pointer.
* @param[out] pointer to hold length of buffer2 (Max is 2048).
* @param[out] virtual pointer for buffer2.
* \return returns present rx descriptor index on success. Negative value if error.
*/
s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2)
{
u32 rxnext = gmacdev->RxBusy; // index of descriptor the DMA just completed. May be useful when data
//is spread over multiple buffers/descriptors
DmaDesc * rxdesc = gmacdev->RxBusyDesc;
u32 len;
if(synopGMAC_is_desc_owned_by_dma(rxdesc))
{
DEBUG_MES("synopGMAC_get_rx_qptr:DMA descriptor is owned by GMAC!\n");
return -1;
}
if(synopGMAC_is_desc_empty(rxdesc))
{
DEBUG_MES("synopGMAC_get_rx_qptr:rx desc is empty!\n");
return -1;
}
if(Status != 0)
*Status = rxdesc->status;// send the status of this descriptor
if(Length1 != 0)
*Length1 = (rxdesc->length & DescSize1Mask) >> DescSize1Shift;
if(Buffer1 != 0)
*Buffer1 = rxdesc->buffer1;
if(Data1 != 0)
*Data1 = rxdesc->data1;
if(Length2 != 0)
*Length2 = (rxdesc->length & DescSize2Mask) >> DescSize2Shift;
if(Buffer2 != 0)
*Buffer2 = rxdesc->buffer2;
if(Data1 != 0)
*Data2 = rxdesc->data2;
len = synopGMAC_get_rx_desc_frame_length(*Status);
DEBUG_MES("Cache sync for data buffer in rx dma desc: length = 0x%x\n",len);
gmacdev->RxBusy = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? 0 : rxnext + 1;
if(synopGMAC_is_rx_desc_chained(rxdesc)){
gmacdev->RxBusyDesc = (DmaDesc *)rxdesc->data2;
synopGMAC_rx_desc_init_chain(rxdesc);
}
else{
gmacdev->RxBusyDesc = synopGMAC_is_last_rx_desc(gmacdev,rxdesc) ? gmacdev->RxDesc : (rxdesc + 1);
//sw: raw data
#if SYNOP_RX_DEBUG
DEBUG_MES("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2);
#endif
synopGMAC_rx_desc_init_ring(rxdesc, synopGMAC_is_last_rx_desc(gmacdev,rxdesc));
}
#if SYNOP_RX_DEBUG
DEBUG_MES("%02d %08x %08x %08x %08x %08x %08x %08x\n",rxnext,(u32)rxdesc,rxdesc->status,rxdesc->length,rxdesc->buffer1,rxdesc->buffer2,rxdesc->data1,rxdesc->data2);
#endif
(gmacdev->BusyRxDesc)--; //This returns one descriptor to processor. So busy count will be decremented by one
return(rxnext);
}
#endif
/**
* Clears all the pending interrupts.
* If the Dma status register is read then all the interrupts gets cleared
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_clear_interrupt(synopGMACdevice *gmacdev)
{
u32 data;
data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus);
TR("DMA status reg = 0x%x before cleared!\n",data);
synopGMACWriteReg(gmacdev->DmaBase, DmaStatus ,data);
// plat_delay(DEFAULT_LOOP_VARIABLE);
// data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus);
TR("DMA status reg = 0x%x after cleared!\n",data);
}
/**
* Returns the all unmasked interrupt status after reading the DmaStatus register.
* @param[in] pointer to synopGMACdevice.
* \return 0 upon success. Error code upon failure.
*/
u32 synopGMAC_get_interrupt_type(synopGMACdevice *gmacdev)
{
u32 data;
u32 interrupts = 0;
data = synopGMACReadReg(gmacdev->DmaBase, DmaStatus);
//data = data & ~0x84; //sw: some bits shoud not be cleaned
synopGMACWriteReg(gmacdev->DmaBase, DmaStatus ,data); //manju: I think this is the appropriate location to clear the interrupts
plat_delay(DEFAULT_LOOP_VARIABLE);
if(data & DmaIntErrorMask) interrupts |= synopGMACDmaError;
if(data & DmaIntRxNormMask) interrupts |= synopGMACDmaRxNormal;
if(data & DmaIntRxAbnMask) interrupts |= synopGMACDmaRxAbnormal;
if(data & DmaIntRxStoppedMask) interrupts |= synopGMACDmaRxStopped;
if(data & DmaIntTxNormMask) interrupts |= synopGMACDmaTxNormal;
if(data & DmaIntTxAbnMask) interrupts |= synopGMACDmaTxAbnormal;
if(data & DmaIntTxStoppedMask) interrupts |= synopGMACDmaTxStopped;
return interrupts;
}
/**
* Returns the interrupt mask.
* @param[in] pointer to synopGMACdevice.
* \return 0 upon success. Error code upon failure.
*/
#if UNUSED
u32 synopGMAC_get_interrupt_mask(synopGMACdevice *gmacdev)
{
return(synopGMACReadReg(gmacdev->DmaBase, DmaInterrupt));
}
#endif
/**
* Enable all the interrupts.
* Enables the DMA interrupt as specified by the bit mask.
* @param[in] pointer to synopGMACdevice.
* @param[in] bit mask of interrupts to be enabled.
* \return returns void.
*/
#if UNUSED
void synopGMAC_enable_interrupt(synopGMACdevice *gmacdev, u32 interrupts)
{
synopGMACWriteReg(gmacdev->DmaBase, DmaInterrupt, interrupts);
return;
}
#endif
/**
* Disable all the interrupts.
* Disables all DMA interrupts.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
* \note This function disabled all the interrupts, if you want to disable a particular interrupt then
* use synopGMAC_disable_interrupt().
*/
void synopGMAC_disable_interrupt_all(synopGMACdevice *gmacdev)
{
// rt_kprintf("dmabase = 0x%x\n",gmacdev->DmaBase);
synopGMACWriteReg(gmacdev->DmaBase, DmaInterrupt, DmaIntDisable);
// synopGMACReadReg(gmacdev->DmaBase, DmaInterrupt);
return;
}
/**
* Disable interrupt according to the bitfield supplied.
* Disables only those interrupts specified in the bit mask in second argument.
* @param[in] pointer to synopGMACdevice.
* @param[in] bit mask for interrupts to be disabled.
* \return returns void.
*/
#if UNUSED
void synopGMAC_disable_interrupt(synopGMACdevice *gmacdev, u32 interrupts)
{
synopGMACClearBits(gmacdev->DmaBase, DmaInterrupt, interrupts);
return;
}
#endif
/**
* Enable the DMA Reception.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_enable_dma_rx(synopGMACdevice * gmacdev)
{
// synopGMACSetBits(gmacdev->DmaBase, DmaControl, DmaRxStart);
u32 data;
data = synopGMACReadReg(gmacdev->DmaBase, DmaControl);
data |= DmaRxStart;
TR0(" ===33334\n");
synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data);
TR0(" ===33344\n");
}
/**
* Enable the DMA Transmission.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_enable_dma_tx(synopGMACdevice * gmacdev)
{
// synopGMACSetBits(gmacdev->DmaBase, DmaControl, DmaTxStart);
u32 data;
data = synopGMACReadReg(gmacdev->DmaBase, DmaControl);
data |= DmaTxStart;
synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data);
}
/**
* Resumes the DMA Transmission.
* the DmaTxPollDemand is written. (the data writeen could be anything).
* This forces the DMA to resume transmission.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_resume_dma_tx(synopGMACdevice * gmacdev)
{
synopGMACWriteReg(gmacdev->DmaBase, DmaTxPollDemand, 1);
}
/**
* Resumes the DMA Reception.
* the DmaRxPollDemand is written. (the data writeen could be anything).
* This forces the DMA to resume reception.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_resume_dma_rx(synopGMACdevice * gmacdev)
{
synopGMACWriteReg(gmacdev->DmaBase, DmaRxPollDemand, 0);
}
/**
* Take ownership of this Descriptor.
* The function is same for both the ring mode and the chain mode DMA structures.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_take_desc_ownership(DmaDesc * desc)
{
if(desc){
desc->status &= ~DescOwnByDma; //Clear the DMA own bit
// desc->status |= DescError; // Set the error to indicate this descriptor is bad
}
}
/**
* Take ownership of all the rx Descriptors.
* This function is called when there is fatal error in DMA transmission.
* When called it takes the ownership of all the rx descriptor in rx descriptor pool/queue from DMA.
* The function is same for both the ring mode and the chain mode DMA structures.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
* \note Make sure to disable the transmission before calling this function, otherwise may result in racing situation.
*/
void synopGMAC_take_desc_ownership_rx(synopGMACdevice * gmacdev)
{
s32 i;
DmaDesc *desc;
desc = gmacdev->RxDesc;
for(i = 0; i < gmacdev->RxDescCount; i++){
if(synopGMAC_is_rx_desc_chained(desc)){ //This descriptor is in chain mode
synopGMAC_take_desc_ownership(desc);
desc = (DmaDesc *)desc->data2;
}
else{
synopGMAC_take_desc_ownership(desc + i);
}
}
}
/**
* Take ownership of all the rx Descriptors.
* This function is called when there is fatal error in DMA transmission.
* When called it takes the ownership of all the tx descriptor in tx descriptor pool/queue from DMA.
* The function is same for both the ring mode and the chain mode DMA structures.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
* \note Make sure to disable the transmission before calling this function, otherwise may result in racing situation.
*/
void synopGMAC_take_desc_ownership_tx(synopGMACdevice * gmacdev)
{
s32 i;
DmaDesc *desc;
desc = gmacdev->TxDesc;
for(i = 0; i < gmacdev->TxDescCount; i++){
if(synopGMAC_is_tx_desc_chained(desc)){ //This descriptor is in chain mode
synopGMAC_take_desc_ownership(desc);
desc = (DmaDesc *)desc->data2;
}
else{
synopGMAC_take_desc_ownership(desc + i);
}
}
}
/**
* Disable the DMA for Transmission.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_disable_dma_tx(synopGMACdevice * gmacdev)
{
// synopGMACClearBits(gmacdev->DmaBase, DmaControl, DmaTxStart);
u32 data;
data = synopGMACReadReg(gmacdev->DmaBase, DmaControl);
data &= (~DmaTxStart);
synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data);
}
/**
* Disable the DMA for Reception.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_disable_dma_rx(synopGMACdevice * gmacdev)
{
// synopGMACClearBits(gmacdev->DmaBase, DmaControl, DmaRxStart);
u32 data;
data = synopGMACReadReg(gmacdev->DmaBase, DmaControl);
data &= (~DmaRxStart);
synopGMACWriteReg(gmacdev->DmaBase, DmaControl ,data);
}
/*******************PMT APIs***************************************/
/**
* Enables the assertion of PMT interrupt.
* This enables the assertion of PMT interrupt due to Magic Pkt or Wakeup frame
* reception.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_pmt_int_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask);
return;
}
#endif
/**
* Disables the assertion of PMT interrupt.
* This disables the assertion of PMT interrupt due to Magic Pkt or Wakeup frame
* reception.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_pmt_int_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask);
return;
}
/**
* Enables the power down mode of GMAC.
* This function puts the Gmac in power down mode.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_power_down_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtPowerDown);
return;
}
#endif
/**
* Disables the powerd down setting of GMAC.
* If the driver wants to bring up the GMAC from powerdown mode, even though the magic packet or the
* wake up frames received from the network, this function should be called.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_power_down_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtPowerDown);
return;
}
#endif
/**
* Enables the pmt interrupt generation in powerdown mode.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_enable_pmt_interrupt(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask);
}
#endif
/**
* Disables the pmt interrupt generation in powerdown mode.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_disable_pmt_interrupt(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask);
}
#endif
/**
* Enables GMAC to look for Magic packet.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_magic_packet_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtMagicPktEnable);
return;
}
#endif
/**
* Enables GMAC to look for wake up frame.
* Wake up frame is defined by the user.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_wakeup_frame_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtWakeupFrameEnable);
return;
}
#endif
/**
* Enables wake-up frame filter to handle unicast packets.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_pmt_unicast_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtGlobalUnicast);
return;
}
#endif
/**
* Checks whether the packet received is a magic packet?.
* @param[in] pointer to synopGMACdevice.
* \return returns True if magic packet received else returns false.
*/
bool synopGMAC_is_magic_packet_received(synopGMACdevice *gmacdev)
{
u32 data;
data = synopGMACReadReg(gmacdev->MacBase,GmacPmtCtrlStatus);
return((data & GmacPmtMagicPktReceived) == GmacPmtMagicPktReceived);
}
/**
* Checks whether the packet received is a wakeup frame?.
* @param[in] pointer to synopGMACdevice.
* \return returns true if wakeup frame received else returns false.
*/
bool synopGMAC_is_wakeup_frame_received(synopGMACdevice *gmacdev)
{
u32 data;
data = synopGMACReadReg(gmacdev->MacBase,GmacPmtCtrlStatus);
return((data & GmacPmtWakeupFrameReceived) == GmacPmtWakeupFrameReceived);
}
/**
* Populates the remote wakeup frame registers.
* Consecutive 8 writes to GmacWakeupAddr writes the wakeup frame filter registers.
* Before commensing a new write, frame filter pointer is reset to 0x0000.
* A small delay is introduced to allow frame filter pointer reset operation.
* @param[in] pointer to synopGMACdevice.
* @param[in] pointer to frame filter contents array.
* \return returns void.
*/
#if UNUSED
void synopGMAC_write_wakeup_frame_register(synopGMACdevice *gmacdev, u32 * filter_contents)
{
s32 i;
synopGMACSetBits(gmacdev->MacBase,GmacPmtCtrlStatus,GmacPmtFrmFilterPtrReset);
plat_delay(10);
for(i =0; i<WAKEUP_REG_LENGTH; i++)
synopGMACWriteReg(gmacdev->MacBase, GmacWakeupAddr, *(filter_contents + i));
return;
}
#endif
/*******************PMT APIs***************************************/
/*******************MMC APIs***************************************/
/**
* Freezes the MMC counters.
* This function call freezes the MMC counters. None of the MMC counters are updated
* due to any tx or rx frames until synopGMAC_mmc_counters_resume is called.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_mmc_counters_stop(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterFreeze);
return;
}
#endif
/**
* Resumes the MMC counter updation.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_mmc_counters_resume(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterFreeze);
return;
}
#endif
/**
* Configures the MMC in Self clearing mode.
* Programs MMC interface so that counters are cleared when the counters are read.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_mmc_counters_set_selfclear(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterResetOnRead);
return;
}
#endif
/**
* Configures the MMC in non-Self clearing mode.
* Programs MMC interface so that counters are cleared when the counters are read.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_mmc_counters_reset_selfclear(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterResetOnRead);
return;
}
#endif
/**
* Configures the MMC to stop rollover.
* Programs MMC interface so that counters will not rollover after reaching maximum value.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_mmc_counters_disable_rollover(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterStopRollover);
return;
}
/**
* Configures the MMC to rollover.
* Programs MMC interface so that counters will rollover after reaching maximum value.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_mmc_counters_enable_rollover(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacMmcCntrl,GmacMmcCounterStopRollover);
return;
}
/**
* Read the MMC Counter.
* @param[in] pointer to synopGMACdevice.
* @param[in] the counter to be read.
* \return returns the read count value.
*/
u32 synopGMAC_read_mmc_counter(synopGMACdevice *gmacdev, u32 counter)
{
return( synopGMACReadReg(gmacdev->MacBase,counter));
}
#endif
/**
* Read the MMC Rx interrupt status.
* @param[in] pointer to synopGMACdevice.
* \return returns the Rx interrupt status.
*/
u32 synopGMAC_read_mmc_rx_int_status(synopGMACdevice *gmacdev)
{
return( synopGMACReadReg(gmacdev->MacBase,GmacMmcIntrRx));
}
/**
* Read the MMC Tx interrupt status.
* @param[in] pointer to synopGMACdevice.
* \return returns the Tx interrupt status.
*/
u32 synopGMAC_read_mmc_tx_int_status(synopGMACdevice *gmacdev)
{
return( synopGMACReadReg(gmacdev->MacBase,GmacMmcIntrTx));
}
/**
* Disable the MMC Tx interrupt.
* The MMC tx interrupts are masked out as per the mask specified.
* @param[in] pointer to synopGMACdevice.
* @param[in] tx interrupt bit mask for which interrupts needs to be disabled.
* \return returns void.
*/
void synopGMAC_disable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask)
{
synopGMACSetBits(gmacdev->MacBase,GmacMmcIntrMaskTx,mask);
return;
}
/**
* Enable the MMC Tx interrupt.
* The MMC tx interrupts are enabled as per the mask specified.
* @param[in] pointer to synopGMACdevice.
* @param[in] tx interrupt bit mask for which interrupts needs to be enabled.
* \return returns void.
*/
#if UNUSED
void synopGMAC_enable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask)
{
synopGMACClearBits(gmacdev->MacBase,GmacMmcIntrMaskTx,mask);
}
#endif
/**
* Disable the MMC Rx interrupt.
* The MMC rx interrupts are masked out as per the mask specified.
* @param[in] pointer to synopGMACdevice.
* @param[in] rx interrupt bit mask for which interrupts needs to be disabled.
* \return returns void.
*/
void synopGMAC_disable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask)
{
synopGMACSetBits(gmacdev->MacBase,GmacMmcIntrMaskRx,mask);
return;
}
/**
* Enable the MMC Rx interrupt.
* The MMC rx interrupts are enabled as per the mask specified.
* @param[in] pointer to synopGMACdevice.
* @param[in] rx interrupt bit mask for which interrupts needs to be enabled.
* \return returns void.
*/
#if UNUSED
void synopGMAC_enable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask)
{
synopGMACClearBits(gmacdev->MacBase,GmacMmcIntrMaskRx,mask);
return;
}
#endif
/**
* Disable the MMC ipc rx checksum offload interrupt.
* The MMC ipc rx checksum offload interrupts are masked out as per the mask specified.
* @param[in] pointer to synopGMACdevice.
* @param[in] rx interrupt bit mask for which interrupts needs to be disabled.
* \return returns void.
*/
void synopGMAC_disable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask)
{
synopGMACSetBits(gmacdev->MacBase,GmacMmcRxIpcIntrMask,mask);
return;
}
/**
* Enable the MMC ipc rx checksum offload interrupt.
* The MMC ipc rx checksum offload interrupts are enabled as per the mask specified.
* @param[in] pointer to synopGMACdevice.
* @param[in] rx interrupt bit mask for which interrupts needs to be enabled.
* \return returns void.
*/
#if UNUSED
void synopGMAC_enable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask)
{
synopGMACClearBits(gmacdev->MacBase,GmacMmcRxIpcIntrMask,mask);
return;
}
#endif
/*******************MMC APIs***************************************/
/*******************Ip checksum offloading APIs***************************************/
/**
* Enables the ip checksum offloading in receive path.
* When set GMAC calculates 16 bit 1's complement of all received ethernet frame payload.
* It also checks IPv4 Header checksum is correct. GMAC core appends the 16 bit checksum calculated
* for payload of IP datagram and appends it to Ethernet frame transferred to the application.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
#if UNUSED
void synopGMAC_enable_rx_chksum_offload(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacConfig,GmacRxIpcOffload);
return;
}
/**
* Disable the ip checksum offloading in receive path.
* Ip checksum offloading is disabled in the receive path.
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_disable_rx_Ipchecksum_offload(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacConfig,GmacRxIpcOffload);
}
/**
* Instruct the DMA to drop the packets fails tcp ip checksum.
* This is to instruct the receive DMA engine to drop the recevied packet if they
* fails the tcp/ip checksum in hardware. Valid only when full checksum offloading is enabled(type-2).
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_rx_tcpip_chksum_drop_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->DmaBase,DmaControl,DmaDisableDropTcpCs);
return;
}
/**
* Instruct the DMA not to drop the packets even if it fails tcp ip checksum.
* This is to instruct the receive DMA engine to allow the packets even if recevied packet
* fails the tcp/ip checksum in hardware. Valid only when full checksum offloading is enabled(type-2).
* @param[in] pointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_rx_tcpip_chksum_drop_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->DmaBase,DmaControl,DmaDisableDropTcpCs);
return;
}
#endif
/**
* When the Enhanced Descriptor is enabled then the bit 0 of RDES0 indicates whether the
* Extended Status is available (RDES4). Time Stamp feature and the Checksum Offload Engine2
* makes use of this extended status to provide the status of the received packet.
* @param[in] pointer to synopGMACdevice
* \return returns TRUE or FALSE
*/
#ifdef ENH_DESC_8W
/**
* This function indicates whether extended status is available in the RDES0.
* Any function which accesses the fields of extended status register must ensure a check on this has been made
* This is valid only for Enhanced Descriptor.
* @param[in] pointer to synopGMACdevice.
* @param[in] u32 status field of the corresponding descriptor.
* \return returns TRUE or FALSE.
*/
bool synopGMAC_is_ext_status(synopGMACdevice *gmacdev,u32 status) // extended status present indicates that the RDES4 need to be probed
{
return((status & DescRxEXTsts ) != 0 ); // if extstatus set then it returns 1
}
/**
* This function returns true if the IP header checksum bit is set in the extended status.
* Valid only when enhaced status available is set in RDES0 bit 0.
* This is valid only for Enhanced Descriptor.
* @param[in] pointer to synopGMACdevice.
* @param[in] u32 status field of the corresponding descriptor.
* \return returns TRUE or FALSE.
*/
bool synopGMAC_ES_is_IP_header_error(synopGMACdevice *gmacdev,u32 ext_status) // IP header (IPV4) checksum error
{
return((ext_status & DescRxIpHeaderError) != 0 ); // if IPV4 header error return 1
}
/**
* This function returns true if the Checksum is bypassed in the hardware.
* Valid only when enhaced status available is set in RDES0 bit 0.
* This is valid only for Enhanced Descriptor.
* @param[in] pointer to synopGMACdevice.
* @param[in] u32 status field of the corresponding descriptor.
* \return returns TRUE or FALSE.
*/
bool synopGMAC_ES_is_rx_checksum_bypassed(synopGMACdevice *gmacdev,u32 ext_status) // Hardware engine bypassed the checksum computation/checking
{
return((ext_status & DescRxChkSumBypass ) != 0 ); // if checksum offloading bypassed return 1
}
/**
* This function returns true if payload checksum error is set in the extended status.
* Valid only when enhaced status available is set in RDES0 bit 0.
* This is valid only for Enhanced Descriptor.
* @param[in] pointer to synopGMACdevice.
* @param[in] u32 status field of the corresponding descriptor.
* \return returns TRUE or FALSE.
*/
bool synopGMAC_ES_is_IP_payload_error(synopGMACdevice *gmacdev,u32 ext_status) // IP payload checksum is in error (UDP/TCP/ICMP checksum error)
{
return((ext_status & DescRxIpPayloadError) != 0 ); // if IP payload error return 1
}
#endif
/**
* Decodes the Rx Descriptor status to various checksum error conditions.
* @param[in] pointer to synopGMACdevice.
* @param[in] u32 status field of the corresponding descriptor.
* \return returns decoded enum (u32) indicating the status.
*/
u32 synopGMAC_is_rx_checksum_error(synopGMACdevice *gmacdev, u32 status)
{
if (((status & DescRxChkBit5) == 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) == 0))
return RxLenLT600;
else if(((status & DescRxChkBit5) == 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) != 0))
return RxIpHdrPayLoadChkBypass;
else if(((status & DescRxChkBit5) == 0) && ((status & DescRxChkBit7) != 0) && ((status & DescRxChkBit0) != 0))
return RxChkBypass;
else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) == 0))
return RxNoChkError;
else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) == 0) && ((status & DescRxChkBit0) != 0))
return RxPayLoadChkError;
else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) != 0) && ((status & DescRxChkBit0) == 0))
return RxIpHdrChkError;
else if(((status & DescRxChkBit5) != 0) && ((status & DescRxChkBit7) != 0) && ((status & DescRxChkBit0) != 0))
return RxIpHdrPayLoadChkError;
else
return RxIpHdrPayLoadRes;
}
/**
* Checks if any Ipv4 header checksum error in the frame just transmitted.
* This serves as indication that error occureed in the IPv4 header checksum insertion.
* The sent out frame doesnot carry any ipv4 header checksum inserted by the hardware.
* @param[in] pointer to synopGMACdevice.
* @param[in] u32 status field of the corresponding descriptor.
* \return returns true if error in ipv4 header checksum, else returns false.
*/
bool synopGMAC_is_tx_ipv4header_checksum_error(synopGMACdevice *gmacdev, u32 status)
{
return((status & DescTxIpv4ChkError) == DescTxIpv4ChkError);
}
/**
* Checks if any payload checksum error in the frame just transmitted.
* This serves as indication that error occureed in the payload checksum insertion.
* The sent out frame doesnot carry any payload checksum inserted by the hardware.
* @param[in] pointer to synopGMACdevice.
* @param[in] u32 status field of the corresponding descriptor.
* \return returns true if error in ipv4 header checksum, else returns false.
*/
bool synopGMAC_is_tx_payload_checksum_error(synopGMACdevice *gmacdev, u32 status)
{
return((status & DescTxPayChkError) == DescTxPayChkError);
}
/**
* The check summ offload engine is bypassed in the tx path.
* Checksum is not computed in the Hardware.
* @param[in] pointer to synopGMACdevice.
* @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_tx_checksum_offload_bypass(synopGMACdevice *gmacdev, DmaDesc *desc)
{
#ifdef ENH_DESC
desc->status = (desc->length & (~DescTxCisMask));//ENH_DESC
#else
desc->length = (desc->length & (~DescTxCisMask));
#endif
}
/**
* The check summ offload engine is enabled to do only IPV4 header checksum.
* IPV4 header Checksum is computed in the Hardware.
* @param[in] pointer to synopGMACdevice.
* @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_tx_checksum_offload_ipv4hdr(synopGMACdevice *gmacdev, DmaDesc *desc)
{
#ifdef ENH_DESC
desc->status = ((desc->status & (~DescTxCisMask)) | DescTxCisIpv4HdrCs);//ENH_DESC
#else
desc->length = ((desc->length & (~DescTxCisMask)) | DescTxCisIpv4HdrCs);
#endif
}
/**
* The check summ offload engine is enabled to do TCPIP checsum assuming Pseudo header is available.
* Hardware computes the tcp ip checksum assuming pseudo header checksum is computed in software.
* Ipv4 header checksum is also inserted.
* @param[in] pointer to synopGMACdevice.
* @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_tx_checksum_offload_tcponly(synopGMACdevice *gmacdev, DmaDesc *desc)
{
#ifdef ENH_DESC
desc->status = ((desc->status & (~DescTxCisMask)) | DescTxCisTcpOnlyCs);//ENH_DESC
#else
desc->length = ((desc->length & (~DescTxCisMask)) | DescTxCisTcpOnlyCs);
#endif
}
/**
* The check summ offload engine is enabled to do complete checksum computation.
* Hardware computes the tcp ip checksum including the pseudo header checksum.
* Here the tcp payload checksum field should be set to 0000.
* Ipv4 header checksum is also inserted.
* @param[in] pointer to synopGMACdevice.
* @param[in] Pointer to tx descriptor for which ointer to synopGMACdevice.
* \return returns void.
*/
void synopGMAC_tx_checksum_offload_tcp_pseudo(synopGMACdevice *gmacdev, DmaDesc *desc)
{
#ifdef ENH_DESC
desc->status = ((desc->length & (~DescTxCisMask)) | DescTxCisTcpPseudoCs);
#else
desc->length = ((desc->length & (~DescTxCisMask)) | DescTxCisTcpPseudoCs);
#endif
}
/*******************Ip checksum offloading APIs***************************************/
/*******************IEEE 1588 Timestamping API***************************************/
/*
* At this time the driver supports the IEEE time stamping feature when the Enhanced Descriptors are enabled.
* For normal descriptor and the IEEE time stamp (version 1), driver support is not proviced
* Please make sure you have enabled the Advanced timestamp feature in the hardware and the driver should
* be compiled with the ADV_TME_STAMP feature.
* Some of the APIs provided here may not be valid for all configurations. Please make sure you call the
* API with due care.
*/
/**
* This function enables the timestamping. This enables the timestamping for transmit and receive frames.
* When disabled timestamp is not added to tx and receive frames and timestamp generator is suspended.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
#if UNUSED
void synopGMAC_TS_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSENA);
return;
}
/**
* This function disables the timestamping.
* When disabled timestamp is not added to tx and receive frames and timestamp generator is suspended.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask, GmacTSIntMask);
return;
}
/**
* Enable the interrupt to get timestamping interrupt.
* This enables the host to get the interrupt when (1) system time is greater or equal to the
* target time high and low register or (2) there is a overflow in th esecond register.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_int_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask);
return;
}
/**
* Disable the interrupt to get timestamping interrupt.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_int_disable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacInterruptMask,GmacPmtIntMask);
return;
}
/**
* Enable MAC address for PTP frame filtering.
* When enabled, uses MAC address (apart from MAC address 0) to filter the PTP frames when
* PTP is sent directly over Ethernet.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_mac_addr_filt_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSENMACADDR);
return;
}
/**
* Disables MAC address for PTP frame filtering.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_mac_addr_filt_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSENMACADDR);
return;
}
/**
* Selet the type of clock mode for PTP.
* Please note to use one of the follwoing as the clk_type argument.
* GmacTSOrdClk = 0x00000000, 00=> Ordinary clock
* GmacTSBouClk = 0x00010000, 01=> Boundary clock
* GmacTSEtoEClk = 0x00020000, 10=> End-to-End transparent clock
* GmacTSPtoPClk = 0x00030000, 11=> P-to-P transparent clock
* @param[in] pointer to synopGMACdevice
* @param[in] u32 value representing one of the above clk value
* \return returns void
*/
void synopGMAC_TS_set_clk_type(synopGMACdevice *gmacdev, u32 clk_type)
{
u32 clkval;
clkval = synopGMACReadReg(gmacdev->MacBase,GmacTSControl); //set the mdc clock to the user defined value
clkval = clkval | clk_type;
synopGMACWriteReg(gmacdev->MacBase,GmacTSControl,clkval);
return;
}
/**
* Enable Snapshot for messages relevant to Master.
* When enabled, snapshot is taken for messages relevant to master mode only, else snapshot is taken for messages relevant
* to slave node.
* Valid only for Ordinary clock and Boundary clock
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_master_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSMSTRENA);
return;
}
/**
* Disable Snapshot for messages relevant to Master.
* When disabled, snapshot is taken for messages relevant
* to slave node.
* Valid only for Ordinary clock and Boundary clock
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_master_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSMSTRENA);
return;
}
/**
* Enable Snapshot for Event messages.
* When enabled, snapshot is taken for event messages only (SYNC, Delay_Req, Pdelay_Req or Pdelay_Resp)
* When disabled, snapshot is taken for all messages except Announce, Management and Signaling.
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_event_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSEVNTENA);
return;
}
/**
* Disable Snapshot for Event messages.
* When disabled, snapshot is taken for all messages except Announce, Management and Signaling.
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_event_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSEVNTENA);
return;
}
/**
* Enable time stamp snapshot for IPV4 frames.
* When enabled, time stamp snapshot is taken for IPV4 frames
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_IPV4_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV4ENA);
return;
}
/**
* Disable time stamp snapshot for IPV4 frames.
* When disabled, time stamp snapshot is not taken for IPV4 frames
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_IPV4_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV4ENA);
return;
} // Only for "Advanced Time Stamp"
/**
* Enable time stamp snapshot for IPV6 frames.
* When enabled, time stamp snapshot is taken for IPV6 frames
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_IPV6_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV6ENA);
return;
}
/**
* Disable time stamp snapshot for IPV6 frames.
* When disabled, time stamp snapshot is not taken for IPV6 frames
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_IPV6_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSIPV6ENA);
return;
}
/**
* Enable time stamp snapshot for PTP over Ethernet frames.
* When enabled, time stamp snapshot is taken for PTP over Ethernet frames
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_ptp_over_ethernet_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSIPENA);
return;
}
/**
* Disable time stamp snapshot for PTP over Ethernet frames.
* When disabled, time stamp snapshot is not taken for PTP over Ethernet frames
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_ptp_over_ethernet_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSIPENA);
return;
}
/**
* Snoop PTP packet for version 2 format
* When set the PTP packets are snooped using the version 2 format.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_pkt_snoop_ver2(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSVER2ENA);
return;
}
/**
* Snoop PTP packet for version 2 format
* When set the PTP packets are snooped using the version 2 format.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_pkt_snoop_ver1(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSVER2ENA);
return;
}
/**
* Timestamp digital rollover
* When set the timestamp low register rolls over after 0x3B9A_C9FF value.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_digital_rollover_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSCTRLSSR);
return;
}
/**
* Timestamp binary rollover
* When set the timestamp low register rolls over after 0x7FFF_FFFF value.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_binary_rollover_enable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSCTRLSSR);
return;
}
/**
* Enable Time Stamp for All frames
* When set the timestamp snap shot is enabled for all frames received by the core.
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_all_frames_enable(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSENALL);
return;
}
/**
* Disable Time Stamp for All frames
* When reset the timestamp snap shot is not enabled for all frames received by the core.
* Reserved when "Advanced Time Stamp" is not selected
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_all_frames_disable(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSENALL);
return;
}
/**
* Addend Register Update
* This function loads the contents of Time stamp addend register with the supplied 32 value.
* This is reserved function when only coarse correction option is selected
* @param[in] pointer to synopGMACdevice
* @param[in] 32 bit addend value
* \return returns 0 for Success or else Failure
*/
s32 synopGMAC_TS_addend_update(synopGMACdevice *gmacdev, u32 addend_value)
{
u32 loop_variable;
synopGMACWriteReg(gmacdev->MacBase,GmacTSAddend,addend_value);// Load the addend_value in to Addend register
for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time
if(!((synopGMACReadReg(gmacdev->MacBase,GmacTSControl)) & GmacTSADDREG)){ // if it is cleared then break
break;
}
plat_delay(DEFAULT_DELAY_VARIABLE);
}
if(loop_variable < DEFAULT_LOOP_VARIABLE)
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSADDREG);
else{
TR("Error::: The TSADDREG bit is not getting cleared !!!!!!\n");
return -ESYNOPGMACPHYERR;
}
return -ESYNOPGMACNOERR;
}
/**
* time stamp Update
* This function updates (adds/subtracts) with the value specified in the Timestamp High Update and
* Timestamp Low Update register.
* @param[in] pointer to synopGMACdevice
* @param[in] Timestamp High Update value
* @param[in] Timestamp Low Update value
* \return returns 0 for Success or else Failure
*/
s32 synopGMAC_TS_timestamp_update(synopGMACdevice *gmacdev, u32 high_value, u32 low_value)
{
u32 loop_variable;
synopGMACWriteReg(gmacdev->MacBase,GmacTSHighUpdate,high_value);// Load the high value to Timestamp High register
synopGMACWriteReg(gmacdev->MacBase,GmacTSLowUpdate,low_value);// Load the high value to Timestamp High register
for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time
if(!((synopGMACReadReg(gmacdev->MacBase,GmacTSControl)) & GmacTSUPDT)){ // if it is cleared then break
break;
}
plat_delay(DEFAULT_DELAY_VARIABLE);
}
if(loop_variable < DEFAULT_LOOP_VARIABLE)
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSUPDT);
else{
TR("Error::: The TSADDREG bit is not getting cleared !!!!!!\n");
return -ESYNOPGMACPHYERR;
}
return -ESYNOPGMACNOERR;
}
/**
* time stamp Initialize
* This function Loads/Initializes h the value specified in the Timestamp High Update and
* Timestamp Low Update register.
* @param[in] pointer to synopGMACdevice
* @param[in] Timestamp High Load value
* @param[in] Timestamp Low Load value
* \return returns 0 for Success or else Failure
*/
s32 synopGMAC_TS_timestamp_init(synopGMACdevice *gmacdev, u32 high_value, u32 low_value)
{
u32 loop_variable;
synopGMACWriteReg(gmacdev->MacBase,GmacTSHighUpdate,high_value);// Load the high value to Timestamp High register
synopGMACWriteReg(gmacdev->MacBase,GmacTSLowUpdate,low_value);// Load the high value to Timestamp High register
for(loop_variable = 0; loop_variable < DEFAULT_LOOP_VARIABLE; loop_variable++){ //Wait till the busy bit gets cleared with in a certain amount of time
if(!((synopGMACReadReg(gmacdev->MacBase,GmacTSControl)) & GmacTSINT)){ // if it is cleared then break
break;
}
plat_delay(DEFAULT_DELAY_VARIABLE);
}
if(loop_variable < DEFAULT_LOOP_VARIABLE)
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSINT);
else{
TR("Error::: The TSADDREG bit is not getting cleared !!!!!!\n");
return -ESYNOPGMACPHYERR;
}
return -ESYNOPGMACNOERR;
}
/**
* Time Stamp Update Coarse
* When reset the timestamp update is done using coarse method.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_coarse_update(synopGMACdevice *gmacdev)
{
synopGMACClearBits(gmacdev->MacBase,GmacTSControl,GmacTSCFUPDT);
return;
}
/**
* Time Stamp Update Fine
* When reset the timestamp update is done using Fine method.
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_fine_update(synopGMACdevice *gmacdev)
{
synopGMACSetBits(gmacdev->MacBase,GmacTSControl,GmacTSCFUPDT);
return;
}
/**
* Load the Sub Second Increment value in to Sub Second increment register
* @param[in] pointer to synopGMACdevice
* \return returns void
*/
void synopGMAC_TS_subsecond_init(synopGMACdevice *gmacdev, u32 sub_sec_inc_value)
{
synopGMACWriteReg(gmacdev->MacBase,GmacTSSubSecIncr,(sub_sec_inc_value & GmacSSINCMsk));
return;
}
/**
* Reads the time stamp contents in to the respective pointers
* These registers are readonly.
* This function returns the 48 bit time stamp assuming Version 2 timestamp with higher word is selected.
* @param[in] pointer to synopGMACdevice
* @param[in] pointer to hold 16 higher bit second register contents
* @param[in] pointer to hold 32 bit second register contents
* @param[in] pointer to hold 32 bit subnanosecond register contents
* \return returns void
* \note Please note that since the atomic access to the timestamp registers is not possible,
* the contents read may be different from the actual time stamp.
*/
void synopGMAC_TS_read_timestamp(synopGMACdevice *gmacdev, u16 * higher_sec_val, u32 * sec_val, u32 * sub_sec_val)
{
* higher_sec_val = (u16)(synopGMACReadReg(gmacdev->MacBase,GmacTSHighWord) & GmacTSHighWordMask);
* sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSHigh);
* sub_sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSLow);
return;
}
/**
* Loads the time stamp higher sec value from the value supplied
* @param[in] pointer to synopGMACdevice
* @param[in] 16 higher bit second register contents passed as 32 bit value
* \return returns void
*/
void synopGMAC_TS_load_timestamp_higher_val(synopGMACdevice *gmacdev, u32 higher_sec_val)
{
synopGMACWriteReg(gmacdev->MacBase,GmacTSHighWord, (higher_sec_val & GmacTSHighWordMask));
return;
}
/**
* Reads the time stamp higher sec value to respective pointers
* @param[in] pointer to synopGMACdevice
* @param[in] pointer to hold 16 higher bit second register contents
* \return returns void
*/
void synopGMAC_TS_read_timestamp_higher_val(synopGMACdevice *gmacdev, u16 * higher_sec_val)
{
* higher_sec_val = (u16)(synopGMACReadReg(gmacdev->MacBase,GmacTSHighWord) & GmacTSHighWordMask);
return;
}
/**
* Load the Target time stamp registers
* This function Loads the target time stamp registers with the values proviced
* @param[in] pointer to synopGMACdevice
* @param[in] target Timestamp High value
* @param[in] target Timestamp Low value
* \return returns 0 for Success or else Failure
*/
void synopGMAC_TS_load_target_timestamp(synopGMACdevice *gmacdev, u32 sec_val, u32 sub_sec_val)
{
synopGMACWriteReg(gmacdev->MacBase,GmacTSTargetTimeHigh,sec_val);
synopGMACWriteReg(gmacdev->MacBase,GmacTSTargetTimeLow,sub_sec_val);
return;
}
/**
* Reads the Target time stamp registers
* This function Loads the target time stamp registers with the values proviced
* @param[in] pointer to synopGMACdevice
* @param[in] pointer to hold target Timestamp High value
* @param[in] pointer to hold target Timestamp Low value
* \return returns 0 for Success or else Failure
*/
void synopGMAC_TS_read_target_timestamp(synopGMACdevice *gmacdev, u32 * sec_val, u32 * sub_sec_val)
{
* sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSTargetTimeHigh);
* sub_sec_val = synopGMACReadReg(gmacdev->MacBase,GmacTSTargetTimeLow);
return;
}
#endif
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
* 2020-08-10 lizhirui porting to ls2k
*/
#define UNUSED 1
#ifndef SYNOP_GMAC_DEV_H
#define SYNOP_GMAC_DEV_H 1
/*******************************************************************/
#define SYNOP_LOOPBACK_MODE 0
#define SYNOP_LOOPBACK_DEBUG 0
#define SYNOP_PHY_LOOPBACK 0
#define SYNOP_TX_TEST 0
#define SYNOP_RX_TEST 0
#define SYNOP_TOP_DEBUG 0
#define SYNOP_REG_DEBUG 0
#define SYNOP_RX_DEBUG 0
#define SYNOP_TX_DEBUG 0
#define ENH_DESC
/*******************************************************************/
#include "synopGMAC_plat.h"
#include "synopGMAC_types.h"
//sw: typedef are included in synopGMAC_plat.h
// it is strange that we should add it here again!!
/*SynopGMAC can support up to 32 phys*/
#define GMAC_PHY_BASE 1
#ifdef GMAC_PHY_BASE
#define DEFAULT_PHY_BASE GMAC_PHY_BASE
#else
#define DEFAULT_PHY_BASE PHY16 //We use First Phy
#endif
#define MACBASE 0x0000 // The Mac Base address offset is 0x0000
#define DMABASE 0x1000 // Dma base address starts with an offset 0x1000
enum GMACPhyBase
{
PHY0 = 0, //The device can support 32 phys, but we use first phy only
PHY1 = 1,
PHY16 = 16,
PHY31 = 31,
};
//#define TRANSMIT_DESC_SIZE 256 //Tx Descriptors needed in the Descriptor pool/queue
//#define RECEIVE_DESC_SIZE 256 //Rx Descriptors needed in the Descriptor pool/queue
//#define TRANSMIT_DESC_SIZE 13//256 //Tx Descriptors needed in the Descriptor pool/queue
#define TRANSMIT_DESC_SIZE 36 //48 //Tx Descriptors needed in the Descriptor pool/queue
#define RECEIVE_DESC_SIZE 36 //96 //Rx Descriptors needed in the Descriptor pool/queue
#define ETHERNET_HEADER 14 //6 byte Dest addr, 6 byte Src addr, 2 byte length/type
#define ETHERNET_CRC 4 //Ethernet CRC
#define ETHERNET_EXTRA 2 //Only God knows about this?????
#define ETHERNET_PACKET_COPY 250 // Maximum length when received data is copied on to a new skb
#define ETHERNET_PACKET_EXTRA 18 // Preallocated length for the rx packets is MTU + ETHERNET_PACKET_EXTRA
#define VLAN_TAG 4 //optional 802.1q VLAN Tag
#define MIN_ETHERNET_PAYLOAD 46 //Minimum Ethernet payload size
#define MAX_ETHERNET_PAYLOAD 1500 //Maximum Ethernet payload size
#define JUMBO_FRAME_PAYLOAD 9000 //Jumbo frame payload size
#define TX_BUF_SIZE ETHERNET_HEADER + ETHERNET_CRC + MAX_ETHERNET_PAYLOAD + VLAN_TAG + 1000
#define RX_BUF_SIZE ETHERNET_HEADER + ETHERNET_CRC + MAX_ETHERNET_PAYLOAD + VLAN_TAG + 1000
// This is the IP's phy address. This is unique address for every MAC in the universe
#define DEFAULT_MAC_ADDRESS {0x00, 0x55, 0x7B, 0xB5, 0x7D, 0xF7}
/*
DMA Descriptor Structure
The structure is common for both receive and transmit descriptors
The descriptor is of 4 words, but our structrue contains 6 words where
last two words are to hold the virtual address of the network buffer pointers
for driver's use
From the GMAC core release 3.50a onwards, the Enhanced Descriptor structure got changed.
The descriptor (both transmit and receive) are of 8 words each rather the 4 words of normal
descriptor structure.
Whenever IEEE 1588 Timestamping is enabled TX/RX DESC6 provides the lower 32 bits of Timestamp value and
TX/RX DESC7 provides the upper 32 bits of Timestamp value
In addition to this whenever extended status bit is set (RX DESC0 bit 0), RX DESC4 contains the extended status information
*/
#define MODULO_INTERRUPT 1 // if it is set to 1, interrupt is available for all the descriptors or else interrupt is available only for
// descriptor whose index%MODULO_INTERRUPT is zero
#ifdef ENH_DESC_8W
typedef struct DmaDescStruct
{
u32 status; /* Status */
u32 length; /* Buffer 1 and Buffer 2 length */
u32 buffer1; /* Network Buffer 1 pointer (Dma-able) */
u32 buffer2; /* Network Buffer 2 pointer or next descriptor pointer (Dma-able)in chain structure */
/* This data below is used only by driver */
u32 extstatus; /* Extended status of a Rx Descriptor */
u32 reserved1; /* Reserved word */
u32 timestamplow; /* Lower 32 bits of the 64 bit timestamp value */
u32 timestamphigh; /* Higher 32 bits of the 64 bit timestamp value */
u64 data1; /* This holds virtual address of buffer1, not used by DMA */
u64 data2; /* This holds virtual address of buffer2, not used by DMA */
} DmaDesc;
#else
typedef struct DmaDescStruct
{
u32 status; /* Status */
u32 length; /* Buffer 1 and Buffer 2 length */
u32 buffer1; /* Network Buffer 1 pointer (Dma-able) */
u32 buffer2; /* Network Buffer 2 pointer or next descriptor pointer (Dma-able)in chain structure */
/* This data below is used only by driver */
u64 data1; /* This holds virtual address of buffer1, not used by DMA */
u64 data2; /* This holds virtual address of buffer2, not used by DMA */
//u32 dummy1; //sw: for addr align
//u32 dummy2; //
} DmaDesc;
#endif
enum DescMode
{
RINGMODE = 0x00000001,
CHAINMODE = 0x00000002,
};
enum BufferMode
{
SINGLEBUF = 0x00000001,
DUALBUF = 0x00000002,
};
/* synopGMAC device data */
typedef struct synopGMACDeviceStruct
{
u64 MacBase; /* base address of MAC registers */
u64 DmaBase; /* base address of DMA registers */
u64 PhyBase; /* PHY device address on MII interface */
u32 Version; /* Gmac Revision version */
dma_addr_t TxDescDma; /* Dma-able address of first tx descriptor either in ring or chain mode, this is used by the GMAC device*/
dma_addr_t RxDescDma; /* Dma-able address of first rx descriptor either in ring or chain mode, this is used by the GMAC device*/
DmaDesc *TxDesc; /* start address of TX descriptors ring or chain, this is used by the driver */
DmaDesc *RxDesc; /* start address of RX descriptors ring or chain, this is used by the driver */
u32 BusyTxDesc; /* Number of Tx Descriptors owned by DMA at any given time*/
u32 BusyRxDesc; /* Number of Rx Descriptors owned by DMA at any given time*/
u32 RxDescCount; /* number of rx descriptors in the tx descriptor queue/pool */
u32 TxDescCount; /* number of tx descriptors in the rx descriptor queue/pool */
u32 TxBusy; /* index of the tx descriptor owned by DMA, is obtained by synopGMAC_get_tx_qptr() */
u32 TxNext; /* index of the tx descriptor next available with driver, given to DMA by synopGMAC_set_tx_qptr() */
u32 RxBusy; /* index of the rx descriptor owned by DMA, obtained by synopGMAC_get_rx_qptr() */
u32 RxNext; /* index of the rx descriptor next available with driver, given to DMA by synopGMAC_set_rx_qptr() */
DmaDesc * TxBusyDesc; /* Tx Descriptor address corresponding to the index TxBusy */
DmaDesc * TxNextDesc; /* Tx Descriptor address corresponding to the index TxNext */
DmaDesc * RxBusyDesc; /* Rx Descriptor address corresponding to the index TxBusy */
DmaDesc * RxNextDesc; /* Rx Descriptor address corresponding to the index RxNext */
/*Phy related stuff*/
u32 ClockDivMdc; /* Clock divider value programmed in the hardware */
/* The status of the link */
u32 LinkState0; /* Link status as reported by the Marvel Phy */
u32 LinkState; /* Link status as reported by the Marvel Phy */
u32 DuplexMode; /* Duplex mode of the Phy */
u32 Speed; /* Speed of the Phy */
u32 LoopBackMode; /* Loopback status of the Phy */
// void * FirstTxDesc;
// void * FirstRxDesc;
// u32 skb_array[RECEIVE_DESC_SIZE];
} synopGMACdevice;
/* Below is "88E1011/88E1011S Integrated 10/100/1000 Gigabit Ethernet Transceiver"
* Register and their layouts. This Phy has been used in the Dot Aster GMAC Phy daughter.
* Since the Phy register map is standard, this map hardly changes to a different Ppy
*/
enum MiiRegisters
{
PHY_CONTROL_REG = 0x0000, /*Control Register*/
PHY_STATUS_REG = 0x0001, /*Status Register */
PHY_ID_HI_REG = 0x0002, /*PHY Identifier High Register*/
PHY_ID_LOW_REG = 0x0003, /*PHY Identifier High Register*/
PHY_AN_ADV_REG = 0x0004, /*Auto-Negotiation Advertisement Register*/
PHY_LNK_PART_ABl_REG = 0x0005, /*Link Partner Ability Register (Base Page)*/
PHY_AN_EXP_REG = 0x0006, /*Auto-Negotiation Expansion Register*/
PHY_AN_NXT_PAGE_TX_REG = 0x0007, /*Next Page Transmit Register*/
PHY_LNK_PART_NXT_PAGE_REG = 0x0008, /*Link Partner Next Page Register*/
PHY_1000BT_CTRL_REG = 0x0009, /*1000BASE-T Control Register*/
PHY_1000BT_STATUS_REG = 0x000a, /*1000BASE-T Status Register*/
PHY_SPECIFIC_CTRL_REG = 0x0010, /*Phy specific control register*/
PHY_SPECIFIC_STATUS_REG = 0x0011, /*Phy specific status register*/
PHY_INTERRUPT_ENABLE_REG = 0x0012, /*Phy interrupt enable register*/
PHY_INTERRUPT_STATUS_REG = 0x0013, /*Phy interrupt status register*/
PHY_EXT_PHY_SPC_CTRL = 0x0014, /*Extended Phy specific control*/
PHY_RX_ERR_COUNTER = 0x0015, /*Receive Error Counter*/
PHY_EXT_ADDR_CBL_DIAG = 0x0016, /*Extended address for cable diagnostic register*/
PHY_LED_CONTROL = 0x0018, /*LED Control*/
PHY_MAN_LED_OVERIDE = 0x0019, /*Manual LED override register*/
PHY_EXT_PHY_SPC_CTRL2 = 0x001a, /*Extended Phy specific control 2*/
PHY_EXT_PHY_SPC_STATUS = 0x001b, /*Extended Phy specific status*/
PHY_CBL_DIAG_REG = 0x001c, /*Cable diagnostic registers*/
};
/* This is Control register layout. Control register is of 16 bit wide.
*/
enum Mii_GEN_CTRL
{ /* Description bits R/W default value */
Mii_reset = 0x8000,
Mii_Speed_10 = 0x0000, /* 10 Mbps 6:13 RW */
Mii_Speed_100 = 0x2000, /* 100 Mbps 6:13 RW */
Mii_Speed_1000 = 0x0040, /* 1000 Mbit/s 6:13 RW */
Mii_Duplex = 0x0100, /* Full Duplex mode 8 RW */
Mii_Manual_Master_Config = 0x0800, /* Manual Master Config 11 RW */
Mii_Loopback = 0x4000, /* Enable Loop back 14 RW */
Mii_NoLoopback = 0x0000, /* Enable Loop back 14 RW */
};
enum Mii_Phy_Status
{
Mii_phy_status_speed_10 = 0x0000,
Mii_phy_status_speed_100 = 0x4000,
Mii_phy_status_speed_1000 = 0x8000,
Mii_phy_status_full_duplex = 0x2000,
Mii_phy_status_half_duplex = 0x0000,
Mii_phy_status_link_up = 0x0400, //lyf:rtl 8211 phy
// Mii_phy_status_link_up = 0x0100, //sw: broadcom BCM5461 PHY
};
/* This is Status register layout. Status register is of 16 bit wide.
*/
enum Mii_GEN_STATUS
{
Mii_AutoNegCmplt = 0x0020, /* Autonegotiation completed 5 RW */
Mii_Link = 0x0004, /* Link status 2 RW */
};
enum Mii_Link_Status
{
LINKDOWN = 0,
LINKUP = 1,
};
enum Mii_Duplex_Mode
{
HALFDUPLEX = 1,
FULLDUPLEX = 2,
};
enum Mii_Link_Speed
{
SPEED10 = 1,
SPEED100 = 2,
SPEED1000 = 3,
};
enum Mii_Loop_Back
{
NOLOOPBACK = 0,
LOOPBACK = 1,
};
/**********************************************************
* GMAC registers Map
* For Pci based system address is BARx + GmacRegisterBase
* For any other system translation is done accordingly
**********************************************************/
enum GmacRegisters
{
GmacConfig = 0x0000, /* Mac config Register */
GmacFrameFilter = 0x0004, /* Mac frame filtering controls */
GmacHashHigh = 0x0008, /* Multi-cast hash table high */
GmacHashLow = 0x000C, /* Multi-cast hash table low */
GmacGmiiAddr = 0x0010, /* GMII address Register(ext. Phy) */
GmacGmiiData = 0x0014, /* GMII data Register(ext. Phy) */
GmacFlowControl = 0x0018, /* Flow control Register */
GmacVlan = 0x001C, /* VLAN tag Register (IEEE 802.1Q) */
GmacVersion = 0x0020, /* GMAC Core Version Register */
GmacWakeupAddr = 0x0028, /* GMAC wake-up frame filter adrress reg */
GmacPmtCtrlStatus = 0x002C, /* PMT control and status register */
GmacInterruptStatus = 0x0038, /* Mac Interrupt ststus register */
GmacInterruptMask = 0x003C, /* Mac Interrupt Mask register */
GmacAddr0High = 0x0040, /* Mac address0 high Register */
GmacAddr0Low = 0x0044, /* Mac address0 low Register */
GmacAddr1High = 0x0048, /* Mac address1 high Register */
GmacAddr1Low = 0x004C, /* Mac address1 low Register */
GmacAddr2High = 0x0050, /* Mac address2 high Register */
GmacAddr2Low = 0x0054, /* Mac address2 low Register */
GmacAddr3High = 0x0058, /* Mac address3 high Register */
GmacAddr3Low = 0x005C, /* Mac address3 low Register */
GmacAddr4High = 0x0060, /* Mac address4 high Register */
GmacAddr4Low = 0x0064, /* Mac address4 low Register */
GmacAddr5High = 0x0068, /* Mac address5 high Register */
GmacAddr5Low = 0x006C, /* Mac address5 low Register */
GmacAddr6High = 0x0070, /* Mac address6 high Register */
GmacAddr6Low = 0x0074, /* Mac address6 low Register */
GmacAddr7High = 0x0078, /* Mac address7 high Register */
GmacAddr7Low = 0x007C, /* Mac address7 low Register */
GmacAddr8High = 0x0080, /* Mac address8 high Register */
GmacAddr8Low = 0x0084, /* Mac address8 low Register */
GmacAddr9High = 0x0088, /* Mac address9 high Register */
GmacAddr9Low = 0x008C, /* Mac address9 low Register */
GmacAddr10High = 0x0090, /* Mac address10 high Register */
GmacAddr10Low = 0x0094, /* Mac address10 low Register */
GmacAddr11High = 0x0098, /* Mac address11 high Register */
GmacAddr11Low = 0x009C, /* Mac address11 low Register */
GmacAddr12High = 0x00A0, /* Mac address12 high Register */
GmacAddr12Low = 0x00A4, /* Mac address12 low Register */
GmacAddr13High = 0x00A8, /* Mac address13 high Register */
GmacAddr13Low = 0x00AC, /* Mac address13 low Register */
GmacAddr14High = 0x00B0, /* Mac address14 high Register */
GmacAddr14Low = 0x00B4, /* Mac address14 low Register */
GmacAddr15High = 0x00B8, /* Mac address15 high Register */
GmacAddr15Low = 0x00BC, /* Mac address15 low Register */
GmacStatus = 0x00d8, /*MAC status*/
/*Time Stamp Register Map*/
GmacTSControl = 0x0700, /* Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */
GmacTSSubSecIncr = 0x0704, /* 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */
GmacTSHigh = 0x0708, /* 32 bit seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */
GmacTSLow = 0x070C, /* 32 bit nano seconds(MS) : only when IEEE 1588 time stamping without external timestamp input */
GmacTSHighUpdate = 0x0710, /* 32 bit seconds(MS) to be written/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */
GmacTSLowUpdate = 0x0714, /* 32 bit nano seconds(MS) to be writeen/added/subtracted : only when IEEE 1588 time stamping without external timestamp input */
GmacTSAddend = 0x0718, /* Used by Software to readjust the clock frequency linearly : only when IEEE 1588 time stamping without external timestamp input */
GmacTSTargetTimeHigh = 0x071C, /* 32 bit seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */
GmacTSTargetTimeLow = 0x0720, /* 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */
GmacTSHighWord = 0x0724, /* Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */
//GmacTSHighWordUpdate = 0x072C, /* Time Stamp Higher Word Update Register (Version 2 only); only lower 16 bits are valid */
GmacTSStatus = 0x0728, /* Time Stamp Status Register */
};
/**********************************************************
* GMAC Network interface registers
* This explains the Register's Layout
* FES is Read only by default and is enabled only when Tx
* Config Parameter is enabled for RGMII/SGMII interface
* during CoreKit Config.
* DM is Read only with value 1'b1 in Full duplex only Config
**********************************************************/
/* GmacConfig = 0x0000, Mac config Register Layout */
enum GmacConfigReg
{
/* Bit description Bits R/W Reset value */
GmacWatchdog = 0x00800000,
GmacWatchdogDisable = 0x00800000, /* (WD)Disable watchdog timer on Rx 23 RW */
GmacWatchdogEnable = 0x00000000, /* Enable watchdog timer 0 */
GmacJabber = 0x00400000,
GmacJabberDisable = 0x00400000, /* (JD)Disable jabber timer on Tx 22 RW */
GmacJabberEnable = 0x00000000, /* Enable jabber timer 0 */
GmacFrameBurst = 0x00200000,
GmacFrameBurstEnable = 0x00200000, /* (BE)Enable frame bursting during Tx 21 RW */
GmacFrameBurstDisable = 0x00000000, /* Disable frame bursting 0 */
GmacJumboFrame = 0x00100000,
GmacJumboFrameEnable = 0x00100000, /* (JE)Enable jumbo frame for Tx 20 RW */
GmacJumboFrameDisable = 0x00000000, /* Disable jumbo frame 0 */
GmacInterFrameGap7 = 0x000E0000, /* (IFG) Config7 - 40 bit times 19:17 RW */
GmacInterFrameGap6 = 0x000C0000, /* (IFG) Config6 - 48 bit times */
GmacInterFrameGap5 = 0x000A0000, /* (IFG) Config5 - 56 bit times */
GmacInterFrameGap4 = 0x00080000, /* (IFG) Config4 - 64 bit times */
GmacInterFrameGap3 = 0x00040000, /* (IFG) Config3 - 72 bit times */
GmacInterFrameGap2 = 0x00020000, /* (IFG) Config2 - 80 bit times */
GmacInterFrameGap1 = 0x00010000, /* (IFG) Config1 - 88 bit times */
GmacInterFrameGap0 = 0x00000000, /* (IFG) Config0 - 96 bit times 000 */
GmacDisableCrs = 0x00010000,
GmacMiiGmii = 0x00008000,
GmacSelectMii = 0x00008000, /* (PS)Port Select-MII mode 15 RW */
GmacSelectGmii = 0x00000000, /* GMII mode 0 */
GmacFESpeed100 = 0x00004000, /*(FES)Fast Ethernet speed 100Mbps 14 RW */
GmacFESpeed10 = 0x00000000, /* 10Mbps 0 */
GmacRxOwn = 0x00002000,
GmacDisableRxOwn = 0x00002000, /* (DO)Disable receive own packets 13 RW */
GmacEnableRxOwn = 0x00000000, /* Enable receive own packets 0 */
GmacLoopback = 0x00001000,
GmacLoopbackOn = 0x00001000, /* (LM)Loopback mode for GMII/MII 12 RW */
GmacLoopbackOff = 0x00000000, /* Normal mode 0 */
GmacDuplex = 0x00000800,
GmacFullDuplex = 0x00000800, /* (DM)Full duplex mode 11 RW */
GmacHalfDuplex = 0x00000000, /* Half duplex mode 0 */
GmacRxIpcOffload = 0x00000400, /*IPC checksum offload 10 RW 0 */
GmacRetry = 0x00000200,
GmacRetryDisable = 0x00000200, /* (DR)Disable Retry 9 RW */
GmacRetryEnable = 0x00000000, /* Enable retransmission as per BL 0 */
GmacLinkUp = 0x00000100, /* (LUD)Link UP 8 RW */
GmacLinkDown = 0x00000100, /* Link Down 0 */
GmacPadCrcStrip = 0x00000080,
GmacPadCrcStripEnable = 0x00000080, /* (ACS) Automatic Pad/Crc strip enable 7 RW */
GmacPadCrcStripDisable = 0x00000000, /* Automatic Pad/Crc stripping disable 0 */
GmacBackoffLimit = 0x00000060,
GmacBackoffLimit3 = 0x00000060, /* (BL)Back-off limit in HD mode 6:5 RW */
GmacBackoffLimit2 = 0x00000040, /* */
GmacBackoffLimit1 = 0x00000020, /* */
GmacBackoffLimit0 = 0x00000000, /* 00 */
GmacDeferralCheck = 0x00000010,
GmacDeferralCheckEnable = 0x00000010, /* (DC)Deferral check enable in HD mode 4 RW */
GmacDeferralCheckDisable = 0x00000000, /* Deferral check disable 0 */
GmacTx = 0x00000008,
GmacTxEnable = 0x00000008, /* (TE)Transmitter enable 3 RW */
GmacTxDisable = 0x00000000, /* Transmitter disable 0 */
GmacRx = 0x00000004,
GmacRxEnable = 0x00000004, /* (RE)Receiver enable 2 RW */
GmacRxDisable = 0x00000000, /* Receiver disable 0 */
};
/* GmacFrameFilter = 0x0004, Mac frame filtering controls Register Layout*/
enum GmacFrameFilterReg
{
GmacFilter = 0x80000000,
GmacFilterOff = 0x80000000, /* (RA)Receive all incoming packets 31 RW */
GmacFilterOn = 0x00000000, /* Receive filtered packets only 0 */
GmacHashPerfectFilter = 0x00000400, /*Hash or Perfect Filter enable 10 RW 0 */
GmacSrcAddrFilter = 0x00000200,
GmacSrcAddrFilterEnable = 0x00000200, /* (SAF)Source Address Filter enable 9 RW */
GmacSrcAddrFilterDisable = 0x00000000, /* 0 */
GmacSrcInvaAddrFilter = 0x00000100,
GmacSrcInvAddrFilterEn = 0x00000100, /* (SAIF)Inv Src Addr Filter enable 8 RW */
GmacSrcInvAddrFilterDis = 0x00000000, /* 0 */
GmacPassControl = 0x000000C0,
GmacPassControl3 = 0x000000C0, /* (PCS)Forwards ctrl frms that pass AF 7:6 RW */
GmacPassControl2 = 0x00000080, /* Forwards all control frames */
GmacPassControl1 = 0x00000040, /* Does not pass control frames */
GmacPassControl0 = 0x00000000, /* Does not pass control frames 00 */
GmacBroadcast = 0x00000020,
GmacBroadcastDisable = 0x00000020, /* (DBF)Disable Rx of broadcast frames 5 RW */
GmacBroadcastEnable = 0x00000000, /* Enable broadcast frames 0 */
GmacMulticastFilter = 0x00000010,
GmacMulticastFilterOff = 0x00000010, /* (PM) Pass all multicast packets 4 RW */
GmacMulticastFilterOn = 0x00000000, /* Pass filtered multicast packets 0 */
GmacDestAddrFilter = 0x00000008,
GmacDestAddrFilterInv = 0x00000008, /* (DAIF)Inverse filtering for DA 3 RW */
GmacDestAddrFilterNor = 0x00000000, /* Normal filtering for DA 0 */
GmacMcastHashFilter = 0x00000004,
GmacMcastHashFilterOn = 0x00000004, /* (HMC)perfom multicast hash filtering 2 RW */
GmacMcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */
GmacUcastHashFilter = 0x00000002,
GmacUcastHashFilterOn = 0x00000002, /* (HUC)Unicast Hash filtering only 1 RW */
GmacUcastHashFilterOff = 0x00000000, /* perfect filtering only 0 */
GmacPromiscuousMode = 0x00000001,
GmacPromiscuousModeOn = 0x00000001, /* Receive all frames 0 RW */
GmacPromiscuousModeOff = 0x00000000, /* Receive filtered packets only 0 */
};
/*GmacGmiiAddr = 0x0010, GMII address Register(ext. Phy) Layout */
enum GmacGmiiAddrReg
{
GmiiDevMask = 0x0000F800, /* (PA)GMII device address 15:11 RW 0x00 */
GmiiDevShift = 11,
GmiiRegMask = 0x000007C0, /* (GR)GMII register in selected Phy 10:6 RW 0x00 */
GmiiRegShift = 6,
GmiiCsrClkMask = 0x0000001C, /*CSR Clock bit Mask 4:2 */
GmiiCsrClk5 = 0x00000014, /* (CR)CSR Clock Range 250-300 MHz 4:2 RW 000 */
GmiiCsrClk4 = 0x00000010, /* 150-250 MHz */
GmiiCsrClk3 = 0x0000000C, /* 35-60 MHz */
GmiiCsrClk2 = 0x00000008, /* 20-35 MHz */
GmiiCsrClk1 = 0x00000004, /* 100-150 MHz */
GmiiCsrClk0 = 0x00000000, /* 60-100 MHz */
GmiiWrite = 0x00000002, /* (GW)Write to register 1 RW */
GmiiRead = 0x00000000, /* Read from register 0 */
GmiiBusy = 0x00000001, /* (GB)GMII interface is busy 0 RW 0 */
};
/* GmacGmiiData = 0x0014, GMII data Register(ext. Phy) Layout */
enum GmacGmiiDataReg
{
GmiiDataMask = 0x0000FFFF, /* (GD)GMII Data 15:0 RW 0x0000 */
};
/*GmacFlowControl = 0x0018, Flow control Register Layout */
enum GmacFlowControlReg
{
GmacPauseTimeMask = 0xFFFF0000, /* (PT) PAUSE TIME field in the control frame 31:16 RW 0x0000 */
GmacPauseTimeShift = 16,
GmacPauseLowThresh = 0x00000030,
GmacPauseLowThresh3 = 0x00000030, /* (PLT)thresh for pause tmr 256 slot time 5:4 RW */
GmacPauseLowThresh2 = 0x00000020, /* 144 slot time */
GmacPauseLowThresh1 = 0x00000010, /* 28 slot time */
GmacPauseLowThresh0 = 0x00000000, /* 4 slot time 000 */
GmacUnicastPauseFrame = 0x00000008,
GmacUnicastPauseFrameOn = 0x00000008, /* (UP)Detect pause frame with unicast addr. 3 RW */
GmacUnicastPauseFrameOff = 0x00000000, /* Detect only pause frame with multicast addr. 0 */
GmacRxFlowControl = 0x00000004,
GmacRxFlowControlEnable = 0x00000004, /* (RFE)Enable Rx flow control 2 RW */
GmacRxFlowControlDisable = 0x00000000, /* Disable Rx flow control 0 */
GmacTxFlowControl = 0x00000002,
GmacTxFlowControlEnable = 0x00000002, /* (TFE)Enable Tx flow control 1 RW */
GmacTxFlowControlDisable = 0x00000000, /* Disable flow control 0 */
GmacFlowControlBackPressure= 0x00000001,
GmacSendPauseFrame = 0x00000001, /* (FCB/PBA)send pause frm/Apply back pressure 0 RW 0 */
};
/* GmacInterruptStatus = 0x0038, Mac Interrupt ststus register */
enum GmacInterruptStatusBitDefinition
{
GmacTSIntSts = 0x00000200, /* set if int generated due to TS (Read Time Stamp Status Register to know details)*/
GmacMmcRxChksumOffload = 0x00000080, /* set if int generated in MMC RX CHECKSUM OFFLOAD int register */
GmacMmcTxIntSts = 0x00000040, /* set if int generated in MMC TX Int register */
GmacMmcRxIntSts = 0x00000020, /* set if int generated in MMC RX Int register */
GmacMmcIntSts = 0x00000010, /* set if any of the above bit [7:5] is set */
GmacPmtIntSts = 0x00000008, /* set whenver magic pkt/wake-on-lan frame is received */
GmacPcsAnComplete = 0x00000004, /* set when AN is complete in TBI/RTBI/SGMIII phy interface */
GmacPcsLnkStsChange = 0x00000002, /* set if any lnk status change in TBI/RTBI/SGMII interface */
GmacRgmiiIntSts = 0x00000001, /* set if any change in lnk status of RGMII interface */
};
/* GmacInterruptMask = 0x003C, Mac Interrupt Mask register */
enum GmacInterruptMaskBitDefinition
{
GmacTSIntMask = 0x00000200, /* when set disables the time stamp interrupt generation */
GmacPmtIntMask = 0x00000008, /* when set Disables the assertion of PMT interrupt */
GmacPcsAnIntMask = 0x00000004, /* When set disables the assertion of PCS AN complete interrupt */
GmacPcsLnkStsIntMask = 0x00000002, /* when set disables the assertion of PCS lnk status change interrupt */
GmacRgmiiIntMask = 0x00000001, /* when set disables the assertion of RGMII int */
};
/**********************************************************
* GMAC DMA registers
* For Pci based system address is BARx + GmaDmaBase
* For any other system translation is done accordingly
**********************************************************/
enum DmaRegisters
{
DmaBusMode = 0x0000, /* CSR0 - Bus Mode Register */
DmaTxPollDemand = 0x0004, /* CSR1 - Transmit Poll Demand Register */
DmaRxPollDemand = 0x0008, /* CSR2 - Receive Poll Demand Register */
DmaRxBaseAddr = 0x000C, /* CSR3 - Receive Descriptor list base address */
DmaTxBaseAddr = 0x0010, /* CSR4 - Transmit Descriptor list base address */
DmaStatus = 0x0014, /* CSR5 - Dma status Register */
DmaControl = 0x0018, /* CSR6 - Dma Operation Mode Register */
DmaInterrupt = 0x001C, /* CSR7 - Interrupt enable */
DmaMissedFr = 0x0020, /* CSR8 - Missed Frame & Buffer overflow Counter */
DmaTxCurrDesc = 0x0048, /* - Current host Tx Desc Register */
DmaRxCurrDesc = 0x004C, /* - Current host Rx Desc Register */
DmaTxCurrAddr = 0x0050, /* CSR20 - Current host transmit buffer address */
DmaRxCurrAddr = 0x0054, /* CSR21 - Current host receive buffer address */
};
/**********************************************************
* DMA Engine registers Layout
**********************************************************/
/*DmaBusMode = 0x0000, CSR0 - Bus Mode */
enum DmaBusModeReg
{ /* Bit description Bits R/W Reset value */
DmaFixedBurstEnable = 0x00010000, /* (FB)Fixed Burst SINGLE, INCR4, INCR8 or INCR16 16 RW */
DmaFixedBurstDisable = 0x00000000, /* SINGLE, INCR 0 */
DmaTxPriorityRatio11 = 0x00000000, /* (PR)TX:RX DMA priority ratio 1:1 15:14 RW 00 */
DmaTxPriorityRatio21 = 0x00004000, /* (PR)TX:RX DMA priority ratio 2:1 */
DmaTxPriorityRatio31 = 0x00008000, /* (PR)TX:RX DMA priority ratio 3:1 */
DmaTxPriorityRatio41 = 0x0000C000, /* (PR)TX:RX DMA priority ratio 4:1 */
DmaBurstLengthx8 = 0x01000000, /* When set mutiplies the PBL by 8 24 RW 0 */
DmaBurstLength256 = 0x01002000, /*(DmaBurstLengthx8 | DmaBurstLength32) = 256 [24]:13:8 */
DmaBurstLength128 = 0x01001000, /*(DmaBurstLengthx8 | DmaBurstLength16) = 128 [24]:13:8 */
DmaBurstLength64 = 0x01000800, /*(DmaBurstLengthx8 | DmaBurstLength8) = 64 [24]:13:8 */
DmaBurstLength32 = 0x00002000, /* (PBL) programmable Dma burst length = 32 13:8 RW */
DmaBurstLength16 = 0x00001000, /* Dma burst length = 16 */
DmaBurstLength8 = 0x00000800, /* Dma burst length = 8 */
DmaBurstLength4 = 0x00000400, /* Dma burst length = 4 */
DmaBurstLength2 = 0x00000200, /* Dma burst length = 2 */
DmaBurstLength1 = 0x00000100, /* Dma burst length = 1 */
DmaBurstLength0 = 0x00000000, /* Dma burst length = 0 0x00 */
DmaDescriptor8Words = 0x00000080, /* Enh Descriptor works 1=> 8 word descriptor 7 0 */
DmaDescriptor4Words = 0x00000000, /* Enh Descriptor works 0=> 4 word descriptor 7 0 */
DmaDescriptorSkip16 = 0x00000040, /* (DSL)Descriptor skip length (no.of dwords) 6:2 RW */
DmaDescriptorSkip8 = 0x00000020, /* between two unchained descriptors */
DmaDescriptorSkip4 = 0x00000010, /* */
DmaDescriptorSkip2 = 0x00000008, /* */
DmaDescriptorSkip1 = 0x00000004, /* */
DmaDescriptorSkip0 = 0x00000000, /* 0x00 */
DmaArbitRr = 0x00000000, /* (DA) DMA RR arbitration 1 RW 0 */
DmaArbitPr = 0x00000002, /* Rx has priority over Tx */
DmaResetOn = 0x00000001, /* (SWR)Software Reset DMA engine 0 RW */
DmaResetOff = 0x00000000, /* 0 */
};
/*DmaStatus = 0x0014, CSR5 - Dma status Register */
enum DmaStatusReg
{
/*Bit 28 27 and 26 indicate whether the interrupt due to PMT GMACMMC or GMAC LINE Remaining bits are DMA interrupts*/
GmacPmtIntr = 0x10000000, /* (GPI)Gmac subsystem interrupt 28 RO 0 */
GmacMmcIntr = 0x08000000, /* (GMI)Gmac MMC subsystem interrupt 27 RO 0 */
GmacLineIntfIntr = 0x04000000, /* Line interface interrupt 26 RO 0 */
DmaErrorBit2 = 0x02000000, /* (EB)Error bits 0-data buffer, 1-desc. access 25 RO 0 */
DmaErrorBit1 = 0x01000000, /* (EB)Error bits 0-write trnsf, 1-read transfr 24 RO 0 */
DmaErrorBit0 = 0x00800000, /* (EB)Error bits 0-Rx DMA, 1-Tx DMA 23 RO 0 */
DmaTxState = 0x00700000, /* (TS)Transmit process state 22:20 RO */
DmaTxStopped = 0x00000000, /* Stopped - Reset or Stop Tx Command issued 000 */
DmaTxFetching = 0x00100000, /* Running - fetching the Tx descriptor */
DmaTxWaiting = 0x00200000, /* Running - waiting for status */
DmaTxReading = 0x00300000, /* Running - reading the data from host memory */
DmaTxSuspended = 0x00600000, /* Suspended - Tx Descriptor unavailabe */
DmaTxClosing = 0x00700000, /* Running - closing Rx descriptor */
DmaRxState = 0x000E0000, /* (RS)Receive process state 19:17 RO */
DmaRxStopped = 0x00000000, /* Stopped - Reset or Stop Rx Command issued 000 */
DmaRxFetching = 0x00020000, /* Running - fetching the Rx descriptor */
DmaRxWaiting = 0x00060000, /* Running - waiting for packet */
DmaRxSuspended = 0x00080000, /* Suspended - Rx Descriptor unavailable */
DmaRxClosing = 0x000A0000, /* Running - closing descriptor */
DmaRxQueuing = 0x000E0000, /* Running - queuing the recieve frame into host memory */
DmaIntNormal = 0x00010000, /* (NIS)Normal interrupt summary 16 RW 0 */
DmaIntAbnormal = 0x00008000, /* (AIS)Abnormal interrupt summary 15 RW 0 */
DmaIntEarlyRx = 0x00004000, /* Early receive interrupt (Normal) RW 0 */
DmaIntBusError = 0x00002000, /* Fatal bus error (Abnormal) RW 0 */
DmaIntEarlyTx = 0x00000400, /* Early transmit interrupt (Abnormal) RW 0 */
DmaIntRxWdogTO = 0x00000200, /* Receive Watchdog Timeout (Abnormal) RW 0 */
DmaIntRxStopped = 0x00000100, /* Receive process stopped (Abnormal) RW 0 */
DmaIntRxNoBuffer = 0x00000080, /* Receive buffer unavailable (Abnormal) RW 0 */
DmaIntRxCompleted = 0x00000040, /* Completion of frame reception (Normal) RW 0 */
DmaIntTxUnderflow = 0x00000020, /* Transmit underflow (Abnormal) RW 0 */
DmaIntRcvOverflow = 0x00000010, /* Receive Buffer overflow interrupt RW 0 */
DmaIntTxJabberTO = 0x00000008, /* Transmit Jabber Timeout (Abnormal) RW 0 */
DmaIntTxNoBuffer = 0x00000004, /* Transmit buffer unavailable (Normal) RW 0 */
DmaIntTxStopped = 0x00000002, /* Transmit process stopped (Abnormal) RW 0 */
DmaIntTxCompleted = 0x00000001, /* Transmit completed (Normal) RW 0 */
};
/*DmaControl = 0x0018, CSR6 - Dma Operation Mode Register */
enum DmaControlReg
{
DmaDisableDropTcpCs = 0x04000000, /* (DT) Dis. drop. of tcp/ip CS error frames 26 RW 0 */
DmaStoreAndForward = 0x02200000, /* (SF)Store and forward 21 RW 0 */
DmaFlushTxFifo = 0x00100000, /* (FTF)Tx FIFO controller is reset to default 20 RW 0 */
DmaTxThreshCtrl = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16:14 RW */
DmaTxThreshCtrl16 = 0x0001C000, /* (TTC)Controls thre Threh of MTL tx Fifo 16 16:14 RW */
DmaTxThreshCtrl24 = 0x00018000, /* (TTC)Controls thre Threh of MTL tx Fifo 24 16:14 RW */
DmaTxThreshCtrl32 = 0x00014000, /* (TTC)Controls thre Threh of MTL tx Fifo 32 16:14 RW */
DmaTxThreshCtrl40 = 0x00010000, /* (TTC)Controls thre Threh of MTL tx Fifo 40 16:14 RW */
DmaTxThreshCtrl256 = 0x0000c000, /* (TTC)Controls thre Threh of MTL tx Fifo 256 16:14 RW */
DmaTxThreshCtrl192 = 0x00008000, /* (TTC)Controls thre Threh of MTL tx Fifo 192 16:14 RW */
DmaTxThreshCtrl128 = 0x00004000, /* (TTC)Controls thre Threh of MTL tx Fifo 128 16:14 RW */
DmaTxThreshCtrl64 = 0x00000000, /* (TTC)Controls thre Threh of MTL tx Fifo 64 16:14 RW 000 */
DmaTxStart = 0x00002000, /* (ST)Start/Stop transmission 13 RW 0 */
DmaRxFlowCtrlDeact = 0x00401800, /* (RFD)Rx flow control deact. threhold [22]:12:11 RW */
DmaRxFlowCtrlDeact1K = 0x00000000, /* (RFD)Rx flow control deact. threhold (1kbytes) [22]:12:11 RW 00 */
DmaRxFlowCtrlDeact2K = 0x00000800, /* (RFD)Rx flow control deact. threhold (2kbytes) [22]:12:11 RW */
DmaRxFlowCtrlDeact3K = 0x00001000, /* (RFD)Rx flow control deact. threhold (3kbytes) [22]:12:11 RW */
DmaRxFlowCtrlDeact4K = 0x00001800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */
DmaRxFlowCtrlDeact5K = 0x00400000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */
DmaRxFlowCtrlDeact6K = 0x00400800, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */
DmaRxFlowCtrlDeact7K = 0x00401000, /* (RFD)Rx flow control deact. threhold (4kbytes) [22]:12:11 RW */
DmaRxFlowCtrlAct = 0x00800600, /* (RFA)Rx flow control Act. threhold [23]:10:09 RW */
DmaRxFlowCtrlAct1K = 0x00000000, /* (RFA)Rx flow control Act. threhold (1kbytes) [23]:10:09 RW 00 */
DmaRxFlowCtrlAct2K = 0x00000200, /* (RFA)Rx flow control Act. threhold (2kbytes) [23]:10:09 RW */
DmaRxFlowCtrlAct3K = 0x00000400, /* (RFA)Rx flow control Act. threhold (3kbytes) [23]:10:09 RW */
DmaRxFlowCtrlAct4K = 0x00000600, /* (RFA)Rx flow control Act. threhold (4kbytes) [23]:10:09 RW */
DmaRxFlowCtrlAct5K = 0x00800000, /* (RFA)Rx flow control Act. threhold (5kbytes) [23]:10:09 RW */
DmaRxFlowCtrlAct6K = 0x00800200, /* (RFA)Rx flow control Act. threhold (6kbytes) [23]:10:09 RW */
DmaRxFlowCtrlAct7K = 0x00800400, /* (RFA)Rx flow control Act. threhold (7kbytes) [23]:10:09 RW */
DmaRxThreshCtrl = 0x00000018, /* (RTC)Controls thre Threh of MTL rx Fifo 4:3 RW */
DmaRxThreshCtrl64 = 0x00000000, /* (RTC)Controls thre Threh of MTL tx Fifo 64 4:3 RW */
DmaRxThreshCtrl32 = 0x00000008, /* (RTC)Controls thre Threh of MTL tx Fifo 32 4:3 RW */
DmaRxThreshCtrl96 = 0x00000010, /* (RTC)Controls thre Threh of MTL tx Fifo 96 4:3 RW */
DmaRxThreshCtrl128 = 0x00000018, /* (RTC)Controls thre Threh of MTL tx Fifo 128 4:3 RW */
DmaEnHwFlowCtrl = 0x00000100, /* (EFC)Enable HW flow control 8 RW */
DmaDisHwFlowCtrl = 0x00000000, /* Disable HW flow control 0 */
DmaFwdErrorFrames = 0x00000080, /* (FEF)Forward error frames 7 RW 0 */
DmaFwdUnderSzFrames = 0x00000040, /* (FUF)Forward undersize frames 6 RW 0 */
DmaTxSecondFrame = 0x00000004, /* (OSF)Operate on second frame 4 RW 0 */
DmaRxStart = 0x00000002, /* (SR)Start/Stop reception 1 RW 0 */
};
/*DmaInterrupt = 0x001C, CSR7 - Interrupt enable Register Layout */
enum DmaInterruptReg
{
DmaIeNormal = DmaIntNormal , /* Normal interrupt enable RW 0 */
DmaIeAbnormal = DmaIntAbnormal , /* Abnormal interrupt enable RW 0 */
DmaIeEarlyRx = DmaIntEarlyRx , /* Early receive interrupt enable RW 0 */
DmaIeBusError = DmaIntBusError , /* Fatal bus error enable RW 0 */
DmaIeEarlyTx = DmaIntEarlyTx , /* Early transmit interrupt enable RW 0 */
DmaIeRxWdogTO = DmaIntRxWdogTO , /* Receive Watchdog Timeout enable RW 0 */
DmaIeRxStopped = DmaIntRxStopped , /* Receive process stopped enable RW 0 */
DmaIeRxNoBuffer = DmaIntRxNoBuffer , /* Receive buffer unavailable enable RW 0 */
DmaIeRxCompleted = DmaIntRxCompleted, /* Completion of frame reception enable RW 0 */
DmaIeTxUnderflow = DmaIntTxUnderflow, /* Transmit underflow enable RW 0 */
DmaIeRxOverflow = DmaIntRcvOverflow, /* Receive Buffer overflow interrupt RW 0 */
DmaIeTxJabberTO = DmaIntTxJabberTO , /* Transmit Jabber Timeout enable RW 0 */
DmaIeTxNoBuffer = DmaIntTxNoBuffer , /* Transmit buffer unavailable enable RW 0 */
DmaIeTxStopped = DmaIntTxStopped , /* Transmit process stopped enable RW 0 */
DmaIeTxCompleted = DmaIntTxCompleted, /* Transmit completed enable RW 0 */
};
/**********************************************************
* DMA Engine descriptors
**********************************************************/
#ifdef ENH_DESC
/*
**********Enhanced Descritpor structure to support 8K buffer per buffer ****************************
DmaRxBaseAddr = 0x000C, CSR3 - Receive Descriptor list base address
DmaRxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a
32 bit Data bus is as shown below
Similarly
DmaTxBaseAddr = 0x0010, CSR4 - Transmit Descriptor list base address
DmaTxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a
32 bit Data bus is as shown below
--------------------------------------------------------------------------
RDES0 |OWN (31)| Status |
--------------------------------------------------------------------------
RDES1 | Ctrl | Res | Byte Count Buffer 2 | Ctrl | Res | Byte Count Buffer 1 |
--------------------------------------------------------------------------
RDES2 | Buffer 1 Address |
--------------------------------------------------------------------------
RDES3 | Buffer 2 Address / Next Descriptor Address |
--------------------------------------------------------------------------
--------------------------------------------------------------------------
TDES0 |OWN (31)| Ctrl | Res | Ctrl | Res | Status |
--------------------------------------------------------------------------
TDES1 | Res | Byte Count Buffer 2 | Res | Byte Count Buffer 1 |
--------------------------------------------------------------------------
TDES2 | Buffer 1 Address |
--------------------------------------------------------------------------
TDES3 | Buffer 2 Address / Next Descriptor Address |
--------------------------------------------------------------------------
*/
enum DmaDescriptorStatus /* status word of DMA descriptor */
{
DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 RW */
DescDAFilterFail = 0x40000000, /* (AFM)Rx - DA Filter Fail for the rx frame 30 */
DescFrameLengthMask = 0x3FFF0000, /* (FL)Receive descriptor frame length 29:16 */
DescFrameLengthShift = 16,
DescError = 0x00008000, /* (ES)Error summary bit - OR of the follo. bits: 15 */
/* DE || OE || IPC || LC || RWT || RE || CE */
DescRxTruncated = 0x00004000, /* (DE)Rx - no more descriptors for receive frame 14 */
DescSAFilterFail = 0x00002000, /* (SAF)Rx - SA Filter Fail for the received frame 13 */
DescRxLengthError = 0x00001000, /* (LE)Rx - frm size not matching with len field 12 */
DescRxDamaged = 0x00000800, /* (OE)Rx - frm was damaged due to buffer overflow 11 */
DescRxVLANTag = 0x00000400, /* (VLAN)Rx - received frame is a VLAN frame 10 */
DescRxFirst = 0x00000200, /* (FS)Rx - first descriptor of the frame 9 */
DescRxLast = 0x00000100, /* (LS)Rx - last descriptor of the frame 8 */
DescRxLongFrame = 0x00000080, /* (Giant Frame)Rx - frame is longer than 1518/1522 7 */
DescRxCollision = 0x00000040, /* (LC)Rx - late collision occurred during reception 6 */
DescRxFrameEther = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
DescRxWatchdog = 0x00000010, /* (RWT)Rx - watchdog timer expired during reception 4 */
DescRxMiiError = 0x00000008, /* (RE)Rx - error reported by MII interface 3 */
DescRxDribbling = 0x00000004, /* (DE)Rx - frame contains non int multiple of 8 bits 2 */
DescRxCrc = 0x00000002, /* (CE)Rx - CRC error 1 */
// DescRxMacMatch = 0x00000001, /* (RX MAC Address) Rx mac address reg(1 to 15)match 0 */
DescRxEXTsts = 0x00000001, /* Extended Status Available (RDES4) 0 */
DescTxIntEnable = 0x40000000, /* (IC)Tx - interrupt on completion 30 */
DescTxLast = 0x20000000, /* (LS)Tx - Last segment of the frame 29 */
DescTxFirst = 0x10000000, /* (FS)Tx - First segment of the frame 28 */
DescTxDisableCrc = 0x08000000, /* (DC)Tx - Add CRC disabled (first segment only) 27 */
DescTxDisablePadd = 0x04000000, /* (DP)disable padding, added by - reyaz 26 */
DescTxCisMask = 0x00c00000, /* Tx checksum offloading control mask 23:22 */
DescTxCisBypass = 0x00000000, /* Checksum bypass */
DescTxCisIpv4HdrCs = 0x00400000, /* IPv4 header checksum */
DescTxCisTcpOnlyCs = 0x00800000, /* TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present */
DescTxCisTcpPseudoCs = 0x00c00000, /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */
TxDescEndOfRing = 0x00200000, /* (TER)End of descriptors ring 21 */
TxDescChain = 0x00100000, /* (TCH)Second buffer address is chain address 20 */
DescRxChkBit0 = 0x00000001, /*() Rx - Rx Payload Checksum Error 0 */
DescRxChkBit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */
DescRxChkBit5 = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
DescRxTSavail = 0x00000080, /* Time stamp available 7 */
DescRxFrameType = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
DescTxIpv4ChkError = 0x00010000, /* (IHE) Tx Ip header error 16 */
DescTxTimeout = 0x00004000, /* (JT)Tx - Transmit jabber timeout 14 */
DescTxFrameFlushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed the frame due to SW flush 13 */
DescTxPayChkError = 0x00001000, /* (PCE) Tx Payload checksum Error 12 */
DescTxLostCarrier = 0x00000800, /* (LC)Tx - carrier lost during tramsmission 11 */
DescTxNoCarrier = 0x00000400, /* (NC)Tx - no carrier signal from the tranceiver 10 */
DescTxLateCollision = 0x00000200, /* (LC)Tx - transmission aborted due to collision 9 */
DescTxExcCollisions = 0x00000100, /* (EC)Tx - transmission aborted after 16 collisions 8 */
DescTxVLANFrame = 0x00000080, /* (VF)Tx - VLAN-type frame 7 */
DescTxCollMask = 0x00000078, /* (CC)Tx - Collision count 6:3 */
DescTxCollShift = 3,
DescTxExcDeferral = 0x00000004, /* (ED)Tx - excessive deferral 2 */
DescTxUnderflow = 0x00000002, /* (UF)Tx - late data arrival from the memory 1 */
DescTxDeferred = 0x00000001, /* (DB)Tx - frame transmision deferred 0 */
/*
This explains the RDES1/TDES1 bits layout
--------------------------------------------------------------------
RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 |
--------------------------------------------------------------------
*/
// DmaDescriptorLength length word of DMA descriptor
RxDisIntCompl = 0x80000000, /* (Disable Rx int on completion) 31 */
RxDescEndOfRing = 0x00008000, /* (TER)End of descriptors ring 15 */
RxDescChain = 0x00004000, /* (TCH)Second buffer address is chain address 14 */
DescSize2Mask = 0x1FFF0000, /* (TBS2) Buffer 2 size 28:16 */
DescSize2Shift = 16,
DescSize1Mask = 0x00001FFF, /* (TBS1) Buffer 1 size 12:0 */
DescSize1Shift = 0,
/*
This explains the RDES4 Extended Status bits layout
--------------------------------------------------------------------
RDES4 | Extended Status |
--------------------------------------------------------------------
*/
DescRxPtpAvail = 0x00004000, /* PTP snapshot available 14 */
DescRxPtpVer = 0x00002000, /* When set indicates IEEE1584 Version 2 (else Ver1) 13 */
DescRxPtpFrameType = 0x00001000, /* PTP frame type Indicates PTP sent over ethernet 12 */
DescRxPtpMessageType = 0x00000F00, /* Message Type 11:8 */
DescRxPtpNo = 0x00000000, /* 0000 => No PTP message received */
DescRxPtpSync = 0x00000100, /* 0001 => Sync (all clock types) received */
DescRxPtpFollowUp = 0x00000200, /* 0010 => Follow_Up (all clock types) received */
DescRxPtpDelayReq = 0x00000300, /* 0011 => Delay_Req (all clock types) received */
DescRxPtpDelayResp = 0x00000400, /* 0100 => Delay_Resp (all clock types) received */
DescRxPtpPdelayReq = 0x00000500, /* 0101 => Pdelay_Req (in P to P tras clk) or Announce in Ord and Bound clk */
DescRxPtpPdelayResp = 0x00000600, /* 0110 => Pdealy_Resp(in P to P trans clk) or Management in Ord and Bound clk */
DescRxPtpPdelayRespFP = 0x00000700, /* 0111 => Pdealy_Resp_Follow_Up (in P to P trans clk) or Signaling in Ord and Bound clk */
DescRxPtpIPV6 = 0x00000080, /* Received Packet is in IPV6 Packet 7 */
DescRxPtpIPV4 = 0x00000040, /* Received Packet is in IPV4 Packet 6 */
DescRxChkSumBypass = 0x00000020, /* When set indicates checksum offload engine 5
is bypassed */
DescRxIpPayloadError = 0x00000010, /* When set indicates 16bit IP payload CS is in error 4 */
DescRxIpHeaderError = 0x00000008, /* When set indicates 16bit IPV4 header CS is in 3
error or IP datagram version is not consistent
with Ethernet type value */
DescRxIpPayloadType = 0x00000007, /* Indicate the type of payload encapsulated 2:0
in IPdatagram processed by COE (Rx) */
DescRxIpPayloadUnknown= 0x00000000, /* Unknown or didnot process IP payload */
DescRxIpPayloadUDP = 0x00000001, /* UDP */
DescRxIpPayloadTCP = 0x00000002, /* TCP */
DescRxIpPayloadICMP = 0x00000003, /* ICMP */
};
#else
/*
********** Default Descritpor structure ****************************
DmaRxBaseAddr = 0x000C, CSR3 - Receive Descriptor list base address
DmaRxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a
32 bit Data bus is as shown below
Similarly
DmaTxBaseAddr = 0x0010, CSR4 - Transmit Descriptor list base address
DmaTxBaseAddr is the pointer to the first Rx Descriptors. the Descriptor format in Little endian with a
32 bit Data bus is as shown below
--------------------------------------------------------------------
RDES0/TDES0 |OWN (31)| Status |
--------------------------------------------------------------------
RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 |
--------------------------------------------------------------------
RDES2/TDES2 | Buffer 1 Address |
--------------------------------------------------------------------
RDES3/TDES3 | Buffer 2 Address / Next Descriptor Address |
--------------------------------------------------------------------
*/
enum DmaDescriptorStatus /* status word of DMA descriptor */
{
DescOwnByDma = 0x80000000, /* (OWN)Descriptor is owned by DMA engine 31 RW */
DescDAFilterFail = 0x40000000, /* (AFM)Rx - DA Filter Fail for the rx frame 30 */
DescFrameLengthMask = 0x3FFF0000, /* (FL)Receive descriptor frame length 29:16 */
DescFrameLengthShift = 16,
DescError = 0x00008000, /* (ES)Error summary bit - OR of the follo. bits: 15 */
/* DE || OE || IPC || LC || RWT || RE || CE */
DescRxTruncated = 0x00004000, /* (DE)Rx - no more descriptors for receive frame 14 */
DescSAFilterFail = 0x00002000, /* (SAF)Rx - SA Filter Fail for the received frame 13 */
DescRxLengthError = 0x00001000, /* (LE)Rx - frm size not matching with len field 12 */
DescRxDamaged = 0x00000800, /* (OE)Rx - frm was damaged due to buffer overflow 11 */
DescRxVLANTag = 0x00000400, /* (VLAN)Rx - received frame is a VLAN frame 10 */
DescRxFirst = 0x00000200, /* (FS)Rx - first descriptor of the frame 9 */
DescRxLast = 0x00000100, /* (LS)Rx - last descriptor of the frame 8 */
DescRxLongFrame = 0x00000080, /* (Giant Frame)Rx - frame is longer than 1518/1522 7 */
DescRxCollision = 0x00000040, /* (LC)Rx - late collision occurred during reception 6 */
DescRxFrameEther = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
DescRxWatchdog = 0x00000010, /* (RWT)Rx - watchdog timer expired during reception 4 */
DescRxMiiError = 0x00000008, /* (RE)Rx - error reported by MII interface 3 */
DescRxDribbling = 0x00000004, /* (DE)Rx - frame contains non int multiple of 8 bits 2 */
DescRxCrc = 0x00000002, /* (CE)Rx - CRC error 1 */
DescRxMacMatch = 0x00000001, /* (RX MAC Address) Rx mac address reg(1 to 15)match 0 */
//Rx Descriptor Checksum Offload engine (type 2) encoding
//DescRxPayChkError = 0x00000001, /* () Rx - Rx Payload Checksum Error 0 */
//DescRxIpv4ChkError = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */
DescRxChkBit0 = 0x00000001, /*() Rx - Rx Payload Checksum Error 0 */
DescRxChkBit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 header checksum error 7 */
DescRxChkBit5 = 0x00000020, /* (FT)Rx - Frame type - Ethernet, otherwise 802.3 5 */
DescTxIpv4ChkError = 0x00010000, /* (IHE) Tx Ip header error 16 */
DescTxTimeout = 0x00004000, /* (JT)Tx - Transmit jabber timeout 14 */
DescTxFrameFlushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed the frame due to SW flush 13 */
DescTxPayChkError = 0x00001000, /* (PCE) Tx Payload checksum Error 12 */
DescTxLostCarrier = 0x00000800, /* (LC)Tx - carrier lost during tramsmission 11 */
DescTxNoCarrier = 0x00000400, /* (NC)Tx - no carrier signal from the tranceiver 10 */
DescTxLateCollision = 0x00000200, /* (LC)Tx - transmission aborted due to collision 9 */
DescTxExcCollisions = 0x00000100, /* (EC)Tx - transmission aborted after 16 collisions 8 */
DescTxVLANFrame = 0x00000080, /* (VF)Tx - VLAN-type frame 7 */
DescTxCollMask = 0x00000078, /* (CC)Tx - Collision count 6:3 */
DescTxCollShift = 3,
DescTxExcDeferral = 0x00000004, /* (ED)Tx - excessive deferral 2 */
DescTxUnderflow = 0x00000002, /* (UF)Tx - late data arrival from the memory 1 */
DescTxDeferred = 0x00000001, /* (DB)Tx - frame transmision deferred 0 */
/*
This explains the RDES1/TDES1 bits layout
--------------------------------------------------------------------
RDES1/TDES1 | Control Bits | Byte Count Buffer 2 | Byte Count Buffer 1 |
--------------------------------------------------------------------
*/
//DmaDescriptorLength length word of DMA descriptor
DescTxIntEnable = 0x80000000, /* (IC)Tx - interrupt on completion 31 */
DescTxLast = 0x40000000, /* (LS)Tx - Last segment of the frame 30 */
DescTxFirst = 0x20000000, /* (FS)Tx - First segment of the frame 29 */
DescTxDisableCrc = 0x04000000, /* (DC)Tx - Add CRC disabled (first segment only) 26 */
RxDisIntCompl = 0x80000000, /* (Disable Rx int on completion) 31 */
RxDescEndOfRing = 0x02000000, /* (TER)End of descriptors ring */
RxDescChain = 0x01000000, /* (TCH)Second buffer address is chain address 24 */
DescTxDisablePadd = 0x00800000, /* (DP)disable padding, added by - reyaz 23 */
TxDescEndOfRing = 0x02000000, /* (TER)End of descriptors ring */
TxDescChain = 0x01000000, /* (TCH)Second buffer address is chain address 24 */
DescSize2Mask = 0x003FF800, /* (TBS2) Buffer 2 size 21:11 */
DescSize2Shift = 11,
DescSize1Mask = 0x000007FF, /* (TBS1) Buffer 1 size 10:0 */
DescSize1Shift = 0,
DescTxCisMask = 0x18000000, /* Tx checksum offloading control mask 28:27 */
DescTxCisBypass = 0x00000000, /* Checksum bypass */
DescTxCisIpv4HdrCs = 0x08000000, /* IPv4 header checksum */
DescTxCisTcpOnlyCs = 0x10000000, /* TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present */
DescTxCisTcpPseudoCs = 0x18000000, /* TCP/UDP/ICMP checksum fully in hardware including pseudo header */
};
#endif
// Rx Descriptor COE type2 encoding
enum RxDescCOEEncode
{
RxLenLT600 = 0, /* Bit(5:7:0)=>0 IEEE 802.3 type frame Length field is Lessthan 0x0600 */
RxIpHdrPayLoadChkBypass = 1, /* Bit(5:7:0)=>1 Payload & Ip header checksum bypassed (unsuppported payload) */
RxIpHdrPayLoadRes = 2, /* Bit(5:7:0)=>2 Reserved */
RxChkBypass = 3, /* Bit(5:7:0)=>3 Neither IPv4 nor IPV6. So checksum bypassed */
RxNoChkError = 4, /* Bit(5:7:0)=>4 No IPv4/IPv6 Checksum error detected */
RxPayLoadChkError = 5, /* Bit(5:7:0)=>5 Payload checksum error detected for Ipv4/Ipv6 frames */
RxIpHdrChkError = 6, /* Bit(5:7:0)=>6 Ip header checksum error detected for Ipv4 frames */
RxIpHdrPayLoadChkError = 7, /* Bit(5:7:0)=>7 Payload & Ip header checksum error detected for Ipv4/Ipv6 frames */
};
/**********************************************************
* DMA engine interrupt handling functions
**********************************************************/
enum synopGMACDmaIntEnum /* Intrerrupt types */
{
synopGMACDmaRxNormal = 0x01, /* normal receiver interrupt */
synopGMACDmaRxAbnormal = 0x02, /* abnormal receiver interrupt */
synopGMACDmaRxStopped = 0x04, /* receiver stopped */
synopGMACDmaTxNormal = 0x08, /* normal transmitter interrupt */
synopGMACDmaTxAbnormal = 0x10, /* abnormal transmitter interrupt */
synopGMACDmaTxStopped = 0x20, /* transmitter stopped */
synopGMACDmaError = 0x80, /* Dma engine error */
};
/**********************************************************
* Initial register values
**********************************************************/
enum InitialRegisters
{
/* Full-duplex mode with perfect filter on */
GmacConfigInitFdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable
| GmacSelectGmii | GmacEnableRxOwn | GmacLoopbackOff
| GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable
| GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable,
/* Full-duplex mode with perfect filter on */
GmacConfigInitFdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable
| GmacSelectMii | GmacEnableRxOwn | GmacLoopbackOff
| GmacFullDuplex | GmacRetryEnable | GmacPadCrcStripDisable
| GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable,
/* Full-duplex mode */
// CHANGED: Pass control config, dest addr filter normal, added source address filter, multicast & unicast
// Hash filter.
/* = GmacFilterOff | GmacPassControlOff | GmacBroadcastEnable */
GmacFrameFilterInitFdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable
| GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff
| GmacPromiscuousModeOff | GmacUcastHashFilterOff,
/* Full-duplex mode */
GmacFlowControlInitFdx = GmacUnicastPauseFrameOff | GmacRxFlowControlEnable | GmacTxFlowControlEnable,
/* Full-duplex mode */
GmacGmiiAddrInitFdx = GmiiCsrClk2,
/* Half-duplex mode with perfect filter on */
// CHANGED: Removed Endian configuration, added single bit config for PAD/CRC strip,
/*| GmacSelectMii | GmacLittleEndian | GmacDisableRxOwn | GmacLoopbackOff*/
GmacConfigInitHdx1000 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable
| GmacSelectGmii | GmacDisableRxOwn | GmacLoopbackOff
| GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable
| GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable,
/* Half-duplex mode with perfect filter on */
GmacConfigInitHdx110 = GmacWatchdogEnable | GmacJabberEnable | GmacFrameBurstEnable | GmacJumboFrameDisable
| GmacSelectMii | GmacDisableRxOwn | GmacLoopbackOff
| GmacHalfDuplex | GmacRetryEnable | GmacPadCrcStripDisable
| GmacBackoffLimit0 | GmacDeferralCheckDisable | GmacTxEnable | GmacRxEnable,
/* Half-duplex mode */
GmacFrameFilterInitHdx = GmacFilterOn | GmacPassControl0 | GmacBroadcastEnable | GmacSrcAddrFilterDisable
| GmacMulticastFilterOn | GmacDestAddrFilterNor | GmacMcastHashFilterOff
| GmacUcastHashFilterOff| GmacPromiscuousModeOff,
/* Half-duplex mode */
GmacFlowControlInitHdx = GmacUnicastPauseFrameOff | GmacRxFlowControlDisable | GmacTxFlowControlDisable,
/* Half-duplex mode */
GmacGmiiAddrInitHdx = GmiiCsrClk2,
/**********************************************
*DMA configurations
**********************************************/
DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip1 | DmaResetOff,
// DmaBusModeInit = DmaFixedBurstEnable | DmaBurstLength8 | DmaDescriptorSkip4 | DmaResetOff,
/* 1000 Mb/s mode */
DmaControlInit1000 = DmaStoreAndForward,// | DmaTxSecondFrame ,
/* 100 Mb/s mode */
DmaControlInit100 = DmaStoreAndForward,
/* 10 Mb/s mode */
DmaControlInit10 = DmaStoreAndForward,
/* Interrupt groups */
DmaIntErrorMask = DmaIntBusError, /* Error */
DmaIntRxAbnMask = DmaIntRxNoBuffer, /* receiver abnormal interrupt */
DmaIntRxNormMask = DmaIntRxCompleted, /* receiver normal interrupt */
DmaIntRxStoppedMask = DmaIntRxStopped, /* receiver stopped */
DmaIntTxAbnMask = DmaIntTxUnderflow, /* transmitter abnormal interrupt */
DmaIntTxNormMask = DmaIntTxCompleted, /* transmitter normal interrupt */
DmaIntTxStoppedMask = DmaIntTxStopped, /* transmitter stopped */
DmaIntEnable = DmaIeNormal | DmaIeAbnormal | DmaIntErrorMask
//DmaIntEnable = DmaIeNormal | DmaIntErrorMask
| DmaIntRxAbnMask | DmaIntRxNormMask | DmaIntRxStoppedMask
// | DmaIntRxNormMask | DmaIntRxStoppedMask
| DmaIntTxAbnMask | DmaIntTxNormMask | DmaIntTxStoppedMask,
DmaIntDisable = 0,
};
/**********************************************************
* Mac Management Counters (MMC)
**********************************************************/
enum MMC_ENABLE
{
GmacMmcCntrl = 0x0100, /* mmc control for operating mode of MMC */
GmacMmcIntrRx = 0x0104, /* maintains interrupts generated by rx counters */
GmacMmcIntrTx = 0x0108, /* maintains interrupts generated by tx counters */
GmacMmcIntrMaskRx = 0x010C, /* mask for interrupts generated from rx counters */
GmacMmcIntrMaskTx = 0x0110, /* mask for interrupts generated from tx counters */
};
enum MMC_TX
{
GmacMmcTxOctetCountGb = 0x0114, /*Bytes Tx excl. of preamble and retried bytes (Good or Bad) */
GmacMmcTxFrameCountGb = 0x0118, /*Frames Tx excl. of retried frames (Good or Bad) */
GmacMmcTxBcFramesG = 0x011C, /*Broadcast Frames Tx (Good) */
GmacMmcTxMcFramesG = 0x0120, /*Multicast Frames Tx (Good) */
GmacMmcTx64OctetsGb = 0x0124, /*Tx with len 64 bytes excl. of pre and retried (Good or Bad) */
GmacMmcTx65To127OctetsGb = 0x0128, /*Tx with len >64 bytes <=127 excl. of pre and retried (Good or Bad) */
GmacMmcTx128To255OctetsGb = 0x012C, /*Tx with len >128 bytes <=255 excl. of pre and retried (Good or Bad) */
GmacMmcTx256To511OctetsGb = 0x0130, /*Tx with len >256 bytes <=511 excl. of pre and retried (Good or Bad) */
GmacMmcTx512To1023OctetsGb = 0x0134, /*Tx with len >512 bytes <=1023 excl. of pre and retried (Good or Bad) */
GmacMmcTx1024ToMaxOctetsGb = 0x0138, /*Tx with len >1024 bytes <=MaxSize excl. of pre and retried (Good or Bad) */
GmacMmcTxUcFramesGb = 0x013C, /*Unicast Frames Tx (Good or Bad) */
GmacMmcTxMcFramesGb = 0x0140, /*Multicast Frames Tx (Good and Bad) */
GmacMmcTxBcFramesGb = 0x0144, /*Broadcast Frames Tx (Good and Bad) */
GmacMmcTxUnderFlowError = 0x0148, /*Frames aborted due to Underflow error */
GmacMmcTxSingleColG = 0x014C, /*Successfully Tx Frames after singel collision in Half duplex mode */
GmacMmcTxMultiColG = 0x0150, /*Successfully Tx Frames after more than singel collision in Half duplex mode */
GmacMmcTxDeferred = 0x0154, /*Successfully Tx Frames after a deferral in Half duplex mode */
GmacMmcTxLateCol = 0x0158, /*Frames aborted due to late collision error */
GmacMmcTxExessCol = 0x015C, /*Frames aborted due to excessive (16) collision errors */
GmacMmcTxCarrierError = 0x0160, /*Frames aborted due to carrier sense error (No carrier or Loss of carrier) */
GmacMmcTxOctetCountG = 0x0164, /*Bytes Tx excl. of preamble and retried bytes (Good) */
GmacMmcTxFrameCountG = 0x0168, /*Frames Tx (Good) */
GmacMmcTxExessDef = 0x016C, /*Frames aborted due to excessive deferral errors (deferred for more than 2 max-sized frame times)*/
GmacMmcTxPauseFrames = 0x0170, /*Number of good pause frames Tx. */
GmacMmcTxVlanFramesG = 0x0174, /*Number of good Vlan frames Tx excl. retried frames */
};
enum MMC_RX
{
GmacMmcRxFrameCountGb = 0x0180, /*Frames Rx (Good or Bad) */
GmacMmcRxOctetCountGb = 0x0184, /*Bytes Rx excl. of preamble and retried bytes (Good or Bad) */
GmacMmcRxOctetCountG = 0x0188, /*Bytes Rx excl. of preamble and retried bytes (Good) */
GmacMmcRxBcFramesG = 0x018C, /*Broadcast Frames Rx (Good) */
GmacMmcRxMcFramesG = 0x0190, /*Multicast Frames Rx (Good) */
GmacMmcRxCrcError = 0x0194, /*Number of frames received with CRC error */
GmacMmcRxAlignError = 0x0198, /*Number of frames received with alignment (dribble) error. Only in 10/100mode */
GmacMmcRxRuntError = 0x019C, /*Number of frames received with runt (<64 bytes and CRC error) error */
GmacMmcRxJabberError = 0x01A0, /*Number of frames rx with jabber (>1518/1522 or >9018/9022 and CRC) */
GmacMmcRxUnderSizeG = 0x01A4, /*Number of frames received with <64 bytes without any error */
GmacMmcRxOverSizeG = 0x01A8, /*Number of frames received with >1518/1522 bytes without any error */
GmacMmcRx64OctetsGb = 0x01AC, /*Rx with len 64 bytes excl. of pre and retried (Good or Bad) */
GmacMmcRx65To127OctetsGb = 0x01B0, /*Rx with len >64 bytes <=127 excl. of pre and retried (Good or Bad) */
GmacMmcRx128To255OctetsGb = 0x01B4, /*Rx with len >128 bytes <=255 excl. of pre and retried (Good or Bad) */
GmacMmcRx256To511OctetsGb = 0x01B8, /*Rx with len >256 bytes <=511 excl. of pre and retried (Good or Bad) */
GmacMmcRx512To1023OctetsGb = 0x01BC, /*Rx with len >512 bytes <=1023 excl. of pre and retried (Good or Bad) */
GmacMmcRx1024ToMaxOctetsGb = 0x01C0, /*Rx with len >1024 bytes <=MaxSize excl. of pre and retried (Good or Bad) */
GmacMmcRxUcFramesG = 0x01C4, /*Unicast Frames Rx (Good) */
GmacMmcRxLengthError = 0x01C8, /*Number of frames received with Length type field != frame size */
GmacMmcRxOutOfRangeType = 0x01CC, /*Number of frames received with length field != valid frame size */
GmacMmcRxPauseFrames = 0x01D0, /*Number of good pause frames Rx. */
GmacMmcRxFifoOverFlow = 0x01D4, /*Number of missed rx frames due to FIFO overflow */
GmacMmcRxVlanFramesGb = 0x01D8, /*Number of good Vlan frames Rx */
GmacMmcRxWatchdobError = 0x01DC, /*Number of frames rx with error due to watchdog timeout error */
};
enum MMC_IP_RELATED
{
GmacMmcRxIpcIntrMask = 0x0200, /*Maintains the mask for interrupt generated from rx IPC statistic counters */
GmacMmcRxIpcIntr = 0x0208, /*Maintains the interrupt that rx IPC statistic counters generate */
GmacMmcRxIpV4FramesG = 0x0210, /*Good IPV4 datagrams received */
GmacMmcRxIpV4HdrErrFrames = 0x0214, /*Number of IPV4 datagrams received with header errors */
GmacMmcRxIpV4NoPayFrames = 0x0218, /*Number of IPV4 datagrams received which didnot have TCP/UDP/ICMP payload */
GmacMmcRxIpV4FragFrames = 0x021C, /*Number of IPV4 datagrams received with fragmentation */
GmacMmcRxIpV4UdpChkDsblFrames = 0x0220, /*Number of IPV4 datagrams received that had a UDP payload checksum disabled */
GmacMmcRxIpV6FramesG = 0x0224, /*Good IPV6 datagrams received */
GmacMmcRxIpV6HdrErrFrames = 0x0228, /*Number of IPV6 datagrams received with header errors */
GmacMmcRxIpV6NoPayFrames = 0x022C, /*Number of IPV6 datagrams received which didnot have TCP/UDP/ICMP payload */
GmacMmcRxUdpFramesG = 0x0230, /*Number of good IP datagrams with good UDP payload */
GmacMmcRxUdpErrorFrames = 0x0234, /*Number of good IP datagrams with UDP payload having checksum error */
GmacMmcRxTcpFramesG = 0x0238, /*Number of good IP datagrams with good TDP payload */
GmacMmcRxTcpErrorFrames = 0x023C, /*Number of good IP datagrams with TCP payload having checksum error */
GmacMmcRxIcmpFramesG = 0x0240, /*Number of good IP datagrams with good Icmp payload */
GmacMmcRxIcmpErrorFrames = 0x0244, /*Number of good IP datagrams with Icmp payload having checksum error */
GmacMmcRxIpV4OctetsG = 0x0250, /*Good IPV4 datagrams received excl. Ethernet hdr,FCS,Pad,Ip Pad bytes */
GmacMmcRxIpV4HdrErrorOctets = 0x0254, /*Number of bytes in IPV4 datagram with header errors */
GmacMmcRxIpV4NoPayOctets = 0x0258, /*Number of bytes in IPV4 datagram with no TCP/UDP/ICMP payload */
GmacMmcRxIpV4FragOctets = 0x025C, /*Number of bytes received in fragmented IPV4 datagrams */
GmacMmcRxIpV4UdpChkDsblOctets = 0x0260, /*Number of bytes received in UDP segment that had UDP checksum disabled */
GmacMmcRxIpV6OctetsG = 0x0264, /*Good IPV6 datagrams received excl. Ethernet hdr,FCS,Pad,Ip Pad bytes */
GmacMmcRxIpV6HdrErrorOctets = 0x0268, /*Number of bytes in IPV6 datagram with header errors */
GmacMmcRxIpV6NoPayOctets = 0x026C, /*Number of bytes in IPV6 datagram with no TCP/UDP/ICMP payload */
GmacMmcRxUdpOctetsG = 0x0270, /*Number of bytes in IP datagrams with good UDP payload */
GmacMmcRxUdpErrorOctets = 0x0274, /*Number of bytes in IP datagrams with UDP payload having checksum error */
GmacMmcRxTcpOctetsG = 0x0278, /*Number of bytes in IP datagrams with good TDP payload */
GmacMmcRxTcpErrorOctets = 0x027C, /*Number of bytes in IP datagrams with TCP payload having checksum error */
GmacMmcRxIcmpOctetsG = 0x0280, /*Number of bytes in IP datagrams with good Icmp payload */
GmacMmcRxIcmpErrorOctets = 0x0284, /*Number of bytes in IP datagrams with Icmp payload having checksum error */
};
enum MMC_CNTRL_REG_BIT_DESCRIPTIONS
{
GmacMmcCounterFreeze = 0x00000008, /* when set MMC counters freeze to current value */
GmacMmcCounterResetOnRead = 0x00000004, /* when set MMC counters will be reset to 0 after read */
GmacMmcCounterStopRollover = 0x00000002, /* when set counters will not rollover after max value */
GmacMmcCounterReset = 0x00000001, /* when set all counters wil be reset (automatically cleared after 1 clk) */
};
enum MMC_RX_INTR_MASK_AND_STATUS_BIT_DESCRIPTIONS
{
GmacMmcRxWDInt = 0x00800000, /* set when rxwatchdog error reaches half of max value */
GmacMmcRxVlanInt = 0x00400000, /* set when GmacMmcRxVlanFramesGb counter reaches half of max value */
GmacMmcRxFifoOverFlowInt = 0x00200000, /* set when GmacMmcRxFifoOverFlow counter reaches half of max value */
GmacMmcRxPauseFrameInt = 0x00100000, /* set when GmacMmcRxPauseFrames counter reaches half of max value */
GmacMmcRxOutOfRangeInt = 0x00080000, /* set when GmacMmcRxOutOfRangeType counter reaches half of max value */
GmacMmcRxLengthErrorInt = 0x00040000, /* set when GmacMmcRxLengthError counter reaches half of max value */
GmacMmcRxUcFramesInt = 0x00020000, /* set when GmacMmcRxUcFramesG counter reaches half of max value */
GmacMmcRx1024OctInt = 0x00010000, /* set when GmacMmcRx1024ToMaxOctetsGb counter reaches half of max value */
GmacMmcRx512OctInt = 0x00008000, /* set when GmacMmcRx512To1023OctetsGb counter reaches half of max value */
GmacMmcRx256OctInt = 0x00004000, /* set when GmacMmcRx256To511OctetsGb counter reaches half of max value */
GmacMmcRx128OctInt = 0x00002000, /* set when GmacMmcRx128To255OctetsGb counter reaches half of max value */
GmacMmcRx65OctInt = 0x00001000, /* set when GmacMmcRx65To127OctetsG counter reaches half of max value */
GmacMmcRx64OctInt = 0x00000800, /* set when GmacMmcRx64OctetsGb counter reaches half of max value */
GmacMmcRxOverSizeInt = 0x00000400, /* set when GmacMmcRxOverSizeG counter reaches half of max value */
GmacMmcRxUnderSizeInt = 0x00000200, /* set when GmacMmcRxUnderSizeG counter reaches half of max value */
GmacMmcRxJabberErrorInt = 0x00000100, /* set when GmacMmcRxJabberError counter reaches half of max value */
GmacMmcRxRuntErrorInt = 0x00000080, /* set when GmacMmcRxRuntError counter reaches half of max value */
GmacMmcRxAlignErrorInt = 0x00000040, /* set when GmacMmcRxAlignError counter reaches half of max value */
GmacMmcRxCrcErrorInt = 0x00000020, /* set when GmacMmcRxCrcError counter reaches half of max value */
GmacMmcRxMcFramesInt = 0x00000010, /* set when GmacMmcRxMcFramesG counter reaches half of max value */
GmacMmcRxBcFramesInt = 0x00000008, /* set when GmacMmcRxBcFramesG counter reaches half of max value */
GmacMmcRxOctetGInt = 0x00000004, /* set when GmacMmcRxOctetCountG counter reaches half of max value */
GmacMmcRxOctetGbInt = 0x00000002, /* set when GmacMmcRxOctetCountGb counter reaches half of max value */
GmacMmcRxFrameInt = 0x00000001, /* set when GmacMmcRxFrameCountGb counter reaches half of max value */
};
enum MMC_TX_INTR_MASK_AND_STATUS_BIT_DESCRIPTIONS
{
GmacMmcTxVlanInt = 0x01000000, /* set when GmacMmcTxVlanFramesG counter reaches half of max value */
GmacMmcTxPauseFrameInt = 0x00800000, /* set when GmacMmcTxPauseFrames counter reaches half of max value */
GmacMmcTxExessDefInt = 0x00400000, /* set when GmacMmcTxExessDef counter reaches half of max value */
GmacMmcTxFrameInt = 0x00200000, /* set when GmacMmcTxFrameCount counter reaches half of max value */
GmacMmcTxOctetInt = 0x00100000, /* set when GmacMmcTxOctetCountG counter reaches half of max value */
GmacMmcTxCarrierErrorInt = 0x00080000, /* set when GmacMmcTxCarrierError counter reaches half of max value */
GmacMmcTxExessColInt = 0x00040000, /* set when GmacMmcTxExessCol counter reaches half of max value */
GmacMmcTxLateColInt = 0x00020000, /* set when GmacMmcTxLateCol counter reaches half of max value */
GmacMmcTxDeferredInt = 0x00010000, /* set when GmacMmcTxDeferred counter reaches half of max value */
GmacMmcTxMultiColInt = 0x00008000, /* set when GmacMmcTxMultiColG counter reaches half of max value */
GmacMmcTxSingleCol = 0x00004000, /* set when GmacMmcTxSingleColG counter reaches half of max value */
GmacMmcTxUnderFlowErrorInt = 0x00002000, /* set when GmacMmcTxUnderFlowError counter reaches half of max value */
GmacMmcTxBcFramesGbInt = 0x00001000, /* set when GmacMmcTxBcFramesGb counter reaches half of max value */
GmacMmcTxMcFramesGbInt = 0x00000800, /* set when GmacMmcTxMcFramesGb counter reaches half of max value */
GmacMmcTxUcFramesInt = 0x00000400, /* set when GmacMmcTxUcFramesGb counter reaches half of max value */
GmacMmcTx1024OctInt = 0x00000200, /* set when GmacMmcTx1024ToMaxOctetsGb counter reaches half of max value */
GmacMmcTx512OctInt = 0x00000100, /* set when GmacMmcTx512To1023OctetsGb counter reaches half of max value */
GmacMmcTx256OctInt = 0x00000080, /* set when GmacMmcTx256To511OctetsGb counter reaches half of max value */
GmacMmcTx128OctInt = 0x00000040, /* set when GmacMmcTx128To255OctetsGb counter reaches half of max value */
GmacMmcTx65OctInt = 0x00000020, /* set when GmacMmcTx65To127OctetsGb counter reaches half of max value */
GmacMmcTx64OctInt = 0x00000010, /* set when GmacMmcTx64OctetsGb counter reaches half of max value */
GmacMmcTxMcFramesInt = 0x00000008, /* set when GmacMmcTxMcFramesG counter reaches half of max value */
GmacMmcTxBcFramesInt = 0x00000004, /* set when GmacMmcTxBcFramesG counter reaches half of max value */
GmacMmcTxFrameGbInt = 0x00000002, /* set when GmacMmcTxFrameCountGb counter reaches half of max value */
GmacMmcTxOctetGbInt = 0x00000001, /* set when GmacMmcTxOctetCountGb counter reaches half of max value */
};
/**********************************************************
* Power Management (PMT) Block
**********************************************************/
/**
* PMT supports the reception of network (remote) wake-up frames and Magic packet frames.
* It generates interrupts for wake-up frames and Magic packets received by GMAC.
* PMT sits in Rx path and is enabled with remote wake-up frame enable and Magic packet enable.
* These enable are in PMT control and Status register and are programmed by apllication.
*
* When power down mode is enabled in PMT, all rx frames are dropped by the core. Core comes
* out of power down mode only when either Magic packe tor a Remote wake-up frame is received
* and the corresponding detection is enabled.
*
* Driver need not be modified to support this feature. Only Api to put the device in to power
* down mode is sufficient
*/
#define WAKEUP_REG_LENGTH 8 /*This is the reg length for wake up register configuration*/
enum GmacPmtCtrlStatusBitDefinition
{
GmacPmtFrmFilterPtrReset = 0x80000000, /* when set remote wake-up frame filter register pointer to 3'b000 */
GmacPmtGlobalUnicast = 0x00000200, /* When set enables any unicast packet to be a wake-up frame */
GmacPmtWakeupFrameReceived = 0x00000040, /* Wake up frame received */
GmacPmtMagicPktReceived = 0x00000020, /* Magic Packet received */
GmacPmtWakeupFrameEnable = 0x00000004, /* Wake-up frame enable */
GmacPmtMagicPktEnable = 0x00000002, /* Magic packet enable */
GmacPmtPowerDown = 0x00000001, /* Power Down */
};
/**********************************************************
* IEEE 1588-2008 Precision Time Protocol (PTP) Support
**********************************************************/
enum PTPMessageType
{
SYNC = 0x0,
Delay_Req = 0x1,
Pdelay_Req = 0x2,
Pdelay_Resp = 0x3,
Follow_up = 0x8,
Delay_Resp = 0x9,
Pdelay_Resp_Follow_Up = 0xA,
Announce = 0xB,
Signaling = 0xC,
Management = 0xD,
};
typedef struct TimeStampStruct
{
u32 TSversion; /* PTP Version 1 or PTP version2 */
u32 TSmessagetype; /* Message type associated with this time stamp */
u16 TShighest16; /* Highest 16 bit time stamp value, Valid onley when ADV_TIME_HIGH_WORD configured in corekit */
u32 TSupper32; /* Most significant 32 bit time stamp value */
u32 TSlower32; /* Least Significat 32 bit time stamp value */
} TimeStamp;
/**
* IEEE 1588-2008 is the optional module to support Ethernet frame time stamping.
* Sixty four (+16) bit time stamps are given in each frames transmit and receive status.
* The driver assumes the following
* 1. "IEEE 1588 Time Stamping" "TIME_STAMPING"is ENABLED in corekit
* 2. "IEEE 1588 External Time Stamp Input Enable" "EXT_TIME_STAMPING" is DISABLED in corekit
* 3. "IEEE 1588 Advanced Time Stamp support" "ADV_TIME_STAMPING" is ENABLED in corekit
* 4. "IEEE 1588 Higher Word Register Enable" "ADV_TIME_HIGH_WORD" is ENABLED in corekit
*/
/* GmacTSControl = 0x0700, Controls the Timestamp update logic : only when IEEE 1588 time stamping is enabled in corekit */
enum GmacTSControlReg
{
GmacTSENMACADDR = 0x00040000, /* Enable Mac Addr for PTP filtering 18 RW 0 */
GmacTSCLKTYPE = 0x00030000, /* Select the type of clock node 17:16 RW 00 */
/*
TSCLKTYPE TSMSTRENA TSEVNTENA Messages for wihich TS snapshot is taken
00/01 X 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP
00/01 1 0 DELAY_REQ
00/01 0 1 SYNC
10 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP
10 NA 1 SYNC, FOLLOW_UP
11 NA 0 SYNC, FOLLOW_UP, DELAY_REQ, DELAY_RESP, PDELAY_REQ, PDELAY_RESP
11 NA 1 SYNC, PDELAY_REQ, PDELAY_RESP
*/
GmacTSOrdClk = 0x00000000, /* 00=> Ordinary clock*/
GmacTSBouClk = 0x00010000, /* 01=> Boundary clock*/
GmacTSEtoEClk = 0x00020000, /* 10=> End-to-End transparent clock*/
GmacTSPtoPClk = 0x00030000, /* 11=> P-to-P transparent clock*/
GmacTSMSTRENA = 0x00008000, /* Ena TS Snapshot for Master Messages 15 RW 0 */
GmacTSEVNTENA = 0x00004000, /* Ena TS Snapshot for Event Messages 14 RW 0 */
GmacTSIPV4ENA = 0x00002000, /* Ena TS snapshot for IPv4 13 RW 1 */
GmacTSIPV6ENA = 0x00001000, /* Ena TS snapshot for IPv6 12 RW 0 */
GmacTSIPENA = 0x00000800, /* Ena TS snapshot for PTP over E'net 11 RW 0 */
GmacTSVER2ENA = 0x00000400, /* Ena PTP snooping for version 2 10 RW 0 */
GmacTSCTRLSSR = 0x00000200, /* Digital or Binary Rollover 9 RW 0 */
GmacTSENALL = 0x00000100, /* Enable TS fro all frames (Ver2 only) 8 RW 0 */
GmacTSADDREG = 0x00000020, /* Addend Register Update 5 RW_SC 0 */
GmacTSUPDT = 0x00000008, /* Time Stamp Update 3 RW_SC 0 */
GmacTSINT = 0x00000004, /* Time Atamp Initialize 2 RW_SC 0 */
GmacTSTRIG = 0x00000010, /* Time stamp interrupt Trigger Enable 4 RW_SC 0 */
GmacTSCFUPDT = 0x00000002, /* Time Stamp Fine/Coarse 1 RW 0 */
GmacTSCUPDTCoarse = 0x00000000, /* 0=> Time Stamp update method is coarse */
GmacTSCUPDTFine = 0x00000002, /* 1=> Time Stamp update method is fine */
GmacTSENA = 0x00000001, /* Time Stamp Enable 0 RW 0 */
};
/* GmacTSSubSecIncr = 0x0704, 8 bit value by which sub second register is incremented : only when IEEE 1588 time stamping without external timestamp input */
enum GmacTSSubSecIncrReg
{
GmacSSINCMsk = 0x000000FF, /* Only Lower 8 bits are valid bits 7:0 RW 00 */
};
/* GmacTSLow = 0x070C, Indicates whether the timestamp low count is positive or negative; for Adv timestamp it is always zero */
enum GmacTSSign
{
GmacTSSign = 0x80000000, /* PSNT 31 RW 0 */
GmacTSPositive = 0x00000000,
GmacTSNegative = 0x80000000,
};
/*GmacTargetTimeLow = 0x0718, 32 bit nano seconds(MS) to be compared with system time : only when IEEE 1588 time stamping without external timestamp input */
enum GmacTSLowReg
{
GmacTSDecThr = 0x3B9AC9FF, /*when TSCTRLSSR is set the max value for GmacTargetTimeLowReg and GmacTimeStampLow register is 0x3B9AC9FF at 1ns precision */
};
/* GmacTSHighWord = 0x0724, Time Stamp Higher Word Register (Version 2 only); only lower 16 bits are valid */
enum GmacTSHighWordReg
{
GmacTSHighWordMask = 0x0000FFFF, /* Time Stamp Higher work register has only lower 16 bits valid */
};
/*GmacTSStatus = 0x0728, Time Stamp Status Register */
enum GmacTSStatusReg
{
GmacTSTargTimeReached = 0x00000002, /* Time Stamp Target Time Reached 1 RO 0 */
GmacTSSecondsOverflow = 0x00000001, /* Time Stamp Seconds Overflow 0 RO 0 */
};
/**********************************************************
* Time stamp related functions
**********************************************************/
void synopGMAC_TS_enable(synopGMACdevice *gmacdev);
void synopGMAC_TS_disable(synopGMACdevice *gmacdev);
void synopGMAC_TS_int_enable(synopGMACdevice *gmacdev);
void synopGMAC_TS_int_disable(synopGMACdevice *gmacdev);
void synopGMAC_TS_mac_addr_filt_enable(synopGMACdevice *gmacdev);
void synopGMAC_TS_mac_addr_filt_disable(synopGMACdevice *gmacdev);
void synopGMAC_TS_set_clk_type(synopGMACdevice *gmacdev, u32 clk_type);
void synopGMAC_TS_master_enable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp"
void synopGMAC_TS_master_disable(synopGMACdevice *gmacdev); // Only for Ordinary clock and Boundary clock and "Advanced Time Stamp"
void synopGMAC_TS_event_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_event_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_IPV4_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_IPV4_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_IPV6_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_IPV6_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_ptp_over_ethernet_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_ptp_over_ethernet_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_pkt_snoop_ver2(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_pkt_snoop_ver1(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_digital_rollover_enable(synopGMACdevice *gmacdev);
void synopGMAC_TS_binary_rollover_enable(synopGMACdevice *gmacdev);
void synopGMAC_TS_all_frames_enable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
void synopGMAC_TS_all_frames_disable(synopGMACdevice *gmacdev); // Only for "Advanced Time Stamp"
s32 synopGMAC_TS_addend_update(synopGMACdevice *gmacdev, u32 addend_value);
s32 synopGMAC_TS_timestamp_update(synopGMACdevice *gmacdev, u32 high_value, u32 low_value);
s32 synopGMAC_TS_timestamp_init(synopGMACdevice *gmacdev, u32 high_value, u32 low_value);
void synopGMAC_TS_coarse_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled
void synopGMAC_TS_fine_update(synopGMACdevice *gmacdev); // Only if "fine correction" enabled
void synopGMAC_TS_subsecond_init(synopGMACdevice *gmacdev, u32 sub_sec_inc_val); // Update should happen making use of subsecond mask
void synopGMAC_TS_read_timestamp(synopGMACdevice *gmacdev, u16 * higher_sec_val,
u32 * sec_val, u32 * sub_sec_val); // Reads the timestamp low,high and higher(Ver2) registers in the the struct pointer; readonly contents
void synopGMAC_TS_load_target_timestamp(synopGMACdevice *gmacdev, u32 sec_val, u32 sub_sec_val); //Loads the timestamp target register with the values provided
void synopGMAC_TS_load_timestamp_higher_val(synopGMACdevice *gmacdev, u32 higher_sec_val);
void synopGMAC_TS_read_timestamp_higher_val(synopGMACdevice *gmacdev, u16 * higher_sec_val);
void synopGMAC_TS_read_target_timestamp(synopGMACdevice *gmacdev, u32 * sec_val, u32 * sub_sec_val); //Read the target time stamp register contents
/**********************************************************
* Common functions
**********************************************************/
s32 synopGMAC_set_mdc_clk_div(synopGMACdevice *gmacdev,u32 clk_div_val );
u32 synopGMAC_get_mdc_clk_div(synopGMACdevice *gmacdev);
s32 synopGMAC_read_phy_reg(u64 RegBase,u32 PhyBase, u32 RegOffset, u16 * data);
s32 synopGMAC_write_phy_reg(u64 RegBase, u32 PhyBase, u32 RegOffset, u16 data);
s32 synopGMAC_phy_loopback(synopGMACdevice *gmacdev, bool loopback);
s32 synopGMAC_read_version (synopGMACdevice * gmacdev) ;
s32 synopGMAC_reset (synopGMACdevice * gmacdev );
s32 synopGMAC_dma_bus_mode_init(synopGMACdevice * gmacdev, u32 init_value );
s32 synopGMAC_dma_control_init(synopGMACdevice * gmacdev, u32 init_value );
void synopGMAC_wd_enable(synopGMACdevice * gmacdev);
void synopGMAC_wd_disable(synopGMACdevice * gmacdev);
void synopGMAC_jab_enable(synopGMACdevice * gmacdev);
void synopGMAC_jab_disable(synopGMACdevice * gmacdev);
void synopGMAC_frame_burst_enable(synopGMACdevice * gmacdev);
void synopGMAC_frame_burst_disable(synopGMACdevice * gmacdev);
void synopGMAC_jumbo_frame_enable(synopGMACdevice * gmacdev);
void synopGMAC_jumbo_frame_disable(synopGMACdevice * gmacdev);
void synopGMAC_select_gmii(synopGMACdevice * gmacdev);
void synopGMAC_select_mii(synopGMACdevice * gmacdev);
void synopGMAC_rx_own_enable(synopGMACdevice * gmacdev);
void synopGMAC_rx_own_disable(synopGMACdevice * gmacdev);
void synopGMAC_loopback_on(synopGMACdevice * gmacdev);
void synopGMAC_loopback_off(synopGMACdevice * gmacdev);
void synopGMAC_set_full_duplex(synopGMACdevice * gmacdev);
void synopGMAC_set_half_duplex(synopGMACdevice * gmacdev);
void synopGMAC_retry_enable(synopGMACdevice * gmacdev);
void synopGMAC_retry_disable(synopGMACdevice * gmacdev);
void synopGMAC_pad_crc_strip_enable(synopGMACdevice * gmacdev);
void synopGMAC_pad_crc_strip_disable(synopGMACdevice * gmacdev);
void synopGMAC_back_off_limit(synopGMACdevice * gmacdev, u32 value);
void synopGMAC_deferral_check_enable(synopGMACdevice * gmacdev);
void synopGMAC_deferral_check_disable(synopGMACdevice * gmacdev);
void synopGMAC_rx_enable(synopGMACdevice * gmacdev);
void synopGMAC_rx_disable(synopGMACdevice * gmacdev);
void synopGMAC_tx_enable(synopGMACdevice * gmacdev);
void synopGMAC_tx_disable(synopGMACdevice * gmacdev);
void synopGMAC_frame_filter_enable(synopGMACdevice * gmacdev);
void synopGMAC_frame_filter_disable(synopGMACdevice * gmacdev);
void synopGMAC_write_hash_table_high(synopGMACdevice * gmacdev, u32 data);
void synopGMAC_write_hash_table_low(synopGMACdevice * gmacdev, u32 data);
void synopGMAC_hash_perfect_filter_enable(synopGMACdevice * gmacdev);
void synopGMAC_Hash_filter_only_enable(synopGMACdevice * gmacdev);
void synopGMAC_src_addr_filter_enable(synopGMACdevice * gmacdev);
void synopGMAC_src_addr_filter_disable(synopGMACdevice * gmacdev);
void synopGMAC_dst_addr_filter_inverse(synopGMACdevice * gmacdev);
void synopGMAC_dst_addr_filter_normal(synopGMACdevice * gmacdev);
void synopGMAC_set_pass_control(synopGMACdevice * gmacdev,u32 passcontrol);
void synopGMAC_broadcast_enable(synopGMACdevice * gmacdev);
void synopGMAC_broadcast_disable(synopGMACdevice * gmacdev);
void synopGMAC_multicast_enable(synopGMACdevice * gmacdev);
void synopGMAC_multicast_disable(synopGMACdevice * gmacdev);
void synopGMAC_multicast_hash_filter_enable(synopGMACdevice * gmacdev);
void synopGMAC_multicast_hash_filter_disable(synopGMACdevice * gmacdev);
void synopGMAC_promisc_enable(synopGMACdevice * gmacdev);
void synopGMAC_promisc_disable(synopGMACdevice * gmacdev);
void synopGMAC_unicast_hash_filter_enable(synopGMACdevice * gmacdev);
void synopGMAC_unicast_hash_filter_disable(synopGMACdevice * gmacdev);
void synopGMAC_unicast_pause_frame_detect_enable(synopGMACdevice * gmacdev);
void synopGMAC_unicast_pause_frame_detect_disable(synopGMACdevice * gmacdev);
void synopGMAC_rx_flow_control_enable(synopGMACdevice * gmacdev);
void synopGMAC_rx_flow_control_disable(synopGMACdevice * gmacdev);
void synopGMAC_tx_flow_control_enable(synopGMACdevice * gmacdev);
void synopGMAC_tx_flow_control_disable(synopGMACdevice * gmacdev);
void synopGMAC_tx_activate_flow_control(synopGMACdevice * gmacdev);
void synopGMAC_tx_deactivate_flow_control(synopGMACdevice * gmacdev);
void synopGMAC_pause_control(synopGMACdevice *gmacdev);
s32 synopGMAC_mac_init(synopGMACdevice * gmacdev);
s32 synopGMAC_set_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr );
s32 synopGMAC_get_mac_addr(synopGMACdevice *gmacdev, u32 MacHigh, u32 MacLow, u8 *MacAddr );
s32 synopGMAC_attach (synopGMACdevice * gmacdev, u64 macBase, u64 dmaBase, u64 phyBase,u8 *mac_addr);
void synopGMAC_rx_desc_init_ring(DmaDesc *desc, bool last_ring_desc);
void synopGMAC_tx_desc_init_ring(DmaDesc *desc, bool last_ring_desc);
void synopGMAC_rx_desc_init_chain(DmaDesc * desc);
void synopGMAC_tx_desc_init_chain(DmaDesc * desc);
s32 synopGMAC_init_tx_rx_desc_queue(synopGMACdevice *gmacdev);
void synopGMAC_init_rx_desc_base(synopGMACdevice *gmacdev);
void synopGMAC_init_tx_desc_base(synopGMACdevice *gmacdev);
void synopGMAC_set_owner_dma(DmaDesc *desc);
void synopGMAC_set_desc_sof(DmaDesc *desc);
void synopGMAC_set_desc_eof(DmaDesc *desc);
bool synopGMAC_is_sof_in_rx_desc(DmaDesc *desc);
bool synopGMAC_is_eof_in_rx_desc(DmaDesc *desc);
bool synopGMAC_is_da_filter_failed(DmaDesc *desc);
bool synopGMAC_is_sa_filter_failed(DmaDesc *desc);
bool synopGMAC_is_desc_owned_by_dma(DmaDesc *desc);
u32 synopGMAC_get_rx_desc_frame_length(u32 status);
bool synopGMAC_is_desc_valid(u32 status);
bool synopGMAC_is_desc_empty(DmaDesc *desc);
bool synopGMAC_is_rx_desc_valid(u32 status);
bool synopGMAC_is_tx_aborted(u32 status);
bool synopGMAC_is_tx_carrier_error(u32 status);
u32 synopGMAC_get_tx_collision_count(u32 status);
u32 synopGMAC_is_exc_tx_collisions(u32 status);
bool synopGMAC_is_rx_frame_damaged(u32 status);
bool synopGMAC_is_rx_frame_collision(u32 status);
bool synopGMAC_is_rx_crc(u32 status);
bool synopGMAC_is_frame_dribbling_errors(u32 status);
bool synopGMAC_is_rx_frame_length_errors(u32 status);
bool synopGMAC_is_last_rx_desc(synopGMACdevice * gmacdev,DmaDesc *desc);
bool synopGMAC_is_last_tx_desc(synopGMACdevice * gmacdev,DmaDesc *desc);
bool synopGMAC_is_rx_desc_chained(DmaDesc * desc);
bool synopGMAC_is_tx_desc_chained(DmaDesc * desc);
void synopGMAC_get_desc_data(DmaDesc * desc, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2);
#ifdef ENH_DESC_8W
s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2,
u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low);
#else
s32 synopGMAC_get_tx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2 );
#endif
s32 synopGMAC_set_tx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u64 Data1, u32 Buffer2, u32 Length2, u64 Data2,u32 offload_needed,u32 * index,DmaDesc *Dpr);
s32 synopGMAC_set_rx_qptr(synopGMACdevice * gmacdev, u32 Buffer1, u32 Length1, u64 Data1, u32 Buffer2, u32 Length2, u64 Data2);
#ifdef ENH_DESC_8W
s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2,
u32 * Ext_Status, u32 * Time_Stamp_High, u32 * Time_Stamp_low);
#else
s32 synopGMAC_get_rx_qptr(synopGMACdevice * gmacdev, u32 * Status, u32 * Buffer1, u32 * Length1, u64 * Data1, u32 * Buffer2, u32 * Length2, u64 * Data2);
#endif
void synopGMAC_clear_interrupt(synopGMACdevice *gmacdev);
u32 synopGMAC_get_interrupt_type(synopGMACdevice *gmacdev);
u32 synopGMAC_get_interrupt_mask(synopGMACdevice *gmacdev);
void synopGMAC_enable_interrupt(synopGMACdevice *gmacdev, u32 interrupts);
void synopGMAC_disable_interrupt_all(synopGMACdevice *gmacdev);
void synopGMAC_disable_interrupt(synopGMACdevice *gmacdev, u32 interrupts);
void synopGMAC_enable_dma_rx(synopGMACdevice * gmacdev);
void synopGMAC_enable_dma_tx(synopGMACdevice * gmacdev);
void synopGMAC_resume_dma_tx(synopGMACdevice * gmacdev);
void synopGMAC_resume_dma_rx(synopGMACdevice * gmacdev);
void synopGMAC_take_desc_ownership(DmaDesc * desc);
void synopGMAC_take_desc_ownership_rx(synopGMACdevice * gmacdev);
void synopGMAC_take_desc_ownership_tx(synopGMACdevice * gmacdev);
void synopGMAC_disable_dma_tx(synopGMACdevice * gmacdev);
void synopGMAC_disable_dma_rx(synopGMACdevice * gmacdev);
/******Following APIs are valid only for Enhanced Descriptor from 3.50a release onwards*******/
bool synopGMAC_is_ext_status(synopGMACdevice *gmacdev,u32 status);
bool synopGMAC_ES_is_IP_header_error(synopGMACdevice *gmacdev,u32 ext_status);
bool synopGMAC_ES_is_rx_checksum_bypassed(synopGMACdevice *gmacdev,u32 ext_status);
bool synopGMAC_ES_is_IP_payload_error(synopGMACdevice *gmacdev,u32 ext_status);
/*******************PMT APIs***************************************/
void synopGMAC_pmt_int_enable(synopGMACdevice *gmacdev);
void synopGMAC_pmt_int_disable(synopGMACdevice *gmacdev);
void synopGMAC_power_down_enable(synopGMACdevice *gmacdev);
void synopGMAC_power_down_disable(synopGMACdevice *gmacdev);
void synopGMAC_enable_pmt_interrupt(synopGMACdevice *gmacdev);
void synopGMAC_disable_pmt_interrupt(synopGMACdevice *gmacdev);
void synopGMAC_magic_packet_enable(synopGMACdevice *gmacdev);
void synopGMAC_wakeup_frame_enable(synopGMACdevice *gmacdev);
void synopGMAC_pmt_unicast_enable(synopGMACdevice *gmacdev);
bool synopGMAC_is_magic_packet_received(synopGMACdevice *gmacdev);
bool synopGMAC_is_wakeup_frame_received(synopGMACdevice *gmacdev);
void synopGMAC_write_wakeup_frame_register(synopGMACdevice *gmacdev, u32 * filter_contents);
/*******************MMC APIs***************************************/
void synopGMAC_mmc_counters_stop(synopGMACdevice *gmacdev);
void synopGMAC_mmc_counters_resume(synopGMACdevice *gmacdev);
void synopGMAC_mmc_counters_set_selfclear(synopGMACdevice *gmacdev);
void synopGMAC_mmc_counters_reset_selfclear(synopGMACdevice *gmacdev);
void synopGMAC_mmc_counters_disable_rollover(synopGMACdevice *gmacdev);
void synopGMAC_mmc_counters_enable_rollover(synopGMACdevice *gmacdev);
u32 synopGMAC_read_mmc_counter(synopGMACdevice *gmacdev, u32 counter);
u32 synopGMAC_read_mmc_rx_int_status(synopGMACdevice *gmacdev);
u32 synopGMAC_read_mmc_tx_int_status(synopGMACdevice *gmacdev);
void synopGMAC_disable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask);
void synopGMAC_enable_mmc_tx_interrupt(synopGMACdevice *gmacdev, u32 mask);
void synopGMAC_disable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask);
void synopGMAC_enable_mmc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask);
void synopGMAC_enable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask);
void synopGMAC_disable_mmc_ipc_rx_interrupt(synopGMACdevice *gmacdev, u32 mask);
/*******************Ip checksum offloading APIs***************************************/
void synopGMAC_enable_rx_chksum_offload(synopGMACdevice *gmacdev);
void synopGMAC_disable_rx_Ipchecksum_offload(synopGMACdevice *gmacdev);
void synopGMAC_rx_tcpip_chksum_drop_enable(synopGMACdevice *gmacdev);
void synopGMAC_rx_tcpip_chksum_drop_disable(synopGMACdevice *gmacdev);
u32 synopGMAC_is_rx_checksum_error(synopGMACdevice *gmacdev, u32 status);
bool synopGMAC_is_tx_ipv4header_checksum_error(synopGMACdevice *gmacdev, u32 status);
bool synopGMAC_is_tx_payload_checksum_error(synopGMACdevice *gmacdev, u32 status);
void synopGMAC_tx_checksum_offload_bypass(synopGMACdevice *gmacdev, DmaDesc *desc);
void synopGMAC_tx_checksum_offload_ipv4hdr(synopGMACdevice *gmacdev, DmaDesc *desc);
void synopGMAC_tx_checksum_offload_tcponly(synopGMACdevice *gmacdev, DmaDesc *desc);
void synopGMAC_tx_checksum_offload_tcp_pseudo(synopGMACdevice *gmacdev, DmaDesc *desc);
#endif /* End of file */
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
*/
#ifndef SYNOP_GMAC_HOST_H
#define SYNOP_GMAC_HOST_H 1
#include "synopGMAC_plat.h"
#include "synopGMAC_Dev.h"
#include "mii.h"
struct net_device_stats
{
unsigned long rx_packets; /* total packets received */
unsigned long tx_packets; /* total packets transmitted */
unsigned long rx_bytes; /* total bytes received */
unsigned long tx_bytes; /* total bytes transmitted */
unsigned long rx_errors; /* bad packets received */
unsigned long tx_errors; /* packet transmit problems */
unsigned long rx_dropped; /* no space in linux buffers */
unsigned long tx_dropped; /* no space available in linux */
unsigned long multicast; /* multicast packets received */
unsigned long collisions;
/* detailed rx_errors: */
unsigned long rx_length_errors;
unsigned long rx_over_errors; /* receiver ring buff overflow */
unsigned long rx_crc_errors; /* recved pkt with crc error */
unsigned long rx_frame_errors; /* recv'd frame alignment error */
unsigned long rx_fifo_errors; /* recv'r fifo overrun */
unsigned long rx_missed_errors; /* receiver missed packet */
/* detailed tx_errors */
unsigned long tx_aborted_errors;
unsigned long tx_carrier_errors;
unsigned long tx_fifo_errors;
unsigned long tx_heartbeat_errors;
unsigned long tx_window_errors;
/* for cslip etc */
unsigned long rx_compressed;
unsigned long tx_compressed;
};
typedef struct synopGMACNetworkAdapter{
/*Device Dependent Data structur*/
synopGMACdevice * synopGMACdev;
struct net_device_stats synopGMACNetStats;
struct mii_if_info mii;
} synopGMACPciNetworkAdapter;
#endif
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
*/
#ifndef __DEBUG_H__
#define __DEBUG_H__
//#define GMAC_DEBUG
#include <rtthread.h>
#ifdef GMAC_DEBUG
#define DEBUG_MES rt_kprintf
#else
#define DEBUG_MES(...)
#endif
#endif /*__DEBUG_H__*/
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
*/
#ifndef SYNOP_GMAC_NETWORK_INTERFACE_H
#define SYNOP_GMAC_NETWORK_INTERFACE_H 1
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#include "synopGMAC_plat.h"
#include "synopGMAC_Host.h"
#include "synopGMAC_Dev.h"
#define NET_IF_TIMEOUT (10*HZ)
#define CHECK_TIME (HZ)
s32 synopGMAC_init_network_interface(char* xname,u64 synopGMACMappedAddr);
void synopGMAC_exit_network_interface(void);
s32 synopGMAC_linux_open(struct eth_device *);
s32 synopGMAC_linux_close(struct eth_device *);
struct net_device_stats * synopGMAC_linux_get_stats(struct synopGMACNetworkAdapter *);
s32 synopGMAC_test(synopGMACdevice * gmacdev_0,synopGMACdevice * gmacdev_1);
void dumpreg(u64 );
void dumpphyreg();
/*
* gethex(vp,p,n)
* convert n hex digits from p to binary, result in vp,
* rtn 1 on success
*/
static int gethex(u8 *vp, char *p, int n)
{
u8 v;
int digit;
for (v = 0; n > 0; n--) {
if (*p == 0)
return (0);
if (*p >= '0' && *p <= '9')
digit = *p - '0';
else if (*p >= 'a' && *p <= 'f')
digit = *p - 'a' + 10;
else if (*p >= 'A' && *p <= 'F')
digit = *p - 'A' + 10;
else
return (0);
v <<= 4;
v |= digit;
p++;
}
*vp = v;
return (1);
}
#endif /* End of file */
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
* 2020-08-10 lizhirui porting to ls2k
*/
#include "synopGMAC_plat.h"
#include "synopGMAC_Dev.h"
#include <rthw.h>
#include <rtthread.h>
void flush_cache(unsigned long start_addr, unsigned long size)
{
/*r4k_dcache_wback_inv(start_addr,size);
//rt_kprintf("flush_cache:start_addr = 0x%p,size = 0x%p",start_addr,size);
unsigned long new_addr = start_addr - CACHED_MEMORY_ADDR + UNCACHED_MEMORY_ADDR;
rt_memcpy(new_addr,start_addr,size);
if(rt_memcmp(start_addr,new_addr,size) != 0)
{
rt_kprintf("flush_cache:data isn't matched!\n");
while(1);
}
else
{
//rt_kprintf("flush_cache:data is matched!\n");
}*/
}
//convert virtual address to physical address
dma_addr_t __attribute__((weak)) gmac_dmamap(unsigned long va,u32 size)
{
return VA_TO_PA (va);
//return UNCACHED_TO_PHYS(va);
}
/**
* This is a wrapper function for Memory allocation routine. In linux Kernel
* it it kmalloc function
* @param[in] bytes in bytes to allocate
*/
void *plat_alloc_memory(u32 bytes)
{
//return (void*)malloc((size_t)bytes, M_DEVBUF, M_DONTWAIT);
void *buf = (void*)rt_malloc((u32)bytes);
flush_cache((unsigned long)buf, bytes);
return buf;
}
/**
* This is a wrapper function for consistent dma-able Memory allocation routine.
* In linux Kernel, it depends on pci dev structure
* @param[in] bytes in bytes to allocate
*/
//allocate a space aligned to 16-byte boundary without cache
void *plat_alloc_consistent_dmaable_memory(synopGMACdevice *pcidev, u32 size, u32 *addr)
{
void *buf;
buf = (void*)rt_malloc((u32)(size + 16));
//CPU_IOFlushDCache( buf,size, SYNC_W);
unsigned long i = (unsigned long)buf;
// rt_kprintf("size = %d\n", size);
// rt_kprintf("bufaddr = %p\n", buf);
// rt_kprintf("i%%16 == %d\n", i%16);
if(i % 16 == 8){
i += 8;
}
else if(i % 16 == 4){
i += 12;
}
else if(i % 16 == 12){
i += 4;
}
flush_cache(i, size);
*addr = gmac_dmamap(i, size);
buf = (unsigned char *)CACHED_TO_UNCACHED(i);
//rt_kprintf("bufaddr = %p\n", buf);
return buf;
}
/**
* This is a wrapper function for freeing consistent dma-able Memory.
* In linux Kernel, it depends on pci dev structure
* @param[in] bytes in bytes to allocate
*/
//void plat_free_consistent_dmaable_memory(void * addr)
void plat_free_consistent_dmaable_memory(synopGMACdevice *pcidev, u32 size, void * addr,u64 dma_addr)
{
rt_free((void*)PHYS_TO_CACHED(UNCACHED_TO_PHYS(addr)));
return;
}
/**
* This is a wrapper function for Memory free routine. In linux Kernel
* it it kfree function
* @param[in] buffer pointer to be freed
*/
void plat_free_memory(void *buffer)
{
rt_free(buffer);
return ;
}
//convert virtual address to physical address and flush cache
dma_addr_t plat_dma_map_single(void *hwdev,void *ptr,u32 size)
{
unsigned long addr = (unsigned long) ptr;
//CPU_IOFlushDCache(addr,size, direction);
flush_cache(addr, size);
return gmac_dmamap(addr, size);
}
/**
* This is a wrapper function for platform dependent delay
* Take care while passing the argument to this function
* @param[in] buffer pointer to be freed
*/
void plat_delay(u32 delay)
{
while (delay--);
return;
}
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
* 2020-08-10 lizhirui porting to ls2k
*/
#ifndef SYNOP_GMAC_PLAT_H
#define SYNOP_GMAC_PLAT_H 1
/* sw
#include <linux/kernel.h>
#include <asm/io.h>
#include <linux/gfp.h>
#include <linux/slab.h>
#include <linux/pci.h>
*/
#include "synopGMAC_types.h"
#include "synopGMAC_debug.h"
//#include "mii.h"
//#include "GMAC_Pmon.h"
//#include "synopGMAC_Host.h"
#include <rtthread.h>
#include <stdint.h>
#include "mips_addrspace.h"
//sw: copy the type define into here
#define IOCTL_READ_REGISTER SIOCDEVPRIVATE+1
#define IOCTL_WRITE_REGISTER SIOCDEVPRIVATE+2
#define IOCTL_READ_IPSTRUCT SIOCDEVPRIVATE+3
#define IOCTL_READ_RXDESC SIOCDEVPRIVATE+4
#define IOCTL_READ_TXDESC SIOCDEVPRIVATE+5
#define IOCTL_POWER_DOWN SIOCDEVPRIVATE+6
#define SYNOP_GMAC0 1
typedef int bool;
//typedef unsigned long dma_addr_t;
#define KUSEG_ADDR 0x0
#define CACHED_MEMORY_ADDR KSEG0BASE
#define UNCACHED_MEMORY_ADDR KSEG0BASE
#define KSEG2_ADDR KSEG2BASE
#define MAX_MEM_ADDR KSEG3BASE
#define RESERVED_ADDR KSEG3BASE
#define CACHED_TO_PHYS(x) ((uint64_t)(x) - CACHED_MEMORY_ADDR)
#define PHYS_TO_CACHED(x) ((uint64_t)(x) + CACHED_MEMORY_ADDR)
#define UNCACHED_TO_PHYS(x) ((uint64_t)(x) - UNCACHED_MEMORY_ADDR)
#define PHYS_TO_UNCACHED(x) ((uint64_t)(x) + UNCACHED_MEMORY_ADDR)
#define VA_TO_CINDEX(x) (PHYS_TO_CACHED(UNCACHED_TO_PHYS(x)))
#define CACHED_TO_UNCACHED(x) (PHYS_TO_UNCACHED(CACHED_TO_PHYS(x)))
#define VA_TO_PA(x) CACHED_TO_PHYS(x)
/* sw
#define TR0(fmt, args...) printk(KERN_CRIT "SynopGMAC: " fmt, ##args)
#ifdef DEBUG
#undef TR
# define TR(fmt, args...) printk(KERN_CRIT "SynopGMAC: " fmt, ##args)
#else
# define TR(fmt, args...) // not debugging: nothing
#endif
*/
/*
#define TR0(fmt, args...) printf("SynopGMAC: " fmt, ##args)
*/
/*
#ifdef DEBUG
#undef TR
# define TR(fmt, args...) printf("SynopGMAC: " fmt, ##args)
#else
//# define TR(fmt, args...) // not debugging: nothing
#define TR(fmt, args...) printf("SynopGMAC: " fmt, ##args)
#endif
*/
//sw: nothing to display
#define TR0(fmt, args...) //rt_kprintf(fmt, ##args)
#define TR(fmt, args...) //rt_kprintf(fmt, ##args)
//typedef int bool;
enum synopGMAC_boolean
{
false = 0,
true = 1
};
#define DEFAULT_DELAY_VARIABLE 10
#define DEFAULT_LOOP_VARIABLE 10000
/* There are platform related endian conversions
*
*/
#define LE32_TO_CPU __le32_to_cpu
#define BE32_TO_CPU __be32_to_cpu
#define CPU_TO_LE32 __cpu_to_le32
/* Error Codes */
#define ESYNOPGMACNOERR 0
#define ESYNOPGMACNOMEM 1
#define ESYNOPGMACPHYERR 2
#define ESYNOPGMACBUSY 3
struct Network_interface_data
{
u32 unit;
u64 addr;
u32 data;
};
/**
* These are the wrapper function prototypes for OS/platform related routines
*/
void * plat_alloc_memory(u32 );
void plat_free_memory(void *);
//void * plat_alloc_consistent_dmaable_memory(struct pci_dev *, u32, u32 *);
//void plat_free_consistent_dmaable_memory (struct pci_dev *, u32, void *, u32);
void plat_delay(u32);
/**
* The Low level function to read register contents from Hardware.
*
* @param[in] pointer to the base of register map
* @param[in] Offset from the base
* \return Returns the register contents
*/
static u32 synopGMACReadReg(u64 RegBase, u32 RegOffset)
{
u64 addr;
u32 data;
addr = RegBase + (u32)RegOffset;
data = *(volatile u32 *)addr;
#if SYNOP_REG_DEBUG
TR("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, (u32)RegBase, RegOffset, data );
#endif
// rt_kprintf("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, (u32)RegBase, RegOffset, data );
return data;
}
/**
* The Low level function to write to a register in Hardware.
*
* @param[in] pointer to the base of register map
* @param[in] Offset from the base
* @param[in] Data to be written
* \return void
*/
static void synopGMACWriteReg(u64 RegBase, u32 RegOffset, u32 RegData )
{
u64 addr;
addr = RegBase + (u32)RegOffset;
// rt_kprintf("%s RegBase = 0x%08x RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__,(u32) RegBase, RegOffset, RegData );
#if SYNOP_REG_DEBUG
TR("%s RegBase = 0x%p RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__,(u32) RegBase, RegOffset, RegData );
#endif
*(volatile u32 *)addr = RegData;
/*if(addr == 0xbfe1100c)
DEBUG_MES("regdata = %08x\n", RegData);*/
return;
}
/**
* The Low level function to set bits of a register in Hardware.
*
* @param[in] pointer to the base of register map
* @param[in] Offset from the base
* @param[in] Bit mask to set bits to logical 1
* \return void
*/
static void synopGMACSetBits(u64 RegBase, u32 RegOffset, u32 BitPos)
{
//u64 addr = (u64)RegBase + (u64)RegOffset;
u32 data;
data = synopGMACReadReg(RegBase, RegOffset);
data |= BitPos;
synopGMACWriteReg(RegBase, RegOffset, data);
// writel(data,(void *)addr);
#if SYNOP_REG_DEBUG
TR("%s !!!!!!!!!!!!! RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, RegOffset, data );
#endif
return;
}
/**
* The Low level function to clear bits of a register in Hardware.
*
* @param[in] pointer to the base of register map
* @param[in] Offset from the base
* @param[in] Bit mask to clear bits to logical 0
* \return void
*/
static void synopGMACClearBits(u64 RegBase, u32 RegOffset, u32 BitPos)
{
u32 data;
data = synopGMACReadReg(RegBase, RegOffset);
data &= (~BitPos);
synopGMACWriteReg(RegBase, RegOffset, data);
#if SYNOP_REG_DEBUG
TR("%s !!!!!!!!!!!!! RegOffset = 0x%08x RegData = 0x%08x\n", __FUNCTION__, RegOffset, data );
#endif
return;
}
/**
* The Low level function to Check the setting of the bits.
*
* @param[in] pointer to the base of register map
* @param[in] Offset from the base
* @param[in] Bit mask to set bits to logical 1
* \return returns TRUE if set to '1' returns FALSE if set to '0'. Result undefined there are no bit set in the BitPos argument.
*
*/
static bool synopGMACCheckBits(u64 RegBase, u32 RegOffset, u32 BitPos)
{
u32 data;
data = synopGMACReadReg(RegBase, RegOffset);
data &= BitPos;
if(data)
{
return true;
}
else
{
return false;
}
}
#endif
\ No newline at end of file
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-08-24 chinesebear first version
*/
#ifndef __TYPES__H
#define __TYPES__H
typedef unsigned char uint8_t;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef signed int s32;
typedef u32 dma_addr_t;
#endif /*__TYPES__H*/
......@@ -6,16 +6,16 @@
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_NAME_MAX 30
#define RT_ALIGN_SIZE 8
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 100
#define RT_TICK_PER_SECOND 1000
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 2048
#define IDLE_THREAD_STACK_SIZE 16384
#define RT_DEBUG
/* Inter-Thread communication */
......@@ -39,13 +39,14 @@
#define RT_CONSOLEBUF_SIZE 256
#define RT_CONSOLE_DEVICE_NAME "uart"
#define RT_VER_NUM 0x40003
#define ARCH_CPU_64BIT
#define ARCH_MIPS64
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_STACK_SIZE 16384
#define RT_MAIN_THREAD_PRIORITY 10
/* C++ features */
......@@ -60,7 +61,7 @@
#define FINSH_USING_SYMTAB
#define FINSH_USING_DESCRIPTION
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 4096
#define FINSH_THREAD_STACK_SIZE 16384
#define FINSH_CMD_SIZE 80
#define FINSH_USING_MSH
#define FINSH_USING_MSH_DEFAULT
......@@ -70,15 +71,30 @@
#define RT_USING_DFS
#define DFS_USING_WORKDIR
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FILESYSTEMS_MAX 10
#define DFS_FILESYSTEM_TYPES_MAX 10
#define DFS_FD_MAX 16
#define RT_USING_DFS_ELMFAT
/* elm-chan's FatFs, Generic FAT Filesystem Module */
#define RT_DFS_ELM_CODE_PAGE 936
#define RT_DFS_ELM_WORD_ACCESS
#define RT_DFS_ELM_USE_LFN_3
#define RT_DFS_ELM_USE_LFN 3
#define RT_DFS_ELM_MAX_LFN 255
#define RT_DFS_ELM_DRIVES 9
#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
#define RT_DFS_ELM_REENTRANT
#define RT_USING_DFS_DEVFS
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512
#define RT_USING_SYSTEM_WORKQUEUE
#define RT_SYSTEM_WORKQUEUE_STACKSIZE 16384
#define RT_SYSTEM_WORKQUEUE_PRIORITY 5
#define RT_USING_SERIAL
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
......@@ -96,12 +112,69 @@
/* Socket abstraction layer */
#define RT_USING_SAL
/* protocol stack implement */
#define SAL_USING_LWIP
#define SAL_SOCKETS_NUM 16
/* Network interface device */
#define RT_USING_NETDEV
#define NETDEV_USING_IFCONFIG
#define NETDEV_USING_PING
#define NETDEV_USING_NETSTAT
#define NETDEV_USING_AUTO_DEFAULT
#define NETDEV_IPV4 1
#define NETDEV_IPV6 0
/* light weight TCP/IP stack */
#define RT_USING_LWIP
#define RT_USING_LWIP202
#define RT_LWIP_MEM_ALIGNMENT 8
#define RT_LWIP_IGMP
#define RT_LWIP_ICMP
#define RT_LWIP_SNMP
#define RT_LWIP_DNS
#define RT_LWIP_DHCP
#define IP_SOF_BROADCAST 1
#define IP_SOF_BROADCAST_RECV 1
/* Static IPv4 Address */
#define RT_LWIP_IPADDR "192.168.1.30"
#define RT_LWIP_GWADDR "192.168.1.1"
#define RT_LWIP_MSKADDR "255.255.255.0"
#define RT_LWIP_UDP
#define RT_LWIP_TCP
#define RT_LWIP_RAW
#define RT_MEMP_NUM_NETCONN 8
#define RT_LWIP_PBUF_NUM 16
#define RT_LWIP_RAW_PCB_NUM 4
#define RT_LWIP_UDP_PCB_NUM 4
#define RT_LWIP_TCP_PCB_NUM 4
#define RT_LWIP_TCP_SEG_NUM 40
#define RT_LWIP_TCP_SND_BUF 8196
#define RT_LWIP_TCP_WND 8196
#define RT_LWIP_TCPTHREAD_PRIORITY 5
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 32
#define RT_LWIP_TCPTHREAD_STACKSIZE 16384
#define RT_LWIP_ETHTHREAD_PRIORITY 5
#define RT_LWIP_ETHTHREAD_STACKSIZE 16384
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 32
#define RT_LWIP_REASSEMBLY_FRAG
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define SO_REUSE 1
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_SNDTIMEO 1
#define LWIP_SO_RCVBUF 1
#define LWIP_SO_LINGER 0
#define LWIP_NETIF_LOOPBACK 0
#define RT_LWIP_STATS
#define RT_LWIP_USING_PING
/* AT commands */
......@@ -145,6 +218,9 @@
/* system packages */
#define PKG_USING_LWEXT4
#define RT_USING_DFS_LWEXT4
#define PKG_USING_LWEXT4_LATEST_VERSION
/* peripheral libraries and drivers */
......@@ -154,12 +230,6 @@
/* samples: kernel and components samples */
/* Privated Packages of RealThread */
/* Network Utilities */
#define SOC_LS2K1000
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册