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