1161196Simp/******************************************************************************* 2157873Simp * 3157873Simp * Filename: emac.c 4157873Simp * 5157873Simp * Instantiation of routines for MAC/ethernet functions supporting tftp. 6157873Simp * 7157873Simp * Revision information: 8157873Simp * 9157873Simp * 28AUG2004 kb_admin initial creation 10157873Simp * 08JAN2005 kb_admin added tftp download 11157873Simp * also adapted from external sources 12157873Simp * 13157873Simp * BEGIN_KBDD_BLOCK 14157873Simp * No warranty, expressed or implied, is included with this software. It is 15157873Simp * provided "AS IS" and no warranty of any kind including statutory or aspects 16157873Simp * relating to merchantability or fitness for any purpose is provided. All 17157873Simp * intellectual property rights of others is maintained with the respective 18157873Simp * owners. This software is not copyrighted and is intended for reference 19157873Simp * only. 20157873Simp * END_BLOCK 21161196Simp * 22157873Simp * $FreeBSD$ 23161196Simp ******************************************************************************/ 24157873Simp 25157873Simp#include "at91rm9200.h" 26161196Simp#include "at91rm9200_lowlevel.h" 27157873Simp#include "emac.h" 28157873Simp#include "lib.h" 29157873Simp 30161196Simp/* ****************************** GLOBALS *************************************/ 31157873Simp 32161196Simp/* ********************** PRIVATE FUNCTIONS/DATA ******************************/ 33157873Simp 34163533Simpstatic receive_descriptor_t *p_rxBD; 35163533Simpstatic unsigned short localPort; 36163533Simpstatic unsigned short serverPort; 37163533Simpstatic unsigned serverMACSet; 38163533Simpstatic unsigned localIPSet, serverIPSet; 39163533Simpstatic unsigned lastSize; 40163533Simpstatic unsigned char serverMACAddr[6]; 41161196Simpstatic unsigned char localIPAddr[4], serverIPAddr[4]; 42157873Simpstatic int ackBlock; 43157873Simpstatic char *dlAddress; 44157873Simp 45157873Simpstatic unsigned transmitBuffer[1024 / sizeof(unsigned)]; 46157873Simpstatic unsigned tftpSendPacket[256 / sizeof(unsigned)]; 47157873Simp 48157873Simp/* 49157873Simp * .KB_C_FN_DEFINITION_START 50157873Simp * unsigned short IP_checksum(unsigned short *p, int len) 51157873Simp * This private function calculates the IP checksum for various headers. 52157873Simp * .KB_C_FN_DEFINITION_END 53157873Simp */ 54157873Simpstatic unsigned short 55161196SimpIP_checksum(unsigned short *p, int len) 56157873Simp{ 57157873Simp unsigned i, t; 58157873Simp 59157873Simp len &= ~1; 60161196Simp 61157873Simp for (i=0,t=0; i<len; i+=2, ++p) 62157873Simp t += SWAP16(*p); 63161196Simp 64157873Simp t = (t & 0xffff) + (t >> 16); 65161196Simp return (~t); 66157873Simp} 67157873Simp 68157873Simp 69157873Simp/* 70157873Simp * .KB_C_FN_DEFINITION_START 71157873Simp * void GetServerAddress(void) 72157873Simp * This private function sends an ARP request to determine the server MAC. 73157873Simp * .KB_C_FN_DEFINITION_END 74157873Simp */ 75157873Simpstatic void 76157873SimpGetServerAddress(void) 77157873Simp{ 78157873Simp arp_header_t *p_ARP; 79157873Simp 80157873Simp p_ARP = (arp_header_t*)transmitBuffer; 81161196Simp 82157873Simp p_memset((char*)p_ARP->dest_mac, 0xFF, 6); 83161196Simp 84163533Simp memcpy(p_ARP->src_mac, localMACAddr, 6); 85157873Simp 86157873Simp p_ARP->frame_type = SWAP16(PROTOCOL_ARP); 87157873Simp p_ARP->hard_type = SWAP16(1); 88157873Simp p_ARP->prot_type = SWAP16(PROTOCOL_IP); 89157873Simp p_ARP->hard_size = 6; 90157873Simp p_ARP->prot_size = 4; 91157873Simp p_ARP->operation = SWAP16(ARP_REQUEST); 92157873Simp 93163533Simp memcpy(p_ARP->sender_mac, localMACAddr, 6); 94163533Simp memcpy(p_ARP->sender_ip, localIPAddr, 4); 95157873Simp p_memset((char*)p_ARP->target_mac, 0, 6); 96163533Simp memcpy(p_ARP->target_ip, serverIPAddr, 4); 97161196Simp 98157873Simp // wait until transmit is available 99157873Simp while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) ; 100157873Simp 101157873Simp *AT91C_EMAC_TSR |= AT91C_EMAC_COMP; 102157873Simp *AT91C_EMAC_TAR = (unsigned)transmitBuffer; 103157873Simp *AT91C_EMAC_TCR = 0x40; 104157873Simp} 105157873Simp 106157873Simp 107157873Simp/* 108157873Simp * .KB_C_FN_DEFINITION_START 109157873Simp * void Send_TFTP_Packet(char *tftpData, unsigned tftpLength) 110157873Simp * This private function initializes and send a TFTP packet. 111157873Simp * .KB_C_FN_DEFINITION_END 112157873Simp */ 113157873Simpstatic void 114157873SimpSend_TFTP_Packet(char *tftpData, unsigned tftpLength) 115157873Simp{ 116157873Simp transmit_header_t *macHdr = (transmit_header_t*)tftpSendPacket; 117157873Simp ip_header_t *ipHdr; 118157873Simp udp_header_t *udpHdr; 119157873Simp unsigned t_checksum; 120157873Simp 121163533Simp memcpy(macHdr->dest_mac, serverMACAddr, 6); 122163533Simp memcpy(macHdr->src_mac, localMACAddr, 6); 123157873Simp macHdr->proto_mac = SWAP16(PROTOCOL_IP); 124157873Simp 125161196Simp ipHdr = (ip_header_t*)&macHdr->packet_length; 126157873Simp 127157873Simp ipHdr->ip_v_hl = 0x45; 128157873Simp ipHdr->ip_tos = 0; 129157873Simp ipHdr->ip_len = SWAP16(28 + tftpLength); 130157873Simp ipHdr->ip_id = 0; 131157873Simp ipHdr->ip_off = SWAP16(0x4000); 132157873Simp ipHdr->ip_ttl = 64; 133157873Simp ipHdr->ip_p = PROTOCOL_UDP; 134157873Simp ipHdr->ip_sum = 0; 135157873Simp 136163533Simp memcpy(ipHdr->ip_src, localIPAddr, 4); 137163533Simp memcpy(ipHdr->ip_dst, serverIPAddr, 4); 138161196Simp 139161196Simp ipHdr->ip_sum = SWAP16(IP_checksum((unsigned short*)ipHdr, 20)); 140157873Simp 141157873Simp udpHdr = (udp_header_t*)(ipHdr + 1); 142157873Simp 143157873Simp udpHdr->src_port = localPort; 144157873Simp udpHdr->dst_port = serverPort; 145157873Simp udpHdr->udp_len = SWAP16(8 + tftpLength); 146157873Simp udpHdr->udp_cksum = 0; 147157873Simp 148163533Simp memcpy((char *)udpHdr+8, tftpData, tftpLength); 149157873Simp 150161196Simp t_checksum = IP_checksum((unsigned short*)ipHdr + 6, (16 + tftpLength)); 151157873Simp 152157873Simp t_checksum = (~t_checksum) & 0xFFFF; 153157873Simp t_checksum += 25 + tftpLength; 154157873Simp 155157873Simp t_checksum = (t_checksum & 0xffff) + (t_checksum >> 16); 156157873Simp t_checksum = (~t_checksum) & 0xFFFF; 157157873Simp 158157873Simp udpHdr->udp_cksum = SWAP16(t_checksum); 159157873Simp 160157873Simp while (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) ; 161157873Simp 162157873Simp *AT91C_EMAC_TSR |= AT91C_EMAC_COMP; 163157873Simp *AT91C_EMAC_TAR = (unsigned)tftpSendPacket; 164157873Simp *AT91C_EMAC_TCR = 42 + tftpLength; 165157873Simp} 166157873Simp 167157873Simp 168157873Simp/* 169157873Simp * .KB_C_FN_DEFINITION_START 170157873Simp * void TFTP_RequestFile(char *filename) 171157873Simp * This private function sends a RRQ packet to the server. 172157873Simp * .KB_C_FN_DEFINITION_END 173157873Simp */ 174157873Simpstatic void 175157873SimpTFTP_RequestFile(char *filename) 176157873Simp{ 177157873Simp tftp_header_t tftpHeader; 178157873Simp char *cPtr, *ePtr, *mPtr; 179157873Simp unsigned length; 180157873Simp 181161196Simp tftpHeader.opcode = TFTP_RRQ_OPCODE; 182157873Simp 183157873Simp cPtr = (char*)&(tftpHeader.block_num); 184157873Simp 185163533Simp ePtr = strcpy(cPtr, filename); 186163533Simp mPtr = strcpy(ePtr, "octet"); 187157873Simp 188157873Simp length = mPtr - cPtr; 189157873Simp length += 2; 190157873Simp 191157873Simp Send_TFTP_Packet((char*)&tftpHeader, length); 192157873Simp} 193157873Simp 194157873Simp 195157873Simp/* 196157873Simp * .KB_C_FN_DEFINITION_START 197157873Simp * void TFTP_ACK_Data(char *data, unsigned short block_num, unsigned short len) 198157873Simp * This private function sends an ACK packet to the server. 199157873Simp * .KB_C_FN_DEFINITION_END 200157873Simp */ 201157873Simpstatic void 202172991ScognetTFTP_ACK_Data(unsigned char *data, unsigned short block_num, unsigned short len) 203157873Simp{ 204157873Simp tftp_header_t tftpHeader; 205157873Simp 206161196Simp if (block_num == (ackBlock + 1)) { 207157873Simp ++ackBlock; 208163533Simp memcpy(dlAddress, data, len); 209157873Simp dlAddress += len; 210157873Simp lastSize += len; 211161196Simp if (ackBlock % 128 == 0) 212161196Simp printf("tftp: %u kB\r", lastSize / 1024); 213157873Simp } 214161196Simp tftpHeader.opcode = TFTP_ACK_OPCODE; 215161196Simp tftpHeader.block_num = SWAP16(ackBlock); 216157873Simp Send_TFTP_Packet((char*)&tftpHeader, 4); 217161196Simp if (len < 512) { 218157873Simp ackBlock = -2; 219163533Simp printf("tftp: %u byte\n", lastSize); 220161196Simp } 221157873Simp} 222157873Simp 223157873Simp 224157873Simp/* 225157873Simp * .KB_C_FN_DEFINITION_START 226157873Simp * void CheckForNewPacket(ip_header_t *pHeader) 227157873Simp * This private function polls for received ethernet packets and handles 228157873Simp * any here. 229157873Simp * .KB_C_FN_DEFINITION_END 230157873Simp */ 231161196Simpstatic int 232161196SimpCheckForNewPacket(ip_header_t *pHeader) 233157873Simp{ 234157873Simp unsigned short *pFrameType; 235157873Simp unsigned i; 236157873Simp char *pData; 237157873Simp ip_header_t *pIpHeader; 238157873Simp arp_header_t *p_ARP; 239157873Simp int process = 0; 240157873Simp 241157873Simp process = 0; 242157873Simp for (i = 0; i < MAX_RX_PACKETS; ++i) { 243157873Simp if(p_rxBD[i].address & 0x1) { 244157873Simp process = 1; 245157873Simp (*AT91C_EMAC_RSR) |= (*AT91C_EMAC_RSR); 246157873Simp break; 247157873Simp } 248157873Simp } 249157873Simp 250157873Simp if (!process) 251161196Simp return (0); 252157873Simp process = i; 253157873Simp 254161196Simp pFrameType = (unsigned short *)((p_rxBD[i].address & 0xFFFFFFFC) + 12); 255157873Simp pData = (char *)(p_rxBD[i].address & 0xFFFFFFFC); 256157873Simp 257161196Simp switch (*pFrameType) { 258157873Simp 259161196Simp case SWAP16(PROTOCOL_ARP): 260157873Simp p_ARP = (arp_header_t*)pData; 261161196Simp if (p_ARP->operation == SWAP16(ARP_REPLY)) { 262157873Simp // check if new server info is available 263157873Simp if ((!serverMACSet) && 264157873Simp (!(p_memcmp((char*)p_ARP->sender_ip, 265157873Simp (char*)serverIPAddr, 4)))) { 266157873Simp 267157873Simp serverMACSet = 1; 268163533Simp memcpy(serverMACAddr, p_ARP->sender_mac, 6); 269157873Simp } 270161196Simp } else if (p_ARP->operation == SWAP16(ARP_REQUEST)) { 271157873Simp // ARP REPLY operation 272157873Simp p_ARP->operation = SWAP16(ARP_REPLY); 273157873Simp 274161196Simp // Fill the dest address and src address 275161196Simp for (i = 0; i <6; i++) { 276161196Simp // swap ethernet dest address and ethernet src address 277161196Simp pData[i] = pData[i+6]; 278161196Simp pData[i+6] = localMACAddr[i]; 279161196Simp // swap sender ethernet address and target ethernet address 280161196Simp pData[i+22] = localMACAddr[i]; 281161196Simp pData[i+32] = pData[i+6]; 282161196Simp } 283157873Simp 284161196Simp // swap sender IP address and target IP address 285161196Simp for (i = 0; i<4; i++) { 286161196Simp pData[i+38] = pData[i+28]; 287161196Simp pData[i+28] = localIPAddr[i]; 288161196Simp } 289157873Simp 290161196Simp if (!(*AT91C_EMAC_TSR & AT91C_EMAC_BNQ)) break; 291161196Simp 292157873Simp *AT91C_EMAC_TSR |= AT91C_EMAC_COMP; 293157873Simp *AT91C_EMAC_TAR = (unsigned)pData; 294157873Simp *AT91C_EMAC_TCR = 0x40; 295157873Simp } 296161196Simp break; 297161196Simp case SWAP16(PROTOCOL_IP): 298161196Simp pIpHeader = (ip_header_t*)(pData + 14); 299163533Simp memcpy(pHeader, pIpHeader, sizeof(ip_header_t)); 300157873Simp 301161196Simp if (pIpHeader->ip_p == PROTOCOL_UDP) { 302157873Simp udp_header_t *udpHdr; 303157873Simp tftp_header_t *tftpHdr; 304157873Simp 305157873Simp udpHdr = (udp_header_t*)((char*)pIpHeader+20); 306157873Simp tftpHdr = (tftp_header_t*)((char*)udpHdr + 8); 307157873Simp 308157873Simp if (udpHdr->dst_port != localPort) 309157873Simp break; 310157873Simp 311161196Simp if (tftpHdr->opcode != TFTP_DATA_OPCODE) 312157873Simp break; 313157873Simp 314157873Simp if (ackBlock == -1) { 315157873Simp if (tftpHdr->block_num != SWAP16(1)) 316161196Simp break; 317161196Simp serverPort = udpHdr->src_port; 318161196Simp ackBlock = 0; 319161196Simp } 320157873Simp 321157873Simp if (serverPort != udpHdr->src_port) 322157873Simp break; 323157873Simp 324157873Simp TFTP_ACK_Data(tftpHdr->data, 325161196Simp SWAP16(tftpHdr->block_num), 326161196Simp SWAP16(udpHdr->udp_len) - 12); 327157873Simp } 328157873Simp } 329157873Simp p_rxBD[process].address &= ~0x01; 330161196Simp return (1); 331157873Simp} 332157873Simp 333157873Simp 334157873Simp/* 335157873Simp * .KB_C_FN_DEFINITION_START 336157873Simp * unsigned short AT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr) 337157873Simp * This private function reads the PHY device. 338157873Simp * .KB_C_FN_DEFINITION_END 339157873Simp */ 340165401Simp#ifndef BOOT_BWCT 341157873Simpstatic unsigned short 342157873SimpAT91F_MII_ReadPhy (AT91PS_EMAC pEmac, unsigned char addr) 343157873Simp{ 344157873Simp unsigned value = 0x60020000 | (addr << 18); 345157873Simp 346157873Simp pEmac->EMAC_CTL |= AT91C_EMAC_MPE; 347157873Simp pEmac->EMAC_MAN = value; 348157873Simp while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE)); 349157873Simp pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE; 350157873Simp return (pEmac->EMAC_MAN & 0x0000ffff); 351157873Simp} 352165401Simp#endif 353157873Simp 354161196Simp/* 355161196Simp * .KB_C_FN_DEFINITION_START 356165401Simp * unsigned short AT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s) 357165401Simp * This private function writes the PHY device. 358161196Simp * .KB_C_FN_DEFINITION_END 359161196Simp */ 360161196Simp#ifdef BOOT_TSC 361161196Simpstatic unsigned short 362161196SimpAT91F_MII_WritePhy (AT91PS_EMAC pEmac, unsigned char addr, unsigned short s) 363161196Simp{ 364161196Simp unsigned value = 0x50020000 | (addr << 18) | s; 365157873Simp 366161196Simp pEmac->EMAC_CTL |= AT91C_EMAC_MPE; 367161196Simp pEmac->EMAC_MAN = value; 368161196Simp while(!((pEmac->EMAC_SR) & AT91C_EMAC_IDLE)); 369161196Simp pEmac->EMAC_CTL &= ~AT91C_EMAC_MPE; 370161196Simp return (pEmac->EMAC_MAN & 0x0000ffff); 371161196Simp} 372161196Simp#endif 373161196Simp 374157873Simp/* 375157873Simp * .KB_C_FN_DEFINITION_START 376157873Simp * void MII_GetLinkSpeed(AT91PS_EMAC pEmac) 377157873Simp * This private function determines the link speed set by the PHY. 378157873Simp * .KB_C_FN_DEFINITION_END 379157873Simp */ 380157873Simpstatic void 381157873SimpMII_GetLinkSpeed(AT91PS_EMAC pEmac) 382157873Simp{ 383171426Simp#if defined(BOOT_TSC) || defined(BOOT_KB920X) || defined(BOOT_CENTIPAD) 384161196Simp unsigned short stat2; 385165401Simp#endif 386161196Simp unsigned update; 387161196Simp#ifdef BOOT_TSC 388161196Simp unsigned sec; 389161196Simp int i; 390161196Simp#endif 391165401Simp#ifdef BOOT_BWCT 392165401Simp /* hardcoded link speed since we connect a switch via MII */ 393165401Simp update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); 394165401Simp update |= AT91C_EMAC_SPD; 395165401Simp update |= AT91C_EMAC_FD; 396165401Simp#endif 397171426Simp#if defined(BOOT_KB920X) || defined(BOOT_CENTIPAD) 398157873Simp stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS2_REG); 399161196Simp if (!(stat2 & MII_STS2_LINK)) 400157873Simp return ; 401161196Simp update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); 402161196Simp if (stat2 & MII_STS2_100TX) 403157873Simp update |= AT91C_EMAC_SPD; 404161196Simp if (stat2 & MII_STS2_FDX) 405161196Simp update |= AT91C_EMAC_FD; 406161196Simp#endif 407161196Simp#ifdef BOOT_TSC 408161196Simp while (1) { 409161196Simp for (i = 0; i < 10; i++) { 410161196Simp stat2 = AT91F_MII_ReadPhy(pEmac, MII_STS_REG); 411161196Simp if (stat2 & MII_STS_LINK_STAT) 412161196Simp break; 413161196Simp printf("."); 414161196Simp sec = GetSeconds(); 415168013Simp while (GetSeconds() == sec) 416168013Simp continue; 417157873Simp } 418161196Simp if (stat2 & MII_STS_LINK_STAT) 419161196Simp break; 420161196Simp printf("Resetting MII..."); 421161196Simp AT91F_MII_WritePhy(pEmac, 0x0, 0x8000); 422161196Simp while (AT91F_MII_ReadPhy(pEmac, 0x0) & 0x8000) continue; 423161196Simp } 424161196Simp printf("emac: link"); 425161196Simp stat2 = AT91F_MII_ReadPhy(pEmac, MII_SPEC_STS_REG); 426161196Simp update = pEmac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD); 427161196Simp if (stat2 & (MII_SSTS_100FDX | MII_SSTS_100HDX)) { 428161196Simp printf(" 100TX"); 429161196Simp update |= AT91C_EMAC_SPD; 430161196Simp } 431161196Simp if (stat2 & (MII_SSTS_100FDX | MII_SSTS_10FDX)) { 432161196Simp printf(" FDX"); 433157873Simp update |= AT91C_EMAC_FD; 434157873Simp } 435163533Simp printf("\n"); 436161196Simp#endif 437161196Simp pEmac->EMAC_CFG = update; 438157873Simp} 439157873Simp 440157873Simp 441157873Simp/* 442157873Simp * .KB_C_FN_DEFINITION_START 443157873Simp * void AT91F_EmacEntry(void) 444157873Simp * This private function initializes the EMAC on the chip. 445157873Simp * .KB_C_FN_DEFINITION_END 446157873Simp */ 447157873Simpstatic void 448157873SimpAT91F_EmacEntry(void) 449157873Simp{ 450157873Simp unsigned i; 451157873Simp char *pRxPacket = (char*)RX_DATA_START; 452157873Simp AT91PS_EMAC pEmac = AT91C_BASE_EMAC; 453157873Simp 454163533Simp p_rxBD = (receive_descriptor_t*)RX_BUFFER_START; 455163533Simp localPort = SWAP16(0x8002); 456163533Simp 457157873Simp for (i = 0; i < MAX_RX_PACKETS; ++i) { 458161196Simp 459157873Simp p_rxBD[i].address = (unsigned)pRxPacket; 460157873Simp p_rxBD[i].size = 0; 461157873Simp pRxPacket += RX_PACKET_SIZE; 462157873Simp } 463157873Simp 464157873Simp // Set the WRAP bit at the end of the list descriptor 465157873Simp p_rxBD[MAX_RX_PACKETS-1].address |= 0x02; 466157873Simp 467161196Simp if (!(pEmac->EMAC_SR & AT91C_EMAC_LINK)) 468157873Simp MII_GetLinkSpeed(pEmac); 469157873Simp 470157873Simp pEmac->EMAC_RBQP = (unsigned) p_rxBD; 471157873Simp pEmac->EMAC_RSR |= (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA); 472161196Simp pEmac->EMAC_CTL = AT91C_EMAC_TE | AT91C_EMAC_RE; 473157873Simp 474157873Simp pEmac->EMAC_TAR = (unsigned)transmitBuffer; 475157873Simp} 476157873Simp 477157873Simp 478157873Simp/* ************************** GLOBAL FUNCTIONS ********************************/ 479157873Simp 480157873Simp/* 481157873Simp * .KB_C_FN_DEFINITION_START 482157873Simp * void SetServerIPAddress(unsigned address) 483157873Simp * This global function sets the IP of the TFTP download server. 484157873Simp * .KB_C_FN_DEFINITION_END 485157873Simp */ 486157873Simpvoid 487157873SimpSetServerIPAddress(unsigned address) 488157873Simp{ 489157873Simp // force update in case the IP has changed 490157873Simp serverMACSet = 0; 491161196Simp 492161196Simp serverIPAddr[0] = (address >> 24) & 0xFF; 493161196Simp serverIPAddr[1] = (address >> 16) & 0xFF; 494161196Simp serverIPAddr[2] = (address >> 8) & 0xFF; 495161196Simp serverIPAddr[3] = (address >> 0) & 0xFF; 496161196Simp 497161196Simp serverIPSet = 1; 498157873Simp} 499157873Simp 500157873Simp 501157873Simp/* 502157873Simp * .KB_C_FN_DEFINITION_START 503157873Simp * void SetLocalIPAddress(unsigned address) 504157873Simp * This global function sets the IP of this module. 505157873Simp * .KB_C_FN_DEFINITION_END 506157873Simp */ 507157873Simpvoid 508157873SimpSetLocalIPAddress(unsigned address) 509157873Simp{ 510157873Simp // force update in case the IP has changed 511157873Simp serverMACSet = 0; 512161196Simp 513161196Simp localIPAddr[0] = (address >> 24) & 0xFF; 514161196Simp localIPAddr[1] = (address >> 16) & 0xFF; 515161196Simp localIPAddr[2] = (address >> 8) & 0xFF; 516161196Simp localIPAddr[3] = (address >> 0) & 0xFF; 517161196Simp 518161196Simp localIPSet = 1; 519157873Simp} 520157873Simp 521157873Simp 522157873Simp/* 523157873Simp * .KB_C_FN_DEFINITION_START 524157873Simp * void TFTP_Download(unsigned address, char *filename) 525157873Simp * This global function initiates and processes a tftp download request. 526157873Simp * The server IP, local IP, local MAC must be set before this function is 527157873Simp * executed. 528157873Simp * .KB_C_FN_DEFINITION_END 529157873Simp */ 530157873Simpvoid 531157873SimpTFTP_Download(unsigned address, char *filename) 532157873Simp{ 533161196Simp ip_header_t IpHeader; 534161196Simp unsigned thisSeconds; 535161196Simp int timeout; 536157873Simp 537161196Simp if ((!localMACSet) || (!localIPSet) || (!serverIPSet)) 538157873Simp return ; 539157873Simp 540157873Simp AT91F_EmacEntry(); 541157873Simp GetServerAddress(); 542157873Simp dlAddress = (char*)address; 543157873Simp lastSize = 0; 544157873Simp timeout = 10; 545168013Simp thisSeconds = (GetSeconds() + 2) % 32; 546157873Simp serverPort = SWAP16(69); 547161196Simp ++localPort; 548157873Simp ackBlock = -1; 549157873Simp 550161196Simp while (timeout) { 551161196Simp if (CheckForNewPacket(&IpHeader)) { 552161196Simp if (ackBlock == -2) 553161196Simp break; 554161196Simp timeout = 10; 555168013Simp thisSeconds = (GetSeconds() + 2) % 32; 556168013Simp } else if (GetSeconds() == thisSeconds) { 557157873Simp --timeout; 558168013Simp thisSeconds = (GetSeconds() + 2) % 32; 559161196Simp if (!serverMACSet) 560161196Simp GetServerAddress(); 561161196Simp else if (ackBlock == -1) 562161196Simp TFTP_RequestFile(filename); 563161196Simp else { 564161196Simp // Be sure to send a NAK, which is done by 565161196Simp // ACKing the last block we got. 566161196Simp TFTP_ACK_Data(0, ackBlock, 512); 567163533Simp printf("\nNAK %u\n", ackBlock); 568161196Simp } 569157873Simp } 570157873Simp } 571161196Simp if (timeout == 0) 572163533Simp printf("TFTP TIMEOUT!\n"); 573157873Simp} 574