text: #include <unistd.h>
  #include <stdlib.h>
  #include <stdio.h>
  #include <syslog.h>
  #include <errno.h>
  #include <string.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>
  
  static int skfd = -1;
  static struct ifreq ifr;
  
  struct mii_data {
    __u16 phy_id;
    __u16 reg_num;
    __u16 val_in;
    __u16 val_out;
  };
  
  int mdio_read(int location) {
    struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
    mii->reg_num = location;
    if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
      fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
              strerror(errno));
      return -1;
    }
    return mii->val_out;
  }
  
  int mdio_write(int location, int value) {
    struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
    mii->reg_num = location;
    mii->val_in = value;
    if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
      fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
              strerror(errno));
      return -1;
    }
    return 0;
  }
  
  void mdio_init() {
    if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
      perror("socket init failed");
      exit(-1);
    }
  }
  
  int mdio_set_interface(const char *ifname) {
    strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
    if (ioctl(skfd, SIOCGMIIPHY, &ifr) < 0) {
      if (errno != ENODEV)
        fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n", ifname,
                strerror(errno));
      return -1;
    }
    return 0;
  }
  
  void mdio_done() { close(skfd); }
  