⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtk8019as.c

📁 lwIP-Softools-11Jul2002-alpha
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif        ipres();        delay_uS( 500 );         //  Wait 0.5ms        // Assign ethernet address        ethif = interface->state;        *(ethif->ethaddr) = rtkEthernetAddress;    }    // Do I have an ethernet address? Complain if I don't    macOr = 0;    for (char i = 0; i < (char) sizeof interface->hwaddr; i++)    {        macOr |= interface->hwaddr[i];    }    if (!macOr)    {        puts("No MAC address (ethernet address) found or given\n");        return;    }    // This device initialization is the same for all boards / modules. The only    // thing that differs is the page addresses.    // Stop nic, change to register page 1    oute( rtkWriteAddress, 0x60 );    //  Write the ethernet address (six bytes) into the 8019as registers    for( unsigned i = 0; i < sizeof interface->hwaddr; ++i )        oute( rtkWriteAddress+1+i, interface->hwaddr[i] );    //  initialize MARx to 0 (ie: reject all multicast)    for( unsigned i = 0; i < 8; ++i )        oute( rtkWriteAddress+8+i, 0 );    //  Initialize the interface    //  Stop nic, abort remote dma, reset to register page 0    oute( rtkWriteAddress, 0x21 );    delay_uS( 1600 );                              //  Wait 1.6ms    //  Normal operation, initialize remote Dma, fifo threshhold 8 bytes    oute( rtkWriteAddress+PD_DATACFG, 0x58 );    //  Remote dma byte count = 0000h    oute( rtkWriteAddress+PD_RMTBCNT0, 0 );    oute( rtkWriteAddress+PD_RMTBCNT1, 0 );    oute( rtkWriteAddress+PD_RMTSADR0, 0 );    //  Remote dma start address = 4000h    oute( rtkWriteAddress+PD_RMTSADR1, 0x40 );    oute( rtkWriteAddress+PD_RXCFG, 0x20 );        //  Monitor mode    oute( rtkWriteAddress+PD_TXCFG, 0x02 );        //  Place NIC in loopback    //  Tx buffer < 4600h <= rx buffer    oute( rtkWriteAddress+PD_PAGESTART, 0x46 );    oute( rtkWriteAddress+PD_BOUNDARY, 0x46 );    //  Rx buffer < 8000h    oute( rtkWriteAddress+PD_PAGESTOP, PD_PAGE_STOP );    //  Clear all interrupt flags    oute( rtkWriteAddress+PD_INTSTATUS, 0xFF );    //  Disable interrupt generation    //oute( rtkWriteAddress+PD_INTMASK, 0 );    oute( rtkWriteAddress+PD_TXPAGE, 0x40 );       //  4000h < tx buffer    //  Stop nic, change to register page 1    oute( rtkWriteAddress, 0x61 );    //  Next place to rx a packet    oute( rtkWriteAddress+PD_CURRENT, 0x46 );    //  Start nic, abort remote dma    oute( rtkWriteAddress, 0x22 );    //  Change from loopback mode to normal op    oute( rtkWriteAddress+PD_TXCFG, 0 );    oute( rtkWriteAddress+PD_RXCFG, 0x04 );        //  Accept broadcast packets    //  Clear any pending interrupts    oute( rtkWriteAddress+PD_INTSTATUS, 0xFF );#ifdef DEBUG    {        char eth[20];        printf("MAC address: %s\n",               etherAddressToString(eth, interface->hwaddr));        printf("read: 0x%x write: 0x%x\n", rtkReadAddress, rtkWriteAddress);    }    printRealTekRegisters();    puts("leaving RTK8019as init\n");#endif}/** * Send a packet to the RTK8019as from a series of pbuf buffers. */int RealTekSendPacket(struct pbuf *p){    struct pbuf * q;    unsigned int packetLength = p->tot_len;    unsigned char padLength = 0;    // Weakness: multiple threads could write at the same time    ipset3();    writing = 1;    ipres();    if (packetLength < 60)    {        padLength = 60 - packetLength;        packetLength = 60;    }#ifdef TX_DEBUG    printf("<send: %d pad: %d\n", packetLength, padLength);#endif    // Semaphore is necessary here or before we get here for lwIP cases.    // Abort any dma currently active    oute( rtkWriteAddress, 0x20 );    // Wait for completion transmitting prev packet - Bit 2 set if busy    while( (char) ( ine( rtkReadAddress ) & (1 << 2) ) != 0 );    // Amount to send    oute( rtkWriteAddress+PD_RMTBCNT0, packetLength );    oute( rtkWriteAddress+PD_RMTBCNT1, packetLength >> 8 );    // Address on NIC to store    oute( rtkWriteAddress+PD_RMTSADR0, 0 );    oute( rtkWriteAddress+PD_RMTSADR1, 0x40 );    oute( rtkWriteAddress, 0x12 );                  // Write command to start    // Send the packet from the chain of buffers, one byte at a time    for (q = p; q != NULL; q = q->next)    {        unsigned char *payload = q->payload;        unsigned int i;        unsigned char j;        //for (int i = 0; i < q->len; i++)        for (i = q->len; i; i--)        {            //oute(rtkWriteAddress + PD_IOPORT, payload[i]);#ifdef TX_DEBUG            //printf("%02x", *payload);#endif            oute(rtkWriteAddress + PD_IOPORT, *payload++);        }        // Write padding for undersized packets        for (j = padLength; j; j--)        {            oute(rtkWriteAddress + PD_IOPORT, 0);        }    }    //  Wait for dma to complete - Bit 6 clear if busy    while( (char) ( ine( rtkReadAddress+PD_INTSTATUS ) & (1 << 6) ) == 0 );    //  Clear dma bit in register    oute( rtkWriteAddress+PD_INTSTATUS, 0x40 );    //  Addr in ring to transmit    oute( rtkWriteAddress+PD_TXPAGE, 0x40 );    oute( rtkWriteAddress+PD_TXBCNT0, packetLength );    //      Amount to send    oute( rtkWriteAddress+PD_TXBCNT1, packetLength >> 8 );    //  Start transmission (and shut off remote dma)    oute( rtkWriteAddress, 0x26 );#ifdef LINK_STATS    stats.link.xmit++;#endif /* LINK_STATS */      #ifdef TX_DEBUG    //printf("done transmitting packet\n");#endif    ipset3();    writing = 0;    ipres();    return ERR_OK;}/** * Read a packet into a pbuf chain. */static struct pbuf * readPacket(void){    unsigned int  packetLength;    unsigned char PDHeader[18];   // Temp storage for DMA and Ethernet headers    struct pbuf * p;    struct pbuf * q;    //  Read header    oute( rtkWriteAddress, 0x1A );           //  Start dma next packet    for( unsigned char i = 0; i < 18; i++ )    {        PDHeader[i] = ine( PD_IOPORT+rtkReadAddress );    }    //  Check for a good packet - Bit 0 set checking all but bit 5    if( ( PDHeader[0] & 0xDF ) != 1 )    {        char current;        char boundary;        boundary = ine( PD_BOUNDARY+rtkReadAddress );        if( boundary <= 0x45 || boundary > PD_PAGE_STOP)            //  Header bad, reset to 0x46            oute( rtkWriteAddress+PD_BOUNDARY, current = 0x46 );        else            //  Set boundary            current = PD_PAGE_STOP+1;        oute( rtkWriteAddress, 0x62 );           //  Page 1 + abort dma        oute( rtkWriteAddress+PD_CURRENT, current );        oute( rtkWriteAddress, 0x22 );           //  Page 0 + abort dma        return NULL;    }    //  Check for IP or ARP exception    if( PDHeader[16] != 8 || ( PDHeader[17] != 0 && PDHeader[17] != 6 ) )    {        oute( rtkWriteAddress, 0x22 );           //  Page 0 + abort dma        oute( rtkWriteAddress+PD_BOUNDARY, PDHeader[1] );   //  Delete packet        return NULL;    }    //  Store real length, set len to packet length - header    packetLength = ((unsigned) PDHeader[2] | ( PDHeader[3] << 8 ));#ifdef RX_DEBUG    //puts(">");    printf("packet length: %d\n", packetLength);#endif    // Allocate the right amount for the packet from the memory pool    p = pbuf_alloc(PBUF_LINK, packetLength, PBUF_POOL);      if (p != NULL) {        // This assumes a minimum pbuf size of 14 ... a good assumption        memcpy(p->payload, PDHeader + 4, 14);        // Iterate over the pbuf chain, reading the entire packet minus        // the header into storage.        for (q = p; q != NULL; q = q->next) {            unsigned char * payload = q->payload;            unsigned char * payload_end = payload + q->len;            // First 14 bytes are already there, skip them            if (q == p)            {                payload += 14;            }            // Fill this pbuf byte by byte in the chain.            while (payload != payload_end)            {                *payload++ = ine(PD_IOPORT + rtkReadAddress);            }        }#ifdef LINK_STATS        stats.link.recv++;#endif /* LINK_STATS */          }    else    {        // Read remainder of packet and discard        for(unsigned int i = packetLength - 14; i; --i)        {            ine(PD_IOPORT + rtkReadAddress);        }#ifdef LINK_STATS        stats.link.memerr++;        stats.link.drop++;#endif /* LINK_STATS */          }    return p;  }/** * Read a packet, clearing overflows. */struct pbuf * RealTekRecvPacket(){    char current;    char boundary;    // Don't try to read if writing is in progress.    ipset3();    if (writing)    {        ipres();        return NULL;    }    ipres();#ifdef RX_DEBUG    //printf("*");#endif    oute( rtkWriteAddress, 0x20 );          //  Select page 0    if ( ( (char) ine( rtkReadAddress+PD_INTSTATUS ) & (char) (1 << 4) ) != 0 )    {        pbuf_free(readPacket());        oute( rtkReadAddress+PD_INTSTATUS, 0x10 );  //  Clear overflow        return NULL;    }    oute( rtkWriteAddress, 0x62 );          //  Page 1 + abort dma    current = ine( rtkReadAddress+PD_CURRENT );    oute( rtkWriteAddress, 0x22 );          //  Page 0 + abort dma    boundary = ine( rtkReadAddress+PD_BOUNDARY );    //  Check for no packet    if (current == boundary)    {        //return E_Interface_NoPacket;        return NULL;    }    return readPacket();}//      Delay microseconds.//      Uses the RTC clock - waiting for 488uS periods.void delay_uS( unsigned uS ){    unsigned base;    if( uS == 0 )        return;    outi( RTC0R, 0 );                   //      Latch clock    //  Count of clock to wait (wrap is ok here)    base = ((ini( RTC1R ) << 8) | (unsigned) ini( RTC0R )) + ((uS + 487) / 488);    do  {        outi( RTC0R, 0 );    }    while( ((ini( RTC1R ) << 8) | (unsigned) ini( RTC0R )) < base );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -