Пример #1
0
/**
 * _eth_format_packet() places the next packet to be transmitted into
 * the above link-layer output packet.
 * \return address of higher-level protocol (IP/RARP/RARP) header.
 */
void *_eth_formatpacket (const void *mac_dest, WORD eth_type)
{
  SIO_TRACE (("_eth_formatpacket, type %04X", eth_type));

  nw_pkt = (*mac_tx_format) (TX_BUF(), mac_dest, eth_type);
  return (nw_pkt);
}
BOOL_32 EMAC_SendPacket(void *pPacket, UNS_32 size)
{
	UNS_32 	Index;
	UNS_32	IndexNext = LPC_EMAC->TxProduceIndex + 1;
	
  if(size == 0)
  {
    return(TRUE);
  }
  if(IndexNext > LPC_EMAC->TxDescriptorNumber)
  {
    IndexNext = 0;
  }
 
  if(IndexNext == LPC_EMAC->TxConsumeIndex)
  {
    return(FALSE);
  }
  Index = LPC_EMAC->TxProduceIndex;
  if (size > ETH_FRAG_SIZE)
  	size = ETH_FRAG_SIZE;

  memcpy((unsigned int *)TX_BUF(Index),pPacket,size);  
  TX_DESC_CTRL(Index) &= ~0x7ff;
  TX_DESC_CTRL(Index) |= (size - 1) & 0x7ff; 

  LPC_EMAC->TxProduceIndex = IndexNext;

  return(TRUE);
}
Пример #3
0
/* transmit packet. */
rt_err_t lpc17xx_emac_tx( rt_device_t dev, struct pbuf* p)
{
	rt_uint32_t Index, IndexNext;
	struct pbuf *q;
	rt_uint8_t *ptr;

	/* calculate next index */
	IndexNext = LPC_EMAC->TxProduceIndex + 1;
	if(IndexNext > LPC_EMAC->TxDescriptorNumber) IndexNext = 0;

	/* check whether block is full */
	while (IndexNext == LPC_EMAC->TxConsumeIndex)
	{
		rt_err_t result;
		rt_uint32_t recved;
		
		/* there is no block yet, wait a flag */
		result = rt_event_recv(&tx_event, 0x01, 
			RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);

		RT_ASSERT(result == RT_EOK);
	}

	/* lock EMAC device */
	rt_sem_take(&sem_lock, RT_WAITING_FOREVER);

	/* get produce index */
	Index = LPC_EMAC->TxProduceIndex;

	/* calculate next index */
	IndexNext = LPC_EMAC->TxProduceIndex + 1;
	if(IndexNext > LPC_EMAC->TxDescriptorNumber)
		IndexNext = 0;

	/* copy data to tx buffer */
	q = p;
	ptr = (rt_uint8_t*)TX_BUF(Index);
	while (q)
	{
		memcpy(ptr, q->payload, q->len);
		ptr += q->len;
		q = q->next;
	}

	TX_DESC_CTRL(Index) &= ~0x7ff;
	TX_DESC_CTRL(Index) |= (p->tot_len - 1) & 0x7ff;

	/* change index to the next */
	LPC_EMAC->TxProduceIndex = IndexNext;

	/* unlock EMAC device */
	rt_sem_release(&sem_lock);

	return RT_EOK;
}
Пример #4
0
static err_t
low_level_output(struct netif *netif, struct pbuf *p)
{
  struct pbuf *q;
  uint32_t Index, IndexNext;
  uint8_t *ptr;

  /* calculate next index */
  IndexNext = LPC_EMAC->TxProduceIndex + 1;
  if(IndexNext > LPC_EMAC->TxDescriptorNumber)
    IndexNext = 0;
#if 0
	/* check whether block is full */
	while (IndexNext == LPC_EMAC->TxConsumeIndex)
	{
		err_t result;
		uint32_t recved;

		/* there is no block yet, wait a flag */
		result = rt_event_recv(&tx_event, 0x01,
			RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);
	}
#endif
  
	Index = LPC_EMAC->TxProduceIndex;

	/* calculate next index */
	IndexNext = LPC_EMAC->TxProduceIndex + 1;
	if(IndexNext > LPC_EMAC->TxDescriptorNumber)
		IndexNext = 0;

#if ETH_PAD_SIZE
  pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif

	/* copy data to tx buffer */
	ptr = (uint8_t*)TX_BUF(Index);
  for(q = p; q != NULL; q = q->next) {
		MEMCPY(ptr, q->payload, q->len);
		ptr += q->len;
  }

	TX_DESC_CTRL(Index) = (p->tot_len - 1) & 0x7ff | EMAC_TCTRL_INT | EMAC_TCTRL_LAST;

	/* change index to the next */
	LPC_EMAC->TxProduceIndex = IndexNext;

#if ETH_PAD_SIZE
  pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
  
  LINK_STATS_INC(link.xmit);

  return ERR_OK;
}
Пример #5
0
// Keil: function added to initialize Tx Descriptors
void tx_descr_init (void) {
  unsigned int i;

  for (i = 0; i < NUM_TX_FRAG; i++) {
    TX_DESC_PACKET(i) = TX_BUF(i);
    TX_DESC_CTRL(i)   = 0;
    TX_STAT_INFO(i)   = 0;
  }

  /* Set EMAC Transmit Descriptor Registers. */
  TxDescriptor    = TX_DESC_BASE;
  TxStatus        = TX_STAT_BASE;
  TxDescriptorNumber = NUM_TX_FRAG-1;

  /* Tx Descriptors Point to 0 */
  TxProduceIndex  = 0;
}
		// Keil: function added to initialize Tx Descriptors
		void tx_descr_init (void) {
		  unsigned int i;
		
		  for (i = 0; i < NUM_TX_FRAG; i++) {
		    TX_DESC_PACKET(i) = TX_BUF(i);
		    TX_DESC_CTRL(i)   = 0;
		    TX_STAT_INFO(i)   = 0;
		  }
		
		  /* Set EMAC Transmit Descriptor Registers. */
		  MAC_TXDESCRIPTOR    = TX_DESC_BASE;
		  MAC_TXSTATUS        = TX_STAT_BASE;
		  MAC_TXDESCRIPTORNUM = NUM_TX_FRAG-1;//Minus 1 Encoding
		
		  /* Tx Descriptors Point to 0 */
		  MAC_TXPRODUCEINDEX  = 0;
		}
static void tx_descr_init (void) {
  UNS_32 i;

  for (i = 0; i < NUM_TX_FRAG; i++) {
    TX_DESC_PACKET(i) = TX_BUF(i);
    TX_DESC_CTRL(i)   = (1<<31) | (1<<30) | (1<<29) | (1<<28) | (1<<26) | (ETH_FRAG_SIZE-1);
    TX_STAT_INFO(i)   = 0;
  }

  /* Set EMAC Transmit Descriptor Registers. */
  LPC_EMAC->TxDescriptor    = TX_DESC_BASE;
  LPC_EMAC->TxStatus        = TX_STAT_BASE;
  LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1;

  /* Tx Descriptors Point to 0 */
  LPC_EMAC->TxProduceIndex  = 0;
}
Пример #8
0
// Keil: function added to initialize Tx Descriptors
void tx_descr_init (void)
{
  unsigned int i;

  for (i = 0; i < NUM_TX_DESC; i++) {						// Take it out!!!!
	 TX_DESC_STAT(i) = 0;
	 TX_DESC_CTRL(i) = 0;
	 TX_BUFADDR(i) = 0;
  }

  for (i = 0; i < NUM_TX_DESC; i++) {
    TX_DESC_STAT(i) = TX_LAST_SEGM | TX_FIRST_SEGM;
	TX_DESC_CTRL(i) = 0;
	TX_BUFADDR(i) = TX_BUF(i); 
	if (i == (NUM_TX_DESC-1)) 		   // Last Descriptor?
	  TX_DESC_STAT(i) |= TX_END_RING;
  }

  /* Set Starting address of RX Descriptor list */
  LPC_ETHERNET->DMA_TRANS_DES_ADDR = TX_DESC_BASE;
}
Пример #9
0
void Init_EthMAC(void)
{
  unsigned int value, phyid1, phyid2;
  volatile unsigned int loop;
  unsigned phy_in_use = 0;
  unsigned phy_linkstatus_reg;
  unsigned phy_linkstatus_mask;  


  /* Power Up the EMAC controller. */
  LPC_SC->PCONP |= (0x1<<30);

#if RMII
  LPC_IOCON->P1_0  &= ~0x07;	/*  ENET I/O config */
  LPC_IOCON->P1_0  |= 0x01;		/* ENET_TXD0 */
  LPC_IOCON->P1_1  &= ~0x07;	
  LPC_IOCON->P1_1  |= 0x01;		/* ENET_TXD1 */
  LPC_IOCON->P1_4  &= ~0x07;
  LPC_IOCON->P1_4  |= 0x01;		/* ENET_TXEN */
  LPC_IOCON->P1_8  &= ~0x07;	
  LPC_IOCON->P1_8  |= 0x01;		/* ENET_CRS */
  LPC_IOCON->P1_9  &= ~0x07;	
  LPC_IOCON->P1_9  |= 0x01;		/* ENET_RXD0 */
  LPC_IOCON->P1_10 &= ~0x07;	
  LPC_IOCON->P1_10 |= 0x01;		/* ENET_RXD1 */
  LPC_IOCON->P1_14 &= ~0x07;	
  LPC_IOCON->P1_14 |= 0x01;		/* ENET_RX_ER */
  LPC_IOCON->P1_15 &= ~0x07;	
  LPC_IOCON->P1_15 |= 0x01;		/* ENET_REF_CLK */
#else
  LPC_IOCON->P1_0  &= ~0x07;	/*  ENET I/O config */
  LPC_IOCON->P1_0  |= 0x01;		/* ENET_TXD0 */
  LPC_IOCON->P1_1  &= ~0x07;	
  LPC_IOCON->P1_1  |= 0x01;		/* ENET_TXD1 */
  LPC_IOCON->P1_2  &= ~0x07;
  LPC_IOCON->P1_2  |= 0x01;		/* ENET_TXD2 */
  LPC_IOCON->P1_3  &= ~0x07;	
  LPC_IOCON->P1_3  |= 0x01;		/* ENET_TXD3 */
  LPC_IOCON->P1_4  &= ~0x07;
  LPC_IOCON->P1_4  |= 0x01;		/* ENET_TXEN */
  LPC_IOCON->P1_5  &= ~0x07;	
  LPC_IOCON->P1_5  |= 0x01;		/* ENET_TXER */
  LPC_IOCON->P1_6  &= ~0x07;	
  LPC_IOCON->P1_6  |= 0x01;		/* ENET_TX_CLK */
  LPC_IOCON->P1_7  &= ~0x07;	
  LPC_IOCON->P1_7  |= 0x01;		/* ENET_COL */
  LPC_IOCON->P1_8  &= ~0x07;	
  LPC_IOCON->P1_8  |= 0x01;		/* ENET_CRS */
  LPC_IOCON->P1_9  &= ~0x07;	
  LPC_IOCON->P1_9  |= 0x01;		/* ENET_RXD0 */
  LPC_IOCON->P1_10 &= ~0x07;	
  LPC_IOCON->P1_10 |= 0x01;		/* ENET_RXD1 */
  LPC_IOCON->P1_11 &= ~0x07;	
  LPC_IOCON->P1_11 |= 0x01;		/* ENET_RXD2 */
  LPC_IOCON->P1_12 &= ~0x07;	
  LPC_IOCON->P1_12 |= 0x01;		/* ENET_RXD3 */
  LPC_IOCON->P1_13 &= ~0x07;	
  LPC_IOCON->P1_13 |= 0x01;		/* ENET_RX_DV */
  LPC_IOCON->P1_14 &= ~0x07;	
  LPC_IOCON->P1_14 |= 0x01;		/* ENET_RX_ER */
  LPC_IOCON->P1_15 &= ~0x07;	
  LPC_IOCON->P1_15 |= 0x01;		/* ENET_RX_CLK/ENET_REF_CLK */
#endif

#if 1
  LPC_IOCON->P1_16 &= ~0x07;	/* ENET/PHY I/O config */
  LPC_IOCON->P1_16 |= 0x01;		/* ENET_MDC */
  LPC_IOCON->P1_17 &= ~0x07;	
  LPC_IOCON->P1_17 |= 0x01;		/* ENET_MDIO */
//  LPC_IOCON->LOC_ENET_MDIO = 0x01;
#endif
#if 0
  LPC_IOCON->P2_8 &= ~0x07;	/* ENET/PHY I/O config */
  LPC_IOCON->P2_8 |= 0x04;		/* ENET_MDC */
  LPC_IOCON->P2_9 &= ~0x07;	
  LPC_IOCON->P2_9 |= 0x04;		/* ENET_MDIO */
//  LPC_IOCON->LOC_ENET_MDIO = 0x00;
#endif

  // Set up MAC Configuration Register 1
  LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | 
         MAC1_RES_MCS_RX |MAC1_SIM_RES | MAC1_SOFT_RES;

  // Set up MAC Command Register
  LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM;
  
  // Short delay
  for (loop = 100; loop; loop--);

  // Set up MAC Configuration Register 1 to pass all receive frames
  LPC_EMAC->MAC1 = MAC1_PASS_ALL;
  // Set up MAC Configuration Register 2 to append CRC and pad out frames
  LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;

  // Set Ethernet Maximum Frame Register
  LPC_EMAC->MAXF = ETH_MAX_FLEN;
  // Set Collision Window / Retry Register
  LPC_EMAC->CLRT = CLRT_DEF;
  // Set Non Back-to-Back Inter-Packet-Gap Register
  LPC_EMAC->IPGR = IPGR_DEF;

  /* Enable Reduced MII interface. */
  LPC_EMAC->MCFG = MCFG_CLK_DIV64 | MCFG_RES_MII;
  for (loop = 100; loop; loop--);
  LPC_EMAC->MCFG = MCFG_CLK_DIV64;

  // Set MAC Command Register to enable Reduced MII interface
  // and prevent runt frames being filtered out
  LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM | CR_PASS_RX_FILT;

  // Put PHY into reset mode
  WriteToPHY (PHY_REG_BMCR, 0x8000);

  // Loop until hardware reset completes
  for (loop = 0; loop < 0x100000; loop++) {
    value = ReadFromPHY (PHY_REG_BMCR);
    if (!(value & 0x8000)) {
      // Reset has completed
      break;
    }
  }

  // Just check this actually is a DP83848C PHY
  phyid1 = ReadFromPHY (PHY_REG_IDR1);
  phyid2 = ReadFromPHY (PHY_REG_IDR2);

  if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == DP83848C_ID) {
    phy_in_use =  DP83848C_ID;
  }
  else if (((phyid1 << 16) | (phyid2 & 0xFFF0)) == LAN8720_ID) {
    phy_in_use = LAN8720_ID;
  }

  if (phy_in_use != 0) {	  
    // Safe to configure the PHY device

    // Set PHY to autonegotiation link speed
    WriteToPHY (PHY_REG_BMCR, PHY_AUTO_NEG);
    // loop until autonegotiation completes
    for (loop = 0; loop < 0x100000; loop++) {
      value = ReadFromPHY (PHY_REG_BMSR);
      if (value & 0x0020) {
        // Autonegotiation has completed
        break;
      }
    }
  }

  // Now check the link status
  for (loop = 0; loop < 0x10000; loop++) {
  	value = ReadFromPHY (PHY_REG_BMSR);
      if (value & 0x04) {						/* bit 2 of BSR = 1? Link Up  */
      // The link is on
      break;
    }
  }


  // Configure the EMAC with the established parameters
  switch (phy_in_use) {
  	  case DP83848C_ID:

  		  value = ReadFromPHY (PHY_REG_STS);	/* PHY Extended Status Register  */
  		  // Now configure for full/half duplex mode
  		  if (value & 0x0004) {
  		    // We are in full duplex is enabled mode
  			  LPC_EMAC->MAC2    |= MAC2_FULL_DUP;
  			  LPC_EMAC->Command |= CR_FULL_DUP;
  			  LPC_EMAC->IPGT     = IPGT_FULL_DUP;
  		  }
  		  else {
  		    // Otherwise we are in half duplex mode
  			  LPC_EMAC->IPGT = IPGT_HALF_DUP;
  		  }

  		  // Now configure 100MBit or 10MBit mode
  		  if (value & 0x0002) {
  		    // 10MBit mode
  			  LPC_EMAC->SUPP = 0;
  		  }
  		  else {
  		    // 100MBit mode
  			  LPC_EMAC->SUPP = SUPP_SPEED;
  		  }
  		  break;

  	  case LAN8720_ID:

  		  value = ReadFromPHY (PHY_REG_SCSR);	/* PHY Extended Status Register  */
  		  // Now configure for full/half duplex mode
  		  if (value & (1<<4)) {		/* bit 4: 1 = Full Duplex, 0 = Half Duplex  */
    		  // We are in full duplex is enabled mode
  			  LPC_EMAC->MAC2    |= MAC2_FULL_DUP;
  			  LPC_EMAC->Command |= CR_FULL_DUP;
  			  LPC_EMAC->IPGT     = IPGT_FULL_DUP;
  		  }else {
   		      // Otherwise we are in half duplex mode
    		  LPC_EMAC->IPGT = IPGT_HALF_DUP;
  		  }

  		  // Now configure 100MBit or 10MBit mode
  		  if (value & (1<<3)) {	/* bit 3: 1 = 100Mbps, 0 = 10Mbps  */
  			  // 100MBit mode
    		  LPC_EMAC->SUPP = SUPP_SPEED;
  		  }else {
    		  // 10MBit mode
    		  LPC_EMAC->SUPP = 0;
  		  }


  		  break;

  }

  // Now set the Ethernet MAC Address registers
  // NOTE - MAC address must be unique on the network!
  LPC_EMAC->SA0 = (MYMAC_1 << 8) | MYMAC_2; // Station address 0 Reg
  LPC_EMAC->SA1 = (MYMAC_3 << 8) | MYMAC_4; // Station address 1 Reg
  LPC_EMAC->SA2 = (MYMAC_5 << 8) | MYMAC_6; // Station address 2 Reg

  // Now initialise the Rx descriptors    
  for (loop = 0; loop < NUM_RX_FRAG; loop++) {
    RX_DESC_PACKET(loop)  = RX_BUF(loop);
    RX_DESC_CTRL(loop)    = RCTRL_INT | (ETH_FRAG_SIZE-1);
    RX_STAT_INFO(loop)    = 0;
    RX_STAT_HASHCRC(loop) = 0;
  }

  // Set up the Receive Descriptor Base address register
  LPC_EMAC->RxDescriptor    = RX_DESC_BASE;
  // Set up the Receive Status Base address register
  LPC_EMAC->RxStatus        = RX_STAT_BASE;
  // Setup the Receive Number of Descriptor register
  LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG-1;
  //  Set Receive Consume Index register to 0
  LPC_EMAC->RxConsumeIndex  = 0;

  // Now initialise the Tx descriptors 
  for (loop = 0; loop < NUM_TX_FRAG; loop++) {
    TX_DESC_PACKET(loop) = TX_BUF(loop);
    TX_DESC_CTRL(loop)   = 0;
    TX_STAT_INFO(loop)   = 0;
  }

  // Set up the Transmit Descriptor Base address register
  LPC_EMAC->TxDescriptor    = TX_DESC_BASE;
  // Set up the Transmit Status Base address register
  LPC_EMAC->TxStatus        = TX_STAT_BASE;
  // Setup the Transmit Number of Descriptor register
  LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG-1;
  //  Set Transmit Consume Index register to 0
  LPC_EMAC->TxProduceIndex  = 0;
 
  // Receive Broadcast and Perfect Match Packets



  LPC_EMAC->RxFilterCtrl = RFC_BCAST_EN | RFC_PERFECT_EN;					 
 
  // Enable interrupts MAC Module Control Interrupt Enable Register
  LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE;

  // Reset all ethernet interrupts in MAC module
  LPC_EMAC->IntClear  = 0xFFFF;

  // Finally enable receive and transmit mode in ethernet core
  LPC_EMAC->Command  |= (CR_RX_EN | CR_TX_EN);
  LPC_EMAC->MAC1     |= MAC1_REC_EN;
}
Пример #10
0
BOOL LPC24XX_EMAC_lwip_init ( struct netif *pNetIf )
{
    UINT32 i;
    LPC24XX_EMAC & ENET = *(LPC24XX_EMAC *)LPC24XX_EMAC::c_EMAC_Base;

    /* Power Up the EMAC controller. */
    LPC24XX::SYSCON().PCONP |= LPC24XX_SYSCON::ENABLE_ENET;
    
    /* Connect EMAC pins */
    LPC24XX_EMAC_lwip_setpins( ENET_PHY_lwip_get_MII_mode() );
    
    /* Reset EMAC */
    ENET.MAC_MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX |
                    MAC1_SIM_RES | MAC1_SOFT_RES;
    ENET.MAC_COMMAND = CR_REG_RES | CR_TX_RES | CR_RX_RES;
    HAL_Time_Sleep_MicroSeconds(1);
    
      /* Initialize MAC control registers. */
    ENET.MAC_MAC1 = 0;
    ENET.MAC_MAC2 = MAC2_CRC_EN | MAC2_PAD_EN;
    ENET.MAC_MAXF = ETH_MAX_FLEN;
    ENET.MAC_CLRT = CLRT_DEF;
    ENET.MAC_IPGR = IPGR_DEF;

    if ( !ENET_PHY_lwip_get_MII_mode() )
    {
        /* Enable RMII mode in MAC command register */
        ENET.MAC_COMMAND = ENET.MAC_COMMAND | CR_RMII;
    }

    /* Reset MII Management hardware */
    ENET.MAC_MCFG = MCFG_RES_MII;
    HAL_Time_Sleep_MicroSeconds(1);
    
    /* Set MDC Clock divider */
    ENET.MAC_MCFG = ENET_PHY_lwip_get_MDC_Clk_Div() & MCFG_CLK_SEL;

    /* Initialiaze external ethernet Phy */
    if ( !ENET_PHY_lwip_init() )
    {
        return FALSE;
    }

    /* Set the Ethernet MAC Address registers */
    ENET.MAC_SA2 = (pNetIf->hwaddr[1] << 8) | pNetIf->hwaddr[0];
    ENET.MAC_SA1 = (pNetIf->hwaddr[3] << 8) | pNetIf->hwaddr[2];
    ENET.MAC_SA0 = (pNetIf->hwaddr[5] << 8) | pNetIf->hwaddr[4];
    
    /* Setup the Rx DMA Descriptors */
    for (i = 0; i < NUM_RX_FRAG; i++)
    {
        RX_DESC_PACKET(i)  = RX_BUF(i);
        RX_DESC_CTRL(i)    = RCTRL_INT | (ETH_FRAG_SIZE-1);
        RX_STAT_INFO(i)    = 0;
        RX_STAT_HASHCRC(i) = 0;
    }

    /* Set the EMAC Rx Descriptor Registers. */
    ENET.MAC_RXDESCRIPTOR    = RX_DESC_BASE;
    ENET.MAC_RXSTATUS        = RX_STAT_BASE;
    ENET.MAC_RXDESCRIPTORNUM = NUM_RX_FRAG-1;
    ENET.MAC_RXCONSUMEINDEX  = 0;

    /* Setup the Tx DMA Descriptors */
    for (i = 0; i < NUM_TX_FRAG; i++) 
    {
        TX_DESC_PACKET(i) = TX_BUF(i);
        TX_DESC_CTRL(i)   = 0;
        TX_STAT_INFO(i)   = 0;
    }

    /* Set the EMAC Tx Descriptor Registers. */
    ENET.MAC_TXDESCRIPTOR    = TX_DESC_BASE;
    ENET.MAC_TXSTATUS        = TX_STAT_BASE;
    ENET.MAC_TXDESCRIPTORNUM = NUM_TX_FRAG-1;
    ENET.MAC_TXPRODUCEINDEX  = 0;
    
    /* Receive Broadcast and Perfect Match Packets */
    ENET.MAC_RXFILTERCTRL = RFC_PERFECT_EN | RFC_BCAST_EN;
    
    /* Enable EMAC interrupts. */
    ENET.MAC_INTENABLE = INT_RX_DONE | INT_TX_DONE | INT_TX_UNDERRUN | INT_RX_OVERRUN;

    /* Reset all interrupts */
    ENET.MAC_INTCLEAR  = 0xFFFF;

    /* Enable receive and transmit */
    ENET.MAC_COMMAND  |= (CR_RX_EN | CR_TX_EN);
    ENET.MAC_MAC1     |= MAC1_REC_EN;
    
    return TRUE;
}
Пример #11
0
/**
 * Initialize the network driver interface.
 * \return 0 okay.
 * \return error-code otherwise.
 */
int _eth_init (void)
{
  int rc;

  SIO_TRACE (("_eth_init"));

  if (_eth_is_init)
     return (0);

  rc = pkt_eth_init (&_eth_addr);
  if (rc)
     return (rc);  /* error message already printed */

  /* Save our MAC-address incase we change it. Change back at exit.
   */
  memcpy (_eth_real_addr, _eth_addr, sizeof(_eth_real_addr));

  switch (_pktdevclass)
  {
    case PDCLASS_ETHER:
         mac_tx_format = eth_mac_format;
         mac_transmit  = eth_mac_xmit;
         break;
    case PDCLASS_TOKEN:
    case PDCLASS_TOKEN_RIF:
         mac_tx_format = tok_mac_format;
         mac_transmit  = tok_mac_xmit;
         break;
    case PDCLASS_FDDI:
         mac_tx_format = fddi_mac_format;
         mac_transmit  = fddi_mac_xmit;
         break;
    case PDCLASS_ARCNET:
         mac_tx_format = arcnet_mac_format;
         mac_transmit  = arcnet_mac_xmit;
         break;
    case PDCLASS_SLIP:
    case PDCLASS_PPP:
    case PDCLASS_AX25:  /* !! for now */
         mac_tx_format = null_mac_format;
         mac_transmit  = null_mac_xmit;
         break;
    default:
         outsnl (_LANG("No supported driver class found"));
         return (WERR_NO_DRIVER);
  }

  memset (TX_BUF(), 0, sizeof(union link_Packet));
  memset (&_eth_brdcast, 0xFF, sizeof(_eth_brdcast));
  _eth_loop_addr[0] = 0xCF;
  pkt_buf_wipe();

  if (!_eth_get_hwtype(NULL, &_eth_mac_len))
     _eth_mac_len = sizeof(eth_address);

  if (!strcmp(_pktdrvrname,"NDIS3PKT"))
     _eth_ndis3pkt = TRUE;

  else if (!strcmp(_pktdrvrname,"SwsVpkt"))
     _eth_SwsVpkt = TRUE;

  _eth_is_init = TRUE;
  RUNDOWN_ADD (_eth_release, 10);

  return (0);  /* everything okay */
}
Пример #12
0
/**
 * _eth_send() does the actual transmission once we are complete with
 * filling the buffer.  Do any last minute patches here, like fix the
 * size. Send to "loopback" device if it's IP and destination matches
 * loopback network (127.x.x.x.).
 *
 * Return length of network-layer packet (not length of link-layer
 * packet).
 */
int _eth_send (WORD len, const void *sock, const char *file, unsigned line)
{
#if defined(USE_DEBUG) || defined(USE_LOOPBACK)
  unsigned errline = 0;
#endif
  BOOL send_loopback_to_driver = FALSE;

  SIO_TRACE (("_eth_send, len %d", len));

  if (!_eth_is_init)  /* GvB 2002-09, Lets us run without a working eth */
  {
    SOCK_ERRNO (ENETDOWN);
    return (0);
  }

#if defined(WIN32)
  /*
   * Just a test for now; send it to the driver and look what happens....
   * They go on the wire and not to the Winsock loopback provider.
   * No surprise here yet.
   */
  if (loopback_mode & LBACK_MODE_WINSOCK)
     send_loopback_to_driver = TRUE;
#endif

  if (proto == IP4_TYPE)
  {
    /* Sending to loopback device if IPv4.
     */
    const in_Header *ip = (const in_Header*) nw_pkt;

    if (!send_loopback_to_driver &&
        _ip4_is_loopback_addr(intel(ip->destination)))
    {
#if defined(USE_LOOPBACK)
      len = send_loopback (*TX_BUF(), FALSE, &errline);
#else
      STAT (ip4stats.ips_odropped++);    /* packet dropped (null-device) */
#endif
      goto debug_tx;
    }
  }

#if defined(USE_IPV6)
  else if (proto == IP6_TYPE)
  {
    const in6_Header *ip = (const in6_Header*) nw_pkt;

    if (!send_loopback_to_driver &&
        IN6_IS_ADDR_LOOPBACK(&ip->destination))
    {
#if defined(USE_LOOPBACK)
      len = send_loopback (*TX_BUF(), TRUE, &errline);
#else
      STAT (ip6stats.ip6s_odropped++);
#endif
      goto debug_tx;
    }
  }
#endif  /* USE_IPV6 */

#if defined(USE_PPPOE)
  else if (proto == PPPOE_SESS_TYPE)
  {
    pppoe_Packet *pppoe = (pppoe_Packet*) TX_BUF()->eth.data;

    pppoe->length = intel16 (len+2);
    len += PPPOE_HDR_SIZE + 2;      /* add 2 for protocol */
  }
#endif

  /* Store the last Tx CPU timestamp (for debugging).
   */
#if (DOSX) && !(DOSX & WINWATT)
  if (_dbugxmit && has_rdtsc)
     get_rdtsc2 (&_eth_last.tx.tstamp);
#endif

  /* Do the MAC-dependant transmit. `len' on return is total length
   * of link-layer packet sent. `len' is 0 on failure. The xmit-hook
   * is used by e.g. libpcap/libnet.
   */
  if (_eth_xmit_hook)
       len = (*_eth_xmit_hook) (TX_BUF(), len + _pkt_ip_ofs);
  else len = (*mac_transmit) (TX_BUF(), len + _pkt_ip_ofs);

  if (len > _pkt_ip_ofs)
  {
    _eth_last.tx.size = len;
    len -= _pkt_ip_ofs;
  }
  else
  {
    if (debug_on)
       outs ("Tx failed. ");
    len = 0;
    _eth_last.tx.size = 0;
  }

debug_tx:

#if defined(NEED_PKT_SPLIT)
  pkt_split_mac_out (TX_BUF());
#endif

#if defined(USE_STATISTICS)
  if (len > 0)
     update_out_stat();
#endif

#if defined(USE_DEBUG)
  if (_dbugxmit)
    (*_dbugxmit) (sock, (const in_Header*)nw_pkt, file, line);

  if (len == 0)
  {
    if (errline && !send_loopback_to_driver)
       dbug_printf ("** Error in loopback handler, line %u\n", errline);
    else
    {
      const char err[] = "** Transmit fault **\n";
      TCP_CONSOLE_MSG (0, ("%s", err));
      dbug_printf (err);
    }
  }
#else
  ARGSUSED (sock);
  ARGSUSED (file);
  ARGSUSED (line);
#endif

  /* Undo hack done in pppoe_mac_format()
   */
  if (proto == PPPOE_SESS_TYPE || _pktdevclass == PDCLASS_ETHER)
     _pkt_ip_ofs = sizeof(eth_Header);
  return (len);
}