diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h index 87071dd7bea..e02150e447b 100644 --- a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe.h @@ -263,6 +263,7 @@ #define PPE_PORT_BRIDGE_CTRL_TXMAC_EN BIT(16) #define PPE_MC_MTU_CTRL(port) (PPE_L2_BASE + 0xa00 + (port) * 0x4) +#define PPE_MC_MTU_CTRL_MTU GENMASK(13, 0) #define PPE_MC_MTU_CTRL_TX_CNT_EN BIT(16) #define PPE_RFDB_TBL(idx) (PPE_L2_BASE + 0x1000 + (idx) * 0x8) @@ -278,6 +279,8 @@ #define PPE_VSI_TBL_STA_MOVE_LRN_EN BIT(3) #define PPE_MRU_MTU_CTRL(port, stride) (PPE_L2_BASE + 0x3000 + (port) * (stride)) +#define PPE_MRU_MTU_CTRL_MRU GENMASK(13, 0) +#define PPE_MRU_MTU_CTRL_MTU GENMASK(29, 16) #define PPE_MRU_MTU_CTRL_RX_CNT_EN BIT(0) #define PPE_MRU_MTU_CTRL_TX_CNT_EN BIT(1) @@ -420,7 +423,6 @@ #define PPE_VSI_MAX 32 #define PPE_VSI_INVALID U32_MAX #define PPE_DEFAULT_MTU 1514 -#define PPE_MTU_SHIFT 16 #define PPE_MAX_FRAME_SIZE 0x3000 #define PPE_AGE_UNIT_MS 8000 diff --git a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c index c870bbf58d7..64c00d388a1 100644 --- a/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c +++ b/target/linux/qualcommax/files/drivers/net/ethernet/qualcomm/qca_ppe_main.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "qca_ppe.h" @@ -434,11 +435,13 @@ static int qca_ppe_setup(struct dsa_switch *ds) { struct qca_ppe_priv *priv = ds_to_priv(ds); int num_ports = ds->num_ports; + u32 frame_size; u32 port_mask; u32 val; int i; port_mask = BIT(num_ports) - 1; + frame_size = PPE_DEFAULT_MTU + 2 * VLAN_HLEN; for (i = 0; i < num_ports; i++) priv->port_vsi[i] = PPE_VSI_INVALID; @@ -451,7 +454,13 @@ static int qca_ppe_setup(struct dsa_switch *ds) regmap_write(priv->regmap, PPE_MRU_MTU_CTRL(i, priv->data->mru_mtu_ctrl_stride), - PPE_DEFAULT_MTU | (PPE_DEFAULT_MTU << PPE_MTU_SHIFT)); + FIELD_PREP(PPE_MRU_MTU_CTRL_MRU, frame_size) | + FIELD_PREP(PPE_MRU_MTU_CTRL_MTU, frame_size)); + + regmap_update_bits(priv->regmap, PPE_MC_MTU_CTRL(i), + PPE_MC_MTU_CTRL_MTU, + FIELD_PREP(PPE_MC_MTU_CTRL_MTU, + frame_size)); if (i >= 1) regmap_write(priv->regmap, PPE_GMAC_MIB_CTRL(i - 1), @@ -512,6 +521,27 @@ static int qca_ppe_set_ageing_time(struct dsa_switch *ds, unsigned int msecs) return 0; } +static int qca_ppe_port_change_mtu(struct dsa_switch *ds, int port, + int new_mtu) +{ + struct qca_ppe_priv *priv = ds_to_priv(ds); + u32 frame_size = new_mtu + ETH_HLEN + 2 * VLAN_HLEN; + int ret; + + ret = regmap_update_bits(priv->regmap, + PPE_MRU_MTU_CTRL(port, + priv->data->mru_mtu_ctrl_stride), + PPE_MRU_MTU_CTRL_MRU | PPE_MRU_MTU_CTRL_MTU, + FIELD_PREP(PPE_MRU_MTU_CTRL_MRU, frame_size) | + FIELD_PREP(PPE_MRU_MTU_CTRL_MTU, frame_size)); + if (ret) + return ret; + + return regmap_update_bits(priv->regmap, PPE_MC_MTU_CTRL(port), + PPE_MC_MTU_CTRL_MTU, + FIELD_PREP(PPE_MC_MTU_CTRL_MTU, frame_size)); +} + static int qca_ppe_port_enable(struct dsa_switch *ds, int port, struct phy_device *phy) { @@ -1346,6 +1376,7 @@ static const struct dsa_switch_ops qca_ppe_ops = { .get_tag_protocol = qca_ppe_get_tag_protocol, .setup = qca_ppe_setup, .set_ageing_time = qca_ppe_set_ageing_time, + .port_change_mtu = qca_ppe_port_change_mtu, .port_enable = qca_ppe_port_enable, .port_disable = qca_ppe_port_disable, .port_stp_state_set = qca_ppe_port_stp_state_set,