u-boot中网口处理--软件部分

u-boot中DM9000驱动分析

1. CSRs和PHY reg读写。

 1 static u16
 2 phy_read(int reg)
 3 {
 4     u16 val;
 5 
 6     /* Fill the phyxcer register into REG_0C */
 7     DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
 8     DM9000_iow(DM9000_EPCR, 0xc);    /* Issue phyxcer read command */
 9     udelay(100);        /* Wait read complete */
10     DM9000_iow(DM9000_EPCR, 0x0);    /* Clear phyxcer read command */
11     val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
12 
13     /* The read data keeps on REG_0D & REG_0E */
14     DM9000_DBG("phy_read(%d): %d\n", reg, val);
15     return val;
16 }
phy_read
 1 static void
 2 phy_write(int reg, u16 value)
 3 {
 4 
 5     /* Fill the phyxcer register into REG_0C */
 6     DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
 7 
 8     /* Fill the written data into REG_0D & REG_0E */
 9     DM9000_iow(DM9000_EPDRL, (value & 0xff));
10     DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
11     DM9000_iow(DM9000_EPCR, 0xa);    /* Issue phyxcer write command */
12     udelay(500);        /* Wait write complete */
13     DM9000_iow(DM9000_EPCR, 0x0);    /* Clear phyxcer write command */
14     DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
15 }
phy_write
 1 static u8
 2 DM9000_ior(int reg)
 3 {
 4     u32     val;
 5     
 6     VALIDATE_ADDR_PORT(reg)
 7 
 8     val = *(u16*)DM9000_DATA;
 9 
10     val &= 0xffff;
11     
12     return (u8)val;
13 }
DM9000_ior
1 static void
2 DM9000_iow(int reg, u8 value)
3 {
4     VALIDATE_ADDR_PORT(reg)
5 
6     *(u16*)(DM9000_DATA) =     (u16)value;
7 }
DM9000_iow
1 #define    VALIDATE_ADDR_PORT(p) \
2     if( m_uLastAddressPort != (p) ) \
3         { \
4             *(u16*)(DM9000_IO)  =(u16)(p);\
5             m_uLastAddressPort = (p);\
6         }
VALIDATE_ADDR_PORT

2. 网口收发

 1 int
 2 eth_rx(void)
 3 {
 4     u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
 5     int     errors=0;
 6     u16        RxLen;
 7 
 8     u32     desc;
 9     PDM9000_RX_DESCRIPTOR    pdesc;
10 
11     DM9000_ior(DM9000_RSR);
12     DM9000_ior(DM9000_ROCR);    
13 
14     for(pdesc=(PDM9000_RX_DESCRIPTOR)&desc;;)
15     {
16         // probe first byte
17         desc = DeviceReadDataWithoutIncrement();    
18         DM9000_DBG("1:\tdesc is 0x%x\n",desc);
19 
20         // check if packet available, 01h means available, 00h means no data
21         if(pdesc->bState != 0x01)
22         {
23             RxLen = 0;
24             break;
25         }
26 
27         // get the data descriptor again
28         desc = DeviceReadData();
29         DM9000_DBG("2:\tdesc is 0x%x\n",desc);        
30 
31         DM9000_DBG("len is 0x%x\n",pdesc->nLength);                
32 
33         DeviceReadString(rdptr,pdesc->nLength);
34 
35         // check status, as specified in DM9000_RXSR,
36         // the following bits are error
37         // <3> PLE
38         // <2> AE
39         // <1> CE
40         // <0> FOE
41         if(pdesc->bStatus & MAKE_MASK4(3,2,1,0))
42         {
43             errors++;
44             continue;
45         } // of error happens
46 
47         RxLen =pdesc->nLength;
48         
49         break;
50     } // of forever read loop
51 
52     /* Pass to upper layer */
53     DM9000_DBG("passing packet to upper layer\n");
54     NetReceive(NetRxPackets[0], RxLen);
55     return RxLen;
56 }
eth_rx
 1 int
 2 eth_send(volatile void *packet, int length)
 3 {
 4     unsigned int loop;
 5 #if 0
 6     for(loop = 0; loop<length;loop++)
 7     {
 8         printf("%02x ",*((char *)packet+loop));    
 9     }
10     printf("\n");    
11 #endif
12     DeviceWriteString((u8*)packet,length);
13 
14     DM9000_iow(DM9000_TXPLH,HIGH_BYTE(length));
15     DM9000_iow(DM9000_TXPLL,LOW_BYTE(length));
16         
17     // TXCR<0>, issue TX request
18     DM9000_iow(DM9000_TCR, MAKE_MASK(0));
19 
20         
21     DM9000_DBG("transmit done\n\n");
22     return 0;
23 }
eth_send

数据接收时首先比对包头4个字节,第一个字节必须是0x01,第3,4字节是数据长度(减去开头的4个字节)。

接收完数据后再比对第二字节(DM9000 RSR),确认是否又错误发生。

用到的编程技巧是读取的包头4个字节直接赋值给一个u32,最低字节即为01,高两位为包长度。

posted @ 2015-09-22 22:33  yuxi_o  阅读(394)  评论(0编辑  收藏  举报