s3c2410上arm-linux上的cs8900网卡驱动

linglidu   2009-5-23 23:26 楼主


我的s3c2410开发板的BANK3上接了一块cs8900,

我用的是IO模式, 中断接收方式, 相关寄存器的初始化如下:

        put_reg(PP_RxCFG, get_reg(PP_RxCFG) | RxOKiE | BufferCRC );       

        put_reg(PP_RxCTL, get_reg(PP_RxCTL) | RxOKA | IndividualA | BroadcastA );

        put_reg(PP_TxCFG, get_reg(PP_TxCFG) | TxOKiE);

        put_reg(PP_LineCTL, get_reg(PP_LineCTL) | SerRxON | SerTxON);

        put_reg(PP_BusCTL, get_reg(PP_BusCTL) | EnableRQ);



接收数据如下:

        ....

        unsigned short data[1000];

        volatile unsigned short status;

        unsigned long  length;

        unsigned short value;

       

        /*read data */

        while(status = get_reg(PP_ISQ)) {

                switch (0x3f & status ) {

                        case RxEvent:

                                value = get_reg(PP_RxStatus);

                                if (value & RxOK) {

                                        volatile unsigned long p = ETH_BASE + 0x300;

                                        int i;



                                        memset(data, 0x00, 2000);

                                        length = get_reg(PP_RxLength);                       

                                       

                                        for (i = 0; i < (length >> 1); i ++) {

                                                *(data + i) = *((volatile unsigned short *)p);       

                                        }                                       

                                        if (length & 1) {

                                                *(data + i) = *((volatile unsigned short *)p);       

                                        }

                                }

                                break;

                }

        }

        ...........



内存控制器相关寄存器初始化如下:

        ....

        volatile unsigned long *r;



        r = (void *)0x48000000;

        *r |=  (*r & ~(0x3 << 12)) | (0x1 << 12) | (1 << 14) | (1 << 15);



        r = (void *)0x48000010;

        *r = 0x1f7c;       

        .........



利用上述代码我在arm-linux下成功驱动,网卡发送数据接收数据都正常,

工作完全正常,可以正常使用。

接收出来的数据,第一个字节开始对应的就是以太网的头,

目的mac地址、源mac地址我用printk打印出来都是正常的,而且字节序不用转换,都是正确的.

注: 在arm-linux驱动中, 上述代码的ETH_BASE=ioremap(0x19000000,.....)





我现在自已写了一个bootloader, 利用上述代码(ETH_BASE=0x19000000),

发送数据都是OK的, 另外一台机能够正常收到开发板发过来的数据.

但是现在就是接收出问题了:

1、接收到的数据从第一个字节本来应该是以太网的头,结果我打印出来看,第一个字节

是一个接收长度低8位的值,从第二个字节开始才是以太网的头.



2、从第二个字节开始是以太网头,但是字节序是反的。按两字节交换过的.





附上数据:



1.从arm-linux驱动中打印出来的接收到的以太网头(从另一台机ping开发板,开发板接收到的数据):

dst mac: ff:ff:ff:ff:ff:ff

src mac: 00:16:36:80:5d:54

type   : 0608





2.同样是用上述代码,在bootloader的irq的异常处理(只开了网卡中断,没有开其它任何中断)中打印出来:

dst mac: 40:ff:ff:ff:ff:ff

src mac: ff:16:00:80:36:54

type   : 065d



第一个字节是十进制的64, 刚好是发送的长度.



哪位大侠指点一下是为什么呀?










回复评论 (2)

结贴 !!!
问题找到了,原来当你编译选项没有加 -march=armv4的时候,像这种代码:

unsigned short a;
a = *(volatile unsigned short *)p;

编译器会将short的存取用 ldrb / strb来实现,然后再移组合,但是如果加了-march=armv4就不会了。

还以为是cs8900的问题。。。。。
点赞  2009-5-24 12:02
哦,已经解决了吗。
点赞  2009-5-24 14:56
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复