Commit d87e6063 authored by Ioana Ciornei's avatar Ioana Ciornei Committed by Jakub Kicinski

dpaa2-mac: export MAC counters even when in TYPE_FIXED

If the network interface object is connected to a MAC of TYPE_FIXED, the
link status management is handled exclusively by the firmware. This does
not mean that the driver cannot access the MAC counters and export them
in ethtool.

For this to happen, we open the attached dpmac device and keep a pointer
to it in priv->mac. Because of this, all the checks in the driver of the
following form 'if (priv->mac)' have to be updated to actually check
the dpmac attribute and not rely on the presence of a non-NULL value.
Signed-off-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 095dca16
...@@ -1691,7 +1691,7 @@ static int dpaa2_eth_link_state_update(struct dpaa2_eth_priv *priv) ...@@ -1691,7 +1691,7 @@ static int dpaa2_eth_link_state_update(struct dpaa2_eth_priv *priv)
/* When we manage the MAC/PHY using phylink there is no need /* When we manage the MAC/PHY using phylink there is no need
* to manually update the netif_carrier. * to manually update the netif_carrier.
*/ */
if (priv->mac) if (dpaa2_eth_is_type_phy(priv))
goto out; goto out;
/* Chech link state; speed / duplex changes are not treated yet */ /* Chech link state; speed / duplex changes are not treated yet */
...@@ -1730,7 +1730,7 @@ static int dpaa2_eth_open(struct net_device *net_dev) ...@@ -1730,7 +1730,7 @@ static int dpaa2_eth_open(struct net_device *net_dev)
priv->dpbp_dev->obj_desc.id, priv->bpid); priv->dpbp_dev->obj_desc.id, priv->bpid);
} }
if (!priv->mac) { if (!dpaa2_eth_is_type_phy(priv)) {
/* We'll only start the txqs when the link is actually ready; /* We'll only start the txqs when the link is actually ready;
* make sure we don't race against the link up notification, * make sure we don't race against the link up notification,
* which may come immediately after dpni_enable(); * which may come immediately after dpni_enable();
...@@ -1752,7 +1752,7 @@ static int dpaa2_eth_open(struct net_device *net_dev) ...@@ -1752,7 +1752,7 @@ static int dpaa2_eth_open(struct net_device *net_dev)
goto enable_err; goto enable_err;
} }
if (priv->mac) if (dpaa2_eth_is_type_phy(priv))
phylink_start(priv->mac->phylink); phylink_start(priv->mac->phylink);
return 0; return 0;
...@@ -1826,11 +1826,11 @@ static int dpaa2_eth_stop(struct net_device *net_dev) ...@@ -1826,11 +1826,11 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
int dpni_enabled = 0; int dpni_enabled = 0;
int retries = 10; int retries = 10;
if (!priv->mac) { if (dpaa2_eth_is_type_phy(priv)) {
phylink_stop(priv->mac->phylink);
} else {
netif_tx_stop_all_queues(net_dev); netif_tx_stop_all_queues(net_dev);
netif_carrier_off(net_dev); netif_carrier_off(net_dev);
} else {
phylink_stop(priv->mac->phylink);
} }
/* On dpni_disable(), the MC firmware will: /* On dpni_disable(), the MC firmware will:
...@@ -2115,7 +2115,7 @@ static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -2115,7 +2115,7 @@ static int dpaa2_eth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (cmd == SIOCSHWTSTAMP) if (cmd == SIOCSHWTSTAMP)
return dpaa2_eth_ts_ioctl(dev, rq, cmd); return dpaa2_eth_ts_ioctl(dev, rq, cmd);
if (priv->mac) if (dpaa2_eth_is_type_phy(priv))
return phylink_mii_ioctl(priv->mac->phylink, rq, cmd); return phylink_mii_ioctl(priv->mac->phylink, rq, cmd);
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -4045,9 +4045,6 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv) ...@@ -4045,9 +4045,6 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
if (IS_ERR_OR_NULL(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type) if (IS_ERR_OR_NULL(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type)
return 0; return 0;
if (dpaa2_mac_is_type_fixed(dpmac_dev, priv->mc_io))
return 0;
mac = kzalloc(sizeof(struct dpaa2_mac), GFP_KERNEL); mac = kzalloc(sizeof(struct dpaa2_mac), GFP_KERNEL);
if (!mac) if (!mac)
return -ENOMEM; return -ENOMEM;
...@@ -4059,18 +4056,21 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv) ...@@ -4059,18 +4056,21 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
err = dpaa2_mac_open(mac); err = dpaa2_mac_open(mac);
if (err) if (err)
goto err_free_mac; goto err_free_mac;
priv->mac = mac;
if (dpaa2_eth_is_type_phy(priv)) {
err = dpaa2_mac_connect(mac); err = dpaa2_mac_connect(mac);
if (err) { if (err) {
netdev_err(priv->net_dev, "Error connecting to the MAC endpoint\n"); netdev_err(priv->net_dev, "Error connecting to the MAC endpoint\n");
goto err_close_mac; goto err_close_mac;
} }
priv->mac = mac; }
return 0; return 0;
err_close_mac: err_close_mac:
dpaa2_mac_close(mac); dpaa2_mac_close(mac);
priv->mac = NULL;
err_free_mac: err_free_mac:
kfree(mac); kfree(mac);
return err; return err;
...@@ -4078,10 +4078,9 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv) ...@@ -4078,10 +4078,9 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv) static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
{ {
if (!priv->mac) if (dpaa2_eth_is_type_phy(priv))
return;
dpaa2_mac_disconnect(priv->mac); dpaa2_mac_disconnect(priv->mac);
dpaa2_mac_close(priv->mac); dpaa2_mac_close(priv->mac);
kfree(priv->mac); kfree(priv->mac);
priv->mac = NULL; priv->mac = NULL;
...@@ -4111,7 +4110,7 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg) ...@@ -4111,7 +4110,7 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
dpaa2_eth_update_tx_fqids(priv); dpaa2_eth_update_tx_fqids(priv);
rtnl_lock(); rtnl_lock();
if (priv->mac) if (dpaa2_eth_has_mac(priv))
dpaa2_eth_disconnect_mac(priv); dpaa2_eth_disconnect_mac(priv);
else else
dpaa2_eth_connect_mac(priv); dpaa2_eth_connect_mac(priv);
......
...@@ -693,6 +693,19 @@ static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv) ...@@ -693,6 +693,19 @@ static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv)
return priv->tx_data_offset - DPAA2_ETH_RX_HWA_SIZE; return priv->tx_data_offset - DPAA2_ETH_RX_HWA_SIZE;
} }
static inline bool dpaa2_eth_is_type_phy(struct dpaa2_eth_priv *priv)
{
if (priv->mac && priv->mac->attr.link_type == DPMAC_LINK_TYPE_PHY)
return true;
return false;
}
static inline bool dpaa2_eth_has_mac(struct dpaa2_eth_priv *priv)
{
return priv->mac ? true : false;
}
int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags); int dpaa2_eth_set_hash(struct net_device *net_dev, u64 flags);
int dpaa2_eth_set_cls(struct net_device *net_dev, u64 key); int dpaa2_eth_set_cls(struct net_device *net_dev, u64 key);
int dpaa2_eth_cls_key_size(u64 key); int dpaa2_eth_cls_key_size(u64 key);
......
...@@ -85,7 +85,7 @@ static int dpaa2_eth_nway_reset(struct net_device *net_dev) ...@@ -85,7 +85,7 @@ static int dpaa2_eth_nway_reset(struct net_device *net_dev)
{ {
struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
if (priv->mac) if (dpaa2_eth_is_type_phy(priv))
return phylink_ethtool_nway_reset(priv->mac->phylink); return phylink_ethtool_nway_reset(priv->mac->phylink);
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -97,7 +97,7 @@ dpaa2_eth_get_link_ksettings(struct net_device *net_dev, ...@@ -97,7 +97,7 @@ dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
{ {
struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
if (priv->mac) if (dpaa2_eth_is_type_phy(priv))
return phylink_ethtool_ksettings_get(priv->mac->phylink, return phylink_ethtool_ksettings_get(priv->mac->phylink,
link_settings); link_settings);
...@@ -115,7 +115,7 @@ dpaa2_eth_set_link_ksettings(struct net_device *net_dev, ...@@ -115,7 +115,7 @@ dpaa2_eth_set_link_ksettings(struct net_device *net_dev,
{ {
struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
if (!priv->mac) if (!dpaa2_eth_is_type_phy(priv))
return -ENOTSUPP; return -ENOTSUPP;
return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings); return phylink_ethtool_ksettings_set(priv->mac->phylink, link_settings);
...@@ -127,7 +127,7 @@ static void dpaa2_eth_get_pauseparam(struct net_device *net_dev, ...@@ -127,7 +127,7 @@ static void dpaa2_eth_get_pauseparam(struct net_device *net_dev,
struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
u64 link_options = priv->link_state.options; u64 link_options = priv->link_state.options;
if (priv->mac) { if (dpaa2_eth_is_type_phy(priv)) {
phylink_ethtool_get_pauseparam(priv->mac->phylink, pause); phylink_ethtool_get_pauseparam(priv->mac->phylink, pause);
return; return;
} }
...@@ -150,7 +150,7 @@ static int dpaa2_eth_set_pauseparam(struct net_device *net_dev, ...@@ -150,7 +150,7 @@ static int dpaa2_eth_set_pauseparam(struct net_device *net_dev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (priv->mac) if (dpaa2_eth_is_type_phy(priv))
return phylink_ethtool_set_pauseparam(priv->mac->phylink, return phylink_ethtool_set_pauseparam(priv->mac->phylink,
pause); pause);
if (pause->autoneg) if (pause->autoneg)
...@@ -198,7 +198,7 @@ static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset, ...@@ -198,7 +198,7 @@ static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
strlcpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN); strlcpy(p, dpaa2_ethtool_extras[i], ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
if (priv->mac) if (dpaa2_eth_has_mac(priv))
dpaa2_mac_get_strings(p); dpaa2_mac_get_strings(p);
break; break;
} }
...@@ -211,7 +211,7 @@ static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset) ...@@ -211,7 +211,7 @@ static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset)
switch (sset) { switch (sset) {
case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */ case ETH_SS_STATS: /* ethtool_get_stats(), ethtool_get_drvinfo() */
if (priv->mac) if (dpaa2_eth_has_mac(priv))
num_ss_stats += dpaa2_mac_get_sset_count(); num_ss_stats += dpaa2_mac_get_sset_count();
return num_ss_stats; return num_ss_stats;
default: default:
...@@ -313,7 +313,7 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev, ...@@ -313,7 +313,7 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
} }
*(data + i++) = buf_cnt; *(data + i++) = buf_cnt;
if (priv->mac) if (dpaa2_eth_has_mac(priv))
dpaa2_mac_get_ethtool_stats(priv->mac, data + i); dpaa2_mac_get_ethtool_stats(priv->mac, data + i);
} }
......
...@@ -228,32 +228,6 @@ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = { ...@@ -228,32 +228,6 @@ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
.mac_link_down = dpaa2_mac_link_down, .mac_link_down = dpaa2_mac_link_down,
}; };
bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,
struct fsl_mc_io *mc_io)
{
struct dpmac_attr attr;
bool fixed = false;
u16 mc_handle = 0;
int err;
err = dpmac_open(mc_io, 0, dpmac_dev->obj_desc.id,
&mc_handle);
if (err || !mc_handle)
return false;
err = dpmac_get_attributes(mc_io, 0, mc_handle, &attr);
if (err)
goto out;
if (attr.link_type == DPMAC_LINK_TYPE_FIXED)
fixed = true;
out:
dpmac_close(mc_io, 0, mc_handle);
return fixed;
}
static int dpaa2_pcs_create(struct dpaa2_mac *mac, static int dpaa2_pcs_create(struct dpaa2_mac *mac,
struct device_node *dpmac_node, int id) struct device_node *dpmac_node, int id)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment