A cable test is a async job for the switch. swconfig dev switch0 port 1 set cabletest # start swconfig dev switch0 port 1 get cableresult # get results
Signed-off-by: Alexander Couzens <[email protected]> --- .../linux/generic/files/drivers/net/phy/ar8216.c | 111 +++++++++++++++++++++ .../linux/generic/files/drivers/net/phy/ar8216.h | 7 ++ 2 files changed, 118 insertions(+) diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index ccc074f..fc27000 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -1653,6 +1653,105 @@ unlock: return ret; } +static int +ar8327_sw_cabletest_start(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct mii_bus *bus = swdev_to_ar8xxx(dev)->phy->bus; + // port 1 = phy 0 + int phy = val->port_vlan -1; + + if(!chip_is_ar8327(swdev_to_ar8xxx(dev))) + { + pr_info("switch: Only ar8327 is supported for cable testing\n"); + return -EINVAL; + } + + if (phy < 0 || phy >= AR8327_NUM_PHYS) { + return -EINVAL; + } + + mutex_lock(&bus->mdio_lock); + // check for a still running test + if(bus->read(bus, phy, AR8327_MII_CBLTEST_CTRL) & 0x1) { + mutex_unlock(&bus->mdio_lock); + return -EINVAL; + } + + // start cable test + bus->write(bus, phy, AR8327_MII_CBLTEST_CTRL, 0x1); + mutex_unlock(&bus->mdio_lock); + + return 0; +} + +static int +ar8327_sw_cabletest_get(struct switch_dev *dev, + const struct switch_attr *attr, + struct switch_val *val) +{ + struct mii_bus *bus = swdev_to_ar8xxx(dev)->phy->bus; + u16 reads; + u16 writes; + unsigned int pair; + /* length multiply *0.824m */ + u8 cablelength; + u8 state; + char buf[2048]; + int len = 0; + // port 1 = phy 0 + int phy = val->port_vlan -1; + + if(!chip_is_ar8327(swdev_to_ar8xxx(dev))) + { + pr_info("switch: Only ar8327 is supported for cable testing\n"); + return -EINVAL; + } + + if (phy < 0 || phy >= AR8327_NUM_PHYS) + return -EINVAL; + + mutex_lock(&bus->mdio_lock); + + // check active cable test + reads = bus->read(bus, phy, AR8327_MII_CBLTEST_CTRL); + if (reads & 0x1) { + len += snprintf(buf + len, sizeof(buf) - len, "Error: Cabletest still running\n"); + goto out; + } + + for (pair = 0; pair < 4 ; pair++) { + writes = pair << AR8327_CBLTEST_CTRL_SELECT_BIT; + bus->write(bus, phy, AR8327_MII_CBLTEST_CTRL, pair << AR8327_CBLTEST_CTRL_SELECT_BIT); + usleep_range(1000, 2000); /* wait for the switch to propagate */ + reads = bus->read(bus, phy, AR8327_MII_CBLTEST_RESULTS); + cablelength = reads & 0xFF; + state = reads >> AR8327_CBLTEST_CTRL_STATUS_BIT; + len += snprintf(buf + len, sizeof(buf) - len, "pair %i, len %i (0.824m), state ", pair, cablelength); + switch(state) { + case AR8327_CBLTEST_CTRL_STATUS_OK: + len += snprintf(buf + len, sizeof(buf) - len, "ok, no link\n"); + break; + case AR8327_CBLTEST_CTRL_STATUS_LINK: + len += snprintf(buf + len, sizeof(buf) - len, "link up\n"); + break; + default: + len += snprintf(buf + len, sizeof(buf) - len, "broken 0x%x\n", state); + break; + } + } + +out: + mutex_unlock(&bus->mdio_lock); + + val->value.s = buf; + val->len = len; + return 0; +} + + + static struct switch_attr ar8xxx_sw_attr_globals[] = { { .type = SWITCH_TYPE_INT, @@ -1685,6 +1784,18 @@ static struct switch_attr ar8xxx_sw_attr_port[] = { .set = NULL, .get = ar8xxx_sw_get_port_mib, }, + { + .type = SWITCH_TYPE_NOVAL, + .name = "cabletest", + .description = "Start a cabletest on port", + .set = ar8327_sw_cabletest_start, + }, + { + .type = SWITCH_TYPE_STRING, + .name = "cableresult", + .description = "Get results of cabletest", + .get = ar8327_sw_cabletest_get, + }, }; static struct switch_attr ar8xxx_sw_attr_vlan[] = { diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h index 95d9a96..709d127 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.h +++ b/target/linux/generic/files/drivers/net/phy/ar8216.h @@ -438,6 +438,13 @@ #define AR8327_REG_PORT_STATS_BASE(_i) (0x1000 + (_i) * 0x100) +#define AR8327_MII_CBLTEST_CTRL 0x16 +#define AR8327_CBLTEST_CTRL_SELECT_BIT 0x8 +#define AR8327_MII_CBLTEST_RESULTS 0x1c +#define AR8327_CBLTEST_CTRL_STATUS_BIT 0x8 +#define AR8327_CBLTEST_CTRL_STATUS_OK 0x0 +#define AR8327_CBLTEST_CTRL_STATUS_LINK 0x3 + /* port speed */ enum { AR8216_PORT_SPEED_10M = 0, -- 1.8.2 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
