[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [microblaze-uclinux] lltemac
Hi Phillipe,
Reynes Philippe wrote:
I would be pleased to know what is the state of the ll-temac ?
Have you planned to release it soon ? if not, is it possible to get an
alpha version ?
Attached is a series of patches that should get the ll_temac going on a
the most recent petalinux release. There's plenty of rework required
because I had to bring in the most recent xilinx_common core drivers,
and that in turn requires changes to the gpio, spi,
ethernet/ethernet_lite, and so on.
Also changes to the petalinux BSP generator to handle Kconfig.auto.
Apply in order 01, 02, 03 from toplevel petalinux-dist tree - let me
know how it goes.
Regards,
John
---
hardware/edk_user_repository/PetaLogix/bsp/petalinux_v1_00_b/data/petalinux_v2_1_0.tcl | 356 +++++++++-
1 file changed, 353 insertions(+), 3 deletions(-)
Index: hardware/edk_user_repository/PetaLogix/bsp/petalinux_v1_00_b/data/petalinux_v2_1_0.tcl
===================================================================
--- hardware/edk_user_repository/PetaLogix/bsp/petalinux_v1_00_b/data/petalinux_v2_1_0.tcl.orig
+++ hardware/edk_user_repository/PetaLogix/bsp/petalinux_v1_00_b/data/petalinux_v2_1_0.tcl
@@ -243,8 +243,16 @@ proc do_memory_setup {os_handle param_pr
# Check for MPMC vs banked vs direct memory core
if {[string match $controller_type "mpmc"]} {
- set base_param_name "C_MPMC_BASEADDR"
- set high_param_name "C_MPMC_HIGHADDR"
+ set share_addresses [xget_sw_parameter_value $mem_handle C_ALL_PIMS_SHARE_ADDRESSES]
+ if {$share_addresses == 1} {
+ set base_param_name "C_MPMC_BASEADDR"
+ set high_param_name "C_MPMC_HIGHADDR"
+ } else {
+ # Which PIM to use? Assume PIM0
+ set base_param_name "C_PIM0_BASEADDR"
+ set high_param_name "C_PIM0_HIGHADDR"
+ }
+
} elseif {$mem_bank == -1 || [string match $mem_bank ""]} {
set base_param_name "C_BASEADDR"
set high_param_name "C_HIGHADDR"
@@ -461,6 +469,9 @@ proc generate_drv_param {drv_handle} {
set device_id -1
set prev_periph_name ""
+ set drv_name [xget_value $drv_handle "NAME"]
+ set drv_ver [xget_value $drv_handle "PARAMETER" "DRIVER_VER"]
+
# global array to keep count of each peripheral type
global periph_count
@@ -485,6 +496,7 @@ proc generate_drv_param {drv_handle} {
# strip any opb_ plb_ or dcr_ prefixes from periph name
regsub -nocase ^OPB_ $periph_name "" periph_name
regsub -nocase ^PLB_ $periph_name "" periph_name
+ regsub -nocase ^PLBV46_ $periph_name "" periph_name
regsub -nocase ^DCR_ $periph_name "" periph_name
regsub -nocase ^XPS_ $periph_name "" periph_name
@@ -525,10 +537,348 @@ proc generate_drv_param {drv_handle} {
}
}
}
-
generate_generic ""
}
+ # Special case fixups on a per-peripheral basis
+ if {[string compare -nocase $drv_name "intc"] == 0} {
+ xredefine_external_intc $drv_handle "xparameters.h" $drv_ver
+ } elseif {[string compare -nocase $drv_name "lltemac"] == 0} {
+ do_lltemac_canonical $drv_handle
+ }
+}
+
+# LLTEMAC is strange - it can have two independent channels, and Linux driver likes to
+# pretend they are completely seperate devices. So, we check for dual channels devices,
+# and spit them out as two seperate devices
+proc do_lltemac_canonical {drvhandle} {
+
+ # We may need to touch the global periph_count for ll_temac, if we have dual channel devices
+ global periph_count
+
+ # Get all periphs with this driver handle
+ set periphs [xget_periphs $drvhandle]
+ set device_id 0
+
+ foreach periph $periphs {
+ # Check for dual channels
+ for {set chan 0} {$chan < 2} {incr chan} {
+ set value [xget_param_value $periph [format "C_TEMAC%d_ENABLED" $chan]]
+ if { $value != "" && $value == 0 } {
+ break
+ }
+
+ # Dual channel device, bump the periph_count to reflect this
+ if {$chan == 1} {
+ incr periph_count(LL_TEMAC)
+ }
+
+ xdefine_temac_params_canonical $periph $device_id $chan
+ xdefine_temac_interrupt $periph $device_id $chan
+ generate_ll_params $periph $device_id $chan
+
+ incr device_id
+
+ }
+
+ }
+}
+
+proc xdefine_temac_interrupt {periph device_id chan} {
+
+ set mhs_handle [xget_hw_parent_handle $periph]
+ set periph_name [string toupper [xget_hw_name $periph]]
+
+ #
+ # In order to reform the XPAR for the interrupt ID, we need to hunt
+ # for the interrupt ID based on the interrupt signal name of the TEMAC
+ #
+
+ # First get the interrupt ports on this peripheral
+ set interrupt_port [xget_port_by_subtype $periph "SIGIS" "INTERRUPT" "DIR" "O"]
+
+ # For each interrupt port, find out the ordinal of the interrupt line
+ # as connected to an interrupt controller
+ set addentry 0
+ foreach intr_port $interrupt_port {
+ set interrupt_signal_name [xget_hw_name $intr_port]
+ set interrupt_signal [xget_hw_value $intr_port]
+ set intc_prt [xget_connected_ports_handle $mhs_handle $interrupt_signal "sink"]
+
+ # Make sure the interrupt signal was connected in this design. We assume
+ # at least one is. (could be a bug if user just wants polled mode)
+ if { $intc_prt != "" } {
+ # set intc_periph [xget_handle $intc_prt "PARENT"]
+ set intc_periph [xget_hw_parent_handle $intc_prt]
+ set intc_name [string toupper [xget_hw_name $intc_periph]]
+ } else {
+ #puts "Info: $periph_name interrupt signal $interrupt_signal_name not connected"
+ continue
+ }
+
+
+ # A bit of ugliness here. The only way to figure the ordinal is to
+ # iterate over the interrupt lines again and see if a particular signal
+ # matches the original interrupt signal we were tracking.
+
+ set intc_src_ports [xget_interrupt_sources $intc_periph]
+
+ set i 0
+ foreach intc_src_port $intc_src_ports {
+
+ if {[llength $intc_src_port] == 0} {
+ incr i
+ continue
+ }
+
+ set intc_src_port_value [xget_hw_value $intc_src_port]
+ if { $intc_src_port_value == $interrupt_signal } {
+
+ # Verify that these are the ports we are interested in
+ if { $interrupt_signal_name == [format "TemacIntc0_Irpt"] } {
+
+ # verify that we are working with channel 0
+ if { $chan == 0 } {
+ # Recreate the XPAR name and add it to the config file
+# set formatted_name [format "XPAR_%s_%s_%s_INTR" $intc_name $periph_name $interrupt_signal_name ]
+ set canonical_name [format "XILINX_LLTEMAC_%d_IRQ" $device_id]
+# add_field_to_periph_config_struct $device_id [string toupper $formatted_name]
+ generate_int_param "$canonical_name" $i ""
+ #add_field_to_periph_config_struct $device_id $canonical_name
+ set addentry 1
+ }
+ }
+ if { $interrupt_signal_name == [format "TemacIntc1_Irpt"] } {
+
+ # verify that we are working with channel 1
+ if { $chan == 1 } {
+ # Recreate the XPAR name and add it to the config file
+# set formatted_name [format "XPAR_%s_%s_%s_INTR" $intc_name $periph_name $interrupt_signal_name ]
+ set canonical_name [format "XILINX_LLTEMAC_%d_IRQ" $device_id]
+# add_field_to_periph_config_struct $device_id [string toupper $formatted_name]
+ generate_int_param "$canonical_name" $i ""
+ #add_field_to_periph_config_struct $device_id $canonical_name
+ set addentry 1
+ }
+ }
+ }
+ incr i
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# This procedure creates configs that are canonical/normalized for the
+# hardware design parameters.
+# ------------------------------------------------------------------
+proc xdefine_temac_params_canonical {periph device_id chan} {
+
+ generate_comment "Canonical definitions for peripheral [string toupper [xget_hw_name $periph]] Channel $chan"
+
+ set canonical_tag [string toupper [format "XILINX_LLTEMAC_%d" $device_id]]
+
+ set canonical_name [format "%s_BASEADDR" $canonical_tag]
+ generate_hex_param "$canonical_name" 0x[format %X [expr [xget_param_value $periph C_BASEADDR] + [expr $chan * 0x40]]] ""
+ set canonical_name [format "%s_HIGHADDR" $canonical_tag]
+ generate_hex_param "$canonical_name" 0x[format %X [expr [xget_param_value $periph C_BASEADDR] + [expr $chan * 0x40] + 0x3f]] ""
+ #add_field_to_periph_config_struct $device_id $canonical_name
+
+ set canonical_name [format "%s_TXCSUM" $canonical_tag]
+ set formatted_value [format "C_TEMAC%d_TXCSUM" $chan]
+ generate_int_param $canonical_name [xget_param_value $periph $formatted_value] ""
+ #add_field_to_periph_config_struct $device_id $canonical_name
+
+ set canonical_name [format "%s_RXCSUM" $canonical_tag]
+ set formatted_value [format "C_TEMAC%d_RXCSUM" $chan]
+ generate_int_param $canonical_name [xget_param_value $periph $formatted_value] ""
+ #add_field_to_periph_config_struct $device_id $canonical_name
+
+ set canonical_name [format "%s_PHY_TYPE" $canonical_tag]
+ generate_int_param $canonical_name [xget_param_value $periph C_PHY_TYPE] ""
+ #add_field_to_periph_config_struct $device_id $canonical_name
+}
+
+
+# Make externally-sourced interrupts visible to the kernel
+proc xredefine_external_intc {drvhandle file_name ver} {
+ #dbg_puts "xredefine_external_intc for PCI interface external interrupts" "ver: $ver"
+
+ set periphs [xget_periphs $drvhandle]
+ set device_id 0
+ set periph_name [string toupper "intc"]
+
+ foreach periph $periphs {
+
+ # Get the edk based name of peripheral for printing redefines
+ set edk_periph_name [xget_value $periph "NAME"]
+
+ # Get ports that are driving the interrupt
+ set source_ports [xget_interrupt_sources $periph]
+ set i 0
+ foreach source_port $source_ports {
+ set source_port_name($i) [xget_value $source_port "NAME"]
+ set source_periph($i) [xget_handle $source_port "PARENT"]
+ set source_name($i) [xget_value $source_periph($i) "NAME"]
+ incr i
+ }
+ set num_intr_inputs [xget_value $periph "PARAMETER" "C_NUM_INTR_INPUTS" ]
+ for {set i 0} {$i < $num_intr_inputs} {incr i} {
+
+ # Handle system (external) non-PCI interrupt ports
+ if {[string compare -nocase $source_name($i) "system"] == 0 && [string match -nocase "*pci*" $source_port_name($i)] == 0} {
+ generate_int_param "XILINX_[string toupper $source_port_name($i)]_IRQ" $i ""
+ continue
+ }
+
+ #
+ # Handle PCI slightly differently with A-D interrupts. For all other
+ # devices/drivers, write the redefine if the driver is not "generic"
+ #
+
+ if {[string compare -nocase $source_name($i) "system"] == 0 && [string match -nocase "*pci*" $source_port_name($i)] != 0} {
+ set second_part [format "XPAR_%s_SYSTEM_%s_INTR" [string toupper $edk_periph_name] [string toupper $source_port_name($i)] ]
+ if {[string match {*_SBR_*} $source_port_name($i)] == 1} {
+ generate_int_param "XILINX_PCI_0_SBR_IRQ" $i "Interrupt number of PCI SBR IRQ"
+ }
+ if {[string match {*_INTA*} $source_port_name($i)] == 1} {
+ generate_int_param "XILINX_PCI_0_INTR_A_IRQ" $i "Interrupt number of PCI INTR_A"
+ }
+ if {[string match {*_INTB*} $source_port_name($i)] == 1} {
+ generate_int_param "XILINX_PCI_0_INTR_B_IRQ" $i "Interrupt number of PCI INTR_A"
+ }
+ if {[string match {*_INTC*} $source_port_name($i)] == 1} {
+ generate_int_param "XILINX_PCI_0_INTR_C_IRQ" $i "Interrupt number of PCI INTR_A"
+ }
+ if {[string match {*_INTD*} $source_port_name($i)] == 1} {
+ generate_int_param "XILINX_PCI_0_INTR_D_IRQ" $i "Interrupt number of PCI INTR_A"
+ }
+
+ }
+ }
+ incr device_id
+ }
+
+}
+
+
+# Handle LocalLink-connected peripherals. This is taken largely from the Xilinx ll_temac SW driver TCL script.
+# FIXME for now only handles LL_TEMAC <-> MPMC-SDMA connectivity.
+proc generate_ll_params {periph device_id chan} {
+ set mhs_handle [xget_hw_parent_handle $periph]
+ set periph_name [string toupper [xget_hw_name $periph]]
+
+ set p2p_busifs_i [xget_hw_busifs_by_subproperty $periph "BUS_TYPE" "INITIATOR"]
+ set p2p_periphs [list]
+
+ foreach p2p_busif $p2p_busifs_i {
+ set busif_name [string toupper [xget_hw_name $p2p_busif]]
+ set bus_name [string toupper [xget_hw_value $p2p_busif]]
+ set conn_busif_handle [xget_hw_connected_busifs_handle $mhs_handle $bus_name "TARGET"]
+
+ if { [string compare -nocase $conn_busif_handle "" ] == 0 } {
+ continue
+ }
+
+ set conn_busif_name [xget_hw_name $conn_busif_handle]
+ set conn_busif_type [xget_hw_value $conn_busif_handle]
+
+ set target_periph [xget_hw_parent_handle $conn_busif_handle]
+
+ # If this is not already in the list of periphs connected to
+ # this peripheral, process the peripheral. Else, skip
+ set posn [lsearch -exact $p2p_periphs $target_periph]
+ if {$posn != -1} {
+ continue
+ }
+
+ set target_periph_type [xget_hw_value $target_periph]
+ set target_periph_name [string toupper [xget_hw_name $target_periph]]
+
+ set canonical_tag [string toupper [format "XILINX_LLTEMAC_%d_LLINK" $device_id ]]
+
+ switch -glob $target_periph_type {
+ "mpmc*" {
+ # Initiator port connected to an MPMC - this is an SDMA style interface
+ scan $conn_busif_name "SDMA_LL%d" mpmc_port_num
+
+ set shared_addr [xget_param_value $target_periph "C_ALL_PIMS_SHARE_ADDRESSES"]
+ if { $shared_addr == 0 } {
+ # DMA engines have their own base addresses
+ set mpmc_baseaddr [xget_value $target_periph "PARAMETER" [format "C_SDMA_CTRL%d_BASEADDR" $mpmc_port_num]]
+ } else {
+ # DMA engines share a base address, offset by the port number
+ set mpmc_baseaddr [xget_param_value $target_periph "C_SDMA_CTRL_BASEADDR"]
+ set mpmc_baseaddr 0x[format %x [expr $mpmc_baseaddr + [expr $mpmc_port_num * 0x80]]]
+ }
+ # LL_SDMA is type 2
+ generate_int_param "${canonical_tag}_TYPE" 2 "MPMC Local Link connection type of ${canonical_tag}"
+ generate_hex_param "${canonical_tag}_SDMA_BASEADDR" $mpmc_baseaddr "MPMC SDMA port base address of ${canonical_tag}"
+
+ # Now sort out the IRQs of the RX and TX signals
+ set dmarx_signal [format "SDMA%d_Rx_IntOut" $mpmc_port_num]
+ set dmatx_signal [format "SDMA%d_Tx_IntOut" $mpmc_port_num]
+
+ define_ll_dma_interrupts $mhs_handle $target_periph $target_periph_name $canonical_tag $dmarx_signal $dmatx_signal
+ }
+ }
+ }
+
+}
+
+# Export IRQ connectivity of LL connected DMA peripherals.
+proc define_ll_dma_interrupts {mhs_handle target_periph target_periph_name canonical_tag dmarx_signal dmatx_signal} {
+# First get the interrupt ports on this LL peripheral
+ set interrupt_port [xget_port_by_subtype $target_periph "SIGIS" "INTERRUPT" "DIR" "O"]
+
+ # For each interrupt port, find out the ordinal of the interrupt line
+ # as connected to an interrupt controller
+ set addentry 0
+ set dmarx "null"
+ set dmatx "null"
+ foreach intr_port $interrupt_port {
+ set interrupt_signal_name [xget_hw_name $intr_port]
+ set interrupt_signal [xget_hw_value $intr_port]
+ set intc_port [xget_connected_ports_handle $mhs_handle $interrupt_signal "sink"]
+
+ # Make sure the interrupt signal was connected in this design. We assume
+ # at least one is. (could be a bug if user just wants polled mode)
+ if { $intc_port != "" } {
+ # set intc_periph [xget_handle $intc_prt "PARENT"]
+ set intc_periph [xget_hw_parent_handle $intc_port]
+ set intc_name [string toupper [xget_hw_name $intc_periph]]
+ } else {
+ puts "Info: $target_periph_name interrupt signal $interrupt_signal_name not connected"
+ continue
+ }
+
+ # A bit of ugliness here. The only way to figure the ordinal is to
+ # iterate over the interrupt lines again and see if a particular signal
+ # matches the original interrupt signal we were tracking.
+ # If it does, put out the XPAR
+ set intc_src_ports [xget_interrupt_sources $intc_periph]
+ set i 0
+ foreach intc_src_port $intc_src_ports {
+
+ if {[llength $intc_src_port] == 0} {
+ incr i
+ continue
+ }
+
+ set intc_src_port_value [xget_hw_value $intc_src_port]
+ if { $intc_src_port_value == $interrupt_signal } {
+
+ # Verify that these are the DMA ports we are interested in
+
+ if { $interrupt_signal_name == $dmarx_signal } {
+ generate_int_param ${canonical_tag}_DMARX_INTR $i "MPMC SDMA RX IRQ of ${canonical_tag}"
+ } elseif { $interrupt_signal_name == $dmatx_signal } {
+ generate_int_param ${canonical_tag}_DMATX_INTR $i "MPMC SDMA TX IRQ of ${canonical_tag}"
+ }
+ incr addentry
+ }
+ incr i
+ }
+ }
}
# Convert EDK param of type std_logic_vector into a C-style hex val
---
software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile | 1
software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.c | 32
software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.h | 54
software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio_l.h | 26
software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/adapter.c | 4
software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.c | 104
software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.h | 94
software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_i.h | 24
software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_l.h | 44
software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_options.c | 46
software/linux-2.6.x-petalogix/drivers/misc/Kconfig | 21
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/adapter.c | 42
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.c | 92
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.h | 200 -
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_g.c | 8
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_i.h | 14
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr.c | 28
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_dma.c | 94
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_fifo.c | 54
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_l.h | 42
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_options.c | 52
software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_phy.c | 36
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/adapter.c | 2
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.c | 22
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.h | 24
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_g.c | 16
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_i.h | 16
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_intr.c | 18
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.c | 16
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.h | 16
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_selftest.c | 18
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.c | 24
software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.h | 18
software/linux-2.6.x-petalogix/drivers/xilinx_common/Kconfig | 2
software/linux-2.6.x-petalogix/drivers/xilinx_common/Makefile | 21
software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.c | 29
software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.h | 84
software/linux-2.6.x-petalogix/drivers/xilinx_common/xbuf_descriptor.h | 6
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdebug.h | 48
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.c | 310 +-
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.h | 136 -
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel_sg.c | 910 +++----
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmabdv3.h | 531 ++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3.c | 104
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3.h | 515 ++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_intr.c | 129 +
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_l.h | 295 ++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_selftest.c | 79
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_sg.c | 1261 ++++++++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_simple.c | 124
software/linux-2.6.x-petalogix/drivers/xilinx_common/xenv.h | 241 +
software/linux-2.6.x-petalogix/drivers/xilinx_common/xenv_linux.h | 241 +
software/linux-2.6.x-petalogix/drivers/xilinx_common/xilinx_syms.c | 84
software/linux-2.6.x-petalogix/drivers/xilinx_common/xio.c | 511 ++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xio.h | 252 -
software/linux-2.6.x-petalogix/drivers/xilinx_common/xio_dcr.c | 512 ++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xio_dcr.h | 689 +++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xipif_v1_23_b.c | 324 ++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xipif_v1_23_b.h | 44
software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma.c | 244 +
software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma.h | 571 ++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bd.h | 302 ++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bdring.c | 1116 ++++++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bdring.h | 426 +++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_hw.h | 373 ++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_userip.h | 106
software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo.c | 385 +++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo.h | 567 ++++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo_hw.h | 211 +
software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.c | 971 +++----
software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.h | 35
software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.c | 224 -
software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.h | 60
software/linux-2.6.x-petalogix/drivers/xilinx_common/xstatus.h | 434 +--
software/linux-2.6.x-petalogix/drivers/xilinx_common/xstreamer.c | 504 +++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xstreamer.h | 317 ++
software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.c | 170 -
software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.h | 21
78 files changed, 13408 insertions(+), 2413 deletions(-)
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xio.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xio.c
@@ -0,0 +1,511 @@
+/* $Id: xio.c,v 1.5 2007/07/24 22:01:35 xduan 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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xio.c
+*
+* Contains I/O functions for memory-mapped or non-memory-mapped I/O
+* architectures. These functions encapsulate PowerPC architecture-specific
+* I/O requirements.
+*
+* @note
+*
+* This file contains architecture-dependent code.
+*
+* The order of the SYNCHRONIZE_IO and the read or write operation is
+* important. For the Read operation, all I/O needs to complete prior
+* to the desired read to insure valid data from the address. The PPC
+* is a weakly ordered I/O model and reads can and will occur prior
+* to writes and the SYNCHRONIZE_IO ensures that any writes occur prior
+* to the read. For the Write operation the SYNCHRONIZE_IO occurs
+* after the desired write to ensure that the address is updated with
+* the new value prior to any subsequent read.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/--------------------------------------------------------
+* 1.00a ecm 10/18/05 initial release
+* needs to be updated to replace eieio with mbar when
+* compilers support this mnemonic.
+*
+* 1.00a ecm 01/24/07 update for new coding standard.
+* 1.10a xd 07/24/07 Corrected the format in asm functions in __DCC__ mode.
+* </pre>
+******************************************************************************/
+
+
+/***************************** Include Files *********************************/
+#include "xio.h"
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+/*****************************************************************************/
+/**
+*
+* Performs a 16-bit endian converion.
+*
+* @param Source contains the value to be converted.
+* @param DestPtr contains a pointer to the location to put the
+* converted value.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void OutSwap16(u16 Source, u16 *DestPtr)
+{
+ *DestPtr = (u16) (((Source & 0xFF00) >> 8) | ((Source & 0x00FF) << 8));
+}
+
+u16 InSwap16(u16 *DestPtr)
+{
+ u16 Source = *DestPtr;
+ return (u16) (((Source & 0xFF00) >> 8) | ((Source & 0x00FF) << 8));
+}
+/*****************************************************************************/
+/**
+*
+* Performs a 32-bit endian converion.
+*
+* @param Source contains the value to be converted.
+* @param DestPtr contains a pointer to the location to put the
+* converted value.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void OutSwap32(u32 Source, u32 *DestPtr)
+{
+
+ /* get each of the half words from the 32 bit word */
+
+ u16 LoWord = (u16) (Source & 0x0000FFFF);
+ u16 HiWord = (u16) ((Source & 0xFFFF0000) >> 16);
+
+ /* byte swap each of the 16 bit half words */
+
+ LoWord = (((LoWord & 0xFF00) >> 8) | ((LoWord & 0x00FF) << 8));
+ HiWord = (((HiWord & 0xFF00) >> 8) | ((HiWord & 0x00FF) << 8));
+
+ /* swap the half words before returning the value */
+
+ *DestPtr = (u32) ((LoWord << 16) | HiWord);
+}
+
+u32 InSwap32(u32 *DestPtr)
+{
+ /* get each of the half words from the 32 bit word */
+ u32 Source = *DestPtr;
+
+ u16 LoWord = (u16) (Source & 0x0000FFFF);
+ u16 HiWord = (u16) ((Source & 0xFFFF0000) >> 16);
+
+ /* byte swap each of the 16 bit half words */
+
+ LoWord = (((LoWord & 0xFF00) >> 8) | ((LoWord & 0x00FF) << 8));
+ HiWord = (((HiWord & 0xFF00) >> 8) | ((HiWord & 0x00FF) << 8));
+
+ /* swap the half words before returning the value */
+
+ return (u32) ((LoWord << 16) | HiWord);
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for an 8-bit memory location by reading from the
+* specified address and returning the value read from that address.
+*
+* @param InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+ u8 XIo_In8(XIo_Address InAddress)
+{
+ /* read the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+
+#if defined CONFIG_PPC
+
+ u8 IoContents;
+ __asm__ volatile ("eieio; lbz %0,0(%1)":"=r" (IoContents):"b"
+ (InAddress));
+ return IoContents;
+
+#else
+
+ SYNCHRONIZE_IO;
+ return *(u8 *) InAddress;
+
+#endif
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 16-bit memory location by reading from the
+* specified address and returning the value read from that address.
+*
+* @param InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u16 XIo_In16(XIo_Address InAddress)
+{
+ /* read the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+
+#if defined CONFIG_PPC
+
+ u16 IoContents;
+ __asm__ volatile ("eieio; lhz %0,0(%1)":"=r" (IoContents):"b"
+ (InAddress));
+ return IoContents;
+
+#else
+
+ SYNCHRONIZE_IO;
+ return *(u16 *) InAddress;
+
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 32-bit memory location by reading from the
+* specified address and returning the value read from that address.
+*
+* @param InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XIo_In32(XIo_Address InAddress)
+{
+ /* read the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+
+#ifdef CONFIG_PPC
+
+ u32 IoContents;
+ __asm__ volatile ("eieio; lwz %0,0(%1)":"=r" (IoContents):"b"
+ (InAddress));
+ return IoContents;
+
+#else
+
+ SYNCHRONIZE_IO;
+ return *(u32 *) InAddress;
+
+#endif
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 16-bit memory location by reading from the
+* specified address and returning the byte-swapped value read from that
+* address.
+*
+* @param InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The byte-swapped value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u16 XIo_InSwap16(XIo_Address InAddress)
+{
+ /* read the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+#ifdef CONFIG_PPC
+ u16 IoContents;
+
+ __asm__ volatile ("eieio; lhbrx %0,0,%1":"=r" (IoContents):"b"
+ (InAddress));
+ return IoContents;
+#else
+ return InSwap16(InAddress);
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an input operation for a 32-bit memory location by reading from the
+* specified address and returning the byte-swapped value read from that
+* address.
+*
+* @param InAddress contains the address to perform the input operation at.
+*
+* @return
+*
+* The byte-swapped value read from the specified input address.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32 XIo_InSwap32(XIo_Address InAddress)
+{
+ /* read the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+#ifdef CONFIG_PPC
+ u32 IoContents;
+
+ __asm__ volatile ("eieio; lwbrx %0,0,%1":"=r" (IoContents):"b"
+ (InAddress));
+ return IoContents;
+#else
+ return InSwap32(InAddress);
+#endif
+
+}
+
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for an 8-bit memory location by writing the
+* specified value to the the specified address.
+*
+* @param OutAddress contains the address to perform the output operation at.
+* @param Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_Out8(XIo_Address OutAddress, u8 Value)
+{
+ /* write the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+
+#ifdef CONFIG_PPC
+
+ __asm__ volatile ("stb %0,0(%1); eieio"::"r" (Value), "b"(OutAddress));
+
+#else
+
+ *(volatile u8 *) OutAddress = Value;
+ SYNCHRONIZE_IO;
+
+#endif
+
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 16-bit memory location by writing the
+* specified value to the the specified address.
+*
+* @param OutAddress contains the address to perform the output operation at.
+* @param Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_Out16(XIo_Address OutAddress, u16 Value)
+{
+ /* write the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+
+#ifdef CONFIG_PPC
+
+ __asm__ volatile ("sth %0,0(%1); eieio"::"r" (Value), "b"(OutAddress));
+
+#else
+
+ *(volatile u16 *) OutAddress = Value;
+ SYNCHRONIZE_IO;
+
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 32-bit memory location by writing the
+* specified value to the the specified address.
+*
+* @param OutAddress contains the address to perform the output operation at.
+* @param Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_Out32(XIo_Address OutAddress, u32 Value)
+{
+ /* write the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+
+#ifdef CONFIG_PPC
+
+ __asm__ volatile ("stw %0,0(%1); eieio"::"r" (Value), "b"(OutAddress));
+
+#else
+
+ *(volatile u32 *) OutAddress = Value;
+ SYNCHRONIZE_IO;
+
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 16-bit memory location by writing the
+* specified value to the the specified address. The value is byte-swapped
+* before being written.
+*
+* @param OutAddress contains the address to perform the output operation at.
+* @param Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_OutSwap16(XIo_Address OutAddress, u16 Value)
+{
+ /* write the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+#ifdef CONFIG_PPC
+ __asm__ volatile ("sthbrx %0,0,%1; eieio"::"r" (Value),
+ "b"(OutAddress));
+#else
+ OutSwap16(OutAddress, Value);
+#endif
+}
+
+/*****************************************************************************/
+/**
+*
+* Performs an output operation for a 32-bit memory location by writing the
+* specified value to the the specified address. The value is byte-swapped
+* before being written.
+*
+* @param OutAddress contains the address to perform the output operation at.
+* @param Value contains the value to be output at the specified address.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void XIo_OutSwap32(XIo_Address OutAddress, u32 Value)
+{
+ /* write the contents of the I/O location and then synchronize the I/O
+ * such that the I/O operation completes before proceeding on
+ */
+#ifdef CONFIG_PPC
+ __asm__ volatile ("stwbrx %0,0,%1; eieio"::"r" (Value),
+ "b"(OutAddress));
+#else
+ OutSwap32(OutAddress, Value);
+#endif
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/Kconfig
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/Kconfig.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/Kconfig
@@ -1,4 +1,4 @@
config XILINX_EDK
bool
+# depends on XILINX_VIRTEX
default y
-
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.h
@@ -47,8 +47,8 @@
*
******************************************************************************/
-#ifndef XBASIC_TYPES_H /* prevent circular inclusions */
-#define XBASIC_TYPES_H /* by using protection macros */
+#ifndef XBASIC_TYPES_H /* prevent circular inclusions */
+#define XBASIC_TYPES_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
@@ -61,25 +61,13 @@ extern "C" {
/************************** Constant Definitions *****************************/
-/** Xboolean true */
-#define XTRUE 1
-/** Xboolean false */
-#define XFALSE 0
-
-#ifndef TRUE
+#ifndef TRUE
#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
+#endif
-#ifndef NULL
-#define NULL 0
+#ifndef FALSE
+#define FALSE !(TRUE)
#endif
-/** Null */
-#define XNULL NULL
#define XCOMPONENT_IS_READY 0x11111111 /**< component has been initialized */
#define XCOMPONENT_IS_STARTED 0x22222222 /**< component has been started */
@@ -97,77 +85,26 @@ extern unsigned int XAssertStatus;
extern void XAssert(char *, int);
/**************************** Type Definitions *******************************/
-
-/** @name Primitive types
- * These primitive types are created for transportability.
- * They are dependent upon the target architecture.
- * @{
- */
-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 floating point */
-typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */
-
-typedef struct
-{
- Xuint32 Upper;
- Xuint32 Lower;
-} Xuint64;
-
-/*@}*/
-
/**
* This data type defines an interrupt handler for a device.
* The argument points to the instance of the component
*/
-typedef void (*XInterruptHandler)(void *InstancePtr);
+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);
+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);
+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
/*****************************************************************************/
@@ -283,5 +220,4 @@ void XNullHandler(void *NullParameter);
}
#endif
-#endif /* end of protection macro */
-
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3.c
@@ -0,0 +1,104 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3.c
+*
+* This file implements initialization and control related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 3.00a rmm 03/11/05 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+#include <asm/delay.h>
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* This function initializes a DMA channel. This function must be called
+* prior to using a DMA channel. Initialization of a channel includes setting
+* up the register base address, setting up the instance data, and ensuring the
+* HW is in a quiescent state.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param BaseAddress is where the registers for this channel can be found.
+* If address translation is being used, then this parameter must
+* reflect the virtual base address.
+*
+* @return
+* - XST_SUCCESS if initialization was successful
+*
+******************************************************************************/
+int XDmaV3_Initialize(XDmaV3 * InstancePtr, u32 BaseAddress)
+{
+ u32 Dmasr;
+
+ /* Setup the instance */
+ memset(InstancePtr, 0, sizeof(XDmaV3));
+ InstancePtr->RegBase = BaseAddress;
+ InstancePtr->IsReady = XCOMPONENT_IS_READY;
+ InstancePtr->BdRing.RunState = XST_DMA_SG_IS_STOPPED;
+
+ /* If this is SGDMA channel, then make sure it is stopped */
+ Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if (Dmasr & (XDMAV3_DMASR_DMACNFG_SGDMARX_MASK |
+ XDMAV3_DMASR_DMACNFG_SGDMATX_MASK |
+ XDMAV3_DMASR_DMACNFG_SSGDMA_MASK)) {
+ XDmaV3_SgStop(InstancePtr);
+ }
+
+ return (XST_SUCCESS);
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo.c
@@ -0,0 +1,385 @@
+/* $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 2005-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file llfifo.c
+ *
+ * The Xilinx local link FIFO driver component. This driver supports the
+ * Xilinx xps_ll_fifo core.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 10/13/06 First release
+ * </pre>
+ ******************************************************************************/
+
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+
+#include "xllfifo_hw.h"
+#include "xllfifo.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+#define FIFO_WIDTH_BYTES 4
+
+/*
+ * Implementation Notes:
+ *
+ * This Fifo driver makes use of a byte streamer driver (xstreamer.h). The code
+ * is structured like so:
+ *
+ * +--------------------+
+ * | llfifo |
+ * | +----------------+
+ * | | +--------------+
+ * | | | xstreamer |
+ * | | +--------------+
+ * | +----------------+
+ * | |
+ * +--------------------+
+ *
+ * Initialization
+ * At initialization time this driver (llfifo) sets up the streamer objects to
+ * use routines in this driver (llfifo) to perform the actual I/O to the H/W
+ * FIFO core.
+ *
+ * Operation
+ * Once the streamer objects are set up, the API routines in this driver, just
+ * call through to the streamer driver to perform the read/write operations.
+ * The streamer driver will eventually make calls back into the routines (which
+ * reside in this driver) given at initialization to peform the actual I/O.
+ *
+ * Interrupts
+ * Interrupts are handled in the OS/Application layer above this driver.
+ */
+
+xdbg_stmnt(u32 _xllfifo_rr_value;)
+xdbg_stmnt(u32 _xllfifo_ipie_value;)
+xdbg_stmnt(u32 _xllfifo_ipis_value;)
+
+/****************************************************************************/
+/*
+*
+* XLlFifo_RxGetWord reads one 32 bit word from the FIFO specified by
+* <i>InstancePtr</i>.
+*
+* XLlFifo_RxGetLen or XLlFifo_iRxGetLen must be called before calling
+* XLlFifo_RxGetWord. Otherwise, the hardware will raise an <i>Over Read
+* Exception</i>.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_RxGetWord returns the 32 bit word read from the FIFO.
+*
+* @note
+* C-style signature:
+* u32 XLlFifo_RxGetWord(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_RxGetWord(InstancePtr) \
+ XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_RDFD_OFFSET)
+
+/****************************************************************************/
+/*
+*
+* XLlFifo_TxPutWord writes the 32 bit word, <i>Word</i> to the FIFO specified by
+* <i>InstancePtr</i>.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlFifo_TxPutWord(XLlFifo *InstancePtr, u32 Word)
+*
+*****************************************************************************/
+#define XLlFifo_TxPutWord(InstancePtr, Word) \
+ XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDFD_OFFSET, \
+ (Word))
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iRxOccupancy returns the number of 32-bit words available (occupancy)
+* to be read from the receive channel of the FIFO, specified by
+* <i>InstancePtr</i>.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_iRxOccupancy returns the occupancy count in 32-bit words for
+* the specified FIFO.
+*
+******************************************************************************/
+static u32 XLlFifo_iRxOccupancy(XLlFifo *InstancePtr)
+{
+ XASSERT_NONVOID(InstancePtr);
+
+ return XLlFifo_ReadReg(InstancePtr->BaseAddress,
+ XLLF_RDFO_OFFSET);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iRxGetLen notifies the hardware that the program is ready to receive the
+* next frame from the receive channel of the FIFO specified by <i>InstancePtr</i>.
+*
+* Note that the program must first call XLlFifo_iRxGetLen before pulling data
+* out of the receive channel of the FIFO with XLlFifo_Read.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_iRxGetLen returns the number of bytes available in the next
+* frame.
+*
+******************************************************************************/
+static u32 XLlFifo_iRxGetLen(XLlFifo *InstancePtr)
+{
+ XASSERT_NONVOID(InstancePtr);
+
+ return XLlFifo_ReadReg(InstancePtr->BaseAddress,
+ XLLF_RLF_OFFSET);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iRead_Aligned reads, <i>WordCount</i>, words from the FIFO referenced by
+* <i>InstancePtr</i> to the block of memory, referenced by <i>BufPtr</i>.
+*
+* XLlFifo_iRead_Aligned assumes that <i>BufPtr</i> is already aligned according
+* to the following hardware limitations:
+* ppc - aligned on 32 bit boundaries to avoid performance penalties
+* from unaligned exception handling.
+* microblaze - aligned on 32 bit boundaries as microblaze does not handle
+* unaligned transfers.
+*
+* Care must be taken to ensure that the number of words read with one or more
+* calls to XLlFifo_Read() does not exceed the number of bytes (rounded up to
+* the nearest whole 32 bit word) available given from the last call to
+* XLlFifo_RxGetLen().
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param BufPtr specifies the memory address to place the data read.
+*
+* @param WordCount specifies the number of 32 bit words to read.
+*
+* @return XLlFifo_iRead_Aligned always returns XST_SUCCESS. Error handling is
+* otherwise handled through hardware exceptions and interrupts.
+*
+* @note
+*
+* C Signature: int XLlFifo_iRead_Aligned(XLlFifo *InstancePtr,
+* void *BufPtr, unsigned WordCount);
+*
+******************************************************************************/
+/* static */ int XLlFifo_iRead_Aligned(XLlFifo *InstancePtr, void *BufPtr,
+ unsigned WordCount)
+{
+ unsigned WordsRemaining = WordCount;
+ u32 *BufPtrIdx = BufPtr;
+
+ xdbg_printf(XDBG_DEBUG_FIFO_RX, "XLlFifo_iRead_Aligned: start\n");
+ XASSERT_NONVOID(InstancePtr);
+ XASSERT_NONVOID(BufPtr);
+ /* assert bufer is 32 bit aligned */
+ XASSERT_NONVOID(((unsigned)BufPtr & 0x3) == 0x0);
+ xdbg_printf(XDBG_DEBUG_FIFO_RX, "XLlFifo_iRead_Aligned: after asserts\n");
+
+ while (WordsRemaining) {
+/* xdbg_printf(XDBG_DEBUG_FIFO_RX,
+ "XLlFifo_iRead_Aligned: WordsRemaining: %d\n",
+ WordsRemaining);
+*/
+ *BufPtrIdx = XLlFifo_RxGetWord(InstancePtr);
+ BufPtrIdx++;
+ WordsRemaining--;
+ }
+ xdbg_printf(XDBG_DEBUG_FIFO_RX,
+ "XLlFifo_iRead_Aligned: returning SUCCESS\n");
+ return XST_SUCCESS;
+}
+
+/****************************************************************************/
+/*
+*
+* XLlFifo_iTxVacancy returns the number of unused 32 bit words available
+* (vacancy) in the send channel of the FIFO, specified by <i>InstancePtr</i>.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_iTxVacancy returns the vacancy count in 32-bit words for
+* the specified FIFO.
+*
+*****************************************************************************/
+static u32 XLlFifo_iTxVacancy(XLlFifo *InstancePtr)
+{
+ XASSERT_NONVOID(InstancePtr);
+
+ return XLlFifo_ReadReg(InstancePtr->BaseAddress,
+ XLLF_TDFV_OFFSET);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iTxSetLen begins a hardware transfer of data out of the transmit
+* channel of the FIFO, specified by <i>InstancePtr</i>. <i>Bytes</i> specifies the number
+* of bytes in the frame to transmit.
+*
+* Note that <i>Bytes</i> (rounded up to the nearest whole 32 bit word) must be same
+* number of words just written using one or more calls to
+* XLlFifo_iWrite_Aligned()
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param Bytes specifies the number of bytes to transmit.
+*
+* @return N/A
+*
+******************************************************************************/
+static void XLlFifo_iTxSetLen(XLlFifo *InstancePtr, u32 Bytes)
+{
+ XASSERT_VOID(InstancePtr);
+
+ XLlFifo_WriteReg(InstancePtr->BaseAddress, XLLF_TLF_OFFSET,
+ Bytes);
+}
+
+/*****************************************************************************/
+/*
+*
+* XLlFifo_iWrite_Aligned writes, <i>WordCount</i>, words to the FIFO referenced by
+* <i>InstancePtr</i> from the block of memory, referenced by <i>BufPtr</i>.
+*
+* XLlFifo_iWrite_Aligned assumes that <i>BufPtr</i> is already aligned according
+* to the following hardware limitations:
+* ppc - aligned on 32 bit boundaries to avoid performance penalties
+* from unaligned exception handling.
+* microblaze - aligned on 32 bit boundaries as microblaze does not handle
+* unaligned transfers.
+*
+* Care must be taken to ensure that the number of words written with one or
+* more calls to XLlFifo_iWrite_Aligned() matches the number of bytes (rounded up
+* to the nearest whole 32 bit word) given in the next call to
+* XLlFifo_iTxSetLen().
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param BufPtr specifies the memory address to place the data read.
+*
+* @param WordCount specifies the number of 32 bit words to read.
+*
+* @return XLlFifo_iWrite_Aligned always returns XST_SUCCESS. Error handling is
+* otherwise handled through hardware exceptions and interrupts.
+*
+* @note
+*
+* C Signature: int XLlFifo_iWrite_Aligned(XLlFifo *InstancePtr,
+* void *BufPtr, unsigned WordCount);
+*
+******************************************************************************/
+/* static */ int XLlFifo_iWrite_Aligned(XLlFifo *InstancePtr, void *BufPtr,
+ unsigned WordCount)
+{
+ unsigned WordsRemaining = WordCount;
+ u32 *BufPtrIdx = BufPtr;
+
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XLlFifo_iWrite_Aligned: Inst: %p; Buff: %p; Count: %d\n",
+ InstancePtr, BufPtr, WordCount);
+ XASSERT_NONVOID(InstancePtr);
+ XASSERT_NONVOID(BufPtr);
+ /* assert bufer is 32 bit aligned */
+ XASSERT_NONVOID(((unsigned)BufPtr & 0x3) == 0x0);
+
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XLlFifo_iWrite_Aligned: WordsRemaining: %d\n",
+ WordsRemaining);
+ while (WordsRemaining) {
+ XLlFifo_TxPutWord(InstancePtr, *BufPtrIdx);
+ BufPtrIdx++;
+ WordsRemaining--;
+ }
+
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XLlFifo_iWrite_Aligned: returning SUCCESS\n");
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_Initialize initializes an XPS_ll_Fifo device along with the
+* <i>InstancePtr</i> that references it.
+*
+* @param InstancePtr references the memory instance to be associated with
+* the FIFO device upon initialization.
+*
+* @param BaseAddress is the processor address used to access the
+* base address of the Fifo device.
+*
+* @return N/A
+*
+******************************************************************************/
+void XLlFifo_Initialize(XLlFifo *InstancePtr, u32 BaseAddress)
+{
+ XASSERT_VOID(InstancePtr);
+ XASSERT_VOID(BaseAddress);
+
+ /* Clear instance memory */
+ memset(InstancePtr, 0, sizeof(XLlFifo));
+
+ /*
+ * We don't care about the physical base address, just copy the
+ * processor address over it.
+ */
+ InstancePtr->BaseAddress = BaseAddress;
+
+ InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+ XLlFifo_TxReset(InstancePtr);
+ XLlFifo_RxReset(InstancePtr);
+
+ XStrm_RxInitialize(&(InstancePtr->RxStreamer), FIFO_WIDTH_BYTES,
+ (void *)InstancePtr,
+ (XStrm_XferFnType)XLlFifo_iRead_Aligned,
+ (XStrm_GetLenFnType)XLlFifo_iRxGetLen,
+ (XStrm_GetOccupancyFnType)XLlFifo_iRxOccupancy);
+
+ XStrm_TxInitialize(&(InstancePtr->TxStreamer), FIFO_WIDTH_BYTES,
+ (void *)InstancePtr,
+ (XStrm_XferFnType)XLlFifo_iWrite_Aligned,
+ (XStrm_SetLenFnType)XLlFifo_iTxSetLen,
+ (XStrm_GetVacancyFnType)XLlFifo_iTxVacancy);
+}
+
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xio.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xio.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xio.h
@@ -1,4 +1,4 @@
-/* $Id: xio.h,v 1.1 2006/12/13 14:22:33 imanuilov Exp $ */
+/* $Id: xio.h,v 1.4 2007/07/24 22:01:35 xduan Exp $ */
/******************************************************************************
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
@@ -15,7 +15,7 @@
* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
-* (c) Copyright 2002-2003 Xilinx Inc.
+* (c) Copyright 2007 Xilinx Inc.
* All rights reserved.
*
******************************************************************************/
@@ -25,31 +25,36 @@
* @file xio.h
*
* This file contains the interface for the XIo component, which encapsulates
-* the Input/Output functions for processors that do not require any special
-* I/O handling.
+* the Input/Output functions for the PowerPC architecture.
+* This header file needs to be updated to replace eieio with mbar when
+* compilers support the mbar mnemonic.
+*
+* @note
+*
+* This file contains architecture-dependent items (memory mapped or non memory
+* mapped I/O).
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
-* ----- ---- -------- -------------------------------------------------------
-* 1.00a rpm 11/07/03 Added InSwap/OutSwap routines for endian conversion
-* 1.00a xd 11/04/04 Improved support for doxygen
-* 1.01a ecm 02/24/06 CR225908 corrected the extra curly braces in macros
-* and bumped version to 1.01.a.
+* ----- ---- -------- --------------------------------------------------------
+* 1.00a ecm 10/18/05 initial release
+* needs to be updated to replace eieio with mbar when
+* compilers support this mnemonic.
*
+* 1.00a ecm 01/24/07 update for new coding standard.
+* 1.10a xd 07/24/07 Corrected the format in asm functions in __DCC__ mode.
* </pre>
-*
-* @note
-*
-* This file may contain architecture-dependent items (memory-mapped or
-* non-memory-mapped I/O).
-*
******************************************************************************/
#ifndef XIO_H /* prevent circular inclusions */
#define XIO_H /* by using protection macros */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/***************************** Include Files *********************************/
#include "xbasic_types.h"
@@ -63,125 +68,81 @@
* Typedef for an I/O address. Typically correlates to the width of the
* address bus.
*/
-typedef Xuint32 XIo_Address;
+typedef u32 XIo_Address;
/***************** Macros (Inline Functions) Definitions *********************/
-/*
- * The following macros allow optimized I/O operations for memory mapped I/O.
- * It should be noted that macros cannot be used if synchronization of the I/O
- * operation is needed as it will likely break some code.
+/* The following macro is specific to the GNU compiler and PowerPC family. It
+ * performs an EIEIO instruction such that I/O operations are synced correctly.
+ * This macro is not necessarily portable across compilers since it uses
+ * inline assembly.
*/
+#ifdef CONFIG_PPC
+# define SYNCHRONIZE_IO __asm__ volatile ("eieio") /* should be 'mbar' ultimately */
+#else
+# define SYNCHRONIZE_IO
+#endif
-/*****************************************************************************/
-/**
-*
-* Performs an input operation for an 8-bit memory location by reading from the
-* specified address and returning the value read from that address.
-*
-* @param InputPtr contains the address to perform the input operation at.
-*
-* @return The value read from the specified input address.
-*
-******************************************************************************/
-#define XIo_In8(InputPtr) (*(volatile Xuint8 *)(InputPtr))
-
-/*****************************************************************************/
-/**
-*
-* Performs an input operation for a 16-bit memory location by reading from the
-* specified address and returning the value read from that address.
-*
-* @param InputPtr contains the address to perform the input operation at.
-*
-* @return The value read from the specified input address.
-*
-******************************************************************************/
-#define XIo_In16(InputPtr) (*(volatile Xuint16 *)(InputPtr))
+/* The following macros allow the software to be transportable across
+ * processors which use big or little endian memory models.
+ *
+ * Defined first are processor-specific endian conversion macros specific to
+ * the GNU compiler and the PowerPC family, as well as a no-op endian conversion
+ * macro. These macros are not to be used directly by software. Instead, the
+ * XIo_To/FromLittleEndianXX and XIo_To/FromBigEndianXX macros below are to be
+ * used to allow the endian conversion to only be performed when necessary
+ */
-/*****************************************************************************/
-/**
-*
-* Performs an input operation for a 32-bit memory location by reading from the
-* specified address and returning the value read from that address.
-*
-* @param InputPtr contains the address to perform the input operation at.
-*
-* @return The value read from the specified input address.
-*
-******************************************************************************/
-#define XIo_In32(InputPtr) (*(volatile Xuint32 *)(InputPtr))
+#define XIo_EndianNoop(Source, DestPtr) (*DestPtr = Source)
+#ifdef CONFIG_PPC
-/*****************************************************************************/
-/**
-*
-* Performs an output operation for an 8-bit memory location by writing the
-* specified value to the the specified address.
-*
-* @param OutputPtr contains the address to perform the output operation at.
-* @param Value contains the value to be output at the specified address.
-*
-* @return None.
-*
-******************************************************************************/
-#define XIo_Out8(OutputPtr, Value) \
- (*(volatile Xuint8 *)((OutputPtr)) = (Value))
+#define XIo_EndianSwap16(Source, DestPtr) __asm__ __volatile__(\
+ "sthbrx %0,0,%1\n"\
+ : : "r" (Source), "r" (DestPtr)\
+ )
+
+#define XIo_EndianSwap32(Source, DestPtr) __asm__ __volatile__(\
+ "stwbrx %0,0,%1\n"\
+ : : "r" (Source), "r" (DestPtr)\
+ )
+#else
-/*****************************************************************************/
-/**
-*
-* Performs an output operation for a 16-bit memory location by writing the
-* specified value to the the specified address.
-*
-* @param OutputPtr contains the address to perform the output operation at.
-* @param Value contains the value to be output at the specified address.
-*
-* @return None.
-*
-******************************************************************************/
-#define XIo_Out16(OutputPtr, Value) \
- (*(volatile Xuint16 *)((OutputPtr)) = (Value))
+#define XIo_EndianSwap16(Source, DestPtr) \
+{\
+ u16 src = (Source); \
+ u16 *destptr = (DestPtr); \
+ *destptr = src >> 8; \
+ *destptr |= (src << 8); \
+}
+
+#define XIo_EndianSwap32(Source, DestPtr) \
+{\
+ u32 src = (Source); \
+ u32 *destptr = (DestPtr); \
+ *destptr = src >> 24; \
+ *destptr |= ((src >> 8) & 0x0000FF00); \
+ *destptr |= ((src << 8) & 0x00FF0000); \
+ *destptr |= ((src << 24) & 0xFF000000); \
+}
-/*****************************************************************************/
-/**
-*
-* Performs an output operation for a 32-bit memory location by writing the
-* specified value to the the specified address.
-*
-* @param OutputPtr contains the address to perform the output operation at.
-* @param Value contains the value to be output at the specified address.
-*
-* @return None.
-*
-******************************************************************************/
-#define XIo_Out32(OutputPtr, Value) \
- (*(volatile Xuint32 *)((OutputPtr)) = (Value))
+#endif
+// #ifdef XLITTLE_ENDIAN
+// /* little-endian processor */
-/* The following macros allow the software to be transportable across
- * processors which use big or little endian memory models.
- *
- * Defined first is a no-op endian conversion macro. This macro is not to
- * be used directly by software. Instead, the XIo_To/FromLittleEndianXX and
- * XIo_To/FromBigEndianXX macros below are to be used to allow the endian
- * conversion to only be performed when necessary
- */
-#define XIo_EndianNoop(Source, Destination) (*DestPtr = Source)
-
-#ifdef XLITTLE_ENDIAN
-
-#define XIo_ToLittleEndian16 XIo_EndianNoop
-#define XIo_ToLittleEndian32 XIo_EndianNoop
-#define XIo_FromLittleEndian16 XIo_EndianNoop
-#define XIo_FromLittleEndian32 XIo_EndianNoop
-
-#define XIo_ToBigEndian16(Source, DestPtr) XIo_EndianSwap16(Source, DestPtr)
-#define XIo_ToBigEndian32(Source, DestPtr) XIo_EndianSwap32(Source, DestPtr)
-#define XIo_FromBigEndian16 XIo_ToBigEndian16
-#define XIo_FromBigEndian32 XIo_ToBigEndian32
+// #define XIo_ToLittleEndian16 XIo_EndianNoop
+// #define XIo_ToLittleEndian32 XIo_EndianNoop
+// #define XIo_FromLittleEndian16 XIo_EndianNoop
+// #define XIo_FromLittleEndian32 XIo_EndianNoop
+
+// #define XIo_ToBigEndian16(Source, DestPtr) XIo_EndianSwap16(Source, DestPtr)
+// #define XIo_ToBigEndian32(Source, DestPtr) XIo_EndianSwap32(Source, DestPtr)
+// #define XIo_FromBigEndian16 XIo_ToBigEndian16
+// #define XIo_FromBigEndian32 XIo_ToBigEndian32
-#else
+// #else
+/* big-endian processor */ // ppc or microblaze
#define XIo_ToLittleEndian16(Source, DestPtr) XIo_EndianSwap16(Source, DestPtr)
#define XIo_ToLittleEndian32(Source, DestPtr) XIo_EndianSwap32(Source, DestPtr)
@@ -193,25 +154,48 @@ typedef Xuint32 XIo_Address;
#define XIo_FromBigEndian16 XIo_EndianNoop
#define XIo_FromBigEndian32 XIo_EndianNoop
-#endif
+// #endif
+
/************************** Function Prototypes ******************************/
-/* The following functions allow the software to be transportable across
- * processors which use big or little endian memory models. These functions
- * should not be directly called, but the macros XIo_To/FromLittleEndianXX and
- * XIo_To/FromBigEndianXX should be used to allow the endian conversion to only
- * be performed when necessary.
+/* The following macros allow optimized I/O operations for memory mapped I/O
+ * Note that the SYNCHRONIZE_IO may be moved by the compiler during
+ * optimization.
+ */
+
+u8 XIo_In8(XIo_Address InAddress);
+u16 XIo_In16(XIo_Address InAddress);
+u32 XIo_In32(XIo_Address InAddress);
+
+void XIo_Out8(XIo_Address OutAddress, u8 Value);
+void XIo_Out16(XIo_Address OutAddress, u16 Value);
+void XIo_Out32(XIo_Address OutAddress, u32 Value);
+
+
+/*
+#define XIo_In8(InputPtr) (*(volatile u8 *)(InputPtr)); SYNCHRONIZE_IO;
+#define XIo_In16(InputPtr) (*(volatile u16 *)(InputPtr)); SYNCHRONIZE_IO;
+#define XIo_In32(InputPtr) (*(volatile u32 *)(InputPtr)); SYNCHRONIZE_IO;
+
+#define XIo_Out8(OutputPtr, Value) \
+ { (*(volatile u8 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
+#define XIo_Out16(OutputPtr, Value) \
+ { (*(volatile u16 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
+#define XIo_Out32(OutputPtr, Value) \
+ { (*(volatile u32 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
*/
-void XIo_EndianSwap16(Xuint16 Source, Xuint16* DestPtr);
-void XIo_EndianSwap32(Xuint32 Source, Xuint32* DestPtr);
/* The following functions handle IO addresses where data must be swapped
* They cannot be implemented as macros
*/
-Xuint16 XIo_InSwap16(XIo_Address InAddress);
-Xuint32 XIo_InSwap32(XIo_Address InAddress);
-void XIo_OutSwap16(XIo_Address OutAddress, Xuint16 Value);
-void XIo_OutSwap32(XIo_Address OutAddress, Xuint32 Value);
+u16 XIo_InSwap16(XIo_Address InAddress);
+u32 XIo_InSwap32(XIo_Address InAddress);
+void XIo_OutSwap16(XIo_Address OutAddress, u16 Value);
+void XIo_OutSwap32(XIo_Address OutAddress, u32 Value);
+
+#ifdef __cplusplus
+}
+#endif
-#endif /* end of protection macro */
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xenv_linux.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xenv_linux.h
@@ -0,0 +1,241 @@
+/******************************************************************************
+*
+* 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 xenv_linux.h
+*
+* Defines common services specified by xenv.h.
+*
+* @note
+* This file is not intended to be included directly by driver code.
+* Instead, the generic xenv.h file is intended to be included by driver
+* code.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-----------------------------------------------
+* 1.00a wgr 02/28/07 Added cache handling macros.
+* 1.00a wgr 02/27/07 Simplified code. Deprecated old-style macro names.
+* 1.00a xd 11/03/04 Improved support for doxygen.
+* 1.00a ch 10/24/02 First release
+* 1.10a wgr 03/22/07 Converted to new coding style.
+* </pre>
+*
+*
+******************************************************************************/
+
+#ifndef XENV_LINUX_H
+#define XENV_LINUX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+
+
+/******************************************************************************
+ *
+ * MEMCPY / MEMSET related macros.
+ *
+ * Those macros are defined to catch legacy code in Xilinx drivers. The
+ * XENV_MEM_COPY and XENV_MEM_FILL macros were used in early Xilinx driver
+ * code. They are being replaced by memcpy() and memset() function calls. These
+ * macros are defined to catch any remaining occurences of those macros.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************/
+/**
+ *
+ * Copies a non-overlapping block of memory.
+ *
+ * @param DestPtr
+ * Destination address to copy data to.
+ *
+ * @param SrcPtr
+ * Source address to copy data from.
+ *
+ * @param Bytes
+ * Number of bytes to copy.
+ *
+ * @return None.
+ *
+ *****************************************************************************/
+
+#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \
+ memcpy(DestPtr, SrcPtr, Bytes)
+/* do_not_use_XENV_MEM_COPY_use_memcpy_instead */
+
+
+/*****************************************************************************/
+/**
+ *
+ * Fills an area of memory with constant data.
+ *
+ * @param DestPtr
+ * Destination address to copy data to.
+ *
+ * @param Data
+ * Value to set.
+ *
+ * @param Bytes
+ * Number of bytes to copy.
+ *
+ * @return None.
+ *
+ *****************************************************************************/
+
+#define XENV_MEM_FILL(DestPtr, Data, Bytes) \
+ memset(DestPtr, Data, Bytes)
+/* do_not_use_XENV_MEM_FILL_use_memset_instead */
+
+
+/******************************************************************************
+ *
+ * TIME related macros
+ *
+ ******************************************************************************/
+/**
+ * A structure that contains a time stamp used by other time stamp macros
+ * defined below. This structure is processor dependent.
+ */
+typedef int XENV_TIME_STAMP;
+
+/*****************************************************************************/
+/**
+ *
+ * Time is derived from the 64 bit PPC timebase register
+ *
+ * @param StampPtr is the storage for the retrieved time stamp.
+ *
+ * @return None.
+ *
+ * @note
+ *
+ * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr)
+ * <br><br>
+ * This macro must be implemented by the user.
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_GET(StampPtr)
+
+/*****************************************************************************/
+/**
+ *
+ * This macro is not yet implemented and always returns 0.
+ *
+ * @param Stamp1Ptr is the first sampled time stamp.
+ * @param Stamp2Ptr is the second sampled time stamp.
+ *
+ * @return 0
+ *
+ * @note
+ *
+ * This macro must be implemented by the user.
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0)
+
+/*****************************************************************************/
+/**
+ *
+ * This macro is not yet implemented and always returns 0.
+ *
+ * @param Stamp1Ptr is the first sampled time stamp.
+ * @param Stamp2Ptr is the second sampled time stamp.
+ *
+ * @return 0
+ *
+ * @note
+ *
+ * This macro must be implemented by the user
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0)
+
+/*****************************************************************************/
+/**
+ *
+ * Delay the specified number of microseconds.
+ *
+ * @param delay
+ * Number of microseconds to delay.
+ *
+ * @return None.
+ *
+ * @note XENV_USLEEP is deprecated. Use udelay() instead.
+ *
+ *****************************************************************************/
+
+#define XENV_USLEEP(delay) udelay(delay)
+/* do_not_use_XENV_MEM_COPY_use_memcpy_instead */
+
+
+/******************************************************************************
+ *
+ * CACHE handling macros / mappings
+ *
+ * The implementation of the cache handling functions can be found in
+ * arch/microblaze.
+ *
+ * These #defines are simple mappings to the Linux API.
+ *
+ * The underlying Linux implementation will take care of taking the right
+ * actions depending on the configuration of the MicroBlaze processor in the
+ * system.
+ *
+ ******************************************************************************/
+
+#define XCACHE_ENABLE_DCACHE() __enable_dcache()
+#define XCACHE_DISABLE_DCACHE() __disable_dcache()
+#define XCACHE_ENABLE_ICACHE() __enable_icache()
+#define XCACHE_DISABLE_ICACHE() __disable_icache()
+
+#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) invalidate_dcache_range((Addr), (Addr)+(Len))
+#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) flush_dcache_range((Addr), (Addr)+(Len))
+
+#define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) "XCACHE_INVALIDATE_ICACHE_RANGE unsupported"
+#define XCACHE_FLUSH_ICACHE_RANGE(Addr, Len) flush_icache_range(Addr, Len)
+
+#define XCACHE_ENABLE_CACHE() \
+ { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); }
+
+#define XCACHE_DISABLE_CACHE() \
+ { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); }
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
+
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bdring.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bdring.c
@@ -0,0 +1,1116 @@
+/* $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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma_bdring.c
+*
+* This file implements buffer descriptor ring related functions. For more
+* information on this driver, see xlldma.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a xd 12/21/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+
+#include "xlldma.h"
+#include "xenv.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
+ * XCACHE_FLUSH_DCACHE_RANGE and XCACHE_INVALIDATE_DCACHE_RANGE macros are not
+ * implemented or they do nothing.
+ *****************************************************************************/
+#ifdef XCACHE_FLUSH_DCACHE_RANGE
+# define XLLDMA_CACHE_FLUSH(BdPtr) \
+ XCACHE_FLUSH_DCACHE_RANGE((BdPtr), XLLDMA_BD_HW_NUM_BYTES)
+#else
+# define XLLDMA_CACHE_FLUSH(BdPtr)
+#endif
+
+#ifdef XCACHE_INVALIDATE_DCACHE_RANGE
+# define XLLDMA_CACHE_INVALIDATE(BdPtr) \
+ XCACHE_INVALIDATE_DCACHE_RANGE((BdPtr), XLLDMA_BD_HW_NUM_BYTES)
+#else
+# define XLLDMA_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
+ * @note RingPtr is an implicit parameter
+ *****************************************************************************/
+#define XLLDMA_PHYS_TO_VIRT(BdPtr) \
+ ((u32)(BdPtr) + (RingPtr->FirstBdAddr - RingPtr->FirstBdPhysAddr))
+
+/******************************************************************************
+ * Compute the physical address of a descriptor from its virtual address
+ *
+ * @param BdPtr is the virtual address of the BD
+ *
+ * @returns Physical address of BdPtr
+ *
+ * @note Assume BdPtr is always a valid BD in the ring
+ * @note RingPtr is an implicit parameter
+ *****************************************************************************/
+#define XLLDMA_VIRT_TO_PHYS(BdPtr) \
+ ((u32)(BdPtr) - (RingPtr->FirstBdAddr - RingPtr->FirstBdPhysAddr))
+
+/******************************************************************************
+ * Move the BdPtr argument ahead an arbitrary number of BDs wrapping around
+ * to the beginning of the ring if needed.
+ *
+ * We know if a wraparound should occur if the new BdPtr is greater than
+ * the high address in the ring OR if the new BdPtr crosses the 0xFFFFFFFF
+ * to 0 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 XLLDMA_RING_SEEKAHEAD(RingPtr, BdPtr, NumBd) \
+ { \
+ u32 Addr = (u32)(BdPtr); \
+ \
+ Addr += ((RingPtr)->Separation * (NumBd)); \
+ if ((Addr > (RingPtr)->LastBdAddr) || ((u32)(BdPtr) > Addr))\
+ { \
+ Addr -= (RingPtr)->Length; \
+ } \
+ \
+ (BdPtr) = (XLlDma_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 wraparound should occur if the new BdPtr is less than
+ * the base address in the ring OR if the new BdPtr crosses the 0xFFFFFFFF
+ * to 0 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 XLLDMA_RING_SEEKBACK(RingPtr, BdPtr, NumBd) \
+ { \
+ u32 Addr = (u32)(BdPtr); \
+ \
+ Addr -= ((RingPtr)->Separation * (NumBd)); \
+ if ((Addr < (RingPtr)->FirstBdAddr) || ((u32)(BdPtr) < Addr)) \
+ { \
+ Addr += (RingPtr)->Length; \
+ } \
+ \
+ (BdPtr) = (XLlDma_Bd*)Addr; \
+ }
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+ * Using a memory segment allocated by the caller, create and setup the BD list
+ * for the given SGDMA ring.
+ *
+ * @param InstancePtr is the instance to be worked on.
+ * @param PhysAddr is the physical base address of application memory region.
+ * @param VirtAddr is the virtual base address of the application 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 XLLDMA_BD_MINIMUM_ALIGNMENT 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 application memory
+ * region. It is assumed the region is large enough to contain the BDs.
+ * Refer to the "SGDMA Ring Creation" section in xlldma.h for more
+ * information. The minimum valid value for this parameter is 1.
+ *
+ * @return
+ *
+ * - XST_SUCCESS if initialization was successful
+ * - XST_NO_FEATURE if the provided instance is a non SGDMA type of DMA
+ * 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.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingCreate(XLlDma_BdRing * RingPtr, u32 PhysAddr,
+ u32 VirtAddr, u32 Alignment, unsigned BdCount)
+{
+ unsigned i;
+ u32 BdVirtAddr;
+ u32 BdPhysAddr;
+
+ /* In case there is a failure prior to creating list, make sure the
+ * following attributes are 0 to prevent calls to other SG 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 < XLLDMA_BD_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);
+ }
+
+ /* Compute how many bytes will be between the start of adjacent BDs */
+ RingPtr->Separation =
+ (sizeof(XLlDma_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 next pointer with the physical address of the
+ * next BD
+ * - Set each BD's DMA complete status bit
+ */
+ memset((void *) VirtAddr, 0, (RingPtr->Separation * BdCount));
+
+ BdVirtAddr = VirtAddr;
+ BdPhysAddr = PhysAddr + RingPtr->Separation;
+ for (i = 1; i < BdCount; i++) {
+ XLlDma_mBdWrite(BdVirtAddr, XLLDMA_BD_NDESC_OFFSET, BdPhysAddr);
+ XLlDma_mBdWrite(BdVirtAddr, XLLDMA_BD_STSCTRL_USR0_OFFSET,
+ XLLDMA_BD_STSCTRL_COMPLETED_MASK);
+ XLLDMA_CACHE_FLUSH(BdVirtAddr);
+ BdVirtAddr += RingPtr->Separation;
+ BdPhysAddr += RingPtr->Separation;
+ }
+
+ /* At the end of the ring, link the last BD back to the top */
+ XLlDma_mBdWrite(BdVirtAddr, XLLDMA_BD_NDESC_OFFSET, PhysAddr);
+ XLLDMA_CACHE_FLUSH(BdVirtAddr);
+
+ /* Setup and initialize pointers and counters */
+ RingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+ RingPtr->FirstBdAddr = VirtAddr;
+ RingPtr->FirstBdPhysAddr = PhysAddr;
+ RingPtr->LastBdAddr = BdVirtAddr;
+ RingPtr->Length = RingPtr->LastBdAddr - RingPtr->FirstBdAddr +
+ RingPtr->Separation;
+ RingPtr->AllCnt = BdCount;
+ RingPtr->FreeCnt = BdCount;
+ RingPtr->FreeHead = (XLlDma_Bd *) VirtAddr;
+ RingPtr->PreHead = (XLlDma_Bd *) VirtAddr;
+ RingPtr->HwHead = (XLlDma_Bd *) VirtAddr;
+ RingPtr->HwTail = (XLlDma_Bd *) VirtAddr;
+ RingPtr->PostHead = (XLlDma_Bd *) VirtAddr;
+ RingPtr->BdaRestart = (XLlDma_Bd *) PhysAddr;
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Clone the given BD into every BD in the ring. Except for
+ * XLLDMA_BD_NDESC_OFFSET, every field of the source BD is replicated in every
+ * BD in the ring.
+ *
+ * This function can be called only when all BDs are in the free group such as
+ * they are immediately after creation of the ring. This prevents modification
+ * of BDs while they are in use by hardware or the application.
+ *
+ * @param InstancePtr is the instance to be worked on.
+ * @param SrcBdPtr is the source BD template to be cloned into the list.
+ *
+ * @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 application control.
+ * - XST_DEVICE_IS_STARTED if the DMA channel has not been stopped.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingClone(XLlDma_BdRing * RingPtr, XLlDma_Bd * SrcBdPtr)
+{
+ unsigned i;
+ u32 CurBd;
+ u32 Save;
+ XLlDma_Bd TmpBd;
+
+ /* 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);
+ }
+
+
+ /* Make a copy of the template then modify it by setting complete bit
+ * in status/control field
+ */
+ memcpy(&TmpBd, SrcBdPtr, sizeof(XLlDma_Bd));
+ Save = XLlDma_mBdRead(&TmpBd, XLLDMA_BD_STSCTRL_USR0_OFFSET);
+ Save |= XLLDMA_BD_STSCTRL_COMPLETED_MASK;
+ XLlDma_mBdWrite(&TmpBd, XLLDMA_BD_STSCTRL_USR0_OFFSET, Save);
+
+ /* 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 = RingPtr->FirstBdAddr;
+ i < RingPtr->AllCnt; i++, CurBd += RingPtr->Separation) {
+ Save = XLlDma_mBdRead(CurBd, XLLDMA_BD_NDESC_OFFSET);
+ memcpy((void *) CurBd, (void *) &TmpBd, sizeof(XLlDma_Bd));
+ XLlDma_mBdWrite(CurBd, XLLDMA_BD_NDESC_OFFSET, Save);
+ XLLDMA_CACHE_FLUSH(CurBd);
+ }
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Allow DMA transactions to commence on the given channels if descriptors are
+ * ready to be processed.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ *
+ * @return
+ * - XST_SUCCESS if the channel) were started.
+ * - XST_DMA_SG_NO_LIST if the channel) have no initialized BD ring.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingStart(XLlDma_BdRing * RingPtr)
+{
+ /* BD list has yet to be created for this channel */
+ if (RingPtr->AllCnt == 0) {
+ return (XST_DMA_SG_NO_LIST);
+ }
+
+ /* Do nothing if already started */
+ if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+ return (XST_SUCCESS);
+ }
+
+ /* Sync hardware and driver with the last unprocessed BD or the 1st BD
+ * in the ring if this is the first time starting the channel
+ */
+ XLlDma_mWriteReg(RingPtr->ChanBase, XLLDMA_CDESC_OFFSET,
+ (u32) RingPtr->BdaRestart);
+
+ /* Note as started */
+ RingPtr->RunState = XST_DMA_SG_IS_STARTED;
+
+ /* If there are unprocessed BDs then we want to channel to begin
+ * processing right away
+ */
+ if (RingPtr->HwCnt > 0) {
+ XLLDMA_CACHE_INVALIDATE(RingPtr->HwTail);
+
+ if ((XLlDma_mBdRead(RingPtr->HwTail,
+ XLLDMA_BD_STSCTRL_USR0_OFFSET) &
+ XLLDMA_BD_STSCTRL_COMPLETED_MASK) == 0) {
+ XLlDma_mWriteReg(RingPtr->ChanBase,
+ XLLDMA_TDESC_OFFSET,
+ XLLDMA_VIRT_TO_PHYS(RingPtr->HwTail));
+ }
+ }
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Set interrupt coalescing parameters for the given descriptor ring channel.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param Counter sets the packet counter on the channel. Valid range is
+ * 1..255, or XLLDMA_NO_CHANGE to leave this setting unchanged.
+ * @param Timer sets the waitbound timer on the channel. Valid range is
+ * 1..255, or XLLDMA_NO_CHANGE to leave this setting unchanged. LSB is
+ * in units of 1 / (local link clock).
+ *
+ * @return
+ * - XST_SUCCESS if interrupt coalescing settings updated
+ * - XST_FAILURE if Counter or Timer parameters are out of range
+ *****************************************************************************/
+int XLlDma_BdRingSetCoalesce(XLlDma_BdRing * RingPtr, u32 Counter, u32 Timer)
+{
+ u32 Cr = XLlDma_mReadReg(RingPtr->ChanBase, XLLDMA_CR_OFFSET);
+
+ if (Counter != XLLDMA_NO_CHANGE) {
+ if ((Counter == 0) || (Counter > 0xFF)) {
+ return (XST_FAILURE);
+ }
+
+ Cr = (Cr & ~XLLDMA_CR_IRQ_COUNT_MASK) |
+ (Counter << XLLDMA_CR_IRQ_COUNT_SHIFT);
+ Cr |= XLLDMA_CR_LD_IRQ_CNT_MASK;
+ }
+
+ if (Timer != XLLDMA_NO_CHANGE) {
+ if ((Timer == 0) || (Timer > 0xFF)) {
+ return (XST_FAILURE);
+ }
+
+ Cr = (Cr & ~XLLDMA_CR_IRQ_TIMEOUT_MASK) |
+ (Timer << XLLDMA_CR_IRQ_TIMEOUT_SHIFT);
+ Cr |= XLLDMA_CR_LD_IRQ_CNT_MASK;
+ }
+
+ XLlDma_mWriteReg(RingPtr->ChanBase, XLLDMA_CR_OFFSET, Cr);
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Retrieve current interrupt coalescing parameters from the given descriptor
+ * ring channel.
+ *
+ * @param RingPtr is a pointer to the descriptor ring instance to be worked on.
+ * @param CounterPtr points to a memory location where the current packet
+ * counter will be written.
+ * @param TimerPtr points to a memory location where the current waitbound
+ * timer will be written.
+ *****************************************************************************/
+void XLlDma_BdRingGetCoalesce(XLlDma_BdRing * RingPtr,
+ u32 *CounterPtr, u32 *TimerPtr)
+{
+ u32 Cr = XLlDma_mReadReg(RingPtr->ChanBase, XLLDMA_CR_OFFSET);
+
+ *CounterPtr =
+ ((Cr & XLLDMA_CR_IRQ_COUNT_MASK) >> XLLDMA_CR_IRQ_COUNT_SHIFT);
+ *TimerPtr =
+ ((Cr & XLLDMA_CR_IRQ_TIMEOUT_MASK) >>
+ XLLDMA_CR_IRQ_TIMEOUT_SHIFT);
+}
+
+
+/*****************************************************************************/
+/**
+ * Reserve locations in the BD ring. The set of returned BDs may be modified in
+ * preparation for future DMA transactions). Once the BDs are ready to be
+ * submitted to hardware, the application must call XLlDma_BdRingToHw() in the
+ * same order which they were allocated here. Example:
+ *
+ * <pre>
+ * NumBd = 2;
+ * Status = XDsma_RingBdAlloc(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 = XLlDma_mBdRingNext(MyRingPtr, CurBd);
+ * }
+ *
+ * // Give list to hardware
+ * Status = XLlDma_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
+ * XLlDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ * XLlDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ *
+ * // Legal
+ * XLlDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ * XLlDma_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
+ * XLlDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ * XLlDma_BdRingToHw(MyRingPtr, NumBd2, MySet2);
+ *
+ * // Not legal
+ * XLlDma_BdRingAlloc(MyRingPtr, NumBd1, &MySet1);
+ * XLlDma_BdRingAlloc(MyRingPtr, NumBd2, &MySet2);
+ * XLlDma_BdRingToHw(MyRingPtr, NumBd2, MySet2);
+ * XLlDma_BdRingToHw(MyRingPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * Use the API defined in xlldmabd.h to modify individual BDs. Traversal of the
+ * BD set can be done using XLlDma_mBdRingNext() and XLlDma_mBdRingPrev().
+ *
+ * @param RingPtr is a pointer to the descriptor 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 XLlDma_BdRing
+ * 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 XLlDma_BdRingAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_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;
+ XLLDMA_RING_SEEKAHEAD(RingPtr, RingPtr->FreeHead, NumBd);
+ RingPtr->FreeCnt -= NumBd;
+ RingPtr->PreCnt += NumBd;
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Fully or partially undo an XLlDma_BdRingAlloc() operation. Use this function
+ * if all the BDs allocated by XLlDma_BdRingAlloc() could not be transferred to
+ * hardware with XLlDma_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.
+ *
+ * This function is not the same as XLlDma_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 = XLlDma_BdRingAlloc(MyRingPtr, 10, &BdPtr);
+ * .
+ * .
+ * if (Error)
+ * {
+ * Status = XLlDma_BdRingUnAlloc(MyRingPtr, 10, &BdPtr);
+ * }
+ * </pre>
+ *
+ * A partial UnAlloc means some of the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ * Status = XLlDma_BdRingAlloc(MyRingPtr, 10, &BdPtr);
+ * BdsLeft = 10;
+ * CurBdPtr = BdPtr;
+ *
+ * while (BdsLeft)
+ * {
+ * if (Error)
+ * {
+ * Status = XLlDma_BdRingUnAlloc(MyRingPtr, BdsLeft, CurBdPtr);
+ * }
+ *
+ * CurBdPtr = XLlDma_mBdRingNext(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 descriptor ring instance to be worked on.
+ * @param NumBd is the number of BDs to unallocate
+ * @param BdSetPtr points to the first of the BDs to be returned.
+ *
+ * @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 XLlDma ring function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingUnAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_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 */
+ XLLDMA_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
+ * XLlDma_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.
+ *
+ * @param RingPtr is a pointer to the descriptor ring 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 first BD
+ * did not have its start-of-packet bit set, the last BD did not have
+ * its end-of-packet bit set, or any one of the BD set has 0 as length
+ * value
+ * - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ * XLlDma_BdRingAlloc()
+ *
+ * @note This function should not be preempted by another XLlDma ring function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingToHw(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_Bd * BdSetPtr)
+{
+ XLlDma_Bd *CurBdPtr;
+ unsigned i;
+ u32 BdStsCr;
+
+ /* If the commit set is empty, do nothing */
+ if (NumBd == 0) {
+ return (XST_SUCCESS);
+ }
+
+ /* Make sure we are in sync with XLlDma_BdRingAlloc() */
+ if ((RingPtr->PreCnt < NumBd) || (RingPtr->PreHead != BdSetPtr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ CurBdPtr = BdSetPtr;
+ BdStsCr = XLlDma_mBdRead(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET);
+
+ /* The first BD should have been marked as start-of-packet */
+ if (!(BdStsCr & XLLDMA_BD_STSCTRL_SOP_MASK)) {
+ return (XST_FAILURE);
+ }
+
+ /* For each BD being submitted except the last one, clear the completed
+ * bit and stop_on_end bit in the status word
+ */
+ for (i = 0; i < NumBd - 1; i++) {
+
+ /* Make sure the length value in the BD is non-zero. */
+ if (XLlDma_mBdGetLength(CurBdPtr) == 0) {
+ return (XST_FAILURE);
+ }
+
+ BdStsCr &=
+ ~(XLLDMA_BD_STSCTRL_COMPLETED_MASK |
+ XLLDMA_BD_STSCTRL_SOE_MASK);
+ XLlDma_mBdWrite(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET,
+ BdStsCr);
+
+ /* In RX channel case, the current BD should have the
+ * XLLDMA_USERIP_APPWORD_OFFSET initialized to
+ * XLLDMA_USERIP_APPWORD_INITVALUE
+ */
+ if (RingPtr->IsRxChannel) {
+ XLlDma_mBdWrite(CurBdPtr, XLLDMA_USERIP_APPWORD_OFFSET,
+ XLLDMA_USERIP_APPWORD_INITVALUE);
+ }
+
+ /* Flush the current BD so DMA core could see the updates */
+ XLLDMA_CACHE_FLUSH(CurBdPtr);
+
+ CurBdPtr = XLlDma_mBdRingNext(RingPtr, CurBdPtr);
+ BdStsCr =
+ XLlDma_mBdRead(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET);
+ }
+
+ /* The last BD should have end-of-packet bit set */
+ if (!(BdStsCr & XLLDMA_BD_STSCTRL_EOP_MASK)) {
+ return (XST_FAILURE);
+ }
+
+ /* Make sure the length value in the last BD is non-zero. */
+ if (XLlDma_mBdGetLength(CurBdPtr) == 0) {
+ return (XST_FAILURE);
+ }
+
+ /* The last BD should also have the completed and stop-on-end bits
+ * cleared
+ */
+ BdStsCr &=
+ ~(XLLDMA_BD_STSCTRL_COMPLETED_MASK |
+ XLLDMA_BD_STSCTRL_SOE_MASK);
+ XLlDma_mBdWrite(CurBdPtr, XLLDMA_BD_STSCTRL_USR0_OFFSET, BdStsCr);
+
+ /* In RX channel case, the last BD should have the
+ * XLLDMA_USERIP_APPWORD_OFFSET initialized to
+ * XLLDMA_USERIP_APPWORD_INITVALUE
+ */
+ if (RingPtr->IsRxChannel) {
+ XLlDma_mBdWrite(CurBdPtr, XLLDMA_USERIP_APPWORD_OFFSET,
+ XLLDMA_USERIP_APPWORD_INITVALUE);
+ }
+
+ /* Flush the last BD so DMA core could see the updates */
+ XLLDMA_CACHE_FLUSH(CurBdPtr);
+
+ /* This set has completed pre-processing, adjust ring pointers and
+ * counters
+ */
+ XLLDMA_RING_SEEKAHEAD(RingPtr, RingPtr->PreHead, NumBd);
+ RingPtr->PreCnt -= NumBd;
+ RingPtr->HwTail = CurBdPtr;
+ RingPtr->HwCnt += NumBd;
+
+ /* If it was enabled, tell the engine to begin processing */
+ if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {
+ XLlDma_mWriteReg(RingPtr->ChanBase, XLLDMA_TDESC_OFFSET,
+ XLLDMA_VIRT_TO_PHYS(RingPtr->HwTail));
+ }
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * Returns a set of BD(s) that have been processed by hardware. The returned
+ * BDs may be examined by the application to determine the outcome of the DMA
+ * transactions). Once the BDs have been examined, the application must call
+ * XLlDma_BdRingFree() in the same order which they were retrieved here.
+ *
+ * Example:
+ *
+ * <pre>
+ * NumBd = XLlDma_BdRingFromHw(MyRingPtr, XLLDMA_ALL_BDS, &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 = XLlDma_mBdRingNext(MyRingPtr, CurBd);
+ * }
+ *
+ * XLlDma_BdRingFree(MyRingPtr, NumBd, MyBdSet); // Return the 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
+ * XLlDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
+ * XLlDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ *
+ * // Legal
+ * XLlDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
+ * XLlDma_BdRingFromHw(MyRingPtr, NumBd2, &MySet2);
+ * XLlDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ * XLlDma_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ *
+ * // Not legal
+ * XLlDma_BdRingFromHw(MyRingPtr, NumBd1, &MySet1);
+ * XLlDma_BdRingFromHw(MyRingPtr, NumBd2, &MySet2);
+ * XLlDma_BdRingFree(MyRingPtr, NumBd2, MySet2);
+ * XLlDma_BdRingFree(MyRingPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * If hardware has 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 descriptor ring instance to be worked on.
+ * @param BdLimit is the maximum number of BDs to return in the set. Use
+ * XLLDMA_ALL_BDS to return all BDs that have been processed.
+ * @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 XLlDma ring function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+unsigned XLlDma_BdRingFromHw(XLlDma_BdRing * RingPtr, unsigned BdLimit,
+ XLlDma_Bd ** BdSetPtr)
+{
+ XLlDma_Bd *CurBdPtr;
+ unsigned BdCount;
+ unsigned BdPartialCount;
+ u32 BdStsCr;
+ u32 UserIpAppWord;
+
+ 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 completed bit clear in the status
+ * word which means hardware has not completed processing of that
+ * BD.
+ * - A BD is encountered with its XLLDMA_USERIP_APPWORD_OFFSET field
+ * with value XLLDMA_USERIP_APPWORD_INITVALUE which means hardware
+ * has not completed updating the BD structure.
+ * - RingPtr->HwTail is reached
+ * - The number of requested BDs has been processed
+ */
+ while (BdCount < BdLimit) {
+ /* Read the status */
+ XLLDMA_CACHE_INVALIDATE(CurBdPtr);
+ BdStsCr = XLlDma_mBdRead(CurBdPtr,
+ XLLDMA_BD_STSCTRL_USR0_OFFSET);
+
+ /* If the hardware still hasn't processed this BD then we are
+ * done
+ */
+ if (!(BdStsCr & XLLDMA_BD_STSCTRL_COMPLETED_MASK)) {
+ break;
+ }
+
+ /* In RX channel case, check if XLLDMA_USERIP_APPWORD_OFFSET
+ * field of the BD has been updated. If not, RX channel has
+ * not completed updating the BD structure and we delay
+ * the processing of this BD to next time
+ */
+ if (RingPtr->IsRxChannel) {
+ UserIpAppWord = XLlDma_mBdRead(CurBdPtr,
+ XLLDMA_USERIP_APPWORD_OFFSET);
+ if (UserIpAppWord == XLLDMA_USERIP_APPWORD_INITVALUE) {
+ 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 (BdStsCr & XLLDMA_BD_STSCTRL_EOP_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 = XLlDma_mBdRingNext(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) {
+ *BdSetPtr = RingPtr->HwHead;
+ RingPtr->HwCnt -= BdCount;
+ RingPtr->PostCnt += BdCount;
+ XLLDMA_RING_SEEKAHEAD(RingPtr, RingPtr->HwHead, BdCount);
+ return (BdCount);
+ }
+ else {
+ *BdSetPtr = NULL;
+ return (0);
+ }
+}
+
+
+/*****************************************************************************/
+/**
+ * Frees a set of BDs that had been previously retrieved with
+ * XLlDma_BdRingFromHw().
+ *
+ * @param RingPtr is a pointer to the descriptor ring 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
+ * XLlDma_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
+ * XLlDma_BdRingFromHw().
+ *
+ * @note This function should not be preempted by another XLlDma function call
+ * that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ * @internal
+ * This Interrupt handler provided by application MUST clear pending
+ * interrupts before handling them by calling the call back. Otherwise
+ * the following corner case could raise some issue:
+ *
+ * - A packet was transmitted and asserted an TX interrupt, and if
+ * this interrupt handler calls the call back before clears the
+ * interrupt, another packet could get transmitted (and assert the
+ * interrupt) between when the call back function returned and when
+ * the interrupt clearing operation begins, and the interrupt
+ * clearing operation will clear the interrupt raised by the second
+ * packet and won't never process its according buffer descriptors
+ * until a new interrupt occurs.
+ *
+ * Changing the sequence to "Clear interrupts, then handle" solve this
+ * issue. If the interrupt raised by the second packet is before the
+ * the interrupt clearing operation, the descriptors associated with
+ * the second packet must have been finished by hardware and ready for
+ * the handling by the call back; otherwise, the interrupt raised by
+ * the second packet is after the interrupt clearing operation,
+ * the packet's buffer descriptors will be handled by the call back in
+ * current pass, if the descriptors are finished before the call back
+ * is invoked, or next pass otherwise.
+ *
+ * Please note that if the second packet is handled by the call back
+ * in current pass, the next pass could find no buffer descriptor
+ * finished by the hardware. (i.e., XLlDma_BdRingFromHw() returns 0).
+ * As XLlDma_BdRingFromHw() and XLlDma_BdRingFree() are used in pair,
+ * XLlDma_BdRingFree() covers this situation by checking if the BD
+ * list to free is empty
+ *****************************************************************************/
+int XLlDma_BdRingFree(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_Bd * BdSetPtr)
+{
+ /* If the BD Set to free is empty, return immediately with value
+ * XST_SUCCESS. See the @internal comment block above for detailed
+ * information
+ */
+ if (NumBd == 0) {
+ return XST_SUCCESS;
+ }
+
+ /* Make sure we are in sync with XLlDma_BdRingFromHw() */
+ if ((RingPtr->PostCnt < NumBd) || (RingPtr->PostHead != BdSetPtr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Update pointers and counters */
+ RingPtr->FreeCnt += NumBd;
+ RingPtr->PostCnt -= NumBd;
+ XLLDMA_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 descriptor ring to be worked on.
+ *
+ * @return
+ * - XST_SUCCESS if no errors were found.
+ * - XST_DMA_SG_NO_LIST if the ring 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 XLlDma ring function
+ * call that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ *****************************************************************************/
+int XLlDma_BdRingCheck(XLlDma_BdRing * RingPtr)
+{
+ u32 AddrV, AddrP;
+ unsigned i;
+
+ /* 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->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->PreHead;
+ if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->HwHead;
+ if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->HwTail;
+ if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->PostHead;
+ if ((AddrV < RingPtr->FirstBdAddr) || (AddrV > RingPtr->LastBdAddr)) {
+ 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->FirstBdAddr;
+ AddrP = RingPtr->FirstBdPhysAddr + RingPtr->Separation;
+ for (i = 1; i < RingPtr->AllCnt; i++) {
+ XLLDMA_CACHE_INVALIDATE(AddrV);
+ /* Check next pointer for this BD. It should equal to the
+ * physical address of next BD
+ */
+ if (XLlDma_mBdRead(AddrV, XLLDMA_BD_NDESC_OFFSET) != AddrP) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Move on to next BD */
+ AddrV += RingPtr->Separation;
+ AddrP += RingPtr->Separation;
+ }
+
+ XLLDMA_CACHE_INVALIDATE(AddrV);
+ /* Last BD should point back to the beginning of ring */
+ if (XLlDma_mBdRead(AddrV, XLLDMA_BD_NDESC_OFFSET) !=
+ RingPtr->FirstBdPhysAddr) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* No problems found */
+ return (XST_SUCCESS);
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo_hw.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo_hw.h
@@ -0,0 +1,211 @@
+/* $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 2004-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file llfifo_hw.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the xps_ll_fifo core.
+* High-level driver functions are defined in xpfifo.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a jvb 10/16/06 First release.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLFIFO_HW_H /* prevent circular inclusions */
+#define XLLFIFO_HW_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xdebug.h"
+
+/************************** Constant Definitions *****************************/
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+/** @name Registers
+ * @{
+ */
+#define XLLF_ISR_OFFSET 0x00000000 /**< Interrupt Status */
+#define XLLF_IER_OFFSET 0x00000004 /**< Interrupt Enable */
+
+#define XLLF_TDFR_OFFSET 0x00000008 /**< Transmit Reset */
+#define XLLF_TDFV_OFFSET 0x0000000c /**< Transmit Vacancy */
+#define XLLF_TDFD_OFFSET 0x00000010 /**< Transmit Data */
+#define XLLF_TLF_OFFSET 0x00000014 /**< Transmit Length */
+
+#define XLLF_RDFR_OFFSET 0x00000018 /**< Receive Reset */
+#define XLLF_RDFO_OFFSET 0x0000001c /**< Receive Occupancy */
+#define XLLF_RDFD_OFFSET 0x00000020 /**< Receive Data */
+#define XLLF_RLF_OFFSET 0x00000024 /**< Receive Length */
+#define XLLF_LLR_OFFSET 0x00000028 /**< Local Link Reset */
+
+/*@}*/
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the HW spec.
+ */
+
+/** @name Interrupt bits
+ * These bits are associated with the XLLF_IER_OFFSET and XLLF_ISR_OFFSET
+ * registers.
+ * @{
+ */
+#define XLLF_INT_RPURE_MASK 0x80000000 /**< Receive under-read */
+#define XLLF_INT_RPORE_MASK 0x40000000 /**< Receive over-read */
+#define XLLF_INT_RPUE_MASK 0x20000000 /**< Receive underrun (empty) */
+#define XLLF_INT_TPOE_MASK 0x10000000 /**< Transmit overrun */
+#define XLLF_INT_TC_MASK 0x08000000 /**< Transmit complete */
+#define XLLF_INT_RC_MASK 0x04000000 /**< Receive complete */
+#define XLLF_INT_TSE_MASK 0x02000000 /**< Transmit length mismatch */
+#define XLLF_INT_TRC_MASK 0x01000000 /**< Transmit reset complete */
+#define XLLF_INT_RRC_MASK 0x00800000 /**< Receive reset complete */
+#define XLLF_INT_ALL_MASK 0xff800000 /**< All the ints */
+#define XLLF_INT_ERROR_MASK 0xf2000000 /**< Error status ints */
+#define XLLF_INT_RXERROR_MASK 0xe0000000 /**< Receive Error status ints */
+#define XLLF_INT_TXERROR_MASK 0x12000000 /**< Transmit Error status ints */
+/*@}*/
+
+/** @name Reset register values
+ * These bits are associated with the XLLF_TDFR_OFFSET and XLLF_RDFR_OFFSET
+ * reset registers.
+ * @{
+ */
+#define XLLF_RDFR_RESET_MASK 0x000000a5 /**< receive reset value */
+#define XLLF_TDFR_RESET_MASK 0x000000a5 /**< Transmit reset value */
+#define XLLF_LLR_RESET_MASK 0x000000a5 /**< Local Link reset value */
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/**** debug macros ****/
+#define XLlFifo_reg_name(RegOffset) \
+ (((RegOffset) == XLLF_ISR_OFFSET) ? "ISR": \
+ ((RegOffset) == XLLF_IER_OFFSET) ? "IER": \
+ ((RegOffset) == XLLF_TDFR_OFFSET) ? "TDFR {tx reset}": \
+ ((RegOffset) == XLLF_TDFV_OFFSET) ? "TDFV {tx vacancy}": \
+ ((RegOffset) == XLLF_TDFD_OFFSET) ? "TDFD {tx data}": \
+ ((RegOffset) == XLLF_TLF_OFFSET) ? "TLF {tx length}": \
+ ((RegOffset) == XLLF_RDFR_OFFSET) ? "RDFR {rx reset}": \
+ ((RegOffset) == XLLF_RDFO_OFFSET) ? "RDFO {rx occupancy}": \
+ ((RegOffset) == XLLF_RDFD_OFFSET) ? "RDFD {rx data}": \
+ ((RegOffset) == XLLF_RLF_OFFSET) ? "RLF {rx length}": \
+ "unknown")
+
+#define XLlFifo_print_reg_o(BaseAddress, RegOffset, Value) \
+ xdbg_printf(XDBG_DEBUG_FIFO_REG, "0x%08x -> %s(0x%08x)\n", (Value), \
+ XLlFifo_reg_name(RegOffset), \
+ (RegOffset) + (BaseAddress))
+
+#define XLlFifo_print_reg_i(BaseAddress, RegOffset, Value) \
+ xdbg_printf(XDBG_DEBUG_FIFO_REG, "%s(0x%08x) -> 0x%08x\n", \
+ XLlFifo_reg_name(RegOffset), \
+ (RegOffset) + (BaseAddress), (Value))
+/**** end debug macros ****/
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_ReadReg returns the value of the register at the offet,
+* <i>RegOffset</i>, from the memory mapped base address, <i>BaseAddress</i>.
+*
+* @param BaseAddress specifies the base address of the device.
+*
+* @param RegOffset specifies the offset from BaseAddress.
+*
+* @return XLlFifo_ReadReg returns the value of the specified register.
+*
+* @note
+* C-style signature:
+* u32 XLlFifo_ReadReg(u32 BaseAddress, u32 RegOffset)
+*
+*****************************************************************************/
+#ifdef DEBUG
+extern u32 _xllfifo_rr_value;
+#define XLlFifo_ReadReg(BaseAddress, RegOffset) \
+ ((((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \
+ "XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \
+ (RegOffset)) : 0), \
+ _xllfifo_rr_value = XIo_In32((BaseAddress) + (RegOffset)), \
+ XLlFifo_print_reg_i((BaseAddress), (RegOffset), _xllfifo_rr_value), \
+ _xllfifo_rr_value)
+#else
+#define XLlFifo_ReadReg(BaseAddress, RegOffset) \
+ (XIo_In32((BaseAddress) + (RegOffset)))
+#endif
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_WriteReg writes the value, <i>Value</i>, to the register at the
+* offet, <i>RegOffset</i>, from the memory mapped base address,
+* <i>BaseAddress</i>.
+*
+* @param BaseAddress specifies the base address of the device.
+*
+* @param RegOffset specifies the offset from BaseAddress.
+*
+* @param Value is value to write to the register.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlFifo_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Value)
+*
+*****************************************************************************/
+#ifdef DEBUG
+#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \
+ (((RegOffset) > 0x24) ? xdbg_printf(XDBG_DEBUG_ERROR, \
+ "XLlFifo_WriteReg: Woah! wrong reg addr: 0x%08x\n", \
+ (RegOffset)) : 0), \
+ XLlFifo_print_reg_o((BaseAddress), (RegOffset), (Value)), \
+ (XIo_Out32((BaseAddress) + (RegOffset), (Value)))
+#else
+#define XLlFifo_WriteReg(BaseAddress, RegOffset, Value) \
+ ((XIo_Out32((BaseAddress) + (RegOffset), (Value))))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* XLLFIFO_HW_H end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3.h
@@ -0,0 +1,515 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3.h
+*
+* The Xilinx Simple and Scatter Gather DMA driver. This component supports a
+* distributed DMA design in which each device can have it's own dedicated DMA
+* channel, as opposed to a centralized DMA design. A device which uses DMA
+* typically contains two DMA channels, one for sending data and the other for
+* receiving data.
+*
+* This component is designed to be used as a basic building block for
+* designing a device driver. It provides registers accesses such that all
+* DMA processing can be maintained easier, but the device driver designer
+* must still understand all the details of the DMA channel.
+*
+* For a full description of DMA features, please see the HW spec. This driver
+* supports the following features:
+* - Simple DMA
+* - Scatter-Gather DMA (SGDMA)
+* - Interrupts
+* - Programmable interrupt coalescing for SGDMA
+* - 36 Bit bus addressing
+* - Programmable transaction types
+* - APIs to manage Buffer Descriptors (BD) movement to and from the SGDMA
+* engine
+* - Virtual memory support
+*
+* <b>Transactions</b>
+*
+* To describe a DMA transaction in its simplest form, you need a source address,
+* destination address, and the number of bytes to transfer. When using a DMA
+* receive channel, the source address is within some piece of IP HW and doesn't
+* require the user explicitly set it. Likewise with a transmit channel and the
+* destination address. So this leaves a user buffer address and the number
+* bytes to transfer as the primary transaction attributes. There are more
+* obscure attributes such as:
+*
+* - Is the user buffer a fixed address FIFO or a range of memory
+* - The size of the data bus over which the transaction occurs.
+* - Does the transfer use single beat or bursting capabilities of the
+* bus over which the transaction occurs.
+* - If the transaction occurs on a bus wider than 32 bits, what are the
+* highest order address bits.
+* - If SGDMA, does this transaction represent the end of a packet.
+*
+* The object used to describe a transaction is referred to as a Buffer
+* Descriptor (BD). The format of a BD closely matches that of the DMA HW.
+* Many fields within the BD correspond directly with the same fields within the
+* HW registers. See xdmabdv3.h for a detailed description of and the API for
+* manipulation of these objects.
+*
+* <b>Simple DMA</b>
+*
+* Simple DMA is a single transaction type of operation. The user uses this
+* driver to setup a transaction, initiate the transaction, then either wait for
+* an interrupt or poll the HW for completion of the transaction. A new
+* transaction may not be initiated until the current one completes.
+*
+* <b>Scatter-Gather DMA</b>
+*
+* SGDMA is more sophisticated in that it allows the user to define a list of
+* transactions in memory which the HW will process without further user
+* intervention. During this time, the user is free to continue adding more work
+* to keep the HW busy.
+*
+* Notification of completed transactions can be done either by polling the HW,
+* or using interrupts that signal a transaction has completed or a series of
+* transactions have been processed.
+*
+* SGDMA processes in units of packets. A packet is defined as a series of
+* data bytes that represent a message. SGDMA allows a packet of data to be
+* broken up into one or more transactions. For example, take an Ethernet IP
+* packet which consists of a 14 byte header followed by a 1 or more byte
+* payload. With SGDMA, the user may point a BD to the header and another BD to
+* the payload, then transfer them as a single message. This strategy can make a
+* TCP/IP stack more efficient by allowing it to keep packet headers and data in
+* different memory regions instead of assembling packets into contiguous blocks
+* of memory.
+*
+* <b>Interrupt Coalescing</b>
+*
+* SGDMA provides control over the frequency of interrupts. On a high speed link
+* significant processor overhead may be used servicing interrupts. Interrupt
+* coalescing provides two mechanisms that help control interrupt frequency.
+*
+* The packet threshold will hold off interrupting the CPU until a programmable
+* number of packets have been processed by the engine. The packet waitbound
+* timer is used to interrupt the CPU if after a programmable amount of time
+* after processing the last packet, no new packets were processed.
+*
+* <b>Interrupts</b>
+*
+* This driver does not service interrupts. This is done typically within
+* a higher level driver that uses DMA. This driver does provide an API to
+* enable or disable specific interrupts.
+*
+* <b>SGDMA List Management</b>
+*
+* The HW expectes BDs to be setup as a singly linked list. As BDs are completed,
+* the DMA engine will dereference BD.Next and load the next BD to process.
+* This driver uses a fixed buffer ring where all BDs are linked to the next
+* adjacent BD in memory. The last BD in the ring is linked to the first.
+*
+* Within the BD ring, the driver maintains four groups of BDs. Each group
+* consists of 0 or more adjacent BDs:
+*
+* - Free group: Those BDs that can be allocated by the user with
+* XDmaV3_SgBdAlloc(). These BDs are under driver control.
+*
+* - Pre-work group: Those BDs that have been allocated with
+* XDmaV3_SgBdAlloc(). These BDs are under user control. The user modifies
+* these BDs in preparation for future DMA transactions.
+*
+* - Work group: Those BDs that have been enqueued to HW with
+* XDmaV3_SgBdToHw(). These BDs are under HW control and may be in a
+* state of awaiting HW processing, in process, or processed by HW.
+*
+* - Post-work group: Those BDs that have been processed by HW and have been
+* extracted from the work group with XDmaV3_SgBdFromHw(). These BDs are under
+* user control. The user may access these BDs to determine the result
+* of DMA transactions. When the user is finished, XDmaV3_SgBdFree() should
+* be called to place them back into the Free group.
+*
+* It is considered an error for the user to change BDs while they are in the
+* Work group. Doing so can cause data corruption and lead to system instability.
+*
+* The API provides macros that allow BD list traversal. These macros should be
+* used with care as they do not understand where one group ends and another
+* begins.
+*
+* The driver does not cache or keep copies of any BD. When the user modifies
+* BDs returned by XDmaV3_SgBdAlloc() or XDmaV3_SgBdFromHw(), they are modifying
+* the same BD list that HW accesses.
+*
+* Certain pairs of list modification functions have usage restrictions. See
+* the function headers for XDmaV3_SgBdAlloc() and XDmaV3_SgBdFromHw() for
+* more information.
+*
+* <b>SGDMA List Creation</b>
+*
+* During initialization, the function XDmaV3_SgListCreate() is used to setup
+* a user supplied memory block to contain all BDs for the DMA channel. This
+* function takes as an argument the number of BDs to place in the list. To
+* arrive at this number, the user is given two methods of calculating it.
+*
+* The first method assumes the user has a block of memory and they just
+* want to fit as many BDs as possible into it. The user must calculate the
+* number of BDs that will fit with XDmaV3_mSgListCntCalc(), then supply that
+* number into the list creation function.
+*
+* The second method allows the user to just supply the number directly. The
+* driver assumes the memory block is large enough to contain them all. To
+* double-check, the user should invoke XDmaV3_mSgListMemCalc() to verify the
+* memory block is adequate.
+*
+* Once the list has been created, it can be used right away to perform DMA
+* transactions. However, there are optional steps that can be done to increase
+* throughput and decrease user code complexity by the use of XDmaV3_SgListClone().
+*
+* BDs have many user accessible attributes that affect how DMA transactions are
+* carried out. Many of these attributes (such as the bus width) will probably
+* be constant at run-time. The cloning function can be used to copy a template
+* BD to every BD in the list relieving the user of having to setup transactions
+* from scratch every time a BD is submitted to HW.
+*
+* Ideally, the only transaction parameters that need to be set at run-time
+* should be: buffer address, bytes to transfer, and whether the BD is the
+* "Last" BD of a packet.
+*
+* <b>Adding / Removing BDs from the SGDMA Engine</b>
+*
+* BDs may be enqueued (see XDmaV3_SgBdToHw()) to the engine any time after
+* the SGDMA list is created. If the channel is running (see XDmaV3_SgStart()),
+* then newly added BDs will be processed as soon as the engine reaches them.
+* If the channel is stopped (see XDmaV3_SgStop()), the newly added BDs will
+* be accepted but not processed by the engine until it is restarted.
+*
+* Processed BDs may be removed (see XDmaV3_SgBdFromHw()) at any time
+* after the SGDMA list is created provided the engine has processed any.
+*
+* <b>Address Translation</b>
+*
+* When the BD list is setup with XDmaV3_SgListCreate(), a physical and
+* virtual address is supplied for the segment of memory containing the
+* descriptors. The driver will handle any translations internally. Subsequent
+* access of descriptors by the user is done in terms of the virtual address.
+*
+* <b>Alignment</b>
+*
+* Except for 4 byte alignment of BDs there are no other alignment restrictions
+* imposed by this driver. Individual DMA channels may, based on their
+* capabilities or which bus they are a master of, have more stringent alignment
+* requirements. It is up to the user to match the requirements of the DMA
+* channel being used.
+*
+* Aside from the initial creation of BD list (see XDmaV3_SgListCreate()),
+* there are no other run-time checks for proper alignment. Misaligned user
+* buffers or BDs may result in corrupted data.
+*
+* <b>Cache Coherency</b>
+*
+* This driver expects all user buffers attached to BDs to be in cache coherent
+* memory. Buffers for transmit should be flushed from the cache before passing
+* the associated BD to this driver. Buffers for receive should be invalidated
+* before being accessed.
+*
+* If the user wishes that the BD space itself be in cached memory, then
+* modification of this driver is required. The driver helps the user in
+* this area by: 1) Allowing the user to specify what alignment BDs should
+* use (ie. aligned along cache lines); 2) Provide unimplemented invalidate/flush
+* macro placeholders in the driver source code where needed.
+*
+* <b>Reset After Stopping</b>
+*
+* This driver is designed to allow for stop-reset-start cycles of the DMA
+* HW while keeping the BD list intact. When restarted after a reset, this
+* driver will point the DMA engine to where it left off after stopping it.
+*
+* <b>Limitations</b>
+*
+* This driver requires exclusive use of the hardware DMACR.SGS bit. This
+* applies to the actual HW register and BDs submitted through this driver to
+* be processed. If a BD is encountered with this bit set, then it will be
+* cleared within the driver.
+*
+* This driver does not have any mechanism for mutual exclusion. It is up to the
+* user to provide this protection.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 3.00a rmm 03/11/06 First release
+* rmm 06/22/06 Added extern "C"
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XDMAV3_H /* prevent circular inclusions */
+#define XDMAV3_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xdmabdv3.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/* Minimum alignment */
+#define XDMABDV3_MINIMUM_ALIGNMENT 4
+
+
+/**************************** Type Definitions *******************************/
+
+/** This is an internal structure used to maintain the SGDMA list */
+typedef struct {
+ u32 PhysBaseAddr;
+ /**< Physical address of 1st BD in list */
+ u32 BaseAddr; /**< Virtual address of 1st BD in list */
+ u32 HighAddr; /**< Virtual address of last BD in the list */
+ u32 Length; /**< Total size of ring in bytes */
+ u32 RunState; /**< Flag to indicate SGDMA is started */
+ u32 Separation;/**< Number of bytes between the starting address
+ of adjacent BDs */
+ XDmaBdV3 *FreeHead;/**< First BD in the free group */
+ XDmaBdV3 *PreHead; /**< First BD in the pre-work group */
+ XDmaBdV3 *HwHead; /**< First BD in the work group */
+ XDmaBdV3 *HwTail; /**< Last BD in the work group */
+ XDmaBdV3 *PostHead;/**< First BD in the post-work group */
+ XDmaBdV3 *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 */
+} XDmaV3_BdRing;
+
+/**
+ * The XDmaV3 driver instance data. An instance must be allocated for each DMA
+ * channel in use. If address translation is enabled, then all addresses and
+ * pointers excluding PhysBase are expressed in terms of the virtual address.
+ */
+typedef struct XDmaV3 {
+ u32 RegBase; /**< Base address of channel registers */
+ u32 IsReady; /**< Flag to indicate device is ready to use */
+ XDmaV3_BdRing BdRing; /**< BD storage for SGDMA */
+} XDmaV3;
+
+
+/***************** 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 XDmaV3_SgListCreate().
+*
+* @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, 126,...)
+* @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 XDmaV3_mSgListCntCalc(u32 Alignment, u32 Bytes)
+*
+******************************************************************************/
+#define XDmaV3_mSgListCntCalc(Alignment, Bytes) \
+ (u32)((Bytes) / ((sizeof(XDmaBdV3) + ((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 XDmaV3_mSgListMemCalc(u32 Alignment, u32 NumBd)
+*
+******************************************************************************/
+#define XDmaV3_mSgListMemCalc(Alignment, NumBd) \
+ (u32)((sizeof(XDmaBdV3) + ((Alignment)-1)) & ~((Alignment)-1)) * (NumBd)
+
+
+/****************************************************************************/
+/**
+* Return the total number of BDs allocated by this channel with
+* XDmaV3_SgListCreate().
+*
+* @param InstancePtr is the DMA channel to operate on.
+*
+* @return The total number of BDs allocated for this channel.
+*
+* @note
+* C-style signature:
+* u32 XDmaBdV3_mSgGetCnt(XDmaV3* InstancePtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgGetCnt(InstancePtr) ((InstancePtr)->BdRing.AllCnt)
+
+
+/****************************************************************************/
+/**
+* Return the number of BDs allocatable with XDmaV3_SgBdAlloc() for pre-
+* processing.
+*
+* @param InstancePtr is the DMA channel to operate on.
+*
+* @return The number of BDs currently allocatable.
+*
+* @note
+* C-style signature:
+* u32 XDmaBdV3_mSgGetFreeCnt(XDmaV3* InstancePtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgGetFreeCnt(InstancePtr) ((InstancePtr)->BdRing.FreeCnt)
+
+
+/****************************************************************************/
+/**
+* Return the next BD 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:
+* XDmaBdV3 *XDmaV3_mSgBdNext(XDmaV3* InstancePtr, XDmaBdV3 *BdPtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgBdNext(InstancePtr, BdPtr) \
+ (((u32)(BdPtr) >= (InstancePtr)->BdRing.HighAddr) ? \
+ (XDmaBdV3*)(InstancePtr)->BdRing.BaseAddr : \
+ (XDmaBdV3*)((u32)(BdPtr) + (InstancePtr)->BdRing.Separation))
+
+
+/****************************************************************************/
+/**
+* Return the previous BD 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:
+* XDmaBdV3 *XDmaV3_mSgBdPrev(XDmaV3* InstancePtr, XDmaBdV3 *BdPtr)
+*
+*****************************************************************************/
+#define XDmaV3_mSgBdPrev(InstancePtr, BdPtr) \
+ (((u32)(BdPtr) <= (InstancePtr)->BdRing.BaseAddr) ? \
+ (XDmaBdV3*)(InstancePtr)->BdRing.HighAddr : \
+ (XDmaBdV3*)((u32)(BdPtr) - (InstancePtr)->BdRing.Separation))
+
+
+/****************************************************************************/
+/**
+* Retrieve the current contents of the DMASR register. This macro can be
+* used to poll the DMA HW for completion of a transaction.
+*
+* @param InstancePtr is the DMA channel to operate on.
+*
+* @return The current contents of the DMASR register.
+*
+* @note
+* C-style signature:
+* u32 XDmaV3_mGetStatus(XDmaV3* InstancePtr)
+*
+*****************************************************************************/
+#define XDmaV3_mGetStatus(InstancePtr) \
+ XDmaV3_mReadReg((InstancePtr)->RegBase, XDMAV3_DMASR_OFFSET)
+
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization and control functions in xdmav3.c
+ */
+int XDmaV3_Initialize(XDmaV3 * InstancePtr, u32 BaseAddress);
+
+/*
+ * Interrupt related functions in xdmav3_intr.c
+ */
+void XDmaV3_SetInterruptStatus(XDmaV3 * InstancePtr, u32 Mask);
+u32 XDmaV3_GetInterruptStatus(XDmaV3 * InstancePtr);
+void XDmaV3_SetInterruptEnable(XDmaV3 * InstancePtr, u32 Mask);
+u32 XDmaV3_GetInterruptEnable(XDmaV3 * InstancePtr);
+
+/*
+ * Simple DMA related functions in xdmav3_simple.c
+ */
+int XDmaV3_SimpleTransfer(XDmaV3 * InstancePtr, XDmaBdV3 * Bdptr);
+
+/*
+ * Scatter gather DMA related functions in xdmav3_sg.c
+ */
+int XDmaV3_SgStart(XDmaV3 * InstancePtr);
+void XDmaV3_SgStop(XDmaV3 * InstancePtr);
+int XDmaV3_SgSetPktThreshold(XDmaV3 * InstancePtr, u16 Threshold);
+int XDmaV3_SgSetPktWaitbound(XDmaV3 * InstancePtr, u16 TimerVal);
+u16 XDmaV3_SgGetPktThreshold(XDmaV3 * InstancePtr);
+u16 XDmaV3_SgGetPktWaitbound(XDmaV3 * InstancePtr);
+
+int XDmaV3_SgListCreate(XDmaV3 * InstancePtr, u32 PhysAddr,
+ u32 VirtAddr, u32 Alignment, unsigned BdCount);
+int XDmaV3_SgListClone(XDmaV3 * InstancePtr, XDmaBdV3 * SrcBdPtr);
+int XDmaV3_SgCheck(XDmaV3 * InstancePtr);
+int XDmaV3_SgBdAlloc(XDmaV3 * InstancePtr, unsigned NumBd,
+ XDmaBdV3 ** BdSetPtr);
+int XDmaV3_SgBdUnAlloc(XDmaV3 * InstancePtr, unsigned NumBd,
+ XDmaBdV3 * BdSetPtr);
+int XDmaV3_SgBdToHw(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr);
+int XDmaV3_SgBdFree(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr);
+unsigned XDmaV3_SgBdFromHw(XDmaV3 * InstancePtr, unsigned BdLimit,
+ XDmaBdV3 ** BdSetPtr);
+
+/*
+ * Selftest functions in xdmav3_selftest.c
+ */
+int XDmaV3_SelfTest(XDmaV3 * InstancePtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xllfifo.h
@@ -0,0 +1,567 @@
+/* $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 2005-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file llfifo.h
+ *
+ * The Xilinx Dual Channel Fifo driver component. This driver supports the
+ * Virtex-5(TM) and Virtex-4(TM) XPS_ll_Fifo.
+ *
+ * For a full description of the bridge features, please see the HW spec. This driver
+ * supports the following features:
+ * - Memory mapped access to host interface registers
+ * - API for polled frame transfers
+ * - API for interrupt driven frame transfers
+ * - Virtual memory support
+ * - Full duplex operation
+ *
+ * <h2>Driver Description</h2>
+ *
+ * This driver enables higher layer software to access the XPS_llFifo core
+ * using any alignment in the data buffers.
+ *
+ * This driver supports send and receive channels in the same instance
+ * structure in the same fashion as the hardware core.
+ *
+ * <h2>Initialization</h2>
+ *
+ * An instance of this driver is initialized using a call to Initialize().
+ *
+ * <h2>Usage</h2>
+ *
+ * It is fairly simple to use the API provided by this FIFO driver. The
+ * only somewhat tricky part is that the calling code must correctly call
+ * a couple routines in the right sequence for receive and transmit.
+ *
+ * This sequence is described here. Check the routine functional
+ * descriptions for information on how to use a specific API routine.
+ *
+ * <h3>Receive</h3>
+ *
+ * A frame is received by using the following sequence:<br>
+ * 1) call XLlFifo_RxGetLen() to get the length of the next incoming frame<br>
+ * 2) call XLlFifo_Read() one or more times to read the number of bytes
+ * reported by XLlFifo_RxGetLen().<br>
+ *
+ * For example:
+ * <pre>
+ * frame_len = XLlFifo_RxGetLen(&RxInstance);
+ * while (frame_len) {
+ * unsigned bytes = min(sizeof(buffer), frame_len);
+ * XLlFifo_Read(&RxInstance, buffer, bytes);
+ * // ********
+ * // do something with buffer here
+ * // ********
+ * frame_len -= bytes;
+ * }
+ * </pre>
+ *
+ * This FIFO hardware core does <b>not</b> support a sequence where the
+ * calling code calls RxGetLen() twice in a row and then receive the data
+ * for two frames. Each frame must be read in by calling RxGetLen() just
+ * prior to reading the data.
+ *
+ * <h3>Transmit</h3>
+ * A frame is transmittted by using the following sequence:<br>
+ * 1) call XLlFifo_Write() one or more times to write all the of bytes in
+ * the next frame.<br>
+ * 2) call XLlFifo_TxSetLen() to begin the transmission of frame just
+ * written.<br>
+ *
+ * For example:
+ * <pre>
+ * frame_left = frame_len;
+ * while (frame_left) {
+ * unsigned bytes = min(sizeof(buffer), frame_left);
+ * XLlFifo_Write(&TxInstance, buffer, bytes);
+ * // ********
+ * // do something here to refill buffer
+ * // ********
+ * }
+ * XLlFifo_TxSetLen(&RxInstance, frame_len);
+ * </pre>
+ *
+ * This FIFO hardware core does <b>not</b> support a sequence where the
+ * calling code writes the data for two frames and then calls TxSetLen()
+ * twice in a row. Each frame must be written by writting the data for one
+ * frame and then calling TxSetLen().
+ *
+ * <h2>Interrupts</h2>
+ * This driver does not handle interrupts from the FIFO hardware. The
+ * software layer above may make use of the interrupts by setting up its
+ * own handlers for the interrupts.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 10/12/06 First release
+ * </pre>
+ *
+ *****************************************************************************/
+#ifndef XLLFIFO_H /* prevent circular inclusions */
+#define XLLFIFO_H /* by using preprocessor symbols */
+
+/* force C linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xllfifo_hw.h"
+#include "xstreamer.h"
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * This typedef defines a run-time instance of an XLlFifo device.
+ */
+typedef struct XLlFifo {
+ u32 BaseAddress; /**< BaseAddress is the physical base address of the
+ * device's registers
+ */
+
+ u32 IsReady; /**< IsReady is non-zero if the driver instance
+ * has been initialized.
+ */
+ XStrm_RxFifoStreamer RxStreamer; /**< RxStreamer is the byte streamer
+ * instance for the receive channel.
+ */
+ XStrm_TxFifoStreamer TxStreamer; /**< TxStreamer is the byte streamer
+ * instance for the transmit channel.
+ */
+} XLlFifo;
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_Reset resets both the Tx and Rx channels and the local link interface
+* the FIFO specified by <i>InstancePtr</i>. XLlFifo_TxReset resets also sends a
+* reset pulse to the downstream device (e.g. TEMAC). XLlFifo_Reset drops any
+* bytes in the FIFO not yet retrieved. XLlFifo_Reset drops any bytes in the FIFO
+* not yet transmitted.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlFifo_Reset(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_Reset(InstancePtr) \
+ XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_LLR_OFFSET, \
+ XLLF_LLR_RESET_MASK)
+
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_Status returns a bit mask of the interrupt status register (ISR)
+* for the FIFO specified by <i>InstancePtr</i>. XLlFifo_Status can be used
+* to query the status of the FIFO without having to have interrupts enabled.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_IntStatus returns a bit mask of the status conditions.
+* The mask will be a set of bitwise or'd values from the
+* <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+* u32 XLlFifo_IntStatus(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_Status(InstancePtr) \
+ XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntEnable enables the interrupts specified in <i>Mask</i> for the
+* FIFO specified by <i>InstancePtr</i>. The corresponding interrupt for each bit
+* set to 1 in <i>Mask</i>, will be enabled.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param Mask contains a bit mask of the interrupts to enable. The mask
+* can be formed using a set of bitwise or'd values from the
+* <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlFifo_IntEnable(XLlFifo *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlFifo_IntEnable(InstancePtr, Mask) \
+{ \
+ u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \
+ XLLF_IER_OFFSET); \
+ Reg |= ((Mask) & XLLF_INT_ALL_MASK); \
+ XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \
+ Reg); \
+}
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntDisable disables the interrupts specified in <i>Mask</i> for the
+* FIFO specified by <i>InstancePtr</i>. The corresponding interrupt for each bit
+* set to 1 in <i>Mask</i>, will be disabled. In other words, XLlFifo_IntDisable
+* uses the "set a bit to clear it" scheme.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param Mask contains a bit mask of the interrupts to disable. The mask
+* can be formed using a set of bitwise or'd values from the
+* <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlFifo_IntDisable(XLlFifo *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlFifo_IntDisable(InstancePtr, Mask) \
+{ \
+ u32 Reg = XLlFifo_ReadReg((InstancePtr)->BaseAddress, \
+ XLLF_IER_OFFSET); \
+ Reg &= ~((Mask) & XLLF_INT_ALL_MASK); \
+ XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET, \
+ Reg); \
+}
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntPending returns a bit mask of the pending interrupts for the
+* FIFO specified by <i>InstancePtr</i>. Each bit set to 1 in the return value
+* represents a pending interrupt.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_IntPending returns a bit mask of the interrupts that are
+* pending. The mask will be a set of bitwise or'd values from the
+* <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+* u32 XLlFifo_IntPending(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#ifdef DEBUG
+extern u32 _xllfifo_ipie_value;
+extern u32 _xllfifo_ipis_value;
+#define XLlFifo_IntPending(InstancePtr) \
+ (_xllfifo_ipie_value = XLlFifo_ReadReg( \
+ (InstancePtr)->BaseAddress, XLLF_IER_OFFSET), \
+ _xllfifo_ipis_value = XLlFifo_ReadReg( \
+ (InstancePtr)->BaseAddress, XLLF_ISR_OFFSET), \
+ (_xllfifo_ipie_value & _xllfifo_ipis_value))
+#else
+#define XLlFifo_IntPending(InstancePtr) \
+ (XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_IER_OFFSET) & \
+ XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET))
+#endif
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IntClear clears pending interrupts specified in <i>Mask</i> for the
+* FIFO specified by <i>InstancePtr</i>. The corresponding pending interrupt for
+* each bit set to 1 in <i>Mask</i>, will be cleared. In other words,
+* XLlFifo_IntClear uses the "set a bit to clear it" scheme.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param Mask contains a bit mask of the pending interrupts to clear. The
+* mask can be formed using a set of bitwise or'd values from the
+* <code>XLLF_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+* void XLlFifo_IntClear(XLlFifo *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlFifo_IntClear(InstancePtr, Mask) \
+ XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET, \
+ ((Mask) & XLLF_INT_ALL_MASK))
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_RxReset resets the receive channel of the FIFO specified by
+* <i>InstancePtr</i>. XLlFifo_RxReset drops any bytes in the FIFO not yet
+* retrieved.
+*
+* The calling software may want to test for the completion of the reset by
+* reading the interrupt status (IS) register and testing for the Rx Reset
+* complete (RRC) bit.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlFifo_RxReset(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_RxReset(InstancePtr) \
+ XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_RDFR_OFFSET, \
+ XLLF_RDFR_RESET_MASK)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IsRxEmpty returns true if the receive channel of the FIFO, specified
+* by <i>InstancePtr</i>, is empty.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_IsRxEmpty returns TRUE when the receive channel of the
+* FIFO is empty. Otherwise, XLlFifo_IsRxEmpty returns FALSE.
+*
+* @note
+* C-style signature:
+* int XLlFifo_IsRxEmpty(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_IsRxEmpty(InstancePtr) \
+ ((XStrm_IsRxInternalEmpty(&((InstancePtr)->RxStreamer)) && \
+ ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, \
+ XLLF_RDFO_OFFSET) == 0))) \
+ ? TRUE : FALSE)
+
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_RxOccupancy returns the number of 32-bit words available (occupancy) to
+* be read from the receive channel of the FIFO, specified by <i>InstancePtr</i>.
+*
+* The xps_ll_fifo core uses the same fifo to store data values and frame length
+* values. Upon initialization, the XLlFifo_RxOccupancy will give the value of
+* 1, which means one length value (a reserved fifo location) and no data
+* values.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_RxOccupancy returns the occupancy count for the specified
+* packet FIFO.
+*
+* @note
+*
+* C Signature: u32 XLlFifo_RxOccupancy(XLlFifo *InstancePtr)
+*
+******************************************************************************/
+#define XLlFifo_RxOccupancy(InstancePtr) \
+ XStrm_RxOccupancy(&((InstancePtr)->RxStreamer))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_RxGetLen notifies the hardware that the program is ready to receive
+* the next frame from the receive channel of the FIFO, specified by
+* <i>InstancePtr</i>.
+*
+* Note that the program must first call XLlFifo_RxGetLen before pulling data
+* out of the receive channel of the FIFO with XLlFifo_Read.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_RxGetLen returns the number of bytes available in the next
+* frame.
+*
+* @note
+*
+* C Signature: u32 XLlFifo_RxGetLen(XLlFifo *InstancePtr)
+*
+******************************************************************************/
+#define XLlFifo_RxGetLen(InstancePtr) \
+ XStrm_RxGetLen(&((InstancePtr)->RxStreamer))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_Read reads <i>Bytes</i> bytes from the receive channel of the FIFO
+* referenced by <i>InstancePtr</i> to the block of memory, referenced by
+* <i>BufPtr</i>.
+*
+* Care must be taken to ensure that the number of bytes read with one or more
+* calls to XLlFifo_Read() does not exceed the number of bytes available given
+* from the last call to XLlFifo_RxGetLen().
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param BufPtr specifies the memory address to place the data read.
+*
+* @param Bytes specifies the number of bytes to read.
+*
+* @return N/A
+*
+* @note
+* Error handling is handled through hardware exceptions and interrupts.
+*
+* C Signature: void XLlFifo_Read(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes)
+*
+******************************************************************************/
+#define XLlFifo_Read(InstancePtr, BufPtr, Bytes) \
+ XStrm_Read(&((InstancePtr)->RxStreamer), (BufPtr), (Bytes))
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_TxReset resets the transmit channel of the FIFO specified by
+* <i>InstancePtr</i>. XLlFifo_TxReset drops any bytes in the FIFO not yet
+* transmitted.
+*
+* The calling software may want to test for the completion of the reset by
+* reading the interrupt status (IS) register and testing for the Tx Reset
+* complete (TRC) bit.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlFifo_TxReset(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_TxReset(InstancePtr) \
+ XLlFifo_WriteReg((InstancePtr)->BaseAddress, XLLF_TDFR_OFFSET, \
+ XLLF_TDFR_RESET_MASK)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_IsTxDone returns true if the transmission in the transmit channel
+* of the FIFO, specified by <i>InstancePtr</i>, is complete. XLlFifo_IsTxDone
+* works only if the TC bit in the IS register is cleared before sending a
+* frame.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_IsTxDone returns TRUE when the transmit channel of the
+* FIFO is complete. Otherwise, XLlFifo_IsTxDone returns FALSE.
+*
+* @note
+* C-style signature:
+* int XLlFifo_IsTxDone(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_IsTxDone(InstancePtr) \
+ ((XLlFifo_ReadReg((InstancePtr)->BaseAddress, XLLF_ISR_OFFSET) & \
+ XLLF_INT_TC_MASK) \
+ ? TRUE : FALSE)
+
+/****************************************************************************/
+/**
+*
+* XLlFifo_TxVacancy returns the number of unused 32 bit words available
+* (vacancy) in the send channel of the FIFO specified by <i>InstancePtr</i>.
+*
+* The xps_ll_fifo core uses tXLLF_he same fifo to store data values and frame length
+* values. Upon initialization, the XLlFifo_TxVacancy will give the value of
+* FIFO_WIDTH - 1, which means one length value used (a reserved fifo location)
+* and no data values yet present.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XLlFifo_TxVacancy returns the vacancy count in 32-bit words for
+* the specified FIFO.
+*
+* @note
+* C-style signature:
+* u32 XLlFifo_TxVacancy(XLlFifo *InstancePtr)
+*
+*****************************************************************************/
+#define XLlFifo_TxVacancy(InstancePtr) \
+ XStrm_TxVacancy(&((InstancePtr)->TxStreamer))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_TxSetLen begins a hardware transfer of <i>Bytes</i> bytes out of the
+* transmit channel of the FIFO specified by <i>InstancePtr</i>.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param Bytes specifies the frame length in bytes.
+*
+* @return N/A
+*
+* @note
+*
+* C Signature: void XLlFifo_TxSetLen(XLlFifo *InstancePtr, u32 Bytes)
+*
+******************************************************************************/
+#define XLlFifo_TxSetLen(InstancePtr, Bytes) \
+ XStrm_TxSetLen(&((InstancePtr)->TxStreamer), (Bytes))
+
+/*****************************************************************************/
+/**
+*
+* XLlFifo_Write writes <i>Bytes</i> bytes of the block of memory, referenced by
+* <i>BufPtr</i>, to the transmit channel of the FIFO referenced by
+* <i>InstancePtr</i>.
+*
+* Care must be taken to ensure that the number of bytes written with one or
+* more calls to XLlFifo_Write() matches the number of bytes given in the next
+* call to XLlFifo_TxSetLen().
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param BufPtr specifies the memory address of data to write.
+*
+* @param Bytes specifies the number of bytes to write.
+*
+* @return N/A
+*
+* @note
+* Error handling is handled through hardware exceptions and interrupts.
+*
+* C Signature: void XLlFifo_Write(XLlFifo *InstancePtr, void *BufPtr, unsigned Bytes)
+*
+******************************************************************************/
+#define XLlFifo_Write(InstancePtr, BufPtr, Bytes) \
+ XStrm_Write(&((InstancePtr)->TxStreamer), (BufPtr), (Bytes))
+
+
+/************************** Function Prototypes ******************************/
+/*
+ * Initialization functions in xtemac_sinit.c
+ */
+void XLlFifo_Initialize(XLlFifo *InstancePtr, u32 BaseAddress);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* XLLFIFO_H end of preprocessor protection symbols */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.c.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.c
@@ -83,27 +83,26 @@
* @note None.
*
******************************************************************************/
-XStatus XPacketFifoV200a_Initialize(XPacketFifoV200a *InstancePtr,
- Xuint32 RegBaseAddress,
- Xuint32 DataBaseAddress)
+int XPacketFifoV200a_Initialize(XPacketFifoV200a * InstancePtr,
+ u32 RegBaseAddress, u32 DataBaseAddress)
{
- /* assert to verify input argument are valid */
+ /* assert to verify input argument are valid */
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
- /* initialize the component variables to the specified state */
+ /* initialize the component variables to the specified state */
- InstancePtr->RegBaseAddress = RegBaseAddress;
- InstancePtr->DataBaseAddress = DataBaseAddress;
- InstancePtr->IsReady = XCOMPONENT_IS_READY;
+ InstancePtr->RegBaseAddress = RegBaseAddress;
+ InstancePtr->DataBaseAddress = DataBaseAddress;
+ InstancePtr->IsReady = XCOMPONENT_IS_READY;
- /* reset the FIFO such that it's empty and ready to use and indicate the
- * initialization was successful, note that the is ready variable must be
- * set prior to calling the reset function to prevent an assert
- */
- XPF_V200A_RESET(InstancePtr);
+ /* reset the FIFO such that it's empty and ready to use and indicate the
+ * initialization was successful, note that the is ready variable must be
+ * set prior to calling the reset function to prevent an assert
+ */
+ XPF_V200A_RESET(InstancePtr);
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/*****************************************************************************/
@@ -132,70 +131,64 @@ XStatus XPacketFifoV200a_Initialize(XPac
* None.
*
******************************************************************************/
-XStatus XPacketFifoV200a_SelfTest(XPacketFifoV200a *InstancePtr,
- Xuint32 FifoType)
+int XPacketFifoV200a_SelfTest(XPacketFifoV200a * InstancePtr, u32 FifoType)
{
- Xuint32 Register;
+ u32 Register;
- /* assert to verify valid input arguments */
+ /* assert to verify valid input arguments */
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID((FifoType == XPF_V200A_READ_FIFO_TYPE) ||
- (FifoType == XPF_V200A_WRITE_FIFO_TYPE));
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* reset the FIFO and then check to make sure the occupancy/vacancy
- * register contents are correct for a reset condition
- */
- XPF_V200A_RESET(InstancePtr);
-
- Register = XIo_In32(InstancePtr->RegBaseAddress +
- XPF_V200A_COUNT_STATUS_REG_OFFSET);
-
- /* check the value of the register to ensure that it's correct for the
- * specified FIFO type since both FIFO types reset to empty, but a bit
- * in the register changes definition based upon FIFO type
- */
-
- if (FifoType == XPF_V200A_READ_FIFO_TYPE)
- {
- /* check the register value for a read FIFO which should be empty */
-
- if ((Register & ~(XPF_V200A_FIFO_WIDTH_MASK)) !=
- XPF_V200A_EMPTY_FULL_MASK)
- {
- return XST_PFIFO_BAD_REG_VALUE;
- }
- }
- else
- {
- /* check the register value for a write FIFO which should not be full
- * on reset
- */
- if (((Register & ~(XPF_V200A_FIFO_WIDTH_MASK) &
- XPF_V200A_EMPTY_FULL_MASK)) != 0)
- {
- return XST_PFIFO_BAD_REG_VALUE;
- }
- }
-
- /* check the register value for the proper FIFO width */
-
- Register &= ~XPF_V200A_EMPTY_FULL_MASK;
-
- if (((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
- XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) &&
- ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
- XPF_V200A_FIFO_WIDTH_32BITS_TYPE) &&
- ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
- XPF_V200A_FIFO_WIDTH_64BITS_TYPE))
- {
- return XST_PFIFO_BAD_REG_VALUE;
- }
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID((FifoType == XPF_V200A_READ_FIFO_TYPE) ||
+ (FifoType == XPF_V200A_WRITE_FIFO_TYPE));
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* reset the FIFO and then check to make sure the occupancy/vacancy
+ * register contents are correct for a reset condition
+ */
+ XPF_V200A_RESET(InstancePtr);
+
+ Register = XIo_In32(InstancePtr->RegBaseAddress +
+ XPF_V200A_COUNT_STATUS_REG_OFFSET);
+
+ /* check the value of the register to ensure that it's correct for the
+ * specified FIFO type since both FIFO types reset to empty, but a bit
+ * in the register changes definition based upon FIFO type
+ */
+
+ if (FifoType == XPF_V200A_READ_FIFO_TYPE) {
+ /* check the register value for a read FIFO which should be empty */
+
+ if ((Register & ~(XPF_V200A_FIFO_WIDTH_MASK)) !=
+ XPF_V200A_EMPTY_FULL_MASK) {
+ return XST_PFIFO_BAD_REG_VALUE;
+ }
+ }
+ else {
+ /* check the register value for a write FIFO which should not be full
+ * on reset
+ */
+ if (((Register & ~(XPF_V200A_FIFO_WIDTH_MASK) &
+ XPF_V200A_EMPTY_FULL_MASK)) != 0) {
+ return XST_PFIFO_BAD_REG_VALUE;
+ }
+ }
+
+ /* check the register value for the proper FIFO width */
+
+ Register &= ~XPF_V200A_EMPTY_FULL_MASK;
+
+ if (((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+ XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) &&
+ ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+ XPF_V200A_FIFO_WIDTH_32BITS_TYPE) &&
+ ((Register & XPF_V200A_FIFO_WIDTH_MASK) !=
+ XPF_V200A_FIFO_WIDTH_64BITS_TYPE)) {
+ return XST_PFIFO_BAD_REG_VALUE;
+ }
- /* the test was successful */
+ /* the test was successful */
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
@@ -227,23 +220,22 @@ XStatus XPacketFifoV200a_SelfTest(XPacke
* None.
*
******************************************************************************/
-XStatus XPacketFifoV200a_Read(XPacketFifoV200a *InstancePtr,
- Xuint8 *BufferPtr,
- Xuint32 ByteCount)
+int XPacketFifoV200a_Read(XPacketFifoV200a * InstancePtr,
+ u8 *BufferPtr, u32 ByteCount)
{
- /* assert to verify valid input arguments including 32 bit alignment of
- * the buffer pointer
- */
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(BufferPtr != XNULL);
- XASSERT_NONVOID(((Xuint32)BufferPtr &
- (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
- XASSERT_NONVOID(ByteCount != 0);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- return XPacketFifoV200a_L0Read(InstancePtr->RegBaseAddress,
- InstancePtr->DataBaseAddress,
- BufferPtr, ByteCount);
+ /* assert to verify valid input arguments including 32 bit alignment of
+ * the buffer pointer
+ */
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufferPtr != NULL);
+ XASSERT_NONVOID(((u32) BufferPtr &
+ (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
+ XASSERT_NONVOID(ByteCount != 0);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ return XPacketFifoV200a_L0Read(InstancePtr->RegBaseAddress,
+ InstancePtr->DataBaseAddress,
+ BufferPtr, ByteCount);
}
/*****************************************************************************/
@@ -273,24 +265,23 @@ XStatus XPacketFifoV200a_Read(XPacketFif
* None.
*
******************************************************************************/
-XStatus XPacketFifoV200a_Write(XPacketFifoV200a *InstancePtr,
- Xuint8 *BufferPtr,
- Xuint32 ByteCount)
+int XPacketFifoV200a_Write(XPacketFifoV200a * InstancePtr,
+ u8 *BufferPtr, u32 ByteCount)
{
- /* assert to verify valid input arguments including 32 bit alignment of
- * the buffer pointer
- */
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(BufferPtr != XNULL);
- XASSERT_NONVOID(((Xuint32)BufferPtr &
- (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
- XASSERT_NONVOID(ByteCount != 0);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /* assert to verify valid input arguments including 32 bit alignment of
+ * the buffer pointer
+ */
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufferPtr != NULL);
+ XASSERT_NONVOID(((u32) BufferPtr &
+ (XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT - 1)) == 0);
+ XASSERT_NONVOID(ByteCount != 0);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- return XPacketFifoV200a_L0Write(InstancePtr->RegBaseAddress,
- InstancePtr-> DataBaseAddress,
- BufferPtr, ByteCount);
+ return XPacketFifoV200a_L0Write(InstancePtr->RegBaseAddress,
+ InstancePtr->DataBaseAddress,
+ BufferPtr, ByteCount);
}
@@ -323,17 +314,16 @@ XStatus XPacketFifoV200a_Write(XPacketFi
* significant byte to the least significant byte.
*
******************************************************************************/
-XStatus XPacketFifoV200a_WriteDre(XPacketFifoV200a *InstancePtr,
- Xuint8 *BufferPtr,
- Xuint32 ByteCount)
+int XPacketFifoV200a_WriteDre(XPacketFifoV200a * InstancePtr,
+ u8 *BufferPtr, u32 ByteCount)
{
- /* assert to verify valid input arguments */
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(BufferPtr != XNULL);
- XASSERT_NONVOID(ByteCount != 0);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- return XPacketFifoV200a_L0WriteDre(InstancePtr->RegBaseAddress,
- InstancePtr-> DataBaseAddress,
- BufferPtr, ByteCount);
+ /* assert to verify valid input arguments */
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufferPtr != NULL);
+ XASSERT_NONVOID(ByteCount != 0);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ return XPacketFifoV200a_L0WriteDre(InstancePtr->RegBaseAddress,
+ InstancePtr->DataBaseAddress,
+ BufferPtr, ByteCount);
}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xstreamer.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xstreamer.c
@@ -0,0 +1,504 @@
+/* $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 2005-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+* @file xstreamer.c
+*
+* See xtreamer.h for a description on how to use this driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a jvb 10/13/06 First release - based on Robert McGee's streaming packet
+* fifo driver.
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xstreamer.h"
+
+/*
+ * Implementation Notes
+ *
+ * --- software/linux-2.6.x-petalogix/Receive ---
+ *
+ * The basic algorithm for receiving bytes through this byte streamer copies a
+ * fifo key-hole width chunk from the fifo into a holding buffer and then doles
+ * out the bytes from the holding buffer. In some cases, when the buffer given
+ * happens to already be aligned in memory, this algorithm will bypass the
+ * holding buffer.
+ *
+ * Here is a picture to depict this process:
+ *
+ * Initial state: holding buffer
+ * +--------------+
+ * | <empty> |
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * during XStrm_Read():
+ * first holding buffer fill: holding buffer
+ * +--------------+
+ * |////<full>////|
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * first holding buffer read: holding buffer
+ * read unread
+ * +--------------+
+ * | |///////|
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * ...
+ *
+ * last holding buffer read: holding buffer
+ * +--------------+
+ * | <empty> |
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * repeat this process ^^^
+ *
+ *
+ * --- software/linux-2.6.x-petalogix/Transmit ---
+ *
+ * The basic algorithm for transmitting bytes through this byte streamer copies
+ * bytes into a holding buffer and then writes the holding buffer into the fifo
+ * when it is full. In some cases, when the buffer given happens to already be
+ * aligned in memory, this algorithm will bypass the holding buffer.
+ *
+ * Here is a picture to depict this process:
+ *
+ * Initial state: holding buffer
+ * +--------------+
+ * | <empty> |
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * during XStrm_Write():
+ * first holding buffer write: holding buffer
+ * writen empty
+ * +--------------+
+ * |//////| |
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * ...
+ * last holding buffer write: holding buffer
+ * +--------------+
+ * |////<full>////|
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * holding buffer flush: holding buffer
+ * +--------------+
+ * | <empty> |
+ * +--------------+
+ * ^
+ * |
+ * index
+ *
+ * repeat this process ^^^
+ */
+
+#ifndef min
+#define min(x, y) (((x) < (y)) ? (x) : (y))
+#endif
+
+/*****************************************************************************/
+/*
+*
+* XStrm_RxInitialize initializes the XStrm_RxFifoStreamer object referenced by
+* <i>InstancePtr</i>.
+*
+* @param InstancePtr references the tx streamer on which to operate.
+*
+* @param FifoWidth specifies the FIFO keyhole size in bytes.
+*
+* @param FifoInstance references the FIFO driver instance that this streamer
+* object should use to transfer data into the the actual fifo.
+*
+* @param ReadFn specifies a routine to use to read data from the actual
+* FIFO. It is assumed that this read routine will handle only reads
+* from an aligned buffer. (Otherwise, why are we using this streamer
+* driver?)
+*
+* @param GetLenFn specifies a routine to use to initiate a receive on the
+* actual FIFO.
+*
+* @param GetOccupancyFn specifies a routine to use to retrieve the occupancy
+* in the actual FIFO. The true occupancy value needs to come through
+* this streamer driver becuase it holds some of the bytes.
+*
+* @return N/A
+*
+******************************************************************************/
+void XStrm_RxInitialize(XStrm_RxFifoStreamer * InstancePtr,
+ unsigned FifoWidth, void *FifoInstance,
+ XStrm_XferFnType ReadFn,
+ XStrm_GetLenFnType GetLenFn,
+ XStrm_GetOccupancyFnType GetOccupancyFn)
+{
+ /* Verify arguments */
+ XASSERT_VOID(InstancePtr != NULL);
+
+ InstancePtr->HeadIndex = FifoWidth;
+ InstancePtr->FifoWidth = FifoWidth;
+ InstancePtr->FifoInstance = FifoInstance;
+ InstancePtr->ReadFn = ReadFn;
+ InstancePtr->GetLenFn = GetLenFn;
+ InstancePtr->GetOccupancyFn = GetOccupancyFn;
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_TxInitialize initializes the XStrm_TxFifoStreamer object referenced by
+* <i>InstancePtr</i>.
+*
+* @param InstancePtr references the tx streamer on which to operate.
+*
+* @param FifoWidth specifies the FIFO keyhole size in bytes.
+*
+* @param FifoInstance references the FIFO driver instance that this streamer
+* object should use to transfer data into the the actual fifo.
+*
+* @param WriteFn specifies a routine to use to write data into the actual
+* FIFO. It is assumed that this write routine will handle only writes
+* from an aligned buffer. (Otherwise, why are we using this streamer
+* driver?)
+*
+* @param SetLenFn specifies a routine to use to initiate a transmit on the
+* actual FIFO.
+*
+* @param GetVacancyFn specifies a routine to use to retrieve the vacancy in
+* the actual FIFO. The true vacancy value needs to come through this
+* streamer driver becuase it holds some of the bytes.
+*
+* @return N/A
+*
+******************************************************************************/
+void XStrm_TxInitialize(XStrm_TxFifoStreamer * InstancePtr, unsigned FifoWidth,
+ void *FifoInstance, XStrm_XferFnType WriteFn,
+ XStrm_SetLenFnType SetLenFn,
+ XStrm_GetVacancyFnType GetVacancyFn)
+{
+ /* Verify arguments */
+ XASSERT_VOID(InstancePtr != NULL);
+
+ InstancePtr->TailIndex = 0;
+ InstancePtr->FifoWidth = FifoWidth;
+ InstancePtr->FifoInstance = FifoInstance;
+ InstancePtr->WriteFn = WriteFn;
+ InstancePtr->SetLenFn = SetLenFn;
+ InstancePtr->GetVacancyFn = GetVacancyFn;
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_RxGetLen notifies the hardware that the program is ready to receive the
+* next frame from the receive channel of the FIFO, specified by
+* <i>InstancePtr</i>.
+*
+* Note that the program must first call XStrm_RxGetLen before pulling data
+* out of the receive channel of the FIFO with XStrm_Read.
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @return XStrm_RxGetLen returns the number of bytes available in the next
+* frame.
+*
+******************************************************************************/
+u32 XStrm_RxGetLen(XStrm_RxFifoStreamer * InstancePtr)
+{
+ u32 len;
+
+ InstancePtr->HeadIndex = InstancePtr->FifoWidth;
+ len = (*InstancePtr->GetLenFn) (InstancePtr->FifoInstance);
+ InstancePtr->FrmByteCnt = len;
+ return len;
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_Read reads <i>Bytes</i> bytes from the FIFO specified by
+* <i>InstancePtr</i> to the block of memory, referenced by <i>BufPtr</i>.
+*
+* Care must be taken to ensure that the number of bytes read with one or more
+* calls to XStrm_Read() does not exceed the number of bytes available given
+* from the last call to XStrm_RxGetLen().
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param BufPtr specifies the memory address to place the data read.
+*
+* @param Bytes specifies the number of bytes to read.
+*
+* @return N/A
+*
+******************************************************************************/
+void XStrm_Read(XStrm_RxFifoStreamer * InstancePtr, void *BufPtr,
+ unsigned Bytes)
+{
+ u8 *DestPtr = (u8 *) BufPtr;
+ unsigned BytesRemaining = Bytes;
+ unsigned FifoWordsToXfer;
+ unsigned PartialBytes;
+ unsigned i;
+
+ while (BytesRemaining) {
+ xdbg_printf(XDBG_DEBUG_FIFO_RX,
+ "XStrm_Read: BytesRemaining: %d\n", BytesRemaining);
+ /* Case 1: There are bytes in the holding buffer
+ *
+ * 1) Read the bytes from the holding buffer to the target buffer.
+ * 2) Loop back around and handle the rest of the transfer.
+ */
+ if (InstancePtr->HeadIndex != InstancePtr->FifoWidth) {
+ xdbg_printf(XDBG_DEBUG_FIFO_RX,
+ "XStrm_Read: Case 1: InstancePtr->HeadIndex [%d] != InstancePtr->FifoWidth [%d]\n",
+ InstancePtr->HeadIndex,
+ InstancePtr->FifoWidth);
+ i = InstancePtr->HeadIndex;
+
+ PartialBytes = min(BytesRemaining,
+ InstancePtr->FifoWidth -
+ InstancePtr->HeadIndex);
+ InstancePtr->HeadIndex += PartialBytes;
+ BytesRemaining -= PartialBytes;
+ InstancePtr->FrmByteCnt -= PartialBytes;
+ while (PartialBytes--) {
+ *DestPtr = InstancePtr->AlignedBuffer.bytes[i];
+ i++;
+ DestPtr++;
+ }
+ }
+ /* Case 2: There are no more bytes in the holding buffer and
+ * the target buffer is 32 bit aligned and
+ * the number of bytes remaining to transfer is greater
+ * than or equal to the fifo width.
+ *
+ * 1) We can go fast by reading a long string of fifo words right out
+ * of the fifo into the target buffer.
+ * 2) Loop back around to transfer the last few bytes.
+ */
+ else if ((((unsigned) DestPtr & 3) == 0) &&
+ (BytesRemaining >= InstancePtr->FifoWidth)) {
+ xdbg_printf(XDBG_DEBUG_FIFO_RX,
+ "XStrm_Read: Case 2: DestPtr: %p, BytesRemaining: %d, InstancePtr->FifoWidth: %d\n",
+ DestPtr, BytesRemaining,
+ InstancePtr->FifoWidth);
+ FifoWordsToXfer =
+ BytesRemaining / InstancePtr->FifoWidth;
+
+ (*(InstancePtr->ReadFn)) (InstancePtr->FifoInstance,
+ DestPtr, FifoWordsToXfer);
+ DestPtr += FifoWordsToXfer * InstancePtr->FifoWidth;
+ BytesRemaining -=
+ FifoWordsToXfer * InstancePtr->FifoWidth;
+ InstancePtr->FrmByteCnt -=
+ FifoWordsToXfer * InstancePtr->FifoWidth;
+ }
+ /* Case 3: There are no more bytes in the holding buffer and
+ * the number of bytes remaining to transfer is less than
+ * the fifo width or
+ * things just don't line up.
+ *
+ * 1) Fill the holding buffer.
+ * 2) Loop back around and handle the rest of the transfer.
+ */
+ else {
+ xdbg_printf(XDBG_DEBUG_FIFO_RX, "XStrm_Read: Case 3\n");
+ /*
+ * At the tail end, read one fifo word into the local holding
+ * buffer and loop back around to take care of the transfer.
+ */
+ (*InstancePtr->ReadFn) (InstancePtr->FifoInstance,
+ &(InstancePtr->AlignedBuffer.
+ bytes[0]), 1);
+ InstancePtr->HeadIndex = 0;
+ }
+ }
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_TxSetLen flushes to the FIFO, specified by <i>InstancePtr</i>, any
+* bytes remaining in internal buffers and begins a hardware transfer of data
+* out of the transmit channel of the FIFO. <i>Bytes</i> specifies the number
+* of bytes in the frame to transmit.
+*
+* @param InstancePtr references the FIFO Streamer on which to operate.
+*
+* @param Bytes specifies the frame length in bytes.
+*
+* @return N/A
+*
+******************************************************************************/
+void XStrm_TxSetLen(XStrm_TxFifoStreamer * InstancePtr, u32 Bytes)
+{
+ /*
+ * First flush what's in the holding buffer
+ */
+ if (InstancePtr->TailIndex != 0) {
+ (*InstancePtr->WriteFn) (InstancePtr->FifoInstance,
+ &(InstancePtr->AlignedBuffer.bytes[0]),
+ 1);
+ InstancePtr->TailIndex = 0;
+ }
+
+ /*
+ * Kick off the hw write
+ */
+ (*(InstancePtr)->SetLenFn) (InstancePtr->FifoInstance, Bytes);
+}
+
+/*****************************************************************************/
+/*
+*
+* XStrm_Write writes <i>Bytes</i> bytes of the block of memory, referenced by
+* <i>BufPtr</i>, to the transmit channel of the FIFO referenced by
+* <i>InstancePtr</i>.
+*
+* Care must be taken to ensure that the number of bytes written with one or
+* more calls to XStrm_Write() matches the number of bytes given in the next
+* call to XStrm_TxSetLen().
+*
+* @param InstancePtr references the FIFO on which to operate.
+*
+* @param BufPtr specifies the memory address of data to write.
+*
+* @param Bytes specifies the number of bytes to write.
+*
+* @return N/A
+*
+******************************************************************************/
+void XStrm_Write(XStrm_TxFifoStreamer * InstancePtr, void *BufPtr,
+ unsigned Bytes)
+{
+ u8 *SrcPtr = (u8 *) BufPtr;
+ unsigned BytesRemaining = Bytes;
+ unsigned FifoWordsToXfer;
+ unsigned PartialBytes;
+ unsigned i;
+
+ while (BytesRemaining) {
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XStrm_Write: BytesRemaining: %d\n",
+ BytesRemaining);
+ /* Case 1: The holding buffer is full
+ *
+ * 1) Write it to the fifo.
+ * 2) Fall through to transfer more bytes in this iteration.
+ */
+ if (InstancePtr->TailIndex == InstancePtr->FifoWidth) {
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XStrm_Write: (case 1) TailIndex: %d; FifoWidth: %d; WriteFn: %p\n",
+ InstancePtr->TailIndex,
+ InstancePtr->FifoWidth,
+ InstancePtr->WriteFn);
+ (*InstancePtr->WriteFn) (InstancePtr->FifoInstance,
+ &(InstancePtr->AlignedBuffer.
+ bytes[0]), 1);
+ InstancePtr->TailIndex = 0;
+ }
+ /* Case 2: There are no bytes in the holding buffer and
+ * the target buffer is 32 bit aligned and
+ * the number of bytes remaining to transfer is greater
+ * than or equal to the fifo width.
+ *
+ * 1) We can go fast by writing a long string of fifo words right out
+ * of the source buffer into the fifo.
+ * 2) Loop back around to transfer the last few bytes.
+ */
+ if ((InstancePtr->TailIndex == 0) &&
+ (BytesRemaining >= InstancePtr->FifoWidth) &&
+ (((unsigned) SrcPtr & 3) == 0)) {
+ FifoWordsToXfer =
+ BytesRemaining / InstancePtr->FifoWidth;
+
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XStrm_Write: (case 2) TailIndex: %d; BytesRemaining: %d; FifoWidth: %d; SrcPtr: %p;\n InstancePtr: %p; WriteFn: %p (XLlFifo_iWrite_Aligned: %p),\nFifoWordsToXfer: %d (BytesRemaining: %d)\n",
+ InstancePtr->TailIndex, BytesRemaining,
+ InstancePtr->FifoWidth, SrcPtr, InstancePtr,
+ InstancePtr->WriteFn,
+ XLlFifo_iWrite_Aligned, FifoWordsToXfer,
+ BytesRemaining);
+
+ (*InstancePtr->WriteFn) (InstancePtr->FifoInstance,
+ SrcPtr, FifoWordsToXfer);
+ SrcPtr += FifoWordsToXfer * InstancePtr->FifoWidth;
+ BytesRemaining -=
+ FifoWordsToXfer * InstancePtr->FifoWidth;
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XStrm_Write: (end case 2) TailIndex: %d; BytesRemaining: %d; SrcPtr: %p\n",
+ InstancePtr->TailIndex, BytesRemaining,
+ SrcPtr);
+ }
+ /* Case 3: The alignment of the "galaxies" didn't occur in
+ * Case 2 above, so we must pump the bytes through the
+ * holding buffer.
+ *
+ * 1) Write bytes from the source buffer to the holding buffer
+ * 2) Loop back around and handle the rest of the transfer.
+ */
+ else {
+ i = InstancePtr->TailIndex;
+
+ PartialBytes =
+ min(BytesRemaining,
+ InstancePtr->FifoWidth -
+ InstancePtr->TailIndex);
+ BytesRemaining -= PartialBytes;
+ InstancePtr->TailIndex += PartialBytes;
+ while (PartialBytes--) {
+ xdbg_printf(XDBG_DEBUG_FIFO_TX,
+ "XStrm_Write: (case 3) PartialBytes: %d\n",
+ PartialBytes);
+ InstancePtr->AlignedBuffer.bytes[i] = *SrcPtr;
+ i++;
+ SrcPtr++;
+ }
+ }
+ }
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bdring.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bdring.h
@@ -0,0 +1,426 @@
+/* $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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma_bdring.h
+*
+* This file contains DMA channel related structure and constant definition
+* as well as function prototypes. Each DMA channel is managed by a Buffer
+* Descriptor ring, and so XLlDma_BdRing is chosen as the symbol prefix used in
+* this file. See xlldma.h for more information.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a xd 12/21/06 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_BDRING_H /* prevent circular inclusions */
+#define XLLDMA_BDRING_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xlldma_hw.h"
+#include "xlldma_bd.h"
+
+/** Container structure for descriptor storage control. If address translation
+ * is enabled, then all addresses and pointers excluding FirstBdPhysAddr are
+ * expressed in terms of the virtual address.
+ */
+typedef struct {
+ u32 ChanBase; /**< Virtual base address of channel registers
+ */
+ u32 IsRxChannel; /**< Is this a receive channel ? */
+ u32 FirstBdPhysAddr; /**< Physical address of 1st BD in list */
+ u32 FirstBdAddr; /**< Virtual address of 1st BD in list */
+ u32 LastBdAddr; /**< Virtual address of last BD in the list */
+ u32 Length; /**< Total size of ring in bytes */
+ u32 RunState; /**< Flag to indicate channel is started */
+ u32 Separation; /**< Number of bytes between the starting
+ address of adjacent BDs */
+ XLlDma_Bd *FreeHead; /**< First BD in the free group */
+ XLlDma_Bd *PreHead; /**< First BD in the pre-work group */
+ XLlDma_Bd *HwHead; /**< First BD in the work group */
+ XLlDma_Bd *HwTail; /**< Last BD in the work group */
+ XLlDma_Bd *PostHead; /**< First BD in the post-work group */
+ XLlDma_Bd *BdaRestart; /**< BD to load when channel is started */
+ u32 FreeCnt; /**< Number of allocatable BDs in free group */
+ u32 PreCnt; /**< Number of BDs in pre-work group */
+ u32 HwCnt; /**< Number of BDs in work group */
+ u32 PostCnt; /**< Number of BDs in post-work group */
+ u32 AllCnt; /**< Total Number of BDs for channel */
+} XLlDma_BdRing;
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many BDs will fit
+* within the given memory constraints.
+*
+* The results of this macro can be provided to XLlDma_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, 126,...)
+* @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 XLlDma_mBdRingCntCalc(u32 Alignment, u32 Bytes)
+*
+******************************************************************************/
+#define XLlDma_mBdRingCntCalc(Alignment, Bytes) \
+ (u32)((Bytes)/((sizeof(XLlDma_Bd)+((Alignment)-1))&~((Alignment)-1)))
+
+
+/*****************************************************************************/
+/**
+* Use this macro at initialization time to determine how many bytes of memory
+* are 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 XLlDma_mBdRingMemCalc(u32 Alignment, u32 NumBd)
+*
+******************************************************************************/
+#define XLlDma_mBdRingMemCalc(Alignment, NumBd) \
+ (u32)((sizeof(XLlDma_Bd)+((Alignment)-1))&~((Alignment)-1))*(NumBd)
+
+
+/****************************************************************************/
+/**
+* Return the total number of BDs allocated by this channel with
+* XLlDma_BdRingCreate().
+*
+* @param RingPtr is the BD ring to operate on.
+*
+* @return The total number of BDs allocated for this channel.
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingGetCnt(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetCnt(RingPtr) ((RingPtr)->AllCnt)
+
+
+/****************************************************************************/
+/**
+* Return the number of BDs allocatable with XLlDma_BdRingAlloc() for pre-
+* processing.
+*
+* @param RingPtr is the BD ring to operate on.
+*
+* @return The number of BDs currently allocatable.
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingGetFreeCnt(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetFreeCnt(RingPtr) ((RingPtr)->FreeCnt)
+
+
+/****************************************************************************/
+/**
+* Snap shot the latest BD a BD ring is processing.
+*
+* @param RingPtr is the BD ring to operate on.
+*
+* @return None
+*
+* @note
+* C-style signature:
+* void XLlDma_mBdRingSnapShotCurrBd(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingSnapShotCurrBd(RingPtr) \
+ { \
+ (RingPtr)->BdaRestart = \
+ (XLlDma_Bd *)XLlDma_mReadReg((RingPtr)->ChanBase, \
+ XLLDMA_CDESC_OFFSET); \
+ }
+
+
+/****************************************************************************/
+/**
+* Return the next BD in the ring.
+*
+* @param RingPtr is the BD ring to operate on.
+* @param BdPtr is the current BD.
+*
+* @return The next BD in the ring relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+* XLlDma_Bd *XLlDma_mBdRingNext(XLlDma_BdRing* RingPtr, XLlDma_Bd *BdPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingNext(RingPtr, BdPtr) \
+ (((u32)(BdPtr) >= (RingPtr)->LastBdAddr) ? \
+ (XLlDma_Bd*)(RingPtr)->FirstBdAddr : \
+ (XLlDma_Bd*)((u32)(BdPtr) + (RingPtr)->Separation))
+
+
+/****************************************************************************/
+/**
+* Return the previous BD in the ring.
+*
+* @param InstancePtr is the DMA channel to operate on.
+* @param BdPtr is the current BD.
+*
+* @return The previous BD in the ring relative to the BdPtr parameter.
+*
+* @note
+* C-style signature:
+* XLlDma_Bd *XLlDma_mBdRingPrev(XLlDma_BdRing* RingPtr, XLlDma_Bd *BdPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingPrev(RingPtr, BdPtr) \
+ (((u32)(BdPtr) <= (RingPtr)->FirstBdAddr) ? \
+ (XLlDma_Bd*)(RingPtr)->LastBdAddr : \
+ (XLlDma_Bd*)((u32)(BdPtr) - (RingPtr)->Separation))
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the channel status register XLLDMA_SR_OFFSET
+*
+* @param RingPtr is the channel instance to operate on.
+*
+* @return Current contents of SR_OFFSET
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingGetSr(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetSr(RingPtr) \
+ XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_SR_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the channel control register XLLDMA_CR_OFFSET
+*
+* @param RingPtr is the channel instance to operate on.
+*
+* @return Current contents of CR_OFFSET
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingGetCr(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetCr(RingPtr) \
+ XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Set the contents of the channel control register XLLDMA_CR_OFFSET. This
+* register does not affect the other DMA channel.
+*
+* @param RingPtr is the channel instance to operate on.
+* @param Data is the data to write to CR_OFFSET
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingSetCr(XLlDma_BdRing* RingPtr, u32 Data)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingSetCr(RingPtr, Data) \
+ XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, (Data))
+
+
+/****************************************************************************/
+/**
+* Check if the current DMA channel is busy with a DMA operation.
+*
+* @param RingPtr is the channel instance to operate on.
+*
+* @return TRUE if the DMA is busy. FALSE otherwise
+*
+* @note
+* C-style signature:
+* XBoolean XLlDma_mBdRingBusy(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingBusy(RingPtr) \
+ ((XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_SR_OFFSET) \
+ & XLLDMA_SR_ENGINE_BUSY_MASK) ? TRUE : FALSE)
+
+
+/****************************************************************************/
+/**
+* Set interrupt enable bits for a channel. This operation will modify the
+* XLLDMA_CR_OFFSET register.
+*
+* @param RingPtr is the channel instance to operate on.
+* @param Mask consists of the interrupt signals to enable. They are formed by
+* OR'ing one or more of the following bitmasks together:
+* XLLDMA_CR_IRQ_EN_MASK, XLLDMA_CR_IRQ_ERROR_EN_MASK,
+* XLLDMA_CR_IRQ_DELAY_EN_MASK, XLLDMA_CR_IRQ_COALESCE_EN_MASK and
+* XLLDMA_CR_IRQ_ALL_EN_MASK. Bits not specified in the mask are not
+* affected.
+*
+* @note
+* C-style signature:
+* void XLlDma_mBdRingIntEnable(XLlDma_BdRing* RingPtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingIntEnable(RingPtr, Mask) \
+ { \
+ u32 Reg = XLlDma_mReadReg((RingPtr)->ChanBase, \
+ XLLDMA_CR_OFFSET); \
+ Reg |= ((Mask) & XLLDMA_CR_IRQ_ALL_EN_MASK); \
+ XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, Reg);\
+ }
+
+
+/****************************************************************************/
+/**
+* Clear interrupt enable bits for a channel. This operation will modify the
+* XLLDMA_CR_OFFSET register.
+*
+* @param RingPtr is the channel instance to operate on.
+* @param Mask consists of the interrupt signals to disable. They are formed
+* by OR'ing one or more of the following bitmasks together:
+* XLLDMA_CR_IRQ_EN_MASK, XLLDMA_CR_IRQ_ERROR_EN_MASK,
+* XLLDMA_CR_IRQ_DELAY_EN_MASK, XLLDMA_CR_IRQ_COALESCE_EN_MASK and
+* XLLDMA_CR_IRQ_ALL_EN_MASK. Bits not specified in the mask are not
+* affected.
+*
+* @note
+* C-style signature:
+* void XLlDma_mBdRingIntDisable(XLlDma_BdRing* RingPtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingIntDisable(RingPtr, Mask) \
+ { \
+ u32 Reg = XLlDma_mReadReg((RingPtr)->ChanBase, \
+ XLLDMA_CR_OFFSET); \
+ Reg &= ~((Mask) & XLLDMA_CR_IRQ_ALL_EN_MASK); \
+ XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET, Reg);\
+ }
+
+
+/****************************************************************************/
+/**
+* Get enabled interrupts of a channel.
+*
+* @param RingPtr is the channel instance to operate on.
+* @return Enabled interrupts of a channel. Use XLLDMA_CR_IRQ_* defined in
+* xlldma_hw.h to interpret this returned value.
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingIntGetEnabled(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingIntGetEnabled(RingPtr) \
+ (XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_CR_OFFSET) \
+ & XLLDMA_CR_IRQ_ALL_EN_MASK)
+
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the channel's IRQ register XDMACR_IRQ_OFFSET. This
+* operation can be used to see which interrupts are pending.
+*
+* @param RingPtr is the channel instance to operate on.
+*
+* @return Current contents of the IRQ_OFFSET register. Use XLLDMA_IRQ_***
+* values defined in xlldma_hw.h to interpret the returned value.
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingGetIrq(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingGetIrq(RingPtr) \
+ XLlDma_mReadReg((RingPtr)->ChanBase, XLLDMA_IRQ_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Acknowledge asserted interrupts.
+*
+* @param RingPtr is the channel instance to operate on.
+* @param Mask are the interrupt signals to acknowledge and are made by Or'ing
+* one or more of the following bits: XLLDMA_IRQ_ERROR_MASK,
+* XLLDMA_IRQ_DELAY_MASK, XLLDMA_IRQ_COALESCE_MASK, XLLDMA_IRQ_ALL_MASK.
+* Any mask bit set for an unasserted interrupt has no effect.
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mBdRingAckIrq(XLlDma_BdRing* RingPtr)
+*
+*****************************************************************************/
+#define XLlDma_mBdRingAckIrq(RingPtr, Mask) \
+ XLlDma_mWriteReg((RingPtr)->ChanBase, XLLDMA_IRQ_OFFSET,\
+ (Mask) & XLLDMA_IRQ_ALL_MASK)
+
+/************************* Function Prototypes ******************************/
+
+/*
+ * Descriptor ring functions xlldma_bdring.c
+ */
+int XLlDma_BdRingCreate(XLlDma_BdRing * RingPtr, u32 PhysAddr,
+ u32 VirtAddr, u32 Alignment, unsigned BdCount);
+int XLlDma_BdRingCheck(XLlDma_BdRing * RingPtr);
+int XLlDma_BdRingClone(XLlDma_BdRing * RingPtr, XLlDma_Bd * SrcBdPtr);
+int XLlDma_BdRingAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_Bd ** BdSetPtr);
+int XLlDma_BdRingUnAlloc(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_Bd * BdSetPtr);
+int XLlDma_BdRingToHw(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_Bd * BdSetPtr);
+unsigned XLlDma_BdRingFromHw(XLlDma_BdRing * RingPtr, unsigned BdLimit,
+ XLlDma_Bd ** BdSetPtr);
+int XLlDma_BdRingFree(XLlDma_BdRing * RingPtr, unsigned NumBd,
+ XLlDma_Bd * BdSetPtr);
+int XLlDma_BdRingStart(XLlDma_BdRing * RingPtr);
+int XLlDma_BdRingSetCoalesce(XLlDma_BdRing * RingPtr, u32 Counter, u32 Timer);
+void XLlDma_BdRingGetCoalesce(XLlDma_BdRing * RingPtr,
+ u32 *CounterPtr, u32 *TimerPtr);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_simple.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_simple.c
@@ -0,0 +1,124 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_simple.c
+*
+* This file implements Simple DMA related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 3.00a rmm 03/11/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* Initiate a simple DMA transfer. The BD argument sets the parameters of the
+* transfer. Since the BD is also used for SG DMA transfers, some fields of the
+* BD will be ignored. The following BD macros will have no effect on the
+* transfer:
+*
+* - XDmaBdV3_mSetLast()
+* - XDmaBdV3_mClearLast()
+* - XDmaBdV3_mSetBdPage()
+*
+* To determine when the transfer has completed, the user can poll the device
+* with XDmaV3_mGetStatus() and test the XDMAV3_DMASR_DMABSY_MASK bit, or wait for
+* an interrupt. When the DMA operation has completed, the outcome of the
+* transfer can be retrieved by calling XDmaV3_mGetStatus() and testing for DMA
+* bus errors bits.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param BdPtr sets the parameters of the transfer.
+*
+* @return
+* - XST_SUCCESS if the transfer was initated
+* - XST_DEVICE_BUSY if a transfer is already in progress
+*
+******************************************************************************/
+int XDmaV3_SimpleTransfer(XDmaV3 * InstancePtr, XDmaBdV3 * BdPtr)
+{
+ u32 Dmasr;
+
+ /* Is the channel busy */
+ Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if (Dmasr & (XDMAV3_DMASR_DMABSY_MASK | XDMAV3_DMASR_SGBSY_MASK)) {
+ return (XST_DEVICE_BUSY);
+ }
+
+ /* Copy BdPtr fields into the appropriate HW registers */
+
+ /* DMACR: SGS bit is set always. This is done in case the transfer
+ * occurs on a SGDMA channel and will prevent the HW from fetching the
+ * next BD.
+ */
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET,
+ XDmaV3_mReadBd(BdPtr, XDMAV3_BD_DMACR_OFFSET)
+ | XDMAV3_DMACR_SGS_MASK);
+
+ /* MSBA */
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_MSBA_OFFSET,
+ XDmaV3_mReadBd(BdPtr, XDMAV3_BD_MSBA_OFFSET));
+
+ /* LSBA */
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_LSBA_OFFSET,
+ XDmaV3_mReadBd(BdPtr, XDMAV3_BD_LSBA_OFFSET));
+
+ /* LENGTH: Writing this register starts HW */
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_LENGTH_OFFSET,
+ XDmaV3_mReadBd(BdPtr, XDMAV3_BD_LENGTH_OFFSET));
+
+ return (XST_SUCCESS);
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmabdv3.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmabdv3.h
@@ -0,0 +1,531 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xdmabdv3.h
+ *
+ * This header provides operations to manage buffer descriptors in support
+ * of simple and scatter-gather DMA (see xdmav3.h).
+ *
+ * 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 (see "Transaction"
+ * section in xdmav3.h). The macros defined by this header file allow access
+ * to most fields within a BD to tailor a DMA transaction according to user
+ * and HW requirements. See the HW IP DMA spec for more information on BD
+ * fields and how they affect transfers.
+ *
+ * The XDmaBdV3 structure defines a BD. The organization of this structure is
+ * driven mainly by the hardware for use in scatter-gather DMA transfers.
+ *
+ * <b>Accessor Macros</b>
+ *
+ * Most of the BD attributes can be accessed through macro functions defined
+ * here in this API. Words such as XDMAV3_BD_USR0_OFFSET (see xdmav3_l.h)
+ * should be accessed using XDmaV3_mReadBd() and XDmaV3_mWriteBd() as defined in
+ * xdmav3_l.h. The USR words are implementation dependent. For example, they may
+ * implement checksum offloading fields for Ethernet devices. Accessor macros
+ * may be defined in the device specific API to get at this data.
+ *
+ * <b>Performance</b>
+ *
+ * BDs are typically in a non-cached memory space. Limiting I/O to BDs can
+ * improve overall performance of the DMA channel.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 3.00a rmm 03/11/06 First release
+ * rmm 06/22/06 Added extern "C"
+ * </pre>
+ *
+ * ***************************************************************************
+ */
+
+#ifndef XDMABD_H /* prevent circular inclusions */
+#define XDMABD_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include <asm/delay.h>
+#include "xdmav3_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * The XDmaBdV3 is the type for buffer descriptors (BDs).
+ */
+typedef u32 XDmaBdV3[XDMAV3_BD_NUM_WORDS];
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+ * Zero out BD fields
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Nothing
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mClear(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mClear(BdPtr) \
+ memset((BdPtr), 0, sizeof(XDmaBdV3))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD's Packet DMA transfer status word.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Word at offset XDMAV3_BD_DMASR_OFFSET
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mGetStatus(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetStatus(BdPtr) \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMASR_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD's Packet status word. This is the first word of local link
+ * footer information for receive channels.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Word at offset XDMAV3_BD_SR_OFFSET
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mGetPacketStatus(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetPacketStatus(BdPtr) \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_SR_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD length field.
+ *
+ * For Tx channels, the returned value is the same as that written with
+ * XDmaBdV3_mSetLength().
+ *
+ * For Rx channels, the returned value is the size of the received packet.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Bytes processed by HW or set by XDmaBdV3_mSetLength().
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mGetLength(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetLength(BdPtr) \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_LENGTH_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD length copy field. See XDmaBdV3_mSetLengthCopy() for
+ * more information.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Value as set by XDmaBdV3_mSetLengthCopy().
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mGetLengthCopy(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetLengthCopy(BdPtr) \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_LENCPY_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Test whether the given BD has been marked as the last BD of a packet.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return TRUE if BD represents the "Last" BD of a packet, FALSE otherwise
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mIsLast(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mIsLast(BdPtr) \
+ ((XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & XDMAV3_DMACR_LAST_MASK) ? \
+ TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ * Set the ID field of the given BD. The ID is an arbitrary piece of data the
+ * user can associate with a specific BD.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param Id is a 32 bit quantity to set in the BD
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetId(XDmaBdV3* BdPtr, void Id)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetId(BdPtr, Id) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_ID_OFFSET, (u32)Id))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the ID field of the given BD previously set with XDmaBdV3_mSetId.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mGetId(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetId(BdPtr) (XDmaV3_mReadBd((BdPtr), XDMAV3_BD_ID_OFFSET))
+
+
+/*****************************************************************************/
+/**
+ * Causes the DMA engine to increment the buffer address during the DMA
+ * transfer for this BD. This is the desirable setting when the buffer data
+ * occupies a memory range.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetBufIncrement(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufIncrement(BdPtr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) | XDMAV3_DMACR_AINC_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Cause the DMA engine to use the same memory buffer address during the DMA
+ * transfer for this BD. This is the desirable setting when the buffer data
+ * occupies a single address as may be the case if transferring to/from a FIFO.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetBufNoIncrement(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufNoIncrement(BdPtr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & ~XDMAV3_DMACR_AINC_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Bypass data realignment engine (DRE) if DMA channel has DRE capability.
+ * Has no effect if channel does not have DRE.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mIgnoreDre(XDmaBdV3* BdPtr)
+ *
+ ******************************************************************************/
+#define XDmaBdV3_mIgnoreDre(BdPtr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) | XDMAV3_DMACR_BPDRE_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Use data realignment engine (DRE) if DMA channel has DRE capability.
+ * Has no effect if channel does not have DRE.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mUseDre(XDmaBdV3* BdPtr)
+ *
+ ******************************************************************************/
+#define XDmaBdV3_mUseDre(BdPtr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & ~XDMAV3_DMACR_BPDRE_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Tell the SG DMA engine that the given BD marks the end of the current packet
+ * to be processed.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetLast(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetLast(BdPtr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) | XDMAV3_DMACR_LAST_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Tell the SG DMA engine that the current packet does not end with the given
+ * BD.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mClearLast(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mClearLast(BdPtr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) & ~XDMAV3_DMACR_LAST_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Set the Device Select field of the given BD.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param DevSel is the IP device select to use with LSB of 1. This value
+ * selects which IP block the transaction will address. Normally this
+ * is set to 0, but complex IP may require a specific DEVSEL.
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetDevSel(XDmaBdV3* BdPtr, unsigned DevSel)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetDevSel(BdPtr, DevSel) \
+ { \
+ u32 Dmacr; \
+ Dmacr = XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET); \
+ Dmacr = Dmacr | (((DevSel) << XDMAV3_DMACR_DEVSEL_SHIFT) & \
+ XDMAV3_DMACR_DEVSEL_MASK); \
+ XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, Dmacr); \
+ }
+
+
+/*****************************************************************************/
+/**
+ * Set the Page field of the given BD. The Page must be in terms of a physical
+ * address. Use this macro if using 36 bit bus addressing.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param Page is the page to set. LSB=1
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetBdPage(XDmaBdV3* BdPtr, unsigned Page)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBdPage(BdPtr, Page) \
+ { \
+ u32 Dmacr; \
+ Dmacr = XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET); \
+ Dmacr = Dmacr | (((Page) << XDMAV3_DMACR_BDPAGE_SHIFT) & \
+ XDMAV3_DMACR_BDPAGE_MASK); \
+ XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, Dmacr); \
+ }
+
+
+/*****************************************************************************/
+/**
+ * Set transfer attributes for the given BD.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param Type defines whether the transfer occurs with single beat or burst
+ * transfers on the target bus. This parameter must be one of the
+ * XDMAV3_DMACR_TYPE_*_MASK constants defined in xdma_l.h.
+ * @param Width defines the width of the transfer as it occurs on the target
+ * bus. This parameter must be one of the XDMAV3_DMACR_DSIZE_*_MASK
+ * constants defined in xdma_l.h
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetTransferType(XDmaBdV3* BdPtr, unsigned Type,
+ * unsigned Width)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetTransferType(BdPtr, Type, Width) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_DMACR_OFFSET, \
+ XDmaV3_mReadBd((BdPtr), XDMAV3_BD_DMACR_OFFSET) | \
+ ((Type) & XDMAV3_DMACR_TYPE_MASK) | ((Width) & XDMAV3_DMACR_DSIZE_MASK)))
+
+
+/*****************************************************************************/
+/**
+ * Set transfer length in bytes for the given BD. The length must be set each
+ * time a BD is submitted to HW.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param LenBytes is the number of bytes to transfer.
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetLength(XDmaBdV3* BdPtr, u32 LenBytes)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetLength(BdPtr, LenBytes) \
+ XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_LENGTH_OFFSET, (LenBytes))
+
+
+/*****************************************************************************/
+/**
+ * Write the given length to the length copy offset of the BD. This function
+ * is useful only if an application needs to recover the number of bytes
+ * originally set by XDmaBdV3_mSetLength() for Rx channels.
+ *
+ * To effectively use this function, an application would call
+ * XDmaBdV3_mSetLength() to set the length on a Rx descriptor, followed by a
+ * call to this macro to set the same length. When HW has processed the Rx
+ * descriptor it will overwrite the BD length field with the actual length of
+ * the packet. When the application performs post processing of the Rx
+ * descriptor, it can call XDmaBdV3_mGetLengthCopy() to find out how many bytes
+ * were originally allocated to the descriptor.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param LenBytes is the number of bytes to transfer.
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetLengthCopy(XDmaBdV3* BdPtr, u32 LenBytes)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetLengthCopy(BdPtr, LenBytes) \
+ XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_LENCPY_OFFSET, (LenBytes))
+
+
+/*****************************************************************************/
+/**
+ * Set the high order address of the BD's buffer address. Use this macro when
+ * the address bus width is greater than 32 bits.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param HighAddr is the high order address bits to set, LSB = 2^32.
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetBufAddrHigh(XDmaBdV3* BdPtr, u32 HighAddr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufAddrHigh(BdPtr, HighAddr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_MSBA_OFFSET, (u32)(HighAddr)))
+
+
+/*****************************************************************************/
+/**
+ * Set the low order address (bits 0..31) of the BD's buffer address.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param LowAddr is the low order address bits to set, LSB = 1.
+ *
+ * @note
+ * C-style signature:
+ * void XDmaBdV3_mSetBufAddrLow(XDmaBdV3* BdPtr, u32 LowAddr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mSetBufAddrLow(BdPtr, LowAddr) \
+ (XDmaV3_mWriteBd((BdPtr), XDMAV3_BD_LSBA_OFFSET, (u32)(LowAddr)))
+
+
+/*****************************************************************************/
+/**
+ * Get the high order address of the BD's buffer address. Use this macro when
+ * the address bus width is greater than 32 bits.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mGetBufAddrHigh(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetBufAddrHigh(BdPtr) \
+ (XDmaV3_mReadBd((BdPtr), XDMAV3_BD_MSBA_OFFSET))
+
+
+/*****************************************************************************/
+/**
+ * Get the low order address (bits 0..31) of the BD's buffer address.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XDmaBdV3_mGetBufAddrLow(XDmaBdV3* BdPtr)
+ *
+ *****************************************************************************/
+#define XDmaBdV3_mGetBufAddrLow(BdPtr) \
+ (XDmaV3_mReadBd((BdPtr), XDMAV3_BD_LSBA_OFFSET))
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_userip.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_userip.h
@@ -0,0 +1,106 @@
+/* $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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma_userip.h
+*
+* This file is for the User-IP core (like Local-Link TEMAC) to define constants
+* that are the User-IP core specific. DMA driver requires the constants to work
+* correctly. Two constants must be defined in this file:
+*
+* - XLLDMA_USR_APPWORD_OFFSET:
+*
+* This constant defines a user word the User-IP always updates in the RX
+* Buffer Descriptors (BD) during any Receive transaction.
+*
+* The DMA driver initializes this chosen user word of any RX BD to the
+* pre-defined value (see XLLDMA_USR_APPWORD_INITVALUE below) before
+* giving it to the RX channel. The DMA relies on its updation (by the
+* User-IP) to ensure the BD has been completed by the RX channel besides
+* checking the COMPLETE bit in XLLDMA_BD_STSCTRL_USR0_OFFSET field (see
+* xlldma_hw.h).
+*
+* The only valid options for this constant are XLLDMA_BD_USR1_OFFSET,
+* XLLDMA_BD_USR2_OFFSET, XLLDMA_BD_USR3_OFFSET and XLLDMA_BD_USR4_OFFSET.
+*
+* If the User-IP does not update any of the option fields above, the DMA
+* driver will not work properly.
+*
+* - XLLDMA_USR_APPWORD_INITVALUE:
+*
+* This constant defines the value the DMA driver uses to populate the
+* XLLDMA_USR_APPWORD_OFFSET field (see above) in any RX BD before giving
+* the BD to the RX channel for receive transaction.
+*
+* It must be ensured that the User-IP will always populates a different
+* value from this constant into the XLLDMA_USR_APPWORD_OFFSET field at
+* the end of any receive transaction. Failing to do so will cause the
+* DMA driver to work improperly.
+*
+* If the User-IP uses different setting, the correct setting must be defined as
+* a compiler options used in the Makefile. In either case the default
+* definition of the constants in this file will be discarded.
+*
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a xd 02/21/07 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_USERIP_H /* prevent circular inclusions */
+#define XLLDMA_USERIP_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xlldma_hw.h"
+
+/************************** Constant Definitions *****************************/
+
+#ifndef XLLDMA_USERIP_APPWORD_OFFSET
+#define XLLDMA_USERIP_APPWORD_OFFSET XLLDMA_BD_USR4_OFFSET
+#endif
+
+#ifndef XLLDMA_USERIP_APPWORD_INITVALUE
+#define XLLDMA_USERIP_APPWORD_INITVALUE 0xFFFFFFFF
+#endif
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_v2_00_a.h
@@ -60,8 +60,8 @@
* </pre>
*
*****************************************************************************/
-#ifndef XPACKET_FIFO_V200A_H /* prevent circular inclusions */
-#define XPACKET_FIFO_V200A_H /* by using protection macros */
+#ifndef XPACKET_FIFO_V200A_H /* prevent circular inclusions */
+#define XPACKET_FIFO_V200A_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
@@ -83,11 +83,10 @@ extern "C" {
* The XPacketFifo driver instance data. The driver is required to allocate a
* variable of this type for every packet FIFO in the device.
*/
-typedef struct
-{
- Xuint32 RegBaseAddress; /**< Base address of registers */
- Xuint32 IsReady; /**< Device is initialized and ready */
- Xuint32 DataBaseAddress; /**< Base address of data for FIFOs */
+typedef struct {
+ u32 RegBaseAddress; /**< Base address of registers */
+ u32 IsReady; /**< Device is initialized and ready */
+ u32 DataBaseAddress;/**< Base address of data for FIFOs */
} XPacketFifoV200a;
/***************** Macros (Inline Functions) Definitions *********************/
@@ -123,7 +122,7 @@ typedef struct
*
* @note
*
-* C Signature: Xuint32 XPF_V200A_GET_COUNT(XPacketFifoV200a *InstancePtr)
+* C Signature: u32 XPF_V200A_GET_COUNT(XPacketFifoV200a *InstancePtr)
*
******************************************************************************/
#define XPF_V200A_GET_COUNT(InstancePtr) \
@@ -141,11 +140,11 @@ typedef struct
*
* @return
*
-* XTRUE if the packet FIFO is almost empty, XFALSE otherwise.
+* TRUE if the packet FIFO is almost empty, FALSE otherwise.
*
* @note
*
-* C Signature: Xboolean XPF_V200A_IS_ALMOST_EMPTY(XPacketFifoV200a *InstancePtr)
+* C Signature: u32 XPF_V200A_IS_ALMOST_EMPTY(XPacketFifoV200a *InstancePtr)
*
******************************************************************************/
#define XPF_V200A_IS_ALMOST_EMPTY(InstancePtr) \
@@ -164,11 +163,11 @@ typedef struct
*
* @return
*
-* XTRUE if the packet FIFO is almost full, XFALSE otherwise.
+* TRUE if the packet FIFO is almost full, FALSE otherwise.
*
* @note
*
-* C Signature: Xboolean XPF_V200A_IS_ALMOST_FULL(XPacketFifoV200a *InstancePtr)
+* C Signature: u32 XPF_V200A_IS_ALMOST_FULL(XPacketFifoV200a *InstancePtr)
*
******************************************************************************/
#define XPF_V200A_IS_ALMOST_FULL(InstancePtr) \
@@ -186,11 +185,11 @@ typedef struct
*
* @return
*
-* XTRUE if the packet FIFO is empty, XFALSE otherwise.
+* TRUE if the packet FIFO is empty, FALSE otherwise.
*
* @note
*
-* C Signature: Xboolean XPF_V200A_IS_EMPTY(XPacketFifoV200a *InstancePtr)
+* C Signature: u32 XPF_V200A_IS_EMPTY(XPacketFifoV200a *InstancePtr)
*
******************************************************************************/
#define XPF_V200A_IS_EMPTY(InstancePtr) \
@@ -208,11 +207,11 @@ typedef struct
*
* @return
*
-* XTRUE if the packet FIFO is full, XFALSE otherwise.
+* TRUE if the packet FIFO is full, FALSE otherwise.
*
* @note
*
-* C Signature: Xboolean XPF_V200A_IS_FULL(XPacketFifoV200a *InstancePtr)
+* C Signature: u32 XPF_V200A_IS_FULL(XPacketFifoV200a *InstancePtr)
*
******************************************************************************/
#define XPF_V200A_IS_FULL(InstancePtr) \
@@ -234,7 +233,7 @@ typedef struct
*
* @return
*
-* XTRUE if the packet FIFO is deadlocked, XFALSE otherwise.
+* TRUE if the packet FIFO is deadlocked, FALSE otherwise.
*
* @note
*
@@ -248,7 +247,7 @@ typedef struct
* to prevent other problems. This error condition could occur as a normal part
* of operation if the size of the FIFO is not setup correctly.
* <br><br>
-* C Signature: Xboolean XPF_V200A_IS_DEADLOCKED(XPacketFifoV200a *InstancePtr)
+* C Signature: u32 XPF_V200A_IS_DEADLOCKED(XPacketFifoV200a *InstancePtr)
*
******************************************************************************/
#define XPF_V200A_IS_DEADLOCKED(InstancePtr) \
@@ -261,27 +260,22 @@ typedef struct
/**
* Standard functions
*/
-XStatus XPacketFifoV200a_Initialize(XPacketFifoV200a *InstancePtr,
- Xuint32 RegBaseAddress,
- Xuint32 DataBaseAddress);
-XStatus XPacketFifoV200a_SelfTest(XPacketFifoV200a *InstancePtr,
- Xuint32 FifoType);
+int XPacketFifoV200a_Initialize(XPacketFifoV200a * InstancePtr,
+ u32 RegBaseAddress, u32 DataBaseAddress);
+int XPacketFifoV200a_SelfTest(XPacketFifoV200a * InstancePtr, u32 FifoType);
/**
* Data functions
*/
-XStatus XPacketFifoV200a_Read(XPacketFifoV200a *InstancePtr,
- Xuint8 *ReadBufferPtr,
- Xuint32 ByteCount);
-XStatus XPacketFifoV200a_Write(XPacketFifoV200a *InstancePtr,
- Xuint8 *WriteBufferPtr,
- Xuint32 ByteCount);
-XStatus XPacketFifoV200a_WriteDre(XPacketFifoV200a *InstancePtr,
- Xuint8 *WriteBufferPtr,
- Xuint32 ByteCount);
+int XPacketFifoV200a_Read(XPacketFifoV200a * InstancePtr,
+ u8 *ReadBufferPtr, u32 ByteCount);
+int XPacketFifoV200a_Write(XPacketFifoV200a * InstancePtr,
+ u8 *WriteBufferPtr, u32 ByteCount);
+int XPacketFifoV200a_WriteDre(XPacketFifoV200a * InstancePtr,
+ u8 *WriteBufferPtr, u32 ByteCount);
#ifdef __cplusplus
}
#endif
-#endif /* end of protection macro */
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xstreamer.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xstreamer.h
@@ -0,0 +1,317 @@
+/* $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 2005-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/*
+ *
+ * @file xstreamer.h
+ *
+ * The Xilinx byte streamer for packet FIFOs.
+ *
+ * <h2>Driver Description</h2>
+ *
+ * This driver enables higher layer software to access a hardware FIFO using
+ * any alignment in the data buffers while preserving alignment for the hardware
+ * FIFO access.
+ *
+ * This driver treats send and receive channels separately, using different
+ * types of instance objects for each.
+ *
+ * This driver makes use of another FIFO driver to access the specific FIFO
+ * hardware through use of the routines passed into the Tx/RxInitialize
+ * routines.
+ *
+ * <h2>Initialization</h2>
+ *
+ * Send and receive channels are intialized separately. The receive channel is
+ * initiailzed using XStrm_RxInitialize(). The send channel is initialized
+ * using XStrm_TxInitialize().
+ *
+ *
+ * <h2>Usage</h2>
+ * It is fairly simple to use the API provided by this byte streamer
+ * driver. The only somewhat tricky part is that the calling code must
+ * correctly call a couple routines in the right sequence for receive and
+ * transmit.
+ *
+ * This sequence is described here. Check the routine functional
+ * descriptions for information on how to use a specific API routine.
+ *
+ * <h3>Receive</h3>
+ * A frame is received by using the following sequence:<br>
+ * 1) call XStrm_RxGetLen() to get the length of the next incoming frame.<br>
+ * 2) call XStrm_Read() one or more times to read the number of bytes
+ * reported by XStrm_RxGetLen().<br>
+ *
+ * For example:
+ * <pre>
+ * frame_len = XStrm_RxGetLen(&RxInstance);
+ * while (frame_len) {
+ * unsigned bytes = min(sizeof(buffer), frame_len);
+ * XStrm_Read(&RxInstance, buffer, bytes);
+ * // do something with buffer here
+ * frame_len -= bytes;
+ * }
+ * </pre>
+ *
+ * Other restrictions on the sequence of API calls may apply depending on
+ * the specific FIFO driver used by this byte streamer driver.
+ *
+ * <h3>Transmit</h3>
+ * A frame is transmittted by using the following sequence:<br>
+ * 1) call XStrm_Write() one or more times to write all the of bytes in
+ * the next frame.<br>
+ * 2) call XStrm_TxSetLen() to begin the transmission of frame just
+ * written.<br>
+ *
+ * For example:
+ * <pre>
+ * frame_left = frame_len;
+ * while (frame_left) {
+ * unsigned bytes = min(sizeof(buffer), frame_left);
+ * XStrm_Write(&TxInstance, buffer, bytes);
+ * // do something here to refill buffer
+ * }
+ * XStrm_TxSetLen(&RxInstance, frame_len);
+ * </pre>
+ *
+ * Other restrictions on the sequence of API calls may apply depending on
+ * the specific FIFO driver used by this byte streamer driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 10/12/06 First release
+ * </pre>
+ *
+ *****************************************************************************/
+#ifndef XSTREAMER_H /* prevent circular inclusions */
+#define XSTREAMER_H /* by using preprocessor symbols */
+
+/* force C linkage */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xdebug.h"
+
+/*
+ * key hole size in 32 bit words
+ */
+#define LARGEST_FIFO_KEYHOLE_SIZE_WORDS 4
+
+/*
+ * This union is used simply to force a 32bit alignment on the
+ * buffer. Only the 'bytes' member is really used.
+ */
+union XStrm_AlignedBufferType {
+ u32 _words[LARGEST_FIFO_KEYHOLE_SIZE_WORDS];
+ char bytes[LARGEST_FIFO_KEYHOLE_SIZE_WORDS * 4];
+};
+
+typedef int(*XStrm_XferFnType) (void *FifoInstance, void *BufPtr,
+ unsigned WordCount);
+typedef u32 (*XStrm_GetLenFnType) (void *FifoInstance);
+typedef void (*XStrm_SetLenFnType) (void *FifoInstance,
+ u32 ByteCount);
+typedef u32 (*XStrm_GetOccupancyFnType) (void *FifoInstance);
+typedef u32 (*XStrm_GetVacancyFnType) (void *FifoInstance);
+
+/**
+ * This typedef defines a run-time instance of a receive byte-streamer.
+ */
+typedef struct XStrm_RxFifoStreamer {
+ union XStrm_AlignedBufferType AlignedBuffer;
+ unsigned HeadIndex; /**< HeadIndex is the index to the AlignedBuffer
+ * as bytes.
+ */
+ unsigned FifoWidth; /**< FifoWidth is the FIFO key hole width in bytes.
+ */
+ unsigned FrmByteCnt; /**< FrmByteCnt is the number of bytes in the next
+ * Frame.
+ */
+ void *FifoInstance; /**< FifoInstance is the FIFO driver instance to
+ * pass to ReadFn, GetLenFn, and GetOccupancyFn
+ * routines.
+ */
+ XStrm_XferFnType ReadFn; /**< ReadFn is the routine the streamer
+ * uses to receive bytes from the Fifo.
+ */
+ XStrm_GetLenFnType GetLenFn; /**< GetLenFn is the routine the streamer
+ * uses to initiate receive operations
+ * on the FIFO.
+ */
+ XStrm_GetOccupancyFnType GetOccupancyFn; /**< GetOccupancyFn is the
+ * routine the streamer uses
+ * to get the occupancy from
+ * the FIFO.
+ */
+} XStrm_RxFifoStreamer;
+
+/**
+ * This typedef defines a run-time instance of a transmit byte-streamer.
+ */
+typedef struct XStrm_TxFifoStreamer {
+ union XStrm_AlignedBufferType AlignedBuffer;
+ unsigned TailIndex; /**< TailIndex is the index to the AlignedBuffer
+ * as bytes
+ */
+ unsigned FifoWidth; /**< FifoWidth is the FIFO key hole width in bytes.
+ */
+
+ void *FifoInstance; /**< FifoInstance is the FIFO driver instance to
+ * pass to WriteFn, SetLenFn, and GetVacancyFn
+ * routines.
+ */
+ XStrm_XferFnType WriteFn; /**< WriteFn is the routine the streamer
+ * uses to transmit bytes to the Fifo.
+ */
+ XStrm_SetLenFnType SetLenFn; /**< SetLenFn is the routine the streamer
+ * uses to initiate transmit operations
+ * on the FIFO.
+ */
+ XStrm_GetVacancyFnType GetVacancyFn; /**< GetVaccancyFn is the routine
+ * the streamer uses to get the
+ * vacancy from the FIFO.
+ */
+} XStrm_TxFifoStreamer;
+
+/*****************************************************************************/
+/*
+*
+* XStrm_TxVacancy returns the number of unused 32-bit words available (vacancy)
+* between the streamer, specified by <i>InstancePtr</i>, and the FIFO this
+* streamer is using.
+*
+* @param InstancePtr references the streamer on which to operate.
+*
+* @return XStrm_TxVacancy returns the vacancy count in number of 32 bit words.
+*
+* @note
+*
+* C Signature: u32 XStrm_TxVacancy(XStrm_TxFifoStreamer *InstancePtr)
+*
+* The amount of bytes in the holding buffer (rounded up to whole 32-bit words)
+* is subtracted from the vacancy value of FIFO this streamer is using. This is
+* to ensure the caller can write the number words given in the return value and
+* not overflow the FIFO.
+*
+******************************************************************************/
+#define XStrm_TxVacancy(InstancePtr) \
+ (((*(InstancePtr)->GetVacancyFn)((InstancePtr)->FifoInstance)) - \
+ (((InstancePtr)->TailIndex + 3) / 4))
+
+/*****************************************************************************/
+/*
+*
+* XStrm_RxOccupancy returns the number of 32-bit words available (occupancy) to
+* be read from the streamer, specified by <i>InstancePtr</i>, and FIFO this
+* steamer is using.
+*
+* @param InstancePtr references the streamer on which to operate.
+*
+* @return XStrm_RxOccupancy returns the occupancy count in number of 32 bit
+* words.
+*
+* @note
+*
+* C Signature: u32 XStrm_RxOccupancy(XStrm_RxFifoStreamer *InstancePtr)
+*
+* The amount of bytes in the holding buffer (rounded up to whole 32-bit words)
+* is added to the occupancy value of FIFO this streamer is using. This is to
+* ensure the caller will get a little more accurate occupancy value.
+*
+******************************************************************************/
+#ifdef DEBUG
+extern u32 _xstrm_ro_value;
+extern u32 _xstrm_buffered;
+#define XStrm_RxOccupancy(InstancePtr) \
+ (_xstrm_ro_value = ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)), \
+ xdbg_printf(XDBG_DEBUG_FIFO_RX, "reg: %d; frmbytecnt: %d\n", \
+ _xstrm_ro_value, (InstancePtr)->FrmByteCnt), \
+ (((InstancePtr)->FrmByteCnt) ? \
+ _xstrm_buffered = ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \
+ 0), \
+ xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered_bytes: %d\n", _xstrm_buffered), \
+ xdbg_printf(XDBG_DEBUG_FIFO_RX, "buffered (rounded): %d\n", _xstrm_buffered), \
+ (_xstrm_ro_value + _xstrm_buffered))
+#else
+#define XStrm_RxOccupancy(InstancePtr) \
+ ( \
+ ((*(InstancePtr)->GetOccupancyFn)((InstancePtr)->FifoInstance)) + \
+ ( \
+ ((InstancePtr)->FrmByteCnt) ? \
+ ((InstancePtr)->FifoWidth - (InstancePtr)->HeadIndex) : \
+ 0 \
+ ) \
+ )
+#endif
+
+/****************************************************************************/
+/*
+*
+* XStrm_IsRxInternalEmpty returns true if the streamer, specified by
+* <i>InstancePtr</i>, is not holding any bytes in it's internal buffers. Note
+* that this routine does not reflect information about the state of the
+* FIFO used by this streamer.
+*
+* @param InstancePtr references the streamer on which to operate.
+*
+* @return XStrm_IsRxInternalEmpty returns TRUE when the streamer is not
+* holding any bytes in it's internal buffers. Otherwise,
+* XStrm_IsRxInternalEmpty returns FALSE.
+*
+* @note
+* C-style signature:
+* int XStrm_IsRxInternalEmpty(XStrm_RxFifoStreamer *InstancePtr)
+*
+*****************************************************************************/
+#define XStrm_IsRxInternalEmpty(InstancePtr) \
+ (((InstancePtr)->HeadIndex == (InstancePtr)->FifoWidth) ? TRUE : FALSE)
+
+void XStrm_RxInitialize(XStrm_RxFifoStreamer *InstancePtr,
+ unsigned FifoWidth, void *FifoInstance,
+ XStrm_XferFnType ReadFn,
+ XStrm_GetLenFnType GetLenFn,
+ XStrm_GetOccupancyFnType GetOccupancyFn);
+
+void XStrm_TxInitialize(XStrm_TxFifoStreamer *InstancePtr,
+ unsigned FifoWidth, void *FifoInstance,
+ XStrm_XferFnType WriteFn,
+ XStrm_SetLenFnType SetLenFn,
+ XStrm_GetVacancyFnType GetVacancyFn);
+
+void XStrm_TxSetLen(XStrm_TxFifoStreamer *InstancePtr, u32 Bytes);
+void XStrm_Write(XStrm_TxFifoStreamer *InstancePtr, void *BufPtr,
+ unsigned bytes);
+
+u32 XStrm_RxGetLen(XStrm_RxFifoStreamer *InstancePtr);
+void XStrm_Read(XStrm_RxFifoStreamer *InstancePtr, void *BufPtr,
+ unsigned bytes);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* XSTREAMER_H end of preprocessor protection symbols */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xstatus.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xstatus.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xstatus.h
@@ -25,13 +25,13 @@
* @file xstatus.h
*
* This file contains Xilinx software status codes. Status codes have their
-* own data type called XStatus. These codes are used throughout the Xilinx
+* 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 */
+#ifndef XSTATUS_H /* prevent circular inclusions */
+#define XSTATUS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
@@ -39,8 +39,6 @@ extern "C" {
/***************************** Include Files *********************************/
-#include "xbasic_types.h"
-
/************************** Constant Definitions *****************************/
/*********************** Common statuses 0 - 500 *****************************/
@@ -52,156 +50,156 @@ extern "C" {
#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 */
+#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 */
+#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
- */
+#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 */
+#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 */
+#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 /* Adapter is out of buffers */
-#define XST_EMAC_PARSE_ERROR 1006L /* Invalid adapter init string */
-#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late
- * collision on polled send */
+#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 /* Adapter is out of buffers */
+#define XST_EMAC_PARSE_ERROR 1006L /* Invalid adapter init string */
+#define XST_EMAC_COLLISION_ERROR 1007L /* Excess deferral or late
+ * collision on polled send */
/*********************** UART statuses 1051 - 1075 ***************************/
#define XST_UART
@@ -216,102 +214,102 @@ extern "C" {
/************************ 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 */
+#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 */
+#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 */
+#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 */
+#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
- */
+#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 */
+#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 */
+#define XST_TMRCTR_TIMER_FAILED 1226 /* self test failed */
/********************** WdtTb statuses 1251 - 1275 ***************************/
@@ -331,7 +329,7 @@ extern "C" {
/********************** SysAce statuses 1351 - 1360 **************************/
-#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted */
+#define XST_SYSACE_NO_LOCK 1351L /* No MPU lock has been granted */
/********************** PCI Bridge statuses 1361 - 1375 **********************/
@@ -339,11 +337,6 @@ extern "C" {
/**************************** Type Definitions *******************************/
-/**
- * The status typedef.
- */
-typedef Xuint32 XStatus;
-
/***************** Macros (Inline Functions) Definitions *********************/
@@ -353,5 +346,4 @@ typedef Xuint32 XStatus;
}
#endif
-#endif /* end of protection macro */
-
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.c.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.c
@@ -103,45 +103,44 @@
* None.
*
******************************************************************************/
-XStatus XDmaChannel_Initialize(XDmaChannel *InstancePtr,
- u32 BaseAddress)
+int XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress)
{
- /* assert to verify input arguments, don't assert base address */
+ /* assert to verify input arguments, don't assert base address */
- XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
- /* setup the base address of the registers for the DMA channel such
- * that register accesses can be done
- */
- InstancePtr->RegBaseAddress = BaseAddress;
+ /* setup the base address of the registers for the DMA channel such
+ * that register accesses can be done
+ */
+ InstancePtr->RegBaseAddress = BaseAddress;
- /* initialize the scatter gather list such that it indicates it has not
- * been created yet and the DMA channel is ready to use (initialized)
- */
- InstancePtr->GetPtr = NULL;
- InstancePtr->PutPtr = NULL;
- InstancePtr->CommitPtr = NULL;
- InstancePtr->LastPtr = NULL;
+ /* initialize the scatter gather list such that it indicates it has not
+ * been created yet and the DMA channel is ready to use (initialized)
+ */
+ InstancePtr->GetPtr = NULL;
+ InstancePtr->PutPtr = NULL;
+ InstancePtr->CommitPtr = NULL;
+ InstancePtr->LastPtr = NULL;
- InstancePtr->TotalDescriptorCount = 0;
- InstancePtr->ActiveDescriptorCount = 0;
+ InstancePtr->TotalDescriptorCount = 0;
+ InstancePtr->ActiveDescriptorCount = 0;
- InstancePtr->ActivePacketCount = 0;
- InstancePtr->Committed = FALSE;
+ InstancePtr->ActivePacketCount = 0;
+ InstancePtr->Committed = FALSE;
- InstancePtr->IsReady = XCOMPONENT_IS_READY;
+ InstancePtr->IsReady = XCOMPONENT_IS_READY;
- /* initialize the version of the component
- */
- XVersion_FromString(&InstancePtr->Version, "1.00a");
+ /* initialize the version of the component
+ */
+ XVersion_FromString(&InstancePtr->Version, "1.00a");
- /* reset the DMA channel such that it's in a known state and ready
- * and indicate the initialization occurred with no errors, note that
- * the is ready variable must be set before this call or reset will assert
- */
- XDmaChannel_Reset(InstancePtr);
+ /* reset the DMA channel such that it's in a known state and ready
+ * and indicate the initialization occurred with no errors, note that
+ * the is ready variable must be set before this call or reset will assert
+ */
+ XDmaChannel_Reset(InstancePtr);
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/*****************************************************************************/
@@ -163,13 +162,13 @@ XStatus XDmaChannel_Initialize(XDmaChann
* None.
*
******************************************************************************/
-u32 XDmaChannel_IsReady(XDmaChannel *InstancePtr)
+u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments used by the base component */
+ /* assert to verify input arguments used by the base component */
- XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
- return InstancePtr->IsReady == XCOMPONENT_IS_READY;
+ return InstancePtr->IsReady == XCOMPONENT_IS_READY;
}
/*****************************************************************************/
@@ -191,16 +190,16 @@ u32 XDmaChannel_IsReady(XDmaChannel *Ins
* None.
*
******************************************************************************/
-XVersion *XDmaChannel_GetVersion(XDmaChannel *InstancePtr)
+XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* return a pointer to the version of the DMA channel */
+ /* return a pointer to the version of the DMA channel */
- return &InstancePtr->Version;
+ return &InstancePtr->Version;
}
/*****************************************************************************/
@@ -231,33 +230,32 @@ XVersion *XDmaChannel_GetVersion(XDmaCha
*
******************************************************************************/
-#define XDC_CONTROL_REG_RESET_MASK 0x98000000UL /* control reg reset value */
+#define XDC_CONTROL_REG_RESET_MASK 0x98000000UL /* control reg reset value */
-XStatus XDmaChannel_SelfTest(XDmaChannel *InstancePtr)
+int XDmaChannel_SelfTest(XDmaChannel * InstancePtr)
{
- u32 ControlReg;
+ u32 ControlReg;
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* reset the DMA channel such that it's in a known state before the test
- * it resets to no interrupts enabled, the desired state for the test
- */
- XDmaChannel_Reset(InstancePtr);
+ /* reset the DMA channel such that it's in a known state before the test
+ * it resets to no interrupts enabled, the desired state for the test
+ */
+ XDmaChannel_Reset(InstancePtr);
- /* this should be the first test to help prevent a lock up with the polling
- * loop that occurs later in the test, check the reset value of the DMA
- * control register to make sure it's correct, return with an error if not
- */
- ControlReg = XDmaChannel_GetControl(InstancePtr);
- if (ControlReg != XDC_CONTROL_REG_RESET_MASK)
- {
- return XST_DMA_RESET_REGISTER_ERROR;
- }
+ /* this should be the first test to help prevent a lock up with the polling
+ * loop that occurs later in the test, check the reset value of the DMA
+ * control register to make sure it's correct, return with an error if not
+ */
+ ControlReg = XDmaChannel_GetControl(InstancePtr);
+ if (ControlReg != XDC_CONTROL_REG_RESET_MASK) {
+ return XST_DMA_RESET_REGISTER_ERROR;
+ }
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/*****************************************************************************/
@@ -283,17 +281,18 @@ XStatus XDmaChannel_SelfTest(XDmaChannel
* None.
*
******************************************************************************/
-void XDmaChannel_Reset(XDmaChannel *InstancePtr)
+void XDmaChannel_Reset(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_VOID(InstancePtr != NULL);
- XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* reset the DMA channel such that it's in a known state, the reset
- * register is self clearing such that it only has to be set
- */
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET, XDC_RESET_MASK);
+ /* reset the DMA channel such that it's in a known state, the reset
+ * register is self clearing such that it only has to be set
+ */
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET,
+ XDC_RESET_MASK);
}
/*****************************************************************************/
@@ -330,16 +329,16 @@ void XDmaChannel_Reset(XDmaChannel *Inst
* None.
*
******************************************************************************/
-u32 XDmaChannel_GetControl(XDmaChannel *InstancePtr)
+u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* return the contents of the DMA control register */
+ /* return the contents of the DMA control register */
- return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+ return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
}
/*****************************************************************************/
@@ -374,24 +373,25 @@ u32 XDmaChannel_GetControl(XDmaChannel *
* None.
*
******************************************************************************/
-void XDmaChannel_SetControl(XDmaChannel *InstancePtr, u32 Control)
+void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control)
{
- u32 Register;
- /* assert to verify input arguments except the control which can't be
- * asserted since all values are valid
- */
- XASSERT_VOID(InstancePtr != NULL);
- XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /*
- * set the DMA control register to the specified value, not altering the
- * other fields in the register
- */
-
- Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
- Register &= XDC_DMACR_TX_CS_INIT_MASK;
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
- Register | Control);
+ u32 Register;
+
+ /* assert to verify input arguments except the control which can't be
+ * asserted since all values are valid
+ */
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /*
+ * set the DMA control register to the specified value, not altering the
+ * other fields in the register
+ */
+
+ Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+ Register &= XDC_DMACR_TX_CS_INIT_MASK;
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
+ Register | Control);
}
/*****************************************************************************/
@@ -422,16 +422,16 @@ void XDmaChannel_SetControl(XDmaChannel
* None.
*
******************************************************************************/
-u32 XDmaChannel_GetStatus(XDmaChannel *InstancePtr)
+u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* return the contents of the DMA status register */
+ /* return the contents of the DMA status register */
- return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+ return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
}
/*****************************************************************************/
@@ -470,19 +470,19 @@ u32 XDmaChannel_GetStatus(XDmaChannel *I
* None.
*
******************************************************************************/
-void XDmaChannel_SetIntrStatus(XDmaChannel *InstancePtr, u32 Status)
+void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status)
{
- /* assert to verify input arguments except the status which can't be
- * asserted since all values are valid
- */
- XASSERT_VOID(InstancePtr != NULL);
- XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* set the interrupt status register with the specified value such that
- * all bits which are set in the register are cleared effectively clearing
- * any active interrupts
- */
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, Status);
+ /* assert to verify input arguments except the status which can't be
+ * asserted since all values are valid
+ */
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* set the interrupt status register with the specified value such that
+ * all bits which are set in the register are cleared effectively clearing
+ * any active interrupts
+ */
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, Status);
}
/*****************************************************************************/
@@ -526,16 +526,16 @@ void XDmaChannel_SetIntrStatus(XDmaChann
* None.
*
******************************************************************************/
-u32 XDmaChannel_GetIntrStatus(XDmaChannel *InstancePtr)
+u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* return the contents of the interrupt status register */
+ /* return the contents of the interrupt status register */
- return XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
+ return XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
}
/*****************************************************************************/
@@ -576,17 +576,17 @@ u32 XDmaChannel_GetIntrStatus(XDmaChanne
* None.
*
******************************************************************************/
-void XDmaChannel_SetIntrEnable(XDmaChannel *InstancePtr, u32 Enable)
+void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable)
{
- /* assert to verify input arguments except the enable which can't be
- * asserted since all values are valid
- */
- XASSERT_VOID(InstancePtr != NULL);
- XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /* assert to verify input arguments except the enable which can't be
+ * asserted since all values are valid
+ */
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* set the interrupt enable register to the specified value */
+ /* set the interrupt enable register to the specified value */
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET, Enable);
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET, Enable);
}
/*****************************************************************************/
@@ -625,16 +625,16 @@ void XDmaChannel_SetIntrEnable(XDmaChann
* None.
*
******************************************************************************/
-u32 XDmaChannel_GetIntrEnable(XDmaChannel *InstancePtr)
+u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* return the contents of the interrupt enable register */
+ /* return the contents of the interrupt enable register */
- return XIo_In32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET);
+ return XIo_In32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET);
}
/*****************************************************************************/
@@ -685,32 +685,30 @@ u32 XDmaChannel_GetIntrEnable(XDmaChanne
* if address translation is being used.
*
******************************************************************************/
-void XDmaChannel_Transfer(XDmaChannel *InstancePtr,
- u32 *SourcePtr,
- u32 *DestinationPtr,
- u32 ByteCount)
-{
- /* assert to verify input arguments and the alignment of any arguments
- * which have expected alignments
- */
- XASSERT_VOID(InstancePtr != NULL);
- XASSERT_VOID(SourcePtr != NULL);
- XASSERT_VOID(((u32)SourcePtr & 3) == 0);
- XASSERT_VOID(DestinationPtr != NULL);
- XASSERT_VOID(((u32)DestinationPtr & 3) == 0);
- XASSERT_VOID(ByteCount != 0);
- XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* setup the source and destination address registers for the transfer */
-
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_SA_REG_OFFSET,
- (u32)SourcePtr);
-
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_DA_REG_OFFSET,
- (u32)DestinationPtr);
-
- /* start the DMA transfer to copy from the source buffer to the
- * destination buffer by writing the length to the length register
- */
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_LEN_REG_OFFSET, ByteCount);
+void XDmaChannel_Transfer(XDmaChannel * InstancePtr,
+ u32 *SourcePtr, u32 *DestinationPtr, u32 ByteCount)
+{
+ /* assert to verify input arguments and the alignment of any arguments
+ * which have expected alignments
+ */
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(SourcePtr != NULL);
+ XASSERT_VOID(((u32) SourcePtr & 3) == 0);
+ XASSERT_VOID(DestinationPtr != NULL);
+ XASSERT_VOID(((u32) DestinationPtr & 3) == 0);
+ XASSERT_VOID(ByteCount != 0);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* setup the source and destination address registers for the transfer */
+
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_SA_REG_OFFSET,
+ (u32) SourcePtr);
+
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_DA_REG_OFFSET,
+ (u32) DestinationPtr);
+
+ /* start the DMA transfer to copy from the source buffer to the
+ * destination buffer by writing the length to the length register
+ */
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_LEN_REG_OFFSET, ByteCount);
}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdebug.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdebug.h
@@ -0,0 +1,48 @@
+#ifndef XDEBUG
+#define XDEBUG
+
+#undef DEBUG
+
+#if defined(DEBUG) && !defined(NDEBUG)
+
+#ifndef XDEBUG_WARNING
+#define XDEBUG_WARNING
+#warning DEBUG is enabled
+#endif
+
+int printf(const char *format, ...);
+
+#define XDBG_DEBUG_ERROR 0x00000001 /* error condition messages */
+#define XDBG_DEBUG_GENERAL 0x00000002 /* general debug messages */
+#define XDBG_DEBUG_ALL 0xFFFFFFFF /* all debugging data */
+
+#define XDBG_DEBUG_FIFO_REG 0x00000100 /* display register reads/writes */
+#define XDBG_DEBUG_FIFO_RX 0x00000101 /* receive debug messages */
+#define XDBG_DEBUG_FIFO_TX 0x00000102 /* transmit debug messages */
+#define XDBG_DEBUG_FIFO_ALL 0x0000010F /* all fifo debug messages */
+
+#define XDBG_DEBUG_TEMAC_REG 0x00000400 /* display register reads/writes */
+#define XDBG_DEBUG_TEMAC_RX 0x00000401 /* receive debug messages */
+#define XDBG_DEBUG_TEMAC_TX 0x00000402 /* transmit debug messages */
+#define XDBG_DEBUG_TEMAC_ALL 0x0000040F /* all temac debug messages */
+
+#define XDBG_DEBUG_TEMAC_ADPT_RX 0x00000800 /* receive debug messages */
+#define XDBG_DEBUG_TEMAC_ADPT_TX 0x00000801 /* transmit debug messages */
+#define XDBG_DEBUG_TEMAC_ADPT_IOCTL 0x00000802 /* ioctl debug messages */
+#define XDBG_DEBUG_TEMAC_ADPT_MISC 0x00000803 /* debug msg for other routines */
+#define XDBG_DEBUG_TEMAC_ADPT_ALL 0x0000080F /* all temac adapter debug messages */
+
+#define xdbg_current_types (XDBG_DEBUG_ERROR | XDBG_DEBUG_GENERAL | XDBG_DEBUG_FIFO_REG | XDBG_DEBUG_TEMAC_REG)
+
+#define xdbg_stmnt(x) x
+#define xdbg_printf(type, ...) (if ((type) & xdbg_current_types) printf (__VA_ARGS__) : 0)
+
+#else
+#define xdbg_stmnt(x)
+#define xdbg_printf(...)
+#endif
+
+
+
+
+#endif /* XDEBUG */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xenv.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xenv.h
@@ -0,0 +1,241 @@
+/******************************************************************************
+*
+* 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 xenv_linux.h
+*
+* Defines common services specified by xenv.h.
+*
+* @note
+* This file is not intended to be included directly by driver code.
+* Instead, the generic xenv.h file is intended to be included by driver
+* code.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-----------------------------------------------
+* 1.00a wgr 02/28/07 Added cache handling macros.
+* 1.00a wgr 02/27/07 Simplified code. Deprecated old-style macro names.
+* 1.00a xd 11/03/04 Improved support for doxygen.
+* 1.00a ch 10/24/02 First release
+* 1.10a wgr 03/22/07 Converted to new coding style.
+* </pre>
+*
+*
+******************************************************************************/
+
+#ifndef XENV_LINUX_H
+#define XENV_LINUX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+
+
+/******************************************************************************
+ *
+ * MEMCPY / MEMSET related macros.
+ *
+ * Those macros are defined to catch legacy code in Xilinx drivers. The
+ * XENV_MEM_COPY and XENV_MEM_FILL macros were used in early Xilinx driver
+ * code. They are being replaced by memcpy() and memset() function calls. These
+ * macros are defined to catch any remaining occurences of those macros.
+ *
+ ******************************************************************************/
+
+/*****************************************************************************/
+/**
+ *
+ * Copies a non-overlapping block of memory.
+ *
+ * @param DestPtr
+ * Destination address to copy data to.
+ *
+ * @param SrcPtr
+ * Source address to copy data from.
+ *
+ * @param Bytes
+ * Number of bytes to copy.
+ *
+ * @return None.
+ *
+ *****************************************************************************/
+
+#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \
+ memcpy(DestPtr, SrcPtr, Bytes)
+/* do_not_use_XENV_MEM_COPY_use_memcpy_instead */
+
+
+/*****************************************************************************/
+/**
+ *
+ * Fills an area of memory with constant data.
+ *
+ * @param DestPtr
+ * Destination address to copy data to.
+ *
+ * @param Data
+ * Value to set.
+ *
+ * @param Bytes
+ * Number of bytes to copy.
+ *
+ * @return None.
+ *
+ *****************************************************************************/
+
+#define XENV_MEM_FILL(DestPtr, Data, Bytes) \
+ memset(DestPtr, Data, Bytes)
+/* do_not_use_XENV_MEM_FILL_use_memset_instead */
+
+
+/******************************************************************************
+ *
+ * TIME related macros
+ *
+ ******************************************************************************/
+/**
+ * A structure that contains a time stamp used by other time stamp macros
+ * defined below. This structure is processor dependent.
+ */
+typedef int XENV_TIME_STAMP;
+
+/*****************************************************************************/
+/**
+ *
+ * Time is derived from the 64 bit PPC timebase register
+ *
+ * @param StampPtr is the storage for the retrieved time stamp.
+ *
+ * @return None.
+ *
+ * @note
+ *
+ * Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr)
+ * <br><br>
+ * This macro must be implemented by the user.
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_GET(StampPtr)
+
+/*****************************************************************************/
+/**
+ *
+ * This macro is not yet implemented and always returns 0.
+ *
+ * @param Stamp1Ptr is the first sampled time stamp.
+ * @param Stamp2Ptr is the second sampled time stamp.
+ *
+ * @return 0
+ *
+ * @note
+ *
+ * This macro must be implemented by the user.
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0)
+
+/*****************************************************************************/
+/**
+ *
+ * This macro is not yet implemented and always returns 0.
+ *
+ * @param Stamp1Ptr is the first sampled time stamp.
+ * @param Stamp2Ptr is the second sampled time stamp.
+ *
+ * @return 0
+ *
+ * @note
+ *
+ * This macro must be implemented by the user
+ *
+ *****************************************************************************/
+#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0)
+
+/*****************************************************************************/
+/**
+ *
+ * Delay the specified number of microseconds.
+ *
+ * @param delay
+ * Number of microseconds to delay.
+ *
+ * @return None.
+ *
+ * @note XENV_USLEEP is deprecated. Use udelay() instead.
+ *
+ *****************************************************************************/
+
+#define XENV_USLEEP(delay) udelay(delay)
+/* do_not_use_XENV_MEM_COPY_use_memcpy_instead */
+
+
+/******************************************************************************
+ *
+ * CACHE handling macros / mappings
+ *
+ * The implementation of the cache handling functions can be found in
+ * arch/microblaze.
+ *
+ * These #defines are simple mappings to the Linux API.
+ *
+ * The underlying Linux implementation will take care of taking the right
+ * actions depending on the configuration of the MicroBlaze processor in the
+ * system.
+ *
+ ******************************************************************************/
+
+#define XCACHE_ENABLE_DCACHE() __enable_dcache()
+#define XCACHE_DISABLE_DCACHE() __disable_dcache()
+#define XCACHE_ENABLE_ICACHE() __enable_icache()
+#define XCACHE_DISABLE_ICACHE() __disable_icache()
+
+#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) flush_dcache_range((u32)(Addr), (u32)((Addr)+(Len)))
+#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) flush_dcache_range((u32)(Addr), (u32)((Addr)+(Len)))
+
+#define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) "XCACHE_INVALIDATE_ICACHE_RANGE unsupported"
+#define XCACHE_FLUSH_ICACHE_RANGE(Addr, Len) flush_icache_range(Addr, Len)
+
+#define XCACHE_ENABLE_CACHE() \
+ { XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); }
+
+#define XCACHE_DISABLE_CACHE() \
+ { XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); }
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
+
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xilinx_syms.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xilinx_syms.c.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xilinx_syms.c
@@ -1,7 +1,7 @@
/*
* xilinx_syms.c
*
- * This file EXPORT_SYMBOL_GPL's all of the Xilinx entry points.
+ * This file EXPORT_SYMBOL's all of the Xilinx entry points.
*
* Author: MontaVista Software, Inc.
* source@xxxxxxxxxx
@@ -14,53 +14,53 @@
#include <linux/module.h>
#include "xbasic_types.h"
-EXPORT_SYMBOL_GPL(XAssert);
-EXPORT_SYMBOL_GPL(XAssertSetCallback);
-EXPORT_SYMBOL_GPL(XAssertStatus);
+EXPORT_SYMBOL(XAssert);
+EXPORT_SYMBOL(XAssertSetCallback);
+EXPORT_SYMBOL(XAssertStatus);
extern u32 XWaitInAssert;
-EXPORT_SYMBOL_GPL(XWaitInAssert);
+EXPORT_SYMBOL(XWaitInAssert);
#include "xdma_channel.h"
-EXPORT_SYMBOL_GPL(XDmaChannel_CommitPuts);
-EXPORT_SYMBOL_GPL(XDmaChannel_CreateSgList);
-EXPORT_SYMBOL_GPL(XDmaChannel_DecrementPktCount);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetControl);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetDescriptor);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetIntrEnable);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetIntrStatus);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetPktCount);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetPktThreshold);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetPktWaitBound);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetStatus);
-EXPORT_SYMBOL_GPL(XDmaChannel_GetVersion);
-EXPORT_SYMBOL_GPL(XDmaChannel_Initialize);
-EXPORT_SYMBOL_GPL(XDmaChannel_IsReady);
-EXPORT_SYMBOL_GPL(XDmaChannel_IsSgListEmpty);
-EXPORT_SYMBOL_GPL(XDmaChannel_PutDescriptor);
-EXPORT_SYMBOL_GPL(XDmaChannel_Reset);
-EXPORT_SYMBOL_GPL(XDmaChannel_SelfTest);
-EXPORT_SYMBOL_GPL(XDmaChannel_SetControl);
-EXPORT_SYMBOL_GPL(XDmaChannel_SetIntrEnable);
-EXPORT_SYMBOL_GPL(XDmaChannel_SetIntrStatus);
-EXPORT_SYMBOL_GPL(XDmaChannel_SetPktThreshold);
-EXPORT_SYMBOL_GPL(XDmaChannel_SetPktWaitBound);
-EXPORT_SYMBOL_GPL(XDmaChannel_SgStart);
-EXPORT_SYMBOL_GPL(XDmaChannel_SgStop);
-EXPORT_SYMBOL_GPL(XDmaChannel_Transfer);
+EXPORT_SYMBOL(XDmaChannel_CommitPuts);
+EXPORT_SYMBOL(XDmaChannel_CreateSgList);
+EXPORT_SYMBOL(XDmaChannel_DecrementPktCount);
+EXPORT_SYMBOL(XDmaChannel_GetControl);
+EXPORT_SYMBOL(XDmaChannel_GetDescriptor);
+EXPORT_SYMBOL(XDmaChannel_GetIntrEnable);
+EXPORT_SYMBOL(XDmaChannel_GetIntrStatus);
+EXPORT_SYMBOL(XDmaChannel_GetPktCount);
+EXPORT_SYMBOL(XDmaChannel_GetPktThreshold);
+EXPORT_SYMBOL(XDmaChannel_GetPktWaitBound);
+EXPORT_SYMBOL(XDmaChannel_GetStatus);
+EXPORT_SYMBOL(XDmaChannel_GetVersion);
+EXPORT_SYMBOL(XDmaChannel_Initialize);
+EXPORT_SYMBOL(XDmaChannel_IsReady);
+EXPORT_SYMBOL(XDmaChannel_IsSgListEmpty);
+EXPORT_SYMBOL(XDmaChannel_PutDescriptor);
+EXPORT_SYMBOL(XDmaChannel_Reset);
+EXPORT_SYMBOL(XDmaChannel_SelfTest);
+EXPORT_SYMBOL(XDmaChannel_SetControl);
+EXPORT_SYMBOL(XDmaChannel_SetIntrEnable);
+EXPORT_SYMBOL(XDmaChannel_SetIntrStatus);
+EXPORT_SYMBOL(XDmaChannel_SetPktThreshold);
+EXPORT_SYMBOL(XDmaChannel_SetPktWaitBound);
+EXPORT_SYMBOL(XDmaChannel_SgStart);
+EXPORT_SYMBOL(XDmaChannel_SgStop);
+EXPORT_SYMBOL(XDmaChannel_Transfer);
#include "xipif_v1_23_b.h"
-//EXPORT_SYMBOL_GPL(XIpIfV123b_SelfTest);
+EXPORT_SYMBOL(XIpIfV123b_SelfTest);
#include "xpacket_fifo_v2_00_a.h"
-EXPORT_SYMBOL_GPL(XPacketFifoV200a_Initialize);
-EXPORT_SYMBOL_GPL(XPacketFifoV200a_Read);
-EXPORT_SYMBOL_GPL(XPacketFifoV200a_SelfTest);
-EXPORT_SYMBOL_GPL(XPacketFifoV200a_Write);
+EXPORT_SYMBOL(XPacketFifoV200a_Initialize);
+EXPORT_SYMBOL(XPacketFifoV200a_Read);
+EXPORT_SYMBOL(XPacketFifoV200a_SelfTest);
+EXPORT_SYMBOL(XPacketFifoV200a_Write);
#include "xversion.h"
-EXPORT_SYMBOL_GPL(XVersion_Copy);
-EXPORT_SYMBOL_GPL(XVersion_FromString);
-EXPORT_SYMBOL_GPL(XVersion_IsEqual);
-EXPORT_SYMBOL_GPL(XVersion_Pack);
-EXPORT_SYMBOL_GPL(XVersion_ToString);
-EXPORT_SYMBOL_GPL(XVersion_UnPack);
+EXPORT_SYMBOL(XVersion_Copy);
+EXPORT_SYMBOL(XVersion_FromString);
+EXPORT_SYMBOL(XVersion_IsEqual);
+EXPORT_SYMBOL(XVersion_Pack);
+EXPORT_SYMBOL(XVersion_ToString);
+EXPORT_SYMBOL(XVersion_UnPack);
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel.h
@@ -166,8 +166,8 @@
*
******************************************************************************/
-#ifndef XDMA_CHANNEL_H /* prevent circular inclusions */
-#define XDMA_CHANNEL_H /* by using protection macros */
+#ifndef XDMA_CHANNEL_H /* prevent circular inclusions */
+#define XDMA_CHANNEL_H /* by using protection macros */
/***************************** Include Files *********************************/
@@ -175,36 +175,36 @@
#include "xstatus.h"
#include "xversion.h"
#include "xbuf_descriptor.h"
-#include "xdma_channel_i.h" /* constants shared with buffer descriptor */
+#include "xdma_channel_i.h" /* constants shared with buffer descriptor */
/************************** Constant Definitions *****************************/
/* the following constants provide access to the bit fields of the DMA control
* register (DMACR)
*/
-#define XDC_DMACR_SOURCE_INCR_MASK 0x80000000UL /* increment source address */
-#define XDC_DMACR_DEST_INCR_MASK 0x40000000UL /* increment dest address */
-#define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL /* local source address */
-#define XDC_DMACR_DEST_LOCAL_MASK 0x10000000UL /* local dest address */
-#define XDC_DMACR_SG_DISABLE_MASK 0x08000000UL /* scatter gather disable */
-#define XDC_DMACR_GEN_BD_INTR_MASK 0x04000000UL /* descriptor interrupt */
-#define XDC_DMACR_LAST_BD_MASK XDC_CONTROL_LAST_BD_MASK /* last buffer */
- /* descriptor */
-#define XDC_DMACR_DRE_MODE_MASK 0x01000000UL /* DRE/normal mode */
-
-#define XDC_DMACR_TX_CS_INIT_MASK 0x0000FFFFUL /* Initial value for TX
- CS offload */
-#define XDC_DMACR_CS_OFFLOAD_MASK 0x00800000UL /* Enable CS offload */
+#define XDC_DMACR_SOURCE_INCR_MASK 0x80000000UL /* increment source address */
+#define XDC_DMACR_DEST_INCR_MASK 0x40000000UL /* increment dest address */
+#define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL /* local source address */
+#define XDC_DMACR_DEST_LOCAL_MASK 0x10000000UL /* local dest address */
+#define XDC_DMACR_SG_DISABLE_MASK 0x08000000UL /* scatter gather disable */
+#define XDC_DMACR_GEN_BD_INTR_MASK 0x04000000UL /* descriptor interrupt */
+#define XDC_DMACR_LAST_BD_MASK XDC_CONTROL_LAST_BD_MASK /* last buffer */
+ /* descriptor */
+#define XDC_DMACR_DRE_MODE_MASK 0x01000000UL /* DRE/normal mode */
+
+#define XDC_DMACR_TX_CS_INIT_MASK 0x0000FFFFUL /* Initial value for TX
+ CS offload */
+#define XDC_DMACR_CS_OFFLOAD_MASK 0x00800000UL /* Enable CS offload */
/* the following constants provide access to the bit fields of the DMA status
* register (DMASR)
*/
-#define XDC_DMASR_BUSY_MASK 0x80000000UL /* channel is busy */
-#define XDC_DMASR_BUS_ERROR_MASK 0x40000000UL /* bus error occurred */
-#define XDC_DMASR_BUS_TIMEOUT_MASK 0x20000000UL /* bus timeout occurred */
-#define XDC_DMASR_LAST_BD_MASK XDC_STATUS_LAST_BD_MASK /* last buffer */
- /* descriptor */
-#define XDC_DMASR_SG_BUSY_MASK 0x08000000UL /* scatter gather is busy */
+#define XDC_DMASR_BUSY_MASK 0x80000000UL /* channel is busy */
+#define XDC_DMASR_BUS_ERROR_MASK 0x40000000UL /* bus error occurred */
+#define XDC_DMASR_BUS_TIMEOUT_MASK 0x20000000UL /* bus timeout occurred */
+#define XDC_DMASR_LAST_BD_MASK XDC_STATUS_LAST_BD_MASK /* last buffer */
+ /* descriptor */
+#define XDC_DMASR_SG_BUSY_MASK 0x08000000UL /* scatter gather is busy */
/* @} */
/** @name DMA destination address register bit fields when checksum offload is
@@ -214,24 +214,24 @@
* Destination Address Register (DAREG)
* @{
*/
-#define XDC_DAREG_CS_BEGIN_MASK 0xFFFF0000UL /* byte position to begin
- checksum calculation*/
-#define XDC_DAREG_CS_INSERT_MASK 0x0000FFFFUL /* byte position to place
- calculated checksum */
+#define XDC_DAREG_CS_BEGIN_MASK 0xFFFF0000UL /* byte position to begin
+ checksum calculation */
+#define XDC_DAREG_CS_INSERT_MASK 0x0000FFFFUL /* byte position to place
+ calculated checksum */
/* the following constants provide access to the bit fields of the interrupt
* status register (ISR) and the interrupt enable register (IER), bit masks
* match for both registers such that they are named IXR
*/
-#define XDC_IXR_DMA_DONE_MASK 0x1UL /* dma operation done */
-#define XDC_IXR_DMA_ERROR_MASK 0x2UL /* dma operation error */
-#define XDC_IXR_PKT_DONE_MASK 0x4UL /* packet done */
-#define XDC_IXR_PKT_THRESHOLD_MASK 0x8UL /* packet count threshold */
-#define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL /* packet wait bound reached */
-#define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL /* scatter gather disable
- acknowledge occurred */
-#define XDC_IXR_SG_END_MASK 0x40UL /* last buffer descriptor
- disabled scatter gather */
-#define XDC_IXR_BD_MASK 0x80UL /* buffer descriptor done */
+#define XDC_IXR_DMA_DONE_MASK 0x1UL /* dma operation done */
+#define XDC_IXR_DMA_ERROR_MASK 0x2UL /* dma operation error */
+#define XDC_IXR_PKT_DONE_MASK 0x4UL /* packet done */
+#define XDC_IXR_PKT_THRESHOLD_MASK 0x8UL /* packet count threshold */
+#define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL /* packet wait bound reached */
+#define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL /* scatter gather disable
+ acknowledge occurred */
+#define XDC_IXR_SG_END_MASK 0x40UL /* last buffer descriptor
+ disabled scatter gather */
+#define XDC_IXR_BD_MASK 0x80UL /* buffer descriptor done */
/**************************** Type Definitions *******************************/
@@ -240,33 +240,33 @@
* for the XDmaChannel component
*/
typedef struct XDmaChannelTag {
- XVersion Version; /* version of the driver */
- u32 RegBaseAddress; /* base address of registers */
- u32 IsReady; /* device is initialized and ready */
-
- XBufDescriptor *PutPtr; /* keep track of where to put into list */
- XBufDescriptor *GetPtr; /* keep track of where to get from list */
- XBufDescriptor *CommitPtr; /* keep track of where to commit in list */
- XBufDescriptor *LastPtr; /* keep track of the last put in the list */
- void *VirtPtr; /* virtual base of memory */
- void *PhyPtr; /* physical base of memory */
- u32 TotalDescriptorCount; /* total # of descriptors in the list */
- u32 ActiveDescriptorCount; /* # of descriptors pointing to buffers
- * in the buffer descriptor list */
- u32 ActivePacketCount; /* # of packets that have been put into
- the list and transmission confirmation
- have not been received by the driver */
- Xboolean Committed; /* CommitPuts is called? */
+ XVersion Version; /* version of the driver */
+ u32 RegBaseAddress; /* base address of registers */
+ u32 IsReady; /* device is initialized and ready */
+
+ XBufDescriptor *PutPtr; /* keep track of where to put into list */
+ XBufDescriptor *GetPtr; /* keep track of where to get from list */
+ XBufDescriptor *CommitPtr; /* keep track of where to commit in list */
+ XBufDescriptor *LastPtr; /* keep track of the last put in the list */
+ void *VirtPtr; /* virtual base of memory */
+ void *PhyPtr; /* physical base of memory */
+ u32 TotalDescriptorCount; /* total # of descriptors in the list */
+ u32 ActiveDescriptorCount; /* # of descriptors pointing to buffers
+ * in the buffer descriptor list */
+ u32 ActivePacketCount; /* # of packets that have been put into
+ the list and transmission confirmation
+ have not been received by the driver */
+ u32 Committed; /* CommitPuts is called? */
} XDmaChannel;
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
-XStatus XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress);
+int XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress);
u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr);
XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr);
-XStatus XDmaChannel_SelfTest(XDmaChannel * InstancePtr);
+int XDmaChannel_SelfTest(XDmaChannel * InstancePtr);
void XDmaChannel_Reset(XDmaChannel * InstancePtr);
/* Control functions */
@@ -285,30 +285,30 @@ u32 XDmaChannel_GetIntrEnable(XDmaChanne
/* DMA without scatter gather functions */
void XDmaChannel_Transfer(XDmaChannel * InstancePtr,
- u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount);
+ u32 *SourcePtr, u32 *DestinationPtr, u32 ByteCount);
/* Scatter gather functions */
-XStatus XDmaChannel_SgStart(XDmaChannel * InstancePtr);
-XStatus XDmaChannel_SgStop(XDmaChannel * InstancePtr,
- XBufDescriptor ** BufDescriptorPtr);
-XStatus XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
- u32 * MemoryPtr, u32 ByteCount, void *PhyPtr);
+int XDmaChannel_SgStart(XDmaChannel * InstancePtr);
+int XDmaChannel_SgStop(XDmaChannel * InstancePtr,
+ XBufDescriptor ** BufDescriptorPtr);
+int XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
+ u32 *MemoryPtr, u32 ByteCount, void *PhyPtr);
u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr);
-XStatus XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
- XBufDescriptor * BufDescriptorPtr);
-XStatus XDmaChannel_CommitPuts(XDmaChannel * InstancePtr);
-XStatus XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
- XBufDescriptor ** BufDescriptorPtr);
+int XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
+ XBufDescriptor * BufDescriptorPtr);
+int XDmaChannel_CommitPuts(XDmaChannel * InstancePtr);
+int XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
+ XBufDescriptor ** BufDescriptorPtr);
/* Packet functions for interrupt collescing */
u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr);
void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr);
-XStatus XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold);
+int XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold);
u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr);
void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound);
u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr);
-#endif /* end of protection macro */
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xio_dcr.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xio_dcr.c
@@ -0,0 +1,512 @@
+/* $Id: xio_dcr.c,v 1.9 2007/01/24 17:00:16 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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xio_dcr.c
+*
+* The implementation of the XDcrIo interface. See xio_dcr.h for more
+* information about the component.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-----------------------------------------------
+* 1.00a ecm 11/09/06 Modified from the PPC405 version to use the indirect
+* addressing that is available in the PPC440 block in V5.
+* Removed the jump table structure in xio_dcr.c also.
+* Added functionality from the SEG driver to allow for
+* one file pair.
+* 1.00a ecm 01/02/07 Incorporated changes from testing with multiple DCR
+* masters, discovered and fixed several concurrency
+* issues.
+* 1.00a ecm 01/24/07 update for new coding standard.
+* </pre>
+*
+* @internal
+*
+* The C functions which subsequently call into either the assembly code or into
+* the provided table of functions are required since the registers assigned to
+* the calling and return from functions are strictly defined in the ABI and that
+* definition is used in the low-level functions directly. The use of macros is
+* not recommended since the temporary registers in the ABI are defined but there
+* is no way to force the compiler to use a specific register in a block of code.
+*
+*****************************************************************************/
+
+/***************************** Include Files ********************************/
+
+#include <asm/dcr.h>
+#include <asm/reg.h>
+
+#include "xstatus.h"
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xio_dcr.h"
+
+/************************** Constant Definitions ****************************/
+
+/*
+ * base address defines for each of the four possible DCR base
+ * addresses a processor can have
+ */
+#define XDCR_0_BASEADDR 0x000
+#define XDCR_1_BASEADDR 0x100
+#define XDCR_2_BASEADDR 0x200
+#define XDCR_3_BASEADDR 0x300
+
+
+#define MAX_DCR_REGISTERS 4096
+#define MAX_DCR_REGISTER MAX_DCR_REGISTERS - 1
+#define MIN_DCR_REGISTER 0
+
+/**************************** Type Definitions ******************************/
+
+
+/***************** Macros (Inline Functions) Definitions ********************/
+
+/************************** Variable Definitions ****************************/
+
+
+
+/************************** Function Prototypes *****************************/
+
+/*****************************************************************************/
+/**
+*
+* Outputs value provided to specified register defined in the header file.
+*
+* @param DcrRegister is the intended destination DCR register
+* @param Data is the value to be placed into the specified DCR register
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+void XIo_DcrOut(u32 DcrRegister, u32 Data)
+{
+ /*
+ * Assert validates the register number
+ */
+ XASSERT_VOID(DcrRegister < MAX_DCR_REGISTERS);
+
+ /*
+ * pass the call on to the proper function
+ */
+ XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister, Data);
+}
+
+/*****************************************************************************/
+/**
+*
+* Reads value from specified register.
+*
+* @param DcrRegister is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* None.
+*
+****************************************************************************/
+u32 XIo_DcrIn(u32 DcrRegister)
+{
+ /*
+ * Assert validates the register number
+ */
+ XASSERT_NONVOID(DcrRegister < MAX_DCR_REGISTERS);
+
+ /*
+ * pass the call on to the proper function
+ */
+ return (XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR, DcrRegister));
+}
+
+/*****************************************************************************/
+/**
+*
+* Reads the value of the specified register using the indirect access method.
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param DcrRegister is the intended destination DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+u32 XIo_DcrReadReg(u32 DcrBase, u32 DcrRegister)
+{
+ switch (DcrBase) {
+ case 0x000:
+ return XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+ DcrRegister);
+ case 0x100:
+ return XIo_mDcrIndirectAddrReadReg(XDCR_1_BASEADDR,
+ DcrRegister);
+ case 0x200:
+ return XIo_mDcrIndirectAddrReadReg(XDCR_2_BASEADDR,
+ DcrRegister);
+ case 0x300:
+ return XIo_mDcrIndirectAddrReadReg(XDCR_3_BASEADDR,
+ DcrRegister);
+ default:
+ return XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+ DcrRegister);
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* Writes the value to the specified register using the indirect access method.
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param DcrRegister is the intended destination DCR register
+* @param Data is the value to be placed into the specified DCR register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data)
+{
+ switch (DcrBase) {
+ case 0x000:
+ XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+ Data);
+ return;
+ case 0x100:
+ XIo_mDcrIndirectAddrWriteReg(XDCR_1_BASEADDR, DcrRegister,
+ Data);
+ return;
+ case 0x200:
+ XIo_mDcrIndirectAddrWriteReg(XDCR_2_BASEADDR, DcrRegister,
+ Data);
+ return;
+ case 0x300:
+ XIo_mDcrIndirectAddrWriteReg(XDCR_3_BASEADDR, DcrRegister,
+ Data);
+ return;
+ default:
+ XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+ Data);
+ return;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* Explicitly acquires and release DCR lock--Auto-Lock is disabled.
+* Reads the value of the specified register using the indirect access method.
+* This function is provided because the most common usecase is to enable
+* Auto-Lock. Checking for Auto-Lock in every indirect access would defeat the
+* purpose of having Auto-Lock.
+* Auto-Lock can only be enable/disabled in hardware.
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param DcrRegister is the intended destination DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+u32 XIo_DcrLockAndReadReg(u32 DcrBase, u32 DcrRegister)
+{
+ unsigned int rVal;
+
+ switch (DcrBase) {
+ case 0x000:
+ XIo_mDcrLock(XDCR_0_BASEADDR);
+ rVal = XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+ DcrRegister);
+ XIo_mDcrUnlock(XDCR_0_BASEADDR);
+ case 0x100:
+ XIo_mDcrLock(XDCR_1_BASEADDR);
+ rVal = XIo_mDcrIndirectAddrReadReg(XDCR_1_BASEADDR,
+ DcrRegister);
+ XIo_mDcrUnlock(XDCR_1_BASEADDR);
+ case 0x200:
+ XIo_mDcrLock(XDCR_2_BASEADDR);
+ rVal = XIo_mDcrIndirectAddrReadReg(XDCR_2_BASEADDR,
+ DcrRegister);
+ XIo_mDcrUnlock(XDCR_2_BASEADDR);
+ case 0x300:
+ XIo_mDcrLock(XDCR_3_BASEADDR);
+ rVal = XIo_mDcrIndirectAddrReadReg(XDCR_3_BASEADDR,
+ DcrRegister);
+ XIo_mDcrUnlock(XDCR_3_BASEADDR);
+ default:
+ XIo_mDcrLock(XDCR_0_BASEADDR);
+ rVal = XIo_mDcrIndirectAddrReadReg(XDCR_0_BASEADDR,
+ DcrRegister);
+ XIo_mDcrUnlock(XDCR_0_BASEADDR);
+ }
+ return rVal;
+}
+
+/*****************************************************************************/
+/**
+*
+* Explicitly acquires and release DCR lock--Auto-Lock is disabled.
+* Writes the value to the specified register using the indirect access method.
+* This function is provided because the most common usecase is to enable
+* Auto-Lock. Checking for Auto-Lock in every indirect access would defeat the
+* purpose of having Auto-Lock.
+* Auto-Lock can only be enable/disabled in hardware.
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param DcrRegister is the intended destination DCR register
+* @param Data is the value to be placed into the specified DCR register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrLockAndWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data)
+{
+ switch (DcrBase) {
+ case 0x000:
+ XIo_mDcrLock(XDCR_0_BASEADDR);
+ XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+ Data);
+ XIo_mDcrUnlock(XDCR_0_BASEADDR);
+ return;
+ case 0x100:
+ XIo_mDcrLock(XDCR_1_BASEADDR);
+ XIo_mDcrIndirectAddrWriteReg(XDCR_1_BASEADDR, DcrRegister,
+ Data);
+ XIo_mDcrUnlock(XDCR_1_BASEADDR);
+ return;
+ case 0x200:
+ XIo_mDcrLock(XDCR_2_BASEADDR);
+ XIo_mDcrIndirectAddrWriteReg(XDCR_2_BASEADDR, DcrRegister,
+ Data);
+ XIo_mDcrUnlock(XDCR_2_BASEADDR);
+ return;
+ case 0x300:
+ XIo_mDcrLock(XDCR_3_BASEADDR);
+ XIo_mDcrIndirectAddrWriteReg(XDCR_3_BASEADDR, DcrRegister,
+ Data);
+ XIo_mDcrUnlock(XDCR_3_BASEADDR);
+ return;
+ default:
+ XIo_mDcrLock(XDCR_0_BASEADDR);
+ XIo_mDcrIndirectAddrWriteReg(XDCR_0_BASEADDR, DcrRegister,
+ Data);
+ XIo_mDcrUnlock(XDCR_0_BASEADDR);
+ return;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* Read APU UDI DCR via indirect addressing.
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param UDInum is the desired APU UDI register
+*
+* @return
+*
+* Contents of the specified APU register.
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+u32 XIo_DcrReadAPUUDIReg(u32 DcrBase, short UDInum)
+{
+ switch (DcrBase) {
+ case 0x000:
+ return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_0_BASEADDR,
+ UDInum);
+ case 0x100:
+ return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_1_BASEADDR,
+ UDInum);
+ case 0x200:
+ return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_2_BASEADDR,
+ UDInum);
+ case 0x300:
+ return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_3_BASEADDR,
+ UDInum);
+ default:
+ return XIo_mDcrIndirectAddrReadAPUUDIReg(XDCR_0_BASEADDR,
+ UDInum);
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* Writes the value to the APU UDI DCR using the indirect access method.
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param UDInum is the intended destination APU register
+* @param Data is the value to be placed into the specified APU register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Uses the indirect addressing method available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrWriteAPUUDIReg(u32 DcrBase, short UDInum, u32 Data)
+{
+ switch (DcrBase) {
+ case 0x000:
+ XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_0_BASEADDR, UDInum,
+ Data);
+ return;
+ case 0x100:
+ XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_1_BASEADDR, UDInum,
+ Data);
+ return;
+ case 0x200:
+ XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_2_BASEADDR, UDInum,
+ Data);
+ return;
+ case 0x300:
+ XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_3_BASEADDR, UDInum,
+ Data);
+ return;
+ default:
+ XIo_mDcrIndirectAddrWriteAPUUDIReg(XDCR_0_BASEADDR, UDInum,
+ Data);
+ return;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* Locks DCR bus via the Global Status/Control register.
+*
+* @param DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared. The internal PPC440 can clear both timeout bits but an
+* external DCR master can only clear the external DCR master's timeout bit.
+*
+* Only available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrLock(u32 DcrBase)
+{
+ switch (DcrBase) {
+ case 0x000:
+ XIo_mDcrLock(XDCR_0_BASEADDR);
+ return;
+ case 0x100:
+ XIo_mDcrLock(XDCR_1_BASEADDR);
+ return;
+ case 0x200:
+ XIo_mDcrLock(XDCR_2_BASEADDR);
+ return;
+ case 0x300:
+ XIo_mDcrLock(XDCR_3_BASEADDR);
+ return;
+ default:
+ XIo_mDcrLock(XDCR_0_BASEADDR);
+ return;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* Unlocks DCR bus via the Global Status/Control register.
+*
+* @param DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared. The internal PPC440 can clear both timeout bits but an
+* external DCR master can only clear the external DCR master's timeout bit.
+*
+* Only available in V5 with PPC440.
+*
+****************************************************************************/
+void XIo_DcrUnlock(u32 DcrBase)
+{
+ switch (DcrBase) {
+ case 0x000:
+ XIo_mDcrUnlock(XDCR_0_BASEADDR);
+ return;
+ case 0x100:
+ XIo_mDcrUnlock(XDCR_1_BASEADDR);
+ return;
+ case 0x200:
+ XIo_mDcrUnlock(XDCR_2_BASEADDR);
+ return;
+ case 0x300:
+ XIo_mDcrUnlock(XDCR_3_BASEADDR);
+ return;
+ default:
+ XIo_mDcrUnlock(XDCR_0_BASEADDR);
+ return;
+ }
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xipif_v1_23_b.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xipif_v1_23_b.c
@@ -0,0 +1,324 @@
+/* $Id: xipif_v1_23_b.c,v 1.3 2004/11/15 20:31:35 xduan 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-2004 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xipif_v1_23_b.c
+*
+* This file contains the implementation of the XIpIf component. The
+* XIpIf component encapsulates the IPIF, which is the standard interface
+* that IP must adhere to when connecting to a bus. The purpose of this
+* component is to encapsulate the IPIF processing such that maintainability
+* is increased. This component does not provide a lot of abstraction from
+* from the details of the IPIF as it is considered a building block for
+* device drivers. A device driver designer must be familiar with the
+* details of the IPIF hardware to use this component.
+*
+* The IPIF hardware provides a building block for all hardware devices such
+* that each device does not need to reimplement these building blocks. The
+* IPIF contains other building blocks, such as FIFOs and DMA channels, which
+* are also common to many devices. These blocks are implemented as separate
+* hardware blocks and instantiated within the IPIF. The primary hardware of
+* the IPIF which is implemented by this software component is the interrupt
+* architecture. Since there are many blocks of a device which may generate
+* interrupts, all the interrupt processing is contained in the common part
+* of the device, the IPIF. This interrupt processing is for the device level
+* only and does not include any processing for the interrupt controller.
+*
+* A device is a mechanism such as an Ethernet MAC. The device is made
+* up of several parts which include an IPIF and the IP. The IPIF contains most
+* of the device infrastructure which is common to all devices, such as
+* interrupt processing, DMA channels, and FIFOs. The infrastructure may also
+* be referred to as IPIF internal blocks since they are part of the IPIF and
+* are separate blocks that can be selected based upon the needs of the device.
+* The IP of the device is the logic that is unique to the device and interfaces
+* to the IPIF of the device.
+*
+* In general, there are two levels of registers within the IPIF. The first
+* level, referred to as the device level, contains registers which are for the
+* entire device. The second level, referred to as the IP level, contains
+* registers which are specific to the IP of the device. The two levels of
+* registers are designed to be hierarchical such that the device level is
+* is a more general register set above the more specific registers of the IP.
+* The IP level of registers provides functionality which is typically common
+* across all devices and allows IP designers to focus on the unique aspects
+* of the IP.
+*
+* The interrupt registers of the IPIF are parameterizable such that the only
+* the number of bits necessary for the device are implemented. The functions
+* of this component do not attempt to validate that the passed in arguments are
+* valid based upon the number of implemented bits. This is necessary to
+* maintain the level of performance required for the common components. Bits
+* of the registers are assigned starting at the least significant bit of the
+* registers.
+*
+* <b>Critical Sections</b>
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the IPIF. This component
+* does not use critical sections and it does access registers using
+* read-modify-write operations. Calls to IPIF functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* <b>Mutual Exclusion</b>
+*
+* The functions of the IPIF are not thread safe such that the caller of all
+* functions is responsible for ensuring mutual exclusion for an IPIF. Mutual
+* exclusion across multiple IPIF components is not necessary.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-----------------------------------------------
+* 1.23b jhl 02/27/01 Repartioned to reduce size
+* 1.23b rpm 08/17/04 Doxygenated for inclusion in API documentation
+* 1.23b xd 10/27/04 Improve Doxygen format
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xipif_v1_23_b.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constant is used to generate bit masks for register testing
+ * in the self test functions, it defines the starting bit mask that is to be
+ * shifted from the LSB to MSB in creating a register test mask
+ */
+#define XIIF_V123B_FIRST_BIT_MASK 1UL
+
+
+/* the following constant defines the maximum number of bits which may be
+ * used in the registers at the device and IP levels, this is based upon the
+ * number of bits available in the registers
+ */
+#define XIIF_V123B_MAX_REG_BIT_COUNT 32
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/************************** Function Prototypes ******************************/
+
+static int IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
+
+/*****************************************************************************/
+/**
+*
+* This function performs a self test on the specified IPIF component. Many
+* of the registers in the IPIF are tested to ensure proper operation. This
+* function is destructive because the IPIF is reset at the start of the test
+* and at the end of the test to ensure predictable results. The IPIF reset
+* also resets the entire device that uses the IPIF. This function exits with
+* all interrupts for the device disabled.
+*
+* @param RegBaseAddress is the base address of the device's IPIF registers
+*
+* @param IpRegistersWidth contains the number of bits in the IP interrupt
+* registers of the device. The hardware is parameterizable such that
+* only the number of bits necessary to support a device are implemented.
+* This value must be between 0 and 32 with 0 indicating there are no IP
+* interrupt registers used.
+*
+* @return
+*
+* A value of XST_SUCCESS indicates the test was successful with no errors.
+* Any one of the following error values may also be returned.
+* <br><br>
+* - XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
+* not valid
+* <br><br>
+* - XST_IPIF_IP_STATUS_ERROR A write to the IP interrupt status
+* register did not read back correctly
+* <br><br>
+* - XST_IPIF_IP_ACK_ERROR One or more bits in the IP interrupt
+* status register did not reset when acked
+* <br><br>
+* - XST_IPIF_IP_ENABLE_ERROR The IP interrupt enable register
+* did not read back correctly based upon
+* what was written to it
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+int XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
+{
+ int Status;
+
+ /* assert to verify arguments are valid */
+
+ XASSERT_NONVOID(IpRegistersWidth <= XIIF_V123B_MAX_REG_BIT_COUNT);
+
+ /* reset the IPIF such that it's in a known state before the test
+ * and interrupts are globally disabled
+ */
+ XIIF_V123B_RESET(RegBaseAddress);
+
+ /* perform the self test on the IP interrupt registers, if
+ * it is not successful exit with the status
+ */
+ Status = IpIntrSelfTest(RegBaseAddress, IpRegistersWidth);
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+
+ /* reset the IPIF such that it's in a known state before exiting test */
+
+ XIIF_V123B_RESET(RegBaseAddress);
+
+ /* reaching this point means there were no errors, return success */
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* Perform a self test on the IP interrupt registers of the IPIF. This
+* function modifies registers of the IPIF such that they are not guaranteed
+* to be in the same state when it returns. Any bits in the IP interrupt
+* status register which are set are assumed to be set by default after a reset
+* and are not tested in the test.
+*
+* @param RegBaseAddress is the base address of the device's IPIF registers
+*
+* @param IpRegistersWidth contains the number of bits in the IP interrupt
+* registers of the device. The hardware is parameterizable such that
+* only the number of bits necessary to support a device are implemented.
+* This value must be between 0 and 32 with 0 indicating there are no IP
+* interrupt registers used.
+*
+* @return
+*
+* A status indicating XST_SUCCESS if the test was successful. Otherwise, one
+* of the following values is returned.
+* - XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
+* not valid
+* <br><br>
+* - XST_IPIF_IP_STATUS_ERROR A write to the IP interrupt status
+* register did not read back correctly
+* <br><br>
+* - XST_IPIF_IP_ACK_ERROR One or more bits in the IP status
+* register did not reset when acked
+* <br><br>
+* - XST_IPIF_IP_ENABLE_ERROR The IP interrupt enable register
+* did not read back correctly based upon
+* what was written to it
+* @note
+*
+* None.
+*
+******************************************************************************/
+static int IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
+{
+ /* ensure that the IP interrupt enable register is zero
+ * as it should be at reset, the interrupt status is dependent upon the
+ * IP such that it's reset value is not known
+ */
+ if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+ return XST_IPIF_RESET_REGISTER_ERROR;
+ }
+
+ /* if there are any used IP interrupts, then test all of the interrupt
+ * bits in all testable registers
+ */
+ if (IpRegistersWidth > 0) {
+ u32 BitCount;
+ u32 IpInterruptMask = XIIF_V123B_FIRST_BIT_MASK;
+ u32 Mask = XIIF_V123B_FIRST_BIT_MASK; /* bits assigned MSB to LSB */
+ u32 InterruptStatus;
+
+ /* generate the register masks to be used for IP register tests, the
+ * number of bits supported by the hardware is parameterizable such
+ * that only that number of bits are implemented in the registers, the
+ * bits are allocated starting at the MSB of the registers
+ */
+ for (BitCount = 1; BitCount < IpRegistersWidth; BitCount++) {
+ Mask = Mask << 1;
+ IpInterruptMask |= Mask;
+ }
+
+ /* get the current IP interrupt status register contents, any bits
+ * already set must default to 1 at reset in the device and these
+ * bits can't be tested in the following test, remove these bits from
+ * the mask that was generated for the test
+ */
+ InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+ IpInterruptMask &= ~InterruptStatus;
+
+ /* set the bits in the device status register and verify them by reading
+ * the register again, all bits of the register are latched
+ */
+ XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+ InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+ if ((InterruptStatus & IpInterruptMask) != IpInterruptMask)
+ {
+ return XST_IPIF_IP_STATUS_ERROR;
+ }
+
+ /* test to ensure that the bits set in the IP interrupt status register
+ * can be cleared by acknowledging them in the IP interrupt status
+ * register then read it again and verify it was cleared
+ */
+ XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
+ InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
+ if ((InterruptStatus & IpInterruptMask) != 0) {
+ return XST_IPIF_IP_ACK_ERROR;
+ }
+
+ /* set the IP interrupt enable set register and then read the IP
+ * interrupt enable register and verify the interrupts were enabled
+ */
+ XIIF_V123B_WRITE_IIER(RegBaseAddress, IpInterruptMask);
+ if (XIIF_V123B_READ_IIER(RegBaseAddress) != IpInterruptMask) {
+ return XST_IPIF_IP_ENABLE_ERROR;
+ }
+
+ /* clear the IP interrupt enable register and then read the
+ * IP interrupt enable register and verify the interrupts were disabled
+ */
+ XIIF_V123B_WRITE_IIER(RegBaseAddress, 0);
+ if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
+ return XST_IPIF_IP_ENABLE_ERROR;
+ }
+ }
+ return XST_SUCCESS;
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bd.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_bd.h
@@ -0,0 +1,302 @@
+/* $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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlldma_bd.h
+ *
+ * This header provides operations to manage buffer descriptors (BD) in support
+ * of Local-Link scatter-gather DMA (see xlldma.h).
+ *
+ * The API exported by this header defines abstracted macros that allow the
+ * application to read/write specific BD fields.
+ *
+ * <b>Buffer Descriptors</b>
+ *
+ * A buffer descriptor defines a DMA transaction (see "Transaction"
+ * section in xlldma.h). The macros defined by this header file allow access
+ * to most fields within a BD to tailor a DMA transaction according to
+ * application and hardware requirements. See the hardware IP DMA spec for
+ * more information on BD fields and how they affect transfers.
+ *
+ * The XLlDma_Bd structure defines a BD. The organization of this structure is
+ * driven mainly by the hardware for use in scatter-gather DMA transfers.
+ *
+ * <b>Accessor Macros</b>
+ *
+ * Most of the BD attributes can be accessed through macro functions defined
+ * here in this API. Words such as XLLDMA_BD_USR1_OFFSET (see xlldma_hw.h)
+ * should be accessed using XLlDma_mBdRead() and XLlDma_mBdWrite() as defined
+ * in xlldma_hw.h. The USR words are implementation dependent. For example,
+ * they may implement checksum offloading fields for Ethernet devices. Accessor
+ * macros may be defined in the device specific API to get at this data.
+ *
+ * <b>Performance</b>
+ *
+ * BDs are typically in a non-cached memory space. Limiting I/O to BDs can
+ * improve overall performance of the DMA channel.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a xd 12/21/06 First release
+ * </pre>
+ *
+ *****************************************************************************/
+
+#ifndef XLLDMA_BD_H /* prevent circular inclusions */
+#define XLLDMA_BD_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xenv.h"
+#include "xlldma_hw.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * The XLlDma_Bd is the type for buffer descriptors (BDs).
+ */
+typedef u32 XLlDma_Bd[XLLDMA_BD_NUM_WORDS];
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+*
+* 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 XLlDma_mBdRead(u32 BaseAddress, u32 Offset)
+*
+******************************************************************************/
+#define XLlDma_mBdRead(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 XLlDma_mBdWrite(u32 BaseAddress, u32 RegOffset, u32 Data)
+*
+******************************************************************************/
+#define XLlDma_mBdWrite(BaseAddress, Offset, Data) \
+ (*(u32*)((u32)(BaseAddress) + (u32)(Offset)) = (Data))
+
+
+/*****************************************************************************/
+/**
+ * Zero out all BD fields
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Nothing
+ *
+ * @note
+ * C-style signature:
+ * void XLlDma_mBdClear(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdClear(BdPtr) \
+ memset((BdPtr), 0, sizeof(XLlDma_Bd))
+
+
+/*****************************************************************************/
+/**
+ * Set the BD's STS/CTRL field. The word containing STS/CTRL also contains the
+ * USR0 field. USR0 will not be modified. This operation requires a read-
+ * modify-write operation. If it is wished to set both STS/CTRL and USR0 with
+ * a single write operation, then use XLlDma_mBdWrite(BdPtr,
+ * XLLDMA_BD_STSCTRL_USR0_OFFSET, Data).
+ *
+ * @param BdPtr is the BD to operate on
+ * @param Data is the value to write to STS/CTRL. Or 0 or more
+ * XLLDMA_BD_STSCTRL_*** values defined in xlldma_hw.h to create a
+ * valid value for this parameter
+ *
+ * @note
+ * C-style signature:
+ * u32 XLlDma_mBdSetStsCtrl(XLlDma_Bd* BdPtr, u32 Data)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetStsCtrl(BdPtr, Data) \
+ XLlDma_mBdWrite((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET, \
+ (XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET) \
+ & XLLDMA_BD_STSCTRL_USR0_MASK) | \
+ ((Data) & XLLDMA_BD_STSCTRL_MASK))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the word containing the BD's STS/CTRL field. This word also
+ * contains the USR0 field.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Word at offset XLLDMA_BD_DMASR_OFFSET. Use XLLDMA_BD_STSCTRL_***
+ * values defined in xlldma_hw.h to interpret this returned value
+ *
+ * @note
+ * C-style signature:
+ * u32 XLlDma_mBdGetStsCtrl(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetStsCtrl(BdPtr) \
+ XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_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 to operate on
+ * @param LenBytes is the number of bytes to transfer.
+ *
+ * @note
+ * C-style signature:
+ * void XLlDma_mBdSetLength(XLlDma_Bd* BdPtr, u32 LenBytes)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetLength(BdPtr, LenBytes) \
+ XLlDma_mBdWrite((BdPtr), XLLDMA_BD_BUFL_OFFSET, (LenBytes))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the BD length field.
+ *
+ * For TX channels, the returned value is the same as that written with
+ * XLlDma_mBdSetLength().
+ *
+ * For RX channels, the returned value is what was written by the DMA engine
+ * after processing the BD. This value represents the number of bytes
+ * processed.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @return Bytes processed by hardware or set by XLlDma_mBdSetLength().
+ *
+ * @note
+ * C-style signature:
+ * u32 XLlDma_mBdGetLength(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetLength(BdPtr) \
+ XLlDma_mBdRead((BdPtr), XLLDMA_BD_BUFL_OFFSET)
+
+
+/*****************************************************************************/
+/**
+ * Set the ID field of the given BD. The ID is an arbitrary piece of data the
+ * application can associate with a specific BD.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param Id is a 32 bit quantity to set in the BD
+ *
+ * @note
+ * C-style signature:
+ * void XLlDma_mBdSetId(XLlDma_Bd* BdPtr, void Id)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetId(BdPtr, Id) \
+ (XLlDma_mBdWrite((BdPtr), XLLDMA_BD_ID_OFFSET, (u32)(Id)))
+
+
+/*****************************************************************************/
+/**
+ * Retrieve the ID field of the given BD previously set with XLlDma_mBdSetId.
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XLlDma_mBdGetId(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetId(BdPtr) (XLlDma_mBdRead((BdPtr), XLLDMA_BD_ID_OFFSET))
+
+
+/*****************************************************************************/
+/**
+ * Set the BD's buffer address.
+ *
+ * @param BdPtr is the BD to operate on
+ * @param Addr is the address to set
+ *
+ * @note
+ * C-style signature:
+ * void XLlDma_mBdSetBufAddr(XLlDma_Bd* BdPtr, u32 Addr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdSetBufAddr(BdPtr, Addr) \
+ (XLlDma_mBdWrite((BdPtr), XLLDMA_BD_BUFA_OFFSET, (u32)(Addr)))
+
+
+/*****************************************************************************/
+/**
+ * Get the BD's buffer address
+ *
+ * @param BdPtr is the BD to operate on
+ *
+ * @note
+ * C-style signature:
+ * u32 XLlDma_mBdGetBufAddrLow(XLlDma_Bd* BdPtr)
+ *
+ *****************************************************************************/
+#define XLlDma_mBdGetBufAddr(BdPtr) \
+ (XLlDma_mBdRead((BdPtr), XLLDMA_BD_BUFA_OFFSET))
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xio_dcr.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xio_dcr.h
@@ -0,0 +1,689 @@
+/* $Id: xio_dcr.h,v 1.8 2007/01/24 17:00:16 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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xio_dcr.h
+*
+* The DCR I/O access functions.
+*
+* @note
+*
+* These access functions are specific to the PPC440 CPU. Changes might be
+* necessary for other members of the IBM PPC Family.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-----------------------------------------------
+* 1.00a ecm 10/18/05 First release
+* Need to verify opcodes for mt/mfdcr remain the same.
+* 1.00a ecm 11/09/06 Modified from the PPC405 version to use the indirect
+* addressing that is available in the PPC440 block in V5.
+* Removed the jump table structure in xio_dcr.c also.
+* Added functionality from the SEG driver to allow for
+* one file pair.
+* 1.00a ecm 01/02/07 Incorporated changes from testing with multiple DCR
+* masters, discovered and fixed several concurrency
+* issues.
+* 1.00a ecm 01/24/07 update for new coding standard.
+* </pre>
+*
+* @internal
+*
+* This code WILL NOT FUNCTION on the PPC405 based architectures, V2P and V4.
+*
+******************************************************************************/
+
+#ifndef XDCRIO_H /* prevent circular inclusions */
+#define XDCRIO_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/***************************** Include Files *********************************/
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+/*
+ * 256 internal DCR registers
+ * Base address: 2 most signifcant bits of 10-bit addr taken from
+ * the C_DCRBASEADDR parameter of the processor block.
+ * Offset: 8 least significant bits
+ */
+/* register base addresses */
+
+#define XDCR_APU_BASE 0x04
+#define XDCR_MIB_BASE 0x10
+#define XDCR_XB_BASE 0x20
+#define XDCR_PLBS0_BASE 0x34
+#define XDCR_PLBS1_BASE 0x44
+#define XDCR_PLBM_BASE 0x54
+#define XDCR_DMA0_BASE 0x80
+#define XDCR_DMA1_BASE 0x98
+#define XDCR_DMA2_BASE 0xB0
+#define XDCR_DMA3_BASE 0xC8
+
+/* register offsets */
+/* global registers 0x00-0x02 */
+
+#define XDCR_IDA_ADDR 0x00
+#define XDCR_IDA_ACC 0x01
+#define XDCR_CTRLCFGSTAT 0x02
+
+/* Auxiliary Processor Unit Controller (APU) 0x04-0x05 */
+
+#define XDCR_APU_UDI (XDCR_APU_BASE+0x00)
+#define XDCR_APU_CTRL (XDCR_APU_BASE+0x01)
+
+/* Memory Interface Bridge (MIB) 0x10-0x13 */
+
+#define XDCR_MIB_CTRL (XDCR_MIB_BASE+0x00)
+#define XDCR_MIB_RCON (XDCR_MIB_BASE+0x01)
+#define XDCR_MIB_BCON (XDCR_MIB_BASE+0x02)
+
+/* Crossbar (XB) 0x20-0x33 */
+
+#define XDCR_XB_IST (XDCR_XB_BASE+0x00)
+#define XDCR_XB_IMASK (XDCR_XB_BASE+0x01)
+#define XDCR_XB_ARBCFGX (XDCR_XB_BASE+0x03)
+#define XDCR_XB_FIFOSTX (XDCR_XB_BASE+0x04)
+#define XDCR_XB_SMSTX (XDCR_XB_BASE+0x05)
+#define XDCR_XB_MISCX (XDCR_XB_BASE+0x06)
+#define XDCR_XB_ARBCFGM (XDCR_XB_BASE+0x08)
+#define XDCR_XB_FIFOSTM (XDCR_XB_BASE+0x09)
+#define XDCR_XB_SMSTM (XDCR_XB_BASE+0x0A)
+#define XDCR_XB_MISCM (XDCR_XB_BASE+0x0B)
+#define XDCR_XB_TMPL0MAP (XDCR_XB_BASE+0x0D)
+#define XDCR_XB_TMPL1MAP (XDCR_XB_BASE+0x0E)
+#define XDCR_XB_TMPL2MAP (XDCR_XB_BASE+0x0F)
+#define XDCR_XB_TMPL3MAP (XDCR_XB_BASE+0x10)
+#define XDCR_XB_TMPLSEL (XDCR_XB_BASE+0x11)
+
+/* PLB Slave DCR offsets only */
+
+#define XDCR_PLBS_CFG 0x00
+#define XDCR_PLBS_SEARU 0x02
+#define XDCR_PLBS_SEARL 0x03
+#define XDCR_PLBS_SESR 0x04
+#define XDCR_PLBS_MISCST 0x05
+#define XDCR_PLBS_PLBERRST 0x06
+#define XDCR_PLBS_SMST 0x07
+#define XDCR_PLBS_MISC 0x08
+#define XDCR_PLBS_CMDSNIFF 0x09
+#define XDCR_PLBS_CMDSNIFFA 0x0A
+#define XDCR_PLBS_TMPL0MAP 0x0C
+#define XDCR_PLBS_TMPL1MAP 0x0D
+#define XDCR_PLBS_TMPL2MAP 0x0E
+#define XDCR_PLBS_TMPL3MAP 0x0F
+
+/* PLB Slave 0 (PLBS0) 0x34-0x43 */
+
+#define XDCR_PLBS0_CFG (XDCR_PLBS0_BASE+0x00)
+#define XDCR_PLBS0_CNT (XDCR_PLBS0_BASE+0x01)
+#define XDCR_PLBS0_SEARU (XDCR_PLBS0_BASE+0x02)
+#define XDCR_PLBS0_SEARL (XDCR_PLBS0_BASE+0x03)
+#define XDCR_PLBS0_SESR (XDCR_PLBS0_BASE+0x04)
+#define XDCR_PLBS0_MISCST (XDCR_PLBS0_BASE+0x05)
+#define XDCR_PLBS0_PLBERRST (XDCR_PLBS0_BASE+0x06)
+#define XDCR_PLBS0_SMST (XDCR_PLBS0_BASE+0x07)
+#define XDCR_PLBS0_MISC (XDCR_PLBS0_BASE+0x08)
+#define XDCR_PLBS0_CMDSNIFF (XDCR_PLBS0_BASE+0x09)
+#define XDCR_PLBS0_CMDSNIFFA (XDCR_PLBS0_BASE+0x0A)
+#define XDCR_PLBS0_TMPL0MAP (XDCR_PLBS0_BASE+0x0C)
+#define XDCR_PLBS0_TMPL1MAP (XDCR_PLBS0_BASE+0x0D)
+#define XDCR_PLBS0_TMPL2MAP (XDCR_PLBS0_BASE+0x0E)
+#define XDCR_PLBS0_TMPL3MAP (XDCR_PLBS0_BASE+0x0F)
+
+/* PLB Slave 1 (PLBS1) 0x44-0x53 */
+
+#define XDCR_PLBS1_CFG (XDCR_PLBS1_BASE+0x00)
+#define XDCR_PLBS1_CNT (XDCR_PLBS1_BASE+0x01)
+#define XDCR_PLBS1_SEARU (XDCR_PLBS1_BASE+0x02)
+#define XDCR_PLBS1_SEARL (XDCR_PLBS1_BASE+0x03)
+#define XDCR_PLBS1_SESR (XDCR_PLBS1_BASE+0x04)
+#define XDCR_PLBS1_MISCST (XDCR_PLBS1_BASE+0x05)
+#define XDCR_PLBS1_PLBERRST (XDCR_PLBS1_BASE+0x06)
+#define XDCR_PLBS1_SMST (XDCR_PLBS1_BASE+0x07)
+#define XDCR_PLBS1_MISC (XDCR_PLBS1_BASE+0x08)
+#define XDCR_PLBS1_CMDSNIFF (XDCR_PLBS1_BASE+0x09)
+#define XDCR_PLBS1_CMDSNIFFA (XDCR_PLBS1_BASE+0x0A)
+#define XDCR_PLBS1_TMPL0MAP (XDCR_PLBS1_BASE+0x0C)
+#define XDCR_PLBS1_TMPL1MAP (XDCR_PLBS1_BASE+0x0D)
+#define XDCR_PLBS1_TMPL2MAP (XDCR_PLBS1_BASE+0x0E)
+#define XDCR_PLBS1_TMPL3MAP (XDCR_PLBS1_BASE+0x0F)
+
+/* PLB Master (PLBM) 0x54-0x5F */
+
+#define XDCR_PLBM_CFG (XDCR_PLBM_BASE+0x00)
+#define XDCR_PLBM_CNT (XDCR_PLBM_BASE+0x01)
+#define XDCR_PLBM_FSEARU (XDCR_PLBM_BASE+0x02)
+#define XDCR_PLBM_FSEARL (XDCR_PLBM_BASE+0x03)
+#define XDCR_PLBM_FSESR (XDCR_PLBM_BASE+0x04)
+#define XDCR_PLBM_MISCST (XDCR_PLBM_BASE+0x05)
+#define XDCR_PLBM_PLBERRST (XDCR_PLBM_BASE+0x06)
+#define XDCR_PLBM_SMST (XDCR_PLBM_BASE+0x07)
+#define XDCR_PLBM_MISC (XDCR_PLBM_BASE+0x08)
+#define XDCR_PLBM_CMDSNIFF (XDCR_PLBM_BASE+0x09)
+#define XDCR_PLBM_CMDSNIFFA (XDCR_PLBM_BASE+0x0A)
+
+/* DMA Controller DCR offsets only */
+#define XDCR_DMA_TXNXTDESCPTR 0x00
+#define XDCR_DMA_TXCURBUFADDR 0x01
+#define XDCR_DMA_TXCURBUFLEN 0x02
+#define XDCR_DMA_TXCURDESCPTR 0x03
+#define XDCR_DMA_TXTAILDESCPTR 0x04
+#define XDCR_DMA_TXCHANNELCTRL 0x05
+#define XDCR_DMA_TXIRQ 0x06
+#define XDCR_DMA_TXSTATUS 0x07
+#define XDCR_DMA_RXNXTDESCPTR 0x08
+#define XDCR_DMA_RXCURBUFADDR 0x09
+#define XDCR_DMA_RXCURBUFLEN 0x0A
+#define XDCR_DMA_RXCURDESCPTR 0x0B
+#define XDCR_DMA_RXTAILDESCPTR 0x0C
+#define XDCR_DMA_RXCHANNELCTRL 0x0D
+#define XDCR_DMA_RXIRQ 0x0E
+#define XDCR_DMA_RXSTATUS 0x0F
+#define XDCR_DMA_CTRL 0x10
+
+/* DMA Controller 0 (DMA0) 0x80-0x90 */
+
+#define XDCR_DMA0_TXNXTDESCPTR (XDCR_DMA0_BASE+0x00)
+#define XDCR_DMA0_TXCURBUFADDR (XDCR_DMA0_BASE+0x01)
+#define XDCR_DMA0_TXCURBUFLEN (XDCR_DMA0_BASE+0x02)
+#define XDCR_DMA0_TXCURDESCPTR (XDCR_DMA0_BASE+0x03)
+#define XDCR_DMA0_TXTAILDESCPTR (XDCR_DMA0_BASE+0x04)
+#define XDCR_DMA0_TXCHANNELCTRL (XDCR_DMA0_BASE+0x05)
+#define XDCR_DMA0_TXIRQ (XDCR_DMA0_BASE+0x06)
+#define XDCR_DMA0_TXSTATUS (XDCR_DMA0_BASE+0x07)
+#define XDCR_DMA0_RXNXTDESCPTR (XDCR_DMA0_BASE+0x08)
+#define XDCR_DMA0_RXCURBUFADDR (XDCR_DMA0_BASE+0x09)
+#define XDCR_DMA0_RXCURBUFLEN (XDCR_DMA0_BASE+0x0A)
+#define XDCR_DMA0_RXCURDESCPTR (XDCR_DMA0_BASE+0x0B)
+#define XDCR_DMA0_RXTAILDESCPTR (XDCR_DMA0_BASE+0x0C)
+#define XDCR_DMA0_RXCHANNELCTRL (XDCR_DMA0_BASE+0x0D)
+#define XDCR_DMA0_RXIRQ (XDCR_DMA0_BASE+0x0E)
+#define XDCR_DMA0_RXSTATUS (XDCR_DMA0_BASE+0x0F)
+#define XDCR_DMA0_CTRL (XDCR_DMA0_BASE+0x10)
+
+/* DMA Controller 1 (DMA1) 0x98-0xA8 */
+
+#define XDCR_DMA1_TXNXTDESCPTR (XDCR_DMA1_BASE+0x00)
+#define XDCR_DMA1_TXCURBUFADDR (XDCR_DMA1_BASE+0x01)
+#define XDCR_DMA1_TXCURBUFLEN (XDCR_DMA1_BASE+0x02)
+#define XDCR_DMA1_TXCURDESCPTR (XDCR_DMA1_BASE+0x03)
+#define XDCR_DMA1_TXTAILDESCPTR (XDCR_DMA1_BASE+0x04)
+#define XDCR_DMA1_TXCHANNELCTRL (XDCR_DMA1_BASE+0x05)
+#define XDCR_DMA1_TXIRQ (XDCR_DMA1_BASE+0x06)
+#define XDCR_DMA1_TXSTATUS (XDCR_DMA1_BASE+0x07)
+#define XDCR_DMA1_RXNXTDESCPTR (XDCR_DMA1_BASE+0x08)
+#define XDCR_DMA1_RXCURBUFADDR (XDCR_DMA1_BASE+0x09)
+#define XDCR_DMA1_RXCURBUFLEN (XDCR_DMA1_BASE+0x0A)
+#define XDCR_DMA1_RXCURDESCPTR (XDCR_DMA1_BASE+0x0B)
+#define XDCR_DMA1_RXTAILDESCPTR (XDCR_DMA1_BASE+0x0C)
+#define XDCR_DMA1_RXCHANNELCTRL (XDCR_DMA1_BASE+0x0D)
+#define XDCR_DMA1_RXIRQ (XDCR_DMA1_BASE+0x0E)
+#define XDCR_DMA1_RXSTATUS (XDCR_DMA1_BASE+0x0F)
+#define XDCR_DMA1_CTRL (XDCR_DMA1_BASE+0x10)
+
+/* DMA Controller 2 (DMA2) 0xB0-0xC0 */
+
+#define XDCR_DMA2_TXNXTDESCPTR (XDCR_DMA2_BASE+0x00)
+#define XDCR_DMA2_TXCURBUFADDR (XDCR_DMA2_BASE+0x01)
+#define XDCR_DMA2_TXCURBUFLEN (XDCR_DMA2_BASE+0x02)
+#define XDCR_DMA2_TXCURDESCPTR (XDCR_DMA2_BASE+0x03)
+#define XDCR_DMA2_TXTAILDESCPTR (XDCR_DMA2_BASE+0x04)
+#define XDCR_DMA2_TXCHANNELCTRL (XDCR_DMA2_BASE+0x05)
+#define XDCR_DMA2_TXIRQ (XDCR_DMA2_BASE+0x06)
+#define XDCR_DMA2_TXSTATUS (XDCR_DMA2_BASE+0x07)
+#define XDCR_DMA2_RXNXTDESCPTR (XDCR_DMA2_BASE+0x08)
+#define XDCR_DMA2_RXCURBUFADDR (XDCR_DMA2_BASE+0x09)
+#define XDCR_DMA2_RXCURBUFLEN (XDCR_DMA2_BASE+0x0A)
+#define XDCR_DMA2_RXCURDESCPTR (XDCR_DMA2_BASE+0x0B)
+#define XDCR_DMA2_RXTAILDESCPTR (XDCR_DMA2_BASE+0x0C)
+#define XDCR_DMA2_RXCHANNELCTRL (XDCR_DMA2_BASE+0x0D)
+#define XDCR_DMA2_RXIRQ (XDCR_DMA2_BASE+0x0E)
+#define XDCR_DMA2_RXSTATUS (XDCR_DMA2_BASE+0x0F)
+#define XDCR_DMA2_CTRL (XDCR_DMA2_BASE+0x10)
+
+/* DMA Controller 3 (DMA3) 0xC8-0xD8 */
+
+#define XDCR_DMA3_TXNXTDESCPTR (XDCR_DMA3_BASE+0x00)
+#define XDCR_DMA3_TXCURBUFADDR (XDCR_DMA3_BASE+0x01)
+#define XDCR_DMA3_TXCURBUFLEN (XDCR_DMA3_BASE+0x02)
+#define XDCR_DMA3_TXCURDESCPTR (XDCR_DMA3_BASE+0x03)
+#define XDCR_DMA3_TXTAILDESCPTR (XDCR_DMA3_BASE+0x04)
+#define XDCR_DMA3_TXCHANNELCTRL (XDCR_DMA3_BASE+0x05)
+#define XDCR_DMA3_TXIRQ (XDCR_DMA3_BASE+0x06)
+#define XDCR_DMA3_TXSTATUS (XDCR_DMA3_BASE+0x07)
+#define XDCR_DMA3_RXNXTDESCPTR (XDCR_DMA3_BASE+0x08)
+#define XDCR_DMA3_RXCURBUFADDR (XDCR_DMA3_BASE+0x09)
+#define XDCR_DMA3_RXCURBUFLEN (XDCR_DMA3_BASE+0x0A)
+#define XDCR_DMA3_RXCURDESCPTR (XDCR_DMA3_BASE+0x0B)
+#define XDCR_DMA3_RXTAILDESCPTR (XDCR_DMA3_BASE+0x0C)
+#define XDCR_DMA3_RXCHANNELCTRL (XDCR_DMA3_BASE+0x0D)
+#define XDCR_DMA3_RXIRQ (XDCR_DMA3_BASE+0x0E)
+#define XDCR_DMA3_RXSTATUS (XDCR_DMA3_BASE+0x0F)
+#define XDCR_DMA3_CTRL (XDCR_DMA3_BASE+0x10)
+
+
+/**
+ * <pre
+ * These are the bit defines for the Control, Configuration, and Status
+ * register (XDCR_CTRLCFGSTAT)
+ * @{
+ */
+#define XDCR_INT_MSTR_LOCK_MASK 0x80000000 /* Internal Master Bus Lock */
+#define XDCR_INT_MSTR_AUTO_LOCK_MASK 0x40000000 /* Internal Master Bus Auto Lock, RO */
+#define XDCR_EXT_MSTR_LOCK_MASK 0x20000000 /* External Master Bus Master Lock */
+#define XDCR_EXT_MSTR_AUTO_LOCK_MASK 0x10000000 /* External Master Bus Auto Lock, RO */
+#define XDCR_ENB_DCR_AUTO_LOCK_MASK 0x08000000 /* Enable Auto Bus Lock */
+#define XDCR_ENB_MSTR_ASYNC_MASK 0x04000000 /* External Master in Async Mode */
+#define XDCR_ENB_SLV_ASYNC_MASK 0x02000000 /* External Slave in Async Mode */
+#define XDCR_ENB_DCR_TIMEOUT_SUPP_MASK 0x01000000 /* Enable Timeout Support */
+#define XDCR_INT_MSTR_TIMEOUT_BIT 0x00000002 /* Internal Master Bus Timeout Occurred */
+#define XDCR_EXT_MSTR_TIMEOUT_BIT 0x00000001 /* External Master Bus Timeout Occurred */
+
+/*
+ * Mask to disable exceptions in PPC440 MSR
+ * Bit 14: Critical Interrupt Enable 0x00020000
+ * Bit 16: External Interrupt Enable 0x00008000
+ * Bit 20: Floating-point Exceptions Mode 0 0x00000800
+ * Bit 23: Floating-point Exceptions Mode 1 0x00000100
+ */
+#define XDCR_DISABLE_EXCEPTIONS 0xFFFD76FF
+#define XDCR_ALL_LOCK (XDCR_INT_MSTR_LOCK_MASK | XDCR_EXT_MSTR_LOCK_MASK)
+#define XDCR_ALL_TIMEOUT (XDCR_INT_MSTR_TIMEOUT_BIT | XDCR_EXT_MSTR_TIMEOUT_BIT)
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/******************************************************************************/
+/**
+* Reads the register at the specified DCR address.
+*
+*
+* @param DcrRegister is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrReadReg(u32 DcrRegister)
+*
+*******************************************************************************/
+#define XIo_mDcrReadReg(DcrRegister) ({ mfdcr((DcrRegister)); })
+
+/******************************************************************************/
+/**
+* Writes the register at specified DCR address.
+*
+*
+* @param DcrRegister is the intended destination DCR register
+* @param Data is the value to be placed into the specified DRC register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrWriteReg(u32 DcrRegister, u32 Data)
+*
+*******************************************************************************/
+#define XIo_mDcrWriteReg(DcrRegister, Data) ({ mtdcr((DcrRegister), (Data)); })
+
+/******************************************************************************/
+/**
+* Explicitly locks the DCR bus
+*
+* @param DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrLock(u32 DcrBase)
+*
+* Sets either Lock bit. Since a master cannot edit another master's Lock bit,
+* the macro can be simplified.
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrLock(DcrBase) \
+({ \
+ mtdcr((DcrBase) | XDCR_CTRLCFGSTAT, \
+ (mfdcr((DcrBase) | XDCR_CTRLCFGSTAT) | XDCR_ALL_LOCK) & ~XDCR_ALL_TIMEOUT); \
+})
+
+/******************************************************************************/
+/**
+* Explicitly locks the DCR bus
+*
+* @param DcrBase is the base of the block of DCR registers
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrUnlock(u32 DcrBase)
+*
+* Unsets either Lock bit. Since a master cannot edit another master's Lock bit,
+* the macro can be simplified.
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrUnlock(DcrBase) \
+({ \
+ mtdcr((DcrBase) | XDCR_CTRLCFGSTAT, \
+ (mfdcr((DcrBase) | XDCR_CTRLCFGSTAT) & ~(XDCR_ALL_LOCK | XDCR_ALL_TIMEOUT))); \
+})
+
+/******************************************************************************/
+/**
+* Reads the APU UDI register at the specified APU address.
+*
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param UDInum is the intended source APU register
+*
+* @return
+*
+* Contents of the specified APU register.
+*
+* @note
+*
+* C-style signature:
+* u32 XIo_mDcrReadAPUUDIReg(u32 DcrRegister, u32 UDInum)
+*
+* Since reading an APU UDI DCR requires a dummy write to the same DCR,
+* the target UDI number is required. In order to make this operation atomic,
+* interrupts are disabled before and enabled after the DCR accesses.
+* Because an APU UDI access involves two DCR accesses, the DCR bus must be
+* locked to ensure that another master doesn't access the APU UDI register
+* at the same time.
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared.
+* Steps:
+* - save old MSR
+* - disable interrupts by writing mask to MSR
+* - acquire lock; since the PPC440 supports timeout wait, it will wait until
+* it successfully acquires the DCR bus lock
+* - shift and mask the UDI number to its bit position of [22:25]
+* - add the DCR base address to the UDI number and perform the read
+* - release DCR bus lock
+* - restore MSR
+* - return value read
+*
+*******************************************************************************/
+#define XIo_mDcrReadAPUUDIReg(DcrBase, UDInum) \
+({ \
+ unsigned int rVal; \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ mtdcr((DcrBase) | XDCR_APU_UDI, (((UDInum) << 6) & 0x000003c0) | 0x00000030); \
+ rVal = mfdcr((DcrBase) | XDCR_APU_UDI); \
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+ rVal; \
+})
+
+/******************************************************************************/
+/**
+* Writes the data to the APU UDI register at the specified APU address.
+*
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param UDInum is the intended source APU register
+* @param Data is the value to be placed into the specified APU register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrWriteAPUUDIReg(u32 DcrRegister, u32 UDInum, u32 Data)
+*
+* Since writing an APU UDI DCR requires a dummy write to the same DCR,
+* the target UDI number is required. In order to make this operation atomic,
+* interrupts are disabled before and enabled after the DCR accesses.
+* Because an APU UDI access involves two DCR accesses, the DCR bus must be
+* locked to ensure that another master doesn't access the APU UDI register
+* at the same time.
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared.
+* Steps:
+* - save old MSR
+* - disable interrupts by writing mask to MSR
+* - acquire lock, since the PPC440 supports timeout wait, it will wait until
+* it successfully acquires the DCR bus lock
+* - shift and mask the UDI number to its bit position of [22:25]
+* - add DCR base address to UDI number offset and perform the write
+* - release DCR bus lock
+* - restore MSR
+*
+*******************************************************************************/
+#define XIo_mDcrWriteAPUUDIReg(DcrBase, UDInum, Data) \
+({ \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ mtdcr((DcrBase) | XDCR_APU_UDI, (((UDInum) << 6) & 0x000003c0) | 0x00000030); \
+ mtdcr((DcrBase) | XDCR_APU_UDI, (Data)); \
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+})
+
+/******************************************************************************/
+/**
+* Reads the register at the specified DCR address using the indirect addressing
+* method.
+*
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param DcrRegister is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified DCR register.
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrIndirectAddrReadReg(u32 DcrBase, u32 DcrRegister)
+*
+* Assumes auto-buslocking feature is ON.
+* In order to make this operation atomic, interrupts are disabled before
+* and enabled after the DCR accesses.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrReadReg(DcrBase, DcrRegister) \
+({ \
+ unsigned int rVal; \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | DcrRegister); \
+ rVal = XIo_mDcrReadReg((DcrBase) | XDCR_IDA_ACC); \
+ mtmsr(oldMSR); \
+ rVal; \
+})
+
+/******************************************************************************/
+/**
+* Writes the register at specified DCR address using the indirect addressing
+* method.
+*
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param DcrRegister is the intended destination DCR register
+* @param Data is the value to be placed into the specified DRC register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrIndirectAddrWriteReg(u32 DcrBase, u32 DcrRegister,
+* u32 Data)
+*
+* Assumes auto-buslocking feature is ON.
+* In order to make this operation atomic, interrupts are disabled before
+* and enabled after the DCR accesses.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrWriteReg(DcrBase, DcrRegister, Data) \
+({ \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | DcrRegister); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, Data); \
+ mtmsr(oldMSR); \
+})
+
+/******************************************************************************/
+/**
+* Reads the APU UDI register at the specified DCR address using the indirect
+* addressing method.
+*
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param UDInum is the intended source DCR register
+*
+* @return
+*
+* Contents of the specified APU register.
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrIndirectAddrReadAPUUDIReg(u32 DcrBase, u32 UDInum)
+*
+* An indirect APU UDI read requires three DCR accesses:
+* 1) Indirect address reg write
+* 2) Indirect access reg write to specify the UDI number
+* 3) Indirect access reg read of the actual data
+* Since (2) unlocks the DCR bus, the DCR bus must be explicitly locked
+* instead of relying on the auto-lock feature.
+* In order to make this operation atomic, interrupts are disabled before
+* and enabled after the DCR accesses.
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrReadAPUUDIReg(DcrBase, UDInum) \
+({ \
+ unsigned int rVal; \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | XDCR_APU_UDI); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, ((UDInum << 6) & 0x000003c0) | 0x00000030); \
+ rVal = XIo_mDcrReadReg((DcrBase) | XDCR_IDA_ACC); \
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+ rVal; \
+})
+
+/******************************************************************************/
+/**
+* Writes the APU UDI register at specified DCR address using the indirect
+* addressing method.
+*
+*
+* @param DcrBase is the base of the block of DCR registers
+* @param UDInum is the intended source DCR register
+* @param Data is the value to be placed into the specified DRC register
+*
+* @return
+*
+* None
+*
+* @note
+*
+* C-style signature:
+* void XIo_mDcrIndirectAddrWriteReg(u32 DcrBase, u32 UDInum, u32 Data)
+*
+* An indirect APU UDI write requires three DCR accesses:
+* 1) Indirect address reg write
+* 2) Indirect access reg write to specify the UDI number
+* 3) Indirect access reg write of the actual data
+* Since (2) unlocks the DCR bus, the DCR bus must be explicitly locked
+* instead of relying on the auto-lock feature.
+* In order to make this operation atomic, interrupts are disabled before
+* and enabled after the DCR accesses.
+* Care must be taken to not write a '1' to either timeout bit because
+* it will be cleared.
+*
+*******************************************************************************/
+#define XIo_mDcrIndirectAddrWriteAPUUDIReg(DcrBase, UDInum, Data) \
+({ \
+ unsigned int oldMSR = mfmsr(); \
+ mtmsr(oldMSR & XDCR_DISABLE_EXCEPTIONS); \
+ XIo_DcrLock((DcrBase)); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ADDR, (DcrBase) | XDCR_APU_UDI); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, ((UDInum << 6) & 0x000003c0) | 0x00000030); \
+ XIo_mDcrWriteReg((DcrBase) | XDCR_IDA_ACC, Data);\
+ XIo_DcrUnlock((DcrBase)); \
+ mtmsr(oldMSR); \
+})
+
+/************************** Function Prototypes ******************************/
+void XIo_DcrOut(u32 DcrRegister, u32 Data);
+u32 XIo_DcrIn(u32 DcrRegister);
+
+u32 XIo_DcrReadReg(u32 DcrBase, u32 DcrRegister);
+void XIo_DcrWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data);
+u32 XIo_DcrLockAndReadReg(u32 DcrBase, u32 DcrRegister);
+void XIo_DcrLockAndWriteReg(u32 DcrBase, u32 DcrRegister, u32 Data);
+
+void XIo_DcrWriteAPUUDIReg(u32 DcrBase, short UDInum, u32 Data);
+u32 XIo_DcrReadAPUUDIReg(u32 DcrBase, short UDInum);
+
+void XIo_DcrLock(u32 DcrBase);
+void XIo_DcrUnlock(u32 DcrBase);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/Makefile
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/Makefile.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/Makefile
@@ -1,6 +1,19 @@
# The Xilinx OS common code
-obj-$(CONFIG_XILINX_EDK) += xbasic_types.o xpacket_fifo_l_v2_00_a.o \
- xpacket_fifo_v2_00_a.o xversion.o \
- xdma_channel.o xdma_channel_sg.o
-obj-$(CONFIG_MODULES) += xilinx_syms.o
+obj-$(CONFIG_XILINX_EDK) += xbasic_types.o \
+ xversion.o xpacket_fifo_v2_00_a.o xpacket_fifo_l_v2_00_a.o \
+ xdma_channel.o xdma_channel_sg.o xio.o
+
+obj-$(CONFIG_NEED_XILINX_DMAV3) += \
+ xdmav3.o xdmav3_intr.o xdmav3_sg.o \
+ xdmav3_selftest.o xdmav3_simple.o
+
+obj-$(CONFIG_NEED_XILINX_LLDMA) += \
+ xlldma_bdring.o xlldma.o \
+ xllfifo.o xstreamer.o
+
+obj-$(CONFIG_NEED_XILINX_IPIF) += \
+ xipif_v1_23_b.o
+
+obj-$(CONFIG_NEED_XILINX_PPC_DCR) += \
+ xio_dcr.o
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_intr.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_intr.c
@@ -0,0 +1,129 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_intr.c
+*
+* This file implements interrupt control related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 3.00a rmm 03/11/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* Set the interrupt status register for this channel. Use this function
+* to ack pending interrupts.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param Mask is a logical OR of XDMAV3_IPXR_*_MASK constants found in
+* xdmav3_l.h.
+*
+******************************************************************************/
+void XDmaV3_SetInterruptStatus(XDmaV3 * InstancePtr, u32 Mask)
+{
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_ISR_OFFSET, Mask);
+}
+
+
+/*****************************************************************************/
+/**
+* Retrieve the interrupt status for this channel. OR the results of this
+* function with results from XDmaV3_GetInterruptEnable() to determine which
+* interrupts are currently pending to the processor.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @return Mask of interrupt bits made up of XDMAV3_IPXR_*_MASK constants found
+* in xdmav3_l.h.
+*
+******************************************************************************/
+u32 XDmaV3_GetInterruptStatus(XDmaV3 * InstancePtr)
+{
+ return (XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_ISR_OFFSET));
+}
+
+
+/*****************************************************************************/
+/**
+* Enable specific DMA interrupts.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+* @param Mask is a logical OR of of XDMAV3_IPXR_*_MASK constants found in
+* xdmav3_l.h.
+*
+******************************************************************************/
+void XDmaV3_SetInterruptEnable(XDmaV3 * InstancePtr, u32 Mask)
+{
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET, Mask);
+}
+
+
+/*****************************************************************************/
+/**
+* Retrieve the interrupt enable register for this channel. Use this function to
+* determine which interrupts are currently enabled to the processor.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @return Mask of interrupt bits made up of XDMAV3_IPXR_*_MASK constants found in
+* xdmav3_l.h.
+*
+******************************************************************************/
+u32 XDmaV3_GetInterruptEnable(XDmaV3 * InstancePtr)
+{
+ return (XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET));
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xipif_v1_23_b.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xipif_v1_23_b.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xipif_v1_23_b.h
@@ -1,4 +1,4 @@
-/* $Id: xipif_v1_23_b.h,v 1.1 2006/12/13 14:22:44 imanuilov Exp $ */
+/* $Id: xipif_v1_23_b.h,v 1.5 2005/09/26 16:04:52 trujillo Exp $ */
/******************************************************************************
*
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
@@ -17,6 +17,14 @@
*
* (c) Copyright 2002-2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -90,8 +98,8 @@
*
******************************************************************************/
-#ifndef XIPIF_V123B_H /* prevent circular inclusions */
-#define XIPIF_V123B_H /* by using protection macros */
+#ifndef XIPIF_V123B_H /* prevent circular inclusions */
+#define XIPIF_V123B_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
@@ -113,14 +121,14 @@ extern "C" {
* controller registers
* @{
*/
-#define XIIF_V123B_DISR_OFFSET 0UL /**< device interrupt status register */
-#define XIIF_V123B_DIPR_OFFSET 4UL /**< device interrupt pending register */
-#define XIIF_V123B_DIER_OFFSET 8UL /**< device interrupt enable register */
-#define XIIF_V123B_DIIR_OFFSET 24UL /**< device interrupt ID register */
-#define XIIF_V123B_DGIER_OFFSET 28UL /**< device global interrupt enable register */
-#define XIIF_V123B_IISR_OFFSET 32UL /**< IP interrupt status register */
-#define XIIF_V123B_IIER_OFFSET 40UL /**< IP interrupt enable register */
-#define XIIF_V123B_RESETR_OFFSET 64UL /**< reset register */
+#define XIIF_V123B_DISR_OFFSET 0UL /**< device interrupt status register */
+#define XIIF_V123B_DIPR_OFFSET 4UL /**< device interrupt pending register */
+#define XIIF_V123B_DIER_OFFSET 8UL /**< device interrupt enable register */
+#define XIIF_V123B_DIIR_OFFSET 24UL /**< device interrupt ID register */
+#define XIIF_V123B_DGIER_OFFSET 28UL /**< device global interrupt enable register */
+#define XIIF_V123B_IISR_OFFSET 32UL /**< IP interrupt status register */
+#define XIIF_V123B_IIER_OFFSET 40UL /**< IP interrupt enable register */
+#define XIIF_V123B_RESETR_OFFSET 64UL /**< reset register */
/* @} */
/**
@@ -140,7 +148,7 @@ extern "C" {
* registers of the IPIF. Interrupts are assigned in the register from LSB
* to the MSB
*/
-#define XIIF_V123B_ERROR_MASK 1UL /**< LSB of the register */
+#define XIIF_V123B_ERROR_MASK 1UL /**< LSB of the register */
/** @name Interrupt IDs
*
@@ -295,8 +303,8 @@ extern "C" {
*
* @note
*
-* Signature: Xuint32 XIIF_V123B_WRITE_DIER(Xuint32 RegBaseAddress,
-* Xuint32 Enable)
+* Signature: u32 XIIF_V123B_WRITE_DIER(u32 RegBaseAddress,
+* u32 Enable)
*
******************************************************************************/
#define XIIF_V123B_WRITE_DIER(RegBaseAddress, Enable) \
@@ -494,7 +502,7 @@ extern "C" {
*
* @return
*
-* XTRUE if interrupts are enabled for the IPIF, XFALSE otherwise.
+* TRUE if interrupts are enabled for the IPIF, FALSE otherwise.
*
* @note
*
@@ -637,7 +645,7 @@ extern "C" {
*
* @note
*
-* Signature: Xuint32 XIIF_V123B_READ_IIER(Xuint32 RegBaseAddress)
+* Signature: u32 XIIF_V123B_READ_IIER(u32 RegBaseAddress)
*
******************************************************************************/
#define XIIF_V123B_READ_IIER(RegBaseAddress) \
@@ -648,10 +656,10 @@ extern "C" {
/**
* Initialization Functions
*/
-XStatus XIpIfV123b_SelfTest(Xuint32 RegBaseAddress, Xuint8 IpRegistersWidth);
+int XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth);
#ifdef __cplusplus
}
#endif
-#endif /* end of protection macro */
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xbuf_descriptor.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xbuf_descriptor.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xbuf_descriptor.h
@@ -50,8 +50,8 @@
*
******************************************************************************/
-#ifndef XBUF_DESCRIPTOR_H /* prevent circular inclusions */
-#define XBUF_DESCRIPTOR_H /* by using protection macros */
+#ifndef XBUF_DESCRIPTOR_H /* prevent circular inclusions */
+#define XBUF_DESCRIPTOR_H /* by using protection macros */
/***************************** Include Files *********************************/
@@ -1084,4 +1084,4 @@ void XBufDescriptor_Copy(XBufDescriptor*
*/
-#endif /* end of protection macro */
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel_sg.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel_sg.c.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdma_channel_sg.c
@@ -259,7 +259,7 @@
/************************** Constant Definitions *****************************/
-#define XDC_SWCR_SG_ENABLE_MASK 0x80000000UL /* scatter gather enable */
+#define XDC_SWCR_SG_ENABLE_MASK 0x80000000UL /* scatter gather enable */
/**************************** Type Definitions *******************************/
@@ -349,99 +349,100 @@
* buffer descriptors may be processed by the hardware more than once.
*
******************************************************************************/
-XStatus
-XDmaChannel_SgStart(XDmaChannel * InstancePtr)
+int XDmaChannel_SgStart(XDmaChannel * InstancePtr)
{
- u32 Register;
- XBufDescriptor *LastDescriptorPtr;
+ u32 Register;
+ XBufDescriptor *LastDescriptorPtr;
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* if a scatter gather list has not been created yet, return a status */
-
- if (InstancePtr->TotalDescriptorCount == 0) {
- return XST_DMA_SG_NO_LIST;
- }
-
- /* if the scatter gather list exists but is empty then return a status */
-
- if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
- return XST_DMA_SG_LIST_EMPTY;
- }
-
- /* if scatter gather is busy for the DMA channel, return a status because
- * restarting it could lose data
- */
-
- Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
- if (Register & XDC_DMASR_SG_BUSY_MASK) {
- return XST_DMA_SG_IS_STARTED;
- }
-
- /* get the address of the last buffer descriptor which the DMA hardware
- * finished processing
- */
- LastDescriptorPtr = (XBufDescriptor *)
- P_TO_V(XIo_In32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
-
- /* setup the first buffer descriptor that will be sent when the scatter
- * gather channel is enabled, this is only necessary one time since
- * the BDA register of the channel maintains the last buffer descriptor
- * processed
- */
- if (LastDescriptorPtr == NULL) {
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET,
- (u32) V_TO_P(InstancePtr->GetPtr));
- } else {
- XBufDescriptor *NextDescriptorPtr;
-
- /* get the next descriptor to be started, if the status indicates it
- * hasn't already been used by the h/w, then it's OK to start it,
- * s/w sets the status of each descriptor to busy and then h/w clears
- * the busy when it is complete
- */
- NextDescriptorPtr =
- P_TO_V(XBufDescriptor_GetNextPtr(LastDescriptorPtr));
-
- if ((XBufDescriptor_GetStatus(NextDescriptorPtr) &
- XDC_DMASR_BUSY_MASK) == 0) {
- return XST_DMA_SG_NO_DATA;
- }
- /* don't start the DMA SG channel if the descriptor to be processed
- * by h/w is to be committed by the s/w, this function can be called
- * such that it interrupts a thread that was putting into the list
- */
- if (NextDescriptorPtr == InstancePtr->CommitPtr) {
- return XST_DMA_SG_BD_NOT_COMMITTED;
- }
- }
-
- /* start the scatter gather operation by clearing the stop bit in the
- * control register and setting the enable bit in the s/w control register,
- * both of these are necessary to cause it to start, right now the order of
- * these statements is important, the software control register should be
- * set 1st. The other order can cause the CPU to have a loss of sync
- * because it cannot read/write the register while the DMA operation is
- * running
- */
-
- Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
-
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
- Register | XDC_SWCR_SG_ENABLE_MASK);
-
- Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
-
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
- Register & ~XDC_DMACR_SG_DISABLE_MASK);
-
- /* indicate the DMA channel scatter gather operation was started
- * successfully
- */
- return XST_SUCCESS;
+ /* if a scatter gather list has not been created yet, return a status */
+
+ if (InstancePtr->TotalDescriptorCount == 0) {
+ return XST_DMA_SG_NO_LIST;
+ }
+
+ /* if the scatter gather list exists but is empty then return a status */
+
+ if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+ return XST_DMA_SG_LIST_EMPTY;
+ }
+
+ /* if scatter gather is busy for the DMA channel, return a status because
+ * restarting it could lose data
+ */
+
+ Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+ if (Register & XDC_DMASR_SG_BUSY_MASK) {
+ return XST_DMA_SG_IS_STARTED;
+ }
+
+ /* get the address of the last buffer descriptor which the DMA hardware
+ * finished processing
+ */
+ LastDescriptorPtr = (XBufDescriptor *)
+ P_TO_V(XIo_In32
+ (InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
+
+ /* setup the first buffer descriptor that will be sent when the scatter
+ * gather channel is enabled, this is only necessary one time since
+ * the BDA register of the channel maintains the last buffer descriptor
+ * processed
+ */
+ if (LastDescriptorPtr == NULL) {
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET,
+ (u32) V_TO_P(InstancePtr->GetPtr));
+ }
+ else {
+ XBufDescriptor *NextDescriptorPtr;
+
+ /* get the next descriptor to be started, if the status indicates it
+ * hasn't already been used by the h/w, then it's OK to start it,
+ * s/w sets the status of each descriptor to busy and then h/w clears
+ * the busy when it is complete
+ */
+ NextDescriptorPtr =
+ P_TO_V(XBufDescriptor_GetNextPtr(LastDescriptorPtr));
+
+ if ((XBufDescriptor_GetStatus(NextDescriptorPtr) &
+ XDC_DMASR_BUSY_MASK) == 0) {
+ return XST_DMA_SG_NO_DATA;
+ }
+ /* don't start the DMA SG channel if the descriptor to be processed
+ * by h/w is to be committed by the s/w, this function can be called
+ * such that it interrupts a thread that was putting into the list
+ */
+ if (NextDescriptorPtr == InstancePtr->CommitPtr) {
+ return XST_DMA_SG_BD_NOT_COMMITTED;
+ }
+ }
+
+ /* start the scatter gather operation by clearing the stop bit in the
+ * control register and setting the enable bit in the s/w control register,
+ * both of these are necessary to cause it to start, right now the order of
+ * these statements is important, the software control register should be
+ * set 1st. The other order can cause the CPU to have a loss of sync
+ * because it cannot read/write the register while the DMA operation is
+ * running
+ */
+
+ Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+ Register | XDC_SWCR_SG_ENABLE_MASK);
+
+ Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
+ Register & ~XDC_DMACR_SG_DISABLE_MASK);
+
+ /* indicate the DMA channel scatter gather operation was started
+ * successfully
+ */
+ return XST_SUCCESS;
}
/******************************************************************************
@@ -495,51 +496,53 @@ XDmaChannel_SgStart(XDmaChannel * Instan
* may never return.
*
******************************************************************************/
-XStatus
+int
XDmaChannel_SgStop(XDmaChannel * InstancePtr,
- XBufDescriptor ** BufDescriptorPtr)
+ XBufDescriptor ** BufDescriptorPtr)
{
- u32 Register;
+ u32 Register;
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(BufDescriptorPtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* get the contents of the software control register, if scatter gather is not
- * enabled (started), then return a status because the disable acknowledge
- * would not be generated
- */
- Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
-
- if ((Register & XDC_SWCR_SG_ENABLE_MASK) == 0) {
- return XST_DMA_SG_IS_STOPPED;
- }
-
- /* disable scatter gather by writing to the software control register
- * without modifying any other bits of the register
- */
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
- Register & ~XDC_SWCR_SG_ENABLE_MASK);
-
- /* scatter gather does not disable immediately, but after the current
- * buffer descriptor is complete, so wait for the DMA channel to indicate
- * the disable is complete
- */
- do {
- Register =
- XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
- }
- while (Register & XDC_DMASR_SG_BUSY_MASK);
-
- /* set the specified buffer descriptor pointer to point to the buffer
- * descriptor that the scatter gather DMA channel was processing
- */
- *BufDescriptorPtr = (XBufDescriptor *)
- P_TO_V(XIo_In32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufDescriptorPtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* get the contents of the software control register, if scatter gather is not
+ * enabled (started), then return a status because the disable acknowledge
+ * would not be generated
+ */
+ Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+ if ((Register & XDC_SWCR_SG_ENABLE_MASK) == 0) {
+ return XST_DMA_SG_IS_STOPPED;
+ }
+
+ /* disable scatter gather by writing to the software control register
+ * without modifying any other bits of the register
+ */
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+ Register & ~XDC_SWCR_SG_ENABLE_MASK);
+
+ /* scatter gather does not disable immediately, but after the current
+ * buffer descriptor is complete, so wait for the DMA channel to indicate
+ * the disable is complete
+ */
+ do {
+ Register =
+ XIo_In32(InstancePtr->RegBaseAddress +
+ XDC_DMAS_REG_OFFSET);
+ }
+ while (Register & XDC_DMASR_SG_BUSY_MASK);
+
+ /* set the specified buffer descriptor pointer to point to the buffer
+ * descriptor that the scatter gather DMA channel was processing
+ */
+ *BufDescriptorPtr = (XBufDescriptor *)
+ P_TO_V(XIo_In32
+ (InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET));
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/******************************************************************************
@@ -587,95 +590,95 @@ XDmaChannel_SgStop(XDmaChannel * Instanc
* None.
*
******************************************************************************/
-XStatus
+int
XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
- u32 * MemoryPtr, u32 ByteCount, void *PhyPtr)
+ u32 *MemoryPtr, u32 ByteCount, void *PhyPtr)
{
- XBufDescriptor *BufferDescriptorPtr = (XBufDescriptor *) MemoryPtr;
- XBufDescriptor *PreviousDescriptorPtr = NULL;
- XBufDescriptor *StartOfListPtr = BufferDescriptorPtr;
- u32 UsedByteCount;
-
- /* assert to verify valid input arguments, alignment for those
- * arguments that have alignment restrictions, and at least enough
- * memory for one buffer descriptor
- */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(MemoryPtr != NULL);
- XASSERT_NONVOID(((u32) MemoryPtr & 3) == 0);
- XASSERT_NONVOID(ByteCount != 0);
- XASSERT_NONVOID(ByteCount >= sizeof (XBufDescriptor));
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* if the scatter gather list has already been created, then return
- * with a status
- */
- if (InstancePtr->TotalDescriptorCount != 0) {
- return XST_DMA_SG_LIST_EXISTS;
- }
-
- /* save this up front so V_TO_P() works correctly */
- InstancePtr->VirtPtr = MemoryPtr;
- InstancePtr->PhyPtr = PhyPtr;
-
- /* loop thru the specified memory block and create as many buffer
- * descriptors as possible putting each into the list which is
- * implemented as a ring buffer, make sure not to use any memory which
- * is not large enough for a complete buffer descriptor
- */
- UsedByteCount = 0;
- while ((UsedByteCount + sizeof (XBufDescriptor)) <= ByteCount) {
- /* setup a pointer to the next buffer descriptor in the memory and
- * update # of used bytes to know when all of memory is used
- */
- BufferDescriptorPtr = (XBufDescriptor *) ((u32) MemoryPtr +
- UsedByteCount);
-
- /* initialize the new buffer descriptor such that it doesn't contain
- * garbage which could be used by the DMA hardware
- */
- XBufDescriptor_Initialize(BufferDescriptorPtr);
-
- /* if this is not the first buffer descriptor to be created,
- * then link it to the last created buffer descriptor
- */
- if (PreviousDescriptorPtr != NULL) {
- XBufDescriptor_SetNextPtr(PreviousDescriptorPtr,
- V_TO_P(BufferDescriptorPtr));
- }
-
- /* always keep a pointer to the last created buffer descriptor such
- * that they can be linked together in the ring buffer
- */
- PreviousDescriptorPtr = BufferDescriptorPtr;
-
- /* keep a count of the number of descriptors in the list to allow
- * error processing to be performed
- */
- InstancePtr->TotalDescriptorCount++;
-
- UsedByteCount += sizeof (XBufDescriptor);
- }
-
- /* connect the last buffer descriptor created and inserted in the list
- * to the first such that a ring buffer is created
- */
- XBufDescriptor_SetNextPtr(BufferDescriptorPtr, V_TO_P(StartOfListPtr));
-
- /* initialize the ring buffer to indicate that there are no
- * buffer descriptors in the list which point to valid data buffers
- */
- InstancePtr->PutPtr = BufferDescriptorPtr;
- InstancePtr->GetPtr = BufferDescriptorPtr;
- InstancePtr->CommitPtr = NULL;
- InstancePtr->LastPtr = BufferDescriptorPtr;
- InstancePtr->ActiveDescriptorCount = 0;
- InstancePtr->ActivePacketCount = 0;
- InstancePtr->Committed = XFALSE;
+ XBufDescriptor *BufferDescriptorPtr = (XBufDescriptor *) MemoryPtr;
+ XBufDescriptor *PreviousDescriptorPtr = NULL;
+ XBufDescriptor *StartOfListPtr = BufferDescriptorPtr;
+ u32 UsedByteCount;
+
+ /* assert to verify valid input arguments, alignment for those
+ * arguments that have alignment restrictions, and at least enough
+ * memory for one buffer descriptor
+ */
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(MemoryPtr != NULL);
+ XASSERT_NONVOID(((u32) MemoryPtr & 3) == 0);
+ XASSERT_NONVOID(ByteCount != 0);
+ XASSERT_NONVOID(ByteCount >= sizeof(XBufDescriptor));
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* if the scatter gather list has already been created, then return
+ * with a status
+ */
+ if (InstancePtr->TotalDescriptorCount != 0) {
+ return XST_DMA_SG_LIST_EXISTS;
+ }
+
+ /* save this up front so V_TO_P() works correctly */
+ InstancePtr->VirtPtr = MemoryPtr;
+ InstancePtr->PhyPtr = PhyPtr;
+
+ /* loop thru the specified memory block and create as many buffer
+ * descriptors as possible putting each into the list which is
+ * implemented as a ring buffer, make sure not to use any memory which
+ * is not large enough for a complete buffer descriptor
+ */
+ UsedByteCount = 0;
+ while ((UsedByteCount + sizeof(XBufDescriptor)) <= ByteCount) {
+ /* setup a pointer to the next buffer descriptor in the memory and
+ * update # of used bytes to know when all of memory is used
+ */
+ BufferDescriptorPtr = (XBufDescriptor *) ((u32) MemoryPtr +
+ UsedByteCount);
+
+ /* initialize the new buffer descriptor such that it doesn't contain
+ * garbage which could be used by the DMA hardware
+ */
+ XBufDescriptor_Initialize(BufferDescriptorPtr);
+
+ /* if this is not the first buffer descriptor to be created,
+ * then link it to the last created buffer descriptor
+ */
+ if (PreviousDescriptorPtr != NULL) {
+ XBufDescriptor_SetNextPtr(PreviousDescriptorPtr,
+ V_TO_P(BufferDescriptorPtr));
+ }
+
+ /* always keep a pointer to the last created buffer descriptor such
+ * that they can be linked together in the ring buffer
+ */
+ PreviousDescriptorPtr = BufferDescriptorPtr;
+
+ /* keep a count of the number of descriptors in the list to allow
+ * error processing to be performed
+ */
+ InstancePtr->TotalDescriptorCount++;
+
+ UsedByteCount += sizeof(XBufDescriptor);
+ }
+
+ /* connect the last buffer descriptor created and inserted in the list
+ * to the first such that a ring buffer is created
+ */
+ XBufDescriptor_SetNextPtr(BufferDescriptorPtr, V_TO_P(StartOfListPtr));
+
+ /* initialize the ring buffer to indicate that there are no
+ * buffer descriptors in the list which point to valid data buffers
+ */
+ InstancePtr->PutPtr = BufferDescriptorPtr;
+ InstancePtr->GetPtr = BufferDescriptorPtr;
+ InstancePtr->CommitPtr = NULL;
+ InstancePtr->LastPtr = BufferDescriptorPtr;
+ InstancePtr->ActiveDescriptorCount = 0;
+ InstancePtr->ActivePacketCount = 0;
+ InstancePtr->Committed = FALSE;
- /* indicate the scatter gather list was successfully created */
+ /* indicate the scatter gather list was successfully created */
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/******************************************************************************
@@ -706,18 +709,17 @@ XDmaChannel_CreateSgList(XDmaChannel * I
* None.
*
******************************************************************************/
-u32
-XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr)
+u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr)
{
- /* assert to verify valid input arguments */
+ /* assert to verify valid input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* if the number of descriptors which are being used in the list is zero
- * then the list is empty
- */
- return (InstancePtr->ActiveDescriptorCount == 0);
+ /* if the number of descriptors which are being used in the list is zero
+ * then the list is empty
+ */
+ return (InstancePtr->ActiveDescriptorCount == 0);
}
/******************************************************************************
@@ -771,103 +773,102 @@ XDmaChannel_IsSgListEmpty(XDmaChannel *
* putting buffer descriptors into it.
*
******************************************************************************/
-XStatus
+int
XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
- XBufDescriptor * BufferDescriptorPtr)
+ XBufDescriptor * BufferDescriptorPtr)
{
- u32 Control;
+ u32 Control;
- /* assert to verify valid input arguments and alignment for those
- * arguments that have alignment restrictions
- */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(BufferDescriptorPtr != NULL);
- XASSERT_NONVOID(((u32) BufferDescriptorPtr & 3) == 0);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* if a scatter gather list has not been created yet, return a status */
-
- if (InstancePtr->TotalDescriptorCount == 0) {
- return XST_DMA_SG_NO_LIST;
- }
-
- /* if the list is full because all descriptors are pointing to valid
- * buffers, then indicate an error, this code assumes no list or an
- * empty list is detected above
- */
- if (InstancePtr->ActiveDescriptorCount ==
- InstancePtr->TotalDescriptorCount) {
- return XST_DMA_SG_LIST_FULL;
- }
-
- /* if the buffer descriptor in the list which is to be overwritten is
- * locked, then don't overwrite it and return a status
- */
- if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) {
- return XST_DMA_SG_BD_LOCKED;
- }
-
- /* set the scatter gather stop bit in the control word of the descriptor
- * to cause the h/w to stop after it processes this descriptor since it
- * will be the last in the list
- */
- Control = XBufDescriptor_GetControl(BufferDescriptorPtr);
- XBufDescriptor_SetControl(BufferDescriptorPtr,
- Control | XDC_DMACR_SG_DISABLE_MASK);
-
- /* set both statuses in the descriptor so we tell if they are updated with
- * the status of the transfer, the hardware should change the busy in the
- * DMA status to be false when it completes
- */
- XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK);
- XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0);
-
- /* copy the descriptor into the next position in the list so it's ready to
- * be used by the h/w, this assumes the descriptor in the list prior to this
- * one still has the stop bit in the control word set such that the h/w
- * use this one yet
- */
- CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr);
-
- /* End of a packet is reached. Bump the packet counter */
- if (XBufDescriptor_IsLastControl(InstancePtr->PutPtr))
- {
- InstancePtr->ActivePacketCount++;
- }
-
- /* only the last in the list and the one to be committed have scatter gather
- * disabled in the control word, a commit requires only one descriptor
- * to be changed, when # of descriptors to commit > 2 all others except the
- * 1st and last have scatter gather enabled
- */
- if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) &&
- (InstancePtr->CommitPtr != NULL)) {
- Control = XBufDescriptor_GetControl(InstancePtr->LastPtr);
- XBufDescriptor_SetControl(InstancePtr->LastPtr,
- Control & ~XDC_DMACR_SG_DISABLE_MASK);
- }
-
- /* update the list data based upon putting a descriptor into the list,
- * these operations must be last
- */
- InstancePtr->ActiveDescriptorCount++;
-
- /* only update the commit pointer if it is not already active, this allows
- * it to be deactivated after every commit such that a single descriptor
- * which is committed does not appear to be waiting to be committed
- */
- if (InstancePtr->CommitPtr == NULL) {
- InstancePtr->CommitPtr = InstancePtr->LastPtr;
- }
-
- /* these updates MUST BE LAST after the commit pointer update in order for
- * the commit pointer to track the correct descriptor to be committed
- */
- InstancePtr->LastPtr = InstancePtr->PutPtr;
- InstancePtr->PutPtr =
- P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->PutPtr));
+ /* assert to verify valid input arguments and alignment for those
+ * arguments that have alignment restrictions
+ */
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufferDescriptorPtr != NULL);
+ XASSERT_NONVOID(((u32) BufferDescriptorPtr & 3) == 0);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* if a scatter gather list has not been created yet, return a status */
+
+ if (InstancePtr->TotalDescriptorCount == 0) {
+ return XST_DMA_SG_NO_LIST;
+ }
+
+ /* if the list is full because all descriptors are pointing to valid
+ * buffers, then indicate an error, this code assumes no list or an
+ * empty list is detected above
+ */
+ if (InstancePtr->ActiveDescriptorCount ==
+ InstancePtr->TotalDescriptorCount) {
+ return XST_DMA_SG_LIST_FULL;
+ }
+
+ /* if the buffer descriptor in the list which is to be overwritten is
+ * locked, then don't overwrite it and return a status
+ */
+ if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) {
+ return XST_DMA_SG_BD_LOCKED;
+ }
+
+ /* set the scatter gather stop bit in the control word of the descriptor
+ * to cause the h/w to stop after it processes this descriptor since it
+ * will be the last in the list
+ */
+ Control = XBufDescriptor_GetControl(BufferDescriptorPtr);
+ XBufDescriptor_SetControl(BufferDescriptorPtr,
+ Control | XDC_DMACR_SG_DISABLE_MASK);
+
+ /* set both statuses in the descriptor so we tell if they are updated with
+ * the status of the transfer, the hardware should change the busy in the
+ * DMA status to be false when it completes
+ */
+ XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK);
+ XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0);
+
+ /* copy the descriptor into the next position in the list so it's ready to
+ * be used by the h/w, this assumes the descriptor in the list prior to this
+ * one still has the stop bit in the control word set such that the h/w
+ * use this one yet
+ */
+ CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr);
+
+ /* End of a packet is reached. Bump the packet counter */
+ if (XBufDescriptor_IsLastControl(InstancePtr->PutPtr)) {
+ InstancePtr->ActivePacketCount++;
+ }
+
+ /* only the last in the list and the one to be committed have scatter gather
+ * disabled in the control word, a commit requires only one descriptor
+ * to be changed, when # of descriptors to commit > 2 all others except the
+ * 1st and last have scatter gather enabled
+ */
+ if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) &&
+ (InstancePtr->CommitPtr != NULL)) {
+ Control = XBufDescriptor_GetControl(InstancePtr->LastPtr);
+ XBufDescriptor_SetControl(InstancePtr->LastPtr,
+ Control & ~XDC_DMACR_SG_DISABLE_MASK);
+ }
+
+ /* update the list data based upon putting a descriptor into the list,
+ * these operations must be last
+ */
+ InstancePtr->ActiveDescriptorCount++;
+
+ /* only update the commit pointer if it is not already active, this allows
+ * it to be deactivated after every commit such that a single descriptor
+ * which is committed does not appear to be waiting to be committed
+ */
+ if (InstancePtr->CommitPtr == NULL) {
+ InstancePtr->CommitPtr = InstancePtr->LastPtr;
+ }
+
+ /* these updates MUST BE LAST after the commit pointer update in order for
+ * the commit pointer to track the correct descriptor to be committed
+ */
+ InstancePtr->LastPtr = InstancePtr->PutPtr;
+ InstancePtr->PutPtr =
+ P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->PutPtr));
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/******************************************************************************
@@ -906,44 +907,43 @@ XDmaChannel_PutDescriptor(XDmaChannel *
* None.
*
******************************************************************************/
-XStatus
-XDmaChannel_CommitPuts(XDmaChannel * InstancePtr)
+int XDmaChannel_CommitPuts(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* if the buffer descriptor to be committed is already committed or
- * the list is empty (none have been put in), then indicate an error
- */
- if ((InstancePtr->CommitPtr == NULL) ||
- XDmaChannel_IsSgListEmpty(InstancePtr)) {
- return XST_DMA_SG_NOTHING_TO_COMMIT;
- }
-
- /* last descriptor in the list must have scatter gather disabled so the end
- * of the list is hit by h/w, if descriptor to commit is not last in list,
- * commit descriptors by enabling scatter gather in the descriptor
- */
- if (InstancePtr->CommitPtr != InstancePtr->LastPtr) {
- u32 Control;
-
- Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr);
- XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control &
- ~XDC_DMACR_SG_DISABLE_MASK);
- }
-
- /* Buffer Descriptors are committed. DMA is ready to be enabled */
- InstancePtr->Committed = XTRUE;
-
- /* Update the commit pointer to indicate that there is nothing to be
- * committed, this state is used by start processing to know that the
- * buffer descriptor to start is not waiting to be committed
- */
- InstancePtr->CommitPtr = NULL;
+ /* if the buffer descriptor to be committed is already committed or
+ * the list is empty (none have been put in), then indicate an error
+ */
+ if ((InstancePtr->CommitPtr == NULL) ||
+ XDmaChannel_IsSgListEmpty(InstancePtr)) {
+ return XST_DMA_SG_NOTHING_TO_COMMIT;
+ }
+
+ /* last descriptor in the list must have scatter gather disabled so the end
+ * of the list is hit by h/w, if descriptor to commit is not last in list,
+ * commit descriptors by enabling scatter gather in the descriptor
+ */
+ if (InstancePtr->CommitPtr != InstancePtr->LastPtr) {
+ u32 Control;
+
+ Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr);
+ XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control &
+ ~XDC_DMACR_SG_DISABLE_MASK);
+ }
+
+ /* Buffer Descriptors are committed. DMA is ready to be enabled */
+ InstancePtr->Committed = TRUE;
+
+ /* Update the commit pointer to indicate that there is nothing to be
+ * committed, this state is used by start processing to know that the
+ * buffer descriptor to start is not waiting to be committed
+ */
+ InstancePtr->CommitPtr = NULL;
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/******************************************************************************
@@ -994,52 +994,52 @@ XDmaChannel_CommitPuts(XDmaChannel * Ins
* None.
*
******************************************************************************/
-XStatus
+int
XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
- XBufDescriptor ** BufDescriptorPtr)
+ XBufDescriptor ** BufDescriptorPtr)
{
- u32 Control;
+ u32 Control;
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(BufDescriptorPtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* if a scatter gather list has not been created yet, return a status */
-
- if (InstancePtr->TotalDescriptorCount == 0) {
- return XST_DMA_SG_NO_LIST;
- }
-
- /* if the buffer descriptor list is empty, then indicate an error */
-
- if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
- return XST_DMA_SG_LIST_EMPTY;
- }
-
- /* retrieve the next buffer descriptor which is ready to be processed from
- * the buffer descriptor list for the DMA channel, set the control word
- * such that hardware will stop after the descriptor has been processed
- */
- Control = XBufDescriptor_GetControl(InstancePtr->GetPtr);
- XBufDescriptor_SetControl(InstancePtr->GetPtr,
- Control | XDC_DMACR_SG_DISABLE_MASK);
-
- /* set the input argument, which is also an output, to point to the
- * buffer descriptor which is to be retrieved from the list
- */
- *BufDescriptorPtr = InstancePtr->GetPtr;
-
- /* update the pointer of the DMA channel to reflect the buffer descriptor
- * was retrieved from the list by setting it to the next buffer descriptor
- * in the list and indicate one less descriptor in the list now
- */
- InstancePtr->GetPtr =
- P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->GetPtr));
- InstancePtr->ActiveDescriptorCount--;
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufDescriptorPtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* if a scatter gather list has not been created yet, return a status */
+
+ if (InstancePtr->TotalDescriptorCount == 0) {
+ return XST_DMA_SG_NO_LIST;
+ }
+
+ /* if the buffer descriptor list is empty, then indicate an error */
+
+ if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+ return XST_DMA_SG_LIST_EMPTY;
+ }
+
+ /* retrieve the next buffer descriptor which is ready to be processed from
+ * the buffer descriptor list for the DMA channel, set the control word
+ * such that hardware will stop after the descriptor has been processed
+ */
+ Control = XBufDescriptor_GetControl(InstancePtr->GetPtr);
+ XBufDescriptor_SetControl(InstancePtr->GetPtr,
+ Control | XDC_DMACR_SG_DISABLE_MASK);
+
+ /* set the input argument, which is also an output, to point to the
+ * buffer descriptor which is to be retrieved from the list
+ */
+ *BufDescriptorPtr = InstancePtr->GetPtr;
+
+ /* update the pointer of the DMA channel to reflect the buffer descriptor
+ * was retrieved from the list by setting it to the next buffer descriptor
+ * in the list and indicate one less descriptor in the list now
+ */
+ InstancePtr->GetPtr =
+ P_TO_V(XBufDescriptor_GetNextPtr(InstancePtr->GetPtr));
+ InstancePtr->ActiveDescriptorCount--;
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/*********************** Interrupt Collescing Functions **********************/
@@ -1071,17 +1071,16 @@ XDmaChannel_GetDescriptor(XDmaChannel *
* None.
*
******************************************************************************/
-u32
-XDmaChannel_GetPktCount(XDmaChannel * InstancePtr)
+u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* get the unserviced packet count from the register and return it */
+ /* get the unserviced packet count from the register and return it */
- return XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+ return XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
}
/******************************************************************************
@@ -1112,26 +1111,25 @@ XDmaChannel_GetPktCount(XDmaChannel * In
* None.
*
******************************************************************************/
-void
-XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr)
+void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr)
{
- u32 Register;
+ u32 Register;
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_VOID(InstancePtr != NULL);
- XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* if the unserviced packet count register can be decremented (rather
- * than rolling over) decrement it by writing a 1 to the register,
- * this is the only valid write to the register as it serves as an
- * acknowledge that a packet was handled by the software
- */
- Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
- if (Register > 0) {
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET,
- 1UL);
- }
+ /* if the unserviced packet count register can be decremented (rather
+ * than rolling over) decrement it by writing a 1 to the register,
+ * this is the only valid write to the register as it serves as an
+ * acknowledge that a packet was handled by the software
+ */
+ Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+ if (Register > 0) {
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET,
+ 1UL);
+ }
}
/******************************************************************************
@@ -1173,25 +1171,24 @@ XDmaChannel_DecrementPktCount(XDmaChanne
* caused confustion.
*
******************************************************************************/
-XStatus
-XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold)
+int XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold)
{
- /* assert to verify input arguments, don't assert the threshold since
- * it's range is unknown
- */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* set the packet count threshold in the register such that an interrupt
- * may be generated, if enabled, when the packet count threshold is
- * reached or exceeded
- */
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET,
- (u32) Threshold);
+ /* assert to verify input arguments, don't assert the threshold since
+ * it's range is unknown
+ */
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* set the packet count threshold in the register such that an interrupt
+ * may be generated, if enabled, when the packet count threshold is
+ * reached or exceeded
+ */
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET,
+ (u32) Threshold);
- /* indicate the packet count threshold was successfully set */
+ /* indicate the packet count threshold was successfully set */
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/******************************************************************************
@@ -1225,18 +1222,17 @@ XDmaChannel_SetPktThreshold(XDmaChannel
* None.
*
******************************************************************************/
-u8
-XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr)
+u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* get the packet count threshold from the register and return it,
- * since only 8 bits are used, cast it to return only those bits */
+ /* get the packet count threshold from the register and return it,
+ * since only 8 bits are used, cast it to return only those bits */
- return (u8) XIo_In32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET);
+ return (u8) XIo_In32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET);
}
/******************************************************************************
@@ -1273,20 +1269,19 @@ XDmaChannel_GetPktThreshold(XDmaChannel
* None.
*
******************************************************************************/
-void
-XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound)
+void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_VOID(InstancePtr != NULL);
- XASSERT_VOID(WaitBound < 1024);
- XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
-
- /* set the packet wait bound in the register such that interrupt may be
- * generated, if enabled, when packets have not been handled for a specific
- * amount of time
- */
- XIo_Out32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET, WaitBound);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(WaitBound < 1024);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ /* set the packet wait bound in the register such that interrupt may be
+ * generated, if enabled, when packets have not been handled for a specific
+ * amount of time
+ */
+ XIo_Out32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET, WaitBound);
}
/******************************************************************************
@@ -1319,15 +1314,14 @@ XDmaChannel_SetPktWaitBound(XDmaChannel
* None.
*
******************************************************************************/
-u32
-XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr)
+u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != NULL);
- XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
- /* get the packet wait bound from the register and return it */
+ /* get the packet wait bound from the register and return it */
- return XIo_In32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET);
+ return XIo_In32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET);
}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_selftest.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_selftest.c
@@ -0,0 +1,79 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_selftest.c
+*
+* This file implements DMA selftest related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 3.00a rmm 03/11/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+* Selftest is not implemented.
+*
+* @param InstancePtr is a pointer to the instance to be worked on.
+*
+* @return
+* - XST_SUCCESS if the self test passes
+*
+******************************************************************************/
+int XDmaV3_SelfTest(XDmaV3 * InstancePtr)
+{
+ return (XST_SUCCESS);
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.c.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.c
@@ -77,10 +77,10 @@
* format, "X.YYZ" where X is the major revision (0 - 9), YY is the minor
* revision (00 - 99), and Z is the compatability revision (a - z)
*/
-#define XVE_MAJOR_CHAR 0 /* major revision 0 - 9 */
-#define XVE_MINOR_TENS_CHAR 2 /* minor revision tens 0 - 9 */
-#define XVE_MINOR_ONES_CHAR 3 /* minor revision ones 0 - 9 */
-#define XVE_COMP_CHAR 4 /* compatability revision a - z */
+#define XVE_MAJOR_CHAR 0 /* major revision 0 - 9 */
+#define XVE_MINOR_TENS_CHAR 2 /* minor revision tens 0 - 9 */
+#define XVE_MINOR_ONES_CHAR 3 /* minor revision ones 0 - 9 */
+#define XVE_COMP_CHAR 4 /* compatability revision a - z */
#define XVE_END_STRING_CHAR 5
/**************************** Type Definitions *******************************/
@@ -91,7 +91,7 @@
/************************** Function Prototypes ******************************/
-static Xboolean IsVersionStringValid(Xint8* StringPtr);
+static u32 IsVersionStringValid(s8 *StringPtr);
/*****************************************************************************/
/**
@@ -109,9 +109,9 @@ static Xboolean IsVersionStringValid(Xin
* @note None.
*
******************************************************************************/
-void XVersion_UnPack(XVersion *InstancePtr, Xuint16 PackedVersion)
+void XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion)
{
- /* not implemented yet since CROM related */
+ /* not implemented yet since CROM related */
}
/*****************************************************************************/
@@ -138,11 +138,11 @@ void XVersion_UnPack(XVersion *InstanceP
* None.
*
******************************************************************************/
-XStatus XVersion_Pack(XVersion *InstancePtr, Xuint16 *PackedVersionPtr)
+int XVersion_Pack(XVersion * InstancePtr, u16 *PackedVersionPtr)
{
- /* not implemented yet since CROM related */
+ /* not implemented yet since CROM related */
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/*****************************************************************************/
@@ -155,39 +155,37 @@ XStatus XVersion_Pack(XVersion *Instance
*
* @return
*
-* XTRUE if the versions are equal, XFALSE otherwise.
+* TRUE if the versions are equal, FALSE otherwise.
*
* @note
*
* None.
*
******************************************************************************/
-Xboolean XVersion_IsEqual(XVersion *InstancePtr, XVersion *VersionPtr)
+u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr)
{
- Xuint8 *Version1 = (Xuint8 *)InstancePtr;
- Xuint8 *Version2 = (Xuint8 *)VersionPtr;
- int Index;
-
- /* assert to verify input arguments */
-
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(VersionPtr != XNULL);
-
- /* check each byte of the versions to see if they are the same,
- * return at any point a byte differs between them
- */
- for (Index = 0; Index < sizeof(XVersion); Index++)
- {
- if (Version1[Index] != Version2[Index])
- {
- return XFALSE;
- }
- }
-
- /* No byte was found to be different between the versions, so indicate
- * the versions are equal
- */
- return XTRUE;
+ u8 *Version1 = (u8 *) InstancePtr;
+ u8 *Version2 = (u8 *) VersionPtr;
+ int Index;
+
+ /* assert to verify input arguments */
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(VersionPtr != NULL);
+
+ /* check each byte of the versions to see if they are the same,
+ * return at any point a byte differs between them
+ */
+ for (Index = 0; Index < sizeof(XVersion); Index++) {
+ if (Version1[Index] != Version2[Index]) {
+ return FALSE;
+ }
+ }
+
+ /* No byte was found to be different between the versions, so indicate
+ * the versions are equal
+ */
+ return TRUE;
}
/*****************************************************************************/
@@ -213,17 +211,17 @@ Xboolean XVersion_IsEqual(XVersion *Inst
* specified in the version header file.
*
******************************************************************************/
-void XVersion_ToString(XVersion *InstancePtr, Xint8 *StringPtr)
+void XVersion_ToString(XVersion * InstancePtr, s8 *StringPtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(StringPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(StringPtr != NULL);
- /* since version is implemented as a string, just copy the specified
- * input into the specified output
- */
- XVersion_Copy(InstancePtr, (XVersion *)StringPtr);
+ /* since version is implemented as a string, just copy the specified
+ * input into the specified output
+ */
+ XVersion_Copy(InstancePtr, (XVersion *) StringPtr);
}
/*****************************************************************************/
@@ -249,26 +247,25 @@ void XVersion_ToString(XVersion *Instanc
* None.
*
******************************************************************************/
-XStatus XVersion_FromString(XVersion *InstancePtr, Xint8 *StringPtr)
+int XVersion_FromString(XVersion * InstancePtr, s8 *StringPtr)
{
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(StringPtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(StringPtr != NULL);
- /* if the version string specified is not valid, return an error */
+ /* if the version string specified is not valid, return an error */
- if (!IsVersionStringValid(StringPtr))
- {
- return XST_INVALID_VERSION;
- }
+ if (!IsVersionStringValid(StringPtr)) {
+ return XST_INVALID_VERSION;
+ }
- /* copy the specified string into the specified version and indicate the
- * conversion was successful
- */
- XVersion_Copy((XVersion *)StringPtr, InstancePtr);
+ /* copy the specified string into the specified version and indicate the
+ * conversion was successful
+ */
+ XVersion_Copy((XVersion *) StringPtr, InstancePtr);
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/*****************************************************************************/
@@ -290,23 +287,22 @@ XStatus XVersion_FromString(XVersion *In
* None.
*
******************************************************************************/
-void XVersion_Copy(XVersion *InstancePtr, XVersion *VersionPtr)
+void XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr)
{
- Xuint8 *Source = (Xuint8 *)InstancePtr;
- Xuint8 *Destination = (Xuint8 *)VersionPtr;
- int Index;
+ u8 *Source = (u8 *) InstancePtr;
+ u8 *Destination = (u8 *) VersionPtr;
+ int Index;
- /* assert to verify input arguments */
+ /* assert to verify input arguments */
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(VersionPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(VersionPtr != NULL);
- /* copy each byte of the source version to the destination version */
+ /* copy each byte of the source version to the destination version */
- for (Index = 0; Index < sizeof(XVersion); Index++)
- {
- Destination[Index] = Source[Index];
- }
+ for (Index = 0; Index < sizeof(XVersion); Index++) {
+ Destination[Index] = Source[Index];
+ }
}
/*****************************************************************************/
@@ -318,30 +314,28 @@ void XVersion_Copy(XVersion *InstancePtr
*
* @return
*
-* XTRUE if the version string is a valid format, XFALSE otherwise.
+* TRUE if the version string is a valid format, FALSE otherwise.
*
* @note
*
* None.
*
******************************************************************************/
-static Xboolean IsVersionStringValid(Xint8* StringPtr)
+static u32 IsVersionStringValid(s8 *StringPtr)
{
- /* if the input string is not a valid format, "X.YYZ" where X = 0 - 9,
- * YY = 00 - 99, and Z = a - z, then indicate it's not valid
- */
- if ((StringPtr[XVE_MAJOR_CHAR] < '0') ||
- (StringPtr[XVE_MAJOR_CHAR] > '9') ||
- (StringPtr[XVE_MINOR_TENS_CHAR] < '0') ||
- (StringPtr[XVE_MINOR_TENS_CHAR] > '9') ||
- (StringPtr[XVE_MINOR_ONES_CHAR] < '0') ||
- (StringPtr[XVE_MINOR_ONES_CHAR] > '9') ||
- (StringPtr[XVE_COMP_CHAR] < 'a') ||
- (StringPtr[XVE_COMP_CHAR] > 'z'))
- {
- return XFALSE;
- }
+ /* if the input string is not a valid format, "X.YYZ" where X = 0 - 9,
+ * YY = 00 - 99, and Z = a - z, then indicate it's not valid
+ */
+ if ((StringPtr[XVE_MAJOR_CHAR] < '0') ||
+ (StringPtr[XVE_MAJOR_CHAR] > '9') ||
+ (StringPtr[XVE_MINOR_TENS_CHAR] < '0') ||
+ (StringPtr[XVE_MINOR_TENS_CHAR] > '9') ||
+ (StringPtr[XVE_MINOR_ONES_CHAR] < '0') ||
+ (StringPtr[XVE_MINOR_ONES_CHAR] > '9') ||
+ (StringPtr[XVE_COMP_CHAR] < 'a') ||
+ (StringPtr[XVE_COMP_CHAR] > 'z')) {
+ return FALSE;
+ }
- return XTRUE;
+ return TRUE;
}
-
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma.c
@@ -0,0 +1,244 @@
+/* $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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma.c
+*
+* This file implements initialization and control related functions. For more
+* information on this driver, see xlldma.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a xd 12/21/06 First release
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+
+#include "xlldma.h"
+#include "xenv.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+ * This function initializes a DMA engine. This function must be called
+ * prior to using a DMA engine. Initialization of a engine includes setting
+ * up the register base address, setting up the instance data, and ensuring the
+ * hardware is in a quiescent state.
+ *
+ * @param InstancePtr is a pointer to the DMA engine instance to be worked on.
+ * @param BaseAddress is where the registers for this engine can be found.
+ * If address translation is being used, then this parameter must
+ * reflect the virtual base address.
+ * @return None.
+ *
+ *****************************************************************************/
+void XLlDma_Initialize(XLlDma * InstancePtr, u32 BaseAddress)
+{
+ /* Setup the instance */
+ memset(InstancePtr, 0, sizeof(XLlDma));
+ InstancePtr->RegBase = BaseAddress;
+
+ /* Initialize the ring structures */
+ InstancePtr->TxBdRing.RunState = XST_DMA_SG_IS_STOPPED;
+ InstancePtr->TxBdRing.ChanBase = BaseAddress + XLLDMA_TX_OFFSET;
+ InstancePtr->TxBdRing.IsRxChannel = 0;
+ InstancePtr->RxBdRing.RunState = XST_DMA_SG_IS_STOPPED;
+ InstancePtr->RxBdRing.ChanBase = BaseAddress + XLLDMA_RX_OFFSET;
+ InstancePtr->RxBdRing.IsRxChannel = 1;
+
+ /* Reset the device and return */
+ XLlDma_Reset(InstancePtr);
+}
+
+/*****************************************************************************/
+/**
+* Reset both TX and RX channels of a DMA engine.
+*
+* Any DMA transaction in progress aborts immediately. The DMA engine is in
+* stop state after the reset.
+*
+* @param InstancePtr is a pointer to the DMA engine instance to be worked on.
+*
+* @return None.
+*
+* @note
+* - If the hardware is not working properly, this function will enter
+* infinite loop and never return.
+* - After the reset, the Normal mode is enabled, and the overflow error
+* for both TX/RX channels are disabled.
+* - After the reset, the DMA engine is no longer in pausing state, if
+* the DMA engine is paused before the reset operation.
+* - After the reset, the coalescing count value and the delay timeout
+* value are both set to 1 for TX and RX channels.
+* - After the reset, all interrupts are disabled.
+*
+******************************************************************************/
+void XLlDma_Reset(XLlDma * InstancePtr)
+{
+ u32 IrqStatus;
+ XLlDma_BdRing *TxRingPtr, *RxRingPtr;
+
+ TxRingPtr = &XLlDma_mGetTxRing(InstancePtr);
+ RxRingPtr = &XLlDma_mGetRxRing(InstancePtr);
+
+ /* Save the locations of current BDs both rings are working on
+ * before the reset so later we can resume the rings smoothly.
+ */
+ XLlDma_mBdRingSnapShotCurrBd(TxRingPtr);
+ XLlDma_mBdRingSnapShotCurrBd(RxRingPtr);
+
+ /* Start reset process then wait for completion */
+ XLlDma_mSetCr(InstancePtr, XLLDMA_DMACR_SW_RESET_MASK);
+
+ /* Loop until the reset is done */
+ while ((XLlDma_mGetCr(InstancePtr) & XLLDMA_DMACR_SW_RESET_MASK)) {
+ }
+
+ /* Disable all interrupts after issue software reset */
+ XLlDma_mBdRingIntDisable(TxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);
+ XLlDma_mBdRingIntDisable(RxRingPtr, XLLDMA_CR_IRQ_ALL_EN_MASK);
+
+ /* Clear Interrupt registers of both channels, as the software reset
+ * does not clear any register values. Not doing so will cause
+ * interrupts asserted after the software reset if there is any
+ * interrupt left over before.
+ */
+ IrqStatus = XLlDma_mBdRingGetIrq(TxRingPtr);
+ XLlDma_mBdRingAckIrq(TxRingPtr, IrqStatus);
+ IrqStatus = XLlDma_mBdRingGetIrq(RxRingPtr);
+ XLlDma_mBdRingAckIrq(RxRingPtr, IrqStatus);
+
+ /* Enable Normal mode, and disable overflow errors for both channels */
+ XLlDma_mSetCr(InstancePtr, XLLDMA_DMACR_TAIL_PTR_EN_MASK |
+ XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK |
+ XLLDMA_DMACR_TX_OVERFLOW_ERR_DIS_MASK);
+
+ /* Set TX/RX Channel coalescing setting */
+ XLlDma_BdRingSetCoalesce(TxRingPtr, 1, 1);
+ XLlDma_BdRingSetCoalesce(RxRingPtr, 1, 1);
+
+ TxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+ RxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+}
+
+/*****************************************************************************/
+/**
+* Pause DMA transactions on both channels. The DMA enters the pausing state
+* immediately. So if a DMA transaction is in progress, it will be left
+* unfinished and will be continued once the DMA engine is resumed
+* (see XLlDma_Resume()).
+*
+* @param InstancePtr is a pointer to the DMA engine instance to be worked on.
+*
+* @return None.
+*
+* @note
+* - If the hardware is not working properly, this function will enter
+* infinite loop and never return.
+* - After the DMA is paused, DMA channels still could accept more BDs
+* from software (see XLlDma_BdRingToHw()), but new BDs will not be
+* processed until the DMA is resumed (see XLlDma_Resume()).
+*
+*****************************************************************************/
+void XLlDma_Pause(XLlDma * InstancePtr)
+{
+ u32 RegValue;
+ XLlDma_BdRing *TxRingPtr, *RxRingPtr;
+
+ TxRingPtr = &XLlDma_mGetTxRing(InstancePtr);
+ RxRingPtr = &XLlDma_mGetRxRing(InstancePtr);
+
+ /* Do nothing if both channels already stopped */
+ if ((TxRingPtr->RunState == XST_DMA_SG_IS_STOPPED) &&
+ (RxRingPtr->RunState == XST_DMA_SG_IS_STOPPED)) {
+ return;
+ }
+
+ /* Enable pause bits for both TX/ RX channels */
+ RegValue = XLlDma_mGetCr(InstancePtr);
+ XLlDma_mSetCr(InstancePtr, RegValue | XLLDMA_DMACR_TX_PAUSE_MASK |
+ XLLDMA_DMACR_RX_PAUSE_MASK);
+
+ /* Loop until Write Command Queue of RX channel is empty, which
+ * indicates that all the write data associated with the pending
+ * commands has been flushed.*/
+ while (!(XLlDma_mBdRingGetIrq(RxRingPtr) | XLLDMA_IRQ_WRQ_EMPTY_MASK));
+
+ TxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+ RxRingPtr->RunState = XST_DMA_SG_IS_STOPPED;
+}
+
+/*****************************************************************************/
+/**
+* Resume DMA transactions on both channels. Any interrupted DMA transaction
+* caused by DMA pause operation (see XLlDma_Pause()) and all committed
+* transactions after DMA is paused will be continued upon the return of this
+* function.
+*
+* @param InstancePtr is a pointer to the DMA engine instance to be worked on.
+*
+* @return None.
+*
+*****************************************************************************/
+void XLlDma_Resume(XLlDma * InstancePtr)
+{
+ u32 RegValue;
+ XLlDma_BdRing *TxRingPtr, *RxRingPtr;
+
+ TxRingPtr = &XLlDma_mGetTxRing(InstancePtr);
+ RxRingPtr = &XLlDma_mGetRxRing(InstancePtr);
+
+ /* Do nothing if both channels already started */
+ if ((TxRingPtr->RunState == XST_DMA_SG_IS_STARTED) &&
+ (RxRingPtr->RunState == XST_DMA_SG_IS_STARTED)) {
+ return;
+ }
+
+ /* Clear pause bits for both TX/ RX channels */
+ RegValue = XLlDma_mGetCr(InstancePtr);
+ XLlDma_mSetCr(InstancePtr, RegValue & ~(XLLDMA_DMACR_TX_PAUSE_MASK |
+ XLLDMA_DMACR_RX_PAUSE_MASK));
+
+ TxRingPtr->RunState = XST_DMA_SG_IS_STARTED;
+ RxRingPtr->RunState = XST_DMA_SG_IS_STARTED;
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_l.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_l.h
@@ -0,0 +1,295 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the Direct Memory Access and Scatter
+* Gather (SG DMA) device.
+*
+* For more information about the operation of this device, see the hardware
+* specification and documentation in the higher level driver xdma.h source
+* code file.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 3.00a rmm 03/11/06 First release
+* rmm 06/22/06 Added extern "C"
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XDMAV3_L_H /* prevent circular inclusions */
+#define XDMAV3_L_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+/** @name DMA channel registers
+ * @{
+ */
+#define XDMAV3_DMASR_OFFSET 0x00000000 /**< DMA Status Register */
+#define XDMAV3_DMACR_OFFSET 0x00000004 /**< DMA Control Register */
+#define XDMAV3_MSBA_OFFSET 0x00000008 /**< Most Significant Bus Address */
+#define XDMAV3_LSBA_OFFSET 0x0000000C /**< Least Significant Bus Address */
+#define XDMAV3_BDA_OFFSET 0x00000010 /**< Buffer Descriptor Address */
+#define XDMAV3_LENGTH_OFFSET 0x00000014 /**< DMA Length */
+#define XDMAV3_ISR_OFFSET 0x00000018 /**< Interrupt Status Register */
+#define XDMAV3_IER_OFFSET 0x0000001C /**< Interrupt Enable Register */
+#define XDMAV3_SWCR_OFFSET 0x00000020 /**< Software Control Register */
+/*@}*/
+
+/** @name Buffer Descriptor register offsets
+ * @{
+ */
+#define XDMAV3_BD_DMASR_OFFSET 0x00 /**< Channel DMASR register contents */
+#define XDMAV3_BD_DMACR_OFFSET 0x04 /**< Channel DMACR register contents */
+#define XDMAV3_BD_MSBA_OFFSET 0x08 /**< Channel MSBA register contents */
+#define XDMAV3_BD_LSBA_OFFSET 0x0C /**< Channel LSBA register contents */
+#define XDMAV3_BD_BDA_OFFSET 0x10 /**< Next buffer descriptor pointer */
+#define XDMAV3_BD_LENGTH_OFFSET 0x14 /**< Channel LENGTH register contents */
+#define XDMAV3_BD_SR_OFFSET 0x18 /**< Packet Status */
+#define XDMAV3_BD_RSVD_OFFSET 0x1C /**< Reserved */
+#define XDMAV3_BD_USR0_OFFSET 0x20 /**< HW User defined */
+#define XDMAV3_BD_USR1_OFFSET 0x24 /**< HW User defined */
+#define XDMAV3_BD_USR2_OFFSET 0x28 /**< HW User defined */
+#define XDMAV3_BD_USR3_OFFSET 0x2C /**< HW User defined */
+#define XDMAV3_BD_USR4_OFFSET 0x30 /**< HW User defined */
+#define XDMAV3_BD_USR5_OFFSET 0x34 /**< HW User defined */
+#define XDMAV3_BD_LENCPY_OFFSET 0x38 /**< SW Driver usage */
+#define XDMAV3_BD_ID_OFFSET 0x3C /**< SW Driver usage */
+
+#define XDMAV3_BD_NUM_WORDS 16 /**< Number of 32-bit words that make
+ up a BD */
+/*@}*/
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the HW spec.
+ */
+
+
+/** @name DMA Status Register (DMASR) bitmasks
+ * @note These bitmasks are identical between XDMAV3_DMASR_OFFSET and
+ * XDMAV3_BD_DMASR_OFFSET
+ * @{
+ */
+#define XDMAV3_DMASR_DMABSY_MASK 0x80000000 /**< DMA busy */
+#define XDMAV3_DMASR_DBE_MASK 0x40000000 /**< Bus error */
+#define XDMAV3_DMASR_DBT_MASK 0x20000000 /**< Bus timeout */
+#define XDMAV3_DMASR_DMADONE_MASK 0x10000000 /**< DMA done */
+#define XDMAV3_DMASR_SGBSY_MASK 0x08000000 /**< SG channel busy */
+#define XDMAV3_DMASR_LAST_MASK 0x04000000 /**< Last BD of packet */
+#define XDMAV3_DMASR_SGDONE_MASK 0x01000000 /**< SGDMA done */
+#define XDMAV3_DMASR_DMACNFG_MASK 0x00300000 /**< DMA configuration */
+
+#define XDMAV3_DMASR_DMACNFG_SIMPLE_MASK 0x00000000 /**< Simple DMA config */
+#define XDMAV3_DMASR_DMACNFG_SSGDMA_MASK 0x00100000 /**< Simple SGDMA config */
+#define XDMAV3_DMASR_DMACNFG_SGDMATX_MASK 0x00200000 /**< SGDMA xmit config */
+#define XDMAV3_DMASR_DMACNFG_SGDMARX_MASK 0x00300000 /**< SGDMA recv config */
+#define XDMAV3_DMASR_DMACNFG_MASK 0x00300000 /**< Mask for all */
+
+/*@}*/
+
+/** @name DMA Control Register (DMACR) bitmasks
+ * @note These bitmasks are identical between XDMAV3_DMACR_OFFSET and
+ * XDMAV3_BD_DMACR_OFFSET
+ * @{
+ */
+#define XDMAV3_DMACR_AINC_MASK 0x80000000 /**< Address increment */
+#define XDMAV3_DMACR_BPDRE_MASK 0x20000000 /**< Bypass DRE */
+#define XDMAV3_DMACR_SGS_MASK 0x08000000 /**< Scatter gather stop */
+#define XDMAV3_DMACR_LAST_MASK 0x04000000 /**< Last BD of packet */
+#define XDMAV3_DMACR_DEVSEL_MASK 0x00FF0000 /**< Device select */
+#define XDMAV3_DMACR_BDPAGE_MASK 0x00000F00 /**< BD page address */
+#define XDMAV3_DMACR_TYPE_MASK 0x00000070 /**< DMA transfer type */
+#define XDMAV3_DMACR_DSIZE_MASK 0x00000007 /**< DMA transfer width */
+
+/* Sub-fields within XDMAV3_DMACR_DIR_MASK */
+#define XDMAV3_DMACR_DIR_RX_MASK 0x40000000 /**< Xfer in Rx direction */
+#define XDMAV3_DMACR_DIR_TX_MASK 0x00000000 /**< Xfer in Tx direction */
+
+/* Sub-fields within XDMAV3_DMACR_TYPE_MASK */
+#define XDMAV3_DMACR_TYPE_BFBURST_MASK 0x00000010 /**< Bounded fixed length
+ burst */
+#define XDMAV3_DMACR_TYPE_BIBURST_MASK 0x00000020 /**< Bounded indeterminate
+ burst */
+
+/* Sub-fields within XDMAV3_DMACR_DSIZE_MASK */
+#define XDMAV3_DMACR_DSIZE_8_MASK 0x00000000 /**< Xfer width = 8 bits */
+#define XDMAV3_DMACR_DSIZE_16_MASK 0x00000001 /**< Xfer width = 16 bits */
+#define XDMAV3_DMACR_DSIZE_32_MASK 0x00000002 /**< Xfer width = 32 bits */
+#define XDMAV3_DMACR_DSIZE_64_MASK 0x00000003 /**< Xfer width = 64 bits */
+#define XDMAV3_DMACR_DSIZE_128_MASK 0x00000004 /**< Xfer width = 128 bits */
+
+/* Left shift values for selected masks */
+#define XDMAV3_DMACR_DEVSEL_SHIFT 16
+#define XDMAV3_DMACR_BDPAGE_SHIFT 8
+/*@}*/
+
+/** @name Interrupt status bits for MAC interrupts
+ * These bits are associated with XDMAV3_ISR_OFFSET and
+ * XDMAV3_IER_OFFSET registers.
+ * @{
+ */
+#define XDMAV3_IPXR_DD_MASK 0x00000040 /**< DMA complete */
+#define XDMAV3_IPXR_DE_MASK 0x00000020 /**< DMA error */
+#define XDMAV3_IPXR_PD_MASK 0x00000010 /**< Pkt done */
+#define XDMAV3_IPXR_PCTR_MASK 0x00000008 /**< Pkt count threshold reached */
+#define XDMAV3_IPXR_PWBR_MASK 0x00000004 /**< Pkt waitbound reached */
+#define XDMAV3_IPXR_SGDA_MASK 0x00000002 /**< SG Disable ack */
+#define XDMAV3_IPXR_SGEND_MASK 0x00000001 /**< SG End */
+/*@}*/
+
+/** @name Software control register (SWCR) bitmasks
+ * @{
+ */
+#define XDMAV3_SWCR_SGE_MASK 0x80000000 /**< SG Enable */
+#define XDMAV3_SWCR_SGD_MASK 0x40000000 /**< SG Disable */
+#define XDMAV3_SWCR_DSGAR_MASK 0x20000000 /**< SG Disable auto-restart */
+#define XDMAV3_SWCR_PWB_MASK 0x00FFF000 /**< Pkt waitbound */
+#define XDMAV3_SWCR_PCT_MASK 0x00000FFF /**< Pkt threshold count */
+
+/* Left shift values for selected masks */
+#define XDMAV3_SWCR_PCT_SHIFT 0
+#define XDMAV3_SWCR_PWB_SHIFT 12
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/****************************************************************************/
+/**
+*
+* Read the given IPIF register.
+*
+* @param BaseAddress is the IPIF 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 XDmaV3_mReadReg(u32 BaseAddress, u32 RegOffset)
+*
+*****************************************************************************/
+#define XDmaV3_mReadReg(BaseAddress, RegOffset) \
+ XIo_In32((u32)(BaseAddress) + (u32)(RegOffset))
+
+
+/****************************************************************************/
+/**
+*
+* Write the given IPIF register.
+*
+* @param BaseAddress is the IPIF 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 XDmaV3_mWriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+*
+*****************************************************************************/
+#define XDmaV3_mWriteReg(BaseAddress, RegOffset, Data) \
+ XIo_Out32((u32)(BaseAddress) + (u32)(RegOffset), (u32)(Data))
+
+
+/****************************************************************************/
+/**
+*
+* 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 XDmaV3_mReadBd(u32 BaseAddress, u32 Offset)
+*
+*****************************************************************************/
+#define XDmaV3_mReadBd(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 XDmaV3_mWriteReg(u32 BaseAddress, u32 Offset, u32 Data)
+*
+*****************************************************************************/
+#define XDmaV3_mWriteBd(BaseAddress, Offset, Data) \
+ (*(u32*)((u32)(BaseAddress) + (u32)(Offset)) = (Data))
+
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xversion.h
@@ -52,8 +52,8 @@
*
******************************************************************************/
-#ifndef XVERSION_H /* prevent circular inclusions */
-#define XVERSION_H /* by using protection macros */
+#ifndef XVERSION_H /* prevent circular inclusions */
+#define XVERSION_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
@@ -72,28 +72,27 @@ extern "C" {
/* the following data type is used to hold a null terminated version string
* consisting of the following format, "X.YYX"
*/
-typedef Xint8 XVersion[6];
+typedef s8 XVersion[6];
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
-void XVersion_UnPack(XVersion *InstancePtr, Xuint16 PackedVersion);
+void XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion);
-XStatus XVersion_Pack(XVersion *InstancePtr, Xuint16 *PackedVersion);
+int XVersion_Pack(XVersion * InstancePtr, u16 *PackedVersion);
-Xboolean XVersion_IsEqual(XVersion *InstancePtr, XVersion *VersionPtr);
+u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr);
-void XVersion_ToString(XVersion *InstancePtr, Xint8 *StringPtr);
+void XVersion_ToString(XVersion * InstancePtr, s8 *StringPtr);
-XStatus XVersion_FromString(XVersion *InstancePtr, Xint8 *StringPtr);
+int XVersion_FromString(XVersion * InstancePtr, s8 *StringPtr);
-void XVersion_Copy(XVersion *InstancePtr, XVersion *VersionPtr);
+void XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr);
#ifdef __cplusplus
}
#endif
-#endif /* end of protection macro */
-
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.c.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.c
@@ -62,17 +62,17 @@
/************************** Function Prototypes ******************************/
-static XStatus Write32(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount);
+static int Write32(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount);
-static XStatus Write64(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount);
+static int Write64(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount);
-static XStatus Read32(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount);
+static int Read32(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount);
-static XStatus Read64(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount);
+static int Read64(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount);
/*****************************************************************************/
@@ -122,28 +122,28 @@ static XStatus Read64(Xuint32 RegBaseAdd
* from the FIFO.
*
******************************************************************************/
-XStatus XPacketFifoV200a_L0Read(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount)
+int XPacketFifoV200a_L0Read(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount)
{
- Xuint32 Width;
- XStatus Result = XST_FIFO_ERROR;
+ u32 Width;
+ int Result = XST_FIFO_ERROR;
- /* determine the width of the FIFO
- */
- Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
- XPF_V200A_FIFO_WIDTH_MASK;
-
- if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
- (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE))
- {
- Result = Read32(RegBaseAddress, DataBaseAddress, BufferPtr, ByteCount);
- }
- else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE)
- {
- Result = Read64(RegBaseAddress, DataBaseAddress, BufferPtr, ByteCount);
- }
+ /* determine the width of the FIFO
+ */
+ Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+ XPF_V200A_FIFO_WIDTH_MASK;
+
+ if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+ (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+ Result = Read32(RegBaseAddress, DataBaseAddress, BufferPtr,
+ ByteCount);
+ }
+ else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+ Result = Read64(RegBaseAddress, DataBaseAddress, BufferPtr,
+ ByteCount);
+ }
- return Result;
+ return Result;
}
@@ -182,31 +182,29 @@ XStatus XPacketFifoV200a_L0Read(Xuint32
* significant byte to the least significant byte.
*
******************************************************************************/
-XStatus XPacketFifoV200a_L0Write(Xuint32 RegBaseAddress,
- Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr,
- Xuint32 ByteCount)
+int XPacketFifoV200a_L0Write(u32 RegBaseAddress,
+ u32 DataBaseAddress, u8 *BufferPtr, u32 ByteCount)
{
- Xuint32 Width;
- XStatus Result = XST_FIFO_ERROR;
+ u32 Width;
+ int Result = XST_FIFO_ERROR;
- /* determine the width of the FIFO
- */
- Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
- XPF_V200A_FIFO_WIDTH_MASK;
-
- if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
- (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE))
- {
- Result = Write32(RegBaseAddress, DataBaseAddress, BufferPtr, ByteCount);
- }
- else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE)
- {
- Result = Write64(RegBaseAddress, DataBaseAddress, BufferPtr, ByteCount);
- }
+ /* determine the width of the FIFO
+ */
+ Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+ XPF_V200A_FIFO_WIDTH_MASK;
+
+ if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+ (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+ Result = Write32(RegBaseAddress, DataBaseAddress, BufferPtr,
+ ByteCount);
+ }
+ else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+ Result = Write64(RegBaseAddress, DataBaseAddress, BufferPtr,
+ ByteCount);
+ }
- return Result;
+ return Result;
}
@@ -243,69 +241,63 @@ XStatus XPacketFifoV200a_L0Write(Xuint32
* significant byte to the least significant byte.
*
******************************************************************************/
-XStatus XPacketFifoV200a_L0WriteDre(Xuint32 RegBaseAddress,
- Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr,
- Xuint32 ByteCount)
+int XPacketFifoV200a_L0WriteDre(u32 RegBaseAddress,
+ u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount)
{
- Xuint32 FifoRoomLeft;
- Xuint32 BytesLeft;
- Xuint32 Width;
-
- /* calculate how many slots are left in the FIFO
- */
- FifoRoomLeft = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET)
- & XPF_V200A_COUNT_MASK;
-
- /* determine the width of the FIFO
- */
- Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
- XPF_V200A_FIFO_WIDTH_MASK;
-
- /* from the width, determine how many bytes can be written to the FIFO
- */
- if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
- (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE))
- {
- FifoRoomLeft *= 4;
- }
- else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE)
- {
- FifoRoomLeft *= 8;
- }
-
- /* Make sure there's enough room in the FIFO */
- if (FifoRoomLeft < ByteCount)
- {
- return XST_PFIFO_NO_ROOM;
- }
-
- /* Determine the number of bytes to write until 32 bit alignment is
- * reached, then write those bytes to the FIFO one byte at a time
- */
- BytesLeft = (unsigned)BufferPtr % sizeof(Xuint32);
- ByteCount -= BytesLeft;
- while (BytesLeft--)
- {
- XIo_Out8(DataBaseAddress, *BufferPtr++);
- }
-
- /* Write as many 32 bit words as we can */
- BytesLeft = ByteCount;
- while (BytesLeft >= sizeof(Xuint32))
- {
- XIo_Out32(DataBaseAddress, *(Xuint32*)BufferPtr);
- BufferPtr += sizeof(Xuint32);
- BytesLeft -= sizeof(Xuint32);
- }
-
- /* Write remaining bytes */
- while (BytesLeft--)
- {
- XIo_Out8(DataBaseAddress, *BufferPtr++);
- }
+ u32 FifoRoomLeft;
+ u32 BytesLeft;
+ u32 Width;
+
+ /* calculate how many slots are left in the FIFO
+ */
+ FifoRoomLeft =
+ XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET)
+ & XPF_V200A_COUNT_MASK;
+
+ /* determine the width of the FIFO
+ */
+ Width = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+ XPF_V200A_FIFO_WIDTH_MASK;
+
+ /* from the width, determine how many bytes can be written to the FIFO
+ */
+ if ((Width == XPF_V200A_FIFO_WIDTH_LEGACY_TYPE) ||
+ (Width == XPF_V200A_FIFO_WIDTH_32BITS_TYPE)) {
+ FifoRoomLeft *= 4;
+ }
+ else if (Width == XPF_V200A_FIFO_WIDTH_64BITS_TYPE) {
+ FifoRoomLeft *= 8;
+ }
+
+ /* Make sure there's enough room in the FIFO */
+ if (FifoRoomLeft < ByteCount) {
+ return XST_PFIFO_NO_ROOM;
+ }
+
+ /* Determine the number of bytes to write until 32 bit alignment is
+ * reached, then write those bytes to the FIFO one byte at a time
+ */
+ BytesLeft = (unsigned) BufferPtr % sizeof(u32);
+ ByteCount -= BytesLeft;
+ while (BytesLeft--) {
+ XIo_Out8(DataBaseAddress, *BufferPtr++);
+ }
+
+ /* Write as many 32 bit words as we can */
+ BytesLeft = ByteCount;
+ while (BytesLeft >= sizeof(u32)) {
+ XIo_Out32(DataBaseAddress, *(u32 *) BufferPtr);
+ BufferPtr += sizeof(u32);
+ BytesLeft -= sizeof(u32);
+ }
+
+ /* Write remaining bytes */
+ while (BytesLeft--) {
+ XIo_Out8(DataBaseAddress, *BufferPtr++);
+ }
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
@@ -356,87 +348,83 @@ XStatus XPacketFifoV200a_L0WriteDre(Xuin
* from the FIFO.
*
******************************************************************************/
-static XStatus Read32(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount)
+static int Read32(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount)
{
- Xuint32 FifoCount;
- Xuint32 WordCount;
- Xuint32 ExtraByteCount;
- Xuint32 *WordBuffer = (Xuint32 *)BufferPtr;
-
- /* get the count of how many 32 bit words are in the FIFO, if there
- * aren't enough words to satisfy the request, return an error
- */
-
- FifoCount = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
- XPF_V200A_COUNT_MASK;
-
- if ((FifoCount * XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount)
- {
- return XST_PFIFO_LACK_OF_DATA;
- }
-
- /* calculate the number of words to read from the FIFO before the word
- * containing the extra bytes, and calculate the number of extra bytes
- * the extra bytes are defined as those at the end of the buffer when
- * the buffer does not end on a 32 bit boundary
- */
- WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
- ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
-
- /* Read the 32 bit words from the FIFO for all the buffer except the
- * last word which contains the extra bytes, the following code assumes
- * that the buffer is 32 bit aligned, otherwise an alignment exception
- * could be generated
- */
- for (FifoCount = 0; FifoCount < WordCount; FifoCount++)
- {
- WordBuffer[FifoCount] = XIo_In32(DataBaseAddress);
- }
-
- /* if there are extra bytes to handle, read the last word from the FIFO
- * and insert the extra bytes into the buffer
- */
- if (ExtraByteCount > 0)
- {
- Xuint32 LastWord;
- Xuint8 *WordPtr;
- Xuint8 *ExtraBytesBuffer = (Xuint8 *)(WordBuffer + WordCount);
-
- /* get the last word from the FIFO for the extra bytes */
-
- LastWord = XIo_In32(DataBaseAddress);
-
- /* one extra byte in the last word, put the byte into the next
- * location of the buffer, bytes in a word of the FIFO are ordered
- * from most significant byte to least
- */
- WordPtr = (Xuint8 *)&LastWord;
- if (ExtraByteCount == 1)
- {
- ExtraBytesBuffer[0] = WordPtr[0];
- }
-
- /* two extra bytes in the last word, put each byte into the next
- * two locations of the buffer
- */
- else if (ExtraByteCount == 2)
- {
- ExtraBytesBuffer[0] = WordPtr[0];
- ExtraBytesBuffer[1] = WordPtr[1];
- }
- /* three extra bytes in the last word, put each byte into the next
- * three locations of the buffer
- */
- else if (ExtraByteCount == 3)
- {
- ExtraBytesBuffer[0] = WordPtr[0];
- ExtraBytesBuffer[1] = WordPtr[1];
- ExtraBytesBuffer[2] = WordPtr[2];
- }
- }
+ u32 FifoCount;
+ u32 WordCount;
+ u32 ExtraByteCount;
+ u32 *WordBuffer = (u32 *) BufferPtr;
+
+ /* get the count of how many 32 bit words are in the FIFO, if there
+ * aren't enough words to satisfy the request, return an error
+ */
+
+ FifoCount =
+ XIo_In32(RegBaseAddress +
+ XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+ XPF_V200A_COUNT_MASK;
+
+ if ((FifoCount * XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
+ return XST_PFIFO_LACK_OF_DATA;
+ }
+
+ /* calculate the number of words to read from the FIFO before the word
+ * containing the extra bytes, and calculate the number of extra bytes
+ * the extra bytes are defined as those at the end of the buffer when
+ * the buffer does not end on a 32 bit boundary
+ */
+ WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+ ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+
+ /* Read the 32 bit words from the FIFO for all the buffer except the
+ * last word which contains the extra bytes, the following code assumes
+ * that the buffer is 32 bit aligned, otherwise an alignment exception
+ * could be generated
+ */
+ for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+ WordBuffer[FifoCount] = XIo_In32(DataBaseAddress);
+ }
+
+ /* if there are extra bytes to handle, read the last word from the FIFO
+ * and insert the extra bytes into the buffer
+ */
+ if (ExtraByteCount > 0) {
+ u32 LastWord;
+ u8 *WordPtr;
+ u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+ /* get the last word from the FIFO for the extra bytes */
+
+ LastWord = XIo_In32(DataBaseAddress);
+
+ /* one extra byte in the last word, put the byte into the next
+ * location of the buffer, bytes in a word of the FIFO are ordered
+ * from most significant byte to least
+ */
+ WordPtr = (u8 *) &LastWord;
+ if (ExtraByteCount == 1) {
+ ExtraBytesBuffer[0] = WordPtr[0];
+ }
+
+ /* two extra bytes in the last word, put each byte into the next
+ * two locations of the buffer
+ */
+ else if (ExtraByteCount == 2) {
+ ExtraBytesBuffer[0] = WordPtr[0];
+ ExtraBytesBuffer[1] = WordPtr[1];
+ }
+ /* three extra bytes in the last word, put each byte into the next
+ * three locations of the buffer
+ */
+ else if (ExtraByteCount == 3) {
+ ExtraBytesBuffer[0] = WordPtr[0];
+ ExtraBytesBuffer[1] = WordPtr[1];
+ ExtraBytesBuffer[2] = WordPtr[2];
+ }
+ }
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
@@ -487,110 +475,102 @@ static XStatus Read32(Xuint32 RegBaseAdd
* from the FIFO.
*
******************************************************************************/
-static XStatus Read64(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount)
+static int Read64(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount)
{
- Xuint32 FifoCount;
- Xuint32 WordCount;
- Xuint32 ExtraByteCount;
- Xuint32 *WordBuffer = (Xuint32 *)BufferPtr;
-
- /* get the count of how many 64 bit words are in the FIFO, if there
- * aren't enough words to satisfy the request, return an error
- */
-
- FifoCount = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
- XPF_V200A_COUNT_MASK;
-
- if ((FifoCount * XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount)
- {
- return XST_PFIFO_LACK_OF_DATA;
- }
-
- /* calculate the number of words to read from the FIFO before the word
- * containing the extra bytes, and calculate the number of extra bytes
- * the extra bytes are defined as those at the end of the buffer when
- * the buffer does not end on a 32 bit boundary
- */
- WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
- ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
-
- /* Read the 64 bit words from the FIFO for all the buffer except the
- * last word which contains the extra bytes, the following code assumes
- * that the buffer is 32 bit aligned, otherwise an alignment exception
- * could be generated. The MSWord must be read first followed by the
- * LSWord
- */
- for (FifoCount = 0; FifoCount < WordCount; FifoCount++)
- {
- WordBuffer[(FifoCount * 2)] =
- XIo_In32(DataBaseAddress);
- WordBuffer[(FifoCount * 2) + 1] =
- XIo_In32(DataBaseAddress + 4);
- }
-
- /* if there are extra bytes to handle, read the last word from the FIFO
- * and insert the extra bytes into the buffer
- */
- if (ExtraByteCount > 0)
- {
- Xuint32 MSLastWord;
- Xuint32 LSLastWord;
- Xuint8 *WordPtr;
- Xuint8 *ExtraBytesBuffer =
- (Xuint8 *)(WordBuffer + (WordCount * 2));
- Xuint8 Index = 0;
-
- /* get the last word from the FIFO for the extra bytes */
-
- MSLastWord = XIo_In32(DataBaseAddress);
- LSLastWord = XIo_In32(DataBaseAddress + 4);
-
- /* four or more extra bytes in the last word, put the byte into
- * the next location of the buffer, bytes in a word of the FIFO
- * are ordered from most significant byte to least
- */
- WordPtr = (Xuint8 *)&MSLastWord;
- if (ExtraByteCount >= 4)
- {
- ExtraBytesBuffer[Index] = WordPtr[0];
- ExtraBytesBuffer[Index + 1] = WordPtr[1];
- ExtraBytesBuffer[Index + 2] = WordPtr[2];
- ExtraBytesBuffer[Index + 3] = WordPtr[3];
- ExtraByteCount = ExtraByteCount - 4;
- MSLastWord = LSLastWord;
- Index = 4;
- }
-
- /* one extra byte in the last word, put the byte into the next
- * location of the buffer, bytes in a word of the FIFO are
- * ordered from most significant byte to least
- */
- if (ExtraByteCount == 1)
- {
- ExtraBytesBuffer[Index] = WordPtr[0];
- }
-
- /* two extra bytes in the last word, put each byte into the next
- * two locations of the buffer
- */
- else if (ExtraByteCount == 2)
- {
- ExtraBytesBuffer[Index] = WordPtr[0];
- ExtraBytesBuffer[Index + 1] = WordPtr[1];
- }
- /* three extra bytes in the last word, put each byte into the next
- * three locations of the buffer
- */
- else if (ExtraByteCount == 3)
- {
- ExtraBytesBuffer[Index] = WordPtr[0];
- ExtraBytesBuffer[Index + 1] = WordPtr[1];
- ExtraBytesBuffer[Index + 2] = WordPtr[2];
- }
- }
+ u32 FifoCount;
+ u32 WordCount;
+ u32 ExtraByteCount;
+ u32 *WordBuffer = (u32 *) BufferPtr;
+
+ /* get the count of how many 64 bit words are in the FIFO, if there
+ * aren't enough words to satisfy the request, return an error
+ */
+
+ FifoCount =
+ XIo_In32(RegBaseAddress +
+ XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+ XPF_V200A_COUNT_MASK;
+
+ if ((FifoCount * XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT) < ByteCount) {
+ return XST_PFIFO_LACK_OF_DATA;
+ }
+
+ /* calculate the number of words to read from the FIFO before the word
+ * containing the extra bytes, and calculate the number of extra bytes
+ * the extra bytes are defined as those at the end of the buffer when
+ * the buffer does not end on a 32 bit boundary
+ */
+ WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+ ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+
+ /* Read the 64 bit words from the FIFO for all the buffer except the
+ * last word which contains the extra bytes, the following code assumes
+ * that the buffer is 32 bit aligned, otherwise an alignment exception
+ * could be generated. The MSWord must be read first followed by the
+ * LSWord
+ */
+ for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+ WordBuffer[(FifoCount * 2)] = XIo_In32(DataBaseAddress);
+ WordBuffer[(FifoCount * 2) + 1] = XIo_In32(DataBaseAddress + 4);
+ }
+
+ /* if there are extra bytes to handle, read the last word from the FIFO
+ * and insert the extra bytes into the buffer
+ */
+ if (ExtraByteCount > 0) {
+ u32 MSLastWord;
+ u32 LSLastWord;
+ u8 *WordPtr;
+ u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + (WordCount * 2));
+ u8 Index = 0;
+
+ /* get the last word from the FIFO for the extra bytes */
+
+ MSLastWord = XIo_In32(DataBaseAddress);
+ LSLastWord = XIo_In32(DataBaseAddress + 4);
+
+ /* four or more extra bytes in the last word, put the byte into
+ * the next location of the buffer, bytes in a word of the FIFO
+ * are ordered from most significant byte to least
+ */
+ WordPtr = (u8 *) &MSLastWord;
+ if (ExtraByteCount >= 4) {
+ ExtraBytesBuffer[Index] = WordPtr[0];
+ ExtraBytesBuffer[Index + 1] = WordPtr[1];
+ ExtraBytesBuffer[Index + 2] = WordPtr[2];
+ ExtraBytesBuffer[Index + 3] = WordPtr[3];
+ ExtraByteCount = ExtraByteCount - 4;
+ MSLastWord = LSLastWord;
+ Index = 4;
+ }
+
+ /* one extra byte in the last word, put the byte into the next
+ * location of the buffer, bytes in a word of the FIFO are
+ * ordered from most significant byte to least
+ */
+ if (ExtraByteCount == 1) {
+ ExtraBytesBuffer[Index] = WordPtr[0];
+ }
+
+ /* two extra bytes in the last word, put each byte into the next
+ * two locations of the buffer
+ */
+ else if (ExtraByteCount == 2) {
+ ExtraBytesBuffer[Index] = WordPtr[0];
+ ExtraBytesBuffer[Index + 1] = WordPtr[1];
+ }
+ /* three extra bytes in the last word, put each byte into the next
+ * three locations of the buffer
+ */
+ else if (ExtraByteCount == 3) {
+ ExtraBytesBuffer[Index] = WordPtr[0];
+ ExtraBytesBuffer[Index + 1] = WordPtr[1];
+ ExtraBytesBuffer[Index + 2] = WordPtr[2];
+ }
+ }
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
@@ -628,104 +608,98 @@ static XStatus Read64(Xuint32 RegBaseAdd
* significant byte to the least significant byte.
*
******************************************************************************/
-static XStatus Write32(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount)
+static int Write32(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount)
{
- Xuint32 FifoCount;
- Xuint32 WordCount;
- Xuint32 ExtraByteCount;
- Xuint32 *WordBuffer = (Xuint32 *)BufferPtr;
-
- /* get the count of how many words may be inserted into the FIFO */
-
- FifoCount = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
- XPF_V200A_COUNT_MASK;
-
- /* Calculate the number of 32 bit words required to insert the
- * specified number of bytes in the FIFO and determine the number
- * of extra bytes if the buffer length is not a multiple of 32 bit
- * words
- */
-
- WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
- ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
-
- /* take into account the extra bytes in the total word count */
-
- if (ExtraByteCount > 0)
- {
- WordCount++;
- }
-
- /* if there's not enough room in the FIFO to hold the specified
- * number of bytes, then indicate an error,
- */
- if (FifoCount < WordCount)
- {
- return XST_PFIFO_NO_ROOM;
- }
-
- /* readjust the word count to not take into account the extra bytes */
-
- if (ExtraByteCount > 0)
- {
- WordCount--;
- }
-
- /* Write all the bytes of the buffer which can be written as 32 bit
- * words into the FIFO, waiting to handle the extra bytes separately
- */
- for (FifoCount = 0; FifoCount < WordCount; FifoCount++)
- {
- XIo_Out32(DataBaseAddress, WordBuffer[FifoCount]);
- }
-
- /* if there are extra bytes to handle, extract them from the buffer
- * and create a 32 bit word and write it to the FIFO
- */
- if (ExtraByteCount > 0)
- {
- Xuint32 LastWord = 0;
- Xuint8 *WordPtr;
- Xuint8 *ExtraBytesBuffer = (Xuint8 *)(WordBuffer + WordCount);
-
- /* one extra byte in the buffer, put the byte into the last word
- * to be inserted into the FIFO, perform this processing inline
- * rather than in a loop to help performance
- */
- WordPtr = (Xuint8 *)&LastWord;
- if (ExtraByteCount == 1)
- {
- WordPtr[0] = ExtraBytesBuffer[0];
- }
-
- /* two extra bytes in the buffer, put each byte into the last word
- * to be inserted into the FIFO
- */
- else if (ExtraByteCount == 2)
- {
- WordPtr[0] = ExtraBytesBuffer[0];
- WordPtr[1] = ExtraBytesBuffer[1];
- }
-
- /* three extra bytes in the buffer, put each byte into the last
- * word to be inserted into the FIFO
- */
- else if (ExtraByteCount == 3)
- {
- WordPtr[0] = ExtraBytesBuffer[0];
- WordPtr[1] = ExtraBytesBuffer[1];
- WordPtr[2] = ExtraBytesBuffer[2];
- }
-
- /* write the last 32 bit word to the FIFO and return with
- * no errors
- */
+ u32 FifoCount;
+ u32 WordCount;
+ u32 ExtraByteCount;
+ u32 *WordBuffer = (u32 *) BufferPtr;
+
+ /* get the count of how many words may be inserted into the FIFO */
+
+ FifoCount =
+ XIo_In32(RegBaseAddress +
+ XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+ XPF_V200A_COUNT_MASK;
+
+ /* Calculate the number of 32 bit words required to insert the
+ * specified number of bytes in the FIFO and determine the number
+ * of extra bytes if the buffer length is not a multiple of 32 bit
+ * words
+ */
+
+ WordCount = ByteCount / XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+ ExtraByteCount = ByteCount % XPF_V200A_32BIT_FIFO_WIDTH_BYTE_COUNT;
+
+ /* take into account the extra bytes in the total word count */
+
+ if (ExtraByteCount > 0) {
+ WordCount++;
+ }
+
+ /* if there's not enough room in the FIFO to hold the specified
+ * number of bytes, then indicate an error,
+ */
+ if (FifoCount < WordCount) {
+ return XST_PFIFO_NO_ROOM;
+ }
+
+ /* readjust the word count to not take into account the extra bytes */
+
+ if (ExtraByteCount > 0) {
+ WordCount--;
+ }
+
+ /* Write all the bytes of the buffer which can be written as 32 bit
+ * words into the FIFO, waiting to handle the extra bytes separately
+ */
+ for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+ XIo_Out32(DataBaseAddress, WordBuffer[FifoCount]);
+ }
+
+ /* if there are extra bytes to handle, extract them from the buffer
+ * and create a 32 bit word and write it to the FIFO
+ */
+ if (ExtraByteCount > 0) {
+ u32 LastWord = 0;
+ u8 *WordPtr;
+ u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount);
+
+ /* one extra byte in the buffer, put the byte into the last word
+ * to be inserted into the FIFO, perform this processing inline
+ * rather than in a loop to help performance
+ */
+ WordPtr = (u8 *) &LastWord;
+ if (ExtraByteCount == 1) {
+ WordPtr[0] = ExtraBytesBuffer[0];
+ }
+
+ /* two extra bytes in the buffer, put each byte into the last word
+ * to be inserted into the FIFO
+ */
+ else if (ExtraByteCount == 2) {
+ WordPtr[0] = ExtraBytesBuffer[0];
+ WordPtr[1] = ExtraBytesBuffer[1];
+ }
+
+ /* three extra bytes in the buffer, put each byte into the last
+ * word to be inserted into the FIFO
+ */
+ else if (ExtraByteCount == 3) {
+ WordPtr[0] = ExtraBytesBuffer[0];
+ WordPtr[1] = ExtraBytesBuffer[1];
+ WordPtr[2] = ExtraBytesBuffer[2];
+ }
+
+ /* write the last 32 bit word to the FIFO and return with
+ * no errors
+ */
- XIo_Out32(DataBaseAddress, LastWord);
- }
+ XIo_Out32(DataBaseAddress, LastWord);
+ }
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
/*****************************************************************************/
@@ -763,123 +737,116 @@ static XStatus Write32(Xuint32 RegBaseAd
* significant byte to the least significant byte.
*
******************************************************************************/
-static XStatus Write64(Xuint32 RegBaseAddress, Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr, Xuint32 ByteCount)
+static int Write64(u32 RegBaseAddress, u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount)
{
- Xuint32 FifoCount;
- Xuint32 WordCount;
- Xuint32 ExtraByteCount;
- Xuint32 *WordBuffer = (Xuint32 *)BufferPtr;
-
- /* get the count of how many words may be inserted into the FIFO */
-
- FifoCount = XIo_In32(RegBaseAddress + XPF_V200A_COUNT_STATUS_REG_OFFSET) &
- XPF_V200A_COUNT_MASK;
-
- /* Calculate the number of 64 bit words required to insert the
- * specified number of bytes in the FIFO and determine the number
- * of extra bytes if the buffer length is not a multiple of 64 bit
- * words
- */
-
- WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
- ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
-
- /* take into account the extra bytes in the total word count */
-
- if (ExtraByteCount > 0)
- {
- WordCount++;
- }
-
- /* if there's not enough room in the FIFO to hold the specified
- * number of bytes, then indicate an error,
- */
- if (FifoCount < WordCount)
- {
- return XST_PFIFO_NO_ROOM;
- }
-
- /* readjust the word count to not take into account the extra bytes */
-
- if (ExtraByteCount > 0)
- {
- WordCount--;
- }
-
- /* Write all the bytes of the buffer which can be written as 32 bit
- * words into the FIFO, waiting to handle the extra bytes separately
- * The MSWord must be written first followed by the LSWord
- */
- for (FifoCount = 0; FifoCount < WordCount; FifoCount++)
- {
- XIo_Out32(DataBaseAddress, WordBuffer[(FifoCount * 2)]);
- XIo_Out32(DataBaseAddress + 4, WordBuffer[(FifoCount * 2) + 1]);
- }
-
- /* if there are extra bytes to handle, extract them from the buffer
- * and create two 32 bit words and write to the FIFO
- */
- if (ExtraByteCount > 0)
- {
-
- Xuint32 MSLastWord = 0;
- Xuint32 LSLastWord = 0;
- Xuint8 Index = 0;
- Xuint8 *WordPtr;
- Xuint8 *ExtraBytesBuffer = (Xuint8 *)(WordBuffer + (WordCount * 2));
-
- /* four extra bytes in the buffer, put the bytes into the last word
- * to be inserted into the FIFO, perform this processing inline
- * rather than in a loop to help performance
- */
- WordPtr = (Xuint8 *)&MSLastWord;
-
- if (ExtraByteCount >= 4)
- {
- WordPtr[0] = ExtraBytesBuffer[Index];
- WordPtr[1] = ExtraBytesBuffer[Index + 1];
- WordPtr[2] = ExtraBytesBuffer[Index + 2];
- WordPtr[3] = ExtraBytesBuffer[Index + 3];
- ExtraByteCount = ExtraByteCount - 4;
- WordPtr = (Xuint8 *)&LSLastWord;
- Index = 4;
- }
-
- /* one extra byte in the buffer, put the byte into the last word
- * to be inserted into the FIFO, perform this processing inline
- * rather than in a loop to help performance
- */
- if (ExtraByteCount == 1)
- {
- WordPtr[0] = ExtraBytesBuffer[Index];
- }
-
- /* two extra bytes in the buffer, put each byte into the last word
- * to be inserted into the FIFO
- */
- else if (ExtraByteCount == 2)
- {
- WordPtr[0] = ExtraBytesBuffer[Index];
- WordPtr[1] = ExtraBytesBuffer[Index + 1];
- }
-
- /* three extra bytes in the buffer, put each byte into the last
- * word to be inserted into the FIFO
- */
- else if (ExtraByteCount == 3)
- {
- WordPtr[0] = ExtraBytesBuffer[Index];
- WordPtr[1] = ExtraBytesBuffer[Index + 1];
- WordPtr[2] = ExtraBytesBuffer[Index + 2];
- }
-
- /* write the last 64 bit word to the FIFO and return with no errors
- * The MSWord must be written first followed by the LSWord
- */
- XIo_Out32(DataBaseAddress, MSLastWord);
- XIo_Out32(DataBaseAddress + 4, LSLastWord);
- }
+ u32 FifoCount;
+ u32 WordCount;
+ u32 ExtraByteCount;
+ u32 *WordBuffer = (u32 *) BufferPtr;
+
+ /* get the count of how many words may be inserted into the FIFO */
+
+ FifoCount =
+ XIo_In32(RegBaseAddress +
+ XPF_V200A_COUNT_STATUS_REG_OFFSET) &
+ XPF_V200A_COUNT_MASK;
+
+ /* Calculate the number of 64 bit words required to insert the
+ * specified number of bytes in the FIFO and determine the number
+ * of extra bytes if the buffer length is not a multiple of 64 bit
+ * words
+ */
+
+ WordCount = ByteCount / XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+ ExtraByteCount = ByteCount % XPF_V200A_64BIT_FIFO_WIDTH_BYTE_COUNT;
+
+ /* take into account the extra bytes in the total word count */
+
+ if (ExtraByteCount > 0) {
+ WordCount++;
+ }
+
+ /* if there's not enough room in the FIFO to hold the specified
+ * number of bytes, then indicate an error,
+ */
+ if (FifoCount < WordCount) {
+ return XST_PFIFO_NO_ROOM;
+ }
+
+ /* readjust the word count to not take into account the extra bytes */
+
+ if (ExtraByteCount > 0) {
+ WordCount--;
+ }
+
+ /* Write all the bytes of the buffer which can be written as 32 bit
+ * words into the FIFO, waiting to handle the extra bytes separately
+ * The MSWord must be written first followed by the LSWord
+ */
+ for (FifoCount = 0; FifoCount < WordCount; FifoCount++) {
+ XIo_Out32(DataBaseAddress, WordBuffer[(FifoCount * 2)]);
+ XIo_Out32(DataBaseAddress + 4, WordBuffer[(FifoCount * 2) + 1]);
+ }
+
+ /* if there are extra bytes to handle, extract them from the buffer
+ * and create two 32 bit words and write to the FIFO
+ */
+ if (ExtraByteCount > 0) {
+
+ u32 MSLastWord = 0;
+ u32 LSLastWord = 0;
+ u8 Index = 0;
+ u8 *WordPtr;
+ u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + (WordCount * 2));
+
+ /* four extra bytes in the buffer, put the bytes into the last word
+ * to be inserted into the FIFO, perform this processing inline
+ * rather than in a loop to help performance
+ */
+ WordPtr = (u8 *) &MSLastWord;
+
+ if (ExtraByteCount >= 4) {
+ WordPtr[0] = ExtraBytesBuffer[Index];
+ WordPtr[1] = ExtraBytesBuffer[Index + 1];
+ WordPtr[2] = ExtraBytesBuffer[Index + 2];
+ WordPtr[3] = ExtraBytesBuffer[Index + 3];
+ ExtraByteCount = ExtraByteCount - 4;
+ WordPtr = (u8 *) &LSLastWord;
+ Index = 4;
+ }
+
+ /* one extra byte in the buffer, put the byte into the last word
+ * to be inserted into the FIFO, perform this processing inline
+ * rather than in a loop to help performance
+ */
+ if (ExtraByteCount == 1) {
+ WordPtr[0] = ExtraBytesBuffer[Index];
+ }
+
+ /* two extra bytes in the buffer, put each byte into the last word
+ * to be inserted into the FIFO
+ */
+ else if (ExtraByteCount == 2) {
+ WordPtr[0] = ExtraBytesBuffer[Index];
+ WordPtr[1] = ExtraBytesBuffer[Index + 1];
+ }
+
+ /* three extra bytes in the buffer, put each byte into the last
+ * word to be inserted into the FIFO
+ */
+ else if (ExtraByteCount == 3) {
+ WordPtr[0] = ExtraBytesBuffer[Index];
+ WordPtr[1] = ExtraBytesBuffer[Index + 1];
+ WordPtr[2] = ExtraBytesBuffer[Index + 2];
+ }
+
+ /* write the last 64 bit word to the FIFO and return with no errors
+ * The MSWord must be written first followed by the LSWord
+ */
+ XIo_Out32(DataBaseAddress, MSLastWord);
+ XIo_Out32(DataBaseAddress + 4, LSLastWord);
+ }
- return XST_SUCCESS;
+ return XST_SUCCESS;
}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_hw.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma_hw.h
@@ -0,0 +1,373 @@
+/* $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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+*
+* @file xlldma_hw.h
+*
+* This header file contains identifiers and register-level driver functions (or
+* macros) that can be used to access the Local-Link Scatter-gather Direct
+* Memory Access Gather (LLDMA) device.
+*
+* For more information about the operation of this device, see the hardware
+* specification and documentation in the higher level driver xlldma.h source
+* code file.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a xd 12/21/06 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_HW_H /* prevent circular inclusions */
+#define XLLDMA_HW_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/** @name Device Bus Type definition
+ * The constant XPAR_XLLDMA_USE_DCR is used to inform this driver the type of
+ * the BUS the DMA device is on. If the DMA core is on DCR BUS,
+ * XPAR_XLLDMA_USE_DCR must be defined as a compiler option used in the
+ * Makefile BEFORE this driver is compiled; Otherwise, the constant must not be
+ * defined.
+ * @{
+ */
+#ifdef XPAR_XLLDMA_USE_DCR
+#include "xio_dcr.h"
+#else
+#include "xio.h"
+#endif
+/*@}*/
+
+/************************** Constant Definitions *****************************/
+
+/** @name Buffer Descriptor Alignment
+ * @{
+ */
+#define XLLDMA_BD_MINIMUM_ALIGNMENT 0x40 /**< Minimum byte alignment
+ requirement for descriptors to
+ satisfy both hardware/software
+ needs */
+/*@}*/
+
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+#ifdef XPAR_XLLDMA_USE_DCR
+
+/* DMA core is on DCR BUS */
+
+/** @name Device registers for DCR based systems.
+ * Offsets defined in DCR address space. TX and RX channels consist of
+ * identical registers
+ * @{
+ */
+#define XLLDMA_TX_OFFSET 0x00000000 /**< TX channel registers base
+ offset [0..7] */
+#define XLLDMA_RX_OFFSET 0x00000008 /**< RX channel registers base
+ offset [8..F] */
+#define XLLDMA_DMACR_OFFSET 0x00000010 /**< DMA control register */
+
+/* This set of registers are applicable for both channels. Add
+ * XLLDMA_TX_OFFSET to get to TX channel, and XLLDMA_RX_OFFSET to get to RX
+ * channel
+ */
+#define XLLDMA_NDESC_OFFSET 0x00000000 /**< Next descriptor pointer */
+#define XLLDMA_BUFA_OFFSET 0x00000001 /**< Current buffer address */
+#define XLLDMA_BUFL_OFFSET 0x00000002 /**< Current buffer length */
+#define XLLDMA_CDESC_OFFSET 0x00000003 /**< Current descriptor pointer */
+#define XLLDMA_TDESC_OFFSET 0x00000004 /**< Tail descriptor pointer */
+#define XLLDMA_CR_OFFSET 0x00000005 /**< Channel control */
+#define XLLDMA_IRQ_OFFSET 0x00000006 /**< Interrupt register */
+#define XLLDMA_SR_OFFSET 0x00000007 /**< Status */
+/*@}*/
+
+#else /* Non-DCR interface is used */
+
+/** @name Device registers for Non-DCR based systems.
+ * Offsets defined in Non-DCR address space. TX and RX channels consist of
+ * identical registers
+ * @{
+ */
+#define XLLDMA_TX_OFFSET 0x00000000 /**< TX channel registers base
+ offset */
+#define XLLDMA_RX_OFFSET 0x00000020 /**< RX channel registers base
+ offset */
+#define XLLDMA_DMACR_OFFSET 0x00000040 /**< DMA control register */
+
+/* This set of registers are applicable for both channels. Add
+ * XLLDMA_TX_OFFSET to get to TX channel, and XLLDMA_RX_OFFSET to get to RX
+ * channel
+ */
+#define XLLDMA_NDESC_OFFSET 0x00000000 /**< Next descriptor pointer */
+#define XLLDMA_BUFA_OFFSET 0x00000004 /**< Current buffer address */
+#define XLLDMA_BUFL_OFFSET 0x00000008 /**< Current buffer length */
+#define XLLDMA_CDESC_OFFSET 0x0000000C /**< Current descriptor pointer */
+#define XLLDMA_TDESC_OFFSET 0x00000010 /**< Tail descriptor pointer */
+#define XLLDMA_CR_OFFSET 0x00000014 /**< Channel control */
+#define XLLDMA_IRQ_OFFSET 0x00000018 /**< Interrupt register */
+#define XLLDMA_SR_OFFSET 0x0000001C /**< Status */
+
+/*@}*/
+
+#endif /* #ifdef XPAR_XLLDMA_USE_DCR */
+
+/** @name Buffer Descriptor register offsets
+ * USR fields are defined by higher level IP. For example, checksum offload
+ * setup for EMAC type devices. The 1st 8 words are utilized by hardware. Any
+ * words after the 8th are for software use only.
+ * @{
+ */
+#define XLLDMA_BD_NDESC_OFFSET 0x00 /**< Next descriptor pointer */
+#define XLLDMA_BD_BUFA_OFFSET 0x04 /**< Buffer address */
+#define XLLDMA_BD_BUFL_OFFSET 0x08 /**< Buffer length */
+#define XLLDMA_BD_STSCTRL_USR0_OFFSET 0x0C /**< Status and Control and
+ hardware implementation
+ specific */
+#define XLLDMA_BD_USR1_OFFSET 0x10 /**< Hardware implementation
+ specific */
+#define XLLDMA_BD_USR2_OFFSET 0x14 /**< Hardware implementation
+ specific */
+#define XLLDMA_BD_USR3_OFFSET 0x18 /**< Hardware implementation
+ specific */
+#define XLLDMA_BD_USR4_OFFSET 0x1C /**< Hardware implementation
+ specific */
+#define XLLDMA_BD_ID_OFFSET 0x20 /**< Software application use */
+
+#define XLLDMA_BD_NUM_WORDS 9 /**< Number of 32-bit words that
+ make up a full BD */
+#define XLLDMA_BD_HW_NUM_WORDS 8 /**< Number of 32-bit words that
+ make up the hardware
+ accessible portion of a BD */
+#define XLLDMA_BD_HW_NUM_BYTES 32 /**< Number of bytes that make up
+ the hardware accessible
+ portion of a BD */
+/*@}*/
+
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the hardware
+ * spec.
+ */
+
+
+/** @name Bitmasks of XLLDMA_TX_CR_OFFSET and XLLDMA_RX_CR_OFFSET registers
+ * @{
+ */
+#define XLLDMA_CR_IRQ_TIMEOUT_MASK 0xFF000000 /**< Interrupt coalesce
+ waitbound timeout */
+#define XLLDMA_CR_IRQ_COUNT_MASK 0x00FF0000 /**< Interrupt coalesce
+ count threshold */
+#define XLLDMA_CR_MSB_ADDR_MASK 0x0000F000 /**< MSB address of DMA
+ buffers and descriptors
+ for 36 bit
+ addressing */
+#define XLLDMA_CR_APP_EN_MASK 0x00000800 /**< Application data mask
+ enable */
+#define XLLDMA_CR_USE_1_BIT_CNT_MASK 0x00000400 /**< Turn 4 and 2 bit
+ interrupt counters into
+ 1 bit counters */
+#define XLLDMA_CR_USE_INT_ON_END_MASK 0x00000200 /**< Use interrupt-on-end */
+#define XLLDMA_CR_LD_IRQ_CNT_MASK 0x00000100 /**< Load IRQ_COUNT */
+#define XLLDMA_CR_IRQ_EN_MASK 0x00000080 /**< Master interrupt
+ enable */
+#define XLLDMA_CR_IRQ_ERROR_EN_MASK 0x00000004 /**< Enable error
+ interrupt */
+#define XLLDMA_CR_IRQ_DELAY_EN_MASK 0x00000002 /**< Enable coalesce delay
+ interrupt */
+#define XLLDMA_CR_IRQ_COALESCE_EN_MASK 0x00000001 /**< Enable coalesce count
+ interrupt */
+#define XLLDMA_CR_IRQ_ALL_EN_MASK 0x00000087 /**< All interrupt enable
+ bits */
+
+/* Shift constants for selected masks */
+#define XLLDMA_CR_IRQ_TIMEOUT_SHIFT 24
+#define XLLDMA_CR_IRQ_COUNT_SHIFT 16
+#define XLLDMA_CR_MSB_ADDR_SHIFT 12
+
+/*@}*/
+
+
+/** @name Bitmasks of XLLDMA_TX_IRQ_OFFSET & XLLDMA_RX_IRQ_OFFSET registers
+ * @{
+ */
+#define XLLDMA_IRQ_WRQ_EMPTY_MASK 0x00004000 /**< Write Command Queue
+ Empty -- RX channel
+ Only */
+#define XLLDMA_IRQ_COALESCE_COUNTER_MASK 0x00003C00 /**< Coalesce IRQ 4 bit
+ counter */
+#define XLLDMA_IRQ_DELAY_COUNTER_MASK 0x00000300 /**< Coalesce delay IRQ 2
+ bit counter */
+#define XLLDMA_IRQ_PLB_RD_ERROR_MASK 0x00000010 /**< PLB Read Error IRQ */
+#define XLLDMA_IRQ_PLB_WR_ERROR_MASK 0x00000008 /**< PLB Write Error IRQ */
+#define XLLDMA_IRQ_ERROR_MASK 0x00000004 /**< Error IRQ */
+#define XLLDMA_IRQ_DELAY_MASK 0x00000002 /**< Coalesce delay IRQ */
+#define XLLDMA_IRQ_COALESCE_MASK 0x00000001 /**< Coalesce threshold
+ IRQ */
+#define XLLDMA_IRQ_ALL_ERR_MASK 0x0000001C /**< All error interrupt */
+#define XLLDMA_IRQ_ALL_MASK 0x0000001F /**< All interrupt bits */
+
+/* Shift constants for selected masks */
+#define XLLDMA_IRQ_COALESCE_COUNTER_SHIFT 10
+#define XLLDMA_IRQ_DELAY_COUNTER_SHIFT 8
+
+/*@}*/
+
+
+/** @name Bitmasks of XLLDMA_TX_SR_OFFSET and XLLDMA_RX_SR_OFFSET registers
+ * @{
+ */
+#define XLLDMA_SR_IRQ_ON_END_MASK 0x00000040 /**< IRQ on end has occurred */
+#define XLLDMA_SR_STOP_ON_END_MASK 0x00000020 /**< Stop on end has occurred */
+#define XLLDMA_SR_COMPLETED_MASK 0x00000010 /**< BD completed */
+#define XLLDMA_SR_SOP_MASK 0x00000008 /**< Current BD has SOP set */
+#define XLLDMA_SR_EOP_MASK 0x00000004 /**< Current BD has EOP set */
+#define XLLDMA_SR_ENGINE_BUSY_MASK 0x00000002 /**< Channel is busy */
+/*@}*/
+
+
+/** @name Bitmasks associated with XLLDMA_DMACR_OFFSET register
+ * @{
+ */
+#define XLLDMA_DMACR_TX_PAUSE_MASK 0x20000000 /**< Pause TX channel
+ */
+#define XLLDMA_DMACR_RX_PAUSE_MASK 0x10000000 /**< Pause RX channel
+ */
+#define XLLDMA_DMACR_PLB_ERR_DIS_MASK 0x00000020 /**< Disable PLB
+ error detection
+ */
+#define XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK 0x00000010 /**< Disable error
+ when 2 or 4 bit
+ coalesce counter
+ overflows */
+#define XLLDMA_DMACR_TX_OVERFLOW_ERR_DIS_MASK 0x00000008 /**< Disable error
+ when 2 or 4 bit
+ coalesce counter
+ overflows */
+#define XLLDMA_DMACR_TAIL_PTR_EN_MASK 0x00000004 /**< Enable use of
+ tail pointer
+ register */
+#define XLLDMA_DMACR_EN_ARB_HOLD_MASK 0x00000002 /**< Enable
+ arbitration
+ hold */
+#define XLLDMA_DMACR_SW_RESET_MASK 0x00000001 /**< Assert Software
+ reset for both
+ channels */
+/*@}*/
+
+
+/** @name Bitmasks of XLLDMA_BD_STSCTRL_USR0_OFFSET descriptor word
+ * @{
+ */
+#define XLLDMA_BD_STSCTRL_ERROR_MASK 0x80000000 /**< DMA error */
+#define XLLDMA_BD_STSCTRL_IOE_MASK 0x40000000 /**< Interrupt on end */
+#define XLLDMA_BD_STSCTRL_SOE_MASK 0x20000000 /**< Stop on end */
+#define XLLDMA_BD_STSCTRL_COMPLETED_MASK 0x10000000 /**< DMA completed */
+#define XLLDMA_BD_STSCTRL_SOP_MASK 0x08000000 /**< Start of packet */
+#define XLLDMA_BD_STSCTRL_EOP_MASK 0x04000000 /**< End of packet */
+#define XLLDMA_BD_STSCTRL_BUSY_MASK 0x02000000 /**< DMA channel busy */
+
+#define XLLDMA_BD_STSCTRL_MASK 0xFF000000 /**< Status/Control field
+ */
+#define XLLDMA_BD_STSCTRL_USR0_MASK 0x00FFFFFF /**< User field #0 */
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+#ifdef XPAR_XLLDMA_USE_DCR
+
+/* DCR interface is used */
+
+#define XLlDma_In32 XIo_DcrIn
+#define XLlDma_Out32 XIo_DcrOut
+
+#else
+
+/* Non-DCR interface is used */
+
+#define XLlDma_In32 XIo_In32
+#define XLlDma_Out32 XIo_Out32
+
+#endif
+
+/*****************************************************************************/
+/**
+*
+* 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 XLlDma_mReadReg(u32 BaseAddress, u32 RegOffset)
+*
+******************************************************************************/
+#define XLlDma_mReadReg(BaseAddress, RegOffset) \
+ XLlDma_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 XLlDma_mWriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+*
+******************************************************************************/
+#define XLlDma_mWriteReg(BaseAddress, RegOffset, Data) \
+ XLlDma_Out32((BaseAddress) + (RegOffset), (Data))
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma.h
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xlldma.h
@@ -0,0 +1,571 @@
+/* $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 2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xlldma.h
+*
+* The Xilinx Local-Link Scatter Gather DMA driver. This driver supports Soft
+* DMA (SDMA) engines. Each SDMA engine contains two separate DMA channels (TX
+* and RX).
+*
+* This component is designed to be used as a basic building block for
+* designing a device driver. It provides registers accesses such that all
+* DMA processing can be maintained easier, but the device driver designer
+* must still understand all the details of the DMA channel.
+*
+* For a full description of DMA features, please see the hardware spec. This
+* driver supports the following features:
+*
+* - Scatter-Gather DMA (SGDMA)
+* - Interrupts
+* - Programmable interrupt coalescing for SGDMA
+* - Capable of using 32 bit addressing for buffer. (Hardware spec states
+* 36 Bit bus addressing, which includes Msb 4-bits of DMA address
+* configurable on each channel through the Channel Control Registers)
+* - APIs to manage Buffer Descriptors (BD) movement to and from the SGDMA
+* engine
+* - Virtual memory support
+*
+* <b>Transactions</b>
+*
+* To describe a DMA transaction in its simplest form, you need source address,
+* destination address, and the number of bytes to transfer. When using a DMA
+* receive channel, the source address is within some piece of IP Hardware and
+* doesn't require the application explicitly set it. Likewise with a transmit
+* channel and the destination address. So this leaves a application buffer
+* address and the number bytes to transfer as the primary transaction
+* attributes. Other attributes include:
+*
+* - If the transaction occurs on a bus wider than 32 bits, what are the
+* highest order address bits.
+* - Does this transaction represent the start of a packet, or end of a
+* packet.
+*
+* The object used to describe a transaction is referred to as a Buffer
+* Descriptor (BD). The format of a BD closely matches that of the DMA hardware.
+* Many fields within the BD correspond directly with the same fields within the
+* hardware registers. See xlldmabd.h for a detailed description of and the API
+* for manipulation of these objects.
+*
+* <b>Scatter-Gather DMA</b>
+*
+* SGDMA allows the application to define a list of transactions in memory which
+* the hardware will process without further application intervention. During
+* this time, the application is free to continue adding more work to keep the
+* Hardware busy.
+*
+* Notification of completed transactions can be done either by polling the
+* hardware, or using interrupts that signal a transaction has completed or a
+* series of transactions have been completed.
+*
+* SGDMA processes whole packets. A packet is defined as a series of
+* data bytes that represent a message. SGDMA allows a packet of data to be
+* broken up into one or more transactions. For example, take an Ethernet IP
+* packet which consists of a 14 byte header followed by a 1 or more byte
+* payload. With SGDMA, the application may point a BD to the header and another
+* BD to the payload, then transfer them as a single message. This strategy can
+* make a TCP/IP stack more efficient by allowing it to keep packet headers and
+* data in different memory regions instead of assembling packets into
+* contiguous blocks of memory.
+*
+* <b>SGDMA Ring Management</b>
+*
+* The hardware expects BDs to be setup as a singly linked list. As a BD is
+* completed, the DMA engine will dereference BD.Next and load the next BD to
+* process. This driver uses a fixed buffer ring where all BDs are linked to the
+* next BD in adjacent memory. The last BD in the ring is linked to the first.
+*
+* Within the ring, the driver maintains four groups of BDs. Each group consists
+* of 0 or more adjacent BDs:
+*
+* - Free: Those BDs that can be allocated by the application with
+* XLlDma_BdRingAlloc(). These BDs are under driver control and may not be
+* modified by the application
+*
+* - Pre-process: Those BDs that have been allocated with
+* XLlDma_BdRingAlloc(). These BDs are under application control. The
+* application modifies these BDs in preparation for future DMA
+* transactions.
+*
+* - Hardware: Those BDs that have been enqueued to hardware with
+* XLlDma_BdRingToHw(). These BDs are under hardware control and may be in a
+* state of awaiting hardware processing, in process, or processed by
+* hardware. It is considered an error for the application to change BDs
+* while they are in this group. Doing so can cause data corruption and lead
+* to system instability.
+*
+* - Post-process: Those BDs that have been processed by hardware and have
+* been extracted from the work group with XLlDma_BdRingFromHw(). These BDs
+* are under application control. The application may access these BDs to
+* determine the result of DMA transactions. When the application is
+* finished, XLlDma_BdRingFree() should be called to place them back into
+* the Free group.
+*
+*
+* Normally BDs are moved in the following way:
+* <pre>
+*
+* XLlDma_BdRingAlloc() XLlDma_BdRingToHw()
+* Free ------------------------> Pre-process ----------------------> Hardware
+* |
+* /|\ |
+* | XLlDma_BdRingFree() XLlDma_BdRingFromHw() |
+* +--------------------------- software/linux-2.6.x-petalogix/Post-process <----------------------+
+*
+* </pre>
+*
+* The only exception to the flow above is that after BDs are moved from Free
+* group to Pre-process group, the application decide for whatever reason these
+* BDs are not ready and could not be given to hardware. In this case these BDs
+* could be moved back to Free group using XLlDma_BdRingUnAlloc() function to
+* help keep the BD ring in great shape and recover the error. See comments of
+* the function for details
+*
+* <pre>
+*
+* XLlDma_BdRingUnAlloc()
+* Free <----------------------- software/linux-2.6.x-petalogix/Pre-process
+*
+* </pre>
+*
+* The API provides macros that allow BD list traversal. These macros should be
+* used with care as they do not understand where one group ends and another
+* begins.
+*
+* The driver does not cache or keep copies of any BD. When the application
+* modifies BDs returned by XLlDma_BdRingAlloc() or XLlDma_BdRingFromHw(), they
+* are modifying the same BD that hardware accesses.
+*
+* Certain pairs of list modification functions have usage restrictions. See
+* the function headers for XLlDma_BdRingAlloc() and XLlDma_BdRingFromHw() for
+* more information.
+*
+* <b>SGDMA Descriptor Ring Creation</b>
+*
+* During initialization, the function XLlDma_BdRingCreate() is used to setup
+* a application supplied memory block to contain all BDs for the DMA channel.
+* This function takes as an argument the number of BDs to place in the list. To
+* arrive at this number, the application is given two methods of calculating
+* it.
+*
+* The first method assumes the application has a block of memory and they just
+* want to fit as many BDs as possible into it. The application must calculate
+* the number of BDs that will fit with XLlDma_mBdRingCntCalc(), then supply
+* that number into the list creation function.
+*
+* The second method allows the application to just supply the number directly.
+* The driver assumes the memory block is large enough to contain them all. To
+* double-check, the application should invoke XLlDma_mBdRingMemCalc() to verify
+* the memory block size is adequate.
+*
+* Once the list has been created, it can be used right away to perform DMA
+* transactions. However, there are optional steps that can be done to increase
+* throughput and decrease application code complexity by the use of
+* XLlDma_BdRingClone().
+*
+* BDs have several application accessible attributes that affect how DMA
+* transactions are carried out. Some of these attributes will probably be
+* constant at run-time. The cloning function can be used to copy a template BD
+* to every BD in the ring relieving the application of having to setup
+* transactions from scratch every time a BD is submitted to hardware.
+*
+* Ideally, the only transaction parameters that need to be set by application
+* should be: buffer address, bytes to transfer, and whether the BD is the
+* Start and/or End of a packet.
+*
+* <b>Interrupt Coalescing</b>
+*
+* SGDMA provides control over the frequency of interrupts. On a high speed link
+* significant processor overhead may be used servicing interrupts. Interrupt
+* coalescing provides two mechanisms that help control interrupt frequency:
+*
+* - The packet threshold counter will hold off interrupting the CPU until a
+* programmable number of packets have been processed by the engine.
+* - The packet waitbound timer is used to interrupt the CPU if after a
+* programmable amount of time after processing the last packet, no new
+* packets were processed.
+*
+* <b>Interrupt Service </b>
+*
+* This driver does not service interrupts. This is done typically by a
+* interrupt handler within a higher level driver/application that uses DMA.
+* This driver does provide an API to enable or disable specific interrupts.
+*
+* This interrupt handler provided by the higher level driver/application
+* !!!MUST!!! clear pending interrupts before handling the BDs processed by the
+* DMA. Otherwise the following corner case could raise some issue:
+*
+* - A packet is transmitted(/received) and asserts a TX(/RX) interrupt, and if
+* this interrupt handler deals with the BDs finished by the DMA before clears
+* the interrupt, another packet could get transmitted(/received) and assert
+* the interrupt between when the BDs are taken care and when the interrupt
+* clearing operation begins, and the interrupt clearing operation will clear
+* the interrupt raised by the second packet and will never process its
+* according BDs until a new interrupt occurs.
+*
+* Changing the sequence to "Clear interrupts before handle BDs" solves this
+* issue:
+*
+* - If the interrupt raised by the second packet is before the interrupt
+* clearing operation, the descriptors associated with the second packet must
+* have been finished by hardware and ready for the handler to deal with,
+* and those descriptors will processed with those BDs of the first packet
+* during the handling of the interrupt asserted by the first packet.
+*
+* - if the interrupt of the second packet is asserted after the interrupt
+* clearing operation but its BDs are finished before the handler starts to
+* deal with BDs, the packet's buffer descriptors will be handled with
+* those of the first packet during the handling of the interrupt asserted
+* by the first packet.
+*
+* - Otherwise, the BDs of the second packet is not ready when the interrupt
+* handler starts to deal with the BDs of the first packet. Those BDs will
+* be handled next time the interrupt handled gets invoked as the interrupt
+* of the second packet is not cleared in current pass and thereby will
+* cause the handler to get invoked again
+*
+* Please note if the second case above occurs, the handler will find
+* NO buffer descriptor is finished by the hardware (i.e.,
+* XLlDma_BdRingFromHw() returns 0) during the handling of the interrupt
+* asserted by the second packet. This is valid and the application should NOT
+* consider this is a hardware error and have no need to reset the hardware.
+*
+* <b> Software Initialization </b>
+*
+* The application needs to do following steps in order for preparing DMA engine
+* to be ready to process DMA transactions:
+*
+* - DMA Initialization using XLlDma_Initialize() function. This step
+* initializes a driver instance for the given DMA engine and resets the
+* engine.
+* - BD Ring creation. A BD ring is needed per channel and can be built by
+* calling XLlDma_BdRingCreate(). A parameter passed to this function is the
+* number of BD fit in a given memory range, and XLlDma_mBdRingCntCalc() helps
+* calculate the value.
+* - (Optional) BD setup using a template. Once a BD ring is created, the
+* application could populate a template BD and then invoke
+* XLlDma_BdRingClone() to set the same attributes on all BDs on the BD ring.
+* This saves the application some effort to populate all fixed attributes of
+* each BD before passing it to the hardware.
+* - (RX channel only) Prepare BDs with attached data buffers and give them to
+* RX channel. First allocate BDs using XLlDma_BdRingAlloc(), then populate
+* data buffer address, data buffer size and the control word fields of each
+* allocated BD with valid values. Last call XLlDma_BdRingToHw() to give the
+* BDs to the channel.
+* - Enable interrupts if interrupt mode is chosen. The application is
+* responsible for setting up the interrupt system, which includes providing
+* and connecting interrupt handlers and call back functions, before
+* the interrupts are enabled.
+* - Start DMA channels: Call XLlDma_BdRingStart() to start a channel
+*
+* <b> How to start DMA transactions </b>
+*
+* RX channel is ready to start RX transactions once the initialization (see
+* Initialization section above) is finished. The DMA transactions are triggered
+* by the user IP (like Local Link TEMAC).
+*
+* Starting TX transactions needs some work. The application calls
+* XLlDma_BdRingAlloc() to allocate a BD list, then populates necessary
+* attributes of each allocated BD including data buffer address, data size,
+* and control word, and last passes those BDs to the TX channel
+* (see XLlDma_BdRingToHw()). The added BDs will be processed as soon as the
+* TX channel reaches them.
+*
+* For both channels, If the DMA engine is currently paused (see
+* XLlDma_Pause()), the newly added BDs will be accepted but not processed
+* until the DMA engine is resumed (see XLlDma_Resume()).
+*
+* <b> Software Post-Processing on completed DMA transactions </b>
+*
+* Some software post-processing is needed after DMA transactions are finished.
+*
+* if interrupt system are set up and enabled, DMA channels notify the software
+* the finishing of DMA transactions using interrupts, Otherwise the
+* application could poll the channels (see XLlDma_BdRingFromHw()).
+*
+* - Once BDs are finished by a channel, the application first needs to fetch
+* them from the channel (see XLlDma_BdRingFromHw()).
+* - On TX side, the application now could free the data buffers attached to
+* those BDs as the data in the buffers has been transmitted.
+* - On RX side, the application now could use the received data in the buffers
+* attached to those BDs
+* - For both channels, those BDs need to be freed back to the Free group (see
+* XLlDma_BdRingFree()) so they are allocatable for future transactions.
+* - On RX side, it is the application's responsibility for having BDs ready
+* to receive data at any time. Otherwise the RX channel will refuse to
+* accept any data once it runs out of RX BDs. As we just freed those hardware
+* completed BDs in the previous step, it is good timing to allocate them
+* back (see XLlDma_BdRingAlloc()), prepare them, and feed them to the RX
+* channel again (see XLlDma_BdRingToHw())
+*
+* <b> Examples </b>
+*
+* Two examples are provided with this driver to demonstrate the driver usage:
+* One for interrupt mode and one for polling mode.
+*
+* <b>Address Translation</b>
+*
+* When the BD list is setup with XLlDma_BdRingCreate(), a physical and
+* virtual address is supplied for the segment of memory containing the
+* descriptors. The driver will handle any translations internally. Subsequent
+* access of descriptors by the application is done in terms of their virtual
+* address.
+*
+* Any application data buffer address attached to a BD must be physical
+* address. The application is responsible for calculating the physical address
+* before assigns it to the buffer address field in the BD.
+*
+* <b>Cache Coherency</b>
+*
+* This driver expects all application buffers attached to BDs to be in cache
+* coherent memory. Buffers for transmit MUST be flushed from the cache before
+* passing the associated BD to this driver. Buffers for receive MUST be
+* invalidated before passing the associated BD to this driver.
+*
+* <b>Alignment</b>
+*
+* For BDs:
+*
+* Minimum alignment is defined by the constant XLLDMA_BD_MINIMUM_ALIGNMENT.
+* This is the smallest alignment allowed by both hardware and software for them
+* to properly work. Other than XLLDMA_BD_MINIMUM_ALIGNMENT, multiples of the
+* constant are the only valid alignments for BDs.
+*
+* If the descriptor ring is to be placed in cached memory, alignment also MUST
+* be at least the processor's cache-line size. If this requirement is not met
+* then system instability will result. This is also true if the length of a BD
+* is longer than one cache-line, in which case multiple cache-lines are needed
+* to accommodate each BD.
+*
+* Aside from the initial creation of the descriptor ring (see
+* XLlDma_BdRingCreate()), there are no other run-time checks for proper
+* alignment.
+*
+* For application data buffers:
+*
+* Application data buffers may reside on any alignment.
+*
+* <b>Reset After Stopping</b>
+*
+* This driver is designed to allow for stop-reset-start cycles of the DMA
+* hardware while keeping the BD list intact. When restarted after a reset, this
+* driver will point the DMA engine to where it left off after stopping it.
+*
+* <b>Limitations</b>
+*
+* This driver only supports Normal mode (i.e., Tail Descriptor Pointer mode).
+* In this mode write of a Tail Descriptor Pointer register (which is done in
+* XLlDma_BdRingStart() and XLlDma_BdRingToHw()) starts DMA transactions.
+*
+* Legacy mode is NOT supported by this driver.
+*
+* This driver does not have any mechanism for mutual exclusion. It is up to the
+* application to provide this protection.
+*
+* <b>Hardware Defaults & Exclusive Use</b>
+*
+* During initialization, this driver will override the following hardware
+* default settings. If desired, the application may change these settings back
+* to their hardware defaults:
+*
+* - Normal mode (Tail Descriptor Pointer mode) will be enabled.
+* - Interrupt coalescing timer and counter overflow errors will be disabled
+* (XLLDMA_DMACR_RX_OVERFLOW_ERR_DIS_MASK and TX_OVERFLOW_ERR_DIS_MASK will
+* be set to 1). These two items control interrupt "overflow" behavior.
+* When enabled, the hardware may signal an error if interrupts are not
+* processed fast enough even though packets were correctly processed. This
+* error is triggered when certain internal counters overflow. The driver
+* disables this feature so no such error will be reported.
+*
+* The driver requires exclusive use of the following hardware features. If any
+* are changed by the application then the driver will not operate properly:
+*
+* - XLLDMA_DMACR_TAIL_PTR_ENABLE_MASK. The driver controls this bit
+* in the DMACR register.
+* - XLLDMA_BD_STSCTRL_COMPLETED_MASK. The driver controls this bit in each BD
+* - XLLDMA_NDESC_OFFSET. The driver controls this register
+* - XLLDMA_DMACR_SW_RESET_MASK. The driver controls this bit in the DMACR
+* register
+*
+* <b>BUS Interface</b>
+*
+* The constant XPAR_XLLDMA_USE_DCR (see xlldma_hw.h) is used to inform the
+* driver the type of the BUS the DMA device is on. If the DMA device is on DCR
+* BUS, XPAR_XLLDMA_USE_DCR must be defined as a compiler option used in the
+* Makefile BEFORE this driver is compiled; Otherwise, the constant must NOT be
+* defined.
+*
+* <b>User-IP Specific Definition</b>
+*
+* This driver relies on two User-IP (like Local-Link TEMAC) specific constants
+* (see xlldma_userip.h) to work properly:
+*
+* - XLLDMA_USR_APPWORD_OFFSET defines a user word the User-IP always updates
+* in the RX Buffer Descriptors (BD) during <b>ALL</b> Receive transactions.
+* This driver uses XLLDMA_BD_USR4_OFFSET as the default value of this
+* constant.
+*
+* - XLLDMA_USR_APPWORD_INITVALUE defines the value the DMA driver uses to
+* populate the XLLDMA_USR_APPWORD_OFFSET field in any RX BD before giving
+* the BD to the RX channel for receive transaction. It must be ensured
+* that the User-IP will always populates a different value into the
+* XLLDMA_USR_APPWORD_OFFSET field during any receive transaction. Failing
+* to do so will cause the DMA driver to work improperly. This driver uses
+* 0xFFFFFFFF as the default value of this constant.
+*
+* If the User-IP uses different setting, the correct setting must be defined as
+* compiler options used in the Makefile BEFORE this driver is compiled. In
+* either case the default definition of the constants in this driver will be
+* discarded.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 1.00a xd 12/21/06 First release
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XLLDMA_H /* prevent circular inclusions */
+#define XLLDMA_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xlldma_bd.h"
+#include "xlldma_bdring.h"
+#include "xlldma_userip.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+#define XLLDMA_NO_CHANGE 0xFFFF /* Used as API argument */
+#define XLLDMA_ALL_BDS 0xFFFFFFFF /* Used as API argument */
+
+/**************************** Type Definitions *******************************/
+
+
+/**
+ * The XLlDma driver instance data. An instance must be allocated for each DMA
+ * engine in use. Each DMA engine includes a TX channel and a RX channel.
+ */
+typedef struct XLlDma {
+ u32 RegBase; /**< Virtual base address of DMA engine */
+ XLlDma_BdRing TxBdRing; /**< BD container management for TX channel */
+ XLlDma_BdRing RxBdRing; /**< BD container management for RX channel */
+
+} XLlDma;
+
+
+/***************** 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 engine to operate on.
+*
+* @return TxBdRing object
+*
+* @note
+* C-style signature:
+* XLlDma_BdRing XLlDma_mGetTxRing(XLlDma* InstancePtr)
+*
+*****************************************************************************/
+#define XLlDma_mGetTxRing(InstancePtr) ((InstancePtr)->TxBdRing)
+
+
+/****************************************************************************/
+/**
+* Retrieve the RX ring object. This object can be used in the various Ring
+* API functions.
+*
+* @param InstancePtr is the DMA engine to operate on.
+*
+* @return RxBdRing object
+*
+* @note
+* C-style signature:
+* XLlDma_BdRing XLlDma_mGetRxRing(XLlDma* InstancePtr)
+*
+*****************************************************************************/
+#define XLlDma_mGetRxRing(InstancePtr) ((InstancePtr)->RxBdRing)
+
+
+/****************************************************************************/
+/**
+* Retrieve the contents of the DMA engine control register
+* (XLLDMA_DMACR_OFFSET).
+*
+* @param InstancePtr is the DMA engine instance to operate on.
+*
+* @return Current contents of the DMA engine control register.
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mGetCr(XLlDma* InstancePtr)
+*
+*****************************************************************************/
+#define XLlDma_mGetCr(InstancePtr) \
+ XLlDma_mReadReg((InstancePtr)->RegBase, XLLDMA_DMACR_OFFSET)
+
+
+/****************************************************************************/
+/**
+* Set the contents of the DMA engine control register (XLLDMA_DMACR_OFFSET).
+* This control register affects both DMA channels.
+*
+* @param InstancePtr is the DMA engine instance to operate on.
+* @param Data is the data to write to the DMA engine control register.
+*
+* @note
+* C-style signature:
+* u32 XLlDma_mSetCr(XLlDma* InstancePtr, u32 Data)
+*
+*****************************************************************************/
+#define XLlDma_mSetCr(InstancePtr, Data) \
+ XLlDma_mWriteReg((InstancePtr)->RegBase, XLLDMA_DMACR_OFFSET, (Data))
+
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization and control functions in xlldma.c
+ */
+void XLlDma_Initialize(XLlDma * InstancePtr, u32 BaseAddress);
+void XLlDma_Reset(XLlDma * InstancePtr);
+void XLlDma_Pause(XLlDma * InstancePtr);
+void XLlDma_Resume(XLlDma * InstancePtr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.h.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xpacket_fifo_l_v2_00_a.h
@@ -41,8 +41,8 @@
* </pre>
*
*****************************************************************************/
-#ifndef XPACKET_FIFO_L_V200A_H /* prevent circular inclusions */
-#define XPACKET_FIFO_L_V200A_H /* by using protection macros */
+#ifndef XPACKET_FIFO_L_V200A_H /* prevent circular inclusions */
+#define XPACKET_FIFO_L_V200A_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
@@ -60,8 +60,8 @@ extern "C" {
* These constants specify the FIFO type and are mutually exclusive
* @{
*/
-#define XPF_V200A_READ_FIFO_TYPE 0 /**< a read FIFO */
-#define XPF_V200A_WRITE_FIFO_TYPE 1 /**< a write FIFO */
+#define XPF_V200A_READ_FIFO_TYPE 0 /**< a read FIFO */
+#define XPF_V200A_WRITE_FIFO_TYPE 1 /**< a write FIFO */
/* @} */
/** @name Register offsets
@@ -126,23 +126,20 @@ extern "C" {
/************************** Function Prototypes ******************************/
-XStatus XPacketFifoV200a_L0Read(Xuint32 RegBaseAddress,
- Xuint32 DataBaseAddress,
- Xuint8 *ReadBufferPtr,
- Xuint32 ByteCount);
-
-XStatus XPacketFifoV200a_L0Write(Xuint32 RegBaseAddress,
- Xuint32 DataBaseAddress,
- Xuint8 *WriteBufferPtr,
- Xuint32 ByteCount);
-
-XStatus XPacketFifoV200a_L0WriteDre(Xuint32 RegBaseAddress,
- Xuint32 DataBaseAddress,
- Xuint8 *BufferPtr,
- Xuint32 ByteCount);
+int XPacketFifoV200a_L0Read(u32 RegBaseAddress,
+ u32 DataBaseAddress,
+ u8 *ReadBufferPtr, u32 ByteCount);
+
+int XPacketFifoV200a_L0Write(u32 RegBaseAddress,
+ u32 DataBaseAddress,
+ u8 *WriteBufferPtr, u32 ByteCount);
+
+int XPacketFifoV200a_L0WriteDre(u32 RegBaseAddress,
+ u32 DataBaseAddress,
+ u8 *BufferPtr, u32 ByteCount);
#ifdef __cplusplus
}
#endif
-#endif /* end of protection macro */
+#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_sg.c
===================================================================
--- /dev/null
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xdmav3_sg.c
@@ -0,0 +1,1261 @@
+/* $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 2006 Xilinx Inc.
+* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xdmav3_sg.c
+*
+* This file implements Scatter-Gather DMA (SGDMA) related functions. For more
+* information on this driver, see xdmav3.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+* 3.00a rmm 03/11/06 First release
+* rmm 06/22/06 Fixed C++ compiler warnings
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+#include <asm/delay.h>
+
+#include "xdmav3.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/****************************************************************************
+ * These cache macros are used throughout this source code file to show
+ * users where cache operations should occur if BDs were to be placed in
+ * a cached memory region. Cacheing BD regions, however, is not common.
+ *
+ * The macros are implemented as NULL operations, but may be hooked into
+ * XENV macros in future revisions of this driver.
+ ****************************************************************************/
+#define XDMAV3_CACHE_FLUSH(BdPtr)
+#define XDMAV3_CACHE_INVALIDATE(BdPtr)
+
+/****************************************************************************
+ * Compute the virtual address of a descriptor from its physical address
+ *
+ * @param Ring is the ring BdPtr appears in
+ * @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 XDMAV3_PHYS_TO_VIRT(Ring, BdPtr) \
+ ((u32)BdPtr + (Ring->BaseAddr - Ring->PhysBaseAddr))
+
+/****************************************************************************
+ * Compute the physical address of a descriptor from its virtual address
+ *
+ * @param Ring is the ring BdPtr appears in
+ * @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 XDMAV3_VIRT_TO_PHYS(Ring, BdPtr) \
+ ((u32)BdPtr - (Ring->BaseAddr - Ring->PhysBaseAddr))
+
+/****************************************************************************
+ * Clear or set the SGS bit of the DMACR register
+ ****************************************************************************/
+#define XDMAV3_HW_SGS_CLEAR \
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET, \
+ XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET) \
+ & ~XDMAV3_DMACR_SGS_MASK)
+
+#define XDMAV3_HW_SGS_SET \
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET, \
+ XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMACR_OFFSET) \
+ | XDMAV3_DMACR_SGS_MASK)
+
+/****************************************************************************
+ * 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 Ring 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 XDMAV3_RING_SEEKAHEAD(Ring, BdPtr, NumBd) \
+ { \
+ u32 Addr = (u32)BdPtr; \
+ \
+ Addr += (Ring->Separation * NumBd); \
+ if ((Addr > Ring->HighAddr) || ((u32)BdPtr > Addr)) \
+ { \
+ Addr -= Ring->Length; \
+ } \
+ \
+ BdPtr = (XDmaBdV3*)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 Ring 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 XDMAV3_RING_SEEKBACK(Ring, BdPtr, NumBd) \
+ { \
+ u32 Addr = (u32)BdPtr; \
+ \
+ Addr -= (Ring->Separation * NumBd); \
+ if ((Addr < Ring->BaseAddr) || ((u32)BdPtr < Addr)) \
+ { \
+ Addr += Ring->Length; \
+ } \
+ \
+ BdPtr = (XDmaBdV3*)Addr; \
+ }
+
+
+/************************** Function Prototypes ******************************/
+
+static int IsSgDmaChannel(XDmaV3 * InstancePtr);
+
+
+/************************** Variable Definitions *****************************/
+
+/******************************************************************************/
+/**
+ * Start the SGDMA channel.
+ *
+ * @param InstancePtr is a pointer to the instance to be started.
+ *
+ * @return
+ * - XST_SUCCESS if channel was started.
+ * - XST_DMA_SG_NO_LIST if the channel has no initialized BD ring.
+ *
+ ******************************************************************************/
+int XDmaV3_SgStart(XDmaV3 * InstancePtr)
+{
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+ u32 Swcr;
+
+ /* BD list has yet to be created for this channel */
+ if (Ring->AllCnt == 0) {
+ return (XST_DMA_SG_NO_LIST);
+ }
+
+ /* Do nothing if already started */
+ if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+ return (XST_SUCCESS);
+ }
+
+ /* Note as started */
+ Ring->RunState = XST_DMA_SG_IS_STARTED;
+
+ /* Restore BDA */
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_BDA_OFFSET,
+ Ring->BdaRestart);
+
+ /* If there are unprocessed BDs then we want to channel to begin processing
+ * right away
+ */
+ if ((XDmaV3_mReadBd(XDMAV3_PHYS_TO_VIRT(Ring, Ring->BdaRestart),
+ XDMAV3_BD_DMASR_OFFSET) & XDMAV3_DMASR_DMADONE_MASK)
+ == 0) {
+ /* DMACR.SGS = 0 */
+ XDMAV3_HW_SGS_CLEAR;
+ }
+
+ /* To start, clear SWCR.DSGAR, and set SWCR.SGE */
+ Swcr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+ Swcr &= ~XDMAV3_SWCR_DSGAR_MASK;
+ Swcr |= XDMAV3_SWCR_SGE_MASK;
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Swcr);
+
+ return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Stop the SGDMA or Simple SGDMA channel gracefully. Any DMA operation
+ * currently in progress is allowed to finish.
+ *
+ * An interrupt may be generated as the DMA engine finishes the packet in
+ * process. To prevent this (if desired) then disabled DMA interrupts prior to
+ * invoking this function.
+ *
+ * If after stopping the channel, new BDs are enqueued with XDmaV3_SgBdToHw(),
+ * then those BDs will not be processed until after XDmaV3_SgStart() is called.
+ *
+ * @param InstancePtr is a pointer to the instance to be stopped.
+ *
+ * @note This function will block until the HW indicates that DMA has stopped.
+ *
+ ******************************************************************************/
+void XDmaV3_SgStop(XDmaV3 * InstancePtr)
+{
+ volatile u32 Swcr;
+ u32 Dmasr;
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+ u32 Ier;
+
+ /* Save the contents of the interrupt enable register then disable
+ * interrupts. This register will be restored at the end of the function
+ */
+ Ier = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET);
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET, 0);
+
+ /* Stopping the HW is a three step process:
+ * 1. Set SWCR.SGD=1
+ * 2. Wait for SWCR.SGE=0
+ * 3. Set SWCR.DSGAR=0 and SWCR.SGE=1
+ *
+ * Once we've successfully gone through this process, the HW is fully
+ * stopped. To restart we must give the HW a new BDA.
+ */
+ Swcr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+
+ /* If the channel is currently active, stop it by setting SWCR.SGD=1
+ * and waiting for SWCR.SGE to toggle to 0
+ */
+ if (Swcr & XDMAV3_SWCR_SGE_MASK) {
+ Swcr |= XDMAV3_SWCR_SGD_MASK;
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET,
+ Swcr);
+
+ while (Swcr & XDMAV3_SWCR_SGE_MASK) {
+ Swcr = XDmaV3_mReadReg(InstancePtr->RegBase,
+ XDMAV3_SWCR_OFFSET);
+ }
+ }
+
+ /* Note as stopped */
+ Ring->RunState = XST_DMA_SG_IS_STOPPED;
+
+ /* Save the BDA to restore when channel is restarted */
+ Ring->BdaRestart =
+ (XDmaBdV3 *) XDmaV3_mReadReg(InstancePtr->RegBase,
+ XDMAV3_BDA_OFFSET);
+
+ /* If this is a receive channel, then the BDA restore may require a more
+ * complex treatment. If the channel stopped without processing a packet,
+ * then DMASR.SGDONE will be clear. The BDA we've already read in this case
+ * is really BDA->BDA so we need to backup one BDA to get the correct
+ * restart point.
+ */
+ Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if ((Dmasr & XDMAV3_DMASR_DMACNFG_MASK) ==
+ XDMAV3_DMASR_DMACNFG_SGDMARX_MASK) {
+ if (!(Dmasr & XDMAV3_DMASR_SGDONE_MASK)) {
+ Ring->BdaRestart =
+ (XDmaBdV3 *) XDMAV3_PHYS_TO_VIRT(Ring,
+ Ring->
+ BdaRestart);
+ Ring->BdaRestart =
+ XDmaV3_mSgBdPrev(InstancePtr, Ring->BdaRestart);
+ Ring->BdaRestart =
+ (XDmaBdV3 *) XDMAV3_VIRT_TO_PHYS(Ring,
+ Ring->
+ BdaRestart);
+ }
+ }
+
+ Swcr |= XDMAV3_SWCR_DSGAR_MASK;
+ Swcr &= ~XDMAV3_SWCR_SGD_MASK;
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Swcr);
+
+ /* Restore interrupt enables. If an interrupt occurs due to this function
+ * stopping the channel then it will happen right here
+ */
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_IER_OFFSET, Ier);
+}
+
+
+/******************************************************************************/
+/**
+ * Set the packet threshold for this SGDMA channel. This has the effect of
+ * delaying processor interrupts until the given number of packets (not BDs)
+ * have been processed.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param Threshold is the packet threshold to set. If 0 is specified, then
+ * this feature is disabled. Maximum threshold is 2^12 - 1.
+ *
+ * @return
+ * - XST_SUCCESS if threshold set properly.
+ * - XST_NO_FEATURE if this function was called on a DMA channel that does not
+ * have interrupt coalescing capabilities.
+ *
+ * @note This function should not be prempted by another XDmaV3 function.
+ *
+ ******************************************************************************/
+int XDmaV3_SgSetPktThreshold(XDmaV3 * InstancePtr, u16 Threshold)
+{
+ u32 Reg;
+
+ /* Is this a SGDMA channel */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if (!IsSgDmaChannel(InstancePtr)) {
+ return (XST_NO_FEATURE);
+ }
+
+ /* Replace the pkt threshold field in the SWCR */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+ Reg &= ~XDMAV3_SWCR_PCT_MASK;
+ Reg |= ((Threshold << XDMAV3_SWCR_PCT_SHIFT) & XDMAV3_SWCR_PCT_MASK);
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Reg);
+
+ /* Finished */
+ return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Set the packet waitbound timer for this SGDMA channel. See xdmav3.h for more
+ * information on interrupt coalescing and the effects of the waitbound timer.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ * @param TimerVal is the waitbound period to set. If 0 is specified, then
+ * this feature is disabled. Maximum waitbound is 2^12 - 1. LSB is
+ * 1 millisecond (approx).
+ *
+ * @return
+ * - XST_SUCCESS if waitbound set properly.
+ * - XST_NO_FEATURE if this function was called on a DMA channel that does not
+ * have interrupt coalescing capabilities.
+ *
+ * @note This function should not be prempted by another XDmaV3 function.
+ *
+ ******************************************************************************/
+int XDmaV3_SgSetPktWaitbound(XDmaV3 * InstancePtr, u16 TimerVal)
+{
+ u32 Reg;
+
+ /* Is this a SGDMA channel */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if (!IsSgDmaChannel(InstancePtr)) {
+ return (XST_NO_FEATURE);
+ }
+
+ /* Replace the waitbound field in the SWCR */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+ Reg &= ~XDMAV3_SWCR_PWB_MASK;
+ Reg |= ((TimerVal << XDMAV3_SWCR_PWB_SHIFT) & XDMAV3_SWCR_PWB_MASK);
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET, Reg);
+
+ /* Finished */
+ return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Get the packet threshold for this channel that was set with
+ * XDmaV3_SgSetPktThreshold().
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return Current packet threshold as reported by HW. If the channel does not
+ * include interrupt coalescing, then the return value will always be 0.
+ ******************************************************************************/
+u16 XDmaV3_SgGetPktThreshold(XDmaV3 * InstancePtr)
+{
+ u32 Reg;
+
+ /* Is this a SGDMA channel */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if (!IsSgDmaChannel(InstancePtr)) {
+ return (0);
+ }
+
+ /* Get the threshold */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+ Reg &= XDMAV3_SWCR_PCT_MASK;
+ Reg >>= XDMAV3_SWCR_PCT_SHIFT;
+ return ((u16) Reg);
+}
+
+
+/******************************************************************************/
+/**
+ * Get the waitbound timer for this channel that was set with
+ * XDmaV3_SgSetPktWaitbound().
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return Current waitbound timer as reported by HW. If the channel does not
+ * include interrupt coalescing, then the return value will always be 0.
+ ******************************************************************************/
+u16 XDmaV3_SgGetPktWaitbound(XDmaV3 * InstancePtr)
+{
+ u32 Reg;
+
+ /* Is this a SGDMA channel */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if (!IsSgDmaChannel(InstancePtr)) {
+ return (0);
+ }
+
+ /* Get the threshold */
+ Reg = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+ Reg &= XDMAV3_SWCR_PWB_MASK;
+ Reg >>= XDMAV3_SWCR_PWB_SHIFT;
+ return ((u16) Reg);
+}
+
+
+/******************************************************************************/
+/**
+ * Using a memory segment allocated by the caller, create and setup the BD list
+ * for the given SGDMA channel.
+ *
+ * @param InstancePtr 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. Refer to the
+ * "SGDMA List Creation" section in xdmav3.h for more information on
+ * list creation.
+ *
+ * @return
+ *
+ * - XST_SUCCESS if initialization was successful
+ * - XST_NO_FEATURE if the provided instance is a non SGDMA type of DMA
+ * 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
+ *
+ * Some DMA HW requires 8 or more byte alignments of BDs. Make sure the correct
+ * value is passed into the Alignment parameter to meet individual DMA HW
+ * requirements.
+ *
+ ******************************************************************************/
+int XDmaV3_SgListCreate(XDmaV3 * InstancePtr, u32 PhysAddr, u32 VirtAddr,
+ u32 Alignment, unsigned BdCount)
+{
+ unsigned i;
+ u32 BdV;
+ u32 BdP;
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+ /* In case there is a failure prior to creating list, make sure the following
+ * attributes are 0 to prevent calls to other SG functions from doing anything
+ */
+ Ring->AllCnt = 0;
+ Ring->FreeCnt = 0;
+ Ring->HwCnt = 0;
+ Ring->PreCnt = 0;
+ Ring->PostCnt = 0;
+
+ /* Is this a SGDMA channel */
+ if (!IsSgDmaChannel(InstancePtr)) {
+ return (XST_NO_FEATURE);
+ }
+
+ /* Make sure Alignment parameter meets minimum requirements */
+ if (Alignment < XDMABDV3_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);
+ }
+
+ /* Parameters are sane. Stop the HW just to be safe */
+ XDmaV3_SgStop(InstancePtr);
+
+ /* Figure out how many bytes will be between the start of adjacent BDs */
+ Ring->Separation =
+ (sizeof(XDmaBdV3) + (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 + (Ring->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
+ * - Set each BD's DMASR.DMADONE bit
+ */
+ memset((void *) VirtAddr, 0, (Ring->Separation * BdCount));
+
+ BdV = VirtAddr;
+ BdP = PhysAddr + Ring->Separation;
+ for (i = 1; i < BdCount; i++) {
+ XDmaV3_mWriteBd(BdV, XDMAV3_BD_BDA_OFFSET, BdP);
+ XDmaV3_mWriteBd(BdV, XDMAV3_BD_DMASR_OFFSET,
+ XDMAV3_DMASR_DMADONE_MASK);
+ XDMAV3_CACHE_FLUSH(BdV);
+ BdV += Ring->Separation;
+ BdP += Ring->Separation;
+ }
+
+ /* At the end of the ring, link the last BD back to the top */
+ XDmaV3_mWriteBd(BdV, XDMAV3_BD_BDA_OFFSET, PhysAddr);
+
+ /* Setup and initialize pointers and counters */
+ InstancePtr->BdRing.RunState = XST_DMA_SG_IS_STOPPED;
+ Ring->BaseAddr = VirtAddr;
+ Ring->PhysBaseAddr = PhysAddr;
+ Ring->HighAddr = BdV;
+ Ring->Length = Ring->HighAddr - Ring->BaseAddr + Ring->Separation;
+ Ring->AllCnt = BdCount;
+ Ring->FreeCnt = BdCount;
+ Ring->FreeHead = (XDmaBdV3 *) VirtAddr;
+ Ring->PreHead = (XDmaBdV3 *) VirtAddr;
+ Ring->HwHead = (XDmaBdV3 *) VirtAddr;
+ Ring->HwTail = (XDmaBdV3 *) VirtAddr;
+ Ring->PostHead = (XDmaBdV3 *) VirtAddr;
+ Ring->BdaRestart = (XDmaBdV3 *) PhysAddr;
+
+ /* Make sure the DMACR.SGS is 1 so that no DMA operations proceed until
+ * the start function is called.
+ */
+ XDMAV3_HW_SGS_SET;
+
+ return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Clone the given BD into every BD in the list. Except for XDMAV3_BD_BDA_OFFSET,
+ * 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 XDmaV3_SgListCreate(). This
+ * prevents modification of BDs while they are in use by HW or the user.
+ *
+ * @param InstancePtr is the 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 HW
+ * or user control.
+ * - XST_DEVICE_IS_STARTED if the DMA channel has not been stopped.
+ *
+ ******************************************************************************/
+int XDmaV3_SgListClone(XDmaV3 * InstancePtr, XDmaBdV3 * SrcBdPtr)
+{
+ unsigned i;
+ u32 CurBd;
+ u32 Save;
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+ /* Can't do this function if there isn't a ring */
+ if (Ring->AllCnt == 0) {
+ return (XST_DMA_SG_NO_LIST);
+ }
+
+ /* Can't do this function with the channel running */
+ if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Can't do this function with some of the BDs in use */
+ if (Ring->FreeCnt != Ring->AllCnt) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Modify the template by setting DMASR.DMADONE */
+ Save = XDmaV3_mReadBd(SrcBdPtr, XDMAV3_BD_DMASR_OFFSET);
+ Save |= XDMAV3_DMASR_DMADONE_MASK;
+ XDmaV3_mWriteBd(SrcBdPtr, XDMAV3_BD_DMASR_OFFSET, Save);
+
+ /* 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 = Ring->BaseAddr;
+ i < Ring->AllCnt; i++, CurBd += Ring->Separation) {
+ Save = XDmaV3_mReadBd(CurBd, XDMAV3_BD_BDA_OFFSET);
+ memcpy((void *) CurBd, SrcBdPtr, sizeof(XDmaBdV3));
+ XDmaV3_mWriteBd(CurBd, XDMAV3_BD_BDA_OFFSET, Save);
+ XDMAV3_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 HW, the user must call XDmaV3_SgBdToHw() in the same order which
+ * they were allocated here. Example:
+ *
+ * <pre>
+ * NumBd = 2;
+ * Status = XDmaV3_SgBdAlloc(MyDmaInstPtr, 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 = XDmaV3_mSgBdNext(MyDmaInstPtr, CurBd);
+ * }
+ *
+ * // Give list to HW
+ * Status = XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd, MyBdSet);
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be allocated and given to HW in the correct sequence:
+ * <pre>
+ * // Legal
+ * XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd1, &MySet1);
+ * XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd1, MySet1);
+ *
+ * // Legal
+ * XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd1, &MySet1);
+ * XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd2, &MySet2);
+ * XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd1, MySet1);
+ * XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd2, MySet2);
+ *
+ * // Not legal
+ * XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd1, &MySet1);
+ * XDmaV3_SgBdAlloc(MyDmaInstPtr, NumBd2, &MySet2);
+ * XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd2, MySet2);
+ * XDmaV3_SgBdToHw(MyDmaInstPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * Use the API defined in xdmabdv3.h to modify individual BDs. Traversal of the
+ * BD set can be done using XDmaV3_mSgBdNext() and XDmaV3_mSgBdPrev().
+ *
+ * @param InstancePtr 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 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 XDmaV3 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 XDmaV3_SgBdAlloc(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 ** BdSetPtr)
+{
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+ /* Enough free BDs available for the request? */
+ if (Ring->FreeCnt < NumBd) {
+ return (XST_FAILURE);
+ }
+
+ /* Set the return argument and move FreeHead forward */
+ *BdSetPtr = Ring->FreeHead;
+ XDMAV3_RING_SEEKAHEAD(Ring, Ring->FreeHead, NumBd);
+ Ring->FreeCnt -= NumBd;
+ Ring->PreCnt += NumBd;
+ return (XST_SUCCESS);
+}
+
+/******************************************************************************/
+/**
+ * Fully or partially undo an XDmaV3_SgBdAlloc() operation. Use this function
+ * if all the BDs allocated by XDmaV3_SgBdAlloc() could not be transferred to
+ * HW with XDmaV3_SgBdToHw().
+ *
+ * This function helps out in situations when an unrelated error occurs after
+ * BDs have been allocated but before they have been given to HW. An example of
+ * this type of error would be an OS running out of resources.
+ *
+ * This function is not the same as XDmaV3_SgBdFree(). The Free function returns
+ * BDs to the free list after they have been processed by HW, while UnAlloc
+ * returns them before being processed by HW.
+ *
+ * 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 = XDmaV3_SgBdAlloc(Inst, 10, &BdPtr);
+ * .
+ * .
+ * if (Error)
+ * {
+ * Status = XDmaV3_SgBdUnAlloc(Inst, 10, &BdPtr);
+ * }
+ * </pre>
+ *
+ * A partial UnAlloc means some of the BDs Alloc'd will be returned:
+ *
+ * <pre>
+ * Status = XDmaV3_SgBdAlloc(Inst, 10, &BdPtr);
+ * BdsLeft = 10;
+ * CurBdPtr = BdPtr;
+ *
+ * while (BdsLeft)
+ * {
+ * if (Error)
+ * {
+ * Status = XDmaV3_SgBdUnAlloc(Inst, BdsLeft, CurBdPtr);
+ * }
+ *
+ * CurBdPtr = XDmaV3_SgBdNext(Inst, CurBdPtr);
+ * BdsLeft--;
+ * }
+ * </pre>
+ *
+ * A partial UnAlloc must include the last BD in the list that was Alloc'd.
+ *
+ * @param InstancePtr 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 XDmaV3 function call
+ * that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgBdUnAlloc(XDmaV3 * InstancePtr, unsigned NumBd,
+ XDmaBdV3 * BdSetPtr)
+{
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+ /* Enough BDs in the free state for the request? */
+ if (Ring->PreCnt < NumBd) {
+ return (XST_FAILURE);
+ }
+
+ /* Set the return argument and move FreeHead backward */
+ XDMAV3_RING_SEEKBACK(Ring, Ring->FreeHead, NumBd);
+ Ring->FreeCnt += NumBd;
+ Ring->PreCnt -= NumBd;
+ return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Enqueue a set of BDs to HW that were previously allocated by
+ * XDmaV3_SgBdAlloc(). Once this function returns, the argument BD set goes
+ * under HW 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 XDmaBdV3_mSetLast()).
+ *
+ * @param InstancePtr 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 HW.
+ *
+ * @return
+ * - XST_SUCCESS if the set of BDs was accepted and enqueued to HW.
+ * - 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
+ * XDmaV3_SgBdAlloc().
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ * that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgBdToHw(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr)
+{
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+ XDmaBdV3 *LastBdPtr;
+ unsigned i;
+ u32 Dmacr;
+ u32 Swcr;
+
+ /* Make sure we are in sync with XDmaV3_SgBdAlloc() */
+ if ((Ring->PreCnt < NumBd) || (Ring->PreHead != BdSetPtr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* For all BDs in this set (except the last one)
+ * - Clear DMASR except for DMASR.DMABSY
+ * - Clear DMACR.SGS
+ *
+ * For the last BD in this set
+ * - Clear DMASR except for DMASR.DMABSY
+ * - Set DMACR.SGS (marks the end of the new active list)
+ */
+ LastBdPtr = BdSetPtr;
+ for (i = 1; i < NumBd; i++) {
+ XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMASR_OFFSET,
+ XDMAV3_DMASR_DMABSY_MASK);
+
+ Dmacr = XDmaV3_mReadBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET);
+ XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET, /* DMACR.SGS = 0 */
+ Dmacr & ~XDMAV3_DMACR_SGS_MASK);
+ XDMAV3_CACHE_FLUSH(LastBdPtr);
+
+ LastBdPtr = XDmaV3_mSgBdNext(InstancePtr, LastBdPtr);
+ }
+
+ /* Last BD */
+ XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMASR_OFFSET,
+ XDMAV3_DMASR_DMABSY_MASK);
+
+ Dmacr = XDmaV3_mReadBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET);
+ XDmaV3_mWriteBd(LastBdPtr, XDMAV3_BD_DMACR_OFFSET, /* DMACR.SGS = 1 */
+ Dmacr | XDMAV3_DMACR_SGS_MASK);
+ XDMAV3_CACHE_FLUSH(LastBdPtr);
+
+ /* The last BD should have DMACR.LAST set */
+ if (!(Dmacr & XDMAV3_DMACR_LAST_MASK)) {
+ return (XST_FAILURE);
+ }
+
+ /* This set has completed pre-processing, adjust ring pointers & counters */
+ XDMAV3_RING_SEEKAHEAD(Ring, Ring->PreHead, NumBd);
+ Ring->PreCnt -= NumBd;
+
+ /* If it is running, tell the DMA engine to pause */
+ Swcr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET);
+ if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+ Swcr |= XDMAV3_SWCR_SGD_MASK;
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET,
+ Swcr);
+ }
+
+ /* Transfer control of the BDs to the DMA engine. There are two cases to
+ * consider:
+ *
+ * 1) No currently active list.
+ * In this case, just resume the engine.
+ *
+ * 2) Active list.
+ * In this case, the last BD in the current list should have DMACR.SGS
+ * cleared so the engine will never stop there. The new stopping
+ * point is at the end of the extended list. Once the SGS bits are
+ * changed, resume the engine.
+ */
+ if (Ring->HwCnt != 0) {
+ /* Handle case 2 */
+ Dmacr = XDmaV3_mReadBd(Ring->HwTail, XDMAV3_BD_DMACR_OFFSET);
+ Dmacr &= ~XDMAV3_DMACR_SGS_MASK;
+ XDmaV3_mWriteBd(Ring->HwTail, XDMAV3_BD_DMACR_OFFSET, Dmacr);
+ XDMAV3_CACHE_FLUSH(Ring->HwTail);
+ }
+
+ /* Adjust Hw pointers and counters. XDMAV3_RING_SEEKAHEAD could be used to
+ * advance HwTail, but it will always evaluate to LastBdPtr
+ */
+ Ring->HwTail = LastBdPtr;
+ Ring->HwCnt += NumBd;
+
+ /* If it was enabled, tell the engine to resume */
+ if (Ring->RunState == XST_DMA_SG_IS_STARTED) {
+ Swcr &= ~XDMAV3_SWCR_SGD_MASK;
+ Swcr |= XDMAV3_SWCR_SGE_MASK;
+ XDmaV3_mWriteReg(InstancePtr->RegBase, XDMAV3_SWCR_OFFSET,
+ Swcr);
+ }
+
+ return (XST_SUCCESS);
+}
+
+
+/******************************************************************************/
+/**
+ * Returns a set of BD(s) that have been processed by HW. 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 XDmaV3_SgBdFree() in the same order
+ * which they were retrieved here. Example:
+ *
+ * <pre>
+ * MaxBd = 0xFFFFFFFF; // Ensure we get all that are ready
+ *
+ * NumBd = XDmaV3_SgBdFromHw(MyDmaInstPtr, MaxBd, &MyBdSet);
+ *
+ * if (NumBd == 0)
+ * {
+ * // HW has nothing ready for us yet
+ * }
+ *
+ * CurBd = MyBdSet;
+ * for (i=0; i<NumBd; i++)
+ * {
+ * // Examine CurBd for post processing.....
+ *
+ * // Onto next BD
+ * CurBd = XDmaV3_mSgBdNext(MyDmaInstPtr, CurBd);
+ * }
+ *
+ * XDmaV3_SgBdFree(MyDmaInstPtr, NumBd, MyBdSet); // Return the list
+ * }
+ * </pre>
+ *
+ * A more advanced use of this function may allocate multiple sets of BDs.
+ * They must be retrieved from HW and freed in the correct sequence:
+ * <pre>
+ * // Legal
+ * XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd1, &MySet1);
+ * XDmaV3_SgBdFree(MyDmaInstPtr, NumBd1, MySet1);
+ *
+ * // Legal
+ * XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd1, &MySet1);
+ * XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd2, &MySet2);
+ * XDmaV3_SgBdFree(MyDmaInstPtr, NumBd1, MySet1);
+ * XDmaV3_SgBdFree(MyDmaInstPtr, NumBd2, MySet2);
+ *
+ * // Not legal
+ * XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd1, &MySet1);
+ * XDmaV3_SgBdFromHw(MyDmaInstPtr, NumBd2, &MySet2);
+ * XDmaV3_SgBdFree(MyDmaInstPtr, NumBd2, MySet2);
+ * XDmaV3_SgBdFree(MyDmaInstPtr, NumBd1, MySet1);
+ * </pre>
+ *
+ * If HW has only partially completed a packet spanning multiple BDs, then none
+ * of the BDs for that packet will be included in the results.
+ *
+ * @param InstancePtr 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 HW. 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 XDmaV3 function call
+ * that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+unsigned XDmaV3_SgBdFromHw(XDmaV3 * InstancePtr, unsigned BdLimit,
+ XDmaBdV3 ** BdSetPtr)
+{
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+ XDmaBdV3 *CurBd;
+ unsigned BdCount;
+ unsigned BdPartialCount;
+ u32 Dmasr;
+
+ CurBd = Ring->HwHead;
+ BdCount = 0;
+ BdPartialCount = 0;
+
+ /* If no BDs in work group, then there's nothing to search */
+ if (Ring->HwCnt == 0) {
+ *BdSetPtr = NULL;
+ return (0);
+ }
+
+ /* Starting at HwHead, keep moving forward in the list until:
+ * - A BD is encountered with its DMASR.DMABSY bit set which means HW has
+ * not completed processing of that BD.
+ * - Ring->HwTail is reached
+ * - The number of requested BDs has been processed
+ */
+ while (BdCount < BdLimit) {
+ /* Read the status */
+ XDMAV3_CACHE_INVALIDATE(CurBd);
+ Dmasr = XDmaV3_mReadBd(CurBd, XDMAV3_BD_DMASR_OFFSET);
+
+ /* If the HW still hasn't processed this BD then we are done */
+ if (Dmasr & XDMAV3_DMASR_DMABSY_MASK) {
+ break;
+ }
+
+ BdCount++;
+
+ /* HW 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 (Dmasr & XDMAV3_DMASR_LAST_MASK) {
+ BdPartialCount = 0;
+ }
+ else {
+ BdPartialCount++;
+ }
+
+ /* Reached the end of the work group */
+ if (CurBd == Ring->HwTail) {
+ break;
+ }
+
+ /* Move on to next BD in work group */
+ CurBd = XDmaV3_mSgBdNext(InstancePtr, CurBd);
+ }
+
+ /* 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) {
+ *BdSetPtr = Ring->HwHead;
+ Ring->HwCnt -= BdCount;
+ Ring->PostCnt += BdCount;
+ XDMAV3_RING_SEEKAHEAD(Ring, Ring->HwHead, BdCount);
+ return (BdCount);
+ }
+ else {
+ *BdSetPtr = NULL;
+ return (0);
+ }
+}
+
+
+/******************************************************************************/
+/**
+ * Frees a set of BDs that had been previously retrieved with XDmaV3_SgBdFromHw().
+ *
+ * @param InstancePtr 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 XDmaV3_SgBdFromHw().
+ *
+ * @return
+ * - XST_SUCCESS if the set of BDs was freed.
+ * - XST_DMA_SG_LIST_ERROR if this function was called out of sequence with
+ * XDmaV3_SgBdFromHw().
+ *
+ * @note This function should not be preempted by another XDmaV3 function call
+ * that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgBdFree(XDmaV3 * InstancePtr, unsigned NumBd, XDmaBdV3 * BdSetPtr)
+{
+ XDmaV3_BdRing *Ring = &InstancePtr->BdRing;
+
+ /* Make sure we are in sync with XDmaV3_SgBdFromHw() */
+ if ((Ring->PostCnt < NumBd) || (Ring->PostHead != BdSetPtr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Update pointers and counters */
+ Ring->FreeCnt += NumBd;
+ Ring->PostCnt -= NumBd;
+ XDMAV3_RING_SEEKAHEAD(Ring, Ring->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 InstancePtr 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 XDmaV3 function call
+ * that modifies the BD space. It is the caller's responsibility to
+ * provide a mutual exclusion mechanism.
+ *
+ ******************************************************************************/
+int XDmaV3_SgCheck(XDmaV3 * InstancePtr)
+{
+ XDmaV3_BdRing *RingPtr = &InstancePtr->BdRing;
+ u32 AddrV, AddrP;
+ unsigned i;
+
+ /* 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->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->PreHead;
+ if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->HwHead;
+ if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->HwTail;
+ if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ AddrV = (u32) RingPtr->PostHead;
+ if ((AddrV < RingPtr->BaseAddr) || (AddrV > RingPtr->HighAddr)) {
+ 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->BaseAddr;
+ 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 (XDmaV3_mReadBd(AddrV, XDMAV3_BD_BDA_OFFSET) != AddrP) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* Move on to next BD */
+ AddrV += RingPtr->Separation;
+ AddrP += RingPtr->Separation;
+ }
+
+ /* Last BD should point back to the beginning of ring */
+ if (XDmaV3_mReadBd(AddrV, XDMAV3_BD_BDA_OFFSET) !=
+ RingPtr->PhysBaseAddr) {
+ return (XST_DMA_SG_LIST_ERROR);
+ }
+
+ /* No problems found */
+ return (XST_SUCCESS);
+}
+
+
+/******************************************************************************
+ * Verify given channel is of the SGDMA variety.
+ *
+ * @param InstancePtr is a pointer to the instance to be worked on.
+ *
+ * @return
+ * - 1 if channel is of type SGDMA
+ * - 0 if channel is not of type SGDMA
+ ******************************************************************************/
+static int IsSgDmaChannel(XDmaV3 * InstancePtr)
+{
+ u32 Dmasr;
+
+ Dmasr = XDmaV3_mReadReg(InstancePtr->RegBase, XDMAV3_DMASR_OFFSET);
+ if (Dmasr & (XDMAV3_DMASR_DMACNFG_SGDMARX_MASK |
+ XDMAV3_DMASR_DMACNFG_SGDMATX_MASK |
+ XDMAV3_DMASR_DMACNFG_SSGDMA_MASK)) {
+ return (1);
+ }
+ else {
+ return (0);
+ }
+}
Index: software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.c.orig
+++ software/linux-2.6.x-petalogix/drivers/xilinx_common/xbasic_types.c
@@ -61,10 +61,10 @@ unsigned int XAssertStatus;
* such that it does not wait infinitely. Use the debugger to disable the
* waiting during testing of asserts.
*/
-Xboolean XWaitInAssert = XTRUE;
+u32 XWaitInAssert = TRUE;
/* The callback function to be invoked when an assert is taken */
-static XAssertCallback XAssertCallbackRoutine = (XAssertCallback)XNULL;
+static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL;
/************************** Function Prototypes ******************************/
@@ -85,18 +85,16 @@ static XAssertCallback XAssertCallbackRo
******************************************************************************/
void XAssert(char *File, int Line)
{
- /* if the callback has been set then invoke it */
- if (XAssertCallbackRoutine != XNULL)
- {
- (*XAssertCallbackRoutine)(File, Line);
- }
-
- /* if specified, wait indefinitely such that the assert will show up
- * in testing
- */
- while (XWaitInAssert)
- {
- }
+ /* 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) {
+ }
}
/*****************************************************************************/
@@ -114,7 +112,7 @@ void XAssert(char *File, int Line)
******************************************************************************/
void XAssertSetCallback(XAssertCallback Routine)
{
- XAssertCallbackRoutine = Routine;
+ XAssertCallbackRoutine = Routine;
}
@@ -135,4 +133,3 @@ void XAssertSetCallback(XAssertCallback
void XNullHandler(void *NullParameter)
{
}
-
Index: software/linux-2.6.x-petalogix/drivers/misc/Kconfig
===================================================================
--- software/linux-2.6.x-petalogix/drivers/misc/Kconfig.orig
+++ software/linux-2.6.x-petalogix/drivers/misc/Kconfig
@@ -117,3 +117,24 @@ if MICROBLAZE_FSLFIFO!=n
endif
endmenu
+
+#
+# Xilinx devices and common device driver infrastructure
+#
+
+config XILINX_DRIVERS
+ bool
+
+config NEED_XILINX_DMAV3
+ bool
+
+config NEED_XILINX_LLDMA
+ bool
+
+config NEED_XILINX_IPIF
+ bool
+
+config NEED_XILINX_PPC_DCR
+ bool
+
+
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.c.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.c
@@ -17,6 +17,14 @@
*
* (c) Copyright 2002 - 2005 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/**
@@ -100,13 +108,13 @@
* None.
*
*****************************************************************************/
-XStatus XGpio_CfgInitialize(XGpio *InstancePtr, XGpio_Config *Config,
- Xuint32 EffectiveAddr)
+int XGpio_CfgInitialize(XGpio *InstancePtr, XGpio_Config *Config,
+ u32 EffectiveAddr)
{
/*
* Assert arguments
*/
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
/*
* Set some default values.
@@ -144,13 +152,13 @@ XStatus XGpio_CfgInitialize(XGpio *Insta
*
*****************************************************************************/
void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel,
- Xuint32 DirectionMask)
+ u32 DirectionMask)
{
- XASSERT_VOID(InstancePtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
XASSERT_VOID((Channel == 1) ||
((Channel == 2) &&
- (InstancePtr->IsDual == XTRUE)));
+ (InstancePtr->IsDual == TRUE)));
XGpio_mWriteReg(InstancePtr->BaseAddress,
((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_TRI_OFFSET,
@@ -173,13 +181,13 @@ void XGpio_SetDataDirection(XGpio *Insta
* with any channel other than 1. If it is not, this function will assert.
*
*****************************************************************************/
-Xuint32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel)
+u32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel)
{
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
XASSERT_NONVOID((Channel == 1) ||
((Channel == 2) &&
- (InstancePtr->IsDual == XTRUE)));
+ (InstancePtr->IsDual == TRUE)));
return XGpio_mReadReg(InstancePtr->BaseAddress,
((Channel - 1) * XGPIO_CHAN_OFFSET) +
@@ -205,13 +213,13 @@ Xuint32 XGpio_DiscreteRead(XGpio *Instan
* See also XGpio_DiscreteSet() and XGpio_DiscreteClear().
*
*****************************************************************************/
-void XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, Xuint32 Data)
+void XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, u32 Data)
{
- XASSERT_VOID(InstancePtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
XASSERT_VOID((Channel == 1) ||
((Channel == 2) &&
- (InstancePtr->IsDual == XTRUE)));
+ (InstancePtr->IsDual == TRUE)));
XGpio_mWriteReg(InstancePtr->BaseAddress,
((Channel - 1) * XGPIO_CHAN_OFFSET) + XGPIO_DATA_OFFSET,
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio_l.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio_l.h.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio_l.h
@@ -17,6 +17,14 @@
*
* (c) Copyright 2002 - 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -122,12 +130,12 @@ extern "C" {
* @note None.
*
* C-style signature:
-* void XGpio_mWriteReg(Xuint32 BaseAddress, unsigned RegOffset,
-* Xuint32 Data)
+* void XGpio_mWriteReg(u32 BaseAddress, unsigned RegOffset,
+* u32 Data)
*
****************************************************************************/
#define XGpio_mWriteReg(BaseAddress, RegOffset, Data) \
- XIo_Out32((BaseAddress) + (RegOffset), (Xuint32)(Data))
+ XIo_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/****************************************************************************/
/**
@@ -146,7 +154,7 @@ extern "C" {
* @note None.
*
* C-style signature:
-* Xuint32 XGpio_mReadReg(Xuint32 BaseAddress, unsigned RegOffset)
+* u32 XGpio_mReadReg(u32 BaseAddress, unsigned RegOffset)
*
****************************************************************************/
#define XGpio_mReadReg(BaseAddress, RegOffset) \
@@ -167,8 +175,8 @@ extern "C" {
* @note None.
*
* C-style signature:
-* void XGpio_mSetDataDirection(Xuint32 BaseAddress, unsigned Channel,
-* Xuint32 DirectionMask)
+* void XGpio_mSetDataDirection(u32 BaseAddress, unsigned Channel,
+* u32 DirectionMask)
*
******************************************************************************/
#define XGpio_mSetDataDirection(BaseAddress, Channel, DirectionMask) \
@@ -188,7 +196,7 @@ extern "C" {
* @note None.
*
* C-style signature:
-* Xuint32 XGpio_mGetDataReg(Xuint32 BaseAddress, unsigned Channel)
+* u32 XGpio_mGetDataReg(u32 BaseAddress, unsigned Channel)
*
*****************************************************************************/
#define XGpio_mGetDataReg(BaseAddress, Channel) \
@@ -208,8 +216,8 @@ extern "C" {
* @note None.
*
* C-style signature:
-* void XGpio_mSetDataReg(Xuint32 BaseAddress, unsigned Channel,
-* Xuint32 Data)
+* void XGpio_mSetDataReg(u32 BaseAddress, unsigned Channel,
+* u32 Data)
*
*****************************************************************************/
#define XGpio_mSetDataReg(BaseAddress, Channel, Data) \
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.h.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_gpio/xgpio.h
@@ -17,6 +17,14 @@
*
* (c) Copyright 2002 - 2005 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -100,10 +108,10 @@ extern "C" {
*/
typedef struct
{
- Xuint16 DeviceId; /* Unique ID of device */
- Xuint32 BaseAddress; /* Device base address */
- Xboolean InterruptPresent; /* Are interrupts supported in h/w */
- Xboolean IsDual; /* Are 2 channels supported in h/w */
+ u16 DeviceId; /* Unique ID of device */
+ u32 BaseAddress; /* Device base address */
+ u32 InterruptPresent; /* Are interrupts supported in h/w */
+ u32 IsDual; /* Are 2 channels supported in h/w */
} XGpio_Config;
/**
@@ -113,10 +121,10 @@ typedef struct
*/
typedef struct
{
- Xuint32 BaseAddress; /* Device base address */
- Xuint32 IsReady; /* Device is initialized and ready */
- Xboolean InterruptPresent; /* Are interrupts supported in h/w */
- Xboolean IsDual; /* Are 2 channels supported in h/w */
+ u32 BaseAddress; /* Device base address */
+ u32 IsReady; /* Device is initialized and ready */
+ u32 InterruptPresent; /* Are interrupts supported in h/w */
+ u32 IsDual; /* Are 2 channels supported in h/w */
} XGpio;
/***************** Macros (Inline Functions) Definitions ********************/
@@ -127,41 +135,41 @@ typedef struct
/*
* Initialization functions in xgpio_sinit.c
*/
-XStatus XGpio_Initialize(XGpio *InstancePtr, Xuint16 DeviceId);
-XGpio_Config *XGpio_LookupConfig(Xuint16 DeviceId);
+int XGpio_Initialize(XGpio *InstancePtr, u16 DeviceId);
+XGpio_Config *XGpio_LookupConfig(u16 DeviceId);
/*
* API Basic functions implemented in xgpio.c
*/
-XStatus XGpio_CfgInitialize(XGpio *InstancePtr, XGpio_Config *Config,
- Xuint32 EffectiveAddr);
+int XGpio_CfgInitialize(XGpio *InstancePtr, XGpio_Config *Config,
+ u32 EffectiveAddr);
void XGpio_SetDataDirection(XGpio *InstancePtr, unsigned Channel,
- Xuint32 DirectionMask);
-Xuint32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel);
-void XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, Xuint32 Mask);
+ u32 DirectionMask);
+u32 XGpio_DiscreteRead(XGpio *InstancePtr, unsigned Channel);
+void XGpio_DiscreteWrite(XGpio *InstancePtr, unsigned Channel, u32 Mask);
/*
* API Functions implemented in xgpio_extra.c
*/
-void XGpio_DiscreteSet(XGpio *InstancePtr, unsigned Channel, Xuint32 Mask);
-void XGpio_DiscreteClear(XGpio *InstancePtr, unsigned Channel, Xuint32 Mask);
+void XGpio_DiscreteSet(XGpio *InstancePtr, unsigned Channel, u32 Mask);
+void XGpio_DiscreteClear(XGpio *InstancePtr, unsigned Channel, u32 Mask);
/*
* API Functions implemented in xgpio_selftest.c
*/
-XStatus XGpio_SelfTest(XGpio *InstancePtr);
+int XGpio_SelfTest(XGpio *InstancePtr);
/*
* API Functions implemented in xgpio_intr.c
*/
void XGpio_InterruptGlobalEnable(XGpio *InstancePtr);
void XGpio_InterruptGlobalDisable(XGpio *InstancePtr);
-void XGpio_InterruptEnable(XGpio *InstancePtr, Xuint32 Mask);
-void XGpio_InterruptDisable(XGpio *InstancePtr, Xuint32 Mask);
-void XGpio_InterruptClear(XGpio *InstancePtr, Xuint32 Mask);
-Xuint32 XGpio_InterruptGetEnabled(XGpio *InstancePtr);
-Xuint32 XGpio_InterruptGetStatus(XGpio *InstancePtr);
+void XGpio_InterruptEnable(XGpio *InstancePtr, u32 Mask);
+void XGpio_InterruptDisable(XGpio *InstancePtr, u32 Mask);
+void XGpio_InterruptClear(XGpio *InstancePtr, u32 Mask);
+u32 XGpio_InterruptGetEnabled(XGpio *InstancePtr);
+u32 XGpio_InterruptGetStatus(XGpio *InstancePtr);
#ifdef __cplusplus
}
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/adapter.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/adapter.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/adapter.c
@@ -186,7 +186,7 @@ static spinlock_t reset_lock = SPIN_LOCK
/* Helper function to determine if a given XEmac error warrants a reset. */
extern inline int
-status_requires_reset(XStatus s)
+status_requires_reset(int s)
{
return (s == XST_DMA_ERROR || s == XST_FIFO_ERROR ||
s == XST_RESET_ERROR || s == XST_DMA_SG_NO_LIST ||
@@ -308,11 +308,11 @@ reset(struct net_device *dev, DUPLEX dup
(void) XEmac_GetPktThreshold(&lp->Emac, XEM_SEND,
&SendThreshold);
(void) XEmac_GetPktWaitBound(&lp->Emac, XEM_SEND,
- (Xuint32 *)&SendWaitBound);
+ (u32 *)&SendWaitBound);
(void) XEmac_GetPktThreshold(&lp->Emac, XEM_RECV,
&RecvThreshold);
(void) XEmac_GetPktWaitBound(&lp->Emac, XEM_RECV,
- (Xuint32 *)&RecvWaitBound);
+ (u32 *)&RecvWaitBound);
} else
dma_works = 0;
@@ -360,7 +360,7 @@ reset(struct net_device *dev, DUPLEX dup
if (dma_works) {
int avail_plus = 0;
while (!(XDmaChannel_IsSgListEmpty(&(lp->Emac.SendChannel)))) { /* list isn't empty, has to be cleared */
- XStatus ret;
+ int ret;
XBufDescriptor* BdPtr;
if ((ret = XDmaChannel_GetDescriptor (&(lp->Emac.SendChannel), &BdPtr)) != XST_SUCCESS) {
@@ -395,7 +395,7 @@ get_phy_status(struct net_device *dev, D
{
struct net_local *lp = (struct net_local *) dev->priv;
u16 reg;
- XStatus xs;
+ int xs;
xs = XEmac_PhyRead(&lp->Emac, lp->mii_addr, MII_BMCR, ®);
if (xs != XST_SUCCESS) {
@@ -883,7 +883,7 @@ SgSendHandlerBH (unsigned long p)
static void
-SgSendHandler(void *CallBackRef, XBufDescriptor * BdPtr, Xuint32 NumBds)
+SgSendHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
{
struct net_device *dev = (struct net_device *) CallBackRef;
struct net_local *lp = (struct net_local *) dev->priv;
@@ -917,7 +917,7 @@ SgRecvHandlerBH (unsigned long p)
u32 len, new_skb_vaddr;
dma_addr_t skb_vaddr;
u32 align;
- XStatus result;
+ int result;
XBufDescriptor *curbd;
unsigned long flags;
@@ -997,7 +997,7 @@ SgRecvHandlerBH (unsigned long p)
static void
-SgRecvHandler(void *CallBackRef, XBufDescriptor * BdPtr, Xuint32 NumBds)
+SgRecvHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
{
struct net_device *dev = (struct net_device *) CallBackRef;
struct net_local *lp = (struct net_local *) dev->priv;
@@ -1043,7 +1043,7 @@ FifoRecvHandler(void *CallbackRef)
struct sk_buff *skb;
unsigned int align;
u32 len;
- XStatus Result;
+ int Result;
/*
* The OS independent Xilinx EMAC code does not provide a
@@ -1077,7 +1077,7 @@ FifoRecvHandler(void *CallbackRef)
if (align)
skb_reserve(skb, align);
- Result = XEmac_FifoRecv(&lp->Emac, (u8 *) skb->data, (Xuint32 *)&len);
+ Result = XEmac_FifoRecv(&lp->Emac, (u8 *) skb->data, (u32 *)&len);
if (Result != XST_SUCCESS) {
int need_reset = status_requires_reset(Result);
@@ -1119,7 +1119,7 @@ FifoRecvHandler(void *CallbackRef)
/* The callback function for errors. */
static void
-ErrorHandler(void *CallbackRef, XStatus Code)
+ErrorHandler(void *CallbackRef, int Code)
{
struct net_device *dev = (struct net_device *) CallbackRef;
int need_reset = status_requires_reset(Code);
@@ -1143,7 +1143,7 @@ descriptor_init(struct net_device *dev)
struct net_local *lp = (struct net_local *) dev->priv;
int i, recvsize, sendsize;
int dftsize;
- Xuint32 *recvpoolptr, *sendpoolptr;
+ u32 *recvpoolptr, *sendpoolptr;
void *recvpoolphy, *sendpoolphy;
/* calc size of descriptor space pool; alloc from non-cached memory */
@@ -1325,7 +1325,7 @@ xenet_ethtool_get_settings (struct net_d
u16 mii_cmd;
u16 mii_status;
u16 mii_advControl;
- XStatus xs;
+ int xs;
memset (ecmd, 0, sizeof(struct ethtool_cmd));
mac_options = XEmac_GetOptions (&(lp->Emac));
@@ -1421,7 +1421,7 @@ xenet_ethtool_get_coalesce (struct net_d
return -EIO;
}
ec->rx_max_coalesced_frames = threshold;
- if ((ret = XEmac_GetPktWaitBound (&lp->Emac, XEM_RECV, (Xuint32 *)&(ec->rx_coalesce_usecs)))
+ if ((ret = XEmac_GetPktWaitBound (&lp->Emac, XEM_RECV, (u32 *)&(ec->rx_coalesce_usecs)))
!= XST_SUCCESS) {
printk (KERN_INFO "XEmac_GetPktWaitBound error %d\n", ret);
return -EIO;
@@ -1431,7 +1431,7 @@ xenet_ethtool_get_coalesce (struct net_d
return -EIO;
}
ec->tx_max_coalesced_frames = threshold;
- if ((ret = XEmac_GetPktWaitBound (&lp->Emac, XEM_SEND, (Xuint32 *)&(ec->tx_coalesce_usecs)))
+ if ((ret = XEmac_GetPktWaitBound (&lp->Emac, XEM_SEND, (u32 *)&(ec->tx_coalesce_usecs)))
!= XST_SUCCESS) {
printk (KERN_INFO "XEmac_GetPktWaitBound send error %d\n", ret);
return -EIO;
@@ -1503,7 +1503,7 @@ xenet_ethtool_get_regs (struct net_devic
struct net_local *lp = (struct net_local *) dev->priv;
struct mac_regsDump* dump = (struct mac_regsDump*)regs;
int i;
- XStatus r;
+ int r;
dump->hd.version = 0;
dump->hd.len = EMAG_REGS_N * sizeof(dump->data);
@@ -1528,7 +1528,7 @@ xenet_do_ethtool_ioctl (struct net_devic
struct ethtool_pauseparam epp;
struct mac_regsDump regs;
int ret = -EOPNOTSUPP;
- XStatus result;
+ int result;
u32 Options;
u16 mii_reg_sset;
u16 mii_reg_spause;
@@ -1748,10 +1748,10 @@ xenet_ioctl(struct net_device *dev, stru
__u32 waitbound;
__u32 direction;
} wbnd_arg ;
- XStatus ret;
+ int ret;
unsigned long flags;
- XStatus Result;
+ int Result;
switch (cmd) {
case SIOCETHTOOL:
@@ -1861,7 +1861,7 @@ xenet_ioctl(struct net_device *dev, stru
if (copy_from_user(&wbnd_arg, rq->ifr_data, sizeof(wbnd_arg))) {
return -EFAULT;
}
- if ((ret = XEmac_GetPktWaitBound(&lp->Emac, wbnd_arg.direction, (Xuint32 *)&(wbnd_arg.waitbound)))
+ if ((ret = XEmac_GetPktWaitBound(&lp->Emac, wbnd_arg.direction, (u32 *)&(wbnd_arg.waitbound)))
!= XST_SUCCESS) {
return -EIO;
}
@@ -2065,7 +2065,7 @@ probe(int index)
/* Scan to find the PHY. */
lp->mii_addr = 0xFF;
for (maddr = 0; maddr < 32; maddr++) {
- XStatus Result;
+ int Result;
u16 reg;
Result = XEmac_PhyRead(&lp->Emac, maddr, MII_BMSR, ®);
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.h.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.h
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -415,36 +423,36 @@
*/
typedef struct
{
- Xuint32 XmitFrames; /**< Number of frames transmitted */
- Xuint32 XmitBytes; /**< Number of bytes transmitted */
- Xuint32 XmitLateCollisionErrors; /**< Number of transmission failures
+ u32 XmitFrames; /**< Number of frames transmitted */
+ u32 XmitBytes; /**< Number of bytes transmitted */
+ u32 XmitLateCollisionErrors; /**< Number of transmission failures
due to late collisions */
- Xuint32 XmitExcessDeferral; /**< Number of transmission failures
+ u32 XmitExcessDeferral; /**< Number of transmission failures
due o excess collision deferrals */
- Xuint32 XmitOverrunErrors; /**< Number of transmit overrun errors */
- Xuint32 XmitUnderrunErrors; /**< Number of transmit underrun errors */
- Xuint32 RecvFrames; /**< Number of frames received */
- Xuint32 RecvBytes; /**< Number of bytes received */
- Xuint32 RecvFcsErrors; /**< Number of frames discarded due
+ u32 XmitOverrunErrors; /**< Number of transmit overrun errors */
+ u32 XmitUnderrunErrors; /**< Number of transmit underrun errors */
+ u32 RecvFrames; /**< Number of frames received */
+ u32 RecvBytes; /**< Number of bytes received */
+ u32 RecvFcsErrors; /**< Number of frames discarded due
to FCS errors */
- Xuint32 RecvAlignmentErrors; /**< Number of frames received with
+ u32 RecvAlignmentErrors; /**< Number of frames received with
alignment errors */
- Xuint32 RecvOverrunErrors; /**< Number of frames discarded due
+ u32 RecvOverrunErrors; /**< Number of frames discarded due
to overrun errors */
- Xuint32 RecvUnderrunErrors; /**< Number of recv underrun errors */
- Xuint32 RecvMissedFrameErrors; /**< Number of frames missed by MAC */
- Xuint32 RecvCollisionErrors; /**< Number of frames discarded due
+ u32 RecvUnderrunErrors; /**< Number of recv underrun errors */
+ u32 RecvMissedFrameErrors; /**< Number of frames missed by MAC */
+ u32 RecvCollisionErrors; /**< Number of frames discarded due
to collisions */
- Xuint32 RecvLengthFieldErrors; /**< Number of frames discarded with
+ u32 RecvLengthFieldErrors; /**< Number of frames discarded with
invalid length field */
- Xuint32 RecvShortErrors; /**< Number of short frames discarded */
- Xuint32 RecvLongErrors; /**< Number of long frames discarded */
- Xuint32 DmaErrors; /**< Number of DMA errors since init */
- Xuint32 FifoErrors; /**< Number of FIFO errors since init */
- Xuint32 RecvInterrupts; /**< Number of receive interrupts */
- Xuint32 XmitInterrupts; /**< Number of transmit interrupts */
- Xuint32 EmacInterrupts; /**< Number of MAC (device) interrupts */
- Xuint32 TotalIntrs; /**< Total interrupts */
+ u32 RecvShortErrors; /**< Number of short frames discarded */
+ u32 RecvLongErrors; /**< Number of long frames discarded */
+ u32 DmaErrors; /**< Number of DMA errors since init */
+ u32 FifoErrors; /**< Number of FIFO errors since init */
+ u32 RecvInterrupts; /**< Number of receive interrupts */
+ u32 XmitInterrupts; /**< Number of transmit interrupts */
+ u32 EmacInterrupts; /**< Number of MAC (device) interrupts */
+ u32 TotalIntrs; /**< Total interrupts */
} XEmac_Stats;
/**
@@ -452,14 +460,14 @@ typedef struct
*/
typedef struct
{
- Xuint16 DeviceId; /**< Unique ID of device */
- Xuint32 BaseAddress; /**< Register base address */
- Xuint32 PhysAddress; /**< Physical Base address */
- Xboolean HasCounters; /**< Does device have counters? */
- Xuint8 IpIfDmaConfig; /**< IPIF/DMA hardware configuration */
- Xboolean HasMii; /**< Does device support MII? */
- Xboolean HasCam; /**< Does device have multicast CAM */
- Xboolean HasJumbo; /**< Can device transfer jumbo frames */
+ u16 DeviceId; /**< Unique ID of device */
+ u32 BaseAddress; /**< Register base address */
+ u32 PhysAddress; /**< Physical Base address */
+ u32 HasCounters; /**< Does device have counters? */
+ u8 IpIfDmaConfig; /**< IPIF/DMA hardware configuration */
+ u32 HasMii; /**< Does device support MII? */
+ u32 HasCam; /**< Does device have multicast CAM */
+ u32 HasJumbo; /**< Can device transfer jumbo frames */
} XEmac_Config;
@@ -479,7 +487,7 @@ typedef struct
* to by BdPtr.
*/
typedef void (*XEmac_SgHandler)(void *CallBackRef, XBufDescriptor *BdPtr,
- Xuint32 NumBds);
+ u32 NumBds);
/**
* Callback when data is sent or received with direct FIFO communication or
@@ -501,7 +509,7 @@ typedef void (*XEmac_FifoHandler)(void *
* @param ErrorCode is a Xilinx error code defined in xstatus.h. Also see
* XEmac_SetErrorHandler() for a description of possible errors.
*/
-typedef void (*XEmac_ErrorHandler)(void *CallBackRef, XStatus ErrorCode);
+typedef void (*XEmac_ErrorHandler)(void *CallBackRef, int ErrorCode);
/*@}*/
/**
@@ -511,11 +519,11 @@ typedef void (*XEmac_ErrorHandler)(void
*/
typedef struct
{
- Xuint32 BaseAddress; /* Base address (of IPIF) */
- Xuint32 PhysAddress; /* Base address, physical (of IPIF) */
- Xuint32 IsStarted; /* Device is currently started */
- Xuint32 IsReady; /* Device is initialized and ready */
- Xboolean IsPolled; /* Device is in polled mode */
+ u32 BaseAddress; /* Base address (of IPIF) */
+ u32 PhysAddress; /* Base address, physical (of IPIF) */
+ u32 IsStarted; /* Device is currently started */
+ u32 IsReady; /* Device is initialized and ready */
+ u32 IsPolled; /* Device is in polled mode */
XEmac_Config *ConfigPtr; /* Configuration table entry */
XEmac_Stats Stats;
@@ -534,7 +542,7 @@ typedef struct
XDmaChannel RecvChannel; /* DMA receive channel driver */
XDmaChannel SendChannel; /* DMA send channel driver */
- Xboolean IsSgEndDisable; /* Does SG DMA enable SGEND interrupt */
+ u32 IsSgEndDisable; /* Does SG DMA enable SGEND interrupt */
XEmac_SgHandler SgRecvHandler; /* callback for scatter-gather DMA */
void *SgRecvRef;
@@ -555,17 +563,17 @@ typedef struct
*
* @return
*
-* Boolean XTRUE if the device is configured for scatter-gather DMA, or XFALSE
+* Boolean TRUE if the device is configured for scatter-gather DMA, or FALSE
* if it is not.
*
* @note
*
-* Signature: Xboolean XEmac_mIsSgDma(XEmac *InstancePtr)
+* Signature: u32 XEmac_mIsSgDma(XEmac *InstancePtr)
*
******************************************************************************/
#define XEmac_mIsSgDma(InstancePtr) \
(((InstancePtr)->ConfigPtr->IpIfDmaConfig == XEM_CFG_DMA_SG) ? \
- XTRUE : XFALSE)
+ TRUE : FALSE)
/*****************************************************************************/
@@ -577,16 +585,16 @@ typedef struct
*
* @return
*
-* Boolean XTRUE if the device is configured for simple DMA, or XFALSE otherwise
+* Boolean TRUE if the device is configured for simple DMA, or FALSE otherwise
*
* @note
*
-* Signature: Xboolean XEmac_mIsSimpleDma(XEmac *InstancePtr)
+* Signature: u32 XEmac_mIsSimpleDma(XEmac *InstancePtr)
*
******************************************************************************/
#define XEmac_mIsSimpleDma(InstancePtr) \
(((InstancePtr)->ConfigPtr->IpIfDmaConfig == XEM_CFG_SIMPLE_DMA) ? \
- XTRUE : XFALSE)
+ TRUE : FALSE)
/*****************************************************************************/
@@ -599,16 +607,16 @@ typedef struct
*
* @return
*
-* Boolean XTRUE if the device is configured with DMA, or XFALSE otherwise
+* Boolean TRUE if the device is configured with DMA, or FALSE otherwise
*
* @note
*
-* Signature: Xboolean XEmac_mIsDma(XEmac *InstancePtr)
+* Signature: u32 XEmac_mIsDma(XEmac *InstancePtr)
*
******************************************************************************/
#define XEmac_mIsDma(InstancePtr) \
((XEmac_mIsSimpleDma(InstancePtr) || XEmac_mIsSgDma(InstancePtr)) ? \
- XTRUE : XFALSE)
+ TRUE : FALSE)
/*****************************************************************************/
/**
@@ -620,15 +628,15 @@ typedef struct
*
* @return
*
-* Boolean XTRUE if the device is configured with the CAM, or XFALSE otherwise
+* Boolean TRUE if the device is configured with the CAM, or FALSE otherwise
*
* @note
*
-* Signature: Xboolean XEmac_mHasCam(XEmac *InstancePtr)
+* Signature: u32 XEmac_mHasCam(XEmac *InstancePtr)
*
******************************************************************************/
#define XEmac_mHasCam(InstancePtr) \
- (((InstancePtr)->ConfigPtr->HasCam == 1) ? XTRUE : XFALSE)
+ (((InstancePtr)->ConfigPtr->HasCam == 1) ? TRUE : FALSE)
/*****************************************************************************/
/**
@@ -640,15 +648,15 @@ typedef struct
*
* @return
*
-* Boolean XTRUE if the device is configured with MII, or XFALSE otherwise
+* Boolean TRUE if the device is configured with MII, or FALSE otherwise
*
* @note
*
-* Signature: Xboolean XEmac_mHasMii(XEmac *InstancePtr)
+* Signature: u32 XEmac_mHasMii(XEmac *InstancePtr)
*
******************************************************************************/
#define XEmac_mHasMii(InstancePtr) \
- (((InstancePtr)->ConfigPtr->HasMii == 1) ? XTRUE : XFALSE)
+ (((InstancePtr)->ConfigPtr->HasMii == 1) ? TRUE : FALSE)
/*****************************************************************************/
/**
@@ -660,16 +668,16 @@ typedef struct
*
* @return
*
-* Boolean XTRUE if the device is configured with jubmo frame capability, or
-* XFALSE otherwise
+* Boolean TRUE if the device is configured with jubmo frame capability, or
+* FALSE otherwise
*
* @note
*
-* Signature: Xboolean XEmac_mHasJumbo(XEmac *InstancePtr)
+* Signature: u32 XEmac_mHasJumbo(XEmac *InstancePtr)
*
******************************************************************************/
#define XEmac_mHasJumbo(InstancePtr) \
- (((InstancePtr)->ConfigPtr->HasJumbo == 1) ? XTRUE : XFALSE)
+ (((InstancePtr)->ConfigPtr->HasJumbo == 1) ? TRUE : FALSE)
/************************** Function Prototypes ******************************/
@@ -677,41 +685,41 @@ typedef struct
/*
* Initialization functions in xemac.c
*/
-XStatus XEmac_Initialize(XEmac *InstancePtr, Xuint16 DeviceId);
-XStatus XEmac_Start(XEmac *InstancePtr);
-XStatus XEmac_Stop(XEmac *InstancePtr);
+int XEmac_Initialize(XEmac *InstancePtr, u16 DeviceId);
+int XEmac_Start(XEmac *InstancePtr);
+int XEmac_Stop(XEmac *InstancePtr);
void XEmac_Reset(XEmac *InstancePtr);
-XEmac_Config *XEmac_LookupConfig(Xuint16 DeviceId);
+XEmac_Config *XEmac_LookupConfig(u16 DeviceId);
/*
* Diagnostic functions in xemac_selftest.c
*/
-XStatus XEmac_SelfTest(XEmac *InstancePtr);
+int XEmac_SelfTest(XEmac *InstancePtr);
/*
* Polled functions in xemac_polled.c
*/
-XStatus XEmac_PollSend(XEmac *InstancePtr, Xuint8 *BufPtr, Xuint32 ByteCount);
-XStatus XEmac_PollRecv(XEmac *InstancePtr, Xuint8 *BufPtr,
- Xuint32 *ByteCountPtr);
+int XEmac_PollSend(XEmac *InstancePtr, u8 *BufPtr, u32 ByteCount);
+int XEmac_PollRecv(XEmac *InstancePtr, u8 *BufPtr,
+ u32 *ByteCountPtr);
/*
* Interrupts with scatter-gather DMA functions in xemac_intr_dma.c
*/
-XStatus XEmac_SgSend(XEmac *InstancePtr, XBufDescriptor *BdPtr, int Delay);
-XStatus XEmac_SgRecv(XEmac *InstancePtr, XBufDescriptor *BdPtr);
-XStatus XEmac_SetPktThreshold(XEmac *InstancePtr, Xuint32 Direction,
- Xuint8 Threshold);
-XStatus XEmac_GetPktThreshold(XEmac *InstancePtr, Xuint32 Direction,
- Xuint8 *ThreshPtr);
-XStatus XEmac_SetPktWaitBound(XEmac *InstancePtr, Xuint32 Direction,
- Xuint32 TimerValue);
-XStatus XEmac_GetPktWaitBound(XEmac *InstancePtr, Xuint32 Direction,
- Xuint32 *WaitPtr);
-XStatus XEmac_SetSgRecvSpace(XEmac *InstancePtr, Xuint32 *MemoryPtr,
- Xuint32 ByteCount, void *PhyPtr);
-XStatus XEmac_SetSgSendSpace(XEmac *InstancePtr, Xuint32 *MemoryPtr,
- Xuint32 ByteCount, void *PhyPtr);
+int XEmac_SgSend(XEmac *InstancePtr, XBufDescriptor *BdPtr, int Delay);
+int XEmac_SgRecv(XEmac *InstancePtr, XBufDescriptor *BdPtr);
+int XEmac_SetPktThreshold(XEmac *InstancePtr, u32 Direction,
+ u8 Threshold);
+int XEmac_GetPktThreshold(XEmac *InstancePtr, u32 Direction,
+ u8 *ThreshPtr);
+int XEmac_SetPktWaitBound(XEmac *InstancePtr, u32 Direction,
+ u32 TimerValue);
+int XEmac_GetPktWaitBound(XEmac *InstancePtr, u32 Direction,
+ u32 *WaitPtr);
+int XEmac_SetSgRecvSpace(XEmac *InstancePtr, u32 *MemoryPtr,
+ u32 ByteCount, void *PhyPtr);
+int XEmac_SetSgSendSpace(XEmac *InstancePtr, u32 *MemoryPtr,
+ u32 ByteCount, void *PhyPtr);
void XEmac_SetSgRecvHandler(XEmac *InstancePtr, void *CallBackRef,
XEmac_SgHandler FuncPtr);
void XEmac_SetSgSendHandler(XEmac *InstancePtr, void *CallBackRef,
@@ -725,9 +733,9 @@ void XEmac_IntrHandlerDma(void *Instance
* Interrupts with direct FIFO functions in xemac_intr_fifo.c. Also used
* for simple DMA.
*/
-XStatus XEmac_FifoSend(XEmac *InstancePtr, Xuint8 *BufPtr, Xuint32 ByteCount);
-XStatus XEmac_FifoRecv(XEmac *InstancePtr, Xuint8 *BufPtr,
- Xuint32 *ByteCountPtr);
+int XEmac_FifoSend(XEmac *InstancePtr, u8 *BufPtr, u32 ByteCount);
+int XEmac_FifoRecv(XEmac *InstancePtr, u8 *BufPtr,
+ u32 *ByteCountPtr);
void XEmac_SetFifoRecvHandler(XEmac *InstancePtr, void *CallBackRef,
XEmac_FifoHandler FuncPtr);
void XEmac_SetFifoSendHandler(XEmac *InstancePtr, void *CallBackRef,
@@ -744,28 +752,28 @@ void XEmac_SetErrorHandler(XEmac *Instan
/*
* MAC configuration in xemac_options.c
*/
-XStatus XEmac_SetOptions(XEmac *InstancePtr, Xuint32 OptionFlag);
-Xuint32 XEmac_GetOptions(XEmac *InstancePtr);
-XStatus XEmac_SetMacAddress(XEmac *InstancePtr, Xuint8 *AddressPtr);
-void XEmac_GetMacAddress(XEmac *InstancePtr, Xuint8 *BufferPtr);
-XStatus XEmac_SetInterframeGap(XEmac *InstancePtr, Xuint8 Part1, Xuint8 Part2);
-void XEmac_GetInterframeGap(XEmac *InstancePtr, Xuint8 *Part1Ptr,
- Xuint8* Part2Ptr);
+int XEmac_SetOptions(XEmac *InstancePtr, u32 OptionFlag);
+u32 XEmac_GetOptions(XEmac *InstancePtr);
+int XEmac_SetMacAddress(XEmac *InstancePtr, u8 *AddressPtr);
+void XEmac_GetMacAddress(XEmac *InstancePtr, u8 *BufferPtr);
+int XEmac_SetInterframeGap(XEmac *InstancePtr, u8 Part1, u8 Part2);
+void XEmac_GetInterframeGap(XEmac *InstancePtr, u8 *Part1Ptr,
+ u8* Part2Ptr);
/*
* Multicast functions in xemac_multicast.c
*/
-XStatus XEmac_MulticastAdd(XEmac *InstancePtr, Xuint8 *AddressPtr, int Entry);
-XStatus XEmac_MulticastClear(XEmac *InstancePtr, int Entry);
+int XEmac_MulticastAdd(XEmac *InstancePtr, u8 *AddressPtr, int Entry);
+int XEmac_MulticastClear(XEmac *InstancePtr, int Entry);
/*
* PHY configuration in xemac_phy.c
*/
void XEmac_PhyReset(XEmac *InstancePtr);
-XStatus XEmac_PhyRead(XEmac *InstancePtr, Xuint32 PhyAddress,
- Xuint32 RegisterNum, Xuint16 *PhyDataPtr);
-XStatus XEmac_PhyWrite(XEmac *InstancePtr, Xuint32 PhyAddress,
- Xuint32 RegisterNum, Xuint16 PhyData);
+int XEmac_PhyRead(XEmac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 *PhyDataPtr);
+int XEmac_PhyWrite(XEmac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 PhyData);
/*
* Statistics in xemac_stats.c
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_g.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_g.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_g.c
@@ -16,6 +16,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_options.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_options.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_options.c
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -73,8 +81,8 @@
*/
typedef struct
{
- Xuint32 Option;
- Xuint32 Mask;
+ u32 Option;
+ u32 Mask;
} OptionMap;
static OptionMap OptionsTable[] =
@@ -122,12 +130,12 @@ static OptionMap OptionsTable[] =
* protection of this shared data (typically using a semaphore) is required.
*
******************************************************************************/
-XStatus XEmac_SetOptions(XEmac *InstancePtr, Xuint32 OptionsFlag)
+int XEmac_SetOptions(XEmac *InstancePtr, u32 OptionsFlag)
{
- Xuint32 ControlReg;
+ u32 ControlReg;
int Index;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED)
@@ -168,11 +176,11 @@ XStatus XEmac_SetOptions(XEmac *Instance
*/
if (OptionsFlag & XEM_POLLED_OPTION)
{
- InstancePtr->IsPolled = XTRUE;
+ InstancePtr->IsPolled = TRUE;
}
else
{
- InstancePtr->IsPolled = XFALSE;
+ InstancePtr->IsPolled = FALSE;
}
/*
@@ -180,11 +188,11 @@ XStatus XEmac_SetOptions(XEmac *Instance
*/
if (OptionsFlag & XEM_NO_SGEND_INT_OPTION)
{
- InstancePtr->IsSgEndDisable = XTRUE;
+ InstancePtr->IsSgEndDisable = TRUE;
}
else
{
- InstancePtr->IsSgEndDisable = XFALSE;
+ InstancePtr->IsSgEndDisable = FALSE;
}
return XST_SUCCESS;
@@ -210,13 +218,13 @@ XStatus XEmac_SetOptions(XEmac *Instance
* None.
*
******************************************************************************/
-Xuint32 XEmac_GetOptions(XEmac *InstancePtr)
+u32 XEmac_GetOptions(XEmac *InstancePtr)
{
- Xuint32 OptionsFlag = 0;
- Xuint32 ControlReg;
+ u32 OptionsFlag = 0;
+ u32 ControlReg;
int Index;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -282,10 +290,10 @@ Xuint32 XEmac_GetOptions(XEmac *Instance
* None.
*
******************************************************************************/
-XStatus XEmac_SetInterframeGap(XEmac *InstancePtr, Xuint8 Part1,
- Xuint8 Part2)
+int XEmac_SetInterframeGap(XEmac *InstancePtr, u8 Part1,
+ u8 Part2)
{
- Xuint32 Ifg;
+ u32 Ifg;
XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(Part1 <= XEM_IFGP_PART1_MAX);
@@ -325,14 +333,14 @@ XStatus XEmac_SetInterframeGap(XEmac *In
* output parameters.
*
******************************************************************************/
-void XEmac_GetInterframeGap(XEmac *InstancePtr, Xuint8 *Part1Ptr,
- Xuint8 *Part2Ptr)
+void XEmac_GetInterframeGap(XEmac *InstancePtr, u8 *Part1Ptr,
+ u8 *Part2Ptr)
{
- Xuint32 Ifg;
+ u32 Ifg;
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(Part1Ptr != XNULL);
- XASSERT_VOID(Part2Ptr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(Part1Ptr != NULL);
+ XASSERT_VOID(Part2Ptr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
Ifg = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET);
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr.c
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -108,8 +116,8 @@
void XEmac_SetErrorHandler(XEmac *InstancePtr, void *CallBackRef,
XEmac_ErrorHandler FuncPtr)
{
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(FuncPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(FuncPtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
InstancePtr->ErrorHandler = FuncPtr;
@@ -163,9 +171,9 @@ void XEmac_SetErrorHandler(XEmac *Instan
* This function is intended for internal use only.
*
******************************************************************************/
-void XEmac_CheckEmacError(XEmac *InstancePtr, Xuint32 IntrStatus)
+void XEmac_CheckEmacError(XEmac *InstancePtr, u32 IntrStatus)
{
- Xboolean ResetError = XFALSE;
+ u32 ResetError = FALSE;
/*
* First check for receive fifo overrun/underrun errors. Most require a
@@ -189,14 +197,14 @@ void XEmac_CheckEmacError(XEmac *Instanc
*/
InstancePtr->Stats.RecvOverrunErrors++;
InstancePtr->Stats.FifoErrors++;
- ResetError = XTRUE; /* requires a reset */
+ ResetError = TRUE; /* requires a reset */
}
if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK)
{
InstancePtr->Stats.RecvUnderrunErrors++;
InstancePtr->Stats.FifoErrors++;
- ResetError = XTRUE; /* requires a reset */
+ ResetError = TRUE; /* requires a reset */
}
/*
@@ -269,7 +277,7 @@ void XEmac_CheckEmacError(XEmac *Instanc
{
InstancePtr->Stats.XmitOverrunErrors++;
InstancePtr->Stats.FifoErrors++;
- ResetError = XTRUE;
+ ResetError = TRUE;
}
if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
@@ -277,7 +285,7 @@ void XEmac_CheckEmacError(XEmac *Instanc
{
InstancePtr->Stats.XmitUnderrunErrors++;
InstancePtr->Stats.FifoErrors++;
- ResetError = XTRUE;
+ ResetError = TRUE;
}
if (ResetError)
@@ -331,7 +339,7 @@ void XEmac_CheckFifoRecvError(XEmac *Ins
*/
if (XPF_V200A_IS_DEADLOCKED(&InstancePtr->RecvFifo))
{
- Xuint32 IntrEnable;
+ u32 IntrEnable;
InstancePtr->Stats.FifoErrors++;
@@ -379,7 +387,7 @@ void XEmac_CheckFifoSendError(XEmac *Ins
*/
if (XPF_V200A_IS_DEADLOCKED(&InstancePtr->SendFifo))
{
- Xuint32 IntrEnable;
+ u32 IntrEnable;
InstancePtr->Stats.FifoErrors++;
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_i.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_i.h.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_i.h
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -174,13 +182,13 @@ extern "C" {
*
* @note
*
-* Signature: void XEmac_mClearStruct(Xuint8 *StructPtr, unsigned int NumBytes)
+* Signature: void XEmac_mClearStruct(u8 *StructPtr, unsigned int NumBytes)
*
******************************************************************************/
#define XEmac_mClearStruct(StructPtr, NumBytes) \
{ \
int i; \
- Xuint8 *BytePtr = (Xuint8 *)(StructPtr); \
+ u8 *BytePtr = (u8 *)(StructPtr); \
for (i=0; i < (unsigned int)(NumBytes); i++) \
{ \
*BytePtr++ = 0; \
@@ -193,7 +201,7 @@ extern XEmac_Config XEmac_ConfigTable[];
/************************** Function Prototypes ******************************/
-void XEmac_CheckEmacError(XEmac *InstancePtr, Xuint32 IntrStatus);
+void XEmac_CheckEmacError(XEmac *InstancePtr, u32 IntrStatus);
void XEmac_CheckFifoRecvError(XEmac *InstancePtr);
void XEmac_CheckFifoSendError(XEmac *InstancePtr);
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_dma.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_dma.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_dma.c
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -150,13 +158,13 @@ static void HandleEmacDmaIntr(XEmac *Ins
* started.
*
******************************************************************************/
-XStatus XEmac_SgSend(XEmac *InstancePtr, XBufDescriptor *BdPtr, int Delay)
+int XEmac_SgSend(XEmac *InstancePtr, XBufDescriptor *BdPtr, int Delay)
{
- XStatus Result;
- Xuint32 BdControl;
+ int Result;
+ u32 BdControl;
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(BdPtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BdPtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -266,13 +274,13 @@ XStatus XEmac_SgSend(XEmac *InstancePtr,
* started.
*
******************************************************************************/
-XStatus XEmac_SgRecv(XEmac *InstancePtr, XBufDescriptor *BdPtr)
+int XEmac_SgRecv(XEmac *InstancePtr, XBufDescriptor *BdPtr)
{
- XStatus Result;
- Xuint32 BdControl;
+ int Result;
+ u32 BdControl;
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(BdPtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BdPtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -354,7 +362,7 @@ XStatus XEmac_SgRecv(XEmac *InstancePtr,
******************************************************************************/
void XEmac_IntrHandlerDma(void *InstancePtr)
{
- Xuint32 IntrStatus;
+ u32 IntrStatus;
XEmac *EmacPtr = (XEmac *)InstancePtr;
EmacPtr->Stats.TotalIntrs++;
@@ -447,10 +455,10 @@ void XEmac_IntrHandlerDma(void *Instance
* caused confustion.
*
******************************************************************************/
-XStatus XEmac_SetPktThreshold(XEmac *InstancePtr, Xuint32 Direction,
- Xuint8 Threshold)
+int XEmac_SetPktThreshold(XEmac *InstancePtr, u32 Direction,
+ u8 Threshold)
{
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -517,12 +525,12 @@ XStatus XEmac_SetPktThreshold(XEmac *Ins
* None.
*
******************************************************************************/
-XStatus XEmac_GetPktThreshold(XEmac *InstancePtr, Xuint32 Direction,
- Xuint8 *ThreshPtr)
+int XEmac_GetPktThreshold(XEmac *InstancePtr, u32 Direction,
+ u8 *ThreshPtr)
{
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
- XASSERT_NONVOID(ThreshPtr != XNULL);
+ XASSERT_NONVOID(ThreshPtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
if (!XEmac_mIsSgDma(InstancePtr))
@@ -583,10 +591,10 @@ XStatus XEmac_GetPktThreshold(XEmac *Ins
* None.
*
******************************************************************************/
-XStatus XEmac_SetPktWaitBound(XEmac *InstancePtr, Xuint32 Direction,
- Xuint32 TimerValue)
+int XEmac_SetPktWaitBound(XEmac *InstancePtr, u32 Direction,
+ u32 TimerValue)
{
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
XASSERT_NONVOID(TimerValue <= XEM_SGDMA_MAX_WAITBOUND);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -655,12 +663,12 @@ XStatus XEmac_SetPktWaitBound(XEmac *Ins
* None.
*
******************************************************************************/
-XStatus XEmac_GetPktWaitBound(XEmac *InstancePtr, Xuint32 Direction,
- Xuint32 *WaitPtr)
+int XEmac_GetPktWaitBound(XEmac *InstancePtr, u32 Direction,
+ u32 *WaitPtr)
{
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
- XASSERT_NONVOID(WaitPtr != XNULL);
+ XASSERT_NONVOID(WaitPtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
if (!XEmac_mIsSgDma(InstancePtr))
@@ -721,8 +729,8 @@ XStatus XEmac_GetPktWaitBound(XEmac *Ins
* components must be initialized before the memory space is set.
*
******************************************************************************/
-XStatus XEmac_SetSgRecvSpace(XEmac *InstancePtr, Xuint32 *MemoryPtr,
- Xuint32 ByteCount, void *PhyPtr)
+int XEmac_SetSgRecvSpace(XEmac *InstancePtr, u32 *MemoryPtr,
+ u32 ByteCount, void *PhyPtr)
{
XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(MemoryPtr != NULL);
@@ -768,8 +776,8 @@ XStatus XEmac_SetSgRecvSpace(XEmac *Inst
* components must be initialized before the memory space is set.
*
******************************************************************************/
-XStatus XEmac_SetSgSendSpace(XEmac *InstancePtr, Xuint32 *MemoryPtr,
- Xuint32 ByteCount, void *PhyPtr)
+int XEmac_SetSgSendSpace(XEmac *InstancePtr, u32 *MemoryPtr,
+ u32 ByteCount, void *PhyPtr)
{
XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(MemoryPtr != NULL);
@@ -886,8 +894,8 @@ void XEmac_SetSgRecvHandler(XEmac *Insta
* Asserted IsDmaSg here instead of run-time check because there is really
* no ill-effects of setting these when not configured for scatter-gather.
*/
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(FuncPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(FuncPtr != NULL);
XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -931,8 +939,8 @@ void XEmac_SetSgSendHandler(XEmac *Insta
* Asserted IsDmaSg here instead of run-time check because there is really
* no ill-effects of setting these when not configured for scatter-gather.
*/
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(FuncPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(FuncPtr != NULL);
XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -990,10 +998,10 @@ void XEmac_SetSgSendHandler(XEmac *Insta
******************************************************************************/
static void HandleDmaRecvIntr(XEmac *InstancePtr)
{
- XStatus Result;
- Xuint32 IntrStatus;
- Xuint32 NumBds;
- Xuint32 PacketsLeft;
+ int Result;
+ u32 IntrStatus;
+ u32 NumBds;
+ u32 PacketsLeft;
XBufDescriptor *BdHeadPtr;
XBufDescriptor *BdPtr;
@@ -1184,11 +1192,11 @@ static void HandleDmaRecvIntr(XEmac *Ins
******************************************************************************/
static void HandleDmaSendIntr(XEmac *InstancePtr)
{
- XStatus Result;
- Xuint32 IntrStatus;
- Xuint32 NumBds;
- Xuint32 PacketsLeft;
- Xuint32 XmitStatus;
+ int Result;
+ u32 IntrStatus;
+ u32 NumBds;
+ u32 PacketsLeft;
+ u32 XmitStatus;
int PacketStart;
XBufDescriptor *BdHeadPtr;
XBufDescriptor *BdPtr;
@@ -1373,7 +1381,7 @@ static void HandleDmaSendIntr(XEmac *Ins
******************************************************************************/
static void HandleEmacDmaIntr(XEmac *InstancePtr)
{
- Xuint32 IntrStatus;
+ u32 IntrStatus;
/*
* When configured with DMA, the EMAC generates interrupts only when errors
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_fifo.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_fifo.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_intr_fifo.c
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -118,13 +126,13 @@ static void HandleEmacFifoIntr(XEmac *In
* when reading or writing to them.
*
******************************************************************************/
-XStatus XEmac_FifoSend(XEmac *InstancePtr, Xuint8 *BufPtr, Xuint32 ByteCount)
+int XEmac_FifoSend(XEmac *InstancePtr, u8 *BufPtr, u32 ByteCount)
{
- XStatus Result;
- volatile Xuint32 StatusReg;
+ int Result;
+ volatile u32 StatusReg;
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(BufPtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufPtr != NULL);
XASSERT_NONVOID(ByteCount > XEM_HDR_SIZE); /* send at least 1 byte */
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -170,7 +178,7 @@ XStatus XEmac_FifoSend(XEmac *InstancePt
}
else
{
- Xuint32 Vacancy;
+ u32 Vacancy;
/*
* Need to make sure there is room in the data FIFO for the packet
@@ -178,7 +186,7 @@ XStatus XEmac_FifoSend(XEmac *InstancePt
* and make sure the packet will fit.
*/
Vacancy = XPF_V200A_GET_COUNT(&InstancePtr->SendFifo);
- if ((Vacancy * sizeof(Xuint32)) < ByteCount)
+ if ((Vacancy * sizeof(u32)) < ByteCount)
{
return XST_FIFO_NO_ROOM;
}
@@ -293,16 +301,16 @@ XStatus XEmac_FifoSend(XEmac *InstancePt
* when reading or writing to them.
*
******************************************************************************/
-XStatus XEmac_FifoRecv(XEmac *InstancePtr, Xuint8 *BufPtr,
- Xuint32 *ByteCountPtr)
+int XEmac_FifoRecv(XEmac *InstancePtr, u8 *BufPtr,
+ u32 *ByteCountPtr)
{
- XStatus Result;
- Xuint32 PktLength;
- Xuint32 StatusReg;
-
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(BufPtr != XNULL);
- XASSERT_NONVOID(ByteCountPtr != XNULL);
+ int Result;
+ u32 PktLength;
+ u32 StatusReg;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(BufPtr != NULL);
+ XASSERT_NONVOID(ByteCountPtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -457,7 +465,7 @@ XStatus XEmac_FifoRecv(XEmac *InstancePt
******************************************************************************/
void XEmac_IntrHandlerFifo(void *InstancePtr)
{
- Xuint32 IntrStatus;
+ u32 IntrStatus;
XEmac *EmacPtr = (XEmac *)InstancePtr;
EmacPtr->Stats.TotalIntrs++;
@@ -529,8 +537,8 @@ void XEmac_IntrHandlerFifo(void *Instanc
void XEmac_SetFifoRecvHandler(XEmac *InstancePtr, void *CallBackRef,
XEmac_FifoHandler FuncPtr)
{
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(FuncPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(FuncPtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
InstancePtr->FifoRecvHandler = FuncPtr;
@@ -569,8 +577,8 @@ void XEmac_SetFifoRecvHandler(XEmac *Ins
void XEmac_SetFifoSendHandler(XEmac *InstancePtr, void *CallBackRef,
XEmac_FifoHandler FuncPtr)
{
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(FuncPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(FuncPtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
InstancePtr->FifoSendHandler = FuncPtr;
@@ -601,7 +609,7 @@ void XEmac_SetFifoSendHandler(XEmac *Ins
******************************************************************************/
static void HandleEmacFifoIntr(XEmac *InstancePtr)
{
- Xuint32 IntrStatus;
+ u32 IntrStatus;
/*
* The EMAC generates interrupts for errors and generates the transmit
@@ -643,7 +651,7 @@ static void HandleEmacFifoIntr(XEmac *In
*/
if (IntrStatus & XEM_EIR_XMIT_DONE_MASK)
{
- Xuint32 XmitStatus;
+ u32 XmitStatus;
InstancePtr->Stats.XmitInterrupts++;
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac.c
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -70,12 +78,12 @@
/************************** Function Prototypes ******************************/
-static XStatus ConfigureDma(XEmac *InstancePtr);
-static XStatus ConfigureFifo(XEmac *InstancePtr);
+static int ConfigureDma(XEmac *InstancePtr);
+static int ConfigureFifo(XEmac *InstancePtr);
static void StubFifoHandler(void *CallBackRef);
-static void StubErrorHandler(void *CallBackRef, XStatus ErrorCode);
+static void StubErrorHandler(void *CallBackRef, int ErrorCode);
static void StubSgHandler(void *CallBackRef, XBufDescriptor *BdPtr,
- Xuint32 NumBds);
+ u32 NumBds);
/************************** Variable Definitions *****************************/
@@ -110,11 +118,11 @@ static void StubSgHandler(void *CallBack
* None.
*
******************************************************************************/
-XStatus XEmac_Initialize(XEmac *InstancePtr, Xuint16 DeviceId)
+int XEmac_Initialize(XEmac *InstancePtr, u16 DeviceId)
{
- XStatus Result;
+ int Result;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
/* Clear instance memory */
memset(InstancePtr, 0, sizeof (XEmac));
@@ -124,7 +132,7 @@ XStatus XEmac_Initialize(XEmac *Instance
* configuration info down below when initializing this component.
*/
InstancePtr->ConfigPtr = XEmac_LookupConfig(DeviceId);
- if (InstancePtr->ConfigPtr == XNULL)
+ if (InstancePtr->ConfigPtr == NULL)
{
return XST_DEVICE_NOT_FOUND;
}
@@ -136,7 +144,7 @@ XStatus XEmac_Initialize(XEmac *Instance
InstancePtr->IsStarted = 0;
/* Always default polled to false, let user configure this mode */
- InstancePtr->IsPolled = XFALSE;
+ InstancePtr->IsPolled = FALSE;
InstancePtr->FifoRecvHandler = StubFifoHandler;
InstancePtr->FifoSendHandler = StubFifoHandler;
InstancePtr->ErrorHandler = StubErrorHandler;
@@ -241,12 +249,12 @@ XStatus XEmac_Initialize(XEmac *Instance
* provide protection of this shared data (typically using a semaphore).
*
******************************************************************************/
-XStatus XEmac_Start(XEmac *InstancePtr)
+int XEmac_Start(XEmac *InstancePtr)
{
- Xuint32 ControlReg;
- XStatus Result;
+ u32 ControlReg;
+ int Result;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -400,11 +408,11 @@ XStatus XEmac_Start(XEmac *InstancePtr)
* provide protection of this shared data (typically using a semaphore).
*
******************************************************************************/
-XStatus XEmac_Stop(XEmac *InstancePtr)
+int XEmac_Stop(XEmac *InstancePtr)
{
- Xuint32 ControlReg;
+ u32 ControlReg;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -517,7 +525,7 @@ XStatus XEmac_Stop(XEmac *InstancePtr)
******************************************************************************/
void XEmac_Reset(XEmac *InstancePtr)
{
- XASSERT_VOID(InstancePtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -528,7 +536,7 @@ void XEmac_Reset(XEmac *InstancePtr)
/*
* Take the driver out of polled mode
*/
- InstancePtr->IsPolled = XFALSE;
+ InstancePtr->IsPolled = FALSE;
/*
* Reset the entire IPIF at once. If we choose someday to reset each
@@ -576,12 +584,12 @@ void XEmac_Reset(XEmac *InstancePtr)
* None.
*
******************************************************************************/
-XStatus XEmac_SetMacAddress(XEmac *InstancePtr, Xuint8 *AddressPtr)
+int XEmac_SetMacAddress(XEmac *InstancePtr, u8 *AddressPtr)
{
- Xuint32 MacAddr = 0;
+ u32 MacAddr = 0;
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(AddressPtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(AddressPtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -625,24 +633,24 @@ XStatus XEmac_SetMacAddress(XEmac *Insta
* None.
*
******************************************************************************/
-void XEmac_GetMacAddress(XEmac *InstancePtr, Xuint8 *BufferPtr)
+void XEmac_GetMacAddress(XEmac *InstancePtr, u8 *BufferPtr)
{
- Xuint32 MacAddrHi;
- Xuint32 MacAddrLo;
+ u32 MacAddrHi;
+ u32 MacAddrLo;
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(BufferPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(BufferPtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
MacAddrHi = XIo_In32(InstancePtr->BaseAddress + XEM_SAH_OFFSET);
MacAddrLo = XIo_In32(InstancePtr->BaseAddress + XEM_SAL_OFFSET);
- BufferPtr[0] = (Xuint8)(MacAddrHi >> 8);
- BufferPtr[1] = (Xuint8)MacAddrHi;
- BufferPtr[2] = (Xuint8)(MacAddrLo >> 24);
- BufferPtr[3] = (Xuint8)(MacAddrLo >> 16);
- BufferPtr[4] = (Xuint8)(MacAddrLo >> 8);
- BufferPtr[5] = (Xuint8)MacAddrLo;
+ BufferPtr[0] = (u8)(MacAddrHi >> 8);
+ BufferPtr[1] = (u8)MacAddrHi;
+ BufferPtr[2] = (u8)(MacAddrLo >> 24);
+ BufferPtr[3] = (u8)(MacAddrLo >> 16);
+ BufferPtr[4] = (u8)(MacAddrLo >> 8);
+ BufferPtr[5] = (u8)MacAddrLo;
}
/******************************************************************************/
@@ -661,9 +669,9 @@ void XEmac_GetMacAddress(XEmac *Instance
* None.
*
******************************************************************************/
-static XStatus ConfigureDma(XEmac *InstancePtr)
+static int ConfigureDma(XEmac *InstancePtr)
{
- XStatus Result;
+ int Result;
/*
* Initialize the DMA channels with their base addresses. We assume
@@ -700,9 +708,9 @@ static XStatus ConfigureDma(XEmac *Insta
* None.
*
******************************************************************************/
-static XStatus ConfigureFifo(XEmac *InstancePtr)
+static int ConfigureFifo(XEmac *InstancePtr)
{
- XStatus Result;
+ int Result;
/*
* Return status from the packet FIFOs initialization is ignored since
@@ -742,7 +750,7 @@ static XStatus ConfigureFifo(XEmac *Inst
*
******************************************************************************/
static void StubSgHandler(void *CallBackRef, XBufDescriptor *BdPtr,
- Xuint32 NumBds)
+ u32 NumBds)
{
XASSERT_VOID_ALWAYS();
}
@@ -787,7 +795,7 @@ static void StubFifoHandler(void *CallBa
* None.
*
******************************************************************************/
-static void StubErrorHandler(void *CallBackRef, XStatus ErrorCode)
+static void StubErrorHandler(void *CallBackRef, int ErrorCode)
{
XASSERT_VOID_ALWAYS();
}
@@ -803,16 +811,16 @@ static void StubErrorHandler(void *CallB
* @return
*
* A pointer to the configuration table entry corresponding to the given
-* device ID, or XNULL if no match is found.
+* device ID, or NULL if no match is found.
*
* @note
*
* None.
*
******************************************************************************/
-XEmac_Config *XEmac_LookupConfig(Xuint16 DeviceId)
+XEmac_Config *XEmac_LookupConfig(u16 DeviceId)
{
- XEmac_Config *CfgPtr = XNULL;
+ XEmac_Config *CfgPtr = NULL;
int i;
for (i=0; i < CONFIG_XILINX_ETHERNET_NUM_INSTANCES; i++)
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_l.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_l.h.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_l.h
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003-2006 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -281,20 +289,20 @@ extern "C" {
* Low-level driver macros and functions. The list below provides signatures
* to help the user use the macros.
*
-* Xuint32 XEmac_mReadReg(Xuint32 BaseAddress, int RegOffset)
-* void XEmac_mWriteReg(Xuint32 BaseAddress, int RegOffset, Xuint32 Mask)
+* u32 XEmac_mReadReg(u32 BaseAddress, int RegOffset)
+* void XEmac_mWriteReg(u32 BaseAddress, int RegOffset, u32 Mask)
*
-* void XEmac_mSetControlReg(Xuint32 BaseAddress, Xuint32 Mask)
-* void XEmac_mSetMacAddress(Xuint32 BaseAddress, Xuint8 *AddressPtr)
+* void XEmac_mSetControlReg(u32 BaseAddress, u32 Mask)
+* void XEmac_mSetMacAddress(u32 BaseAddress, u8 *AddressPtr)
*
-* void XEmac_mEnable(Xuint32 BaseAddress)
-* void XEmac_mDisable(Xuint32 BaseAddress)
+* void XEmac_mEnable(u32 BaseAddress)
+* void XEmac_mDisable(u32 BaseAddress)
*
-* Xboolean XEmac_mIsTxDone(Xuint32 BaseAddress)
-* Xboolean XEmac_mIsRxEmpty(Xuint32 BaseAddress)
+* u32 XEmac_mIsTxDone(u32 BaseAddress)
+* u32 XEmac_mIsRxEmpty(u32 BaseAddress)
*
-* void XEmac_SendFrame(Xuint32 BaseAddress, Xuint8 *FramePtr, int Size)
-* int XEmac_RecvFrame(Xuint32 BaseAddress, Xuint8 *FramePtr)
+* void XEmac_SendFrame(u32 BaseAddress, u8 *FramePtr, int Size)
+* int XEmac_RecvFrame(u32 BaseAddress, u8 *FramePtr)
*
*****************************************************************************/
@@ -366,7 +374,7 @@ extern "C" {
*****************************************************************************/
#define XEmac_mSetMacAddress(BaseAddress, AddressPtr) \
{ \
- Xuint32 MacAddr; \
+ u32 MacAddr; \
\
MacAddr = ((AddressPtr)[0] << 8) | (AddressPtr)[1]; \
XIo_Out32((BaseAddress) + XEM_SAH_OFFSET, MacAddr); \
@@ -393,7 +401,7 @@ extern "C" {
*****************************************************************************/
#define XEmac_mEnable(BaseAddress) \
{ \
- Xuint32 Control; \
+ u32 Control; \
Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
Control &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK); \
Control |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK); \
@@ -427,7 +435,7 @@ extern "C" {
*
* @param BaseAddress is the base address of the device
*
-* @return XTRUE if it is done, or XFALSE if it is not.
+* @return TRUE if it is done, or FALSE if it is not.
*
* @note None.
*
@@ -443,7 +451,7 @@ extern "C" {
*
* @param BaseAddress is the base address of the device
*
-* @return XTRUE if it is empty, or XFALSE if it is not.
+* @return TRUE if it is empty, or FALSE if it is not.
*
* @note None.
*
@@ -466,7 +474,7 @@ extern "C" {
*****************************************************************************/
#define XEmac_mPhyReset(BaseAddress) \
{ \
- Xuint32 Control; \
+ u32 Control; \
Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
Control &= ~XEM_ECR_PHY_ENABLE_MASK; \
XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
@@ -477,8 +485,8 @@ extern "C" {
/************************** Function Prototypes ******************************/
-void XEmac_SendFrame(Xuint32 BaseAddress, Xuint8 *FramePtr, int Size);
-int XEmac_RecvFrame(Xuint32 BaseAddress, Xuint8 *FramePtr);
+void XEmac_SendFrame(u32 BaseAddress, u8 *FramePtr, int Size);
+int XEmac_RecvFrame(u32 BaseAddress, u8 *FramePtr);
#ifdef __cplusplus
}
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_phy.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_phy.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emac/xemac_phy.c
@@ -17,6 +17,14 @@
*
* (c) Copyright 2003 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -79,9 +87,9 @@
******************************************************************************/
void XEmac_PhyReset(XEmac *InstancePtr)
{
- Xuint32 RegECR;
+ u32 RegECR;
- XASSERT_VOID(InstancePtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
/* Disable/reset the PHY */
RegECR = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
@@ -130,16 +138,16 @@ void XEmac_PhyReset(XEmac *InstancePtr)
* PhyRead thread.
*
******************************************************************************/
-XStatus XEmac_PhyRead(XEmac *InstancePtr, Xuint32 PhyAddress,
- Xuint32 RegisterNum, Xuint16 *PhyDataPtr)
+int XEmac_PhyRead(XEmac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 *PhyDataPtr)
{
- Xuint32 MiiControl;
- Xuint32 MiiData;
+ u32 MiiControl;
+ u32 MiiData;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(PhyAddress <= XEM_MGTCR_MAX_PHY_ADDR);
XASSERT_NONVOID(RegisterNum <= XEM_MGTCR_MAX_PHY_REG);
- XASSERT_NONVOID(PhyDataPtr != XNULL);
+ XASSERT_NONVOID(PhyDataPtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -200,7 +208,7 @@ XStatus XEmac_PhyRead(XEmac *InstancePtr
*/
MiiData = XIo_In32(InstancePtr->BaseAddress + XEM_MGTDR_OFFSET);
- *PhyDataPtr = (Xuint16)MiiData;
+ *PhyDataPtr = (u16)MiiData;
return XST_SUCCESS;
}
@@ -242,12 +250,12 @@ XStatus XEmac_PhyRead(XEmac *InstancePtr
* PhyWrite thread.
*
******************************************************************************/
-XStatus XEmac_PhyWrite(XEmac *InstancePtr, Xuint32 PhyAddress,
- Xuint32 RegisterNum, Xuint16 PhyData)
+int XEmac_PhyWrite(XEmac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 PhyData)
{
- Xuint32 MiiControl;
+ u32 MiiControl;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(PhyAddress <= XEM_MGTCR_MAX_PHY_ADDR);
XASSERT_NONVOID(RegisterNum <= XEM_MGTCR_MAX_PHY_REG);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -274,7 +282,7 @@ XStatus XEmac_PhyWrite(XEmac *InstancePt
* Set up the MII data register first. Write the 16-bit input
* value to the 32-bit data register.
*/
- XIo_Out32(InstancePtr->BaseAddress + XEM_MGTDR_OFFSET, (Xuint32)PhyData);
+ XIo_Out32(InstancePtr->BaseAddress + XEM_MGTDR_OFFSET, (u32)PhyData);
/*
* Now set up the MII control register. We set up a control
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/adapter.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/adapter.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/adapter.c
@@ -145,7 +145,7 @@ static spinlock_t reset_lock = SPIN_LOCK
/* Helper function to determine if a given XEmac error warrants a reset. */
extern inline int
-status_requires_reset(XStatus s)
+status_requires_reset(int s)
{
return (s == XST_DMA_ERROR || s == XST_FIFO_ERROR ||
s == XST_RESET_ERROR || s == XST_DMA_SG_NO_LIST ||
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.c
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -94,7 +110,7 @@
* None
*
******************************************************************************/
-XStatus XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId)
+int XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId)
{
XEmacLite_Config *EmacLiteConfigPtr; /* Pointer to Configuration data. */
@@ -107,7 +123,7 @@ XStatus XEmacLite_Initialize(XEmacLite *
* Zero the provided instance memory
*/
- //XENV_MEM_FILL(InstancePtr, 0, sizeof(XEmacLite));
+ //memset(InstancePtr, 0, sizeof(XEmacLite));
memset(InstancePtr, 0, sizeof(XEmacLite));
/*
@@ -173,7 +189,7 @@ XStatus XEmacLite_Initialize(XEmacLite *
* frame is transmitted.
*
******************************************************************************/
-XStatus XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount)
+int XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount)
{
u32 Register;
u32 BaseAddress;
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.h.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite.h
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -245,21 +261,21 @@ typedef struct
/*
* Initialization functions in xemaclite.c
*/
-XStatus XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId);
+int XEmacLite_Initialize(XEmacLite *InstancePtr, u16 DeviceId);
void XEmacLite_SetMacAddress(XEmacLite *InstancePtr, u8 *AddressPtr);
u32 XEmacLite_TxBufferAvailable(XEmacLite *InstancePtr);
void XEmacLite_FlushReceive(XEmacLite *InstancePtr);
XEmacLite_Config *XEmacLite_LookupConfig(u16 DeviceId);
-XStatus XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount);
+int XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount);
u16 XEmacLite_Recv(XEmacLite *InstancePtr, u8 *FramePtr);
/*
* Interrupt driven functions in xemaclite_intr.c
*/
-XStatus XEmacLite_EnableInterrupts(XEmacLite *InstancePtr);
+int XEmacLite_EnableInterrupts(XEmacLite *InstancePtr);
void XEmacLite_DisableInterrupts(XEmacLite *InstancePtr);
void XEmacLite_InterruptHandler(void *InstancePtr);
@@ -272,6 +288,6 @@ void XEmacLite_SetSendHandler(XEmacLite
/*
* Selftest function in xemaclite_selftest.c
*/
-XStatus XEmacLite_SelfTest(XEmacLite *InstancePtr);
+int XEmacLite_SelfTest(XEmacLite *InstancePtr);
#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_g.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_g.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_g.c
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_i.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_i.h.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_i.h
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/******************************************************************************/
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_intr.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_intr.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_intr.c
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -75,7 +91,7 @@
* None
*
******************************************************************************/
-XStatus XEmacLite_EnableInterrupts(XEmacLite *InstancePtr)
+int XEmacLite_EnableInterrupts(XEmacLite *InstancePtr)
{
u32 Register;
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.c
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.h.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_l.h
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_selftest.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_selftest.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xemaclite_selftest.c
@@ -17,6 +17,22 @@
*
* (c) Copyright 2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -77,7 +93,7 @@
* None.
*
******************************************************************************/
-XStatus XEmacLite_SelfTest(XEmacLite *InstancePtr)
+int XEmacLite_SelfTest(XEmacLite *InstancePtr)
{
u32 BaseAddress;
u8 i;
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.c.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.c
@@ -29,6 +29,22 @@
*
* (c) Copyright 2002-2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* You should have received a copy of the GNU General Public License along
@@ -139,7 +155,7 @@
/************************** Function Prototypes ******************************/
-static XStatus IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
+static int IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
/******************************************************************************
*
@@ -197,10 +213,10 @@ static XStatus IpIntrSelfTest(u32 RegBas
*/
#define XIIF_V123B_MAX_REG_BIT_COUNT 32
-XStatus
+int
XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
{
- XStatus Status;
+ int Status;
/* assert to verify arguments are valid */
@@ -270,7 +286,7 @@ XIpIfV123b_SelfTest(u32 RegBaseAddress,
* None.
*
******************************************************************************/
-static XStatus
+static int
IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
{
/* ensure that the IP interrupt interrupt enable register is zero
Index: software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.h.orig
+++ software/linux-2.6.x-petalogix/drivers/net/xilinx_emaclite/xipif_v1_23_b.h
@@ -29,6 +29,22 @@
*
* (c) Copyright 2002-2004 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* You should have received a copy of the GNU General Public License along
@@ -758,6 +774,6 @@
/*
* Initialization Functions
*/
-XStatus XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth);
+int XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth);
#endif /* end of protection macro */
Index: software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile
===================================================================
--- software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile.orig
+++ software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile
@@ -25,6 +25,7 @@ obj-y += $(platobj-y) $(platobj-m)
# the device struct initialiser macros and find the real dependencies
# on the CONFIG_XILINX_ macros, when we use macro string substitution
#
+$(obj)/built-in.o: .config
$(obj)/xsysace.o: .config
$(obj)/xuartlite.o: .config
$(obj)/x16550.o: .config
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/adapter.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/adapter.c.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/adapter.c
@@ -105,7 +105,7 @@ struct xspi_instance {
static DECLARE_MUTEX(cfg_sem);
-static int convert_status(XStatus status)
+static int convert_status(int status)
{
switch (status) {
case XST_SUCCESS:
@@ -138,7 +138,7 @@ static irqreturn_t xspi_isr(int irq, voi
* XST_SPI_TRANSMIT_UNDERRUN,
* XST_SPI_SLAVE_MODE_FAULT - should not happen: the driver doesn't support slave mode.
*/
-static void xspi_status_handler(void *CallBackRef, Xuint32 StatusEvent,
+static void xspi_status_handler(void *CallBackRef, u32 StatusEvent,
unsigned int ByteCount)
{
struct xspi_instance *dev = (struct xspi_instance *) CallBackRef;
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.c.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.c
@@ -17,6 +17,30 @@
*
* (c) Copyright 2002-2005 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -66,7 +90,7 @@
/************************** Function Prototypes ******************************/
-static void StubStatusHandler(void *CallBackRef, XStatus StatusEvent,
+static void StubStatusHandler(void *CallBackRef, int StatusEvent,
unsigned int ByteCount);
/************************** Variable Definitions *****************************/
@@ -110,10 +134,10 @@ static void StubStatusHandler(void *Call
* None.
*
******************************************************************************/
-XStatus XSpi_CfgInitialize(XSpi *InstancePtr, XSpi_Config *Config,
- Xuint32 EffectiveAddr)
+int XSpi_CfgInitialize(XSpi *InstancePtr, XSpi_Config *Config,
+ u32 EffectiveAddr)
{
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
/*
* If the device is started, disallow the initialize and return a status
@@ -129,13 +153,13 @@ XStatus XSpi_CfgInitialize(XSpi *Instanc
* Set some default values
*/
InstancePtr->IsStarted = 0;
- InstancePtr->IsBusy = XFALSE;
+ InstancePtr->IsBusy = FALSE;
InstancePtr->BaseAddr = EffectiveAddr;
InstancePtr->StatusHandler = StubStatusHandler;
- InstancePtr->SendBufferPtr = XNULL;
- InstancePtr->RecvBufferPtr = XNULL;
+ InstancePtr->SendBufferPtr = NULL;
+ InstancePtr->RecvBufferPtr = NULL;
InstancePtr->RequestedBytes = 0;
InstancePtr->RemainingBytes = 0;
InstancePtr->HasFifos = Config->HasFifos;
@@ -187,11 +211,11 @@ XStatus XSpi_CfgInitialize(XSpi *Instanc
* None.
*
******************************************************************************/
-XStatus XSpi_Start(XSpi *InstancePtr)
+int XSpi_Start(XSpi *InstancePtr)
{
- Xuint16 ControlReg;
+ u16 ControlReg;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -266,11 +290,11 @@ XStatus XSpi_Start(XSpi *InstancePtr)
* semaphore).
*
******************************************************************************/
-XStatus XSpi_Stop(XSpi *InstancePtr)
+int XSpi_Stop(XSpi *InstancePtr)
{
- Xuint16 ControlReg;
+ u16 ControlReg;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -328,7 +352,7 @@ XStatus XSpi_Stop(XSpi *InstancePtr)
******************************************************************************/
void XSpi_Reset(XSpi *InstancePtr)
{
- XASSERT_VOID(InstancePtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -420,18 +444,18 @@ void XSpi_Reset(XSpi *InstancePtr)
* no two threads are transferring data on the SPI bus at the same time.
*
******************************************************************************/
-XStatus XSpi_Transfer(XSpi *InstancePtr, Xuint8* SendBufPtr,
- Xuint8 *RecvBufPtr, unsigned int ByteCount)
+int XSpi_Transfer(XSpi *InstancePtr, u8* SendBufPtr,
+ u8 *RecvBufPtr, unsigned int ByteCount)
{
- Xuint16 ControlReg;
- Xuint8 StatusReg;
- Xuint32 IntrEnable;
+ u16 ControlReg;
+ u8 StatusReg;
+ u32 IntrEnable;
/*
* The RecvBufPtr argument can be null
*/
- XASSERT_NONVOID(InstancePtr != XNULL);
- XASSERT_NONVOID(SendBufPtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(SendBufPtr != NULL);
XASSERT_NONVOID(ByteCount > 0);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
@@ -488,7 +512,7 @@ XStatus XSpi_Transfer(XSpi *InstancePtr,
* Set the busy flag, which will be cleared in the Isr when the transfer
* is entirely done.
*/
- InstancePtr->IsBusy = XTRUE;
+ InstancePtr->IsBusy = TRUE;
/*
* Set up buffer pointers
@@ -577,12 +601,12 @@ XStatus XSpi_Transfer(XSpi *InstancePtr,
* has no affect when the device is configured as a slave.
*
******************************************************************************/
-XStatus XSpi_SetSlaveSelect(XSpi *InstancePtr, Xuint32 SlaveMask)
+int XSpi_SetSlaveSelect(XSpi *InstancePtr, u32 SlaveMask)
{
int NumAsserted;
int Index;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -645,11 +669,11 @@ XStatus XSpi_SetSlaveSelect(XSpi *Instan
* None.
*
******************************************************************************/
-Xuint32 XSpi_GetSlaveSelect(XSpi *InstancePtr)
+u32 XSpi_GetSlaveSelect(XSpi *InstancePtr)
{
- Xuint32 SsReg;
+ u32 SsReg;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
SsReg = XIo_In32(InstancePtr->BaseAddr + XSP_SSR_OFFSET);
@@ -713,8 +737,8 @@ Xuint32 XSpi_GetSlaveSelect(XSpi *Instan
void XSpi_SetStatusHandler(XSpi *InstancePtr, void *CallBackRef,
XSpi_StatusHandler FuncPtr)
{
- XASSERT_VOID(InstancePtr != XNULL);
- XASSERT_VOID(FuncPtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(FuncPtr != NULL);
XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
InstancePtr->StatusHandler = FuncPtr;
@@ -741,7 +765,7 @@ void XSpi_SetStatusHandler(XSpi *Instanc
* None.
*
******************************************************************************/
-static void StubStatusHandler(void *CallBackRef, XStatus StatusEvent,
+static void StubStatusHandler(void *CallBackRef, int StatusEvent,
unsigned int ByteCount)
{
XASSERT_VOID_ALWAYS();
@@ -798,10 +822,10 @@ static void StubStatusHandler(void *Call
void XSpi_InterruptHandler(void *InstancePtr)
{
XSpi *SpiPtr = (XSpi *)InstancePtr;
- Xuint32 IntrStatus;
+ u32 IntrStatus;
unsigned int BytesDone; /* number of bytes done so far */
- XASSERT_VOID(InstancePtr != XNULL);
+ XASSERT_VOID(InstancePtr != NULL);
/*
* Update the stats for the number of interrupts
@@ -847,9 +871,9 @@ void XSpi_InterruptHandler(void *Instanc
if (IntrStatus & XSP_INTR_TX_EMPTY_MASK)
{
- Xuint16 ControlReg;
- Xuint8 StatusReg;
- Xuint8 TempData;
+ u16 ControlReg;
+ u8 StatusReg;
+ u8 TempData;
/*
* A transmit has just completed. Process received data and check
@@ -874,7 +898,7 @@ void XSpi_InterruptHandler(void *Instanc
SpiPtr->Stats.BytesTransferred++;
TempData = XIo_In8(SpiPtr->BaseAddr + XSP_DRR_OFFSET);
- if (SpiPtr->RecvBufferPtr != XNULL)
+ if (SpiPtr->RecvBufferPtr != NULL)
{
*SpiPtr->RecvBufferPtr++ = TempData;
}
@@ -914,7 +938,7 @@ void XSpi_InterruptHandler(void *Instanc
}
else
{
- Xuint32 IntrEnable;
+ u32 IntrEnable;
/*
* Select the slave on the SPI bus when the transfer is complete,
@@ -932,7 +956,7 @@ void XSpi_InterruptHandler(void *Instanc
XIIF_V123B_WRITE_IIER(SpiPtr->BaseAddr,
IntrEnable & ~XSP_INTR_TX_EMPTY_MASK);
- SpiPtr->IsBusy = XFALSE;
+ SpiPtr->IsBusy = FALSE;
SpiPtr->StatusHandler(SpiPtr->StatusRef,
XST_SPI_TRANSFER_DONE,
@@ -992,7 +1016,7 @@ void XSpi_InterruptHandler(void *Instanc
******************************************************************************/
void XSpi_Abort(XSpi *InstancePtr)
{
- Xuint16 ControlReg;
+ u16 ControlReg;
/*
* Deselect the slave on the SPI bus to abort a transfer, this must be
@@ -1024,6 +1048,6 @@ void XSpi_Abort(XSpi *InstancePtr)
InstancePtr->RemainingBytes = 0;
InstancePtr->RequestedBytes = 0;
- InstancePtr->IsBusy = XFALSE;
+ InstancePtr->IsBusy = FALSE;
}
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.h.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi.h
@@ -17,6 +17,30 @@
*
* (c) Copyright 2002-2005 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -256,7 +280,7 @@ extern "C" {
* transferred. This may be less than the number of bytes
* requested if the status event indicates an error.
*/
-typedef void (*XSpi_StatusHandler)(void *CallBackRef, Xuint32 StatusEvent,
+typedef void (*XSpi_StatusHandler)(void *CallBackRef, u32 StatusEvent,
unsigned int ByteCount);
/**
@@ -264,12 +288,12 @@ typedef void (*XSpi_StatusHandler)(void
*/
typedef struct
{
- Xuint32 ModeFaults; /**< Number of mode fault errors */
- Xuint32 XmitUnderruns; /**< Number of transmit underruns */
- Xuint32 RecvOverruns; /**< Number of receive overruns */
- Xuint32 SlaveModeFaults; /**< Number of selects as a slave while disabled */
- Xuint32 BytesTransferred; /**< Number of bytes transferred */
- Xuint32 NumInterrupts; /**< Number of transmit/receive interrupts */
+ u32 ModeFaults; /**< Number of mode fault errors */
+ u32 XmitUnderruns; /**< Number of transmit underruns */
+ u32 RecvOverruns; /**< Number of receive overruns */
+ u32 SlaveModeFaults; /**< Number of selects as a slave while disabled */
+ u32 BytesTransferred; /**< Number of bytes transferred */
+ u32 NumInterrupts; /**< Number of transmit/receive interrupts */
} XSpi_Stats;
/**
@@ -277,13 +301,13 @@ typedef struct
*/
typedef struct
{
- Xuint16 DeviceId; /**< Unique ID of device */
- Xuint32 BaseAddress; /**< Base address of the device */
+ u16 DeviceId; /**< Unique ID of device */
+ u32 BaseAddress; /**< Base address of the device */
/* Device capabilities */
- Xboolean HasFifos; /**< Does device have FIFOs? */
- Xboolean SlaveOnly; /**< Is the device slave only? */
- Xuint8 NumSlaveBits; /**< Number of slave select bits on the device */
+ u32 HasFifos; /**< Does device have FIFOs? */
+ u32 SlaveOnly; /**< Is the device slave only? */
+ u8 NumSlaveBits; /**< Number of slave select bits on the device */
} XSpi_Config;
/**
@@ -294,20 +318,20 @@ typedef struct
typedef struct
{
XSpi_Stats Stats; /* Statistics */
- Xuint32 BaseAddr; /* Base address of device (IPIF) */
- Xuint32 IsReady; /* Device is initialized and ready */
- Xuint32 IsStarted; /* Device has been started */
- Xboolean HasFifos; /* Device is configured with FIFOs or not */
- Xboolean SlaveOnly; /* Device is configured to be slave only */
- Xuint8 NumSlaveBits; /* Number of slave selects for this device */
- Xuint32 SlaveSelectMask; /* Mask that matches the number of SS bits */
- Xuint32 SlaveSelectReg; /* Slave select register */
+ u32 BaseAddr; /* Base address of device (IPIF) */
+ u32 IsReady; /* Device is initialized and ready */
+ u32 IsStarted; /* Device has been started */
+ u32 HasFifos; /* Device is configured with FIFOs or not */
+ u32 SlaveOnly; /* Device is configured to be slave only */
+ u8 NumSlaveBits; /* Number of slave selects for this device */
+ u32 SlaveSelectMask; /* Mask that matches the number of SS bits */
+ u32 SlaveSelectReg; /* Slave select register */
- Xuint8 *SendBufferPtr; /* Buffer to send (state) */
- Xuint8 *RecvBufferPtr; /* Buffer to receive (state) */
+ u8 *SendBufferPtr; /* Buffer to send (state) */
+ u8 *RecvBufferPtr; /* Buffer to receive (state) */
unsigned int RequestedBytes; /* Number of bytes to transfer (state) */
unsigned int RemainingBytes; /* Number of bytes left to transfer (state) */
- Xboolean IsBusy; /* A transfer is in progress (state) */
+ u32 IsBusy; /* A transfer is in progress (state) */
XSpi_StatusHandler StatusHandler;
void *StatusRef; /* Callback reference for status handler */
@@ -322,24 +346,24 @@ typedef struct
/*
* Initialization functions in xspi_sinit.c
*/
-XStatus XSpi_Initialize(XSpi *InstancePtr, Xuint16 DeviceId);
-XSpi_Config *XSpi_LookupConfig(Xuint16 DeviceId);
+int XSpi_Initialize(XSpi *InstancePtr, u16 DeviceId);
+XSpi_Config *XSpi_LookupConfig(u16 DeviceId);
/*
* required functions, in xspi.c
*/
-XStatus XSpi_CfgInitialize(XSpi *InstancePtr, XSpi_Config *Config,
- Xuint32 EffectiveAddr);
+int XSpi_CfgInitialize(XSpi *InstancePtr, XSpi_Config *Config,
+ u32 EffectiveAddr);
-XStatus XSpi_Start(XSpi *InstancePtr);
-XStatus XSpi_Stop(XSpi *InstancePtr);
+int XSpi_Start(XSpi *InstancePtr);
+int XSpi_Stop(XSpi *InstancePtr);
void XSpi_Reset(XSpi *InstancePtr);
-XStatus XSpi_SetSlaveSelect(XSpi *InstancePtr, Xuint32 SlaveMask);
-Xuint32 XSpi_GetSlaveSelect(XSpi *InstancePtr);
+int XSpi_SetSlaveSelect(XSpi *InstancePtr, u32 SlaveMask);
+u32 XSpi_GetSlaveSelect(XSpi *InstancePtr);
-XStatus XSpi_Transfer(XSpi *InstancePtr, Xuint8 *SendBufPtr, Xuint8 *RecvBufPtr,
+int XSpi_Transfer(XSpi *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr,
unsigned int ByteCount);
void XSpi_SetStatusHandler(XSpi *InstancePtr, void *CallBackRef,
@@ -350,7 +374,7 @@ void XSpi_InterruptHandler(void *Instanc
/*
* functions for selftest, in xspi_selftest.c
*/
-XStatus XSpi_SelfTest(XSpi *InstancePtr);
+int XSpi_SelfTest(XSpi *InstancePtr);
/*
* functions for statistics, in xspi_stats.c
@@ -361,8 +385,8 @@ void XSpi_ClearStats(XSpi *InstancePtr);
/*
* functions for options, in xspi_options.c
*/
-XStatus XSpi_SetOptions(XSpi *InstancePtr, Xuint32 Options);
-Xuint32 XSpi_GetOptions(XSpi *InstancePtr);
+int XSpi_SetOptions(XSpi *InstancePtr, u32 Options);
+u32 XSpi_GetOptions(XSpi *InstancePtr);
#ifdef __cplusplus
}
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_i.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_i.h.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_i.h
@@ -17,6 +17,30 @@
*
* (c) Copyright 2002 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_l.h
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_l.h.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_l.h
@@ -17,6 +17,30 @@
*
* (c) Copyright 2002 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -114,18 +138,18 @@ extern "C" {
* Low-level driver macros. The list below provides signatures to help the
* user use the macros.
*
-* void XSpi_mSetControlReg(Xuint32 BaseAddress, Xuint16 Mask)
-* Xuint16 XSpi_mGetControlReg(Xuint32 BaseAddress)
-* Xuint8 XSpi_mGetStatusReg(Xuint32 BaseAddress)
+* void XSpi_mSetControlReg(u32 BaseAddress, u16 Mask)
+* u16 XSpi_mGetControlReg(u32 BaseAddress)
+* u8 XSpi_mGetStatusReg(u32 BaseAddress)
*
-* void XSpi_mSetSlaveSelectReg(Xuint32 BaseAddress, Xuint32 Mask)
-* Xuint32 XSpi_mGetSlaveSelectReg(Xuint32 BaseAddress)
+* void XSpi_mSetSlaveSelectReg(u32 BaseAddress, u32 Mask)
+* u32 XSpi_mGetSlaveSelectReg(u32 BaseAddress)
*
-* void XSpi_mEnable(Xuint32 BaseAddress)
-* void XSpi_mDisable(Xuint32 BaseAddress)
+* void XSpi_mEnable(u32 BaseAddress)
+* void XSpi_mDisable(u32 BaseAddress)
*
-* void XSpi_mSendByte(Xuint32 BaseAddress, Xuint8 Data);
-* Xuint8 XSpi_mRecvByte(Xuint32 BaseAddress);
+* void XSpi_mSendByte(u32 BaseAddress, u8 Data);
+* u8 XSpi_mRecvByte(u32 BaseAddress);
*
*****************************************************************************/
@@ -232,7 +256,7 @@ extern "C" {
*****************************************************************************/
#define XSpi_mEnable(BaseAddress) \
{ \
- Xuint16 Control; \
+ u16 Control; \
Control = XSpi_mGetControlReg((BaseAddress)); \
Control |= XSP_CR_ENABLE_MASK; \
Control &= ~XSP_CR_TRANS_INHIBIT_MASK; \
Index: software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_options.c
===================================================================
--- software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_options.c.orig
+++ software/linux-2.6.x-petalogix/drivers/char/xilinx_spi/xspi_options.c
@@ -17,6 +17,30 @@
*
* (c) Copyright 2002 Xilinx Inc.
* All rights reserved.
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+* 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.
+*
+* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
******************************************************************************/
/*****************************************************************************/
@@ -64,8 +88,8 @@
*/
typedef struct
{
- Xuint32 Option;
- Xuint16 Mask;
+ u32 Option;
+ u16 Mask;
} OptionsMap;
static OptionsMap OptionsTable[] =
@@ -109,12 +133,12 @@ static OptionsMap OptionsTable[] =
* semaphore).
*
******************************************************************************/
-XStatus XSpi_SetOptions(XSpi *InstancePtr, Xuint32 Options)
+int XSpi_SetOptions(XSpi *InstancePtr, u32 Options)
{
- Xuint16 ControlReg;
- Xuint32 Index;
+ u16 ControlReg;
+ u32 Index;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
@@ -183,13 +207,13 @@ XStatus XSpi_SetOptions(XSpi *InstancePt
* None.
*
******************************************************************************/
-Xuint32 XSpi_GetOptions(XSpi *InstancePtr)
+u32 XSpi_GetOptions(XSpi *InstancePtr)
{
- Xuint32 OptionsFlag = 0;
- Xuint16 ControlReg;
- Xuint32 Index;
+ u32 OptionsFlag = 0;
+ u16 ControlReg;
+ u32 Index;
- XASSERT_NONVOID(InstancePtr != XNULL);
+ XASSERT_NONVOID(InstancePtr != NULL);
XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
/*
---
software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile | 2
software/linux-2.6.x-petalogix/arch/microblaze/platform/common/xlltemac.c | 80
software/linux-2.6.x-petalogix/drivers/net/Kconfig | 6
software/linux-2.6.x-petalogix/drivers/net/Makefile | 1
software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/Makefile | 10
software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac.c | 1378 ++++
software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac.h | 777 ++
software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_control.c | 671 +
software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_hw.h | 554 +
software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_main.c | 3411 ++++++++++
software/linux-2.6.x-petalogix/include/asm-microblaze/delay.h | 55
software/linux-2.6.x-petalogix/include/linux/skbuff.h | 6
software/linux-2.6.x-petalogix/include/linux/xilinx_devices.h | 19
13 files changed, 6969 insertions(+), 1 deletion(-)
Index: trunk/software/linux-2.6.x-petalogix/include/linux/xilinx_devices.h
===================================================================
--- trunk.orig/software/linux-2.6.x-petalogix/include/linux/xilinx_devices.h
+++ trunk/software/linux-2.6.x-petalogix/include/linux/xilinx_devices.h
@@ -74,6 +74,25 @@ struct xtemac_platform_data {
#define XTEMAC_DMA_SIMPLE 2 /* simple 2 channel DMA */
#define XTEMAC_DMA_SGDMA 3 /* scatter gather DMA */
+
+struct xlltemac_platform_data {
+ u8 tx_csum;
+ u8 rx_csum;
+ u8 phy_type;
+ u8 dcr_host;
+ u8 ll_dev_type;
+ u32 ll_dev_baseaddress;
+ u32 ll_dev_dma_rx_irq;
+ u32 ll_dev_dma_tx_irq;
+ u32 ll_dev_fifo_irq;
+
+ u8 mac_addr[6];
+};
+
+/* LocalLink TYPE Enumerations */
+#define XPAR_LL_FIFO 1
+#define XPAR_LL_DMA 2
+
/*- SPI -*/
struct xspi_platform_data {
Index: trunk/software/linux-2.6.x-petalogix/include/linux/skbuff.h
===================================================================
--- trunk.orig/software/linux-2.6.x-petalogix/include/linux/skbuff.h
+++ trunk/software/linux-2.6.x-petalogix/include/linux/skbuff.h
@@ -957,6 +957,12 @@ static inline void skb_reserve(struct sk
skb->tail += len;
}
+/* Back port from newer kernel version, in support of xilinx ll_temac driver */
+static inline int skb_transport_offset(const struct sk_buff *skb)
+{
+ return skb->h.raw - skb->data;
+}
+
/*
* CPUs often take a performance hit when accessing unaligned memory
* locations. The actual performance hit varies, it can be small if the
Index: trunk/software/linux-2.6.x-petalogix/arch/microblaze/platform/common/xlltemac.c
===================================================================
--- /dev/null
+++ trunk/software/linux-2.6.x-petalogix/arch/microblaze/platform/common/xlltemac.c
@@ -0,0 +1,80 @@
+/*
+ * arch/microblaze/platform/xlltemac.c
+ *
+ * platform device initialisation for Xilinx LLTEMAC devices
+ * Copyright 2007 PetaLogix
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/autoconf.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/xilinx_devices.h>
+
+/* Generic XLLTEMAC platform_device initialiser macro.*/
+#define XILINX_LLTEMAC_PLATFORM_INITIALISER(n) \
+{ \
+ .name = "xilinx_lltemac", \
+ .id = (n), \
+ .num_resources = 2, \
+ .resource = (struct resource[]) { \
+ { \
+ .start = CONFIG_XILINX_LLTEMAC_##n##_BASEADDR,\
+ .end = CONFIG_XILINX_LLTEMAC_##n##_HIGHADDR,\
+ .flags = IORESOURCE_MEM \
+ }, \
+ { \
+ .start = CONFIG_XILINX_LLTEMAC_##n##_IRQ, \
+ .end = CONFIG_XILINX_LLTEMAC_##n##_IRQ, \
+ .flags = IORESOURCE_IRQ, \
+ } \
+ }, \
+ .dev.platform_data = &(struct xlltemac_platform_data) { \
+ .tx_csum = CONFIG_XILINX_LLTEMAC_##n##_TXCSUM, \
+ .rx_csum = CONFIG_XILINX_LLTEMAC_##n##_RXCSUM, \
+ .phy_type = CONFIG_XILINX_LLTEMAC_##n##_PHY_TYPE, \
+ .ll_dev_type = CONFIG_XILINX_LLTEMAC_##n##_LLINK_TYPE, \
+ .ll_dev_baseaddress = CONFIG_XILINX_LLTEMAC_##n##_LLINK_SDMA_BASEADDR, \
+ .ll_dev_dma_rx_irq = CONFIG_XILINX_LLTEMAC_##n##_LLINK_DMARX_INTR, \
+ .ll_dev_dma_tx_irq = CONFIG_XILINX_LLTEMAC_##n##_LLINK_DMATX_INTR, \
+ /* locally administered default address */ \
+ .mac_addr = {0x00, 0x0A, 0x35, 5, 5, ((n+1))<<3}, \
+ } \
+}
+
+static struct platform_device xilinx_lltemac_device[]= {
+#ifdef CONFIG_XILINX_LLTEMAC_0_BASEADDR
+XILINX_LLTEMAC_PLATFORM_INITIALISER(0),
+#endif
+#ifdef CONFIG_XILINX_LLTEMAC_1_BASEADDR
+XILINX_LLTEMAC_PLATFORM_INITIALISER(1),
+#endif
+#ifdef CONFIG_XILINX_LLTEMAC_2_BASEADDR
+XILINX_LLTEMAC_PLATFORM_INITIALISER(2),
+#endif
+#ifdef CONFIG_XILINX_LLTEMAC_3_BASEADDR
+XILINX_LLTEMAC_PLATFORM_INITIALISER(3),
+#endif
+#ifdef CONFIG_XILINX_LLTEMAC_4_BASEADDR
+XILINX_LLTEMAC_PLATFORM_INITIALISER(4),
+#endif
+#ifdef CONFIG_XILINX_LLTEMAC_5_BASEADDR
+XILINX_LLTEMAC_PLATFORM_INITIALISER(5),
+#endif
+};
+
+static int __init xlltemac_platform_init(void)
+{
+ int i;
+
+ for(i=0;i<ARRAY_SIZE(xilinx_lltemac_device); i++) {
+ platform_device_register(&xilinx_lltemac_device[i]);
+ }
+
+ return 0;
+}
+
+device_initcall(xlltemac_platform_init);
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/Kconfig
===================================================================
--- trunk.orig/software/linux-2.6.x-petalogix/drivers/net/Kconfig
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/Kconfig
@@ -1956,6 +1956,12 @@ endmenu
menu "Ethernet (1000 Mbit)"
depends on !UML
+config XILINX_LLTEMAC
+ tristate "Xilinx 10/100/1000 LL TEMAC support"
+ select NEED_XILINX_LLDMA
+ help
+ This driver supports the Xilinx GigaBit LL_TEMAC core
+
config ACENIC
tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
depends on PCI
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/Makefile
===================================================================
--- trunk.orig/software/linux-2.6.x-petalogix/drivers/net/Makefile
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/Makefile
@@ -216,6 +216,7 @@ obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000
obj-$(CONFIG_ETH_KS8695) += ks8695/
obj-$(CONFIG_XILINX_EMAC) += xilinx_emac/
obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite/
+obj-$(CONFIG_XILINX_LLTEMAC) += xilinx_lltemac/
obj-$(CONFIG_NETCONSOLE) += netconsole.o
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac.h
===================================================================
--- /dev/null
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac.h
@@ -0,0 +1,777 @@
+/* $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 2005-2007 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac.h
+ *
+ * The Xilinx Tri-Mode Ethernet driver component. This driver supports the
+ * Virtex-5(TM) and Virtex-4(TM) 10/100/1000 MAC (TEMAC).
+ *
+ * For a full description of TEMAC features, please see the hardware spec. This driver
+ * supports the following features:
+ * - Memory mapped access to host interface registers
+ * - Virtual memory support
+ * - Unicast, broadcast, and multicast receive address filtering
+ * - Full duplex operation (half duplex not supported)
+ * - Automatic source address insertion or overwrite (programmable)
+ * - Automatic PAD & FCS insertion and stripping (programmable)
+ * - Flow control
+ * - VLAN frame support
+ * - Pause frame support
+ * - Jumbo frame support
+ * - Checksum offload
+ *
+ * <h2>Driver Description</h2>
+ *
+ * The device driver enables higher layer software (e.g., an application) to
+ * configure a TEMAC channel. It is intended that this driver be used in
+ * cooperation with another driver (FIFO or DMA) for data communication. This
+ * device driver can support multiple devices even when those devices have
+ * significantly different configurations.
+ *
+ * <h2>Initialization & Configuration</h2>
+ *
+ * The XLlTemac_Config structure can be used by the driver to configure itself.
+ * This configuration structure is typically created by the tool-chain based on
+ * hardware build properties, although, other methods are allowed and currently
+ * used in some systems.
+ *
+ * To support multiple runtime loading and initialization strategies employed
+ * by various operating systems, the driver instance can be initialized using
+ * the XLlTemac_CfgInitialze() routine.
+ *
+ * <h2>Interrupts and Asynchronous Callbacks</h2>
+ *
+ * The driver has no dependencies on the interrupt controller. It provides
+ * no interrupt handlers. The application/OS software should set up its own
+ * interrupt handlers if required.
+ *
+ * <h2>Device Reset</h2>
+ *
+ * When a TEMAC channel is connected up to a FIFO or DMA core in hardware,
+ * errors may be reported on one of those cores (FIFO or DMA) such that it can
+ * be determined that the TEMAC channel needs to be reset. If a reset is
+ * performed, the calling code should also reconfigure and reapply the proper
+ * settings in the TEMAC channel.
+ *
+ * When a TEMAC channel reset is required, XLlTemac_Reset() should be utilized.
+ *
+ * <h2>Virtual Memory</h2>
+ *
+ * This driver may be used in systems with virtual memory support by passing
+ * the appropriate value for the <i>EffectiveAddress</i> parameter to the
+ * XLlTemac_CfgInitialize() routine.
+ *
+ * <h2>Transfering Data</h2>
+ *
+ * The TEMAC core by itself is not cabable of transmitting or receiving data in
+ * any meaninful way. Instead one or both TEMAC channels need to be connected
+ * to a FIFO or DMA core in hardware.
+ *
+ * This TEMAC driver is modeled in a similar fashion where the application code
+ * or O/S adapter driver needs to make use of a separte FIFO or DMA driver in
+ * connection with this driver to establish meaningful communication over
+ * ethernet.
+ *
+ * <h2>Checksum Offloading</h2>
+ *
+ * If configured, the device can compute a 16-bit checksum from frame data. In
+ * most circumstances this can lead to a substantial gain in throughput.
+ *
+ * The checksum offload settings for each frame sent or recieved are
+ * transmitted through the LocalLink interface in hardware. What this means is
+ * that the checksum offload feature is indirectly controlled in the TEMAC
+ * channel through the driver for the FIFO or DMA core connected to the TEMAC
+ * channel.
+ *
+ * Refer to the documentation for the FIFO or DMA driver used for data
+ * communication on how to set the values for the relevant LocalLink header
+ * words.
+ *
+ * Since this hardware implementation is general purpose in nature system software must
+ * perform pre and post frame processing to obtain the desired results for the
+ * types of packets being transferred. Most of the time this will be TCP/IP
+ * traffic.
+ *
+ * TCP/IP and UDP/IP frames contain separate checksums for the IP header and
+ * UDP/TCP header+data. With this hardware implementation, the IP header checksum
+ * cannot be offloaded. Many stacks that support offloading will compute the IP
+ * header if required and use hardware to compute the UDP/TCP header+data checksum.
+ * There are other complications concerning the IP pseudo header that must be
+ * taken into consideration. Readers should consult a TCP/IP design reference
+ * for more details.
+ *
+ * There are certain device options that will affect the checksum calculation
+ * performed by hardware for Tx:
+ *
+ * - FCS insertion disabled (XTE_FCS_INSERT_OPTION): software is required to
+ * calculate and insert the FCS value at the end of the frame, but the
+ * checksum must be known ahead of time prior to calculating the FCS.
+ * Therefore checksum offloading cannot be used in this situation.
+ *
+ * And for Rx:
+ *
+ * - FCS/PAD stripping disabled (XTE_FCS_STRIP_OPTION): The 4 byte FCS at the
+ * end of frame will be included in the hardware calculated checksum. software must
+ * subtract out this data.
+ *
+ * - FCS/PAD stripping disabled (XTE_FCS_STRIP_OPTION): For frames smaller
+ * than 64 bytes, padding will be included in the hardware calculated checksum.
+ * software must subtract out this data. It may be better to allow the TCP/IP
+ * stack verify checksums for this type of packet.
+ *
+ * - VLAN enabled (XTE_VLAN_OPTION): The 4 extra bytes in the Ethernet header
+ * affect the hardware calculated checksum. software must subtract out the 1st two
+ * 16-bit words starting at the 15th byte.
+ *
+ * <h3>Transmit Checksum Offloading</h3>
+ *
+ * For transmit, the software can specify where in the frame the checksum
+ * calculation is to start, where the result should be inserted, and a seed
+ * value. The checksum is calculated from the start point through the end of
+ * frame.
+ *
+ * The checsum offloading settings are sent in the transmit LocalLink header
+ * words. The relevant LocalLink header words are described in brief below.
+ * Refer to the XPS_LL_TEMAC v1.00a hardware specification for more details.
+ *
+ * <h4>LocalLink header word 3:</h4>
+ * <pre>
+ * Bits 31 (MSB): Transmit Checksum Enable: 1 - enabled, 0 - disabled
+ * Bits 0-30 (LSB): Reserved
+ * </pre>
+ *
+ * <h4>LocalLink header word 4:</h4>
+ * <pre>
+ * Bits 16-31 (MSB): Transmit Checksum Insertion Point: Frame offset where the
+ * computed checksum value is stored, which should be in the
+ * TCP or UDP header
+ * Bits 0-15 (LSB): Transmit Checksum Calculation Starting Point: Offset
+ * in the frame where checksum calculation should begin
+ * </pre>
+ *
+ * <h4>LocalLink header word 5:</h4>
+ * <pre>
+ * Bits 16-31 (MSB): Transmit Checksum Calculation Initial Value: Checksum
+ * seed value
+ * Bits 0-15 (LSB): Reserved
+ * </pre>
+ *
+ * <h3>Receive Checksum Offloading</h3>
+ *
+ * For Receive, the 15th byte to end of frame is checksummed. This range of
+ * bytes is the entire Ethernet payload (for non-VLAN frames).
+ *
+ * The checsum offloading information is sent in the receive LocalLink header
+ * words. The relevant LocalLink header words are described in brief below.
+ * Refer to the XPS_LL_TEMAC v1.00a hardware specification for more details.
+ *
+ * <h4>LocalLink header word 6:</h4>
+ * <pre>
+ * Bits 16-31 (MSB): Receive Raw Checksum: Computed checksum value
+ * Bits 0-15 (LSB): Reserved
+ * </pre>
+ *
+ * <h2>PHY Communication</h2>
+ *
+ * Prior to PHY access, the MDIO clock must be setup. This driver will set a
+ * safe default that should work with PLB bus speeds of up to 150 MHz and keep
+ * the MDIO clock below 2.5 MHz. If the user wishes faster access to the PHY
+ * then the clock divisor can be set to a different value (see
+ * XLlTemac_PhySetMdioDivisor()).
+ *
+ * MII register access is performed through the functions XLlTemac_PhyRead() and
+ * XLlTemac_PhyWrite().
+ *
+ * <h2>Link Sync</h2>
+ *
+ * When the device is used in a multispeed environment, the link speed must be
+ * explicitly set using XLlTemac_SetOperatingSpeed() and must match the speed the
+ * PHY has negotiated. If the speeds are mismatched, then the MAC will not pass
+ * traffic.
+ *
+ * The application/OS software may use the AutoNegotiation interrupt to be
+ * notified when the PHY has completed auto-negotiation.
+ *
+ * <h2>Asserts</h2>
+ *
+ * Asserts are used within all Xilinx drivers to enforce constraints on argument
+ * values. 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.
+ *
+ * <h2>Driver Errata</h2>
+ *
+ * - A dropped receive frame indication may be reported by the driver after
+ * calling XLlTemac_Stop() followed by XLlTemac_Start(). This can occur if a
+ * frame is arriving when stop is called.
+ * - On Rx with checksum offloading enabled and FCS/PAD stripping disabled,
+ * FCS and PAD data will be included in the checksum result.
+ * - On Tx with checksum offloading enabled and auto FCS insertion disabled,
+ * the user calculated FCS will be included in the checksum result.
+ *
+ * @note
+ *
+ * Xilinx drivers are typically composed of two components, 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.
+ * <br><br>
+ * 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 by the layer above this driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 11/10/06 First release
+ * 1.00a rpm 06/08/07 Added interrupt IDs to config structure for convenience
+ * </pre>
+ *
+ *****************************************************************************/
+
+#ifndef XTEMAC_H /* prevent circular inclusions */
+#define XTEMAC_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xenv.h"
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xlltemac_hw.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Device information
+ */
+#define XTE_DEVICE_NAME "xlltemac"
+#define XTE_DEVICE_DESC "Xilinx Tri-speed 10/100/1000 MAC"
+
+/* LocalLink TYPE Enumerations */
+#define XPAR_LL_FIFO 1
+#define XPAR_LL_DMA 2
+
+/** @name Configuration options
+ *
+ * The following are device configuration options. See the
+ * <i>XLlTemac_SetOptions</i>, <i>XLlTemac_ClearOptions</i> and
+ * <i>XLlTemac_GetOptions</i> routines for information on how to use options.
+ *
+ * The default state of the options are also noted below.
+ *
+ * @{
+ */
+
+#define XTE_PROMISC_OPTION 0x00000001
+/**< XTE_PROMISC_OPTION specifies the TEMAC channel to accept all incoming
+ * packets.
+ * This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_JUMBO_OPTION 0x00000002
+/**< XTE_JUMBO_OPTION specifies the TEMAC channel to accept jumbo frames
+ * for transmit and receive.
+ * This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_VLAN_OPTION 0x00000004
+/**< XTE_VLAN_OPTION specifies the TEMAC channel to enable VLAN support for
+ * transmit and receive.
+ * This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_FLOW_CONTROL_OPTION 0x00000008
+/**< XTE_FLOW_CONTROL_OPTION specifies the TEMAC channel to recognize
+ * received flow control frames.
+ * This driver sets this option to enabled (set) by default. */
+
+#define XTE_FCS_STRIP_OPTION 0x00000010
+/**< XTE_FCS_STRIP_OPTION specifies the TEMAC channel to strip FCS and PAD
+ * from received frames. Note that PAD from VLAN frames is not stripped.
+ * This driver sets this option to enabled (set) by default. */
+
+#define XTE_FCS_INSERT_OPTION 0x00000020
+/**< XTE_FCS_INSERT_OPTION specifies the TEMAC channel to generate the FCS
+ * field and add PAD automatically for outgoing frames.
+ * This driver sets this option to enabled (set) by default. */
+
+#define XTE_LENTYPE_ERR_OPTION 0x00000040
+/**< XTE_LENTYPE_ERR_OPTION specifies the TEMAC channel to enable
+ * Length/Type error checking (mismatched type/length field) for received
+ * frames.
+ * This driver sets this option to enabled (set) by default. */
+
+#define XTE_TRANSMITTER_ENABLE_OPTION 0x00000080
+/**< XTE_TRANSMITTER_ENABLE_OPTION specifies the TEMAC channel transmitter
+ * to be enabled.
+ * This driver sets this option to enabled (set) by default. */
+
+#define XTE_RECEIVER_ENABLE_OPTION 0x00000100
+/**< XTE_RECEIVER_ENABLE_OPTION specifies the TEMAC channel receiver to be
+ * enabled.
+ * This driver sets this option to enabled (set) by default. */
+
+#define XTE_BROADCAST_OPTION 0x00000200
+/**< XTE_BROADCAST_OPTION specifies the TEMAC channel to receive frames
+ * sent to the broadcast Ethernet address.
+ * This driver sets this option to enabled (set) by default. */
+
+#define XTE_MULTICAST_OPTION 0x00000400
+/**< XTE_MULTICAST_OPTION specifies the TEMAC channel to receive frames
+ * sent to Ethernet addresses that are programmed into the Multicast Address
+ * Table (MAT).
+ * This driver sets this option to disabled (cleared) by default. */
+
+#define XTE_DEFAULT_OPTIONS \
+ (XTE_FLOW_CONTROL_OPTION | \
+ XTE_BROADCAST_OPTION | \
+ XTE_FCS_INSERT_OPTION | \
+ XTE_FCS_STRIP_OPTION | \
+ XTE_LENTYPE_ERR_OPTION | \
+ XTE_TRANSMITTER_ENABLE_OPTION | \
+ XTE_RECEIVER_ENABLE_OPTION)
+/**< XTE_DEFAULT_OPTIONS specify the options set in XLlTemac_Reset() and
+ * XLlTemac_CfgInitialize() */
+
+/*@}*/
+
+/** @name Reset parameters
+ *
+ * These are used by function XLlTemac_Reset().
+ * @{
+ */
+#define XTE_RESET_HARD 1
+#define XTE_NORESET_HARD 0
+/*@}*/
+
+#define XTE_MULTI_MAT_ENTRIES 4 /* Number of storable addresses in
+ the Multicast Address Table */
+
+#define XTE_MDIO_DIV_DFT 29 /* 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 XTE_MAC_ADDR_SIZE 6 /* MAC addresses are 6 bytes */
+#define XTE_MTU 1500 /* max MTU size of an Ethernet frame */
+#define XTE_JUMBO_MTU 8982 /* max MTU size of a jumbo Ethernet frame */
+#define XTE_HDR_SIZE 14 /* size of an Ethernet header */
+#define XTE_HDR_VLAN_SIZE 18 /* size of an Ethernet header with VLAN */
+#define XTE_TRL_SIZE 4 /* size of an Ethernet trailer (FCS) */
+#define XTE_MAX_FRAME_SIZE (XTE_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+#define XTE_MAX_VLAN_FRAME_SIZE (XTE_MTU + XTE_HDR_VLAN_SIZE + XTE_TRL_SIZE)
+#define XTE_MAX_JUMBO_FRAME_SIZE (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+
+/* Constant values returned by XLlTemac_mGetPhysicalInterface(). Note that these
+ * values match design parameters from the PLB_TEMAC spec
+ */
+#define XTE_PHY_TYPE_MII 0
+#define XTE_PHY_TYPE_GMII 1
+#define XTE_PHY_TYPE_RGMII_1_3 2
+#define XTE_PHY_TYPE_RGMII_2_0 3
+#define XTE_PHY_TYPE_SGMII 4
+#define XTE_PHY_TYPE_1000BASE_X 5
+
+/**************************** Type Definitions *******************************/
+
+
+/**
+ * This typedef contains configuration information for a TEMAC channel.
+ * Each channel is treated as a separate device from the point of view of this
+ * driver.
+ */
+typedef struct {
+ /** u16 DeviceId; < DeviceId is the unique ID of the device */
+ u32 BaseAddress;/**< BaseAddress is the physical base address of the
+ * channel's registers
+ */
+ u8 TxCsum; /**< TxCsum indicates that the channel has checksum
+ * offload on the Tx channel or not.
+ */
+ u8 RxCsum; /**< RxCsum indicates that the channel has checksum
+ * offload on the Rx channel or not.
+ */
+ u8 PhyType; /**< PhyType indicates which type of PHY interface is
+ * used (MII, GMII, RGMII, ect.
+ */
+ u8 TemacIntr; /**< TEMAC interrupt ID */
+
+ int LLDevType; /**< LLDevType is the type of device attached to the
+ * temac's local link interface.
+ */
+ u32 LLDevBaseAddress; /**< LLDevBaseAddress is the base address of then
+ * device attached to the temac's local link
+ * interface.
+ */
+ u8 LLFifoIntr; /**< LL FIFO interrupt ID (unused if DMA) */
+ u8 LLDmaRxIntr; /**< LL DMA RX interrupt ID (unused if FIFO) */
+ u8 LLDmaTxIntr; /**< LL DMA TX interrupt ID (unused if FIFO) */
+
+} XLlTemac_Config;
+
+
+/**
+ * struct XLlTemac is the type for TEMAC driver instance data. The calling code
+ * is required to use a unique instance of this structure for every TEMAC
+ * channel used in the system. Each channel is treated as a separate device
+ * from the point of view of this driver. A reference to a structure of this
+ * type is then passed to the driver API functions.
+ */
+typedef struct XLlTemac {
+ XLlTemac_Config Config; /* hardware configuration */
+ u32 IsStarted; /* Device is currently started */
+ u32 IsReady; /* Device is initialized and ready */
+ u32 Options; /* Current options word */
+ u32 Flags; /* Internal driver flags */
+} XLlTemac;
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsStarted reports if the device is in the started or stopped state. To
+ * be in the started state, the calling code must have made a successful call to
+ * <i>XLlTemac_Start</i>. To be in the stopped state, <i>XLlTemac_Stop</i> or
+ * <i>XLlTemac_CfgInitialize</i> function must have been called.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsStarted returns TRUE if the device has been started.
+ * Otherwise, XLlTemac_IsStarted returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsStarted(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsStarted(InstancePtr) \
+ (((InstancePtr)->IsStarted == XCOMPONENT_IS_STARTED) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+*
+* XLlTemac_IsDma reports if the device is currently connected to DMA.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IsDma returns TRUE if the device is connected DMA. Otherwise,
+* XLlTemac_IsDma returns FALSE.
+*
+* @note
+*
+* Signature: u32 XLlTemac_IsDma(XLlTemac *InstancePtr)
+*
+******************************************************************************/
+#define XLlTemac_IsDma(InstancePtr) \
+ (((InstancePtr)->Config.LLDevType == XPAR_LL_DMA) ? TRUE: FALSE)
+
+/*****************************************************************************/
+/**
+*
+* XLlTemac_IsFifo reports if the device is currently connected to a fifo core.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IsFifo returns TRUE if the device is connected to a fifo core.
+* Otherwise, XLlTemac_IsFifo returns FALSE.
+*
+* @note
+*
+* Signature: u32 XLlTemac_IsFifo(XLlTemac *InstancePtr)
+*
+******************************************************************************/
+#define XLlTemac_IsFifo(InstancePtr) \
+ (((InstancePtr)->Config.LLDevType == XPAR_LL_FIFO) ? TRUE: FALSE)
+
+/*****************************************************************************/
+/**
+*
+* XLlTemac_LlDevBaseAddress reports the base address of the core connected to
+* the TEMAC's local link interface.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IsFifo returns the base address of the core connected to
+* the TEMAC's local link interface.
+*
+* @note
+*
+* Signature: u32 XLlTemac_LlDevBaseAddress(XLlTemac *InstancePtr)
+*
+******************************************************************************/
+#define XLlTemac_LlDevBaseAddress(InstancePtr) \
+ ((InstancePtr)->Config.LLDevBaseAddress)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsRecvFrameDropped determines if the device thinks it has dropped a
+ * receive frame.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsRecvFrameDropped returns TRUE if the device interrupt
+ * status register reports that a frame has been dropped. Otherwise,
+ * XLlTemac_IsRecvFrameDropped returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsRecvFrameDropped(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsRecvFrameDropped(InstancePtr) \
+ ((XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, XTE_IS_OFFSET) \
+ & XTE_INT_RXRJECT_MASK) ? TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsRxCsum determines if the device is configured with checksum
+ * offloading on the receive channel.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsRxCsum returns TRUE if the device is configured with
+ * checksum offloading on the receive channel. Otherwise,
+ * XLlTemac_IsRxCsum returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsRxCsum(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsRxCsum(InstancePtr) (((InstancePtr)->Config.RxCsum) ? \
+ TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_IsTxCsum determines if the device is configured with checksum
+ * offloading on the transmit channel.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_IsTxCsum returns TRUE if the device is configured with
+ * checksum offloading on the transmit channel. Otherwise,
+ * XLlTemac_IsTxCsum returns FALSE.
+ *
+ * @note
+ *
+ * Signature: u32 XLlTemac_IsTxCsum(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_IsTxCsum(InstancePtr) (((InstancePtr)->Config.TxCsum) ? \
+ TRUE : FALSE)
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_GetPhysicalInterface returns the type of PHY interface being used by
+ * the given instance, specified by <i>InstancePtr</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_GetPhysicalInterface returns one of XTE_PHY_TYPE_<x> where
+ * <x> is MII, GMII, RGMII_1_3, RGMII_2_0, SGMII, or 1000BASE_X (defined in
+ * xlltemac.h).
+ *
+ * @note
+ *
+ * Signature: int XLlTemac_GetPhysicalInterface(XLlTemac *InstancePtr)
+ *
+ ******************************************************************************/
+#define XLlTemac_GetPhysicalInterface(InstancePtr) \
+ ((InstancePtr)->Config.PhyType)
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_Status returns a bit mask of the interrupt status register (ISR).
+* XLlTemac_Status can be used to query the status without having to have
+* interrupts enabled.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IntStatus returns a bit mask of the status conditions.
+* The mask will be a set of bitwise or'd values from the
+* <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+* u32 XLlTemac_IntStatus(XLlTemac *InstancePtr)
+*
+*****************************************************************************/
+#define XLlTemac_Status(InstancePtr) \
+ XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, XTE_IS_OFFSET)
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntEnable enables the interrupts specified in <i>Mask</i>. The
+* corresponding interrupt for each bit set to 1 in <i>Mask</i>, will be
+* enabled.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @param Mask contains a bit mask of the interrupts to enable. The mask
+* can be formed using a set of bitwise or'd values from the
+* <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlTemac_IntEnable(XLlTemac *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlTemac_IntEnable(InstancePtr, Mask) \
+ XLlTemac_WriteReg((InstancePtr)->Config.BaseAddress, XTE_IE_OFFSET, \
+ XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, \
+ XTE_IE_OFFSET) | ((Mask) & XTE_INT_ALL_MASK)); \
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntDisable disables the interrupts specified in <i>Mask</i>. The
+* corresponding interrupt for each bit set to 1 in <i>Mask</i>, will be
+* disabled. In other words, XLlTemac_IntDisable uses the "set a bit to clear it"
+* scheme.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @param Mask contains a bit mask of the interrupts to disable. The mask
+* can be formed using a set of bitwise or'd values from the
+* <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @return N/A
+*
+* @note
+* C-style signature:
+* void XLlTemac_IntDisable(XLlTemac *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlTemac_IntDisable(InstancePtr, Mask) \
+ XLlTemac_WriteReg((InstancePtr)->Config.BaseAddress, XTE_IE_OFFSET, \
+ XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, \
+ XTE_IE_OFFSET) & ~((Mask) & XTE_INT_ALL_MASK)); \
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntPending returns a bit mask of the pending interrupts. Each bit
+* set to 1 in the return value represents a pending interrupt.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @return XLlTemac_IntPending returns a bit mask of the interrupts that are
+* pending. The mask will be a set of bitwise or'd values from the
+* <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+* u32 XLlTemac_IntPending(XLlTemac *InstancePtr)
+*
+*****************************************************************************/
+#define XLlTemac_IntPending(InstancePtr) \
+ XLlTemac_ReadReg((InstancePtr)->Config.BaseAddress, XTE_IP_OFFSET)
+
+/****************************************************************************/
+/**
+*
+* XLlTemac_IntClear clears pending interrupts specified in <i>Mask</i>.
+* The corresponding pending interrupt for each bit set to 1 in <i>Mask</i>,
+* will be cleared. In other words, XLlTemac_IntClear uses the "set a bit to
+* clear it" scheme.
+*
+* @param InstancePtr references the TEMAC channel on which to operate.
+*
+* @param Mask contains a bit mask of the pending interrupts to clear. The
+* mask can be formed using a set of bitwise or'd values from the
+* <code>XTE_INT_*_MASK</code> preprocessor symbols.
+*
+* @note
+* C-style signature:
+* void XLlTemac_IntClear(XLlTemac *InstancePtr, u32 Mask)
+*
+*****************************************************************************/
+#define XLlTemac_IntClear(InstancePtr, Mask) \
+ XLlTemac_WriteReg((InstancePtr)->Config.BaseAddress, XTE_IS_OFFSET, \
+ ((Mask) & XTE_INT_ALL_MASK))
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization functions in xlltemac.c
+ */
+int XLlTemac_CfgInitialize(XLlTemac *InstancePtr, XLlTemac_Config *CfgPtr,
+ u32 VirtualAddress);
+void XLlTemac_Start(XLlTemac *InstancePtr);
+void XLlTemac_Stop(XLlTemac *InstancePtr);
+void XLlTemac_Reset(XLlTemac *InstancePtr, int HardCoreAction);
+
+/*
+ * Initialization functions in xlltemac_sinit.c
+ */
+XLlTemac_Config *XLlTemac_LookupConfig(u16 DeviceId);
+
+/*
+ * MAC configuration/control functions in xlltemac_control.c
+ */
+int XLlTemac_SetOptions(XLlTemac *InstancePtr, u32 Options);
+int XLlTemac_ClearOptions(XLlTemac *InstancePtr, u32 Options);
+u32 XLlTemac_GetOptions(XLlTemac *InstancePtr);
+
+int XLlTemac_SetMacAddress(XLlTemac *InstancePtr, void *AddressPtr);
+void XLlTemac_GetMacAddress(XLlTemac *InstancePtr, void *AddressPtr);
+
+int XLlTemac_SetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr);
+void XLlTemac_GetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr);
+int XLlTemac_SendPausePacket(XLlTemac *InstancePtr, u16 PauseValue);
+
+int XLlTemac_GetSgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr);
+int XLlTemac_GetRgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr,
+ int *IsFullDuplexPtr, int *IsLinkUpPtr);
+u16 XLlTemac_GetOperatingSpeed(XLlTemac *InstancePtr);
+void XLlTemac_SetOperatingSpeed(XLlTemac *InstancePtr, u16 Speed);
+
+void XLlTemac_PhySetMdioDivisor(XLlTemac *InstancePtr, u8 Divisor);
+void XLlTemac_PhyRead(XLlTemac *InstancePtr, u32 PhyAddress, u32 RegisterNum,
+ u16 *PhyDataPtr);
+void XLlTemac_PhyWrite(XLlTemac *InstancePtr, u32 PhyAddress, u32 RegisterNum,
+ u16 PhyData);
+int XLlTemac_MulticastAdd(XLlTemac *InstancePtr, void *AddressPtr, int Entry);
+void XLlTemac_MulticastGet(XLlTemac *InstancePtr, void *AddressPtr, int Entry);
+int XLlTemac_MulticastClear(XLlTemac *InstancePtr, int Entry);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac.c
===================================================================
--- /dev/null
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac.c
@@ -0,0 +1,1378 @@
+/* $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 2005-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac.c
+ *
+ * The XLlTemac driver. Functions in this file are the minimum required functions
+ * for this driver. See xlltemac.h for a detailed description of the driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 11/10/06 First release
+ * </pre>
+ ******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include <linux/string.h>
+#include <linux/delay.h>
+
+#include "xlltemac.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+static void InitHw(XLlTemac *InstancePtr); /* HW reset */
+
+/************************** Variable Definitions *****************************/
+
+xdbg_stmnt(int indent_on = 0;
+
+ )
+ xdbg_stmnt(u32 _xlltemac_rir_value;
+
+ )
+
+/*****************************************************************************/
+/**
+ *
+ * XLlTemac_CfgInitialize initializes a TEMAC channel along with the
+ * <i>InstancePtr</i> that references it. Each TEMAC channel is treated as a
+ * separate device from the point of view of this driver.
+ *
+ * The PHY is setup independently from the TEMAC. Use the MII or whatever other
+ * interface may be present for setup.
+ *
+ * @param InstancePtr references the memory instance to be associated with
+ * the TEMAC channel upon initialization.
+ * @param CfgPtr references the structure holding the hardware configuration
+ * for the TEMAC channel to initialize.
+ * @param EffectiveAddress is the processor address used to access the
+ * base address of the TEMAC channel. In systems with an MMU and virtual
+ * memory, <i>EffectiveAddress</i> is the virtual address mapped to the
+ * physical in <code>ConfigPtr->Config.BaseAddress</code>. In systems
+ * without an active MMU, <i>EffectiveAddress</i> should be set to the
+ * same value as <code>ConfigPtr->Config.BaseAddress</code>.
+ *
+ * @return XLlTemac_CfgInitialize returns XST_SUCCESS.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ *
+ ******************************************************************************/
+ int XLlTemac_CfgInitialize(XLlTemac *InstancePtr,
+ XLlTemac_Config *CfgPtr, u32 EffectiveAddress)
+{
+ /* Verify arguments */
+ XASSERT_NONVOID(InstancePtr != NULL);
+
+ /* Clear instance memory and make copy of configuration */
+ memset(InstancePtr, 0, sizeof(XLlTemac));
+ memcpy(&InstancePtr->Config, CfgPtr, sizeof(XLlTemac_Config));
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_CfgInitialize\n");
+ /* Set device base address */
+ InstancePtr->Config.BaseAddress = EffectiveAddress;
+
+ /* Reset the hardware and set default options */
+ InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+ XLlTemac_Reset(InstancePtr, XTE_NORESET_HARD);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Temac_CfgInitialize: returning SUCCESS\n");
+ return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_Start starts the TEMAC channel as follows:
+ * - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
+ * - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_Start(XLlTemac *InstancePtr)
+{
+ u32 Reg;
+
+ /* Assert bad arguments and conditions */
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ /* If already started, then there is nothing to do */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return;
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Start\n");
+ /* Enable transmitter if not already enabled */
+ if (InstancePtr->Options & XTE_TRANSMITTER_ENABLE_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL, "enabling transmitter\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET);
+ if (!(Reg & XTE_TC_TX_MASK)) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "transmitter not enabled, enabling now\n");
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.
+ BaseAddress, XTE_TC_OFFSET,
+ Reg | XTE_TC_TX_MASK);
+ }
+ xdbg_printf(XDBG_DEBUG_GENERAL, "transmitter enabled\n");
+ }
+
+ /* Enable receiver */
+ if (InstancePtr->Options & XTE_RECEIVER_ENABLE_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL, "enabling receiver\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ if (!(Reg & XTE_RCW1_RX_MASK)) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "receiver not enabled, enabling now\n");
+
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.
+ BaseAddress, XTE_RCW1_OFFSET,
+ Reg | XTE_RCW1_RX_MASK);
+ }
+ xdbg_printf(XDBG_DEBUG_GENERAL, "receiver enabled\n");
+ }
+
+ /* Mark as started */
+ InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Start: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_Stop gracefully stops the TEMAC channel as follows:
+ * - Disable all interrupts from this device
+ * - Disable the receiver
+ *
+ * XLlTemac_Stop does not modify any of the current device options.
+ *
+ * Since the transmitter is not disabled, frames currently in internal buffers
+ * or in process by a DMA engine are allowed to be transmitted.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_Stop(XLlTemac *InstancePtr)
+{
+ u32 Reg;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ /* If already stopped, then there is nothing to do */
+ if (InstancePtr->IsStarted == 0) {
+ return;
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Stop\n");
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_Stop: disabling interrupts\n");
+ /* Disable interrupts */
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET, 0);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Stop: disabling receiver\n");
+ /* Disable the receiver */
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ Reg &= ~XTE_RCW1_RX_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET, Reg);
+
+ /* Stopping the receiver in mid-packet causes a dropped packet indication
+ * from HW. Clear it.
+ */
+ /* get the interrupt pending register */
+ Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IP_OFFSET);
+ if (Reg & XTE_INT_RXRJECT_MASK) {
+ /* set the interrupt status register to clear the interrupt */
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+ XTE_IS_OFFSET, XTE_INT_RXRJECT_MASK);
+ }
+
+ /* Mark as stopped */
+ InstancePtr->IsStarted = 0;
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Stop: done\n");
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_Reset performs a reset of the TEMAC channel, specified by
+ * <i>InstancePtr</i>, or both channels if <i>HardCoreAction</i> is set to
+ * XTE_RESET_HARD.
+ *
+ * XLlTemac_Reset also resets the TEMAC channel's options to their default values.
+ *
+ * The calling software is responsible for re-configuring the TEMAC channel
+ * (if necessary) and restarting the MAC after the reset.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param HardCoreAction describes how XLlTemac_Reset should treat the hard core
+ * block of the TEMAC.<br><br>
+ *
+ * If XTE_RESET_HARD is set to XTE_RESET_HARD, then XLlTemac_Reset asserts
+ * the reset signal to the hard core block which will reset both channels
+ * of the TEMAC. This, of course, will bork any activity that may be
+ * occuring on the other channel. So, be careful here.<br><br>
+ *
+ * Otherwise, XLlTemac_Reset resets just the transmitter and receiver of
+ * this TEMAC channel.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_Reset(XLlTemac *InstancePtr, int HardCoreAction)
+{
+ u32 Reg;
+ u32 TimeoutCount = 2;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_Reset\n");
+ /* Stop the device and reset HW */
+ XLlTemac_Stop(InstancePtr);
+ InstancePtr->Options = XTE_DEFAULT_OPTIONS;
+
+ /* Reset the receiver */
+ xdbg_printf(XDBG_DEBUG_GENERAL, "resetting the receiver\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ Reg |= XTE_RCW1_RST_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET, Reg);
+
+ /* Reset the transmitter */
+ xdbg_printf(XDBG_DEBUG_GENERAL, "resetting the transmitter\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET);
+ Reg |= XTE_TC_RST_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET, Reg);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "waiting until reset is done\n");
+ /* Poll until the reset is done */
+ while (Reg & (XTE_RCW1_RST_MASK | XTE_TC_RST_MASK)) {
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ Reg |= XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET);
+ }
+
+ /* Reset hard core if required */
+ /* Resetting hard core will cause both channels to reset :-( */
+ if (HardCoreAction == XTE_RESET_HARD) {
+ xdbg_printf(XDBG_DEBUG_GENERAL, "hard reset\n");
+ Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET);
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET, Reg | XTE_RAF_HTRST_MASK);
+ while (TimeoutCount &&
+ (!(XLlTemac_ReadReg
+ (InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK))) {
+ udelay(XTE_RESET_HARD_DELAY_US);
+ TimeoutCount--;
+ }
+ }
+
+ /* Setup HW */
+ InitHw(InstancePtr);
+}
+
+
+/******************************************************************************
+ * InitHw (internal use only) performs a one-time setup of a TEMAC channel. The
+ * setup performed here only need to occur once after any reset.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+static void InitHw(XLlTemac *InstancePtr)
+{
+ u32 Reg;
+
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac InitHw\n");
+ /* Disable the receiver */
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac InitHw\n");
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac InitHw: disabling receiver\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ Reg &= ~XTE_RCW1_RX_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET, Reg);
+
+ /*
+ * Stopping the receiver in mid-packet causes a dropped packet
+ * indication from HW. Clear it.
+ */
+ /* get the interrupt pending register */
+ Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IP_OFFSET);
+ if (Reg & XTE_INT_RXRJECT_MASK) {
+ /*
+ * set the interrupt status register to clear the pending
+ * interrupt
+ */
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+ XTE_IS_OFFSET, XTE_INT_RXRJECT_MASK);
+ }
+
+ /* Sync default options with HW but leave receiver and transmitter
+ * disabled. They get enabled with XLlTemac_Start() if
+ * XTE_TRANSMITTER_ENABLE_OPTION and XTE_RECEIVER_ENABLE_OPTION are set
+ */
+ XLlTemac_SetOptions(InstancePtr, InstancePtr->Options &
+ ~(XTE_TRANSMITTER_ENABLE_OPTION |
+ XTE_RECEIVER_ENABLE_OPTION));
+
+ XLlTemac_ClearOptions(InstancePtr, ~InstancePtr->Options);
+
+ /* Set default MDIO divisor */
+ XLlTemac_PhySetMdioDivisor(InstancePtr, XTE_MDIO_DIV_DFT);
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac InitHw: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SetMacAddress sets the MAC address for the TEMAC channel, specified
+ * by <i>InstancePtr</i> to the MAC address specified by <i>AddressPtr</i>.
+ * The TEMAC channel must be stopped before calling this function.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr is a reference to the 6-byte MAC address to set.
+ *
+ * @return On successful completion, XLlTemac_SetMacAddress returns XST_SUCCESS.
+ * Otherwise, if the TEMAC channel has not stopped,
+ * XLlTemac_SetMacAddress returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SetMacAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+ u32 MacAddr;
+ u8 *Aptr = (u8 *) AddressPtr;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(AddressPtr != NULL);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SetMacAddress: setting mac address to: 0x%08x%8x%8x%8x%8x%8x\n",
+ Aptr[0], Aptr[1], Aptr[2], Aptr[3], Aptr[4], Aptr[5]);
+ /*
+ * Set the MAC bits [31:0] in UAW0
+ * Having Aptr be unsigned type prevents the following operations from sign extending
+ */
+ MacAddr = Aptr[0];
+ MacAddr |= Aptr[1] << 8;
+ MacAddr |= Aptr[2] << 16;
+ MacAddr |= Aptr[3] << 24;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_UAW0_OFFSET, MacAddr);
+
+ /* There are reserved bits in UAW1 so don't affect them */
+ MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_UAW1_OFFSET);
+ MacAddr &= ~XTE_UAW1_UNICASTADDR_MASK;
+
+ /* Set MAC bits [47:32] in UAW1 */
+ MacAddr |= Aptr[4];
+ MacAddr |= Aptr[5] << 8;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_UAW1_OFFSET, MacAddr);
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetMacAddress gets the MAC address for the TEMAC channel, specified
+ * by <i>InstancePtr</i> into the memory buffer specified by <i>AddressPtr</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr references the memory buffer to store the retrieved MAC
+ * address. This memory buffer must be at least 6 bytes in length.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_GetMacAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+ u32 MacAddr;
+ u8 *Aptr = (u8 *) AddressPtr;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ /* Read MAC bits [31:0] in UAW0 */
+ MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_UAW0_OFFSET);
+ 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 UAW1 */
+ MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_UAW1_OFFSET);
+ Aptr[4] = (u8) MacAddr;
+ Aptr[5] = (u8) (MacAddr >> 8);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SetOptions enables the options, <i>Options</i> for the TEMAC channel,
+ * specified by <i>InstancePtr</i>. The TEMAC channel should be stopped with
+ * XLlTemac_Stop() before changing options.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Options is a bitmask of OR'd XTE_*_OPTION values for options to
+ * set. Options not specified are not affected.
+ *
+ * @return On successful completion, XLlTemac_SetOptions returns XST_SUCCESS.
+ * Otherwise, if the device has not been stopped, XLlTemac_SetOptions
+ * returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ * See xlltemac.h for a description of the available options.
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SetOptions(XLlTemac *InstancePtr, u32 Options)
+{
+ u32 Reg; /* Generic register contents */
+ u32 RegRcw1; /* Reflects original contents of RCW1 */
+ u32 RegTc; /* Reflects original contents of TC */
+ u32 RegNewRcw1; /* Reflects new contents of RCW1 */
+ u32 RegNewTc; /* Reflects new contents of TC */
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetOptions\n");
+ /* Many of these options will change the RCW1 or TC registers.
+ * To reduce the amount of IO to the device, group these options here
+ * and change them all at once.
+ */
+
+ /* Grab current register contents */
+ RegRcw1 = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ RegTc = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET);
+ RegNewRcw1 = RegRcw1;
+ RegNewTc = RegTc;
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "current control regs: RCW1: 0x%0x; TC: 0x%0x\n", RegRcw1,
+ RegTc);
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Options: 0x%0x; default options: 0x%0x\n", Options,
+ XTE_DEFAULT_OPTIONS);
+
+ /* Turn on jumbo packet support for both Rx and Tx */
+ if (Options & XTE_JUMBO_OPTION) {
+ RegNewTc |= XTE_TC_JUM_MASK;
+ RegNewRcw1 |= XTE_RCW1_JUM_MASK;
+ }
+
+ /* Turn on VLAN packet support for both Rx and Tx */
+ if (Options & XTE_VLAN_OPTION) {
+ RegNewTc |= XTE_TC_VLAN_MASK;
+ RegNewRcw1 |= XTE_RCW1_VLAN_MASK;
+ }
+
+ /* Turn on FCS stripping on receive packets */
+ if (Options & XTE_FCS_STRIP_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: enabling fcs stripping\n");
+ RegNewRcw1 &= ~XTE_RCW1_FCS_MASK;
+ }
+
+ /* Turn on FCS insertion on transmit packets */
+ if (Options & XTE_FCS_INSERT_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: enabling fcs insertion\n");
+ RegNewTc &= ~XTE_TC_FCS_MASK;
+ }
+
+ /* Turn on length/type field checking on receive packets */
+ if (Options & XTE_LENTYPE_ERR_OPTION) {
+ RegNewRcw1 &= ~XTE_RCW1_LT_DIS_MASK;
+ }
+
+ /* Enable transmitter */
+ if (Options & XTE_TRANSMITTER_ENABLE_OPTION) {
+ RegNewTc |= XTE_TC_TX_MASK;
+ }
+
+ /* Enable receiver */
+ if (Options & XTE_RECEIVER_ENABLE_OPTION) {
+ RegNewRcw1 |= XTE_RCW1_RX_MASK;
+ }
+
+ /* Change the TC or RCW1 registers if they need to be modified */
+ if (RegTc != RegNewTc) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: writting tc: 0x%0x\n", RegNewTc);
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET, RegNewTc);
+ }
+
+ if (RegRcw1 != RegNewRcw1) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: writting rcw1: 0x%0x\n", RegNewRcw1);
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET, RegNewRcw1);
+ }
+
+ /* Rest of options twiddle bits of other registers. Handle them one at
+ * a time
+ */
+
+ /* Turn on flow control */
+ if (Options & XTE_FLOW_CONTROL_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: endabling flow control\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_FCC_OFFSET);
+ Reg |= XTE_FCC_FCRX_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_FCC_OFFSET, Reg);
+ }
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: rcw1 is now (fcc): 0x%0x\n",
+ XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET));
+
+ /* Turn on promiscuous frame filtering (all frames are received ) */
+ if (Options & XTE_PROMISC_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: endabling promiscuous mode\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_AFM_OFFSET);
+ Reg |= XTE_AFM_PM_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_AFM_OFFSET, Reg);
+ }
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: rcw1 is now (afm): 0x%0x\n",
+ XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET));
+
+ /* Allow broadcast address filtering */
+ if (Options & XTE_BROADCAST_OPTION) {
+ Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET);
+ Reg &= ~XTE_RAF_BCSTREJ_MASK;
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET, Reg);
+ }
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: rcw1 is now (raf): 0x%0x\n",
+ XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET));
+
+ /* Allow multicast address filtering */
+ if (Options & XTE_MULTICAST_OPTION) {
+ Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET);
+ Reg &= ~XTE_RAF_MCSTREJ_MASK;
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET, Reg);
+ }
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: rcw1 is now (raf2): 0x%0x\n",
+ XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET));
+
+ /* 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;
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "setOptions: rcw1 is now (end): 0x%0x\n",
+ XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET));
+ xdbg_printf(XDBG_DEBUG_GENERAL, "setOptions: returning SUCCESS\n");
+ return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_ClearOptions clears the options, <i>Options</i> for the TEMAC channel,
+ * specified by <i>InstancePtr</i>. The TEMAC channel should be stopped with
+ * XLlTemac_Stop() before changing options.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Options is a bitmask of OR'd XTE_*_OPTION values for options to
+ * clear. Options not specified are not affected.
+ *
+ * @return On successful completion, XLlTemac_ClearOptions returns XST_SUCCESS.
+ * Otherwise, if the device has not been stopped, XLlTemac_ClearOptions
+ * returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ * See xlltemac.h for a description of the available options.
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_ClearOptions(XLlTemac *InstancePtr, u32 Options)
+{
+ u32 Reg; /* Generic */
+ u32 RegRcw1; /* Reflects original contents of RCW1 */
+ u32 RegTc; /* Reflects original contents of TC */
+ u32 RegNewRcw1; /* Reflects new contents of RCW1 */
+ u32 RegNewTc; /* Reflects new contents of TC */
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "Xtemac_ClearOptions: 0x%08x\n",
+ Options);
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Many of these options will change the RCW1 or TC registers.
+ * Group these options here and change them all at once. What we are
+ * trying to accomplish is to reduce the amount of IO to the device
+ */
+
+ /* Grab current register contents */
+ RegRcw1 = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ RegTc = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET);
+ RegNewRcw1 = RegRcw1;
+ RegNewTc = RegTc;
+
+ /* Turn off jumbo packet support for both Rx and Tx */
+ if (Options & XTE_JUMBO_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling jumbo\n");
+ RegNewTc &= ~XTE_TC_JUM_MASK;
+ RegNewRcw1 &= ~XTE_RCW1_JUM_MASK;
+ }
+
+ /* Turn off VLAN packet support for both Rx and Tx */
+ if (Options & XTE_VLAN_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling vlan\n");
+ RegNewTc &= ~XTE_TC_VLAN_MASK;
+ RegNewRcw1 &= ~XTE_RCW1_VLAN_MASK;
+ }
+
+ /* Turn off FCS stripping on receive packets */
+ if (Options & XTE_FCS_STRIP_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling fcs strip\n");
+ RegNewRcw1 |= XTE_RCW1_FCS_MASK;
+ }
+
+ /* Turn off FCS insertion on transmit packets */
+ if (Options & XTE_FCS_INSERT_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling fcs insert\n");
+ RegNewTc |= XTE_TC_FCS_MASK;
+ }
+
+ /* Turn off length/type field checking on receive packets */
+ if (Options & XTE_LENTYPE_ERR_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling lentype err\n");
+ RegNewRcw1 |= XTE_RCW1_LT_DIS_MASK;
+ }
+
+ /* Disable transmitter */
+ if (Options & XTE_TRANSMITTER_ENABLE_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling transmitter\n");
+ RegNewTc &= ~XTE_TC_TX_MASK;
+ }
+
+ /* Disable receiver */
+ if (Options & XTE_RECEIVER_ENABLE_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling receiver\n");
+ RegNewRcw1 &= ~XTE_RCW1_RX_MASK;
+ }
+
+ /* Change the TC and RCW1 registers if they need to be
+ * modified
+ */
+ if (RegTc != RegNewTc) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: setting TC: 0x%0x\n",
+ RegNewTc);
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TC_OFFSET, RegNewTc);
+ }
+
+ if (RegRcw1 != RegNewRcw1) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: setting RCW1: 0x%0x\n",
+ RegNewRcw1);
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET, RegNewRcw1);
+ }
+
+ /* Rest of options twiddle bits of other registers. Handle them one at
+ * a time
+ */
+
+ /* Turn off flow control */
+ if (Options & XTE_FLOW_CONTROL_OPTION) {
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_FCC_OFFSET);
+ Reg &= ~XTE_FCC_FCRX_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_FCC_OFFSET, Reg);
+ }
+
+ /* Turn off promiscuous frame filtering */
+ if (Options & XTE_PROMISC_OPTION) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: disabling promiscuous mode\n");
+ Reg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_AFM_OFFSET);
+ Reg &= ~XTE_AFM_PM_MASK;
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "Xtemac_ClearOptions: setting AFM: 0x%0x\n", Reg);
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_AFM_OFFSET, Reg);
+ }
+
+ /* Disable broadcast address filtering */
+ if (Options & XTE_BROADCAST_OPTION) {
+ Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET);
+ Reg |= XTE_RAF_BCSTREJ_MASK;
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET, Reg);
+ }
+
+ /* Disable multicast address filtering */
+ if (Options & XTE_MULTICAST_OPTION) {
+ Reg = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_OFFSET);
+ Reg |= XTE_RAF_MCSTREJ_MASK;
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress,
+ XTE_RAF_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);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetOptions returns the current option settings.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_GetOptions returns a bitmask of XTE_*_OPTION constants,
+ * each bit specifying an option that is currently active.
+ *
+ * @note
+ * See xlltemac.h for a description of the available options.
+ *
+ ******************************************************************************/
+u32 XLlTemac_GetOptions(XLlTemac *InstancePtr)
+{
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+ return (InstancePtr->Options);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetOperatingSpeed gets the current operating link speed. This may be
+ * the value set by XLlTemac_SetOperatingSpeed() or a hardware default.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ *
+ * @return XLlTemac_GetOperatingSpeed returns the link speed in units of megabits
+ * per second.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+u16 XLlTemac_GetOperatingSpeed(XLlTemac *InstancePtr)
+{
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_GetOperatingSpeed\n");
+ switch (XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_EMMC_OFFSET) &
+ XTE_EMMC_LINKSPEED_MASK) {
+ case XTE_EMMC_LINKSPD_1000:
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_GetOperatingSpeed: returning 1000\n");
+ return (1000);
+
+ case XTE_EMMC_LINKSPD_100:
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_GetOperatingSpeed: returning 100\n");
+ return (100);
+
+ case XTE_EMMC_LINKSPD_10:
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_GetOperatingSpeed: returning 10\n");
+ return (10);
+
+ default:
+ return (0);
+ }
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_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. XLlTemac_SetOperatingSpeed ignores invalid values.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_SetOperatingSpeed(XLlTemac *InstancePtr, u16 Speed)
+{
+ u32 EmmcReg;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_VOID((Speed == 10) || (Speed == 100) || (Speed == 1000));
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetOperatingSpeed\n");
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SetOperatingSpeed: setting speed to: %d (0x%0x)\n",
+ Speed, Speed);
+ /* Get the current contents of the EMAC config register and zero out
+ * speed bits
+ */
+ EmmcReg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_EMMC_OFFSET) &
+ ~XTE_EMMC_LINKSPEED_MASK;
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SetOperatingSpeed: current speed: 0x%0x\n",
+ EmmcReg);
+ switch (Speed) {
+ case 10:
+ break;
+
+ case 100:
+ EmmcReg |= XTE_EMMC_LINKSPD_100;
+ break;
+
+ case 1000:
+ EmmcReg |= XTE_EMMC_LINKSPD_1000;
+ break;
+
+ default:
+ return;
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SetOperatingSpeed: new speed: 0x%0x\n", EmmcReg);
+ /* Set register and return */
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_EMMC_OFFSET, EmmcReg);
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetOperatingSpeed: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_PhySetMdioDivisor sets the MDIO clock divisor in the TEMAC channel,
+ * specified by <i>InstancePtr</i> to the value, <i>Divisor</i>. This function
+ * must be called once after each reset prior to accessing MII PHY registers.
+ *
+ * From the Virtex-4 Embedded Tri-Mode Ethernet MAC User's Guide, the
+ * following equation governs the MDIO clock to the PHY:
+ *
+ * <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.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Divisor is the divisor value to set within the range of 0 to
+ * XTE_MC_CLK_DVD_MAX.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_PhySetMdioDivisor(XLlTemac *InstancePtr, u8 Divisor)
+{
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY)
+ XASSERT_VOID(Divisor <= XTE_MC_CLOCK_DIVIDE_MAX);
+
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_PhySetMdioDivisor\n");
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_MC_OFFSET,
+ (u32) Divisor | XTE_MC_MDIOEN_MASK);
+}
+
+/*****************************************************************************/
+/*
+ * XLlTemac_PhyRead reads the specified PHY register, <i>RegiseterNum</i> on the
+ * PHY specified by <i>PhyAddress</i> into <i>PhyDataPtr</i>. This Ethernet
+ * driver does not require the device to be stopped before reading from the PHY.
+ * It is the responsibility of the calling code to stop the device if it is
+ * deemed necessary.
+ *
+ * Note that the TEMAC hardware provides the ability to talk to a PHY that
+ * adheres to the Media Independent Interface (MII) as defined in the IEEE 802.3
+ * standard.
+ *
+ * <b>It is important that calling code set up the MDIO clock with
+ * XLlTemac_PhySetMdioDivisor() prior to accessing the PHY with this function.</b>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param PhyAddress is the address of the PHY to be written (multiple
+ * PHYs supported).
+ * @param RegisterNum is the register number, 0-31, of the specific PHY register
+ * to write.
+ * @param PhyDataPtr is a reference to the location where the 16-bit result
+ * value is stored.
+ *
+ * @return N/A
+ *
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.<br><br>
+ *
+ * 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, the calling code should provide a mechanism
+ * suitable for recovery.
+ *
+ ******************************************************************************/
+void XLlTemac_PhyRead(XLlTemac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 *PhyDataPtr)
+{
+ u32 MiiReg;
+ u32 Rdy;
+ u32 Ie;
+ u32 Tis;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_PhyRead: BaseAddress: 0x%08x\n",
+ InstancePtr->Config.BaseAddress);
+ /*
+ * XLlTemac_PhyRead saves the state of the IE register so that it can
+ * clear the HardAcsCmplt bit and later restore the state of the IE
+ * register. Since XLlTemac_PhyRead will poll for the status already, the
+ * HardAcsCmplt bit is cleared in the IE register so that the
+ * application code above doesn't also receive the interrupt.
+ */
+ Ie = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET);
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET,
+ Ie & ~XTE_INT_HARDACSCMPLT_MASK);
+
+ /*
+ * This is a double indirect mechanism. We indirectly write the
+ * PHYAD and REGAD so we can read the PHY register back out in
+ * the LSW register.
+ *
+ * In this case, the method of reading the data is a little unusual.
+ * Normally to write to a TEMAC register, one would set the WEN bit
+ * in the CTL register so that the values of the LSW will be written.
+ *
+ * In this case, the WEN bit is not set, and the PHYAD and REGAD
+ * values in the LSW will still get sent to the PHY before actually
+ * reading the result in the LSW.
+ *
+ * What needs to be done, is the following:
+ * 1) Write lsw reg with the phyad, and the regad
+ * 2) write the ctl reg with the miimai value (BUT WEN bit set to 0!!!)
+ * 3) poll the ready bit
+ * 4) get the value out of lsw
+ */
+ MiiReg = RegisterNum & XTE_MIIM_REGAD_MASK;
+ MiiReg |= ((PhyAddress << XTE_MIIM_PHYAD_SHIFT) & XTE_MIIM_PHYAD_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_PhyRead: Mii Reg: 0x%0x; Value written: 0x%0x\n",
+ RegisterNum, MiiReg);
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_LSW_OFFSET,
+ MiiReg);
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_CTL_OFFSET,
+ XTE_MIIMAI_OFFSET);
+
+ /*
+ * Wait here polling, until the value is ready to be read.
+ */
+ do {
+ Rdy = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET);
+ } while (!(Rdy & XTE_RSE_MIIM_RR_MASK));
+
+ /* Read data */
+ *PhyDataPtr = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_LSW_OFFSET);
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_PhyRead: Value retrieved: 0x%0x\n", *PhyDataPtr);
+
+ /*
+ * Clear MII status bits. The TIS register in the hard TEMAC doesn't
+ * use the 'write a 1 to clear' method, so we need to read the TIS
+ * register, clear the MIIM RST bit, and then write it back out.
+ */
+ Tis = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TIS_OFFSET);
+ Tis &= ~XTE_RSE_MIIM_RR_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TIS_OFFSET, Tis);
+
+ /*
+ * restore the state of the IE reg
+ */
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET, Ie);
+}
+
+
+/*****************************************************************************/
+/*
+ * XLlTemac_PhyWrite writes <i>PhyData</i> to the specified PHY register,
+ * <i>RegiseterNum</i> on the PHY specified by <i>PhyAddress</i>. This Ethernet
+ * driver does not require the device to be stopped before writing to the PHY.
+ * It is the responsibility of the calling code to stop the device if it is
+ * deemed necessary.
+ *
+ * Note that the TEMAC hardware provides the ability to talk to a PHY that
+ * adheres to the Media Independent Interface (MII) as defined in the IEEE 802.3
+ * standard.
+ *
+ * <b>It is important that calling code set up the MDIO clock with
+ * XLlTemac_PhySetMdioDivisor() prior to accessing the PHY with this function.</b>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param PhyAddress is the address of the PHY to be written (multiple
+ * PHYs supported).
+ * @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 N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.<br><br>
+ *
+ * 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, the calling code should provide a mechanism
+ * suitable for recovery.
+ *
+ ******************************************************************************/
+void XLlTemac_PhyWrite(XLlTemac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 PhyData)
+{
+ u32 MiiReg;
+ u32 Rdy;
+ u32 Ie;
+ u32 Tis;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_PhyWrite\n");
+ /*
+ * XLlTemac_PhyWrite saves the state of the IE register so that it can
+ * clear the HardAcsCmplt bit and later restore the state of the IE
+ * register. Since XLlTemac_PhyWrite will poll for the status already, the
+ * HardAcsCmplt bit is cleared in the IE register so that the
+ * application code above doesn't also receive the interrupt.
+ */
+ Ie = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET);
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET,
+ Ie & ~XTE_INT_HARDACSCMPLT_MASK);
+
+ /*
+ * This is a double indirect mechanism. We indirectly write the
+ * PhyData to the MIIMWD register, and then indirectly write PHYAD and
+ * REGAD so the value in MIIMWD will get written to the PHY.
+ */
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_MIIMWD_OFFSET, PhyData);
+
+ MiiReg = RegisterNum & XTE_MIIM_REGAD_MASK;
+ MiiReg |= ((PhyAddress << XTE_MIIM_PHYAD_SHIFT) & XTE_MIIM_PHYAD_MASK);
+
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_MIIMAI_OFFSET, MiiReg);
+
+ /*
+ * Wait here polling, until the value is ready to be read.
+ */
+ do {
+ Rdy = XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET);
+ } while (!(Rdy & XTE_RSE_MIIM_WR_MASK));
+
+ /*
+ * Clear MII status bits. The TIS register in the hard TEMAC doesn't
+ * use the 'write a 1 to clear' method, so we need to read the TIS
+ * register, clear the MIIM WST bit, and then write it back out.
+ */
+ Tis = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TIS_OFFSET);
+ Tis &= XTE_RSE_MIIM_WR_MASK;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_TIS_OFFSET, Tis);
+
+ /*
+ * restore the state of the IE reg
+ */
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_IE_OFFSET, Ie);
+}
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_control.c
===================================================================
--- /dev/null
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_control.c
@@ -0,0 +1,671 @@
+/* $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 2005-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac_control.c
+ *
+ * Functions in this file implement general purpose command and control related
+ * functionality. See xlltemac.h for a detailed description of the driver.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 11/10/06 First release
+ * </pre>
+ *****************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xlltemac.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/**************************** Type Definitions *******************************/
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+
+/************************** Function Prototypes ******************************/
+
+
+/************************** Variable Definitions *****************************/
+
+
+/*****************************************************************************/
+/**
+ * in the TEMAC channel's multicast filter list.
+ *
+ * XLlTemac_MulticastAdd adds the Ethernet address, <i>AddressPtr</i> to the
+ * TEMAC channel's multicast filter list, at list index <i>Entry</i>. The
+ * address referenced by <i>AddressPtr</i> may be of any unicast, multicast, or
+ * broadcast address form. The harware for the TEMAC channel can hold up to
+ * XTE_MULTI_MAT_ENTRIES addresses in this filter list.<br><br>
+ *
+ * The device must be stopped to use this function.<br><br>
+ *
+ * Once an Ethernet address is programmed, the TEMAC channel will begin
+ * receiving data sent from that address. The TEMAC hardware does not have a
+ * control bit to disable multicast filtering. The only way to prevent the
+ * TEMAC channel from receiving messages from an Ethernet address in the
+ * Multicast Address Table (MAT) is to clear it with XLlTemac_MulticastClear().
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr is a pointer to the 6-byte Ethernet address to set. The
+ * previous address at the location <i>Entry</i> (if any) is overwritten
+ * with the value at <i>AddressPtr</i>.
+ * @param Entry is the hardware storage location to program this address and
+ * must be between 0..XTE_MULTI_MAT_ENTRIES-1.
+ *
+ * @return On successful completion, XLlTemac_MulticastAdd returns XST_SUCCESS.
+ * Otherwise, if the TEMAC channel is not stopped, XLlTemac_MulticastAdd
+ * returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_MulticastAdd(XLlTemac *InstancePtr, void *AddressPtr, int Entry)
+{
+ u32 Maw0Reg;
+ u32 Maw1Reg;
+ u8 *Aptr = (u8 *) AddressPtr;
+ u32 Rdy;
+ int MaxWait = 100;
+ u32 BaseAddress = InstancePtr->Config.BaseAddress;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(AddressPtr != NULL);
+ XASSERT_NONVOID(Entry < XTE_MULTI_MAT_ENTRIES);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastAdd\n");
+
+ /* The device must be stopped before clearing the multicast hash table */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_MulticastAdd: returning DEVICE_IS_STARTED\n");
+
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Set MAC bits [31:0] */
+ Maw0Reg = Aptr[0];
+ Maw0Reg |= Aptr[1] << 8;
+ Maw0Reg |= Aptr[2] << 16;
+ Maw0Reg |= Aptr[3] << 24;
+
+ /* Set MAC bits [47:32] */
+ Maw1Reg = Aptr[4];
+ Maw1Reg |= Aptr[5] << 8;
+
+ /* Add in MAT address */
+ Maw1Reg |= (Entry << XTE_MAW1_MATADDR_SHIFT_MASK);
+
+ /* Program HW */
+ xdbg_printf(XDBG_DEBUG_GENERAL, "Setting MAT entry: %d\n", Entry);
+ XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET, Maw0Reg);
+ XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
+ XTE_MAW0_OFFSET | XTE_CTL_WEN_MASK);
+ Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+ while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
+ Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+ xdbg_stmnt(
+ if (MaxWait == 100) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "RDY reg not initially ready\n");
+ }
+ );
+ MaxWait--;
+ xdbg_stmnt(
+ if (MaxWait == 0) {
+ xdbg_printf (XDBG_DEBUG_GENERAL,
+ "RDY reg never showed ready\n");
+ }
+ )
+ }
+ XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET,
+ Maw1Reg);
+ XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
+ XTE_MAW1_OFFSET | XTE_CTL_WEN_MASK);
+ Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+ while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
+ Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+ xdbg_stmnt(
+ if (MaxWait == 100) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "RDY reg not initially ready\n");
+ }
+ );
+ MaxWait--;
+ xdbg_stmnt(
+ if (MaxWait == 0) {
+ xdbg_printf (XDBG_DEBUG_GENERAL,
+ "RDY reg never showed ready\n");
+ }
+ )
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastAdd: returning SUCCESS\n");
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_MulticastGet gets the Ethernet address stored at index <i>Entry</i>
+ * in the TEMAC channel's multicast filter list.<br><br>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr references the memory buffer to store the retrieved
+ * Ethernet address. This memory buffer must be at least 6 bytes in
+ * length.
+ * @param Entry is the hardware storage location from which to retrieve the
+ * address and must be between 0..XTE_MULTI_MAT_ENTRIES-1.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_MulticastGet(XLlTemac *InstancePtr, void *AddressPtr, int Entry)
+{
+ u32 Maw0Reg;
+ u32 Maw1Reg;
+ u8 *Aptr = (u8 *) AddressPtr;
+ u32 Rdy;
+ int MaxWait = 100;
+ u32 BaseAddress = InstancePtr->Config.BaseAddress;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_VOID(Entry < XTE_MULTI_MAT_ENTRIES);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET) &
+ XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastGet\n");
+
+ /*
+ * Tell HW to provide address stored in given entry.
+ * In this case, the Access is a little weird, becuase we need to
+ * write the LSW register first, then initiate a write operation,
+ * even though it's a read operation.
+ */
+ xdbg_printf(XDBG_DEBUG_GENERAL, "Getting MAT entry: %d\n", Entry);
+ XLlTemac_WriteReg(BaseAddress, XTE_LSW_OFFSET,
+ Entry << XTE_MAW1_MATADDR_SHIFT_MASK | XTE_MAW1_RNW_MASK);
+ XLlTemac_WriteReg(BaseAddress, XTE_CTL_OFFSET,
+ XTE_MAW1_OFFSET | XTE_CTL_WEN_MASK);
+ Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+ while (MaxWait && (!(Rdy & XTE_RDY_HARD_ACS_RDY_MASK))) {
+ Rdy = XLlTemac_ReadReg(BaseAddress, XTE_RDY_OFFSET);
+ xdbg_stmnt(
+ if (MaxWait == 100) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "RDY reg not initially ready\n");
+ }
+ );
+ MaxWait--;
+ xdbg_stmnt(
+ if (MaxWait == 0) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "RDY reg never showed ready\n");
+ }
+ )
+
+ }
+ Maw0Reg = XLlTemac_ReadReg(BaseAddress, XTE_LSW_OFFSET);
+ Maw1Reg = XLlTemac_ReadReg(BaseAddress, XTE_MSW_OFFSET);
+
+ /* Copy the address to the user buffer */
+ Aptr[0] = (u8) Maw0Reg;
+ Aptr[1] = (u8) (Maw0Reg >> 8);
+ Aptr[2] = (u8) (Maw0Reg >> 16);
+ Aptr[3] = (u8) (Maw0Reg >> 24);
+ Aptr[4] = (u8) Maw1Reg;
+ Aptr[5] = (u8) (Maw1Reg >> 8);
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastGet: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_MulticastClear clears the Ethernet address stored at index <i>Entry</i>
+ * in the TEMAC channel's multicast filter list.<br><br>
+ *
+ * The device must be stopped to use this function.<br><br>
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param Entry is the HW storage location used when this address was added.
+ * It must be between 0..XTE_MULTI_MAT_ENTRIES-1.
+ * @param Entry is the hardware storage location to clear and must be between
+ * 0..XTE_MULTI_MAT_ENTRIES-1.
+ *
+ * @return On successful completion, XLlTemac_MulticastClear returns XST_SUCCESS.
+ * Otherwise, if the TEMAC channel is not stopped, XLlTemac_MulticastClear
+ * returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_MulticastClear(XLlTemac *InstancePtr, int Entry)
+{
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ XASSERT_NONVOID(Entry < XTE_MULTI_MAT_ENTRIES);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_MulticastClear\n");
+
+ /* The device must be stopped before clearing the multicast hash table */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_MulticastClear: returning DEVICE_IS_STARTED\n");
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Clear the entry by writing 0:0:0:0:0:0 to it */
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_MAW0_OFFSET, 0);
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_MAW1_OFFSET, Entry << XTE_MAW1_MATADDR_SHIFT_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_MulticastClear: returning SUCCESS\n");
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SetMacPauseAddress sets the MAC address used for pause frames to
+ * <i>AddressPtr</i>. <i>AddressPtr</i> will be the address the TEMAC channel
+ * will recognize as being for pause frames. Pause frames transmitted with
+ * XLlTemac_SendPausePacket() will also use this address.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr is a pointer to the 6-byte Ethernet address to set.
+ *
+ * @return On successful completion, XLlTemac_SetMacPauseAddress returns
+ * XST_SUCCESS. Otherwise, if the TEMAC channel is not stopped,
+ * XLlTemac_SetMacPauseAddress returns XST_DEVICE_IS_STARTED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+ u32 MacAddr;
+ u8 *Aptr = (u8 *) AddressPtr;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress\n");
+ /* Be sure device has been stopped */
+ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SetMacPauseAddress: returning DEVICE_IS_STARTED\n");
+ return (XST_DEVICE_IS_STARTED);
+ }
+
+ /* Set the MAC bits [31:0] in ERXC0 */
+ MacAddr = Aptr[0];
+ MacAddr |= Aptr[1] << 8;
+ MacAddr |= Aptr[2] << 16;
+ MacAddr |= Aptr[3] << 24;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW0_OFFSET, MacAddr);
+
+ /* ERCW1 contains other info that must be preserved */
+ MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ MacAddr &= ~XTE_RCW1_PAUSEADDR_MASK;
+
+ /* Set MAC bits [47:32] */
+ MacAddr |= Aptr[4];
+ MacAddr |= Aptr[5] << 8;
+ XLlTemac_WriteIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET, MacAddr);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SetMacPauseAddress: returning SUCCESS\n");
+
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetMacPauseAddress gets the MAC address used for pause frames for the
+ * TEMAC channel specified by <i>InstancePtr</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param AddressPtr references the memory buffer to store the retrieved MAC
+ * address. This memory buffer must be at least 6 bytes in length.
+ *
+ * @return N/A
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+void XLlTemac_GetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+ u32 MacAddr;
+ u8 *Aptr = (u8 *) AddressPtr;
+
+ XASSERT_VOID(InstancePtr != NULL);
+ XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_VOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress\n");
+
+ /* Read MAC bits [31:0] in ERXC0 */
+ MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW0_OFFSET);
+ 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 RCW1 */
+ MacAddr = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_RCW1_OFFSET);
+ Aptr[4] = (u8) MacAddr;
+ Aptr[5] = (u8) (MacAddr >> 8);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress: done\n");
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_SendPausePacket sends a pause packet with the value of
+ * <i>PauseValue</i>.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param PauseValue is the pause value in units of 512 bit times.
+ *
+ * @return On successful completion, XLlTemac_SendPausePacket returns
+ * XST_SUCCESS. Otherwise, if the TEMAC channel is not started,
+ * XLlTemac_SendPausePacket returns XST_DEVICE_IS_STOPPED.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_SendPausePacket(XLlTemac *InstancePtr, u16 PauseValue)
+{
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_SetMacPauseAddress\n");
+
+ /* Make sure device is ready for this operation */
+ if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SendPausePacket: returning DEVICE_IS_STOPPED\n");
+ return (XST_DEVICE_IS_STOPPED);
+ }
+
+ /* Send flow control frame */
+ XLlTemac_WriteReg(InstancePtr->Config.BaseAddress, XTE_TPF_OFFSET,
+ (u32) PauseValue & XTE_TPF_TPFV_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_SendPausePacket: returning SUCCESS\n");
+ return (XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetSgmiiStatus get the state of the link when using the SGMII media
+ * interface.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param SpeedPtr references the location to store the result, which is the
+ * autonegotiated link speed in units of Mbits/sec, either 0, 10, 100,
+ * or 1000.
+ *
+ * @return On successful completion, XLlTemac_GetSgmiiStatus returns XST_SUCCESS.
+ * Otherwise, if TEMAC channel is not using an SGMII interface,
+ * XLlTemac_GetSgmiiStatus returns XST_NO_FEATURE.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_GetSgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr)
+{
+ int PhyType;
+ u32 EgmicReg;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_GetSgmiiStatus\n");
+ /* Make sure PHY is SGMII */
+ PhyType = XLlTemac_GetPhysicalInterface(InstancePtr);
+ if (PhyType != XTE_PHY_TYPE_SGMII) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_GetSgmiiStatus: returning NO_FEATURE\n");
+ return (XST_NO_FEATURE);
+ }
+
+ /* Get the current contents of RGMII/SGMII config register */
+ EgmicReg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_PHYC_OFFSET);
+
+ /* Extract speed */
+ switch (EgmicReg & XTE_PHYC_SGMIILINKSPEED_MASK) {
+ case XTE_PHYC_SGLINKSPD_10:
+ *SpeedPtr = 10;
+ break;
+
+ case XTE_PHYC_SGLINKSPD_100:
+ *SpeedPtr = 100;
+ break;
+
+ case XTE_PHYC_SGLINKSPD_1000:
+ *SpeedPtr = 1000;
+ break;
+
+ default:
+ *SpeedPtr = 0;
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_GetSgmiiStatus: returning SUCCESS\n");
+ return (XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+ * XLlTemac_GetRgmiiStatus get the state of the link when using the RGMII media
+ * interface.
+ *
+ * @param InstancePtr references the TEMAC channel on which to operate.
+ * @param SpeedPtr references the location to store the result, which is the
+ * autonegotiaged link speed in units of Mbits/sec, either 0, 10, 100,
+ * or 1000.
+ * @param IsFullDuplexPtr references the value to set to indicate full duplex
+ * operation. XLlTemac_GetRgmiiStatus sets <i>IsFullDuplexPtr</i> to TRUE
+ * when the RGMII link is operating in full duplex mode. Otherwise,
+ * XLlTemac_GetRgmiiStatus sets <i>IsFullDuplexPtr</i> to FALSE.
+ * @param IsLinkUpPtr references the value to set to indicate the link status.
+ * XLlTemac_GetRgmiiStatus sets <i>IsLinkUpPtr</i> to TRUE when the RGMII
+ * link up. Otherwise, XLlTemac_GetRgmiiStatus sets <i>IsLinkUpPtr</i> to
+ * FALSE.
+ *
+ * @return On successful completion, XLlTemac_GetRgmiiStatus returns XST_SUCCESS.
+ * Otherwise, if TEMAC channel is not using an RGMII interface,
+ * XLlTemac_GetRgmiiStatus returns XST_NO_FEATURE.
+ *
+ * @note
+ *
+ * This routine accesses the hard TEMAC registers through a shared interface
+ * between both channels of the TEMAC. Becuase of this, the application/OS code
+ * must provide mutual exclusive access to this routine with any of the other
+ * routines in this TEMAC driverr.
+ *
+ ******************************************************************************/
+int XLlTemac_GetRgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr,
+ int *IsFullDuplexPtr, int *IsLinkUpPtr)
+{
+ int PhyType;
+ u32 EgmicReg;
+
+ XASSERT_NONVOID(InstancePtr != NULL);
+ XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+ /*
+ * If the mutual exclusion is enforced properly in the calling code, we
+ * should never get into the following case.
+ */
+ XASSERT_NONVOID(XLlTemac_ReadReg(InstancePtr->Config.BaseAddress,
+ XTE_RDY_OFFSET) & XTE_RDY_HARD_ACS_RDY_MASK);
+
+ xdbg_printf(XDBG_DEBUG_GENERAL, "XLlTemac_GetRgmiiStatus\n");
+ /* Make sure PHY is RGMII */
+ PhyType = XLlTemac_GetPhysicalInterface(InstancePtr);
+ if ((PhyType != XTE_PHY_TYPE_RGMII_1_3) &&
+ (PhyType != XTE_PHY_TYPE_RGMII_2_0)) {
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_GetRgmiiStatus: returning NO_FEATURE\n");
+ return (XST_NO_FEATURE);
+ }
+
+ /* Get the current contents of RGMII/SGMII config register */
+ EgmicReg = XLlTemac_ReadIndirectReg(InstancePtr->Config.BaseAddress,
+ XTE_PHYC_OFFSET);
+
+ /* Extract speed */
+ switch (EgmicReg & XTE_PHYC_RGMIILINKSPEED_MASK) {
+ case XTE_PHYC_RGLINKSPD_10:
+ *SpeedPtr = 10;
+ break;
+
+ case XTE_PHYC_RGLINKSPD_100:
+ *SpeedPtr = 100;
+ break;
+
+ case XTE_PHYC_RGLINKSPD_1000:
+ *SpeedPtr = 1000;
+ break;
+
+ default:
+ *SpeedPtr = 0;
+ }
+
+ /* Extract duplex and link status */
+ if (EgmicReg & XTE_PHYC_RGMIIHD_MASK) {
+ *IsFullDuplexPtr = FALSE;
+ }
+ else {
+ *IsFullDuplexPtr = TRUE;
+ }
+
+ if (EgmicReg & XTE_PHYC_RGMIILINK_MASK) {
+ *IsLinkUpPtr = TRUE;
+ }
+ else {
+ *IsLinkUpPtr = FALSE;
+ }
+
+ xdbg_printf(XDBG_DEBUG_GENERAL,
+ "XLlTemac_GetRgmiiStatus: returning SUCCESS\n");
+ return (XST_SUCCESS);
+}
+
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/Makefile
===================================================================
--- /dev/null
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the Xilinx Tri-mode ethernet driver
+#
+
+EXTRA_CFLAGS += -Idrivers/xilinx_common
+
+# The Linux adapter for the Xilinx driver code.
+xilinx_temac-objs := xlltemac_main.o xlltemac.o xlltemac_control.o
+
+obj-$(CONFIG_XILINX_LLTEMAC) := xilinx_temac.o
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_hw.h
===================================================================
--- /dev/null
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_hw.h
@@ -0,0 +1,554 @@
+/* iId: */
+/******************************************************************************
+*
+* 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 2004-2006 Xilinx Inc.
+* All rights reserved.
+*
+******************************************************************************/
+
+/*****************************************************************************/
+/**
+ *
+ * @file xlltemac_hw.h
+ *
+ * This header file contains identifiers and low-level driver functions (or
+ * macros) that can be used to access the Tri-Mode MAC Ethernet (TEMAC) device.
+ * High-level driver functions are defined in xlltemac.h.
+ *
+ * @note
+ *
+ * Some registers are not accessible when a HW instance is configured for SGDMA.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 11/10/06 First release
+ * </pre>
+ *
+ ******************************************************************************/
+
+#ifndef XTEMAC_HW_H /* prevent circular inclusions */
+#define XTEMAC_HW_H /* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xdebug.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/************************** Constant Definitions *****************************/
+
+#define XTE_RESET_HARD_DELAY_US 4 /**< Us to delay for hard core reset */
+
+/* Register offset definitions. Unless otherwise noted, register access is
+ * 32 bit.
+ */
+
+/** @name Direct registers
+ * @{
+ */
+#define XTE_RAF_OFFSET 0x00000000 /**< Reset and address filter */
+#define XTE_TPF_OFFSET 0x00000004 /**< Transmit pause frame */
+#define XTE_IFGP_OFFSET 0x00000008 /**< Transmit inter-frame gap adjustment */
+#define XTE_IS_OFFSET 0x0000000C /**< Interrupt status */
+#define XTE_IP_OFFSET 0x00000010 /**< Interrupt pending */
+#define XTE_IE_OFFSET 0x00000014 /**< Interrupt enable */
+
+#define XTE_MSW_OFFSET 0x00000020 /**< Most significant word data */
+#define XTE_LSW_OFFSET 0x00000024 /**< Least significant word data */
+#define XTE_CTL_OFFSET 0x00000028 /**< Control */
+#define XTE_RDY_OFFSET 0x0000002C /**< Ready status */
+/*@}*/
+
+
+/** @name HARD_TEMAC Core Registers
+ * These are registers defined within the device's hard core located in the
+ * processor block. They are accessed indirectly through the registers, MSW,
+ * LSW, and CTL.
+ *
+ * Access to these registers should go through macros XLlTemac_ReadIndirectReg()
+ * and XLlTemac_WriteIndirectReg() to guarantee proper access.
+ * @{
+ */
+#define XTE_RCW0_OFFSET 0x00000200 /**< Rx configuration word 0 */
+#define XTE_RCW1_OFFSET 0x00000240 /**< Rx configuration word 1 */
+#define XTE_TC_OFFSET 0x00000280 /**< Tx configuration */
+#define XTE_FCC_OFFSET 0x000002C0 /**< Flow control configuration */
+#define XTE_EMMC_OFFSET 0x00000300 /**< EMAC mode configuration */
+#define XTE_PHYC_OFFSET 0x00000320 /**< RGMII/SGMII configuration */
+#define XTE_MC_OFFSET 0x00000340 /**< Management configuration */
+#define XTE_UAW0_OFFSET 0x00000380 /**< Unicast address word 0 */
+#define XTE_UAW1_OFFSET 0x00000384 /**< Unicast address word 1 */
+#define XTE_MAW0_OFFSET 0x00000388 /**< Multicast address word 0 */
+#define XTE_MAW1_OFFSET 0x0000038C /**< Multicast address word 1 */
+#define XTE_AFM_OFFSET 0x00000390 /**< Address Filter (promiscuous) mode */
+#define XTE_TIS_OFFSET 0x000003A0 /**< Interrupt status */
+#define XTE_TIE_OFFSET 0x000003A4 /**< Interrupt enable */
+#define XTE_MIIMWD_OFFSET 0x000003B0 /**< MII management write data */
+#define XTE_MIIMAI_OFFSET 0x000003B4 /**< MII management access initiate */
+/*@}*/
+
+
+/* Register masks. The following constants define bit locations of various
+ * control bits in the registers. Constants are not defined for those registers
+ * that have a single bit field representing all 32 bits. For further
+ * information on the meaning of the various bit masks, refer to the HW spec.
+ */
+
+/** @name Reset and Address Filter bits
+ * These bits are associated with the XTE_RAF_OFFSET register.
+ * @{
+ */
+#define XTE_RAF_HTRST_MASK 0x00000001 /**< Hard TEMAC Reset */
+#define XTE_RAF_MCSTREJ_MASK 0x00000002 /**< Reject receive multicast destination address */
+#define XTE_RAF_BCSTREJ_MASK 0x00000004 /**< Reject receive broadcast destination address */
+/*@}*/
+
+/** @name Transmit Pause Frame Register (TPF)
+ * @{
+ */
+#define XTE_TPF_TPFV_MASK 0x0000FFFF /**< Tx pause frame value */
+/*@}*/
+
+/** @name Transmit Inter-Frame Gap Adjustement Register (TFGP)
+ * @{
+ */
+#define XTE_TFGP_IFGP_MASK 0x0000007F /**< Transmit inter-frame gap adjustment value */
+/*@}*/
+
+/** @name Interrupt bits
+ * These bits are associated with the XTE_IS_OFFSET, XTE_IP_OFFSET, and
+ * XTE_IE_OFFSET registers.
+ * @{
+ */
+#define XTE_INT_HARDACSCMPLT_MASK 0x00000001 /**< Hard register access complete */
+#define XTE_INT_AUTONEG_MASK 0x00000002 /**< Auto negotiation complete */
+#define XTE_INT_RC_MASK 0x00000004 /**< Receive complete */
+#define XTE_INT_RXRJECT_MASK 0x00000008 /**< Receive frame rejected */
+#define XTE_INT_RXFIFOOVR_MASK 0x00000010 /**< Receive fifo overrun */
+#define XTE_INT_TC_MASK 0x00000020 /**< Transmit complete */
+#define XTE_INT_ALL_MASK 0x0000003f /**< All the ints */
+/*@}*/
+
+
+#define XTE_INT_RECV_ERROR_MASK \
+ (XTE_INT_RXRJECT_MASK | XTE_INT_RXFIFOOVR_MASK) /**< INT bits that indicate receive errors */
+/*@}*/
+
+
+/** @name Control Register (CTL)
+ * @{
+ */
+#define XTE_CTL_WEN_MASK 0x00008000 /**< Write Enable */
+/*@}*/
+
+
+/** @name Ready Status, TEMAC Interrupt Status, TEMAC Interrupt Enable Registers
+ * (RDY, TIS, TIE)
+ * @{
+ */
+#define XTE_RSE_FABR_RR_MASK 0x00000001 /**< Fabric read ready */
+#define XTE_RSE_MIIM_RR_MASK 0x00000002 /**< MII management read ready */
+#define XTE_RSE_MIIM_WR_MASK 0x00000004 /**< MII management write ready */
+#define XTE_RSE_AF_RR_MASK 0x00000008 /**< Address filter read ready*/
+#define XTE_RSE_AF_WR_MASK 0x00000010 /**< Address filter write ready*/
+#define XTE_RSE_CFG_RR_MASK 0x00000020 /**< Configuration register read ready*/
+#define XTE_RSE_CFG_WR_MASK 0x00000040 /**< Configuration register write ready*/
+#define XTE_RDY_HARD_ACS_RDY_MASK 0x00010000 /**< Hard register access ready */
+#define XTE_RDY_ALL (XTE_RSE_FABR_RR_MASK | \
+ XTE_RSE_MIIM_RR_MASK | \
+ XTE_RSE_MIIM_WR_MASK | \
+ XTE_RSE_AF_RR_MASK | \
+ XTE_RSE_AF_WR_MASK | \
+ XTE_RSE_CFG_RR_MASK | \
+ XTE_RSE_CFG_WR_MASK | \
+ XTE_RDY_HARD_ACS_RDY_MASK)
+/*@}*/
+
+
+/** @name Receive Configuration Word 1 (RCW1)
+ * @{
+ */
+#define XTE_RCW1_RST_MASK 0x80000000 /**< Reset */
+#define XTE_RCW1_JUM_MASK 0x40000000 /**< Jumbo frame enable */
+#define XTE_RCW1_FCS_MASK 0x20000000 /**< In-Band FCS enable (FCS not stripped) */
+#define XTE_RCW1_RX_MASK 0x10000000 /**< Receiver enable */
+#define XTE_RCW1_VLAN_MASK 0x08000000 /**< VLAN frame enable */
+#define XTE_RCW1_HD_MASK 0x04000000 /**< Half duplex mode */
+#define XTE_RCW1_LT_DIS_MASK 0x02000000 /**< Length/type field valid check disable */
+#define XTE_RCW1_PAUSEADDR_MASK 0x0000FFFF /**< Pause frame source address
+ bits [47:32]. Bits [31:0]
+ are stored in register
+ RCW0 */
+/*@}*/
+
+
+/** @name Transmitter Configuration (TC)
+ * @{
+ */
+#define XTE_TC_RST_MASK 0x80000000 /**< reset */
+#define XTE_TC_JUM_MASK 0x40000000 /**< Jumbo frame enable */
+#define XTE_TC_FCS_MASK 0x20000000 /**< In-Band FCS enable (FCS not generated) */
+#define XTE_TC_TX_MASK 0x10000000 /**< Transmitter enable */
+#define XTE_TC_VLAN_MASK 0x08000000 /**< VLAN frame enable */
+#define XTE_TC_HD_MASK 0x04000000 /**< Half duplex mode */
+#define XTE_TC_IFG_MASK 0x02000000 /**< Inter-frame gap adjustment enable */
+/*@}*/
+
+
+/** @name Flow Control Configuration (FCC)
+ * @{
+ */
+#define XTE_FCC_FCRX_MASK 0x20000000 /**< Rx flow control enable */
+#define XTE_FCC_FCTX_MASK 0x40000000 /**< Tx flow control enable */
+/*@}*/
+
+
+/** @name EMAC Configuration (EMMC)
+ * @{
+ */
+#define XTE_EMMC_LINKSPEED_MASK 0xC0000000 /**< Link speed */
+#define XTE_EMMC_RGMII_MASK 0x20000000 /**< RGMII mode enable */
+#define XTE_EMMC_SGMII_MASK 0x10000000 /**< SGMII mode enable */
+#define XTE_EMMC_GPCS_MASK 0x08000000 /**< 1000BaseX mode enable */
+#define XTE_EMMC_HOST_MASK 0x04000000 /**< Host interface enable */
+#define XTE_EMMC_TX16BIT 0x02000000 /**< 16 bit Tx client enable */
+#define XTE_EMMC_RX16BIT 0x01000000 /**< 16 bit Rx client enable */
+
+#define XTE_EMMC_LINKSPD_10 0x00000000 /**< XTE_EMCFG_LINKSPD_MASK for
+ 10 Mbit */
+#define XTE_EMMC_LINKSPD_100 0x40000000 /**< XTE_EMCFG_LINKSPD_MASK for
+ 100 Mbit */
+#define XTE_EMMC_LINKSPD_1000 0x80000000 /**< XTE_EMCFG_LINKSPD_MASK for
+ 1000 Mbit */
+/*@}*/
+
+
+/** @name EMAC RGMII/SGMII Configuration (PHYC)
+ * @{
+ */
+#define XTE_PHYC_SGMIILINKSPEED_MASK 0xC0000000 /**< SGMII link speed */
+#define XTE_PHYC_RGMIILINKSPEED_MASK 0x0000000C /**< RGMII link speed */
+#define XTE_PHYC_RGMIIHD_MASK 0x00000002 /**< RGMII Half-duplex mode */
+#define XTE_PHYC_RGMIILINK_MASK 0x00000001 /**< RGMII link status */
+
+#define XTE_PHYC_RGLINKSPD_10 0x00000000 /**< XTE_GMIC_RGLINKSPD_MASK
+ for 10 Mbit */
+#define XTE_PHYC_RGLINKSPD_100 0x40000000 /**< XTE_GMIC_RGLINKSPD_MASK
+ for 100 Mbit */
+#define XTE_PHYC_RGLINKSPD_1000 0x80000000 /**< XTE_GMIC_RGLINKSPD_MASK
+ for 1000 Mbit */
+#define XTE_PHYC_SGLINKSPD_10 0x00000000 /**< XTE_SGMIC_RGLINKSPD_MASK
+ for 10 Mbit */
+#define XTE_PHYC_SGLINKSPD_100 0x00000004 /**< XTE_SGMIC_RGLINKSPD_MASK
+ for 100 Mbit */
+#define XTE_PHYC_SGLINKSPD_1000 0x00000008 /**< XTE_SGMIC_RGLINKSPD_MASK
+ for 1000 Mbit */
+/*@}*/
+
+
+/** @name EMAC Management Configuration (MC)
+ * @{
+ */
+#define XTE_MC_MDIOEN_MASK 0x00000040 /**< MII management enable */
+#define XTE_MC_CLOCK_DIVIDE_MAX 0x3F /**< Maximum MDIO divisor */
+/*@}*/
+
+
+/** @name EMAC Unicast Address Register Word 1 (UAW1)
+ * @{
+ */
+#define XTE_UAW1_UNICASTADDR_MASK 0x0000FFFF /**< Station address bits [47:32]
+ Station address bits [31:0]
+ are stored in register
+ UAW0 */
+/*@}*/
+
+
+/** @name EMAC Multicast Address Register Word 1 (MAW1)
+ * @{
+ */
+#define XTE_MAW1_RNW_MASK 0x00800000 /**< Multicast address table register read enable */
+#define XTE_MAW1_ADDR_MASK 0x00030000 /**< Multicast address table register address */
+#define XTE_MAW1_MULTICADDR_MASK 0x0000FFFF /**< Multicast address bits [47:32]
+ Multicast address bits [31:0]
+ are stored in register
+ MAW0 */
+#define XTE_MAW1_MATADDR_SHIFT_MASK 16 /**< Number of bits to shift right
+ to align with
+ XTE_MAW1_CAMADDR_MASK */
+/*@}*/
+
+
+/** @name EMAC Address Filter Mode (AFM)
+ * @{
+ */
+#define XTE_AFM_PM_MASK 0x80000000 /**< Promiscuous mode enable */
+/*@}*/
+
+
+/** @name Media Independent Interface Management (MIIM)
+ * @{
+ */
+#define XTE_MIIM_REGAD_MASK 0x1F /**< MII Phy register address (REGAD) */
+#define XTE_MIIM_PHYAD_MASK 0x03E0 /**< MII Phy address (PHYAD) */
+#define XTE_MIIM_PHYAD_SHIFT 5 /**< MII Shift bits for PHYAD */
+/*@}*/
+
+
+/** @name Checksum offload buffer descriptor extensions
+ * @{
+ */
+/** Byte offset where checksum should begin (16 bit word) */
+#define XTE_BD_TX_CSBEGIN_OFFSET XDMAV3_BD_USR0_OFFSET
+
+/** Offset where checksum should be inserted (16 bit word) */
+#define XTE_BD_TX_CSINSERT_OFFSET (XDMAV3_BD_USR0_OFFSET + 2)
+
+/** Checksum offload control for transmit (16 bit word) */
+#define XTE_BD_TX_CSCNTRL_OFFSET XDMAV3_BD_USR1_OFFSET
+
+/** Seed value for checksum calculation (16 bit word) */
+#define XTE_BD_TX_CSINIT_OFFSET (XDMAV3_BD_USR1_OFFSET + 2)
+
+/** Receive frame checksum calculation (16 bit word) */
+#define XTE_BD_RX_CSRAW_OFFSET (XDMAV3_BD_USR5_OFFSET + 2)
+
+/*@}*/
+
+/** @name TX_CSCNTRL bit mask
+ * @{
+ */
+#define XTE_BD_TX_CSCNTRL_CALC_MASK 0x0001 /**< Enable/disable Tx
+ checksum */
+/*@}*/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+xdbg_stmnt(extern int indent_on);
+
+#define XLlTemac_indent(RegOffset) \
+ ((indent_on && ((RegOffset) >= XTE_RAF_OFFSET) && ((RegOffset) <= XTE_RDY_OFFSET)) ? "\t" : "")
+
+#define XLlTemac_reg_name(RegOffset) \
+ (((RegOffset) == XTE_RAF_OFFSET) ? "XTE_RAF_OFFSET": \
+ ((RegOffset) == XTE_TPF_OFFSET) ? "XTE_TPF_OFFSET": \
+ ((RegOffset) == XTE_IFGP_OFFSET) ? "XTE_IFGP_OFFSET": \
+ ((RegOffset) == XTE_IS_OFFSET) ? "XTE_IS_OFFSET": \
+ ((RegOffset) == XTE_IP_OFFSET) ? "XTE_IP_OFFSET": \
+ ((RegOffset) == XTE_IE_OFFSET) ? "XTE_IE_OFFSET": \
+ ((RegOffset) == XTE_MSW_OFFSET) ? "XTE_MSW_OFFSET": \
+ ((RegOffset) == XTE_LSW_OFFSET) ? "XTE_LSW_OFFSET": \
+ ((RegOffset) == XTE_CTL_OFFSET) ? "XTE_CTL_OFFSET": \
+ ((RegOffset) == XTE_RDY_OFFSET) ? "XTE_RDY_OFFSET": \
+ ((RegOffset) == XTE_RCW0_OFFSET) ? "XTE_RCW0_OFFSET": \
+ ((RegOffset) == XTE_RCW1_OFFSET) ? "XTE_RCW1_OFFSET": \
+ ((RegOffset) == XTE_TC_OFFSET) ? "XTE_TC_OFFSET": \
+ ((RegOffset) == XTE_FCC_OFFSET) ? "XTE_FCC_OFFSET": \
+ ((RegOffset) == XTE_EMMC_OFFSET) ? "XTE_EMMC_OFFSET": \
+ ((RegOffset) == XTE_PHYC_OFFSET) ? "XTE_PHYC_OFFSET": \
+ ((RegOffset) == XTE_MC_OFFSET) ? "XTE_MC_OFFSET": \
+ ((RegOffset) == XTE_UAW0_OFFSET) ? "XTE_UAW0_OFFSET": \
+ ((RegOffset) == XTE_UAW1_OFFSET) ? "XTE_UAW1_OFFSET": \
+ ((RegOffset) == XTE_MAW0_OFFSET) ? "XTE_MAW0_OFFSET": \
+ ((RegOffset) == XTE_MAW1_OFFSET) ? "XTE_MAW1_OFFSET": \
+ ((RegOffset) == XTE_AFM_OFFSET) ? "XTE_AFM_OFFSET": \
+ ((RegOffset) == XTE_TIS_OFFSET) ? "XTE_TIS_OFFSET": \
+ ((RegOffset) == XTE_TIE_OFFSET) ? "XTE_TIE_OFFSET": \
+ ((RegOffset) == XTE_MIIMWD_OFFSET) ? "XTE_MIIMWD_OFFSET": \
+ ((RegOffset) == XTE_MIIMAI_OFFSET) ? "XTE_MIIMAI_OFFSET": \
+ "unknown")
+
+#define XLlTemac_print_reg_o(BaseAddress, RegOffset, Value) \
+ xdbg_printf(XDBG_DEBUG_TEMAC_REG, "%s0x%0x -> %s(0x%0x)\n", \
+ XLlTemac_indent(RegOffset), (Value), \
+ XLlTemac_reg_name(RegOffset), (RegOffset)) \
+
+#define XLlTemac_print_reg_i(BaseAddress, RegOffset, Value) \
+ xdbg_printf(XDBG_DEBUG_TEMAC_REG, "%s%s(0x%0x) -> 0x%0x\n", \
+ XLlTemac_indent(RegOffset), XLlTemac_reg_name(RegOffset), \
+ (RegOffset), (Value)) \
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_ReadReg returns the value read from the register specified by
+ * <i>RegOffset</i>.
+ *
+ * @param BaseAddress is the base address of the TEMAC channel.
+ * @param RegOffset is the offset of the register to be read.
+ *
+ * @return XLlTemac_ReadReg returns the 32-bit value of the register.
+ *
+ * @note
+ * C-style signature:
+ * u32 XLlTemac_mReadReg(u32 BaseAddress, u32 RegOffset)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+#define XLlTemac_ReadReg(BaseAddress, RegOffset) \
+({ \
+ u32 value; \
+ if ((RegOffset) > 0x2c) { \
+ printf ("readreg: Woah! wrong reg addr: 0x%0x\n", (RegOffset)); \
+ } \
+ value = XIo_In32(((BaseAddress) + (RegOffset))); \
+ XLlTemac_print_reg_i((BaseAddress), (RegOffset), value); \
+ value; \
+})
+#else
+#define XLlTemac_ReadReg(BaseAddress, RegOffset) \
+ (XIo_In32(((BaseAddress) + (RegOffset))))
+#endif
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_WriteReg, writes <i>Data</i> to the register specified by
+ * <i>RegOffset</i>.
+ *
+ * @param BaseAddress is the base address of the TEMAC channel.
+ * @param RegOffset is the offset of the register to be written.
+ * @param Data is the 32-bit value to write to the register.
+ *
+ * @return N/A
+ *
+ * @note
+ * C-style signature:
+ * void XLlTemac_mWriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+#define XLlTemac_WriteReg(BaseAddress, RegOffset, Data) \
+({ \
+ if ((RegOffset) > 0x2c) { \
+ printf ("writereg: Woah! wrong reg addr: 0x%0x\n", (RegOffset)); \
+ } \
+ XLlTemac_print_reg_o((BaseAddress), (RegOffset), (Data)); \
+ XIo_Out32(((BaseAddress) + (RegOffset)), (Data)); \
+})
+#else
+#define XLlTemac_WriteReg(BaseAddress, RegOffset, Data) \
+ XIo_Out32(((BaseAddress) + (RegOffset)), (Data))
+#endif
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_ReadIndirectReg returns the value read from the hard TEMAC register
+ * specified by <i>RegOffset</i>.
+ *
+ * @param BaseAddress is the base address of the TEMAC channel.
+ * @param RegOffset is the offset of the hard TEMAC register to be read.
+ *
+ * @return XLlTemac_ReadIndirectReg returns the 32-bit value of the register.
+ *
+ * @note
+ * C-style signature:
+ * u32 XLlTemac_mReadIndirectReg(u32 BaseAddress, u32 RegOffset)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+extern u32 _xlltemac_rir_value;
+
+#define XLlTemac_ReadIndirectReg(BaseAddress, RegOffset) \
+( \
+ indent_on = 1, \
+ (((RegOffset) < 0x200) ? \
+ xdbg_printf(XDBG_DEBUG_ERROR, \
+ "readindirect: Woah! wrong reg addr: 0x%0x\n", \
+ (RegOffset)) : 0), \
+ (((RegOffset) > 0x3b4) ? \
+ xdbg_printf(XDBG_DEBUG_ERROR, \
+ "readindirect: Woah! wrong reg addr: 0x%0x\n", \
+ (RegOffset)) : 0), \
+ XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, (RegOffset)), \
+ _xlltemac_rir_value = XLlTemac_ReadReg((BaseAddress), XTE_LSW_OFFSET), \
+ XLlTemac_print_reg_i((BaseAddress), (RegOffset), _xlltemac_rir_value), \
+ indent_on = 0, \
+ _xlltemac_rir_value \
+)
+#else
+#define XLlTemac_ReadIndirectReg(BaseAddress, RegOffset) \
+( \
+ XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, (RegOffset)), \
+ XLlTemac_ReadReg((BaseAddress), XTE_LSW_OFFSET) \
+)
+#endif
+
+/****************************************************************************/
+/**
+ *
+ * XLlTemac_WriteIndirectReg, writes <i>Data</i> to the hard TEMAC register
+ * specified by <i>RegOffset</i>.
+ *
+ * @param BaseAddress is the base address of the TEMAC channel.
+ * @param RegOffset is the offset of the hard TEMAC register to be written.
+ * @param Data is the 32-bit value to write to the register.
+ *
+ * @return N/A
+ *
+ * @note
+ * C-style signature:
+ * void XLlTemac_WriteIndirectReg(u32 BaseAddress, u32 RegOffset, u32 Data)
+ *
+ *****************************************************************************/
+#ifdef DEBUG
+#define XLlTemac_WriteIndirectReg(BaseAddress, RegOffset, Data) \
+( \
+ indent_on = 1, \
+ (((RegOffset) < 0x200) ? \
+ xdbg_printf(XDBG_DEBUG_ERROR, \
+ "readindirect: Woah! wrong reg addr: 0x%0x\n", \
+ (RegOffset)) : 0), \
+ (((RegOffset) > 0x3b4) ? \
+ xdbg_printf(XDBG_DEBUG_ERROR, \
+ "readindirect: Woah! wrong reg addr: 0x%0x\n", \
+ (RegOffset)) : 0), \
+ XLlTemac_print_reg_o((BaseAddress), (RegOffset), (Data)), \
+ XLlTemac_WriteReg((BaseAddress), XTE_LSW_OFFSET, (Data)), \
+ XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, \
+ ((RegOffset) | XTE_CTL_WEN_MASK)), \
+ ((XLlTemac_ReadReg((BaseAddress), XTE_RDY_OFFSET) & \
+ XTE_RDY_HARD_ACS_RDY_MASK) ? \
+ ((XLlTemac_ReadIndirectReg((BaseAddress), (RegOffset)) != (Data)) ? \
+ xdbg_printf(XDBG_DEBUG_ERROR, \
+ "data written is not read back: Reg: 0x%0x\n", \
+ (RegOffset)) \
+ : 0) \
+ : xdbg_printf(XDBG_DEBUG_ERROR, "(temac_wi) RDY reg not initially ready\n")), \
+ indent_on = 0 \
+)
+#else
+#define XLlTemac_WriteIndirectReg(BaseAddress, RegOffset, Data) \
+ XLlTemac_WriteReg((BaseAddress), XTE_LSW_OFFSET, (Data)), \
+ XLlTemac_WriteReg((BaseAddress), XTE_CTL_OFFSET, \
+ ((RegOffset) | XTE_CTL_WEN_MASK))
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* end of protection macro */
Index: trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_main.c
===================================================================
--- /dev/null
+++ trunk/software/linux-2.6.x-petalogix/drivers/net/xilinx_lltemac/xlltemac_main.c
@@ -0,0 +1,3411 @@
+/*
+ * Xilinx Ethernet: Linux driver for the XPS_LLTEMAC core.
+ *
+ * Author: Xilinx, Inc.
+ *
+ * 2006-2007 (c) Xilinx, Inc. This file is licensed uner the terms of the GNU
+ * General Public License version 2.1. This program is licensed "as is" without
+ * any warranty of any kind, whether express or implied.
+ *
+ * <pre>
+ * MODIFICATION HISTORY:
+ *
+ * Ver Who Date Changes
+ * ----- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------------------------------------------------------
+ * 1.00a jvb 05/08/05 First release
+ * </pre>
+ *
+ */
+
+/*
+ * With the way the hardened Temac works, the driver needs to communicate
+ * with the PHY controller. Since each board will have a different
+ * type of PHY, the code that communicates with the MII type controller
+ * is inside #ifdef XILINX_PLB_TEMAC_3_00A_ML403_PHY_SUPPORT conditional
+ * compilation. For your specific board, you will want to replace this code with
+ * code of your own for your specific board.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/xilinx_devices.h>
+#include <asm/io.h>
+#include <linux/ethtool.h>
+#include <linux/vmalloc.h>
+
+#ifdef CONFIG_OF
+// For open firmware.
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#endif
+
+#include "xbasic_types.h"
+#include "xlltemac.h"
+#include "xllfifo.h"
+#include "xlldma.h"
+#include "xlldma_bdring.h"
+
+#define LOCAL_FEATURE_RX_CSUM 0x01
+
+/*
+ * Default SEND and RECV buffer descriptors (BD) numbers.
+ * BD Space needed is (XTE_SEND_BD_CNT+XTE_RECV_BD_CNT)*Sizeof(XLlDma_Bd).
+ * Each XLlDma_Bd instance currently takes 40 bytes.
+ */
+#define XTE_SEND_BD_CNT 256
+#define XTE_RECV_BD_CNT 256
+
+/* Must be shorter than length of ethtool_drvinfo.driver field to fit */
+#define DRIVER_NAME "xilinx_lltemac"
+#define DRIVER_DESCRIPTION "Xilinx Tri-Mode Ethernet MAC driver"
+#define DRIVER_VERSION "1.00a"
+
+#define TX_TIMEOUT (3*HZ) /* Transmission timeout is 3 seconds. */
+
+/*
+ * This version of the Xilinx TEMAC uses external DMA or FIFO cores.
+ * Currently neither the DMA or FIFO cores used require any memory alignment
+ * restrictions.
+ */
+/*
+ * ALIGNMENT_RECV = the alignement required to receive
+ * ALIGNMENT_SEND = the alignement required to send
+ * ALIGNMENT_SEND_PERF = tx alignment for better performance
+ *
+ * ALIGNMENT_SEND is used to see if we *need* to copy the data to re-align.
+ * ALIGNMENT_SEND_PERF is used if we've decided we need to copy anyway, we just
+ * copy to this alignment for better performance.
+ */
+
+#define ALIGNMENT_RECV 32
+#define ALIGNMENT_SEND 8
+#define ALIGNMENT_SEND_PERF 32
+
+#define XTE_SEND 1
+#define XTE_RECV 2
+
+/* SGDMA buffer descriptors must be aligned on a 8-byte boundary. */
+#define ALIGNMENT_BD XLLDMA_BD_MINIMUM_ALIGNMENT
+
+/* BUFFER_ALIGN(adr) calculates the number of bytes to the next alignment. */
+#define BUFFER_ALIGNSEND(adr) ((ALIGNMENT_SEND - ((u32) adr)) % ALIGNMENT_SEND)
+#define BUFFER_ALIGNSEND_PERF(adr) ((ALIGNMENT_SEND_PERF - ((u32) adr)) % ALIGNMENT_SEND_PERF)
+#define BUFFER_ALIGNRECV(adr) ((ALIGNMENT_RECV - ((u32) adr)) % ALIGNMENT_RECV)
+
+/* Default TX/RX Threshold and waitbound values for SGDMA mode */
+#define DFT_TX_THRESHOLD 24
+#define DFT_TX_WAITBOUND 254
+#define DFT_RX_THRESHOLD 4
+#define DFT_RX_WAITBOUND 254
+
+#define XTE_AUTOSTRIPPING 1
+
+/* Put Buffer Descriptors in BRAM?
+ * NOTE:
+ * Putting BDs in BRAM only works if there is only ONE instance of the TEMAC
+ * in hardware. The code does not handle multiple instances, e.g. it does
+ * not manage the memory in BRAM.
+ */
+#define BD_IN_BRAM 0
+#define BRAM_BASEADDR 0xffff8000
+
+
+/*
+ * Checksum offload macros
+ */
+#define BdCsumEnable(BdPtr) \
+ XLlDma_mBdWrite((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET, \
+ (XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)) | 1 )
+
+/* Used for debugging */
+#define BdCsumEnabled(BdPtr) \
+ ((XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)) & 1)
+
+#define BdCsumDisable(BdPtr) \
+ XLlDma_mBdWrite((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET, \
+ (XLlDma_mBdRead((BdPtr), XLLDMA_BD_STSCTRL_USR0_OFFSET)) & 0xFFFFFFFE )
+
+#define BdCsumSetup(BdPtr, Start, Insert) \
+ XLlDma_mBdWrite((BdPtr), XLLDMA_BD_USR1_OFFSET, (Start) << 16 | (Insert))
+
+/* Used for debugging */
+#define BdCsumInsert(BdPtr) \
+ (XLlDma_mBdRead((BdPtr), XLLDMA_BD_USR1_OFFSET) & 0xffff)
+
+#define BdCsumSeed(BdPtr, Seed) \
+ XLlDma_mBdWrite((BdPtr), XLLDMA_BD_USR2_OFFSET, 0)
+
+#define BdCsumGet(BdPtr) \
+ XLlDma_mBdRead((BdPtr), XLLDMA_BD_USR3_OFFSET)
+
+#define BdGetRxLen(BdPtr) \
+ XLlDma_mBdRead((BdPtr), XLLDMA_BD_USR4_OFFSET)
+
+/*
+ * Our private per device data. When a net_device is allocated we will
+ * ask for enough extra space for this.
+ */
+struct net_local {
+ struct list_head rcv;
+ struct list_head xmit;
+
+ struct net_device *ndev; /* this device */
+ struct net_device *next_dev; /* The next device in dev_list */
+ struct net_device_stats stats; /* Statistics for this device */
+ struct timer_list phy_timer; /* PHY monitoring timer */
+
+ u32 index; /* Which interface is this */
+#if 0
+ XInterruptHandler Isr; /* Pointer to the XLlTemac ISR routine */
+#endif
+ u8 gmii_addr; /* The GMII address of the PHY */
+
+ /* The underlying OS independent code needs space as well. A
+ * pointer to the following XLlTemac structure will be passed to
+ * any XLlTemac_ function that requires it. However, we treat the
+ * data as an opaque object in this file (meaning that we never
+ * reference any of the fields inside of the structure). */
+ XLlFifo Fifo;
+ XLlDma Dma;
+ XLlTemac Emac;
+
+ unsigned int fifo_irq; /* fifo irq */
+ unsigned int dma_irq_s; /* send irq */
+ unsigned int dma_irq_r; /* recv irq */
+ unsigned int max_frame_size;
+
+ int cur_speed;
+
+ /* Buffer Descriptor space for both TX and RX BD ring */
+ void *desc_space; /* virtual address of BD space */
+ dma_addr_t desc_space_handle; /* physical address of BD space */
+ int desc_space_size; /* size of BD space */
+
+ /* buffer for one skb in case no room is available for transmission */
+ struct sk_buff *deferred_skb;
+
+ /* send buffers for non tx-dre hw */
+ void **tx_orig_buffers; /* Buffer addresses as returned by
+ dma_alloc_coherent() */
+ void **tx_buffers; /* Buffers addresses aligned for DMA */
+ dma_addr_t *tx_phys_buffers; /* Buffer addresses in physical memory */
+ size_t tx_buffers_cur; /* Index of current buffer used */
+
+ /* stats */
+ int max_frags_in_a_packet;
+ unsigned long realignments;
+ unsigned long tx_hw_csums;
+ unsigned long rx_hw_csums;
+ unsigned long local_features;
+#if ! XTE_AUTOSTRIPPING
+ unsigned long stripping;
+#endif
+};
+
+u32 dma_rx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK;
+u32 dma_tx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK;
+
+/* for exclusion of all program flows (processes, ISRs and BHs) */
+spinlock_t XTE_spinlock = SPIN_LOCK_UNLOCKED;
+spinlock_t XTE_tx_spinlock = SPIN_LOCK_UNLOCKED;
+spinlock_t XTE_rx_spinlock = SPIN_LOCK_UNLOCKED;
+
+/*
+ * ethtool has a status reporting feature where we can report any sort of
+ * status information we'd like. This is the list of strings used for that
+ * status reporting. ETH_GSTRING_LEN is defined in ethtool.h
+ */
+static char xenet_ethtool_gstrings_stats[][ETH_GSTRING_LEN] = {
+ "txpkts", "txdropped", "txerr", "txfifoerr",
+ "rxpkts", "rxdropped", "rxerr", "rxfifoerr",
+ "rxrejerr", "max_frags", "tx_hw_csums", "rx_hw_csums",
+};
+
+#define XENET_STATS_LEN sizeof(xenet_ethtool_gstrings_stats) / ETH_GSTRING_LEN
+
+/* Helper function to determine if a given XLlTemac error warrants a reset. */
+extern inline int status_requires_reset(int s)
+{
+ return (s == XST_FIFO_ERROR ||
+ s == XST_PFIFO_DEADLOCK ||
+ s == XST_DMA_ERROR || s == XST_IPIF_ERROR);
+}
+
+/* Queues with locks */
+static LIST_HEAD(receivedQueue);
+static spinlock_t receivedQueueSpin = SPIN_LOCK_UNLOCKED;
+
+static LIST_HEAD(sentQueue);
+static spinlock_t sentQueueSpin = SPIN_LOCK_UNLOCKED;
+
+
+/* from mii.h
+ *
+ * Items in mii.h but not in gmii.h
+ */
+#define ADVERTISE_100FULL 0x0100
+#define ADVERTISE_100HALF 0x0080
+#define ADVERTISE_10FULL 0x0040
+#define ADVERTISE_10HALF 0x0020
+#define ADVERTISE_CSMA 0x0001
+
+#define EX_ADVERTISE_1000FULL 0x0200
+#define EX_ADVERTISE_1000HALF 0x0100
+
+/*
+ * items not in mii.h nor gmii.h but should be
+ */
+#define MII_EXADVERTISE 0x09
+
+/*
+ * Wrap certain temac routines with a lock, so access to the shared hard temac
+ * interface is accessed mutually exclusive for dual channel temac support.
+ */
+
+static inline void _XLlTemac_Start(XLlTemac *InstancePtr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_Start(InstancePtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_Stop(XLlTemac *InstancePtr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_Stop(InstancePtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_Reset(XLlTemac *InstancePtr, int HardCoreAction)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_Reset(InstancePtr, HardCoreAction);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline int _XLlTemac_SetMacAddress(XLlTemac *InstancePtr,
+ void *AddressPtr)
+{
+ int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ status = XLlTemac_SetMacAddress(InstancePtr, AddressPtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return status;
+}
+
+static inline void _XLlTemac_GetMacAddress(XLlTemac *InstancePtr,
+ void *AddressPtr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_GetMacAddress(InstancePtr, AddressPtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline int _XLlTemac_SetOptions(XLlTemac *InstancePtr, u32 Options)
+{
+ int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ status = XLlTemac_SetOptions(InstancePtr, Options);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return status;
+}
+
+static inline int _XLlTemac_ClearOptions(XLlTemac *InstancePtr, u32 Options)
+{
+ int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ status = XLlTemac_ClearOptions(InstancePtr, Options);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return status;
+}
+
+static inline u16 _XLlTemac_GetOperatingSpeed(XLlTemac *InstancePtr)
+{
+ u16 speed;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ speed = XLlTemac_GetOperatingSpeed(InstancePtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return speed;
+}
+
+static inline void _XLlTemac_SetOperatingSpeed(XLlTemac *InstancePtr, u16 Speed)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_SetOperatingSpeed(InstancePtr, Speed);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ /* We need a delay after we set the speed. Otherwise the PHY will not be ready. */
+ udelay(10000);
+}
+
+static inline void _XLlTemac_PhySetMdioDivisor(XLlTemac *InstancePtr, u8 Divisor)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_PhySetMdioDivisor(InstancePtr, Divisor);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_PhyRead(XLlTemac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 *PhyDataPtr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_PhyRead(InstancePtr, PhyAddress, RegisterNum, PhyDataPtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline void _XLlTemac_PhyWrite(XLlTemac *InstancePtr, u32 PhyAddress,
+ u32 RegisterNum, u16 PhyData)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_PhyWrite(InstancePtr, PhyAddress, RegisterNum, PhyData);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+
+static inline int _XLlTemac_MulticastClear(XLlTemac *InstancePtr, int Entry)
+{
+ int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ status = XLlTemac_MulticastClear(InstancePtr, Entry);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return status;
+}
+
+static inline int _XLlTemac_SetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+ int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ status = XLlTemac_SetMacPauseAddress(InstancePtr, AddressPtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return status;
+}
+
+static inline void _XLlTemac_GetMacPauseAddress(XLlTemac *InstancePtr, void *AddressPtr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ XLlTemac_GetMacPauseAddress(InstancePtr, AddressPtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+}
+
+static inline int _XLlTemac_GetSgmiiStatus(XLlTemac *InstancePtr, u16 *SpeedPtr)
+{
+ int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ status = XLlTemac_GetSgmiiStatus(InstancePtr, SpeedPtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return status;
+}
+
+static inline int _XLlTemac_GetRgmiiStatus(XLlTemac *InstancePtr,
+ u16 *SpeedPtr,
+ int *IsFullDuplexPtr,
+ int *IsLinkUpPtr)
+{
+ int status;
+ unsigned long flags;
+
+ spin_lock_irqsave(&XTE_spinlock, flags);
+ status = XLlTemac_GetRgmiiStatus(InstancePtr, SpeedPtr, IsFullDuplexPtr, IsLinkUpPtr);
+ spin_unlock_irqrestore(&XTE_spinlock, flags);
+
+ return status;
+}
+
+
+
+// #define PHY_MARVELL_88E1111_RGMII
+
+#ifdef PHY_MARVELL_88E1111_RGMII
+#define MARVELL_88E1111_EXTENDED_PHY_CTL_REG_OFFSET 20
+#define MARVELL_88E1111_EXTENDED_PHY_STATUS_REG_OFFSET 27
+#endif
+
+#define DEBUG_ERROR KERN_ERR
+#define DEBUG_LOG(level, ...) printk(level __VA_ARGS__)
+
+/*
+ * Perform any necessary special phy setup. In the gmii case, nothing needs to
+ * be done.
+ */
+static void phy_setup(struct net_local *lp)
+{
+ u16 Register;
+
+#ifdef PHY_VITESSE_8211_SGMII
+ /* Setup the MAC into SGMII mode */
+ Register = 0xAA23;
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, 31, 0x0000);
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, 23, Register);
+
+ /* Set SIGDET as an input */
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, 31, 0x0001);
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, 19, 0x0002);
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, 31, 0x0000);
+
+ /* Signal all possible autonegotiation modes */
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_ADVERTISE,
+ ADVERTISE_ALL);
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_EXADVERTISE,
+ ADVERTISE_1000FULL| ADVERTISE_1000HALF);
+
+ /*
+ * Reset the PHY
+ */
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMCR, &Register);
+ Register |= BMCR_RESET;
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_BMCR, Register);
+#endif
+
+#ifdef PHY_MARVELL_88E1111_RGMII
+ u16 Register;
+
+ /*
+ * Set up MAC interface
+ *
+ * Write 0x0cc3 to reg 20 in PHY
+ * 5432 1098 7654 3210
+ * ---- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/----
+ * 0cc3=0000 1100 1100 0011
+ * downshift counter (bits 11-9): 110 = 7 times
+ * downshift enable (bit 8): 0 = enable
+ * RGMII timing control (bit 7): 1 = add delay to rx clk ro rxd
+ * outputs
+ * Default Mac interface speed (bits 6-4): 100 = 10mbps 2.5 mhz
+ * (between phy and temac - gets renegotiated)
+ * reserved (bit 3)
+ * DTE detect (bit 2): 0 disabled
+ * RGMII transmit timing control (bit 1): 1 = add delay
+ * to tx clk ro txd outputs
+ * Transmitter Disable (bit 0): 1 = enabled
+ */
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MARVELL_88E1111_EXTENDED_PHY_CTL_REG_OFFSET, 0x0cc3);
+
+ /*
+ * Set RGMII to copper with correct hysterisis and correct mode
+ * Disable fiber/copper auto sel, choose copper
+ * RGMII /Modified MII to copper mode
+ *
+ * Write 0x848b to reg 27
+ * 5432 1098 7654 3210
+ * ---- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/---- software/linux-2.6.x-petalogix/----
+ * 848b=1000 0100 1000 1011
+ * Fiber/Copper Auto Selection (bit 15): 1 = disable auto selection
+ * Interrupt Polarity (bit 10): 1 = int active low
+ * DTE detect status drop hysteresis (bts 8-5): 0100 = report 20s after DTE power status drop
+ * HWCFG mode (bits 3-0): 1011 = RGMII/Modified MII to Copper
+ */
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MARVELL_88E1111_EXTENDED_PHY_STATUS_REG_OFFSET, 0x848b);
+
+ /*
+ * Reset the PHY
+ */
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMCR, &Register);
+ Register |= BMCR_RESET;
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_BMCR, Register);
+
+#endif /* PHY_MARVELL_88E1111_RGMII */
+}
+
+
+typedef enum DUPLEX { UNKNOWN_DUPLEX, HALF_DUPLEX, FULL_DUPLEX } DUPLEX;
+
+int renegotiate_speed(struct net_device *dev, int speed, DUPLEX duplex)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ int retries = 2;
+ int wait_count;
+ u16 phy_reg0 = BMCR_ANENABLE | BMCR_ANRESTART;
+ u16 phy_reg1;
+ u16 phy_reg4;
+ u16 phy_reg9 = 0;
+
+
+ /*
+ * It appears that the 10baset full and half duplex settings
+ * are overloaded for gigabit ethernet
+ */
+ if ((duplex == FULL_DUPLEX) && (speed == 10)) {
+ phy_reg4 = ADVERTISE_10FULL | ADVERTISE_CSMA;
+ }
+ else if ((duplex == FULL_DUPLEX) && (speed == 100)) {
+ phy_reg4 = ADVERTISE_100FULL | ADVERTISE_CSMA;
+ }
+ else if ((duplex == FULL_DUPLEX) && (speed == 1000)) {
+ phy_reg4 = ADVERTISE_CSMA;
+ phy_reg9 = EX_ADVERTISE_1000FULL;
+ }
+ else if (speed == 10) {
+ phy_reg4 = ADVERTISE_10HALF | ADVERTISE_CSMA;
+ }
+ else if (speed == 100) {
+ phy_reg4 = ADVERTISE_100HALF | ADVERTISE_CSMA;
+ }
+ else if (speed == 1000) {
+ phy_reg4 = ADVERTISE_CSMA;
+ phy_reg9 = EX_ADVERTISE_1000HALF;
+ }
+ else {
+ printk(KERN_ERR
+ "%s: XLlTemac: unsupported speed requested: %d\n",
+ dev->name, speed);
+ return -1;
+ }
+
+ /*
+ * link status in register 1:
+ * first read / second read:
+ * 0 0 link is down
+ * 0 1 link is up (but it was down earlier)
+ * 1 0 link is down (but it was just up)
+ * 1 1 link is up
+ *
+ */
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &phy_reg1);
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &phy_reg1);
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_ADVERTISE, phy_reg4);
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_EXADVERTISE, phy_reg9);
+
+ while (retries--) {
+ /* initiate an autonegotiation of the speed */
+ _XLlTemac_PhyWrite(&lp->Emac, lp->gmii_addr, MII_BMCR, phy_reg0);
+
+ wait_count = 1000; /* so we don't loop forever */
+ while (wait_count--) {
+ /* wait a bit for the negotiation to complete */
+ mdelay(100);
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR,
+ &phy_reg1);
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR,
+ &phy_reg1);
+
+ if ((phy_reg1 & BMSR_LSTATUS) &&
+ (phy_reg1 & BMSR_ANEGCOMPLETE))
+ break;
+
+ }
+
+ if (phy_reg1 & BMSR_LSTATUS) {
+ printk(KERN_INFO
+ "%s: XLlTemac: We renegotiated the speed to: %d\n",
+ dev->name, speed);
+ return 0;
+ }
+ else {
+ printk(KERN_ERR
+ "%s: XLlTemac: Not able to set the speed to %d (status: 0x%0x)\n",
+ dev->name, speed, phy_reg1);
+ return -1;
+ }
+ }
+
+ printk(KERN_ERR
+ "%s: XLlTemac: Not able to set the speed to %d\n", dev->name,
+ speed);
+ return -1;
+}
+
+// #define XILINX_PLB_TEMAC_3_00A_ML403_PHY_SUPPORT
+/*
+ * This function sets up MAC's speed according to link speed of PHY
+ * This function is specific to MARVELL 88E1111 PHY chip on Xilinx ML403
+ * board and assumes GMII interface is being used by the TEMAC
+ */
+void set_mac_speed(struct net_local *lp)
+{
+ u16 phylinkspeed;
+ struct net_device *dev = lp->ndev;
+ int ret;
+
+#ifndef XILINX_PLB_TEMAC_3_00A_ML403_PHY_SUPPORT
+ int retry_count = 1;
+#endif
+
+ /*
+ * See comments at top for an explanation of
+ * XILINX_PLB_TEMAC_3_00A_ML403_PHY_SUPPORT
+ */
+#ifdef XILINX_PLB_TEMAC_3_00A_ML403_PHY_SUPPORT
+#define MARVELL_88E1111_PHY_SPECIFIC_STATUS_REG_OFFSET 17
+#define MARVELL_88E1111_LINKSPEED_MARK 0xC000
+#define MARVELL_88E1111_LINKSPEED_SHIFT 14
+#define MARVELL_88E1111_LINKSPEED_1000M 0x0002
+#define MARVELL_88E1111_LINKSPEED_100M 0x0001
+#define MARVELL_88E1111_LINKSPEED_10M 0x0000
+ u16 RegValue;
+
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr,
+ MARVELL_88E1111_PHY_SPECIFIC_STATUS_REG_OFFSET,
+ &RegValue);
+ /* Get current link speed */
+ phylinkspeed = (RegValue & MARVELL_88E1111_LINKSPEED_MARK)
+ >> MARVELL_88E1111_LINKSPEED_SHIFT;
+
+ /* Update TEMAC speed accordingly */
+ switch (phylinkspeed) {
+ case (MARVELL_88E1111_LINKSPEED_1000M):
+ _XLlTemac_SetOperatingSpeed(&lp->Emac, 1000);
+ printk(KERN_INFO "%s: XLlTemac: speed set to 1000Mb/s\n",
+ dev->name);
+ lp->cur_speed = 1000;
+ break;
+ case (MARVELL_88E1111_LINKSPEED_100M):
+ _XLlTemac_SetOperatingSpeed(&lp->Emac, 100);
+ printk(KERN_INFO "%s: XLlTemac: speed set to 100Mb/s\n",
+ dev->name);
+ lp->cur_speed = 100;
+ break;
+ case (MARVELL_88E1111_LINKSPEED_10M):
+ _XLlTemac_SetOperatingSpeed(&lp->Emac, 10);
+ printk(KERN_INFO "%s: XLlTemac: speed set to 10Mb/s\n",
+ dev->name);
+ lp->cur_speed = 10;
+ break;
+ default:
+ _XLlTemac_SetOperatingSpeed(&lp->Emac, 1000);
+ printk(KERN_INFO "%s: XLlTemac: speed defaults to 1000Mb/s\n",
+ dev->name);
+ lp->cur_speed = 1000;
+ break;
+ }
+
+#else
+ if (XLlTemac_GetPhysicalInterface(&lp->Emac) == XTE_PHY_TYPE_MII) {
+ phylinkspeed = 100;
+ }
+ else {
+ phylinkspeed = 1000;
+ }
+
+ /*
+ * Try to renegotiate the speed until something sticks
+ */
+ while (phylinkspeed > 1) {
+ ret = renegotiate_speed(dev, phylinkspeed, FULL_DUPLEX);
+ /*
+ * ret == 1 - try it again
+ * ret == 0 - it worked
+ * ret < 0 - there was some failure negotiating the speed
+ */
+ if (ret == 0) {
+ /* it worked, get out of the loop */
+ break;
+ }
+
+ /* it didn't work this time, but it may work if we try again */
+ if ((ret == 1) && (retry_count)) {
+ retry_count--;
+ printk("trying again...\n");
+ continue;
+ }
+ /* reset the retry_count, becuase we're about to try a lower speed */
+ retry_count = 1;
+ phylinkspeed /= 10;
+ }
+ if (phylinkspeed == 1) {
+ printk(KERN_INFO "%s: XLlTemac: could not negotiate speed\n",
+ dev->name);
+ lp->cur_speed = 0;
+
+ return;
+ }
+
+ _XLlTemac_SetOperatingSpeed(&lp->Emac, phylinkspeed);
+ printk(KERN_INFO "%s: XLlTemac: speed set to %dMb/s\n", dev->name,
+ phylinkspeed);
+ lp->cur_speed = phylinkspeed;
+#endif
+}
+
+/*
+ * Helper function to reset the underlying hardware. This is called
+ * when we get into such deep trouble that we don't know how to handle
+ * otherwise.
+ */
+static void reset(struct net_device *dev, u32 line_num)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ u32 TxThreshold, TxWaitBound, RxThreshold, RxWaitBound;
+ u32 Options;
+ static u32 reset_cnt = 0;
+ int status;
+
+ printk(KERN_INFO "%s: XLlTemac: resets (#%u) from adapter code line %d\n",
+ dev->name, ++reset_cnt, line_num);
+
+ /* Shouldn't really be necessary, but shouldn't hurt. */
+ netif_stop_queue(dev);
+
+ /* Stop device */
+ _XLlTemac_Stop(&lp->Emac);
+
+ /*
+ * XLlTemac_Reset puts the device back to the default state. We need
+ * to save all the settings we don't already know, reset, restore
+ * the settings, and then restart the TEMAC.
+ */
+ Options = XLlTemac_GetOptions(&lp->Emac);
+
+ /*
+ * Capture the dma coalesce settings (if needed) and reset the
+ * connected core, dma or fifo
+ */
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ XLlDma_BdRingGetCoalesce(&XLlDma_mGetRxRing(&lp->Dma),
+ &RxThreshold, &RxWaitBound);
+ XLlDma_BdRingGetCoalesce(&XLlDma_mGetTxRing(&lp->Dma),
+ &TxThreshold, &TxWaitBound);
+
+ XLlDma_Reset(&lp->Dma);
+ } else {
+ XLlFifo_Reset(&lp->Fifo);
+ }
+
+ /* now we can reset the device */
+ _XLlTemac_Reset(&lp->Emac, XTE_NORESET_HARD);
+
+ /* Reset on TEMAC also resets PHY. Give it some time to finish negotiation
+ * before we move on */
+ mdelay(2000);
+
+ /*
+ * The following four functions will return an error if the
+ * EMAC is already started. We just stopped it by calling
+ * _XLlTemac_Reset() so we can safely ignore the return values.
+ */
+ (int) _XLlTemac_SetMacAddress(&lp->Emac, dev->dev_addr);
+ (int) _XLlTemac_SetOptions(&lp->Emac, Options);
+ (int) _XLlTemac_ClearOptions(&lp->Emac, ~Options);
+ Options = XLlTemac_GetOptions(&lp->Emac);
+ printk(KERN_INFO "%s: XLlTemac: Options: 0x%x\n", dev->name, Options);
+
+ phy_setup(lp);
+ set_mac_speed(lp);
+
+ if (XLlTemac_IsDma(&lp->Emac)) { /* SG DMA mode */
+ status = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing,
+ RxThreshold, RxWaitBound);
+ status |= XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing,
+ TxThreshold, TxWaitBound);
+ if (status != XST_SUCCESS) {
+ /* Print the error, but keep on going as it's not a fatal error. */
+ printk(KERN_ERR "%s: XLlTemac: error setting coalesce values (probably out of range). status: %d\n",
+ dev->name, status);
+ }
+ XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+ XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+ } else { /* FIFO interrupt mode */
+ XLlFifo_IntEnable(&lp->Fifo, XLLF_INT_TC_MASK |
+ XLLF_INT_RC_MASK | XLLF_INT_RXERROR_MASK |
+ XLLF_INT_TXERROR_MASK);
+ }
+ XLlTemac_IntDisable(&lp->Emac, XTE_INT_ALL_MASK);
+
+ if (lp->deferred_skb) {
+ dev_kfree_skb_any(lp->deferred_skb);
+ lp->deferred_skb = NULL;
+ lp->stats.tx_errors++;
+ }
+
+ /*
+ * XLlTemac_Start returns an error when: if configured for
+ * scatter-gather DMA and a descriptor list has not yet been created
+ * for the send or receive channel, or if no receive buffer descriptors
+ * have been initialized. Those are not happening. so ignore the returned
+ * result checking.
+ */
+ _XLlTemac_Start(&lp->Emac);
+
+ /* We're all ready to go. Start the queue in case it was stopped. */
+ netif_wake_queue(dev);
+}
+
+/*
+ * The PHY registers read here should be standard registers in all PHY chips
+ */
+static int get_phy_status(struct net_device *dev, DUPLEX * duplex, int *linkup)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ u16 reg;
+
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMCR, ®);
+ *duplex = FULL_DUPLEX;
+
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, ®);
+ *linkup = (reg & BMSR_LSTATUS) != 0;
+
+ return 0;
+}
+
+/*
+ * This routine is used for two purposes. The first is to keep the
+ * EMAC's duplex setting in sync with the PHY's. The second is to keep
+ * the system apprised of the state of the link. Note that this driver
+ * does not configure the PHY. Either the PHY should be configured for
+ * auto-negotiation or it should be handled by something like mii-tool. */
+static void poll_gmii(unsigned long data)
+{
+ struct net_device *dev;
+ struct net_local *lp;
+ DUPLEX phy_duplex;
+ int phy_carrier;
+ int netif_carrier;
+
+ dev = (struct net_device *) data;
+ lp = (struct net_local *) dev->priv;
+
+ /* First, find out what's going on with the PHY. */
+ if (get_phy_status(dev, &phy_duplex, &phy_carrier)) {
+ printk(KERN_ERR "%s: XLlTemac: terminating link monitoring.\n",
+ dev->name);
+ return;
+ }
+ netif_carrier = netif_carrier_ok(dev) != 0;
+ if (phy_carrier != netif_carrier) {
+ if (phy_carrier) {
+ printk(KERN_INFO
+ "%s: XLlTemac: PHY Link carrier restored.\n",
+ dev->name);
+ netif_carrier_on(dev);
+ }
+ else {
+ printk(KERN_INFO "%s: XLlTemac: PHY Link carrier lost.\n",
+ dev->name);
+ netif_carrier_off(dev);
+ }
+ }
+
+ /* Set up the timer so we'll get called again in 2 seconds. */
+ lp->phy_timer.expires = jiffies + 2 * HZ;
+ add_timer(&lp->phy_timer);
+}
+
+static irqreturn_t xenet_temac_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct net_local *lp = (struct net_local *) dev->priv;
+
+ /*
+ * All we care about here is the RxRject interrupts. Explanation below:
+ *
+ * Interrupt Usage Description
+ * --------- software/linux-2.6.x-petalogix/ -----------------
+ * TxCmplt: Fifo or DMA will have completion interrupts. We'll use
+ * those and not the TEMAC ones.
+ * RxFifoOvr: if the RX fifo is overflowing, the last thing we need
+ * is more interrupts to handle.
+ * RxRJect: We're keeping stats on rejected packets (we could
+ * choose not to).
+ * RxCmplt: Fifo or DMA will have completion interrupts. We'll use
+ * those and not the TEMAC ones.
+ * AutoNeg: This driver doesn't make use of the autonegotation
+ * completion interrupt.
+ * HardAcsCmplt: This driver just polls the RDY register for this
+ * information instead of using an interrupt handler.
+ * CfgWst, CfgRst,
+ * AfWst, AfRst,
+ * MiimWst, MiimRst,
+ * FabrRst: All of these registers indicate when access (read or
+ * write) to one or other of the Hard Temac Core
+ * registers is complete. Instead of relying on an
+ * interrupt context switch to be notified that the
+ * access is complete, this driver instead polls for the
+ * status, which, in most cases, should be faster.
+ */
+ XLlTemac_IntClear(&lp->Emac, XTE_INT_ALL_MASK);
+
+ lp->stats.rx_errors++;
+ lp->stats.rx_crc_errors++;
+
+
+ return IRQ_HANDLED;
+}
+
+static void FifoSendHandler(struct net_device *dev);
+static void FifoRecvHandler(unsigned long p /*struct net_device *dev*/);
+
+DECLARE_TASKLET(FifoRecvBH, FifoRecvHandler, 0);
+
+static irqreturn_t xenet_fifo_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct net_local *lp = (struct net_local *) dev->priv;
+ u32 irq_status;
+
+ unsigned long flags;
+
+ /*
+ * Need to:
+ * 1) Read the FIFO IS register
+ * 2) clear all bits in the FIFO IS register
+ * 3) loop on each bit in the IS register, and handle each interrupt event
+ *
+ */
+ irq_status = XLlFifo_IntPending(&lp->Fifo);
+ XLlFifo_IntClear(&lp->Fifo, irq_status);
+ while (irq_status) {
+ if (irq_status & XLLF_INT_RC_MASK) {
+ /* handle the receive completion */
+ struct list_head *cur_lp;
+ spin_lock_irqsave(&receivedQueueSpin, flags);
+ list_for_each(cur_lp, &receivedQueue) {
+ if (cur_lp == &(lp->rcv)) {
+ break;
+ }
+ }
+ if (cur_lp != &(lp->rcv)) {
+ list_add_tail(&lp->rcv, &receivedQueue);
+ XLlFifo_IntDisable(&lp->Fifo, XLLF_INT_ALL_MASK);
+ tasklet_schedule(&FifoRecvBH);
+ }
+ spin_unlock_irqrestore(&receivedQueueSpin, flags);
+ irq_status &= ~XLLF_INT_RC_MASK;
+ } else if (irq_status & XLLF_INT_TC_MASK) {
+ /* handle the transmit completion */
+ FifoSendHandler(dev);
+ irq_status &= ~XLLF_INT_TC_MASK;
+ } else if (irq_status & XLLF_INT_TXERROR_MASK) {
+ lp->stats.tx_errors++;
+ lp->stats.tx_fifo_errors++;
+ XLlFifo_Reset(&lp->Fifo);
+ irq_status &= ~XLLF_INT_TXERROR_MASK;
+ } else if (irq_status & XLLF_INT_RXERROR_MASK) {
+ lp->stats.rx_errors++;
+ XLlFifo_Reset(&lp->Fifo);
+ irq_status &= ~XLLF_INT_RXERROR_MASK;
+ } else {
+ /* debug
+ * if (irq_status == 0) printk("Temac: spurious fifo int\n");
+ */
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* The callback function for completed frames sent in SGDMA mode. */
+static void DmaSendHandlerBH(unsigned long p);
+static void DmaRecvHandlerBH(unsigned long p);
+
+DECLARE_TASKLET(DmaSendBH, DmaSendHandlerBH, 0);
+DECLARE_TASKLET(DmaRecvBH, DmaRecvHandlerBH, 0);
+
+static irqreturn_t xenet_dma_rx_interrupt(int irq, void *dev_id)
+{
+ u32 irq_status;
+ struct net_device *dev = dev_id;
+ struct net_local *lp = (struct net_local *) dev->priv;
+ struct list_head *cur_lp;
+
+ unsigned int flags;
+
+ /* Read pending interrupts */
+ irq_status = XLlDma_mBdRingGetIrq(&lp->Dma.RxBdRing);
+
+ XLlDma_mBdRingAckIrq(&lp->Dma.RxBdRing, irq_status);
+
+ if ((irq_status & XLLDMA_IRQ_ALL_ERR_MASK)) {
+ XLlDma_Reset(&lp->Dma);
+ return IRQ_HANDLED;
+ }
+
+ if ((irq_status & (XLLDMA_IRQ_DELAY_MASK | XLLDMA_IRQ_COALESCE_MASK))) {
+ spin_lock_irqsave(&receivedQueueSpin, flags);
+ list_for_each(cur_lp, &receivedQueue) {
+ if (cur_lp == &(lp->rcv)) {
+ break;
+ }
+ }
+ if (cur_lp != &(lp->rcv)) {
+ list_add_tail(&lp->rcv, &receivedQueue);
+ XLlDma_mBdRingIntDisable(&lp->Dma.RxBdRing,
+ XLLDMA_CR_IRQ_ALL_EN_MASK);
+ tasklet_schedule(&DmaRecvBH);
+ }
+ spin_unlock_irqrestore(&receivedQueueSpin, flags);
+ }
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t xenet_dma_tx_interrupt(int irq, void *dev_id)
+{
+ u32 irq_status;
+ struct net_device *dev = dev_id;
+ struct net_local *lp = (struct net_local *) dev->priv;
+ struct list_head *cur_lp;
+
+ unsigned int flags;
+
+ /* Read pending interrupts */
+ irq_status = XLlDma_mBdRingGetIrq(&(lp->Dma.TxBdRing));
+
+ XLlDma_mBdRingAckIrq(&(lp->Dma.TxBdRing), irq_status);
+
+ if ((irq_status & XLLDMA_IRQ_ALL_ERR_MASK)) {
+ XLlDma_Reset(&lp->Dma);
+ return IRQ_HANDLED;
+ }
+
+ if ((irq_status & (XLLDMA_IRQ_DELAY_MASK | XLLDMA_IRQ_COALESCE_MASK))) {
+ spin_lock_irqsave(&sentQueueSpin, flags);
+ list_for_each(cur_lp, &sentQueue) {
+ if (cur_lp == &(lp->xmit)) {
+ break;
+ }
+ }
+ if (cur_lp != &(lp->xmit)) {
+ list_add_tail(&lp->xmit, &sentQueue);
+ XLlDma_mBdRingIntDisable(&lp->Dma.TxBdRing,
+ XLLDMA_CR_IRQ_ALL_EN_MASK);
+ tasklet_schedule(&DmaSendBH);
+ }
+ spin_unlock_irqrestore(&sentQueueSpin, flags);
+ }
+ return IRQ_HANDLED;
+}
+
+/*
+ * Q:
+ * Why doesn't this linux driver use an interrupt handler for the TEMAC itself?
+ *
+ * A:
+ * Let's take a look at all the possible events that could be signaled by the
+ * TEMAC core.
+ *
+ * possible events:
+ * Transmit Complete (TxCmplt) [not handled by this driver]
+ * The TEMAC TxCmplt interrupt status is ignored by software in favor of
+ * paying attention to the transmit complete status in the connected DMA
+ * or FIFO core.
+ * Receive Fifo Overflow (RxFifoOver) [not handled by this driver]
+ * We have discovered that the overhead of an interrupt context switch
+ * to attempt to handle this sort of event actually worsens the
+ * condition, and cuases further dropped packets further increasing the
+ * time spent in this interrupt handler.
+ * Receive Frame Rejected (RxRject) [not handled by this driver]
+ * We could possibly handle this interrupt and gather statistics
+ * information based on these events that occur. However it is not that
+ * critical.
+ * Receive Complete (RxCmplt) [not handled by this driver]
+ * The TEMAC RxCmplt interrupt status is ignored by software in favor of
+ * paying attention to the receive complete status in the connected DMA
+ * or FIFO core.
+ * Autonegotiaion Complete (AutoNeg) [not handled by this driver]
+ * Autonegotiation on the TEMAC is a bit complicated, and is handled in
+ * a way that does not require the use of this interrupt event.
+ * Hard Temac Core Access Complete (HardAcsCmplt) [not handled by this driver]
+ * This event really just indicates if there are any events in the TIS
+ * register. As can be seen below, none of the events from the TIS
+ * register are handled, so there is no need to handle this event
+ * either.
+ * Configuration Write Complete (CfgWst) [not handled by this driver]
+ * Configuration Read Complete (CfgRst) [not handled by this driver]
+ * Address Filter Write Complete (AfWst) [not handled by this driver]
+ * Address Filter Read Complete (AfRst) [not handled by this driver]
+ * MII Management Write Complete (MiimWst) [not handled by this driver]
+ * MII Management Read Complete (MiimRst) [not handled by this driver]
+ * Fabric Read Complete (FabrRst) [not handled by this driver]
+ * All of the above registers indicate when access (read or write) to
+ * one or other of the Hard Temac Core registers is complete. Instead of
+ * relying on an interrupt context switch to be notified that the access
+ * is complete, this driver instead polls for the status, which, in most
+ * cases, should be faster.
+ */
+
+static int xenet_open(struct net_device *dev)
+{
+ struct net_local *lp;
+ u32 Options;
+ int irqval = 0;
+
+ /*
+ * Just to be safe, stop TX queue and the device first. If the device is
+ * already stopped, an error will be returned. In this case, we don't
+ * really care.
+ */
+ netif_stop_queue(dev);
+ lp = (struct net_local *) dev->priv;
+ _XLlTemac_Stop(&lp->Emac);
+
+ INIT_LIST_HEAD(&(lp->rcv));
+ INIT_LIST_HEAD(&(lp->xmit));
+
+ /* Set the MAC address each time opened. */
+ if (_XLlTemac_SetMacAddress(&lp->Emac, dev->dev_addr) != XST_SUCCESS) {
+ printk(KERN_ERR "%s: XLlTemac: could not set MAC address.\n",
+ dev->name);
+ return -EIO;
+ }
+
+ /*
+ * If the device is not configured for polled mode, connect to the
+ * interrupt controller and enable interrupts. Currently, there
+ * isn't any code to set polled mode, so this check is probably
+ * superfluous.
+ */
+ Options = XLlTemac_GetOptions(&lp->Emac);
+ Options |= XTE_FLOW_CONTROL_OPTION;
+ Options |= XTE_JUMBO_OPTION;
+ Options |= XTE_TRANSMITTER_ENABLE_OPTION;
+ Options |= XTE_RECEIVER_ENABLE_OPTION;
+#if XTE_AUTOSTRIPPING
+ Options |= XTE_FCS_STRIP_OPTION;
+#endif
+
+ (int) _XLlTemac_SetOptions(&lp->Emac, Options);
+ (int) _XLlTemac_ClearOptions(&lp->Emac, ~Options);
+ Options = XLlTemac_GetOptions(&lp->Emac);
+ printk(KERN_INFO "%s: XLlTemac: Options: 0x%x\n", dev->name, Options);
+
+ /* Just use interrupt driven methods - no polled mode */
+
+ irqval = request_irq(dev->irq, &xenet_temac_interrupt, IRQF_DISABLED, dev->name, dev);
+ if (irqval) {
+ printk(KERN_ERR
+ "%s: XLlTemac: could not allocate interrupt %d.\n",
+ dev->name, dev->irq);
+ return irqval;
+ }
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ printk(KERN_INFO
+ "%s: XLlTemac: allocating interrupt %d for dma mode tx.\n",
+ dev->name, lp->dma_irq_s);
+ irqval = request_irq(lp->dma_irq_s,
+ &xenet_dma_tx_interrupt, 0, "xilinx_dma_tx_int", dev);
+ if (irqval) {
+ printk(KERN_ERR
+ "%s: XLlTemac: could not allocate interrupt %d.\n",
+ dev->name, lp->dma_irq_s);
+ return irqval;
+ }
+ printk(KERN_INFO
+ "%s: XLlTemac: allocating interrupt %d for dma mode rx.\n",
+ dev->name, lp->dma_irq_r);
+ irqval = request_irq(lp->dma_irq_r,
+ &xenet_dma_rx_interrupt, 0, "xilinx_dma_rx_int", dev);
+ if (irqval) {
+ printk(KERN_ERR
+ "%s: XLlTemac: could not allocate interrupt %d.\n",
+ dev->name, lp->dma_irq_r);
+ return irqval;
+ }
+ } else {
+ printk(KERN_INFO
+ "%s: XLlTemac: allocating interrupt %d for fifo mode.\n",
+ dev->name, lp->fifo_irq);
+ /* With the way interrupts are issued on the fifo core, this needs to be
+ * fast interrupt handler.
+ */
+ irqval = request_irq(lp->fifo_irq,
+ &xenet_fifo_interrupt, IRQF_DISABLED, "xilinx_fifo_int", dev);
+ if (irqval) {
+ printk(KERN_ERR
+ "%s: XLlTemac: could not allocate interrupt %d.\n",
+ dev->name, lp->fifo_irq);
+ return irqval;
+ }
+ }
+
+ /* give the system enough time to establish a link */
+ mdelay(2000);
+
+ phy_setup(lp);
+ set_mac_speed(lp);
+
+ /* Enable interrupts - no polled mode */
+ if (XLlTemac_IsFifo(&lp->Emac)) { /* fifo direct interrupt driver mode */
+ XLlFifo_IntEnable(&lp->Fifo, XLLF_INT_TC_MASK |
+ XLLF_INT_RC_MASK | XLLF_INT_RXERROR_MASK |
+ XLLF_INT_TXERROR_MASK);
+ } else { /* SG DMA mode */
+ XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+ XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+ }
+ /*
+ * Make sure all temac interrupts are disabled. These
+ * interrupts are not data flow releated.
+ */
+ XLlTemac_IntDisable(&lp->Emac, XTE_INT_ALL_MASK);
+
+ /* Start TEMAC device */
+ _XLlTemac_Start(&lp->Emac);
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ u32 threshold_s, timer_s, threshold_r, timer_r;
+
+ XLlDma_BdRingGetCoalesce(&lp->Dma.TxBdRing, &threshold_s, &timer_s);
+ XLlDma_BdRingGetCoalesce(&lp->Dma.RxBdRing, &threshold_r, &timer_r);
+ printk(KERN_INFO
+ "%s: XLlTemac: Send Threshold = %d, Receive Threshold = %d\n",
+ dev->name, threshold_s, threshold_r);
+ printk(KERN_INFO
+ "%s: XLlTemac: Send Wait bound = %d, Receive Wait bound = %d\n",
+ dev->name, timer_s, timer_r);
+ if (XLlDma_BdRingStart(&lp->Dma.TxBdRing) == XST_FAILURE) {
+ printk(KERN_ERR "%s: XLlTemac: could not start dma tx channel\n", dev->name);
+ return -EIO;
+ }
+ if (XLlDma_BdRingStart(&lp->Dma.RxBdRing) == XST_FAILURE) {
+ printk(KERN_ERR "%s: XLlTemac: could not start dma rx channel\n", dev->name);
+ return -EIO;
+ }
+ }
+
+ /* We're ready to go. */
+ netif_start_queue(dev);
+
+ /* Set up the PHY monitoring timer. */
+ lp->phy_timer.expires = jiffies + 2 * HZ;
+ lp->phy_timer.data = (unsigned long) dev;
+ lp->phy_timer.function = &poll_gmii;
+ init_timer(&lp->phy_timer);
+ add_timer(&lp->phy_timer);
+ return 0;
+}
+
+static int xenet_close(struct net_device *dev)
+{
+ struct net_local *lp;
+ unsigned long flags;
+
+ lp = (struct net_local *) dev->priv;
+
+ /* Shut down the PHY monitoring timer. */
+ del_timer_sync(&lp->phy_timer);
+
+ /* Stop Send queue */
+ netif_stop_queue(dev);
+
+ /* Now we could stop the device */
+ _XLlTemac_Stop(&lp->Emac);
+
+ /*
+ * Free the interrupt - not polled mode.
+ */
+ free_irq(dev->irq, dev);
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ free_irq(lp->dma_irq_s, dev);
+ free_irq(lp->dma_irq_r, dev);
+ } else {
+ free_irq(lp->fifo_irq, dev);
+ }
+
+ spin_lock_irqsave(&receivedQueueSpin, flags);
+ list_del(&(lp->rcv));
+ spin_unlock_irqrestore(&receivedQueueSpin, flags);
+
+ spin_lock_irqsave(&sentQueueSpin, flags);
+ list_del(&(lp->xmit));
+ spin_unlock_irqrestore(&sentQueueSpin, flags);
+
+ return 0;
+}
+
+static struct net_device_stats *xenet_get_stats(struct net_device *dev)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+
+ return &lp->stats;
+}
+
+static int xenet_change_mtu(struct net_device *dev, int new_mtu)
+{
+#ifdef CONFIG_XILINX_GIGE_VLAN
+ int head_size = XTE_HDR_VLAN_SIZE;
+#else
+ int head_size = XTE_HDR_SIZE;
+#endif
+ struct net_local *lp = (struct net_local *) dev->priv;
+ int max_frame = new_mtu + head_size + XTE_TRL_SIZE;
+ int min_frame = 1 + head_size + XTE_TRL_SIZE;
+
+ if ((max_frame < min_frame) || (max_frame > lp->max_frame_size))
+ return -EINVAL;
+
+ dev->mtu = new_mtu; /* change mtu in net_device structure */
+ return 0;
+}
+
+static int xenet_FifoSend(struct sk_buff *skb, struct net_device *dev)
+{
+ struct net_local *lp;
+ unsigned long flags, fifo_free_bytes;
+ int total_frags = skb_shinfo(skb)->nr_frags + 1;
+ unsigned int total_len;
+ skb_frag_t *frag;
+ int i;
+ void *virt_addr;
+
+ total_len = skb_headlen(skb);
+
+ frag = &skb_shinfo(skb)->frags[0];
+ for (i = 1; i < total_frags; i++, frag++) {
+ total_len += frag->size;
+ }
+
+ /* The following lock is used to protect TxVacancy, Write
+ * and TxSetLen sequence which could happen from FifoSendHandler
+ * or other processor in SMP case.
+ */
+ spin_lock_irqsave(&XTE_tx_spinlock, flags);
+ lp = (struct net_local *) dev->priv;
+
+ fifo_free_bytes = XLlFifo_TxVacancy(&lp->Fifo) * 4;
+ if (fifo_free_bytes < total_len) {
+ netif_stop_queue(dev); /* stop send queue */
+ lp->deferred_skb = skb; /* buffer the sk_buffer and will send
+ it in interrupt context */
+ spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+ return 0;
+ }
+
+ /* Write frame data to FIFO */
+ XLlFifo_Write(&lp->Fifo, (void *) skb->data, skb_headlen(skb));
+
+ frag = &skb_shinfo(skb)->frags[0];
+ for (i = 1; i < total_frags; i++, frag++) {
+ virt_addr =
+ (void *) page_address(frag->page) + frag->page_offset;
+ XLlFifo_Write(&lp->Fifo, virt_addr, frag->size);
+ }
+
+ /* Initiate transmit */
+ XLlFifo_TxSetLen(&lp->Fifo, total_len);
+ lp->stats.tx_bytes += total_len;
+ spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+
+ dev_kfree_skb(skb); /* free skb */
+ dev->trans_start = jiffies;
+ return 0;
+}
+
+/* Callback function for completed frames sent in FIFO interrupt driven mode */
+static void FifoSendHandler(struct net_device *dev)
+{
+ struct net_local *lp;
+ struct sk_buff *skb;
+ unsigned int flags;
+
+ spin_lock_irqsave(&XTE_tx_spinlock, flags);
+ lp = (struct net_local *) dev->priv;
+ lp->stats.tx_packets++;
+
+ /*Send out the deferred skb and wake up send queue if a deferred skb exists */
+ if (lp->deferred_skb) {
+ int total_frags;
+ unsigned int total_len;
+ unsigned long fifo_free_bytes;
+ skb_frag_t *frag;
+ int i;
+ void *virt_addr;
+
+ skb = lp->deferred_skb;
+ total_frags = skb_shinfo(skb)->nr_frags + 1;
+ total_len = skb_headlen(skb);
+
+ frag = &skb_shinfo(skb)->frags[0];
+ for (i = 1; i < total_frags; i++, frag++) {
+ total_len += frag->size;
+ }
+
+ fifo_free_bytes = XLlFifo_TxVacancy(&lp->Fifo) * 4;
+ if (fifo_free_bytes < total_len) {
+ /* If still no room for the deferred packet, return */
+ spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+ return;
+ }
+
+ /* Write frame data to FIFO */
+ XLlFifo_Write(&lp->Fifo, (void *) skb->data, skb_headlen(skb));
+
+ frag = &skb_shinfo(skb)->frags[0];
+ for (i = 1; i < total_frags; i++, frag++) {
+ virt_addr =
+ (void *) page_address(frag->page) + frag->page_offset;
+ XLlFifo_Write(&lp->Fifo, virt_addr, frag->size);
+ }
+
+ /* Initiate transmit */
+ XLlFifo_TxSetLen(&lp->Fifo, total_len);
+
+ dev_kfree_skb(skb); /* free skb */
+ lp->deferred_skb = NULL;
+ lp->stats.tx_packets++;
+ lp->stats.tx_bytes += total_len;
+ dev->trans_start = jiffies;
+ netif_wake_queue(dev); /* wake up send queue */
+ }
+ spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+}
+
+#if 0
+/*
+ * These are used for debugging purposes, left here in case they are useful
+ * for further debugging
+ */
+static unsigned int _xenet_tx_csum(struct sk_buff *skb)
+{
+ unsigned int csum = 0;
+ long csstart = skb_transport_header(skb) - skb->data;
+
+ if (csstart != skb->len) {
+ csum = skb_checksum(skb, csstart, skb->len - csstart, 0);
+ }
+
+ return csum;
+}
+
+static inline unsigned int _xenet_rx_csum(struct sk_buff *skb)
+{
+ return skb_checksum(skb, 0, skb->len, 0);
+}
+#endif
+
+/*
+ * xenet_DmaSend_internal is an internal use, send routine.
+ * Any locks that need to be acquired, should be acquired
+ * prior to calling this routine.
+ */
+static int xenet_DmaSend_internal(struct sk_buff *skb, struct net_device *dev)
+{
+ struct net_local *lp;
+ XLlDma_Bd *bd_ptr;
+ int result;
+ int total_frags;
+ int i;
+ void *virt_addr;
+ size_t len;
+ dma_addr_t phy_addr;
+ XLlDma_Bd *first_bd_ptr;
+ XLlDma_Bd *last_bd_ptr;
+ skb_frag_t *frag;
+
+ lp = (struct net_local *) dev->priv;
+ /* get skb_shinfo(skb)->nr_frags + 1 buffer descriptors */
+ total_frags = skb_shinfo(skb)->nr_frags + 1;
+
+ /* stats */
+ if (lp->max_frags_in_a_packet < total_frags) {
+ lp->max_frags_in_a_packet = total_frags;
+ }
+
+ if (total_frags < XTE_SEND_BD_CNT) {
+ result = XLlDma_BdRingAlloc(&lp->Dma.TxBdRing, total_frags,
+ &bd_ptr);
+
+ if (result != XST_SUCCESS) {
+ netif_stop_queue(dev); /* stop send queue */
+ lp->deferred_skb = skb; /* buffer the sk_buffer and will send
+ it in interrupt context */
+ return result;
+ }
+ } else {
+ dev_kfree_skb(skb);
+ lp->stats.tx_dropped++;
+ printk(KERN_ERR
+ "%s: XLlTemac: could not send TX socket buffers (too many fragments).\n",
+ dev->name);
+ return XST_FAILURE;
+ }
+
+ len = skb_headlen(skb);
+
+ /* get the physical address of the header */
+ phy_addr = (u32) dma_map_single(NULL, skb->data, len, DMA_TO_DEVICE);
+
+ /* get the header fragment, it's in the skb differently */
+ XLlDma_mBdSetBufAddr(bd_ptr, phy_addr);
+ XLlDma_mBdSetLength(bd_ptr, len);
+ XLlDma_mBdSetId(bd_ptr, skb);
+
+ /*
+ * if tx checksum offloading is enabled, when the ethernet stack
+ * wants us to perform the checksum in hardware,
+ * skb->ip_summed is CHECKSUM_PARTIAL. Otherwise skb->ip_summed is
+ * CHECKSUM_NONE, meaning the checksum is already done, or
+ * CHECKSUM_UNNECESSARY, meaning checksumming is turned off (e.g.
+ * loopback interface)
+ *
+ * skb->csum is an overloaded value. On send, skb->csum is the offset
+ * into the buffer (skb_transport_header(skb)) to place the csum value.
+ * On receive this feild gets set to the actual csum value, before it's
+ * passed up the stack.
+ *
+ * When we get here, the ethernet stack above will have already
+ * computed the pseudoheader csum value and have placed it in the
+ * TCP/UDP header.
+ *
+ * The IP header csum has also already been computed and inserted.
+ *
+ * Since the IP header with it's own csum should compute to a null
+ * csum, it should be ok to include it in the hw csum. If it is decided
+ * to change this scheme, skb should be examined before dma_map_single()
+ * is called, which flushes the page from the cpu's cache.
+ *
+ * skb->data points to the beginning of the whole packet
+ * skb_transport_header(skb) points to the beginning of the ip header
+ *
+ */
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ unsigned int csum_start_off = skb_transport_offset(skb);
+ unsigned int csum_index_off = csum_start_off + skb->csum_offset;
+
+#if 0
+ {
+ unsigned int csum = _xenet_tx_csum(skb);
+
+ *((unsigned short *) (raw + skb->csum)) =
+ csum_fold(csum);
+ BdCsumDisable(bd_ptr);
+ }
+#else
+ BdCsumEnable(bd_ptr);
+ BdCsumSetup(bd_ptr, csum_start_off,
+ csum_index_off);
+#endif
+ lp->tx_hw_csums++;
+ }
+ else {
+ /*
+ * This routine will do no harm even if hardware checksum capability is
+ * off.
+ */
+ BdCsumDisable(bd_ptr);
+ }
+
+ first_bd_ptr = bd_ptr;
+ last_bd_ptr = bd_ptr;
+
+ frag = &skb_shinfo(skb)->frags[0];
+
+ for (i = 1; i < total_frags; i++, frag++) {
+ bd_ptr = XLlDma_mBdRingNext(&lp->Dma.TxBdRing, bd_ptr);
+ last_bd_ptr = bd_ptr;
+
+ virt_addr =
+ (void *) page_address(frag->page) + frag->page_offset;
+ phy_addr =
+ (u32) dma_map_single(NULL, virt_addr, frag->size,
+ DMA_TO_DEVICE);
+
+ XLlDma_mBdSetBufAddr(bd_ptr, phy_addr);
+ XLlDma_mBdSetLength(bd_ptr, frag->size);
+ XLlDma_mBdSetId(bd_ptr, NULL);
+ BdCsumDisable(bd_ptr);
+ XLlDma_mBdSetStsCtrl(bd_ptr, 0);
+ }
+
+ if (first_bd_ptr == last_bd_ptr) {
+ XLlDma_mBdSetStsCtrl(last_bd_ptr,
+ XLLDMA_BD_STSCTRL_SOP_MASK |
+ XLLDMA_BD_STSCTRL_EOP_MASK);
+ } else {
+ XLlDma_mBdSetStsCtrl(first_bd_ptr, XLLDMA_BD_STSCTRL_SOP_MASK);
+ XLlDma_mBdSetStsCtrl(last_bd_ptr, XLLDMA_BD_STSCTRL_EOP_MASK);
+ }
+
+
+ /* Enqueue to HW */
+ result = XLlDma_BdRingToHw(&lp->Dma.TxBdRing, total_frags,
+ first_bd_ptr);
+ if (result != XST_SUCCESS) {
+ netif_stop_queue(dev); /* stop send queue */
+ dev_kfree_skb(skb);
+ XLlDma_mBdSetId(first_bd_ptr, NULL);
+ lp->stats.tx_dropped++;
+ printk(KERN_ERR
+ "%s: XLlTemac: could not send commit TX buffer descriptor (%d).\n",
+ dev->name, result);
+ reset(dev, __LINE__);
+
+ return XST_FAILURE;
+ }
+
+ dev->trans_start = jiffies;
+
+ return XST_SUCCESS;
+}
+
+/* The send function for frames sent in DMA mode */
+static int xenet_DmaSend(struct sk_buff *skb, struct net_device *dev)
+{
+ /* The following spin_lock protects
+ * SgAlloc, SgCommit sequence, which also exists in DmaSendHandlerBH Bottom
+ * Half, or triggered by other processor in SMP case.
+ */
+ spin_lock_bh(&XTE_tx_spinlock);
+
+ xenet_DmaSend_internal(skb, dev);
+
+ spin_unlock_bh(&XTE_tx_spinlock);
+
+ return 0;
+}
+
+
+static void DmaSendHandlerBH(unsigned long p)
+{
+ struct net_device *dev;
+ struct net_local *lp;
+ XLlDma_Bd *BdPtr, *BdCurPtr;
+ unsigned long len;
+ unsigned long flags;
+ struct sk_buff *skb;
+ dma_addr_t skb_dma_addr;
+ int result = XST_SUCCESS;
+ unsigned int bd_processed, bd_processed_save;
+
+ while (1) {
+ spin_lock_irqsave(&sentQueueSpin, flags);
+ if (list_empty(&sentQueue)) {
+ spin_unlock_irqrestore(&sentQueueSpin, flags);
+ break;
+ }
+
+ lp = list_entry(sentQueue.next, struct net_local, xmit);
+
+ list_del_init(&(lp->xmit));
+ spin_unlock_irqrestore(&sentQueueSpin, flags);
+
+ spin_lock_irqsave(&XTE_tx_spinlock, flags);
+ dev = lp->ndev;
+ bd_processed_save = 0;
+ while ((bd_processed =
+ XLlDma_BdRingFromHw(&lp->Dma.TxBdRing, XTE_SEND_BD_CNT,
+ &BdPtr)) > 0) {
+
+ bd_processed_save = bd_processed;
+ BdCurPtr = BdPtr;
+ do {
+ len = XLlDma_mBdGetLength(BdCurPtr);
+ skb_dma_addr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdCurPtr);
+ dma_unmap_single(NULL, (void *)skb_dma_addr, len,
+ DMA_TO_DEVICE);
+
+ /* get ptr to skb */
+ skb = (struct sk_buff *)
+ XLlDma_mBdGetId(BdCurPtr);
+ if (skb)
+ dev_kfree_skb(skb);
+
+ /* reset BD id */
+ XLlDma_mBdSetId(BdCurPtr, NULL);
+
+ lp->stats.tx_bytes += len;
+ if (XLlDma_mBdGetStsCtrl(BdCurPtr) & XLLDMA_BD_STSCTRL_EOP_MASK) {
+ lp->stats.tx_packets++;
+ }
+
+ BdCurPtr = XLlDma_mBdRingNext(&lp->Dma.TxBdRing, BdCurPtr);
+ bd_processed--;
+ } while (bd_processed > 0);
+
+ result = XLlDma_BdRingFree(&lp->Dma.TxBdRing,
+ bd_processed_save, BdPtr);
+ if (result != XST_SUCCESS) {
+ printk(KERN_ERR
+ "%s: XLlDma: BdRingFree() error %d.\n",
+ dev->name, result);
+ reset(dev, __LINE__);
+ spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+ return;
+ }
+ }
+ XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+
+ /* Send out the deferred skb if it exists */
+ if ((lp->deferred_skb) && bd_processed_save) {
+ skb = lp->deferred_skb;
+ lp->deferred_skb = NULL;
+
+ result = xenet_DmaSend_internal(skb, dev);
+ }
+
+ if (result == XST_SUCCESS) {
+ netif_wake_queue(dev); /* wake up send queue */
+ }
+ spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+ }
+}
+
+static void xenet_tx_timeout(struct net_device *dev)
+{
+ struct net_local *lp;
+ unsigned long flags;
+
+ /*
+ * Make sure that no interrupts come in that could cause reentrancy
+ * problems in reset.
+ */
+ spin_lock_irqsave(&XTE_tx_spinlock, flags);
+
+ lp = (struct net_local *) dev->priv;
+ printk(KERN_ERR
+ "%s: XLlTemac: exceeded transmit timeout of %lu ms. Resetting emac.\n",
+ dev->name, TX_TIMEOUT * 1000UL / HZ);
+ lp->stats.tx_errors++;
+
+ reset(dev, __LINE__);
+
+ spin_unlock_irqrestore(&XTE_tx_spinlock, flags);
+}
+
+/* The callback function for frames received when in FIFO mode. */
+static void FifoRecvHandler(unsigned long p)
+{
+ struct net_local *lp;
+ struct sk_buff *skb;
+ u32 len;
+
+ struct net_device *dev;
+ unsigned long flags;
+ spin_lock_irqsave(&receivedQueueSpin, flags);
+ if (list_empty(&receivedQueue)) {
+ spin_unlock_irqrestore(&receivedQueueSpin, flags);
+ return;
+ }
+ lp = list_entry(receivedQueue.next, struct net_local, rcv);
+
+ list_del_init(&(lp->rcv));
+ spin_unlock_irqrestore(&receivedQueueSpin, flags);
+ dev = lp->ndev;
+
+ while (XLlFifo_RxOccupancy(&lp->Fifo) != 0) {
+
+ len = XLlFifo_RxGetLen(&lp->Fifo);
+
+ /*
+ * TODO: Hm this is odd, if we can't allocate the skb, we throw away the next packet. Why?
+ */
+ if (!(skb = /*dev_ */ alloc_skb(len + ALIGNMENT_RECV, GFP_ATOMIC))) {
+#define XTE_RX_SINK_BUFFER_SIZE 1024
+ static u32 rx_buffer_sink[XTE_RX_SINK_BUFFER_SIZE / sizeof(u32)];
+
+ /* Couldn't get memory. */
+ lp->stats.rx_dropped++;
+ printk(KERN_ERR
+ "%s: XLlTemac: could not allocate receive buffer.\n",
+ dev->name);
+
+ /* consume data in Xilinx TEMAC RX data fifo so it is sync with RX length fifo */
+ for (; len > XTE_RX_SINK_BUFFER_SIZE;
+ len -= XTE_RX_SINK_BUFFER_SIZE) {
+ XLlFifo_Read(&lp->Fifo, rx_buffer_sink,
+ XTE_RX_SINK_BUFFER_SIZE);
+ }
+ XLlFifo_Read(&lp->Fifo, rx_buffer_sink, len);
+ break;
+ }
+
+ /* Read the packet data */
+ XLlFifo_Read(&lp->Fifo, skb->data, len);
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += len;
+
+ skb_put(skb, len); /* Tell the skb how much data we got. */
+ skb->dev = dev; /* Fill out required meta-data. */
+ skb->protocol = eth_type_trans(skb, dev);
+ skb->ip_summed = CHECKSUM_NONE;
+ netif_rx(skb); /* Send the packet upstream. */
+ }
+ XLlFifo_IntEnable(&lp->Fifo, XLLF_INT_TC_MASK | XLLF_INT_RC_MASK |
+ XLLF_INT_RXERROR_MASK | XLLF_INT_TXERROR_MASK);
+
+}
+
+
+/*
+ * _xenet_DmaSetupRecvBuffers allocates as many socket buffers (sk_buff's) as it
+ * can up to the number of free RX buffer descriptors. Then it sets up the RX
+ * buffer descriptors to DMA into the socket_buffers.
+ *
+ * The net_device, dev, indcates on which device to operate for buffer
+ * descriptor allocation.
+ */
+static void _xenet_DmaSetupRecvBuffers(struct net_device *dev)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+
+ int free_bd_count = XLlDma_mBdRingGetFreeCnt(&lp->Dma.RxBdRing);
+ int num_sk_buffs;
+ struct sk_buff_head sk_buff_list;
+ struct sk_buff *new_skb;
+ u32 new_skb_baddr;
+ XLlDma_Bd *BdPtr, *BdCurPtr;
+ u32 align;
+ int result;
+
+#if 0
+ int align_max = ALIGNMENT_RECV;
+#else
+ int align_max = 0;
+#endif
+
+
+ skb_queue_head_init(&sk_buff_list);
+ for (num_sk_buffs = 0; num_sk_buffs < free_bd_count; num_sk_buffs++) {
+ new_skb = alloc_skb(lp->max_frame_size + align_max, GFP_ATOMIC);
+ if (new_skb == NULL) {
+ break;
+ }
+ /*
+ * I think the XTE_spinlock, and Recv DMA int disabled will protect this
+ * list as well, so we can use the __ version just fine
+ */
+ __skb_queue_tail(&sk_buff_list, new_skb);
+ }
+ if (!num_sk_buffs) {
+ printk(KERN_ERR "%s: XLlTemac: alloc_skb unsuccessful\n",
+ dev->name);
+ return;
+ }
+
+ /* now we got a bunch o' sk_buffs */
+ result = XLlDma_BdRingAlloc(&lp->Dma.RxBdRing, num_sk_buffs, &BdPtr);
+ if (result != XST_SUCCESS) {
+ /* we really shouldn't get this */
+ skb_queue_purge(&sk_buff_list);
+ printk(KERN_ERR "%s: XLlDma: BdRingAlloc unsuccessful (%d)\n",
+ dev->name, result);
+ reset(dev, __LINE__);
+ return;
+ }
+
+ BdCurPtr = BdPtr;
+
+ new_skb = skb_dequeue(&sk_buff_list);
+ while (new_skb) {
+ /* make sure we're long-word aligned */
+ align = BUFFER_ALIGNRECV(new_skb->data);
+ if (align) {
+ skb_reserve(new_skb, align);
+ }
+
+ /* Get dma handle of skb->data */
+ new_skb_baddr = (u32) dma_map_single(NULL, new_skb->data,
+ lp->max_frame_size,
+ DMA_FROM_DEVICE);
+
+ XLlDma_mBdSetBufAddr(BdCurPtr, new_skb_baddr);
+ XLlDma_mBdSetLength(BdCurPtr, lp->max_frame_size);
+ XLlDma_mBdSetId(BdCurPtr, new_skb);
+ XLlDma_mBdSetStsCtrl(BdCurPtr,
+ XLLDMA_BD_STSCTRL_SOP_MASK |
+ XLLDMA_BD_STSCTRL_EOP_MASK);
+
+ BdCurPtr = XLlDma_mBdRingNext(&lp->Dma.RxBdRing, BdCurPtr);
+
+ new_skb = skb_dequeue(&sk_buff_list);
+ }
+
+ /* enqueue RxBD with the attached skb buffers such that it is
+ * ready for frame reception */
+ result = XLlDma_BdRingToHw(&lp->Dma.RxBdRing, num_sk_buffs, BdPtr);
+ if (result != XST_SUCCESS) {
+ printk(KERN_ERR
+ "%s: XLlDma: (DmaSetupRecvBuffers) BdRingToHw unsuccessful (%d)\n",
+ dev->name, result);
+ skb_queue_purge(&sk_buff_list);
+ BdCurPtr = BdPtr;
+ while (num_sk_buffs > 0) {
+ XLlDma_mBdSetId(BdCurPtr, NULL);
+ BdCurPtr = XLlDma_mBdRingNext(&lp->Dma.RxBdRing,
+ BdCurPtr);
+ num_sk_buffs--;
+ }
+ reset(dev, __LINE__);
+ return;
+ }
+}
+
+static void DmaRecvHandlerBH(unsigned long p)
+{
+ struct net_device *dev;
+ struct net_local *lp;
+ struct sk_buff *skb;
+ u32 len, skb_baddr;
+ int result;
+ unsigned long flags;
+ XLlDma_Bd *BdPtr, *BdCurPtr;
+ unsigned int bd_processed, bd_processed_saved;
+
+ while (1) {
+ spin_lock_irqsave(&receivedQueueSpin, flags);
+ if (list_empty(&receivedQueue)) {
+ spin_unlock_irqrestore(&receivedQueueSpin, flags);
+ break;
+ }
+ lp = list_entry(receivedQueue.next, struct net_local, rcv);
+
+ list_del_init(&(lp->rcv));
+ spin_unlock_irqrestore(&receivedQueueSpin, flags);
+ dev = lp->ndev;
+
+ spin_lock_irqsave(&XTE_rx_spinlock, flags);
+ if ((bd_processed =
+ XLlDma_BdRingFromHw(&lp->Dma.RxBdRing, XTE_RECV_BD_CNT, &BdPtr)) > 0) {
+
+ bd_processed_saved = bd_processed;
+ BdCurPtr = BdPtr;
+ do {
+ /*
+ * Regular length field not updated on rx,
+ * USR4 updated instead.
+ */
+ len = BdGetRxLen(BdCurPtr);
+
+ /* get ptr to skb */
+ skb = (struct sk_buff *)
+ XLlDma_mBdGetId(BdCurPtr);
+
+ /* get and free up dma handle used by skb->data */
+ skb_baddr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdCurPtr);
+ dma_unmap_single(NULL, (void *)skb_baddr,
+ lp->max_frame_size,
+ DMA_FROM_DEVICE);
+
+ /* reset ID */
+ XLlDma_mBdSetId(BdCurPtr, NULL);
+
+ /* setup received skb and send it upstream */
+ skb_put(skb, len); /* Tell the skb how much data we got. */
+ skb->dev = dev;
+
+ /* this routine adjusts skb->data to skip the header */
+ skb->protocol = eth_type_trans(skb, dev);
+
+ /* default the ip_summed value */
+ skb->ip_summed = CHECKSUM_NONE;
+
+ /* if we're doing rx csum offload, set it up */
+ if (((lp->local_features & LOCAL_FEATURE_RX_CSUM) != 0) &&
+ (skb->protocol == __constant_htons(ETH_P_IP)) &&
+ (skb->len > 64)) {
+ unsigned int csum;
+
+ /*
+ * This hardware only supports proper checksum calculations
+ * on TCP/UDP packets.
+ *
+ * skb->csum is an overloaded value. On send, skb->csum is
+ * the offset into the buffer (skb_transport_header(skb))
+ * to place the csum value. On receive this feild gets set
+ * to the actual csum value, before it's passed up the stack.
+ *
+ * If we set skb->ip_summed to CHECKSUM_COMPLETE, the ethernet
+ * stack above will compute the pseudoheader csum value and
+ * add it to the partial checksum already computed (to be
+ * placed in skb->csum) and verify it.
+ *
+ * Setting skb->ip_summed to CHECKSUM_NONE means that the
+ * cheksum didn't verify and the stack will (re)check it.
+ *
+ * Setting skb->ip_summed to CHECKSUM_UNNECESSARY means
+ * that the cheksum was verified/assumed to be good and the
+ * stack does not need to (re)check it.
+ *
+ * The ethernet stack above will (re)compute the checksum
+ * under the following conditions:
+ * 1) skb->ip_summed was set to CHECKSUM_NONE
+ * 2) skb->len does not match the length of the ethernet
+ * packet determined by parsing the packet. In this case
+ * the ethernet stack will assume any prior checksum
+ * value was miscomputed and throw it away.
+ * 3) skb->ip_summed was set to CHECKSUM_COMPLETE, skb->csum was
+ * set, but the result does not check out ok by the
+ * ethernet stack.
+ *
+ * If the TEMAC hardware stripping feature is off, each
+ * packet will contain an FCS feild which will have been
+ * computed by the hardware checksum operation. This 4 byte
+ * FCS value needs to be subtracted back out of the checksum
+ * value computed by hardware as it's not included in a
+ * normal ethernet packet checksum.
+ *
+ * The minimum transfer packet size over the wire is 64
+ * bytes. If the packet is sent as exactly 64 bytes, then
+ * it probably contains some random padding bytes. It's
+ * somewhat difficult to determine the actual length of the
+ * real packet data, so we just let the stack recheck the
+ * checksum for us.
+ *
+ * After the call to eth_type_trans(), the following holds
+ * true:
+ * skb->data points to the beginning of the ip header
+ */
+ csum = BdCsumGet(BdCurPtr);
+ //printk("hw csum is 0x%08x\n",csum);
+
+#if ! XTE_AUTOSTRIPPING
+ if (!lp->stripping) {
+ /* take off the FCS */
+ u16 *data;
+
+ /* FCS is 4 bytes */
+ skb_put(skb, -4);
+
+ data = (u16 *) (&skb->
+ data[skb->len]);
+
+ /* subtract out the FCS from the csum value */
+ csum = csum_sub(csum, *data /* & 0xffff */);
+ data++;
+ csum = csum_sub(csum, *data /* & 0xffff */);
+ }
+#endif
+ skb->csum = csum;
+ skb->ip_summed = CHECKSUM_COMPLETE;
+
+ lp->rx_hw_csums++;
+ }
+
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += len;
+ netif_rx(skb); /* Send the packet upstream. */
+
+ BdCurPtr =
+ XLlDma_mBdRingNext(&lp->Dma.RxBdRing,
+ BdCurPtr);
+ bd_processed--;
+ } while (bd_processed > 0);
+
+ /* give the descriptor back to the driver */
+ result = XLlDma_BdRingFree(&lp->Dma.RxBdRing,
+ bd_processed_saved, BdPtr);
+ if (result != XST_SUCCESS) {
+ printk(KERN_ERR
+ "%s: XLlDma: BdRingFree unsuccessful (%d)\n",
+ dev->name, result);
+ reset(dev, __LINE__);
+ spin_unlock_irqrestore(&XTE_rx_spinlock, flags);
+ return;
+ }
+
+ _xenet_DmaSetupRecvBuffers(dev);
+ }
+ XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+ spin_unlock_irqrestore(&XTE_rx_spinlock, flags);
+ }
+}
+
+static int descriptor_init(struct net_device *dev)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ int recvsize, sendsize;
+ int dftsize;
+ u32 *recvpoolptr, *sendpoolptr;
+ void *recvpoolphy, *sendpoolphy;
+ int result;
+
+/*
+ * Buffer Descriptr
+ * word byte description
+ * 0 0h next ptr
+ * 1 4h buffer addr
+ * 2 8h buffer len
+ * 3 ch sts/ctrl | app data (0) [tx csum enable (bit 31 LSB)]
+ * 4 10h app data (1) [tx csum begin (bits 0-15 MSB) | csum insert (bits 16-31 LSB)]
+ * 5 14h app data (2) [tx csum seed (bits 16-31 LSB)]
+ * 6 18h app data (3) [rx raw csum (bits 16-31 LSB)]
+ * 7 1ch app data (4) [rx recv length (bits 18-31 LSB)]
+ */
+#if 0
+ int XferType = XDMAV3_DMACR_TYPE_BFBURST_MASK;
+ int XferWidth = XDMAV3_DMACR_DSIZE_64_MASK;
+#endif
+
+ /* calc size of descriptor space pool; alloc from non-cached memory */
+ dftsize = XLlDma_mBdRingMemCalc(ALIGNMENT_BD,
+ XTE_RECV_BD_CNT + XTE_SEND_BD_CNT);
+ printk(KERN_INFO "XLlTemac: buffer descriptor size: %d (0x%0x)\n",
+ dftsize, dftsize);
+
+#if BD_IN_BRAM == 0
+ /*
+ * Allow buffer descriptors to be cached.
+ * Old method w/cache on buffer descriptors disabled:
+ * lp->desc_space = dma_alloc_coherent(NULL, dftsize,
+ * &lp->desc_space_handle, GFP_KERNEL);
+ * (note if going back to dma_alloc_coherent() the CACHE macros in
+ * xenv_linux.h need to be disabled.
+ */
+
+ printk(KERN_INFO "XLlTemac: Allocating DMA descriptors with kmalloc");
+ lp->desc_space = kmalloc(dftsize, GFP_KERNEL);
+ lp->desc_space_handle = (dma_addr_t) page_to_phys(virt_to_page(lp->desc_space));
+#else
+ printk(KERN_INFO "XLlTemac: Allocating DMA descriptors in Block Ram");
+ lp->desc_space_handle = BRAM_BASEADDR;
+ lp->desc_space = ioremap(lp->desc_space_handle, dftsize);
+#endif
+ if (lp->desc_space == 0) {
+ return -1;
+ }
+
+ lp->desc_space_size = dftsize;
+
+ printk(KERN_INFO
+ "XLlTemac: (buffer_descriptor_init) phy: 0x%x, virt: 0x%x, size: 0x%x\n",
+ lp->desc_space_handle, (unsigned int) lp->desc_space,
+ lp->desc_space_size);
+
+ /* calc size of send and recv descriptor space */
+ recvsize = XLlDma_mBdRingMemCalc(ALIGNMENT_BD, XTE_RECV_BD_CNT);
+ sendsize = XLlDma_mBdRingMemCalc(ALIGNMENT_BD, XTE_SEND_BD_CNT);
+
+ recvpoolptr = lp->desc_space;
+ sendpoolptr = (void *) ((u32) lp->desc_space + recvsize);
+
+ recvpoolphy = (void *) lp->desc_space_handle;
+ sendpoolphy = (void *) ((u32) lp->desc_space_handle + recvsize);
+
+ result = XLlDma_BdRingCreate(&lp->Dma.RxBdRing, (u32) recvpoolphy,
+ (u32) recvpoolptr, ALIGNMENT_BD,
+ XTE_RECV_BD_CNT);
+ if (result != XST_SUCCESS) {
+ printk(KERN_ERR "XLlTemac: DMA Ring Create (RECV). Error: %d\n", result);
+ return -EIO;
+ }
+
+ result = XLlDma_BdRingCreate(&lp->Dma.TxBdRing, (u32) sendpoolphy,
+ (u32) sendpoolptr, ALIGNMENT_BD,
+ XTE_SEND_BD_CNT);
+ if (result != XST_SUCCESS) {
+ printk(KERN_ERR "XLlTemac: DMA Ring Create (SEND). Error: %d\n", result);
+ return -EIO;
+ }
+
+ _xenet_DmaSetupRecvBuffers(dev);
+ return 0;
+}
+
+static void free_descriptor_skb(struct net_device *dev)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ XLlDma_Bd *BdPtr;
+ struct sk_buff *skb;
+ dma_addr_t skb_dma_addr;
+ u32 len, i;
+
+ /* Unmap and free skb's allocated and mapped in descriptor_init() */
+
+ /* Get the virtual address of the 1st BD in the DMA RX BD ring */
+ BdPtr = (XLlDma_Bd *) lp->Dma.RxBdRing.FirstBdAddr;
+
+ for (i = 0; i < XTE_RECV_BD_CNT; i++) {
+ skb = (struct sk_buff *) XLlDma_mBdGetId(BdPtr);
+ if (skb) {
+ skb_dma_addr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdPtr);
+ dma_unmap_single(NULL, (void *)skb_dma_addr, lp->max_frame_size,
+ DMA_FROM_DEVICE);
+ dev_kfree_skb(skb);
+ }
+ /* find the next BD in the DMA RX BD ring */
+ BdPtr = XLlDma_mBdRingNext(&lp->Dma.RxBdRing, BdPtr);
+ }
+
+ /* Unmap and free TX skb's that have not had a chance to be freed
+ * in DmaSendHandlerBH(). This could happen when TX Threshold is larger
+ * than 1 and TX waitbound is 0
+ */
+
+ /* Get the virtual address of the 1st BD in the DMA TX BD ring */
+ BdPtr = (XLlDma_Bd *) lp->Dma.TxBdRing.FirstBdAddr;
+
+ for (i = 0; i < XTE_SEND_BD_CNT; i++) {
+ skb = (struct sk_buff *) XLlDma_mBdGetId(BdPtr);
+ if (skb) {
+ skb_dma_addr = (dma_addr_t) XLlDma_mBdGetBufAddr(BdPtr);
+ len = XLlDma_mBdGetLength(BdPtr);
+ dma_unmap_single(NULL, (void *)skb_dma_addr, len,
+ DMA_TO_DEVICE);
+ dev_kfree_skb(skb);
+ }
+ /* find the next BD in the DMA TX BD ring */
+ BdPtr = XLlDma_mBdRingNext(&lp->Dma.TxBdRing, BdPtr);
+ }
+
+#if BD_IN_BRAM == 0
+ dma_free_coherent(NULL,
+ lp->desc_space_size,
+ lp->desc_space, lp->desc_space_handle);
+#else
+ iounmap(lp->desc_space);
+#endif
+}
+
+static int
+xenet_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ u32 mac_options;
+ u32 threshold, timer;
+ u16 gmii_cmd, gmii_status, gmii_advControl;
+
+ memset(ecmd, 0, sizeof(struct ethtool_cmd));
+
+ mac_options = XLlTemac_GetOptions(&(lp->Emac));
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMCR, &gmii_cmd);
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_BMSR, &gmii_status);
+
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, MII_ADVERTISE, &gmii_advControl);
+
+ ecmd->duplex = DUPLEX_FULL;
+
+ ecmd->supported |= SUPPORTED_MII;
+
+ ecmd->port = PORT_MII;
+
+ ecmd->speed = lp->cur_speed;
+
+ if (gmii_status & BMSR_ANEGCAPABLE) {
+ ecmd->supported |= SUPPORTED_Autoneg;
+ }
+ if (gmii_status & BMSR_ANEGCOMPLETE) {
+ ecmd->autoneg = AUTONEG_ENABLE;
+ ecmd->advertising |= ADVERTISED_Autoneg;
+ }
+ else {
+ ecmd->autoneg = AUTONEG_DISABLE;
+ }
+ ecmd->phy_address = lp->Emac.Config.BaseAddress;
+ ecmd->transceiver = XCVR_INTERNAL;
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ /* get TX threshold */
+
+ XLlDma_BdRingGetCoalesce(&lp->Dma.TxBdRing, &threshold, &timer);
+ ecmd->maxtxpkt = threshold;
+
+ /* get RX threshold */
+ XLlDma_BdRingGetCoalesce(&lp->Dma.RxBdRing, &threshold, &timer);
+ ecmd->maxrxpkt = threshold;
+ }
+
+ ecmd->supported |= SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg;
+
+ return 0;
+}
+
+static int
+xenet_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+
+ if ((ecmd->duplex != DUPLEX_FULL) ||
+ (ecmd->transceiver != XCVR_INTERNAL) ||
+ (ecmd->phy_address &&
+ (ecmd->phy_address != lp->Emac.Config.BaseAddress))) {
+ return -EOPNOTSUPP;
+ }
+
+ if ((ecmd->speed != 1000) && (ecmd->speed != 100) &&
+ (ecmd->speed != 10)) {
+ printk(KERN_ERR
+ "%s: XLlTemac: xenet_ethtool_set_settings speed not supported: %d\n",
+ dev->name, ecmd->speed);
+ return -EOPNOTSUPP;
+ }
+
+ if (ecmd->speed != lp->cur_speed) {
+ renegotiate_speed(dev, ecmd->speed, FULL_DUPLEX);
+ _XLlTemac_SetOperatingSpeed(&lp->Emac, ecmd->speed);
+ lp->cur_speed = ecmd->speed;
+ }
+ return 0;
+}
+
+static int
+xenet_ethtool_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ u32 threshold, waitbound;
+
+ memset(ec, 0, sizeof(struct ethtool_coalesce));
+
+ XLlDma_BdRingGetCoalesce(&lp->Dma.RxBdRing, &threshold, &waitbound);
+ ec->rx_max_coalesced_frames = threshold;
+ ec->rx_coalesce_usecs = waitbound;
+
+ XLlDma_BdRingGetCoalesce(&lp->Dma.TxBdRing, &threshold, &waitbound);
+ ec->tx_max_coalesced_frames = threshold;
+ ec->tx_coalesce_usecs = waitbound;
+
+ return 0;
+}
+
+void disp_bd_ring(XLlDma_BdRing *bd_ring)
+{
+ int num_bds = bd_ring->AllCnt;
+ u32 *cur_bd_ptr = (u32 *) bd_ring->FirstBdAddr;
+ int idx;
+
+ printk("ChanBase: %p\n", (void *) bd_ring->ChanBase);
+ printk("FirstBdPhysAddr: %p\n", (void *) bd_ring->FirstBdPhysAddr);
+ printk("FirstBdAddr: %p\n", (void *) bd_ring->FirstBdAddr);
+ printk("LastBdAddr: %p\n", (void *) bd_ring->LastBdAddr);
+ printk("Length: %d (0x%0x)\n", bd_ring->Length, bd_ring->Length);
+ printk("RunState: %d (0x%0x)\n", bd_ring->RunState, bd_ring->RunState);
+ printk("Separation: %d (0x%0x)\n", bd_ring->Separation,
+ bd_ring->Separation);
+ printk("BD Count: %d\n", bd_ring->AllCnt);
+
+ printk("\n");
+
+ printk("FreeHead: %p\n", (void *) bd_ring->FreeHead);
+ printk("PreHead: %p\n", (void *) bd_ring->PreHead);
+ printk("HwHead: %p\n", (void *) bd_ring->HwHead);
+ printk("HwTail: %p\n", (void *) bd_ring->HwTail);
+ printk("PostHead: %p\n", (void *) bd_ring->PostHead);
+ printk("BdaRestart: %p\n", (void *) bd_ring->BdaRestart);
+
+ printk("Ring Contents:\n");
+/*
+ * Buffer Descriptr
+ * word byte description
+ * 0 0h next ptr
+ * 1 4h buffer addr
+ * 2 8h buffer len
+ * 3 ch sts/ctrl | app data (0) [tx csum enable (bit 31 LSB)]
+ * 4 10h app data (1) [tx csum begin (bits 0-15 MSB) | csum insert (bits 16-31 LSB)]
+ * 5 14h app data (2) [tx csum seed (bits 16-31 LSB)]
+ * 6 18h app data (3) [rx raw csum (bits 16-31 LSB)]
+ * 7 1ch app data (4) [rx recv length (bits 18-31 LSB)]
+ * 8 20h sw app data (0) [id]
+ */
+ printk("Idx NextBD BuffAddr Length CTL/CSE CSUM B/I CSUMSeed Raw CSUM RecvLen ID\n");
+ printk("--- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/-------- software/linux-2.6.x-petalogix/--------\n");
+
+ for (idx = 0; idx < num_bds; idx++) {
+ printk("%3d %08x %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ idx,
+ cur_bd_ptr[XLLDMA_BD_NDESC_OFFSET / sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_BUFA_OFFSET / sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_BUFL_OFFSET / sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_STSCTRL_USR0_OFFSET /
+ sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_USR1_OFFSET / sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_USR2_OFFSET / sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_USR3_OFFSET / sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_USR4_OFFSET / sizeof(*cur_bd_ptr)],
+ cur_bd_ptr[XLLDMA_BD_ID_OFFSET / sizeof(*cur_bd_ptr)]);
+
+ cur_bd_ptr += bd_ring->Separation / sizeof(int);
+ }
+ printk("--------------------------------------- software/linux-2.6.x-petalogix/Done ---------------------------------------\n");
+}
+
+static int
+xenet_ethtool_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
+{
+ int ret;
+ struct net_local *lp;
+
+ lp = (struct net_local *) dev->priv;
+
+ if (ec->rx_coalesce_usecs == 0) {
+ ec->rx_coalesce_usecs = 1;
+ dma_rx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+ }
+ if ((ret = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing,
+ (u16) (ec->rx_max_coalesced_frames),
+ (u16) (ec->rx_coalesce_usecs))) != XST_SUCCESS) {
+ printk(KERN_ERR "%s: XLlDma: BdRingSetCoalesce error %d\n",
+ dev->name, ret);
+ return -EIO;
+ }
+ XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+
+ if (ec->tx_coalesce_usecs == 0) {
+ ec->tx_coalesce_usecs = 1;
+ dma_tx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+ }
+ if ((ret = XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing,
+ (u16) (ec->tx_max_coalesced_frames),
+ (u16) (ec->tx_coalesce_usecs))) != XST_SUCCESS) {
+ printk(KERN_ERR "%s: XLlDma: BdRingSetCoalesce error %d\n",
+ dev->name, ret);
+ return -EIO;
+ }
+ XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+
+ return 0;
+}
+
+static int
+xenet_ethtool_get_ringparam(struct net_device *dev,
+ struct ethtool_ringparam *erp)
+{
+ memset(erp, 0, sizeof(struct ethtool_ringparam));
+
+ erp->rx_max_pending = XTE_RECV_BD_CNT;
+ erp->tx_max_pending = XTE_SEND_BD_CNT;
+ erp->rx_pending = XTE_RECV_BD_CNT;
+ erp->tx_pending = XTE_SEND_BD_CNT;
+ return 0;
+}
+
+#define EMAC_REGS_N 32
+struct mac_regsDump {
+ struct ethtool_regs hd;
+ u16 data[EMAC_REGS_N];
+};
+
+static void
+xenet_ethtool_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ void *ret)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ struct mac_regsDump *dump = (struct mac_regsDump *) regs;
+ int i;
+
+ dump->hd.version = 0;
+ dump->hd.len = sizeof(dump->data);
+ memset(dump->data, 0, sizeof(dump->data));
+
+ for (i = 0; i < EMAC_REGS_N; i++) {
+ _XLlTemac_PhyRead(&lp->Emac, lp->gmii_addr, i, &(dump->data[i]));
+ }
+
+ *(int *) ret = 0;
+}
+
+static int
+xenet_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *ed)
+{
+ memset(ed, 0, sizeof(struct ethtool_drvinfo));
+ strncpy(ed->driver, DRIVER_NAME, sizeof(ed->driver) - 1);
+ strncpy(ed->version, DRIVER_VERSION, sizeof(ed->version) - 1);
+ /* Also tell how much memory is needed for dumping register values */
+ ed->regdump_len = sizeof(u16) * EMAC_REGS_N;
+ return 0;
+}
+
+static int xenet_do_ethtool_ioctl(struct net_device *dev, struct ifreq *rq)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+ struct ethtool_cmd ecmd;
+ struct ethtool_coalesce eco;
+ struct ethtool_drvinfo edrv;
+ struct ethtool_ringparam erp;
+ struct ethtool_pauseparam epp;
+ struct mac_regsDump regs;
+ int ret = -EOPNOTSUPP;
+ u32 Options;
+
+ if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+ return -EFAULT;
+ switch (ecmd.cmd) {
+ case ETHTOOL_GSET: /* Get setting. No command option needed w/ ethtool */
+ ret = xenet_ethtool_get_settings(dev, &ecmd);
+ if (ret < 0)
+ return -EIO;
+ if (copy_to_user(rq->ifr_data, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ ret = 0;
+ break;
+ case ETHTOOL_SSET: /* Change setting. Use "-s" command option w/ ethtool */
+ ret = xenet_ethtool_set_settings(dev, &ecmd);
+ break;
+ case ETHTOOL_GPAUSEPARAM: /* Get pause parameter information. Use "-a" w/ ethtool */
+ ret = xenet_ethtool_get_settings(dev, &ecmd);
+ if (ret < 0)
+ return ret;
+ epp.cmd = ecmd.cmd;
+ epp.autoneg = ecmd.autoneg;
+ Options = XLlTemac_GetOptions(&lp->Emac);
+ if (Options & XTE_FCS_INSERT_OPTION) {
+ epp.rx_pause = 1;
+ epp.tx_pause = 1;
+ }
+ else {
+ epp.rx_pause = 0;
+ epp.tx_pause = 0;
+ }
+ if (copy_to_user
+ (rq->ifr_data, &epp, sizeof(struct ethtool_pauseparam)))
+ return -EFAULT;
+ ret = 0;
+ break;
+ case ETHTOOL_SPAUSEPARAM: /* Set pause parameter. Use "-A" w/ ethtool */
+ return -EOPNOTSUPP; /* TODO: To support in next version */
+ case ETHTOOL_GRXCSUM:{ /* Get rx csum offload info. Use "-k" w/ ethtool */
+ struct ethtool_value edata = { ETHTOOL_GRXCSUM };
+
+ edata.data =
+ (lp->local_features & LOCAL_FEATURE_RX_CSUM) !=
+ 0;
+ if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
+ return -EFAULT;
+ ret = 0;
+ break;
+ }
+ case ETHTOOL_SRXCSUM:{ /* Set rx csum offload info. Use "-K" w/ ethtool */
+ struct ethtool_value edata;
+
+ if (copy_from_user(&edata, rq->ifr_data, sizeof(edata)))
+ return -EFAULT;
+
+ if (edata.data) {
+ if (XLlTemac_IsRxCsum(&lp->Emac) == TRUE) {
+ lp->local_features |=
+ LOCAL_FEATURE_RX_CSUM;
+ }
+ }
+ else {
+ lp->local_features &= ~LOCAL_FEATURE_RX_CSUM;
+ }
+
+ ret = 0;
+ break;
+ }
+ case ETHTOOL_GTXCSUM:{ /* Get tx csum offload info. Use "-k" w/ ethtool */
+ struct ethtool_value edata = { ETHTOOL_GTXCSUM };
+
+ edata.data = (dev->features & NETIF_F_IP_CSUM) != 0;
+ if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
+ return -EFAULT;
+ ret = 0;
+ break;
+ }
+ case ETHTOOL_STXCSUM:{ /* Set tx csum offload info. Use "-K" w/ ethtool */
+ struct ethtool_value edata;
+
+ if (copy_from_user(&edata, rq->ifr_data, sizeof(edata)))
+ return -EFAULT;
+
+ if (edata.data) {
+ if (XLlTemac_IsTxCsum(&lp->Emac) == TRUE) {
+ dev->features |= NETIF_F_IP_CSUM;
+ }
+ }
+ else {
+ dev->features &= ~NETIF_F_IP_CSUM;
+ }
+
+ ret = 0;
+ break;
+ }
+ case ETHTOOL_GSG:{ /* Get ScatterGather info. Use "-k" w/ ethtool */
+ struct ethtool_value edata = { ETHTOOL_GSG };
+
+ edata.data = (dev->features & NETIF_F_SG) != 0;
+ if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
+ return -EFAULT;
+ ret = 0;
+ break;
+ }
+ case ETHTOOL_SSG:{ /* Set ScatterGather info. Use "-K" w/ ethtool */
+ struct ethtool_value edata;
+
+ if (copy_from_user(&edata, rq->ifr_data, sizeof(edata)))
+ return -EFAULT;
+
+ if (edata.data) {
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ dev->features |=
+ NETIF_F_SG | NETIF_F_FRAGLIST;
+ }
+ }
+ else {
+ dev->features &=
+ ~(NETIF_F_SG | NETIF_F_FRAGLIST);
+ }
+
+ ret = 0;
+ break;
+ }
+ case ETHTOOL_GCOALESCE: /* Get coalescing info. Use "-c" w/ ethtool */
+ if (!(XLlTemac_IsDma(&lp->Emac)))
+ break;
+ eco.cmd = ecmd.cmd;
+ ret = xenet_ethtool_get_coalesce(dev, &eco);
+ if (ret < 0) {
+ return -EIO;
+ }
+ if (copy_to_user
+ (rq->ifr_data, &eco, sizeof(struct ethtool_coalesce))) {
+ return -EFAULT;
+ }
+ ret = 0;
+ break;
+ case ETHTOOL_SCOALESCE: /* Set coalescing info. Use "-C" w/ ethtool */
+ if (!(XLlTemac_IsDma(&lp->Emac)))
+ break;
+ if (copy_from_user
+ (&eco, rq->ifr_data, sizeof(struct ethtool_coalesce)))
+ return -EFAULT;
+ ret = xenet_ethtool_set_coalesce(dev, &eco);
+ break;
+ case ETHTOOL_GDRVINFO: /* Get driver information. Use "-i" w/ ethtool */
+ edrv.cmd = edrv.cmd;
+ ret = xenet_ethtool_get_drvinfo(dev, &edrv);
+ if (ret < 0) {
+ return -EIO;
+ }
+ edrv.n_stats = XENET_STATS_LEN;
+ if (copy_to_user
+ (rq->ifr_data, &edrv, sizeof(struct ethtool_drvinfo))) {
+ return -EFAULT;
+ }
+ ret = 0;
+ break;
+ case ETHTOOL_GREGS: /* Get register values. Use "-d" with ethtool */
+ regs.hd.cmd = edrv.cmd;
+ xenet_ethtool_get_regs(dev, &(regs.hd), &ret);
+ if (ret < 0) {
+ return ret;
+ }
+ if (copy_to_user
+ (rq->ifr_data, ®s, sizeof(struct mac_regsDump))) {
+ return -EFAULT;
+ }
+ ret = 0;
+ break;
+ case ETHTOOL_GRINGPARAM: /* Get RX/TX ring parameters. Use "-g" w/ ethtool */
+ erp.cmd = edrv.cmd;
+ ret = xenet_ethtool_get_ringparam(dev, &(erp));
+ if (ret < 0) {
+ return ret;
+ }
+ if (copy_to_user
+ (rq->ifr_data, &erp, sizeof(struct ethtool_ringparam))) {
+ return -EFAULT;
+ }
+ ret = 0;
+ break;
+ case ETHTOOL_NWAY_RST: /* Restart auto negotiation if enabled. Use "-r" w/ ethtool */
+ return -EOPNOTSUPP; /* TODO: To support in next version */
+ case ETHTOOL_GSTRINGS:{
+ struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS };
+ void *addr = rq->ifr_data;
+ char *strings = NULL;
+
+ if (copy_from_user(&gstrings, addr, sizeof(gstrings))) {
+ return -EFAULT;
+ }
+ switch (gstrings.string_set) {
+ case ETH_SS_STATS:
+ gstrings.len = XENET_STATS_LEN;
+ strings = *xenet_ethtool_gstrings_stats;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ if (copy_to_user(addr, &gstrings, sizeof(gstrings))) {
+ return -EFAULT;
+ }
+ addr += offsetof(struct ethtool_gstrings, data);
+ if (copy_to_user
+ (addr, strings, gstrings.len * ETH_GSTRING_LEN)) {
+ return -EFAULT;
+ }
+ ret = 0;
+ break;
+ }
+ case ETHTOOL_GSTATS:{
+ struct {
+ struct ethtool_stats cmd;
+ uint64_t data[XENET_STATS_LEN];
+ } stats = { {
+ ETHTOOL_GSTATS, XENET_STATS_LEN}};
+
+ stats.data[0] = lp->stats.tx_packets;
+ stats.data[1] = lp->stats.tx_dropped;
+ stats.data[2] = lp->stats.tx_errors;
+ stats.data[3] = lp->stats.tx_fifo_errors;
+ stats.data[4] = lp->stats.rx_packets;
+ stats.data[5] = lp->stats.rx_dropped;
+ stats.data[6] = lp->stats.rx_errors;
+ stats.data[7] = lp->stats.rx_fifo_errors;
+ stats.data[8] = lp->stats.rx_crc_errors;
+ stats.data[9] = lp->max_frags_in_a_packet;
+ stats.data[10] = lp->tx_hw_csums;
+ stats.data[11] = lp->rx_hw_csums;
+
+ if (copy_to_user(rq->ifr_data, &stats, sizeof(stats))) {
+ return -EFAULT;
+ }
+ ret = 0;
+ break;
+ }
+ default:
+ return -EOPNOTSUPP; /* All other operations not supported */
+ }
+ return ret;
+}
+
+static int xenet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct net_local *lp = (struct net_local *) dev->priv;
+
+ /* gmii_ioctl_data has 4 u16 fields: phy_id, reg_num, val_in & val_out */
+ struct mii_ioctl_data *data = (struct mii_ioctl_data *) &rq->ifr_data;
+ struct {
+ __u16 threshold;
+ __u32 direction;
+ } thr_arg;
+ struct {
+ __u16 waitbound;
+ __u32 direction;
+ } wbnd_arg;
+
+ int ret;
+ u32 threshold, timer;
+ XLlDma_BdRing *RingPtr;
+ u32 *dma_int_mask_ptr;
+
+ switch (cmd) {
+ case SIOCETHTOOL:
+ return xenet_do_ethtool_ioctl(dev, rq);
+ case SIOCGMIIPHY: /* Get address of GMII PHY in use. */
+ case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
+ data->phy_id = lp->gmii_addr;
+ /* Fall Through */
+
+ case SIOCGMIIREG: /* Read GMII PHY register. */
+ case SIOCDEVPRIVATE + 1: /* for binary compat, remove in 2.5 */
+ if (data->phy_id > 31 || data->reg_num > 31)
+ return -ENXIO;
+
+ /* Stop the PHY timer to prevent reentrancy. */
+ del_timer_sync(&lp->phy_timer);
+
+ _XLlTemac_PhyRead(&lp->Emac, data->phy_id, data->reg_num,
+ &data->val_out);
+
+ /* Start the PHY timer up again. */
+ lp->phy_timer.expires = jiffies + 2 * HZ;
+ add_timer(&lp->phy_timer);
+ return 0;
+
+ case SIOCSMIIREG: /* Write GMII PHY register. */
+ case SIOCDEVPRIVATE + 2: /* for binary compat, remove in 2.5 */
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (data->phy_id > 31 || data->reg_num > 31)
+ return -ENXIO;
+
+ /* Stop the PHY timer to prevent reentrancy. */
+ del_timer_sync(&lp->phy_timer);
+
+ _XLlTemac_PhyWrite(&lp->Emac, data->phy_id, data->reg_num,
+ data->val_in);
+
+ /* Start the PHY timer up again. */
+ lp->phy_timer.expires = jiffies + 2 * HZ;
+ add_timer(&lp->phy_timer);
+ return 0;
+
+ case SIOCDEVPRIVATE + 3: /* set THRESHOLD */
+ if (XLlTemac_IsFifo(&lp->Emac))
+ return -EFAULT;
+
+ if (copy_from_user(&thr_arg, rq->ifr_data, sizeof(thr_arg)))
+ return -EFAULT;
+
+ if (thr_arg.direction == XTE_SEND) {
+ RingPtr = &lp->Dma.TxBdRing;
+ } else {
+ RingPtr = &lp->Dma.RxBdRing;
+ }
+ XLlDma_BdRingGetCoalesce(RingPtr, &threshold, &timer);
+ if (thr_arg.direction == XTE_SEND) {
+ RingPtr = &lp->Dma.TxBdRing;
+ } else {
+ RingPtr = &lp->Dma.RxBdRing;
+ }
+ if ((ret = XLlDma_BdRingSetCoalesce(RingPtr, thr_arg.threshold,
+ timer)) != XST_SUCCESS) {
+ return -EIO;
+ }
+ return 0;
+
+ case SIOCDEVPRIVATE + 4: /* set WAITBOUND */
+ if (!(XLlTemac_IsDma(&lp->Emac)))
+ return -EFAULT;
+
+ if (copy_from_user(&wbnd_arg, rq->ifr_data, sizeof(wbnd_arg)))
+ return -EFAULT;
+
+ if (wbnd_arg.direction == XTE_SEND) {
+ RingPtr = &lp->Dma.TxBdRing;
+ } else {
+ RingPtr = &lp->Dma.RxBdRing;
+ }
+ XLlDma_BdRingGetCoalesce(RingPtr, &threshold, &timer);
+ if (wbnd_arg.direction == XTE_SEND) {
+ RingPtr = &lp->Dma.TxBdRing;
+ dma_int_mask_ptr = &dma_tx_int_mask;
+ } else {
+ RingPtr = &lp->Dma.RxBdRing;
+ dma_int_mask_ptr = &dma_rx_int_mask;
+ }
+ if (wbnd_arg.waitbound == 0) {
+ wbnd_arg.waitbound = 1;
+ *dma_int_mask_ptr = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+ }
+ if ((ret = XLlDma_BdRingSetCoalesce(RingPtr, threshold,
+ wbnd_arg.waitbound)) != XST_SUCCESS) {
+ return -EIO;
+ }
+ XLlDma_mBdRingIntEnable(RingPtr, *dma_int_mask_ptr);
+
+ return 0;
+
+ case SIOCDEVPRIVATE + 5: /* get THRESHOLD */
+ if (!(XLlTemac_IsDma(&lp->Emac)))
+ return -EFAULT;
+
+ if (copy_from_user(&thr_arg, rq->ifr_data, sizeof(thr_arg)))
+ return -EFAULT;
+
+ if (thr_arg.direction == XTE_SEND) {
+ RingPtr = &lp->Dma.TxBdRing;
+ } else {
+ RingPtr = &lp->Dma.RxBdRing;
+ }
+ XLlDma_BdRingGetCoalesce(RingPtr,
+ (u32 *) &(thr_arg.threshold), &timer);
+ if (copy_to_user(rq->ifr_data, &thr_arg, sizeof(thr_arg))) {
+ return -EFAULT;
+ }
+ return 0;
+
+ case SIOCDEVPRIVATE + 6: /* get WAITBOUND */
+ if (!(XLlTemac_IsDma(&lp->Emac)))
+ return -EFAULT;
+
+ if (copy_from_user(&wbnd_arg, rq->ifr_data, sizeof(wbnd_arg))) {
+ return -EFAULT;
+ }
+ if (thr_arg.direction == XTE_SEND) {
+ RingPtr = &lp->Dma.TxBdRing;
+ } else {
+ RingPtr = &lp->Dma.RxBdRing;
+ }
+ XLlDma_BdRingGetCoalesce(RingPtr, &threshold,
+ (u32 *) &(wbnd_arg.waitbound));
+ if (copy_to_user(rq->ifr_data, &wbnd_arg, sizeof(wbnd_arg))) {
+ return -EFAULT;
+ }
+ return 0;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+
+/******************************************************************************
+ *
+ * NEW FUNCTIONS FROM LINUX 2.6
+ *
+ ******************************************************************************/
+
+static void xtenet_remove_ndev(struct net_device *ndev)
+{
+ if (ndev) {
+ struct net_local *lp = netdev_priv(ndev);
+
+ if (XLlTemac_IsDma(&lp->Emac) && (lp->desc_space))
+ free_descriptor_skb(ndev);
+
+ iounmap((void *) (lp->Emac.Config.BaseAddress));
+ free_netdev(ndev);
+ }
+}
+
+static int xtenet_remove(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+
+ unregister_netdev(ndev);
+ xtenet_remove_ndev(ndev);
+
+ return 0; /* success */
+}
+
+/* Detect the PHY address by scanning addresses 0 to 31 and
+ * looking at the MII status register (register 1) and assuming
+ * the PHY supports 10Mbps full/half duplex. Feel free to change
+ * this code to match your PHY, or hardcode the address if needed.
+ */
+/* Use MII register 1 (MII status register) to detect PHY */
+#define PHY_DETECT_REG 1
+
+/* Mask used to verify certain PHY features (or register contents)
+ * in the register above:
+ * 0x1000: 10Mbps full duplex support
+ * 0x0800: 10Mbps half duplex support
+ * 0x0008: Auto-negotiation support
+ */
+//#define PHY_DETECT_MASK 0x1808
+
+/* FIXME JW The Vitesse PHY with our ebc701 CMODE register values doesn't
+ report it's 10/100/1000 capabiltiies until it gets an SGMII link with the
+ MGT. But, we need the PHY address to do this setup.
+
+ So, hack the detect mask down to what is reported by the PHY even when in
+ "cold boot" mode, so we at least find it.
+
+ A better long term solution is required here
+*/
+#define PHY_DETECT_MASK 0x0149
+
+void phy_reg_scan(struct net_local *lp, u32 phy_addr)
+{
+ u16 phy_reg;
+ int i;
+
+ printk("Scanning phy address %i",phy_addr);
+ for(i=0;i<32; i++) {
+ _XLlTemac_PhyRead(&lp->Emac, phy_addr, i,&phy_reg);
+ if(!(i%4))
+ printk("\n");
+ printk("%d: 0x%08x ",i,phy_reg);
+ }
+ printk("\n------------------\n");
+
+}
+
+static int detect_phy(struct net_local *lp, char *dev_name)
+{
+ u16 phy_reg;
+ u32 phy_addr;
+
+ for (phy_addr = 31; phy_addr > 0; phy_addr--) {
+
+ _XLlTemac_PhyRead(&lp->Emac, phy_addr, PHY_DETECT_REG, &phy_reg);
+ if ((phy_reg != 0xFFFF) &&
+ ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+ /* Found a valid PHY address */
+ printk(KERN_INFO "XTemac: PHY detected at address %d.\n", phy_addr);
+ return phy_addr;
+ }
+ }
+
+ printk(KERN_WARNING "XTemac: No PHY detected. Assuming a PHY at address 0\n");
+ return 0; /* default to zero */
+}
+
+
+/** Shared device initialization code */
+static int xtenet_setup(
+ struct device *dev,
+ struct resource *r_mem,
+ struct resource *r_irq,
+ struct xlltemac_platform_data *pdata) {
+ int xs;
+ u32 virt_baddr; /* virtual base address of TEMAC */
+
+ XLlTemac_Config Temac_Config;
+
+ struct net_device *ndev = NULL;
+ struct net_local *lp = NULL;
+
+ int rc = 0;
+
+ /* Create an ethernet device instance */
+ ndev = alloc_etherdev(sizeof(struct net_local));
+ if (!ndev) {
+ dev_err(dev, "xlltemac: Could not allocate net device.\n");
+ rc = -ENOMEM;
+ goto error;
+ }
+ dev_set_drvdata(dev, ndev);
+
+ ndev->irq = r_irq->start;
+
+ /* Initialize the private data used by XEmac_LookupConfig().
+ * The private data are zeroed out by alloc_etherdev() already.
+ */
+ lp = netdev_priv(ndev);
+ lp->ndev = ndev;
+ lp->dma_irq_r = pdata->ll_dev_dma_rx_irq;
+ lp->dma_irq_s = pdata->ll_dev_dma_tx_irq;
+ lp->fifo_irq = pdata->ll_dev_fifo_irq;
+
+ /* Setup the Config structure for the XLlTemac_CfgInitialize() call. */
+ Temac_Config.BaseAddress = r_mem->start;
+#if 0
+ Config.RxPktFifoDepth = pdata->rx_pkt_fifo_depth;
+ Config.TxPktFifoDepth = pdata->tx_pkt_fifo_depth;
+ Config.MacFifoDepth = pdata->mac_fifo_depth;
+ Config.IpIfDmaConfig = pdata->dma_mode;
+#endif
+ Temac_Config.TxCsum = pdata->tx_csum;
+ Temac_Config.RxCsum = pdata->rx_csum;
+ Temac_Config.LLDevType = pdata->ll_dev_type;
+ Temac_Config.LLDevBaseAddress = pdata->ll_dev_baseaddress;
+ Temac_Config.PhyType = pdata->phy_type;
+
+ /* Get the virtual base address for the device */
+ virt_baddr = (u32) ioremap(r_mem->start, r_mem->end - r_mem->start + 1);
+ if (0 == virt_baddr) {
+ dev_err(dev, "XLlTemac: Could not allocate iomem.\n");
+ rc = -EIO;
+ goto error;
+ }
+
+ if (XLlTemac_CfgInitialize(&lp->Emac, &Temac_Config, virt_baddr) !=
+ XST_SUCCESS) {
+ dev_err(dev, "XLlTemac: Could not initialize device.\n");
+
+ rc = -ENODEV;
+ goto error;
+ }
+
+ /* Set the MAC address */
+ memcpy(ndev->dev_addr, pdata->mac_addr, 6);
+ if (_XLlTemac_SetMacAddress(&lp->Emac, ndev->dev_addr) != XST_SUCCESS) {
+ /* should not fail right after an initialize */
+ dev_err(dev, "XLlTemac: could not set MAC address.\n");
+ rc = -EIO;
+ goto error;
+ }
+
+ dev_info(dev,
+ "MAC address is now %2x:%2x:%2x:%2x:%2x:%2x\n",
+ pdata->mac_addr[0], pdata->mac_addr[1],
+ pdata->mac_addr[2], pdata->mac_addr[3],
+ pdata->mac_addr[4], pdata->mac_addr[5]);
+
+ lp->max_frame_size = XTE_MAX_JUMBO_FRAME_SIZE;
+ if (ndev->mtu > XTE_JUMBO_MTU)
+ ndev->mtu = XTE_JUMBO_MTU;
+
+
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ int result;
+
+ dev_err(dev, "XLlTemac: using DMA mode.\n");
+
+#ifndef XDCRIO_H
+ virt_baddr = (u32) ioremap(pdata->ll_dev_baseaddress, 4096);
+ if (0 == virt_baddr) {
+ dev_err(dev,
+ "XLlTemac: Could not allocate iomem for local link connected device.\n");
+ rc = -EIO;
+ goto error;
+ }
+#endif
+ printk("XLlTemac: Dma base address: phy: 0x%x, virt: 0x%x\n", pdata->ll_dev_baseaddress, virt_baddr);
+ XLlDma_Initialize(&lp->Dma, virt_baddr);
+
+
+ ndev->hard_start_xmit = xenet_DmaSend;
+
+ result = descriptor_init(ndev);
+ if (result) {
+ rc = -EIO;
+ goto error;
+ }
+
+ /* set the packet threshold and wait bound for both TX/RX directions */
+ if (DFT_TX_WAITBOUND == 0) {
+ dma_tx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+ xs = XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing, DFT_TX_THRESHOLD, 1);
+ } else {
+ xs = XLlDma_BdRingSetCoalesce(&lp->Dma.TxBdRing, DFT_TX_THRESHOLD, DFT_TX_WAITBOUND);
+ }
+ if (xs != XST_SUCCESS) {
+ dev_err(dev,
+ "XLlTemac: could not set SEND pkt threshold/waitbound, ERROR %d",
+ xs);
+ }
+ XLlDma_mBdRingIntEnable(&lp->Dma.TxBdRing, dma_tx_int_mask);
+
+ if (DFT_RX_WAITBOUND == 0) {
+ dma_rx_int_mask = XLLDMA_CR_IRQ_ALL_EN_MASK & ~XLLDMA_CR_IRQ_DELAY_EN_MASK;
+ xs = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing, DFT_RX_THRESHOLD, 1);
+ } else {
+ xs = XLlDma_BdRingSetCoalesce(&lp->Dma.RxBdRing, DFT_RX_THRESHOLD, DFT_RX_WAITBOUND);
+ }
+ if (xs != XST_SUCCESS) {
+ dev_err(dev,
+ "XLlTemac: Could not set RECV pkt threshold/waitbound ERROR %d",
+ xs);
+ }
+ XLlDma_mBdRingIntEnable(&lp->Dma.RxBdRing, dma_rx_int_mask);
+ }
+ else {
+ dev_err(dev,
+ "XLlTemac: using FIFO direct interrupt driven mode.\n");
+
+ virt_baddr = (u32) ioremap(pdata->ll_dev_baseaddress, 4096);
+ if (0 == virt_baddr) {
+ dev_err(dev,
+ "XLlTemac: Could not allocate iomem for local link connected device.\n");
+ rc = -EIO;
+ goto error;
+ }
+ printk("XLlTemac: Fifo base address: 0x%0x\n", virt_baddr);
+ XLlFifo_Initialize(&lp->Fifo, virt_baddr);
+
+ ndev->hard_start_xmit = xenet_FifoSend;
+ }
+
+ /** Scan to find the PHY */
+ lp->gmii_addr = detect_phy(lp, ndev->name);
+
+
+ /* initialize the netdev structure */
+ ndev->open = xenet_open;
+ ndev->stop = xenet_close;
+ ndev->change_mtu = xenet_change_mtu;
+ ndev->get_stats = xenet_get_stats;
+ ndev->flags &= ~IFF_MULTICAST;
+
+ if (XLlTemac_IsDma(&lp->Emac)) {
+ ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+
+ if (XLlTemac_IsTxCsum(&lp->Emac) == TRUE) {
+ /*
+ * This hardware only supports proper checksum calculations
+ * on TCP/UDP packets.
+ */
+ ndev->features |= NETIF_F_IP_CSUM;
+ }
+ if (XLlTemac_IsRxCsum(&lp->Emac) == TRUE) {
+ lp->local_features |= LOCAL_FEATURE_RX_CSUM;
+ }
+ }
+
+ ndev->do_ioctl = xenet_ioctl;
+ ndev->tx_timeout = xenet_tx_timeout;
+ ndev->watchdog_timeo = TX_TIMEOUT;
+
+ /* init the stats */
+ lp->max_frags_in_a_packet = 0;
+ lp->tx_hw_csums = 0;
+ lp->rx_hw_csums = 0;
+
+#if ! XTE_AUTOSTRIPPING
+ lp->stripping =
+ (XLlTemac_GetOptions(&(lp->Emac)) & XTE_FCS_STRIP_OPTION) != 0;
+#endif
+
+ rc = register_netdev(ndev);
+ if (rc) {
+ dev_err(dev,
+ "%s: Cannot register net device, aborting.\n",
+ ndev->name);
+ goto error; /* rc is already set here... */
+ }
+
+ dev_info(dev,
+ "%s: Xilinx TEMAC at 0x%08X mapped to 0x%08X, irq=%d\n",
+ ndev->name,
+ r_mem->start,
+ lp->Emac.Config.BaseAddress,
+ ndev->irq);
+
+ return 0;
+
+error:
+ if (ndev) {
+ xtenet_remove_ndev(ndev);
+ }
+ return rc;
+}
+
+static int xtenet_probe(struct device *dev)
+{
+ struct resource *r_irq = NULL; /* Interrupt resources */
+ struct resource *r_mem = NULL; /* IO mem resources */
+ struct xlltemac_platform_data *pdata;
+ struct platform_device *pdev = to_platform_device(dev);
+
+ /* param check */
+ if (!pdev) {
+ dev_err(dev, "XLlTemac: Internal error. Probe called with NULL param.\n");
+ return -ENODEV;
+ }
+
+ pdata = (struct xlltemac_platform_data *) pdev->dev.platform_data;
+ if (!pdata) {
+ dev_err(dev, "xlltemac: Couldn't find platform data.\n");
+
+ return -ENODEV;
+ }
+
+ /* Get iospace and an irq for the device */
+ r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r_irq || !r_mem) {
+ dev_err(dev, "xlltemac: IO resource(s) not found.\n");
+ return -ENODEV;
+ }
+
+ return xtenet_setup(dev, r_mem, r_irq, pdata);
+}
+
+static struct device_driver xtenet_driver = {
+ .name = DRIVER_NAME,
+ .bus = &platform_bus_type,
+
+ .probe = xtenet_probe,
+ .remove = xtenet_remove
+};
+
+#ifdef CONFIG_OF
+static u32 get_u32(struct of_device *ofdev, const char *s) {
+ u32 *p = (u32 *)of_get_property(ofdev->node, s, NULL);
+ if(p) {
+ return *p;
+ } else {
+ dev_warn(&ofdev->dev, "Parameter %s not found, defaulting to false.\n", s);
+ return FALSE;
+ }
+}
+
+static int __devinit xtenet_of_probe(struct of_device *ofdev, const struct of_device_id *match)
+{
+ struct resource r_irq_struct;
+ struct resource r_mem_struct;
+ struct xlltemac_platform_data pdata_struct;
+
+ struct resource *r_irq = &r_irq_struct; /* Interrupt resources */
+ struct resource *r_mem = &r_mem_struct; /* IO mem resources */
+ struct xlltemac_platform_data *pdata = &pdata_struct;
+ int rc = 0;
+
+ printk(KERN_INFO "Device Tree Probing \'%s\'\n",
+ ofdev->node->name);
+
+ /* Get iospace for the device */
+ rc = of_address_to_resource(ofdev->node, 0, r_mem);
+ if(rc) {
+ dev_warn(&ofdev->dev, "invalid address\n");
+ return rc;
+ }
+
+ /* Get IRQ for the device */
+ rc = of_irq_to_resource(ofdev->node, 0, r_irq);
+ if(rc == NO_IRQ) {
+ dev_warn(&ofdev->dev, "no IRQ found.\n");
+ return rc;
+ }
+
+ pdata_struct.tx_csum = get_u32(ofdev, "xlnx,txcsum");
+ pdata_struct.rx_csum = get_u32(ofdev, "xlnx,rxcsum");
+ pdata_struct.phy_type = get_u32(ofdev, "xlnx,phy-type");
+ pdata_struct.ll_dev_type = get_u32(ofdev, "xlnx,llink-connected-type");
+ pdata_struct.ll_dev_baseaddress = get_u32(ofdev, "xlnx,llink-connected-baseaddr");
+ pdata_struct.ll_dev_dma_rx_irq = get_u32(ofdev, "xlnx,llink-connected-dmarx-intr");
+ pdata_struct.ll_dev_dma_tx_irq = get_u32(ofdev, "xlnx,llink-connected-dmatx-intr");
+ pdata_struct.ll_dev_fifo_irq = get_u32(ofdev, "xlnx,llink-connected-fifo-intr");
+ memcpy(pdata_struct.mac_addr, of_get_mac_address(ofdev->node), 6);
+
+ return xtenet_setup(&ofdev->dev, r_mem, r_irq, pdata);
+}
+
+static int __devexit xtenet_of_remove(struct of_device *dev)
+{
+ return xtenet_remove(&dev->dev);
+}
+
+static struct of_device_id xtenet_of_match[] = {
+ { .compatible = "xlnx,xps-ll-temac", },
+ { /* end of list */ },
+};
+
+MODULE_DEVICE_TABLE(of, xtenet_of_match);
+
+static struct of_platform_driver xtenet_of_driver = {
+ .name = DRIVER_NAME,
+ .match_table = xtenet_of_match,
+ .probe = xtenet_of_probe,
+ .remove = __devexit_p(xtenet_of_remove),
+};
+#endif
+
+static int __init xtenet_init(void)
+{
+ int status;
+
+ /*
+ * Make sure the locks are initialized
+ */
+ spin_lock_init(&XTE_spinlock);
+ spin_lock_init(&XTE_tx_spinlock);
+ spin_lock_init(&XTE_tx_spinlock);
+
+ INIT_LIST_HEAD(&sentQueue);
+ INIT_LIST_HEAD(&receivedQueue);
+
+ spin_lock_init(&sentQueueSpin);
+ spin_lock_init(&receivedQueueSpin);
+
+ /*
+ * No kernel boot options used,
+ * so we just need to register the driver
+ */
+ status = driver_register(&xtenet_driver);
+#ifdef CONFIG_OF
+ status |= of_register_platform_driver(&xtenet_of_driver);
+#endif
+ return status;
+
+}
+
+static void __exit xtenet_cleanup(void)
+{
+ driver_unregister(&xtenet_driver);
+#ifdef CONFIG_OF
+ of_unregister_platform_driver(&xtenet_of_driver);
+#endif
+}
+
+module_init(xtenet_init);
+module_exit(xtenet_cleanup);
+
+MODULE_AUTHOR("Xilinx, Inc.");
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_LICENSE("GPL");
Index: trunk/software/linux-2.6.x-petalogix/include/asm-microblaze/delay.h
===================================================================
--- trunk.orig/software/linux-2.6.x-petalogix/include/asm-microblaze/delay.h
+++ trunk/software/linux-2.6.x-petalogix/include/asm-microblaze/delay.h
@@ -11,6 +11,8 @@
#ifndef _ASM_DELAY_H
#define _ASM_DELAY_H
+#include <asm/param.h> /* For HZ */
+
extern inline void __delay(unsigned long loops)
{
asm volatile ("# __delay \n\t" \
@@ -21,8 +23,59 @@ extern inline void __delay(unsigned long
: "0" (loops));
}
-static inline void udelay(unsigned long usec)
+/*
+ * Note that 19 * 226 == 4294 ==~ 2^32 / 10^6, so
+ * loops = (4294 * usecs * loops_per_jiffy * HZ) / 2^32.
+ *
+ * The mul instruction gives us loops = (a * b) / 2^32.
+ * We choose a = usecs * 19 * HZ and b = loops_per_jiffy * 226
+ * because this lets us support a wide range of HZ and
+ * loops_per_jiffy values without either a or b overflowing 2^32.
+ * Thus we need usecs * HZ <= (2^32 - 1) / 19 = 226050910 and
+ * loops_per_jiffy <= (2^32 - 1) / 226 = 19004280
+ * (which corresponds to ~3800 bogomips at HZ = 100).
+ * -- paulus
+ */
+#define __MAX_UDELAY (226050910UL/HZ) /* maximum udelay argument */
+#define __MAX_NDELAY (4294967295UL/HZ) /* maximum ndelay argument */
+
+extern unsigned long loops_per_jiffy;
+
+extern __inline__ void __udelay(unsigned int x)
+{
+ unsigned long long tmp=(unsigned long long)x*(unsigned long long)loops_per_jiffy*226LL;
+ unsigned loops=tmp>>32;
+
+/*
+ __asm__("mulxuu %0,%1,%2" : "=r" (loops) :
+ "r" (x), "r" (loops_per_jiffy * 226));
+*/
+ __delay(loops);
+}
+
+extern __inline__ void __ndelay(unsigned int x)
{
+ unsigned long long tmp=(unsigned long long)x*(unsigned long long)loops_per_jiffy*226LL;
+ unsigned loops=tmp>>32;
+
+/*
+ __asm__("mulxuu %0,%1,%2" : "=r" (loops) :
+ "r" (x), "r" (loops_per_jiffy * 5));
+*/
+ __delay(loops);
}
+extern void __bad_udelay(void); /* deliberately undefined */
+extern void __bad_ndelay(void); /* deliberately undefined */
+
+#define udelay(n) (__builtin_constant_p(n)? \
+ ((n) > __MAX_UDELAY? __bad_udelay(): __udelay((n) * (19 * HZ))) : \
+ __udelay((n) * (19 * HZ)))
+
+#define ndelay(n) (__builtin_constant_p(n)? \
+ ((n) > __MAX_NDELAY? __bad_ndelay(): __ndelay((n) * HZ)) : \
+ __ndelay((n) * HZ))
+
+#define muldiv(a, b, c) (((a)*(b))/(c))
+
#endif /* _ASM_DELAY_H */
Index: trunk/software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile
===================================================================
--- trunk.orig/software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile
+++ trunk/software/linux-2.6.x-petalogix/arch/microblaze/platform/common/Makefile
@@ -11,6 +11,7 @@
# Build a local list of -y and -m driver options.
platobj-$(CONFIG_MTD_PHYSMAP) += physmap-flash.o
+platobj-$(CONFIG_XILINX_LLTEMAC) += xlltemac.o
platobj-$(CONFIG_XILINX_GPIO) += xgpio.o
platobj-$(CONFIG_XILINX_SPI) += xspi.o
platobj-$(CONFIG_SERIAL_UARTLITE) += xuartlite.o
@@ -28,6 +29,7 @@ obj-y += $(platobj-y) $(platobj-m)
$(obj)/built-in.o: .config
$(obj)/xsysace.o: .config
$(obj)/xuartlite.o: .config
+$(obj)/xlltemac.o: .config
$(obj)/x16550.o: .config
$(obj)/xgpio.o: .config
$(obj)/xspi.o: .config