此阶段,只需要把各个描述符的地地址指针连接成一个链表就可以了。由于是用链的模式结构,所以ctrl域的第28位必须设置为1,也就是说发送描述符的ctrl与TD_TCH相或,接收描述符的ctrl与RD_RCH相或。这样,DMA传输数据的时候就会以链模式去获取地址和数据。在status字段里有个重要的域OWN,为1时,表示MAC占有该描述符,为0时,表示CPU占有该描述符。实际上,当属于这个描述符的资源,不进行数据传输时,为0,当进行数据传输时为1。这样,在初始化的时候,不发送,所以发送描述符的OWN为0,进行接收,所以接收描述符的OWN为1。
所以:
对于发送描述符
tx_desc.status = 0x80000000;
tx_desc.ctrl |= TD_TCH;
tx_desc.addr = 0;
tx_desc.next = next_tx_desc_addr;
对于接收描述符
rx_desc.status = 0;
rx_desc.ctrl |= RD_RCH;
rx_desc.addr = rev_buf1;
rx_desc.next = next_rx_desc_addr;
由于发送描述符的OWN为1,也就是说在进行接收,这样就需要指定接收的最后一个描述符,所以对于最后一个接收描述符,应该有这样的操作:rx_desc.ctrl |= RD_RER。也就是说,对于ctrl字段,设置第25位来指定该描述符为最后一个描述符。
接着,把第一个接收描述符和第一个发送描述符保存到MAC0_RX_LIST_BASE_ADDR和MAC0_TX_LIST_BASE_ADDR寄存器。
4、使能MAC控制器
这部分是通过设置操作模式寄存器MAC0_OPERATION_MODE,也即CSR6来进行操作。
CSR6 = 0x32000040 | OMR_ST | OMR_SR | OMR_PS
其中0x32000040为默认值,第6位为1,表示启动混杂模式,这样,所以的合法数据帧将被接收,如果只需要接收目标地址为MAC地址的数据包的话,那么需要进入正常模式,也就是把第6位清零。OMR_ST和OMR_SR为使能发送接收。OMR_PS为端口选择,设置该位后,就选择了MII接口。如果我们进入正常模式,那么:
CSR6 &= ~(1<<6);
5、发送建立数据帧
根据文档说明,建立数据帧并不是真正发送出去,而是进行地址滤,也就是说,需要接收什么目标地址的数据包,那么就将该MAC地址放到建立帧里。
那么该表内的Physical Adress都将被MAC接收,不在此表内的就丢弃。所以自己MAC地址必须包括在内,这样就可以对发送给自己的数据包接收了。
对该帧数据对应的发送描述符进行赋值:
tx_desc.status = (1<<OWN);
tx_desc.ctrl = TD_TCH | TD_SET| SETUP_FRAME_LEN;
tx_desc.addr = setup_frame_buf;
然后写入非零值到发送查询请求寄存器MAC_TX_POLL_REQ,即CSR3。
当OWN清零之后,数据发送完毕。这样建立帧完成了。
PS:关于建立帧帧格式和发送完成标志与DC2114A文档所说有所不同,在帧格式中的第一个地址里填入自身的MAC地址后,还需要在其后填上
0xffff,或者写入广播地址。建立帧完成后,status等于0,而不是文档所说的0x7fffffff。
6、使能CPU中断控制器中的MAC中断
设置中断触发类型
使能MAC中断
到此网卡的初始化基本完成。