lib
arch/TARGET_K64F/k64f_emac.c@10:ab9330955226, 2014-04-24 (annotated)
- Committer:
- mbed_official
- Date:
- Thu Apr 24 10:45:51 2014 +0100
- Revision:
- 10:ab9330955226
- Child:
- 11:fd39ffab9527
Synchronized with git revision 94fd2228fb4a382fb98d0115f6691fc0b659eea8
Full URL: https://github.com/mbedmicro/mbed/commit/94fd2228fb4a382fb98d0115f6691fc0b659eea8/
Currently NET_7 (HttpClient test) and NET_8 (NTP test) fail for
unknown reasons.
Who changed what in which revision?
User | Revision | Line number | New 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 | 10:ab9330955226 | 30 | |
mbed_official | 10:ab9330955226 | 31 | /******************************************************************************** |
mbed_official | 10:ab9330955226 | 32 | * Internal data |
mbed_official | 10:ab9330955226 | 33 | ********************************************************************************/ |
mbed_official | 10:ab9330955226 | 34 | |
mbed_official | 10:ab9330955226 | 35 | extern void k64f_init_eth_hardware(void); |
mbed_official | 10:ab9330955226 | 36 | |
mbed_official | 10:ab9330955226 | 37 | /* K64F EMAC driver data structure */ |
mbed_official | 10:ab9330955226 | 38 | struct k64f_enetdata { |
mbed_official | 10:ab9330955226 | 39 | struct netif *netif; /**< Reference back to LWIP parent netif */ |
mbed_official | 10:ab9330955226 | 40 | sys_sem_t RxReadySem; /**< RX packet ready semaphore */ |
mbed_official | 10:ab9330955226 | 41 | sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */ |
mbed_official | 10:ab9330955226 | 42 | sys_mutex_t TXLockMutex; /**< TX critical section mutex */ |
mbed_official | 10:ab9330955226 | 43 | sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */ |
mbed_official | 10:ab9330955226 | 44 | volatile u32_t rx_free_descs; /**< Count of free RX descriptors */ |
mbed_official | 10:ab9330955226 | 45 | struct pbuf *rxb[ENET_RX_RING_LEN]; /**< RX pbuf pointer list, zero-copy mode */ |
mbed_official | 10:ab9330955226 | 46 | uint8_t *rx_desc_start_addr; /**< RX descriptor start address */ |
mbed_official | 10:ab9330955226 | 47 | uint8_t *tx_desc_start_addr; /**< TX descriptor start address */ |
mbed_official | 10:ab9330955226 | 48 | uint8_t tx_consume_index, tx_produce_index; /**< TX buffers ring */ |
mbed_official | 10:ab9330955226 | 49 | uint8_t rx_fill_index; /**< RX ring fill index */ |
mbed_official | 10:ab9330955226 | 50 | struct pbuf *txb[ENET_TX_RING_LEN]; /**< TX pbuf pointer list, zero-copy mode */ |
mbed_official | 10:ab9330955226 | 51 | void *txb_aligned[ENET_TX_RING_LEN]; /**< TX aligned buffers (if needed) */ |
mbed_official | 10:ab9330955226 | 52 | }; |
mbed_official | 10:ab9330955226 | 53 | |
mbed_official | 10:ab9330955226 | 54 | static struct k64f_enetdata k64f_enetdata; |
mbed_official | 10:ab9330955226 | 55 | |
mbed_official | 10:ab9330955226 | 56 | static enet_dev_if_t enetDevIf[HW_ENET_INSTANCE_COUNT]; |
mbed_official | 10:ab9330955226 | 57 | static enet_mac_config_t g_enetMacCfg[HW_ENET_INSTANCE_COUNT] = |
mbed_official | 10:ab9330955226 | 58 | { |
mbed_official | 10:ab9330955226 | 59 | { |
mbed_official | 10:ab9330955226 | 60 | ENET_ETH_MAX_FLEN , /*!< enet receive buffer size*/ |
mbed_official | 10:ab9330955226 | 61 | ENET_RX_LARGE_BUFFER_NUM, /*!< enet large receive buffer number*/ |
mbed_official | 10:ab9330955226 | 62 | ENET_RX_RING_LEN, /*!< enet receive bd number*/ |
mbed_official | 10:ab9330955226 | 63 | ENET_TX_RING_LEN, /*!< enet transmit bd number*/ |
mbed_official | 10:ab9330955226 | 64 | {0}, /*!< enet mac address*/ |
mbed_official | 10:ab9330955226 | 65 | kEnetCfgRmii, /*!< enet rmii interface*/ |
mbed_official | 10:ab9330955226 | 66 | kEnetCfgSpeed100M, /*!< enet rmii 100M*/ |
mbed_official | 10:ab9330955226 | 67 | kEnetCfgFullDuplex, /*!< enet rmii Full- duplex*/ |
mbed_official | 10:ab9330955226 | 68 | /*!< enet mac control flag recommended to use enet_mac_control_flag_t |
mbed_official | 10:ab9330955226 | 69 | we send frame with crc so receive crc forward for data length check test*/ |
mbed_official | 10:ab9330955226 | 70 | kEnetRxCrcFwdEnable | kEnetRxFlowControlEnable, |
mbed_official | 10:ab9330955226 | 71 | true, /*!< enet txaccelerator enabled*/ |
mbed_official | 10:ab9330955226 | 72 | true, /*!< enet rxaccelerator enabled*/ |
mbed_official | 10:ab9330955226 | 73 | false, /*!< enet store and forward*/ |
mbed_official | 10:ab9330955226 | 74 | {false, false, true, false, true}, /*!< enet rxaccelerator config*/ |
mbed_official | 10:ab9330955226 | 75 | {false, false, true}, /*!< enet txaccelerator config*/ |
mbed_official | 10:ab9330955226 | 76 | true, /*!< vlan frame support*/ |
mbed_official | 10:ab9330955226 | 77 | true, /*!< phy auto discover*/ |
mbed_official | 10:ab9330955226 | 78 | ENET_MII_CLOCK, /*!< enet MDC clock*/ |
mbed_official | 10:ab9330955226 | 79 | }, |
mbed_official | 10:ab9330955226 | 80 | }; |
mbed_official | 10:ab9330955226 | 81 | |
mbed_official | 10:ab9330955226 | 82 | static enet_phy_config_t g_enetPhyCfg[HW_ENET_INSTANCE_COUNT] = |
mbed_official | 10:ab9330955226 | 83 | { |
mbed_official | 10:ab9330955226 | 84 | {0, false} |
mbed_official | 10:ab9330955226 | 85 | }; |
mbed_official | 10:ab9330955226 | 86 | |
mbed_official | 10:ab9330955226 | 87 | /** \brief Driver transmit and receive thread priorities |
mbed_official | 10:ab9330955226 | 88 | * |
mbed_official | 10:ab9330955226 | 89 | * Thread priorities for receive thread and TX cleanup thread. Alter |
mbed_official | 10:ab9330955226 | 90 | * to prioritize receive or transmit bandwidth. In a heavily loaded |
mbed_official | 10:ab9330955226 | 91 | * system or with LEIP_DEBUG enabled, the priorities might be better |
mbed_official | 10:ab9330955226 | 92 | * the same. */ |
mbed_official | 10:ab9330955226 | 93 | #define RX_PRIORITY (osPriorityNormal) |
mbed_official | 10:ab9330955226 | 94 | #define TX_PRIORITY (osPriorityNormal) |
mbed_official | 10:ab9330955226 | 95 | #define PHY_PRIORITY (osPriorityNormal) |
mbed_official | 10:ab9330955226 | 96 | |
mbed_official | 10:ab9330955226 | 97 | /** \brief Debug output formatter lock define |
mbed_official | 10:ab9330955226 | 98 | * |
mbed_official | 10:ab9330955226 | 99 | * When using FreeRTOS and with LWIP_DEBUG enabled, enabling this |
mbed_official | 10:ab9330955226 | 100 | * define will allow RX debug messages to not interleave with the |
mbed_official | 10:ab9330955226 | 101 | * TX messages (so they are actually readable). Not enabling this |
mbed_official | 10:ab9330955226 | 102 | * define when the system is under load will cause the output to |
mbed_official | 10:ab9330955226 | 103 | * be unreadable. There is a small tradeoff in performance for this |
mbed_official | 10:ab9330955226 | 104 | * so use it only for debug. */ |
mbed_official | 10:ab9330955226 | 105 | //#define LOCK_RX_THREAD |
mbed_official | 10:ab9330955226 | 106 | |
mbed_official | 10:ab9330955226 | 107 | /** \brief Signal used for ethernet ISR to signal packet_rx() thread. |
mbed_official | 10:ab9330955226 | 108 | */ |
mbed_official | 10:ab9330955226 | 109 | #define RX_SIGNAL 1 |
mbed_official | 10:ab9330955226 | 110 | |
mbed_official | 10:ab9330955226 | 111 | // K64F-specific macros |
mbed_official | 10:ab9330955226 | 112 | #define RX_PBUF_AUTO_INDEX (-1) |
mbed_official | 10:ab9330955226 | 113 | #define TX_DESC_UPDATED_MASK (0x8000) |
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 | 10:ab9330955226 | 859 | /** |
mbed_official | 10:ab9330955226 | 860 | * @} |
mbed_official | 10:ab9330955226 | 861 | */ |
mbed_official | 10:ab9330955226 | 862 | |
mbed_official | 10:ab9330955226 | 863 | /* --------------------------------- End Of File ------------------------------ */ |
mbed_official | 10:ab9330955226 | 864 |