提交 af9b45d0 编写于 作者: C Casper Andersson 提交者: David S. Miller

net: sparx5: Add arbiter for managing PGID table

The PGID (Port Group ID) table holds port masks
for different purposes. The first 72 are reserved
for port destination masks, flood masks, and CPU
forwarding. The rest are shared between multicast,
link aggregation, and virtualization profiles. The
GLAG area is reserved to not be used by anything
else, since it is a subset of the MCAST area.

The arbiter keeps track of which entries are in
use. You can ask for a free ID or give back one
you are done using.
Signed-off-by: NCasper Andersson <casper.casan@gmail.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 57939fdc
...@@ -8,4 +8,4 @@ obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o ...@@ -8,4 +8,4 @@ obj-$(CONFIG_SPARX5_SWITCH) += sparx5-switch.o
sparx5-switch-objs := sparx5_main.o sparx5_packet.o \ sparx5-switch-objs := sparx5_main.o sparx5_packet.o \
sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \ sparx5_netdev.o sparx5_phylink.o sparx5_port.o sparx5_mactable.o sparx5_vlan.o \
sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o \ sparx5_switchdev.o sparx5_calendar.o sparx5_ethtool.o sparx5_fdma.o \
sparx5_ptp.o sparx5_ptp.o sparx5_pgid.o
...@@ -626,6 +626,9 @@ static int sparx5_start(struct sparx5 *sparx5) ...@@ -626,6 +626,9 @@ static int sparx5_start(struct sparx5 *sparx5)
/* Init MAC table, ageing */ /* Init MAC table, ageing */
sparx5_mact_init(sparx5); sparx5_mact_init(sparx5);
/* Init PGID table arbitrator */
sparx5_pgid_init(sparx5);
/* Setup VLANs */ /* Setup VLANs */
sparx5_vlan_init(sparx5); sparx5_vlan_init(sparx5);
......
...@@ -66,6 +66,12 @@ enum sparx5_vlan_port_type { ...@@ -66,6 +66,12 @@ enum sparx5_vlan_port_type {
#define PGID_BCAST (PGID_BASE + 6) #define PGID_BCAST (PGID_BASE + 6)
#define PGID_CPU (PGID_BASE + 7) #define PGID_CPU (PGID_BASE + 7)
#define PGID_TABLE_SIZE 3290
#define PGID_MCAST_START 65
#define PGID_GLAG_START 833
#define PGID_GLAG_END 1088
#define IFH_LEN 9 /* 36 bytes */ #define IFH_LEN 9 /* 36 bytes */
#define NULL_VID 0 #define NULL_VID 0
#define SPX5_MACT_PULL_DELAY (2 * HZ) #define SPX5_MACT_PULL_DELAY (2 * HZ)
...@@ -271,6 +277,8 @@ struct sparx5 { ...@@ -271,6 +277,8 @@ struct sparx5 {
struct mutex ptp_lock; /* lock for ptp interface state */ struct mutex ptp_lock; /* lock for ptp interface state */
u16 ptp_skbs; u16 ptp_skbs;
int ptp_irq; int ptp_irq;
/* PGID allocation map */
u8 pgid_map[PGID_TABLE_SIZE];
}; };
/* sparx5_switchdev.c */ /* sparx5_switchdev.c */
...@@ -359,6 +367,19 @@ void sparx5_ptp_txtstamp_release(struct sparx5_port *port, ...@@ -359,6 +367,19 @@ void sparx5_ptp_txtstamp_release(struct sparx5_port *port,
struct sk_buff *skb); struct sk_buff *skb);
irqreturn_t sparx5_ptp_irq_handler(int irq, void *args); irqreturn_t sparx5_ptp_irq_handler(int irq, void *args);
/* sparx5_pgid.c */
enum sparx5_pgid_type {
SPX5_PGID_FREE,
SPX5_PGID_RESERVED,
SPX5_PGID_MULTICAST,
SPX5_PGID_GLAG
};
void sparx5_pgid_init(struct sparx5 *spx5);
int sparx5_pgid_alloc_glag(struct sparx5 *spx5, u16 *idx);
int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx);
int sparx5_pgid_free(struct sparx5 *spx5, u16 idx);
/* Clock period in picoseconds */ /* Clock period in picoseconds */
static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock) static inline u32 sparx5_clk_period(enum sparx5_core_clockfreq cclock)
{ {
......
// SPDX-License-Identifier: GPL-2.0+
#include "sparx5_main.h"
void sparx5_pgid_init(struct sparx5 *spx5)
{
int i;
for (i = 0; i < PGID_TABLE_SIZE; i++)
spx5->pgid_map[i] = SPX5_PGID_FREE;
/* Reserved for unicast, flood control, broadcast, and CPU.
* These cannot be freed.
*/
for (i = 0; i <= PGID_CPU; i++)
spx5->pgid_map[i] = SPX5_PGID_RESERVED;
}
int sparx5_pgid_alloc_glag(struct sparx5 *spx5, u16 *idx)
{
int i;
for (i = PGID_GLAG_START; i <= PGID_GLAG_END; i++)
if (spx5->pgid_map[i] == SPX5_PGID_FREE) {
spx5->pgid_map[i] = SPX5_PGID_GLAG;
*idx = i;
return 0;
}
return -EBUSY;
}
int sparx5_pgid_alloc_mcast(struct sparx5 *spx5, u16 *idx)
{
int i;
for (i = PGID_MCAST_START; i < PGID_TABLE_SIZE; i++) {
if (i == PGID_GLAG_START)
i = PGID_GLAG_END + 1;
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 <= PGID_CPU || idx >= PGID_TABLE_SIZE)
return -EINVAL;
if (spx5->pgid_map[idx] == SPX5_PGID_FREE)
return -EINVAL;
spx5->pgid_map[idx] = SPX5_PGID_FREE;
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册