arch/arm/src/lpc54xx: Addes packet buffer and DMA descriptor logic
This commit is contained in:
parent
5394681dea
commit
5146725edc
@ -747,6 +747,56 @@ config LPC54_ETH_8023AS2K
|
||||
bool "Enable 8023as support for 2K packets"
|
||||
default n
|
||||
|
||||
config LPC54_ETH_NRXDESC0
|
||||
int "Number of Rx DMA descriptors (ch0)"
|
||||
default 8
|
||||
range 4 1024
|
||||
---help---
|
||||
The number of Rx DMA descriptors to configure for Rx Channel 0. The
|
||||
minimum is 4; the upper limit is 1024.
|
||||
|
||||
NOTE: Each Rx descriptor will require a receive buffer at the size
|
||||
of the configured MTU.
|
||||
|
||||
config LPC54_ETH_NRXDESC1
|
||||
int "Number of Rx DMA descriptors (ch1)"
|
||||
default 8
|
||||
range 4 1024
|
||||
depends on LPC54_ETH_MULTIQUEUE
|
||||
---help---
|
||||
The number of Rx DMA descriptors to configure for Rx Channel 1. The
|
||||
minimum is 4; the upper limit is 1024.
|
||||
|
||||
NOTE: Each Rx descriptor will require a receive buffer at the size
|
||||
of the configured MTU.
|
||||
|
||||
config LPC54_ETH_NTXDESC0
|
||||
int "Number of Tx DMA descriptors (ch0)"
|
||||
default 8
|
||||
range 4 1024
|
||||
---help---
|
||||
The number of Tx DMA descriptors to configure for Rx Channel 0. The
|
||||
minimum is 4; the upper limit is 1024.
|
||||
|
||||
NOTE: Each Rx descriptor will require a transmit buffer at the size
|
||||
of the configured MTU.
|
||||
|
||||
config LPC54_ETH_NTXDESC1
|
||||
int "Number of Tx DMA descriptors (ch1)"
|
||||
default 8
|
||||
range 4 1024
|
||||
depends on LPC54_ETH_MULTIQUEUE
|
||||
---help---
|
||||
The number of Tx DMA descriptors to configure for Rx Channel 1. The
|
||||
minimum is 4; the upper limit is 1024.
|
||||
|
||||
NOTE: Each Rx descriptor will require a transmit buffer at the size
|
||||
of the configured MTU.
|
||||
|
||||
config LPC54_ETH_RX_DOUBLEBUFFER
|
||||
bool "Enable Rx double buffering"
|
||||
default n
|
||||
|
||||
endmenu # Ethernet configuration
|
||||
|
||||
menu "SD/MMC Configuration"
|
||||
|
@ -578,24 +578,28 @@
|
||||
#define ETH_DMACH_RX_CTRL_SR (1 << 0) /* Bit 0: Start or stop receive command */
|
||||
#define ETH_DMACH_RX_CTRL_RBSZ_SHIFT (3) /* Bits 3-14: Receive buffer size */
|
||||
#define ETH_DMACH_RX_CTRL_RBSZ_MASK (0xfff << ETH_DMACH_RX_CTRL_RBSZ_SHIFT)
|
||||
# define ETH_DMACH_RX_CTRL(n) ((uint32_t)(n) << ETH_DMACH_RX_CTRL_RBSZ_SHIFT)
|
||||
# define ETH_DMACH_RX_CTRL_RBSZ(n) ((uint32_t)(n) << ETH_DMACH_RX_CTRL_RBSZ_SHIFT)
|
||||
#define ETH_DMACH_RX_CTRL_RxPBL_SHIFT (16) /* Bits 16-21: Receive programmable burst length */
|
||||
#define ETH_DMACH_RX_CTRL_RxPBL_MASK (0x3f << ETH_DMACH_RX_CTRL_RxPBL_SHIFT)
|
||||
# define ETH_DMACH_RX_CTRL_RxPBL(n) ((uint32_t)(n) << ETH_DMACH_RX_CTRL_RxPBL_SHIFT)
|
||||
#define ETH_DMACH_RX_CTRL_RPF (1 << 31) /* Bit 31: DMA Rx channel n packet flush */
|
||||
|
||||
/* DMA channel n Tx descriptor list address */
|
||||
#define ETH_DMACH_TXDESC_LIST_ADDR_
|
||||
/* DMA channel n Rx descriptor list address */
|
||||
#define ETH_DMACH_RXDESC_LIST_ADDR_
|
||||
/* DMA channel n Tx descriptor tail pointer */
|
||||
#define ETH_DMACH_TXDESC_TAIL_PTR_
|
||||
/* DMA channel n Rx descriptor tail pointer */
|
||||
#define ETH_DMACH_RXDESC_TAIL_PTR_
|
||||
/* DMA channel n Tx descriptor list address (32-bit, word-aligned address) */
|
||||
/* DMA channel n Rx descriptor list address (32-bit, word-aligned address) */
|
||||
/* DMA channel n Tx descriptor tail pointer (32-bit, word-aligned address) */
|
||||
/* DMA channel n Rx descriptor tail pointer (32-bit, word-aligned address) */
|
||||
|
||||
/* DMA channel n Tx descriptor ring length */
|
||||
#define ETH_DMACH_TXDESC_RING_LENGTH_
|
||||
|
||||
#define ETH_DMACH_TXDESC_RING_LENGTH_SHIFT (0) /* Bits 0-9: Transmit ring length */
|
||||
#define ETH_DMACH_TXDESC_RING_LENGTH_MASK (0x3ff << ETH_DMACH_TXDESC_RING_LENGTH_SHIFT)
|
||||
# define ETH_DMACH_TXDESC_RING_LENGTH(n) ((uint32_t)((n)-1) << ETH_DMACH_TXDESC_RING_LENGTH_SHIFT)
|
||||
|
||||
/* DMA channel n Rx descriptor ring length */
|
||||
#define ETH_DMACH_RXDESC_RING_LENGTH_
|
||||
|
||||
#define ETH_DMACH_RXDESC_RING_LENGTH_SHIFT (0) /* Bits 0-9: Receive ring length */
|
||||
#define ETH_DMACH_RXDESC_RING_LENGTH_MASK (0x3ff << ETH_DMACH_RXDESC_RING_LENGTH_SHIFT)
|
||||
# define ETH_DMACH_RXDESC_RING_LENGTH(n) ((uint32_t)((n)-1) << ETH_DMACH_RXDESC_RING_LENGTH_SHIFT)
|
||||
|
||||
/* DMA channel n interrupt enable and DMA channel n DMA status */
|
||||
|
||||
@ -790,7 +794,7 @@ struct enet_rxdesc_s
|
||||
uint32_t buffer1; /* Buffer 1 address */
|
||||
uint32_t reserved; /* Reserved */
|
||||
uint32_t buffer2; /* Buffer 2 or next descriptor address */
|
||||
uint32_t control; /* Buffer 1/2 byte counts and control */
|
||||
uint32_t ctrl; /* Buffer 1/2 byte counts and control */
|
||||
};
|
||||
|
||||
/* Transmit descriptor structure (read format) */
|
||||
|
@ -709,7 +709,7 @@
|
||||
|
||||
#define SYSCON_ETHSBDCTRL_SHIFT (0) /* Bits 0-1: Sideband Flow Control */
|
||||
#define SYSCON_ETHSBDCTRL_MASK (3 << SYSCON_ETHSBDCTRL_SHIFT)
|
||||
# define SYSCON_ETHSBDCTRL CHAN1 (0 << SYSCON_ETHSBDCTRL_SHIFT) /* Controls channel 0 */
|
||||
# define SYSCON_ETHSBDCTRL_CHAN1 (0 << SYSCON_ETHSBDCTRL_SHIFT) /* Controls channel 0 */
|
||||
# define SYSCON_ETHSBDCTRL_CHAN2 (2 << SYSCON_ETHSBDCTRL_SHIFT) /* Controls channel 1 */
|
||||
|
||||
/* SDIO CCLKIN phase and delay control */
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <queue.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
@ -121,9 +122,26 @@
|
||||
|
||||
#define LPC54_MAC_HALFDUPLEX_IPG ETH_MAC_CONFIG_IPG_64 /* Default half-duplex IPG */
|
||||
|
||||
/* Packet-buffer definitions */
|
||||
|
||||
#ifdef CONFIG_LPC54_ETH_MULTIQUEUE
|
||||
# define LPC54_NBUFFERS (CONFIG_LPC54_ETH_NRXDESC0 + \
|
||||
CONFIG_LPC54_ETH_NRXDESC1 + \
|
||||
CONFIG_LPC54_ETH_NTXDESC0 + \
|
||||
CONFIG_LPC54_ETH_NTXDESC1)
|
||||
#else
|
||||
# define LPC54_NBUFFERS (CONFIG_LPC54_ETH_NRXDESC0 + \
|
||||
CONFIG_LPC54_ETH_NTXDESC0)
|
||||
#endif
|
||||
|
||||
#define LPC54_BUFFER_SIZE MAX_NET_DEV_MTU
|
||||
#define LPC54_BUFFER_ALLOC ((MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE + 3) & ~3)
|
||||
#define LPC54_BUFFER_WORDS ((MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE + 3) >> 2)
|
||||
|
||||
/* DMA descriptor definitions */
|
||||
|
||||
#define LPC54_MIN_RINGLEN 4 /* Min length of a ring */
|
||||
#define LPC54_MAX_RINGLEN 1023 /* Max length of a ring */
|
||||
#define LPC54_MAX_RINGS 2 /* Max number of tx/rx descriptor rings */
|
||||
|
||||
/* Interrupt masks */
|
||||
@ -152,17 +170,25 @@
|
||||
|
||||
struct lpc54_ethdriver_s
|
||||
{
|
||||
bool eth_bifup; /* true:ifup false:ifdown */
|
||||
bool eth_fullduplex; /* true:Full duplex false:Half duplex mode */
|
||||
bool eth_100mbps; /* true:100mbps false:10mbps */
|
||||
WDOG_ID eth_txpoll; /* TX poll timer */
|
||||
WDOG_ID eth_txtimeout; /* TX timeout timer */
|
||||
struct work_s eth_irqwork; /* For deferring interupt work to the work queue */
|
||||
struct work_s eth_pollwork; /* For deferring poll work to the work queue */
|
||||
bool eth_bifup; /* true:ifup false:ifdown */
|
||||
bool eth_fullduplex; /* true:Full duplex false:Half duplex mode */
|
||||
bool eth_100mbps; /* true:100mbps false:10mbps */
|
||||
WDOG_ID eth_txpoll; /* TX poll timer */
|
||||
WDOG_ID eth_txtimeout; /* TX timeout timer */
|
||||
struct work_s eth_irqwork; /* For deferring interupt work to the work queue */
|
||||
struct work_s eth_pollwork; /* For deferring poll work to the work queue */
|
||||
struct sq_queue_s eth_freebuf; /* Free packet buffers */
|
||||
|
||||
/* Packet buffers assigned to Rx descriptors */
|
||||
|
||||
uint32_t *eth_rxbuffers1[CONFIG_LPC54_ETH_NRXDESC0];
|
||||
#ifdef CONFIG_LPC54_ETH_MULTIQUEUE
|
||||
uint32_t *eth_rxbuffers2[CONFIG_LPC54_ETH_NRXDESC1];
|
||||
#endif
|
||||
|
||||
/* This holds the information visible to the NuttX network */
|
||||
|
||||
struct net_driver_s eth_dev; /* Interface understood by the network */
|
||||
struct net_driver_s eth_dev; /* Interface understood by the network */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -185,65 +211,104 @@ static uint8_t g_pktbuf[MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE];
|
||||
|
||||
static struct lpc54_ethdriver_s g_ethdriver;
|
||||
|
||||
/* Rx DMA descriptors */
|
||||
|
||||
static struct enet_rxdesc_s g_ch0_rxdesc[CONFIG_LPC54_ETH_NRXDESC0];
|
||||
#ifdef CONFIG_LPC54_ETH_MULTIQUEUE
|
||||
static struct enet_rxdesc_s g_ch1_rxdesc[CONFIG_LPC54_ETH_NRXDESC1];
|
||||
#endif
|
||||
|
||||
/* Tx DMA descriptors */
|
||||
|
||||
static struct enet_txdesc_s g_ch0_txdesc[CONFIG_LPC54_ETH_NTXDESC0];
|
||||
#ifdef CONFIG_LPC54_ETH_MULTIQUEUE
|
||||
static struct enet_txdesc_s g_ch1_txdesc[CONFIG_LPC54_ETH_NTXDESC1];
|
||||
#endif
|
||||
|
||||
/* Preallocated packet buffers */
|
||||
|
||||
static uint32_t g_prealloc_buffers[LPC54_NBUFFERS * LPC54_BUFFER_WORDS];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Common TX logic */
|
||||
|
||||
static int lpc54_eth_transmit(FAR struct lpc54_ethdriver_s *priv);
|
||||
static int lpc54_eth_txpoll(FAR struct net_driver_s *dev);
|
||||
static int lpc54_eth_transmit(struct lpc54_ethdriver_s *priv);
|
||||
static int lpc54_eth_txpoll(struct net_driver_s *dev);
|
||||
|
||||
/* Interrupt handling */
|
||||
|
||||
static void lpc54_eth_receive(FAR struct lpc54_ethdriver_s *priv);
|
||||
static void lpc54_eth_txdone(FAR struct lpc54_ethdriver_s *priv);
|
||||
static void lpc54_eth_receive(struct lpc54_ethdriver_s *priv);
|
||||
static void lpc54_eth_txdone(struct lpc54_ethdriver_s *priv);
|
||||
|
||||
static void lpc54_eth_interrupt_work(FAR void *arg);
|
||||
static int lpc54_eth_interrupt(int irq, FAR void *context, FAR void *arg);
|
||||
static void lpc54_eth_interrupt_work(void *arg);
|
||||
static int lpc54_eth_interrupt(int irq, void *context, void *arg);
|
||||
#if 0 /* Not used */
|
||||
static int lpc54_pmt_interrupt(int irq, void *context, void *arg);
|
||||
static int lpc54_mac_interrupt(int irq, void *context, void *arg);
|
||||
#endif
|
||||
|
||||
/* Watchdog timer expirations */
|
||||
|
||||
static void lpc54_eth_txtimeout_work(FAR void *arg);
|
||||
static void lpc54_eth_txtimeout_work(void *arg);
|
||||
static void lpc54_eth_txtimeout_expiry(int argc, wdparm_t arg, ...);
|
||||
|
||||
static void lpc54_eth_poll_work(FAR void *arg);
|
||||
static void lpc54_eth_poll_work(void *arg);
|
||||
static void lpc54_eth_poll_expiry(int argc, wdparm_t arg, ...);
|
||||
|
||||
/* NuttX callback functions */
|
||||
|
||||
static int lpc54_eth_ifup(FAR struct net_driver_s *dev);
|
||||
static int lpc54_eth_ifdown(FAR struct net_driver_s *dev);
|
||||
static int lpc54_eth_ifup(struct net_driver_s *dev);
|
||||
static int lpc54_eth_ifdown(struct net_driver_s *dev);
|
||||
|
||||
static void lpc54_eth_txavail_work(FAR void *arg);
|
||||
static int lpc54_eth_txavail(FAR struct net_driver_s *dev);
|
||||
static void lpc54_eth_txavail_work(void *arg);
|
||||
static int lpc54_eth_txavail(struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int lpc54_eth_addmac(FAR struct net_driver_s *dev,
|
||||
FAR const uint8_t *mac);
|
||||
static int lpc54_eth_addmac(struct net_driver_s *dev,
|
||||
const uint8_t *mac);
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int lpc54_eth_rmmac(FAR struct net_driver_s *dev,
|
||||
FAR const uint8_t *mac);
|
||||
static int lpc54_eth_rmmac(struct net_driver_s *dev,
|
||||
const uint8_t *mac);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
static void lpc54_eth_ipv6multicast(FAR struct lpc54_ethdriver_s *priv);
|
||||
static void lpc54_eth_ipv6multicast(struct lpc54_ethdriver_s *priv);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
static int lpc54_eth_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
static int lpc54_eth_ioctl(struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
#endif
|
||||
|
||||
/* Packet buffers */
|
||||
|
||||
static void lpc54_pktbuf_initialize(struct lpc54_ethdriver_s *priv);
|
||||
static inline uint32_t *lpc54_pktbuf_alloc(struct lpc54_ethdriver_s *priv);
|
||||
static inline void lpc54_pktbuf_free(struct lpc54_ethdriver_s *priv,
|
||||
uint32_t *pktbuf);
|
||||
|
||||
/* DMA descriptors */
|
||||
|
||||
static void lpc54_txdesc_initialize(struct lpc54_ethdriver_s *priv,
|
||||
unsigned int chan, struct enet_txdesc_s *txdesc,
|
||||
unsigned int ndesc);
|
||||
static void lpc54_rxdesc_initialize(struct lpc54_ethdriver_s *priv,
|
||||
unsigned int chan, struct enet_txdesc_s *rxdesc,
|
||||
unsigned int ndesc);
|
||||
static void lpc54_desc_initialize(struct lpc54_ethdriver_s *priv);
|
||||
|
||||
/* Initialization/PHY control */
|
||||
|
||||
static void lpc54_set_csrdiv(void);
|
||||
static uint16_t lpc54_phy_read(FAR struct lpc54_ethdriver_s *priv,
|
||||
static uint16_t lpc54_phy_read(struct lpc54_ethdriver_s *priv,
|
||||
uint8_t phyreg);
|
||||
static void lpc54_phy_write(FAR struct lpc54_ethdriver_s *priv,
|
||||
static void lpc54_phy_write(struct lpc54_ethdriver_s *priv,
|
||||
uint8_t phyreg, uint16_t phyval);
|
||||
static inline bool lpc54_phy_linkstatus(ENET_Type *base);
|
||||
static int lpc54_phy_autonegotiate(FAR struct lpc54_ethdriver_s *priv);
|
||||
static int lpc54_phy_reset(FAR struct lpc54_ethdriver_s *priv);
|
||||
static int lpc54_phy_autonegotiate(struct lpc54_ethdriver_s *priv);
|
||||
static int lpc54_phy_reset(struct lpc54_ethdriver_s *priv);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@ -268,7 +333,7 @@ static int lpc54_phy_reset(FAR struct lpc54_ethdriver_s *priv);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_eth_transmit(FAR struct lpc54_ethdriver_s *priv)
|
||||
static int lpc54_eth_transmit(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
/* Verify that the hardware is ready to send another packet. If we get
|
||||
* here, then we are committed to sending a packet; Higher level logic
|
||||
@ -317,9 +382,9 @@ static int lpc54_eth_transmit(FAR struct lpc54_ethdriver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_eth_txpoll(FAR struct net_driver_s *dev)
|
||||
static int lpc54_eth_txpoll(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private;
|
||||
|
||||
/* If the polling resulted in data that should be sent out on the network,
|
||||
* the field d_len is set to a value > 0.
|
||||
@ -382,7 +447,7 @@ static int lpc54_eth_txpoll(FAR struct net_driver_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_eth_receive(FAR struct lpc54_ethdriver_s *priv)
|
||||
static void lpc54_eth_receive(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -527,7 +592,7 @@ static void lpc54_eth_receive(FAR struct lpc54_ethdriver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_eth_txdone(FAR struct lpc54_ethdriver_s *priv)
|
||||
static void lpc54_eth_txdone(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
int delay;
|
||||
|
||||
@ -570,9 +635,9 @@ static void lpc54_eth_txdone(FAR struct lpc54_ethdriver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_eth_interrupt_work(FAR void *arg)
|
||||
static void lpc54_eth_interrupt_work(void *arg)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)arg;
|
||||
|
||||
/* Lock the network and serialize driver operations if necessary.
|
||||
* NOTE: Serialization is only required in the case where the driver work
|
||||
@ -614,7 +679,7 @@ static void lpc54_eth_interrupt_work(FAR void *arg)
|
||||
* Name: lpc54_eth_interrupt
|
||||
*
|
||||
* Description:
|
||||
* Hardware interrupt handler
|
||||
* Ethernet interrupt handler
|
||||
*
|
||||
* Parameters:
|
||||
* irq - Number of the IRQ that generated the interrupt
|
||||
@ -623,13 +688,11 @@ static void lpc54_eth_interrupt_work(FAR void *arg)
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
* Assumptions:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_eth_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||
static int lpc54_eth_interrupt(int irq, void *context, void *arg)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)arg;
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
@ -658,6 +721,50 @@ static int lpc54_eth_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_pmt_interrupt
|
||||
*
|
||||
* Description:
|
||||
* Ethernet power management interrupt handler
|
||||
*
|
||||
* Parameters:
|
||||
* irq - Number of the IRQ that generated the interrupt
|
||||
* context - Interrupt register state save info (architecture-specific)
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if 0 /* Not used */
|
||||
static int lpc54_pmt_interrupt(int irq, void *context, void *arg)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_mac_interrupt
|
||||
*
|
||||
* Description:
|
||||
* Ethernet MAC interrupt handler
|
||||
*
|
||||
* Parameters:
|
||||
* irq - Number of the IRQ that generated the interrupt
|
||||
* context - Interrupt register state save info (architecture-specific)
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#if 0 /* Not used */
|
||||
static int lpc54_mac_interrupt(int irq, void *context, void *arg)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_eth_txtimeout_work
|
||||
*
|
||||
@ -675,9 +782,9 @@ static int lpc54_eth_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_eth_txtimeout_work(FAR void *arg)
|
||||
static void lpc54_eth_txtimeout_work(void *arg)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)arg;
|
||||
|
||||
/* Lock the network and serialize driver operations if necessary.
|
||||
* NOTE: Serialization is only required in the case where the driver work
|
||||
@ -721,7 +828,7 @@ static void lpc54_eth_txtimeout_work(FAR void *arg)
|
||||
|
||||
static void lpc54_eth_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)arg;
|
||||
|
||||
/* Disable further Ethernet interrupts. This will prevent some race
|
||||
* conditions with interrupt work. There is still a potential race
|
||||
@ -752,7 +859,7 @@ static void lpc54_eth_txtimeout_expiry(int argc, wdparm_t arg, ...)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc54_eth_poll_process(FAR struct lpc54_ethdriver_s *priv)
|
||||
static inline void lpc54_eth_poll_process(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
#warning Missing logic
|
||||
}
|
||||
@ -774,9 +881,9 @@ static inline void lpc54_eth_poll_process(FAR struct lpc54_ethdriver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_eth_poll_work(FAR void *arg)
|
||||
static void lpc54_eth_poll_work(void *arg)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)arg;
|
||||
|
||||
/* Lock the network and serialize driver operations if necessary.
|
||||
* NOTE: Serialization is only required in the case where the driver work
|
||||
@ -827,7 +934,7 @@ static void lpc54_eth_poll_work(FAR void *arg)
|
||||
|
||||
static void lpc54_eth_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)arg;
|
||||
|
||||
/* Schedule to perform the interrupt processing on the worker thread. */
|
||||
|
||||
@ -851,10 +958,10 @@ static void lpc54_eth_poll_expiry(int argc, wdparm_t arg, ...)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_eth_ifup(FAR struct net_driver_s *dev)
|
||||
static int lpc54_eth_ifup(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private;
|
||||
FAR uint8_t *mptr;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private;
|
||||
uint8_t *mptr;
|
||||
uintptr_t base;
|
||||
uint32_t regval;
|
||||
uint32_t burstlen;
|
||||
@ -983,7 +1090,7 @@ static int lpc54_eth_ifup(FAR struct net_driver_s *dev)
|
||||
* device structure:
|
||||
*/
|
||||
|
||||
mptr = (FAR uint8_t *)priv->eth_dev.d_mac.ether.ether_addr_octet;
|
||||
mptr = (uint8_t *)priv->eth_dev.d_mac.ether.ether_addr_octet;
|
||||
regval = ((uint32_t)mptr[3] << 24) | ((uint32_t)mptr[2] << 16) |
|
||||
((uint32_t)mptr[1] << 8) | ((uint32_t)mptr[0]);
|
||||
putreg32(regval, LPC54_ETH_MAC_ADDR_LOW);
|
||||
@ -1016,7 +1123,7 @@ static int lpc54_eth_ifup(FAR struct net_driver_s *dev)
|
||||
putreg32(regval, LPC54_ETH_MAC_TX_FLOW_CTRL_Q1);
|
||||
#endif
|
||||
|
||||
/* Set the 1us tick counter*/
|
||||
/* Set the 1uS tick counter*/
|
||||
|
||||
regval = ETH_MAC_1US_TIC_COUNTR(BOARD_MAIN_CLK / USEC_PER_SEC);
|
||||
putreg32(regval, LPC54_ETH_MAC_1US_TIC_COUNTR);
|
||||
@ -1047,6 +1154,9 @@ static int lpc54_eth_ifup(FAR struct net_driver_s *dev)
|
||||
|
||||
putreg32(regval, LPC54_ETH_MAC_CONFIG);
|
||||
|
||||
/* Set the SYSCON sideband flow control for each channel (see UserManual) */
|
||||
#warning Missing logic
|
||||
|
||||
/* Enable Rx queues */
|
||||
|
||||
regval = ETH_MAC_RXQ_CTRL0_RXQ0EN_ENABLE | ETH_MAC_RXQ_CTRL0_RXQ1EN_ENABLE;
|
||||
@ -1060,21 +1170,39 @@ static int lpc54_eth_ifup(FAR struct net_driver_s *dev)
|
||||
|
||||
putreg32(0, LPC54_ETH_MAC_INTR_EN);
|
||||
|
||||
/* Initialize descriptors */
|
||||
#warning Missing logic
|
||||
|
||||
/* Activate Rx and Tx */
|
||||
#warning Missing logic
|
||||
|
||||
/* Set the sideband flow control for each channel (see UserManual) */
|
||||
#warning Missing logic
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
/* Set up IPv6 multicast address filtering */
|
||||
|
||||
lpc54_eth_ipv6multicast(priv);
|
||||
#endif
|
||||
|
||||
/* Initialize packet buffers */
|
||||
|
||||
lpc54_pktbuf_initialize(priv);
|
||||
|
||||
/* Initialize descriptors */
|
||||
|
||||
lpc54_desc_initialize(priv);
|
||||
|
||||
/* Activate DMA on channel 0 */
|
||||
|
||||
regval = getreg32(LPC54_ETH_DMACH_RX_CTRL(0));
|
||||
regval |= ETH_DMACH_RX_CTRL_SR;
|
||||
putreg32(regval, LPC54_ETH_DMACH_RX_CTRL(0));
|
||||
|
||||
regval = getreg32(LPC54_ETH_DMACH_TX_CTRL(0));
|
||||
regval |= ETH_DMACH_TX_CTRL_ST;
|
||||
putreg32(regval, LPC54_ETH_DMACH_TX_CTRL(0));
|
||||
|
||||
/* Then enable the Rx/Tx */
|
||||
|
||||
regval = getreg32(LPC54_ETH_MAC_CONFIG);
|
||||
regval |= ETH_MAC_CONFIG_RE;
|
||||
putreg32(regval, LPC54_ETH_MAC_CONFIG);
|
||||
|
||||
regval |= ETH_MAC_CONFIG_TE;
|
||||
putreg32(regval, LPC54_ETH_MAC_CONFIG);
|
||||
|
||||
/* Set and activate a timer process */
|
||||
|
||||
(void)wd_start(priv->eth_txpoll, LPC54_WDDELAY, lpc54_eth_poll_expiry, 1,
|
||||
@ -1103,9 +1231,9 @@ static int lpc54_eth_ifup(FAR struct net_driver_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_eth_ifdown(FAR struct net_driver_s *dev)
|
||||
static int lpc54_eth_ifdown(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private;
|
||||
irqstate_t flags;
|
||||
uint32_t regval;
|
||||
|
||||
@ -1174,9 +1302,9 @@ static int lpc54_eth_ifdown(FAR struct net_driver_s *dev)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_eth_txavail_work(FAR void *arg)
|
||||
static void lpc54_eth_txavail_work(void *arg)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)arg;
|
||||
|
||||
/* Lock the network and serialize driver operations if necessary.
|
||||
* NOTE: Serialization is only required in the case where the driver work
|
||||
@ -1220,9 +1348,9 @@ static void lpc54_eth_txavail_work(FAR void *arg)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_eth_txavail(FAR struct net_driver_s *dev)
|
||||
static int lpc54_eth_txavail(struct net_driver_s *dev)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private;
|
||||
|
||||
/* Is our single work structure available? It may not be if there are
|
||||
* pending interrupt actions and we will have to ignore the Tx
|
||||
@ -1256,9 +1384,9 @@ static int lpc54_eth_txavail(FAR struct net_driver_s *dev)
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int lpc54_eth_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
static int lpc54_eth_addmac(struct net_driver_s *dev, const uint8_t *mac)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private;
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
#warning Missing logic
|
||||
@ -1284,9 +1412,9 @@ static int lpc54_eth_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int lpc54_eth_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
static int lpc54_eth_rmmac(struct net_driver_s *dev, const uint8_t *mac)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private;
|
||||
|
||||
/* Add the MAC address to the hardware multicast routing table */
|
||||
#warning Missing logic
|
||||
@ -1310,9 +1438,9 @@ static int lpc54_eth_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
static void lpc54_eth_ipv6multicast(FAR struct lpc54_ethdriver_s *priv)
|
||||
static void lpc54_eth_ipv6multicast(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
FAR struct net_driver_s *dev;
|
||||
struct net_driver_s *dev;
|
||||
uint16_t tmp16;
|
||||
uint8_t mac[6];
|
||||
|
||||
@ -1386,10 +1514,10 @@ static void lpc54_eth_ipv6multicast(FAR struct lpc54_ethdriver_s *priv)
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
static int lpc54_eth_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg)
|
||||
static int lpc54_eth_ioctl(struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private;
|
||||
struct lpc54_ethdriver_s *priv = (struct lpc54_ethdriver_s *)dev->d_private;
|
||||
int ret;
|
||||
|
||||
/* Decode and dispatch the driver-specific IOCTL command */
|
||||
@ -1429,6 +1557,241 @@ static int lpc54_eth_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_pktbuf_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize packet buffers my placing all of the pre-allocated packet
|
||||
* buffers into a free list.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_pktbuf_initialize(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
uint32_t *pktbuf;
|
||||
int i;
|
||||
|
||||
for (i = 0, pktbuf = g_prealloc_buffers;
|
||||
i < LPC54_NBUFFERS;
|
||||
i++, pktbuf += LPC54_BUFFER_WORDS)
|
||||
{
|
||||
sq_addlast((sq_entry_t *)pktbuf, priv->ð_freebuf);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_pktbuf_alloc
|
||||
*
|
||||
* Description:
|
||||
* Allocate one packet buffer by removing it from the free list.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* A pointer to the allocated packet buffer on succes; NULL is returned if
|
||||
* there are no available packet buffers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint32_t *lpc54_pktbuf_alloc(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
return (uint32_t *)sq_remfirst(priv->ð_freebuf);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_pktbuf_free
|
||||
*
|
||||
* Description:
|
||||
* Allocate one packet buffer by removing it from the free list.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* pktbuf - The packet buffer to be freed
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void lpc54_pktbuf_free(struct lpc54_ethdriver_s *priv,
|
||||
uint32_t *pktbuf)
|
||||
{
|
||||
sq_addlast((sq_entry_t *)pktbuf, priv->ð_freebuf);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_txdesc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize one Tx descriptor ring.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* chan - Channel being initialized
|
||||
* txdesc - An array of pre-allocated Tx descriptors
|
||||
* ndesc - The number of descriptors in the array
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_txdesc_initialize(struct lpc54_ethdriver_s *priv,
|
||||
unsigned int chan,
|
||||
struct enet_txdesc_s *txdesc,
|
||||
unsigned int ndesc);
|
||||
{
|
||||
uint32_t control;
|
||||
uint32_t regval;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(ndesc >= LPC54_MIN_RINGLEN && ndesc <= LPC54_MAX_RINGLEN);
|
||||
|
||||
/* Set the word-aligned Tx descriptor start/tail pointers. */
|
||||
|
||||
regval = (uint32_t)txdesc;
|
||||
putreg32(regval, LPC54_ETH_DMACH_TXDESC_LIST_ADDR(ch));
|
||||
|
||||
regval += ndesc * sizeof(struct enet_txdesc_s);
|
||||
putreg32(regval, LPC54_ETH_DMACH_TXDESC_TAIL_PTR(ch));
|
||||
|
||||
/* Set the Tx ring length */
|
||||
|
||||
regval = ETH_DMACH_TXDESC_RING_LENGTH(ndesc);
|
||||
putreg32(regval, LPC54_ETH_DMACH_TXDESC_RING_LENGTH(ch));
|
||||
|
||||
/* Inituialize the Tx desriptors . */
|
||||
|
||||
for (i = 0; i < ndesc; i++, txdesc++)
|
||||
{
|
||||
txdesc->buffer1 = 0;
|
||||
txdesc->buffer2 = 0;
|
||||
txdesc->buflen = ETH_TXDES2_IOC;
|
||||
txdesc->ctrlstat = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_rxdesc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize one Rx descriptor ring.
|
||||
*
|
||||
* Parameters:
|
||||
* priv - Reference to the driver state structure
|
||||
* chan - Channel being initialized
|
||||
* txdesc - An array of pre-allocated Tx descriptors
|
||||
* ndesc - The number of descriptors in the array
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_rxdesc_initialize(struct lpc54_ethdriver_s *priv,
|
||||
unsigned int chan,
|
||||
struct enet_txdesc_s *rxdesc,
|
||||
unsigned int ndesc)
|
||||
{
|
||||
uint32_t regval;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
DEBUGASSERT(ndesc >= LPC54_MIN_RINGLEN && ndesc <= LPC54_MAX_RINGLEN);
|
||||
|
||||
#define LPC54_ETH_DMACH_RXDESC_RING_LENGTH(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH0_RXDESC_RING_LENGTH_OFFSET)
|
||||
|
||||
/* Set the word-aligned Rx descriptor start/tail pointers. */
|
||||
|
||||
regval = (uint32_t)rxdesc;
|
||||
putreg32(regval, LPC54_ETH_DMACH_RXDESC_LIST_ADDR(chan));
|
||||
|
||||
regval += ndesc * sizeof(struct enet_rxdesc_s);
|
||||
putreg32(regval, LPC54_ETH_DMACH_RXDESC_TAIL_PTR(chan));
|
||||
|
||||
/* Set the Rx ring length */
|
||||
|
||||
regval = ETH_DMACH_RXDESC_RING_LENGTH(ndesc);
|
||||
putreg32(regval, LPC54_ETH_DMACH_RXDESC_RING_LENGTH(ch));
|
||||
|
||||
/* Set the receive buffer size (in words) in the Rx control register */
|
||||
|
||||
regval = getreg32(LPC54_ETH_DMACH_RX_CTRL(chan));
|
||||
regval &= ~ETH_DMACH_RX_CTRL_RBSZ_MASK;
|
||||
regval |= ETH_DMACH_RX_CTRL_RBSZ(LPC54_BUFFER_SIZE >> 2);
|
||||
putreg32(regval, LPC54_ETH_DMACH_RX_CTRL(chan));
|
||||
|
||||
/* Initialize the Rx descriptor ring. */
|
||||
|
||||
regval = ETH_RXDES3_BUF1V | ETH_RXDES3_IOC | ETH_RXDES3_OWN;
|
||||
#ifdef CONFIG_LPC54_ETH_RX_DOUBLEBUFFER
|
||||
regval |= ETH_RXDES3_BUF2V;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ndesc; i++, rxdesc++)
|
||||
{
|
||||
/* Allocate the first Rx packet buffer */
|
||||
|
||||
rxdesc->buffer1 = (uint32_t)lpc54_pktbuf_alloc(priv);
|
||||
DEBUGASSERT(rxdesc->buffer1 != NULL);
|
||||
priv->eth_rxbuffers1[i] = rxdesc->buffer1;
|
||||
|
||||
#ifdef CONFIG_LPC54_ETH_RX_DOUBLEBUFFER
|
||||
/* Allocate the second Rx packet buffer */
|
||||
|
||||
rxdesc->buffer2 = (uint32_t)lpc54_pktbuf_alloc(priv);
|
||||
DEBUGASSERT(rxdesc->buffer2 != NULL);
|
||||
priv->eth_rxbuffers2[i] = rxdesc->buffer2;
|
||||
|
||||
#else
|
||||
/* The second buffer is not used */
|
||||
|
||||
rxdesc->buffer2 = 0;
|
||||
#endif
|
||||
|
||||
/* Set the valid and DMA own flag.*/
|
||||
|
||||
rxdesc->ctrl = regval;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_desc_initialize
|
||||
*
|
||||
* Description:
|
||||
* Set the CSR clock divider. The MDC clock derives from the divided down
|
||||
* CSR clock (aka core clock or main clock).
|
||||
*
|
||||
* Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_desc_initialize(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
/* Initialize channel 0 descriptors */
|
||||
|
||||
lpc54_txdesc_initialize(priv, 0, g_ch0_txdesc, CONFIG_LPC54_ETH_NTXDESC0);
|
||||
lpc54_rxdesc_initialize(priv, 0, g_ch0_rxdesc, CONFIG_LPC54_ETH_NRXDESC0);
|
||||
|
||||
#ifdef CONFIG_LPC54_ETH_MULTIQUEUE
|
||||
/* Initialize channel 1 descriptors */
|
||||
|
||||
lpc54_txdesc_initialize(priv, 1, g_ch1_txdesc, CONFIG_LPC54_ETH_NTXDESC1);
|
||||
lpc54_rxdesc_initialize(priv, 0, g_ch1_rxdesc, CONFIG_LPC54_ETH_NRXDESC1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lpc54_set_csrdiv
|
||||
*
|
||||
@ -1487,7 +1850,7 @@ static void lpc54_set_csrdiv(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint16_t lpc54_phy_read(FAR struct lpc54_ethdriver_s *priv,
|
||||
static uint16_t lpc54_phy_read(struct lpc54_ethdriver_s *priv,
|
||||
uint8_t phyreg)
|
||||
{
|
||||
uint32_t regval = base->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_CR_MASK;
|
||||
@ -1530,7 +1893,7 @@ static uint16_t lpc54_phy_read(FAR struct lpc54_ethdriver_s *priv,
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lpc54_phy_write(FAR struct lpc54_ethdriver_s *priv,
|
||||
static void lpc54_phy_write(struct lpc54_ethdriver_s *priv,
|
||||
uint8_t phyreg, uint16_t phyval)
|
||||
{
|
||||
uint32_t regval = base->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_CR_MASK;
|
||||
@ -1594,7 +1957,7 @@ static inline bool lpc54_phy_linkstatus(ENET_Type *base)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_phy_autonegotiate(FAR struct lpc54_ethdriver_s *priv)
|
||||
static int lpc54_phy_autonegotiate(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
volatile int32_t timeout;
|
||||
uint16_t phyid1;
|
||||
@ -1672,7 +2035,7 @@ static int lpc54_phy_autonegotiate(FAR struct lpc54_ethdriver_s *priv)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lpc54_phy_reset(FAR struct lpc54_ethdriver_s *priv)
|
||||
static int lpc54_phy_reset(struct lpc54_ethdriver_s *priv)
|
||||
{
|
||||
volatile int32_t timeout;
|
||||
uint16_t phyid1;
|
||||
@ -1737,14 +2100,14 @@ static int lpc54_phy_reset(FAR struct lpc54_ethdriver_s *priv)
|
||||
|
||||
int up_netinitialize(int intf)
|
||||
{
|
||||
FAR struct lpc54_ethdriver_s *priv;
|
||||
struct lpc54_ethdriver_s *priv;
|
||||
|
||||
/* Get the interface structure associated with this interface number. */
|
||||
|
||||
DEBUGASSERT(intf == 0);
|
||||
priv = &g_ethdriver;
|
||||
|
||||
/* Attach the IRQ to the driver */
|
||||
/* Attach the three Ethernet-related IRQs to the handlers */
|
||||
|
||||
if (irq_attach(LPC54_IRQ_ETHERNET, lpc54_eth_interrupt, priv))
|
||||
{
|
||||
@ -1754,6 +2117,22 @@ int up_netinitialize(int intf)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (irq_attach(LPC54_IRQ_ETHERNETPMT, lpc54_pmt_interrupt, priv))
|
||||
{
|
||||
/* We could not attach the ISR to the interrupt */
|
||||
|
||||
nerr("ERROR: irq_attach for PMTfailed\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (irq_attach(LPC54_IRQ_ETHERNETMACLP, lpc54_mac_interrupt, priv))
|
||||
{
|
||||
/* We could not attach the ISR to the interrupt */
|
||||
|
||||
nerr("ERROR: irq_attach for MAC failed\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Initialize the driver structure */
|
||||
|
||||
memset(priv, 0, sizeof(struct lpc54_ethdriver_s));
|
||||
@ -1768,7 +2147,7 @@ int up_netinitialize(int intf)
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
priv->eth_dev.d_ioctl = lpc54_eth_ioctl; /* Handle network IOCTL commands */
|
||||
#endif
|
||||
priv->eth_dev.d_private = (FAR void *)g_ethdriver; /* Used to recover private state from dev */
|
||||
priv->eth_dev.d_private = (void *)g_ethdriver; /* Used to recover private state from dev */
|
||||
|
||||
/* Create a watchdog for timing polling for and timing of transmisstions */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user