天天看點

linux網絡驅動phy的讀寫調試方法

目前嵌入式晶片支援雙網卡的有很多。在調試網絡驅動時,需要通過mdc 和mdio信号對phy的寄存器進行操作調試。如果每次調試都修改網絡驅動的話會很麻煩。下面提供我常用的網絡驅動調試方法

![image.png](https://ucc.alicdn.com/pic/developer-ecology/ee408d1dd26b4bc2b5b7a2a3cd6b16c8.png)

在驅動層,裝置樹綁定mac與mdio總線的關系。

在Linux應用層,編寫測試程式mdio  。代碼如下:

如果是寫寄存器操作,就傳入四個參數./mdio ethX phyId addr value.

- ethX 表示是哪個網卡,如eth0 eth1

- phyId是  phy的實體位址,一般0x00是廣播位址.有些phy 的0x00不是廣播位址,如marvell 的88e1512 - ID 隻能時0x00 0x11,0x00不是88e1512的廣播位址。

- addr  是phy手冊的寄存器位址

- value 是phy位址要寫入的值

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <linux/mii.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/ioctl.h>

#include <net/if.h>

#include <linux/sockios.h>

#include <linux/types.h>

#include <netinet/in.h>

#include <unistd.h>

int main(int argc, char *argv[])

{

   int sockfd;

   struct mii_ioctl_data *mii = NULL;

   struct ifreq ifr;

   memset(&ifr, 0, sizeof(ifr));

   strncpy(ifr.ifr_name, "eth0", IFNAMSIZ - 1);

   sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);

   ioctl(sockfd, SIOCGMIIPHY, &ifr);

   mii = (struct mii_ioctl_data*)&ifr.ifr_data;

   if(argc == 4)

   {

       strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1);

       sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);

       ioctl(sockfd, SIOCGMIIPHY, &ifr);

       mii = (struct mii_ioctl_data*)&ifr.ifr_data;

       mii->phy_id    = (uint16_t)strtoul(argv[2], NULL, 0);

       mii->reg_num    = (uint16_t)strtoul(argv[3], NULL, 0);

       ioctl(sockfd, SIOCGMIIREG, &ifr);

       printf("read --- value : 0x%x", mii->val_out);

   }

   else if(argc == 5)

       mii->val_in     = (uint16_t)strtoul(argv[4], NULL, 0);

       ioctl(sockfd, SIOCSMIIREG, &ifr);

   }else{

      printf("mdio ethX phyId addr value\n");

   close(sockfd);

   return 0;

}

繼續閱讀