net: dsa: felix: support changing the MTU
Changing the MTU for this switch means altering the DEV_GMII:MAC_CFG_STATUS:MAC_MAXLEN_CFG field MAX_LEN, which in turn limits the size of frames that can be received. Special accounting needs to be done for the DSA CPU port (NPI port in hardware terms). The NPI port configuration needs to be held inside the private ocelot structure, since it is now accessed from multiple places. 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>
This commit is contained in:

committed by
David S. Miller

parent
fb77ffc6ec
commit
0b912fc93a
@@ -2185,13 +2185,25 @@ static int ocelot_init_timestamp(struct ocelot *ocelot)
|
||||
|
||||
/* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu.
|
||||
* The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG.
|
||||
* In the special case that it's the NPI port that we're configuring, the
|
||||
* length of the tag and optional prefix needs to be accounted for privately,
|
||||
* in order to be able to sustain communication at the requested @sdu.
|
||||
*/
|
||||
static void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
|
||||
void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
|
||||
{
|
||||
struct ocelot_port *ocelot_port = ocelot->ports[port];
|
||||
int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN;
|
||||
int atop_wm;
|
||||
|
||||
if (port == ocelot->npi) {
|
||||
maxlen += OCELOT_TAG_LEN;
|
||||
|
||||
if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_SHORT)
|
||||
maxlen += OCELOT_SHORT_PREFIX_LEN;
|
||||
else if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_LONG)
|
||||
maxlen += OCELOT_LONG_PREFIX_LEN;
|
||||
}
|
||||
|
||||
ocelot_port_writel(ocelot_port, maxlen, DEV_MAC_MAXLEN_CFG);
|
||||
|
||||
/* Set Pause WM hysteresis
|
||||
@@ -2209,6 +2221,24 @@ static void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
|
||||
SYS_ATOP, port);
|
||||
ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG);
|
||||
}
|
||||
EXPORT_SYMBOL(ocelot_port_set_maxlen);
|
||||
|
||||
int ocelot_get_max_mtu(struct ocelot *ocelot, int port)
|
||||
{
|
||||
int max_mtu = 65535 - ETH_HLEN - ETH_FCS_LEN;
|
||||
|
||||
if (port == ocelot->npi) {
|
||||
max_mtu -= OCELOT_TAG_LEN;
|
||||
|
||||
if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_SHORT)
|
||||
max_mtu -= OCELOT_SHORT_PREFIX_LEN;
|
||||
else if (ocelot->inj_prefix == OCELOT_TAG_PREFIX_LONG)
|
||||
max_mtu -= OCELOT_LONG_PREFIX_LEN;
|
||||
}
|
||||
|
||||
return max_mtu;
|
||||
}
|
||||
EXPORT_SYMBOL(ocelot_get_max_mtu);
|
||||
|
||||
void ocelot_init_port(struct ocelot *ocelot, int port)
|
||||
{
|
||||
@@ -2318,6 +2348,10 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
|
||||
{
|
||||
int cpu = ocelot->num_phys_ports;
|
||||
|
||||
ocelot->npi = npi;
|
||||
ocelot->inj_prefix = injection;
|
||||
ocelot->xtr_prefix = extraction;
|
||||
|
||||
/* The unicast destination PGID for the CPU port module is unused */
|
||||
ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, cpu);
|
||||
/* Instead set up a multicast destination PGID for traffic copied to
|
||||
@@ -2330,19 +2364,10 @@ void ocelot_configure_cpu(struct ocelot *ocelot, int npi,
|
||||
ANA_PORT_PORT_CFG, cpu);
|
||||
|
||||
if (npi >= 0 && npi < ocelot->num_phys_ports) {
|
||||
int sdu = ETH_DATA_LEN + OCELOT_TAG_LEN;
|
||||
|
||||
ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M |
|
||||
QSYS_EXT_CPU_CFG_EXT_CPU_PORT(npi),
|
||||
QSYS_EXT_CPU_CFG);
|
||||
|
||||
if (injection == OCELOT_TAG_PREFIX_SHORT)
|
||||
sdu += OCELOT_SHORT_PREFIX_LEN;
|
||||
else if (injection == OCELOT_TAG_PREFIX_LONG)
|
||||
sdu += OCELOT_LONG_PREFIX_LEN;
|
||||
|
||||
ocelot_port_set_maxlen(ocelot, npi, sdu);
|
||||
|
||||
/* Enable NPI port */
|
||||
ocelot_write_rix(ocelot,
|
||||
QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE |
|
||||
|
Reference in New Issue
Block a user