00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include <board.h>
00104 #include <string.h>
00105
00106 #include "MiniIp.h"
00107
00108
00109
00110
00111
00112 #define TX_BUFFERS 32
00113 #define RX_BUFFERS 32
00114
00115 #define BUFFER_SIZE 1536
00116 #define DUMMY_SIZE 2
00117 #define DUMMY_BUFF_SIZE 128
00118
00119
00120 #define GMAC_RCV_OFFSET 0
00121
00122
00123 #define GMAC_CAF_DISABLE 0
00124 #define GMAC_CAF_ENABLE 1
00125
00126
00127 #define GMAC_NBC_DISABLE 0
00128 #define GMAC_NBC_ENABLE 1
00129
00130
00131
00132 #define GMAX_ARP_REQUEST 100
00133 #define GMIN_ARP_REPLY 90
00134
00135
00136 #define GMAX_TRY_LINK 500
00137
00138
00139
00140
00141
00142
00143 #if !defined(BOARD_GMAC_POWER_ALWAYS_ON)
00144 static const Pin gmacPwrDn[] = {BOARD_GMAC_PIN_PWRDN};
00145 #endif
00146
00147
00148 static const Pin gmacPins[] = {BOARD_GMAC_RUN_PINS};
00149 static const Pin gmacResetPin = BOARD_GMAC_RESET_PIN;
00150
00151
00152 static uint8_t GMacAddress[6] = {0x3a, 0x1f, 0x34, 0x08, 0x54, 0x54};
00153
00154
00155 static uint8_t GIpAddress[4] = {192, 168, 1, 3 };
00156 static uint8_t GDesIpAddress[4] = {192, 168, 1, 2 };
00157
00158
00159 static sGmacd gGmacd;
00160
00161
00162 static GMacb gGmacb;
00163
00164
00165 COMPILER_SECTION(".ram_nocache")
00166 COMPILER_ALIGNED(8) static sGmacTxDescriptor gTxDs[TX_BUFFERS], gDummyTxDs[DUMMY_SIZE];
00167
00168
00169
00170 COMPILER_ALIGNED(8) static fGmacdTransferCallback gTxCbs[TX_BUFFERS],
00171 gDummyTxCbs[DUMMY_SIZE];
00172
00173
00174 COMPILER_SECTION(".ram_nocache")
00175 COMPILER_ALIGNED(8) static sGmacRxDescriptor gRxDs[RX_BUFFERS],
00176 gDummyRxDs[DUMMY_SIZE];
00177
00178
00179
00180
00181
00182 COMPILER_ALIGNED(8) static uint8_t pTxBuffer[TX_BUFFERS * BUFFER_SIZE],
00183 pTxDummyBuffer[DUMMY_SIZE*DUMMY_BUFF_SIZE];
00184
00185
00186 COMPILER_ALIGNED(8) static uint8_t pRxBuffer[RX_BUFFERS * BUFFER_SIZE],
00187 pRxDummyBuffer[DUMMY_SIZE*DUMMY_BUFF_SIZE];
00188
00189
00190 static uint8_t GEthBuffer[BUFFER_SIZE*TX_BUFFERS*2];
00191
00192 static uint8_t gbIsIpAddrInit = 1;
00193 static uint8_t gtotal_request;
00194 static uint8_t gtotal_reply;
00195
00196
00197
00198
00199
00200
00201
00202 void GMAC_Handler(void)
00203 {
00204 GMACD_Handler(&gGmacd, GMAC_QUE_0);
00205 }
00206
00207
00208
00209
00210 static void GDisplayEthernetHeader(PEthHeader pEth, uint32_t size)
00211 {
00212 printf("======= Ethernet %4u bytes, HEADER ==========\n\r",
00213 (unsigned int)size);
00214 printf(" @Mac dst = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00215 pEth->et_dest[0], pEth->et_dest[1], pEth->et_dest[2],
00216 pEth->et_dest[3], pEth->et_dest[4], pEth->et_dest[5]);
00217 printf(" @Mac src = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00218 pEth->et_src[0], pEth->et_src[1], pEth->et_src[2],
00219 pEth->et_src[3], pEth->et_src[4], pEth->et_src[5]);
00220 printf(" Protocol = %d\n\r", pEth->et_protlen);
00221 }
00222
00223 static void GDisplayArpHeader(PArpHeader pArp, uint32_t size)
00224 {
00225 printf("======= ARP %4u bytes, HEADER ==========\n\r", (unsigned int)size);
00226 printf(" Hardware type = %d\n\r", SWAP16(pArp->ar_hrd) );
00227 printf(" protocol type = 0x%04x\n\r", SWAP16(pArp->ar_pro) );
00228 printf(" Hardware addr lg = %d\n\r", pArp->ar_hln);
00229 printf(" Protocol addr lg = %d\n\r", pArp->ar_pln);
00230 printf(" Operation = %d\n\r", SWAP16(pArp->ar_op) );
00231 printf(" Sender hardware addr = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00232 pArp->ar_sha[0], pArp->ar_sha[1], pArp->ar_sha[2],
00233 pArp->ar_sha[3], pArp->ar_sha[4], pArp->ar_sha[5]);
00234 printf(" Sender protocol addr = %d.%d.%d.%d\n\r",
00235 pArp->ar_spa[0],pArp->ar_spa[1],pArp->ar_spa[2],pArp->ar_spa[3]);
00236 printf(" Target hardware addr = %02x.%02x.%02x.%02x.%02x.%02x\n\r",
00237 pArp->ar_tha[0], pArp->ar_tha[1], pArp->ar_tha[2],
00238 pArp->ar_tha[3], pArp->ar_tha[4], pArp->ar_tha[5]);
00239 printf(" Target protocol addr = %d.%d.%d.%d\n\r",
00240 pArp->ar_tpa[0],pArp->ar_tpa[1],pArp->ar_tpa[2],pArp->ar_tpa[3]);
00241 }
00242
00243 static void GDisplayIpHeader(PIpHeader pIpHeader, uint32_t size)
00244 {
00245 printf("======= IP %4u bytes, HEADER ==========\n\r", (unsigned int) size);
00246 printf(" IP Version = v.%d\n\r",(pIpHeader->ip_hl_v & 0xF0) >> 4);
00247 printf(" Header Length = %d\n\r", pIpHeader->ip_hl_v & 0x0F);
00248 printf(" Type of service = 0x%x\n\r", pIpHeader->ip_tos);
00249 printf(" Total IP Length = 0x%X\n\r",
00250 (((pIpHeader->ip_len)>>8)&0xff) + (((pIpHeader->ip_len)<<8)&0xff00) );
00251 printf(" ID = 0x%X\n\r",
00252 (((pIpHeader->ip_id)>>8)&0xff) + (((pIpHeader->ip_id)<<8)&0xff00) );
00253 printf(" Header Checksum = 0x%X\n\r",
00254 (((pIpHeader->ip_sum)>>8)&0xff) + (((pIpHeader->ip_sum)<<8)&0xff00) );
00255 printf(" Protocol = ");
00256
00257 switch(pIpHeader->ip_p) {
00258 case IP_PROT_ICMP:
00259 printf( "ICMP\n\r");
00260 break;
00261
00262 case IP_PROT_IP:
00263 printf( "IP\n\r");
00264 break;
00265
00266 case IP_PROT_TCP:
00267 printf("TCP\n\r");
00268 break;
00269
00270 case IP_PROT_UDP:
00271 printf("UDP\n\r");
00272 break;
00273
00274 default:
00275 printf( "%d (0x%X)\n\r", pIpHeader->ip_p, pIpHeader->ip_p);
00276 break;
00277 }
00278
00279 printf( " IP Src Address = %d:%d:%d:%d\n\r",
00280 pIpHeader->ip_src[0],
00281 pIpHeader->ip_src[1],
00282 pIpHeader->ip_src[2],
00283 pIpHeader->ip_src[3]);
00284
00285 printf( " IP Dest Address = %d:%d:%d:%d\n\r",
00286 pIpHeader->ip_dst[0],
00287 pIpHeader->ip_dst[1],
00288 pIpHeader->ip_dst[2],
00289 pIpHeader->ip_dst[3]);
00290 printf("----------------------------------------\n\r");
00291 }
00292
00293
00294
00295
00296 static void garp_init_ip_addr(uint8_t* pData)
00297 {
00298 uint32_t i;
00299 PArpHeader pArp = (PArpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00300
00301 if (SWAP16(pArp->ar_op) == ARP_REQUEST) {
00302
00303 if(gbIsIpAddrInit == 0) {
00304
00305 printf("first arp request, Check @ip. src=%d.%d.%d.%d dst=%d.%d.%d.%d ",
00306 pArp->ar_spa[0], pArp->ar_spa[1], pArp->ar_spa[2], pArp->ar_spa[3],
00307 pArp->ar_tpa[0], pArp->ar_tpa[1], pArp->ar_tpa[2], pArp->ar_tpa[3]);
00308
00309 if( (pArp->ar_tpa[0] == pArp->ar_spa[0]) &&
00310 (pArp->ar_tpa[1] == pArp->ar_spa[1]) &&
00311 (pArp->ar_tpa[2] == pArp->ar_spa[2]) &&
00312 (pArp->ar_tpa[3] >= 250) &&
00313 (pArp->ar_tpa[3] <= 254) ) {
00314 for (i = 0; i<4; i++) {
00315 GIpAddress[i] = pArp->ar_tpa[i];
00316 }
00317
00318 printf("=> OK\n\r");
00319 gbIsIpAddrInit = 1;
00320
00321 } else {
00322 printf("=> KO!\n\r");
00323 }
00324 }
00325 }
00326 }
00327
00328
00329
00330 static void garp_request(uint8_t* pData)
00331 {
00332 uint32_t i;
00333 uint8_t gmac_rc = GMACD_OK;
00334
00335 PEthHeader pEth = (PEthHeader)(pData + GMAC_RCV_OFFSET);
00336 PArpHeader pArp = (PArpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00337
00338 pEth->et_protlen = SWAP16(ETH_PROT_ARP);
00339
00340 pArp->ar_hrd = SWAP16(0x0001);
00341 pArp->ar_pro = SWAP16(ETH_PROT_IP);
00342 pArp->ar_hln = 6;
00343 pArp->ar_pln = 4;
00344 pArp->ar_op = SWAP16(ARP_REQUEST);
00345
00346
00347 for (i = 0; i <6; i++) {
00348
00349 pEth->et_dest[i] = 0xff;
00350 pEth->et_src[i] = GMacAddress[i];
00351 pArp->ar_tha[i] = 0x00;
00352 pArp->ar_sha[i] = GMacAddress[i];
00353 }
00354
00355 for (i = 0; i<4; i++) {
00356 pArp->ar_tpa[i] = GDesIpAddress[i];
00357 pArp->ar_spa[i] = GIpAddress[i];
00358 }
00359 gmac_rc = GMACD_Send(&gGmacd,
00360 (pData + GMAC_RCV_OFFSET),
00361 42,
00362 NULL, GMAC_QUE_0);
00363
00364 if (gmac_rc != GMACD_OK) {
00365 printf("-E- ARP_REQUEST Send - 0x%x\n\r", gmac_rc);
00366 }
00367 }
00368
00369
00370
00371
00372 static void garp_process_packet(uint8_t* pData, uint32_t size)
00373 {
00374 uint32_t i,j;
00375 uint8_t gmac_rc = GMACD_OK;
00376
00377 PEthHeader pEth = (PEthHeader)pData;
00378 PArpHeader pArp = (PArpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00379
00380 if (SWAP16(pArp->ar_op) == ARP_REQUEST) {
00381
00382
00383 pArp->ar_op = SWAP16(ARP_REPLY);
00384
00385
00386 for (i = 0; i < 6; i++) {
00387
00388 pEth->et_dest[i] = pEth->et_src[i];
00389 pEth->et_src[i] = GMacAddress[i];
00390 pArp->ar_tha[i] = pArp->ar_sha[i];
00391 pArp->ar_sha[i] = GMacAddress[i];
00392 }
00393
00394 for (i = 0; i<4; i++) {
00395 pArp->ar_tpa[i] = pArp->ar_spa[i];
00396 pArp->ar_spa[i] = GIpAddress[i];
00397 }
00398
00399 gmac_rc = GMACD_Send(&gGmacd,
00400 (pData + GMAC_RCV_OFFSET),
00401 size,
00402 NULL, GMAC_QUE_0);
00403
00404 if (gmac_rc != GMACD_OK) {
00405 printf("-E- ARP Send - 0x%x\n\r", gmac_rc);
00406 }
00407 }
00408
00409 if (SWAP16(pArp->ar_op) == ARP_REPLY) {
00410
00411 for (i = 0,j = 0; i<4; i++) {
00412 if(pArp->ar_tpa[i] != GIpAddress[i]){j++;break;}
00413 if(pArp->ar_spa[i] != GDesIpAddress[i]){j++;break;}
00414 }
00415 if(!j){
00416 gtotal_reply++;
00417 }
00418 }
00419 }
00420
00421
00422
00423
00424 static void gip_process_packet(uint8_t* pData)
00425 {
00426 uint32_t i;
00427 uint32_t icmp_len;
00428 uint32_t gmac_rc = GMACD_OK;
00429
00430 PEthHeader pEth = (PEthHeader)pData;
00431 PIpHeader pIpHeader = (PIpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00432
00433 PIcmpEchoHeader pIcmpEcho = (PIcmpEchoHeader)((char *)pIpHeader + 20);
00434
00435 switch(pIpHeader->ip_p) {
00436
00437 case IP_PROT_ICMP:
00438
00439 if(pIcmpEcho->type == ICMP_ECHO_REQUEST) {
00440 pIcmpEcho->type = ICMP_ECHO_REPLY;
00441 pIcmpEcho->code = 0;
00442 pIcmpEcho->cksum = 0;
00443
00444
00445 icmp_len = (SWAP16(pIpHeader->ip_len) - 20);
00446 if (icmp_len % 2) {
00447 *((uint8_t *)pIcmpEcho + icmp_len) = 0;
00448 icmp_len ++;
00449 }
00450 icmp_len = icmp_len / sizeof(unsigned short);
00451
00452 pIcmpEcho->cksum =
00453 SWAP16(IcmpChksum((unsigned short *) pIcmpEcho, icmp_len));
00454
00455 for(i = 0; i <4; i++) {
00456 GIpAddress[i] = pIpHeader->ip_dst[i];
00457 pIpHeader->ip_dst[i] = pIpHeader->ip_src[i];
00458 pIpHeader->ip_src[i] = GIpAddress[i];
00459 }
00460
00461 for(i = 0; i <6; i++) {
00462
00463
00464
00465 pEth->et_dest[i] = pEth->et_src[i];
00466 pEth->et_src[i] = GMacAddress[i];
00467 }
00468
00469
00470 gmac_rc = GMACD_Send(&gGmacd,
00471 (pData + GMAC_RCV_OFFSET),
00472 SWAP16(pIpHeader->ip_len) + 14 + GMAC_RCV_OFFSET,
00473 NULL, GMAC_QUE_0);
00474
00475 if (gmac_rc != GMACD_OK) {
00476 printf("-E- ICMP Send - 0x%x\n\r", (unsigned int) gmac_rc);
00477 }
00478 }
00479 break;
00480
00481 default:
00482 break;
00483 }
00484 }
00485
00486
00487
00488
00489
00490 static void geth_process_packet(uint8_t* pData, uint32_t size)
00491 {
00492 uint16_t pkt_format;
00493
00494 PEthHeader pEth = (PEthHeader)(pData + GMAC_RCV_OFFSET);
00495 PIpHeader pIpHeader = (PIpHeader)(pData + 14 + GMAC_RCV_OFFSET);
00496 IpHeader ipHeader;
00497
00498 pkt_format = SWAP16(pEth->et_protlen);
00499 switch (pkt_format) {
00500
00501 case ETH_PROT_ARP:
00502
00503
00504 GDisplayEthernetHeader(pEth, size);
00505 GDisplayArpHeader( (PArpHeader)(pData + 14 + GMAC_RCV_OFFSET), size);
00506
00507
00508 garp_init_ip_addr(pData);
00509
00510
00511 if(gbIsIpAddrInit == 0) return;
00512 garp_process_packet(pData, size);
00513
00514
00515 break;
00516
00517 case ETH_PROT_IP:
00518
00519 if(gbIsIpAddrInit == 0) return;
00520
00521
00522 memcpy(&ipHeader, pIpHeader,sizeof(IpHeader));
00523
00524
00525 gip_process_packet(pData);
00526
00527
00528 GDisplayIpHeader(&ipHeader, size);
00529 break;
00530 default:
00531 break;
00532 }
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 int main(void)
00546 {
00547 sGmacd *pGmacd = &gGmacd;
00548 GMacb *pGmacb = &gGmacb;
00549 uint32_t frmSize;
00550 uint32_t delay;
00551 sGmacInit Que0, Que;
00552
00553
00554 WDT_Disable( WDT ) ;
00555
00556
00557 SCB_EnableICache();
00558 SCB_EnableDCache();
00559
00560 printf("-- GMAC Example %s --\n\r", SOFTPACK_VERSION);
00561 printf("-- %s\n\r", BOARD_NAME);
00562 printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00563
00564
00565 TimeTick_Configure ();
00566
00567
00568 printf("-- MAC %x:%x:%x:%x:%x:%x\n\r",
00569 GMacAddress[0], GMacAddress[1], GMacAddress[2],
00570 GMacAddress[3], GMacAddress[4], GMacAddress[5]);
00571 printf("-- EK`s IP %d.%d.%d.%d\n\r",
00572 GIpAddress[0], GIpAddress[1], GIpAddress[2], GIpAddress[3]);
00573 printf("-- PC`s IP %d.%d.%d.%d\n\r",
00574 GDesIpAddress[0], GDesIpAddress[1], GDesIpAddress[2], GDesIpAddress[3]);
00575
00576 printf("Connect the board to a host PC via an ethernet cable\n\r");
00577
00578
00579 memset(&Que0, 0, sizeof(Que0));
00580 Que0.bIsGem = 1;
00581 Que0.bDmaBurstLength = 4;
00582 Que0.pRxBuffer =pRxBuffer;
00583 Que0.pRxD = gRxDs;
00584 Que0.wRxBufferSize = BUFFER_SIZE;
00585 Que0.wRxSize = RX_BUFFERS;
00586 Que0.pTxBuffer = pTxBuffer;
00587 Que0.pTxD = gTxDs;
00588 Que0.wTxBufferSize = BUFFER_SIZE;
00589 Que0.wTxSize = TX_BUFFERS;
00590 Que0.pTxCb = gTxCbs;
00591
00592
00593
00594 memset(&Que, 0, sizeof(Que));
00595 Que.bIsGem = 1;
00596 Que.bDmaBurstLength = 4;
00597 Que.pRxBuffer =pRxDummyBuffer;
00598 Que.pRxD = gDummyRxDs;
00599 Que.wRxBufferSize = DUMMY_BUFF_SIZE;
00600 Que.wRxSize = DUMMY_SIZE;
00601 Que.pTxBuffer = pTxDummyBuffer;
00602 Que.pTxD = gDummyTxDs;
00603 Que.wTxBufferSize = DUMMY_BUFF_SIZE;
00604 Que.wTxSize = DUMMY_SIZE;
00605 Que.pTxCb = gDummyTxCbs;
00606
00607 GMACD_Init(pGmacd, GMAC, ID_GMAC, GMAC_CAF_ENABLE, GMAC_NBC_DISABLE);
00608 GMACD_InitTransfer(pGmacd, &Que, GMAC_QUE_2);
00609 GMACD_InitTransfer(pGmacd, &Que, GMAC_QUE_1);
00610 GMACD_InitTransfer(pGmacd, &Que0, GMAC_QUE_0);
00611 GMAC_SetAddress(gGmacd.pHw, 0, GMacAddress);
00612
00613
00614
00615 NVIC_ClearPendingIRQ(GMAC_IRQn);
00616 NVIC_EnableIRQ(GMAC_IRQn);
00617
00618 GMACB_Init(pGmacb,pGmacd, BOARD_GMAC_PHY_ADDR);
00619 GMACB_ResetPhy(pGmacb);
00620
00621
00622 if (!GMACB_InitPhy(pGmacb, BOARD_MCK, &gmacResetPin, 1, gmacPins,
00623 PIO_LISTSIZE(gmacPins))) {
00624 printf("PHY Initialize ERROR!\n\r");
00625 return 0;
00626 }
00627 printf("GMACB_AutoNegotiate\n\r");
00628 if (!GMACB_AutoNegotiate(pGmacb)) {
00629 printf("Auto Negotiate ERROR!\n\r");
00630 return 0;
00631 }
00632
00633 delay = 0;
00634 gtotal_request = 0;
00635 gtotal_reply = 0;
00636 while(1) {
00637 if(gtotal_request >= GMAX_ARP_REQUEST)break;
00638
00639 if((delay++)>=(BOARD_MCK/1000000)){
00640 delay=0;
00641 gtotal_request++;
00642 printf("arp... \n\r");
00643 garp_request(GEthBuffer);
00644 }
00645
00646
00647 if( GMACD_OK != GMACD_Poll(pGmacd, GEthBuffer, sizeof(GEthBuffer),
00648 &frmSize, GMAC_QUE_0) ) {
00649 continue;
00650 }
00651
00652 if (frmSize > 0) {
00653
00654 printf("Process_packet ...\n\r");
00655 geth_process_packet(GEthBuffer, frmSize);
00656 }
00657 }
00658
00659
00660 NVIC_DisableIRQ(GMAC_IRQn);
00661
00662 printf("EK sends out %d ARP request and gets %d reply\n\r",
00663 gtotal_request,gtotal_reply);
00664 while(1);
00665 }