summaryrefslogtreecommitdiffstats
path: root/c/src/libchip/network/dwmac-common.h
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/libchip/network/dwmac-common.h')
-rw-r--r--c/src/libchip/network/dwmac-common.h374
1 files changed, 374 insertions, 0 deletions
diff --git a/c/src/libchip/network/dwmac-common.h b/c/src/libchip/network/dwmac-common.h
new file mode 100644
index 0000000000..b61b833078
--- /dev/null
+++ b/c/src/libchip/network/dwmac-common.h
@@ -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_ */