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

📄 adam.c

📁 altera epxa1的例子程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            // move onto the next
            eth->tx_desc_done = *(volatile ULONG *)(eth->tx_desc_done + 0x00);
        }
        else return 1;  // busy
    }
    return 0;
}






int eth_receive(type_eth_descriptors *eth, rx_callback_proc rx_callback, void *context)
{
	int err;
	int i;

	ULONG next;
	ULONG stat;
	ULONG ctl;
    int buffer_count;
    ULONG rptr;
    int rlen;
    int rlen1;
    ULONG rbuf1;
	int rerror;



    readtimeus();
    err = 0;
    // check the rx Q
    if (!((*(volatile ULONG *)(eth->rx_fda_desc+0x0c)) & 0x80000000))
    {
// if q nearly full - do a pause ...
// how do we know how far the controller has got ???
// .. just check the own bit of the rx_fda_desc at the required threshold
// this is a bad way - just chase up the fda descriptor list, counting how far
// behind we are - if the q is nearly full do a pause.

    	ULONG own;
	    int count;
    	ULONG fda;

        // race up the fda q
        fda = eth->rx_fda_desc;
        count = 0;
        own = 0;
        while(!own && (count < 0x200))
        {
            own = (*(volatile ULONG *)(fda+0x0c)) & 0x80000000;
            fda = *(volatile ULONG *)(fda+0x00);
            count++;
        }

        // if not yet freed, then we're getting full
        // we have ~0x200 descs
        if ((count > 0x1c0))
        {
            eth_pause(eth, 16000);    // 200 = ~ 1ms
        }



        next = *(volatile ULONG *)(eth->rx_fda_desc+0x00);
        ctl  = (*(volatile ULONG *)(eth->rx_fda_desc+0x0c) >> 16) & 0x1f;

        // if the rx packet is spread across several buffers
        buffer_count = ((*(volatile ULONG *)(eth->rx_fda_desc+0x0c)) >> 16) & 0x1f;

        if (buffer_count == 1)
        {
            rptr = (*(volatile ULONG *)(eth->rx_fda_desc+0x10+(0*0x8)));
            rlen = (*(volatile ULONG *)(eth->rx_fda_desc+0x14+(0*0x8))) & 0xffff;
        }
        else
        {
            // if the rx packet its fragmented
            // copy the rxpacket into a single buffer

            rbuf1 = (ULONG)rbuf;
            rlen = 0;
            for (i=0; i<buffer_count; i++)
            {
                rptr = (*(volatile ULONG *)(eth->rx_fda_desc+0x10+(i*0x8)));
                rlen1 = (*(volatile ULONG *)(eth->rx_fda_desc+0x14+(i*0x8))) & 0xffff;

                memcpy((UCHAR *)rbuf1, (UCHAR *)rptr, rlen1);
                rbuf1 += rlen1;
                rlen += rlen1;
            }
            rptr = (ULONG)rbuf;
        }

        // this is a good place to check for errors
        // any 'late' errors, such as fcs, overflow will already have transferred to
        // memory, so should be discarded, and freed
        stat = *(volatile ULONG *)(eth->rx_fda_desc+0x08);
        rerror = 0;
        if (stat & 0x0f10)
        {
            printf("\n*** rx error  ***\n");
            printf("MAC_RX_STAT = %08lx\n", stat);
            if (stat & 0x0010) printf("*** lenerr ***\n");
            if (stat & 0x0100) printf("*** alignment error ***\n");
            if (stat & 0x0200) printf("*** crc error ***\n");
            if (stat & 0x0400) printf("*** overflow ***\n");
            if (stat & 0x0800) printf("*** long error ***\n");
            rerror = 1;
        }

        if (eth->debug & 0x01) printf("R");
        if (eth->debug & 0x02) printf("R: rbuf = 0x%08lx, rlen = 0x%x, eth->rx_fda_desc = 0x%08lx\n",(ULONG)rptr, rlen, eth->rx_fda_desc);
        if (eth->debug & 0x04) dump_pkt((pkt_type *)rptr, rlen);
        if (eth->debug & 0x08) decode_pkt((pkt_type *)rptr, rlen);

        // this can be the original buffer - unless it is fragmented
        if (rlen && !rerror)
        {
            // this is the call to the users ip stack
            if (rx_callback)
    			err = (rx_callback)((void *)rptr, rlen, context);
        }

        // now free the rx
        // return the buffer list descriptors
        // how do we know the address of the buffer list ???

        // actually, the packet may be split accross more than 1 bl_desc
        // and the fdsystem points to the LAST bl_desc used
        // should only free up the bl's that are actually used ...

        // now just free them all
        for (i=0; i<ctl; i=i+1)
        {
        	ULONG buff;
        	ULONG desc;
        	ULONG offset;
            // free buffer
            // buffer address should not have changed

            // calculate the rx_bl_desc for each buffer, and the offset ...
            buff   = (*(volatile ULONG *)(eth->rx_fda_desc+0x10+(8*i)) - eth->rx_buffer_base) / eth->rx_buffer_length;
            desc   = buff / eth->rx_num_buffs;
            offset = buff % eth->rx_num_buffs;
            eth->rx_bl_desc = eth->rx_bl_desc_base + (0x10 + (8*eth->rx_num_buffs)) * desc;
            *(volatile ULONG *)(eth->rx_bl_desc+0x14+(8*offset)) = 0x80000000 | eth->rx_buffer_length;      // set OWN bit + length
        }

        // return fda descriptor
        *(volatile ULONG *)(eth->rx_fda_desc+0x00) = 0xffffffff;
        *(volatile ULONG *)(eth->rx_fda_desc+0x04) = 0xffffffff;
        *(volatile ULONG *)(eth->rx_fda_desc+0x08) = 0xffffffff;
        *(volatile ULONG *)(eth->rx_fda_desc+0x0c) = 0xffffffff;
        for (i=0; i<buffer_count; i++)
        {
            *(volatile ULONG *)(eth->rx_fda_desc+(i*8)+0x10) = 0xffffffff;
            *(volatile ULONG *)(eth->rx_fda_desc+(i*8)+0x14) = 0xffffffff;
        }

        // move on eth->rx_fda_desc ptr
        eth->rx_fda_desc = next;
        return err;
    }
    return -1;
}


// issue a pause command for slots (1 slot = 5.12us/51.2us)
int eth_pause(type_eth_descriptors *eth, USHORT slots)
{
    ULONG tx_ctl;

    // skip if previous not yet completed
    if (read_csr(MAC_TX_CTL) & 0x40) return 1;

    // set the pause duration
    eth->macaddr[0x7c] = (slots >> 8) & 0xff;   // pause duration
    eth->macaddr[0x7d] = slots & 0xff;
    // set up ARC
    write_csr(MAC_ARC_ADDR, 0x7c);
    write_csr(MAC_ARC_DATA, ((eth->macaddr[0x7c+0] & 0xff) << 24) | ((eth->macaddr[0x7c+1] & 0xff) << 16) | ((eth->macaddr[0x7c+2] & 0xff) << 8) | ((eth->macaddr[0x7c+3] & 0xff) << 0));

    // issue the pause command
    tx_ctl = read_csr(MAC_TX_CTL);
    write_csr(MAC_TX_CTL, tx_ctl | 0x40);

    return 0;
}




// phy stuff
int eth_mdread(int addr, int reg)
{
    int rdata;

    // ensure busy not set
    do
    {
        rdata = read_csr(MAC_MD_CA);
    } while (rdata & 0x0800);

    // read md, phy_addr:addr, phy_reg:reg
    write_csr(MAC_MD_CA, 0x00000800 | ((addr & 0x1f) << 5) | ((reg & 0x1f) << 0));

    // wait while busy set
    do
    {
        rdata = read_csr(MAC_MD_CA);
    } while (rdata & 0x0800);
    rdata = read_csr(MAC_MD_DATA);

    return rdata;
}

int eth_mdwrite(int addr, int reg, int wdata)
{
    int rdata;

    // ensure busy not set
    do
    {
        rdata = read_csr(MAC_MD_CA);
    } while (rdata & 0x0800);

    // write md, phy_addr:addr, phy_reg:reg
    write_csr(MAC_MD_DATA, wdata);
    write_csr(MAC_MD_CA, 0x00000c00 | ((addr & 0x1f) << 5) | ((reg & 0x1f) << 0));

    // wait while busy set
    do
    {
        rdata = read_csr(MAC_MD_CA);
    } while (rdata & 0x0800);

    return 0;
}


// read bank n
// if bank n is currently being written, do a bankswap first
int eth_rmon_getstats(int banksel, ULONG *sdata, int clear, int view)
{
    ULONG rdata;
    ULONG addr;
    int   bank;

    rdata =  read_csr(RMON_COUNT_ACCESS);
    bank = (rdata >> 11) & 1;       // this is the bank currently being written
    if (bank == banksel)
    {
        // bankswap
        write_csr(RMON_COUNT_ACCESS, RMON_CMD_BANKSWAP);
        // wait til done
        rdata = read_csr(RMON_COUNT_ACCESS);
        while(rdata & RMON_STATUS_BANKBSY)
        {
            rdata = read_csr(RMON_COUNT_ACCESS);
        }
    }

    for (addr=0; addr<0x40; addr=addr+1)
    {
        if (clear)
            write_csr(RMON_COUNT_ACCESS, RMON_CMD_READCLR | addr);
        else
            write_csr(RMON_COUNT_ACCESS, RMON_CMD_READ | addr);

        sdata[addr] = read_csr(RMON_COUNT_DATA);
    }

    if (view)
    {
        printf("\n");
        printf("bank :%d\n",bank);
        printf("Transmit\n");
        printf("00 CollisionFrames0               = %ld\n",sdata[0x00]);
        printf("01 CollisionFrames1               = %ld\n",sdata[0x01]);
        printf("   ...\n");
        printf("10 CollisionFrames16              = %ld\n",sdata[0x10]);
        printf("11 FramesWithDeferredXmissions    = %ld\n",sdata[0x11]);
        printf("12 LateCollisions                 = %ld\n",sdata[0x12]);
        printf("13 FramesLostDueToIntMACXmitError = %ld\n",sdata[0x13]);
        printf("14 CarrierSenseError              = %ld\n",sdata[0x14]);
        printf("15 FramesWithExcessiveDeferral    = %ld\n",sdata[0x15]);
        printf("16 UnicastFramesXmittedOK         = %ld\n",sdata[0x16]);
        printf("17 MulticastFramesXmittedOK       = %ld\n",sdata[0x17]);
        printf("18 BroadcastFramesXmittedOK       = %ld\n",sdata[0x18]);
        printf("19 SQETestErrors                  = %ld\n",sdata[0x19]);
        printf("1a PAUSEMACCtlFramesTransmitted   = %ld\n",sdata[0x1a]);
        printf("1b MACCtlFramesTransmitted        = %ld\n",sdata[0x1b]);
        printf("1c VLANFramesTransmitted          = %ld\n",sdata[0x1c]);
        printf("1d OctetsTransmittedOK            = %ld\n",sdata[0x1d]);
        printf("1e OctetsTransmittedOKHi          = %ld\n",sdata[0x1e]);
        printf("\n");
        printf("Receive\n");
        printf("20 ReceivePacketSize0 (0-63)      = %ld\n",sdata[0x20]);
        printf("21 ReceivePacketSize1 (64)        = %ld\n",sdata[0x21]);
        printf("22 ReceivePacketSize2 (65-127)    = %ld\n",sdata[0x22]);
        printf("23 ReceivePacketSize3 (128-255)   = %ld\n",sdata[0x23]);
        printf("24 ReceivePacketSize4 (256-511)   = %ld\n",sdata[0x24]);
        printf("25 ReceivePacketSize5 (512-1023)  = %ld\n",sdata[0x25]);
        printf("26 ReceivePacketSize6 (1024-1518) = %ld\n",sdata[0x26]);
        printf("27 ReceivePacketSize7 (>1518)     = %ld\n",sdata[0x27]);
        printf("28 FrameCheckSequenceErrors       = %ld\n",sdata[0x28]);
        printf("29 AlignmentErrors                = %ld\n",sdata[0x29]);
        printf("2a Fragments                      = %ld\n",sdata[0x2a]);
        printf("2b Jabbers                        = %ld\n",sdata[0x2b]);
        printf("2c FramesLostDueToIntMACRcvError  = %ld\n",sdata[0x2c]);
        printf("2d UnicastFramesReceivedOK        = %ld\n",sdata[0x2d]);
        printf("2e MulticastFramesReceivedOK      = %ld\n",sdata[0x2e]);
        printf("2f BroadcastFramesReceivedOK      = %ld\n",sdata[0x2f]);
        printf("30 InRangeLengthErrors            = %ld\n",sdata[0x30]);
        printf("31 OutOfRangeLengthErrors         = %ld\n",sdata[0x31]);
        printf("32 VLANFramesReceived             = %ld\n",sdata[0x32]);
        printf("33 PAUSEMACCtlFramesReceived      = %ld\n",sdata[0x33]);
        printf("34 MACCtlFramesReceived           = %ld\n",sdata[0x34]);
        printf("35 OctetsReceivedOK               = %ld\n",sdata[0x35]);
        printf("36 OctetsReceivedOKHi             = %ld\n",sdata[0x36]);
        printf("37 OctetsReceivedOther            = %ld\n",sdata[0x37]);
        printf("38 OctetsReceivedOtherHi          = %ld\n",sdata[0x38]);
    }
    return 0;
}

⌨️ 快捷键说明

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