.name = (_n), \
}
+#define AR8216_MIB_RXB_ID 14 /* RxGoodByte */
+#define AR8216_MIB_TXB_ID 29 /* TxByte */
+
+#define AR8236_MIB_RXB_ID 15 /* RxGoodByte */
+#define AR8236_MIB_TXB_ID 31 /* TxByte */
+
static const struct ar8xxx_mib_desc ar8216_mibs[] = {
MIB_DESC(1, AR8216_STATS_RXBROAD, "RxBroad"),
MIB_DESC(1, AR8216_STATS_RXPAUSE, "RxPause"),
if (ret & BMCR_ANENABLE)
return 0;
- dev_info(&phydev->dev, "ANEG disabled, re-enabling ...\n");
+ dev_info(&phydev->mdio.dev, "ANEG disabled, re-enabling ...\n");
ret |= BMCR_ANENABLE | BMCR_ANRESTART;
return phy_write(phydev, MII_BMCR, ret);
}
{
struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
- if (val->port_vlan >= AR8X16_MAX_PORTS)
+ if (val->port_vlan >= AR8X16_MAX_VLANS)
return -EINVAL;
priv->vlan_id[val->port_vlan] = val->value.i;
priv->arl_age_time = AR8XXX_DEFAULT_ARL_AGE_TIME;
chip->init_globals(priv);
+ chip->atu_flush(priv);
mutex_unlock(&priv->reg_mutex);
return ret;
}
+int
+ar8xxx_sw_get_port_stats(struct switch_dev *dev, int port,
+ struct switch_port_stats *stats)
+{
+ struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+ u64 *mib_stats;
+ int ret;
+ int mib_txb_id, mib_rxb_id;
+
+ if (!ar8xxx_has_mib_counters(priv))
+ return -EOPNOTSUPP;
+
+ if (port >= dev->ports)
+ return -EINVAL;
+
+ switch (priv->chip_ver) {
+ case AR8XXX_VER_AR8216:
+ mib_txb_id = AR8216_MIB_TXB_ID;
+ mib_rxb_id = AR8216_MIB_RXB_ID;
+ break;
+ case AR8XXX_VER_AR8236:
+ case AR8XXX_VER_AR8316:
+ case AR8XXX_VER_AR8327:
+ case AR8XXX_VER_AR8337:
+ mib_txb_id = AR8236_MIB_TXB_ID;
+ mib_rxb_id = AR8236_MIB_RXB_ID;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ mutex_lock(&priv->mib_lock);
+ ret = ar8xxx_mib_capture(priv);
+ if (ret)
+ goto unlock;
+
+ ar8xxx_mib_fetch_port_stat(priv, port, false);
+
+ mib_stats = &priv->mib_stats[port * priv->chip->num_mibs];
+
+ stats->tx_bytes = mib_stats[mib_txb_id];
+ stats->rx_bytes = mib_stats[mib_rxb_id];
+
+ ret = 0;
+
+unlock:
+ mutex_unlock(&priv->mib_lock);
+ return ret;
+}
+
static const struct switch_attr ar8xxx_sw_attr_globals[] = {
{
.type = SWITCH_TYPE_INT,
.apply_config = ar8xxx_sw_hw_apply,
.reset_switch = ar8xxx_sw_reset_switch,
.get_port_link = ar8xxx_sw_get_port_link,
+ .get_port_stats = ar8xxx_sw_get_port_stats,
};
static const struct ar8xxx_chip ar8216_chip = {
priv->phy = phydev;
- if (phydev->addr != 0) {
+ if (phydev->mdio.addr != 0) {
if (chip_is_ar8316(priv)) {
/* switch device has been initialized, reinit */
priv->dev.ports = (AR8216_NUM_PORTS - 1);
/* flush ARL entries for this port if it went down*/
if (!link_new)
priv->chip->atu_flush_port(priv, i);
- dev_info(&priv->phy->dev, "Port %d is %s\n",
+ dev_info(&priv->phy->mdio.dev, "Port %d is %s\n",
i, link_new ? "up" : "down");
}
if (phydev->state == PHY_CHANGELINK)
ar8xxx_check_link_states(priv);
- if (phydev->addr != 0)
+ if (phydev->mdio.addr != 0)
return genphy_read_status(phydev);
- ar8216_read_port_link(priv, phydev->addr, &link);
+ ar8216_read_port_link(priv, phydev->mdio.addr, &link);
phydev->link = !!link.link;
if (!phydev->link)
return 0;
static int
ar8xxx_phy_config_aneg(struct phy_device *phydev)
{
- if (phydev->addr == 0)
+ if (phydev->mdio.addr == 0)
return 0;
return genphy_config_aneg(phydev);
int ret;
/* skip PHYs at unused adresses */
- if (phydev->addr != 0 && phydev->addr != 4)
+ if (phydev->mdio.addr != 0 && phydev->mdio.addr != 4)
return -ENODEV;
- if (!ar8xxx_is_possible(phydev->bus))
+ if (!ar8xxx_is_possible(phydev->mdio.bus))
return -ENODEV;
mutex_lock(&ar8xxx_dev_list_lock);
list_for_each_entry(priv, &ar8xxx_dev_list, list)
- if (priv->mii_bus == phydev->bus)
+ if (priv->mii_bus == phydev->mdio.bus)
goto found;
priv = ar8xxx_create();
goto unlock;
}
- priv->mii_bus = phydev->bus;
+ priv->mii_bus = phydev->mdio.bus;
ret = ar8xxx_probe_switch(priv);
if (ret)
found:
priv->use_count++;
- if (phydev->addr == 0) {
+ if (phydev->mdio.addr == 0) {
if (ar8xxx_has_gige(priv)) {
phydev->supported = SUPPORTED_1000baseT_Full;
phydev->advertising = ADVERTISED_1000baseT_Full;
ar8xxx_free(priv);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
static int
ar8xxx_phy_soft_reset(struct phy_device *phydev)
{
/* we don't need an extra reset */
return 0;
}
-#endif
-
-static struct phy_driver ar8xxx_phy_driver = {
- .phy_id = 0x004d0000,
- .name = "Atheros AR8216/AR8236/AR8316",
- .phy_id_mask = 0xffff0000,
- .features = PHY_BASIC_FEATURES,
- .probe = ar8xxx_phy_probe,
- .remove = ar8xxx_phy_remove,
- .detach = ar8xxx_phy_detach,
- .config_init = ar8xxx_phy_config_init,
- .config_aneg = ar8xxx_phy_config_aneg,
- .read_status = ar8xxx_phy_read_status,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
- .soft_reset = ar8xxx_phy_soft_reset,
-#endif
- .driver = { .owner = THIS_MODULE },
-};
-
-int __init
-ar8xxx_init(void)
-{
- return phy_driver_register(&ar8xxx_phy_driver);
-}
-void __exit
-ar8xxx_exit(void)
-{
- phy_driver_unregister(&ar8xxx_phy_driver);
-}
+static struct phy_driver ar8xxx_phy_driver[] = {
+ {
+ .phy_id = 0x004d0000,
+ .name = "Atheros AR8216/AR8236/AR8316",
+ .phy_id_mask = 0xffff0000,
+ .features = PHY_BASIC_FEATURES,
+ .probe = ar8xxx_phy_probe,
+ .remove = ar8xxx_phy_remove,
+ .detach = ar8xxx_phy_detach,
+ .config_init = ar8xxx_phy_config_init,
+ .config_aneg = ar8xxx_phy_config_aneg,
+ .read_status = ar8xxx_phy_read_status,
+ .soft_reset = ar8xxx_phy_soft_reset,
+ }
+};
-module_init(ar8xxx_init);
-module_exit(ar8xxx_exit);
+module_phy_driver(ar8xxx_phy_driver);
MODULE_LICENSE("GPL");