mirror of
				https://github.com/FreeRTOS/FreeRTOS-Kernel.git
				synced 2025-11-03 18:22:45 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			1346 lines
		
	
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1346 lines
		
	
	
	
		
			41 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 /**
 | 
						|
 * \file
 | 
						|
 *
 | 
						|
 * \brief GMAC (Ethernet MAC) driver for SAM.
 | 
						|
 *
 | 
						|
 * Copyright (c) 2013 Atmel Corporation. All rights reserved.
 | 
						|
 *
 | 
						|
 * \asf_license_start
 | 
						|
 *
 | 
						|
 * \page License
 | 
						|
 *
 | 
						|
 * Redistribution and use in source and binary forms, with or without
 | 
						|
 * modification, are permitted provided that the following conditions are met:
 | 
						|
 *
 | 
						|
 * 1. Redistributions of source code must retain the above copyright notice,
 | 
						|
 *    this list of conditions and the following disclaimer.
 | 
						|
 *
 | 
						|
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 | 
						|
 *    this list of conditions and the following disclaimer in the documentation
 | 
						|
 *    and/or other materials provided with the distribution.
 | 
						|
 *
 | 
						|
 * 3. The name of Atmel may not be used to endorse or promote products derived
 | 
						|
 *    from this software without specific prior written permission.
 | 
						|
 *
 | 
						|
 * 4. This software may only be redistributed and used in connection with an
 | 
						|
 *    Atmel microcontroller product.
 | 
						|
 *
 | 
						|
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
						|
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
						|
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 | 
						|
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 | 
						|
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
						|
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
						|
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
						|
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 | 
						|
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 | 
						|
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
						|
 * POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 *
 | 
						|
 * \asf_license_stop
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef GMAC_H_INCLUDED
 | 
						|
#define GMAC_H_INCLUDED
 | 
						|
 | 
						|
#include "compiler.h"
 | 
						|
 | 
						|
/// @cond 0
 | 
						|
/**INDENT-OFF**/
 | 
						|
#ifdef __cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
/**INDENT-ON**/
 | 
						|
/// @endcond
 | 
						|
 | 
						|
/** The buffer addresses written into the descriptors must be aligned, so the
 | 
						|
    last few bits are zero.  These bits have special meaning for the GMAC
 | 
						|
    peripheral and cannot be used as part of the address. */
 | 
						|
#define GMAC_RXD_ADDR_MASK      0xFFFFFFFC
 | 
						|
#define GMAC_RXD_WRAP         (1ul << 1)  /**< Wrap bit */
 | 
						|
#define GMAC_RXD_OWNERSHIP    (1ul << 0)  /**< Ownership bit */
 | 
						|
 | 
						|
#define GMAC_RXD_BROADCAST    (1ul << 31) /**< Broadcast detected */
 | 
						|
#define GMAC_RXD_MULTIHASH    (1ul << 30) /**< Multicast hash match */
 | 
						|
#define GMAC_RXD_UNIHASH      (1ul << 29) /**< Unicast hash match */
 | 
						|
#define GMAC_RXD_ADDR_FOUND      (1ul << 27) /**< Specific address match found */
 | 
						|
#define GMAC_RXD_ADDR        (3ul << 25) /**< Address match */
 | 
						|
#define GMAC_RXD_RXCOEN        (1ul << 24) /**< RXCOEN related function */
 | 
						|
#define GMAC_RXD_TYPE         (3ul << 22) /**< Type ID match */
 | 
						|
#define GMAC_RXD_VLAN         (1ul << 21) /**< VLAN tag detected */
 | 
						|
#define GMAC_RXD_PRIORITY     (1ul << 20) /**< Priority tag detected */
 | 
						|
#define GMAC_RXD_PRIORITY_MASK  (3ul << 17) /**< VLAN priority */
 | 
						|
#define GMAC_RXD_CFI          (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
 | 
						|
#define GMAC_RXD_EOF          (1ul << 15) /**< End of frame */
 | 
						|
#define GMAC_RXD_SOF          (1ul << 14) /**< Start of frame */
 | 
						|
#define GMAC_RXD_FCS          (1ul << 13) /**< Frame check sequence */
 | 
						|
#define GMAC_RXD_OFFSET_MASK                /**< Receive buffer offset */
 | 
						|
#define GMAC_RXD_LEN_MASK       (0xFFF)     /**< Length of frame including FCS (if selected) */
 | 
						|
#define GMAC_RXD_LENJUMBO_MASK  (0x3FFF)    /**< Jumbo frame length */
 | 
						|
 | 
						|
#define GMAC_TXD_USED         (1ul << 31) /**< Frame is transmitted */
 | 
						|
#define GMAC_TXD_WRAP         (1ul << 30) /**< Last descriptor */
 | 
						|
#define GMAC_TXD_ERROR        (1ul << 29) /**< Retry limit exceeded, error */
 | 
						|
#define GMAC_TXD_UNDERRUN     (1ul << 28) /**< Transmit underrun */
 | 
						|
#define GMAC_TXD_EXHAUSTED    (1ul << 27) /**< Buffer exhausted */
 | 
						|
#define GMAC_TXD_LATE    (1ul << 26) /**< Late collision,transmit  error  */
 | 
						|
#define GMAC_TXD_CHECKSUM_ERROR   (7ul << 20) /**< Checksum error */
 | 
						|
#define GMAC_TXD_NOCRC        (1ul << 16) /**< No CRC */
 | 
						|
#define GMAC_TXD_LAST         (1ul << 15) /**< Last buffer in frame */
 | 
						|
#define GMAC_TXD_LEN_MASK       (0x1FFF)     /**< Length of buffer */
 | 
						|
 | 
						|
/** The MAC can support frame lengths up to 1536 bytes */
 | 
						|
#define GMAC_FRAME_LENTGH_MAX       1536
 | 
						|
 | 
						|
#define GMAC_RX_UNITSIZE            128     /**< Fixed size for RX buffer  */
 | 
						|
#define GMAC_TX_UNITSIZE            1518    /**< Size for ETH frame length */
 | 
						|
 | 
						|
/** GMAC clock speed */
 | 
						|
#define GMAC_MCK_SPEED_240MHZ        (240*1000*1000)
 | 
						|
#define GMAC_MCK_SPEED_160MHZ        (160*1000*1000)
 | 
						|
#define GMAC_MCK_SPEED_120MHZ        (120*1000*1000)
 | 
						|
#define GMAC_MCK_SPEED_80MHZ          (80*1000*1000)
 | 
						|
#define GMAC_MCK_SPEED_40MHZ          (40*1000*1000)
 | 
						|
#define GMAC_MCK_SPEED_20MHZ          (20*1000*1000)
 | 
						|
 | 
						|
/** GMAC maintain code default value*/
 | 
						|
#define GMAC_MAN_CODE_VALUE    (10)
 | 
						|
 | 
						|
/** GMAC maintain start of frame default value*/
 | 
						|
#define GMAC_MAN_SOF_VALUE     (1)
 | 
						|
 | 
						|
/** GMAC maintain read/write*/
 | 
						|
#define GMAC_MAN_RW_TYPE       (2)
 | 
						|
 | 
						|
/** GMAC maintain read only*/
 | 
						|
#define GMAC_MAN_READ_ONLY     (1)
 | 
						|
 | 
						|
/** GMAC address length */
 | 
						|
#define GMAC_ADDR_LENGTH       (6)
 | 
						|
 | 
						|
 | 
						|
#define GMAC_DUPLEX_HALF 0
 | 
						|
#define GMAC_DUPLEX_FULL 1
 | 
						|
 | 
						|
#define GMAC_SPEED_10M      0
 | 
						|
#define GMAC_SPEED_100M     1
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Return codes for GMAC APIs.
 | 
						|
 */
 | 
						|
typedef enum {
 | 
						|
	GMAC_OK = 0,         /** 0  Operation OK */
 | 
						|
	GMAC_TIMEOUT = 1,    /** 1  GMAC operation timeout */
 | 
						|
	GMAC_TX_BUSY,        /** 2  TX in progress */
 | 
						|
	GMAC_RX_NULL,        /** 3  No data received */
 | 
						|
	GMAC_SIZE_TOO_SMALL, /** 4  Buffer size not enough */
 | 
						|
	GMAC_PARAM,          /** 5  Parameter error, TX packet invalid or RX size too small */
 | 
						|
	GMAC_INVALID = 0xFF, /* Invalid */
 | 
						|
} gmac_status_t;
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Media Independent Interface (MII) type.
 | 
						|
 */
 | 
						|
typedef enum {
 | 
						|
	GMAC_PHY_MII = 0,         /** MII mode */
 | 
						|
	GMAC_PHY_RMII = 1,    /** Reduced MII mode */
 | 
						|
	GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
 | 
						|
} gmac_mii_mode_t;
 | 
						|
 | 
						|
/** Receive buffer descriptor struct */
 | 
						|
COMPILER_PACK_SET(8)
 | 
						|
typedef struct gmac_rx_descriptor {
 | 
						|
	union gmac_rx_addr {
 | 
						|
		uint32_t val;
 | 
						|
		struct gmac_rx_addr_bm {
 | 
						|
			uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
 | 
						|
			b_wrap:1,   /**< Marks last descriptor in receive buffer */
 | 
						|
			addr_dw:30; /**< Address in number of DW */
 | 
						|
		} bm;
 | 
						|
	} addr; /**< Address, Wrap & Ownership */
 | 
						|
	union gmac_rx_status {
 | 
						|
		uint32_t val;
 | 
						|
		struct gmac_rx_status_bm {
 | 
						|
			uint32_t len:13,       /**  0..12  Length of frame including FCS */
 | 
						|
			b_fcs:1,               /**  13     Receive buffer offset,  bits 13:12 of frame length for jumbo frame */
 | 
						|
			b_sof:1,               /**  14     Start of frame */
 | 
						|
			b_eof:1,               /**  15     End of frame */
 | 
						|
			b_cfi:1,               /**  16     Concatenation Format Indicator */
 | 
						|
			vlan_priority:3,       /**  17..19 VLAN priority (if VLAN detected) */
 | 
						|
			b_priority_detected:1, /**  20     Priority tag detected */
 | 
						|
			b_vlan_detected:1,     /**  21     VLAN tag detected */
 | 
						|
			b_type_id_match:2,     /**  22..23 Type ID match */
 | 
						|
			b_checksumoffload:1,   /**  24     Checksum offload specific function */
 | 
						|
			b_addrmatch:2,         /**  25..26 Address register match */
 | 
						|
			b_ext_addr_match:1,    /**  27     External address match found */
 | 
						|
			reserved:1,            /**  28     */
 | 
						|
			b_uni_hash_match:1,    /**  29     Unicast hash match */
 | 
						|
			b_multi_hash_match:1,  /**  30     Multicast hash match */
 | 
						|
			b_boardcast_detect:1;  /**  31     Global broadcast address detected */
 | 
						|
		} bm;
 | 
						|
	} status;
 | 
						|
} gmac_rx_descriptor_t;
 | 
						|
 | 
						|
/** Transmit buffer descriptor struct */
 | 
						|
COMPILER_PACK_SET(8)
 | 
						|
typedef struct gmac_tx_descriptor {
 | 
						|
	uint32_t addr;
 | 
						|
	union gmac_tx_status {
 | 
						|
		uint32_t val;
 | 
						|
		struct gmac_tx_status_bm {
 | 
						|
			uint32_t len:14,     /**  0..13 Length of buffer */
 | 
						|
			reserved:1,          /** 14            */
 | 
						|
			b_last_buffer:1,     /** 15     Last buffer (in the current frame) */
 | 
						|
			b_no_crc:1,          /** 16     No CRC */
 | 
						|
			reserved1:3,         /** 17..19        */
 | 
						|
			b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
 | 
						|
			reserved2:3,         /** 23..25        */
 | 
						|
			b_lco:1,             /** 26     Late collision, transmit error detected */
 | 
						|
			b_exhausted:1,       /** 27     Buffer exhausted in mid frame */
 | 
						|
			b_underrun:1,        /** 28     Transmit underrun */
 | 
						|
			b_error:1,           /** 29     Retry limit exceeded, error detected */
 | 
						|
			b_wrap:1,            /** 30     Marks last descriptor in TD list */
 | 
						|
			b_used:1;            /** 31     User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
 | 
						|
		} bm;
 | 
						|
	} status;
 | 
						|
} gmac_tx_descriptor_t;
 | 
						|
 | 
						|
COMPILER_PACK_RESET()
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Input parameters when initializing the gmac module mode.
 | 
						|
 */
 | 
						|
typedef struct gmac_options {
 | 
						|
	/*  Enable/Disable CopyAllFrame */
 | 
						|
	uint8_t uc_copy_all_frame;
 | 
						|
	/* Enable/Disable NoBroadCast */
 | 
						|
	uint8_t uc_no_boardcast;
 | 
						|
	/* MAC address */
 | 
						|
	uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
 | 
						|
} gmac_options_t;
 | 
						|
 | 
						|
/** RX callback */
 | 
						|
typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status);
 | 
						|
/** Wakeup callback */
 | 
						|
typedef void (*gmac_dev_wakeup_cb_t) (void);
 | 
						|
 | 
						|
/**
 | 
						|
 * GMAC driver structure.
 | 
						|
 */
 | 
						|
typedef struct gmac_device {
 | 
						|
 | 
						|
	/** Pointer to HW register base */
 | 
						|
	Gmac *p_hw;
 | 
						|
	/**
 | 
						|
	 * Pointer to allocated TX buffer.
 | 
						|
	 * Section 3.6 of AMBA 2.0 spec states that burst should not cross
 | 
						|
	 * 1K Boundaries.
 | 
						|
	 * Receive buffer manager writes are burst of 2 words => 3 lsb bits
 | 
						|
	 * of the address shall be set to 0.
 | 
						|
	 */
 | 
						|
	uint8_t *p_tx_buffer;
 | 
						|
	/** Pointer to allocated RX buffer */
 | 
						|
	uint8_t *p_rx_buffer;
 | 
						|
	/** Pointer to Rx TDs (must be 8-byte aligned) */
 | 
						|
	gmac_rx_descriptor_t *p_rx_dscr;
 | 
						|
	/** Pointer to Tx TDs (must be 8-byte aligned) */
 | 
						|
	gmac_tx_descriptor_t *p_tx_dscr;
 | 
						|
	/** Optional callback to be invoked once a frame has been received */
 | 
						|
	gmac_dev_tx_cb_t func_rx_cb;
 | 
						|
#if( GMAC_USES_WAKEUP_CALLBACK )
 | 
						|
	/** Optional callback to be invoked once several TDs have been released */
 | 
						|
	gmac_dev_wakeup_cb_t func_wakeup_cb;
 | 
						|
#endif
 | 
						|
#if( GMAC_USES_TX_CALLBACK != 0 )
 | 
						|
	/** Optional callback list to be invoked once TD has been processed */
 | 
						|
	gmac_dev_tx_cb_t *func_tx_cb_list;
 | 
						|
#endif
 | 
						|
	/** RX TD list size */
 | 
						|
	uint32_t ul_rx_list_size;
 | 
						|
	/** RX index for current processing TD */
 | 
						|
	uint32_t ul_rx_idx;
 | 
						|
	/** TX TD list size */
 | 
						|
	uint32_t ul_tx_list_size;
 | 
						|
	/** Circular buffer head pointer by upper layer (buffer to be sent) */
 | 
						|
	int32_t l_tx_head;
 | 
						|
	/** Circular buffer tail pointer incremented by handlers (buffer sent) */
 | 
						|
	int32_t l_tx_tail;
 | 
						|
 | 
						|
	/** Number of free TD before wakeup callback is invoked */
 | 
						|
	uint32_t uc_wakeup_threshold;
 | 
						|
} gmac_device_t;
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Write network control value.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_ncr   Network control value.
 | 
						|
 */
 | 
						|
static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR = ul_ncr;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Get network control value.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
 | 
						|
static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_NCR;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable GMAC receive.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable GMAC receiver, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable GMAC transmit.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable GMAC transmit, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable GMAC management.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable GMAC management, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Clear all statistics registers.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_clear_statistics(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Increase all statistics registers.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_increase_statistics(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable statistics registers writing.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable the statistics registers writing, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_statistics_write(Gmac* p_gmac,
 | 
						|
		uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief In half-duplex mode, forces collisions on all received frames.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable the back pressure, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_BP;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Start transmission.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_start_transmission(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Halt transmission.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_halt_transmission(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Transmit pause frame.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_tx_pause_frame(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Transmit zero quantum pause frame.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Read snapshot.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_read_snapshot(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Store receivetime stamp to memory.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to normal operation, else to enable the store.
 | 
						|
 */
 | 
						|
static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable PFC priority-based pause reception.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   1 to set the reception, 0 to disable.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Transmit PFC priority-based pause reception.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
 | 
						|
{
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Flush next packet.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_flush_next_packet(Gmac* p_gmac)
 | 
						|
{
 | 
						|
		p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set up network configuration register.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
  * \param ul_cfg   Network configuration value.
 | 
						|
 */
 | 
						|
static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCFGR = ul_cfg;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Get network configuration.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return Network configuration.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_configure(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_NCFGR;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/* Get and set DMA Configuration Register */
 | 
						|
static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_DCFGR = ul_cfg;
 | 
						|
}
 | 
						|
 | 
						|
static inline uint32_t gmac_get_dma(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_DCFGR;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set speed.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
 | 
						|
 */
 | 
						|
static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
 | 
						|
{
 | 
						|
	if (uc_speed) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable Full-Duplex mode.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable the Full-Duplex mode, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable Copy(Receive) All Valid Frames.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable copying all valid frames, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable jumbo frames (up to 10240 bytes).
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable the jumbo frames, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Disable/Enable broadcast receiving.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   1 to disable the broadcast, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable multicast hash.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable the multicast hash, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable big frames (over 1518, up to 1536).
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable big frames else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set MDC clock divider.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_mck   GMAC MCK.
 | 
						|
 *
 | 
						|
 * \return GMAC_OK if successfully.
 | 
						|
 */
 | 
						|
static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
 | 
						|
{
 | 
						|
	uint32_t ul_clk;
 | 
						|
	
 | 
						|
	if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
 | 
						|
		return GMAC_INVALID;
 | 
						|
	} else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
 | 
						|
		ul_clk = GMAC_NCFGR_CLK_MCK_96;
 | 
						|
	} else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
 | 
						|
		ul_clk = GMAC_NCFGR_CLK_MCK_64;
 | 
						|
	} else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
 | 
						|
		ul_clk = GMAC_NCFGR_CLK_MCK_48;
 | 
						|
	} else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
 | 
						|
		ul_clk = GMAC_NCFGR_CLK_MCK_32;
 | 
						|
	} else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
 | 
						|
		ul_clk = GMAC_NCFGR_CLK_MCK_16;
 | 
						|
	} else {
 | 
						|
		ul_clk = GMAC_NCFGR_CLK_MCK_8;
 | 
						|
	}
 | 
						|
	;
 | 
						|
	p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
 | 
						|
	return GMAC_OK;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable retry test.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable the GMAC receiver, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable pause (when a valid pause frame is received).
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable pause frame, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set receive buffer offset to 0 ~ 3.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
 | 
						|
	p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable receive length field checking.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable receive length field checking, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable discarding FCS field of received frames.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable discarding FCS field of received frames, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable frames to be received in half-duplex mode
 | 
						|
 * while transmitting.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable the received in half-duplex mode, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable/Disable ignore RX FCS.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_enable   0 to disable ignore RX FCS, else to enable it.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
 | 
						|
{
 | 
						|
	if (uc_enable) {
 | 
						|
		p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
 | 
						|
	} else {
 | 
						|
		p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Get Network Status.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return Network status.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_status(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_NSR;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Get MDIO IN pin status.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return MDIO IN pin status.
 | 
						|
 */
 | 
						|
static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Check if PHY is idle.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return  1 if PHY is idle.
 | 
						|
 */
 | 
						|
static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Return transmit status.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return  Transmit status.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_TSR;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Clear transmit status.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_status   Transmit status.
 | 
						|
 */
 | 
						|
static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_TSR = ul_status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Return receive status.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_RSR;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Clear receive status.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_status   Receive status.
 | 
						|
 */
 | 
						|
static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_RSR = ul_status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set Rx Queue.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_addr   Rx queue address.
 | 
						|
 */
 | 
						|
static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Get Rx Queue Address.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return  Rx queue address.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_RBQB;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set Tx Queue.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_addr  Tx queue address.
 | 
						|
 */
 | 
						|
static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Get Tx Queue.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return  Rx queue address.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_TBQB;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Enable interrupt(s).
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_source   Interrupt source(s) to be enabled.
 | 
						|
 */
 | 
						|
static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_IER = ul_source;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Disable interrupt(s).
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_source   Interrupt source(s) to be disabled.
 | 
						|
 */
 | 
						|
static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_IDR = ul_source;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Return interrupt status.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return Interrupt status.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_ISR;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Return interrupt mask.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return Interrupt mask.
 | 
						|
 */
 | 
						|
static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	return p_gmac->GMAC_IMR;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Execute PHY maintenance command.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_phy_addr   PHY address.
 | 
						|
 * \param uc_reg_addr   Register address.
 | 
						|
 * \param uc_rw   1 to Read, 0 to write.
 | 
						|
 * \param us_data   Data to be performed, write only.
 | 
						|
 */
 | 
						|
static inline void gmac_maintain_phy(Gmac* p_gmac,
 | 
						|
		uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
 | 
						|
		uint16_t us_data)
 | 
						|
{
 | 
						|
	/* Wait until bus idle */
 | 
						|
	while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
 | 
						|
	/* Write maintain register */
 | 
						|
	p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
 | 
						|
			| GMAC_MAN_CLTTO 
 | 
						|
			| GMAC_MAN_PHYA(uc_phy_addr)
 | 
						|
			| GMAC_MAN_REGA(uc_reg_addr)
 | 
						|
			| GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
 | 
						|
			| GMAC_MAN_DATA(us_data);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Get PHY maintenance data returned.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 *
 | 
						|
 * \return Get PHY data.
 | 
						|
 */
 | 
						|
static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
 | 
						|
{
 | 
						|
	/* Wait until bus idle */
 | 
						|
	while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
 | 
						|
	/* Return data */
 | 
						|
	return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set Hash.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ul_hash_top   Hash top.
 | 
						|
 * \param ul_hash_bottom   Hash bottom.
 | 
						|
 */
 | 
						|
static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
 | 
						|
		uint32_t ul_hash_bottom)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_HRB = ul_hash_bottom;
 | 
						|
	p_gmac->GMAC_HRT = ul_hash_top;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set 64 bits Hash.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param ull_hash   64 bits hash value.
 | 
						|
 */
 | 
						|
static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_HRB = (uint32_t) ull_hash;
 | 
						|
	p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set MAC Address.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_index  GMAC specific address register index.
 | 
						|
 * \param p_mac_addr  GMAC address.
 | 
						|
 */
 | 
						|
static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
 | 
						|
		uint8_t* p_mac_addr)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
 | 
						|
			| (p_mac_addr[2] << 16)
 | 
						|
			| (p_mac_addr[1] << 8)
 | 
						|
			| (p_mac_addr[0]);
 | 
						|
	p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
 | 
						|
			| (p_mac_addr[4]);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set MAC Address via 2 dword.
 | 
						|
  *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_index  GMAC specific address register index.
 | 
						|
 * \param ul_mac_top  GMAC top address.
 | 
						|
 * \param ul_mac_bottom  GMAC bottom address.
 | 
						|
 */
 | 
						|
static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
 | 
						|
		uint32_t ul_mac_top, uint32_t ul_mac_bottom)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
 | 
						|
	p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Set MAC Address via int64.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param uc_index  GMAC specific address register index.
 | 
						|
 * \param ull_mac  64-bit GMAC address.
 | 
						|
 */
 | 
						|
static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
 | 
						|
		uint64_t ull_mac)
 | 
						|
{
 | 
						|
	p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
 | 
						|
	p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * \brief Select media independent interface mode.
 | 
						|
 *
 | 
						|
 * \param p_gmac   Pointer to the GMAC instance.
 | 
						|
 * \param mode   Media independent interface mode.
 | 
						|
 */
 | 
						|
static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
 | 
						|
{
 | 
						|
	switch (mode) {
 | 
						|
		case GMAC_PHY_MII:
 | 
						|
		case GMAC_PHY_RMII:
 | 
						|
			p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
 | 
						|
		break;
 | 
						|
 | 
						|
		default:
 | 
						|
			p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
 | 
						|
		break;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
 | 
						|
		uint32_t* p_value);
 | 
						|
uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
 | 
						|
		uint8_t uc_address, uint32_t ul_value);
 | 
						|
void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
 | 
						|
		gmac_options_t* p_opt);
 | 
						|
uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
 | 
						|
		uint32_t ul_frame_size, uint32_t* p_rcv_size);
 | 
						|
uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
 | 
						|
		uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
 | 
						|
uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
 | 
						|
void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
 | 
						|
		gmac_dev_tx_cb_t func_rx_cb);
 | 
						|
uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
 | 
						|
		gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
 | 
						|
void gmac_dev_reset(gmac_device_t* p_gmac_dev);
 | 
						|
void gmac_handler(gmac_device_t* p_gmac_dev);
 | 
						|
 | 
						|
/// @cond 0
 | 
						|
/**INDENT-OFF**/
 | 
						|
#ifdef __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
/**INDENT-ON**/
 | 
						|
/// @endcond
 | 
						|
 | 
						|
/**
 | 
						|
 * \page gmac_quickstart Quickstart guide for GMAC driver.
 | 
						|
 *
 | 
						|
 * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
 | 
						|
 * with step-by-step instructions on how to configure and use the driver in a
 | 
						|
 * selection of use cases.
 | 
						|
 *
 | 
						|
 * The use cases contain several code fragments. The code fragments in the
 | 
						|
 * steps for setup can be copied into a custom initialization function, while
 | 
						|
 * the steps for usage can be copied into, e.g., the main application function.
 | 
						|
 *
 | 
						|
 * \section gmac_basic_use_case Basic use case
 | 
						|
 * In the basic use case, the GMAC driver are configured for:
 | 
						|
 * - PHY component KSZ8051MNL is used
 | 
						|
 * - GMAC uses MII mode
 | 
						|
 * - The number of receive buffer is 16
 | 
						|
 * - The number of transfer buffer is 8
 | 
						|
 * - MAC address is set to 00-04-25-1c-a0-02
 | 
						|
 * - IP address is set to 192.168.0.2
 | 
						|
 * - IP address is set to 192.168.0.2
 | 
						|
 * - Gateway is set to 192.168.0.1
 | 
						|
 * - Network mask is 255.255.255.0
 | 
						|
 * - PHY operation max retry count is 1000000
 | 
						|
 * - GMAC is configured to not support copy all frame and support broadcast
 | 
						|
 * - The data will be read from the ethernet
 | 
						|
 *
 | 
						|
 * \section gmac_basic_use_case_setup Setup steps
 | 
						|
 *
 | 
						|
 * \subsection gmac_basic_use_case_setup_prereq Prerequisites
 | 
						|
 * -# \ref sysclk_group "System Clock Management (sysclock)"
 | 
						|
 * -# \ref pmc_group "Power Management Controller (pmc)"
 | 
						|
 * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
 | 
						|
 *
 | 
						|
 * \subsection gmac_basic_use_case_setup_code Example code
 | 
						|
 * Content of conf_eth.h
 | 
						|
 * \code
 | 
						|
 * #define GMAC_RX_BUFFERS                               16
 | 
						|
 * #define GMAC_TX_BUFFERS                               8
 | 
						|
 * #define MAC_PHY_RETRY_MAX                             1000000
 | 
						|
 * #define ETHERNET_CONF_ETHADDR0                        0x00
 | 
						|
 * #define ETHERNET_CONF_ETHADDR0                        0x00
 | 
						|
 * #define ETHERNET_CONF_ETHADDR1                        0x04
 | 
						|
 * #define ETHERNET_CONF_ETHADDR2                        0x25
 | 
						|
 * #define ETHERNET_CONF_ETHADDR3                        0x1C
 | 
						|
 * #define ETHERNET_CONF_ETHADDR4                        0xA0
 | 
						|
 * #define ETHERNET_CONF_ETHADDR5                        0x02
 | 
						|
 * #define ETHERNET_CONF_IPADDR0                         192
 | 
						|
 * #define ETHERNET_CONF_IPADDR1                         168
 | 
						|
 * #define ETHERNET_CONF_IPADDR2                         0
 | 
						|
 * #define ETHERNET_CONF_IPADDR3                         2
 | 
						|
 * #define ETHERNET_CONF_GATEWAY_ADDR0                   192
 | 
						|
 * #define ETHERNET_CONF_GATEWAY_ADDR1                   168
 | 
						|
 * #define ETHERNET_CONF_GATEWAY_ADDR2                   0
 | 
						|
 * #define ETHERNET_CONF_GATEWAY_ADDR3                   1
 | 
						|
 * #define ETHERNET_CONF_NET_MASK0                       255
 | 
						|
 * #define ETHERNET_CONF_NET_MASK1                       255
 | 
						|
 * #define ETHERNET_CONF_NET_MASK2                       255
 | 
						|
 * #define ETHERNET_CONF_NET_MASK3                       0
 | 
						|
 * #define ETH_PHY_MODE                                  ETH_PHY_MODE
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
 | 
						|
 * to trace the actual size of the data received.
 | 
						|
 * \code
 | 
						|
 * static gmac_device_t gs_gmac_dev;
 | 
						|
 * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
 | 
						|
 *
 | 
						|
 * uint32_t ul_frm_size;
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * Add to application C-file:
 | 
						|
 * \code
 | 
						|
 *   void gmac_init(void)
 | 
						|
 *   {
 | 
						|
 *       sysclk_init();
 | 
						|
 *
 | 
						|
 *       board_init();
 | 
						|
 *
 | 
						|
 *       pmc_enable_periph_clk(ID_GMAC);
 | 
						|
 *
 | 
						|
 *       gmac_option.uc_copy_all_frame = 0;
 | 
						|
 *       gmac_option.uc_no_boardcast = 0;
 | 
						|
 *       memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
 | 
						|
 *       gs_gmac_dev.p_hw = GMAC;
 | 
						|
 *
 | 
						|
 *       gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
 | 
						|
 *
 | 
						|
 *       NVIC_EnableIRQ(GMAC_IRQn);
 | 
						|
 *
 | 
						|
 *       ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
 | 
						|
 * 
 | 
						|
 *       ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
 | 
						|
 *
 | 
						|
 *       ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * \subsection gmac_basic_use_case_setup_flow Workflow
 | 
						|
 * - Ensure that conf_eth.h is present and contains the
 | 
						|
 * following configuration symbol. This configuration file is used
 | 
						|
 * by the driver and should not be included by the application.
 | 
						|
 * -# Define the receiving buffer size used in the internal GMAC driver.
 | 
						|
 * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
 | 
						|
 * If it was supposed receiving a large number of frame, the
 | 
						|
 * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
 | 
						|
 * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least 
 | 
						|
 * (2048/128)=16, and as there are additional frames coming, a preferred
 | 
						|
 * number is 24 depending on a normal Ethernet throughput.
 | 
						|
 *   - \code
 | 
						|
 *        #define GMAC_RX_BUFFERS                               16
 | 
						|
 *   \endcode
 | 
						|
 * -# Define the transmitting buffer size used in the internal GMAC driver.
 | 
						|
 * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
 | 
						|
 *   - \code
 | 
						|
 *        #define GMAC_TX_BUFFERS                               8
 | 
						|
 *   \endcode
 | 
						|
 * -# Define maximum retry time for a PHY read/write operation.
 | 
						|
 *   - \code
 | 
						|
 *        #define MAC_PHY_RETRY_MAX                             1000000
 | 
						|
 *   \endcode
 | 
						|
 * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
 | 
						|
 * for ATMEL, application should always change this address to its' own.
 | 
						|
 *   - \code
 | 
						|
 *        #define ETHERNET_CONF_ETHADDR0                        0x00
 | 
						|
 *        #define ETHERNET_CONF_ETHADDR1                        0x04
 | 
						|
 *        #define ETHERNET_CONF_ETHADDR2                        0x25
 | 
						|
 *        #define ETHERNET_CONF_ETHADDR3                        0x1C
 | 
						|
 *        #define ETHERNET_CONF_ETHADDR4                        0xA0
 | 
						|
 *        #define ETHERNET_CONF_ETHADDR5                        0x02
 | 
						|
 *   \endcode
 | 
						|
 * -# Define the IP address configration used in the application. When DHCP
 | 
						|
 *  is enabled, this configuration is not effected.
 | 
						|
 *   - \code
 | 
						|
 *        #define ETHERNET_CONF_IPADDR0                         192
 | 
						|
 *        #define ETHERNET_CONF_IPADDR1                         168
 | 
						|
 *        #define ETHERNET_CONF_IPADDR2                         0
 | 
						|
 *        #define ETHERNET_CONF_IPADDR3                         2
 | 
						|
 *        #define ETHERNET_CONF_GATEWAY_ADDR0                   192
 | 
						|
 *        #define ETHERNET_CONF_GATEWAY_ADDR1                   168
 | 
						|
 *        #define ETHERNET_CONF_GATEWAY_ADDR2                   0
 | 
						|
 *        #define ETHERNET_CONF_GATEWAY_ADDR3                   1
 | 
						|
 *        #define ETHERNET_CONF_NET_MASK0                       255
 | 
						|
 *        #define ETHERNET_CONF_NET_MASK1                       255
 | 
						|
 *        #define ETHERNET_CONF_NET_MASK2                       255
 | 
						|
 *        #define ETHERNET_CONF_NET_MASK3                       0
 | 
						|
 *   \endcode
 | 
						|
 * -# Configure the PHY maintainance interface.
 | 
						|
 *   - \code
 | 
						|
 *        #define ETH_PHY_MODE                                  GMAC_PHY_MII
 | 
						|
 *   \endcode
 | 
						|
 * -# Enable the system clock:
 | 
						|
 *   - \code sysclk_init(); \endcode
 | 
						|
 * -# Enable PIO configurations for GMAC:
 | 
						|
 *   - \code board_init(); \endcode
 | 
						|
 * -# Enable PMC clock for GMAC:
 | 
						|
 *   - \code pmc_enable_periph_clk(ID_GMAC); \endcode
 | 
						|
 * -# Set the GMAC options; it's set to copy all frame and support broadcast:
 | 
						|
 *   - \code
 | 
						|
 *         gmac_option.uc_copy_all_frame = 0;
 | 
						|
 *         gmac_option.uc_no_boardcast = 0;
 | 
						|
 *         memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
 | 
						|
 *         gs_gmac_dev.p_hw = GMAC;
 | 
						|
 * \endcode
 | 
						|
 * -# Initialize GMAC device with the filled option:
 | 
						|
 *   - \code
 | 
						|
 *         gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
 | 
						|
 * \endcode
 | 
						|
 * -# Enable the interrupt service for GMAC:
 | 
						|
 *   - \code
 | 
						|
 *         NVIC_EnableIRQ(GMAC_IRQn);
 | 
						|
 * \endcode
 | 
						|
 * -# Initialize the PHY component:
 | 
						|
 *   - \code
 | 
						|
 *         ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
 | 
						|
 * \endcode
 | 
						|
  * -# The link will be established based on auto negotiation.
 | 
						|
 *   - \code
 | 
						|
 *         ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
 | 
						|
 * \endcode
 | 
						|
 * -# Establish the ethernet link; the network can be worked from now on:
 | 
						|
 *   - \code
 | 
						|
 *         ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * \section gmac_basic_use_case_usage Usage steps
 | 
						|
 * \subsection gmac_basic_use_case_usage_code Example code
 | 
						|
 * Add to, e.g., main loop in application C-file:
 | 
						|
 * \code
 | 
						|
 *    gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
 | 
						|
 * \endcode
 | 
						|
 *
 | 
						|
 * \subsection gmac_basic_use_case_usage_flow Workflow
 | 
						|
 * -# Start reading the data from the ethernet:
 | 
						|
 *   - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
 | 
						|
 */
 | 
						|
 | 
						|
#	define GMAC_STATS 0
 | 
						|
 | 
						|
#if( GMAC_STATS != 0 )
 | 
						|
 | 
						|
	/* Here below some code to study the types and
 | 
						|
	frequencies of 	GMAC interrupts. */
 | 
						|
	#define GMAC_IDX_RXUBR 0
 | 
						|
	#define GMAC_IDX_TUR   1
 | 
						|
	#define GMAC_IDX_RLEX  2
 | 
						|
	#define GMAC_IDX_TFC   3
 | 
						|
	#define GMAC_IDX_RCOMP 4
 | 
						|
	#define GMAC_IDX_TCOMP 5
 | 
						|
	#define GMAC_IDX_ROVR  6
 | 
						|
	#define GMAC_IDX_HRESP 7
 | 
						|
	#define GMAC_IDX_PFNZ  8
 | 
						|
	#define GMAC_IDX_PTZ   9
 | 
						|
 | 
						|
	struct SGmacStats {
 | 
						|
		unsigned recvCount;
 | 
						|
		unsigned rovrCount;
 | 
						|
		unsigned bnaCount;
 | 
						|
		unsigned sendCount;
 | 
						|
		unsigned sovrCount;
 | 
						|
		unsigned incompCount;
 | 
						|
		unsigned truncCount;
 | 
						|
 | 
						|
		unsigned intStatus[10];
 | 
						|
	};
 | 
						|
	extern struct SGmacStats gmacStats;
 | 
						|
 | 
						|
	struct SIntPair {
 | 
						|
		const char *name;
 | 
						|
		unsigned mask;
 | 
						|
		int index;
 | 
						|
	};
 | 
						|
 | 
						|
	#define MK_PAIR( NAME )   #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
 | 
						|
	static const struct SIntPair intPairs[] = {
 | 
						|
		{ MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
 | 
						|
		{ MK_PAIR( TUR   ) }, /* Enable transmit underrun interrupt. */
 | 
						|
		{ MK_PAIR( RLEX  ) }, /* Enable retry limit  exceeded interrupt. */
 | 
						|
		{ MK_PAIR( TFC   ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
 | 
						|
		{ MK_PAIR( RCOMP ) }, /* Receive complete */
 | 
						|
		{ MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
 | 
						|
		{ MK_PAIR( ROVR  ) }, /* Enable receive overrun interrupt. */
 | 
						|
		{ MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
 | 
						|
		{ MK_PAIR( PFNZ  ) }, /* Enable pause frame received interrupt. */
 | 
						|
		{ MK_PAIR( PTZ   ) }  /* Enable pause time zero interrupt. */
 | 
						|
	};
 | 
						|
 | 
						|
	void gmac_show_irq_counts ();
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#endif /* GMAC_H_INCLUDED */
 |