libchip: Add dwmac 10/100/1000 network driver

This commit is contained in:
Ralf Kirchner
2014-03-13 16:21:55 +01:00
committed by Sebastian Huber
parent bbc5527010
commit 4953b72490
16 changed files with 6540 additions and 1 deletions
+10 -1
View File
@@ -44,11 +44,20 @@ libnetchip_a_SOURCES = network/cs8900.c network/dec21140.c network/i82586.c \
libnetchip_a_SOURCES += network/greth.c
include_libchip_HEADERS += network/smc91111.h network/smc91111exp.h
libnetchip_a_SOURCES += network/smc91111.c network/smc91111config.h
include_libchip_HEADERS += network/dwmac.h
libnetchip_a_SOURCES += \
network/dwmac-1000-core.c \
network/dwmac-1000-dma.c \
network/dwmac-1000-ethernet-mac-ops.c \
network/dwmac-core.c \
network/dwmac-desc-com.c \
network/dwmac-desc-enh.c \
network/dwmac.c
endif
EXTRA_DIST += network/README network/README.cs8900 network/README.dec21140 \
network/README.i82586 network/README.open_eth network/README.sonic \
network/cs8900.c.bsp network/README.tulipclone
network/cs8900.c.bsp network/README.tulipclone network/README.dwmac
# rtc
include_libchip_HEADERS += rtc/rtc.h rtc/icm7170.h rtc/m48t08.h \
+25
View File
@@ -0,0 +1,25 @@
About
=====
The dwmac* files implement libchip driver for the DWMAC 10/100/1000
ethernet MAC. The DWMAC 10/100/1000 ethernet MAC is a Synopsys IP core.
Target Support
==============
The target is required to provide the low level support routines as
listed in the Configuration section of this file.
The file cs8900.[ch].bsp are an example BSP files for DIMMPC target.
Conditionals
============
None
Todo
====
+ Add support for DWMAC 10/100. currently only support for DWMAC 1000
is implemented
Configuration
=============
See the dwmac.h header file for the documentation.
+238
View File
@@ -0,0 +1,238 @@
/**
* @file
*
* @brief DWMAC 1000 on-chip Ethernet controllers Core Handling
*
* Functions and data which are specific to the DWMAC 1000 Core Handling.
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <assert.h>
#include "dwmac-core.h"
#include "dwmac-common.h"
#define DWMAC_1000_CORE_DEBUG
//#undef DWMAC_1000_CORE_DEBUG
#ifdef DWMAC_1000_CORE_DEBUG
#define DWMAC_1000_CORE_PRINT_DBG( fmt, args ... ) printk( fmt, ## args )
#else
#define DWMAC_1000_CORE_PRINT_DBG( fmt, args ... ) do { } while ( 0 )
#endif
#define DWMAC_1000_CORE_INIT \
( \
( MACGRP_MAC_CONFIGURATION_JD \
| MACGRP_MAC_CONFIGURATION_BE ) \
& ~MACGRP_MAC_CONFIGURATION_PS \
)
#define DWMAC_1000_CORE_HASH_TABLE_SIZE 256
static volatile uint32_t *dwmac_1000_core_get_mac_addr_low(
dwmac_common_context *self,
const unsigned int mac_addr_index )
{
volatile uint32_t *addr = NULL;
assert( self != NULL );
assert( mac_addr_index <= 127 );
if ( mac_addr_index > 15 ) {
addr = &self->macgrp->mac_addr16_127[mac_addr_index].low;
} else {
addr = &self->macgrp->mac_addr0_15[mac_addr_index].low;
}
return addr;
}
static volatile uint32_t *dwmac_1000_core_get_mac_addr_high(
dwmac_common_context *self,
const unsigned int mac_addr_index )
{
volatile uint32_t *addr = NULL;
assert( self != NULL );
assert( mac_addr_index <= 127 );
if ( mac_addr_index > 15 ) {
addr = &self->macgrp->mac_addr16_127[mac_addr_index].high;
} else {
addr = &self->macgrp->mac_addr0_15[mac_addr_index].high;
}
return addr;
}
static void dwmac_1000_core_init( dwmac_common_context *self )
{
uint32_t value = self->macgrp->mac_configuration;
value |= DWMAC_1000_CORE_INIT;
if ( ( self->dmagrp->hw_feature & DMAGRP_HW_FEATURE_RXTYP1COE ) != 0
|| ( self->dmagrp->hw_feature & DMAGRP_HW_FEATURE_RXTYP2COE ) != 0 ) {
/* Enable RX checksum calculation offload to hardware */
value |= MACGRP_MAC_CONFIGURATION_IPC;
}
/* No Jumbo- or Giant frames. The network stack does not support them */
value &= ~MACGRP_MAC_CONFIGURATION_JE;
value &= ~MACGRP_MAC_CONFIGURATION_TWOKPE;
self->macgrp->mac_configuration = value;
/* Mask GMAC interrupts */
self->macgrp->interrupt_mask =
MACGRP_INTERRUPT_MASK_RGSMIIIM
| MACGRP_INTERRUPT_MASK_PCSLCHGIM
| MACGRP_INTERRUPT_MASK_PCSANCIM
| MACGRP_INTERRUPT_MASK_TSIM;
/* mask out interrupts because we don't handle them yet */
self->macgrp->mmc_receive_interrupt_mask = ( uint32_t ) ~0L;
self->macgrp->mmc_transmit_interrupt_mask = ( uint32_t ) ~0L;
self->macgrp->mmc_ipc_receive_interrupt_mask = ( uint32_t ) ~0L;
}
static void dwmac_1000_core_set_umac_addr(
dwmac_common_context *self,
const uint8_t *addr,
unsigned int reg_n )
{
dwmac_core_set_mac_addr(
addr,
dwmac_1000_core_get_mac_addr_high( self, reg_n ),
dwmac_1000_core_get_mac_addr_low( self, reg_n )
);
}
static void dwmac_1000_core_set_hash_filter(
dwmac_common_context *self,
const bool add,
struct ifreq *ifr )
{
int eno = 0;
struct arpcom *ac = &self->arpcom;
if ( add ) {
eno = ether_addmulti( ifr, ac );
} else {
eno = ether_delmulti( ifr, ac );
}
if ( eno == ENETRESET ) {
struct ether_multistep step;
struct ether_multi *enm;
unsigned int num_multi = 0;
unsigned int index;
ETHER_FIRST_MULTI( step, ac, enm );
while ( enm != NULL ) {
/* Find out how many multicast addresses we have to handle */
uint64_t addrlo = 0;
uint64_t addrhi = 0;
memcpy( &addrlo, enm->enm_addrlo, ETHER_ADDR_LEN );
memcpy( &addrhi, enm->enm_addrhi, ETHER_ADDR_LEN );
num_multi += 1U + (uint32_t) ( addrhi - addrlo );
}
if ( num_multi > DWMAC_1000_CORE_HASH_TABLE_SIZE ) {
/* Too many addresses to be hashed, Use the
* pass all multi option instead */
for ( index = 0; index < 8; ++index ) {
self->macgrp->hash_table_reg[index] = 0xffffffff;
}
self->macgrp->mac_frame_filter |= MACGRP_MAC_FRAME_FILTER_PM;
} else if ( num_multi > 0 ) {
uint32_t hash_shadow[8] = {0, 0, 0, 0, 0, 0, 0, 0};
ETHER_FIRST_MULTI( step, ac, enm );
while ( enm != NULL ) {
uint64_t addrlo = 0;
uint64_t addrhi = 0;
memcpy( &addrlo, enm->enm_addrlo, ETHER_ADDR_LEN );
memcpy( &addrhi, enm->enm_addrhi, ETHER_ADDR_LEN );
while ( addrlo <= addrhi ) {
/* XXX: ether_crc32_le() does not work, why? */
uint32_t crc = ether_crc32_be( (uint8_t *) &addrlo, ETHER_ADDR_LEN );
/* The upper 8 bits of the bit reversed 32 bit CRC are used for hash filtering.
* The most significant bits determine the register to be used and the
* least significant five bits determine which bit to be set within the register */
uint32_t index_reg = ( crc >> 29 ) & 0x7;
uint32_t index_bit = ( crc >> 24 ) & 0x1f;
hash_shadow[index_reg] |= 1U << index_bit;
++addrlo;
}
ETHER_NEXT_MULTI( step, enm );
}
for ( index = 0; index < 8; ++index ) {
self->macgrp->hash_table_reg[index] = hash_shadow[index];
}
/* Hash filter for multicast */
self->macgrp->mac_frame_filter |= MACGRP_MAC_FRAME_FILTER_HMC;
} else {
/* Set all hash registers to accect to accept no multicast packets */
for ( index = 0; index < 8; ++index ) {
self->macgrp->hash_table_reg[index] = 0x00000000;
}
/* Hash filter for multicast */
self->macgrp->mac_frame_filter |= MACGRP_MAC_FRAME_FILTER_HMC;
}
DWMAC_1000_CORE_PRINT_DBG(
"Frame Filter reg: 0x%08x\n",
self->macgrp->mac_frame_filter
);
DWMAC_1000_CORE_PRINT_DBG(
"Hash regs:\n"
"0x%08x\n"
"0x%08x\n"
"0x%08x\n"
"0x%08x\n"
"0x%08x\n"
"0x%08x\n"
"0x%08x\n"
"0x%08x\n",
self->macgrp->hash_table_reg[0],
self->macgrp->hash_table_reg[1],
self->macgrp->hash_table_reg[2],
self->macgrp->hash_table_reg[3],
self->macgrp->hash_table_reg[4],
self->macgrp->hash_table_reg[5],
self->macgrp->hash_table_reg[6],
self->macgrp->hash_table_reg[7]
);
}
}
const dwmac_common_core_ops dwmac_core_ops_1000 = {
.core_init = dwmac_1000_core_init,
.set_hash_filter = dwmac_1000_core_set_hash_filter,
.set_umac_addr = dwmac_1000_core_set_umac_addr,
};
+244
View File
@@ -0,0 +1,244 @@
/**
* @file
*
* @brief DWMAC 1000 on-chip Ethernet controllers DMA handling
*
* Functions and data which are specific to the DWMAC 1000 DMA Handling.
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <errno.h>
#include "dwmac-core.h"
#include "dwmac-common.h"
typedef enum {
DWMAC100_OPERATION_MODE_TTC_CONTROL_64 = 0x00000000,
DWMAC100_OPERATION_MODE_TTC_CONTROL_128 = 0x00004000,
DWMAC100_OPERATION_MODE_TTC_CONTROL_192 = 0x00008000,
DWMAC100_OPERATION_MODE_TTC_CONTROL_256 = 0x0000c000,
DWMAC100_OPERATION_MODE_TTC_CONTROL_40 = 0x00010000,
DWMAC100_OPERATION_MODE_TTC_CONTROL_32 = 0x00014000,
DWMAC100_OPERATION_MODE_TTC_CONTROL_24 = 0x00018000,
DWMAC100_OPERATION_MODE_TTC_CONTROL_16 = 0x0001c000,
} dwmac1000_operation_mode_ttc_control;
typedef enum {
DWMAC100_OPERATION_MODE_RTC_CONTROL_64 = 0x00000000,
DWMAC100_OPERATION_MODE_RTC_CONTROL_32 = 0x00000008,
DWMAC100_OPERATION_MODE_RTC_CONTROL_96 = 0x00000010,
DWMAC100_OPERATION_MODE_RTC_CONTROL_128 = 0x00000018,
} dwmac1000_operation_mode_rtc_control;
static int dwmac1000_dma_init(
dwmac_common_context *self,
const uint32_t pbl,
const uint32_t fb,
const uint32_t mb,
const bool use_enhanced_desc,
const uint32_t burst_len_4_support,
const uint32_t burst_len_8_support,
const uint32_t burst_len_16_support,
const uint32_t burst_boundary,
volatile dwmac_desc *dma_tx,
volatile dwmac_desc *dma_rx )
{
int eno = 0;
uint32_t value = self->dmagrp->bus_mode;
int limit = 10;
/* DMA SW reset */
value |= DMAGRP_BUS_MODE_SWR;
self->dmagrp->bus_mode = value;
while ( limit-- ) {
if ( !( self->dmagrp->bus_mode & DMAGRP_BUS_MODE_SWR ) )
break;
rtems_task_wake_after( rtems_clock_get_ticks_per_second() / 100 );
}
if ( limit < 0 ) {
eno = EBUSY;
} else {
/*
* Set the DMA PBL (Programmable Burst Length) mode
*/
if ( pbl >= DWMAC_DMA_CFG_BUS_MODE_BURST_LENGTH_8 ) {
value =
DMAGRP_BUS_MODE_PBL( ( pbl + 1 ) / 8 ) | DMAGRP_BUS_MODE_RPBL(
( pbl + 1 ) / 8 ) | DMAGRP_BUS_MODE_EIGHTXPBL;
} else {
value = DMAGRP_BUS_MODE_PBL( pbl + 1 ) | DMAGRP_BUS_MODE_RPBL( pbl + 1 );
}
/* Set the Fixed burst mode */
if ( fb ) {
value |= DMAGRP_BUS_MODE_FB;
}
/* Mixed Burst has no effect when fb is set */
if ( mb ) {
value |= DMAGRP_BUS_MODE_MB;
}
if ( use_enhanced_desc ) {
value |= DMAGRP_BUS_MODE_ATDS;
}
self->dmagrp->bus_mode = value;
/* In case of GMAC AXI configuration, program the DMA_AXI_BUS_MODE
* for supported bursts.
*
* Note: This is applicable only for revision GMACv3.61a. For
* older version this register is reserved and shall have no
* effect.
*
* Note:
* For Fixed Burst Mode: if we directly write 0xFF to this
* register using the configurations pass from platform code,
* this would ensure that all bursts supported by core are set
* and those which are not supported would remain ineffective.
*
* For Non Fixed Burst Mode: provide the maximum value of the
* burst length. Any burst equal or below the provided burst
* length would be allowed to perform. */
value = self->dmagrp->axi_bus_mode;
if ( burst_len_4_support ) {
value |= DMAGRP_AXI_BUS_MODE_BLEND4;
} else {
value &= ~DMAGRP_AXI_BUS_MODE_BLEND4;
}
if ( burst_len_8_support ) {
value |= DMAGRP_AXI_BUS_MODE_BLEND8;
} else {
value &= ~DMAGRP_AXI_BUS_MODE_BLEND8;
}
if ( burst_len_16_support ) {
value |= DMAGRP_AXI_BUS_MODE_BLEND16;
} else {
value &= ~DMAGRP_AXI_BUS_MODE_BLEND16;
}
if ( burst_boundary ) {
value |= DMAGRP_AXI_BUS_MODE_ONEKBBE;
} else {
value &= ~DMAGRP_AXI_BUS_MODE_ONEKBBE;
}
self->dmagrp->axi_bus_mode = value;
/* Mask interrupts by writing to CSR7 */
dwmac_core_enable_dma_irq_rx( self );
dwmac_core_enable_dma_irq_tx( self );
/* The base address of the RX/TX descriptor lists must be written into
* DMA CSR3 and CSR4, respectively. */
self->dmagrp->transmit_descr_list_addr = (uintptr_t) &dma_tx[0];
self->dmagrp->receive_descr_list_addr = (uintptr_t) &dma_rx[0];
}
return eno;
}
static void dwmac1000_dma_operation_mode(
dwmac_common_context *self,
const unsigned int txmode,
const unsigned int rxmode )
{
uint32_t value = self->dmagrp->operation_mode;
if ( txmode == DWMAC_COMMON_DMA_MODE_STORE_AND_FORWARD ) {
/* Transmit COE type 2 cannot be done in cut-through mode. */
value |= DMAGRP_OPERATION_MODE_TSF;
/* Operating on second frame increase the performance
* especially when transmit store-and-forward is used.*/
value |= DMAGRP_OPERATION_MODE_OSF;
} else {
value &= ~DMAGRP_OPERATION_MODE_TSF;
value &= ~DMAGRP_OPERATION_MODE_TTC_GET( value );
/* Set the transmit threshold */
if ( txmode <= 32 ) {
value |= DMAGRP_OPERATION_MODE_TTC_SET(
value,
DWMAC100_OPERATION_MODE_TTC_CONTROL_32
);
} else if ( txmode <= 64 ) {
value = DMAGRP_OPERATION_MODE_TTC_SET(
value,
DWMAC100_OPERATION_MODE_TTC_CONTROL_64
);
} else if ( txmode <= 128 ) {
value = DMAGRP_OPERATION_MODE_TTC_SET(
value,
DWMAC100_OPERATION_MODE_TTC_CONTROL_128
);
} else if ( txmode <= 192 ) {
value = DMAGRP_OPERATION_MODE_TTC_SET(
value,
DWMAC100_OPERATION_MODE_TTC_CONTROL_192
);
} else {
value = DMAGRP_OPERATION_MODE_TTC_SET(
value,
DWMAC100_OPERATION_MODE_TTC_CONTROL_256
);
}
}
if ( rxmode == DWMAC_COMMON_DMA_MODE_STORE_AND_FORWARD ) {
value |= DMAGRP_OPERATION_MODE_RSF;
} else {
value &= ~DMAGRP_OPERATION_MODE_RSF;
value &= DMAGRP_OPERATION_MODE_RTC_GET( value );
if ( rxmode <= 32 ) {
value = DMAGRP_OPERATION_MODE_RTC_SET(
value,
DWMAC100_OPERATION_MODE_RTC_CONTROL_32
);
} else if ( rxmode <= 64 ) {
value = DMAGRP_OPERATION_MODE_RTC_SET(
value,
DWMAC100_OPERATION_MODE_RTC_CONTROL_64
);
} else if ( rxmode <= 96 ) {
value = DMAGRP_OPERATION_MODE_RTC_SET(
value,
DWMAC100_OPERATION_MODE_RTC_CONTROL_96
);
} else {
value = DMAGRP_OPERATION_MODE_RTC_SET(
value,
DWMAC100_OPERATION_MODE_RTC_CONTROL_128
);
}
}
self->dmagrp->operation_mode = value;
}
const dwmac_common_dma_ops dwmac_dma_ops_1000 = {
.init = dwmac1000_dma_init,
.dma_mode = dwmac1000_dma_operation_mode,
};
@@ -0,0 +1,33 @@
/**
* @file
*
* @brief Operations for the dwmac 1000 ethernet mac
*
* DWMAC_1000_ETHERNET_MAC_OPS will be accessible in the API header and can be
* passed to the configuration data if handling a DWMAC 1000 driver
*/
/*
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include "dwmac-common.h"
extern const dwmac_common_dma_ops dwmac_dma_ops_1000;
extern const dwmac_common_core_ops dwmac_core_ops_1000;
const dwmac_ethernet_mac_ops DWMAC_1000_ETHERNET_MAC_OPS =
DWMAC_ETHERNET_MAC_OPS_INITIALIZER(
&dwmac_core_ops_1000,
&dwmac_dma_ops_1000
);
+374
View File
@@ -0,0 +1,374 @@
/**
* @file
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems./license/LICENSE.
*/
#ifndef DWMAC_COMMON_H_
#define DWMAC_COMMON_H_
#define __INSIDE_RTEMS_BSD_TCPIP_STACK__ 1
#define __BSD_VISIBLE 1
#include <stdint.h>
#include <rtems.h>
#include <rtems/rtems_bsdnet.h>
#include <rtems/rtems_mii_ioctl.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <libchip/dwmac.h>
#include "dwmac-desc.h"
#include "dwmac-regs.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DWMAC_COMMON_DMA_MODE_STORE_AND_FORWARD 1 /* DMA STORE-AND-FORWARD Operation Mode */
/* Events */
/* Common task events */
#define DWMAC_COMMON_EVENT_TASK_INIT RTEMS_EVENT_1
#define DWMAC_COMMON_EVENT_TASK_STOP RTEMS_EVENT_2
/* Events for the transmit task */
#define DWMAC_COMMON_EVENT_TX_TRANSMIT_FRAME RTEMS_EVENT_3
#define DWMAC_COMMON_EVENT_TX_FRAME_TRANSMITTED RTEMS_EVENT_4
#define DWMAC_COMMON_EVENT_TX_BUMP_UP_DMA_THRESHOLD RTEMS_EVENT_5
#define DWMAC_COMMON_EVENT_TX_PHY_STATUS_CHANGE RTEMS_EVENT_6
/* Events for the receive task */
#define DWMAC_COMMON_EVENT_RX_FRAME_RECEIVED RTEMS_EVENT_3
#ifdef __ARM_ARCH_7A__
#define DWMAC_COMMON_DSB() _ARM_Data_synchronization_barrier()
#else /* __ARM_ARCH_7A__ */
#define DWMAC_COMMON_DSB()
#endif /* __ARM_ARCH_7A__ */
/* Foreward declarations */
typedef struct dwmac_common_core_ops dwmac_common_core_ops;
typedef struct dwmac_common_dma_ops dwmac_common_dma_ops;
typedef struct dwmac_common_desc_ops dwmac_common_desc_ops;
typedef enum { /* IPC status */
DWMAC_COMMON_RX_FRAME_STATUS_GOOD,
DWMAC_COMMON_RX_FRAME_STATUS_DISCARD,
DWMAC_COMMON_RX_FRAME_STATUS_CSUM_NONE,
DWMAC_COMMON_RX_FRAME_STATUS_LLC_SNAP
} dwmac_common_rx_frame_status;
typedef enum {
DWMAC_COMMON_STATE_DOWN,
DWMAC_COMMON_STATE_UP,
DWMAC_COMMON_STATE_COUNT
} dwmac_common_state;
typedef struct {
uint32_t link_down;
uint32_t link_up;
} dwmac_common_phy_status_counts;
typedef struct {
uint32_t receive;
uint32_t transmit;
uint32_t tx_underflow;
uint32_t tx_jabber;
uint32_t rx_overflow;
uint32_t rx_early;
uint32_t rx_buf_unav;
uint32_t rx_process_stopped;
uint32_t rx_watchdog;
uint32_t tx_early;
uint32_t tx_buf_unav;
uint32_t tx_process_stopped;
uint32_t fatal_bus_error;
uint32_t unhandled;
} dwmac_common_dma_irq_counts;
typedef struct {
uint32_t dest_addr_fail; /* When set, this bit indicates a frame that failed in the DA Filter in the MAC. */
uint32_t crc_error; /* When set, this bit indicates that a CRC error occurred on the received frame. This field is valid only when the Last
Descriptor (RDES0[8]) is set. */
uint32_t receive_error; /* When set, this bit indicates that the gmii_rxer_i signal is asserted while gmii_rxdv_i is asserted during frame
reception. Error can be of less or no extension, or error (rxd !=0xf) during extension. */
uint32_t watchdog_timeout; /* When set, this bit indicates that the receive Watchdog Timer has expired while receiving the current frame and the
current frame is truncated after the Watchdog Timeout. */
uint32_t late_collision; /* When set, this bit indicates that a late collision has occurred while receiving the frame in the half-duplex mode. */
uint32_t giant_frame; /* When advanced timestamp feature is present, when set, this bit indicates that a snapshot of the Timestamp is
written in descriptor words 6 (RDES6) and 7 (RDES7). This is valid only when the Last Descriptor bit (RDES0[8]) is
set.
When IP Checksum Engine (Type 1) is selected, this bit, when set, indicates that the 16-bit IPv4 Header checksum
calculated by the EMAC did not match the received checksum bytes.
Otherwise, this bit, when set, indicates the Giant frame Status. Giant frames are larger than 1,518-byte (or
1,522-byte for VLAN or 2,000-byte when Bit 27 (2KPE) of MAC Configuration register is set) normal frames and
larger than 9,018-byte (9,022-byte for VLAN) frame when Jumbo frame processing is enabled. */
uint32_t overflow_error; /* When set, this bit indicates that the received frame was damaged because of buffer overflow in MTL.
Note: This bit is set only when the DMA transfers a partial frame to the application. This happens only when the RX
FIFO buffer is operating in the threshold mode. In the store-and-forward mode, all partial frames are dropped
completely in RX FIFO buffer. */
uint32_t descriptor_error; /* When set, this bit indicates a frame truncation caused by a frame that does not fit within the current descriptor
buffers, and that the DMA does not own the Next descriptor. The frame is truncated. This field is valid only when the
Last Descriptor (RDES0[8]) is set. */
uint32_t source_addr_fail; /* When set, this bit indicates that the SA field of frame failed the SA Filter in the MAC. */
uint32_t length_error; /* When set, this bit indicates that the actual length of the frame received and that the Length/ Type field does not
match. This bit is valid only when the Frame Type (RDES0[5]) bit is reset. */
uint32_t vlan_tag; /* When set, this bit indicates that the frame to which this descriptor is pointing is a VLAN frame tagged by the MAC.
The VLAN tagging depends on checking the VLAN fields of received frame based on the Register 7 (VLAN Tag
Register) setting. */
uint32_t ethernet_frames; /* When set, this bit indicates that the receive frame is an Ethernet-type frame (the LT field is greater than or equal to
0x0600). When this bit is reset, it indicates that the received frame is an IEEE802.3 frame. This bit is not valid for
Runt frames less than 14 bytes. */
uint32_t dribble_bit_error; /* When set, this bit indicates that the received frame has a non-integer multiple of bytes (odd nibbles). This bit is valid
only in the MII Mode. */
} dwmac_common_desc_status_counts_rx;
typedef struct {
uint32_t jabber; /* When set, this bit indicates the MAC transmitter has experienced a jabber time-out. This bit is only set when Bit 22
(Jabber Disable) of Register 0 (MAC Configuration Register) is not set. */
uint32_t frame_flushed; /* When set, this bit indicates that the DMA or MTL flushed the frame because of a software Flush command given by
the CPU. */
uint32_t losscarrier; /* When set, this bit indicates that a loss of carrier occurred during frame transmission (that is, the gmii_crs_i
signal was inactive for one or more transmit clock periods during frame transmission). This is valid only for the
frames transmitted without collision when the MAC operates in the half-duplex mode. */
uint32_t no_carrier; /* When set, this bit indicates that the Carrier Sense signal form the PHY was not asserted during transmission. */
uint32_t excessive_collisions; /* When set, this bit indicates that the transmission was aborted after 16 successive collisions while attempting to
transmit the current frame. If Bit 9 (Disable Retry) bit in the Register 0 (MAC Configuration Register) is set, this bit
is set after the first collision, and the transmission of the frame is aborted. */
uint32_t excessive_deferral; /* When set, this bit indicates that the transmission has ended because of excessive deferral of over 24,288 bit times
(155,680 bits times in 1,000-Mbps mode or if Jumbo frame is enabled) if Bit 4 (Deferral Check) bit in Register 0
(MAC Configuration Register) is set high. */
uint32_t underflow; /* When set, this bit indicates that the MAC aborted the frame because the data arrived late from the Host memory.
Underflow Error indicates that the DMA encountered an empty transmit buffer while transmitting the frame. The
transmission process enters the Suspended state and sets both Transmit Underflow (Register 5[5]) and Transmit
Interrupt (Register 5[0]). */
uint32_t ip_header_error; /* When set, this bit indicates that the MAC transmitter detected an error in the IP datagram header. The transmitter
checks the header length in the IPv4 packet against the number of header bytes received from the application and
indicates an error status if there is a mismatch. For IPv6 frames, a header error is reported if the main header length
is not 40 bytes. Furthermore, the Ethernet Length/Type field value for an IPv4 or IPv6 frame must match the IP
header version received with the packet. For IPv4 frames, an error status is also indicated if the Header Length field
has a value less than 0x5. */
uint32_t payload_error; /* When set, this bit indicates that MAC transmitter detected an error in the TCP, UDP, or ICMP IP datagram payload.
The transmitter checks the payload length received in the IPv4 or IPv6 header against the actual number of TCP,
UDP, or ICMP packet bytes received from the application and issues an error status in case of a mismatch. */
uint32_t deferred; /* When set, this bit indicates that the MAC defers before transmission because of the presence of carrier. This bit is
valid only in the half-duplex mode. */
uint32_t vlan; /* When set, this bit indicates that the transmitted frame is a VLAN-type frame. */
} dwmac_common_desc_status_counts_tx;
typedef struct {
uint32_t errors; /* Frames with errors */
uint32_t dropped; /* Frames dropped */
uint32_t frames_good; /* Frames passed to the network stack */
uint32_t bytes_good; /* Sum of bytes passed to the network stack */
uint32_t frames; /* Frames handled (good or bad) */
uint32_t dma_suspended; /* The receive DMA was supended due to lack of descriptors */
} dwmac_common_rx_frame_counts;
typedef struct {
uint32_t frames_from_stack; /* Frames received from the network stack fro tranmission */
uint32_t frames_to_dma; /* Number of frames transmitted to DMA */
uint32_t packets_to_dma; /* Number of packets transmitted to DMA*/
uint32_t bytes_to_dma; /* Number of bytes transmitted */
uint32_t packet_errors; /* Packets with errors */
uint32_t packets_tranmitted_by_DMA; /* Packets tranmitted by the DMA */
} dwmac_common_tx_frame_counts;
typedef struct {
dwmac_common_phy_status_counts phy_status_counts;
dwmac_common_dma_irq_counts dma_irq_counts;
dwmac_common_desc_status_counts_rx desc_status_counts_rx;
dwmac_common_desc_status_counts_tx desc_status_counts_tx;
dwmac_common_rx_frame_counts frame_counts_rx;
dwmac_common_tx_frame_counts frame_counts_tx;
} dwmac_common_stats;
typedef struct {
struct arpcom arpcom;
struct rtems_bsdnet_ifconfig *bsd_config;
struct rtems_mdio_info mdio;
rtems_id task_id_rx;
rtems_id task_id_tx;
rtems_id task_id_control;
void *arg;
volatile macgrp *macgrp;
volatile dmagrp *dmagrp;
unsigned int csr_clock;
dwmac_common_state state;
dwmac_common_stats stats;
unsigned int dma_threshold_control;
volatile dwmac_desc *dma_tx;
volatile dwmac_desc *dma_rx;
unsigned int idx_rx;
struct mbuf **mbuf_addr_rx;
struct mbuf **mbuf_addr_tx;
const dwmac_cfg *CFG;
} dwmac_common_context;
struct dwmac_common_core_ops {
/* MAC core initialization */
void (*core_init) ( dwmac_common_context *self );
/* Multicast filter setting */
void (*set_hash_filter) (
dwmac_common_context *self,
const bool add,
struct ifreq *ifr );
/* Set/Get Unicast MAC addresses */
void (*set_umac_addr) (
dwmac_common_context *ioaddr,
const unsigned char *addr,
const unsigned int reg_n );
};
struct dwmac_common_dma_ops {
/* DMA core initialization */
int (*init) (
dwmac_common_context *self,
const uint32_t pbl,
const uint32_t fb,
const uint32_t mb,
const bool use_enhanced_desc,
const uint32_t burst_len_4_support,
const uint32_t burst_len_8_support,
const uint32_t burst_len_16_support,
const uint32_t burst_boundary,
volatile dwmac_desc *dma_tx,
volatile dwmac_desc *dma_rx );
/* Set tx/rx threshold in the csr6 register
* An invalid value enables the store-and-forward mode */
void (*dma_mode) (
dwmac_common_context *self,
const unsigned int txmode,
const unsigned int rxmode );
};
struct dwmac_common_desc_ops {
/* Verify that it is OK to use the selected descriptor operations */
int (*validate) ( dwmac_common_context *self );
bool (*use_enhanced_descs) ( dwmac_common_context *self );
/* DMA RX descriptor ring allocation */
int (*create_rx_desc) ( dwmac_common_context *self );
/* DMA TX descriptor ring allocation */
int (*create_tx_desc) ( dwmac_common_context *self );
/* Free DMA RX descriptor ring */
int (*destroy_rx_desc) ( dwmac_common_context *self );
/* Free DMA TX descriptor ring */
int (*destroy_tx_desc) ( dwmac_common_context *self );
/* DMA RX descriptor initialization */
void (*init_rx_desc) (
dwmac_common_context *self,
const unsigned int index );
/* DMA TX descriptor ring initialization */
void (*init_tx_desc) ( dwmac_common_context *self );
/* Free rx data buffers */
void (*release_rx_bufs) ( dwmac_common_context *self );
/* Allocate a data buffer */
struct mbuf *(*alloc_data_buf)( dwmac_common_context *self );
/* Free tx data buffers */
void (*release_tx_bufs) ( dwmac_common_context *self );
/* Invoked by the xmit function to prepare the tx descriptor */
void (*prepare_tx_desc) (
dwmac_common_context *self,
const unsigned int idx,
const bool is_first,
const size_t len,
const void *pdata );
/* Set/get the owner of the descriptor */
void (*release_tx_ownership) (
dwmac_common_context *self,
const unsigned int idx_tx );
bool (*am_i_tx_owner) (
dwmac_common_context *self,
const unsigned int idx_tx );
/* Invoked by the xmit function to close the tx descriptor */
void (*close_tx_desc) (
dwmac_common_context *self,
const unsigned int idx_tx );
/* Clean the tx descriptor as soon as the tx irq is received */
void (*release_tx_desc) (
dwmac_common_context *self,
const unsigned int idx_tx );
/* Last tx segment reports the transmit status */
int (*get_tx_ls) (
dwmac_common_context *self,
const unsigned int idx_tx );
/* Return the transmit status looking at the TDES1 */
int (*tx_status) (
dwmac_common_context *self,
const unsigned int idx_tx );
/* Handle extra events on specific interrupts hw dependent */
bool (*am_i_rx_owner) (
dwmac_common_context *self,
const unsigned int desc_idx );
/* Get the receive frame size */
size_t (*get_rx_frame_len) (
dwmac_common_context *self,
const unsigned int desc_idx );
/* Return the reception status looking at the RDES1 */
dwmac_common_rx_frame_status (*rx_status) (
dwmac_common_context *self,
const unsigned int desc_idx );
bool (*is_first_rx_segment) (
dwmac_common_context *self,
const unsigned int descriptor_index );
bool (*is_last_rx_segment) (
dwmac_common_context *self,
const unsigned int descriptor_index );
void (*print_tx_desc) (
volatile dwmac_desc *p,
const unsigned int count );
void (*print_rx_desc) (
volatile dwmac_desc *p,
const unsigned int count );
};
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DWMAC_COMMON_H_ */
+406
View File
@@ -0,0 +1,406 @@
/**
* @file
*
* @brief DWMAC 10/100/1000 Network Interface Controllers Core Handling
*
* DWMAC 10/100/1000 on-chip Synopsys IP Ethernet controllers.
* Driver core handling.
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include "dwmac-core.h"
#include "dwmac-common.h"
#include "dwmac-regs.h"
#undef DWMAC_CORE_DEBUG
#ifdef DWMAC_CORE_DEBUG
#define DWMAC_CORE_PRINT_DBG( fmt, args ... ) printk( fmt, ## args )
#else
#define DWMAC_CORE_PRINT_DBG( fmt, args ... ) do { } while ( 0 )
#endif
/* DMA default interrupt masks */
#define DWMAC_CORE_INTR_ENABLE_DEFAULT_MASK_RX \
( \
DMAGRP_INTERRUPT_ENABLE_NIE \
| DMAGRP_INTERRUPT_ENABLE_RIE \
)
#define DWMAC_CORE_INTR_ENABLE_DEFAULT_MASK_TX \
( \
DMAGRP_INTERRUPT_ENABLE_NIE \
| DMAGRP_INTERRUPT_ENABLE_TIE \
| DMAGRP_INTERRUPT_ENABLE_FBE \
| DMAGRP_INTERRUPT_ENABLE_UNE \
| DMAGRP_INTERRUPT_ENABLE_AIE \
)
#define DWMAC_CORE_INTR_STATUS_DEFAULT_MASK_RX \
( \
DMAGRP_STATUS_NIS \
| DMAGRP_STATUS_RI \
)
#define DWMAC_CORE_INTR_STATUS_DEFAULT_MASK_TX \
( \
DMAGRP_STATUS_NIS \
| DMAGRP_STATUS_TI \
| DMAGRP_STATUS_FBI \
| DMAGRP_STATUS_UNF \
| DMAGRP_STATUS_AIS \
)
/* CSR1 enables the transmit DMA to check for new descriptor */
void dwmac_core_dma_restart_tx( dwmac_common_context *self )
{
self->dmagrp->transmit_poll_demand = 1;
}
void dwmac_core_enable_dma_irq_tx( dwmac_common_context *self )
{
self->dmagrp->interrupt_enable |= DWMAC_CORE_INTR_ENABLE_DEFAULT_MASK_TX;
}
void dwmac_core_enable_dma_irq_rx( dwmac_common_context *self )
{
self->dmagrp->interrupt_enable |= DWMAC_CORE_INTR_ENABLE_DEFAULT_MASK_RX;
}
void dwmac_core_disable_dma_irq_tx( dwmac_common_context *self )
{
self->dmagrp->interrupt_enable &= ~DWMAC_CORE_INTR_ENABLE_DEFAULT_MASK_TX;
}
void dwmac_core_reset_dma_irq_status_tx( dwmac_common_context *self )
{
self->dmagrp->status = DWMAC_CORE_INTR_STATUS_DEFAULT_MASK_TX;
}
void dwmac_core_reset_dma_irq_status_rx( dwmac_common_context *self )
{
self->dmagrp->status = DWMAC_CORE_INTR_STATUS_DEFAULT_MASK_RX;
}
void dwmac_core_disable_dma_irq_rx( dwmac_common_context *self )
{
self->dmagrp->interrupt_enable &= ~DWMAC_CORE_INTR_ENABLE_DEFAULT_MASK_RX;
}
void dwmac_core_dma_start_tx( dwmac_common_context *self )
{
self->dmagrp->operation_mode |= DMAGRP_OPERATION_MODE_ST;
}
void dwmac_core_dma_stop_tx( dwmac_common_context *self )
{
self->dmagrp->operation_mode &= ~DMAGRP_OPERATION_MODE_ST;
}
void dwmac_core_dma_start_rx( dwmac_common_context *self )
{
self->dmagrp->operation_mode |= DMAGRP_OPERATION_MODE_SR;
}
void dwmac_core_dma_stop_rx( dwmac_common_context *self )
{
self->dmagrp->operation_mode &= ~DMAGRP_OPERATION_MODE_SR;
}
void dwmac_core_dma_restart_rx( dwmac_common_context *self )
{
self->dmagrp->receive_poll_demand = 1;
}
#ifdef DWMAC_CORE_DEBUG
static void show_tx_process_state( const uint32_t status )
{
const uint32_t STATE = DMAGRP_STATUS_TS_GET( status );
switch ( STATE ) {
case 0:
DWMAC_CORE_PRINT_DBG( "- TX (Stopped): Reset or Stop command\n" );
break;
case 1:
DWMAC_CORE_PRINT_DBG( "- TX (Running):Fetching the Tx desc\n" );
break;
case 2:
DWMAC_CORE_PRINT_DBG( "- TX (Running): Waiting for end of tx\n" );
break;
case 3:
DWMAC_CORE_PRINT_DBG( "- TX (Running): Reading the data "
"and queuing the data into the Tx buf\n" );
break;
case 6:
DWMAC_CORE_PRINT_DBG( "- TX (Suspended): Tx Buff Underflow "
"or an unavailable Transmit descriptor\n" );
break;
case 7:
DWMAC_CORE_PRINT_DBG( "- TX (Running): Closing Tx descriptor\n" );
break;
default:
break;
}
}
static void show_rx_process_state( const uint32_t status )
{
const uint32_t STATE = DMAGRP_STATUS_RS_GET( status );
switch ( STATE ) {
case 0:
DWMAC_CORE_PRINT_DBG( "- RX (Stopped): Reset or Stop command\n" );
break;
case 1:
DWMAC_CORE_PRINT_DBG( "- RX (Running): Fetching the Rx desc\n" );
break;
case 2:
DWMAC_CORE_PRINT_DBG( "- RX (Running):Checking for end of pkt\n" );
break;
case 3:
DWMAC_CORE_PRINT_DBG( "- RX (Running): Waiting for Rx pkt\n" );
break;
case 4:
DWMAC_CORE_PRINT_DBG( "- RX (Suspended): Unavailable Rx buf\n" );
break;
case 5:
DWMAC_CORE_PRINT_DBG( "- RX (Running): Closing Rx descriptor\n" );
break;
case 6:
DWMAC_CORE_PRINT_DBG( "- RX(Running): Flushing the current frame"
" from the Rx buf\n" );
break;
case 7:
DWMAC_CORE_PRINT_DBG( "- RX (Running): Queuing the Rx frame"
" from the Rx buf into memory\n" );
break;
default:
break;
}
}
#else /* DWMAC_CORE_DEBUG */
#define show_tx_process_state( status )
#define show_rx_process_state( status )
#endif /* DWMAC_CORE_DEBUG */
void dwmac_core_dma_interrupt( void *arg )
{
dwmac_common_context *self = (dwmac_common_context *) arg;
dwmac_common_dma_irq_counts *count = &self->stats.dma_irq_counts;
rtems_event_set events_receive = 0;
rtems_event_set events_transmit = 0;
/* Get interrupt status */
uint32_t irq_status = self->dmagrp->status & self->dmagrp->interrupt_enable;
uint32_t irq_handled = 0;
uint32_t irq_disable = 0;
DWMAC_CORE_PRINT_DBG( "%s: [CSR5: 0x%08x]\n", __func__, irq_status );
/* It displays the DMA process states (CSR5 register) if DWMAC_CORE_DEBUG is #defined */
show_tx_process_state( self->dmagrp->status );
show_rx_process_state( self->dmagrp->status );
/* Is there any abnormal interrupt? */
if ( irq_status & DMAGRP_STATUS_AIS ) {
DWMAC_CORE_PRINT_DBG( "CSR5[15] DMA ABNORMAL IRQ: " );
if ( irq_status & DMAGRP_STATUS_UNF ) {
DWMAC_CORE_PRINT_DBG( "transmit underflow\n" );
events_transmit |= DWMAC_COMMON_EVENT_TX_BUMP_UP_DMA_THRESHOLD;
irq_handled |= DMAGRP_STATUS_UNF;
irq_disable |= DMAGRP_INTERRUPT_ENABLE_UNE;
++count->tx_underflow;
}
if ( irq_status & DMAGRP_STATUS_TJT ) {
DWMAC_CORE_PRINT_DBG( "transmit jabber\n" );
irq_handled |= DMAGRP_STATUS_TJT;
++count->tx_jabber;
}
if ( irq_status & DMAGRP_STATUS_OVF ) {
DWMAC_CORE_PRINT_DBG( "recv overflow\n" );
irq_handled |= DMAGRP_STATUS_OVF;
++count->rx_overflow;
}
if ( irq_status & DMAGRP_STATUS_TU ) {
DWMAC_CORE_PRINT_DBG( "transmit buffer unavailable\n" );
irq_handled |= DMAGRP_STATUS_TU;
++count->tx_buf_unav;
}
if ( irq_status & DMAGRP_STATUS_RU ) {
DWMAC_CORE_PRINT_DBG( "receive buffer unavailable\n" );
irq_handled |= DMAGRP_STATUS_RU;
++count->rx_buf_unav;
}
if ( irq_status & DMAGRP_STATUS_RPS ) {
DWMAC_CORE_PRINT_DBG( "receive process stopped\n" );
irq_handled |= DMAGRP_STATUS_RPS;
++count->rx_process_stopped;
}
if ( irq_status & DMAGRP_STATUS_RWT ) {
DWMAC_CORE_PRINT_DBG( "receive watchdog\n" );
irq_handled |= DMAGRP_STATUS_RWT;
++count->rx_watchdog;
}
if ( irq_status & DMAGRP_STATUS_ETI ) {
DWMAC_CORE_PRINT_DBG( "transmit early interrupt\n" );
irq_handled |= DMAGRP_STATUS_ETI;
++count->tx_early;
}
if ( irq_status & DMAGRP_STATUS_ERI ) {
DWMAC_CORE_PRINT_DBG( "receive early interrupt\n" );
irq_handled |= DMAGRP_STATUS_ERI;
++count->rx_early;
}
if ( irq_status & DMAGRP_STATUS_TPS ) {
DWMAC_CORE_PRINT_DBG( "transmit process stopped\n" );
events_transmit |= DWMAC_COMMON_EVENT_TASK_INIT;
irq_handled |= DMAGRP_STATUS_TPS;
irq_disable |= DMAGRP_INTERRUPT_ENABLE_TSE;
++count->tx_process_stopped;
}
if ( irq_status & DMAGRP_STATUS_FBI ) {
DWMAC_CORE_PRINT_DBG( "fatal bus error\n" );
events_transmit |= DWMAC_COMMON_EVENT_TASK_INIT;
irq_handled |= DMAGRP_STATUS_FBI;
irq_disable |= DMAGRP_INTERRUPT_ENABLE_FBE;
++count->fatal_bus_error;
}
irq_handled |= DMAGRP_STATUS_AIS;
}
/* Is there any normal interrupt? */
if ( irq_status & DMAGRP_STATUS_NIS ) {
/* Transmit interrupt */
if ( irq_status & DMAGRP_STATUS_TI ) {
events_transmit |= DWMAC_COMMON_EVENT_TX_FRAME_TRANSMITTED;
irq_handled |= DMAGRP_STATUS_TI;
irq_disable |= DMAGRP_INTERRUPT_ENABLE_TIE;
++count->transmit;
}
/* Receive interrupt */
if ( irq_status & DMAGRP_STATUS_RI ) {
events_receive |= DWMAC_COMMON_EVENT_RX_FRAME_RECEIVED;
irq_handled |= DMAGRP_STATUS_RI;
irq_disable |= DMAGRP_INTERRUPT_ENABLE_RIE;
++count->receive;
}
irq_handled |= DMAGRP_STATUS_NIS;
}
/* Optional hardware blocks, interrupts should be disabled */
if ( irq_status
& ( DMAGRP_STATUS_GMI | DMAGRP_STATUS_GLI ) ) {
DWMAC_CORE_PRINT_DBG( "%s: unexpected status %08x\n", __func__,
irq_status );
if ( irq_status & DMAGRP_STATUS_GMI ) {
irq_handled |= DMAGRP_STATUS_GMI;
++count->unhandled;
}
if ( irq_status & DMAGRP_STATUS_GLI ) {
irq_handled |= DMAGRP_STATUS_GLI;
++count->unhandled;
}
}
/* Count remaining unhandled interrupts (there should not be any) */
if ( ( irq_status & 0x1FFCF ) != irq_handled ) {
++count->unhandled;
}
/* Disable interrupts which need further handling by tasks.
* The tasks will re-enable them. */
self->dmagrp->interrupt_enable &= ~irq_disable;
/* Clear interrupts */
self->dmagrp->status = irq_handled;
/* Send events to receive task */
if ( events_receive != 0 ) {
(void) rtems_bsdnet_event_send( self->task_id_rx, events_receive );
}
/* Send events to transmit task */
if ( events_transmit != 0 ) {
(void) rtems_bsdnet_event_send( self->task_id_tx, events_transmit );
}
DWMAC_CORE_PRINT_DBG( "\n\n" );
}
void dwmac_core_dma_flush_tx_fifo( dwmac_common_context *self )
{
self->dmagrp->operation_mode |= DMAGRP_OPERATION_MODE_FTF;
do {
} while ( ( self->dmagrp->operation_mode & DMAGRP_OPERATION_MODE_FTF ) != 0 );
}
void dwmac_core_set_mac_addr(
const uint8_t addr[6],
volatile uint32_t *reg_high,
volatile uint32_t *reg_low )
{
uint32_t data = MAC_HIGH_ADDRHI( ( addr[5] << 8 ) | addr[4] );
/* For MAC Addr registers se have to set the Address Enable (AE)
* bit that has no effect on the High Reg 0 where the bit 31 (MO)
* is RO.
*/
data |= MAC_HIGH_AE;
*reg_high = data;
data =
( (uint32_t) addr[3] << 24 )
| ( (uint32_t) addr[2] << 16 )
| ( (uint32_t) addr[1] << 8 )
| addr[0];
*reg_low = data;
}
/* Enable disable MAC RX/TX */
void dwmac_core_set_mac(
dwmac_common_context *self,
const bool enable )
{
uint32_t value = self->macgrp->mac_configuration;
if ( enable ) {
value |= MACGRP_MAC_CONFIGURATION_RE | MACGRP_MAC_CONFIGURATION_TE;
} else {
value &= ~( MACGRP_MAC_CONFIGURATION_RE | MACGRP_MAC_CONFIGURATION_TE );
}
self->macgrp->mac_configuration = value;
}
+76
View File
@@ -0,0 +1,76 @@
/**
* @file
*
* @brief DWMAC 10/100/1000 Network Interface Controllers Core Handling
*
* DWMAC 10/100/1000 on-chip Synopsys IP Ethernet controllers.
* Driver core handling.
* This header file is NOT part of the driver API.
*/
/*
* Copyright (c) 2014 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef DWMAC_CORE_H_
#define DWMAC_CORE_H_
#include <stdint.h>
#include "dwmac-common.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void dwmac_core_set_mac_addr(
const uint8_t addr[6],
volatile uint32_t *reg_high,
volatile uint32_t *reg_low );
void dwmac_core_set_mac(
dwmac_common_context *self,
const bool enable );
void dwmac_core_dma_start_tx( dwmac_common_context *self );
void dwmac_core_dma_stop_tx( dwmac_common_context *self );
void dwmac_core_dma_start_rx( dwmac_common_context *self );
void dwmac_core_dma_stop_rx( dwmac_common_context *self );
void dwmac_core_dma_restart_rx( dwmac_common_context *self );
void dwmac_core_dma_restart_tx( dwmac_common_context *self );
void dwmac_core_enable_dma_irq_rx( dwmac_common_context *self );
void dwmac_core_enable_dma_irq_tx( dwmac_common_context *self );
void dwmac_core_disable_dma_irq_tx( dwmac_common_context *self );
void dwmac_core_disable_dma_irq_rx( dwmac_common_context *self );
void dwmac_core_reset_dma_irq_status_tx( dwmac_common_context *self );
void dwmac_core_reset_dma_irq_status_rx( dwmac_common_context *self );
void dwmac_core_dma_interrupt( void *arg );
void dwmac_core_dma_flush_tx_fifo( dwmac_common_context *self );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DWMAC_CORE_H_ */
+60
View File
@@ -0,0 +1,60 @@
/**
* @file
*
* @brief DWMAC 10/100/1000 Common Descriptor Handling
*
* DWMAC 10/100/1000 on-chip Ethernet controllers.
* Functions which are common to normal and enhanced DMA descriptors.
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include "dwmac-desc-com.h"
#undef DWMAC_DESC_COM_DEBUG
#ifdef DWMAC_DESC_COM_DEBUG
#define DWMAC_DESC_COM_PRINT_DBG( fmt, args ... ) printk( fmt, ## args )
#else
#define DWMAC_DESC_COM_PRINT_DBG( fmt, args ... ) do { } while ( 0 )
#endif
struct mbuf *dwmac_desc_com_new_mbuf( dwmac_common_context *self ) {
struct ifnet *ifp = &self->arpcom.ac_if;
struct mbuf *m = NULL;
MGETHDR( m, M_DONTWAIT, MT_DATA );
if ( m != NULL ) {
MCLGET( m, M_DONTWAIT );
if ( m->m_ext.ext_buf != NULL ) {
if ( ( m->m_flags & M_EXT ) != 0 ) {
/* Set receive interface */
m->m_pkthdr.rcvif = ifp;
/* Make sure packet data will be aligned */
m->m_data = mtod( m, char * ) + ETHER_ALIGN;
return m;
} else {
m_free( m );
}
} else {
m_free( m );
}
}
return NULL;
}
+44
View File
@@ -0,0 +1,44 @@
/**
* @file
*
* @brief DWMAC 10/100/1000 Common Descriptor Handling.
*
* DWMAC 10/100/1000 on-chip Ethernet controllers.
* Functions and data which are common to normal and enhanced DMA descriptors.
* This header file is NOT part of the driver API.
*/
/*
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef DWMAC_DESC_COM_H_
#define DWMAC_DESC_COM_H_
#include "dwmac-common.h"
#include <sys/queue.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define DWMAC_DESC_COM_HW_CRC_BYTES 4
#define DWMAC_DESC_COM_BUF_SIZE ( ETHER_MAX_LEN + DWMAC_DESC_COM_HW_CRC_BYTES )
struct mbuf *dwmac_desc_com_new_mbuf( dwmac_common_context *self );
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DWMAC_DESC_COM_H_ */
File diff suppressed because it is too large Load Diff
+257
View File
@@ -0,0 +1,257 @@
#ifndef DWMAC_DESC_RX_REGS_H
#define DWMAC_DESC_RX_REGS_H
#include <bsp/utility.h>
typedef struct {
uint32_t des0;
#define DWMAC_DESC_RX_DES0_OWN_BIT BSP_BIT32(31)
#define DWMAC_DESC_RX_DES0_DEST_ADDR_FILTER_FAIL BSP_BIT32(30)
#define DWMAC_DESC_RX_DES0_FRAME_LENGTH(val) BSP_FLD32(val, 16, 29)
#define DWMAC_DESC_RX_DES0_FRAME_LENGTH_GET(reg) BSP_FLD32GET(reg, 16, 29)
#define DWMAC_DESC_RX_DES0_FRAME_LENGTH_SET(reg, val) BSP_FLD32SET(reg, val, 16, 29)
#define DWMAC_DESC_RX_DES0_ERROR_SUMMARY BSP_BIT32(15)
#define DWMAC_DESC_RX_DES0_DESCRIPTOR_ERROR BSP_BIT32(14)
#define DWMAC_DESC_RX_DES0_SRC_ADDR_FILTER_FAIL BSP_BIT32(13)
#define DWMAC_DESC_RX_DES0_LENGTH_ERROR BSP_BIT32(12)
#define DWMAC_DESC_RX_DES0_OVERFLOW_ERROR BSP_BIT32(11)
#define DWMAC_DESC_RX_DES0_VLAN_TAG BSP_BIT32(10)
#define DWMAC_DESC_RX_DES0_FIRST_DESCRIPTOR BSP_BIT32(9)
#define DWMAC_DESC_RX_DES0_LAST_DESCRIPTOR BSP_BIT32(8)
#define DWMAC_DESC_RX_DES0_CHECKSUM_ERROR BSP_BIT32(7)
#define DWMAC_DESC_RX_DES0_LATE_COLLISION BSP_BIT32(6)
#define DWMAC_DESC_RX_DES0_FRAME_TYPE BSP_BIT32(5)
#define DWMAC_DESC_RX_DES0_RECEIVE_WATCHDOG_TIMEOUT BSP_BIT32(4)
#define DWMAC_DESC_RX_DES0_RECEIVE_ERROR BSP_BIT32(3)
#define DWMAC_DESC_RX_DES0_DRIBBLE_BIT_ERROR BSP_BIT32(2)
#define DWMAC_DESC_RX_DES0_CRC_ERROR BSP_BIT32(1)
#define DWMAC_DESC_RX_DES0_RX_MAC_ADDR_OR_PAYLOAD_CHECKSUM_ERROR BSP_BIT32(0)
uint32_t des1;
#define DWMAC_DESC_RX_DES1_DISABLE_IRQ_ON_COMPLETION BSP_BIT32(31)
#define DWMAC_DESC_RX_DES1_RECEIVE_END_OF_RING BSP_BIT32(25)
#define DWMAC_DESC_RX_DES1_SECOND_ADDR_CHAINED BSP_BIT32(24)
#define DWMAC_DESC_RX_DES1_RECEIVE_BUFFER_2_SIZE(val) BSP_FLD32(val, 11, 21)
#define DWMAC_DESC_RX_DES1_RECEIVE_BUFFER_2_SIZE_GET(reg) BSP_FLD32GET(reg, 11, 21)
#define DWMAC_DESC_RX_DES1_RECEIVE_BUFFER_2_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 11, 21)
#define DWMAC_DESC_RX_DES1_RECIVE_BUFFER_1_SIZE(val) BSP_FLD32(val, 0, 10)
#define DWMAC_DESC_RX_DES1_RECIVE_BUFFER_1_SIZE_GET(reg) BSP_FLD32GET(reg, 0, 10)
#define DWMAC_DESC_RX_DES1_RECIVE_BUFFER_1_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 0, 10)
uint32_t des2;
#define DWMAC_DESC_RX_DES2_BUFF_1_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_RX_DES2_BUFF_1_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_RX_DES2_BUFF_1_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
#define DWMAC_DESC_RX_DES2_IEEE_RECEIVE_FRAME_TIMESTAMP_LOW(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_RX_DES2_IEEE_RECEIVE_FRAME_TIMESTAMP_LOW_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_RX_DES2_IEEE_RECEIVE_FRAME_TIMESTAMP_LOW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
uint32_t des3;
#define DWMAC_DESC_RX_DES3_BUFF_2_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_RX_DES3_BUFF_2_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_RX_DES3_BUFF_2_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
#define DWMAC_DESC_RX_DES3_IEEE_RECEIVE_FRAME_TIMESTAMP_LOW(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_RX_DES3_IEEE_RECEIVE_FRAME_TIMESTAMP_LOW_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_RX_DES3_IEEE_RECEIVE_FRAME_TIMESTAMP_LOW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
} dwmac_desc_rx;
typedef struct {
uint32_t des0;
#define DWMAC_DESC_TX_DES0_OWN_BIT BSP_BIT32(31)
#define DWMAC_DESC_TX_DES0_TX_TIMESTAMP_STATUS BSP_BIT32(17)
#define DWMAC_DESC_TX_DES0_IP_HEADER_ERROR BSP_BIT32(16)
#define DWMAC_DESC_TX_DES0_ERROR_SUMMARY BSP_BIT32(15)
#define DWMAC_DESC_TX_DES0_JABBER_TIMEOUT BSP_BIT32(14)
#define DWMAC_DESC_TX_DES0_FRAME_FLUSHED BSP_BIT32(13)
#define DWMAC_DESC_TX_DES0_PAYLOAD_CHECKSUM_ERROR BSP_BIT32(12)
#define DWMAC_DESC_TX_DES0_LOSS_OF_CARRIER BSP_BIT32(11)
#define DWMAC_DESC_TX_DES0_NO_CARRIER BSP_BIT32(10)
#define DWMAC_DESC_TX_DES0_EXCESSIVE_COLLISION BSP_BIT32(8)
#define DWMAC_DESC_TX_DES0_VLAN_FRAME BSP_BIT32(7)
#define DWMAC_DESC_TX_DES0_COLLISION_TIMEOUT(val) BSP_FLD32(val, 3, 6)
#define DWMAC_DESC_TX_DES0_COLLISION_TIMEOUT_GET(reg) BSP_FLD32GET(reg, 3, 6)
#define DWMAC_DESC_TX_DES0_COLLISION_TIMEOUT_SET(reg, val) BSP_FLD32SET(reg, val, 3, 6)
#define DWMAC_DESC_TX_DES0_EXCESSIVE_DEFERAL BSP_BIT32(2)
#define DWMAC_DESC_TX_DES0_UNDERFLOW_ERROR BSP_BIT32(1)
#define DWMAC_DESC_TX_DES0_DEFERED_BIT BSP_BIT32(0)
uint32_t des1;
#define DWMAC_DESC_TX_DES1_IRQ_ON_COMPLETION BSP_BIT32(31)
#define DWMAC_DESC_TX_DES1_LAST_SEGMENT BSP_BIT32(30)
#define DWMAC_DESC_TX_DES1_FIRST_SEGMENT BSP_BIT32(29)
#define DWMAC_DESC_TX_DES1_CHECKSUM_INSERTION_CONTROL(val) BSP_FLD32(val, 27, 28)
#define DWMAC_DESC_TX_DES1_CHECKSUM_INSERTION_CONTROL_GET(reg) BSP_FLD32GET(reg, 27, 28)
#define DWMAC_DESC_TX_DES1_CHECKSUM_INSERTION_CONTROL_SET(reg, val) BSP_FLD32SET(reg, val, 27, 28)
#define DWMAC_DESC_TX_DES1_DISABLE_CRC BSP_BIT32(26)
#define DWMAC_DESC_TX_DES1_TRANSMIT_END_OF_RING BSP_BIT32(25)
#define DWMAC_DESC_TX_DES1_SECOND_ADDRESS_CHAINED BSP_BIT32(24)
#define DWMAC_DESC_TX_DES1_DISABLE_PADDING BSP_BIT32(23)
#define DWMAC_DESC_TX_DES1_TRANSMIT_TIMESTAMP_ENABLE BSP_BIT32(22)
#define DWMAC_DESC_TX_DES1_TRANMIT_BUFFER_2_SIZE(val) BSP_FLD32(val, 11, 21)
#define DWMAC_DESC_TX_DES1_TRANMIT_BUFFER_2_SIZE_GET(reg) BSP_FLD32GET(reg, 11, 21)
#define DWMAC_DESC_TX_DES1_TRANMIT_BUFFER_2_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 11, 21)
#define DWMAC_DESC_TX_DES1_TRANSMIT_BUFFER_1_SIZE(val) BSP_FLD32(val, 0, 10)
#define DWMAC_DESC_TX_DES1_TRANSMIT_BUFFER_1_SIZE_GET(reg) BSP_FLD32GET(reg, 0, 10)
#define DWMAC_DESC_TX_DES1_TRANSMIT_BUFFER_1_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 0, 10)
uint32_t des2;
#define DWMAC_DESC_TX_DES2_BUFF_1_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_TX_DES2_BUFF_1_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_TX_DES2_BUFF_1_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
#define DWMAC_DESC_TX_DES2_IEEE_TRANSMIT_FRAME_TIMESTAMP_LOW(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_TX_DES2_IEEE_TRANSMIT_FRAME_TIMESTAMP_LOW_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_TX_DES2_IEEE_TRANSMIT_FRAME_TIMESTAMP_LOW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
uint32_t des3;
#define DWMAC_DESC_TX_DES3_BUFF_2_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_TX_DES3_BUFF_2_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_TX_DES3_BUFF_2_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
#define DWMAC_DESC_TX_DES3_IEEE_TRANSMIT_FRAME_TIMESTAMP_LOW(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_TX_DES3_IEEE_TRANSMIT_FRAME_TIMESTAMP_LOW_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_TX_DES3_IEEE_TRANSMIT_FRAME_TIMESTAMP_LOW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
} dwmac_desc_tx;
typedef struct {
uint32_t des0;
#define DWMAC_DESC_ERX_DES0_OWN_BIT BSP_BIT32(31)
#define DWMAC_DESC_ERX_DES0_DEST_ADDR_FILTER_FAIL BSP_BIT32(30)
#define DWMAC_DESC_ERX_DES0_FRAME_LENGTH(val) BSP_FLD32(val, 16, 29)
#define DWMAC_DESC_ERX_DES0_FRAME_LENGTH_GET(reg) BSP_FLD32GET(reg, 16, 29)
#define DWMAC_DESC_ERX_DES0_FRAME_LENGTH_SET(reg, val) BSP_FLD32SET(reg, val, 16, 29)
#define DWMAC_DESC_ERX_DES0_ERROR_SUMMARY BSP_BIT32(15)
#define DWMAC_DESC_ERX_DES0_DESCRIPTOR_ERROR BSP_BIT32(14)
#define DWMAC_DESC_ERX_DES0_SRC_ADDR_FILTER_FAIL BSP_BIT32(13)
#define DWMAC_DESC_ERX_DES0_LENGTH_ERROR BSP_BIT32(12)
#define DWMAC_DESC_ERX_DES0_OVERFLOW_ERROR BSP_BIT32(11)
#define DWMAC_DESC_ERX_DES0_VLAN_TAG BSP_BIT32(10)
#define DWMAC_DESC_ERX_DES0_FIRST_DESCRIPTOR BSP_BIT32(9)
#define DWMAC_DESC_ERX_DES0_LAST_DESCRIPTOR BSP_BIT32(8)
#define DWMAC_DESC_ERX_DES0_TIMESTAMP_AVAIL_OR_CHECKSUM_ERROR_OR_GIANT_FRAME BSP_BIT32(7)
#define DWMAC_DESC_ERX_DES0_LATE_COLLISION BSP_BIT32(6)
#define DWMAC_DESC_ERX_DES0_FREAME_TYPE BSP_BIT32(5)
#define DWMAC_DESC_ERX_DES0_RECEIVE_WATCHDOG_TIMEOUT BSP_BIT32(4)
#define DWMAC_DESC_ERX_DES0_RECEIVE_ERROR BSP_BIT32(3)
#define DWMAC_DESC_ERX_DES0_DRIBBLE_BIT_ERROR BSP_BIT32(2)
#define DWMAC_DESC_ERX_DES0_CRC_ERROR BSP_BIT32(1)
#define DWMAC_DESC_ERX_DES0_EXT_STATUS_AVAIL_OR_RX_MAC_ADDR_STATUS BSP_BIT32(0)
uint32_t des1;
#define DWMAC_DESC_ERX_DES1_DISABLE_IRQ_ON_COMPLETION BSP_BIT32(31)
#define DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_2_SIZE(val) BSP_FLD32(val, 16, 28)
#define DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_2_SIZE_GET(reg) BSP_FLD32GET(reg, 16, 28)
#define DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_2_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 16, 28)
#define DWMAC_DESC_ERX_DES1_RECEIVE_END_OF_RING BSP_BIT32(15)
#define DWMAC_DESC_ERX_DES1_SECOND_ADDR_CHAINED BSP_BIT32(14)
#define DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_1_SIZE(val) BSP_FLD32(val, 0, 12)
#define DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_1_SIZE_GET(reg) BSP_FLD32GET(reg, 0, 12)
#define DWMAC_DESC_ERX_DES1_RECEIVE_BUFF_1_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 0, 12)
uint32_t des2;
#define DWMAC_DESC_ERX_DES2_BUFF_1_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_ERX_DES2_BUFF_1_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_ERX_DES2_BUFF_1_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
uint32_t des3;
#define DWMAC_DESC_ERX_DES3_BUFF_2_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_ERX_DES3_BUFF_2_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_ERX_DES3_BUFF_2_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
} dwmac_desc_erx;
typedef struct {
uint32_t des0;
#define DWMAC_DESC_ETX_DES0_OWN_BIT BSP_BIT32(31)
#define DWMAC_DESC_ETX_DES0_IRQ_ON_COMPLETION BSP_BIT32(30)
#define DWMAC_DESC_ETX_DES0_LAST_SEGMENT BSP_BIT32(29)
#define DWMAC_DESC_ETX_DES0_FIRST_SEGMENT BSP_BIT32(28)
#define DWMAC_DESC_ETX_DES0_DISABLE_CRC BSP_BIT32(27)
#define DWMAC_DESC_ETX_DES0_DISABLE_PAD BSP_BIT32(26)
#define DWMAC_DESC_ETX_DES0_TRANSMIT_TIMESTAMP_ENABLE BSP_BIT32(25)
#define DWMAC_DESC_ETX_DES0_CHECKSUM_INSERTION_CONTROL(val) BSP_FLD32(val, 22, 23)
#define DWMAC_DESC_ETX_DES0_CHECKSUM_INSERTION_CONTROL_GET(reg) BSP_FLD32GET(reg, 22, 23)
#define DWMAC_DESC_ETX_DES0_CHECKSUM_INSERTION_CONTROL_SET(reg, val) BSP_FLD32SET(reg, val, 22, 23)
#define DWMAC_DESC_ETX_DES0_TRANSMIT_END_OF_RING BSP_BIT32(21)
#define DWMAC_DESC_ETX_DES0_SECOND_ADDR_CHAINED BSP_BIT32(20)
#define DWMAC_DESC_ETX_DES0_TRANSMIT_TIMESTAMP_STATUS BSP_BIT32(17)
#define DWMAC_DESC_ETX_DES0_IP_HEADER_ERROR BSP_BIT32(16)
#define DWMAC_DESC_ETX_DES0_ERROR_SUMMARY BSP_BIT32(15)
#define DWMAC_DESC_ETX_DES0_JABBER_TIMEOUT BSP_BIT32(14)
#define DWMAC_DESC_ETX_DES0_FRAME_FLUSHED BSP_BIT32(13)
#define DWMAC_DESC_ETX_DES0_IP_PAYLOAD_ERROR BSP_BIT32(12)
#define DWMAC_DESC_ETX_DES0_LOSS_OF_CARRIER BSP_BIT32(11)
#define DWMAC_DESC_ETX_DES0_NO_CARRIER BSP_BIT32(10)
#define DWMAC_DESC_ETX_DES0_EXCESSIVE_COLLISION BSP_BIT32(8)
#define DWMAC_DESC_ETX_DES0_VLAN_FRAME BSP_BIT32(7)
#define DWMAC_DESC_ETX_DES0_COLLISION_COUNT(val) BSP_FLD32(val, 3, 6)
#define DWMAC_DESC_ETX_DES0_COLLISION_COUNT_GET(reg) BSP_FLD32GET(reg, 3, 6)
#define DWMAC_DESC_ETX_DES0_COLLISION_COUNT_SET(reg, val) BSP_FLD32SET(reg, val, 3, 6)
#define DWMAC_DESC_ETX_DES0_EXCESSIVE_DEFERAL BSP_BIT32(2)
#define DWMAC_DESC_ETX_DES0_UNDERFLOW_ERROR BSP_BIT32(1)
#define DWMAC_DESC_ETX_DES0_DEFERRED_BIT BSP_BIT32(0)
uint32_t des1;
#define DWMAC_DESC_ETX_DES1_TRANSMIT_BUFFER_2_SIZE(val) BSP_FLD32(val, 16, 28)
#define DWMAC_DESC_ETX_DES1_TRANSMIT_BUFFER_2_SIZE_GET(reg) BSP_FLD32GET(reg, 16, 28)
#define DWMAC_DESC_ETX_DES1_TRANSMIT_BUFFER_2_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 16, 28)
#define DWMAC_DESC_ETX_DES1_TRANSMIT_BUFFER_1_SIZE(val) BSP_FLD32(val, 0, 12)
#define DWMAC_DESC_ETX_DES1_TRANSMIT_BUFFER_1_SIZE_GET(reg) BSP_FLD32GET(reg, 0, 12)
#define DWMAC_DESC_ETX_DES1_TRANSMIT_BUFFER_1_SIZE_SET(reg, val) BSP_FLD32SET(reg, val, 0, 12)
uint32_t des2;
#define DWMAC_DESC_ETX_DES2_BUFF_1_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_ETX_DES2_BUFF_1_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_ETX_DES2_BUFF_1_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
uint32_t des3;
#define DWMAC_DESC_ETX_DES3_BUFF_2_ADDR_PTR(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_ETX_DES3_BUFF_2_ADDR_PTR_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_ETX_DES3_BUFF_2_ADDR_PTR_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
} dwmac_desc_etx;
typedef union {
dwmac_desc_rx rx;
dwmac_desc_tx tx;
dwmac_desc_erx erx;
dwmac_desc_etx etx;
} dwmac_desc;
typedef struct {
dwmac_desc_erx des0_3;
uint32_t des4;
#define DWMAC_DESC_EXT_ERX_DES4_LAYER3_AND_LAYER4_FILTER_MATCHED(val) BSP_FLD32(val, 26, 27)
#define DWMAC_DESC_EXT_ERX_DES4_LAYER3_AND_LAYER4_FILTER_MATCHED_GET(reg) BSP_FLD32GET(reg, 26, 27)
#define DWMAC_DESC_EXT_ERX_DES4_LAYER3_AND_LAYER4_FILTER_MATCHED_SET(reg, val) BSP_FLD32SET(reg, val, 26, 27)
#define DWMAC_DESC_EXT_ERX_DES4_LAYER4_FILTER_MATCH BSP_BIT32(25)
#define DWMAC_DESC_EXT_ERX_DES4_LAYER3_FILTER_MATCH BSP_BIT32(24)
#define DWMAC_DESC_EXT_ERX_DES4_TIMESTAMP_DROPPED BSP_BIT32(14)
#define DWMAC_DESC_EXT_ERX_DES4_PTP_VERSION BSP_BIT32(13)
#define DWMAC_DESC_EXT_ERX_DES4_PTP_FRAME_TYPE BSP_BIT32(12)
#define DWMAC_DESC_EXT_ERX_DES4_MESSAGE_TYPE(val) BSP_FLD32(val, 8, 11)
#define DWMAC_DESC_EXT_ERX_DES4_MESSAGE_TYPE_GET(reg) BSP_FLD32GET(reg, 8, 11)
#define DWMAC_DESC_EXT_ERX_DES4_MESSAGE_TYPE_SET(reg, val) BSP_FLD32SET(reg, val, 8, 11)
#define DWMAC_DESC_EXT_ERX_DES4_IPV6_PACKET_RECEIVED BSP_BIT32(7)
#define DWMAC_DESC_EXT_ERX_DES4_IPV4_PACKET_RECEIVED BSP_BIT32(6)
#define DWMAC_DESC_EXT_ERX_DES4_IP_CHECKSUM_BYPASSED BSP_BIT32(5)
#define DWMAC_DESC_EXT_ERX_DES4_IP_PAYLOAD_ERROR BSP_BIT32(4)
#define DWMAC_DESC_EXT_ERX_DES4_IP_HEADER_ERROR BSP_BIT32(3)
#define DWMAC_DESC_EXT_ERX_DES4_IP_PAYLOAD_TYPE(val) BSP_FLD32(val, 0, 2)
#define DWMAC_DESC_EXT_ERX_DES4_IP_PAYLOAD_TYPE_GET(reg) BSP_FLD32GET(reg, 0, 2)
#define DWMAC_DESC_EXT_ERX_DES4_IP_PAYLOAD_TYPE_SET(reg, val) BSP_FLD32SET(reg, val, 0, 2)
uint32_t des5;
uint32_t des6;
#define DWMAC_DESC_EXT_ERX_DES6_RECEIVE_FRAME_TIMESTAMP_LOW(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_EXT_ERX_DES6_RECEIVE_FRAME_TIMESTAMP_LOW_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_EXT_ERX_DES6_RECEIVE_FRAME_TIMESTAMP_LOW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
uint32_t des7;
#define DWMAC_DESC_EXT_ERX_DES7_RECEIVE_FRAME_TIMESTAMP_HIGH(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_EXT_ERX_DES7_RECEIVE_FRAME_TIMESTAMP_HIGH_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_EXT_ERX_DES7_RECEIVE_FRAME_TIMESTAMP_HIGH_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
} dwmac_desc_ext_erx;
typedef struct {
dwmac_desc_etx des0_3;
uint32_t des4;
uint32_t des5;
uint32_t des6;
#define DWMAC_DESC_EXT_ETX_DES6_TRANSMIT_FRAME_TIMESTAMP_LOW(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_EXT_ETX_DES6_TRANSMIT_FRAME_TIMESTAMP_LOW_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_EXT_ETX_DES6_TRANSMIT_FRAME_TIMESTAMP_LOW_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
uint32_t des7;
#define DWMAC_DESC_EXT_ETX_DES7_TRANSMIT_FRAME_TIMESTAMP_HIGH(val) BSP_FLD32(val, 0, 31)
#define DWMAC_DESC_EXT_ETX_DES7_TRANSMIT_FRAME_TIMESTAMP_HIGH_GET(reg) BSP_FLD32GET(reg, 0, 31)
#define DWMAC_DESC_EXT_ETX_DES7_TRANSMIT_FRAME_TIMESTAMP_HIGH_SET(reg, val) BSP_FLD32SET(reg, val, 0, 31)
} dwmac_desc_ext_etx;
typedef union {
dwmac_desc_ext_erx erx;
dwmac_desc_ext_etx etx;
} dwmac_desc_ext;
#endif /* DWMAC_DESC_RX_REGS_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4
View File
@@ -97,6 +97,10 @@ PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/smc91111.h
$(PROJECT_INCLUDE)/libchip/smc91111exp.h: network/smc91111exp.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/smc91111exp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/smc91111exp.h
$(PROJECT_INCLUDE)/libchip/dwmac.h: network/dwmac.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/dwmac.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libchip/dwmac.h
endif
$(PROJECT_INCLUDE)/libchip/rtc.h: rtc/rtc.h $(PROJECT_INCLUDE)/libchip/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libchip/rtc.h