diff options
Diffstat (limited to 'drivers/net/dsa/sja1105/sja1105_main.c')
| -rw-r--r-- | drivers/net/dsa/sja1105/sja1105_main.c | 42 | 
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index df976b259e43..b9def744bcb3 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -22,6 +22,7 @@  #include <linux/if_ether.h>  #include <linux/dsa/8021q.h>  #include "sja1105.h" +#include "sja1105_tas.h"  static void sja1105_hw_reset(struct gpio_desc *gpio, unsigned int pulse_len,  			     unsigned int startup_delay) @@ -384,7 +385,9 @@ static int sja1105_init_general_params(struct sja1105_private *priv)  		/* Disallow dynamic changing of the mirror port */  		.mirr_ptacu = 0,  		.switchid = priv->ds->index, -		/* Priority queue for link-local frames trapped to CPU */ +		/* Priority queue for link-local management frames +		 * (both ingress to and egress from CPU - PTP, STP etc) +		 */  		.hostprio = 7,  		.mac_fltres1 = SJA1105_LINKLOCAL_FILTER_A,  		.mac_flt1    = SJA1105_LINKLOCAL_FILTER_A_MASK, @@ -1380,7 +1383,7 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port,   * modify at runtime (currently only MAC) and restore them after uploading,   * such that this operation is relatively seamless.   */ -static int sja1105_static_config_reload(struct sja1105_private *priv) +int sja1105_static_config_reload(struct sja1105_private *priv)  {  	struct sja1105_mac_config_entry *mac;  	int speed_mbps[SJA1105_NUM_PORTS]; @@ -1711,6 +1714,9 @@ static int sja1105_setup(struct dsa_switch *ds)  	 */  	ds->vlan_filtering_is_global = true; +	/* Advertise the 8 egress queues */ +	ds->num_tx_queues = SJA1105_NUM_TC; +  	/* The DSA/switchdev model brings up switch ports in standalone mode by  	 * default, and that means vlan_filtering is 0 since they're not under  	 * a bridge, so it's safe to set up switch tagging at this time. @@ -1722,12 +1728,28 @@ static void sja1105_teardown(struct dsa_switch *ds)  {  	struct sja1105_private *priv = ds->priv; +	sja1105_tas_teardown(ds);  	cancel_work_sync(&priv->tagger_data.rxtstamp_work);  	skb_queue_purge(&priv->tagger_data.skb_rxtstamp_queue);  	sja1105_ptp_clock_unregister(priv);  	sja1105_static_config_free(&priv->static_config);  } +static int sja1105_port_enable(struct dsa_switch *ds, int port, +			       struct phy_device *phy) +{ +	struct net_device *slave; + +	if (!dsa_is_user_port(ds, port)) +		return 0; + +	slave = ds->ports[port].slave; + +	slave->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER; + +	return 0; +} +  static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,  			     struct sk_buff *skb, bool takets)  { @@ -2036,6 +2058,18 @@ static bool sja1105_port_txtstamp(struct dsa_switch *ds, int port,  	return true;  } +static int sja1105_port_setup_tc(struct dsa_switch *ds, int port, +				 enum tc_setup_type type, +				 void *type_data) +{ +	switch (type) { +	case TC_SETUP_QDISC_TAPRIO: +		return sja1105_setup_tc_taprio(ds, port, type_data); +	default: +		return -EOPNOTSUPP; +	} +} +  static const struct dsa_switch_ops sja1105_switch_ops = {  	.get_tag_protocol	= sja1105_get_tag_protocol,  	.setup			= sja1105_setup, @@ -2049,6 +2083,7 @@ static const struct dsa_switch_ops sja1105_switch_ops = {  	.get_ethtool_stats	= sja1105_get_ethtool_stats,  	.get_sset_count		= sja1105_get_sset_count,  	.get_ts_info		= sja1105_get_ts_info, +	.port_enable		= sja1105_port_enable,  	.port_fdb_dump		= sja1105_fdb_dump,  	.port_fdb_add		= sja1105_fdb_add,  	.port_fdb_del		= sja1105_fdb_del, @@ -2067,6 +2102,7 @@ static const struct dsa_switch_ops sja1105_switch_ops = {  	.port_hwtstamp_set	= sja1105_hwtstamp_set,  	.port_rxtstamp		= sja1105_port_rxtstamp,  	.port_txtstamp		= sja1105_port_txtstamp, +	.port_setup_tc		= sja1105_port_setup_tc,  };  static int sja1105_check_device_id(struct sja1105_private *priv) @@ -2176,6 +2212,8 @@ static int sja1105_probe(struct spi_device *spi)  	}  	mutex_init(&priv->mgmt_lock); +	sja1105_tas_setup(ds); +  	return dsa_register_switch(priv->ds);  }  |