Skip to content

Instantly share code, notes, and snippets.

@jvandenbroek
Forked from khenriks/phyfix.c
Created December 2, 2019 10:28
Show Gist options
  • Save jvandenbroek/8e9cfd9ceaa42903c45e2b6de63afdb4 to your computer and use it in GitHub Desktop.
Save jvandenbroek/8e9cfd9ceaa42903c45e2b6de63afdb4 to your computer and use it in GitHub Desktop.
// Userspace ethernet PHY fix for Pine64
// by khenriks@ 2018-03-18
// Free to use and distribute under BSD-2-Clause style license, e.g.
// https://choosealicense.com/licenses/bsd-2-clause/
#include <stdint.h>
#include <string.h>
#include <linux/ethtool.h>
#include <linux/mdio.h>
#include <linux/sockios.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
uint8_t get_phy_address(const char* iface) {
struct ethtool_cmd eth;
eth.cmd = ETHTOOL_GSET;
struct ifreq ifr;
strcpy(ifr.ifr_name, iface);
ifr.ifr_data = (char*)&eth;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
ioctl(fd, SIOCETHTOOL, &ifr);
return eth.phy_address;
}
int simple_phy_write(const char* iface, uint16_t phy_id, uint16_t reg,
uint16_t val) {
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, iface);
struct mii_ioctl_data* mii = (struct mii_ioctl_data*)(&ifr.ifr_data);
mii->phy_id = phy_id;
mii->reg_num = reg;
mii->val_in = val;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
return ioctl(fd, SIOCSMIIREG, &ifr);
}
int main() {
const char* iface = "eth0";
const uint8_t phy_id = get_phy_address(iface);
simple_phy_write(iface, phy_id, 0x1f, 0x0007);
simple_phy_write(iface, phy_id, 0x1e, 0x00a4);
simple_phy_write(iface, phy_id, 0x1c, 0xb591);
simple_phy_write(iface, phy_id, 0x1f, 0x0000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment