Browse Source

Merge pull request #3883 from bigmagic123/ls2k_add_gmac

Ls2k add gmac
Bernard Xiong 4 years ago
parent
commit
de0bb6f96c
45 changed files with 9225 additions and 204 deletions
  1. 1 0
      bsp/ls1bdev/SConstruct
  2. 1 1
      bsp/ls1cdev/SConstruct
  3. 130 46
      bsp/ls2kdev/.config
  4. 32 2
      bsp/ls2kdev/README.md
  5. 1 2
      bsp/ls2kdev/SConstruct
  6. 10 0
      bsp/ls2kdev/drivers/SConscript
  7. 2 2
      bsp/ls2kdev/drivers/board.h
  8. 0 1
      bsp/ls2kdev/drivers/clk.c
  9. 2 2
      bsp/ls2kdev/drivers/drv_gpio.c
  10. 1 2
      bsp/ls2kdev/drivers/drv_gpio.h
  11. 74 75
      bsp/ls2kdev/drivers/drv_uart.h
  12. 13 13
      bsp/ls2kdev/drivers/interrupt.h
  13. 8 8
      bsp/ls2kdev/drivers/ls2k1000.h
  14. 16 0
      bsp/ls2kdev/drivers/net/SConscript
  15. 132 0
      bsp/ls2kdev/drivers/net/mii.c
  16. 229 0
      bsp/ls2kdev/drivers/net/mii.h
  17. 961 0
      bsp/ls2kdev/drivers/net/synopGMAC.c
  18. 23 0
      bsp/ls2kdev/drivers/net/synopGMAC.h
  19. 3721 0
      bsp/ls2kdev/drivers/net/synopGMAC_Dev.c
  20. 1717 0
      bsp/ls2kdev/drivers/net/synopGMAC_Dev.h
  21. 60 0
      bsp/ls2kdev/drivers/net/synopGMAC_Host.h
  22. 22 0
      bsp/ls2kdev/drivers/net/synopGMAC_debug.h
  23. 65 0
      bsp/ls2kdev/drivers/net/synopGMAC_network_interface.h
  24. 130 0
      bsp/ls2kdev/drivers/net/synopGMAC_plat.c
  25. 242 0
      bsp/ls2kdev/drivers/net/synopGMAC_plat.h
  26. 23 0
      bsp/ls2kdev/drivers/net/synopGMAC_types.h
  27. 83 13
      bsp/ls2kdev/rtconfig.h
  28. 5 1
      components/net/Kconfig
  29. 2 2
      components/net/lwip-2.0.2/src/arch/sys_arch.c
  30. 5 0
      components/net/lwip-2.0.2/src/lwipopts.h
  31. 10 9
      components/net/lwip-2.0.2/src/netif/ethernetif.c
  32. 6 6
      components/net/uip/rt-thread/uip_ethernetif.c
  33. 4 0
      libcpu/Kconfig
  34. 11 10
      libcpu/mips/common/context_gcc.S
  35. 44 4
      libcpu/mips/common/exception.c
  36. 7 1
      libcpu/mips/common/exception_gcc.S
  37. 2 0
      libcpu/mips/common/stackframe.h
  38. 70 0
      libcpu/mips/gs264/cache.c
  39. 24 0
      libcpu/mips/gs264/cache.h
  40. 4 4
      libcpu/mips/gs264/cpuinit_gcc.S
  41. 222 0
      libcpu/mips/gs264/mips_mmu.c
  42. 99 0
      libcpu/mips/gs264/mips_mmu.h
  43. 79 0
      libcpu/mips/gs264/mipscfg.c
  44. 819 0
      libcpu/mips/gs264/mmu.c
  45. 113 0
      libcpu/mips/gs264/mmu.h

+ 1 - 0
bsp/ls1bdev/SConstruct

@@ -19,6 +19,7 @@ env = Environment(tools = ['mingw'],
     AR = rtconfig.AR, ARFLAGS = '-rc',
     LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
 env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+env['ASCOM'] = env['ASPPCOM']
 
 Export('RTT_ROOT')
 Export('rtconfig')

+ 1 - 1
bsp/ls1cdev/SConstruct

@@ -12,7 +12,6 @@ from building import *
 
 TARGET = 'rtthread.' + rtconfig.TARGET_EXT
 
-rtconfig.AFLAGS += ' -I' + str(Dir('#'))
 
 DefaultEnvironment(tools=[])
 env = Environment(tools = ['mingw'],
@@ -21,6 +20,7 @@ env = Environment(tools = ['mingw'],
     AR = rtconfig.AR, ARFLAGS = '-rc',
     LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
 env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+env['ASCOM'] = env['ASPPCOM']
 
 Export('RTT_ROOT')
 Export('rtconfig')

+ 130 - 46
bsp/ls2kdev/.config

@@ -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

+ 32 - 2
bsp/ls2kdev/README.md

@@ -84,13 +84,43 @@ Hi, this is RT-Thread!!
 msh >
 ```
 
-## 4. 支持情况
+## 4.开机自动启动
+
+在调试阶段,可以利用脚本,在pmon阶段从TFTP服务器上获取固件,然后引导启动。这样可以节省开发配置的时间。具体的步骤如下:
+
+**第一步:**
+设置开发板的IP地址,在进入pmon的控制台后,输入`set ifconfig syn0:10.1.1.100`。其中`syn0`后面的ip地址为开发板的ip地址,与存放rt-thread固件的TFTP的服务器IP地址在**同一网段**。
+
+**第二步:**
+
+进入龙芯的Debian系统,用管理员权限进入,输入用户名`root`,密码`loongson`。并且修改boot分区下的boot.cfg文件。增加如下:
+
+```
+title   TFTPBOOT
+ kernel tftfp://10.1.1.118/rtthread.elf
+ args console=tty root=/dev/sda2
+ initrd (wd0,0)/initrd.img
+```
+
+其中`tftfp://10.1.1.118/rtthread.elf`中的`10.1.1.118`为tftp服务器的ip地址。
+
+**第三步:**
+
+电脑开启TFTP服务器,将路径指向存放有ls2k的rt-thread固件的目录下。
+
+以上三步完成之后,重启系统,就可以省略每次都需要进入pmon的输入命令的麻烦,板子上电后,可以自动从系统TFTP服务器中获取固件,然后启动,大大提高调试代码效率。
+
+## 5. 支持情况
 
 | 驱动 | 支持情况  |  备注  |
 | ------ | ----  | :------:  |
 | UART | 支持 | UART0|
+| GPIO | 支持 | - |
+| PWM | 支持 | - |
+| GMAC | 支持 | 网卡驱动 |
+| RTC  | 支持 | - |
 
-## 5. 联系人信息
+## 6. 联系人信息
 
 维护人:[bernard][4]
 

+ 1 - 2
bsp/ls2kdev/SConstruct

@@ -9,8 +9,6 @@ from building import *
 
 TARGET = 'rtthread.' + rtconfig.TARGET_EXT
 
-rtconfig.AFLAGS += ' -I' + str(Dir('#')) + ' -I ' + RTT_ROOT + '/libcpu/mips/common/'
-
 DefaultEnvironment(tools=[])
 env = Environment(tools = ['mingw'],
 	AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
@@ -19,6 +17,7 @@ env = Environment(tools = ['mingw'],
 	AR = rtconfig.AR, ARFLAGS = '-rc',
 	LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
 env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+env['ASCOM'] = env['ASPPCOM']
 
 Export('RTT_ROOT')
 Export('rtconfig')

+ 10 - 0
bsp/ls2kdev/drivers/SConscript

@@ -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')

+ 2 - 2
bsp/ls2kdev/drivers/board.h

@@ -15,8 +15,8 @@
 
 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 CPU_HZ              (1000 * 1000 * 1000) //QEMU 200*1000*1000
+#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);

+ 0 - 1
bsp/ls2kdev/drivers/clk.c

@@ -14,7 +14,6 @@
 #include <rtthread.h>
 #include "ls2k1000.h"
 
-
 struct loongson_pll {
     rt_uint64_t PLL_SYS_0;
     rt_uint64_t PLL_SYS_1;

+ 2 - 2
bsp/ls2kdev/drivers/drv_gpio.c

@@ -5,8 +5,8 @@
  * Change Logs:
  * Date           Author       Notes
  * 2015-01-20     Bernard      the first version
- * 2017-10-20      ZYH          add mode open drain and input pull down
- * 2020-06-01     Du Huanpeng   GPIO driver based on <components/drivers/include/drivers/pin.h>
+ * 2017-10-20      ZYH         add mode open drain and input pull down
+ * 2020-06-01     Du Huanpeng  GPIO driver based on <components/drivers/include/drivers/pin.h>
  */
 #include <rtthread.h>
 #include <drivers/pin.h>

+ 1 - 2
bsp/ls2kdev/drivers/drv_gpio.h

@@ -6,7 +6,7 @@
  *
  * Change Logs:
  * Date           Author       Notes
- * 2017-11-24     勤为本          first version
+ * 2017-11-24     勤为本        first version
  * 2018-05-11     zhuangwei    add gpio interrupt ops
  */
 
@@ -36,6 +36,5 @@ struct loongson_gpio {
 
 int loongson_pin_init(void);
 
-
 #endif
 

+ 74 - 75
bsp/ls2kdev/drivers/drv_uart.h

@@ -15,100 +15,99 @@
 #include <rthw.h>
 
 /* UART registers */
-#define UART_DAT(base)		HWREG8(base + 0x00)
-#define UART_IER(base)		HWREG8(base + 0x01)
-#define UART_IIR(base)		HWREG8(base + 0x02)
-#define UART_FCR(base)		HWREG8(base + 0x02)
-#define UART_LCR(base)		HWREG8(base + 0x03)
-#define UART_MCR(base)		HWREG8(base + 0x04)
-#define UART_LSR(base)		HWREG8(base + 0x05)
-#define UART_MSR(base)		HWREG8(base + 0x06)
+#define UART_DAT(base)        HWREG8(base + 0x00)
+#define UART_IER(base)        HWREG8(base + 0x01)
+#define UART_IIR(base)        HWREG8(base + 0x02)
+#define UART_FCR(base)        HWREG8(base + 0x02)
+#define UART_LCR(base)        HWREG8(base + 0x03)
+#define UART_MCR(base)        HWREG8(base + 0x04)
+#define UART_LSR(base)        HWREG8(base + 0x05)
+#define UART_MSR(base)        HWREG8(base + 0x06)
 
-#define UART_LSB(base)		HWREG8(base + 0x00)
-#define UART_MSB(base)		HWREG8(base + 0x01)
+#define UART_LSB(base)        HWREG8(base + 0x00)
+#define UART_MSB(base)        HWREG8(base + 0x01)
 
 /* interrupt enable register */
-#define	IER_IRxE	0x1
-#define	IER_ITxE	0x2
-#define	IER_ILE	    0x4
-#define	IER_IME	    0x8
+#define    IER_IRxE         0x1
+#define    IER_ITxE         0x2
+#define    IER_ILE          0x4
+#define    IER_IME          0x8
 
 /* interrupt identification register */
-#define	IIR_IMASK	0xf	/* mask */
-#define	IIR_RXTOUT	0xc	/* receive timeout */
-#define	IIR_RLS		0x6	/* receive line status */
-#define	IIR_RXRDY	0x4	/* receive ready */
-#define	IIR_TXRDY	0x2	/* transmit ready */
-#define	IIR_NOPEND	0x1	/* nothing */
-#define	IIR_MLSC	0x0	/* modem status */
-#define	IIR_FIFO_MASK	0xc0	/* set if FIFOs are enabled */
+#define    IIR_IMASK        0xf    /* mask */
+#define    IIR_RXTOUT       0xc    /* receive timeout */
+#define    IIR_RLS          0x6    /* receive line status */
+#define    IIR_RXRDY        0x4    /* receive ready */
+#define    IIR_TXRDY        0x2    /* transmit ready */
+#define    IIR_NOPEND       0x1    /* nothing */
+#define    IIR_MLSC         0x0    /* modem status */
+#define    IIR_FIFO_MASK    0xc0    /* set if FIFOs are enabled */
 
 /* fifo control register */
-#define	FIFO_ENABLE	    0x01	/* enable fifo */
-#define	FIFO_RCV_RST	0x02	/* reset receive fifo */
-#define	FIFO_XMT_RST	0x04	/* reset transmit fifo */
-#define	FIFO_DMA_MODE	0x08	/* enable dma mode */
-#define	FIFO_TRIGGER_1	0x00	/* trigger at 1 char */
-#define	FIFO_TRIGGER_4	0x40	/* trigger at 4 chars */
-#define	FIFO_TRIGGER_8	0x80	/* trigger at 8 chars */
-#define	FIFO_TRIGGER_14	0xc0	/* trigger at 14 chars */
+#define    FIFO_ENABLE      0x01    /* enable fifo */
+#define    FIFO_RCV_RST     0x02    /* reset receive fifo */
+#define    FIFO_XMT_RST     0x04    /* reset transmit fifo */
+#define    FIFO_DMA_MODE    0x08    /* enable dma mode */
+#define    FIFO_TRIGGER_1   0x00    /* trigger at 1 char */
+#define    FIFO_TRIGGER_4   0x40    /* trigger at 4 chars */
+#define    FIFO_TRIGGER_8   0x80    /* trigger at 8 chars */
+#define    FIFO_TRIGGER_14  0xc0    /* trigger at 14 chars */
 
-// 线路控制寄存器
 /* character format control register */
-#define	CFCR_DLAB	0x80	/* divisor latch */
-#define	CFCR_SBREAK	0x40	/* send break */
-#define	CFCR_PZERO	0x30	/* zero parity */
-#define	CFCR_PONE	0x20	/* one parity */
-#define	CFCR_PEVEN	0x10	/* even parity */
-#define	CFCR_PODD	0x00	/* odd parity */
-#define	CFCR_PENAB	0x08	/* parity enable */
-#define	CFCR_STOPB	0x04	/* 2 stop bits */
-#define	CFCR_8BITS	0x03	/* 8 data bits */
-#define	CFCR_7BITS	0x02	/* 7 data bits */
-#define	CFCR_6BITS	0x01	/* 6 data bits */
-#define	CFCR_5BITS	0x00	/* 5 data bits */
+#define    CFCR_DLAB        0x80    /* divisor latch */
+#define    CFCR_SBREAK      0x40    /* send break */
+#define    CFCR_PZERO       0x30    /* zero parity */
+#define    CFCR_PONE        0x20    /* one parity */
+#define    CFCR_PEVEN       0x10    /* even parity */
+#define    CFCR_PODD        0x00    /* odd parity */
+#define    CFCR_PENAB       0x08    /* parity enable */
+#define    CFCR_STOPB       0x04    /* 2 stop bits */
+#define    CFCR_8BITS       0x03    /* 8 data bits */
+#define    CFCR_7BITS       0x02    /* 7 data bits */
+#define    CFCR_6BITS       0x01    /* 6 data bits */
+#define    CFCR_5BITS       0x00    /* 5 data bits */
 
 /* modem control register */
-#define	MCR_LOOPBACK	0x10	/* loopback */
-#define	MCR_IENABLE	0x08	/* output 2 = int enable */
-#define	MCR_DRS		0x04	/* output 1 = xxx */
-#define	MCR_RTS		0x02	/* enable RTS */
-#define	MCR_DTR		0x01	/* enable DTR */
+#define    MCR_LOOPBACK     0x10    /* loopback */
+#define    MCR_IENABLE      0x08    /* output 2 = int enable */
+#define    MCR_DRS          0x04    /* output 1 = xxx */
+#define    MCR_RTS          0x02    /* enable RTS */
+#define    MCR_DTR          0x01    /* enable DTR */
 
 /* line status register */
-#define	LSR_RCV_FIFO	0x80	/* error in receive fifo */
-#define	LSR_TSRE	0x40	/* transmitter empty */
-#define	LSR_TXRDY	0x20	/* transmitter ready */
-#define	LSR_BI		0x10	/* break detected */
-#define	LSR_FE		0x08	/* framing error */
-#define	LSR_PE		0x04	/* parity error */
-#define	LSR_OE		0x02	/* overrun error */
-#define	LSR_RXRDY	0x01	/* receiver ready */
-#define	LSR_RCV_MASK	0x1f
+#define    LSR_RCV_FIFO     0x80    /* error in receive fifo */
+#define    LSR_TSRE         0x40    /* transmitter empty */
+#define    LSR_TXRDY        0x20    /* transmitter ready */
+#define    LSR_BI           0x10    /* break detected */
+#define    LSR_FE           0x08    /* framing error */
+#define    LSR_PE           0x04    /* parity error */
+#define    LSR_OE           0x02    /* overrun error */
+#define    LSR_RXRDY        0x01    /* receiver ready */
+#define    LSR_RCV_MASK     0x1f
 
 
 /* UART interrupt enable register value */
-#define UARTIER_IME		(1 << 3)
-#define UARTIER_ILE		(1 << 2)
-#define UARTIER_ITXE	(1 << 1)
-#define UARTIER_IRXE	(1 << 0)
+#define UARTIER_IME       (1 << 3)
+#define UARTIER_ILE       (1 << 2)
+#define UARTIER_ITXE      (1 << 1)
+#define UARTIER_IRXE      (1 << 0)
 
 /* UART line control register value */
-#define UARTLCR_DLAB	(1 << 7)
-#define UARTLCR_BCB		(1 << 6)
-#define UARTLCR_SPB		(1 << 5)
-#define UARTLCR_EPS		(1 << 4)
-#define UARTLCR_PE		(1 << 3)
-#define UARTLCR_SB		(1 << 2)
+#define UARTLCR_DLAB      (1 << 7)
+#define UARTLCR_BCB       (1 << 6)
+#define UARTLCR_SPB       (1 << 5)
+#define UARTLCR_EPS       (1 << 4)
+#define UARTLCR_PE        (1 << 3)
+#define UARTLCR_SB        (1 << 2)
 
 /* UART line status register value */
-#define UARTLSR_ERROR	(1 << 7)
-#define UARTLSR_TE		(1 << 6)
-#define UARTLSR_TFE		(1 << 5)
-#define UARTLSR_BI		(1 << 4)
-#define UARTLSR_FE		(1 << 3)
-#define UARTLSR_PE		(1 << 2)
-#define UARTLSR_OE		(1 << 1)
-#define UARTLSR_DR		(1 << 0)
+#define UARTLSR_ERROR     (1 << 7)
+#define UARTLSR_TE        (1 << 6)
+#define UARTLSR_TFE       (1 << 5)
+#define UARTLSR_BI        (1 << 4)
+#define UARTLSR_FE        (1 << 3)
+#define UARTLSR_PE        (1 << 2)
+#define UARTLSR_OE        (1 << 1)
+#define UARTLSR_DR        (1 << 0)
 
 #endif

+ 13 - 13
bsp/ls2kdev/drivers/interrupt.h

@@ -64,22 +64,22 @@
 #define LS2K_GPIO2_INT_IRQ          (62)
 #define LS2K_GPIO3_INT_IRQ          (63)
 
-#define MAX_INTR 64
-#define LIOINTC0_IRQBASE 0
-#define LIOINTC1_IRQBASE 32
+#define MAX_INTR                    (64)
+#define LIOINTC0_IRQBASE            (0)
+#define LIOINTC1_IRQBASE            (32)
 
-#define LIOINTC_SHIFT_INTx 4
-#define LIOINTC_COREx_INTy(x, y)   ((1 << x) | (1 << (y + LIOINTC_SHIFT_INTx)))
+#define LIOINTC_SHIFT_INTx          (4)
+#define LIOINTC_COREx_INTy(x, y)    ((1 << x) | (1 << (y + LIOINTC_SHIFT_INTx)))
 
-#define LIOINTC_INTC_CHIP_START	    0x20
+#define LIOINTC_INTC_CHIP_START      0x20
 
-#define LIOINTC_REG_INTC_STATUS	    (LIOINTC_INTC_CHIP_START + 0x00)
-#define LIOINTC_REG_INTC_EN_STATUS	(LIOINTC_INTC_CHIP_START + 0x04)
-#define LIOINTC_REG_INTC_ENABLE	    (LIOINTC_INTC_CHIP_START + 0x08)
-#define LIOINTC_REG_INTC_DISABLE	(LIOINTC_INTC_CHIP_START + 0x0c)
-#define LIOINTC_REG_INTC_POL	    (LIOINTC_INTC_CHIP_START + 0x10)
-#define LIOINTC_REG_INTC_EDGE	    (LIOINTC_INTC_CHIP_START + 0x14)
+#define LIOINTC_REG_INTC_STATUS      (LIOINTC_INTC_CHIP_START + 0x00)
+#define LIOINTC_REG_INTC_EN_STATUS   (LIOINTC_INTC_CHIP_START + 0x04)
+#define LIOINTC_REG_INTC_ENABLE      (LIOINTC_INTC_CHIP_START + 0x08)
+#define LIOINTC_REG_INTC_DISABLE     (LIOINTC_INTC_CHIP_START + 0x0c)
+#define LIOINTC_REG_INTC_POL         (LIOINTC_INTC_CHIP_START + 0x10)
+#define LIOINTC_REG_INTC_EDGE        (LIOINTC_INTC_CHIP_START + 0x14)
 
 void liointc_set_irq_mode(int irq, int mode);
 
-#endif
+#endif

+ 8 - 8
bsp/ls2kdev/drivers/ls2k1000.h

@@ -6,11 +6,11 @@
 
 #define APB_BASE         CKSEG1ADDR(0xbfe00000)
 
-#define UART0_BASE_ADDR 0xbfe00000
-#define UART0_OFF   0x0
-#define UART0_BASE CKSEG1ADDR(UART0_BASE_ADDR + UART0_OFF)
+#define UART0_BASE_ADDR  (0xbfe00000)
+#define UART0_OFF        (0x0)
+#define UART0_BASE       CKSEG1ADDR(UART0_BASE_ADDR + UART0_OFF)
 
-#define UARTx_BASE(x)   ((APB_BASE | (0x0 << 12) | (x << 8)))
+#define UARTx_BASE(x)    ((APB_BASE | (0x0 << 12) | (x << 8)))
 
 #define LIOINTC0_BASE    CKSEG1ADDR(0x1fe11400)
 #define CORE0_INTISR0    CKSEG1ADDR(0x1fe11040)
@@ -18,11 +18,11 @@
 #define LIOINTC1_BASE    CKSEG1ADDR(0x1fe11440)
 #define CORE0_INTISR1    CKSEG1ADDR(0x1fe11048)
 
-#define GPIO_BASE    0xFFFFFFFFBFE10500
-#define PLL_SYS_BASE 0xFFFFFFFFBFE10480
-#define RTC_BASE 0xFFFFFFFFBFE07820
+#define GPIO_BASE        (0xFFFFFFFFBFE10500)
+#define PLL_SYS_BASE     (0xFFFFFFFFBFE10480)
+#define RTC_BASE         (0xFFFFFFFFBFE07820)
 
-#define GEN_CONFIG0_REG 0xFFFFFFFFBfe10420
+#define GEN_CONFIG0_REG  (0xFFFFFFFFBfe10420)
 
 void rt_hw_timer_handler(void);
 void rt_hw_uart_init(void);

+ 16 - 0
bsp/ls2kdev/drivers/net/SConscript

@@ -0,0 +1,16 @@
+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')

+ 132 - 0
bsp/ls2kdev/drivers/net/mii.c

@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2006-2020, 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;
+}

+ 229 - 0
bsp/ls2kdev/drivers/net/mii.h

@@ -0,0 +1,229 @@
+/*
+ * 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

+ 961 - 0
bsp/ls2kdev/drivers/net/synopGMAC.c

@@ -0,0 +1,961 @@
+/*
+ * 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_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
+    return 0;
+}
+INIT_COMPONENT_EXPORT(rt_hw_eth_init);

+ 23 - 0
bsp/ls2kdev/drivers/net/synopGMAC.h

@@ -0,0 +1,23 @@
+/*
+ * 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*/

+ 3721 - 0
bsp/ls2kdev/drivers/net/synopGMAC_Dev.c

@@ -0,0 +1,3721 @@
+/*
+ * 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

+ 1717 - 0
bsp/ls2kdev/drivers/net/synopGMAC_Dev.h

@@ -0,0 +1,1717 @@
+/*
+ * 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 */

+ 60 - 0
bsp/ls2kdev/drivers/net/synopGMAC_Host.h

@@ -0,0 +1,60 @@
+/*
+ * 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

+ 22 - 0
bsp/ls2kdev/drivers/net/synopGMAC_debug.h

@@ -0,0 +1,22 @@
+/*
+ * 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__*/

+ 65 - 0
bsp/ls2kdev/drivers/net/synopGMAC_network_interface.h

@@ -0,0 +1,65 @@
+/*
+ * 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 */

+ 130 - 0
bsp/ls2kdev/drivers/net/synopGMAC_plat.c

@@ -0,0 +1,130 @@
+/*
+ * 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;
+}

+ 242 - 0
bsp/ls2kdev/drivers/net/synopGMAC_plat.h

@@ -0,0 +1,242 @@
+/*
+ * 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

+ 23 - 0
bsp/ls2kdev/drivers/net/synopGMAC_types.h

@@ -0,0 +1,23 @@
+/*
+ * 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*/

+ 83 - 13
bsp/ls2kdev/rtconfig.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

+ 5 - 1
components/net/Kconfig

@@ -118,7 +118,7 @@ config RT_USING_LWIP
             config RT_USING_LWIP202
                 bool "lwIP v2.0.2"
 
-	    config RT_USING_LWIP212
+        config RT_USING_LWIP212
                 bool "lwIP v2.1.2"
 
         endchoice
@@ -131,6 +131,10 @@ config RT_USING_LWIP
                 select NETDEV_IPV6_SCOPES if RT_USING_LWIP212
         endif
 
+        config RT_LWIP_MEM_ALIGNMENT
+            int "Memory alignment"
+            default 4
+
         config RT_LWIP_IGMP
             bool "IGMP protocol"
             default y

+ 2 - 2
components/net/lwip-2.0.2/src/arch/sys_arch.c

@@ -460,7 +460,7 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg)
 {
     RT_DEBUG_NOT_IN_INTERRUPT;
 
-    rt_mb_send_wait(*mbox, (rt_uint32_t)msg, RT_WAITING_FOREVER);
+    rt_mb_send_wait(*mbox, (rt_ubase_t)msg, RT_WAITING_FOREVER);
 
     return;
 }
@@ -472,7 +472,7 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg)
  */
 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
 {
-    if (rt_mb_send(*mbox, (rt_uint32_t)msg) == RT_EOK)
+    if (rt_mb_send(*mbox, (rt_ubase_t)msg) == RT_EOK)
         return ERR_OK;
 
     return ERR_MEM;

+ 5 - 0
components/net/lwip-2.0.2/src/lwipopts.h

@@ -230,7 +230,12 @@
 #define LWIP_DBG_TYPES_ON           (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
 
 /* ---------- Memory options ---------- */
+#ifdef RT_LWIP_MEM_ALIGNMENT
+#define MEM_ALIGNMENT RT_LWIP_MEM_ALIGNMENT
+#else
 #define MEM_ALIGNMENT               4
+#endif
+
 #define MEMP_OVERFLOW_CHECK         1 ////
 #define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 1 ////
 //#define MEM_LIBC_MALLOC             1

+ 10 - 9
components/net/lwip-2.0.2/src/netif/ethernetif.c

@@ -38,6 +38,7 @@
  *                             after lwIP initialization.
  * 2013-02-28     aozima       fixed list_tcps bug: ipaddr_ntoa isn't reentrant.
  * 2016-08-18     Bernard      port to lwIP 2.0.0
+ * 2020-08-10     lizhirui     fixed some problems when this is running on 64-bit cpu
  */
 
 #include "lwip/opt.h"
@@ -85,10 +86,10 @@ struct eth_tx_msg
 static struct rt_mailbox eth_tx_thread_mb;
 static struct rt_thread eth_tx_thread;
 #ifndef RT_LWIP_ETHTHREAD_MBOX_SIZE
-static char eth_tx_thread_mb_pool[32 * 4];
+static char eth_tx_thread_mb_pool[32 * sizeof(rt_ubase_t)];
 static char eth_tx_thread_stack[512];
 #else
-static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
+static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * sizeof(rt_ubase_t)];
 static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
 #endif
 #endif
@@ -97,10 +98,10 @@ static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
 static struct rt_mailbox eth_rx_thread_mb;
 static struct rt_thread eth_rx_thread;
 #ifndef RT_LWIP_ETHTHREAD_MBOX_SIZE
-static char eth_rx_thread_mb_pool[48 * 4];
+static char eth_rx_thread_mb_pool[48 * sizeof(rt_ubase_t)];
 static char eth_rx_thread_stack[1024];
 #else
-static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
+static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * sizeof(rt_ubase_t)];
 static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
 #endif
 #endif
@@ -395,7 +396,7 @@ static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
     /* send a message to eth tx thread */
     msg.netif = netif;
     msg.buf   = p;
-    if (rt_mb_send(&eth_tx_thread_mb, (rt_uint32_t) &msg) == RT_EOK)
+    if (rt_mb_send(&eth_tx_thread_mb, (rt_ubase_t) &msg) == RT_EOK)
     {
         /* waiting for ack */
         rt_sem_take(&(enetif->tx_ack), RT_WAITING_FOREVER);
@@ -599,7 +600,7 @@ rt_err_t eth_device_ready(struct eth_device* dev)
 {
     if (dev->netif)
         /* post message to Ethernet thread */
-        return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+        return rt_mb_send(&eth_rx_thread_mb, (rt_ubase_t)dev);
     else
         return ERR_OK; /* netif is not initialized yet, just return. */
 }
@@ -619,7 +620,7 @@ rt_err_t eth_device_linkchange(struct eth_device* dev, rt_bool_t up)
     rt_hw_interrupt_enable(level);
 
     /* post message to ethernet thread */
-    return rt_mb_send(&eth_rx_thread_mb, (rt_uint32_t)dev);
+    return rt_mb_send(&eth_rx_thread_mb, (rt_ubase_t)dev);
 }
 #else
 /* NOTE: please not use it in interrupt when no RxThread exist */
@@ -739,7 +740,7 @@ int eth_system_device_init_private(void)
 #ifndef LWIP_NO_RX_THREAD
     /* initialize mailbox and create Ethernet Rx thread */
     result = rt_mb_init(&eth_rx_thread_mb, "erxmb",
-                        &eth_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4,
+                        &eth_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/sizeof(rt_ubase_t),
                         RT_IPC_FLAG_FIFO);
     RT_ASSERT(result == RT_EOK);
 
@@ -755,7 +756,7 @@ int eth_system_device_init_private(void)
 #ifndef LWIP_NO_TX_THREAD
     /* initialize mailbox and create Ethernet Tx thread */
     result = rt_mb_init(&eth_tx_thread_mb, "etxmb",
-                        &eth_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4,
+                        &eth_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/sizeof(rt_ubase_t),
                         RT_IPC_FLAG_FIFO);
     RT_ASSERT(result == RT_EOK);
 

+ 6 - 6
components/net/uip/rt-thread/uip_ethernetif.c

@@ -63,11 +63,11 @@ static struct rt_mailbox eth_rx_thread_mb;
 static struct rt_thread eth_rx_thread;
 #ifndef RT_LWIP_ETHTHREAD_PRIORITY
 #define RT_ETHERNETIF_THREAD_PREORITY	0x90
-static char eth_rx_thread_mb_pool[48 * 4];
+static char eth_rx_thread_mb_pool[48 * sizeof(rt_ubase_t)];
 static char eth_rx_thread_stack[1024];
 #else
 #define RT_ETHERNETIF_THREAD_PREORITY	RT_LWIP_ETHTHREAD_PRIORITY
-static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
+static char eth_rx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * sizeof(rt_ubase_t)];
 static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
 #endif
 
@@ -79,10 +79,10 @@ struct eth_tx_msg
 static struct rt_mailbox eth_tx_thread_mb;
 static struct rt_thread eth_tx_thread;
 #ifndef RT_LWIP_ETHTHREAD_PRIORITY
-static char eth_tx_thread_mb_pool[32 * 4];
+static char eth_tx_thread_mb_pool[32 * sizeof(rt_ubase_t)];
 static char eth_tx_thread_stack[512];
 #else
-static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * 4];
+static char eth_tx_thread_mb_pool[RT_LWIP_ETHTHREAD_MBOX_SIZE * sizeof(rt_ubase_t)];
 static char eth_tx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
 #endif
 
@@ -281,7 +281,7 @@ rt_err_t eth_system_device_init()
 	/* init rx thread */
 	/* init mailbox and create ethernet thread */
 	result = rt_mb_init(&eth_rx_thread_mb, "erxmb",
-		&eth_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/4,
+		&eth_rx_thread_mb_pool[0], sizeof(eth_rx_thread_mb_pool)/sizeof(rt_ubase_t),
 		RT_IPC_FLAG_FIFO);
 	RT_ASSERT(result == RT_EOK);
 
@@ -297,7 +297,7 @@ rt_err_t eth_system_device_init()
 	/* init mailbox and create ethernet thread */
         
 	result = rt_mb_init(&eth_tx_thread_mb, "etxmb",
-		&eth_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/4,
+		&eth_tx_thread_mb_pool[0], sizeof(eth_tx_thread_mb_pool)/sizeof(rt_ubase_t),
 		RT_IPC_FLAG_FIFO);
 	RT_ASSERT(result == RT_EOK);
 

+ 4 - 0
libcpu/Kconfig

@@ -82,6 +82,10 @@ config ARCH_MIPS
 
 config ARCH_MIPS64
     bool
+	select ARCH_CPU_64BIT
+	
+config ARCH_CPU_64BIT
+		bool
 
 config ARCH_MIPS_XBURST
     bool

+ 11 - 10
libcpu/mips/common/context_gcc.S

@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2019-12-04     Jiaxun Yang  Initial version
+ * 2020-07-26     lizhirui     Fixed some problems
  */
 
 #ifndef __ASSEMBLY__
@@ -56,12 +57,12 @@ rt_hw_context_switch_interrupt:
     bnez    t1, _reswitch
     nop
     li      t1, 0x01                       /* set rt_thread_switch_interrupt_flag to 1 */
-    sw      t1, 0(t0)
+    LONG_S      t1, 0(t0)
     PTR_LA      t0, rt_interrupt_from_thread   /* set rt_interrupt_from_thread */
-    sw      a0, 0(t0)
+    LONG_S      a0, 0(t0)
 _reswitch:
     PTR_LA      t0, rt_interrupt_to_thread     /* set rt_interrupt_to_thread */
-    sw      a1, 0(t0)
+    LONG_S      a1, 0(t0)
     jr      ra
     nop
 
@@ -97,24 +98,24 @@ mips_irq_handle:
     * rt_hw_context_switch_interrupt_do and do not return
     */
     PTR_LA  k0, rt_thread_switch_interrupt_flag
-    lw      k1, 0(k0)
+    LONG_L  k1, 0(k0)
     beqz    k1, spurious_interrupt
     nop
-    sw      zero, 0(k0)                     /* clear flag */
+    LONG_S  zero, 0(k0)                     /* clear flag */
     nop
 
     /*
     * switch to the new thread
     */
     PTR_LA  k0, rt_interrupt_from_thread
-    lw      k1, 0(k0)
+    LONG_L  k1, 0(k0)
     nop
-    sw      sp, 0(k1)                       /* store sp in preempted task TCB */
+    LONG_S  sp, 0(k1)                       /* store sp in preempted task TCB */
 
     PTR_LA  k0, rt_interrupt_to_thread
-    lw      k1, 0(k0)
+    LONG_L  k1, 0(k0)
     nop
-    lw      sp, 0(k1)                       /* get new task stack pointer */
+    LONG_L  sp, 0(k1)                       /* get new task stack pointer */
     j       spurious_interrupt
     nop
 

+ 44 - 4
libcpu/mips/common/exception.c

@@ -24,6 +24,41 @@ rt_ubase_t rt_interrupt_from_thread;
 rt_ubase_t rt_interrupt_to_thread;
 rt_ubase_t rt_thread_switch_interrupt_flag;
 
+const char *exception_name[] = {
+                                "Interrupt",
+                                "(X)TLB Modify Exception",
+                                "(X)TLB Read/Fetch Exception",
+                                "(X)TLB Write Exception",
+                                "Address Read/Fetch Exception",
+                                "Address Write Exception",
+                                "",
+                                "",
+                                "Syscall",
+                                "Breakpoint",
+                                "Reversed Instruction Exception",
+                                "Coprocessor Unit Invalid",
+                                "Overflow",
+                                "Trap",
+                                "FPU Exception in Vector Instruction",
+                                "FPU Exception",
+                                "Loongson Custom Exception",
+                                "",
+                                "",
+                                "(X)TLB Read Denied Exception",
+                                "(X)TLB Execute Denied Exception",
+                                "Vector Module Disabled Exception",
+                                "",
+                                "",
+                                "",
+                                "",
+                                "",
+                                "",
+                                "",
+                                "",
+                                "Cache Error Exception",
+                                ""
+                                };
+
 rt_base_t rt_hw_interrupt_disable(void)
 {
     rt_base_t status = read_c0_status();
@@ -87,10 +122,15 @@ void cache_error_handler(void)
 
 static void unhandled_exception_handle(struct pt_regs *regs)
 {
-    rt_kprintf("Unknown Exception, EPC: 0x%08x, CAUSE: 0x%08x\n", read_c0_epc(),
-               read_c0_cause());
-    rt_kprintf("ST0: 0x%08x ", regs->cp0_status);
-    rt_kprintf("ErrorPC: 0x%08x\n", read_c0_errorepc());
+    rt_kprintf("Unknown Exception, EPC: 0x%p, CAUSE: 0x%08x\n", read_c0_epc(), read_c0_cause());
+    rt_kprintf("Exception Name:%s\n",exception_name[(read_c0_cause() >> 2) & 0x1f]);
+#ifdef SOC_LS2K1000
+    rt_kprintf("ExeCode = 0x%08x,BadAddr = 0x%p\n",(read_c0_cause() >> 2) & 0x1f,mmu_tlb_get_bad_vaddr());
+#else
+    rt_kprintf("ExeCode = 0x%08x\n",(read_c0_cause() >> 2) & 0x1f);
+#endif
+    rt_kprintf("ST0: 0x%08x ",regs->cp0_status);
+    rt_kprintf("ErrorPC: 0x%p\n",read_c0_errorepc());
     mips_dump_regs(regs);
     rt_hw_cpu_shutdown();
 }

+ 7 - 1
libcpu/mips/common/exception_gcc.S

@@ -1,11 +1,12 @@
 /*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
  * 2019-12-04     Jiaxun Yang  Initial version
+ * 2020-07-26     lizhirui     Add xtlb exception entry
  */
 #ifndef __ASSEMBLY__
 #define __ASSEMBLY__
@@ -26,6 +27,11 @@ tlb_refill_exception:
     b	_general_exception_handler
     nop
 
+    /* 0x080 - XTLB refill handler */
+    .org ebase_start + 0x080
+    b	_general_exception_handler
+    nop
+
     /* 0x100 - Cache error handler */
     .org ebase_start + 0x100
     j	cache_error_handler

+ 2 - 0
libcpu/mips/common/stackframe.h

@@ -206,6 +206,8 @@
     li	v1, ~(ST0_CU1 | ST0_FR | ST0_IM)
     and	v0, v1
     or	v0, a0
+    li  v1, (ST0_KX | ST0_SX | ST0_UX)
+    or  v0, v1
     mtc0	v0, CP0_STATUS
     LONG_L	v1, PT_EPC(sp)
     MTC0	v1, CP0_EPC

+ 70 - 0
libcpu/mips/gs264/cache.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-03-29     quanzhao     the first version
+ * 2020-07-26     lizhirui     porting to ls2k
+ */
+
+#include <rthw.h>
+#include <rtdef.h>
+
+rt_inline rt_uint64_t rt_cpu_icache_line_size(void)
+{
+    rt_uint64_t ctr;
+    return 4 << (ctr & 0xF);
+}
+
+rt_inline rt_uint64_t rt_cpu_dcache_line_size(void)
+{
+    rt_uint64_t ctr;
+    return 4 << ((ctr >> 16) & 0xF);
+}
+
+void rt_hw_cpu_icache_invalidate(void *addr, int size)
+{
+    rt_uint64_t line_size = rt_cpu_icache_line_size();
+    rt_uint64_t start_addr = (rt_uint64_t)addr;
+    rt_uint64_t end_addr = (rt_uint64_t) addr + size + line_size - 1;
+}
+
+void rt_hw_cpu_dcache_invalidate(void *addr, int size)
+{
+    rt_uint64_t line_size = rt_cpu_dcache_line_size();
+    rt_uint64_t start_addr = (rt_uint64_t)addr;
+    rt_uint64_t end_addr = (rt_uint64_t) addr + size + line_size - 1;
+}
+
+void rt_hw_cpu_dcache_clean(void *addr, int size)
+{
+    rt_uint64_t line_size = rt_cpu_dcache_line_size();
+    rt_uint64_t start_addr = (rt_uint64_t)addr;
+    rt_uint64_t end_addr = (rt_uint64_t) addr + size + line_size - 1;
+}
+
+void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_INVALIDATE)
+        rt_hw_cpu_icache_invalidate(addr, size);
+}
+
+void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
+{
+    if (ops == RT_HW_CACHE_FLUSH)
+        rt_hw_cpu_dcache_clean(addr, size);
+    else if (ops == RT_HW_CACHE_INVALIDATE)
+        rt_hw_cpu_dcache_invalidate(addr, size);
+}
+
+rt_base_t rt_hw_cpu_icache_status(void)
+{
+    return 0;
+}
+
+rt_base_t rt_hw_cpu_dcache_status(void)
+{
+    return 0;
+}

+ 24 - 0
libcpu/mips/gs264/cache.h

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-03-25     quanzhao     the first version
+ */
+#ifndef __CACHE_H__
+#define __CACHE_H__
+
+unsigned long rt_cpu_get_smp_id(void);
+
+void rt_cpu_mmu_disable(void);
+void rt_cpu_mmu_enable(void);
+void rt_cpu_tlb_set(volatile unsigned long*);
+
+void rt_cpu_dcache_clean_flush(void);
+void rt_cpu_icache_flush(void);
+
+void rt_cpu_vector_set_base(unsigned int addr);
+
+#endif

+ 4 - 4
libcpu/mips/gs264/cpuinit_gcc.S

@@ -19,8 +19,8 @@
 
     .globl  rt_cpu_early_init
 rt_cpu_early_init:
-     mfc0	t0, CP0_CONFIG
-     ori	t0, 3
-     mtc0	t0, CP0_CONFIG
+     mfc0    t0, CP0_CONFIG
+     ori     t0, 3
+     mtc0    t0, CP0_CONFIG
      ehb
-     jr	ra
+     jr      ra

+ 222 - 0
libcpu/mips/gs264/mips_mmu.c

@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-07-26     lizhirui     the first version
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "mips.h"
+#include "mips_mmu.h"
+
+void mmu_init()
+{
+    uint32_t status = read_c0_status();
+    status |= 0x07 << 5;//ux = 1,sx = 1,kx = 1
+    write_c0_status(status);
+    
+    mmu_clear_tlb();
+    mmu_clear_itlb();
+}
+
+void mmu_set_cpu_mode(cpu_mode_t cpu_mode)
+{
+    uint32_t status = read_c0_status();
+    status &= ~(0x03 << 3);
+    status |= ((uint32_t)cpu_mode & 0x03) << 3;
+    write_c0_status(status);
+}
+
+cpu_mode_t mmu_get_cpu_mode()
+{
+    uint32_t status = read_c0_status();
+    return (cpu_mode_t)((status >> 3) & 0x03);
+}
+
+void mmu_clear_tlb()
+{
+    uint32_t max_tlb_index = mmu_get_max_tlb_index();
+    uint64_t va = KSEG0BASE;
+    uint32_t entry;
+    tlb_item_t tlb_item;
+
+    for(entry = 0;entry <= max_tlb_index;entry++)
+    {
+        mmu_tlb_item_init(&tlb_item);
+        mmu_tlb_write_indexed(entry,&tlb_item);
+    }
+}
+
+void mmu_clear_itlb()
+{
+    uint32_t diag = read_c0_diag();
+    write_c0_diag(diag | (0x01 << 2));//write ITLB bit
+    read_c0_entrylo0();
+}
+
+uint32_t mmu_get_max_tlb_index()
+{
+    uint32_t config1 = read_c0_config1();
+    return ((config1 >> 25) & 0x3F);
+}
+
+void mmu_tlb_write_indexed(uint32_t index,tlb_item_t *tlb_item)
+{
+    tlb_item -> entry_lo[0].g |= tlb_item -> entry_lo[1].g;
+    tlb_item -> entry_lo[1].g |= tlb_item -> entry_lo[0].g;
+    mmu_tlb_set_index(index);
+    write_c0_entrylo0(reg_type_convert(tlb_item -> entry_lo[0],uint64_t));
+    write_c0_entrylo1(reg_type_convert(tlb_item -> entry_lo[1],uint64_t));
+    write_c0_entryhi(reg_type_convert(tlb_item -> entry_hi,uint64_t));
+    write_c0_pagemask(reg_type_convert(tlb_item -> page_mask,uint64_t));
+    tlb_write_indexed();
+    read_c0_entrylo0();
+}
+
+void mmu_tlb_write_random(tlb_item_t *tlb_item)
+{
+    tlb_item -> entry_lo[0].g |= tlb_item -> entry_lo[1].g;
+    tlb_item -> entry_lo[1].g |= tlb_item -> entry_lo[0].g;
+    write_c0_entrylo0(reg_type_convert(tlb_item -> entry_lo[0],uint64_t));
+    write_c0_entrylo1(reg_type_convert(tlb_item -> entry_lo[1],uint64_t));
+    write_c0_entryhi(reg_type_convert(tlb_item -> entry_hi,uint64_t));
+    write_c0_pagemask(reg_type_convert(tlb_item -> page_mask,uint64_t));
+    tlb_write_random();
+    read_c0_entrylo0();
+}
+
+void mmu_tlb_read(uint32_t index,tlb_item_t *tlb_item)
+{
+    mmu_tlb_set_index(index);
+    tlb_read();
+    uint64_t entrylo[2];
+    uint64_t entryhi;
+    uint64_t page_mask;
+    entrylo[0] = read_c0_entrylo0();
+    entrylo[1] = read_c0_entrylo1();
+    entryhi = read_c0_entryhi();
+    page_mask = read_c0_pagemask();
+    tlb_item -> entry_lo[0] = reg_type_convert(entrylo[0],entry_lo_t);
+    tlb_item -> entry_lo[1] = reg_type_convert(entrylo[1],entry_lo_t);
+    tlb_item -> entry_hi = reg_type_convert(entryhi,entry_hi_t);
+    tlb_item -> page_mask = reg_type_convert(page_mask,page_mask_t);
+}
+
+uint32_t mmu_tlb_find(uint64_t vpn,uint32_t asid,uint32_t *index)
+{
+    entry_hi_t entry_hi;
+    entry_hi.r = (vpn >> 62) & 0x03;
+    entry_hi.vpn2 = (vpn >> 13) & 0x7FFFFFFU;
+    entry_hi.asid = asid & 0xFFU;
+    tlb_item_t tlb_item;
+    //mmu_tlb_read(6,&tlb_item);
+    //tlb_dump();
+    mmu_tlb_item_init(&tlb_item);
+    tlb_item.entry_lo[0].g = tlb_item.entry_lo[1].g = 1;
+    read_c0_entrylo0();//i don't know why,but if i don't read any register of mmu,tplb will be failed in qemu.
+    write_c0_entrylo0(reg_type_convert(tlb_item.entry_lo[0],uint64_t));
+    write_c0_entrylo1(reg_type_convert(tlb_item.entry_lo[1],uint64_t));
+    write_c0_entryhi(reg_type_convert(entry_hi,uint64_t));
+    //__asm__ __volatile__("ehb");
+    //read_c0_entryhi();
+    //rt_kprintf("entry_hi = %p\n",read_c0_entryhi());
+    tlb_probe();
+    *index = mmu_tlb_get_index();
+    return mmu_tlb_is_matched();
+}
+
+void mmu_tlb_item_init(tlb_item_t *tlb_item)
+{
+    memset(tlb_item,0,sizeof(tlb_item_t));
+    tlb_item -> entry_lo[0].c = 0x03;
+    tlb_item -> entry_lo[1].c = 0x03;
+}
+
+void mmu_set_map(uint64_t vpn,uint64_t ppn,page_mask_enum_t page_mask,uint32_t asid,uint32_t global)
+{
+    uint64_t page_mask_v = (uint64_t)page_mask;
+
+    /*if(page_mask_v & (1 << 13))
+    {
+        page_mask_v |= (1 << 12);
+    }*/
+
+    uint64_t lb = lowbit((~(page_mask_v)) << 12);
+    uint64_t pn_remained = ((~(page_mask_v)) << 12) | lb;
+    vpn &= pn_remained;
+    ppn &= pn_remained;
+    uint64_t odd_vpn = vpn | lb;
+    uint64_t even_vpn = vpn & (~lb);
+    uint32_t index;
+    tlb_item_t tlb_item,tlb2_item;
+    
+    mmu_tlb_item_init(&tlb_item);
+    mmu_tlb_item_init(&tlb2_item);
+    tlb_item.page_mask.mask = page_mask;
+
+    if(mmu_tlb_find(vpn & (~lb),asid,&index))
+    {
+        mmu_tlb_read(index,&tlb_item);
+        mmu_tlb_write_indexed(index,&tlb2_item);
+    }
+
+    entry_lo_t *entry_lo = &tlb_item.entry_lo[vpn == even_vpn ? 0 : 1];
+    tlb_item.entry_lo[0].g = tlb_item.entry_lo[1].g = global;
+    entry_lo -> d = 1;
+    entry_lo -> ri = 0;
+    entry_lo -> xi = 0;
+    entry_lo -> v = 1;
+    entry_lo -> pfn = ppn >> 12;
+    tlb_item.entry_hi.r = (vpn >> 62) & 0x03;
+    tlb_item.entry_hi.vpn2 = (vpn >> 13) & 0x7FFFFFFU;
+    tlb_item.entry_hi.asid = asid & 0xFFU;
+    mmu_tlb_write_random(&tlb_item);
+}
+
+uint32_t mmu_tlb_get_random()
+{
+    return read_c0_random();
+}
+
+uint32_t mmu_tlb_get_index()
+{
+    return read_c0_index() & 0x3F;
+}
+
+void mmu_tlb_set_index(uint32_t index)
+{
+    write_c0_index(index & 0x3F);
+}
+
+uint32_t mmu_tlb_is_matched()
+{
+    return (read_c0_index() & 0x80000000) == 0;
+}
+
+uint64_t mmu_tlb_get_bad_vaddr()
+{
+    return read_c0_badvaddr();
+}
+
+void tlb_dump()
+{
+    uint32_t max_index = mmu_get_max_tlb_index();
+    //uint32_t max_index = 10;
+    uint32_t entry;
+    tlb_item_t tlb_item;
+
+    for(entry = 0;entry <= max_index;entry++)
+    {
+        mmu_tlb_read(entry,&tlb_item);
+        //mmu_tlb_write_indexed(entry,&tlb_item);
+        //mmu_tlb_read(entry,&tlb_item);
+        rt_kprintf("vpn = 0x%p,ppn0 = 0x%p,ppn1 = 0x%p\n",(uint64_t)tlb_item.entry_hi.vpn2 << 13 | (uint64_t)tlb_item.entry_hi.asid << 62,(uint64_t)tlb_item.entry_lo[0].pfn << 12,(uint64_t)tlb_item.entry_lo[1].pfn << 12);
+        rt_kprintf("v = %d,d = %d,g = %d,ri = %d,xi = %d,c = %d\n",tlb_item.entry_lo[0].v,tlb_item.entry_lo[0].d,tlb_item.entry_lo[0].g,tlb_item.entry_lo[0].ri,tlb_item.entry_lo[0].xi,tlb_item.entry_lo[0].c);
+        rt_kprintf("v = %d,d = %d,g = %d,ri = %d,xi = %d,c = %d\n",tlb_item.entry_lo[1].v,tlb_item.entry_lo[1].d,tlb_item.entry_lo[1].g,tlb_item.entry_lo[1].ri,tlb_item.entry_lo[1].xi,tlb_item.entry_lo[1].c);
+    }
+}

+ 99 - 0
libcpu/mips/gs264/mips_mmu.h

@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-07-26     lizhirui     the first version
+ */
+#ifndef __MIPS_MMU_H__
+#define __MIPS_MMU_H__
+
+typedef enum cpu_mode_t
+{
+    CPU_MODE_KERNEL = 0x00,
+    CPU_MODE_SUPERVISOR = 0x01,
+    CPU_MODE_USER = 0x02
+}cpu_mode_t;
+
+typedef enum page_mask_enum_t
+{
+    PAGE_MASK_4KB = 0x00,
+    PAGE_MASK_16KB = 0x03,
+    PAGE_MASK_64KB = 0x0F,
+    PAGE_MASK_256KB = 0x3F,
+    PAGE_MASK_1MB = 0xFF,
+    PAGE_MASK_4MB = 0x3FF,
+    PAGE_MASK_16MB = 0xFFF,
+    PAGE_MASK_64MB = 0x3FFF,
+    PAGE_MASK_256MB = 0xFFFF,
+    PAGE_MASK_1GB = 0x3FFFF
+}page_mask_enum_t;
+
+typedef struct page_mask_t
+{
+    uint64_t : 11;
+    uint64_t : 2;
+    uint64_t mask : 18;
+    uint64_t : 33;
+}page_mask_t;
+
+typedef struct entry_lo_t
+{
+    uint64_t g : 1;
+    uint64_t v : 1;
+    uint64_t d : 1;
+    uint64_t c : 3;
+    uint64_t pfn : 24;
+    uint64_t pfnx : 3;
+    uint64_t : 29;
+    uint64_t xi : 1;
+    uint64_t ri : 1;
+}entry_lo_t;
+
+typedef struct entry_hi_t
+{
+    uint64_t asid : 8;
+    uint64_t : 5;
+    uint64_t vpn2 : 27;
+    uint64_t : 22;
+    uint64_t r : 2;
+}entry_hi_t;
+
+typedef struct tlb_item_t
+{
+    entry_lo_t entry_lo[2];
+    entry_hi_t entry_hi;
+    page_mask_t page_mask;
+}tlb_item_t;
+
+#define read_c0_diag()        __read_32bit_c0_register($22, 0)
+#define write_c0_diag(val)    __write_32bit_c0_register($22, 0, val)
+#define read_c0_badvaddr()    __read_64bit_c0_register($8, 0)
+#define read_c0_random()      __read_32bit_c0_register($1, 0)
+
+#define reg_type_convert(variable,new_type) *((new_type *)(&variable))
+#define lowbit(x) ((x) & (-(x)))
+
+void mmu_init();
+void mmu_set_cpu_mode(cpu_mode_t cpu_mode);
+cpu_mode_t mmu_get_cpu_mode();
+void mmu_clear_tlb();
+void mmu_clear_itlb();
+uint32_t mmu_get_max_tlb_index();
+void mmu_tlb_write_indexed(uint32_t index,tlb_item_t *tlb_item);
+void mmu_tlb_write_random(tlb_item_t *tlb_item);
+void mmu_tlb_read(uint32_t index,tlb_item_t *tlb_item);
+uint32_t mmu_tlb_find(uint64_t vpn,uint32_t asid,uint32_t *index);
+void mmu_tlb_item_init(tlb_item_t *tlb_item);
+void mmu_set_map(uint64_t vpn,uint64_t ppn,page_mask_enum_t page_mask,uint32_t asid,uint32_t global);
+uint32_t mmu_tlb_get_random();
+uint32_t mmu_tlb_get_index();
+void mmu_tlb_set_index(uint32_t index);
+uint32_t mmu_tlb_is_matched();
+uint64_t mmu_tlb_get_bad_vaddr();
+
+void tlb_dump();
+
+#endif

+ 79 - 0
libcpu/mips/gs264/mipscfg.c

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-07-28     lizhirui       first version
+ */
+#include <rtthread.h>
+#include <mips.h>
+
+mips32_core_cfg_t g_mips_core =
+{
+    64,        /* icache_line_size */
+    128,       /* icache_lines_per_way */
+    4,         /* icache_ways */
+    32768,
+    64,        /* dcache_line_size */
+    128,       /* dcache_lines_per_way */
+    4,         /* dcache_ways */
+    32768,
+    64,        /* max_tlb_entries */
+};
+
+static rt_uint16_t m_pow(rt_uint16_t b, rt_uint16_t n)
+{
+    rt_uint16_t rets = 1;
+
+    while (n--)
+        rets *= b;
+
+    return rets;
+}
+
+static rt_uint16_t m_log2(rt_uint16_t b)
+{
+    rt_uint16_t rets = 0;
+
+    while (b != 1)
+    {
+        b /= 2;
+        rets++;
+    }
+
+    return rets;
+}
+
+/**
+ * read core attribute
+ */
+void mips32_cfg_init(void)
+{
+    rt_uint16_t val;
+    rt_uint32_t cp0_config1;
+
+    cp0_config1 = read_c0_config();
+    if (cp0_config1 & 0x80000000)
+    {
+        cp0_config1 = read_c0_config1();
+
+        val = (cp0_config1 & (7<<22))>>22;
+        g_mips_core.icache_lines_per_way = 64 * m_pow(2, val);
+        val = (cp0_config1 & (7<<19))>>19;
+        g_mips_core.icache_line_size = 2 * m_pow(2, val);
+        val = (cp0_config1 & (7<<16))>>16;
+        g_mips_core.icache_ways = val + 1;
+
+        val = (cp0_config1 & (7<<13))>>13;
+        g_mips_core.dcache_lines_per_way = 64 * m_pow(2, val);
+        val = (cp0_config1 & (7<<10))>>10;
+        g_mips_core.dcache_line_size = 2 * m_pow(2, val);
+        val = (cp0_config1 & (7<<7))>>7;
+        g_mips_core.dcache_ways = val + 1;
+
+        val = (cp0_config1 & (0x3F<<25))>>25;
+        g_mips_core.max_tlb_entries = val + 1;
+    }
+}

+ 819 - 0
libcpu/mips/gs264/mmu.c

@@ -0,0 +1,819 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-01-10     bernard      porting to AM1808
+ * 2020-07-26     lizhirui     porting to ls2k
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <board.h>
+
+#include "cache.h"
+#include "mips_mmu.h"
+#include "mmu.h"
+
+void *current_mmu_table = RT_NULL;
+
+void *mmu_table_get()
+{
+    return current_mmu_table;
+}
+
+void switch_mmu(void *mmu_table)
+{
+    current_mmu_table = mmu_table;
+
+    mmu_clear_tlb();
+    mmu_clear_itlb();
+}
+
+/* dump 2nd level page table */
+void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
+{
+    int i;
+    int fcnt = 0;
+
+    for (i = 0; i < 256; i++)
+    {
+        rt_uint32_t pte2 = ptb[i];
+        if ((pte2 & 0x3) == 0)
+        {
+            if (fcnt == 0)
+                rt_kprintf("    ");
+            rt_kprintf("%04x: ", i);
+            fcnt++;
+            if (fcnt == 16)
+            {
+                rt_kprintf("fault\n");
+                fcnt = 0;
+            }
+            continue;
+        }
+        if (fcnt != 0)
+        {
+            rt_kprintf("fault\n");
+            fcnt = 0;
+        }
+
+        rt_kprintf("    %04x: %x: ", i, pte2);
+        if ((pte2 & 0x3) == 0x1)
+        {
+            rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
+                       ((pte2 >> 7) | (pte2 >> 4))& 0xf,
+                       (pte2 >> 15) & 0x1,
+                       ((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
+        }
+        else
+        {
+            rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
+                       ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
+                       ((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
+        }
+    }
+}
+
+void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
+{
+    int i;
+    int fcnt = 0;
+
+    rt_kprintf("page table@%p\n", ptb);
+    for (i = 0; i < 1024*4; i++)
+    {
+        rt_uint32_t pte1 = ptb[i];
+        if ((pte1 & 0x3) == 0)
+        {
+            rt_kprintf("%03x: ", i);
+            fcnt++;
+            if (fcnt == 16)
+            {
+                rt_kprintf("fault\n");
+                fcnt = 0;
+            }
+            continue;
+        }
+        if (fcnt != 0)
+        {
+            rt_kprintf("fault\n");
+            fcnt = 0;
+        }
+
+        rt_kprintf("%03x: %08x: ", i, pte1);
+        if ((pte1 & 0x3) == 0x3)
+        {
+            rt_kprintf("LPAE\n");
+        }
+        else if ((pte1 & 0x3) == 0x1)
+        {
+            rt_kprintf("pte,ns:%d,domain:%d\n",
+                       (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
+            /*
+             *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
+             *                               - 0x80000000 + 0xC0000000));
+             */
+        }
+        else if (pte1 & (1 << 18))
+        {
+            rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
+                       (pte1 >> 19) & 0x1,
+                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
+                       (pte1 >> 4) & 0x1,
+                       ((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
+        }
+        else
+        {
+            rt_kprintf("section,ns:%d,ap:%x,"
+                       "xn:%d,texcb:%02x,domain:%d\n",
+                       (pte1 >> 19) & 0x1,
+                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
+                       (pte1 >> 4) & 0x1,
+                       (((pte1 & (0x7 << 12)) >> 10) |
+                        ((pte1 &        0x0c) >>  2)) & 0x1f,
+                       (pte1 >> 5) & 0xf);
+        }
+    }
+}
+
+/* level1 page table, each entry for 1MB memory. */
+volatile unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024)));
+void rt_hw_mmu_setmtt(rt_uint32_t vaddrStart,
+                      rt_uint32_t vaddrEnd,
+                      rt_uint32_t paddrStart,
+                      rt_uint32_t attr)
+{
+    volatile rt_uint32_t *pTT;
+    volatile int i, nSec;
+    pTT  = (rt_uint32_t *)MMUTable + (vaddrStart >> 20);
+    nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
+    for(i = 0; i <= nSec; i++)
+    {
+        *pTT = attr | (((paddrStart >> 20) + i) << 20);
+        pTT++;
+    }
+}
+
+unsigned long rt_hw_set_domain_register(unsigned long domain_val)
+{
+    unsigned long old_domain;
+
+    //asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain));
+    //asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory");
+
+    return old_domain;
+}
+
+void rt_hw_cpu_dcache_clean(void *addr, int size);
+void rt_hw_init_mmu_table(struct mem_desc *mdesc, rt_uint32_t size)
+{
+    /* set page table */
+    for(; size > 0; size--)
+    {
+        rt_hw_mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+                mdesc->paddr_start, mdesc->attr);
+        mdesc++;
+    }
+    rt_hw_cpu_dcache_clean((void*)MMUTable, sizeof MMUTable);
+}
+
+void rt_hw_mmu_init(void)
+{
+    rt_cpu_dcache_clean_flush();
+    rt_cpu_icache_flush();
+    rt_hw_cpu_dcache_disable();
+    rt_hw_cpu_icache_disable();
+    rt_cpu_mmu_disable();
+
+    /*rt_hw_cpu_dump_page_table(MMUTable);*/
+    rt_hw_set_domain_register(0x55555555);
+
+    rt_cpu_tlb_set(MMUTable);
+
+    rt_cpu_mmu_enable();
+
+    rt_hw_cpu_icache_enable();
+    rt_hw_cpu_dcache_enable();
+}
+
+/*
+ mem map
+*/
+
+void rt_hw_cpu_dcache_clean(void *addr, int size);
+
+int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off)
+{
+    size_t l1_off, va_s, va_e;
+    rt_base_t level;
+
+    if (!mmu_info || !vtable)
+    {
+        return -1;
+    }
+
+    va_s = (size_t)v_address;
+    va_e = (size_t)v_address + size - 1;
+
+    if ( va_e < va_s)
+    {
+        return -1;
+    }
+
+    va_s >>= ARCH_SECTION_SHIFT;
+    va_e >>= ARCH_SECTION_SHIFT;
+
+    if (va_s == 0)
+    {
+        return -1;
+    }
+
+    level = rt_hw_interrupt_disable();
+
+    for (l1_off = va_s; l1_off <= va_e; l1_off++)
+    {
+        size_t v = vtable[l1_off];
+
+        if (v & ARCH_MMU_USED_MASK)
+        {
+            rt_kprintf("Error:vtable[%d] = 0x%p(is not zero),va_s = 0x%p,va_e = 0x%p!\n",l1_off,v,va_s,va_e);
+            rt_hw_interrupt_enable(level);
+            return -1;
+        }
+    }
+
+    mmu_info->vtable = vtable;
+    mmu_info->vstart = va_s;
+    mmu_info->vend = va_e;
+    mmu_info->pv_off = pv_off;
+
+    rt_hw_interrupt_enable(level);
+
+    return 0;
+}
+
+static size_t find_vaddr(rt_mmu_info *mmu_info, int pages)
+{
+    size_t l1_off, l2_off;
+    size_t *mmu_l1, *mmu_l2;
+    size_t find_off = 0;
+    size_t find_va = 0;
+    int n = 0;
+
+    if (!pages)
+    {
+        return 0;
+    }
+
+    if (!mmu_info)
+    {
+        return 0;
+    }
+
+    for (l1_off = mmu_info->vstart; l1_off <= mmu_info->vend; l1_off++)
+    {
+        mmu_l1 =  (size_t*)mmu_info->vtable + l1_off;
+        if (*mmu_l1 & ARCH_MMU_USED_MASK)
+        {
+            mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+            for (l2_off = 0; l2_off < (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE); l2_off++)
+            {
+                if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK)
+                {
+                    /* in use */
+                    n = 0;
+                }
+                else
+                {
+                    if (!n)
+                    {
+                        find_va = l1_off;
+                        find_off = l2_off;
+                    }
+                    n++;
+                    if (n >= pages)
+                    {
+                        return (find_va << ARCH_SECTION_SHIFT) + (find_off << ARCH_PAGE_SHIFT);
+                    }
+                }
+            }
+        }
+        else
+        {
+            if (!n)
+            {
+                find_va = l1_off;
+                find_off = 0;
+            }
+            n += (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
+            if (n >= pages)
+            {
+                return (find_va << ARCH_SECTION_SHIFT) + (find_off << ARCH_PAGE_SHIFT);
+            }
+        }
+    }
+    return 0;
+}
+
+#ifdef RT_USING_USERSPACE
+static int check_vaddr(rt_mmu_info *mmu_info, void *va, int pages)
+{
+    size_t loop_va = (size_t)va & ~ARCH_PAGE_MASK;
+    size_t l1_off, l2_off;
+    size_t *mmu_l1, *mmu_l2;
+
+    if (!pages)
+    {
+        return -1;
+    }
+
+    if (!mmu_info)
+    {
+        return -1;
+    }
+
+    while (pages--)
+    {
+        l1_off = (loop_va >> ARCH_SECTION_SHIFT);
+        l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
+        mmu_l1 =  (size_t*)mmu_info->vtable + l1_off;
+
+        if (*mmu_l1 & ARCH_MMU_USED_MASK)
+        {
+            mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+            if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK)
+            {
+                return -1;
+            }
+        }
+        loop_va += ARCH_PAGE_SIZE;
+    }
+    return 0;
+}
+#endif
+
+static void __rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t npages)
+{
+    size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
+    size_t l1_off, l2_off;
+    size_t *mmu_l1, *mmu_l2;
+    size_t *ref_cnt;
+
+    if (!mmu_info)
+    {
+        return;
+    }
+
+    while (npages--)
+    {
+        l1_off = (loop_va >> ARCH_SECTION_SHIFT);
+        if (l1_off < mmu_info->vstart || l1_off > mmu_info->vend)
+        {
+            return;
+        }
+
+        l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
+        mmu_l1 =  (size_t*)mmu_info->vtable + l1_off;
+
+        if (*mmu_l1 & ARCH_MMU_USED_MASK)
+        {
+            mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+        }
+        else
+        {
+            return;
+        }
+
+        if (*(mmu_l2 + l2_off) & ARCH_MMU_USED_MASK) 
+        {
+            *(mmu_l2 + l2_off) = 0;
+            /* cache maintain */
+            rt_hw_cpu_dcache_clean(mmu_l2 + l2_off, 4);
+
+            ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
+            (*ref_cnt)--;
+            if (!*ref_cnt)
+            {
+#ifdef RT_USING_USERSPACE
+                rt_pages_free(mmu_l2, 0);
+#else
+                rt_free_align(mmu_l2);
+#endif
+                *mmu_l1 = 0;
+
+                /* cache maintain */
+                rt_hw_cpu_dcache_clean(mmu_l1, 4);
+            }
+        }
+        loop_va += ARCH_PAGE_SIZE;
+    }
+}
+
+static int __rt_hw_mmu_map(rt_mmu_info *mmu_info, void* v_addr, void* p_addr, size_t npages, size_t attr)
+{
+    size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
+    size_t loop_pa = (size_t)p_addr & ~ARCH_PAGE_MASK;
+    size_t l1_off, l2_off;
+    size_t *mmu_l1, *mmu_l2;
+    size_t *ref_cnt;
+
+    if (!mmu_info)
+    {
+        return -1;
+    }
+
+    while (npages--)
+    {
+        l1_off = (loop_va >> ARCH_SECTION_SHIFT);
+        l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
+        mmu_l1 =  (size_t*)mmu_info->vtable + l1_off;
+
+        if (*mmu_l1 & ARCH_MMU_USED_MASK)
+        {
+            mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+        }
+        else
+        {
+#ifdef RT_USING_USERSPACE
+            mmu_l2 = (size_t*)rt_pages_alloc(0);
+#else
+            mmu_l2 = (size_t*)rt_malloc_align(ARCH_PAGE_TBL_SIZE * 2, ARCH_PAGE_TBL_SIZE);
+#endif
+            if (mmu_l2)
+            {
+                rt_memset(mmu_l2, 0, ARCH_PAGE_TBL_SIZE * 2);
+                /* cache maintain */
+                rt_hw_cpu_dcache_clean(mmu_l2, ARCH_PAGE_TBL_SIZE);
+
+                *mmu_l1 = (((size_t)mmu_l2 + mmu_info->pv_off) | 0x1);
+                /* cache maintain */
+                rt_hw_cpu_dcache_clean(mmu_l1, 4);
+            }
+            else
+            {
+                /* error, unmap and quit */
+                __rt_hw_mmu_unmap(mmu_info, v_addr, npages);
+                return -1;
+            }
+        }
+
+        ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
+        (*ref_cnt)++;
+
+        *(mmu_l2 + l2_off) = (loop_pa | attr);
+        /* cache maintain */
+        rt_hw_cpu_dcache_clean(mmu_l2 + l2_off, 4);
+
+        loop_va += ARCH_PAGE_SIZE;
+        loop_pa += ARCH_PAGE_SIZE;
+    }
+    return 0;
+}
+
+static void rt_hw_cpu_tlb_invalidate(void)
+{
+    mmu_clear_tlb();
+    mmu_clear_itlb();
+}
+
+#ifdef RT_USING_USERSPACE
+void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr)
+{
+    size_t pa_s, pa_e;
+    size_t vaddr;
+    int pages;
+    int ret;
+
+    if (!size)
+    {
+        return 0;
+    }
+    pa_s = (size_t)p_addr;
+    pa_e = (size_t)p_addr + size - 1;
+    pa_s >>= ARCH_PAGE_SHIFT;
+    pa_e >>= ARCH_PAGE_SHIFT;
+    pages = pa_e - pa_s + 1;
+    if (v_addr)
+    {
+        vaddr = (size_t)v_addr;
+        pa_s = (size_t)p_addr;
+        if ((vaddr & ARCH_PAGE_MASK) != (pa_s & ARCH_PAGE_MASK))
+        {
+            return 0;
+        }
+        vaddr &= ~ARCH_PAGE_MASK;
+        if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0)
+        {
+            return 0;
+        }
+    }
+    else
+    {
+        vaddr = find_vaddr(mmu_info, pages);
+    }
+    if (vaddr) {
+        ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr);
+        if (ret == 0)
+        {
+            rt_hw_cpu_tlb_invalidate();
+            return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
+        }
+    }
+    return 0;
+}
+#else
+void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr)
+{
+    size_t pa_s, pa_e;
+    size_t vaddr;
+    int pages;
+    int ret;
+
+    pa_s = (size_t)p_addr;
+    pa_e = (size_t)p_addr + size - 1;
+    pa_s >>= ARCH_PAGE_SHIFT;
+    pa_e >>= ARCH_PAGE_SHIFT;
+    pages = pa_e - pa_s + 1;
+    vaddr = find_vaddr(mmu_info, pages);
+    if (vaddr) {
+        ret = __rt_hw_mmu_map(mmu_info, (void*)vaddr, p_addr, pages, attr);
+        if (ret == 0)
+        {
+            rt_hw_cpu_tlb_invalidate();
+            return (void*)(vaddr + ((size_t)p_addr & ARCH_PAGE_MASK));
+        }
+    }
+    return 0;
+}
+#endif
+
+#ifdef RT_USING_USERSPACE
+static int __rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void* v_addr, size_t npages, size_t attr)
+{
+    size_t loop_va = (size_t)v_addr & ~ARCH_PAGE_MASK;
+    size_t loop_pa;
+    size_t l1_off, l2_off;
+    size_t *mmu_l1, *mmu_l2;
+    size_t *ref_cnt;
+
+    if (!mmu_info)
+    {
+        return -1;
+    }
+
+    while (npages--)
+    {
+        loop_pa = (size_t)rt_pages_alloc(0) + mmu_info->pv_off;
+        if (!loop_pa)
+            goto err;
+
+        //rt_kprintf("vaddr = %08x is mapped to paddr = %08x\n",v_addr,loop_pa);
+        l1_off = (loop_va >> ARCH_SECTION_SHIFT);
+        l2_off = ((loop_va & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
+        mmu_l1 =  (size_t*)mmu_info->vtable + l1_off;
+
+        if (*mmu_l1 & ARCH_MMU_USED_MASK)
+        {
+            mmu_l2 = (size_t *)((*mmu_l1 & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+        }
+        else
+        {
+            //mmu_l2 = (size_t*)rt_malloc_align(ARCH_PAGE_TBL_SIZE * 2, ARCH_PAGE_TBL_SIZE);
+            mmu_l2 = (size_t*)rt_pages_alloc(0);
+            if (mmu_l2)
+            {
+                rt_memset(mmu_l2, 0, ARCH_PAGE_TBL_SIZE * 2);
+                /* cache maintain */
+                rt_hw_cpu_dcache_clean(mmu_l2, ARCH_PAGE_TBL_SIZE);
+
+                *mmu_l1 = (((size_t)mmu_l2 + mmu_info->pv_off) | 0x1);
+                /* cache maintain */
+                rt_hw_cpu_dcache_clean(mmu_l1, 4);
+            }
+            else
+                goto err;
+        }
+
+        ref_cnt = mmu_l2 + (ARCH_SECTION_SIZE/ARCH_PAGE_SIZE);
+        (*ref_cnt)++;
+
+        //loop_pa += mmu_info->pv_off;
+        *(mmu_l2 + l2_off) = (loop_pa | attr);
+        /* cache maintain */
+        rt_hw_cpu_dcache_clean(mmu_l2 + l2_off, 4);
+
+        loop_va += ARCH_PAGE_SIZE;
+    }
+    return 0;
+err:
+    {
+        /* error, unmap and quit */
+        int i;
+        void *va, *pa;
+
+        va = (void*)((size_t)v_addr & ~ARCH_PAGE_MASK);
+        for (i = 0; i < npages; i++)
+        {
+            pa = rt_hw_mmu_v2p(mmu_info, va);
+            pa -= mmu_info->pv_off;
+            rt_pages_free(pa, 0);
+            va += ARCH_PAGE_SIZE;
+        }
+
+        __rt_hw_mmu_unmap(mmu_info, v_addr, npages);
+        return -1;
+    }
+}
+
+void *_rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
+{
+    size_t vaddr;
+    size_t offset;
+    int pages;
+    int ret;
+
+    if (!size)
+    {
+        return 0;
+    }
+    offset = (size_t)v_addr & ARCH_PAGE_MASK;
+    size += (offset + ARCH_PAGE_SIZE - 1);
+    pages = (size >> ARCH_PAGE_SHIFT);
+    if (v_addr)
+    {
+        vaddr = (size_t)v_addr;
+        vaddr &= ~ARCH_PAGE_MASK;
+        if (check_vaddr(mmu_info, (void*)vaddr, pages) != 0)
+        {
+            return 0;
+        }
+    }
+    else
+    {
+        vaddr = find_vaddr(mmu_info, pages);
+    }
+    if (vaddr) {
+        ret = __rt_hw_mmu_map_auto(mmu_info, (void*)vaddr, pages, attr);
+        if (ret == 0)
+        {
+            rt_hw_cpu_tlb_invalidate();
+            return (void*)vaddr + offset;
+        }
+    }
+    return 0;
+}
+#endif
+
+void _rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size)
+{
+    size_t va_s, va_e;
+    int pages;
+
+    va_s = (size_t)v_addr;
+    va_e = (size_t)v_addr + size - 1;
+    va_s >>= ARCH_PAGE_SHIFT;
+    va_e >>= ARCH_PAGE_SHIFT;
+    pages = va_e - va_s + 1;
+    __rt_hw_mmu_unmap(mmu_info, v_addr, pages);
+    rt_hw_cpu_tlb_invalidate();
+}
+
+//va --> pa
+void *rt_hw_kernel_virt_to_phys(void *v_addr, size_t size)
+{
+    void *p_addr = 0;
+
+    return p_addr;
+}
+
+//pa --> va
+void *rt_hw_kernel_phys_to_virt(void *p_addr, size_t size)
+{   
+    void *v_addr = 0;
+
+    #ifdef RT_USING_USERSPACE
+    extern rt_mmu_info mmu_info;
+    v_addr = rt_hw_mmu_map(&mmu_info, 0, p_addr, size, MMU_MAP_K_RW);
+    #else
+    v_addr = p_addr;
+    #endif
+
+    return v_addr;
+}
+
+#ifdef RT_USING_USERSPACE
+void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr)
+{
+    void *ret;
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    ret = _rt_hw_mmu_map(mmu_info, v_addr, p_addr, size, attr);
+    rt_hw_interrupt_enable(level);
+    return ret;
+}
+
+void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr)
+{
+    void *ret;
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    ret = _rt_hw_mmu_map_auto(mmu_info, v_addr, size, attr);
+    rt_hw_interrupt_enable(level);
+    return ret;
+}
+#endif
+
+void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size)
+{
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    _rt_hw_mmu_unmap(mmu_info, v_addr, size);
+    rt_hw_interrupt_enable(level);
+}
+
+void *_rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
+{
+    size_t l1_off, l2_off;
+    size_t *mmu_l1, *mmu_l2;
+    size_t tmp;
+    size_t pa;
+
+    l1_off = (size_t)v_addr >> ARCH_SECTION_SHIFT;
+
+    if (!mmu_info)
+    {
+        return (void*)0;
+    }
+
+    mmu_l1 =  (size_t*)mmu_info->vtable + l1_off;
+
+    tmp = *mmu_l1;
+
+    switch (tmp & ARCH_MMU_USED_MASK)
+    {
+        case 0: /* not used */
+            break;
+        case 1: /* page table */
+            mmu_l2 = (size_t *)((tmp & ~ARCH_PAGE_TBL_MASK) - mmu_info->pv_off);
+            l2_off = (((size_t)v_addr & ARCH_SECTION_MASK) >> ARCH_PAGE_SHIFT);
+            pa = *(mmu_l2 + l2_off);
+            if (pa & ARCH_MMU_USED_MASK)
+            {
+                if ((pa & ARCH_MMU_USED_MASK) == 1)
+                {
+                    /* lage page, not support */
+                    break;
+                }
+                pa &= ~(ARCH_PAGE_MASK);
+                pa += ((size_t)v_addr & ARCH_PAGE_MASK);
+                return (void*)pa;
+            }
+            break;
+        case 2:
+        case 3:
+            /* section */
+            if (tmp & ARCH_TYPE_SUPERSECTION)
+            {
+                /* super section, not support */
+                break;
+            }
+            pa = (tmp & ~ARCH_SECTION_MASK);
+            pa += ((size_t)v_addr & ARCH_SECTION_MASK);
+            return (void*)pa;
+    }
+    return (void*)0;
+}
+
+void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr)
+{
+    void *ret;
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    ret = _rt_hw_mmu_v2p(mmu_info, v_addr);
+    rt_hw_interrupt_enable(level);
+    return ret;
+}
+
+#ifdef RT_USING_USERSPACE
+void init_mm_setup(unsigned int *mtbl, unsigned int size, unsigned int pv_off) {
+    unsigned int va;
+
+    for (va = 0; va < 0x1000; va++) {
+        unsigned int vaddr = (va << 20);
+        if (vaddr >= KERNEL_VADDR_START && vaddr - KERNEL_VADDR_START < size) {
+            mtbl[va] = ((va << 20) + pv_off) | NORMAL_MEM;
+        } else if (vaddr >= (KERNEL_VADDR_START + pv_off) && vaddr - (KERNEL_VADDR_START + pv_off) < size) {
+            mtbl[va] = (va << 20) | NORMAL_MEM;
+        } else {
+            mtbl[va] = 0;
+        }
+    }
+}
+#endif

+ 113 - 0
libcpu/mips/gs264/mmu.h

@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-03-25     quanzhao     the first version
+ * 2020-07-26     lizhirui     porting to ls2k
+ */
+#ifndef __MMU_H_
+#define __MMU_H_
+
+#include <rtthread.h>
+
+#define DESC_SEC       (0x2)
+#define MEMWBWA        ((1<<12)|(3<<2))      /* write back, write allocate */
+#define MEMWB          (3<<2)                /* write back, no write allocate */
+#define MEMWT          (2<<2)                /* write through, no write allocate */
+#define SHAREDEVICE    (1<<2)                /* shared device */
+#define STRONGORDER    (0<<2)                /* strong ordered */
+#define XN             (1<<4)                /* execute Never */
+#ifdef RT_USING_USERSPACE
+#define AP_RW          (1<<10)               /* supervisor=RW, user=No */
+#define AP_RO          ((1<<10) |(1 << 15))  /* supervisor=RW, user=No */
+#else
+#define AP_RW          (3<<10)               /* supervisor=RW, user=RW */
+#define AP_RO          ((2<<10)              /* supervisor=RW, user=RO */
+#endif
+
+#define SHARED         (1<<16)               /* shareable */
+
+#define DOMAIN_FAULT   (0x0)
+#define DOMAIN_CHK     (0x1)
+#define DOMAIN_NOTCHK  (0x3)
+#define DOMAIN0        (0x0<<5)
+#define DOMAIN1        (0x1<<5)
+
+#define DOMAIN0_ATTR   (DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR   (DOMAIN_FAULT<<2)
+
+/* device mapping type */
+#define DEVICE_MEM     (SHARED|AP_RW|DOMAIN0|SHAREDEVICE|DESC_SEC|XN)
+/* normal memory mapping type */
+#define NORMAL_MEM     (SHARED|AP_RW|DOMAIN0|MEMWBWA|DESC_SEC)
+
+#define STRONG_ORDER_MEM (SHARED|AP_RO|XN|DESC_SEC)
+
+struct mem_desc
+{
+    rt_uint32_t vaddr_start;
+    rt_uint32_t vaddr_end;
+    rt_uint32_t paddr_start;
+    rt_uint32_t attr;
+};
+
+#define MMU_MAP_MTBL_XN       (1<<0)
+#define MMU_MAP_MTBL_A        (1<<1)
+#define MMU_MAP_MTBL_B        (1<<2)
+#define MMU_MAP_MTBL_C        (1<<3)
+#define MMU_MAP_MTBL_AP01(x)  (x<<4)
+#define MMU_MAP_MTBL_TEX(x)   (x<<6)
+#define MMU_MAP_MTBL_AP2(x)   (x<<9)
+#define MMU_MAP_MTBL_SHARE    (1<<10)
+
+#define MMU_MAP_K_RO          (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE)
+#define MMU_MAP_K_RWCB        (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE)
+#define MMU_MAP_K_RW          (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE)
+#define MMU_MAP_K_DEVICE      (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(1)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE)
+#define MMU_MAP_U_RO          (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(1)|MMU_MAP_MTBL_AP01(2)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE)
+#define MMU_MAP_U_RWCB        (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_C|MMU_MAP_MTBL_SHARE)
+#define MMU_MAP_U_RW          (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_SHARE)
+#define MMU_MAP_U_DEVICE      (MMU_MAP_MTBL_A|MMU_MAP_MTBL_AP2(0)|MMU_MAP_MTBL_AP01(3)|MMU_MAP_MTBL_TEX(0)|MMU_MAP_MTBL_B|MMU_MAP_MTBL_SHARE)
+
+#define ARCH_SECTION_SHIFT  20
+#define ARCH_SECTION_SIZE   (1 << ARCH_SECTION_SHIFT)
+#define ARCH_SECTION_MASK   (ARCH_SECTION_SIZE - 1)
+#define ARCH_PAGE_SHIFT     14
+#define ARCH_PAGE_SIZE      (1 << ARCH_PAGE_SHIFT)
+#define ARCH_PAGE_MASK      (ARCH_PAGE_SIZE - 1)
+#define ARCH_PAGE_TBL_SHIFT 10
+#define ARCH_PAGE_TBL_SIZE  (1 << ARCH_PAGE_TBL_SHIFT)
+#define ARCH_PAGE_TBL_MASK  (ARCH_PAGE_TBL_SIZE - 1)
+
+#define ARCH_MMU_USED_MASK  3
+
+#define ARCH_TYPE_SUPERSECTION (1 << 18)
+
+typedef struct
+{
+    size_t *vtable;
+    size_t vstart;
+    size_t vend;
+    size_t pv_off;
+} rt_mmu_info;
+
+void *mmu_table_get();
+void switch_mmu(void *mmu_table);
+
+int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void* v_address, size_t size, size_t *vtable, size_t pv_off);
+#ifdef RT_USING_USERSPACE
+void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void* p_addr, size_t size, size_t attr);
+void *rt_hw_mmu_map_auto(rt_mmu_info *mmu_info, void *v_addr, size_t size, size_t attr);
+#else
+void *rt_hw_mmu_map(rt_mmu_info *mmu_info, void* p_addr, size_t size, size_t attr);
+#endif
+void rt_hw_mmu_unmap(rt_mmu_info *mmu_info, void* v_addr, size_t size);
+void *rt_hw_mmu_v2p(rt_mmu_info *mmu_info, void* v_addr);
+
+void *rt_hw_kernel_phys_to_virt(void *p_addr, size_t size);
+void *rt_hw_kernel_virt_to_phys(void *v_addr, size_t size);
+
+#endif