@@ -63,6 +63,36 @@ void lan937x_cfg_port_member(struct ksz_device *dev, int port, u8 member)
lan937x_pwrite32(dev, port, REG_PORT_VLAN_MEMBERSHIP__4, member);
}
+static void lan937x_flush_dyn_mac_table(struct ksz_device *dev, int port)
+{
+ unsigned int value;
+ u8 data;
+
+ regmap_update_bits(dev->regmap[0], REG_SW_LUE_CTRL_2,
+ SW_FLUSH_OPTION_M << SW_FLUSH_OPTION_S,
+ SW_FLUSH_OPTION_DYN_MAC << SW_FLUSH_OPTION_S);
+
+ if (port < dev->port_cnt) {
+ /* flush individual port */
+ lan937x_pread8(dev, port, P_STP_CTRL, &data);
+ if (!(data & PORT_LEARN_DISABLE))
+ lan937x_pwrite8(dev, port, P_STP_CTRL,
+ (data | PORT_LEARN_DISABLE));
+ lan937x_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_DYN_MAC_TABLE,
+ true);
+
+ regmap_read_poll_timeout(dev->regmap[0], S_FLUSH_TABLE_CTRL,
+ value,
+ !(value & SW_FLUSH_DYN_MAC_TABLE), 10,
+ 1000);
+
+ lan937x_pwrite8(dev, port, P_STP_CTRL, data);
+ } else {
+ /* flush all */
+ lan937x_cfg(dev, S_FLUSH_TABLE_CTRL, SW_FLUSH_STP_TABLE, true);
+ }
+}
+
int lan937x_reset_switch(struct ksz_device *dev)
{
u32 data32;
@@ -437,6 +467,7 @@ static int lan937x_init(struct ksz_device *dev)
const struct ksz_dev_ops lan937x_dev_ops = {
.get_port_addr = lan937x_get_port_addr,
.cfg_port_member = lan937x_cfg_port_member,
+ .flush_dyn_mac_table = lan937x_flush_dyn_mac_table,
.port_setup = lan937x_port_setup,
.shutdown = lan937x_reset_switch,
.detect = lan937x_switch_detect,
@@ -8,6 +8,7 @@
#include <linux/phy.h>
#include <linux/of_net.h>
#include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
#include <linux/math.h>
#include <net/dsa.h>
#include <net/switchdev.h>
@@ -217,6 +218,46 @@ static int lan937x_setup(struct dsa_switch *ds)
return 0;
}
+static int lan937x_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+ struct ksz_device *dev = ds->priv;
+ int ret;
+
+ new_mtu += VLAN_ETH_HLEN + ETH_FCS_LEN;
+
+ if (dsa_is_cpu_port(ds, port))
+ new_mtu += LAN937X_TAG_LEN;
+
+ if (new_mtu >= FR_MIN_SIZE)
+ ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
+ PORT_JUMBO_EN, true);
+ else
+ ret = lan937x_port_cfg(dev, port, REG_PORT_MAC_CTRL_0,
+ PORT_JUMBO_EN, false);
+ if (ret < 0) {
+ dev_err(ds->dev, "failed to enable jumbo\n");
+ return ret;
+ }
+
+ /* Write the frame size in PORT_MAX_FR_SIZE register */
+ ret = lan937x_pwrite16(dev, port, PORT_MAX_FR_SIZE, new_mtu);
+ if (ret < 0) {
+ dev_err(ds->dev, "failed to change the mtu\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int lan937x_get_max_mtu(struct dsa_switch *ds, int port)
+{
+ /* Frame max size is 9000 (= 0x2328) if
+ * jumbo frame support is enabled, PORT_JUMBO_EN bit will be enabled
+ * based on mtu in lan937x_change_mtu() API
+ */
+ return (FR_MAX_SIZE - VLAN_ETH_HLEN - ETH_FCS_LEN);
+}
+
const struct dsa_switch_ops lan937x_switch_ops = {
.get_tag_protocol = lan937x_get_tag_protocol,
.setup = lan937x_setup,
@@ -226,6 +267,9 @@ const struct dsa_switch_ops lan937x_switch_ops = {
.port_bridge_join = ksz_port_bridge_join,
.port_bridge_leave = ksz_port_bridge_leave,
.port_stp_state_set = lan937x_port_stp_state_set,
+ .port_fast_age = ksz_port_fast_age,
+ .port_max_mtu = lan937x_get_max_mtu,
+ .port_change_mtu = lan937x_change_mtu,
};
int lan937x_switch_register(struct ksz_device *dev)
This patch add the support for port_max_mtu, port_change_mtu and port_fast_age dsa functionality. Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com> --- drivers/net/dsa/microchip/lan937x_dev.c | 31 +++++++++++++++++ drivers/net/dsa/microchip/lan937x_main.c | 44 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+)