ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)),
                         ANA_PGID_PGID, PGID_UC);
 
+       ds->mtu_enforcement_ingress = true;
        /* It looks like the MAC/PCS interrupt register - PM0_IEVENT (0x8040)
         * isn't instantiated for the Felix PF.
         * In-band AN may take a few ms to complete, so we need to poll.
        return false;
 }
 
+static int felix_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+       struct ocelot *ocelot = ds->priv;
+
+       ocelot_port_set_maxlen(ocelot, port, new_mtu);
+
+       return 0;
+}
+
+static int felix_get_max_mtu(struct dsa_switch *ds, int port)
+{
+       struct ocelot *ocelot = ds->priv;
+
+       return ocelot_get_max_mtu(ocelot, port);
+}
+
 static int felix_cls_flower_add(struct dsa_switch *ds, int port,
                                struct flow_cls_offload *cls, bool ingress)
 {
        .port_hwtstamp_set      = felix_hwtstamp_set,
        .port_rxtstamp          = felix_rxtstamp,
        .port_txtstamp          = felix_txtstamp,
+       .port_change_mtu        = felix_change_mtu,
+       .port_max_mtu           = felix_get_max_mtu,
        .cls_flower_add         = felix_cls_flower_add,
        .cls_flower_del         = felix_cls_flower_del,
        .cls_flower_stats       = felix_cls_flower_stats,
 
 
 /* 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
                         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)
 {
 {
        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
                         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 |
 
         */
        u8                              num_phys_ports;
 
+       int                             npi;
+
+       enum ocelot_tag_prefix          inj_prefix;
+       enum ocelot_tag_prefix          xtr_prefix;
+
        u32                             *lags;
 
        struct list_head                multicast;
 int ocelot_port_add_txtstamp_skb(struct ocelot_port *ocelot_port,
                                 struct sk_buff *skb);
 void ocelot_get_txtstamp(struct ocelot *ocelot);
+void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu);
+int ocelot_get_max_mtu(struct ocelot *ocelot, int port);
 int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
                              struct flow_cls_offload *f, bool ingress);
 int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,