mirror of https://gitee.com/openkylin/linux.git
Merge branch 'dpaa2-mac-various-updates'
Ioana Ciornei says: ==================== dpaa2-mac: various updates The first two patches of this series extends the MAC statistics support to also work for network interfaces which have their link status handled by firmware (TYPE_FIXED). The next two patches are fixing a sporadic problem which happens when the connected DPMAC object is not yet discovered by the fsl-mc bus, thus the dpaa2-eth is not able to get a reference to it. A referred probe will be requested in this case. Finally, the last two patches make some cosmetic changes, mostly removing comments and unnecessary checks. Changes in v2: - replaced IS_ERR_OR_NULL() by IS_ERR() in patch 4/6 - reworded the commit message of patch 6/6 ==================== Link: https://lore.kernel.org/r/20210108090727.866283-1-ciorneiioana@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
430cc4841f
|
@ -840,6 +840,15 @@ struct fsl_mc_device *fsl_mc_get_endpoint(struct fsl_mc_device *mc_dev)
|
|||
endpoint_desc.id = endpoint2.id;
|
||||
endpoint = fsl_mc_device_lookup(&endpoint_desc, mc_bus_dev);
|
||||
|
||||
/*
|
||||
* We know that the device has an endpoint because we verified by
|
||||
* interrogating the firmware. This is the case when the device was not
|
||||
* yet discovered by the fsl-mc bus, thus the lookup returned NULL.
|
||||
* Differentiate this case by returning EPROBE_DEFER.
|
||||
*/
|
||||
if (!endpoint)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
return endpoint;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsl_mc_get_endpoint);
|
||||
|
|
|
@ -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
|
||||
* to manually update the netif_carrier.
|
||||
*/
|
||||
if (priv->mac)
|
||||
if (dpaa2_eth_is_type_phy(priv))
|
||||
goto out;
|
||||
|
||||
/* Chech link state; speed / duplex changes are not treated yet */
|
||||
|
@ -1730,7 +1730,7 @@ static int dpaa2_eth_open(struct net_device *net_dev)
|
|||
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;
|
||||
* make sure we don't race against the link up notification,
|
||||
* which may come immediately after dpni_enable();
|
||||
|
@ -1752,7 +1752,7 @@ static int dpaa2_eth_open(struct net_device *net_dev)
|
|||
goto enable_err;
|
||||
}
|
||||
|
||||
if (priv->mac)
|
||||
if (dpaa2_eth_is_type_phy(priv))
|
||||
phylink_start(priv->mac->phylink);
|
||||
|
||||
return 0;
|
||||
|
@ -1826,11 +1826,11 @@ static int dpaa2_eth_stop(struct net_device *net_dev)
|
|||
int dpni_enabled = 0;
|
||||
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_carrier_off(net_dev);
|
||||
} else {
|
||||
phylink_stop(priv->mac->phylink);
|
||||
}
|
||||
|
||||
/* 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)
|
|||
if (cmd == SIOCSHWTSTAMP)
|
||||
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 -EOPNOTSUPP;
|
||||
|
@ -4042,10 +4042,11 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
|
|||
|
||||
dpni_dev = to_fsl_mc_device(priv->net_dev->dev.parent);
|
||||
dpmac_dev = fsl_mc_get_endpoint(dpni_dev);
|
||||
if (IS_ERR_OR_NULL(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type)
|
||||
return 0;
|
||||
|
||||
if (dpaa2_mac_is_type_fixed(dpmac_dev, priv->mc_io))
|
||||
if (PTR_ERR(dpmac_dev) == -EPROBE_DEFER)
|
||||
return PTR_ERR(dpmac_dev);
|
||||
|
||||
if (IS_ERR(dpmac_dev) || dpmac_dev->dev.type != &fsl_mc_bus_dpmac_type)
|
||||
return 0;
|
||||
|
||||
mac = kzalloc(sizeof(struct dpaa2_mac), GFP_KERNEL);
|
||||
|
@ -4056,23 +4057,35 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv)
|
|||
mac->mc_io = priv->mc_io;
|
||||
mac->net_dev = priv->net_dev;
|
||||
|
||||
err = dpaa2_mac_connect(mac);
|
||||
if (err) {
|
||||
netdev_err(priv->net_dev, "Error connecting to the MAC endpoint\n");
|
||||
kfree(mac);
|
||||
return err;
|
||||
}
|
||||
err = dpaa2_mac_open(mac);
|
||||
if (err)
|
||||
goto err_free_mac;
|
||||
priv->mac = mac;
|
||||
|
||||
if (dpaa2_eth_is_type_phy(priv)) {
|
||||
err = dpaa2_mac_connect(mac);
|
||||
if (err) {
|
||||
netdev_err(priv->net_dev, "Error connecting to the MAC endpoint\n");
|
||||
goto err_close_mac;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_close_mac:
|
||||
dpaa2_mac_close(mac);
|
||||
priv->mac = NULL;
|
||||
err_free_mac:
|
||||
kfree(mac);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void dpaa2_eth_disconnect_mac(struct dpaa2_eth_priv *priv)
|
||||
{
|
||||
if (!priv->mac)
|
||||
return;
|
||||
if (dpaa2_eth_is_type_phy(priv))
|
||||
dpaa2_mac_disconnect(priv->mac);
|
||||
|
||||
dpaa2_mac_disconnect(priv->mac);
|
||||
dpaa2_mac_close(priv->mac);
|
||||
kfree(priv->mac);
|
||||
priv->mac = NULL;
|
||||
}
|
||||
|
@ -4101,7 +4114,7 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
|
|||
dpaa2_eth_update_tx_fqids(priv);
|
||||
|
||||
rtnl_lock();
|
||||
if (priv->mac)
|
||||
if (dpaa2_eth_has_mac(priv))
|
||||
dpaa2_eth_disconnect_mac(priv);
|
||||
else
|
||||
dpaa2_eth_connect_mac(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;
|
||||
}
|
||||
|
||||
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_cls(struct net_device *net_dev, 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)
|
|||
{
|
||||
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 -EOPNOTSUPP;
|
||||
|
@ -97,7 +97,7 @@ dpaa2_eth_get_link_ksettings(struct net_device *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,
|
||||
link_settings);
|
||||
|
||||
|
@ -115,7 +115,7 @@ dpaa2_eth_set_link_ksettings(struct net_device *net_dev,
|
|||
{
|
||||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
||||
|
||||
if (!priv->mac)
|
||||
if (!dpaa2_eth_is_type_phy(priv))
|
||||
return -ENOTSUPP;
|
||||
|
||||
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,
|
|||
struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ static int dpaa2_eth_set_pauseparam(struct net_device *net_dev,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (priv->mac)
|
||||
if (dpaa2_eth_is_type_phy(priv))
|
||||
return phylink_ethtool_set_pauseparam(priv->mac->phylink,
|
||||
pause);
|
||||
if (pause->autoneg)
|
||||
|
@ -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);
|
||||
p += ETH_GSTRING_LEN;
|
||||
}
|
||||
if (priv->mac)
|
||||
if (dpaa2_eth_has_mac(priv))
|
||||
dpaa2_mac_get_strings(p);
|
||||
break;
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ static int dpaa2_eth_get_sset_count(struct net_device *net_dev, int sset)
|
|||
|
||||
switch (sset) {
|
||||
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();
|
||||
return num_ss_stats;
|
||||
default:
|
||||
|
@ -313,7 +313,7 @@ static void dpaa2_eth_get_ethtool_stats(struct net_device *net_dev,
|
|||
}
|
||||
*(data + i++) = buf_cnt;
|
||||
|
||||
if (priv->mac)
|
||||
if (dpaa2_eth_has_mac(priv))
|
||||
dpaa2_mac_get_ethtool_stats(priv->mac, data + i);
|
||||
}
|
||||
|
||||
|
|
|
@ -174,30 +174,22 @@ static void dpaa2_mac_link_up(struct phylink_config *config,
|
|||
|
||||
dpmac_state->up = 1;
|
||||
|
||||
if (mac->if_link_type == DPMAC_LINK_TYPE_PHY) {
|
||||
/* If the DPMAC is configured for PHY mode, we need
|
||||
* to pass the link parameters to the MC firmware.
|
||||
*/
|
||||
dpmac_state->rate = speed;
|
||||
dpmac_state->rate = speed;
|
||||
|
||||
if (duplex == DUPLEX_HALF)
|
||||
dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
|
||||
else if (duplex == DUPLEX_FULL)
|
||||
dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX;
|
||||
if (duplex == DUPLEX_HALF)
|
||||
dpmac_state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
|
||||
else if (duplex == DUPLEX_FULL)
|
||||
dpmac_state->options &= ~DPMAC_LINK_OPT_HALF_DUPLEX;
|
||||
|
||||
/* This is lossy; the firmware really should take the pause
|
||||
* enablement status rather than pause/asym pause status.
|
||||
*/
|
||||
if (rx_pause)
|
||||
dpmac_state->options |= DPMAC_LINK_OPT_PAUSE;
|
||||
else
|
||||
dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE;
|
||||
if (rx_pause)
|
||||
dpmac_state->options |= DPMAC_LINK_OPT_PAUSE;
|
||||
else
|
||||
dpmac_state->options &= ~DPMAC_LINK_OPT_PAUSE;
|
||||
|
||||
if (rx_pause ^ tx_pause)
|
||||
dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE;
|
||||
else
|
||||
dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE;
|
||||
}
|
||||
if (rx_pause ^ tx_pause)
|
||||
dpmac_state->options |= DPMAC_LINK_OPT_ASYM_PAUSE;
|
||||
else
|
||||
dpmac_state->options &= ~DPMAC_LINK_OPT_ASYM_PAUSE;
|
||||
|
||||
err = dpmac_set_link_state(mac->mc_io, 0,
|
||||
mac->mc_dev->mc_handle, dpmac_state);
|
||||
|
@ -228,32 +220,6 @@ static const struct phylink_mac_ops dpaa2_mac_phylink_ops = {
|
|||
.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,
|
||||
struct device_node *dpmac_node, int id)
|
||||
{
|
||||
|
@ -302,36 +268,20 @@ static void dpaa2_pcs_destroy(struct dpaa2_mac *mac)
|
|||
|
||||
int dpaa2_mac_connect(struct dpaa2_mac *mac)
|
||||
{
|
||||
struct fsl_mc_device *dpmac_dev = mac->mc_dev;
|
||||
struct net_device *net_dev = mac->net_dev;
|
||||
struct device_node *dpmac_node;
|
||||
struct phylink *phylink;
|
||||
struct dpmac_attr attr;
|
||||
int err;
|
||||
|
||||
err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id,
|
||||
&dpmac_dev->mc_handle);
|
||||
if (err || !dpmac_dev->mc_handle) {
|
||||
netdev_err(net_dev, "dpmac_open() = %d\n", err);
|
||||
mac->if_link_type = mac->attr.link_type;
|
||||
|
||||
dpmac_node = dpaa2_mac_get_node(mac->attr.id);
|
||||
if (!dpmac_node) {
|
||||
netdev_err(net_dev, "No dpmac@%d node found.\n", mac->attr.id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle, &attr);
|
||||
if (err) {
|
||||
netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err);
|
||||
goto err_close_dpmac;
|
||||
}
|
||||
|
||||
mac->if_link_type = attr.link_type;
|
||||
|
||||
dpmac_node = dpaa2_mac_get_node(attr.id);
|
||||
if (!dpmac_node) {
|
||||
netdev_err(net_dev, "No dpmac@%d node found.\n", attr.id);
|
||||
err = -ENODEV;
|
||||
goto err_close_dpmac;
|
||||
}
|
||||
|
||||
err = dpaa2_mac_get_if_mode(dpmac_node, attr);
|
||||
err = dpaa2_mac_get_if_mode(dpmac_node, mac->attr);
|
||||
if (err < 0) {
|
||||
err = -EINVAL;
|
||||
goto err_put_node;
|
||||
|
@ -351,9 +301,9 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
|
|||
goto err_put_node;
|
||||
}
|
||||
|
||||
if (attr.link_type == DPMAC_LINK_TYPE_PHY &&
|
||||
attr.eth_if != DPMAC_ETH_IF_RGMII) {
|
||||
err = dpaa2_pcs_create(mac, dpmac_node, attr.id);
|
||||
if (mac->attr.link_type == DPMAC_LINK_TYPE_PHY &&
|
||||
mac->attr.eth_if != DPMAC_ETH_IF_RGMII) {
|
||||
err = dpaa2_pcs_create(mac, dpmac_node, mac->attr.id);
|
||||
if (err)
|
||||
goto err_put_node;
|
||||
}
|
||||
|
@ -389,8 +339,7 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
|
|||
dpaa2_pcs_destroy(mac);
|
||||
err_put_node:
|
||||
of_node_put(dpmac_node);
|
||||
err_close_dpmac:
|
||||
dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -402,8 +351,40 @@ void dpaa2_mac_disconnect(struct dpaa2_mac *mac)
|
|||
phylink_disconnect_phy(mac->phylink);
|
||||
phylink_destroy(mac->phylink);
|
||||
dpaa2_pcs_destroy(mac);
|
||||
}
|
||||
|
||||
dpmac_close(mac->mc_io, 0, mac->mc_dev->mc_handle);
|
||||
int dpaa2_mac_open(struct dpaa2_mac *mac)
|
||||
{
|
||||
struct fsl_mc_device *dpmac_dev = mac->mc_dev;
|
||||
struct net_device *net_dev = mac->net_dev;
|
||||
int err;
|
||||
|
||||
err = dpmac_open(mac->mc_io, 0, dpmac_dev->obj_desc.id,
|
||||
&dpmac_dev->mc_handle);
|
||||
if (err || !dpmac_dev->mc_handle) {
|
||||
netdev_err(net_dev, "dpmac_open() = %d\n", err);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = dpmac_get_attributes(mac->mc_io, 0, dpmac_dev->mc_handle,
|
||||
&mac->attr);
|
||||
if (err) {
|
||||
netdev_err(net_dev, "dpmac_get_attributes() = %d\n", err);
|
||||
goto err_close_dpmac;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_close_dpmac:
|
||||
dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
|
||||
return err;
|
||||
}
|
||||
|
||||
void dpaa2_mac_close(struct dpaa2_mac *mac)
|
||||
{
|
||||
struct fsl_mc_device *dpmac_dev = mac->mc_dev;
|
||||
|
||||
dpmac_close(mac->mc_io, 0, dpmac_dev->mc_handle);
|
||||
}
|
||||
|
||||
static char dpaa2_mac_ethtool_stats[][ETH_GSTRING_LEN] = {
|
||||
|
|
|
@ -17,6 +17,7 @@ struct dpaa2_mac {
|
|||
struct dpmac_link_state state;
|
||||
struct net_device *net_dev;
|
||||
struct fsl_mc_io *mc_io;
|
||||
struct dpmac_attr attr;
|
||||
|
||||
struct phylink_config phylink_config;
|
||||
struct phylink *phylink;
|
||||
|
@ -28,6 +29,10 @@ struct dpaa2_mac {
|
|||
bool dpaa2_mac_is_type_fixed(struct fsl_mc_device *dpmac_dev,
|
||||
struct fsl_mc_io *mc_io);
|
||||
|
||||
int dpaa2_mac_open(struct dpaa2_mac *mac);
|
||||
|
||||
void dpaa2_mac_close(struct dpaa2_mac *mac);
|
||||
|
||||
int dpaa2_mac_connect(struct dpaa2_mac *mac);
|
||||
|
||||
void dpaa2_mac_disconnect(struct dpaa2_mac *mac);
|
||||
|
|
Loading…
Reference in New Issue