diff options
Diffstat (limited to 'drivers/net')
39 files changed, 277 insertions, 199 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 7d3752cbf761..2ec8e015c7b3 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -50,7 +50,7 @@ struct arp_pkt { #pragma pack() /* Forward declaration */ -static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], +static void alb_send_learning_packets(struct slave *slave, const u8 mac_addr[], bool strict_match); static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp); static void rlb_src_unlink(struct bonding *bond, u32 index); @@ -353,7 +353,8 @@ static struct slave *rlb_next_rx_slave(struct bonding *bond) * * Caller must hold RTNL */ -static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, u8 addr[]) +static void rlb_teach_disabled_mac_on_primary(struct bonding *bond, + const u8 addr[]) { struct slave *curr_active = rtnl_dereference(bond->curr_active_slave); @@ -904,7 +905,7 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id) /*********************** tlb/rlb shared functions *********************/ -static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], +static void alb_send_lp_vid(struct slave *slave, const u8 mac_addr[], __be16 vlan_proto, u16 vid) { struct learning_pkt pkt; @@ -940,7 +941,7 @@ static void alb_send_lp_vid(struct slave *slave, u8 mac_addr[], struct alb_walk_data { struct bonding *bond; struct slave *slave; - u8 *mac_addr; + const u8 *mac_addr; bool strict_match; }; @@ -949,9 +950,9 @@ static int alb_upper_dev_walk(struct net_device *upper, { struct alb_walk_data *data = (struct alb_walk_data *)priv->data; bool strict_match = data->strict_match; + const u8 *mac_addr = data->mac_addr; struct bonding *bond = data->bond; struct slave *slave = data->slave; - u8 *mac_addr = data->mac_addr; struct bond_vlan_tag *tags; if (is_vlan_dev(upper) && @@ -982,7 +983,7 @@ static int alb_upper_dev_walk(struct net_device *upper, return 0; } -static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], +static void alb_send_learning_packets(struct slave *slave, const u8 mac_addr[], bool strict_match) { struct bonding *bond = bond_get_bond_by_slave(slave); @@ -1006,14 +1007,14 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], rcu_read_unlock(); } -static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], +static int alb_set_slave_mac_addr(struct slave *slave, const u8 addr[], unsigned int len) { struct net_device *dev = slave->dev; struct sockaddr_storage ss; if (BOND_MODE(slave->bond) == BOND_MODE_TLB) { - memcpy(dev->dev_addr, addr, len); + __dev_addr_set(dev, addr, len); return 0; } @@ -1242,8 +1243,7 @@ static int alb_set_mac_address(struct bonding *bond, void *addr) res = dev_set_mac_address(slave->dev, addr, NULL); /* restore net_device's hw address */ - bond_hw_addr_copy(slave->dev->dev_addr, tmp_addr, - slave->dev->addr_len); + dev_addr_set(slave->dev, tmp_addr); if (res) goto unwind; @@ -1263,8 +1263,7 @@ unwind: rollback_slave->dev->addr_len); dev_set_mac_address(rollback_slave->dev, (struct sockaddr *)&ss, NULL); - bond_hw_addr_copy(rollback_slave->dev->dev_addr, tmp_addr, - rollback_slave->dev->addr_len); + dev_addr_set(rollback_slave->dev, tmp_addr); } return res; @@ -1727,8 +1726,7 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave dev_set_mac_address(new_slave->dev, (struct sockaddr *)&ss, NULL); - bond_hw_addr_copy(new_slave->dev->dev_addr, tmp_addr, - new_slave->dev->addr_len); + dev_addr_set(new_slave->dev, tmp_addr); } /* curr_active_slave must be set before calling alb_swap_mac_addr */ @@ -1761,7 +1759,7 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr) if (res) return res; - bond_hw_addr_copy(bond_dev->dev_addr, ss->__data, bond_dev->addr_len); + dev_addr_set(bond_dev, ss->__data); /* If there is no curr_active_slave there is nothing else to do. * Otherwise we'll need to pass the new address to it and handle diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 0c52612cb8e9..ff8da720a33a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -923,7 +923,7 @@ static int bond_set_dev_addr(struct net_device *bond_dev, if (err) return err; - memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len); + __dev_addr_set(bond_dev, slave_dev->dev_addr, slave_dev->addr_len); bond_dev->addr_assign_type = NET_ADDR_STOLEN; call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev); return 0; diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 06279ba64cc8..b0262e69a170 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -1343,10 +1343,8 @@ void b53_phylink_validate(struct dsa_switch *ds, int port, phylink_set(mask, 100baseT_Full); } - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); phylink_helper_basex_speed(state); } @@ -1546,6 +1544,7 @@ EXPORT_SYMBOL(b53_vlan_del); /* Address Resolution Logic routines */ static int b53_arl_op_wait(struct b53_device *dev) + __must_hold(&dev->arl_mutex) { unsigned int timeout = 10; u8 reg; @@ -1564,6 +1563,7 @@ static int b53_arl_op_wait(struct b53_device *dev) } static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) + __must_hold(&dev->arl_mutex) { u8 reg; @@ -1587,6 +1587,7 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) static int b53_arl_read(struct b53_device *dev, u64 mac, u16 vid, struct b53_arl_entry *ent, u8 *idx) + __must_hold(&dev->arl_mutex) { DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); unsigned int i; @@ -1632,6 +1633,7 @@ static int b53_arl_read(struct b53_device *dev, u64 mac, static int b53_arl_op(struct b53_device *dev, int op, int port, const unsigned char *addr, u16 vid, bool is_valid) + __must_hold(&dev->arl_mutex) { struct b53_arl_entry ent; u32 fwd_entry; @@ -1709,6 +1711,7 @@ int b53_fdb_add(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid) { struct b53_device *priv = ds->priv; + int ret; /* 5325 and 5365 require some more massaging, but could * be supported eventually @@ -1716,7 +1719,11 @@ int b53_fdb_add(struct dsa_switch *ds, int port, if (is5325(priv) || is5365(priv)) return -EOPNOTSUPP; - return b53_arl_op(priv, 0, port, addr, vid, true); + mutex_lock(&priv->arl_mutex); + ret = b53_arl_op(priv, 0, port, addr, vid, true); + mutex_unlock(&priv->arl_mutex); + + return ret; } EXPORT_SYMBOL(b53_fdb_add); @@ -1724,12 +1731,18 @@ int b53_fdb_del(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid) { struct b53_device *priv = ds->priv; + int ret; - return b53_arl_op(priv, 0, port, addr, vid, false); + mutex_lock(&priv->arl_mutex); + ret = b53_arl_op(priv, 0, port, addr, vid, false); + mutex_unlock(&priv->arl_mutex); + + return ret; } EXPORT_SYMBOL(b53_fdb_del); static int b53_arl_search_wait(struct b53_device *dev) + __must_hold(&dev->arl_mutex) { unsigned int timeout = 1000; u8 reg; @@ -1750,6 +1763,7 @@ static int b53_arl_search_wait(struct b53_device *dev) static void b53_arl_search_rd(struct b53_device *dev, u8 idx, struct b53_arl_entry *ent) + __must_hold(&dev->arl_mutex) { u64 mac_vid; u32 fwd_entry; @@ -1782,6 +1796,8 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, int ret; u8 reg; + mutex_lock(&priv->arl_mutex); + /* Start search operation */ reg = ARL_SRCH_STDN; b53_write8(priv, B53_ARLIO_PAGE, B53_ARL_SRCH_CTL, reg); @@ -1789,18 +1805,18 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, do { ret = b53_arl_search_wait(priv); if (ret) - return ret; + break; b53_arl_search_rd(priv, 0, &results[0]); ret = b53_fdb_copy(port, &results[0], cb, data); if (ret) - return ret; + break; if (priv->num_arl_bins > 2) { b53_arl_search_rd(priv, 1, &results[1]); ret = b53_fdb_copy(port, &results[1], cb, data); if (ret) - return ret; + break; if (!results[0].is_valid && !results[1].is_valid) break; @@ -1808,6 +1824,8 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, } while (count++ < b53_max_arl_entries(priv) / 2); + mutex_unlock(&priv->arl_mutex); + return 0; } EXPORT_SYMBOL(b53_fdb_dump); @@ -1816,6 +1834,7 @@ int b53_mdb_add(struct dsa_switch *ds, int port, const struct switchdev_obj_port_mdb *mdb) { struct b53_device *priv = ds->priv; + int ret; /* 5325 and 5365 require some more massaging, but could * be supported eventually @@ -1823,7 +1842,11 @@ int b53_mdb_add(struct dsa_switch *ds, int port, if (is5325(priv) || is5365(priv)) return -EOPNOTSUPP; - return b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true); + mutex_lock(&priv->arl_mutex); + ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, true); + mutex_unlock(&priv->arl_mutex); + + return ret; } EXPORT_SYMBOL(b53_mdb_add); @@ -1833,7 +1856,9 @@ int b53_mdb_del(struct dsa_switch *ds, int port, struct b53_device *priv = ds->priv; int ret; + mutex_lock(&priv->arl_mutex); ret = b53_arl_op(priv, 0, port, mdb->addr, mdb->vid, false); + mutex_unlock(&priv->arl_mutex); if (ret) dev_err(ds->dev, "failed to delete MDB entry\n"); @@ -2670,6 +2695,7 @@ struct b53_device *b53_switch_alloc(struct device *base, mutex_init(&dev->reg_mutex); mutex_init(&dev->stats_mutex); + mutex_init(&dev->arl_mutex); return dev; } diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h index 544101e74bca..579da74ada64 100644 --- a/drivers/net/dsa/b53/b53_priv.h +++ b/drivers/net/dsa/b53/b53_priv.h @@ -107,6 +107,7 @@ struct b53_device { struct mutex reg_mutex; struct mutex stats_mutex; + struct mutex arl_mutex; const struct b53_io_ops *ops; /* chip specific data */ diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c index a86ddc4bb897..13aa43b5cffd 100644 --- a/drivers/net/dsa/bcm_sf2.c +++ b/drivers/net/dsa/bcm_sf2.c @@ -685,7 +685,7 @@ static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port, state->interface != PHY_INTERFACE_MODE_GMII && state->interface != PHY_INTERFACE_MODE_INTERNAL && state->interface != PHY_INTERFACE_MODE_MOCA) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); if (port != core_readl(priv, CORE_IMP0_PRT_ID)) dev_err(ds->dev, "Unsupported interface: %d for port %d\n", @@ -713,10 +713,8 @@ static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port, phylink_set(mask, 100baseT_Half); phylink_set(mask, 100baseT_Full); - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port, diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c index 354655f9ed00..4e0b53d94b52 100644 --- a/drivers/net/dsa/hirschmann/hellcreek.c +++ b/drivers/net/dsa/hirschmann/hellcreek.c @@ -1403,10 +1403,8 @@ static void hellcreek_phylink_validate(struct dsa_switch *ds, int port, else phylink_set(mask, 1000baseT_Full); - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static int diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index dbd4486a173f..7056d98d8177 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -276,6 +276,7 @@ struct gswip_priv { int num_gphy_fw; struct gswip_gphy_fw *gphy_fw; u32 port_vlan_filter; + struct mutex pce_table_lock; }; struct gswip_pce_table_entry { @@ -523,10 +524,14 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSRD : GSWIP_PCE_TBL_CTRL_OPMOD_ADRD; + mutex_lock(&priv->pce_table_lock); + err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS); - if (err) + if (err) { + mutex_unlock(&priv->pce_table_lock); return err; + } gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK | @@ -536,8 +541,10 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS); - if (err) + if (err) { + mutex_unlock(&priv->pce_table_lock); return err; + } for (i = 0; i < ARRAY_SIZE(tbl->key); i++) tbl->key[i] = gswip_switch_r(priv, GSWIP_PCE_TBL_KEY(i)); @@ -553,6 +560,8 @@ static int gswip_pce_table_entry_read(struct gswip_priv *priv, tbl->valid = !!(crtl & GSWIP_PCE_TBL_CTRL_VLD); tbl->gmap = (crtl & GSWIP_PCE_TBL_CTRL_GMAP_MASK) >> 7; + mutex_unlock(&priv->pce_table_lock); + return 0; } @@ -565,10 +574,14 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, u16 addr_mode = tbl->key_mode ? GSWIP_PCE_TBL_CTRL_OPMOD_KSWR : GSWIP_PCE_TBL_CTRL_OPMOD_ADWR; + mutex_lock(&priv->pce_table_lock); + err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, GSWIP_PCE_TBL_CTRL_BAS); - if (err) + if (err) { + mutex_unlock(&priv->pce_table_lock); return err; + } gswip_switch_w(priv, tbl->index, GSWIP_PCE_TBL_ADDR); gswip_switch_mask(priv, GSWIP_PCE_TBL_CTRL_ADDR_MASK | @@ -600,8 +613,12 @@ static int gswip_pce_table_entry_write(struct gswip_priv *priv, crtl |= GSWIP_PCE_TBL_CTRL_BAS; gswip_switch_w(priv, crtl, GSWIP_PCE_TBL_CTRL); - return gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, - GSWIP_PCE_TBL_CTRL_BAS); + err = gswip_switch_r_timeout(priv, GSWIP_PCE_TBL_CTRL, + GSWIP_PCE_TBL_CTRL_BAS); + + mutex_unlock(&priv->pce_table_lock); + + return err; } /* Add the LAN port into a bridge with the CPU port by @@ -1447,10 +1464,8 @@ static void gswip_phylink_set_capab(unsigned long *supported, phylink_set(mask, 100baseT_Half); phylink_set(mask, 100baseT_Full); - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port, @@ -1478,7 +1493,7 @@ static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port, goto unsupported; break; default: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported port: %i\n", port); return; } @@ -1488,7 +1503,7 @@ static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port, return; unsupported: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported interface '%s' for port %d\n", phy_modes(state->interface), port); } @@ -1518,7 +1533,7 @@ static void gswip_xrx300_phylink_validate(struct dsa_switch *ds, int port, goto unsupported; break; default: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported port: %i\n", port); return; } @@ -1528,7 +1543,7 @@ static void gswip_xrx300_phylink_validate(struct dsa_switch *ds, int port, return; unsupported: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported interface '%s' for port %d\n", phy_modes(state->interface), port); } @@ -2106,6 +2121,7 @@ static int gswip_probe(struct platform_device *pdev) priv->ds->priv = priv; priv->ds->ops = priv->hw_info->ops; priv->dev = dev; + mutex_init(&priv->pce_table_lock); version = gswip_switch_r(priv, GSWIP_VERSION); np = dev->of_node; diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index c5142f86a3c7..43fc3087aeb3 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -1542,15 +1542,13 @@ static void ksz8_validate(struct dsa_switch *ds, int port, phylink_set(mask, 100baseT_Half); phylink_set(mask, 100baseT_Full); - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); return; unsupported: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported interface: %s, port: %d\n", phy_modes(state->interface), port); } diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 8dadcae93c9b..14c678a9e41b 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -674,9 +674,8 @@ static void mv88e6xxx_validate(struct dsa_switch *ds, int port, if (chip->info->ops->phylink_validate) chip->info->ops->phylink_validate(chip, port, mask, state); - bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); /* We can only operate at 2500BaseX or 1000BaseX. If requested * to advertise both, only report advertising at 2500BaseX. diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 11b42fd812e4..45c5ec7a83ea 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -943,7 +943,7 @@ static void vsc9959_phylink_validate(struct ocelot *ocelot, int port, if (state->interface != PHY_INTERFACE_MODE_NA && state->interface != ocelot_port->phy_mode) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } @@ -965,10 +965,8 @@ static void vsc9959_phylink_validate(struct ocelot *ocelot, int port, phylink_set(mask, 2500baseX_Full); } - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static int vsc9959_prevalidate_phy_mode(struct ocelot *ocelot, int port, diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c index de1d34a1f1e4..92eae63150ea 100644 --- a/drivers/net/dsa/ocelot/seville_vsc9953.c +++ b/drivers/net/dsa/ocelot/seville_vsc9953.c @@ -999,7 +999,7 @@ static void vsc9953_phylink_validate(struct ocelot *ocelot, int port, if (state->interface != PHY_INTERFACE_MODE_NA && state->interface != ocelot_port->phy_mode) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } @@ -1018,10 +1018,8 @@ static void vsc9953_phylink_validate(struct ocelot *ocelot, int port, phylink_set(mask, 2500baseX_Full); } - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static int vsc9953_prevalidate_phy_mode(struct ocelot *ocelot, int port, diff --git a/drivers/net/dsa/qca/ar9331.c b/drivers/net/dsa/qca/ar9331.c index a6bfb6abc51a..da0d7e68643a 100644 --- a/drivers/net/dsa/qca/ar9331.c +++ b/drivers/net/dsa/qca/ar9331.c @@ -522,7 +522,7 @@ static void ar9331_sw_phylink_validate(struct dsa_switch *ds, int port, goto unsupported; break; default: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported port: %i\n", port); return; } @@ -536,15 +536,13 @@ static void ar9331_sw_phylink_validate(struct dsa_switch *ds, int port, phylink_set(mask, 100baseT_Half); phylink_set(mask, 100baseT_Full); - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); return; unsupported: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported interface: %d, port: %d\n", state->interface, port); } diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 808419f3b808..21dba16af097 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -261,6 +261,8 @@ struct sja1105_private { * the switch doesn't confuse them with one another. */ struct mutex mgmt_lock; + /* Serializes access to the dynamic config interface */ + struct mutex dynamic_config_lock; struct devlink_region **regions; struct sja1105_cbs_entry *cbs; struct mii_bus *mdio_base_t1; diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c index f2049f52833c..7729d3f8b7f5 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c @@ -1170,6 +1170,56 @@ const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = { }, }; +#define SJA1105_DYNAMIC_CONFIG_SLEEP_US 10 +#define SJA1105_DYNAMIC_CONFIG_TIMEOUT_US 100000 + +static int +sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, + struct sja1105_dyn_cmd *cmd, + const struct sja1105_dynamic_table_ops *ops) +{ + u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {}; + int rc; + + /* We don't _need_ to read the full entry, just the command area which + * is a fixed SJA1105_SIZE_DYN_CMD. But our cmd_packing() API expects a + * buffer that contains the full entry too. Additionally, our API + * doesn't really know how many bytes into the buffer does the command + * area really begin. So just read back the whole entry. + */ + rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, + ops->packed_size); + if (rc) + return rc; + + /* Unpack the command structure, and return it to the caller in case it + * needs to perform further checks on it (VALIDENT). + */ + memset(cmd, 0, sizeof(*cmd)); + ops->cmd_packing(packed_buf, cmd, UNPACK); + + /* Hardware hasn't cleared VALID => still working on it */ + return cmd->valid ? -EAGAIN : 0; +} + +/* Poll the dynamic config entry's control area until the hardware has + * cleared the VALID bit, which means we have confirmation that it has + * finished processing the command. + */ +static int +sja1105_dynamic_config_wait_complete(struct sja1105_private *priv, + struct sja1105_dyn_cmd *cmd, + const struct sja1105_dynamic_table_ops *ops) +{ + int rc; + + return read_poll_timeout(sja1105_dynamic_config_poll_valid, + rc, rc != -EAGAIN, + SJA1105_DYNAMIC_CONFIG_SLEEP_US, + SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, + false, priv, cmd, ops); +} + /* Provides read access to the settings through the dynamic interface * of the switch. * @blk_idx is used as key to select from the sja1105_dynamic_table_ops. @@ -1196,7 +1246,6 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv, struct sja1105_dyn_cmd cmd = {0}; /* SPI payload buffer */ u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {0}; - int retries = 3; int rc; if (blk_idx >= BLK_IDX_MAX_DYN) @@ -1234,33 +1283,21 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv, ops->entry_packing(packed_buf, entry, PACK); /* Send SPI write operation: read config table entry */ + mutex_lock(&priv->dynamic_config_lock); rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, ops->packed_size); - if (rc < 0) + if (rc < 0) { + mutex_unlock(&priv->dynamic_config_lock); return rc; + } - /* Loop until we have confirmation that hardware has finished - * processing the command and has cleared the VALID field - */ - do { - memset(packed_buf, 0, ops->packed_size); - - /* Retrieve the read operation's result */ - rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, - ops->packed_size); - if (rc < 0) - return rc; - - cmd = (struct sja1105_dyn_cmd) {0}; - ops->cmd_packing(packed_buf, &cmd, UNPACK); - - if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY)) - return -ENOENT; - cpu_relax(); - } while (cmd.valid && --retries); + rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); + mutex_unlock(&priv->dynamic_config_lock); + if (rc < 0) + return rc; - if (cmd.valid) - return -ETIMEDOUT; + if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY)) + return -ENOENT; /* Don't dereference possibly NULL pointer - maybe caller * only wanted to see whether the entry existed or not. @@ -1316,8 +1353,16 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv, ops->entry_packing(packed_buf, entry, PACK); /* Send SPI write operation: read config table entry */ + mutex_lock(&priv->dynamic_config_lock); rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, ops->packed_size); + if (rc < 0) { + mutex_unlock(&priv->dynamic_config_lock); + return rc; + } + + rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); + mutex_unlock(&priv->dynamic_config_lock); if (rc < 0) return rc; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 70ece441b3b8..c343effe2e96 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -1431,7 +1431,7 @@ static void sja1105_phylink_validate(struct dsa_switch *ds, int port, */ if (state->interface != PHY_INTERFACE_MODE_NA && sja1105_phy_mode_mismatch(priv, port, state->interface)) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } @@ -1451,9 +1451,8 @@ static void sja1105_phylink_validate(struct dsa_switch *ds, int port, phylink_set(mask, 2500baseX_Full); } - bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static int @@ -3366,6 +3365,7 @@ static int sja1105_probe(struct spi_device *spi) priv->ds = ds; mutex_init(&priv->ptp_data.lock); + mutex_init(&priv->dynamic_config_lock); mutex_init(&priv->mgmt_lock); rc = sja1105_parse_dt(priv); diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c index 469420941054..910fcb3b252b 100644 --- a/drivers/net/dsa/xrs700x/xrs700x.c +++ b/drivers/net/dsa/xrs700x/xrs700x.c @@ -456,7 +456,7 @@ static void xrs700x_phylink_validate(struct dsa_switch *ds, int port, phylink_set(mask, 1000baseT_Full); break; default: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); dev_err(ds->dev, "Unsupported port: %i\n", port); return; } @@ -467,10 +467,8 @@ static void xrs700x_phylink_validate(struct dsa_switch *ds, int port, phylink_set(mask, 10baseT_Full); phylink_set(mask, 100baseT_Full); - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void xrs700x_mac_link_up(struct dsa_switch *ds, int port, diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c index bafc51c34e0b..94879cf8b420 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c @@ -369,9 +369,8 @@ static int xgbe_set_link_ksettings(struct net_device *netdev, __ETHTOOL_LINK_MODE_MASK_NBITS, cmd->link_modes.advertising, __ETHTOOL_LINK_MODE_MASK_NBITS, lks->link_modes.supported); - bitmap_and(advertising, - cmd->link_modes.advertising, lks->link_modes.supported, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(advertising, cmd->link_modes.advertising, + lks->link_modes.supported); if ((cmd->base.autoneg == AUTONEG_ENABLE) && bitmap_empty(advertising, __ETHTOOL_LINK_MODE_MASK_NBITS)) { @@ -384,8 +383,7 @@ static int xgbe_set_link_ksettings(struct net_device *netdev, pdata->phy.autoneg = cmd->base.autoneg; pdata->phy.speed = speed; pdata->phy.duplex = cmd->base.duplex; - bitmap_copy(lks->link_modes.advertising, advertising, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_copy(lks->link_modes.advertising, advertising); if (cmd->base.autoneg == AUTONEG_ENABLE) XGBE_SET_ADV(lks, Autoneg); diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c index ada3a9f0c8c8..88d2ab748399 100644 --- a/drivers/net/ethernet/atheros/ag71xx.c +++ b/drivers/net/ethernet/atheros/ag71xx.c @@ -1082,14 +1082,12 @@ static void ag71xx_mac_validate(struct phylink_config *config, phylink_set(mask, 1000baseX_Full); } - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); return; unsupported: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); } static void ag71xx_mac_pcs_get_state(struct phylink_config *config, diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 30a65cac9e87..309371abfe23 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -522,21 +522,21 @@ static void macb_validate(struct phylink_config *config, state->interface != PHY_INTERFACE_MODE_SGMII && state->interface != PHY_INTERFACE_MODE_10GBASER && !phy_interface_mode_is_rgmii(state->interface)) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } if (!macb_is_gem(bp) && (state->interface == PHY_INTERFACE_MODE_GMII || phy_interface_mode_is_rgmii(state->interface))) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } if (state->interface == PHY_INTERFACE_MODE_10GBASER && !(bp->caps & MACB_CAPS_HIGH_SPEED && bp->caps & MACB_CAPS_PCS)) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } @@ -570,9 +570,8 @@ static void macb_validate(struct phylink_config *config, phylink_set(mask, 1000baseT_Half); } out: - bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode, diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index 64f92770691f..0e87c7043b77 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -942,7 +942,7 @@ static void enetc_pl_mac_validate(struct phylink_config *config, state->interface != PHY_INTERFACE_MODE_2500BASEX && state->interface != PHY_INTERFACE_MODE_USXGMII && !phy_interface_mode_is_rgmii(state->interface)) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } @@ -965,10 +965,8 @@ static void enetc_pl_mac_validate(struct phylink_config *config, phylink_set(mask, 2500baseX_Full); } - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void enetc_pl_mac_config(struct phylink_config *config, diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c index b431c300ef1b..a85667078b72 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c @@ -322,12 +322,10 @@ static int hinic_get_link_ksettings(struct net_device *netdev, } } - bitmap_copy(link_ksettings->link_modes.supported, - (unsigned long *)&settings.supported, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_copy(link_ksettings->link_modes.advertising, - (unsigned long *)&settings.advertising, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_copy(link_ksettings->link_modes.supported, + (unsigned long *)&settings.supported); + linkmode_copy(link_ksettings->link_modes.advertising, + (unsigned long *)&settings.advertising); return 0; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index beda8e0ef7d4..8362822316a9 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -467,9 +467,8 @@ static int ixgbe_set_link_ksettings(struct net_device *netdev, * this function does not support duplex forcing, but can * limit the advertising of the adapter to the specified speed */ - if (!bitmap_subset(cmd->link_modes.advertising, - cmd->link_modes.supported, - __ETHTOOL_LINK_MODE_MASK_NBITS)) + if (!linkmode_subset(cmd->link_modes.advertising, + cmd->link_modes.supported)) return -EINVAL; /* only allow one speed at a time if no autoneg */ diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 98f276c617fb..b6c636592dfa 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -3834,14 +3834,14 @@ static void mvneta_validate(struct phylink_config *config, */ if (phy_interface_mode_is_8023z(state->interface)) { if (!phylink_test(state->advertising, Autoneg)) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } } else if (state->interface != PHY_INTERFACE_MODE_NA && state->interface != PHY_INTERFACE_MODE_QSGMII && state->interface != PHY_INTERFACE_MODE_SGMII && !phy_interface_mode_is_rgmii(state->interface)) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } @@ -3870,10 +3870,8 @@ static void mvneta_validate(struct phylink_config *config, phylink_set(mask, 100baseT_Full); } - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); /* We can only operate at 2500BaseX or 1000BaseX. If requested * to advertise both, only report advertising at 2500BaseX. diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index ad3be55cce68..8ddf58f379ac 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -6338,15 +6338,14 @@ static void mvpp2_phylink_validate(struct phylink_config *config, goto empty_set; } - bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); phylink_helper_basex_speed(state); return; empty_set: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); } static void mvpp2_xlg_config(struct mvpp2_port *port, unsigned int mode, diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c index b0f57bda7e27..80d4ce61f442 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c @@ -1175,9 +1175,8 @@ static int otx2_set_link_ksettings(struct net_device *netdev, otx2_get_link_ksettings(netdev, &cur_ks); /* Check requested modes against supported modes by hardware */ - if (!bitmap_subset(cmd->link_modes.advertising, - cur_ks.link_modes.supported, - __ETHTOOL_LINK_MODE_MASK_NBITS)) + if (!linkmode_subset(cmd->link_modes.advertising, + cur_ks.link_modes.supported)) return -EINVAL; mutex_lock(&mbox->lock); diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 6c02e1740609..1d607bc6b59e 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -977,8 +977,7 @@ static int pxa168_init_phy(struct net_device *dev) cmd.base.phy_address = pep->phy_addr; cmd.base.speed = pep->phy_speed; cmd.base.duplex = pep->phy_duplex; - bitmap_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES); cmd.base.autoneg = AUTONEG_ENABLE; if (cmd.base.speed != 0) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index 66c8ae29bc7a..066d79e4ecfc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -39,6 +39,7 @@ #include <linux/in.h> #include <net/ip.h> #include <linux/bitmap.h> +#include <linux/mii.h> #include "mlx4_en.h" #include "en_port.h" @@ -651,10 +652,8 @@ static unsigned long *ptys2ethtool_link_mode(struct ptys2ethtool_config *cfg, unsigned int i; \ cfg = &ptys2ethtool_map[reg_]; \ cfg->speed = speed_; \ - bitmap_zero(cfg->supported, \ - __ETHTOOL_LINK_MODE_MASK_NBITS); \ - bitmap_zero(cfg->advertised, \ - __ETHTOOL_LINK_MODE_MASK_NBITS); \ + linkmode_zero(cfg->supported); \ + linkmode_zero(cfg->advertised); \ for (i = 0 ; i < ARRAY_SIZE(modes) ; ++i) { \ __set_bit(modes[i], cfg->supported); \ __set_bit(modes[i], cfg->advertised); \ @@ -710,10 +709,8 @@ static void ptys2ethtool_update_link_modes(unsigned long *link_modes, int i; for (i = 0; i < MLX4_LINK_MODES_SZ; i++) { if (eth_proto & MLX4_PROT_MASK(i)) - bitmap_or(link_modes, link_modes, - ptys2ethtool_link_mode(&ptys2ethtool_map[i], - report), - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_or(link_modes, link_modes, + ptys2ethtool_link_mode(&ptys2ethtool_map[i], report)); } } @@ -724,11 +721,9 @@ static u32 ethtool2ptys_link_modes(const unsigned long *link_modes, u32 ptys_modes = 0; for (i = 0; i < MLX4_LINK_MODES_SZ; i++) { - if (bitmap_intersects( - ptys2ethtool_link_mode(&ptys2ethtool_map[i], - report), - link_modes, - __ETHTOOL_LINK_MODE_MASK_NBITS)) + ulong *map_mode = ptys2ethtool_link_mode(&ptys2ethtool_map[i], + report); + if (linkmode_intersects(map_mode, link_modes)) ptys_modes |= 1 << i; } return ptys_modes; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c index af70e2795125..fb74752de0ca 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c @@ -92,12 +92,11 @@ static void sparx5_phylink_validate(struct phylink_config *config, } break; default: - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } - bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void sparx5_phylink_mac_config(struct phylink_config *config, diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 4e5ae687d2e2..33a4a9a17436 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -21,11 +21,13 @@ struct ocelot_mact_entry { }; static inline u32 ocelot_mact_read_macaccess(struct ocelot *ocelot) + __must_hold(&ocelot->mact_lock) { return ocelot_read(ocelot, ANA_TABLES_MACACCESS); } static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot) + __must_hold(&ocelot->mact_lock) { u32 val; @@ -39,6 +41,7 @@ static inline int ocelot_mact_wait_for_completion(struct ocelot *ocelot) static void ocelot_mact_select(struct ocelot *ocelot, const unsigned char mac[ETH_ALEN], unsigned int vid) + __must_hold(&ocelot->mact_lock) { u32 macl = 0, mach = 0; @@ -67,6 +70,7 @@ int ocelot_mact_learn(struct ocelot *ocelot, int port, ANA_TABLES_MACACCESS_ENTRYTYPE(type) | ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN); unsigned int mc_ports; + int err; /* Set MAC_CPU_COPY if the CPU port is used by a multicast entry */ if (type == ENTRYTYPE_MACv4) @@ -79,18 +83,28 @@ int ocelot_mact_learn(struct ocelot *ocelot, int port, if (mc_ports & BIT(ocelot->num_phys_ports)) cmd |= ANA_TABLES_MACACCESS_MAC_CPU_COPY; + mutex_lock(&ocelot->mact_lock); + ocelot_mact_select(ocelot, mac, vid); /* Issue a write command */ ocelot_write(ocelot, cmd, ANA_TABLES_MACACCESS); - return ocelot_mact_wait_for_completion(ocelot); + err = ocelot_mact_wait_for_completion(ocelot); + + mutex_unlock(&ocelot->mact_lock); + + return err; } EXPORT_SYMBOL(ocelot_mact_learn); int ocelot_mact_forget(struct ocelot *ocelot, const unsigned char mac[ETH_ALEN], unsigned int vid) { + int err; + + mutex_lock(&ocelot->mact_lock); + ocelot_mact_select(ocelot, mac, vid); /* Issue a forget command */ @@ -98,7 +112,11 @@ int ocelot_mact_forget(struct ocelot *ocelot, ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_FORGET), ANA_TABLES_MACACCESS); - return ocelot_mact_wait_for_completion(ocelot); + err = ocelot_mact_wait_for_completion(ocelot); + + mutex_unlock(&ocelot->mact_lock); + + return err; } EXPORT_SYMBOL(ocelot_mact_forget); @@ -114,7 +132,9 @@ static void ocelot_mact_init(struct ocelot *ocelot) | ANA_AGENCTRL_LEARN_IGNORE_VLAN, ANA_AGENCTRL); - /* Clear the MAC table */ + /* Clear the MAC table. We are not concurrent with anyone, so + * holding &ocelot->mact_lock is pointless. + */ ocelot_write(ocelot, MACACCESS_CMD_INIT, ANA_TABLES_MACACCESS); } @@ -1172,6 +1192,7 @@ EXPORT_SYMBOL(ocelot_port_fdb_do_dump); static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col, struct ocelot_mact_entry *entry) + __must_hold(&ocelot->mact_lock) { u32 val, dst, macl, mach; char mac[ETH_ALEN]; @@ -1220,33 +1241,40 @@ static int ocelot_mact_read(struct ocelot *ocelot, int port, int row, int col, int ocelot_fdb_dump(struct ocelot *ocelot, int port, dsa_fdb_dump_cb_t *cb, void *data) { + int err = 0; int i, j; + /* We could take the lock just around ocelot_mact_read, but doing so + * thousands of times in a row seems rather pointless and inefficient. + */ + mutex_lock(&ocelot->mact_lock); + /* Loop through all the mac tables entries. */ for (i = 0; i < ocelot->num_mact_rows; i++) { for (j = 0; j < 4; j++) { struct ocelot_mact_entry entry; bool is_static; - int ret; - ret = ocelot_mact_read(ocelot, port, i, j, &entry); + err = ocelot_mact_read(ocelot, port, i, j, &entry); /* If the entry is invalid (wrong port, invalid...), * skip it. */ - if (ret == -EINVAL) + if (err == -EINVAL) continue; - else if (ret) - return ret; + else if (err) + break; is_static = (entry.type == ENTRYTYPE_LOCKED); - ret = cb(entry.mac, entry.vid, is_static, data); - if (ret) - return ret; + err = cb(entry.mac, entry.vid, is_static, data); + if (err) + break; } } - return 0; + mutex_unlock(&ocelot->mact_lock); + + return err; } EXPORT_SYMBOL(ocelot_fdb_dump); @@ -2231,6 +2259,7 @@ int ocelot_init(struct ocelot *ocelot) mutex_init(&ocelot->stats_lock); mutex_init(&ocelot->ptp_lock); + mutex_init(&ocelot->mact_lock); spin_lock_init(&ocelot->ptp_clock_lock); spin_lock_init(&ocelot->ts_id_lock); snprintf(queue_name, sizeof(queue_name), "%s-stats", diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index e3fc4548f642..eaeba60b1bba 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -1509,7 +1509,7 @@ static void vsc7514_phylink_validate(struct phylink_config *config, if (state->interface != PHY_INTERFACE_MODE_NA && state->interface != ocelot_port->phy_mode) { - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } @@ -1528,9 +1528,8 @@ static void vsc7514_phylink_validate(struct phylink_config *config, phylink_set(mask, 2500baseT_Full); phylink_set(mask, 2500baseX_Full); - bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void vsc7514_phylink_mac_config(struct phylink_config *config, diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c index 6b45cae39a20..c54d735b9e2e 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c @@ -214,8 +214,7 @@ static int ionic_get_link_ksettings(struct net_device *netdev, break; } - bitmap_copy(ks->link_modes.advertising, ks->link_modes.supported, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_copy(ks->link_modes.advertising, ks->link_modes.supported); ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER); ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 0b7606987c1e..9b068b81ae09 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1525,7 +1525,7 @@ static void axienet_validate(struct phylink_config *config, netdev_warn(ndev, "Cannot use PHY mode %s, supported: %s\n", phy_modes(state->interface), phy_modes(lp->phy_mode)); - bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(supported); return; } } @@ -1558,10 +1558,8 @@ static void axienet_validate(struct phylink_config *config, break; } - bitmap_and(supported, supported, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); - bitmap_and(state->advertising, state->advertising, mask, - __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_and(supported, supported, mask); + linkmode_and(state->advertising, state->advertising, mask); } static void axienet_mac_pcs_get_state(struct phylink_config *config, diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 18b6dba9394e..16aa3a478e9e 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -250,7 +250,7 @@ static bool send_sci(const struct macsec_secy *secy) (secy->n_rx_sc > 1 && !tx_sc->end_station && !tx_sc->scb); } -static sci_t make_sci(u8 *addr, __be16 port) +static sci_t make_sci(const u8 *addr, __be16 port) { sci_t sci; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 6189acb33973..d2f830ec2969 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -698,7 +698,8 @@ hash_del: return 0; } -static int macvlan_sync_address(struct net_device *dev, unsigned char *addr) +static int macvlan_sync_address(struct net_device *dev, + const unsigned char *addr) { struct macvlan_dev *vlan = netdev_priv(dev); struct net_device *lowerdev = vlan->lowerdev; diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index 7de631f5356f..cd6742e6ba8b 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -646,7 +646,7 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported, if (state->interface == PHY_INTERFACE_MODE_NA) return; - bitmap_zero(xpcs_supported, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_zero(xpcs_supported); compat = xpcs_find_compat(xpcs->id, state->interface); diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 914619f3f0e3..8561f2d4443b 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -182,7 +182,7 @@ static int dp83867_set_wol(struct phy_device *phydev, { struct net_device *ndev = phydev->attached_dev; u16 val_rxcfg, val_micr; - u8 *mac; + const u8 *mac; val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG); val_micr = phy_read(phydev, MII_DP83867_MICR); @@ -193,7 +193,7 @@ static int dp83867_set_wol(struct phy_device *phydev, val_micr |= MII_DP83867_MICR_WOL_INT_EN; if (wol->wolopts & WAKE_MAGIC) { - mac = (u8 *)ndev->dev_addr; + mac = (const u8 *)ndev->dev_addr; if (!is_valid_ether_addr(mac)) return -EINVAL; diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c index 755220c6451f..7113925606f7 100644 --- a/drivers/net/phy/dp83869.c +++ b/drivers/net/phy/dp83869.c @@ -246,7 +246,7 @@ static int dp83869_set_wol(struct phy_device *phydev, { struct net_device *ndev = phydev->attached_dev; int val_rxcfg, val_micr; - u8 *mac; + const u8 *mac; int ret; val_rxcfg = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RXFCFG); @@ -264,7 +264,7 @@ static int dp83869_set_wol(struct phy_device *phydev, if (wol->wolopts & WAKE_MAGIC || wol->wolopts & WAKE_MAGICSECURE) { - mac = (u8 *)ndev->dev_addr; + mac = (const u8 *)ndev->dev_addr; if (!is_valid_ether_addr(mac)) return -EINVAL; diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index 7362f8c3271c..0c6c0d1843bc 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c @@ -373,7 +373,7 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id, if (bus->sfp_quirk) bus->sfp_quirk->modes(id, modes); - bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS); + linkmode_or(support, support, modes); phylink_set(support, Autoneg); phylink_set(support, Pause); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 7a205ddf0060..3e1b7746cce4 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -46,7 +46,7 @@ MODULE_DEVICE_TABLE(pci, vmxnet3_pciid_table); static int enable_mq = 1; static void -vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac); +vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, const u8 *mac); /* * Enable/Disable the given intr @@ -2806,7 +2806,7 @@ vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter) static void -vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac) +vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, const u8 *mac) { u32 tmp; |