AT91Sam9260的网卡驱动

首先先上电路原理图,关于AT91芯片网卡部分的引脚:



内核源码中对网卡以及其他外设设备的驱动程序,设备的注册都在 Board_sam9260ek_.c文件中。

结构体原型:

/* Ethernet (EMAC & MACB) */

struct at91_eth_data {

u32phy_mask;
u8 phy_irq_pin;/* PHY IRQ */
u8 is_rmii;/* using RMII interface? */
};

注册为中断引脚为AT91_PIN_PA7,MII模式

/* MACB Ethernet device*/
static struct at91_eth_data __initdata ek_macb_data = {
.phy_irq_pin = AT91_PIN_PA7,
.is_rmii = 1,
};

添加设备

/* Ethernet */
at91_add_device_eth(&ek_macb_data);


static struct platform_device at91sam9260_eth_device = {
.name = "macb",
.id = -1,
.dev = {
.dma_mask = &eth_dmamask,
.coherent_dma_mask= DMA_BIT_MASK(32),
.platform_data= &eth_data,
},
.resource = eth_resources,
.num_resources= ARRAY_SIZE(eth_resources),
};

void __init at91_add_device_eth(struct at91_eth_data *data)
{
if (!data)
return;

if (data->phy_irq_pin) {
at91_set_gpio_input(data->phy_irq_pin, 0);
at91_set_deglitch(data->phy_irq_pin, 1);
}

/* Pins used for MII and RMII */
at91_set_A_periph(AT91_PIN_PA19, 0);/* ETXCK_EREFCK */
at91_set_A_periph(AT91_PIN_PA17, 0);/* ERXDV */
at91_set_A_periph(AT91_PIN_PA14, 0);/* ERX0 */
at91_set_A_periph(AT91_PIN_PA15, 0);/* ERX1 */
at91_set_A_periph(AT91_PIN_PA18, 0);/* ERXER */
at91_set_A_periph(AT91_PIN_PA16, 0);/* ETXEN */
at91_set_A_periph(AT91_PIN_PA12, 0);/* ETX0 */
at91_set_A_periph(AT91_PIN_PA13, 0);/* ETX1 */
at91_set_A_periph(AT91_PIN_PA21, 0);/* EMDIO */
at91_set_A_periph(AT91_PIN_PA20, 0);/* EMDC */

if (!data->is_rmii) {
at91_set_B_periph(AT91_PIN_PA28, 0);/* ECRS */
at91_set_B_periph(AT91_PIN_PA29, 0);/* ECOL */
at91_set_B_periph(AT91_PIN_PA25, 0);/* ERX2 */
at91_set_B_periph(AT91_PIN_PA26, 0);/* ERX3 */
at91_set_B_periph(AT91_PIN_PA27, 0);/* ERXCK */
at91_set_B_periph(AT91_PIN_PA23, 0);/* ETX2 */
at91_set_B_periph(AT91_PIN_PA24, 0);/* ETX3 */
at91_set_B_periph(AT91_PIN_PA22, 0);/* ETXER */
}

eth_data = *data;
platform_device_register(&at91sam9260_eth_device);

}


可以发现注册的为platform总线上的设备

在内核启动后可在 sys/bus/platform/devices中找到macb、除此之外,你也可以发现注册在platform总线上的nandflash、uart、spi、i2c等设备

[@SD9260: /]# cd sys/
[@SD9260: /sys]# ls
block     class     devices   fs        module
bus       dev       firmware  kernel    power
[@SD9260: /sys]# clear
[@SD9260: /sys]# ls
block     class     devices   fs        module
bus       dev       firmware  kernel    power
[@SD9260: /sys]# cd bus/
[@SD9260: bus]# ls
i2c       mmc       scsi      serio     usb
mdio_bus  platform  sdio      spi
[@SD9260: bus]# cd platform/
[@SD9260: platform]# ls
devices            drivers_autoprobe  uevent
drivers            drivers_probe
[@SD9260: platform]# cd devices/
[@SD9260: devices]# ls
at91_mci       atmel_nand     atmel_usart.1  atmel_usart.5  macb
at91_ohci      atmel_spi.0    atmel_usart.2  atmel_usart.6  ssc.0
at91_rtt.0     atmel_spi.1    atmel_usart.3  i2c-gpio
at91_udc       atmel_usart.0  atmel_usart.4  leds-gpio
[@SD9260: devices]# cd macb/
[@SD9260: macb]# ls
bus        driver     modalias   net:eth0   power      subsystem  uevent


对应引脚连接到DP83848以太网控制芯片,0用的是MII模式 百兆网口芯片,这样就网卡芯片驱动就起来了。

但是在网卡使用的过程中是如何判断网卡的状态的呢?
Linux内核通过读取网卡内置芯片中的寄存器来判断网卡的工作状态。下面来说明网卡link up过程。
地址为0x00 的寄存器的各位功能如下:
Table 6-9. Basic Mode Control Register (BMCR), address 0x00
Bit Bit Name Default Description
15 Reset 0, RW/SC Reset:
1 = Initiate software Reset / Reset in Process.
0 = Normal operation.
This bit, which is self-clearing, returns a value of one until the reset process is complete. The
configuration is re-strapped.
14 Loopback 0, RW Loopback:
1 = Loopback enabled.
0 = Normal operation.
The loopback function enables MII transmit data to be routed to the MII receive data path.
Setting this bit may cause the descrambler to lose synchronization and produce a 500 µs “dead
time” before any valid data will appear at the MII receive outputs.
13 Speed Selection RW Speed Select:
When auto-negotiation is disabled writing to this bit allows the port speed to be selected.
1 = 100 Mb/s.
0 = 10 Mb/s.
12 Auto-Negotiation
Enable
RW Auto-Negotiation Enable:
Strap controls initial value at reset.
1 = Auto-Negotiation Enabled - bits 8 and 13 of this register are ignored when this bit is set.
0 = Auto-Negotiation Disabled - bits 8 and 13 determine the port speed and duplex mode.
11 Power Down 0, RW Power Down:
1 = Power down.
0 = Normal operation.
Setting this bit powers down the PHY. Only the register block is enabled during a power-down
condition.
10 Isolate 0, RW Isolate:
1 = Isolates the Port from the MII with the exception of the serial management.
0 = Normal operation.
9 Restart Auto
Negotiation
0, RW/SC Restart Auto-Negotiation:
1 = Restart Auto-Negotiation. Re-initiates the Auto-Negotiation process. If Auto-Negotiation is
disabled (bit 12 = 0), this bit is ignored. This bit is self-clearing and will return a value of 1 until
Auto-Negotiation is initiated, whereupon it will self-clear. Operation of the Auto-Negotiation
process is not affected by the management entity clearing this bit.
0 = Normal operation.
8 Duplex Mode RW Duplex Mode:
When auto-negotiation is disabled writing to this bit allows the port Duplex capability to be
selected.
1 = Full Duplex operation.
0 = Half Duplex operation.

Bit Bit Name Default Description
7 Collision Test 0, RW Collision Test:
1 = Collision test enabled.
0 = Normal operation.
When set, this bit will cause the COL signal to be asserted in response to the assertion of
TX_EN within 512-bit times. The COL signal will be deasserted within 4-bit times in response to
the deassertion of TX_EN.
6:0 RESERVED 0, RO RESERVED: Write ignored, read as 0

关于以太网芯片寄存器的详细描述可参考该博客 http://blog.csdn.net/subfate/article/details/44958597
Linux中通过程序来读取寄存器当前的值:源代码如下:
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
        
        
#include 
        
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              #include 
             
               #include 
              
                #define reteck(ret) \ if(ret < 0){ \ printf("%m! \"%s\" : line: %d\n", __func__, __LINE__); \ goto lab; \ } #define help() \ printf("mdio:\n"); \ printf("read operation: mdio reg_addr\n"); \ printf("write operation: mdio reg_addr value\n"); \ printf("For example:\n"); \ printf("mdio eth0 1\n"); \ printf("mdio eth0 0 0x12\n\n"); \ exit(0); int sockfd; int main(int argc, char *argv[]){ if(argc == 1 || !strcmp(argv[1], "-h")){ help(); } struct mii_ioctl_data *mii = NULL; struct ifreq ifr; int ret; memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1); sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0); reteck(sockfd); //get phy address in smi bus ret = ioctl(sockfd, SIOCGMIIPHY, &ifr); reteck(ret); mii = (struct mii_ioctl_data*)&ifr.ifr_data; if(argc == 3){ mii->reg_num = (uint16_t)strtoul(argv[2], NULL, 0); ret = ioctl(sockfd, SIOCGMIIREG, &ifr); reteck(ret); printf("read phy addr: 0x%x reg: 0x%x value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_out); }else if(argc == 4){ mii->reg_num = (uint16_t)strtoul(argv[2], NULL, 0); mii->val_in = (uint16_t)strtoul(argv[3], NULL, 0); ret = ioctl(sockfd, SIOCSMIIREG, &ifr); reteck(ret); printf("write phy addr: 0x%x reg: 0x%x value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_in); } lab: close(sockfd); return 0; } 
               
              
             
            
           
          
        
       
       
      
      
     
     
    
    

通过对PHY层 的寄存器来判断网卡的工作状态。

./phy eth0 0x1

./phy eth0 0x1 0x7849  将0x7849写入寄存器1

以上就是我对AT91SAM9260网卡驱动以及DP83848网卡芯片的一些理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值