ar8216: add 802.3az EEE info to swconfig get_link attribute
AR8327/AR8337 allow to read the result of EEE autonegotiation. If EEE is autonegotiated between the link partners, display this as part of the swconfig get_link attribute. eee100: 100MBit EEE supported by both link partners eee1000: 1GBit EEE supported by both link partners Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> SVN-Revision: 44022
This commit is contained in:
parent
bdc0750191
commit
53c0c6054f
5 changed files with 49 additions and 1 deletions
|
@ -332,6 +332,20 @@ ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 data)
|
||||||
mutex_unlock(&bus->mdio_lock);
|
mutex_unlock(&bus->mdio_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16
|
||||||
|
ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr)
|
||||||
|
{
|
||||||
|
struct mii_bus *bus = priv->mii_bus;
|
||||||
|
u16 data;
|
||||||
|
|
||||||
|
mutex_lock(&bus->mdio_lock);
|
||||||
|
bus->write(bus, phy_addr, MII_ATH_MMD_ADDR, addr);
|
||||||
|
data = bus->read(bus, phy_addr, MII_ATH_MMD_DATA);
|
||||||
|
mutex_unlock(&bus->mdio_lock);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ar8xxx_reg_wait(struct ar8xxx_priv *priv, u32 reg, u32 mask, u32 val,
|
ar8xxx_reg_wait(struct ar8xxx_priv *priv, u32 reg, u32 mask, u32 val,
|
||||||
unsigned timeout)
|
unsigned timeout)
|
||||||
|
@ -453,6 +467,9 @@ ar8216_read_port_link(struct ar8xxx_priv *priv, int port,
|
||||||
link->tx_flow = !!(status & AR8216_PORT_STATUS_TXFLOW);
|
link->tx_flow = !!(status & AR8216_PORT_STATUS_TXFLOW);
|
||||||
link->rx_flow = !!(status & AR8216_PORT_STATUS_RXFLOW);
|
link->rx_flow = !!(status & AR8216_PORT_STATUS_RXFLOW);
|
||||||
|
|
||||||
|
if (link->aneg && link->duplex && priv->chip->read_port_eee_status)
|
||||||
|
link->eee = priv->chip->read_port_eee_status(priv, port);
|
||||||
|
|
||||||
speed = (status & AR8216_PORT_STATUS_SPEED) >>
|
speed = (status & AR8216_PORT_STATUS_SPEED) >>
|
||||||
AR8216_PORT_STATUS_SPEED_S;
|
AR8216_PORT_STATUS_SPEED_S;
|
||||||
|
|
||||||
|
|
|
@ -366,6 +366,7 @@ struct ar8xxx_chip {
|
||||||
void (*init_port)(struct ar8xxx_priv *priv, int port);
|
void (*init_port)(struct ar8xxx_priv *priv, int port);
|
||||||
void (*setup_port)(struct ar8xxx_priv *priv, int port, u32 members);
|
void (*setup_port)(struct ar8xxx_priv *priv, int port, u32 members);
|
||||||
u32 (*read_port_status)(struct ar8xxx_priv *priv, int port);
|
u32 (*read_port_status)(struct ar8xxx_priv *priv, int port);
|
||||||
|
u32 (*read_port_eee_status)(struct ar8xxx_priv *priv, int port);
|
||||||
int (*atu_flush)(struct ar8xxx_priv *priv);
|
int (*atu_flush)(struct ar8xxx_priv *priv);
|
||||||
void (*vtu_flush)(struct ar8xxx_priv *priv);
|
void (*vtu_flush)(struct ar8xxx_priv *priv);
|
||||||
void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vid, u32 port_mask);
|
void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32 vid, u32 port_mask);
|
||||||
|
@ -432,6 +433,8 @@ ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr,
|
||||||
u16 dbg_addr, u16 dbg_data);
|
u16 dbg_addr, u16 dbg_data);
|
||||||
void
|
void
|
||||||
ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 data);
|
ar8xxx_phy_mmd_write(struct ar8xxx_priv *priv, int phy_addr, u16 addr, u16 data);
|
||||||
|
u16
|
||||||
|
ar8xxx_phy_mmd_read(struct ar8xxx_priv *priv, int phy_addr, u16 addr);
|
||||||
void
|
void
|
||||||
ar8xxx_phy_init(struct ar8xxx_priv *priv);
|
ar8xxx_phy_init(struct ar8xxx_priv *priv);
|
||||||
int
|
int
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
|
#include <linux/mdio.h>
|
||||||
|
|
||||||
#include "ar8216.h"
|
#include "ar8216.h"
|
||||||
#include "ar8327.h"
|
#include "ar8327.h"
|
||||||
|
@ -712,6 +713,27 @@ ar8327_read_port_status(struct ar8xxx_priv *priv, int port)
|
||||||
return ar8xxx_read(priv, AR8327_REG_PORT_STATUS(port));
|
return ar8xxx_read(priv, AR8327_REG_PORT_STATUS(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32
|
||||||
|
ar8327_read_port_eee_status(struct ar8xxx_priv *priv, int port)
|
||||||
|
{
|
||||||
|
int phy;
|
||||||
|
u16 t;
|
||||||
|
|
||||||
|
if (port >= priv->dev.ports)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (port == 0 || port == 6)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
phy = port - 1;
|
||||||
|
|
||||||
|
/* EEE Ability Auto-negotiation Result */
|
||||||
|
ar8xxx_phy_mmd_write(priv, phy, 0x7, 0x8000);
|
||||||
|
t = ar8xxx_phy_mmd_read(priv, phy, 0x4007);
|
||||||
|
|
||||||
|
return mmd_eee_adv_to_ethtool_adv_t(t);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ar8327_atu_flush(struct ar8xxx_priv *priv)
|
ar8327_atu_flush(struct ar8xxx_priv *priv)
|
||||||
{
|
{
|
||||||
|
@ -1069,6 +1091,7 @@ const struct ar8xxx_chip ar8327_chip = {
|
||||||
.init_port = ar8327_init_port,
|
.init_port = ar8327_init_port,
|
||||||
.setup_port = ar8327_setup_port,
|
.setup_port = ar8327_setup_port,
|
||||||
.read_port_status = ar8327_read_port_status,
|
.read_port_status = ar8327_read_port_status,
|
||||||
|
.read_port_eee_status = ar8327_read_port_eee_status,
|
||||||
.atu_flush = ar8327_atu_flush,
|
.atu_flush = ar8327_atu_flush,
|
||||||
.vtu_flush = ar8327_vtu_flush,
|
.vtu_flush = ar8327_vtu_flush,
|
||||||
.vtu_load_vlan = ar8327_vtu_load_vlan,
|
.vtu_load_vlan = ar8327_vtu_load_vlan,
|
||||||
|
@ -1100,6 +1123,7 @@ const struct ar8xxx_chip ar8337_chip = {
|
||||||
.init_port = ar8327_init_port,
|
.init_port = ar8327_init_port,
|
||||||
.setup_port = ar8327_setup_port,
|
.setup_port = ar8327_setup_port,
|
||||||
.read_port_status = ar8327_read_port_status,
|
.read_port_status = ar8327_read_port_status,
|
||||||
|
.read_port_eee_status = ar8327_read_port_eee_status,
|
||||||
.atu_flush = ar8327_atu_flush,
|
.atu_flush = ar8327_atu_flush,
|
||||||
.vtu_flush = ar8327_vtu_flush,
|
.vtu_flush = ar8327_vtu_flush,
|
||||||
.vtu_load_vlan = ar8327_vtu_load_vlan,
|
.vtu_load_vlan = ar8327_vtu_load_vlan,
|
||||||
|
|
|
@ -167,12 +167,14 @@ swconfig_get_link(struct switch_dev *dev, const struct switch_attr *attr,
|
||||||
|
|
||||||
if (link.link)
|
if (link.link)
|
||||||
len = snprintf(dev->buf, sizeof(dev->buf),
|
len = snprintf(dev->buf, sizeof(dev->buf),
|
||||||
"port:%d link:up speed:%s %s-duplex %s%s%s",
|
"port:%d link:up speed:%s %s-duplex %s%s%s%s%s",
|
||||||
val->port_vlan,
|
val->port_vlan,
|
||||||
swconfig_speed_str(link.speed),
|
swconfig_speed_str(link.speed),
|
||||||
link.duplex ? "full" : "half",
|
link.duplex ? "full" : "half",
|
||||||
link.tx_flow ? "txflow " : "",
|
link.tx_flow ? "txflow " : "",
|
||||||
link.rx_flow ? "rxflow " : "",
|
link.rx_flow ? "rxflow " : "",
|
||||||
|
link.eee & ADVERTISED_100baseT_Full ? "eee100 " : "",
|
||||||
|
link.eee & ADVERTISED_1000baseT_Full ? "eee1000 " : "",
|
||||||
link.aneg ? "auto" : "");
|
link.aneg ? "auto" : "");
|
||||||
else
|
else
|
||||||
len = snprintf(dev->buf, sizeof(dev->buf), "port:%d link:down",
|
len = snprintf(dev->buf, sizeof(dev->buf), "port:%d link:down",
|
||||||
|
|
|
@ -54,6 +54,8 @@ struct switch_port_link {
|
||||||
bool tx_flow;
|
bool tx_flow;
|
||||||
bool rx_flow;
|
bool rx_flow;
|
||||||
enum switch_port_speed speed;
|
enum switch_port_speed speed;
|
||||||
|
/* in ethtool adv_t format */
|
||||||
|
u32 eee;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct switch_port_stats {
|
struct switch_port_stats {
|
||||||
|
|
Loading…
Reference in a new issue