/** \brief Sets up the RX descriptor ring buffers. * * This function sets up the descriptor list used for receive packets. * * \param[in] netif Pointer to driver data structure * \returns true/false */ static NyLPC_TBool k64f_rx_setup(enet_rxbd_config_t *rxbdCfg) { // struct k64f_enetdata *k64f_enet = &(netif->state); enet_dev_if_t *enetIfPtr = (enet_dev_if_t *)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE]; uint32_t rxBufferSizeAligned; int i; // Allocate RX descriptors if(RX_DESC_BUF_BASE!=NULL){ free(RX_DESC_BUF_BASE); RX_DESC_BUF_BASE=NULL; } RX_DESC_BUF_BASE = (void*)calloc(1, enet_hal_get_bd_size() * enetIfPtr->macCfgPtr->rxBdNumber + ENET_BD_ALIGNMENT); if(RX_DESC_BUF_BASE==NULL){ return NyLPC_TBool_FALSE; } //16byteアライメントに修正 _driver.rx_desc_start_addr = (uint8_t *)ENET_ALIGN((NyLPC_TUInt32)RX_DESC_BUF_BASE, ENET_BD_ALIGNMENT); rxBufferSizeAligned = ENET_ALIGN(enetIfPtr->macCfgPtr->rxBufferSize, ENET_RX_BUFFER_ALIGNMENT); enetIfPtr->macContextPtr->rxBufferSizeAligned = rxBufferSizeAligned; rxbdCfg->rxBdPtrAlign = _driver.rx_desc_start_addr; rxbdCfg->rxBdNum = enetIfPtr->macCfgPtr->rxBdNumber; rxbdCfg->rxBufferNum = enetIfPtr->macCfgPtr->rxBdNumber; //初期化 enet_hal_active_rxbd(BOARD_DEBUG_ENET_INSTANCE); for(i=0;i<NUM_OF_RX_RING;i++){ setRxDesc(RX_BUF+(i*SIZE_OF_ETH_PACKET),i); } // k64f_rx_queue(netif, RX_PBUF_AUTO_INDEX); return NyLPC_TBool_TRUE; }
static void updateRxDesc(int idx) { enet_bd_struct_t *start = (enet_bd_struct_t *)_driver.rx_desc_start_addr; /* Setup descriptor and clear statuses */ enet_hal_update_rxbds(start + idx,NULL,false); enet_hal_active_rxbd(BOARD_DEBUG_ENET_INSTANCE); }
/** * i_idx番目のデスクリプタにバッファをセット */ static void setRxDesc(void* rx_buf, int idx) { enet_bd_struct_t *start = (enet_bd_struct_t *)_driver.rx_desc_start_addr; /* Setup descriptor and clear statuses */ enet_hal_init_rxbds(start + idx, (uint8_t*)rx_buf,idx ==(NUM_OF_RX_RING - 1)); enet_hal_active_rxbd(BOARD_DEBUG_ENET_INSTANCE); }
/** \brief Queues a pbuf into the RX descriptor list * * \param[in] k64f_enet Pointer to the drvier data structure * \param[in] p Pointer to pbuf to queue * \param[in] bidx Index to queue into */ static void k64f_rxqueue_pbuf(struct k64f_enetdata *k64f_enet, struct pbuf *p, int bidx) { enet_bd_struct_t *start = (enet_bd_struct_t *)k64f_enet->rx_desc_start_addr; int idx; /* Get next free descriptor index */ if (bidx == RX_PBUF_AUTO_INDEX) idx = k64f_enet->rx_fill_index; else idx = bidx; /* Setup descriptor and clear statuses */ enet_hal_init_rxbds(start + idx, (uint8_t*)p->payload, idx == ENET_RX_RING_LEN - 1); /* Save pbuf pointer for push to network layer later */ k64f_enet->rxb[idx] = p; /* Wrap at end of descriptor list */ idx = (idx + 1) % ENET_RX_RING_LEN; /* Queue descriptor(s) */ k64f_enet->rx_free_descs -= 1; if (bidx == RX_PBUF_AUTO_INDEX) k64f_enet->rx_fill_index = idx; enet_hal_active_rxbd(BOARD_DEBUG_ENET_INSTANCE_ADDR); LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE, ("k64f_rxqueue_pbuf: pbuf packet queued: %p (free desc=%d)\n", p, k64f_enet->rx_free_descs)); }
/** \brief Low level init of the MAC and PHY. * * \param[in] netif Pointer to LWIP netif structure */ NyLPC_TBool low_level_init(const unsigned char* i_ethaddr,int i_addr_len) { enet_dev_if_t * enetIfPtr; uint32_t device = BOARD_DEBUG_ENET_INSTANCE; enet_rxbd_config_t rxbdCfg; enet_txbd_config_t txbdCfg; enet_phy_speed_t phy_speed; enet_phy_duplex_t phy_duplex; //RX/TXメモリはデバイス選択時に確保 k64f_init_eth_hardware(); /* Initialize device*/ enetIfPtr = (enet_dev_if_t *)&enetDevIf[device]; enetIfPtr->deviceNumber = device; enetIfPtr->macCfgPtr = &g_enetMacCfg[device]; enetIfPtr->phyCfgPtr = &g_enetPhyCfg[device]; enetIfPtr->macApiPtr = &g_enetMacApi; enetIfPtr->phyApiPtr = (void *)&g_enetPhyApi; //macアドレスのコピー memcpy(enetIfPtr->macCfgPtr->macAddr,(char*)i_ethaddr,i_addr_len); //enetIfPtr->macContextPtrはgetInterface if(ENET_MAC_CONTEXT_BUF!=NULL){ free(ENET_MAC_CONTEXT_BUF); ENET_MAC_CONTEXT_BUF=NULL; } ENET_MAC_CONTEXT_BUF=calloc(1, sizeof(enet_mac_context_t)); if(ENET_MAC_CONTEXT_BUF==NULL){ return NyLPC_TBool_FALSE;//ERR_BUF; } enetIfPtr->macContextPtr = (enet_mac_context_t *)ENET_MAC_CONTEXT_BUF; /* Initialize enet buffers*/ if(!k64f_rx_setup(&rxbdCfg)) { return NyLPC_TBool_FALSE;//ERR_BUF; } /* Initialize enet buffers*/ if(!k64f_tx_setup(&txbdCfg)) { return NyLPC_TBool_FALSE;//ERR_BUF; } /* Initialize enet module*/ if (enet_mac_init(enetIfPtr, &rxbdCfg, &txbdCfg) == kStatus_ENET_Success) { /* Initialize PHY*/ if (enetIfPtr->macCfgPtr->isPhyAutoDiscover) { if (((enet_phy_api_t *)(enetIfPtr->phyApiPtr))->phy_auto_discover(enetIfPtr) != kStatus_PHY_Success) return NyLPC_TBool_FALSE;//ERR_IF; } if (((enet_phy_api_t *)(enetIfPtr->phyApiPtr))->phy_init(enetIfPtr) != kStatus_PHY_Success) return NyLPC_TBool_FALSE;//ERR_IF; enetIfPtr->isInitialized = true; }else{ // TODOETH: cleanup memory return NyLPC_TBool_FALSE;//ERR_IF; } /* Get link information from PHY */ phy_get_link_speed(enetIfPtr, &phy_speed); phy_get_link_duplex(enetIfPtr, &phy_duplex); BW_ENET_RCR_RMII_10T(enetIfPtr->deviceNumber, phy_speed == kEnetSpeed10M ? kEnetCfgSpeed10M : kEnetCfgSpeed100M); BW_ENET_TCR_FDEN(enetIfPtr->deviceNumber, phy_duplex == kEnetFullDuplex ? kEnetCfgFullDuplex : kEnetCfgHalfDuplex); /* Enable Ethernet module*/ enet_hal_config_ethernet(device, true, true); /* Active Receive buffer descriptor must be done after module enable*/ enet_hal_active_rxbd(enetIfPtr->deviceNumber); enet_hal_active_txbd(enetIfPtr->deviceNumber); return NyLPC_TBool_TRUE;//ERR_OK; }
/** \brief Low level init of the MAC and PHY. * * \param[in] netif Pointer to LWIP netif structure */ static err_t low_level_init(struct netif *netif) { enet_dev_if_t * enetIfPtr; uint32_t device = BOARD_DEBUG_ENET_INSTANCE_ADDR; enet_rxbd_config_t rxbdCfg; enet_txbd_config_t txbdCfg; enet_phy_speed_t phy_speed; enet_phy_duplex_t phy_duplex; k64f_init_eth_hardware(); /* Initialize device*/ enetIfPtr = (enet_dev_if_t *)&enetDevIf[BOARD_DEBUG_ENET_INSTANCE]; enetIfPtr->deviceNumber = device; enetIfPtr->macCfgPtr = &g_enetMacCfg[BOARD_DEBUG_ENET_INSTANCE]; enetIfPtr->phyCfgPtr = &g_enetPhyCfg[BOARD_DEBUG_ENET_INSTANCE]; enetIfPtr->macApiPtr = &g_enetMacApi; enetIfPtr->phyApiPtr = (void *)&g_enetPhyApi; memcpy(enetIfPtr->macCfgPtr->macAddr, (char*)netif->hwaddr, kEnetMacAddrLen); /* Allocate buffer for ENET mac context*/ enetIfPtr->macContextPtr = (enet_mac_context_t *)calloc(1, sizeof(enet_mac_context_t)); if (!enetIfPtr->macContextPtr) { return ERR_BUF; } /* Initialize enet buffers*/ if(k64f_rx_setup(netif, &rxbdCfg) != ERR_OK) { return ERR_BUF; } /* Initialize enet buffers*/ if(k64f_tx_setup(netif, &txbdCfg) != ERR_OK) { return ERR_BUF; } /* Initialize enet module*/ if (enet_mac_init(enetIfPtr, &rxbdCfg, &txbdCfg) == kStatus_ENET_Success) { /* Initialize PHY*/ if (enetIfPtr->macCfgPtr->isPhyAutoDiscover) { if (((enet_phy_api_t *)(enetIfPtr->phyApiPtr))->phy_auto_discover(enetIfPtr) != kStatus_PHY_Success) return ERR_IF; } if (((enet_phy_api_t *)(enetIfPtr->phyApiPtr))->phy_init(enetIfPtr) != kStatus_PHY_Success) return ERR_IF; enetIfPtr->isInitialized = true; } else { // TODOETH: cleanup memory return ERR_IF; } /* Get link information from PHY */ phy_get_link_speed(enetIfPtr, &phy_speed); phy_get_link_duplex(enetIfPtr, &phy_duplex); BW_ENET_RCR_RMII_10T(enetIfPtr->deviceNumber, phy_speed == kEnetSpeed10M ? kEnetCfgSpeed10M : kEnetCfgSpeed100M); BW_ENET_TCR_FDEN(enetIfPtr->deviceNumber, phy_duplex == kEnetFullDuplex ? kEnetCfgFullDuplex : kEnetCfgHalfDuplex); /* Enable Ethernet module*/ enet_hal_config_ethernet(BOARD_DEBUG_ENET_INSTANCE_ADDR, true, true); /* Active Receive buffer descriptor must be done after module enable*/ enet_hal_active_rxbd(enetIfPtr->deviceNumber); return ERR_OK; }