From owner-p4-projects@FreeBSD.ORG Fri Apr 21 18:03:11 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8374516A403; Fri, 21 Apr 2006 18:03:11 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 5C04316A401 for ; Fri, 21 Apr 2006 18:03:11 +0000 (UTC) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 11CAD43D46 for ; Fri, 21 Apr 2006 18:03:11 +0000 (GMT) (envelope-from imp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k3LI3BhG078694 for ; Fri, 21 Apr 2006 18:03:11 GMT (envelope-from imp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k3LI3Alc078686 for perforce@freebsd.org; Fri, 21 Apr 2006 18:03:10 GMT (envelope-from imp@freebsd.org) Date: Fri, 21 Apr 2006 18:03:10 GMT Message-Id: <200604211803.k3LI3Alc078686@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to imp@freebsd.org using -f From: Warner Losh To: Perforce Change Reviews Cc: Subject: PERFORCE change 95807 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Apr 2006 18:03:11 -0000 http://perforce.freebsd.org/chv.cgi?CH=95807 Change 95807 by imp@imp_hammer on 2006/04/21 18:03:02 Revert optimizations until they can be debugged. Affected files ... .. //depot/projects/arm/src/sys/boot/arm/at91/libat91/emac.c#5 edit Differences ... ==== //depot/projects/arm/src/sys/boot/arm/at91/libat91/emac.c#5 (text+ko) ==== @@ -1,4 +1,4 @@ -/****************************************************************************** +/******************************************************************************* * * Filename: emac.c * @@ -18,23 +18,22 @@ * owners. This software is not copyrighted and is intended for reference * only. * END_BLOCK - * - * $FreeBSD: src/sys/boot/arm/at91/libat91/emac.c,v 1.1 2006/04/19 17:16:49 imp Exp $ - *****************************************************************************/ + ******************************************************************************/ #include "at91rm9200.h" +#include "at91rm9200_lowlevel.h" #include "emac.h" #include "p_string.h" -#include "at91rm9200_lowlevel.h" #include "lib.h" -/******************************* GLOBALS *************************************/ +/* ****************************** GLOBALS *************************************/ -/*********************** PRIVATE FUNCTIONS/DATA ******************************/ +/* ********************** PRIVATE FUNCTIONS/DATA ******************************/ static unsigned localMACSet, serverMACSet, MAC_init; static unsigned char localMACAddr[6], serverMACAddr[6]; -static unsigned localIPAddr, serverIPAddr; +static unsigned localIPSet, serverIPSet; +static unsigned char localIPAddr[4], serverIPAddr[4]; static unsigned short serverPort, localPort; static int ackBlock; @@ -53,17 +52,17 @@ * This private function calculates the IP checksum for various headers. * .KB_C_FN_DEFINITION_END */ -static unsigned short -IP_checksum(void *cp, int len) +static unsigned short IP_checksum(unsigned short *p, int len) { unsigned i, t; - unsigned short *p = (unsigned short *)cp; len &= ~1; + for (i=0,t=0; i> 16); - return (~t); + return (~t); } @@ -73,13 +72,14 @@ * This private function sends an ARP request to determine the server MAC. * .KB_C_FN_DEFINITION_END */ -static void -GetServerAddress(void) -{ +static void GetServerAddress(void) { + arp_header_t *p_ARP; p_ARP = (arp_header_t*)transmitBuffer; + p_memset((char*)p_ARP->dest_mac, 0xFF, 6); + p_memcpy((char*)p_ARP->src_mac, (char*)localMACAddr, 6); p_ARP->frame_type = SWAP16(PROTOCOL_ARP); @@ -90,8 +90,11 @@ p_ARP->operation = SWAP16(ARP_REQUEST); p_memcpy((char*)p_ARP->sender_mac, (char*)localMACAddr, 6); + p_memcpy((char*)p_ARP->sender_ip, (char*)localIPAddr, 4); + p_memset((char*)p_ARP->target_mac, 0, 6); + p_memcpy((char*)p_ARP->target_ip, (char*)serverIPAddr, 4); // wait until transmit is available @@ -109,8 +112,7 @@ * This private function initializes and send a TFTP packet. * .KB_C_FN_DEFINITION_END */ -static void -Send_TFTP_Packet(char *tftpData, unsigned tftpLength) +static void Send_TFTP_Packet(char *tftpData, unsigned tftpLength) { transmit_header_t *macHdr = (transmit_header_t*)tftpSendPacket; ip_header_t *ipHdr; @@ -118,11 +120,12 @@ unsigned t_checksum; p_memcpy((char*)macHdr->dest_mac, (char*)serverMACAddr, 6); + p_memcpy((char*)macHdr->src_mac, (char*)localMACAddr, 6); macHdr->proto_mac = SWAP16(PROTOCOL_IP); - ipHdr = &macHdr->iphdr; + ipHdr = (ip_header_t*)&macHdr->packet_length; ipHdr->ip_v_hl = 0x45; ipHdr->ip_tos = 0; @@ -134,20 +137,21 @@ ipHdr->ip_sum = 0; p_memcpy((char*)ipHdr->ip_src, (char*)localIPAddr, 4); + p_memcpy((char*)ipHdr->ip_dst, (char*)serverIPAddr, 4); - ipHdr->ip_sum = SWAP16(IP_checksum(ipHdr, 20)); + ipHdr->ip_sum = SWAP16(IP_checksum((unsigned short*)ipHdr, 20)); udpHdr = (udp_header_t*)(ipHdr + 1); - udpHdr->src_port = localPort; - udpHdr->dst_port = serverPort; + udpHdr->src_port = SWAP16(localPort); + udpHdr->dst_port = SWAP16(serverPort); udpHdr->udp_len = SWAP16(8 + tftpLength); udpHdr->udp_cksum = 0; p_memcpy((char*)udpHdr+8, tftpData, tftpLength); - t_checksum = IP_checksum((char *)ipHdr + 12, (16 + tftpLength)); + t_checksum = IP_checksum((unsigned short*)ipHdr + 6, (16 + tftpLength)); t_checksum = (~t_checksum) & 0xFFFF; t_checksum += 25 + tftpLength; @@ -171,9 +175,8 @@ * This private function sends a RRQ packet to the server. * .KB_C_FN_DEFINITION_END */ -static void -TFTP_RequestFile(char *filename) -{ +static void TFTP_RequestFile(char *filename) { + tftp_header_t tftpHeader; char *cPtr, *ePtr, *mPtr; unsigned length; @@ -198,12 +201,11 @@ * This private function sends an ACK packet to the server. * .KB_C_FN_DEFINITION_END */ -static void -TFTP_ACK_Data(char *data, unsigned short block_num, unsigned short len) -{ +static void TFTP_ACK_Data(char *data, unsigned short block_num, unsigned short len) { + tftp_header_t tftpHeader; - if (block_num == SWAP16(ackBlock + 1)) { + if (block_num == (ackBlock + 1)) { ++ackBlock; p_memcpy(dlAddress, data, len); dlAddress += len; @@ -211,7 +213,7 @@ } tftpHeader.opcode = SWAP16(TFTP_ACK_OPCODE); - tftpHeader.block_num = block_num; + tftpHeader.block_num = SWAP16(block_num); Send_TFTP_Packet((char*)&tftpHeader, 4); if (len < 512) @@ -226,10 +228,9 @@ * any here. * .KB_C_FN_DEFINITION_END */ -static void -CheckForNewPacket(void) -{ - unsigned short *pFrameType; +static void CheckForNewPacket(ip_header_t *pHeader) { + + unsigned short *pFrameType, *pArpOp; unsigned i; char *pData; ip_header_t *pIpHeader; @@ -256,10 +257,11 @@ switch (SWAP16(*pFrameType)) { case PROTOCOL_ARP: + + pArpOp = (unsigned short *) (pData + 20); p_ARP = (arp_header_t*)pData; - i = SWAP16(p_ARP->operation); - if (i == ARP_REPLY) { + if (SWAP16(*pArpOp) == ARP_REPLY) { // check if new server info is available if ((!serverMACSet) && @@ -271,22 +273,30 @@ p_memcpy((char*)serverMACAddr, (char*)p_ARP->sender_mac, 6); } - } else if (i == ARP_REQUEST) { + } + + if (SWAP16(*pArpOp) == ARP_REQUEST) { // ARP REPLY operation - p_ARP->operation = SWAP16(ARP_REPLY); + *pArpOp = SWAP16(ARP_REPLY); + + // Fill the dest address and src address + for (i = 0; i <6; i++) { + // swap ethernet dest address and ethernet src address + pData[i] = pData[i+6]; + pData[i+6] = localMACAddr[i]; + // swap sender ethernet address and target ethernet address + pData[i+22] = localMACAddr[i]; + pData[i+32] = pData[i+6]; + } - // Swap the src/dst MAC addr - p_memcpy(p_ARP->dest_mac, p_ARP->src_mac, 6); - p_memcpy(p_ARP->src_mac, localMACAddr, 6); - - // Do IP and MAC addr at same time. - p_memcpy(p_ARP->target_mac, p_ARP->sender_mac, 10); - p_memcpy(p_ARP->sender_mac, localMACAddr, 6); - p_memcpy(p_ARP->sender_ip, (char *)&localIPAddr, 4); + // swap sender IP address and target IP address + for (i = 0; i<4; i++) { + pData[i+38] = pData[i+28]; + pData[i+28] = localIPAddr[i]; + } - if (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) - break; + if (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) break; *AT91C_EMAC_TSR |= AT91C_EMAC_COMP; *AT91C_EMAC_TAR = (unsigned)pData; @@ -295,8 +305,11 @@ break; case PROTOCOL_IP: - pIpHeader = (ip_header_t*)(pData + 14); + pIpHeader = (ip_header_t*)(pData + 14); + p_memcpy((char*)pHeader, (char*)pIpHeader,sizeof(ip_header_t)); + switch(pIpHeader->ip_p) { + case PROTOCOL_UDP: { udp_header_t *udpHdr; @@ -305,24 +318,24 @@ udpHdr = (udp_header_t*)((char*)pIpHeader+20); tftpHdr = (tftp_header_t*)((char*)udpHdr + 8); - if (udpHdr->dst_port != localPort) + if (SWAP16(udpHdr->dst_port) != localPort) break; - if (tftpHdr->opcode != SWAP16(TFTP_DATA_OPCODE)) + if (SWAP16(tftpHdr->opcode) != TFTP_DATA_OPCODE) break; if (ackBlock == -1) { - if (tftpHdr->block_num != SWAP16(1)) + if (SWAP16(tftpHdr->block_num) != 1) break; - serverPort = udpHdr->src_port; + serverPort = SWAP16(udpHdr->src_port); ackBlock = 0; } - if (serverPort != udpHdr->src_port) + if (serverPort != SWAP16(udpHdr->src_port)) break; TFTP_ACK_Data(tftpHdr->data, - tftpHdr->block_num, + SWAP16(tftpHdr->block_num), SWAP16(udpHdr->udp_len) - 12); } break; @@ -345,9 +358,8 @@ * This private function reads the PHY device. * .KB_C_FN_DEFINITION_END */ -static unsigned short -AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr) -{ +static unsigned short AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr) { + unsigned value = 0x60020000 | (addr << 18); pEmac->EMAC_CTL |= AT91C_EMAC_MPE; @@ -364,12 +376,11 @@ * This private function determines the link speed set by the PHY. * .KB_C_FN_DEFINITION_END */ -static void -MII_GetLinkSpeed(AT91PS_EMAC pEmac) -{ - unsigned short stat2; +static void MII_GetLinkSpeed(AT91PS_EMAC pEmac) { + + unsigned short stat2; unsigned update = 0; - + stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS2_REG); if (!(stat2 & 0x400)) { @@ -398,14 +409,14 @@ * This private function initializes the EMAC on the chip. * .KB_C_FN_DEFINITION_END */ -static void -AT91F_EmacEntry(void) -{ +static void AT91F_EmacEntry(void) { + unsigned i; char *pRxPacket = (char*)RX_DATA_START; AT91PS_EMAC pEmac = AT91C_BASE_EMAC; for (i = 0; i < MAX_RX_PACKETS; ++i) { + p_rxBD[i].address = (unsigned)pRxPacket; p_rxBD[i].size = 0; pRxPacket += RX_PACKET_SIZE; @@ -420,9 +431,7 @@ MII_GetLinkSpeed(pEmac); // the sequence write EMAC_SA1L and write EMAC_SA1H must be respected - pEmac->EMAC_SA1L = ((unsigned)localMACAddr[2] << 24) | - ((unsigned)localMACAddr[3] << 16) | ((int)localMACAddr[4] << 8) | - localMACAddr[5]; + pEmac->EMAC_SA1L = ((unsigned)localMACAddr[2] << 24) | ((unsigned)localMACAddr[3] << 16) | ((int)localMACAddr[4] << 8) | localMACAddr[5]; pEmac->EMAC_SA1H = ((unsigned)localMACAddr[0] << 8) | localMACAddr[1]; pEmac->EMAC_RBQP = (unsigned) p_rxBD; @@ -446,9 +455,7 @@ * four bytes while high_address is the last 2 bytes of the 48-bit value. * .KB_C_FN_DEFINITION_END */ -void -SetMACAddress(unsigned low_address, unsigned high_address) -{ +void SetMACAddress(unsigned low_address, unsigned high_address) { AT91PS_EMAC pEmac = AT91C_BASE_EMAC; AT91PS_PMC pPMC = AT91C_BASE_PMC; @@ -483,12 +490,17 @@ * This global function sets the IP of the TFTP download server. * .KB_C_FN_DEFINITION_END */ -void -SetServerIPAddress(unsigned address) -{ +void SetServerIPAddress(unsigned address) { + // force update in case the IP has changed serverMACSet = 0; - serverIPAddr = address; + + serverIPAddr[0] = (address >> 24) & 0xFF; + serverIPAddr[1] = (address >> 16) & 0xFF; + serverIPAddr[2] = (address >> 8) & 0xFF; + serverIPAddr[3] = (address >> 0) & 0xFF; + + serverIPSet = 1; } @@ -498,12 +510,17 @@ * This global function sets the IP of this module. * .KB_C_FN_DEFINITION_END */ -void -SetLocalIPAddress(unsigned address) -{ +void SetLocalIPAddress(unsigned address) { + // force update in case the IP has changed serverMACSet = 0; - localIPAddr = address; + + localIPAddr[0] = (address >> 24) & 0xFF; + localIPAddr[1] = (address >> 16) & 0xFF; + localIPAddr[2] = (address >> 8) & 0xFF; + localIPAddr[3] = (address >> 0) & 0xFF; + + localIPSet = 1; } @@ -515,68 +532,71 @@ * executed. * .KB_C_FN_DEFINITION_END */ -void -TFTP_Download(unsigned address, char *filename) +void TFTP_Download(unsigned address, char *filename) { + ip_header_t IpHeader; unsigned thisSeconds, running, state; int timeout, tickUpdate; if (!address) { // report last transfer information - printf("Last tftp transfer info --\r\n" - "address: 0x%x\r\n" - " size: 0x%x\r\n", lastAddress, lastSize); + printf("\r\n -- Last tftp transfer info --\r\n" + " address: 0x%x\r\n" + " size: 0x%x\r\n", lastAddress, lastSize); return ; } - if ((!localMACSet) || (!localIPAddr) || (!serverIPAddr)) + if ((!localMACSet) || (!localIPSet) || (!serverIPSet)) return ; if (!MAC_init) { - AT91C_BASE_PMC->PMC_PCER = 1u << AT91C_ID_EMAC; + AT91C_BASE_PMC->PMC_PCER = + ((unsigned) 1 << AT91C_ID_EMAC); - AT91C_BASE_PIOA->PIO_ASR = - AT91C_PA14_ERXER | - AT91C_PA12_ERX0 | - AT91C_PA13_ERX1 | - AT91C_PA8_ETXEN | - AT91C_PA16_EMDIO | - AT91C_PA9_ETX0 | - AT91C_PA10_ETX1 | - AT91C_PA11_ECRS_ECRSDV | - AT91C_PA15_EMDC | - AT91C_PA7_ETXCK_EREFCK; + AT91C_BASE_PIOA->PIO_ASR = + ((unsigned) AT91C_PA14_ERXER ) | + ((unsigned) AT91C_PA12_ERX0 ) | + ((unsigned) AT91C_PA13_ERX1 ) | + ((unsigned) AT91C_PA8_ETXEN ) | + ((unsigned) AT91C_PA16_EMDIO ) | + ((unsigned) AT91C_PA9_ETX0 ) | + ((unsigned) AT91C_PA10_ETX1 ) | + ((unsigned) AT91C_PA11_ECRS_ECRSDV) | + ((unsigned) AT91C_PA15_EMDC ) | + ((unsigned) AT91C_PA7_ETXCK_EREFCK); AT91C_BASE_PIOA->PIO_BSR = 0; - AT91C_BASE_PIOA->PIO_PDR = - AT91C_PA14_ERXER | - AT91C_PA12_ERX0 | - AT91C_PA13_ERX1 | - AT91C_PA8_ETXEN | - AT91C_PA16_EMDIO | - AT91C_PA9_ETX0 | - AT91C_PA10_ETX1 | - AT91C_PA11_ECRS_ECRSDV | - AT91C_PA15_EMDC | - AT91C_PA7_ETXCK_EREFCK; + AT91C_BASE_PIOA->PIO_PDR = + ((unsigned) AT91C_PA14_ERXER ) | + ((unsigned) AT91C_PA12_ERX0 ) | + ((unsigned) AT91C_PA13_ERX1 ) | + ((unsigned) AT91C_PA8_ETXEN ) | + ((unsigned) AT91C_PA16_EMDIO ) | + ((unsigned) AT91C_PA9_ETX0 ) | + ((unsigned) AT91C_PA10_ETX1 ) | + ((unsigned) AT91C_PA11_ECRS_ECRSDV) | + ((unsigned) AT91C_PA15_EMDC ) | + ((unsigned) AT91C_PA7_ETXCK_EREFCK); + AT91C_BASE_PIOB->PIO_ASR = 0; AT91C_BASE_PIOB->PIO_BSR = - AT91C_PB12_ETX2 | - AT91C_PB13_ETX3 | - AT91C_PB14_ETXER | - AT91C_PB15_ERX2 | - AT91C_PB16_ERX3 | - AT91C_PB17_ERXDV | - AT91C_PB18_ECOL | - AT91C_PB19_ERXCK; + ((unsigned) AT91C_PB12_ETX2) | + ((unsigned) AT91C_PB13_ETX3) | + ((unsigned) AT91C_PB14_ETXER) | + ((unsigned) AT91C_PB15_ERX2) | + ((unsigned) AT91C_PB16_ERX3) | + ((unsigned) AT91C_PB17_ERXDV) | + ((unsigned) AT91C_PB18_ECOL) | + ((unsigned) AT91C_PB19_ERXCK); AT91C_BASE_PIOB->PIO_PDR = - AT91C_PB12_ETX2 | - AT91C_PB13_ETX3 | - AT91C_PB14_ETXER | - AT91C_PB15_ERX2 | - AT91C_PB16_ERX3 | - AT91C_PB17_ERXDV | - AT91C_PB18_ECOL | - AT91C_PB19_ERXCK; + ((unsigned) AT91C_PB12_ETX2) | + ((unsigned) AT91C_PB13_ETX3) | + ((unsigned) AT91C_PB14_ETXER) | + ((unsigned) AT91C_PB15_ERX2) | + ((unsigned) AT91C_PB16_ERX3) | + ((unsigned) AT91C_PB17_ERXDV) | + ((unsigned) AT91C_PB18_ECOL) | + ((unsigned) AT91C_PB19_ERXCK); + MAC_init = 1; } @@ -590,13 +610,13 @@ state = TFTP_WAITING_SERVER_MAC; timeout = 10; thisSeconds = GetSeconds(); - serverPort = SWAP16(69); - localPort++; /* In network byte order, but who cares */ + serverPort = 69; + ++localPort; ackBlock = -1; while (running && timeout) { - CheckForNewPacket(); + CheckForNewPacket(&IpHeader); tickUpdate = 0; @@ -652,13 +672,14 @@ * This global function initializes variables used in tftp transfers. * .KB_C_FN_DEFINITION_END */ -void -EMAC_Init(void) -{ +void EMAC_Init(void) { + p_rxBD = (receive_descriptor_t*)RX_BUFFER_START; localMACSet = 0; serverMACSet = 0; - localPort = SWAP16(0x8002); + localIPSet = 0; + serverIPSet = 0; + localPort = 0x8002; lastAddress = 0; lastSize = 0; MAC_init = 0;