Top secrets sources NedoPC zxusbnet

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

#include <stdio.h>
#include <string.h>
#include "w5300.h"
#include "md5.h"

static uint8 Subnet[4];

uint32 TXMEM_SIZE[MAX_SOCK_NUM];

uint32 RXMEM_SIZE[MAX_SOCK_NUM];

uint8 SOCK_INT[MAX_SOCK_NUM];


/***********************
 * Basic I/O  Function *
 ***********************/

 
uint8 IINCHIP_READ(uint16 addr)
{
 #if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)  
      return (*((uint8*)addr));
 #else
      uint8  data;  
      IINCHIP_CRITICAL_SECTION_ENTER();
      *((uint8*)IDM_AR0) = (uint8)(addr >> 8);
      *((uint8*)IDM_AR1) = (uint8)(addr & 0x00ff);
      if(addr & 0x01) data = *((uint8*)IDM_DR1);
      else data = *((uint8*)IDM_DR0);  
      IINCHIP_CRITICAL_SECTION_EXIT();
      return data;
 #endif
}
void IINCHIP_WRITE(uint16 addr, uint8 data)
{
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)  
      (*((vuint8*)addr)) = data;
#else
      IINCHIP_CRITICAL_SECTION_ENTER();
      *((vuint8*)IDM_AR0) = (uint8)(addr >> 8);
      *((vuint8*)IDM_AR1) = (uint8)(addr & 0x00ff);
      if(addr & 0x01) *((vuint8*)IDM_DR1) = data;
      else *((vuint8*)IDM_DR0) = data;
      IINCHIP_CRITICAL_SECTION_EXIT();
#endif  
}

uint16 getMR(void)
{
        uint16 ret;
        ret = *(uint8*)MR0;
        ret = (ret << 8) + *(uint8*)MR1;
        return ret;
}
void setMR(uint16 val)
{
        *(uint8*)MR0 = (uint8)((val >> 8) & 0xff);
        *(uint8*)MR1 = (uint8)(val & 0xff);
}


/***********************************
 * COMMON Register Access Function *
 ***********************************/


/* Interrupt */

uint16 getIR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(IR0);
        ret = (ret << 8) + (IINCHIP_READ(IR1));
        return ret;
}

void setIR(uint16 val)
{
        IINCHIP_WRITE(IR0, (uint8)(val >> 8));
        IINCHIP_WRITE(IR1, (uint8)(val & 0xff));  
}

uint16 getIMR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(IMR0);
        ret = (ret<<8) + IINCHIP_READ(IMR1);
  return ret;
}
void setIMR(uint16 mask)
{
        IINCHIP_WRITE(IMR0, (uint8)(mask >> 8));
        IINCHIP_WRITE(IMR1, (uint8)(mask & 0xff));
}


/* Network Information */

void getSHAR(uint8 * addr)
{
  addr[0] = (uint8)IINCHIP_READ(SHAR0);
  addr[1] = (uint8)IINCHIP_READ(SHAR1);
  addr[2] = (uint8)IINCHIP_READ(SHAR2);
  addr[3] = (uint8)IINCHIP_READ(SHAR3);
  addr[4] = (uint8)IINCHIP_READ(SHAR4);
  addr[5] = (uint8)IINCHIP_READ(SHAR5);
}
void setSHAR(uint8 * addr)
{
  IINCHIP_WRITE(SHAR0,(uint8)addr[0]);
  IINCHIP_WRITE(SHAR1,(uint8)addr[1]);
  IINCHIP_WRITE(SHAR2,(uint8)addr[2]);
  IINCHIP_WRITE(SHAR3,(uint8)addr[3]);
  IINCHIP_WRITE(SHAR4,(uint8)addr[4]);
  IINCHIP_WRITE(SHAR5,(uint8)addr[5]);
}

void getGAR(uint8 * addr)
{
  addr[0] = (uint8)(IINCHIP_READ(GAR0));
  addr[1] = (uint8)(IINCHIP_READ(GAR1));
  addr[2] = (uint8)(IINCHIP_READ(GAR2));
  addr[3] = (uint8)(IINCHIP_READ(GAR3));  
}

void setGAR(uint8 * addr)
{
  IINCHIP_WRITE(GAR0, (uint8)addr[0]);
  IINCHIP_WRITE(GAR1, (uint8)addr[1]);
  IINCHIP_WRITE(GAR2, (uint8)addr[2]);
  IINCHIP_WRITE(GAR3, (uint8)addr[3]);
}

void getSUBR(uint8 * addr)
{
        addr[0] = (uint8)Subnet[0];
        addr[1] = (uint8)Subnet[1];
        addr[2] = (uint8)Subnet[2];
        addr[3] = (uint8)Subnet[3];
}

void setSUBR(uint8 * addr)
{
        Subnet[0] = addr[0];
        Subnet[1] = addr[1];
        Subnet[2] = addr[2];
        Subnet[3] = addr[3];
}
void ApplySubnet()
{
        IINCHIP_WRITE((SUBR),Subnet[0]);
        IINCHIP_WRITE((SUBR),Subnet[1]);
        IINCHIP_WRITE((SUBR),Subnet[2]);
        IINCHIP_WRITE((SUBR),Subnet[3]);
}
void ClearSubnet()
{
        IINCHIP_WRITE((SUBR),0);
        IINCHIP_WRITE((SUBR),0);
        IINCHIP_WRITE((SUBR),0);
        IINCHIP_WRITE((SUBR),0);
}
void getSIPR(uint8 * addr)
{
  addr[0] = (uint8)(IINCHIP_READ(SIPR0));
  addr[1] = (uint8)(IINCHIP_READ(SIPR1));
  addr[2] = (uint8)(IINCHIP_READ(SIPR2));
  addr[3] = (uint8)(IINCHIP_READ(SIPR3));  
}

void setSIPR(uint8 * addr)
{
  IINCHIP_WRITE(SIPR0,(uint8)addr[0]);
  IINCHIP_WRITE(SIPR1,(uint8)addr[1]);
  IINCHIP_WRITE(SIPR2,(uint8)addr[2]);
  IINCHIP_WRITE(SIPR3,(uint8)addr[3]);
}


/* Retransmittion */

uint16 getRTR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(RTR0);
        ret = (RTR0 << 8) + IINCHIP_READ(RTR1);
  return ret;
}
void setRTR(uint16 timeout)
{
        IINCHIP_WRITE(RTR0, ((uint8)(timeout >> 8)));
        IINCHIP_WRITE(RTR1, timeout & 0xff);
}

uint8 getRCR(void)
{
  return (uint8)IINCHIP_READ(RCR1);
}

void setRCR(uint8 retry)
{
  IINCHIP_WRITE(RCR1,retry);
}

/* PPPoE */
uint16 getPATR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(PATR0);
        ret = (ret << 8) + IINCHIP_READ(PATR1);
  return ret;
}

uint8 getPTIMER(void)
{
        return (uint8)IINCHIP_READ(PTIMER1);
}
void setPTIMER(uint8 time)
{
  IINCHIP_WRITE(PTIMER1,time);
}

uint8 getPMAGICR(void)
{
  return (uint8)IINCHIP_READ(PMAGICR1);
}

void setPMAGICR(uint8 magic)
{
  IINCHIP_WRITE(PMAGICR1,magic);
}

uint16 getPSIDR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(PSIDR0);
        ret = (ret << 8) + IINCHIP_READ(PSIDR1);
        return ret;
}

void getPDHAR(uint8* addr)
{
   addr[0] = (uint8)(IINCHIP_READ(PDHAR0));
   addr[1] = (uint8)(IINCHIP_READ(PDHAR1));
   addr[2] = (uint8)(IINCHIP_READ(PDHAR2));
   addr[3] = (uint8)(IINCHIP_READ(PDHAR3));
   addr[4] = (uint8)(IINCHIP_READ(PDHAR4));
   addr[5] = (uint8)(IINCHIP_READ(PDHAR5));
}


/* ICMP packets */

void getUIPR(uint8* addr)
{
   addr[0] = (uint8)(IINCHIP_READ(UIPR0));
   addr[1] = (uint8)(IINCHIP_READ(UIPR1));
   addr[2] = (uint8)(IINCHIP_READ(UIPR2));
   addr[3] = (uint8)(IINCHIP_READ(UIPR3));  
}

uint16 getUPORTR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(UPORTR0);
        ret = (ret << 8) + IINCHIP_READ(UPORTR1);
  return ret;
}

uint16 getFMTUR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(FMTUR0);
        ret = (ret << 8) + IINCHIP_READ(FMTUR1);
  return ret;
}


/* PIN "BRYDn" */

uint8 getPn_BRDYR(uint8 p)
{
  return (uint8)IINCHIP_READ(Pn_BRDYR1(p));
}
void setPn_BRDYR(uint8 p, uint8 cfg)
{
  IINCHIP_WRITE(Pn_BRDYR1(p),cfg);  
}


uint16   getPn_BDPTHR(uint8 p)
{
  uint16 ret;
  ret = IINCHIP_READ(Pn_BDPTHR0(p));
  ret = (ret << 8) + IINCHIP_READ(Pn_BDPTHR1(p));
  return ret;  
}

void setPn_BDPTHR(uint8 p, uint16 depth)
{
        IINCHIP_WRITE(Pn_BDPTHR0(p), (uint8)(depth >> 8));
  IINCHIP_WRITE(Pn_BDPTHR1(p), (uint8)(depth & 0xff));
}


/* IINCHIP ID */
uint16 getIDR(void)
{
        uint16 ret;
        ret = IINCHIP_READ(IDR0);
        ret = (ret << 8) + IINCHIP_READ(IDR1);
  return ret;
}


/***********************************
 * SOCKET Register Access Function *
 ***********************************/


/* SOCKET control */

uint16 getSn_MR(SOCKET s)
{
        uint16 ret;
        ret = IINCHIP_READ(Sn_MR0(s));
        ret = (ret << 8) + IINCHIP_READ(Sn_MR1(s));
  return ret;
}
void setSn_MR(SOCKET s, uint16 mode)
{
        IINCHIP_WRITE(Sn_MR0(s), (uint8)(mode >> 8));
        IINCHIP_WRITE(Sn_MR1(s), (uint8)(mode & 0xff));
}

uint8 getSn_CR(SOCKET s)
{
  return IINCHIP_READ(Sn_CR1(s));
}

void setSn_CR(SOCKET s, uint8 com)
{
        IINCHIP_WRITE(Sn_CR1(s), (uint8)(com & 0xff));
  while(IINCHIP_READ(Sn_CR1(s))); // wait until Sn_CR is cleared.
}

uint8 getSn_IMR(SOCKET s)
{
  return (uint8)IINCHIP_READ(Sn_IMR1(s));
}

void setSn_IMR(SOCKET s, uint8 mask)
{
  IINCHIP_WRITE(Sn_IMR1(s),mask);
}

uint8 getSn_IR(SOCKET s)
{
#ifdef __DEF_IINCHIP_INT__    // In case of using ISR routine of iinchip
  return SOCK_INT[s];
#else                         // In case of processing directly
  return (uint8)IINCHIP_READ(Sn_IR1(s));
#endif  
}

void setSn_IR(SOCKET s, uint8 ir)
{
#ifdef __DEF_IINCHIP_INT__    // In case of using ISR routine of iinchip
  SOCK_INT[s] = SOCK_INT[s] & ~(ir);
#else                         // In case of processing directly
  IINCHIP_WRITE(Sn_IR1(s),ir);
#endif  
}


/* SOCKET information */

uint8 getSn_SSR(SOCKET s)
{
  uint8 ssr, ssr1;
  ssr = (uint8)IINCHIP_READ(Sn_SSR1(s));     // first read

  while(1)
  {
    ssr1 = (uint8)IINCHIP_READ(Sn_SSR1(s)); // second read
    if(ssr == ssr1) break;                 // if first == sencond, Sn_SSR value is valid.
    ssr = ssr1;                            // if first <> second, save second value into first.
  }
  return ssr;
}

void getSn_DHAR(SOCKET s, uint8* addr)
{
  addr[0] = (uint8)(IINCHIP_READ(Sn_DHAR0(s)));
  addr[1] = (uint8)(IINCHIP_READ(Sn_DHAR1(s)));
  addr[2] = (uint8)(IINCHIP_READ(Sn_DHAR2(s)));
  addr[3] = (uint8)(IINCHIP_READ(Sn_DHAR3(s)));
  addr[4] = (uint8)(IINCHIP_READ(Sn_DHAR4(s)));
  addr[5] = (uint8)(IINCHIP_READ(Sn_DHAR5(s)));
}

void setSn_DHAR(SOCKET s, uint8* addr)
{
  IINCHIP_WRITE(Sn_DHAR0(s), (uint8)(addr[0]));
  IINCHIP_WRITE(Sn_DHAR1(s), (uint8)(addr[1]));
  IINCHIP_WRITE(Sn_DHAR2(s), (uint8)(addr[2]));
  IINCHIP_WRITE(Sn_DHAR3(s), (uint8)(addr[3]));
  IINCHIP_WRITE(Sn_DHAR4(s), (uint8)(addr[4]));
  IINCHIP_WRITE(Sn_DHAR5(s), (uint8)(addr[5]));
}

// M_15052008 : Delete this function
//uint16   getSn_DPORTR(SOCKET s)
//{
//   return IINCHIP_READ(Sn_DPORTR(s));
//}


void setSn_DPORTR(SOCKET s, uint16 port)
{
        IINCHIP_WRITE(Sn_DPORTR0(s), (uint8)(port >>8));
        IINCHIP_WRITE(Sn_DPORTR1(s), (uint8)(port & 0xff));
}

void getSn_DIPR(SOCKET s, uint8* addr)
{
  addr[0] = (uint8)(IINCHIP_READ(Sn_DIPR0(s)));
  addr[1] = (uint8)(IINCHIP_READ(Sn_DIPR1(s)));
  addr[2] = (uint8)(IINCHIP_READ(Sn_DIPR2(s)));
        addr[3] = (uint8)(IINCHIP_READ(Sn_DIPR3(s)));
}

void setSn_DIPR(SOCKET s, uint8* addr)
{
  IINCHIP_WRITE(Sn_DIPR0(s), (uint8)addr[0]);
  IINCHIP_WRITE(Sn_DIPR1(s), (uint8)addr[1]);
  IINCHIP_WRITE(Sn_DIPR2(s), (uint8)addr[2]);
  IINCHIP_WRITE(Sn_DIPR3(s), (uint8)addr[3]);
}

uint16 getSn_MSSR(SOCKET s)
{
        uint16 ret;
        ret = IINCHIP_READ(Sn_MSSR0(s));
        ret = (ret << 8) + IINCHIP_READ(Sn_MSSR1(s));
  return ret;
}

void setSn_MSSR(SOCKET s, uint16 mss)
{
        IINCHIP_WRITE(Sn_MSSR0(s), (uint8)(mss >> 8));
        IINCHIP_WRITE(Sn_MSSR1(s), (uint8)(mss & 0xff));
}


/* SOCKET communication */

uint8 getSn_KPALVTR(SOCKET s)
{
  return IINCHIP_READ(Sn_KPALVTR(s));
}

void setSn_KPALVTR(SOCKET s, uint8 time)
{
  IINCHIP_WRITE(Sn_KPALVTR(s), time);
}

uint32 getSn_TX_WRSR(SOCKET s)
{
        uint32 ret;
        ret = IINCHIP_READ(Sn_TX_WRSR0(s));
        ret = (ret << 8) + IINCHIP_READ(Sn_TX_WRSR1(s));
        ret = (ret << 8) + IINCHIP_READ(Sn_TX_WRSR2(s));
        ret = (ret << 8) + IINCHIP_READ(Sn_TX_WRSR3(s));
        return ret;  
}
void setSn_TX_WRSR(SOCKET s, uint32 size)
{
        IINCHIP_WRITE(Sn_TX_WRSR0(s), (uint8)(size >> 24));
        IINCHIP_WRITE(Sn_TX_WRSR1(s), (uint8)(size >> 16));
        IINCHIP_WRITE(Sn_TX_WRSR2(s), (uint8)(size >> 8));
        IINCHIP_WRITE(Sn_TX_WRSR3(s), (uint8)(size & 0xff));
}

uint32 getSn_TX_FSR(SOCKET s)
{
   uint32 free_tx_size=0;
   uint32 free_tx_size1=0;
   while(1)
   {
      free_tx_size = IINCHIP_READ(Sn_TX_FSR0(s));                           // read                                      
      free_tx_size = (free_tx_size << 8) + IINCHIP_READ(Sn_TX_FSR1(s));
      free_tx_size = (free_tx_size << 8) + IINCHIP_READ(Sn_TX_FSR2(s));
      free_tx_size = (free_tx_size << 8) + IINCHIP_READ(Sn_TX_FSR3(s));
      if(free_tx_size == free_tx_size1) break;                             // if first == sencond, Sn_TX_FSR value is valid.                                                          
      free_tx_size1 = free_tx_size;                                        // save second value into first                                                  
   }                                                                      
   return free_tx_size;                                                    
}                                                                          

uint32 getSn_RX_RSR(SOCKET s)
{
   uint32 received_rx_size=0;
   uint32 received_rx_size1=1;
   while(1)
   {
      received_rx_size = IINCHIP_READ(Sn_RX_RSR0(s));
      received_rx_size = (received_rx_size << 8) + IINCHIP_READ(Sn_RX_RSR1(s)); // read
      received_rx_size = (received_rx_size << 8) + IINCHIP_READ(Sn_RX_RSR2(s));
      received_rx_size = (received_rx_size << 8) + IINCHIP_READ(Sn_RX_RSR3(s));                                      
      if(received_rx_size == received_rx_size1) break;                                                                        
      received_rx_size1 = received_rx_size;                                      // if first == sencond, Sn_RX_RSR value is valid.
   }                                                                             // save second value into first                
   return received_rx_size;  
}


void setSn_TX_FIFOR(SOCKET s, uint16 data)
{
        IINCHIP_WRITE(Sn_TX_FIFOR0(s), (uint8)(data >> 8));
        IINCHIP_WRITE(Sn_TX_FIFOR1(s), (uint8)(data & 0xff));
}

uint16 getSn_RX_FIFOR(SOCKET s)
{
        uint16 ret;
        ret = IINCHIP_READ(Sn_RX_FIFOR0(s));
        ret = (ret << 8) + IINCHIP_READ(Sn_RX_FIFOR1(s));
  return ret;
}


/* IP header field */

uint8 getSn_PROTOR(SOCKET s)
{
  return (uint8)IINCHIP_READ(Sn_PROTOR(s));
}
void setSn_PROTOR(SOCKET s, uint8 pronum)
{
  IINCHIP_WRITE(Sn_PROTOR(s), pronum);
}

uint8 getSn_TOSR(SOCKET s)
{
  return (uint8)IINCHIP_READ(Sn_TOSR1(s));
}
void setSn_TOSR(SOCKET s, uint8 tos)
{
  IINCHIP_WRITE(Sn_TOSR1(s),tos);
}

uint8 getSn_TTLR(SOCKET s)
{
  return (uint8)IINCHIP_READ(Sn_TTLR1(s));
}
void setSn_TTLR(SOCKET s, uint8 ttl)
{
  IINCHIP_WRITE(Sn_TTLR1(s),ttl);
}

uint8 getSn_FRAGR(SOCKET s)
{
  return (uint8)IINCHIP_READ(Sn_FRAGR1(s));
}

void setSn_FRAGR(SOCKET s, uint8 frag)
{
  IINCHIP_WRITE(Sn_FRAGR1(s),frag);
}


/*******
 * ETC *
 *******/


/* Initialization & Interrupt request routine */

void iinchip_init(void)
{
   *((uint8*)MR) = MR_RST;
   wait_1ms(5);
   #if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_INDIRECT_MODE__)
      *((vint8*)MR) |= MR_IND;
      #ifdef __DEF_IINCHIP_DBG__        
              printf("MR value is %04x\r\n",*((vuint16*)MR));
      #endif    
   #endif
}

//This statement is commented for using 'Doxygen'.
//#ifdef __DEF_IINCHIP_INT__
void iinchip_irq(void)
{
   uint16 int_val;
   uint16 idx;
   IINCHIP_CRITICAL_SECTION_ENTER();
   // M_01052008 : replaced '==' with '='
   //while(int_val == IINCHIP_READ(IR))  // process all interrupt    
   while((int_val = ((IINCHIP_READ(IR0) << 8) | IINCHIP_READ(IR1))))  // process all interrupt
   {          
      for(idx = 0 ; idx < MAX_SOCK_NUM ; idx++)
      {
         if (int_val & IR_SnINT(idx))  // check the SOCKETn interrupt
         {
            SOCK_INT[idx] |= (uint8)IINCHIP_READ(Sn_IR1(idx)); // Save the interrupt stauts to SOCK_INT[idx]
            IINCHIP_WRITE(Sn_IR1(idx),SOCK_INT[idx]);  // Clear the interrupt status bit of SOCKETn
         }
      }
     
      if (int_val & (IR_IPCF << 8))    // check the IP conflict interrupt
      {
         printf("IP conflict : %04x\r\n", int_val);
      }
      if (int_val & (IR_DPUR << 8))    // check the unreachable destination interrupt
      {
         printf("INT Port Unreachable : %04x\r\n", int_val);
         printf("UIPR : %d.%d.%d.%d\r\n", IINCHIP_READ(UIPR0),
                                          IINCHIP_READ(UIPR1),
                                          IINCHIP_READ(UIPR2),
                                          IINCHIP_READ(UIPR3));
         printf("UPORTR : %02x%02x\r\n", IINCHIP_READ(UPORTR0),IINCHIP_READ(UPORTR1));
      }
      IINCHIP_WRITE(IR0, (uint8)(int_val >> 8));
   }
   IINCHIP_CRITICAL_SECTION_EXIT();
}
//This statement is commented for using 'Doxygen'.
//#endif


/* Internal memory operation */
 
uint8 sysinit(uint8* tx_size, uint8* rx_size)
{
   uint16 i;
   uint16 ssum=0,rsum=0;
   uint mem_cfg = 0;
   
   for(i=0; i < MAX_SOCK_NUM; i++)
   {
      if(tx_size[i] > 64)
      {
      #ifdef __DEF_IINCHIP_DBG__
         printf("Illegal Channel(%d) TX Memory Size.\r\n",i);
      #endif
         return 0;
      }
      if(rx_size[i] > 64)
      {
      #ifdef __DEF_IINCHIP_DBG__        
         printf("Illegal Channel(%d) RX Memory Size.\r\n",i);
      #endif
         return 0;
      }
      ssum += (uint16)tx_size[i];
      rsum += (uint16)rx_size[i];
      TXMEM_SIZE[i] = ((uint32)tx_size[i]) << 10;
      RXMEM_SIZE[i] = ((uint32)rx_size[i]) << 10;
   }
   if( (ssum % 8) || ((ssum + rsum) != 128) )
   {
   #ifdef __DEF_IINCHIP_DBG__
      printf("Illegal Memory Allocation\r\n");
   #endif
      return 0;
   }
   
   IINCHIP_WRITE(TMSR0,tx_size[0]);
   IINCHIP_WRITE(TMSR1,tx_size[1]);
   IINCHIP_WRITE(TMSR2,tx_size[2]);
   IINCHIP_WRITE(TMSR3,tx_size[3]);
   IINCHIP_WRITE(TMSR4,tx_size[4]);
   IINCHIP_WRITE(TMSR5,tx_size[5]);
   IINCHIP_WRITE(TMSR6,tx_size[6]);
   IINCHIP_WRITE(TMSR7,tx_size[7]);
     
   IINCHIP_WRITE(RMSR0,rx_size[0]);
   IINCHIP_WRITE(RMSR1,rx_size[1]);
   IINCHIP_WRITE(RMSR2,rx_size[2]);
   IINCHIP_WRITE(RMSR3,rx_size[3]);
   IINCHIP_WRITE(RMSR4,rx_size[4]);
   IINCHIP_WRITE(RMSR5,rx_size[5]);
   IINCHIP_WRITE(RMSR6,rx_size[6]);
   IINCHIP_WRITE(RMSR7,rx_size[7]);
   
   for(i=0; i <ssum/8 ; i++)
   {
      mem_cfg <<= 1;
      mem_cfg |= 1;
   }
   
   IINCHIP_WRITE(MTYPER,(uint8)(mem_cfg >> 8));
   IINCHIP_WRITE(MTYPER1,(uint8)(mem_cfg & 0xff));
   
   #ifdef __DEF_IINCHIP_DBG__
      printf("Total TX Memory Size = %dKB\r\n",ssum);
      printf("Total RX Memory Size = %dKB\r\n",rsum);
      printf("Ch : TX SIZE : RECV SIZE\r\n");
      printf("%02d : %07dKB : %07dKB \r\n", 0, IINCHIP_READ(TMSR0),IINCHIP_READ(RMSR0));
      printf("%02d : %07dKB : %07dKB \r\n", 1, IINCHIP_READ(TMSR1),IINCHIP_READ(RMSR1));
      printf("%02d : %07dKB : %07dKB \r\n", 2, IINCHIP_READ(TMSR2),IINCHIP_READ(RMSR2));
      printf("%02d : %07dKB : %07dKB \r\n", 3, IINCHIP_READ(TMSR3),IINCHIP_READ(RMSR3));
      printf("%02d : %07dKB : %07dKB \r\n", 4, IINCHIP_READ(TMSR4),IINCHIP_READ(RMSR4));
      printf("%02d : %07dKB : %07dKB \r\n", 5, IINCHIP_READ(TMSR5),IINCHIP_READ(RMSR5));
      printf("%02d : %07dKB : %07dKB \r\n", 6, IINCHIP_READ(TMSR6),IINCHIP_READ(RMSR6));
      printf("%02d : %07dKB : %07dKB \r\n", 7, IINCHIP_READ(TMSR7),IINCHIP_READ(RMSR7));
      printf("\r\nMTYPER=%02x%02x\r\n",IINCHIP_READ(MTYPER0),IINCHIP_READ(MTYPER1));
   #endif
   
   return 1;
}

uint32 wiz_write_buf(SOCKET s,uint8* buf,uint32 len)
{
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)
   #if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__)
      uint32 idx=0;
      // M_08082008
      IINCHIP_CRITICAL_SECTION_ENTER();
      for (idx = 0; idx < len; idx+=2)
      {
                                        *((vuint8*)Sn_TX_FIFOR0(s)) = *(buf+idx);
                                        *((vuint8*)Sn_TX_FIFOR1(s)) = *(buf+idx+1);
                        }
      // M_08082008
      IINCHIP_CRITICAL_SECTION_EXIT();
   #elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
      #error "You should do implement this block."
   #endif
#elif (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_INDIRECT_MODE__)
   #if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__) */
      uint32 idx=0;
      IINCHIP_CRITICAL_SECTION_ENTER();
      *((vuint8*)IDM_AR0) = Sn_TX_FIFOR0(s);
      *((vuint8*)IDM_AR1) = Sn_TX_FIFOR1(s);
      for (idx = 0; idx < len; idx+=2)
      {
          *((vuint8*)IDM_DR0) = *((uint8*)(buf+idx));
          *((vuint8*)IDM_DR1) = *((uint8*)(buf+idx+1));
      }
      IINCHIP_CRITICAL_SECTION_EXIT();
   #elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
      #error "You should do implement this block."
   #else
      #error "Undefined __DEF_IINCHIP_BUF_OP__"
   #endif
#else
   #error "Undefined __DEF_IINCHIP_ADDRESS_MODE__"  
#endif
    return len;  
}

uint32 wiz_read_buf(SOCKET s, uint8* buf,uint32 len)
{
#if (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_DIRECT_MODE__)
   #if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__)
      uint32 idx;
      // M_08082008
      IINCHIP_CRITICAL_SECTION_ENTER();
      for (idx = 0; idx < len; idx+=2)
      {
                                *(buf+idx) = *((vuint8*)Sn_RX_FIFOR0(s));
                                *(buf+idx+1) = *((vuint8*)Sn_RX_FIFOR1(s));
                        }
      // M_08082008  
      IINCHIP_CRITICAL_SECTION_EXIT();
   #elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
      #error "You should do implement this block."
   #else
      #error "Undefined __DEF_IINCHIP_BUF_OP__"
   #endif
#elif (__DEF_IINCHIP_ADDRESS_MODE__ == __DEF_IINCHIP_INDIRECT_MODE__)
   #if (__DEF_IINCHIP_BUF_OP__ == __DEF_C__) */
      uint32 idx=0;
      IINCHIP_CRITICAL_SECTION_ENTER();
      *((vuint8*)IDM_AR0) = Sn_RX_FIFOR0(s);
      *((vuint8*)IDM_AR1) = Sn_RX_FIFOR1(s);
      for (idx = 0; idx < len; idx+=2)
      {
         *((uint8*)(buf+idx)) = *((vuint8*)IDM_DR0);
         *((uint8*)(buf+idx+1)) = *((vuint8*)IDM_DR1);
      }
      IINCHIP_CRITICAL_SECTION_EXIT();
   #elif (__DEF_IINCHIP_BUF_OP__ == __DEF_MCU_DEP_DMA__)
      #error "You should do implement this block."
   #else
      #error "Undefined __DEF_IINCHIP_BUF_OP__"
   #endif
#else
   #error "Undefined __DEF_IINCHIP_ADDRESS_MODE__"  
#endif
    return len;
}


uint32 getIINCHIP_TxMAX(SOCKET s)
{
  return TXMEM_SIZE[s];
}

uint32 getIINCHIP_RxMAX(SOCKET s)
{
  return RXMEM_SIZE[s];
}


// This statement is commented for using 'Doxygen'.
//#ifdef __DEF_IINCHIP_PPP__

#define PPP_OPTION_BUF_LEN 64

uint8 pppinit_in(uint8 * id, uint8 idlen, uint8 * passwd, uint8 passwdlen)
{
  uint8 loop_idx = 0;
  uint8 isr = 0;
  uint8 buf[PPP_OPTION_BUF_LEN];
  uint32 len;
  uint8 str[PPP_OPTION_BUF_LEN];
  uint8 str_idx,dst_idx;
   
  // PHASE1. PPPoE Discovery //
  // start to connect pppoe connection
  printf("-- PHASE 1. PPPoE Discovery process --");
  printf(" ok\r\n");
  printf("\r\n");
  setSn_CR(0,Sn_CR_PCON);
  wait_10ms(100);
   
  // check if PPPoE discovery phase is success or not
  loop_idx = 0;
  while (!(getSn_IR(0) & Sn_IR_PNEXT))
  {
     printf(".");
     if (loop_idx++ == 10) // timeout
     {
        printf("timeout before LCP\r\n");
        return 3;
     }
     wait_10ms(100);
  }
  setSn_IR(0,Sn_IR_PNEXT);
   
  // PHASE2. LCP process //
  printf("-- PHASE 2. LCP process --");
  {
     // Magic number option
     // option format (type value + length value + data)
     // write magic number value
     buf[0] = 0x05; // type value
     buf[1] = 0x06; // length value
     buf[2] = 0x01; buf[3] = 0x01; buf[4] = 0x01; buf[5]= 0x01; // data
     // for MRU option, 1492 0x05d4  
     // buf[6] = 0x01; buf[7] = 0x04; buf[8] = 0x05; buf[9] = 0xD4;
  }
  wiz_write_buf(0,buf, 0x06);
  setSn_TX_WRSR(0,0x06);
  setSn_CR(0,Sn_CR_PCR); // send LCP request to PPPoE server
  wait_10ms(100);
 
  while (!((isr = getSn_IR(0)) & Sn_IR_PNEXT))
  {
     if (isr & Sn_IR_PRECV)     // Not support option
     {
        len = getSn_RX_RSR(0);
        if ( len > 2 )
        {
           wiz_read_buf(0,str, 2);
           len = ((uint16)str[0] << 8) + str[1];
           wiz_read_buf(0,(str+2), len);
           setSn_CR(0,Sn_CR_RECV);
           // get option length
           len = (uint32)str[4]; len = ((len & 0xff) << 8) + (uint32)str[5];
           len += 2;
           str_idx = 6; dst_idx = 0; // PPP header is 6 byte, so starts at 6.
           do
           {
              if ((str[str_idx] == 0x01) || (str[str_idx] == 0x02) || (str[str_idx] == 0x03) || (str[str_idx] == 0x05))
              {
                 // skip as length of support option. str_idx+1 is option's length.
                 str_idx += str[str_idx+1];
              }
              else
              {
                 // not support option , REJECT
                 memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
                 dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
              }
           } while (str_idx != len);
       
           // send LCP REJECT packet
           wiz_write_buf(0,buf, dst_idx);
           setSn_TX_WRSR(0,dst_idx);
           setSn_CR(0,Sn_CR_PCJ);
           setSn_IR(0,Sn_IR_PRECV);
        }
     }
     printf(".");
     if (loop_idx++ == 10) // timeout
     {
        printf("timeout after LCP\r\n");
        return 3;
     }
     wait_10ms(100);
  }
  setSn_IR(0,Sn_IR_PNEXT);
  printf(" ok\r\n");
  printf("\r\n");
 
  // PHASE 3. PPPoE Authentication //
  printf("-- PHASE 3. PPPoE Authentication mode --\r\n");
  printf("Authentication protocol : %04x, ", getPATR());
  loop_idx = 0;
  if (getPATR() == 0xC023)         // PAP type
  {
     printf("PAP\r\n"); // in case of adsl normally supports PAP.
     // send authentication data
     // copy (idlen + id + passwdlen + passwd)
     buf[loop_idx] = idlen; loop_idx++;
     memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen;
     buf[loop_idx] = passwdlen; loop_idx++;
     memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen;
     wiz_write_buf(0,buf, loop_idx);
     setSn_TX_WRSR(0,loop_idx);
     setSn_CR(0,Sn_CR_PCR);
     wait_10ms(100);
  }
  else if (getPATR() == 0xC223)    // CHAP type
  {
     uint8 chal_len;
     md5_ctx context;
     uint8  digest[16];
     
     len = getSn_RX_RSR(0);
     if ( len > 2 )
     {
        wiz_read_buf(0,str,2);
        len = ((uint32)str[0] << 8) + (uint32)str[1];
        wiz_read_buf(0, str, len);
        setSn_CR(0,Sn_CR_RECV);
        #ifdef __DEF_IINCHIP_DBG__
        {
           int16 i;
           printf("recv CHAP\r\n");
           for (i = 0; i < 32; i++) printf ("%02X ", str[i]);
           printf("\r\n");
        }
        #endif
        // str is C2 23 xx CHAL_ID xx xx CHAP_LEN CHAP_DATA
        // index  0  1  2  3       4  5  6        7 ...
       
        memset(buf,0x00,64);
        buf[loop_idx] = str[3]; loop_idx++; // chal_id
        memcpy((uint8 *)(buf+loop_idx), (uint8 *)(passwd), passwdlen); loop_idx += passwdlen; //passwd
        chal_len = str[6]; // chal_id
        memcpy((uint8 *)(buf+loop_idx), (uint8 *)(str+7), chal_len); loop_idx += chal_len; //challenge
        buf[loop_idx] = 0x80;
        #ifdef __DEF_IINCHIP_DBG__
        {
           int16 i;
           printf("CHAP proc d1\r\n");
           
           for (i = 0; i < 64; i++) printf ("%02X ", buf[i]);
           printf("\r\n");
        }
        #endif
       
        md5_init(&context);
        md5_update(&context, buf, loop_idx);
        md5_final(digest, &context);
       
        #ifdef __DEF_IINCHIP_DBG__
        {
           uint i;
           printf("CHAP proc d1\r\n");
           for (i = 0; i < 16; i++) printf ("%02X", digest[i]);
           printf("\r\n");
        }
        #endif
        loop_idx = 0;
        buf[loop_idx] = 16; loop_idx++; // hash_len
        memcpy((uint8 *)(buf+loop_idx), (uint8 *)(digest), 16); loop_idx += 16; // hashed value
        memcpy((uint8 *)(buf+loop_idx), (uint8 *)(id), idlen); loop_idx += idlen; // id
        wiz_write_buf(0,buf, loop_idx);
        setSn_TX_WRSR(0,loop_idx);
        setSn_CR(0,Sn_CR_PCR);
        wait_10ms(100);
     }
  }
  else
  {
     printf("Not support\r\n");
     #ifdef __DEF_IINCHIP_DBG__
        printf("Not support PPP Auth type: %.4x\r\n",getPATR());
     #endif
     return 4;
  }
  printf("\r\n");
 
  printf("-- Waiting for PPPoE server's admission --");
  loop_idx = 0;
  while (!((isr = getSn_IR(0)) & Sn_IR_PNEXT))
  {
     if (isr & Sn_IR_PFAIL)
     {
        printf("failed\r\nReinput id, password..\r\n");
        return 2;
     }
     printf(".");
     if (loop_idx++ == 10) // timeout
     {
        printf("timeout after PAP\r\n");
        return 3;
     }
     wait_10ms(100);
  }
  setSn_IR(0,Sn_IR_PNEXT);
  printf("ok\r\n");
  printf("\r\n");
 
  // PHASE 4. IPCP process //
  printf("-- PHASE 4. IPCP process --");
  // IP Address
  buf[0] = 0x03; buf[1] = 0x06; buf[2] = 0x00; buf[3] = 0x00; buf[4] = 0x00; buf[5] = 0x00;
  wiz_write_buf(0,buf, 6);
  setSn_TX_WRSR(0,6);
  setSn_CR(0,Sn_CR_PCR);
  wait_10ms(100);
 
  loop_idx = 0;
  while (1)
  {
     if (getSn_IR(0) & Sn_IR_PRECV)
     {
        len = getSn_RX_RSR(0);
        if ( len > 2 )
        {
           wiz_read_buf(0,str,2);
           len = ((uint32)str[0] << 8) + (uint32)str[1];
           wiz_read_buf(0, str, len);
           setSn_CR(0,Sn_CR_RECV);
           str_idx = 6; dst_idx = 0;
           if (str[2] == 0x03) // in case of NAK
           {
              do
              {
                 if (str[str_idx] == 0x03) // request only ip information
                 {
                    memcpy((uint8 *)(buf+dst_idx), (uint8 *)(str+str_idx), str[str_idx+1]);
                    dst_idx += str[str_idx+1]; str_idx += str[str_idx+1];
                 }
                 else
                 {
                    // skip byte
                    str_idx += str[str_idx+1];
                 }
                 // for debug
                 //printf("s: %d, d: %d, l: %d", str_idx, dst_idx, len);
              } while (str_idx != len);
              wiz_write_buf(0,buf, dst_idx);
              setSn_TX_WRSR(0,dst_idx);
              setSn_CR(0,Sn_CR_PCR); // send ipcp request
              wait_10ms(100);
              break;
           }
        }
        setSn_IR(0,Sn_IR_PRECV);
     }
     printf(".");
     if (loop_idx++ == 10) // timeout
     {
        printf("timeout after IPCP\r\n");
        return 3;
     }
     wait_10ms(100);
     wiz_write_buf(0, buf, 6);
     setSn_TX_WRSR(0,6);
     setSn_CR(0,Sn_CR_PCR); //ipcp re-request
  }
 
  loop_idx = 0;
  while (!(getSn_IR(0) & Sn_IR_PNEXT))
  {
     printf(".");
     if (loop_idx++ == 10) // timeout
     {
        printf("timeout after IPCP NAK\r\n");
        return 3;
     }
     wait_10ms(100);
     setSn_CR(0,Sn_CR_PCR); // send ipcp request
  }
  setSn_IR(0,Sn_IR_PNEXT);
  printf("ok\r\n");
  printf("\r\n");
  return 1;
  // after this function, the pppoe server's mac address and pppoe session id is saved in PHAR and PSIDR repectly.
}

uint8 pppinit(uint8 *id, uint8 idlen, uint8 *passwd, uint8 passwdlen)
{
        uint8 ret;
        uint8 isr;
       
        // PHASE0. PPPoE setup

        printf("-- PHASE 0. PPPoE setup process --\r\n");
        printf("\r\n");
        setMR(getMR()|MR_PPPoE);                     // set PPPoE mode
        setMR(getMR()|MR_FS);                        // If little-endian, set MR_FS. Otherwise, comment.

        isr =  getSn_IR(0);
        setSn_IR(0,isr);                     // clear the previous value of Sn_IR(0)  
       
        setPTIMER(200);                              // set LPC request time to 5 seconds
        setPMAGICR(0x01);                            // set the magic number
        setSn_MR(0, Sn_MR_PPPoE);                    // set Sn_MR(0) to PPPoE mode
        setSn_CR(0,Sn_CR_OPEN);                      //open SOCKET0 with PPPoE mode                      
       
        ret = pppinit_in(id, idlen, passwd, passwdlen); // process the PPPoE message

        setSn_CR(0, Sn_CR_CLOSE);                       // close PPPoE SOCKET0

        return ret;  
}
   
void  pppterm(uint8 *mac, uint16 sessionid)
{
   uint8 isr;
   #ifdef __DEF_IINCHIP_DBG__
      printf("pppterm()\r\n");
   #endif
   
   // set PPPoE mode
   setMR(getMR() | MR_PPPoE);                
   
   // set pppoe server's mac address and session id
   // must be setted these value.
   setSn_DHAR(0, mac);
   setSn_DPORTR(0,sessionid);

   // clear the previous value of Sn_IR(0)
        isr =  getSn_IR(0);
        setSn_IR(0,isr);                  
   
   //open SOCKET0 with PPPoE mode
        setSn_MR(0, Sn_MR_PPPoE);                    
        setSn_CR(0,Sn_CR_OPEN);                      
   while(getSn_SSR(0) != SOCK_PPPoE)            
   
   // close PPPoE connection
   setSn_CR(0,Sn_CR_PDISCON);
   wait_10ms(100);
   // close socket
   setSn_CR(0,Sn_CR_CLOSE);
   
   #ifdef __DEF_IINCHIP_DBG__
      printf("pppterm() end ..\r\n");
   #endif
}
// This statement is commented for using 'Doxygen'.
//#endif


void wait_1us(uint32 us)
{
   uint32 i,j;
   for(i = 0; i < us ; i++)
   {
      for(j = 0; j < 100; j++);
   }
}

void wait_1ms(uint32 ms)
{
   uint32 i;
   for(i = 0; i < ms ; i++)
   {
     wait_1us(1000);
   }
   
}

void wait_10ms(uint32 ms)
{
   uint32 i;
   for(i = 0; i < ms ; i++)
   {
     wait_1ms(10);
   }
}