xref: /linux/drivers/net/ethernet/microchip/sparx5/sparx5_pgid.c (revision fcc79e1714e8c2b8e216dc3149812edd37884eef)
1 // SPDX-License-Identifier: GPL-2.0+
2 #include "sparx5_main.h"
3 
4 void sparx5_pgid_init(struct sparx5 *spx5)
5 {
6 	int i;
7 
8 	for (i = 0; i < spx5->data->consts->n_pgids; i++)
9 		spx5->pgid_map[i] = SPX5_PGID_FREE;
10 
11 	/* Reserved for unicast, flood control, broadcast, and CPU.
12 	 * These cannot be freed.
13 	 */
14 	for (i = 0; i <= sparx5_get_pgid(spx5, PGID_CPU); i++)
15 		spx5->pgid_map[i] = SPX5_PGID_RESERVED;
16 }
17 
18 int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx)
19 {
20 	int i;
21 
22 	/* The multicast area starts at index 65, but the first 7
23 	 * are reserved for flood masks and CPU. Start alloc after that.
24 	 */
25 	for (i = sparx5_get_pgid(spx5, PGID_MCAST_START);
26 	     i < spx5->data->consts->n_pgids; i++) {
27 		if (spx5->pgid_map[i] == SPX5_PGID_FREE) {
28 			spx5->pgid_map[i] = SPX5_PGID_MULTICAST;
29 			*idx = i;
30 			return 0;
31 		}
32 	}
33 
34 	return -EBUSY;
35 }
36 
37 int sparx5_pgid_free(struct sparx5 *spx5, u16 idx)
38 {
39 	if (idx <= sparx5_get_pgid(spx5, PGID_CPU) ||
40 	    idx >= spx5->data->consts->n_pgids)
41 		return -EINVAL;
42 
43 	if (spx5->pgid_map[idx] == SPX5_PGID_FREE)
44 		return -EINVAL;
45 
46 	spx5->pgid_map[idx] = SPX5_PGID_FREE;
47 	return 0;
48 }
49 
50 int sparx5_get_pgid(struct sparx5 *sparx5, int pgid)
51 {
52 	return sparx5->data->consts->n_ports + pgid;
53 }
54