--- /dev/null
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := flash.o pl353_x8.o xemacpss_g.o xbasic_types.o xemacpss_control.o xemacpss_sinit.o xemacpss_bdring.o xemacpss.o xgmac.o
+SOBJS := # lowlevel_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
--- /dev/null
+TEXT_BASE = 0x04003000
--- /dev/null
+/*
+ * flash.c: Support code for the flash chips on the Xilinx PELE board
+ *
+ * This software may be used and distributed according to the terms of
+ * the GNU General Public License (GPL) version 2, incorporated herein by
+ * reference. Drivers based on or derived from this code fall under the GPL
+ * and must retain the authorship, copyright and this license notice. This
+ * file is not a complete program and may only be used when the entire program
+ * is licensed under the GPL.
+ *
+ */
+
+#include <common.h>
+#include <asm/u-boot.h>
+#include <configs/xpele.h>
+#include "pl353_x8.h"
+
+#ifndef CONFIG_SYS_NO_FLASH
+
+#define FLASH_BANK_SIZE (16*1024*1024) //16MB
+#define FLASH_SIZE CONFIG_SYS_FLASH_SIZE
+#define SECT_SIZE (64*1024) //a.k.a BLOCK_SIZE
+#define PAGE_SIZE 32
+
+#define FLASH_STATUS_DONE 0x80
+#define FLASH_STATUS_ESS 0x40
+#define FLASH_STATUS_ECLBS 0x20
+#define FLASH_STATUS_PSLBS 0x10
+#define FLASH_STATUS_VPENS 0x08
+#define FLASH_STATUS_PSS 0x04
+#define FLASH_STATUS_DPS 0x02
+#define FLASH_STATUS_PROTECT 0x01
+
+
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+
+static int flash_full_status_check(ulong addr);
+
+static initialize=0;
+
+ulong flash_init(void) {
+
+ int i, j;
+ ulong size = 0;
+ for(i=0;i<CONFIG_SYS_MAX_FLASH_BANKS;i++) {
+ ulong flashbase = 0;
+
+ flash_info[i].flash_id = (INTEL_MANUFACT & FLASH_VENDMASK) |
+ (INTEL_ID_28F256P30T & FLASH_TYPEMASK);
+ flash_info[i].size = FLASH_BANK_SIZE;
+ flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
+ memset(flash_info[i].protect, 1, CONFIG_SYS_MAX_FLASH_SECT);
+ if (i==0)
+ flashbase = CONFIG_SYS_FLASH_BASE;
+
+ for (j = 0; j < flash_info[i].sector_count; j++)
+ flash_info[i].start[j]=flashbase + j * SECT_SIZE;
+
+ size += flash_info[i].size;
+ }
+
+ return size;
+}
+
+int do_flinit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ if(initialize){
+ printf("FLASH already initialized\r\n");
+ return 1;
+ }
+ initialize = 1;
+ printf("FLASH Initialized\r\n");
+ init_nor_flash();
+ return 0;
+}
+
+U_BOOT_CMD(
+ flinit, 1, 0, do_flinit,
+ "FLASH memory initialization",
+ "\n - flinit initialize the FLASH memory\n"
+ "flinit \n - initialize the FLASH "
+);
+
+void flash_print_info (flash_info_t *info) {
+
+ int i;
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (INTEL_MANUFACT & FLASH_VENDMASK):
+ printf("Intel: ");
+ break;
+ default:
+ printf("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case (INTEL_ID_28F256P30T & FLASH_TYPEMASK):
+ printf("INTEL_ID_28F256P30T 16MByte)\n");
+ break;
+ default:
+ printf("Unknown Chip Type\n");
+ break;
+ }
+
+ printf(" Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
+ printf(" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0)
+ printf("\n ");
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+}
+
+
+int flash_erase (flash_info_t *info, int s_first, int s_last) {
+
+ int rc = ERR_OK;
+ int sect;
+
+ if(!initialize){
+ printf("FLASH not initialized. Use flinit command. \r\n");
+ return ERR_UNKNOWN_FLASH_TYPE;
+ }
+ if (info->flash_id == FLASH_UNKNOWN)
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if ((s_first < 0) || (s_first > s_last))
+ return ERR_INVAL;
+
+ if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK))
+ return ERR_UNKNOWN_FLASH_VENDOR;
+
+ for (sect=s_first; sect<=s_last; ++sect)
+ if (info->protect[sect]){
+ printf("Flash is protected.\n");
+ return ERR_PROTECTED;
+ }
+ printf("\n");
+ for (sect = s_first; sect<=s_last && !ctrlc(); sect++) {
+ volatile unsigned long long *addr= (unsigned long long *)(info->start[sect]);
+
+ printf("Erasing sector %d ... \n", sect);
+ block_erase_nor_flash((u32)addr);
+ rc = flash_full_status_check(info->start[sect]);
+ }
+
+ if (ctrlc())
+ printf("User Interrupt!\n");
+
+ return rc;
+}
+
+
+int flash_real_protect(flash_info_t * info, long sector, int prot)
+{
+
+ if(!initialize){
+ printf("FLASH not initialized. Use flinit command. \r\n");
+ return ERR_UNKNOWN_FLASH_TYPE;
+ }
+ int retcode=0;
+ if(prot)
+ lock_nor_flash(info->start[sector]);
+ else
+ unlock_nor_flash(info->start[sector]);
+
+ info->protect[sector] = prot;
+ retcode = flash_full_status_check(info->start[sector]);
+ return retcode;
+}
+
+static int flash_full_status_check(ulong addr)
+{
+ int retcode;
+ retcode = read_status_reg_nor_flash(addr);
+ if (retcode != FLASH_STATUS_DONE) {
+ printf("\nFlash error at address %lx with retcode=0x%x\n",addr,retcode);
+ if (retcode & (FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS))
+ printf("Command Sequence Error.\n");
+ else if (retcode & FLASH_STATUS_ECLBS)
+ printf("Block Erase Error.\n");
+ else if (retcode & FLASH_STATUS_PSLBS)
+ printf("Locking Error\n");
+ if (retcode & FLASH_STATUS_DPS)
+ printf("Block locked.\n");
+ if (retcode & FLASH_STATUS_VPENS)
+ printf("Vpp Low Error.\n");
+ retcode = 1;
+ }
+ else
+ retcode = 0;
+
+ Xil_Out8(addr, 0xFF);
+ return retcode;
+}
+
+static int write_word (flash_info_t *info, ulong dest, unsigned long data) {
+
+ volatile unsigned char *addr1=(unsigned char *)dest;
+ volatile unsigned long *addr2=(unsigned long *)dest;
+ unsigned long result;
+ int rc = ERR_OK;
+ int i;
+ char real_data;
+ result = *addr2;
+ if ((result & data) != data)
+ return ERR_NOT_ERASED;
+ for(i=0;i<4;i++){
+ real_data = (data >> (i*8)) & 0xFF;
+ write_byte_nor_flash((u32)(addr1+i),real_data);
+ }
+ rc = flash_full_status_check((u32)addr1);
+ return rc;
+
+}
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+
+ if(!initialize){
+ printf("FLASH not initialized. Use flinit command. \r\n");
+ return ERR_UNKNOWN_FLASH_TYPE;
+ }
+#if CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+ ulong pages,remain;
+ int i,rc=0;
+ char *src_ptr , *dst_ptr;
+
+ src_ptr = (char *)src;
+ dst_ptr = (char *)addr;
+ pages = cnt/PAGE_SIZE;
+ remain = cnt % PAGE_SIZE;
+ if(pages)
+ {
+ for(i=0;i<pages;i++)
+ {
+ if ((i % 500) == 0)
+ putc('.');
+ buffered_wirte_nor_flash((u32)dst_ptr,(u8 *)src_ptr,(u16)PAGE_SIZE);
+ if((rc = flash_full_status_check((u32)dst_ptr)) != 0)
+ break;
+ dst_ptr += PAGE_SIZE;
+ src_ptr += PAGE_SIZE;
+ }
+ }
+
+ if(remain)
+ {
+ buffered_wirte_nor_flash((u32)dst_ptr,(u8 *)src_ptr,(u16)remain);
+ rc = flash_full_status_check((u32)dst_ptr);
+ }
+
+ printf("\nCopied 0x%x bytes from 0x%x to 0x%x\r\n",cnt,src,addr);
+ return rc;
+
+#else
+ u32 *sp, *dp;
+ char *src_ptr, *dst_ptr;
+ u32 len, remain,i;
+ int rc=0;
+ sp = (u32 *)src;
+ dp = (u32 *)addr;
+ len = cnt & ~0x3;
+ remain = cnt % 4;
+
+ while(len)
+ {
+ if ((len % 2000) == 0)
+ putc('.');
+ if((rc = write_word(info,dp,*sp)) != 0 )
+ break;
+ dp++ ;
+ sp++;
+ len -= 4;
+ }
+ src_ptr = (char *)sp;
+ dst_ptr = (char *)dp;
+ if(remain)
+ {
+ for(i=0;i<remain;i++)
+ {
+ write_byte_nor_flash((dst_ptr+i),*(src_ptr+i));
+ }
+ rc = flash_full_status_check((u32)dst_ptr);
+ }
+ printf("\nCopied 0x%xbytes from 0x%x to 0x%x\r\n",cnt,src,addr);
+ return rc;
+
+#endif
+}
+
+#endif
--- /dev/null
+
+/******************************************************************************
+*
+* $xilinx_legal_disclaimer
+*
+******************************************************************************/
+
+#include "pl353_x8.h"
+/*
+ * init_nor_flash init the parameters of pl353 for the P30 flash
+ */
+//typedef volatile u32 XIo_Address;
+
+void Xil_Out8(XIo_Address OutAddress, u8 Value);
+u8 Xil_In8(XIo_Address InAddress);
+
+void init_nor_flash(void)
+{
+ /* Init variables */
+
+ /* Write timing info to set_cycles registers */
+ u32 set_cycles_reg = (0x0 << 20) | /* Set_t6 or we_time from sram_cycles */
+ (0x0 << 17) | /* Set_t5 or t_tr from sram_cycles */
+ (0x1 << 14) | /* Set_t4 or t_pc from sram_cycles */
+ (0x5 << 11) | /* Set_t3 or t_wp from sram_cycles */
+ (0x1 << 8) | /* Set_t2 t_ceoe from sram_cycles */
+ (0x7 << 4) | /* Set_t1 t_wc from sram_cycles */
+ (0x7); /* Set_t0 t_rc from sram_cycles */
+
+ X_mWriteReg(PARPORT_CRTL_BASEADDR, PARPORT_MC_SET_CYCLES, set_cycles_reg);
+
+ /* write operation mode to set_opmode registers */
+ u32 set_opmode_reg = (0x1 << 13) | /* set_burst_align, see to 32 beats */
+ (0x0 << 12) | /* set_bls, set to default I am not sure */
+ (0x0 << 11) | /* set_adv bit, set to default */
+ (0x0 << 10) | /* set_baa, I guess we don't use baa_n */
+ (0x0 << 7) | /* set_wr_bl, write brust length, set to 0 */
+ (0x0 << 6) | /* set_wr_sync, set to 0 */
+ (0x0 << 3) | /* set_rd_bl, read brust lenght, set to 0 */
+ (0x0 << 2) | /* set_rd_sync, set to 0 */
+ (0x0 ); /* set_mw, memory width, 16bits width*/
+ X_mWriteReg(PARPORT_CRTL_BASEADDR, PARPORT_MC_SET_OPMODE, set_opmode_reg);
+
+
+ /*
+ * Issue a direct_cmd by writing to direct_cmd register
+ * This is needed becuase the UpdatesReg flag in direct_cmd updates the state of SMC
+ * I think....
+ */
+ u32 direct_cmd_reg = (0x0 << 23) | /* chip 0 from interface 0 */
+ (0x2 << 21) | /* UpdateRegs operation, to update the two reg we wrote earlier*/
+ (0x0 << 20) | /* Not sure about this one cre, what does it do? */
+ (0x0); /* addr, not use in UpdateRegs */
+ X_mWriteReg(PARPORT_CRTL_BASEADDR, PARPORT_MC_DIRECT_CMD, direct_cmd_reg);
+
+ /* Now the flash should be ready to be accessed */
+}
+
+
+/*
+ * wirte_nor_flash returns 1 after a seccussful write
+ */
+void write_half_word_nor_flash(u32 address, u8 data)
+{
+ /* status reg polling to be added later */
+ Xil_Out8(address, 0x40);
+ Xil_Out8(address, data);
+ while(read_status_reg_nor_flash(address) >> 7 != 1);
+}
+
+void write_byte_nor_flash(u32 address, u8 data)
+{
+ Xil_Out8(address, 0x40);
+ Xil_Out8(address, data);
+ while(read_status_reg_nor_flash(address) >> 7 != 1);
+}
+/*
+ * read_nor_flash returns the data of a memeory location
+ */
+u16 read_half_word_nor_flash(u32 address)
+{
+ Xil_Out8(address, 0xFF);
+ return Xil_In8(address);
+}
+
+/*
+ * read_status_reg_nor_flash returns the status register of a block address
+ */
+u16 read_status_reg_nor_flash(u32 address)
+{
+ Xil_Out8(address, 0x70);
+ return Xil_In8(address);
+}
+
+/*
+ * clear_status_reg_nor_flash clears the status register of a block address
+ */
+void clear_status_reg_nor_flash(u32 address)
+{
+ Xil_Out8(address, 0x50);
+}
+
+/*
+ * unlock_nor_flash put the selected block of address in unlock mode
+ */
+void unlock_nor_flash(u32 blockAddress)
+{
+ Xil_Out8((blockAddress & 0xFFFF0000), 0x60);
+ Xil_Out8((blockAddress & 0xFFFF0000), 0xD0);
+}
+
+/*
+ * lock_nor_flash put the selected block of address in lock mode
+ */
+void lock_nor_flash(u32 blockAddress)
+{
+ Xil_Out8((blockAddress & 0xFFFF0000), 0x60);
+ Xil_Out8((blockAddress & 0xFFFF0000), 0x01);
+}
+
+/*
+ * block_erase_nor_flash
+ */
+void block_erase_nor_flash(u32 blockAddress)
+{
+ /* Clear status before erase */
+ if(read_status_reg_nor_flash(blockAddress & 0xFFFF0000) != 0x80)
+ {
+ clear_status_reg_nor_flash(blockAddress & 0xFFFF0000);
+ }
+
+ Xil_Out8((blockAddress & 0xFFFF0000), 0x20);
+ Xil_Out8((blockAddress & 0xFFFF0000), 0xD0);
+
+ while(Xil_In8((blockAddress & 0xFFFF0000)) >> 7 != 1);
+
+}
+
+/*
+ * buffered_write_nor_flash
+ */
+void buffered_wirte_nor_flash(u32 address, u8 *dataBuffer, u16 wordCount)
+{
+
+ /* Issue write program */
+ Xil_Out8((address & 0xFFFF0000), 0xE8);
+
+ /* Poll status reg at block address until ready*/
+ while(Xil_In8((address & 0xFFFF0000)) >> 7 != 1);
+
+ /* write count to block address */
+ Xil_Out8((address & 0xFFFF0000), wordCount - 1);
+
+ /* write data */
+ int i;
+ for(i = 0; i < wordCount; i++)
+ {
+ Xil_Out8((address + i), dataBuffer[i]);
+ }
+
+ /* write confirm to block address */
+ Xil_Out8((address & 0xFFFF0000), 0xD0);
+
+ /* Poll status reg */
+ while(Xil_In8((address & 0xFFFF0000)) >> 7 != 1);
+
+
+}
+void Xil_Out8(XIo_Address OutAddress, u8 Value)
+{
+ *(volatile u8 *) OutAddress = Value;
+}
+
+u8 Xil_In8(XIo_Address InAddress)
+{
+ return *(u8 *) InAddress;
+}
--- /dev/null
+ /******************************************************************************
+*
+* $xilinx_legal_disclaimer
+*
+******************************************************************************/
+
+#ifndef pl353_H
+#define pl353_H
+
+#include <common.h>
+/* pl353 base address*/
+#define PARPORT_CRTL_BASEADDR 0xE000E000
+#define NOR_FLASH_BASEADDR 0xE2000000
+
+/* Now for the register offsets */
+#define PARPORT_MC_OFFSET 0x000 /* Begining of Memory controller config reg offset */
+
+#define PARPORT_MC_STATUS 0x000
+#define PARPORT_MC_INTERFACE_CONFIG 0x004
+#define PARPORT_MC_SET_CONFIG 0x008
+#define PARPORT_MC_CLR_CONFIG 0x00C
+#define PARPORT_MC_DIRECT_CMD 0x010
+#define PARPORT_MC_SET_CYCLES 0x014
+#define PARPORT_MC_SET_OPMODE 0x018
+#define PARPORT_MC_REFRESH_PERIOD_0 0x020
+#define PARPORT_MC_REFRESH_PERIOD_1 0x024
+
+#define PARPORT_CS_OFFSET 0x100 /* Begining of Chip select config reg offset*/
+
+#define PARPORT_CS_INTERFACE_1_CHIP_3_OFFSET 0x1E0 /* Interface 1 chip 3 configuration */
+#define PARPORT_CS_INTERFACE_1_CHIP_2_OFFSET 0x1C0 /* Interface 1 chip 2 configuration */
+#define PARPORT_CS_INTERFACE_1_CHIP_1_OFFSET 0x1A0 /* Interface 1 chip 1 configuration */
+#define PARPORT_CS_INTERFACE_1_CHIP_0_OFFSET 0x180 /* Interface 1 chip 0 configuration */
+#define PARPORT_CS_INTERFACE_0_CHIP_3_OFFSET 0x160 /* Interface 0 chip 3 configuration */
+#define PARPORT_CS_INTERFACE_0_CHIP_2_OFFSET 0x140 /* Interface 0 chip 2 configuration */
+#define PARPORT_CS_INTERFACE_0_CHIP_1_OFFSET 0x120 /* Interface 0 chip 1 configuration */
+#define PARPORT_CS_INTERFACE_0_CHIP_0_OFFSET 0x100 /* Interface 0 chip 0 configuration */
+
+#define PARPORT_UC_OFFSET 0x200 /* Begining of User config reg offset*/
+
+#define PARPORT_UC_CONFIG_OFFSET 0x204 /* user config reg */
+#define PARPORT_UC_STATUS_OFFSET 0x200 /* user status reg */
+
+#define PARPORT_IT_OFFSET 0xE00 /* Inegration test */
+
+#define PARPORT_ID_OFFSET 0xFE0 /* Begining of PrimeCell ID config reg offset*/
+#define PARPORT_ID_PCELL_3_OFFSET 0xFFC
+#define PARPORT_ID_PCELL_2_OFFSET 0xFF8
+#define PARPORT_ID_PCELL_1_OFFSET 0xFF4
+#define PARPORT_ID_PCELL_0_OFFSET 0xFF0
+#define PARPORT_ID_PERIP_3_OFFSET 0xFEC
+#define PARPORT_ID_PERIP_2_OFFSET 0xFE8
+#define PARPORT_ID_PERIP_1_OFFSET 0xFE4
+#define PARPORT_ID_PERIP_0_OFFSET 0xFE0
+
+/* Read Write macros */
+
+/* Write to memory location or register */
+#define X_mWriteReg(BASE_ADDRESS, RegOffset, data) \
+ *(unsigned long *)(BASE_ADDRESS + RegOffset) = ((unsigned long) data);
+/* Read from memory location or register */
+#define X_mReadReg(BASE_ADDRESS, RegOffset) \
+ *(unsigned long *)(BASE_ADDRESS + RegOffset);
+
+typedef volatile u32 XIo_Address;
+
+typedef u32 AddressType;
+
+void Xil_Out8(XIo_Address OutAddress, u8 Value);
+u8 Xil_In8(XIo_Address InAddress);
+
+/* Function definitionas */
+/*
+ * init_nor_flash init the parameters of pl353 for the P30 flash
+ */
+void init_nor_flash(void);
+
+/*
+ * wirte_nor_flash
+ */
+void write_half_word_nor_flash(u32 address, u8 data);
+void write_byte_nor_flash(u32 address, u8 data);
+/*
+ * read_nor_flash returns the data of a memeory location
+ */
+u16 read_half_word_nor_flash(u32 address);
+
+/*
+ * read_status_reg_nor_flash returns the status register of a block address
+ */
+u16 read_status_reg_nor_flash(u32 address);
+
+/*
+ * clear_status_reg_nor_flash clears the status register of a block address
+ */
+void clear_status_reg_nor_flash(u32 address);
+
+/*
+ * unlock_nor_flash put the selected block of address in unlock mode
+ */
+void unlock_nor_flash(u32 blockAddress);
+
+/*
+ * lock_nor_flash put the selected block of address in lock mode
+ */
+void lock_nor_flash(u32 blockAddress);
+
+/*
+ * block_erase_nor_flash
+ */
+void block_erase_nor_flash(u32 blockAddress);
+
+/*
+ * bufferred_write_nor_flash
+ */
+void buffered_wirte_nor_flash(u32 address, u8 *dataBuffer, u16 wordCount);
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * And thoroughly mangled into dragonfire form, probably never to escape Xilinx.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/proc-armv/ptrace.h>
+#include <div64.h>
+
+#include <asm/arch/ttc.h>
+
+static ulong timer_load_val;
+
+#define PRESCALER 167
+
+/* read the 16 bit timer */
+static inline ulong read_timer(void)
+{
+ return xdfttc_readl(COUNT_VALUE);
+}
+
+/* Internal tick units */
+/* Last decremneter snapshot */
+static unsigned long lastdec;
+/* Monotonic incrementing timer */
+static unsigned long long timestamp;
+
+int interrupt_init(void)
+{
+/* s3c64xx_timers *const timers = s3c64xx_get_base_timers(); */
+
+/* /\* use PWM Timer 4 because it has no output *\/ */
+/* /\* */
+/* * We use the following scheme for the timer: */
+/* * Prescaler is hard fixed at 167, divider at 1/4. */
+/* * This gives at PCLK frequency 66MHz approx. 10us ticks */
+/* * The timer is set to wrap after 100s, at 66MHz this obviously */
+/* * happens after 10,000,000 ticks. A long variable can thus */
+/* * keep values up to 40,000s, i.e., 11 hours. This should be */
+/* * enough for most uses:-) Possible optimizations: select a */
+/* * binary-friendly frequency, e.g., 1ms / 128. Also calculate */
+/* * the prescaler automatically for other PCLK frequencies. */
+/* *\/ */
+/* timers->TCFG0 = PRESCALER << 8; */
+/* if (timer_load_val == 0) { */
+/* timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /\* 100s *\/ */
+/* timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000; */
+/* } */
+
+/* /\* load value for 10 ms timeout *\/ */
+/* lastdec = timers->TCNTB4 = timer_load_val; */
+/* /\* auto load, manual update of Timer 4 *\/ */
+/* timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | */
+/* TCON_4_UPDATE; */
+
+/* /\* auto load, start Timer 4 *\/ */
+/* timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON; */
+/* timestamp = 0; */
+
+ /* complete garbage. */
+ timer_load_val = 0x800000;
+ lastdec = 0x100;
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ ulong now = read_timer();
+
+ if (lastdec >= now) {
+ /* normal mode */
+ timestamp += lastdec - now;
+ } else {
+ /* we have an overflow ... */
+ timestamp += lastdec + timer_load_val - now;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ /* We overrun in 100s */
+ return (ulong)(timer_load_val / 100);
+}
+
+void reset_timer_masked(void)
+{
+ /* reset time */
+ lastdec = read_timer();
+ timestamp = 0;
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer_masked(void)
+{
+ unsigned long long res = get_ticks();
+ do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ)));
+ return res;
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+ timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ));
+}
+
+void udelay(unsigned long usec)
+{
+ unsigned long long tmp;
+ ulong tmo;
+
+ tmo = (usec + 9) / 10;
+ tmp = get_ticks() + tmo; /* get current timestamp */
+
+ while (get_ticks() < tmp)/* loop till event */
+ /*NOP*/;
+}
--- /dev/null
+/*
+ * January 2004 - Changed to support H4 device
+ * Copyright (c) 2004 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm1176/start.o (.text)
+ *(.text)
+ }
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+
+ . = ALIGN(4);
+ .data : { *(.data) }
+
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) . = ALIGN(4); }
+ _end = .;
+}
--- /dev/null
+/* $Id $ */
+/******************************************************************************
+*
+* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
+* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
+* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE.
+*
+* (c) Copyright 2002-2003 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xbasic_types.c
+*
+* This file contains basic functions for Xilinx software IP.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm 11/07/03 Added XNullHandler function as a stub interrupt handler
+* 1.00a xd 11/03/04 Improved support for doxygen.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/**
+ * This variable allows testing to be done easier with asserts. An assert
+ * sets this variable such that a driver can evaluate this variable
+ * to determine if an assert occurred.
+ */
+unsigned int XAssertStatus;
+
+/**
+ * This variable allows the assert functionality to be changed for testing
+ * such that it does not wait infinitely. Use the debugger to disable the
+ * waiting during testing of asserts.
+ */
+int XWaitInAssert = TRUE;
+
+/* The callback function to be invoked when an assert is taken */
+static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL;
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Implements assert. Currently, it calls a user-defined callback function
+* if one has been set. Then, it potentially enters an infinite loop depending
+* on the value of the XWaitInAssert variable.
+*
+* @param File is the name of the filename of the source
+* @param Line is the linenumber within File
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XAssert(char *File, int Line)
+{
+ /* if the callback has been set then invoke it */
+ if (XAssertCallbackRoutine != NULL) {
+ (*XAssertCallbackRoutine) (File, Line);
+ }
+
+ /* if specified, wait indefinitely such that the assert will show up
+ * in testing
+ */
+ while (XWaitInAssert) {
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* Sets up a callback function to be invoked when an assert occurs. If there
+* was already a callback installed, then it is replaced.
+*
+* @param Routine is the callback to be invoked when an assert is taken
+*
+* @return None.
+*
+* @note This function has no effect if NDEBUG is set
+*
+******************************************************************************/
+void XAssertSetCallback(XAssertCallback Routine)
+{
+ XAssertCallbackRoutine = Routine;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Null handler function. This follows the XInterruptHandler signature for
+* interrupt handlers. It can be used to assign a null handler (a stub) to an
+* interrupt controller vector table.
+*
+* @param NullParameter is an arbitrary void pointer and not used.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void XNullHandler(void *NullParameter)
+{
+}
--- /dev/null
+/* $Id: xbasic_types.h,v 1.1.2.1 2009/05/19 14:56:55 meinelte Exp $ */
+/******************************************************************************
+*
+* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
+* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
+* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE.
+*
+* (c) Copyright 2002-2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xbasic_types.h
+*
+* This file contains basic types for Xilinx software IP. These types do not
+* follow the standard naming convention with respect to using the component
+* name in front of each name because they are considered to be primitives.
+*
+* @note
+*
+* This file contains items which are architecture dependent.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rmm 12/14/01 First release
+* rmm 05/09/03 Added "xassert always" macros to rid ourselves of diab
+* compiler warnings
+* 1.00a rpm 11/07/03 Added XNullHandler function as a stub interrupt handler
+* 1.00a rpm 07/21/04 Added XExceptionHandler typedef for processor exceptions
+* 1.00a xd 11/03/04 Improved support for doxygen.
+* 1.00a wre 01/25/07 Added Linux style data types u32, u16, u8, TRUE, FALSE
+* 1.00a rpm 04/02/07 Added ifndef KERNEL around u32, u16, u8 data types
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XBASIC_TYPES_H /* prevent circular inclusions */
+#define XBASIC_TYPES_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/** Xilinx NULL, TRUE and FALSE legacy support. Deprecated. */
+#define XNULL NULL
+#define XTRUE TRUE
+#define XFALSE FALSE
+
+
+#define XCOMPONENT_IS_READY 0x11111111 /**< component has been initialized */
+#define XCOMPONENT_IS_STARTED 0x22222222 /**< component has been started */
+
+/* the following constants and declarations are for unit test purposes and are
+ * designed to be used in test applications.
+ */
+#define XTEST_PASSED 0
+#define XTEST_FAILED 1
+
+#define XASSERT_NONE 0
+#define XASSERT_OCCURRED 1
+
+extern unsigned int XAssertStatus;
+extern void XAssert(char *, int);
+
+/**************************** Type Definitions *******************************/
+
+/** @name Legacy types
+ * Deprecated legacy types.
+ * @{
+ */
+typedef unsigned char Xuint8; /**< unsigned 8-bit */
+typedef char Xint8; /**< signed 8-bit */
+typedef unsigned short Xuint16; /**< unsigned 16-bit */
+typedef short Xint16; /**< signed 16-bit */
+typedef unsigned long Xuint32; /**< unsigned 32-bit */
+typedef long Xint32; /**< signed 32-bit */
+typedef float Xfloat32; /**< 32-bit floating point */
+typedef double Xfloat64; /**< 64-bit double precision FP */
+typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */
+
+typedef struct
+{
+ Xuint32 Upper;
+ Xuint32 Lower;
+} Xuint64;
+
+/** @name New types
+ * New simple types.
+ * @{
+ */
+#ifndef __KERNEL__
+typedef Xuint32 u32;
+typedef Xuint16 u16;
+typedef Xuint8 u8;
+#else
+#include <linux/types.h>
+#endif
+
+/*@}*/
+
+/**
+ * This data type defines an interrupt handler for a device.
+ * The argument points to the instance of the component
+ */
+typedef void (*XInterruptHandler) (void *InstancePtr);
+
+/**
+ * This data type defines an exception handler for a processor.
+ * The argument points to the instance of the component
+ */
+typedef void (*XExceptionHandler) (void *InstancePtr);
+
+/**
+ * This data type defines a callback to be invoked when an
+ * assert occurs. The callback is invoked only when asserts are enabled
+ */
+typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber);
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+* Return the most significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return The upper 32 bits of the 64 bit word.
+*
+* @note None.
+*
+******************************************************************************/
+#define XUINT64_MSW(x) ((x).Upper)
+
+/*****************************************************************************/
+/**
+* Return the least significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return The lower 32 bits of the 64 bit word.
+*
+* @note None.
+*
+******************************************************************************/
+#define XUINT64_LSW(x) ((x).Lower)
+
+
+#ifndef NDEBUG
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do not return anything
+* (void). This in conjunction with the XWaitInAssert boolean can be used to
+* accomodate tests so that asserts which fail allow execution to continue.
+*
+* @param expression is the expression to evaluate. If it evaluates to
+* false, the assert occurs.
+*
+* @return Returns void unless the XWaitInAssert variable is true, in which
+* case no return is made and an infinite loop is entered.
+*
+* @note None.
+*
+******************************************************************************/
+#define XASSERT_VOID(expression) \
+{ \
+ if (expression) \
+ { \
+ XAssertStatus = XASSERT_NONE; \
+ } \
+ else \
+ { \
+ XAssert(__FILE__, __LINE__); \
+ XAssertStatus = XASSERT_OCCURRED; \
+ return; \
+ } \
+}
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do return a value. This in
+* conjunction with the XWaitInAssert boolean can be used to accomodate tests so
+* that asserts which fail allow execution to continue.
+*
+* @param expression is the expression to evaluate. If it evaluates to false,
+* the assert occurs.
+*
+* @return Returns 0 unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID(expression) \
+{ \
+ if (expression) \
+ { \
+ XAssertStatus = XASSERT_NONE; \
+ } \
+ else \
+ { \
+ XAssert(__FILE__, __LINE__); \
+ XAssertStatus = XASSERT_OCCURRED; \
+ return 0; \
+ } \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do not
+* return anything (void). Use for instances where an assert should always
+* occur.
+*
+* @return Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note None.
+*
+******************************************************************************/
+#define XASSERT_VOID_ALWAYS() \
+{ \
+ XAssert(__FILE__, __LINE__); \
+ XAssertStatus = XASSERT_OCCURRED; \
+ return; \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do return
+* a value. Use for instances where an assert should always occur.
+*
+* @return Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID_ALWAYS() \
+{ \
+ XAssert(__FILE__, __LINE__); \
+ XAssertStatus = XASSERT_OCCURRED; \
+ return 0; \
+}
+
+
+#else
+
+#define XASSERT_VOID(expression)
+#define XASSERT_VOID_ALWAYS()
+#define XASSERT_NONVOID(expression)
+#define XASSERT_NONVOID_ALWAYS()
+#endif
+
+/************************** Function Prototypes ******************************/
+
+void XAssertSetCallback(XAssertCallback Routine);
+void XNullHandler(void *NullParameter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
--- /dev/null
+/* $Id: xemacpss.c,v 1.1.2.2 2009/07/07 22:54:36 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemacpss.c
+*
+* The XEmacPss driver. Functions in this file are the minimum required functions
+* for this driver. See xemacpss.h for a detailed description of the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a wsy 06/01/09 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xemacpss.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+void XEmacPss_StubHandler(void); /* Default handler routine */
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* Initialize a specific XEmacPss instance/driver. The initialization entails:
+* - Initialize fields of the XEmacPss instance structure
+* - Reset hardware and apply default options
+* - Configure the DMA channels
+*
+* The PHY is setup independently from the device. Use the MII or whatever other
+* interface may be present for setup.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param CfgPtr is the device configuration structure containing required
+* hardware build data.
+* @param EffectiveAddress is the base address of the device. If address
+* translation is not utilized, this parameter can be passed in using
+* CfgPtr->Config.BaseAddress to specify the physical base address.
+*
+* @return
+* - XST_SUCCESS if initialization was successful
+*
+******************************************************************************/
+int XEmacPss_CfgInitialize(XEmacPss *InstancePtr, XEmacPss_Config * CfgPtr,
+ u32 EffectiveAddress)
+{
+ /* Verify arguments */
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(CfgPtr != NULL);
+
+ /* Set device base address and ID */
+ InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
+ InstancePtr->Config.BaseAddress = EffectiveAddress;
+
+ /* Set callbacks to an initial stub routine */
+ InstancePtr->SendHandler = (XEmacPss_Handler) XEmacPss_StubHandler;
+ InstancePtr->RecvHandler = (XEmacPss_Handler) XEmacPss_StubHandler;
+ InstancePtr->ErrorHandler = (XEmacPss_ErrHandler) XEmacPss_StubHandler;
+
+ /* Reset the hardware and set default options */
+ InstancePtr->IsReady = XCOMPONENT_IS_READY;
+ XEmacPss_Reset(InstancePtr);
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+* Start the Ethernet controller as follows:
+* - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
+* - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
+* - Start the SG DMA send and receive channels and enable the device
+* interrupt
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @return N/A
+*
+* @note
+* Hardware is configured with scatter-gather DMA, the driver expects to start
+* the scatter-gather channels and expects that the user has previously set up
+* the buffer descriptor lists.
+*
+* This function makes use of internal resources that are shared between the
+* Start, Stop, and Set/ClearOptions functions. So if one task might be setting
+* device options while another is trying to start the device, the user is
+* required to provide protection of this shared data (typically using a
+* semaphore).
+*
+* This function must not be preempted by an interrupt that may service the
+* device.
+*
+******************************************************************************/
+void XEmacPss_Start(XEmacPss *InstancePtr)
+{
+ u32 Reg;
+
+ /* Assert bad arguments and conditions */
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_VOID(InstancePtr->RxBdRing.BaseBdAddr != 0);
+ XASSERT_VOID(InstancePtr->TxBdRing.BaseBdAddr != 0);
+
+ /* If already started, then there is nothing to do */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return;
+ }
+
+ /* Start DMA */
+ /* When starting the DMA channels, both transmit and receive sides
+ * need an initialized BD list.
+ */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_RXQBASE_OFFSET,
+ InstancePtr->RxBdRing.BaseBdAddr);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_TXQBASE_OFFSET,
+ InstancePtr->TxBdRing.BaseBdAddr);
+
+ /* clear any existed int status */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress, XEMACPSS_ISR_OFFSET,
+ XEMACPSS_IXR_ALL_MASK);
+
+ /* Enable transmitter if not already enabled */
+ if (InstancePtr->Options & XEMACPSS_TRANSMITTER_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ if (!(Reg & XEMACPSS_NWCTRL_TXEN_MASK)) {
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET,
+ Reg | XEMACPSS_NWCTRL_TXEN_MASK);
+ }
+ }
+
+ /* Enable receiver if not already enabled */
+ if (InstancePtr->Options & XEMACPSS_RECEIVER_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ if (!(Reg & XEMACPSS_NWCTRL_RXEN_MASK)) {
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET,
+ Reg | XEMACPSS_NWCTRL_RXEN_MASK);
+ }
+ }
+
+#if 0
+ /* Enable TX and RX interrupts */
+ XEmacPss_IntEnable(InstancePtr, (XEMACPSS_IXR_TX_ERR_MASK |
+ XEMACPSS_IXR_RX_ERR_MASK | XEMACPSS_IXR_FRAMERX_MASK |
+ XEMACPSS_IXR_TXCOMPL_MASK));
+#endif
+ /* Mark as started */
+ InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
+
+ return;
+}
+
+
+/*****************************************************************************/
+/**
+* Gracefully stop the Ethernet MAC as follows:
+* - Disable all interrupts from this device
+* - Stop DMA channels
+* - Disable the tansmitter and receiver
+*
+* Device options currently in effect are not changed.
+*
+* This function will disable all interrupts. Default interrupts settings that
+* had been enabled will be restored when XEmacPss_Start() is called.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @note
+* This function makes use of internal resources that are shared between the
+* Start, Stop, SetOptions, and ClearOptions functions. So if one task might be
+* setting device options while another is trying to start the device, the user
+* is required to provide protection of this shared data (typically using a
+* semaphore).
+*
+* Stopping the DMA channels causes this function to block until the DMA
+* operation is complete.
+*
+******************************************************************************/
+void XEmacPss_Stop(XEmacPss *InstancePtr)
+{
+ u32 Reg;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* Disable all interrupts */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress, XEMACPSS_IDR_OFFSET,
+ XEMACPSS_IXR_ALL_MASK);
+
+ /* Disable the receiver & transmitter */
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ Reg &= ~XEMACPSS_NWCTRL_RXEN_MASK;
+ Reg &= ~XEMACPSS_NWCTRL_TXEN_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET, Reg);
+
+ /* Mark as stopped */
+ InstancePtr->IsStarted = 0;
+}
+
+
+/*****************************************************************************/
+/**
+* Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
+* transmitter, and the receiver.
+*
+* Steps to reset
+* - Stops transmit and receive channels
+* - Stops DMA
+* - Configure transmit and receive buffer size to default
+* - Clear transmit and receive status register and counters
+* - Clear all interrupt sources
+* - Clear phy (if there is any previously detected) address
+* - Clear MAC addresses (1-4) as well as Type IDs and hash value
+*
+* All options are placed in their default state. Any frames in the
+* descriptor lists will remain in the lists. The side effect of doing
+* this is that after a reset and following a restart of the device, frames
+* were in the list before the reset may be transmitted or received.
+*
+* The upper layer software is responsible for re-configuring (if necessary)
+* and restarting the MAC after the reset. Note also that driver statistics
+* are not cleared on reset. It is up to the upper layer software to clear the
+* statistics if needed.
+*
+* When a reset is required, the driver notifies the upper layer software of
+* this need through the ErrorHandler callback and specific status codes.
+* The upper layer software is responsible for calling this Reset function
+* and then re-configuring the device.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+******************************************************************************/
+void XEmacPss_Reset(XEmacPss *InstancePtr)
+{
+ u32 Reg;
+ u8 i;
+ char EmacPss_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* Stop the device and reset hardware */
+ XEmacPss_Stop(InstancePtr);
+ InstancePtr->Options = XEMACPSS_DEFAULT_OPTIONS;
+
+ /* Setup hardware with default values */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET,
+ (XEMACPSS_NWCTRL_STATCLR_MASK |
+ XEMACPSS_NWCTRL_MDEN_MASK) &
+ ~XEMACPSS_NWCTRL_LOOPEN_MASK);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET,
+ XEMACPSS_NWCFG_100_MASK |
+ XEMACPSS_NWCFG_FDEN_MASK |
+ XEMACPSS_NWCFG_UCASTHASHEN_MASK);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_DMACR_OFFSET,
+ ((((XEMACPSS_RX_BUF_SIZE / XEMACPSS_RX_BUF_UNIT) +
+ ((XEMACPSS_RX_BUF_SIZE %
+ XEMACPSS_RX_BUF_UNIT) ? 1 : 0)) <<
+ XEMACPSS_DMACR_RXBUF_SHIFT) &
+ XEMACPSS_DMACR_RXBUF_MASK) |
+ XEMACPSS_DMACR_RXSIZE_MASK |
+ XEMACPSS_DMACR_TXSIZE_MASK);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_TXSR_OFFSET, 0x0);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_RXQBASE_OFFSET, 0x0);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_TXQBASE_OFFSET, 0x0);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_RXSR_OFFSET, 0x0);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress, XEMACPSS_IDR_OFFSET,
+ XEMACPSS_IXR_ALL_MASK);
+
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_ISR_OFFSET);
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress, XEMACPSS_ISR_OFFSET,
+ Reg);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_PHYMNTNC_OFFSET, 0x0);
+
+ XEmacPss_ClearHash(InstancePtr);
+
+ for (i = 1; i < 5; i++) {
+ XEmacPss_SetMacAddress(InstancePtr, EmacPss_zero_MAC, i);
+ XEmacPss_SetTypeIdCheck(InstancePtr, 0x0, i);
+ }
+
+ /* clear all counters */
+ for (i = 0; i < (XEMACPSS_LAST_OFFSET - XEMACPSS_OCTTXL_OFFSET) / 4;
+ i++) {
+ XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_OCTTXL_OFFSET + i * 4);
+ }
+
+ /* Disable the receiver */
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ Reg &= ~XEMACPSS_NWCTRL_RXEN_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET, Reg);
+
+ /* Sync default options with hardware but leave receiver and
+ * transmitter disabled. They get enabled with XEmacPss_Start() if
+ * XEMACPSS_TRANSMITTER_ENABLE_OPTION and
+ * XEMACPSS_RECEIVER_ENABLE_OPTION are set.
+ */
+ XEmacPss_SetOptions(InstancePtr, InstancePtr->Options &
+ ~(XEMACPSS_TRANSMITTER_ENABLE_OPTION |
+ XEMACPSS_RECEIVER_ENABLE_OPTION));
+
+ XEmacPss_ClearOptions(InstancePtr, ~InstancePtr->Options);
+}
+
+
+/******************************************************************************/
+/**
+ * This is a stub for the asynchronous callbacks. The stub is here in case the
+ * upper layer forgot to set the handler(s). On initialization, all handlers are
+ * set to this callback. It is considered an error for this handler to be
+ * invoked.
+ *
+ ******************************************************************************/
+void XEmacPss_StubHandler(void)
+{
+ XASSERT_VOID_ALWAYS();
+}
--- /dev/null
+/* $Id: xemacpss.h,v 1.1.2.3 2009/07/29 20:05:30 wyang Exp $ */
+/*****************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+*****************************************************************************/
+/****************************************************************************/
+/**
+ *
+ * @file xemacpss.h
+ *
+ * The Xilinx Embedded Processor Block Ethernet driver.
+ *
+ * For a full description of XEMACPSS features, please see the hardware spec.
+ * This driver supports the following features:
+ * - Memory mapped access to host interface registers
+ * - Statistics counter registers for RMON/MIB
+ * - API for interrupt driven frame transfers for hardware configured DMA
+ * - Virtual memory support
+ * - Unicast, broadcast, and multicast receive address filtering
+ * - Full and half duplex operation
+ * - Automatic PAD & FCS insertion and stripping
+ * - Flow control
+ * - Support up to four 48bit addresses
+ * - Address checking for four specific 48bit addresses
+ * - VLAN frame support
+ * - Pause frame support
+ * - Large frame support up to 1536 bytes
+ * - Checksum offload
+ *
+ * <b>Driver Description</b>
+ *
+ * The device driver enables higher layer software (e.g., an application) to
+ * communicate to the XEmacPss. The driver handles transmission and reception
+ * of Ethernet frames, as well as configuration and control. No pre or post
+ * processing of frame data is performed. The driver does not validate the
+ * contents of an incoming frame in addition to what has already occurred in
+ * hardware.
+ * A single device driver can support multiple devices even when those devices
+ * have significantly different configurations.
+ *
+ * <b>Initialization & Configuration</b>
+ *
+ * The XEmacPss_Config structure is used by the driver to configure itself.
+ * This configuration structure is typically created by the tool-chain based
+ * on hardware build properties.
+ *
+ * The driver instance can be initialized in
+ *
+ * - XEmacPss_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddress): Uses a
+ * configuration structure provided by the caller. If running in a system
+ * with address translation, the provided virtual memory base address
+ * replaces the physical address present in the configuration structure.
+ *
+ * The device supports DMA only as current development plan. No FIFO mode is
+ * supported. The driver expects to start the DMA channels and expects that
+ * the user has set up the buffer descriptor lists.
+ *
+ * <b>Interrupts and Asynchronous Callbacks</b>
+ *
+ * The driver has no dependencies on the interrupt controller. When an
+ * interrupt occurs, the handler will perform a small amount of
+ * housekeeping work, determine the source of the interrupt, and call the
+ * appropriate callback function. All callbacks are registered by the user
+ * level application.
+ *
+ * <b>Virtual Memory</b>
+ *
+ * All virtual to physical memory mappings must occur prior to accessing the
+ * driver API.
+ *
+ * For DMA transactions, user buffers supplied to the driver must be in terms
+ * of their physical address.
+ *
+ * <b>DMA</b>
+ *
+ * The DMA engine uses buffer descriptors (BDs) to describe Ethernet frames.
+ * These BDs are typically chained together into a list the hardware follows
+ * when transferring data in and out of the packet buffers. Each BD describes
+ * a memory region containing either a full or partial Ethernet packet.
+ *
+ * Interrupt coalescing is not suppoted from this built-in DMA engine.
+ *
+ * This API requires the user to understand how the DMA operates. The
+ * following paragraphs provide some explanation, but the user is encouraged
+ * to read documentation in xemacpss_bdring.h as well as study example code
+ * that accompanies this driver.
+ *
+ * The API is designed to get BDs to and from the DMA engine in the most
+ * efficient means possible. The first step is to establish a memory region
+ * to contain all BDs for a specific channel. This is done with
+ * XEmacPss_BdRingCreate(). This function sets up a BD ring that hardware will
+ * follow as BDs are processed. The ring will consist of a user defined number
+ * of BDs which will all be partially initialized. For example on the transmit
+ * channel, the driver will initialize all BDs' so that they are configured
+ * for transmit. The more fields that can be permanently setup at
+ * initialization, then the fewer accesses will be needed to each BD while
+ * the DMA engine is in operation resulting in better throughput and CPU
+ * utilization. The best case initialization would require the user to set
+ * only a frame buffer address and length prior to submitting the BD to the
+ * engine.
+ *
+ * BDs move through the engine with the help of functions
+ * XEmacPss_BdRingAlloc(), XEmacPss_BdRingToHw(), XEmacPss_BdRingFromHw(),
+ * and XEmacPss_BdRingFree().
+ * All these functions handle BDs that are in place. That is, there are no
+ * copies of BDs kept anywhere and any BD the user interacts with is an actual
+ * BD from the same ring hardware accesses.
+ *
+ * BDs in the ring go through a series of states as follows:
+ * 1. Idle. The driver controls BDs in this state.
+ * 2. The user has data to transfer. XEmacPss_BdRingAlloc() is called to
+ * reserve BD(s). Once allocated, the user may setup the BD(s) with
+ * frame buffer address, length, and other attributes. The user controls
+ * BDs in this state.
+ * 3. The user submits BDs to the DMA engine with XEmacPss_BdRingToHw. BDs
+ * in this state are either waiting to be processed by hardware, are in
+ * process, or have been processed. The DMA engine controls BDs in this
+ * state.
+ * 4. Processed BDs are retrieved with XEmacEpv_BdRingFromHw() by the
+ * user. Once retrieved, the user can examine each BD for the outcome of
+ * the DMA transfer. The user controls BDs in this state. After examining
+ * the BDs the user calls XEmacPss_BdRingFree() which places the BDs back
+ * into state 1.
+ *
+ * Each of the four BD accessor functions operate on a set of BDs. A set is
+ * defined as a segment of the BD ring consisting of one or more BDs. The user
+ * views the set as a pointer to the first BD along with the number of BDs for
+ * that set. The set can be navigated by using macros XEmacPss_BdNext(). The
+ * user must exercise extreme caution when changing BDs in a set as there is
+ * nothing to prevent doing a mBdNext past the end of the set and modifying a
+ * BD out of bounds.
+ *
+ * XEmacPss_BdRingAlloc() + XEmacPss_BdRingToHw(), as well as
+ * XEmacPss_BdRingFromHw() + XEmacPss_BdRingFree() are designed to be used in
+ * tandem. The same BD set retrieved with BdRingAlloc should be the same one
+ * provided to hardware with BdRingToHw. Same goes with BdRingFromHw and
+ * BdRIngFree.
+ *
+ * <b>Alignment & Data Cache Restrictions</b>
+ *
+ * Due to the design of the hardware, all RX buffers, BDs need to be 4-byte
+ * aligned. Please reference xemacpss_bd.h for cache related macros.
+ *
+ * DMA Tx:
+ *
+ * - If frame buffers exist in cached memory, then they must be flushed
+ * prior to committing them to hardware.
+ *
+ * DMA Rx:
+ *
+ * - If frame buffers exist in cached memory, then the cache must be
+ * invalidated for the memory region containing the frame prior to data
+ * access
+ *
+ * Both cache invalidate/flush are taken care of in driver code.
+ *
+ * <b>Buffer Copying</b>
+ *
+ * The driver is designed for a zero-copy buffer scheme. That is, the driver
+ * will not copy buffers. This avoids potential throughput bottlenecks within
+ * the driver. If byte copying is required, then the transfer will take longer
+ * to complete.
+ *
+ * <b>Checksum Offloading</b>
+ *
+ * The Embedded Processor Block Ethernet can be configured to perform IP, TCP
+ * and UDP checksum offloading in both receive and transmit directions.
+ *
+ * IP packets contain a 16-bit checksum field, which is the 16-bit 1s
+ * complement of the 1s complement sum of all 16-bit words in the header.
+ * TCP and UDP packets contain a 16-bit checksum field, which is the 16-bit
+ * 1s complement of the 1s complement sum of all 16-bit words in the header,
+ * the data and a conceptual pseudo header.
+ *
+ * To calculate these checksums in software requires each byte of the packet
+ * to be read. For TCP and UDP this can use a large amount of processing power.
+ * Offloading the checksum calculation to hardware can result in significant
+ * performance improvements.
+ *
+ * The transmit checksum offload is only available to use DMA in packet buffer
+ * mode. This is because the complete frame to be transmitted must be read
+ * into the packet buffer memory before the checksum can be calculated and
+ * written to the header at the beginning of the frame.
+ *
+ * For IP, TCP or UDP receive checksum offload to be useful, the operating
+ * system containing the protocol stack must be aware that this offload is
+ * available so that it can make use of the fact that the hardware has verified
+ * the checksum.
+ *
+ * When receive checksum offloading is enabled in the hardware, the IP header
+ * checksum is checked, where the packet meets the following criteria:
+ *
+ * 1. If present, the VLAN header must be four octets long and the CFI bit
+ * must not be set.
+ * 2. Encapsulation must be RFC 894 Ethernet Type Encoding or RFC 1042 SNAP
+ * encoding.
+ * 3. IP v4 packet.
+ * 4. IP header is of a valid length.
+ * 5. Good IP header checksum.
+ * 6. No IP fragmentation.
+ * 7. TCP or UDP packet.
+ *
+ * When an IP, TCP or UDP frame is received, the receive buffer descriptor
+ * gives an indication if the hardware was able to verify the checksums.
+ * There is also an indication if the frame had SNAP encapsulation. These
+ * indication bits will replace the type ID match indication bits when the
+ * receive checksum offload is enabled.
+ *
+ * If any of the checksums are verified incorrect by the hardware, the packet
+ * is discarded and the appropriate statistics counter incremented.
+ *
+ * <b>PHY Interfaces</b>
+ *
+ * RGMII 1.3 is the only interface supported.
+ *
+ * <b>Asserts</b>
+ *
+ * Asserts are used within all Xilinx drivers to enforce constraints on
+ * parameters. Asserts can be turned off on a system-wide basis by defining,
+ * at compile time, the NDEBUG identifier. By default, asserts are turned on
+ * and it is recommended that users leave asserts on during development. For
+ * deployment use -DNDEBUG compiler switch to remove assert code.
+ *
+ * @note
+ *
+ * Xilinx drivers are typically composed of two parts, one is the driver
+ * and the other is the adapter. The driver is independent of OS and processor
+ * and is intended to be highly portable. The adapter is OS-specific and
+ * facilitates communication between the driver and an OS.
+ * This driver is intended to be RTOS and processor independent. Any needs for
+ * dynamic memory management, threads or thread mutual exclusion, or cache
+ * control must be satisfied bythe layer above this driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a wsy 06/01/09 First release
+ * </pre>
+ *
+ ****************************************************************************/
+
+#ifndef XEMACPSS_H /* prevent circular inclusions */
+#define XEMACPSS_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files ********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xemacpss_hw.h"
+#include "xemacpss_bd.h"
+#include "xemacpss_bdring.h"
+
+/************************** Constant Definitions ****************************/
+
+/*
+ * Device information
+ */
+#define XEMACPSS_DEVICE_NAME "xemacpss"
+#define XEMACPSS_DEVICE_DESC "Xilinx PSS 10/100/1000 MAC"
+
+#define XPSS_GEM0_BASEADDR 0xE000B000
+#define XPSS_GEM1_BASEADDR 0xE000C000
+#define XPAR_XEMACPSS_NUM_INSTANCES 2
+#define XPAR_XEMACPSS_0_DEVICE_ID 0
+#define XPAR_XEMACPSS_0_BASEADDR XPSS_GEM0_BASEADDR
+#define XPAR_XEMACPSS_1_DEVICE_ID 1
+#define XPAR_XEMACPSS_1_BASEADDR XPSS_GEM1_BASEADDR
+
+/** @name Configuration options
+ *
+ * Device configuration options. See the XEmacPss_SetOptions(),
+ * XEmacPss_ClearOptions() and XEmacPss_GetOptions() for information on how to
+ * use options.
+ *
+ * The default state of the options are noted and are what the device and
+ * driver will be set to after calling XEmacPss_Reset() or
+ * XEmacPss_Initialize().
+ *
+ * @{
+ */
+
+#define XEMACPSS_PROMISC_OPTION 0x00000001
+/**< Accept all incoming packets.
+ * This option defaults to disabled (cleared) */
+
+#define XEMACPSS_FRAME1536_OPTION 0x00000002
+/**< Frame larger than 1516 support for Tx & Rx.
+ * This option defaults to disabled (cleared) */
+
+#define XEMACPSS_VLAN_OPTION 0x00000004
+/**< VLAN Rx & Tx frame support.
+ * This option defaults to disabled (cleared) */
+
+#define XEMACPSS_FLOW_CONTROL_OPTION 0x00000010
+/**< Enable recognition of flow control frames on Rx
+ * This option defaults to enabled (set) */
+
+#define XEMACPSS_FCS_STRIP_OPTION 0x00000020
+/**< Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not
+ * stripped.
+ * This option defaults to enabled (set) */
+
+#define XEMACPSS_FCS_INSERT_OPTION 0x00000040
+/**< Generate FCS field and add PAD automatically for outgoing frames.
+ * This option defaults to disabled (cleared) */
+
+#define XEMACPSS_LENTYPE_ERR_OPTION 0x00000080
+/**< Enable Length/Type error checking for incoming frames. When this option is
+ * set, the MAC will filter frames that have a mismatched type/length field
+ * and if XEMACPSS_REPORT_RXERR_OPTION is set, the user is notified when these
+ * types of frames are encountered. When this option is cleared, the MAC will
+ * allow these types of frames to be received.
+ *
+ * This option defaults to disabled (cleared) */
+
+#define XEMACPSS_TRANSMITTER_ENABLE_OPTION 0x00000100
+/**< Enable the transmitter.
+ * This option defaults to enabled (set) */
+
+#define XEMACPSS_RECEIVER_ENABLE_OPTION 0x00000200
+/**< Enable the receiver
+ * This option defaults to enabled (set) */
+
+#define XEMACPSS_BROADCAST_OPTION 0x00000400
+/**< Allow reception of the broadcast address
+ * This option defaults to enabled (set) */
+
+#define XEMACPSS_MULTICAST_OPTION 0x00000800
+/**< Allows reception of multicast addresses programmed into hash
+ * This option defaults to disabled (clear) */
+
+#define XEMACPSS_RX_CHKSUM_ENABLE_OPTION 0x00001000
+/**< Enable the RX checksum offload
+ * This option defaults to enabled (set) */
+
+#define XEMACPSS_TX_CHKSUM_ENABLE_OPTION 0x00002000
+/**< Enable the TX checksum offload
+ * This option defaults to enabled (set) */
+
+
+#define XEMACPSS_DEFAULT_OPTIONS \
+ (XEMACPSS_FLOW_CONTROL_OPTION | \
+ XEMACPSS_FCS_INSERT_OPTION | \
+ XEMACPSS_FCS_STRIP_OPTION | \
+ XEMACPSS_BROADCAST_OPTION | \
+ XEMACPSS_LENTYPE_ERR_OPTION | \
+ XEMACPSS_TRANSMITTER_ENABLE_OPTION | \
+ XEMACPSS_RECEIVER_ENABLE_OPTION | \
+ XEMACPSS_RX_CHKSUM_ENABLE_OPTION | \
+ XEMACPSS_TX_CHKSUM_ENABLE_OPTION)
+
+/**< Default options set when device is initialized or reset */
+/*@}*/
+
+/** @name Callback identifiers
+ *
+ * These constants are used as parameters to XEmacPss_SetHandler()
+ * @{
+ */
+#define XEMACPSS_HANDLER_DMASEND 1
+#define XEMACPSS_HANDLER_DMARECV 2
+#define XEMACPSS_HANDLER_ERROR 3
+/*@}*/
+
+/* Constants to determine the configuration of the hardware device. They are
+ * used to allow the driver to verify it can operate with the hardware.
+ */
+#define XEMACPSS_MDIO_DIV_DFT MDC_DIV_32 /**< Default MDIO clock divisor */
+
+/* The next few constants help upper layers determine the size of memory
+ * pools used for Ethernet buffers and descriptor lists.
+ */
+#define XEMACPSS_MAC_ADDR_SIZE 6 /* size of Ethernet header */
+
+#define XEMACPSS_MTU 1500 /* max MTU size of Ethernet frame */
+#define XEMACPSS_HDR_SIZE 14 /* size of Ethernet header */
+#define XEMACPSS_HDR_VLAN_SIZE 18 /* size of Ethernet header with VLAN */
+#define XEMACPSS_TRL_SIZE 4 /* size of Ethernet trailer (FCS) */
+#define XEMACPSS_MAX_FRAME_SIZE (XEMACPSS_MTU + XEMACPSS_HDR_SIZE + \
+ XEMACPSS_TRL_SIZE)
+#define XEMACPSS_MAX_VLAN_FRAME_SIZE (XEMACPSS_MTU + XEMACPSS_HDR_SIZE + \
+ XEMACPSS_HDR_VLAN_SIZE + XEMACPSS_TRL_SIZE)
+
+
+/**************************** Type Definitions ******************************/
+/** @name Typedefs for callback functions
+ *
+ * These callbacks are invoked in interrupt context.
+ * @{
+ */
+/**
+ * Callback invoked when frame(s) have been sent or received in interrupt
+ * driven DMA mode. To set the send callback, invoke XEmacPss_SetHandler().
+ *
+ * @param CallBackRef is user data assigned when the callback was set.
+ *
+ * @note
+ * See xemacpss_hw.h for bitmasks definitions and the device hardware spec for
+ * further information on their meaning.
+ *
+ */
+typedef void (*XEmacPss_Handler) (void *CallBackRef);
+
+/**
+ * Callback when an asynchronous error occurs. To set this callback, invoke
+ * XEmacPss_SetHandler() with XEMACPSS_HANDLER_ERROR in the HandlerType
+ * paramter.
+ *
+ * @param CallBackRef is user data assigned when the callback was set.
+ * @param Direction defines either receive or transmit error(s) has occurred.
+ * @param ErrorWord definition varies with Direction
+ *
+ */
+typedef void (*XEmacPss_ErrHandler) (void *CallBackRef, u8 Direction,
+ u32 ErrorWord);
+
+/*@}*/
+
+/**
+ * This typedef contains configuration information for a device.
+ */
+typedef struct {
+ u16 DeviceId; /**< Unique ID of device */
+ u32 BaseAddress;/**< Physical base address of IPIF registers */
+} XEmacPss_Config;
+
+
+/**
+ * The XEmacPss driver instance data. The user is required to allocate a
+ * structure of this type for every XEmacPss device in the system. A pointer
+ * to a structure of this type is then passed to the driver API functions.
+ */
+typedef struct XEmacPss {
+ XEmacPss_Config Config; /* Hardware configuration */
+ u32 IsStarted; /* Device is currently started */
+ u32 IsReady; /* Device is initialized and ready */
+ u32 Options; /* Current options word */
+
+ XEmacPss_BdRing TxBdRing; /* Transmit BD ring */
+ XEmacPss_BdRing RxBdRing; /* Receive BD ring */
+
+ XEmacPss_Handler SendHandler;
+ XEmacPss_Handler RecvHandler;
+ void *SendRef;
+ void *RecvRef;
+
+ XEmacPss_ErrHandler ErrorHandler;
+ void *ErrorRef;
+
+} XEmacPss;
+
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/****************************************************************************/
+/**
+* Retrieve the Tx ring object. This object can be used in the various Ring
+* API functions.
+*
+* @param InstancePtr is the DMA channel to operate on.
+*
+* @return TxBdRing attribute
+*
+* @note
+* C-style signature:
+* XEmacPss_BdRing XEmacPss_GetTxRing(XEmacPss *InstancePtr)
+*
+*****************************************************************************/
+#define XEmacPss_GetTxRing(InstancePtr) ((InstancePtr)->TxBdRing)
+
+/****************************************************************************/
+/**
+* Retrieve the Rx ring object. This object can be used in the various Ring
+* API functions.
+*
+* @param InstancePtr is the DMA channel to operate on.
+*
+* @return RxBdRing attribute
+*
+* @note
+* C-style signature:
+* XEmacPss_BdRing XEmacPss_GetRxRing(XEmacPss *InstancePtr)
+*
+*****************************************************************************/
+#define XEmacPss_GetRxRing(InstancePtr) ((InstancePtr)->RxBdRing)
+
+/****************************************************************************/
+/**
+*
+* Enable interrupts specified in <i>Mask</i>. The corresponding interrupt for
+* each bit set to 1 in <i>Mask</i>, will be enabled.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param Mask contains a bit mask of interrupts to enable. The mask can
+* be formed using a set of bitwise or'd values.
+*
+* @note
+* The state of the transmitter and receiver are not modified by this function.
+* C-style signature
+* void XEmacPss_IntEnable(XEmacPss *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XEmacPss_IntEnable(InstancePtr, Mask) \
+ XEmacPss_WriteReg((InstancePtr)->Config.BaseAddress, \
+ XEMACPSS_IER_OFFSET, \
+ XEmacPss_ReadReg((InstancePtr)->Config.BaseAddress, \
+ XEMACPSS_IER_OFFSET) | ((Mask) & XEMACPSS_IXR_ALL_MASK));
+
+/****************************************************************************/
+/**
+*
+* Disable interrupts specified in <i>Mask</i>. The corresponding interrupt for
+* each bit set to 1 in <i>Mask</i>, will be enabled.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param Mask contains a bit mask of interrupts to disable. The mask can
+* be formed using a set of bitwise or'd values.
+*
+* @note
+* The state of the transmitter and receiver are not modified by this function.
+* C-style signature
+* void XEmacPss_IntDisable(XEmacPss *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XEmacPss_IntDisable(InstancePtr, Mask) \
+ XEmacPss_WriteReg((InstancePtr)->Config.BaseAddress, \
+ XEMACPSS_IER_OFFSET, \
+ XEmacPss_ReadReg((InstancePtr)->Config.BaseAddress, \
+ XEMACPSS_IER_OFFSET) & ~((Mask) & XEMACPSS_IXR_ALL_MASK));
+
+/****************************************************************************/
+/**
+*
+* This macro triggers trasmit circuit to send data currently in TX buffer(s).
+*
+* @param InstancePtr is a pointer to the XEmacPss instance to be worked on.
+*
+* @return
+*
+* @note
+*
+* Signature: void XEmacPss_Transmit(XEmacPss *InstancePtr)
+*
+*****************************************************************************/
+#define XEmacPss_Transmit(InstancePtr) \
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress, \
+ XEMACPSS_NWCTRL_OFFSET, \
+ (XEmacPss_ReadReg(InstancePtr->Config.BaseAddress, \
+ XEMACPSS_NWCTRL_OFFSET) | XEMACPSS_NWCTRL_STARTTX_MASK))
+
+/****************************************************************************/
+/**
+*
+* This macro determines if the device is configured with checksum offloading
+* on the receive channel
+*
+* @param InstancePtr is a pointer to the XEmacPss instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with checksum offloading, or
+* FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XEmacPss_IsRxCsum(XEmacPss *InstancePtr)
+*
+*****************************************************************************/
+#define XEmacPss_IsRxCsum(InstancePtr) \
+ ((XEmacPss_ReadReg((InstancePtr)->Config.BaseAddress, \
+ XEMACPSS_NWCFG_OFFSET) & XEMACPSS_NWCFG_RXCHKSUMEN_MASK) \
+ ? TRUE : FALSE)
+
+/****************************************************************************/
+/**
+*
+* This macro determines if the device is configured with checksum offloading
+* on the transmit channel
+*
+* @param InstancePtr is a pointer to the XEmacPss instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with checksum offloading, or
+* FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XEmacPss_IsTxCsum(XEmacPss *InstancePtr)
+*
+*****************************************************************************/
+#define XEmacPss_IsTxCsum(InstancePtr) \
+ ((XEmacPss_ReadReg((InstancePtr)->Config.BaseAddress, \
+ XEMACPSS_DMACR_OFFSET) & XEMACPSS_DMACR_TCPCKSUM_MASK) \
+ ? TRUE : FALSE)
+
+/************************** Function Prototypes *****************************/
+
+/*
+ * Initialization functions in xemacpss.c
+ */
+int XEmacPss_CfgInitialize(XEmacPss *InstancePtr, XEmacPss_Config *CfgPtr,
+ u32 EffectiveAddress);
+void XEmacPss_Start(XEmacPss *InstancePtr);
+void XEmacPss_Stop(XEmacPss *InstancePtr);
+void XEmacPss_Reset(XEmacPss *InstancePtr);
+
+/*
+ * Lookup configuration in xemacpss_sinit.c
+ */
+XEmacPss_Config *XEmacPss_LookupConfig(u16 DeviceId);
+
+/*
+ * Interrupt-related functions in xemacpss_intr.c
+ * DMA only and FIFO is not supported. This DMA does not support coalescing.
+ */
+int XEmacPss_SetHandler(XEmacPss *InstancePtr, u32 HandlerType,
+ void *FuncPtr, void *CallBackRef);
+void XEmacPss_IntrHandler(void *InstancePtr);
+
+/*
+ * MAC configuration/control functions in XEmacPss_control.c
+ */
+int XEmacPss_SetOptions(XEmacPss *InstancePtr, u32 Options);
+int XEmacPss_ClearOptions(XEmacPss *InstancePtr, u32 Options);
+u32 XEmacPss_GetOptions(XEmacPss *InstancePtr);
+
+int XEmacPss_SetMacAddress(XEmacPss *InstancePtr, void *AddressPtr, u8 Index);
+void XEmacPss_GetMacAddress(XEmacPss *InstancePtr, void *AddressPtr, u8 Index);
+
+int XEmacPss_SetHash(XEmacPss *InstancePtr, void *AddressPtr);
+void XEmacPss_ClearHash(XEmacPss *InstancePtr);
+void XEmacPss_GetHash(XEmacPss *InstancePtr, void *AddressPtr);
+
+void XEmacPss_PhySetMdioDivisor(XEmacPss *InstancePtr,
+ XEmacPss_MdcDiv Divisor);
+void XEmacPss_SetOperatingSpeed(XEmacPss *InstancePtr, u16 Speed);
+u16 XEmacPss_GetOperatingSpeed(XEmacPss *InstancePtr);
+int XEmacPss_PhyRead(XEmacPss *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 *PhyDataPtr);
+int XEmacPss_PhyWrite(XEmacPss *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 PhyData);
+int XEmacPss_SetTypeIdCheck(XEmacPss *InstancePtr, u32 Id_Check, u8 Index);
+
+int XEmacPss_SendPausePacket(XEmacPss *InstancePtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
--- /dev/null
+/* $Id: xemacpss_bd.h,v 1.1.2.1 2009/06/17 16:10:26 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xemacpss_bd.h
+ *
+ * This header provides operations to manage buffer descriptors in support
+ * of scatter-gather DMA.
+ *
+ * The API exported by this header defines abstracted macros that allow the
+ * user to read/write specific BD fields.
+ *
+ * <b>Buffer Descriptors</b>
+ *
+ * A buffer descriptor (BD) defines a DMA transaction. The macros defined by
+ * this header file allow access to most fields within a BD to tailor a DMA
+ * transaction according to user and hardware requirements. See the hardware
+ * IP DMA spec for more information on BD fields and how they affect transfers.
+ *
+ * The XEmacPss_Bd structure defines a BD. The organization of this structure
+ * is driven mainly by the hardware for use in scatter-gather DMA transfers.
+ *
+ * <b>Performance</b>
+ *
+ * Limiting I/O to BDs can improve overall performance of the DMA channel.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a wsy 06/01/09 First release
+ * </pre>
+ *
+ * ***************************************************************************
+ */
+
+#ifndef XEMACPSS_BD_H /* prevent circular inclusions */
+#define XEMACPSS_BD_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+//#include <string.h>
+//#include "xbasic_types.h"
+#include <common.h>
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/* Minimum BD alignment */
+#define XEMACPSS_DMABD_MINIMUM_ALIGNMENT 4
+
+/**
+ * The XEmacPss_Bd is the type for buffer descriptors (BDs).
+ */
+#define XEMACPSS_BD_NUM_WORDS 2
+typedef u32 XEmacPss_Bd[XEMACPSS_BD_NUM_WORDS];
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+ * Zero out BD fields
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @return Nothing
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdClear(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdClear(BdPtr) \
+ memset((BdPtr), 0, sizeof(XEmacPss_Bd))
+
+/****************************************************************************/
+/**
+*
+* Read the given Buffer Descriptor word.
+*
+* @param BaseAddress is the base address of the BD to read
+* @param Offset is the word offset to be read
+*
+* @return The 32-bit value of the field
+*
+* @note
+* C-style signature:
+* u32 XEmacPss_BdRead(u32 BaseAddress, u32 Offset)
+*
+*****************************************************************************/
+#define XEmacPss_BdRead(BaseAddress, Offset) \
+ (*(u32*)((u32)(BaseAddress) + (u32)(Offset)))
+
+/****************************************************************************/
+/**
+*
+* Write the given Buffer Descriptor word.
+*
+* @param BaseAddress is the base address of the BD to write
+* @param Offset is the word offset to be written
+* @param Data is the 32-bit value to write to the field
+*
+* @return None.
+*
+* @note
+* C-style signature:
+* void XEmacPss_BdWrite(u32 BaseAddress, u32 Offset, u32 Data)
+*
+*****************************************************************************/
+#define XEmacPss_BdWrite(BaseAddress, Offset, Data) \
+ (*(u32*)((u32)(BaseAddress) + (u32)(Offset)) = (Data))
+
+/*****************************************************************************/
+/**
+ * Set the BD's Address field (word 0).
+ *
+ * @param BdPtr is the BD pointer to operate on
+ * @param Addr is the value to write to BD's status field.
+ *
+ * @note :
+ *
+ * C-style signature:
+ * void XEmacPss_BdSetAddressTx(XEmacPss_Bd* BdPtr, u32 Addr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetAddressTx(BdPtr, Addr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_ADDR_OFFSET, (u32)(Addr)))
+
+
+/*****************************************************************************/
+/**
+ * Set the BD's Address field (word 0).
+ *
+ * @param BdPtr is the BD pointer to operate on
+ * @param Data is the value to write to BD's status field.
+ *
+ * @note : Due to some bits are mixed within recevie BD's address field,
+ * read-modify-write is performed.
+ *
+ * C-style signature:
+ * void XEmacPss_BdSetAddressRx(XEmacPss_Bd* BdPtr, u32 Addr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetAddressRx(BdPtr, Addr) \
+ XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_ADDR_OFFSET, \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_ADDR_OFFSET) & \
+ ~XEMACPSS_RXBUF_ADD_MASK) | (u32)(Addr)))
+
+
+/*****************************************************************************/
+/**
+ * Set the BD's Status field (word 1).
+ *
+ * @param BdPtr is the BD pointer to operate on
+ * @param Data is the value to write to BD's status field.
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdSetStatus(XEmacPss_Bd* BdPtr, u32 Data)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetStatus(BdPtr, Data) \
+ XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) | Data)
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD's Packet DMA transfer status word (word 1).
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @return Status word
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdGetStatus(XEmacPss_Bd* BdPtr)
+ *
+ * Due to the BD bit layout differences in transmit and receive. User's
+ * caution is required.
+ *****************************************************************************/
+#define XEmacPss_BdGetStatus(BdPtr) \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Get the address (bits 0..31) of the BD's buffer address (word 0)
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdGetBufAddr(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdGetBufAddr(BdPtr) \
+ (XEmacPss_BdRead((BdPtr), XEMACPSS_BD_ADDR_OFFSET))
+
+
+/*****************************************************************************/
+/**
+ * Set transfer length in bytes for the given BD. The length must be set each
+ * time a BD is submitted to hardware.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ * @param LenBytes is the number of bytes to transfer.
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdSetLength(XEmacPss_Bd* BdPtr, u32 LenBytes)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetLength(BdPtr, LenBytes) \
+ XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ ~XEMACPSS_TXBUF_LEN_MASK) | (LenBytes)))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD length field.
+ *
+ * For Tx channels, the returned value is the same as that written with
+ * XEmacPss_BdSetLength().
+ *
+ * For Rx channels, the returned value is the size of the received packet.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @return Length field processed by hardware or set by
+ * XEmacPss_BdSetLength().
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdGetLength(XEmacPss_Bd* BdPtr)
+ * XEAMCPSS_RXBUF_LEN_MASK is same as XEMACPSS_TXBUF_LEN_MASK.
+ *
+ *****************************************************************************/
+#define XEmacPss_BdGetLength(BdPtr) \
+ (XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_LEN_MASK)
+
+
+/*****************************************************************************/
+/**
+ * Test whether the given BD has been marked as the last BD of a packet.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @return TRUE if BD represents the "Last" BD of a packet, FALSE otherwise
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsLast(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsLast(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_EOF_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Tell the DMA engine that the given transmit BD marks the end of the current
+ * packet to be processed.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdSetLast(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetLast(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) | \
+ XEMACPSS_TXBUF_LAST_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Tell the DMA engine that the current packet does not end with the given
+ * BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdClearLast(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdClearLast(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ ~XEMACPSS_TXBUF_LAST_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Set this bit to mark the last descriptor in the receive buffer descriptor
+ * list.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdSetRxWrap(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetRxWrap(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_ADDR_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_ADDR_OFFSET) | \
+ XEMACPSS_RXBUF_WRAP_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Determine the wrap bit of the receive BD which indicates end of the
+ * BD list.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxWrap(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxWrap(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_ADDR_OFFSET) & \
+ XEMACPSS_RXBUF_WRAP_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Sets this bit to mark the last descriptor in the transmit buffer
+ * descriptor list.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdSetTxWrap(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetTxWrap(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) | \
+ XEMACPSS_TXBUF_WRAP_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Determine the wrap bit of the transmit BD which indicates end of the
+ * BD list.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdGetTxWrap(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsTxWrap(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_TXBUF_WRAP_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/*
+ * Must clear this bit to enable the MAC to write data to the receive
+ * buffer. Hardware sets this bit once it has successfully written a frame to
+ * memory. Once set, software has to clear the bit before the buffer can be
+ * used again. This macro clear the new bit of the receive BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdClearRxNew(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdClearRxNew(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_ADDR_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_ADDR_OFFSET) & \
+ ~XEMACPSS_RXBUF_NEW_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Determine the new bit of the receive BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxNew(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxNew(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_ADDR_OFFSET) & \
+ XEMACPSS_RXBUF_NEW_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Software sets this bit to disable the buffer to be read by the hardware.
+ * Hardware sets this bit for the first buffer of a frame once it has been
+ * successfully transmitted. This macro sets this bit of transmit BD to avoid
+ * confusion.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdSetTxUsed(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetTxUsed(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) | \
+ XEMACPSS_TXBUF_USED_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Software clears this bit to enable the buffer to be read by the hardware.
+ * Hardware sets this bit for the first buffer of a frame once it has been
+ * successfully transmitted. This macro clears this bit of transmit BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XEmacPss_BdClearTxUsed(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdClearTxUsed(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ ~XEMACPSS_TXBUF_USED_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Determine the used bit of the transmit BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsTxUsed(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsTxUsed(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_TXBUF_USED_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine if a frame fails to be transmitted due to too many retries.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsTxRetry(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsTxRetry(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_TXBUF_RETRY_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine if a frame fails to be transmitted due to data can not be
+ * feteched in time or buffers are exhausted.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsTxUrun(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsTxUrun(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_TXBUF_URUN_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine if a frame fails to be transmitted due to buffer is exhausted
+ * mid-frame.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsTxExh(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsTxExh(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_TXBUF_EXH_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Sets this bit, no CRC will be appended to the current frame. This control
+ * bit must be set for the first buffer in a frame and will be ignored for
+ * the subsequent buffers of a frame.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * This bit must be clear when using the transmit checksum generation offload,
+ * otherwise checksum generation and substitution will not occur.
+ *
+ * C-style signature:
+ * u32 XEmacPss_BdSetTxNoCRC(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdSetTxNoCRC(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) | \
+ XEMACPSS_TXBUF_NOCRC_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Clear this bit, CRC will be appended to the current frame. This control
+ * bit must be set for the first buffer in a frame and will be ignored for
+ * the subsequent buffers of a frame.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * This bit must be clear when using the transmit checksum generation offload,
+ * otherwise checksum generation and substitution will not occur.
+ *
+ * C-style signature:
+ * u32 XEmacPss_BdClearTxNoCRC(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdClearTxNoCRC(BdPtr) \
+ (XEmacPss_BdWrite((BdPtr), XEMACPSS_BD_STAT_OFFSET, \
+ XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ ~XEMACPSS_TXBUF_NOCRC_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Determine the broadcast bit of the receive BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxBcast(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxBcast(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_BCAST_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine the multicast hash bit of the receive BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxMultiHash(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxMultiHash(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_MULTIHASH_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine the unicast hash bit of the receive BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxUniHash(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxUniHash(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_UNIHASH_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine if the received frame is a VLAN Tagged frame.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxVlan(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxVlan(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_VLAN_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine if the received frame has Type ID of 8100h and null VLAN
+ * identifier(Priority tag).
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxPri(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxPri(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_PRI_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine if the received frame's Concatenation Format Indicator (CFI) of
+ * the frames VLANTCI field was set.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdIsRxCFI(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxCFI(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_CFI_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine the End Of Frame (EOF) bit of the receive BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdGetRxEOF(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxEOF(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_EOF_MASK) ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+ * Determine the Start Of Frame (SOF) bit of the receive BD.
+ *
+ * @param BdPtr is the BD pointer to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XEmacPss_BdGetRxSOF(XEmacPss_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XEmacPss_BdIsRxSOF(BdPtr) \
+ ((XEmacPss_BdRead((BdPtr), XEMACPSS_BD_STAT_OFFSET) & \
+ XEMACPSS_RXBUF_SOF_MASK) ? TRUE : FALSE)
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
--- /dev/null
+/* $Id: xemacpss_bdring.c,v 1.1.2.2 2009/08/04 23:30:32 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemacpss_bdring.c
+*
+* This file implements buffer descriptor ring related functions.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a wsy 06/01/09 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xstatus.h"
+//#include "xcache.h"
+#include "xemacpss_hw.h"
+#include "xemacpss_bd.h"
+#include "xemacpss_bdring.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/****************************************************************************
+ * Define methods to flush and invalidate cache for BDs should they be
+ * located in cached memory. These macros may NOPs if the underlying
+ * XENV_BD_CACHE macros are not implemented or they do nothing.
+ *
+ * @note Assume cache line size is in word length. Please update accordingly
+ * for different system.
+ ****************************************************************************/
+//#define XENV_BD_CACHE_FLUSH
+//#define XENV_BD_CACHE_INVALIDATE
+
+#ifdef XENV_BD_CACHE_FLUSH
+# define XEMACPSS_CACHE_FLUSH(BdPtr) \
+ XCache_FlushDCacheRange((unsigned)BdPtr, XEMACPSS_BD_NUM_WORDS * 4)
+#else
+# define XEMACPSS_CACHE_FLUSH(BdPtr)
+#endif
+
+#ifdef XENV_BD_CACHE_INVALIDATE
+# define XEMACPSS_CACHE_INVALIDATE(BdPtr) \
+ XCache_InvalidateDCacheRange((unsigned)BdPtr, XEMACPSS_BD_NUM_WORDS * 4)
+#else
+# define XEMACPSS_CACHE_INVALIDATE(BdPtr)
+#endif
+
+/****************************************************************************
+ * Compute the virtual address of a descriptor from its physical address
+ *
+ * @param BdPtr is the physical address of the BD
+ *
+ * @returns Virtual address of BdPtr
+ *
+ * @note Assume BdPtr is always a valid BD in the ring
+ ****************************************************************************/
+#define XEMACPSS_PHYS_TO_VIRT(BdPtr) \
+ ((u32)BdPtr + (RingPtr->BaseBdAddr - RingPtr->PhysBaseAddr))
+
+/****************************************************************************
+ * Compute the physical address of a descriptor from its virtual address
+ *
+ * @param BdPtr is the physical address of the BD
+ *
+ * @returns Physical address of BdPtr
+ *
+ * @note Assume BdPtr is always a valid BD in the ring
+ ****************************************************************************/
+#define XEMACPSS_VIRT_TO_PHYS(BdPtr) \
+ ((u32)BdPtr - (RingPtr->BaseBdAddr - RingPtr->PhysBaseAddr))
+
+/****************************************************************************
+ * Move the BdPtr argument ahead an arbitrary number of BDs wrapping around
+ * to the beginning of the ring if needed.
+ *
+ * We know if a wrapaound should occur if the new BdPtr is greater than
+ * the high address in the ring OR if the new BdPtr crosses over the
+ * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not
+ * allow a BD space to span this boundary.
+ *
+ * @param RingPtr is the ring BdPtr appears in
+ * @param BdPtr on input is the starting BD position and on output is the
+ * final BD position
+ * @param NumBd is the number of BD spaces to increment
+ *
+ ****************************************************************************/
+#define XEMACPSS_RING_SEEKAHEAD(RingPtr, BdPtr, NumBd) \
+ { \
+ u32 Addr = (u32)BdPtr; \
+ \
+ Addr += ((RingPtr)->Separation * NumBd); \
+ if ((Addr > (RingPtr)->HighBdAddr) || ((u32)BdPtr > Addr)) \
+ { \
+ Addr -= (RingPtr)->Length; \
+ } \
+ \
+ BdPtr = (XEmacPss_Bd*)Addr; \
+ }
+
+/****************************************************************************
+ * Move the BdPtr argument backwards an arbitrary number of BDs wrapping
+ * around to the end of the ring if needed.
+ *
+ * We know if a wrapaound should occur if the new BdPtr is less than
+ * the base address in the ring OR if the new BdPtr crosses over the
+ * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not
+ * allow a BD space to span this boundary.
+ *
+ * @param RingPtr is the ring BdPtr appears in
+ * @param BdPtr on input is the starting BD position and on output is the
+ * final BD position
+ * @param NumBd is the number of BD spaces to increment
+ *
+ ****************************************************************************/
+#define XEMACPSS_RING_SEEKBACK(RingPtr, BdPtr, NumBd) \
+ { \
+ u32 Addr = (u32)BdPtr; \
+ \
+ Addr -= ((RingPtr)->Separation * NumBd); \
+ if ((Addr < (RingPtr)->BaseBdAddr) || ((u32)BdPtr < Addr)) \
+ { \
+ Addr += (RingPtr)->Length; \
+ } \
+ \
+ BdPtr = (XEmacPss_Bd*)Addr; \
+ }
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+ * Using a memory segment allocated by the caller, create and setup the BD list
+ * for the given DMA channel.
+ *
+ * @param RingPtr is the instance to be worked on.
+ * @param PhysAddr is the physical base address of user memory region.
+ * @param VirtAddr is the virtual base address of the user memory region. If
+ * address translation is not being utilized, then VirtAddr should be
+ * equivalent to PhysAddr.
+ * @param Alignment governs the byte alignment of individual BDs. This function
+ * will enforce a minimum alignment of 4 bytes with no maximum as long
+ * as it is specified as a power of 2.
+ * @param BdCount is the number of BDs to setup in the user memory region. It
+ * is assumed the region is large enough to contain the BDs.
+ *
+ * @return
+ *
+ * - XST_SUCCESS if initialization was successful
+ * - XST_NO_FEATURE if the provided instance is a non DMA type
+ * channel.
+ * - XST_INVALID_PARAM under any of the following conditions:
+ * 1) PhysAddr and/or VirtAddr are not aligned to the given Alignment
+ * parameter;
+ * 2) Alignment parameter does not meet minimum requirements or is not a
+ * power of 2 value;
+ * 3) BdCount is 0.
+ * - XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans
+ * over address 0x00000000 in virtual address space.
+ *
+ * @note
+ * Make sure to pass in the right alignment value.
+ *****************************************************************************/
+int XEmacPss_BdRingCreate(XEmacPss_BdRing * RingPtr, u32 PhysAddr,
+ u32 VirtAddr, u32 Alignment, unsigned BdCount)
+{
+ unsigned i;
+ u32 BdVirtAddr;
+ u32 BdPhyAddr;
+
+ /* In case there is a failure prior to creating list, make sure the
+ * following attributes are 0 to prevent calls to other functions
+ * from doing anything.
+ */
+ RingPtr->AllCnt = 0;
+ RingPtr->FreeCnt = 0;
+ RingPtr->HwCnt = 0;
+ RingPtr->PreCnt = 0;
+ RingPtr->PostCnt = 0;
+
+ /* Make sure Alignment parameter meets minimum requirements */
+ if (Alignment < XEMACPSS_DMABD_MINIMUM_ALIGNMENT) {
+ return (XST_INVALID_PARAM);
+ }
+
+ /* Make sure Alignment is a power of 2 */
+ if ((Alignment - 1) & Alignment) {
+ return (XST_INVALID_PARAM);
+ }
+
+ /* Make sure PhysAddr and VirtAddr are on same Alignment */
+ if ((PhysAddr % Alignment) || (VirtAddr % Alignment)) {
+ return (XST_INVALID_PARAM);
+ }
+
+ /* Is BdCount reasonable? */
+ if (BdCount == 0) {
+ return (XST_INVALID_PARAM);
+ }
+
+ /* Figure out how many bytes will be between the start of adjacent BDs */
+ RingPtr->Separation =
+ (sizeof(XEmacPss_Bd) + (Alignment - 1)) & ~(Alignment - 1);
+
+ /* Must make sure the ring doesn't span address 0x00000000. If it does,
+ * then the next/prev BD traversal macros will fail.
+ */
+ if (VirtAddr > (VirtAddr + (RingPtr->Separation * BdCount) - 1)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Initial ring setup:
+ * - Clear the entire space
+ * - Setup each BD's BDA field with the physical address of the next BD
+ */
+ memset((void *) VirtAddr, 0, (RingPtr->Separation * BdCount));
+
+ BdVirtAddr = VirtAddr;
+ BdPhyAddr = PhysAddr + RingPtr->Separation;
+ for (i = 1; i < BdCount; i++) {
+ XEMACPSS_CACHE_FLUSH(BdVirtAddr);
+ BdVirtAddr += RingPtr->Separation;
+ BdPhyAddr += RingPtr->Separation;
+ }
+
+ /* Setup and initialize pointers and counters */
+ RingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+ RingPtr->BaseBdAddr = VirtAddr;
+ RingPtr->PhysBaseAddr = PhysAddr;
+ RingPtr->HighBdAddr = BdVirtAddr;
+ RingPtr->Length =
+ RingPtr->HighBdAddr - RingPtr->BaseBdAddr + RingPtr->Separation;
+ RingPtr->AllCnt = BdCount;
+ RingPtr->FreeCnt = BdCount;
+ RingPtr->FreeHead = (XEmacPss_Bd *) VirtAddr;
+ RingPtr->PreHead = (XEmacPss_Bd *) VirtAddr;
+ RingPtr->HwHead = (XEmacPss_Bd *) VirtAddr;
+ RingPtr->HwTail = (XEmacPss_Bd *) VirtAddr;
+ RingPtr->PostHead = (XEmacPss_Bd *) VirtAddr;
+ RingPtr->BdaRestart = (XEmacPss_Bd *) PhysAddr;
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Clone the given BD into every BD in the list.
+ * every field of the source BD is replicated in every BD of the list.
+ *
+ * This function can be called only when all BDs are in the free group such as
+ * they are immediately after initialization with XEmacPss_BdRingCreate().
+ * This prevents modification of BDs while they are in use by hardware or the
+ * user.
+ *
+ * @param RingPtr is the pointer of BD ring instance to be worked on.
+ * @param SrcBdPtr is the source BD template to be cloned into the list. This
+ * BD will be modified.
+ *
+ * @return
+ * - XST_SUCCESS if the list was modified.
+ * - XST_DMA_SG_NO_LIST if a list has not been created.
+ * - XST_DMA_SG_LIST_ERROR if some of the BDs in this channel are under
+ * hardware or user control.
+ * - XST_DEVICE_IS_STARTED if the DMA channel has not been stopped.
+ *
+ *****************************************************************************/
+int XEmacPss_BdRingClone(XEmacPss_BdRing * RingPtr, XEmacPss_Bd * SrcBdPtr,
+ u8 Direction)
+{
+ unsigned i;
+ u32 CurBd;
+
+ /* Can't do this function if there isn't a ring */
+ if (RingPtr->AllCnt == 0) {
+ return (XST_DMA_SG_NO_LIST);
+ }
+
+ /* Can't do this function with the channel running */
+ if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Can't do this function with some of the BDs in use */
+ if (RingPtr->FreeCnt != RingPtr->AllCnt) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ if ((Direction != XEMACPSS_SEND) && (Direction != XEMACPSS_RECV)) {
+ return (XST_INVALID_PARAM);
+ }
+
+ /* Starting from the top of the ring, save BD.Next, overwrite the entire
+ * BD with the template, then restore BD.Next
+ */
+ for (i = 0, CurBd = (u32) RingPtr->BaseBdAddr;
+ i < RingPtr->AllCnt; i++, CurBd += RingPtr->Separation) {
+ memcpy((void *)CurBd, SrcBdPtr, sizeof(XEmacPss_Bd));
+ XEMACPSS_CACHE_FLUSH(CurBd);
+ }
+
+ CurBd -= RingPtr->Separation;
+
+ if (Direction == XEMACPSS_RECV) {
+ XEmacPss_BdSetRxWrap(CurBd);
+ }
+ else {
+ XEmacPss_BdSetTxWrap(CurBd);
+ }
+
+ XEMACPSS_CACHE_FLUSH(CurBd);
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Reserve locations in the BD list. The set of returned BDs may be modified
+ * in preparation for future DMA transaction(s). Once the BDs are ready to be
+ * submitted to hardware, the user must call XEmacPss_BdRingToHw() in the same
+ * order which they were allocated here. Example:
+ *
+ * <pre>
+ * NumBd = 2;
+ * Status = XEmacPss_BdRingAlloc(MyRingPtr, NumBd, &MyBdSet);
+ *
+ * if (Status != XST_SUCCESS)
+ * {
+ * // Not enough BDs available for the request
+ * }
+ *
+ * CurBd = MyBdSet;
+ * for (i=0; i<NumBd; i++)
+ * {
+ * // Prepare CurBd.....
+ *
+ * // Onto next BD
+ * CurBd = XEmacPss_BdRingNext(MyRingPtr, CurBd);
+ * }
+ *
+ * // Give list to hardware
+ * Status = XEmacPss_BdRingToHw(MyRingPtr, NumBd, MyBdSet);
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be allocated and given to hardware in the correct sequence:
+ * <pre>
+ * // Legal
+ * XEmacPss_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ *
+ * // Legal
+ * XEmacPss_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
+ * XEmacPss_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ * XEmacPss_BdRingToHw(MyRingPtr, NumBd2, MySet2);
+ *
+ * // Not legal
+ * XEmacPss_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
+ * XEmacPss_BdRingToHw(MyRingPtr, NumBd2, MySet2);
+ * XEmacPss_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * Use the API defined in xemacpss_bd.h to modify individual BDs. Traversal
+ * of the BD set can be done using XEmacPss_BdRingNext() and
+ * XEmacPss_BdRingPrev().
+ *
+ * @param RingPtr is a pointer to the BD ring instance to be worked on.
+ * @param NumBd is the number of BDs to allocate
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ * for modification.
+ *
+ * @return
+ * - XST_SUCCESS if the requested number of BDs was returned in the BdSetPtr
+ * parameter.
+ * - XST_FAILURE if there were not enough free BDs to satisfy the request.
+ *
+ * @note This function should not be preempted by another XEmacPss_Bd function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ * @note Do not modify more BDs than the number requested with the NumBd
+ * parameter. Doing so will lead to data corruption and system
+ * instability.
+ *
+ *****************************************************************************/
+int XEmacPss_BdRingAlloc(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd ** BdSetPtr)
+{
+ /* Enough free BDs available for the request? */
+ if (RingPtr->FreeCnt < NumBd) {
+ return (XST_FAILURE);
+ }
+
+ /* Set the return argument and move FreeHead forward */
+ *BdSetPtr = RingPtr->FreeHead;
+ XEMACPSS_RING_SEEKAHEAD(RingPtr, RingPtr->FreeHead, NumBd);
+ RingPtr->FreeCnt -= NumBd;
+ RingPtr->PreCnt += NumBd;
+ return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * Fully or partially undo an XEmacPss_BdRingAlloc() operation. Use this
+ * function if all the BDs allocated by XEmacPss_BdRingAlloc() could not be
+ * transferred to hardware with XEmacPss_BdRingToHw().
+ *
+ * This function helps out in situations when an unrelated error occurs after
+ * BDs have been allocated but before they have been given to hardware.
+ * An example of this type of error would be an OS running out of resources.
+ *
+ * This function is not the same as XEmacPss_BdRingFree(). The Free function
+ * returns BDs to the free list after they have been processed by hardware,
+ * while UnAlloc returns them before being processed by hardware.
+ *
+ * There are two scenarios where this function can be used. Full UnAlloc or
+ * Partial UnAlloc. A Full UnAlloc means all the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ * Status = XEmacPss_BdRingAlloc(MyRingPtr, 10, &BdPtr);
+ * .
+ * .
+ * if (Error)
+ * {
+ * Status = XEmacPss_BdRingUnAlloc(MyRingPtr, 10, &BdPtr);
+ * }
+ * </pre>
+ *
+ * A partial UnAlloc means some of the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ * Status = XEmacPss_BdRingAlloc(MyRingPtr, 10, &BdPtr);
+ * BdsLeft = 10;
+ * CurBdPtr = BdPtr;
+ *
+ * while (BdsLeft)
+ * {
+ * if (Error)
+ * {
+ * Status = XEmacPss_BdRingUnAlloc(MyRingPtr, BdsLeft, CurBdPtr);
+ * }
+ *
+ * CurBdPtr = XEmacPss_BdRingNext(MyRingPtr, CurBdPtr);
+ * BdsLeft--;
+ * }
+ * </pre>
+ *
+ * A partial UnAlloc must include the last BD in the list that was Alloc'd.
+ *
+ * @param RingPtr is a pointer to the instance to be worked on.
+ * @param NumBd is the number of BDs to allocate
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ * for modification.
+ *
+ * @return
+ * - XST_SUCCESS if the BDs were unallocated.
+ * - XST_FAILURE if NumBd parameter was greater that the number of BDs in
+ * the preprocessing state.
+ *
+ * @note This function should not be preempted by another XEmacPss_Bd function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XEmacPss_BdRingUnAlloc(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd * BdSetPtr)
+{
+ /* Enough BDs in the free state for the request? */
+ if (RingPtr->PreCnt < NumBd) {
+ return (XST_FAILURE);
+ }
+
+ /* Set the return argument and move FreeHead backward */
+ XEMACPSS_RING_SEEKBACK(RingPtr, RingPtr->FreeHead, NumBd);
+ RingPtr->FreeCnt += NumBd;
+ RingPtr->PreCnt -= NumBd;
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Enqueue a set of BDs to hardware that were previously allocated by
+ * XEmacPss_BdRingAlloc(). Once this function returns, the argument BD set goes
+ * under hardware control. Any changes made to these BDs after this point will
+ * corrupt the BD list leading to data corruption and system instability.
+ *
+ * The set will be rejected if the last BD of the set does not mark the end of
+ * a packet (see XEmacPss_BdSetLast()).
+ *
+ * @param RingPtr is a pointer to the instance to be worked on.
+ * @param NumBd is the number of BDs in the set.
+ * @param BdSetPtr is the first BD of the set to commit to hardware.
+ *
+ * @return
+ * - XST_SUCCESS if the set of BDs was accepted and enqueued to hardware.
+ * - XST_FAILURE if the set of BDs was rejected because the last BD of the set
+ * did not have its "last" bit set.
+ * - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ * XEmacPss_BdRingAlloc().
+ *
+ * @note This function should not be preempted by another XEmacPss_Bd function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XEmacPss_BdRingToHw(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd * BdSetPtr)
+{
+ XEmacPss_Bd *CurBdPtr;
+ unsigned i;
+
+ /* if no bds to process, simply return. */
+ if (0 == NumBd)
+ return (XST_SUCCESS);
+
+ /* Make sure we are in sync with XEmacPss_BdRingAlloc() */
+ if ((RingPtr->PreCnt < NumBd) || (RingPtr->PreHead != BdSetPtr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ CurBdPtr = BdSetPtr;
+ for (i = 0; i < NumBd; i++) {
+ XEMACPSS_CACHE_FLUSH(CurBdPtr);
+ CurBdPtr = XEmacPss_BdRingNext(RingPtr, CurBdPtr);
+ }
+
+ /* Adjust ring pointers & counters */
+ XEMACPSS_RING_SEEKAHEAD(RingPtr, RingPtr->PreHead, NumBd);
+ RingPtr->PreCnt -= NumBd;
+
+ RingPtr->HwTail = CurBdPtr;
+ RingPtr->HwCnt += NumBd;
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Returns a set of BD(s) that have been processed by hardware. The returned
+ * BDs may be examined to determine the outcome of the DMA transaction(s).
+ * Once the BDs have been examined, the user must call XEmacPss_BdRingFree()
+ * in the same order which they were retrieved here. Example:
+ *
+ * <pre>
+ * NumBd = XEmacPss_BdRingFromHwTx(MyRingPtr, MaxBd, &MyBdSet);
+ *
+ * if (NumBd == 0)
+ * {
+ * // hardware has nothing ready for us yet
+ * }
+ *
+ * CurBd = MyBdSet;
+ * for (i=0; i<NumBd; i++)
+ * {
+ * // Examine CurBd for post processing.....
+ *
+ * // Onto next BD
+ * CurBd = XEmacPss_BdRingNext(MyRingPtr, CurBd);
+ * }
+ *
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd, MyBdSet); // Return list
+ * }
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be retrieved from hardware and freed in the correct sequence:
+ * <pre>
+ * // Legal
+ * XEmacPss_BdRingFromHwTx(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ *
+ * // Legal
+ * XEmacPss_BdRingFromHwTx(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingFromHwTx(MyRingPtr, NumBd2, &MySet2);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ *
+ * // Not legal
+ * XEmacPss_BdRingFromHwTx(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingFromHwTx(MyRingPtr, NumBd2, &MySet2);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * If hardware has only partially completed a packet spanning multiple BDs,
+ * then none of the BDs for that packet will be included in the results.
+ *
+ * @param RingPtr is a pointer to the instance to be worked on.
+ * @param BdLimit is the maximum number of BDs to return in the set.
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ * for examination.
+ *
+ * @return
+ * The number of BDs processed by hardware. A value of 0 indicates that no
+ * data is available. No more than BdLimit BDs will be returned.
+ *
+ * @note Treat BDs returned by this function as read-only.
+ *
+ * @note This function should not be preempted by another XEmacPss_Bd function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+unsigned XEmacPss_BdRingFromHwTx(XEmacPss_BdRing * RingPtr, unsigned BdLimit,
+ XEmacPss_Bd ** BdSetPtr)
+{
+ XEmacPss_Bd *CurBdPtr;
+ u32 BdStr = 0;
+ unsigned BdCount;
+ unsigned BdPartialCount;
+
+ CurBdPtr = RingPtr->HwHead;
+ BdCount = 0;
+ BdPartialCount = 0;
+
+ /* If no BDs in work group, then there's nothing to search */
+ if (RingPtr->HwCnt == 0) {
+ *BdSetPtr = NULL;
+ return (0);
+ }
+
+ /* Starting at HwHead, keep moving forward in the list until:
+ * - A BD is encountered with its new/used bit set which means
+ * hardware has not completed processing of that BD.
+ * - RingPtr->HwTail is reached and RingPtr->HwCnt is reached.
+ * - The number of requested BDs has been processed
+ */
+ while (BdCount < BdLimit) {
+ /* Read the status */
+ XEMACPSS_CACHE_INVALIDATE(CurBdPtr);
+ BdStr = XEmacPss_BdRead(CurBdPtr, XEMACPSS_BD_STAT_OFFSET);
+
+ BdCount++;
+
+ /* hardware has processed this BD so check the "last" bit. If
+ * it is clear, then there are more BDs for the current packet.
+ * Keep a count of these partial packet BDs.
+ */
+ if (BdStr & XEMACPSS_TXBUF_LAST_MASK) {
+ BdPartialCount = 0;
+ }
+ else {
+ BdPartialCount++;
+ }
+
+ /* Reached the end of the work group */
+ if (CurBdPtr == RingPtr->HwTail) {
+ break;
+ }
+
+ /* Move on to next BD in work group */
+ CurBdPtr = XEmacPss_BdRingNext(RingPtr, CurBdPtr);
+ }
+
+ /* Subtract off any partial packet BDs found */
+ BdCount -= BdPartialCount;
+
+ /* If BdCount is non-zero then BDs were found to return. Set return
+ * parameters, update pointers and counters, return success
+ */
+ if (BdCount > 0) {
+ *BdSetPtr = RingPtr->HwHead;
+ RingPtr->HwCnt -= BdCount;
+ RingPtr->PostCnt += BdCount;
+ XEMACPSS_RING_SEEKAHEAD(RingPtr, RingPtr->HwHead, BdCount);
+ return (BdCount);
+ }
+ else {
+ *BdSetPtr = NULL;
+ return (0);
+ }
+}
+
+
+/*****************************************************************************/
+/**
+ * Returns a set of BD(s) that have been processed by hardware. The returned
+ * BDs may be examined to determine the outcome of the DMA transaction(s).
+ * Once the BDs have been examined, the user must call XEmacPss_BdRingFree()
+ * in the same order which they were retrieved here. Example:
+ *
+ * <pre>
+ * NumBd = XEmacPss_BdRingFromHwRx(MyRingPtr, MaxBd, &MyBdSet);
+ *
+ * if (NumBd == 0)
+ * {
+ * // hardware has nothing ready for us yet
+ * }
+ *
+ * CurBd = MyBdSet;
+ * for (i=0; i<NumBd; i++)
+ * {
+ * // Examine CurBd for post processing.....
+ *
+ * // Onto next BD
+ * CurBd = XEmacPss_BdRingNext(MyRingPtr, CurBd);
+ * }
+ *
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd, MyBdSet); // Return list
+ * }
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be retrieved from hardware and freed in the correct sequence:
+ * <pre>
+ * // Legal
+ * XEmacPss_BdRingFromHwRx(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ *
+ * // Legal
+ * XEmacPss_BdRingFromHwRx(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingFromHwRx(MyRingPtr, NumBd2, &MySet2);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ *
+ * // Not legal
+ * XEmacPss_BdRingFromHwRx(MyRingPtr, NumBd1, &MySet1);
+ * XEmacPss_BdRingFromHwRx(MyRingPtr, NumBd2, &MySet2);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ * XEmacPss_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * If hardware has only partially completed a packet spanning multiple BDs,
+ * then none of the BDs for that packet will be included in the results.
+ *
+ * @param RingPtr is a pointer to the instance to be worked on.
+ * @param BdLimit is the maximum number of BDs to return in the set.
+ * @param BdSetPtr is an output parameter, it points to the first BD available
+ * for examination.
+ *
+ * @return
+ * The number of BDs processed by hardware. A value of 0 indicates that no
+ * data is available. No more than BdLimit BDs will be returned.
+ *
+ * @note Treat BDs returned by this function as read-only.
+ *
+ * @note This function should not be preempted by another XEmacPss_Bd function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+unsigned XEmacPss_BdRingFromHwRx(XEmacPss_BdRing * RingPtr, unsigned BdLimit,
+ XEmacPss_Bd ** BdSetPtr)
+{
+ XEmacPss_Bd *CurBdPtr;
+ u32 BdStr = 0;
+ unsigned BdCount;
+ unsigned BdPartialCount;
+
+ CurBdPtr = RingPtr->HwHead;
+ BdCount = 0;
+ BdPartialCount = 0;
+
+ /* If no BDs in work group, then there's nothing to search */
+ if (RingPtr->HwCnt == 0) {
+ *BdSetPtr = NULL;
+ return (0);
+ }
+
+ /* Starting at HwHead, keep moving forward in the list until:
+ * - A BD is encountered with its new/used bit set which means
+ * hardware has completed processing of that BD.
+ * - RingPtr->HwTail is reached and RingPtr->HwCnt is reached.
+ * - The number of requested BDs has been processed
+ */
+ while (BdCount < BdLimit) {
+ /* Read the status */
+ XEMACPSS_CACHE_INVALIDATE(CurBdPtr);
+ BdStr = XEmacPss_BdRead(CurBdPtr, XEMACPSS_BD_STAT_OFFSET);
+
+ if (!(XEmacPss_BdIsRxNew(CurBdPtr))) {
+ break;
+ }
+
+ BdCount++;
+
+ /* hardware has processed this BD so check the "last" bit. If
+ * it is clear, then there are more BDs for the current packet.
+ * Keep a count of these partial packet BDs.
+ */
+ if (BdStr & XEMACPSS_RXBUF_EOF_MASK) {
+ BdPartialCount = 0;
+ }
+ else {
+ BdPartialCount++;
+ }
+
+ /* Reached the end of the work group */
+ if (CurBdPtr == RingPtr->HwTail) {
+ break;
+ }
+
+ /* Move on to next BD in work group */
+ CurBdPtr = XEmacPss_BdRingNext(RingPtr, CurBdPtr);
+ }
+
+ /* Subtract off any partial packet BDs found */
+ BdCount -= BdPartialCount;
+
+ /* If BdCount is non-zero then BDs were found to return. Set return
+ * parameters, update pointers and counters, return success
+ */
+ if (BdCount > 0) {
+ *BdSetPtr = RingPtr->HwHead;
+ RingPtr->HwCnt -= BdCount;
+ RingPtr->PostCnt += BdCount;
+ XEMACPSS_RING_SEEKAHEAD(RingPtr, RingPtr->HwHead, BdCount);
+ return (BdCount);
+ }
+ else {
+ *BdSetPtr = NULL;
+ return (0);
+ }
+}
+
+
+/*****************************************************************************/
+/**
+ * Frees a set of BDs that had been previously retrieved with
+ * XEmacPss_BdRingFromHw().
+ *
+ * @param RingPtr is a pointer to the instance to be worked on.
+ * @param NumBd is the number of BDs to free.
+ * @param BdSetPtr is the head of a list of BDs returned by
+ * XEmacPss_BdRingFromHw().
+ *
+ * @return
+ * - XST_SUCCESS if the set of BDs was freed.
+ * - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ * XEmacPss_BdRingFromHw().
+ *
+ * @note This function should not be preempted by another XEmacPss_Bd function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XEmacPss_BdRingFree(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd * BdSetPtr)
+{
+ /* if no bds to process, simply return. */
+ if (0 == NumBd)
+ return (XST_SUCCESS);
+
+ /* Make sure we are in sync with XEmacPss_BdRingFromHw() */
+ if ((RingPtr->PostCnt < NumBd) || (RingPtr->PostHead != BdSetPtr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Update pointers and counters */
+ RingPtr->FreeCnt += NumBd;
+ RingPtr->PostCnt -= NumBd;
+ XEMACPSS_RING_SEEKAHEAD(RingPtr, RingPtr->PostHead, NumBd);
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Check the internal data structures of the BD ring for the provided channel.
+ * The following checks are made:
+ *
+ * - Is the BD ring linked correctly in physical address space.
+ * - Do the internal pointers point to BDs in the ring.
+ * - Do the internal counters add up.
+ *
+ * The channel should be stopped prior to calling this function.
+ *
+ * @param RingPtr is a pointer to the instance to be worked on.
+ *
+ * @return
+ * - XST_SUCCESS if the set of BDs was freed.
+ * - XST_DMA_SG_NO_LIST if the list has not been created.
+ * - XST_IS_STARTED if the channel is not stopped.
+ * - XST_DMA_SG_LIST_ERROR if a problem is found with the internal data
+ * structures. If this value is returned, the channel should be reset to
+ * avoid data corruption or system instability.
+ *
+ * @note This function should not be preempted by another XEmacPss_Bd function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XEmacPss_BdRingCheck(XEmacPss_BdRing * RingPtr, u8 Direction)
+{
+ u32 AddrV, AddrP;
+ unsigned i;
+
+ if ((Direction != XEMACPSS_SEND) && (Direction != XEMACPSS_RECV)) {
+ return (XST_INVALID_PARAM);
+ }
+
+ /* Is the list created */
+ if (RingPtr->AllCnt == 0) {
+ return (XST_DMA_SG_NO_LIST);
+ }
+
+ /* Can't check if channel is running */
+ if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+ return (XST_IS_STARTED);
+ }
+
+ /* RunState doesn't make sense */
+ else if (RingPtr->RunState != XST_DMA_SG_IS_STOPPED) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Verify internal pointers point to correct memory space */
+ AddrV = (u32) RingPtr->FreeHead;
+ if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->PreHead;
+ if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->HwHead;
+ if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->HwTail;
+ if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->PostHead;
+ if ((AddrV < RingPtr->BaseBdAddr) || (AddrV > RingPtr->HighBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Verify internal counters add up */
+ if ((RingPtr->HwCnt + RingPtr->PreCnt + RingPtr->FreeCnt +
+ RingPtr->PostCnt) != RingPtr->AllCnt) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Verify BDs are linked correctly */
+ AddrV = RingPtr->BaseBdAddr;
+ AddrP = RingPtr->PhysBaseAddr + RingPtr->Separation;
+
+ for (i = 1; i < RingPtr->AllCnt; i++) {
+ /* Check BDA for this BD. It should point to next physical addr */
+ if (XEmacPss_BdRead(AddrV, XEMACPSS_BD_ADDR_OFFSET) != AddrP) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Move on to next BD */
+ AddrV += RingPtr->Separation;
+ AddrP += RingPtr->Separation;
+ }
+
+ /* Last BD should have wrap bit set */
+ if (XEMACPSS_SEND == Direction) {
+ if (!XEmacPss_BdIsTxWrap(AddrV)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+ }
+ else { /* XEMACPSS_RECV */
+ if (!XEmacPss_BdIsRxWrap(AddrV)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+ }
+
+ /* No problems found */
+ return (XST_SUCCESS);
+}
--- /dev/null
+/* $Id: xemacpss_bdring.h,v 1.1.2.1 2009/06/17 16:10:26 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemacpss_bdring.h
+*
+* The Xiline EmacPss Buffer Descriptor ring driver. This is part of EmacPss
+* DMA functionalities.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a wsy 06/01/09 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMACPSS_BDRING_H /* prevent curcular inclusions */
+#define XEMACPSS_BDRING_H /* by using protection macros */
+
+
+/**************************** Type Definitions *******************************/
+
+/** This is an internal structure used to maintain the DMA list */
+typedef struct {
+ u32 PhysBaseAddr;/**< Physical address of 1st BD in list */
+ u32 BaseBdAddr; /**< Virtual address of 1st BD in list */
+ u32 HighBdAddr; /**< Virtual address of last BD in the list */
+ u32 Length; /**< Total size of ring in bytes */
+ u32 RunState; /**< Flag to indicate DMA is started */
+ u32 Separation; /**< Number of bytes between the starting address
+ of adjacent BDs */
+ XEmacPss_Bd *RxBD_start; /**< First BD in the Rx queue*/
+ int RxBD_current; /**< Index to the current BD*/
+ int RxBD_end; /**< Index to the last BD*/
+ int Rx_first_buf; /**< Index to the first BD*/
+ XEmacPss_Bd *FreeHead;
+ /**< First BD in the free group */
+ XEmacPss_Bd *PreHead;/**< First BD in the pre-work group */
+ XEmacPss_Bd *HwHead; /**< First BD in the work group */
+ XEmacPss_Bd *HwTail; /**< Last BD in the work group */
+ XEmacPss_Bd *PostHead;
+ /**< First BD in the post-work group */
+ XEmacPss_Bd *BdaRestart;
+ /**< BDA to load when channel is started */
+ unsigned HwCnt; /**< Number of BDs in work group */
+ unsigned PreCnt; /**< Number of BDs in pre-work group */
+ unsigned FreeCnt; /**< Number of allocatable BDs in the free group */
+ unsigned PostCnt; /**< Number of BDs in post-work group */
+ unsigned AllCnt; /**< Total Number of BDs for channel */
+} XEmacPss_BdRing;
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many BDs will fit
+* in a BD list within the given memory constraints.
+*
+* The results of this macro can be provided to XEmacPss_BdRingCreate().
+*
+* @param Alignment specifies what byte alignment the BDs must fall on and
+* must be a power of 2 to get an accurate calculation (32, 64, 128,...)
+* @param Bytes is the number of bytes to be used to store BDs.
+*
+* @return Number of BDs that can fit in the given memory area
+*
+* @note
+* C-style signature:
+* u32 XEmacPss_BdRingCntCalc(u32 Alignment, u32 Bytes)
+*
+******************************************************************************/
+#define XEmacPss_BdRingCntCalc(Alignment, Bytes) \
+ (u32)((Bytes) / ((sizeof(XEmacPss_Bd) + ((Alignment)-1)) & \
+ ~((Alignment)-1)))
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many bytes of memory
+* is required to contain a given number of BDs at a given alignment.
+*
+* @param Alignment specifies what byte alignment the BDs must fall on. This
+* parameter must be a power of 2 to get an accurate calculation (32, 64,
+* 128,...)
+* @param NumBd is the number of BDs to calculate memory size requirements for
+*
+* @return The number of bytes of memory required to create a BD list with the
+* given memory constraints.
+*
+* @note
+* C-style signature:
+* u32 XEmacPss_BdRingMemCalc(u32 Alignment, u32 NumBd)
+*
+******************************************************************************/
+#define XEmacPss_BdRingMemCalc(Alignment, NumBd) \
+ (u32)((sizeof(XEmacPss_Bd) + ((Alignment)-1)) & \
+ ~((Alignment)-1)) * (NumBd)
+
+/****************************************************************************/
+/**
+* Return the total number of BDs allocated by this channel with
+* XEmacPss_BdRingCreate().
+*
+* @param InstancePtr is the DMA channel to operate on.
+*
+* @return The total number of BDs allocated for this channel.
+*
+* @note
+* C-style signature:
+* u32 XEmacPss_BdRingGetCnt(XEmacPss_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XEmacPss_BdRingGetCnt(RingPtr) ((RingPtr)->AllCnt)
+
+/****************************************************************************/
+/**
+* Return the number of BDs allocatable with XEmacPss_BdRingAlloc() for pre-
+* processing.
+*
+* @param InstancePtr is the DMA channel to operate on.
+*
+* @return The number of BDs currently allocatable.
+*
+* @note
+* C-style signature:
+* u32 XEmacPss_BdRingGetFreeCnt(XEmacPss_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XEmacPss_BdRingGetFreeCnt(RingPtr) ((RingPtr)->FreeCnt)
+
+/****************************************************************************/
+/**
+* Return the next BD from BdPtr in a list.
+*
+* @param InstancePtr is the DMA channel to operate on.
+* @param BdPtr is the BD to operate on.
+*
+* @return The next BD in the list relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+* XEmacPss_Bd *XEmacPss_BdRingNext(XEmacPss_BdRing* RingPtr,
+* XEmacPss_Bd *BdPtr)
+*
+*****************************************************************************/
+#define XEmacPss_BdRingNext(RingPtr, BdPtr) \
+ (((u32)(BdPtr) >= (RingPtr)->HighBdAddr) ? \
+ (XEmacPss_Bd*)(RingPtr)->BaseBdAddr : \
+ (XEmacPss_Bd*)((u32)(BdPtr) + (RingPtr)->Separation))
+
+/****************************************************************************/
+/**
+* Return the previous BD from BdPtr in the list.
+*
+* @param InstancePtr is the DMA channel to operate on.
+* @param BdPtr is the BD to operate on
+*
+* @return The previous BD in the list relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+* XEmacPss_Bd *XEmacPss_BdRingPrev(XEmacPss_BdRing* RingPtr,
+* XEmacPss_Bd *BdPtr)
+*
+*****************************************************************************/
+#define XEmacPss_BdRingPrev(RingPtr, BdPtr) \
+ (((u32)(BdPtr) <= (RingPtr)->BaseBdAddr) ? \
+ (XEmacPss_Bd*)(RingPtr)->HighBdAddr : \
+ (XEmacPss_Bd*)((u32)(BdPtr) - (RingPtr)->Separation))
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Scatter gather DMA related functions in xemacpss_bdring.c
+ */
+int XEmacPss_BdRingCreate(XEmacPss_BdRing * RingPtr, u32 PhysAddr,
+ u32 VirtAddr, u32 Alignment, unsigned BdCount);
+int XEmacPss_BdRingClone(XEmacPss_BdRing * RingPtr, XEmacPss_Bd * SrcBdPtr,
+ u8 Direction);
+int XEmacPss_BdRingAlloc(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd ** BdSetPtr);
+int XEmacPss_BdRingUnAlloc(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd * BdSetPtr);
+int XEmacPss_BdRingToHw(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd * BdSetPtr);
+int XEmacPss_BdRingFree(XEmacPss_BdRing * RingPtr, unsigned NumBd,
+ XEmacPss_Bd * BdSetPtr);
+unsigned XEmacPss_BdRingFromHwTx(XEmacPss_BdRing * RingPtr, unsigned BdLimit,
+ XEmacPss_Bd ** BdSetPtr);
+unsigned XEmacPss_BdRingFromHwRx(XEmacPss_BdRing * RingPtr, unsigned BdLimit,
+ XEmacPss_Bd ** BdSetPtr);
+int XEmacPss_BdRingCheck(XEmacPss_BdRing * RingPtr, u8 Direction);
+
+
+#endif /* end of protection macros */
--- /dev/null
+/* $Id: xemacpss_control.c,v 1.1.2.2 2009/07/07 22:54:36 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xemacpss_control.c
+ *
+ * Functions in this file implement general purpose command and control related
+ * functionality. See xemacpss.h for a detailed description of the driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- ---- -------- -------------------------------------------------------
+ * 1.00a wsy 06/01/09 First release
+ * </pre>
+ *****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xemacpss.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+ * Set the MAC address for this driver/device. The address is a 48-bit value.
+ * The device must be stopped before calling this function.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param AddressPtr is a pointer to a 6-byte MAC address.
+ * @param Index is a index to which MAC (1-4) address.
+ *
+ * @return
+ * - XST_SUCCESS if the MAC address was set successfully
+ * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+ *
+ *****************************************************************************/
+int XEmacPss_SetMacAddress(XEmacPss *InstancePtr, void *AddressPtr, u8 Index)
+{
+ u32 MacAddr;
+ u8 *Aptr = (u8 *) AddressPtr;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(AddressPtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID((Index <= XEMACPSS_MAX_MAC_ADDR) && (Index > 0));
+
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
+ Index--;
+
+ /* Set the MAC bits [31:0] in BOT */
+ MacAddr = Aptr[0];
+ MacAddr |= Aptr[1] << 8;
+ MacAddr |= Aptr[2] << 16;
+ MacAddr |= Aptr[3] << 24;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ (XEMACPSS_LADDR1L_OFFSET + Index * 8), MacAddr);
+
+ /* There are reserved bits in TOP so don't affect them */
+ MacAddr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ (XEMACPSS_LADDR1H_OFFSET + (Index * 8)));
+
+ MacAddr &= ~XEMACPSS_LADDR_MACH_MASK;
+
+ /* Set MAC bits [47:32] in TOP */
+ MacAddr |= Aptr[4];
+ MacAddr |= Aptr[5] << 8;
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ (XEMACPSS_LADDR1H_OFFSET + (Index * 8)), MacAddr);
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Get the MAC address for this driver/device.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param AddressPtr is an output parameter, and is a pointer to a buffer into
+ * which the current MAC address will be copied.
+ * @param Index is a index to which MAC (1-4) address.
+ *
+ *****************************************************************************/
+void XEmacPss_GetMacAddress(XEmacPss *InstancePtr, void *AddressPtr, u8 Index)
+{
+ u32 MacAddr;
+ u8 *Aptr = (u8 *) AddressPtr;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(AddressPtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_VOID((Index <= XEMACPSS_MAX_MAC_ADDR) && (Index > 0));
+
+ /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
+ Index--;
+
+ MacAddr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ (XEMACPSS_LADDR1L_OFFSET + (Index * 8)));
+ Aptr[0] = (u8) MacAddr;
+ Aptr[1] = (u8) (MacAddr >> 8);
+ Aptr[2] = (u8) (MacAddr >> 16);
+ Aptr[3] = (u8) (MacAddr >> 24);
+
+ /* Read MAC bits [47:32] in TOP */
+ MacAddr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ (XEMACPSS_LADDR1H_OFFSET + (Index * 8)));
+ Aptr[4] = (u8) MacAddr;
+ Aptr[5] = (u8) (MacAddr >> 8);
+}
+
+
+/*****************************************************************************/
+/**
+ * Set 48-bit MAC addresses in hash table.
+ * The device must be stopped before calling this function.
+ *
+ * The hash address register is 64 bits long and takes up two locations in
+ * the memory map. The least significant bits are stored in hash register
+ * bottom and the most significant bits in hash register top.
+ *
+ * The unicast hash enable and the multicast hash enable bits in the network
+ * configuration register enable the reception of hash matched frames. The
+ * destination address is reduced to a 6 bit index into the 64 bit hash
+ * register using the following hash function. The hash function is an XOR
+ * of every sixth bit of the destination address.
+ *
+ * <pre>
+ * hash_index[05] = da[05]^da[11]^da[17]^da[23]^da[29]^da[35]^da[41]^da[47]
+ * hash_index[04] = da[04]^da[10]^da[16]^da[22]^da[28]^da[34]^da[40]^da[46]
+ * hash_index[03] = da[03]^da[09]^da[15]^da[21]^da[27]^da[33]^da[39]^da[45]
+ * hash_index[02] = da[02]^da[08]^da[14]^da[20]^da[26]^da[32]^da[38]^da[44]
+ * hash_index[01] = da[01]^da[07]^da[13]^da[19]^da[25]^da[31]^da[37]^da[43]
+ * hash_index[00] = da[00]^da[06]^da[12]^da[18]^da[24]^da[30]^da[36]^da[42]
+ * </pre>
+ *
+ * da[0] represents the least significant bit of the first byte received,
+ * that is, the multicast/unicast indicator, and da[47] represents the most
+ * significant bit of the last byte received.
+ *
+ * If the hash index points to a bit that is set in the hash register then
+ * the frame will be matched according to whether the frame is multicast
+ * or unicast.
+ *
+ * A multicast match will be signaled if the multicast hash enable bit is
+ * set, da[0] is logic 1 and the hash index points to a bit set in the hash
+ * register.
+ *
+ * A unicast match will be signaled if the unicast hash enable bit is set,
+ * da[0] is logic 0 and the hash index points to a bit set in the hash
+ * register.
+ *
+ * To receive all multicast frames, the hash register should be set with
+ * all ones and the multicast hash enable bit should be set in the network
+ * configuration register.
+ *
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param AddressPtr is a pointer to a 6-byte MAC address.
+ *
+ * @return
+ * - XST_SUCCESS if the HASH MAC address was set successfully
+ * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+ * - XST_INVALID_PARAM if the HASH MAC address passed in does not meet
+ * requirement after calculation
+ *
+ * @note
+ * Having Aptr be unsigned type prevents the following operations from sign
+ * extending.
+ *****************************************************************************/
+int XEmacPss_SetHash(XEmacPss *InstancePtr, void *AddressPtr)
+{
+ u32 HashAddr;
+ u8 *Aptr = (u8 *) AddressPtr;
+ u8 Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8;
+ int Result;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(AddressPtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+ Temp1 = Aptr[0] & 0x3F;
+ Temp2 = ((Aptr[0] >> 6) & 0x3) | ((Aptr[1] & 0xF) << 2);
+ Temp3 = ((Aptr[1] >> 4) & 0xF) | ((Aptr[2] & 0x3) << 4);
+ Temp4 = ((Aptr[2] >> 2) & 0x3F);
+ Temp5 = Aptr[3] & 0x3F;
+ Temp6 = ((Aptr[3] >> 6) & 0x3) | ((Aptr[4] & 0xF) << 2);
+ Temp7 = ((Aptr[4] >> 4) & 0xF) | ((Aptr[5] & 0x3) << 4);
+ Temp8 = ((Aptr[5] >> 2) & 0x3F);
+
+ Result = Temp1 ^ Temp2 ^ Temp3 ^ Temp4 ^ Temp5 ^ Temp6 ^ Temp7 ^ Temp8;
+
+ if (Result >= XEMACPSS_MAX_HASH_BITS) {
+ return (XST_INVALID_PARAM);
+ }
+
+ if (Result < 32) {
+ HashAddr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHL_OFFSET);
+ HashAddr |= (1 << Result);
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHL_OFFSET, HashAddr);
+ } else {
+ HashAddr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHH_OFFSET);
+ HashAddr |= (1 << (Result - 32));
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHH_OFFSET, HashAddr);
+ }
+
+ return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * Clear the Hash registers for the mac address pointed by AddressPtr.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ *****************************************************************************/
+void XEmacPss_ClearHash(XEmacPss *InstancePtr)
+{
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHL_OFFSET, 0x0);
+
+ /* write bits [63:32] in TOP */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHH_OFFSET, 0x0);
+}
+
+
+/*****************************************************************************/
+/**
+ * Get the Hash address for this driver/device.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param AddressPtr is an output parameter, and is a pointer to a buffer into
+ * which the current HASH MAC address will be copied.
+ *
+ *****************************************************************************/
+void XEmacPss_GetHash(XEmacPss *InstancePtr, void *AddressPtr)
+{
+ u32 *Aptr = (u32 *) AddressPtr;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(AddressPtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ Aptr[0] = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHL_OFFSET);
+
+ /* Read Hash bits [63:32] in TOP */
+ Aptr[1] = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_HASHH_OFFSET);
+}
+
+
+/*****************************************************************************/
+/**
+ * Set the Type ID match for this driver/device. The register is a 32-bit
+ * value. The device must be stopped before calling this function.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param Id_Check.
+ * @param Index is a index to which Type ID (1-4).
+ *
+ * @return
+ * - XST_SUCCESS if the MAC address was set successfully
+ * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+ *
+ *****************************************************************************/
+int XEmacPss_SetTypeIdCheck(XEmacPss *InstancePtr, u32 Id_Check, u8 Index)
+{
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID((Index <= XEMACPSS_MAX_TYPE_ID) && (Index > 0));
+
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
+ Index--;
+
+ /* Set the ID bits in MATCHx register */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ (XEMACPSS_MATCH1_OFFSET + (Index * 4)), Id_Check);
+
+ return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * Set options for the driver/device. The driver should be stopped with
+ * XEmacPss_Stop() before changing options.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param Options are the options to set. Multiple options can be set by OR'ing
+ * XTE_*_OPTIONS constants together. Options not specified are not
+ * affected.
+ *
+ * @return
+ * - XST_SUCCESS if the options were set successfully
+ * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+ *
+ * @note
+ * See xemacpss.h for a description of the available options.
+ *
+ *****************************************************************************/
+int XEmacPss_SetOptions(XEmacPss *InstancePtr, u32 Options)
+{
+ u32 Reg; /* Generic register contents */
+ u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
+ u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Many of these options will change the NET_CONFIG registers.
+ * To reduce the amount of IO to the device, group these options here
+ * and change them all at once.
+ */
+
+ /* Grab current register contents */
+ RegNetCfg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET);
+ RegNewNetCfg = RegNetCfg;
+
+ /*
+ * It is configured to max 1536.
+ */
+ if (Options & XEMACPSS_FRAME1536_OPTION) {
+ RegNewNetCfg |= (XEMACPSS_NWCFG_1536RXEN_MASK);
+ }
+
+ /* Turn on VLAN packet only, only VLAN tagged will be accepted */
+ if (Options & XEMACPSS_VLAN_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_NVLANDISC_MASK;
+ }
+
+ /* Turn on FCS stripping on receive packets */
+ if (Options & XEMACPSS_FCS_STRIP_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_FCSREM_MASK;
+ }
+
+ /* Turn on length/type field checking on receive packets */
+ if (Options & XEMACPSS_LENTYPE_ERR_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_LENGTHERRDSCRD_MASK;
+ }
+
+ /* Turn on flow control */
+ if (Options & XEMACPSS_FLOW_CONTROL_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_PAUSEEN_MASK;
+ }
+
+ /* Turn on promiscuous frame filtering (all frames are received) */
+ if (Options & XEMACPSS_PROMISC_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_COPYALLEN_MASK;
+ }
+
+ /* Allow broadcast address reception */
+ if (Options & XEMACPSS_BROADCAST_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_BCASTDI_MASK;
+ }
+
+ /* Allow multicast address filtering */
+ if (Options & XEMACPSS_MULTICAST_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_MCASTHASHEN_MASK;
+ }
+
+ /* enable RX checksum offload */
+ if (Options & XEMACPSS_RX_CHKSUM_ENABLE_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_RXCHKSUMEN_MASK;
+ }
+
+ /* Officially change the NET_CONFIG registers if it needs to be
+ * modified.
+ */
+ if (RegNetCfg != RegNewNetCfg) {
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET, RegNewNetCfg);
+ }
+
+ /* Enable TX checksum offload */
+ if (Options & XEMACPSS_TX_CHKSUM_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_DMACR_OFFSET);
+ Reg |= XEMACPSS_DMACR_TCPCKSUM_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_DMACR_OFFSET, Reg);
+ }
+
+ /* Enable transmitter */
+ if (Options & XEMACPSS_TRANSMITTER_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ Reg |= XEMACPSS_NWCTRL_TXEN_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET, Reg);
+ }
+
+ /* Enable receiver */
+ if (Options & XEMACPSS_RECEIVER_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ Reg |= XEMACPSS_NWCTRL_RXEN_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET, Reg);
+ }
+
+ /* The remaining options not handled here are managed elsewhere in the
+ * driver. No register modifications are needed at this time. Reflecting
+ * the option in InstancePtr->Options is good enough for now.
+ */
+
+ /* Set options word to its new value */
+ InstancePtr->Options |= Options;
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Clear options for the driver/device
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param Options are the options to clear. Multiple options can be cleared by
+ * OR'ing XEMACPSS_*_OPTIONS constants together. Options not specified
+ * are not affected.
+ *
+ * @return
+ * - XST_SUCCESS if the options were set successfully
+ * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+ *
+ * @note
+ * See xemacpss.h for a description of the available options.
+ *
+ *****************************************************************************/
+int XEmacPss_ClearOptions(XEmacPss *InstancePtr, u32 Options)
+{
+ u32 Reg; /* Generic */
+ u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
+ u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Many of these options will change the NET_CONFIG registers.
+ * To reduce the amount of IO to the device, group these options here
+ * and change them all at once.
+ */
+
+ /* Grab current register contents */
+ RegNetCfg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET);
+ RegNewNetCfg = RegNetCfg;
+
+ /* There is only RX configuration!?
+ * It is configured in two different length, upto 1536 and 10240 bytes
+ */
+ if (Options & XEMACPSS_FRAME1536_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_1536RXEN_MASK;
+ }
+
+ /* Turn off VLAN packet only */
+ if (Options & XEMACPSS_VLAN_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_NVLANDISC_MASK;
+ }
+
+ /* Turn off FCS stripping on receive packets */
+ if (Options & XEMACPSS_FCS_STRIP_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_FCSREM_MASK;
+ }
+
+ /* Turn off length/type field checking on receive packets */
+ if (Options & XEMACPSS_LENTYPE_ERR_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_LENGTHERRDSCRD_MASK;
+ }
+
+ /* Turn off flow control */
+ if (Options & XEMACPSS_FLOW_CONTROL_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_PAUSEEN_MASK;
+ }
+
+ /* Turn off promiscuous frame filtering (all frames are received) */
+ if (Options & XEMACPSS_PROMISC_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_COPYALLEN_MASK;
+ }
+
+ /* Disallow broadcast address filtering => broadcast reception */
+ if (Options & XEMACPSS_BROADCAST_OPTION) {
+ RegNewNetCfg |= XEMACPSS_NWCFG_BCASTDI_MASK;
+ }
+
+ /* Disallow multicast address filtering */
+ if (Options & XEMACPSS_MULTICAST_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_MCASTHASHEN_MASK;
+ }
+
+ /* Disable RX checksum offload */
+ if (Options & XEMACPSS_RX_CHKSUM_ENABLE_OPTION) {
+ RegNewNetCfg &= ~XEMACPSS_NWCFG_RXCHKSUMEN_MASK;
+ }
+
+ /* Officially change the NET_CONFIG registers if it needs to be
+ * modified.
+ */
+ if (RegNetCfg != RegNewNetCfg) {
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET, RegNewNetCfg);
+ }
+
+ /* Disable TX checksum offload */
+ if (Options & XEMACPSS_TX_CHKSUM_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_DMACR_OFFSET);
+ Reg &= ~XEMACPSS_DMACR_TCPCKSUM_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_DMACR_OFFSET, Reg);
+ }
+
+ /* Disable transmitter */
+ if (Options & XEMACPSS_TRANSMITTER_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ Reg &= ~XEMACPSS_NWCTRL_TXEN_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET, Reg);
+ }
+
+ /* Disable receiver */
+ if (Options & XEMACPSS_RECEIVER_ENABLE_OPTION) {
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ Reg &= ~XEMACPSS_NWCTRL_RXEN_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET, Reg);
+ }
+
+ /* The remaining options not handled here are managed elsewhere in the
+ * driver. No register modifications are needed at this time. Reflecting
+ * option in InstancePtr->Options is good enough for now.
+ */
+
+ /* Set options word to its new value */
+ InstancePtr->Options &= ~Options;
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Get current option settings
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return
+ * A bitmask of XTE_*_OPTION constants. Any bit set to 1 is to be interpreted
+ * as a set opion.
+ *
+ * @note
+ * See xemacpss.h for a description of the available options.
+ *
+ *****************************************************************************/
+u32 XEmacPss_GetOptions(XEmacPss *InstancePtr)
+{
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ return (InstancePtr->Options);
+}
+
+
+/*****************************************************************************/
+/**
+ * Send a pause packet
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return
+ * - XST_SUCCESS if pause frame transmission was initiated
+ * - XST_DEVICE_IS_STOPPED if the device has not been started.
+ *
+ *****************************************************************************/
+int XEmacPss_SendPausePacket(XEmacPss *InstancePtr)
+{
+ u32 Reg;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* Make sure device is ready for this operation */
+ if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STOPPED);
+ }
+
+ /* Send flow control frame */
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET);
+ Reg |= XEMACPSS_NWCTRL_PAUSETX_MASK;
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCTRL_OFFSET, Reg);
+ return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * XEmacPss_GetOperatingSpeed gets the current operating link speed. This may
+ * be the value set by XEmacPss_SetOperatingSpeed() or a hardware default.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XEmacPss_GetOperatingSpeed returns the link speed in units of
+ * megabits per second.
+ *
+ * @note
+ *
+ *****************************************************************************/
+u16 XEmacPss_GetOperatingSpeed(XEmacPss *InstancePtr)
+{
+ u32 Reg;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET);
+
+ if (Reg & XEMACPSS_NWCFG_1000_MASK) {
+ return (1000);
+ } else {
+ if (Reg & XEMACPSS_NWCFG_100_MASK) {
+ return (100);
+ } else {
+ return (10);
+ }
+ }
+}
+
+
+/*****************************************************************************/
+/**
+ * XEmacPss_SetOperatingSpeed sets the current operating link speed. For any
+ * traffic to be passed, this speed must match the current MII/GMII/SGMII/RGMII
+ * link speed.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Speed is the speed to set in units of Mbps. Valid values are 10, 100,
+ * or 1000. XEmacPss_SetOperatingSpeed ignores invalid values.
+ *
+ * @note
+ *
+ *****************************************************************************/
+void XEmacPss_SetOperatingSpeed(XEmacPss *InstancePtr, u16 Speed)
+{
+ u32 Reg;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_VOID((Speed == 10) || (Speed == 100) || (Speed == 1000));
+
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET);
+ Reg &= ~(XEMACPSS_NWCFG_1000_MASK | XEMACPSS_NWCFG_100_MASK);
+
+ switch (Speed) {
+ case 10:
+ break;
+
+ case 100:
+ Reg |= XEMACPSS_NWCFG_100_MASK;
+ break;
+
+ case 1000:
+ Reg |= XEMACPSS_NWCFG_1000_MASK;
+ break;
+
+ default:
+ return;
+ }
+
+ /* Set register and return */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET, Reg);
+}
+
+
+/*****************************************************************************/
+/**
+ * Set the MDIO clock divisor.
+ *
+ * Calculating the divisor:
+ *
+ * <pre>
+ * f[HOSTCLK]
+ * f[MDC] = -----------------
+ * (1 + Divisor) * 2
+ * </pre>
+ *
+ * where f[HOSTCLK] is the bus clock frequency in MHz, and f[MDC] is the
+ * MDIO clock frequency in MHz to the PHY. Typically, f[MDC] should not
+ * exceed 2.5 MHz. Some PHYs can tolerate faster speeds which means faster
+ * access. Here is the table to show values to generate MDC,
+ *
+ * <pre>
+ * 000 : divide pclk by 8 (pclk up to 20 MHz)
+ * 001 : divide pclk by 16 (pclk up to 40 MHz)
+ * 010 : divide pclk by 32 (pclk up to 80 MHz)
+ * 011 : divide pclk by 48 (pclk up to 120 MHz)
+ * 100 : divide pclk by 64 (pclk up to 160 MHz)
+ * 101 : divide pclk by 96 (pclk up to 240 MHz)
+ * 110 : divide pclk by 128 (pclk up to 320 MHz)
+ * 111 : divide pclk by 224 (pclk up to 540 MHz)
+ * </pre>
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param Divisor is the divisor to set. Range is 0b000 to 0b111.
+ *
+ *****************************************************************************/
+void XEmacPss_SetMdioDivisor(XEmacPss *InstancePtr, XEmacPss_MdcDiv Divisor)
+{
+ u32 Reg;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY)
+ XASSERT_VOID(Divisor <= 0x7); /* only last three bits are valid */
+
+ Reg = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET);
+ /* clear these three bits, could be done with mask */
+ Reg &= ~XEMACPSS_NWCFG_MDCCLKDIV_MASK;
+
+ Reg |= (Divisor << XEMACPSS_NWCFG_MDC_SHIFT_MASK);
+
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWCFG_OFFSET, Reg);
+
+}
+
+
+/*****************************************************************************/
+/**
+* Read the current value of the PHY register indicated by the PhyAddress and
+* the RegisterNum parameters. The MAC provides the driver with the ability to
+* talk to a PHY that adheres to the Media Independent Interface (MII) as
+* defined in the IEEE 802.3 standard.
+*
+* Prior to PHY access with this function, the user should have setup the MDIO
+* clock with XEmacPss_SetMdioDivisor().
+*
+* @param InstancePtr is a pointer to the XEmacPss instance to be worked on.
+* @param PhyAddress is the address of the PHY to be read (supports multiple
+* PHYs)
+* @param RegisterNum is the register number, 0-31, of the specific PHY register
+* to read
+* @param PhyDataPtr is an output parameter, and points to a 16-bit buffer into
+* which the current value of the register will be copied.
+*
+* @return
+*
+* - XST_SUCCESS if the PHY was read from successfully
+* - XST_EMAC_MII_BUSY if there is another PHY operation in progress
+*
+* @note
+*
+* This function is not thread-safe. The user must provide mutually exclusive
+* access to this function if there are to be multiple threads that can call it.
+*
+* There is the possibility that this function will not return if the hardware
+* is broken (i.e., it never sets the status bit indicating that the read is
+* done). If this is of concern to the user, the user should provide a mechanism
+* suitable to their needs for recovery.
+*
+* For the duration of this function, all host interface reads and writes are
+* blocked to the current XEmacPss instance.
+*
+******************************************************************************/
+int XEmacPss_PhyRead(XEmacPss *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 *PhyDataPtr)
+{
+ u32 Mgtcr;
+ volatile u32 Ipisr;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+
+ /* Make sure no other PHY operation is currently in progress */
+ if (!(XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWSR_OFFSET) &
+ XEMACPSS_NWSR_MDIOIDLE_MASK)) {
+ return (XST_EMAC_MII_BUSY);
+ }
+
+ /* Construct Mgtcr mask for the operation */
+ Mgtcr = XEMACPSS_PHYMNTNC_OP_MASK | XEMACPSS_PHYMNTNC_OP_R_MASK |
+ (PhyAddress << XEMACPSS_PHYMNTNC_PHYAD_SHIFT_MASK) |
+ (RegisterNum << XEMACPSS_PHYMNTNC_PHREG_SHIFT_MASK);
+
+ /* Write Mgtcr and wait for completion */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_PHYMNTNC_OFFSET, Mgtcr);
+
+ do {
+ Ipisr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWSR_OFFSET);
+ } while ((Ipisr & XEMACPSS_NWSR_MDIOIDLE_MASK) == 0);
+
+ /* Read data */
+ *PhyDataPtr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_PHYMNTNC_OFFSET);
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+* Write data to the specified PHY register. The Ethernet driver does not
+* require the device to be stopped before writing to the PHY. Although it is
+* probably a good idea to stop the device, it is the responsibility of the
+* application to deem this necessary. The MAC provides the driver with the
+* ability to talk to a PHY that adheres to the Media Independent Interface
+* (MII) as defined in the IEEE 802.3 standard.
+*
+* Prior to PHY access with this function, the user should have setup the MDIO
+* clock with XEmacPss_SetMdioDivisor().
+*
+* @param InstancePtr is a pointer to the XEmacPss instance to be worked on.
+* @param PhyAddress is the address of the PHY to be written (supports multiple
+* PHYs)
+* @param RegisterNum is the register number, 0-31, of the specific PHY register
+* to write
+* @param PhyData is the 16-bit value that will be written to the register
+*
+* @return
+*
+* - XST_SUCCESS if the PHY was written to successfully. Since there is no error
+* status from the MAC on a write, the user should read the PHY to verify the
+* write was successful.
+* - XST_EMAC_MII_BUSY if there is another PHY operation in progress
+*
+* @note
+*
+* This function is not thread-safe. The user must provide mutually exclusive
+* access to this function if there are to be multiple threads that can call it.
+*
+* There is the possibility that this function will not return if the hardware
+* is broken (i.e., it never sets the status bit indicating that the write is
+* done). If this is of concern to the user, the user should provide a mechanism
+* suitable to their needs for recovery.
+*
+* For the duration of this function, all host interface reads and writes are
+* blocked to the current XEmacPss instance.
+*
+******************************************************************************/
+int XEmacPss_PhyWrite(XEmacPss *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 PhyData)
+{
+ u32 Mgtcr;
+ volatile u32 Ipisr;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+
+ /* Make sure no other PHY operation is currently in progress */
+ if (!(XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWSR_OFFSET) &
+ XEMACPSS_NWSR_MDIOIDLE_MASK)) {
+ return (XST_EMAC_MII_BUSY);
+ }
+
+ /* Construct Mgtcr mask for the operation */
+ Mgtcr = XEMACPSS_PHYMNTNC_OP_MASK | XEMACPSS_PHYMNTNC_OP_W_MASK |
+ (PhyAddress << XEMACPSS_PHYMNTNC_PHYAD_SHIFT_MASK) |
+ (RegisterNum << XEMACPSS_PHYMNTNC_PHREG_SHIFT_MASK) | PhyData;
+
+ /* Write Mgtcr and wait for completion */
+ XEmacPss_WriteReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_PHYMNTNC_OFFSET, Mgtcr);
+
+ do {
+ Ipisr = XEmacPss_ReadReg(InstancePtr->Config.BaseAddress,
+ XEMACPSS_NWSR_OFFSET);
+ } while ((Ipisr & XEMACPSS_NWSR_MDIOIDLE_MASK) == 0);
+
+ return (XST_SUCCESS);
+}
+
+void XIo_Out32(u32 OutAddress, u32 Value)
+{
+ *(volatile u32 *) OutAddress = Value;
+}
+
+u32 XIo_In32(u32 InAddress)
+{
+ return *(u32 *) InAddress;
+}
--- /dev/null
+/* $Id: */
+/*****************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+*****************************************************************************/
+/****************************************************************************/
+/**
+*
+* @file xemacpss_example.h
+*
+* Defines common data types, prototypes, and includes the proper headers
+* for use with the EMACPSS example code residing in this directory.
+*
+* This file along with xemacpss_example_util.c are utilized with the specific
+* example code in the other source code files provided.
+* These examples are designed to be compiled and utilized within the EDK
+* standalone BSP development environment. The readme file contains more
+* information on build requirements needed by these examples.
+*
+* Look for TODO comments and make appropriate code changes for your system.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a wsy 06/01/09 First release
+* </pre>
+*
+*****************************************************************************/
+#ifndef XEMACPSS_EXAMPLE_H
+#define XEMACPSS_EXAMPLE_H
+
+
+/***************************** Include Files ********************************/
+
+//#include "xbasic_types.h"
+//#include <xio.h>
+#include "xemacpss.h" /* defines XEmacPss API */
+
+/************************** Constant Definitions ****************************/
+
+/* TODO: Other link related */
+#define EMACPSS_LOOPBACK_SPEED 100 /* 100Mbps */
+#define EMACPSS_LOOPBACK_SPEED_1G 1000 /* 1000Mbps */
+#define EMACPSS_PHY_DELAY_SEC 4 /* Amount of time to delay waiting on
+ PHY to reset */
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+
+/**************************** Type Definitions ******************************/
+
+/*
+ * Define an aligned data type for an ethernet frame. This declaration is
+ * specific to the GNU compiler
+ */
+typedef char EthernetFrame[XEMACPSS_RX_BUF_SIZE]
+ __attribute__ ((aligned(4)));
+
+
+/************************** Function Prototypes *****************************/
+
+
+
+
+/************************** Variable Definitions ****************************/
+
+//extern XEmacPss EmacPssInstance; /* Device instance used throughout examples */
+//extern char EmacPssMAC[]; /* Local MAC address */
+
+
+#endif /* XEMACPSS_EXAMPLE_H */
--- /dev/null
+/* $Id: xemacpss_g.c,v 1.1.2.1 2009/06/17 16:10:26 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemacpss_g.c
+*
+* This file contains a configuration table that specifies the configuration of
+* ethernet devices in the system.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a wsy 06/01/09 First release
+* </pre>
+*
+* @internal
+*
+* This configuration table contains entries that are modified at runtime by the
+* driver. This table reflects only the hardware configuration of the device.
+* This emac configuration table contains software information in addition to
+* hardware configuration.
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+//#include "xparameters.h"
+#include "xemacpss.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Prototypes ******************************/
+
+/*
+ * The configuration table for emacpss device
+ */
+
+XEmacPss_Config XEmacPss_ConfigTable[XPAR_XEMACPSS_NUM_INSTANCES] = {
+ {
+ XPAR_XEMACPSS_0_DEVICE_ID, /* Device ID */
+ XPAR_XEMACPSS_0_BASEADDR /* Device base address */
+ },
+ {
+ XPAR_XEMACPSS_1_DEVICE_ID, /* Device ID */
+ XPAR_XEMACPSS_1_BASEADDR /* Device base address */
+ }
+};
--- /dev/null
+/* $Id: xemacpss_hw.h,v 1.1.2.1 2009/06/17 16:10:26 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemacpss_hw.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the PSS Ethernet MAC (XEmacPss) device.
+* High-level driver functions are defined in xemacpss.h.
+*
+* @note
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a wsy 06/01/09 First release.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMACPSS_HW_H /* prevent circular inclusions */
+#define XEMACPSS_HW_H /* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+//#include "xbasic_types.h"
+//#include "xio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************** Constant Definitions *****************************/
+
+#define XEMACPSS_MAX_MAC_ADDR 4 /**< Maxmum number of mac address
+ supported */
+#define XEMACPSS_MAX_TYPE_ID 4 /**< Maxmum number of type id supported */
+#define XEMACPSS_BD_ALIGNMENT 4 /**< Minimum buffer descriptor alignment
+ on the local bus */
+#define XEMACPSS_RX_BUF_ALIGNMENT 4 /**< Minimum buffer alignment when using
+ options that impose alignment
+ restrictions on the buffer data on
+ the local bus */
+
+/** @name Direction identifiers
+ *
+ * These are used by several functions and callbacks that need
+ * to specify whether an operation specifies a send or receive channel.
+ * @{
+ */
+#define XEMACPSS_SEND 1 /**< send direction */
+#define XEMACPSS_RECV 2 /**< receive direction */
+/*@}*/
+
+/** @name MDC clock division
+ * currently supporting 8, 16, 32, 48, 64, 96, 128, 224.
+ * @{
+ */
+typedef enum { XMDC_DIV_8 = 0, XMDC_DIV_16, XMDC_DIV_32, XMDC_DIV_48,
+ XMDC_DIV_64, XMDC_DIV_96, XMDC_DIV_128, XMDC_DIV_224
+} XEmacPss_MdcDiv;
+
+/*@}*/
+
+#define XEMACPSS_RX_BUF_SIZE 1536 /**< Specify the receive buffer size in
+ bytes, 64, 128, ... 10240 */
+#define XEMACPSS_RX_BUF_UNIT 64 /**< Number of receive buffer bytes as a
+ unit, this is HW setup */
+
+#define XEMACPSS_MAX_RXBD 128 /**< Size of RX buffer descriptor queues */
+#define XEMACPSS_MAX_TXBD 128 /**< Size of TX buffer descriptor queues */
+
+#define XEMACPSS_MAX_HASH_BITS 64 /**< Maximum value for hash bits. 2**6 */
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit. Names are self explained here.
+ */
+
+#define XEMACPSS_NWCTRL_OFFSET 0x00000000 /**< Network Control reg */
+#define XEMACPSS_NWCFG_OFFSET 0x00000004 /**< Network Config reg */
+#define XEMACPSS_NWSR_OFFSET 0x00000008 /**< Network Status reg */
+
+#define XEMACPSS_DMACR_OFFSET 0x00000010 /**< DMA Control reg */
+#define XEMACPSS_TXSR_OFFSET 0x00000014 /**< TX Status reg */
+#define XEMACPSS_RXQBASE_OFFSET 0x00000018 /**< RX Q Base address reg */
+#define XEMACPSS_TXQBASE_OFFSET 0x0000001C /**< TX Q Base address reg */
+#define XEMACPSS_RXSR_OFFSET 0x00000020 /**< RX Status reg */
+
+#define XEMACPSS_ISR_OFFSET 0x00000024 /**< Interrupt Status reg */
+#define XEMACPSS_IER_OFFSET 0x00000028 /**< Interrupt Enable reg */
+#define XEMACPSS_IDR_OFFSET 0x0000002C /**< Interrupt Disable reg */
+#define XEMACPSS_IMR_OFFSET 0x00000030 /**< Interrupt Mask reg */
+
+#define XEMACPSS_PHYMNTNC_OFFSET 0x00000034 /**< Phy Maintaince reg */
+#define XEMACPSS_RXPAUSE_OFFSET 0x00000038 /**< RX Pause Time reg */
+#define XEMACPSS_TXPAUSE_OFFSET 0x0000003C /**< TX Pause Time reg */
+
+#define XEMACPSS_HASHL_OFFSET 0x00000080 /**< Hash Low address reg */
+#define XEMACPSS_HASHH_OFFSET 0x00000084 /**< Hash High address reg */
+
+#define XEMACPSS_LADDR1L_OFFSET 0x00000088 /**< Specific1 addr low reg */
+#define XEMACPSS_LADDR1H_OFFSET 0x0000008C /**< Specific1 addr high reg */
+#define XEMACPSS_LADDR2L_OFFSET 0x00000090 /**< Specific2 addr low reg */
+#define XEMACPSS_LADDR2H_OFFSET 0x00000094 /**< Specific2 addr high reg */
+#define XEMACPSS_LADDR3L_OFFSET 0x00000098 /**< Specific3 addr low reg */
+#define XEMACPSS_LADDR3H_OFFSET 0x0000009C /**< Specific3 addr high reg */
+#define XEMACPSS_LADDR4L_OFFSET 0x000000A0 /**< Specific4 addr low reg */
+#define XEMACPSS_LADDR4H_OFFSET 0x000000A4 /**< Specific4 addr high reg */
+
+#define XEMACPSS_MATCH1_OFFSET 0x000000A8 /**< Type ID1 Match reg */
+#define XEMACPSS_MATCH2_OFFSET 0x000000AC /**< Type ID2 Match reg */
+#define XEMACPSS_MATCH3_OFFSET 0x000000B0 /**< Type ID3 Match reg */
+#define XEMACPSS_MATCH4_OFFSET 0x000000B4 /**< Type ID4 Match reg */
+
+#define XEMACPSS_STRETCH_OFFSET 0x000000BC /**< IPG Stretch reg */
+
+#define XEMACPSS_OCTTXL_OFFSET 0x00000100 /**< Octects transmitted Low
+ reg */
+#define XEMACPSS_OCTTXH_OFFSET 0x00000104 /**< Octects transmitted High
+ reg */
+
+#define XEMACPSS_TXCNT_OFFSET 0x00000108 /**< Error-free Frmaes
+ transmitted counter */
+#define XEMACPSS_TXBCCNT_OFFSET 0x0000010C /**< Error-free Broadcast
+ Frames counter*/
+#define XEMACPSS_TXMCCNT_OFFSET 0x00000110 /**< Error-free Multicast
+ Frame counter */
+#define XEMACPSS_TXPAUSECNT_OFFSET 0x00000114 /**< Pause Frames Transmitted
+ Counter */
+#define XEMACPSS_TX64CNT_OFFSET 0x00000118 /**< Error-free 64 byte Frames
+ Transmitted counter */
+#define XEMACPSS_TX65CNT_OFFSET 0x0000011C /**< Error-free 65-127 byte
+ Frames Transmitted
+ counter */
+#define XEMACPSS_TX128CNT_OFFSET 0x00000120 /**< Error-free 128-255 byte
+ Frames Transmitted
+ counter*/
+#define XEMACPSS_TX256CNT_OFFSET 0x00000124 /**< Error-free 256-511 byte
+ Frames transmitted
+ counter */
+#define XEMACPSS_TX512CNT_OFFSET 0x00000128 /**< Error-free 512-1023 byte
+ Frames transmitted
+ counter */
+#define XEMACPSS_TX1024CNT_OFFSET 0x0000012C /**< Error-free 1024-1518 byte
+ Frames transmitted
+ counter */
+#define XEMACPSS_TX1519CNT_OFFSET 0x00000130 /**< Error-free larger than
+ 1519 byte Frames
+ transmitted counter */
+#define XEMACPSS_TXURUNCNT_OFFSET 0x00000134 /**< TX under run error
+ counter */
+
+#define XEMACPSS_SNGLCOLLCNT_OFFSET 0x00000138 /**< Single Collision Frame
+ Counter */
+#define XEMACPSS_MULTICOLLCNT_OFFSET 0x0000013C /**< Multiple Collision Frame
+ Counter */
+#define XEMACPSS_EXCESSCOLLCNT_OFFSET 0x00000140 /**< Excessive Collision Frame
+ Counter */
+#define XEMACPSS_LATECOLLCNT_OFFSET 0x00000144 /**< Late Collision Frame
+ Counter */
+#define XEMACPSS_TXDEFERCNT_OFFSET 0x00000148 /**< Deferred Transmission
+ Frame Counter */
+#define XEMACPSS_TXCSENSECNT_OFFSET 0x0000014C /**< Transmit Carrier Sense
+ Error Counter */
+
+#define XEMACPSS_OCTRXL_OFFSET 0x00000150 /**< Octects Received register
+ Low */
+#define XEMACPSS_OCTRXH_OFFSET 0x00000154 /**< Octects Received register
+ High */
+
+#define XEMACPSS_RXCNT_OFFSET 0x00000158 /**< Error-free Frames
+ Received Counter */
+#define XEMACPSS_RXBROADCNT_OFFSET 0x0000015C /**< Error-free Broadcast
+ Frames Received Counter */
+#define XEMACPSS_RXMULTICNT_OFFSET 0x00000160 /**< Error-free Multicast
+ Frames Received Counter */
+#define XEMACPSS_RXPAUSECNT_OFFSET 0x00000164 /**< Pause Frames
+ Received Counter */
+#define XEMACPSS_RX64CNT_OFFSET 0x00000168 /**< Error-free 64 byte Frames
+ Received Counter */
+#define XEMACPSS_RX65CNT_OFFSET 0x0000016C /**< Error-free 65-127 byte
+ Frames Received Counter */
+#define XEMACPSS_RX128CNT_OFFSET 0x00000170 /**< Error-free 128-255 byte
+ Frames Received Counter */
+#define XEMACPSS_RX256CNT_OFFSET 0x00000174 /**< Error-free 256-512 byte
+ Frames Received Counter */
+#define XEMACPSS_RX512CNT_OFFSET 0x00000178 /**< Error-free 512-1023 byte
+ Frames Received Counter */
+#define XEMACPSS_RX1024CNT_OFFSET 0x0000017C /**< Error-free 1024-1518 byte
+ Frames Received Counter */
+#define XEMACPSS_RX1519CNT_OFFSET 0x00000180 /**< Error-free 1519-max byte
+ Frames Received Counter */
+#define XEMACPSS_RXUNDRCNT_OFFSET 0x00000184 /**< Undersize Frames Received
+ Counter */
+#define XEMACPSS_RXOVRCNT_OFFSET 0x00000188 /**< Oversize Frames Received
+ Counter */
+#define XEMACPSS_RXJABCNT_OFFSET 0x0000018C /**< Jabbers Received
+ Counter */
+#define XEMACPSS_RXFCSCNT_OFFSET 0x00000190 /**< Frame Check Sequence
+ Error Counter */
+#define XEMACPSS_RXLENGTHCNT_OFFSET 0x00000194 /**< Length Field Error
+ Counter */
+#define XEMACPSS_RXSYMBCNT_OFFSET 0x00000198 /**< Symbol Error Counter */
+#define XEMACPSS_RXALIGNCNT_OFFSET 0x0000019C /**< Alignment Error Counter */
+#define XEMACPSS_RXRESERRCNT_OFFSET 0x000001A0 /**< Receive Resource Error
+ Counter */
+#define XEMACPSS_RXORCNT_OFFSET 0x000001A4 /**< Receive Overrun Counter */
+#define XEMACPSS_RXIPCCNT_OFFSET 0x000001A8 /**< IP header Checksum Error
+ Counter */
+#define XEMACPSS_RXTCPCCNT_OFFSET 0x000001AC /**< TCP Checksum Error
+ Counter */
+#define XEMACPSS_RXUDPCCNT_OFFSET 0x000001B0 /**< UDP Checksum Error
+ Counter */
+#define XEMACPSS_LAST_OFFSET 0x000001B4 /**< Last statistic counter
+ offset, for clearing */
+
+#define XEMACPSS_1588_SEC_OFFSET 0x000001D0 /**< 1588 second counter */
+#define XEMACPSS_1588_NANOSEC_OFFSET 0x000001D4 /**< 1588 nanosecond counter */
+#define XEMACPSS_1588_ADJ_OFFSET 0x000001D8 /**< 1588 nanosecond
+ adjustment counter */
+#define XEMACPSS_1588_INC_OFFSET 0x000001DC /**< 1588 nanosecond
+ increment counter */
+#define XEMACPSS_PTP_TXSEC_OFFSET 0x000001E0 /**< 1588 PTP transmit second
+ counter */
+#define XEMACPSS_PTP_TXNANOSEC_OFFSET 0x000001E4 /**< 1588 PTP transmit
+ nanosecond counter */
+#define XEMACPSS_PTP_RXSEC_OFFSET 0x000001E8 /**< 1588 PTP receive second
+ counter */
+#define XEMACPSS_PTP_RXNANOSEC_OFFSET 0x000001EC /**< 1588 PTP receive
+ nanosecond counter */
+#define XEMACPSS_PTPP_TXSEC_OFFSET 0x000001F0 /**< 1588 PTP peer transmit
+ second counter */
+#define XEMACPSS_PTPP_TXNANOSEC_OFFSET 0x000001F4 /**< 1588 PTP peer transmit
+ nanosecond counter */
+#define XEMACPSS_PTPP_RXSEC_OFFSET 0x000001F8 /**< 1588 PTP peer receive
+ second counter */
+#define XEMACPSS_PTPP_RXNANOSEC_OFFSET 0x000001FC /**< 1588 PTP peer receive
+ nanosecond counter */
+
+/* Define some bit positions for registers. */
+
+/** @name network control register bit definitions
+ * @{
+ */
+#define XEMACPSS_NWCTRL_ZEROPAUSETX_MASK 0x00000800 /**< Transmit zero quantum
+ pause frame */
+#define XEMACPSS_NWCTRL_PAUSETX_MASK 0x00000800 /**< Transmit pause frame */
+#define XEMACPSS_NWCTRL_HALTTX_MASK 0x00000400 /**< Halt transmission
+ after current frame */
+#define XEMACPSS_NWCTRL_STARTTX_MASK 0x00000200 /**< Start tx (tx_go) */
+
+#define XEMACPSS_NWCTRL_STATWEN_MASK 0x00000080 /**< Enable writing to
+ stat counters */
+#define XEMACPSS_NWCTRL_STATINC_MASK 0x00000040 /**< Increment statistic
+ registers */
+#define XEMACPSS_NWCTRL_STATCLR_MASK 0x00000020 /**< Clear statistic
+ registers */
+#define XEMACPSS_NWCTRL_MDEN_MASK 0x00000010 /**< Enable MDIO port */
+#define XEMACPSS_NWCTRL_TXEN_MASK 0x00000008 /**< Enable transmit */
+#define XEMACPSS_NWCTRL_RXEN_MASK 0x00000004 /**< Enable receive */
+#define XEMACPSS_NWCTRL_LOOPEN_MASK 0x00000002 /**< local loopback */
+/*@}*/
+
+/** @name network configuration register bit definitions
+ * @{
+ */
+#define XEMACPSS_NWCFG_BADPREAMBEN_MASK 0x20000000 /**< disable rejection of
+ non-standard preamble */
+#define XEMACPSS_NWCFG_IPDSTRETCH_MASK 0x10000000 /**< enable transmit IPG */
+#define XEMACPSS_NWCFG_FCSIGNORE_MASK 0x04000000 /**< disable rejection of
+ FCS error */
+#define XEMACPSS_NWCFG_HDRXEN_MASK 0x02000000 /**< RX half duplex */
+#define XEMACPSS_NWCFG_RXCHKSUMEN_MASK 0x01000000 /**< enable RX checksum
+ offload */
+#define XEMACPSS_NWCFG_PAUSECOPYDI_MASK 0x00800000 /**< Do not copy pause
+ Frames to memory */
+#define XEMACPSS_NWCFG_MDC_SHIFT_MASK 18 /**< shift bits for MDC */
+#define XEMACPSS_NWCFG_MDCCLKDIV_MASK 0x001C0000 /**< MDC Mask PCLK divisor */
+#define XEMACPSS_NWCFG_FCSREM_MASK 0x00020000 /**< Discard FCS from
+ received frames */
+#define XEMACPSS_NWCFG_LENGTHERRDSCRD_MASK 0x00010000
+/**< RX length error discard */
+#define XEMACPSS_NWCFG_RXOFFS_MASK 0x0000C000 /**< RX buffer offset */
+#define XEMACPSS_NWCFG_PAUSEEN_MASK 0x00002000 /**< Enable pause RX */
+#define XEMACPSS_NWCFG_RETRYTESTEN_MASK 0x00001000 /**< Retry test */
+#define XEMACPSS_NWCFG_EXTADDRMATCHEN_MASK 0x00000200
+/**< External address match enable */
+#define XEMACPSS_NWCFG_1000_MASK 0x00000400 /**< 1000 Mbps */
+#define XEMACPSS_NWCFG_1536RXEN_MASK 0x00000100 /**< Enable 1536 byte
+ frames reception */
+#define XEMACPSS_NWCFG_UCASTHASHEN_MASK 0x00000080 /**< Receive unicast hash
+ frames */
+#define XEMACPSS_NWCFG_MCASTHASHEN_MASK 0x00000040 /**< Receive multicast hash
+ frames */
+#define XEMACPSS_NWCFG_BCASTDI_MASK 0x00000020 /**< Do not receive
+ broadcast frames */
+#define XEMACPSS_NWCFG_COPYALLEN_MASK 0x00000010 /**< Copy all frames */
+#define XEMACPSS_NWCFG_JUMBO_MASK 0x00000008 /**< Jumbo frames */
+#define XEMACPSS_NWCFG_NVLANDISC_MASK 0x00000004 /**< Receive only VLAN
+ frames */
+#define XEMACPSS_NWCFG_FDEN_MASK 0x00000002 /**< full duplex */
+#define XEMACPSS_NWCFG_100_MASK 0x00000001 /**< 100 Mbps */
+/*@}*/
+
+/** @name network status register bit definitaions
+ * @{
+ */
+#define XEMACPSS_NWSR_MDIOIDLE_MASK 0x00000004 /**< PHY management idle */
+#define XEMACPSS_NWSR_MDIO_MASK 0x00000002 /**< Status of mdio_in */
+/*@}*/
+
+
+/** @name MAC address register word 1 mask
+ * @{
+ */
+#define XEMACPSS_LADDR_MACH_MASK 0x0000FFFF /**< Address bits[47:32]
+ bit[31:0] are in BOTTOM */
+/*@}*/
+
+
+/** @name DMA control register bit definitions
+ * @{
+ */
+#define XEMACPSS_DMACR_RXBUF_MASK 0x00FF0000 /**< Mask bit for RX buffer
+ size */
+#define XEMACPSS_DMACR_RXBUF_SHIFT 16 /**< Shift bit for RX buffer
+ size */
+#define XEMACPSS_DMACR_TCPCKSUM_MASK 0x00000800 /**< enable/disable TX
+ checksum offload */
+#define XEMACPSS_DMACR_TXSIZE_MASK 0x00000400 /**< TX buffer memory size */
+#define XEMACPSS_DMACR_RXSIZE_MASK 0x00000300 /**< RX buffer memory size */
+#define XEMACPSS_DMACR_ENDIAN_MASK 0x00000080 /**< endian configuration */
+#define XEMACPSS_DMACR_BLENGTH_MASK 0x0000001F /**< buffer burst length */
+/*@}*/
+
+/** @name transmit status register bit definitions
+ * @{
+ */
+#define XEMACPSS_TXSR_HRESPNOK_MASK 0x00000100 /**< Transmit hresp not OK */
+#define XEMACPSS_TXSR_URUN_MASK 0x00000040 /**< Transmit underrun */
+#define XEMACPSS_TXSR_TXCOMPL_MASK 0x00000020 /**< Transmit completed OK */
+#define XEMACPSS_TXSR_BUFEXH_MASK 0x00000010 /**< Transmit buffs exhausted
+ mid frame */
+#define XEMACPSS_TXSR_TXGO_MASK 0x00000008 /**< Status of go flag */
+#define XEMACPSS_TXSR_RXOVR_MASK 0x00000004 /**< Retry limit exceeded */
+#define XEMACPSS_TXSR_FRAMERX_MASK 0x00000002 /**< Collision tx frame */
+#define XEMACPSS_TXSR_USEDREAD_MASK 0x00000001 /**< TX buffer used bit set */
+
+#define XEMACPSS_TXSR_ERROR_MASK (XEMACPSS_TXSR_HRESPNOK_MASK | \
+ XEMACPSS_TXSR_URUN_MASK | \
+ XEMACPSS_TXSR_BUFEXH_MASK | \
+ XEMACPSS_TXSR_RXOVR_MASK | \
+ XEMACPSS_TXSR_FRAMERX_MASK | \
+ XEMACPSS_TXSR_USEDREAD_MASK)
+/*@}*/
+
+/** @name receive status register bit definitions
+ * @{
+ */
+#define XEMACPSS_RXSR_HRESPNOK_MASK 0x00000008 /**< Receive hresp not OK */
+#define XEMACPSS_RXSR_RXOVR_MASK 0x00000004 /**< Receive overrun */
+#define XEMACPSS_RXSR_FRAMERX_MASK 0x00000002 /**< Frame received OK */
+#define XEMACPSS_RXSR_BUFFNA_MASK 0x00000001 /**< RX buffer used bit set */
+
+#define XEMACPSS_RXSR_ERROR_MASK (XEMACPSS_RXSR_HRESPNOK_MASK | \
+ XEMACPSS_RXSR_RXOVR_MASK | \
+ XEMACPSS_RXSR_BUFFNA_MASK)
+/*@}*/
+
+/** @name interrupts bit definitions
+ * Bits definitions are same in XEMACPSS_ISR_OFFSET,
+ * XEMACPSS_IER_OFFSET, XEMACPSS_IDR_OFFSET, and XEMACPSS_IMR_OFFSET
+ * @{
+ */
+#define XEMACPSS_IXR_PTPPSTX_MASK 0x02000000 /**< PTP Psync transmitted */
+#define XEMACPSS_IXR_PTPPDRTX_MASK 0x01000000 /**< PTP Pdelay_req
+ transmitted */
+#define XEMACPSS_IXR_PTPSTX_MASK 0x00800000 /**< PTP Sync transmitted */
+#define XEMACPSS_IXR_PTPDRTX_MASK 0x00400000 /**< PTP Delay_req transmitted
+ */
+#define XEMACPSS_IXR_PTPPSRX_MASK 0x00200000 /**< PTP Psync received */
+#define XEMACPSS_IXR_PTPPDRRX_MASK 0x00100000 /**< PTP Pdelay_req received */
+#define XEMACPSS_IXR_PTPSRX_MASK 0x00080000 /**< PTP Sync received */
+#define XEMACPSS_IXR_PTPDRRX_MASK 0x00040000 /**< PTP Delay_req received */
+#define XEMACPSS_IXR_PAUSETX_MASK 0x00004000 /**< Pause frame transmitted */
+#define XEMACPSS_IXR_PAUSEZERO_MASK 0x00002000 /**< Pause time has reached
+ zero */
+#define XEMACPSS_IXR_PAUSENZERO_MASK 0x00001000 /**< Pause frame received */
+#define XEMACPSS_IXR_HRESPNOK_MASK 0x00000800 /**< hresp not ok */
+#define XEMACPSS_IXR_RXOVR_MASK 0x00000400 /**< Receive overrun occurred */
+#define XEMACPSS_IXR_TXCOMPL_MASK 0x00000080 /**< Frame transmitted ok */
+#define XEMACPSS_IXR_TXEXH_MASK 0x00000040 /**< Transmit err occurred or
+ no buffers*/
+#define XEMACPSS_IXR_RETRY_MASK 0x00000020 /**< Retry limit exceeded */
+#define XEMACPSS_IXR_URUN_MASK 0x00000010 /**< Transmit underrun */
+#define XEMACPSS_IXR_TXUSED_MASK 0x00000008 /**< Tx buffer used bit read */
+#define XEMACPSS_IXR_RXUSED_MASK 0x00000004 /**< Rx buffer used bit read */
+#define XEMACPSS_IXR_FRAMERX_MASK 0x00000002 /**< Frame received ok */
+#define XEMACPSS_IXR_MGMNT_MASK 0x00000001 /**< PHY management complete */
+#define XEMACPSS_IXR_ALL_MASK 0x00007FFF /**< Everything! */
+
+#define XEMACPSS_IXR_TX_ERR_MASK (XEMACPSS_IXR_TXEXH_MASK | \
+ XEMACPSS_IXR_RETRY_MASK | \
+ XEMACPSS_IXR_URUN_MASK | \
+ XEMACPSS_IXR_TXUSED_MASK)
+
+
+#define XEMACPSS_IXR_RX_ERR_MASK (XEMACPSS_IXR_HRESPNOK_MASK | \
+ XEMACPSS_IXR_RXUSED_MASK | \
+ XEMACPSS_IXR_RXOVR_MASK)
+
+/*@}*/
+
+/** @name PHY Maintenance bit definitions
+ * @{
+ */
+#define XEMACPSS_PHYMNTNC_OP_MASK 0x40020000 /**< operation mask bits */
+#define XEMACPSS_PHYMNTNC_OP_R_MASK 0x20000000 /**< read operation */
+#define XEMACPSS_PHYMNTNC_OP_W_MASK 0x10000000 /**< write operation */
+#define XEMACPSS_PHYMNTNC_ADDR_MASK 0x0F800000 /**< Address bits */
+#define XEMACPSS_PHYMNTNC_REG_MASK 0x007C0000 /**< register bits */
+#define XEMACPSS_PHYMNTNC_DATA_MASK 0x00000FFF /**< data bits */
+#define XEMACPSS_PHYMNTNC_PHYAD_SHIFT_MASK 23 /**< Shift bits for PHYAD */
+#define XEMACPSS_PHYMNTNC_PHREG_SHIFT_MASK 18 /**< Shift bits for PHREG */
+/*@}*/
+
+/* Transmit buffer descriptor status words offset
+ * @{
+ */
+#define XEMACPSS_BD_ADDR_OFFSET 0x00000000 /**< word 0/addr of BDs */
+#define XEMACPSS_BD_STAT_OFFSET 0x00000004 /**< word 1/status of BDs */
+/*@}*/
+
+/* Transmit buffer descriptor status words bit positions.
+ * Transmit buffer descriptor consists of two 32-bit registers,
+ * the first - word0 contains a 32-bit address pointing to the location of
+ * the transmit data.
+ * The following register - word1, consists of various information to control
+ * the XEmacPss transmit process. After transmit, this is updated with status
+ * information, whether the frame was transmitted OK or why it had failed.
+ * @{
+ */
+#define XEMACPSS_TXBUF_USED_MASK 0x80000000 /**< Used bit. */
+#define XEMACPSS_TXBUF_WRAP_MASK 0x40000000 /**< Wrap bit, last descriptor */
+#define XEMACPSS_TXBUF_RETRY_MASK 0x20000000 /**< Retry limit exceeded */
+#define XEMACPSS_TXBUF_URUN_MASK 0x10000000 /**< Transmit underrun occurred */
+#define XEMACPSS_TXBUF_EXH_MASK 0x08000000 /**< Buffers exhausted */
+#define XEMACPSS_TXBUF_TCP_MASK 0x04000000 /**< Late collision. */
+#define XEMACPSS_TXBUF_NOCRC_MASK 0x00010000 /**< No CRC */
+#define XEMACPSS_TXBUF_LAST_MASK 0x00008000 /**< Last buffer */
+#define XEMACPSS_TXBUF_LEN_MASK 0x00003FFF /**< Mask for length field */
+/*@}*/
+
+/* Receive buffer descriptor status words bit positions.
+ * Receive buffer descriptor consists of two 32-bit registers,
+ * the first - word0 contains a 32-bit word aligned address pointing to the
+ * address of the buffer. The lower two bits make up the wrap bit indicating
+ * the last descriptor and the ownership bit to indicate it has been used by
+ * the XEmacPss.
+ * The following register - word1, contains status information regarding why
+ * the frame was received (the filter match condition) as well as other
+ * useful info.
+ * @{
+ */
+#define XEMACPSS_RXBUF_BCAST_MASK 0x80000000 /**< Broadcast frame */
+#define XEMACPSS_RXBUF_MULTIHASH_MASK 0x40000000 /**< Multicast hashed frame */
+#define XEMACPSS_RXBUF_UNIHASH_MASK 0x20000000 /**< Unicast hashed frame */
+#define XEMACPSS_RXBUF_EXH_MASK 0x08000000 /**< buffer exhausted */
+#define XEMACPSS_RXBUF_AMATCH_MASK 0x06000000 /**< Specific address
+ matched */
+#define XEMACPSS_RXBUF_IDFOUND_MASK 0x01000000 /**< Type ID matched */
+#define XEMACPSS_RXBUF_IDMATCH_MASK 0x00C00000 /**< ID matched mask */
+#define XEMACPSS_RXBUF_VLAN_MASK 0x00200000 /**< VLAN tagged */
+#define XEMACPSS_RXBUF_PRI_MASK 0x00100000 /**< Priority tagged */
+#define XEMACPSS_RXBUF_VPRI_MASK 0x000E0000 /**< Vlan priority */
+#define XEMACPSS_RXBUF_CFI_MASK 0x00010000 /**< CFI frame */
+#define XEMACPSS_RXBUF_EOF_MASK 0x00008000 /**< End of frame. */
+#define XEMACPSS_RXBUF_SOF_MASK 0x00004000 /**< Start of frame. */
+#define XEMACPSS_RXBUF_LEN_MASK 0x00003FFF /**< Mask for length field */
+
+#define XEMACPSS_RXBUF_WRAP_MASK 0x00000002 /**< Wrap bit, last BD */
+#define XEMACPSS_RXBUF_NEW_MASK 0x00000001 /**< Used bit.. */
+#define XEMACPSS_RXBUF_ADD_MASK 0xFFFFFFFC /**< Mask for address */
+/*@}*/
+
+/*
+ * Define appropriate I/O access method to mempry mapped I/O or other
+ * intarfce if necessary.
+ */
+/* Defined in xemacpss_control.c*/
+void XIo_Out32(u32 OutAddress, u32 Value);
+u32 XIo_In32(u32 InAddress);
+
+#define XEmacPss_In32 XIo_In32
+#define XEmacPss_Out32 XIo_Out32
+
+
+/****************************************************************************/
+/**
+*
+* Read the given register.
+*
+* @param BaseAddress is the base address of the device
+* @param RegOffset is the register offset to be read
+*
+* @return The 32-bit value of the register
+*
+* @note
+* C-style signature:
+* u32 XEmacPss_ReadReg(u32 BaseAddress, u32 RegOffset)
+*
+*****************************************************************************/
+#define XEmacPss_ReadReg(BaseAddress, RegOffset) \
+ XEmacPss_In32((BaseAddress) + (RegOffset))
+
+
+/****************************************************************************/
+/**
+*
+* Write the given register.
+*
+* @param BaseAddress is the base address of the device
+* @param RegOffset is the register offset to be written
+* @param Data is the 32-bit value to write to the register
+*
+* @return None.
+*
+* @note
+* C-style signature:
+* void XEmacPss_WriteReg(u32 BaseAddress, u32 RegOffset,
+* u32 Data)
+*
+*****************************************************************************/
+#define XEmacPss_WriteReg(BaseAddress, RegOffset, Data) \
+ XEmacPss_Out32((BaseAddress) + (RegOffset), (Data))
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* end of protection macro */
--- /dev/null
+/* $Id: xemacpss_sinit.c,v 1.1.2.1 2009/06/17 16:10:26 wyang Exp $ */
+/******************************************************************************
+*
+* (c) Copyright 2009-2010 Xilinx, Inc. All rights reserved.
+*
+* This file contains confidential and proprietary information of Xilinx, Inc.
+* and is protected under U.S. and international copyright and other
+* intellectual property laws.
+*
+* DISCLAIMER
+* This disclaimer is not a license and does not grant any rights to the
+* materials distributed herewith. Except as otherwise provided in a valid
+* license issued to you by Xilinx, and to the maximum extent permitted by
+* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
+* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
+* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
+* and (2) Xilinx shall not be liable (whether in contract or tort, including
+* negligence, or under any other theory of liability) for any loss or damage
+* of any kind or nature related to, arising under or in connection with these
+* materials, including for any direct, or any indirect, special, incidental,
+* or consequential loss or damage (including loss of data, profits, goodwill,
+* or any type of loss or damage suffered as a result of any action brought by
+* a third party) even if such damage or loss was reasonably foreseeable or
+* Xilinx had been advised of the possibility of the same.
+*
+* CRITICAL APPLICATIONS
+* Xilinx products are not designed or intended to be fail-safe, or for use in
+* any application requiring fail-safe performance, such as life-support or
+* safety devices or systems, Class III medical devices, nuclear facilities,
+* applications related to the deployment of airbags, or any other applications
+* that could lead to death, personal injury, or severe property or
+* environmental damage (individually and collectively, "Critical
+* Applications"). Customer assumes the sole risk and liability of any use of
+* Xilinx products in Critical Applications, subject only to applicable laws
+* and regulations governing limitations on product liability.
+*
+* THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
+* AT ALL TIMES.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xemacpss_sinit.c
+*
+* This file contains lookup method by device ID when success, it returns
+* pointer to config table to be used to initialize the device.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a wsy 06/01/09 New
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+//#include "xparameters.h"
+#include "xemacpss.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+* Lookup the device configuration based on the unique device ID. The table
+* contains the configuration info for each device in the system.
+*
+* @param DeviceId is the unique device ID of the device being looked up.
+*
+* @return
+* A pointer to the configuration table entry corresponding to the given
+* device ID, or NULL if no match is found.
+*
+******************************************************************************/
+XEmacPss_Config *XEmacPss_LookupConfig(u16 DeviceId)
+{
+ extern XEmacPss_Config XEmacPss_ConfigTable[];
+ XEmacPss_Config *CfgPtr = NULL;
+ int i;
+
+ for (i = 0; i < XPAR_XEMACPSS_NUM_INSTANCES; i++) {
+ if (XEmacPss_ConfigTable[i].DeviceId == DeviceId) {
+ CfgPtr = &XEmacPss_ConfigTable[i];
+ break;
+ }
+ }
+
+ return (CfgPtr);
+}
--- /dev/null
+/*
+ */
+
+#include <common.h>
+#include <net.h>
+
+#include "xemacpss_example.h"
+
+/************************ Forward function declaration **********************/
+
+int Xgmac_process_rx(XEmacPss *EmacPssInstancePtr);
+int Xgmac_init_rxq(XEmacPss *EmacPssInstancePtr, void *bd_start, int num_elem);
+int Xgmac_make_rxbuff_mem(XEmacPss *EmacPssInstancePtr, void *rx_buf_start, u32 rx_buffsize);
+int Xgmac_next_rx_buf(XEmacPss *EmacPssInstancePtr);
+int Xgmac_phy_mgmt_idle(XEmacPss *EmacPssInstancePtr);
+
+/*************************** Constant Definitions ***************************/
+
+#define EMACPSS_DEVICE_ID 0
+#define PHY_ADDR 7
+
+#define RXBD_CNT 8 /* Number of RxBDs to use */
+#define TXBD_CNT 8 /* Number of TxBDs to use */
+
+#define phy_spinwait(e) do { while (!Xgmac_phy_mgmt_idle(e)); } while (0)
+
+/*************************** Variable Definitions ***************************/
+
+/*
+ * Aligned memory segments to be used for buffer descriptors
+ */
+
+static XEmacPss_Bd RxBdSpace[RXBD_CNT] __attribute__((aligned (16)));
+/* To have some space between the BDs and Rx buffer. */
+static u32 dummy1;
+static u32 dummy2;
+static XEmacPss_Bd TxBdSpace[TXBD_CNT] __attribute__((aligned (16)));
+static u32 dummy3;
+static char RxBuffer[RXBD_CNT * XEMACPSS_RX_BUF_SIZE];
+static uchar data_buffer[XEMACPSS_RX_BUF_SIZE];
+
+static struct {
+ u8 initialized;
+} ethstate = { 0 };
+
+XEmacPss EmacPssInstance;
+
+/*******************************************************************************************/
+/*
+* Following are the supporting functions to read and write GEM PHY registers.
+*/
+int Xgmac_phy_mgmt_idle(XEmacPss *EmacPssInstancePtr)
+{
+ return ((XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress , XEMACPSS_NWSR_OFFSET)
+ & XEMACPSS_NWSR_MDIOIDLE_MASK)== XEMACPSS_NWSR_MDIOIDLE_MASK);
+}
+
+static u32 phy_rd(XEmacPss* e, u32 a)
+{
+ u16 PhyData;
+ phy_spinwait(e);
+ XEmacPss_PhyRead(e,PHY_ADDR,a,&PhyData);
+ phy_spinwait(e);
+ return PhyData;
+}
+
+static void phy_wr(XEmacPss* e, u32 a, u32 v)
+{
+ phy_spinwait(e);
+ XEmacPss_PhyWrite(e,PHY_ADDR,a,v);
+ phy_spinwait(e);
+}
+
+static void phy_rst(XEmacPss* e)
+{
+ int tmp;
+ puts("Resetting PHY...\n");
+ tmp = phy_rd(e,0);
+ tmp |= 0x8000;
+ phy_wr(e,0,tmp);
+
+ while (phy_rd(e,0) & 0x8000)
+ putc('.');
+ puts("\nPHY reset complete.\n");
+}
+
+/*******************************************************************************************/
+
+#if DEBUG
+void device_regs(int num)
+{
+ int i;
+ if(num & 0x2){
+ printf("***PHY REGISTER DUMP***\n");
+ for (i = 0; i < 32; i++) {
+ printf("\t%2d: 0x%04x",i,phy_rd(&EmacPssInstance,i));
+ if (i % 8 == 7)
+ putc('\n');
+ }
+ }
+ if(num & 0x1){
+ printf("***GEM REGISTER DUMP***\n");
+ for (i = 0; i < 0x040; i += 4) {
+ printf("\t0x%03x: 0x%08lx",i,XEmacPss_ReadReg(EmacPssInstance.Config.BaseAddress,i));
+ if (i % 16 == 12)
+ putc('\n');
+ }
+ }
+}
+#endif
+
+void eth_halt(void)
+{
+ return;
+}
+
+int eth_init(bd_t *bis)
+{
+ int tmp;
+ int Status;
+ XEmacPss_Config *Config;
+ XEmacPss *EmacPssInstancePtr = &EmacPssInstance;
+ XEmacPss_Bd BdTemplate;
+ if (ethstate.initialized) {
+ return 1;
+ }
+
+ ethstate.initialized = 0;
+
+ Config = XEmacPss_LookupConfig(EMACPSS_DEVICE_ID);
+
+ Status = XEmacPss_CfgInitialize(EmacPssInstancePtr, Config, Config->BaseAddress);
+ if (Status != 0) {
+ puts("Error in initialize");
+ return 0;
+ }
+
+ /*
+ * Setup RxBD space.
+ */
+
+ if (Xgmac_init_rxq(EmacPssInstancePtr, &RxBdSpace,RXBD_CNT)) {
+ puts("Xgmac_init_rxq failed!\n");
+ return -1;
+ }
+
+ /*
+ * Create the RxBD ring
+ */
+ tmp = Xgmac_make_rxbuff_mem(EmacPssInstancePtr, &RxBuffer, sizeof(RxBuffer));
+ if (tmp == 0 || tmp == -1) {
+ printf("Xgmac_make_rxbuff_mem failed! (%i)\n",tmp);
+ return -1;
+ }
+
+ /*
+ * Setup TxBD space.
+ */
+
+ XEmacPss_BdClear(&BdTemplate);
+ XEmacPss_BdSetStatus(&BdTemplate, XEMACPSS_TXBUF_USED_MASK);
+
+ /*
+ * Create the TxBD ring
+ */
+ Status = XEmacPss_BdRingCreate(&(XEmacPss_GetTxRing(EmacPssInstancePtr)), (u32) &TxBdSpace,
+ (u32) &TxBdSpace, XEMACPSS_BD_ALIGNMENT, TXBD_CNT);
+ if (Status != 0) {
+ puts("Error setting up TxBD space, BdRingCreate");
+ return 0;
+ }
+
+ Status = XEmacPss_BdRingClone(&(XEmacPss_GetTxRing(EmacPssInstancePtr)),
+ &BdTemplate, XEMACPSS_SEND);
+ if (Status != 0) {
+ puts("Error setting up TxBD space, BdRingClone");
+ return 0;
+ }
+
+ XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,
+ XEMACPSS_TXQBASE_OFFSET,
+ EmacPssInstancePtr->TxBdRing.BaseBdAddr);
+
+
+ /* MAC Setup */
+ /*
+ * Following is the setup for Network Configuration register.
+ * Bit 0: Set for 100 Mbps operation.
+ * Bit 1: Set for Full Duplex mode.
+ * Bit 4: Set to allow Copy all frames.
+ * Bit 17: Set for FCS removal.
+ * Bits 20-18: Set with value binary 010 to divide pclk by 32 (pclk up to 80 MHz)
+ */
+ XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_NWCFG_OFFSET,0x000A0013);
+
+ /*
+ * Following is the setup for DMA Configuration register.
+ * Bits 4-0: To set AHB fixed burst length for DMA data operations -> Set with binary 00100 to use INCR4 AHB bursts.
+ * Bits 9-8: Receiver packet buffer memory size -> Set with binary 11 to Use full configured addressable space (8 Kb).
+ * Bit 10 : Transmitter packet buffer memory size -> Set with binary 1 to Use full configured addressable space (4 Kb).
+ * Bits 23-16 : DMA receive buffer size in AHB system memory -> Set with binary 00011000 to use 1536 byte (1*max length frame/buffer).
+ */
+ XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_DMACR_OFFSET,0x00180704);
+
+ /* Disable all the MAC Interrupts*/
+ XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_IDR_OFFSET,0xFFFFFFFF);
+
+ /*
+ * Following is the setup for Network Control register.
+ * Bit 2: Set to enable Receive operation.
+ * Bit 3: Set to enable Transmitt operation.
+ * Bit 4: Set to enable MDIO operation.
+ */
+ tmp = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_NWCTRL_OFFSET);
+ /*MDIO, Rx and Tx enable */
+ tmp |= XEMACPSS_NWCTRL_MDEN_MASK | XEMACPSS_NWCTRL_RXEN_MASK | XEMACPSS_NWCTRL_TXEN_MASK;
+ XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_NWCTRL_OFFSET,tmp);
+
+
+ /* PHY Setup */
+ /* enable autonegotiation, set 100Mbps, full-duplex, restart aneg */
+ tmp = phy_rd(EmacPssInstancePtr,0);
+ phy_wr(EmacPssInstancePtr,0,0x3300 | (tmp & 0x1F));
+
+ /* "add delay to RGMII rx interface" */
+ phy_wr(EmacPssInstancePtr,20,0xc93);
+
+ /* link speed advertisement for autonegotiation */
+ tmp = phy_rd(EmacPssInstancePtr,4);
+ tmp |= 0xd80; /* enable 100Mbps */
+ tmp &= ~0x60; /* disable 10 Mbps */
+ phy_wr(EmacPssInstancePtr,4,tmp);
+
+ /* *disable* gigabit advertisement */
+ tmp = phy_rd(EmacPssInstancePtr,9);
+ tmp &= ~0x0300;
+ phy_wr(EmacPssInstancePtr,9,tmp);
+
+ phy_rst(EmacPssInstancePtr);
+ puts("\nWaiting for PHY to complete autonegotiation.");
+ while (!(phy_rd(EmacPssInstancePtr,1) & (1 << 5)));
+ puts("\nPHY claims autonegotiation complete...\n");
+
+ puts("GEM link speed is 100Mbps\n");
+
+ ethstate.initialized = 1;
+ return 0;
+}
+
+int eth_send(volatile void *ptr, int len)
+{
+ volatile int Status;
+ XEmacPss_Bd *BdPtr;
+ XEmacPss * EmacPssInstancePtr = &EmacPssInstance;
+ if(!ethstate.initialized){
+ puts("Error GMAC not initialized");
+ return 0;
+ }
+
+ Status = XEmacPss_BdRingAlloc(&(XEmacPss_GetTxRing(&EmacPssInstance)),1, &BdPtr);
+ if (Status != 0) {
+ puts("Error allocating TxBD");
+ return 0;
+ }
+
+ /*
+ * Setup TxBD
+ */
+ XEmacPss_BdSetAddressTx(BdPtr, (u32)ptr);
+ XEmacPss_BdSetLength(BdPtr, len);
+ XEmacPss_BdClearTxUsed(BdPtr);
+ XEmacPss_BdSetLast(BdPtr);
+
+ /*
+ * Enqueue to HW
+ */
+ Status = XEmacPss_BdRingToHw(&(XEmacPss_GetTxRing(&EmacPssInstance)),1, BdPtr);
+ if (Status != 0) {
+ puts("Error committing TxBD to HW");
+ return 0;
+ }
+
+
+ /* Start transmit */
+ XEmacPss_Transmit(EmacPssInstancePtr);
+
+
+ /* Read the status register to know if the packet has been Transmitted.*/
+ Status = XEmacPss_ReadReg(EmacPssInstance.Config.BaseAddress,XEMACPSS_TXSR_OFFSET);
+ if(Status & (XEMACPSS_TXSR_HRESPNOK_MASK | XEMACPSS_TXSR_URUN_MASK | XEMACPSS_TXSR_BUFEXH_MASK))
+ {
+ printf("Something has gone wrong here!? Status is 0x%x.\n",Status);
+ }
+
+ if(Status & XEMACPSS_TXSR_TXCOMPL_MASK)
+ {
+ /*
+ * Now that the frame has been sent, post process our TxBDs.
+ */
+ if (XEmacPss_BdRingFromHwTx(&(XEmacPss_GetTxRing(&EmacPssInstance)),1, &BdPtr) == 0) {
+ puts("TxBDs were not ready for post processing");
+ return 0;
+ }
+
+ /*
+ * Free the TxBD.
+ */
+ Status = XEmacPss_BdRingFree(&(XEmacPss_GetTxRing(&EmacPssInstance)),1, BdPtr);
+ if (Status != 0) {
+ puts("Error freeing up TxBDs");
+ return 0;
+ }
+ }
+ /* Clear Tx status register before leaving .*/
+ XEmacPss_WriteReg(EmacPssInstance.Config.BaseAddress,XEMACPSS_TXSR_OFFSET,Status);
+ return 1;
+
+}
+
+int eth_rx(void)
+{
+ volatile u32 status;
+ XEmacPss *EmacPssInstancePtr = &EmacPssInstance;
+ status = XEmacPss_ReadReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_RXSR_OFFSET);
+ if(status & XEMACPSS_RXSR_FRAMERX_MASK)
+ {
+ if((Xgmac_process_rx(EmacPssInstancePtr)) == (-1) )
+ {
+ return 0;
+ }
+ }
+
+ /* Disabled clearing the status because NetLoop() calls eth_rx() in a tight loop
+ * and if Rx status is cleared it will not receive any pasket after the first pasket.
+ * XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_RXSR_OFFSET,status);
+ */
+ return 1;
+}
+
+/*=============================================================================
+ *
+ * Xgmac_process_rx- process the next incoming packet
+ *
+ * return's 0 if OK, -1 on error
+ */
+int Xgmac_process_rx(XEmacPss *EmacPssInstancePtr)
+{
+
+ uchar * buffer = data_buffer;
+ u32 rx_status, mem_addr;
+ int frame_len;
+ u32 * addr =(u32 *)&EmacPssInstancePtr->RxBdRing.RxBD_start[EmacPssInstancePtr->RxBdRing.RxBD_current];
+
+ rx_status = XEmacPss_BdIsRxSOF(addr);
+
+ /* if not a start of frame, something wrong. So recover and return */
+ if(!rx_status)
+ {
+ return (-1);
+ }
+ rx_status = XEmacPss_BdIsRxEOF(addr);
+
+ if(rx_status)
+ {
+ frame_len = XEmacPss_BdGetLength(addr);
+ if (frame_len == 0)
+ {
+ printf("Hardware reported 0 length frame!\n");
+ return (-1);
+ }
+
+ mem_addr = (u32)(*addr & XEMACPSS_RXBUF_ADD_MASK);
+ if (mem_addr == (u32) NULL)
+ {
+ printf("Error swapping out buffer!\n");
+ return (-1);
+ }
+ memcpy(buffer, (void *)mem_addr, frame_len);
+ Xgmac_next_rx_buf(EmacPssInstancePtr);
+ NetReceive(buffer,frame_len);
+ return (0);
+ }
+ else
+ {
+ /* this is wrong ! should never be here is things are OK */
+ printf("Something is wrong we should not be here for last buffer received!\n");
+ return (-1);
+ }
+ return 0;
+}
+
+
+int Xgmac_init_rxq(XEmacPss *EmacPssInstancePtr, void *bd_start, int num_elem)
+{
+ int loop=0;
+
+ if ((num_elem <= 0) || (num_elem > RXBD_CNT) )
+ {
+ return (-1);
+ }
+ else
+ {
+ for (;loop < 2*(num_elem);)
+ {
+ *( ((u32 *) bd_start) + loop ) = 0x00000000;
+ *( ((u32 *) bd_start) + loop + 1) = 0xF0000000;
+ loop += 2;
+ }
+ EmacPssInstancePtr->RxBdRing.RxBD_start = (XEmacPss_Bd *) bd_start;
+ EmacPssInstancePtr->RxBdRing.Length = num_elem;
+ EmacPssInstancePtr->RxBdRing.RxBD_current = 0;
+ EmacPssInstancePtr->RxBdRing.RxBD_end = 0;
+ EmacPssInstancePtr->RxBdRing.Rx_first_buf =0;
+
+ XEmacPss_WriteReg(EmacPssInstancePtr->Config.BaseAddress,XEMACPSS_RXQBASE_OFFSET,(u32)bd_start);
+
+ return 0;
+ }
+}
+
+int Xgmac_make_rxbuff_mem(XEmacPss *EmacPssInstancePtr, void *rx_buf_start, u32 rx_buffsize)
+{
+ int num_bufs;
+ int assigned_bufs;
+ int i;
+ u32 * addr;
+ if((EmacPssInstancePtr == NULL) || (rx_buf_start == NULL) )
+ {
+ return (-1);
+ }
+ else
+ {
+ assigned_bufs = 0;
+
+ if ( (num_bufs = rx_buffsize/XEMACPSS_RX_BUF_SIZE) == 0 )
+ {
+ return 0;
+ }
+ for(i=0;i<num_bufs;i++)
+ {
+ if (EmacPssInstancePtr->RxBdRing.RxBD_end < EmacPssInstancePtr->RxBdRing.Length)
+ {
+ memset((char *)(rx_buf_start + (i*XEMACPSS_RX_BUF_SIZE)),0,XEMACPSS_RX_BUF_SIZE);
+
+ addr = (u32 *)&EmacPssInstancePtr->RxBdRing.RxBD_start[EmacPssInstancePtr->RxBdRing.RxBD_end];
+
+ XEmacPss_BdSetAddressRx(addr,(u32)(((char *)rx_buf_start) + (i*XEMACPSS_RX_BUF_SIZE)));
+
+ EmacPssInstancePtr->RxBdRing.RxBD_end++;
+ assigned_bufs++;
+ }
+ else
+ {
+ return assigned_bufs;
+ }
+ }
+ addr = (u32 *)&EmacPssInstancePtr->RxBdRing.RxBD_start[EmacPssInstancePtr->RxBdRing.RxBD_end-1];
+ XEmacPss_BdSetRxWrap(addr);
+ return assigned_bufs;
+ }
+}
+
+int Xgmac_next_rx_buf(XEmacPss *EmacPssInstancePtr)
+{
+ u32 prev_stat = 0;
+ u32 * addr = NULL ;
+ if (EmacPssInstancePtr != NULL)
+ {
+ addr = (u32 *)&EmacPssInstancePtr->RxBdRing.RxBD_start[EmacPssInstancePtr->RxBdRing.RxBD_current];
+ prev_stat = XEmacPss_BdIsRxSOF(addr);
+
+ if(prev_stat)
+ {
+ EmacPssInstancePtr->RxBdRing.Rx_first_buf = EmacPssInstancePtr->RxBdRing.RxBD_current;
+ }
+ else
+ {
+ XEmacPss_BdClearRxNew(addr);
+ XIo_Out32((u32)(addr+1),0xF0000000);
+ }
+
+ if(XEmacPss_BdIsRxEOF(addr))
+ {
+ addr = (u32 *)&EmacPssInstancePtr->RxBdRing.RxBD_start[EmacPssInstancePtr->RxBdRing.Rx_first_buf];
+ XEmacPss_BdClearRxNew(addr);
+ XIo_Out32((u32)(addr+1),0xF0000000);
+ }
+
+ if((++EmacPssInstancePtr->RxBdRing.RxBD_current) > EmacPssInstancePtr->RxBdRing.Length -1)
+ {
+ EmacPssInstancePtr->RxBdRing.RxBD_current = 0;
+ }
+
+ return 0;
+ }
+ else
+ {
+ printf("\ngem_clr_rx_buf with EmacPssInstancePtr as !!NULL!! \n");
+ return -1;
+ }
+}
--- /dev/null
+/*
+ * Harvested from Cadence driver.
+ */
+
+#ifndef __XDFETH_H__
+#define __XDFETH_H__
+
+#define XDFETH_RX_BUF_SIZE 128
+
+#define XDFETH_RBQ_LENGTH 128
+#define XDFETH_TBQ_LENGTH 128
+
+#define XDFETH_MDIO_ENABLED (GEM_MDIO_EN)
+
+#define XDFETH_DEF_PCLK_DIV (MDC_DIV_32)
+
+#define XDFETH_DEF_AHB_WIDTH (AMBA_AHB_32)
+
+#define XDFETH_DEF_DUPLEX (GEM_FULL_DUPLEX)
+
+#define XDFETH_DEF_SPEED (SPEED_100M)
+
+#define XDFETH_DEF_LOOP (LB_NONE)
+
+#define XDFETH_READ_SNAP (1<<14) /* Read snapshot register */
+#define XDFETH_TAKE_SNAP (1<<13) /* Take a snapshot */
+#define XDFETH_TX_0Q_PAUSE (1<<12) /* Transmit zero quantum pause frame */
+#define XDFETH_TX_PAUSE (1<<11) /* Transmit pause frame */
+#define XDFETH_TX_HALT (1<<10) /* Halt transmission after curr frame */
+#define XDFETH_TX_START (1<<9) /* Start tx (tx_go) */
+#define XDFETH_STATS_WR_EN (1<<7) /* Enable writing to stat registers */
+#define XDFETH_STATS_INC (1<<6) /* Increment statistic registers */
+#define XDFETH_STATS_CLR (1<<5) /* Clear statistic registers */
+#define XDFETH_MDIO_EN (1<<4) /* Enable MDIO port */
+#define XDFETH_TX_EN (1<<3) /* Enable transmit circuits */
+#define XDFETH_RX_EN (1<<2) /* Enable receive circuits */
+#define XDFETH_LB_MAC (1<<1) /* Perform local loopback at MAC */
+#define XDFETH_LB_PHY (1<<0) /* Perform ext loopback through PHY */
+
+#define XDFETH_RX_NO_PAUSE (1<<23) /* Do not copy pause frames to memory */
+#define XDFETH_AHB_WIDTH1 (1<<22) /* Bit 1 for defining AHB width */
+#define XDFETH_AHB_WIDTH0 (1<<21) /* Bit 0 for defining AHB width */
+#define XDFETH_MDC_DIV2 (1<<20) /* PCLK divisor for MDC, bit 2 */
+#define XDFETH_MDC_DIV1 (1<<19) /* PCLK divisor for MDC, bit 1 */
+#define XDFETH_MDC_DIV0 (1<<18) /* PCLK divisor for MDC, bit 0 */
+#define XDFETH_RX_NO_FCS (1<<17) /* Discard FCS from received frames. */
+#define XDFETH_RX_LEN_CHK (1<<16) /* Receive length check. */
+#define XDFETH_RX_OFFSET_BASE 14 /* Pos of LSB for rx buffer offsets. */
+#define XDFETH_RX_OFFSET1 (1<<(GEM_RX_OFFSET_BASE + 1)) /* RX offset bit 1 */
+#define XDFETH_RX_OFFSET0 (1<<GEM_RX_OFFSET_BASE) /* RX offset bit 0 */
+#define XDFETH_RX_PAUSE_EN (1<<13) /* Enable pause reception */
+#define XDFETH_RETRY_TEST (1<<12) /* Retry test for speeding up debug */
+#define XDFETH_PCS_SEL (1<<11) /* Select PCS */
+#define XDFETH_GIG_MODE (1<<10) /* Gigabit mode enable */
+#define XDFETH_EAM_EN (1<<9) /* External address match enable */
+#define XDFETH_FRAME_1536 (1<<8) /* Enable 1536 byte frames reception */
+#define XDFETH_UNICAST_EN (1<<7) /* Receive unicast hash frames */
+#define XDFETH_MULTICAST_EN (1<<6) /* Receive multicast hash frames */
+#define XDFETH_NO_BROADCAST (1<<5) /* Do not receive broadcast frames */
+#define XDFETH_COPY_ALL (1<<4) /* Copy all frames */
+#define XDFETH_RX_JUMBO (1<<3) /* Allow jumbo frame reception */
+#define XDFETH_VLAN_ONLY (1<<2) /* Receive only VLAN frames */
+#define XDFETH_FULL_DUPLEX (1<<1) /* Enable full duplex */
+#define XDFETH_SPEED_100 (1<<0) /* Set to 100Mb mode */
+
+#define XDFETH_PHY_IDLE (1<<2) /* PHY management is idle */
+#define XDFETH_MDIO_IN (1<<1) /* Status of mdio_in pin */
+#define XDFETH_LINK_STATUS (1<<0) /* Status of link pin */
+
+#define XDFETH_TX_HRESP (1<<8) /* Transmit hresp not OK */
+#define XDFETH_LATE_COL (1<<7) /* Late collision */
+#define XDFETH_TX_URUN (1<<6) /* Transmit underrun occurred */
+#define XDFETH_TX_COMPLETE (1<<5) /* Transmit completed OK */
+#define XDFETH_TX_BUF_EXH (1<<4) /* Transmit buffs exhausted mid frame */
+#define XDFETH_TX_GO (1<<3) /* Status of tx_go internal variable */
+#define XDFETH_TX_RETRY_EXC (1<<2) /* Retry limit exceeded */
+#define XDFETH_TX_COL (1<<1) /* Collision occurred during frame tx */
+#define XDFETH_TX_USED (1<<0) /* Used bit read in tx buffer */
+
+#define XDFETH_RX_HRESP (1<<3) /* Receive hresp not OK */
+#define XDFETH_RX_ORUN (1<<2) /* Receive overrun occurred */
+#define XDFETH_RX_DONE (1<<1) /* Frame successfully received */
+#define XDFETH_RX_BUF_USED (1<<0) /* Receive buffer used bit read */
+
+#define XDFETH_IRQ_PCS_AN (1<<16) /* PCS autonegotiation complete */
+#define XDFETH_IRQ_EXT_INT (1<<15) /* External interrupt pin triggered */
+#define XDFETH_IRQ_PAUSE_TX (1<<14) /* Pause frame transmitted */
+#define XDFETH_IRQ_PAUSE_0 (1<<13) /* Pause time has reached zero */
+#define XDFETH_IRQ_PAUSE_RX (1<<12) /* Pause frame received */
+#define XDFETH_IRQ_HRESP (1<<11) /* hresp not ok */
+#define XDFETH_IRQ_RX_ORUN (1<<10) /* Receive overrun occurred */
+#define XDFETH_IRQ_PCS_LINK (1<<9) /* Status of PCS link changed */
+#define XDFETH_IRQ_TX_DONE (1<<7) /* Frame transmitted ok */
+#define XDFETH_IRQ_TX_ERROR (1<<6) /* Transmit err occurred or no buffers*/
+#define XDFETH_IRQ_RETRY_EXC (1<<5) /* Retry limit exceeded */
+#define XDFETH_IRQ_TX_URUN (1<<4) /* Transmit underrun occurred */
+#define XDFETH_IRQ_TX_USED (1<<3) /* Tx buffer used bit read */
+#define XDFETH_IRQ_RX_USED (1<<2) /* Rx buffer used bit read */
+#define XDFETH_IRQ_RX_DONE (1<<1) /* Frame received ok */
+#define XDFETH_IRQ_MAN_DONE (1<<0) /* PHY management operation complete */
+#define XDFETH_IRQ_ALL (0xFFFFFFFF)/* Everything! */
+
+#define XDFETH_TBQE_USED (1<<31) /* Used bit. */
+#define XDFETH_TBQE_WRAP (1<<30) /* Wrap bit */
+#define XDFETH_TBQE_RETRY_EXC (1<<29) /* Retry limit exceeded. */
+#define XDFETH_TBQE_URUN (1<<28) /* Transmit underrun occurred. */
+#define XDFETH_TBQE_BUF_EXH (1<<27) /* Buffers exhausted mid frame. */
+#define XDFETH_TBQE_LATE_COL (1<<26) /* Late collision. */
+#define XDFETH_TBQE_NO_CRC (1<<16) /* No CRC */
+#define XDFETH_TBQE_LAST_BUF (1<<15) /* Last buffer */
+#define XDFETH_TBQE_LEN_MASK (0x3FFF) /* Mask for length field */
+#define XDFETH_TX_MAX_LEN (0x3FFF) /* Maximum transmit length value */
+#define XDFETH_TBQE_DUMMY (0x8000BFFF)/* Dummy value to check for free buffer*/
+
+#define XDFETH_RBQE_BROADCAST (1<<31) /* Broadcast frame */
+#define XDFETH_RBQE_MULTICAST (1<<30) /* Multicast hashed frame */
+#define XDFETH_RBQE_UNICAST (1<<29) /* Unicast hashed frame */
+#define XDFETH_RBQE_EXT_ADDR (1<<28) /* External address match */
+#define XDFETH_RBQE_SPEC_MATCH (1<<27) /* Specific address matched */
+#define XDFETH_RBQE_SPEC_BASE (25) /* Pos for base of specific match */
+#define XDFETH_RBQE_SPEC_MAT1 (1<<(RBQE_SPEC_BASE + 1))
+#define XDFETH_RBQE_SPEC_MAT0 (1<<RBQE_SPEC_BASE)
+#define XDFETH_RBQE_TYPE_MATCH (1<<24) /* Type ID matched */
+#define XDFETH_RBQE_TYPE_BASE (22) /* Position for base of type id match */
+#define XDFETH_RBQE_TYPE_MAT1 (1<<(RBQE_TYPE_BASE + 1))
+#define XDFETH_RBQE_TYPE_MAT0 (1<<RBQE_TYPE_BASE)
+#define XDFETH_RBQE_VLAN (1<<21) /* VLAN tagged */
+#define XDFETH_RBQE_PRIORITY (1<<20) /* Priority tagged */
+#define XDFETH_RBQE_VLAN_BASE (17) /* Position for base of VLAN priority */
+#define XDFETH_RBQE_VLAN_P2 (1<<(RBQE_VLAN_BASE+2))
+#define XDFETH_RBQE_VLAN_P1 (1<<(RBQE_VLAN_BASE+1))
+#define XDFETH_RBQE_VLAN_P0 (1<<RBQE_VLAN_BASE)
+#define XDFETH_RBQE_CFI (1<<16) /* CFI frame */
+#define XDFETH_RBQE_EOF (1<<15) /* End of frame. */
+#define XDFETH_RBQE_SOF (1<<14) /* Start of frame. */
+#define XDFETH_RBQE_LEN_MASK (0x3FFF) /* Mask for the length field. */
+#define XDFETH_RBQE_WRAP (1<<1) /* Wrap bit.. */
+#define XDFETH_RBQE_USED (1<<0) /* Used bit.. */
+#define XDFETH_RBQE_ADD_MASK (0xFFFFFFFC)/* Mask for address */
+
+#define XDFETH_REV_ID_MODEL_MASK (0x000F0000) /* Model ID */
+#define XDFETH_REV_ID_MODEL_BASE (16) /* For Shifting */
+#define XDFETH_REV_ID_REG_MODEL (0x00020000) /* GEM module ID */
+#define XDFETH_REV_ID_REV_MASK (0x0000FFFF) /* Revision ID */
+
+#define XDFETH_NET_CONTROL (0x00)
+#define XDFETH_NET_CONFIG (0x04)
+#define XDFETH_NET_STATUS (0x08)
+#define XDFETH_USER_IO (0x0C)
+#define XDFETH_TX_STATUS (0x14)
+#define XDFETH_RX_QPTR (0x18)
+#define XDFETH_TX_QPTR (0x1C)
+#define XDFETH_RX_STATUS (0x20)
+#define XDFETH_IRQ_STATUS (0x24)
+#define XDFETH_IRQ_ENABLE (0x28)
+#define XDFETH_IRQ_DISABLE (0x2C)
+#define XDFETH_IRQ_MASK (0x30)
+#define XDFETH_PHY_MAN (0x34)
+#define XDFETH_RX_PAUSE_TIME (0x38)
+#define XDFETH_TX_PAUSE_QUANT (0x3C)
+
+#define XDFETH_HASH_BOT (0x80)
+#define XDFETH_HASH_TOP (0x84)
+#define XDFETH_LADDR1_BOT (0x88)
+#define XDFETH_LADDR1_TOP (0x8C)
+#define XDFETH_LADDR2_BOT (0x90)
+#define XDFETH_LADDR2_TOP (0x94)
+#define XDFETH_LADDR3_BOT (0x98)
+#define XDFETH_LADDR3_TOP (0x9C)
+#define XDFETH_LADDR4_BOT (0xA0)
+#define XDFETH_LADDR4_TOP (0xA4)
+#define XDFETH_ID_CHECK1 (0xA8)
+#define XDFETH_ID_CHECK2 (0xAC)
+#define XDFETH_ID_CHECK3 (0xB0)
+#define XDFETH_ID_CHECK4 (0xB4)
+#define XDFETH_REV_ID (0xFC)
+
+#define XDFETH_OCT_TX_BOT (0x100)
+#define XDFETH_OCT_TX_TOP (0x104)
+#define XDFETH_STATS_FRAMES_TX (0x108)
+#define XDFETH_BROADCAST_TX (0x10C)
+#define XDFETH_MULTICAST_TX (0x110)
+#define XDFETH_STATS_PAUSE_TX (0x114)
+#define XDFETH_FRAME64_TX (0x118)
+#define XDFETH_FRAME65_TX (0x11C)
+#define XDFETH_FRAME128_TX (0x120)
+#define XDFETH_FRAME256_TX (0x124)
+#define XDFETH_FRAME512_TX (0x128)
+#define XDFETH_FRAME1024_TX (0x12C)
+#define XDFETH_FRAME1519_TX (0x130)
+#define XDFETH_STATS_TX_URUN (0x134)
+#define XDFETH_STATS_SINGLE_COL (0x138)
+#define XDFETH_STATS_MULTI_COL (0x13C)
+#define XDFETH_STATS_EXCESS_COL (0x140)
+#define XDFETH_STATS_LATE_COL (0x144)
+#define XDFETH_STATS_DEF_TX (0x148)
+#define XDFETH_STATS_CRS_ERRORS (0x14C)
+#define XDFETH_OCT_RX_BOT (0x150)
+#define XDFETH_OCT_RX_TOP (0x154)
+#define XDFETH_STATS_FRAMES_RX (0x158)
+#define XDFETH_BROADCAST_RX (0x15C)
+#define XDFETH_MULTICAST_RX (0x160)
+#define XDFETH_STATS_PAUSE_RX (0x164)
+#define XDFETH_FRAME64_RX (0x168)
+#define XDFETH_FRAME65_RX (0x16C)
+#define XDFETH_FRAME128_RX (0x170)
+#define XDFETH_FRAME256_RX (0x174)
+#define XDFETH_FRAME512_RX (0x178)
+#define XDFETH_FRAME1024_RX (0x17C)
+#define XDFETH_FRAME1519_RX (0x180)
+#define XDFETH_STATS_USIZE_FRAMES (0x184)
+#define XDFETH_STATS_EXCESS_LEN (0x188)
+#define XDFETH_STATS_JABBERS (0x18C)
+#define XDFETH_STATS_FCS_ERRORS (0x190)
+#define XDFETH_STATS_LENGTH_ERRORS (0x194)
+#define XDFETH_STATS_RX_SYM_ERR (0x198)
+#define XDFETH_STATS_ALIGN_ERRORS (0x19C)
+#define XDFETH_STATS_RX_RES_ERR (0x1a0)
+#define XDFETH_STATS_RX_ORUN (0x1a4)
+
+#define XDFETH_REG_TOP (0x23C)
+
+#define gem_get_tbq_end(mac) ((mac)->tbq_end)
+#define gem_get_tbq_current(mac) ((mac)->tbq_current)
+
+#define gem_get_rbq_end(mac) ((mac)->rbq_end)
+#define gem_get_rbq_current(mac) ((mac)->rbq_current)
+
+#define gem_check_free_tbq_buf(mac) \
+
+#define gem_check_a_free_tbq_buf(mac, index) \
+
+#define gem_get_free_tbq_num(mac, free_tbq_num) \
+
--- /dev/null
+/* $Id: xstatus.h,v 1.1.2.1 2009/05/19 14:56:56 meinelte Exp $ */
+/******************************************************************************
+*
+* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+* AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+* SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
+* OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+* APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+* THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
+* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE.
+*
+* (c) Copyright 2002-2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xstatus.h
+*
+* This file contains Xilinx software status codes. Status codes have their
+* own data type called int. These codes are used throughout the Xilinx
+* device drivers.
+*
+******************************************************************************/
+
+#ifndef XSTATUS_H /* prevent circular inclusions */
+#define XSTATUS_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+/*********************** Common statuses 0 - 500 *****************************/
+
+#define XST_SUCCESS 0L
+#define XST_FAILURE 1L
+#define XST_DEVICE_NOT_FOUND 2L
+#define XST_DEVICE_BLOCK_NOT_FOUND 3L
+#define XST_INVALID_VERSION 4L
+#define XST_DEVICE_IS_STARTED 5L
+#define XST_DEVICE_IS_STOPPED 6L
+#define XST_FIFO_ERROR 7L /* an error occurred during an
+ operation with a FIFO such as
+ an underrun or overrun, this
+ error requires the device to
+ be reset */
+#define XST_RESET_ERROR 8L /* an error occurred which requires
+ the device to be reset */
+#define XST_DMA_ERROR 9L /* a DMA error occurred, this error
+ typically requires the device
+ using the DMA to be reset */
+#define XST_NOT_POLLED 10L /* the device is not configured for
+ polled mode operation */
+#define XST_FIFO_NO_ROOM 11L /* a FIFO did not have room to put
+ the specified data into */
+#define XST_BUFFER_TOO_SMALL 12L /* the buffer is not large enough
+ to hold the expected data */
+#define XST_NO_DATA 13L /* there was no data available */
+#define XST_REGISTER_ERROR 14L /* a register did not contain the
+ expected value */
+#define XST_INVALID_PARAM 15L /* an invalid parameter was passed
+ into the function */
+#define XST_NOT_SGDMA 16L /* the device is not configured for
+ scatter-gather DMA operation */
+#define XST_LOOPBACK_ERROR 17L /* a loopback test failed */
+#define XST_NO_CALLBACK 18L /* a callback has not yet been
+ registered */
+#define XST_NO_FEATURE 19L /* device is not configured with
+ the requested feature */
+#define XST_NOT_INTERRUPT 20L /* device is not configured for
+ interrupt mode operation */
+#define XST_DEVICE_BUSY 21L /* device is busy */
+#define XST_ERROR_COUNT_MAX 22L /* the error counters of a device
+ have maxed out */
+#define XST_IS_STARTED 23L /* used when part of device is
+ already started i.e.
+ sub channel */
+#define XST_IS_STOPPED 24L /* used when part of device is
+ already stopped i.e.
+ sub channel */
+#define XST_DATA_LOST 26L /* driver defined error */
+#define XST_RECV_ERROR 27L /* generic receive error */
+#define XST_SEND_ERROR 28L /* generic transmit error */
+#define XST_NOT_ENABLED 29L /* a requested service is not
+ available because it has not
+ been enabled */
+
+/***************** Utility Component statuses 401 - 500 *********************/
+
+#define XST_MEMTEST_FAILED 401L /* memory test failed */
+
+
+/***************** Common Components statuses 501 - 1000 *********************/
+
+/********************* Packet Fifo statuses 501 - 510 ************************/
+
+#define XST_PFIFO_LACK_OF_DATA 501L /* not enough data in FIFO */
+#define XST_PFIFO_NO_ROOM 502L /* not enough room in FIFO */
+#define XST_PFIFO_BAD_REG_VALUE 503L /* self test, a register value
+ was invalid after reset */
+#define XST_PFIFO_ERROR 504L /* generic packet FIFO error */
+#define XST_PFIFO_DEADLOCK 505L /* packet FIFO is reporting
+ * empty and full simultaneously
+ */
+
+/************************** DMA statuses 511 - 530 ***************************/
+
+#define XST_DMA_TRANSFER_ERROR 511L /* self test, DMA transfer
+ failed */
+#define XST_DMA_RESET_REGISTER_ERROR 512L /* self test, a register value
+ was invalid after reset */
+#define XST_DMA_SG_LIST_EMPTY 513L /* scatter gather list contains
+ no buffer descriptors ready
+ to be processed */
+#define XST_DMA_SG_IS_STARTED 514L /* scatter gather not stopped */
+#define XST_DMA_SG_IS_STOPPED 515L /* scatter gather not running */
+#define XST_DMA_SG_LIST_FULL 517L /* all the buffer desciptors of
+ the scatter gather list are
+ being used */
+#define XST_DMA_SG_BD_LOCKED 518L /* the scatter gather buffer
+ descriptor which is to be
+ copied over in the scatter
+ list is locked */
+#define XST_DMA_SG_NOTHING_TO_COMMIT 519L /* no buffer descriptors have been
+ put into the scatter gather
+ list to be commited */
+#define XST_DMA_SG_COUNT_EXCEEDED 521L /* the packet count threshold
+ specified was larger than the
+ total # of buffer descriptors
+ in the scatter gather list */
+#define XST_DMA_SG_LIST_EXISTS 522L /* the scatter gather list has
+ already been created */
+#define XST_DMA_SG_NO_LIST 523L /* no scatter gather list has
+ been created */
+#define XST_DMA_SG_BD_NOT_COMMITTED 524L /* the buffer descriptor which was
+ being started was not committed
+ to the list */
+#define XST_DMA_SG_NO_DATA 525L /* the buffer descriptor to start
+ has already been used by the
+ hardware so it can't be reused
+ */
+#define XST_DMA_SG_LIST_ERROR 526L /* general purpose list access
+ error */
+#define XST_DMA_BD_ERROR 527L /* general buffer descriptor
+ error */
+
+/************************** IPIF statuses 531 - 550 ***************************/
+
+#define XST_IPIF_REG_WIDTH_ERROR 531L /* an invalid register width
+ was passed into the function */
+#define XST_IPIF_RESET_REGISTER_ERROR 532L /* the value of a register at
+ reset was not valid */
+#define XST_IPIF_DEVICE_STATUS_ERROR 533L /* a write to the device interrupt
+ status register did not read
+ back correctly */
+#define XST_IPIF_DEVICE_ACK_ERROR 534L /* the device interrupt status
+ register did not reset when
+ acked */
+#define XST_IPIF_DEVICE_ENABLE_ERROR 535L /* the device interrupt enable
+ register was not updated when
+ other registers changed */
+#define XST_IPIF_IP_STATUS_ERROR 536L /* a write to the IP interrupt
+ status register did not read
+ back correctly */
+#define XST_IPIF_IP_ACK_ERROR 537L /* the IP interrupt status register
+ did not reset when acked */
+#define XST_IPIF_IP_ENABLE_ERROR 538L /* IP interrupt enable register was
+ not updated correctly when other
+ registers changed */
+#define XST_IPIF_DEVICE_PENDING_ERROR 539L /* The device interrupt pending
+ register did not indicate the
+ expected value */
+#define XST_IPIF_DEVICE_ID_ERROR 540L /* The device interrupt ID register
+ did not indicate the expected
+ value */
+#define XST_IPIF_ERROR 541L /* generic ipif error */
+
+/****************** Device specific statuses 1001 - 4095 *********************/
+
+/********************* Ethernet statuses 1001 - 1050 *************************/
+
+#define XST_EMAC_MEMORY_SIZE_ERROR 1001L /* Memory space is not big enough
+ * to hold the minimum number of
+ * buffers or descriptors */
+#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L /* Memory allocation failed */
+#define XST_EMAC_MII_READ_ERROR 1003L /* MII read error */
+#define XST_EMAC_MII_BUSY 1004L /* An MII operation is in progress */
+#define XST_EMAC_OUT_OF_BUFFERS 1005L /* Driver is out of buffers */
+#define XST_EMAC_PARSE_ERROR 1006L /* Invalid driver init string */
+#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late
+ * collision on polled send */
+
+/*********************** UART statuses 1051 - 1075 ***************************/
+#define XST_UART
+
+#define XST_UART_INIT_ERROR 1051L
+#define XST_UART_START_ERROR 1052L
+#define XST_UART_CONFIG_ERROR 1053L
+#define XST_UART_TEST_FAIL 1054L
+#define XST_UART_BAUD_ERROR 1055L
+#define XST_UART_BAUD_RANGE 1056L
+
+
+/************************ IIC statuses 1076 - 1100 ***************************/
+
+#define XST_IIC_SELFTEST_FAILED 1076 /* self test failed */
+#define XST_IIC_BUS_BUSY 1077 /* bus found busy */
+#define XST_IIC_GENERAL_CALL_ADDRESS 1078 /* mastersend attempted with */
+ /* general call address */
+#define XST_IIC_STAND_REG_RESET_ERROR 1079 /* A non parameterizable reg */
+ /* value after reset not valid */
+#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080 /* Tx fifo included in design */
+ /* value after reset not valid */
+#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081 /* Rx fifo included in design */
+ /* value after reset not valid */
+#define XST_IIC_TBA_REG_RESET_ERROR 1082 /* 10 bit addr incl in design */
+ /* value after reset not valid */
+#define XST_IIC_CR_READBACK_ERROR 1083 /* Read of the control register */
+ /* didn't return value written */
+#define XST_IIC_DTR_READBACK_ERROR 1084 /* Read of the data Tx reg */
+ /* didn't return value written */
+#define XST_IIC_DRR_READBACK_ERROR 1085 /* Read of the data Receive reg */
+ /* didn't return value written */
+#define XST_IIC_ADR_READBACK_ERROR 1086 /* Read of the data Tx reg */
+ /* didn't return value written */
+#define XST_IIC_TBA_READBACK_ERROR 1087 /* Read of the 10 bit addr reg */
+ /* didn't return written value */
+#define XST_IIC_NOT_SLAVE 1088 /* The device isn't a slave */
+
+/*********************** ATMC statuses 1101 - 1125 ***************************/
+
+#define XST_ATMC_ERROR_COUNT_MAX 1101L /* the error counters in the ATM
+ controller hit the max value
+ which requires the statistics
+ to be cleared */
+
+/*********************** Flash statuses 1126 - 1150 **************************/
+
+#define XST_FLASH_BUSY 1126L /* Flash is erasing or programming
+ */
+#define XST_FLASH_READY 1127L /* Flash is ready for commands */
+#define XST_FLASH_ERROR 1128L /* Flash had detected an internal
+ error. Use XFlash_DeviceControl
+ to retrieve device specific codes
+ */
+#define XST_FLASH_ERASE_SUSPENDED 1129L /* Flash is in suspended erase state
+ */
+#define XST_FLASH_WRITE_SUSPENDED 1130L /* Flash is in suspended write state
+ */
+#define XST_FLASH_PART_NOT_SUPPORTED 1131L /* Flash type not supported by
+ driver */
+#define XST_FLASH_NOT_SUPPORTED 1132L /* Operation not supported */
+#define XST_FLASH_TOO_MANY_REGIONS 1133L /* Too many erase regions */
+#define XST_FLASH_TIMEOUT_ERROR 1134L /* Programming or erase operation
+ aborted due to a timeout */
+#define XST_FLASH_ADDRESS_ERROR 1135L /* Accessed flash outside its
+ addressible range */
+#define XST_FLASH_ALIGNMENT_ERROR 1136L /* Write alignment error */
+#define XST_FLASH_BLOCKING_CALL_ERROR 1137L /* Couldn't return immediately from
+ write/erase function with
+ XFL_NON_BLOCKING_WRITE/ERASE
+ option cleared */
+#define XST_FLASH_CFI_QUERY_ERROR 1138L /* Failed to query the device */
+
+/*********************** SPI statuses 1151 - 1175 ****************************/
+
+#define XST_SPI_MODE_FAULT 1151 /* master was selected as slave */
+#define XST_SPI_TRANSFER_DONE 1152 /* data transfer is complete */
+#define XST_SPI_TRANSMIT_UNDERRUN 1153 /* slave underruns transmit register */
+#define XST_SPI_RECEIVE_OVERRUN 1154 /* device overruns receive register */
+#define XST_SPI_NO_SLAVE 1155 /* no slave has been selected yet */
+#define XST_SPI_TOO_MANY_SLAVES 1156 /* more than one slave is being
+ * selected */
+#define XST_SPI_NOT_MASTER 1157 /* operation is valid only as master */
+#define XST_SPI_SLAVE_ONLY 1158 /* device is configured as slave-only
+ */
+#define XST_SPI_SLAVE_MODE_FAULT 1159 /* slave was selected while disabled */
+
+/********************** OPB Arbiter statuses 1176 - 1200 *********************/
+
+#define XST_OPBARB_INVALID_PRIORITY 1176 /* the priority registers have either
+ * one master assigned to two or more
+ * priorities, or one master not
+ * assigned to any priority
+ */
+#define XST_OPBARB_NOT_SUSPENDED 1177 /* an attempt was made to modify the
+ * priority levels without first
+ * suspending the use of priority
+ * levels
+ */
+#define XST_OPBARB_PARK_NOT_ENABLED 1178 /* bus parking by id was enabled but
+ * bus parking was not enabled
+ */
+#define XST_OPBARB_NOT_FIXED_PRIORITY 1179 /* the arbiter must be in fixed
+ * priority mode to allow the
+ * priorities to be changed
+ */
+
+/************************ Intc statuses 1201 - 1225 **************************/
+
+#define XST_INTC_FAIL_SELFTEST 1201 /* self test failed */
+#define XST_INTC_CONNECT_ERROR 1202 /* interrupt already in use */
+
+/********************** TmrCtr statuses 1226 - 1250 **************************/
+
+#define XST_TMRCTR_TIMER_FAILED 1226 /* self test failed */
+
+/********************** WdtTb statuses 1251 - 1275 ***************************/
+
+#define XST_WDTTB_TIMER_FAILED 1251L
+
+/********************** PlbArb statuses 1276 - 1300 **************************/
+
+#define XST_PLBARB_FAIL_SELFTEST 1276L
+
+/********************** Plb2Opb statuses 1301 - 1325 *************************/
+
+#define XST_PLB2OPB_FAIL_SELFTEST 1301L
+
+/********************** Opb2Plb statuses 1326 - 1350 *************************/
+
+#define XST_OPB2PLB_FAIL_SELFTEST 1326L
+
+/********************** SysAce statuses 1351 - 1360 **************************/
+
+#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted */
+
+/********************** PCI Bridge statuses 1361 - 1375 **********************/
+
+#define XST_PCI_INVALID_ADDRESS 1361L
+
+/********************** FlexRay constants 1400 - 1409 *************************/
+
+#define XST_FR_TX_ERROR 1400
+#define XST_FR_TX_BUSY 1401
+#define XST_FR_BUF_LOCKED 1402
+#define XST_FR_NO_BUF 1403
+
+/****************** USB constants 1410 - 1420 *******************************/
+
+#define XST_USB_ALREADY_CONFIGURED 1410
+#define XST_USB_BUF_ALIGN_ERROR 1411
+#define XST_USB_NO_DESC_AVAILABLE 1412
+#define XST_USB_BUF_TOO_BIG 1413
+#define XST_USB_NO_BUF 1414
+
+/****************** HWICAP constants 1421 - 1430 *****************************/
+
+#define XST_HWICAP_WRITE_DONE 1421
+
+/**************************** Type Definitions *******************************/
+
+typedef int XStatus;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */