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

📄 ixp2400_rx.uc

📁 linux2.6.16版本
💻 UC
字号:
/* * RX ucode for the Intel IXP2400 in POS-PHY mode. * Copyright (C) 2004, 2005 Lennert Buytenhek * Dedicated to Marija Kulikova. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Assumptions made in this code: * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where *   only one full element list is used.  This includes, for example, *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4.  (This *   is not an exhaustive list.) * - The RBUF uses 64-byte mpackets. * - RX descriptors reside in SRAM, and have the following format: *	struct rx_desc *	{ *	// to uengine *		u32	buf_phys_addr; *		u32	buf_length; * *	// from uengine *		u32	channel; *		u32	pkt_length; *	}; * - Packet data resides in DRAM. * - Packet buffer addresses are 8-byte aligned. * - Scratch ring 0 is rx_pending. * - Scratch ring 1 is rx_done, and has status condition 'full'. * - The host triggers rx_done flush and rx_pending refill on seeing INTA. * - This code is run on all eight threads of the microengine it runs on. * * Local memory is used for per-channel RX state. */#define RX_THREAD_FREELIST_0		0x0030#define RBUF_ELEMENT_DONE		0x0044#define CHANNEL_FLAGS			*l$index0[0]#define CHANNEL_FLAG_RECEIVING		1#define PACKET_LENGTH			*l$index0[1]#define PACKET_CHECKSUM			*l$index0[2]#define BUFFER_HANDLE			*l$index0[3]#define BUFFER_START			*l$index0[4]#define BUFFER_LENGTH			*l$index0[5]#define CHANNEL_STATE_SIZE		24	// in bytes#define CHANNEL_STATE_SHIFT		5	// ceil(log2(state size))	.sig volatile sig1	.sig volatile sig2	.sig volatile sig3	.sig mpacket_arrived	.reg add_to_rx_freelist	.reg read $rsw0, $rsw1	.xfer_order $rsw0 $rsw1	.reg zero	/*	 * Initialise add_to_rx_freelist.	 */	.begin		.reg temp		.reg temp2		immed[add_to_rx_freelist, RX_THREAD_FREELIST_0]		immed_w1[add_to_rx_freelist, (&$rsw0 | (&mpacket_arrived << 12))]		local_csr_rd[ACTIVE_CTX_STS]		immed[temp, 0]		alu[temp2, temp, and, 0x1f]		alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<20]		alu[temp2, temp, and, 0x80]		alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<18]	.end	immed[zero, 0]	/*	 * Skip context 0 initialisation?	 */	.begin		br!=ctx[0, mpacket_receive_loop#]	.end	/*	 * Initialise local memory.	 */	.begin		.reg addr		.reg temp		immed[temp, 0]	init_local_mem_loop#:		alu_shf[addr, --, b, temp, <<CHANNEL_STATE_SHIFT]		local_csr_wr[ACTIVE_LM_ADDR_0, addr]		nop		nop		nop		immed[CHANNEL_FLAGS, 0]		alu[temp, temp, +, 1]		alu[--, temp, and, 0x20]		beq[init_local_mem_loop#]	.end	/*	 * Initialise signal pipeline.	 */	.begin		local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]		.set_sig sig1		local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]		.set_sig sig2		local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]		.set_sig sig3	.endmpacket_receive_loop#:	/*	 * Synchronise and wait for mpacket.	 */	.begin		ctx_arb[sig1]		local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]		msf[fast_wr, --, add_to_rx_freelist, 0]		.set_sig mpacket_arrived		ctx_arb[mpacket_arrived]		.set $rsw0 $rsw1	.end	/*	 * We halt if we see {inbparerr,parerr,null,soperror}.	 */	.begin		alu_shf[--, 0x1b, and, $rsw0, >>8]		bne[abort_rswerr#]	.end	/*	 * Point local memory pointer to this channel's state area.	 */	.begin		.reg chanaddr		alu[chanaddr, $rsw0, and, 0x1f]		alu_shf[chanaddr, --, b, chanaddr, <<CHANNEL_STATE_SHIFT]		local_csr_wr[ACTIVE_LM_ADDR_0, chanaddr]		nop		nop		nop	.end	/*	 * Check whether we received a SOP mpacket while we were already	 * working on a packet, or a non-SOP mpacket while there was no	 * packet pending.  (SOP == RECEIVING -> abort)  If everything's	 * okay, update the RECEIVING flag to reflect our new state.	 */	.begin		.reg temp		.reg eop		#if CHANNEL_FLAG_RECEIVING != 1		#error CHANNEL_FLAG_RECEIVING is not 1		#endif		alu_shf[temp, 1, and, $rsw0, >>15]		alu[temp, temp, xor, CHANNEL_FLAGS]		alu[--, temp, and, CHANNEL_FLAG_RECEIVING]		beq[abort_proterr#]		alu_shf[eop, 1, and, $rsw0, >>14]		alu[CHANNEL_FLAGS, temp, xor, eop]	.end	/*	 * Copy the mpacket into the right spot, and in case of EOP,	 * write back the descriptor and pass the packet on.	 */	.begin		.reg buffer_offset		.reg _packet_length		.reg _packet_checksum		.reg _buffer_handle		.reg _buffer_start		.reg _buffer_length		/*		 * Determine buffer_offset, _packet_length and		 * _packet_checksum.		 */		.begin			.reg temp			alu[--, 1, and, $rsw0, >>15]			beq[not_sop#]			immed[PACKET_LENGTH, 0]			immed[PACKET_CHECKSUM, 0]		not_sop#:			alu[buffer_offset, --, b, PACKET_LENGTH]			alu_shf[temp, 0xff, and, $rsw0, >>16]			alu[_packet_length, buffer_offset, +, temp]			alu[PACKET_LENGTH, --, b, _packet_length]			immed[temp, 0xffff]			alu[temp, $rsw1, and, temp]			alu[_packet_checksum, PACKET_CHECKSUM, +, temp]			alu[PACKET_CHECKSUM, --, b, _packet_checksum]		.end		/*		 * Allocate buffer in case of SOP.		 */		.begin			.reg temp			alu[temp, 1, and, $rsw0, >>15]			beq[skip_buffer_alloc#]			.begin				.sig zzz				.reg read $stemp $stemp2				.xfer_order $stemp $stemp2			rx_nobufs#:				scratch[get, $stemp, zero, 0, 1], ctx_swap[zzz]				alu[_buffer_handle, --, b, $stemp]				beq[rx_nobufs#]				sram[read, $stemp, _buffer_handle, 0, 2],								ctx_swap[zzz]				alu[_buffer_start, --, b, $stemp]				alu[_buffer_length, --, b, $stemp2]			.end		skip_buffer_alloc#:		.end		/*		 * Resynchronise.		 */		.begin			ctx_arb[sig2]			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]		.end		/*		 * Synchronise buffer state.		 */		.begin			.reg temp			alu[temp, 1, and, $rsw0, >>15]			beq[copy_from_local_mem#]			alu[BUFFER_HANDLE, --, b, _buffer_handle]			alu[BUFFER_START, --, b, _buffer_start]			alu[BUFFER_LENGTH, --, b, _buffer_length]			br[sync_state_done#]		copy_from_local_mem#:			alu[_buffer_handle, --, b, BUFFER_HANDLE]			alu[_buffer_start, --, b, BUFFER_START]			alu[_buffer_length, --, b, BUFFER_LENGTH]		sync_state_done#:		.end#if 0		/*		 * Debug buffer state management.		 */		.begin			.reg temp			alu[temp, 1, and, $rsw0, >>14]			beq[no_poison#]			immed[BUFFER_HANDLE, 0xdead]			immed[BUFFER_START, 0xdead]			immed[BUFFER_LENGTH, 0xdead]		no_poison#:			immed[temp, 0xdead]			alu[--, _buffer_handle, -, temp]			beq[state_corrupted#]			alu[--, _buffer_start, -, temp]			beq[state_corrupted#]			alu[--, _buffer_length, -, temp]			beq[state_corrupted#]		.end#endif		/*		 * Check buffer length.		 */		.begin			alu[--, _buffer_length, -, _packet_length]			blo[buffer_overflow#]		.end		/*		 * Copy the mpacket and give back the RBUF element.		 */		.begin			.reg element			.reg xfer_size			.reg temp			.sig copy_sig			alu_shf[element, 0x7f, and, $rsw0, >>24]			alu_shf[xfer_size, 0xff, and, $rsw0, >>16]			alu[xfer_size, xfer_size, -, 1]			alu_shf[xfer_size, 0x10, or, xfer_size, >>3]			alu_shf[temp, 0x10, or, xfer_size, <<21]			alu_shf[temp, temp, or, element, <<11]			alu_shf[--, temp, or, 1, <<18]			dram[rbuf_rd, --, _buffer_start, buffer_offset, max_8],						indirect_ref, sig_done[copy_sig]			ctx_arb[copy_sig]			alu[temp, RBUF_ELEMENT_DONE, or, element, <<16]			msf[fast_wr, --, temp, 0]		.end		/*		 * If EOP, write back the packet descriptor.		 */		.begin			.reg write $stemp $stemp2			.xfer_order $stemp $stemp2			.sig zzz			alu_shf[--, 1, and, $rsw0, >>14]			beq[no_writeback#]			alu[$stemp, $rsw0, and, 0x1f]			alu[$stemp2, --, b, _packet_length]			sram[write, $stemp, _buffer_handle, 8, 2], ctx_swap[zzz]		no_writeback#:		.end		/*		 * Resynchronise.		 */		.begin			ctx_arb[sig3]			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]		.end		/*		 * If EOP, put the buffer back onto the scratch ring.		 */		.begin			.reg write $stemp			.sig zzz			br_inp_state[SCR_Ring1_Status, rx_done_ring_overflow#]			alu_shf[--, 1, and, $rsw0, >>14]			beq[mpacket_receive_loop#]			alu[--, 1, and, $rsw0, >>10]			bne[rxerr#]			alu[$stemp, --, b, _buffer_handle]			scratch[put, $stemp, zero, 4, 1], ctx_swap[zzz]			cap[fast_wr, 0, XSCALE_INT_A]			br[mpacket_receive_loop#]		rxerr#:			alu[$stemp, --, b, _buffer_handle]			scratch[put, $stemp, zero, 0, 1], ctx_swap[zzz]			br[mpacket_receive_loop#]		.end	.endabort_rswerr#:	haltabort_proterr#:	haltstate_corrupted#:	haltbuffer_overflow#:	haltrx_done_ring_overflow#:	halt

⌨️ 快捷键说明

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