lab 3

Committer:
mbed_official
Date:
Thu May 26 09:00:26 2016 +0100
Revision:
33:9de8bd8ca1c8
Synchronized with git revision 745ebbf4557f0f3964f73063c1d88ddbcda0ed22

Full URL: https://github.com/mbedmicro/mbed/commit/745ebbf4557f0f3964f73063c1d88ddbcda0ed22/

Synch - fix lwip-eth path

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 33:9de8bd8ca1c8 1 #include "lwip/opt.h"
mbed_official 33:9de8bd8ca1c8 2 #include "lwip/sys.h"
mbed_official 33:9de8bd8ca1c8 3 #include "lwip/def.h"
mbed_official 33:9de8bd8ca1c8 4 #include "lwip/mem.h"
mbed_official 33:9de8bd8ca1c8 5 #include "lwip/pbuf.h"
mbed_official 33:9de8bd8ca1c8 6 #include "lwip/stats.h"
mbed_official 33:9de8bd8ca1c8 7 #include "lwip/snmp.h"
mbed_official 33:9de8bd8ca1c8 8 #include "lwip/tcpip.h"
mbed_official 33:9de8bd8ca1c8 9 #include "netif/etharp.h"
mbed_official 33:9de8bd8ca1c8 10 #include "netif/ppp_oe.h"
mbed_official 33:9de8bd8ca1c8 11
mbed_official 33:9de8bd8ca1c8 12 #include "eth_arch.h"
mbed_official 33:9de8bd8ca1c8 13 #include "sys_arch.h"
mbed_official 33:9de8bd8ca1c8 14
mbed_official 33:9de8bd8ca1c8 15 #include "fsl_phy.h"
mbed_official 33:9de8bd8ca1c8 16 #include "k64f_emac_config.h"
mbed_official 33:9de8bd8ca1c8 17 #include <ctype.h>
mbed_official 33:9de8bd8ca1c8 18 #include <stdio.h>
mbed_official 33:9de8bd8ca1c8 19 #include <string.h>
mbed_official 33:9de8bd8ca1c8 20 #include <stdlib.h>
mbed_official 33:9de8bd8ca1c8 21
mbed_official 33:9de8bd8ca1c8 22 #include "mbed_interface.h"
mbed_official 33:9de8bd8ca1c8 23
mbed_official 33:9de8bd8ca1c8 24 enet_handle_t g_handle;
mbed_official 33:9de8bd8ca1c8 25 // TX Buffer descriptors
mbed_official 33:9de8bd8ca1c8 26 uint8_t *tx_desc_start_addr;
mbed_official 33:9de8bd8ca1c8 27 // RX Buffer descriptors
mbed_official 33:9de8bd8ca1c8 28 uint8_t *rx_desc_start_addr;
mbed_official 33:9de8bd8ca1c8 29 // RX packet buffer pointers
mbed_official 33:9de8bd8ca1c8 30 struct pbuf *rx_buff[ENET_RX_RING_LEN];
mbed_official 33:9de8bd8ca1c8 31 // TX packet buffer pointers
mbed_official 33:9de8bd8ca1c8 32 struct pbuf *tx_buff[ENET_RX_RING_LEN];
mbed_official 33:9de8bd8ca1c8 33 // RX packet payload pointers
mbed_official 33:9de8bd8ca1c8 34 uint32_t *rx_ptr[ENET_RX_RING_LEN];
mbed_official 33:9de8bd8ca1c8 35
mbed_official 33:9de8bd8ca1c8 36 /********************************************************************************
mbed_official 33:9de8bd8ca1c8 37 * Internal data
mbed_official 33:9de8bd8ca1c8 38 ********************************************************************************/
mbed_official 33:9de8bd8ca1c8 39 #define ENET_BuffSizeAlign(n) ENET_ALIGN(n, ENET_BUFF_ALIGNMENT)
mbed_official 33:9de8bd8ca1c8 40 #define ENET_ALIGN(x,align) ((unsigned int)((x) + ((align)-1)) & (unsigned int)(~(unsigned int)((align)- 1)))
mbed_official 33:9de8bd8ca1c8 41 extern void k64f_init_eth_hardware(void);
mbed_official 33:9de8bd8ca1c8 42
mbed_official 33:9de8bd8ca1c8 43 /* K64F EMAC driver data structure */
mbed_official 33:9de8bd8ca1c8 44 struct k64f_enetdata {
mbed_official 33:9de8bd8ca1c8 45 struct netif *netif; /**< Reference back to LWIP parent netif */
mbed_official 33:9de8bd8ca1c8 46 sys_sem_t RxReadySem; /**< RX packet ready semaphore */
mbed_official 33:9de8bd8ca1c8 47 sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
mbed_official 33:9de8bd8ca1c8 48 sys_mutex_t TXLockMutex; /**< TX critical section mutex */
mbed_official 33:9de8bd8ca1c8 49 sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
mbed_official 33:9de8bd8ca1c8 50 uint8_t tx_consume_index, tx_produce_index; /**< TX buffers ring */
mbed_official 33:9de8bd8ca1c8 51 };
mbed_official 33:9de8bd8ca1c8 52
mbed_official 33:9de8bd8ca1c8 53 static struct k64f_enetdata k64f_enetdata;
mbed_official 33:9de8bd8ca1c8 54
mbed_official 33:9de8bd8ca1c8 55 /** \brief Driver transmit and receive thread priorities
mbed_official 33:9de8bd8ca1c8 56 *
mbed_official 33:9de8bd8ca1c8 57 * Thread priorities for receive thread and TX cleanup thread. Alter
mbed_official 33:9de8bd8ca1c8 58 * to prioritize receive or transmit bandwidth. In a heavily loaded
mbed_official 33:9de8bd8ca1c8 59 * system or with LEIP_DEBUG enabled, the priorities might be better
mbed_official 33:9de8bd8ca1c8 60 * the same. */
mbed_official 33:9de8bd8ca1c8 61 #define RX_PRIORITY (osPriorityNormal)
mbed_official 33:9de8bd8ca1c8 62 #define TX_PRIORITY (osPriorityNormal)
mbed_official 33:9de8bd8ca1c8 63 #define PHY_PRIORITY (osPriorityNormal)
mbed_official 33:9de8bd8ca1c8 64
mbed_official 33:9de8bd8ca1c8 65 /********************************************************************************
mbed_official 33:9de8bd8ca1c8 66 * Buffer management
mbed_official 33:9de8bd8ca1c8 67 ********************************************************************************/
mbed_official 33:9de8bd8ca1c8 68 /*
mbed_official 33:9de8bd8ca1c8 69 * This function will queue a new receive buffer
mbed_official 33:9de8bd8ca1c8 70 */
mbed_official 33:9de8bd8ca1c8 71 static void update_read_buffer(uint8_t *buf)
mbed_official 33:9de8bd8ca1c8 72 {
mbed_official 33:9de8bd8ca1c8 73 if (buf != NULL) {
mbed_official 33:9de8bd8ca1c8 74 g_handle.rxBdCurrent->buffer = buf;
mbed_official 33:9de8bd8ca1c8 75 }
mbed_official 33:9de8bd8ca1c8 76
mbed_official 33:9de8bd8ca1c8 77 /* Clears status. */
mbed_official 33:9de8bd8ca1c8 78 g_handle.rxBdCurrent->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
mbed_official 33:9de8bd8ca1c8 79
mbed_official 33:9de8bd8ca1c8 80 /* Sets the receive buffer descriptor with the empty flag. */
mbed_official 33:9de8bd8ca1c8 81 g_handle.rxBdCurrent->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
mbed_official 33:9de8bd8ca1c8 82
mbed_official 33:9de8bd8ca1c8 83 /* Increases the buffer descriptor to the next one. */
mbed_official 33:9de8bd8ca1c8 84 if (g_handle.rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) {
mbed_official 33:9de8bd8ca1c8 85 g_handle.rxBdCurrent = g_handle.rxBdBase;
mbed_official 33:9de8bd8ca1c8 86 g_handle.rxBdDirty = g_handle.rxBdBase;
mbed_official 33:9de8bd8ca1c8 87 } else {
mbed_official 33:9de8bd8ca1c8 88 g_handle.rxBdCurrent++;
mbed_official 33:9de8bd8ca1c8 89 g_handle.rxBdDirty++;
mbed_official 33:9de8bd8ca1c8 90 }
mbed_official 33:9de8bd8ca1c8 91
mbed_official 33:9de8bd8ca1c8 92 /* Actives the receive buffer descriptor. */
mbed_official 33:9de8bd8ca1c8 93 ENET->RDAR = ENET_RDAR_RDAR_MASK;
mbed_official 33:9de8bd8ca1c8 94 }
mbed_official 33:9de8bd8ca1c8 95
mbed_official 33:9de8bd8ca1c8 96 /** \brief Free TX buffers that are complete
mbed_official 33:9de8bd8ca1c8 97 *
mbed_official 33:9de8bd8ca1c8 98 * \param[in] k64f_enet Pointer to driver data structure
mbed_official 33:9de8bd8ca1c8 99 */
mbed_official 33:9de8bd8ca1c8 100 static void k64f_tx_reclaim(struct k64f_enetdata *k64f_enet)
mbed_official 33:9de8bd8ca1c8 101 {
mbed_official 33:9de8bd8ca1c8 102 uint8_t i = 0 ;
mbed_official 33:9de8bd8ca1c8 103
mbed_official 33:9de8bd8ca1c8 104 /* Get exclusive access */
mbed_official 33:9de8bd8ca1c8 105 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 106
mbed_official 33:9de8bd8ca1c8 107 i = k64f_enet->tx_consume_index;
mbed_official 33:9de8bd8ca1c8 108 // Traverse all descriptors, looking for the ones modified by the uDMA
mbed_official 33:9de8bd8ca1c8 109 while((i != k64f_enet->tx_produce_index) && (!(g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))) {
mbed_official 33:9de8bd8ca1c8 110 pbuf_free(tx_buff[i]);
mbed_official 33:9de8bd8ca1c8 111 if (g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
mbed_official 33:9de8bd8ca1c8 112 g_handle.txBdDirty = g_handle.txBdBase;
mbed_official 33:9de8bd8ca1c8 113 else
mbed_official 33:9de8bd8ca1c8 114 g_handle.txBdDirty++;
mbed_official 33:9de8bd8ca1c8 115
mbed_official 33:9de8bd8ca1c8 116 i = (i + 1) % ENET_TX_RING_LEN;
mbed_official 33:9de8bd8ca1c8 117 }
mbed_official 33:9de8bd8ca1c8 118
mbed_official 33:9de8bd8ca1c8 119 k64f_enet->tx_consume_index = i;
mbed_official 33:9de8bd8ca1c8 120 /* Restore access */
mbed_official 33:9de8bd8ca1c8 121 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 122 }
mbed_official 33:9de8bd8ca1c8 123
mbed_official 33:9de8bd8ca1c8 124 /** \brief Ethernet receive interrupt handler
mbed_official 33:9de8bd8ca1c8 125 *
mbed_official 33:9de8bd8ca1c8 126 * This function handles the receive interrupt of K64F.
mbed_official 33:9de8bd8ca1c8 127 */
mbed_official 33:9de8bd8ca1c8 128 void enet_mac_rx_isr()
mbed_official 33:9de8bd8ca1c8 129 {
mbed_official 33:9de8bd8ca1c8 130 sys_sem_signal(&k64f_enetdata.RxReadySem);
mbed_official 33:9de8bd8ca1c8 131 }
mbed_official 33:9de8bd8ca1c8 132
mbed_official 33:9de8bd8ca1c8 133 void enet_mac_tx_isr()
mbed_official 33:9de8bd8ca1c8 134 {
mbed_official 33:9de8bd8ca1c8 135 sys_sem_signal(&k64f_enetdata.TxCleanSem);
mbed_official 33:9de8bd8ca1c8 136 }
mbed_official 33:9de8bd8ca1c8 137
mbed_official 33:9de8bd8ca1c8 138 void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param)
mbed_official 33:9de8bd8ca1c8 139 {
mbed_official 33:9de8bd8ca1c8 140 switch (event)
mbed_official 33:9de8bd8ca1c8 141 {
mbed_official 33:9de8bd8ca1c8 142 case kENET_RxEvent:
mbed_official 33:9de8bd8ca1c8 143 enet_mac_rx_isr();
mbed_official 33:9de8bd8ca1c8 144 break;
mbed_official 33:9de8bd8ca1c8 145 case kENET_TxEvent:
mbed_official 33:9de8bd8ca1c8 146 enet_mac_tx_isr();
mbed_official 33:9de8bd8ca1c8 147 break;
mbed_official 33:9de8bd8ca1c8 148 default:
mbed_official 33:9de8bd8ca1c8 149 break;
mbed_official 33:9de8bd8ca1c8 150 }
mbed_official 33:9de8bd8ca1c8 151 }
mbed_official 33:9de8bd8ca1c8 152
mbed_official 33:9de8bd8ca1c8 153 /** \brief Low level init of the MAC and PHY.
mbed_official 33:9de8bd8ca1c8 154 *
mbed_official 33:9de8bd8ca1c8 155 * \param[in] netif Pointer to LWIP netif structure
mbed_official 33:9de8bd8ca1c8 156 */
mbed_official 33:9de8bd8ca1c8 157 static err_t low_level_init(struct netif *netif)
mbed_official 33:9de8bd8ca1c8 158 {
mbed_official 33:9de8bd8ca1c8 159 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 33:9de8bd8ca1c8 160 uint8_t i;
mbed_official 33:9de8bd8ca1c8 161 uint32_t sysClock;
mbed_official 33:9de8bd8ca1c8 162 phy_speed_t phy_speed;
mbed_official 33:9de8bd8ca1c8 163 phy_duplex_t phy_duplex;
mbed_official 33:9de8bd8ca1c8 164 uint32_t phyAddr = 0;
mbed_official 33:9de8bd8ca1c8 165 bool link = false;
mbed_official 33:9de8bd8ca1c8 166 enet_config_t config;
mbed_official 33:9de8bd8ca1c8 167
mbed_official 33:9de8bd8ca1c8 168 // Allocate RX descriptors
mbed_official 33:9de8bd8ca1c8 169 rx_desc_start_addr = (uint8_t *)calloc(1, sizeof(enet_rx_bd_struct_t) * ENET_RX_RING_LEN + ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 170 if(!rx_desc_start_addr)
mbed_official 33:9de8bd8ca1c8 171 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 172
mbed_official 33:9de8bd8ca1c8 173 // Allocate TX descriptors
mbed_official 33:9de8bd8ca1c8 174 tx_desc_start_addr = (uint8_t *)calloc(1, sizeof(enet_tx_bd_struct_t) * ENET_TX_RING_LEN + ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 175 if(!tx_desc_start_addr)
mbed_official 33:9de8bd8ca1c8 176 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 177
mbed_official 33:9de8bd8ca1c8 178 rx_desc_start_addr = (uint8_t *)ENET_ALIGN(rx_desc_start_addr, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 179 tx_desc_start_addr = (uint8_t *)ENET_ALIGN(tx_desc_start_addr, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 180
mbed_official 33:9de8bd8ca1c8 181 /* Create buffers for each receive BD */
mbed_official 33:9de8bd8ca1c8 182 for (i = 0; i < ENET_RX_RING_LEN; i++) {
mbed_official 33:9de8bd8ca1c8 183 rx_buff[i] = pbuf_alloc(PBUF_RAW, ENET_ETH_MAX_FLEN + ENET_BUFF_ALIGNMENT, PBUF_RAM);
mbed_official 33:9de8bd8ca1c8 184 if (NULL == rx_buff[i])
mbed_official 33:9de8bd8ca1c8 185 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 186
mbed_official 33:9de8bd8ca1c8 187 /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
mbed_official 33:9de8bd8ca1c8 188 RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
mbed_official 33:9de8bd8ca1c8 189 a data structure which is internal to lwIP. This might not prove to be a good idea
mbed_official 33:9de8bd8ca1c8 190 in the long run, but a better fix would probably involve modifying lwIP itself */
mbed_official 33:9de8bd8ca1c8 191 rx_buff[i]->payload = (void*)ENET_ALIGN((uint32_t)rx_buff[i]->payload, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 192 rx_ptr[i] = rx_buff[i]->payload;
mbed_official 33:9de8bd8ca1c8 193 }
mbed_official 33:9de8bd8ca1c8 194
mbed_official 33:9de8bd8ca1c8 195 k64f_enet->tx_consume_index = k64f_enet->tx_produce_index = 0;
mbed_official 33:9de8bd8ca1c8 196
mbed_official 33:9de8bd8ca1c8 197 /* prepare the buffer configuration. */
mbed_official 33:9de8bd8ca1c8 198 enet_buffer_config_t buffCfg = {
mbed_official 33:9de8bd8ca1c8 199 ENET_RX_RING_LEN,
mbed_official 33:9de8bd8ca1c8 200 ENET_TX_RING_LEN,
mbed_official 33:9de8bd8ca1c8 201 ENET_ALIGN(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT),
mbed_official 33:9de8bd8ca1c8 202 0,
mbed_official 33:9de8bd8ca1c8 203 (volatile enet_rx_bd_struct_t *)rx_desc_start_addr,
mbed_official 33:9de8bd8ca1c8 204 (volatile enet_tx_bd_struct_t *)tx_desc_start_addr,
mbed_official 33:9de8bd8ca1c8 205 (uint8_t *)&rx_ptr,
mbed_official 33:9de8bd8ca1c8 206 NULL,
mbed_official 33:9de8bd8ca1c8 207 };
mbed_official 33:9de8bd8ca1c8 208
mbed_official 33:9de8bd8ca1c8 209 k64f_init_eth_hardware();
mbed_official 33:9de8bd8ca1c8 210
mbed_official 33:9de8bd8ca1c8 211 sysClock = CLOCK_GetFreq(kCLOCK_CoreSysClk);
mbed_official 33:9de8bd8ca1c8 212
mbed_official 33:9de8bd8ca1c8 213 ENET_GetDefaultConfig(&config);
mbed_official 33:9de8bd8ca1c8 214
mbed_official 33:9de8bd8ca1c8 215 PHY_Init(ENET, 0, sysClock);
mbed_official 33:9de8bd8ca1c8 216 PHY_GetLinkStatus(ENET, phyAddr, &link);
mbed_official 33:9de8bd8ca1c8 217 if (link)
mbed_official 33:9de8bd8ca1c8 218 {
mbed_official 33:9de8bd8ca1c8 219 /* Get link information from PHY */
mbed_official 33:9de8bd8ca1c8 220 PHY_GetLinkSpeedDuplex(ENET, phyAddr, &phy_speed, &phy_duplex);
mbed_official 33:9de8bd8ca1c8 221 /* Change the MII speed and duplex for actual link status. */
mbed_official 33:9de8bd8ca1c8 222 config.miiSpeed = (enet_mii_speed_t)phy_speed;
mbed_official 33:9de8bd8ca1c8 223 config.miiDuplex = (enet_mii_duplex_t)phy_duplex;
mbed_official 33:9de8bd8ca1c8 224 config.interrupt = kENET_RxFrameInterrupt | kENET_TxFrameInterrupt;
mbed_official 33:9de8bd8ca1c8 225 }
mbed_official 33:9de8bd8ca1c8 226 config.rxMaxFrameLen = ENET_ETH_MAX_FLEN;
mbed_official 33:9de8bd8ca1c8 227 config.macSpecialConfig = kENET_ControlFlowControlEnable;
mbed_official 33:9de8bd8ca1c8 228 config.txAccelerConfig = kENET_TxAccelIsShift16Enabled;
mbed_official 33:9de8bd8ca1c8 229 config.rxAccelerConfig = kENET_RxAccelisShift16Enabled | kENET_RxAccelMacCheckEnabled;
mbed_official 33:9de8bd8ca1c8 230 ENET_Init(ENET, &g_handle, &config, &buffCfg, netif->hwaddr, sysClock);
mbed_official 33:9de8bd8ca1c8 231 ENET_SetCallback(&g_handle, ethernet_callback, netif);
mbed_official 33:9de8bd8ca1c8 232 ENET_ActiveRead(ENET);
mbed_official 33:9de8bd8ca1c8 233
mbed_official 33:9de8bd8ca1c8 234 return ERR_OK;
mbed_official 33:9de8bd8ca1c8 235 }
mbed_official 33:9de8bd8ca1c8 236
mbed_official 33:9de8bd8ca1c8 237
mbed_official 33:9de8bd8ca1c8 238 /**
mbed_official 33:9de8bd8ca1c8 239 * This function is the ethernet packet send function. It calls
mbed_official 33:9de8bd8ca1c8 240 * etharp_output after checking link status.
mbed_official 33:9de8bd8ca1c8 241 *
mbed_official 33:9de8bd8ca1c8 242 * \param[in] netif the lwip network interface structure for this enetif
mbed_official 33:9de8bd8ca1c8 243 * \param[in] q Pointer to pbug to send
mbed_official 33:9de8bd8ca1c8 244 * \param[in] ipaddr IP address
mbed_official 33:9de8bd8ca1c8 245 * \return ERR_OK or error code
mbed_official 33:9de8bd8ca1c8 246 */
mbed_official 33:9de8bd8ca1c8 247 err_t k64f_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
mbed_official 33:9de8bd8ca1c8 248 {
mbed_official 33:9de8bd8ca1c8 249 /* Only send packet is link is up */
mbed_official 33:9de8bd8ca1c8 250 if (netif->flags & NETIF_FLAG_LINK_UP)
mbed_official 33:9de8bd8ca1c8 251 return etharp_output(netif, q, ipaddr);
mbed_official 33:9de8bd8ca1c8 252
mbed_official 33:9de8bd8ca1c8 253 return ERR_CONN;
mbed_official 33:9de8bd8ca1c8 254 }
mbed_official 33:9de8bd8ca1c8 255
mbed_official 33:9de8bd8ca1c8 256 /** \brief Allocates a pbuf and returns the data from the incoming packet.
mbed_official 33:9de8bd8ca1c8 257 *
mbed_official 33:9de8bd8ca1c8 258 * \param[in] netif the lwip network interface structure
mbed_official 33:9de8bd8ca1c8 259 * \param[in] idx index of packet to be read
mbed_official 33:9de8bd8ca1c8 260 * \return a pbuf filled with the received packet (including MAC header)
mbed_official 33:9de8bd8ca1c8 261 */
mbed_official 33:9de8bd8ca1c8 262 static struct pbuf *k64f_low_level_input(struct netif *netif, int idx)
mbed_official 33:9de8bd8ca1c8 263 {
mbed_official 33:9de8bd8ca1c8 264 volatile enet_rx_bd_struct_t *bdPtr = g_handle.rxBdCurrent;
mbed_official 33:9de8bd8ca1c8 265 struct pbuf *p = NULL;
mbed_official 33:9de8bd8ca1c8 266 struct pbuf *temp_rxbuf = NULL;
mbed_official 33:9de8bd8ca1c8 267 u32_t length = 0;
mbed_official 33:9de8bd8ca1c8 268 const u16_t err_mask = ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK | ENET_BUFFDESCRIPTOR_RX_CRC_MASK |
mbed_official 33:9de8bd8ca1c8 269 ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK | ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK;
mbed_official 33:9de8bd8ca1c8 270
mbed_official 33:9de8bd8ca1c8 271
mbed_official 33:9de8bd8ca1c8 272 #ifdef LOCK_RX_THREAD
mbed_official 33:9de8bd8ca1c8 273 /* Get exclusive access */
mbed_official 33:9de8bd8ca1c8 274 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 275 #endif
mbed_official 33:9de8bd8ca1c8 276
mbed_official 33:9de8bd8ca1c8 277 /* Determine if a frame has been received */
mbed_official 33:9de8bd8ca1c8 278 if ((bdPtr->control & err_mask) != 0) {
mbed_official 33:9de8bd8ca1c8 279 #if LINK_STATS
mbed_official 33:9de8bd8ca1c8 280 if ((bdPtr->control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK) != 0)
mbed_official 33:9de8bd8ca1c8 281 LINK_STATS_INC(link.lenerr);
mbed_official 33:9de8bd8ca1c8 282 else
mbed_official 33:9de8bd8ca1c8 283 LINK_STATS_INC(link.chkerr);
mbed_official 33:9de8bd8ca1c8 284 #endif
mbed_official 33:9de8bd8ca1c8 285 LINK_STATS_INC(link.drop);
mbed_official 33:9de8bd8ca1c8 286 /* Re-use the same buffer in case of error */
mbed_official 33:9de8bd8ca1c8 287 update_read_buffer(NULL);
mbed_official 33:9de8bd8ca1c8 288 } else {
mbed_official 33:9de8bd8ca1c8 289 /* A packet is waiting, get length */
mbed_official 33:9de8bd8ca1c8 290 length = bdPtr->length;
mbed_official 33:9de8bd8ca1c8 291
mbed_official 33:9de8bd8ca1c8 292 /* Zero-copy */
mbed_official 33:9de8bd8ca1c8 293 p = rx_buff[idx];
mbed_official 33:9de8bd8ca1c8 294 p->len = length;
mbed_official 33:9de8bd8ca1c8 295
mbed_official 33:9de8bd8ca1c8 296 /* Attempt to queue new buffer */
mbed_official 33:9de8bd8ca1c8 297 temp_rxbuf = pbuf_alloc(PBUF_RAW, ENET_ETH_MAX_FLEN + ENET_BUFF_ALIGNMENT, PBUF_RAM);
mbed_official 33:9de8bd8ca1c8 298 if (NULL == temp_rxbuf) {
mbed_official 33:9de8bd8ca1c8 299 /* Drop frame (out of memory) */
mbed_official 33:9de8bd8ca1c8 300 LINK_STATS_INC(link.drop);
mbed_official 33:9de8bd8ca1c8 301
mbed_official 33:9de8bd8ca1c8 302 /* Re-queue the same buffer */
mbed_official 33:9de8bd8ca1c8 303 update_read_buffer(NULL);
mbed_official 33:9de8bd8ca1c8 304
mbed_official 33:9de8bd8ca1c8 305 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 33:9de8bd8ca1c8 306 ("k64f_low_level_input: Packet index %d dropped for OOM\n",
mbed_official 33:9de8bd8ca1c8 307 idx));
mbed_official 33:9de8bd8ca1c8 308 #ifdef LOCK_RX_THREAD
mbed_official 33:9de8bd8ca1c8 309 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 310 #endif
mbed_official 33:9de8bd8ca1c8 311
mbed_official 33:9de8bd8ca1c8 312 return NULL;
mbed_official 33:9de8bd8ca1c8 313 }
mbed_official 33:9de8bd8ca1c8 314
mbed_official 33:9de8bd8ca1c8 315 rx_buff[idx] = temp_rxbuf;
mbed_official 33:9de8bd8ca1c8 316 /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
mbed_official 33:9de8bd8ca1c8 317 RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
mbed_official 33:9de8bd8ca1c8 318 a data structure which is internal to lwIP. This might not prove to be a good idea
mbed_official 33:9de8bd8ca1c8 319 in the long run, but a better fix would probably involve modifying lwIP itself */
mbed_official 33:9de8bd8ca1c8 320 rx_buff[idx]->payload = (void*)ENET_ALIGN((uint32_t)rx_buff[idx]->payload, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 321 rx_ptr[idx] = rx_buff[idx]->payload;
mbed_official 33:9de8bd8ca1c8 322
mbed_official 33:9de8bd8ca1c8 323 update_read_buffer(rx_buff[idx]->payload);
mbed_official 33:9de8bd8ca1c8 324 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 33:9de8bd8ca1c8 325 ("k64f_low_level_input: Packet received: %p, size %d (index=%d)\n",
mbed_official 33:9de8bd8ca1c8 326 p, length, idx));
mbed_official 33:9de8bd8ca1c8 327
mbed_official 33:9de8bd8ca1c8 328 /* Save size */
mbed_official 33:9de8bd8ca1c8 329 p->tot_len = (u16_t) length;
mbed_official 33:9de8bd8ca1c8 330 LINK_STATS_INC(link.recv);
mbed_official 33:9de8bd8ca1c8 331 }
mbed_official 33:9de8bd8ca1c8 332
mbed_official 33:9de8bd8ca1c8 333 #ifdef LOCK_RX_THREAD
mbed_official 33:9de8bd8ca1c8 334 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 335 #endif
mbed_official 33:9de8bd8ca1c8 336
mbed_official 33:9de8bd8ca1c8 337 return p;
mbed_official 33:9de8bd8ca1c8 338 }
mbed_official 33:9de8bd8ca1c8 339
mbed_official 33:9de8bd8ca1c8 340 /** \brief Attempt to read a packet from the EMAC interface.
mbed_official 33:9de8bd8ca1c8 341 *
mbed_official 33:9de8bd8ca1c8 342 * \param[in] netif the lwip network interface structure
mbed_official 33:9de8bd8ca1c8 343 * \param[in] idx index of packet to be read
mbed_official 33:9de8bd8ca1c8 344 */
mbed_official 33:9de8bd8ca1c8 345 void k64f_enetif_input(struct netif *netif, int idx)
mbed_official 33:9de8bd8ca1c8 346 {
mbed_official 33:9de8bd8ca1c8 347 struct eth_hdr *ethhdr;
mbed_official 33:9de8bd8ca1c8 348 struct pbuf *p;
mbed_official 33:9de8bd8ca1c8 349
mbed_official 33:9de8bd8ca1c8 350 /* move received packet into a new pbuf */
mbed_official 33:9de8bd8ca1c8 351 p = k64f_low_level_input(netif, idx);
mbed_official 33:9de8bd8ca1c8 352 if (p == NULL)
mbed_official 33:9de8bd8ca1c8 353 return;
mbed_official 33:9de8bd8ca1c8 354
mbed_official 33:9de8bd8ca1c8 355 /* points to packet payload, which starts with an Ethernet header */
mbed_official 33:9de8bd8ca1c8 356 ethhdr = (struct eth_hdr*)p->payload;
mbed_official 33:9de8bd8ca1c8 357
mbed_official 33:9de8bd8ca1c8 358 switch (htons(ethhdr->type)) {
mbed_official 33:9de8bd8ca1c8 359 case ETHTYPE_IP:
mbed_official 33:9de8bd8ca1c8 360 case ETHTYPE_ARP:
mbed_official 33:9de8bd8ca1c8 361 #if PPPOE_SUPPORT
mbed_official 33:9de8bd8ca1c8 362 case ETHTYPE_PPPOEDISC:
mbed_official 33:9de8bd8ca1c8 363 case ETHTYPE_PPPOE:
mbed_official 33:9de8bd8ca1c8 364 #endif /* PPPOE_SUPPORT */
mbed_official 33:9de8bd8ca1c8 365 /* full packet send to tcpip_thread to process */
mbed_official 33:9de8bd8ca1c8 366 if (netif->input(p, netif) != ERR_OK) {
mbed_official 33:9de8bd8ca1c8 367 LWIP_DEBUGF(NETIF_DEBUG, ("k64f_enetif_input: IP input error\n"));
mbed_official 33:9de8bd8ca1c8 368 /* Free buffer */
mbed_official 33:9de8bd8ca1c8 369 pbuf_free(p);
mbed_official 33:9de8bd8ca1c8 370 }
mbed_official 33:9de8bd8ca1c8 371 break;
mbed_official 33:9de8bd8ca1c8 372
mbed_official 33:9de8bd8ca1c8 373 default:
mbed_official 33:9de8bd8ca1c8 374 /* Return buffer */
mbed_official 33:9de8bd8ca1c8 375 pbuf_free(p);
mbed_official 33:9de8bd8ca1c8 376 break;
mbed_official 33:9de8bd8ca1c8 377 }
mbed_official 33:9de8bd8ca1c8 378 }
mbed_official 33:9de8bd8ca1c8 379
mbed_official 33:9de8bd8ca1c8 380 /** \brief Packet reception task
mbed_official 33:9de8bd8ca1c8 381 *
mbed_official 33:9de8bd8ca1c8 382 * This task is called when a packet is received. It will
mbed_official 33:9de8bd8ca1c8 383 * pass the packet to the LWIP core.
mbed_official 33:9de8bd8ca1c8 384 *
mbed_official 33:9de8bd8ca1c8 385 * \param[in] pvParameters pointer to the interface data
mbed_official 33:9de8bd8ca1c8 386 */
mbed_official 33:9de8bd8ca1c8 387 static void packet_rx(void* pvParameters) {
mbed_official 33:9de8bd8ca1c8 388 struct k64f_enetdata *k64f_enet = pvParameters;
mbed_official 33:9de8bd8ca1c8 389 int idx = 0;
mbed_official 33:9de8bd8ca1c8 390
mbed_official 33:9de8bd8ca1c8 391 while (1) {
mbed_official 33:9de8bd8ca1c8 392 /* Wait for receive task to wakeup */
mbed_official 33:9de8bd8ca1c8 393 sys_arch_sem_wait(&k64f_enet->RxReadySem, 0);
mbed_official 33:9de8bd8ca1c8 394
mbed_official 33:9de8bd8ca1c8 395 while ((g_handle.rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK) == 0) {
mbed_official 33:9de8bd8ca1c8 396 k64f_enetif_input(k64f_enet->netif, idx);
mbed_official 33:9de8bd8ca1c8 397 idx = (idx + 1) % ENET_RX_RING_LEN;
mbed_official 33:9de8bd8ca1c8 398 }
mbed_official 33:9de8bd8ca1c8 399 }
mbed_official 33:9de8bd8ca1c8 400 }
mbed_official 33:9de8bd8ca1c8 401
mbed_official 33:9de8bd8ca1c8 402 /** \brief Transmit cleanup task
mbed_official 33:9de8bd8ca1c8 403 *
mbed_official 33:9de8bd8ca1c8 404 * This task is called when a transmit interrupt occurs and
mbed_official 33:9de8bd8ca1c8 405 * reclaims the pbuf and descriptor used for the packet once
mbed_official 33:9de8bd8ca1c8 406 * the packet has been transferred.
mbed_official 33:9de8bd8ca1c8 407 *
mbed_official 33:9de8bd8ca1c8 408 * \param[in] pvParameters pointer to the interface data
mbed_official 33:9de8bd8ca1c8 409 */
mbed_official 33:9de8bd8ca1c8 410 static void packet_tx(void* pvParameters) {
mbed_official 33:9de8bd8ca1c8 411 struct k64f_enetdata *k64f_enet = pvParameters;
mbed_official 33:9de8bd8ca1c8 412
mbed_official 33:9de8bd8ca1c8 413 while (1) {
mbed_official 33:9de8bd8ca1c8 414 /* Wait for transmit cleanup task to wakeup */
mbed_official 33:9de8bd8ca1c8 415 sys_arch_sem_wait(&k64f_enet->TxCleanSem, 0);
mbed_official 33:9de8bd8ca1c8 416 k64f_tx_reclaim(k64f_enet);
mbed_official 33:9de8bd8ca1c8 417 }
mbed_official 33:9de8bd8ca1c8 418 }
mbed_official 33:9de8bd8ca1c8 419
mbed_official 33:9de8bd8ca1c8 420 /** \brief Low level output of a packet. Never call this from an
mbed_official 33:9de8bd8ca1c8 421 * interrupt context, as it may block until TX descriptors
mbed_official 33:9de8bd8ca1c8 422 * become available.
mbed_official 33:9de8bd8ca1c8 423 *
mbed_official 33:9de8bd8ca1c8 424 * \param[in] netif the lwip network interface structure for this netif
mbed_official 33:9de8bd8ca1c8 425 * \param[in] p the MAC packet to send (e.g. IP packet including MAC addresses and type)
mbed_official 33:9de8bd8ca1c8 426 * \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent
mbed_official 33:9de8bd8ca1c8 427 */
mbed_official 33:9de8bd8ca1c8 428 static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p)
mbed_official 33:9de8bd8ca1c8 429 {
mbed_official 33:9de8bd8ca1c8 430 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 33:9de8bd8ca1c8 431 struct pbuf *q;
mbed_official 33:9de8bd8ca1c8 432 struct pbuf *temp_pbuf;
mbed_official 33:9de8bd8ca1c8 433 uint8_t *psend = NULL, *dst;
mbed_official 33:9de8bd8ca1c8 434
mbed_official 33:9de8bd8ca1c8 435
mbed_official 33:9de8bd8ca1c8 436 temp_pbuf = pbuf_alloc(PBUF_RAW, p->tot_len + ENET_BUFF_ALIGNMENT, PBUF_RAM);
mbed_official 33:9de8bd8ca1c8 437 if (NULL == temp_pbuf)
mbed_official 33:9de8bd8ca1c8 438 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 439
mbed_official 33:9de8bd8ca1c8 440 /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
mbed_official 33:9de8bd8ca1c8 441 RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
mbed_official 33:9de8bd8ca1c8 442 a data structure which is internal to lwIP. This might not prove to be a good idea
mbed_official 33:9de8bd8ca1c8 443 in the long run, but a better fix would probably involve modifying lwIP itself */
mbed_official 33:9de8bd8ca1c8 444 psend = (uint8_t *)ENET_ALIGN((uint32_t)temp_pbuf->payload, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 445
mbed_official 33:9de8bd8ca1c8 446 for (q = p, dst = psend; q != NULL; q = q->next) {
mbed_official 33:9de8bd8ca1c8 447 MEMCPY(dst, q->payload, q->len);
mbed_official 33:9de8bd8ca1c8 448 dst += q->len;
mbed_official 33:9de8bd8ca1c8 449 }
mbed_official 33:9de8bd8ca1c8 450
mbed_official 33:9de8bd8ca1c8 451 /* Wait until a descriptor is available for the transfer. */
mbed_official 33:9de8bd8ca1c8 452 /* THIS WILL BLOCK UNTIL THERE ARE A DESCRIPTOR AVAILABLE */
mbed_official 33:9de8bd8ca1c8 453 while (g_handle.txBdCurrent->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
mbed_official 33:9de8bd8ca1c8 454 osSemaphoreWait(k64f_enet->xTXDCountSem.id, osWaitForever);
mbed_official 33:9de8bd8ca1c8 455
mbed_official 33:9de8bd8ca1c8 456 /* Get exclusive access */
mbed_official 33:9de8bd8ca1c8 457 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 458
mbed_official 33:9de8bd8ca1c8 459 /* Save the buffer so that it can be freed when transmit is done */
mbed_official 33:9de8bd8ca1c8 460 tx_buff[k64f_enet->tx_produce_index] = temp_pbuf;
mbed_official 33:9de8bd8ca1c8 461 k64f_enet->tx_produce_index = (k64f_enet->tx_produce_index + 1) % ENET_TX_RING_LEN;
mbed_official 33:9de8bd8ca1c8 462
mbed_official 33:9de8bd8ca1c8 463 /* Setup transfers */
mbed_official 33:9de8bd8ca1c8 464 g_handle.txBdCurrent->buffer = psend;
mbed_official 33:9de8bd8ca1c8 465 g_handle.txBdCurrent->length = p->tot_len;
mbed_official 33:9de8bd8ca1c8 466 g_handle.txBdCurrent->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
mbed_official 33:9de8bd8ca1c8 467
mbed_official 33:9de8bd8ca1c8 468 /* Increase the buffer descriptor address. */
mbed_official 33:9de8bd8ca1c8 469 if (g_handle.txBdCurrent->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
mbed_official 33:9de8bd8ca1c8 470 g_handle.txBdCurrent = g_handle.txBdBase;
mbed_official 33:9de8bd8ca1c8 471 else
mbed_official 33:9de8bd8ca1c8 472 g_handle.txBdCurrent++;
mbed_official 33:9de8bd8ca1c8 473
mbed_official 33:9de8bd8ca1c8 474 /* Active the transmit buffer descriptor. */
mbed_official 33:9de8bd8ca1c8 475 ENET->TDAR = ENET_TDAR_TDAR_MASK;
mbed_official 33:9de8bd8ca1c8 476
mbed_official 33:9de8bd8ca1c8 477 LINK_STATS_INC(link.xmit);
mbed_official 33:9de8bd8ca1c8 478
mbed_official 33:9de8bd8ca1c8 479 /* Restore access */
mbed_official 33:9de8bd8ca1c8 480 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 481
mbed_official 33:9de8bd8ca1c8 482 return ERR_OK;
mbed_official 33:9de8bd8ca1c8 483 }
mbed_official 33:9de8bd8ca1c8 484
mbed_official 33:9de8bd8ca1c8 485 /*******************************************************************************
mbed_official 33:9de8bd8ca1c8 486 * PHY task: monitor link
mbed_official 33:9de8bd8ca1c8 487 *******************************************************************************/
mbed_official 33:9de8bd8ca1c8 488
mbed_official 33:9de8bd8ca1c8 489 #define PHY_TASK_PERIOD_MS 200
mbed_official 33:9de8bd8ca1c8 490 #define STATE_UNKNOWN (-1)
mbed_official 33:9de8bd8ca1c8 491
mbed_official 33:9de8bd8ca1c8 492 typedef struct {
mbed_official 33:9de8bd8ca1c8 493 int connected;
mbed_official 33:9de8bd8ca1c8 494 phy_speed_t speed;
mbed_official 33:9de8bd8ca1c8 495 phy_duplex_t duplex;
mbed_official 33:9de8bd8ca1c8 496 } PHY_STATE;
mbed_official 33:9de8bd8ca1c8 497
mbed_official 33:9de8bd8ca1c8 498 int phy_link_status() {
mbed_official 33:9de8bd8ca1c8 499 bool connection_status;
mbed_official 33:9de8bd8ca1c8 500 uint32_t phyAddr = 0;
mbed_official 33:9de8bd8ca1c8 501
mbed_official 33:9de8bd8ca1c8 502 PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
mbed_official 33:9de8bd8ca1c8 503 return (int)connection_status;
mbed_official 33:9de8bd8ca1c8 504 }
mbed_official 33:9de8bd8ca1c8 505
mbed_official 33:9de8bd8ca1c8 506 static void k64f_phy_task(void *data) {
mbed_official 33:9de8bd8ca1c8 507 struct netif *netif = (struct netif*)data;
mbed_official 33:9de8bd8ca1c8 508 bool connection_status;
mbed_official 33:9de8bd8ca1c8 509 PHY_STATE crt_state = {STATE_UNKNOWN, (phy_speed_t)STATE_UNKNOWN, (phy_duplex_t)STATE_UNKNOWN};
mbed_official 33:9de8bd8ca1c8 510 PHY_STATE prev_state;
mbed_official 33:9de8bd8ca1c8 511 uint32_t phyAddr = 0;
mbed_official 33:9de8bd8ca1c8 512 uint32_t rcr = 0;
mbed_official 33:9de8bd8ca1c8 513
mbed_official 33:9de8bd8ca1c8 514 prev_state = crt_state;
mbed_official 33:9de8bd8ca1c8 515 while (true) {
mbed_official 33:9de8bd8ca1c8 516 // Get current status
mbed_official 33:9de8bd8ca1c8 517 PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
mbed_official 33:9de8bd8ca1c8 518 crt_state.connected = connection_status ? 1 : 0;
mbed_official 33:9de8bd8ca1c8 519 // Get the actual PHY link speed
mbed_official 33:9de8bd8ca1c8 520 PHY_GetLinkSpeedDuplex(ENET, phyAddr, &crt_state.speed, &crt_state.duplex);
mbed_official 33:9de8bd8ca1c8 521
mbed_official 33:9de8bd8ca1c8 522 // Compare with previous state
mbed_official 33:9de8bd8ca1c8 523 if (crt_state.connected != prev_state.connected) {
mbed_official 33:9de8bd8ca1c8 524 if (crt_state.connected)
mbed_official 33:9de8bd8ca1c8 525 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1);
mbed_official 33:9de8bd8ca1c8 526 else
mbed_official 33:9de8bd8ca1c8 527 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1);
mbed_official 33:9de8bd8ca1c8 528 }
mbed_official 33:9de8bd8ca1c8 529
mbed_official 33:9de8bd8ca1c8 530 if (crt_state.speed != prev_state.speed) {
mbed_official 33:9de8bd8ca1c8 531 rcr = ENET->RCR;
mbed_official 33:9de8bd8ca1c8 532 rcr &= ~ENET_RCR_RMII_10T_MASK;
mbed_official 33:9de8bd8ca1c8 533 rcr |= ENET_RCR_RMII_10T(!crt_state.speed);
mbed_official 33:9de8bd8ca1c8 534 ENET->RCR = rcr;
mbed_official 33:9de8bd8ca1c8 535 }
mbed_official 33:9de8bd8ca1c8 536
mbed_official 33:9de8bd8ca1c8 537 prev_state = crt_state;
mbed_official 33:9de8bd8ca1c8 538 osDelay(PHY_TASK_PERIOD_MS);
mbed_official 33:9de8bd8ca1c8 539 }
mbed_official 33:9de8bd8ca1c8 540 }
mbed_official 33:9de8bd8ca1c8 541
mbed_official 33:9de8bd8ca1c8 542 /**
mbed_official 33:9de8bd8ca1c8 543 * Should be called at the beginning of the program to set up the
mbed_official 33:9de8bd8ca1c8 544 * network interface.
mbed_official 33:9de8bd8ca1c8 545 *
mbed_official 33:9de8bd8ca1c8 546 * This function should be passed as a parameter to netif_add().
mbed_official 33:9de8bd8ca1c8 547 *
mbed_official 33:9de8bd8ca1c8 548 * @param[in] netif the lwip network interface structure for this netif
mbed_official 33:9de8bd8ca1c8 549 * @return ERR_OK if the loopif is initialized
mbed_official 33:9de8bd8ca1c8 550 * ERR_MEM if private data couldn't be allocated
mbed_official 33:9de8bd8ca1c8 551 * any other err_t on error
mbed_official 33:9de8bd8ca1c8 552 */
mbed_official 33:9de8bd8ca1c8 553 err_t eth_arch_enetif_init(struct netif *netif)
mbed_official 33:9de8bd8ca1c8 554 {
mbed_official 33:9de8bd8ca1c8 555 err_t err;
mbed_official 33:9de8bd8ca1c8 556
mbed_official 33:9de8bd8ca1c8 557 LWIP_ASSERT("netif != NULL", (netif != NULL));
mbed_official 33:9de8bd8ca1c8 558
mbed_official 33:9de8bd8ca1c8 559 k64f_enetdata.netif = netif;
mbed_official 33:9de8bd8ca1c8 560
mbed_official 33:9de8bd8ca1c8 561 /* set MAC hardware address */
mbed_official 33:9de8bd8ca1c8 562 #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
mbed_official 33:9de8bd8ca1c8 563 netif->hwaddr[0] = MBED_MAC_ADDR_0;
mbed_official 33:9de8bd8ca1c8 564 netif->hwaddr[1] = MBED_MAC_ADDR_1;
mbed_official 33:9de8bd8ca1c8 565 netif->hwaddr[2] = MBED_MAC_ADDR_2;
mbed_official 33:9de8bd8ca1c8 566 netif->hwaddr[3] = MBED_MAC_ADDR_3;
mbed_official 33:9de8bd8ca1c8 567 netif->hwaddr[4] = MBED_MAC_ADDR_4;
mbed_official 33:9de8bd8ca1c8 568 netif->hwaddr[5] = MBED_MAC_ADDR_5;
mbed_official 33:9de8bd8ca1c8 569 #else
mbed_official 33:9de8bd8ca1c8 570 mbed_mac_address((char *)netif->hwaddr);
mbed_official 33:9de8bd8ca1c8 571 #endif
mbed_official 33:9de8bd8ca1c8 572 netif->hwaddr_len = ETHARP_HWADDR_LEN;
mbed_official 33:9de8bd8ca1c8 573
mbed_official 33:9de8bd8ca1c8 574 /* maximum transfer unit */
mbed_official 33:9de8bd8ca1c8 575 netif->mtu = 1500;
mbed_official 33:9de8bd8ca1c8 576
mbed_official 33:9de8bd8ca1c8 577 /* device capabilities */
mbed_official 33:9de8bd8ca1c8 578 // TODOETH: check if the flags are correct below
mbed_official 33:9de8bd8ca1c8 579 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
mbed_official 33:9de8bd8ca1c8 580
mbed_official 33:9de8bd8ca1c8 581 /* Initialize the hardware */
mbed_official 33:9de8bd8ca1c8 582 netif->state = &k64f_enetdata;
mbed_official 33:9de8bd8ca1c8 583 err = low_level_init(netif);
mbed_official 33:9de8bd8ca1c8 584 if (err != ERR_OK)
mbed_official 33:9de8bd8ca1c8 585 return err;
mbed_official 33:9de8bd8ca1c8 586
mbed_official 33:9de8bd8ca1c8 587 #if LWIP_NETIF_HOSTNAME
mbed_official 33:9de8bd8ca1c8 588 /* Initialize interface hostname */
mbed_official 33:9de8bd8ca1c8 589 netif->hostname = "lwipk64f";
mbed_official 33:9de8bd8ca1c8 590 #endif /* LWIP_NETIF_HOSTNAME */
mbed_official 33:9de8bd8ca1c8 591
mbed_official 33:9de8bd8ca1c8 592 netif->name[0] = 'e';
mbed_official 33:9de8bd8ca1c8 593 netif->name[1] = 'n';
mbed_official 33:9de8bd8ca1c8 594
mbed_official 33:9de8bd8ca1c8 595 netif->output = k64f_etharp_output;
mbed_official 33:9de8bd8ca1c8 596 netif->linkoutput = k64f_low_level_output;
mbed_official 33:9de8bd8ca1c8 597
mbed_official 33:9de8bd8ca1c8 598 /* CMSIS-RTOS, start tasks */
mbed_official 33:9de8bd8ca1c8 599 #ifdef CMSIS_OS_RTX
mbed_official 33:9de8bd8ca1c8 600 memset(k64f_enetdata.xTXDCountSem.data, 0, sizeof(k64f_enetdata.xTXDCountSem.data));
mbed_official 33:9de8bd8ca1c8 601 k64f_enetdata.xTXDCountSem.def.semaphore = k64f_enetdata.xTXDCountSem.data;
mbed_official 33:9de8bd8ca1c8 602 #endif
mbed_official 33:9de8bd8ca1c8 603 k64f_enetdata.xTXDCountSem.id = osSemaphoreCreate(&k64f_enetdata.xTXDCountSem.def, ENET_TX_RING_LEN);
mbed_official 33:9de8bd8ca1c8 604
mbed_official 33:9de8bd8ca1c8 605 LWIP_ASSERT("xTXDCountSem creation error", (k64f_enetdata.xTXDCountSem.id != NULL));
mbed_official 33:9de8bd8ca1c8 606
mbed_official 33:9de8bd8ca1c8 607 err = sys_mutex_new(&k64f_enetdata.TXLockMutex);
mbed_official 33:9de8bd8ca1c8 608 LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
mbed_official 33:9de8bd8ca1c8 609
mbed_official 33:9de8bd8ca1c8 610 /* Packet receive task */
mbed_official 33:9de8bd8ca1c8 611 err = sys_sem_new(&k64f_enetdata.RxReadySem, 0);
mbed_official 33:9de8bd8ca1c8 612 LWIP_ASSERT("RxReadySem creation error", (err == ERR_OK));
mbed_official 33:9de8bd8ca1c8 613 sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
mbed_official 33:9de8bd8ca1c8 614
mbed_official 33:9de8bd8ca1c8 615 /* Transmit cleanup task */
mbed_official 33:9de8bd8ca1c8 616 err = sys_sem_new(&k64f_enetdata.TxCleanSem, 0);
mbed_official 33:9de8bd8ca1c8 617 LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK));
mbed_official 33:9de8bd8ca1c8 618 sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY);
mbed_official 33:9de8bd8ca1c8 619
mbed_official 33:9de8bd8ca1c8 620 /* PHY monitoring task */
mbed_official 33:9de8bd8ca1c8 621 sys_thread_new("phy_thread", k64f_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_PRIORITY);
mbed_official 33:9de8bd8ca1c8 622
mbed_official 33:9de8bd8ca1c8 623 /* Allow the PHY task to detect the initial link state and set up the proper flags */
mbed_official 33:9de8bd8ca1c8 624 osDelay(10);
mbed_official 33:9de8bd8ca1c8 625
mbed_official 33:9de8bd8ca1c8 626 return ERR_OK;
mbed_official 33:9de8bd8ca1c8 627 }
mbed_official 33:9de8bd8ca1c8 628
mbed_official 33:9de8bd8ca1c8 629 void eth_arch_enable_interrupts(void) {
mbed_official 33:9de8bd8ca1c8 630 //NVIC_SetPriority(ENET_Receive_IRQn, 6U);
mbed_official 33:9de8bd8ca1c8 631 //NVIC_SetPriority(ENET_Transmit_IRQn, 6U);
mbed_official 33:9de8bd8ca1c8 632 }
mbed_official 33:9de8bd8ca1c8 633
mbed_official 33:9de8bd8ca1c8 634 void eth_arch_disable_interrupts(void) {
mbed_official 33:9de8bd8ca1c8 635
mbed_official 33:9de8bd8ca1c8 636 }
mbed_official 33:9de8bd8ca1c8 637
mbed_official 33:9de8bd8ca1c8 638 /**
mbed_official 33:9de8bd8ca1c8 639 * @}
mbed_official 33:9de8bd8ca1c8 640 */
mbed_official 33:9de8bd8ca1c8 641
mbed_official 33:9de8bd8ca1c8 642 /* --------------------------------- End Of File ------------------------------ */
mbed_official 33:9de8bd8ca1c8 643