Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9dfa6911 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller
Browse files

net: dsa: sja1105: Make room for P/Q/R/S FDB operations



The DSA callbacks were written with the E/T (first generation) in mind,
which is quite different.

For P/Q/R/S completely new implementations need to be provided, which
are held as function pointers in the priv->info structure.  We are
taking a slightly roundabout way for this (a function from
sja1105_main.c reads a structure defined in sja1105_spi.c that
points to a function defined in sja1105_main.c), but it is what it is.

The FDB dump callback works for both families, hence no function pointer
for that.

Signed-off-by: default avatarVladimir Oltean <olteanv@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 90c96cca
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -55,6 +55,11 @@ struct sja1105_info {
	const struct sja1105_regs *regs;
	int (*reset_cmd)(const void *ctx, const void *data);
	int (*setup_rgmii_delay)(const void *ctx, int port);
	/* Prototypes from include/net/dsa.h */
	int (*fdb_add_cmd)(struct dsa_switch *ds, int port,
			   const unsigned char *addr, u16 vid);
	int (*fdb_del_cmd)(struct dsa_switch *ds, int port,
			   const unsigned char *addr, u16 vid);
	const char *name;
};

@@ -142,7 +147,15 @@ int sja1105_dynamic_config_write(struct sja1105_private *priv,
				 enum sja1105_blk_idx blk_idx,
				 int index, void *entry, bool keep);

u8 sja1105_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid);
u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid);
int sja1105et_fdb_add(struct dsa_switch *ds, int port,
		      const unsigned char *addr, u16 vid);
int sja1105et_fdb_del(struct dsa_switch *ds, int port,
		      const unsigned char *addr, u16 vid);
int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port,
			const unsigned char *addr, u16 vid);
int sja1105pqrs_fdb_del(struct dsa_switch *ds, int port,
			const unsigned char *addr, u16 vid);

/* Common implementations for the static and dynamic configs */
size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,
+1 −1
Original line number Diff line number Diff line
@@ -552,7 +552,7 @@ static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly)
 * is also received as argument in the Koopman notation that the switch
 * hardware stores it in.
 */
u8 sja1105_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid)
u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid)
{
	struct sja1105_l2_lookup_params_entry *l2_lookup_params =
		priv->static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS].entries;
+42 −14
Original line number Diff line number Diff line
@@ -786,7 +786,7 @@ static inline int sja1105et_fdb_index(int bin, int way)
	return bin * SJA1105ET_FDB_BIN_SIZE + way;
}

static int sja1105_is_fdb_entry_in_bin(struct sja1105_private *priv, int bin,
static int sja1105et_is_fdb_entry_in_bin(struct sja1105_private *priv, int bin,
					 const u8 *addr, u16 vid,
					 struct sja1105_l2_lookup_entry *match,
					 int *last_unused)
@@ -818,7 +818,7 @@ static int sja1105_is_fdb_entry_in_bin(struct sja1105_private *priv, int bin,
	return -1;
}

static int sja1105_fdb_add(struct dsa_switch *ds, int port,
int sja1105et_fdb_add(struct dsa_switch *ds, int port,
		      const unsigned char *addr, u16 vid)
{
	struct sja1105_l2_lookup_entry l2_lookup = {0};
@@ -827,9 +827,9 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
	int last_unused = -1;
	int bin, way;

	bin = sja1105_fdb_hash(priv, addr, vid);
	bin = sja1105et_fdb_hash(priv, addr, vid);

	way = sja1105_is_fdb_entry_in_bin(priv, bin, addr, vid,
	way = sja1105et_is_fdb_entry_in_bin(priv, bin, addr, vid,
					    &l2_lookup, &last_unused);
	if (way >= 0) {
		/* We have an FDB entry. Is our port in the destination
@@ -874,7 +874,7 @@ static int sja1105_fdb_add(struct dsa_switch *ds, int port,
					    true);
}

static int sja1105_fdb_del(struct dsa_switch *ds, int port,
int sja1105et_fdb_del(struct dsa_switch *ds, int port,
		      const unsigned char *addr, u16 vid)
{
	struct sja1105_l2_lookup_entry l2_lookup = {0};
@@ -882,8 +882,8 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port,
	int index, bin, way;
	bool keep;

	bin = sja1105_fdb_hash(priv, addr, vid);
	way = sja1105_is_fdb_entry_in_bin(priv, bin, addr, vid,
	bin = sja1105et_fdb_hash(priv, addr, vid);
	way = sja1105et_is_fdb_entry_in_bin(priv, bin, addr, vid,
					    &l2_lookup, NULL);
	if (way < 0)
		return 0;
@@ -905,6 +905,34 @@ static int sja1105_fdb_del(struct dsa_switch *ds, int port,
					    index, &l2_lookup, keep);
}

int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port,
			const unsigned char *addr, u16 vid)
{
	return -EOPNOTSUPP;
}

int sja1105pqrs_fdb_del(struct dsa_switch *ds, int port,
			const unsigned char *addr, u16 vid)
{
	return -EOPNOTSUPP;
}

static int sja1105_fdb_add(struct dsa_switch *ds, int port,
			   const unsigned char *addr, u16 vid)
{
	struct sja1105_private *priv = ds->priv;

	return priv->info->fdb_add_cmd(ds, port, addr, vid);
}

static int sja1105_fdb_del(struct dsa_switch *ds, int port,
			   const unsigned char *addr, u16 vid)
{
	struct sja1105_private *priv = ds->priv;

	return priv->info->fdb_del_cmd(ds, port, addr, vid);
}

static int sja1105_fdb_dump(struct dsa_switch *ds, int port,
			    dsa_fdb_dump_cb_t *cb, void *data)
{
+12 −0
Original line number Diff line number Diff line
@@ -541,6 +541,8 @@ struct sja1105_info sja1105e_info = {
	.static_ops		= sja1105e_table_ops,
	.dyn_ops		= sja1105et_dyn_ops,
	.reset_cmd		= sja1105et_reset_cmd,
	.fdb_add_cmd		= sja1105et_fdb_add,
	.fdb_del_cmd		= sja1105et_fdb_del,
	.regs			= &sja1105et_regs,
	.name			= "SJA1105E",
};
@@ -550,6 +552,8 @@ struct sja1105_info sja1105t_info = {
	.static_ops		= sja1105t_table_ops,
	.dyn_ops		= sja1105et_dyn_ops,
	.reset_cmd		= sja1105et_reset_cmd,
	.fdb_add_cmd		= sja1105et_fdb_add,
	.fdb_del_cmd		= sja1105et_fdb_del,
	.regs			= &sja1105et_regs,
	.name			= "SJA1105T",
};
@@ -559,6 +563,8 @@ struct sja1105_info sja1105p_info = {
	.static_ops		= sja1105p_table_ops,
	.dyn_ops		= sja1105pqrs_dyn_ops,
	.reset_cmd		= sja1105pqrs_reset_cmd,
	.fdb_add_cmd		= sja1105pqrs_fdb_add,
	.fdb_del_cmd		= sja1105pqrs_fdb_del,
	.regs			= &sja1105pqrs_regs,
	.name			= "SJA1105P",
};
@@ -568,6 +574,8 @@ struct sja1105_info sja1105q_info = {
	.static_ops		= sja1105q_table_ops,
	.dyn_ops		= sja1105pqrs_dyn_ops,
	.reset_cmd		= sja1105pqrs_reset_cmd,
	.fdb_add_cmd		= sja1105pqrs_fdb_add,
	.fdb_del_cmd		= sja1105pqrs_fdb_del,
	.regs			= &sja1105pqrs_regs,
	.name			= "SJA1105Q",
};
@@ -577,6 +585,8 @@ struct sja1105_info sja1105r_info = {
	.static_ops		= sja1105r_table_ops,
	.dyn_ops		= sja1105pqrs_dyn_ops,
	.reset_cmd		= sja1105pqrs_reset_cmd,
	.fdb_add_cmd		= sja1105pqrs_fdb_add,
	.fdb_del_cmd		= sja1105pqrs_fdb_del,
	.regs			= &sja1105pqrs_regs,
	.name			= "SJA1105R",
};
@@ -587,5 +597,7 @@ struct sja1105_info sja1105s_info = {
	.dyn_ops		= sja1105pqrs_dyn_ops,
	.regs			= &sja1105pqrs_regs,
	.reset_cmd		= sja1105pqrs_reset_cmd,
	.fdb_add_cmd		= sja1105pqrs_fdb_add,
	.fdb_del_cmd		= sja1105pqrs_fdb_del,
	.name			= "SJA1105S",
};