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

📄 keymile_hdlc_enet.c

📁 uboot200903最新版本的通用uboot
💻 C
📖 第 1 页 / 共 2 页
字号:
	et = NULL;	arp = NULL;	ip = NULL;	j = 0;	while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) {		/* will also trigger Wd if needed, but maybe too often  */		udelay(1);		j++;	}	if (j >= TOUT_LOOP) {		dprintf("TX not ready sc %x\n", rtx->txbd.cbd_sc);		return -1;	}	/*	 * First check for an ARP Request since this requires special handling.	 */	if (len >= (ARP_HDR_SIZE + ETHER_HDR_SIZE)) {		et = (Ethernet_t *)packet;		arp = (ARP_t *)(((char *)et) + ETHER_HDR_SIZE);		/* ARP and REQUEST? */		if (et->et_protlen == PROT_ARP &&			arp->ar_op == htons(ARPOP_REQUEST)) {			/* just short-circuit the request on the U-Boot side */			keymile_hdlc_enet_doarp(packet, len);			return 0;		}	}	/*	 * GJ - I suppose the assumption here that len will always be	 * > INET_HDR_SIZE is alright as long as the network stack	 * isn't changed.	 * Do not send INET header.	 */	data_len = len + sizeof(header) - INET_HDR_SIZE;	frame = (struct icn_frame *) (((char *)packet) + INET_HDR_SIZE -		sizeof(header));#ifdef TEST_TX	printf("frame: %08x, ", frame);	hexdump((unsigned char *)packet, data_len + INET_HDR_SIZE);#endif	data_addr = (uint)frame;	if (len >= (IP_HDR_SIZE + ETHER_HDR_SIZE))		ip = (IP_t *)(packet + ETHER_HDR_SIZE);	/* Is it TFTP? TFTP always uses UDP and the cached dport */	if (ip != NULL && ip->ip_p == IPPROTO_UDP && ip->udp_dst ==			(ushort)cachedNumbers[TFTP_DST_PORT]) {		/* just in case the port wasn't set in the environment */		if (cachedNumbers[TFTP_SRC_PORT] == (ulong)-1)			cachedNumbers[TFTP_SRC_PORT] = ip->udp_src;		frame->hdr.application = MGS_TFTP;	}	/*	 * Is it NETCONSOLE?  NETCONSOLE always uses UDP.	 */	else if (ip != NULL && ip->ip_p == IPPROTO_UDP		&& ip->udp_dst == (ushort)cachedNumbers[NETCONS_PORT]) {			frame->hdr.application = MGS_NETCONS;	} else {		/* reject unknown packets */		/* may do some check on frame->hdr.application */		dprintf("Unknown packet type in %s, rejected\n",			__func__);		return -1;	}	/*	 * Could extract the target's slot ID from its MAC here,	 * but u-boot only wants to talk to the active server.	 *	 * avoid setting new source address when moving to another slot	 */	frame->hdr.src_addr = keymile_slot;	frame->hdr.dest_addr = HDLC_UACUA;#ifdef TEST_TX	{		dprintf("TX: ");		hexdump((unsigned char *)data_addr, data_len);	}#endif	flush_cache(data_addr, data_len);	rtx->txbd.cbd_bufaddr = data_addr;	rtx->txbd.cbd_datlen = data_len;	rtx->txbd.cbd_sc |= (BD_SC_READY | BD_SC_TC | BD_SC_LAST | BD_SC_WRAP);	while ((rtx->txbd.cbd_sc & BD_SC_READY) && (j < TOUT_LOOP)) {		/* will also trigger Wd if needed, but maybe too often  */		udelay(1);		j++;	}	if (j >= TOUT_LOOP)		dprintf("TX timeout\n");#ifdef ET_DEBUG	dprintf("cycles: %d    status: %x\n", j, rtx->txbd.cbd_sc);#endif	j = (rtx->txbd.cbd_sc & BD_SC_STATS); /* return only status bits */	return j;}/* * During a receive, the RxIdx points to the current incoming buffer. * When we update through the ring, if the next incoming buffer has * not been given to the system, we just set the empty indicator, * effectively tossing the packet. */static int keymile_hdlc_enet_recv(struct eth_device *dev){	int length;	unsigned char app;	struct icn_frame *fp;	Ethernet_t *ep;	IP_t *ip;	for (;;) {		if (rtx->rxbd[keymile_rxIdx].cbd_sc & BD_SC_EMPTY) {			length = -1;			break;	/* nothing received - leave for() loop */		}		length = rtx->rxbd[keymile_rxIdx].cbd_datlen;#ifdef TEST_RX		dprintf("packet %d bytes long\n", length);#endif		/*		 * BD_SC_BR -> LG bit		 * BD_SC_FR -> NO bit		 * BD_SC_PR -> AB bit		 * BD_SC_NAK -> CR bit		 * 0x80 -> DE bit		 */		if (rtx->rxbd[keymile_rxIdx].cbd_sc & BD_SC_STATS) {#ifdef ET_DEBUG			dprintf("err: %x\n", rtx->rxbd[keymile_rxIdx].cbd_sc);#endif		} else if (length > MAX_FRAME_LENGTH) { /* can't happen */#ifdef ET_DEBUG			dprintf("err: packet too big\n");#endif		} else {			fp = (struct icn_frame *)(MyRxPackets[keymile_rxIdx] +				INET_HDR_ALIGN - INET_HDR_SIZE);#ifdef TEST_RX			dprintf("RX %d: ", keymile_rxIdx);			hexdump((unsigned char *)MyRxPackets[keymile_rxIdx],				INET_HDR_ALIGN + INET_HDR_SIZE + 4);#endif			/* copy icn header to the beginning */			memcpy(fp, ((char *)fp + INET_HDR_SIZE),				sizeof(struct icn_hdr));			app = fp->hdr.application;			if (app == MGS_NETCONS || app == MGS_TFTP) {				struct icn_hdr *ih = &fp->hdr;				unsigned char icn_src_addr = ih->src_addr;				unsigned char icn_dest_addr = ih->dest_addr;				/*				 * expand header by INET_HDR_SIZE				 */				length += INET_HDR_SIZE;				/* initalize header */				memset((char *)fp->data, 0x00, INET_HDR_SIZE);				ep = (Ethernet_t *)fp->data;				/* set MACs */				ep->et_dest[0] = icn_dest_addr;				ep->et_src[0] = icn_src_addr;				ep->et_protlen = htons(PROT_IP);				/* set ip stuff */				ip = (IP_t *)(fp->data + ETHER_HDR_SIZE);				/* set ip addresses */				ip->ip_src = cachedNumbers[IP_SERVER];				ip->ip_dst = cachedNumbers[IP_ADDR];				/* ip length */				ip->ip_len = htons(length - ETHER_HDR_SIZE -					REMOVE);				/* ip proto */				ip->ip_p = IPPROTO_UDP;				switch (app) {				case MGS_TFTP:					/* swap src/dst port numbers */					ip->udp_src = (ushort)						cachedNumbers[TFTP_DST_PORT];					ip->udp_dst = (ushort)						cachedNumbers[TFTP_SRC_PORT];					ip->udp_len = ip->ip_len -						IP_HDR_SIZE_NO_UDP;					ip->udp_xsum = 0;					break;				case MGS_NETCONS:					ip->udp_src = (ushort)						cachedNumbers[NETCONS_PORT];					/*					 * in drivers/net/netconsole.c src port					 * equals dest port					 */					ip->udp_dst = ip->udp_src;					ip->udp_len = ip->ip_len -						IP_HDR_SIZE_NO_UDP;					ip->udp_xsum = 0;					break;				}				/* ip version */				ip->ip_hl_v = (0x40) | (0x0f &					(IP_HDR_SIZE_NO_UDP / 4));				ip->ip_tos = 0;				ip->ip_id = 0;				/* flags, fragment offset */				ip->ip_off = htons(0x4000);				ip->ip_ttl = 255; /* time to live */				/* have to fixup the checksum */				ip->ip_sum = ~NetCksum((uchar *)ip,					IP_HDR_SIZE_NO_UDP / 2);				/*				 * Pass the packet up to the protocol layers				 * but remove dest_addr, src_addr, application				 * and the CRC.				 */#ifdef TEST_RX				hexdump((unsigned char *)fp->data,					INET_HDR_SIZE + 4);#endif				NetReceive(fp->data, length - REMOVE);			} else {				/*				 * the other application types are not yet				 * supported by u-boot.				 */				/* normally drop it */#ifdef TEST_NO				/* send it anyway */				fp = (struct icn_frame *)					(MyRxPackets[keymile_rxIdx] +						INET_HDR_ALIGN);				NetReceive(fp->data, length - REMOVE);#endif			}		}		/* Give the buffer back to the SCC. */		rtx->rxbd[keymile_rxIdx].cbd_datlen = 0;		/* wrap around buffer index when necessary */		if ((keymile_rxIdx + 1) >= HDLC_PKTBUFSRX) {			rtx->rxbd[HDLC_PKTBUFSRX - 1].cbd_sc =				(BD_SC_WRAP | BD_SC_EMPTY);			keymile_rxIdx = 0;		} else {			rtx->rxbd[keymile_rxIdx].cbd_sc = BD_SC_EMPTY;			keymile_rxIdx++;		}	}	return length;}#ifdef TEST_IT/* simple send test routine */int hdlc_enet_stest(struct cmd_tbl_s *a, int b, int c, char **d){	unsigned char pkt[2];	int ret;	dprintf("enter stest\n");	/* may have to initialize things */	if (seth->state != ETH_STATE_ACTIVE) {		/* the bd_t* is not used */		if (seth->init(seth, NULL) >= 0)			seth->state = ETH_STATE_ACTIVE;	}	pkt[0] = 0xea;	pkt[1] = 0xae;	ret = keymile_hdlc_enet_send(seth, pkt, 2);	dprintf("return from send %x\n", ret);	dprintf("exit stest\n");	return ret;}U_BOOT_CMD(	stest, 1, 1, hdlc_enet_stest,	"simple send test for hdlc_enet",	"no arguments\n");/* simple receive test routine */int hdlc_enet_rtest(struct cmd_tbl_s *a, int b, int c, char **d){	int ret;	dprintf("enter rtest\n");	/* may have to initialize things */	if (seth->state != ETH_STATE_ACTIVE) {		/* the bd_t* is not used */		if (seth->init(seth, NULL) >= 0)			seth->state = ETH_STATE_ACTIVE;	}	ret = keymile_hdlc_enet_recv(seth);	dprintf("return from recv %x\n", ret);	dprintf("exit rtest\n");	return ret;}U_BOOT_CMD(	rtest, 1, 1, hdlc_enet_rtest,	"simple receive test for hdlc_enet",	"no arguments\n");#endif#endif /* CONFIG_KEYMILE_HDLC_ENET */

⌨️ 快捷键说明

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