Skip to content

Commit c279c72

Browse files
vladimirolteandavem330
authored andcommitted
net: dsa: sja1105: implement the port MTU callbacks
On this switch, the frame length enforcements are performed by the ingress policers. There are 2 types of those: regular L2 (also called best-effort) and Virtual Link policers (an ARINC664/AFDX concept for defining L2 streams with certain QoS abilities). To avoid future confusion, I prefer to call the reset reason "Best-effort policers", even though the VL policers are not yet supported. We also need to change the setup of the initial static config, such that DSA calls to .change_mtu (which are expensive) become no-ops and don't reset the switch 5 times. A driver-level decision is to unconditionally allow single VLAN-tagged traffic on all ports. The CPU port must accept an additional VLAN header for the DSA tag, which is again a driver-level decision. The policers actually count bytes not only from the SDU, but also from the Ethernet header and FCS, so those need to be accounted for as well. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6ae5834 commit c279c72

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

drivers/net/dsa/sja1105/sja1105.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ enum sja1105_reset_reason {
126126
SJA1105_RX_HWTSTAMPING,
127127
SJA1105_AGEING_TIME,
128128
SJA1105_SCHEDULING,
129+
SJA1105_BEST_EFFORT_POLICING,
129130
};
130131

131132
int sja1105_static_config_reload(struct sja1105_private *priv,

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -519,12 +519,12 @@ static int sja1105_init_avb_params(struct sja1105_private *priv)
519519
#define SJA1105_RATE_MBPS(speed) (((speed) * 64000) / 1000)
520520

521521
static void sja1105_setup_policer(struct sja1105_l2_policing_entry *policing,
522-
int index)
522+
int index, int mtu)
523523
{
524524
policing[index].sharindx = index;
525525
policing[index].smax = 65535; /* Burst size in bytes */
526526
policing[index].rate = SJA1105_RATE_MBPS(1000);
527-
policing[index].maxlen = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
527+
policing[index].maxlen = mtu;
528528
policing[index].partition = 0;
529529
}
530530

@@ -556,12 +556,16 @@ static int sja1105_init_l2_policing(struct sja1105_private *priv)
556556
*/
557557
for (i = 0, k = 0; i < SJA1105_NUM_PORTS; i++) {
558558
int bcast = (SJA1105_NUM_PORTS * SJA1105_NUM_TC) + i;
559+
int mtu = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN;
560+
561+
if (dsa_is_cpu_port(priv->ds, i))
562+
mtu += VLAN_HLEN;
559563

560564
for (j = 0; j < SJA1105_NUM_TC; j++, k++)
561-
sja1105_setup_policer(policing, k);
565+
sja1105_setup_policer(policing, k, mtu);
562566

563567
/* Set up this port's policer for broadcast traffic */
564-
sja1105_setup_policer(policing, bcast);
568+
sja1105_setup_policer(policing, bcast, mtu);
565569
}
566570
return 0;
567571
}
@@ -1544,6 +1548,7 @@ static const char * const sja1105_reset_reasons[] = {
15441548
[SJA1105_RX_HWTSTAMPING] = "RX timestamping",
15451549
[SJA1105_AGEING_TIME] = "Ageing time",
15461550
[SJA1105_SCHEDULING] = "Time-aware scheduling",
1551+
[SJA1105_BEST_EFFORT_POLICING] = "Best-effort policing",
15471552
};
15481553

15491554
/* For situations where we need to change a setting at runtime that is only
@@ -1952,6 +1957,8 @@ static int sja1105_setup(struct dsa_switch *ds)
19521957
/* Advertise the 8 egress queues */
19531958
ds->num_tx_queues = SJA1105_NUM_TC;
19541959

1960+
ds->mtu_enforcement_ingress = true;
1961+
19551962
/* The DSA/switchdev model brings up switch ports in standalone mode by
19561963
* default, and that means vlan_filtering is 0 since they're not under
19571964
* a bridge, so it's safe to set up switch tagging at this time.
@@ -2120,6 +2127,39 @@ static int sja1105_set_ageing_time(struct dsa_switch *ds,
21202127
return sja1105_static_config_reload(priv, SJA1105_AGEING_TIME);
21212128
}
21222129

2130+
static int sja1105_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
2131+
{
2132+
int bcast = (SJA1105_NUM_PORTS * SJA1105_NUM_TC) + port;
2133+
struct sja1105_l2_policing_entry *policing;
2134+
struct sja1105_private *priv = ds->priv;
2135+
int tc;
2136+
2137+
new_mtu += VLAN_ETH_HLEN + ETH_FCS_LEN;
2138+
2139+
if (dsa_is_cpu_port(ds, port))
2140+
new_mtu += VLAN_HLEN;
2141+
2142+
policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;
2143+
2144+
/* We set all 9 port policers to the same value, so just checking the
2145+
* broadcast one is fine.
2146+
*/
2147+
if (policing[bcast].maxlen == new_mtu)
2148+
return 0;
2149+
2150+
for (tc = 0; tc < SJA1105_NUM_TC; tc++)
2151+
policing[port * SJA1105_NUM_TC + tc].maxlen = new_mtu;
2152+
2153+
policing[bcast].maxlen = new_mtu;
2154+
2155+
return sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);
2156+
}
2157+
2158+
static int sja1105_get_max_mtu(struct dsa_switch *ds, int port)
2159+
{
2160+
return 2043 - VLAN_ETH_HLEN - ETH_FCS_LEN;
2161+
}
2162+
21232163
static int sja1105_port_setup_tc(struct dsa_switch *ds, int port,
21242164
enum tc_setup_type type,
21252165
void *type_data)
@@ -2215,6 +2255,8 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
22152255
.setup = sja1105_setup,
22162256
.teardown = sja1105_teardown,
22172257
.set_ageing_time = sja1105_set_ageing_time,
2258+
.port_change_mtu = sja1105_change_mtu,
2259+
.port_max_mtu = sja1105_get_max_mtu,
22182260
.phylink_validate = sja1105_phylink_validate,
22192261
.phylink_mac_link_state = sja1105_mac_pcs_get_state,
22202262
.phylink_mac_config = sja1105_mac_config,

0 commit comments

Comments
 (0)