⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scceth.c

📁 Coldfire MCF5282 DBug bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (i = 0; i < data_length; i++)
	{
		*data++ =  eth_data[i];
	}
	for (i = data_length; i < ETH_MIN_SIZE; ++i)
	{
		*data++ = 0x00;
	}
	if (data_length < ETH_MIN_SIZE)
	{
		data_length = ETH_MIN_SIZE;
	}

	/*
	 * The SCC will compute the CRC for us.
	 */

	/*
	 * Update the BD and send it off!
	 */
	txbd->length = 6 + 6 + 2 + data_length;

	txbd->status = ( 0
		| MPC8XX_BD_SCCETH_TX_STATUS_R
		| MPC8XX_BD_SCCETH_TX_STATUS_PAD
		| MPC8XX_BD_SCCETH_TX_STATUS_W
		| MPC8XX_BD_SCCETH_TX_STATUS_I
		| MPC8XX_BD_SCCETH_TX_STATUS_L
		| MPC8XX_BD_SCCETH_TX_STATUS_TC
		) ;

	return TRUE;
}

/********************************************************************/
static void
SCC_RECEIVE (NIF *eth_nif)
{
	/*
	 * This routine pulls one or more ethernet frames from
	 * the ethernet buffers.
	 */
	MPC8XX_IMM	*imm = mpc8xx_get_immp();
	MPC8XX_BD *rxbd, *nextbd;
	ETH_ADDR eth_src, eth_dest;
	uint16 eth_type;
	NBUF *frame;
	int i, frame_length;
	uint8 *rdata;
	rxbd = (MPC8XX_BD *)eth_nif->next_receive;
	eth_type = 0;
	frame = NULL;
	frame_length = 0;
	
	do
	{
		if (rxbd->status & MPC8XX_BD_SCCETH_RX_STATUS_EMASK)
		{
			/*
			 * Record the error and clear this BD for future use.
			 */
			++eth_nif->f_rx_err;

			/*
			 * Update pointer to next valid Rx buffer
			 */
			goto next_frame;
		}

		rdata = (uint8 *)rxbd->address;
		frame_length = rxbd->length;

		/* receive the frame */
		eth_dest[0] = *rdata++;
		eth_dest[1] = *rdata++;
		eth_dest[2] = *rdata++;
		eth_dest[3] = *rdata++;
		eth_dest[4] = *rdata++;
		eth_dest[5] = *rdata++;

		eth_src[0] = *rdata++;
		eth_src[1] = *rdata++;
		eth_src[2] = *rdata++;
		eth_src[3] = *rdata++;
		eth_src[4] = *rdata++;
		eth_src[5] = *rdata++;

		eth_type = ((*rdata++) << 8);
		eth_type |= *rdata++;

/*
 * FIX !!! This is a temporary solution to prevent sending up
 * un-necessary packets due to the fragile implementation of TFTP.
 */
if ((eth_dest[0] == 0xFF) && (eth_dest[1] == 0xFF) &&
	(eth_dest[2] == 0xFF) && (eth_dest[3] == 0xFF) &&
	(eth_dest[4] == 0xFF) && (eth_dest[5] == 0xFF))
  {
    /*
      printf("RX: Ethernet Broadcast hdr  FF FF FF FF FF FF\n");	
    */
    goto next_frame;
  }


#if 0
	printf("Dst: %02X:%02X:%02X:%02X:%02X:%02X\n",
		eth_dest[0],
		eth_dest[1],
		eth_dest[2],
		eth_dest[3],
		eth_dest[4],
		eth_dest[5]);
	printf("Src: %02X:%02X:%02X:%02X:%02X:%02X\n",
		eth_src[0],
		eth_src[1],
		eth_src[2],
		eth_src[3],
		eth_src[4],
		eth_src[5]);
	printf("Typ: %04X\n", eth_type);
#endif

		if (!nif_proto(eth_nif, eth_type))
			goto next_frame;

#if 0
		not_me = FALSE;
		for (i = 0; i < sizeof(ETH_ADDR); i++)
		{
			if (eth_src[i] != eth_nif->hwa[i])
			{
				not_me = TRUE;
				break;
			}
		}
		if (!not_me)
			goto next_frame;
#endif
		/*
		 * Obtain system RAM buffer for the frame.
		 */
		if ((frame = nbuf_allocate(frame_length)) == NULL)
		{
		  /*
		    printf("\n Failed in nbuf_allocate()\n");
		  */
		  goto next_frame;
		}

		frame_length -= (6 + 6 + 2 + 0/*CRC*/);
		for (i = 0; i < frame_length; ++i)
		{
			frame->data[i] = *rdata++;
		}
		frame->length = frame_length;
		/*
		  Check if there is any request to abort
		*/
		if (board_getchar_present()) {
		  if (board_getchar() == 0x03) 
		    {  /* check for ctrl-c */
		      printf("\nINFO: SCC received Ctrl-C, abort!\n");
		      nbuf_allocate(frame_length);
		      eth_nif->f_err=1; 
		    }
		}
		nif_proto_handler(eth_nif, eth_type,
			&frame->data[0], frame_length);

		/*
		 * This frame has been processed, move on to the next
		 */
	next_frame:

		if (board_getchar_present()) {
		  if (board_getchar() == 0x03) 
		    {  /* check for ctrl-c */
		      printf("\nINFO: SCC received Ctrl-C, Abort!\n");
		      eth_nif->f_err=1; 
		      /*allocate nbuf to allow polling function to read C-c*/
		      nbuf_allocate(frame_length);
		      nif_proto_handler(eth_nif, eth_type,
					&frame->data[0], frame_length);
		    }
		}

		/*
		 * Update pointer to next valid Rx buffer
		 */
		rxbd->length = 0;
		if (rxbd->status & MPC8XX_BD_SCCETH_RX_STATUS_W)
		{
			rxbd->status = ( 0
				| MPC8XX_BD_SCCETH_RX_STATUS_E
				| MPC8XX_BD_SCCETH_RX_STATUS_W
				| MPC8XX_BD_SCCETH_RX_STATUS_I
				) ;

			nextbd = &imm->dpram.bd[_BD_SCC_RX_];
		}
		else
		{
			rxbd->status = ( 0
				| MPC8XX_BD_SCCETH_RX_STATUS_E
				| MPC8XX_BD_SCCETH_RX_STATUS_I
				) ;

			nextbd = rxbd;
			++nextbd;
		}
		eth_nif->next_receive = (int)nextbd;

		rxbd = nextbd;

	} while (!(rxbd->status & MPC8XX_BD_SCCETH_RX_STATUS_E));
}

/********************************************************************/
static void
SCC_START (NIF *eth_nif)
{
	/*
	 * This function allows the MPC8XX SCC Ethernet channel to
	 * start receiving frames from the network.
	 */
	MPC8XX_IMM *imm = mpc8xx_get_immp();

	(void)eth_nif;
 
	/*
	 * Turn off transmitter by giving graceful stop command.
	 */ 
	imm->cp.CPCR = ( 0
		| MPC8XX_CP_CPCR_OPCODE_GR_STOP_TX
		| MPC8XX_CP_CPCR_FLG
		| _MPC8XX_CP_CPCR_CHANNEL_SCCx_
		) ;
	while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
		;

	/*
	 * Initialize Tx and Rx Parameters and wait for Ack
	 */
	while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
		;
	imm->cp.CPCR = ( 0
		| MPC8XX_CP_CPCR_OPCODE_INIT_RX_TX
		| _MPC8XX_CP_CPCR_CHANNEL_SCCx_
		| MPC8XX_CP_CPCR_FLG
		) ;
	while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
		;

	/*
	 * Enable the Transmitter and Receiver and we're done!
	 */
	imm-> _SCC_ .GSMR_L |= ( 0
		| MPC8XX_SCC_GSMR_L_ENR
		| MPC8XX_SCC_GSMR_L_ENT
		) ;
}

/********************************************************************/
static void
SCC_STOP (NIF *eth_nif)
{
	/*
	 * This function stops the MPC8XX SCC Ethernet channel from
	 * receiving frames from the network.
	 */
	MPC8XX_IMM *imm = mpc8xx_get_immp();

	(void)eth_nif;

	/*
	 * Turn off the receiver
	 */
	imm-> _SCC_ .GSMR_L &= ~MPC8XX_SCC_GSMR_L_ENR;

	/*
	 * Turn off transmitter by giving graceful stop command.
	 */ 
	imm->cp.CPCR = ( 0
		| MPC8XX_CP_CPCR_OPCODE_GR_STOP_TX
		| MPC8XX_CP_CPCR_FLG
		| _MPC8XX_CP_CPCR_CHANNEL_SCCx_
		) ;

	/*
	 * Wait for completion
	 */
#if 0
	while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
		;
#endif

	board_second_wait(1);
}

/********************************************************************/
int
SCC_HANDLER (void *dev, void *arg)
{
	/*
	 * This is the interrupt service routine for SCC Ethernet
	 */
	MPC8XX_IMM	*imm = mpc8xx_get_immp();
	MPC8XX_PRAM_SCCETH *sccpram;
	uint16 scce;
	MPC8XX_BD *bd;
	NIF *eth_nif = (NIF *)arg;

	(void)dev;

	sccpram = (MPC8XX_PRAM_SCCETH *)&imm->dpram. _SCC_ ;

	/*
	 * Check the cause of interrupts in SCC
	 */
	scce = imm-> _SCC_ .SCCE;

	if (scce == 0)
	{
		return FALSE; /* wasn't me! */
	}

	if (scce & MPC8XX_SCC_ETH_SCCE_GRA)
	{
		/* printf("Graceful Stop\n"); */
	}
	if (scce & MPC8XX_SCC_ETH_SCCE_TXE)
	{
		bd = (MPC8XX_BD *)((uint32)sccpram->scc.TBASE + (uint32)imm);
		printf("TXE, BD->status:  %04X\n",bd->status);
		printf("TXE, BD->length:  %04X\n",bd->length);
		/*
		 * Send TRANSMIT RESTART
		 */
		while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
			;
		imm->cp.CPCR = ( 0
			| MPC8XX_CP_CPCR_OPCODE_RESTART_TX
			| _MPC8XX_CP_CPCR_CHANNEL_SCCx_
			| MPC8XX_CP_CPCR_FLG
			) ;
		while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
			;

		/*
		 * Resend the packet!
		 */
		bd->status = ( 0
			| MPC8XX_BD_SCCETH_TX_STATUS_R
			| MPC8XX_BD_SCCETH_TX_STATUS_PAD
			| MPC8XX_BD_SCCETH_TX_STATUS_W
			| MPC8XX_BD_SCCETH_TX_STATUS_I
			| MPC8XX_BD_SCCETH_TX_STATUS_L
			| MPC8XX_BD_SCCETH_TX_STATUS_TC
			) ;
	}
	if (scce & MPC8XX_SCC_ETH_SCCE_RXF)
	{
		SCC_RECEIVE (eth_nif);
	}
	if (scce & MPC8XX_SCC_ETH_SCCE_BSY)
	{
		/*printf("RX Buf\n");*/
	}
	if (scce & MPC8XX_SCC_ETH_SCCE_TXB)
	{
	}
	if (scce & MPC8XX_SCC_ETH_SCCE_RXB)
	{
		printf("RXE\n");
	}

	/*
	 * Clear the interrupt
	 */
	imm-> _SCC_ .SCCE = ~0;

	return TRUE;
}

/********************************************************************/
int
mpc8xx_eth_init (NIF *eth_nif)
{
	/*
	 * This function initializes the network interface.
	 */
	void board_get_ethaddr(uint8 *);

	nif_create (eth_nif, "mpc8xx SCC");
	eth_nif->nic = (void *)mpc8xx_get_immp();
	board_get_ethaddr(&eth_nif->hwa[0]);

	eth_nif->hwa_size = 6;
	eth_nif->mtu = 1500;
	eth_nif->reset = SCC_RESET ;
	eth_nif->start = SCC_START ;
	eth_nif->stop = SCC_STOP ;
	eth_nif->send = SCC_SEND ;
	eth_nif->receive = (void *)SCC_RECEIVE ;

	return TRUE;
}

/********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -