mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 13:40:53 +07:00
net: dsa: remove bitmap operations
The bitmap operations were introduced to simplify the switch drivers in the future, since most of them could implement the common VLAN and MDB operations (add, del, dump) with simple functions taking all target ports at once, and thus limiting the number of hardware accesses. Programming an MDB or VLAN this way in a single operation would clearly simplify the drivers a lot but would require a new get-set interface in DSA. The usage of such bitmap from the stack also raised concerned in the past, leading to the dynamic allocation of a new ds->_bitmap member in the dsa_switch structure. So let's get rid of them for now. This commit nicely wraps the ds->ops->port_{mdb,vlan}_{prepare,add} switch operations into new dsa_switch_{mdb,vlan}_{prepare,add} variants not using any bitmap argument anymore. New dsa_switch_{mdb,vlan}_match helpers have been introduced to make clear which local port of a switch must be programmed with the target object. While the targeted user port is an obvious candidate, the DSA links must also be programmed, as well as the CPU port for VLANs. While at it, also remove local variables that are only used once. Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
68aaf44595
commit
e65d45cc35
@ -275,9 +275,6 @@ struct dsa_switch {
|
|||||||
*/
|
*/
|
||||||
bool vlan_filtering;
|
bool vlan_filtering;
|
||||||
|
|
||||||
unsigned long *bitmap;
|
|
||||||
unsigned long _bitmap;
|
|
||||||
|
|
||||||
/* Dynamically allocated ports, keep last */
|
/* Dynamically allocated ports, keep last */
|
||||||
size_t num_ports;
|
size_t num_ports;
|
||||||
struct dsa_port ports[];
|
struct dsa_port ports[];
|
||||||
|
@ -834,20 +834,6 @@ struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)
|
|||||||
if (!ds)
|
if (!ds)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* We avoid allocating memory outside dsa_switch
|
|
||||||
* if it is not needed.
|
|
||||||
*/
|
|
||||||
if (n <= sizeof(ds->_bitmap) * 8) {
|
|
||||||
ds->bitmap = &ds->_bitmap;
|
|
||||||
} else {
|
|
||||||
ds->bitmap = devm_kcalloc(dev,
|
|
||||||
BITS_TO_LONGS(n),
|
|
||||||
sizeof(unsigned long),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (unlikely(!ds->bitmap))
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ds->dev = dev;
|
ds->dev = dev;
|
||||||
ds->num_ports = n;
|
ds->num_ports = n;
|
||||||
|
|
||||||
|
136
net/dsa/switch.c
136
net/dsa/switch.c
@ -128,57 +128,51 @@ static int dsa_switch_fdb_del(struct dsa_switch *ds,
|
|||||||
return ds->ops->port_fdb_del(ds, port, info->addr, info->vid);
|
return ds->ops->port_fdb_del(ds, port, info->addr, info->vid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool dsa_switch_mdb_match(struct dsa_switch *ds, int port,
|
||||||
dsa_switch_mdb_prepare_bitmap(struct dsa_switch *ds,
|
struct dsa_notifier_mdb_info *info)
|
||||||
const struct switchdev_obj_port_mdb *mdb,
|
{
|
||||||
const unsigned long *bitmap)
|
if (ds->index == info->sw_index && port == info->port)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (dsa_is_dsa_port(ds, port))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_switch_mdb_prepare(struct dsa_switch *ds,
|
||||||
|
struct dsa_notifier_mdb_info *info)
|
||||||
{
|
{
|
||||||
int port, err;
|
int port, err;
|
||||||
|
|
||||||
if (!ds->ops->port_mdb_prepare || !ds->ops->port_mdb_add)
|
if (!ds->ops->port_mdb_prepare || !ds->ops->port_mdb_add)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
for_each_set_bit(port, bitmap, ds->num_ports) {
|
for (port = 0; port < ds->num_ports; port++) {
|
||||||
err = ds->ops->port_mdb_prepare(ds, port, mdb);
|
if (dsa_switch_mdb_match(ds, port, info)) {
|
||||||
if (err)
|
err = ds->ops->port_mdb_prepare(ds, port, info->mdb);
|
||||||
return err;
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dsa_switch_mdb_add_bitmap(struct dsa_switch *ds,
|
|
||||||
const struct switchdev_obj_port_mdb *mdb,
|
|
||||||
const unsigned long *bitmap)
|
|
||||||
{
|
|
||||||
int port;
|
|
||||||
|
|
||||||
if (!ds->ops->port_mdb_add)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for_each_set_bit(port, bitmap, ds->num_ports)
|
|
||||||
ds->ops->port_mdb_add(ds, port, mdb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dsa_switch_mdb_add(struct dsa_switch *ds,
|
static int dsa_switch_mdb_add(struct dsa_switch *ds,
|
||||||
struct dsa_notifier_mdb_info *info)
|
struct dsa_notifier_mdb_info *info)
|
||||||
{
|
{
|
||||||
const struct switchdev_obj_port_mdb *mdb = info->mdb;
|
|
||||||
struct switchdev_trans *trans = info->trans;
|
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
/* Build a mask of Multicast group members */
|
if (switchdev_trans_ph_prepare(info->trans))
|
||||||
bitmap_zero(ds->bitmap, ds->num_ports);
|
return dsa_switch_mdb_prepare(ds, info);
|
||||||
if (ds->index == info->sw_index)
|
|
||||||
set_bit(info->port, ds->bitmap);
|
if (!ds->ops->port_mdb_add)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (port = 0; port < ds->num_ports; port++)
|
for (port = 0; port < ds->num_ports; port++)
|
||||||
if (dsa_is_dsa_port(ds, port))
|
if (dsa_switch_mdb_match(ds, port, info))
|
||||||
set_bit(port, ds->bitmap);
|
ds->ops->port_mdb_add(ds, port, info->mdb);
|
||||||
|
|
||||||
if (switchdev_trans_ph_prepare(trans))
|
|
||||||
return dsa_switch_mdb_prepare_bitmap(ds, mdb, ds->bitmap);
|
|
||||||
|
|
||||||
dsa_switch_mdb_add_bitmap(ds, mdb, ds->bitmap);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -186,13 +180,11 @@ static int dsa_switch_mdb_add(struct dsa_switch *ds,
|
|||||||
static int dsa_switch_mdb_del(struct dsa_switch *ds,
|
static int dsa_switch_mdb_del(struct dsa_switch *ds,
|
||||||
struct dsa_notifier_mdb_info *info)
|
struct dsa_notifier_mdb_info *info)
|
||||||
{
|
{
|
||||||
const struct switchdev_obj_port_mdb *mdb = info->mdb;
|
|
||||||
|
|
||||||
if (!ds->ops->port_mdb_del)
|
if (!ds->ops->port_mdb_del)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (ds->index == info->sw_index)
|
if (ds->index == info->sw_index)
|
||||||
return ds->ops->port_mdb_del(ds, info->port, mdb);
|
return ds->ops->port_mdb_del(ds, info->port, info->mdb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -234,59 +226,55 @@ static int dsa_port_vlan_check(struct dsa_switch *ds, int port,
|
|||||||
(void *)vlan);
|
(void *)vlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool dsa_switch_vlan_match(struct dsa_switch *ds, int port,
|
||||||
dsa_switch_vlan_prepare_bitmap(struct dsa_switch *ds,
|
struct dsa_notifier_vlan_info *info)
|
||||||
const struct switchdev_obj_port_vlan *vlan,
|
{
|
||||||
const unsigned long *bitmap)
|
if (ds->index == info->sw_index && port == info->port)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsa_switch_vlan_prepare(struct dsa_switch *ds,
|
||||||
|
struct dsa_notifier_vlan_info *info)
|
||||||
{
|
{
|
||||||
int port, err;
|
int port, err;
|
||||||
|
|
||||||
if (!ds->ops->port_vlan_prepare || !ds->ops->port_vlan_add)
|
if (!ds->ops->port_vlan_prepare || !ds->ops->port_vlan_add)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
for_each_set_bit(port, bitmap, ds->num_ports) {
|
for (port = 0; port < ds->num_ports; port++) {
|
||||||
err = dsa_port_vlan_check(ds, port, vlan);
|
if (dsa_switch_vlan_match(ds, port, info)) {
|
||||||
if (err)
|
err = dsa_port_vlan_check(ds, port, info->vlan);
|
||||||
return err;
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
err = ds->ops->port_vlan_prepare(ds, port, vlan);
|
err = ds->ops->port_vlan_prepare(ds, port, info->vlan);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
dsa_switch_vlan_add_bitmap(struct dsa_switch *ds,
|
|
||||||
const struct switchdev_obj_port_vlan *vlan,
|
|
||||||
const unsigned long *bitmap)
|
|
||||||
{
|
|
||||||
int port;
|
|
||||||
|
|
||||||
for_each_set_bit(port, bitmap, ds->num_ports)
|
|
||||||
ds->ops->port_vlan_add(ds, port, vlan);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dsa_switch_vlan_add(struct dsa_switch *ds,
|
static int dsa_switch_vlan_add(struct dsa_switch *ds,
|
||||||
struct dsa_notifier_vlan_info *info)
|
struct dsa_notifier_vlan_info *info)
|
||||||
{
|
{
|
||||||
const struct switchdev_obj_port_vlan *vlan = info->vlan;
|
|
||||||
struct switchdev_trans *trans = info->trans;
|
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
/* Build a mask of VLAN members */
|
if (switchdev_trans_ph_prepare(info->trans))
|
||||||
bitmap_zero(ds->bitmap, ds->num_ports);
|
return dsa_switch_vlan_prepare(ds, info);
|
||||||
if (ds->index == info->sw_index)
|
|
||||||
set_bit(info->port, ds->bitmap);
|
if (!ds->ops->port_vlan_add)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (port = 0; port < ds->num_ports; port++)
|
for (port = 0; port < ds->num_ports; port++)
|
||||||
if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port))
|
if (dsa_switch_vlan_match(ds, port, info))
|
||||||
set_bit(port, ds->bitmap);
|
ds->ops->port_vlan_add(ds, port, info->vlan);
|
||||||
|
|
||||||
if (switchdev_trans_ph_prepare(trans))
|
|
||||||
return dsa_switch_vlan_prepare_bitmap(ds, vlan, ds->bitmap);
|
|
||||||
|
|
||||||
dsa_switch_vlan_add_bitmap(ds, vlan, ds->bitmap);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -294,13 +282,11 @@ static int dsa_switch_vlan_add(struct dsa_switch *ds,
|
|||||||
static int dsa_switch_vlan_del(struct dsa_switch *ds,
|
static int dsa_switch_vlan_del(struct dsa_switch *ds,
|
||||||
struct dsa_notifier_vlan_info *info)
|
struct dsa_notifier_vlan_info *info)
|
||||||
{
|
{
|
||||||
const struct switchdev_obj_port_vlan *vlan = info->vlan;
|
|
||||||
|
|
||||||
if (!ds->ops->port_vlan_del)
|
if (!ds->ops->port_vlan_del)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (ds->index == info->sw_index)
|
if (ds->index == info->sw_index)
|
||||||
return ds->ops->port_vlan_del(ds, info->port, vlan);
|
return ds->ops->port_vlan_del(ds, info->port, info->vlan);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user