The private data of the switch is already
allocated in ar8216_priv, assign that to
each PHY on the same MDIO bus. Also remove
the redundant code from ar8216_config_init.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
SVN-Revision: 35559
int mib_next_port;
u64 *mib_stats;
int mib_next_port;
u64 *mib_stats;
+ struct list_head list;
+ unsigned int use_count;
+
/* all fields below are cleared on reset */
bool vlan;
u16 vlan_id[AR8X16_MAX_VLANS];
/* all fields below are cleared on reset */
bool vlan;
u16 vlan_id[AR8X16_MAX_VLANS];
MIB_DESC(1, AR8236_STATS_TXLATECOL, "TxLateCol"),
};
MIB_DESC(1, AR8236_STATS_TXLATECOL, "TxLateCol"),
};
+static DEFINE_MUTEX(ar8xxx_dev_list_lock);
+static LIST_HEAD(ar8xxx_dev_list);
+
static inline struct ar8216_priv *
swdev_to_ar8216(struct switch_dev *swdev)
{
static inline struct ar8216_priv *
swdev_to_ar8216(struct switch_dev *swdev)
{
struct switch_dev *swdev;
int ret;
struct switch_dev *swdev;
int ret;
- if (!priv) {
- priv = ar8xxx_create_mii(phydev->bus);
- if (priv == NULL)
- return -ENOMEM;
-
- ret = ar8xxx_probe_switch(priv);
- if (ret)
- goto err_free_priv;
- }
+ if (WARN_ON(!priv))
+ return -ENODEV;
if (chip_is_ar8316(priv)) {
/* check if we're attaching to the switch twice */
phydev = phydev->bus->phy_map[0];
if (chip_is_ar8316(priv)) {
/* check if we're attaching to the switch twice */
phydev = phydev->bus->phy_map[0];
- if (!phydev) {
- ar8xxx_free(priv);
/* switch device has not been initialized, reuse priv */
if (!phydev->priv) {
priv->port4_phy = true;
priv->dev.ports = (AR8216_NUM_PORTS - 1);
/* switch device has not been initialized, reuse priv */
if (!phydev->priv) {
priv->port4_phy = true;
priv->dev.ports = (AR8216_NUM_PORTS - 1);
/* switch device has been initialized, reinit */
/* switch device has been initialized, reinit */
priv->dev.ports = (AR8216_NUM_PORTS - 1);
priv->initialized = false;
priv->port4_phy = true;
priv->dev.ports = (AR8216_NUM_PORTS - 1);
priv->initialized = false;
priv->port4_phy = true;
swdev = &priv->dev;
ret = register_switch(swdev, phydev->attached_dev);
if (ret)
swdev = &priv->dev;
ret = register_switch(swdev, phydev->attached_dev);
if (ret)
pr_info("%s: %s switch driver attached.\n",
phydev->attached_dev->name, swdev->name);
pr_info("%s: %s switch driver attached.\n",
phydev->attached_dev->name, swdev->name);
err_unregister_switch:
unregister_switch(&priv->dev);
err_unregister_switch:
unregister_switch(&priv->dev);
-err_free_priv:
- ar8xxx_free(priv);
- phydev->priv = NULL;
if (!ar8xxx_is_possible(phydev->bus))
return -ENODEV;
if (!ar8xxx_is_possible(phydev->bus))
return -ENODEV;
- priv = ar8xxx_create_mii(phydev->bus);
- if (priv == NULL)
- return -ENOMEM;
+ mutex_lock(&ar8xxx_dev_list_lock);
+ list_for_each_entry(priv, &ar8xxx_dev_list, list)
+ if (priv->mii_bus == phydev->bus)
+ goto found;
+ priv = ar8xxx_create_mii(phydev->bus);
+ if (priv == NULL) {
+ ret = -ENOMEM;
+ goto unlock;
+ }
ret = ar8xxx_probe_switch(priv);
if (ret)
ret = ar8xxx_probe_switch(priv);
if (ret)
if (phydev->addr == 0) {
if (ar8xxx_has_gige(priv)) {
phydev->supported = SUPPORTED_1000baseT_Full;
if (phydev->addr == 0) {
if (ar8xxx_has_gige(priv)) {
phydev->supported = SUPPORTED_1000baseT_Full;
+ phydev->priv = priv;
+ priv->use_count++;
+ list_add(&priv->list, &ar8xxx_dev_list);
+
+ mutex_unlock(&ar8xxx_dev_list_lock);
+
+ return 0;
+
+free_priv:
+unlock:
+ mutex_unlock(&ar8xxx_dev_list_lock);
{
struct ar8216_priv *priv = phydev->priv;
{
struct ar8216_priv *priv = phydev->priv;
return;
phydev->priv = NULL;
return;
phydev->priv = NULL;
+ if (--priv->use_count > 0)
+ return;
- if (phydev->addr == 0)
- unregister_switch(&priv->dev);
+ mutex_lock(&ar8xxx_dev_list_lock);
+ list_del(&priv->list);
+ mutex_unlock(&ar8xxx_dev_list_lock);
+ unregister_switch(&priv->dev);
ar8xxx_mib_stop(priv);
ar8xxx_free(priv);
}
ar8xxx_mib_stop(priv);
ar8xxx_free(priv);
}