summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/freescale
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/freescale')
-rw-r--r--drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c132
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc.c1
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_ethtool.c31
-rw-r--r--drivers/net/ethernet/freescale/enetc/enetc_pf.c3
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c16
-rw-r--r--drivers/net/ethernet/freescale/fsl_pq_mdio.c1
6 files changed, 118 insertions, 66 deletions
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
index e01a246124..f3543a2df6 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -289,7 +289,7 @@ static int dpaa2_switch_port_add_vlan(struct ethsw_port_priv *port_priv,
int err;
if (port_priv->vlans[vid]) {
- netdev_warn(netdev, "VLAN %d already configured\n", vid);
+ netdev_err(netdev, "VLAN %d already configured\n", vid);
return -EEXIST;
}
@@ -1509,9 +1509,9 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
struct device *dev = (struct device *)arg;
struct ethsw_core *ethsw = dev_get_drvdata(dev);
struct ethsw_port_priv *port_priv;
- u32 status = ~0;
int err, if_id;
bool had_mac;
+ u32 status;
err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
DPSW_IRQ_INDEX_IF, &status);
@@ -1523,12 +1523,11 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
if_id = (status & 0xFFFF0000) >> 16;
port_priv = ethsw->ports[if_id];
- if (status & DPSW_IRQ_EVENT_LINK_CHANGED) {
+ if (status & DPSW_IRQ_EVENT_LINK_CHANGED)
dpaa2_switch_port_link_state_update(port_priv->netdev);
- dpaa2_switch_port_set_mac_addr(port_priv);
- }
if (status & DPSW_IRQ_EVENT_ENDPOINT_CHANGED) {
+ dpaa2_switch_port_set_mac_addr(port_priv);
/* We can avoid locking because the "endpoint changed" IRQ
* handler is the only one who changes priv->mac at runtime,
* so we are not racing with anyone.
@@ -1540,20 +1539,20 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg)
dpaa2_switch_port_connect_mac(port_priv);
}
-out:
err = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
DPSW_IRQ_INDEX_IF, status);
if (err)
dev_err(dev, "Can't clear irq status (err %d)\n", err);
+out:
return IRQ_HANDLED;
}
static int dpaa2_switch_setup_irqs(struct fsl_mc_device *sw_dev)
{
+ u32 mask = DPSW_IRQ_EVENT_LINK_CHANGED | DPSW_IRQ_EVENT_ENDPOINT_CHANGED;
struct device *dev = &sw_dev->dev;
struct ethsw_core *ethsw = dev_get_drvdata(dev);
- u32 mask = DPSW_IRQ_EVENT_LINK_CHANGED;
struct fsl_mc_device_irq *irq;
int err;
@@ -1775,8 +1774,10 @@ int dpaa2_switch_port_vlans_add(struct net_device *netdev,
/* Make sure that the VLAN is not already configured
* on the switch port
*/
- if (port_priv->vlans[vlan->vid] & ETHSW_VLAN_MEMBER)
+ if (port_priv->vlans[vlan->vid] & ETHSW_VLAN_MEMBER) {
+ netdev_err(netdev, "VLAN %d already configured\n", vlan->vid);
return -EEXIST;
+ }
/* Check if there is space for a new VLAN */
err = dpsw_get_attributes(ethsw->mc_io, 0, ethsw->dpsw_handle,
@@ -2003,25 +2004,11 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev,
struct netlink_ext_ack *extack)
{
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
+ struct dpaa2_switch_fdb *old_fdb = port_priv->fdb;
struct ethsw_core *ethsw = port_priv->ethsw_data;
- struct ethsw_port_priv *other_port_priv;
- struct net_device *other_dev;
- struct list_head *iter;
bool learn_ena;
int err;
- netdev_for_each_lower_dev(upper_dev, other_dev, iter) {
- if (!dpaa2_switch_port_dev_check(other_dev))
- continue;
-
- other_port_priv = netdev_priv(other_dev);
- if (other_port_priv->ethsw_data != port_priv->ethsw_data) {
- NL_SET_ERR_MSG_MOD(extack,
- "Interface from a different DPSW is in the bridge already");
- return -EINVAL;
- }
- }
-
/* Delete the previously manually installed VLAN 1 */
err = dpaa2_switch_port_del_vlan(port_priv, 1);
if (err)
@@ -2039,6 +2026,11 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev,
if (err)
goto err_egress_flood;
+ /* Recreate the egress flood domain of the FDB that we just left. */
+ err = dpaa2_switch_fdb_set_egress_flood(ethsw, old_fdb->fdb_id);
+ if (err)
+ goto err_egress_flood;
+
err = switchdev_bridge_port_offload(netdev, netdev, NULL,
NULL, NULL, false, extack);
if (err)
@@ -2155,6 +2147,10 @@ dpaa2_switch_prechangeupper_sanity_checks(struct net_device *netdev,
struct net_device *upper_dev,
struct netlink_ext_ack *extack)
{
+ struct ethsw_port_priv *port_priv = netdev_priv(netdev);
+ struct ethsw_port_priv *other_port_priv;
+ struct net_device *other_dev;
+ struct list_head *iter;
int err;
if (!br_vlan_enabled(upper_dev)) {
@@ -2169,54 +2165,93 @@ dpaa2_switch_prechangeupper_sanity_checks(struct net_device *netdev,
return 0;
}
+ netdev_for_each_lower_dev(upper_dev, other_dev, iter) {
+ if (!dpaa2_switch_port_dev_check(other_dev))
+ continue;
+
+ other_port_priv = netdev_priv(other_dev);
+ if (other_port_priv->ethsw_data != port_priv->ethsw_data) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Interface from a different DPSW is in the bridge already");
+ return -EINVAL;
+ }
+ }
+
return 0;
}
-static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb,
- unsigned long event, void *ptr)
+static int dpaa2_switch_port_prechangeupper(struct net_device *netdev,
+ struct netdev_notifier_changeupper_info *info)
{
- struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
- struct netdev_notifier_changeupper_info *info = ptr;
struct netlink_ext_ack *extack;
struct net_device *upper_dev;
- int err = 0;
+ int err;
if (!dpaa2_switch_port_dev_check(netdev))
- return NOTIFY_DONE;
+ return 0;
extack = netdev_notifier_info_to_extack(&info->info);
-
- switch (event) {
- case NETDEV_PRECHANGEUPPER:
- upper_dev = info->upper_dev;
- if (!netif_is_bridge_master(upper_dev))
- break;
-
+ upper_dev = info->upper_dev;
+ if (netif_is_bridge_master(upper_dev)) {
err = dpaa2_switch_prechangeupper_sanity_checks(netdev,
upper_dev,
extack);
if (err)
- goto out;
+ return err;
if (!info->linking)
dpaa2_switch_port_pre_bridge_leave(netdev);
+ }
+
+ return 0;
+}
+
+static int dpaa2_switch_port_changeupper(struct net_device *netdev,
+ struct netdev_notifier_changeupper_info *info)
+{
+ struct netlink_ext_ack *extack;
+ struct net_device *upper_dev;
+
+ if (!dpaa2_switch_port_dev_check(netdev))
+ return 0;
+
+ extack = netdev_notifier_info_to_extack(&info->info);
+
+ upper_dev = info->upper_dev;
+ if (netif_is_bridge_master(upper_dev)) {
+ if (info->linking)
+ return dpaa2_switch_port_bridge_join(netdev,
+ upper_dev,
+ extack);
+ else
+ return dpaa2_switch_port_bridge_leave(netdev);
+ }
+
+ return 0;
+}
+
+static int dpaa2_switch_port_netdevice_event(struct notifier_block *nb,
+ unsigned long event, void *ptr)
+{
+ struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
+ int err = 0;
+
+ switch (event) {
+ case NETDEV_PRECHANGEUPPER:
+ err = dpaa2_switch_port_prechangeupper(netdev, ptr);
+ if (err)
+ return notifier_from_errno(err);
break;
case NETDEV_CHANGEUPPER:
- upper_dev = info->upper_dev;
- if (netif_is_bridge_master(upper_dev)) {
- if (info->linking)
- err = dpaa2_switch_port_bridge_join(netdev,
- upper_dev,
- extack);
- else
- err = dpaa2_switch_port_bridge_leave(netdev);
- }
+ err = dpaa2_switch_port_changeupper(netdev, ptr);
+ if (err)
+ return notifier_from_errno(err);
+
break;
}
-out:
- return notifier_from_errno(err);
+ return NOTIFY_DONE;
}
struct ethsw_switchdev_event_work {
@@ -3294,6 +3329,7 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw,
port_netdev->features = NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_STAG_FILTER |
NETIF_F_HW_TC;
+ port_netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
err = dpaa2_switch_port_init(port_priv, port_idx);
if (err)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index cffbf27c46..bfdbdab443 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -3216,4 +3216,5 @@ void enetc_pci_remove(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(enetc_pci_remove);
+MODULE_DESCRIPTION("NXP ENETC Ethernet driver");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
index e993ed04ab..f7753ea5b5 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
@@ -690,25 +690,26 @@ static u32 enetc_get_rxfh_indir_size(struct net_device *ndev)
return priv->si->num_rss;
}
-static int enetc_get_rxfh(struct net_device *ndev, u32 *indir, u8 *key,
- u8 *hfunc)
+static int enetc_get_rxfh(struct net_device *ndev,
+ struct ethtool_rxfh_param *rxfh)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct enetc_hw *hw = &priv->si->hw;
int err = 0, i;
/* return hash function */
- if (hfunc)
- *hfunc = ETH_RSS_HASH_TOP;
+ rxfh->hfunc = ETH_RSS_HASH_TOP;
/* return hash key */
- if (key && hw->port)
+ if (rxfh->key && hw->port)
for (i = 0; i < ENETC_RSSHASH_KEY_SIZE / 4; i++)
- ((u32 *)key)[i] = enetc_port_rd(hw, ENETC_PRSSK(i));
+ ((u32 *)rxfh->key)[i] = enetc_port_rd(hw,
+ ENETC_PRSSK(i));
/* return RSS table */
- if (indir)
- err = enetc_get_rss_table(priv->si, indir, priv->si->num_rss);
+ if (rxfh->indir)
+ err = enetc_get_rss_table(priv->si, rxfh->indir,
+ priv->si->num_rss);
return err;
}
@@ -722,20 +723,22 @@ void enetc_set_rss_key(struct enetc_hw *hw, const u8 *bytes)
}
EXPORT_SYMBOL_GPL(enetc_set_rss_key);
-static int enetc_set_rxfh(struct net_device *ndev, const u32 *indir,
- const u8 *key, const u8 hfunc)
+static int enetc_set_rxfh(struct net_device *ndev,
+ struct ethtool_rxfh_param *rxfh,
+ struct netlink_ext_ack *extack)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct enetc_hw *hw = &priv->si->hw;
int err = 0;
/* set hash key, if PF */
- if (key && hw->port)
- enetc_set_rss_key(hw, key);
+ if (rxfh->key && hw->port)
+ enetc_set_rss_key(hw, rxfh->key);
/* set RSS table */
- if (indir)
- err = enetc_set_rss_table(priv->si, indir, priv->si->num_rss);
+ if (rxfh->indir)
+ err = enetc_set_rss_table(priv->si, rxfh->indir,
+ priv->si->num_rss);
return err;
}
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index c153dc083a..11b1455580 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -920,6 +920,7 @@ static void enetc_imdio_remove(struct enetc_pf *pf)
static bool enetc_port_has_pcs(struct enetc_pf *pf)
{
return (pf->if_mode == PHY_INTERFACE_MODE_SGMII ||
+ pf->if_mode == PHY_INTERFACE_MODE_1000BASEX ||
pf->if_mode == PHY_INTERFACE_MODE_2500BASEX ||
pf->if_mode == PHY_INTERFACE_MODE_USXGMII);
}
@@ -1116,6 +1117,8 @@ static int enetc_phylink_create(struct enetc_ndev_priv *priv,
pf->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_SGMII,
pf->phylink_config.supported_interfaces);
+ __set_bit(PHY_INTERFACE_MODE_1000BASEX,
+ pf->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_2500BASEX,
pf->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_USXGMII,
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index c107680985..8decb1b072 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2406,8 +2406,6 @@ static int fec_enet_mii_probe(struct net_device *ndev)
fep->link = 0;
fep->full_duplex = 0;
- phy_dev->mac_managed_pm = true;
-
phy_attached_info(phy_dev);
return 0;
@@ -2419,10 +2417,12 @@ static int fec_enet_mii_init(struct platform_device *pdev)
struct net_device *ndev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(ndev);
bool suppress_preamble = false;
+ struct phy_device *phydev;
struct device_node *node;
int err = -ENXIO;
u32 mii_speed, holdtime;
u32 bus_freq;
+ int addr;
/*
* The i.MX28 dual fec interfaces are not equal.
@@ -2536,6 +2536,13 @@ static int fec_enet_mii_init(struct platform_device *pdev)
goto err_out_free_mdiobus;
of_node_put(node);
+ /* find all the PHY devices on the bus and set mac_managed_pm to true */
+ for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+ phydev = mdiobus_get_phy(fep->mii_bus, addr);
+ if (phydev)
+ phydev->mac_managed_pm = true;
+ }
+
mii_cnt++;
/* save fec0 mii_bus */
@@ -2934,10 +2941,10 @@ static void fec_enet_get_strings(struct net_device *netdev,
switch (stringset) {
case ETH_SS_STATS:
for (i = 0; i < ARRAY_SIZE(fec_stats); i++) {
- ethtool_sprintf(&data, "%s", fec_stats[i].name);
+ ethtool_puts(&data, fec_stats[i].name);
}
for (i = 0; i < ARRAY_SIZE(fec_xdp_stat_strs); i++) {
- ethtool_sprintf(&data, "%s", fec_xdp_stat_strs[i]);
+ ethtool_puts(&data, fec_xdp_stat_strs[i]);
}
page_pool_ethtool_stats_get_strings(data);
@@ -4771,4 +4778,5 @@ static struct platform_driver fec_driver = {
module_platform_driver(fec_driver);
+MODULE_DESCRIPTION("NXP Fast Ethernet Controller (FEC) driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
index 70dd982a5e..026f7270a5 100644
--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
+++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
@@ -531,4 +531,5 @@ static struct platform_driver fsl_pq_mdio_driver = {
module_platform_driver(fsl_pq_mdio_driver);
+MODULE_DESCRIPTION("Freescale PQ MDIO helpers");
MODULE_LICENSE("GPL");