diff options
Diffstat (limited to 'drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c')
| -rw-r--r-- | drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c b/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c new file mode 100644 index 000000000000..eae819fa9486 --- /dev/null +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include "sparx5_main.h" + +void sparx5_pgid_init(struct sparx5 *spx5) +{ + int i; + + for (i = 0; i < spx5->data->consts->n_pgids; i++) + spx5->pgid_map[i] = SPX5_PGID_FREE; + + /* Reserved for unicast, flood control, broadcast, and CPU. + * These cannot be freed. + */ + for (i = 0; i <= sparx5_get_pgid(spx5, PGID_CPU); i++) + spx5->pgid_map[i] = SPX5_PGID_RESERVED; +} + +int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx) +{ + int i; + + /* The multicast area starts at index 65, but the first 7 + * are reserved for flood masks and CPU. Start alloc after that. + */ + for (i = sparx5_get_pgid(spx5, PGID_MCAST_START); + i < spx5->data->consts->n_pgids; i++) { + if (spx5->pgid_map[i] == SPX5_PGID_FREE) { + spx5->pgid_map[i] = SPX5_PGID_MULTICAST; + *idx = i; + return 0; + } + } + + return -EBUSY; +} + +int sparx5_pgid_free(struct sparx5 *spx5, u16 idx) +{ + if (idx <= sparx5_get_pgid(spx5, PGID_CPU) || + idx >= spx5->data->consts->n_pgids) + return -EINVAL; + + if (spx5->pgid_map[idx] == SPX5_PGID_FREE) + return -EINVAL; + + spx5->pgid_map[idx] = SPX5_PGID_FREE; + return 0; +} + +int sparx5_get_pgid(struct sparx5 *sparx5, int pgid) +{ + return sparx5->data->consts->n_ports + pgid; +} |
