Example #1
0
static void setTxDesc(int idx)
{
    enet_bd_struct_t *start = (enet_bd_struct_t *)_driver.tx_desc_start_addr;
    /* Setup descriptor and clear statuses */
    enet_hal_init_txbds(start + idx,idx ==(NUM_OF_RX_RING - 1));
    enet_hal_active_txbd(BOARD_DEBUG_ENET_INSTANCE);
}
Example #2
0
static void updateTxDesc(int idx, uint8_t *buffer, uint16_t length, bool isLast)
{
	volatile enet_bd_struct_t * bdPtr = (enet_bd_struct_t *)(_driver.tx_desc_start_addr + idx * enet_hal_get_bd_size());
	
	bdPtr->length = HTONS(length); /* Set data length*/
	bdPtr->buffer = (uint8_t *)HTONL((uint32_t)buffer); /* Set data buffer*/
	bdPtr->control |= kEnetTxBdLast;//最終フラグメントのフラグね
	bdPtr->controlExtend1 |= kEnetTxBdTxInterrupt;
	bdPtr->controlExtend2 &= ~TX_DESC_UPDATED_MASK; // descriptor not updated by DMA
	bdPtr->control |= kEnetTxBdTransmitCrc | kEnetTxBdReady;
	if(isLast){
		//これはデスクリプタの終了位置のフラグ
		bdPtr->control |=kEnetTxBdWrap;
	}
	enet_hal_active_txbd(BOARD_DEBUG_ENET_INSTANCE);	
}
Example #3
0
/** \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;
}
Example #4
0
/** \brief  Low level output of a packet. Never call this from an
 *          interrupt context, as it may block until TX descriptors
 *          become available.
 *
 *  \param[in] netif the lwip network interface structure for this netif
 *  \param[in] p the MAC packet to send (e.g. IP packet including MAC addresses and type)
 *  \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent
 */
static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p)
{
  struct k64f_enetdata *k64f_enet = netif->state;
  struct pbuf *q;
  u32_t idx;
  s32_t dn;
  uint8_t *psend = NULL, *dst;

  /* Get free TX buffer index */
  idx = k64f_enet->tx_produce_index;
  
  /* Check the pbuf chain for payloads that are not 8-byte aligned.
     If found, a new properly aligned buffer needs to be allocated
     and the data copied there */
  for (q = p; q != NULL; q = q->next)
    if (((u32_t)q->payload & (TX_BUF_ALIGNMENT - 1)) != 0)
      break;
  if (q != NULL) {
    // Allocate properly aligned buffer
    psend = (uint8_t*)malloc(p->tot_len);
    if (NULL == psend)
      return ERR_MEM;   
    LWIP_ASSERT("k64f_low_level_output: buffer not properly aligned", ((u32_t)psend & (TX_BUF_ALIGNMENT - 1)) == 0);
    for (q = p, dst = psend; q != NULL; q = q->next) {
      MEMCPY(dst, q->payload, q->len);
      dst += q->len;
    }
    k64f_enet->txb_aligned[idx] = psend;
    dn = 1;
  } else {
    k64f_enet->txb_aligned[idx] = NULL;
    dn = (s32_t) pbuf_clen(p);
    pbuf_ref(p);
  }

  /* Wait until enough descriptors are available for the transfer. */
  /* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */
  while (dn > k64f_tx_ready(netif))
    osSemaphoreWait(k64f_enet->xTXDCountSem.id, osWaitForever);

  /* Get exclusive access */
  sys_mutex_lock(&k64f_enet->TXLockMutex);

  /* Setup transfers */
  q = p;
  while (dn > 0) {
    dn--;
    if (psend != NULL) {
      k64f_update_txbds(k64f_enet, idx, psend, p->tot_len, 1);
      k64f_enet->txb[idx] = NULL;
      
      LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
      ("k64f_low_level_output: aligned packet(%p) sent"
      " size = %d (index=%d)\n", psend, p->tot_len, idx));      
    } else {
      LWIP_ASSERT("k64f_low_level_output: buffer not properly aligned", ((u32_t)q->payload & 0x07) == 0);

      /* Only save pointer to free on last descriptor */
      if (dn == 0) {
        /* Save size of packet and signal it's ready */
        k64f_update_txbds(k64f_enet, idx, q->payload, q->len, 1);
        k64f_enet->txb[idx] = p;
      }
      else {
        /* Save size of packet, descriptor is not last */
        k64f_update_txbds(k64f_enet, idx, q->payload, q->len, 0);
        k64f_enet->txb[idx] = NULL;
      }
      
      LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
      ("k64f_low_level_output: pbuf packet(%p) sent, chain#=%d,"
      " size = %d (index=%d)\n", q->payload, dn, q->len, idx));
    }

    q = q->next;

    idx = (idx + 1) % ENET_TX_RING_LEN;
  }

  k64f_enet->tx_produce_index = idx;
  enet_hal_active_txbd(BOARD_DEBUG_ENET_INSTANCE_ADDR);
  LINK_STATS_INC(link.xmit);

  /* Restore access */
  sys_mutex_unlock(&k64f_enet->TXLockMutex);

  return ERR_OK;
}