NXP LPC1768 Ethernet driver for lwip and CMSIS-RTOS

Dependents:   EthernetInterface EthernetInterface EthernetInterface_RSF EthernetInterface ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed 5, the networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of the NXP LPC port of the Lightweight TCP/IP Stack

Copyright(C) 2011, NXP Semiconductor
All rights reserved.

Software that is described herein is for illustrative purposes only
which provides customers with programming information regarding the
products. This software is supplied "AS IS" without any warranties.
NXP Semiconductors assumes no responsibility or liability for the
use of the software, conveys no license or title under any patent,
copyright, or mask work right to the product. NXP Semiconductors
reserves the right to make changes in the software without
notification. NXP Semiconductors also make no representation or
warranty that such application will be suitable for the specified
use without further testing or modification.
Committer:
mbed_official
Date:
Wed Jun 11 09:30:25 2014 +0100
Revision:
15:82aaaa2f4d5c
Parent:
12:8722e4b223d8
Child:
16:eb4a98a54ad0
Synchronized with git revision ff65c63a80830b0c36f91f13488d79bafef442e6

Full URL: https://github.com/mbedmicro/mbed/commit/ff65c63a80830b0c36f91f13488d79bafef442e6/

Add support for remote CAN frames on LPC11CXX

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 10:ab9330955226 1 #include "lwip/opt.h"
mbed_official 10:ab9330955226 2 #include "lwip/sys.h"
mbed_official 10:ab9330955226 3 #include "lwip/def.h"
mbed_official 10:ab9330955226 4 #include "lwip/mem.h"
mbed_official 10:ab9330955226 5 #include "lwip/pbuf.h"
mbed_official 10:ab9330955226 6 #include "lwip/stats.h"
mbed_official 10:ab9330955226 7 #include "lwip/snmp.h"
mbed_official 10:ab9330955226 8 #include "lwip/tcpip.h"
mbed_official 10:ab9330955226 9 #include "netif/etharp.h"
mbed_official 10:ab9330955226 10 #include "netif/ppp_oe.h"
mbed_official 10:ab9330955226 11
mbed_official 10:ab9330955226 12 #include "eth_arch.h"
mbed_official 10:ab9330955226 13 #include "sys_arch.h"
mbed_official 10:ab9330955226 14
mbed_official 10:ab9330955226 15 #include "fsl_enet_driver.h"
mbed_official 10:ab9330955226 16 #include "fsl_enet_hal.h"
mbed_official 10:ab9330955226 17 #include "fsl_device_registers.h"
mbed_official 10:ab9330955226 18 #include "fsl_phy_driver.h"
mbed_official 10:ab9330955226 19 #include "fsl_interrupt_manager.h"
mbed_official 10:ab9330955226 20 #include "k64f_emac_config.h"
mbed_official 10:ab9330955226 21 #include <ctype.h>
mbed_official 10:ab9330955226 22 #include <stdio.h>
mbed_official 10:ab9330955226 23 #include <string.h>
mbed_official 10:ab9330955226 24 #include <stdlib.h>
mbed_official 10:ab9330955226 25
mbed_official 10:ab9330955226 26 #include "mbed_interface.h"
mbed_official 10:ab9330955226 27
mbed_official 10:ab9330955226 28 extern IRQn_Type enet_irq_ids[HW_ENET_INSTANCE_COUNT][FSL_FEATURE_ENET_INTERRUPT_COUNT];
mbed_official 10:ab9330955226 29 extern uint8_t enetIntMap[kEnetIntNum];
mbed_official 15:82aaaa2f4d5c 30 extern void *enetIfHandle;
mbed_official 10:ab9330955226 31
mbed_official 10:ab9330955226 32 /********************************************************************************
mbed_official 10:ab9330955226 33 * Internal data
mbed_official 10:ab9330955226 34 ********************************************************************************/
mbed_official 10:ab9330955226 35
mbed_official 10:ab9330955226 36 extern void k64f_init_eth_hardware(void);
mbed_official 10:ab9330955226 37
mbed_official 10:ab9330955226 38 /* K64F EMAC driver data structure */
mbed_official 10:ab9330955226 39 struct k64f_enetdata {
mbed_official 10:ab9330955226 40 struct netif *netif; /**< Reference back to LWIP parent netif */
mbed_official 10:ab9330955226 41 sys_sem_t RxReadySem; /**< RX packet ready semaphore */
mbed_official 10:ab9330955226 42 sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
mbed_official 10:ab9330955226 43 sys_mutex_t TXLockMutex; /**< TX critical section mutex */
mbed_official 10:ab9330955226 44 sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
mbed_official 10:ab9330955226 45 volatile u32_t rx_free_descs; /**< Count of free RX descriptors */
mbed_official 10:ab9330955226 46 struct pbuf *rxb[ENET_RX_RING_LEN]; /**< RX pbuf pointer list, zero-copy mode */
mbed_official 10:ab9330955226 47 uint8_t *rx_desc_start_addr; /**< RX descriptor start address */
mbed_official 10:ab9330955226 48 uint8_t *tx_desc_start_addr; /**< TX descriptor start address */
mbed_official 10:ab9330955226 49 uint8_t tx_consume_index, tx_produce_index; /**< TX buffers ring */
mbed_official 10:ab9330955226 50 uint8_t rx_fill_index; /**< RX ring fill index */
mbed_official 10:ab9330955226 51 struct pbuf *txb[ENET_TX_RING_LEN]; /**< TX pbuf pointer list, zero-copy mode */
mbed_official 10:ab9330955226 52 void *txb_aligned[ENET_TX_RING_LEN]; /**< TX aligned buffers (if needed) */
mbed_official 10:ab9330955226 53 };
mbed_official 10:ab9330955226 54
mbed_official 10:ab9330955226 55 static struct k64f_enetdata k64f_enetdata;
mbed_official 10:ab9330955226 56
mbed_official 10:ab9330955226 57 static enet_dev_if_t enetDevIf[HW_ENET_INSTANCE_COUNT];
mbed_official 10:ab9330955226 58 static enet_mac_config_t g_enetMacCfg[HW_ENET_INSTANCE_COUNT] =
mbed_official 10:ab9330955226 59 {
mbed_official 10:ab9330955226 60 {
mbed_official 10:ab9330955226 61 ENET_ETH_MAX_FLEN , /*!< enet receive buffer size*/
mbed_official 10:ab9330955226 62 ENET_RX_LARGE_BUFFER_NUM, /*!< enet large receive buffer number*/
mbed_official 10:ab9330955226 63 ENET_RX_RING_LEN, /*!< enet receive bd number*/
mbed_official 10:ab9330955226 64 ENET_TX_RING_LEN, /*!< enet transmit bd number*/
mbed_official 10:ab9330955226 65 {0}, /*!< enet mac address*/
mbed_official 10:ab9330955226 66 kEnetCfgRmii, /*!< enet rmii interface*/
mbed_official 10:ab9330955226 67 kEnetCfgSpeed100M, /*!< enet rmii 100M*/
mbed_official 10:ab9330955226 68 kEnetCfgFullDuplex, /*!< enet rmii Full- duplex*/
mbed_official 10:ab9330955226 69 /*!< enet mac control flag recommended to use enet_mac_control_flag_t
mbed_official 10:ab9330955226 70 we send frame with crc so receive crc forward for data length check test*/
mbed_official 10:ab9330955226 71 kEnetRxCrcFwdEnable | kEnetRxFlowControlEnable,
mbed_official 10:ab9330955226 72 true, /*!< enet txaccelerator enabled*/
mbed_official 10:ab9330955226 73 true, /*!< enet rxaccelerator enabled*/
mbed_official 10:ab9330955226 74 false, /*!< enet store and forward*/
mbed_official 10:ab9330955226 75 {false, false, true, false, true}, /*!< enet rxaccelerator config*/
mbed_official 10:ab9330955226 76 {false, false, true}, /*!< enet txaccelerator config*/
mbed_official 10:ab9330955226 77 true, /*!< vlan frame support*/
mbed_official 10:ab9330955226 78 true, /*!< phy auto discover*/
mbed_official 10:ab9330955226 79 ENET_MII_CLOCK, /*!< enet MDC clock*/
mbed_official 10:ab9330955226 80 },
mbed_official 10:ab9330955226 81 };
mbed_official 10:ab9330955226 82
mbed_official 10:ab9330955226 83 static enet_phy_config_t g_enetPhyCfg[HW_ENET_INSTANCE_COUNT] =
mbed_official 10:ab9330955226 84 {
mbed_official 10:ab9330955226 85 {0, false}
mbed_official 10:ab9330955226 86 };
mbed_official 10:ab9330955226 87
mbed_official 10:ab9330955226 88 /** \brief Driver transmit and receive thread priorities
mbed_official 10:ab9330955226 89 *
mbed_official 10:ab9330955226 90 * Thread priorities for receive thread and TX cleanup thread. Alter
mbed_official 10:ab9330955226 91 * to prioritize receive or transmit bandwidth. In a heavily loaded
mbed_official 10:ab9330955226 92 * system or with LEIP_DEBUG enabled, the priorities might be better
mbed_official 10:ab9330955226 93 * the same. */
mbed_official 10:ab9330955226 94 #define RX_PRIORITY (osPriorityNormal)
mbed_official 10:ab9330955226 95 #define TX_PRIORITY (osPriorityNormal)
mbed_official 10:ab9330955226 96 #define PHY_PRIORITY (osPriorityNormal)
mbed_official 10:ab9330955226 97
mbed_official 10:ab9330955226 98 /** \brief Debug output formatter lock define
mbed_official 10:ab9330955226 99 *
mbed_official 10:ab9330955226 100 * When using FreeRTOS and with LWIP_DEBUG enabled, enabling this
mbed_official 10:ab9330955226 101 * define will allow RX debug messages to not interleave with the
mbed_official 10:ab9330955226 102 * TX messages (so they are actually readable). Not enabling this
mbed_official 10:ab9330955226 103 * define when the system is under load will cause the output to
mbed_official 10:ab9330955226 104 * be unreadable. There is a small tradeoff in performance for this
mbed_official 10:ab9330955226 105 * so use it only for debug. */
mbed_official 10:ab9330955226 106 //#define LOCK_RX_THREAD
mbed_official 10:ab9330955226 107
mbed_official 10:ab9330955226 108 /** \brief Signal used for ethernet ISR to signal packet_rx() thread.
mbed_official 10:ab9330955226 109 */
mbed_official 10:ab9330955226 110 #define RX_SIGNAL 1
mbed_official 10:ab9330955226 111
mbed_official 10:ab9330955226 112 // K64F-specific macros
mbed_official 10:ab9330955226 113 #define RX_PBUF_AUTO_INDEX (-1)
mbed_official 10:ab9330955226 114
mbed_official 10:ab9330955226 115 /********************************************************************************
mbed_official 10:ab9330955226 116 * Buffer management
mbed_official 10:ab9330955226 117 ********************************************************************************/
mbed_official 10:ab9330955226 118
mbed_official 10:ab9330955226 119 /** \brief Queues a pbuf into the RX descriptor list
mbed_official 10:ab9330955226 120 *
mbed_official 10:ab9330955226 121 * \param[in] k64f_enet Pointer to the drvier data structure
mbed_official 10:ab9330955226 122 * \param[in] p Pointer to pbuf to queue
mbed_official 10:ab9330955226 123 * \param[in] bidx Index to queue into
mbed_official 10:ab9330955226 124 */
mbed_official 10:ab9330955226 125 static void k64f_rxqueue_pbuf(struct k64f_enetdata *k64f_enet, struct pbuf *p, int bidx)
mbed_official 10:ab9330955226 126 {
mbed_official 10:ab9330955226 127 enet_bd_struct_t *start = (enet_bd_struct_t *)k64f_enet->rx_desc_start_addr;
mbed_official 10:ab9330955226 128 int idx;
mbed_official 10:ab9330955226 129
mbed_official 10:ab9330955226 130 /* Get next free descriptor index */
mbed_official 10:ab9330955226 131 if (bidx == RX_PBUF_AUTO_INDEX)
mbed_official 10:ab9330955226 132 idx = k64f_enet->rx_fill_index;
mbed_official 10:ab9330955226 133 else
mbed_official 10:ab9330955226 134 idx = bidx;
mbed_official 10:ab9330955226 135
mbed_official 10:ab9330955226 136 /* Setup descriptor and clear statuses */
mbed_official 10:ab9330955226 137 enet_hal_init_rxbds(start + idx, (uint8_t*)p->payload, idx == ENET_RX_RING_LEN - 1);
mbed_official 10:ab9330955226 138
mbed_official 10:ab9330955226 139 /* Save pbuf pointer for push to network layer later */
mbed_official 10:ab9330955226 140 k64f_enet->rxb[idx] = p;
mbed_official 10:ab9330955226 141
mbed_official 10:ab9330955226 142 /* Wrap at end of descriptor list */
mbed_official 10:ab9330955226 143 idx = (idx + 1) % ENET_RX_RING_LEN;
mbed_official 10:ab9330955226 144
mbed_official 10:ab9330955226 145 /* Queue descriptor(s) */
mbed_official 10:ab9330955226 146 k64f_enet->rx_free_descs -= 1;
mbed_official 10:ab9330955226 147
mbed_official 10:ab9330955226 148 if (bidx == RX_PBUF_AUTO_INDEX)
mbed_official 10:ab9330955226 149 k64f_enet->rx_fill_index = idx;
mbed_official 10:ab9330955226 150
mbed_official 10:ab9330955226 151 enet_hal_active_rxbd(BOARD_DEBUG_ENET_INSTANCE);
mbed_official 10:ab9330955226 152
mbed_official 10:ab9330955226 153 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 10:ab9330955226 154 ("k64f_rxqueue_pbuf: pbuf packet queued: %p (free desc=%d)\n", p,
mbed_official 10:ab9330955226 155 k64f_enet->rx_free_descs));
mbed_official 10:ab9330955226 156 }
mbed_official 10:ab9330955226 157
mbed_official 10:ab9330955226 158 /** \brief Attempt to allocate and requeue a new pbuf for RX
mbed_official 10:ab9330955226 159 *
mbed_official 10:ab9330955226 160 * \param[in] netif Pointer to the netif structure
mbed_official 10:ab9330955226 161 * \returns number of queued packets
mbed_official 10:ab9330955226 162 */
mbed_official 10:ab9330955226 163 s32_t k64f_rx_queue(struct netif *netif, int idx)
mbed_official 10:ab9330955226 164 {
mbed_official 10:ab9330955226 165 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 10:ab9330955226 166 enet_dev_if_t *enetIfPtr = (enet_dev_if_t *)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE];
mbed_official 10:ab9330955226 167 struct pbuf *p;
mbed_official 10:ab9330955226 168 int queued = 0;
mbed_official 10:ab9330955226 169
mbed_official 10:ab9330955226 170 /* Attempt to requeue as many packets as possible */
mbed_official 10:ab9330955226 171 while (k64f_enet->rx_free_descs > 0) {
mbed_official 10:ab9330955226 172 /* Allocate a pbuf from the pool. We need to allocate at the
mbed_official 10:ab9330955226 173 maximum size as we don't know the size of the yet to be
mbed_official 10:ab9330955226 174 received packet. */
mbed_official 10:ab9330955226 175 p = pbuf_alloc(PBUF_RAW, enetIfPtr->macCfgPtr->rxBufferSize + RX_BUF_ALIGNMENT, PBUF_RAM);
mbed_official 10:ab9330955226 176 if (p == NULL) {
mbed_official 10:ab9330955226 177 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 10:ab9330955226 178 ("k64_rx_queue: could not allocate RX pbuf (free desc=%d)\n",
mbed_official 10:ab9330955226 179 k64f_enet->rx_free_descs));
mbed_official 10:ab9330955226 180 return queued;
mbed_official 10:ab9330955226 181 }
mbed_official 10:ab9330955226 182 /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
mbed_official 10:ab9330955226 183 RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
mbed_official 10:ab9330955226 184 a data structure which is internal to lwIP. This might not prove to be a good idea
mbed_official 10:ab9330955226 185 in the long run, but a better fix would probably involve modifying lwIP itself */
mbed_official 10:ab9330955226 186 p->payload = (void*)ENET_ALIGN((uint32_t)p->payload, RX_BUF_ALIGNMENT);
mbed_official 10:ab9330955226 187
mbed_official 10:ab9330955226 188 /* pbufs allocated from the RAM pool should be non-chained. */
mbed_official 10:ab9330955226 189 LWIP_ASSERT("k64f_rx_queue: pbuf is not contiguous (chained)", pbuf_clen(p) <= 1);
mbed_official 10:ab9330955226 190
mbed_official 10:ab9330955226 191 /* Queue packet */
mbed_official 10:ab9330955226 192 k64f_rxqueue_pbuf(k64f_enet, p, idx);
mbed_official 10:ab9330955226 193 queued++;
mbed_official 10:ab9330955226 194 }
mbed_official 10:ab9330955226 195
mbed_official 10:ab9330955226 196 return queued;
mbed_official 10:ab9330955226 197 }
mbed_official 10:ab9330955226 198
mbed_official 10:ab9330955226 199 /** \brief Sets up the RX descriptor ring buffers.
mbed_official 10:ab9330955226 200 *
mbed_official 10:ab9330955226 201 * This function sets up the descriptor list used for receive packets.
mbed_official 10:ab9330955226 202 *
mbed_official 10:ab9330955226 203 * \param[in] netif Pointer to driver data structure
mbed_official 10:ab9330955226 204 * \returns ERR_MEM if out of memory, ERR_OK otherwise
mbed_official 10:ab9330955226 205 */
mbed_official 10:ab9330955226 206 static err_t k64f_rx_setup(struct netif *netif, enet_rxbd_config_t *rxbdCfg) {
mbed_official 10:ab9330955226 207 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 10:ab9330955226 208 enet_dev_if_t *enetIfPtr = (enet_dev_if_t *)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE];
mbed_official 10:ab9330955226 209 uint8_t *rxBdPtr;
mbed_official 10:ab9330955226 210 uint32_t rxBufferSizeAligned;
mbed_official 10:ab9330955226 211
mbed_official 10:ab9330955226 212 // Allocate RX descriptors
mbed_official 10:ab9330955226 213 rxBdPtr = (uint8_t *)calloc(1, enet_hal_get_bd_size() * enetIfPtr->macCfgPtr->rxBdNumber + ENET_BD_ALIGNMENT);
mbed_official 10:ab9330955226 214 if(!rxBdPtr)
mbed_official 10:ab9330955226 215 return ERR_MEM;
mbed_official 10:ab9330955226 216 k64f_enet->rx_desc_start_addr = (uint8_t *)ENET_ALIGN((uint32_t)rxBdPtr, ENET_BD_ALIGNMENT);
mbed_official 10:ab9330955226 217 k64f_enet->rx_free_descs = enetIfPtr->macCfgPtr->rxBdNumber;
mbed_official 10:ab9330955226 218 k64f_enet->rx_fill_index = 0;
mbed_official 10:ab9330955226 219
mbed_official 10:ab9330955226 220 rxBufferSizeAligned = ENET_ALIGN(enetIfPtr->macCfgPtr->rxBufferSize, ENET_RX_BUFFER_ALIGNMENT);
mbed_official 10:ab9330955226 221 enetIfPtr->macContextPtr->rxBufferSizeAligned = rxBufferSizeAligned;
mbed_official 10:ab9330955226 222 rxbdCfg->rxBdPtrAlign = k64f_enet->rx_desc_start_addr;
mbed_official 10:ab9330955226 223 rxbdCfg->rxBdNum = enetIfPtr->macCfgPtr->rxBdNumber;
mbed_official 10:ab9330955226 224 rxbdCfg->rxBufferNum = enetIfPtr->macCfgPtr->rxBdNumber;
mbed_official 10:ab9330955226 225
mbed_official 10:ab9330955226 226 k64f_rx_queue(netif, RX_PBUF_AUTO_INDEX);
mbed_official 10:ab9330955226 227 return ERR_OK;
mbed_official 10:ab9330955226 228 }
mbed_official 10:ab9330955226 229
mbed_official 10:ab9330955226 230 /** \brief Sets up the TX descriptor ring buffers.
mbed_official 10:ab9330955226 231 *
mbed_official 10:ab9330955226 232 * This function sets up the descriptor list used for transmit packets.
mbed_official 10:ab9330955226 233 *
mbed_official 10:ab9330955226 234 * \param[in] netif Pointer to driver data structure
mbed_official 10:ab9330955226 235 * \returns ERR_MEM if out of memory, ERR_OK otherwise
mbed_official 10:ab9330955226 236 */
mbed_official 10:ab9330955226 237 static err_t k64f_tx_setup(struct netif *netif, enet_txbd_config_t *txbdCfg) {
mbed_official 10:ab9330955226 238 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 10:ab9330955226 239 enet_dev_if_t *enetIfPtr = (enet_dev_if_t *)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE];
mbed_official 10:ab9330955226 240 uint8_t *txBdPtr;
mbed_official 10:ab9330955226 241
mbed_official 10:ab9330955226 242 // Allocate TX descriptors
mbed_official 10:ab9330955226 243 txBdPtr = (uint8_t *)calloc(1, enet_hal_get_bd_size() * enetIfPtr->macCfgPtr->txBdNumber + ENET_BD_ALIGNMENT);
mbed_official 10:ab9330955226 244 if(!txBdPtr)
mbed_official 10:ab9330955226 245 return ERR_MEM;
mbed_official 10:ab9330955226 246
mbed_official 10:ab9330955226 247 k64f_enet->tx_desc_start_addr = (uint8_t *)ENET_ALIGN((uint32_t)txBdPtr, ENET_BD_ALIGNMENT);
mbed_official 10:ab9330955226 248 k64f_enet->tx_consume_index = k64f_enet->tx_produce_index = 0;
mbed_official 10:ab9330955226 249
mbed_official 10:ab9330955226 250 txbdCfg->txBdPtrAlign = k64f_enet->tx_desc_start_addr;
mbed_official 10:ab9330955226 251 txbdCfg->txBufferNum = enetIfPtr->macCfgPtr->txBdNumber;
mbed_official 10:ab9330955226 252 txbdCfg->txBufferSizeAlign = ENET_ALIGN(enetIfPtr->maxFrameSize, ENET_TX_BUFFER_ALIGNMENT);
mbed_official 10:ab9330955226 253
mbed_official 10:ab9330955226 254 // Make the TX descriptor ring circular
mbed_official 10:ab9330955226 255 enet_hal_init_txbds(k64f_enet->tx_desc_start_addr + enet_hal_get_bd_size() * (ENET_TX_RING_LEN - 1), 1);
mbed_official 10:ab9330955226 256
mbed_official 10:ab9330955226 257 return ERR_OK;
mbed_official 10:ab9330955226 258 }
mbed_official 10:ab9330955226 259
mbed_official 10:ab9330955226 260 /** \brief Free TX buffers that are complete
mbed_official 10:ab9330955226 261 *
mbed_official 10:ab9330955226 262 * \param[in] k64f_enet Pointer to driver data structure
mbed_official 10:ab9330955226 263 */
mbed_official 10:ab9330955226 264 static void k64f_tx_reclaim(struct k64f_enetdata *k64f_enet)
mbed_official 10:ab9330955226 265 {
mbed_official 10:ab9330955226 266 uint8_t i;
mbed_official 10:ab9330955226 267 volatile enet_bd_struct_t * bdPtr = (enet_bd_struct_t *)k64f_enet->tx_desc_start_addr;
mbed_official 10:ab9330955226 268
mbed_official 10:ab9330955226 269 /* Get exclusive access */
mbed_official 10:ab9330955226 270 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 10:ab9330955226 271
mbed_official 10:ab9330955226 272 // Traverse all descriptors, looking for the ones modified by the uDMA
mbed_official 10:ab9330955226 273 i = k64f_enet->tx_consume_index;
mbed_official 10:ab9330955226 274 while(i != k64f_enet->tx_produce_index) {
mbed_official 10:ab9330955226 275 if (bdPtr[i].controlExtend2 & TX_DESC_UPDATED_MASK) { // descriptor updated by uDMA
mbed_official 10:ab9330955226 276 if (k64f_enet->txb_aligned[i]) {
mbed_official 10:ab9330955226 277 free(k64f_enet->txb_aligned[i]);
mbed_official 10:ab9330955226 278 k64f_enet->txb_aligned[i] = NULL;
mbed_official 10:ab9330955226 279 } else if (k64f_enet->txb[i]) {
mbed_official 10:ab9330955226 280 pbuf_free(k64f_enet->txb[i]);
mbed_official 10:ab9330955226 281 k64f_enet->txb[i] = NULL;
mbed_official 10:ab9330955226 282 }
mbed_official 10:ab9330955226 283 osSemaphoreRelease(k64f_enet->xTXDCountSem.id);
mbed_official 10:ab9330955226 284 bdPtr[i].controlExtend2 &= ~TX_DESC_UPDATED_MASK;
mbed_official 10:ab9330955226 285 }
mbed_official 10:ab9330955226 286 i = (i + 1) % ENET_TX_RING_LEN;
mbed_official 10:ab9330955226 287 }
mbed_official 10:ab9330955226 288 k64f_enet->tx_consume_index = i;
mbed_official 10:ab9330955226 289
mbed_official 10:ab9330955226 290 /* Restore access */
mbed_official 10:ab9330955226 291 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 10:ab9330955226 292 }
mbed_official 10:ab9330955226 293
mbed_official 10:ab9330955226 294 /** \brief Low level init of the MAC and PHY.
mbed_official 10:ab9330955226 295 *
mbed_official 10:ab9330955226 296 * \param[in] netif Pointer to LWIP netif structure
mbed_official 10:ab9330955226 297 */
mbed_official 10:ab9330955226 298 static err_t low_level_init(struct netif *netif)
mbed_official 10:ab9330955226 299 {
mbed_official 10:ab9330955226 300 enet_dev_if_t * enetIfPtr;
mbed_official 10:ab9330955226 301 uint32_t device = BOARD_DEBUG_ENET_INSTANCE;
mbed_official 10:ab9330955226 302 enet_rxbd_config_t rxbdCfg;
mbed_official 10:ab9330955226 303 enet_txbd_config_t txbdCfg;
mbed_official 10:ab9330955226 304 enet_phy_speed_t phy_speed;
mbed_official 10:ab9330955226 305 enet_phy_duplex_t phy_duplex;
mbed_official 10:ab9330955226 306
mbed_official 10:ab9330955226 307 k64f_init_eth_hardware();
mbed_official 10:ab9330955226 308
mbed_official 10:ab9330955226 309 /* Initialize device*/
mbed_official 10:ab9330955226 310 enetIfPtr = (enet_dev_if_t *)&enetDevIf[device];
mbed_official 10:ab9330955226 311 enetIfPtr->deviceNumber = device;
mbed_official 10:ab9330955226 312 enetIfPtr->macCfgPtr = &g_enetMacCfg[device];
mbed_official 10:ab9330955226 313 enetIfPtr->phyCfgPtr = &g_enetPhyCfg[device];
mbed_official 10:ab9330955226 314 enetIfPtr->macApiPtr = &g_enetMacApi;
mbed_official 10:ab9330955226 315 enetIfPtr->phyApiPtr = (void *)&g_enetPhyApi;
mbed_official 10:ab9330955226 316 memcpy(enetIfPtr->macCfgPtr->macAddr, (char*)netif->hwaddr, kEnetMacAddrLen);
mbed_official 10:ab9330955226 317
mbed_official 10:ab9330955226 318 /* Allocate buffer for ENET mac context*/
mbed_official 10:ab9330955226 319 enetIfPtr->macContextPtr = (enet_mac_context_t *)calloc(1, sizeof(enet_mac_context_t));
mbed_official 10:ab9330955226 320 if (!enetIfPtr->macContextPtr) {
mbed_official 10:ab9330955226 321 return ERR_BUF;
mbed_official 10:ab9330955226 322 }
mbed_official 10:ab9330955226 323
mbed_official 10:ab9330955226 324 /* Initialize enet buffers*/
mbed_official 10:ab9330955226 325 if(k64f_rx_setup(netif, &rxbdCfg) != ERR_OK) {
mbed_official 10:ab9330955226 326 return ERR_BUF;
mbed_official 10:ab9330955226 327 }
mbed_official 10:ab9330955226 328 /* Initialize enet buffers*/
mbed_official 10:ab9330955226 329 if(k64f_tx_setup(netif, &txbdCfg) != ERR_OK) {
mbed_official 10:ab9330955226 330 return ERR_BUF;
mbed_official 10:ab9330955226 331 }
mbed_official 10:ab9330955226 332 /* Initialize enet module*/
mbed_official 10:ab9330955226 333 if (enet_mac_init(enetIfPtr, &rxbdCfg, &txbdCfg) == kStatus_ENET_Success)
mbed_official 10:ab9330955226 334 {
mbed_official 10:ab9330955226 335 /* Initialize PHY*/
mbed_official 10:ab9330955226 336 if (enetIfPtr->macCfgPtr->isPhyAutoDiscover) {
mbed_official 10:ab9330955226 337 if (((enet_phy_api_t *)(enetIfPtr->phyApiPtr))->phy_auto_discover(enetIfPtr) != kStatus_PHY_Success)
mbed_official 10:ab9330955226 338 return ERR_IF;
mbed_official 10:ab9330955226 339 }
mbed_official 10:ab9330955226 340 if (((enet_phy_api_t *)(enetIfPtr->phyApiPtr))->phy_init(enetIfPtr) != kStatus_PHY_Success)
mbed_official 10:ab9330955226 341 return ERR_IF;
mbed_official 10:ab9330955226 342
mbed_official 10:ab9330955226 343 enetIfPtr->isInitialized = true;
mbed_official 10:ab9330955226 344 }
mbed_official 10:ab9330955226 345 else
mbed_official 10:ab9330955226 346 {
mbed_official 10:ab9330955226 347 // TODOETH: cleanup memory
mbed_official 10:ab9330955226 348 return ERR_IF;
mbed_official 10:ab9330955226 349 }
mbed_official 10:ab9330955226 350
mbed_official 10:ab9330955226 351 /* Get link information from PHY */
mbed_official 10:ab9330955226 352 phy_get_link_speed(enetIfPtr, &phy_speed);
mbed_official 10:ab9330955226 353 phy_get_link_duplex(enetIfPtr, &phy_duplex);
mbed_official 10:ab9330955226 354 BW_ENET_RCR_RMII_10T(enetIfPtr->deviceNumber, phy_speed == kEnetSpeed10M ? kEnetCfgSpeed10M : kEnetCfgSpeed100M);
mbed_official 10:ab9330955226 355 BW_ENET_TCR_FDEN(enetIfPtr->deviceNumber, phy_duplex == kEnetFullDuplex ? kEnetCfgFullDuplex : kEnetCfgHalfDuplex);
mbed_official 10:ab9330955226 356
mbed_official 10:ab9330955226 357 /* Enable Ethernet module*/
mbed_official 10:ab9330955226 358 enet_hal_config_ethernet(device, true, true);
mbed_official 10:ab9330955226 359
mbed_official 10:ab9330955226 360 /* Active Receive buffer descriptor must be done after module enable*/
mbed_official 10:ab9330955226 361 enet_hal_active_rxbd(enetIfPtr->deviceNumber);
mbed_official 10:ab9330955226 362
mbed_official 10:ab9330955226 363 return ERR_OK;
mbed_official 10:ab9330955226 364 }
mbed_official 10:ab9330955226 365
mbed_official 10:ab9330955226 366 /********************************************************************************
mbed_official 10:ab9330955226 367 * LWIP port
mbed_official 10:ab9330955226 368 ********************************************************************************/
mbed_official 10:ab9330955226 369
mbed_official 10:ab9330955226 370 /** \brief Ethernet receive interrupt handler
mbed_official 10:ab9330955226 371 *
mbed_official 10:ab9330955226 372 * This function handles the receive interrupt of K64F.
mbed_official 10:ab9330955226 373 */
mbed_official 10:ab9330955226 374 void enet_mac_rx_isr(void *enetIfPtr)
mbed_official 10:ab9330955226 375 {
mbed_official 10:ab9330955226 376 /* Clear interrupt */
mbed_official 10:ab9330955226 377 enet_hal_clear_interrupt(((enet_dev_if_t *)enetIfPtr)->deviceNumber, kEnetRxFrameInterrupt);
mbed_official 10:ab9330955226 378 sys_sem_signal(&k64f_enetdata.RxReadySem);
mbed_official 10:ab9330955226 379 }
mbed_official 10:ab9330955226 380
mbed_official 10:ab9330955226 381 void enet_mac_tx_isr(void *enetIfPtr)
mbed_official 10:ab9330955226 382 {
mbed_official 10:ab9330955226 383 /*Clear interrupt*/
mbed_official 10:ab9330955226 384 enet_hal_clear_interrupt(((enet_dev_if_t *)enetIfPtr)->deviceNumber, kEnetTxFrameInterrupt);
mbed_official 10:ab9330955226 385 sys_sem_signal(&k64f_enetdata.TxCleanSem);
mbed_official 10:ab9330955226 386 }
mbed_official 10:ab9330955226 387
mbed_official 10:ab9330955226 388 /**
mbed_official 10:ab9330955226 389 * This function is the ethernet packet send function. It calls
mbed_official 10:ab9330955226 390 * etharp_output after checking link status.
mbed_official 10:ab9330955226 391 *
mbed_official 10:ab9330955226 392 * \param[in] netif the lwip network interface structure for this enetif
mbed_official 10:ab9330955226 393 * \param[in] q Pointer to pbug to send
mbed_official 10:ab9330955226 394 * \param[in] ipaddr IP address
mbed_official 10:ab9330955226 395 * \return ERR_OK or error code
mbed_official 10:ab9330955226 396 */
mbed_official 10:ab9330955226 397 err_t k64f_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
mbed_official 10:ab9330955226 398 {
mbed_official 10:ab9330955226 399 /* Only send packet is link is up */
mbed_official 10:ab9330955226 400 if (netif->flags & NETIF_FLAG_LINK_UP)
mbed_official 10:ab9330955226 401 return etharp_output(netif, q, ipaddr);
mbed_official 10:ab9330955226 402
mbed_official 10:ab9330955226 403 return ERR_CONN;
mbed_official 10:ab9330955226 404 }
mbed_official 10:ab9330955226 405
mbed_official 10:ab9330955226 406 /** \brief Allocates a pbuf and returns the data from the incoming packet.
mbed_official 10:ab9330955226 407 *
mbed_official 10:ab9330955226 408 * \param[in] netif the lwip network interface structure
mbed_official 10:ab9330955226 409 * \param[in] idx index of packet to be read
mbed_official 10:ab9330955226 410 * \return a pbuf filled with the received packet (including MAC header)
mbed_official 10:ab9330955226 411 */
mbed_official 10:ab9330955226 412 static struct pbuf *k64f_low_level_input(struct netif *netif, int idx)
mbed_official 10:ab9330955226 413 {
mbed_official 10:ab9330955226 414 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 10:ab9330955226 415 enet_bd_struct_t * bdPtr = (enet_bd_struct_t*)k64f_enet->rx_desc_start_addr;
mbed_official 10:ab9330955226 416 struct pbuf *p = NULL;
mbed_official 10:ab9330955226 417 u32_t length = 0, orig_length;
mbed_official 10:ab9330955226 418 const u16_t err_mask = kEnetRxBdTrunc | kEnetRxBdCrc | kEnetRxBdNoOctet | kEnetRxBdLengthViolation;
mbed_official 10:ab9330955226 419
mbed_official 10:ab9330955226 420 #ifdef LOCK_RX_THREAD
mbed_official 10:ab9330955226 421 /* Get exclusive access */
mbed_official 10:ab9330955226 422 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 10:ab9330955226 423 #endif
mbed_official 10:ab9330955226 424
mbed_official 10:ab9330955226 425 /* Determine if a frame has been received */
mbed_official 10:ab9330955226 426 if ((bdPtr[idx].control & err_mask) != 0) {
mbed_official 10:ab9330955226 427 #if LINK_STATS
mbed_official 10:ab9330955226 428 if ((bdPtr[idx].control & kEnetRxBdLengthViolation) != 0)
mbed_official 10:ab9330955226 429 LINK_STATS_INC(link.lenerr);
mbed_official 10:ab9330955226 430 else
mbed_official 10:ab9330955226 431 LINK_STATS_INC(link.chkerr);
mbed_official 10:ab9330955226 432 #endif
mbed_official 10:ab9330955226 433 LINK_STATS_INC(link.drop);
mbed_official 10:ab9330955226 434
mbed_official 10:ab9330955226 435 /* Re-queue the same buffer */
mbed_official 10:ab9330955226 436 k64f_enet->rx_free_descs++;
mbed_official 10:ab9330955226 437 p = k64f_enet->rxb[idx];
mbed_official 10:ab9330955226 438 k64f_enet->rxb[idx] = NULL;
mbed_official 10:ab9330955226 439 k64f_rxqueue_pbuf(k64f_enet, p, idx);
mbed_official 10:ab9330955226 440 p = NULL;
mbed_official 10:ab9330955226 441 } else {
mbed_official 10:ab9330955226 442 /* A packet is waiting, get length */
mbed_official 10:ab9330955226 443 length = enet_hal_get_bd_length(bdPtr + idx);
mbed_official 10:ab9330955226 444
mbed_official 10:ab9330955226 445 /* Zero-copy */
mbed_official 10:ab9330955226 446 p = k64f_enet->rxb[idx];
mbed_official 10:ab9330955226 447 orig_length = p->len;
mbed_official 10:ab9330955226 448 p->len = (u16_t) length;
mbed_official 10:ab9330955226 449
mbed_official 10:ab9330955226 450 /* Free pbuf from descriptor */
mbed_official 10:ab9330955226 451 k64f_enet->rxb[idx] = NULL;
mbed_official 10:ab9330955226 452 k64f_enet->rx_free_descs++;
mbed_official 10:ab9330955226 453
mbed_official 10:ab9330955226 454 /* Attempt to queue new buffer */
mbed_official 10:ab9330955226 455 if (k64f_rx_queue(netif, idx) == 0) {
mbed_official 10:ab9330955226 456 /* Drop frame (out of memory) */
mbed_official 10:ab9330955226 457 LINK_STATS_INC(link.drop);
mbed_official 10:ab9330955226 458
mbed_official 10:ab9330955226 459 /* Re-queue the same buffer */
mbed_official 10:ab9330955226 460 p->len = orig_length;
mbed_official 10:ab9330955226 461 k64f_rxqueue_pbuf(k64f_enet, p, idx);
mbed_official 10:ab9330955226 462
mbed_official 10:ab9330955226 463 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 10:ab9330955226 464 ("k64f_low_level_input: Packet index %d dropped for OOM\n",
mbed_official 10:ab9330955226 465 idx));
mbed_official 10:ab9330955226 466 #ifdef LOCK_RX_THREAD
mbed_official 10:ab9330955226 467 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 10:ab9330955226 468 #endif
mbed_official 10:ab9330955226 469
mbed_official 10:ab9330955226 470 return NULL;
mbed_official 10:ab9330955226 471 }
mbed_official 10:ab9330955226 472
mbed_official 10:ab9330955226 473 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 10:ab9330955226 474 ("k64f_low_level_input: Packet received: %p, size %d (index=%d)\n",
mbed_official 10:ab9330955226 475 p, length, idx));
mbed_official 10:ab9330955226 476
mbed_official 10:ab9330955226 477 /* Save size */
mbed_official 10:ab9330955226 478 p->tot_len = (u16_t) length;
mbed_official 10:ab9330955226 479 LINK_STATS_INC(link.recv);
mbed_official 10:ab9330955226 480 }
mbed_official 10:ab9330955226 481
mbed_official 10:ab9330955226 482 #ifdef LOCK_RX_THREAD
mbed_official 10:ab9330955226 483 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 10:ab9330955226 484 #endif
mbed_official 10:ab9330955226 485
mbed_official 10:ab9330955226 486 return p;
mbed_official 10:ab9330955226 487 }
mbed_official 10:ab9330955226 488
mbed_official 10:ab9330955226 489 /** \brief Attempt to read a packet from the EMAC interface.
mbed_official 10:ab9330955226 490 *
mbed_official 10:ab9330955226 491 * \param[in] netif the lwip network interface structure
mbed_official 10:ab9330955226 492 * \param[in] idx index of packet to be read
mbed_official 10:ab9330955226 493 */
mbed_official 10:ab9330955226 494 void k64f_enetif_input(struct netif *netif, int idx)
mbed_official 10:ab9330955226 495 {
mbed_official 10:ab9330955226 496 struct eth_hdr *ethhdr;
mbed_official 10:ab9330955226 497 struct pbuf *p;
mbed_official 10:ab9330955226 498
mbed_official 10:ab9330955226 499 /* move received packet into a new pbuf */
mbed_official 10:ab9330955226 500 p = k64f_low_level_input(netif, idx);
mbed_official 10:ab9330955226 501 if (p == NULL)
mbed_official 10:ab9330955226 502 return;
mbed_official 10:ab9330955226 503
mbed_official 10:ab9330955226 504 /* points to packet payload, which starts with an Ethernet header */
mbed_official 10:ab9330955226 505 ethhdr = (struct eth_hdr*)p->payload;
mbed_official 10:ab9330955226 506
mbed_official 10:ab9330955226 507 switch (htons(ethhdr->type)) {
mbed_official 10:ab9330955226 508 case ETHTYPE_IP:
mbed_official 10:ab9330955226 509 case ETHTYPE_ARP:
mbed_official 10:ab9330955226 510 #if PPPOE_SUPPORT
mbed_official 10:ab9330955226 511 case ETHTYPE_PPPOEDISC:
mbed_official 10:ab9330955226 512 case ETHTYPE_PPPOE:
mbed_official 10:ab9330955226 513 #endif /* PPPOE_SUPPORT */
mbed_official 10:ab9330955226 514 /* full packet send to tcpip_thread to process */
mbed_official 10:ab9330955226 515 if (netif->input(p, netif) != ERR_OK) {
mbed_official 10:ab9330955226 516 LWIP_DEBUGF(NETIF_DEBUG, ("k64f_enetif_input: IP input error\n"));
mbed_official 10:ab9330955226 517 /* Free buffer */
mbed_official 10:ab9330955226 518 pbuf_free(p);
mbed_official 10:ab9330955226 519 }
mbed_official 10:ab9330955226 520 break;
mbed_official 10:ab9330955226 521
mbed_official 10:ab9330955226 522 default:
mbed_official 10:ab9330955226 523 /* Return buffer */
mbed_official 10:ab9330955226 524 pbuf_free(p);
mbed_official 10:ab9330955226 525 break;
mbed_official 10:ab9330955226 526 }
mbed_official 10:ab9330955226 527 }
mbed_official 10:ab9330955226 528
mbed_official 10:ab9330955226 529 /** \brief Packet reception task
mbed_official 10:ab9330955226 530 *
mbed_official 10:ab9330955226 531 * This task is called when a packet is received. It will
mbed_official 10:ab9330955226 532 * pass the packet to the LWIP core.
mbed_official 10:ab9330955226 533 *
mbed_official 10:ab9330955226 534 * \param[in] pvParameters pointer to the interface data
mbed_official 10:ab9330955226 535 */
mbed_official 10:ab9330955226 536 static void packet_rx(void* pvParameters) {
mbed_official 10:ab9330955226 537 struct k64f_enetdata *k64f_enet = pvParameters;
mbed_official 10:ab9330955226 538 volatile enet_bd_struct_t * bdPtr = (enet_bd_struct_t*)k64f_enet->rx_desc_start_addr;
mbed_official 10:ab9330955226 539 int idx = 0;
mbed_official 10:ab9330955226 540
mbed_official 10:ab9330955226 541 while (1) {
mbed_official 10:ab9330955226 542 /* Wait for receive task to wakeup */
mbed_official 10:ab9330955226 543 sys_arch_sem_wait(&k64f_enet->RxReadySem, 0);
mbed_official 10:ab9330955226 544
mbed_official 10:ab9330955226 545 if ((bdPtr[idx].control & kEnetRxBdEmpty) == 0) {
mbed_official 10:ab9330955226 546 k64f_enetif_input(k64f_enet->netif, idx);
mbed_official 10:ab9330955226 547 idx = (idx + 1) % ENET_RX_RING_LEN;
mbed_official 10:ab9330955226 548 }
mbed_official 10:ab9330955226 549 }
mbed_official 10:ab9330955226 550 }
mbed_official 10:ab9330955226 551
mbed_official 10:ab9330955226 552 /** \brief Transmit cleanup task
mbed_official 10:ab9330955226 553 *
mbed_official 10:ab9330955226 554 * This task is called when a transmit interrupt occurs and
mbed_official 10:ab9330955226 555 * reclaims the pbuf and descriptor used for the packet once
mbed_official 10:ab9330955226 556 * the packet has been transferred.
mbed_official 10:ab9330955226 557 *
mbed_official 10:ab9330955226 558 * \param[in] pvParameters pointer to the interface data
mbed_official 10:ab9330955226 559 */
mbed_official 10:ab9330955226 560 static void packet_tx(void* pvParameters) {
mbed_official 10:ab9330955226 561 struct k64f_enetdata *k64f_enet = pvParameters;
mbed_official 10:ab9330955226 562
mbed_official 10:ab9330955226 563 while (1) {
mbed_official 10:ab9330955226 564 /* Wait for transmit cleanup task to wakeup */
mbed_official 10:ab9330955226 565 sys_arch_sem_wait(&k64f_enet->TxCleanSem, 0);
mbed_official 10:ab9330955226 566 // TODOETH: handle TX underrun?
mbed_official 10:ab9330955226 567 k64f_tx_reclaim(k64f_enet);
mbed_official 10:ab9330955226 568 }
mbed_official 10:ab9330955226 569 }
mbed_official 10:ab9330955226 570
mbed_official 10:ab9330955226 571 /** \brief Polls if an available TX descriptor is ready. Can be used to
mbed_official 10:ab9330955226 572 * determine if the low level transmit function will block.
mbed_official 10:ab9330955226 573 *
mbed_official 10:ab9330955226 574 * \param[in] netif the lwip network interface structure
mbed_official 10:ab9330955226 575 * \return 0 if no descriptors are read, or >0
mbed_official 10:ab9330955226 576 */
mbed_official 10:ab9330955226 577 s32_t k64f_tx_ready(struct netif *netif)
mbed_official 10:ab9330955226 578 {
mbed_official 10:ab9330955226 579 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 10:ab9330955226 580 s32_t fb;
mbed_official 10:ab9330955226 581 u32_t idx, cidx;
mbed_official 10:ab9330955226 582
mbed_official 10:ab9330955226 583 cidx = k64f_enet->tx_consume_index;
mbed_official 10:ab9330955226 584 idx = k64f_enet->tx_produce_index;
mbed_official 10:ab9330955226 585
mbed_official 10:ab9330955226 586 /* Determine number of free buffers */
mbed_official 10:ab9330955226 587 if (idx == cidx)
mbed_official 10:ab9330955226 588 fb = ENET_TX_RING_LEN;
mbed_official 10:ab9330955226 589 else if (cidx > idx)
mbed_official 10:ab9330955226 590 fb = (ENET_TX_RING_LEN - 1) -
mbed_official 10:ab9330955226 591 ((idx + ENET_TX_RING_LEN) - cidx);
mbed_official 10:ab9330955226 592 else
mbed_official 10:ab9330955226 593 fb = (ENET_TX_RING_LEN - 1) - (cidx - idx);
mbed_official 10:ab9330955226 594
mbed_official 10:ab9330955226 595 return fb;
mbed_official 10:ab9330955226 596 }
mbed_official 10:ab9330955226 597
mbed_official 10:ab9330955226 598 /*FUNCTION****************************************************************
mbed_official 10:ab9330955226 599 *
mbed_official 10:ab9330955226 600 * Function Name: enet_hal_update_txbds
mbed_official 10:ab9330955226 601 * Description: Update ENET transmit buffer descriptors.
mbed_official 10:ab9330955226 602 *END*********************************************************************/
mbed_official 10:ab9330955226 603 void k64f_update_txbds(struct k64f_enetdata *k64f_enet, int idx, uint8_t *buffer, uint16_t length, bool isLast)
mbed_official 10:ab9330955226 604 {
mbed_official 10:ab9330955226 605 volatile enet_bd_struct_t * bdPtr = (enet_bd_struct_t *)(k64f_enet->tx_desc_start_addr + idx * enet_hal_get_bd_size());
mbed_official 10:ab9330955226 606
mbed_official 10:ab9330955226 607 bdPtr->length = HTONS(length); /* Set data length*/
mbed_official 10:ab9330955226 608 bdPtr->buffer = (uint8_t *)HTONL((uint32_t)buffer); /* Set data buffer*/
mbed_official 10:ab9330955226 609 if (isLast)
mbed_official 10:ab9330955226 610 bdPtr->control |= kEnetTxBdLast;
mbed_official 10:ab9330955226 611 else
mbed_official 10:ab9330955226 612 bdPtr->control &= ~kEnetTxBdLast;
mbed_official 10:ab9330955226 613 bdPtr->controlExtend1 |= kEnetTxBdTxInterrupt;
mbed_official 10:ab9330955226 614 bdPtr->controlExtend2 &= ~TX_DESC_UPDATED_MASK; // descriptor not updated by DMA
mbed_official 10:ab9330955226 615 bdPtr->control |= kEnetTxBdTransmitCrc | kEnetTxBdReady;
mbed_official 10:ab9330955226 616 }
mbed_official 10:ab9330955226 617
mbed_official 10:ab9330955226 618 /** \brief Low level output of a packet. Never call this from an
mbed_official 10:ab9330955226 619 * interrupt context, as it may block until TX descriptors
mbed_official 10:ab9330955226 620 * become available.
mbed_official 10:ab9330955226 621 *
mbed_official 10:ab9330955226 622 * \param[in] netif the lwip network interface structure for this netif
mbed_official 10:ab9330955226 623 * \param[in] p the MAC packet to send (e.g. IP packet including MAC addresses and type)
mbed_official 10:ab9330955226 624 * \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent
mbed_official 10:ab9330955226 625 */
mbed_official 10:ab9330955226 626 static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p)
mbed_official 10:ab9330955226 627 {
mbed_official 10:ab9330955226 628 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 10:ab9330955226 629 struct pbuf *q;
mbed_official 10:ab9330955226 630 u32_t idx;
mbed_official 10:ab9330955226 631 s32_t dn;
mbed_official 10:ab9330955226 632 uint8_t *psend = NULL, *dst;
mbed_official 10:ab9330955226 633
mbed_official 10:ab9330955226 634 /* Get free TX buffer index */
mbed_official 10:ab9330955226 635 idx = k64f_enet->tx_produce_index;
mbed_official 10:ab9330955226 636
mbed_official 10:ab9330955226 637 /* Check the pbuf chain for payloads that are not 8-byte aligned.
mbed_official 10:ab9330955226 638 If found, a new properly aligned buffer needs to be allocated
mbed_official 10:ab9330955226 639 and the data copied there */
mbed_official 10:ab9330955226 640 for (q = p; q != NULL; q = q->next)
mbed_official 10:ab9330955226 641 if (((u32_t)q->payload & (TX_BUF_ALIGNMENT - 1)) != 0)
mbed_official 10:ab9330955226 642 break;
mbed_official 10:ab9330955226 643 if (q != NULL) {
mbed_official 10:ab9330955226 644 // Allocate properly aligned buffer
mbed_official 10:ab9330955226 645 psend = (uint8_t*)malloc(p->tot_len);
mbed_official 10:ab9330955226 646 if (NULL == psend)
mbed_official 10:ab9330955226 647 return ERR_MEM;
mbed_official 10:ab9330955226 648 LWIP_ASSERT("k64f_low_level_output: buffer not properly aligned", ((u32_t)psend & (TX_BUF_ALIGNMENT - 1)) == 0);
mbed_official 10:ab9330955226 649 for (q = p, dst = psend; q != NULL; q = q->next) {
mbed_official 10:ab9330955226 650 MEMCPY(dst, q->payload, q->len);
mbed_official 10:ab9330955226 651 dst += q->len;
mbed_official 10:ab9330955226 652 }
mbed_official 10:ab9330955226 653 k64f_enet->txb_aligned[idx] = psend;
mbed_official 10:ab9330955226 654 dn = 1;
mbed_official 10:ab9330955226 655 } else {
mbed_official 10:ab9330955226 656 k64f_enet->txb_aligned[idx] = NULL;
mbed_official 10:ab9330955226 657 dn = (s32_t) pbuf_clen(p);
mbed_official 10:ab9330955226 658 pbuf_ref(p);
mbed_official 10:ab9330955226 659 }
mbed_official 10:ab9330955226 660
mbed_official 10:ab9330955226 661 /* Wait until enough descriptors are available for the transfer. */
mbed_official 10:ab9330955226 662 /* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */
mbed_official 10:ab9330955226 663 while (dn > k64f_tx_ready(netif))
mbed_official 10:ab9330955226 664 osSemaphoreWait(k64f_enet->xTXDCountSem.id, osWaitForever);
mbed_official 10:ab9330955226 665
mbed_official 10:ab9330955226 666 /* Get exclusive access */
mbed_official 10:ab9330955226 667 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 10:ab9330955226 668
mbed_official 10:ab9330955226 669 /* Setup transfers */
mbed_official 10:ab9330955226 670 q = p;
mbed_official 10:ab9330955226 671 while (dn > 0) {
mbed_official 10:ab9330955226 672 dn--;
mbed_official 10:ab9330955226 673 if (psend != NULL) {
mbed_official 10:ab9330955226 674 k64f_update_txbds(k64f_enet, idx, psend, p->tot_len, 1);
mbed_official 10:ab9330955226 675 k64f_enet->txb[idx] = NULL;
mbed_official 10:ab9330955226 676
mbed_official 10:ab9330955226 677 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 10:ab9330955226 678 ("k64f_low_level_output: aligned packet(%p) sent"
mbed_official 10:ab9330955226 679 " size = %d (index=%d)\n", psend, p->tot_len, idx));
mbed_official 10:ab9330955226 680 } else {
mbed_official 10:ab9330955226 681 LWIP_ASSERT("k64f_low_level_output: buffer not properly aligned", ((u32_t)q->payload & 0x07) == 0);
mbed_official 10:ab9330955226 682
mbed_official 10:ab9330955226 683 /* Only save pointer to free on last descriptor */
mbed_official 10:ab9330955226 684 if (dn == 0) {
mbed_official 10:ab9330955226 685 /* Save size of packet and signal it's ready */
mbed_official 10:ab9330955226 686 k64f_update_txbds(k64f_enet, idx, q->payload, q->len, 1);
mbed_official 10:ab9330955226 687 k64f_enet->txb[idx] = p;
mbed_official 10:ab9330955226 688 }
mbed_official 10:ab9330955226 689 else {
mbed_official 10:ab9330955226 690 /* Save size of packet, descriptor is not last */
mbed_official 10:ab9330955226 691 k64f_update_txbds(k64f_enet, idx, q->payload, q->len, 0);
mbed_official 10:ab9330955226 692 k64f_enet->txb[idx] = NULL;
mbed_official 10:ab9330955226 693 }
mbed_official 10:ab9330955226 694
mbed_official 10:ab9330955226 695 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 10:ab9330955226 696 ("k64f_low_level_output: pbuf packet(%p) sent, chain#=%d,"
mbed_official 10:ab9330955226 697 " size = %d (index=%d)\n", q->payload, dn, q->len, idx));
mbed_official 10:ab9330955226 698 }
mbed_official 10:ab9330955226 699
mbed_official 10:ab9330955226 700 q = q->next;
mbed_official 10:ab9330955226 701
mbed_official 10:ab9330955226 702 idx = (idx + 1) % ENET_TX_RING_LEN;
mbed_official 10:ab9330955226 703 }
mbed_official 10:ab9330955226 704
mbed_official 10:ab9330955226 705 k64f_enet->tx_produce_index = idx;
mbed_official 10:ab9330955226 706 enet_hal_active_txbd(BOARD_DEBUG_ENET_INSTANCE);
mbed_official 10:ab9330955226 707 LINK_STATS_INC(link.xmit);
mbed_official 10:ab9330955226 708
mbed_official 10:ab9330955226 709 /* Restore access */
mbed_official 10:ab9330955226 710 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 10:ab9330955226 711
mbed_official 10:ab9330955226 712 return ERR_OK;
mbed_official 10:ab9330955226 713 }
mbed_official 10:ab9330955226 714
mbed_official 10:ab9330955226 715 /*******************************************************************************
mbed_official 10:ab9330955226 716 * PHY task: monitor link
mbed_official 10:ab9330955226 717 *******************************************************************************/
mbed_official 10:ab9330955226 718
mbed_official 10:ab9330955226 719 #define PHY_TASK_PERIOD_MS 200
mbed_official 10:ab9330955226 720 #define STATE_UNKNOWN (-1)
mbed_official 10:ab9330955226 721
mbed_official 10:ab9330955226 722 typedef struct {
mbed_official 10:ab9330955226 723 int connected;
mbed_official 10:ab9330955226 724 enet_phy_speed_t speed;
mbed_official 10:ab9330955226 725 enet_phy_duplex_t duplex;
mbed_official 10:ab9330955226 726 } PHY_STATE;
mbed_official 10:ab9330955226 727
mbed_official 10:ab9330955226 728 static void k64f_phy_task(void *data) {
mbed_official 10:ab9330955226 729 struct netif *netif = (struct netif*)data;
mbed_official 10:ab9330955226 730 bool connection_status;
mbed_official 10:ab9330955226 731 enet_dev_if_t * enetIfPtr = (enet_dev_if_t*)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE];
mbed_official 10:ab9330955226 732 PHY_STATE crt_state = {STATE_UNKNOWN, (enet_phy_speed_t)STATE_UNKNOWN, (enet_phy_duplex_t)STATE_UNKNOWN};
mbed_official 10:ab9330955226 733 PHY_STATE prev_state;
mbed_official 10:ab9330955226 734
mbed_official 10:ab9330955226 735 prev_state = crt_state;
mbed_official 10:ab9330955226 736 while (true) {
mbed_official 10:ab9330955226 737 // Get current status
mbed_official 10:ab9330955226 738 phy_get_link_status(enetIfPtr, &connection_status);
mbed_official 10:ab9330955226 739 crt_state.connected = connection_status ? 1 : 0;
mbed_official 10:ab9330955226 740 phy_get_link_speed(enetIfPtr, &crt_state.speed);
mbed_official 10:ab9330955226 741 phy_get_link_duplex(enetIfPtr, &crt_state.duplex);
mbed_official 10:ab9330955226 742
mbed_official 10:ab9330955226 743 // Compare with previous state
mbed_official 10:ab9330955226 744 if (crt_state.connected != prev_state.connected) {
mbed_official 10:ab9330955226 745 if (crt_state.connected)
mbed_official 10:ab9330955226 746 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1);
mbed_official 10:ab9330955226 747 else
mbed_official 10:ab9330955226 748 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1);
mbed_official 10:ab9330955226 749 }
mbed_official 10:ab9330955226 750
mbed_official 10:ab9330955226 751 if (crt_state.speed != prev_state.speed)
mbed_official 10:ab9330955226 752 BW_ENET_RCR_RMII_10T(enetIfPtr->deviceNumber, crt_state.speed == kEnetSpeed10M ? kEnetCfgSpeed10M : kEnetCfgSpeed100M);
mbed_official 10:ab9330955226 753
mbed_official 10:ab9330955226 754 // TODO: duplex change requires disable/enable of Ethernet interface, to be implemented
mbed_official 10:ab9330955226 755
mbed_official 10:ab9330955226 756 prev_state = crt_state;
mbed_official 10:ab9330955226 757 osDelay(PHY_TASK_PERIOD_MS);
mbed_official 10:ab9330955226 758 }
mbed_official 10:ab9330955226 759 }
mbed_official 10:ab9330955226 760
mbed_official 10:ab9330955226 761 /**
mbed_official 10:ab9330955226 762 * Should be called at the beginning of the program to set up the
mbed_official 10:ab9330955226 763 * network interface.
mbed_official 10:ab9330955226 764 *
mbed_official 10:ab9330955226 765 * This function should be passed as a parameter to netif_add().
mbed_official 10:ab9330955226 766 *
mbed_official 10:ab9330955226 767 * @param[in] netif the lwip network interface structure for this netif
mbed_official 10:ab9330955226 768 * @return ERR_OK if the loopif is initialized
mbed_official 10:ab9330955226 769 * ERR_MEM if private data couldn't be allocated
mbed_official 10:ab9330955226 770 * any other err_t on error
mbed_official 10:ab9330955226 771 */
mbed_official 10:ab9330955226 772 err_t eth_arch_enetif_init(struct netif *netif)
mbed_official 10:ab9330955226 773 {
mbed_official 10:ab9330955226 774 err_t err;
mbed_official 10:ab9330955226 775
mbed_official 10:ab9330955226 776 LWIP_ASSERT("netif != NULL", (netif != NULL));
mbed_official 10:ab9330955226 777
mbed_official 10:ab9330955226 778 k64f_enetdata.netif = netif;
mbed_official 10:ab9330955226 779
mbed_official 10:ab9330955226 780 /* set MAC hardware address */
mbed_official 10:ab9330955226 781 #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
mbed_official 10:ab9330955226 782 netif->hwaddr[0] = MBED_MAC_ADDR_0;
mbed_official 10:ab9330955226 783 netif->hwaddr[1] = MBED_MAC_ADDR_1;
mbed_official 10:ab9330955226 784 netif->hwaddr[2] = MBED_MAC_ADDR_2;
mbed_official 10:ab9330955226 785 netif->hwaddr[3] = MBED_MAC_ADDR_3;
mbed_official 10:ab9330955226 786 netif->hwaddr[4] = MBED_MAC_ADDR_4;
mbed_official 10:ab9330955226 787 netif->hwaddr[5] = MBED_MAC_ADDR_5;
mbed_official 10:ab9330955226 788 #else
mbed_official 10:ab9330955226 789 mbed_mac_address((char *)netif->hwaddr);
mbed_official 10:ab9330955226 790 #endif
mbed_official 10:ab9330955226 791 netif->hwaddr_len = ETHARP_HWADDR_LEN;
mbed_official 10:ab9330955226 792
mbed_official 10:ab9330955226 793 /* maximum transfer unit */
mbed_official 10:ab9330955226 794 netif->mtu = 1500;
mbed_official 10:ab9330955226 795
mbed_official 10:ab9330955226 796 /* device capabilities */
mbed_official 10:ab9330955226 797 // TODOETH: check if the flags are correct below
mbed_official 10:ab9330955226 798 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
mbed_official 10:ab9330955226 799
mbed_official 10:ab9330955226 800 /* Initialize the hardware */
mbed_official 10:ab9330955226 801 netif->state = &k64f_enetdata;
mbed_official 10:ab9330955226 802 err = low_level_init(netif);
mbed_official 10:ab9330955226 803 if (err != ERR_OK)
mbed_official 10:ab9330955226 804 return err;
mbed_official 10:ab9330955226 805
mbed_official 10:ab9330955226 806 #if LWIP_NETIF_HOSTNAME
mbed_official 10:ab9330955226 807 /* Initialize interface hostname */
mbed_official 10:ab9330955226 808 netif->hostname = "lwipk64f";
mbed_official 10:ab9330955226 809 #endif /* LWIP_NETIF_HOSTNAME */
mbed_official 10:ab9330955226 810
mbed_official 10:ab9330955226 811 netif->name[0] = 'e';
mbed_official 10:ab9330955226 812 netif->name[1] = 'n';
mbed_official 10:ab9330955226 813
mbed_official 10:ab9330955226 814 netif->output = k64f_etharp_output;
mbed_official 10:ab9330955226 815 netif->linkoutput = k64f_low_level_output;
mbed_official 10:ab9330955226 816
mbed_official 10:ab9330955226 817 /* CMSIS-RTOS, start tasks */
mbed_official 10:ab9330955226 818 #ifdef CMSIS_OS_RTX
mbed_official 10:ab9330955226 819 memset(k64f_enetdata.xTXDCountSem.data, 0, sizeof(k64f_enetdata.xTXDCountSem.data));
mbed_official 10:ab9330955226 820 k64f_enetdata.xTXDCountSem.def.semaphore = k64f_enetdata.xTXDCountSem.data;
mbed_official 10:ab9330955226 821 #endif
mbed_official 10:ab9330955226 822 k64f_enetdata.xTXDCountSem.id = osSemaphoreCreate(&k64f_enetdata.xTXDCountSem.def, ENET_TX_RING_LEN);
mbed_official 10:ab9330955226 823
mbed_official 10:ab9330955226 824 LWIP_ASSERT("xTXDCountSem creation error", (k64f_enetdata.xTXDCountSem.id != NULL));
mbed_official 10:ab9330955226 825
mbed_official 10:ab9330955226 826 err = sys_mutex_new(&k64f_enetdata.TXLockMutex);
mbed_official 10:ab9330955226 827 LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
mbed_official 10:ab9330955226 828
mbed_official 10:ab9330955226 829 /* Packet receive task */
mbed_official 10:ab9330955226 830 err = sys_sem_new(&k64f_enetdata.RxReadySem, 0);
mbed_official 10:ab9330955226 831 LWIP_ASSERT("RxReadySem creation error", (err == ERR_OK));
mbed_official 10:ab9330955226 832 sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
mbed_official 10:ab9330955226 833
mbed_official 10:ab9330955226 834 /* Transmit cleanup task */
mbed_official 10:ab9330955226 835 err = sys_sem_new(&k64f_enetdata.TxCleanSem, 0);
mbed_official 10:ab9330955226 836 LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK));
mbed_official 10:ab9330955226 837 sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY);
mbed_official 10:ab9330955226 838
mbed_official 10:ab9330955226 839 /* PHY monitoring task */
mbed_official 10:ab9330955226 840 sys_thread_new("phy_thread", k64f_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_PRIORITY);
mbed_official 10:ab9330955226 841
mbed_official 10:ab9330955226 842 /* Allow the PHY task to detect the initial link state and set up the proper flags */
mbed_official 10:ab9330955226 843 osDelay(10);
mbed_official 10:ab9330955226 844
mbed_official 10:ab9330955226 845 return ERR_OK;
mbed_official 10:ab9330955226 846 }
mbed_official 10:ab9330955226 847
mbed_official 10:ab9330955226 848 void eth_arch_enable_interrupts(void) {
mbed_official 10:ab9330955226 849 enet_hal_config_interrupt(BOARD_DEBUG_ENET_INSTANCE, (kEnetTxFrameInterrupt | kEnetRxFrameInterrupt), true);
mbed_official 10:ab9330955226 850 interrupt_enable(enet_irq_ids[BOARD_DEBUG_ENET_INSTANCE][enetIntMap[kEnetRxfInt]]);
mbed_official 10:ab9330955226 851 interrupt_enable(enet_irq_ids[BOARD_DEBUG_ENET_INSTANCE][enetIntMap[kEnetTxfInt]]);
mbed_official 10:ab9330955226 852 }
mbed_official 10:ab9330955226 853
mbed_official 10:ab9330955226 854 void eth_arch_disable_interrupts(void) {
mbed_official 10:ab9330955226 855 interrupt_disable(enet_irq_ids[BOARD_DEBUG_ENET_INSTANCE][enetIntMap[kEnetRxfInt]]);
mbed_official 10:ab9330955226 856 interrupt_disable(enet_irq_ids[BOARD_DEBUG_ENET_INSTANCE][enetIntMap[kEnetTxfInt]]);
mbed_official 10:ab9330955226 857 }
mbed_official 10:ab9330955226 858
mbed_official 15:82aaaa2f4d5c 859 void ENET_Transmit_IRQHandler(void)
mbed_official 15:82aaaa2f4d5c 860 {
mbed_official 15:82aaaa2f4d5c 861 enet_mac_tx_isr(enetIfHandle);
mbed_official 15:82aaaa2f4d5c 862 }
mbed_official 15:82aaaa2f4d5c 863
mbed_official 15:82aaaa2f4d5c 864 void ENET_Receive_IRQHandler(void)
mbed_official 15:82aaaa2f4d5c 865 {
mbed_official 15:82aaaa2f4d5c 866 enet_mac_rx_isr(enetIfHandle);
mbed_official 15:82aaaa2f4d5c 867 }
mbed_official 15:82aaaa2f4d5c 868
mbed_official 15:82aaaa2f4d5c 869 #if FSL_FEATURE_ENET_SUPPORT_PTP
mbed_official 15:82aaaa2f4d5c 870 void ENET_1588_Timer_IRQHandler(void)
mbed_official 15:82aaaa2f4d5c 871 {
mbed_official 15:82aaaa2f4d5c 872 enet_mac_ts_isr(enetIfHandle);
mbed_official 15:82aaaa2f4d5c 873 }
mbed_official 15:82aaaa2f4d5c 874 #endif
mbed_official 10:ab9330955226 875 /**
mbed_official 10:ab9330955226 876 * @}
mbed_official 10:ab9330955226 877 */
mbed_official 10:ab9330955226 878
mbed_official 10:ab9330955226 879 /* --------------------------------- End Of File ------------------------------ */
mbed_official 10:ab9330955226 880