diff options
Diffstat (limited to 'drivers/net/dsa')
| -rw-r--r-- | drivers/net/dsa/sja1105/Makefile | 1 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105.h | 43 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_clocking.c | 91 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_dynamic_config.c | 321 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_dynamic_config.h | 1 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_main.c | 132 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_mdio.c | 288 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_spi.c | 282 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_static_config.c | 483 | ||||
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_static_config.h | 99 | 
10 files changed, 1728 insertions, 13 deletions
| diff --git a/drivers/net/dsa/sja1105/Makefile b/drivers/net/dsa/sja1105/Makefile index a860e3a910be..40d69e6c0bae 100644 --- a/drivers/net/dsa/sja1105/Makefile +++ b/drivers/net/dsa/sja1105/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_NET_DSA_SJA1105) += sja1105.o  sja1105-objs := \      sja1105_spi.o \      sja1105_main.o \ +    sja1105_mdio.o \      sja1105_flower.o \      sja1105_ethtool.o \      sja1105_devlink.o \ diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 3c66e5945cca..f762f5488a76 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -13,15 +13,12 @@  #include <linux/mutex.h>  #include "sja1105_static_config.h" -#define SJA1105_NUM_PORTS		5 -#define SJA1105_MAX_NUM_PORTS		SJA1105_NUM_PORTS -#define SJA1105_NUM_TC			8  #define SJA1105ET_FDB_BIN_SIZE		4  /* The hardware value is in multiples of 10 ms.   * The passed parameter is in multiples of 1 ms.   */  #define SJA1105_AGEING_TIME_MS(ms)	((ms) / 10) -#define SJA1105_NUM_L2_POLICERS		45 +#define SJA1105_NUM_L2_POLICERS		SJA1110_MAX_L2_POLICING_COUNT  typedef enum {  	SPI_READ = 0, @@ -70,6 +67,12 @@ struct sja1105_regs {  	u64 rmii_ref_clk[SJA1105_MAX_NUM_PORTS];  	u64 rmii_ext_tx_clk[SJA1105_MAX_NUM_PORTS];  	u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_MAX_NUM_PORTS]; +	u64 mdio_100base_tx; +	u64 mdio_100base_t1; +}; + +struct sja1105_mdio_private { +	struct sja1105_private *priv;  };  enum { @@ -81,6 +84,12 @@ enum {  	SJA1105_SPEED_MAX,  }; +enum sja1105_internal_phy_t { +	SJA1105_NO_PHY		= 0, +	SJA1105_PHY_BASE_TX, +	SJA1105_PHY_BASE_T1, +}; +  struct sja1105_info {  	u64 device_id;  	/* Needed for distinction between P and R, and between Q and S @@ -99,6 +108,7 @@ struct sja1105_info {  	int ptpegr_ts_bytes;  	int num_cbs_shapers;  	int max_frame_mem; +	int num_ports;  	const struct sja1105_dynamic_table_ops *dyn_ops;  	const struct sja1105_table_ops *static_ops;  	const struct sja1105_regs *regs; @@ -125,6 +135,7 @@ struct sja1105_info {  	bool supports_rgmii[SJA1105_MAX_NUM_PORTS];  	bool supports_sgmii[SJA1105_MAX_NUM_PORTS];  	bool supports_2500basex[SJA1105_MAX_NUM_PORTS]; +	enum sja1105_internal_phy_t internal_phy[SJA1105_MAX_NUM_PORTS];  	const u64 port_speed[SJA1105_SPEED_MAX];  }; @@ -248,6 +259,8 @@ struct sja1105_private {  	enum sja1105_vlan_state vlan_state;  	struct devlink_region **regions;  	struct sja1105_cbs_entry *cbs; +	struct mii_bus *mdio_base_t1; +	struct mii_bus *mdio_base_tx;  	struct sja1105_tagger_data tagger_data;  	struct sja1105_ptp_data ptp_data;  	struct sja1105_tas_data tas_data; @@ -277,6 +290,10 @@ int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled,  			   struct netlink_ext_ack *extack);  void sja1105_frame_memory_partitioning(struct sja1105_private *priv); +/* From sja1105_mdio.c */ +int sja1105_mdiobus_register(struct dsa_switch *ds); +void sja1105_mdiobus_unregister(struct dsa_switch *ds); +  /* From sja1105_devlink.c */  int sja1105_devlink_setup(struct dsa_switch *ds);  void sja1105_devlink_teardown(struct dsa_switch *ds); @@ -310,6 +327,10 @@ extern const struct sja1105_info sja1105p_info;  extern const struct sja1105_info sja1105q_info;  extern const struct sja1105_info sja1105r_info;  extern const struct sja1105_info sja1105s_info; +extern const struct sja1105_info sja1110a_info; +extern const struct sja1105_info sja1110b_info; +extern const struct sja1105_info sja1110c_info; +extern const struct sja1105_info sja1110d_info;  /* From sja1105_clocking.c */ @@ -326,8 +347,10 @@ typedef enum {  } sja1105_phy_interface_t;  int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port); +int sja1110_setup_rgmii_delay(const void *ctx, int port);  int sja1105_clocking_setup_port(struct sja1105_private *priv, int port);  int sja1105_clocking_setup(struct sja1105_private *priv); +int sja1110_clocking_setup(struct sja1105_private *priv);  /* From sja1105_ethtool.c */  void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data); @@ -348,6 +371,18 @@ enum sja1105_iotag {  	SJA1105_S_TAG = 1, /* Outer VLAN header */  }; +enum sja1110_vlan_type { +	SJA1110_VLAN_INVALID = 0, +	SJA1110_VLAN_C_TAG = 1, /* Single inner VLAN tag */ +	SJA1110_VLAN_S_TAG = 2, /* Single outer VLAN tag */ +	SJA1110_VLAN_D_TAG = 3, /* Double tagged, use outer tag for lookup */ +}; + +enum sja1110_shaper_type { +	SJA1110_LEAKY_BUCKET_SHAPER = 0, +	SJA1110_CBS_SHAPER = 1, +}; +  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); diff --git a/drivers/net/dsa/sja1105/sja1105_clocking.c b/drivers/net/dsa/sja1105/sja1105_clocking.c index ae297648611f..645edea5a81f 100644 --- a/drivers/net/dsa/sja1105/sja1105_clocking.c +++ b/drivers/net/dsa/sja1105/sja1105_clocking.c @@ -6,6 +6,7 @@  #include "sja1105.h"  #define SJA1105_SIZE_CGU_CMD	4 +#define SJA1110_BASE_TIMER_CLK	SJA1110_CGU_ADDR(0x74)  /* Common structure for CFG_PAD_MIIx_RX and CFG_PAD_MIIx_TX */  struct sja1105_cfg_pad_mii { @@ -61,6 +62,12 @@ struct sja1105_cgu_pll_ctrl {  	u64 pd;  }; +struct sja1110_cgu_outclk { +	u64 clksrc; +	u64 autoblock; +	u64 pd; +}; +  enum {  	CLKSRC_MII0_TX_CLK	= 0x00,  	CLKSRC_MII0_RX_CLK	= 0x01, @@ -461,6 +468,35 @@ sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd,  	sja1105_packing(buf, &cmd->txc_pd,          0,  0, size, op);  } +static void +sja1110_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd, +			       enum packing_op op) +{ +	const int size = SJA1105_SIZE_CGU_CMD; +	u64 range = 4; + +	/* Fields RXC_RANGE and TXC_RANGE select the input frequency range: +	 * 0 = 2.5MHz +	 * 1 = 25MHz +	 * 2 = 50MHz +	 * 3 = 125MHz +	 * 4 = Automatically determined by port speed. +	 * There's no point in defining a structure different than the one for +	 * SJA1105, so just hardcode the frequency range to automatic, just as +	 * before. +	 */ +	sja1105_packing(buf, &cmd->rxc_stable_ovr, 26, 26, size, op); +	sja1105_packing(buf, &cmd->rxc_delay,      25, 21, size, op); +	sja1105_packing(buf, &range,               20, 18, size, op); +	sja1105_packing(buf, &cmd->rxc_bypass,     17, 17, size, op); +	sja1105_packing(buf, &cmd->rxc_pd,         16, 16, size, op); +	sja1105_packing(buf, &cmd->txc_stable_ovr, 10, 10, size, op); +	sja1105_packing(buf, &cmd->txc_delay,       9,  5, size, op); +	sja1105_packing(buf, &range,                4,  2, size, op); +	sja1105_packing(buf, &cmd->txc_bypass,      1,  1, size, op); +	sja1105_packing(buf, &cmd->txc_pd,          0,  0, size, op); +} +  /* Valid range in degrees is an integer between 73.8 and 101.7 */  static u64 sja1105_rgmii_delay(u64 phase)  { @@ -519,6 +555,35 @@ int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port)  				packed_buf, SJA1105_SIZE_CGU_CMD);  } +int sja1110_setup_rgmii_delay(const void *ctx, int port) +{ +	const struct sja1105_private *priv = ctx; +	const struct sja1105_regs *regs = priv->info->regs; +	struct sja1105_cfg_pad_mii_id pad_mii_id = {0}; +	u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; + +	pad_mii_id.rxc_pd = 1; +	pad_mii_id.txc_pd = 1; + +	if (priv->rgmii_rx_delay[port]) { +		pad_mii_id.rxc_delay = sja1105_rgmii_delay(90); +		/* The "BYPASS" bit in SJA1110 is actually a "don't bypass" */ +		pad_mii_id.rxc_bypass = 1; +		pad_mii_id.rxc_pd = 0; +	} + +	if (priv->rgmii_tx_delay[port]) { +		pad_mii_id.txc_delay = sja1105_rgmii_delay(90); +		pad_mii_id.txc_bypass = 1; +		pad_mii_id.txc_pd = 0; +	} + +	sja1110_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK); + +	return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port], +				packed_buf, SJA1105_SIZE_CGU_CMD); +} +  static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port,  					sja1105_mii_role_t role)  { @@ -755,3 +820,29 @@ int sja1105_clocking_setup(struct sja1105_private *priv)  	}  	return 0;  } + +static void +sja1110_cgu_outclk_packing(void *buf, struct sja1110_cgu_outclk *outclk, +			   enum packing_op op) +{ +	const int size = 4; + +	sja1105_packing(buf, &outclk->clksrc,    27, 24, size, op); +	sja1105_packing(buf, &outclk->autoblock, 11, 11, size, op); +	sja1105_packing(buf, &outclk->pd,         0,  0, size, op); +} + +/* Power down the BASE_TIMER_CLK in order to disable the watchdog */ +int sja1110_clocking_setup(struct sja1105_private *priv) +{ +	u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; +	struct sja1110_cgu_outclk outclk_7_c = { +		.clksrc = 0x5, +		.pd = true, +	}; + +	sja1110_cgu_outclk_packing(packed_buf, &outclk_7_c, PACK); + +	return sja1105_xfer_buf(priv, SPI_WRITE, SJA1110_BASE_TIMER_CLK, +				packed_buf, SJA1105_SIZE_CGU_CMD); +} diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c index ff2742f53de3..4c4c04f04269 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c @@ -106,6 +106,9 @@  #define SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD			\  	(SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_LOOKUP_ENTRY) +#define SJA1110_SIZE_VL_POLICING_DYN_CMD			\ +	(SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_POLICING_ENTRY) +  #define SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY			\  	SJA1105_SIZE_DYN_CMD @@ -115,9 +118,15 @@  #define SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD			\  	(SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY) +#define SJA1110_SIZE_L2_LOOKUP_DYN_CMD				\ +	(SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_ENTRY) +  #define SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD			\  	(SJA1105_SIZE_DYN_CMD + 4 + SJA1105_SIZE_VLAN_LOOKUP_ENTRY) +#define SJA1110_SIZE_VLAN_LOOKUP_DYN_CMD			\ +	(SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_VLAN_LOOKUP_ENTRY) +  #define SJA1105_SIZE_L2_FORWARDING_DYN_CMD			\  	(SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_FORWARDING_ENTRY) @@ -133,12 +142,18 @@  #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD		\  	(SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY) +#define SJA1110_SIZE_L2_LOOKUP_PARAMS_DYN_CMD		\ +	(SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY) +  #define SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD			\  	SJA1105_SIZE_DYN_CMD  #define SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD			\  	(SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY) +#define SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD			\ +	(SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_GENERAL_PARAMS_ENTRY) +  #define SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD			\  	(SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY) @@ -151,8 +166,17 @@  #define SJA1105PQRS_SIZE_CBS_DYN_CMD				\  	(SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_CBS_ENTRY) +#define SJA1110_SIZE_XMII_PARAMS_DYN_CMD			\ +	SJA1110_SIZE_XMII_PARAMS_ENTRY + +#define SJA1110_SIZE_L2_POLICING_DYN_CMD			\ +	(SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_POLICING_ENTRY) + +#define SJA1110_SIZE_L2_FORWARDING_PARAMS_DYN_CMD		\ +	SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY +  #define SJA1105_MAX_DYN_CMD_SIZE				\ -	SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD +	SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD  struct sja1105_dyn_cmd {  	bool search; @@ -197,6 +221,19 @@ sja1105pqrs_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  	sja1105_packing(p, &cmd->index,    9,  0, size, op);  } +static void +sja1110_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +			      enum packing_op op) +{ +	u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +	sja1105_packing(p, &cmd->index,   11,  0, size, op); +} +  static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr,  						enum packing_op op)  { @@ -209,6 +246,18 @@ static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr,  }  static void +sja1110_vl_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				enum packing_op op) +{ +	u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->index,   11,  0, size, op); +} + +static void  sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				  enum packing_op op)  { @@ -326,6 +375,18 @@ sja1105pqrs_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr,  	return sja1105pqrs_l2_lookup_entry_packing(buf, entry_ptr, op);  } +static size_t sja1110_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr, +						  enum packing_op op) +{ +	struct sja1105_l2_lookup_entry *entry = entry_ptr; +	u8 *cmd = buf + SJA1110_SIZE_L2_LOOKUP_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op); + +	return sja1110_l2_lookup_entry_packing(buf, entry_ptr, op); +} +  static void  sja1105et_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				enum packing_op op) @@ -437,6 +498,39 @@ sja1105_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  			SJA1105_SIZE_VLAN_LOOKUP_ENTRY, op);  } +/* In SJA1110 there is no gap between the command and the data, yay... */ +static void +sja1110_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				enum packing_op op) +{ +	u8 *p = buf + SJA1110_SIZE_VLAN_LOOKUP_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; +	u64 type_entry = 0; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +	/* Hack: treat 'vlanid' field of struct sja1105_vlan_lookup_entry as +	 * cmd->index. +	 */ +	sja1105_packing(buf, &cmd->index, 38, 27, +			SJA1110_SIZE_VLAN_LOOKUP_ENTRY, op); + +	/* But the VALIDENT bit has disappeared, now we are supposed to +	 * invalidate an entry through the TYPE_ENTRY field of the entry.. +	 * This is a hack to transform the non-zero quality of the TYPE_ENTRY +	 * field into a VALIDENT bit. +	 */ +	if (op == PACK && !cmd->valident) { +		sja1105_packing(buf, &type_entry, 40, 39, +				SJA1110_SIZE_VLAN_LOOKUP_ENTRY, PACK); +	} else if (op == UNPACK) { +		sja1105_packing(buf, &type_entry, 40, 39, +				SJA1110_SIZE_VLAN_LOOKUP_ENTRY, UNPACK); +		cmd->valident = !!type_entry; +	} +} +  static void  sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				  enum packing_op op) @@ -451,6 +545,19 @@ sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  }  static void +sja1110_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				  enum packing_op op) +{ +	u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +	sja1105_packing(p, &cmd->index,    4,  0, size, op); +} + +static void  sja1105et_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				 enum packing_op op)  { @@ -505,6 +612,19 @@ sja1105pqrs_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  }  static void +sja1110_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +			       enum packing_op op) +{ +	u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +	sja1105_packing(p, &cmd->index,    3,  0, size, op); +} + +static void  sja1105et_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				       enum packing_op op)  { @@ -537,6 +657,18 @@ sja1105pqrs_l2_lookup_params_cmd_packing(void *buf,  }  static void +sja1110_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				     enum packing_op op) +{ +	u8 *p = buf + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +} + +static void  sja1105et_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				     enum packing_op op)  { @@ -571,6 +703,18 @@ sja1105pqrs_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  }  static void +sja1110_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				   enum packing_op op) +{ +	u8 *p = buf + SJA1110_SIZE_GENERAL_PARAMS_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +} + +static void  sja1105pqrs_avb_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				   enum packing_op op)  { @@ -596,6 +740,20 @@ sja1105_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  	sja1105_packing(p, &cmd->index,     5,  0, size, op);  } +static void +sja1110_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +			      enum packing_op op) +{ +	u8 *p = buf + SJA1105_SIZE_RETAGGING_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,    31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset,  30, 30, size, op); +	sja1105_packing(p, &cmd->errors,   29, 29, size, op); +	sja1105_packing(p, &cmd->valident, 28, 28, size, op); +	sja1105_packing(p, &cmd->index,     4,  0, size, op); +} +  static void sja1105et_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  				      enum packing_op op)  { @@ -635,6 +793,18 @@ static void sja1105pqrs_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd,  	sja1105_packing(p, &cmd->index,    3,  0, size, op);  } +static void sja1110_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				    enum packing_op op) +{ +	u8 *p = buf + SJA1105PQRS_SIZE_CBS_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +	sja1105_packing(p, &cmd->index,    7,  0, size, op); +} +  static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr,  					    enum packing_op op)  { @@ -650,6 +820,39 @@ static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr,  	return size;  } +static size_t sja1110_cbs_entry_packing(void *buf, void *entry_ptr, +					enum packing_op op) +{ +	const size_t size = SJA1105PQRS_SIZE_CBS_ENTRY; +	struct sja1105_cbs_entry *entry = entry_ptr; +	u64 entry_type = SJA1110_CBS_SHAPER; + +	sja1105_packing(buf, &entry_type,       159, 159, size, op); +	sja1105_packing(buf, &entry->credit_lo, 151, 120, size, op); +	sja1105_packing(buf, &entry->credit_hi, 119,  88, size, op); +	sja1105_packing(buf, &entry->send_slope, 87,  56, size, op); +	sja1105_packing(buf, &entry->idle_slope, 55,  24, size, op); +	return size; +} + +static void sja1110_dummy_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				      enum packing_op op) +{ +} + +static void +sja1110_l2_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, +				enum packing_op op) +{ +	u8 *p = buf + SJA1105_SIZE_L2_POLICING_ENTRY; +	const int size = SJA1105_SIZE_DYN_CMD; + +	sja1105_packing(p, &cmd->valid,   31, 31, size, op); +	sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); +	sja1105_packing(p, &cmd->errors,  29, 29, size, op); +	sja1105_packing(p, &cmd->index,    6,  0, size, op); +} +  #define OP_READ		BIT(0)  #define OP_WRITE	BIT(1)  #define OP_DEL		BIT(2) @@ -832,6 +1035,122 @@ const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = {  	},  }; +/* SJA1110: Third generation */ +const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = { +	[BLK_IDX_VL_LOOKUP] = { +		.entry_packing = sja1110_vl_lookup_entry_packing, +		.cmd_packing = sja1110_vl_lookup_cmd_packing, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT, +		.packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x124), +	}, +	[BLK_IDX_VL_POLICING] = { +		.entry_packing = sja1110_vl_policing_entry_packing, +		.cmd_packing = sja1110_vl_policing_cmd_packing, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.max_entry_count = SJA1110_MAX_VL_POLICING_COUNT, +		.packed_size = SJA1110_SIZE_VL_POLICING_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x310), +	}, +	[BLK_IDX_L2_LOOKUP] = { +		.entry_packing = sja1110_dyn_l2_lookup_entry_packing, +		.cmd_packing = sja1105pqrs_l2_lookup_cmd_packing, +		.access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH), +		.max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, +		.packed_size = SJA1110_SIZE_L2_LOOKUP_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x8c), +	}, +	[BLK_IDX_VLAN_LOOKUP] = { +		.entry_packing = sja1110_vlan_lookup_entry_packing, +		.cmd_packing = sja1110_vlan_lookup_cmd_packing, +		.access = (OP_READ | OP_WRITE | OP_DEL), +		.max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, +		.packed_size = SJA1110_SIZE_VLAN_LOOKUP_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0xb4), +	}, +	[BLK_IDX_L2_FORWARDING] = { +		.entry_packing = sja1110_l2_forwarding_entry_packing, +		.cmd_packing = sja1110_l2_forwarding_cmd_packing, +		.max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0xa8), +	}, +	[BLK_IDX_MAC_CONFIG] = { +		.entry_packing = sja1110_mac_config_entry_packing, +		.cmd_packing = sja1110_mac_config_cmd_packing, +		.max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.packed_size = SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x134), +	}, +	[BLK_IDX_L2_LOOKUP_PARAMS] = { +		.entry_packing = sja1110_l2_lookup_params_entry_packing, +		.cmd_packing = sja1110_l2_lookup_params_cmd_packing, +		.max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.packed_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x158), +	}, +	[BLK_IDX_AVB_PARAMS] = { +		.entry_packing = sja1105pqrs_avb_params_entry_packing, +		.cmd_packing = sja1105pqrs_avb_params_cmd_packing, +		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.packed_size = SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x2000C), +	}, +	[BLK_IDX_GENERAL_PARAMS] = { +		.entry_packing = sja1110_general_params_entry_packing, +		.cmd_packing = sja1110_general_params_cmd_packing, +		.max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.packed_size = SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0xe8), +	}, +	[BLK_IDX_RETAGGING] = { +		.entry_packing = sja1110_retagging_entry_packing, +		.cmd_packing = sja1110_retagging_cmd_packing, +		.max_entry_count = SJA1105_MAX_RETAGGING_COUNT, +		.access = (OP_READ | OP_WRITE | OP_DEL), +		.packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0xdc), +	}, +	[BLK_IDX_CBS] = { +		.entry_packing = sja1110_cbs_entry_packing, +		.cmd_packing = sja1110_cbs_cmd_packing, +		.max_entry_count = SJA1110_MAX_CBS_COUNT, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.packed_size = SJA1105PQRS_SIZE_CBS_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0xc4), +	}, +	[BLK_IDX_XMII_PARAMS] = { +		.entry_packing = sja1110_xmii_params_entry_packing, +		.cmd_packing = sja1110_dummy_cmd_packing, +		.max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, +		.access = (OP_READ | OP_VALID_ANYWAY), +		.packed_size = SJA1110_SIZE_XMII_PARAMS_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x3c), +	}, +	[BLK_IDX_L2_POLICING] = { +		.entry_packing = sja1110_l2_policing_entry_packing, +		.cmd_packing = sja1110_l2_policing_cmd_packing, +		.max_entry_count = SJA1110_MAX_L2_POLICING_COUNT, +		.access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), +		.packed_size = SJA1110_SIZE_L2_POLICING_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x2fc), +	}, +	[BLK_IDX_L2_FORWARDING_PARAMS] = { +		.entry_packing = sja1110_l2_forwarding_params_entry_packing, +		.cmd_packing = sja1110_dummy_cmd_packing, +		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, +		.access = (OP_READ | OP_VALID_ANYWAY), +		.packed_size = SJA1110_SIZE_L2_FORWARDING_PARAMS_DYN_CMD, +		.addr = SJA1110_SPI_ADDR(0x20000), +	}, +}; +  /* Provides read access to the settings through the dynamic interface   * of the switch.   * @blk_idx	is used as key to select from the sja1105_dynamic_table_ops. diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h index 28d4eb5efb8b..a1472f80a059 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h @@ -36,5 +36,6 @@ struct sja1105_mgmt_entry {  extern const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN];  extern const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN]; +extern const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN];  #endif diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index cbce6e90dc63..3b031864ad74 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -168,6 +168,15 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv)  			continue;  		switch (priv->phy_mode[i]) { +		case PHY_INTERFACE_MODE_INTERNAL: +			if (priv->info->internal_phy[i] == SJA1105_NO_PHY) +				goto unsupported; + +			mii->xmii_mode[i] = XMII_MODE_MII; +			if (priv->info->internal_phy[i] == SJA1105_PHY_BASE_TX) +				mii->special[i] = true; + +			break;  		case PHY_INTERFACE_MODE_REVMII:  			role = XMII_PHY;  			fallthrough; @@ -343,6 +352,7 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv)  {  	struct sja1105_table *table;  	struct sja1105_vlan_lookup_entry pvid = { +		.type_entry = SJA1110_VLAN_D_TAG,  		.ving_mirr = 0,  		.vegr_mirr = 0,  		.vmemb_port = 0, @@ -455,6 +465,47 @@ static int sja1105_init_l2_forwarding(struct sja1105_private *priv)  			l2fwd[ds->num_ports + i].vlan_pmap[j] = i;  		} + +		l2fwd[ds->num_ports + i].type_egrpcp2outputq = true; +	} + +	return 0; +} + +static int sja1110_init_pcp_remapping(struct sja1105_private *priv) +{ +	struct sja1110_pcp_remapping_entry *pcp_remap; +	struct dsa_switch *ds = priv->ds; +	struct sja1105_table *table; +	int port, tc; + +	table = &priv->static_config.tables[BLK_IDX_PCP_REMAPPING]; + +	/* Nothing to do for SJA1105 */ +	if (!table->ops->max_entry_count) +		return 0; + +	if (table->entry_count) { +		kfree(table->entries); +		table->entry_count = 0; +	} + +	table->entries = kcalloc(table->ops->max_entry_count, +				 table->ops->unpacked_entry_size, GFP_KERNEL); +	if (!table->entries) +		return -ENOMEM; + +	table->entry_count = table->ops->max_entry_count; + +	pcp_remap = table->entries; + +	/* Repeat the configuration done for vlan_pmap */ +	for (port = 0; port < ds->num_ports; port++) { +		if (dsa_is_unused_port(ds, port)) +			continue; + +		for (tc = 0; tc < SJA1105_NUM_TC; tc++) +			pcp_remap[port].egrpcp[tc] = tc;  	}  	return 0; @@ -523,6 +574,60 @@ void sja1105_frame_memory_partitioning(struct sja1105_private *priv)  	vl_fwd_params->partspc[0] = SJA1105_VL_FRAME_MEMORY;  } +/* SJA1110 TDMACONFIGIDX values: + * + *      | 100 Mbps ports |  1Gbps ports  | 2.5Gbps ports | Disabled ports + * -----+----------------+---------------+---------------+--------------- + *   0  |   0, [5:10]    |     [1:2]     |     [3:4]     |     retag + *   1  |0, [5:10], retag|     [1:2]     |     [3:4]     |       - + *   2  |   0, [5:10]    |  [1:3], retag |       4       |       - + *   3  |   0, [5:10]    |[1:2], 4, retag|       3       |       - + *   4  |  0, 2, [5:10]  |    1, retag   |     [3:4]     |       - + *   5  |  0, 1, [5:10]  |    2, retag   |     [3:4]     |       - + *  14  |   0, [5:10]    | [1:4], retag  |       -       |       - + *  15  |     [5:10]     | [0:4], retag  |       -       |       - + */ +static void sja1110_select_tdmaconfigidx(struct sja1105_private *priv) +{ +	struct sja1105_general_params_entry *general_params; +	struct sja1105_table *table; +	bool port_1_is_base_tx; +	bool port_3_is_2500; +	bool port_4_is_2500; +	u64 tdmaconfigidx; + +	if (priv->info->device_id != SJA1110_DEVICE_ID) +		return; + +	table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; +	general_params = table->entries; + +	/* All the settings below are "as opposed to SGMII", which is the +	 * other pinmuxing option. +	 */ +	port_1_is_base_tx = priv->phy_mode[1] == PHY_INTERFACE_MODE_INTERNAL; +	port_3_is_2500 = priv->phy_mode[3] == PHY_INTERFACE_MODE_2500BASEX; +	port_4_is_2500 = priv->phy_mode[4] == PHY_INTERFACE_MODE_2500BASEX; + +	if (port_1_is_base_tx) +		/* Retagging port will operate at 1 Gbps */ +		tdmaconfigidx = 5; +	else if (port_3_is_2500 && port_4_is_2500) +		/* Retagging port will operate at 100 Mbps */ +		tdmaconfigidx = 1; +	else if (port_3_is_2500) +		/* Retagging port will operate at 1 Gbps */ +		tdmaconfigidx = 3; +	else if (port_4_is_2500) +		/* Retagging port will operate at 1 Gbps */ +		tdmaconfigidx = 2; +	else +		/* Retagging port will operate at 1 Gbps */ +		tdmaconfigidx = 14; + +	general_params->tdmaconfigidx = tdmaconfigidx; +} +  static int sja1105_init_general_params(struct sja1105_private *priv)  {  	struct sja1105_general_params_entry default_general_params = { @@ -598,6 +703,8 @@ static int sja1105_init_general_params(struct sja1105_private *priv)  	((struct sja1105_general_params_entry *)table->entries)[0] =  				default_general_params; +	sja1110_select_tdmaconfigidx(priv); +  	return 0;  } @@ -779,6 +886,9 @@ static int sja1105_static_config_load(struct sja1105_private *priv)  	rc = sja1105_init_avb_params(priv);  	if (rc < 0)  		return rc; +	rc = sja1110_init_pcp_remapping(priv); +	if (rc < 0) +		return rc;  	/* Send initial configuration to hardware via SPI */  	return sja1105_static_config_upload(priv); @@ -2295,6 +2405,7 @@ sja1105_build_bridge_vlans(struct sja1105_private *priv,  		new_vlan[match].vlan_bc |= BIT(v->port);  		if (!v->untagged)  			new_vlan[match].tag_port |= BIT(v->port); +		new_vlan[match].type_entry = SJA1110_VLAN_D_TAG;  	}  	return 0; @@ -2317,6 +2428,7 @@ sja1105_build_dsa_8021q_vlans(struct sja1105_private *priv,  		new_vlan[match].vlan_bc |= BIT(v->port);  		if (!v->untagged)  			new_vlan[match].tag_port |= BIT(v->port); +		new_vlan[match].type_entry = SJA1110_VLAN_D_TAG;  	}  	return 0; @@ -2377,6 +2489,7 @@ static int sja1105_build_subvlans(struct sja1105_private *priv,  			new_vlan[match].tag_port |= BIT(v->port);  		/* But it's always tagged towards the CPU */  		new_vlan[match].tag_port |= BIT(upstream); +		new_vlan[match].type_entry = SJA1110_VLAN_D_TAG;  		/* The Retagging Table generates packet *clones* with  		 * the new VLAN. This is a very odd hardware quirk @@ -2544,6 +2657,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv,  		if (!tmp->untagged)  			new_vlan[match].tag_port |= BIT(tmp->port);  		new_vlan[match].tag_port |= BIT(upstream); +		new_vlan[match].type_entry = SJA1110_VLAN_D_TAG;  		/* Deny egress of @rx_vid towards our front-panel port.  		 * This will force the switch to drop it, and we'll see  		 * only the re-retagged packets (having the original, @@ -3004,11 +3118,19 @@ static int sja1105_setup(struct dsa_switch *ds)  		dev_err(ds->dev, "Failed to register PTP clock: %d\n", rc);  		return rc;  	} + +	rc = sja1105_mdiobus_register(ds); +	if (rc < 0) { +		dev_err(ds->dev, "Failed to register MDIO bus: %pe\n", +			ERR_PTR(rc)); +		goto out_ptp_clock_unregister; +	} +  	/* Create and send configuration down to device */  	rc = sja1105_static_config_load(priv);  	if (rc < 0) {  		dev_err(ds->dev, "Failed to load static config: %d\n", rc); -		goto out_ptp_clock_unregister; +		goto out_mdiobus_unregister;  	}  	/* Configure the CGU (PHY link modes and speeds) */  	rc = priv->info->clocking_setup(priv); @@ -3051,6 +3173,8 @@ static int sja1105_setup(struct dsa_switch *ds)  out_devlink_teardown:  	sja1105_devlink_teardown(ds); +out_mdiobus_unregister: +	sja1105_mdiobus_unregister(ds);  out_ptp_clock_unregister:  	sja1105_ptp_clock_unregister(ds);  out_static_config_free: @@ -3684,7 +3808,7 @@ static int sja1105_probe(struct spi_device *spi)  		return -ENOMEM;  	ds->dev = dev; -	ds->num_ports = SJA1105_MAX_NUM_PORTS; +	ds->num_ports = priv->info->num_ports;  	ds->ops = &sja1105_switch_ops;  	ds->priv = priv;  	priv->ds = ds; @@ -3788,6 +3912,10 @@ static const struct of_device_id sja1105_dt_ids[] = {  	{ .compatible = "nxp,sja1105q", .data = &sja1105q_info },  	{ .compatible = "nxp,sja1105r", .data = &sja1105r_info },  	{ .compatible = "nxp,sja1105s", .data = &sja1105s_info }, +	{ .compatible = "nxp,sja1110a", .data = &sja1110a_info }, +	{ .compatible = "nxp,sja1110b", .data = &sja1110b_info }, +	{ .compatible = "nxp,sja1110c", .data = &sja1110c_info }, +	{ .compatible = "nxp,sja1110d", .data = &sja1110d_info },  	{ /* sentinel */ },  };  MODULE_DEVICE_TABLE(of, sja1105_dt_ids); diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c new file mode 100644 index 000000000000..8dfd06318b23 --- /dev/null +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2021, NXP Semiconductors + */ +#include <linux/of_mdio.h> +#include "sja1105.h" + +enum sja1105_mdio_opcode { +	SJA1105_C45_ADDR = 0, +	SJA1105_C22 = 1, +	SJA1105_C45_DATA = 2, +	SJA1105_C45_DATA_AUTOINC = 3, +}; + +static u64 sja1105_base_t1_encode_addr(struct sja1105_private *priv, +				       int phy, enum sja1105_mdio_opcode op, +				       int xad) +{ +	const struct sja1105_regs *regs = priv->info->regs; + +	return regs->mdio_100base_t1 | (phy << 7) | (op << 5) | (xad << 0); +} + +static int sja1105_base_t1_mdio_read(struct mii_bus *bus, int phy, int reg) +{ +	struct sja1105_mdio_private *mdio_priv = bus->priv; +	struct sja1105_private *priv = mdio_priv->priv; +	u64 addr; +	u32 tmp; +	int rc; + +	if (reg & MII_ADDR_C45) { +		u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + +		addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR, +						   mmd); + +		tmp = reg & MII_REGADDR_C45_MASK; + +		rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); +		if (rc < 0) +			return rc; + +		addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA, +						   mmd); + +		rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); +		if (rc < 0) +			return rc; + +		return tmp & 0xffff; +	} + +	/* Clause 22 read */ +	addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f); + +	rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); +	if (rc < 0) +		return rc; + +	return tmp & 0xffff; +} + +static int sja1105_base_t1_mdio_write(struct mii_bus *bus, int phy, int reg, +				      u16 val) +{ +	struct sja1105_mdio_private *mdio_priv = bus->priv; +	struct sja1105_private *priv = mdio_priv->priv; +	u64 addr; +	u32 tmp; +	int rc; + +	if (reg & MII_ADDR_C45) { +		u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + +		addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR, +						   mmd); + +		tmp = reg & MII_REGADDR_C45_MASK; + +		rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); +		if (rc < 0) +			return rc; + +		addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA, +						   mmd); + +		tmp = val & 0xffff; + +		rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); +		if (rc < 0) +			return rc; + +		return 0; +	} + +	/* Clause 22 write */ +	addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f); + +	tmp = val & 0xffff; + +	return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); +} + +static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg) +{ +	struct sja1105_mdio_private *mdio_priv = bus->priv; +	struct sja1105_private *priv = mdio_priv->priv; +	const struct sja1105_regs *regs = priv->info->regs; +	u32 tmp; +	int rc; + +	rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg, +			      &tmp, NULL); +	if (rc < 0) +		return rc; + +	return tmp & 0xffff; +} + +static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg, +				      u16 val) +{ +	struct sja1105_mdio_private *mdio_priv = bus->priv; +	struct sja1105_private *priv = mdio_priv->priv; +	const struct sja1105_regs *regs = priv->info->regs; +	u32 tmp = val; + +	return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg, +				&tmp, NULL); +} + +static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv, +					    struct device_node *mdio_node) +{ +	struct sja1105_mdio_private *mdio_priv; +	struct device_node *np; +	struct mii_bus *bus; +	int rc = 0; + +	np = of_find_compatible_node(mdio_node, NULL, +				     "nxp,sja1110-base-tx-mdio"); +	if (!np) +		return 0; + +	if (!of_device_is_available(np)) +		goto out_put_np; + +	bus = mdiobus_alloc_size(sizeof(*mdio_priv)); +	if (!bus) { +		rc = -ENOMEM; +		goto out_put_np; +	} + +	bus->name = "SJA1110 100base-TX MDIO bus"; +	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx", +		 dev_name(priv->ds->dev)); +	bus->read = sja1105_base_tx_mdio_read; +	bus->write = sja1105_base_tx_mdio_write; +	bus->parent = priv->ds->dev; +	mdio_priv = bus->priv; +	mdio_priv->priv = priv; + +	rc = of_mdiobus_register(bus, np); +	if (rc) { +		mdiobus_free(bus); +		goto out_put_np; +	} + +	priv->mdio_base_tx = bus; + +out_put_np: +	of_node_put(np); + +	return 0; +} + +static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv) +{ +	if (!priv->mdio_base_tx) +		return; + +	mdiobus_unregister(priv->mdio_base_tx); +	mdiobus_free(priv->mdio_base_tx); +	priv->mdio_base_tx = NULL; +} + +static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv, +					    struct device_node *mdio_node) +{ +	struct sja1105_mdio_private *mdio_priv; +	struct device_node *np; +	struct mii_bus *bus; +	int rc = 0; + +	np = of_find_compatible_node(mdio_node, NULL, +				     "nxp,sja1110-base-t1-mdio"); +	if (!np) +		return 0; + +	if (!of_device_is_available(np)) +		goto out_put_np; + +	bus = mdiobus_alloc_size(sizeof(*mdio_priv)); +	if (!bus) { +		rc = -ENOMEM; +		goto out_put_np; +	} + +	bus->name = "SJA1110 100base-T1 MDIO bus"; +	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1", +		 dev_name(priv->ds->dev)); +	bus->read = sja1105_base_t1_mdio_read; +	bus->write = sja1105_base_t1_mdio_write; +	bus->parent = priv->ds->dev; +	mdio_priv = bus->priv; +	mdio_priv->priv = priv; + +	rc = of_mdiobus_register(bus, np); +	if (rc) { +		mdiobus_free(bus); +		goto out_put_np; +	} + +	priv->mdio_base_t1 = bus; + +out_put_np: +	of_node_put(np); + +	return rc; +} + +static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv) +{ +	if (!priv->mdio_base_t1) +		return; + +	mdiobus_unregister(priv->mdio_base_t1); +	mdiobus_free(priv->mdio_base_t1); +	priv->mdio_base_t1 = NULL; +} + +int sja1105_mdiobus_register(struct dsa_switch *ds) +{ +	struct sja1105_private *priv = ds->priv; +	const struct sja1105_regs *regs = priv->info->regs; +	struct device_node *switch_node = ds->dev->of_node; +	struct device_node *mdio_node; +	int rc; + +	mdio_node = of_get_child_by_name(switch_node, "mdios"); +	if (!mdio_node) +		return 0; + +	if (!of_device_is_available(mdio_node)) +		goto out_put_mdio_node; + +	if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) { +		rc = sja1105_mdiobus_base_tx_register(priv, mdio_node); +		if (rc) +			goto err_put_mdio_node; +	} + +	if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) { +		rc = sja1105_mdiobus_base_t1_register(priv, mdio_node); +		if (rc) +			goto err_free_base_tx_mdiobus; +	} + +out_put_mdio_node: +	of_node_put(mdio_node); + +	return 0; + +err_free_base_tx_mdiobus: +	sja1105_mdiobus_base_tx_unregister(priv); +err_put_mdio_node: +	of_node_put(mdio_node); + +	return rc; +} + +void sja1105_mdiobus_unregister(struct dsa_switch *ds) +{ +	struct sja1105_private *priv = ds->priv; + +	sja1105_mdiobus_base_t1_unregister(priv); +	sja1105_mdiobus_base_tx_unregister(priv); +} diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 786c16a77e46..54ecb5565761 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -193,6 +193,16 @@ static int sja1105pqrs_reset_cmd(struct dsa_switch *ds)  	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL);  } +static int sja1110_reset_cmd(struct dsa_switch *ds) +{ +	struct sja1105_private *priv = ds->priv; +	const struct sja1105_regs *regs = priv->info->regs; +	u32 switch_reset = BIT(20); + +	/* Switch core reset */ +	return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL); +} +  int sja1105_inhibit_tx(const struct sja1105_private *priv,  		       unsigned long port_bitmap, bool tx_inhibited)  { @@ -426,6 +436,8 @@ static struct sja1105_regs sja1105et_regs = {  	.ptpclkval = 0x18, /* Spans 0x18 to 0x19 */  	.ptpclkrate = 0x1A,  	.ptpclkcorp = 0x1D, +	.mdio_100base_tx = SJA1105_RSV_ADDR, +	.mdio_100base_t1 = SJA1105_RSV_ADDR,  };  static struct sja1105_regs sja1105pqrs_regs = { @@ -463,6 +475,92 @@ static struct sja1105_regs sja1105pqrs_regs = {  	.ptpclkrate = 0x1B,  	.ptpclkcorp = 0x1E,  	.ptpsyncts = 0x1F, +	.mdio_100base_tx = SJA1105_RSV_ADDR, +	.mdio_100base_t1 = SJA1105_RSV_ADDR, +}; + +static struct sja1105_regs sja1110_regs = { +	.device_id = SJA1110_SPI_ADDR(0x0), +	.prod_id = SJA1110_ACU_ADDR(0xf00), +	.status = SJA1110_SPI_ADDR(0x4), +	.port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */ +	.vl_status = 0x10000, +	.config = 0x020000, +	.rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */ +	/* Ports 2 and 3 are capable of xMII, but there isn't anything to +	 * configure in the CGU/ACU for them. +	 */ +	.pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR}, +	.pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR}, +	.pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28), +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR}, +	.rmii_pll1 = SJA1105_RSV_ADDR, +	.cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		     SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, +	.stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208, 0x20a, +		       0x20c, 0x20e, 0x210, 0x212, 0x214}, +	.stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440, 0x450, +		       0x460, 0x470, 0x480, 0x490, 0x4a0}, +	.stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640, 0x650, +		       0x660, 0x670, 0x680, 0x690, 0x6a0}, +	.stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460, 0x1478, +			 0x1490, 0x14a8, 0x14c0, 0x14d8, 0x14f0}, +	.mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, +	.mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +		       SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, +	.mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, +	.mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			   SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, +	.rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, +	.rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			 SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, +	.rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, +			    SJA1105_RSV_ADDR}, +	.ptpschtm = SJA1110_SPI_ADDR(0x54), +	.ptppinst = SJA1110_SPI_ADDR(0x5c), +	.ptppindur = SJA1110_SPI_ADDR(0x64), +	.ptp_control = SJA1110_SPI_ADDR(0x68), +	.ptpclkval = SJA1110_SPI_ADDR(0x6c), +	.ptpclkrate = SJA1110_SPI_ADDR(0x74), +	.ptpclkcorp = SJA1110_SPI_ADDR(0x80), +	.ptpsyncts = SJA1110_SPI_ADDR(0x84), +	.mdio_100base_tx = 0x1c2400, +	.mdio_100base_t1 = 0x1c1000,  };  const struct sja1105_info sja1105e_info = { @@ -475,6 +573,7 @@ const struct sja1105_info sja1105e_info = {  	.ptp_ts_bits		= 24,  	.ptpegr_ts_bytes	= 4,  	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY, +	.num_ports		= SJA1105_NUM_PORTS,  	.num_cbs_shapers	= SJA1105ET_MAX_CBS_COUNT,  	.reset_cmd		= sja1105et_reset_cmd,  	.fdb_add_cmd		= sja1105et_fdb_add, @@ -505,6 +604,7 @@ const struct sja1105_info sja1105t_info = {  	.ptp_ts_bits		= 24,  	.ptpegr_ts_bytes	= 4,  	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY, +	.num_ports		= SJA1105_NUM_PORTS,  	.num_cbs_shapers	= SJA1105ET_MAX_CBS_COUNT,  	.reset_cmd		= sja1105et_reset_cmd,  	.fdb_add_cmd		= sja1105et_fdb_add, @@ -535,6 +635,7 @@ const struct sja1105_info sja1105p_info = {  	.ptp_ts_bits		= 32,  	.ptpegr_ts_bytes	= 8,  	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY, +	.num_ports		= SJA1105_NUM_PORTS,  	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,  	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,  	.reset_cmd		= sja1105pqrs_reset_cmd, @@ -566,6 +667,7 @@ const struct sja1105_info sja1105q_info = {  	.ptp_ts_bits		= 32,  	.ptpegr_ts_bytes	= 8,  	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY, +	.num_ports		= SJA1105_NUM_PORTS,  	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,  	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,  	.reset_cmd		= sja1105pqrs_reset_cmd, @@ -597,6 +699,7 @@ const struct sja1105_info sja1105r_info = {  	.ptp_ts_bits		= 32,  	.ptpegr_ts_bytes	= 8,  	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY, +	.num_ports		= SJA1105_NUM_PORTS,  	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,  	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,  	.reset_cmd		= sja1105pqrs_reset_cmd, @@ -630,6 +733,7 @@ const struct sja1105_info sja1105s_info = {  	.ptp_ts_bits		= 32,  	.ptpegr_ts_bytes	= 8,  	.max_frame_mem		= SJA1105_MAX_FRAME_MEMORY, +	.num_ports		= SJA1105_NUM_PORTS,  	.num_cbs_shapers	= SJA1105PQRS_MAX_CBS_COUNT,  	.setup_rgmii_delay	= sja1105pqrs_setup_rgmii_delay,  	.reset_cmd		= sja1105pqrs_reset_cmd, @@ -650,3 +754,181 @@ const struct sja1105_info sja1105s_info = {  	.supports_sgmii		= {false, false, false, false, true},  	.name			= "SJA1105S",  }; + +const struct sja1105_info sja1110a_info = { +	.device_id		= SJA1110_DEVICE_ID, +	.part_no		= SJA1110A_PART_NO, +	.static_ops		= sja1110_table_ops, +	.dyn_ops		= sja1110_dyn_ops, +	.regs			= &sja1110_regs, +	.qinq_tpid		= ETH_P_8021AD, +	.can_limit_mcast_flood	= true, +	.ptp_ts_bits		= 32, +	.ptpegr_ts_bytes	= 8, +	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY, +	.num_ports		= SJA1110_NUM_PORTS, +	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT, +	.setup_rgmii_delay	= sja1110_setup_rgmii_delay, +	.reset_cmd		= sja1110_reset_cmd, +	.fdb_add_cmd		= sja1105pqrs_fdb_add, +	.fdb_del_cmd		= sja1105pqrs_fdb_del, +	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing, +	.clocking_setup		= sja1110_clocking_setup, +	.port_speed		= { +		[SJA1105_SPEED_AUTO] = 0, +		[SJA1105_SPEED_10MBPS] = 4, +		[SJA1105_SPEED_100MBPS] = 3, +		[SJA1105_SPEED_1000MBPS] = 2, +		[SJA1105_SPEED_2500MBPS] = 1, +	}, +	.supports_mii		= {true, true, true, true, false, +				   true, true, true, true, true, true}, +	.supports_rmii		= {false, false, true, true, false, +				   false, false, false, false, false, false}, +	.supports_rgmii		= {false, false, true, true, false, +				   false, false, false, false, false, false}, +	.supports_sgmii		= {false, true, true, true, true, +				   false, false, false, false, false, false}, +	.supports_2500basex	= {false, false, false, true, true, +				   false, false, false, false, false, false}, +	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, +				   SJA1105_NO_PHY, SJA1105_NO_PHY, +				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, +				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, +				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, +				   SJA1105_PHY_BASE_T1}, +	.name			= "SJA1110A", +}; + +const struct sja1105_info sja1110b_info = { +	.device_id		= SJA1110_DEVICE_ID, +	.part_no		= SJA1110B_PART_NO, +	.static_ops		= sja1110_table_ops, +	.dyn_ops		= sja1110_dyn_ops, +	.regs			= &sja1110_regs, +	.qinq_tpid		= ETH_P_8021AD, +	.can_limit_mcast_flood	= true, +	.ptp_ts_bits		= 32, +	.ptpegr_ts_bytes	= 8, +	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY, +	.num_ports		= SJA1110_NUM_PORTS, +	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT, +	.setup_rgmii_delay	= sja1110_setup_rgmii_delay, +	.reset_cmd		= sja1110_reset_cmd, +	.fdb_add_cmd		= sja1105pqrs_fdb_add, +	.fdb_del_cmd		= sja1105pqrs_fdb_del, +	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing, +	.clocking_setup		= sja1110_clocking_setup, +	.port_speed		= { +		[SJA1105_SPEED_AUTO] = 0, +		[SJA1105_SPEED_10MBPS] = 4, +		[SJA1105_SPEED_100MBPS] = 3, +		[SJA1105_SPEED_1000MBPS] = 2, +		[SJA1105_SPEED_2500MBPS] = 1, +	}, +	.supports_mii		= {true, true, true, true, false, +				   true, true, true, true, true, false}, +	.supports_rmii		= {false, false, true, true, false, +				   false, false, false, false, false, false}, +	.supports_rgmii		= {false, false, true, true, false, +				   false, false, false, false, false, false}, +	.supports_sgmii		= {false, false, false, true, true, +				   false, false, false, false, false, false}, +	.supports_2500basex	= {false, false, false, true, true, +				   false, false, false, false, false, false}, +	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, +				   SJA1105_NO_PHY, SJA1105_NO_PHY, +				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, +				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, +				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, +				   SJA1105_NO_PHY}, +	.name			= "SJA1110B", +}; + +const struct sja1105_info sja1110c_info = { +	.device_id		= SJA1110_DEVICE_ID, +	.part_no		= SJA1110C_PART_NO, +	.static_ops		= sja1110_table_ops, +	.dyn_ops		= sja1110_dyn_ops, +	.regs			= &sja1110_regs, +	.qinq_tpid		= ETH_P_8021AD, +	.can_limit_mcast_flood	= true, +	.ptp_ts_bits		= 32, +	.ptpegr_ts_bytes	= 8, +	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY, +	.num_ports		= SJA1110_NUM_PORTS, +	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT, +	.setup_rgmii_delay	= sja1110_setup_rgmii_delay, +	.reset_cmd		= sja1110_reset_cmd, +	.fdb_add_cmd		= sja1105pqrs_fdb_add, +	.fdb_del_cmd		= sja1105pqrs_fdb_del, +	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing, +	.clocking_setup		= sja1110_clocking_setup, +	.port_speed		= { +		[SJA1105_SPEED_AUTO] = 0, +		[SJA1105_SPEED_10MBPS] = 4, +		[SJA1105_SPEED_100MBPS] = 3, +		[SJA1105_SPEED_1000MBPS] = 2, +		[SJA1105_SPEED_2500MBPS] = 1, +	}, +	.supports_mii		= {true, true, true, true, false, +				   true, true, true, false, false, false}, +	.supports_rmii		= {false, false, true, true, false, +				   false, false, false, false, false, false}, +	.supports_rgmii		= {false, false, true, true, false, +				   false, false, false, false, false, false}, +	.supports_sgmii		= {false, false, false, false, true, +				   false, false, false, false, false, false}, +	.supports_2500basex	= {false, false, false, false, true, +				   false, false, false, false, false, false}, +	.internal_phy		= {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, +				   SJA1105_NO_PHY, SJA1105_NO_PHY, +				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, +				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, +				   SJA1105_NO_PHY, SJA1105_NO_PHY, +				   SJA1105_NO_PHY}, +	.name			= "SJA1110C", +}; + +const struct sja1105_info sja1110d_info = { +	.device_id		= SJA1110_DEVICE_ID, +	.part_no		= SJA1110D_PART_NO, +	.static_ops		= sja1110_table_ops, +	.dyn_ops		= sja1110_dyn_ops, +	.regs			= &sja1110_regs, +	.qinq_tpid		= ETH_P_8021AD, +	.can_limit_mcast_flood	= true, +	.ptp_ts_bits		= 32, +	.ptpegr_ts_bytes	= 8, +	.max_frame_mem		= SJA1110_MAX_FRAME_MEMORY, +	.num_ports		= SJA1110_NUM_PORTS, +	.num_cbs_shapers	= SJA1110_MAX_CBS_COUNT, +	.setup_rgmii_delay	= sja1110_setup_rgmii_delay, +	.reset_cmd		= sja1110_reset_cmd, +	.fdb_add_cmd		= sja1105pqrs_fdb_add, +	.fdb_del_cmd		= sja1105pqrs_fdb_del, +	.ptp_cmd_packing	= sja1105pqrs_ptp_cmd_packing, +	.clocking_setup		= sja1110_clocking_setup, +	.port_speed		= { +		[SJA1105_SPEED_AUTO] = 0, +		[SJA1105_SPEED_10MBPS] = 4, +		[SJA1105_SPEED_100MBPS] = 3, +		[SJA1105_SPEED_1000MBPS] = 2, +		[SJA1105_SPEED_2500MBPS] = 1, +	}, +	.supports_mii		= {true, false, true, false, false, +				   true, true, true, false, false, false}, +	.supports_rmii		= {false, false, true, false, false, +				   false, false, false, false, false, false}, +	.supports_rgmii		= {false, false, true, false, false, +				   false, false, false, false, false, false}, +	.supports_sgmii		= {false, true, true, true, true, +				   false, false, false, false, false, false}, +	.internal_phy		= {SJA1105_NO_PHY, SJA1105_NO_PHY, +				   SJA1105_NO_PHY, SJA1105_NO_PHY, +				   SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, +				   SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, +				   SJA1105_NO_PHY, SJA1105_NO_PHY, +				   SJA1105_NO_PHY}, +	.name			= "SJA1110D", +}; diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c index 33f91ecbe07b..eda571819d45 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.c +++ b/drivers/net/dsa/sja1105/sja1105_static_config.c @@ -180,6 +180,42 @@ size_t sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr, +					    enum packing_op op) +{ +	struct sja1105_general_params_entry *entry = entry_ptr; +	const size_t size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY; + +	sja1105_packing(buf, &entry->vllupformat,  447, 447, size, op); +	sja1105_packing(buf, &entry->mirr_ptacu,   446, 446, size, op); +	sja1105_packing(buf, &entry->switchid,     445, 442, size, op); +	sja1105_packing(buf, &entry->hostprio,     441, 439, size, op); +	sja1105_packing(buf, &entry->mac_fltres1,  438, 391, size, op); +	sja1105_packing(buf, &entry->mac_fltres0,  390, 343, size, op); +	sja1105_packing(buf, &entry->mac_flt1,     342, 295, size, op); +	sja1105_packing(buf, &entry->mac_flt0,     294, 247, size, op); +	sja1105_packing(buf, &entry->incl_srcpt1,  246, 246, size, op); +	sja1105_packing(buf, &entry->incl_srcpt0,  245, 245, size, op); +	sja1105_packing(buf, &entry->send_meta1,   244, 244, size, op); +	sja1105_packing(buf, &entry->send_meta0,   243, 243, size, op); +	sja1105_packing(buf, &entry->casc_port,    242, 232, size, op); +	sja1105_packing(buf, &entry->host_port,    231, 228, size, op); +	sja1105_packing(buf, &entry->mirr_port,    227, 224, size, op); +	sja1105_packing(buf, &entry->vlmarker,     223, 192, size, op); +	sja1105_packing(buf, &entry->vlmask,       191, 160, size, op); +	sja1105_packing(buf, &entry->tpid2,        159, 144, size, op); +	sja1105_packing(buf, &entry->ignore2stf,   143, 143, size, op); +	sja1105_packing(buf, &entry->tpid,         142, 127, size, op); +	sja1105_packing(buf, &entry->queue_ts,     126, 126, size, op); +	sja1105_packing(buf, &entry->egrmirrvid,   125, 114, size, op); +	sja1105_packing(buf, &entry->egrmirrpcp,   113, 111, size, op); +	sja1105_packing(buf, &entry->egrmirrdei,   110, 110, size, op); +	sja1105_packing(buf, &entry->replay_port,  109, 106, size, op); +	sja1105_packing(buf, &entry->tdmaconfigidx, 70,  67, size, op); +	sja1105_packing(buf, &entry->tte_en,        16,  16, size, op); +	return size; +} +  static size_t  sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,  					   enum packing_op op) @@ -195,6 +231,20 @@ sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, +						  enum packing_op op) +{ +	struct sja1105_l2_forwarding_params_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY; +	int offset, i; + +	sja1105_packing(buf, &entry->max_dynp, 95, 93, size, op); +	for (i = 0, offset = 5; i < 8; i++, offset += 11) +		sja1105_packing(buf, &entry->part_spc[i], +				offset + 10, offset + 0, size, op); +	return size; +} +  size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,  					   enum packing_op op)  { @@ -211,6 +261,27 @@ size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr, +					   enum packing_op op) +{ +	struct sja1105_l2_forwarding_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY; +	int offset, i; + +	if (entry->type_egrpcp2outputq) { +		for (i = 0, offset = 31; i < SJA1110_NUM_PORTS; +		     i++, offset += 3) { +			sja1105_packing(buf, &entry->vlan_pmap[i], +					offset + 2, offset + 0, size, op); +		} +	} else { +		sja1105_packing(buf, &entry->bc_domain,  63, 53, size, op); +		sja1105_packing(buf, &entry->reach_port, 52, 42, size, op); +		sja1105_packing(buf, &entry->fl_domain,  41, 31, size, op); +	} +	return size; +} +  static size_t  sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,  					 enum packing_op op) @@ -249,6 +320,28 @@ size_t sja1105pqrs_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, +					      enum packing_op op) +{ +	struct sja1105_l2_lookup_params_entry *entry = entry_ptr; +	const size_t size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY; +	int offset, i; + +	for (i = 0, offset = 70; i < SJA1110_NUM_PORTS; i++, offset += 11) +		sja1105_packing(buf, &entry->maxaddrp[i], +				offset + 10, offset + 0, size, op); +	sja1105_packing(buf, &entry->maxage,         69,  55, size, op); +	sja1105_packing(buf, &entry->start_dynspc,   54,  45, size, op); +	sja1105_packing(buf, &entry->drpnolearn,     44,  34, size, op); +	sja1105_packing(buf, &entry->shared_learn,   33,  33, size, op); +	sja1105_packing(buf, &entry->no_enf_hostprt, 32,  32, size, op); +	sja1105_packing(buf, &entry->no_mgmt_learn,  31,  31, size, op); +	sja1105_packing(buf, &entry->use_static,     30,  30, size, op); +	sja1105_packing(buf, &entry->owr_dyn,        29,  29, size, op); +	sja1105_packing(buf, &entry->learn_once,     28,  28, size, op); +	return size; +} +  size_t sja1105et_l2_lookup_entry_packing(void *buf, void *entry_ptr,  					 enum packing_op op)  { @@ -291,6 +384,36 @@ size_t sja1105pqrs_l2_lookup_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_l2_lookup_entry_packing(void *buf, void *entry_ptr, +				       enum packing_op op) +{ +	const size_t size = SJA1110_SIZE_L2_LOOKUP_ENTRY; +	struct sja1105_l2_lookup_entry *entry = entry_ptr; + +	if (entry->lockeds) { +		sja1105_packing(buf, &entry->trap,     168, 168, size, op); +		sja1105_packing(buf, &entry->mirrvlan, 167, 156, size, op); +		sja1105_packing(buf, &entry->takets,   155, 155, size, op); +		sja1105_packing(buf, &entry->mirr,     154, 154, size, op); +		sja1105_packing(buf, &entry->retag,    153, 153, size, op); +	} else { +		sja1105_packing(buf, &entry->touched,  168, 168, size, op); +		sja1105_packing(buf, &entry->age,      167, 153, size, op); +	} +	sja1105_packing(buf, &entry->mask_iotag,   152, 152, size, op); +	sja1105_packing(buf, &entry->mask_vlanid,  151, 140, size, op); +	sja1105_packing(buf, &entry->mask_macaddr, 139,  92, size, op); +	sja1105_packing(buf, &entry->mask_srcport,  91,  88, size, op); +	sja1105_packing(buf, &entry->iotag,         87,  87, size, op); +	sja1105_packing(buf, &entry->vlanid,        86,  75, size, op); +	sja1105_packing(buf, &entry->macaddr,       74,  27, size, op); +	sja1105_packing(buf, &entry->srcport,       26,  23, size, op); +	sja1105_packing(buf, &entry->destports,     22,  12, size, op); +	sja1105_packing(buf, &entry->enfport,       11,  11, size, op); +	sja1105_packing(buf, &entry->index,         10,   1, size, op); +	return size; +} +  static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr,  						enum packing_op op)  { @@ -305,6 +428,20 @@ static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op) +{ +	struct sja1105_l2_policing_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY; + +	sja1105_packing(buf, &entry->sharindx, 63, 57, size, op); +	sja1105_packing(buf, &entry->smax,     56, 39, size, op); +	sja1105_packing(buf, &entry->rate,     38, 21, size, op); +	sja1105_packing(buf, &entry->maxlen,   20, 10, size, op); +	sja1105_packing(buf, &entry->partition, 9,  7, size, op); +	return size; +} +  static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr,  						 enum packing_op op)  { @@ -373,6 +510,40 @@ size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr, +					enum packing_op op) +{ +	const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY; +	struct sja1105_mac_config_entry *entry = entry_ptr; +	int offset, i; + +	for (i = 0, offset = 104; i < 8; i++, offset += 19) { +		sja1105_packing(buf, &entry->enabled[i], +				offset +  0, offset +  0, size, op); +		sja1105_packing(buf, &entry->base[i], +				offset +  9, offset +  1, size, op); +		sja1105_packing(buf, &entry->top[i], +				offset + 18, offset + 10, size, op); +	} +	sja1105_packing(buf, &entry->speed,      98, 96, size, op); +	sja1105_packing(buf, &entry->tp_delin,   95, 80, size, op); +	sja1105_packing(buf, &entry->tp_delout,  79, 64, size, op); +	sja1105_packing(buf, &entry->maxage,     63, 56, size, op); +	sja1105_packing(buf, &entry->vlanprio,   55, 53, size, op); +	sja1105_packing(buf, &entry->vlanid,     52, 41, size, op); +	sja1105_packing(buf, &entry->ing_mirr,   40, 40, size, op); +	sja1105_packing(buf, &entry->egr_mirr,   39, 39, size, op); +	sja1105_packing(buf, &entry->drpnona664, 38, 38, size, op); +	sja1105_packing(buf, &entry->drpdtag,    37, 37, size, op); +	sja1105_packing(buf, &entry->drpuntag,   34, 34, size, op); +	sja1105_packing(buf, &entry->retag,      33, 33, size, op); +	sja1105_packing(buf, &entry->dyn_learn,  32, 32, size, op); +	sja1105_packing(buf, &entry->egress,     31, 31, size, op); +	sja1105_packing(buf, &entry->ingress,    30, 30, size, op); +	sja1105_packing(buf, &entry->ifg,        10,  5, size, op); +	return size; +} +  static size_t  sja1105_schedule_entry_points_params_entry_packing(void *buf, void *entry_ptr,  						   enum packing_op op) @@ -398,6 +569,19 @@ sja1105_schedule_entry_points_entry_packing(void *buf, void *entry_ptr,  	return size;  } +static size_t +sja1110_schedule_entry_points_entry_packing(void *buf, void *entry_ptr, +					    enum packing_op op) +{ +	struct sja1105_schedule_entry_points_entry *entry = entry_ptr; +	const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY; + +	sja1105_packing(buf, &entry->subschindx, 63, 61, size, op); +	sja1105_packing(buf, &entry->delta,      60, 43, size, op); +	sja1105_packing(buf, &entry->address,    42, 31, size, op); +	return size; +} +  static size_t sja1105_schedule_params_entry_packing(void *buf, void *entry_ptr,  						    enum packing_op op)  { @@ -411,6 +595,19 @@ static size_t sja1105_schedule_params_entry_packing(void *buf, void *entry_ptr,  	return size;  } +static size_t sja1110_schedule_params_entry_packing(void *buf, void *entry_ptr, +						    enum packing_op op) +{ +	struct sja1105_schedule_params_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY; +	int offset, i; + +	for (i = 0, offset = 0; i < 8; i++, offset += 12) +		sja1105_packing(buf, &entry->subscheind[i], +				offset + 11, offset + 0, size, op); +	return size; +} +  static size_t sja1105_schedule_entry_packing(void *buf, void *entry_ptr,  					     enum packing_op op)  { @@ -430,6 +627,25 @@ static size_t sja1105_schedule_entry_packing(void *buf, void *entry_ptr,  	return size;  } +static size_t sja1110_schedule_entry_packing(void *buf, void *entry_ptr, +					     enum packing_op op) +{ +	const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY; +	struct sja1105_schedule_entry *entry = entry_ptr; + +	sja1105_packing(buf, &entry->winstindex,  95, 84, size, op); +	sja1105_packing(buf, &entry->winend,      83, 83, size, op); +	sja1105_packing(buf, &entry->winst,       82, 82, size, op); +	sja1105_packing(buf, &entry->destports,   81, 71, size, op); +	sja1105_packing(buf, &entry->setvalid,    70, 70, size, op); +	sja1105_packing(buf, &entry->txen,        69, 69, size, op); +	sja1105_packing(buf, &entry->resmedia_en, 68, 68, size, op); +	sja1105_packing(buf, &entry->resmedia,    67, 60, size, op); +	sja1105_packing(buf, &entry->vlindex,     59, 48, size, op); +	sja1105_packing(buf, &entry->delta,       47, 30, size, op); +	return size; +} +  static size_t  sja1105_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr,  					   enum packing_op op) @@ -445,6 +661,21 @@ sja1105_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr,  	return size;  } +static size_t +sja1110_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr, +					   enum packing_op op) +{ +	struct sja1105_vl_forwarding_params_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY; +	int offset, i; + +	for (i = 0, offset = 8; i < 8; i++, offset += 11) +		sja1105_packing(buf, &entry->partspc[i], +				offset + 10, offset + 0, size, op); +	sja1105_packing(buf, &entry->debugen, 7, 7, size, op); +	return size; +} +  static size_t sja1105_vl_forwarding_entry_packing(void *buf, void *entry_ptr,  						  enum packing_op op)  { @@ -458,6 +689,19 @@ static size_t sja1105_vl_forwarding_entry_packing(void *buf, void *entry_ptr,  	return size;  } +static size_t sja1110_vl_forwarding_entry_packing(void *buf, void *entry_ptr, +						  enum packing_op op) +{ +	struct sja1105_vl_forwarding_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_VL_FORWARDING_ENTRY; + +	sja1105_packing(buf, &entry->type,      31, 31, size, op); +	sja1105_packing(buf, &entry->priority,  30, 28, size, op); +	sja1105_packing(buf, &entry->partition, 27, 25, size, op); +	sja1105_packing(buf, &entry->destports, 24, 14, size, op); +	return size; +} +  size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr,  				       enum packing_op op)  { @@ -492,6 +736,40 @@ size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_vl_lookup_entry_packing(void *buf, void *entry_ptr, +				       enum packing_op op) +{ +	struct sja1105_vl_lookup_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_VL_LOOKUP_ENTRY; + +	if (entry->format == SJA1105_VL_FORMAT_PSFP) { +		/* Interpreting vllupformat as 0 */ +		sja1105_packing(buf, &entry->destports, +				94, 84, size, op); +		sja1105_packing(buf, &entry->iscritical, +				83, 83, size, op); +		sja1105_packing(buf, &entry->macaddr, +				82, 35, size, op); +		sja1105_packing(buf, &entry->vlanid, +				34, 23, size, op); +		sja1105_packing(buf, &entry->port, +				22, 19, size, op); +		sja1105_packing(buf, &entry->vlanprior, +				18, 16, size, op); +	} else { +		/* Interpreting vllupformat as 1 */ +		sja1105_packing(buf, &entry->egrmirr, +				94, 84, size, op); +		sja1105_packing(buf, &entry->ingrmirr, +				83, 83, size, op); +		sja1105_packing(buf, &entry->vlid, +				50, 35, size, op); +		sja1105_packing(buf, &entry->port, +				22, 19, size, op); +	} +	return size; +} +  static size_t sja1105_vl_policing_entry_packing(void *buf, void *entry_ptr,  						enum packing_op op)  { @@ -508,6 +786,22 @@ static size_t sja1105_vl_policing_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_vl_policing_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op) +{ +	struct sja1105_vl_policing_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_VL_POLICING_ENTRY; + +	sja1105_packing(buf, &entry->type,      63, 63, size, op); +	sja1105_packing(buf, &entry->maxlen,    62, 52, size, op); +	sja1105_packing(buf, &entry->sharindx,  51, 40, size, op); +	if (entry->type == 0) { +		sja1105_packing(buf, &entry->bag,    41, 28, size, op); +		sja1105_packing(buf, &entry->jitter, 27, 18, size, op); +	} +	return size; +} +  size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr,  					 enum packing_op op)  { @@ -523,6 +817,22 @@ size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op) +{ +	struct sja1105_vlan_lookup_entry *entry = entry_ptr; +	const size_t size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY; + +	sja1105_packing(buf, &entry->ving_mirr,  95, 85, size, op); +	sja1105_packing(buf, &entry->vegr_mirr,  84, 74, size, op); +	sja1105_packing(buf, &entry->vmemb_port, 73, 63, size, op); +	sja1105_packing(buf, &entry->vlan_bc,    62, 52, size, op); +	sja1105_packing(buf, &entry->tag_port,   51, 41, size, op); +	sja1105_packing(buf, &entry->type_entry, 40, 39, size, op); +	sja1105_packing(buf, &entry->vlanid,     38, 27, size, op); +	return size; +} +  static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr,  						enum packing_op op)  { @@ -539,6 +849,24 @@ static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op) +{ +	const size_t size = SJA1110_SIZE_XMII_PARAMS_ENTRY; +	struct sja1105_xmii_params_entry *entry = entry_ptr; +	int offset, i; + +	for (i = 0, offset = 20; i < SJA1110_NUM_PORTS; i++, offset += 4) { +		sja1105_packing(buf, &entry->xmii_mode[i], +				offset + 1, offset + 0, size, op); +		sja1105_packing(buf, &entry->phy_mac[i], +				offset + 2, offset + 2, size, op); +		sja1105_packing(buf, &entry->special[i], +				offset + 3, offset + 3, size, op); +	} +	return size; +} +  size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr,  				       enum packing_op op)  { @@ -555,6 +883,36 @@ size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr,  	return size;  } +size_t sja1110_retagging_entry_packing(void *buf, void *entry_ptr, +				       enum packing_op op) +{ +	struct sja1105_retagging_entry *entry = entry_ptr; +	const size_t size = SJA1105_SIZE_RETAGGING_ENTRY; + +	sja1105_packing(buf, &entry->egr_port,       63, 53, size, op); +	sja1105_packing(buf, &entry->ing_port,       52, 42, size, op); +	sja1105_packing(buf, &entry->vlan_ing,       41, 30, size, op); +	sja1105_packing(buf, &entry->vlan_egr,       29, 18, size, op); +	sja1105_packing(buf, &entry->do_not_learn,   17, 17, size, op); +	sja1105_packing(buf, &entry->use_dest_ports, 16, 16, size, op); +	sja1105_packing(buf, &entry->destports,      15, 5, size, op); +	return size; +} + +static size_t sja1110_pcp_remapping_entry_packing(void *buf, void *entry_ptr, +						  enum packing_op op) +{ +	struct sja1110_pcp_remapping_entry *entry = entry_ptr; +	const size_t size = SJA1110_SIZE_PCP_REMAPPING_ENTRY; +	int offset, i; + +	for (i = 0, offset = 8; i < SJA1105_NUM_TC; i++, offset += 3) +		sja1105_packing(buf, &entry->egrpcp[i], +				offset + 2, offset + 0, size, op); + +	return size; +} +  size_t sja1105_table_header_packing(void *buf, void *entry_ptr,  				    enum packing_op op)  { @@ -619,6 +977,7 @@ static u64 blk_id_map[BLK_IDX_MAX] = {  	[BLK_IDX_GENERAL_PARAMS] = BLKID_GENERAL_PARAMS,  	[BLK_IDX_RETAGGING] = BLKID_RETAGGING,  	[BLK_IDX_XMII_PARAMS] = BLKID_XMII_PARAMS, +	[BLK_IDX_PCP_REMAPPING] = BLKID_PCP_REMAPPING,  };  const char *sja1105_static_config_error_msg[] = { @@ -1400,6 +1759,130 @@ const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = {  	},  }; +/* SJA1110A: Third generation */ +const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX] = { +	[BLK_IDX_SCHEDULE] = { +		.packing = sja1110_schedule_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_schedule_entry), +		.packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY, +		.max_entry_count = SJA1110_MAX_SCHEDULE_COUNT, +	}, +	[BLK_IDX_SCHEDULE_ENTRY_POINTS] = { +		.packing = sja1110_schedule_entry_points_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), +		.packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, +		.max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, +	}, +	[BLK_IDX_VL_LOOKUP] = { +		.packing = sja1110_vl_lookup_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), +		.packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, +		.max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT, +	}, +	[BLK_IDX_VL_POLICING] = { +		.packing = sja1110_vl_policing_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), +		.packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, +		.max_entry_count = SJA1110_MAX_VL_POLICING_COUNT, +	}, +	[BLK_IDX_VL_FORWARDING] = { +		.packing = sja1110_vl_forwarding_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), +		.packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, +		.max_entry_count = SJA1110_MAX_VL_FORWARDING_COUNT, +	}, +	[BLK_IDX_L2_LOOKUP] = { +		.packing = sja1110_l2_lookup_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), +		.packed_entry_size = SJA1110_SIZE_L2_LOOKUP_ENTRY, +		.max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, +	}, +	[BLK_IDX_L2_POLICING] = { +		.packing = sja1110_l2_policing_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), +		.packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, +		.max_entry_count = SJA1110_MAX_L2_POLICING_COUNT, +	}, +	[BLK_IDX_VLAN_LOOKUP] = { +		.packing = sja1110_vlan_lookup_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), +		.packed_entry_size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY, +		.max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, +	}, +	[BLK_IDX_L2_FORWARDING] = { +		.packing = sja1110_l2_forwarding_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), +		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, +		.max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT, +	}, +	[BLK_IDX_MAC_CONFIG] = { +		.packing = sja1110_mac_config_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), +		.packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, +		.max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT, +	}, +	[BLK_IDX_SCHEDULE_PARAMS] = { +		.packing = sja1110_schedule_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), +		.packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, +	}, +	[BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { +		.packing = sja1105_schedule_entry_points_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), +		.packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, +	}, +	[BLK_IDX_VL_FORWARDING_PARAMS] = { +		.packing = sja1110_vl_forwarding_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), +		.packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, +	}, +	[BLK_IDX_L2_LOOKUP_PARAMS] = { +		.packing = sja1110_l2_lookup_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), +		.packed_entry_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, +	}, +	[BLK_IDX_L2_FORWARDING_PARAMS] = { +		.packing = sja1110_l2_forwarding_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), +		.packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, +	}, +	[BLK_IDX_AVB_PARAMS] = { +		.packing = sja1105pqrs_avb_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), +		.packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, +	}, +	[BLK_IDX_GENERAL_PARAMS] = { +		.packing = sja1110_general_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_general_params_entry), +		.packed_entry_size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, +	}, +	[BLK_IDX_RETAGGING] = { +		.packing = sja1110_retagging_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_retagging_entry), +		.packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, +		.max_entry_count = SJA1105_MAX_RETAGGING_COUNT, +	}, +	[BLK_IDX_XMII_PARAMS] = { +		.packing = sja1110_xmii_params_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), +		.packed_entry_size = SJA1110_SIZE_XMII_PARAMS_ENTRY, +		.max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, +	}, +	[BLK_IDX_PCP_REMAPPING] = { +		.packing = sja1110_pcp_remapping_entry_packing, +		.unpacked_entry_size = sizeof(struct sja1110_pcp_remapping_entry), +		.packed_entry_size = SJA1110_SIZE_PCP_REMAPPING_ENTRY, +		.max_entry_count = SJA1110_MAX_PCP_REMAPPING_COUNT, +	}, +}; +  int sja1105_static_config_init(struct sja1105_static_config *config,  			       const struct sja1105_table_ops *static_ops,  			       u64 device_id) diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.h b/drivers/net/dsa/sja1105/sja1105_static_config.h index 4ddb06bd8e92..9bef51791bff 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.h +++ b/drivers/net/dsa/sja1105/sja1105_static_config.h @@ -9,21 +9,30 @@  #include <linux/types.h>  #include <asm/types.h> +#define SJA1105_NUM_PORTS				5 +#define SJA1110_NUM_PORTS				11 +#define SJA1105_MAX_NUM_PORTS				SJA1110_NUM_PORTS +#define SJA1105_NUM_TC					8 +  #define SJA1105_SIZE_SPI_MSG_HEADER			4  #define SJA1105_SIZE_SPI_MSG_MAXLEN			(64 * 4)  #define SJA1105_SIZE_DEVICE_ID				4  #define SJA1105_SIZE_TABLE_HEADER			12  #define SJA1105_SIZE_SCHEDULE_ENTRY			8 +#define SJA1110_SIZE_SCHEDULE_ENTRY			12  #define SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY	4 +#define SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY	8  #define SJA1105_SIZE_VL_LOOKUP_ENTRY			12  #define SJA1105_SIZE_VL_POLICING_ENTRY			8  #define SJA1105_SIZE_VL_FORWARDING_ENTRY		4  #define SJA1105_SIZE_L2_POLICING_ENTRY			8  #define SJA1105_SIZE_VLAN_LOOKUP_ENTRY			8 +#define SJA1110_SIZE_VLAN_LOOKUP_ENTRY			12  #define SJA1105_SIZE_L2_FORWARDING_ENTRY		8  #define SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY		12  #define SJA1105_SIZE_RETAGGING_ENTRY			8  #define SJA1105_SIZE_XMII_PARAMS_ENTRY			4 +#define SJA1110_SIZE_XMII_PARAMS_ENTRY			8  #define SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY		12  #define SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY	4  #define SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY         12 @@ -34,11 +43,15 @@  #define SJA1105ET_SIZE_AVB_PARAMS_ENTRY			12  #define SJA1105ET_SIZE_CBS_ENTRY			16  #define SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY		20 +#define SJA1110_SIZE_L2_LOOKUP_ENTRY			24  #define SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY		32  #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY		16 +#define SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY		28  #define SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY		44 +#define SJA1110_SIZE_GENERAL_PARAMS_ENTRY		56  #define SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY		16  #define SJA1105PQRS_SIZE_CBS_ENTRY			20 +#define SJA1110_SIZE_PCP_REMAPPING_ENTRY		4  /* UM10944.pdf Page 11, Table 2. Configuration Blocks */  enum { @@ -61,6 +74,7 @@ enum {  	BLKID_GENERAL_PARAMS				= 0x11,  	BLKID_RETAGGING					= 0x12,  	BLKID_CBS					= 0x13, +	BLKID_PCP_REMAPPING				= 0x1C,  	BLKID_XMII_PARAMS				= 0x4E,  }; @@ -85,6 +99,7 @@ enum sja1105_blk_idx {  	BLK_IDX_RETAGGING,  	BLK_IDX_CBS,  	BLK_IDX_XMII_PARAMS, +	BLK_IDX_PCP_REMAPPING,  	BLK_IDX_MAX,  	/* Fake block indices that are only valid for dynamic access */  	BLK_IDX_MGMT_ROUTE, @@ -93,15 +108,22 @@ enum sja1105_blk_idx {  };  #define SJA1105_MAX_SCHEDULE_COUNT			1024 +#define SJA1110_MAX_SCHEDULE_COUNT			4096  #define SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT		2048  #define SJA1105_MAX_VL_LOOKUP_COUNT			1024 +#define SJA1110_MAX_VL_LOOKUP_COUNT			4096  #define SJA1105_MAX_VL_POLICING_COUNT			1024 +#define SJA1110_MAX_VL_POLICING_COUNT			4096  #define SJA1105_MAX_VL_FORWARDING_COUNT			1024 +#define SJA1110_MAX_VL_FORWARDING_COUNT			4096  #define SJA1105_MAX_L2_LOOKUP_COUNT			1024  #define SJA1105_MAX_L2_POLICING_COUNT			45 +#define SJA1110_MAX_L2_POLICING_COUNT			110  #define SJA1105_MAX_VLAN_LOOKUP_COUNT			4096  #define SJA1105_MAX_L2_FORWARDING_COUNT			13 +#define SJA1110_MAX_L2_FORWARDING_COUNT			19  #define SJA1105_MAX_MAC_CONFIG_COUNT			5 +#define SJA1110_MAX_MAC_CONFIG_COUNT			11  #define SJA1105_MAX_SCHEDULE_PARAMS_COUNT		1  #define SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT	1  #define SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT		1 @@ -113,8 +135,11 @@ enum sja1105_blk_idx {  #define SJA1105_MAX_AVB_PARAMS_COUNT			1  #define SJA1105ET_MAX_CBS_COUNT				10  #define SJA1105PQRS_MAX_CBS_COUNT			16 +#define SJA1110_MAX_CBS_COUNT				80 +#define SJA1110_MAX_PCP_REMAPPING_COUNT			11  #define SJA1105_MAX_FRAME_MEMORY			929 +#define SJA1110_MAX_FRAME_MEMORY			1820  #define SJA1105_FRAME_MEMORY_RETAGGING_OVERHEAD		19  #define SJA1105_VL_FRAME_MEMORY				100 @@ -122,12 +147,26 @@ enum sja1105_blk_idx {  #define SJA1105T_DEVICE_ID				0x9E00030Eull  #define SJA1105PR_DEVICE_ID				0xAF00030Eull  #define SJA1105QS_DEVICE_ID				0xAE00030Eull +#define SJA1110_DEVICE_ID				0xB700030Full  #define SJA1105ET_PART_NO				0x9A83  #define SJA1105P_PART_NO				0x9A84  #define SJA1105Q_PART_NO				0x9A85  #define SJA1105R_PART_NO				0x9A86  #define SJA1105S_PART_NO				0x9A87 +#define SJA1110A_PART_NO				0x1110 +#define SJA1110B_PART_NO				0x1111 +#define SJA1110C_PART_NO				0x1112 +#define SJA1110D_PART_NO				0x1113 + +#define SJA1110_ACU			0x1c4400 +#define SJA1110_RGU			0x1c6000 +#define SJA1110_CGU			0x1c6400 + +#define SJA1110_SPI_ADDR(x)		((x) / 4) +#define SJA1110_ACU_ADDR(x)		(SJA1110_ACU + SJA1110_SPI_ADDR(x)) +#define SJA1110_CGU_ADDR(x)		(SJA1110_CGU + SJA1110_SPI_ADDR(x)) +#define SJA1110_RGU_ADDR(x)		(SJA1110_RGU + SJA1110_SPI_ADDR(x))  #define SJA1105_RSV_ADDR		0xffffffffffffffffull @@ -175,6 +214,9 @@ struct sja1105_general_params_entry {  	u64 egrmirrpcp;  	u64 egrmirrdei;  	u64 replay_port; +	/* SJA1110 only */ +	u64 tte_en; +	u64 tdmaconfigidx;  };  struct sja1105_schedule_entry_points_entry { @@ -195,6 +237,7 @@ struct sja1105_vlan_lookup_entry {  	u64 vlan_bc;  	u64 tag_port;  	u64 vlanid; +	u64 type_entry; /* SJA1110 only */  };  struct sja1105_l2_lookup_entry { @@ -207,11 +250,17 @@ struct sja1105_l2_lookup_entry {  	u64 mask_iotag;  	u64 mask_vlanid;  	u64 mask_macaddr; +	u64 mask_srcport;  	u64 iotag; +	u64 srcport;  	u64 lockeds;  	union {  		/* LOCKEDS=1: Static FDB entries */  		struct { +			/* TSREG is deprecated in SJA1110, TRAP is supported only +			 * in SJA1110. +			 */ +			u64 trap;  			u64 tsreg;  			u64 mirrvlan;  			u64 takets; @@ -227,7 +276,7 @@ struct sja1105_l2_lookup_entry {  };  struct sja1105_l2_lookup_params_entry { -	u64 maxaddrp[5];     /* P/Q/R/S only */ +	u64 maxaddrp[SJA1105_MAX_NUM_PORTS]; /* P/Q/R/S only */  	u64 start_dynspc;    /* P/Q/R/S only */  	u64 drpnolearn;      /* P/Q/R/S only */  	u64 use_static;      /* P/Q/R/S only */ @@ -245,7 +294,9 @@ struct sja1105_l2_forwarding_entry {  	u64 bc_domain;  	u64 reach_port;  	u64 fl_domain; -	u64 vlan_pmap[8]; +	/* This is actually max(SJA1105_NUM_TC, SJA1105_MAX_NUM_PORTS) */ +	u64 vlan_pmap[SJA1105_MAX_NUM_PORTS]; +	bool type_egrpcp2outputq;  };  struct sja1105_l2_forwarding_params_entry { @@ -300,8 +351,8 @@ struct sja1105_retagging_entry {  };  struct sja1105_cbs_entry { -	u64 port; -	u64 prio; +	u64 port; /* Not used for SJA1110 */ +	u64 prio; /* Not used for SJA1110 */  	u64 credit_hi;  	u64 credit_lo;  	u64 send_slope; @@ -309,8 +360,19 @@ struct sja1105_cbs_entry {  };  struct sja1105_xmii_params_entry { -	u64 phy_mac[5]; -	u64 xmii_mode[5]; +	u64 phy_mac[SJA1105_MAX_NUM_PORTS]; +	u64 xmii_mode[SJA1105_MAX_NUM_PORTS]; +	/* The SJA1110 insists being a snowflake, and requires SGMII, +	 * 2500base-x and internal MII ports connected to the 100base-TX PHY to +	 * set this bit. We set it unconditionally from the high-level logic, +	 * and only sja1110_xmii_params_entry_packing writes it to the static +	 * config. I have no better name for it than "special". +	 */ +	u64 special[SJA1105_MAX_NUM_PORTS]; +}; + +struct sja1110_pcp_remapping_entry { +	u64 egrpcp[SJA1105_NUM_TC];  };  enum { @@ -391,6 +453,7 @@ extern const struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX];  extern const struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX];  extern const struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX];  extern const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX]; +extern const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX];  size_t sja1105_table_header_packing(void *buf, void *hdr, enum packing_op op);  void @@ -438,23 +501,47 @@ void sja1105_packing(void *buf, u64 *val, int start, int end,  /* Common implementations for the static and dynamic configs */  size_t sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr,  						enum packing_op op); +size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr, +					    enum packing_op op);  size_t sja1105pqrs_l2_lookup_params_entry_packing(void *buf, void *entry_ptr,  						  enum packing_op op); +size_t sja1110_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, +					      enum packing_op op);  size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr,  					   enum packing_op op); +size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr, +					   enum packing_op op);  size_t sja1105pqrs_l2_lookup_entry_packing(void *buf, void *entry_ptr,  					   enum packing_op op);  size_t sja1105et_l2_lookup_entry_packing(void *buf, void *entry_ptr,  					 enum packing_op op); +size_t sja1110_l2_lookup_entry_packing(void *buf, void *entry_ptr, +				       enum packing_op op);  size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr,  					 enum packing_op op); +size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op);  size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr,  				       enum packing_op op); +size_t sja1110_retagging_entry_packing(void *buf, void *entry_ptr, +				       enum packing_op op);  size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr,  					    enum packing_op op); +size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr, +					enum packing_op op);  size_t sja1105pqrs_avb_params_entry_packing(void *buf, void *entry_ptr,  					    enum packing_op op);  size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr,  				       enum packing_op op); +size_t sja1110_vl_lookup_entry_packing(void *buf, void *entry_ptr, +				       enum packing_op op); +size_t sja1110_vl_policing_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op); +size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op); +size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr, +					 enum packing_op op); +size_t sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, +						  enum packing_op op);  #endif |