lkml.org 
[lkml]   [2022]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[net-next PATCH v5 11/14] net: dsa: qca8k: move port mirror functions to common code
    Date
    The same port mirror functions are used by drivers based on qca8k family
    switch. Move them to common code to make them accessible also by other
    drivers.

    Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
    Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
    ---
    drivers/net/dsa/qca/qca8k-8xxx.c | 93 ------------------------------
    drivers/net/dsa/qca/qca8k-common.c | 91 +++++++++++++++++++++++++++++
    drivers/net/dsa/qca/qca8k.h | 7 +++
    3 files changed, 98 insertions(+), 93 deletions(-)

    diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
    index bf4dd1cd0f9d..f6ea5a82da9e 100644
    --- a/drivers/net/dsa/qca/qca8k-8xxx.c
    +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
    @@ -1687,99 +1687,6 @@ qca8k_get_ethtool_stats_eth(struct dsa_switch *ds, int port, u64 *data)
    return ret;
    }

    -static int
    -qca8k_port_mirror_add(struct dsa_switch *ds, int port,
    - struct dsa_mall_mirror_tc_entry *mirror,
    - bool ingress, struct netlink_ext_ack *extack)
    -{
    - struct qca8k_priv *priv = ds->priv;
    - int monitor_port, ret;
    - u32 reg, val;
    -
    - /* Check for existent entry */
    - if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
    - return -EEXIST;
    -
    - ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
    - if (ret)
    - return ret;
    -
    - /* QCA83xx can have only one port set to mirror mode.
    - * Check that the correct port is requested and return error otherwise.
    - * When no mirror port is set, the values is set to 0xF
    - */
    - monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
    - if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
    - return -EEXIST;
    -
    - /* Set the monitor port */
    - val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
    - mirror->to_local_port);
    - ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
    - QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
    - if (ret)
    - return ret;
    -
    - if (ingress) {
    - reg = QCA8K_PORT_LOOKUP_CTRL(port);
    - val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
    - } else {
    - reg = QCA8K_REG_PORT_HOL_CTRL1(port);
    - val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
    - }
    -
    - ret = regmap_update_bits(priv->regmap, reg, val, val);
    - if (ret)
    - return ret;
    -
    - /* Track mirror port for tx and rx to decide when the
    - * mirror port has to be disabled.
    - */
    - if (ingress)
    - priv->mirror_rx |= BIT(port);
    - else
    - priv->mirror_tx |= BIT(port);
    -
    - return 0;
    -}
    -
    -static void
    -qca8k_port_mirror_del(struct dsa_switch *ds, int port,
    - struct dsa_mall_mirror_tc_entry *mirror)
    -{
    - struct qca8k_priv *priv = ds->priv;
    - u32 reg, val;
    - int ret;
    -
    - if (mirror->ingress) {
    - reg = QCA8K_PORT_LOOKUP_CTRL(port);
    - val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
    - } else {
    - reg = QCA8K_REG_PORT_HOL_CTRL1(port);
    - val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
    - }
    -
    - ret = regmap_clear_bits(priv->regmap, reg, val);
    - if (ret)
    - goto err;
    -
    - if (mirror->ingress)
    - priv->mirror_rx &= ~BIT(port);
    - else
    - priv->mirror_tx &= ~BIT(port);
    -
    - /* No port set to send packet to mirror port. Disable mirror port */
    - if (!priv->mirror_rx && !priv->mirror_tx) {
    - val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
    - ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
    - QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
    - if (ret)
    - goto err;
    - }
    -err:
    - dev_err(priv->dev, "Failed to del mirror port from %d", port);
    -}
    -
    static int
    qca8k_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
    struct netlink_ext_ack *extack)
    diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
    index 8e92837781ee..c0a088418c20 100644
    --- a/drivers/net/dsa/qca/qca8k-common.c
    +++ b/drivers/net/dsa/qca/qca8k-common.c
    @@ -746,3 +746,94 @@ int qca8k_port_mdb_del(struct dsa_switch *ds, int port,

    return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
    }
    +
    +int qca8k_port_mirror_add(struct dsa_switch *ds, int port,
    + struct dsa_mall_mirror_tc_entry *mirror,
    + bool ingress, struct netlink_ext_ack *extack)
    +{
    + struct qca8k_priv *priv = ds->priv;
    + int monitor_port, ret;
    + u32 reg, val;
    +
    + /* Check for existent entry */
    + if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
    + return -EEXIST;
    +
    + ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
    + if (ret)
    + return ret;
    +
    + /* QCA83xx can have only one port set to mirror mode.
    + * Check that the correct port is requested and return error otherwise.
    + * When no mirror port is set, the values is set to 0xF
    + */
    + monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
    + if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
    + return -EEXIST;
    +
    + /* Set the monitor port */
    + val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
    + mirror->to_local_port);
    + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
    + QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
    + if (ret)
    + return ret;
    +
    + if (ingress) {
    + reg = QCA8K_PORT_LOOKUP_CTRL(port);
    + val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
    + } else {
    + reg = QCA8K_REG_PORT_HOL_CTRL1(port);
    + val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
    + }
    +
    + ret = regmap_update_bits(priv->regmap, reg, val, val);
    + if (ret)
    + return ret;
    +
    + /* Track mirror port for tx and rx to decide when the
    + * mirror port has to be disabled.
    + */
    + if (ingress)
    + priv->mirror_rx |= BIT(port);
    + else
    + priv->mirror_tx |= BIT(port);
    +
    + return 0;
    +}
    +
    +void qca8k_port_mirror_del(struct dsa_switch *ds, int port,
    + struct dsa_mall_mirror_tc_entry *mirror)
    +{
    + struct qca8k_priv *priv = ds->priv;
    + u32 reg, val;
    + int ret;
    +
    + if (mirror->ingress) {
    + reg = QCA8K_PORT_LOOKUP_CTRL(port);
    + val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
    + } else {
    + reg = QCA8K_REG_PORT_HOL_CTRL1(port);
    + val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
    + }
    +
    + ret = regmap_clear_bits(priv->regmap, reg, val);
    + if (ret)
    + goto err;
    +
    + if (mirror->ingress)
    + priv->mirror_rx &= ~BIT(port);
    + else
    + priv->mirror_tx &= ~BIT(port);
    +
    + /* No port set to send packet to mirror port. Disable mirror port */
    + if (!priv->mirror_rx && !priv->mirror_tx) {
    + val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
    + ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
    + QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
    + if (ret)
    + goto err;
    + }
    +err:
    + dev_err(priv->dev, "Failed to del mirror port from %d", port);
    +}
    diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
    index 9da7928de83c..3a2131b7abfa 100644
    --- a/drivers/net/dsa/qca/qca8k.h
    +++ b/drivers/net/dsa/qca/qca8k.h
    @@ -494,4 +494,11 @@ int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
    const struct switchdev_obj_port_mdb *mdb,
    struct dsa_db db);

    +/* Common port mirror function */
    +int qca8k_port_mirror_add(struct dsa_switch *ds, int port,
    + struct dsa_mall_mirror_tc_entry *mirror,
    + bool ingress, struct netlink_ext_ack *extack);
    +void qca8k_port_mirror_del(struct dsa_switch *ds, int port,
    + struct dsa_mall_mirror_tc_entry *mirror);
    +
    #endif /* __QCA8K_H */
    --
    2.36.1
    \
     
     \ /
      Last update: 2022-07-27 13:39    [W:4.179 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site